@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,419 @@
|
|
|
1
|
+
import {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useEffect,
|
|
4
|
+
useLayoutEffect,
|
|
5
|
+
useRef,
|
|
6
|
+
type HTMLAttributes,
|
|
7
|
+
type KeyboardEvent as ReactKeyboardEvent,
|
|
8
|
+
} from 'react';
|
|
9
|
+
import { createPortal } from 'react-dom';
|
|
10
|
+
import {
|
|
11
|
+
autoUpdate,
|
|
12
|
+
flip,
|
|
13
|
+
offset,
|
|
14
|
+
shift,
|
|
15
|
+
size,
|
|
16
|
+
useFloating,
|
|
17
|
+
type Placement,
|
|
18
|
+
} from '@floating-ui/react-dom';
|
|
19
|
+
import clsx from 'clsx';
|
|
20
|
+
import { useDropdownMenuContext } from './context';
|
|
21
|
+
import { isTourHeld, overlayStack } from '../_internal/overlay';
|
|
22
|
+
import { mergeRefs } from '../_internal/refs';
|
|
23
|
+
import styles from './DropdownMenu.module.scss';
|
|
24
|
+
|
|
25
|
+
/** Which side of the trigger the menu prefers. Floating UI auto-flips if it doesn't fit. */
|
|
26
|
+
export type DropdownMenuSide = 'top' | 'bottom' | 'left' | 'right';
|
|
27
|
+
/** Which edge of the menu aligns to the corresponding trigger edge. */
|
|
28
|
+
export type DropdownMenuAlign = 'start' | 'center' | 'end';
|
|
29
|
+
|
|
30
|
+
// Focus an item without scrolling the page, then explicitly scroll it into
|
|
31
|
+
// view WITHIN the panel: `.content` is height-clamped by the size middleware
|
|
32
|
+
// and scrolls (#303), and preventScroll suppresses that scroll too.
|
|
33
|
+
// ONLY for the keydown paths, where the panel is already positioned — at
|
|
34
|
+
// open time the panel still sits at the document origin and scrollIntoView
|
|
35
|
+
// would yank the page (the open effect defers to the isPositioned effect
|
|
36
|
+
// instead). Guarded — jsdom has no scrollIntoView.
|
|
37
|
+
const focusItem = (el: HTMLElement | null | undefined) => {
|
|
38
|
+
el?.focus({ preventScroll: true });
|
|
39
|
+
el?.scrollIntoView?.({ block: 'nearest' });
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Content props.
|
|
44
|
+
*
|
|
45
|
+
* Note: the `style` prop from `HTMLAttributes` is reserved — Floating UI sets
|
|
46
|
+
* inline `position`/`top`/`left` styles to position the menu. A consumer
|
|
47
|
+
* `style` value is silently overridden. Set `minWidth` via the prop, not via
|
|
48
|
+
* `style`. Class-based styling (`className` / SCSS module) is the supported
|
|
49
|
+
* customization surface.
|
|
50
|
+
*/
|
|
51
|
+
export interface DropdownMenuContentProps extends HTMLAttributes<HTMLDivElement> {
|
|
52
|
+
/** Preferred side. Default `'bottom'`. Auto-flips on collision. */
|
|
53
|
+
side?: DropdownMenuSide;
|
|
54
|
+
/** Edge alignment. Default `'start'`. */
|
|
55
|
+
align?: DropdownMenuAlign;
|
|
56
|
+
/** Gap in px between trigger and menu. Default `4`. */
|
|
57
|
+
sideOffset?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Preferred minimum width in px or any CSS length. Defaults to the trigger's
|
|
60
|
+
* width and is reduced when necessary to keep the menu within the viewport.
|
|
61
|
+
*/
|
|
62
|
+
minWidth?: number | string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The floating menu panel, rendered only while the menu is open.
|
|
67
|
+
* @see docs/components/DropdownMenu.md
|
|
68
|
+
*/
|
|
69
|
+
// Owns keyboard handling (Escape, Tab, arrows, Home/End, Enter/Space, typeahead) and outside-click dismissal.
|
|
70
|
+
export const Content = forwardRef<HTMLDivElement, DropdownMenuContentProps>(function Content(
|
|
71
|
+
{ side = 'bottom', align = 'start', sideOffset = 4, minWidth, className, children, ...rest },
|
|
72
|
+
forwardedRef,
|
|
73
|
+
) {
|
|
74
|
+
const ctx = useDropdownMenuContext('Content');
|
|
75
|
+
const inOverlay = ctx.inOverlay;
|
|
76
|
+
|
|
77
|
+
const placement: Placement = (align === 'center' ? side : `${side}-${align}`) as Placement;
|
|
78
|
+
|
|
79
|
+
const {
|
|
80
|
+
refs,
|
|
81
|
+
floatingStyles,
|
|
82
|
+
isPositioned,
|
|
83
|
+
placement: resolvedPlacement,
|
|
84
|
+
} = useFloating({
|
|
85
|
+
open: ctx.open,
|
|
86
|
+
placement,
|
|
87
|
+
transform: false,
|
|
88
|
+
middleware: [
|
|
89
|
+
offset(sideOffset),
|
|
90
|
+
flip(),
|
|
91
|
+
shift({ padding: 8 }),
|
|
92
|
+
size({
|
|
93
|
+
apply({ availableHeight, availableWidth, rects, elements }) {
|
|
94
|
+
const viewportWidth = Math.max(0, availableWidth);
|
|
95
|
+
const requestedMinWidth =
|
|
96
|
+
typeof minWidth === 'number'
|
|
97
|
+
? `${minWidth}px`
|
|
98
|
+
: ((minWidth as string | undefined) ?? `${rects.reference.width}px`);
|
|
99
|
+
Object.assign(elements.floating.style, {
|
|
100
|
+
maxHeight: `${availableHeight}px`,
|
|
101
|
+
maxWidth: `${viewportWidth}px`,
|
|
102
|
+
minWidth: `min(${requestedMinWidth}, ${viewportWidth}px)`,
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
padding: 8,
|
|
106
|
+
}),
|
|
107
|
+
],
|
|
108
|
+
whileElementsMounted: autoUpdate,
|
|
109
|
+
elements: { reference: ctx.triggerRef.current },
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const [resolvedSide, resolvedAlign = 'center'] = resolvedPlacement.split('-') as [
|
|
113
|
+
DropdownMenuSide,
|
|
114
|
+
DropdownMenuAlign | undefined,
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
const setFloatingRef = mergeRefs<HTMLDivElement>(refs.setFloating, forwardedRef);
|
|
118
|
+
|
|
119
|
+
const typeaheadRef = useRef<{ buffer: string; timer: ReturnType<typeof setTimeout> | null }>({
|
|
120
|
+
buffer: '',
|
|
121
|
+
timer: null,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
const typeahead = typeaheadRef.current;
|
|
126
|
+
return () => {
|
|
127
|
+
if (typeahead.timer) clearTimeout(typeahead.timer);
|
|
128
|
+
};
|
|
129
|
+
}, []);
|
|
130
|
+
|
|
131
|
+
// Outside-click: pointerdown on document, target is neither inside this
|
|
132
|
+
// Content nor inside the Trigger, AND not inside any other open submenu
|
|
133
|
+
// panel (recognised by [data-dropdown-menu-content]) OR any open popover
|
|
134
|
+
// panel (recognised by [data-popover-content]). Excluding the trigger
|
|
135
|
+
// prevents fighting the trigger's own toggle handler. Excluding popovers
|
|
136
|
+
// lets a Popover opened from inside a menu item handle its own clicks
|
|
137
|
+
// (Cancel/Confirm buttons, form controls) without collapsing the menu.
|
|
138
|
+
useEffect(() => {
|
|
139
|
+
if (!ctx.open) return;
|
|
140
|
+
const onPointerDown = (e: globalThis.PointerEvent) => {
|
|
141
|
+
const target = e.target as Node | null;
|
|
142
|
+
if (!target) return;
|
|
143
|
+
const content = refs.floating.current;
|
|
144
|
+
const trigger = ctx.triggerRef.current;
|
|
145
|
+
if (content && content.contains(target)) return;
|
|
146
|
+
if (trigger && trigger.contains(target)) return;
|
|
147
|
+
// #684: a tour pointing into this menu — its Next/card/blocker press
|
|
148
|
+
// must not dismiss the surface the next step is about to feature.
|
|
149
|
+
if (isTourHeld(target, content, trigger)) return;
|
|
150
|
+
// If the click is inside a deeper submenu panel or any popover panel,
|
|
151
|
+
// let that surface handle it.
|
|
152
|
+
const allPanels = document.querySelectorAll(
|
|
153
|
+
'[data-dropdown-menu-content], [data-popover-content]',
|
|
154
|
+
);
|
|
155
|
+
for (const panel of allPanels) {
|
|
156
|
+
if (panel !== content && panel.contains(target)) return;
|
|
157
|
+
}
|
|
158
|
+
ctx.setOpen(false);
|
|
159
|
+
};
|
|
160
|
+
document.addEventListener('pointerdown', onPointerDown, true);
|
|
161
|
+
return () => document.removeEventListener('pointerdown', onPointerDown, true);
|
|
162
|
+
}, [ctx, refs]);
|
|
163
|
+
|
|
164
|
+
// Escape: close from anywhere (focus may be on the trigger or inside the menu).
|
|
165
|
+
// Tab: close and return focus to trigger when focus is inside the menu.
|
|
166
|
+
// These use document-level listeners so they fire regardless of which element
|
|
167
|
+
// currently holds focus.
|
|
168
|
+
// For subs (depth > 0): stop propagation after handling Escape so the
|
|
169
|
+
// parent Content's listener does not also close the parent.
|
|
170
|
+
useEffect(() => {
|
|
171
|
+
if (!ctx.open) return;
|
|
172
|
+
const onKeyDown = (e: globalThis.KeyboardEvent) => {
|
|
173
|
+
if (e.key === 'Escape') {
|
|
174
|
+
// #280: defer the WHOLE menu to a DEEPER non-menu floating surface —
|
|
175
|
+
// e.g. a ConfirmationPopover/Select opened from a menu item, which
|
|
176
|
+
// registers after the menu and is thus innermost. Its own listener
|
|
177
|
+
// closes it on this press; the menu stays open. (isTopFloating is keyed
|
|
178
|
+
// on the root's floating id, shared by every Content panel via context.)
|
|
179
|
+
if (!overlayStack.isTopFloating(ctx.floatingId)) return;
|
|
180
|
+
e.preventDefault();
|
|
181
|
+
overlayStack.consumeEscape(e); // hosts yield even if we ran first (#274)
|
|
182
|
+
// Defer to any DEEPER open dropdown panel: only the single innermost
|
|
183
|
+
// panel (no deeper panel in the DOM) closes, so one Escape peels exactly
|
|
184
|
+
// one level. This is purely DOM-based — it does NOT rely on listener
|
|
185
|
+
// registration order (the keydown effect re-registers every render, so
|
|
186
|
+
// that order isn't guaranteed). Applies at EVERY depth (#279): a depth-1
|
|
187
|
+
// sub must defer to a depth-2 sub, not only depth-0 to depth-1.
|
|
188
|
+
const deeperPanels = document.querySelectorAll(
|
|
189
|
+
`[data-dropdown-menu-content][data-dropdown-depth]`,
|
|
190
|
+
);
|
|
191
|
+
for (const panel of deeperPanels) {
|
|
192
|
+
const depth = Number(panel.getAttribute('data-dropdown-depth') ?? '0');
|
|
193
|
+
if (depth > ctx.depth) return;
|
|
194
|
+
}
|
|
195
|
+
if (ctx.depth > 0) {
|
|
196
|
+
// Stop propagation so no later document listener double-handles this
|
|
197
|
+
// press. Shallower ancestor listeners already fired and deferred.
|
|
198
|
+
e.stopImmediatePropagation();
|
|
199
|
+
}
|
|
200
|
+
ctx.setOpen(false);
|
|
201
|
+
ctx.triggerRef.current?.focus({ preventScroll: true });
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (e.key === 'Tab') {
|
|
205
|
+
const content = refs.floating.current;
|
|
206
|
+
const activeEl = document.activeElement as Node | null;
|
|
207
|
+
// Only intercept Tab when focus is inside the menu.
|
|
208
|
+
// Do NOT preventDefault — browser continues Tab traversal from the
|
|
209
|
+
// (now-focused) trigger to the next focusable element (WAI-ARIA menu pattern).
|
|
210
|
+
if (content && activeEl && content.contains(activeEl)) {
|
|
211
|
+
ctx.setOpen(false);
|
|
212
|
+
ctx.triggerRef.current?.focus({ preventScroll: true });
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
document.addEventListener('keydown', onKeyDown, true);
|
|
217
|
+
return () => document.removeEventListener('keydown', onKeyDown, true);
|
|
218
|
+
}, [ctx, refs]);
|
|
219
|
+
|
|
220
|
+
// When the menu opens, set activeIndex from openIntent and focus the active item.
|
|
221
|
+
// useLayoutEffect (not useEffect) so this runs after Items' layout effects
|
|
222
|
+
// have populated itemsRef.current (layout effects fire bottom-up: children first).
|
|
223
|
+
useLayoutEffect(() => {
|
|
224
|
+
if (!ctx.open) return;
|
|
225
|
+
|
|
226
|
+
if (ctx.openIntent === null) {
|
|
227
|
+
// Mouse-opened: don't pre-highlight any item. Focus the menu container
|
|
228
|
+
// itself so subsequent Arrow keys still route through handleKeyDown,
|
|
229
|
+
// and so Escape works from inside the menu.
|
|
230
|
+
ctx.setActiveIndex(-1);
|
|
231
|
+
// preventScroll: the portaled menu starts at the document origin until
|
|
232
|
+
// Floating UI's autoUpdate computes the real coords. Focusing it without
|
|
233
|
+
// preventScroll yanks the page to the top.
|
|
234
|
+
queueMicrotask(() => refs.floating.current?.focus({ preventScroll: true }));
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Keyboard-opened: focus first/last enabled item per intent.
|
|
239
|
+
const enabled = ctx.itemsRef.current.filter((x) => !x.disabled);
|
|
240
|
+
if (enabled.length === 0) return;
|
|
241
|
+
const target = ctx.openIntent === 'last' ? enabled[enabled.length - 1] : enabled[0];
|
|
242
|
+
const idx = ctx.itemsRef.current.findIndex((x) => x.id === target.id);
|
|
243
|
+
ctx.setActiveIndex(idx);
|
|
244
|
+
queueMicrotask(() => target.ref.current?.focus({ preventScroll: true }));
|
|
245
|
+
ctx.setOpenIntent(null);
|
|
246
|
+
// Depend only on ctx.open so this fires exactly when the menu transitions
|
|
247
|
+
// to open. openIntent is read but not re-fired on its own.
|
|
248
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
249
|
+
}, [ctx.open]);
|
|
250
|
+
|
|
251
|
+
// #303 (open path): once Floating UI has positioned the panel — and the
|
|
252
|
+
// size middleware has clamped its maxHeight — bring the active item into
|
|
253
|
+
// view. The open-intent focus above runs BEFORE positioning, while the
|
|
254
|
+
// portaled panel still sits at the document origin: scrollIntoView there
|
|
255
|
+
// would scroll the WINDOW to the top of the document, and the not-yet-
|
|
256
|
+
// clamped panel has nothing to scroll anyway (ArrowUp-open focuses the
|
|
257
|
+
// last item, which sits below the fold once the clamp lands). isPositioned
|
|
258
|
+
// resets to false on close, so this fires once per open.
|
|
259
|
+
useEffect(() => {
|
|
260
|
+
if (!ctx.open || !isPositioned) return;
|
|
261
|
+
if (ctx.activeIndex < 0) return;
|
|
262
|
+
const active = ctx.itemsRef.current[ctx.activeIndex];
|
|
263
|
+
active?.ref.current?.scrollIntoView?.({ block: 'nearest' });
|
|
264
|
+
// Mid-open activeIndex changes are scrolled by focusItem in the keydown
|
|
265
|
+
// path; this effect only covers the positioning transition.
|
|
266
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
267
|
+
}, [ctx.open, isPositioned]);
|
|
268
|
+
|
|
269
|
+
const handleKeyDown = (e: ReactKeyboardEvent<HTMLDivElement>) => {
|
|
270
|
+
// #528: React bubbles events through the REACT tree, so a surface opened
|
|
271
|
+
// from a menu item — ConfirmationPopover, Popover, Select, and every
|
|
272
|
+
// SubContent — delivers its key presses here even though its DOM is
|
|
273
|
+
// portaled outside this panel. Handling them stole the whole menu's
|
|
274
|
+
// keyboard: Tab closed the menu (unmounting the popover with it), Escape
|
|
275
|
+
// closed both instead of peeling one level, and Enter/Space were
|
|
276
|
+
// preventDefault-ed before the popover's own button could activate.
|
|
277
|
+
// Only keys that really happened inside this panel are ours; the deeper
|
|
278
|
+
// surface owns the rest (and its own Content, at depth+1, owns its keys).
|
|
279
|
+
if (!e.currentTarget.contains(e.target as Node)) return;
|
|
280
|
+
|
|
281
|
+
if (e.key === 'Escape') {
|
|
282
|
+
e.preventDefault();
|
|
283
|
+
ctx.setOpen(false);
|
|
284
|
+
ctx.triggerRef.current?.focus({ preventScroll: true });
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
if (e.key === 'Tab') {
|
|
288
|
+
// Close, focus trigger, do NOT preventDefault — browser continues Tab
|
|
289
|
+
// traversal from the (now-focused) trigger to the next focusable element
|
|
290
|
+
// (the WAI-ARIA menu pattern).
|
|
291
|
+
ctx.setOpen(false);
|
|
292
|
+
ctx.triggerRef.current?.focus({ preventScroll: true });
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (e.key === 'ArrowLeft' && ctx.depth > 0) {
|
|
297
|
+
e.preventDefault();
|
|
298
|
+
ctx.setOpen(false);
|
|
299
|
+
ctx.triggerRef.current?.focus({ preventScroll: true });
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (e.key === 'ArrowRight') {
|
|
304
|
+
const items = ctx.itemsRef.current;
|
|
305
|
+
if (ctx.activeIndex >= 0 && ctx.activeIndex < items.length) {
|
|
306
|
+
const target = items[ctx.activeIndex];
|
|
307
|
+
if (target.openSubmenu) {
|
|
308
|
+
e.preventDefault();
|
|
309
|
+
target.openSubmenu();
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
316
|
+
e.preventDefault();
|
|
317
|
+
const items = ctx.itemsRef.current;
|
|
318
|
+
if (ctx.activeIndex >= 0 && ctx.activeIndex < items.length) {
|
|
319
|
+
const target = items[ctx.activeIndex];
|
|
320
|
+
if (!target.disabled) {
|
|
321
|
+
if (target.openSubmenu) {
|
|
322
|
+
target.openSubmenu();
|
|
323
|
+
} else {
|
|
324
|
+
target.ref.current?.click();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const items = ctx.itemsRef.current;
|
|
332
|
+
const enabledIndices = items.map((it, i) => (it.disabled ? -1 : i)).filter((i) => i !== -1);
|
|
333
|
+
if (enabledIndices.length === 0) return;
|
|
334
|
+
|
|
335
|
+
const currentPos = enabledIndices.indexOf(ctx.activeIndex);
|
|
336
|
+
|
|
337
|
+
const focusAt = (registryIndex: number) => {
|
|
338
|
+
ctx.setActiveIndex(registryIndex);
|
|
339
|
+
queueMicrotask(() => focusItem(items[registryIndex].ref.current));
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
switch (e.key) {
|
|
343
|
+
case 'ArrowDown': {
|
|
344
|
+
e.preventDefault();
|
|
345
|
+
const nextPos = currentPos === -1 ? 0 : (currentPos + 1) % enabledIndices.length;
|
|
346
|
+
focusAt(enabledIndices[nextPos]);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
case 'ArrowUp': {
|
|
350
|
+
e.preventDefault();
|
|
351
|
+
const prevPos =
|
|
352
|
+
currentPos === -1
|
|
353
|
+
? enabledIndices.length - 1
|
|
354
|
+
: (currentPos - 1 + enabledIndices.length) % enabledIndices.length;
|
|
355
|
+
focusAt(enabledIndices[prevPos]);
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
case 'Home': {
|
|
359
|
+
e.preventDefault();
|
|
360
|
+
focusAt(enabledIndices[0]);
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
case 'End': {
|
|
364
|
+
e.preventDefault();
|
|
365
|
+
focusAt(enabledIndices[enabledIndices.length - 1]);
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Typeahead: printable characters (length 1) with no modifier keys append
|
|
371
|
+
// to a debounced buffer and jump to the first non-disabled matching item.
|
|
372
|
+
// This block comes AFTER Enter/Space and Arrow/Home/End so those keys are
|
|
373
|
+
// not accidentally consumed here (' ' is length 1 but is caught above).
|
|
374
|
+
if (e.key.length === 1 && !e.altKey && !e.ctrlKey && !e.metaKey) {
|
|
375
|
+
const ta = typeaheadRef.current;
|
|
376
|
+
ta.buffer += e.key.toLowerCase();
|
|
377
|
+
if (ta.timer) clearTimeout(ta.timer);
|
|
378
|
+
ta.timer = setTimeout(() => {
|
|
379
|
+
ta.buffer = '';
|
|
380
|
+
ta.timer = null;
|
|
381
|
+
}, 500);
|
|
382
|
+
|
|
383
|
+
const match = items.findIndex(
|
|
384
|
+
(it) => !it.disabled && it.label.toLowerCase().startsWith(ta.buffer),
|
|
385
|
+
);
|
|
386
|
+
if (match !== -1) {
|
|
387
|
+
e.preventDefault();
|
|
388
|
+
focusAt(match);
|
|
389
|
+
}
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
if (!ctx.open) return null;
|
|
395
|
+
|
|
396
|
+
return createPortal(
|
|
397
|
+
// {...rest} first so consumer-supplied props don't override the menu
|
|
398
|
+
// ARIA contract or our event wiring.
|
|
399
|
+
<div
|
|
400
|
+
{...rest}
|
|
401
|
+
ref={setFloatingRef}
|
|
402
|
+
id={ctx.contentId}
|
|
403
|
+
role="menu"
|
|
404
|
+
tabIndex={-1}
|
|
405
|
+
aria-orientation="vertical"
|
|
406
|
+
data-side={resolvedSide}
|
|
407
|
+
data-align={resolvedAlign}
|
|
408
|
+
data-dropdown-menu-content=""
|
|
409
|
+
data-dropdown-depth={ctx.depth}
|
|
410
|
+
data-in-overlay={inOverlay ? '' : undefined}
|
|
411
|
+
style={floatingStyles}
|
|
412
|
+
className={clsx(styles.content, className)}
|
|
413
|
+
onKeyDown={handleKeyDown}
|
|
414
|
+
>
|
|
415
|
+
{children}
|
|
416
|
+
</div>,
|
|
417
|
+
document.body,
|
|
418
|
+
);
|
|
419
|
+
});
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
@use '../../styles/mixins' as *;
|
|
2
|
+
@use './DropdownMenu.tokens';
|
|
3
|
+
|
|
4
|
+
// `.content` carries both the visual chrome and the open-only entrance
|
|
5
|
+
// animation. The animation half (transition + @starting-style + per-side
|
|
6
|
+
// transform-origin rules below) relies on Floating UI being in `transform:
|
|
7
|
+
// false` mode (see Content.tsx) so the CSS `transform` property is free for
|
|
8
|
+
// the scale/translate entrance without clobbering placement.
|
|
9
|
+
.content {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
gap: var(--dropdown-menu-gap);
|
|
13
|
+
min-width: var(--dropdown-menu-min-width);
|
|
14
|
+
|
|
15
|
+
// #303: Floating UI's size middleware inline-clamps maxHeight to the
|
|
16
|
+
// available viewport space; without these the clamped panel clips its
|
|
17
|
+
// items with no way to reach them.
|
|
18
|
+
overflow-y: auto;
|
|
19
|
+
overflow-x: hidden;
|
|
20
|
+
|
|
21
|
+
// Don't chain wheel/touch scrolling past the panel's edge to the page —
|
|
22
|
+
// the menu stays open while the page shifts underneath otherwise.
|
|
23
|
+
overscroll-behavior: contain;
|
|
24
|
+
padding: var(--dropdown-menu-padding);
|
|
25
|
+
background: var(--dropdown-menu-bg);
|
|
26
|
+
border: var(--border-width) solid var(--dropdown-menu-border-color);
|
|
27
|
+
border-radius: var(--dropdown-menu-radius);
|
|
28
|
+
box-shadow: var(--dropdown-menu-shadow);
|
|
29
|
+
z-index: var(--dropdown-menu-z);
|
|
30
|
+
outline: none;
|
|
31
|
+
|
|
32
|
+
// Explicit so each per-side @starting-style transform has a defined
|
|
33
|
+
// resting target to interpolate to. `none` is the CSS default; declaring
|
|
34
|
+
// it here prevents a future cleanup PR from removing the "redundant" line.
|
|
35
|
+
transform: none;
|
|
36
|
+
transition:
|
|
37
|
+
opacity var(--dropdown-menu-transition),
|
|
38
|
+
transform var(--dropdown-menu-transition);
|
|
39
|
+
|
|
40
|
+
// Open-only entrance — Content unmounts on close so there is no exit.
|
|
41
|
+
// @starting-style only applies while a transition is active; the
|
|
42
|
+
// prefers-reduced-motion override below disables the transition, which
|
|
43
|
+
// neutralises @starting-style (panel renders directly at its rest style).
|
|
44
|
+
@starting-style {
|
|
45
|
+
opacity: var(--opacity-hidden);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.content[data-in-overlay] {
|
|
50
|
+
z-index: var(--z-overlay-floating);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// #685: the tour's current target is INSIDE this surface — drop just under the
|
|
54
|
+
// scrim (--z-tour) so only the target is lit, not the whole panel.
|
|
55
|
+
.content[data-in-overlay]:has([data-tour-current-target]) {
|
|
56
|
+
z-index: calc(var(--z-tour) - 1);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.item {
|
|
60
|
+
display: flex;
|
|
61
|
+
align-items: center;
|
|
62
|
+
gap: var(--dropdown-menu-item-gap);
|
|
63
|
+
padding: var(--dropdown-menu-item-padding-y) var(--dropdown-menu-item-padding-x);
|
|
64
|
+
border-radius: var(--dropdown-menu-item-radius);
|
|
65
|
+
font-size: var(--dropdown-menu-item-font-size);
|
|
66
|
+
line-height: var(--dropdown-menu-item-line-height);
|
|
67
|
+
color: var(--dropdown-menu-item-fg);
|
|
68
|
+
cursor: pointer;
|
|
69
|
+
user-select: none;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.item:hover:not([aria-disabled='true']),
|
|
73
|
+
.item:focus-visible:not([aria-disabled='true']) {
|
|
74
|
+
background: var(--dropdown-menu-item-bg-hover);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Same defect as FileUpload/Slider (#513): the rule above shared its
|
|
78
|
+
// background between :hover and :focus-visible, and the base rule's
|
|
79
|
+
// `outline: none` (removed) suppressed the ring entirely.
|
|
80
|
+
// INSET, but not because an outset ring would clip at rest: --dropdown-menu-
|
|
81
|
+
// padding is 4px and an outset ring extends offset 2px + width 2px = 4px, so
|
|
82
|
+
// at rest it fits exactly inside `.content`'s clip edge (overflow-y: auto;
|
|
83
|
+
// overflow-x: hidden), first and last item included. The real reason is
|
|
84
|
+
// --dropdown-menu-gap defaults to 0 — items are flush, so an OUTSET ring would
|
|
85
|
+
// paint over the item above and below. PillMenu sets a gap; inset is kept
|
|
86
|
+
// there too for one consistent ring and the checked-accent note below. A
|
|
87
|
+
// *scrolled* menu still clips whichever item straddles the scrollport edge,
|
|
88
|
+
// same as any inset call site.
|
|
89
|
+
// What the inset ring covers: a checked item's left accent bar below
|
|
90
|
+
// (box-shadow: inset ...-accent-width-checked, = --border-width-emphasis =
|
|
91
|
+
// 2px) sits in exactly the same outermost 2px the ring occupies, and outline
|
|
92
|
+
// paints above box-shadow — so a focused checked item loses its accent bar
|
|
93
|
+
// completely. Acceptable: the checked background tint and `aria-checked`
|
|
94
|
+
// both survive, so the state is still legible without it.
|
|
95
|
+
.item:focus-visible:not([aria-disabled='true']) {
|
|
96
|
+
@include focus-ring($offset: calc(-1 * var(--ring-offset)));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.item[data-tone='danger'] {
|
|
100
|
+
color: var(--dropdown-menu-item-fg-danger);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.item[data-tone='danger']:hover:not([aria-disabled='true']),
|
|
104
|
+
.item[data-tone='danger']:focus-visible:not([aria-disabled='true']) {
|
|
105
|
+
background: var(--dropdown-menu-item-bg-danger-hover);
|
|
106
|
+
color: var(--dropdown-menu-item-fg-danger);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.item[aria-disabled='true'] {
|
|
110
|
+
color: var(--dropdown-menu-item-fg-disabled);
|
|
111
|
+
cursor: not-allowed;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Checked state for CheckboxItem / RadioItem: accent-tinted row with a 2px left
|
|
115
|
+
// accent. Replaces the default ✓/● glyphs from earlier versions of the API.
|
|
116
|
+
// Left corners square off so the 2px accent sits flush against a straight edge.
|
|
117
|
+
.item[aria-checked='true'] {
|
|
118
|
+
background: var(--dropdown-menu-item-bg-checked);
|
|
119
|
+
color: var(--dropdown-menu-item-fg-checked);
|
|
120
|
+
box-shadow: inset var(--dropdown-menu-item-accent-width-checked) 0 0
|
|
121
|
+
var(--dropdown-menu-item-accent-checked);
|
|
122
|
+
border-top-left-radius: 0;
|
|
123
|
+
border-bottom-left-radius: 0;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Hover/focus on a checked item keeps the accent tint instead of falling through
|
|
127
|
+
// to the neutral bg-muted hover. The left accent remains visible.
|
|
128
|
+
// NOTE: `tone="danger"` is not a valid prop on CheckboxItem or RadioItem
|
|
129
|
+
// today. If ever added, re-examine this rule's source-order relationship
|
|
130
|
+
// with `.item[data-tone='danger']:hover` — equal specificity means later
|
|
131
|
+
// rule wins, and this rule would silently suppress the danger color.
|
|
132
|
+
.item[aria-checked='true']:hover:not([aria-disabled='true']),
|
|
133
|
+
.item[aria-checked='true']:focus-visible:not([aria-disabled='true']) {
|
|
134
|
+
background: var(--dropdown-menu-item-bg-checked);
|
|
135
|
+
color: var(--dropdown-menu-item-fg-checked);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Disabled + checked: keep the visual cue but use disabled foreground so the
|
|
139
|
+
// user can still see what was selected, just not interact with it.
|
|
140
|
+
.item[aria-checked='true'][aria-disabled='true'] {
|
|
141
|
+
color: var(--dropdown-menu-item-fg-disabled);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.icon {
|
|
145
|
+
display: inline-flex;
|
|
146
|
+
align-items: center;
|
|
147
|
+
justify-content: center;
|
|
148
|
+
width: var(--dropdown-menu-icon-size);
|
|
149
|
+
height: var(--dropdown-menu-icon-size);
|
|
150
|
+
flex-shrink: 0;
|
|
151
|
+
color: var(--dropdown-menu-icon-fg);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.itemLabel {
|
|
155
|
+
flex: 1 1 auto;
|
|
156
|
+
overflow-wrap: anywhere;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Trailing secondary content about the item itself (region code, count,
|
|
160
|
+
// Badge). Sits between the label and `.shortcut` so a keyboard hint, when
|
|
161
|
+
// both are present, stays rightmost. `flex-shrink: 0` keeps a short
|
|
162
|
+
// qualifier intact — the label (`flex: 1 1 auto`) absorbs the squeeze.
|
|
163
|
+
.meta {
|
|
164
|
+
display: inline-flex;
|
|
165
|
+
align-items: center;
|
|
166
|
+
flex-shrink: 0;
|
|
167
|
+
color: var(--dropdown-menu-meta-fg);
|
|
168
|
+
font-size: var(--dropdown-menu-meta-font-size);
|
|
169
|
+
padding-left: var(--dropdown-menu-meta-padding-left);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.shortcut {
|
|
173
|
+
color: var(--dropdown-menu-shortcut-fg);
|
|
174
|
+
font-size: var(--dropdown-menu-shortcut-font-size);
|
|
175
|
+
padding-left: var(--dropdown-menu-shortcut-padding-left);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.separator {
|
|
179
|
+
display: flex;
|
|
180
|
+
align-items: center;
|
|
181
|
+
height: var(--dropdown-menu-separator-height);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.separator::before {
|
|
185
|
+
content: '';
|
|
186
|
+
display: block;
|
|
187
|
+
width: 100%;
|
|
188
|
+
height: var(--border-width);
|
|
189
|
+
background: var(--dropdown-menu-separator-color);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.group {
|
|
193
|
+
display: flex;
|
|
194
|
+
flex-direction: column;
|
|
195
|
+
padding-block: var(--dropdown-menu-group-padding-block);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Section label: uppercase muted text identifying a group of items.
|
|
199
|
+
.label {
|
|
200
|
+
padding: var(--dropdown-menu-label-padding-y) var(--dropdown-menu-label-padding-x);
|
|
201
|
+
font-size: var(--dropdown-menu-label-font-size);
|
|
202
|
+
font-weight: var(--dropdown-menu-label-font-weight);
|
|
203
|
+
letter-spacing: var(--dropdown-menu-label-letter-spacing);
|
|
204
|
+
text-transform: uppercase;
|
|
205
|
+
color: var(--dropdown-menu-label-fg);
|
|
206
|
+
user-select: none;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Optional indicator slot rendered when a custom <ItemIndicator> is provided
|
|
210
|
+
// as a direct child of CheckboxItem/RadioItem. The default checked state has
|
|
211
|
+
// no glyph (the row's tinted background + left accent IS the indicator).
|
|
212
|
+
.indicatorSlot {
|
|
213
|
+
display: inline-flex;
|
|
214
|
+
align-items: center;
|
|
215
|
+
justify-content: center;
|
|
216
|
+
width: var(--dropdown-menu-indicator-size);
|
|
217
|
+
height: var(--dropdown-menu-indicator-size);
|
|
218
|
+
flex-shrink: 0;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.subTrigger {
|
|
222
|
+
// .subTrigger inherits all .item styles via the className composition.
|
|
223
|
+
// This class exists so we can target data-state in the rule below.
|
|
224
|
+
display: flex;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.subTriggerChevron {
|
|
228
|
+
display: inline-flex;
|
|
229
|
+
align-items: center;
|
|
230
|
+
font-size: var(--dropdown-menu-sub-chevron-font-size);
|
|
231
|
+
line-height: var(--dropdown-menu-sub-chevron-line-height);
|
|
232
|
+
color: var(--dropdown-menu-sub-chevron-fg);
|
|
233
|
+
padding-left: var(--dropdown-menu-sub-chevron-padding-left);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.subTrigger[data-state='open'] {
|
|
237
|
+
background: var(--dropdown-menu-sub-trigger-bg-open);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// --- Open-only entrance: per-side origin + starting-transform -------------
|
|
241
|
+
// Each data-side variant sets transform-origin so the panel appears to grow
|
|
242
|
+
// toward the trigger, and a 4px directional translate in @starting-style for
|
|
243
|
+
// a subtle slide cue layered on top of the scale-fade declared on .content.
|
|
244
|
+
.content[data-side='bottom'] {
|
|
245
|
+
transform-origin: top center;
|
|
246
|
+
|
|
247
|
+
@starting-style {
|
|
248
|
+
transform: scale(0.96) translateY(-4px);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.content[data-side='top'] {
|
|
253
|
+
transform-origin: bottom center;
|
|
254
|
+
|
|
255
|
+
@starting-style {
|
|
256
|
+
transform: scale(0.96) translateY(4px);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.content[data-side='right'] {
|
|
261
|
+
transform-origin: left center;
|
|
262
|
+
|
|
263
|
+
@starting-style {
|
|
264
|
+
transform: scale(0.96) translateX(-4px);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.content[data-side='left'] {
|
|
269
|
+
transform-origin: right center;
|
|
270
|
+
|
|
271
|
+
@starting-style {
|
|
272
|
+
transform: scale(0.96) translateX(4px);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
@media (prefers-reduced-motion: reduce) {
|
|
277
|
+
.content {
|
|
278
|
+
transition: none;
|
|
279
|
+
}
|
|
280
|
+
}
|