@astryxdesign/core 0.5.0 → 0.5.1-canary.046f6ea
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 +222 -0
- package/dist/AlertDialog/AlertDialog.d.ts +1 -1
- package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
- package/dist/AlertDialog/AlertDialog.js +45 -20
- package/dist/AspectRatio/AspectRatio.d.ts +6 -6
- package/dist/Avatar/Avatar.d.ts +25 -1
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +43 -9
- package/dist/Avatar/index.d.ts +2 -2
- package/dist/Avatar/index.d.ts.map +1 -1
- package/dist/Avatar/index.js +1 -1
- package/dist/AvatarGroup/AvatarGroup.d.ts +9 -2
- package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroup.js +5 -2
- package/dist/AvatarGroup/AvatarGroupContext.d.ts +2 -1
- package/dist/AvatarGroup/AvatarGroupContext.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.js +11 -7
- package/dist/Badge/Badge.d.ts.map +1 -1
- package/dist/Badge/Badge.js +26 -2
- package/dist/Banner/Banner.d.ts +10 -1
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +11 -2
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +8 -7
- package/dist/Calendar/Calendar.d.ts +4 -2
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +15 -21
- package/dist/Calendar/hooks/useCalendarDays.js +4 -6
- package/dist/Calendar/hooks/useCalendarNavigation.js +4 -6
- package/dist/Calendar/styles.d.ts +5 -20
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +15 -17
- package/dist/Card/Card.d.ts +12 -12
- package/dist/Card/Card.d.ts.map +1 -1
- package/dist/Card/Card.js +17 -9
- package/dist/Card/index.d.ts +35 -1
- package/dist/Card/index.d.ts.map +1 -1
- package/dist/Card/index.js +21 -1
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +108 -7
- package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
- package/dist/CheckboxInput/CheckboxInput.js +7 -1
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +15 -4
- package/dist/CodeBlock/highlightRanges.js +1 -1
- package/dist/CodeBlock/highlightStyles.js +13 -13
- package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteItem.js +2 -7
- package/dist/ComplexSelector/ComplexSelector.d.ts +10 -2
- package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
- package/dist/ComplexSelector/ComplexSelector.js +14 -7
- package/dist/DateInput/DateInput.d.ts +43 -0
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +22 -5
- package/dist/DateInput/MonthScroller.d.ts.map +1 -1
- package/dist/DateInput/MonthScroller.js +5 -3
- package/dist/DateInput/MonthYearWheels.d.ts.map +1 -1
- package/dist/DateInput/MonthYearWheels.js +6 -4
- package/dist/DateInput/NativeDateField.d.ts +10 -0
- package/dist/DateInput/NativeDateField.d.ts.map +1 -0
- package/dist/DateInput/NativeDateField.js +494 -0
- package/dist/DateInput/TouchDateField.d.ts.map +1 -1
- package/dist/DateInput/TouchDateField.js +52 -25
- package/dist/DateInput/Wheel.d.ts.map +1 -1
- package/dist/DateInput/Wheel.js +1 -0
- package/dist/DateInput/index.d.ts +1 -1
- package/dist/DateInput/index.d.ts.map +1 -1
- package/dist/DateInput/nativeDateSegments.d.ts +22 -0
- package/dist/DateInput/nativeDateSegments.d.ts.map +1 -0
- package/dist/DateInput/nativeDateSegments.js +111 -0
- package/dist/DateRangeInput/DateRangeInput.d.ts +4 -2
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +3 -5
- package/dist/DateTimeInput/DateTimeInput.d.ts +23 -24
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +35 -10
- package/dist/DateTimeInput/TouchDateTimeField.d.ts +6 -0
- package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -0
- package/dist/DateTimeInput/TouchDateTimeField.js +1021 -0
- package/dist/Dialog/Dialog.d.ts +16 -2
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +28 -7
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +4 -13
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +9 -1
- package/dist/Field/InputClearButton.d.ts +9 -3
- package/dist/Field/InputClearButton.d.ts.map +1 -1
- package/dist/Field/InputClearButton.js +14 -3
- package/dist/Heading/Heading.d.ts.map +1 -1
- package/dist/Heading/Heading.js +0 -1
- package/dist/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/HoverCard/HoverCard.js +104 -3
- package/dist/HoverCard/useHoverCard.d.ts +14 -2
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +7 -1
- package/dist/Icon/Icon.d.ts +4 -2
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/defaultIcons.d.ts +3 -2
- package/dist/Icon/defaultIcons.d.ts.map +1 -1
- package/dist/Icon/defaultIcons.js +7 -0
- package/dist/Icon/globalIconRegistry.d.ts +13 -0
- package/dist/Icon/globalIconRegistry.d.ts.map +1 -1
- package/dist/Icon/globalIconRegistry.js +34 -6
- package/dist/Icon/index.d.ts +1 -1
- package/dist/Icon/index.d.ts.map +1 -1
- package/dist/Icon/useIcon.d.ts +5 -2
- package/dist/Icon/useIcon.d.ts.map +1 -1
- package/dist/Icon/useIcon.js +3 -0
- package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
- package/dist/Indicator/CheckboxIndicator.js +6 -2
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +2 -2
- package/dist/Kbd/Kbd.d.ts.map +1 -1
- package/dist/Kbd/Kbd.js +2 -26
- package/dist/Layer/gestureCounter.d.ts +8 -0
- package/dist/Layer/gestureCounter.d.ts.map +1 -0
- package/dist/Layer/gestureCounter.js +53 -0
- package/dist/Layer/useLayer.d.ts +23 -13
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +146 -24
- package/dist/List/List.d.ts +1 -1
- package/dist/List/List.d.ts.map +1 -1
- package/dist/List/List.js +15 -4
- package/dist/Markdown/Markdown.d.ts +1 -1
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +20 -7
- package/dist/Markdown/parser.d.ts.map +1 -1
- package/dist/Markdown/parser.js +5 -3
- package/dist/MetadataList/MetadataListItem.d.ts +1 -1
- package/dist/MetadataList/MetadataListItem.d.ts.map +1 -1
- package/dist/MetadataList/MetadataListItem.js +4 -1
- package/dist/MultiSelector/MultiSelector.d.ts +18 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +58 -11
- package/dist/MultiSelector/hooks.d.ts +7 -1
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +3 -2
- package/dist/NavIcon/NavIcon.d.ts.map +1 -1
- package/dist/NavIcon/NavIcon.js +5 -1
- package/dist/NavItem/navItemStyles.stylex.d.ts +0 -8
- package/dist/NavItem/navItemStyles.stylex.d.ts.map +1 -1
- package/dist/NavItem/navItemStyles.stylex.js +0 -2
- package/dist/NavMenu/NavHeadingMenu.d.ts +1 -1
- package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
- package/dist/NavMenu/NavHeadingMenu.js +7 -4
- package/dist/NumberInput/NumberInput.d.ts +6 -1
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +95 -126
- package/dist/NumberInput/numberInputCommit.d.ts +34 -0
- package/dist/NumberInput/numberInputCommit.d.ts.map +1 -0
- package/dist/NumberInput/numberInputCommit.js +71 -0
- package/dist/NumberInput/numberParser.d.ts +64 -0
- package/dist/NumberInput/numberParser.d.ts.map +1 -0
- package/dist/NumberInput/numberParser.js +350 -0
- package/dist/Outline/Outline.d.ts.map +1 -1
- package/dist/Outline/Outline.js +2 -3
- package/dist/OverflowList/OverflowList.d.ts +41 -1
- package/dist/OverflowList/OverflowList.d.ts.map +1 -1
- package/dist/OverflowList/OverflowList.js +43 -2
- package/dist/Popover/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +8 -14
- package/dist/Popover/usePopover.d.ts +15 -41
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +26 -7
- package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearchValueEditor.js +91 -18
- package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
- package/dist/PowerSearch/formatFilterValue.js +4 -2
- package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar/ProgressBar.js +18 -5
- package/dist/Resizable/useResizable.d.ts +19 -1
- package/dist/Resizable/useResizable.d.ts.map +1 -1
- package/dist/Resizable/useResizable.js +104 -38
- package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
- package/dist/SelectableCard/SelectableCard.js +9 -0
- package/dist/Selector/Selector.d.ts +18 -1
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +92 -21
- package/dist/Selector/hooks.d.ts +7 -1
- package/dist/Selector/hooks.d.ts.map +1 -1
- package/dist/Selector/hooks.js +3 -2
- package/dist/SideNav/SideNav.d.ts +6 -1
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +57 -27
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +5 -4
- package/dist/SideNav/SideNavItem.d.ts +29 -4
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +75 -20
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +34 -2
- package/dist/Spinner/Spinner.d.ts +3 -1
- package/dist/Spinner/Spinner.d.ts.map +1 -1
- package/dist/Spinner/Spinner.js +199 -20
- package/dist/StatusDot/StatusDot.d.ts.map +1 -1
- package/dist/StatusDot/StatusDot.js +6 -1
- package/dist/Stepper/Step.d.ts.map +1 -1
- package/dist/Stepper/Step.js +7 -6
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +5 -1
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +6 -1
- package/dist/Table/Table.d.ts.map +1 -1
- package/dist/Table/Table.js +3 -6
- package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
- package/dist/Table/plugins/filtering/useTableFiltering.js +73 -4
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +26 -0
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +34 -3
- package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
- package/dist/Table/plugins/selection/useTableSelection.js +25 -1
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +3 -4
- package/dist/Text/Text.d.ts.map +1 -1
- package/dist/Text/Text.js +0 -1
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +13 -8
- package/dist/Timestamp/Timestamp.d.ts +1 -1
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +10 -18
- package/dist/Timestamp/formatInstant.d.ts.map +1 -1
- package/dist/Timestamp/formatInstant.js +10 -5
- package/dist/Toast/Toast.d.ts +17 -2
- package/dist/Toast/Toast.d.ts.map +1 -1
- package/dist/Toast/Toast.js +77 -11
- package/dist/Toast/ToastViewport.d.ts +1 -0
- package/dist/Toast/ToastViewport.d.ts.map +1 -1
- package/dist/Toast/ToastViewport.js +76 -21
- package/dist/Toast/index.d.ts +1 -1
- package/dist/Toast/index.d.ts.map +1 -1
- package/dist/Toast/types.d.ts +38 -0
- package/dist/Toast/types.d.ts.map +1 -1
- package/dist/Toast/useToastGesture.d.ts +26 -0
- package/dist/Toast/useToastGesture.d.ts.map +1 -0
- package/dist/Toast/useToastGesture.js +223 -0
- package/dist/Token/Token.d.ts +1 -1
- package/dist/Token/Token.d.ts.map +1 -1
- package/dist/Token/Token.js +23 -12
- package/dist/Token/TokenLink.d.ts +1 -1
- package/dist/Token/TokenLink.d.ts.map +1 -1
- package/dist/Token/TokenLink.js +5 -2
- package/dist/Tokenizer/Tokenizer.d.ts +12 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +31 -21
- package/dist/TopNav/TopNavHeading.js +2 -2
- package/dist/TopNav/TopNavItem.d.ts.map +1 -1
- package/dist/TopNav/TopNavItem.js +3 -3
- package/dist/TopNav/TopNavMegaMenu.d.ts +1 -1
- package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenu.js +30 -9
- package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenuItem.js +3 -3
- package/dist/TopNav/TopNavMenu.d.ts +1 -1
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +21 -6
- package/dist/TreeList/TreeList.d.ts +1 -1
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +7 -2
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +2 -2
- package/dist/Typeahead/BaseTypeahead.d.ts +33 -0
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +51 -8
- package/dist/Typeahead/Typeahead.d.ts +8 -1
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +2 -0
- package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
- package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
- package/dist/Typeahead/TypeaheadItem.js +7 -2
- package/dist/astryx.css +87 -22
- package/dist/hooks/useHotkeys.d.ts.map +1 -1
- package/dist/hooks/useHotkeys.js +3 -25
- package/dist/hooks/useOverflow.d.ts.map +1 -1
- package/dist/hooks/useOverflow.js +14 -4
- package/dist/i18n/InternationalizationContext.d.ts +2 -0
- package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
- package/dist/i18n/InternationalizationContext.js +3 -1
- package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
- package/dist/i18n/InternationalizationProvider.js +3 -1
- package/dist/i18n/resolve.d.ts +1 -1
- package/dist/i18n/resolve.d.ts.map +1 -1
- package/dist/i18n/resolve.js +37 -38
- package/dist/i18n/useTranslator.d.ts.map +1 -1
- package/dist/i18n/useTranslator.js +2 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/theme/Theme.d.ts.map +1 -1
- package/dist/theme/Theme.js +46 -10
- package/dist/theme/defineTheme.d.ts +9 -3
- package/dist/theme/defineTheme.d.ts.map +1 -1
- package/dist/theme/defineTheme.js +5 -0
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +24 -4
- package/dist/theme/generateThemeRules.d.ts +21 -0
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +26 -0
- package/dist/theme/syntax/tokens.d.ts +1 -1
- package/dist/theme/syntax/tokens.d.ts.map +1 -1
- package/dist/theme/syntax/tokens.js +5 -2
- package/dist/theme/useTheme.d.ts.map +1 -1
- package/dist/theme/useTheme.js +6 -7
- package/dist/utils/dateParser.d.ts +5 -8
- package/dist/utils/dateParser.d.ts.map +1 -1
- package/dist/utils/dateParser.js +10 -11
- package/dist/utils/focusOutline.stylex.d.ts +25 -0
- package/dist/utils/focusOutline.stylex.d.ts.map +1 -1
- package/dist/utils/focusOutline.stylex.js +15 -0
- package/dist/utils/interactionOverlay.stylex.d.ts +26 -0
- package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -0
- package/dist/utils/interactionOverlay.stylex.js +42 -0
- package/dist/utils/isApplePlatform.d.ts +18 -0
- package/dist/utils/isApplePlatform.d.ts.map +1 -0
- package/dist/utils/isApplePlatform.js +37 -0
- package/dist/utils/plainDate.d.ts +11 -0
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +20 -4
- package/locales/af-ZA.json +7 -7
- package/locales/ar-SA.json +7 -7
- package/locales/ca-ES.json +6 -6
- package/locales/cs-CZ.json +7 -7
- package/locales/da-DK.json +7 -7
- package/locales/de-DE.json +7 -7
- package/locales/el-GR.json +7 -7
- package/locales/en.json +178 -6
- package/locales/es-ES.json +6 -6
- package/locales/fi-FI.json +7 -7
- package/locales/fr-FR.json +7 -7
- package/locales/he-IL.json +7 -7
- package/locales/hu-HU.json +7 -7
- package/locales/it-IT.json +7 -7
- package/locales/ja-JP.json +7 -7
- package/locales/ko-KR.json +7 -7
- package/locales/nl-NL.json +7 -7
- package/locales/no-NO.json +7 -7
- package/locales/pl-PL.json +7 -7
- package/locales/pseudo.json +130 -1
- package/locales/pt-BR.json +7 -7
- package/locales/pt-PT.json +7 -7
- package/locales/ro-RO.json +7 -7
- package/locales/ru-RU.json +7 -7
- package/locales/sr-SP.json +7 -7
- package/locales/sv-SE.json +7 -7
- package/locales/tr-TR.json +7 -7
- package/locales/uk-UA.json +7 -7
- package/locales/vi-VN.json +7 -7
- package/locales/zh-CN.json +7 -7
- package/locales/zh-TW.json +7 -7
- package/package.json +4 -5
- package/src/AlertDialog/AlertDialog.doc.mjs +114 -30
- package/src/AlertDialog/AlertDialog.test.tsx +211 -2
- package/src/AlertDialog/AlertDialog.tsx +62 -20
- package/src/AspectRatio/AspectRatio.doc.mjs +3 -3
- package/src/AspectRatio/AspectRatio.tsx +6 -6
- package/src/Avatar/Avatar.doc.mjs +12 -2
- package/src/Avatar/Avatar.test.tsx +80 -0
- package/src/Avatar/Avatar.tsx +64 -14
- package/src/Avatar/index.ts +2 -2
- package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
- package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
- package/src/AvatarGroup/AvatarGroup.tsx +12 -4
- package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +12 -12
- package/src/Badge/Badge.doc.mjs +3 -2
- package/src/Badge/Badge.test.tsx +32 -3
- package/src/Badge/Badge.tsx +42 -1
- package/src/Banner/Banner.doc.mjs +9 -0
- package/src/Banner/Banner.test.tsx +76 -11
- package/src/Banner/Banner.tsx +21 -2
- package/src/Button/Button.doc.mjs +2 -1
- package/src/Button/Button.test.tsx +19 -4
- package/src/Button/Button.tsx +9 -29
- package/src/ButtonGroup/ButtonGroup.doc.mjs +2 -2
- package/src/ButtonGroup/ButtonGroup.test.tsx +13 -0
- package/src/Calendar/Calendar.doc.mjs +4 -4
- package/src/Calendar/Calendar.test.tsx +112 -0
- package/src/Calendar/Calendar.tsx +18 -16
- package/src/Calendar/hooks/useCalendarDays.ts +4 -4
- package/src/Calendar/hooks/useCalendarNavigation.ts +4 -4
- package/src/Calendar/styles.ts +48 -42
- package/src/Card/Card.doc.mjs +10 -7
- package/src/Card/Card.test.tsx +113 -19
- package/src/Card/Card.tsx +67 -89
- package/src/Card/index.ts +36 -1
- package/src/Carousel/Carousel.doc.mjs +3 -0
- package/src/Carousel/Carousel.test.tsx +360 -0
- package/src/Carousel/Carousel.tsx +116 -15
- package/src/CheckboxInput/CheckboxInput.doc.mjs +3 -1
- package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
- package/src/CheckboxInput/CheckboxInput.tsx +5 -0
- package/src/CheckboxList/CheckboxList.doc.mjs +1 -1
- package/src/CodeBlock/CodeBlock.doc.mjs +10 -4
- package/src/CodeBlock/CodeBlock.test.tsx +37 -0
- package/src/CodeBlock/CodeBlock.tsx +20 -4
- package/src/CodeBlock/highlightRanges.ts +1 -1
- package/src/CodeBlock/highlightStyles.ts +13 -13
- package/src/CommandPalette/CommandPaletteItem.tsx +2 -12
- package/src/ComplexSelector/ComplexSelector.doc.mjs +9 -2
- package/src/ComplexSelector/ComplexSelector.test.tsx +183 -0
- package/src/ComplexSelector/ComplexSelector.tsx +22 -12
- package/src/DateInput/DateInput.doc.mjs +17 -1
- package/src/DateInput/DateInput.test.tsx +9 -4
- package/src/DateInput/DateInput.tsx +54 -3
- package/src/DateInput/DateInputTouch.test.tsx +146 -32
- package/src/DateInput/MonthScroller.tsx +5 -1
- package/src/DateInput/MonthYearWheels.tsx +7 -4
- package/src/DateInput/NativeDateField.test.tsx +635 -0
- package/src/DateInput/NativeDateField.tsx +641 -0
- package/src/DateInput/TouchDateField.tsx +83 -33
- package/src/DateInput/Wheel.tsx +1 -0
- package/src/DateInput/index.ts +1 -0
- package/src/DateInput/nativeDateSegments.ts +127 -0
- package/src/DateRangeInput/DateRangeInput.doc.mjs +3 -3
- package/src/DateRangeInput/DateRangeInput.test.tsx +46 -0
- package/src/DateRangeInput/DateRangeInput.tsx +8 -13
- package/src/DateTimeInput/DateTimeInput.doc.mjs +39 -22
- package/src/DateTimeInput/DateTimeInput.test.tsx +76 -0
- package/src/DateTimeInput/DateTimeInput.tsx +54 -20
- package/src/DateTimeInput/DateTimeInputTouch.test.tsx +980 -0
- package/src/DateTimeInput/TouchDateTimeField.tsx +1437 -0
- package/src/Dialog/Dialog.test.tsx +185 -18
- package/src/Dialog/Dialog.tsx +35 -11
- package/src/DropdownMenu/DropdownMenu.test.tsx +44 -10
- package/src/DropdownMenu/DropdownMenu.tsx +4 -13
- package/src/Field/Field.doc.mjs +1 -1
- package/src/Field/FieldLabel.test.tsx +29 -0
- package/src/Field/FieldLabel.tsx +7 -0
- package/src/Field/InputClearButton.test.tsx +15 -1
- package/src/Field/InputClearButton.tsx +28 -4
- package/src/FieldStatus/FieldStatus.doc.mjs +1 -1
- package/src/FileInput/FileInput.doc.mjs +1 -1
- package/src/Heading/Heading.tsx +0 -1
- package/src/HoverCard/HoverCard.doc.mjs +8 -2
- package/src/HoverCard/HoverCard.test.tsx +154 -4
- package/src/HoverCard/HoverCard.tsx +137 -3
- package/src/HoverCard/useHoverCard.tsx +23 -3
- package/src/Icon/Icon.test.tsx +55 -1
- package/src/Icon/Icon.tsx +5 -3
- package/src/Icon/defaultIcons.tsx +11 -2
- package/src/Icon/globalIconRegistry.test.tsx +16 -3
- package/src/Icon/globalIconRegistry.tsx +37 -6
- package/src/Icon/index.ts +1 -0
- package/src/Icon/useIcon.ts +9 -2
- package/src/Indicator/CheckboxIndicator.tsx +14 -8
- package/src/Indicator/Indicator.doc.mjs +3 -1
- package/src/InputGroup/InputGroup.doc.mjs +1 -1
- package/src/Item/Item.tsx +2 -7
- package/src/Kbd/Kbd.test.tsx +0 -17
- package/src/Kbd/Kbd.tsx +2 -26
- package/src/Layer/gestureCounter.ts +57 -0
- package/src/Layer/useLayer.test.tsx +368 -16
- package/src/Layer/useLayer.tsx +208 -35
- package/src/Layout/__tests__/edgeCompensation.test.tsx +1 -1
- package/src/List/List.test.tsx +38 -0
- package/src/List/List.tsx +8 -1
- package/src/Markdown/Markdown.test.tsx +37 -0
- package/src/Markdown/Markdown.tsx +16 -5
- package/src/Markdown/parser.test.ts +33 -0
- package/src/Markdown/parser.ts +9 -3
- package/src/MetadataList/MetadataList.test.tsx +75 -2
- package/src/MetadataList/MetadataListItem.tsx +5 -2
- package/src/MultiSelector/MultiSelector.doc.mjs +23 -2
- package/src/MultiSelector/MultiSelector.test.tsx +205 -0
- package/src/MultiSelector/MultiSelector.tsx +103 -16
- package/src/MultiSelector/hooks.ts +9 -2
- package/src/NavIcon/NavIcon.doc.mjs +8 -2
- package/src/NavIcon/NavIcon.test.tsx +9 -0
- package/src/NavIcon/NavIcon.tsx +5 -1
- package/src/NavItem/navItemStyles.stylex.ts +0 -8
- package/src/NavMenu/NavHeadingMenu.test.tsx +30 -0
- package/src/NavMenu/NavHeadingMenu.tsx +7 -4
- package/src/NumberInput/NumberInput.doc.mjs +27 -8
- package/src/NumberInput/NumberInput.test.tsx +563 -8
- package/src/NumberInput/NumberInput.tsx +77 -131
- package/src/NumberInput/numberInputCommit.test.ts +72 -0
- package/src/NumberInput/numberInputCommit.ts +103 -0
- package/src/NumberInput/numberParser.docblock.test.ts +234 -0
- package/src/NumberInput/numberParser.test.ts +222 -0
- package/src/NumberInput/numberParser.ts +403 -0
- package/src/Outline/Outline.tsx +2 -4
- package/src/OverflowList/OverflowList.doc.mjs +102 -21
- package/src/OverflowList/OverflowList.test.tsx +550 -4
- package/src/OverflowList/OverflowList.tsx +100 -2
- package/src/Pagination/Pagination.test.tsx +3 -2
- package/src/Popover/Popover.doc.mjs +2 -2
- package/src/Popover/Popover.test.tsx +38 -0
- package/src/Popover/Popover.tsx +28 -66
- package/src/Popover/usePopover.tsx +44 -5
- package/src/PowerSearch/PowerSearch.doc.mjs +1 -1
- package/src/PowerSearch/PowerSearchEditPopover.test.tsx +87 -0
- package/src/PowerSearch/PowerSearchValueEditor.test.tsx +64 -0
- package/src/PowerSearch/PowerSearchValueEditor.tsx +109 -10
- package/src/PowerSearch/formatFilterValue.test.ts +16 -1
- package/src/PowerSearch/formatFilterValue.ts +2 -0
- package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
- package/src/ProgressBar/ProgressBar.test.tsx +24 -0
- package/src/ProgressBar/ProgressBar.tsx +28 -8
- package/src/RadioList/RadioList.doc.mjs +1 -1
- package/src/Resizable/Resizable.doc.mjs +2 -2
- package/src/Resizable/useResizable.doc.mjs +21 -2
- package/src/Resizable/useResizable.test.ts +421 -0
- package/src/Resizable/useResizable.ts +133 -48
- package/src/SelectableCard/SelectableCard.doc.mjs +3 -0
- package/src/SelectableCard/SelectableCard.tsx +16 -0
- package/src/Selector/Selector.doc.mjs +15 -1
- package/src/Selector/Selector.source-build.test.mjs +65 -0
- package/src/Selector/Selector.test.tsx +301 -0
- package/src/Selector/Selector.tsx +145 -32
- package/src/Selector/hooks.ts +17 -2
- package/src/SideNav/SideNav.doc.mjs +2 -2
- package/src/SideNav/SideNav.test.tsx +1069 -6
- package/src/SideNav/SideNav.tsx +109 -38
- package/src/SideNav/SideNavHeading.tsx +5 -2
- package/src/SideNav/SideNavItem.doc.mjs +24 -3
- package/src/SideNav/SideNavItem.tsx +134 -44
- package/src/Slider/Slider.doc.mjs +2 -2
- package/src/Slider/Slider.test.tsx +106 -1
- package/src/Slider/Slider.tsx +52 -1
- package/src/Spinner/Spinner.doc.mjs +17 -5
- package/src/Spinner/Spinner.test.tsx +164 -0
- package/src/Spinner/Spinner.tsx +252 -22
- package/src/StatusDot/StatusDot.doc.mjs +8 -2
- package/src/StatusDot/StatusDot.test.tsx +9 -0
- package/src/StatusDot/StatusDot.tsx +7 -1
- package/src/Stepper/Step.doc.mjs +1 -1
- package/src/Stepper/Step.tsx +7 -14
- package/src/Switch/Switch.doc.mjs +3 -1
- package/src/Switch/Switch.test.tsx +10 -0
- package/src/Switch/Switch.tsx +3 -0
- package/src/Table/BaseTable.tsx +6 -1
- package/src/Table/Table.doc.mjs +5 -3
- package/src/Table/Table.tsx +3 -8
- package/src/Table/TableBody.doc.mjs +2 -2
- package/src/Table/TableFooter.doc.mjs +1 -1
- package/src/Table/TableHeader.doc.mjs +1 -1
- package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
- package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
- package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +50 -4
- package/src/Table/plugins/selection/useTableSelection.test.tsx +62 -0
- package/src/Table/plugins/selection/useTableSelection.tsx +25 -2
- package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
- package/src/Table/useTableGroupedRows.doc.mjs +3 -3
- package/src/Table/useTablePagination.doc.mjs +1 -1
- package/src/Table/useTableSelection.doc.mjs +1 -1
- package/src/Text/Text.test.tsx +44 -0
- package/src/Text/Text.tsx +0 -1
- package/src/TextArea/TextArea.doc.mjs +13 -3
- package/src/TextArea/TextArea.test.tsx +11 -0
- package/src/TextArea/TextArea.tsx +34 -22
- package/src/TextInput/TextInput.doc.mjs +1 -1
- package/src/TimeInput/TimeInput.doc.mjs +1 -1
- package/src/Timestamp/Timestamp.test.tsx +89 -0
- package/src/Timestamp/Timestamp.tsx +8 -8
- package/src/Timestamp/formatInstant.ts +5 -0
- package/src/Toast/Toast.doc.mjs +213 -44
- package/src/Toast/Toast.tsx +118 -23
- package/src/Toast/ToastViewport.test.tsx +1434 -8
- package/src/Toast/ToastViewport.tsx +85 -14
- package/src/Toast/index.ts +2 -0
- package/src/Toast/types.ts +43 -5
- package/src/Toast/useToastGesture.ts +361 -0
- package/src/Token/Token.test.tsx +95 -0
- package/src/Token/Token.tsx +19 -17
- package/src/Token/TokenLink.tsx +12 -3
- package/src/Tokenizer/Tokenizer.doc.mjs +17 -4
- package/src/Tokenizer/Tokenizer.test.tsx +161 -0
- package/src/Tokenizer/Tokenizer.tsx +49 -24
- package/src/TopNav/TopNavHeading.tsx +2 -2
- package/src/TopNav/TopNavItem.tsx +3 -7
- package/src/TopNav/TopNavMegaMenu.test.tsx +104 -0
- package/src/TopNav/TopNavMegaMenu.tsx +47 -4
- package/src/TopNav/TopNavMegaMenuItem.tsx +10 -9
- package/src/TopNav/TopNavMenu.test.tsx +133 -1
- package/src/TopNav/TopNavMenu.tsx +38 -5
- package/src/TreeList/TreeList.test.tsx +49 -0
- package/src/TreeList/TreeList.tsx +7 -2
- package/src/TreeList/TreeListItem.tsx +2 -7
- package/src/Typeahead/BaseTypeahead.doc.mjs +13 -0
- package/src/Typeahead/BaseTypeahead.tsx +96 -6
- package/src/Typeahead/Typeahead.doc.mjs +7 -1
- package/src/Typeahead/Typeahead.test.tsx +154 -0
- package/src/Typeahead/Typeahead.tsx +9 -0
- package/src/Typeahead/TypeaheadItem.test.tsx +43 -0
- package/src/Typeahead/TypeaheadItem.tsx +8 -1
- package/src/hooks/useAnnounce.doc.mjs +96 -0
- package/src/hooks/useDevWarning.doc.mjs +96 -0
- package/src/hooks/useHotkeys.test.ts +0 -18
- package/src/hooks/useHotkeys.ts +3 -25
- package/src/hooks/useIndicatorFocusRing.doc.mjs +104 -0
- package/src/hooks/useInputStatusIcon.doc.mjs +142 -0
- package/src/hooks/useInteractiveRole.doc.mjs +119 -0
- package/src/hooks/useLongPress.doc.mjs +123 -0
- package/src/hooks/useOverflow.doc.mjs +58 -17
- package/src/hooks/useOverflow.ts +16 -4
- package/src/hooks/useTypeahead.doc.mjs +153 -0
- package/src/i18n/InternationalizationContext.ts +3 -0
- package/src/i18n/InternationalizationProvider.tsx +8 -1
- package/src/i18n/__tests__/resolve.test.ts +23 -1
- package/src/i18n/resolve.ts +46 -49
- package/src/i18n/useTranslator.ts +2 -7
- package/src/index.ts +2 -0
- package/src/raw-import.d.ts +14 -0
- package/src/theme/Theme.test.tsx +104 -2
- package/src/theme/Theme.tsx +49 -14
- package/src/theme/defineTheme.test.ts +23 -0
- package/src/theme/defineTheme.ts +12 -3
- package/src/theme/derivedVarRegistry.test.ts +87 -3
- package/src/theme/derivedVarRegistry.ts +23 -4
- package/src/theme/generateThemeRules.test.ts +99 -1
- package/src/theme/generateThemeRules.ts +28 -0
- package/src/theme/syntax/tokens.ts +5 -2
- package/src/theme/useTheme.test.tsx +10 -0
- package/src/theme/useTheme.ts +16 -10
- package/src/utils/dateParser.test.ts +34 -2
- package/src/utils/dateParser.ts +11 -14
- package/src/utils/focusOutline.stylex.ts +50 -0
- package/src/utils/interactionOverlay.stylex.ts +74 -0
- package/src/utils/isApplePlatform.test.ts +61 -0
- package/src/utils/isApplePlatform.ts +37 -0
- package/src/utils/plainDate.test.ts +46 -0
- package/src/utils/plainDate.ts +18 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
-
import {describe, it, expect} from 'vitest';
|
|
4
|
-
import {render, screen} from '@testing-library/react';
|
|
3
|
+
import {describe, it, expect, vi} from 'vitest';
|
|
4
|
+
import {render, screen, fireEvent} from '@testing-library/react';
|
|
5
5
|
import userEvent from '@testing-library/user-event';
|
|
6
6
|
import {MetadataList} from './MetadataList';
|
|
7
7
|
import {MetadataListItem} from './MetadataListItem';
|
|
@@ -223,3 +223,76 @@ describe('MetadataListItem', () => {
|
|
|
223
223
|
expect(wrapper?.querySelector('dd')).toBeInTheDocument();
|
|
224
224
|
});
|
|
225
225
|
});
|
|
226
|
+
|
|
227
|
+
describe('MetadataListItem pass-through props', () => {
|
|
228
|
+
it('forwards pass-through props to the item element', () => {
|
|
229
|
+
render(
|
|
230
|
+
<MetadataList>
|
|
231
|
+
<MetadataListItem
|
|
232
|
+
label="Owner"
|
|
233
|
+
aria-label="Owner field"
|
|
234
|
+
id="owner"
|
|
235
|
+
data-source="crm"
|
|
236
|
+
data-testid="item">
|
|
237
|
+
Alice
|
|
238
|
+
</MetadataListItem>
|
|
239
|
+
</MetadataList>,
|
|
240
|
+
);
|
|
241
|
+
const item = screen.getByTestId('item-label');
|
|
242
|
+
expect(item).toHaveAttribute('aria-label', 'Owner field');
|
|
243
|
+
expect(item).toHaveAttribute('id', 'owner');
|
|
244
|
+
expect(item).toHaveAttribute('data-source', 'crm');
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it('forwards pass-through props in the stacked layout', () => {
|
|
248
|
+
render(
|
|
249
|
+
<MetadataList orientation="horizontal">
|
|
250
|
+
<MetadataListItem label="Owner" id="owner-stacked" data-testid="item">
|
|
251
|
+
Alice
|
|
252
|
+
</MetadataListItem>
|
|
253
|
+
</MetadataList>,
|
|
254
|
+
);
|
|
255
|
+
expect(screen.getByTestId('item')).toHaveAttribute('id', 'owner-stacked');
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
describe('MetadataListItem pass-through target', () => {
|
|
260
|
+
it('lands pass-through props on the <dt> in the inline layout, where the ref also goes', () => {
|
|
261
|
+
const handleClick = vi.fn();
|
|
262
|
+
render(
|
|
263
|
+
<MetadataList>
|
|
264
|
+
<MetadataListItem
|
|
265
|
+
label="Owner"
|
|
266
|
+
onClick={handleClick}
|
|
267
|
+
data-testid="item">
|
|
268
|
+
Alice
|
|
269
|
+
</MetadataListItem>
|
|
270
|
+
</MetadataList>,
|
|
271
|
+
);
|
|
272
|
+
|
|
273
|
+
const label = screen.getByTestId('item-label');
|
|
274
|
+
expect(label.tagName).toBe('DT');
|
|
275
|
+
fireEvent.click(label);
|
|
276
|
+
expect(handleClick).toHaveBeenCalledOnce();
|
|
277
|
+
|
|
278
|
+
fireEvent.click(screen.getByTestId('item-value'));
|
|
279
|
+
expect(handleClick).toHaveBeenCalledOnce();
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it('lands them on the wrapper in the stacked layout, so both halves are covered', () => {
|
|
283
|
+
const handleClick = vi.fn();
|
|
284
|
+
render(
|
|
285
|
+
<MetadataList orientation="horizontal">
|
|
286
|
+
<MetadataListItem
|
|
287
|
+
label="Owner"
|
|
288
|
+
onClick={handleClick}
|
|
289
|
+
data-testid="item">
|
|
290
|
+
Alice
|
|
291
|
+
</MetadataListItem>
|
|
292
|
+
</MetadataList>,
|
|
293
|
+
);
|
|
294
|
+
|
|
295
|
+
fireEvent.click(screen.getByText('Alice'));
|
|
296
|
+
expect(handleClick).toHaveBeenCalledOnce();
|
|
297
|
+
});
|
|
298
|
+
});
|
|
@@ -144,6 +144,7 @@ export function MetadataListItem({
|
|
|
144
144
|
style,
|
|
145
145
|
'data-testid': testId,
|
|
146
146
|
ref,
|
|
147
|
+
...rest
|
|
147
148
|
}: MetadataListItemProps) {
|
|
148
149
|
const ctx = use(MetadataListContext);
|
|
149
150
|
const labelPosition = ctx?.labelConfig.position ?? 'start';
|
|
@@ -170,7 +171,8 @@ export function MetadataListItem({
|
|
|
170
171
|
stylex.props(styles.stackedWrapper, xstyle),
|
|
171
172
|
className,
|
|
172
173
|
style,
|
|
173
|
-
)}
|
|
174
|
+
)}
|
|
175
|
+
{...rest}>
|
|
174
176
|
<dt {...stylex.props(styles.stackedLabel)}>{labelContent}</dt>
|
|
175
177
|
<dd {...stylex.props(styles.stackedValue)}>{children}</dd>
|
|
176
178
|
</div>
|
|
@@ -188,7 +190,8 @@ export function MetadataListItem({
|
|
|
188
190
|
stylex.props(styles.label, xstyle),
|
|
189
191
|
className,
|
|
190
192
|
style,
|
|
191
|
-
)}
|
|
193
|
+
)}
|
|
194
|
+
{...rest}>
|
|
192
195
|
{labelContent}
|
|
193
196
|
</dt>
|
|
194
197
|
<dd
|
|
@@ -6,7 +6,7 @@ export const docs = {
|
|
|
6
6
|
name: 'MultiSelector',
|
|
7
7
|
displayName: 'Multi Selector',
|
|
8
8
|
group: 'Selector',
|
|
9
|
-
category: '
|
|
9
|
+
category: 'Form Controls',
|
|
10
10
|
keywords: [
|
|
11
11
|
'multiselect',
|
|
12
12
|
'checkbox',
|
|
@@ -25,7 +25,10 @@ export const docs = {
|
|
|
25
25
|
visualProps: ['variant', 'size', 'status'],
|
|
26
26
|
states: ['disabled'],
|
|
27
27
|
},
|
|
28
|
-
{
|
|
28
|
+
{
|
|
29
|
+
className: 'astryx-multi-selector-clear-icon',
|
|
30
|
+
deprecatedFor: 'input-clear-icon',
|
|
31
|
+
},
|
|
29
32
|
{className: 'astryx-multi-selector-empty-state'},
|
|
30
33
|
{className: 'astryx-multi-selector-search'},
|
|
31
34
|
{className: 'astryx-multi-selector-section-heading'},
|
|
@@ -139,6 +142,20 @@ export const docs = {
|
|
|
139
142
|
description: 'Placeholder text for the search input.',
|
|
140
143
|
default: "'Search...'",
|
|
141
144
|
},
|
|
145
|
+
{
|
|
146
|
+
name: 'emptyText',
|
|
147
|
+
type: 'ReactNode',
|
|
148
|
+
description:
|
|
149
|
+
'Content shown in the dropdown panel when there are no options to show, and announced in a polite live region when the panel opens (a string override is announced verbatim; a richer node falls back to the default text). Not shown while isLoading.',
|
|
150
|
+
default: "'No options'",
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: 'emptySearchText',
|
|
154
|
+
type: 'ReactNode',
|
|
155
|
+
description:
|
|
156
|
+
'Content shown in the dropdown panel when a search query matches no options, and announced in a polite live region at the same time (a string override is announced verbatim; a richer node falls back to the default text).',
|
|
157
|
+
default: "'No results found'",
|
|
158
|
+
},
|
|
142
159
|
{
|
|
143
160
|
name: 'isDisabled',
|
|
144
161
|
type: 'boolean',
|
|
@@ -315,6 +332,8 @@ export const docsZh = {
|
|
|
315
332
|
selectAllLabel: '全选复选框的标签。',
|
|
316
333
|
hasSearch: '是否显示用于过滤选项的搜索输入。',
|
|
317
334
|
searchPlaceholder: '搜索输入的占位文本。',
|
|
335
|
+
emptyText: '没有可显示的选项时,下拉面板中显示的内容。',
|
|
336
|
+
emptySearchText: '搜索查询未匹配到任何选项时,下拉面板中显示的内容。',
|
|
318
337
|
isDisabled: '禁用选择器。',
|
|
319
338
|
htmlName:
|
|
320
339
|
'用于表单提交的 HTML name 属性。为每个已选值渲染一个隐藏输入,类似原生多选。',
|
|
@@ -452,6 +471,8 @@ export const docsDense = {
|
|
|
452
471
|
selectAllLabel: 'select-all label',
|
|
453
472
|
hasSearch: 'show search input',
|
|
454
473
|
searchPlaceholder: 'search placeholder',
|
|
474
|
+
emptyText: 'panel content when there are no options',
|
|
475
|
+
emptySearchText: 'panel content when the query matches nothing',
|
|
455
476
|
isDisabled: 'disables selector',
|
|
456
477
|
htmlName: 'HTML name attr; one hidden input per selected value.',
|
|
457
478
|
disabledMessage:
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
|
|
13
13
|
import {
|
|
14
|
+
act,
|
|
14
15
|
render,
|
|
15
16
|
screen,
|
|
16
17
|
fireEvent,
|
|
@@ -911,6 +912,176 @@ describe('MultiSelector', () => {
|
|
|
911
912
|
expect(empty).toHaveAttribute('role', 'presentation');
|
|
912
913
|
});
|
|
913
914
|
|
|
915
|
+
it('renders emptySearchText in place of the default message', async () => {
|
|
916
|
+
const user = userEvent.setup();
|
|
917
|
+
render(
|
|
918
|
+
<MultiSelector
|
|
919
|
+
label="Fruit"
|
|
920
|
+
options={defaultOptions}
|
|
921
|
+
value={[]}
|
|
922
|
+
onChange={() => {}}
|
|
923
|
+
hasSearch
|
|
924
|
+
emptySearchText="Nothing like that here"
|
|
925
|
+
/>,
|
|
926
|
+
);
|
|
927
|
+
|
|
928
|
+
await user.click(screen.getByRole('button', {name: 'Fruit'}));
|
|
929
|
+
await user.type(screen.getByRole('combobox', h), 'xyz');
|
|
930
|
+
|
|
931
|
+
const listbox = screen.getByRole('listbox', h);
|
|
932
|
+
expect(
|
|
933
|
+
within(listbox).getByText('Nothing like that here'),
|
|
934
|
+
).toBeInTheDocument();
|
|
935
|
+
expect(
|
|
936
|
+
within(listbox).queryByText('No results found'),
|
|
937
|
+
).not.toBeInTheDocument();
|
|
938
|
+
});
|
|
939
|
+
|
|
940
|
+
it('renders emptyText, not emptySearchText, with no options and no query', async () => {
|
|
941
|
+
const user = userEvent.setup();
|
|
942
|
+
render(
|
|
943
|
+
<MultiSelector
|
|
944
|
+
label="Fruit"
|
|
945
|
+
options={[]}
|
|
946
|
+
value={[]}
|
|
947
|
+
onChange={() => {}}
|
|
948
|
+
hasSearch
|
|
949
|
+
emptySearchText="Nothing like that here"
|
|
950
|
+
/>,
|
|
951
|
+
);
|
|
952
|
+
|
|
953
|
+
await user.click(screen.getByRole('button', {name: 'Fruit'}));
|
|
954
|
+
|
|
955
|
+
const listbox = screen.getByRole('listbox', h);
|
|
956
|
+
expect(within(listbox).getByText('No options')).toBeInTheDocument();
|
|
957
|
+
expect(
|
|
958
|
+
within(listbox).queryByText('Nothing like that here'),
|
|
959
|
+
).not.toBeInTheDocument();
|
|
960
|
+
});
|
|
961
|
+
|
|
962
|
+
it('announces emptySearchText, not the catalog default', async () => {
|
|
963
|
+
const user = userEvent.setup();
|
|
964
|
+
render(
|
|
965
|
+
<MultiSelector
|
|
966
|
+
label="Fruit"
|
|
967
|
+
options={defaultOptions}
|
|
968
|
+
value={[]}
|
|
969
|
+
onChange={() => {}}
|
|
970
|
+
hasSearch
|
|
971
|
+
emptySearchText="Nothing like that here"
|
|
972
|
+
/>,
|
|
973
|
+
);
|
|
974
|
+
|
|
975
|
+
await user.click(screen.getByRole('button', {name: 'Fruit'}));
|
|
976
|
+
await user.type(screen.getByRole('combobox', h), 'xyz');
|
|
977
|
+
|
|
978
|
+
// The panel message is role="presentation", so the live region is the
|
|
979
|
+
// only thing a screen reader gets — it has to say the same words.
|
|
980
|
+
await waitFor(() =>
|
|
981
|
+
expect(politeRegion()?.textContent).toBe('Nothing like that here'),
|
|
982
|
+
);
|
|
983
|
+
});
|
|
984
|
+
|
|
985
|
+
it('announces the empty state when opened with no options', async () => {
|
|
986
|
+
const user = userEvent.setup();
|
|
987
|
+
render(
|
|
988
|
+
<MultiSelector
|
|
989
|
+
label="Fruit"
|
|
990
|
+
options={[]}
|
|
991
|
+
value={[]}
|
|
992
|
+
onChange={() => {}}
|
|
993
|
+
emptyText="Add a fruit first"
|
|
994
|
+
/>,
|
|
995
|
+
);
|
|
996
|
+
|
|
997
|
+
await user.click(screen.getByRole('combobox', {name: 'Fruit'}));
|
|
998
|
+
|
|
999
|
+
await waitFor(() =>
|
|
1000
|
+
expect(politeRegion()?.textContent).toBe('Add a fruit first'),
|
|
1001
|
+
);
|
|
1002
|
+
});
|
|
1003
|
+
|
|
1004
|
+
it('shows and announces nothing while isLoading', async () => {
|
|
1005
|
+
const user = userEvent.setup();
|
|
1006
|
+
render(
|
|
1007
|
+
<MultiSelector
|
|
1008
|
+
label="Fruit"
|
|
1009
|
+
options={[]}
|
|
1010
|
+
value={[]}
|
|
1011
|
+
onChange={() => {}}
|
|
1012
|
+
isLoading
|
|
1013
|
+
/>,
|
|
1014
|
+
);
|
|
1015
|
+
|
|
1016
|
+
await user.click(screen.getByRole('combobox', {name: 'Fruit'}));
|
|
1017
|
+
|
|
1018
|
+
// useAnnounce writes on the next animation frame, so an immediate read
|
|
1019
|
+
// would pass whether or not anything was announced.
|
|
1020
|
+
await act(
|
|
1021
|
+
async () =>
|
|
1022
|
+
void (await new Promise(resolve => requestAnimationFrame(resolve))),
|
|
1023
|
+
);
|
|
1024
|
+
|
|
1025
|
+
// The options have not arrived, so "No options" would be a claim the
|
|
1026
|
+
// component cannot make; the trigger's spinner carries the state.
|
|
1027
|
+
const listbox = screen.getByRole('listbox', h);
|
|
1028
|
+
expect(within(listbox).queryByText('No options')).not.toBeInTheDocument();
|
|
1029
|
+
expect(politeRegion()?.textContent ?? '').toBe('');
|
|
1030
|
+
});
|
|
1031
|
+
|
|
1032
|
+
it('announces nothing while isLoading, matching the silent panel', async () => {
|
|
1033
|
+
const user = userEvent.setup();
|
|
1034
|
+
render(
|
|
1035
|
+
<MultiSelector
|
|
1036
|
+
label="Fruit"
|
|
1037
|
+
options={defaultOptions}
|
|
1038
|
+
value={[]}
|
|
1039
|
+
onChange={() => {}}
|
|
1040
|
+
hasSearch
|
|
1041
|
+
isLoading
|
|
1042
|
+
emptySearchText="Nothing like that here"
|
|
1043
|
+
/>,
|
|
1044
|
+
);
|
|
1045
|
+
|
|
1046
|
+
await user.click(screen.getByRole('button', {name: 'Fruit'}));
|
|
1047
|
+
await user.type(screen.getByRole('combobox', h), 'xyz');
|
|
1048
|
+
|
|
1049
|
+
// useAnnounce writes on the next animation frame, so an immediate read
|
|
1050
|
+
// would pass whether or not anything was announced.
|
|
1051
|
+
await act(
|
|
1052
|
+
async () =>
|
|
1053
|
+
void (await new Promise(resolve => requestAnimationFrame(resolve))),
|
|
1054
|
+
);
|
|
1055
|
+
|
|
1056
|
+
// The panel is deliberately blank while loading; the live region is the
|
|
1057
|
+
// only channel left, so a result there would be a claim the screen
|
|
1058
|
+
// refuses to make.
|
|
1059
|
+
const listbox = screen.getByRole('listbox', h);
|
|
1060
|
+
expect(
|
|
1061
|
+
within(listbox).queryByText('Nothing like that here'),
|
|
1062
|
+
).not.toBeInTheDocument();
|
|
1063
|
+
expect(politeRegion()?.textContent ?? '').toBe('');
|
|
1064
|
+
});
|
|
1065
|
+
|
|
1066
|
+
it('renders emptyText when there are no options and no search input', async () => {
|
|
1067
|
+
const user = userEvent.setup();
|
|
1068
|
+
render(
|
|
1069
|
+
<MultiSelector
|
|
1070
|
+
label="Fruit"
|
|
1071
|
+
options={[]}
|
|
1072
|
+
value={[]}
|
|
1073
|
+
onChange={() => {}}
|
|
1074
|
+
emptyText="Add a fruit first"
|
|
1075
|
+
/>,
|
|
1076
|
+
);
|
|
1077
|
+
|
|
1078
|
+
// Without hasSearch the trigger itself is the combobox.
|
|
1079
|
+
await user.click(screen.getByRole('combobox', {name: 'Fruit'}));
|
|
1080
|
+
|
|
1081
|
+
const listbox = screen.getByRole('listbox', h);
|
|
1082
|
+
expect(within(listbox).getByText('Add a fruit first')).toBeInTheDocument();
|
|
1083
|
+
});
|
|
1084
|
+
|
|
914
1085
|
describe('result announcements', () => {
|
|
915
1086
|
it('announces the match count politely while searching', async () => {
|
|
916
1087
|
const user = userEvent.setup();
|
|
@@ -2489,4 +2660,38 @@ describe('MultiSelector popup theme target', () => {
|
|
|
2489
2660
|
expect(popup).not.toBe(layer);
|
|
2490
2661
|
expect(layer.contains(popup)).toBe(true);
|
|
2491
2662
|
});
|
|
2663
|
+
|
|
2664
|
+
it('stays closed when the trigger click follows its own light dismiss (#5004)', async () => {
|
|
2665
|
+
const user = userEvent.setup();
|
|
2666
|
+
render(
|
|
2667
|
+
<MultiSelector
|
|
2668
|
+
label="Fruit"
|
|
2669
|
+
options={['Apple', 'Banana', 'Cherry']}
|
|
2670
|
+
value={[]}
|
|
2671
|
+
onChange={() => {}}
|
|
2672
|
+
/>,
|
|
2673
|
+
);
|
|
2674
|
+
const trigger = screen.getByRole('combobox');
|
|
2675
|
+
await user.click(trigger);
|
|
2676
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'true');
|
|
2677
|
+
|
|
2678
|
+
// The browser dismissed the popup on pointerup and queued the toggle. When
|
|
2679
|
+
// that event lands before the click — WebKit, or any engine under load —
|
|
2680
|
+
// the click used to read a closed popup and reopen it.
|
|
2681
|
+
fireEvent.pointerDown(trigger);
|
|
2682
|
+
const popover = document.querySelector('[popover]') as HTMLElement;
|
|
2683
|
+
act(() => {
|
|
2684
|
+
popover.dispatchEvent(
|
|
2685
|
+
Object.assign(new Event('toggle'), {
|
|
2686
|
+
oldState: 'open',
|
|
2687
|
+
newState: 'closed',
|
|
2688
|
+
}),
|
|
2689
|
+
);
|
|
2690
|
+
});
|
|
2691
|
+
// Synchronously: the click falls inside the one gesture the guard covers,
|
|
2692
|
+
// as it does in a browser a few milliseconds behind the dismissal.
|
|
2693
|
+
fireEvent.click(trigger);
|
|
2694
|
+
|
|
2695
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'false');
|
|
2696
|
+
});
|
|
2492
2697
|
});
|
|
@@ -28,18 +28,19 @@ import React, {
|
|
|
28
28
|
type ReactNode,
|
|
29
29
|
} from 'react';
|
|
30
30
|
import * as stylex from '@stylexjs/stylex';
|
|
31
|
-
import {
|
|
31
|
+
import {usePopoverInternal} from '../Popover/usePopover';
|
|
32
32
|
import {useTooltip} from '../Tooltip';
|
|
33
33
|
import {Icon, renderIconSlot, type IconType} from '../Icon';
|
|
34
34
|
import type {IconName} from '../Icon';
|
|
35
35
|
import {
|
|
36
36
|
Field,
|
|
37
|
-
InputClearButton,
|
|
38
37
|
inputStatusBorderStyles,
|
|
39
38
|
inputStatusHoverShadowStyles,
|
|
40
39
|
inputWrapperStyles,
|
|
41
40
|
type FieldStatusVariant,
|
|
42
41
|
} from '../Field';
|
|
42
|
+
import {useKeepLayerOpenProps} from '../Layer/useLayer';
|
|
43
|
+
import {InternalInputClearButton} from '../Field/InputClearButton';
|
|
43
44
|
import {Divider} from '../Divider';
|
|
44
45
|
import {Spinner} from '../Spinner';
|
|
45
46
|
import {PanelSearchInput} from '../Field/PanelSearchInput';
|
|
@@ -79,6 +80,7 @@ import type {SizeValue} from '../utils/types';
|
|
|
79
80
|
import {useSize} from '../SizeContext/SizeContext';
|
|
80
81
|
import {themeProps} from '../utils/themeProps';
|
|
81
82
|
import {focusOutlineStyles} from '../utils/focusOutline.stylex';
|
|
83
|
+
import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
|
|
82
84
|
import {stableClassName} from '../naming';
|
|
83
85
|
import {groupStyles} from '../InputGroup/groupStyles';
|
|
84
86
|
import {useInputGroup} from '../InputGroup/InputGroupContext';
|
|
@@ -194,13 +196,6 @@ const styles = stylex.create({
|
|
|
194
196
|
width: 'auto',
|
|
195
197
|
borderWidth: 0,
|
|
196
198
|
backgroundColor: 'transparent',
|
|
197
|
-
backgroundImage: {
|
|
198
|
-
default: null,
|
|
199
|
-
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
200
|
-
'@media (hover: hover)': `linear-gradient(${colorVars['--color-overlay-hover']}, ${colorVars['--color-overlay-hover']})`,
|
|
201
|
-
},
|
|
202
|
-
':active': `linear-gradient(${colorVars['--color-overlay-pressed']}, ${colorVars['--color-overlay-pressed']})`,
|
|
203
|
-
},
|
|
204
199
|
boxShadow: {
|
|
205
200
|
default: 'none',
|
|
206
201
|
':hover:not(:focus-within):where(:not(:disabled,[aria-disabled="true"]))':
|
|
@@ -604,6 +599,25 @@ export interface MultiSelectorProps<
|
|
|
604
599
|
*/
|
|
605
600
|
searchPlaceholder?: string;
|
|
606
601
|
|
|
602
|
+
/**
|
|
603
|
+
* Content shown in the panel when there are no options to show, and
|
|
604
|
+
* announced in a polite live region when the panel opens. Not shown while
|
|
605
|
+
* `isLoading` — the options have not arrived yet.
|
|
606
|
+
* @default 'No options'
|
|
607
|
+
*/
|
|
608
|
+
emptyText?: ReactNode;
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* Content shown in the panel when a search query matches no options, and
|
|
612
|
+
* announced in a polite live region at the same time.
|
|
613
|
+
*
|
|
614
|
+
* The panel message is `role="presentation"`, so the live region is the only
|
|
615
|
+
* route to assistive tech: a string is announced verbatim, a richer node
|
|
616
|
+
* falls back to the default text since it cannot be spoken.
|
|
617
|
+
* @default 'No results found'
|
|
618
|
+
*/
|
|
619
|
+
emptySearchText?: ReactNode;
|
|
620
|
+
|
|
607
621
|
/**
|
|
608
622
|
* How to display selected items in the trigger.
|
|
609
623
|
* - 'count': "3 selected"
|
|
@@ -726,6 +740,8 @@ export function MultiSelector<T extends MultiSelectorOptionType>({
|
|
|
726
740
|
selectAllLabel: selectAllLabelFromProps,
|
|
727
741
|
hasSearch = false,
|
|
728
742
|
searchPlaceholder: searchPlaceholderFromProps,
|
|
743
|
+
emptyText: emptyTextFromProps,
|
|
744
|
+
emptySearchText: emptySearchTextFromProps,
|
|
729
745
|
triggerDisplay = 'count',
|
|
730
746
|
formatValue,
|
|
731
747
|
maxBadges = 3,
|
|
@@ -747,6 +763,9 @@ export function MultiSelector<T extends MultiSelectorOptionType>({
|
|
|
747
763
|
selectAllLabelFromProps ?? t('@astryx.multiSelector.selectAll');
|
|
748
764
|
const searchPlaceholder =
|
|
749
765
|
searchPlaceholderFromProps ?? t('@astryx.multiSelector.searchPlaceholder');
|
|
766
|
+
const emptyText = emptyTextFromProps ?? t('@astryx.multiSelector.empty');
|
|
767
|
+
const emptySearchText =
|
|
768
|
+
emptySearchTextFromProps ?? t('@astryx.multiSelector.emptySearchResults');
|
|
750
769
|
const size = useSize(sizeProp, 'md');
|
|
751
770
|
const effectiveStatusVariant =
|
|
752
771
|
variant === 'ghost' && statusVariant === 'attached'
|
|
@@ -821,6 +840,19 @@ export function MultiSelector<T extends MultiSelectorOptionType>({
|
|
|
821
840
|
// Announce selection-count changes politely (comboboxes-7 announce path).
|
|
822
841
|
// Toggling options / select-all previously produced no audible feedback.
|
|
823
842
|
const announce = useAnnounce();
|
|
843
|
+
|
|
844
|
+
// The panel's empty message is role="presentation" and reaches assistive tech
|
|
845
|
+
// only through this live region, so the region has to speak whatever the
|
|
846
|
+
// panel shows. A ReactNode override cannot be spoken; fall back to the
|
|
847
|
+
// catalog copy for that case rather than announcing nothing.
|
|
848
|
+
const emptyAnnouncement =
|
|
849
|
+
typeof emptyText === 'string'
|
|
850
|
+
? emptyText
|
|
851
|
+
: t('@astryx.multiSelector.empty');
|
|
852
|
+
const emptySearchAnnouncement =
|
|
853
|
+
typeof emptySearchText === 'string'
|
|
854
|
+
? emptySearchText
|
|
855
|
+
: t('@astryx.multiSelector.emptySearchResults');
|
|
824
856
|
const announceSelection = useCallback(
|
|
825
857
|
(nextValue: string[]) => {
|
|
826
858
|
const total = selectableItems.length;
|
|
@@ -906,7 +938,7 @@ export function MultiSelector<T extends MultiSelectorOptionType>({
|
|
|
906
938
|
triggerRef.current?.focus();
|
|
907
939
|
}, [announce]);
|
|
908
940
|
|
|
909
|
-
const popover =
|
|
941
|
+
const popover = usePopoverInternal({
|
|
910
942
|
hasLightDismiss: true,
|
|
911
943
|
onHide: handleLayerHide,
|
|
912
944
|
hasCloseButton: false,
|
|
@@ -918,6 +950,7 @@ export function MultiSelector<T extends MultiSelectorOptionType>({
|
|
|
918
950
|
// `usePopover` owns — not on the scrolling list inside it.
|
|
919
951
|
surfaceTarget: 'multi-selector-popup',
|
|
920
952
|
});
|
|
953
|
+
const keepOpenProps = useKeepLayerOpenProps(popover.id, popover.isOpen);
|
|
921
954
|
|
|
922
955
|
// Open dropdown on mount when isDefaultOpen is true
|
|
923
956
|
useEffect(() => {
|
|
@@ -940,16 +973,54 @@ export function MultiSelector<T extends MultiSelectorOptionType>({
|
|
|
940
973
|
announce('');
|
|
941
974
|
return;
|
|
942
975
|
}
|
|
976
|
+
// While isLoading the panel deliberately shows nothing, so announcing a
|
|
977
|
+
// result would put a claim in the one channel the screen has gone quiet
|
|
978
|
+
// for.
|
|
979
|
+
if (isLoading) {
|
|
980
|
+
announce('');
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
943
983
|
const count = filterOptionsByQuery(selectableItems, nextQuery).length;
|
|
944
984
|
announce(
|
|
945
985
|
count === 0
|
|
946
|
-
?
|
|
986
|
+
? emptySearchAnnouncement
|
|
947
987
|
: t('@astryx.multiSelector.resultCount', {count}),
|
|
948
988
|
);
|
|
949
989
|
},
|
|
950
|
-
[announce, selectableItems, t],
|
|
990
|
+
[announce, isLoading, selectableItems, emptySearchAnnouncement, t],
|
|
951
991
|
);
|
|
952
992
|
|
|
993
|
+
// The panel's empty message is role="presentation", so this region is the
|
|
994
|
+
// only route to assistive tech. It has to watch the STATE rather than the
|
|
995
|
+
// open event: the panel can become empty either on open or when a fetch
|
|
996
|
+
// lands with nothing in it, and an open-only announcement leaves the second
|
|
997
|
+
// case silent while the message sits on screen. The ref makes it fire once
|
|
998
|
+
// per arrival at that state rather than on every re-render.
|
|
999
|
+
const announcedEmptyRef = useRef<string | null>(null);
|
|
1000
|
+
useEffect(() => {
|
|
1001
|
+
const isPanelEmpty =
|
|
1002
|
+
popover.isOpen &&
|
|
1003
|
+
!isLoading &&
|
|
1004
|
+
searchQuery === '' &&
|
|
1005
|
+
selectableItems.length === 0;
|
|
1006
|
+
if (!isPanelEmpty) {
|
|
1007
|
+
announcedEmptyRef.current = null;
|
|
1008
|
+
return;
|
|
1009
|
+
}
|
|
1010
|
+
if (announcedEmptyRef.current === emptyAnnouncement) {
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
announcedEmptyRef.current = emptyAnnouncement;
|
|
1014
|
+
announce(emptyAnnouncement);
|
|
1015
|
+
}, [
|
|
1016
|
+
popover.isOpen,
|
|
1017
|
+
isLoading,
|
|
1018
|
+
searchQuery,
|
|
1019
|
+
selectableItems.length,
|
|
1020
|
+
emptyAnnouncement,
|
|
1021
|
+
announce,
|
|
1022
|
+
]);
|
|
1023
|
+
|
|
953
1024
|
// Handle toggle
|
|
954
1025
|
// Clear all selected values. Shared by the clear button and the keyboard
|
|
955
1026
|
// Delete/Backspace path so clearing is reachable without a mouse.
|
|
@@ -1087,6 +1158,7 @@ export function MultiSelector<T extends MultiSelectorOptionType>({
|
|
|
1087
1158
|
onKeyDown,
|
|
1088
1159
|
onItemMouseEnter,
|
|
1089
1160
|
} = useMultiCombobox({
|
|
1161
|
+
wasJustDismissed: popover.wasJustDismissed,
|
|
1090
1162
|
selectableItems: sortedItems,
|
|
1091
1163
|
isDisabled,
|
|
1092
1164
|
isOpen: popover.isOpen,
|
|
@@ -1416,7 +1488,10 @@ export function MultiSelector<T extends MultiSelectorOptionType>({
|
|
|
1416
1488
|
// message out of the listbox's accessibility tree (role="listbox" only
|
|
1417
1489
|
// permits option/group children); the no-results outcome is announced
|
|
1418
1490
|
// via the result-count live region instead.
|
|
1419
|
-
|
|
1491
|
+
// While isLoading the options have not arrived yet, so asserting either
|
|
1492
|
+
// message would be a claim the component cannot make; the trigger's
|
|
1493
|
+
// spinner covers it.
|
|
1494
|
+
if (realItemCount === 0 && !isLoading) {
|
|
1420
1495
|
elements.push(
|
|
1421
1496
|
<div
|
|
1422
1497
|
key="empty"
|
|
@@ -1425,7 +1500,7 @@ export function MultiSelector<T extends MultiSelectorOptionType>({
|
|
|
1425
1500
|
themeProps('multi-selector-empty-state'),
|
|
1426
1501
|
stylex.props(styles.emptyState),
|
|
1427
1502
|
)}>
|
|
1428
|
-
|
|
1503
|
+
{searchQuery ? emptySearchText : emptyText}
|
|
1429
1504
|
</div>,
|
|
1430
1505
|
);
|
|
1431
1506
|
return elements;
|
|
@@ -1515,7 +1590,16 @@ export function MultiSelector<T extends MultiSelectorOptionType>({
|
|
|
1515
1590
|
flushPending();
|
|
1516
1591
|
|
|
1517
1592
|
return elements;
|
|
1518
|
-
}, [
|
|
1593
|
+
}, [
|
|
1594
|
+
options,
|
|
1595
|
+
renderItem,
|
|
1596
|
+
sortedItems,
|
|
1597
|
+
searchQuery,
|
|
1598
|
+
hasSelectAll,
|
|
1599
|
+
isLoading,
|
|
1600
|
+
emptyText,
|
|
1601
|
+
emptySearchText,
|
|
1602
|
+
]);
|
|
1519
1603
|
|
|
1520
1604
|
// The detached message box renders its own leading status icon, so the
|
|
1521
1605
|
// on-field icon would duplicate it — keep the chevron indicator instead.
|
|
@@ -1548,6 +1632,7 @@ export function MultiSelector<T extends MultiSelectorOptionType>({
|
|
|
1548
1632
|
styles.triggerContainer,
|
|
1549
1633
|
sizeStyles[size],
|
|
1550
1634
|
variant === 'ghost' && styles.triggerGhost,
|
|
1635
|
+
variant === 'ghost' && interactionOverlayStyles.backgroundImage,
|
|
1551
1636
|
variant === 'ghost' && focusOutlineStyles.focusWithin,
|
|
1552
1637
|
isDisabled && inputWrapperStyles.disabled,
|
|
1553
1638
|
variant === 'ghost' && isDisabled && styles.triggerGhostDisabled,
|
|
@@ -1617,7 +1702,8 @@ export function MultiSelector<T extends MultiSelectorOptionType>({
|
|
|
1617
1702
|
))}
|
|
1618
1703
|
{isBusy && <Spinner size="sm" />}
|
|
1619
1704
|
{hasClear && value.length > 0 && !isDisabled && (
|
|
1620
|
-
<
|
|
1705
|
+
<InternalInputClearButton
|
|
1706
|
+
{...keepOpenProps}
|
|
1621
1707
|
label={t('@astryx.multiSelector.clearAll', {label})}
|
|
1622
1708
|
onClick={handleClear}
|
|
1623
1709
|
iconClassName={stableClassName('multi-selector-clear-icon')}
|
|
@@ -1636,6 +1722,7 @@ export function MultiSelector<T extends MultiSelectorOptionType>({
|
|
|
1636
1722
|
type="button"
|
|
1637
1723
|
aria-label={t(STATUS_BUTTON_LABEL_KEY[status.type])}
|
|
1638
1724
|
aria-describedby={statusTooltip.describedBy}
|
|
1725
|
+
{...keepOpenProps}
|
|
1639
1726
|
onClick={e => e.stopPropagation()}
|
|
1640
1727
|
{...stylex.props(
|
|
1641
1728
|
focusOutlineStyles.focusVisible,
|
|
@@ -34,6 +34,12 @@ interface UseMultiComboboxOptions {
|
|
|
34
34
|
* The Delete/Backspace clear path is skipped when false.
|
|
35
35
|
*/
|
|
36
36
|
hasValue?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Whether the browser's light dismiss just closed the popup. The trigger
|
|
39
|
+
* click that follows belongs to that same press, so acting on it would
|
|
40
|
+
* reopen the popup the user just closed.
|
|
41
|
+
*/
|
|
42
|
+
wasJustDismissed?: () => boolean;
|
|
37
43
|
listboxId: string;
|
|
38
44
|
}
|
|
39
45
|
|
|
@@ -62,6 +68,7 @@ export function useMultiCombobox({
|
|
|
62
68
|
onToggle,
|
|
63
69
|
onClear,
|
|
64
70
|
hasValue = false,
|
|
71
|
+
wasJustDismissed,
|
|
65
72
|
listboxId,
|
|
66
73
|
}: UseMultiComboboxOptions): UseMultiComboboxResult {
|
|
67
74
|
const [highlightedIndex, setHighlightedIndex] = useState<number>(-1);
|
|
@@ -87,7 +94,7 @@ export function useMultiCombobox({
|
|
|
87
94
|
}, [onClose]);
|
|
88
95
|
|
|
89
96
|
const onTriggerClick = useCallback(() => {
|
|
90
|
-
if (isDisabled) {
|
|
97
|
+
if (isDisabled || wasJustDismissed?.()) {
|
|
91
98
|
return;
|
|
92
99
|
}
|
|
93
100
|
if (isOpen) {
|
|
@@ -98,7 +105,7 @@ export function useMultiCombobox({
|
|
|
98
105
|
setHighlightedIndex(0);
|
|
99
106
|
}
|
|
100
107
|
}
|
|
101
|
-
}, [isDisabled, isOpen, onOpen, closeAndReset, hasSearch]);
|
|
108
|
+
}, [isDisabled, wasJustDismissed, isOpen, onOpen, closeAndReset, hasSearch]);
|
|
102
109
|
|
|
103
110
|
const onItemMouseEnter = useCallback(
|
|
104
111
|
(item: MultiSelectorOptionData, index: number) => {
|