@eocrm/design-system 0.0.0-stage → 0.6.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI-PRIMER.md +341 -0
- package/LICENSE +202 -0
- package/README.md +266 -2
- package/docs/components/Accordion.md +114 -0
- package/docs/components/AgentAvatar.md +58 -0
- package/docs/components/Alert.md +81 -0
- package/docs/components/AppLayout.md +70 -0
- package/docs/components/Avatar.md +49 -0
- package/docs/components/AvatarGroup.md +47 -0
- package/docs/components/Badge.md +60 -0
- package/docs/components/Banner.md +89 -0
- package/docs/components/BrandIcon.md +32 -0
- package/docs/components/Breadcrumb.md +72 -0
- package/docs/components/Button.md +107 -0
- package/docs/components/ButtonGroup.md +78 -0
- package/docs/components/Calendar.md +158 -0
- package/docs/components/Card.md +165 -0
- package/docs/components/CatalogPicker.md +83 -0
- package/docs/components/Chart.md +114 -0
- package/docs/components/ChatBubble.md +55 -0
- package/docs/components/ChatLauncher.md +97 -0
- package/docs/components/Checkbox.md +55 -0
- package/docs/components/CircularProgress.md +53 -0
- package/docs/components/Cluster.md +96 -0
- package/docs/components/Code.md +35 -0
- package/docs/components/CodeBlock.md +67 -0
- package/docs/components/ColorPicker.md +115 -0
- package/docs/components/ConfirmationPopover.md +70 -0
- package/docs/components/Constrain.md +39 -0
- package/docs/components/CurrencySelect.md +57 -0
- package/docs/components/CursorPagination.md +43 -0
- package/docs/components/DashboardCanvas.md +79 -0
- package/docs/components/DashboardWidget.md +131 -0
- package/docs/components/DataTable.md +88 -0
- package/docs/components/DatePicker.md +68 -0
- package/docs/components/DateRangePicker.md +71 -0
- package/docs/components/DateStrip.md +56 -0
- package/docs/components/DefinitionList.md +82 -0
- package/docs/components/Divider.md +57 -0
- package/docs/components/Dot.md +26 -0
- package/docs/components/Drawer.md +94 -0
- package/docs/components/DropdownMenu.md +299 -0
- package/docs/components/EmojiPicker.md +84 -0
- package/docs/components/EmptyState.md +55 -0
- package/docs/components/EntityChip.md +102 -0
- package/docs/components/ErrorState.md +72 -0
- package/docs/components/Field.md +91 -0
- package/docs/components/FileUpload.md +109 -0
- package/docs/components/FilterChip.md +88 -0
- package/docs/components/FlowCanvas.md +108 -0
- package/docs/components/FormRow.md +31 -0
- package/docs/components/FormSection.md +37 -0
- package/docs/components/Grid.md +103 -0
- package/docs/components/Highlight.md +75 -0
- package/docs/components/HighlightedText.md +50 -0
- package/docs/components/IconPicker.md +134 -0
- package/docs/components/IconTile.md +30 -0
- package/docs/components/Image.md +84 -0
- package/docs/components/ImageCrop.md +163 -0
- package/docs/components/Indent.md +31 -0
- package/docs/components/InlineDatePicker.md +58 -0
- package/docs/components/InlineDateRangePicker.md +57 -0
- package/docs/components/Input.md +54 -0
- package/docs/components/Kanban.md +122 -0
- package/docs/components/Kbd.md +41 -0
- package/docs/components/Lightbox.md +105 -0
- package/docs/components/Link.md +65 -0
- package/docs/components/LinkCard.md +41 -0
- package/docs/components/LiquidEditor.md +84 -0
- package/docs/components/List.md +68 -0
- package/docs/components/LiveRegion.md +29 -0
- package/docs/components/LocaleProvider.md +25 -0
- package/docs/components/Logo.md +41 -0
- package/docs/components/Masonry.md +48 -0
- package/docs/components/MediaTile.md +95 -0
- package/docs/components/Modal.md +107 -0
- package/docs/components/MoneyInput.md +62 -0
- package/docs/components/OptionsPicker.md +123 -0
- package/docs/components/OtpInput.md +65 -0
- package/docs/components/Page.md +35 -0
- package/docs/components/PageHeader.md +133 -0
- package/docs/components/Pagination.md +44 -0
- package/docs/components/Palette.md +32 -0
- package/docs/components/PasswordInput.md +45 -0
- package/docs/components/PasswordStrengthMeter.md +27 -0
- package/docs/components/PersonDisplay.md +153 -0
- package/docs/components/PhoneInput.md +54 -0
- package/docs/components/PillMenu.md +91 -0
- package/docs/components/Popover.md +127 -0
- package/docs/components/Progress.md +56 -0
- package/docs/components/QrCode.md +34 -0
- package/docs/components/Radio.md +37 -0
- package/docs/components/RadioGroup.md +56 -0
- package/docs/components/Rail.md +191 -0
- package/docs/components/RelativeDateInput.md +114 -0
- package/docs/components/RichText.md +44 -0
- package/docs/components/RichTextEditor.md +112 -0
- package/docs/components/Screen.md +37 -0
- package/docs/components/ScrollArea.md +39 -0
- package/docs/components/Select.md +131 -0
- package/docs/components/SettingRow.md +98 -0
- package/docs/components/Skeleton.md +68 -0
- package/docs/components/Slider.md +92 -0
- package/docs/components/SlotGrid.md +55 -0
- package/docs/components/SocialButton.md +31 -0
- package/docs/components/Sortable.md +127 -0
- package/docs/components/SortableGroup.md +52 -0
- package/docs/components/Sparkline.md +51 -0
- package/docs/components/Split.md +76 -0
- package/docs/components/Stack.md +59 -0
- package/docs/components/StagePath.md +66 -0
- package/docs/components/StatGroup.md +61 -0
- package/docs/components/StatTile.md +58 -0
- package/docs/components/Sticky.md +69 -0
- package/docs/components/Switch.md +89 -0
- package/docs/components/Table.md +184 -0
- package/docs/components/TableOfContents.md +76 -0
- package/docs/components/Tabs.md +94 -0
- package/docs/components/Text.md +63 -0
- package/docs/components/Textarea.md +59 -0
- package/docs/components/Thread.md +52 -0
- package/docs/components/TimeField.md +70 -0
- package/docs/components/Timeline.md +57 -0
- package/docs/components/Title.md +54 -0
- package/docs/components/ToastViewport.md +61 -0
- package/docs/components/Tooltip.md +63 -0
- package/docs/components/TopBar.md +214 -0
- package/docs/components/Tour.md +85 -0
- package/docs/components/TreeView.md +113 -0
- package/docs/components/VisuallyHidden.md +43 -0
- package/docs/components/WidgetPreview.md +54 -0
- package/docs/components/useBelowBreakpoint.md +11 -0
- package/docs/components/useMonth.md +18 -0
- package/docs/setup.md +51 -0
- package/docs/theming.md +95 -0
- package/docs/tokens.md +123 -0
- package/docs/transient-state.md +56 -0
- package/package.json +86 -4
- package/src/_meta/manifest.ts +293 -0
- package/src/app/AppProvider.tsx +78 -0
- package/src/app/index.ts +3 -0
- package/src/app/themeTokens.ts +95 -0
- package/src/calendar/dateMath.ts +114 -0
- package/src/calendar/formatters.ts +75 -0
- package/src/calendar/index.ts +39 -0
- package/src/calendar/types.ts +36 -0
- package/src/calendar/useAgenda.ts +70 -0
- package/src/calendar/useDay.ts +51 -0
- package/src/calendar/useMonth.ts +82 -0
- package/src/calendar/useWeek.ts +62 -0
- package/src/calendar/weekInfo.ts +83 -0
- package/src/components/Accordion/Accordion.module.scss +304 -0
- package/src/components/Accordion/Accordion.tokens.scss +64 -0
- package/src/components/Accordion/Accordion.tsx +272 -0
- package/src/components/Accordion/AccordionContent.tsx +36 -0
- package/src/components/Accordion/AccordionItem.tsx +66 -0
- package/src/components/Accordion/AccordionTrigger.tsx +121 -0
- package/src/components/Accordion/context.ts +47 -0
- package/src/components/Accordion/index.ts +14 -0
- package/src/components/Alert/Alert.module.scss +92 -0
- package/src/components/Alert/Alert.tokens.scss +60 -0
- package/src/components/Alert/Alert.tsx +136 -0
- package/src/components/Alert/index.ts +2 -0
- package/src/components/AppLayout/AppLayout.module.scss +130 -0
- package/src/components/AppLayout/AppLayout.tokens.scss +27 -0
- package/src/components/AppLayout/AppLayout.tsx +211 -0
- package/src/components/AppLayout/index.ts +2 -0
- package/src/components/Avatar/AgentAvatar.module.scss +117 -0
- package/src/components/Avatar/AgentAvatar.tsx +122 -0
- package/src/components/Avatar/Avatar.module.scss +181 -0
- package/src/components/Avatar/Avatar.tokens.scss +107 -0
- package/src/components/Avatar/Avatar.tsx +210 -0
- package/src/components/Avatar/AvatarGroup.module.scss +128 -0
- package/src/components/Avatar/AvatarGroup.tsx +119 -0
- package/src/components/Avatar/AvatarGroupContext.tsx +20 -0
- package/src/components/Avatar/index.ts +6 -0
- package/src/components/Badge/Badge.module.scss +124 -0
- package/src/components/Badge/Badge.tokens.scss +74 -0
- package/src/components/Badge/Badge.tsx +164 -0
- package/src/components/Badge/index.ts +2 -0
- package/src/components/Banner/Banner.module.scss +73 -0
- package/src/components/Banner/Banner.tokens.scss +51 -0
- package/src/components/Banner/Banner.tsx +138 -0
- package/src/components/Banner/index.ts +2 -0
- package/src/components/BrandIcon/BrandIcon.module.scss +5 -0
- package/src/components/BrandIcon/BrandIcon.tsx +99 -0
- package/src/components/BrandIcon/index.ts +2 -0
- package/src/components/Breadcrumb/Breadcrumb.module.scss +32 -0
- package/src/components/Breadcrumb/Breadcrumb.tokens.scss +9 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +146 -0
- package/src/components/Breadcrumb/index.ts +2 -0
- package/src/components/Button/Button.module.scss +167 -0
- package/src/components/Button/Button.tokens.scss +90 -0
- package/src/components/Button/Button.tsx +205 -0
- package/src/components/Button/index.ts +2 -0
- package/src/components/ButtonGroup/ButtonGroup.module.scss +134 -0
- package/src/components/ButtonGroup/ButtonGroup.tokens.scss +42 -0
- package/src/components/ButtonGroup/ButtonGroup.tsx +278 -0
- package/src/components/ButtonGroup/ButtonGroupItem.tsx +74 -0
- package/src/components/ButtonGroup/context.ts +45 -0
- package/src/components/ButtonGroup/index.ts +2 -0
- package/src/components/Calendar/AgendaView.module.scss +231 -0
- package/src/components/Calendar/AgendaView.tsx +214 -0
- package/src/components/Calendar/AllDayBand.module.scss +18 -0
- package/src/components/Calendar/AllDayBand.tsx +75 -0
- package/src/components/Calendar/Calendar.module.scss +23 -0
- package/src/components/Calendar/Calendar.tokens.scss +262 -0
- package/src/components/Calendar/Calendar.tsx +370 -0
- package/src/components/Calendar/DayCell.module.scss +30 -0
- package/src/components/Calendar/DayCell.tsx +50 -0
- package/src/components/Calendar/DayView.module.scss +10 -0
- package/src/components/Calendar/DayView.tsx +163 -0
- package/src/components/Calendar/EventChip.module.scss +171 -0
- package/src/components/Calendar/EventChip.tsx +115 -0
- package/src/components/Calendar/HourGrid.module.scss +123 -0
- package/src/components/Calendar/HourGrid.tsx +381 -0
- package/src/components/Calendar/MonthView.module.scss +99 -0
- package/src/components/Calendar/MonthView.tsx +296 -0
- package/src/components/Calendar/TimedEvent.module.scss +205 -0
- package/src/components/Calendar/TimedEvent.tsx +247 -0
- package/src/components/Calendar/ViewSwitcher.module.scss +3 -0
- package/src/components/Calendar/ViewSwitcher.tsx +47 -0
- package/src/components/Calendar/WeekView.module.scss +10 -0
- package/src/components/Calendar/WeekView.tsx +137 -0
- package/src/components/Calendar/eventColor.ts +60 -0
- package/src/components/Calendar/index.ts +18 -0
- package/src/components/Calendar/types.ts +451 -0
- package/src/components/Calendar/useEventDrag.ts +783 -0
- package/src/components/Calendar/utils.ts +622 -0
- package/src/components/Card/Card.module.scss +264 -0
- package/src/components/Card/Card.tokens.scss +55 -0
- package/src/components/Card/Card.tsx +170 -0
- package/src/components/Card/CardBody.tsx +45 -0
- package/src/components/Card/CardHeader.tsx +113 -0
- package/src/components/Card/CardList.tsx +24 -0
- package/src/components/Card/CardListRow.tsx +24 -0
- package/src/components/Card/index.ts +7 -0
- package/src/components/CatalogPicker/CatalogPicker.module.scss +193 -0
- package/src/components/CatalogPicker/CatalogPicker.tokens.scss +26 -0
- package/src/components/CatalogPicker/CatalogPicker.tsx +339 -0
- package/src/components/CatalogPicker/index.ts +2 -0
- package/src/components/Chart/Chart.module.scss +287 -0
- package/src/components/Chart/Chart.tokens.scss +63 -0
- package/src/components/Chart/Chart.tsx +607 -0
- package/src/components/Chart/ChartLegend.tsx +99 -0
- package/src/components/Chart/ChartTable.tsx +62 -0
- package/src/components/Chart/ChartTooltip.tsx +91 -0
- package/src/components/Chart/chartModel.ts +689 -0
- package/src/components/Chart/index.ts +2 -0
- package/src/components/ChatBubble/ChatBubble.module.scss +93 -0
- package/src/components/ChatBubble/ChatBubble.tokens.scss +17 -0
- package/src/components/ChatBubble/ChatBubble.tsx +61 -0
- package/src/components/ChatBubble/ChatBubbleList.tsx +27 -0
- package/src/components/ChatBubble/index.ts +3 -0
- package/src/components/ChatLauncher/ChatLauncher.module.scss +68 -0
- package/src/components/ChatLauncher/ChatLauncher.tokens.scss +27 -0
- package/src/components/ChatLauncher/ChatLauncher.tsx +202 -0
- package/src/components/ChatLauncher/index.ts +2 -0
- package/src/components/ChatLauncher/isAtBottom.ts +12 -0
- package/src/components/Checkbox/Checkbox.module.scss +147 -0
- package/src/components/Checkbox/Checkbox.tokens.scss +44 -0
- package/src/components/Checkbox/Checkbox.tsx +188 -0
- package/src/components/Checkbox/index.ts +2 -0
- package/src/components/CircularProgress/CircularProgress.module.scss +133 -0
- package/src/components/CircularProgress/CircularProgress.tokens.scss +40 -0
- package/src/components/CircularProgress/CircularProgress.tsx +139 -0
- package/src/components/CircularProgress/index.ts +7 -0
- package/src/components/Cluster/Cluster.module.scss +145 -0
- package/src/components/Cluster/Cluster.tokens.scss +11 -0
- package/src/components/Cluster/Cluster.tsx +215 -0
- package/src/components/Cluster/index.ts +2 -0
- package/src/components/Code/Code.module.scss +28 -0
- package/src/components/Code/Code.tokens.scss +15 -0
- package/src/components/Code/Code.tsx +44 -0
- package/src/components/Code/index.ts +2 -0
- package/src/components/CodeBlock/CodeBlock.module.scss +146 -0
- package/src/components/CodeBlock/CodeBlock.tokens.scss +27 -0
- package/src/components/CodeBlock/CodeBlock.tsx +274 -0
- package/src/components/CodeBlock/highlight.ts +179 -0
- package/src/components/CodeBlock/index.ts +8 -0
- package/src/components/CodeBlock/sampleSync.ts +42 -0
- package/src/components/ColorPicker/ColorPicker.module.scss +286 -0
- package/src/components/ColorPicker/ColorPicker.tokens.scss +60 -0
- package/src/components/ColorPicker/ColorPicker.tsx +367 -0
- package/src/components/ColorPicker/ColorPickerPanel.tsx +265 -0
- package/src/components/ColorPicker/SVSquare.tsx +189 -0
- package/src/components/ColorPicker/colorMath.ts +141 -0
- package/src/components/ColorPicker/index.ts +6 -0
- package/src/components/ConfirmationPopover/ConfirmationPopover.module.scss +39 -0
- package/src/components/ConfirmationPopover/ConfirmationPopover.tokens.scss +13 -0
- package/src/components/ConfirmationPopover/ConfirmationPopover.tsx +395 -0
- package/src/components/ConfirmationPopover/index.ts +2 -0
- package/src/components/Constrain/Constrain.module.scss +99 -0
- package/src/components/Constrain/Constrain.tsx +79 -0
- package/src/components/Constrain/index.ts +2 -0
- package/src/components/CurrencySelect/CurrencySelect.module.scss +7 -0
- package/src/components/CurrencySelect/CurrencySelect.tsx +167 -0
- package/src/components/CurrencySelect/index.ts +3 -0
- package/src/components/CursorPagination/CursorPagination.module.scss +69 -0
- package/src/components/CursorPagination/CursorPagination.tokens.scss +32 -0
- package/src/components/CursorPagination/CursorPagination.tsx +121 -0
- package/src/components/CursorPagination/index.ts +2 -0
- package/src/components/DashboardCanvas/DashboardCanvas.module.scss +360 -0
- package/src/components/DashboardCanvas/DashboardCanvas.tokens.scss +48 -0
- package/src/components/DashboardCanvas/DashboardCanvas.tsx +1270 -0
- package/src/components/DashboardCanvas/DashboardCanvasItem.tsx +140 -0
- package/src/components/DashboardCanvas/DashboardCanvasSection.tsx +174 -0
- package/src/components/DashboardCanvas/engine.ts +363 -0
- package/src/components/DashboardCanvas/index.ts +9 -0
- package/src/components/DashboardWidget/DashboardWidget.module.scss +100 -0
- package/src/components/DashboardWidget/DashboardWidget.tokens.scss +16 -0
- package/src/components/DashboardWidget/DashboardWidget.tsx +188 -0
- package/src/components/DashboardWidget/index.ts +7 -0
- package/src/components/DataTable/BodyRow.tsx +197 -0
- package/src/components/DataTable/ColumnVisibilityTrigger.module.scss +7 -0
- package/src/components/DataTable/ColumnVisibilityTrigger.tsx +105 -0
- package/src/components/DataTable/DataTable.module.scss +511 -0
- package/src/components/DataTable/DataTable.tokens.scss +80 -0
- package/src/components/DataTable/DataTable.tsx +734 -0
- package/src/components/DataTable/HeaderCell.module.scss +215 -0
- package/src/components/DataTable/HeaderCell.tsx +440 -0
- package/src/components/DataTable/columnShift.ts +117 -0
- package/src/components/DataTable/index.ts +23 -0
- package/src/components/DataTable/pinStyle.ts +47 -0
- package/src/components/DataTable/reorderColumns.ts +66 -0
- package/src/components/DataTable/types.ts +289 -0
- package/src/components/DataTable/useColumnDragShift.ts +216 -0
- package/src/components/DataTable/useDataTable.ts +372 -0
- package/src/components/DataTable/useResizeHandle.ts +97 -0
- package/src/components/DatePicker/DatePicker.module.scss +180 -0
- package/src/components/DatePicker/DatePicker.tokens.scss +152 -0
- package/src/components/DatePicker/DatePicker.tsx +664 -0
- package/src/components/DatePicker/DatePickerGrid.module.scss +172 -0
- package/src/components/DatePicker/DatePickerGrid.tsx +341 -0
- package/src/components/DatePicker/InlineDatePicker.module.scss +32 -0
- package/src/components/DatePicker/InlineDatePicker.tsx +201 -0
- package/src/components/DatePicker/index.ts +4 -0
- package/src/components/DatePicker/utils.ts +364 -0
- package/src/components/DateRangePicker/DateRangePicker.module.scss +237 -0
- package/src/components/DateRangePicker/DateRangePicker.tokens.scss +78 -0
- package/src/components/DateRangePicker/DateRangePicker.tsx +720 -0
- package/src/components/DateRangePicker/InlineDateRangePicker.module.scss +94 -0
- package/src/components/DateRangePicker/InlineDateRangePicker.tsx +376 -0
- package/src/components/DateRangePicker/index.ts +5 -0
- package/src/components/DateRangePicker/utils.ts +151 -0
- package/src/components/DateStrip/DateStrip.module.scss +78 -0
- package/src/components/DateStrip/DateStrip.tokens.scss +23 -0
- package/src/components/DateStrip/DateStrip.tsx +205 -0
- package/src/components/DateStrip/index.ts +2 -0
- package/src/components/DefinitionList/DefinitionList.module.scss +102 -0
- package/src/components/DefinitionList/DefinitionList.tokens.scss +29 -0
- package/src/components/DefinitionList/DefinitionList.tsx +198 -0
- package/src/components/DefinitionList/index.ts +9 -0
- package/src/components/Divider/Divider.module.scss +144 -0
- package/src/components/Divider/Divider.tokens.scss +21 -0
- package/src/components/Divider/Divider.tsx +103 -0
- package/src/components/Divider/index.ts +2 -0
- package/src/components/Dot/Dot.module.scss +40 -0
- package/src/components/Dot/Dot.tokens.scss +4 -0
- package/src/components/Dot/Dot.tsx +45 -0
- package/src/components/Dot/index.ts +2 -0
- package/src/components/Drawer/Body.tsx +23 -0
- package/src/components/Drawer/Close.tsx +35 -0
- package/src/components/Drawer/Content.tsx +93 -0
- package/src/components/Drawer/Drawer.module.scss +232 -0
- package/src/components/Drawer/Drawer.tokens.scss +38 -0
- package/src/components/Drawer/Drawer.tsx +23 -0
- package/src/components/Drawer/DrawerRoot.tsx +190 -0
- package/src/components/Drawer/Footer.tsx +24 -0
- package/src/components/Drawer/Header.tsx +64 -0
- package/src/components/Drawer/Overlay.tsx +82 -0
- package/src/components/Drawer/context.ts +44 -0
- package/src/components/Drawer/index.ts +12 -0
- package/src/components/Drawer/useDragToClose.ts +149 -0
- package/src/components/DropdownMenu/CheckboxItem.tsx +144 -0
- package/src/components/DropdownMenu/Content.tsx +419 -0
- package/src/components/DropdownMenu/DropdownMenu.module.scss +280 -0
- package/src/components/DropdownMenu/DropdownMenu.tokens.scss +88 -0
- package/src/components/DropdownMenu/DropdownMenu.tsx +43 -0
- package/src/components/DropdownMenu/Group.tsx +76 -0
- package/src/components/DropdownMenu/Item.tsx +148 -0
- package/src/components/DropdownMenu/ItemIndicator.tsx +30 -0
- package/src/components/DropdownMenu/Radio.tsx +178 -0
- package/src/components/DropdownMenu/Root.tsx +100 -0
- package/src/components/DropdownMenu/Sub.tsx +332 -0
- package/src/components/DropdownMenu/Trigger.tsx +76 -0
- package/src/components/DropdownMenu/context.ts +65 -0
- package/src/components/DropdownMenu/index.ts +20 -0
- package/src/components/EmojiPicker/EmojiPicker.module.scss +84 -0
- package/src/components/EmojiPicker/EmojiPicker.tokens.scss +24 -0
- package/src/components/EmojiPicker/EmojiPicker.tsx +341 -0
- package/src/components/EmojiPicker/emojiData.ts +245 -0
- package/src/components/EmojiPicker/index.ts +3 -0
- package/src/components/EmptyState/EmptyState.module.scss +102 -0
- package/src/components/EmptyState/EmptyState.tokens.scss +28 -0
- package/src/components/EmptyState/EmptyState.tsx +112 -0
- package/src/components/EmptyState/index.ts +7 -0
- package/src/components/EntityChip/EntityChip.module.scss +275 -0
- package/src/components/EntityChip/EntityChip.tokens.scss +66 -0
- package/src/components/EntityChip/EntityChip.tsx +649 -0
- package/src/components/EntityChip/index.ts +10 -0
- package/src/components/ErrorState/ErrorState.module.scss +105 -0
- package/src/components/ErrorState/ErrorState.tokens.scss +32 -0
- package/src/components/ErrorState/ErrorState.tsx +125 -0
- package/src/components/ErrorState/index.ts +8 -0
- package/src/components/Field/Field.module.scss +46 -0
- package/src/components/Field/Field.tsx +185 -0
- package/src/components/Field/index.ts +2 -0
- package/src/components/FileUpload/FileUpload.module.scss +187 -0
- package/src/components/FileUpload/FileUpload.tokens.scss +81 -0
- package/src/components/FileUpload/FileUpload.tsx +569 -0
- package/src/components/FileUpload/formatBytes.ts +34 -0
- package/src/components/FileUpload/iconForFile.ts +40 -0
- package/src/components/FileUpload/index.ts +2 -0
- package/src/components/FilterChip/FilterChip.module.scss +61 -0
- package/src/components/FilterChip/FilterChip.tokens.scss +25 -0
- package/src/components/FilterChip/FilterChip.tsx +208 -0
- package/src/components/FilterChip/index.ts +5 -0
- package/src/components/FlowCanvas/FlowCanvas.module.scss +329 -0
- package/src/components/FlowCanvas/FlowCanvas.tokens.scss +45 -0
- package/src/components/FlowCanvas/FlowCanvas.tsx +1867 -0
- package/src/components/FlowCanvas/FlowControls.tsx +46 -0
- package/src/components/FlowCanvas/FlowEdge.tsx +58 -0
- package/src/components/FlowCanvas/FlowNode.tsx +76 -0
- package/src/components/FlowCanvas/edgePath.ts +85 -0
- package/src/components/FlowCanvas/index.ts +4 -0
- package/src/components/FlowCanvas/layout.ts +148 -0
- package/src/components/FlowCanvas/spatialNav.ts +76 -0
- package/src/components/FlowCanvas/types.ts +59 -0
- package/src/components/FlowCanvas/useViewport.ts +122 -0
- package/src/components/FormRow/FormRow.module.scss +2 -0
- package/src/components/FormRow/FormRow.tsx +37 -0
- package/src/components/FormRow/index.ts +2 -0
- package/src/components/FormSection/FormSection.module.scss +24 -0
- package/src/components/FormSection/FormSection.tsx +46 -0
- package/src/components/FormSection/index.ts +2 -0
- package/src/components/Grid/Grid.module.scss +162 -0
- package/src/components/Grid/Grid.tokens.scss +13 -0
- package/src/components/Grid/Grid.tsx +226 -0
- package/src/components/Grid/GridItem.tsx +77 -0
- package/src/components/Grid/index.ts +11 -0
- package/src/components/Highlight/Highlight.module.scss +43 -0
- package/src/components/Highlight/Highlight.tokens.scss +35 -0
- package/src/components/Highlight/Highlight.tsx +164 -0
- package/src/components/Highlight/HighlightOverlay.tsx +100 -0
- package/src/components/Highlight/index.ts +2 -0
- package/src/components/HighlightedText/HighlightedText.module.scss +11 -0
- package/src/components/HighlightedText/HighlightedText.tokens.scss +9 -0
- package/src/components/HighlightedText/HighlightedText.tsx +50 -0
- package/src/components/HighlightedText/highlightRanges.ts +44 -0
- package/src/components/HighlightedText/index.ts +2 -0
- package/src/components/IconPicker/IconPicker.module.scss +175 -0
- package/src/components/IconPicker/IconPicker.tokens.scss +40 -0
- package/src/components/IconPicker/IconPicker.tsx +629 -0
- package/src/components/IconPicker/index.ts +9 -0
- package/src/components/IconTile/IconTile.module.scss +57 -0
- package/src/components/IconTile/IconTile.tokens.scss +16 -0
- package/src/components/IconTile/IconTile.tsx +91 -0
- package/src/components/IconTile/index.ts +2 -0
- package/src/components/Image/Image.module.scss +266 -0
- package/src/components/Image/Image.tokens.scss +55 -0
- package/src/components/Image/Image.tsx +342 -0
- package/src/components/Image/index.ts +2 -0
- package/src/components/ImageCrop/ImageCrop.module.scss +274 -0
- package/src/components/ImageCrop/ImageCrop.tokens.scss +33 -0
- package/src/components/ImageCrop/ImageCrop.tsx +542 -0
- package/src/components/ImageCrop/cropGeometry.ts +120 -0
- package/src/components/ImageCrop/extractCropBlob.ts +140 -0
- package/src/components/ImageCrop/index.ts +11 -0
- package/src/components/ImageCrop/useCropPreview.ts +161 -0
- package/src/components/Indent/Indent.module.scss +33 -0
- package/src/components/Indent/Indent.tokens.scss +10 -0
- package/src/components/Indent/Indent.tsx +46 -0
- package/src/components/Indent/index.ts +2 -0
- package/src/components/Input/Input.module.scss +99 -0
- package/src/components/Input/Input.tokens.scss +54 -0
- package/src/components/Input/Input.tsx +105 -0
- package/src/components/Input/Suggestions.tsx +260 -0
- package/src/components/Input/index.ts +2 -0
- package/src/components/Kanban/Kanban.module.scss +39 -0
- package/src/components/Kanban/Kanban.tokens.scss +15 -0
- package/src/components/Kanban/Kanban.tsx +951 -0
- package/src/components/Kanban/index.ts +7 -0
- package/src/components/Kbd/Kbd.module.scss +47 -0
- package/src/components/Kbd/Kbd.tokens.scss +26 -0
- package/src/components/Kbd/Kbd.tsx +73 -0
- package/src/components/Kbd/index.ts +2 -0
- package/src/components/Lightbox/Lightbox.module.scss +283 -0
- package/src/components/Lightbox/Lightbox.tokens.scss +36 -0
- package/src/components/Lightbox/Lightbox.tsx +506 -0
- package/src/components/Lightbox/index.ts +2 -0
- package/src/components/Link/Link.module.scss +78 -0
- package/src/components/Link/Link.tokens.scss +28 -0
- package/src/components/Link/Link.tsx +114 -0
- package/src/components/Link/index.ts +2 -0
- package/src/components/LinkCard/LinkCard.module.scss +92 -0
- package/src/components/LinkCard/LinkCard.tokens.scss +9 -0
- package/src/components/LinkCard/LinkCard.tsx +72 -0
- package/src/components/LinkCard/index.ts +2 -0
- package/src/components/LiquidEditor/AutocompleteMenu.tsx +133 -0
- package/src/components/LiquidEditor/HighlightLayer.tsx +53 -0
- package/src/components/LiquidEditor/InsertVariableMenu.tsx +81 -0
- package/src/components/LiquidEditor/LiquidEditor.module.scss +339 -0
- package/src/components/LiquidEditor/LiquidEditor.tokens.scss +81 -0
- package/src/components/LiquidEditor/LiquidEditor.tsx +412 -0
- package/src/components/LiquidEditor/PreviewPane.tsx +29 -0
- package/src/components/LiquidEditor/caretCoordinates.ts +97 -0
- package/src/components/LiquidEditor/index.ts +7 -0
- package/src/components/LiquidEditor/liquidFilters.ts +23 -0
- package/src/components/LiquidEditor/liquidTokenizer.ts +235 -0
- package/src/components/LiquidEditor/types.ts +101 -0
- package/src/components/LiquidEditor/useLiquidAutocomplete.ts +178 -0
- package/src/components/List/List.module.scss +105 -0
- package/src/components/List/List.tokens.scss +42 -0
- package/src/components/List/List.tsx +124 -0
- package/src/components/List/index.ts +9 -0
- package/src/components/LiveRegion/LiveRegion.module.scss +3 -0
- package/src/components/LiveRegion/LiveRegion.tsx +116 -0
- package/src/components/LiveRegion/index.ts +2 -0
- package/src/components/Logo/Logo.module.scss +139 -0
- package/src/components/Logo/Logo.tokens.scss +14 -0
- package/src/components/Logo/Logo.tsx +126 -0
- package/src/components/Logo/index.ts +2 -0
- package/src/components/Masonry/Masonry.module.scss +42 -0
- package/src/components/Masonry/Masonry.tokens.scss +8 -0
- package/src/components/Masonry/Masonry.tsx +136 -0
- package/src/components/Masonry/index.ts +2 -0
- package/src/components/Masonry/masonryUtils.ts +42 -0
- package/src/components/MediaTile/MediaTile.module.scss +183 -0
- package/src/components/MediaTile/MediaTile.tokens.scss +60 -0
- package/src/components/MediaTile/MediaTile.tsx +208 -0
- package/src/components/MediaTile/index.ts +8 -0
- package/src/components/Modal/Body.tsx +27 -0
- package/src/components/Modal/Close.tsx +45 -0
- package/src/components/Modal/Content.tsx +98 -0
- package/src/components/Modal/Footer.tsx +28 -0
- package/src/components/Modal/Header.tsx +51 -0
- package/src/components/Modal/Modal.module.scss +262 -0
- package/src/components/Modal/Modal.tokens.scss +50 -0
- package/src/components/Modal/Modal.tsx +23 -0
- package/src/components/Modal/ModalRoot.tsx +299 -0
- package/src/components/Modal/Overlay.tsx +101 -0
- package/src/components/Modal/context.ts +60 -0
- package/src/components/Modal/index.ts +11 -0
- package/src/components/MoneyInput/MoneyInput.module.scss +57 -0
- package/src/components/MoneyInput/MoneyInput.tsx +433 -0
- package/src/components/MoneyInput/index.ts +2 -0
- package/src/components/OptionsPicker/OptionsPicker.module.scss +216 -0
- package/src/components/OptionsPicker/OptionsPicker.tokens.scss +68 -0
- package/src/components/OptionsPicker/OptionsPicker.tsx +936 -0
- package/src/components/OptionsPicker/index.ts +9 -0
- package/src/components/OtpInput/OtpInput.module.scss +69 -0
- package/src/components/OtpInput/OtpInput.tokens.scss +45 -0
- package/src/components/OtpInput/OtpInput.tsx +368 -0
- package/src/components/OtpInput/index.ts +2 -0
- package/src/components/Page/Page.module.scss +30 -0
- package/src/components/Page/Page.tokens.scss +11 -0
- package/src/components/Page/Page.tsx +53 -0
- package/src/components/Page/index.ts +2 -0
- package/src/components/PageHeader/PageHeader.module.scss +197 -0
- package/src/components/PageHeader/PageHeader.tokens.scss +41 -0
- package/src/components/PageHeader/PageHeader.tsx +310 -0
- package/src/components/PageHeader/index.ts +20 -0
- package/src/components/Pagination/Pagination.module.scss +117 -0
- package/src/components/Pagination/Pagination.tokens.scss +54 -0
- package/src/components/Pagination/Pagination.tsx +165 -0
- package/src/components/Pagination/index.ts +4 -0
- package/src/components/Pagination/paginationRange.ts +72 -0
- package/src/components/PasswordInput/PasswordInput.module.scss +120 -0
- package/src/components/PasswordInput/PasswordInput.tokens.scss +44 -0
- package/src/components/PasswordInput/PasswordInput.tsx +210 -0
- package/src/components/PasswordInput/index.ts +2 -0
- package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.module.scss +80 -0
- package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tokens.scss +40 -0
- package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tsx +96 -0
- package/src/components/PasswordStrengthMeter/index.ts +2 -0
- package/src/components/PersonDisplay/PersonDisplay.module.scss +180 -0
- package/src/components/PersonDisplay/PersonDisplay.tokens.scss +35 -0
- package/src/components/PersonDisplay/PersonDisplay.tsx +420 -0
- package/src/components/PersonDisplay/index.ts +10 -0
- package/src/components/PhoneInput/PhoneInput.module.scss +23 -0
- package/src/components/PhoneInput/PhoneInput.tsx +271 -0
- package/src/components/PhoneInput/index.ts +4 -0
- package/src/components/PhoneInput/phone.ts +128 -0
- package/src/components/PillMenu/PillMenu.module.scss +117 -0
- package/src/components/PillMenu/PillMenu.tokens.scss +22 -0
- package/src/components/PillMenu/PillMenu.tsx +324 -0
- package/src/components/PillMenu/index.ts +2 -0
- package/src/components/Popover/Anchor.tsx +37 -0
- package/src/components/Popover/Close.tsx +45 -0
- package/src/components/Popover/Content.tsx +213 -0
- package/src/components/Popover/Heading.tsx +33 -0
- package/src/components/Popover/Popover.module.scss +177 -0
- package/src/components/Popover/Popover.tokens.scss +22 -0
- package/src/components/Popover/Popover.tsx +23 -0
- package/src/components/Popover/PopoverRoot.tsx +75 -0
- package/src/components/Popover/Trigger.tsx +86 -0
- package/src/components/Popover/context.ts +22 -0
- package/src/components/Popover/index.ts +7 -0
- package/src/components/Progress/Progress.module.scss +110 -0
- package/src/components/Progress/Progress.tokens.scss +44 -0
- package/src/components/Progress/Progress.tsx +129 -0
- package/src/components/Progress/index.ts +2 -0
- package/src/components/QrCode/QrCode.module.scss +97 -0
- package/src/components/QrCode/QrCode.tokens.scss +17 -0
- package/src/components/QrCode/QrCode.tsx +233 -0
- package/src/components/QrCode/index.ts +2 -0
- package/src/components/QrCode/qr.ts +161 -0
- package/src/components/Radio/Radio.module.scss +175 -0
- package/src/components/Radio/Radio.tokens.scss +59 -0
- package/src/components/Radio/Radio.tsx +127 -0
- package/src/components/Radio/RadioGroup.module.scss +42 -0
- package/src/components/Radio/RadioGroup.tsx +120 -0
- package/src/components/Radio/RadioGroupContext.tsx +30 -0
- package/src/components/Radio/index.ts +4 -0
- package/src/components/Rail/Rail.module.scss +510 -0
- package/src/components/Rail/Rail.tokens.scss +92 -0
- package/src/components/Rail/Rail.tsx +287 -0
- package/src/components/Rail/RailCollapseToggle.tsx +57 -0
- package/src/components/Rail/RailFooter.tsx +17 -0
- package/src/components/Rail/RailGroup.tsx +728 -0
- package/src/components/Rail/RailGroupContext.ts +9 -0
- package/src/components/Rail/RailHeader.tsx +23 -0
- package/src/components/Rail/RailItem.tsx +119 -0
- package/src/components/Rail/RailSection.tsx +39 -0
- package/src/components/Rail/RailSpacer.tsx +19 -0
- package/src/components/Rail/index.ts +9 -0
- package/src/components/RelativeDateInput/RelativeDateInput.module.scss +15 -0
- package/src/components/RelativeDateInput/RelativeDateInput.tokens.scss +6 -0
- package/src/components/RelativeDateInput/RelativeDateInput.tsx +474 -0
- package/src/components/RelativeDateInput/index.ts +10 -0
- package/src/components/RelativeDateInput/relativeDate.ts +127 -0
- package/src/components/RichText/RichText.module.scss +5 -0
- package/src/components/RichText/RichText.tsx +70 -0
- package/src/components/RichText/RichTextAttachment.module.scss +82 -0
- package/src/components/RichText/RichTextAttachment.tsx +122 -0
- package/src/components/RichText/_prose.scss +79 -0
- package/src/components/RichText/attachmentIcon.tsx +24 -0
- package/src/components/RichText/engine/attachment.ts +154 -0
- package/src/components/RichText/engine/autolink.ts +64 -0
- package/src/components/RichText/engine/blockUnit.ts +174 -0
- package/src/components/RichText/engine/colorMarks.ts +85 -0
- package/src/components/RichText/engine/escape.ts +11 -0
- package/src/components/RichText/engine/fromHtml.ts +353 -0
- package/src/components/RichText/engine/fromMarkdown.ts +20 -0
- package/src/components/RichText/engine/inlines.ts +82 -0
- package/src/components/RichText/engine/listDepths.ts +32 -0
- package/src/components/RichText/engine/marks.ts +80 -0
- package/src/components/RichText/engine/mdToHtml.ts +178 -0
- package/src/components/RichText/engine/model.ts +157 -0
- package/src/components/RichText/engine/position.ts +118 -0
- package/src/components/RichText/engine/renderDoc.tsx +395 -0
- package/src/components/RichText/engine/renderLink.ts +15 -0
- package/src/components/RichText/engine/renderMention.ts +16 -0
- package/src/components/RichText/engine/safeHref.ts +22 -0
- package/src/components/RichText/engine/toHtml.ts +154 -0
- package/src/components/RichText/engine/toMarkdown.ts +97 -0
- package/src/components/RichText/engine/transforms.ts +434 -0
- package/src/components/RichText/imageMaxHeightStyle.ts +10 -0
- package/src/components/RichText/index.ts +31 -0
- package/src/components/RichTextEditor/RichTextAttachmentConfig.tsx +264 -0
- package/src/components/RichTextEditor/RichTextBlockControls.tsx +365 -0
- package/src/components/RichTextEditor/RichTextBlockMenu.tsx +162 -0
- package/src/components/RichTextEditor/RichTextColorMenu.tsx +115 -0
- package/src/components/RichTextEditor/RichTextEditor.module.scss +298 -0
- package/src/components/RichTextEditor/RichTextEditor.tsx +1910 -0
- package/src/components/RichTextEditor/RichTextImageResizer.tsx +131 -0
- package/src/components/RichTextEditor/RichTextLinkEditor.tsx +151 -0
- package/src/components/RichTextEditor/RichTextMentionMenu.tsx +99 -0
- package/src/components/RichTextEditor/RichTextToolbar.tsx +379 -0
- package/src/components/RichTextEditor/autolinkInput.ts +65 -0
- package/src/components/RichTextEditor/blockDrop.ts +9 -0
- package/src/components/RichTextEditor/blockReflow.ts +62 -0
- package/src/components/RichTextEditor/commands.ts +300 -0
- package/src/components/RichTextEditor/history.ts +93 -0
- package/src/components/RichTextEditor/icons.tsx +152 -0
- package/src/components/RichTextEditor/imageSize.ts +70 -0
- package/src/components/RichTextEditor/index.ts +5 -0
- package/src/components/RichTextEditor/input.ts +209 -0
- package/src/components/RichTextEditor/inputRules.ts +71 -0
- package/src/components/RichTextEditor/links.ts +103 -0
- package/src/components/RichTextEditor/mentionContext.ts +37 -0
- package/src/components/RichTextEditor/mentions.ts +28 -0
- package/src/components/RichTextEditor/preventSelectionLoss.ts +15 -0
- package/src/components/RichTextEditor/selection.ts +415 -0
- package/src/components/RichTextEditor/shortcuts.ts +44 -0
- package/src/components/RichTextEditor/useAnchoredFloating.ts +50 -0
- package/src/components/RichTextEditor/useAttachmentConfig.ts +134 -0
- package/src/components/RichTextEditor/useDismissOnOutsidePointerDown.ts +26 -0
- package/src/components/RichTextEditor/useLinkEditor.ts +107 -0
- package/src/components/RichTextEditor/useMention.ts +226 -0
- package/src/components/RichTextEditor/useOverlayRect.ts +73 -0
- package/src/components/RichTextEditor/useUpload.ts +246 -0
- package/src/components/Screen/Screen.module.scss +46 -0
- package/src/components/Screen/Screen.tokens.scss +20 -0
- package/src/components/Screen/Screen.tsx +97 -0
- package/src/components/Screen/index.ts +2 -0
- package/src/components/ScrollArea/ScrollArea.module.scss +39 -0
- package/src/components/ScrollArea/ScrollArea.tokens.scss +15 -0
- package/src/components/ScrollArea/ScrollArea.tsx +154 -0
- package/src/components/ScrollArea/index.ts +2 -0
- package/src/components/Select/Chip.tsx +45 -0
- package/src/components/Select/Empty.tsx +39 -0
- package/src/components/Select/Error.tsx +51 -0
- package/src/components/Select/HiddenInputs.tsx +44 -0
- package/src/components/Select/Listbox.tsx +557 -0
- package/src/components/Select/Loading.tsx +30 -0
- package/src/components/Select/Select.module.scss +512 -0
- package/src/components/Select/Select.tokens.scss +140 -0
- package/src/components/Select/Select.tsx +685 -0
- package/src/components/Select/Trigger.tsx +952 -0
- package/src/components/Select/context.ts +101 -0
- package/src/components/Select/emptyStateText.ts +19 -0
- package/src/components/Select/index.ts +9 -0
- package/src/components/Select/useSelectState.ts +157 -0
- package/src/components/Select/utils-types.ts +7 -0
- package/src/components/Select/utils.ts +122 -0
- package/src/components/SettingRow/SettingRow.module.scss +166 -0
- package/src/components/SettingRow/SettingRow.tokens.scss +37 -0
- package/src/components/SettingRow/SettingRow.tsx +242 -0
- package/src/components/SettingRow/index.ts +7 -0
- package/src/components/Skeleton/Skeleton.module.scss +55 -0
- package/src/components/Skeleton/Skeleton.tokens.scss +17 -0
- package/src/components/Skeleton/Skeleton.tsx +131 -0
- package/src/components/Skeleton/index.ts +4 -0
- package/src/components/Skeleton/useSkeletonVisibility.ts +95 -0
- package/src/components/Slider/Slider.module.scss +293 -0
- package/src/components/Slider/Slider.tokens.scss +98 -0
- package/src/components/Slider/Slider.tsx +624 -0
- package/src/components/Slider/index.ts +9 -0
- package/src/components/SlotGrid/SlotGrid.module.scss +61 -0
- package/src/components/SlotGrid/SlotGrid.tokens.scss +21 -0
- package/src/components/SlotGrid/SlotGrid.tsx +111 -0
- package/src/components/SlotGrid/index.ts +2 -0
- package/src/components/SocialButton/SocialButton.module.scss +4 -0
- package/src/components/SocialButton/SocialButton.tsx +40 -0
- package/src/components/SocialButton/index.ts +2 -0
- package/src/components/Sortable/Sortable.module.scss +177 -0
- package/src/components/Sortable/Sortable.tokens.scss +27 -0
- package/src/components/Sortable/Sortable.tsx +572 -0
- package/src/components/Sortable/containerAwareCollision.ts +125 -0
- package/src/components/Sortable/index.ts +13 -0
- package/src/components/SortableGroup/SortableGroup.module.scss +23 -0
- package/src/components/SortableGroup/SortableGroup.tsx +315 -0
- package/src/components/SortableGroup/index.ts +4 -0
- package/src/components/SortableGroup/moveSortableItem.ts +39 -0
- package/src/components/Sparkline/Sparkline.module.scss +28 -0
- package/src/components/Sparkline/Sparkline.tokens.scss +7 -0
- package/src/components/Sparkline/Sparkline.tsx +133 -0
- package/src/components/Sparkline/index.ts +2 -0
- package/src/components/Sparkline/sparklineModel.ts +119 -0
- package/src/components/Split/Split.module.scss +158 -0
- package/src/components/Split/Split.tokens.scss +10 -0
- package/src/components/Split/Split.tsx +231 -0
- package/src/components/Split/index.ts +2 -0
- package/src/components/Stack/Stack.module.scss +67 -0
- package/src/components/Stack/Stack.tokens.scss +11 -0
- package/src/components/Stack/Stack.tsx +100 -0
- package/src/components/Stack/index.ts +2 -0
- package/src/components/StagePath/StagePath.module.scss +255 -0
- package/src/components/StagePath/StagePath.tokens.scss +43 -0
- package/src/components/StagePath/StagePath.tsx +176 -0
- package/src/components/StagePath/index.ts +2 -0
- package/src/components/StatGroup/StatGroup.module.scss +6 -0
- package/src/components/StatGroup/StatGroup.tsx +70 -0
- package/src/components/StatGroup/StatGroupContext.ts +10 -0
- package/src/components/StatGroup/StatTile.module.scss +99 -0
- package/src/components/StatGroup/StatTile.tokens.scss +35 -0
- package/src/components/StatGroup/StatTile.tsx +143 -0
- package/src/components/StatGroup/index.ts +4 -0
- package/src/components/Sticky/Sticky.module.scss +98 -0
- package/src/components/Sticky/Sticky.tokens.scss +17 -0
- package/src/components/Sticky/Sticky.tsx +103 -0
- package/src/components/Sticky/index.ts +2 -0
- package/src/components/Switch/Switch.module.scss +182 -0
- package/src/components/Switch/Switch.tokens.scss +59 -0
- package/src/components/Switch/Switch.tsx +214 -0
- package/src/components/Switch/index.ts +2 -0
- package/src/components/Table/Table.module.scss +308 -0
- package/src/components/Table/Table.tokens.scss +79 -0
- package/src/components/Table/Table.tsx +381 -0
- package/src/components/Table/index.ts +15 -0
- package/src/components/TableOfContents/TableOfContents.module.scss +83 -0
- package/src/components/TableOfContents/TableOfContents.tokens.scss +26 -0
- package/src/components/TableOfContents/TableOfContents.tsx +192 -0
- package/src/components/TableOfContents/activeSection.ts +18 -0
- package/src/components/TableOfContents/index.ts +2 -0
- package/src/components/Tabs/Tabs.module.scss +359 -0
- package/src/components/Tabs/Tabs.tokens.scss +50 -0
- package/src/components/Tabs/Tabs.tsx +538 -0
- package/src/components/Tabs/index.ts +2 -0
- package/src/components/Text/Text.module.scss +115 -0
- package/src/components/Text/Text.tokens.scss +55 -0
- package/src/components/Text/Text.tsx +197 -0
- package/src/components/Text/index.ts +2 -0
- package/src/components/Textarea/Textarea.module.scss +94 -0
- package/src/components/Textarea/Textarea.tokens.scss +48 -0
- package/src/components/Textarea/Textarea.tsx +246 -0
- package/src/components/Textarea/index.ts +2 -0
- package/src/components/Thread/Thread.module.scss +161 -0
- package/src/components/Thread/Thread.tokens.scss +32 -0
- package/src/components/Thread/Thread.tsx +176 -0
- package/src/components/Thread/index.ts +2 -0
- package/src/components/TimeField/TimeField.module.scss +232 -0
- package/src/components/TimeField/TimeField.tsx +793 -0
- package/src/components/TimeField/index.ts +2 -0
- package/src/components/Timeline/Timeline.module.scss +58 -0
- package/src/components/Timeline/Timeline.tokens.scss +13 -0
- package/src/components/Timeline/Timeline.tsx +53 -0
- package/src/components/Timeline/index.ts +2 -0
- package/src/components/Title/Title.module.scss +84 -0
- package/src/components/Title/Title.tokens.scss +37 -0
- package/src/components/Title/Title.tsx +150 -0
- package/src/components/Title/index.ts +2 -0
- package/src/components/Toast/Toast.module.scss +299 -0
- package/src/components/Toast/Toast.tokens.scss +65 -0
- package/src/components/Toast/Toast.tsx +122 -0
- package/src/components/Toast/ToastViewport.tsx +166 -0
- package/src/components/Toast/api.ts +175 -0
- package/src/components/Toast/index.ts +5 -0
- package/src/components/Toast/store.ts +133 -0
- package/src/components/Toast/useToastTimer.ts +94 -0
- package/src/components/Tooltip/Tooltip.module.scss +99 -0
- package/src/components/Tooltip/Tooltip.tokens.scss +23 -0
- package/src/components/Tooltip/Tooltip.tsx +341 -0
- package/src/components/Tooltip/index.ts +2 -0
- package/src/components/TopBar/TopBar.module.scss +235 -0
- package/src/components/TopBar/TopBar.tokens.scss +79 -0
- package/src/components/TopBar/TopBar.tsx +87 -0
- package/src/components/TopBar/TopBarEnd.tsx +20 -0
- package/src/components/TopBar/TopBarIconButton.tsx +86 -0
- package/src/components/TopBar/TopBarSearch.tsx +319 -0
- package/src/components/TopBar/TopBarSearchPanel.tsx +268 -0
- package/src/components/TopBar/TopBarStart.tsx +20 -0
- package/src/components/TopBar/index.ts +11 -0
- package/src/components/Tour/Spotlight.tsx +121 -0
- package/src/components/Tour/Tour.module.scss +210 -0
- package/src/components/Tour/Tour.tokens.scss +58 -0
- package/src/components/Tour/Tour.tsx +617 -0
- package/src/components/Tour/index.ts +2 -0
- package/src/components/Tour/useTourTarget.ts +115 -0
- package/src/components/TreeView/TreeView.module.scss +268 -0
- package/src/components/TreeView/TreeView.tokens.scss +36 -0
- package/src/components/TreeView/TreeView.tsx +536 -0
- package/src/components/TreeView/index.ts +3 -0
- package/src/components/TreeView/treeModel.ts +224 -0
- package/src/components/VisuallyHidden/VisuallyHidden.module.scss +7 -0
- package/src/components/VisuallyHidden/VisuallyHidden.tsx +29 -0
- package/src/components/VisuallyHidden/index.ts +2 -0
- package/src/components/WidgetPreview/WidgetPreview.module.scss +11 -0
- package/src/components/WidgetPreview/WidgetPreview.tokens.scss +26 -0
- package/src/components/WidgetPreview/WidgetPreview.tsx +36 -0
- package/src/components/WidgetPreview/WidgetShape.module.scss +140 -0
- package/src/components/WidgetPreview/WidgetShape.tsx +159 -0
- package/src/components/WidgetPreview/index.ts +2 -0
- package/src/components/_internal/Trend.tsx +27 -0
- package/src/components/_internal/choiceTile.scss +74 -0
- package/src/components/_internal/collapse.scss +10 -0
- package/src/components/_internal/collapse.ts +58 -0
- package/src/components/_internal/currency.ts +257 -0
- package/src/components/_internal/dragAnnouncements.ts +200 -0
- package/src/components/_internal/fieldWiring.ts +225 -0
- package/src/components/_internal/gridSpan.ts +54 -0
- package/src/components/_internal/isoDay.ts +35 -0
- package/src/components/_internal/letterKey.ts +26 -0
- package/src/components/_internal/overlay/focusRestore.ts +21 -0
- package/src/components/_internal/overlay/index.ts +12 -0
- package/src/components/_internal/overlay/tourHold.ts +23 -0
- package/src/components/_internal/overlay/useFocusTrap.ts +120 -0
- package/src/components/_internal/overlay/useInOverlay.ts +81 -0
- package/src/components/_internal/overlay/useOverlayStack.ts +232 -0
- package/src/components/_internal/overlay/useScrollLock.ts +112 -0
- package/src/components/_internal/refs.ts +48 -0
- package/src/components/_internal/statusColor.ts +26 -0
- package/src/components/_internal/timeUtils.ts +23 -0
- package/src/components/_internal/useAsyncOptions.ts +145 -0
- package/src/components/_internal/useClippedTooltip.ts +50 -0
- package/src/components/_internal/useControllableState.ts +50 -0
- package/src/components.manifest.json +1141 -0
- package/src/hooks/useBelowBreakpoint.ts +58 -0
- package/src/i18n/I18nProvider.tsx +52 -0
- package/src/i18n/LocaleProvider.tsx +17 -0
- package/src/i18n/en.ts +648 -0
- package/src/i18n/format.ts +71 -0
- package/src/i18n/index.ts +13 -0
- package/src/i18n/messages.ts +1275 -0
- package/src/i18n/ru.ts +677 -0
- package/src/i18n/useLocale.ts +19 -0
- package/src/i18n/useTranslation.ts +58 -0
- package/src/index.ts +913 -0
- package/src/palette/index.ts +2 -0
- package/src/palette/palette.ts +108 -0
- package/src/styles/dark.scss +4 -0
- package/src/styles/global.scss +7 -0
- package/src/styles/mixins.scss +143 -0
- package/src/styles/reset.scss +78 -0
- package/src/styles/tokens.scss +18 -0
- package/src/styles/typography.scss +44 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
KeyboardEvent as ReactKeyboardEvent,
|
|
3
|
+
PointerEvent as ReactPointerEvent,
|
|
4
|
+
ReactNode,
|
|
5
|
+
} from 'react';
|
|
6
|
+
import { useTranslation } from '../../i18n/useTranslation';
|
|
7
|
+
import type { ContainerRef, DashboardPlacement } from './engine';
|
|
8
|
+
import styles from './DashboardCanvas.module.scss';
|
|
9
|
+
|
|
10
|
+
/** Which resize handle a resize gesture started from. */
|
|
11
|
+
export type ResizeEdge = 'e' | 's' | 'se';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Gesture wiring handed down from DashboardCanvas to every item, top-level or
|
|
15
|
+
* inside a section. One bag instead of five props so DashboardCanvasSection
|
|
16
|
+
* forwards it untouched.
|
|
17
|
+
*/
|
|
18
|
+
export interface CanvasGestures {
|
|
19
|
+
readOnly: boolean;
|
|
20
|
+
/** Item currently being moved — its cell renders the drop-preview style. */
|
|
21
|
+
movingId: string | number | null;
|
|
22
|
+
/** Item currently being resized — its cell renders the resize affordance. */
|
|
23
|
+
resizingId: string | number | null;
|
|
24
|
+
/** Item currently keyboard-picked — its cell renders the picked style. */
|
|
25
|
+
pickedId: string | number | null;
|
|
26
|
+
/** id of the visually-hidden keyboard instructions block (aria-describedby). */
|
|
27
|
+
instructionsId: string;
|
|
28
|
+
onMovePointerDown: (
|
|
29
|
+
event: ReactPointerEvent<HTMLDivElement>,
|
|
30
|
+
placement: DashboardPlacement,
|
|
31
|
+
container: ContainerRef,
|
|
32
|
+
) => void;
|
|
33
|
+
onResizePointerDown: (
|
|
34
|
+
event: ReactPointerEvent<HTMLDivElement>,
|
|
35
|
+
placement: DashboardPlacement,
|
|
36
|
+
container: ContainerRef,
|
|
37
|
+
edge: ResizeEdge,
|
|
38
|
+
) => void;
|
|
39
|
+
onItemKeyDown: (
|
|
40
|
+
event: ReactKeyboardEvent<HTMLDivElement>,
|
|
41
|
+
placement: DashboardPlacement,
|
|
42
|
+
container: ContainerRef,
|
|
43
|
+
) => void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Stable (y, then x) render order — matches the engine's own processing
|
|
48
|
+
* order (`compact`/`placeWithPushDown`/`stackOrder`), so DOM order always
|
|
49
|
+
* agrees with visual stacking order (load-bearing below the md breakpoint,
|
|
50
|
+
* Task 5, where DOM order becomes the single-column stack order).
|
|
51
|
+
*/
|
|
52
|
+
export function sortByPosition(items: readonly DashboardPlacement[]): DashboardPlacement[] {
|
|
53
|
+
return [...items].sort((a, b) => a.y - b.y || a.x - b.x);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface DashboardCanvasItemProps {
|
|
57
|
+
placement: DashboardPlacement;
|
|
58
|
+
container: ContainerRef;
|
|
59
|
+
gestures: CanvasGestures;
|
|
60
|
+
children: ReactNode;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Internal — one grid cell. Stamps the placement as inline custom properties
|
|
65
|
+
* consumed by `.item` in DashboardCanvas.module.scss (Grid.Item precedent).
|
|
66
|
+
* `data-dc-item` is a stable hook for tests/consumers' CSS, independent of
|
|
67
|
+
* the hashed-in-production module class name.
|
|
68
|
+
*
|
|
69
|
+
* In edit mode the whole cell is the move-drag surface, and E/S/SE resize
|
|
70
|
+
* handles overlay the edges. The handles are pointer-only `aria-hidden` divs
|
|
71
|
+
* (not focusable) — keyboard resize is Shift+arrows on the focused cell, so
|
|
72
|
+
* exposing the handles to AT would only add noise. The cell itself is the
|
|
73
|
+
* keyboard editing surface: role=button (named by the widget's own content,
|
|
74
|
+
* FlowNode precedent) with a localized "widget" roledescription.
|
|
75
|
+
*/
|
|
76
|
+
export function DashboardCanvasItem({
|
|
77
|
+
placement,
|
|
78
|
+
container,
|
|
79
|
+
gestures,
|
|
80
|
+
children,
|
|
81
|
+
}: DashboardCanvasItemProps) {
|
|
82
|
+
const t = useTranslation();
|
|
83
|
+
const { id, x, y, w, h } = placement;
|
|
84
|
+
const {
|
|
85
|
+
readOnly,
|
|
86
|
+
movingId,
|
|
87
|
+
resizingId,
|
|
88
|
+
pickedId,
|
|
89
|
+
instructionsId,
|
|
90
|
+
onMovePointerDown,
|
|
91
|
+
onResizePointerDown,
|
|
92
|
+
onItemKeyDown,
|
|
93
|
+
} = gestures;
|
|
94
|
+
return (
|
|
95
|
+
<div
|
|
96
|
+
className={styles.item}
|
|
97
|
+
data-dc-item={String(id)}
|
|
98
|
+
data-dc-drop-preview={movingId === id ? '' : undefined}
|
|
99
|
+
data-dc-resizing={resizingId === id ? '' : undefined}
|
|
100
|
+
data-dc-picked={pickedId === id ? '' : undefined}
|
|
101
|
+
role={readOnly ? undefined : 'button'}
|
|
102
|
+
tabIndex={readOnly ? undefined : 0}
|
|
103
|
+
aria-roledescription={readOnly ? undefined : t('dashboardCanvas.itemRole')}
|
|
104
|
+
aria-describedby={readOnly ? undefined : instructionsId}
|
|
105
|
+
style={{
|
|
106
|
+
['--dc-col' as string]: `${x + 1} / span ${w}`,
|
|
107
|
+
['--dc-row' as string]: `${y + 1} / span ${h}`,
|
|
108
|
+
// Task 5's below-md single-column rule reads this to keep the
|
|
109
|
+
// item's own height once `--dc-row` stops being consumed.
|
|
110
|
+
['--dc-h-span' as string]: `span ${h}`,
|
|
111
|
+
}}
|
|
112
|
+
onPointerDown={readOnly ? undefined : (e) => onMovePointerDown(e, placement, container)}
|
|
113
|
+
onKeyDown={readOnly ? undefined : (e) => onItemKeyDown(e, placement, container)}
|
|
114
|
+
>
|
|
115
|
+
{children}
|
|
116
|
+
{!readOnly && (
|
|
117
|
+
<>
|
|
118
|
+
<div
|
|
119
|
+
className={styles.handleE}
|
|
120
|
+
data-dc-resize="e"
|
|
121
|
+
aria-hidden="true"
|
|
122
|
+
onPointerDown={(e) => onResizePointerDown(e, placement, container, 'e')}
|
|
123
|
+
/>
|
|
124
|
+
<div
|
|
125
|
+
className={styles.handleS}
|
|
126
|
+
data-dc-resize="s"
|
|
127
|
+
aria-hidden="true"
|
|
128
|
+
onPointerDown={(e) => onResizePointerDown(e, placement, container, 's')}
|
|
129
|
+
/>
|
|
130
|
+
<div
|
|
131
|
+
className={styles.handleSE}
|
|
132
|
+
data-dc-resize="se"
|
|
133
|
+
aria-hidden="true"
|
|
134
|
+
onPointerDown={(e) => onResizePointerDown(e, placement, container, 'se')}
|
|
135
|
+
/>
|
|
136
|
+
</>
|
|
137
|
+
)}
|
|
138
|
+
</div>
|
|
139
|
+
);
|
|
140
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import type {
|
|
3
|
+
KeyboardEvent as ReactKeyboardEvent,
|
|
4
|
+
PointerEvent as ReactPointerEvent,
|
|
5
|
+
ReactNode,
|
|
6
|
+
} from 'react';
|
|
7
|
+
import { GripVertical } from 'lucide-react';
|
|
8
|
+
import { useTranslation } from '../../i18n/useTranslation';
|
|
9
|
+
import { Accordion } from '../Accordion';
|
|
10
|
+
import { Highlight } from '../Highlight';
|
|
11
|
+
import type { ContainerRef, DashboardSection } from './engine';
|
|
12
|
+
import { DashboardCanvasItem, sortByPosition } from './DashboardCanvasItem';
|
|
13
|
+
import type { CanvasGestures } from './DashboardCanvasItem';
|
|
14
|
+
import styles from './DashboardCanvas.module.scss';
|
|
15
|
+
|
|
16
|
+
interface DashboardCanvasSectionProps {
|
|
17
|
+
section: DashboardSection;
|
|
18
|
+
renderItem: (id: string | number) => ReactNode;
|
|
19
|
+
renderSectionHeader?: (id: string | number) => ReactNode;
|
|
20
|
+
gestures: CanvasGestures;
|
|
21
|
+
/** True while this band is being pointer-reordered (styling hook). */
|
|
22
|
+
dragging: boolean;
|
|
23
|
+
/** True while a move-drag hovers this body grid (it alone gets trailing drop space). */
|
|
24
|
+
dropTarget: boolean;
|
|
25
|
+
/** Band-reorder drag zone: the dedicated grip handle only (see remarks below). */
|
|
26
|
+
onHeaderPointerDown: (
|
|
27
|
+
event: ReactPointerEvent<HTMLDivElement>,
|
|
28
|
+
sectionId: string | number,
|
|
29
|
+
) => void;
|
|
30
|
+
/** Keyboard band reorder: Shift+ArrowUp/Down while the trigger button has focus. */
|
|
31
|
+
onHeaderKeyDown: (
|
|
32
|
+
event: ReactKeyboardEvent<HTMLButtonElement>,
|
|
33
|
+
sectionId: string | number,
|
|
34
|
+
) => void;
|
|
35
|
+
/** Registers the body grid in the cross-container drop-target registry. */
|
|
36
|
+
setContainerEl: (cref: ContainerRef, el: HTMLElement | null) => void;
|
|
37
|
+
/** Registers the band root for reorder insertion-index hit-testing. */
|
|
38
|
+
setBandEl: (id: string | number, el: HTMLElement | null) => void;
|
|
39
|
+
/** True while this band is the consumer's `highlightedSectionId`. */
|
|
40
|
+
highlighted: boolean;
|
|
41
|
+
onHighlightDone?: () => void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Internal — one full-width collapsible band, composed from the DS
|
|
46
|
+
* `Accordion` for its header/chevron/panel look and open↔close animation:
|
|
47
|
+
* `Accordion.Item` is the band root, `Accordion.Trigger` the title + chevron
|
|
48
|
+
* (its accessible name is overridden with the toggle's full i18n'd label),
|
|
49
|
+
* `Accordion.Content` the animated body. Open state is driven entirely by
|
|
50
|
+
* `section.collapsed` from the parent's shared `<Accordion type="multiple">` —
|
|
51
|
+
* this component never toggles itself.
|
|
52
|
+
*
|
|
53
|
+
* `Accordion.Content` never unmounts its body (its collapse is a CSS height
|
|
54
|
+
* animation, not a DOM removal), unlike the pre-Accordion custom header this
|
|
55
|
+
* replaces. Two things that invariant used to buy for free are now explicit:
|
|
56
|
+
* `inert` on the body while `collapsed` removes it (and anything the
|
|
57
|
+
* consumer's `renderItem` puts inside it) from focus and the accessibility
|
|
58
|
+
* tree, and `DashboardCanvas.tsx` filters collapsed containers out of both
|
|
59
|
+
* the pointer drop-target hit-test and the keyboard container order.
|
|
60
|
+
*
|
|
61
|
+
* Band drag-reorder gets its own explicit grip handle (`GripVertical`, same
|
|
62
|
+
* icon `Sortable.Handle` uses) instead of "grab anywhere in the header": the
|
|
63
|
+
* Accordion trigger button spans the header's full width by construction
|
|
64
|
+
* (the title lives inside it, for a single accessible name), so there's no
|
|
65
|
+
* separate row surface left to grab without either doubling the toggle as a
|
|
66
|
+
* drag source or reaching into Accordion's private layout. The handle rides
|
|
67
|
+
* in `Accordion.Trigger`'s `actions` slot alongside `renderSectionHeader`
|
|
68
|
+
* extras — both are outside the toggle button by Accordion's own contract,
|
|
69
|
+
* so neither ever starts nor is mistaken for a collapse click.
|
|
70
|
+
*/
|
|
71
|
+
export function DashboardCanvasSection({
|
|
72
|
+
section,
|
|
73
|
+
renderItem,
|
|
74
|
+
renderSectionHeader,
|
|
75
|
+
gestures,
|
|
76
|
+
dragging,
|
|
77
|
+
dropTarget,
|
|
78
|
+
onHeaderPointerDown,
|
|
79
|
+
onHeaderKeyDown,
|
|
80
|
+
setContainerEl,
|
|
81
|
+
setBandEl,
|
|
82
|
+
highlighted,
|
|
83
|
+
onHighlightDone,
|
|
84
|
+
}: DashboardCanvasSectionProps) {
|
|
85
|
+
const t = useTranslation();
|
|
86
|
+
const { id, title, collapsed, items } = section;
|
|
87
|
+
const containerRef: ContainerRef = { kind: 'section', id };
|
|
88
|
+
// Collapsed content stays mounted (Accordion's animation needs real height
|
|
89
|
+
// to animate from/to) but must behave exactly like readOnly: not
|
|
90
|
+
// draggable, not resizable, not keyboard-editable. `inert` below covers
|
|
91
|
+
// consumer-rendered content too; this covers our own item chrome/wiring.
|
|
92
|
+
const itemGestures: CanvasGestures = collapsed ? { ...gestures, readOnly: true } : gestures;
|
|
93
|
+
// #353: while a move (pointer drag or keyboard pick) is in flight, an empty
|
|
94
|
+
// expanded body advertises itself as a drop target. When the drag preview
|
|
95
|
+
// hovers this section the previewed item mounts here, `items` stops being
|
|
96
|
+
// empty, and the hint yields to the regular drop-preview cell.
|
|
97
|
+
const showDropHint =
|
|
98
|
+
!collapsed &&
|
|
99
|
+
items.length === 0 &&
|
|
100
|
+
!gestures.readOnly &&
|
|
101
|
+
(gestures.movingId != null || gestures.pickedId != null);
|
|
102
|
+
|
|
103
|
+
const bandRef = useCallback((el: HTMLElement | null) => setBandEl(id, el), [id, setBandEl]);
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<Highlight active={highlighted} scrollIntoView onDone={onHighlightDone}>
|
|
107
|
+
<Accordion.Item
|
|
108
|
+
value={String(id)}
|
|
109
|
+
ref={bandRef}
|
|
110
|
+
data-dc-section={String(id)}
|
|
111
|
+
data-dragging={dragging ? '' : undefined}
|
|
112
|
+
>
|
|
113
|
+
<Accordion.Trigger
|
|
114
|
+
aria-label={t(
|
|
115
|
+
collapsed ? 'dashboardCanvas.sectionExpand' : 'dashboardCanvas.sectionCollapse',
|
|
116
|
+
{ title },
|
|
117
|
+
)}
|
|
118
|
+
onKeyDown={gestures.readOnly ? undefined : (e) => onHeaderKeyDown(e, id)}
|
|
119
|
+
actions={
|
|
120
|
+
<>
|
|
121
|
+
{renderSectionHeader != null && (
|
|
122
|
+
<div data-dc-section-actions>{renderSectionHeader(id)}</div>
|
|
123
|
+
)}
|
|
124
|
+
{!gestures.readOnly && (
|
|
125
|
+
<div
|
|
126
|
+
className={styles.sectionDragHandle}
|
|
127
|
+
data-dc-section-handle
|
|
128
|
+
aria-hidden="true"
|
|
129
|
+
onPointerDown={(e) => onHeaderPointerDown(e, id)}
|
|
130
|
+
>
|
|
131
|
+
<GripVertical size={14} aria-hidden="true" />
|
|
132
|
+
</div>
|
|
133
|
+
)}
|
|
134
|
+
</>
|
|
135
|
+
}
|
|
136
|
+
>
|
|
137
|
+
{title}
|
|
138
|
+
</Accordion.Trigger>
|
|
139
|
+
<Accordion.Content>
|
|
140
|
+
{/* .sizer: the square-cell measuring box, INSIDE Accordion.Content's
|
|
141
|
+
body padding — its width is the grid's own width, so the `cqw`
|
|
142
|
+
row unit stays square in section bodies too (same wrapper as the
|
|
143
|
+
top-level grid; see DashboardCanvas.tsx). */}
|
|
144
|
+
<div className={styles.sizer}>
|
|
145
|
+
<div
|
|
146
|
+
className={styles.container}
|
|
147
|
+
data-dc-container={String(id)}
|
|
148
|
+
data-dc-empty={items.length === 0 ? '' : undefined}
|
|
149
|
+
data-dc-drop-target={dropTarget ? '' : undefined}
|
|
150
|
+
inert={collapsed}
|
|
151
|
+
ref={(el) => setContainerEl(containerRef, el)}
|
|
152
|
+
>
|
|
153
|
+
{sortByPosition(items).map((item) => (
|
|
154
|
+
<DashboardCanvasItem
|
|
155
|
+
key={item.id}
|
|
156
|
+
placement={item}
|
|
157
|
+
container={containerRef}
|
|
158
|
+
gestures={itemGestures}
|
|
159
|
+
>
|
|
160
|
+
{renderItem(item.id)}
|
|
161
|
+
</DashboardCanvasItem>
|
|
162
|
+
))}
|
|
163
|
+
{showDropHint && (
|
|
164
|
+
<div className={styles.dropHint} data-dc-drop-hint aria-hidden="true">
|
|
165
|
+
{t('dashboardCanvas.dropHint')}
|
|
166
|
+
</div>
|
|
167
|
+
)}
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
</Accordion.Content>
|
|
171
|
+
</Accordion.Item>
|
|
172
|
+
</Highlight>
|
|
173
|
+
);
|
|
174
|
+
}
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure geometry engine for DashboardCanvas: snap-grid placement (24 columns
|
|
3
|
+
* by default; every bounds-aware op takes a trailing `columns`) with
|
|
4
|
+
* Datadog-style push-down collision and vertical compaction. No React, no DOM
|
|
5
|
+
* mutation — every function is deterministic and returns fresh objects,
|
|
6
|
+
* never mutating its inputs.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** One placed item: grid units within its container. */
|
|
10
|
+
export interface DashboardPlacement {
|
|
11
|
+
id: string | number;
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
w: number;
|
|
15
|
+
h: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** A full-width collapsible band with its own sub-grid of items. */
|
|
19
|
+
export interface DashboardSection {
|
|
20
|
+
id: string | number;
|
|
21
|
+
title: string;
|
|
22
|
+
collapsed: boolean;
|
|
23
|
+
items: DashboardPlacement[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Controlled value. Section array order = band order; top-level items render above the first section. */
|
|
27
|
+
export interface DashboardCanvasValue {
|
|
28
|
+
items: DashboardPlacement[];
|
|
29
|
+
sections: DashboardSection[];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Per-item size constraints, by item id. */
|
|
33
|
+
export interface DashboardItemConstraints {
|
|
34
|
+
minW?: number;
|
|
35
|
+
minH?: number;
|
|
36
|
+
maxH?: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Identifies a placement container: the top-level canvas or one section's sub-grid. */
|
|
40
|
+
export type ContainerRef = { kind: 'top' } | { kind: 'section'; id: string | number };
|
|
41
|
+
|
|
42
|
+
/** Default column count of a container grid (`DashboardCanvas`'s `columns` default). */
|
|
43
|
+
export const DASHBOARD_COLUMNS = 24;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Clamps a placement into the grid: `w`/`h` at least 1 (and `minW`/`minH` when
|
|
47
|
+
* set), `h` capped at `maxH`, `w` capped at `columns`, then `x` pulled back so
|
|
48
|
+
* `x + w <= columns` and `x`/`y` floored at 0.
|
|
49
|
+
*/
|
|
50
|
+
export function clampPlacement(
|
|
51
|
+
p: DashboardPlacement,
|
|
52
|
+
c: DashboardItemConstraints | undefined,
|
|
53
|
+
columns: number = DASHBOARD_COLUMNS,
|
|
54
|
+
): DashboardPlacement {
|
|
55
|
+
const w = Math.min(Math.max(p.w, c?.minW ?? 1, 1), columns);
|
|
56
|
+
let h = Math.max(p.h, c?.minH ?? 1, 1);
|
|
57
|
+
if (c?.maxH !== undefined) h = Math.max(Math.min(h, c.maxH), 1);
|
|
58
|
+
const x = Math.min(Math.max(p.x, 0), columns - w);
|
|
59
|
+
const y = Math.max(p.y, 0);
|
|
60
|
+
return { ...p, x, y, w, h };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** True when the two rects overlap; rects that merely touch edges do NOT collide. */
|
|
64
|
+
export function collides(a: DashboardPlacement, b: DashboardPlacement): boolean {
|
|
65
|
+
return a.x < b.x + b.w && b.x < a.x + a.w && a.y < b.y + b.h && b.y < a.y + a.h;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Stable (y, then x) processing order; ties keep input order (Array.sort is stable). */
|
|
69
|
+
function sortByPosition(items: readonly DashboardPlacement[]): DashboardPlacement[] {
|
|
70
|
+
return [...items].sort((a, b) => a.y - b.y || a.x - b.x);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Core packing pass: settles `items` (in stable (y, x) order) each to the
|
|
75
|
+
* lowest collision-free y at its own x-span, treating `obstacles` as fixed.
|
|
76
|
+
* With `fromCurrentY`, an item never rises — it only moves down when it
|
|
77
|
+
* collides (the push-down phase); without it, items drop to the lowest free y
|
|
78
|
+
* (the compaction phase). Returns new placements keyed by id.
|
|
79
|
+
*/
|
|
80
|
+
function settle(
|
|
81
|
+
items: readonly DashboardPlacement[],
|
|
82
|
+
obstacles: DashboardPlacement[],
|
|
83
|
+
fromCurrentY = false,
|
|
84
|
+
): Map<string | number, DashboardPlacement> {
|
|
85
|
+
const placed = [...obstacles];
|
|
86
|
+
const settled = new Map<string | number, DashboardPlacement>();
|
|
87
|
+
for (const item of sortByPosition(items)) {
|
|
88
|
+
let y = fromCurrentY ? item.y : 0;
|
|
89
|
+
for (;;) {
|
|
90
|
+
const probe = { ...item, y };
|
|
91
|
+
const hit = placed.find((other) => collides(probe, other));
|
|
92
|
+
if (!hit) break;
|
|
93
|
+
y = hit.y + hit.h; // just below the collider; y strictly grows, so this terminates
|
|
94
|
+
}
|
|
95
|
+
const next = { ...item, y };
|
|
96
|
+
placed.push(next);
|
|
97
|
+
settled.set(item.id, next);
|
|
98
|
+
}
|
|
99
|
+
return settled;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Pulls every item up to the lowest free y at its own x-span. Stable (y, then
|
|
104
|
+
* x) processing; never changes x; also resolves any pre-existing overlaps
|
|
105
|
+
* deterministically (later item in processing order lands below). Output
|
|
106
|
+
* preserves the input array order.
|
|
107
|
+
*/
|
|
108
|
+
export function compact(items: DashboardPlacement[]): DashboardPlacement[] {
|
|
109
|
+
const settled = settle(items, []);
|
|
110
|
+
return items.map((item) => settled.get(item.id)!);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Datadog push-down drop: `moved` claims its dropped cell for collision
|
|
115
|
+
* resolution — colliding items are pushed down just enough (chains
|
|
116
|
+
* recursively), never sideways — and then the WHOLE layout, `moved` included,
|
|
117
|
+
* compacts vertically, so no placement ever floats over free space. When the
|
|
118
|
+
* drop is collision-free this equals `compact([...others, moved])`. An
|
|
119
|
+
* existing item with `moved.id` is replaced in place; otherwise `moved` is
|
|
120
|
+
* appended.
|
|
121
|
+
*/
|
|
122
|
+
export function placeWithPushDown(
|
|
123
|
+
items: DashboardPlacement[],
|
|
124
|
+
moved: DashboardPlacement,
|
|
125
|
+
): DashboardPlacement[] {
|
|
126
|
+
const rest = items.filter((item) => item.id !== moved.id);
|
|
127
|
+
const pushed = settle(rest, [moved], true);
|
|
128
|
+
const intermediate = items.map((item) =>
|
|
129
|
+
item.id === moved.id ? { ...moved } : pushed.get(item.id)!,
|
|
130
|
+
);
|
|
131
|
+
if (!items.some((item) => item.id === moved.id)) intermediate.push({ ...moved });
|
|
132
|
+
return compact(intermediate);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** Item ids must be unique per container; duplicate ids produce undefined layouts. */
|
|
136
|
+
function containerItems(
|
|
137
|
+
value: DashboardCanvasValue,
|
|
138
|
+
ref: ContainerRef,
|
|
139
|
+
): DashboardPlacement[] | undefined {
|
|
140
|
+
if (ref.kind === 'top') return value.items;
|
|
141
|
+
return value.sections.find((section) => section.id === ref.id)?.items;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Item ids must be unique per container; duplicate ids produce undefined layouts. */
|
|
145
|
+
function withContainerItems(
|
|
146
|
+
value: DashboardCanvasValue,
|
|
147
|
+
ref: ContainerRef,
|
|
148
|
+
items: DashboardPlacement[],
|
|
149
|
+
): DashboardCanvasValue {
|
|
150
|
+
if (ref.kind === 'top') return { ...value, items };
|
|
151
|
+
return {
|
|
152
|
+
...value,
|
|
153
|
+
sections: value.sections.map((section) =>
|
|
154
|
+
section.id === ref.id ? { ...section, items } : section,
|
|
155
|
+
),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function sameContainer(a: ContainerRef, b: ContainerRef): boolean {
|
|
160
|
+
return a.kind === 'top' ? b.kind === 'top' : b.kind === 'section' && a.id === b.id;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Index-wise placement equality — lets `applyMove`/`applyResize` return their
|
|
165
|
+
* input by reference when a gesture resolves to the current layout, so
|
|
166
|
+
* callers can gate commits on `next !== value` alone.
|
|
167
|
+
*/
|
|
168
|
+
function samePlacements(
|
|
169
|
+
a: readonly DashboardPlacement[],
|
|
170
|
+
b: readonly DashboardPlacement[],
|
|
171
|
+
): boolean {
|
|
172
|
+
return (
|
|
173
|
+
a.length === b.length &&
|
|
174
|
+
a.every((p, i) => {
|
|
175
|
+
const q = b[i];
|
|
176
|
+
return p.id === q.id && p.x === q.x && p.y === q.y && p.w === q.w && p.h === q.h;
|
|
177
|
+
})
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Moves an item to cell (x, y) of the `to` container (which may equal `from`).
|
|
183
|
+
* The source compacts after removal; the item is push-down-placed in the
|
|
184
|
+
* target with its coordinates clamped to the grid. Unknown item, missing
|
|
185
|
+
* target container, or a same-container move that resolves to the current
|
|
186
|
+
* layout returns the value unchanged (same reference).
|
|
187
|
+
*/
|
|
188
|
+
export function applyMove(
|
|
189
|
+
value: DashboardCanvasValue,
|
|
190
|
+
from: ContainerRef,
|
|
191
|
+
to: ContainerRef,
|
|
192
|
+
id: string | number,
|
|
193
|
+
x: number,
|
|
194
|
+
y: number,
|
|
195
|
+
columns: number = DASHBOARD_COLUMNS,
|
|
196
|
+
): DashboardCanvasValue {
|
|
197
|
+
const source = containerItems(value, from);
|
|
198
|
+
const item = source?.find((candidate) => candidate.id === id);
|
|
199
|
+
if (!source || !item || containerItems(value, to) === undefined) return value;
|
|
200
|
+
const dropped = clampPlacement({ ...item, x, y }, undefined, columns);
|
|
201
|
+
if (sameContainer(from, to)) {
|
|
202
|
+
const placed = placeWithPushDown(source, dropped);
|
|
203
|
+
return samePlacements(source, placed) ? value : withContainerItems(value, from, placed);
|
|
204
|
+
}
|
|
205
|
+
const removed = withContainerItems(
|
|
206
|
+
value,
|
|
207
|
+
from,
|
|
208
|
+
compact(source.filter((candidate) => candidate.id !== id)),
|
|
209
|
+
);
|
|
210
|
+
return withContainerItems(removed, to, placeWithPushDown(containerItems(removed, to)!, dropped));
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Resizes an item in place (`x` is kept, `y` moves only through the shared
|
|
215
|
+
* vertical compaction): `w`/`h` are clamped by the constraints and by the
|
|
216
|
+
* columns remaining right of `x`, then the layout resettles around it —
|
|
217
|
+
* growing pushes neighbors down, shrinking lets them compact back up.
|
|
218
|
+
* Unknown item, or a resize whose clamped dimensions resolve to the current
|
|
219
|
+
* layout, returns the value unchanged (same reference).
|
|
220
|
+
*/
|
|
221
|
+
export function applyResize(
|
|
222
|
+
value: DashboardCanvasValue,
|
|
223
|
+
container: ContainerRef,
|
|
224
|
+
id: string | number,
|
|
225
|
+
w: number,
|
|
226
|
+
h: number,
|
|
227
|
+
c?: DashboardItemConstraints,
|
|
228
|
+
columns: number = DASHBOARD_COLUMNS,
|
|
229
|
+
): DashboardCanvasValue {
|
|
230
|
+
const items = containerItems(value, container);
|
|
231
|
+
const item = items?.find((candidate) => candidate.id === id);
|
|
232
|
+
if (!items || !item) return value;
|
|
233
|
+
// Outermost floor: an invalid controlled x >= columns must not yield w <= 0.
|
|
234
|
+
const nextW = Math.max(1, Math.min(Math.max(w, c?.minW ?? 1), columns - item.x));
|
|
235
|
+
let nextH = Math.max(h, c?.minH ?? 1, 1);
|
|
236
|
+
if (c?.maxH !== undefined) nextH = Math.max(Math.min(nextH, c.maxH), 1);
|
|
237
|
+
const placed = placeWithPushDown(items, { ...item, w: nextW, h: nextH });
|
|
238
|
+
return samePlacements(items, placed) ? value : withContainerItems(value, container, placed);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** Flips one section's `collapsed` flag; everything else is untouched (same refs). */
|
|
242
|
+
export function toggleSection(
|
|
243
|
+
value: DashboardCanvasValue,
|
|
244
|
+
sectionId: string | number,
|
|
245
|
+
): DashboardCanvasValue {
|
|
246
|
+
if (!value.sections.some((section) => section.id === sectionId)) return value;
|
|
247
|
+
return {
|
|
248
|
+
...value,
|
|
249
|
+
sections: value.sections.map((section) =>
|
|
250
|
+
section.id === sectionId ? { ...section, collapsed: !section.collapsed } : section,
|
|
251
|
+
),
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/** Moves a section band to `toIndex` (clamped into range). Unknown id or no-op index returns the value unchanged. */
|
|
256
|
+
export function reorderSection(
|
|
257
|
+
value: DashboardCanvasValue,
|
|
258
|
+
sectionId: string | number,
|
|
259
|
+
toIndex: number,
|
|
260
|
+
): DashboardCanvasValue {
|
|
261
|
+
const fromIndex = value.sections.findIndex((section) => section.id === sectionId);
|
|
262
|
+
if (fromIndex === -1) return value;
|
|
263
|
+
const target = Math.min(Math.max(toIndex, 0), value.sections.length - 1);
|
|
264
|
+
if (target === fromIndex) return value;
|
|
265
|
+
const sections = [...value.sections];
|
|
266
|
+
const [moved] = sections.splice(fromIndex, 1);
|
|
267
|
+
sections.splice(target, 0, moved);
|
|
268
|
+
return { ...value, sections };
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Flattened below-`md` stacking order: top-level items first, then each
|
|
273
|
+
* section's items in band order; within a container by (y, then x). Collapsed
|
|
274
|
+
* sections are included — the renderer decides whether to show their bodies.
|
|
275
|
+
*/
|
|
276
|
+
export function stackOrder(
|
|
277
|
+
value: DashboardCanvasValue,
|
|
278
|
+
): { container: ContainerRef; id: string | number }[] {
|
|
279
|
+
const out: { container: ContainerRef; id: string | number }[] = [];
|
|
280
|
+
for (const item of sortByPosition(value.items)) {
|
|
281
|
+
out.push({ container: { kind: 'top' }, id: item.id });
|
|
282
|
+
}
|
|
283
|
+
for (const section of value.sections) {
|
|
284
|
+
for (const item of sortByPosition(section.items)) {
|
|
285
|
+
out.push({ container: { kind: 'section', id: section.id }, id: item.id });
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return out;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Snaps a viewport point to a grid cell of the container: each cell owns its
|
|
293
|
+
* trailing gap, x is clamped to [0, columns - 1], y is floored at 0 but
|
|
294
|
+
* unbounded above (the grid grows downward). Zero/negative cell sizes (jsdom)
|
|
295
|
+
* yield cell 0.
|
|
296
|
+
*/
|
|
297
|
+
export function cellFromPoint(
|
|
298
|
+
px: number,
|
|
299
|
+
py: number,
|
|
300
|
+
containerRect: DOMRect,
|
|
301
|
+
colWidth: number,
|
|
302
|
+
rowHeight: number,
|
|
303
|
+
gap: number,
|
|
304
|
+
columns: number = DASHBOARD_COLUMNS,
|
|
305
|
+
): { x: number; y: number } {
|
|
306
|
+
const colPitch = colWidth + gap;
|
|
307
|
+
const rowPitch = rowHeight + gap;
|
|
308
|
+
const rawX = colPitch > 0 ? Math.floor((px - containerRect.left) / colPitch) : 0;
|
|
309
|
+
const rawY = rowPitch > 0 ? Math.floor((py - containerRect.top) / rowPitch) : 0;
|
|
310
|
+
return {
|
|
311
|
+
x: Math.min(Math.max(rawX, 0), columns - 1),
|
|
312
|
+
y: Math.max(rawY, 0),
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Where a drop lands when the pointer is over another item: the hovered
|
|
318
|
+
* item's upper half inserts the dragged item before it (at its `y`), the
|
|
319
|
+
* lower half after it (below its bottom), so stacked widgets reorder instead
|
|
320
|
+
* of snapping to the ghost's origin cell. x follows the ghost (`fallback.x`)
|
|
321
|
+
* clamped inside the hovered item's column span when the dragged item fits in
|
|
322
|
+
* it, otherwise it aligns to the hovered item's left edge (kept on-grid). `px`/`py` are the pointer in
|
|
323
|
+
* fractional cell units relative to the container. Callers pass the ORIGINAL
|
|
324
|
+
* pre-drag `items`, never the live preview — a preview reflows the hovered
|
|
325
|
+
* item and would flip the half under a stationary pointer (oscillation).
|
|
326
|
+
* Over empty cells or the dragged item itself, returns `fallback`.
|
|
327
|
+
*/
|
|
328
|
+
export function insertionCell(
|
|
329
|
+
items: readonly DashboardPlacement[],
|
|
330
|
+
id: string | number,
|
|
331
|
+
w: number,
|
|
332
|
+
px: number,
|
|
333
|
+
py: number,
|
|
334
|
+
fallback: { x: number; y: number },
|
|
335
|
+
columns: number = DASHBOARD_COLUMNS,
|
|
336
|
+
): { x: number; y: number } {
|
|
337
|
+
const t = items.find(
|
|
338
|
+
(i) => i.id !== id && i.x <= px && px < i.x + i.w && i.y <= py && py < i.y + i.h,
|
|
339
|
+
);
|
|
340
|
+
if (!t) return fallback;
|
|
341
|
+
return {
|
|
342
|
+
x:
|
|
343
|
+
w <= t.w
|
|
344
|
+
? Math.min(Math.max(fallback.x, t.x), t.x + t.w - w)
|
|
345
|
+
: Math.max(0, Math.min(t.x, columns - w)),
|
|
346
|
+
y: py < t.y + t.h / 2 ? t.y : t.y + t.h,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/** Clamps a ghost's top-left into `[0, bounds - size]` per axis (never negative). */
|
|
351
|
+
export function clampGhost(
|
|
352
|
+
left: number,
|
|
353
|
+
top: number,
|
|
354
|
+
w: number,
|
|
355
|
+
h: number,
|
|
356
|
+
boundsW: number,
|
|
357
|
+
boundsH: number,
|
|
358
|
+
): { left: number; top: number } {
|
|
359
|
+
return {
|
|
360
|
+
left: Math.min(Math.max(left, 0), Math.max(0, boundsW - w)),
|
|
361
|
+
top: Math.min(Math.max(top, 0), Math.max(0, boundsH - h)),
|
|
362
|
+
};
|
|
363
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { DashboardCanvas } from './DashboardCanvas';
|
|
2
|
+
export type { DashboardCanvasProps, DashboardCanvasConstraintsProp } from './DashboardCanvas';
|
|
3
|
+
export { DASHBOARD_COLUMNS } from './engine';
|
|
4
|
+
export type {
|
|
5
|
+
DashboardPlacement,
|
|
6
|
+
DashboardSection,
|
|
7
|
+
DashboardCanvasValue,
|
|
8
|
+
DashboardItemConstraints,
|
|
9
|
+
} from './engine';
|