@eocrm/design-system 0.0.0-stage → 0.6.18
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/AI-PRIMER.md +341 -0
- package/LICENSE +202 -0
- package/README.md +266 -2
- package/docs/components/Accordion.md +114 -0
- package/docs/components/AgentAvatar.md +58 -0
- package/docs/components/Alert.md +81 -0
- package/docs/components/AppLayout.md +70 -0
- package/docs/components/Avatar.md +49 -0
- package/docs/components/AvatarGroup.md +47 -0
- package/docs/components/Badge.md +60 -0
- package/docs/components/Banner.md +89 -0
- package/docs/components/BrandIcon.md +32 -0
- package/docs/components/Breadcrumb.md +72 -0
- package/docs/components/Button.md +107 -0
- package/docs/components/ButtonGroup.md +78 -0
- package/docs/components/Calendar.md +158 -0
- package/docs/components/Card.md +165 -0
- package/docs/components/CatalogPicker.md +83 -0
- package/docs/components/Chart.md +114 -0
- package/docs/components/ChatBubble.md +55 -0
- package/docs/components/ChatLauncher.md +97 -0
- package/docs/components/Checkbox.md +55 -0
- package/docs/components/CircularProgress.md +53 -0
- package/docs/components/Cluster.md +96 -0
- package/docs/components/Code.md +35 -0
- package/docs/components/CodeBlock.md +67 -0
- package/docs/components/ColorPicker.md +115 -0
- package/docs/components/ConfirmationPopover.md +70 -0
- package/docs/components/Constrain.md +39 -0
- package/docs/components/CurrencySelect.md +57 -0
- package/docs/components/CursorPagination.md +43 -0
- package/docs/components/DashboardCanvas.md +79 -0
- package/docs/components/DashboardWidget.md +131 -0
- package/docs/components/DataTable.md +88 -0
- package/docs/components/DatePicker.md +68 -0
- package/docs/components/DateRangePicker.md +71 -0
- package/docs/components/DateStrip.md +56 -0
- package/docs/components/DefinitionList.md +82 -0
- package/docs/components/Divider.md +57 -0
- package/docs/components/Dot.md +26 -0
- package/docs/components/Drawer.md +94 -0
- package/docs/components/DropdownMenu.md +299 -0
- package/docs/components/EmojiPicker.md +84 -0
- package/docs/components/EmptyState.md +55 -0
- package/docs/components/EntityChip.md +102 -0
- package/docs/components/ErrorState.md +72 -0
- package/docs/components/Field.md +91 -0
- package/docs/components/FileUpload.md +109 -0
- package/docs/components/FilterChip.md +88 -0
- package/docs/components/FlowCanvas.md +108 -0
- package/docs/components/FormRow.md +31 -0
- package/docs/components/FormSection.md +37 -0
- package/docs/components/Grid.md +103 -0
- package/docs/components/Highlight.md +75 -0
- package/docs/components/HighlightedText.md +50 -0
- package/docs/components/IconPicker.md +134 -0
- package/docs/components/IconTile.md +30 -0
- package/docs/components/Image.md +84 -0
- package/docs/components/ImageCrop.md +163 -0
- package/docs/components/Indent.md +31 -0
- package/docs/components/InlineDatePicker.md +58 -0
- package/docs/components/InlineDateRangePicker.md +57 -0
- package/docs/components/Input.md +54 -0
- package/docs/components/Kanban.md +122 -0
- package/docs/components/Kbd.md +41 -0
- package/docs/components/Lightbox.md +105 -0
- package/docs/components/Link.md +65 -0
- package/docs/components/LinkCard.md +41 -0
- package/docs/components/LiquidEditor.md +84 -0
- package/docs/components/List.md +68 -0
- package/docs/components/LiveRegion.md +29 -0
- package/docs/components/LocaleProvider.md +25 -0
- package/docs/components/Logo.md +41 -0
- package/docs/components/Masonry.md +48 -0
- package/docs/components/MediaTile.md +95 -0
- package/docs/components/Modal.md +107 -0
- package/docs/components/MoneyInput.md +62 -0
- package/docs/components/OptionsPicker.md +123 -0
- package/docs/components/OtpInput.md +65 -0
- package/docs/components/Page.md +35 -0
- package/docs/components/PageHeader.md +133 -0
- package/docs/components/Pagination.md +44 -0
- package/docs/components/Palette.md +32 -0
- package/docs/components/PasswordInput.md +45 -0
- package/docs/components/PasswordStrengthMeter.md +27 -0
- package/docs/components/PersonDisplay.md +153 -0
- package/docs/components/PhoneInput.md +54 -0
- package/docs/components/PillMenu.md +91 -0
- package/docs/components/Popover.md +127 -0
- package/docs/components/Progress.md +56 -0
- package/docs/components/QrCode.md +34 -0
- package/docs/components/Radio.md +37 -0
- package/docs/components/RadioGroup.md +56 -0
- package/docs/components/Rail.md +191 -0
- package/docs/components/RelativeDateInput.md +114 -0
- package/docs/components/RichText.md +44 -0
- package/docs/components/RichTextEditor.md +112 -0
- package/docs/components/Screen.md +37 -0
- package/docs/components/ScrollArea.md +39 -0
- package/docs/components/Select.md +131 -0
- package/docs/components/SettingRow.md +98 -0
- package/docs/components/Skeleton.md +68 -0
- package/docs/components/Slider.md +92 -0
- package/docs/components/SlotGrid.md +55 -0
- package/docs/components/SocialButton.md +31 -0
- package/docs/components/Sortable.md +127 -0
- package/docs/components/SortableGroup.md +52 -0
- package/docs/components/Sparkline.md +51 -0
- package/docs/components/Split.md +76 -0
- package/docs/components/Stack.md +59 -0
- package/docs/components/StagePath.md +66 -0
- package/docs/components/StatGroup.md +61 -0
- package/docs/components/StatTile.md +58 -0
- package/docs/components/Sticky.md +69 -0
- package/docs/components/Switch.md +89 -0
- package/docs/components/Table.md +184 -0
- package/docs/components/TableOfContents.md +76 -0
- package/docs/components/Tabs.md +94 -0
- package/docs/components/Text.md +63 -0
- package/docs/components/Textarea.md +59 -0
- package/docs/components/Thread.md +52 -0
- package/docs/components/TimeField.md +70 -0
- package/docs/components/Timeline.md +57 -0
- package/docs/components/Title.md +54 -0
- package/docs/components/ToastViewport.md +61 -0
- package/docs/components/Tooltip.md +63 -0
- package/docs/components/TopBar.md +214 -0
- package/docs/components/Tour.md +85 -0
- package/docs/components/TreeView.md +113 -0
- package/docs/components/VisuallyHidden.md +43 -0
- package/docs/components/WidgetPreview.md +54 -0
- package/docs/components/useBelowBreakpoint.md +11 -0
- package/docs/components/useMonth.md +18 -0
- package/docs/setup.md +51 -0
- package/docs/theming.md +95 -0
- package/docs/tokens.md +123 -0
- package/docs/transient-state.md +56 -0
- package/package.json +86 -4
- package/src/_meta/manifest.ts +293 -0
- package/src/app/AppProvider.tsx +78 -0
- package/src/app/index.ts +3 -0
- package/src/app/themeTokens.ts +95 -0
- package/src/calendar/dateMath.ts +114 -0
- package/src/calendar/formatters.ts +75 -0
- package/src/calendar/index.ts +39 -0
- package/src/calendar/types.ts +36 -0
- package/src/calendar/useAgenda.ts +70 -0
- package/src/calendar/useDay.ts +51 -0
- package/src/calendar/useMonth.ts +82 -0
- package/src/calendar/useWeek.ts +62 -0
- package/src/calendar/weekInfo.ts +83 -0
- package/src/components/Accordion/Accordion.module.scss +304 -0
- package/src/components/Accordion/Accordion.tokens.scss +64 -0
- package/src/components/Accordion/Accordion.tsx +272 -0
- package/src/components/Accordion/AccordionContent.tsx +36 -0
- package/src/components/Accordion/AccordionItem.tsx +66 -0
- package/src/components/Accordion/AccordionTrigger.tsx +121 -0
- package/src/components/Accordion/context.ts +47 -0
- package/src/components/Accordion/index.ts +14 -0
- package/src/components/Alert/Alert.module.scss +92 -0
- package/src/components/Alert/Alert.tokens.scss +60 -0
- package/src/components/Alert/Alert.tsx +136 -0
- package/src/components/Alert/index.ts +2 -0
- package/src/components/AppLayout/AppLayout.module.scss +130 -0
- package/src/components/AppLayout/AppLayout.tokens.scss +27 -0
- package/src/components/AppLayout/AppLayout.tsx +211 -0
- package/src/components/AppLayout/index.ts +2 -0
- package/src/components/Avatar/AgentAvatar.module.scss +117 -0
- package/src/components/Avatar/AgentAvatar.tsx +122 -0
- package/src/components/Avatar/Avatar.module.scss +181 -0
- package/src/components/Avatar/Avatar.tokens.scss +107 -0
- package/src/components/Avatar/Avatar.tsx +210 -0
- package/src/components/Avatar/AvatarGroup.module.scss +128 -0
- package/src/components/Avatar/AvatarGroup.tsx +119 -0
- package/src/components/Avatar/AvatarGroupContext.tsx +20 -0
- package/src/components/Avatar/index.ts +6 -0
- package/src/components/Badge/Badge.module.scss +124 -0
- package/src/components/Badge/Badge.tokens.scss +74 -0
- package/src/components/Badge/Badge.tsx +164 -0
- package/src/components/Badge/index.ts +2 -0
- package/src/components/Banner/Banner.module.scss +73 -0
- package/src/components/Banner/Banner.tokens.scss +51 -0
- package/src/components/Banner/Banner.tsx +138 -0
- package/src/components/Banner/index.ts +2 -0
- package/src/components/BrandIcon/BrandIcon.module.scss +5 -0
- package/src/components/BrandIcon/BrandIcon.tsx +99 -0
- package/src/components/BrandIcon/index.ts +2 -0
- package/src/components/Breadcrumb/Breadcrumb.module.scss +32 -0
- package/src/components/Breadcrumb/Breadcrumb.tokens.scss +9 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +146 -0
- package/src/components/Breadcrumb/index.ts +2 -0
- package/src/components/Button/Button.module.scss +167 -0
- package/src/components/Button/Button.tokens.scss +90 -0
- package/src/components/Button/Button.tsx +205 -0
- package/src/components/Button/index.ts +2 -0
- package/src/components/ButtonGroup/ButtonGroup.module.scss +134 -0
- package/src/components/ButtonGroup/ButtonGroup.tokens.scss +42 -0
- package/src/components/ButtonGroup/ButtonGroup.tsx +278 -0
- package/src/components/ButtonGroup/ButtonGroupItem.tsx +74 -0
- package/src/components/ButtonGroup/context.ts +45 -0
- package/src/components/ButtonGroup/index.ts +2 -0
- package/src/components/Calendar/AgendaView.module.scss +231 -0
- package/src/components/Calendar/AgendaView.tsx +214 -0
- package/src/components/Calendar/AllDayBand.module.scss +18 -0
- package/src/components/Calendar/AllDayBand.tsx +75 -0
- package/src/components/Calendar/Calendar.module.scss +23 -0
- package/src/components/Calendar/Calendar.tokens.scss +262 -0
- package/src/components/Calendar/Calendar.tsx +370 -0
- package/src/components/Calendar/DayCell.module.scss +30 -0
- package/src/components/Calendar/DayCell.tsx +50 -0
- package/src/components/Calendar/DayView.module.scss +10 -0
- package/src/components/Calendar/DayView.tsx +163 -0
- package/src/components/Calendar/EventChip.module.scss +171 -0
- package/src/components/Calendar/EventChip.tsx +115 -0
- package/src/components/Calendar/HourGrid.module.scss +123 -0
- package/src/components/Calendar/HourGrid.tsx +381 -0
- package/src/components/Calendar/MonthView.module.scss +99 -0
- package/src/components/Calendar/MonthView.tsx +296 -0
- package/src/components/Calendar/TimedEvent.module.scss +205 -0
- package/src/components/Calendar/TimedEvent.tsx +247 -0
- package/src/components/Calendar/ViewSwitcher.module.scss +3 -0
- package/src/components/Calendar/ViewSwitcher.tsx +47 -0
- package/src/components/Calendar/WeekView.module.scss +10 -0
- package/src/components/Calendar/WeekView.tsx +137 -0
- package/src/components/Calendar/eventColor.ts +60 -0
- package/src/components/Calendar/index.ts +18 -0
- package/src/components/Calendar/types.ts +451 -0
- package/src/components/Calendar/useEventDrag.ts +783 -0
- package/src/components/Calendar/utils.ts +622 -0
- package/src/components/Card/Card.module.scss +264 -0
- package/src/components/Card/Card.tokens.scss +55 -0
- package/src/components/Card/Card.tsx +170 -0
- package/src/components/Card/CardBody.tsx +45 -0
- package/src/components/Card/CardHeader.tsx +113 -0
- package/src/components/Card/CardList.tsx +24 -0
- package/src/components/Card/CardListRow.tsx +24 -0
- package/src/components/Card/index.ts +7 -0
- package/src/components/CatalogPicker/CatalogPicker.module.scss +193 -0
- package/src/components/CatalogPicker/CatalogPicker.tokens.scss +26 -0
- package/src/components/CatalogPicker/CatalogPicker.tsx +339 -0
- package/src/components/CatalogPicker/index.ts +2 -0
- package/src/components/Chart/Chart.module.scss +287 -0
- package/src/components/Chart/Chart.tokens.scss +63 -0
- package/src/components/Chart/Chart.tsx +607 -0
- package/src/components/Chart/ChartLegend.tsx +99 -0
- package/src/components/Chart/ChartTable.tsx +62 -0
- package/src/components/Chart/ChartTooltip.tsx +91 -0
- package/src/components/Chart/chartModel.ts +689 -0
- package/src/components/Chart/index.ts +2 -0
- package/src/components/ChatBubble/ChatBubble.module.scss +93 -0
- package/src/components/ChatBubble/ChatBubble.tokens.scss +17 -0
- package/src/components/ChatBubble/ChatBubble.tsx +61 -0
- package/src/components/ChatBubble/ChatBubbleList.tsx +27 -0
- package/src/components/ChatBubble/index.ts +3 -0
- package/src/components/ChatLauncher/ChatLauncher.module.scss +68 -0
- package/src/components/ChatLauncher/ChatLauncher.tokens.scss +27 -0
- package/src/components/ChatLauncher/ChatLauncher.tsx +202 -0
- package/src/components/ChatLauncher/index.ts +2 -0
- package/src/components/ChatLauncher/isAtBottom.ts +12 -0
- package/src/components/Checkbox/Checkbox.module.scss +147 -0
- package/src/components/Checkbox/Checkbox.tokens.scss +44 -0
- package/src/components/Checkbox/Checkbox.tsx +188 -0
- package/src/components/Checkbox/index.ts +2 -0
- package/src/components/CircularProgress/CircularProgress.module.scss +133 -0
- package/src/components/CircularProgress/CircularProgress.tokens.scss +40 -0
- package/src/components/CircularProgress/CircularProgress.tsx +139 -0
- package/src/components/CircularProgress/index.ts +7 -0
- package/src/components/Cluster/Cluster.module.scss +145 -0
- package/src/components/Cluster/Cluster.tokens.scss +11 -0
- package/src/components/Cluster/Cluster.tsx +215 -0
- package/src/components/Cluster/index.ts +2 -0
- package/src/components/Code/Code.module.scss +28 -0
- package/src/components/Code/Code.tokens.scss +15 -0
- package/src/components/Code/Code.tsx +44 -0
- package/src/components/Code/index.ts +2 -0
- package/src/components/CodeBlock/CodeBlock.module.scss +146 -0
- package/src/components/CodeBlock/CodeBlock.tokens.scss +27 -0
- package/src/components/CodeBlock/CodeBlock.tsx +274 -0
- package/src/components/CodeBlock/highlight.ts +179 -0
- package/src/components/CodeBlock/index.ts +8 -0
- package/src/components/CodeBlock/sampleSync.ts +42 -0
- package/src/components/ColorPicker/ColorPicker.module.scss +286 -0
- package/src/components/ColorPicker/ColorPicker.tokens.scss +60 -0
- package/src/components/ColorPicker/ColorPicker.tsx +367 -0
- package/src/components/ColorPicker/ColorPickerPanel.tsx +265 -0
- package/src/components/ColorPicker/SVSquare.tsx +189 -0
- package/src/components/ColorPicker/colorMath.ts +141 -0
- package/src/components/ColorPicker/index.ts +6 -0
- package/src/components/ConfirmationPopover/ConfirmationPopover.module.scss +39 -0
- package/src/components/ConfirmationPopover/ConfirmationPopover.tokens.scss +13 -0
- package/src/components/ConfirmationPopover/ConfirmationPopover.tsx +395 -0
- package/src/components/ConfirmationPopover/index.ts +2 -0
- package/src/components/Constrain/Constrain.module.scss +99 -0
- package/src/components/Constrain/Constrain.tsx +79 -0
- package/src/components/Constrain/index.ts +2 -0
- package/src/components/CurrencySelect/CurrencySelect.module.scss +7 -0
- package/src/components/CurrencySelect/CurrencySelect.tsx +167 -0
- package/src/components/CurrencySelect/index.ts +3 -0
- package/src/components/CursorPagination/CursorPagination.module.scss +69 -0
- package/src/components/CursorPagination/CursorPagination.tokens.scss +32 -0
- package/src/components/CursorPagination/CursorPagination.tsx +121 -0
- package/src/components/CursorPagination/index.ts +2 -0
- package/src/components/DashboardCanvas/DashboardCanvas.module.scss +360 -0
- package/src/components/DashboardCanvas/DashboardCanvas.tokens.scss +48 -0
- package/src/components/DashboardCanvas/DashboardCanvas.tsx +1270 -0
- package/src/components/DashboardCanvas/DashboardCanvasItem.tsx +140 -0
- package/src/components/DashboardCanvas/DashboardCanvasSection.tsx +174 -0
- package/src/components/DashboardCanvas/engine.ts +363 -0
- package/src/components/DashboardCanvas/index.ts +9 -0
- package/src/components/DashboardWidget/DashboardWidget.module.scss +100 -0
- package/src/components/DashboardWidget/DashboardWidget.tokens.scss +16 -0
- package/src/components/DashboardWidget/DashboardWidget.tsx +188 -0
- package/src/components/DashboardWidget/index.ts +7 -0
- package/src/components/DataTable/BodyRow.tsx +197 -0
- package/src/components/DataTable/ColumnVisibilityTrigger.module.scss +7 -0
- package/src/components/DataTable/ColumnVisibilityTrigger.tsx +105 -0
- package/src/components/DataTable/DataTable.module.scss +511 -0
- package/src/components/DataTable/DataTable.tokens.scss +80 -0
- package/src/components/DataTable/DataTable.tsx +734 -0
- package/src/components/DataTable/HeaderCell.module.scss +215 -0
- package/src/components/DataTable/HeaderCell.tsx +440 -0
- package/src/components/DataTable/columnShift.ts +117 -0
- package/src/components/DataTable/index.ts +23 -0
- package/src/components/DataTable/pinStyle.ts +47 -0
- package/src/components/DataTable/reorderColumns.ts +66 -0
- package/src/components/DataTable/types.ts +289 -0
- package/src/components/DataTable/useColumnDragShift.ts +216 -0
- package/src/components/DataTable/useDataTable.ts +372 -0
- package/src/components/DataTable/useResizeHandle.ts +97 -0
- package/src/components/DatePicker/DatePicker.module.scss +180 -0
- package/src/components/DatePicker/DatePicker.tokens.scss +152 -0
- package/src/components/DatePicker/DatePicker.tsx +664 -0
- package/src/components/DatePicker/DatePickerGrid.module.scss +172 -0
- package/src/components/DatePicker/DatePickerGrid.tsx +341 -0
- package/src/components/DatePicker/InlineDatePicker.module.scss +32 -0
- package/src/components/DatePicker/InlineDatePicker.tsx +201 -0
- package/src/components/DatePicker/index.ts +4 -0
- package/src/components/DatePicker/utils.ts +364 -0
- package/src/components/DateRangePicker/DateRangePicker.module.scss +237 -0
- package/src/components/DateRangePicker/DateRangePicker.tokens.scss +78 -0
- package/src/components/DateRangePicker/DateRangePicker.tsx +720 -0
- package/src/components/DateRangePicker/InlineDateRangePicker.module.scss +94 -0
- package/src/components/DateRangePicker/InlineDateRangePicker.tsx +376 -0
- package/src/components/DateRangePicker/index.ts +5 -0
- package/src/components/DateRangePicker/utils.ts +151 -0
- package/src/components/DateStrip/DateStrip.module.scss +78 -0
- package/src/components/DateStrip/DateStrip.tokens.scss +23 -0
- package/src/components/DateStrip/DateStrip.tsx +205 -0
- package/src/components/DateStrip/index.ts +2 -0
- package/src/components/DefinitionList/DefinitionList.module.scss +102 -0
- package/src/components/DefinitionList/DefinitionList.tokens.scss +29 -0
- package/src/components/DefinitionList/DefinitionList.tsx +198 -0
- package/src/components/DefinitionList/index.ts +9 -0
- package/src/components/Divider/Divider.module.scss +144 -0
- package/src/components/Divider/Divider.tokens.scss +21 -0
- package/src/components/Divider/Divider.tsx +103 -0
- package/src/components/Divider/index.ts +2 -0
- package/src/components/Dot/Dot.module.scss +40 -0
- package/src/components/Dot/Dot.tokens.scss +4 -0
- package/src/components/Dot/Dot.tsx +45 -0
- package/src/components/Dot/index.ts +2 -0
- package/src/components/Drawer/Body.tsx +23 -0
- package/src/components/Drawer/Close.tsx +35 -0
- package/src/components/Drawer/Content.tsx +93 -0
- package/src/components/Drawer/Drawer.module.scss +232 -0
- package/src/components/Drawer/Drawer.tokens.scss +38 -0
- package/src/components/Drawer/Drawer.tsx +23 -0
- package/src/components/Drawer/DrawerRoot.tsx +190 -0
- package/src/components/Drawer/Footer.tsx +24 -0
- package/src/components/Drawer/Header.tsx +64 -0
- package/src/components/Drawer/Overlay.tsx +82 -0
- package/src/components/Drawer/context.ts +44 -0
- package/src/components/Drawer/index.ts +12 -0
- package/src/components/Drawer/useDragToClose.ts +149 -0
- package/src/components/DropdownMenu/CheckboxItem.tsx +144 -0
- package/src/components/DropdownMenu/Content.tsx +419 -0
- package/src/components/DropdownMenu/DropdownMenu.module.scss +280 -0
- package/src/components/DropdownMenu/DropdownMenu.tokens.scss +88 -0
- package/src/components/DropdownMenu/DropdownMenu.tsx +43 -0
- package/src/components/DropdownMenu/Group.tsx +76 -0
- package/src/components/DropdownMenu/Item.tsx +148 -0
- package/src/components/DropdownMenu/ItemIndicator.tsx +30 -0
- package/src/components/DropdownMenu/Radio.tsx +178 -0
- package/src/components/DropdownMenu/Root.tsx +100 -0
- package/src/components/DropdownMenu/Sub.tsx +332 -0
- package/src/components/DropdownMenu/Trigger.tsx +76 -0
- package/src/components/DropdownMenu/context.ts +65 -0
- package/src/components/DropdownMenu/index.ts +20 -0
- package/src/components/EmojiPicker/EmojiPicker.module.scss +84 -0
- package/src/components/EmojiPicker/EmojiPicker.tokens.scss +24 -0
- package/src/components/EmojiPicker/EmojiPicker.tsx +341 -0
- package/src/components/EmojiPicker/emojiData.ts +245 -0
- package/src/components/EmojiPicker/index.ts +3 -0
- package/src/components/EmptyState/EmptyState.module.scss +102 -0
- package/src/components/EmptyState/EmptyState.tokens.scss +28 -0
- package/src/components/EmptyState/EmptyState.tsx +112 -0
- package/src/components/EmptyState/index.ts +7 -0
- package/src/components/EntityChip/EntityChip.module.scss +275 -0
- package/src/components/EntityChip/EntityChip.tokens.scss +66 -0
- package/src/components/EntityChip/EntityChip.tsx +649 -0
- package/src/components/EntityChip/index.ts +10 -0
- package/src/components/ErrorState/ErrorState.module.scss +105 -0
- package/src/components/ErrorState/ErrorState.tokens.scss +32 -0
- package/src/components/ErrorState/ErrorState.tsx +125 -0
- package/src/components/ErrorState/index.ts +8 -0
- package/src/components/Field/Field.module.scss +46 -0
- package/src/components/Field/Field.tsx +185 -0
- package/src/components/Field/index.ts +2 -0
- package/src/components/FileUpload/FileUpload.module.scss +187 -0
- package/src/components/FileUpload/FileUpload.tokens.scss +81 -0
- package/src/components/FileUpload/FileUpload.tsx +569 -0
- package/src/components/FileUpload/formatBytes.ts +34 -0
- package/src/components/FileUpload/iconForFile.ts +40 -0
- package/src/components/FileUpload/index.ts +2 -0
- package/src/components/FilterChip/FilterChip.module.scss +61 -0
- package/src/components/FilterChip/FilterChip.tokens.scss +25 -0
- package/src/components/FilterChip/FilterChip.tsx +208 -0
- package/src/components/FilterChip/index.ts +5 -0
- package/src/components/FlowCanvas/FlowCanvas.module.scss +329 -0
- package/src/components/FlowCanvas/FlowCanvas.tokens.scss +45 -0
- package/src/components/FlowCanvas/FlowCanvas.tsx +1867 -0
- package/src/components/FlowCanvas/FlowControls.tsx +46 -0
- package/src/components/FlowCanvas/FlowEdge.tsx +58 -0
- package/src/components/FlowCanvas/FlowNode.tsx +76 -0
- package/src/components/FlowCanvas/edgePath.ts +85 -0
- package/src/components/FlowCanvas/index.ts +4 -0
- package/src/components/FlowCanvas/layout.ts +148 -0
- package/src/components/FlowCanvas/spatialNav.ts +76 -0
- package/src/components/FlowCanvas/types.ts +59 -0
- package/src/components/FlowCanvas/useViewport.ts +122 -0
- package/src/components/FormRow/FormRow.module.scss +2 -0
- package/src/components/FormRow/FormRow.tsx +37 -0
- package/src/components/FormRow/index.ts +2 -0
- package/src/components/FormSection/FormSection.module.scss +24 -0
- package/src/components/FormSection/FormSection.tsx +46 -0
- package/src/components/FormSection/index.ts +2 -0
- package/src/components/Grid/Grid.module.scss +162 -0
- package/src/components/Grid/Grid.tokens.scss +13 -0
- package/src/components/Grid/Grid.tsx +226 -0
- package/src/components/Grid/GridItem.tsx +77 -0
- package/src/components/Grid/index.ts +11 -0
- package/src/components/Highlight/Highlight.module.scss +43 -0
- package/src/components/Highlight/Highlight.tokens.scss +35 -0
- package/src/components/Highlight/Highlight.tsx +164 -0
- package/src/components/Highlight/HighlightOverlay.tsx +100 -0
- package/src/components/Highlight/index.ts +2 -0
- package/src/components/HighlightedText/HighlightedText.module.scss +11 -0
- package/src/components/HighlightedText/HighlightedText.tokens.scss +9 -0
- package/src/components/HighlightedText/HighlightedText.tsx +50 -0
- package/src/components/HighlightedText/highlightRanges.ts +44 -0
- package/src/components/HighlightedText/index.ts +2 -0
- package/src/components/IconPicker/IconPicker.module.scss +175 -0
- package/src/components/IconPicker/IconPicker.tokens.scss +40 -0
- package/src/components/IconPicker/IconPicker.tsx +629 -0
- package/src/components/IconPicker/index.ts +9 -0
- package/src/components/IconTile/IconTile.module.scss +57 -0
- package/src/components/IconTile/IconTile.tokens.scss +16 -0
- package/src/components/IconTile/IconTile.tsx +91 -0
- package/src/components/IconTile/index.ts +2 -0
- package/src/components/Image/Image.module.scss +266 -0
- package/src/components/Image/Image.tokens.scss +55 -0
- package/src/components/Image/Image.tsx +342 -0
- package/src/components/Image/index.ts +2 -0
- package/src/components/ImageCrop/ImageCrop.module.scss +274 -0
- package/src/components/ImageCrop/ImageCrop.tokens.scss +33 -0
- package/src/components/ImageCrop/ImageCrop.tsx +542 -0
- package/src/components/ImageCrop/cropGeometry.ts +120 -0
- package/src/components/ImageCrop/extractCropBlob.ts +140 -0
- package/src/components/ImageCrop/index.ts +11 -0
- package/src/components/ImageCrop/useCropPreview.ts +161 -0
- package/src/components/Indent/Indent.module.scss +33 -0
- package/src/components/Indent/Indent.tokens.scss +10 -0
- package/src/components/Indent/Indent.tsx +46 -0
- package/src/components/Indent/index.ts +2 -0
- package/src/components/Input/Input.module.scss +99 -0
- package/src/components/Input/Input.tokens.scss +54 -0
- package/src/components/Input/Input.tsx +105 -0
- package/src/components/Input/Suggestions.tsx +260 -0
- package/src/components/Input/index.ts +2 -0
- package/src/components/Kanban/Kanban.module.scss +39 -0
- package/src/components/Kanban/Kanban.tokens.scss +15 -0
- package/src/components/Kanban/Kanban.tsx +951 -0
- package/src/components/Kanban/index.ts +7 -0
- package/src/components/Kbd/Kbd.module.scss +47 -0
- package/src/components/Kbd/Kbd.tokens.scss +26 -0
- package/src/components/Kbd/Kbd.tsx +73 -0
- package/src/components/Kbd/index.ts +2 -0
- package/src/components/Lightbox/Lightbox.module.scss +283 -0
- package/src/components/Lightbox/Lightbox.tokens.scss +36 -0
- package/src/components/Lightbox/Lightbox.tsx +506 -0
- package/src/components/Lightbox/index.ts +2 -0
- package/src/components/Link/Link.module.scss +78 -0
- package/src/components/Link/Link.tokens.scss +28 -0
- package/src/components/Link/Link.tsx +114 -0
- package/src/components/Link/index.ts +2 -0
- package/src/components/LinkCard/LinkCard.module.scss +92 -0
- package/src/components/LinkCard/LinkCard.tokens.scss +9 -0
- package/src/components/LinkCard/LinkCard.tsx +72 -0
- package/src/components/LinkCard/index.ts +2 -0
- package/src/components/LiquidEditor/AutocompleteMenu.tsx +133 -0
- package/src/components/LiquidEditor/HighlightLayer.tsx +53 -0
- package/src/components/LiquidEditor/InsertVariableMenu.tsx +81 -0
- package/src/components/LiquidEditor/LiquidEditor.module.scss +339 -0
- package/src/components/LiquidEditor/LiquidEditor.tokens.scss +81 -0
- package/src/components/LiquidEditor/LiquidEditor.tsx +412 -0
- package/src/components/LiquidEditor/PreviewPane.tsx +29 -0
- package/src/components/LiquidEditor/caretCoordinates.ts +97 -0
- package/src/components/LiquidEditor/index.ts +7 -0
- package/src/components/LiquidEditor/liquidFilters.ts +23 -0
- package/src/components/LiquidEditor/liquidTokenizer.ts +235 -0
- package/src/components/LiquidEditor/types.ts +101 -0
- package/src/components/LiquidEditor/useLiquidAutocomplete.ts +178 -0
- package/src/components/List/List.module.scss +105 -0
- package/src/components/List/List.tokens.scss +42 -0
- package/src/components/List/List.tsx +124 -0
- package/src/components/List/index.ts +9 -0
- package/src/components/LiveRegion/LiveRegion.module.scss +3 -0
- package/src/components/LiveRegion/LiveRegion.tsx +116 -0
- package/src/components/LiveRegion/index.ts +2 -0
- package/src/components/Logo/Logo.module.scss +139 -0
- package/src/components/Logo/Logo.tokens.scss +14 -0
- package/src/components/Logo/Logo.tsx +126 -0
- package/src/components/Logo/index.ts +2 -0
- package/src/components/Masonry/Masonry.module.scss +42 -0
- package/src/components/Masonry/Masonry.tokens.scss +8 -0
- package/src/components/Masonry/Masonry.tsx +136 -0
- package/src/components/Masonry/index.ts +2 -0
- package/src/components/Masonry/masonryUtils.ts +42 -0
- package/src/components/MediaTile/MediaTile.module.scss +183 -0
- package/src/components/MediaTile/MediaTile.tokens.scss +60 -0
- package/src/components/MediaTile/MediaTile.tsx +208 -0
- package/src/components/MediaTile/index.ts +8 -0
- package/src/components/Modal/Body.tsx +27 -0
- package/src/components/Modal/Close.tsx +45 -0
- package/src/components/Modal/Content.tsx +98 -0
- package/src/components/Modal/Footer.tsx +28 -0
- package/src/components/Modal/Header.tsx +51 -0
- package/src/components/Modal/Modal.module.scss +262 -0
- package/src/components/Modal/Modal.tokens.scss +50 -0
- package/src/components/Modal/Modal.tsx +23 -0
- package/src/components/Modal/ModalRoot.tsx +299 -0
- package/src/components/Modal/Overlay.tsx +101 -0
- package/src/components/Modal/context.ts +60 -0
- package/src/components/Modal/index.ts +11 -0
- package/src/components/MoneyInput/MoneyInput.module.scss +57 -0
- package/src/components/MoneyInput/MoneyInput.tsx +433 -0
- package/src/components/MoneyInput/index.ts +2 -0
- package/src/components/OptionsPicker/OptionsPicker.module.scss +216 -0
- package/src/components/OptionsPicker/OptionsPicker.tokens.scss +68 -0
- package/src/components/OptionsPicker/OptionsPicker.tsx +936 -0
- package/src/components/OptionsPicker/index.ts +9 -0
- package/src/components/OtpInput/OtpInput.module.scss +69 -0
- package/src/components/OtpInput/OtpInput.tokens.scss +45 -0
- package/src/components/OtpInput/OtpInput.tsx +368 -0
- package/src/components/OtpInput/index.ts +2 -0
- package/src/components/Page/Page.module.scss +30 -0
- package/src/components/Page/Page.tokens.scss +11 -0
- package/src/components/Page/Page.tsx +53 -0
- package/src/components/Page/index.ts +2 -0
- package/src/components/PageHeader/PageHeader.module.scss +197 -0
- package/src/components/PageHeader/PageHeader.tokens.scss +41 -0
- package/src/components/PageHeader/PageHeader.tsx +310 -0
- package/src/components/PageHeader/index.ts +20 -0
- package/src/components/Pagination/Pagination.module.scss +117 -0
- package/src/components/Pagination/Pagination.tokens.scss +54 -0
- package/src/components/Pagination/Pagination.tsx +165 -0
- package/src/components/Pagination/index.ts +4 -0
- package/src/components/Pagination/paginationRange.ts +72 -0
- package/src/components/PasswordInput/PasswordInput.module.scss +120 -0
- package/src/components/PasswordInput/PasswordInput.tokens.scss +44 -0
- package/src/components/PasswordInput/PasswordInput.tsx +210 -0
- package/src/components/PasswordInput/index.ts +2 -0
- package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.module.scss +80 -0
- package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tokens.scss +40 -0
- package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tsx +96 -0
- package/src/components/PasswordStrengthMeter/index.ts +2 -0
- package/src/components/PersonDisplay/PersonDisplay.module.scss +180 -0
- package/src/components/PersonDisplay/PersonDisplay.tokens.scss +35 -0
- package/src/components/PersonDisplay/PersonDisplay.tsx +420 -0
- package/src/components/PersonDisplay/index.ts +10 -0
- package/src/components/PhoneInput/PhoneInput.module.scss +23 -0
- package/src/components/PhoneInput/PhoneInput.tsx +271 -0
- package/src/components/PhoneInput/index.ts +4 -0
- package/src/components/PhoneInput/phone.ts +128 -0
- package/src/components/PillMenu/PillMenu.module.scss +117 -0
- package/src/components/PillMenu/PillMenu.tokens.scss +22 -0
- package/src/components/PillMenu/PillMenu.tsx +324 -0
- package/src/components/PillMenu/index.ts +2 -0
- package/src/components/Popover/Anchor.tsx +37 -0
- package/src/components/Popover/Close.tsx +45 -0
- package/src/components/Popover/Content.tsx +213 -0
- package/src/components/Popover/Heading.tsx +33 -0
- package/src/components/Popover/Popover.module.scss +177 -0
- package/src/components/Popover/Popover.tokens.scss +22 -0
- package/src/components/Popover/Popover.tsx +23 -0
- package/src/components/Popover/PopoverRoot.tsx +75 -0
- package/src/components/Popover/Trigger.tsx +86 -0
- package/src/components/Popover/context.ts +22 -0
- package/src/components/Popover/index.ts +7 -0
- package/src/components/Progress/Progress.module.scss +110 -0
- package/src/components/Progress/Progress.tokens.scss +44 -0
- package/src/components/Progress/Progress.tsx +129 -0
- package/src/components/Progress/index.ts +2 -0
- package/src/components/QrCode/QrCode.module.scss +97 -0
- package/src/components/QrCode/QrCode.tokens.scss +17 -0
- package/src/components/QrCode/QrCode.tsx +233 -0
- package/src/components/QrCode/index.ts +2 -0
- package/src/components/QrCode/qr.ts +161 -0
- package/src/components/Radio/Radio.module.scss +175 -0
- package/src/components/Radio/Radio.tokens.scss +59 -0
- package/src/components/Radio/Radio.tsx +127 -0
- package/src/components/Radio/RadioGroup.module.scss +42 -0
- package/src/components/Radio/RadioGroup.tsx +120 -0
- package/src/components/Radio/RadioGroupContext.tsx +30 -0
- package/src/components/Radio/index.ts +4 -0
- package/src/components/Rail/Rail.module.scss +510 -0
- package/src/components/Rail/Rail.tokens.scss +92 -0
- package/src/components/Rail/Rail.tsx +287 -0
- package/src/components/Rail/RailCollapseToggle.tsx +57 -0
- package/src/components/Rail/RailFooter.tsx +17 -0
- package/src/components/Rail/RailGroup.tsx +728 -0
- package/src/components/Rail/RailGroupContext.ts +9 -0
- package/src/components/Rail/RailHeader.tsx +23 -0
- package/src/components/Rail/RailItem.tsx +119 -0
- package/src/components/Rail/RailSection.tsx +39 -0
- package/src/components/Rail/RailSpacer.tsx +19 -0
- package/src/components/Rail/index.ts +9 -0
- package/src/components/RelativeDateInput/RelativeDateInput.module.scss +15 -0
- package/src/components/RelativeDateInput/RelativeDateInput.tokens.scss +6 -0
- package/src/components/RelativeDateInput/RelativeDateInput.tsx +474 -0
- package/src/components/RelativeDateInput/index.ts +10 -0
- package/src/components/RelativeDateInput/relativeDate.ts +127 -0
- package/src/components/RichText/RichText.module.scss +5 -0
- package/src/components/RichText/RichText.tsx +70 -0
- package/src/components/RichText/RichTextAttachment.module.scss +82 -0
- package/src/components/RichText/RichTextAttachment.tsx +122 -0
- package/src/components/RichText/_prose.scss +79 -0
- package/src/components/RichText/attachmentIcon.tsx +24 -0
- package/src/components/RichText/engine/attachment.ts +154 -0
- package/src/components/RichText/engine/autolink.ts +64 -0
- package/src/components/RichText/engine/blockUnit.ts +174 -0
- package/src/components/RichText/engine/colorMarks.ts +85 -0
- package/src/components/RichText/engine/escape.ts +11 -0
- package/src/components/RichText/engine/fromHtml.ts +353 -0
- package/src/components/RichText/engine/fromMarkdown.ts +20 -0
- package/src/components/RichText/engine/inlines.ts +82 -0
- package/src/components/RichText/engine/listDepths.ts +32 -0
- package/src/components/RichText/engine/marks.ts +80 -0
- package/src/components/RichText/engine/mdToHtml.ts +178 -0
- package/src/components/RichText/engine/model.ts +157 -0
- package/src/components/RichText/engine/position.ts +118 -0
- package/src/components/RichText/engine/renderDoc.tsx +395 -0
- package/src/components/RichText/engine/renderLink.ts +15 -0
- package/src/components/RichText/engine/renderMention.ts +16 -0
- package/src/components/RichText/engine/safeHref.ts +22 -0
- package/src/components/RichText/engine/toHtml.ts +154 -0
- package/src/components/RichText/engine/toMarkdown.ts +97 -0
- package/src/components/RichText/engine/transforms.ts +434 -0
- package/src/components/RichText/imageMaxHeightStyle.ts +10 -0
- package/src/components/RichText/index.ts +31 -0
- package/src/components/RichTextEditor/RichTextAttachmentConfig.tsx +264 -0
- package/src/components/RichTextEditor/RichTextBlockControls.tsx +365 -0
- package/src/components/RichTextEditor/RichTextBlockMenu.tsx +162 -0
- package/src/components/RichTextEditor/RichTextColorMenu.tsx +115 -0
- package/src/components/RichTextEditor/RichTextEditor.module.scss +298 -0
- package/src/components/RichTextEditor/RichTextEditor.tsx +1910 -0
- package/src/components/RichTextEditor/RichTextImageResizer.tsx +131 -0
- package/src/components/RichTextEditor/RichTextLinkEditor.tsx +151 -0
- package/src/components/RichTextEditor/RichTextMentionMenu.tsx +99 -0
- package/src/components/RichTextEditor/RichTextToolbar.tsx +379 -0
- package/src/components/RichTextEditor/autolinkInput.ts +65 -0
- package/src/components/RichTextEditor/blockDrop.ts +9 -0
- package/src/components/RichTextEditor/blockReflow.ts +62 -0
- package/src/components/RichTextEditor/commands.ts +300 -0
- package/src/components/RichTextEditor/history.ts +93 -0
- package/src/components/RichTextEditor/icons.tsx +152 -0
- package/src/components/RichTextEditor/imageSize.ts +70 -0
- package/src/components/RichTextEditor/index.ts +5 -0
- package/src/components/RichTextEditor/input.ts +209 -0
- package/src/components/RichTextEditor/inputRules.ts +71 -0
- package/src/components/RichTextEditor/links.ts +103 -0
- package/src/components/RichTextEditor/mentionContext.ts +37 -0
- package/src/components/RichTextEditor/mentions.ts +28 -0
- package/src/components/RichTextEditor/preventSelectionLoss.ts +15 -0
- package/src/components/RichTextEditor/selection.ts +415 -0
- package/src/components/RichTextEditor/shortcuts.ts +44 -0
- package/src/components/RichTextEditor/useAnchoredFloating.ts +50 -0
- package/src/components/RichTextEditor/useAttachmentConfig.ts +134 -0
- package/src/components/RichTextEditor/useDismissOnOutsidePointerDown.ts +26 -0
- package/src/components/RichTextEditor/useLinkEditor.ts +107 -0
- package/src/components/RichTextEditor/useMention.ts +226 -0
- package/src/components/RichTextEditor/useOverlayRect.ts +73 -0
- package/src/components/RichTextEditor/useUpload.ts +246 -0
- package/src/components/Screen/Screen.module.scss +46 -0
- package/src/components/Screen/Screen.tokens.scss +20 -0
- package/src/components/Screen/Screen.tsx +97 -0
- package/src/components/Screen/index.ts +2 -0
- package/src/components/ScrollArea/ScrollArea.module.scss +39 -0
- package/src/components/ScrollArea/ScrollArea.tokens.scss +15 -0
- package/src/components/ScrollArea/ScrollArea.tsx +154 -0
- package/src/components/ScrollArea/index.ts +2 -0
- package/src/components/Select/Chip.tsx +45 -0
- package/src/components/Select/Empty.tsx +39 -0
- package/src/components/Select/Error.tsx +51 -0
- package/src/components/Select/HiddenInputs.tsx +44 -0
- package/src/components/Select/Listbox.tsx +557 -0
- package/src/components/Select/Loading.tsx +30 -0
- package/src/components/Select/Select.module.scss +512 -0
- package/src/components/Select/Select.tokens.scss +140 -0
- package/src/components/Select/Select.tsx +685 -0
- package/src/components/Select/Trigger.tsx +952 -0
- package/src/components/Select/context.ts +101 -0
- package/src/components/Select/emptyStateText.ts +19 -0
- package/src/components/Select/index.ts +9 -0
- package/src/components/Select/useSelectState.ts +157 -0
- package/src/components/Select/utils-types.ts +7 -0
- package/src/components/Select/utils.ts +122 -0
- package/src/components/SettingRow/SettingRow.module.scss +166 -0
- package/src/components/SettingRow/SettingRow.tokens.scss +37 -0
- package/src/components/SettingRow/SettingRow.tsx +242 -0
- package/src/components/SettingRow/index.ts +7 -0
- package/src/components/Skeleton/Skeleton.module.scss +55 -0
- package/src/components/Skeleton/Skeleton.tokens.scss +17 -0
- package/src/components/Skeleton/Skeleton.tsx +131 -0
- package/src/components/Skeleton/index.ts +4 -0
- package/src/components/Skeleton/useSkeletonVisibility.ts +95 -0
- package/src/components/Slider/Slider.module.scss +293 -0
- package/src/components/Slider/Slider.tokens.scss +98 -0
- package/src/components/Slider/Slider.tsx +624 -0
- package/src/components/Slider/index.ts +9 -0
- package/src/components/SlotGrid/SlotGrid.module.scss +61 -0
- package/src/components/SlotGrid/SlotGrid.tokens.scss +21 -0
- package/src/components/SlotGrid/SlotGrid.tsx +111 -0
- package/src/components/SlotGrid/index.ts +2 -0
- package/src/components/SocialButton/SocialButton.module.scss +4 -0
- package/src/components/SocialButton/SocialButton.tsx +40 -0
- package/src/components/SocialButton/index.ts +2 -0
- package/src/components/Sortable/Sortable.module.scss +177 -0
- package/src/components/Sortable/Sortable.tokens.scss +27 -0
- package/src/components/Sortable/Sortable.tsx +572 -0
- package/src/components/Sortable/containerAwareCollision.ts +125 -0
- package/src/components/Sortable/index.ts +13 -0
- package/src/components/SortableGroup/SortableGroup.module.scss +23 -0
- package/src/components/SortableGroup/SortableGroup.tsx +315 -0
- package/src/components/SortableGroup/index.ts +4 -0
- package/src/components/SortableGroup/moveSortableItem.ts +39 -0
- package/src/components/Sparkline/Sparkline.module.scss +28 -0
- package/src/components/Sparkline/Sparkline.tokens.scss +7 -0
- package/src/components/Sparkline/Sparkline.tsx +133 -0
- package/src/components/Sparkline/index.ts +2 -0
- package/src/components/Sparkline/sparklineModel.ts +119 -0
- package/src/components/Split/Split.module.scss +158 -0
- package/src/components/Split/Split.tokens.scss +10 -0
- package/src/components/Split/Split.tsx +231 -0
- package/src/components/Split/index.ts +2 -0
- package/src/components/Stack/Stack.module.scss +67 -0
- package/src/components/Stack/Stack.tokens.scss +11 -0
- package/src/components/Stack/Stack.tsx +100 -0
- package/src/components/Stack/index.ts +2 -0
- package/src/components/StagePath/StagePath.module.scss +255 -0
- package/src/components/StagePath/StagePath.tokens.scss +43 -0
- package/src/components/StagePath/StagePath.tsx +176 -0
- package/src/components/StagePath/index.ts +2 -0
- package/src/components/StatGroup/StatGroup.module.scss +6 -0
- package/src/components/StatGroup/StatGroup.tsx +70 -0
- package/src/components/StatGroup/StatGroupContext.ts +10 -0
- package/src/components/StatGroup/StatTile.module.scss +99 -0
- package/src/components/StatGroup/StatTile.tokens.scss +35 -0
- package/src/components/StatGroup/StatTile.tsx +143 -0
- package/src/components/StatGroup/index.ts +4 -0
- package/src/components/Sticky/Sticky.module.scss +98 -0
- package/src/components/Sticky/Sticky.tokens.scss +17 -0
- package/src/components/Sticky/Sticky.tsx +103 -0
- package/src/components/Sticky/index.ts +2 -0
- package/src/components/Switch/Switch.module.scss +182 -0
- package/src/components/Switch/Switch.tokens.scss +59 -0
- package/src/components/Switch/Switch.tsx +214 -0
- package/src/components/Switch/index.ts +2 -0
- package/src/components/Table/Table.module.scss +308 -0
- package/src/components/Table/Table.tokens.scss +79 -0
- package/src/components/Table/Table.tsx +381 -0
- package/src/components/Table/index.ts +15 -0
- package/src/components/TableOfContents/TableOfContents.module.scss +83 -0
- package/src/components/TableOfContents/TableOfContents.tokens.scss +26 -0
- package/src/components/TableOfContents/TableOfContents.tsx +192 -0
- package/src/components/TableOfContents/activeSection.ts +18 -0
- package/src/components/TableOfContents/index.ts +2 -0
- package/src/components/Tabs/Tabs.module.scss +359 -0
- package/src/components/Tabs/Tabs.tokens.scss +50 -0
- package/src/components/Tabs/Tabs.tsx +538 -0
- package/src/components/Tabs/index.ts +2 -0
- package/src/components/Text/Text.module.scss +115 -0
- package/src/components/Text/Text.tokens.scss +55 -0
- package/src/components/Text/Text.tsx +197 -0
- package/src/components/Text/index.ts +2 -0
- package/src/components/Textarea/Textarea.module.scss +94 -0
- package/src/components/Textarea/Textarea.tokens.scss +48 -0
- package/src/components/Textarea/Textarea.tsx +246 -0
- package/src/components/Textarea/index.ts +2 -0
- package/src/components/Thread/Thread.module.scss +161 -0
- package/src/components/Thread/Thread.tokens.scss +32 -0
- package/src/components/Thread/Thread.tsx +176 -0
- package/src/components/Thread/index.ts +2 -0
- package/src/components/TimeField/TimeField.module.scss +232 -0
- package/src/components/TimeField/TimeField.tsx +793 -0
- package/src/components/TimeField/index.ts +2 -0
- package/src/components/Timeline/Timeline.module.scss +58 -0
- package/src/components/Timeline/Timeline.tokens.scss +13 -0
- package/src/components/Timeline/Timeline.tsx +53 -0
- package/src/components/Timeline/index.ts +2 -0
- package/src/components/Title/Title.module.scss +84 -0
- package/src/components/Title/Title.tokens.scss +37 -0
- package/src/components/Title/Title.tsx +150 -0
- package/src/components/Title/index.ts +2 -0
- package/src/components/Toast/Toast.module.scss +299 -0
- package/src/components/Toast/Toast.tokens.scss +65 -0
- package/src/components/Toast/Toast.tsx +122 -0
- package/src/components/Toast/ToastViewport.tsx +166 -0
- package/src/components/Toast/api.ts +175 -0
- package/src/components/Toast/index.ts +5 -0
- package/src/components/Toast/store.ts +133 -0
- package/src/components/Toast/useToastTimer.ts +94 -0
- package/src/components/Tooltip/Tooltip.module.scss +99 -0
- package/src/components/Tooltip/Tooltip.tokens.scss +23 -0
- package/src/components/Tooltip/Tooltip.tsx +341 -0
- package/src/components/Tooltip/index.ts +2 -0
- package/src/components/TopBar/TopBar.module.scss +235 -0
- package/src/components/TopBar/TopBar.tokens.scss +79 -0
- package/src/components/TopBar/TopBar.tsx +87 -0
- package/src/components/TopBar/TopBarEnd.tsx +20 -0
- package/src/components/TopBar/TopBarIconButton.tsx +86 -0
- package/src/components/TopBar/TopBarSearch.tsx +319 -0
- package/src/components/TopBar/TopBarSearchPanel.tsx +268 -0
- package/src/components/TopBar/TopBarStart.tsx +20 -0
- package/src/components/TopBar/index.ts +11 -0
- package/src/components/Tour/Spotlight.tsx +121 -0
- package/src/components/Tour/Tour.module.scss +210 -0
- package/src/components/Tour/Tour.tokens.scss +58 -0
- package/src/components/Tour/Tour.tsx +617 -0
- package/src/components/Tour/index.ts +2 -0
- package/src/components/Tour/useTourTarget.ts +115 -0
- package/src/components/TreeView/TreeView.module.scss +268 -0
- package/src/components/TreeView/TreeView.tokens.scss +36 -0
- package/src/components/TreeView/TreeView.tsx +536 -0
- package/src/components/TreeView/index.ts +3 -0
- package/src/components/TreeView/treeModel.ts +224 -0
- package/src/components/VisuallyHidden/VisuallyHidden.module.scss +7 -0
- package/src/components/VisuallyHidden/VisuallyHidden.tsx +29 -0
- package/src/components/VisuallyHidden/index.ts +2 -0
- package/src/components/WidgetPreview/WidgetPreview.module.scss +11 -0
- package/src/components/WidgetPreview/WidgetPreview.tokens.scss +26 -0
- package/src/components/WidgetPreview/WidgetPreview.tsx +36 -0
- package/src/components/WidgetPreview/WidgetShape.module.scss +140 -0
- package/src/components/WidgetPreview/WidgetShape.tsx +159 -0
- package/src/components/WidgetPreview/index.ts +2 -0
- package/src/components/_internal/Trend.tsx +27 -0
- package/src/components/_internal/choiceTile.scss +74 -0
- package/src/components/_internal/collapse.scss +10 -0
- package/src/components/_internal/collapse.ts +58 -0
- package/src/components/_internal/currency.ts +257 -0
- package/src/components/_internal/dragAnnouncements.ts +200 -0
- package/src/components/_internal/fieldWiring.ts +225 -0
- package/src/components/_internal/gridSpan.ts +54 -0
- package/src/components/_internal/isoDay.ts +35 -0
- package/src/components/_internal/letterKey.ts +26 -0
- package/src/components/_internal/overlay/focusRestore.ts +21 -0
- package/src/components/_internal/overlay/index.ts +12 -0
- package/src/components/_internal/overlay/tourHold.ts +23 -0
- package/src/components/_internal/overlay/useFocusTrap.ts +120 -0
- package/src/components/_internal/overlay/useInOverlay.ts +81 -0
- package/src/components/_internal/overlay/useOverlayStack.ts +232 -0
- package/src/components/_internal/overlay/useScrollLock.ts +112 -0
- package/src/components/_internal/refs.ts +48 -0
- package/src/components/_internal/statusColor.ts +26 -0
- package/src/components/_internal/timeUtils.ts +23 -0
- package/src/components/_internal/useAsyncOptions.ts +145 -0
- package/src/components/_internal/useClippedTooltip.ts +50 -0
- package/src/components/_internal/useControllableState.ts +50 -0
- package/src/components.manifest.json +1141 -0
- package/src/hooks/useBelowBreakpoint.ts +58 -0
- package/src/i18n/I18nProvider.tsx +52 -0
- package/src/i18n/LocaleProvider.tsx +17 -0
- package/src/i18n/en.ts +648 -0
- package/src/i18n/format.ts +71 -0
- package/src/i18n/index.ts +13 -0
- package/src/i18n/messages.ts +1275 -0
- package/src/i18n/ru.ts +677 -0
- package/src/i18n/useLocale.ts +19 -0
- package/src/i18n/useTranslation.ts +58 -0
- package/src/index.ts +913 -0
- package/src/palette/index.ts +2 -0
- package/src/palette/palette.ts +108 -0
- package/src/styles/dark.scss +4 -0
- package/src/styles/global.scss +7 -0
- package/src/styles/mixins.scss +143 -0
- package/src/styles/reset.scss +78 -0
- package/src/styles/tokens.scss +18 -0
- package/src/styles/typography.scss +44 -0
|
@@ -0,0 +1,734 @@
|
|
|
1
|
+
import {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useEffect,
|
|
4
|
+
useCallback,
|
|
5
|
+
useMemo,
|
|
6
|
+
useRef,
|
|
7
|
+
useState,
|
|
8
|
+
type ReactNode,
|
|
9
|
+
type Ref,
|
|
10
|
+
type RefObject,
|
|
11
|
+
} from 'react';
|
|
12
|
+
import clsx from 'clsx';
|
|
13
|
+
import {
|
|
14
|
+
DndContext,
|
|
15
|
+
PointerSensor,
|
|
16
|
+
KeyboardSensor,
|
|
17
|
+
useDndContext,
|
|
18
|
+
useSensor,
|
|
19
|
+
useSensors,
|
|
20
|
+
type DragEndEvent,
|
|
21
|
+
type Modifier,
|
|
22
|
+
} from '@dnd-kit/core';
|
|
23
|
+
import {
|
|
24
|
+
SortableContext,
|
|
25
|
+
horizontalListSortingStrategy,
|
|
26
|
+
sortableKeyboardCoordinates,
|
|
27
|
+
} from '@dnd-kit/sortable';
|
|
28
|
+
import { Table } from '../Table';
|
|
29
|
+
import type { TableDensity } from '../Table';
|
|
30
|
+
import { Checkbox } from '../Checkbox';
|
|
31
|
+
import { Skeleton, useSkeletonVisibility } from '../Skeleton';
|
|
32
|
+
import { EmptyState } from '../EmptyState';
|
|
33
|
+
import { HeaderCell } from './HeaderCell';
|
|
34
|
+
import { BodyRow } from './BodyRow';
|
|
35
|
+
import { reorderRespectingPins } from './reorderColumns';
|
|
36
|
+
import { useColumnDragShift } from './useColumnDragShift';
|
|
37
|
+
import { clampX, type DragRangeX } from './columnShift';
|
|
38
|
+
import { useFloatingSurface } from '../_internal/overlay';
|
|
39
|
+
import {
|
|
40
|
+
dragLabelOf,
|
|
41
|
+
useDragAccessibility,
|
|
42
|
+
type DescribeDragTarget,
|
|
43
|
+
} from '../_internal/dragAnnouncements';
|
|
44
|
+
import { AUTO_CELL_WIDTH } from './pinStyle';
|
|
45
|
+
import type { DataTableInstance } from './types';
|
|
46
|
+
import type { CollapseBreakpoint } from '../_internal/collapse';
|
|
47
|
+
import { useTranslation } from '../../i18n/useTranslation';
|
|
48
|
+
import styles from './DataTable.module.scss';
|
|
49
|
+
|
|
50
|
+
const collapseClass: Record<CollapseBreakpoint, string> = {
|
|
51
|
+
sm: styles.collapseSm,
|
|
52
|
+
md: styles.collapseMd,
|
|
53
|
+
lg: styles.collapseLg,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export interface DataTableProps<T> {
|
|
57
|
+
instance: DataTableInstance<T>;
|
|
58
|
+
density?: TableDensity;
|
|
59
|
+
striped?: boolean;
|
|
60
|
+
/** Hover highlight on body rows. Defaults TRUE (DataTable rows are usually interactive). */
|
|
61
|
+
hover?: boolean;
|
|
62
|
+
bordered?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Marks the table busy. Empty tables show skeleton rows; populated tables
|
|
65
|
+
* keep their rows mounted during a refetch so focus and local row state are
|
|
66
|
+
* preserved. Defaults to `false`.
|
|
67
|
+
*
|
|
68
|
+
* Announced from a polite live region the table owns, gated on the SKELETON
|
|
69
|
+
* rather than on this prop: a load shorter than `skeletonDelay` shows nothing
|
|
70
|
+
* and so says nothing, and a refetch over rows already on screen is silent
|
|
71
|
+
* because nothing visibly changes. The resolution is announced too — "Rows
|
|
72
|
+
* loaded" or "No rows loaded". `aria-busy` is also set, but reaches no screen
|
|
73
|
+
* reader on its own.
|
|
74
|
+
*/
|
|
75
|
+
loading?: boolean;
|
|
76
|
+
/** Number of skeleton rows when `loading`. Defaults 10. */
|
|
77
|
+
loadingRowCount?: number;
|
|
78
|
+
/**
|
|
79
|
+
* Milliseconds to wait before showing skeleton rows for an empty initial
|
|
80
|
+
* load. Defaults to `0`; fast loads that finish inside the delay never show
|
|
81
|
+
* a skeleton.
|
|
82
|
+
*/
|
|
83
|
+
skeletonDelay?: number;
|
|
84
|
+
/**
|
|
85
|
+
* Minimum milliseconds skeleton rows remain visible after appearing.
|
|
86
|
+
* Defaults to `0`. Arriving rows and the empty state remain hidden until the
|
|
87
|
+
* visual tail finishes. `aria-busy` still follows actual `loading`, not the
|
|
88
|
+
* skeleton's visual tail.
|
|
89
|
+
*/
|
|
90
|
+
skeletonMinDuration?: number;
|
|
91
|
+
/** Element shown when `data` is empty and not loading. Defaults to a stock <EmptyState>. */
|
|
92
|
+
emptyState?: ReactNode;
|
|
93
|
+
/**
|
|
94
|
+
* Stacks responsive data cells below this container-query breakpoint: `sm`
|
|
95
|
+
* (480px), `md` (640px), or `lg` (768px). Selection, expansion, sorting,
|
|
96
|
+
* row actions, and column visibility remain usable. Column sizing, pinning,
|
|
97
|
+
* and ordering state is retained, but resize/reorder controls and sticky pin
|
|
98
|
+
* presentation are unavailable while stacked and return after widening.
|
|
99
|
+
*
|
|
100
|
+
* This adds a wrapper with `container-type: inline-size`, so the breakpoint
|
|
101
|
+
* measures the table's available container width, not the viewport. Avoid an
|
|
102
|
+
* intrinsic-width parent such as `width: max-content`: inline-size containment
|
|
103
|
+
* can make the wrapper contribute zero intrinsic width there.
|
|
104
|
+
*/
|
|
105
|
+
collapseBelow?: CollapseBreakpoint;
|
|
106
|
+
/** Required for a11y when no caption is provided. */
|
|
107
|
+
'aria-label'?: string;
|
|
108
|
+
caption?: ReactNode;
|
|
109
|
+
/**
|
|
110
|
+
* Drag the whole column while reordering, not just its header cell.
|
|
111
|
+
*
|
|
112
|
+
* Default `true` — the dragged column's body cells travel with its header,
|
|
113
|
+
* and every column the drag displaces shifts its body cells too, so the
|
|
114
|
+
* header row and the body never disagree mid-drag. Costs one CSS-variable
|
|
115
|
+
* write per shifted column per frame; the cells move on the compositor, so
|
|
116
|
+
* the table body is not re-rendered during pointer movement. It does cost
|
|
117
|
+
* two full body reconciliations per drag — one at drag start, one at drag
|
|
118
|
+
* end — because the drag-active flag is component state and body rows are
|
|
119
|
+
* not memoized; that is the number to weigh for a very large table.
|
|
120
|
+
*
|
|
121
|
+
* Set `false` for the cheaper preview: only the dragged header cell follows
|
|
122
|
+
* the pointer and the body stays put until drop. Worth it for very large
|
|
123
|
+
* tables on low-end hardware, or to restore the previous behavior.
|
|
124
|
+
*
|
|
125
|
+
* Pinned columns never move under either setting — they are excluded from
|
|
126
|
+
* reordering entirely.
|
|
127
|
+
*
|
|
128
|
+
* The two settings also differ on **what a release means when no unpinned
|
|
129
|
+
* slot is under the column** — over a pinned column, or off the table
|
|
130
|
+
* entirely. Default: the drop commits the slot the preview is showing. The
|
|
131
|
+
* opt-out: the drop is discarded, because dnd-kit's own preview retracts (the
|
|
132
|
+
* header snaps back home) in that situation, and a commit would contradict
|
|
133
|
+
* it. See `docs/components/DataTable.md`, the column-drag bullet.
|
|
134
|
+
*/
|
|
135
|
+
dragWholeColumn?: boolean;
|
|
136
|
+
className?: string;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* #282: registers the active column-reorder drag as a floating surface so a
|
|
141
|
+
* host Modal/Drawer yields the Escape that cancels it. A leaf inside DndContext
|
|
142
|
+
* (reads `active` via `useDndContext`) so the drag-active toggle re-renders only
|
|
143
|
+
* this null node — never the table body.
|
|
144
|
+
*/
|
|
145
|
+
function DragFloatingProbe() {
|
|
146
|
+
const { active } = useDndContext();
|
|
147
|
+
useFloatingSurface(active != null);
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Publishes per-column drag offsets as CSS custom properties on the table
|
|
153
|
+
* element. A leaf that renders `null` for the same reason `DragFloatingProbe`
|
|
154
|
+
* is one: `useDndMonitor` fires on every pointer move, and keeping the
|
|
155
|
+
* subscription here means those events never re-render the table body.
|
|
156
|
+
*/
|
|
157
|
+
function ColumnShiftDriver({
|
|
158
|
+
rootRef,
|
|
159
|
+
enabled,
|
|
160
|
+
orderedIds,
|
|
161
|
+
widths,
|
|
162
|
+
dragRangeRef,
|
|
163
|
+
lastSlotIdRef,
|
|
164
|
+
onDragActiveChange,
|
|
165
|
+
}: {
|
|
166
|
+
rootRef: RefObject<HTMLElement | null>;
|
|
167
|
+
enabled: boolean;
|
|
168
|
+
orderedIds: string[];
|
|
169
|
+
widths: Record<string, number>;
|
|
170
|
+
dragRangeRef: RefObject<DragRangeX | null>;
|
|
171
|
+
lastSlotIdRef: RefObject<string | null>;
|
|
172
|
+
onDragActiveChange: (active: boolean) => void;
|
|
173
|
+
}) {
|
|
174
|
+
useColumnDragShift({
|
|
175
|
+
rootRef,
|
|
176
|
+
enabled,
|
|
177
|
+
orderedIds,
|
|
178
|
+
widths,
|
|
179
|
+
dragRangeRef,
|
|
180
|
+
lastSlotIdRef,
|
|
181
|
+
onDragActiveChange,
|
|
182
|
+
});
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** Sorting strategy that moves nothing — see the SortableContext comment. */
|
|
187
|
+
const noopSortingStrategy = () => null;
|
|
188
|
+
|
|
189
|
+
function ResponsiveScrollWrap({
|
|
190
|
+
collapseBelow,
|
|
191
|
+
children,
|
|
192
|
+
}: {
|
|
193
|
+
collapseBelow?: CollapseBreakpoint;
|
|
194
|
+
children: ReactNode;
|
|
195
|
+
}) {
|
|
196
|
+
if (!collapseBelow) return children;
|
|
197
|
+
return (
|
|
198
|
+
<div className={clsx(styles.responsiveScrollWrap, collapseClass[collapseBelow])}>
|
|
199
|
+
{children}
|
|
200
|
+
</div>
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function DataTableInner<T>(
|
|
205
|
+
{
|
|
206
|
+
instance,
|
|
207
|
+
density = 'comfortable',
|
|
208
|
+
striped,
|
|
209
|
+
hover = true,
|
|
210
|
+
bordered,
|
|
211
|
+
loading = false,
|
|
212
|
+
loadingRowCount = 10,
|
|
213
|
+
skeletonDelay = 0,
|
|
214
|
+
skeletonMinDuration = 0,
|
|
215
|
+
emptyState,
|
|
216
|
+
caption,
|
|
217
|
+
dragWholeColumn = true,
|
|
218
|
+
collapseBelow,
|
|
219
|
+
className,
|
|
220
|
+
...rest
|
|
221
|
+
}: DataTableProps<T>,
|
|
222
|
+
ref: Ref<HTMLTableElement>,
|
|
223
|
+
) {
|
|
224
|
+
const t = useTranslation();
|
|
225
|
+
const sensors = useSensors(
|
|
226
|
+
useSensor(PointerSensor, { activationConstraint: { distance: 6 } }),
|
|
227
|
+
useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
|
|
228
|
+
);
|
|
229
|
+
const visibleIds = useMemo(
|
|
230
|
+
() => instance.visibleColumns.map((c) => c.id),
|
|
231
|
+
[instance.visibleColumns],
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
// SortableContext items: only columns that are actually reorderable (unpinned
|
|
235
|
+
// AND enableReorder !== false). Pinned columns are excluded so dnd-kit doesn't
|
|
236
|
+
// animate them out of position when a draggable column crosses over them —
|
|
237
|
+
// their per-column `useSortable({ disabled })` blocks drag activation, but
|
|
238
|
+
// their presence in the items list still makes horizontalListSortingStrategy
|
|
239
|
+
// shift them during another column's drag.
|
|
240
|
+
// Note this deliberately does NOT mirror HeaderCell's "hide the grip when
|
|
241
|
+
// there is only one unpinned column" rule. A lone unpinned column stays in
|
|
242
|
+
// this list while its own `useSortable({ disabled })` blocks activation —
|
|
243
|
+
// a single-item sorting context is a no-op, and keeping the lists derived
|
|
244
|
+
// from one filter each is clearer than keeping two conditions in sync.
|
|
245
|
+
const sortableIds = useMemo(
|
|
246
|
+
() => instance.unpinnedColumns.filter((c) => c.enableReorder !== false).map((c) => c.id),
|
|
247
|
+
[instance.unpinnedColumns],
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
// Shift-driver geometry: EVERY unpinned column, reorderable or not. Do not
|
|
251
|
+
// "deduplicate" this with `sortableIds` — the enableReorder filter above is
|
|
252
|
+
// correct for SortableContext and wrong here. A non-reorderable unpinned
|
|
253
|
+
// column still occupies space and is still displaced when a reorderable
|
|
254
|
+
// column is dragged past it, and the drop path (reorderRespectingPins) moves
|
|
255
|
+
// it. Feeding sortableIds here made the preview skip it: the skipped column
|
|
256
|
+
// and its neighbour rendered on top of each other full-height, then the drop
|
|
257
|
+
// landed somewhere the preview never showed.
|
|
258
|
+
const shiftOrderedIds = useMemo(
|
|
259
|
+
() => instance.unpinnedColumns.map((c) => c.id),
|
|
260
|
+
[instance.unpinnedColumns],
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
// Travel available to the column being dragged, measured from real header
|
|
264
|
+
// rects when the drag starts (see `measureDragRangeX`). One measurement, two
|
|
265
|
+
// readers: `useColumnDragShift` clamps the delta it publishes, and the
|
|
266
|
+
// modifier below clamps `modifiedTranslate`. Null when no drag is active.
|
|
267
|
+
const dragRangeRef = useRef<DragRangeX | null>(null);
|
|
268
|
+
|
|
269
|
+
// Keep the dragged column inside the unpinned band. Without a clamp the
|
|
270
|
+
// pointer delta is applied raw, so a column can be dragged past the first or
|
|
271
|
+
// last slot and off the table entirely — and since `dragWholeColumn` defaults
|
|
272
|
+
// to true, that drags a full column of body cells over unrelated page content
|
|
273
|
+
// (#381).
|
|
274
|
+
//
|
|
275
|
+
// This modifier covers two things the delta clamp in `useColumnDragShift`
|
|
276
|
+
// cannot:
|
|
277
|
+
// - the COLLISION RECT. dnd-kit derives it as
|
|
278
|
+
// `getAdjustedRect(draggingNodeRect, modifiedTranslate)`, so clamping here
|
|
279
|
+
// keeps `over` resolving to the last reachable column instead of going
|
|
280
|
+
// null once the pointer leaves the table.
|
|
281
|
+
// - the HEADER-ONLY path (`dragWholeColumn={false}`), where the header rides
|
|
282
|
+
// `useSortable`'s own transform — which is `modifiedTranslate` — and never
|
|
283
|
+
// touches this component's shift variables.
|
|
284
|
+
//
|
|
285
|
+
// Known residual, deliberately not papered over: on the header-only path this
|
|
286
|
+
// modifier can still be exceeded by dnd-kit's horizontal auto-scroll, because
|
|
287
|
+
// `scrollAdjustedTranslate = add(modifiedTranslate, scrollAdjustment)` adds
|
|
288
|
+
// the scroll adjustment AFTER modifiers run. The default whole-column path is
|
|
289
|
+
// unaffected — it clamps `delta`, which is already post-adjustment. Fixing
|
|
290
|
+
// the opt-out path too would mean overriding dnd-kit's auto-scroll.
|
|
291
|
+
const clampToUnpinnedBand = useCallback<Modifier>(({ transform, active }) => {
|
|
292
|
+
const range = dragRangeRef.current;
|
|
293
|
+
if (!active || !range) return transform;
|
|
294
|
+
return { ...transform, x: clampX(transform.x, range) };
|
|
295
|
+
}, []);
|
|
296
|
+
const modifiers = useMemo(() => [clampToUnpinnedBand], [clampToUnpinnedBand]);
|
|
297
|
+
|
|
298
|
+
// #383: the last slot in the unpinned band that this drag resolved. Written
|
|
299
|
+
// by the shift driver — nulled at drag start, set on every `onDragOver` whose
|
|
300
|
+
// target is a band member — and read by BOTH the whole-column preview and the
|
|
301
|
+
// drop below. One value feeding both is what makes them agree by construction
|
|
302
|
+
// on that path, instead of by coincidence.
|
|
303
|
+
//
|
|
304
|
+
// WHOLE-COLUMN MODE ONLY, and that restriction is load-bearing rather than
|
|
305
|
+
// cautious. On the header-only path the preview is dnd-kit's own, driven by
|
|
306
|
+
// `overIndex` against `SortableContext items={sortableIds}` — a list that
|
|
307
|
+
// excludes pinned columns. When the pinned column wins the collision the
|
|
308
|
+
// index is -1, so every transform including the dragged header's resolves to
|
|
309
|
+
// null: the header snaps back home and the gap closes. The preview there
|
|
310
|
+
// RETRACTS its promise, so committing would contradict what the user is
|
|
311
|
+
// looking at just as badly as discarding does here. That path keeps its
|
|
312
|
+
// discard, which at least agrees with its own preview.
|
|
313
|
+
//
|
|
314
|
+
// dnd-kit hands us a target the drop cannot use in two situations, and a
|
|
315
|
+
// pinned column produces both:
|
|
316
|
+
//
|
|
317
|
+
// - `over` IS the pinned column. A boolean `disabled` on `useSortable`
|
|
318
|
+
// normalizes to `{ draggable: true, droppable: false }` — it stands the
|
|
319
|
+
// DRAGGABLE down and leaves the droppable registered — so a pinned column
|
|
320
|
+
// is still a collision target. It is `position: sticky`, so once the table
|
|
321
|
+
// is scrolled its rect sits ON TOP of the band's last columns and it wins
|
|
322
|
+
// the intersection outright. `reorderRespectingPins` then rejects the move
|
|
323
|
+
// as cross-boundary and the drop evaporates.
|
|
324
|
+
// - `over` is null, which is where dnd-kit's horizontal auto-scroll lands:
|
|
325
|
+
// the scroll adjustment is applied to the translate AFTER modifiers run,
|
|
326
|
+
// so the collision rect desyncs from the droppable rects and stops
|
|
327
|
+
// intersecting anything at all.
|
|
328
|
+
//
|
|
329
|
+
// Either way the column is visibly parked at a valid slot when the user lets
|
|
330
|
+
// go — #382's clamp holds it inside the band — so discarding the drop breaks
|
|
331
|
+
// the promise the preview just made. Falling back to the last band slot keeps
|
|
332
|
+
// it. `reorderRespectingPins` stays as the backstop; this ref can only ever
|
|
333
|
+
// hold a band member, so a cross-boundary move cannot reach it.
|
|
334
|
+
//
|
|
335
|
+
// FAILS CLOSED, deliberately. `over` resolves to the dragged column itself at
|
|
336
|
+
// pickup, and the dragged column is a band member, so the ref seeds with
|
|
337
|
+
// `activeId`. A drag that never resolves any OTHER band member — a two-column
|
|
338
|
+
// band whose only other slot is covered by a wide sticky pinned column, say —
|
|
339
|
+
// therefore falls back to `activeId`, which the guard below reads as "no
|
|
340
|
+
// move" and the original discard survives. Wrong in the harmless direction:
|
|
341
|
+
// nothing moves that the user did not aim at.
|
|
342
|
+
const lastSlotIdRef = useRef<string | null>(null);
|
|
343
|
+
|
|
344
|
+
const handleDragEnd = (event: DragEndEvent) => {
|
|
345
|
+
const { active, over } = event;
|
|
346
|
+
const activeId = String(active.id);
|
|
347
|
+
// An out-of-band target is not a slot. When `over` is one, the last slot
|
|
348
|
+
// the band DID resolve is both the honest answer and the one on screen —
|
|
349
|
+
// but only where the whole-column preview is what painted it (see above).
|
|
350
|
+
//
|
|
351
|
+
// The raw branch is not dead weight even though `onDragOver` has already
|
|
352
|
+
// recorded any in-band `over` into the ref: it is the ONLY source on the
|
|
353
|
+
// header-only path, where the fallback is null by design.
|
|
354
|
+
const overIdRaw = over ? String(over.id) : null;
|
|
355
|
+
const fallbackId = dragWholeColumn ? lastSlotIdRef.current : null;
|
|
356
|
+
const overId =
|
|
357
|
+
overIdRaw != null && shiftOrderedIds.includes(overIdRaw) ? overIdRaw : fallbackId;
|
|
358
|
+
if (overId == null || activeId === overId) return;
|
|
359
|
+
|
|
360
|
+
instance.setColumnOrder((prev) => {
|
|
361
|
+
const next = reorderRespectingPins({
|
|
362
|
+
prev,
|
|
363
|
+
activeId,
|
|
364
|
+
overId,
|
|
365
|
+
visibleIds,
|
|
366
|
+
pinning: instance.columnPinning,
|
|
367
|
+
});
|
|
368
|
+
return next ?? prev; // null = rejected, keep prev unchanged
|
|
369
|
+
});
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
// Pin-ordered render list: [left-pinned, unpinned, right-pinned].
|
|
373
|
+
// Drives <colgroup>, header row, and body rows so all three stay aligned.
|
|
374
|
+
const renderColumns = useMemo(
|
|
375
|
+
() => [
|
|
376
|
+
...instance.leftPinnedColumns,
|
|
377
|
+
...instance.unpinnedColumns,
|
|
378
|
+
...instance.rightPinnedColumns,
|
|
379
|
+
],
|
|
380
|
+
[instance.leftPinnedColumns, instance.unpinnedColumns, instance.rightPinnedColumns],
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
const totalColCount =
|
|
384
|
+
instance.visibleColumns.length +
|
|
385
|
+
(instance.enableRowSelection ? 1 : 0) +
|
|
386
|
+
(instance.hasExpansion ? 1 : 0);
|
|
387
|
+
const hasRenderedRows = instance.data.length > 0 || instance.pinnedRows.length > 0;
|
|
388
|
+
const showSkeletonRows = useSkeletonVisibility(loading && !hasRenderedRows, {
|
|
389
|
+
delay: skeletonDelay,
|
|
390
|
+
minDuration: skeletonMinDuration,
|
|
391
|
+
});
|
|
392
|
+
const dataIsEmpty = !loading && !showSkeletonRows && !hasRenderedRows;
|
|
393
|
+
|
|
394
|
+
// Announce the SKELETON, not the raw `loading` prop. Tying it to `loading`
|
|
395
|
+
// meant a table with `skeletonDelay={300}` still announced a 200ms load it
|
|
396
|
+
// had deliberately decided to show nothing for, and a background refetch
|
|
397
|
+
// over rendered rows — which changes nothing on screen — interrupted the
|
|
398
|
+
// user on every poll. And announce the resolution: going from "Loading
|
|
399
|
+
// rows…" to populated in silence is the same half-finished shape this
|
|
400
|
+
// region exists to fix.
|
|
401
|
+
//
|
|
402
|
+
// Resolution announces the OUTCOME, not just "finished": landing on an empty
|
|
403
|
+
// table said "Rows loaded" while the screen read "No data". And it clears
|
|
404
|
+
// once announced — a live region only fires on change, so leaving the text
|
|
405
|
+
// in place bought nothing and left a stale node for a browse-mode reader to
|
|
406
|
+
// trip over under every loaded table.
|
|
407
|
+
const [loadPhase, setLoadPhase] = useState<'idle' | 'loading' | 'loaded' | 'empty'>('idle');
|
|
408
|
+
useEffect(() => {
|
|
409
|
+
setLoadPhase((prev) => {
|
|
410
|
+
if (showSkeletonRows) return 'loading';
|
|
411
|
+
if (prev !== 'loading') return prev;
|
|
412
|
+
return hasRenderedRows ? 'loaded' : 'empty';
|
|
413
|
+
});
|
|
414
|
+
}, [showSkeletonRows, hasRenderedRows]);
|
|
415
|
+
useEffect(() => {
|
|
416
|
+
if (loadPhase !== 'loaded' && loadPhase !== 'empty') return;
|
|
417
|
+
const id = setTimeout(() => setLoadPhase('idle'), CLEAR_STATUS_MS);
|
|
418
|
+
return () => clearTimeout(id);
|
|
419
|
+
}, [loadPhase]);
|
|
420
|
+
const responsiveEnabled = collapseBelow != null;
|
|
421
|
+
const hasResponsiveHeaderItems =
|
|
422
|
+
instance.enableRowSelection ||
|
|
423
|
+
renderColumns.some((column) => column.sortable === true || typeof column.header !== 'string');
|
|
424
|
+
|
|
425
|
+
const [dragActive, setDragActive] = useState(false);
|
|
426
|
+
|
|
427
|
+
// Localized column-reorder announcements (Hard rule 9). `HeaderCell` publishes
|
|
428
|
+
// the rendered header text, so a drag says "Amount, position 3 of 7" instead
|
|
429
|
+
// of "col-amount was moved over droppable area col-name".
|
|
430
|
+
//
|
|
431
|
+
// This resolves the slot exactly the way `handleDragEnd` does, in the SAME
|
|
432
|
+
// index space, and both halves of that are load-bearing:
|
|
433
|
+
//
|
|
434
|
+
// - `shiftOrderedIds`, not `sortableIds`. The two differ by the
|
|
435
|
+
// `enableReorder: false` columns: excluded from `SortableContext` (nothing
|
|
436
|
+
// to activate) but still droppable, still displaced, and still moved by
|
|
437
|
+
// `reorderRespectingPins` — see the comment on `shiftOrderedIds`. Deciding
|
|
438
|
+
// "in band" from the SortableContext list therefore calls a legal target
|
|
439
|
+
// unusable, and announces "Nothing moved." over a drop that reordered. It
|
|
440
|
+
// is also the set the position number belongs in: a listener is being told
|
|
441
|
+
// where the column landed among the visible unpinned columns.
|
|
442
|
+
// - the same `lastSlotIdRef` fallback (#383). In whole-column mode `over` can
|
|
443
|
+
// name something the drop cannot use — a sticky pinned column covering the
|
|
444
|
+
// band's last slot, or nothing at all after an auto-scroll desync, both
|
|
445
|
+
// observed — and `handleDragEnd` commits the last band slot the drag
|
|
446
|
+
// resolved rather than discarding. Announcing from raw `over` would call
|
|
447
|
+
// that reorder "nothing", which is the defect #390 was filed about with the
|
|
448
|
+
// sign flipped.
|
|
449
|
+
//
|
|
450
|
+
// The label is only ever read off `active`; a drop target's is unused.
|
|
451
|
+
const describeColumn: DescribeDragTarget = (entry) => {
|
|
452
|
+
const id = entry ? String(entry.id) : null;
|
|
453
|
+
const slotId =
|
|
454
|
+
id != null && shiftOrderedIds.includes(id)
|
|
455
|
+
? id
|
|
456
|
+
: dragWholeColumn
|
|
457
|
+
? lastSlotIdRef.current
|
|
458
|
+
: null;
|
|
459
|
+
const slot = slotId == null ? -1 : shiftOrderedIds.indexOf(slotId);
|
|
460
|
+
if (slot < 0) return null;
|
|
461
|
+
return {
|
|
462
|
+
label: dragLabelOf(entry?.data.current),
|
|
463
|
+
index: slot + 1,
|
|
464
|
+
total: shiftOrderedIds.length,
|
|
465
|
+
};
|
|
466
|
+
};
|
|
467
|
+
const dragAccessibility = useDragAccessibility(describeColumn);
|
|
468
|
+
|
|
469
|
+
// The shift driver writes custom properties onto the <table> element, so we
|
|
470
|
+
// need our own handle on it while still honouring the consumer's ref.
|
|
471
|
+
const tableRef = useRef<HTMLTableElement | null>(null);
|
|
472
|
+
const setTableRef = useCallback(
|
|
473
|
+
(node: HTMLTableElement | null) => {
|
|
474
|
+
tableRef.current = node;
|
|
475
|
+
if (typeof ref === 'function') {
|
|
476
|
+
// React 19 callback refs may return a cleanup function. Returning one
|
|
477
|
+
// from here keeps that contract alive — swallowing it would make React
|
|
478
|
+
// fall back to the legacy `ref(null)` call and leak whatever the
|
|
479
|
+
// consumer set up. Callback refs that return nothing, and object refs,
|
|
480
|
+
// behave exactly as before.
|
|
481
|
+
const cleanup = ref(node);
|
|
482
|
+
if (typeof cleanup === 'function')
|
|
483
|
+
return () => {
|
|
484
|
+
cleanup();
|
|
485
|
+
tableRef.current = null;
|
|
486
|
+
};
|
|
487
|
+
} else if (ref) (ref as { current: HTMLTableElement | null }).current = node;
|
|
488
|
+
},
|
|
489
|
+
[ref],
|
|
490
|
+
);
|
|
491
|
+
|
|
492
|
+
const table = (
|
|
493
|
+
<DndContext
|
|
494
|
+
accessibility={dragAccessibility}
|
|
495
|
+
sensors={sensors}
|
|
496
|
+
modifiers={modifiers}
|
|
497
|
+
onDragEnd={handleDragEnd}
|
|
498
|
+
>
|
|
499
|
+
{/* #282: register the column-reorder drag as a floating surface while
|
|
500
|
+
active so a host Modal/Drawer yields the Escape that cancels it (the
|
|
501
|
+
drag cancels; the host survives). A leaf probe (not root state) so the
|
|
502
|
+
drag-active toggle re-renders only this null node, never the table body. */}
|
|
503
|
+
<DragFloatingProbe />
|
|
504
|
+
<ColumnShiftDriver
|
|
505
|
+
rootRef={tableRef}
|
|
506
|
+
enabled={dragWholeColumn}
|
|
507
|
+
orderedIds={shiftOrderedIds}
|
|
508
|
+
widths={instance.columnSizesPx}
|
|
509
|
+
dragRangeRef={dragRangeRef}
|
|
510
|
+
lastSlotIdRef={lastSlotIdRef}
|
|
511
|
+
onDragActiveChange={setDragActive}
|
|
512
|
+
/>
|
|
513
|
+
<SortableContext
|
|
514
|
+
items={sortableIds}
|
|
515
|
+
// In whole-column mode the shift variables are the single source of
|
|
516
|
+
// truth for BOTH header and body. Standing dnd-kit's own transforms
|
|
517
|
+
// down takes TWO mechanisms, because `useSortable` treats the dragged
|
|
518
|
+
// item and its neighbours differently:
|
|
519
|
+
// - DISPLACED NEIGHBOURS go through the strategy, so a no-op strategy
|
|
520
|
+
// is what silences them. That is all this prop does.
|
|
521
|
+
// - The ACTIVE column never consults the strategy at all: with no
|
|
522
|
+
// <DragOverlay> rendered, useSortable short-circuits to its own
|
|
523
|
+
// `dragSourceDisplacement`. It is `useShiftVar` in HeaderCell —
|
|
524
|
+
// which discards `transform` outright — that keeps the dragged
|
|
525
|
+
// header glued to its body cells. Relaxing that guard would desync
|
|
526
|
+
// the dragged column no matter what this strategy says.
|
|
527
|
+
strategy={dragWholeColumn ? noopSortingStrategy : horizontalListSortingStrategy}
|
|
528
|
+
>
|
|
529
|
+
{/* Consumer-native table attributes still override component defaults.
|
|
530
|
+
`scroll` is the one invariant: it is not public on DataTableProps,
|
|
531
|
+
and keeping it after the spread also rejects a runtime-only override
|
|
532
|
+
that would break the instance-owned responsive wrapper. */}
|
|
533
|
+
<ResponsiveScrollWrap collapseBelow={collapseBelow}>
|
|
534
|
+
<Table
|
|
535
|
+
ref={setTableRef}
|
|
536
|
+
stickyHeader
|
|
537
|
+
hover={hover}
|
|
538
|
+
density={density}
|
|
539
|
+
striped={striped}
|
|
540
|
+
bordered={bordered}
|
|
541
|
+
aria-busy={loading || undefined}
|
|
542
|
+
aria-rowcount={instance.rowCount}
|
|
543
|
+
className={clsx(styles.root, className)}
|
|
544
|
+
{...rest}
|
|
545
|
+
scroll={!responsiveEnabled}
|
|
546
|
+
>
|
|
547
|
+
{caption && <Table.Caption>{caption}</Table.Caption>}
|
|
548
|
+
|
|
549
|
+
<colgroup>
|
|
550
|
+
{instance.enableRowSelection && <col style={{ width: AUTO_CELL_WIDTH }} />}
|
|
551
|
+
{instance.hasExpansion && <col style={{ width: AUTO_CELL_WIDTH }} />}
|
|
552
|
+
{renderColumns.map((col) => (
|
|
553
|
+
<col key={col.id} style={{ width: instance.columnSizesPx[col.id] ?? 120 }} />
|
|
554
|
+
))}
|
|
555
|
+
</colgroup>
|
|
556
|
+
|
|
557
|
+
<Table.Header
|
|
558
|
+
data-responsive-has-items={responsiveEnabled ? hasResponsiveHeaderItems : undefined}
|
|
559
|
+
>
|
|
560
|
+
<Table.Row>
|
|
561
|
+
{instance.enableRowSelection && (
|
|
562
|
+
<Table.HeaderCell
|
|
563
|
+
align="center"
|
|
564
|
+
scope="col"
|
|
565
|
+
className={clsx(styles.autoCell, styles.autoCellStickyHeader)}
|
|
566
|
+
style={{ position: 'sticky', left: 0 }}
|
|
567
|
+
data-responsive-control={responsiveEnabled || undefined}
|
|
568
|
+
>
|
|
569
|
+
<Checkbox
|
|
570
|
+
checked={instance.isAllOnPageSelected()}
|
|
571
|
+
indeterminate={instance.isSomeOnPageSelected()}
|
|
572
|
+
onChange={() => instance.toggleAllOnPage()}
|
|
573
|
+
aria-label={t('dataTable.selectAll')}
|
|
574
|
+
/>
|
|
575
|
+
</Table.HeaderCell>
|
|
576
|
+
)}
|
|
577
|
+
{instance.hasExpansion && (
|
|
578
|
+
<Table.HeaderCell
|
|
579
|
+
align="center"
|
|
580
|
+
scope="col"
|
|
581
|
+
className={clsx(styles.autoCell, styles.autoCellStickyHeader)}
|
|
582
|
+
style={{
|
|
583
|
+
position: 'sticky',
|
|
584
|
+
left: instance.enableRowSelection ? AUTO_CELL_WIDTH : 0,
|
|
585
|
+
}}
|
|
586
|
+
// Empty header — the expand column has no per-column action.
|
|
587
|
+
aria-label={t('dataTable.rowExpansion')}
|
|
588
|
+
/>
|
|
589
|
+
)}
|
|
590
|
+
{renderColumns.map((col) => (
|
|
591
|
+
<HeaderCell
|
|
592
|
+
key={col.id}
|
|
593
|
+
column={col}
|
|
594
|
+
instance={instance}
|
|
595
|
+
dragWholeColumn={dragWholeColumn}
|
|
596
|
+
dragActive={dragActive}
|
|
597
|
+
responsiveEnabled={responsiveEnabled}
|
|
598
|
+
/>
|
|
599
|
+
))}
|
|
600
|
+
</Table.Row>
|
|
601
|
+
</Table.Header>
|
|
602
|
+
|
|
603
|
+
{!showSkeletonRows && instance.pinnedRows.length > 0 && (
|
|
604
|
+
<Table.Body className={styles.pinnedRowsTbody} aria-label={t('dataTable.pinnedRows')}>
|
|
605
|
+
{instance.pinnedRows.map((row) => (
|
|
606
|
+
<BodyRow
|
|
607
|
+
key={instance.getRowId(row)}
|
|
608
|
+
row={row}
|
|
609
|
+
instance={instance}
|
|
610
|
+
isPinnedRow
|
|
611
|
+
dragWholeColumn={dragWholeColumn}
|
|
612
|
+
dragActive={dragActive}
|
|
613
|
+
responsiveEnabled={responsiveEnabled}
|
|
614
|
+
/>
|
|
615
|
+
))}
|
|
616
|
+
</Table.Body>
|
|
617
|
+
)}
|
|
618
|
+
|
|
619
|
+
<Table.Body>
|
|
620
|
+
{showSkeletonRows ? (
|
|
621
|
+
<SkeletonRows
|
|
622
|
+
count={loadingRowCount}
|
|
623
|
+
totalColCount={totalColCount}
|
|
624
|
+
responsiveEnabled={responsiveEnabled}
|
|
625
|
+
/>
|
|
626
|
+
) : dataIsEmpty ? (
|
|
627
|
+
<EmptyRow
|
|
628
|
+
totalColCount={totalColCount}
|
|
629
|
+
content={emptyState}
|
|
630
|
+
responsiveEnabled={responsiveEnabled}
|
|
631
|
+
/>
|
|
632
|
+
) : (
|
|
633
|
+
instance.data.map((row) => (
|
|
634
|
+
<BodyRow
|
|
635
|
+
key={instance.getRowId(row)}
|
|
636
|
+
row={row}
|
|
637
|
+
instance={instance}
|
|
638
|
+
dragWholeColumn={dragWholeColumn}
|
|
639
|
+
dragActive={dragActive}
|
|
640
|
+
responsiveEnabled={responsiveEnabled}
|
|
641
|
+
/>
|
|
642
|
+
))
|
|
643
|
+
)}
|
|
644
|
+
</Table.Body>
|
|
645
|
+
</Table>
|
|
646
|
+
</ResponsiveScrollWrap>
|
|
647
|
+
{/* Polite live region OUTSIDE the table — a <span> inside <table> is
|
|
648
|
+
invalid HTML — and AFTER the scroll wrap, so it does not displace
|
|
649
|
+
the wrapper as first child. Rendered unconditionally so only its
|
|
650
|
+
text mutates. `aria-busy` on the table is inert to screen readers,
|
|
651
|
+
so without this the table goes from silent to populated with
|
|
652
|
+
nothing said. See CLAUDE.md Hard rule 10. */}
|
|
653
|
+
<span role="status" aria-live="polite" className={styles.srStatus}>
|
|
654
|
+
{loadPhase === 'loading'
|
|
655
|
+
? t('dataTable.loading')
|
|
656
|
+
: loadPhase === 'loaded'
|
|
657
|
+
? t('dataTable.loaded')
|
|
658
|
+
: loadPhase === 'empty'
|
|
659
|
+
? t('dataTable.loadedEmpty')
|
|
660
|
+
: ''}
|
|
661
|
+
</span>
|
|
662
|
+
</SortableContext>
|
|
663
|
+
</DndContext>
|
|
664
|
+
);
|
|
665
|
+
|
|
666
|
+
if (!collapseBelow) return table;
|
|
667
|
+
|
|
668
|
+
return (
|
|
669
|
+
<div className={styles.responsiveContainer} data-collapse-below={collapseBelow}>
|
|
670
|
+
{table}
|
|
671
|
+
</div>
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
function SkeletonRows({
|
|
676
|
+
count,
|
|
677
|
+
totalColCount,
|
|
678
|
+
responsiveEnabled,
|
|
679
|
+
}: {
|
|
680
|
+
count: number;
|
|
681
|
+
totalColCount: number;
|
|
682
|
+
responsiveEnabled: boolean;
|
|
683
|
+
}) {
|
|
684
|
+
return (
|
|
685
|
+
<>
|
|
686
|
+
{Array.from({ length: count }, (_, i) => (
|
|
687
|
+
<Table.Row key={`sk-${i}`}>
|
|
688
|
+
{Array.from({ length: totalColCount }, (_, j) => (
|
|
689
|
+
<Table.Cell
|
|
690
|
+
key={j}
|
|
691
|
+
className={clsx(styles.skeletonCell, responsiveEnabled && styles.responsiveFullWidth)}
|
|
692
|
+
>
|
|
693
|
+
<Skeleton variant="text" width="80%" />
|
|
694
|
+
</Table.Cell>
|
|
695
|
+
))}
|
|
696
|
+
</Table.Row>
|
|
697
|
+
))}
|
|
698
|
+
</>
|
|
699
|
+
);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/** Long enough for the announcement to be picked up, short enough not to linger. */
|
|
703
|
+
const CLEAR_STATUS_MS = 1000;
|
|
704
|
+
|
|
705
|
+
function EmptyRow({
|
|
706
|
+
totalColCount,
|
|
707
|
+
content,
|
|
708
|
+
responsiveEnabled,
|
|
709
|
+
}: {
|
|
710
|
+
totalColCount: number;
|
|
711
|
+
content?: ReactNode;
|
|
712
|
+
responsiveEnabled: boolean;
|
|
713
|
+
}) {
|
|
714
|
+
const t = useTranslation();
|
|
715
|
+
return (
|
|
716
|
+
<Table.Row>
|
|
717
|
+
<Table.Cell
|
|
718
|
+
colSpan={totalColCount}
|
|
719
|
+
className={clsx(styles.emptyCell, responsiveEnabled && styles.responsiveFullWidth)}
|
|
720
|
+
>
|
|
721
|
+
{content ?? <EmptyState title={t('dataTable.empty')} />}
|
|
722
|
+
</Table.Cell>
|
|
723
|
+
</Table.Row>
|
|
724
|
+
);
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* Server-driven data table driven by a `useDataTable` instance.
|
|
729
|
+
* @see docs/components/DataTable.md
|
|
730
|
+
*/
|
|
731
|
+
// Generic forwardRef: TS erases `T` in a plain forwardRef, so the type is re-asserted.
|
|
732
|
+
export const DataTable = forwardRef(DataTableInner) as <T>(
|
|
733
|
+
props: DataTableProps<T> & { ref?: Ref<HTMLTableElement> },
|
|
734
|
+
) => ReturnType<typeof DataTableInner>;
|