@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,293 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build-time helper that derives a dependency graph of every component
|
|
3
|
+
* directory in `src/components/`. Output is committed as
|
|
4
|
+
* `src/components.manifest.json` and consumed by:
|
|
5
|
+
*
|
|
6
|
+
* - the drift-detection Vitest test alongside this file
|
|
7
|
+
* - the playground's `/components/dependencies` page
|
|
8
|
+
* - (future) AI-PRIMER.md auto-generated architecture section
|
|
9
|
+
*
|
|
10
|
+
* The graph is computed from import statements — no per-component
|
|
11
|
+
* metadata to maintain. A component is a "primitive" if it imports no
|
|
12
|
+
* other components in this directory; "composition" otherwise.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { readdirSync, readFileSync } from 'node:fs';
|
|
16
|
+
import { join, dirname } from 'node:path';
|
|
17
|
+
import { fileURLToPath } from 'node:url';
|
|
18
|
+
|
|
19
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20
|
+
const COMPONENTS_DIR = join(__dirname, '..', 'components');
|
|
21
|
+
|
|
22
|
+
export type ComponentTier = 'primitive' | 'composition';
|
|
23
|
+
|
|
24
|
+
export interface ComponentManifestEntry {
|
|
25
|
+
/** `'primitive'` if no other library components are imported; `'composition'` otherwise. */
|
|
26
|
+
tier: ComponentTier;
|
|
27
|
+
/** Functional cluster — derived from `CLUSTERS` map below. `null` if not classified. */
|
|
28
|
+
cluster: string | null;
|
|
29
|
+
/** Sorted list of library components this one imports. Empty for primitives. */
|
|
30
|
+
composes: string[];
|
|
31
|
+
/** Sorted inverse — components that import this one. */
|
|
32
|
+
composedBy: string[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type ComponentManifest = Record<string, ComponentManifestEntry>;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Functional-cluster table. Mirrors the AI-PRIMER.md and AppShell sidebar
|
|
39
|
+
* grouping. Update this when adding a component to keep the cluster
|
|
40
|
+
* column accurate; the test alongside this file fails if a component is
|
|
41
|
+
* unclassified.
|
|
42
|
+
*/
|
|
43
|
+
const CLUSTERS: Record<string, string> = {
|
|
44
|
+
// Layout
|
|
45
|
+
Stack: 'Layout',
|
|
46
|
+
Cluster: 'Layout',
|
|
47
|
+
Constrain: 'Layout',
|
|
48
|
+
Indent: 'Layout',
|
|
49
|
+
AppLayout: 'Layout',
|
|
50
|
+
Divider: 'Layout',
|
|
51
|
+
Grid: 'Layout',
|
|
52
|
+
Split: 'Layout',
|
|
53
|
+
Sticky: 'Layout',
|
|
54
|
+
Masonry: 'Layout',
|
|
55
|
+
Card: 'Layout',
|
|
56
|
+
ScrollArea: 'Layout',
|
|
57
|
+
Page: 'Layout',
|
|
58
|
+
Screen: 'Layout',
|
|
59
|
+
PageHeader: 'Layout',
|
|
60
|
+
|
|
61
|
+
// Forms
|
|
62
|
+
Button: 'Forms',
|
|
63
|
+
SocialButton: 'Forms',
|
|
64
|
+
ButtonGroup: 'Forms',
|
|
65
|
+
Checkbox: 'Forms',
|
|
66
|
+
ColorPicker: 'Forms',
|
|
67
|
+
DatePicker: 'Forms',
|
|
68
|
+
DatePickers: 'Forms',
|
|
69
|
+
RelativeDateInput: 'Forms',
|
|
70
|
+
DateStrip: 'Forms',
|
|
71
|
+
SlotGrid: 'Forms',
|
|
72
|
+
DateRangePicker: 'Forms',
|
|
73
|
+
Field: 'Forms',
|
|
74
|
+
SettingRow: 'Forms',
|
|
75
|
+
FormRow: 'Forms',
|
|
76
|
+
FormSection: 'Forms',
|
|
77
|
+
FileUpload: 'Forms',
|
|
78
|
+
IconPicker: 'Forms',
|
|
79
|
+
ImageCrop: 'Forms',
|
|
80
|
+
Input: 'Forms',
|
|
81
|
+
Kanban: 'Forms',
|
|
82
|
+
LiquidEditor: 'Forms',
|
|
83
|
+
OtpInput: 'Forms',
|
|
84
|
+
PasswordInput: 'Forms',
|
|
85
|
+
PasswordStrengthMeter: 'Forms',
|
|
86
|
+
CurrencySelect: 'Forms',
|
|
87
|
+
MoneyInput: 'Forms',
|
|
88
|
+
PhoneInput: 'Forms',
|
|
89
|
+
Radio: 'Forms',
|
|
90
|
+
OptionsPicker: 'Forms',
|
|
91
|
+
EmojiPicker: 'Forms',
|
|
92
|
+
Select: 'Forms',
|
|
93
|
+
Slider: 'Forms',
|
|
94
|
+
Sortable: 'Forms',
|
|
95
|
+
SortableGroup: 'Forms',
|
|
96
|
+
CatalogPicker: 'Forms',
|
|
97
|
+
PillMenu: 'Forms',
|
|
98
|
+
Switch: 'Forms',
|
|
99
|
+
RichTextEditor: 'Forms',
|
|
100
|
+
Textarea: 'Forms',
|
|
101
|
+
TimeField: 'Forms',
|
|
102
|
+
|
|
103
|
+
// Display
|
|
104
|
+
Avatar: 'Display',
|
|
105
|
+
AgentAvatar: 'Display',
|
|
106
|
+
Image: 'Display',
|
|
107
|
+
QrCode: 'Display',
|
|
108
|
+
MediaTile: 'Display',
|
|
109
|
+
WidgetPreview: 'Display',
|
|
110
|
+
Badge: 'Display',
|
|
111
|
+
Dot: 'Display',
|
|
112
|
+
EntityChip: 'Display',
|
|
113
|
+
Timeline: 'Display',
|
|
114
|
+
StagePath: 'Display',
|
|
115
|
+
Thread: 'Display',
|
|
116
|
+
BrandIcon: 'Display',
|
|
117
|
+
Logo: 'Display',
|
|
118
|
+
DefinitionList: 'Display',
|
|
119
|
+
List: 'Display',
|
|
120
|
+
Calendar: 'Display',
|
|
121
|
+
CircularProgress: 'Display',
|
|
122
|
+
Code: 'Display',
|
|
123
|
+
CodeBlock: 'Display',
|
|
124
|
+
HighlightedText: 'Display',
|
|
125
|
+
CursorPagination: 'Display',
|
|
126
|
+
DashboardCanvas: 'Display',
|
|
127
|
+
DashboardWidget: 'Display',
|
|
128
|
+
StatGroup: 'Display',
|
|
129
|
+
Chart: 'Display',
|
|
130
|
+
Sparkline: 'Display',
|
|
131
|
+
TreeView: 'Display',
|
|
132
|
+
DataTable: 'Display',
|
|
133
|
+
EmptyState: 'Display',
|
|
134
|
+
ErrorState: 'Display',
|
|
135
|
+
IconTile: 'Display',
|
|
136
|
+
FilterChip: 'Display',
|
|
137
|
+
FlowCanvas: 'Display',
|
|
138
|
+
Kbd: 'Display',
|
|
139
|
+
Pagination: 'Display',
|
|
140
|
+
PersonDisplay: 'Display',
|
|
141
|
+
Progress: 'Display',
|
|
142
|
+
Skeleton: 'Display',
|
|
143
|
+
Table: 'Display',
|
|
144
|
+
RichText: 'Display',
|
|
145
|
+
Text: 'Display',
|
|
146
|
+
Title: 'Display',
|
|
147
|
+
|
|
148
|
+
// Feedback
|
|
149
|
+
Alert: 'Feedback',
|
|
150
|
+
Banner: 'Feedback',
|
|
151
|
+
ChatBubble: 'Feedback',
|
|
152
|
+
ChatLauncher: 'Feedback',
|
|
153
|
+
Highlight: 'Feedback',
|
|
154
|
+
Toast: 'Feedback',
|
|
155
|
+
|
|
156
|
+
// Navigation
|
|
157
|
+
Accordion: 'Navigation',
|
|
158
|
+
Breadcrumb: 'Navigation',
|
|
159
|
+
Link: 'Navigation',
|
|
160
|
+
LinkCard: 'Navigation',
|
|
161
|
+
Rail: 'Navigation',
|
|
162
|
+
TableOfContents: 'Navigation',
|
|
163
|
+
Tabs: 'Navigation',
|
|
164
|
+
TopBar: 'Navigation',
|
|
165
|
+
|
|
166
|
+
// Overlays
|
|
167
|
+
ConfirmationPopover: 'Overlays',
|
|
168
|
+
Drawer: 'Overlays',
|
|
169
|
+
DropdownMenu: 'Overlays',
|
|
170
|
+
Lightbox: 'Overlays',
|
|
171
|
+
Modal: 'Overlays',
|
|
172
|
+
Popover: 'Overlays',
|
|
173
|
+
Tooltip: 'Overlays',
|
|
174
|
+
Tour: 'Overlays',
|
|
175
|
+
|
|
176
|
+
// Accessibility
|
|
177
|
+
VisuallyHidden: 'Accessibility',
|
|
178
|
+
LiveRegion: 'Accessibility',
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
// `(?:\.\./)+`, not a single `../`, since #509 — the other half of the flat-walk
|
|
182
|
+
// bug. Once nested files are read, their imports are one level deeper, so
|
|
183
|
+
// `from '../../RichTextEditor/…'` inside RichText/engine/ has to match too.
|
|
184
|
+
// Widening the walk without widening this pattern still sees nothing.
|
|
185
|
+
const FROM_PARENT_PATH = /from\s+['"](?:\.\.\/)+([A-Z][a-zA-Z0-9]+)(?:\/[^'"]*)?['"]/g;
|
|
186
|
+
|
|
187
|
+
function listComponentDirs(): string[] {
|
|
188
|
+
return readdirSync(COMPONENTS_DIR, { withFileTypes: true })
|
|
189
|
+
.filter((entry) => entry.isDirectory())
|
|
190
|
+
.filter((entry) => !entry.name.startsWith('_'))
|
|
191
|
+
.map((entry) => entry.name)
|
|
192
|
+
.sort();
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function collectSourceText(componentDir: string): string {
|
|
196
|
+
// Concatenate every non-test .tsx + .ts file UNDER the component dir so that
|
|
197
|
+
// sub-files (e.g. SVSquare.tsx inside ColorPicker/) contribute their imports
|
|
198
|
+
// to the parent component's dependency set.
|
|
199
|
+
//
|
|
200
|
+
// Recursive since #509. It said "every" and read one level, so nothing in a
|
|
201
|
+
// nested directory counted — RichText/engine/ holds 20 modules and none of
|
|
202
|
+
// them were ever parsed. That hid a real bidirectional dependency between
|
|
203
|
+
// RichText and RichTextEditor for as long as the acyclic gate has been green;
|
|
204
|
+
// the gate was not wrong, it was being fed half the source. Fixing the walk
|
|
205
|
+
// without first breaking that cycle turns the gate red.
|
|
206
|
+
const out: string[] = [];
|
|
207
|
+
const walk = (dir: string) => {
|
|
208
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
209
|
+
const path = join(dir, entry.name);
|
|
210
|
+
if (entry.isDirectory()) {
|
|
211
|
+
walk(path);
|
|
212
|
+
} else if (
|
|
213
|
+
(entry.name.endsWith('.tsx') || entry.name.endsWith('.ts')) &&
|
|
214
|
+
!entry.name.endsWith('.test.tsx') &&
|
|
215
|
+
!entry.name.endsWith('.test.ts')
|
|
216
|
+
) {
|
|
217
|
+
out.push(readFileSync(path, 'utf-8'));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
walk(componentDir);
|
|
222
|
+
return out.join('\n');
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* The import-matching half of the walk, exposed so it can be asserted directly.
|
|
227
|
+
*
|
|
228
|
+
* The pattern has to accept more than one `../` (#509). Nothing in the tree
|
|
229
|
+
* currently exercises that — the only nested directory, RichText/engine, had
|
|
230
|
+
* its single upward import removed when the RichText <-> RichTextEditor cycle
|
|
231
|
+
* was broken — so the manifest looks the same whether the pattern is right or
|
|
232
|
+
* wrong. That is exactly the condition under which a fix rots.
|
|
233
|
+
*/
|
|
234
|
+
export function collectImportsFrom(lines: string[]): string[] {
|
|
235
|
+
return extractParentImports(lines.join('\n'));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function extractParentImports(source: string): string[] {
|
|
239
|
+
const deps = new Set<string>();
|
|
240
|
+
for (const match of source.matchAll(FROM_PARENT_PATH)) {
|
|
241
|
+
deps.add(match[1]);
|
|
242
|
+
}
|
|
243
|
+
return [...deps];
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Build the full component manifest by walking every directory under
|
|
248
|
+
* `src/components/` and parsing its source-file imports. Output is sorted
|
|
249
|
+
* (component keys + composes / composedBy arrays) so the JSON is stable
|
|
250
|
+
* across runs.
|
|
251
|
+
*/
|
|
252
|
+
export function buildManifest(): ComponentManifest {
|
|
253
|
+
const names = listComponentDirs();
|
|
254
|
+
const knownComponents = new Set(names);
|
|
255
|
+
const manifest: ComponentManifest = {};
|
|
256
|
+
|
|
257
|
+
// First pass: populate `composes` for each component.
|
|
258
|
+
for (const name of names) {
|
|
259
|
+
const dir = join(COMPONENTS_DIR, name);
|
|
260
|
+
const src = collectSourceText(dir);
|
|
261
|
+
const imports = extractParentImports(src).filter((n) => knownComponents.has(n) && n !== name);
|
|
262
|
+
imports.sort();
|
|
263
|
+
manifest[name] = {
|
|
264
|
+
tier: imports.length === 0 ? 'primitive' : 'composition',
|
|
265
|
+
cluster: CLUSTERS[name] ?? null,
|
|
266
|
+
composes: imports,
|
|
267
|
+
composedBy: [],
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Second pass: invert the graph for `composedBy`.
|
|
272
|
+
for (const [name, entry] of Object.entries(manifest)) {
|
|
273
|
+
for (const dep of entry.composes) {
|
|
274
|
+
const target = manifest[dep];
|
|
275
|
+
if (target) {
|
|
276
|
+
target.composedBy.push(name);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Sort composedBy lists for stable output.
|
|
282
|
+
for (const entry of Object.values(manifest)) {
|
|
283
|
+
entry.composedBy.sort();
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Return a key-sorted object so JSON.stringify gives deterministic output.
|
|
287
|
+
return Object.fromEntries(
|
|
288
|
+
Object.entries(manifest).sort(([a], [b]) => a.localeCompare(b)),
|
|
289
|
+
) as ComponentManifest;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/** Path to the committed manifest JSON (relative to the design-system root). */
|
|
293
|
+
export const MANIFEST_PATH = join(__dirname, '..', 'components.manifest.json');
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { type ReactNode, useMemo } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
LocaleProvider,
|
|
4
|
+
I18nProvider,
|
|
5
|
+
type DeepPartial,
|
|
6
|
+
type Locale,
|
|
7
|
+
type Messages,
|
|
8
|
+
} from '../i18n';
|
|
9
|
+
import { ToastViewport, type ToastViewportProps } from '../components/Toast';
|
|
10
|
+
import { buildThemeTokenCss, type TokenMap } from './themeTokens';
|
|
11
|
+
|
|
12
|
+
export interface AppProviderProps {
|
|
13
|
+
/**
|
|
14
|
+
* UI-string locale — selects the built-in message bundle. v1 ships `'en'`
|
|
15
|
+
* and `'ru'`. Drives every design-system component's copy via `useTranslation`.
|
|
16
|
+
*/
|
|
17
|
+
locale: Locale;
|
|
18
|
+
/**
|
|
19
|
+
* BCP-47 locale for Intl-facing formatting (Calendar, dates, numbers), read
|
|
20
|
+
* by components via `useLocale`. Optional — defaults to `locale` verbatim
|
|
21
|
+
* (`'en'` / `'ru'` are valid language tags). Set it for a region, e.g.
|
|
22
|
+
* `'en-US'` / `'ru-RU'` / `'en-GB'`.
|
|
23
|
+
*/
|
|
24
|
+
intlLocale?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Deep-partial overrides deep-merged over the built-in messages for `locale`.
|
|
27
|
+
* Supply only the keys you rebrand/retext; the rest fall back to the shipped
|
|
28
|
+
* defaults. Memoize this object — passing a fresh literal every render
|
|
29
|
+
* rebuilds the merged messages each time.
|
|
30
|
+
*/
|
|
31
|
+
translations?: DeepPartial<Messages>;
|
|
32
|
+
/**
|
|
33
|
+
* Toast viewport configuration (`position`, `duration`, …), or `false` to
|
|
34
|
+
* NOT mount a viewport (place `<ToastViewport>` yourself). Omitted ⇒ a
|
|
35
|
+
* viewport is mounted with the library defaults.
|
|
36
|
+
*/
|
|
37
|
+
toast?: ToastViewportProps | false;
|
|
38
|
+
/**
|
|
39
|
+
* CSS design-token overrides applied in BOTH light and dark — a flat map of
|
|
40
|
+
* token name → value (`{ '--color-accent': '#7c3aed', '--radius-md': '6px' }`).
|
|
41
|
+
* Rebrands the design system globally (reaches portaled Modal/Tooltip/Toast).
|
|
42
|
+
* Emitted as a declarative `<style>`; layers over the dark theme correctly.
|
|
43
|
+
* **Memoize this object** — a fresh literal each render rebuilds the CSS.
|
|
44
|
+
*/
|
|
45
|
+
tokens?: TokenMap;
|
|
46
|
+
/**
|
|
47
|
+
* Token overrides applied ONLY in dark (forced `data-theme="dark"` and system
|
|
48
|
+
* `prefers-color-scheme: dark`), merged over `tokens` — use it to tune a token
|
|
49
|
+
* for dark surfaces (e.g. a lighter accent). **Memoize this object.**
|
|
50
|
+
*/
|
|
51
|
+
darkTokens?: TokenMap;
|
|
52
|
+
children: ReactNode;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* App root: composes `LocaleProvider` + `I18nProvider` and mounts the toast viewport.
|
|
57
|
+
* @see docs/setup.md
|
|
58
|
+
*/
|
|
59
|
+
export function AppProvider({
|
|
60
|
+
locale,
|
|
61
|
+
intlLocale,
|
|
62
|
+
translations,
|
|
63
|
+
toast,
|
|
64
|
+
tokens,
|
|
65
|
+
darkTokens,
|
|
66
|
+
children,
|
|
67
|
+
}: AppProviderProps) {
|
|
68
|
+
const tokenCss = useMemo(() => buildThemeTokenCss(tokens, darkTokens), [tokens, darkTokens]);
|
|
69
|
+
return (
|
|
70
|
+
<LocaleProvider locale={intlLocale ?? locale}>
|
|
71
|
+
<I18nProvider locale={locale} overrides={translations}>
|
|
72
|
+
{tokenCss && <style data-eocrm-tokens>{tokenCss}</style>}
|
|
73
|
+
{children}
|
|
74
|
+
{toast !== false && <ToastViewport {...(toast ?? {})} />}
|
|
75
|
+
</I18nProvider>
|
|
76
|
+
</LocaleProvider>
|
|
77
|
+
);
|
|
78
|
+
}
|
package/src/app/index.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A flat map of CSS design-token overrides: custom-property name → value.
|
|
3
|
+
* Keys must start with `--` (e.g. `--color-accent`, `--radius-md`,
|
|
4
|
+
* `--font-family-sans`). Consumed by `<AppProvider tokens>` / `darkTokens`.
|
|
5
|
+
*/
|
|
6
|
+
export type TokenMap = Partial<Record<`--${string}`, string>>;
|
|
7
|
+
|
|
8
|
+
// Read NODE_ENV defensively so the library never throws at module init
|
|
9
|
+
// (mirrors components/Tabs/Tabs.tsx).
|
|
10
|
+
const IS_DEV = typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production';
|
|
11
|
+
|
|
12
|
+
// A valid CSS custom-property name: `--` followed by word chars / dashes.
|
|
13
|
+
const KEY_RE = /^--[\w-]+$/;
|
|
14
|
+
// Characters that could break out of a CSS declaration or the <style> element.
|
|
15
|
+
const UNSAFE_VALUE_RE = /[{}<>]/;
|
|
16
|
+
|
|
17
|
+
function warn(message: string): void {
|
|
18
|
+
if (IS_DEV) console.warn(`[AppProvider] ${message}`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Keep only entries whose key is a valid custom-property name and whose value
|
|
23
|
+
* cannot break out of a CSS declaration / the <style> element. Rejected
|
|
24
|
+
* entries are dropped with a dev warning (the consumer is trusted — this is
|
|
25
|
+
* defensive, not a security boundary). Preserves the map's own key order.
|
|
26
|
+
*/
|
|
27
|
+
function sanitizeEntries(map: TokenMap | undefined): Array<[string, string]> {
|
|
28
|
+
if (!map) return [];
|
|
29
|
+
const out: Array<[string, string]> = [];
|
|
30
|
+
for (const [key, value] of Object.entries(map)) {
|
|
31
|
+
if (value == null) continue;
|
|
32
|
+
if (!KEY_RE.test(key)) {
|
|
33
|
+
warn(`ignoring override with invalid key ${JSON.stringify(key)} (must match --name)`);
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (UNSAFE_VALUE_RE.test(value)) {
|
|
37
|
+
warn(`ignoring override ${key}: value contains an unsafe character ({ } < >)`);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
out.push([key, value]);
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function declarations(entries: Array<[string, string]>, indent: string): string {
|
|
46
|
+
return entries.map(([key, value]) => `${indent}${key}: ${value};`).join('\n');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Each scope also lists an accent-aware selector (`:root:root[data-accent]`) that
|
|
50
|
+
// STRICTLY out-specifies the matching generated `data-accent` block, so overrides
|
|
51
|
+
// win over an accent regardless of <style> order. Specificity: light (0,3,0) >
|
|
52
|
+
// accent light (0,2,0); dark/OS-dark (0,4,0) > accent dark (0,3,0). Dark (0,4,0)
|
|
53
|
+
// also beats light (0,3,0), so `darkTokens` still win in dark with an accent set.
|
|
54
|
+
const LIGHT_SELECTOR = ':root, :root:root[data-accent]';
|
|
55
|
+
const DARK_SELECTOR = ":root[data-theme='dark'], :root:root[data-accent][data-theme='dark']";
|
|
56
|
+
const OS_DARK_SELECTOR =
|
|
57
|
+
":root:not([data-theme='light']), :root:root[data-accent]:not([data-theme='light'])";
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Build the CSS for consumer token overrides, mirroring `dark.scss`'s scopes so
|
|
61
|
+
* the cascade resolves correctly:
|
|
62
|
+
* - `tokens` → `:root {}` plus accent-aware twins (`:root:root[data-accent]`) that
|
|
63
|
+
* win over the generated `data-accent` blocks by specificity, AND re-emitted
|
|
64
|
+
* into the dark scopes so a single map applies in both themes.
|
|
65
|
+
* - `darkTokens` → layered AFTER `tokens` inside the dark scopes only.
|
|
66
|
+
*
|
|
67
|
+
* Returns `null` when there is nothing to emit, so `<AppProvider>` renders no
|
|
68
|
+
* `<style>` for the no-override case (preserving its zero-side-effect default).
|
|
69
|
+
*/
|
|
70
|
+
export function buildThemeTokenCss(tokens?: TokenMap, darkTokens?: TokenMap): string | null {
|
|
71
|
+
const base = sanitizeEntries(tokens);
|
|
72
|
+
const dark = sanitizeEntries(darkTokens);
|
|
73
|
+
if (base.length === 0 && dark.length === 0) return null;
|
|
74
|
+
|
|
75
|
+
const blocks: string[] = [];
|
|
76
|
+
|
|
77
|
+
if (base.length > 0) {
|
|
78
|
+
blocks.push(`${LIGHT_SELECTOR} {\n${declarations(base, ' ')}\n}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// tokens re-emitted into dark so a single map applies in dark too; darkTokens
|
|
82
|
+
// layered after so they win.
|
|
83
|
+
const darkScope = [...base, ...dark];
|
|
84
|
+
if (darkScope.length > 0) {
|
|
85
|
+
blocks.push(`${DARK_SELECTOR} {\n${declarations(darkScope, ' ')}\n}`);
|
|
86
|
+
blocks.push(
|
|
87
|
+
`@media (prefers-color-scheme: dark) {\n` +
|
|
88
|
+
` ${OS_DARK_SELECTOR} {\n` +
|
|
89
|
+
`${declarations(darkScope, ' ')}\n` +
|
|
90
|
+
` }\n}`,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return blocks.join('\n');
|
|
95
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
const MS_PER_DAY = 86_400_000;
|
|
2
|
+
|
|
3
|
+
/** Return a new Date `n` days after `date`. Local-time anchored. Does not mutate `date`. */
|
|
4
|
+
export function addDays(date: Date, n: number): Date {
|
|
5
|
+
const result = new Date(date);
|
|
6
|
+
result.setDate(result.getDate() + n);
|
|
7
|
+
return result;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Return a new Date `n` months after `date`. Clamps day-of-month onto shorter
|
|
12
|
+
* target months (Jan 31 + 1 month → Feb 28/29). Does not mutate `date`.
|
|
13
|
+
*/
|
|
14
|
+
export function addMonths(date: Date, n: number): Date {
|
|
15
|
+
const result = new Date(date);
|
|
16
|
+
const originalDay = result.getDate();
|
|
17
|
+
result.setDate(1);
|
|
18
|
+
result.setMonth(result.getMonth() + n);
|
|
19
|
+
// Clamp day to the target month's last day (handles Jan 31 + 1m → Feb 28/29)
|
|
20
|
+
const lastDay = new Date(result.getFullYear(), result.getMonth() + 1, 0).getDate();
|
|
21
|
+
result.setDate(Math.min(originalDay, lastDay));
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Return a new Date `n` weeks after `date` (sugar for `addDays(date, n * 7)`). */
|
|
26
|
+
export function addWeeks(date: Date, n: number): Date {
|
|
27
|
+
return addDays(date, n * 7);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Return a new Date with the same calendar day at local 00:00:00.000. */
|
|
31
|
+
export function startOfDay(date: Date): Date {
|
|
32
|
+
const result = new Date(date);
|
|
33
|
+
result.setHours(0, 0, 0, 0);
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Return the local-midnight start of the week containing `date`. `weekStartsOn`
|
|
39
|
+
* is the column index of the locale's first-day-of-week (0 = Sunday, 1 = Monday).
|
|
40
|
+
*/
|
|
41
|
+
export function startOfWeek(date: Date, weekStartsOn: 0 | 1 | 2 | 3 | 4 | 5 | 6): Date {
|
|
42
|
+
const result = startOfDay(date);
|
|
43
|
+
const delta = (result.getDay() - weekStartsOn + 7) % 7;
|
|
44
|
+
result.setDate(result.getDate() - delta);
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Return the 1st of `date`'s month at local midnight. */
|
|
49
|
+
export function startOfMonth(date: Date): Date {
|
|
50
|
+
const result = new Date(date.getFullYear(), date.getMonth(), 1);
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Return the last day of `date`'s month at local midnight (e.g., Jan 31, Feb 28/29). */
|
|
55
|
+
export function endOfMonth(date: Date): Date {
|
|
56
|
+
// Day 0 of next month = last day of current month.
|
|
57
|
+
return new Date(date.getFullYear(), date.getMonth() + 1, 0);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** True when `a` and `b` fall on the same calendar day (ignores time component). */
|
|
61
|
+
export function isSameDay(a: Date, b: Date): boolean {
|
|
62
|
+
return (
|
|
63
|
+
a.getFullYear() === b.getFullYear() &&
|
|
64
|
+
a.getMonth() === b.getMonth() &&
|
|
65
|
+
a.getDate() === b.getDate()
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** True when `a` and `b` fall in the same calendar month and year. */
|
|
70
|
+
export function isSameMonth(a: Date, b: Date): boolean {
|
|
71
|
+
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* True when `date` is today. Pass an explicit `now` for deterministic tests;
|
|
76
|
+
* defaults to `new Date()`.
|
|
77
|
+
*/
|
|
78
|
+
export function isToday(date: Date, now: Date = new Date()): boolean {
|
|
79
|
+
return isSameDay(date, now);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* True when `date.getDay()` is in `weekendDays` (e.g., `[0, 6]` for Sat/Sun
|
|
84
|
+
* in most locales; `[5, 6]` for Fri/Sat in ar-SA / he-IL). Use
|
|
85
|
+
* `getWeekendDays(locale)` to derive the array.
|
|
86
|
+
*/
|
|
87
|
+
export function isWeekend(date: Date, weekendDays: readonly number[]): boolean {
|
|
88
|
+
return weekendDays.includes(date.getDay());
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Calendar-day difference between `a` and `b`. DST-safe — rounds to whole
|
|
93
|
+
* days so the ±1 hour offset across a DST boundary doesn't shift the count.
|
|
94
|
+
* Positive when `b` is after `a`.
|
|
95
|
+
*/
|
|
96
|
+
export function daysBetween(a: Date, b: Date): number {
|
|
97
|
+
const startA = startOfDay(a).getTime();
|
|
98
|
+
const startB = startOfDay(b).getTime();
|
|
99
|
+
return Math.round((startB - startA) / MS_PER_DAY);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Return `'YYYY-MM-DD'` in local time. Zero-padded month and day. */
|
|
103
|
+
export function toDateKey(date: Date): string {
|
|
104
|
+
const yyyy = String(date.getFullYear()).padStart(4, '0');
|
|
105
|
+
const mm = String(date.getMonth() + 1).padStart(2, '0');
|
|
106
|
+
const dd = String(date.getDate()).padStart(2, '0');
|
|
107
|
+
return `${yyyy}-${mm}-${dd}`;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Parse a `'YYYY-MM-DD'` key (as produced by `toDateKey`) to a local-midnight Date. */
|
|
111
|
+
export function fromDateKey(key: string): Date {
|
|
112
|
+
const [yyyy, mm, dd] = key.split('-').map(Number);
|
|
113
|
+
return new Date(yyyy, mm - 1, dd);
|
|
114
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const cache = new Map<string, Intl.DateTimeFormat>();
|
|
2
|
+
|
|
3
|
+
function getFormatter(locale: string, options: Intl.DateTimeFormatOptions): Intl.DateTimeFormat {
|
|
4
|
+
const key = `${locale}|${JSON.stringify(options)}`;
|
|
5
|
+
let f = cache.get(key);
|
|
6
|
+
if (!f) {
|
|
7
|
+
f = new Intl.DateTimeFormat(locale, options);
|
|
8
|
+
cache.set(key, f);
|
|
9
|
+
}
|
|
10
|
+
return f;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* "May 2026" / "Май 2026" — capitalized standalone month name + numeric year,
|
|
15
|
+
* without the locale's era suffix.
|
|
16
|
+
*
|
|
17
|
+
* `Intl.DateTimeFormat(locale, { year: 'numeric', month: 'long' })` in some
|
|
18
|
+
* locales (notably `ru-RU`) yields "май 2026 г." — lowercase genitive month
|
|
19
|
+
* with an era marker. For calendar headers we want a nominative-cased
|
|
20
|
+
* standalone month, so we format month and year separately and uppercase the
|
|
21
|
+
* first character of the month with locale-aware casing.
|
|
22
|
+
*/
|
|
23
|
+
export function formatMonth(date: Date, locale: string): string {
|
|
24
|
+
const month = getFormatter(locale, { month: 'long' }).format(date);
|
|
25
|
+
const year = date.getFullYear();
|
|
26
|
+
const capitalized = month.charAt(0).toLocaleUpperCase(locale) + month.slice(1);
|
|
27
|
+
return `${capitalized} ${year}`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** "Mon" (Intl 'short' weekday). */
|
|
31
|
+
export function formatWeekdayShort(date: Date, locale: string): string {
|
|
32
|
+
return getFormatter(locale, { weekday: 'short' }).format(date);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** "M" (Intl 'narrow' weekday — for tight column headers). */
|
|
36
|
+
export function formatWeekdayNarrow(date: Date, locale: string): string {
|
|
37
|
+
return getFormatter(locale, { weekday: 'narrow' }).format(date);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** "Wed 20" */
|
|
41
|
+
export function formatDayShort(date: Date, locale: string): string {
|
|
42
|
+
return getFormatter(locale, { weekday: 'short', day: 'numeric' }).format(date);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** "Wednesday, May 20" */
|
|
46
|
+
export function formatDayLong(date: Date, locale: string): string {
|
|
47
|
+
return getFormatter(locale, { weekday: 'long', month: 'long', day: 'numeric' }).format(date);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** "May 18 – 24, 2026" via Intl.DateTimeFormat#formatRange. */
|
|
51
|
+
export function formatRange(from: Date, to: Date, locale: string): string {
|
|
52
|
+
return getFormatter(locale, { year: 'numeric', month: 'long', day: 'numeric' }).formatRange(
|
|
53
|
+
from,
|
|
54
|
+
to,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** "9 AM" / "09:00" — hour only, 12/24-hour determined by locale default. */
|
|
59
|
+
export function formatHour(hour: number, locale: string): string {
|
|
60
|
+
const date = new Date(2000, 0, 1, hour);
|
|
61
|
+
return getFormatter(locale, { hour: 'numeric' }).format(date);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* "9:00 AM" / "09:00" — hour + minute, suitable for event start times.
|
|
66
|
+
* 12/24-hour determined by locale default.
|
|
67
|
+
*/
|
|
68
|
+
export function formatTime(date: Date, locale: string): string {
|
|
69
|
+
return getFormatter(locale, { hour: 'numeric', minute: '2-digit' }).format(date);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Test-only helper. Resets the formatter cache between tests. */
|
|
73
|
+
export function _resetFormatterCacheForTests(): void {
|
|
74
|
+
cache.clear();
|
|
75
|
+
}
|