@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,27 @@
|
|
|
1
|
+
// AppLayout.tokens.scss — Component-scoped tokens for <AppLayout>.
|
|
2
|
+
@use '../_internal/collapse' as bp;
|
|
3
|
+
|
|
4
|
+
:root {
|
|
5
|
+
// Padding of the main content region — the canonical shell content gutter, so
|
|
6
|
+
// a DS-only consumer gets the shell padding with no prop and no raw CSS.
|
|
7
|
+
// Defaults to --space-6 (matches the playground AppShell's .content gutter).
|
|
8
|
+
// Override to `0` (or another token) in your scope for a full-bleed main
|
|
9
|
+
// region — no prop needed.
|
|
10
|
+
--app-layout-content-padding: var(--space-6);
|
|
11
|
+
|
|
12
|
+
// Background of the main content region — a subtle canvas so page Cards lift
|
|
13
|
+
// off it (matches every playground mockup). Defaults to --color-bg-subtle.
|
|
14
|
+
// Override to `transparent` in your scope for a flat content area — no prop.
|
|
15
|
+
--app-layout-content-background: var(--color-bg-subtle);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Narrow viewports: --space-6 (24px) each side costs a 380px phone 48px of its
|
|
19
|
+
// width. Step the gutter down so content keeps its room. This only moves the
|
|
20
|
+
// DEFAULT: a consumer override in a scope BELOW :root still wins (e.g. a class
|
|
21
|
+
// on their own root element), but an override written as another :root rule is
|
|
22
|
+
// the same (0,1,0) specificity as this one — whichever rule loads last wins.
|
|
23
|
+
@media (max-width: bp.$collapse-md) {
|
|
24
|
+
:root {
|
|
25
|
+
--app-layout-content-padding: var(--space-4);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { forwardRef, useEffect, useRef, type HTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { useTranslation } from '../../i18n';
|
|
4
|
+
import { useBelowBreakpoint } from '../../hooks/useBelowBreakpoint';
|
|
5
|
+
import type { CollapseBreakpoint } from '../_internal/collapse';
|
|
6
|
+
import { useControllableState } from '../_internal/useControllableState';
|
|
7
|
+
import { Drawer } from '../Drawer';
|
|
8
|
+
import styles from './AppLayout.module.scss';
|
|
9
|
+
|
|
10
|
+
export interface AppLayoutProps extends HTMLAttributes<HTMLDivElement> {
|
|
11
|
+
/**
|
|
12
|
+
* System-wide banner slot — full WINDOW width, above the sidebar + content
|
|
13
|
+
* row. For messages that apply wherever the user is: maintenance, billing
|
|
14
|
+
* overdue, impersonation. Pass a `<Banner>` (or several, most severe first).
|
|
15
|
+
* Not sticky: it scrolls away with the page while the `topBar` stays pinned.
|
|
16
|
+
* Omit (or pass `null` / `false`) for no wrapper.
|
|
17
|
+
*
|
|
18
|
+
* With `sidebarPinned`, the pinned sidebar starts below this banner, so at
|
|
19
|
+
* scroll position 0 its bottom (a `Rail.Footer`) sits up to one banner height
|
|
20
|
+
* below the fold until the page scrolls past the banner. This is accepted —
|
|
21
|
+
* banners are temporary.
|
|
22
|
+
*/
|
|
23
|
+
banner?: ReactNode;
|
|
24
|
+
/**
|
|
25
|
+
* Context banner slot — inside the content column, between the `topBar` and
|
|
26
|
+
* the padded content region, full-bleed within the column. For messages
|
|
27
|
+
* scoped to a module or route ("Email sending suspended" on the Email
|
|
28
|
+
* pages); the app decides which routes render it. Pass a `<Banner>`. Not
|
|
29
|
+
* sticky. Page-level messages belong in the content as `<Alert>` instead.
|
|
30
|
+
*/
|
|
31
|
+
contextBanner?: ReactNode;
|
|
32
|
+
/**
|
|
33
|
+
* Top bar slot — sits above the main content, spanning the content column to
|
|
34
|
+
* the right of the sidebar (not the full window width). Omit for no top bar.
|
|
35
|
+
*/
|
|
36
|
+
topBar?: ReactNode;
|
|
37
|
+
/**
|
|
38
|
+
* Sidebar slot — runs the full height down the left, alongside both the top
|
|
39
|
+
* bar and the content. Sets its own width (intrinsic). Omit for no sidebar.
|
|
40
|
+
*/
|
|
41
|
+
sidebar?: ReactNode;
|
|
42
|
+
/**
|
|
43
|
+
* Pin the sidebar to the viewport: `position: sticky; top: 0; height: 100dvh`
|
|
44
|
+
* with internal overflow scrolling. On pages taller than the viewport the
|
|
45
|
+
* sidebar (and a `Rail` inside it — including its `Rail.Footer` /
|
|
46
|
+
* CollapseToggle) spans exactly the SCREEN, keeping the footer glued to the
|
|
47
|
+
* viewport bottom instead of the page bottom. Default `false` (sidebar
|
|
48
|
+
* stretches to the full row/page height — the original behavior).
|
|
49
|
+
*
|
|
50
|
+
* Prefer this over wrapping the sidebar slot in `Sticky` — the rail pins its
|
|
51
|
+
* footer by filling its own `height: 100%` box, which needs a DEFINITE
|
|
52
|
+
* height to resolve against. `Sticky` sets `align-self: start`, which drops
|
|
53
|
+
* the row stretch that made it definite, so the footer stops pinning.
|
|
54
|
+
*
|
|
55
|
+
* `100dvh` is always relative to the real browser viewport, never to a
|
|
56
|
+
* nested scroll container — so this only pins correctly when AppLayout is
|
|
57
|
+
* the actual outermost, page-scroll shell (its documented top-level use).
|
|
58
|
+
* Nest it inside another scrollable region and the sidebar will size to
|
|
59
|
+
* the whole window, not that region, and overflow it.
|
|
60
|
+
*/
|
|
61
|
+
sidebarPinned?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Move the sidebar out of the flow and into a left-anchored `<Drawer>` while
|
|
64
|
+
* the **viewport** is at or below a width threshold: `'sm'` 480px / `'md'`
|
|
65
|
+
* 640px / `'lg'` 768px. Omit for no responsive behavior (the default) — the
|
|
66
|
+
* sidebar always renders in the flow.
|
|
67
|
+
*
|
|
68
|
+
* Below the threshold the content column claims the full viewport width, and
|
|
69
|
+
* the sidebar is reachable only by opening the drawer. Render your own
|
|
70
|
+
* trigger (a hamburger in the `topBar`) and drive it with `sidebarOpen` +
|
|
71
|
+
* `onSidebarOpenChange` — AppLayout deliberately renders no trigger of its
|
|
72
|
+
* own, since where it belongs in the bar is the consumer's call, which means
|
|
73
|
+
* both props are effectively required together (see `sidebarOpen`'s doc).
|
|
74
|
+
* Use the exported `useBelowBreakpoint` hook to show that trigger only while
|
|
75
|
+
* the overlay mode is active.
|
|
76
|
+
*
|
|
77
|
+
* `sidebarPinned` is ignored below the threshold: the drawer owns the
|
|
78
|
+
* sidebar's box there, and a `sticky; height: 100dvh` wrapper inside it would
|
|
79
|
+
* size the rail to the window instead of the drawer.
|
|
80
|
+
*
|
|
81
|
+
* Measures the viewport (`matchMedia`), not a container — the sidebar's
|
|
82
|
+
* presence in the row is exactly what the threshold changes, so a container
|
|
83
|
+
* query would be circular. Same scale and same basis as `<Rail collapseBelow>`.
|
|
84
|
+
*
|
|
85
|
+
* The `sidebar` node moves between the in-flow slot and the `Drawer`,
|
|
86
|
+
* remounting it, so a `Rail`'s internal state (expanded `Rail.Group`s, scroll
|
|
87
|
+
* position) resets each time, by design. A `<Rail>` in the drawer scrolls its
|
|
88
|
+
* own body while its footer stays visible; a custom non-`Rail` sidebar needs
|
|
89
|
+
* its own height-filling scroll container, especially on short viewports
|
|
90
|
+
* (phone landscape, ~380px).
|
|
91
|
+
*/
|
|
92
|
+
sidebarOverlayBelow?: CollapseBreakpoint;
|
|
93
|
+
/**
|
|
94
|
+
* Open state of the overlay sidebar. Technically optional, but effectively
|
|
95
|
+
* required together with `onSidebarOpenChange` whenever `sidebarOverlayBelow`
|
|
96
|
+
* is set — AppLayout renders no trigger of its own (see `sidebarOverlayBelow`),
|
|
97
|
+
* so with both omitted nothing can ever open the drawer; Esc/backdrop close it,
|
|
98
|
+
* but there's no way in. Has no effect unless `sidebarOverlayBelow` is set and
|
|
99
|
+
* the viewport is below it.
|
|
100
|
+
*/
|
|
101
|
+
sidebarOpen?: boolean;
|
|
102
|
+
/** Fires whenever the overlay sidebar opens or closes — close button, Esc, backdrop click, swipe, or programmatic. Pair with `sidebarOpen` — see its doc. */
|
|
103
|
+
onSidebarOpenChange?: (open: boolean) => void;
|
|
104
|
+
/**
|
|
105
|
+
* Render the content region as a `<main>` landmark instead of a plain `<div>`.
|
|
106
|
+
* Pass it on the outermost app shell so the page gets its single `main`
|
|
107
|
+
* landmark without a wrapper element. Leave it off (default) for nested
|
|
108
|
+
* use — demos, documentation previews — so the page never gets two `main`s.
|
|
109
|
+
*/
|
|
110
|
+
mainLandmark?: boolean;
|
|
111
|
+
/** Main content slot — fills the remaining space below the top bar. */
|
|
112
|
+
children: ReactNode;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Viewport-filling application shell layout: full-height `sidebar`, optional `topBar` over the content column, main `children` below.
|
|
117
|
+
* @see docs/components/AppLayout.md
|
|
118
|
+
*/
|
|
119
|
+
export const AppLayout = forwardRef<HTMLDivElement, AppLayoutProps>(function AppLayout(
|
|
120
|
+
{
|
|
121
|
+
banner,
|
|
122
|
+
contextBanner,
|
|
123
|
+
topBar,
|
|
124
|
+
sidebar,
|
|
125
|
+
sidebarPinned,
|
|
126
|
+
sidebarOverlayBelow,
|
|
127
|
+
mainLandmark,
|
|
128
|
+
sidebarOpen,
|
|
129
|
+
onSidebarOpenChange,
|
|
130
|
+
children,
|
|
131
|
+
className,
|
|
132
|
+
...props
|
|
133
|
+
},
|
|
134
|
+
ref,
|
|
135
|
+
) {
|
|
136
|
+
const t = useTranslation();
|
|
137
|
+
const Main = mainLandmark ? 'main' : 'div';
|
|
138
|
+
const overlay = useBelowBreakpoint(sidebarOverlayBelow) && sidebar != null;
|
|
139
|
+
// Whether the Drawer should exist AT ALL, independent of the live viewport
|
|
140
|
+
// threshold. Kept mounted across the crossing (see below) rather than
|
|
141
|
+
// gated on `overlay` — that's what lets a still-mounted DrawerRoot receive
|
|
142
|
+
// a real open:true→false PROP transition on the up-crossing instead of
|
|
143
|
+
// being yanked from the tree mid-open.
|
|
144
|
+
const overlayConfigured = sidebarOverlayBelow != null && sidebar != null;
|
|
145
|
+
|
|
146
|
+
// Uncontrolled fallback so Esc / backdrop still close the drawer when the
|
|
147
|
+
// consumer passes `sidebarOverlayBelow` without wiring open state.
|
|
148
|
+
const [open, setOpen] = useControllableState<boolean>({
|
|
149
|
+
value: sidebarOpen,
|
|
150
|
+
defaultValue: false,
|
|
151
|
+
onChange: onSidebarOpenChange,
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// Crossing back above the threshold must CLOSE the drawer via a real prop
|
|
155
|
+
// transition, not unmount it out from under an open dialog — DrawerRoot's
|
|
156
|
+
// own focus-restore effect only fires on open:true→false while mounted, so
|
|
157
|
+
// Drawer stays mounted (above) and gets `open={overlay && open}`, which
|
|
158
|
+
// flips synchronously in the same render as the crossing. That alone still
|
|
159
|
+
// leaves `open` state remembering `true`, so re-entering overlay mode later
|
|
160
|
+
// would reopen it unprompted — this effect resets the state on the
|
|
161
|
+
// overlay:true→false EDGE only (a ref, not `!overlay`), so it never fights
|
|
162
|
+
// a controlled consumer legitimately setting `sidebarOpen` while already
|
|
163
|
+
// above the threshold.
|
|
164
|
+
const wasOverlay = useRef(overlay);
|
|
165
|
+
useEffect(() => {
|
|
166
|
+
// `&& open` — otherwise every up-crossing fires onSidebarOpenChange(false)
|
|
167
|
+
// even when the drawer was never opened (setOpen is a no-op value-wise,
|
|
168
|
+
// but the callback still fires on a resize the consumer didn't ask about).
|
|
169
|
+
if (wasOverlay.current && !overlay && open) setOpen(false);
|
|
170
|
+
wasOverlay.current = overlay;
|
|
171
|
+
}, [overlay, open, setOpen]);
|
|
172
|
+
|
|
173
|
+
// Pattern A — props last: AppLayout is a consumer-overridable layout
|
|
174
|
+
// primitive (like Stack/Card), so {...props} wins over our defaults.
|
|
175
|
+
// Topology: banner above a row of [full-height sidebar | column of (topBar,
|
|
176
|
+
// contextBanner, main)] — so
|
|
177
|
+
// the sidebar spans the whole height and the top bar sits only over the
|
|
178
|
+
// content column, matching the CRM shell (see playground AppShell).
|
|
179
|
+
return (
|
|
180
|
+
<div ref={ref} className={clsx(styles.root, className)} {...props}>
|
|
181
|
+
{banner != null && banner !== false && <div className={styles.banner}>{banner}</div>}
|
|
182
|
+
<div className={styles.row}>
|
|
183
|
+
{sidebar != null && !overlay && (
|
|
184
|
+
<div className={clsx(styles.sidebar, sidebarPinned && styles.sidebarPinned)}>
|
|
185
|
+
{sidebar}
|
|
186
|
+
</div>
|
|
187
|
+
)}
|
|
188
|
+
<div className={styles.body}>
|
|
189
|
+
{topBar != null && <div className={styles.topBar}>{topBar}</div>}
|
|
190
|
+
{contextBanner != null && contextBanner !== false && (
|
|
191
|
+
<div className={styles.contextBanner}>{contextBanner}</div>
|
|
192
|
+
)}
|
|
193
|
+
<Main className={styles.main}>{children}</Main>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
{overlayConfigured && (
|
|
197
|
+
<Drawer
|
|
198
|
+
open={overlay && open}
|
|
199
|
+
onOpenChange={setOpen}
|
|
200
|
+
side="left"
|
|
201
|
+
size="sm"
|
|
202
|
+
className={styles.overlaySidebar}
|
|
203
|
+
aria-label={t('appLayout.sidebar')}
|
|
204
|
+
>
|
|
205
|
+
<Drawer.Header>{t('appLayout.sidebar')}</Drawer.Header>
|
|
206
|
+
<div className={styles.overlaySidebarContent}>{sidebar}</div>
|
|
207
|
+
</Drawer>
|
|
208
|
+
)}
|
|
209
|
+
</div>
|
|
210
|
+
);
|
|
211
|
+
});
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
@use './Avatar.tokens';
|
|
2
|
+
|
|
3
|
+
// Root carries the Avatar size class (diameter); position:relative anchors the
|
|
4
|
+
// .badge (Rule 4 escape hatch for an internal child, same as Avatar's .presence).
|
|
5
|
+
.agent {
|
|
6
|
+
position: relative;
|
|
7
|
+
display: inline-flex;
|
|
8
|
+
align-items: center;
|
|
9
|
+
justify-content: center;
|
|
10
|
+
flex-shrink: 0;
|
|
11
|
+
border-radius: var(--avatar-radius);
|
|
12
|
+
user-select: none;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// The circular tile; clips the mark (incl. non-SVG marks) to the circle. The
|
|
16
|
+
// badge is the tile's sibling, not a descendant, so this clip never reaches it.
|
|
17
|
+
.tile {
|
|
18
|
+
display: flex;
|
|
19
|
+
overflow: hidden;
|
|
20
|
+
align-items: center;
|
|
21
|
+
justify-content: center;
|
|
22
|
+
width: 100%;
|
|
23
|
+
height: 100%;
|
|
24
|
+
border-radius: inherit;
|
|
25
|
+
background: var(--agent-avatar-bg);
|
|
26
|
+
color: var(--agent-avatar-fg);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.mark {
|
|
30
|
+
display: flex;
|
|
31
|
+
align-items: center;
|
|
32
|
+
justify-content: center;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.mark svg {
|
|
36
|
+
width: 100%;
|
|
37
|
+
height: 100%;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.inline .mark {
|
|
41
|
+
width: var(--agent-avatar-mark-size-inline);
|
|
42
|
+
height: var(--agent-avatar-mark-size-inline);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.sm .mark {
|
|
46
|
+
width: var(--agent-avatar-mark-size-sm);
|
|
47
|
+
height: var(--agent-avatar-mark-size-sm);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.md .mark {
|
|
51
|
+
width: var(--agent-avatar-mark-size-md);
|
|
52
|
+
height: var(--agent-avatar-mark-size-md);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.lg .mark {
|
|
56
|
+
width: var(--agent-avatar-mark-size-lg);
|
|
57
|
+
height: var(--agent-avatar-mark-size-lg);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.xl .mark {
|
|
61
|
+
width: var(--agent-avatar-mark-size-xl);
|
|
62
|
+
height: var(--agent-avatar-mark-size-xl);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Member badge, bottom-right, with a surface ring. The inner <Avatar> keeps
|
|
66
|
+
// its own size class, so force it to fill the sized badge box.
|
|
67
|
+
.badge {
|
|
68
|
+
position: absolute;
|
|
69
|
+
right: 0;
|
|
70
|
+
bottom: 0;
|
|
71
|
+
display: flex;
|
|
72
|
+
border-radius: var(--avatar-radius);
|
|
73
|
+
box-shadow: 0 0 0 var(--agent-avatar-badge-ring-width) var(--agent-avatar-badge-ring-color);
|
|
74
|
+
font-size: var(--agent-avatar-badge-font-size);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.badge > span {
|
|
78
|
+
width: 100%;
|
|
79
|
+
height: 100%;
|
|
80
|
+
font-size: inherit;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.erased {
|
|
84
|
+
display: flex;
|
|
85
|
+
align-items: center;
|
|
86
|
+
justify-content: center;
|
|
87
|
+
width: 100%;
|
|
88
|
+
height: 100%;
|
|
89
|
+
border-radius: inherit;
|
|
90
|
+
background: var(--agent-avatar-bg);
|
|
91
|
+
color: var(--agent-avatar-fg);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.erased svg {
|
|
95
|
+
width: 70%;
|
|
96
|
+
height: 70%;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.sm .badge {
|
|
100
|
+
width: var(--agent-avatar-badge-size-sm);
|
|
101
|
+
height: var(--agent-avatar-badge-size-sm);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.md .badge {
|
|
105
|
+
width: var(--agent-avatar-badge-size-md);
|
|
106
|
+
height: var(--agent-avatar-badge-size-md);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.lg .badge {
|
|
110
|
+
width: var(--agent-avatar-badge-size-lg);
|
|
111
|
+
height: var(--agent-avatar-badge-size-lg);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.xl .badge {
|
|
115
|
+
width: var(--agent-avatar-badge-size-xl);
|
|
116
|
+
height: var(--agent-avatar-badge-size-xl);
|
|
117
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { Bot, User } from 'lucide-react';
|
|
4
|
+
import { useTranslation } from '../../i18n';
|
|
5
|
+
import { Avatar, type AvatarSize } from './Avatar';
|
|
6
|
+
import avatarStyles from './Avatar.module.scss';
|
|
7
|
+
import styles from './AgentAvatar.module.scss';
|
|
8
|
+
|
|
9
|
+
/** The member an agent acts for, shown as a badge on the tile. */
|
|
10
|
+
export interface AgentAvatarMember {
|
|
11
|
+
/** Member's full name; drives the badge initials and the accessible name. */
|
|
12
|
+
name: string;
|
|
13
|
+
/** Member's photo URL; initials are shown when omitted or it fails to load. */
|
|
14
|
+
src?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface AgentAvatarProps extends HTMLAttributes<HTMLSpanElement> {
|
|
18
|
+
/**
|
|
19
|
+
* Agent label; drives the accessible name (an empty label reads as "?",
|
|
20
|
+
* like `Avatar`). Unused when `decorative`.
|
|
21
|
+
*/
|
|
22
|
+
name: string;
|
|
23
|
+
/** Agent mark, inherits `currentColor` (a neutral foreground), so pass a glyph drawn with `fill`/`stroke="currentColor"`; marks with hard-coded fills keep their colours (the app's responsibility). Defaults to a lucide `Bot`. */
|
|
24
|
+
mark?: ReactNode;
|
|
25
|
+
/**
|
|
26
|
+
* The member the agent acts for. Omit for an agent alone (no badge); `null`
|
|
27
|
+
* or an empty name for an erased member (placeholder badge).
|
|
28
|
+
*/
|
|
29
|
+
member?: AgentAvatarMember | null;
|
|
30
|
+
/** Diameter, same scale as `Avatar`. The member badge is hidden at `inline`. */
|
|
31
|
+
size?: AvatarSize;
|
|
32
|
+
/**
|
|
33
|
+
* Hide the avatar from assistive tech (`aria-hidden`, no role or label). Use
|
|
34
|
+
* when visible text next to it already names the agent and the member, e.g.
|
|
35
|
+
* a Thread node beside a "Scout for Sarah Chen" byline; otherwise both are
|
|
36
|
+
* announced. Without such text keep the default: a `role="img"` named
|
|
37
|
+
* "{agent}, on behalf of {member}". `PersonDisplay.AgentAvatar` always sets
|
|
38
|
+
* it. Defaults to `false`.
|
|
39
|
+
*/
|
|
40
|
+
decorative?: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const sizeClass: Record<AvatarSize, string> = {
|
|
44
|
+
inline: styles.inline,
|
|
45
|
+
sm: styles.sm,
|
|
46
|
+
md: styles.md,
|
|
47
|
+
lg: styles.lg,
|
|
48
|
+
xl: styles.xl,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const avatarSizeClass: Record<AvatarSize, string> = {
|
|
52
|
+
inline: avatarStyles.inline,
|
|
53
|
+
sm: avatarStyles.sm,
|
|
54
|
+
md: avatarStyles.md,
|
|
55
|
+
lg: avatarStyles.lg,
|
|
56
|
+
xl: avatarStyles.xl,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* AI agent tile with an optional badge of the member it acts for.
|
|
61
|
+
* @see docs/components/AgentAvatar.md
|
|
62
|
+
*/
|
|
63
|
+
export const AgentAvatar = forwardRef<HTMLSpanElement, AgentAvatarProps>(function AgentAvatar(
|
|
64
|
+
{ name, mark, member, size = 'md', decorative, className, ...props },
|
|
65
|
+
ref,
|
|
66
|
+
) {
|
|
67
|
+
const t = useTranslation();
|
|
68
|
+
const agent = name.trim() === '' ? '?' : name.trim();
|
|
69
|
+
const memberName = member?.name?.trim() ?? '';
|
|
70
|
+
const erased = member === null || (member !== undefined && memberName === '');
|
|
71
|
+
|
|
72
|
+
const label = erased
|
|
73
|
+
? t('avatar.agent.onBehalfOfFormer', { agent })
|
|
74
|
+
: member
|
|
75
|
+
? t('avatar.agent.onBehalfOf', { agent, member: memberName })
|
|
76
|
+
: agent;
|
|
77
|
+
|
|
78
|
+
const badge =
|
|
79
|
+
size === 'inline' || member === undefined ? null : (
|
|
80
|
+
<span
|
|
81
|
+
aria-hidden="true"
|
|
82
|
+
className={styles.badge}
|
|
83
|
+
data-part="badge"
|
|
84
|
+
data-erased={erased || undefined}
|
|
85
|
+
>
|
|
86
|
+
{erased ? (
|
|
87
|
+
<span className={styles.erased}>
|
|
88
|
+
<User />
|
|
89
|
+
</span>
|
|
90
|
+
) : (
|
|
91
|
+
<Avatar size="sm" name={memberName} src={member?.src} />
|
|
92
|
+
)}
|
|
93
|
+
</span>
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
// {...props} first so component-owned ARIA (role, aria-label) wins. Decorative
|
|
97
|
+
// strips consumer role/label; otherwise aria-labelledby is dropped so it can't
|
|
98
|
+
// override the computed aria-label.
|
|
99
|
+
return (
|
|
100
|
+
<span
|
|
101
|
+
{...props}
|
|
102
|
+
ref={ref}
|
|
103
|
+
{...(decorative
|
|
104
|
+
? {
|
|
105
|
+
'aria-hidden': true,
|
|
106
|
+
role: undefined,
|
|
107
|
+
'aria-label': undefined,
|
|
108
|
+
'aria-labelledby': undefined,
|
|
109
|
+
}
|
|
110
|
+
: { role: 'img', 'aria-label': label, 'aria-labelledby': undefined })}
|
|
111
|
+
className={clsx(styles.agent, avatarSizeClass[size], sizeClass[size], className)}
|
|
112
|
+
data-agent-avatar=""
|
|
113
|
+
>
|
|
114
|
+
<span className={styles.tile}>
|
|
115
|
+
<span aria-hidden="true" className={styles.mark} data-part="mark">
|
|
116
|
+
{mark ?? <Bot />}
|
|
117
|
+
</span>
|
|
118
|
+
</span>
|
|
119
|
+
{badge}
|
|
120
|
+
</span>
|
|
121
|
+
);
|
|
122
|
+
});
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
@use './Avatar.tokens';
|
|
2
|
+
|
|
3
|
+
// Outer wrapper — position:relative anchors the .presence dot (Rule 4 escape
|
|
4
|
+
// hatch for an internal child). No overflow:hidden here — that lives on .crop
|
|
5
|
+
// so the presence dot sibling is never clipped.
|
|
6
|
+
.avatar {
|
|
7
|
+
position: relative;
|
|
8
|
+
display: inline-flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
justify-content: center;
|
|
11
|
+
flex-shrink: 0;
|
|
12
|
+
border-radius: var(--avatar-radius);
|
|
13
|
+
color: var(--avatar-fg);
|
|
14
|
+
font-weight: var(--avatar-font-weight);
|
|
15
|
+
text-transform: uppercase;
|
|
16
|
+
user-select: none;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Inner crop — clips the image or initials into a circle. Inherits the
|
|
20
|
+
// background color CSS variable set on the outer wrapper.
|
|
21
|
+
.crop {
|
|
22
|
+
position: relative;
|
|
23
|
+
width: 100%;
|
|
24
|
+
height: 100%;
|
|
25
|
+
display: flex;
|
|
26
|
+
align-items: center;
|
|
27
|
+
justify-content: center;
|
|
28
|
+
border-radius: inherit;
|
|
29
|
+
overflow: hidden;
|
|
30
|
+
background: var(--avatar-bg, var(--avatar-bg-fallback));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.crop img {
|
|
34
|
+
width: 100%;
|
|
35
|
+
height: 100%;
|
|
36
|
+
object-fit: cover;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Font-relative (#579): one line of the surrounding text tall. `lh` resolves
|
|
40
|
+
// against THIS element's line-height, so the wrapper must keep the inherited
|
|
41
|
+
// font-size — the initials get their smaller size on .crop instead.
|
|
42
|
+
.inline {
|
|
43
|
+
width: var(--avatar-size-inline);
|
|
44
|
+
height: var(--avatar-size-inline);
|
|
45
|
+
|
|
46
|
+
// In running text the default baseline is the initials' (or, for a photo,
|
|
47
|
+
// the box's bottom), which pushes the 1lh box off the line and grows it.
|
|
48
|
+
// A box exactly one line tall aligned to the line box's top fills it
|
|
49
|
+
// without growing it. Ignored in flex rows, which centre it.
|
|
50
|
+
vertical-align: top;
|
|
51
|
+
|
|
52
|
+
.crop {
|
|
53
|
+
font-size: var(--avatar-font-size-inline);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.sm {
|
|
58
|
+
width: var(--avatar-size-sm);
|
|
59
|
+
height: var(--avatar-size-sm);
|
|
60
|
+
font-size: var(--avatar-font-size-sm);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.md {
|
|
64
|
+
width: var(--avatar-size-md);
|
|
65
|
+
height: var(--avatar-size-md);
|
|
66
|
+
font-size: var(--avatar-font-size-md);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.lg {
|
|
70
|
+
width: var(--avatar-size-lg);
|
|
71
|
+
height: var(--avatar-size-lg);
|
|
72
|
+
font-size: var(--avatar-font-size-lg);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.xl {
|
|
76
|
+
width: var(--avatar-size-xl);
|
|
77
|
+
height: var(--avatar-size-xl);
|
|
78
|
+
font-size: var(--avatar-font-size-xl);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Presence dot (Avatar status). Anchored to the bottom-right via the
|
|
82
|
+
// parent's position:relative. Carries a 2px ring of --color-bg so the dot
|
|
83
|
+
// stays visible on tinted ancestors.
|
|
84
|
+
.presence {
|
|
85
|
+
position: absolute;
|
|
86
|
+
right: 0;
|
|
87
|
+
bottom: 0;
|
|
88
|
+
border-radius: var(--avatar-presence-radius);
|
|
89
|
+
box-shadow: 0 0 0 var(--avatar-presence-ring-width) var(--avatar-presence-ring-color);
|
|
90
|
+
|
|
91
|
+
// Each status carries a distinct SILHOUETTE as well as a colour (#506).
|
|
92
|
+
// Colour was the entire channel, and OKLab separation — what the presence
|
|
93
|
+
// gate in contrast.test.ts measures — is blind to colour-vision deficiency:
|
|
94
|
+
// light away/busy collapses from 0.158 to roughly 0.015 under simulated
|
|
95
|
+
// protanopia while that gate passes. No palette choice fixes it, because
|
|
96
|
+
// `away` has to read as yellow and no amber-or-yellow candidate separates
|
|
97
|
+
// from `busy`. A second channel is the only lever, so:
|
|
98
|
+
// online filled disc
|
|
99
|
+
// away half disc, the cut edge vertical through the centre
|
|
100
|
+
// busy filled disc with a bar across it
|
|
101
|
+
// offline hollow ring
|
|
102
|
+
// Filled / half / barred / hollow stay distinguishable at --size-presence-sm,
|
|
103
|
+
// which is 8px, and none of them depend on hue. Each cut is painted in
|
|
104
|
+
// --color-bg — the same colour as the ring the dot already carries, so the cut
|
|
105
|
+
// and the ring read as one continuous hole rather than as a second colour.
|
|
106
|
+
// That matches the surface exactly only ON --color-bg; on a sunken panel or a
|
|
107
|
+
// selected row the dot sits on its own slightly-off chip, which the pre-existing
|
|
108
|
+
// ring did too. The channel does not depend on the match: cut-vs-fill runs
|
|
109
|
+
// 4.52-11.86:1, so the silhouette survives greyscale and every dichromacy
|
|
110
|
+
// either way. (The 4.52 is offline, the status this branch re-pointed — an
|
|
111
|
+
// earlier version of this line said "5-12:1" and excluded the one value the
|
|
112
|
+
// same commit had just changed.)
|
|
113
|
+
&[data-status='online'] {
|
|
114
|
+
background: var(--avatar-presence-bg-online);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
&[data-status='busy'] {
|
|
118
|
+
background: var(--avatar-presence-bg-busy);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// The bar. `inset` keeps it centred at every dot size without a per-size
|
|
122
|
+
// rule, and it is painted in the surface colour so it reads as a cut.
|
|
123
|
+
&[data-status='busy']::after {
|
|
124
|
+
position: absolute;
|
|
125
|
+
inset: calc(50% - (var(--avatar-presence-bar-height) / 2)) 20%;
|
|
126
|
+
background: var(--avatar-presence-glyph-color);
|
|
127
|
+
content: '';
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Half disc. A hard-stop gradient rather than a pseudo-element, so the shape
|
|
131
|
+
// survives the border-radius clip at any size.
|
|
132
|
+
&[data-status='away'] {
|
|
133
|
+
background-image: linear-gradient(
|
|
134
|
+
to right,
|
|
135
|
+
var(--avatar-presence-bg-away) 0 50%,
|
|
136
|
+
var(--avatar-presence-glyph-color) 50% 100%
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Hollow. The inset shadow draws the stroke inside the same circle, so the
|
|
141
|
+
// outer ring against the avatar is unaffected.
|
|
142
|
+
&[data-status='offline'] {
|
|
143
|
+
background: var(--avatar-presence-glyph-color);
|
|
144
|
+
box-shadow:
|
|
145
|
+
0 0 0 var(--avatar-presence-ring-width) var(--avatar-presence-ring-color),
|
|
146
|
+
inset 0 0 0 var(--avatar-presence-hollow-width) var(--avatar-presence-bg-offline);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Per-size dot dimensions. The size class lives on the avatar wrapper (the
|
|
151
|
+
// .presence child's parent), so a descendant selector picks the right size.
|
|
152
|
+
.inline .presence {
|
|
153
|
+
width: var(--avatar-presence-size-inline);
|
|
154
|
+
height: var(--avatar-presence-size-inline);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.sm .presence {
|
|
158
|
+
width: var(--avatar-presence-size-sm);
|
|
159
|
+
height: var(--avatar-presence-size-sm);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.md .presence {
|
|
163
|
+
width: var(--avatar-presence-size-md);
|
|
164
|
+
height: var(--avatar-presence-size-md);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.lg .presence {
|
|
168
|
+
width: var(--avatar-presence-size-lg);
|
|
169
|
+
height: var(--avatar-presence-size-lg);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.xl .presence {
|
|
173
|
+
width: var(--avatar-presence-size-xl);
|
|
174
|
+
height: var(--avatar-presence-size-xl);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// When inside an AvatarGroup, each avatar picks up a --color-bg ring so
|
|
178
|
+
// stacked siblings read as distinct.
|
|
179
|
+
.inGroup {
|
|
180
|
+
box-shadow: 0 0 0 var(--avatar-in-group-ring-width) var(--avatar-in-group-ring-color);
|
|
181
|
+
}
|