@primer/components
Version:
Primer react components
137 lines (114 loc) • 6.33 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.FilteredActionList = FilteredActionList;
var _react = _interopRequireWildcard(require("react"));
var _ssr = require("@react-aria/ssr");
var _TextInput = _interopRequireDefault(require("../TextInput"));
var _Box = _interopRequireDefault(require("../Box"));
var _ActionList = require("../ActionList");
var _Spinner = _interopRequireDefault(require("../Spinner"));
var _useFocusZone = require("../hooks/useFocusZone");
var _useProvidedStateOrCreate = require("../hooks/useProvidedStateOrCreate");
var _styledComponents = _interopRequireDefault(require("styled-components"));
var _constants = require("../constants");
var _useProvidedRefOrCreate = require("../hooks/useProvidedRefOrCreate");
var _useScrollFlash = _interopRequireDefault(require("../hooks/useScrollFlash"));
var _scrollIntoViewingArea = require("../behaviors/scrollIntoViewingArea");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
const StyledHeader = _styledComponents.default.div.withConfig({
displayName: "FilteredActionList__StyledHeader",
componentId: "sc-yg3jkv-0"
})(["box-shadow:0 1px 0 ", ";z-index:1;"], (0, _constants.get)('colors.border.default'));
function FilteredActionList({
loading = false,
placeholderText,
filterValue: externalFilterValue,
onFilterChange,
items,
textInputProps,
inputRef: providedInputRef,
sx,
...listProps
}) {
const [filterValue, setInternalFilterValue] = (0, _useProvidedStateOrCreate.useProvidedStateOrCreate)(externalFilterValue, undefined, '');
const onInputChange = (0, _react.useCallback)(e => {
const value = e.target.value;
onFilterChange(value, e);
setInternalFilterValue(value);
}, [onFilterChange, setInternalFilterValue]);
const scrollContainerRef = (0, _react.useRef)(null);
const listContainerRef = (0, _react.useRef)(null);
const inputRef = (0, _useProvidedRefOrCreate.useProvidedRefOrCreate)(providedInputRef);
const activeDescendantRef = (0, _react.useRef)();
const listId = (0, _ssr.useSSRSafeId)();
const onInputKeyPress = (0, _react.useCallback)(event => {
if (event.key === 'Enter' && activeDescendantRef.current) {
event.preventDefault();
event.nativeEvent.stopImmediatePropagation(); // Forward Enter key press to active descendant so that item gets activated
const activeDescendantEvent = new KeyboardEvent(event.type, event.nativeEvent);
activeDescendantRef.current.dispatchEvent(activeDescendantEvent);
}
}, [activeDescendantRef]);
(0, _useFocusZone.useFocusZone)({
containerRef: listContainerRef,
focusOutBehavior: 'wrap',
focusableElementFilter: element => {
return !(element instanceof HTMLInputElement);
},
activeDescendantFocus: inputRef,
onActiveDescendantChanged: (current, previous, directlyActivated) => {
activeDescendantRef.current = current;
if (current && scrollContainerRef.current && directlyActivated) {
(0, _scrollIntoViewingArea.scrollIntoViewingArea)(current, scrollContainerRef.current);
}
}
}, [// List ref isn't set while loading. Need to re-bind focus zone when it changes
loading]);
(0, _react.useEffect)(() => {
// if items changed, we want to instantly move active descendant into view
if (activeDescendantRef.current && scrollContainerRef.current) {
(0, _scrollIntoViewingArea.scrollIntoViewingArea)(activeDescendantRef.current, scrollContainerRef.current, 'vertical', undefined, undefined, 'auto');
}
}, [items]);
(0, _useScrollFlash.default)(scrollContainerRef);
return /*#__PURE__*/_react.default.createElement(_Box.default, {
display: "flex",
flexDirection: "column",
overflow: "hidden",
sx: sx
}, /*#__PURE__*/_react.default.createElement(StyledHeader, null, /*#__PURE__*/_react.default.createElement(_TextInput.default, _extends({
ref: inputRef,
block: true,
width: "auto",
color: "fg.default",
value: filterValue,
onChange: onInputChange,
onKeyPress: onInputKeyPress,
placeholder: placeholderText,
"aria-label": placeholderText,
"aria-controls": listId
}, textInputProps))), /*#__PURE__*/_react.default.createElement(_Box.default, {
ref: scrollContainerRef,
overflow: "auto"
}, loading ? /*#__PURE__*/_react.default.createElement(_Box.default, {
width: "100%",
display: "flex",
flexDirection: "row",
justifyContent: "center",
pt: 6,
pb: 7
}, /*#__PURE__*/_react.default.createElement(_Spinner.default, null)) : /*#__PURE__*/_react.default.createElement(_ActionList.ActionList, _extends({
ref: listContainerRef,
items: items
}, listProps, {
role: "listbox",
id: listId
}))));
}
FilteredActionList.displayName = "FilteredActionList";
FilteredActionList.displayName = 'FilteredActionList';