@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,728 @@
|
|
|
1
|
+
import {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useCallback,
|
|
4
|
+
useEffect,
|
|
5
|
+
useId,
|
|
6
|
+
useRef,
|
|
7
|
+
useState,
|
|
8
|
+
type ElementType,
|
|
9
|
+
type ForwardedRef,
|
|
10
|
+
type HTMLAttributes,
|
|
11
|
+
type KeyboardEvent as ReactKeyboardEvent,
|
|
12
|
+
type PointerEvent as ReactPointerEvent,
|
|
13
|
+
type ReactElement,
|
|
14
|
+
type ReactNode,
|
|
15
|
+
} from 'react';
|
|
16
|
+
import { createPortal } from 'react-dom';
|
|
17
|
+
import { ChevronRight } from 'lucide-react';
|
|
18
|
+
import {
|
|
19
|
+
autoUpdate,
|
|
20
|
+
flip,
|
|
21
|
+
offset,
|
|
22
|
+
shift,
|
|
23
|
+
size,
|
|
24
|
+
useFloating,
|
|
25
|
+
type Placement,
|
|
26
|
+
} from '@floating-ui/react-dom';
|
|
27
|
+
import clsx from 'clsx';
|
|
28
|
+
import { useTranslation } from '../../i18n';
|
|
29
|
+
import { useRail } from './Rail';
|
|
30
|
+
import { RailGroupContext, RailGroupDuplicateContext } from './RailGroupContext';
|
|
31
|
+
import { type PolymorphicProps } from './RailItem';
|
|
32
|
+
import { isTourHeld, overlayStack, useFloatingSurface, useInOverlay } from '../_internal/overlay';
|
|
33
|
+
import styles from './Rail.module.scss';
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Runs the consumer's handler, then ours. Used only for the handlers that
|
|
37
|
+
* drive the collapsed-mode flyout on a linkable group — see the comment at
|
|
38
|
+
* the call site for why those five can't simply lose to `{...rest}`. Ours runs
|
|
39
|
+
* unconditionally: opening a flyout is not a cancellable default, so a
|
|
40
|
+
* consumer's `preventDefault()` must not strand the subitems.
|
|
41
|
+
*/
|
|
42
|
+
function composeHandlers<E>(
|
|
43
|
+
theirs: ((e: E) => void) | undefined,
|
|
44
|
+
ours: ((e: E) => void) | undefined,
|
|
45
|
+
) {
|
|
46
|
+
return (e: E) => {
|
|
47
|
+
theirs?.(e);
|
|
48
|
+
ours?.(e);
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Open-delay for hover-intent before opening the collapsed-mode flyout. */
|
|
53
|
+
const OPEN_DELAY_MS = 80;
|
|
54
|
+
/** Close-grace so the cursor has time to traverse from trigger to flyout. */
|
|
55
|
+
const CLOSE_GRACE_MS = 200;
|
|
56
|
+
|
|
57
|
+
interface RailGroupOwnProps {
|
|
58
|
+
/**
|
|
59
|
+
* Required leading icon — the only thing visible when the rail is collapsed.
|
|
60
|
+
* Groups always have an icon; subitems don't need one.
|
|
61
|
+
*/
|
|
62
|
+
icon: ReactNode;
|
|
63
|
+
/**
|
|
64
|
+
* Group label — visible next to the icon when the rail is expanded, and
|
|
65
|
+
* rendered as the flyout's header when collapsed.
|
|
66
|
+
*/
|
|
67
|
+
label: string;
|
|
68
|
+
/**
|
|
69
|
+
* Controlled inline-expand state (only meaningful when the rail itself is
|
|
70
|
+
* expanded — collapsed-mode uses hover-driven popover state instead).
|
|
71
|
+
* Provide alongside `onOpenChange` to drive open state externally.
|
|
72
|
+
*/
|
|
73
|
+
open?: boolean;
|
|
74
|
+
/** Initial open state for the uncontrolled case. Default `false`. */
|
|
75
|
+
defaultOpen?: boolean;
|
|
76
|
+
/** Fires whenever the inline-expand toggles. */
|
|
77
|
+
onOpenChange?: (open: boolean) => void;
|
|
78
|
+
/** Subitems — typically a list of `<Rail.Item>` without icons. */
|
|
79
|
+
children: ReactNode;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Public prop type. Generic `C` defaults to `'div'` — the wrapping element the
|
|
84
|
+
* group has always rendered, so **omitting `as` is exactly today's API**: the
|
|
85
|
+
* group is toggle-only and the remaining props land on the wrapper `<div>`.
|
|
86
|
+
*
|
|
87
|
+
* Passing `as` (e.g. `as={NavLink}`) opts into the **linkable** shape: the
|
|
88
|
+
* icon + label become a navigable element of that type with all of its props
|
|
89
|
+
* available (`to`, `replace`, `end`, …), the chevron becomes its own button,
|
|
90
|
+
* and the remaining props land on the rendered link rather than the wrapper —
|
|
91
|
+
* except `className` and `ref`, which stay on the wrapper `<div>` in both
|
|
92
|
+
* shapes, as they always have.
|
|
93
|
+
*
|
|
94
|
+
* Your `onPointerEnter` / `onPointerLeave` / `onFocus` / `onBlur` / `onClick` / `onKeyDown`
|
|
95
|
+
* on a linkable group are **composed** with the group's own handlers (yours
|
|
96
|
+
* runs first), not replaced by them: those six are what open the
|
|
97
|
+
* collapsed-mode flyout, and overriding them would make the subitems
|
|
98
|
+
* unreachable while the rail is collapsed.
|
|
99
|
+
*/
|
|
100
|
+
export type RailGroupProps<C extends ElementType = 'div'> = PolymorphicProps<C, RailGroupOwnProps>;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Internal generic-preserving signature. React's `forwardRef` strips the
|
|
104
|
+
* generic from the returned component, so we re-attach it via the cast below.
|
|
105
|
+
* Unlike `<Rail.Item>`, the ref type is fixed to the wrapper `<div>` — that is
|
|
106
|
+
* the element the group has always forwarded to, linkable or not.
|
|
107
|
+
*/
|
|
108
|
+
type RailGroupComponent = <C extends ElementType = 'div'>(
|
|
109
|
+
props: RailGroupProps<C> & { ref?: ForwardedRef<HTMLDivElement> },
|
|
110
|
+
) => ReactElement | null;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Implementation-side props. The generic lives only on the exported
|
|
114
|
+
* `RailGroupComponent` signature — inlining it on the `forwardRef` render
|
|
115
|
+
* function would force `C` to widen to the whole `ElementType` union, which
|
|
116
|
+
* collapses the intersection and drops the required `icon` / `label` /
|
|
117
|
+
* `children`. `<Rail.Item>` works around that by making its own props
|
|
118
|
+
* optional; keeping the required ones is worth this extra type instead.
|
|
119
|
+
*/
|
|
120
|
+
type RailGroupImplProps = RailGroupOwnProps & {
|
|
121
|
+
as?: ElementType;
|
|
122
|
+
} & Omit<HTMLAttributes<HTMLDivElement>, 'children'>;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Two-state navigation parent: inline-expanding subitems when expanded, a hover flyout when collapsed; optionally linkable via `as` (`Rail.Group`).
|
|
126
|
+
* @see docs/components/Rail.md
|
|
127
|
+
*/
|
|
128
|
+
export const RailGroup = forwardRef<HTMLDivElement, RailGroupImplProps>(function RailGroup(
|
|
129
|
+
{
|
|
130
|
+
as,
|
|
131
|
+
icon,
|
|
132
|
+
label,
|
|
133
|
+
open: controlledOpen,
|
|
134
|
+
defaultOpen = false,
|
|
135
|
+
onOpenChange,
|
|
136
|
+
children,
|
|
137
|
+
className,
|
|
138
|
+
...rest
|
|
139
|
+
},
|
|
140
|
+
forwardedRef,
|
|
141
|
+
) {
|
|
142
|
+
const t = useTranslation();
|
|
143
|
+
const { collapsed } = useRail();
|
|
144
|
+
|
|
145
|
+
// `as` is the opt-in for the linkable two-target row. Without it the group
|
|
146
|
+
// renders exactly as it always has: one <button> spanning the whole row,
|
|
147
|
+
// with `rest` landing on the wrapping <div>.
|
|
148
|
+
const isLink = as !== undefined;
|
|
149
|
+
const LinkComponent = (as ?? 'div') as ElementType;
|
|
150
|
+
|
|
151
|
+
// ─── Inline expand state (used when rail is expanded) ─────────────────
|
|
152
|
+
const isControlled = controlledOpen !== undefined;
|
|
153
|
+
const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
|
|
154
|
+
const open = isControlled ? (controlledOpen as boolean) : uncontrolledOpen;
|
|
155
|
+
|
|
156
|
+
const setOpen = useCallback(
|
|
157
|
+
(next: boolean) => {
|
|
158
|
+
onOpenChange?.(next);
|
|
159
|
+
if (!isControlled) setUncontrolledOpen(next);
|
|
160
|
+
},
|
|
161
|
+
[isControlled, onOpenChange],
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
const toggleOpen = useCallback(() => setOpen(!open), [open, setOpen]);
|
|
165
|
+
|
|
166
|
+
// ─── Auto-open when the group's own link OR a subitem is active ──────
|
|
167
|
+
// The query below deliberately scans the WHOLE group block, not just
|
|
168
|
+
// `.subitems`: on a linkable group the row's link lives in the same subtree,
|
|
169
|
+
// so landing on /deals opens the group and reveals the nested views. Narrow
|
|
170
|
+
// this to `.subitems` and that behavior silently disappears.
|
|
171
|
+
const groupRef = useRef<HTMLDivElement | null>(null);
|
|
172
|
+
// One-shot guard so we don't re-open the group every render after the
|
|
173
|
+
// consumer manually closed it. Uncontrolled-only by design.
|
|
174
|
+
const autoOpenedRef = useRef(false);
|
|
175
|
+
|
|
176
|
+
useEffect(() => {
|
|
177
|
+
if (isControlled) return;
|
|
178
|
+
if (autoOpenedRef.current) return;
|
|
179
|
+
if (!groupRef.current) return;
|
|
180
|
+
if (uncontrolledOpen) {
|
|
181
|
+
autoOpenedRef.current = true;
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (groupRef.current.querySelector('[aria-current="page"]')) {
|
|
185
|
+
autoOpenedRef.current = true;
|
|
186
|
+
setUncontrolledOpen(true);
|
|
187
|
+
}
|
|
188
|
+
}, [isControlled, uncontrolledOpen]);
|
|
189
|
+
|
|
190
|
+
// ─── Hover-driven popover state (used when rail is collapsed) ────────
|
|
191
|
+
const [popoverOpen, setPopoverOpen] = useState(false);
|
|
192
|
+
// #274: hosts yield Escape while the flyout is open — our own capture
|
|
193
|
+
// listener closes it on the same press instead of the Modal/Drawer.
|
|
194
|
+
useFloatingSurface(popoverOpen);
|
|
195
|
+
const openTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
196
|
+
const closeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
197
|
+
const focusFlyoutOnOpenRef = useRef(false);
|
|
198
|
+
const suppressNextTriggerFocusOpenRef = useRef(false);
|
|
199
|
+
|
|
200
|
+
const clearOpenTimer = useCallback(() => {
|
|
201
|
+
if (openTimerRef.current) {
|
|
202
|
+
clearTimeout(openTimerRef.current);
|
|
203
|
+
openTimerRef.current = null;
|
|
204
|
+
}
|
|
205
|
+
}, []);
|
|
206
|
+
|
|
207
|
+
const clearCloseTimer = useCallback(() => {
|
|
208
|
+
if (closeTimerRef.current) {
|
|
209
|
+
clearTimeout(closeTimerRef.current);
|
|
210
|
+
closeTimerRef.current = null;
|
|
211
|
+
}
|
|
212
|
+
}, []);
|
|
213
|
+
|
|
214
|
+
const scheduleOpen = useCallback(() => {
|
|
215
|
+
clearCloseTimer();
|
|
216
|
+
clearOpenTimer();
|
|
217
|
+
openTimerRef.current = setTimeout(() => {
|
|
218
|
+
openTimerRef.current = null;
|
|
219
|
+
setPopoverOpen(true);
|
|
220
|
+
}, OPEN_DELAY_MS);
|
|
221
|
+
}, [clearCloseTimer, clearOpenTimer]);
|
|
222
|
+
|
|
223
|
+
const scheduleClose = useCallback(() => {
|
|
224
|
+
clearOpenTimer();
|
|
225
|
+
clearCloseTimer();
|
|
226
|
+
closeTimerRef.current = setTimeout(() => {
|
|
227
|
+
closeTimerRef.current = null;
|
|
228
|
+
setPopoverOpen(false);
|
|
229
|
+
}, CLOSE_GRACE_MS);
|
|
230
|
+
}, [clearCloseTimer, clearOpenTimer]);
|
|
231
|
+
|
|
232
|
+
// Cleanup any pending timers on unmount so React doesn't warn about state
|
|
233
|
+
// updates on an unmounted component (and so navigations that swap routes
|
|
234
|
+
// don't leak setTimeouts onto the dead component).
|
|
235
|
+
useEffect(() => {
|
|
236
|
+
return () => {
|
|
237
|
+
clearOpenTimer();
|
|
238
|
+
clearCloseTimer();
|
|
239
|
+
};
|
|
240
|
+
}, [clearOpenTimer, clearCloseTimer]);
|
|
241
|
+
|
|
242
|
+
// Reset popover state whenever the rail's collapsed flag flips. When the
|
|
243
|
+
// rail expands while a flyout was open, the flyout would visually overlap
|
|
244
|
+
// the now-inline subitems — close it eagerly.
|
|
245
|
+
useEffect(() => {
|
|
246
|
+
if (!collapsed) {
|
|
247
|
+
clearOpenTimer();
|
|
248
|
+
clearCloseTimer();
|
|
249
|
+
setPopoverOpen(false);
|
|
250
|
+
}
|
|
251
|
+
}, [collapsed, clearOpenTimer, clearCloseTimer]);
|
|
252
|
+
|
|
253
|
+
// ─── Floating UI for the collapsed-mode flyout ────────────────────────
|
|
254
|
+
// HTMLElement, not HTMLButtonElement: on a linkable group the collapsed-mode
|
|
255
|
+
// trigger is the rendered link, not a button.
|
|
256
|
+
const triggerRef = useRef<HTMLElement | null>(null);
|
|
257
|
+
const placement: Placement = 'right-start';
|
|
258
|
+
const { refs, floatingStyles } = useFloating({
|
|
259
|
+
open: popoverOpen,
|
|
260
|
+
placement,
|
|
261
|
+
transform: false,
|
|
262
|
+
middleware: [
|
|
263
|
+
offset(8),
|
|
264
|
+
flip(),
|
|
265
|
+
shift({ padding: 8 }),
|
|
266
|
+
size({
|
|
267
|
+
apply({ availableWidth, elements }) {
|
|
268
|
+
const width = Math.max(0, availableWidth);
|
|
269
|
+
Object.assign(elements.floating.style, {
|
|
270
|
+
maxWidth: `${width}px`,
|
|
271
|
+
minWidth: `min(var(--rail-flyout-min-width), ${width}px)`,
|
|
272
|
+
});
|
|
273
|
+
},
|
|
274
|
+
padding: 8,
|
|
275
|
+
}),
|
|
276
|
+
],
|
|
277
|
+
whileElementsMounted: autoUpdate,
|
|
278
|
+
elements: { reference: triggerRef.current },
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// #273: the flyout portals to document.body — elevate it above Modal/
|
|
282
|
+
// Drawer (and any other elevated surface), same pattern as the date/time
|
|
283
|
+
// popovers (#272); its base z sits at --z-popover otherwise.
|
|
284
|
+
const inOverlay = useInOverlay(triggerRef, popoverOpen);
|
|
285
|
+
|
|
286
|
+
// #684: focus or the pointer moving into the tour layer while the tour
|
|
287
|
+
// points into this flyout (or its trigger) isn't leaving — the tour focuses
|
|
288
|
+
// its card on every step, and the user moves to Next.
|
|
289
|
+
const scheduleLeaveClose = useCallback(
|
|
290
|
+
(e: { relatedTarget: EventTarget | null }) => {
|
|
291
|
+
if (isTourHeld(e.relatedTarget, refs.floating.current, triggerRef.current)) return;
|
|
292
|
+
scheduleClose();
|
|
293
|
+
},
|
|
294
|
+
[refs.floating, scheduleClose],
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
const isSequentiallyFocusable = useCallback((candidate: HTMLElement, checkVisible = true) => {
|
|
298
|
+
if (candidate.tabIndex < 0) return false;
|
|
299
|
+
if (candidate.matches(':disabled')) return false;
|
|
300
|
+
if (candidate.closest('[hidden], [inert]')) return false;
|
|
301
|
+
if (!checkVisible) return true;
|
|
302
|
+
const style = window.getComputedStyle(candidate);
|
|
303
|
+
if (style.display === 'none' || style.visibility === 'hidden') return false;
|
|
304
|
+
const layoutUnavailable = document.documentElement.getClientRects().length === 0;
|
|
305
|
+
return layoutUnavailable || candidate.getClientRects().length > 0;
|
|
306
|
+
}, []);
|
|
307
|
+
|
|
308
|
+
const getFlyoutFocusableItems = useCallback(
|
|
309
|
+
() =>
|
|
310
|
+
Array.from(refs.floating.current?.querySelectorAll<HTMLElement>('*') ?? []).filter(
|
|
311
|
+
(candidate) => isSequentiallyFocusable(candidate),
|
|
312
|
+
),
|
|
313
|
+
[refs.floating, isSequentiallyFocusable],
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
const hasFlyoutFocusTarget = useCallback(() => {
|
|
317
|
+
if (isLink && triggerRef.current && isSequentiallyFocusable(triggerRef.current, false)) {
|
|
318
|
+
return true;
|
|
319
|
+
}
|
|
320
|
+
const inlineSubitems = groupRef.current?.querySelector(`.${styles.subitems}`);
|
|
321
|
+
return Array.from(inlineSubitems?.querySelectorAll<HTMLElement>('*') ?? []).some((candidate) =>
|
|
322
|
+
isSequentiallyFocusable(candidate, false),
|
|
323
|
+
);
|
|
324
|
+
}, [isLink, isSequentiallyFocusable]);
|
|
325
|
+
|
|
326
|
+
const findNextFocusTargets = useCallback(() => {
|
|
327
|
+
const trigger = triggerRef.current;
|
|
328
|
+
const group = groupRef.current;
|
|
329
|
+
if (!trigger || !group) return [];
|
|
330
|
+
const candidates = Array.from(document.querySelectorAll<HTMLElement>('*'));
|
|
331
|
+
const triggerIndex = candidates.indexOf(trigger);
|
|
332
|
+
return candidates.slice(triggerIndex + 1).filter((candidate) => {
|
|
333
|
+
if (group.contains(candidate)) return false;
|
|
334
|
+
if (refs.floating.current?.contains(candidate)) return false;
|
|
335
|
+
return isSequentiallyFocusable(candidate);
|
|
336
|
+
});
|
|
337
|
+
}, [refs.floating, isSequentiallyFocusable]);
|
|
338
|
+
|
|
339
|
+
const focusFirstAvailable = useCallback((candidates: HTMLElement[]) => {
|
|
340
|
+
for (const candidate of candidates) {
|
|
341
|
+
candidate.focus({ preventScroll: true });
|
|
342
|
+
if (document.activeElement === candidate) return true;
|
|
343
|
+
}
|
|
344
|
+
return false;
|
|
345
|
+
}, []);
|
|
346
|
+
|
|
347
|
+
const focusFirstFlyoutItem = useCallback(() => {
|
|
348
|
+
if (focusFirstAvailable(getFlyoutFocusableItems())) return;
|
|
349
|
+
setPopoverOpen(false);
|
|
350
|
+
if (focusFirstAvailable(findNextFocusTargets())) return;
|
|
351
|
+
// Tab was already cancelled to enter the portal. If no valid destination
|
|
352
|
+
// remains (for example a hidden-only final group), release focus rather
|
|
353
|
+
// than trapping it on the trigger.
|
|
354
|
+
triggerRef.current?.blur();
|
|
355
|
+
}, [getFlyoutFocusableItems, findNextFocusTargets, focusFirstAvailable]);
|
|
356
|
+
|
|
357
|
+
// A portalled panel sits after #root in DOM order, so native Tab traversal
|
|
358
|
+
// cannot move from the trigger into it. When keyboard interaction opens the
|
|
359
|
+
// flyout, move focus to its first interactive element after the portal has
|
|
360
|
+
// mounted. Escape already restores focus to the trigger below.
|
|
361
|
+
useEffect(() => {
|
|
362
|
+
if (!popoverOpen || !focusFlyoutOnOpenRef.current) return;
|
|
363
|
+
focusFlyoutOnOpenRef.current = false;
|
|
364
|
+
focusFirstFlyoutItem();
|
|
365
|
+
}, [popoverOpen, focusFirstFlyoutItem]);
|
|
366
|
+
|
|
367
|
+
// Close on Escape (a11y).
|
|
368
|
+
useEffect(() => {
|
|
369
|
+
if (!popoverOpen) return;
|
|
370
|
+
const onKeyDown = (e: KeyboardEvent) => {
|
|
371
|
+
if (e.key === 'Escape') {
|
|
372
|
+
e.preventDefault(); // consistency with every other floating surface
|
|
373
|
+
overlayStack.consumeEscape(e); // hosts yield even if we ran first (#274)
|
|
374
|
+
clearOpenTimer();
|
|
375
|
+
clearCloseTimer();
|
|
376
|
+
setPopoverOpen(false);
|
|
377
|
+
suppressNextTriggerFocusOpenRef.current = true;
|
|
378
|
+
triggerRef.current?.focus({ preventScroll: true });
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
document.addEventListener('keydown', onKeyDown, true);
|
|
382
|
+
return () => document.removeEventListener('keydown', onKeyDown, true);
|
|
383
|
+
}, [popoverOpen, clearOpenTimer, clearCloseTimer]);
|
|
384
|
+
|
|
385
|
+
// Close eagerly on outside-click — the popover is hover-driven but a click
|
|
386
|
+
// anywhere outside the trigger or panel should still dismiss it (matching
|
|
387
|
+
// the standard floater dismissal pattern).
|
|
388
|
+
useEffect(() => {
|
|
389
|
+
if (!popoverOpen) return;
|
|
390
|
+
const onPointerDown = (e: PointerEvent) => {
|
|
391
|
+
const target = e.target as Node | null;
|
|
392
|
+
if (!target) return;
|
|
393
|
+
if (triggerRef.current?.contains(target)) return;
|
|
394
|
+
if (refs.floating.current?.contains(target)) return;
|
|
395
|
+
// #684: a tour pointing into the flyout doesn't dismiss it.
|
|
396
|
+
if (isTourHeld(target, refs.floating.current, triggerRef.current)) return;
|
|
397
|
+
clearOpenTimer();
|
|
398
|
+
clearCloseTimer();
|
|
399
|
+
setPopoverOpen(false);
|
|
400
|
+
};
|
|
401
|
+
document.addEventListener('pointerdown', onPointerDown, true);
|
|
402
|
+
return () => document.removeEventListener('pointerdown', onPointerDown, true);
|
|
403
|
+
}, [popoverOpen, refs.floating, clearOpenTimer, clearCloseTimer]);
|
|
404
|
+
|
|
405
|
+
// ─── Render ──────────────────────────────────────────────────────────
|
|
406
|
+
const reactId = useId();
|
|
407
|
+
const subitemsId = `rail-group-${reactId}`;
|
|
408
|
+
|
|
409
|
+
const handleTriggerClick = useCallback(() => {
|
|
410
|
+
if (collapsed) return;
|
|
411
|
+
toggleOpen();
|
|
412
|
+
}, [collapsed, toggleOpen]);
|
|
413
|
+
|
|
414
|
+
const handleTriggerKeyDown = useCallback(
|
|
415
|
+
(e: ReactKeyboardEvent<HTMLElement>) => {
|
|
416
|
+
if (collapsed && e.key === 'Tab' && !e.shiftKey) {
|
|
417
|
+
if (!hasFlyoutFocusTarget()) return;
|
|
418
|
+
e.preventDefault();
|
|
419
|
+
clearOpenTimer();
|
|
420
|
+
clearCloseTimer();
|
|
421
|
+
if (popoverOpen) {
|
|
422
|
+
focusFirstFlyoutItem();
|
|
423
|
+
} else {
|
|
424
|
+
focusFlyoutOnOpenRef.current = true;
|
|
425
|
+
setPopoverOpen(true);
|
|
426
|
+
}
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
// In collapsed mode the trigger acts like a popup-haspopup button
|
|
430
|
+
// (Enter / Space opens the popover); in expanded mode native button
|
|
431
|
+
// semantics already cover Enter/Space toggling.
|
|
432
|
+
if (!isLink && collapsed && (e.key === 'Enter' || e.key === ' ')) {
|
|
433
|
+
e.preventDefault();
|
|
434
|
+
clearCloseTimer();
|
|
435
|
+
setPopoverOpen((prev) => !prev);
|
|
436
|
+
}
|
|
437
|
+
},
|
|
438
|
+
[
|
|
439
|
+
collapsed,
|
|
440
|
+
isLink,
|
|
441
|
+
popoverOpen,
|
|
442
|
+
focusFirstFlyoutItem,
|
|
443
|
+
hasFlyoutFocusTarget,
|
|
444
|
+
clearOpenTimer,
|
|
445
|
+
clearCloseTimer,
|
|
446
|
+
],
|
|
447
|
+
);
|
|
448
|
+
|
|
449
|
+
const handlePointerEnter = useCallback(
|
|
450
|
+
(_e: ReactPointerEvent<HTMLElement>) => {
|
|
451
|
+
if (!collapsed) return;
|
|
452
|
+
scheduleOpen();
|
|
453
|
+
},
|
|
454
|
+
[collapsed, scheduleOpen],
|
|
455
|
+
);
|
|
456
|
+
|
|
457
|
+
const handlePointerLeave = useCallback(
|
|
458
|
+
(e: ReactPointerEvent<HTMLElement>) => {
|
|
459
|
+
if (!collapsed) return;
|
|
460
|
+
scheduleLeaveClose(e);
|
|
461
|
+
},
|
|
462
|
+
[collapsed, scheduleLeaveClose],
|
|
463
|
+
);
|
|
464
|
+
|
|
465
|
+
const handleTriggerFocus = useCallback(() => {
|
|
466
|
+
if (suppressNextTriggerFocusOpenRef.current) {
|
|
467
|
+
suppressNextTriggerFocusOpenRef.current = false;
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
scheduleOpen();
|
|
471
|
+
}, [scheduleOpen]);
|
|
472
|
+
|
|
473
|
+
const handleFlyoutPointerEnter = useCallback(() => {
|
|
474
|
+
if (!collapsed) return;
|
|
475
|
+
clearCloseTimer();
|
|
476
|
+
}, [collapsed, clearCloseTimer]);
|
|
477
|
+
|
|
478
|
+
const handleFlyoutPointerLeave = useCallback(
|
|
479
|
+
(e: ReactPointerEvent<HTMLElement>) => {
|
|
480
|
+
if (!collapsed) return;
|
|
481
|
+
scheduleLeaveClose(e);
|
|
482
|
+
},
|
|
483
|
+
[collapsed, scheduleLeaveClose],
|
|
484
|
+
);
|
|
485
|
+
|
|
486
|
+
// Clicking a subitem inside the flyout — or the linkable group's own
|
|
487
|
+
// collapsed-mode link — should dismiss the flyout: any navigation should
|
|
488
|
+
// dismiss the floater per spec.
|
|
489
|
+
const handleFlyoutClick = useCallback(() => {
|
|
490
|
+
if (!collapsed) return;
|
|
491
|
+
clearOpenTimer();
|
|
492
|
+
clearCloseTimer();
|
|
493
|
+
setPopoverOpen(false);
|
|
494
|
+
}, [collapsed, clearOpenTimer, clearCloseTimer]);
|
|
495
|
+
|
|
496
|
+
const handleFlyoutKeyDown = useCallback(
|
|
497
|
+
(e: ReactKeyboardEvent<HTMLDivElement>) => {
|
|
498
|
+
if (e.key !== 'Tab') return;
|
|
499
|
+
const items = getFlyoutFocusableItems();
|
|
500
|
+
if (items.length === 0) return;
|
|
501
|
+
const target = e.target as HTMLElement;
|
|
502
|
+
if (e.shiftKey && target === items[0]) {
|
|
503
|
+
e.preventDefault();
|
|
504
|
+
clearCloseTimer();
|
|
505
|
+
suppressNextTriggerFocusOpenRef.current = true;
|
|
506
|
+
triggerRef.current?.focus({ preventScroll: true });
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
if (!e.shiftKey && target === items.at(-1)) {
|
|
510
|
+
const nextTargets = findNextFocusTargets();
|
|
511
|
+
// If the group is the final page control, preserve native Tab so the
|
|
512
|
+
// browser can move beyond the document instead of trapping focus.
|
|
513
|
+
if (nextTargets.length === 0) return;
|
|
514
|
+
e.preventDefault();
|
|
515
|
+
clearOpenTimer();
|
|
516
|
+
clearCloseTimer();
|
|
517
|
+
setPopoverOpen(false);
|
|
518
|
+
if (!focusFirstAvailable(nextTargets)) triggerRef.current?.blur();
|
|
519
|
+
}
|
|
520
|
+
},
|
|
521
|
+
[
|
|
522
|
+
getFlyoutFocusableItems,
|
|
523
|
+
findNextFocusTargets,
|
|
524
|
+
focusFirstAvailable,
|
|
525
|
+
clearOpenTimer,
|
|
526
|
+
clearCloseTimer,
|
|
527
|
+
],
|
|
528
|
+
);
|
|
529
|
+
|
|
530
|
+
// Compose the consumer ref with our internal ref so consumers can still
|
|
531
|
+
// attach refs to the group's wrapping <div>.
|
|
532
|
+
const setGroupRef = (node: HTMLDivElement | null) => {
|
|
533
|
+
groupRef.current = node;
|
|
534
|
+
if (typeof forwardedRef === 'function') {
|
|
535
|
+
forwardedRef(node);
|
|
536
|
+
} else if (forwardedRef && 'current' in forwardedRef) {
|
|
537
|
+
(forwardedRef as React.MutableRefObject<HTMLDivElement | null>).current = node;
|
|
538
|
+
}
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
const setTriggerRef = (node: HTMLElement | null) => {
|
|
542
|
+
triggerRef.current = node;
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
// The flyout header is a SECOND rendering of the same destination, not a
|
|
546
|
+
// second instance of the consumer's element — so it carries the navigation
|
|
547
|
+
// props but not the identifying ones. A duplicated `id` is invalid HTML, and
|
|
548
|
+
// a duplicated `data-testid` makes `getByTestId` throw on "found multiple",
|
|
549
|
+
// while duplicated `aria-current` would expose two current destinations.
|
|
550
|
+
const headerLinkProps = Object.fromEntries(
|
|
551
|
+
Object.entries(rest).filter(
|
|
552
|
+
([key]) => key !== 'id' && key !== 'aria-current' && !key.startsWith('data-'),
|
|
553
|
+
),
|
|
554
|
+
);
|
|
555
|
+
|
|
556
|
+
const chevron = (
|
|
557
|
+
<ChevronRight
|
|
558
|
+
size={14}
|
|
559
|
+
aria-hidden
|
|
560
|
+
className={clsx(styles.groupChevron, open && styles.groupChevronOpen)}
|
|
561
|
+
/>
|
|
562
|
+
);
|
|
563
|
+
|
|
564
|
+
const groupedChildren = <RailGroupContext.Provider value>{children}</RailGroupContext.Provider>;
|
|
565
|
+
|
|
566
|
+
return (
|
|
567
|
+
<div
|
|
568
|
+
ref={setGroupRef}
|
|
569
|
+
className={clsx(styles.group, className)}
|
|
570
|
+
// Toggle-only groups keep their historical contract: `rest` is div props
|
|
571
|
+
// and lands here. A linkable group's `rest` is the link element's props
|
|
572
|
+
// (`to`, `end`, …) and lands on the link instead.
|
|
573
|
+
{...(isLink ? undefined : rest)}
|
|
574
|
+
>
|
|
575
|
+
{isLink ? (
|
|
576
|
+
<div className={styles.groupRow}>
|
|
577
|
+
{/* The row's link reuses `.item` so hover / focus / the
|
|
578
|
+
[aria-current="page"] active accent all come for free — it IS an
|
|
579
|
+
item row, minus the chevron. */}
|
|
580
|
+
<LinkComponent
|
|
581
|
+
ref={setTriggerRef}
|
|
582
|
+
className={styles.item}
|
|
583
|
+
// Collapsed mode: the single icon-sized target navigates on click
|
|
584
|
+
// and reveals the children on hover/focus, so it advertises the
|
|
585
|
+
// flyout rather than an inline disclosure. Expanded mode: the
|
|
586
|
+
// chevron button below owns aria-expanded / aria-controls.
|
|
587
|
+
aria-haspopup={collapsed ? 'dialog' : undefined}
|
|
588
|
+
// {...rest} last so consumer overrides win (Pattern A), matching
|
|
589
|
+
// <Rail.Item> — EXCEPT these five, which are composed rather than
|
|
590
|
+
// overridable. They are the collapsed-mode flyout's only trigger:
|
|
591
|
+
// if a consumer's own `onPointerEnter` (analytics, say) replaced
|
|
592
|
+
// ours, hover would stop opening the flyout and the subitems would
|
|
593
|
+
// become unreachable entirely — `.collapsed .subitems` is
|
|
594
|
+
// `display: none`, so the flyout is the only path to them. Nothing
|
|
595
|
+
// would warn. Do not "restore consistency" by deleting the
|
|
596
|
+
// composition and letting the spread win.
|
|
597
|
+
{...rest}
|
|
598
|
+
onPointerEnter={composeHandlers(rest.onPointerEnter, handlePointerEnter)}
|
|
599
|
+
onPointerLeave={composeHandlers(rest.onPointerLeave, handlePointerLeave)}
|
|
600
|
+
onFocus={composeHandlers(rest.onFocus, collapsed ? handleTriggerFocus : undefined)}
|
|
601
|
+
onBlur={composeHandlers(rest.onBlur, collapsed ? scheduleLeaveClose : undefined)}
|
|
602
|
+
onClick={composeHandlers(rest.onClick, collapsed ? handleFlyoutClick : undefined)}
|
|
603
|
+
onKeyDown={composeHandlers(
|
|
604
|
+
rest.onKeyDown,
|
|
605
|
+
collapsed ? handleTriggerKeyDown : undefined,
|
|
606
|
+
)}
|
|
607
|
+
>
|
|
608
|
+
<span className={styles.itemIcon} aria-hidden="true">
|
|
609
|
+
{icon}
|
|
610
|
+
</span>
|
|
611
|
+
<span className={styles.itemLabel}>{label}</span>
|
|
612
|
+
</LinkComponent>
|
|
613
|
+
{/* No chevron when collapsed: there is no room for a second target
|
|
614
|
+
at 56px, and hover already reveals the children. */}
|
|
615
|
+
{!collapsed && (
|
|
616
|
+
<button
|
|
617
|
+
type="button"
|
|
618
|
+
className={styles.groupChevronButton}
|
|
619
|
+
aria-expanded={open}
|
|
620
|
+
aria-controls={subitemsId}
|
|
621
|
+
aria-label={`${open ? t('rail.collapseGroup') : t('rail.expandGroup')} ${label}`}
|
|
622
|
+
onClick={toggleOpen}
|
|
623
|
+
>
|
|
624
|
+
{chevron}
|
|
625
|
+
</button>
|
|
626
|
+
)}
|
|
627
|
+
</div>
|
|
628
|
+
) : (
|
|
629
|
+
<button
|
|
630
|
+
ref={setTriggerRef}
|
|
631
|
+
type="button"
|
|
632
|
+
className={styles.groupTrigger}
|
|
633
|
+
// Expanded mode: aria-expanded reflects the inline-disclosure state;
|
|
634
|
+
// collapsed mode: aria-haspopup reflects the flyout (rendered as a
|
|
635
|
+
// dialog-shaped panel).
|
|
636
|
+
aria-expanded={collapsed ? undefined : open}
|
|
637
|
+
aria-controls={collapsed ? undefined : subitemsId}
|
|
638
|
+
aria-haspopup={collapsed ? 'dialog' : undefined}
|
|
639
|
+
onClick={handleTriggerClick}
|
|
640
|
+
onKeyDown={handleTriggerKeyDown}
|
|
641
|
+
onPointerEnter={handlePointerEnter}
|
|
642
|
+
onPointerLeave={handlePointerLeave}
|
|
643
|
+
onFocus={collapsed ? handleTriggerFocus : undefined}
|
|
644
|
+
onBlur={collapsed ? scheduleLeaveClose : undefined}
|
|
645
|
+
>
|
|
646
|
+
<span className={styles.itemIcon} aria-hidden="true">
|
|
647
|
+
{icon}
|
|
648
|
+
</span>
|
|
649
|
+
<span className={styles.itemLabel}>{label}</span>
|
|
650
|
+
{chevron}
|
|
651
|
+
</button>
|
|
652
|
+
)}
|
|
653
|
+
|
|
654
|
+
{/* Expanded-mode inline subitems. When the rail is collapsed, .subitems
|
|
655
|
+
is set to display:none via the .collapsed CSS cascade — we still
|
|
656
|
+
render the DOM so :has([aria-current="page"]) on the .group can
|
|
657
|
+
light up the trigger even while the rail is closed. When the rail
|
|
658
|
+
is expanded but the group is closed, we set hidden so the items
|
|
659
|
+
don't display and aren't in the accessibility tree. */}
|
|
660
|
+
<div
|
|
661
|
+
id={subitemsId}
|
|
662
|
+
className={styles.subitems}
|
|
663
|
+
// `hidden` attribute when expanded + closed (group itself collapsed).
|
|
664
|
+
// We use the boolean form, not `data-hidden`, because the spec wants
|
|
665
|
+
// the items removed from layout AND from the AT tree when closed.
|
|
666
|
+
// In collapsed-rail mode, CSS `display: none` on `.collapsed .subitems`
|
|
667
|
+
// handles the visual hide while keeping the DOM intact for `:has`.
|
|
668
|
+
hidden={!collapsed && !open}
|
|
669
|
+
>
|
|
670
|
+
{groupedChildren}
|
|
671
|
+
</div>
|
|
672
|
+
|
|
673
|
+
{/* Collapsed-mode flyout popover. Portaled to document.body, positioned
|
|
674
|
+
by Floating UI on the right of the trigger. */}
|
|
675
|
+
{collapsed &&
|
|
676
|
+
popoverOpen &&
|
|
677
|
+
createPortal(
|
|
678
|
+
<div
|
|
679
|
+
ref={refs.setFloating}
|
|
680
|
+
role="dialog"
|
|
681
|
+
data-in-overlay={inOverlay ? '' : undefined}
|
|
682
|
+
aria-label={label}
|
|
683
|
+
style={floatingStyles}
|
|
684
|
+
className={styles.flyout}
|
|
685
|
+
onPointerEnter={handleFlyoutPointerEnter}
|
|
686
|
+
onPointerLeave={handleFlyoutPointerLeave}
|
|
687
|
+
onClick={handleFlyoutClick}
|
|
688
|
+
onKeyDown={handleFlyoutKeyDown}
|
|
689
|
+
// Keyboard-tab traversal from the trigger into a subitem fires the
|
|
690
|
+
// trigger's onBlur. Without these handlers, the 200ms close timer
|
|
691
|
+
// would fire and unmount the flyout mid-tab. onFocus on the panel
|
|
692
|
+
// (capturing focus via descendant) cancels any pending close;
|
|
693
|
+
// onBlur re-schedules only when focus leaves the panel entirely.
|
|
694
|
+
onFocus={clearCloseTimer}
|
|
695
|
+
onBlur={(e) => {
|
|
696
|
+
if (!e.currentTarget.contains(e.relatedTarget as Node | null)) {
|
|
697
|
+
scheduleLeaveClose(e);
|
|
698
|
+
}
|
|
699
|
+
}}
|
|
700
|
+
>
|
|
701
|
+
{/* A linkable group's flyout header links to the same destination
|
|
702
|
+
so the parent page stays reachable once the panel is open —
|
|
703
|
+
collapsed mode has no chevron, so the row's own target is the
|
|
704
|
+
only other way there. */}
|
|
705
|
+
<div className={styles.flyoutHeader}>
|
|
706
|
+
{isLink ? (
|
|
707
|
+
<LinkComponent
|
|
708
|
+
className={styles.flyoutHeaderLink}
|
|
709
|
+
{...headerLinkProps}
|
|
710
|
+
aria-current={false}
|
|
711
|
+
>
|
|
712
|
+
{label}
|
|
713
|
+
</LinkComponent>
|
|
714
|
+
) : (
|
|
715
|
+
label
|
|
716
|
+
)}
|
|
717
|
+
</div>
|
|
718
|
+
<div className={styles.flyoutBody}>
|
|
719
|
+
<RailGroupDuplicateContext.Provider value>
|
|
720
|
+
{groupedChildren}
|
|
721
|
+
</RailGroupDuplicateContext.Provider>
|
|
722
|
+
</div>
|
|
723
|
+
</div>,
|
|
724
|
+
document.body,
|
|
725
|
+
)}
|
|
726
|
+
</div>
|
|
727
|
+
);
|
|
728
|
+
}) as RailGroupComponent;
|