@astryxdesign/core 0.5.0 → 0.5.1-canary.f64186a
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/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 +3 -3
- 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 +2 -0
- package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
- package/src/CheckboxInput/CheckboxInput.tsx +5 -0
- 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 +7 -0
- package/src/ComplexSelector/ComplexSelector.test.tsx +183 -0
- package/src/ComplexSelector/ComplexSelector.tsx +22 -12
- package/src/DateInput/DateInput.doc.mjs +16 -0
- 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 +2 -2
- package/src/DateRangeInput/DateRangeInput.test.tsx +46 -0
- package/src/DateRangeInput/DateRangeInput.tsx +8 -13
- package/src/DateTimeInput/DateTimeInput.doc.mjs +38 -21
- 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/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/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 +2 -0
- 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 +22 -1
- 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 +26 -7
- 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/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/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 +14 -0
- 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.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 +2 -0
- 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 +12 -2
- package/src/TextArea/TextArea.test.tsx +11 -0
- package/src/TextArea/TextArea.tsx +34 -22
- 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 +16 -3
- 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 +6 -0
- 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/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
|
@@ -176,12 +176,6 @@ const styles = stylex.create({
|
|
|
176
176
|
},
|
|
177
177
|
scrollbarWidth: 'none',
|
|
178
178
|
maskImage: 'none',
|
|
179
|
-
transitionProperty: 'mask-image',
|
|
180
|
-
transitionDuration: {
|
|
181
|
-
default: durationVars['--duration-medium'],
|
|
182
|
-
'@media (prefers-reduced-motion: reduce)': '0ms',
|
|
183
|
-
},
|
|
184
|
-
transitionTimingFunction: easeVars['--ease-standard'],
|
|
185
179
|
},
|
|
186
180
|
fadeStart: {
|
|
187
181
|
maskImage: `linear-gradient(to right, transparent 0%, rgba(0,0,0,0.3) 2px, black ${spacingVars['--spacing-1']})`,
|
|
@@ -341,6 +335,13 @@ export function Carousel({
|
|
|
341
335
|
const t = useTranslator();
|
|
342
336
|
const ariaLabel = ariaLabelFromProps ?? t('@astryx.carousel.label');
|
|
343
337
|
const scrollElRef = useRef<HTMLElement | null>(null);
|
|
338
|
+
const startButtonRef = useRef<HTMLButtonElement>(null);
|
|
339
|
+
const endButtonRef = useRef<HTMLButtonElement>(null);
|
|
340
|
+
// Which nav button last held focus, and what the overflow state was on the
|
|
341
|
+
// previous render. Together they are how the Effect below recognises the one
|
|
342
|
+
// transition it is allowed to act on.
|
|
343
|
+
const focusedNavRef = useRef<'start' | 'end' | null>(null);
|
|
344
|
+
const prevCanScrollRef = useRef<{start: boolean; end: boolean} | null>(null);
|
|
344
345
|
const {scrollRef, overflowStart, overflowEnd, hasOverflow} =
|
|
345
346
|
useScrollOverflow();
|
|
346
347
|
|
|
@@ -487,6 +488,76 @@ export function Carousel({
|
|
|
487
488
|
const canScrollStart = hasLoop && hasOverflow ? true : overflowStart;
|
|
488
489
|
const canScrollEnd = hasLoop && hasOverflow ? true : overflowEnd;
|
|
489
490
|
|
|
491
|
+
// Keep the keyboard user where they are when a nav button disables under
|
|
492
|
+
// them. The browser drops focus off a control it disables, so reaching an
|
|
493
|
+
// edge used to land the user on <body> and cost them their place in the page.
|
|
494
|
+
//
|
|
495
|
+
// This is an Effect on purpose, and the exception is narrow. The thing that
|
|
496
|
+
// disables the button IS this state transition, so it is the only correct
|
|
497
|
+
// trigger: three attempts to predict it from the press -- the position after
|
|
498
|
+
// the scroll, the position before it plus the step, and the settled position
|
|
499
|
+
// reported by `scrollend` -- were each wrong somewhere, under reduced motion,
|
|
500
|
+
// under mandatory scroll-snap, and on a browser that never fires the event.
|
|
501
|
+
// Running after the commit also makes the opposite button a valid receiver,
|
|
502
|
+
// which it is not during the press: at that moment it is still disabled and
|
|
503
|
+
// focus() on a disabled control does nothing. Ruled acceptable by the
|
|
504
|
+
// maintainer, 2026-08-27, on the conditions encoded below: it acts only on
|
|
505
|
+
// the transition that newly disables the focused button, it moves focus and
|
|
506
|
+
// nothing else, and it cannot fire twice for one transition.
|
|
507
|
+
//
|
|
508
|
+
// Which button the person is on is tracked by the buttons' own focus and blur
|
|
509
|
+
// handlers, and the blur has to ignore the one the commit itself causes: a
|
|
510
|
+
// tracker that outlived the person let a later edge -- a swipe, a resize, no
|
|
511
|
+
// press at all -- pull their focus back onto a control they never chose.
|
|
512
|
+
useEffect(() => {
|
|
513
|
+
const previous = prevCanScrollRef.current;
|
|
514
|
+
prevCanScrollRef.current = {start: canScrollStart, end: canScrollEnd};
|
|
515
|
+
const side = focusedNavRef.current;
|
|
516
|
+
if (previous == null || side == null) {
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// Only the edge that just ran out, and only while it held focus. An edge
|
|
521
|
+
// that was already disabled, or one the user was not on, is not ours.
|
|
522
|
+
const wasEnabled = side === 'start' ? previous.start : previous.end;
|
|
523
|
+
const isEnabled = side === 'start' ? canScrollStart : canScrollEnd;
|
|
524
|
+
if (!wasEnabled || isEnabled) {
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
const pressed =
|
|
529
|
+
side === 'start' ? startButtonRef.current : endButtonRef.current;
|
|
530
|
+
if (pressed == null) {
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
// The browser has already blurred it, so focus reads as the body. Anything
|
|
534
|
+
// else means the user moved on themselves and this is not ours to redirect.
|
|
535
|
+
const active = pressed.ownerDocument.activeElement;
|
|
536
|
+
if (active !== pressed && active !== pressed.ownerDocument.body) {
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
const opposite =
|
|
541
|
+
side === 'start' ? endButtonRef.current : startButtonRef.current;
|
|
542
|
+
// The opposite button is the receiver. It is disabled only when the
|
|
543
|
+
// carousel stopped overflowing entirely, which happens when its content
|
|
544
|
+
// shrinks; the scroll container is then the nearest tab stop still inside
|
|
545
|
+
// the labelled region.
|
|
546
|
+
const receiver =
|
|
547
|
+
opposite != null && !opposite.disabled ? opposite : scrollElRef.current;
|
|
548
|
+
if (receiver == null) {
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// One move per transition: clearing the tracker first means a re-render or
|
|
553
|
+
// a StrictMode double-invoke re-runs this and returns at the `side == null`
|
|
554
|
+
// guard above. Focusing the receiver sets it again, to the other side.
|
|
555
|
+
focusedNavRef.current = null;
|
|
556
|
+
// preventScroll: a plain focus() scrolls its element into view, which on
|
|
557
|
+
// the scroll container cancels the scroll the press just started.
|
|
558
|
+
receiver.focus({preventScroll: true});
|
|
559
|
+
}, [canScrollStart, canScrollEnd]);
|
|
560
|
+
|
|
490
561
|
const fadeStyle = hasEdgeFade
|
|
491
562
|
? (hasLoop && hasOverflow) || (overflowStart && overflowEnd)
|
|
492
563
|
? styles.fadeBoth
|
|
@@ -523,12 +594,20 @@ export function Carousel({
|
|
|
523
594
|
ref={composedRef}
|
|
524
595
|
tabIndex={0}
|
|
525
596
|
onWheel={handleWheel}
|
|
526
|
-
{...
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
597
|
+
{...mergeProps(
|
|
598
|
+
themeProps('carousel-scroller', {
|
|
599
|
+
gap,
|
|
600
|
+
padding,
|
|
601
|
+
snap: hasSnap ? 'snap' : null,
|
|
602
|
+
edgeFade: hasEdgeFade ? 'edge-fade' : null,
|
|
603
|
+
}),
|
|
604
|
+
stylex.props(
|
|
605
|
+
styles.scroller,
|
|
606
|
+
gapStyles[gap],
|
|
607
|
+
padding != null && paddingStyles[padding],
|
|
608
|
+
hasSnap && styles.snap,
|
|
609
|
+
fadeStyle,
|
|
610
|
+
),
|
|
532
611
|
)}>
|
|
533
612
|
{slides.map((child, index) => (
|
|
534
613
|
// APG carousel pattern: each slide container is a group with
|
|
@@ -560,6 +639,7 @@ export function Carousel({
|
|
|
560
639
|
!canScrollStart && styles.buttonHidden,
|
|
561
640
|
)}>
|
|
562
641
|
<Button
|
|
642
|
+
ref={startButtonRef}
|
|
563
643
|
icon={
|
|
564
644
|
<Icon
|
|
565
645
|
icon="chevronLeft"
|
|
@@ -572,10 +652,21 @@ export function Carousel({
|
|
|
572
652
|
size="sm"
|
|
573
653
|
isIconOnly
|
|
574
654
|
// Disabled when there's nothing to scroll toward. Keeps the
|
|
575
|
-
// button mounted (stable layout
|
|
576
|
-
//
|
|
577
|
-
//
|
|
655
|
+
// button mounted (stable layout) but removes it from the tab
|
|
656
|
+
// order and a11y tree while it's visually hidden, so keyboard
|
|
657
|
+
// users don't land on an invisible control. The Effect above
|
|
658
|
+
// hands focus to the other button when the state behind this
|
|
659
|
+
// one flips it disabled.
|
|
578
660
|
isDisabled={!canScrollStart}
|
|
661
|
+
onFocus={() => {
|
|
662
|
+
focusedNavRef.current = 'start';
|
|
663
|
+
}}
|
|
664
|
+
onBlur={event => {
|
|
665
|
+
// A disabled button was blurred by the commit, not the person.
|
|
666
|
+
if (!event.currentTarget.disabled) {
|
|
667
|
+
focusedNavRef.current = null;
|
|
668
|
+
}
|
|
669
|
+
}}
|
|
579
670
|
onClick={() => scrollBy(-1)}
|
|
580
671
|
xstyle={styles.buttonRadiusOverride}
|
|
581
672
|
/>
|
|
@@ -587,6 +678,7 @@ export function Carousel({
|
|
|
587
678
|
!canScrollEnd && styles.buttonHidden,
|
|
588
679
|
)}>
|
|
589
680
|
<Button
|
|
681
|
+
ref={endButtonRef}
|
|
590
682
|
icon={
|
|
591
683
|
<Icon
|
|
592
684
|
icon="chevronRight"
|
|
@@ -601,6 +693,15 @@ export function Carousel({
|
|
|
601
693
|
// See "Scroll left" — disabled while visually hidden so the
|
|
602
694
|
// button stays mounted but out of the tab order / a11y tree.
|
|
603
695
|
isDisabled={!canScrollEnd}
|
|
696
|
+
onFocus={() => {
|
|
697
|
+
focusedNavRef.current = 'end';
|
|
698
|
+
}}
|
|
699
|
+
onBlur={event => {
|
|
700
|
+
// A disabled button was blurred by the commit, not the person.
|
|
701
|
+
if (!event.currentTarget.disabled) {
|
|
702
|
+
focusedNavRef.current = null;
|
|
703
|
+
}
|
|
704
|
+
}}
|
|
604
705
|
onClick={() => scrollBy(1)}
|
|
605
706
|
xstyle={styles.buttonRadiusOverride}
|
|
606
707
|
/>
|
|
@@ -133,6 +133,7 @@ export const docs = {
|
|
|
133
133
|
{className: 'astryx-checkbox-input', visualProps: ['size']},
|
|
134
134
|
{className: 'astryx-checkbox-indicator', visualProps: ['size'], states: ['checked', 'disabled']},
|
|
135
135
|
{className: 'astryx-checkbox', visualProps: ['size'], states: ['checked', 'disabled'], deprecatedFor: 'checkbox-indicator'},
|
|
136
|
+
{className: 'astryx-checkbox-label'},
|
|
136
137
|
],
|
|
137
138
|
},
|
|
138
139
|
usage: {
|
|
@@ -209,6 +210,7 @@ export const docsZh = {
|
|
|
209
210
|
},
|
|
210
211
|
{className: 'astryx-checkbox-indicator', visualProps: ['size'], states: ['checked', 'disabled']},
|
|
211
212
|
{className: 'astryx-checkbox', visualProps: ['size'], states: ['checked', 'disabled'], deprecatedFor: 'checkbox-indicator'},
|
|
213
|
+
{className: 'astryx-checkbox-label'},
|
|
212
214
|
],
|
|
213
215
|
},
|
|
214
216
|
};
|
|
@@ -719,3 +719,18 @@ describe('focus ring ownership (WCAG 2.4.7)', () => {
|
|
|
719
719
|
expect(indicatorOf(container).style.outlineStyle).toBe('');
|
|
720
720
|
});
|
|
721
721
|
});
|
|
722
|
+
|
|
723
|
+
describe('label theme target', () => {
|
|
724
|
+
it('names its own label so a theme can style it apart from a field label', () => {
|
|
725
|
+
// The control knows this label shares a row with it; the label does not.
|
|
726
|
+
// Both classes land on the one element, so a theme reaches every label
|
|
727
|
+
// through `astryx-field-label` and only this kind through
|
|
728
|
+
// `astryx-checkbox-label`.
|
|
729
|
+
render(
|
|
730
|
+
<CheckboxInput label="Notify me" value={false} onChange={() => {}} />,
|
|
731
|
+
);
|
|
732
|
+
const label = screen.getByText('Notify me').closest('label');
|
|
733
|
+
expect(label).toHaveClass('astryx-field-label');
|
|
734
|
+
expect(label).toHaveClass('astryx-checkbox-label');
|
|
735
|
+
});
|
|
736
|
+
});
|
|
@@ -478,6 +478,11 @@ export function CheckboxInput({
|
|
|
478
478
|
</div>
|
|
479
479
|
<div {...stylex.props(styles.labelWrapper)}>
|
|
480
480
|
<FieldLabel
|
|
481
|
+
// A checkbox's label shares a row with its control, unlike a form
|
|
482
|
+
// field's label above its input. Naming the label rather than the
|
|
483
|
+
// arrangement means a theme asks for the thing it wants, and the
|
|
484
|
+
// component that actually knows what this is says so.
|
|
485
|
+
{...themeProps('checkbox-label')}
|
|
481
486
|
label={label}
|
|
482
487
|
inputID={id}
|
|
483
488
|
isLabelHidden={isLabelHidden}
|
|
@@ -147,10 +147,16 @@ export const docs = {
|
|
|
147
147
|
theming: {
|
|
148
148
|
targets: [
|
|
149
149
|
{className: 'astryx-code', visualProps: ['color']},
|
|
150
|
-
{className: 'astryx-
|
|
151
|
-
{className: 'astryx-
|
|
152
|
-
{className: 'astryx-
|
|
153
|
-
{className: 'astryx-
|
|
150
|
+
{className: 'astryx-code-block', visualProps: ['size', 'language', 'container']},
|
|
151
|
+
{className: 'astryx-code-block-header', visualProps: ['size', 'language', 'container']},
|
|
152
|
+
{className: 'astryx-code-block-title', visualProps: ['size', 'language']},
|
|
153
|
+
{className: 'astryx-code-block-copy-button'},
|
|
154
|
+
// Still emitted beside the names above, so themes written against
|
|
155
|
+
// them keep working. Drop in the next major.
|
|
156
|
+
{className: 'astryx-codeblock', visualProps: ['size', 'language', 'container'], deprecatedFor: 'code-block'},
|
|
157
|
+
{className: 'astryx-codeblock-header', visualProps: ['size', 'language', 'container'], deprecatedFor: 'code-block-header'},
|
|
158
|
+
{className: 'astryx-codeblock-title', visualProps: ['size', 'language'], deprecatedFor: 'code-block-title'},
|
|
159
|
+
{className: 'astryx-codeblock-copy-button', deprecatedFor: 'code-block-copy-button'},
|
|
154
160
|
],
|
|
155
161
|
vars: [
|
|
156
162
|
{name: '--_codeblock-gutter-width', description: 'Width of the line-number gutter, computed from the digit count of the last line so the code column starts at a stable offset.', default: '2ch', private: true},
|
|
@@ -396,3 +396,40 @@ describe('CodeBlock', () => {
|
|
|
396
396
|
});
|
|
397
397
|
});
|
|
398
398
|
});
|
|
399
|
+
|
|
400
|
+
describe('CodeBlock theme target names', () => {
|
|
401
|
+
it('renders the deprecated classes beside the current ones', () => {
|
|
402
|
+
const {container} = render(
|
|
403
|
+
<CodeBlock
|
|
404
|
+
code="const x = 1;"
|
|
405
|
+
language="javascript"
|
|
406
|
+
title="example.js"
|
|
407
|
+
/>,
|
|
408
|
+
);
|
|
409
|
+
expect(container.querySelector('.astryx-code-block')).toHaveClass(
|
|
410
|
+
'astryx-codeblock',
|
|
411
|
+
);
|
|
412
|
+
expect(container.querySelector('.astryx-code-block-header')).toHaveClass(
|
|
413
|
+
'astryx-codeblock-header',
|
|
414
|
+
);
|
|
415
|
+
expect(container.querySelector('.astryx-code-block-title')).toHaveClass(
|
|
416
|
+
'astryx-codeblock-title',
|
|
417
|
+
);
|
|
418
|
+
expect(screen.getByRole('button', {name: 'Copy code'})).toHaveClass(
|
|
419
|
+
'astryx-code-block-copy-button',
|
|
420
|
+
);
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
it('reaches the header and title through the current defineTheme keys', () => {
|
|
424
|
+
const theme = defineTheme({
|
|
425
|
+
name: 'code-block-header-target-test',
|
|
426
|
+
components: {
|
|
427
|
+
'code-block-header': {base: {paddingBlock: 'var(--spacing-1)'}},
|
|
428
|
+
'code-block-title': {base: {fontSize: 'var(--text-body-size)'}},
|
|
429
|
+
},
|
|
430
|
+
});
|
|
431
|
+
const css = generateThemeTestCSS(theme);
|
|
432
|
+
expect(css).toContain('.astryx-code-block-header');
|
|
433
|
+
expect(css).toContain('.astryx-code-block-title');
|
|
434
|
+
});
|
|
435
|
+
});
|
|
@@ -810,14 +810,20 @@ export function CodeBlock({
|
|
|
810
810
|
void handleCopy();
|
|
811
811
|
}}
|
|
812
812
|
xstyle={[styles.copyButton, !showHeader && styles.copyButtonAbsolute]}
|
|
813
|
-
{...themeProps('
|
|
813
|
+
{...themeProps('code-block-copy-button', undefined, {
|
|
814
|
+
legacyNames: ['codeblock-copy-button'],
|
|
815
|
+
})}
|
|
814
816
|
/>
|
|
815
817
|
) : null;
|
|
816
818
|
|
|
817
819
|
const headerEl = showHeader ? (
|
|
818
820
|
<div
|
|
819
821
|
{...mergeProps(
|
|
820
|
-
themeProps(
|
|
822
|
+
themeProps(
|
|
823
|
+
'code-block-header',
|
|
824
|
+
{size, language, container},
|
|
825
|
+
{legacyNames: ['codeblock-header']},
|
|
826
|
+
),
|
|
821
827
|
stylex.props(
|
|
822
828
|
styles.headerRow,
|
|
823
829
|
hasLineNumbers ? styles.headerWithDivider : styles.headerCompact,
|
|
@@ -845,7 +851,11 @@ export function CodeBlock({
|
|
|
845
851
|
)}>
|
|
846
852
|
<span
|
|
847
853
|
{...mergeProps(
|
|
848
|
-
themeProps(
|
|
854
|
+
themeProps(
|
|
855
|
+
'code-block-title',
|
|
856
|
+
{size, language},
|
|
857
|
+
{legacyNames: ['codeblock-title']},
|
|
858
|
+
),
|
|
849
859
|
stylex.props(styles.headerTitle),
|
|
850
860
|
)}>
|
|
851
861
|
{canCollapse && (
|
|
@@ -917,7 +927,13 @@ export function CodeBlock({
|
|
|
917
927
|
<pre
|
|
918
928
|
ref={ref}
|
|
919
929
|
{...mergeProps(
|
|
920
|
-
themeProps(
|
|
930
|
+
themeProps(
|
|
931
|
+
'code-block',
|
|
932
|
+
{size, language, container},
|
|
933
|
+
// `codeblock` ran the compound name together; themes styling it keep
|
|
934
|
+
// working until the next major.
|
|
935
|
+
{legacyNames: ['codeblock']},
|
|
936
|
+
),
|
|
921
937
|
stylex.props(
|
|
922
938
|
styles.root,
|
|
923
939
|
dynamicStyles.width(widthProp),
|
|
@@ -67,7 +67,7 @@ function ensureDynamicHighlightType(tokenType: string): void {
|
|
|
67
67
|
const name = `astryx-${tokenType}`;
|
|
68
68
|
const colorVar = `var(--color-syntax-${tokenType}, currentColor)`;
|
|
69
69
|
dynamicStyleSheet.insertRule(
|
|
70
|
-
`.astryx-
|
|
70
|
+
`.astryx-code-block code::highlight(${name}), .astryx-codeeditor code::highlight(${name}) { color: ${colorVar}; }`,
|
|
71
71
|
);
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -30,31 +30,31 @@ const FALLBACK_TOKENS = `:root {\n${Object.entries(syntaxTokenDefaults)
|
|
|
30
30
|
const HIGHLIGHT_STYLES = `
|
|
31
31
|
${FALLBACK_TOKENS}
|
|
32
32
|
|
|
33
|
-
.astryx-
|
|
33
|
+
.astryx-code-block code::highlight(astryx-keyword),
|
|
34
34
|
.astryx-codeeditor code::highlight(astryx-keyword) { color: var(--color-syntax-keyword); }
|
|
35
|
-
.astryx-
|
|
35
|
+
.astryx-code-block code::highlight(astryx-string),
|
|
36
36
|
.astryx-codeeditor code::highlight(astryx-string) { color: var(--color-syntax-string); }
|
|
37
|
-
.astryx-
|
|
37
|
+
.astryx-code-block code::highlight(astryx-comment),
|
|
38
38
|
.astryx-codeeditor code::highlight(astryx-comment) { color: var(--color-syntax-comment); }
|
|
39
|
-
.astryx-
|
|
39
|
+
.astryx-code-block code::highlight(astryx-number),
|
|
40
40
|
.astryx-codeeditor code::highlight(astryx-number) { color: var(--color-syntax-number); }
|
|
41
|
-
.astryx-
|
|
41
|
+
.astryx-code-block code::highlight(astryx-function),
|
|
42
42
|
.astryx-codeeditor code::highlight(astryx-function) { color: var(--color-syntax-function); }
|
|
43
|
-
.astryx-
|
|
43
|
+
.astryx-code-block code::highlight(astryx-type),
|
|
44
44
|
.astryx-codeeditor code::highlight(astryx-type) { color: var(--color-syntax-type); }
|
|
45
|
-
.astryx-
|
|
45
|
+
.astryx-code-block code::highlight(astryx-tag),
|
|
46
46
|
.astryx-codeeditor code::highlight(astryx-tag) { color: var(--color-syntax-tag); }
|
|
47
|
-
.astryx-
|
|
47
|
+
.astryx-code-block code::highlight(astryx-attribute),
|
|
48
48
|
.astryx-codeeditor code::highlight(astryx-attribute) { color: var(--color-syntax-attribute); }
|
|
49
|
-
.astryx-
|
|
49
|
+
.astryx-code-block code::highlight(astryx-property),
|
|
50
50
|
.astryx-codeeditor code::highlight(astryx-property) { color: var(--color-syntax-property); }
|
|
51
|
-
.astryx-
|
|
51
|
+
.astryx-code-block code::highlight(astryx-operator),
|
|
52
52
|
.astryx-codeeditor code::highlight(astryx-operator) { color: var(--color-syntax-operator); }
|
|
53
|
-
.astryx-
|
|
53
|
+
.astryx-code-block code::highlight(astryx-constant),
|
|
54
54
|
.astryx-codeeditor code::highlight(astryx-constant) { color: var(--color-syntax-constant); }
|
|
55
|
-
.astryx-
|
|
55
|
+
.astryx-code-block code::highlight(astryx-punctuation),
|
|
56
56
|
.astryx-codeeditor code::highlight(astryx-punctuation) { color: var(--color-syntax-punctuation); }
|
|
57
|
-
.astryx-
|
|
57
|
+
.astryx-code-block code::highlight(astryx-variable),
|
|
58
58
|
.astryx-codeeditor code::highlight(astryx-variable) { color: var(--color-syntax-variable); }
|
|
59
59
|
|
|
60
60
|
/* Span-based fallback classes — used when highlightMode='spans' or
|
|
@@ -26,9 +26,9 @@ import {
|
|
|
26
26
|
import {useCommandPaletteContext} from './CommandPaletteContext';
|
|
27
27
|
import {useDialogContext} from '../Dialog/DialogContext';
|
|
28
28
|
import {themeProps} from '../utils/themeProps';
|
|
29
|
+
import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
|
|
29
30
|
|
|
30
31
|
import {useMergedRefs} from '../hooks/useMergedRefs';
|
|
31
|
-
const HOVER_HOVER = '@media (hover: hover)';
|
|
32
32
|
|
|
33
33
|
const styles = stylex.create({
|
|
34
34
|
item: {
|
|
@@ -52,16 +52,6 @@ const styles = stylex.create({
|
|
|
52
52
|
outline: 'none',
|
|
53
53
|
userSelect: 'none',
|
|
54
54
|
},
|
|
55
|
-
itemHover: {
|
|
56
|
-
':hover:where(:not(:disabled,[aria-disabled="true"]))': {
|
|
57
|
-
[HOVER_HOVER]: {
|
|
58
|
-
backgroundColor: colorVars['--color-overlay-hover'],
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
':active': {
|
|
62
|
-
backgroundColor: colorVars['--color-overlay-pressed'],
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
55
|
itemHighlighted: {
|
|
66
56
|
backgroundColor: colorVars['--color-overlay-hover'],
|
|
67
57
|
},
|
|
@@ -205,7 +195,7 @@ export function CommandPaletteItem({
|
|
|
205
195
|
themeProps('command-palette-item'),
|
|
206
196
|
stylex.props(
|
|
207
197
|
styles.item,
|
|
208
|
-
!isDisabled &&
|
|
198
|
+
!isDisabled && interactionOverlayStyles.backgroundColor,
|
|
209
199
|
isHighlighted && styles.itemHighlighted,
|
|
210
200
|
isSelected && styles.itemSelected,
|
|
211
201
|
isDisabled && styles.itemDisabled,
|
|
@@ -143,6 +143,12 @@ export const docs = {
|
|
|
143
143
|
description:
|
|
144
144
|
'Imperative handle for programmatic control. Exposes open(), close(), toggle(), and isOpen().',
|
|
145
145
|
},
|
|
146
|
+
{
|
|
147
|
+
name: 'onOpenChange',
|
|
148
|
+
type: '(isOpen: boolean) => void',
|
|
149
|
+
description:
|
|
150
|
+
'Called whenever the surface opens or closes, however it happened — trigger, keyboard, light dismiss, Escape, close(), or the imperative handle.',
|
|
151
|
+
},
|
|
146
152
|
{
|
|
147
153
|
name: 'contentXstyle',
|
|
148
154
|
type: 'StyleXStyles',
|
|
@@ -274,6 +280,7 @@ export const docsDense = {
|
|
|
274
280
|
placement: 'Popup placement.',
|
|
275
281
|
alignment: 'Popup alignment.',
|
|
276
282
|
handleRef: 'Imperative open/close/toggle handle.',
|
|
283
|
+
onOpenChange: 'Notified on every open and close, whatever caused it.',
|
|
277
284
|
accessibility:
|
|
278
285
|
'Custom content must provide its own accessible structure. Use focus hooks and evaluate against WCAG 2.2.',
|
|
279
286
|
},
|
|
@@ -353,6 +353,7 @@ describe('ComplexSelector', () => {
|
|
|
353
353
|
.closest('[popover]');
|
|
354
354
|
expect(popover).not.toBeNull();
|
|
355
355
|
|
|
356
|
+
fireEvent.pointerDown(trigger);
|
|
356
357
|
const closeEvent = new Event('toggle');
|
|
357
358
|
Object.defineProperty(closeEvent, 'newState', {value: 'closed'});
|
|
358
359
|
fireEvent(popover as HTMLElement, closeEvent);
|
|
@@ -417,4 +418,186 @@ describe('ComplexSelector popup theme target', () => {
|
|
|
417
418
|
document.querySelector('.astryx-complex-selector-popup'),
|
|
418
419
|
).not.toBeNull();
|
|
419
420
|
});
|
|
421
|
+
|
|
422
|
+
it('stays closed when the trigger click follows its own light dismiss (#5004)', async () => {
|
|
423
|
+
const user = userEvent.setup();
|
|
424
|
+
render(
|
|
425
|
+
<ComplexSelector label="Fruit blend" value="Apple" triggerLabel="Apple">
|
|
426
|
+
{() => <button type="button">Done</button>}
|
|
427
|
+
</ComplexSelector>,
|
|
428
|
+
);
|
|
429
|
+
const trigger = screen.getByRole('button', {name: 'Fruit blend'});
|
|
430
|
+
await user.click(trigger);
|
|
431
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'true');
|
|
432
|
+
|
|
433
|
+
// The browser dismissed the popup on pointerup and queued the toggle. When
|
|
434
|
+
// that event lands before the click — WebKit, or any engine under load —
|
|
435
|
+
// the click used to read a closed popup and reopen it.
|
|
436
|
+
fireEvent.pointerDown(trigger);
|
|
437
|
+
const popover = document.querySelector('[popover]') as HTMLElement;
|
|
438
|
+
act(() => {
|
|
439
|
+
popover.dispatchEvent(
|
|
440
|
+
Object.assign(new Event('toggle'), {
|
|
441
|
+
oldState: 'open',
|
|
442
|
+
newState: 'closed',
|
|
443
|
+
}),
|
|
444
|
+
);
|
|
445
|
+
});
|
|
446
|
+
// Synchronously: the click falls inside the one gesture the guard covers,
|
|
447
|
+
// as it does in a browser a few milliseconds behind the dismissal.
|
|
448
|
+
fireEvent.click(trigger);
|
|
449
|
+
|
|
450
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'false');
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
describe('ComplexSelector onOpenChange', () => {
|
|
455
|
+
function renderSelector(onOpenChange: (isOpen: boolean) => void) {
|
|
456
|
+
render(
|
|
457
|
+
<ComplexSelector
|
|
458
|
+
label="View options"
|
|
459
|
+
value={[]}
|
|
460
|
+
onOpenChange={onOpenChange}>
|
|
461
|
+
{(_value, _onChange, close) => (
|
|
462
|
+
<button type="button" onClick={close}>
|
|
463
|
+
Apply
|
|
464
|
+
</button>
|
|
465
|
+
)}
|
|
466
|
+
</ComplexSelector>,
|
|
467
|
+
);
|
|
468
|
+
return screen.getByRole('button', {name: 'View options'});
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
it('reports the open and the close of a trigger toggle', async () => {
|
|
472
|
+
const user = userEvent.setup();
|
|
473
|
+
const onOpenChange = vi.fn();
|
|
474
|
+
const trigger = renderSelector(onOpenChange);
|
|
475
|
+
|
|
476
|
+
await user.click(trigger);
|
|
477
|
+
expect(onOpenChange.mock.calls).toEqual([[true]]);
|
|
478
|
+
|
|
479
|
+
await user.click(trigger);
|
|
480
|
+
expect(onOpenChange.mock.calls).toEqual([[true], [false]]);
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
it('reports an open from ArrowDown', async () => {
|
|
484
|
+
const user = userEvent.setup();
|
|
485
|
+
const onOpenChange = vi.fn();
|
|
486
|
+
const trigger = renderSelector(onOpenChange);
|
|
487
|
+
|
|
488
|
+
trigger.focus();
|
|
489
|
+
await user.keyboard('{ArrowDown}');
|
|
490
|
+
|
|
491
|
+
expect(onOpenChange.mock.calls).toEqual([[true]]);
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
it('reports a close from Escape', async () => {
|
|
495
|
+
const user = userEvent.setup();
|
|
496
|
+
const onOpenChange = vi.fn();
|
|
497
|
+
const trigger = renderSelector(onOpenChange);
|
|
498
|
+
|
|
499
|
+
await user.click(trigger);
|
|
500
|
+
onOpenChange.mockClear();
|
|
501
|
+
await user.keyboard('{Escape}');
|
|
502
|
+
|
|
503
|
+
expect(onOpenChange.mock.calls).toEqual([[false]]);
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
it('reports a close the browser performed (light dismiss)', async () => {
|
|
507
|
+
const user = userEvent.setup();
|
|
508
|
+
const onOpenChange = vi.fn();
|
|
509
|
+
const trigger = renderSelector(onOpenChange);
|
|
510
|
+
|
|
511
|
+
await user.click(trigger);
|
|
512
|
+
onOpenChange.mockClear();
|
|
513
|
+
|
|
514
|
+
const popover = screen
|
|
515
|
+
.getByRole('dialog', {hidden: true})
|
|
516
|
+
.closest('[popover]') as HTMLElement;
|
|
517
|
+
const closeEvent = new Event('toggle');
|
|
518
|
+
Object.defineProperty(closeEvent, 'newState', {value: 'closed'});
|
|
519
|
+
fireEvent(popover, closeEvent);
|
|
520
|
+
|
|
521
|
+
expect(onOpenChange.mock.calls).toEqual([[false]]);
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
it('reports a gesture light dismiss once without reopening from its click', async () => {
|
|
525
|
+
const user = userEvent.setup();
|
|
526
|
+
const onOpenChange = vi.fn();
|
|
527
|
+
const trigger = renderSelector(onOpenChange);
|
|
528
|
+
|
|
529
|
+
await user.click(trigger);
|
|
530
|
+
onOpenChange.mockClear();
|
|
531
|
+
|
|
532
|
+
const popover = screen
|
|
533
|
+
.getByRole('dialog', {hidden: true})
|
|
534
|
+
.closest('[popover]') as HTMLElement;
|
|
535
|
+
fireEvent.pointerDown(trigger);
|
|
536
|
+
fireEvent(
|
|
537
|
+
popover,
|
|
538
|
+
Object.assign(new Event('toggle'), {
|
|
539
|
+
oldState: 'open',
|
|
540
|
+
newState: 'closed',
|
|
541
|
+
}),
|
|
542
|
+
);
|
|
543
|
+
fireEvent.click(trigger);
|
|
544
|
+
|
|
545
|
+
expect(onOpenChange.mock.calls).toEqual([[false]]);
|
|
546
|
+
expect(trigger).toHaveAttribute('aria-expanded', 'false');
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
it('reports a close from content calling close()', async () => {
|
|
550
|
+
const user = userEvent.setup();
|
|
551
|
+
const onOpenChange = vi.fn();
|
|
552
|
+
const trigger = renderSelector(onOpenChange);
|
|
553
|
+
|
|
554
|
+
await user.click(trigger);
|
|
555
|
+
onOpenChange.mockClear();
|
|
556
|
+
await user.click(screen.getByRole('button', {name: 'Apply', ...h}));
|
|
557
|
+
|
|
558
|
+
expect(onOpenChange.mock.calls).toEqual([[false]]);
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
it('reports opens and closes driven through the imperative handle', () => {
|
|
562
|
+
const onOpenChange = vi.fn();
|
|
563
|
+
const handleRef = React.createRef<ComplexSelectorHandle>();
|
|
564
|
+
render(
|
|
565
|
+
<ComplexSelector
|
|
566
|
+
label="View options"
|
|
567
|
+
value={[]}
|
|
568
|
+
handleRef={handleRef}
|
|
569
|
+
onOpenChange={onOpenChange}>
|
|
570
|
+
{() => <button type="button">Apply</button>}
|
|
571
|
+
</ComplexSelector>,
|
|
572
|
+
);
|
|
573
|
+
|
|
574
|
+
act(() => handleRef.current?.open());
|
|
575
|
+
act(() => handleRef.current?.close());
|
|
576
|
+
act(() => handleRef.current?.toggle());
|
|
577
|
+
|
|
578
|
+
expect(onOpenChange.mock.calls).toEqual([[true], [false], [true]]);
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
it('does not report a state it is already in', async () => {
|
|
582
|
+
const user = userEvent.setup();
|
|
583
|
+
const onOpenChange = vi.fn();
|
|
584
|
+
const handleRef = React.createRef<ComplexSelectorHandle>();
|
|
585
|
+
render(
|
|
586
|
+
<ComplexSelector
|
|
587
|
+
label="View options"
|
|
588
|
+
value={[]}
|
|
589
|
+
handleRef={handleRef}
|
|
590
|
+
onOpenChange={onOpenChange}>
|
|
591
|
+
{() => <button type="button">Apply</button>}
|
|
592
|
+
</ComplexSelector>,
|
|
593
|
+
);
|
|
594
|
+
const trigger = screen.getByRole('button', {name: 'View options'});
|
|
595
|
+
|
|
596
|
+
act(() => handleRef.current?.close());
|
|
597
|
+
expect(onOpenChange).not.toHaveBeenCalled();
|
|
598
|
+
|
|
599
|
+
await user.click(trigger);
|
|
600
|
+
act(() => handleRef.current?.open());
|
|
601
|
+
expect(onOpenChange.mock.calls).toEqual([[true]]);
|
|
602
|
+
});
|
|
420
603
|
});
|