@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,242 @@
|
|
|
1
|
+
import { forwardRef, type CSSProperties, type HTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { Text } from '../Text';
|
|
4
|
+
import { hasContent, useFieldWiring, type FieldRenderProps } from '../_internal/fieldWiring';
|
|
5
|
+
import { type CollapseBreakpoint } from '../_internal/collapse';
|
|
6
|
+
import styles from './SettingRow.module.scss';
|
|
7
|
+
|
|
8
|
+
/** Width of the control only (not its trailing adornments), capped at the column. A subset of `<Constrain>`'s measure scale. */
|
|
9
|
+
export type SettingRowControlWidth = 'auto' | 'xs' | 'sm' | 'md';
|
|
10
|
+
|
|
11
|
+
export interface SettingRowProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
12
|
+
/** Label text. Renders a `<label htmlFor>` that names the control. Required — an empty or falsy value (e.g. `0`, `''`, `[]`, `<></>`) renders no `<label>` at all; see the anti-pattern below. */
|
|
13
|
+
label: ReactNode;
|
|
14
|
+
/**
|
|
15
|
+
* Badges / chips on the label line, rendered as a SIBLING of the `<label>`.
|
|
16
|
+
* Deliberately outside it: label content becomes the control's accessible
|
|
17
|
+
* name, so a provenance badge placed inside makes the input announce
|
|
18
|
+
* "Seats From plan".
|
|
19
|
+
*/
|
|
20
|
+
labelAdornment?: ReactNode;
|
|
21
|
+
/** Helper text under the label, in the label column. Linked via `aria-describedby`. */
|
|
22
|
+
description?: ReactNode;
|
|
23
|
+
/**
|
|
24
|
+
* Width of the control only — `trailing` is not sized by it. Default
|
|
25
|
+
* `'auto'` — the control's intrinsic width. Every row using the same step
|
|
26
|
+
* gets the same control width (capped at the column, so a narrow container
|
|
27
|
+
* still shrinks it), which is what keeps controls aligned down a
|
|
28
|
+
* `<SettingRow.List>`. Intended for controls that stretch to `width: 100%`
|
|
29
|
+
* (`Input`, `Select`); a fixed-size control (`Switch`) does not grow — the
|
|
30
|
+
* slot just reserves the width.
|
|
31
|
+
*
|
|
32
|
+
* `trailing` stays on the control's line only while both fit: in a narrow
|
|
33
|
+
* column a wide step (`'md'`) plus `trailing` can wrap `trailing` onto a
|
|
34
|
+
* second line. Use a smaller step if that matters.
|
|
35
|
+
*/
|
|
36
|
+
controlWidth?: SettingRowControlWidth;
|
|
37
|
+
/**
|
|
38
|
+
* Content after the control on the same line — a mode select, a state
|
|
39
|
+
* badge, a reset button. `controlWidth` does NOT apply here — it only sizes
|
|
40
|
+
* the main control. A control that sizes itself to `width: 100%` (`Select`,
|
|
41
|
+
* `Input`, `Textarea`) fills the ENTIRE trailing group and pushes any other
|
|
42
|
+
* adornment onto a second line; wrap it in `<Constrain width="xs">` (or
|
|
43
|
+
* another named step) to size it instead. Plain truthiness check: an empty
|
|
44
|
+
* array or fragment still renders an empty wrapper (a stray gap) — pass
|
|
45
|
+
* `undefined` for "none".
|
|
46
|
+
*/
|
|
47
|
+
trailing?: ReactNode;
|
|
48
|
+
/**
|
|
49
|
+
* Block under the control column — a usage meter, a caveat, a preview.
|
|
50
|
+
* Fills the control column's full width; cap a meter with `<Constrain>` —
|
|
51
|
+
* safe here, `footer` is not the wired child.
|
|
52
|
+
*/
|
|
53
|
+
footer?: ReactNode;
|
|
54
|
+
/**
|
|
55
|
+
* Error message. Takes over `aria-describedby` and flips the control to
|
|
56
|
+
* `invalid`. Unlike `<Field>`, the `description` stays VISIBLE alongside it —
|
|
57
|
+
* the two sit in different columns, so an invalid value is no reason to
|
|
58
|
+
* remove the explanation of what the setting is.
|
|
59
|
+
*
|
|
60
|
+
* **Not announced, deliberately** — `aria-describedby` is read on focus, so
|
|
61
|
+
* the form owns the submit-time summary. Same reasoning as `<Field error>`.
|
|
62
|
+
*/
|
|
63
|
+
error?: ReactNode;
|
|
64
|
+
/** Marks the row required: shows `*` and injects `required` onto the control. */
|
|
65
|
+
required?: boolean;
|
|
66
|
+
/** Explicit control id. The row owns the id by default so the label always matches. */
|
|
67
|
+
id?: string;
|
|
68
|
+
/** A single control element (auto-wired) or a render-prop `(field) => ReactNode`. */
|
|
69
|
+
children: ReactNode | ((field: FieldRenderProps) => ReactNode);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* One row of a settings screen: label and description in a shared left column, control and footer on the right.
|
|
74
|
+
* @see docs/components/SettingRow.md
|
|
75
|
+
*/
|
|
76
|
+
const SettingRowRoot = forwardRef<HTMLDivElement, SettingRowProps>(function SettingRow(
|
|
77
|
+
{
|
|
78
|
+
label,
|
|
79
|
+
labelAdornment,
|
|
80
|
+
description,
|
|
81
|
+
controlWidth = 'auto',
|
|
82
|
+
trailing,
|
|
83
|
+
footer,
|
|
84
|
+
error,
|
|
85
|
+
required,
|
|
86
|
+
id,
|
|
87
|
+
className,
|
|
88
|
+
children,
|
|
89
|
+
...rest
|
|
90
|
+
},
|
|
91
|
+
ref,
|
|
92
|
+
) {
|
|
93
|
+
// Single source of truth for each "is there an X" predicate — round 5
|
|
94
|
+
// hoisted only `hasLabel` (it had two consumers and had already diverged);
|
|
95
|
+
// round 6 did the same for `hasDescription`/`hasError`/`hasRequired`,
|
|
96
|
+
// still each computed twice (once for the wiring call, once for the
|
|
97
|
+
// matching render gate). Round 7: `hasLabel`/`hasDescription`/`hasError`
|
|
98
|
+
// now use `hasContent`, not `Boolean` — see that function's doc in
|
|
99
|
+
// fieldWiring.ts. `hasRequired` stays `Boolean` since `required` is a
|
|
100
|
+
// plain boolean, not ReactNode content that can be an empty-but-truthy
|
|
101
|
+
// container.
|
|
102
|
+
const hasLabel = hasContent(label);
|
|
103
|
+
const hasDescription = hasContent(description);
|
|
104
|
+
const hasError = hasContent(error);
|
|
105
|
+
const hasRequired = Boolean(required);
|
|
106
|
+
const { controlId, labelId, descriptionId, errorId, wire } = useFieldWiring({
|
|
107
|
+
id,
|
|
108
|
+
hasLabel,
|
|
109
|
+
hasDescription,
|
|
110
|
+
hasError,
|
|
111
|
+
required: hasRequired,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<div ref={ref} data-setting-row="" className={clsx(styles.row, className)} {...rest}>
|
|
116
|
+
<div className={styles.term}>
|
|
117
|
+
<div className={styles.labelLine}>
|
|
118
|
+
{hasLabel && (
|
|
119
|
+
<label htmlFor={controlId} id={labelId} className={styles.label}>
|
|
120
|
+
{label}
|
|
121
|
+
{hasRequired && (
|
|
122
|
+
<span aria-hidden="true" className={styles.required}>
|
|
123
|
+
{' '}
|
|
124
|
+
*
|
|
125
|
+
</span>
|
|
126
|
+
)}
|
|
127
|
+
</label>
|
|
128
|
+
)}
|
|
129
|
+
{Boolean(labelAdornment) && labelAdornment}
|
|
130
|
+
</div>
|
|
131
|
+
{hasDescription && (
|
|
132
|
+
<Text as="div" id={descriptionId} size="sm" tone="muted">
|
|
133
|
+
{description}
|
|
134
|
+
</Text>
|
|
135
|
+
)}
|
|
136
|
+
</div>
|
|
137
|
+
<div className={styles.control}>
|
|
138
|
+
<div className={styles.controlLine}>
|
|
139
|
+
<div className={styles.controlSlot} data-control-width={controlWidth}>
|
|
140
|
+
{wire(children)}
|
|
141
|
+
</div>
|
|
142
|
+
{Boolean(trailing) && <div className={styles.trailing}>{trailing}</div>}
|
|
143
|
+
</div>
|
|
144
|
+
{Boolean(footer) && footer}
|
|
145
|
+
{hasError && (
|
|
146
|
+
<Text as="div" id={errorId} size="sm" tone="danger">
|
|
147
|
+
{error}
|
|
148
|
+
</Text>
|
|
149
|
+
)}
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
);
|
|
153
|
+
});
|
|
154
|
+
SettingRowRoot.displayName = 'SettingRow';
|
|
155
|
+
|
|
156
|
+
/** Vertical padding per row: `sm` = `--space-2`, `md` = `--space-3`, `lg` = `--space-4`. */
|
|
157
|
+
export type SettingRowListSpacing = 'sm' | 'md' | 'lg';
|
|
158
|
+
|
|
159
|
+
export interface SettingRowListProps extends HTMLAttributes<HTMLDivElement> {
|
|
160
|
+
/**
|
|
161
|
+
* CSS length for the label column, shared by every row in the list
|
|
162
|
+
* (e.g. `'18rem'`, `'240px'`). Default `'16rem'` via the
|
|
163
|
+
* `--setting-row-label-width` token.
|
|
164
|
+
*
|
|
165
|
+
* A LENGTH, not `max-content` — rows align because they each resolve the
|
|
166
|
+
* same value, with no subgrid.
|
|
167
|
+
*/
|
|
168
|
+
labelWidth?: string;
|
|
169
|
+
/** 1px border between rows. Default `false`, matching `<DefinitionList>`. */
|
|
170
|
+
dividers?: boolean;
|
|
171
|
+
/** Vertical padding per row. Default `'md'`. */
|
|
172
|
+
spacing?: SettingRowListSpacing;
|
|
173
|
+
/**
|
|
174
|
+
* Container width at or below which each row stacks its label column above
|
|
175
|
+
* its control column. `'sm'` 480px / `'md'` 640px / `'lg'` 768px, measured
|
|
176
|
+
* against the LIST's own box (a container query, like `<Grid>` and
|
|
177
|
+
* `<Split>`). Default `'sm'`.
|
|
178
|
+
*
|
|
179
|
+
* Pass `false` to opt out of containment entirely — e.g. inside a
|
|
180
|
+
* shrink-to-fit parent (a `width: max-content` flex item, an inline-block,
|
|
181
|
+
* a table cell), where `container-type: inline-size` would otherwise zero
|
|
182
|
+
* the List's intrinsic-width contribution. See the anti-pattern below.
|
|
183
|
+
*/
|
|
184
|
+
collapseBelow?: CollapseBreakpoint | false;
|
|
185
|
+
/** The rows. */
|
|
186
|
+
children: ReactNode;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Same shape as Grid's `collapseClass` (Grid.tsx:143) — no non-null
|
|
190
|
+
// assertions: types/scss-modules.d.ts types a CSS-module member as `string`.
|
|
191
|
+
const COLLAPSE_CLASS: Record<CollapseBreakpoint, string> = {
|
|
192
|
+
sm: styles.collapseSm,
|
|
193
|
+
md: styles.collapseMd,
|
|
194
|
+
lg: styles.collapseLg,
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* A list of `<SettingRow>`s that owns the shared label column, vertical rhythm, dividers and narrow-container collapse.
|
|
199
|
+
* @see docs/components/SettingRow.md
|
|
200
|
+
*/
|
|
201
|
+
const SettingRowList = forwardRef<HTMLDivElement, SettingRowListProps>(function SettingRowList(
|
|
202
|
+
{
|
|
203
|
+
labelWidth,
|
|
204
|
+
dividers = false,
|
|
205
|
+
spacing = 'md',
|
|
206
|
+
collapseBelow = 'sm',
|
|
207
|
+
className,
|
|
208
|
+
style,
|
|
209
|
+
children,
|
|
210
|
+
...rest
|
|
211
|
+
},
|
|
212
|
+
ref,
|
|
213
|
+
) {
|
|
214
|
+
return (
|
|
215
|
+
<div
|
|
216
|
+
ref={ref}
|
|
217
|
+
data-setting-row-list=""
|
|
218
|
+
data-spacing={spacing}
|
|
219
|
+
data-dividers={dividers ? 'true' : undefined}
|
|
220
|
+
className={clsx(
|
|
221
|
+
styles.list,
|
|
222
|
+
collapseBelow !== false && styles.collapsible,
|
|
223
|
+
collapseBelow !== false && COLLAPSE_CLASS[collapseBelow],
|
|
224
|
+
className,
|
|
225
|
+
)}
|
|
226
|
+
// Custom-property-in-style idiom copied from Grid.tsx:204.
|
|
227
|
+
style={
|
|
228
|
+
labelWidth != null
|
|
229
|
+
? { ...(style as CSSProperties), ['--setting-row-label-width' as string]: labelWidth }
|
|
230
|
+
: style
|
|
231
|
+
}
|
|
232
|
+
{...rest}
|
|
233
|
+
>
|
|
234
|
+
{children}
|
|
235
|
+
</div>
|
|
236
|
+
);
|
|
237
|
+
});
|
|
238
|
+
SettingRowList.displayName = 'SettingRowList';
|
|
239
|
+
|
|
240
|
+
export const SettingRow = Object.assign(SettingRowRoot, {
|
|
241
|
+
List: SettingRowList,
|
|
242
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
@use './Skeleton.tokens';
|
|
2
|
+
|
|
3
|
+
.skeleton {
|
|
4
|
+
display: inline-block;
|
|
5
|
+
background: var(--skeleton-bg);
|
|
6
|
+
|
|
7
|
+
// Prevent text selection — skeletons are decorative.
|
|
8
|
+
user-select: none;
|
|
9
|
+
|
|
10
|
+
// Ensures the inline-block lays out cleanly inside text flow.
|
|
11
|
+
vertical-align: middle;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.variant-text {
|
|
15
|
+
border-radius: var(--skeleton-radius-text);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.variant-circular {
|
|
19
|
+
border-radius: var(--skeleton-radius-circular);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.variant-rectangular {
|
|
23
|
+
display: block;
|
|
24
|
+
border-radius: var(--skeleton-radius-rectangular);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Pulse — opacity cycle. Hardware-accelerated (opacity is a compositor
|
|
28
|
+
// property). 1.5s read as "alive" without being distracting.
|
|
29
|
+
.pulse {
|
|
30
|
+
animation: skeleton-pulse 1.5s ease-in-out infinite;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@keyframes skeleton-pulse {
|
|
34
|
+
0% {
|
|
35
|
+
opacity: var(--skeleton-opacity-high);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
50% {
|
|
39
|
+
opacity: var(--skeleton-opacity-low);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
100% {
|
|
43
|
+
opacity: var(--skeleton-opacity-high);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Respect reduced-motion. Wins over the .pulse rule above purely via
|
|
48
|
+
// source order — both selectors are class-specificity (0,1,0), so the
|
|
49
|
+
// later declaration takes precedence in the cascade. No !important
|
|
50
|
+
// needed.
|
|
51
|
+
@media (prefers-reduced-motion: reduce) {
|
|
52
|
+
.pulse {
|
|
53
|
+
animation: none;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Skeleton.tokens.scss — Component-scoped tokens for <Skeleton>. Background
|
|
2
|
+
// (the muted block), the per-variant radii (text/circular/rectangular), and
|
|
3
|
+
// the pulse animation's opacity extremes. The 1.5s pulse duration stays raw
|
|
4
|
+
// since motion timings are not tokenized.
|
|
5
|
+
:root {
|
|
6
|
+
// Block
|
|
7
|
+
--skeleton-bg: var(--color-bg-muted);
|
|
8
|
+
|
|
9
|
+
// Variant radii
|
|
10
|
+
--skeleton-radius-text: var(--radius-sm);
|
|
11
|
+
--skeleton-radius-circular: var(--radius-full);
|
|
12
|
+
--skeleton-radius-rectangular: var(--radius-md);
|
|
13
|
+
|
|
14
|
+
// Pulse opacity range
|
|
15
|
+
--skeleton-opacity-high: var(--opacity-visible);
|
|
16
|
+
--skeleton-opacity-low: var(--opacity-subtle);
|
|
17
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { forwardRef, type CSSProperties, type HTMLAttributes } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { useSkeletonVisibility } from './useSkeletonVisibility';
|
|
4
|
+
import styles from './Skeleton.module.scss';
|
|
5
|
+
|
|
6
|
+
/** Shape preset. */
|
|
7
|
+
export type SkeletonVariant = 'text' | 'circular' | 'rectangular';
|
|
8
|
+
|
|
9
|
+
/** Animation style. */
|
|
10
|
+
export type SkeletonAnimation = 'pulse' | 'none';
|
|
11
|
+
|
|
12
|
+
export interface SkeletonProps extends HTMLAttributes<HTMLSpanElement> {
|
|
13
|
+
/**
|
|
14
|
+
* Shape preset. Defaults to `'text'`.
|
|
15
|
+
* - `'text'` — inline-block; `height` defaults to `1em` so it sits on text
|
|
16
|
+
* baselines. Use inside paragraphs / labels for word-shaped placeholders.
|
|
17
|
+
* - `'circular'` — `border-radius: 50%`; when only one of `width`/`height`
|
|
18
|
+
* is set, the other matches (square). Avatar / icon placeholder.
|
|
19
|
+
* - `'rectangular'` — block, small radius. Image / card / button placeholder.
|
|
20
|
+
*/
|
|
21
|
+
variant?: SkeletonVariant;
|
|
22
|
+
|
|
23
|
+
/** Explicit width. Number → px, string → as-is (e.g., `'60%'`, `'12rem'`). */
|
|
24
|
+
width?: number | string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Explicit height. Number → px, string → as-is.
|
|
28
|
+
* Defaults: `text` → `1em`, `circular` → matches `width` (square),
|
|
29
|
+
* `rectangular` → no default (consumer must size).
|
|
30
|
+
*/
|
|
31
|
+
height?: number | string;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Animation. Defaults to `'pulse'`.
|
|
35
|
+
* - `'pulse'` — opacity 1 → 0.6 → 1, 1.5s ease-in-out infinite.
|
|
36
|
+
* - `'none'` — static. Use when stacking many skeletons to avoid motion
|
|
37
|
+
* overload.
|
|
38
|
+
*
|
|
39
|
+
* Regardless of this prop, animation is suppressed when the user has
|
|
40
|
+
* `prefers-reduced-motion: reduce`.
|
|
41
|
+
*/
|
|
42
|
+
animation?: SkeletonAnimation;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Whether the loading placeholder is needed. Defaults to `true`.
|
|
46
|
+
* Keep Skeleton mounted and drive this prop when using `minDuration`, so
|
|
47
|
+
* the component can finish its visibility window after loading completes.
|
|
48
|
+
*/
|
|
49
|
+
loading?: boolean;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Milliseconds to wait before rendering the placeholder. Defaults to `0`.
|
|
53
|
+
* A load that finishes inside this window never displays the Skeleton.
|
|
54
|
+
*/
|
|
55
|
+
delay?: number;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Minimum milliseconds to remain visible after the placeholder renders.
|
|
59
|
+
* Defaults to `0`. Prevents a Skeleton that appears just after `delay`
|
|
60
|
+
* from disappearing again within a frame or two.
|
|
61
|
+
*/
|
|
62
|
+
minDuration?: number;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function toCssSize(value: number | string | undefined): string | undefined {
|
|
66
|
+
if (value === undefined) return undefined;
|
|
67
|
+
return typeof value === 'number' ? `${value}px` : value;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Placeholder rectangle for loading states, composed in any layout to mimic the eventual content shape.
|
|
72
|
+
* @see docs/components/Skeleton.md
|
|
73
|
+
*/
|
|
74
|
+
export const Skeleton = forwardRef<HTMLSpanElement, SkeletonProps>(function Skeleton(
|
|
75
|
+
{
|
|
76
|
+
variant = 'text',
|
|
77
|
+
width,
|
|
78
|
+
height,
|
|
79
|
+
animation = 'pulse',
|
|
80
|
+
loading = true,
|
|
81
|
+
delay = 0,
|
|
82
|
+
minDuration = 0,
|
|
83
|
+
className,
|
|
84
|
+
style,
|
|
85
|
+
...props
|
|
86
|
+
},
|
|
87
|
+
ref,
|
|
88
|
+
) {
|
|
89
|
+
const visible = useSkeletonVisibility(loading, { delay, minDuration });
|
|
90
|
+
|
|
91
|
+
// Default height: text → 1em (sits on baseline), circular → matches width
|
|
92
|
+
// (square), rectangular → undefined (consumer must size).
|
|
93
|
+
let resolvedHeight: string | undefined = toCssSize(height);
|
|
94
|
+
if (resolvedHeight === undefined) {
|
|
95
|
+
if (variant === 'text') resolvedHeight = '1em';
|
|
96
|
+
else if (variant === 'circular' && width !== undefined) resolvedHeight = toCssSize(width);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Default width: circular with only height set → matches height (square).
|
|
100
|
+
let resolvedWidth: string | undefined = toCssSize(width);
|
|
101
|
+
if (resolvedWidth === undefined && variant === 'circular' && height !== undefined) {
|
|
102
|
+
resolvedWidth = toCssSize(height);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const mergedStyle: CSSProperties = {
|
|
106
|
+
width: resolvedWidth,
|
|
107
|
+
height: resolvedHeight,
|
|
108
|
+
...style,
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// Spread order: ref + aria-hidden BEFORE {...props} so a consumer can
|
|
112
|
+
// override aria-hidden (e.g., for a Skeleton that IS the loading
|
|
113
|
+
// announcement on a page with no parent live region). className and
|
|
114
|
+
// style live AFTER {...props} so the component's class composition +
|
|
115
|
+
// dimension style win over any consumer-supplied raw className / style
|
|
116
|
+
// (consumer composes via the prop, not by replacing).
|
|
117
|
+
return visible ? (
|
|
118
|
+
<span
|
|
119
|
+
ref={ref}
|
|
120
|
+
aria-hidden="true"
|
|
121
|
+
{...props}
|
|
122
|
+
className={clsx(
|
|
123
|
+
styles.skeleton,
|
|
124
|
+
styles[`variant-${variant}`],
|
|
125
|
+
animation === 'pulse' && styles.pulse,
|
|
126
|
+
className,
|
|
127
|
+
)}
|
|
128
|
+
style={mergedStyle}
|
|
129
|
+
/>
|
|
130
|
+
) : null;
|
|
131
|
+
});
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { useLayoutEffect, useRef, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
/** Timing controls for {@link useSkeletonVisibility}. */
|
|
4
|
+
export interface SkeletonVisibilityOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Milliseconds to wait before showing the placeholder. Defaults to `0`.
|
|
7
|
+
* A loading cycle that finishes inside this window never becomes visible.
|
|
8
|
+
*/
|
|
9
|
+
delay?: number;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Minimum milliseconds to remain visible after the placeholder appears.
|
|
13
|
+
* Defaults to `0`.
|
|
14
|
+
*/
|
|
15
|
+
minDuration?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function normalizeDuration(value: number | undefined): number {
|
|
19
|
+
const duration = value ?? 0;
|
|
20
|
+
return Number.isFinite(duration) ? Math.max(0, duration) : 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Coordinates delayed placeholder visibility and a minimum visible duration.
|
|
25
|
+
* Use the returned boolean to keep placeholder and content branches mutually
|
|
26
|
+
* exclusive while preserving the timing window after `loading` becomes false.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* // Immediate placeholder, then content.
|
|
30
|
+
* const showPlaceholder = useSkeletonVisibility(loading);
|
|
31
|
+
* return showPlaceholder ? <Skeleton width="60%" /> : <ContactList />;
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* // Suppress quick-load flashes and avoid flashing content during the delay.
|
|
35
|
+
* const showPlaceholder = useSkeletonVisibility(loading, {
|
|
36
|
+
* delay: 200,
|
|
37
|
+
* minDuration: 300,
|
|
38
|
+
* });
|
|
39
|
+
* return showPlaceholder ? <Skeleton width="60%" /> : loading ? null : <ContactList />;
|
|
40
|
+
*
|
|
41
|
+
* @remarks Keep the hook's consumer mounted for the whole loading cycle. If it
|
|
42
|
+
* unmounts as soon as `loading` changes, the minimum-duration tail cannot finish.
|
|
43
|
+
*/
|
|
44
|
+
export function useSkeletonVisibility(
|
|
45
|
+
loading: boolean,
|
|
46
|
+
options: SkeletonVisibilityOptions = {},
|
|
47
|
+
): boolean {
|
|
48
|
+
const normalizedDelay = normalizeDuration(options.delay);
|
|
49
|
+
const normalizedMinDuration = normalizeDuration(options.minDuration);
|
|
50
|
+
const [visible, setVisible] = useState(() => loading && normalizedDelay === 0);
|
|
51
|
+
const now = Date.now();
|
|
52
|
+
const shownAt = useRef<number | null>(visible ? now : null);
|
|
53
|
+
const loadingStartedAt = useRef<number | null>(loading ? now : null);
|
|
54
|
+
const wasLoading = useRef(loading);
|
|
55
|
+
|
|
56
|
+
useLayoutEffect(() => {
|
|
57
|
+
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
58
|
+
|
|
59
|
+
if (loading) {
|
|
60
|
+
if (!wasLoading.current || loadingStartedAt.current === null) {
|
|
61
|
+
loadingStartedAt.current = Date.now();
|
|
62
|
+
}
|
|
63
|
+
if (!visible) {
|
|
64
|
+
const show = () => {
|
|
65
|
+
shownAt.current = Date.now();
|
|
66
|
+
setVisible(true);
|
|
67
|
+
};
|
|
68
|
+
const elapsed = Date.now() - loadingStartedAt.current;
|
|
69
|
+
const remaining = Math.max(0, normalizedDelay - elapsed);
|
|
70
|
+
if (remaining === 0) show();
|
|
71
|
+
else timer = setTimeout(show, remaining);
|
|
72
|
+
}
|
|
73
|
+
} else if (visible) {
|
|
74
|
+
const elapsed =
|
|
75
|
+
shownAt.current === null ? normalizedMinDuration : Date.now() - shownAt.current;
|
|
76
|
+
const remaining = Math.max(0, normalizedMinDuration - elapsed);
|
|
77
|
+
const hide = () => {
|
|
78
|
+
shownAt.current = null;
|
|
79
|
+
setVisible(false);
|
|
80
|
+
};
|
|
81
|
+
if (remaining === 0) hide();
|
|
82
|
+
else timer = setTimeout(hide, remaining);
|
|
83
|
+
} else {
|
|
84
|
+
loadingStartedAt.current = null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
wasLoading.current = loading;
|
|
88
|
+
|
|
89
|
+
return () => {
|
|
90
|
+
if (timer !== undefined) clearTimeout(timer);
|
|
91
|
+
};
|
|
92
|
+
}, [loading, normalizedDelay, normalizedMinDuration, visible]);
|
|
93
|
+
|
|
94
|
+
return visible;
|
|
95
|
+
}
|