@astryxdesign/core 0.1.8 → 0.1.9
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 +18 -2
- package/dist/Avatar/Avatar.d.ts.map +1 -1
- package/dist/Avatar/Avatar.js +63 -7
- package/dist/Avatar/AvatarStatusDot.d.ts +33 -5
- package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
- package/dist/Avatar/AvatarStatusDot.js +144 -19
- package/dist/Banner/Banner.d.ts +9 -1
- package/dist/Banner/Banner.d.ts.map +1 -1
- package/dist/Banner/Banner.js +31 -2
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts +31 -2
- package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
- package/dist/Breadcrumbs/BreadcrumbItem.js +208 -6
- package/dist/Breadcrumbs/index.d.ts +5 -0
- package/dist/Breadcrumbs/index.d.ts.map +1 -1
- package/dist/Breadcrumbs/index.js +9 -1
- package/dist/Button/Button.d.ts +8 -2
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +31 -2
- 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 +30 -2
- package/dist/Calendar/dayCellUtils.js +1 -1
- 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 +24 -4
- 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 +35 -3
- 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 +1 -1
- package/dist/Chat/ChatLayout.d.ts.map +1 -1
- 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 +18 -9
- 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/CheckboxInput/CheckboxInput.js +1 -1
- 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/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 +8 -1
- package/dist/CommandPalette/CommandPalette.d.ts +1 -1
- package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
- package/dist/CommandPalette/CommandPalette.js +3 -1
- 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/DateInput/DateInput.d.ts +47 -1
- package/dist/DateInput/DateInput.d.ts.map +1 -1
- package/dist/DateInput/DateInput.js +26 -2
- package/dist/DateInput/index.d.ts +1 -1
- package/dist/DateInput/index.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
- package/dist/DateTimeInput/DateTimeInput.js +10 -1
- 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/DropdownMenuCheckboxItem.d.ts +1 -2
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +1 -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/Field/Field.d.ts.map +1 -1
- package/dist/Field/Field.js +2 -3
- package/dist/Field/FieldLabel.d.ts +1 -1
- package/dist/Field/FieldLabel.d.ts.map +1 -1
- package/dist/Field/FieldLabel.js +42 -15
- package/dist/FieldStatus/FieldStatus.d.ts +8 -0
- package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
- package/dist/FieldStatus/FieldStatus.js +22 -4
- package/dist/FileInput/FileInput.d.ts.map +1 -1
- package/dist/FileInput/FileInput.js +10 -2
- 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 +7 -2
- package/dist/Icon/Icon.d.ts +7 -2
- package/dist/Icon/Icon.d.ts.map +1 -1
- 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/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.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +39 -12
- package/dist/MultiSelector/hooks.d.ts.map +1 -1
- package/dist/MultiSelector/hooks.js +16 -0
- package/dist/NumberInput/NumberInput.d.ts.map +1 -1
- 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/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/PowerSearchEditPopover.js +1 -1
- package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -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.map +1 -1
- package/dist/Selector/Selector.js +4 -2
- package/dist/Selector/hooks.d.ts.map +1 -1
- package/dist/Selector/hooks.js +16 -0
- package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
- package/dist/SideNav/SideNavHeading.js +21 -8
- package/dist/SideNav/SideNavItem.d.ts.map +1 -1
- package/dist/Slider/Slider.d.ts.map +1 -1
- package/dist/Slider/Slider.js +19 -2
- package/dist/Stack/stack.stylex.d.ts +9 -9
- package/dist/Table/BaseTable.d.ts.map +1 -1
- package/dist/Table/BaseTable.js +3 -2
- 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/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 +4 -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 +87 -0
- 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/useBaseTablePlugins.d.ts.map +1 -1
- package/dist/Table/useBaseTablePlugins.js +5 -3
- 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.map +1 -1
- package/dist/TimeInput/TimeInput.js +15 -4
- 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/Tokenizer/Tokenizer.d.ts +1 -1
- package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
- package/dist/Tokenizer/Tokenizer.js +16 -4
- 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 +2 -0
- package/dist/TreeList/TreeListBranches.d.ts +5 -0
- package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
- package/dist/TreeList/TreeListBranches.js +10 -4
- package/dist/TreeList/TreeListItem.d.ts +8 -2
- package/dist/TreeList/TreeListItem.d.ts.map +1 -1
- package/dist/TreeList/TreeListItem.js +27 -7
- 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/astryx.css +28 -18
- package/dist/astryx.umd.js +51 -51
- 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 +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +2 -1
- 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/useOverflow.d.ts +19 -0
- package/dist/hooks/useOverflow.d.ts.map +1 -1
- package/dist/hooks/useOverflow.js +36 -25
- package/dist/i18n/resolve.d.ts.map +1 -1
- package/dist/i18n/resolve.js +7 -18
- package/dist/theme/Theme.d.ts.map +1 -1
- package/dist/theme/Theme.js +2 -7
- 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 +3 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -2
- package/dist/utils/plainDate.d.ts +30 -0
- package/dist/utils/plainDate.d.ts.map +1 -1
- package/dist/utils/plainDate.js +53 -0
- package/dist/utils/types.d.ts +13 -0
- package/dist/utils/types.d.ts.map +1 -1
- package/locales/en.json +24 -0
- package/locales/fr-FR.json +14 -0
- package/locales/pseudo.json +18 -0
- package/package.json +1 -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 +15 -3
- package/src/Avatar/Avatar.test.tsx +156 -1
- package/src/Avatar/Avatar.tsx +96 -4
- package/src/Avatar/AvatarStatusDot.doc.mjs +23 -12
- package/src/Avatar/AvatarStatusDot.test.tsx +284 -0
- package/src/Avatar/AvatarStatusDot.tsx +178 -21
- package/src/Banner/Banner.doc.mjs +9 -0
- package/src/Banner/Banner.test.tsx +30 -0
- package/src/Banner/Banner.tsx +47 -3
- 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 +284 -2
- package/src/Breadcrumbs/index.ts +27 -0
- package/src/Button/Button.doc.mjs +9 -0
- package/src/Button/Button.test.tsx +49 -0
- package/src/Button/Button.tsx +25 -1
- 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 +193 -0
- package/src/Calendar/Calendar.tsx +38 -16
- package/src/Calendar/dayCellUtils.test.ts +5 -0
- package/src/Calendar/dayCellUtils.ts +1 -1
- 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 +34 -4
- 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 +49 -3
- package/src/Chat/ChatContext.tsx +37 -10
- package/src/Chat/ChatDictationButton.tsx +4 -1
- package/src/Chat/ChatLayout.tsx +3 -1
- 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 +25 -4
- 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 +3 -1
- package/src/CheckboxInput/CheckboxInput.test.tsx +32 -1
- package/src/CheckboxInput/CheckboxInput.tsx +1 -1
- 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/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 +9 -1
- package/src/CommandPalette/CommandPalette.doc.mjs +1 -0
- package/src/CommandPalette/CommandPalette.tsx +3 -1
- 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/ContextMenu/ContextMenu.test.tsx +193 -0
- package/src/DateInput/DateInput.doc.mjs +16 -0
- package/src/DateInput/DateInput.test.tsx +108 -0
- package/src/DateInput/DateInput.tsx +68 -3
- package/src/DateInput/index.ts +1 -0
- package/src/DateTimeInput/DateTimeInput.test.tsx +35 -0
- package/src/DateTimeInput/DateTimeInput.tsx +14 -2
- 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 +169 -0
- package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +1 -2
- package/src/DropdownMenu/DropdownMenuRadioGroup.tsx +1 -2
- package/src/Field/Field.test.tsx +57 -12
- package/src/Field/Field.tsx +6 -5
- package/src/Field/FieldLabel.tsx +8 -0
- package/src/FieldStatus/FieldStatus.doc.mjs +17 -5
- package/src/FieldStatus/FieldStatus.test.tsx +78 -40
- package/src/FieldStatus/FieldStatus.tsx +22 -4
- package/src/FileInput/FileInput.test.tsx +52 -3
- package/src/FileInput/FileInput.tsx +13 -2
- 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 +24 -2
- package/src/Icon/Icon.doc.mjs +3 -2
- package/src/Icon/Icon.tsx +7 -2
- 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/List/List.test.tsx +9 -8
- 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 +4 -2
- package/src/MultiSelector/MultiSelector.test.tsx +172 -3
- package/src/MultiSelector/MultiSelector.tsx +55 -12
- package/src/MultiSelector/hooks.ts +17 -0
- package/src/NumberInput/NumberInput.test.tsx +11 -7
- package/src/NumberInput/NumberInput.tsx +1 -2
- 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/Popover/Popover.tsx +7 -4
- package/src/Popover/usePopover.tsx +9 -13
- package/src/PowerSearch/PowerSearch.doc.mjs +14 -0
- package/src/PowerSearch/PowerSearch.test.tsx +20 -0
- package/src/PowerSearch/PowerSearchEditPopover.test.tsx +67 -0
- package/src/PowerSearch/PowerSearchEditPopover.tsx +1 -1
- package/src/PowerSearch/usePowerSearchSource.ts +1 -2
- 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.test.tsx +69 -0
- package/src/Selector/Selector.tsx +5 -1
- package/src/Selector/hooks.ts +17 -0
- package/src/SideNav/SideNav.test.tsx +119 -3
- package/src/SideNav/SideNavCollapseButton.tsx +6 -1
- package/src/SideNav/SideNavHeading.tsx +24 -8
- package/src/SideNav/SideNavItem.tsx +5 -1
- package/src/Slider/Slider.test.tsx +75 -2
- package/src/Slider/Slider.tsx +21 -5
- package/src/Switch/Switch.test.tsx +32 -1
- package/src/Table/BaseTable.tsx +3 -5
- package/src/Table/index.ts +5 -0
- package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +6 -2
- 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 +16 -0
- package/src/Table/plugins/selection/useTableSelection.tsx +19 -1
- package/src/Table/plugins/tree/useTableTreeData.test.tsx +135 -3
- package/src/Table/plugins/tree/useTableTreeData.tsx +128 -1
- package/src/Table/plugins/tree/useTableTreeState.test.tsx +104 -0
- package/src/Table/plugins/tree/useTableTreeState.tsx +46 -2
- 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.test.tsx +9 -1
- package/src/Thumbnail/Thumbnail.doc.mjs +19 -10
- package/src/Thumbnail/Thumbnail.test.tsx +98 -7
- package/src/Thumbnail/Thumbnail.tsx +141 -41
- package/src/Thumbnail/thumbnail.markers.stylex.ts +12 -0
- package/src/TimeInput/TimeInput.test.tsx +76 -1
- package/src/TimeInput/TimeInput.tsx +19 -6
- 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/Tokenizer/Tokenizer.doc.mjs +15 -1
- package/src/Tokenizer/Tokenizer.test.tsx +183 -2
- package/src/Tokenizer/Tokenizer.tsx +16 -4
- 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 +22 -0
- package/src/TreeList/TreeList.test.tsx +232 -0
- package/src/TreeList/TreeList.tsx +18 -2
- package/src/TreeList/TreeListBranches.tsx +16 -2
- package/src/TreeList/TreeListItem.tsx +51 -11
- package/src/TreeList/TreeListTypes.ts +27 -1
- package/src/TreeList/index.ts +2 -2
- package/src/authoring/doc.ts +1 -3
- 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 +2 -0
- package/src/hooks/useDevWarning.test.tsx +45 -0
- package/src/hooks/useDevWarning.ts +54 -0
- package/src/hooks/useOverflow.test.ts +96 -4
- package/src/hooks/useOverflow.ts +74 -33
- package/src/i18n/InternationalizationProvider.doc.mjs +99 -2
- package/src/i18n/resolve.ts +9 -21
- package/src/theme/Theme.tsx +11 -14
- package/src/theme/generateThemeRules.test.ts +65 -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 +6 -0
- package/src/utils/plainDate.test.ts +22 -0
- package/src/utils/plainDate.ts +61 -0
- package/src/utils/types.ts +14 -0
|
@@ -634,3 +634,107 @@ describe('useTableTreeState — semantics edges', () => {
|
|
|
634
634
|
expect(ids(result.current.visibleData)).toEqual(['src', 'readme']);
|
|
635
635
|
});
|
|
636
636
|
});
|
|
637
|
+
|
|
638
|
+
// =============================================================================
|
|
639
|
+
// isAllExpanded (drives the header expand-all control)
|
|
640
|
+
// =============================================================================
|
|
641
|
+
|
|
642
|
+
describe('useTableTreeState: isAllExpanded', () => {
|
|
643
|
+
it('reports false when nothing is expanded', () => {
|
|
644
|
+
const {result} = renderHook(() =>
|
|
645
|
+
useTableTreeState({data: fileTree, idKey: 'id'}),
|
|
646
|
+
);
|
|
647
|
+
|
|
648
|
+
expect(result.current.isAllExpanded).toBe(false);
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
it('reports true only when every expandable row is expanded', () => {
|
|
652
|
+
const {result} = renderHook(() =>
|
|
653
|
+
useTableTreeState({data: fileTree, idKey: 'id'}),
|
|
654
|
+
);
|
|
655
|
+
|
|
656
|
+
act(() => {
|
|
657
|
+
result.current.expandAll();
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
expect(result.current.isAllExpanded).toBe(true);
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
it("reports 'indeterminate' when some but not all expandable rows are expanded", () => {
|
|
664
|
+
const {result} = renderHook(() =>
|
|
665
|
+
useTableTreeState({
|
|
666
|
+
data: fileTree,
|
|
667
|
+
idKey: 'id',
|
|
668
|
+
defaultExpandedIds: ['src'],
|
|
669
|
+
}),
|
|
670
|
+
);
|
|
671
|
+
|
|
672
|
+
// 'src' and 'components' are both expandable; only 'src' is expanded.
|
|
673
|
+
expect(result.current.isAllExpanded).toBe('indeterminate');
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
it('returns to false after collapseAll', () => {
|
|
677
|
+
const {result} = renderHook(() =>
|
|
678
|
+
useTableTreeState({
|
|
679
|
+
data: fileTree,
|
|
680
|
+
idKey: 'id',
|
|
681
|
+
defaultExpandedIds: ['src', 'components'],
|
|
682
|
+
}),
|
|
683
|
+
);
|
|
684
|
+
|
|
685
|
+
act(() => {
|
|
686
|
+
result.current.collapseAll();
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
expect(result.current.isAllExpanded).toBe(false);
|
|
690
|
+
});
|
|
691
|
+
|
|
692
|
+
it('reports false for flat data (no expandable rows)', () => {
|
|
693
|
+
const flat: FileRow[] = [
|
|
694
|
+
{id: 'a', name: 'A', size: 1},
|
|
695
|
+
{id: 'b', name: 'B', size: 2},
|
|
696
|
+
];
|
|
697
|
+
const {result} = renderHook(() =>
|
|
698
|
+
useTableTreeState({data: flat, idKey: 'id'}),
|
|
699
|
+
);
|
|
700
|
+
|
|
701
|
+
expect(result.current.isAllExpanded).toBe(false);
|
|
702
|
+
});
|
|
703
|
+
|
|
704
|
+
it('ignores expanded ids that match no expandable row when aggregating', () => {
|
|
705
|
+
// 'readme' is a leaf (not expandable) and 'ghost' matches nothing; neither
|
|
706
|
+
// should count toward the expandable total, so an all-expandable set that
|
|
707
|
+
// omits them still reads as fully expanded.
|
|
708
|
+
const {result} = renderHook(() =>
|
|
709
|
+
useTableTreeState({
|
|
710
|
+
data: fileTree,
|
|
711
|
+
idKey: 'id',
|
|
712
|
+
defaultExpandedIds: ['src', 'components', 'readme', 'ghost'],
|
|
713
|
+
}),
|
|
714
|
+
);
|
|
715
|
+
|
|
716
|
+
expect(result.current.isAllExpanded).toBe(true);
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
it('exposes the aggregate state and expand/collapse handlers through treeConfig', () => {
|
|
720
|
+
const {result} = renderHook(() =>
|
|
721
|
+
useTableTreeState({data: fileTree, idKey: 'id'}),
|
|
722
|
+
);
|
|
723
|
+
|
|
724
|
+
// The headless plugin reads everything it needs to render the header
|
|
725
|
+
// expand-all control from treeConfig, not from the state hook directly.
|
|
726
|
+
expect(result.current.treeConfig.isAllExpanded).toBe(false);
|
|
727
|
+
|
|
728
|
+
act(() => {
|
|
729
|
+
result.current.treeConfig.onExpandAll?.();
|
|
730
|
+
});
|
|
731
|
+
expect(result.current.isAllExpanded).toBe(true);
|
|
732
|
+
expect(result.current.treeConfig.isAllExpanded).toBe(true);
|
|
733
|
+
|
|
734
|
+
act(() => {
|
|
735
|
+
result.current.treeConfig.onCollapseAll?.();
|
|
736
|
+
});
|
|
737
|
+
expect(result.current.isAllExpanded).toBe(false);
|
|
738
|
+
expect(result.current.treeConfig.isAllExpanded).toBe(false);
|
|
739
|
+
});
|
|
740
|
+
});
|
|
@@ -74,6 +74,12 @@ export interface UseTableTreeStateResult<T extends Record<string, unknown>> {
|
|
|
74
74
|
treeConfig: UseTableTreeDataConfig<T>;
|
|
75
75
|
/** The current expanded row ids. */
|
|
76
76
|
expandedIds: ReadonlySet<string>;
|
|
77
|
+
/**
|
|
78
|
+
* Aggregate expansion state across every expandable row: `true` when all are
|
|
79
|
+
* expanded, `false` when none are, `'indeterminate'` when some but not all
|
|
80
|
+
* are. Drives the header expand-all control. Reports `false` for flat data.
|
|
81
|
+
*/
|
|
82
|
+
isAllExpanded: boolean | 'indeterminate';
|
|
77
83
|
/** Expand every expandable row in the tree. */
|
|
78
84
|
expandAll: () => void;
|
|
79
85
|
/** Collapse every row. */
|
|
@@ -211,6 +217,25 @@ export function useTableTreeState<T extends Record<string, unknown>>(
|
|
|
211
217
|
|
|
212
218
|
const hasExpandableRows = allExpandableIds.length > 0;
|
|
213
219
|
|
|
220
|
+
// Aggregate state for the header expand-all control. Only expandable ids
|
|
221
|
+
// count toward the total, so expanded ids that match a leaf or no row at
|
|
222
|
+
// all never skew the tally.
|
|
223
|
+
const isAllExpanded: boolean | 'indeterminate' = useMemo(() => {
|
|
224
|
+
if (!hasExpandableRows) {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
const expandedCount = allExpandableIds.filter(id =>
|
|
228
|
+
expandedIds.has(id),
|
|
229
|
+
).length;
|
|
230
|
+
if (expandedCount === 0) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
if (expandedCount === allExpandableIds.length) {
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
return 'indeterminate';
|
|
237
|
+
}, [hasExpandableRows, allExpandableIds, expandedIds]);
|
|
238
|
+
|
|
214
239
|
const onToggleItem = useCallback(
|
|
215
240
|
(item: T) => {
|
|
216
241
|
const id = getId(item);
|
|
@@ -243,11 +268,30 @@ export function useTableTreeState<T extends Record<string, unknown>>(
|
|
|
243
268
|
getRowMeta,
|
|
244
269
|
onToggleItem,
|
|
245
270
|
hasExpandableRows,
|
|
271
|
+
isAllExpanded,
|
|
272
|
+
onExpandAll: expandAll,
|
|
273
|
+
onCollapseAll: collapseAll,
|
|
246
274
|
indent,
|
|
247
275
|
treeColumnKey,
|
|
248
276
|
}),
|
|
249
|
-
[
|
|
277
|
+
[
|
|
278
|
+
getRowMeta,
|
|
279
|
+
onToggleItem,
|
|
280
|
+
hasExpandableRows,
|
|
281
|
+
isAllExpanded,
|
|
282
|
+
expandAll,
|
|
283
|
+
collapseAll,
|
|
284
|
+
indent,
|
|
285
|
+
treeColumnKey,
|
|
286
|
+
],
|
|
250
287
|
);
|
|
251
288
|
|
|
252
|
-
return {
|
|
289
|
+
return {
|
|
290
|
+
visibleData,
|
|
291
|
+
treeConfig,
|
|
292
|
+
expandedIds,
|
|
293
|
+
isAllExpanded,
|
|
294
|
+
expandAll,
|
|
295
|
+
collapseAll,
|
|
296
|
+
};
|
|
253
297
|
}
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
|
|
39
39
|
import {useRef} from 'react';
|
|
40
40
|
import type {TablePlugin} from './types';
|
|
41
|
+
import {devWarn} from '../utils/devWarning';
|
|
41
42
|
|
|
42
43
|
// ======================================================================// Canonical Plugin Order
|
|
43
44
|
// ======================================================================
|
|
@@ -112,8 +113,9 @@ function validatePlugin<T extends Record<string, unknown>>(
|
|
|
112
113
|
// Warn about unknown keys (likely misspelled transform names)
|
|
113
114
|
for (const key of keys) {
|
|
114
115
|
if (!VALID_TRANSFORM_KEYS.has(key)) {
|
|
115
|
-
|
|
116
|
-
|
|
116
|
+
devWarn(
|
|
117
|
+
'Table',
|
|
118
|
+
`Plugin "${name}" has unknown key "${key}". ` +
|
|
117
119
|
`Valid keys: ${[...VALID_TRANSFORM_KEYS].join(', ')}. ` +
|
|
118
120
|
`This key will be ignored.`,
|
|
119
121
|
);
|
|
@@ -125,8 +127,9 @@ function validatePlugin<T extends Record<string, unknown>>(
|
|
|
125
127
|
if (VALID_TRANSFORM_KEYS.has(key)) {
|
|
126
128
|
const value = (plugin as Record<string, unknown>)[key];
|
|
127
129
|
if (value != null && typeof value !== 'function') {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
+
devWarn(
|
|
131
|
+
'Table',
|
|
132
|
+
`Plugin "${name}" has non-function value for "${key}" ` +
|
|
130
133
|
`(got ${typeof value}). Transform will be skipped.`,
|
|
131
134
|
);
|
|
132
135
|
}
|
|
@@ -140,8 +143,9 @@ function validatePlugin<T extends Record<string, unknown>>(
|
|
|
140
143
|
typeof (plugin as Record<string, unknown>)[key] === 'function',
|
|
141
144
|
);
|
|
142
145
|
if (!hasTransforms) {
|
|
143
|
-
|
|
144
|
-
|
|
146
|
+
devWarn(
|
|
147
|
+
'Table',
|
|
148
|
+
`Plugin "${name}" has no transform methods. ` +
|
|
145
149
|
`It will be included in the pipeline but won't do anything.`,
|
|
146
150
|
);
|
|
147
151
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/** @type {import('../docs-types').ComponentDoc} */
|
|
4
|
+
|
|
5
|
+
export const docs = {
|
|
6
|
+
name: 'useTableRowStatus',
|
|
7
|
+
subComponentOf: 'Table',
|
|
8
|
+
displayName: 'useTableRowStatus',
|
|
9
|
+
description:
|
|
10
|
+
'Hook that returns a TablePlugin which prepends a narrow column signaling per-row status: a colored status dot by default, or an icon when provided (shape + color is more accessible than color alone). getStatus maps a row to a semantic color (mapped to a theme token) or raw CSS color, an optional icon, and a required accessible label (shown in a tooltip on hover and announced to assistive technology, so status is never color-only); return null for no indicator. Memoize getStatus with useCallback for a stable plugin identity.',
|
|
11
|
+
props: [
|
|
12
|
+
{
|
|
13
|
+
name: 'getStatus',
|
|
14
|
+
type: "(item: T) => { color: 'accent' | 'success' | 'error' | 'warning' | 'red' | 'orange' | 'green' | 'yellow' | 'blue' | 'gray' | string; icon?: IconName; label: string } | null",
|
|
15
|
+
description:
|
|
16
|
+
'Derive the status indicator for a row: a semantic color (accent, success, error, warning, red, orange, green, yellow, blue, gray — mapped to a theme token) or a raw CSS color as an escape hatch; an optional icon to signal status by shape instead of the dot (recommended when multiple statuses coexist; valid names: close, chevronDown, chevronLeft, chevronRight, check, success, error, warning, info, calendar, clock, externalLink, menu, moreHorizontal, search, arrowUp, arrowDown, arrowsUpDown, funnel, eyeSlash, viewColumns, copy, checkDouble, wrench, stop, microphone); and a required accessible label (announced via role="img" and shown in a tooltip on hover, so a status is never conveyed by color alone). Return null for rows with no status. Memoize with useCallback for a stable plugin identity.',
|
|
17
|
+
required: true,
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/** @type {import('../docs-types').TranslationDoc} */
|
|
23
|
+
export const docsDense = {
|
|
24
|
+
description:
|
|
25
|
+
'Returns a TablePlugin that prepends a narrow per-row status column: a colored dot, or an icon when provided (shape + color beats color alone for a11y). getStatus maps a row to {color, icon?, label} or null. color is a semantic name (success/error/warning/etc.) mapped to a theme token, or a raw CSS color. label is required (tooltip + accessible name). Memoize getStatus with useCallback.',
|
|
26
|
+
propDescriptions: {
|
|
27
|
+
getStatus:
|
|
28
|
+
'Map a row to {color, icon?, label} or null. color = semantic status name (mapped to a token) or raw CSS; icon = shape signifier (a11y); label = required accessible name (tooltip + role="img"). Memoize with useCallback.',
|
|
29
|
+
},
|
|
30
|
+
};
|
|
@@ -6,7 +6,8 @@ export const docs = {
|
|
|
6
6
|
name: 'useTableSelection',
|
|
7
7
|
subComponentOf: 'Table',
|
|
8
8
|
displayName: 'useTableSelection',
|
|
9
|
-
description:
|
|
9
|
+
description:
|
|
10
|
+
'Hook that returns a TablePlugin implementing row selection with checkboxes, select-all, and aria-selected. Uses React Context for independent checkbox re-renders.',
|
|
10
11
|
props: [
|
|
11
12
|
{
|
|
12
13
|
name: 'getIsItemSelected',
|
|
@@ -17,7 +18,8 @@ export const docs = {
|
|
|
17
18
|
{
|
|
18
19
|
name: 'onSelectItem',
|
|
19
20
|
type: '(event: {item: T; isSelected: boolean}) => void',
|
|
20
|
-
description:
|
|
21
|
+
description:
|
|
22
|
+
'Called when a row checkbox is toggled. isSelected is the new desired state.',
|
|
21
23
|
required: true,
|
|
22
24
|
},
|
|
23
25
|
{
|
|
@@ -29,33 +31,67 @@ export const docs = {
|
|
|
29
31
|
{
|
|
30
32
|
name: 'getIsAllSelected',
|
|
31
33
|
type: '() => boolean',
|
|
32
|
-
description:
|
|
34
|
+
description:
|
|
35
|
+
'Returns whether all selectable items are currently selected.',
|
|
33
36
|
required: true,
|
|
34
37
|
},
|
|
35
38
|
{
|
|
36
39
|
name: 'getIsIndeterminate',
|
|
37
40
|
type: '() => boolean',
|
|
38
|
-
description:
|
|
41
|
+
description:
|
|
42
|
+
'Returns whether selection is partial (some but not all). Renders the select-all checkbox in indeterminate state.',
|
|
39
43
|
},
|
|
40
44
|
{
|
|
41
45
|
name: 'getIsItemSelectable',
|
|
42
46
|
type: '(item: T) => boolean',
|
|
43
|
-
description:
|
|
47
|
+
description:
|
|
48
|
+
'Returns whether a row should show a checkbox. Non-selectable rows render nothing in the selection cell.',
|
|
44
49
|
default: '() => true',
|
|
45
50
|
},
|
|
46
51
|
{
|
|
47
52
|
name: 'getIsItemEnabled',
|
|
48
53
|
type: '(item: T) => boolean',
|
|
49
|
-
description:
|
|
54
|
+
description:
|
|
55
|
+
'Returns whether a row checkbox is interactive. Disabled rows show a disabled checkbox.',
|
|
50
56
|
default: '() => true',
|
|
51
57
|
},
|
|
58
|
+
{
|
|
59
|
+
name: 'getRowLabel',
|
|
60
|
+
type: '(item: T) => string',
|
|
61
|
+
description:
|
|
62
|
+
'Derives a human-readable identity for a row; the row checkbox\'s hidden label becomes `Select ${getRowLabel(item)}` so screen readers announce which row each checkbox selects. Falls back to "Select row" when omitted.',
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
examples: [
|
|
66
|
+
{
|
|
67
|
+
label: 'Accessible per-row checkbox names',
|
|
68
|
+
code: `
|
|
69
|
+
const selectionPlugin = useTableSelection({
|
|
70
|
+
getIsItemSelected: item => selectedIds.has(item.id),
|
|
71
|
+
onSelectItem: ({item, isSelected}) => toggle(item.id, isSelected),
|
|
72
|
+
onSelectAll: ({isAllSelected}) => selectAll(isAllSelected),
|
|
73
|
+
getIsAllSelected: () => selectedIds.size === users.length,
|
|
74
|
+
// Screen readers announce "Select Alice", "Select Bob", ...
|
|
75
|
+
// instead of an undifferentiated "Select row" for every checkbox.
|
|
76
|
+
getRowLabel: item => item.name,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
<Table
|
|
80
|
+
data={users}
|
|
81
|
+
columns={columns}
|
|
82
|
+
idKey="id"
|
|
83
|
+
plugins={{selection: selectionPlugin}}
|
|
84
|
+
/>;
|
|
85
|
+
`,
|
|
86
|
+
},
|
|
52
87
|
],
|
|
53
88
|
};
|
|
54
89
|
|
|
55
90
|
export const docsZh = {
|
|
56
91
|
name: 'useTableSelection',
|
|
57
92
|
displayName: 'useTableSelection',
|
|
58
|
-
description:
|
|
93
|
+
description:
|
|
94
|
+
'返回 TablePlugin 的 Hook,实现带复选框、全选和 aria-selected 的行选择功能。使用 React Context 实现独立的复选框重新渲染。',
|
|
59
95
|
props: [
|
|
60
96
|
{
|
|
61
97
|
name: 'getIsItemSelected',
|
|
@@ -84,12 +120,14 @@ export const docsZh = {
|
|
|
84
120
|
{
|
|
85
121
|
name: 'getIsIndeterminate',
|
|
86
122
|
type: '() => boolean',
|
|
87
|
-
description:
|
|
123
|
+
description:
|
|
124
|
+
'返回选择是否为部分选中(部分但非全部)。将全选复选框渲染为不确定状态。',
|
|
88
125
|
},
|
|
89
126
|
{
|
|
90
127
|
name: 'getIsItemSelectable',
|
|
91
128
|
type: '(item: T) => boolean',
|
|
92
|
-
description:
|
|
129
|
+
description:
|
|
130
|
+
'返回行是否应显示复选框。不可选择的行在选择单元格中不渲染任何内容。',
|
|
93
131
|
default: '() => true',
|
|
94
132
|
},
|
|
95
133
|
{
|
|
@@ -98,20 +136,33 @@ export const docsZh = {
|
|
|
98
136
|
description: '返回行复选框是否可交互。禁用的行显示禁用状态的复选框。',
|
|
99
137
|
default: '() => true',
|
|
100
138
|
},
|
|
139
|
+
{
|
|
140
|
+
name: 'getRowLabel',
|
|
141
|
+
type: '(item: T) => string',
|
|
142
|
+
description:
|
|
143
|
+
'为行派生人类可读的标识;行复选框的隐藏标签变为 `Select ${getRowLabel(item)}`,让屏幕阅读器播报每个复选框选择的是哪一行。省略时回退为 "Select row"。',
|
|
144
|
+
},
|
|
101
145
|
],
|
|
102
146
|
};
|
|
103
147
|
|
|
104
148
|
export const docsDense = {
|
|
105
149
|
name: 'useTableSelection',
|
|
106
150
|
displayName: 'useTableSelection',
|
|
107
|
-
description:
|
|
151
|
+
description:
|
|
152
|
+
'Hook returning TablePlugin for row selection w/ checkboxes, select-all, aria-selected. Uses React Context for independent checkbox re-renders.',
|
|
108
153
|
propDescriptions: {
|
|
109
154
|
getIsItemSelected: 'Returns whether item is selected.',
|
|
110
|
-
onSelectItem:
|
|
155
|
+
onSelectItem:
|
|
156
|
+
'Called on row checkbox toggle; isSelected = new desired state.',
|
|
111
157
|
onSelectAll: 'Called on select-all header checkbox toggle.',
|
|
112
158
|
getIsAllSelected: 'Returns whether all selectable items are selected.',
|
|
113
|
-
getIsIndeterminate:
|
|
114
|
-
|
|
115
|
-
|
|
159
|
+
getIsIndeterminate:
|
|
160
|
+
'Returns partial selection state; renders indeterminate checkbox.',
|
|
161
|
+
getIsItemSelectable:
|
|
162
|
+
'Returns whether row shows checkbox; non-selectable rows render nothing.',
|
|
163
|
+
getIsItemEnabled:
|
|
164
|
+
'Returns whether row checkbox is interactive; disabled rows show disabled checkbox.',
|
|
165
|
+
getRowLabel:
|
|
166
|
+
'Derives row identity for the checkbox\'s hidden label: `Select ${getRowLabel(item)}`. Falls back to "Select row" when omitted.',
|
|
116
167
|
},
|
|
117
168
|
};
|
|
@@ -29,6 +29,29 @@ export const docs = {
|
|
|
29
29
|
'Whether any row in the dataset is expandable. When false the plugin is a no-op: no expanders, no indent, no tree ARIA.',
|
|
30
30
|
required: true,
|
|
31
31
|
},
|
|
32
|
+
{
|
|
33
|
+
name: 'hasExpandAllControl',
|
|
34
|
+
type: 'boolean',
|
|
35
|
+
description:
|
|
36
|
+
'Show an expand-all/collapse-all toggle in the tree column header. Requires isAllExpanded plus onExpandAll/onCollapseAll (all supplied by useTableTreeState).',
|
|
37
|
+
default: 'false',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'isAllExpanded',
|
|
41
|
+
type: "boolean | 'indeterminate'",
|
|
42
|
+
description:
|
|
43
|
+
'Aggregate expansion state across every expandable row, driving the header expand-all toggle. true when all are expanded, false when none are, indeterminate when some are.',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'onExpandAll',
|
|
47
|
+
type: '() => void',
|
|
48
|
+
description: 'Expand every expandable row. Wired to the header control.',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'onCollapseAll',
|
|
52
|
+
type: '() => void',
|
|
53
|
+
description: 'Collapse every row. Wired to the header control.',
|
|
54
|
+
},
|
|
32
55
|
{
|
|
33
56
|
name: 'indent',
|
|
34
57
|
type: "'sm' | 'md' | 'lg'",
|
|
@@ -71,5 +94,11 @@ export const docsDense = {
|
|
|
71
94
|
indent:
|
|
72
95
|
"indent step per level: 'sm' | 'md' | 'lg' (spacing-3/4/6). Defaults to 'md'.",
|
|
73
96
|
treeColumnKey: 'column carrying indent + expander. Defaults to first column.',
|
|
97
|
+
hasExpandAllControl:
|
|
98
|
+
'show expand-all/collapse-all toggle in tree column header. Needs isAllExpanded + onExpandAll/onCollapseAll (from useTableTreeState). Defaults to false.',
|
|
99
|
+
isAllExpanded:
|
|
100
|
+
"aggregate state driving the header toggle: true (all) | false (none) | 'indeterminate' (some).",
|
|
101
|
+
onExpandAll: 'expand every expandable row (header control)',
|
|
102
|
+
onCollapseAll: 'collapse every row (header control)',
|
|
74
103
|
},
|
|
75
104
|
};
|
|
@@ -7,7 +7,7 @@ export const docs = {
|
|
|
7
7
|
subComponentOf: 'Table',
|
|
8
8
|
displayName: 'useTableTreeState',
|
|
9
9
|
description:
|
|
10
|
-
'State management companion for useTableTreeData. Owns the expanded set (controlled or uncontrolled) and flattens nested data into the visible row array; collapsed subtrees are unmounted, not hidden, so the table body contains exactly the visible rows. Returns expandAll/collapseAll helpers and a ready-to-use config for the tree plugin. Note: because collapsed rows unmount, cell-local React state inside collapsed subtrees is lost on collapse; lift state that must survive.',
|
|
10
|
+
'State management companion for useTableTreeData. Owns the expanded set (controlled or uncontrolled) and flattens nested data into the visible row array; collapsed subtrees are unmounted, not hidden, so the table body contains exactly the visible rows. Returns expandAll/collapseAll helpers, the aggregate isAllExpanded state (true/false/indeterminate) for a header expand-all control, and a ready-to-use config for the tree plugin. Note: because collapsed rows unmount, cell-local React state inside collapsed subtrees is lost on collapse; lift state that must survive.',
|
|
11
11
|
props: [
|
|
12
12
|
{
|
|
13
13
|
name: 'data',
|
|
@@ -79,7 +79,7 @@ export const docsDense = {
|
|
|
79
79
|
name: 'useTableTreeState',
|
|
80
80
|
displayName: 'useTableTreeState',
|
|
81
81
|
description:
|
|
82
|
-
'State companion for useTableTreeData. Owns expanded set (controlled or uncontrolled), flattens nested data to visible rows (collapsed subtrees unmounted, not hidden). Returns {visibleData, treeConfig, expandedIds, expandAll, collapseAll}. Cell-local state in collapsed subtrees is lost on collapse; lift state that must survive.',
|
|
82
|
+
'State companion for useTableTreeData. Owns expanded set (controlled or uncontrolled), flattens nested data to visible rows (collapsed subtrees unmounted, not hidden). Returns {visibleData, treeConfig, expandedIds, isAllExpanded, expandAll, collapseAll} (isAllExpanded = true/false/indeterminate for a header expand-all control). Cell-local state in collapsed subtrees is lost on collapse; lift state that must survive.',
|
|
83
83
|
propDescriptions: {
|
|
84
84
|
data: 'nested data; rows carry child rows under childrenKey. Flat data => plugin is a no-op.',
|
|
85
85
|
idKey: 'row ID accessor: property name or fn returning unique id',
|
|
@@ -10,11 +10,19 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import {useState} from 'react';
|
|
13
|
-
import {describe, it, expect, vi, beforeEach} from 'vitest';
|
|
13
|
+
import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
|
|
14
14
|
import {render, screen, fireEvent, waitFor} from '@testing-library/react';
|
|
15
15
|
import userEvent from '@testing-library/user-event';
|
|
16
16
|
import {TestIcon} from '../__tests__/TestIcon';
|
|
17
17
|
import {TextArea} from './TextArea';
|
|
18
|
+
import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
|
|
19
|
+
|
|
20
|
+
// FieldStatus announces status messages through the persistent useAnnounce
|
|
21
|
+
// singletons; remove them between tests so role/aria-live queries in this
|
|
22
|
+
// file never match a leftover region.
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
__resetLiveRegionsForTest();
|
|
25
|
+
});
|
|
18
26
|
|
|
19
27
|
// Mock showPopover/hidePopover since jsdom does not implement them. Used by the
|
|
20
28
|
// disabledMessage tooltip.
|
|
@@ -16,7 +16,7 @@ export const docs = {
|
|
|
16
16
|
{
|
|
17
17
|
name: 'alt',
|
|
18
18
|
type: 'string',
|
|
19
|
-
description: 'Alt text for the image.',
|
|
19
|
+
description: 'Alt text for the image. When omitted, the image is explicitly decorative (alt="", role="presentation", aria-hidden) and hidden from screen readers; a dev warning fires if neither alt nor label is set.',
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
name: 'label',
|
|
@@ -31,7 +31,7 @@ export const docs = {
|
|
|
31
31
|
{
|
|
32
32
|
name: 'onClick',
|
|
33
33
|
type: '(e: React.MouseEvent) => void',
|
|
34
|
-
description: 'Click handler. Adds button semantics and hover
|
|
34
|
+
description: 'Click handler. Adds button semantics and a hover overlay.',
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
name: 'isLoading',
|
|
@@ -45,6 +45,13 @@ export const docs = {
|
|
|
45
45
|
description: 'Whether the thumbnail is disabled.',
|
|
46
46
|
default: 'false',
|
|
47
47
|
},
|
|
48
|
+
{
|
|
49
|
+
name: 'showRemoveOn',
|
|
50
|
+
type: "'always' | 'hover'",
|
|
51
|
+
description:
|
|
52
|
+
'When the remove button is visible. `hover` (the default) reveals it on hover and on keyboard focus, and keeps it visible on any touch-capable device; `always` shows it at rest. Only applies when `onRemove` is set.',
|
|
53
|
+
default: "'hover'",
|
|
54
|
+
},
|
|
48
55
|
{
|
|
49
56
|
name: 'xstyle',
|
|
50
57
|
type: 'StyleXStyles',
|
|
@@ -77,14 +84,14 @@ export const docs = {
|
|
|
77
84
|
bestPractices: [
|
|
78
85
|
{guidance: true, description: 'Always provide a label prop with the file name so the thumbnail and its remove button are accessible to screen readers and show a tooltip on hover.'},
|
|
79
86
|
{guidance: true, description: 'Use isLoading without a src to show a skeleton during initial upload, and isLoading with a src to show a spinner overlay once a preview URL is available.'},
|
|
80
|
-
{guidance: true, description: 'Pair onClick with a lightbox or detail view so users can inspect the full image; the thumbnail adds button semantics and a hover
|
|
87
|
+
{guidance: true, description: 'Pair onClick with a lightbox or detail view so users can inspect the full image; the thumbnail adds button semantics and a hover overlay automatically.'},
|
|
81
88
|
{guidance: false, description: "Don't use Thumbnail for non-image file types like PDFs or spreadsheets; use a file attachment component with an appropriate icon instead."},
|
|
82
89
|
{guidance: false, description: "Don't omit alt text when a src is provided; screen readers need a description of the image content, not just the file name from label."},
|
|
83
90
|
],
|
|
84
91
|
anatomy: [
|
|
85
92
|
{name: 'Image', required: false, description: 'The preview image, displayed as a square with cover fit.'},
|
|
86
93
|
{name: 'Placeholder', required: false, description: 'An image silhouette icon shown when no src is provided.'},
|
|
87
|
-
{name: 'Remove button', required: false, description: 'An overlaid close button in the top-right corner. Appears when onRemove is set.
|
|
94
|
+
{name: 'Remove button', required: false, description: 'An overlaid close button in the top-right corner. Appears when onRemove is set. Sits on a fixed --color-overlay scrim with an --color-on-dark icon to stay visible on any image.'},
|
|
88
95
|
{name: 'Upload overlay', required: false, description: 'A semi-transparent overlay with a spinner, shown when isLoading is true and a src preview is available.'},
|
|
89
96
|
{name: 'Skeleton', required: false, description: 'A shimmer animation shown when isLoading is true and no src is set.'},
|
|
90
97
|
],
|
|
@@ -95,12 +102,13 @@ export const docs = {
|
|
|
95
102
|
export const docsZh = {
|
|
96
103
|
propDescriptions: {
|
|
97
104
|
src: '\u56FE\u7247\u6E90 URL\u3002',
|
|
98
|
-
alt: '\u56FE\u7247\u7684\u66FF\u4EE3\u6587\u672C\u3002',
|
|
105
|
+
alt: '\u56FE\u7247\u7684\u66FF\u4EE3\u6587\u672C\u3002\u7701\u7565\u65F6\u56FE\u7247\u4F1A\u88AB\u663E\u5F0F\u6807\u8BB0\u4E3A\u88C5\u9970\u6027\uFF08alt=""\u3001role="presentation"\u3001aria-hidden\uFF09\u5E76\u5BF9\u5C4F\u5E55\u9605\u8BFB\u5668\u9690\u85CF\uFF1B\u82E5 alt \u548C label \u5747\u672A\u8BBE\u7F6E\uFF0C\u5F00\u53D1\u73AF\u5883\u4F1A\u53D1\u51FA\u8B66\u544A\u3002',
|
|
99
106
|
label: '\u65E0\u969C\u788D\u6807\u7B7E\uFF08\u5982\u6587\u4EF6\u540D\uFF09\u3002\u60AC\u505C\u65F6\u4EE5\u63D0\u793A\u5DE5\u5177\u663E\u793A\u3002',
|
|
100
107
|
onRemove: '\u8986\u76D6\u5C42\u79FB\u9664\u6309\u94AE\u7684\u56DE\u8C03\u3002',
|
|
101
|
-
onClick: '\u70B9\u51FB\u5904\u7406\u5668\u3002\u6DFB\u52A0\u6309\u94AE\u8BED\u4E49\u548C\u60AC\u505C\
|
|
108
|
+
onClick: '\u70B9\u51FB\u5904\u7406\u5668\u3002\u6DFB\u52A0\u6309\u94AE\u8BED\u4E49\u548C\u60AC\u505C\u8986\u76D6\u5C42\u3002',
|
|
102
109
|
isLoading: '\u663E\u793A\u9AA8\u67B6\u5C4F\uFF08\u65E0 src\uFF09\u6216\u4E0A\u4F20\u8986\u76D6\u5C42\uFF08\u6709 src\uFF09\u3002',
|
|
103
110
|
isDisabled: '\u662F\u5426\u7981\u7528\u7F29\u7565\u56FE\u3002',
|
|
111
|
+
showRemoveOn: '\u4F55\u65F6\u663E\u793A\u79FB\u9664\u6309\u94AE\uFF1Ahover\uFF08\u9ED8\u8BA4\uFF0C\u60AC\u505C\u65F6\u4EE5\u53CA\u952E\u76D8\u805A\u7126\u65F6\u663E\u793A\uFF0C\u89E6\u6478\u8BBE\u5907\u4E0A\u4FDD\u6301\u53EF\u89C1\uFF09| always\uFF08\u59CB\u7EC8\u663E\u793A\uFF09\u3002\u4EC5\u5728\u8BBE\u7F6E onRemove \u65F6\u751F\u6548\u3002',
|
|
104
112
|
xstyle: '\u7528\u4E8E\u5E03\u5C40\u81EA\u5B9A\u4E49\u7684 StyleX \u6837\u5F0F\u3002\u5FC5\u987B\u662F stylex.create() \u7684\u503C\uFF0C\u800C\u975E\u5185\u8054\u6837\u5F0F\u5BF9\u8C61\u3002',
|
|
105
113
|
className: '\u6839\u5143\u7D20\u7684 CSS \u7C7B\u540D\u3002\u5EFA\u8BAE\u4F7F\u7528 xstyle\u3002',
|
|
106
114
|
style: '\u6839\u5143\u7D20\u7684\u5185\u8054\u6837\u5F0F\u3002\u5EFA\u8BAE\u4F7F\u7528 xstyle\u3002',
|
|
@@ -112,7 +120,7 @@ export const docsZh = {
|
|
|
112
120
|
bestPractices: [
|
|
113
121
|
{guidance: true, description: '\u59CB\u7EC8\u63D0\u4F9B label \u5C5E\u6027\u5E76\u586B\u5199\u6587\u4EF6\u540D\uFF0C\u4EE5\u4FBF\u5C4F\u5E55\u9605\u8BFB\u5668\u80FD\u591F\u8BC6\u522B\u7F29\u7565\u56FE\u53CA\u5176\u79FB\u9664\u6309\u94AE\uFF0C\u5E76\u5728\u60AC\u505C\u65F6\u663E\u793A\u63D0\u793A\u3002'},
|
|
114
122
|
{guidance: true, description: '\u4E0A\u4F20\u521D\u671F\u4F7F\u7528\u4E0D\u5E26 src \u7684 isLoading \u663E\u793A\u9AA8\u67B6\u5C4F\uFF1B\u83B7\u5F97\u9884\u89C8 URL \u540E\u4F7F\u7528\u5E26 src \u7684 isLoading \u663E\u793A\u65CB\u8F6C\u52A0\u8F7D\u8986\u76D6\u5C42\u3002'},
|
|
115
|
-
{guidance: true, description: '\u5C06 onClick \u4E0E\u706F\u7BB1\u6216\u8BE6\u60C5\u89C6\u56FE\u914D\u5BF9\uFF0C\u4EE5\u4FBF\u7528\u6237\u67E5\u770B\u5B8C\u6574\u56FE\u7247\u2014\u2014\u7EC4\u4EF6\u4F1A\u81EA\u52A8\u6DFB\u52A0\u6309\u94AE\u8BED\u4E49\u548C\u60AC\u505C\
|
|
123
|
+
{guidance: true, description: '\u5C06 onClick \u4E0E\u706F\u7BB1\u6216\u8BE6\u60C5\u89C6\u56FE\u914D\u5BF9\uFF0C\u4EE5\u4FBF\u7528\u6237\u67E5\u770B\u5B8C\u6574\u56FE\u7247\u2014\u2014\u7EC4\u4EF6\u4F1A\u81EA\u52A8\u6DFB\u52A0\u6309\u94AE\u8BED\u4E49\u548C\u60AC\u505C\u8986\u76D6\u5C42\u3002'},
|
|
116
124
|
{guidance: false, description: '\u5BF9 PDF \u6216\u7535\u5B50\u8868\u683C\u7B49\u975E\u56FE\u7247\u6587\u4EF6\u7C7B\u578B\u4F7F\u7528 Thumbnail\u2014\u2014\u5E94\u4F7F\u7528\u5E26\u6709\u76F8\u5E94\u56FE\u6807\u7684\u6587\u4EF6\u9644\u4EF6\u7EC4\u4EF6\u3002'},
|
|
117
125
|
{guidance: false, description: '\u63D0\u4F9B src \u65F6\u7701\u7565 alt \u6587\u672C\u2014\u2014\u5C4F\u5E55\u9605\u8BFB\u5668\u9700\u8981\u56FE\u7247\u5185\u5BB9\u7684\u63CF\u8FF0\uFF0C\u800C\u4E0D\u4EC5\u662F label \u4E2D\u7684\u6587\u4EF6\u540D\u3002'},
|
|
118
126
|
],
|
|
@@ -128,19 +136,20 @@ export const docsDense = {
|
|
|
128
136
|
bestPractices: [
|
|
129
137
|
{guidance: true, description: 'Always set label (file name) for a11y; powers screen reader announce + hover tooltip.'},
|
|
130
138
|
{guidance: true, description: 'isLoading w/o src \u2192 skeleton; isLoading w/ src \u2192 spinner overlay. Two distinct loading states.'},
|
|
131
|
-
{guidance: true, description: 'onClick adds button semantics + hover
|
|
139
|
+
{guidance: true, description: 'onClick adds button semantics + hover overlay; pair with lightbox for full preview.'},
|
|
132
140
|
{guidance: false, description: "Don't use for non-image files (PDF, xlsx); use file attachment component with icon instead."},
|
|
133
141
|
{guidance: false, description: "Don't omit alt when src present; screen readers need image content description, not just label."},
|
|
134
142
|
],
|
|
135
143
|
},
|
|
136
144
|
propDescriptions: {
|
|
137
145
|
src: 'Image source URL.',
|
|
138
|
-
alt: 'Alt text for image.',
|
|
146
|
+
alt: 'Alt text for image. Omitted → explicitly decorative (alt="" + role="presentation" + aria-hidden); dev warn when src set with no alt and no label.',
|
|
139
147
|
label: 'Accessible label (file name). Tooltip on hover, aria-label.',
|
|
140
148
|
onRemove: '(e) => void. Overlaid remove button callback.',
|
|
141
|
-
onClick: '(e) => void. Adds button semantics + hover
|
|
149
|
+
onClick: '(e) => void. Adds button semantics + hover overlay.',
|
|
142
150
|
isLoading: 'Skeleton (no src) or upload overlay (with src). Default: false.',
|
|
143
151
|
isDisabled: 'Disabled state. Default: false.',
|
|
152
|
+
showRemoveOn: "When remove button shows: hover (default — reveal on hover/focus, stays visible on touch) | always. Only when onRemove set.",
|
|
144
153
|
xstyle: 'stylex.create() for layout.',
|
|
145
154
|
className: 'CSS class. Prefer xstyle.',
|
|
146
155
|
style: 'Inline styles. Prefer xstyle.',
|