@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,216 @@
|
|
|
1
|
+
import { useRef, type RefObject } from 'react';
|
|
2
|
+
import { useDndMonitor } from '@dnd-kit/core';
|
|
3
|
+
import { clampX, computeColumnShifts, shiftVarName, type DragRangeX } from './columnShift';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Measure how far the active column may travel, in px, from the REAL rendered
|
|
7
|
+
* geometry of the header cells inside `root`.
|
|
8
|
+
*
|
|
9
|
+
* Declared widths (`columnSizingPx` / the `<col>` elements) cannot be used for
|
|
10
|
+
* this. `DataTable.module.scss` sets `table-layout: fixed; width: max-content;
|
|
11
|
+
* min-width: 100%`, so whenever the column sum is narrower than the scroll wrap
|
|
12
|
+
* the table stretches and every rendered column is WIDER than declared. Summing
|
|
13
|
+
* declared widths then under-reports the travel and makes the last slot
|
|
14
|
+
* unreachable — the exact regression this replaced.
|
|
15
|
+
*
|
|
16
|
+
* The bound is the unpinned band, not the table: pinned columns are excluded
|
|
17
|
+
* from reordering and `reorderRespectingPins` rejects a drop across a pin
|
|
18
|
+
* boundary, so travelling over a pin would take the column somewhere it can
|
|
19
|
+
* never land. `orderedIds` is therefore the unpinned columns only.
|
|
20
|
+
*
|
|
21
|
+
* All three rects are read in the same instant from the same scrolling
|
|
22
|
+
* container, so the differences are correct table-space offsets no matter where
|
|
23
|
+
* the wrap happens to be scrolled.
|
|
24
|
+
*
|
|
25
|
+
* Returns a zeroed range (pin in place) when `root` or any of the three header
|
|
26
|
+
* cells cannot be found — an unmeasurable drag must not be an unbounded one.
|
|
27
|
+
*/
|
|
28
|
+
export function measureDragRangeX(
|
|
29
|
+
root: HTMLElement | null,
|
|
30
|
+
orderedIds: string[],
|
|
31
|
+
activeId: string,
|
|
32
|
+
): DragRangeX {
|
|
33
|
+
const zero = { min: 0, max: 0 };
|
|
34
|
+
if (!root || orderedIds.length === 0) return zero;
|
|
35
|
+
|
|
36
|
+
// Column ids are consumer-supplied and routinely contain dots, spaces, or
|
|
37
|
+
// non-ASCII text — CSS.escape is what keeps them legal in a selector.
|
|
38
|
+
const rectOf = (id: string) =>
|
|
39
|
+
root.querySelector(`th[data-dt-column-id=${CSS.escape(id)}]`)?.getBoundingClientRect();
|
|
40
|
+
|
|
41
|
+
const active = rectOf(activeId);
|
|
42
|
+
const first = rectOf(orderedIds[0]);
|
|
43
|
+
const last = rectOf(orderedIds[orderedIds.length - 1]);
|
|
44
|
+
if (!active || !first || !last) return zero;
|
|
45
|
+
|
|
46
|
+
return { min: first.left - active.left, max: last.right - active.right };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Write one custom property per shifted column onto `root`, and remove the
|
|
51
|
+
* properties for any column that shifted on the previous frame but not this
|
|
52
|
+
* one. Returns the ids written, to be passed back as `previousIds` next frame.
|
|
53
|
+
*
|
|
54
|
+
* Custom properties are set on the table element, NOT a transform — a
|
|
55
|
+
* transformed ancestor would establish a containing block and break
|
|
56
|
+
* `position: sticky` on pinned cells. Variables inherit harmlessly.
|
|
57
|
+
*/
|
|
58
|
+
export function applyColumnShifts(
|
|
59
|
+
root: HTMLElement | null,
|
|
60
|
+
shifts: Record<string, number>,
|
|
61
|
+
previousIds: string[],
|
|
62
|
+
): string[] {
|
|
63
|
+
if (!root) return [];
|
|
64
|
+
|
|
65
|
+
for (const id of previousIds) {
|
|
66
|
+
if (!(id in shifts)) root.style.removeProperty(shiftVarName(id));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const written: string[] = [];
|
|
70
|
+
for (const [id, px] of Object.entries(shifts)) {
|
|
71
|
+
// Round: sub-pixel precision is invisible and would rewrite the style
|
|
72
|
+
// attribute on every pointer event for no visual gain.
|
|
73
|
+
root.style.setProperty(shiftVarName(id), `${Math.round(px)}px`);
|
|
74
|
+
written.push(id);
|
|
75
|
+
}
|
|
76
|
+
return written;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Inputs for {@link useColumnDragShift}. */
|
|
80
|
+
export interface ColumnDragShiftArgs {
|
|
81
|
+
/** The `<table>` element the custom properties are written to. */
|
|
82
|
+
rootRef: RefObject<HTMLElement | null>;
|
|
83
|
+
/** False when `dragWholeColumn` is off — the hook then does nothing. */
|
|
84
|
+
enabled: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* ALL unpinned column ids in current visual order — including columns with
|
|
87
|
+
* `enableReorder: false`. Do NOT filter by reorderability: a non-reorderable
|
|
88
|
+
* column cannot be *picked up*, but it is still displaced when a reorderable
|
|
89
|
+
* column is dragged past it (and the drop moves it for real). Omit it and it
|
|
90
|
+
* never shifts, so it and its neighbour render on top of each other.
|
|
91
|
+
*/
|
|
92
|
+
orderedIds: string[];
|
|
93
|
+
/** Rendered width per column id, px. */
|
|
94
|
+
widths: Record<string, number>;
|
|
95
|
+
/**
|
|
96
|
+
* Caller-owned slot for the travel range measured at drag start, so the
|
|
97
|
+
* `DndContext` modifier (which lives in the PARENT of this hook and therefore
|
|
98
|
+
* cannot read a return value from it) clamps against the same numbers.
|
|
99
|
+
* Written on drag start, nulled on drag end/cancel.
|
|
100
|
+
*/
|
|
101
|
+
dragRangeRef: RefObject<DragRangeX | null>;
|
|
102
|
+
/**
|
|
103
|
+
* Caller-owned slot for the last member of `orderedIds` this drag resolved as
|
|
104
|
+
* its target, or null before it resolves one. Written here — nulled at drag
|
|
105
|
+
* start, set on every `onDragOver` whose target is in the band — and read
|
|
106
|
+
* both here, to keep the displaced neighbours parked when dnd-kit hands over
|
|
107
|
+
* something the drop cannot use, and by the drop handler in the parent — but
|
|
108
|
+
* there only in whole-column mode, where this ref IS the preview. The
|
|
109
|
+
* header-only path has its own preview (dnd-kit's strategy), which retracts
|
|
110
|
+
* in exactly this situation, so it discards instead. See the `lastSlotIdRef`
|
|
111
|
+
* comment in `DataTable` for what "cannot use" covers.
|
|
112
|
+
*/
|
|
113
|
+
lastSlotIdRef: RefObject<string | null>;
|
|
114
|
+
/** Called once at drag start (true) and once at drag end/cancel (false). */
|
|
115
|
+
onDragActiveChange: (active: boolean) => void;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Subscribes to the surrounding `DndContext` and publishes per-column drag
|
|
120
|
+
* offsets as CSS custom properties on the table element.
|
|
121
|
+
*
|
|
122
|
+
* MUST be called from a component rendered inside `<DndContext>`. Mount it in
|
|
123
|
+
* a leaf that renders `null`, never in `DataTable` itself — `useDndMonitor`'s
|
|
124
|
+
* callbacks fire on every pointer move, and keeping them in a leaf guarantees
|
|
125
|
+
* the table body is never re-rendered mid-drag.
|
|
126
|
+
*/
|
|
127
|
+
export function useColumnDragShift({
|
|
128
|
+
rootRef,
|
|
129
|
+
enabled,
|
|
130
|
+
orderedIds,
|
|
131
|
+
widths,
|
|
132
|
+
dragRangeRef,
|
|
133
|
+
lastSlotIdRef,
|
|
134
|
+
onDragActiveChange,
|
|
135
|
+
}: ColumnDragShiftArgs): void {
|
|
136
|
+
const writtenRef = useRef<string[]>([]);
|
|
137
|
+
|
|
138
|
+
const clear = () => {
|
|
139
|
+
writtenRef.current = applyColumnShifts(rootRef.current, {}, writtenRef.current);
|
|
140
|
+
dragRangeRef.current = null;
|
|
141
|
+
onDragActiveChange(false);
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
useDndMonitor({
|
|
145
|
+
onDragStart(event) {
|
|
146
|
+
// Measured even when `enabled` is false: the header-only path does not
|
|
147
|
+
// use this hook's shift variables, but its DndContext modifier reads the
|
|
148
|
+
// very same range out of `dragRangeRef`.
|
|
149
|
+
dragRangeRef.current = measureDragRangeX(
|
|
150
|
+
rootRef.current,
|
|
151
|
+
orderedIds,
|
|
152
|
+
String(event.active.id),
|
|
153
|
+
);
|
|
154
|
+
// Ungated deliberately, even though only the whole-column path reads it:
|
|
155
|
+
// `dragWholeColumn` can be flipped between drags, so a clear that ran
|
|
156
|
+
// only while enabled would leave a stale target behind for the first
|
|
157
|
+
// drag after it is switched back on. Cleared at drag START rather than
|
|
158
|
+
// at drag end so one drag can never inherit the previous drag's target,
|
|
159
|
+
// and so the drop handler is free to read it without depending on which
|
|
160
|
+
// of dnd-kit's two end callbacks runs first.
|
|
161
|
+
lastSlotIdRef.current = null;
|
|
162
|
+
if (!enabled) return;
|
|
163
|
+
onDragActiveChange(true);
|
|
164
|
+
},
|
|
165
|
+
onDragOver(event) {
|
|
166
|
+
// Band members only. A pinned column is a live droppable (dnd-kit's
|
|
167
|
+
// boolean `disabled` stands down the draggable alone) and, being sticky,
|
|
168
|
+
// it covers the band's last columns on a scrolled table — so it wins
|
|
169
|
+
// collisions it can never accept a drop from.
|
|
170
|
+
const id = event.over ? String(event.over.id) : null;
|
|
171
|
+
if (id != null && orderedIds.includes(id)) lastSlotIdRef.current = id;
|
|
172
|
+
},
|
|
173
|
+
onDragMove(event) {
|
|
174
|
+
if (!enabled) return;
|
|
175
|
+
const shifts = computeColumnShifts({
|
|
176
|
+
orderedIds,
|
|
177
|
+
activeId: String(event.active.id),
|
|
178
|
+
// #383: the last BAND slot, which is `over` itself whenever `over` is
|
|
179
|
+
// one — `onDragOver` above has already recorded it. Reading `event.over`
|
|
180
|
+
// raw is what used to collapse the preview: `computeColumnShifts` finds
|
|
181
|
+
// no index for an out-of-band id, returns the active column's offset
|
|
182
|
+
// alone, and every displaced neighbour snaps back, leaving the dragged
|
|
183
|
+
// column overlapping the slot it is about to take. The drop commits
|
|
184
|
+
// this same id, so preview and commit cannot disagree.
|
|
185
|
+
overId: lastSlotIdRef.current,
|
|
186
|
+
widths,
|
|
187
|
+
// Clamping HERE, not only in the modifier, is what actually bounds the
|
|
188
|
+
// column. dnd-kit computes `delta` as
|
|
189
|
+
// `scrollAdjustedTranslate = add(modifiedTranslate, scrollAdjustment)`
|
|
190
|
+
// — the scroll adjustment is added AFTER modifiers run, so a
|
|
191
|
+
// modifier-only clamp is escaped by horizontal auto-scroll. Worse, it
|
|
192
|
+
// ran away: the translated header inflated `scrollWidth`, which let
|
|
193
|
+
// `scrollLeft` grow, which grew `scrollAdjustment`. `delta` is the
|
|
194
|
+
// post-adjustment value, so clamping it is authoritative and the
|
|
195
|
+
// feedback loop cannot start.
|
|
196
|
+
// Fail CLOSED: an unmeasurable drag is a pinned one, never an
|
|
197
|
+
// unbounded one. Unreachable today (onDragStart always sets the ref)
|
|
198
|
+
// but the `??` keeps the guarantee if that ever stops being true.
|
|
199
|
+
deltaX: clampX(event.delta.x, dragRangeRef.current ?? { min: 0, max: 0 }),
|
|
200
|
+
});
|
|
201
|
+
writtenRef.current = applyColumnShifts(rootRef.current, shifts, writtenRef.current);
|
|
202
|
+
},
|
|
203
|
+
// Deliberately ungated (unlike onDragStart/onDragMove above): `enabled`
|
|
204
|
+
// can flip to false mid-drag, and if cleanup were also gated the
|
|
205
|
+
// properties written at drag start would never be removed and
|
|
206
|
+
// onDragActiveChange(false) would never fire — the table would be stuck
|
|
207
|
+
// showing a shifted column. clear() is harmless as a no-op when nothing
|
|
208
|
+
// was written, so running it unconditionally is always safe.
|
|
209
|
+
onDragEnd() {
|
|
210
|
+
clear();
|
|
211
|
+
},
|
|
212
|
+
onDragCancel() {
|
|
213
|
+
clear();
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
}
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
|
2
|
+
import { useControllableState } from '../_internal/useControllableState';
|
|
3
|
+
import type {
|
|
4
|
+
ColumnOrderState,
|
|
5
|
+
ColumnPinningState,
|
|
6
|
+
ColumnSizingState,
|
|
7
|
+
ColumnVisibilityState,
|
|
8
|
+
DataTableInstance,
|
|
9
|
+
ExpandedRowsState,
|
|
10
|
+
RowSelectionState,
|
|
11
|
+
SortState,
|
|
12
|
+
UseDataTableOptions,
|
|
13
|
+
} from './types';
|
|
14
|
+
|
|
15
|
+
const EMPTY_PINNING: ColumnPinningState = { left: [], right: [] };
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Headless state machine for `<DataTable>`. Implements the Radix-style
|
|
19
|
+
* controlled/uncontrolled pattern for every state piece. Returns an
|
|
20
|
+
* `instance` object passed into `<DataTable instance={...} />` and any
|
|
21
|
+
* companion components (e.g. `<DataTable.ColumnVisibilityTrigger>`).
|
|
22
|
+
*
|
|
23
|
+
* Pure logic — no DOM, no refs to elements, no side effects beyond firing
|
|
24
|
+
* the consumer's onChange callbacks.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* const instance = useDataTable<Deal>({
|
|
28
|
+
* data,
|
|
29
|
+
* columns,
|
|
30
|
+
* getRowId: (r) => r.id,
|
|
31
|
+
* sort,
|
|
32
|
+
* onSortChange: setSort,
|
|
33
|
+
* });
|
|
34
|
+
* <DataTable instance={instance} aria-label="Deals" />
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* // With row selection and column visibility:
|
|
38
|
+
* const instance = useDataTable<Deal>({
|
|
39
|
+
* data,
|
|
40
|
+
* columns,
|
|
41
|
+
* getRowId: (r) => r.id,
|
|
42
|
+
* enableRowSelection: true,
|
|
43
|
+
* onRowSelectionChange: setRowSelection,
|
|
44
|
+
* });
|
|
45
|
+
* <Cluster justify="end">
|
|
46
|
+
* <ColumnVisibilityTrigger instance={instance} />
|
|
47
|
+
* </Cluster>
|
|
48
|
+
* <DataTable instance={instance} aria-label="Deals" />
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* // Fully controlled column order + sizing (e.g. persisted to localStorage):
|
|
52
|
+
* const instance = useDataTable<Deal>({
|
|
53
|
+
* data,
|
|
54
|
+
* columns,
|
|
55
|
+
* getRowId: (r) => r.id,
|
|
56
|
+
* columnOrder: savedOrder,
|
|
57
|
+
* onColumnOrderChange: setSavedOrder,
|
|
58
|
+
* columnSizing: savedSizing,
|
|
59
|
+
* onColumnSizingChange: setSavedSizing,
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* @remarks When NOT to use
|
|
63
|
+
* - For a read-only static table — use `<Table>` directly. `useDataTable`
|
|
64
|
+
* adds overhead you don't need when there's no column or row interactivity.
|
|
65
|
+
*
|
|
66
|
+
* @remarks Anti-patterns
|
|
67
|
+
* - ❌ Passing both `value` and `defaultValue` for the same state piece — `value`
|
|
68
|
+
* wins and `defaultValue` is silently ignored. Pick one.
|
|
69
|
+
* - ❌ Mutating `columns` identity across renders. The hook captures
|
|
70
|
+
* `defaultColumnOrder` from `columns` once at mount; later identity changes
|
|
71
|
+
* don't trigger a re-derive. Pass a stable reference (`useMemo` or module-level).
|
|
72
|
+
* - ❌ Client-sorting `data` AND passing controlled `sort`. DataTable is
|
|
73
|
+
* server-driven — `data` must be the pre-sorted slice the server returned.
|
|
74
|
+
*/
|
|
75
|
+
export function useDataTable<T>(options: UseDataTableOptions<T>): DataTableInstance<T> {
|
|
76
|
+
const {
|
|
77
|
+
data,
|
|
78
|
+
pinnedRows = [],
|
|
79
|
+
columns,
|
|
80
|
+
getRowId,
|
|
81
|
+
rowCount,
|
|
82
|
+
enableRowSelection = false,
|
|
83
|
+
onRowClick,
|
|
84
|
+
renderExpandedRow,
|
|
85
|
+
} = options;
|
|
86
|
+
|
|
87
|
+
const defaultColumnOrder = useMemo(
|
|
88
|
+
() => options.defaultColumnOrder ?? columns.map((c) => c.id),
|
|
89
|
+
// Intentionally not depending on `columns` — defaultColumnOrder is a
|
|
90
|
+
// one-time initial value. If columns change identity, consumer must
|
|
91
|
+
// pass a controlled columnOrder.
|
|
92
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
93
|
+
[],
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
// Initial pinning derived from `ColumnDef.pin` when the consumer didn't
|
|
97
|
+
// pass `defaultColumnPinning`. Like `defaultColumnOrder`, this is a one-time
|
|
98
|
+
// initial value — after mount, runtime calls to `instance.pinColumn(...)`
|
|
99
|
+
// update the controllable state and take over. Columns with
|
|
100
|
+
// `enablePin: false` are skipped — a column that opted out of pinning
|
|
101
|
+
// shouldn't be pinned by its own `pin` field either.
|
|
102
|
+
const derivedColumnPinning = useMemo<ColumnPinningState>(
|
|
103
|
+
() => {
|
|
104
|
+
const left: string[] = [];
|
|
105
|
+
const right: string[] = [];
|
|
106
|
+
for (const c of columns) {
|
|
107
|
+
if (c.enablePin === false) continue;
|
|
108
|
+
if (c.pin === 'left') left.push(c.id);
|
|
109
|
+
else if (c.pin === 'right') right.push(c.id);
|
|
110
|
+
}
|
|
111
|
+
return left.length === 0 && right.length === 0 ? EMPTY_PINNING : { left, right };
|
|
112
|
+
},
|
|
113
|
+
// Same one-time-init rationale as defaultColumnOrder.
|
|
114
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
115
|
+
[],
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
const [columnOrder, setColumnOrder] = useControllableState<ColumnOrderState>({
|
|
119
|
+
value: options.columnOrder,
|
|
120
|
+
defaultValue: defaultColumnOrder,
|
|
121
|
+
onChange: options.onColumnOrderChange,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const [columnSizing, setColumnSizing] = useControllableState<ColumnSizingState>({
|
|
125
|
+
value: options.columnSizing,
|
|
126
|
+
defaultValue: options.defaultColumnSizing ?? {},
|
|
127
|
+
onChange: options.onColumnSizingChange,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const [columnVisibility, setColumnVisibility] = useControllableState<ColumnVisibilityState>({
|
|
131
|
+
value: options.columnVisibility,
|
|
132
|
+
defaultValue: options.defaultColumnVisibility ?? {},
|
|
133
|
+
onChange: options.onColumnVisibilityChange,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const [columnPinning, setColumnPinning] = useControllableState<ColumnPinningState>({
|
|
137
|
+
value: options.columnPinning,
|
|
138
|
+
defaultValue: options.defaultColumnPinning ?? derivedColumnPinning,
|
|
139
|
+
onChange: options.onColumnPinningChange,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const [rowSelection, setRowSelection] = useControllableState<RowSelectionState>({
|
|
143
|
+
value: options.rowSelection,
|
|
144
|
+
defaultValue: options.defaultRowSelection ?? {},
|
|
145
|
+
onChange: options.onRowSelectionChange,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const [expandedRows, setExpandedRows] = useControllableState<ExpandedRowsState>({
|
|
149
|
+
value: options.expandedRows,
|
|
150
|
+
defaultValue: options.defaultExpandedRows ?? {},
|
|
151
|
+
onChange: options.onExpandedRowsChange,
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const [sort, setSort] = useControllableState<SortState | null>({
|
|
155
|
+
value: options.sort,
|
|
156
|
+
defaultValue: options.defaultSort ?? null,
|
|
157
|
+
onChange: options.onSortChange,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const DEFAULT_COL_WIDTH = 120;
|
|
161
|
+
|
|
162
|
+
const columnsById = useMemo(() => {
|
|
163
|
+
const m = new Map<string, (typeof columns)[number]>();
|
|
164
|
+
for (const c of columns) m.set(c.id, c);
|
|
165
|
+
return m;
|
|
166
|
+
}, [columns]);
|
|
167
|
+
|
|
168
|
+
// columnSizesPx: id → resolved width (sizing state > ColumnDef.size > default)
|
|
169
|
+
const columnSizesPx = useMemo<Record<string, number>>(() => {
|
|
170
|
+
const out: Record<string, number> = {};
|
|
171
|
+
for (const c of columns) {
|
|
172
|
+
out[c.id] = columnSizing[c.id] ?? c.size ?? DEFAULT_COL_WIDTH;
|
|
173
|
+
}
|
|
174
|
+
return out;
|
|
175
|
+
}, [columns, columnSizing]);
|
|
176
|
+
|
|
177
|
+
// visibleColumns: ordered (per columnOrder) and filtered (visibility !== false)
|
|
178
|
+
const visibleColumns = useMemo(() => {
|
|
179
|
+
const isVisible = (id: string) => columnVisibility[id] !== false;
|
|
180
|
+
const ordered: typeof columns = [];
|
|
181
|
+
for (const id of columnOrder) {
|
|
182
|
+
const col = columnsById.get(id);
|
|
183
|
+
if (col && isVisible(id)) ordered.push(col);
|
|
184
|
+
}
|
|
185
|
+
// Any column not in columnOrder (e.g. added after init) goes to the end.
|
|
186
|
+
for (const c of columns) {
|
|
187
|
+
if (!columnOrder.includes(c.id) && isVisible(c.id)) ordered.push(c);
|
|
188
|
+
}
|
|
189
|
+
return ordered;
|
|
190
|
+
}, [columns, columnsById, columnOrder, columnVisibility]);
|
|
191
|
+
|
|
192
|
+
// Pin grouping. Pinning order within a side is given by columnPinning.left/right.
|
|
193
|
+
const leftPinnedColumns = useMemo(
|
|
194
|
+
() =>
|
|
195
|
+
columnPinning.left
|
|
196
|
+
.map((id) => columnsById.get(id))
|
|
197
|
+
.filter((c): c is (typeof columns)[number] => !!c && columnVisibility[c.id] !== false),
|
|
198
|
+
[columnPinning.left, columnsById, columnVisibility],
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
const rightPinnedColumns = useMemo(
|
|
202
|
+
() =>
|
|
203
|
+
columnPinning.right
|
|
204
|
+
.map((id) => columnsById.get(id))
|
|
205
|
+
.filter((c): c is (typeof columns)[number] => !!c && columnVisibility[c.id] !== false),
|
|
206
|
+
[columnPinning.right, columnsById, columnVisibility],
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
const unpinnedColumns = useMemo(() => {
|
|
210
|
+
const pinned = new Set([...columnPinning.left, ...columnPinning.right]);
|
|
211
|
+
return visibleColumns.filter((c) => !pinned.has(c.id));
|
|
212
|
+
}, [visibleColumns, columnPinning.left, columnPinning.right]);
|
|
213
|
+
|
|
214
|
+
// Pin offsets — cumulative widths from the pinned edge inward.
|
|
215
|
+
const leftPinOffsets = useMemo<Record<string, number>>(() => {
|
|
216
|
+
const out: Record<string, number> = {};
|
|
217
|
+
let acc = 0;
|
|
218
|
+
for (const col of leftPinnedColumns) {
|
|
219
|
+
out[col.id] = acc;
|
|
220
|
+
acc += columnSizesPx[col.id] ?? DEFAULT_COL_WIDTH;
|
|
221
|
+
}
|
|
222
|
+
return out;
|
|
223
|
+
}, [leftPinnedColumns, columnSizesPx]);
|
|
224
|
+
|
|
225
|
+
const rightPinOffsets = useMemo<Record<string, number>>(() => {
|
|
226
|
+
const out: Record<string, number> = {};
|
|
227
|
+
let acc = 0;
|
|
228
|
+
// Rightmost pinned column has offset 0; walk right-to-left accumulating.
|
|
229
|
+
for (let i = rightPinnedColumns.length - 1; i >= 0; i--) {
|
|
230
|
+
const col = rightPinnedColumns[i]!;
|
|
231
|
+
out[col.id] = acc;
|
|
232
|
+
acc += columnSizesPx[col.id] ?? DEFAULT_COL_WIDTH;
|
|
233
|
+
}
|
|
234
|
+
return out;
|
|
235
|
+
}, [rightPinnedColumns, columnSizesPx]);
|
|
236
|
+
|
|
237
|
+
const toggleRowSelection = useCallback(
|
|
238
|
+
(rowId: string) => {
|
|
239
|
+
setRowSelection((prev) => {
|
|
240
|
+
const next = { ...prev };
|
|
241
|
+
if (next[rowId]) delete next[rowId];
|
|
242
|
+
else next[rowId] = true;
|
|
243
|
+
return next;
|
|
244
|
+
});
|
|
245
|
+
},
|
|
246
|
+
[setRowSelection],
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
const toggleAllOnPage = useCallback(() => {
|
|
250
|
+
setRowSelection((prev) => {
|
|
251
|
+
const pageIds = data.map(getRowId);
|
|
252
|
+
const allSelected = pageIds.every((id) => prev[id]);
|
|
253
|
+
if (allSelected) {
|
|
254
|
+
const next = { ...prev };
|
|
255
|
+
for (const id of pageIds) delete next[id];
|
|
256
|
+
return next;
|
|
257
|
+
}
|
|
258
|
+
const next = { ...prev };
|
|
259
|
+
for (const id of pageIds) next[id] = true;
|
|
260
|
+
return next;
|
|
261
|
+
});
|
|
262
|
+
}, [data, getRowId, setRowSelection]);
|
|
263
|
+
|
|
264
|
+
const isAllOnPageSelected = useCallback(() => {
|
|
265
|
+
if (data.length === 0) return false;
|
|
266
|
+
return data.every((row) => rowSelection[getRowId(row)] === true);
|
|
267
|
+
}, [data, getRowId, rowSelection]);
|
|
268
|
+
|
|
269
|
+
const isSomeOnPageSelected = useCallback(() => {
|
|
270
|
+
if (data.length === 0) return false;
|
|
271
|
+
let some = false;
|
|
272
|
+
let all = true;
|
|
273
|
+
for (const row of data) {
|
|
274
|
+
if (rowSelection[getRowId(row)]) some = true;
|
|
275
|
+
else all = false;
|
|
276
|
+
}
|
|
277
|
+
return some && !all;
|
|
278
|
+
}, [data, getRowId, rowSelection]);
|
|
279
|
+
|
|
280
|
+
const toggleRowExpanded = useCallback(
|
|
281
|
+
(rowId: string) => {
|
|
282
|
+
setExpandedRows((prev) => {
|
|
283
|
+
const next = { ...prev };
|
|
284
|
+
if (next[rowId]) delete next[rowId];
|
|
285
|
+
else next[rowId] = true;
|
|
286
|
+
return next;
|
|
287
|
+
});
|
|
288
|
+
},
|
|
289
|
+
[setExpandedRows],
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
const toggleColumnVisibility = useCallback(
|
|
293
|
+
(columnId: string) => {
|
|
294
|
+
setColumnVisibility((prev) => ({
|
|
295
|
+
...prev,
|
|
296
|
+
[columnId]: prev[columnId] === false ? true : false,
|
|
297
|
+
}));
|
|
298
|
+
},
|
|
299
|
+
[setColumnVisibility],
|
|
300
|
+
);
|
|
301
|
+
|
|
302
|
+
const pinColumn = useCallback(
|
|
303
|
+
(columnId: string, side: 'left' | 'right' | false) => {
|
|
304
|
+
setColumnPinning((prev) => {
|
|
305
|
+
const left = prev.left.filter((id) => id !== columnId);
|
|
306
|
+
const right = prev.right.filter((id) => id !== columnId);
|
|
307
|
+
if (side === 'left') left.push(columnId);
|
|
308
|
+
else if (side === 'right') right.push(columnId);
|
|
309
|
+
return { left, right };
|
|
310
|
+
});
|
|
311
|
+
},
|
|
312
|
+
[setColumnPinning],
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
const toggleSort = useCallback(
|
|
316
|
+
(columnId: string) => {
|
|
317
|
+
setSort((prev) => {
|
|
318
|
+
if (!prev || prev.columnId !== columnId) {
|
|
319
|
+
return { columnId, direction: 'asc' };
|
|
320
|
+
}
|
|
321
|
+
if (prev.direction === 'asc') return { columnId, direction: 'desc' };
|
|
322
|
+
return null;
|
|
323
|
+
});
|
|
324
|
+
},
|
|
325
|
+
[setSort],
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
return {
|
|
329
|
+
data,
|
|
330
|
+
pinnedRows,
|
|
331
|
+
columns,
|
|
332
|
+
getRowId,
|
|
333
|
+
rowCount,
|
|
334
|
+
enableRowSelection,
|
|
335
|
+
hasExpansion: renderExpandedRow != null,
|
|
336
|
+
onRowClick,
|
|
337
|
+
renderExpandedRow,
|
|
338
|
+
|
|
339
|
+
columnOrder,
|
|
340
|
+
columnSizing,
|
|
341
|
+
columnVisibility,
|
|
342
|
+
columnPinning,
|
|
343
|
+
rowSelection,
|
|
344
|
+
expandedRows,
|
|
345
|
+
sort,
|
|
346
|
+
|
|
347
|
+
visibleColumns,
|
|
348
|
+
leftPinnedColumns,
|
|
349
|
+
rightPinnedColumns,
|
|
350
|
+
unpinnedColumns,
|
|
351
|
+
columnSizesPx,
|
|
352
|
+
leftPinOffsets,
|
|
353
|
+
rightPinOffsets,
|
|
354
|
+
|
|
355
|
+
setColumnOrder,
|
|
356
|
+
setColumnSizing,
|
|
357
|
+
setColumnVisibility,
|
|
358
|
+
setColumnPinning,
|
|
359
|
+
setRowSelection,
|
|
360
|
+
setExpandedRows,
|
|
361
|
+
setSort,
|
|
362
|
+
|
|
363
|
+
toggleRowSelection,
|
|
364
|
+
toggleAllOnPage,
|
|
365
|
+
isAllOnPageSelected,
|
|
366
|
+
isSomeOnPageSelected,
|
|
367
|
+
toggleRowExpanded,
|
|
368
|
+
toggleColumnVisibility,
|
|
369
|
+
pinColumn,
|
|
370
|
+
toggleSort,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import type { PointerEvent as ReactPointerEvent } from 'react';
|
|
3
|
+
|
|
4
|
+
interface UseResizeHandleOptions {
|
|
5
|
+
initialWidth: number;
|
|
6
|
+
minWidth: number;
|
|
7
|
+
maxWidth?: number;
|
|
8
|
+
onResize: (nextWidth: number) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface ResizeHandleApi {
|
|
12
|
+
isResizing: boolean;
|
|
13
|
+
onPointerDown: (e: ReactPointerEvent<HTMLElement>) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Pointer-based resize-handle hook. Attach `onPointerDown` to the handle
|
|
18
|
+
* element. While dragging, `pointermove` on window fires `onResize` with
|
|
19
|
+
* the clamped width; `pointerup` / `pointercancel` ends the drag.
|
|
20
|
+
*
|
|
21
|
+
* `initialWidth` is captured at pointerdown — callers don't need to keep
|
|
22
|
+
* it in sync between events (the hook holds the start width internally).
|
|
23
|
+
*
|
|
24
|
+
* @remarks
|
|
25
|
+
* **When NOT to use / anti-patterns**
|
|
26
|
+
*
|
|
27
|
+
* - Do not use this hook outside of a column-resize context. It is
|
|
28
|
+
* purpose-built for DataTable header cells and assumes a horizontal
|
|
29
|
+
* drag interaction with a fixed start width.
|
|
30
|
+
* - Do not wire `onPointerDown` to a full cell — only the narrow resize
|
|
31
|
+
* handle element. Attaching it to the whole header cell will intercept
|
|
32
|
+
* sort clicks and other cell interactions.
|
|
33
|
+
* - Do not rely on `setPointerCapture` being functional in all
|
|
34
|
+
* environments (it is best-effort / no-op in jsdom). The hook falls
|
|
35
|
+
* back to window-level listeners for cross-browser reliability.
|
|
36
|
+
*/
|
|
37
|
+
export function useResizeHandle(options: UseResizeHandleOptions): ResizeHandleApi {
|
|
38
|
+
const { minWidth, maxWidth, onResize } = options;
|
|
39
|
+
const [isResizing, setIsResizing] = useState(false);
|
|
40
|
+
|
|
41
|
+
// Held in refs so handlers attached to window don't go stale.
|
|
42
|
+
const startXRef = useRef(0);
|
|
43
|
+
const startWidthRef = useRef(0);
|
|
44
|
+
const onResizeRef = useRef(onResize);
|
|
45
|
+
onResizeRef.current = onResize;
|
|
46
|
+
const minRef = useRef(minWidth);
|
|
47
|
+
minRef.current = minWidth;
|
|
48
|
+
const maxRef = useRef(maxWidth);
|
|
49
|
+
maxRef.current = maxWidth;
|
|
50
|
+
|
|
51
|
+
const onPointerDown = useCallback(
|
|
52
|
+
(e: ReactPointerEvent<HTMLElement>) => {
|
|
53
|
+
e.stopPropagation?.();
|
|
54
|
+
startXRef.current = e.clientX;
|
|
55
|
+
startWidthRef.current = options.initialWidth;
|
|
56
|
+
try {
|
|
57
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
58
|
+
} catch {
|
|
59
|
+
// No-op for older browsers / jsdom.
|
|
60
|
+
}
|
|
61
|
+
setIsResizing(true);
|
|
62
|
+
},
|
|
63
|
+
[options.initialWidth],
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
if (!isResizing) return;
|
|
68
|
+
|
|
69
|
+
function clamp(n: number) {
|
|
70
|
+
const min = minRef.current;
|
|
71
|
+
const max = maxRef.current;
|
|
72
|
+
let v = Math.max(min, n);
|
|
73
|
+
if (max != null) v = Math.min(max, v);
|
|
74
|
+
return v;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function onMove(e: PointerEvent) {
|
|
78
|
+
const delta = e.clientX - startXRef.current;
|
|
79
|
+
const next = clamp(startWidthRef.current + delta);
|
|
80
|
+
onResizeRef.current(next);
|
|
81
|
+
}
|
|
82
|
+
function onEnd() {
|
|
83
|
+
setIsResizing(false);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
window.addEventListener('pointermove', onMove);
|
|
87
|
+
window.addEventListener('pointerup', onEnd);
|
|
88
|
+
window.addEventListener('pointercancel', onEnd);
|
|
89
|
+
return () => {
|
|
90
|
+
window.removeEventListener('pointermove', onMove);
|
|
91
|
+
window.removeEventListener('pointerup', onEnd);
|
|
92
|
+
window.removeEventListener('pointercancel', onEnd);
|
|
93
|
+
};
|
|
94
|
+
}, [isResizing]);
|
|
95
|
+
|
|
96
|
+
return { isResizing, onPointerDown };
|
|
97
|
+
}
|