@eocrm/design-system 0.0.0-stage → 0.6.17
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/README.md +262 -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 +82 -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,215 @@
|
|
|
1
|
+
@use '../../styles/mixins' as *;
|
|
2
|
+
@use './DataTable.tokens';
|
|
3
|
+
|
|
4
|
+
.headerCell {
|
|
5
|
+
position: relative;
|
|
6
|
+
|
|
7
|
+
// overflow:hidden ensures dnd-kit's CSS transform doesn't cause the cell
|
|
8
|
+
// content to appear wider than the column's <col> width during drag.
|
|
9
|
+
overflow: hidden;
|
|
10
|
+
|
|
11
|
+
// Header is interactive (sort click + drag + resize); rapid clicks
|
|
12
|
+
// shouldn't initiate a text selection range that bleeds into the body
|
|
13
|
+
// (commonly visible as the pinned-row cell below the column getting
|
|
14
|
+
// highlighted after a double-click on the sort header).
|
|
15
|
+
user-select: none;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Drag grip — absolutely positioned at the left edge of the cell. The cell's
|
|
19
|
+
// left padding is reserved via `--data-table-cell-padding-left` (16px) on the
|
|
20
|
+
// DataTable root (see DataTable.module.scss); the 12px grip sits in that
|
|
21
|
+
// padding area with a small gap before the column label, and body cells share
|
|
22
|
+
// the same padding-left so the header label stays aligned with body content.
|
|
23
|
+
// Only the grip's opacity toggles on hover — no layout shift.
|
|
24
|
+
.grip {
|
|
25
|
+
position: absolute;
|
|
26
|
+
top: 0;
|
|
27
|
+
bottom: 0;
|
|
28
|
+
left: 0;
|
|
29
|
+
width: 12px;
|
|
30
|
+
display: flex;
|
|
31
|
+
align-items: center;
|
|
32
|
+
justify-content: center;
|
|
33
|
+
color: var(--data-table-header-grip-fg);
|
|
34
|
+
opacity: var(--data-table-header-grip-opacity-hidden);
|
|
35
|
+
cursor: grab;
|
|
36
|
+
transition: opacity var(--data-table-header-grip-transition);
|
|
37
|
+
|
|
38
|
+
// Reveal on header hover OR when grip itself is focused.
|
|
39
|
+
.headerCell:hover &,
|
|
40
|
+
&:focus-visible {
|
|
41
|
+
opacity: var(--data-table-header-grip-opacity-visible);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
&:focus-visible {
|
|
45
|
+
@include focus-ring($offset: calc(-1 * var(--ring-offset)));
|
|
46
|
+
|
|
47
|
+
border-radius: var(--data-table-header-grip-focus-radius);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.inner {
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
gap: var(--data-table-header-inner-gap);
|
|
55
|
+
height: 100%;
|
|
56
|
+
|
|
57
|
+
// Prevent content overflow from expanding the measured cell width.
|
|
58
|
+
min-width: 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Reserve right space for the absolute-positioned resize handle (~24px — it
|
|
62
|
+
// contains chevrons + bar). Omitted when enableResize is false so the label
|
|
63
|
+
// + sort icon can extend to the cell's right padding edge.
|
|
64
|
+
.innerWithResize {
|
|
65
|
+
padding-right: 24px;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Flex justification mirrors `column.align` so end- / center-aligned columns
|
|
69
|
+
// position their label + sort indicator the same way the body cells render.
|
|
70
|
+
// Label.flex is overridden from `1 1 auto` to `0 1 auto` so it doesn't fill
|
|
71
|
+
// the row — otherwise `justify-content` has no effect.
|
|
72
|
+
.innerAlignEnd {
|
|
73
|
+
justify-content: flex-end;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.innerAlignCenter {
|
|
77
|
+
justify-content: center;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.innerAlignEnd .label,
|
|
81
|
+
.innerAlignCenter .label {
|
|
82
|
+
flex: 0 1 auto;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.label {
|
|
86
|
+
display: inline-flex;
|
|
87
|
+
align-items: center;
|
|
88
|
+
gap: var(--data-table-header-label-gap);
|
|
89
|
+
flex: 1 1 auto;
|
|
90
|
+
min-width: 0;
|
|
91
|
+
|
|
92
|
+
// Clip overflowing text instead of stretching the cell.
|
|
93
|
+
overflow: hidden;
|
|
94
|
+
text-overflow: ellipsis;
|
|
95
|
+
white-space: nowrap;
|
|
96
|
+
font-weight: var(--data-table-header-label-font-weight);
|
|
97
|
+
color: var(--data-table-header-label-fg);
|
|
98
|
+
cursor: default;
|
|
99
|
+
user-select: none;
|
|
100
|
+
|
|
101
|
+
&.sortable {
|
|
102
|
+
cursor: pointer;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
&.sortable:focus-visible {
|
|
106
|
+
@include focus-ring($offset: calc(-1 * var(--ring-offset)));
|
|
107
|
+
|
|
108
|
+
border-radius: var(--data-table-header-label-focus-radius);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Sort chevron — sits at the end of .inner, after the label. Rendered only
|
|
113
|
+
// when the column is sortable, so it can always carry the pointer cursor
|
|
114
|
+
// (matches the .label.sortable cursor: pointer treatment).
|
|
115
|
+
.sortIcon {
|
|
116
|
+
flex-shrink: 0;
|
|
117
|
+
color: var(--data-table-header-sort-icon-fg);
|
|
118
|
+
cursor: pointer;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.sortIconActive {
|
|
122
|
+
color: var(--data-table-header-sort-icon-fg-active);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Resize handle — absolutely positioned at the right edge of the cell so it
|
|
126
|
+
// never occupies flex space and is always at the exact cell boundary.
|
|
127
|
+
.resizeHandle {
|
|
128
|
+
position: absolute;
|
|
129
|
+
top: 0;
|
|
130
|
+
bottom: 0;
|
|
131
|
+
right: 0;
|
|
132
|
+
width: 24px;
|
|
133
|
+
cursor: col-resize;
|
|
134
|
+
display: flex;
|
|
135
|
+
align-items: center;
|
|
136
|
+
justify-content: center;
|
|
137
|
+
user-select: none;
|
|
138
|
+
opacity: var(--data-table-header-resize-handle-opacity-hidden);
|
|
139
|
+
transition: opacity var(--data-table-header-resize-handle-transition);
|
|
140
|
+
|
|
141
|
+
// Reveal when hovering anywhere on the header cell.
|
|
142
|
+
.headerCell:hover & {
|
|
143
|
+
opacity: var(--data-table-header-resize-handle-opacity-visible);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
&:focus-visible {
|
|
147
|
+
@include focus-ring($offset: calc(-1 * var(--ring-offset)));
|
|
148
|
+
|
|
149
|
+
opacity: var(--data-table-header-resize-handle-opacity-visible);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.resizeChevron {
|
|
154
|
+
width: 8px;
|
|
155
|
+
height: 8px;
|
|
156
|
+
color: var(--data-table-header-resize-chevron-fg);
|
|
157
|
+
flex-shrink: 0;
|
|
158
|
+
transition: color var(--data-table-header-resize-chevron-transition);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.resizeBar {
|
|
162
|
+
width: 1px;
|
|
163
|
+
height: 60%;
|
|
164
|
+
background: var(--data-table-header-resize-bar-bg);
|
|
165
|
+
flex-shrink: 0;
|
|
166
|
+
transition:
|
|
167
|
+
background var(--data-table-header-resize-bar-transition-bg),
|
|
168
|
+
width var(--data-table-header-resize-bar-transition-width);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Accent-colour the bar and chevrons when hovered or actively resizing.
|
|
172
|
+
.resizeHandle:hover .resizeBar,
|
|
173
|
+
.resizeBar.active {
|
|
174
|
+
background: var(--data-table-header-resize-bar-bg-active);
|
|
175
|
+
width: 2px;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.resizeHandle:hover .resizeChevron,
|
|
179
|
+
.resizeHandle:has(.resizeBar.active) .resizeChevron {
|
|
180
|
+
color: var(--data-table-header-resize-chevron-fg-active);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.dragging {
|
|
184
|
+
opacity: var(--data-table-header-dragging-opacity);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Pinned columns get sticky positioning via inline `left` / `right` styles;
|
|
188
|
+
// these class additions handle the background (otherwise body cells would
|
|
189
|
+
// scroll under transparent pinned headers) and the inside-edge shadow.
|
|
190
|
+
|
|
191
|
+
.pinnedLeft,
|
|
192
|
+
.pinnedRight {
|
|
193
|
+
// Solid background so unpinned content doesn't show through during scroll.
|
|
194
|
+
// Header cells use --color-table-header-bg (muted gray chrome) — match it
|
|
195
|
+
// here so the pinned corner cell blends with the rest of the header band.
|
|
196
|
+
background: var(--data-table-header-pinned-bg);
|
|
197
|
+
|
|
198
|
+
// Sticky pinned column header — the "corner" that stacks above:
|
|
199
|
+
// - Table's sticky-header band (z-index 1 per Table.module.scss)
|
|
200
|
+
// - Pinned body cells (z-index 1 per DataTable.module.scss)
|
|
201
|
+
// The :where() in Table.module.scss drops the header band's specificity to
|
|
202
|
+
// 0,1,0, so this z-index can override it via cascade order (DataTable's CSS
|
|
203
|
+
// module is imported later and wins on equal specificity).
|
|
204
|
+
z-index: 3;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.pinnedLeft {
|
|
208
|
+
// Inside-edge shadow on the right of left-pinned columns.
|
|
209
|
+
box-shadow: var(--data-table-header-pinned-shadow-left);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.pinnedRight {
|
|
213
|
+
// Mirror shadow on the left of right-pinned columns.
|
|
214
|
+
box-shadow: var(--data-table-header-pinned-shadow-right);
|
|
215
|
+
}
|
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
import { useId, useMemo, useRef, type KeyboardEvent } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import {
|
|
4
|
+
GripVertical,
|
|
5
|
+
ChevronUp,
|
|
6
|
+
ChevronDown,
|
|
7
|
+
ChevronsUpDown,
|
|
8
|
+
ChevronLeft,
|
|
9
|
+
ChevronRight,
|
|
10
|
+
} from 'lucide-react';
|
|
11
|
+
import { useSortable } from '@dnd-kit/sortable';
|
|
12
|
+
import { CSS } from '@dnd-kit/utilities';
|
|
13
|
+
import { Table } from '../Table';
|
|
14
|
+
import type { TableSortDirection } from '../Table';
|
|
15
|
+
import { useTranslation } from '../../i18n/useTranslation';
|
|
16
|
+
import { useResizeHandle } from './useResizeHandle';
|
|
17
|
+
import type { ColumnDef, DataTableInstance } from './types';
|
|
18
|
+
import { getPinStyle } from './pinStyle';
|
|
19
|
+
import { shiftVarName } from './columnShift';
|
|
20
|
+
|
|
21
|
+
import styles from './HeaderCell.module.scss';
|
|
22
|
+
|
|
23
|
+
export interface HeaderCellProps<T> {
|
|
24
|
+
column: ColumnDef<T>;
|
|
25
|
+
instance: DataTableInstance<T>;
|
|
26
|
+
/** Whole-column drag preview is enabled for this table. */
|
|
27
|
+
dragWholeColumn?: boolean;
|
|
28
|
+
/** A column drag is currently in progress. */
|
|
29
|
+
dragActive?: boolean;
|
|
30
|
+
/** Enables responsive-only header hooks and the dedicated keyboard resize handle. */
|
|
31
|
+
responsiveEnabled?: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Sortable header cell with a hover-revealed drag grip and a resize handle.
|
|
36
|
+
*
|
|
37
|
+
* - **Label area** is the sort click-target when `column.sortable === true`.
|
|
38
|
+
* - **Grip** appears on hover or keyboard focus; it's the drag handle wired
|
|
39
|
+
* to `@dnd-kit/sortable`'s `useSortable`. The grip is the ONLY draggable
|
|
40
|
+
* target — listeners are not attached to the cell or label, so clicking
|
|
41
|
+
* the label never starts a drag.
|
|
42
|
+
* - **Resize handle** is a 24px hit-zone on the right edge. Disabled when
|
|
43
|
+
* `column.enableResize === false`. By default, the sortable label keeps the
|
|
44
|
+
* legacy Arrow-key resize behavior and the pointer handle is not focusable.
|
|
45
|
+
* Responsive tables move Arrow-key resizing to the dedicated handle so CSS
|
|
46
|
+
* can remove that focus stop together with the handle when rows stack.
|
|
47
|
+
*/
|
|
48
|
+
/** See the `animateLayoutChanges` comment in HeaderCell. Module scope so the
|
|
49
|
+
* identity is stable across renders. */
|
|
50
|
+
const neverAnimateLayoutChanges = () => false;
|
|
51
|
+
|
|
52
|
+
const sortAriaMap: Record<TableSortDirection, 'ascending' | 'descending' | 'none'> = {
|
|
53
|
+
asc: 'ascending',
|
|
54
|
+
desc: 'descending',
|
|
55
|
+
none: 'none',
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export function HeaderCell<T>({
|
|
59
|
+
column,
|
|
60
|
+
instance,
|
|
61
|
+
dragWholeColumn,
|
|
62
|
+
dragActive,
|
|
63
|
+
responsiveEnabled,
|
|
64
|
+
}: HeaderCellProps<T>) {
|
|
65
|
+
// Pinned columns are LOCKED in position — no drag-to-reorder grip, can't
|
|
66
|
+
// be moved within or across pin groups. Sort and resize remain available
|
|
67
|
+
// since they don't change column position. Within-pin-group drag is also a
|
|
68
|
+
// low-value interaction (consumers typically pin once and leave it).
|
|
69
|
+
const isPinned =
|
|
70
|
+
instance.columnPinning.left.includes(column.id) ||
|
|
71
|
+
instance.columnPinning.right.includes(column.id);
|
|
72
|
+
const sortable = column.sortable === true;
|
|
73
|
+
// TWO separate questions, kept separate. `plainHeader` is a LAYOUT input —
|
|
74
|
+
// it drives `retainedResponsiveHeader` below and `data-responsive-plain-label`
|
|
75
|
+
// on the cell, which decide whether the compact strip hides the header or
|
|
76
|
+
// renders it as a padded block. Narrowing it for the naming fix flipped both
|
|
77
|
+
// for `header: ''`, so the playground's three row-actions columns rendered an
|
|
78
|
+
// empty padded block in the stacked strip instead of being hidden.
|
|
79
|
+
const plainHeader = typeof column.header === 'string';
|
|
80
|
+
// Whether the header actually renders TEXT, which is the naming question.
|
|
81
|
+
// `header: ''` is a string, so treating it as self-naming silently ignored
|
|
82
|
+
// the `visibilityLabel` beside it and pointed `aria-labelledby` at an empty
|
|
83
|
+
// span — an unnamed column header.
|
|
84
|
+
const rendersText = typeof column.header === 'string' && column.header.trim() !== '';
|
|
85
|
+
const retainedResponsiveHeader = sortable || !plainHeader;
|
|
86
|
+
const t = useTranslation();
|
|
87
|
+
// NO `column.id` fallback. It used to end here, so a column with neither a
|
|
88
|
+
// string header nor a `visibilityLabel` gave its grip the name "Drag to
|
|
89
|
+
// reorder starred_col" and its resize handle "Resize starred_col column" —
|
|
90
|
+
// a raw developer identifier read aloud to a keyboard user. Whether the
|
|
91
|
+
// `<th>` itself then inherits that through name-from-content is disputed
|
|
92
|
+
// (two reviewers measured Chromium and disagreed), but the CONTROLS speak it
|
|
93
|
+
// either way, so the identifier is removed at the source and the question
|
|
94
|
+
// stops mattering for the harmful part.
|
|
95
|
+
// `||`, not `??`: `visibilityLabel={col.title ?? ''}` is ordinary consumer
|
|
96
|
+
// code, and an empty one names the column no better than omitting it — it
|
|
97
|
+
// must not discard a perfectly usable string header and drop the grip and
|
|
98
|
+
// resize handle to the generic "this column" copy.
|
|
99
|
+
// `.trim()` on the header too, matching `rendersText` above and the other
|
|
100
|
+
// two readers of this prop: `header: ' '` renders no text, so accepting it
|
|
101
|
+
// named the resize handle "Resize column" (#536 follow-up). The predicate
|
|
102
|
+
// is repeated inline rather than reusing `rendersText`, because a boolean
|
|
103
|
+
// const does not narrow `column.header` from ReactNode to string.
|
|
104
|
+
const columnLabel =
|
|
105
|
+
column.visibilityLabel ||
|
|
106
|
+
(typeof column.header === 'string' && column.header.trim() ? column.header : undefined);
|
|
107
|
+
// The handle's own name has to describe the ACTION. It used to be the column
|
|
108
|
+
// label verbatim, so a keyboard user heard "Name, separator".
|
|
109
|
+
const resizeLabel = columnLabel
|
|
110
|
+
? t('dataTable.resizeColumn', { name: columnLabel })
|
|
111
|
+
: t('dataTable.resizeColumnUnnamed');
|
|
112
|
+
// The header's name comes from this id, not from its content. The resize
|
|
113
|
+
// handle is a named, focusable descendant of the <th>, so with
|
|
114
|
+
// name-from-content the header computed as "Name Name" at every width the
|
|
115
|
+
// moment `collapseBelow` was set (#500). Pointing at the label span excludes
|
|
116
|
+
// the handle and the drag grip without hiding either from AT.
|
|
117
|
+
const labelId = `${useId()}-label`;
|
|
118
|
+
const sortDir: TableSortDirection | undefined =
|
|
119
|
+
instance.sort?.columnId === column.id ? instance.sort.direction : sortable ? 'none' : undefined;
|
|
120
|
+
|
|
121
|
+
// Derive the visual sort icon to render in our own .inner layout (approach
|
|
122
|
+
// a): we do NOT pass sortDirection to Table.HeaderCell (to suppress its
|
|
123
|
+
// built-in inline icon). Instead we pass aria-sort directly and render the
|
|
124
|
+
// chevron ourselves at the end of the label area, just before the resize
|
|
125
|
+
// handle.
|
|
126
|
+
const SortIcon =
|
|
127
|
+
sortDir === 'asc' ? ChevronUp : sortDir === 'desc' ? ChevronDown : ChevronsUpDown;
|
|
128
|
+
|
|
129
|
+
// dnd-kit sortable — column is its own sortable item. Pinned columns are
|
|
130
|
+
// locked in place (see the isPinned comment above), and so is a LONE unpinned
|
|
131
|
+
// column: with no sibling in its band, `reorderRespectingPins` rejects every
|
|
132
|
+
// drop it could reach, so the drag clamp correctly pins it at zero travel. A
|
|
133
|
+
// grip that visibly does nothing is worse than no grip, so it hides for the
|
|
134
|
+
// same reason a pinned column's does.
|
|
135
|
+
const reorderable =
|
|
136
|
+
column.enableReorder !== false && !isPinned && instance.unpinnedColumns.length > 1;
|
|
137
|
+
|
|
138
|
+
const headerContent =
|
|
139
|
+
typeof column.header === 'function' ? column.header({ column, instance }) : column.header;
|
|
140
|
+
|
|
141
|
+
// Screen-reader announcements name the column by its RENDERED header text,
|
|
142
|
+
// not by `column.id` (#390). The ref goes on the label span rather than the
|
|
143
|
+
// <th> so the grip and resize chrome — and any menu the header renders —
|
|
144
|
+
// stay out of it. Ref identity is stable, so the memo never re-runs.
|
|
145
|
+
const labelRef = useRef<HTMLSpanElement | null>(null);
|
|
146
|
+
const dragData = useMemo(() => ({ dragNode: labelRef }), []);
|
|
147
|
+
|
|
148
|
+
// No DOM measurement. Seven versions of one tried to answer "will this span
|
|
149
|
+
// produce an accessible name?" without computing the accessible name, and
|
|
150
|
+
// each was wrong in a new way — the last three inside the commit meant to
|
|
151
|
+
// close the class. The mechanism existed to rescue ICON-ONLY headers.
|
|
152
|
+
//
|
|
153
|
+
// Precisely, because the first version of this note overstated it: before
|
|
154
|
+
// #500 the `<th>` carried no `aria-labelledby` and no `aria-label`, so it was
|
|
155
|
+
// named from CONTENT — which swept in the resize handle. An icon-only header
|
|
156
|
+
// therefore announced the handle's label, which was the bare `column.id`
|
|
157
|
+
// when the column had nothing better; the "Resize … column" wrapper came
|
|
158
|
+
// with #500 itself. A plain header announced its label twice. That second
|
|
159
|
+
// one IS #500. So the old
|
|
160
|
+
// name was not absent, it was the bug; and the only sources available for
|
|
161
|
+
// an icon-only header are `visibilityLabel`, `column.id`, or nothing.
|
|
162
|
+
// `column.id` is indefensible to speak, which leaves the author's label —
|
|
163
|
+
// and nothing when they have not given one.
|
|
164
|
+
//
|
|
165
|
+
// The rule is static, and `column.id` is spoken nowhere IN THIS CELL: not
|
|
166
|
+
// the header, not the grip, not the resize handle. Scoped deliberately —
|
|
167
|
+
// `ColumnVisibilityTrigger` still renders it as the visible label of a
|
|
168
|
+
// menu item for a ReactNode-header column with no `visibilityLabel`, which
|
|
169
|
+
// is a documented residual rather than an oversight, and the note this
|
|
170
|
+
// replaced existed precisely to flag surviving fallbacks. (An earlier scope
|
|
171
|
+
// note here said the handle still fell back to it. True when written, and
|
|
172
|
+
// falsified by the commit that removed the fallback — two commits after the
|
|
173
|
+
// doc-correction pass that was supposed to catch exactly this.)
|
|
174
|
+
//
|
|
175
|
+
// What an unnamed header then announces is MEASURED, not guessed: Chromium
|
|
176
|
+
// marks an `aria-labelledby` resolving to no text `invalid` and falls
|
|
177
|
+
// through to name-from-content, so the cell's own controls name it. That is
|
|
178
|
+
// why `header: ''` is special-cased below.
|
|
179
|
+
//
|
|
180
|
+
// Two residuals:
|
|
181
|
+
//
|
|
182
|
+
// 1. A ReactNode header that renders visible text AND sets
|
|
183
|
+
// `visibilityLabel` announces the label rather than the text. A WCAG
|
|
184
|
+
// 2.5.3 concern ONLY when `sortable` makes the label span a button —
|
|
185
|
+
// 2.5.3 is scoped to user interface components — and only a violation
|
|
186
|
+
// when the label does not CONTAIN the visible text: "Revenue (USD)"
|
|
187
|
+
// over `<strong>Revenue</strong>` passes, `'Status'` over
|
|
188
|
+
// `<Badge>Active</Badge>` does not.
|
|
189
|
+
// 2. A ReactNode header that names nothing, with no `visibilityLabel`,
|
|
190
|
+
// leaves an unnamed focusable `role="button"` when sortable — WCAG
|
|
191
|
+
// 4.1.2. Unfixable HERE because nothing static distinguishes it from a
|
|
192
|
+
// ReactNode that names itself. `header: ''` IS distinguishable and is
|
|
193
|
+
// fixed; an earlier version of this note said the whole case was
|
|
194
|
+
// unfixable "because the only remaining name source is `column.id`",
|
|
195
|
+
// which the fix for it disproved.
|
|
196
|
+
const namedByLabel = !rendersText && Boolean(column.visibilityLabel);
|
|
197
|
+
/** A string header that renders nothing — the one no-content case we can prove. */
|
|
198
|
+
const emptyStringHeader = plainHeader && !rendersText && !column.visibilityLabel;
|
|
199
|
+
// No dev warning here, deliberately. One was added and removed within the
|
|
200
|
+
// hour: having deleted the measurement, nothing static can distinguish a
|
|
201
|
+
// ReactNode header that names itself (`<strong>Revenue</strong>`) from one
|
|
202
|
+
// that names nothing (an icon), so it fired on the commonest VALID shape.
|
|
203
|
+
// A warning on correct code is the same defect as a gate that false-alarms,
|
|
204
|
+
// and this file's own history is the argument — noise gets ignored, and then
|
|
205
|
+
// the real case is ignored with it. The contract is documented in docs/components/DataTable.md
|
|
206
|
+
// instead, which is where a rule only the author can satisfy belongs.
|
|
207
|
+
|
|
208
|
+
const sortableResult = useSortable({
|
|
209
|
+
id: column.id,
|
|
210
|
+
data: dragData,
|
|
211
|
+
disabled: !reorderable,
|
|
212
|
+
// Whole-column mode only: kill dnd-kit's post-drop FLIP animation. On
|
|
213
|
+
// release `defaultAnimateLayoutChanges` returns true for every column whose
|
|
214
|
+
// index changed, so the headers would glide to their new positions over
|
|
215
|
+
// ~200ms while the body cells — whose shift variable is removed on the same
|
|
216
|
+
// tick — snap instantly. That is the exact header/body disagreement this
|
|
217
|
+
// feature exists to remove, just relocated to the drop. Snapping the header
|
|
218
|
+
// with the body is the only way the two stay glued.
|
|
219
|
+
//
|
|
220
|
+
// `undefined` when the mode is off, so that path keeps dnd-kit's default
|
|
221
|
+
// animation byte-for-byte.
|
|
222
|
+
animateLayoutChanges: dragWholeColumn === true ? neverAnimateLayoutChanges : undefined,
|
|
223
|
+
});
|
|
224
|
+
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = sortableResult;
|
|
225
|
+
|
|
226
|
+
const width = instance.columnSizesPx[column.id] ?? 120;
|
|
227
|
+
const resize = useResizeHandle({
|
|
228
|
+
initialWidth: width,
|
|
229
|
+
minWidth: column.minSize ?? 40,
|
|
230
|
+
maxWidth: column.maxSize,
|
|
231
|
+
onResize: (next) => {
|
|
232
|
+
instance.setColumnSizing((prev) => ({ ...prev, [column.id]: next }));
|
|
233
|
+
},
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
const onLabelKeyDown = (e: KeyboardEvent<HTMLSpanElement>) => {
|
|
237
|
+
// Sort cycle on Enter / Space (when sortable)
|
|
238
|
+
if (sortable && (e.key === 'Enter' || e.key === ' ')) {
|
|
239
|
+
e.preventDefault();
|
|
240
|
+
instance.toggleSort(column.id);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
if (!responsiveEnabled && column.enableResize !== false) onResizeKeyDown(e);
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const onResizeKeyDown = (e: KeyboardEvent<HTMLSpanElement>) => {
|
|
247
|
+
// Keyboard resize: ← / → for ±8px; Shift+← / Shift+→ for ±32px.
|
|
248
|
+
if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
|
|
249
|
+
e.preventDefault();
|
|
250
|
+
const step = (e.shiftKey ? 32 : 8) * (e.key === 'ArrowRight' ? 1 : -1);
|
|
251
|
+
const current = instance.columnSizesPx[column.id] ?? 120;
|
|
252
|
+
const minW = column.minSize ?? 40;
|
|
253
|
+
const maxW = column.maxSize;
|
|
254
|
+
let next = current + step;
|
|
255
|
+
if (next < minW) next = minW;
|
|
256
|
+
if (maxW != null && next > maxW) next = maxW;
|
|
257
|
+
instance.setColumnSizing((prev) => ({ ...prev, [column.id]: next }));
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
const pinStyle = getPinStyle(column.id, instance);
|
|
262
|
+
const stickyStyle = pinStyle.position
|
|
263
|
+
? { position: pinStyle.position, left: pinStyle.left, right: pinStyle.right }
|
|
264
|
+
: undefined;
|
|
265
|
+
// In whole-column mode the header rides the SAME custom property as its body
|
|
266
|
+
// cells, so the two cannot desync — that is the entire point of the feature.
|
|
267
|
+
// Pinned cells are excluded: a transform would break their position: sticky.
|
|
268
|
+
const useShiftVar = dragWholeColumn === true && dragActive === true && !isPinned;
|
|
269
|
+
const cellStyle = {
|
|
270
|
+
transform: useShiftVar
|
|
271
|
+
? `translateX(var(${shiftVarName(column.id)}, 0px))`
|
|
272
|
+
: CSS.Transform.toString(transform),
|
|
273
|
+
transition: useShiftVar ? undefined : transition,
|
|
274
|
+
...stickyStyle,
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
return (
|
|
278
|
+
// sortDirection is intentionally NOT passed to Table.HeaderCell — we suppress
|
|
279
|
+
// its built-in inline chevron and render our own at the end of .inner (between
|
|
280
|
+
// label and resize handle). aria-sort is set directly so the ARIA contract is
|
|
281
|
+
// preserved without the visual side-effect.
|
|
282
|
+
<Table.HeaderCell
|
|
283
|
+
align={column.align ?? 'start'}
|
|
284
|
+
// Addressable by column id so a drag can measure this cell's REAL
|
|
285
|
+
// rendered rect (see `measureDragRangeX`). Declared `<col>` widths are
|
|
286
|
+
// not a substitute — the table stretches past them to fill its wrap.
|
|
287
|
+
data-dt-column-id={column.id}
|
|
288
|
+
data-responsive-sortable={responsiveEnabled && sortable ? true : undefined}
|
|
289
|
+
data-responsive-control={responsiveEnabled && sortable ? true : undefined}
|
|
290
|
+
data-responsive-plain-label={responsiveEnabled && plainHeader ? true : undefined}
|
|
291
|
+
data-responsive-retained-header={
|
|
292
|
+
responsiveEnabled && retainedResponsiveHeader && !sortable ? true : undefined
|
|
293
|
+
}
|
|
294
|
+
data-responsive-pinned={responsiveEnabled && isPinned ? true : undefined}
|
|
295
|
+
aria-sort={sortDir != null ? sortAriaMap[sortDir] : undefined}
|
|
296
|
+
// #500's actual fix, and the only part of it that was ever in question:
|
|
297
|
+
// point at the label span so the resize handle is not concatenated into
|
|
298
|
+
// the name. `visibilityLabel` overrides it only for a ReactNode header,
|
|
299
|
+
// where the author has explicitly supplied the text they want spoken.
|
|
300
|
+
// `aria-labelledby` pointing at a span that resolves to no text is NOT a
|
|
301
|
+
// way to leave a header unnamed: Chromium marks that source `invalid`
|
|
302
|
+
// and hands naming back to CONTENTS, which in this cell means the drag
|
|
303
|
+
// grip and the resize handle. Measured off Chromium's own AX tree via
|
|
304
|
+
// CDP — and the reason three reviewers got three answers is that
|
|
305
|
+
// Playwright and jsdom each ship their own accname implementation, so
|
|
306
|
+
// `getByRole({ name })` does not measure the browser.
|
|
307
|
+
//
|
|
308
|
+
// Contents winning is CORRECT for a ReactNode that names itself, which
|
|
309
|
+
// is how a select-all checkbox header works. It is wrong only where we
|
|
310
|
+
// know statically there is no content to win with — `header: ''` — and
|
|
311
|
+
// there a `collapseBelow` table announced "200px", the resize handle's
|
|
312
|
+
// `aria-valuetext`, changing as the user dragged. That case takes an
|
|
313
|
+
// explicit name, which wins in every implementation and makes the fix
|
|
314
|
+
// engine-independent even though the bug was not.
|
|
315
|
+
//
|
|
316
|
+
// A ReactNode that names NOTHING is the residual: indistinguishable from
|
|
317
|
+
// one that names itself without the runtime measurement this component
|
|
318
|
+
// deleted, so it still falls to contents. Set `visibilityLabel`.
|
|
319
|
+
aria-labelledby={namedByLabel || emptyStringHeader ? undefined : labelId}
|
|
320
|
+
aria-label={
|
|
321
|
+
namedByLabel
|
|
322
|
+
? column.visibilityLabel
|
|
323
|
+
: emptyStringHeader
|
|
324
|
+
? t('dataTable.unlabelledColumn')
|
|
325
|
+
: undefined
|
|
326
|
+
}
|
|
327
|
+
onClick={sortable ? () => instance.toggleSort(column.id) : undefined}
|
|
328
|
+
className={clsx(
|
|
329
|
+
styles.headerCell,
|
|
330
|
+
isDragging && styles.dragging,
|
|
331
|
+
pinStyle.pinSide === 'left' && styles.pinnedLeft,
|
|
332
|
+
pinStyle.pinSide === 'right' && styles.pinnedRight,
|
|
333
|
+
)}
|
|
334
|
+
// HTMLTableCellElement extends HTMLElement; dnd-kit only reads DOM geometry from the ref.
|
|
335
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
336
|
+
ref={setNodeRef as any}
|
|
337
|
+
style={cellStyle}
|
|
338
|
+
>
|
|
339
|
+
{/* Grip pinned to absolute left of the cell regardless of column.align.
|
|
340
|
+
Kept outside .inner so it doesn't shift the content area. Only
|
|
341
|
+
rendered when reorderable. */}
|
|
342
|
+
{reorderable && (
|
|
343
|
+
<span
|
|
344
|
+
className={styles.grip}
|
|
345
|
+
data-responsive-drag-grip={responsiveEnabled || undefined}
|
|
346
|
+
// Spread BOTH attributes (aria/role) and listeners (pointerdown etc.)
|
|
347
|
+
{...attributes}
|
|
348
|
+
{...listeners}
|
|
349
|
+
aria-label={
|
|
350
|
+
columnLabel
|
|
351
|
+
? t('dataTable.dragReorder', { name: columnLabel })
|
|
352
|
+
: t('dataTable.dragReorderUnnamed')
|
|
353
|
+
}
|
|
354
|
+
// tabIndex so keyboard users can focus to reveal grip + activate drag
|
|
355
|
+
tabIndex={0}
|
|
356
|
+
// Stop sort click from misfiring when the user clicks the grip without moving.
|
|
357
|
+
onClick={(e) => e.stopPropagation()}
|
|
358
|
+
>
|
|
359
|
+
<GripVertical size={14} aria-hidden="true" />
|
|
360
|
+
</span>
|
|
361
|
+
)}
|
|
362
|
+
|
|
363
|
+
{/* Content area: label (flex:1) + sort icon pinned to end of content.
|
|
364
|
+
Padding is conditional: only reserve grip space (left) when reorderable
|
|
365
|
+
and only reserve resize space (right) when resizable, so the header
|
|
366
|
+
label aligns with the body cell content when the surrounding chrome
|
|
367
|
+
isn't there. Flex justification mirrors `column.align` so end-aligned
|
|
368
|
+
and center-aligned columns position their label + sort indicator the
|
|
369
|
+
same way the body cells render. */}
|
|
370
|
+
<div
|
|
371
|
+
data-responsive-header-content={responsiveEnabled || undefined}
|
|
372
|
+
className={clsx(
|
|
373
|
+
styles.inner,
|
|
374
|
+
column.enableResize !== false && styles.innerWithResize,
|
|
375
|
+
column.align === 'end' && styles.innerAlignEnd,
|
|
376
|
+
column.align === 'center' && styles.innerAlignCenter,
|
|
377
|
+
)}
|
|
378
|
+
>
|
|
379
|
+
<span
|
|
380
|
+
ref={labelRef}
|
|
381
|
+
id={labelId}
|
|
382
|
+
className={clsx(styles.label, sortable && styles.sortable)}
|
|
383
|
+
tabIndex={sortable ? 0 : undefined}
|
|
384
|
+
role={sortable ? 'button' : undefined}
|
|
385
|
+
// The span is a focusable button when sortable, so it needs a name of
|
|
386
|
+
// its own on the one path where its content supplies none. Mirrors
|
|
387
|
+
// the plain-text case, where the <th> and this button both take the
|
|
388
|
+
// header text.
|
|
389
|
+
aria-label={
|
|
390
|
+
sortable && namedByLabel
|
|
391
|
+
? column.visibilityLabel
|
|
392
|
+
: sortable && emptyStringHeader
|
|
393
|
+
? t('dataTable.unlabelledColumn')
|
|
394
|
+
: undefined
|
|
395
|
+
}
|
|
396
|
+
onKeyDown={onLabelKeyDown}
|
|
397
|
+
>
|
|
398
|
+
{headerContent}
|
|
399
|
+
</span>
|
|
400
|
+
{/* Sort chevron always at end of content area — aria-hidden because
|
|
401
|
+
aria-sort on the <th> carries the semantic signal. */}
|
|
402
|
+
{sortDir != null && (
|
|
403
|
+
<SortIcon
|
|
404
|
+
size={12}
|
|
405
|
+
aria-hidden="true"
|
|
406
|
+
className={clsx(styles.sortIcon, sortDir !== 'none' && styles.sortIconActive)}
|
|
407
|
+
/>
|
|
408
|
+
)}
|
|
409
|
+
</div>
|
|
410
|
+
|
|
411
|
+
{/* Resize handle pinned to absolute right — outside .inner so it
|
|
412
|
+
doesn't consume flex space and stays at the exact cell edge. */}
|
|
413
|
+
{column.enableResize !== false && (
|
|
414
|
+
<span
|
|
415
|
+
className={styles.resizeHandle}
|
|
416
|
+
data-responsive-resize-handle={responsiveEnabled || undefined}
|
|
417
|
+
onPointerDown={resize.onPointerDown}
|
|
418
|
+
onKeyDown={responsiveEnabled ? onResizeKeyDown : undefined}
|
|
419
|
+
// Stop sort click when interacting with resize.
|
|
420
|
+
onClick={(e) => e.stopPropagation()}
|
|
421
|
+
role={responsiveEnabled ? 'separator' : undefined}
|
|
422
|
+
aria-label={responsiveEnabled ? resizeLabel : undefined}
|
|
423
|
+
aria-hidden={responsiveEnabled ? undefined : true}
|
|
424
|
+
aria-orientation={responsiveEnabled ? 'vertical' : undefined}
|
|
425
|
+
aria-valuemin={responsiveEnabled ? (column.minSize ?? 40) : undefined}
|
|
426
|
+
aria-valuemax={
|
|
427
|
+
responsiveEnabled ? (column.maxSize ?? Number.MAX_SAFE_INTEGER) : undefined
|
|
428
|
+
}
|
|
429
|
+
aria-valuenow={responsiveEnabled ? width : undefined}
|
|
430
|
+
aria-valuetext={responsiveEnabled ? `${width}px` : undefined}
|
|
431
|
+
tabIndex={responsiveEnabled ? 0 : undefined}
|
|
432
|
+
>
|
|
433
|
+
<ChevronLeft className={styles.resizeChevron} aria-hidden="true" />
|
|
434
|
+
<span className={clsx(styles.resizeBar, resize.isResizing && styles.active)} />
|
|
435
|
+
<ChevronRight className={styles.resizeChevron} aria-hidden="true" />
|
|
436
|
+
</span>
|
|
437
|
+
)}
|
|
438
|
+
</Table.HeaderCell>
|
|
439
|
+
);
|
|
440
|
+
}
|