@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,649 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Fragment,
|
|
3
|
+
forwardRef,
|
|
4
|
+
type ComponentPropsWithoutRef,
|
|
5
|
+
type ComponentPropsWithRef,
|
|
6
|
+
type CSSProperties,
|
|
7
|
+
type ElementType,
|
|
8
|
+
type FocusEvent as ReactFocusEvent,
|
|
9
|
+
type ForwardedRef,
|
|
10
|
+
type ReactElement,
|
|
11
|
+
type ReactNode,
|
|
12
|
+
} from 'react';
|
|
13
|
+
import clsx from 'clsx';
|
|
14
|
+
import { useTranslation } from '../../i18n/useTranslation';
|
|
15
|
+
import { paletteTokens, type PaletteColor } from '../../palette';
|
|
16
|
+
import { resolveStatusColor, type StatusCategory } from '../_internal/statusColor';
|
|
17
|
+
import { chain } from '../_internal/refs';
|
|
18
|
+
import { useClippedTooltip } from '../_internal/useClippedTooltip';
|
|
19
|
+
import { Tooltip } from '../Tooltip';
|
|
20
|
+
import styles from './EntityChip.module.scss';
|
|
21
|
+
|
|
22
|
+
/** Elements EntityChip can render as. All inline-safe phrasing content. */
|
|
23
|
+
export type EntityChipAs = ElementType;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Font weight for `label` (#590). `'medium'` (default) matches a plain chip
|
|
27
|
+
* and the RichText `@mention`, and applies to `label` only — `prefix` has no
|
|
28
|
+
* weight rule of its own and stays inherited (normal). `'semibold'` is the
|
|
29
|
+
* one value that also sets `prefix`, for designs that want a heavier title —
|
|
30
|
+
* e.g. the segmented task chip, whose key and title are both semibold. See
|
|
31
|
+
* `labelWeight` on `EntityChipOwnProps`.
|
|
32
|
+
*/
|
|
33
|
+
export type EntityChipLabelWeight = 'medium' | 'semibold';
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Which end of a clipped `label` is cut (#593). See `labelEllipsis` on
|
|
37
|
+
* `EntityChipOwnProps`.
|
|
38
|
+
*/
|
|
39
|
+
export type EntityChipLabelEllipsis = 'end' | 'start';
|
|
40
|
+
|
|
41
|
+
export interface EntityChipStatus {
|
|
42
|
+
/** Status label, rendered inside the chip in the status's own color. */
|
|
43
|
+
label: string;
|
|
44
|
+
/** Semantic category → default color: to_do slate / in_progress blue / open violet / done green / won green / lost red. */
|
|
45
|
+
category?: StatusCategory;
|
|
46
|
+
/** Explicit palette color — wins over `category` (per-state custom colors). */
|
|
47
|
+
color?: PaletteColor;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* A coloured part of a segmented chip (#582), rendered before or after the
|
|
52
|
+
* chip's core (icon · prefix · label · status · trailing). Non-interactive:
|
|
53
|
+
* the chip itself is the link.
|
|
54
|
+
*/
|
|
55
|
+
export type EntityChipSegment =
|
|
56
|
+
| {
|
|
57
|
+
/** Discriminant: an icon segment — a glyph on a palette colour. */
|
|
58
|
+
kind: 'icon';
|
|
59
|
+
/**
|
|
60
|
+
* The glyph, e.g. a lucide icon. `size` below sizes a direct `<svg>`
|
|
61
|
+
* child only — a wrapped icon (an `<IconTile>`, a styled span) isn't
|
|
62
|
+
* sized by it. Rendered `aria-hidden`; `label` carries the meaning.
|
|
63
|
+
*/
|
|
64
|
+
icon: ReactNode;
|
|
65
|
+
/**
|
|
66
|
+
* This segment's accessible name (the segment is `role="img"`) AND its
|
|
67
|
+
* hover tooltip — it IS the segment's meaning, not decoration. An icon
|
|
68
|
+
* segment with no meaningful label is an anti-pattern; a purely
|
|
69
|
+
* decorative glyph belongs in the chip's own `icon` prop instead.
|
|
70
|
+
*/
|
|
71
|
+
label: string;
|
|
72
|
+
/** Palette color for the segment's fill/fg pair. Default `'slate'`. */
|
|
73
|
+
color?: PaletteColor;
|
|
74
|
+
/**
|
|
75
|
+
* Overrides the glyph size, a positive number in em of the chip text,
|
|
76
|
+
* at most `1` (larger values are clamped to 1 — a segment never makes
|
|
77
|
+
* the chip taller than a plain chip). Default `0.85em`.
|
|
78
|
+
*/
|
|
79
|
+
size?: number;
|
|
80
|
+
}
|
|
81
|
+
| {
|
|
82
|
+
/** Discriminant: a text segment — a short value on a palette colour. */
|
|
83
|
+
kind: 'text';
|
|
84
|
+
/**
|
|
85
|
+
* The segment's text AND its accessible name — this is what a screen
|
|
86
|
+
* reader hears, so the full meaning must live here, not in `tooltip`.
|
|
87
|
+
*/
|
|
88
|
+
text: ReactNode;
|
|
89
|
+
/** Palette color for the segment's fill/fg pair. Default `'slate'`. */
|
|
90
|
+
color?: PaletteColor;
|
|
91
|
+
/**
|
|
92
|
+
* Supplementary detail shown on hover only — the segment isn't
|
|
93
|
+
* focusable (focus lands on the chip), and it's never part of the
|
|
94
|
+
* accessible name. Don't put meaning here that isn't also in `text`;
|
|
95
|
+
* keyboard and screen-reader users never see it.
|
|
96
|
+
*/
|
|
97
|
+
tooltip?: ReactNode;
|
|
98
|
+
/**
|
|
99
|
+
* Overrides the segment's font size, a positive number in em of the
|
|
100
|
+
* chip text, at most `1` (larger values are clamped to 1). Default
|
|
101
|
+
* `0.9em`. The segment text always sits on the label's baseline and the
|
|
102
|
+
* chip keeps a plain chip's height; a segment larger than the chip's
|
|
103
|
+
* own text would break both, so it isn't supported.
|
|
104
|
+
*/
|
|
105
|
+
size?: number;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
interface EntityChipOwnProps {
|
|
109
|
+
/** Leading icon — consumer passes the element (e.g. a lucide icon). Rendered aria-hidden. */
|
|
110
|
+
icon?: ReactNode;
|
|
111
|
+
/**
|
|
112
|
+
* Entity name. Optional at the type level only to satisfy the polymorphic
|
|
113
|
+
* `forwardRef` generic (same workaround `<Rail.Item>` documents on its
|
|
114
|
+
* `children`); in practice every chip needs a label.
|
|
115
|
+
*/
|
|
116
|
+
label?: ReactNode;
|
|
117
|
+
/** Muted leading run before the name (e.g. task key `ENG-5`). */
|
|
118
|
+
prefix?: ReactNode;
|
|
119
|
+
/**
|
|
120
|
+
* Inline workflow status `{ label, category?, color? }`, separated by a small dot and rendered in the
|
|
121
|
+
* status's own color. `category` (`to_do`/`in_progress`/`open`/`done`/`won`/`lost`) resolves a default
|
|
122
|
+
* palette color (same mapping as `<PillMenu>`); `color` overrides it. The dot takes the resolved color too.
|
|
123
|
+
*/
|
|
124
|
+
status?: EntityChipStatus;
|
|
125
|
+
/**
|
|
126
|
+
* Optional categorical palette color for the chip fill. When set, takes
|
|
127
|
+
* precedence over the default accent chip tokens: the chip fills with the
|
|
128
|
+
* matching `--color-palette-<name>-bg/-fg` pair (same contract as `Badge
|
|
129
|
+
* color` — picking a readable pair is the consumer's call). Omit for the
|
|
130
|
+
* default fill, which matches RichText's `@mention` styling
|
|
131
|
+
* (`--color-accent-bg-subtle` / `--color-accent`) so a chip and a rendered
|
|
132
|
+
* mention read as the same visual object. The `status` run keeps its own
|
|
133
|
+
* resolved color independent of this prop, and `unavailable` still mutes
|
|
134
|
+
* the label/status text over any `color`.
|
|
135
|
+
*/
|
|
136
|
+
color?: PaletteColor;
|
|
137
|
+
/** Renders `as="a"` with this href when `as` is omitted. */
|
|
138
|
+
href?: string;
|
|
139
|
+
/**
|
|
140
|
+
* Loading placeholder: icon slot + `…` body, aria-busy; the label stays in
|
|
141
|
+
* the DOM visually hidden so the chip keeps its accessible name. Purely
|
|
142
|
+
* visual — with a link target (`href`/`as`) the chip stays a live,
|
|
143
|
+
* keyboard-reachable link while loading.
|
|
144
|
+
*
|
|
145
|
+
* The state is announced: a localized word is rendered visually hidden, so a
|
|
146
|
+
* linked chip's name becomes "Appointment (loading)". `aria-busy` alone did
|
|
147
|
+
* not do this. It is a GLOBAL ARIA state, so unlike `aria-disabled` it is
|
|
148
|
+
* perfectly valid on the chip's role-less span and browsers do expose it —
|
|
149
|
+
* but no mainstream screen reader conveys `busy` as a state on a non-live
|
|
150
|
+
* element, and the ellipsis is `aria-hidden`. The label reached the user
|
|
151
|
+
* fine; no signal of the LOADING STATE did.
|
|
152
|
+
*
|
|
153
|
+
* Know the trade: the accessible name CHANGES when loading resolves — and by
|
|
154
|
+
* more than this word. The loading branch renders neither `prefix` nor
|
|
155
|
+
* `status` (nor `before`/`after` segments), so a chip with both goes from
|
|
156
|
+
* "Fix login bug (loading)" to "ENG-5 Fix login bug In progress". That is
|
|
157
|
+
* unavoidable when announcing a transient state through the name, and it is
|
|
158
|
+
* why this was initially left alone. Note it also means a consumer query like
|
|
159
|
+
* `getByRole('link', { name: 'Appointment' })` no longer matches a LOADING
|
|
160
|
+
* chip.
|
|
161
|
+
*
|
|
162
|
+
* Measured, the mutation itself is benign: Chromium keeps the SAME
|
|
163
|
+
* accessibility node across the transition (same backendNodeId) and focus
|
|
164
|
+
* survives, so nothing is torn down and rebuilt — the name and `busy` simply
|
|
165
|
+
* change on the existing object.
|
|
166
|
+
*
|
|
167
|
+
* The alternative — an `aria-live` region — has to be owned by the consumer,
|
|
168
|
+
* because only the consumer knows whether a given chip resolving is worth
|
|
169
|
+
* interrupting someone for. To take that route, override this word to `''`
|
|
170
|
+
* at your TOP-LEVEL provider: the override is global to a provider subtree
|
|
171
|
+
* (there is no per-chip opt-out), `I18nProvider` requires a `locale`, and a
|
|
172
|
+
* nested provider replaces rather than extends its parent — so wrapping a
|
|
173
|
+
* single chip would silently discard every other override you have set.
|
|
174
|
+
*/
|
|
175
|
+
loading?: boolean;
|
|
176
|
+
/**
|
|
177
|
+
* Entity missing/no access: muted styling. With a link target (`href`/`as`)
|
|
178
|
+
* the chip remains a real link — unavailable is a visual state, not a
|
|
179
|
+
* disabling one. Only a target-less chip (bare span) becomes non-interactive
|
|
180
|
+
* with aria-disabled.
|
|
181
|
+
*
|
|
182
|
+
* The state is also announced: a localized word is rendered visually hidden
|
|
183
|
+
* inside the chip. A linked chip's accessible name becomes
|
|
184
|
+
* "Appointment (unavailable)"; a target-less chip is `role=generic`, which
|
|
185
|
+
* has no accessible name at all, so the word is announced as part of the
|
|
186
|
+
* chip's text in reading order. Either way it reaches the user.
|
|
187
|
+
*
|
|
188
|
+
* That matters because the canonical use is to withhold the entity's name and
|
|
189
|
+
* show a TYPE word instead — without the state, a masked reference is
|
|
190
|
+
* indistinguishable from a real entity that happens to be called
|
|
191
|
+
* "Appointment". Colour alone cannot carry it, and `aria-disabled` does not
|
|
192
|
+
* either: browsers do expose it, but it carries no meaning on a
|
|
193
|
+
* non-widget role such as `generic`, so no assistive tech conveys it.
|
|
194
|
+
*
|
|
195
|
+
* `loading` is announced the same way — see that prop for why `aria-busy`
|
|
196
|
+
* alone was not enough, and for the name-mutation trade it carries.
|
|
197
|
+
*
|
|
198
|
+
* Do NOT put an `aria-label` on the chip. It replaces the whole name and
|
|
199
|
+
* takes the state word with it; the state lives in the chip's contents.
|
|
200
|
+
*
|
|
201
|
+
* Override the word via the i18n provider (`entityChip.unavailable`); it
|
|
202
|
+
* carries its own punctuation so a locale can choose different marks.
|
|
203
|
+
*/
|
|
204
|
+
unavailable?: boolean;
|
|
205
|
+
/**
|
|
206
|
+
* Single-line mode for list rows. The chip is capped at its container's
|
|
207
|
+
* width (`max-width: 100%`, `min-width: 0`, so it also shrinks as a flex
|
|
208
|
+
* item) and only the `label` ellipsizes — `icon`, `prefix`, `status` and
|
|
209
|
+
* `trailing` keep their full size. Default `false`: the label wraps, which
|
|
210
|
+
* is right for a chip inside running text.
|
|
211
|
+
*
|
|
212
|
+
* The full label stays in the DOM, so the accessible name is unchanged. A
|
|
213
|
+
* clipped label shows its full text in a tooltip on hover or keyboard
|
|
214
|
+
* focus — don't add a `title`, which would give a double tooltip.
|
|
215
|
+
*/
|
|
216
|
+
truncate?: boolean;
|
|
217
|
+
/**
|
|
218
|
+
* Extra adornments inside the chip, after `status` (e.g. a priority icon or
|
|
219
|
+
* a status `<Badge>`), kept at full size under `truncate`. Not rendered
|
|
220
|
+
* while `loading` (same as `prefix`/`status`).
|
|
221
|
+
*
|
|
222
|
+
* Non-interactive content only: the chip is itself a link, so a button or
|
|
223
|
+
* link here is invalid nested interactive content. Its text JOINS the chip's
|
|
224
|
+
* accessible name ("ENG-5 Fix login bug High") — give a decorative icon
|
|
225
|
+
* `aria-hidden`, and a meaningful one a short text alternative.
|
|
226
|
+
*/
|
|
227
|
+
trailing?: ReactNode;
|
|
228
|
+
/**
|
|
229
|
+
* Coloured segments before the chip's core, in order (e.g. the task type).
|
|
230
|
+
* Any segment turns the chip segmented: one line, only the outer corners
|
|
231
|
+
* rounded, only the label shrinks (as with `truncate`). Every segment's text
|
|
232
|
+
* joins the accessible name ("Bug ENG-15 Fix login bug Normal Reported").
|
|
233
|
+
* Not rendered while `loading` or `unavailable`.
|
|
234
|
+
*/
|
|
235
|
+
before?: readonly EntityChipSegment[];
|
|
236
|
+
/** Coloured segments after the core, in order (e.g. priority, status). See `before`. */
|
|
237
|
+
after?: readonly EntityChipSegment[];
|
|
238
|
+
/**
|
|
239
|
+
* Caps the label's width, a positive number of `ch`; past it the label
|
|
240
|
+
* ellipsizes on one line (also on a chip without `truncate`). For chips in
|
|
241
|
+
* running text, where the container edge is a whole paragraph away. The
|
|
242
|
+
* full label stays in the DOM and the accessible name; a clipped label
|
|
243
|
+
* shows it in a tooltip on hover or keyboard focus.
|
|
244
|
+
*/
|
|
245
|
+
labelMaxWidth?: number;
|
|
246
|
+
/**
|
|
247
|
+
* Which end of a clipped label is cut. Applies only where the label can
|
|
248
|
+
* clip at all (`truncate`, segments, or `labelMaxWidth`); ignored on a
|
|
249
|
+
* wrapping chip.
|
|
250
|
+
* - `'end'` (default) — `Fix the login bu…`. Right for titles, whose
|
|
251
|
+
* distinctive part is the start.
|
|
252
|
+
* - `'start'` — `…/pull/1116`. For labels whose distinctive part is the
|
|
253
|
+
* tail, e.g. a URL path under a host `prefix`. The text keeps its order;
|
|
254
|
+
* `prefix` and segments stay whole, and the tooltip still shows it all.
|
|
255
|
+
*/
|
|
256
|
+
labelEllipsis?: EntityChipLabelEllipsis;
|
|
257
|
+
/**
|
|
258
|
+
* Font weight for `label`. `'medium'` (default) matches a plain chip's
|
|
259
|
+
* fixed weight and the RichText `@mention` — most chips should leave this
|
|
260
|
+
* unset. `'medium'` does NOT apply to `prefix`: `.prefix` carries no
|
|
261
|
+
* font-weight rule of its own and simply inherits (normal), so a default
|
|
262
|
+
* chip's key is lighter than its title. `'semibold'` is the one value that
|
|
263
|
+
* touches BOTH — it sets `prefix` AND `label` to the same heavier weight
|
|
264
|
+
* (a task-chip design that wants its key heavier along with its title,
|
|
265
|
+
* #590). Use `'semibold'` for a design that explicitly wants that.
|
|
266
|
+
*
|
|
267
|
+
* Don't reach for a styled `<Text weight="semibold">` around `label` to get
|
|
268
|
+
* a heavier title instead (see the clipped-label tooltip bullet in `docs/components/EntityChip.md`) —
|
|
269
|
+
* it buys nothing: the clipped-label tooltip reads the label's own
|
|
270
|
+
* `textContent` and always renders it plain, in the tooltip's own color,
|
|
271
|
+
* regardless of what the label node carries. Only this prop changes the
|
|
272
|
+
* rendered weight.
|
|
273
|
+
*/
|
|
274
|
+
labelWeight?: EntityChipLabelWeight;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Polymorphic props helper. Intersects the component's own props with the
|
|
279
|
+
* underlying element's props (minus what we own), plus the `as` selector.
|
|
280
|
+
* Mirrors `<Link>`'s `PolymorphicProps`.
|
|
281
|
+
*/
|
|
282
|
+
type PolymorphicProps<C extends ElementType, P> = P & { as?: C } & Omit<
|
|
283
|
+
ComponentPropsWithoutRef<C>,
|
|
284
|
+
keyof P | 'as'
|
|
285
|
+
>;
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Public EntityChip prop type. Generic `C` defaults to `'a'`. When the
|
|
289
|
+
* consumer passes `as={SomeComponent}`, all of SomeComponent's props become
|
|
290
|
+
* available with full TypeScript inference (including `to`, `replace`,
|
|
291
|
+
* `state`, etc. for `react-router-dom`'s `<Link>`).
|
|
292
|
+
*/
|
|
293
|
+
export type EntityChipProps<C extends ElementType = 'a'> = PolymorphicProps<C, EntityChipOwnProps>;
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Internal ref type for the polymorphic generic. React's `forwardRef` strips
|
|
297
|
+
* the generic from the returned component, so we re-attach it via the
|
|
298
|
+
* `EntityChipComponent` cast on the export below.
|
|
299
|
+
*/
|
|
300
|
+
type EntityChipComponent = <C extends ElementType = 'a'>(
|
|
301
|
+
props: EntityChipProps<C> & { ref?: ComponentPropsWithRef<C>['ref'] },
|
|
302
|
+
) => ReactElement | null;
|
|
303
|
+
|
|
304
|
+
/** Injectable custom-property for a status's resolved color. */
|
|
305
|
+
function statusColorStyle(status: EntityChipStatus): CSSProperties {
|
|
306
|
+
const { fg } = paletteTokens(resolveStatusColor(status));
|
|
307
|
+
return { '--entity-chip-status-fg': fg } as CSSProperties;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/** Injectable custom-properties for a consumer `color` override — same
|
|
311
|
+
* inline-injection contract as `Badge color`. Points bg-hover at the same
|
|
312
|
+
* bg so the hover brightness filter works on any palette color. */
|
|
313
|
+
function colorStyle(color: PaletteColor): CSSProperties {
|
|
314
|
+
return {
|
|
315
|
+
'--entity-chip-bg': `var(--color-palette-${color}-bg)`,
|
|
316
|
+
'--entity-chip-fg': `var(--color-palette-${color}-fg)`,
|
|
317
|
+
'--entity-chip-bg-hover': `var(--color-palette-${color}-bg)`,
|
|
318
|
+
} as CSSProperties;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Merged inline style for the chip root: the `color` prop's palette
|
|
323
|
+
* injection, the `status`'s resolved color (read by both `.status` and
|
|
324
|
+
* `.dot` — set on the root, not the `.status` span, so the dot — a sibling,
|
|
325
|
+
* not a descendant of `.status` — can see it too), then the consumer's own
|
|
326
|
+
* `style` last so it wins on a collision.
|
|
327
|
+
*/
|
|
328
|
+
function rootStyle(
|
|
329
|
+
color: PaletteColor | undefined,
|
|
330
|
+
status: EntityChipStatus | undefined,
|
|
331
|
+
consumerStyle: CSSProperties | undefined,
|
|
332
|
+
): CSSProperties | undefined {
|
|
333
|
+
const colorVars = color ? colorStyle(color) : undefined;
|
|
334
|
+
const statusVars = status ? statusColorStyle(status) : undefined;
|
|
335
|
+
return colorVars || statusVars || consumerStyle
|
|
336
|
+
? { ...colorVars, ...statusVars, ...consumerStyle }
|
|
337
|
+
: undefined;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* A segment is at most the chip's own text size (1em). Measured in Chromium:
|
|
342
|
+
* above 1, only the segment grows (the core doesn't stretch), leaving a
|
|
343
|
+
* ragged bottom edge and the segment text below the label's baseline.
|
|
344
|
+
*/
|
|
345
|
+
function clampSegmentSize(size: number): number {
|
|
346
|
+
return Math.min(size, 1);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Palette fill/fg for one segment, read by `.segment`, plus an icon segment's
|
|
351
|
+
* `size` override (its glyph size custom property). A text segment's `size`
|
|
352
|
+
* is NOT set here (#591) — it goes on the inner `.segmentTextValue` span
|
|
353
|
+
* instead, so the outer box keeps the chip's own font-size/line-height and
|
|
354
|
+
* its text sits on the label's baseline.
|
|
355
|
+
*/
|
|
356
|
+
function segmentStyle(segment: EntityChipSegment): CSSProperties {
|
|
357
|
+
const { bg, fg } = paletteTokens(segment.color ?? 'slate');
|
|
358
|
+
const style: Record<string, string> = {
|
|
359
|
+
'--entity-chip-segment-bg': bg,
|
|
360
|
+
'--entity-chip-segment-fg': fg,
|
|
361
|
+
};
|
|
362
|
+
if (segment.kind === 'icon' && segment.size != null) {
|
|
363
|
+
style['--entity-chip-segment-glyph-size'] = `${clampSegmentSize(segment.size)}em`;
|
|
364
|
+
}
|
|
365
|
+
return style as CSSProperties;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
function Segment({ segment }: { segment: EntityChipSegment }): ReactElement {
|
|
369
|
+
if (segment.kind === 'icon') {
|
|
370
|
+
return (
|
|
371
|
+
<Tooltip content={segment.label}>
|
|
372
|
+
<span
|
|
373
|
+
className={clsx(styles.segment, styles.segmentIcon)}
|
|
374
|
+
style={segmentStyle(segment)}
|
|
375
|
+
role="img"
|
|
376
|
+
aria-label={segment.label}
|
|
377
|
+
>
|
|
378
|
+
<span className={styles.segmentGlyph} aria-hidden="true">
|
|
379
|
+
{segment.icon}
|
|
380
|
+
</span>
|
|
381
|
+
</span>
|
|
382
|
+
</Tooltip>
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
const node = (
|
|
386
|
+
<span className={clsx(styles.segment, styles.segmentText)} style={segmentStyle(segment)}>
|
|
387
|
+
{/* Inner span carries the smaller size (#591) — the outer box keeps the
|
|
388
|
+
chip's own font-size/line-height so the strut sets the baseline;
|
|
389
|
+
this span then sits on it via normal inline layout. */}
|
|
390
|
+
<span
|
|
391
|
+
className={styles.segmentTextValue}
|
|
392
|
+
style={
|
|
393
|
+
segment.size != null ? { fontSize: `${clampSegmentSize(segment.size)}em` } : undefined
|
|
394
|
+
}
|
|
395
|
+
>
|
|
396
|
+
{segment.text}
|
|
397
|
+
</span>
|
|
398
|
+
</span>
|
|
399
|
+
);
|
|
400
|
+
return segment.tooltip != null ? <Tooltip content={segment.tooltip}>{node}</Tooltip> : node;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Inline entity-link chip: icon, muted prefix, name and workflow status in one inline root.
|
|
405
|
+
* @see docs/components/EntityChip.md
|
|
406
|
+
*/
|
|
407
|
+
export const EntityChip = forwardRef(function EntityChip<C extends ElementType = 'a'>(
|
|
408
|
+
{
|
|
409
|
+
as,
|
|
410
|
+
icon,
|
|
411
|
+
label,
|
|
412
|
+
prefix,
|
|
413
|
+
status,
|
|
414
|
+
color,
|
|
415
|
+
href,
|
|
416
|
+
loading = false,
|
|
417
|
+
unavailable = false,
|
|
418
|
+
truncate = false,
|
|
419
|
+
trailing,
|
|
420
|
+
before,
|
|
421
|
+
after,
|
|
422
|
+
labelMaxWidth,
|
|
423
|
+
labelWeight = 'medium',
|
|
424
|
+
labelEllipsis = 'end',
|
|
425
|
+
className,
|
|
426
|
+
style,
|
|
427
|
+
...rest
|
|
428
|
+
}: EntityChipProps<C>,
|
|
429
|
+
ref: ForwardedRef<Element>,
|
|
430
|
+
) {
|
|
431
|
+
// A link target (`as` or `href`) always wins: loading/unavailable are then
|
|
432
|
+
// purely visual states on a live, keyboard-reachable link. Only a bare span
|
|
433
|
+
// (no target) becomes genuinely non-interactive when unavailable.
|
|
434
|
+
const t = useTranslation();
|
|
435
|
+
const Component = (as ?? (href ? 'a' : 'span')) as ElementType;
|
|
436
|
+
const bareSpan = !as && !href;
|
|
437
|
+
const inert = unavailable && bareSpan;
|
|
438
|
+
// Segments only in the normal state — like prefix/status under `loading`, a
|
|
439
|
+
// not-yet-loaded or unavailable entity has no known type/status (#582).
|
|
440
|
+
const hasSegments = (before?.length ?? 0) > 0 || (after?.length ?? 0) > 0;
|
|
441
|
+
const segmented = !loading && !unavailable && hasSegments;
|
|
442
|
+
// `hasSegments`, not `segmented`: a loading/unavailable chip with `before`/
|
|
443
|
+
// `after` configured still gets the `truncate` class (below) even though
|
|
444
|
+
// `segmented` itself stays gated off — its label can still be clipped, and
|
|
445
|
+
// should still get a tooltip. Safe for `loading` regardless, since that
|
|
446
|
+
// branch never renders the label Tooltip at all (#582 review).
|
|
447
|
+
const clippable = truncate || hasSegments || labelMaxWidth != null;
|
|
448
|
+
// Whether the label Tooltip is mounted: the loading branch never renders it.
|
|
449
|
+
const labelTip = clippable && !loading;
|
|
450
|
+
// Full label on hover/focus, only when actually clipped (see useClippedTooltip).
|
|
451
|
+
const labelTipState = useClippedTooltip<HTMLSpanElement>(label, labelTip);
|
|
452
|
+
// Keyboard reachability for the clipped-label tooltip: its Tooltip trigger
|
|
453
|
+
// is the label `<span>`, which is not itself focusable — focus lands on the
|
|
454
|
+
// chip root. Chain onto the root's own onFocus/onBlur (preserving whatever
|
|
455
|
+
// the consumer passed via `...rest`) so tabbing onto the chip opens the same
|
|
456
|
+
// controlled tooltip `labelTipState` already opens on hover — only when it is
|
|
457
|
+
// actually clipped, and only when the chip has a clippable label at all.
|
|
458
|
+
// `:focus-visible` gate mirrors Tooltip.tsx's `handleFocus` exactly,
|
|
459
|
+
// including its jsdom fallback (matches() unsupported/throwing → open).
|
|
460
|
+
const restOnFocus = (rest as { onFocus?: (e: ReactFocusEvent<Element>) => void }).onFocus;
|
|
461
|
+
const restOnBlur = (rest as { onBlur?: (e: ReactFocusEvent<Element>) => void }).onBlur;
|
|
462
|
+
// Attached only when `clippable` (below), so no guard here.
|
|
463
|
+
const handleRootFocus = (e: ReactFocusEvent<Element>) => {
|
|
464
|
+
const node = e.currentTarget;
|
|
465
|
+
let focusVisible = true;
|
|
466
|
+
try {
|
|
467
|
+
if (typeof node.matches === 'function') {
|
|
468
|
+
focusVisible = node.matches(':focus-visible');
|
|
469
|
+
}
|
|
470
|
+
} catch {
|
|
471
|
+
focusVisible = true;
|
|
472
|
+
}
|
|
473
|
+
if (!focusVisible) return;
|
|
474
|
+
labelTipState.onOpenChange(true);
|
|
475
|
+
};
|
|
476
|
+
const handleRootBlur = () => labelTipState.onOpenChange(false);
|
|
477
|
+
// The state as real text, not just muted colour. Browsers do expose
|
|
478
|
+
// `aria-disabled`, but it carries no meaning on a non-widget role such as
|
|
479
|
+
// `generic`, so no AT conveys it — without this the state reached nobody using a screen reader,
|
|
480
|
+
// and an `unavailable` chip labelled with a type word ("Appointment") was
|
|
481
|
+
// indistinguishable from a real entity of that name. Rendered for linked
|
|
482
|
+
// chips too: muted styling is the sole signal there as well.
|
|
483
|
+
//
|
|
484
|
+
// The leading space is for `textContent` only — it is what selection/copy
|
|
485
|
+
// yields, and what the tests assert. It reaches no accessible name in either
|
|
486
|
+
// engine: measured, the space never renders (line-leading in this block box,
|
|
487
|
+
// so it collapses — 0.000px delta), Chromium supplies its own separator
|
|
488
|
+
// between the block-level children, and `dom-accessibility-api` drops it too.
|
|
489
|
+
// A sibling text node would be equivalent and would NOT take the chip's `gap`
|
|
490
|
+
// (a whitespace-only flex item is not rendered at all); keeping it inside
|
|
491
|
+
// just leaves the chip's children all elements. Same shape as Field's
|
|
492
|
+
// "(optional)".
|
|
493
|
+
//
|
|
494
|
+
// Defined once, rendered in both branches so it can sit immediately after the
|
|
495
|
+
// entity name. Trailing the status instead gave "Appointment In progress
|
|
496
|
+
// (unavailable)", where the parenthetical can be heard as qualifying the
|
|
497
|
+
// STATUS rather than the entity. Out of flow, so placing it costs no layout.
|
|
498
|
+
const stateWord = unavailable ? (
|
|
499
|
+
<span className={styles.hiddenLabel}> {t('entityChip.unavailable')}</span>
|
|
500
|
+
) : null;
|
|
501
|
+
const elementProps: { href?: string; type?: string } = {};
|
|
502
|
+
if (Component === 'a') elementProps.href = href;
|
|
503
|
+
if (Component === 'button') elementProps.type = 'button';
|
|
504
|
+
|
|
505
|
+
const content = (
|
|
506
|
+
<>
|
|
507
|
+
{icon && (
|
|
508
|
+
<span className={styles.icon} aria-hidden="true">
|
|
509
|
+
{icon}
|
|
510
|
+
</span>
|
|
511
|
+
)}
|
|
512
|
+
{loading ? (
|
|
513
|
+
<>
|
|
514
|
+
<span className={styles.ellipsis} aria-hidden="true">
|
|
515
|
+
…
|
|
516
|
+
</span>
|
|
517
|
+
{/* Label stays in the DOM visually hidden so a linked loading chip
|
|
518
|
+
keeps its accessible name instead of being announced as "…". */}
|
|
519
|
+
<span className={styles.hiddenLabel}>{label}</span>
|
|
520
|
+
{/* The busy state as real text. `aria-busy` is set on the chip root
|
|
521
|
+
above and is valid there — unlike `aria-disabled` it is a GLOBAL
|
|
522
|
+
ARIA state, so the role-less span is not the problem. But no
|
|
523
|
+
mainstream screen reader conveys `busy` on a non-live element, so
|
|
524
|
+
the aria-hidden ellipsis was the only signal. Placed after the
|
|
525
|
+
label and before the unavailable word so a chip carrying both
|
|
526
|
+
reads "Appointment (loading) (unavailable)". */}
|
|
527
|
+
<span className={styles.hiddenLabel}> {t('entityChip.loading')}</span>
|
|
528
|
+
{stateWord}
|
|
529
|
+
</>
|
|
530
|
+
) : (
|
|
531
|
+
<>
|
|
532
|
+
{prefix && (
|
|
533
|
+
<span className={clsx(styles.prefix, labelWeight === 'semibold' && styles.semibold)}>
|
|
534
|
+
{prefix}
|
|
535
|
+
</span>
|
|
536
|
+
)}
|
|
537
|
+
{/* Wrapper keeps the name a single flex item (matters when `label`
|
|
538
|
+
is itself multiple nodes — e.g. a fragment) so the chip's `gap`
|
|
539
|
+
doesn't insert extra space inside the name. No longer scopes
|
|
540
|
+
hover styling (the fake-bold rule was dropped, see #345). */}
|
|
541
|
+
{labelTip ? (
|
|
542
|
+
<Tooltip
|
|
543
|
+
content={labelTipState.content}
|
|
544
|
+
open={labelTipState.open}
|
|
545
|
+
onOpenChange={labelTipState.onOpenChange}
|
|
546
|
+
>
|
|
547
|
+
<span
|
|
548
|
+
ref={labelTipState.ref}
|
|
549
|
+
className={clsx(
|
|
550
|
+
styles.label,
|
|
551
|
+
labelWeight === 'semibold' && styles.semibold,
|
|
552
|
+
labelMaxWidth != null && styles.capped,
|
|
553
|
+
labelEllipsis === 'start' && styles.ellipsisStart,
|
|
554
|
+
)}
|
|
555
|
+
style={labelMaxWidth != null ? { maxWidth: `${labelMaxWidth}ch` } : undefined}
|
|
556
|
+
>
|
|
557
|
+
{/* `ellipsisStart` flips the span to RTL so the overflow (and
|
|
558
|
+
its ellipsis) falls at the start; this isolated LTR run
|
|
559
|
+
keeps the text itself in order — without it, trailing
|
|
560
|
+
neutrals like `/` or `?` would hop to the other end. */}
|
|
561
|
+
{labelEllipsis === 'start' ? <span dir="ltr">{label}</span> : label}
|
|
562
|
+
</span>
|
|
563
|
+
</Tooltip>
|
|
564
|
+
) : (
|
|
565
|
+
<span className={clsx(styles.label, labelWeight === 'semibold' && styles.semibold)}>
|
|
566
|
+
{label}
|
|
567
|
+
</span>
|
|
568
|
+
)}
|
|
569
|
+
{stateWord}
|
|
570
|
+
{status && (
|
|
571
|
+
<>
|
|
572
|
+
{/* Separator dot is its own flex item so the chip's `gap` spaces
|
|
573
|
+
it symmetrically between name and status. A solid circle, not
|
|
574
|
+
a font glyph — exact size, no line-box inflation. Colored via
|
|
575
|
+
--entity-chip-status-fg, set on the chip root above (rootStyle). */}
|
|
576
|
+
<span className={styles.dot} aria-hidden="true" />
|
|
577
|
+
<span className={styles.status}>{status.label}</span>
|
|
578
|
+
</>
|
|
579
|
+
)}
|
|
580
|
+
{trailing != null && <span className={styles.trailing}>{trailing}</span>}
|
|
581
|
+
</>
|
|
582
|
+
)}
|
|
583
|
+
</>
|
|
584
|
+
);
|
|
585
|
+
|
|
586
|
+
return (
|
|
587
|
+
<Component
|
|
588
|
+
ref={ref}
|
|
589
|
+
style={rootStyle(color, status, style)}
|
|
590
|
+
className={clsx(
|
|
591
|
+
styles.chip,
|
|
592
|
+
unavailable && styles.unavailable,
|
|
593
|
+
// Only the one-line (truncate) layout is kept while loading/unavailable
|
|
594
|
+
// drops the segments themselves — nothing about the segments is
|
|
595
|
+
// reserved, but a list row must still not reflow from one line to
|
|
596
|
+
// wrapping, so the single-line class applies whenever segments are
|
|
597
|
+
// configured, even though `segmented` itself stays gated to the
|
|
598
|
+
// normal state (#582 review).
|
|
599
|
+
(truncate || hasSegments) && styles.truncate,
|
|
600
|
+
segmented && styles.segmented,
|
|
601
|
+
className,
|
|
602
|
+
)}
|
|
603
|
+
{...elementProps}
|
|
604
|
+
{...rest}
|
|
605
|
+
// A target-less unavailable chip is non-interactive — cancel any
|
|
606
|
+
// consumer onClick that {...rest} just spread on above, so it can't
|
|
607
|
+
// fire through a chip keyboard users have no way to reach (Pattern B).
|
|
608
|
+
{...(inert ? { onClick: undefined } : null)}
|
|
609
|
+
// Component-owned ARIA state must survive whatever the consumer passes
|
|
610
|
+
// via {...rest} — aria-busy/aria-disabled are the component's contract.
|
|
611
|
+
aria-busy={loading || undefined}
|
|
612
|
+
aria-disabled={inert || undefined}
|
|
613
|
+
// The clipped-label tooltip's focus/blur handlers only when the label can
|
|
614
|
+
// clip; otherwise {...rest} above already passed the consumer's own
|
|
615
|
+
// onFocus/onBlur through untouched. (Behaviourally equivalent to always
|
|
616
|
+
// attaching — labelTipState can't open without a clipped label — but it
|
|
617
|
+
// keeps a non-clipping chip's handlers exactly the consumer's.)
|
|
618
|
+
{...(clippable
|
|
619
|
+
? {
|
|
620
|
+
onFocus: chain(restOnFocus, handleRootFocus),
|
|
621
|
+
onBlur: chain(restOnBlur, handleRootBlur),
|
|
622
|
+
}
|
|
623
|
+
: null)}
|
|
624
|
+
>
|
|
625
|
+
{segmented ? (
|
|
626
|
+
<>
|
|
627
|
+
{/* A space after/before each part keeps the accessible name
|
|
628
|
+
"Bug ENG-15 … Normal Reported" separated in every engine, not
|
|
629
|
+
only where blockified flex items get a separator. Whitespace-only
|
|
630
|
+
text between flex items isn't rendered, so layout is unchanged. */}
|
|
631
|
+
{before?.map((segment, i) => (
|
|
632
|
+
<Fragment key={`b${i}`}>
|
|
633
|
+
<Segment segment={segment} />{' '}
|
|
634
|
+
</Fragment>
|
|
635
|
+
))}
|
|
636
|
+
<span className={styles.core}>{content}</span>
|
|
637
|
+
{after?.map((segment, i) => (
|
|
638
|
+
<Fragment key={`a${i}`}>
|
|
639
|
+
{' '}
|
|
640
|
+
<Segment segment={segment} />
|
|
641
|
+
</Fragment>
|
|
642
|
+
))}
|
|
643
|
+
</>
|
|
644
|
+
) : (
|
|
645
|
+
content
|
|
646
|
+
)}
|
|
647
|
+
</Component>
|
|
648
|
+
);
|
|
649
|
+
}) as EntityChipComponent;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { EntityChip } from './EntityChip';
|
|
2
|
+
export type {
|
|
3
|
+
EntityChipProps,
|
|
4
|
+
EntityChipAs,
|
|
5
|
+
EntityChipStatus,
|
|
6
|
+
EntityChipSegment,
|
|
7
|
+
EntityChipLabelWeight,
|
|
8
|
+
EntityChipLabelEllipsis,
|
|
9
|
+
} from './EntityChip';
|
|
10
|
+
export type { StatusCategory } from '../_internal/statusColor';
|