@primer/components 0.0.0-20211030163410 → 0.0.0-20211030175556
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -28
- package/dist/browser.esm.js +591 -602
- package/dist/browser.esm.js.map +1 -1
- package/dist/browser.umd.js +200 -211
- package/dist/browser.umd.js.map +1 -1
- package/lib/ActionList/Divider.jsx +29 -0
- package/lib/ActionList/Group.jsx +23 -0
- package/lib/ActionList/Header.jsx +66 -0
- package/lib/ActionList/Item.js +3 -3
- package/lib/ActionList/Item.jsx +288 -0
- package/lib/ActionList/List.jsx +138 -0
- package/lib/ActionList/index.js +12 -23
- package/lib/ActionList2/Description.jsx +29 -0
- package/lib/ActionList2/Divider.jsx +22 -0
- package/lib/ActionList2/Group.jsx +54 -0
- package/lib/ActionList2/Header.d.ts +26 -0
- package/lib/ActionList2/Header.js +55 -0
- package/lib/ActionList2/Header.jsx +36 -0
- package/lib/ActionList2/Item.js +1 -3
- package/lib/ActionList2/Item.jsx +174 -0
- package/lib/ActionList2/LinkItem.jsx +28 -0
- package/lib/ActionList2/List.js +2 -1
- package/lib/ActionList2/List.jsx +41 -0
- package/lib/ActionList2/Selection.js +1 -3
- package/lib/ActionList2/Selection.jsx +50 -0
- package/lib/ActionList2/Visuals.jsx +48 -0
- package/lib/ActionList2/index.js +23 -41
- package/lib/ActionMenu.jsx +73 -0
- package/lib/AnchoredOverlay/AnchoredOverlay.jsx +100 -0
- package/lib/AnchoredOverlay/index.js +4 -12
- package/lib/Autocomplete/Autocomplete.d.ts +0 -1
- package/lib/Autocomplete/Autocomplete.jsx +100 -0
- package/lib/Autocomplete/AutocompleteContext.jsx +5 -0
- package/lib/Autocomplete/AutocompleteInput.d.ts +0 -1
- package/lib/Autocomplete/AutocompleteInput.jsx +113 -0
- package/lib/Autocomplete/AutocompleteMenu.js +13 -6
- package/lib/Autocomplete/AutocompleteMenu.jsx +190 -0
- package/lib/Autocomplete/AutocompleteOverlay.jsx +55 -0
- package/lib/Autocomplete/index.js +7 -14
- package/lib/Avatar.jsx +34 -0
- package/lib/AvatarPair.jsx +29 -0
- package/lib/AvatarStack.jsx +151 -0
- package/lib/BaseStyles.jsx +65 -0
- package/lib/BorderBox.jsx +18 -0
- package/lib/Box.jsx +10 -0
- package/lib/BranchName.jsx +20 -0
- package/lib/Breadcrumbs.jsx +71 -0
- package/lib/Button/Button.d.ts +0 -1
- package/lib/Button/Button.jsx +40 -0
- package/lib/Button/ButtonBase.jsx +33 -0
- package/lib/Button/ButtonClose.d.ts +1 -2
- package/lib/Button/ButtonClose.jsx +53 -0
- package/lib/Button/ButtonDanger.d.ts +0 -1
- package/lib/Button/ButtonDanger.jsx +43 -0
- package/lib/Button/ButtonGroup.jsx +55 -0
- package/lib/Button/ButtonInvisible.d.ts +0 -1
- package/lib/Button/ButtonInvisible.jsx +32 -0
- package/lib/Button/ButtonOutline.d.ts +0 -1
- package/lib/Button/ButtonOutline.jsx +43 -0
- package/lib/Button/ButtonPrimary.d.ts +0 -1
- package/lib/Button/ButtonPrimary.jsx +42 -0
- package/lib/Button/ButtonStyles.jsx +37 -0
- package/lib/Button/ButtonTableList.jsx +46 -0
- package/lib/Button/index.js +21 -70
- package/lib/Caret.jsx +93 -0
- package/lib/CircleBadge.jsx +42 -0
- package/lib/CircleOcticon.d.ts +0 -1
- package/lib/CircleOcticon.jsx +21 -0
- package/lib/CounterLabel.jsx +43 -0
- package/lib/Details.jsx +21 -0
- package/lib/Dialog/ConfirmationDialog.jsx +146 -0
- package/lib/Dialog/Dialog.jsx +279 -0
- package/lib/Dialog.d.ts +2 -3
- package/lib/Dialog.jsx +129 -0
- package/lib/Dropdown.d.ts +0 -4
- package/lib/Dropdown.jsx +131 -0
- package/lib/DropdownMenu/DropdownButton.d.ts +1 -2
- package/lib/DropdownMenu/DropdownButton.jsx +14 -0
- package/lib/DropdownMenu/DropdownMenu.jsx +70 -0
- package/lib/DropdownMenu/index.js +6 -20
- package/lib/DropdownStyles.js +18 -26
- package/lib/FilterList.d.ts +0 -1
- package/lib/FilterList.jsx +59 -0
- package/lib/FilteredActionList/FilteredActionList.jsx +100 -0
- package/lib/FilteredActionList/index.js +4 -12
- package/lib/FilteredSearch.jsx +28 -0
- package/lib/Flash.jsx +69 -0
- package/lib/Flex.jsx +15 -0
- package/lib/FormGroup.jsx +22 -0
- package/lib/Grid.jsx +15 -0
- package/lib/Header.jsx +83 -0
- package/lib/Heading.jsx +21 -0
- package/lib/Label.jsx +82 -0
- package/lib/LabelGroup.jsx +18 -0
- package/lib/Link.jsx +36 -0
- package/lib/NewButton/button-counter.jsx +14 -0
- package/lib/NewButton/button.jsx +279 -0
- package/lib/NewButton/index.js +5 -12
- package/lib/NewButton/types.js +2 -1
- package/lib/Overlay.d.ts +3 -5
- package/lib/Overlay.jsx +154 -0
- package/lib/Pagehead.jsx +17 -0
- package/lib/Pagination/Pagination.jsx +161 -0
- package/lib/Pagination/index.js +6 -12
- package/lib/Pagination/model.jsx +174 -0
- package/lib/PointerBox.jsx +25 -0
- package/lib/Popover.jsx +202 -0
- package/lib/Portal/Portal.jsx +79 -0
- package/lib/Portal/index.js +5 -16
- package/lib/Position.d.ts +4 -4
- package/lib/Position.jsx +46 -0
- package/lib/ProgressBar.jsx +39 -0
- package/lib/SelectMenu/SelectMenu.d.ts +4 -10
- package/lib/SelectMenu/SelectMenu.jsx +112 -0
- package/lib/SelectMenu/SelectMenuContext.jsx +5 -0
- package/lib/SelectMenu/SelectMenuDivider.jsx +42 -0
- package/lib/SelectMenu/SelectMenuFilter.jsx +58 -0
- package/lib/SelectMenu/SelectMenuFooter.jsx +45 -0
- package/lib/SelectMenu/SelectMenuHeader.jsx +42 -0
- package/lib/SelectMenu/SelectMenuItem.d.ts +1 -1
- package/lib/SelectMenu/SelectMenuItem.jsx +142 -0
- package/lib/SelectMenu/SelectMenuList.jsx +59 -0
- package/lib/SelectMenu/SelectMenuLoadingAnimation.jsx +22 -0
- package/lib/SelectMenu/SelectMenuModal.d.ts +1 -1
- package/lib/SelectMenu/SelectMenuModal.jsx +118 -0
- package/lib/SelectMenu/SelectMenuTab.jsx +92 -0
- package/lib/SelectMenu/SelectMenuTabPanel.jsx +42 -0
- package/lib/SelectMenu/SelectMenuTabs.jsx +57 -0
- package/lib/SelectMenu/hooks/useKeyboardNav.js +80 -96
- package/lib/SelectMenu/index.js +7 -14
- package/lib/SelectPanel/SelectPanel.jsx +105 -0
- package/lib/SelectPanel/index.js +4 -12
- package/lib/SideNav.jsx +173 -0
- package/lib/Spinner.jsx +35 -0
- package/lib/StateLabel.jsx +93 -0
- package/lib/StyledOcticon.jsx +18 -0
- package/lib/SubNav.jsx +101 -0
- package/lib/TabNav.jsx +58 -0
- package/lib/Text.jsx +14 -0
- package/lib/TextInput.jsx +23 -0
- package/lib/TextInputWithTokens.d.ts +0 -1
- package/lib/TextInputWithTokens.jsx +218 -0
- package/lib/ThemeProvider.jsx +130 -0
- package/lib/Timeline.jsx +123 -0
- package/lib/Token/AvatarToken.d.ts +1 -1
- package/lib/Token/AvatarToken.jsx +54 -0
- package/lib/Token/IssueLabelToken.d.ts +1 -1
- package/lib/Token/IssueLabelToken.jsx +125 -0
- package/lib/Token/Token.d.ts +1 -1
- package/lib/Token/Token.jsx +103 -0
- package/lib/Token/TokenBase.jsx +88 -0
- package/lib/Token/_RemoveTokenButton.jsx +108 -0
- package/lib/Token/_TokenTextContainer.jsx +49 -0
- package/lib/Token/index.js +11 -30
- package/lib/Tooltip.jsx +246 -0
- package/lib/Truncate.jsx +24 -0
- package/lib/UnderlineNav.jsx +88 -0
- package/lib/_TextInputWrapper.jsx +120 -0
- package/lib/_UnstyledTextInput.jsx +22 -0
- package/lib/behaviors/anchoredPosition.js +205 -234
- package/lib/behaviors/focusTrap.js +121 -157
- package/lib/behaviors/focusZone.js +434 -509
- package/lib/behaviors/scrollIntoViewingArea.js +18 -35
- package/lib/constants.js +39 -43
- package/lib/drafts.js +20 -30
- package/lib/hooks/index.js +16 -60
- package/lib/hooks/useAnchoredPosition.js +32 -40
- package/lib/hooks/useCombinedRefs.js +32 -36
- package/lib/hooks/useDetails.jsx +39 -0
- package/lib/hooks/useDialog.js +72 -96
- package/lib/hooks/useFocusTrap.js +43 -60
- package/lib/hooks/useFocusZone.js +54 -50
- package/lib/hooks/useOnEscapePress.js +25 -36
- package/lib/hooks/useOnOutsideClick.jsx +61 -0
- package/lib/hooks/useOpenAndCloseFocus.js +22 -34
- package/lib/hooks/useOverlay.jsx +15 -0
- package/lib/hooks/useProvidedRefOrCreate.js +10 -14
- package/lib/hooks/useProvidedStateOrCreate.js +13 -16
- package/lib/hooks/useRenderForcingRef.js +13 -17
- package/lib/hooks/useResizeObserver.js +15 -18
- package/lib/hooks/useSafeTimeout.js +22 -30
- package/lib/hooks/useScrollFlash.js +16 -23
- package/lib/index.d.ts +0 -5
- package/lib/index.js +163 -676
- package/lib/polyfills/eventListenerSignal.js +37 -45
- package/lib/sx.js +10 -22
- package/lib/theme-preval.js +64 -3169
- package/lib/theme.js +3 -12
- package/lib/utils/create-slots.jsx +65 -0
- package/lib/utils/deprecate.jsx +59 -0
- package/lib/utils/isNumeric.jsx +7 -0
- package/lib/utils/iterateFocusableElements.js +63 -85
- package/lib/utils/ssr.jsx +6 -0
- package/lib/utils/test-deprecations.jsx +20 -0
- package/lib/utils/test-helpers.jsx +8 -0
- package/lib/utils/test-matchers.jsx +100 -0
- package/lib/utils/testing.d.ts +1 -2
- package/lib/utils/testing.js +0 -29
- package/lib/utils/testing.jsx +206 -0
- package/lib/utils/theme.js +33 -47
- package/lib/utils/types/AriaRole.js +2 -1
- package/lib/utils/types/ComponentProps.js +2 -1
- package/lib/utils/types/Flatten.js +2 -1
- package/lib/utils/types/KeyPaths.js +2 -1
- package/lib/utils/types/MandateProps.js +16 -1
- package/lib/utils/types/Merge.js +2 -1
- package/lib/utils/types/index.js +16 -69
- package/lib/utils/uniqueId.js +5 -8
- package/lib/utils/use-force-update.js +8 -14
- package/lib/utils/useIsomorphicLayoutEffect.js +8 -11
- package/lib/utils/userAgent.js +8 -12
- package/lib-esm/ActionList/Item.js +3 -3
- package/lib-esm/ActionList2/Header.d.ts +26 -0
- package/lib-esm/ActionList2/Header.js +44 -0
- package/lib-esm/ActionList2/Item.js +1 -3
- package/lib-esm/ActionList2/List.js +2 -1
- package/lib-esm/ActionList2/Selection.js +1 -3
- package/lib-esm/Autocomplete/Autocomplete.d.ts +0 -1
- package/lib-esm/Autocomplete/AutocompleteInput.d.ts +0 -1
- package/lib-esm/Autocomplete/AutocompleteMenu.js +13 -3
- package/lib-esm/Button/Button.d.ts +0 -1
- package/lib-esm/Button/ButtonClose.d.ts +1 -2
- package/lib-esm/Button/ButtonDanger.d.ts +0 -1
- package/lib-esm/Button/ButtonInvisible.d.ts +0 -1
- package/lib-esm/Button/ButtonOutline.d.ts +0 -1
- package/lib-esm/Button/ButtonPrimary.d.ts +0 -1
- package/lib-esm/CircleOcticon.d.ts +0 -1
- package/lib-esm/Dialog.d.ts +2 -3
- package/lib-esm/Dropdown.d.ts +0 -4
- package/lib-esm/DropdownMenu/DropdownButton.d.ts +1 -2
- package/lib-esm/FilterList.d.ts +0 -1
- package/lib-esm/Overlay.d.ts +3 -5
- package/lib-esm/Position.d.ts +4 -4
- package/lib-esm/SelectMenu/SelectMenu.d.ts +4 -10
- package/lib-esm/SelectMenu/SelectMenuItem.d.ts +1 -1
- package/lib-esm/SelectMenu/SelectMenuModal.d.ts +1 -1
- package/lib-esm/TextInputWithTokens.d.ts +0 -1
- package/lib-esm/Token/AvatarToken.d.ts +1 -1
- package/lib-esm/Token/IssueLabelToken.d.ts +1 -1
- package/lib-esm/Token/Token.d.ts +1 -1
- package/lib-esm/index.d.ts +0 -5
- package/lib-esm/index.js +0 -4
- package/lib-esm/theme-preval.js +0 -446
- package/lib-esm/utils/testing.d.ts +1 -2
- package/lib-esm/utils/testing.js +0 -24
- package/package.json +6 -5
- package/lib/Checkbox.d.ts +0 -29
- package/lib/Checkbox.js +0 -64
- package/lib/CheckboxInputField.d.ts +0 -11
- package/lib/CheckboxInputField.js +0 -74
- package/lib/RadioInputField.d.ts +0 -9
- package/lib/RadioInputField.js +0 -83
- package/lib/TextInputField.d.ts +0 -581
- package/lib/TextInputField.js +0 -66
- package/lib/_InputCaption.d.ts +0 -6
- package/lib/_InputCaption.js +0 -23
- package/lib/_InputField/InputField.d.ts +0 -39
- package/lib/_InputField/InputField.js +0 -90
- package/lib/_InputField/InputFieldCaption.d.ts +0 -3
- package/lib/_InputField/InputFieldCaption.js +0 -28
- package/lib/_InputField/InputFieldLabel.d.ts +0 -9
- package/lib/_InputField/InputFieldLabel.js +0 -34
- package/lib/_InputField/InputFieldValidation.d.ts +0 -6
- package/lib/_InputField/InputFieldValidation.js +0 -17
- package/lib/_InputField/ToggleInputField.d.ts +0 -13
- package/lib/_InputField/ToggleInputField.js +0 -71
- package/lib/_InputField/ToggleInputLeadingVisual.d.ts +0 -3
- package/lib/_InputField/ToggleInputLeadingVisual.js +0 -22
- package/lib/_InputField/ValidationAnimationContainer.d.ts +0 -6
- package/lib/_InputField/ValidationAnimationContainer.js +0 -48
- package/lib/_InputField/index.d.ts +0 -1
- package/lib/_InputField/index.js +0 -15
- package/lib/_InputField/slots.d.ts +0 -13
- package/lib/_InputField/slots.js +0 -17
- package/lib/_InputLabel.d.ts +0 -8
- package/lib/_InputLabel.js +0 -44
- package/lib/_InputValidation.d.ts +0 -8
- package/lib/_InputValidation.js +0 -56
- package/lib/_VisuallyHidden.d.ts +0 -6
- package/lib/_VisuallyHidden.js +0 -39
- package/lib/utils/types/FormValidationStatus.d.ts +0 -1
- package/lib/utils/types/FormValidationStatus.js +0 -1
- package/lib-esm/Checkbox.d.ts +0 -29
- package/lib-esm/Checkbox.js +0 -44
- package/lib-esm/CheckboxInputField.d.ts +0 -11
- package/lib-esm/CheckboxInputField.js +0 -57
- package/lib-esm/RadioInputField.d.ts +0 -9
- package/lib-esm/RadioInputField.js +0 -66
- package/lib-esm/TextInputField.d.ts +0 -581
- package/lib-esm/TextInputField.js +0 -50
- package/lib-esm/_InputCaption.d.ts +0 -6
- package/lib-esm/_InputCaption.js +0 -12
- package/lib-esm/_InputField/InputField.d.ts +0 -39
- package/lib-esm/_InputField/InputField.js +0 -70
- package/lib-esm/_InputField/InputFieldCaption.d.ts +0 -3
- package/lib-esm/_InputField/InputFieldCaption.js +0 -16
- package/lib-esm/_InputField/InputFieldLabel.d.ts +0 -9
- package/lib-esm/_InputField/InputFieldLabel.js +0 -22
- package/lib-esm/_InputField/InputFieldValidation.d.ts +0 -6
- package/lib-esm/_InputField/InputFieldValidation.js +0 -7
- package/lib-esm/_InputField/ToggleInputField.d.ts +0 -13
- package/lib-esm/_InputField/ToggleInputField.js +0 -54
- package/lib-esm/_InputField/ToggleInputLeadingVisual.d.ts +0 -3
- package/lib-esm/_InputField/ToggleInputLeadingVisual.js +0 -11
- package/lib-esm/_InputField/ValidationAnimationContainer.d.ts +0 -6
- package/lib-esm/_InputField/ValidationAnimationContainer.js +0 -33
- package/lib-esm/_InputField/index.d.ts +0 -1
- package/lib-esm/_InputField/index.js +0 -1
- package/lib-esm/_InputField/slots.d.ts +0 -13
- package/lib-esm/_InputField/slots.js +0 -5
- package/lib-esm/_InputLabel.d.ts +0 -8
- package/lib-esm/_InputLabel.js +0 -32
- package/lib-esm/_InputValidation.d.ts +0 -8
- package/lib-esm/_InputValidation.js +0 -43
- package/lib-esm/_VisuallyHidden.d.ts +0 -6
- package/lib-esm/_VisuallyHidden.js +0 -26
- package/lib-esm/utils/types/FormValidationStatus.d.ts +0 -1
- package/lib-esm/utils/types/FormValidationStatus.js +0 -1
@@ -0,0 +1,73 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
5
|
+
}) : (function(o, m, k, k2) {
|
6
|
+
if (k2 === undefined) k2 = k;
|
7
|
+
o[k2] = m[k];
|
8
|
+
}));
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
11
|
+
}) : function(o, v) {
|
12
|
+
o["default"] = v;
|
13
|
+
});
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
15
|
+
if (mod && mod.__esModule) return mod;
|
16
|
+
var result = {};
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
18
|
+
__setModuleDefault(result, mod);
|
19
|
+
return result;
|
20
|
+
};
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
23
|
+
};
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
25
|
+
exports.ActionMenu = void 0;
|
26
|
+
const List_1 = require("./ActionList/List");
|
27
|
+
const Item_1 = require("./ActionList/Item");
|
28
|
+
const Divider_1 = require("./ActionList/Divider");
|
29
|
+
const Button_1 = __importDefault(require("./Button"));
|
30
|
+
const react_1 = __importStar(require("react"));
|
31
|
+
const AnchoredOverlay_1 = require("./AnchoredOverlay");
|
32
|
+
const useProvidedStateOrCreate_1 = require("./hooks/useProvidedStateOrCreate");
|
33
|
+
const hooks_1 = require("./hooks");
|
34
|
+
const ActionMenuItem = (props) => <Item_1.Item role="menuitem" {...props}/>;
|
35
|
+
ActionMenuItem.displayName = 'ActionMenu.Item';
|
36
|
+
const ActionMenuBase = ({ anchorContent, renderAnchor = (props) => <Button_1.default {...props}/>, anchorRef: externalAnchorRef, onAction, open, setOpen, overlayProps, items, ...listProps }) => {
|
37
|
+
const [combinedOpenState, setCombinedOpenState] = useProvidedStateOrCreate_1.useProvidedStateOrCreate(open, setOpen, false);
|
38
|
+
const anchorRef = hooks_1.useProvidedRefOrCreate(externalAnchorRef);
|
39
|
+
const onOpen = react_1.useCallback(() => setCombinedOpenState(true), [setCombinedOpenState]);
|
40
|
+
const onClose = react_1.useCallback(() => setCombinedOpenState(false), [setCombinedOpenState]);
|
41
|
+
const renderMenuAnchor = react_1.useMemo(() => {
|
42
|
+
if (renderAnchor === null) {
|
43
|
+
return null;
|
44
|
+
}
|
45
|
+
return (props) => {
|
46
|
+
return renderAnchor({
|
47
|
+
'aria-label': 'menu',
|
48
|
+
children: anchorContent,
|
49
|
+
...props
|
50
|
+
});
|
51
|
+
};
|
52
|
+
}, [anchorContent, renderAnchor]);
|
53
|
+
const itemsToRender = react_1.useMemo(() => {
|
54
|
+
return items.map(item => {
|
55
|
+
return {
|
56
|
+
...item,
|
57
|
+
role: 'menuitem',
|
58
|
+
onAction: (props, event) => {
|
59
|
+
const actionCallback = item.onAction ?? onAction;
|
60
|
+
actionCallback?.(props, event);
|
61
|
+
if (!event.defaultPrevented) {
|
62
|
+
onClose();
|
63
|
+
}
|
64
|
+
}
|
65
|
+
};
|
66
|
+
});
|
67
|
+
}, [items, onAction, onClose]);
|
68
|
+
return (<AnchoredOverlay_1.AnchoredOverlay renderAnchor={renderMenuAnchor} anchorRef={anchorRef} open={combinedOpenState} onOpen={onOpen} onClose={onClose} overlayProps={overlayProps}>
|
69
|
+
<List_1.List {...listProps} role="menu" items={itemsToRender}/>
|
70
|
+
</AnchoredOverlay_1.AnchoredOverlay>);
|
71
|
+
};
|
72
|
+
ActionMenuBase.displayName = 'ActionMenu';
|
73
|
+
exports.ActionMenu = Object.assign(ActionMenuBase, { Divider: Divider_1.Divider, Item: ActionMenuItem });
|
@@ -0,0 +1,100 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
5
|
+
}) : (function(o, m, k, k2) {
|
6
|
+
if (k2 === undefined) k2 = k;
|
7
|
+
o[k2] = m[k];
|
8
|
+
}));
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
11
|
+
}) : function(o, v) {
|
12
|
+
o["default"] = v;
|
13
|
+
});
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
15
|
+
if (mod && mod.__esModule) return mod;
|
16
|
+
var result = {};
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
18
|
+
__setModuleDefault(result, mod);
|
19
|
+
return result;
|
20
|
+
};
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
23
|
+
};
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
25
|
+
exports.AnchoredOverlay = void 0;
|
26
|
+
const react_1 = __importStar(require("react"));
|
27
|
+
const Overlay_1 = __importDefault(require("../Overlay"));
|
28
|
+
const useFocusTrap_1 = require("../hooks/useFocusTrap");
|
29
|
+
const useFocusZone_1 = require("../hooks/useFocusZone");
|
30
|
+
const hooks_1 = require("../hooks");
|
31
|
+
const ssr_1 = require("@react-aria/ssr");
|
32
|
+
/**
|
33
|
+
* An `AnchoredOverlay` provides an anchor that will open a floating overlay positioned relative to the anchor.
|
34
|
+
* The overlay can be opened and navigated using keyboard or mouse.
|
35
|
+
*/
|
36
|
+
const AnchoredOverlay = ({ renderAnchor, anchorRef: externalAnchorRef, children, open, onOpen, onClose, height, width, overlayProps, focusTrapSettings, focusZoneSettings, side, align }) => {
|
37
|
+
const anchorRef = hooks_1.useProvidedRefOrCreate(externalAnchorRef);
|
38
|
+
const [overlayRef, updateOverlayRef] = hooks_1.useRenderForcingRef();
|
39
|
+
const anchorId = ssr_1.useSSRSafeId();
|
40
|
+
const onClickOutside = react_1.useCallback(() => onClose?.('click-outside'), [onClose]);
|
41
|
+
const onEscape = react_1.useCallback(() => onClose?.('escape'), [onClose]);
|
42
|
+
const onAnchorKeyDown = react_1.useCallback((event) => {
|
43
|
+
if (!event.defaultPrevented) {
|
44
|
+
if (!open && ['ArrowDown', 'ArrowUp', ' ', 'Enter'].includes(event.key)) {
|
45
|
+
onOpen?.('anchor-key-press');
|
46
|
+
event.preventDefault();
|
47
|
+
}
|
48
|
+
}
|
49
|
+
}, [open, onOpen]);
|
50
|
+
const onAnchorClick = react_1.useCallback((event) => {
|
51
|
+
if (event.defaultPrevented || event.button !== 0) {
|
52
|
+
return;
|
53
|
+
}
|
54
|
+
if (!open) {
|
55
|
+
onOpen?.('anchor-click');
|
56
|
+
}
|
57
|
+
else {
|
58
|
+
onClose?.('anchor-click');
|
59
|
+
}
|
60
|
+
}, [open, onOpen, onClose]);
|
61
|
+
const { position } = hooks_1.useAnchoredPosition({
|
62
|
+
anchorElementRef: anchorRef,
|
63
|
+
floatingElementRef: overlayRef,
|
64
|
+
side,
|
65
|
+
align
|
66
|
+
}, [overlayRef.current]);
|
67
|
+
react_1.useEffect(() => {
|
68
|
+
// ensure overlay ref gets cleared when closed, so position can reset between closing/re-opening
|
69
|
+
if (!open && overlayRef.current) {
|
70
|
+
updateOverlayRef(null);
|
71
|
+
}
|
72
|
+
}, [open, overlayRef, updateOverlayRef]);
|
73
|
+
useFocusZone_1.useFocusZone({
|
74
|
+
containerRef: overlayRef,
|
75
|
+
disabled: !open || !position,
|
76
|
+
...focusZoneSettings
|
77
|
+
});
|
78
|
+
useFocusTrap_1.useFocusTrap({ containerRef: overlayRef, disabled: !open || !position, ...focusTrapSettings });
|
79
|
+
return (<>
|
80
|
+
{renderAnchor &&
|
81
|
+
renderAnchor({
|
82
|
+
ref: anchorRef,
|
83
|
+
id: anchorId,
|
84
|
+
'aria-labelledby': anchorId,
|
85
|
+
'aria-haspopup': 'true',
|
86
|
+
tabIndex: 0,
|
87
|
+
onClick: onAnchorClick,
|
88
|
+
onKeyDown: onAnchorKeyDown
|
89
|
+
})}
|
90
|
+
{open ? (<Overlay_1.default returnFocusRef={anchorRef} onClickOutside={onClickOutside} ignoreClickRefs={[anchorRef]} onEscape={onEscape} ref={updateOverlayRef} role="none" visibility={position ? 'visible' : 'hidden'} height={height} width={width} top={position?.top || 0} left={position?.left || 0} anchorSide={position?.anchorSide} {...overlayProps}>
|
91
|
+
{children}
|
92
|
+
</Overlay_1.default>) : null}
|
93
|
+
</>);
|
94
|
+
};
|
95
|
+
exports.AnchoredOverlay = AnchoredOverlay;
|
96
|
+
exports.AnchoredOverlay.displayName = 'AnchoredOverlay';
|
97
|
+
exports.AnchoredOverlay.defaultProps = {
|
98
|
+
side: 'outside-bottom',
|
99
|
+
align: 'start'
|
100
|
+
};
|
@@ -1,13 +1,5 @@
|
|
1
1
|
"use strict";
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
});
|
6
|
-
Object.defineProperty(exports, "AnchoredOverlay", {
|
7
|
-
enumerable: true,
|
8
|
-
get: function () {
|
9
|
-
return _AnchoredOverlay.AnchoredOverlay;
|
10
|
-
}
|
11
|
-
});
|
12
|
-
|
13
|
-
var _AnchoredOverlay = require("./AnchoredOverlay");
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.AnchoredOverlay = void 0;
|
4
|
+
var AnchoredOverlay_1 = require("./AnchoredOverlay");
|
5
|
+
Object.defineProperty(exports, "AnchoredOverlay", { enumerable: true, get: function () { return AnchoredOverlay_1.AnchoredOverlay; } });
|
@@ -290,7 +290,6 @@ declare const _default: React.FC<{
|
|
290
290
|
onAnimationIterationCapture?: React.AnimationEventHandler<HTMLSpanElement> | undefined;
|
291
291
|
onTransitionEnd?: React.TransitionEventHandler<HTMLSpanElement> | undefined;
|
292
292
|
onTransitionEndCapture?: React.TransitionEventHandler<HTMLSpanElement> | undefined;
|
293
|
-
css?: import("@emotion/core").InterpolationWithTheme<any>;
|
294
293
|
disabled?: boolean | undefined;
|
295
294
|
hasIcon?: boolean | undefined;
|
296
295
|
contrast?: boolean | undefined;
|
@@ -0,0 +1,100 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
5
|
+
}) : (function(o, m, k, k2) {
|
6
|
+
if (k2 === undefined) k2 = k;
|
7
|
+
o[k2] = m[k];
|
8
|
+
}));
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
11
|
+
}) : function(o, v) {
|
12
|
+
o["default"] = v;
|
13
|
+
});
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
15
|
+
if (mod && mod.__esModule) return mod;
|
16
|
+
var result = {};
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
18
|
+
__setModuleDefault(result, mod);
|
19
|
+
return result;
|
20
|
+
};
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
23
|
+
};
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
25
|
+
const react_1 = __importStar(require("react"));
|
26
|
+
const ssr_1 = require("@react-aria/ssr");
|
27
|
+
const AutocompleteContext_1 = require("./AutocompleteContext");
|
28
|
+
const AutocompleteInput_1 = __importDefault(require("./AutocompleteInput"));
|
29
|
+
const AutocompleteMenu_1 = __importDefault(require("./AutocompleteMenu"));
|
30
|
+
const AutocompleteOverlay_1 = __importDefault(require("./AutocompleteOverlay"));
|
31
|
+
const initialState = {
|
32
|
+
inputValue: '',
|
33
|
+
showMenu: false,
|
34
|
+
isMenuDirectlyActivated: false,
|
35
|
+
autocompleteSuggestion: '',
|
36
|
+
selectedItemLength: 0
|
37
|
+
};
|
38
|
+
const reducer = (state, action) => {
|
39
|
+
const { type, payload } = action;
|
40
|
+
switch (type) {
|
41
|
+
case 'inputValue':
|
42
|
+
return { ...state, inputValue: payload };
|
43
|
+
case 'showMenu':
|
44
|
+
return { ...state, showMenu: payload };
|
45
|
+
case 'isMenuDirectlyActivated':
|
46
|
+
return { ...state, isMenuDirectlyActivated: payload };
|
47
|
+
case 'autocompleteSuggestion':
|
48
|
+
return { ...state, autocompleteSuggestion: payload };
|
49
|
+
case 'selectedItemLength':
|
50
|
+
return { ...state, selectedItemLength: payload };
|
51
|
+
default:
|
52
|
+
return state;
|
53
|
+
}
|
54
|
+
};
|
55
|
+
const Autocomplete = ({ children, id: idProp }) => {
|
56
|
+
const activeDescendantRef = react_1.useRef(null);
|
57
|
+
const scrollContainerRef = react_1.useRef(null);
|
58
|
+
const inputRef = react_1.useRef(null);
|
59
|
+
const [state, dispatch] = react_1.useReducer(reducer, initialState);
|
60
|
+
const { inputValue, showMenu, autocompleteSuggestion, isMenuDirectlyActivated, selectedItemLength } = state;
|
61
|
+
const setInputValue = react_1.useCallback((value) => {
|
62
|
+
dispatch({ type: 'inputValue', payload: value });
|
63
|
+
}, []);
|
64
|
+
const setShowMenu = react_1.useCallback((value) => {
|
65
|
+
dispatch({ type: 'showMenu', payload: value });
|
66
|
+
}, []);
|
67
|
+
const setAutocompleteSuggestion = react_1.useCallback((value) => {
|
68
|
+
dispatch({ type: 'autocompleteSuggestion', payload: value });
|
69
|
+
}, []);
|
70
|
+
const setIsMenuDirectlyActivated = react_1.useCallback((value) => {
|
71
|
+
dispatch({ type: 'isMenuDirectlyActivated', payload: value });
|
72
|
+
}, []);
|
73
|
+
const setSelectedItemLength = react_1.useCallback((value) => {
|
74
|
+
dispatch({ type: 'selectedItemLength', payload: value });
|
75
|
+
}, []);
|
76
|
+
const id = ssr_1.useSSRSafeId(idProp);
|
77
|
+
return (<AutocompleteContext_1.AutocompleteContext.Provider value={{
|
78
|
+
activeDescendantRef,
|
79
|
+
autocompleteSuggestion,
|
80
|
+
id,
|
81
|
+
inputRef,
|
82
|
+
inputValue,
|
83
|
+
isMenuDirectlyActivated,
|
84
|
+
scrollContainerRef,
|
85
|
+
selectedItemLength,
|
86
|
+
setAutocompleteSuggestion,
|
87
|
+
setInputValue,
|
88
|
+
setIsMenuDirectlyActivated,
|
89
|
+
setShowMenu,
|
90
|
+
setSelectedItemLength,
|
91
|
+
showMenu
|
92
|
+
}}>
|
93
|
+
{children}
|
94
|
+
</AutocompleteContext_1.AutocompleteContext.Provider>);
|
95
|
+
};
|
96
|
+
exports.default = Object.assign(Autocomplete, {
|
97
|
+
Input: AutocompleteInput_1.default,
|
98
|
+
Menu: AutocompleteMenu_1.default,
|
99
|
+
Overlay: AutocompleteOverlay_1.default
|
100
|
+
});
|
@@ -282,7 +282,6 @@ declare const AutocompleteInput: PolymorphicForwardRefComponent<React.ForwardRef
|
|
282
282
|
onAnimationIterationCapture?: React.AnimationEventHandler<HTMLSpanElement> | undefined;
|
283
283
|
onTransitionEnd?: React.TransitionEventHandler<HTMLSpanElement> | undefined;
|
284
284
|
onTransitionEndCapture?: React.TransitionEventHandler<HTMLSpanElement> | undefined;
|
285
|
-
css?: import("@emotion/core").InterpolationWithTheme<any>;
|
286
285
|
disabled?: boolean | undefined;
|
287
286
|
hasIcon?: boolean | undefined;
|
288
287
|
contrast?: boolean | undefined;
|
@@ -0,0 +1,113 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
5
|
+
}) : (function(o, m, k, k2) {
|
6
|
+
if (k2 === undefined) k2 = k;
|
7
|
+
o[k2] = m[k];
|
8
|
+
}));
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
11
|
+
}) : function(o, v) {
|
12
|
+
o["default"] = v;
|
13
|
+
});
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
15
|
+
if (mod && mod.__esModule) return mod;
|
16
|
+
var result = {};
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
18
|
+
__setModuleDefault(result, mod);
|
19
|
+
return result;
|
20
|
+
};
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
23
|
+
};
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
25
|
+
const react_1 = __importStar(require("react"));
|
26
|
+
const AutocompleteContext_1 = require("./AutocompleteContext");
|
27
|
+
const TextInput_1 = __importDefault(require("../TextInput"));
|
28
|
+
const useCombinedRefs_1 = require("../hooks/useCombinedRefs");
|
29
|
+
const AutocompleteInput = react_1.default.forwardRef(({ as: Component = TextInput_1.default, onFocus, onBlur, onChange, onKeyDown, onKeyUp, onKeyPress, value, ...props }, forwardedRef) => {
|
30
|
+
const autocompleteContext = react_1.useContext(AutocompleteContext_1.AutocompleteContext);
|
31
|
+
if (autocompleteContext === null) {
|
32
|
+
throw new Error('AutocompleteContext returned null values');
|
33
|
+
}
|
34
|
+
const { activeDescendantRef, autocompleteSuggestion = '', id, inputRef, inputValue = '', isMenuDirectlyActivated, setInputValue, setShowMenu, showMenu } = autocompleteContext;
|
35
|
+
const combinedInputRef = useCombinedRefs_1.useCombinedRefs(inputRef, forwardedRef);
|
36
|
+
const [highlightRemainingText, setHighlightRemainingText] = react_1.useState(true);
|
37
|
+
const handleInputFocus = react_1.useCallback(event => {
|
38
|
+
onFocus && onFocus(event);
|
39
|
+
setShowMenu(true);
|
40
|
+
}, [onFocus, setShowMenu]);
|
41
|
+
const handleInputBlur = react_1.useCallback(event => {
|
42
|
+
onBlur && onBlur(event);
|
43
|
+
// HACK: wait a tick and check the focused element before hiding the autocomplete menu
|
44
|
+
// this prevents the menu from hiding when the user is clicking an option in the Autoselect.Menu,
|
45
|
+
// but still hides the menu when the user blurs the input by tabbing out or clicking somewhere else on the page
|
46
|
+
setTimeout(() => {
|
47
|
+
if (document.activeElement !== combinedInputRef.current) {
|
48
|
+
setShowMenu(false);
|
49
|
+
}
|
50
|
+
}, 0);
|
51
|
+
}, [onBlur, setShowMenu, combinedInputRef]);
|
52
|
+
const handleInputChange = react_1.useCallback(event => {
|
53
|
+
onChange && onChange(event);
|
54
|
+
setInputValue(event.currentTarget.value);
|
55
|
+
if (!showMenu) {
|
56
|
+
setShowMenu(true);
|
57
|
+
}
|
58
|
+
}, [onChange, setInputValue, setShowMenu, showMenu]);
|
59
|
+
const handleInputKeyDown = react_1.useCallback(event => {
|
60
|
+
onKeyDown && onKeyDown(event);
|
61
|
+
if (event.key === 'Backspace') {
|
62
|
+
setHighlightRemainingText(false);
|
63
|
+
}
|
64
|
+
if (event.key === 'Escape' && inputRef.current?.value) {
|
65
|
+
setInputValue('');
|
66
|
+
inputRef.current.value = '';
|
67
|
+
}
|
68
|
+
}, [inputRef, setInputValue, setHighlightRemainingText, onKeyDown]);
|
69
|
+
const handleInputKeyUp = react_1.useCallback(event => {
|
70
|
+
onKeyUp && onKeyUp(event);
|
71
|
+
if (event.key === 'Backspace') {
|
72
|
+
setHighlightRemainingText(true);
|
73
|
+
}
|
74
|
+
}, [setHighlightRemainingText, onKeyUp]);
|
75
|
+
const onInputKeyPress = react_1.useCallback(event => {
|
76
|
+
onKeyPress && onKeyPress(event);
|
77
|
+
if (showMenu && event.key === 'Enter' && activeDescendantRef.current) {
|
78
|
+
event.preventDefault();
|
79
|
+
event.nativeEvent.stopImmediatePropagation();
|
80
|
+
// Forward Enter key press to active descendant so that item gets activated
|
81
|
+
const activeDescendantEvent = new KeyboardEvent(event.type, event.nativeEvent);
|
82
|
+
activeDescendantRef.current.dispatchEvent(activeDescendantEvent);
|
83
|
+
}
|
84
|
+
}, [activeDescendantRef, showMenu, onKeyPress]);
|
85
|
+
react_1.useEffect(() => {
|
86
|
+
if (!inputRef.current) {
|
87
|
+
return;
|
88
|
+
}
|
89
|
+
// resets input value to being empty after a selection has been made
|
90
|
+
if (!autocompleteSuggestion) {
|
91
|
+
inputRef.current.value = inputValue;
|
92
|
+
}
|
93
|
+
// TODO: fix bug where this function prevents `onChange` from being triggered if the highlighted item text
|
94
|
+
// is the same as what I'm typing
|
95
|
+
// e.g.: typing 'tw' highights 'two', but when I 'two', the text input change does not get triggered
|
96
|
+
if (highlightRemainingText && autocompleteSuggestion && (inputValue || isMenuDirectlyActivated)) {
|
97
|
+
inputRef.current.value = autocompleteSuggestion;
|
98
|
+
if (autocompleteSuggestion.toLowerCase().indexOf(inputValue.toLowerCase()) === 0) {
|
99
|
+
inputRef.current.setSelectionRange(inputValue.length, autocompleteSuggestion.length);
|
100
|
+
}
|
101
|
+
}
|
102
|
+
// calling this useEffeect when `highlightRemainingText` changes breaks backspace functionality
|
103
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
104
|
+
}, [autocompleteSuggestion, inputValue, inputRef, isMenuDirectlyActivated]);
|
105
|
+
react_1.useEffect(() => {
|
106
|
+
if (value) {
|
107
|
+
setInputValue(value.toString());
|
108
|
+
}
|
109
|
+
}, [value, setInputValue]);
|
110
|
+
return (<Component onFocus={handleInputFocus} onBlur={handleInputBlur} onChange={handleInputChange} onKeyDown={handleInputKeyDown} onKeyPress={onInputKeyPress} onKeyUp={handleInputKeyUp} ref={combinedInputRef} aria-controls={`${id}-listbox`} aria-autocomplete="both" role="combobox" aria-expanded={showMenu} aria-haspopup="listbox" aria-owns={`${id}-listbox`} autocomplete="off" {...props}/>);
|
111
|
+
});
|
112
|
+
AutocompleteInput.displayName = 'AutocompleteInput';
|
113
|
+
exports.default = AutocompleteInput;
|
@@ -21,10 +21,6 @@ var _uniqueId = require("../utils/uniqueId");
|
|
21
21
|
|
22
22
|
var _scrollIntoViewingArea = require("../behaviors/scrollIntoViewingArea");
|
23
23
|
|
24
|
-
var _VisuallyHidden = _interopRequireDefault(require("../_VisuallyHidden"));
|
25
|
-
|
26
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
27
|
-
|
28
24
|
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); }
|
29
25
|
|
30
26
|
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; }
|
@@ -186,8 +182,19 @@ function AutocompleteMenu(props) {
|
|
186
182
|
setSelectedItemLength(selectedItemIds.length);
|
187
183
|
}
|
188
184
|
}, [selectedItemIds, setSelectedItemLength]);
|
189
|
-
return /*#__PURE__*/_react.default.createElement(
|
190
|
-
|
185
|
+
return /*#__PURE__*/_react.default.createElement(_.Box, {
|
186
|
+
sx: !showMenu ? {
|
187
|
+
// visually hides this label for sighted users
|
188
|
+
position: 'absolute',
|
189
|
+
width: '1px',
|
190
|
+
height: '1px',
|
191
|
+
padding: '0',
|
192
|
+
margin: '-1px',
|
193
|
+
overflow: 'hidden',
|
194
|
+
clip: 'rect(0, 0, 0, 0)',
|
195
|
+
whiteSpace: 'nowrap',
|
196
|
+
borderWidth: '0'
|
197
|
+
} : {}
|
191
198
|
}, loading ? /*#__PURE__*/_react.default.createElement(_.Box, {
|
192
199
|
p: 3,
|
193
200
|
display: "flex",
|
@@ -0,0 +1,190 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
5
|
+
}) : (function(o, m, k, k2) {
|
6
|
+
if (k2 === undefined) k2 = k;
|
7
|
+
o[k2] = m[k];
|
8
|
+
}));
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
11
|
+
}) : function(o, v) {
|
12
|
+
o["default"] = v;
|
13
|
+
});
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
15
|
+
if (mod && mod.__esModule) return mod;
|
16
|
+
var result = {};
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
18
|
+
__setModuleDefault(result, mod);
|
19
|
+
return result;
|
20
|
+
};
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
22
|
+
const react_1 = __importStar(require("react"));
|
23
|
+
const ActionList_1 = require("../ActionList");
|
24
|
+
const useFocusZone_1 = require("../hooks/useFocusZone");
|
25
|
+
const __1 = require("../");
|
26
|
+
const AutocompleteContext_1 = require("./AutocompleteContext");
|
27
|
+
const octicons_react_1 = require("@primer/octicons-react");
|
28
|
+
const uniqueId_1 = require("../utils/uniqueId");
|
29
|
+
const scrollIntoViewingArea_1 = require("../behaviors/scrollIntoViewingArea");
|
30
|
+
const getDefaultSortFn = (isItemSelectedFn) => (itemIdA, itemIdB) => isItemSelectedFn(itemIdA) === isItemSelectedFn(itemIdB) ? 0 : isItemSelectedFn(itemIdA) ? -1 : 1;
|
31
|
+
function getDefaultItemFilter(filterValue) {
|
32
|
+
return function (item, _i) {
|
33
|
+
return Boolean(item.text?.toLowerCase().startsWith(filterValue.toLowerCase()));
|
34
|
+
};
|
35
|
+
}
|
36
|
+
function getDefaultOnSelectionChange(setInputValueFn) {
|
37
|
+
return function (itemOrItems) {
|
38
|
+
const { text = '' } = Array.isArray(itemOrItems) ? itemOrItems.slice(-1)[0] : itemOrItems;
|
39
|
+
setInputValueFn(text);
|
40
|
+
};
|
41
|
+
}
|
42
|
+
const isItemSelected = (itemId, selectedItemIds) => selectedItemIds.includes(itemId);
|
43
|
+
function getItemById(itemId, items) {
|
44
|
+
return items.find(item => item.id === itemId);
|
45
|
+
}
|
46
|
+
function AutocompleteMenu(props) {
|
47
|
+
const autocompleteContext = react_1.useContext(AutocompleteContext_1.AutocompleteContext);
|
48
|
+
if (autocompleteContext === null) {
|
49
|
+
throw new Error('AutocompleteContext returned null values');
|
50
|
+
}
|
51
|
+
const { activeDescendantRef, id, inputRef, inputValue = '', scrollContainerRef, setAutocompleteSuggestion, setShowMenu, setInputValue, setIsMenuDirectlyActivated, setSelectedItemLength, showMenu } = autocompleteContext;
|
52
|
+
const { items, selectedItemIds, sortOnCloseFn, emptyStateText, addNewItem, loading, selectionVariant, filterFn, 'aria-labelledby': ariaLabelledBy, onOpenChange, onSelectedChange, customScrollContainerRef } = props;
|
53
|
+
const listContainerRef = react_1.useRef(null);
|
54
|
+
const [highlightedItem, setHighlightedItem] = react_1.useState();
|
55
|
+
const [sortedItemIds, setSortedItemIds] = react_1.useState(items.map(({ id: itemId }) => itemId));
|
56
|
+
const selectableItems = react_1.useMemo(() => items.map(selectableItem => {
|
57
|
+
return {
|
58
|
+
...selectableItem,
|
59
|
+
role: 'option',
|
60
|
+
id: selectableItem.id,
|
61
|
+
selected: selectionVariant === 'multiple' ? selectedItemIds.includes(selectableItem.id) : undefined,
|
62
|
+
onAction: (item) => {
|
63
|
+
const otherSelectedItemIds = selectedItemIds.filter(selectedItemId => selectedItemId !== item.id);
|
64
|
+
const newSelectedItemIds = selectedItemIds.includes(item.id)
|
65
|
+
? otherSelectedItemIds
|
66
|
+
: [...otherSelectedItemIds, item.id];
|
67
|
+
const onSelectedChangeFn = onSelectedChange ? onSelectedChange : getDefaultOnSelectionChange(setInputValue);
|
68
|
+
onSelectedChangeFn(newSelectedItemIds.map(newSelectedItemId => getItemById(newSelectedItemId, items)));
|
69
|
+
if (selectionVariant === 'multiple') {
|
70
|
+
setInputValue('');
|
71
|
+
setAutocompleteSuggestion('');
|
72
|
+
}
|
73
|
+
else {
|
74
|
+
setShowMenu(false);
|
75
|
+
inputRef.current?.setSelectionRange(inputRef.current.value.length, inputRef.current.value.length);
|
76
|
+
}
|
77
|
+
}
|
78
|
+
};
|
79
|
+
}), [
|
80
|
+
items,
|
81
|
+
selectedItemIds,
|
82
|
+
inputRef,
|
83
|
+
onSelectedChange,
|
84
|
+
selectionVariant,
|
85
|
+
setAutocompleteSuggestion,
|
86
|
+
setInputValue,
|
87
|
+
setShowMenu
|
88
|
+
]);
|
89
|
+
const itemSortOrderData = react_1.useMemo(() => sortedItemIds.reduce((acc, curr, i) => {
|
90
|
+
acc[curr] = i;
|
91
|
+
return acc;
|
92
|
+
}, {}), [sortedItemIds]);
|
93
|
+
const sortedAndFilteredItemsToRender = react_1.useMemo(() => selectableItems
|
94
|
+
.filter(filterFn ? filterFn : getDefaultItemFilter(inputValue))
|
95
|
+
.sort((a, b) => itemSortOrderData[a.id] - itemSortOrderData[b.id]), [selectableItems, itemSortOrderData, filterFn, inputValue]);
|
96
|
+
const allItemsToRender = react_1.useMemo(() => [
|
97
|
+
// sorted and filtered selectable items
|
98
|
+
...sortedAndFilteredItemsToRender,
|
99
|
+
// menu item used for creating a token from whatever is in the text input
|
100
|
+
...(addNewItem
|
101
|
+
? [
|
102
|
+
{
|
103
|
+
...addNewItem,
|
104
|
+
leadingVisual: () => <octicons_react_1.PlusIcon />,
|
105
|
+
onAction: (item) => {
|
106
|
+
// TODO: make it possible to pass a leadingVisual when using `addNewItem`
|
107
|
+
addNewItem.handleAddItem({ ...item, id: item.id || uniqueId_1.uniqueId(), leadingVisual: undefined });
|
108
|
+
if (selectionVariant === 'multiple') {
|
109
|
+
setInputValue('');
|
110
|
+
setAutocompleteSuggestion('');
|
111
|
+
}
|
112
|
+
}
|
113
|
+
}
|
114
|
+
]
|
115
|
+
: [])
|
116
|
+
], [sortedAndFilteredItemsToRender, addNewItem, setAutocompleteSuggestion, selectionVariant, setInputValue]);
|
117
|
+
useFocusZone_1.useFocusZone({
|
118
|
+
containerRef: listContainerRef,
|
119
|
+
focusOutBehavior: 'wrap',
|
120
|
+
focusableElementFilter: element => {
|
121
|
+
return !(element instanceof HTMLInputElement);
|
122
|
+
},
|
123
|
+
activeDescendantFocus: inputRef,
|
124
|
+
onActiveDescendantChanged: (current, _previous, directlyActivated) => {
|
125
|
+
activeDescendantRef.current = current || null;
|
126
|
+
if (current) {
|
127
|
+
const selectedItem = selectableItems.find(item => item.id.toString() === current.getAttribute('data-id'));
|
128
|
+
setHighlightedItem(selectedItem);
|
129
|
+
setIsMenuDirectlyActivated(directlyActivated);
|
130
|
+
}
|
131
|
+
if (current && customScrollContainerRef && customScrollContainerRef.current && directlyActivated) {
|
132
|
+
scrollIntoViewingArea_1.scrollIntoViewingArea(current, customScrollContainerRef.current);
|
133
|
+
}
|
134
|
+
else if (current && scrollContainerRef.current && directlyActivated) {
|
135
|
+
scrollIntoViewingArea_1.scrollIntoViewingArea(current, scrollContainerRef.current);
|
136
|
+
}
|
137
|
+
}
|
138
|
+
}, [loading]);
|
139
|
+
react_1.useEffect(() => {
|
140
|
+
if (highlightedItem?.text?.startsWith(inputValue) && !selectedItemIds.includes(highlightedItem.id)) {
|
141
|
+
setAutocompleteSuggestion(highlightedItem.text);
|
142
|
+
}
|
143
|
+
else {
|
144
|
+
setAutocompleteSuggestion('');
|
145
|
+
}
|
146
|
+
}, [highlightedItem, inputValue, selectedItemIds, setAutocompleteSuggestion]);
|
147
|
+
react_1.useEffect(() => {
|
148
|
+
const itemIdSortResult = [...sortedItemIds].sort(sortOnCloseFn ? sortOnCloseFn : getDefaultSortFn(itemId => isItemSelected(itemId, selectedItemIds)));
|
149
|
+
const sortResultMatchesState = itemIdSortResult.length === sortedItemIds.length &&
|
150
|
+
itemIdSortResult.every((element, index) => element === sortedItemIds[index]);
|
151
|
+
if (showMenu === false && !sortResultMatchesState) {
|
152
|
+
setSortedItemIds(itemIdSortResult);
|
153
|
+
}
|
154
|
+
onOpenChange && onOpenChange(Boolean(showMenu));
|
155
|
+
}, [showMenu, onOpenChange, selectedItemIds, sortOnCloseFn, sortedItemIds]);
|
156
|
+
react_1.useEffect(() => {
|
157
|
+
if (selectedItemIds.length) {
|
158
|
+
setSelectedItemLength(selectedItemIds.length);
|
159
|
+
}
|
160
|
+
}, [selectedItemIds, setSelectedItemLength]);
|
161
|
+
return (<__1.Box sx={!showMenu
|
162
|
+
? {
|
163
|
+
// visually hides this label for sighted users
|
164
|
+
position: 'absolute',
|
165
|
+
width: '1px',
|
166
|
+
height: '1px',
|
167
|
+
padding: '0',
|
168
|
+
margin: '-1px',
|
169
|
+
overflow: 'hidden',
|
170
|
+
clip: 'rect(0, 0, 0, 0)',
|
171
|
+
whiteSpace: 'nowrap',
|
172
|
+
borderWidth: '0'
|
173
|
+
}
|
174
|
+
: {}}>
|
175
|
+
{loading ? (<__1.Box p={3} display="flex" justifyContent="center">
|
176
|
+
<__1.Spinner />
|
177
|
+
</__1.Box>) : (<div ref={listContainerRef}>
|
178
|
+
{allItemsToRender.length ? (<ActionList_1.ActionList selectionVariant="multiple"
|
179
|
+
// have to typecast to `ItemProps` because we have an extra property
|
180
|
+
// on `items` for Autocomplete: `metadata`
|
181
|
+
items={allItemsToRender} role="listbox" id={`${id}-listbox`} aria-labelledby={ariaLabelledBy}/>) : (<__1.Box p={3}>{emptyStateText}</__1.Box>)}
|
182
|
+
</div>)}
|
183
|
+
</__1.Box>);
|
184
|
+
}
|
185
|
+
AutocompleteMenu.defaultProps = {
|
186
|
+
emptyStateText: 'No selectable options',
|
187
|
+
selectionVariant: 'single'
|
188
|
+
};
|
189
|
+
AutocompleteMenu.displayName = 'AutocompleteMenu';
|
190
|
+
exports.default = AutocompleteMenu;
|