@astryxdesign/core 0.1.8 → 0.1.9-canary.02ef052
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 +100 -0
- package/dist/AppShell/AppShell.d.ts.map +1 -1
- package/dist/AppShell/AppShell.js +6 -2
- package/dist/AppShell/AppShellMobileContext.d.ts +8 -0
- package/dist/AppShell/AppShellMobileContext.d.ts.map +1 -1
- package/dist/Avatar/Avatar.d.ts +58 -3
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +240 -53
- package/dist/Avatar/AvatarStatusDot.d.ts +35 -5
- package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
- package/dist/Avatar/AvatarStatusDot.js +144 -19
- package/dist/AvatarGroup/AvatarGroup.d.ts +7 -1
- package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroup.js +58 -6
- package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
- package/dist/AvatarGroup/AvatarGroupOverflow.js +1 -0
- package/dist/Banner/Banner.d.ts +9 -1
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +33 -4
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts +31 -2
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +215 -6
- package/dist/Breadcrumbs/index.d.ts +6 -0
- package/dist/Breadcrumbs/index.d.ts.map +1 -1
- package/dist/Breadcrumbs/index.js +10 -1
- package/dist/Button/Button.d.ts +8 -2
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +33 -4
- package/dist/ButtonGroup/ButtonGroup.d.ts +9 -1
- package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
- package/dist/ButtonGroup/ButtonGroup.js +30 -1
- package/dist/Calendar/Calendar.d.ts.map +1 -1
- package/dist/Calendar/Calendar.js +80 -11
- package/dist/Calendar/dayCellUtils.d.ts +4 -4
- package/dist/Calendar/dayCellUtils.js +3 -3
- package/dist/Calendar/styles.d.ts +30 -31
- package/dist/Calendar/styles.d.ts.map +1 -1
- package/dist/Calendar/styles.js +30 -31
- package/dist/Card/Card.d.ts +8 -2
- package/dist/Card/Card.d.ts.map +1 -1
- package/dist/Card/Card.js +28 -2
- package/dist/Carousel/Carousel.d.ts +4 -1
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +46 -16
- package/dist/Chat/ChatComposer.d.ts +8 -0
- package/dist/Chat/ChatComposer.d.ts.map +1 -1
- package/dist/Chat/ChatComposer.js +46 -7
- package/dist/Chat/ChatComposerDrawer.d.ts +2 -0
- package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
- package/dist/Chat/ChatComposerDrawer.js +11 -1
- package/dist/Chat/ChatComposerInput.d.ts +20 -3
- package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
- package/dist/Chat/ChatComposerInput.js +36 -4
- package/dist/Chat/ChatContext.d.ts +33 -0
- package/dist/Chat/ChatContext.d.ts.map +1 -1
- package/dist/Chat/ChatContext.js +16 -2
- package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
- package/dist/Chat/ChatDictationButton.js +4 -2
- package/dist/Chat/ChatLayout.d.ts.map +1 -1
- package/dist/Chat/ChatLayout.js +4 -4
- package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
- package/dist/Chat/ChatLayoutScrollButton.js +4 -4
- package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
- package/dist/Chat/ChatSendButton.d.ts.map +1 -1
- package/dist/Chat/ChatSendButton.js +7 -1
- package/dist/Chat/ChatToolCalls.d.ts +5 -1
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +27 -11
- package/dist/Chat/index.d.ts +2 -1
- package/dist/Chat/index.d.ts.map +1 -1
- package/dist/Chat/index.js +1 -1
- package/dist/Chat/useChatStreamScroll.d.ts +2 -1
- package/dist/Chat/useChatStreamScroll.d.ts.map +1 -1
- package/dist/Chat/useChatStreamScroll.js +22 -8
- package/dist/Chat/useSpeechRecognition.d.ts +0 -1
- package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
- package/dist/Chat/useSpeechRecognition.js +1 -1
- package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
- package/dist/Chat/useTriggerMenu.js +2 -2
- package/dist/CheckboxInput/CheckboxInput.js +5 -5
- package/dist/CheckboxList/CheckboxListItem.d.ts +20 -1
- package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
- package/dist/CheckboxList/CheckboxListItem.js +11 -1
- package/dist/Citation/Citation.d.ts +22 -1
- package/dist/Citation/Citation.d.ts.map +1 -1
- package/dist/Citation/Citation.js +20 -6
- package/dist/ClickableCard/ClickableCard.d.ts +9 -2
- package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
- package/dist/ClickableCard/ClickableCard.js +5 -2
- package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/CodeBlock/CodeBlock.js +22 -9
- package/dist/Collapsible/Collapsible.d.ts.map +1 -1
- package/dist/Collapsible/Collapsible.js +3 -1
- package/dist/CommandPalette/CommandPalette.d.ts +2 -2
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +45 -4
- package/dist/CommandPalette/CommandPaletteGroup.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteGroup.js +9 -2
- package/dist/CommandPalette/CommandPaletteInput.d.ts +7 -1
- package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPaletteInput.js +6 -1
- package/dist/CommandPalette/CommandPaletteItem.js +1 -1
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +14 -5
- package/dist/ContextMenu/index.d.ts +1 -0
- package/dist/ContextMenu/index.d.ts.map +1 -1
- package/dist/ContextMenu/index.js +3 -1
- package/dist/DateInput/DateInput.d.ts +56 -2
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +59 -21
- package/dist/DateInput/index.d.ts +1 -1
- package/dist/DateInput/index.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.d.ts +10 -2
- package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
- package/dist/DateRangeInput/DateRangeInput.js +23 -20
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +33 -19
- package/dist/Dialog/Dialog.d.ts +3 -0
- package/dist/Dialog/Dialog.d.ts.map +1 -1
- package/dist/Dialog/Dialog.js +57 -6
- package/dist/Dialog/DialogContext.d.ts +7 -0
- package/dist/Dialog/DialogContext.d.ts.map +1 -1
- package/dist/Dialog/DialogContext.js +2 -2
- package/dist/Dialog/DialogHeader.d.ts +5 -2
- package/dist/Dialog/DialogHeader.d.ts.map +1 -1
- package/dist/Dialog/DialogHeader.js +6 -1
- package/dist/Divider/Divider.js +1 -1
- package/dist/DropdownMenu/DropdownMenu.d.ts +6 -0
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +22 -5
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +1 -2
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +5 -3
- package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.js +5 -2
- package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +1 -2
- package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioGroup.js +1 -2
- package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuRadioItem.js +4 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +104 -0
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -0
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +427 -0
- package/dist/DropdownMenu/index.d.ts +10 -0
- package/dist/DropdownMenu/index.d.ts.map +1 -1
- package/dist/DropdownMenu/index.js +13 -0
- package/dist/DropdownMenu/menuItemHover.d.ts +23 -0
- package/dist/DropdownMenu/menuItemHover.d.ts.map +1 -0
- package/dist/DropdownMenu/menuItemHover.js +33 -0
- package/dist/DropdownMenu/menuItemRoles.d.ts +8 -0
- package/dist/DropdownMenu/menuItemRoles.d.ts.map +1 -1
- package/dist/DropdownMenu/menuItemRoles.js +10 -1
- package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
- package/dist/DropdownMenu/renderDropdownItems.js +21 -6
- package/dist/Field/Field.d.ts +3 -1
- package/dist/Field/Field.d.ts.map +1 -1
- package/dist/Field/Field.js +6 -4
- package/dist/Field/FieldLabel.d.ts +1 -1
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +43 -16
- package/dist/Field/inputStyles.stylex.d.ts +1 -0
- package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
- package/dist/Field/inputStyles.stylex.js +1 -0
- package/dist/FieldStatus/FieldStatus.d.ts +18 -0
- package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
- package/dist/FieldStatus/FieldStatus.js +60 -6
- package/dist/FileInput/FileInput.d.ts +10 -2
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +54 -35
- package/dist/HoverCard/HoverCard.d.ts +9 -1
- package/dist/HoverCard/HoverCard.d.ts.map +1 -1
- package/dist/HoverCard/HoverCard.js +2 -0
- package/dist/HoverCard/useHoverCard.d.ts +8 -0
- package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
- package/dist/HoverCard/useHoverCard.js +17 -6
- package/dist/Icon/Icon.d.ts +22 -3
- package/dist/Icon/Icon.d.ts.map +1 -1
- package/dist/Icon/Icon.js +19 -3
- package/dist/Item/Item.d.ts +6 -1
- package/dist/Item/Item.d.ts.map +1 -1
- package/dist/Item/Item.js +22 -1
- package/dist/Layer/useLayer.d.ts +6 -0
- package/dist/Layer/useLayer.d.ts.map +1 -1
- package/dist/Layer/useLayer.js +2 -0
- package/dist/Lightbox/Lightbox.d.ts.map +1 -1
- package/dist/Lightbox/Lightbox.js +19 -13
- package/dist/Markdown/Markdown.d.ts.map +1 -1
- package/dist/Markdown/Markdown.js +7 -0
- package/dist/MobileNav/MobileNav.d.ts.map +1 -1
- package/dist/MobileNav/MobileNav.js +6 -1
- package/dist/MobileNav/MobileNavToggle.d.ts.map +1 -1
- package/dist/MobileNav/MobileNavToggle.js +4 -0
- package/dist/MultiSelector/MultiSelector.d.ts +9 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +104 -50
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +16 -0
- package/dist/NavMenu/NavHeadingMenuItem.js +1 -1
- package/dist/NumberInput/NumberInput.d.ts +10 -2
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/NumberInput/NumberInput.js +22 -17
- package/dist/Outline/Outline.d.ts +0 -1
- package/dist/Outline/Outline.d.ts.map +1 -1
- package/dist/Outline/Outline.js +0 -1
- package/dist/OverflowList/OverflowList.d.ts +20 -3
- package/dist/OverflowList/OverflowList.d.ts.map +1 -1
- package/dist/OverflowList/OverflowList.js +29 -4
- package/dist/Pagination/Pagination.d.ts.map +1 -1
- package/dist/Pagination/Pagination.js +11 -3
- package/dist/Popover/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +3 -2
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +3 -9
- package/dist/PowerSearch/PowerSearch.d.ts +9 -2
- package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
- package/dist/PowerSearch/PowerSearch.js +2 -0
- package/dist/PowerSearch/PowerSearchEditPopover.js +1 -1
- package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
- package/dist/RadioList/RadioList.d.ts +2 -2
- package/dist/RadioList/RadioListItem.js +4 -4
- package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
- package/dist/SegmentedControl/SegmentedControlItem.js +2 -1
- package/dist/SelectableCard/SelectableCard.d.ts +9 -2
- package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
- package/dist/SelectableCard/SelectableCard.js +16 -13
- package/dist/Selector/Selector.d.ts +8 -0
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +65 -19
- package/dist/Selector/hooks.d.ts.map +1 -1
- package/dist/Selector/hooks.js +16 -0
- package/dist/SideNav/SideNav.d.ts.map +1 -1
- package/dist/SideNav/SideNav.js +5 -5
- package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
- package/dist/SideNav/SideNavCollapseButton.js +13 -10
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +21 -8
- package/dist/SideNav/SideNavItem.d.ts +1 -1
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/SideNav/SideNavItem.js +12 -10
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +106 -36
- package/dist/Stack/stack.stylex.d.ts +9 -9
- package/dist/Switch/Switch.d.ts +8 -1
- package/dist/Switch/Switch.d.ts.map +1 -1
- package/dist/Switch/Switch.js +160 -91
- package/dist/TabList/Tab.js +2 -2
- package/dist/TabList/TabMenu.js +1 -1
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +33 -6
- package/dist/Table/TableCell.js +3 -3
- package/dist/Table/TableHeaderCell.js +3 -3
- package/dist/Table/index.d.ts +2 -0
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +1 -0
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
- package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +15 -11
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
- package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +36 -26
- package/dist/Table/plugins/rowStatus/index.d.ts +3 -0
- package/dist/Table/plugins/rowStatus/index.d.ts.map +1 -0
- package/dist/Table/plugins/rowStatus/index.js +3 -0
- package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts +60 -0
- package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -0
- package/dist/Table/plugins/rowStatus/useTableRowStatus.js +145 -0
- package/dist/Table/plugins/selection/useTableSelection.d.ts +13 -0
- package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
- package/dist/Table/plugins/selection/useTableSelection.js +7 -1
- package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +1 -1
- package/dist/Table/plugins/tree/useTableTreeData.d.ts +16 -0
- package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
- package/dist/Table/plugins/tree/useTableTreeData.js +105 -12
- package/dist/Table/plugins/tree/useTableTreeState.d.ts +6 -0
- package/dist/Table/plugins/tree/useTableTreeState.d.ts.map +1 -1
- package/dist/Table/plugins/tree/useTableTreeState.js +22 -1
- package/dist/Table/types.d.ts +32 -0
- package/dist/Table/types.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.js +5 -3
- package/dist/TextArea/TextArea.d.ts +10 -1
- package/dist/TextArea/TextArea.d.ts.map +1 -1
- package/dist/TextArea/TextArea.js +18 -19
- package/dist/TextInput/TextInput.d.ts +10 -2
- package/dist/TextInput/TextInput.d.ts.map +1 -1
- package/dist/TextInput/TextInput.js +20 -17
- package/dist/Thumbnail/Thumbnail.d.ts +26 -5
- package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
- package/dist/Thumbnail/Thumbnail.js +97 -54
- package/dist/Thumbnail/thumbnail.markers.stylex.d.ts +9 -0
- package/dist/Thumbnail/thumbnail.markers.stylex.d.ts.map +1 -0
- package/dist/Thumbnail/thumbnail.markers.stylex.js +14 -0
- package/dist/TimeInput/TimeInput.d.ts +10 -2
- package/dist/TimeInput/TimeInput.d.ts.map +1 -1
- package/dist/TimeInput/TimeInput.js +32 -21
- package/dist/Timestamp/Timestamp.d.ts +3 -1
- package/dist/Timestamp/Timestamp.d.ts.map +1 -1
- package/dist/Timestamp/Timestamp.js +8 -6
- package/dist/Toast/useToast.d.ts.map +1 -1
- package/dist/Toast/useToast.js +2 -5
- package/dist/ToggleButton/ToggleButtonGroup.d.ts +0 -1
- package/dist/ToggleButton/ToggleButtonGroup.d.ts.map +1 -1
- package/dist/ToggleButton/ToggleButtonGroup.js +1 -1
- package/dist/Token/Token.d.ts +30 -3
- package/dist/Token/Token.d.ts.map +1 -1
- package/dist/Token/Token.js +17 -2
- package/dist/Token/index.d.ts +1 -1
- package/dist/Token/index.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.d.ts +10 -3
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +20 -6
- package/dist/Tooltip/useTooltip.d.ts.map +1 -1
- package/dist/Tooltip/useTooltip.js +17 -1
- package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
- package/dist/TopNav/TopNavHeading.js +18 -8
- package/dist/TopNav/TopNavMegaMenu.js +10 -4
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts +9 -1
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts.map +1 -1
- package/dist/TopNav/TopNavMegaMenuFeaturedCard.js +8 -1
- package/dist/TopNav/TopNavMenu.d.ts +2 -1
- package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
- package/dist/TopNav/TopNavMenu.js +68 -6
- package/dist/TreeList/TreeList.d.ts +12 -3
- package/dist/TreeList/TreeList.d.ts.map +1 -1
- package/dist/TreeList/TreeList.js +3 -0
- package/dist/TreeList/TreeListBranches.d.ts +5 -0
- package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
- package/dist/TreeList/TreeListBranches.js +18 -10
- package/dist/TreeList/TreeListItem.d.ts +8 -2
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +59 -21
- package/dist/TreeList/TreeListTypes.d.ts +25 -1
- package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
- package/dist/TreeList/index.d.ts +2 -2
- package/dist/TreeList/index.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
- package/dist/Typeahead/BaseTypeahead.js +20 -11
- package/dist/Typeahead/Typeahead.d.ts +9 -2
- package/dist/Typeahead/Typeahead.d.ts.map +1 -1
- package/dist/Typeahead/Typeahead.js +3 -1
- package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
- package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
- package/dist/Typeahead/TypeaheadItem.js +20 -10
- package/dist/astryx.css +61 -39
- package/dist/astryx.umd.js +53 -53
- package/dist/astryx.umd.js.map +4 -4
- package/dist/authoring/doc.d.ts.map +1 -1
- package/dist/docs-types.d.ts +8 -0
- package/dist/docs-types.d.ts.map +1 -1
- package/dist/hooks/computeOverflow.d.ts +47 -0
- package/dist/hooks/computeOverflow.d.ts.map +1 -0
- package/dist/hooks/computeOverflow.js +213 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +3 -1
- package/dist/hooks/isRtlElement.d.ts +18 -0
- package/dist/hooks/isRtlElement.d.ts.map +1 -0
- package/dist/hooks/isRtlElement.js +27 -0
- package/dist/hooks/useDevWarning.d.ts +18 -0
- package/dist/hooks/useDevWarning.d.ts.map +1 -0
- package/dist/hooks/useDevWarning.js +49 -0
- package/dist/hooks/useGridFocus.d.ts +6 -1
- package/dist/hooks/useGridFocus.d.ts.map +1 -1
- package/dist/hooks/useGridFocus.js +12 -9
- package/dist/hooks/useInputStatusIcon.d.ts +38 -0
- package/dist/hooks/useInputStatusIcon.d.ts.map +1 -0
- package/dist/hooks/useInputStatusIcon.js +158 -0
- package/dist/hooks/useListFocus.d.ts +39 -1
- package/dist/hooks/useListFocus.d.ts.map +1 -1
- package/dist/hooks/useListFocus.js +54 -9
- package/dist/hooks/useOverflow.d.ts +19 -0
- package/dist/hooks/useOverflow.d.ts.map +1 -1
- package/dist/hooks/useOverflow.js +36 -25
- package/dist/i18n/InternationalizationContext.d.ts +1 -0
- package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
- package/dist/i18n/InternationalizationContext.js +3 -0
- package/dist/i18n/InternationalizationProvider.d.ts +8 -1
- package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
- package/dist/i18n/InternationalizationProvider.js +5 -1
- package/dist/i18n/getLocaleDirection.d.ts +18 -0
- package/dist/i18n/getLocaleDirection.d.ts.map +1 -0
- package/dist/i18n/getLocaleDirection.js +29 -0
- package/dist/i18n/index.d.ts +6 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +7 -1
- package/dist/i18n/resolve.d.ts.map +1 -1
- package/dist/i18n/resolve.js +7 -18
- package/dist/i18n/useDirection.d.ts +2 -0
- package/dist/i18n/useDirection.d.ts.map +1 -0
- package/dist/i18n/useDirection.js +27 -0
- package/dist/theme/Theme.d.ts.map +1 -1
- package/dist/theme/Theme.js +2 -7
- package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
- package/dist/theme/derivedVarRegistry.js +13 -0
- package/dist/theme/generateThemeRules.d.ts.map +1 -1
- package/dist/theme/generateThemeRules.js +51 -0
- package/dist/theme/hct.d.ts +0 -1
- package/dist/theme/hct.d.ts.map +1 -1
- package/dist/theme/hct.js +1 -1
- package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
- package/dist/theme/syntax/defineSyntaxTheme.js +2 -1
- package/dist/utils/devWarning.d.ts +42 -0
- package/dist/utils/devWarning.d.ts.map +1 -0
- package/dist/utils/devWarning.js +88 -0
- package/dist/utils/index.d.ts +4 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +4 -2
- package/dist/utils/plainDate.d.ts +30 -0
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +65 -3
- package/dist/utils/rtlStyles.d.ts +24 -0
- package/dist/utils/rtlStyles.d.ts.map +1 -0
- package/dist/utils/rtlStyles.js +27 -0
- package/dist/utils/types.d.ts +13 -0
- package/dist/utils/types.d.ts.map +1 -1
- package/locales/en.json +104 -0
- package/locales/fr-FR.json +14 -0
- package/locales/pseudo.json +78 -0
- package/package.json +6 -1
- package/src/AppShell/AppShell.tsx +6 -0
- package/src/AppShell/AppShellMobileContext.tsx +8 -0
- package/src/AppShell/useAppShellMobile.doc.mjs +8 -0
- package/src/Avatar/Avatar.doc.mjs +64 -5
- package/src/Avatar/Avatar.test.tsx +374 -1
- package/src/Avatar/Avatar.tsx +367 -69
- package/src/Avatar/AvatarStatusDot.doc.mjs +23 -12
- package/src/Avatar/AvatarStatusDot.test.tsx +284 -0
- package/src/Avatar/AvatarStatusDot.tsx +180 -21
- package/src/AvatarGroup/AvatarGroup.doc.mjs +2 -0
- package/src/AvatarGroup/AvatarGroup.test.tsx +141 -1
- package/src/AvatarGroup/AvatarGroup.tsx +58 -3
- package/src/AvatarGroup/AvatarGroupOverflow.tsx +1 -0
- package/src/Banner/Banner.doc.mjs +9 -0
- package/src/Banner/Banner.test.tsx +30 -0
- package/src/Banner/Banner.tsx +53 -9
- package/src/Breadcrumbs/BreadcrumbItem.doc.mjs +26 -0
- package/src/Breadcrumbs/BreadcrumbItem.tsx +333 -14
- package/src/Breadcrumbs/Breadcrumbs.doc.mjs +2 -0
- package/src/Breadcrumbs/Breadcrumbs.test.tsx +335 -2
- package/src/Breadcrumbs/index.ts +31 -0
- package/src/Button/Button.doc.mjs +9 -4
- package/src/Button/Button.test.tsx +49 -0
- package/src/Button/Button.tsx +27 -3
- package/src/ButtonGroup/ButtonGroup.doc.mjs +3 -0
- package/src/ButtonGroup/ButtonGroup.test.tsx +37 -0
- package/src/ButtonGroup/ButtonGroup.tsx +32 -0
- package/src/Calendar/Calendar.doc.mjs +12 -1
- package/src/Calendar/Calendar.test.tsx +362 -19
- package/src/Calendar/Calendar.tsx +111 -32
- package/src/Calendar/dayCellUtils.test.ts +23 -18
- package/src/Calendar/dayCellUtils.ts +3 -3
- package/src/Calendar/styles.ts +33 -39
- package/src/Card/Card.doc.mjs +9 -0
- package/src/Card/Card.test.tsx +21 -3
- package/src/Card/Card.tsx +35 -2
- package/src/Carousel/Carousel.doc.mjs +1 -0
- package/src/Carousel/Carousel.test.tsx +53 -0
- package/src/Carousel/Carousel.tsx +59 -10
- package/src/Chat/ChatComposer.doc.mjs +12 -3
- package/src/Chat/ChatComposer.test.tsx +115 -0
- package/src/Chat/ChatComposer.tsx +73 -9
- package/src/Chat/ChatComposerDrawer.test.tsx +61 -0
- package/src/Chat/ChatComposerDrawer.tsx +11 -1
- package/src/Chat/ChatComposerInput.doc.mjs +7 -0
- package/src/Chat/ChatComposerInput.test.tsx +103 -0
- package/src/Chat/ChatComposerInput.tsx +51 -5
- package/src/Chat/ChatContext.tsx +37 -10
- package/src/Chat/ChatDictationButton.tsx +11 -2
- package/src/Chat/ChatLayout.tsx +7 -5
- package/src/Chat/ChatLayoutScrollButton.tsx +7 -2
- package/src/Chat/ChatMessageMetadata.tsx +1 -2
- package/src/Chat/ChatSendButton.tsx +11 -1
- package/src/Chat/ChatToolCalls.test.tsx +64 -0
- package/src/Chat/ChatToolCalls.tsx +33 -5
- package/src/Chat/index.ts +5 -1
- package/src/Chat/useChatStreamScroll.test.tsx +49 -0
- package/src/Chat/useChatStreamScroll.ts +27 -10
- package/src/Chat/useSpeechRecognition.ts +1 -1
- package/src/Chat/useTriggerMenu.tsx +4 -2
- package/src/CheckboxInput/CheckboxInput.doc.mjs +6 -0
- package/src/CheckboxInput/CheckboxInput.test.tsx +32 -1
- package/src/CheckboxInput/CheckboxInput.tsx +5 -5
- package/src/CheckboxList/CheckboxList.doc.mjs +6 -0
- package/src/CheckboxList/CheckboxList.test.tsx +81 -3
- package/src/CheckboxList/CheckboxListItem.doc.mjs +33 -5
- package/src/CheckboxList/CheckboxListItem.tsx +41 -5
- package/src/Citation/Citation.doc.mjs +4 -3
- package/src/Citation/Citation.test.tsx +97 -0
- package/src/Citation/Citation.tsx +43 -11
- package/src/ClickableCard/ClickableCard.doc.mjs +2 -0
- package/src/ClickableCard/ClickableCard.test.tsx +34 -0
- package/src/ClickableCard/ClickableCard.tsx +13 -3
- package/src/CodeBlock/CodeBlock.test.tsx +56 -0
- package/src/CodeBlock/CodeBlock.tsx +45 -10
- package/src/Collapsible/Collapsible.doc.mjs +1 -0
- package/src/Collapsible/Collapsible.test.tsx +7 -0
- package/src/Collapsible/Collapsible.tsx +16 -6
- package/src/CommandPalette/CommandPalette.doc.mjs +1 -0
- package/src/CommandPalette/CommandPalette.test.tsx +95 -1
- package/src/CommandPalette/CommandPalette.tsx +44 -3
- package/src/CommandPalette/CommandPaletteGroup.test.tsx +71 -0
- package/src/CommandPalette/CommandPaletteGroup.tsx +12 -1
- package/src/CommandPalette/CommandPaletteInput.doc.mjs +26 -9
- package/src/CommandPalette/CommandPaletteInput.test.tsx +34 -0
- package/src/CommandPalette/CommandPaletteInput.tsx +11 -0
- package/src/CommandPalette/CommandPaletteItem.tsx +1 -1
- package/src/ContextMenu/ContextMenu.test.tsx +235 -0
- package/src/ContextMenu/ContextMenu.tsx +13 -11
- package/src/ContextMenu/index.ts +5 -0
- package/src/DateInput/DateInput.doc.mjs +41 -0
- package/src/DateInput/DateInput.test.tsx +338 -0
- package/src/DateInput/DateInput.tsx +119 -32
- package/src/DateInput/index.ts +1 -0
- package/src/DateRangeInput/DateRangeInput.doc.mjs +16 -0
- package/src/DateRangeInput/DateRangeInput.test.tsx +140 -0
- package/src/DateRangeInput/DateRangeInput.tsx +42 -30
- package/src/DateTimeInput/DateTimeInput.doc.mjs +22 -1
- package/src/DateTimeInput/DateTimeInput.test.tsx +147 -0
- package/src/DateTimeInput/DateTimeInput.tsx +58 -41
- package/src/Dialog/Dialog.doc.mjs +2 -2
- package/src/Dialog/Dialog.test.tsx +77 -4
- package/src/Dialog/Dialog.tsx +89 -5
- package/src/Dialog/DialogContext.ts +9 -2
- package/src/Dialog/DialogHeader.doc.mjs +2 -2
- package/src/Dialog/DialogHeader.tsx +9 -2
- package/src/Divider/Divider.tsx +2 -2
- package/src/DropdownMenu/DropdownMenu.test.tsx +229 -0
- package/src/DropdownMenu/DropdownMenu.tsx +31 -12
- package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +9 -4
- package/src/DropdownMenu/DropdownMenuItem.tsx +9 -3
- package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +1 -2
- package/src/DropdownMenu/DropdownMenuRadioItem.tsx +8 -2
- package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +88 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +635 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +553 -0
- package/src/DropdownMenu/index.ts +16 -0
- package/src/DropdownMenu/menuItemHover.ts +39 -0
- package/src/DropdownMenu/menuItemRoles.ts +9 -0
- package/src/DropdownMenu/renderDropdownItems.tsx +29 -15
- package/src/Field/Field.test.tsx +57 -12
- package/src/Field/Field.tsx +20 -14
- package/src/Field/FieldLabel.tsx +9 -1
- package/src/Field/inputStyles.stylex.ts +2 -0
- package/src/FieldStatus/FieldStatus.doc.mjs +17 -5
- package/src/FieldStatus/FieldStatus.test.tsx +150 -40
- package/src/FieldStatus/FieldStatus.tsx +69 -5
- package/src/FileInput/FileInput.doc.mjs +23 -2
- package/src/FileInput/FileInput.test.tsx +135 -12
- package/src/FileInput/FileInput.tsx +65 -51
- package/src/HoverCard/HoverCard.doc.mjs +13 -0
- package/src/HoverCard/HoverCard.test.tsx +21 -2
- package/src/HoverCard/HoverCard.tsx +11 -0
- package/src/HoverCard/useHoverCard.doc.mjs +2 -0
- package/src/HoverCard/useHoverCard.tsx +39 -5
- package/src/Icon/Icon.doc.mjs +16 -2
- package/src/Icon/Icon.test.tsx +89 -0
- package/src/Icon/Icon.tsx +58 -5
- package/src/IconButton/IconButton.doc.mjs +8 -0
- package/src/IconButton/IconButton.test.tsx +15 -18
- package/src/Item/Item.test.tsx +40 -18
- package/src/Item/Item.tsx +38 -2
- package/src/Layer/useLayer.tsx +8 -0
- package/src/Lightbox/Lightbox.tsx +15 -7
- package/src/List/List.test.tsx +9 -8
- package/src/Markdown/Markdown.test.tsx +21 -0
- package/src/Markdown/Markdown.tsx +4 -0
- package/src/MobileNav/MobileNav.tsx +12 -1
- package/src/MobileNav/MobileNavToggle.test.tsx +116 -0
- package/src/MobileNav/MobileNavToggle.tsx +9 -1
- package/src/MultiSelector/MultiSelector.doc.mjs +24 -2
- package/src/MultiSelector/MultiSelector.test.tsx +498 -3
- package/src/MultiSelector/MultiSelector.tsx +149 -65
- package/src/MultiSelector/hooks.ts +17 -0
- package/src/NavMenu/NavHeadingMenuItem.tsx +1 -1
- package/src/NumberInput/NumberInput.doc.mjs +21 -0
- package/src/NumberInput/NumberInput.test.tsx +82 -7
- package/src/NumberInput/NumberInput.tsx +36 -28
- package/src/Outline/Outline.tsx +0 -1
- package/src/OverflowList/OverflowList.doc.mjs +39 -6
- package/src/OverflowList/OverflowList.test.tsx +111 -0
- package/src/OverflowList/OverflowList.tsx +48 -8
- package/src/Pagination/Pagination.tsx +11 -3
- package/src/Popover/Popover.tsx +7 -4
- package/src/Popover/usePopover.tsx +9 -13
- package/src/PowerSearch/PowerSearch.doc.mjs +29 -0
- package/src/PowerSearch/PowerSearch.test.tsx +43 -0
- package/src/PowerSearch/PowerSearch.tsx +10 -1
- package/src/PowerSearch/PowerSearchEditPopover.test.tsx +67 -0
- package/src/PowerSearch/PowerSearchEditPopover.tsx +1 -1
- package/src/PowerSearch/usePowerSearchSource.ts +1 -2
- package/src/RadioList/RadioList.doc.mjs +6 -0
- package/src/RadioList/RadioList.tsx +2 -2
- package/src/RadioList/RadioListItem.tsx +4 -4
- package/src/SegmentedControl/SegmentedControlItem.tsx +2 -0
- package/src/SelectableCard/SelectableCard.doc.mjs +2 -0
- package/src/SelectableCard/SelectableCard.test.tsx +46 -4
- package/src/SelectableCard/SelectableCard.tsx +29 -16
- package/src/Selector/Selector.doc.mjs +15 -0
- package/src/Selector/Selector.test.tsx +417 -0
- package/src/Selector/Selector.tsx +86 -21
- package/src/Selector/hooks.ts +17 -0
- package/src/SideNav/SideNav.test.tsx +119 -3
- package/src/SideNav/SideNav.tsx +1 -8
- package/src/SideNav/SideNavCollapseButton.tsx +15 -8
- package/src/SideNav/SideNavHeading.tsx +24 -8
- package/src/SideNav/SideNavItem.tsx +10 -4
- package/src/Slider/Slider.doc.mjs +6 -0
- package/src/Slider/Slider.test.tsx +314 -13
- package/src/Slider/Slider.tsx +117 -28
- package/src/Switch/Switch.doc.mjs +142 -42
- package/src/Switch/Switch.test.tsx +54 -1
- package/src/Switch/Switch.tsx +90 -33
- package/src/TabList/Tab.tsx +2 -2
- package/src/TabList/TabMenu.tsx +2 -2
- package/src/Table/BaseTable.tsx +37 -7
- package/src/Table/Table.doc.mjs +11 -0
- package/src/Table/Table.test.tsx +85 -0
- package/src/Table/TableCell.tsx +3 -3
- package/src/Table/TableHeaderCell.tsx +3 -3
- package/src/Table/index.ts +5 -0
- package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +15 -8
- package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +24 -17
- package/src/Table/plugins/rowStatus/index.ts +7 -0
- package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +138 -0
- package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +189 -0
- package/src/Table/plugins/selection/useTableSelection.test.tsx +77 -3
- package/src/Table/plugins/selection/useTableSelection.tsx +22 -1
- package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -1
- package/src/Table/plugins/tree/useTableTreeData.test.tsx +135 -3
- package/src/Table/plugins/tree/useTableTreeData.tsx +139 -8
- package/src/Table/plugins/tree/useTableTreeState.test.tsx +104 -0
- package/src/Table/plugins/tree/useTableTreeState.tsx +46 -2
- package/src/Table/types.ts +33 -0
- package/src/Table/useBaseTablePlugins.ts +10 -6
- package/src/Table/useTableRowStatus.doc.mjs +30 -0
- package/src/Table/useTableSelection.doc.mjs +65 -14
- package/src/Table/useTableTreeData.doc.mjs +29 -0
- package/src/Table/useTableTreeState.doc.mjs +2 -2
- package/src/TextArea/TextArea.doc.mjs +21 -0
- package/src/TextArea/TextArea.test.tsx +32 -1
- package/src/TextArea/TextArea.tsx +27 -26
- package/src/TextInput/TextInput.doc.mjs +21 -0
- package/src/TextInput/TextInput.test.tsx +150 -0
- package/src/TextInput/TextInput.tsx +28 -25
- package/src/Thumbnail/Thumbnail.doc.mjs +19 -10
- package/src/Thumbnail/Thumbnail.test.tsx +98 -7
- package/src/Thumbnail/Thumbnail.tsx +142 -42
- package/src/Thumbnail/thumbnail.markers.stylex.ts +12 -0
- package/src/TimeInput/TimeInput.doc.mjs +21 -0
- package/src/TimeInput/TimeInput.test.tsx +99 -1
- package/src/TimeInput/TimeInput.tsx +43 -31
- package/src/Timestamp/Timestamp.doc.mjs +4 -4
- package/src/Timestamp/Timestamp.test.tsx +32 -0
- package/src/Timestamp/Timestamp.tsx +28 -8
- package/src/Toast/useToast.tsx +7 -8
- package/src/ToggleButton/ToggleButtonGroup.tsx +1 -1
- package/src/Token/Token.test.tsx +21 -15
- package/src/Token/Token.tsx +31 -14
- package/src/Token/index.ts +1 -1
- package/src/Tokenizer/Tokenizer.doc.mjs +38 -2
- package/src/Tokenizer/Tokenizer.test.tsx +206 -2
- package/src/Tokenizer/Tokenizer.tsx +30 -6
- package/src/Tooltip/Tooltip.test.tsx +46 -0
- package/src/Tooltip/useTooltip.tsx +20 -0
- package/src/TopNav/TopNav.test.tsx +125 -1
- package/src/TopNav/TopNavHeading.tsx +24 -8
- package/src/TopNav/TopNavMegaMenu.test.tsx +149 -1
- package/src/TopNav/TopNavMegaMenu.tsx +10 -4
- package/src/TopNav/TopNavMegaMenuFeaturedCard.doc.mjs +3 -3
- package/src/TopNav/TopNavMegaMenuFeaturedCard.tsx +19 -2
- package/src/TopNav/TopNavMenu.test.tsx +118 -4
- package/src/TopNav/TopNavMenu.tsx +83 -5
- package/src/TreeList/TreeList.doc.mjs +28 -0
- package/src/TreeList/TreeList.test.tsx +272 -0
- package/src/TreeList/TreeList.tsx +23 -2
- package/src/TreeList/TreeListBranches.tsx +24 -8
- package/src/TreeList/TreeListItem.tsx +84 -22
- package/src/TreeList/TreeListTypes.ts +27 -1
- package/src/TreeList/index.ts +2 -2
- package/src/Typeahead/BaseTypeahead.tsx +30 -15
- package/src/Typeahead/Typeahead.doc.mjs +13 -0
- package/src/Typeahead/Typeahead.test.tsx +50 -0
- package/src/Typeahead/Typeahead.tsx +11 -1
- package/src/Typeahead/TypeaheadItem.tsx +2 -1
- package/src/__tests__/inputWidthContract.test.tsx +62 -0
- package/src/authoring/doc.ts +1 -3
- package/src/doc-mjs.d.ts +19 -0
- package/src/docs-types.ts +5 -0
- package/src/hooks/computeOverflow.test.ts +422 -0
- package/src/hooks/computeOverflow.ts +290 -0
- package/src/hooks/index.ts +8 -0
- package/src/hooks/isRtlElement.ts +27 -0
- package/src/hooks/useDevWarning.test.tsx +45 -0
- package/src/hooks/useDevWarning.ts +54 -0
- package/src/hooks/useGridFocus.doc.mjs +3 -3
- package/src/hooks/useGridFocus.test.tsx +41 -0
- package/src/hooks/useGridFocus.ts +21 -10
- package/src/hooks/useInputStatusIcon.test.tsx +162 -0
- package/src/hooks/useInputStatusIcon.tsx +224 -0
- package/src/hooks/useListFocus.doc.mjs +25 -3
- package/src/hooks/useListFocus.test.tsx +153 -1
- package/src/hooks/useListFocus.ts +102 -9
- package/src/hooks/useOverflow.test.ts +96 -4
- package/src/hooks/useOverflow.ts +74 -33
- package/src/i18n/InternationalizationContext.ts +4 -0
- package/src/i18n/InternationalizationProvider.doc.mjs +99 -2
- package/src/i18n/InternationalizationProvider.tsx +12 -2
- package/src/i18n/__tests__/getLocaleDirection.test.ts +40 -0
- package/src/i18n/__tests__/useDirection.test.tsx +66 -0
- package/src/i18n/getLocaleDirection.ts +29 -0
- package/src/i18n/index.ts +6 -0
- package/src/i18n/resolve.ts +9 -21
- package/src/i18n/useDirection.ts +29 -0
- package/src/reset.css +0 -26
- package/src/reset.test.ts +60 -0
- package/src/theme/Theme.tsx +11 -14
- package/src/theme/derivedVarRegistry.test.ts +1 -0
- package/src/theme/derivedVarRegistry.ts +6 -0
- package/src/theme/generateThemeRules.test.ts +107 -0
- package/src/theme/generateThemeRules.ts +56 -0
- package/src/theme/hct.ts +1 -1
- package/src/theme/syntax/defineSyntaxTheme.ts +5 -6
- package/src/utils/devWarning.test.ts +56 -0
- package/src/utils/devWarning.ts +102 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/plainDate.test.ts +46 -6
- package/src/utils/plainDate.ts +69 -3
- package/src/utils/rtlStyles.ts +27 -0
- package/src/utils/types.ts +14 -0
|
@@ -4,14 +4,18 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file Thumbnail.tsx
|
|
7
|
-
* @input Uses React, stylex, Button, Skeleton, Spinner
|
|
7
|
+
* @input Uses React, stylex, Button, Skeleton, Spinner
|
|
8
8
|
* @output Exports Thumbnail component, ThumbnailProps
|
|
9
9
|
* @position Core implementation; consumed by index.ts
|
|
10
10
|
*
|
|
11
11
|
* Square preview card for image attachments. Shows a skeleton shimmer while
|
|
12
12
|
* the image loads, the image on success, or a placeholder on failure.
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* The overlaid remove button sits on a fixed --color-overlay scrim with an
|
|
14
|
+
* --color-on-dark icon so it always has sufficient contrast against the image.
|
|
15
|
+
*
|
|
16
|
+
* Images without `alt` are explicitly decorative (alt="" +
|
|
17
|
+
* role="presentation" + aria-hidden, matching Avatar). A dev-time warning
|
|
18
|
+
* fires once when `src` is set with no `alt` and no other name source.
|
|
15
19
|
*
|
|
16
20
|
* SYNC: When modified, update these files to stay in sync:
|
|
17
21
|
* - /packages/core/src/Thumbnail/Thumbnail.doc.mjs
|
|
@@ -26,7 +30,6 @@ import {
|
|
|
26
30
|
colorVars,
|
|
27
31
|
radiusVars,
|
|
28
32
|
spacingVars,
|
|
29
|
-
shadowVars,
|
|
30
33
|
durationVars,
|
|
31
34
|
easeVars,
|
|
32
35
|
} from '../theme/tokens.stylex';
|
|
@@ -35,15 +38,12 @@ import {Icon} from '../Icon';
|
|
|
35
38
|
import {Skeleton} from '../Skeleton';
|
|
36
39
|
import {Spinner} from '../Spinner';
|
|
37
40
|
import {Tooltip} from '../Tooltip/Tooltip';
|
|
38
|
-
import {
|
|
39
|
-
import {useImageMode} from '../hooks/useImageMode';
|
|
41
|
+
import {useDevWarning} from '../hooks/useDevWarning';
|
|
40
42
|
import type {BaseProps} from '../BaseProps';
|
|
41
43
|
import {mergeProps} from '../utils';
|
|
42
44
|
import {themeProps} from '../utils/themeProps';
|
|
43
45
|
import {useTranslator} from '../i18n';
|
|
44
|
-
|
|
45
|
-
/** Sample the region behind the remove button (20px button, 4px inset, in 64px container). */
|
|
46
|
-
const BUTTON_REGION = {x: 0.5, y: 0.06, width: 0.44, height: 0.44};
|
|
46
|
+
import {thumbnailScope} from './thumbnail.markers.stylex';
|
|
47
47
|
|
|
48
48
|
export interface ThumbnailProps extends BaseProps<HTMLDivElement> {
|
|
49
49
|
/** Ref forwarded to the root element */
|
|
@@ -54,7 +54,14 @@ export interface ThumbnailProps extends BaseProps<HTMLDivElement> {
|
|
|
54
54
|
*/
|
|
55
55
|
src?: string;
|
|
56
56
|
/**
|
|
57
|
-
* Alt text for the image.
|
|
57
|
+
* Alt text for the image.
|
|
58
|
+
*
|
|
59
|
+
* When omitted, the image is explicitly decorative (`alt=""` +
|
|
60
|
+
* `role="presentation"` + `aria-hidden`, matching Avatar) and hidden from
|
|
61
|
+
* assistive technology. Provide `alt` whenever the image conveys content;
|
|
62
|
+
* without it, screen reader users only hear the `label` (file name), or a
|
|
63
|
+
* generic "thumbnail" if `label` is also missing — which triggers a
|
|
64
|
+
* dev-time warning.
|
|
58
65
|
*/
|
|
59
66
|
alt?: string;
|
|
60
67
|
/**
|
|
@@ -90,6 +97,17 @@ export interface ThumbnailProps extends BaseProps<HTMLDivElement> {
|
|
|
90
97
|
* @default false
|
|
91
98
|
*/
|
|
92
99
|
isDisabled?: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* When the remove button is visible.
|
|
102
|
+
* - `'hover'` — the button is revealed on hover, and on keyboard focus so
|
|
103
|
+
* it stays reachable. On any touch-capable device it stays visible.
|
|
104
|
+
* This is the default.
|
|
105
|
+
* - `'always'` — the button is always shown.
|
|
106
|
+
*
|
|
107
|
+
* Only has an effect when `onRemove` is set.
|
|
108
|
+
* @default 'hover'
|
|
109
|
+
*/
|
|
110
|
+
showRemoveOn?: 'always' | 'hover';
|
|
93
111
|
/**
|
|
94
112
|
* Test ID for testing frameworks.
|
|
95
113
|
*/
|
|
@@ -140,22 +158,6 @@ const styles = stylex.create({
|
|
|
140
158
|
},
|
|
141
159
|
interactive: {
|
|
142
160
|
cursor: 'pointer',
|
|
143
|
-
transitionProperty: 'opacity, box-shadow',
|
|
144
|
-
transitionDuration: durationVars['--duration-fast'],
|
|
145
|
-
transitionTimingFunction: easeVars['--ease-standard'],
|
|
146
|
-
boxShadow: {
|
|
147
|
-
default: 'none',
|
|
148
|
-
':hover': {
|
|
149
|
-
'@media (hover: hover)': shadowVars['--shadow-med'],
|
|
150
|
-
},
|
|
151
|
-
},
|
|
152
|
-
opacity: {
|
|
153
|
-
default: 1,
|
|
154
|
-
':hover': {
|
|
155
|
-
'@media (hover: hover)': 0.85,
|
|
156
|
-
},
|
|
157
|
-
':active': 0.75,
|
|
158
|
-
},
|
|
159
161
|
outline: {
|
|
160
162
|
default: null,
|
|
161
163
|
':has(:focus-visible)': `2px solid ${colorVars['--color-accent']}`,
|
|
@@ -165,6 +167,33 @@ const styles = stylex.create({
|
|
|
165
167
|
':has(:focus-visible)': '2px',
|
|
166
168
|
},
|
|
167
169
|
},
|
|
170
|
+
// Hover/pressed overlay — the exact same treatment as ClickableCard and
|
|
171
|
+
// SelectableCard. A transparent `::after` tints on hover/press instead of
|
|
172
|
+
// shifting shadow or opacity. Guarded by @media (hover: hover) so touch
|
|
173
|
+
// devices don't show a stuck hover state; active/pressed works everywhere.
|
|
174
|
+
overlay: {
|
|
175
|
+
'::after': {
|
|
176
|
+
content: '""',
|
|
177
|
+
position: 'absolute',
|
|
178
|
+
inset: 0,
|
|
179
|
+
borderRadius: 'inherit',
|
|
180
|
+
pointerEvents: 'none',
|
|
181
|
+
transitionProperty: 'background-color',
|
|
182
|
+
transitionDuration: durationVars['--duration-fast'],
|
|
183
|
+
transitionTimingFunction: easeVars['--ease-standard'],
|
|
184
|
+
backgroundColor: 'transparent',
|
|
185
|
+
},
|
|
186
|
+
':active::after': {
|
|
187
|
+
backgroundColor: colorVars['--color-overlay-pressed'],
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
hoverOnPointer: {
|
|
191
|
+
'@media (hover: hover)': {
|
|
192
|
+
':hover::after': {
|
|
193
|
+
backgroundColor: colorVars['--color-overlay-hover'],
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
},
|
|
168
197
|
interactiveButton: {
|
|
169
198
|
all: 'unset',
|
|
170
199
|
cursor: 'pointer',
|
|
@@ -175,14 +204,22 @@ const styles = stylex.create({
|
|
|
175
204
|
overflow: 'hidden',
|
|
176
205
|
},
|
|
177
206
|
|
|
178
|
-
|
|
207
|
+
removeSlot: {
|
|
179
208
|
position: 'absolute',
|
|
180
209
|
top: spacingVars['--spacing-1'],
|
|
181
|
-
|
|
210
|
+
insetInlineEnd: spacingVars['--spacing-1'],
|
|
182
211
|
zIndex: 1,
|
|
212
|
+
lineHeight: 0,
|
|
213
|
+
},
|
|
214
|
+
removeButtonOverrides: {
|
|
183
215
|
'--_button-radius': `calc(${radiusVars['--radius-element']} - ${spacingVars['--spacing-1']})`,
|
|
184
216
|
height: 20,
|
|
185
217
|
minWidth: 20,
|
|
218
|
+
// Fixed colors instead of luminance-adapting theme: a translucent scrim
|
|
219
|
+
// (--color-overlay) plus an --color-on-dark icon reads on any image
|
|
220
|
+
// without sampling pixel brightness.
|
|
221
|
+
backgroundColor: colorVars['--color-overlay'],
|
|
222
|
+
color: colorVars['--color-on-dark'],
|
|
186
223
|
},
|
|
187
224
|
disabled: {
|
|
188
225
|
opacity: 0.5,
|
|
@@ -199,6 +236,28 @@ const styles = stylex.create({
|
|
|
199
236
|
zIndex: 1,
|
|
200
237
|
lineHeight: 0,
|
|
201
238
|
},
|
|
239
|
+
// showRemoveOn="hover": the remove button is hidden at rest and revealed
|
|
240
|
+
// when the thumbnail is hovered or when focus enters it (keyboard). Only
|
|
241
|
+
// opacity is animated — the button stays mounted and focusable so tabbing
|
|
242
|
+
// to it triggers the :focus-within reveal. Any touch-capable device (incl.
|
|
243
|
+
// hybrid laptops that also report hover) keeps the button visible so the
|
|
244
|
+
// remove path is never gated behind an unavailable hover.
|
|
245
|
+
removeOnHover: {
|
|
246
|
+
opacity: {
|
|
247
|
+
default: 0,
|
|
248
|
+
[stylex.when.ancestor(':hover', thumbnailScope)]: {
|
|
249
|
+
'@media (hover: hover)': 1,
|
|
250
|
+
},
|
|
251
|
+
[stylex.when.ancestor(':focus-within', thumbnailScope)]: 1,
|
|
252
|
+
'@media (any-pointer: coarse)': 1,
|
|
253
|
+
},
|
|
254
|
+
transitionProperty: 'opacity',
|
|
255
|
+
transitionDuration: {
|
|
256
|
+
default: durationVars['--duration-fast'],
|
|
257
|
+
'@media (prefers-reduced-motion: reduce)': '0s',
|
|
258
|
+
},
|
|
259
|
+
transitionTimingFunction: easeVars['--ease-standard'],
|
|
260
|
+
},
|
|
202
261
|
});
|
|
203
262
|
|
|
204
263
|
// =============================================================================
|
|
@@ -227,15 +286,18 @@ function ImagePlaceholder() {
|
|
|
227
286
|
*
|
|
228
287
|
* Shows a skeleton shimmer while the image loads, the image on success, or
|
|
229
288
|
* a placeholder icon on failure / when no src is provided. An overlaid
|
|
230
|
-
* remove button appears when `onRemove` is set
|
|
289
|
+
* remove button appears when `onRemove` is set — revealed on hover or
|
|
290
|
+
* keyboard focus by default (`showRemoveOn`), or always shown.
|
|
231
291
|
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
292
|
+
* The remove button uses a fixed `--color-overlay` scrim with an
|
|
293
|
+
* `--color-on-dark` icon so it stays legible on any image without sampling
|
|
294
|
+
* the image's luminance.
|
|
234
295
|
*
|
|
235
296
|
* @example
|
|
236
297
|
* ```
|
|
237
298
|
* <Thumbnail src="/photo.jpg" alt="Vacation photo" onRemove={() => {}} />
|
|
238
299
|
* <Thumbnail src="/preview.png" alt="Preview" onClick={() => {}} label="preview.png" />
|
|
300
|
+
* <Thumbnail src="/logo.png" alt="Logo" onRemove={() => {}} showRemoveOn="always" />
|
|
239
301
|
* ```
|
|
240
302
|
*/
|
|
241
303
|
export function Thumbnail({
|
|
@@ -246,6 +308,7 @@ export function Thumbnail({
|
|
|
246
308
|
onClick,
|
|
247
309
|
isLoading = false,
|
|
248
310
|
isDisabled = false,
|
|
311
|
+
showRemoveOn = 'hover',
|
|
249
312
|
xstyle,
|
|
250
313
|
className,
|
|
251
314
|
style,
|
|
@@ -254,7 +317,6 @@ export function Thumbnail({
|
|
|
254
317
|
...props
|
|
255
318
|
}: ThumbnailProps) {
|
|
256
319
|
const t = useTranslator();
|
|
257
|
-
const imageMode = useImageMode(src, {region: BUTTON_REGION, fallback: null});
|
|
258
320
|
|
|
259
321
|
const hasSrc = src != null;
|
|
260
322
|
const showSkeleton = isLoading && !hasSrc;
|
|
@@ -262,13 +324,47 @@ export function Thumbnail({
|
|
|
262
324
|
const showUploadOverlay = isLoading && hasSrc;
|
|
263
325
|
const showPlaceholder = !isLoading && !hasSrc;
|
|
264
326
|
const isInteractive = onClick != null && !isDisabled && !isLoading;
|
|
327
|
+
const hasRemove = onRemove != null && !isDisabled;
|
|
328
|
+
const isHoverReveal = hasRemove && showRemoveOn === 'hover';
|
|
265
329
|
const accessibleName =
|
|
266
|
-
label && alt
|
|
330
|
+
label && alt
|
|
331
|
+
? `${label} — ${alt}`
|
|
332
|
+
: (label ?? alt ?? t('@astryx.thumbnail.fallbackName'));
|
|
333
|
+
|
|
334
|
+
// Without `alt`, the image is explicitly decorative rather than silently
|
|
335
|
+
// empty-alt, matching Avatar's handling of unnamed images.
|
|
336
|
+
const isImageDecorative = !alt;
|
|
337
|
+
|
|
338
|
+
// Dev-time guardrail: `src` with no `alt` hides the image from assistive
|
|
339
|
+
// technology. That is fine when the thumbnail is otherwise named — `label`
|
|
340
|
+
// (or a consumer-provided aria name) becomes the group's accessible name —
|
|
341
|
+
// but with no name source at all the group falls back to a generic
|
|
342
|
+
// "thumbnail".
|
|
343
|
+
const hasNameSource =
|
|
344
|
+
alt != null ||
|
|
345
|
+
label != null ||
|
|
346
|
+
props['aria-label'] != null ||
|
|
347
|
+
props['aria-labelledby'] != null;
|
|
348
|
+
useDevWarning(
|
|
349
|
+
'Thumbnail',
|
|
350
|
+
'`src` is set without `alt` or `label`. The image is ' +
|
|
351
|
+
'treated as decorative and hidden from assistive technology, and ' +
|
|
352
|
+
'the thumbnail falls back to a generic "thumbnail" name. Pass ' +
|
|
353
|
+
'`alt` to describe the image content, or `label` (file name) to ' +
|
|
354
|
+
'name the thumbnail.',
|
|
355
|
+
hasSrc && !hasNameSource,
|
|
356
|
+
);
|
|
267
357
|
|
|
268
358
|
const imageContent = (
|
|
269
359
|
<>
|
|
270
360
|
{showImage && (
|
|
271
|
-
<img
|
|
361
|
+
<img
|
|
362
|
+
src={src}
|
|
363
|
+
alt={alt ?? ''}
|
|
364
|
+
role={isImageDecorative ? 'presentation' : undefined}
|
|
365
|
+
aria-hidden={isImageDecorative || undefined}
|
|
366
|
+
{...stylex.props(styles.image)}
|
|
367
|
+
/>
|
|
272
368
|
)}
|
|
273
369
|
{showSkeleton && <Skeleton radius={2} />}
|
|
274
370
|
{showPlaceholder && (
|
|
@@ -279,8 +375,12 @@ export function Thumbnail({
|
|
|
279
375
|
</>
|
|
280
376
|
);
|
|
281
377
|
|
|
282
|
-
const removeButtonEl =
|
|
283
|
-
|
|
378
|
+
const removeButtonEl = hasRemove ? (
|
|
379
|
+
<div
|
|
380
|
+
{...stylex.props(
|
|
381
|
+
styles.removeSlot,
|
|
382
|
+
isHoverReveal && styles.removeOnHover,
|
|
383
|
+
)}>
|
|
284
384
|
<Button
|
|
285
385
|
icon={<Icon icon="close" size="xsm" />}
|
|
286
386
|
label={t('@astryx.thumbnail.remove', {accessibleName})}
|
|
@@ -293,7 +393,8 @@ export function Thumbnail({
|
|
|
293
393
|
}}
|
|
294
394
|
xstyle={styles.removeButtonOverrides}
|
|
295
395
|
/>
|
|
296
|
-
|
|
396
|
+
</div>
|
|
397
|
+
) : null;
|
|
297
398
|
|
|
298
399
|
const thumbnail = (
|
|
299
400
|
<div
|
|
@@ -311,7 +412,10 @@ export function Thumbnail({
|
|
|
311
412
|
<div
|
|
312
413
|
{...stylex.props(
|
|
313
414
|
styles.imageContainer,
|
|
415
|
+
isHoverReveal && thumbnailScope,
|
|
314
416
|
isInteractive && styles.interactive,
|
|
417
|
+
isInteractive && styles.overlay,
|
|
418
|
+
isInteractive && styles.hoverOnPointer,
|
|
315
419
|
)}>
|
|
316
420
|
{isInteractive ? (
|
|
317
421
|
<button
|
|
@@ -330,11 +434,7 @@ export function Thumbnail({
|
|
|
330
434
|
<Spinner size="sm" shade="onMedia" />
|
|
331
435
|
</div>
|
|
332
436
|
)}
|
|
333
|
-
{removeButtonEl
|
|
334
|
-
<MediaTheme mode={imageMode}>{removeButtonEl}</MediaTheme>
|
|
335
|
-
) : (
|
|
336
|
-
removeButtonEl
|
|
337
|
-
)}
|
|
437
|
+
{removeButtonEl}
|
|
338
438
|
</div>
|
|
339
439
|
</div>
|
|
340
440
|
);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
import * as stylex from '@stylexjs/stylex';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Scoped marker for Thumbnail ancestor selectors. Applied to the image
|
|
7
|
+
* container so the remove button's hover/focus reveal (`showRemoveOn="hover"`)
|
|
8
|
+
* responds only to this thumbnail — not to hover/focus state from an outer
|
|
9
|
+
* container the thumbnail happens to sit inside.
|
|
10
|
+
*/
|
|
11
|
+
export const thumbnailScope: ReturnType<typeof stylex.defineMarker> =
|
|
12
|
+
stylex.defineMarker();
|
|
@@ -229,12 +229,25 @@ export const docs = {
|
|
|
229
229
|
description:
|
|
230
230
|
'Status indicator that colors the border and displays an icon. When a message is provided it is rendered below the input.',
|
|
231
231
|
},
|
|
232
|
+
{
|
|
233
|
+
name: 'statusVariant',
|
|
234
|
+
type: "'attached' | 'detached' | 'tooltip'",
|
|
235
|
+
description:
|
|
236
|
+
'How the status message is placed relative to the input. attached overlaps directly below the input (bordered treatment); detached floats below as a separate element with spacing; tooltip hides the message box and surfaces it in a tooltip on the status icon.',
|
|
237
|
+
default: "'attached'",
|
|
238
|
+
},
|
|
232
239
|
{
|
|
233
240
|
name: 'labelTooltip',
|
|
234
241
|
type: 'string',
|
|
235
242
|
description:
|
|
236
243
|
'Tooltip text rendered as an info icon at the end of the label row.',
|
|
237
244
|
},
|
|
245
|
+
{
|
|
246
|
+
name: 'width',
|
|
247
|
+
type: 'SizeValue',
|
|
248
|
+
description:
|
|
249
|
+
'Width of the field (number = pixels, string used as-is, e.g. "100%"). Sizes the whole field (label, control, and status) so they stay aligned.',
|
|
250
|
+
},
|
|
238
251
|
{
|
|
239
252
|
name: 'xstyle',
|
|
240
253
|
type: 'StyleXStyles',
|
|
@@ -372,6 +385,13 @@ export const docsZh = {
|
|
|
372
385
|
description:
|
|
373
386
|
'为边框着色并显示图标的状态指示器。当提供消息时,消息渲染在输入框下方。',
|
|
374
387
|
},
|
|
388
|
+
{
|
|
389
|
+
name: 'statusVariant',
|
|
390
|
+
type: "'attached' | 'detached' | 'tooltip'",
|
|
391
|
+
description:
|
|
392
|
+
'状态消息相对于输入框的放置方式。attached 直接叠加在输入框下方(带边框处理);detached 作为独立元素浮于下方并留有间距;tooltip 隐藏消息框,并在状态图标上以提示气泡形式显示。',
|
|
393
|
+
default: "'attached'",
|
|
394
|
+
},
|
|
375
395
|
{
|
|
376
396
|
name: 'labelTooltip',
|
|
377
397
|
type: 'string',
|
|
@@ -545,6 +565,7 @@ export const docsDense = {
|
|
|
545
565
|
placeholder: 'Placeholder when empty. Focused+empty shows format hint.',
|
|
546
566
|
size: 'Input element height.',
|
|
547
567
|
status: 'Colored border+icon. Message rendered below input.',
|
|
568
|
+
statusVariant: 'How status message is placed: attached overlaps below input; detached floats below w/ spacing; tooltip hides the box and shows it on the status icon.',
|
|
548
569
|
labelTooltip: 'Tooltip as info icon at label row end.',
|
|
549
570
|
xstyle:
|
|
550
571
|
'StyleX styles for layout customization. Must be stylex.create() value, not inline style.',
|
|
@@ -9,12 +9,24 @@
|
|
|
9
9
|
* SYNC: When TimeInput.tsx changes, update tests to match new behavior
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import {describe, it, expect, vi, beforeEach} from 'vitest';
|
|
12
|
+
import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
|
|
13
13
|
import {render, screen, fireEvent, waitFor} from '@testing-library/react';
|
|
14
14
|
import userEvent from '@testing-library/user-event';
|
|
15
15
|
import {TimeInput} from './TimeInput';
|
|
16
16
|
import {InputGroup, InputGroupText} from '../InputGroup';
|
|
17
17
|
import type {ISOTimeString} from '../utils';
|
|
18
|
+
import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
|
|
19
|
+
|
|
20
|
+
function politeRegion(): HTMLElement | null {
|
|
21
|
+
return document.querySelector('[data-astryx-live-region="polite"]');
|
|
22
|
+
}
|
|
23
|
+
function assertiveRegion(): HTMLElement | null {
|
|
24
|
+
return document.querySelector('[data-astryx-live-region="assertive"]');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
__resetLiveRegionsForTest();
|
|
29
|
+
});
|
|
18
30
|
|
|
19
31
|
describe('TimeInput', () => {
|
|
20
32
|
it('renders with label', () => {
|
|
@@ -352,6 +364,69 @@ describe('TimeInput', () => {
|
|
|
352
364
|
// duplicated.
|
|
353
365
|
expect(container.querySelectorAll('svg')).toHaveLength(1);
|
|
354
366
|
});
|
|
367
|
+
|
|
368
|
+
// The grouped status node exists only for aria-describedby; announcing
|
|
369
|
+
// happens through the persistent useAnnounce regions because a live
|
|
370
|
+
// region mounted together with its content is not reliably announced.
|
|
371
|
+
it('keeps the grouped status node role-free while announcing via the persistent region', async () => {
|
|
372
|
+
render(
|
|
373
|
+
<InputGroup label="Schedule">
|
|
374
|
+
<InputGroupText>Starts</InputGroupText>
|
|
375
|
+
<TimeInput
|
|
376
|
+
label="Start time"
|
|
377
|
+
isLabelHidden
|
|
378
|
+
value={'09:00' as ISOTimeString}
|
|
379
|
+
onChange={() => {}}
|
|
380
|
+
status={{type: 'error', message: 'Start time is required'}}
|
|
381
|
+
/>
|
|
382
|
+
</InputGroup>,
|
|
383
|
+
);
|
|
384
|
+
|
|
385
|
+
const input = screen.getByRole('textbox', {
|
|
386
|
+
name: 'Schedule Start time',
|
|
387
|
+
});
|
|
388
|
+
const describedByIDs =
|
|
389
|
+
input.getAttribute('aria-describedby')?.split(' ') ?? [];
|
|
390
|
+
const statusNode = describedByIDs
|
|
391
|
+
.map(id => document.getElementById(id))
|
|
392
|
+
.find(el => el?.textContent === 'Start time is required');
|
|
393
|
+
expect(statusNode).toBeTruthy();
|
|
394
|
+
expect(statusNode).not.toHaveAttribute('role');
|
|
395
|
+
expect(statusNode).not.toHaveAttribute('aria-live');
|
|
396
|
+
|
|
397
|
+
await waitFor(() => {
|
|
398
|
+
expect(assertiveRegion()).toHaveTextContent('Start time is required');
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
// Regression: a grouped status message appearing after mount (the common
|
|
403
|
+
// validation flow) must land in the persistent announce region.
|
|
404
|
+
it('announces a grouped status message that appears after mount', async () => {
|
|
405
|
+
const grouped = (status?: {
|
|
406
|
+
type: 'error' | 'warning';
|
|
407
|
+
message: string;
|
|
408
|
+
}) => (
|
|
409
|
+
<InputGroup label="Schedule">
|
|
410
|
+
<InputGroupText>Starts</InputGroupText>
|
|
411
|
+
<TimeInput
|
|
412
|
+
label="Start time"
|
|
413
|
+
isLabelHidden
|
|
414
|
+
value={'09:00' as ISOTimeString}
|
|
415
|
+
onChange={() => {}}
|
|
416
|
+
status={status}
|
|
417
|
+
/>
|
|
418
|
+
</InputGroup>
|
|
419
|
+
);
|
|
420
|
+
const {rerender} = render(grouped());
|
|
421
|
+
expect(politeRegion()).toBeNull();
|
|
422
|
+
|
|
423
|
+
rerender(grouped({type: 'warning', message: 'Schedule is unusual'}));
|
|
424
|
+
await waitFor(() => {
|
|
425
|
+
expect(politeRegion()).toHaveTextContent('Schedule is unusual');
|
|
426
|
+
});
|
|
427
|
+
// Non-error statuses stay on the polite channel.
|
|
428
|
+
expect(assertiveRegion()).toHaveTextContent('');
|
|
429
|
+
});
|
|
355
430
|
});
|
|
356
431
|
|
|
357
432
|
describe('disabledMessage', () => {
|
|
@@ -496,3 +571,26 @@ describe('TimeInput', () => {
|
|
|
496
571
|
});
|
|
497
572
|
});
|
|
498
573
|
});
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
describe('TimeInput statusVariant forwarding', () => {
|
|
577
|
+
it('defaults to attached (status renders with data-variant="attached")', () => {
|
|
578
|
+
const {container} = render(
|
|
579
|
+
<TimeInput label="Start" value={undefined} onChange={() => {}} status={{type: 'error', message: 'Required'}} />,
|
|
580
|
+
);
|
|
581
|
+
expect(container.querySelector('.astryx-field-status')).toHaveAttribute(
|
|
582
|
+
'data-variant',
|
|
583
|
+
'attached',
|
|
584
|
+
);
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
it('forwards statusVariant="detached" to the underlying Field status', () => {
|
|
588
|
+
const {container} = render(
|
|
589
|
+
<TimeInput label="Start" value={undefined} onChange={() => {}} status={{type: 'error', message: 'Required'}} statusVariant="detached" />,
|
|
590
|
+
);
|
|
591
|
+
expect(container.querySelector('.astryx-field-status')).toHaveAttribute(
|
|
592
|
+
'data-variant',
|
|
593
|
+
'detached',
|
|
594
|
+
);
|
|
595
|
+
});
|
|
596
|
+
});
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @file TimeInput.tsx
|
|
7
|
-
* @input Uses React, useId, useState, useCallback, useRef, Field, Icon, InputGroupContext
|
|
7
|
+
* @input Uses React, useId, useState, useCallback, useRef, Field, Icon, InputGroupContext, useAnnounce
|
|
8
8
|
* @output Exports TimeInput component, TimeInputProps
|
|
9
9
|
* @position Core implementation; consumed by index.ts, tested by TimeInput.test.tsx
|
|
10
10
|
*
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
useId,
|
|
21
21
|
useState,
|
|
22
22
|
useCallback,
|
|
23
|
+
useEffect,
|
|
23
24
|
useRef,
|
|
24
25
|
useMemo,
|
|
25
26
|
useOptimistic,
|
|
@@ -28,7 +29,6 @@ import {
|
|
|
28
29
|
type FocusEvent,
|
|
29
30
|
} from 'react';
|
|
30
31
|
import * as stylex from '@stylexjs/stylex';
|
|
31
|
-
import type {IconName} from '../Icon';
|
|
32
32
|
import {
|
|
33
33
|
colorVars,
|
|
34
34
|
sizeVars,
|
|
@@ -40,11 +40,11 @@ import {
|
|
|
40
40
|
import {
|
|
41
41
|
Field,
|
|
42
42
|
type InputStatus,
|
|
43
|
-
type InputStatusType,
|
|
44
43
|
inputWrapperStyles,
|
|
45
44
|
inputStatusBorderStyles,
|
|
46
45
|
inputStatusHoverShadowStyles,
|
|
47
46
|
inputStatusFocusWithinStyles,
|
|
47
|
+
type FieldStatusVariant,
|
|
48
48
|
} from '../Field';
|
|
49
49
|
import {Icon} from '../Icon';
|
|
50
50
|
import {Spinner} from '../Spinner';
|
|
@@ -64,7 +64,9 @@ import {
|
|
|
64
64
|
import type {BaseProps} from '../BaseProps';
|
|
65
65
|
import type {SizeValue} from '../utils/types';
|
|
66
66
|
import {useSize} from '../SizeContext/SizeContext';
|
|
67
|
+
import {useAnnounce} from '../hooks/useAnnounce';
|
|
67
68
|
import {useInputContainer} from '../hooks/useInputContainer';
|
|
69
|
+
import {useInputStatusIcon} from '../hooks/useInputStatusIcon';
|
|
68
70
|
import {useInputGroup} from '../InputGroup/InputGroupContext';
|
|
69
71
|
import {groupStyles} from '../InputGroup/groupStyles';
|
|
70
72
|
import {useTooltip} from '../Tooltip';
|
|
@@ -296,6 +298,14 @@ export interface TimeInputProps extends Omit<
|
|
|
296
298
|
* If message is provided, displays below the input.
|
|
297
299
|
*/
|
|
298
300
|
status?: InputStatus;
|
|
301
|
+
/**
|
|
302
|
+
* How the status message is placed relative to the input.
|
|
303
|
+
* - 'attached': message overlaps directly below the input (bordered treatment)
|
|
304
|
+
* - 'detached': message floats below as a separate element with spacing
|
|
305
|
+
* - 'tooltip': no message box; the status icon becomes a focusable info-tip button that reveals the message on hover, keyboard focus, or tap
|
|
306
|
+
* @default 'attached'
|
|
307
|
+
*/
|
|
308
|
+
statusVariant?: FieldStatusVariant;
|
|
299
309
|
|
|
300
310
|
/**
|
|
301
311
|
* Width of the field. Numbers are treated as pixels, strings are used as-is
|
|
@@ -345,6 +355,7 @@ export function TimeInput({
|
|
|
345
355
|
placeholder: placeholderFromProps,
|
|
346
356
|
size: sizeProp,
|
|
347
357
|
status,
|
|
358
|
+
statusVariant = 'attached',
|
|
348
359
|
labelTooltip,
|
|
349
360
|
width,
|
|
350
361
|
xstyle,
|
|
@@ -369,6 +380,21 @@ export function TimeInput({
|
|
|
369
380
|
const [optimisticValue, setOptimisticValue] = useOptimistic(value);
|
|
370
381
|
const isBusy = isLoading || optimisticValue !== value;
|
|
371
382
|
|
|
383
|
+
// In grouped mode the status message renders as a visually-hidden node that
|
|
384
|
+
// exists only for aria-describedby. Announce it through the persistent
|
|
385
|
+
// useAnnounce live regions instead of role/aria-live on that node — a live
|
|
386
|
+
// region mounted together with its content is not reliably announced.
|
|
387
|
+
// Ungrouped mode delegates to Field -> FieldStatus, which announces itself.
|
|
388
|
+
const announce = useAnnounce();
|
|
389
|
+
useEffect(() => {
|
|
390
|
+
if (inputGroup && status?.message) {
|
|
391
|
+
announce(
|
|
392
|
+
status.message,
|
|
393
|
+
status.type === 'error' ? 'assertive' : 'polite',
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
}, [announce, inputGroup, status?.message, status?.type]);
|
|
397
|
+
|
|
372
398
|
// Disabled-reason tooltip. Disabled controls swallow pointer events, so the
|
|
373
399
|
// tooltip listeners attach to the input container (which already exists) and
|
|
374
400
|
// the input stays perceivable via aria-disabled instead of the disabled
|
|
@@ -383,26 +409,21 @@ export function TimeInput({
|
|
|
383
409
|
});
|
|
384
410
|
|
|
385
411
|
// Status icon mapping
|
|
386
|
-
const
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
const statusIconColorMap: Record<
|
|
393
|
-
InputStatusType,
|
|
394
|
-
'warning' | 'error' | 'success'
|
|
395
|
-
> = {
|
|
396
|
-
warning: 'warning',
|
|
397
|
-
error: 'error',
|
|
398
|
-
success: 'success',
|
|
399
|
-
};
|
|
412
|
+
const {statusIcon, describedBy: statusTooltipDescribedBy} =
|
|
413
|
+
useInputStatusIcon({
|
|
414
|
+
status,
|
|
415
|
+
statusVariant,
|
|
416
|
+
isInGroup: !!inputGroup,
|
|
417
|
+
});
|
|
400
418
|
|
|
401
419
|
const {ariaLabelledBy, ariaDescribedBy} = getInputARIA(
|
|
402
420
|
inputLabelID,
|
|
403
421
|
[
|
|
404
422
|
description ? descriptionID : null,
|
|
405
|
-
status?.message ? statusMessageID : null,
|
|
423
|
+
statusVariant !== 'tooltip' && status?.message ? statusMessageID : null,
|
|
424
|
+
// The tooltip variant renders no message box; describe the input by the
|
|
425
|
+
// tooltip's content instead so the status is still announced.
|
|
426
|
+
statusTooltipDescribedBy,
|
|
406
427
|
showsDisabledMessage ? disabledMessageTooltip.describedBy : null,
|
|
407
428
|
],
|
|
408
429
|
inputGroup,
|
|
@@ -593,7 +614,7 @@ export function TimeInput({
|
|
|
593
614
|
sizeStyles[size],
|
|
594
615
|
isDisabled && inputWrapperStyles.disabled,
|
|
595
616
|
status && inputStatusBorderStyles[status.type],
|
|
596
|
-
status && inputStatusHoverShadowStyles[status.type],
|
|
617
|
+
status && !isDisabled && inputStatusHoverShadowStyles[status.type],
|
|
597
618
|
status && inputStatusFocusWithinStyles[status.type],
|
|
598
619
|
inputGroup && groupStyles.inGroup,
|
|
599
620
|
xstyle,
|
|
@@ -611,11 +632,7 @@ export function TimeInput({
|
|
|
611
632
|
</VisuallyHidden>
|
|
612
633
|
)}
|
|
613
634
|
{inputGroup && status?.message && (
|
|
614
|
-
<VisuallyHidden
|
|
615
|
-
as="div"
|
|
616
|
-
id={statusMessageID}
|
|
617
|
-
role={status.type === 'error' ? 'alert' : 'status'}
|
|
618
|
-
aria-live={status.type === 'error' ? 'assertive' : 'polite'}>
|
|
635
|
+
<VisuallyHidden as="div" id={statusMessageID}>
|
|
619
636
|
{status.message}
|
|
620
637
|
</VisuallyHidden>
|
|
621
638
|
)}
|
|
@@ -668,13 +685,7 @@ export function TimeInput({
|
|
|
668
685
|
<Icon icon="close" size="sm" color="secondary" />
|
|
669
686
|
</button>
|
|
670
687
|
)}
|
|
671
|
-
{
|
|
672
|
-
<Icon
|
|
673
|
-
icon={statusIconMap[status.type]}
|
|
674
|
-
size="md"
|
|
675
|
-
color={statusIconColorMap[status.type]}
|
|
676
|
-
/>
|
|
677
|
-
)}
|
|
688
|
+
{statusIcon}
|
|
678
689
|
</div>
|
|
679
690
|
);
|
|
680
691
|
|
|
@@ -707,6 +718,7 @@ export function TimeInput({
|
|
|
707
718
|
}
|
|
708
719
|
: undefined
|
|
709
720
|
}
|
|
721
|
+
statusVariant={statusVariant}
|
|
710
722
|
labelTooltip={labelTooltip}
|
|
711
723
|
width={width}>
|
|
712
724
|
{inputWrapper}
|