@eocrm/design-system 0.0.0-stage → 0.6.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI-PRIMER.md +341 -0
- package/README.md +262 -2
- package/docs/components/Accordion.md +114 -0
- package/docs/components/AgentAvatar.md +58 -0
- package/docs/components/Alert.md +81 -0
- package/docs/components/AppLayout.md +70 -0
- package/docs/components/Avatar.md +49 -0
- package/docs/components/AvatarGroup.md +47 -0
- package/docs/components/Badge.md +60 -0
- package/docs/components/Banner.md +89 -0
- package/docs/components/BrandIcon.md +32 -0
- package/docs/components/Breadcrumb.md +72 -0
- package/docs/components/Button.md +107 -0
- package/docs/components/ButtonGroup.md +78 -0
- package/docs/components/Calendar.md +158 -0
- package/docs/components/Card.md +165 -0
- package/docs/components/CatalogPicker.md +83 -0
- package/docs/components/Chart.md +114 -0
- package/docs/components/ChatBubble.md +55 -0
- package/docs/components/ChatLauncher.md +97 -0
- package/docs/components/Checkbox.md +55 -0
- package/docs/components/CircularProgress.md +53 -0
- package/docs/components/Cluster.md +96 -0
- package/docs/components/Code.md +35 -0
- package/docs/components/CodeBlock.md +67 -0
- package/docs/components/ColorPicker.md +115 -0
- package/docs/components/ConfirmationPopover.md +70 -0
- package/docs/components/Constrain.md +39 -0
- package/docs/components/CurrencySelect.md +57 -0
- package/docs/components/CursorPagination.md +43 -0
- package/docs/components/DashboardCanvas.md +79 -0
- package/docs/components/DashboardWidget.md +131 -0
- package/docs/components/DataTable.md +88 -0
- package/docs/components/DatePicker.md +68 -0
- package/docs/components/DateRangePicker.md +71 -0
- package/docs/components/DateStrip.md +56 -0
- package/docs/components/DefinitionList.md +82 -0
- package/docs/components/Divider.md +57 -0
- package/docs/components/Dot.md +26 -0
- package/docs/components/Drawer.md +94 -0
- package/docs/components/DropdownMenu.md +299 -0
- package/docs/components/EmojiPicker.md +84 -0
- package/docs/components/EmptyState.md +55 -0
- package/docs/components/EntityChip.md +102 -0
- package/docs/components/ErrorState.md +72 -0
- package/docs/components/Field.md +91 -0
- package/docs/components/FileUpload.md +109 -0
- package/docs/components/FilterChip.md +88 -0
- package/docs/components/FlowCanvas.md +108 -0
- package/docs/components/FormRow.md +31 -0
- package/docs/components/FormSection.md +37 -0
- package/docs/components/Grid.md +103 -0
- package/docs/components/Highlight.md +75 -0
- package/docs/components/HighlightedText.md +50 -0
- package/docs/components/IconPicker.md +134 -0
- package/docs/components/IconTile.md +30 -0
- package/docs/components/Image.md +84 -0
- package/docs/components/ImageCrop.md +163 -0
- package/docs/components/Indent.md +31 -0
- package/docs/components/InlineDatePicker.md +58 -0
- package/docs/components/InlineDateRangePicker.md +57 -0
- package/docs/components/Input.md +54 -0
- package/docs/components/Kanban.md +122 -0
- package/docs/components/Kbd.md +41 -0
- package/docs/components/Lightbox.md +105 -0
- package/docs/components/Link.md +65 -0
- package/docs/components/LinkCard.md +41 -0
- package/docs/components/LiquidEditor.md +84 -0
- package/docs/components/List.md +68 -0
- package/docs/components/LiveRegion.md +29 -0
- package/docs/components/LocaleProvider.md +25 -0
- package/docs/components/Logo.md +41 -0
- package/docs/components/Masonry.md +48 -0
- package/docs/components/MediaTile.md +95 -0
- package/docs/components/Modal.md +107 -0
- package/docs/components/MoneyInput.md +62 -0
- package/docs/components/OptionsPicker.md +123 -0
- package/docs/components/OtpInput.md +65 -0
- package/docs/components/Page.md +35 -0
- package/docs/components/PageHeader.md +133 -0
- package/docs/components/Pagination.md +44 -0
- package/docs/components/Palette.md +32 -0
- package/docs/components/PasswordInput.md +45 -0
- package/docs/components/PasswordStrengthMeter.md +27 -0
- package/docs/components/PersonDisplay.md +153 -0
- package/docs/components/PhoneInput.md +54 -0
- package/docs/components/PillMenu.md +91 -0
- package/docs/components/Popover.md +127 -0
- package/docs/components/Progress.md +56 -0
- package/docs/components/QrCode.md +34 -0
- package/docs/components/Radio.md +37 -0
- package/docs/components/RadioGroup.md +56 -0
- package/docs/components/Rail.md +191 -0
- package/docs/components/RelativeDateInput.md +114 -0
- package/docs/components/RichText.md +44 -0
- package/docs/components/RichTextEditor.md +112 -0
- package/docs/components/Screen.md +37 -0
- package/docs/components/ScrollArea.md +39 -0
- package/docs/components/Select.md +131 -0
- package/docs/components/SettingRow.md +98 -0
- package/docs/components/Skeleton.md +68 -0
- package/docs/components/Slider.md +92 -0
- package/docs/components/SlotGrid.md +55 -0
- package/docs/components/SocialButton.md +31 -0
- package/docs/components/Sortable.md +127 -0
- package/docs/components/SortableGroup.md +52 -0
- package/docs/components/Sparkline.md +51 -0
- package/docs/components/Split.md +76 -0
- package/docs/components/Stack.md +59 -0
- package/docs/components/StagePath.md +66 -0
- package/docs/components/StatGroup.md +61 -0
- package/docs/components/StatTile.md +58 -0
- package/docs/components/Sticky.md +69 -0
- package/docs/components/Switch.md +89 -0
- package/docs/components/Table.md +184 -0
- package/docs/components/TableOfContents.md +76 -0
- package/docs/components/Tabs.md +94 -0
- package/docs/components/Text.md +63 -0
- package/docs/components/Textarea.md +59 -0
- package/docs/components/Thread.md +52 -0
- package/docs/components/TimeField.md +70 -0
- package/docs/components/Timeline.md +57 -0
- package/docs/components/Title.md +54 -0
- package/docs/components/ToastViewport.md +61 -0
- package/docs/components/Tooltip.md +63 -0
- package/docs/components/TopBar.md +214 -0
- package/docs/components/Tour.md +85 -0
- package/docs/components/TreeView.md +113 -0
- package/docs/components/VisuallyHidden.md +43 -0
- package/docs/components/WidgetPreview.md +54 -0
- package/docs/components/useBelowBreakpoint.md +11 -0
- package/docs/components/useMonth.md +18 -0
- package/docs/setup.md +51 -0
- package/docs/theming.md +95 -0
- package/docs/tokens.md +123 -0
- package/docs/transient-state.md +56 -0
- package/package.json +82 -4
- package/src/_meta/manifest.ts +293 -0
- package/src/app/AppProvider.tsx +78 -0
- package/src/app/index.ts +3 -0
- package/src/app/themeTokens.ts +95 -0
- package/src/calendar/dateMath.ts +114 -0
- package/src/calendar/formatters.ts +75 -0
- package/src/calendar/index.ts +39 -0
- package/src/calendar/types.ts +36 -0
- package/src/calendar/useAgenda.ts +70 -0
- package/src/calendar/useDay.ts +51 -0
- package/src/calendar/useMonth.ts +82 -0
- package/src/calendar/useWeek.ts +62 -0
- package/src/calendar/weekInfo.ts +83 -0
- package/src/components/Accordion/Accordion.module.scss +304 -0
- package/src/components/Accordion/Accordion.tokens.scss +64 -0
- package/src/components/Accordion/Accordion.tsx +272 -0
- package/src/components/Accordion/AccordionContent.tsx +36 -0
- package/src/components/Accordion/AccordionItem.tsx +66 -0
- package/src/components/Accordion/AccordionTrigger.tsx +121 -0
- package/src/components/Accordion/context.ts +47 -0
- package/src/components/Accordion/index.ts +14 -0
- package/src/components/Alert/Alert.module.scss +92 -0
- package/src/components/Alert/Alert.tokens.scss +60 -0
- package/src/components/Alert/Alert.tsx +136 -0
- package/src/components/Alert/index.ts +2 -0
- package/src/components/AppLayout/AppLayout.module.scss +130 -0
- package/src/components/AppLayout/AppLayout.tokens.scss +27 -0
- package/src/components/AppLayout/AppLayout.tsx +211 -0
- package/src/components/AppLayout/index.ts +2 -0
- package/src/components/Avatar/AgentAvatar.module.scss +117 -0
- package/src/components/Avatar/AgentAvatar.tsx +122 -0
- package/src/components/Avatar/Avatar.module.scss +181 -0
- package/src/components/Avatar/Avatar.tokens.scss +107 -0
- package/src/components/Avatar/Avatar.tsx +210 -0
- package/src/components/Avatar/AvatarGroup.module.scss +128 -0
- package/src/components/Avatar/AvatarGroup.tsx +119 -0
- package/src/components/Avatar/AvatarGroupContext.tsx +20 -0
- package/src/components/Avatar/index.ts +6 -0
- package/src/components/Badge/Badge.module.scss +124 -0
- package/src/components/Badge/Badge.tokens.scss +74 -0
- package/src/components/Badge/Badge.tsx +164 -0
- package/src/components/Badge/index.ts +2 -0
- package/src/components/Banner/Banner.module.scss +73 -0
- package/src/components/Banner/Banner.tokens.scss +51 -0
- package/src/components/Banner/Banner.tsx +138 -0
- package/src/components/Banner/index.ts +2 -0
- package/src/components/BrandIcon/BrandIcon.module.scss +5 -0
- package/src/components/BrandIcon/BrandIcon.tsx +99 -0
- package/src/components/BrandIcon/index.ts +2 -0
- package/src/components/Breadcrumb/Breadcrumb.module.scss +32 -0
- package/src/components/Breadcrumb/Breadcrumb.tokens.scss +9 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +146 -0
- package/src/components/Breadcrumb/index.ts +2 -0
- package/src/components/Button/Button.module.scss +167 -0
- package/src/components/Button/Button.tokens.scss +90 -0
- package/src/components/Button/Button.tsx +205 -0
- package/src/components/Button/index.ts +2 -0
- package/src/components/ButtonGroup/ButtonGroup.module.scss +134 -0
- package/src/components/ButtonGroup/ButtonGroup.tokens.scss +42 -0
- package/src/components/ButtonGroup/ButtonGroup.tsx +278 -0
- package/src/components/ButtonGroup/ButtonGroupItem.tsx +74 -0
- package/src/components/ButtonGroup/context.ts +45 -0
- package/src/components/ButtonGroup/index.ts +2 -0
- package/src/components/Calendar/AgendaView.module.scss +231 -0
- package/src/components/Calendar/AgendaView.tsx +214 -0
- package/src/components/Calendar/AllDayBand.module.scss +18 -0
- package/src/components/Calendar/AllDayBand.tsx +75 -0
- package/src/components/Calendar/Calendar.module.scss +23 -0
- package/src/components/Calendar/Calendar.tokens.scss +262 -0
- package/src/components/Calendar/Calendar.tsx +370 -0
- package/src/components/Calendar/DayCell.module.scss +30 -0
- package/src/components/Calendar/DayCell.tsx +50 -0
- package/src/components/Calendar/DayView.module.scss +10 -0
- package/src/components/Calendar/DayView.tsx +163 -0
- package/src/components/Calendar/EventChip.module.scss +171 -0
- package/src/components/Calendar/EventChip.tsx +115 -0
- package/src/components/Calendar/HourGrid.module.scss +123 -0
- package/src/components/Calendar/HourGrid.tsx +381 -0
- package/src/components/Calendar/MonthView.module.scss +99 -0
- package/src/components/Calendar/MonthView.tsx +296 -0
- package/src/components/Calendar/TimedEvent.module.scss +205 -0
- package/src/components/Calendar/TimedEvent.tsx +247 -0
- package/src/components/Calendar/ViewSwitcher.module.scss +3 -0
- package/src/components/Calendar/ViewSwitcher.tsx +47 -0
- package/src/components/Calendar/WeekView.module.scss +10 -0
- package/src/components/Calendar/WeekView.tsx +137 -0
- package/src/components/Calendar/eventColor.ts +60 -0
- package/src/components/Calendar/index.ts +18 -0
- package/src/components/Calendar/types.ts +451 -0
- package/src/components/Calendar/useEventDrag.ts +783 -0
- package/src/components/Calendar/utils.ts +622 -0
- package/src/components/Card/Card.module.scss +264 -0
- package/src/components/Card/Card.tokens.scss +55 -0
- package/src/components/Card/Card.tsx +170 -0
- package/src/components/Card/CardBody.tsx +45 -0
- package/src/components/Card/CardHeader.tsx +113 -0
- package/src/components/Card/CardList.tsx +24 -0
- package/src/components/Card/CardListRow.tsx +24 -0
- package/src/components/Card/index.ts +7 -0
- package/src/components/CatalogPicker/CatalogPicker.module.scss +193 -0
- package/src/components/CatalogPicker/CatalogPicker.tokens.scss +26 -0
- package/src/components/CatalogPicker/CatalogPicker.tsx +339 -0
- package/src/components/CatalogPicker/index.ts +2 -0
- package/src/components/Chart/Chart.module.scss +287 -0
- package/src/components/Chart/Chart.tokens.scss +63 -0
- package/src/components/Chart/Chart.tsx +607 -0
- package/src/components/Chart/ChartLegend.tsx +99 -0
- package/src/components/Chart/ChartTable.tsx +62 -0
- package/src/components/Chart/ChartTooltip.tsx +91 -0
- package/src/components/Chart/chartModel.ts +689 -0
- package/src/components/Chart/index.ts +2 -0
- package/src/components/ChatBubble/ChatBubble.module.scss +93 -0
- package/src/components/ChatBubble/ChatBubble.tokens.scss +17 -0
- package/src/components/ChatBubble/ChatBubble.tsx +61 -0
- package/src/components/ChatBubble/ChatBubbleList.tsx +27 -0
- package/src/components/ChatBubble/index.ts +3 -0
- package/src/components/ChatLauncher/ChatLauncher.module.scss +68 -0
- package/src/components/ChatLauncher/ChatLauncher.tokens.scss +27 -0
- package/src/components/ChatLauncher/ChatLauncher.tsx +202 -0
- package/src/components/ChatLauncher/index.ts +2 -0
- package/src/components/ChatLauncher/isAtBottom.ts +12 -0
- package/src/components/Checkbox/Checkbox.module.scss +147 -0
- package/src/components/Checkbox/Checkbox.tokens.scss +44 -0
- package/src/components/Checkbox/Checkbox.tsx +188 -0
- package/src/components/Checkbox/index.ts +2 -0
- package/src/components/CircularProgress/CircularProgress.module.scss +133 -0
- package/src/components/CircularProgress/CircularProgress.tokens.scss +40 -0
- package/src/components/CircularProgress/CircularProgress.tsx +139 -0
- package/src/components/CircularProgress/index.ts +7 -0
- package/src/components/Cluster/Cluster.module.scss +145 -0
- package/src/components/Cluster/Cluster.tokens.scss +11 -0
- package/src/components/Cluster/Cluster.tsx +215 -0
- package/src/components/Cluster/index.ts +2 -0
- package/src/components/Code/Code.module.scss +28 -0
- package/src/components/Code/Code.tokens.scss +15 -0
- package/src/components/Code/Code.tsx +44 -0
- package/src/components/Code/index.ts +2 -0
- package/src/components/CodeBlock/CodeBlock.module.scss +146 -0
- package/src/components/CodeBlock/CodeBlock.tokens.scss +27 -0
- package/src/components/CodeBlock/CodeBlock.tsx +274 -0
- package/src/components/CodeBlock/highlight.ts +179 -0
- package/src/components/CodeBlock/index.ts +8 -0
- package/src/components/CodeBlock/sampleSync.ts +42 -0
- package/src/components/ColorPicker/ColorPicker.module.scss +286 -0
- package/src/components/ColorPicker/ColorPicker.tokens.scss +60 -0
- package/src/components/ColorPicker/ColorPicker.tsx +367 -0
- package/src/components/ColorPicker/ColorPickerPanel.tsx +265 -0
- package/src/components/ColorPicker/SVSquare.tsx +189 -0
- package/src/components/ColorPicker/colorMath.ts +141 -0
- package/src/components/ColorPicker/index.ts +6 -0
- package/src/components/ConfirmationPopover/ConfirmationPopover.module.scss +39 -0
- package/src/components/ConfirmationPopover/ConfirmationPopover.tokens.scss +13 -0
- package/src/components/ConfirmationPopover/ConfirmationPopover.tsx +395 -0
- package/src/components/ConfirmationPopover/index.ts +2 -0
- package/src/components/Constrain/Constrain.module.scss +99 -0
- package/src/components/Constrain/Constrain.tsx +79 -0
- package/src/components/Constrain/index.ts +2 -0
- package/src/components/CurrencySelect/CurrencySelect.module.scss +7 -0
- package/src/components/CurrencySelect/CurrencySelect.tsx +167 -0
- package/src/components/CurrencySelect/index.ts +3 -0
- package/src/components/CursorPagination/CursorPagination.module.scss +69 -0
- package/src/components/CursorPagination/CursorPagination.tokens.scss +32 -0
- package/src/components/CursorPagination/CursorPagination.tsx +121 -0
- package/src/components/CursorPagination/index.ts +2 -0
- package/src/components/DashboardCanvas/DashboardCanvas.module.scss +360 -0
- package/src/components/DashboardCanvas/DashboardCanvas.tokens.scss +48 -0
- package/src/components/DashboardCanvas/DashboardCanvas.tsx +1270 -0
- package/src/components/DashboardCanvas/DashboardCanvasItem.tsx +140 -0
- package/src/components/DashboardCanvas/DashboardCanvasSection.tsx +174 -0
- package/src/components/DashboardCanvas/engine.ts +363 -0
- package/src/components/DashboardCanvas/index.ts +9 -0
- package/src/components/DashboardWidget/DashboardWidget.module.scss +100 -0
- package/src/components/DashboardWidget/DashboardWidget.tokens.scss +16 -0
- package/src/components/DashboardWidget/DashboardWidget.tsx +188 -0
- package/src/components/DashboardWidget/index.ts +7 -0
- package/src/components/DataTable/BodyRow.tsx +197 -0
- package/src/components/DataTable/ColumnVisibilityTrigger.module.scss +7 -0
- package/src/components/DataTable/ColumnVisibilityTrigger.tsx +105 -0
- package/src/components/DataTable/DataTable.module.scss +511 -0
- package/src/components/DataTable/DataTable.tokens.scss +80 -0
- package/src/components/DataTable/DataTable.tsx +734 -0
- package/src/components/DataTable/HeaderCell.module.scss +215 -0
- package/src/components/DataTable/HeaderCell.tsx +440 -0
- package/src/components/DataTable/columnShift.ts +117 -0
- package/src/components/DataTable/index.ts +23 -0
- package/src/components/DataTable/pinStyle.ts +47 -0
- package/src/components/DataTable/reorderColumns.ts +66 -0
- package/src/components/DataTable/types.ts +289 -0
- package/src/components/DataTable/useColumnDragShift.ts +216 -0
- package/src/components/DataTable/useDataTable.ts +372 -0
- package/src/components/DataTable/useResizeHandle.ts +97 -0
- package/src/components/DatePicker/DatePicker.module.scss +180 -0
- package/src/components/DatePicker/DatePicker.tokens.scss +152 -0
- package/src/components/DatePicker/DatePicker.tsx +664 -0
- package/src/components/DatePicker/DatePickerGrid.module.scss +172 -0
- package/src/components/DatePicker/DatePickerGrid.tsx +341 -0
- package/src/components/DatePicker/InlineDatePicker.module.scss +32 -0
- package/src/components/DatePicker/InlineDatePicker.tsx +201 -0
- package/src/components/DatePicker/index.ts +4 -0
- package/src/components/DatePicker/utils.ts +364 -0
- package/src/components/DateRangePicker/DateRangePicker.module.scss +237 -0
- package/src/components/DateRangePicker/DateRangePicker.tokens.scss +78 -0
- package/src/components/DateRangePicker/DateRangePicker.tsx +720 -0
- package/src/components/DateRangePicker/InlineDateRangePicker.module.scss +94 -0
- package/src/components/DateRangePicker/InlineDateRangePicker.tsx +376 -0
- package/src/components/DateRangePicker/index.ts +5 -0
- package/src/components/DateRangePicker/utils.ts +151 -0
- package/src/components/DateStrip/DateStrip.module.scss +78 -0
- package/src/components/DateStrip/DateStrip.tokens.scss +23 -0
- package/src/components/DateStrip/DateStrip.tsx +205 -0
- package/src/components/DateStrip/index.ts +2 -0
- package/src/components/DefinitionList/DefinitionList.module.scss +102 -0
- package/src/components/DefinitionList/DefinitionList.tokens.scss +29 -0
- package/src/components/DefinitionList/DefinitionList.tsx +198 -0
- package/src/components/DefinitionList/index.ts +9 -0
- package/src/components/Divider/Divider.module.scss +144 -0
- package/src/components/Divider/Divider.tokens.scss +21 -0
- package/src/components/Divider/Divider.tsx +103 -0
- package/src/components/Divider/index.ts +2 -0
- package/src/components/Dot/Dot.module.scss +40 -0
- package/src/components/Dot/Dot.tokens.scss +4 -0
- package/src/components/Dot/Dot.tsx +45 -0
- package/src/components/Dot/index.ts +2 -0
- package/src/components/Drawer/Body.tsx +23 -0
- package/src/components/Drawer/Close.tsx +35 -0
- package/src/components/Drawer/Content.tsx +93 -0
- package/src/components/Drawer/Drawer.module.scss +232 -0
- package/src/components/Drawer/Drawer.tokens.scss +38 -0
- package/src/components/Drawer/Drawer.tsx +23 -0
- package/src/components/Drawer/DrawerRoot.tsx +190 -0
- package/src/components/Drawer/Footer.tsx +24 -0
- package/src/components/Drawer/Header.tsx +64 -0
- package/src/components/Drawer/Overlay.tsx +82 -0
- package/src/components/Drawer/context.ts +44 -0
- package/src/components/Drawer/index.ts +12 -0
- package/src/components/Drawer/useDragToClose.ts +149 -0
- package/src/components/DropdownMenu/CheckboxItem.tsx +144 -0
- package/src/components/DropdownMenu/Content.tsx +419 -0
- package/src/components/DropdownMenu/DropdownMenu.module.scss +280 -0
- package/src/components/DropdownMenu/DropdownMenu.tokens.scss +88 -0
- package/src/components/DropdownMenu/DropdownMenu.tsx +43 -0
- package/src/components/DropdownMenu/Group.tsx +76 -0
- package/src/components/DropdownMenu/Item.tsx +148 -0
- package/src/components/DropdownMenu/ItemIndicator.tsx +30 -0
- package/src/components/DropdownMenu/Radio.tsx +178 -0
- package/src/components/DropdownMenu/Root.tsx +100 -0
- package/src/components/DropdownMenu/Sub.tsx +332 -0
- package/src/components/DropdownMenu/Trigger.tsx +76 -0
- package/src/components/DropdownMenu/context.ts +65 -0
- package/src/components/DropdownMenu/index.ts +20 -0
- package/src/components/EmojiPicker/EmojiPicker.module.scss +84 -0
- package/src/components/EmojiPicker/EmojiPicker.tokens.scss +24 -0
- package/src/components/EmojiPicker/EmojiPicker.tsx +341 -0
- package/src/components/EmojiPicker/emojiData.ts +245 -0
- package/src/components/EmojiPicker/index.ts +3 -0
- package/src/components/EmptyState/EmptyState.module.scss +102 -0
- package/src/components/EmptyState/EmptyState.tokens.scss +28 -0
- package/src/components/EmptyState/EmptyState.tsx +112 -0
- package/src/components/EmptyState/index.ts +7 -0
- package/src/components/EntityChip/EntityChip.module.scss +275 -0
- package/src/components/EntityChip/EntityChip.tokens.scss +66 -0
- package/src/components/EntityChip/EntityChip.tsx +649 -0
- package/src/components/EntityChip/index.ts +10 -0
- package/src/components/ErrorState/ErrorState.module.scss +105 -0
- package/src/components/ErrorState/ErrorState.tokens.scss +32 -0
- package/src/components/ErrorState/ErrorState.tsx +125 -0
- package/src/components/ErrorState/index.ts +8 -0
- package/src/components/Field/Field.module.scss +46 -0
- package/src/components/Field/Field.tsx +185 -0
- package/src/components/Field/index.ts +2 -0
- package/src/components/FileUpload/FileUpload.module.scss +187 -0
- package/src/components/FileUpload/FileUpload.tokens.scss +81 -0
- package/src/components/FileUpload/FileUpload.tsx +569 -0
- package/src/components/FileUpload/formatBytes.ts +34 -0
- package/src/components/FileUpload/iconForFile.ts +40 -0
- package/src/components/FileUpload/index.ts +2 -0
- package/src/components/FilterChip/FilterChip.module.scss +61 -0
- package/src/components/FilterChip/FilterChip.tokens.scss +25 -0
- package/src/components/FilterChip/FilterChip.tsx +208 -0
- package/src/components/FilterChip/index.ts +5 -0
- package/src/components/FlowCanvas/FlowCanvas.module.scss +329 -0
- package/src/components/FlowCanvas/FlowCanvas.tokens.scss +45 -0
- package/src/components/FlowCanvas/FlowCanvas.tsx +1867 -0
- package/src/components/FlowCanvas/FlowControls.tsx +46 -0
- package/src/components/FlowCanvas/FlowEdge.tsx +58 -0
- package/src/components/FlowCanvas/FlowNode.tsx +76 -0
- package/src/components/FlowCanvas/edgePath.ts +85 -0
- package/src/components/FlowCanvas/index.ts +4 -0
- package/src/components/FlowCanvas/layout.ts +148 -0
- package/src/components/FlowCanvas/spatialNav.ts +76 -0
- package/src/components/FlowCanvas/types.ts +59 -0
- package/src/components/FlowCanvas/useViewport.ts +122 -0
- package/src/components/FormRow/FormRow.module.scss +2 -0
- package/src/components/FormRow/FormRow.tsx +37 -0
- package/src/components/FormRow/index.ts +2 -0
- package/src/components/FormSection/FormSection.module.scss +24 -0
- package/src/components/FormSection/FormSection.tsx +46 -0
- package/src/components/FormSection/index.ts +2 -0
- package/src/components/Grid/Grid.module.scss +162 -0
- package/src/components/Grid/Grid.tokens.scss +13 -0
- package/src/components/Grid/Grid.tsx +226 -0
- package/src/components/Grid/GridItem.tsx +77 -0
- package/src/components/Grid/index.ts +11 -0
- package/src/components/Highlight/Highlight.module.scss +43 -0
- package/src/components/Highlight/Highlight.tokens.scss +35 -0
- package/src/components/Highlight/Highlight.tsx +164 -0
- package/src/components/Highlight/HighlightOverlay.tsx +100 -0
- package/src/components/Highlight/index.ts +2 -0
- package/src/components/HighlightedText/HighlightedText.module.scss +11 -0
- package/src/components/HighlightedText/HighlightedText.tokens.scss +9 -0
- package/src/components/HighlightedText/HighlightedText.tsx +50 -0
- package/src/components/HighlightedText/highlightRanges.ts +44 -0
- package/src/components/HighlightedText/index.ts +2 -0
- package/src/components/IconPicker/IconPicker.module.scss +175 -0
- package/src/components/IconPicker/IconPicker.tokens.scss +40 -0
- package/src/components/IconPicker/IconPicker.tsx +629 -0
- package/src/components/IconPicker/index.ts +9 -0
- package/src/components/IconTile/IconTile.module.scss +57 -0
- package/src/components/IconTile/IconTile.tokens.scss +16 -0
- package/src/components/IconTile/IconTile.tsx +91 -0
- package/src/components/IconTile/index.ts +2 -0
- package/src/components/Image/Image.module.scss +266 -0
- package/src/components/Image/Image.tokens.scss +55 -0
- package/src/components/Image/Image.tsx +342 -0
- package/src/components/Image/index.ts +2 -0
- package/src/components/ImageCrop/ImageCrop.module.scss +274 -0
- package/src/components/ImageCrop/ImageCrop.tokens.scss +33 -0
- package/src/components/ImageCrop/ImageCrop.tsx +542 -0
- package/src/components/ImageCrop/cropGeometry.ts +120 -0
- package/src/components/ImageCrop/extractCropBlob.ts +140 -0
- package/src/components/ImageCrop/index.ts +11 -0
- package/src/components/ImageCrop/useCropPreview.ts +161 -0
- package/src/components/Indent/Indent.module.scss +33 -0
- package/src/components/Indent/Indent.tokens.scss +10 -0
- package/src/components/Indent/Indent.tsx +46 -0
- package/src/components/Indent/index.ts +2 -0
- package/src/components/Input/Input.module.scss +99 -0
- package/src/components/Input/Input.tokens.scss +54 -0
- package/src/components/Input/Input.tsx +105 -0
- package/src/components/Input/Suggestions.tsx +260 -0
- package/src/components/Input/index.ts +2 -0
- package/src/components/Kanban/Kanban.module.scss +39 -0
- package/src/components/Kanban/Kanban.tokens.scss +15 -0
- package/src/components/Kanban/Kanban.tsx +951 -0
- package/src/components/Kanban/index.ts +7 -0
- package/src/components/Kbd/Kbd.module.scss +47 -0
- package/src/components/Kbd/Kbd.tokens.scss +26 -0
- package/src/components/Kbd/Kbd.tsx +73 -0
- package/src/components/Kbd/index.ts +2 -0
- package/src/components/Lightbox/Lightbox.module.scss +283 -0
- package/src/components/Lightbox/Lightbox.tokens.scss +36 -0
- package/src/components/Lightbox/Lightbox.tsx +506 -0
- package/src/components/Lightbox/index.ts +2 -0
- package/src/components/Link/Link.module.scss +78 -0
- package/src/components/Link/Link.tokens.scss +28 -0
- package/src/components/Link/Link.tsx +114 -0
- package/src/components/Link/index.ts +2 -0
- package/src/components/LinkCard/LinkCard.module.scss +92 -0
- package/src/components/LinkCard/LinkCard.tokens.scss +9 -0
- package/src/components/LinkCard/LinkCard.tsx +72 -0
- package/src/components/LinkCard/index.ts +2 -0
- package/src/components/LiquidEditor/AutocompleteMenu.tsx +133 -0
- package/src/components/LiquidEditor/HighlightLayer.tsx +53 -0
- package/src/components/LiquidEditor/InsertVariableMenu.tsx +81 -0
- package/src/components/LiquidEditor/LiquidEditor.module.scss +339 -0
- package/src/components/LiquidEditor/LiquidEditor.tokens.scss +81 -0
- package/src/components/LiquidEditor/LiquidEditor.tsx +412 -0
- package/src/components/LiquidEditor/PreviewPane.tsx +29 -0
- package/src/components/LiquidEditor/caretCoordinates.ts +97 -0
- package/src/components/LiquidEditor/index.ts +7 -0
- package/src/components/LiquidEditor/liquidFilters.ts +23 -0
- package/src/components/LiquidEditor/liquidTokenizer.ts +235 -0
- package/src/components/LiquidEditor/types.ts +101 -0
- package/src/components/LiquidEditor/useLiquidAutocomplete.ts +178 -0
- package/src/components/List/List.module.scss +105 -0
- package/src/components/List/List.tokens.scss +42 -0
- package/src/components/List/List.tsx +124 -0
- package/src/components/List/index.ts +9 -0
- package/src/components/LiveRegion/LiveRegion.module.scss +3 -0
- package/src/components/LiveRegion/LiveRegion.tsx +116 -0
- package/src/components/LiveRegion/index.ts +2 -0
- package/src/components/Logo/Logo.module.scss +139 -0
- package/src/components/Logo/Logo.tokens.scss +14 -0
- package/src/components/Logo/Logo.tsx +126 -0
- package/src/components/Logo/index.ts +2 -0
- package/src/components/Masonry/Masonry.module.scss +42 -0
- package/src/components/Masonry/Masonry.tokens.scss +8 -0
- package/src/components/Masonry/Masonry.tsx +136 -0
- package/src/components/Masonry/index.ts +2 -0
- package/src/components/Masonry/masonryUtils.ts +42 -0
- package/src/components/MediaTile/MediaTile.module.scss +183 -0
- package/src/components/MediaTile/MediaTile.tokens.scss +60 -0
- package/src/components/MediaTile/MediaTile.tsx +208 -0
- package/src/components/MediaTile/index.ts +8 -0
- package/src/components/Modal/Body.tsx +27 -0
- package/src/components/Modal/Close.tsx +45 -0
- package/src/components/Modal/Content.tsx +98 -0
- package/src/components/Modal/Footer.tsx +28 -0
- package/src/components/Modal/Header.tsx +51 -0
- package/src/components/Modal/Modal.module.scss +262 -0
- package/src/components/Modal/Modal.tokens.scss +50 -0
- package/src/components/Modal/Modal.tsx +23 -0
- package/src/components/Modal/ModalRoot.tsx +299 -0
- package/src/components/Modal/Overlay.tsx +101 -0
- package/src/components/Modal/context.ts +60 -0
- package/src/components/Modal/index.ts +11 -0
- package/src/components/MoneyInput/MoneyInput.module.scss +57 -0
- package/src/components/MoneyInput/MoneyInput.tsx +433 -0
- package/src/components/MoneyInput/index.ts +2 -0
- package/src/components/OptionsPicker/OptionsPicker.module.scss +216 -0
- package/src/components/OptionsPicker/OptionsPicker.tokens.scss +68 -0
- package/src/components/OptionsPicker/OptionsPicker.tsx +936 -0
- package/src/components/OptionsPicker/index.ts +9 -0
- package/src/components/OtpInput/OtpInput.module.scss +69 -0
- package/src/components/OtpInput/OtpInput.tokens.scss +45 -0
- package/src/components/OtpInput/OtpInput.tsx +368 -0
- package/src/components/OtpInput/index.ts +2 -0
- package/src/components/Page/Page.module.scss +30 -0
- package/src/components/Page/Page.tokens.scss +11 -0
- package/src/components/Page/Page.tsx +53 -0
- package/src/components/Page/index.ts +2 -0
- package/src/components/PageHeader/PageHeader.module.scss +197 -0
- package/src/components/PageHeader/PageHeader.tokens.scss +41 -0
- package/src/components/PageHeader/PageHeader.tsx +310 -0
- package/src/components/PageHeader/index.ts +20 -0
- package/src/components/Pagination/Pagination.module.scss +117 -0
- package/src/components/Pagination/Pagination.tokens.scss +54 -0
- package/src/components/Pagination/Pagination.tsx +165 -0
- package/src/components/Pagination/index.ts +4 -0
- package/src/components/Pagination/paginationRange.ts +72 -0
- package/src/components/PasswordInput/PasswordInput.module.scss +120 -0
- package/src/components/PasswordInput/PasswordInput.tokens.scss +44 -0
- package/src/components/PasswordInput/PasswordInput.tsx +210 -0
- package/src/components/PasswordInput/index.ts +2 -0
- package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.module.scss +80 -0
- package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tokens.scss +40 -0
- package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tsx +96 -0
- package/src/components/PasswordStrengthMeter/index.ts +2 -0
- package/src/components/PersonDisplay/PersonDisplay.module.scss +180 -0
- package/src/components/PersonDisplay/PersonDisplay.tokens.scss +35 -0
- package/src/components/PersonDisplay/PersonDisplay.tsx +420 -0
- package/src/components/PersonDisplay/index.ts +10 -0
- package/src/components/PhoneInput/PhoneInput.module.scss +23 -0
- package/src/components/PhoneInput/PhoneInput.tsx +271 -0
- package/src/components/PhoneInput/index.ts +4 -0
- package/src/components/PhoneInput/phone.ts +128 -0
- package/src/components/PillMenu/PillMenu.module.scss +117 -0
- package/src/components/PillMenu/PillMenu.tokens.scss +22 -0
- package/src/components/PillMenu/PillMenu.tsx +324 -0
- package/src/components/PillMenu/index.ts +2 -0
- package/src/components/Popover/Anchor.tsx +37 -0
- package/src/components/Popover/Close.tsx +45 -0
- package/src/components/Popover/Content.tsx +213 -0
- package/src/components/Popover/Heading.tsx +33 -0
- package/src/components/Popover/Popover.module.scss +177 -0
- package/src/components/Popover/Popover.tokens.scss +22 -0
- package/src/components/Popover/Popover.tsx +23 -0
- package/src/components/Popover/PopoverRoot.tsx +75 -0
- package/src/components/Popover/Trigger.tsx +86 -0
- package/src/components/Popover/context.ts +22 -0
- package/src/components/Popover/index.ts +7 -0
- package/src/components/Progress/Progress.module.scss +110 -0
- package/src/components/Progress/Progress.tokens.scss +44 -0
- package/src/components/Progress/Progress.tsx +129 -0
- package/src/components/Progress/index.ts +2 -0
- package/src/components/QrCode/QrCode.module.scss +97 -0
- package/src/components/QrCode/QrCode.tokens.scss +17 -0
- package/src/components/QrCode/QrCode.tsx +233 -0
- package/src/components/QrCode/index.ts +2 -0
- package/src/components/QrCode/qr.ts +161 -0
- package/src/components/Radio/Radio.module.scss +175 -0
- package/src/components/Radio/Radio.tokens.scss +59 -0
- package/src/components/Radio/Radio.tsx +127 -0
- package/src/components/Radio/RadioGroup.module.scss +42 -0
- package/src/components/Radio/RadioGroup.tsx +120 -0
- package/src/components/Radio/RadioGroupContext.tsx +30 -0
- package/src/components/Radio/index.ts +4 -0
- package/src/components/Rail/Rail.module.scss +510 -0
- package/src/components/Rail/Rail.tokens.scss +92 -0
- package/src/components/Rail/Rail.tsx +287 -0
- package/src/components/Rail/RailCollapseToggle.tsx +57 -0
- package/src/components/Rail/RailFooter.tsx +17 -0
- package/src/components/Rail/RailGroup.tsx +728 -0
- package/src/components/Rail/RailGroupContext.ts +9 -0
- package/src/components/Rail/RailHeader.tsx +23 -0
- package/src/components/Rail/RailItem.tsx +119 -0
- package/src/components/Rail/RailSection.tsx +39 -0
- package/src/components/Rail/RailSpacer.tsx +19 -0
- package/src/components/Rail/index.ts +9 -0
- package/src/components/RelativeDateInput/RelativeDateInput.module.scss +15 -0
- package/src/components/RelativeDateInput/RelativeDateInput.tokens.scss +6 -0
- package/src/components/RelativeDateInput/RelativeDateInput.tsx +474 -0
- package/src/components/RelativeDateInput/index.ts +10 -0
- package/src/components/RelativeDateInput/relativeDate.ts +127 -0
- package/src/components/RichText/RichText.module.scss +5 -0
- package/src/components/RichText/RichText.tsx +70 -0
- package/src/components/RichText/RichTextAttachment.module.scss +82 -0
- package/src/components/RichText/RichTextAttachment.tsx +122 -0
- package/src/components/RichText/_prose.scss +79 -0
- package/src/components/RichText/attachmentIcon.tsx +24 -0
- package/src/components/RichText/engine/attachment.ts +154 -0
- package/src/components/RichText/engine/autolink.ts +64 -0
- package/src/components/RichText/engine/blockUnit.ts +174 -0
- package/src/components/RichText/engine/colorMarks.ts +85 -0
- package/src/components/RichText/engine/escape.ts +11 -0
- package/src/components/RichText/engine/fromHtml.ts +353 -0
- package/src/components/RichText/engine/fromMarkdown.ts +20 -0
- package/src/components/RichText/engine/inlines.ts +82 -0
- package/src/components/RichText/engine/listDepths.ts +32 -0
- package/src/components/RichText/engine/marks.ts +80 -0
- package/src/components/RichText/engine/mdToHtml.ts +178 -0
- package/src/components/RichText/engine/model.ts +157 -0
- package/src/components/RichText/engine/position.ts +118 -0
- package/src/components/RichText/engine/renderDoc.tsx +395 -0
- package/src/components/RichText/engine/renderLink.ts +15 -0
- package/src/components/RichText/engine/renderMention.ts +16 -0
- package/src/components/RichText/engine/safeHref.ts +22 -0
- package/src/components/RichText/engine/toHtml.ts +154 -0
- package/src/components/RichText/engine/toMarkdown.ts +97 -0
- package/src/components/RichText/engine/transforms.ts +434 -0
- package/src/components/RichText/imageMaxHeightStyle.ts +10 -0
- package/src/components/RichText/index.ts +31 -0
- package/src/components/RichTextEditor/RichTextAttachmentConfig.tsx +264 -0
- package/src/components/RichTextEditor/RichTextBlockControls.tsx +365 -0
- package/src/components/RichTextEditor/RichTextBlockMenu.tsx +162 -0
- package/src/components/RichTextEditor/RichTextColorMenu.tsx +115 -0
- package/src/components/RichTextEditor/RichTextEditor.module.scss +298 -0
- package/src/components/RichTextEditor/RichTextEditor.tsx +1910 -0
- package/src/components/RichTextEditor/RichTextImageResizer.tsx +131 -0
- package/src/components/RichTextEditor/RichTextLinkEditor.tsx +151 -0
- package/src/components/RichTextEditor/RichTextMentionMenu.tsx +99 -0
- package/src/components/RichTextEditor/RichTextToolbar.tsx +379 -0
- package/src/components/RichTextEditor/autolinkInput.ts +65 -0
- package/src/components/RichTextEditor/blockDrop.ts +9 -0
- package/src/components/RichTextEditor/blockReflow.ts +62 -0
- package/src/components/RichTextEditor/commands.ts +300 -0
- package/src/components/RichTextEditor/history.ts +93 -0
- package/src/components/RichTextEditor/icons.tsx +152 -0
- package/src/components/RichTextEditor/imageSize.ts +70 -0
- package/src/components/RichTextEditor/index.ts +5 -0
- package/src/components/RichTextEditor/input.ts +209 -0
- package/src/components/RichTextEditor/inputRules.ts +71 -0
- package/src/components/RichTextEditor/links.ts +103 -0
- package/src/components/RichTextEditor/mentionContext.ts +37 -0
- package/src/components/RichTextEditor/mentions.ts +28 -0
- package/src/components/RichTextEditor/preventSelectionLoss.ts +15 -0
- package/src/components/RichTextEditor/selection.ts +415 -0
- package/src/components/RichTextEditor/shortcuts.ts +44 -0
- package/src/components/RichTextEditor/useAnchoredFloating.ts +50 -0
- package/src/components/RichTextEditor/useAttachmentConfig.ts +134 -0
- package/src/components/RichTextEditor/useDismissOnOutsidePointerDown.ts +26 -0
- package/src/components/RichTextEditor/useLinkEditor.ts +107 -0
- package/src/components/RichTextEditor/useMention.ts +226 -0
- package/src/components/RichTextEditor/useOverlayRect.ts +73 -0
- package/src/components/RichTextEditor/useUpload.ts +246 -0
- package/src/components/Screen/Screen.module.scss +46 -0
- package/src/components/Screen/Screen.tokens.scss +20 -0
- package/src/components/Screen/Screen.tsx +97 -0
- package/src/components/Screen/index.ts +2 -0
- package/src/components/ScrollArea/ScrollArea.module.scss +39 -0
- package/src/components/ScrollArea/ScrollArea.tokens.scss +15 -0
- package/src/components/ScrollArea/ScrollArea.tsx +154 -0
- package/src/components/ScrollArea/index.ts +2 -0
- package/src/components/Select/Chip.tsx +45 -0
- package/src/components/Select/Empty.tsx +39 -0
- package/src/components/Select/Error.tsx +51 -0
- package/src/components/Select/HiddenInputs.tsx +44 -0
- package/src/components/Select/Listbox.tsx +557 -0
- package/src/components/Select/Loading.tsx +30 -0
- package/src/components/Select/Select.module.scss +512 -0
- package/src/components/Select/Select.tokens.scss +140 -0
- package/src/components/Select/Select.tsx +685 -0
- package/src/components/Select/Trigger.tsx +952 -0
- package/src/components/Select/context.ts +101 -0
- package/src/components/Select/emptyStateText.ts +19 -0
- package/src/components/Select/index.ts +9 -0
- package/src/components/Select/useSelectState.ts +157 -0
- package/src/components/Select/utils-types.ts +7 -0
- package/src/components/Select/utils.ts +122 -0
- package/src/components/SettingRow/SettingRow.module.scss +166 -0
- package/src/components/SettingRow/SettingRow.tokens.scss +37 -0
- package/src/components/SettingRow/SettingRow.tsx +242 -0
- package/src/components/SettingRow/index.ts +7 -0
- package/src/components/Skeleton/Skeleton.module.scss +55 -0
- package/src/components/Skeleton/Skeleton.tokens.scss +17 -0
- package/src/components/Skeleton/Skeleton.tsx +131 -0
- package/src/components/Skeleton/index.ts +4 -0
- package/src/components/Skeleton/useSkeletonVisibility.ts +95 -0
- package/src/components/Slider/Slider.module.scss +293 -0
- package/src/components/Slider/Slider.tokens.scss +98 -0
- package/src/components/Slider/Slider.tsx +624 -0
- package/src/components/Slider/index.ts +9 -0
- package/src/components/SlotGrid/SlotGrid.module.scss +61 -0
- package/src/components/SlotGrid/SlotGrid.tokens.scss +21 -0
- package/src/components/SlotGrid/SlotGrid.tsx +111 -0
- package/src/components/SlotGrid/index.ts +2 -0
- package/src/components/SocialButton/SocialButton.module.scss +4 -0
- package/src/components/SocialButton/SocialButton.tsx +40 -0
- package/src/components/SocialButton/index.ts +2 -0
- package/src/components/Sortable/Sortable.module.scss +177 -0
- package/src/components/Sortable/Sortable.tokens.scss +27 -0
- package/src/components/Sortable/Sortable.tsx +572 -0
- package/src/components/Sortable/containerAwareCollision.ts +125 -0
- package/src/components/Sortable/index.ts +13 -0
- package/src/components/SortableGroup/SortableGroup.module.scss +23 -0
- package/src/components/SortableGroup/SortableGroup.tsx +315 -0
- package/src/components/SortableGroup/index.ts +4 -0
- package/src/components/SortableGroup/moveSortableItem.ts +39 -0
- package/src/components/Sparkline/Sparkline.module.scss +28 -0
- package/src/components/Sparkline/Sparkline.tokens.scss +7 -0
- package/src/components/Sparkline/Sparkline.tsx +133 -0
- package/src/components/Sparkline/index.ts +2 -0
- package/src/components/Sparkline/sparklineModel.ts +119 -0
- package/src/components/Split/Split.module.scss +158 -0
- package/src/components/Split/Split.tokens.scss +10 -0
- package/src/components/Split/Split.tsx +231 -0
- package/src/components/Split/index.ts +2 -0
- package/src/components/Stack/Stack.module.scss +67 -0
- package/src/components/Stack/Stack.tokens.scss +11 -0
- package/src/components/Stack/Stack.tsx +100 -0
- package/src/components/Stack/index.ts +2 -0
- package/src/components/StagePath/StagePath.module.scss +255 -0
- package/src/components/StagePath/StagePath.tokens.scss +43 -0
- package/src/components/StagePath/StagePath.tsx +176 -0
- package/src/components/StagePath/index.ts +2 -0
- package/src/components/StatGroup/StatGroup.module.scss +6 -0
- package/src/components/StatGroup/StatGroup.tsx +70 -0
- package/src/components/StatGroup/StatGroupContext.ts +10 -0
- package/src/components/StatGroup/StatTile.module.scss +99 -0
- package/src/components/StatGroup/StatTile.tokens.scss +35 -0
- package/src/components/StatGroup/StatTile.tsx +143 -0
- package/src/components/StatGroup/index.ts +4 -0
- package/src/components/Sticky/Sticky.module.scss +98 -0
- package/src/components/Sticky/Sticky.tokens.scss +17 -0
- package/src/components/Sticky/Sticky.tsx +103 -0
- package/src/components/Sticky/index.ts +2 -0
- package/src/components/Switch/Switch.module.scss +182 -0
- package/src/components/Switch/Switch.tokens.scss +59 -0
- package/src/components/Switch/Switch.tsx +214 -0
- package/src/components/Switch/index.ts +2 -0
- package/src/components/Table/Table.module.scss +308 -0
- package/src/components/Table/Table.tokens.scss +79 -0
- package/src/components/Table/Table.tsx +381 -0
- package/src/components/Table/index.ts +15 -0
- package/src/components/TableOfContents/TableOfContents.module.scss +83 -0
- package/src/components/TableOfContents/TableOfContents.tokens.scss +26 -0
- package/src/components/TableOfContents/TableOfContents.tsx +192 -0
- package/src/components/TableOfContents/activeSection.ts +18 -0
- package/src/components/TableOfContents/index.ts +2 -0
- package/src/components/Tabs/Tabs.module.scss +359 -0
- package/src/components/Tabs/Tabs.tokens.scss +50 -0
- package/src/components/Tabs/Tabs.tsx +538 -0
- package/src/components/Tabs/index.ts +2 -0
- package/src/components/Text/Text.module.scss +115 -0
- package/src/components/Text/Text.tokens.scss +55 -0
- package/src/components/Text/Text.tsx +197 -0
- package/src/components/Text/index.ts +2 -0
- package/src/components/Textarea/Textarea.module.scss +94 -0
- package/src/components/Textarea/Textarea.tokens.scss +48 -0
- package/src/components/Textarea/Textarea.tsx +246 -0
- package/src/components/Textarea/index.ts +2 -0
- package/src/components/Thread/Thread.module.scss +161 -0
- package/src/components/Thread/Thread.tokens.scss +32 -0
- package/src/components/Thread/Thread.tsx +176 -0
- package/src/components/Thread/index.ts +2 -0
- package/src/components/TimeField/TimeField.module.scss +232 -0
- package/src/components/TimeField/TimeField.tsx +793 -0
- package/src/components/TimeField/index.ts +2 -0
- package/src/components/Timeline/Timeline.module.scss +58 -0
- package/src/components/Timeline/Timeline.tokens.scss +13 -0
- package/src/components/Timeline/Timeline.tsx +53 -0
- package/src/components/Timeline/index.ts +2 -0
- package/src/components/Title/Title.module.scss +84 -0
- package/src/components/Title/Title.tokens.scss +37 -0
- package/src/components/Title/Title.tsx +150 -0
- package/src/components/Title/index.ts +2 -0
- package/src/components/Toast/Toast.module.scss +299 -0
- package/src/components/Toast/Toast.tokens.scss +65 -0
- package/src/components/Toast/Toast.tsx +122 -0
- package/src/components/Toast/ToastViewport.tsx +166 -0
- package/src/components/Toast/api.ts +175 -0
- package/src/components/Toast/index.ts +5 -0
- package/src/components/Toast/store.ts +133 -0
- package/src/components/Toast/useToastTimer.ts +94 -0
- package/src/components/Tooltip/Tooltip.module.scss +99 -0
- package/src/components/Tooltip/Tooltip.tokens.scss +23 -0
- package/src/components/Tooltip/Tooltip.tsx +341 -0
- package/src/components/Tooltip/index.ts +2 -0
- package/src/components/TopBar/TopBar.module.scss +235 -0
- package/src/components/TopBar/TopBar.tokens.scss +79 -0
- package/src/components/TopBar/TopBar.tsx +87 -0
- package/src/components/TopBar/TopBarEnd.tsx +20 -0
- package/src/components/TopBar/TopBarIconButton.tsx +86 -0
- package/src/components/TopBar/TopBarSearch.tsx +319 -0
- package/src/components/TopBar/TopBarSearchPanel.tsx +268 -0
- package/src/components/TopBar/TopBarStart.tsx +20 -0
- package/src/components/TopBar/index.ts +11 -0
- package/src/components/Tour/Spotlight.tsx +121 -0
- package/src/components/Tour/Tour.module.scss +210 -0
- package/src/components/Tour/Tour.tokens.scss +58 -0
- package/src/components/Tour/Tour.tsx +617 -0
- package/src/components/Tour/index.ts +2 -0
- package/src/components/Tour/useTourTarget.ts +115 -0
- package/src/components/TreeView/TreeView.module.scss +268 -0
- package/src/components/TreeView/TreeView.tokens.scss +36 -0
- package/src/components/TreeView/TreeView.tsx +536 -0
- package/src/components/TreeView/index.ts +3 -0
- package/src/components/TreeView/treeModel.ts +224 -0
- package/src/components/VisuallyHidden/VisuallyHidden.module.scss +7 -0
- package/src/components/VisuallyHidden/VisuallyHidden.tsx +29 -0
- package/src/components/VisuallyHidden/index.ts +2 -0
- package/src/components/WidgetPreview/WidgetPreview.module.scss +11 -0
- package/src/components/WidgetPreview/WidgetPreview.tokens.scss +26 -0
- package/src/components/WidgetPreview/WidgetPreview.tsx +36 -0
- package/src/components/WidgetPreview/WidgetShape.module.scss +140 -0
- package/src/components/WidgetPreview/WidgetShape.tsx +159 -0
- package/src/components/WidgetPreview/index.ts +2 -0
- package/src/components/_internal/Trend.tsx +27 -0
- package/src/components/_internal/choiceTile.scss +74 -0
- package/src/components/_internal/collapse.scss +10 -0
- package/src/components/_internal/collapse.ts +58 -0
- package/src/components/_internal/currency.ts +257 -0
- package/src/components/_internal/dragAnnouncements.ts +200 -0
- package/src/components/_internal/fieldWiring.ts +225 -0
- package/src/components/_internal/gridSpan.ts +54 -0
- package/src/components/_internal/isoDay.ts +35 -0
- package/src/components/_internal/letterKey.ts +26 -0
- package/src/components/_internal/overlay/focusRestore.ts +21 -0
- package/src/components/_internal/overlay/index.ts +12 -0
- package/src/components/_internal/overlay/tourHold.ts +23 -0
- package/src/components/_internal/overlay/useFocusTrap.ts +120 -0
- package/src/components/_internal/overlay/useInOverlay.ts +81 -0
- package/src/components/_internal/overlay/useOverlayStack.ts +232 -0
- package/src/components/_internal/overlay/useScrollLock.ts +112 -0
- package/src/components/_internal/refs.ts +48 -0
- package/src/components/_internal/statusColor.ts +26 -0
- package/src/components/_internal/timeUtils.ts +23 -0
- package/src/components/_internal/useAsyncOptions.ts +145 -0
- package/src/components/_internal/useClippedTooltip.ts +50 -0
- package/src/components/_internal/useControllableState.ts +50 -0
- package/src/components.manifest.json +1141 -0
- package/src/hooks/useBelowBreakpoint.ts +58 -0
- package/src/i18n/I18nProvider.tsx +52 -0
- package/src/i18n/LocaleProvider.tsx +17 -0
- package/src/i18n/en.ts +648 -0
- package/src/i18n/format.ts +71 -0
- package/src/i18n/index.ts +13 -0
- package/src/i18n/messages.ts +1275 -0
- package/src/i18n/ru.ts +677 -0
- package/src/i18n/useLocale.ts +19 -0
- package/src/i18n/useTranslation.ts +58 -0
- package/src/index.ts +913 -0
- package/src/palette/index.ts +2 -0
- package/src/palette/palette.ts +108 -0
- package/src/styles/dark.scss +4 -0
- package/src/styles/global.scss +7 -0
- package/src/styles/mixins.scss +143 -0
- package/src/styles/reset.scss +78 -0
- package/src/styles/tokens.scss +18 -0
- package/src/styles/typography.scss +44 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cloneElement,
|
|
3
|
+
Fragment,
|
|
4
|
+
isValidElement,
|
|
5
|
+
useId,
|
|
6
|
+
type ReactElement,
|
|
7
|
+
type ReactNode,
|
|
8
|
+
} from 'react';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* `Boolean(n)`, plus: an empty RE-ITERABLE container (array, `Set`, or `Map`
|
|
12
|
+
* used directly — NOT `Map.values()`/`.entries()`, see below) and an empty
|
|
13
|
+
* fragment (`<></>`) count as ABSENT rather than present. `Boolean(label)`
|
|
14
|
+
* alone treats both as truthy when empty, so `Field`/`SettingRow` used to render
|
|
15
|
+
* a real, empty `<label>` and point `aria-labelledby` at it — and a
|
|
16
|
+
* real-but-empty referent is authoritative in the accname algorithm, so it
|
|
17
|
+
* silently named the control `""` instead of falling through to anything else.
|
|
18
|
+
* Use this everywhere a `hasX` predicate feeds BOTH a render gate (should
|
|
19
|
+
* something visible exist) and an ARIA reference (does that visible thing
|
|
20
|
+
* actually name/describe the control) — `hasLabel`, `hasDescription`, `hasError`.
|
|
21
|
+
*
|
|
22
|
+
* Known, deliberate limits:
|
|
23
|
+
* - This cannot see a REAL element with empty visual content
|
|
24
|
+
* (`label={<span />}`) or a whitespace-only string (`label=" "`) — both are
|
|
25
|
+
* still truthy content as far as this function is concerned, same as
|
|
26
|
+
* `Boolean(x)` was. Detecting those needs rendering the element and
|
|
27
|
+
* inspecting its content, which this predicate does not attempt.
|
|
28
|
+
* - A one-shot iterator — `Map.prototype.values()`, a generator — always
|
|
29
|
+
* counts as PRESENT, empty or not. Round 8 tried inspecting it (spreading
|
|
30
|
+
* the iterator to check), which reads correctly here but then hands React
|
|
31
|
+
* the same, now-exhausted iterator to render — React gets nothing, so a
|
|
32
|
+
* non-empty generator silently produced an empty `<label>` and suppressed
|
|
33
|
+
* the control's own `aria-label`: this predicate's own bug, reintroduced by
|
|
34
|
+
* the fix for it. You cannot ask a one-shot iterator whether it is empty
|
|
35
|
+
* without spending it, so this only inspects containers that survive being
|
|
36
|
+
* read twice (arrays, `Set`, a `Map` itself — iterating any of them fresh
|
|
37
|
+
* each time, unlike the iterator `.values()`/`.entries()` RETURN) and
|
|
38
|
+
* otherwise falls back to `Boolean(n)`, which is `true` for any non-null
|
|
39
|
+
* object — same as an untouched iterator reaching React does. Nobody
|
|
40
|
+
* passes `label={someGenerator()}` on purpose; React itself dev-warns on
|
|
41
|
+
* both iterator and `Map` children regardless ("Using Maps as children is
|
|
42
|
+
* not supported").
|
|
43
|
+
*/
|
|
44
|
+
export function hasContent(n: ReactNode): boolean {
|
|
45
|
+
// Only RE-ITERABLE containers are inspected — reading them (`[...n]`) to
|
|
46
|
+
// check for content doesn't consume what React later reads to render them.
|
|
47
|
+
// A one-shot iterator (generator, `Map.values()`/`.entries()`) is
|
|
48
|
+
// deliberately NOT matched here — see the "Known, deliberate limits" doc
|
|
49
|
+
// above. `n instanceof Map` catches a Map passed DIRECTLY (its default
|
|
50
|
+
// iteration yields `[k, v]` tuples — themselves arrays of ReactNode-legal
|
|
51
|
+
// values, so this recurses into them correctly), which is a real,
|
|
52
|
+
// type-legal, re-iterable input distinct from its one-shot `.values()`.
|
|
53
|
+
if (Array.isArray(n) || n instanceof Set || n instanceof Map) {
|
|
54
|
+
return [...(n as Iterable<ReactNode>)].some(hasContent);
|
|
55
|
+
}
|
|
56
|
+
if (isValidElement(n) && n.type === Fragment) {
|
|
57
|
+
return hasContent((n.props as { children?: ReactNode }).children);
|
|
58
|
+
}
|
|
59
|
+
return Boolean(n);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** The wiring a field-like component hands to its control. Spread onto the control in render-prop form. */
|
|
63
|
+
export interface FieldRenderProps {
|
|
64
|
+
id: string;
|
|
65
|
+
'aria-describedby': string | undefined;
|
|
66
|
+
/** Id of the label element to name the control — set only when a label is rendered. */
|
|
67
|
+
'aria-labelledby': string | undefined;
|
|
68
|
+
'aria-invalid': boolean | undefined;
|
|
69
|
+
invalid: boolean;
|
|
70
|
+
required: boolean;
|
|
71
|
+
/** Id of the label/caption element — for manual `aria-labelledby` wiring. */
|
|
72
|
+
labelId: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface FieldWiringOptions {
|
|
76
|
+
/** Explicit control id. Omit to let the wiring own it (auto-generated). */
|
|
77
|
+
id?: string;
|
|
78
|
+
/** Whether the caller renders a label — drives `aria-labelledby` injection. */
|
|
79
|
+
hasLabel: boolean;
|
|
80
|
+
/** Whether the caller renders a description — drives `aria-describedby` when there is no error. */
|
|
81
|
+
hasDescription: boolean;
|
|
82
|
+
/** Truthy when the caller renders an error message. */
|
|
83
|
+
hasError: boolean;
|
|
84
|
+
/** Marks the control required. */
|
|
85
|
+
required?: boolean;
|
|
86
|
+
/** Group mode (radio/checkbox sets): skip id/ARIA injection, inject only `invalid`/`required`. */
|
|
87
|
+
asGroup?: boolean;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface FieldWiring {
|
|
91
|
+
controlId: string;
|
|
92
|
+
labelId: string;
|
|
93
|
+
descriptionId: string;
|
|
94
|
+
errorId: string;
|
|
95
|
+
/** The id the control's `aria-describedby` should point at — error wins over description. */
|
|
96
|
+
describedBy: string | undefined;
|
|
97
|
+
/** The id the control's `aria-labelledby` should point at — set only when a label is rendered. */
|
|
98
|
+
labelledBy: string | undefined;
|
|
99
|
+
invalid: boolean;
|
|
100
|
+
/** Auto-wire a single element child, or invoke a render-prop with `field`. */
|
|
101
|
+
wire: (children: ReactNode | ((field: FieldRenderProps) => ReactNode)) => ReactNode;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Shared control wiring for `<Field>` and `<SettingRow>`: id ownership, the
|
|
106
|
+
* `aria-describedby` error-over-description choice, `aria-invalid`, and the
|
|
107
|
+
* `cloneElement` injection onto a single child.
|
|
108
|
+
*
|
|
109
|
+
* Extracted rather than copied because the `||`-not-`??` rule below is subtle
|
|
110
|
+
* and load-bearing for every named input in the library.
|
|
111
|
+
*/
|
|
112
|
+
export function useFieldWiring({
|
|
113
|
+
id,
|
|
114
|
+
hasLabel,
|
|
115
|
+
hasDescription,
|
|
116
|
+
hasError,
|
|
117
|
+
required,
|
|
118
|
+
asGroup = false,
|
|
119
|
+
}: FieldWiringOptions): FieldWiring {
|
|
120
|
+
const reactId = useId();
|
|
121
|
+
const controlId = id ?? reactId;
|
|
122
|
+
const labelId = `${controlId}-label`;
|
|
123
|
+
const descriptionId = `${controlId}-description`;
|
|
124
|
+
const errorId = `${controlId}-error`;
|
|
125
|
+
|
|
126
|
+
const invalid = hasError;
|
|
127
|
+
const requiredBool = Boolean(required);
|
|
128
|
+
const describedBy = hasError ? errorId : hasDescription ? descriptionId : undefined;
|
|
129
|
+
// Single source for the labelledby value, same shape as describedBy above —
|
|
130
|
+
// computed once and reused by the render-prop field object, the
|
|
131
|
+
// cloneElement branch below, AND returned to the caller (Field's `asGroup`
|
|
132
|
+
// wrapper reads this instead of re-deriving `hasLabel ? labelId : undefined`
|
|
133
|
+
// a third time), so none of them can recompute `hasLabel` a different way
|
|
134
|
+
// and drift (that drift is exactly what shipped: the render-prop path and
|
|
135
|
+
// the cloneElement path used to each derive this independently).
|
|
136
|
+
const labelledBy = hasLabel ? labelId : undefined;
|
|
137
|
+
|
|
138
|
+
const field: FieldRenderProps = {
|
|
139
|
+
id: controlId,
|
|
140
|
+
'aria-describedby': describedBy,
|
|
141
|
+
'aria-labelledby': labelledBy,
|
|
142
|
+
'aria-invalid': invalid || undefined,
|
|
143
|
+
invalid,
|
|
144
|
+
required: requiredBool,
|
|
145
|
+
labelId,
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const wire = (children: ReactNode | ((f: FieldRenderProps) => ReactNode)): ReactNode => {
|
|
149
|
+
if (typeof children === 'function') return children(field);
|
|
150
|
+
if (!isValidElement(children)) return children;
|
|
151
|
+
|
|
152
|
+
const child = children as ReactElement<Record<string, unknown>>;
|
|
153
|
+
const childProps = child.props;
|
|
154
|
+
let injected: Record<string, unknown>;
|
|
155
|
+
if (asGroup) {
|
|
156
|
+
injected = {
|
|
157
|
+
invalid: childProps.invalid ?? invalid,
|
|
158
|
+
required: childProps.required ?? requiredBool,
|
|
159
|
+
};
|
|
160
|
+
} else {
|
|
161
|
+
injected = {
|
|
162
|
+
id: controlId,
|
|
163
|
+
// `||`, not `??`, on both ARIA id references: `aria-labelledby={sectionId ?? ''}`
|
|
164
|
+
// is ordinary consumer code, and an empty id list references nothing — it
|
|
165
|
+
// contributes no name and lets the computation fall through, exactly like an
|
|
166
|
+
// empty `aria-label`. Treating it as an explicit override would suppress
|
|
167
|
+
// `labelId` and leave the control anonymous, which matters more here than
|
|
168
|
+
// anywhere else: Field names every input in the library through
|
|
169
|
+
// `aria-labelledby` rather than `<label for>`. `invalid` / `required` keep `??`
|
|
170
|
+
// — those are booleans, where `false` is a meaningful explicit value.
|
|
171
|
+
'aria-describedby': childProps['aria-describedby'] || describedBy,
|
|
172
|
+
invalid: childProps.invalid ?? invalid,
|
|
173
|
+
required: childProps.required ?? requiredBool,
|
|
174
|
+
};
|
|
175
|
+
// ROUND 7 — round 6 shipped `if (hasLabel && !childProps['aria-label'])`:
|
|
176
|
+
// skip injecting aria-labelledby whenever the child already carries its
|
|
177
|
+
// own aria-label, reasoning it as the same "child's explicit value wins"
|
|
178
|
+
// rule as the `||` two lines up. Both round-7 reviewers measured that
|
|
179
|
+
// this is the wrong fix, at the wrong altitude: `aria-describedby` is
|
|
180
|
+
// SUPPLEMENTARY (a consumer overriding it loses helper text — nothing
|
|
181
|
+
// breaks), but the accessible NAME is the control's identity, and WCAG
|
|
182
|
+
// 2.5.3 (Level A) requires a control's VISIBLE label text to be
|
|
183
|
+
// contained in that name. `<Field label="Work email"><Input
|
|
184
|
+
// aria-label="Email address" /></Field>` — a completely ordinary,
|
|
185
|
+
// defensive pattern an agent writes reflexively — computed name
|
|
186
|
+
// "Work email" before round 6 and "Email address" after: the visible
|
|
187
|
+
// text silently dropped out of the name on the library's single most
|
|
188
|
+
// common path. Reverted.
|
|
189
|
+
//
|
|
190
|
+
// The REAL fix is hasLabel itself: it now reads hasContent(label), not
|
|
191
|
+
// Boolean(label) — see that function's doc. An empty label
|
|
192
|
+
// (`label={<></>}`, `label={[]}`) no longer renders a `<label>` at all,
|
|
193
|
+
// hasLabel is correctly false, and `labelledBy` above is `undefined` —
|
|
194
|
+
// on BOTH this cloneElement path AND the render-prop `field` object,
|
|
195
|
+
// which reads the same hoisted `hasLabel` (round 6's fix could not
|
|
196
|
+
// reach the render-prop path at all, since that object is built before
|
|
197
|
+
// the child is known and has no childProps to inspect — this fix has
|
|
198
|
+
// no such asymmetry).
|
|
199
|
+
//
|
|
200
|
+
// No `if (hasLabel)` guard here, on purpose, verified by mutation: one
|
|
201
|
+
// was restored in an earlier round-7 draft and stayed green with the
|
|
202
|
+
// condition hardcoded `true`, and again with the `if` deleted outright
|
|
203
|
+
// — because `labelledBy` is already `hasLabel ? labelId : undefined`,
|
|
204
|
+
// so when `!hasLabel` this line reduces to `childProps['aria-labelledby']
|
|
205
|
+
// || undefined`, and `cloneElement` receiving an explicit `undefined`
|
|
206
|
+
// for a key the child never set is indistinguishable from omitting the
|
|
207
|
+
// key — the same argument that killed round 5's and round 6's guards
|
|
208
|
+
// here. Unlike those, this isn't a wrong claim shipped with a live
|
|
209
|
+
// gate; there's no gate left to be wrong about.
|
|
210
|
+
injected['aria-labelledby'] = childProps['aria-labelledby'] || labelledBy;
|
|
211
|
+
}
|
|
212
|
+
return cloneElement(child, injected);
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
controlId,
|
|
217
|
+
labelId,
|
|
218
|
+
descriptionId,
|
|
219
|
+
errorId,
|
|
220
|
+
describedBy,
|
|
221
|
+
labelledBy,
|
|
222
|
+
invalid,
|
|
223
|
+
wire,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Column-span vocabulary shared by `Grid.Item` and `Sortable.Item` (grid
|
|
3
|
+
* arrangement). Lives in `_internal` so both components reference one source of
|
|
4
|
+
* the fraction→track mapping without either importing the other (which would
|
|
5
|
+
* imply a render-composition edge in the component manifest that doesn't exist).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Column span for a grid cell. Numbers span that many tracks of whatever
|
|
10
|
+
* `columns` the parent grid declares. Fraction strings assume a 12-column
|
|
11
|
+
* grid (`columns={12}`): `'25%'`→3, `'33%'`→4, `'50%'`→6, `'67%'`→8,
|
|
12
|
+
* `'75%'`→9 tracks. `'100%'` / `'full'` span the entire row (`1 / -1`) and
|
|
13
|
+
* are safe in ANY grid, including auto-fit.
|
|
14
|
+
*/
|
|
15
|
+
export type GridItemSpan = number | 'full' | '25%' | '33%' | '50%' | '67%' | '75%' | '100%';
|
|
16
|
+
|
|
17
|
+
/** Fraction → 12-col track count. 100%/full handled separately (1 / -1). */
|
|
18
|
+
const FRACTION_TRACKS: Record<Exclude<GridItemSpan, number | 'full' | '100%'>, number> = {
|
|
19
|
+
'25%': 3,
|
|
20
|
+
'33%': 4,
|
|
21
|
+
'50%': 6,
|
|
22
|
+
'67%': 8,
|
|
23
|
+
'75%': 9,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Resolve a `GridItemSpan` to a CSS `grid-column` value (or `undefined` when
|
|
28
|
+
* no span is set; callers substitute `'auto'`).
|
|
29
|
+
* - `undefined` → `undefined`
|
|
30
|
+
* - `'full'` / `'100%'` → `'1 / -1'`
|
|
31
|
+
* - number → `'span N'`
|
|
32
|
+
* - fraction → `'span <tracks>'`
|
|
33
|
+
*/
|
|
34
|
+
export function resolveGridItemSpan(span: GridItemSpan | undefined): string | undefined {
|
|
35
|
+
if (span === undefined) return undefined;
|
|
36
|
+
if (span === 'full' || span === '100%') return '1 / -1';
|
|
37
|
+
if (typeof span === 'number') return `span ${span}`;
|
|
38
|
+
return `span ${FRACTION_TRACKS[span]}`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Resolve a span against a graduated-collapse step's column count: spans that
|
|
43
|
+
* fit keep their track count, spans >= the step's columns clamp to the full
|
|
44
|
+
* row (`1 / -1`), full-row spans stay full-row, span-less stays `auto`.
|
|
45
|
+
*/
|
|
46
|
+
export function resolveCollapsedGridItemSpan(
|
|
47
|
+
span: GridItemSpan | undefined,
|
|
48
|
+
columns: number,
|
|
49
|
+
): string {
|
|
50
|
+
if (span === undefined) return 'auto';
|
|
51
|
+
if (span === 'full' || span === '100%' || columns <= 1) return '1 / -1';
|
|
52
|
+
const tracks = typeof span === 'number' ? span : FRACTION_TRACKS[span];
|
|
53
|
+
return tracks >= columns ? '1 / -1' : `span ${tracks}`;
|
|
54
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calendar days as ISO `'YYYY-MM-DD'` strings, formatted in UTC so the host
|
|
3
|
+
* timezone can never shift a day (a booking's day belongs to the business's
|
|
4
|
+
* timezone, not the browser's). Used by DateStrip.
|
|
5
|
+
*/
|
|
6
|
+
const ISO_DAY = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
7
|
+
|
|
8
|
+
/** `'2026-10-07'` → `Date` at 2026-10-07T00:00:00Z. Throws on anything else. */
|
|
9
|
+
export function parseIsoDay(iso: string): Date {
|
|
10
|
+
const m = ISO_DAY.exec(iso);
|
|
11
|
+
if (!m) throw new Error(`[isoDay] expected 'YYYY-MM-DD', got '${iso}'`);
|
|
12
|
+
return new Date(Date.UTC(Number(m[1]), Number(m[2]) - 1, Number(m[3])));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Format one ISO day in UTC. */
|
|
16
|
+
export function formatIsoDay(
|
|
17
|
+
iso: string,
|
|
18
|
+
locale: string,
|
|
19
|
+
options: Intl.DateTimeFormatOptions,
|
|
20
|
+
): string {
|
|
21
|
+
return new Intl.DateTimeFormat(locale, { ...options, timeZone: 'UTC' }).format(parseIsoDay(iso));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Format a first..last ISO day range in UTC ("October 2026", "September – October 2026"). */
|
|
25
|
+
export function formatIsoRange(
|
|
26
|
+
first: string,
|
|
27
|
+
last: string,
|
|
28
|
+
locale: string,
|
|
29
|
+
options: Intl.DateTimeFormatOptions,
|
|
30
|
+
): string {
|
|
31
|
+
const f = new Intl.DateTimeFormat(locale, { ...options, timeZone: 'UTC' });
|
|
32
|
+
return first === last
|
|
33
|
+
? f.format(parseIsoDay(first))
|
|
34
|
+
: f.formatRange(parseIsoDay(first), parseIsoDay(last));
|
|
35
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layout-independent letter-shortcut match (#654).
|
|
3
|
+
*
|
|
4
|
+
* `event.key` is the character the layout produced, so on a Russian layout the
|
|
5
|
+
* K key yields `'л'` and a `key === 'k'` check silently drops the shortcut.
|
|
6
|
+
* `event.code` is the physical key (`'KeyK'`) on every layout — but on a remapped
|
|
7
|
+
* Latin layout (AZERTY, Dvorak) it names the wrong letter. So: trust `key` when
|
|
8
|
+
* it is a Latin letter, fall back to `code` only when it is a non-ASCII
|
|
9
|
+
* character (Cyrillic, Greek, …). ASCII punctuation on a letter position is a
|
|
10
|
+
* real key (Dvorak's `;` sits on KeyZ), so it never falls back.
|
|
11
|
+
*
|
|
12
|
+
* No fallback while Alt is held: Windows reports AltGr as Ctrl+Alt, so AltGr+Z
|
|
13
|
+
* on a Polish layout (`'ż'`, `KeyZ`, ctrlKey) is typing, not ⌘Z; the same goes
|
|
14
|
+
* for macOS Option+letter.
|
|
15
|
+
*
|
|
16
|
+
* `letter` is a single lowercase a–z.
|
|
17
|
+
*/
|
|
18
|
+
export function isLetterKey(
|
|
19
|
+
event: { key: string; code: string; altKey?: boolean },
|
|
20
|
+
letter: string,
|
|
21
|
+
): boolean {
|
|
22
|
+
const key = event.key.toLowerCase();
|
|
23
|
+
if (/^[a-z]$/.test(key)) return key === letter;
|
|
24
|
+
const nonAscii = key.length === 1 && key > '\x7f';
|
|
25
|
+
return nonAscii && !event.altKey && event.code === `Key${letter.toUpperCase()}`;
|
|
26
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Focus is "lost" when nothing live holds it: `<body>`, nothing, or a detached node. */
|
|
2
|
+
export function isFocusLost(): boolean {
|
|
3
|
+
const active = document.activeElement;
|
|
4
|
+
return !active || active === document.body || !active.isConnected;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Focus `el` on overlay close, retrying once in a microtask if the first
|
|
9
|
+
* `focus()` did not take. A lower overlay in `stackMode="replace"` is still
|
|
10
|
+
* `display: none` when the upper one closes — its `isTop` update renders just
|
|
11
|
+
* after that commit — so focusing an element inside it no-ops (#551). The
|
|
12
|
+
* retry only runs if focus is still lost by then, so it never steals focus
|
|
13
|
+
* from wherever something else put it.
|
|
14
|
+
*/
|
|
15
|
+
export function restoreFocusTo(el: HTMLElement): void {
|
|
16
|
+
el.focus({ preventScroll: true });
|
|
17
|
+
if (document.activeElement === el) return;
|
|
18
|
+
queueMicrotask(() => {
|
|
19
|
+
if (el.isConnected && isFocusLost()) el.focus({ preventScroll: true });
|
|
20
|
+
});
|
|
21
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { useFocusTrap } from './useFocusTrap';
|
|
2
|
+
export { useInOverlay } from './useInOverlay';
|
|
3
|
+
export { useScrollLock } from './useScrollLock';
|
|
4
|
+
export {
|
|
5
|
+
useFloatingSurface,
|
|
6
|
+
useOverlayStack,
|
|
7
|
+
overlayStack,
|
|
8
|
+
type OverlayStackMode,
|
|
9
|
+
type OverlayStackState,
|
|
10
|
+
} from './useOverlayStack';
|
|
11
|
+
export { isFocusLost, restoreFocusTo } from './focusRestore';
|
|
12
|
+
export { TOUR_CURRENT_TARGET, isTourHeld } from './tourHold';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Set by Tour on the current step's found target (any step kind, modal or
|
|
3
|
+
* not) while the tour is open. Distinct from `data-tour-active-target`, which
|
|
4
|
+
* only marks interactive modal-step targets for overlay elevation (#684).
|
|
5
|
+
*/
|
|
6
|
+
export const TOUR_CURRENT_TARGET = 'data-tour-current-target';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* True when a floating surface must ignore a dismiss caused by `node` (a
|
|
10
|
+
* pointerdown target or the element focus moved to): `node` is inside the
|
|
11
|
+
* tour layer AND the tour's current target is inside `panel` or `trigger`.
|
|
12
|
+
* A tour pointing into an open menu/picker must not close it just because
|
|
13
|
+
* the user pressed Next or the tour focused its card (#684).
|
|
14
|
+
*/
|
|
15
|
+
export function isTourHeld(
|
|
16
|
+
node: EventTarget | null,
|
|
17
|
+
panel: Element | null,
|
|
18
|
+
trigger: Element | null,
|
|
19
|
+
): boolean {
|
|
20
|
+
if (!(node instanceof Element) || !node.closest('[data-tour-portal-root]')) return false;
|
|
21
|
+
const target = document.querySelector(`[${TOUR_CURRENT_TARGET}]`);
|
|
22
|
+
return !!target && (!!panel?.contains(target) || !!trigger?.contains(target));
|
|
23
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { useEffect, type RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
export const FOCUSABLE_SELECTOR = [
|
|
4
|
+
'button:not([disabled])',
|
|
5
|
+
'[href]',
|
|
6
|
+
'input:not([disabled]):not([type="hidden"])',
|
|
7
|
+
'select:not([disabled])',
|
|
8
|
+
'textarea:not([disabled])',
|
|
9
|
+
'[tabindex]:not([tabindex="-1"])',
|
|
10
|
+
].join(',');
|
|
11
|
+
|
|
12
|
+
// Floating UI surfaces whose portals are direct body-siblings of our modal
|
|
13
|
+
// portal. Focus moving into these should not be redirected back to the modal —
|
|
14
|
+
// the popover / dropdown / tooltip is handling its own focus session.
|
|
15
|
+
// The DatePicker/DateRangePicker calendar popovers rely on the [role="dialog"]
|
|
16
|
+
// entry here: they move real DOM focus into body-portaled grid cells while
|
|
17
|
+
// open inside a Modal (unlike Select's aria-activedescendant pattern), so
|
|
18
|
+
// removing that entry would re-trap their keyboard users (#272).
|
|
19
|
+
const FLOATING_BYPASS_SELECTOR = [
|
|
20
|
+
'[data-popover-content]',
|
|
21
|
+
// RTE link-editor / attachment-config bubbles: form-like, hold their own
|
|
22
|
+
// focus while open inside a Modal (#274).
|
|
23
|
+
'[data-rte-overlay]',
|
|
24
|
+
'[data-dropdown-menu-content]',
|
|
25
|
+
'[role="tooltip"]',
|
|
26
|
+
'[role="menu"]',
|
|
27
|
+
'[role="listbox"]',
|
|
28
|
+
'[role="dialog"]',
|
|
29
|
+
].join(',');
|
|
30
|
+
|
|
31
|
+
function getFocusables(container: HTMLElement): HTMLElement[] {
|
|
32
|
+
return Array.from(container.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Focus trap: keeps Tab focus cycling inside `containerRef`. Attaches a
|
|
37
|
+
* `keydown` listener to detect Tab at the first/last focusable and wrap, plus
|
|
38
|
+
* a `focusin` listener at document level to redirect any focus that escapes
|
|
39
|
+
* the container back to it.
|
|
40
|
+
*
|
|
41
|
+
* `active = false` no-ops the trap (used by Modal when not top of stack — the
|
|
42
|
+
* inner modal mounts but only the topmost modal owns focus).
|
|
43
|
+
*
|
|
44
|
+
* `extra` (optional) — an element outside the container that joins the Tab cycle after it (Tour's interactive target).
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* const contentRef = useRef<HTMLDivElement | null>(null);
|
|
48
|
+
* useFocusTrap(contentRef, open);
|
|
49
|
+
*/
|
|
50
|
+
export function useFocusTrap(
|
|
51
|
+
containerRef: RefObject<HTMLElement | null>,
|
|
52
|
+
active: boolean,
|
|
53
|
+
extra: HTMLElement | null = null,
|
|
54
|
+
): void {
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (!active) return;
|
|
57
|
+
const container = containerRef.current;
|
|
58
|
+
if (!container) return;
|
|
59
|
+
|
|
60
|
+
// Tour's interactive target joins the cycle AFTER the container's
|
|
61
|
+
// focusables. Its DOM position is arbitrary, so with `extra` the cycle is
|
|
62
|
+
// driven manually instead of by native Tab order.
|
|
63
|
+
function extraFocusables(): HTMLElement[] {
|
|
64
|
+
if (!extra) return [];
|
|
65
|
+
return [extra, ...getFocusables(extra)].filter((el) => el.matches(FOCUSABLE_SELECTOR));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function onKeyDown(e: KeyboardEvent) {
|
|
69
|
+
if (e.key !== 'Tab') return;
|
|
70
|
+
const focusables = [...getFocusables(container!), ...extraFocusables()];
|
|
71
|
+
if (focusables.length === 0) {
|
|
72
|
+
// Zero focusables: prevent Tab from escaping the container.
|
|
73
|
+
e.preventDefault();
|
|
74
|
+
container!.focus();
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (extra) {
|
|
78
|
+
const n = focusables.length;
|
|
79
|
+
const i = focusables.indexOf(document.activeElement as HTMLElement);
|
|
80
|
+
const next = i === -1 ? (e.shiftKey ? n - 1 : 0) : (i + (e.shiftKey ? -1 : 1) + n) % n;
|
|
81
|
+
e.preventDefault();
|
|
82
|
+
focusables[next]!.focus();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const first = focusables[0]!;
|
|
86
|
+
const last = focusables[focusables.length - 1]!;
|
|
87
|
+
if (!e.shiftKey && document.activeElement === last) {
|
|
88
|
+
e.preventDefault();
|
|
89
|
+
first.focus();
|
|
90
|
+
} else if (e.shiftKey && document.activeElement === first) {
|
|
91
|
+
e.preventDefault();
|
|
92
|
+
last.focus();
|
|
93
|
+
}
|
|
94
|
+
// Middle of the cycle: browser handles it natively.
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function onFocusIn(e: FocusEvent) {
|
|
98
|
+
const target = e.target as HTMLElement | null;
|
|
99
|
+
if (!target || !container) return;
|
|
100
|
+
if (container.contains(target)) return;
|
|
101
|
+
if (extra?.contains(target)) return;
|
|
102
|
+
// Allow focus to live inside floating UI surfaces that were opened
|
|
103
|
+
// from within this modal (Popover, DropdownMenu, Tooltip, nested Modal).
|
|
104
|
+
// Their portals are body-direct siblings of our portal — checking by
|
|
105
|
+
// selector instead of containment.
|
|
106
|
+
if (target.closest(FLOATING_BYPASS_SELECTOR)) return;
|
|
107
|
+
// Focus escaped — redirect to the container.
|
|
108
|
+
container.focus();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
container.addEventListener('keydown', onKeyDown);
|
|
112
|
+
extra?.addEventListener('keydown', onKeyDown);
|
|
113
|
+
document.addEventListener('focusin', onFocusIn);
|
|
114
|
+
return () => {
|
|
115
|
+
container.removeEventListener('keydown', onKeyDown);
|
|
116
|
+
extra?.removeEventListener('keydown', onKeyDown);
|
|
117
|
+
document.removeEventListener('focusin', onFocusIn);
|
|
118
|
+
};
|
|
119
|
+
}, [containerRef, active, extra]);
|
|
120
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { useLayoutEffect, useState, type RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
// Overlay hosts whose descendants' floating surfaces must stack above them.
|
|
4
|
+
// Modal/Drawer portal roots, plus Popover.Content and DropdownMenu content
|
|
5
|
+
// (so a DropdownMenu/Popover/ConfirmationPopover opened from inside a Popover —
|
|
6
|
+
// or from a DropdownMenu item nested in one — elevates above its host instead
|
|
7
|
+
// of rendering behind it). Reuses the existing content markers; no new attrs.
|
|
8
|
+
// `[data-in-overlay]` makes elevation transitive: a surface nested inside an
|
|
9
|
+
// already-elevated surface (the embedded TimeField clock inside a DatePicker
|
|
10
|
+
// calendar that sits in a Modal, #272) elevates with its host — the host's
|
|
11
|
+
// marker lands on the DOM via the layout effect's setState (a second
|
|
12
|
+
// synchronous commit, still pre-paint) before the nested surface can open,
|
|
13
|
+
// so the chain is observable by the time the child's hook runs.
|
|
14
|
+
// Also the in-place maximized FlowCanvas ([data-flowcanvas-maximized]), so a
|
|
15
|
+
// consumer DropdownMenu/Select/Popover opened from its controls elevates above
|
|
16
|
+
// the fixed maximized surface instead of rendering behind it.
|
|
17
|
+
// Also Tour's portal ([data-tour-portal-root]): a Select/Popover/DropdownMenu/
|
|
18
|
+
// DatePicker opened from inside a Tour step's card body must elevate above
|
|
19
|
+
// the tour (--z-tour) instead of rendering behind it.
|
|
20
|
+
// Also [data-tour-active-target]: an interactive modal-tour step marks its
|
|
21
|
+
// `found` target element with this attribute directly (see Tour.tsx), not a
|
|
22
|
+
// wrapper around it — so unlike `data-in-overlay`, which must never sit on
|
|
23
|
+
// the reference element itself (a marked reference would self-match via
|
|
24
|
+
// closest() on the next recompute), this one is deliberately placed ON the
|
|
25
|
+
// reference. `closest()` including the start node is exactly what's wanted:
|
|
26
|
+
// the interactive target may BE a floating-surface trigger (e.g. a
|
|
27
|
+
// DropdownMenu trigger button carrying `data-tour`) or contain one, and
|
|
28
|
+
// either way its floating surface must elevate above the tour it was opened
|
|
29
|
+
// from.
|
|
30
|
+
const OVERLAY_PORTAL_SELECTOR =
|
|
31
|
+
'[data-drawer-portal-root], [data-modal-portal-root], [data-lightbox-portal-root], [data-flowcanvas-maximized], [data-popover-content], [data-dropdown-menu-content], [data-in-overlay], [data-tour-portal-root], [data-tour-active-target]';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* True when `referenceRef`'s element is rendered inside an overlay host — a
|
|
35
|
+
* `Modal`/`Drawer`/`Lightbox`/`Tour` portal, a `Popover.Content` / `DropdownMenu`
|
|
36
|
+
* content panel, an interactive `Tour` step's target (`[data-tour-active-target]`),
|
|
37
|
+
* or ANY already-elevated surface carrying `[data-in-overlay]`
|
|
38
|
+
* (transitive elevation). Floating surfaces (`Select` / `Popover` /
|
|
39
|
+
* `DropdownMenu` / `DatePicker` / `DateRangePicker` / `TimeField` / the
|
|
40
|
+
* `Rail.Group` collapsed-mode flyout) use this
|
|
41
|
+
* to elevate their portaled content above the host — their default z-index
|
|
42
|
+
* sits below `--z-modal` (and at/below an open Popover, and below `--z-tour`),
|
|
43
|
+
* so without elevation they render behind it. Covers a kebab `DropdownMenu`,
|
|
44
|
+
* nested `Popover`, or `ConfirmationPopover` opened from inside a Popover
|
|
45
|
+
* panel; a floating surface opened from inside a `Tour` step's card body
|
|
46
|
+
* (`[data-tour-portal-root]`) or from an interactive modal-tour step's target
|
|
47
|
+
* (`[data-tour-active-target]`); and, via the transitive marker, the embedded
|
|
48
|
+
* `TimeField` clock inside an elevated `DatePicker` calendar (#272).
|
|
49
|
+
*
|
|
50
|
+
* Consumers MUST place `data-in-overlay` on the portaled FLOATING element,
|
|
51
|
+
* never on the reference element itself — `closest()` includes the start
|
|
52
|
+
* node, so a marked reference would self-match on the next recompute.
|
|
53
|
+
*
|
|
54
|
+
* Recomputed whenever `active` toggles (the trigger is mounted by then). Uses
|
|
55
|
+
* `useLayoutEffect` so the elevation attribute lands in the same pre-paint
|
|
56
|
+
* commit as the opened surface (no flash behind the overlay).
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* // `ctx` is the component's own context (e.g. useSelectContext()) — but any
|
|
60
|
+
* // ref to the trigger or a wrapper ancestor works equally well (DatePicker/
|
|
61
|
+
* // DateRangePicker/TimeField pass their wrapperRef).
|
|
62
|
+
* const inOverlay = useInOverlay(ctx.triggerRef, ctx.open);
|
|
63
|
+
* // Empty-string presence idiom — React serializes `{true}` on a data-*
|
|
64
|
+
* // attribute as "true", so use `? '' : undefined` to match the CSS
|
|
65
|
+
* // `[data-in-overlay]` selector and the `data-*-content=""` convention:
|
|
66
|
+
* // <ul data-in-overlay={inOverlay ? '' : undefined} ...>
|
|
67
|
+
*/
|
|
68
|
+
export function useInOverlay(
|
|
69
|
+
referenceRef: RefObject<HTMLElement | null>,
|
|
70
|
+
active: boolean,
|
|
71
|
+
): boolean {
|
|
72
|
+
const [inOverlay, setInOverlay] = useState(false);
|
|
73
|
+
useLayoutEffect(() => {
|
|
74
|
+
if (!active) {
|
|
75
|
+
setInOverlay(false);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
setInOverlay(Boolean(referenceRef.current?.closest(OVERLAY_PORTAL_SELECTOR)));
|
|
79
|
+
}, [active, referenceRef]);
|
|
80
|
+
return inOverlay;
|
|
81
|
+
}
|