@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,87 @@
|
|
|
1
|
+
import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { useTranslation } from '../../i18n';
|
|
4
|
+
import { TopBarStart } from './TopBarStart';
|
|
5
|
+
import { TopBarEnd } from './TopBarEnd';
|
|
6
|
+
import { TopBarSearch } from './TopBarSearch';
|
|
7
|
+
import { TopBarIconButton } from './TopBarIconButton';
|
|
8
|
+
import styles from './TopBar.module.scss';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Element type the root renders as. `'header'` (default) is the right choice
|
|
12
|
+
* for the application's primary top bar — it carries the implicit `banner`
|
|
13
|
+
* landmark when placed as a direct child of `<body>`. Use `'div'` for the
|
|
14
|
+
* rare case of a nested toolbar inside a main content area where another
|
|
15
|
+
* `<header>` element would be semantically wrong.
|
|
16
|
+
*/
|
|
17
|
+
export type TopBarElement = 'header' | 'div';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Props for `<TopBar>` — the application top-bar primitive.
|
|
21
|
+
*
|
|
22
|
+
* Composes via `<TopBar.Start>` + `<TopBar.End>` for the two horizontal
|
|
23
|
+
* clusters, plus `<TopBar.Search>` and `<TopBar.IconButton>` for the most
|
|
24
|
+
* common children. Any other children are accepted — the root is just a
|
|
25
|
+
* flex row that owns its own height, padding, sticky positioning, and
|
|
26
|
+
* bottom border.
|
|
27
|
+
*/
|
|
28
|
+
export interface TopBarProps extends Omit<HTMLAttributes<HTMLElement>, 'aria-label'> {
|
|
29
|
+
/**
|
|
30
|
+
* Element to render. Defaults to `'header'`. Pick `'div'` when the bar is
|
|
31
|
+
* nested inside another content area where a second `<header>` landmark
|
|
32
|
+
* would conflict with page semantics.
|
|
33
|
+
*/
|
|
34
|
+
as?: TopBarElement;
|
|
35
|
+
/**
|
|
36
|
+
* Accessible label for the bar's landmark. Defaults to `t('topBar.label')`
|
|
37
|
+
* when omitted OR empty — an empty string is not an explicit name — so screen
|
|
38
|
+
* readers always announce a name for the region. Override when a page has
|
|
39
|
+
* multiple bars to disambiguate them.
|
|
40
|
+
*/
|
|
41
|
+
'aria-label'?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Children of the bar — typically `<TopBar.Start>` + `<TopBar.End>`. The
|
|
44
|
+
* children area is open so consumers can render a single cluster, a
|
|
45
|
+
* single trailing element, or any other arrangement they need.
|
|
46
|
+
*/
|
|
47
|
+
children?: ReactNode;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Sticky application top-bar primitive; a layout-owning compound (`TopBar.Start`, `.End`, `.Search`, `.IconButton`).
|
|
52
|
+
* @see docs/components/TopBar.md
|
|
53
|
+
*/
|
|
54
|
+
const TopBarRoot = forwardRef<HTMLElement, TopBarProps>(function TopBar(
|
|
55
|
+
{ as = 'header', 'aria-label': ariaLabel, className, children, ...props },
|
|
56
|
+
ref,
|
|
57
|
+
) {
|
|
58
|
+
const t = useTranslation();
|
|
59
|
+
// The `as` union is narrow (`'header' | 'div'`), so a single cast is
|
|
60
|
+
// enough — both elements accept the same HTMLAttributes<HTMLElement>
|
|
61
|
+
// surface used by the props interface. The forwarded ref is typed to
|
|
62
|
+
// HTMLElement (the common supertype) so the same ref works for either
|
|
63
|
+
// rendered element without leaking a generic into the public type.
|
|
64
|
+
const Comp = as as 'header';
|
|
65
|
+
return (
|
|
66
|
+
<Comp
|
|
67
|
+
ref={ref as never}
|
|
68
|
+
aria-label={ariaLabel || t('topBar.label')}
|
|
69
|
+
className={clsx(styles.topBar, className)}
|
|
70
|
+
// {...props} last so consumer overrides win (Pattern A).
|
|
71
|
+
{...props}
|
|
72
|
+
>
|
|
73
|
+
{children}
|
|
74
|
+
</Comp>
|
|
75
|
+
);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Compound `<TopBar>`; subcomponents are attached via `Object.assign`.
|
|
80
|
+
* @see docs/components/TopBar.md
|
|
81
|
+
*/
|
|
82
|
+
export const TopBar = Object.assign(TopBarRoot, {
|
|
83
|
+
Start: TopBarStart,
|
|
84
|
+
End: TopBarEnd,
|
|
85
|
+
Search: TopBarSearch,
|
|
86
|
+
IconButton: TopBarIconButton,
|
|
87
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { forwardRef, type HTMLAttributes } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import styles from './TopBar.module.scss';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Props for `<TopBar.End>`. Inherits the full `<div>` HTML attribute set;
|
|
7
|
+
* use the standard `className` / `style` / event-handler props as usual.
|
|
8
|
+
*/
|
|
9
|
+
export type TopBarEndProps = HTMLAttributes<HTMLDivElement>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Right-side cluster of a `<TopBar>` that shrinks to its content.
|
|
13
|
+
* @see docs/components/TopBar.md
|
|
14
|
+
*/
|
|
15
|
+
export const TopBarEnd = forwardRef<HTMLDivElement, TopBarEndProps>(function TopBarEnd(
|
|
16
|
+
{ className, ...props },
|
|
17
|
+
ref,
|
|
18
|
+
) {
|
|
19
|
+
return <div ref={ref} className={clsx(styles.end, className)} {...props} />;
|
|
20
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { Button } from '../Button';
|
|
4
|
+
import styles from './TopBar.module.scss';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Tone of the optional notification-indicator dot. Selects the dot color.
|
|
8
|
+
* - `'danger'` (default) — red, for unread / urgent notifications.
|
|
9
|
+
* - `'warning'` — dark amber, for soft-warning cues (maintenance banner, etc.).
|
|
10
|
+
* - `'info'` — blue, for informational badges.
|
|
11
|
+
* - `'accent'` — accent color, for "new content" cues.
|
|
12
|
+
*/
|
|
13
|
+
export type TopBarIndicatorTone = 'danger' | 'warning' | 'info' | 'accent';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Props for `<TopBar.IconButton>` — a thin wrapper over `<Button iconOnly
|
|
17
|
+
* variant="ghost" size="sm">` sized for the bar with one addition: an
|
|
18
|
+
* optional notification-indicator dot positioned in the upper-right corner.
|
|
19
|
+
*/
|
|
20
|
+
export interface TopBarIconButtonProps extends Omit<
|
|
21
|
+
ButtonHTMLAttributes<HTMLButtonElement>,
|
|
22
|
+
'children' | 'color'
|
|
23
|
+
> {
|
|
24
|
+
/**
|
|
25
|
+
* Icon to render inside the button. Typically a single lucide icon
|
|
26
|
+
* (e.g. `<Bell size={16} />`). The wrapping button supplies the
|
|
27
|
+
* accessible name via `aria-label` — the icon itself is decorative.
|
|
28
|
+
*/
|
|
29
|
+
children: ReactNode;
|
|
30
|
+
/**
|
|
31
|
+
* Show a small dot in the upper-right corner of the button. Useful for
|
|
32
|
+
* "unread notifications", "pending updates", etc. The dot is purely
|
|
33
|
+
* visual (`aria-hidden`); the consumer is responsible for surfacing
|
|
34
|
+
* count / status text to assistive tech, typically via the button's
|
|
35
|
+
* `aria-label` or a hidden span.
|
|
36
|
+
*/
|
|
37
|
+
indicator?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Dot color. Defaults to `'danger'` (red). See `TopBarIndicatorTone` for
|
|
40
|
+
* the full option set.
|
|
41
|
+
*/
|
|
42
|
+
indicatorTone?: TopBarIndicatorTone;
|
|
43
|
+
/**
|
|
44
|
+
* **Required.** Accessible name for the icon-only button — without it,
|
|
45
|
+
* screen readers announce nothing. Phrase as an action (`'Notifications'`,
|
|
46
|
+
* `'Create new'`). Include count info here when the indicator is on
|
|
47
|
+
* (e.g. `'Notifications, 3 unread'`).
|
|
48
|
+
*/
|
|
49
|
+
'aria-label': string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Per-tone CSS class lookup. Kept as a record so adding a tone is one edit. */
|
|
53
|
+
const TONE_CLASS: Record<TopBarIndicatorTone, string> = {
|
|
54
|
+
danger: styles.indicatorDanger,
|
|
55
|
+
warning: styles.indicatorWarning,
|
|
56
|
+
info: styles.indicatorInfo,
|
|
57
|
+
accent: styles.indicatorAccent,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Icon-only ghost button for `<TopBar>` with an optional notification-indicator dot.
|
|
62
|
+
* @see docs/components/TopBar.md
|
|
63
|
+
*/
|
|
64
|
+
export const TopBarIconButton = forwardRef<HTMLButtonElement, TopBarIconButtonProps>(
|
|
65
|
+
function TopBarIconButton(
|
|
66
|
+
{ children, indicator = false, indicatorTone = 'danger', className, ...props },
|
|
67
|
+
ref,
|
|
68
|
+
) {
|
|
69
|
+
return (
|
|
70
|
+
<Button
|
|
71
|
+
ref={ref}
|
|
72
|
+
variant="ghost"
|
|
73
|
+
size="sm"
|
|
74
|
+
iconOnly
|
|
75
|
+
className={clsx(styles.iconButton, className)}
|
|
76
|
+
// {...props} last so consumer overrides win (Pattern A).
|
|
77
|
+
{...props}
|
|
78
|
+
>
|
|
79
|
+
{children}
|
|
80
|
+
{indicator && (
|
|
81
|
+
<span aria-hidden className={clsx(styles.indicator, TONE_CLASS[indicatorTone])} />
|
|
82
|
+
)}
|
|
83
|
+
</Button>
|
|
84
|
+
);
|
|
85
|
+
},
|
|
86
|
+
);
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useId,
|
|
4
|
+
useMemo,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
type ChangeEvent,
|
|
8
|
+
type FocusEvent,
|
|
9
|
+
type InputHTMLAttributes,
|
|
10
|
+
type KeyboardEvent,
|
|
11
|
+
type MouseEvent,
|
|
12
|
+
type ReactNode,
|
|
13
|
+
} from 'react';
|
|
14
|
+
import { Search } from 'lucide-react';
|
|
15
|
+
import clsx from 'clsx';
|
|
16
|
+
import { useTranslation } from '../../i18n';
|
|
17
|
+
import { Kbd } from '../Kbd';
|
|
18
|
+
import { isTourHeld, useInOverlay } from '../_internal/overlay';
|
|
19
|
+
import {
|
|
20
|
+
TopBarSearchPanel,
|
|
21
|
+
optionId,
|
|
22
|
+
type PanelGroup,
|
|
23
|
+
type SearchOption,
|
|
24
|
+
} from './TopBarSearchPanel';
|
|
25
|
+
import styles from './TopBar.module.scss';
|
|
26
|
+
|
|
27
|
+
/** One result row in `<TopBar.Search>` combobox mode. */
|
|
28
|
+
export interface TopBarSearchItem {
|
|
29
|
+
/** Unique across ALL groups. Identifies the result set: the highlight resets to the first row when the set of ids changes. */
|
|
30
|
+
id: string;
|
|
31
|
+
/** Primary text. Truncates to one line. */
|
|
32
|
+
label: ReactNode;
|
|
33
|
+
/** Trailing muted text, e.g. the entity type or an email. */
|
|
34
|
+
meta?: ReactNode;
|
|
35
|
+
/** Leading decorative icon (e.g. `<User size={16} />`); hidden from assistive tech. */
|
|
36
|
+
icon?: ReactNode;
|
|
37
|
+
/**
|
|
38
|
+
* Renders the row as a link so Cmd/Ctrl/Shift/middle-click and "copy link"
|
|
39
|
+
* work natively. A plain click or Enter still calls `onSelect` (the library
|
|
40
|
+
* never navigates) — route there.
|
|
41
|
+
*/
|
|
42
|
+
href?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** A labelled block of results. Groups with no items are not rendered. */
|
|
46
|
+
export interface TopBarSearchGroup {
|
|
47
|
+
/** Visible heading; also the group's accessible name. */
|
|
48
|
+
label: string;
|
|
49
|
+
/** Result rows in this group. */
|
|
50
|
+
items: TopBarSearchItem[];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Trailing row in the ↑/↓ cycle, e.g. "View all results". */
|
|
54
|
+
export interface TopBarSearchFooterAction {
|
|
55
|
+
/** Row content. */
|
|
56
|
+
label: ReactNode;
|
|
57
|
+
/** Called on Enter or click. */
|
|
58
|
+
onSelect: () => void;
|
|
59
|
+
/** Optional link target, same semantics as `TopBarSearchItem.href`. */
|
|
60
|
+
href?: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Props for `<TopBar.Search>` — a styled `<input type="search">` with a
|
|
65
|
+
* leading magnifying-glass icon and an optional trailing `<Kbd>` hotkey
|
|
66
|
+
* hint. Passing `results` turns it into a combobox with a results panel.
|
|
67
|
+
*
|
|
68
|
+
* Inherits the standard `<input>` HTML attribute surface (minus `type`,
|
|
69
|
+
* fixed to `'search'`, the legacy `results` attribute, and the native
|
|
70
|
+
* `onSelect` text-selection event, replaced by the combobox `onSelect`). Spread `value` / `defaultValue` /
|
|
71
|
+
* `onChange` / `name` / `id` through normally — they reach the input.
|
|
72
|
+
*/
|
|
73
|
+
export interface TopBarSearchProps extends Omit<
|
|
74
|
+
InputHTMLAttributes<HTMLInputElement>,
|
|
75
|
+
'type' | 'onSelect' | 'results'
|
|
76
|
+
> {
|
|
77
|
+
/**
|
|
78
|
+
* Optional hotkey hint shown after the input. Rendered internally via
|
|
79
|
+
* `<Kbd size="sm">`. Pass an **array** of key labels for a multi-key
|
|
80
|
+
* combo (`['⌘', 'K']` → two chips joined with `+`) or a single string
|
|
81
|
+
* for a one-chip hint (`'Esc'` → one chip). Note: `'⌘K'` is treated as
|
|
82
|
+
* a single chip — use the array form for multi-key combos.
|
|
83
|
+
*
|
|
84
|
+
* The hint is **visual only**; the library does not bind any keyboard
|
|
85
|
+
* shortcut to it. Omit for no hint.
|
|
86
|
+
*/
|
|
87
|
+
hotkey?: string | string[];
|
|
88
|
+
/**
|
|
89
|
+
* `className` for the wrapping `<div>` (the search surface itself).
|
|
90
|
+
* The input's own className lives on the underlying `<input>` via the
|
|
91
|
+
* spread input-props (use the standard `inputClassName` pattern if you
|
|
92
|
+
* need to target the inner element specifically — not exposed in v1).
|
|
93
|
+
*/
|
|
94
|
+
className?: string;
|
|
95
|
+
/**
|
|
96
|
+
* Turns on combobox mode: the input gets `role="combobox"` and a results
|
|
97
|
+
* panel opens under it. Presence switches the mode — pass `[]` (not
|
|
98
|
+
* `undefined`) while there are no results yet. You filter or fetch; the
|
|
99
|
+
* library owns keyboard, focus, dismissal, positioning and announcements.
|
|
100
|
+
* The first row is highlighted whenever the set of ids changes, so Enter
|
|
101
|
+
* opens the top hit.
|
|
102
|
+
*/
|
|
103
|
+
results?: TopBarSearchGroup[];
|
|
104
|
+
/** Controlled panel visibility. Omit for uncontrolled. */
|
|
105
|
+
open?: boolean;
|
|
106
|
+
/** Uncontrolled initial visibility. Default `false`. */
|
|
107
|
+
defaultOpen?: boolean;
|
|
108
|
+
/** Called when the panel wants to open (focus, typing, ↓) or close (Esc, blur, selection). */
|
|
109
|
+
onOpenChange?: (open: boolean) => void;
|
|
110
|
+
/** Called on Enter or click on a result. The input text is left as is — clear it here if wanted. */
|
|
111
|
+
onSelect?: (item: TopBarSearchItem, groupIndex: number) => void;
|
|
112
|
+
/** Shows a loading row and sets `aria-busy`; existing results stay visible and the live region keeps announcing their count. */
|
|
113
|
+
loading?: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* Row shown for a non-empty query with no results. Default `t('topBar.searchEmpty')`
|
|
116
|
+
* (also used when this is an empty string). A non-string node is rendered but the
|
|
117
|
+
* live region still announces the default text — pass a string to have it announced.
|
|
118
|
+
*/
|
|
119
|
+
emptyMessage?: ReactNode;
|
|
120
|
+
/** Trailing row in the ↑/↓ cycle (e.g. "View all results"). Rendered whenever the panel is shown (results, loading row, or empty row), as the last row. */
|
|
121
|
+
footerAction?: TopBarSearchFooterAction;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Search input for `<TopBar>`: a pill with a leading icon, a native search input, an optional hotkey hint and an optional results combobox.
|
|
126
|
+
* @see docs/components/TopBar.md
|
|
127
|
+
*/
|
|
128
|
+
export const TopBarSearch = forwardRef<HTMLInputElement, TopBarSearchProps>(function TopBarSearch(
|
|
129
|
+
{
|
|
130
|
+
hotkey,
|
|
131
|
+
placeholder,
|
|
132
|
+
className,
|
|
133
|
+
'aria-label': ariaLabel,
|
|
134
|
+
results,
|
|
135
|
+
open,
|
|
136
|
+
defaultOpen = false,
|
|
137
|
+
onOpenChange,
|
|
138
|
+
onSelect,
|
|
139
|
+
loading = false,
|
|
140
|
+
emptyMessage,
|
|
141
|
+
footerAction,
|
|
142
|
+
onChange,
|
|
143
|
+
onFocus,
|
|
144
|
+
onBlur,
|
|
145
|
+
onClick,
|
|
146
|
+
onKeyDown,
|
|
147
|
+
...inputProps
|
|
148
|
+
},
|
|
149
|
+
ref,
|
|
150
|
+
) {
|
|
151
|
+
const t = useTranslation();
|
|
152
|
+
const listboxId = useId();
|
|
153
|
+
const wrapperRef = useRef<HTMLDivElement>(null);
|
|
154
|
+
const combobox = results !== undefined;
|
|
155
|
+
// `||` on BOTH links, not `??`: an empty string is never a meaningful
|
|
156
|
+
// explicit name, so it must fall through to placeholder, then translation.
|
|
157
|
+
const name = ariaLabel || placeholder || t('topBar.search');
|
|
158
|
+
|
|
159
|
+
const [openState, setOpenState] = useState(defaultOpen);
|
|
160
|
+
const isOpen = open ?? openState;
|
|
161
|
+
const setOpen = (next: boolean) => {
|
|
162
|
+
if (next === isOpen) return;
|
|
163
|
+
if (open === undefined) setOpenState(next);
|
|
164
|
+
onOpenChange?.(next);
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// Value is needed to decide whether an empty result set shows "No results".
|
|
168
|
+
const [uncontrolledValue, setUncontrolledValue] = useState(String(inputProps.defaultValue ?? ''));
|
|
169
|
+
const value = inputProps.value !== undefined ? String(inputProps.value) : uncontrolledValue;
|
|
170
|
+
|
|
171
|
+
const { groups, options } = useMemo(() => {
|
|
172
|
+
const groups: PanelGroup[] = [];
|
|
173
|
+
const options: SearchOption[] = [];
|
|
174
|
+
(results ?? []).forEach((g, groupIndex) => {
|
|
175
|
+
if (g.items.length === 0) return;
|
|
176
|
+
groups.push({ label: g.label, groupIndex, start: options.length, items: g.items });
|
|
177
|
+
for (const item of g.items) options.push({ kind: 'item', item, groupIndex });
|
|
178
|
+
});
|
|
179
|
+
if (footerAction) options.push({ kind: 'footer', action: footerAction });
|
|
180
|
+
return { groups, options };
|
|
181
|
+
}, [results, footerAction]);
|
|
182
|
+
|
|
183
|
+
const hasItems = groups.length > 0;
|
|
184
|
+
const shown = combobox && isOpen && (loading || hasItems || value.trim() !== '');
|
|
185
|
+
// Probed here, not in the panel: a child's layout effect runs before this wrapper's ref attaches.
|
|
186
|
+
const inOverlay = useInOverlay(wrapperRef, shown);
|
|
187
|
+
const empty = !loading && !hasItems ? emptyMessage || t('topBar.searchEmpty') : null;
|
|
188
|
+
const announcement = !shown
|
|
189
|
+
? ''
|
|
190
|
+
: hasItems
|
|
191
|
+
? t('topBar.searchResults', { count: options.filter((o) => o.kind === 'item').length })
|
|
192
|
+
: loading
|
|
193
|
+
? t('topBar.searchLoading')
|
|
194
|
+
: typeof empty === 'string'
|
|
195
|
+
? empty
|
|
196
|
+
: t('topBar.searchEmpty');
|
|
197
|
+
|
|
198
|
+
// Reset to the first row when the SET of ids changes — not on every new
|
|
199
|
+
// array identity, so a consumer rebuilding `results` inline keeps the highlight.
|
|
200
|
+
// Item ids only: the footer is always last, so toggling it must not reset the highlight or re-announce.
|
|
201
|
+
const signature = options.flatMap((o) => (o.kind === 'item' ? [o.item.id] : [])).join('\u0000');
|
|
202
|
+
const [active, setActive] = useState(0);
|
|
203
|
+
const [prevSignature, setPrevSignature] = useState(signature);
|
|
204
|
+
// Adjust state while rendering (not in an effect): no painted frame with a stale highlight.
|
|
205
|
+
if (signature !== prevSignature) {
|
|
206
|
+
setPrevSignature(signature);
|
|
207
|
+
setActive(0);
|
|
208
|
+
}
|
|
209
|
+
const activeIndex = options.length === 0 ? -1 : Math.min(active, options.length - 1);
|
|
210
|
+
|
|
211
|
+
const choose = (option: SearchOption) => {
|
|
212
|
+
if (option.kind === 'footer') option.action.onSelect();
|
|
213
|
+
else onSelect?.(option.item, option.groupIndex);
|
|
214
|
+
setOpen(false);
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
218
|
+
onChange?.(e);
|
|
219
|
+
if (inputProps.value === undefined) setUncontrolledValue(e.target.value);
|
|
220
|
+
if (combobox) setOpen(true);
|
|
221
|
+
};
|
|
222
|
+
const handleFocus = (e: FocusEvent<HTMLInputElement>) => {
|
|
223
|
+
onFocus?.(e);
|
|
224
|
+
if (combobox && !e.defaultPrevented) setOpen(true);
|
|
225
|
+
};
|
|
226
|
+
const handleBlur = (e: FocusEvent<HTMLInputElement>) => {
|
|
227
|
+
onBlur?.(e);
|
|
228
|
+
// Panel presses are mousedown-prevented, so a blur always means focus left.
|
|
229
|
+
// #684: unless a tour pointing into the panel took focus to its card.
|
|
230
|
+
const panel = document.getElementById(listboxId);
|
|
231
|
+
if (isTourHeld(e.relatedTarget, panel, wrapperRef.current)) return;
|
|
232
|
+
if (combobox) setOpen(false);
|
|
233
|
+
};
|
|
234
|
+
const handleClick = (e: MouseEvent<HTMLInputElement>) => {
|
|
235
|
+
onClick?.(e);
|
|
236
|
+
if (combobox && !e.defaultPrevented) setOpen(true);
|
|
237
|
+
};
|
|
238
|
+
const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
|
|
239
|
+
onKeyDown?.(e);
|
|
240
|
+
if (!combobox || e.defaultPrevented) return;
|
|
241
|
+
if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
|
|
242
|
+
if (!shown) {
|
|
243
|
+
if (e.key === 'ArrowDown') {
|
|
244
|
+
e.preventDefault();
|
|
245
|
+
setOpen(true);
|
|
246
|
+
}
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
if (options.length === 0) return;
|
|
250
|
+
e.preventDefault();
|
|
251
|
+
const step = e.key === 'ArrowDown' ? 1 : -1;
|
|
252
|
+
setActive((activeIndex + step + options.length) % options.length);
|
|
253
|
+
} else if (
|
|
254
|
+
e.key === 'Enter' &&
|
|
255
|
+
!e.nativeEvent.isComposing &&
|
|
256
|
+
e.keyCode !== 229 &&
|
|
257
|
+
shown &&
|
|
258
|
+
activeIndex >= 0
|
|
259
|
+
) {
|
|
260
|
+
e.preventDefault();
|
|
261
|
+
choose(options[activeIndex]!);
|
|
262
|
+
}
|
|
263
|
+
// Escape: TopBarSearchPanel's document listener (overlay registry).
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
return (
|
|
267
|
+
<div ref={wrapperRef} className={clsx(styles.search, className)}>
|
|
268
|
+
<Search aria-hidden className={styles.searchIcon} />
|
|
269
|
+
<input
|
|
270
|
+
ref={ref}
|
|
271
|
+
type="search"
|
|
272
|
+
placeholder={placeholder}
|
|
273
|
+
aria-label={name}
|
|
274
|
+
className={styles.searchInput}
|
|
275
|
+
// Password managers and browser autofill must skip a free-text search box.
|
|
276
|
+
autoComplete="off"
|
|
277
|
+
data-1p-ignore
|
|
278
|
+
data-lpignore="true"
|
|
279
|
+
data-form-type="other"
|
|
280
|
+
// {...inputProps} after the defaults so consumer overrides win (Pattern A) ...
|
|
281
|
+
{...inputProps}
|
|
282
|
+
// ... but the combobox ARIA contract is applied after them (Pattern B).
|
|
283
|
+
{...(combobox && {
|
|
284
|
+
role: 'combobox',
|
|
285
|
+
'aria-expanded': shown,
|
|
286
|
+
'aria-controls': shown ? listboxId : undefined,
|
|
287
|
+
'aria-activedescendant':
|
|
288
|
+
shown && activeIndex >= 0 ? optionId(listboxId, activeIndex) : undefined,
|
|
289
|
+
'aria-autocomplete': 'list' as const,
|
|
290
|
+
})}
|
|
291
|
+
onChange={handleChange}
|
|
292
|
+
onFocus={handleFocus}
|
|
293
|
+
onBlur={handleBlur}
|
|
294
|
+
onClick={handleClick}
|
|
295
|
+
onKeyDown={handleKeyDown}
|
|
296
|
+
/>
|
|
297
|
+
{hotkey != null && <Kbd keys={Array.isArray(hotkey) ? hotkey : [hotkey]} size="sm" />}
|
|
298
|
+
{combobox && (
|
|
299
|
+
<TopBarSearchPanel
|
|
300
|
+
id={listboxId}
|
|
301
|
+
shown={shown}
|
|
302
|
+
label={name}
|
|
303
|
+
groups={groups}
|
|
304
|
+
options={options}
|
|
305
|
+
activeIndex={activeIndex}
|
|
306
|
+
onActivate={setActive}
|
|
307
|
+
onChoose={choose}
|
|
308
|
+
anchorRef={wrapperRef}
|
|
309
|
+
inOverlay={inOverlay}
|
|
310
|
+
onClose={() => setOpen(false)}
|
|
311
|
+
loading={loading}
|
|
312
|
+
emptyMessage={shown ? empty : null}
|
|
313
|
+
announcement={announcement}
|
|
314
|
+
announceKey={signature}
|
|
315
|
+
/>
|
|
316
|
+
)}
|
|
317
|
+
</div>
|
|
318
|
+
);
|
|
319
|
+
});
|