@eocrm/design-system 0.0.0-stage → 0.6.17
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/README.md +262 -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 +82 -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,395 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useCallback,
|
|
3
|
+
useEffect,
|
|
4
|
+
useId,
|
|
5
|
+
useLayoutEffect,
|
|
6
|
+
useRef,
|
|
7
|
+
useState,
|
|
8
|
+
type ReactElement,
|
|
9
|
+
type ReactNode,
|
|
10
|
+
type RefObject,
|
|
11
|
+
} from 'react';
|
|
12
|
+
import { Button } from '../Button';
|
|
13
|
+
import { Cluster } from '../Cluster';
|
|
14
|
+
import { Stack } from '../Stack';
|
|
15
|
+
import { Popover } from '../Popover';
|
|
16
|
+
import { usePopoverContext } from '../Popover/context';
|
|
17
|
+
import { sanitizeId } from '../_internal/refs';
|
|
18
|
+
import { useTranslation } from '../../i18n/useTranslation';
|
|
19
|
+
import styles from './ConfirmationPopover.module.scss';
|
|
20
|
+
|
|
21
|
+
/** `'danger'` swaps Confirm to a danger-variant button; `'default'` uses primary. */
|
|
22
|
+
export type ConfirmationVariant = 'default' | 'danger';
|
|
23
|
+
|
|
24
|
+
export interface ConfirmationPopoverProps {
|
|
25
|
+
/**
|
|
26
|
+
* The trigger element. Same forwardRef-required contract as
|
|
27
|
+
* `<Popover.Trigger>` — `<Button>` qualifies; a custom component without
|
|
28
|
+
* `forwardRef` does not.
|
|
29
|
+
*/
|
|
30
|
+
children: ReactElement;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Heading text. Renders inside `<Popover.Heading>` (an `<h3>`) and wires
|
|
34
|
+
* `aria-labelledby` on the dialog automatically.
|
|
35
|
+
*/
|
|
36
|
+
title: string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Optional body text below the title. When provided, wires
|
|
40
|
+
* `aria-describedby` so screen readers announce it.
|
|
41
|
+
*/
|
|
42
|
+
description?: ReactNode;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Confirm button label. Defaults to the i18n value at
|
|
46
|
+
* `confirmationPopover.confirm` (`'Confirm'` in English).
|
|
47
|
+
*
|
|
48
|
+
* An EMPTY string counts as unset, not as an explicit blank: this label is
|
|
49
|
+
* the confirm button's only name source (the pending spinner beside it is
|
|
50
|
+
* `aria-hidden`), so an empty one would leave the button anonymous.
|
|
51
|
+
*/
|
|
52
|
+
confirmLabel?: string;
|
|
53
|
+
|
|
54
|
+
/** `'danger'` makes Confirm a danger-variant button. Defaults to `'default'` (primary). */
|
|
55
|
+
variant?: ConfirmationVariant;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Async-aware confirm handler. May return a Promise; while pending,
|
|
59
|
+
* both buttons disable, the Confirm button shows a small spinner, and
|
|
60
|
+
* Escape / click-outside dismissal is blocked.
|
|
61
|
+
*
|
|
62
|
+
* - Resolve → popover closes.
|
|
63
|
+
* - Reject → popover stays open, buttons re-enable. `onCancel` is NOT
|
|
64
|
+
* fired (the user neither confirmed nor cancelled — it's an error
|
|
65
|
+
* state owned by the consumer).
|
|
66
|
+
*
|
|
67
|
+
* The consumer is expected to surface error feedback externally (toast,
|
|
68
|
+
* inline message, etc.). ConfirmationPopover does NOT render errors.
|
|
69
|
+
*/
|
|
70
|
+
onConfirm: () => void | Promise<void>;
|
|
71
|
+
|
|
72
|
+
/** Optional. Fires on Cancel click, Escape, or click-outside dismissal. NOT fired if `onConfirm` rejects. */
|
|
73
|
+
onCancel?: () => void;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Direct initial focus into the panel's content instead of the default
|
|
77
|
+
* Cancel button — e.g. an `<Input>` rendered in `description` for a rename
|
|
78
|
+
* flow. When provided and its `.current` is non-null on open, the component
|
|
79
|
+
* focuses this element after the panel mounts (skipping the Cancel-focus).
|
|
80
|
+
* Tip: add `onFocus={(e) => e.currentTarget.select()}` to a text input to
|
|
81
|
+
* select its contents so the user can type/replace immediately.
|
|
82
|
+
*/
|
|
83
|
+
initialFocusRef?: RefObject<HTMLElement | null>;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Where focus goes when the popover closes. Default: back to the trigger.
|
|
87
|
+
*
|
|
88
|
+
* That default breaks whenever the trigger is gone by close time — the
|
|
89
|
+
* confirmed action deleted the row that owned it — and focus lands on
|
|
90
|
+
* `<body>`, so a keyboard user loses their place.
|
|
91
|
+
*
|
|
92
|
+
* The ref is read **at close time**, not at open time, so it may be pointed
|
|
93
|
+
* at whatever still exists once the work is done — the next row's trigger,
|
|
94
|
+
* the empty state's first button. If it is empty or its element has left
|
|
95
|
+
* the document, focus falls back to the trigger (when it still exists).
|
|
96
|
+
*
|
|
97
|
+
* It applies when the popover closes via Confirm, Cancel or Escape. An
|
|
98
|
+
* outside click never restores focus — focus stays wherever the click put
|
|
99
|
+
* it (on a control, or `<body>` for an inert area).
|
|
100
|
+
*
|
|
101
|
+
* A ref that is set statically (not only inside `onConfirm`) ALSO fires when
|
|
102
|
+
* the user closes by clicking the trigger again, pulling focus off the
|
|
103
|
+
* trigger. To return to the trigger on Cancel / toggle and only move
|
|
104
|
+
* elsewhere after a confirm, aim the ref inside `onConfirm` and clear it in
|
|
105
|
+
* `onOpenChange(true)`.
|
|
106
|
+
*
|
|
107
|
+
* If focus is already on some other live element when the popover closes,
|
|
108
|
+
* it is left alone.
|
|
109
|
+
*
|
|
110
|
+
* The target is scrolled into view with `{ block: 'nearest' }` (a no-op
|
|
111
|
+
* when it is already visible) — it may be far from where the user was.
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* const returnFocusRef = useRef<HTMLElement | null>(null);
|
|
115
|
+
* <ConfirmationPopover
|
|
116
|
+
* title="Delete row?"
|
|
117
|
+
* variant="danger"
|
|
118
|
+
* returnFocusRef={returnFocusRef}
|
|
119
|
+
* onOpenChange={(next) => { if (next) returnFocusRef.current = null; }}
|
|
120
|
+
* onConfirm={async () => {
|
|
121
|
+
* await deleteRow(id);
|
|
122
|
+
* returnFocusRef.current = nextRowTriggerRef.current ?? addRowButtonRef.current;
|
|
123
|
+
* }}
|
|
124
|
+
* >
|
|
125
|
+
* <Button variant="danger">Delete</Button>
|
|
126
|
+
* </ConfirmationPopover>
|
|
127
|
+
*/
|
|
128
|
+
returnFocusRef?: RefObject<HTMLElement | null>;
|
|
129
|
+
|
|
130
|
+
/** Preferred side. Default `'top'` — confirmations anchor above the trigger by convention. */
|
|
131
|
+
side?: 'top' | 'right' | 'bottom' | 'left';
|
|
132
|
+
|
|
133
|
+
/** Edge alignment. Default `'center'`. */
|
|
134
|
+
align?: 'start' | 'center' | 'end';
|
|
135
|
+
|
|
136
|
+
/** Gap in px between trigger and panel. Default `10`. */
|
|
137
|
+
sideOffset?: number;
|
|
138
|
+
|
|
139
|
+
/** Controlled open state. Pair with `onOpenChange`. */
|
|
140
|
+
open?: boolean;
|
|
141
|
+
|
|
142
|
+
/** Open-change callback. Required when `open` is provided. */
|
|
143
|
+
onOpenChange?: (open: boolean) => void;
|
|
144
|
+
|
|
145
|
+
/** Default open state for uncontrolled usage. Defaults to `false`. */
|
|
146
|
+
defaultOpen?: boolean;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Returns focus when the popover closes (#552, #553). Popover itself only
|
|
151
|
+
* refocuses the trigger on Escape / `Popover.Close`; a Confirm or Cancel
|
|
152
|
+
* click unmounts the focused button and would drop focus to `<body>`.
|
|
153
|
+
* Rendered inside `<Popover>` so it can read the trigger ref from context.
|
|
154
|
+
*/
|
|
155
|
+
function FocusReturn({ returnFocusRef }: { returnFocusRef?: RefObject<HTMLElement | null> }) {
|
|
156
|
+
const { open, triggerRef, contentRef } = usePopoverContext('FocusReturn');
|
|
157
|
+
const prevOpenRef = useRef(open);
|
|
158
|
+
const generationRef = useRef(0);
|
|
159
|
+
const outsidePointerRef = useRef(false);
|
|
160
|
+
|
|
161
|
+
// An outside-click dismissal commits BEFORE the browser's mousedown moves
|
|
162
|
+
// focus to what was clicked; restoring then would flash focus onto the
|
|
163
|
+
// trigger (and maybe scroll to returnFocusRef) only for the click to take
|
|
164
|
+
// it away. Flag such pointerdowns — same "outside" test as Popover.Content
|
|
165
|
+
// — so the close leaves focus to the click.
|
|
166
|
+
useEffect(() => {
|
|
167
|
+
if (!open) return;
|
|
168
|
+
outsidePointerRef.current = false;
|
|
169
|
+
const onPointerDown = (e: PointerEvent) => {
|
|
170
|
+
const target = e.target as Node | null;
|
|
171
|
+
if (!target) return;
|
|
172
|
+
if (contentRef.current?.contains(target) || triggerRef.current?.contains(target)) return;
|
|
173
|
+
const el = target instanceof Element ? target : target.parentElement;
|
|
174
|
+
if (el?.closest('[data-dropdown-menu-content], [data-popover-content]')) return;
|
|
175
|
+
outsidePointerRef.current = true;
|
|
176
|
+
// Only this pointerdown's own close commit (flushed in a microtask) may
|
|
177
|
+
// see the flag; a pointerdown that did NOT close (blocked while pending)
|
|
178
|
+
// must not suppress a later Confirm-resolve restore.
|
|
179
|
+
setTimeout(() => {
|
|
180
|
+
outsidePointerRef.current = false;
|
|
181
|
+
}, 0);
|
|
182
|
+
};
|
|
183
|
+
// On WINDOW capture, not document: Popover.Content's dismiss listener is
|
|
184
|
+
// a document capture listener registered first, and real browsers run a
|
|
185
|
+
// microtask checkpoint between listeners — React flushes the close there,
|
|
186
|
+
// so a document listener of ours would set the flag after restore() ran.
|
|
187
|
+
// Window capture fires before any document listener.
|
|
188
|
+
window.addEventListener('pointerdown', onPointerDown, true);
|
|
189
|
+
return () => window.removeEventListener('pointerdown', onPointerDown, true);
|
|
190
|
+
}, [open, contentRef, triggerRef]);
|
|
191
|
+
|
|
192
|
+
useLayoutEffect(() => {
|
|
193
|
+
const generation = ++generationRef.current;
|
|
194
|
+
const restore = () => {
|
|
195
|
+
if (outsidePointerRef.current) return;
|
|
196
|
+
const active = document.activeElement;
|
|
197
|
+
const trigger = triggerRef.current;
|
|
198
|
+
// An outside click onto a real control already moved focus — respect
|
|
199
|
+
// it. Focus counts as lost on <body>, on a detached node (the panel's
|
|
200
|
+
// button that was just removed), or on the trigger (Popover's Escape
|
|
201
|
+
// path refocuses it before we run, and returnFocusRef must still win).
|
|
202
|
+
const lost = !active || active === document.body || !active.isConnected || active === trigger;
|
|
203
|
+
if (!lost) return;
|
|
204
|
+
const requested = returnFocusRef?.current ?? null;
|
|
205
|
+
if (requested?.isConnected) {
|
|
206
|
+
requested.focus({ preventScroll: true });
|
|
207
|
+
requested.scrollIntoView?.({ block: 'nearest' });
|
|
208
|
+
} else if (trigger?.isConnected && active !== trigger) {
|
|
209
|
+
trigger.focus({ preventScroll: true });
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
if (!open && prevOpenRef.current) restore();
|
|
213
|
+
prevOpenRef.current = open;
|
|
214
|
+
// The whole ConfirmationPopover unmounted while open (the confirmed
|
|
215
|
+
// action removed its row): no open → closed commit will ever run, so
|
|
216
|
+
// restore from the unmount cleanup. Deferred until React finishes the
|
|
217
|
+
// teardown; a later effect run (a normal close) bumps the generation and
|
|
218
|
+
// cancels it, so focus is only moved once — same scheme as Modal.
|
|
219
|
+
if (open) {
|
|
220
|
+
return () => {
|
|
221
|
+
queueMicrotask(() => {
|
|
222
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- the generation counter must be read at cleanup time
|
|
223
|
+
if (generationRef.current === generation) restore();
|
|
224
|
+
});
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
}, [open, triggerRef, returnFocusRef]);
|
|
228
|
+
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Opinionated "Are you sure?" preset on top of `<Popover>`.
|
|
234
|
+
* @see docs/components/ConfirmationPopover.md
|
|
235
|
+
*/
|
|
236
|
+
export function ConfirmationPopover({
|
|
237
|
+
children,
|
|
238
|
+
title,
|
|
239
|
+
description,
|
|
240
|
+
confirmLabel,
|
|
241
|
+
variant = 'default',
|
|
242
|
+
onConfirm,
|
|
243
|
+
onCancel,
|
|
244
|
+
initialFocusRef,
|
|
245
|
+
returnFocusRef,
|
|
246
|
+
side = 'top',
|
|
247
|
+
align = 'center',
|
|
248
|
+
sideOffset = 10,
|
|
249
|
+
open: controlledOpen,
|
|
250
|
+
onOpenChange,
|
|
251
|
+
defaultOpen = false,
|
|
252
|
+
}: ConfirmationPopoverProps) {
|
|
253
|
+
const t = useTranslation();
|
|
254
|
+
// Hoist open state into ConfirmationPopover so we can close after a
|
|
255
|
+
// successful sync/async onConfirm without going through the consumer.
|
|
256
|
+
const isConsumerControlled = controlledOpen !== undefined;
|
|
257
|
+
const [internalOpen, setInternalOpen] = useState(defaultOpen);
|
|
258
|
+
const open = isConsumerControlled ? (controlledOpen as boolean) : internalOpen;
|
|
259
|
+
|
|
260
|
+
const setOpen = useCallback(
|
|
261
|
+
(next: boolean) => {
|
|
262
|
+
onOpenChange?.(next);
|
|
263
|
+
if (!isConsumerControlled) setInternalOpen(next);
|
|
264
|
+
},
|
|
265
|
+
[isConsumerControlled, onOpenChange],
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
const reactId = useId();
|
|
269
|
+
const descriptionId = description ? `confirm-desc-${sanitizeId(reactId)}` : undefined;
|
|
270
|
+
|
|
271
|
+
const [pending, setPending] = useState(false);
|
|
272
|
+
|
|
273
|
+
// Wrap Popover's onOpenChange to fire onCancel when the popover closes
|
|
274
|
+
// via Escape / click-outside (i.e. a close that didn't come from Confirm).
|
|
275
|
+
const handleOpenChange = useCallback(
|
|
276
|
+
(next: boolean) => {
|
|
277
|
+
// Block close while a confirm is pending — the in-flight Promise
|
|
278
|
+
// should resolve before we tear down the popover.
|
|
279
|
+
if (pending && !next) return;
|
|
280
|
+
if (!next) onCancel?.();
|
|
281
|
+
setOpen(next);
|
|
282
|
+
},
|
|
283
|
+
[pending, onCancel, setOpen],
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
const cancelRef = useRef<HTMLButtonElement | null>(null);
|
|
287
|
+
|
|
288
|
+
// Focus the Cancel button after Popover.Content focuses the panel.
|
|
289
|
+
// queueMicrotask runs after Popover.Content's own focus effect (which also
|
|
290
|
+
// uses queueMicrotask), so by the time this runs, the panel has focus and
|
|
291
|
+
// we override it with Cancel. A consumer-supplied initialFocusRef takes
|
|
292
|
+
// precedence (mirrors Modal) — e.g. an <Input> in the description slot.
|
|
293
|
+
useEffect(() => {
|
|
294
|
+
if (!open) return;
|
|
295
|
+
queueMicrotask(() => {
|
|
296
|
+
const target = initialFocusRef?.current ?? cancelRef.current;
|
|
297
|
+
target?.focus({ preventScroll: true });
|
|
298
|
+
});
|
|
299
|
+
}, [open, initialFocusRef]);
|
|
300
|
+
|
|
301
|
+
// Polite live region text, computed in an effect rather than during render so
|
|
302
|
+
// a popover that opens ALREADY pending still announces — mounting the region
|
|
303
|
+
// and its text together announces nothing. See CLAUDE.md Hard rule 10.
|
|
304
|
+
const [pendingText, setPendingText] = useState('');
|
|
305
|
+
useEffect(() => {
|
|
306
|
+
setPendingText(pending ? t('confirmationPopover.pending') : '');
|
|
307
|
+
}, [pending, t]);
|
|
308
|
+
|
|
309
|
+
const handleConfirm = useCallback(() => {
|
|
310
|
+
if (pending) return;
|
|
311
|
+
const result = onConfirm();
|
|
312
|
+
if (result instanceof Promise) {
|
|
313
|
+
setPending(true);
|
|
314
|
+
result
|
|
315
|
+
.then(() => {
|
|
316
|
+
setPending(false);
|
|
317
|
+
setOpen(false);
|
|
318
|
+
})
|
|
319
|
+
.catch(() => {
|
|
320
|
+
setPending(false);
|
|
321
|
+
// Popover stays open. onCancel NOT fired — failure is its own state.
|
|
322
|
+
});
|
|
323
|
+
} else {
|
|
324
|
+
setOpen(false);
|
|
325
|
+
}
|
|
326
|
+
}, [pending, onConfirm, setOpen]);
|
|
327
|
+
|
|
328
|
+
const handleCancel = useCallback(() => {
|
|
329
|
+
// Required now that the button is aria-disabled rather than natively
|
|
330
|
+
// disabled: aria-disabled preserves pointer events and focusability.
|
|
331
|
+
if (pending) return;
|
|
332
|
+
onCancel?.();
|
|
333
|
+
setOpen(false);
|
|
334
|
+
}, [pending, onCancel, setOpen]);
|
|
335
|
+
|
|
336
|
+
return (
|
|
337
|
+
<Popover open={open} onOpenChange={handleOpenChange}>
|
|
338
|
+
<Popover.Trigger>{children}</Popover.Trigger>
|
|
339
|
+
<Popover.Content
|
|
340
|
+
side={side}
|
|
341
|
+
align={align}
|
|
342
|
+
sideOffset={sideOffset}
|
|
343
|
+
aria-describedby={descriptionId}
|
|
344
|
+
>
|
|
345
|
+
<Stack gap="sm">
|
|
346
|
+
<Popover.Heading>{title}</Popover.Heading>
|
|
347
|
+
{description && (
|
|
348
|
+
<p id={descriptionId} className={styles.description}>
|
|
349
|
+
{description}
|
|
350
|
+
</p>
|
|
351
|
+
)}
|
|
352
|
+
{/* Rendered unconditionally; only the text mutates. The spinner
|
|
353
|
+
below is aria-hidden and `aria-busy` alone reaches no screen
|
|
354
|
+
reader, so before this the pending state was silent from the
|
|
355
|
+
moment the user confirmed until the popover closed (#497). */}
|
|
356
|
+
<span role="status" aria-live="polite" className={styles.srOnly}>
|
|
357
|
+
{pendingText}
|
|
358
|
+
</span>
|
|
359
|
+
<Cluster justify="end" gap="sm">
|
|
360
|
+
<Button
|
|
361
|
+
ref={cancelRef}
|
|
362
|
+
variant="secondary"
|
|
363
|
+
size="sm"
|
|
364
|
+
// aria-disabled, not native `disabled`: the latter drops the
|
|
365
|
+
// button out of the tab order the moment the user confirms,
|
|
366
|
+
// leaving focus on a detached element. aria-disabled does NOT
|
|
367
|
+
// block activation (see Button's own anti-patterns), so both
|
|
368
|
+
// handlers guard on `pending` themselves.
|
|
369
|
+
aria-disabled={pending || undefined}
|
|
370
|
+
onClick={handleCancel}
|
|
371
|
+
>
|
|
372
|
+
{t('confirmationPopover.cancel')}
|
|
373
|
+
</Button>
|
|
374
|
+
<Button
|
|
375
|
+
variant={variant === 'danger' ? 'danger' : 'primary'}
|
|
376
|
+
size="sm"
|
|
377
|
+
aria-disabled={pending || undefined}
|
|
378
|
+
onClick={handleConfirm}
|
|
379
|
+
>
|
|
380
|
+
{pending && <span className={styles.spinner} aria-hidden="true" />}
|
|
381
|
+
{/* `||`, not `??`: the spinner beside it is aria-hidden, so this
|
|
382
|
+
is the confirm button's only name source and `confirmLabel=""`
|
|
383
|
+
would leave it with no accessible name (#535). */}
|
|
384
|
+
{confirmLabel || t('confirmationPopover.confirm')}
|
|
385
|
+
</Button>
|
|
386
|
+
</Cluster>
|
|
387
|
+
</Stack>
|
|
388
|
+
</Popover.Content>
|
|
389
|
+
{/* Last on purpose: Popover.Trigger re-attaches triggerRef (a fresh
|
|
390
|
+
merged callback ref each render) in the layout phase, in tree
|
|
391
|
+
order — FocusReturn's layout effect must run after that. */}
|
|
392
|
+
<FocusReturn returnFocusRef={returnFocusRef} />
|
|
393
|
+
</Popover>
|
|
394
|
+
);
|
|
395
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// No base class — a Constrain with no props is a plain <div>; all styling comes
|
|
2
|
+
// from the width/flex modifier classes below. Mirrors how Stack/Cluster carry
|
|
3
|
+
// their scale in modifier classes.
|
|
4
|
+
|
|
5
|
+
@each $name in xs, sm, md, lg, xl {
|
|
6
|
+
.w-#{$name} {
|
|
7
|
+
width: var(--measure-#{$name});
|
|
8
|
+
}
|
|
9
|
+
.minW-#{$name} {
|
|
10
|
+
min-width: var(--measure-#{$name});
|
|
11
|
+
}
|
|
12
|
+
.maxW-#{$name} {
|
|
13
|
+
max-width: var(--measure-#{$name});
|
|
14
|
+
}
|
|
15
|
+
.h-#{$name} {
|
|
16
|
+
height: var(--measure-#{$name});
|
|
17
|
+
}
|
|
18
|
+
.minH-#{$name} {
|
|
19
|
+
min-height: var(--measure-#{$name});
|
|
20
|
+
}
|
|
21
|
+
.maxH-#{$name} {
|
|
22
|
+
max-height: var(--measure-#{$name});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.w-full {
|
|
27
|
+
width: 100%;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.minW-full {
|
|
31
|
+
min-width: 100%;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.maxW-full {
|
|
35
|
+
max-width: 100%;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.h-full {
|
|
39
|
+
height: 100%;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.minH-full {
|
|
43
|
+
min-height: 100%;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.maxH-full {
|
|
47
|
+
max-height: 100%;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.h-viewport {
|
|
51
|
+
height: 100vh;
|
|
52
|
+
height: 100dvh;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.minH-viewport {
|
|
56
|
+
min-height: 100vh;
|
|
57
|
+
min-height: 100dvh;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.maxH-viewport {
|
|
61
|
+
max-height: 100vh;
|
|
62
|
+
max-height: 100dvh;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.h-viewport-70 {
|
|
66
|
+
height: 70vh;
|
|
67
|
+
height: 70dvh;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.minH-viewport-70 {
|
|
71
|
+
min-height: 70vh;
|
|
72
|
+
min-height: 70dvh;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.maxH-viewport-70 {
|
|
76
|
+
max-height: 70vh;
|
|
77
|
+
max-height: 70dvh;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.flex-grow {
|
|
81
|
+
flex: 1 1 0;
|
|
82
|
+
|
|
83
|
+
// Allow shrinking below the content's intrinsic width so a `<Text truncate>`
|
|
84
|
+
// (or any overflow:hidden child) can actually clip inside a flex row, instead
|
|
85
|
+
// of forcing the row to overflow. Only matters under overflow — safe otherwise.
|
|
86
|
+
min-width: 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.flex-auto {
|
|
90
|
+
flex: 1 1 auto;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.flex-shrink {
|
|
94
|
+
flex: 0 1 auto;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.flex-none {
|
|
98
|
+
flex: 0 0 auto;
|
|
99
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import styles from './Constrain.module.scss';
|
|
4
|
+
|
|
5
|
+
/** Named width step → a `--measure-*` token; `'full'` = 100%. */
|
|
6
|
+
export type ConstrainWidth = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
7
|
+
|
|
8
|
+
/** Fixed named measure, `'full'` (containing block), or a dynamic viewport height. */
|
|
9
|
+
export type ConstrainHeight = ConstrainWidth | 'viewport' | 'viewport-70';
|
|
10
|
+
|
|
11
|
+
/** How the box behaves as a flex child (`Cluster`/`Stack` item). */
|
|
12
|
+
export type ConstrainFlex = 'grow' | 'shrink' | 'auto' | 'none';
|
|
13
|
+
|
|
14
|
+
export interface ConstrainProps extends HTMLAttributes<HTMLDivElement> {
|
|
15
|
+
/** Fixed width — a named step (`xs` 200 / `sm` 320 / `md` 448 / `lg` 640 / `xl` 800px, via `--measure-*` tokens) or `'full'` (100%). */
|
|
16
|
+
width?: ConstrainWidth;
|
|
17
|
+
/** Minimum width floor — a named step or `'full'` (100%). */
|
|
18
|
+
minWidth?: ConstrainWidth;
|
|
19
|
+
/** Maximum width cap — the common case (e.g. a search input at `'sm'`). */
|
|
20
|
+
maxWidth?: ConstrainWidth;
|
|
21
|
+
/**
|
|
22
|
+
* Fixed height — a named measure (same scale as the widths), `'full'` (100%),
|
|
23
|
+
* `'viewport'` (100dvh), or `'viewport-70'` (70dvh). `height="viewport-70"` with
|
|
24
|
+
* `maxHeight="lg"` makes a viewport-relative panel that never exceeds 640px.
|
|
25
|
+
*/
|
|
26
|
+
height?: ConstrainHeight;
|
|
27
|
+
/** Minimum height floor — a named measure, `'full'`, `'viewport'`, or `'viewport-70'`. */
|
|
28
|
+
minHeight?: ConstrainHeight;
|
|
29
|
+
/** Maximum height cap — a named measure, `'full'`, `'viewport'`, or `'viewport-70'`. */
|
|
30
|
+
maxHeight?: ConstrainHeight;
|
|
31
|
+
/**
|
|
32
|
+
* Flex behavior as a child of a flex row/column.
|
|
33
|
+
* - `'grow'` — fill remaining space (`flex: 1 1 0`) and shrink below content
|
|
34
|
+
* width (`min-width: 0`) so a truncating child (`<Text truncate>`) can clip.
|
|
35
|
+
* To opt a `Stack`/`Cluster` into that truncating chain WITHOUT also making
|
|
36
|
+
* it fill the row, use their `minWidth0` prop instead — and note Constrain
|
|
37
|
+
* renders a `<div>`, so it is invalid inside a `<button>`/`<a>`/`<label>`,
|
|
38
|
+
* where `<Cluster as="span" minWidth0>` is the only option.
|
|
39
|
+
* - `'auto'` — size to content, may grow/shrink (`flex: 1 1 auto`).
|
|
40
|
+
* - `'shrink'` — don't grow, may shrink (`flex: 0 1 auto`, the flex default).
|
|
41
|
+
* - `'none'` — fixed, never grow/shrink (`flex: 0 0 auto`).
|
|
42
|
+
*
|
|
43
|
+
* Omit for no flex class: the element behaves as its flex container dictates.
|
|
44
|
+
*/
|
|
45
|
+
flex?: ConstrainFlex;
|
|
46
|
+
/** The content to size. Required — a Constrain with nothing inside has nothing to constrain. */
|
|
47
|
+
children: ReactNode;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Size / flex constraint primitive; sizes its own box and does not lay out its children.
|
|
52
|
+
* @see docs/components/Constrain.md
|
|
53
|
+
*/
|
|
54
|
+
// `children` is destructured out of `rest` and rendered once below (Stack/Cluster
|
|
55
|
+
// pass children via {...props} instead — both are correct; this is explicit).
|
|
56
|
+
export const Constrain = forwardRef<HTMLDivElement, ConstrainProps>(function Constrain(
|
|
57
|
+
{ width, minWidth, maxWidth, height, minHeight, maxHeight, flex, className, children, ...rest },
|
|
58
|
+
ref,
|
|
59
|
+
) {
|
|
60
|
+
// {...rest} last so consumer overrides win (Pattern A) — Constrain locks no attrs.
|
|
61
|
+
return (
|
|
62
|
+
<div
|
|
63
|
+
ref={ref}
|
|
64
|
+
className={clsx(
|
|
65
|
+
width && styles[`w-${width}`],
|
|
66
|
+
minWidth && styles[`minW-${minWidth}`],
|
|
67
|
+
maxWidth && styles[`maxW-${maxWidth}`],
|
|
68
|
+
height && styles[`h-${height}`],
|
|
69
|
+
minHeight && styles[`minH-${minHeight}`],
|
|
70
|
+
maxHeight && styles[`maxH-${maxHeight}`],
|
|
71
|
+
flex && styles[`flex-${flex}`],
|
|
72
|
+
className,
|
|
73
|
+
)}
|
|
74
|
+
{...rest}
|
|
75
|
+
>
|
|
76
|
+
{children}
|
|
77
|
+
</div>
|
|
78
|
+
);
|
|
79
|
+
});
|