@eocrm/design-system 0.0.0-stage → 0.6.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI-PRIMER.md +341 -0
- package/LICENSE +202 -0
- package/README.md +266 -2
- package/docs/components/Accordion.md +114 -0
- package/docs/components/AgentAvatar.md +58 -0
- package/docs/components/Alert.md +81 -0
- package/docs/components/AppLayout.md +70 -0
- package/docs/components/Avatar.md +49 -0
- package/docs/components/AvatarGroup.md +47 -0
- package/docs/components/Badge.md +60 -0
- package/docs/components/Banner.md +89 -0
- package/docs/components/BrandIcon.md +32 -0
- package/docs/components/Breadcrumb.md +72 -0
- package/docs/components/Button.md +107 -0
- package/docs/components/ButtonGroup.md +78 -0
- package/docs/components/Calendar.md +158 -0
- package/docs/components/Card.md +165 -0
- package/docs/components/CatalogPicker.md +83 -0
- package/docs/components/Chart.md +114 -0
- package/docs/components/ChatBubble.md +55 -0
- package/docs/components/ChatLauncher.md +97 -0
- package/docs/components/Checkbox.md +55 -0
- package/docs/components/CircularProgress.md +53 -0
- package/docs/components/Cluster.md +96 -0
- package/docs/components/Code.md +35 -0
- package/docs/components/CodeBlock.md +67 -0
- package/docs/components/ColorPicker.md +115 -0
- package/docs/components/ConfirmationPopover.md +70 -0
- package/docs/components/Constrain.md +39 -0
- package/docs/components/CurrencySelect.md +57 -0
- package/docs/components/CursorPagination.md +43 -0
- package/docs/components/DashboardCanvas.md +79 -0
- package/docs/components/DashboardWidget.md +131 -0
- package/docs/components/DataTable.md +88 -0
- package/docs/components/DatePicker.md +68 -0
- package/docs/components/DateRangePicker.md +71 -0
- package/docs/components/DateStrip.md +56 -0
- package/docs/components/DefinitionList.md +82 -0
- package/docs/components/Divider.md +57 -0
- package/docs/components/Dot.md +26 -0
- package/docs/components/Drawer.md +94 -0
- package/docs/components/DropdownMenu.md +299 -0
- package/docs/components/EmojiPicker.md +84 -0
- package/docs/components/EmptyState.md +55 -0
- package/docs/components/EntityChip.md +102 -0
- package/docs/components/ErrorState.md +72 -0
- package/docs/components/Field.md +91 -0
- package/docs/components/FileUpload.md +109 -0
- package/docs/components/FilterChip.md +88 -0
- package/docs/components/FlowCanvas.md +108 -0
- package/docs/components/FormRow.md +31 -0
- package/docs/components/FormSection.md +37 -0
- package/docs/components/Grid.md +103 -0
- package/docs/components/Highlight.md +75 -0
- package/docs/components/HighlightedText.md +50 -0
- package/docs/components/IconPicker.md +134 -0
- package/docs/components/IconTile.md +30 -0
- package/docs/components/Image.md +84 -0
- package/docs/components/ImageCrop.md +163 -0
- package/docs/components/Indent.md +31 -0
- package/docs/components/InlineDatePicker.md +58 -0
- package/docs/components/InlineDateRangePicker.md +57 -0
- package/docs/components/Input.md +54 -0
- package/docs/components/Kanban.md +122 -0
- package/docs/components/Kbd.md +41 -0
- package/docs/components/Lightbox.md +105 -0
- package/docs/components/Link.md +65 -0
- package/docs/components/LinkCard.md +41 -0
- package/docs/components/LiquidEditor.md +84 -0
- package/docs/components/List.md +68 -0
- package/docs/components/LiveRegion.md +29 -0
- package/docs/components/LocaleProvider.md +25 -0
- package/docs/components/Logo.md +41 -0
- package/docs/components/Masonry.md +48 -0
- package/docs/components/MediaTile.md +95 -0
- package/docs/components/Modal.md +107 -0
- package/docs/components/MoneyInput.md +62 -0
- package/docs/components/OptionsPicker.md +123 -0
- package/docs/components/OtpInput.md +65 -0
- package/docs/components/Page.md +35 -0
- package/docs/components/PageHeader.md +133 -0
- package/docs/components/Pagination.md +44 -0
- package/docs/components/Palette.md +32 -0
- package/docs/components/PasswordInput.md +45 -0
- package/docs/components/PasswordStrengthMeter.md +27 -0
- package/docs/components/PersonDisplay.md +153 -0
- package/docs/components/PhoneInput.md +54 -0
- package/docs/components/PillMenu.md +91 -0
- package/docs/components/Popover.md +127 -0
- package/docs/components/Progress.md +56 -0
- package/docs/components/QrCode.md +34 -0
- package/docs/components/Radio.md +37 -0
- package/docs/components/RadioGroup.md +56 -0
- package/docs/components/Rail.md +191 -0
- package/docs/components/RelativeDateInput.md +114 -0
- package/docs/components/RichText.md +44 -0
- package/docs/components/RichTextEditor.md +112 -0
- package/docs/components/Screen.md +37 -0
- package/docs/components/ScrollArea.md +39 -0
- package/docs/components/Select.md +131 -0
- package/docs/components/SettingRow.md +98 -0
- package/docs/components/Skeleton.md +68 -0
- package/docs/components/Slider.md +92 -0
- package/docs/components/SlotGrid.md +55 -0
- package/docs/components/SocialButton.md +31 -0
- package/docs/components/Sortable.md +127 -0
- package/docs/components/SortableGroup.md +52 -0
- package/docs/components/Sparkline.md +51 -0
- package/docs/components/Split.md +76 -0
- package/docs/components/Stack.md +59 -0
- package/docs/components/StagePath.md +66 -0
- package/docs/components/StatGroup.md +61 -0
- package/docs/components/StatTile.md +58 -0
- package/docs/components/Sticky.md +69 -0
- package/docs/components/Switch.md +89 -0
- package/docs/components/Table.md +184 -0
- package/docs/components/TableOfContents.md +76 -0
- package/docs/components/Tabs.md +94 -0
- package/docs/components/Text.md +63 -0
- package/docs/components/Textarea.md +59 -0
- package/docs/components/Thread.md +52 -0
- package/docs/components/TimeField.md +70 -0
- package/docs/components/Timeline.md +57 -0
- package/docs/components/Title.md +54 -0
- package/docs/components/ToastViewport.md +61 -0
- package/docs/components/Tooltip.md +63 -0
- package/docs/components/TopBar.md +214 -0
- package/docs/components/Tour.md +85 -0
- package/docs/components/TreeView.md +113 -0
- package/docs/components/VisuallyHidden.md +43 -0
- package/docs/components/WidgetPreview.md +54 -0
- package/docs/components/useBelowBreakpoint.md +11 -0
- package/docs/components/useMonth.md +18 -0
- package/docs/setup.md +51 -0
- package/docs/theming.md +95 -0
- package/docs/tokens.md +123 -0
- package/docs/transient-state.md +56 -0
- package/package.json +86 -4
- package/src/_meta/manifest.ts +293 -0
- package/src/app/AppProvider.tsx +78 -0
- package/src/app/index.ts +3 -0
- package/src/app/themeTokens.ts +95 -0
- package/src/calendar/dateMath.ts +114 -0
- package/src/calendar/formatters.ts +75 -0
- package/src/calendar/index.ts +39 -0
- package/src/calendar/types.ts +36 -0
- package/src/calendar/useAgenda.ts +70 -0
- package/src/calendar/useDay.ts +51 -0
- package/src/calendar/useMonth.ts +82 -0
- package/src/calendar/useWeek.ts +62 -0
- package/src/calendar/weekInfo.ts +83 -0
- package/src/components/Accordion/Accordion.module.scss +304 -0
- package/src/components/Accordion/Accordion.tokens.scss +64 -0
- package/src/components/Accordion/Accordion.tsx +272 -0
- package/src/components/Accordion/AccordionContent.tsx +36 -0
- package/src/components/Accordion/AccordionItem.tsx +66 -0
- package/src/components/Accordion/AccordionTrigger.tsx +121 -0
- package/src/components/Accordion/context.ts +47 -0
- package/src/components/Accordion/index.ts +14 -0
- package/src/components/Alert/Alert.module.scss +92 -0
- package/src/components/Alert/Alert.tokens.scss +60 -0
- package/src/components/Alert/Alert.tsx +136 -0
- package/src/components/Alert/index.ts +2 -0
- package/src/components/AppLayout/AppLayout.module.scss +130 -0
- package/src/components/AppLayout/AppLayout.tokens.scss +27 -0
- package/src/components/AppLayout/AppLayout.tsx +211 -0
- package/src/components/AppLayout/index.ts +2 -0
- package/src/components/Avatar/AgentAvatar.module.scss +117 -0
- package/src/components/Avatar/AgentAvatar.tsx +122 -0
- package/src/components/Avatar/Avatar.module.scss +181 -0
- package/src/components/Avatar/Avatar.tokens.scss +107 -0
- package/src/components/Avatar/Avatar.tsx +210 -0
- package/src/components/Avatar/AvatarGroup.module.scss +128 -0
- package/src/components/Avatar/AvatarGroup.tsx +119 -0
- package/src/components/Avatar/AvatarGroupContext.tsx +20 -0
- package/src/components/Avatar/index.ts +6 -0
- package/src/components/Badge/Badge.module.scss +124 -0
- package/src/components/Badge/Badge.tokens.scss +74 -0
- package/src/components/Badge/Badge.tsx +164 -0
- package/src/components/Badge/index.ts +2 -0
- package/src/components/Banner/Banner.module.scss +73 -0
- package/src/components/Banner/Banner.tokens.scss +51 -0
- package/src/components/Banner/Banner.tsx +138 -0
- package/src/components/Banner/index.ts +2 -0
- package/src/components/BrandIcon/BrandIcon.module.scss +5 -0
- package/src/components/BrandIcon/BrandIcon.tsx +99 -0
- package/src/components/BrandIcon/index.ts +2 -0
- package/src/components/Breadcrumb/Breadcrumb.module.scss +32 -0
- package/src/components/Breadcrumb/Breadcrumb.tokens.scss +9 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +146 -0
- package/src/components/Breadcrumb/index.ts +2 -0
- package/src/components/Button/Button.module.scss +167 -0
- package/src/components/Button/Button.tokens.scss +90 -0
- package/src/components/Button/Button.tsx +205 -0
- package/src/components/Button/index.ts +2 -0
- package/src/components/ButtonGroup/ButtonGroup.module.scss +134 -0
- package/src/components/ButtonGroup/ButtonGroup.tokens.scss +42 -0
- package/src/components/ButtonGroup/ButtonGroup.tsx +278 -0
- package/src/components/ButtonGroup/ButtonGroupItem.tsx +74 -0
- package/src/components/ButtonGroup/context.ts +45 -0
- package/src/components/ButtonGroup/index.ts +2 -0
- package/src/components/Calendar/AgendaView.module.scss +231 -0
- package/src/components/Calendar/AgendaView.tsx +214 -0
- package/src/components/Calendar/AllDayBand.module.scss +18 -0
- package/src/components/Calendar/AllDayBand.tsx +75 -0
- package/src/components/Calendar/Calendar.module.scss +23 -0
- package/src/components/Calendar/Calendar.tokens.scss +262 -0
- package/src/components/Calendar/Calendar.tsx +370 -0
- package/src/components/Calendar/DayCell.module.scss +30 -0
- package/src/components/Calendar/DayCell.tsx +50 -0
- package/src/components/Calendar/DayView.module.scss +10 -0
- package/src/components/Calendar/DayView.tsx +163 -0
- package/src/components/Calendar/EventChip.module.scss +171 -0
- package/src/components/Calendar/EventChip.tsx +115 -0
- package/src/components/Calendar/HourGrid.module.scss +123 -0
- package/src/components/Calendar/HourGrid.tsx +381 -0
- package/src/components/Calendar/MonthView.module.scss +99 -0
- package/src/components/Calendar/MonthView.tsx +296 -0
- package/src/components/Calendar/TimedEvent.module.scss +205 -0
- package/src/components/Calendar/TimedEvent.tsx +247 -0
- package/src/components/Calendar/ViewSwitcher.module.scss +3 -0
- package/src/components/Calendar/ViewSwitcher.tsx +47 -0
- package/src/components/Calendar/WeekView.module.scss +10 -0
- package/src/components/Calendar/WeekView.tsx +137 -0
- package/src/components/Calendar/eventColor.ts +60 -0
- package/src/components/Calendar/index.ts +18 -0
- package/src/components/Calendar/types.ts +451 -0
- package/src/components/Calendar/useEventDrag.ts +783 -0
- package/src/components/Calendar/utils.ts +622 -0
- package/src/components/Card/Card.module.scss +264 -0
- package/src/components/Card/Card.tokens.scss +55 -0
- package/src/components/Card/Card.tsx +170 -0
- package/src/components/Card/CardBody.tsx +45 -0
- package/src/components/Card/CardHeader.tsx +113 -0
- package/src/components/Card/CardList.tsx +24 -0
- package/src/components/Card/CardListRow.tsx +24 -0
- package/src/components/Card/index.ts +7 -0
- package/src/components/CatalogPicker/CatalogPicker.module.scss +193 -0
- package/src/components/CatalogPicker/CatalogPicker.tokens.scss +26 -0
- package/src/components/CatalogPicker/CatalogPicker.tsx +339 -0
- package/src/components/CatalogPicker/index.ts +2 -0
- package/src/components/Chart/Chart.module.scss +287 -0
- package/src/components/Chart/Chart.tokens.scss +63 -0
- package/src/components/Chart/Chart.tsx +607 -0
- package/src/components/Chart/ChartLegend.tsx +99 -0
- package/src/components/Chart/ChartTable.tsx +62 -0
- package/src/components/Chart/ChartTooltip.tsx +91 -0
- package/src/components/Chart/chartModel.ts +689 -0
- package/src/components/Chart/index.ts +2 -0
- package/src/components/ChatBubble/ChatBubble.module.scss +93 -0
- package/src/components/ChatBubble/ChatBubble.tokens.scss +17 -0
- package/src/components/ChatBubble/ChatBubble.tsx +61 -0
- package/src/components/ChatBubble/ChatBubbleList.tsx +27 -0
- package/src/components/ChatBubble/index.ts +3 -0
- package/src/components/ChatLauncher/ChatLauncher.module.scss +68 -0
- package/src/components/ChatLauncher/ChatLauncher.tokens.scss +27 -0
- package/src/components/ChatLauncher/ChatLauncher.tsx +202 -0
- package/src/components/ChatLauncher/index.ts +2 -0
- package/src/components/ChatLauncher/isAtBottom.ts +12 -0
- package/src/components/Checkbox/Checkbox.module.scss +147 -0
- package/src/components/Checkbox/Checkbox.tokens.scss +44 -0
- package/src/components/Checkbox/Checkbox.tsx +188 -0
- package/src/components/Checkbox/index.ts +2 -0
- package/src/components/CircularProgress/CircularProgress.module.scss +133 -0
- package/src/components/CircularProgress/CircularProgress.tokens.scss +40 -0
- package/src/components/CircularProgress/CircularProgress.tsx +139 -0
- package/src/components/CircularProgress/index.ts +7 -0
- package/src/components/Cluster/Cluster.module.scss +145 -0
- package/src/components/Cluster/Cluster.tokens.scss +11 -0
- package/src/components/Cluster/Cluster.tsx +215 -0
- package/src/components/Cluster/index.ts +2 -0
- package/src/components/Code/Code.module.scss +28 -0
- package/src/components/Code/Code.tokens.scss +15 -0
- package/src/components/Code/Code.tsx +44 -0
- package/src/components/Code/index.ts +2 -0
- package/src/components/CodeBlock/CodeBlock.module.scss +146 -0
- package/src/components/CodeBlock/CodeBlock.tokens.scss +27 -0
- package/src/components/CodeBlock/CodeBlock.tsx +274 -0
- package/src/components/CodeBlock/highlight.ts +179 -0
- package/src/components/CodeBlock/index.ts +8 -0
- package/src/components/CodeBlock/sampleSync.ts +42 -0
- package/src/components/ColorPicker/ColorPicker.module.scss +286 -0
- package/src/components/ColorPicker/ColorPicker.tokens.scss +60 -0
- package/src/components/ColorPicker/ColorPicker.tsx +367 -0
- package/src/components/ColorPicker/ColorPickerPanel.tsx +265 -0
- package/src/components/ColorPicker/SVSquare.tsx +189 -0
- package/src/components/ColorPicker/colorMath.ts +141 -0
- package/src/components/ColorPicker/index.ts +6 -0
- package/src/components/ConfirmationPopover/ConfirmationPopover.module.scss +39 -0
- package/src/components/ConfirmationPopover/ConfirmationPopover.tokens.scss +13 -0
- package/src/components/ConfirmationPopover/ConfirmationPopover.tsx +395 -0
- package/src/components/ConfirmationPopover/index.ts +2 -0
- package/src/components/Constrain/Constrain.module.scss +99 -0
- package/src/components/Constrain/Constrain.tsx +79 -0
- package/src/components/Constrain/index.ts +2 -0
- package/src/components/CurrencySelect/CurrencySelect.module.scss +7 -0
- package/src/components/CurrencySelect/CurrencySelect.tsx +167 -0
- package/src/components/CurrencySelect/index.ts +3 -0
- package/src/components/CursorPagination/CursorPagination.module.scss +69 -0
- package/src/components/CursorPagination/CursorPagination.tokens.scss +32 -0
- package/src/components/CursorPagination/CursorPagination.tsx +121 -0
- package/src/components/CursorPagination/index.ts +2 -0
- package/src/components/DashboardCanvas/DashboardCanvas.module.scss +360 -0
- package/src/components/DashboardCanvas/DashboardCanvas.tokens.scss +48 -0
- package/src/components/DashboardCanvas/DashboardCanvas.tsx +1270 -0
- package/src/components/DashboardCanvas/DashboardCanvasItem.tsx +140 -0
- package/src/components/DashboardCanvas/DashboardCanvasSection.tsx +174 -0
- package/src/components/DashboardCanvas/engine.ts +363 -0
- package/src/components/DashboardCanvas/index.ts +9 -0
- package/src/components/DashboardWidget/DashboardWidget.module.scss +100 -0
- package/src/components/DashboardWidget/DashboardWidget.tokens.scss +16 -0
- package/src/components/DashboardWidget/DashboardWidget.tsx +188 -0
- package/src/components/DashboardWidget/index.ts +7 -0
- package/src/components/DataTable/BodyRow.tsx +197 -0
- package/src/components/DataTable/ColumnVisibilityTrigger.module.scss +7 -0
- package/src/components/DataTable/ColumnVisibilityTrigger.tsx +105 -0
- package/src/components/DataTable/DataTable.module.scss +511 -0
- package/src/components/DataTable/DataTable.tokens.scss +80 -0
- package/src/components/DataTable/DataTable.tsx +734 -0
- package/src/components/DataTable/HeaderCell.module.scss +215 -0
- package/src/components/DataTable/HeaderCell.tsx +440 -0
- package/src/components/DataTable/columnShift.ts +117 -0
- package/src/components/DataTable/index.ts +23 -0
- package/src/components/DataTable/pinStyle.ts +47 -0
- package/src/components/DataTable/reorderColumns.ts +66 -0
- package/src/components/DataTable/types.ts +289 -0
- package/src/components/DataTable/useColumnDragShift.ts +216 -0
- package/src/components/DataTable/useDataTable.ts +372 -0
- package/src/components/DataTable/useResizeHandle.ts +97 -0
- package/src/components/DatePicker/DatePicker.module.scss +180 -0
- package/src/components/DatePicker/DatePicker.tokens.scss +152 -0
- package/src/components/DatePicker/DatePicker.tsx +664 -0
- package/src/components/DatePicker/DatePickerGrid.module.scss +172 -0
- package/src/components/DatePicker/DatePickerGrid.tsx +341 -0
- package/src/components/DatePicker/InlineDatePicker.module.scss +32 -0
- package/src/components/DatePicker/InlineDatePicker.tsx +201 -0
- package/src/components/DatePicker/index.ts +4 -0
- package/src/components/DatePicker/utils.ts +364 -0
- package/src/components/DateRangePicker/DateRangePicker.module.scss +237 -0
- package/src/components/DateRangePicker/DateRangePicker.tokens.scss +78 -0
- package/src/components/DateRangePicker/DateRangePicker.tsx +720 -0
- package/src/components/DateRangePicker/InlineDateRangePicker.module.scss +94 -0
- package/src/components/DateRangePicker/InlineDateRangePicker.tsx +376 -0
- package/src/components/DateRangePicker/index.ts +5 -0
- package/src/components/DateRangePicker/utils.ts +151 -0
- package/src/components/DateStrip/DateStrip.module.scss +78 -0
- package/src/components/DateStrip/DateStrip.tokens.scss +23 -0
- package/src/components/DateStrip/DateStrip.tsx +205 -0
- package/src/components/DateStrip/index.ts +2 -0
- package/src/components/DefinitionList/DefinitionList.module.scss +102 -0
- package/src/components/DefinitionList/DefinitionList.tokens.scss +29 -0
- package/src/components/DefinitionList/DefinitionList.tsx +198 -0
- package/src/components/DefinitionList/index.ts +9 -0
- package/src/components/Divider/Divider.module.scss +144 -0
- package/src/components/Divider/Divider.tokens.scss +21 -0
- package/src/components/Divider/Divider.tsx +103 -0
- package/src/components/Divider/index.ts +2 -0
- package/src/components/Dot/Dot.module.scss +40 -0
- package/src/components/Dot/Dot.tokens.scss +4 -0
- package/src/components/Dot/Dot.tsx +45 -0
- package/src/components/Dot/index.ts +2 -0
- package/src/components/Drawer/Body.tsx +23 -0
- package/src/components/Drawer/Close.tsx +35 -0
- package/src/components/Drawer/Content.tsx +93 -0
- package/src/components/Drawer/Drawer.module.scss +232 -0
- package/src/components/Drawer/Drawer.tokens.scss +38 -0
- package/src/components/Drawer/Drawer.tsx +23 -0
- package/src/components/Drawer/DrawerRoot.tsx +190 -0
- package/src/components/Drawer/Footer.tsx +24 -0
- package/src/components/Drawer/Header.tsx +64 -0
- package/src/components/Drawer/Overlay.tsx +82 -0
- package/src/components/Drawer/context.ts +44 -0
- package/src/components/Drawer/index.ts +12 -0
- package/src/components/Drawer/useDragToClose.ts +149 -0
- package/src/components/DropdownMenu/CheckboxItem.tsx +144 -0
- package/src/components/DropdownMenu/Content.tsx +419 -0
- package/src/components/DropdownMenu/DropdownMenu.module.scss +280 -0
- package/src/components/DropdownMenu/DropdownMenu.tokens.scss +88 -0
- package/src/components/DropdownMenu/DropdownMenu.tsx +43 -0
- package/src/components/DropdownMenu/Group.tsx +76 -0
- package/src/components/DropdownMenu/Item.tsx +148 -0
- package/src/components/DropdownMenu/ItemIndicator.tsx +30 -0
- package/src/components/DropdownMenu/Radio.tsx +178 -0
- package/src/components/DropdownMenu/Root.tsx +100 -0
- package/src/components/DropdownMenu/Sub.tsx +332 -0
- package/src/components/DropdownMenu/Trigger.tsx +76 -0
- package/src/components/DropdownMenu/context.ts +65 -0
- package/src/components/DropdownMenu/index.ts +20 -0
- package/src/components/EmojiPicker/EmojiPicker.module.scss +84 -0
- package/src/components/EmojiPicker/EmojiPicker.tokens.scss +24 -0
- package/src/components/EmojiPicker/EmojiPicker.tsx +341 -0
- package/src/components/EmojiPicker/emojiData.ts +245 -0
- package/src/components/EmojiPicker/index.ts +3 -0
- package/src/components/EmptyState/EmptyState.module.scss +102 -0
- package/src/components/EmptyState/EmptyState.tokens.scss +28 -0
- package/src/components/EmptyState/EmptyState.tsx +112 -0
- package/src/components/EmptyState/index.ts +7 -0
- package/src/components/EntityChip/EntityChip.module.scss +275 -0
- package/src/components/EntityChip/EntityChip.tokens.scss +66 -0
- package/src/components/EntityChip/EntityChip.tsx +649 -0
- package/src/components/EntityChip/index.ts +10 -0
- package/src/components/ErrorState/ErrorState.module.scss +105 -0
- package/src/components/ErrorState/ErrorState.tokens.scss +32 -0
- package/src/components/ErrorState/ErrorState.tsx +125 -0
- package/src/components/ErrorState/index.ts +8 -0
- package/src/components/Field/Field.module.scss +46 -0
- package/src/components/Field/Field.tsx +185 -0
- package/src/components/Field/index.ts +2 -0
- package/src/components/FileUpload/FileUpload.module.scss +187 -0
- package/src/components/FileUpload/FileUpload.tokens.scss +81 -0
- package/src/components/FileUpload/FileUpload.tsx +569 -0
- package/src/components/FileUpload/formatBytes.ts +34 -0
- package/src/components/FileUpload/iconForFile.ts +40 -0
- package/src/components/FileUpload/index.ts +2 -0
- package/src/components/FilterChip/FilterChip.module.scss +61 -0
- package/src/components/FilterChip/FilterChip.tokens.scss +25 -0
- package/src/components/FilterChip/FilterChip.tsx +208 -0
- package/src/components/FilterChip/index.ts +5 -0
- package/src/components/FlowCanvas/FlowCanvas.module.scss +329 -0
- package/src/components/FlowCanvas/FlowCanvas.tokens.scss +45 -0
- package/src/components/FlowCanvas/FlowCanvas.tsx +1867 -0
- package/src/components/FlowCanvas/FlowControls.tsx +46 -0
- package/src/components/FlowCanvas/FlowEdge.tsx +58 -0
- package/src/components/FlowCanvas/FlowNode.tsx +76 -0
- package/src/components/FlowCanvas/edgePath.ts +85 -0
- package/src/components/FlowCanvas/index.ts +4 -0
- package/src/components/FlowCanvas/layout.ts +148 -0
- package/src/components/FlowCanvas/spatialNav.ts +76 -0
- package/src/components/FlowCanvas/types.ts +59 -0
- package/src/components/FlowCanvas/useViewport.ts +122 -0
- package/src/components/FormRow/FormRow.module.scss +2 -0
- package/src/components/FormRow/FormRow.tsx +37 -0
- package/src/components/FormRow/index.ts +2 -0
- package/src/components/FormSection/FormSection.module.scss +24 -0
- package/src/components/FormSection/FormSection.tsx +46 -0
- package/src/components/FormSection/index.ts +2 -0
- package/src/components/Grid/Grid.module.scss +162 -0
- package/src/components/Grid/Grid.tokens.scss +13 -0
- package/src/components/Grid/Grid.tsx +226 -0
- package/src/components/Grid/GridItem.tsx +77 -0
- package/src/components/Grid/index.ts +11 -0
- package/src/components/Highlight/Highlight.module.scss +43 -0
- package/src/components/Highlight/Highlight.tokens.scss +35 -0
- package/src/components/Highlight/Highlight.tsx +164 -0
- package/src/components/Highlight/HighlightOverlay.tsx +100 -0
- package/src/components/Highlight/index.ts +2 -0
- package/src/components/HighlightedText/HighlightedText.module.scss +11 -0
- package/src/components/HighlightedText/HighlightedText.tokens.scss +9 -0
- package/src/components/HighlightedText/HighlightedText.tsx +50 -0
- package/src/components/HighlightedText/highlightRanges.ts +44 -0
- package/src/components/HighlightedText/index.ts +2 -0
- package/src/components/IconPicker/IconPicker.module.scss +175 -0
- package/src/components/IconPicker/IconPicker.tokens.scss +40 -0
- package/src/components/IconPicker/IconPicker.tsx +629 -0
- package/src/components/IconPicker/index.ts +9 -0
- package/src/components/IconTile/IconTile.module.scss +57 -0
- package/src/components/IconTile/IconTile.tokens.scss +16 -0
- package/src/components/IconTile/IconTile.tsx +91 -0
- package/src/components/IconTile/index.ts +2 -0
- package/src/components/Image/Image.module.scss +266 -0
- package/src/components/Image/Image.tokens.scss +55 -0
- package/src/components/Image/Image.tsx +342 -0
- package/src/components/Image/index.ts +2 -0
- package/src/components/ImageCrop/ImageCrop.module.scss +274 -0
- package/src/components/ImageCrop/ImageCrop.tokens.scss +33 -0
- package/src/components/ImageCrop/ImageCrop.tsx +542 -0
- package/src/components/ImageCrop/cropGeometry.ts +120 -0
- package/src/components/ImageCrop/extractCropBlob.ts +140 -0
- package/src/components/ImageCrop/index.ts +11 -0
- package/src/components/ImageCrop/useCropPreview.ts +161 -0
- package/src/components/Indent/Indent.module.scss +33 -0
- package/src/components/Indent/Indent.tokens.scss +10 -0
- package/src/components/Indent/Indent.tsx +46 -0
- package/src/components/Indent/index.ts +2 -0
- package/src/components/Input/Input.module.scss +99 -0
- package/src/components/Input/Input.tokens.scss +54 -0
- package/src/components/Input/Input.tsx +105 -0
- package/src/components/Input/Suggestions.tsx +260 -0
- package/src/components/Input/index.ts +2 -0
- package/src/components/Kanban/Kanban.module.scss +39 -0
- package/src/components/Kanban/Kanban.tokens.scss +15 -0
- package/src/components/Kanban/Kanban.tsx +951 -0
- package/src/components/Kanban/index.ts +7 -0
- package/src/components/Kbd/Kbd.module.scss +47 -0
- package/src/components/Kbd/Kbd.tokens.scss +26 -0
- package/src/components/Kbd/Kbd.tsx +73 -0
- package/src/components/Kbd/index.ts +2 -0
- package/src/components/Lightbox/Lightbox.module.scss +283 -0
- package/src/components/Lightbox/Lightbox.tokens.scss +36 -0
- package/src/components/Lightbox/Lightbox.tsx +506 -0
- package/src/components/Lightbox/index.ts +2 -0
- package/src/components/Link/Link.module.scss +78 -0
- package/src/components/Link/Link.tokens.scss +28 -0
- package/src/components/Link/Link.tsx +114 -0
- package/src/components/Link/index.ts +2 -0
- package/src/components/LinkCard/LinkCard.module.scss +92 -0
- package/src/components/LinkCard/LinkCard.tokens.scss +9 -0
- package/src/components/LinkCard/LinkCard.tsx +72 -0
- package/src/components/LinkCard/index.ts +2 -0
- package/src/components/LiquidEditor/AutocompleteMenu.tsx +133 -0
- package/src/components/LiquidEditor/HighlightLayer.tsx +53 -0
- package/src/components/LiquidEditor/InsertVariableMenu.tsx +81 -0
- package/src/components/LiquidEditor/LiquidEditor.module.scss +339 -0
- package/src/components/LiquidEditor/LiquidEditor.tokens.scss +81 -0
- package/src/components/LiquidEditor/LiquidEditor.tsx +412 -0
- package/src/components/LiquidEditor/PreviewPane.tsx +29 -0
- package/src/components/LiquidEditor/caretCoordinates.ts +97 -0
- package/src/components/LiquidEditor/index.ts +7 -0
- package/src/components/LiquidEditor/liquidFilters.ts +23 -0
- package/src/components/LiquidEditor/liquidTokenizer.ts +235 -0
- package/src/components/LiquidEditor/types.ts +101 -0
- package/src/components/LiquidEditor/useLiquidAutocomplete.ts +178 -0
- package/src/components/List/List.module.scss +105 -0
- package/src/components/List/List.tokens.scss +42 -0
- package/src/components/List/List.tsx +124 -0
- package/src/components/List/index.ts +9 -0
- package/src/components/LiveRegion/LiveRegion.module.scss +3 -0
- package/src/components/LiveRegion/LiveRegion.tsx +116 -0
- package/src/components/LiveRegion/index.ts +2 -0
- package/src/components/Logo/Logo.module.scss +139 -0
- package/src/components/Logo/Logo.tokens.scss +14 -0
- package/src/components/Logo/Logo.tsx +126 -0
- package/src/components/Logo/index.ts +2 -0
- package/src/components/Masonry/Masonry.module.scss +42 -0
- package/src/components/Masonry/Masonry.tokens.scss +8 -0
- package/src/components/Masonry/Masonry.tsx +136 -0
- package/src/components/Masonry/index.ts +2 -0
- package/src/components/Masonry/masonryUtils.ts +42 -0
- package/src/components/MediaTile/MediaTile.module.scss +183 -0
- package/src/components/MediaTile/MediaTile.tokens.scss +60 -0
- package/src/components/MediaTile/MediaTile.tsx +208 -0
- package/src/components/MediaTile/index.ts +8 -0
- package/src/components/Modal/Body.tsx +27 -0
- package/src/components/Modal/Close.tsx +45 -0
- package/src/components/Modal/Content.tsx +98 -0
- package/src/components/Modal/Footer.tsx +28 -0
- package/src/components/Modal/Header.tsx +51 -0
- package/src/components/Modal/Modal.module.scss +262 -0
- package/src/components/Modal/Modal.tokens.scss +50 -0
- package/src/components/Modal/Modal.tsx +23 -0
- package/src/components/Modal/ModalRoot.tsx +299 -0
- package/src/components/Modal/Overlay.tsx +101 -0
- package/src/components/Modal/context.ts +60 -0
- package/src/components/Modal/index.ts +11 -0
- package/src/components/MoneyInput/MoneyInput.module.scss +57 -0
- package/src/components/MoneyInput/MoneyInput.tsx +433 -0
- package/src/components/MoneyInput/index.ts +2 -0
- package/src/components/OptionsPicker/OptionsPicker.module.scss +216 -0
- package/src/components/OptionsPicker/OptionsPicker.tokens.scss +68 -0
- package/src/components/OptionsPicker/OptionsPicker.tsx +936 -0
- package/src/components/OptionsPicker/index.ts +9 -0
- package/src/components/OtpInput/OtpInput.module.scss +69 -0
- package/src/components/OtpInput/OtpInput.tokens.scss +45 -0
- package/src/components/OtpInput/OtpInput.tsx +368 -0
- package/src/components/OtpInput/index.ts +2 -0
- package/src/components/Page/Page.module.scss +30 -0
- package/src/components/Page/Page.tokens.scss +11 -0
- package/src/components/Page/Page.tsx +53 -0
- package/src/components/Page/index.ts +2 -0
- package/src/components/PageHeader/PageHeader.module.scss +197 -0
- package/src/components/PageHeader/PageHeader.tokens.scss +41 -0
- package/src/components/PageHeader/PageHeader.tsx +310 -0
- package/src/components/PageHeader/index.ts +20 -0
- package/src/components/Pagination/Pagination.module.scss +117 -0
- package/src/components/Pagination/Pagination.tokens.scss +54 -0
- package/src/components/Pagination/Pagination.tsx +165 -0
- package/src/components/Pagination/index.ts +4 -0
- package/src/components/Pagination/paginationRange.ts +72 -0
- package/src/components/PasswordInput/PasswordInput.module.scss +120 -0
- package/src/components/PasswordInput/PasswordInput.tokens.scss +44 -0
- package/src/components/PasswordInput/PasswordInput.tsx +210 -0
- package/src/components/PasswordInput/index.ts +2 -0
- package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.module.scss +80 -0
- package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tokens.scss +40 -0
- package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tsx +96 -0
- package/src/components/PasswordStrengthMeter/index.ts +2 -0
- package/src/components/PersonDisplay/PersonDisplay.module.scss +180 -0
- package/src/components/PersonDisplay/PersonDisplay.tokens.scss +35 -0
- package/src/components/PersonDisplay/PersonDisplay.tsx +420 -0
- package/src/components/PersonDisplay/index.ts +10 -0
- package/src/components/PhoneInput/PhoneInput.module.scss +23 -0
- package/src/components/PhoneInput/PhoneInput.tsx +271 -0
- package/src/components/PhoneInput/index.ts +4 -0
- package/src/components/PhoneInput/phone.ts +128 -0
- package/src/components/PillMenu/PillMenu.module.scss +117 -0
- package/src/components/PillMenu/PillMenu.tokens.scss +22 -0
- package/src/components/PillMenu/PillMenu.tsx +324 -0
- package/src/components/PillMenu/index.ts +2 -0
- package/src/components/Popover/Anchor.tsx +37 -0
- package/src/components/Popover/Close.tsx +45 -0
- package/src/components/Popover/Content.tsx +213 -0
- package/src/components/Popover/Heading.tsx +33 -0
- package/src/components/Popover/Popover.module.scss +177 -0
- package/src/components/Popover/Popover.tokens.scss +22 -0
- package/src/components/Popover/Popover.tsx +23 -0
- package/src/components/Popover/PopoverRoot.tsx +75 -0
- package/src/components/Popover/Trigger.tsx +86 -0
- package/src/components/Popover/context.ts +22 -0
- package/src/components/Popover/index.ts +7 -0
- package/src/components/Progress/Progress.module.scss +110 -0
- package/src/components/Progress/Progress.tokens.scss +44 -0
- package/src/components/Progress/Progress.tsx +129 -0
- package/src/components/Progress/index.ts +2 -0
- package/src/components/QrCode/QrCode.module.scss +97 -0
- package/src/components/QrCode/QrCode.tokens.scss +17 -0
- package/src/components/QrCode/QrCode.tsx +233 -0
- package/src/components/QrCode/index.ts +2 -0
- package/src/components/QrCode/qr.ts +161 -0
- package/src/components/Radio/Radio.module.scss +175 -0
- package/src/components/Radio/Radio.tokens.scss +59 -0
- package/src/components/Radio/Radio.tsx +127 -0
- package/src/components/Radio/RadioGroup.module.scss +42 -0
- package/src/components/Radio/RadioGroup.tsx +120 -0
- package/src/components/Radio/RadioGroupContext.tsx +30 -0
- package/src/components/Radio/index.ts +4 -0
- package/src/components/Rail/Rail.module.scss +510 -0
- package/src/components/Rail/Rail.tokens.scss +92 -0
- package/src/components/Rail/Rail.tsx +287 -0
- package/src/components/Rail/RailCollapseToggle.tsx +57 -0
- package/src/components/Rail/RailFooter.tsx +17 -0
- package/src/components/Rail/RailGroup.tsx +728 -0
- package/src/components/Rail/RailGroupContext.ts +9 -0
- package/src/components/Rail/RailHeader.tsx +23 -0
- package/src/components/Rail/RailItem.tsx +119 -0
- package/src/components/Rail/RailSection.tsx +39 -0
- package/src/components/Rail/RailSpacer.tsx +19 -0
- package/src/components/Rail/index.ts +9 -0
- package/src/components/RelativeDateInput/RelativeDateInput.module.scss +15 -0
- package/src/components/RelativeDateInput/RelativeDateInput.tokens.scss +6 -0
- package/src/components/RelativeDateInput/RelativeDateInput.tsx +474 -0
- package/src/components/RelativeDateInput/index.ts +10 -0
- package/src/components/RelativeDateInput/relativeDate.ts +127 -0
- package/src/components/RichText/RichText.module.scss +5 -0
- package/src/components/RichText/RichText.tsx +70 -0
- package/src/components/RichText/RichTextAttachment.module.scss +82 -0
- package/src/components/RichText/RichTextAttachment.tsx +122 -0
- package/src/components/RichText/_prose.scss +79 -0
- package/src/components/RichText/attachmentIcon.tsx +24 -0
- package/src/components/RichText/engine/attachment.ts +154 -0
- package/src/components/RichText/engine/autolink.ts +64 -0
- package/src/components/RichText/engine/blockUnit.ts +174 -0
- package/src/components/RichText/engine/colorMarks.ts +85 -0
- package/src/components/RichText/engine/escape.ts +11 -0
- package/src/components/RichText/engine/fromHtml.ts +353 -0
- package/src/components/RichText/engine/fromMarkdown.ts +20 -0
- package/src/components/RichText/engine/inlines.ts +82 -0
- package/src/components/RichText/engine/listDepths.ts +32 -0
- package/src/components/RichText/engine/marks.ts +80 -0
- package/src/components/RichText/engine/mdToHtml.ts +178 -0
- package/src/components/RichText/engine/model.ts +157 -0
- package/src/components/RichText/engine/position.ts +118 -0
- package/src/components/RichText/engine/renderDoc.tsx +395 -0
- package/src/components/RichText/engine/renderLink.ts +15 -0
- package/src/components/RichText/engine/renderMention.ts +16 -0
- package/src/components/RichText/engine/safeHref.ts +22 -0
- package/src/components/RichText/engine/toHtml.ts +154 -0
- package/src/components/RichText/engine/toMarkdown.ts +97 -0
- package/src/components/RichText/engine/transforms.ts +434 -0
- package/src/components/RichText/imageMaxHeightStyle.ts +10 -0
- package/src/components/RichText/index.ts +31 -0
- package/src/components/RichTextEditor/RichTextAttachmentConfig.tsx +264 -0
- package/src/components/RichTextEditor/RichTextBlockControls.tsx +365 -0
- package/src/components/RichTextEditor/RichTextBlockMenu.tsx +162 -0
- package/src/components/RichTextEditor/RichTextColorMenu.tsx +115 -0
- package/src/components/RichTextEditor/RichTextEditor.module.scss +298 -0
- package/src/components/RichTextEditor/RichTextEditor.tsx +1910 -0
- package/src/components/RichTextEditor/RichTextImageResizer.tsx +131 -0
- package/src/components/RichTextEditor/RichTextLinkEditor.tsx +151 -0
- package/src/components/RichTextEditor/RichTextMentionMenu.tsx +99 -0
- package/src/components/RichTextEditor/RichTextToolbar.tsx +379 -0
- package/src/components/RichTextEditor/autolinkInput.ts +65 -0
- package/src/components/RichTextEditor/blockDrop.ts +9 -0
- package/src/components/RichTextEditor/blockReflow.ts +62 -0
- package/src/components/RichTextEditor/commands.ts +300 -0
- package/src/components/RichTextEditor/history.ts +93 -0
- package/src/components/RichTextEditor/icons.tsx +152 -0
- package/src/components/RichTextEditor/imageSize.ts +70 -0
- package/src/components/RichTextEditor/index.ts +5 -0
- package/src/components/RichTextEditor/input.ts +209 -0
- package/src/components/RichTextEditor/inputRules.ts +71 -0
- package/src/components/RichTextEditor/links.ts +103 -0
- package/src/components/RichTextEditor/mentionContext.ts +37 -0
- package/src/components/RichTextEditor/mentions.ts +28 -0
- package/src/components/RichTextEditor/preventSelectionLoss.ts +15 -0
- package/src/components/RichTextEditor/selection.ts +415 -0
- package/src/components/RichTextEditor/shortcuts.ts +44 -0
- package/src/components/RichTextEditor/useAnchoredFloating.ts +50 -0
- package/src/components/RichTextEditor/useAttachmentConfig.ts +134 -0
- package/src/components/RichTextEditor/useDismissOnOutsidePointerDown.ts +26 -0
- package/src/components/RichTextEditor/useLinkEditor.ts +107 -0
- package/src/components/RichTextEditor/useMention.ts +226 -0
- package/src/components/RichTextEditor/useOverlayRect.ts +73 -0
- package/src/components/RichTextEditor/useUpload.ts +246 -0
- package/src/components/Screen/Screen.module.scss +46 -0
- package/src/components/Screen/Screen.tokens.scss +20 -0
- package/src/components/Screen/Screen.tsx +97 -0
- package/src/components/Screen/index.ts +2 -0
- package/src/components/ScrollArea/ScrollArea.module.scss +39 -0
- package/src/components/ScrollArea/ScrollArea.tokens.scss +15 -0
- package/src/components/ScrollArea/ScrollArea.tsx +154 -0
- package/src/components/ScrollArea/index.ts +2 -0
- package/src/components/Select/Chip.tsx +45 -0
- package/src/components/Select/Empty.tsx +39 -0
- package/src/components/Select/Error.tsx +51 -0
- package/src/components/Select/HiddenInputs.tsx +44 -0
- package/src/components/Select/Listbox.tsx +557 -0
- package/src/components/Select/Loading.tsx +30 -0
- package/src/components/Select/Select.module.scss +512 -0
- package/src/components/Select/Select.tokens.scss +140 -0
- package/src/components/Select/Select.tsx +685 -0
- package/src/components/Select/Trigger.tsx +952 -0
- package/src/components/Select/context.ts +101 -0
- package/src/components/Select/emptyStateText.ts +19 -0
- package/src/components/Select/index.ts +9 -0
- package/src/components/Select/useSelectState.ts +157 -0
- package/src/components/Select/utils-types.ts +7 -0
- package/src/components/Select/utils.ts +122 -0
- package/src/components/SettingRow/SettingRow.module.scss +166 -0
- package/src/components/SettingRow/SettingRow.tokens.scss +37 -0
- package/src/components/SettingRow/SettingRow.tsx +242 -0
- package/src/components/SettingRow/index.ts +7 -0
- package/src/components/Skeleton/Skeleton.module.scss +55 -0
- package/src/components/Skeleton/Skeleton.tokens.scss +17 -0
- package/src/components/Skeleton/Skeleton.tsx +131 -0
- package/src/components/Skeleton/index.ts +4 -0
- package/src/components/Skeleton/useSkeletonVisibility.ts +95 -0
- package/src/components/Slider/Slider.module.scss +293 -0
- package/src/components/Slider/Slider.tokens.scss +98 -0
- package/src/components/Slider/Slider.tsx +624 -0
- package/src/components/Slider/index.ts +9 -0
- package/src/components/SlotGrid/SlotGrid.module.scss +61 -0
- package/src/components/SlotGrid/SlotGrid.tokens.scss +21 -0
- package/src/components/SlotGrid/SlotGrid.tsx +111 -0
- package/src/components/SlotGrid/index.ts +2 -0
- package/src/components/SocialButton/SocialButton.module.scss +4 -0
- package/src/components/SocialButton/SocialButton.tsx +40 -0
- package/src/components/SocialButton/index.ts +2 -0
- package/src/components/Sortable/Sortable.module.scss +177 -0
- package/src/components/Sortable/Sortable.tokens.scss +27 -0
- package/src/components/Sortable/Sortable.tsx +572 -0
- package/src/components/Sortable/containerAwareCollision.ts +125 -0
- package/src/components/Sortable/index.ts +13 -0
- package/src/components/SortableGroup/SortableGroup.module.scss +23 -0
- package/src/components/SortableGroup/SortableGroup.tsx +315 -0
- package/src/components/SortableGroup/index.ts +4 -0
- package/src/components/SortableGroup/moveSortableItem.ts +39 -0
- package/src/components/Sparkline/Sparkline.module.scss +28 -0
- package/src/components/Sparkline/Sparkline.tokens.scss +7 -0
- package/src/components/Sparkline/Sparkline.tsx +133 -0
- package/src/components/Sparkline/index.ts +2 -0
- package/src/components/Sparkline/sparklineModel.ts +119 -0
- package/src/components/Split/Split.module.scss +158 -0
- package/src/components/Split/Split.tokens.scss +10 -0
- package/src/components/Split/Split.tsx +231 -0
- package/src/components/Split/index.ts +2 -0
- package/src/components/Stack/Stack.module.scss +67 -0
- package/src/components/Stack/Stack.tokens.scss +11 -0
- package/src/components/Stack/Stack.tsx +100 -0
- package/src/components/Stack/index.ts +2 -0
- package/src/components/StagePath/StagePath.module.scss +255 -0
- package/src/components/StagePath/StagePath.tokens.scss +43 -0
- package/src/components/StagePath/StagePath.tsx +176 -0
- package/src/components/StagePath/index.ts +2 -0
- package/src/components/StatGroup/StatGroup.module.scss +6 -0
- package/src/components/StatGroup/StatGroup.tsx +70 -0
- package/src/components/StatGroup/StatGroupContext.ts +10 -0
- package/src/components/StatGroup/StatTile.module.scss +99 -0
- package/src/components/StatGroup/StatTile.tokens.scss +35 -0
- package/src/components/StatGroup/StatTile.tsx +143 -0
- package/src/components/StatGroup/index.ts +4 -0
- package/src/components/Sticky/Sticky.module.scss +98 -0
- package/src/components/Sticky/Sticky.tokens.scss +17 -0
- package/src/components/Sticky/Sticky.tsx +103 -0
- package/src/components/Sticky/index.ts +2 -0
- package/src/components/Switch/Switch.module.scss +182 -0
- package/src/components/Switch/Switch.tokens.scss +59 -0
- package/src/components/Switch/Switch.tsx +214 -0
- package/src/components/Switch/index.ts +2 -0
- package/src/components/Table/Table.module.scss +308 -0
- package/src/components/Table/Table.tokens.scss +79 -0
- package/src/components/Table/Table.tsx +381 -0
- package/src/components/Table/index.ts +15 -0
- package/src/components/TableOfContents/TableOfContents.module.scss +83 -0
- package/src/components/TableOfContents/TableOfContents.tokens.scss +26 -0
- package/src/components/TableOfContents/TableOfContents.tsx +192 -0
- package/src/components/TableOfContents/activeSection.ts +18 -0
- package/src/components/TableOfContents/index.ts +2 -0
- package/src/components/Tabs/Tabs.module.scss +359 -0
- package/src/components/Tabs/Tabs.tokens.scss +50 -0
- package/src/components/Tabs/Tabs.tsx +538 -0
- package/src/components/Tabs/index.ts +2 -0
- package/src/components/Text/Text.module.scss +115 -0
- package/src/components/Text/Text.tokens.scss +55 -0
- package/src/components/Text/Text.tsx +197 -0
- package/src/components/Text/index.ts +2 -0
- package/src/components/Textarea/Textarea.module.scss +94 -0
- package/src/components/Textarea/Textarea.tokens.scss +48 -0
- package/src/components/Textarea/Textarea.tsx +246 -0
- package/src/components/Textarea/index.ts +2 -0
- package/src/components/Thread/Thread.module.scss +161 -0
- package/src/components/Thread/Thread.tokens.scss +32 -0
- package/src/components/Thread/Thread.tsx +176 -0
- package/src/components/Thread/index.ts +2 -0
- package/src/components/TimeField/TimeField.module.scss +232 -0
- package/src/components/TimeField/TimeField.tsx +793 -0
- package/src/components/TimeField/index.ts +2 -0
- package/src/components/Timeline/Timeline.module.scss +58 -0
- package/src/components/Timeline/Timeline.tokens.scss +13 -0
- package/src/components/Timeline/Timeline.tsx +53 -0
- package/src/components/Timeline/index.ts +2 -0
- package/src/components/Title/Title.module.scss +84 -0
- package/src/components/Title/Title.tokens.scss +37 -0
- package/src/components/Title/Title.tsx +150 -0
- package/src/components/Title/index.ts +2 -0
- package/src/components/Toast/Toast.module.scss +299 -0
- package/src/components/Toast/Toast.tokens.scss +65 -0
- package/src/components/Toast/Toast.tsx +122 -0
- package/src/components/Toast/ToastViewport.tsx +166 -0
- package/src/components/Toast/api.ts +175 -0
- package/src/components/Toast/index.ts +5 -0
- package/src/components/Toast/store.ts +133 -0
- package/src/components/Toast/useToastTimer.ts +94 -0
- package/src/components/Tooltip/Tooltip.module.scss +99 -0
- package/src/components/Tooltip/Tooltip.tokens.scss +23 -0
- package/src/components/Tooltip/Tooltip.tsx +341 -0
- package/src/components/Tooltip/index.ts +2 -0
- package/src/components/TopBar/TopBar.module.scss +235 -0
- package/src/components/TopBar/TopBar.tokens.scss +79 -0
- package/src/components/TopBar/TopBar.tsx +87 -0
- package/src/components/TopBar/TopBarEnd.tsx +20 -0
- package/src/components/TopBar/TopBarIconButton.tsx +86 -0
- package/src/components/TopBar/TopBarSearch.tsx +319 -0
- package/src/components/TopBar/TopBarSearchPanel.tsx +268 -0
- package/src/components/TopBar/TopBarStart.tsx +20 -0
- package/src/components/TopBar/index.ts +11 -0
- package/src/components/Tour/Spotlight.tsx +121 -0
- package/src/components/Tour/Tour.module.scss +210 -0
- package/src/components/Tour/Tour.tokens.scss +58 -0
- package/src/components/Tour/Tour.tsx +617 -0
- package/src/components/Tour/index.ts +2 -0
- package/src/components/Tour/useTourTarget.ts +115 -0
- package/src/components/TreeView/TreeView.module.scss +268 -0
- package/src/components/TreeView/TreeView.tokens.scss +36 -0
- package/src/components/TreeView/TreeView.tsx +536 -0
- package/src/components/TreeView/index.ts +3 -0
- package/src/components/TreeView/treeModel.ts +224 -0
- package/src/components/VisuallyHidden/VisuallyHidden.module.scss +7 -0
- package/src/components/VisuallyHidden/VisuallyHidden.tsx +29 -0
- package/src/components/VisuallyHidden/index.ts +2 -0
- package/src/components/WidgetPreview/WidgetPreview.module.scss +11 -0
- package/src/components/WidgetPreview/WidgetPreview.tokens.scss +26 -0
- package/src/components/WidgetPreview/WidgetPreview.tsx +36 -0
- package/src/components/WidgetPreview/WidgetShape.module.scss +140 -0
- package/src/components/WidgetPreview/WidgetShape.tsx +159 -0
- package/src/components/WidgetPreview/index.ts +2 -0
- package/src/components/_internal/Trend.tsx +27 -0
- package/src/components/_internal/choiceTile.scss +74 -0
- package/src/components/_internal/collapse.scss +10 -0
- package/src/components/_internal/collapse.ts +58 -0
- package/src/components/_internal/currency.ts +257 -0
- package/src/components/_internal/dragAnnouncements.ts +200 -0
- package/src/components/_internal/fieldWiring.ts +225 -0
- package/src/components/_internal/gridSpan.ts +54 -0
- package/src/components/_internal/isoDay.ts +35 -0
- package/src/components/_internal/letterKey.ts +26 -0
- package/src/components/_internal/overlay/focusRestore.ts +21 -0
- package/src/components/_internal/overlay/index.ts +12 -0
- package/src/components/_internal/overlay/tourHold.ts +23 -0
- package/src/components/_internal/overlay/useFocusTrap.ts +120 -0
- package/src/components/_internal/overlay/useInOverlay.ts +81 -0
- package/src/components/_internal/overlay/useOverlayStack.ts +232 -0
- package/src/components/_internal/overlay/useScrollLock.ts +112 -0
- package/src/components/_internal/refs.ts +48 -0
- package/src/components/_internal/statusColor.ts +26 -0
- package/src/components/_internal/timeUtils.ts +23 -0
- package/src/components/_internal/useAsyncOptions.ts +145 -0
- package/src/components/_internal/useClippedTooltip.ts +50 -0
- package/src/components/_internal/useControllableState.ts +50 -0
- package/src/components.manifest.json +1141 -0
- package/src/hooks/useBelowBreakpoint.ts +58 -0
- package/src/i18n/I18nProvider.tsx +52 -0
- package/src/i18n/LocaleProvider.tsx +17 -0
- package/src/i18n/en.ts +648 -0
- package/src/i18n/format.ts +71 -0
- package/src/i18n/index.ts +13 -0
- package/src/i18n/messages.ts +1275 -0
- package/src/i18n/ru.ts +677 -0
- package/src/i18n/useLocale.ts +19 -0
- package/src/i18n/useTranslation.ts +58 -0
- package/src/index.ts +913 -0
- package/src/palette/index.ts +2 -0
- package/src/palette/palette.ts +108 -0
- package/src/styles/dark.scss +4 -0
- package/src/styles/global.scss +7 -0
- package/src/styles/mixins.scss +143 -0
- package/src/styles/reset.scss +78 -0
- package/src/styles/tokens.scss +18 -0
- package/src/styles/typography.scss +44 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import {
|
|
2
|
+
forwardRef,
|
|
3
|
+
useState,
|
|
4
|
+
type CSSProperties,
|
|
5
|
+
type ImgHTMLAttributes,
|
|
6
|
+
type MouseEventHandler,
|
|
7
|
+
type ReactNode,
|
|
8
|
+
} from 'react';
|
|
9
|
+
import clsx from 'clsx';
|
|
10
|
+
import { ImageOff } from 'lucide-react';
|
|
11
|
+
import { Button } from '../Button';
|
|
12
|
+
import { Skeleton } from '../Skeleton';
|
|
13
|
+
import { useTranslation } from '../../i18n/useTranslation';
|
|
14
|
+
import styles from './Image.module.scss';
|
|
15
|
+
|
|
16
|
+
/** How the image fills its box. Maps to CSS `object-fit`. */
|
|
17
|
+
export type ImageObjectFit = 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
|
|
18
|
+
|
|
19
|
+
/** Corner rounding. Maps to the radius token scale. */
|
|
20
|
+
export type ImageRadius = 'none' | 'sm' | 'md' | 'lg' | 'full';
|
|
21
|
+
|
|
22
|
+
/** Fixed square size, aligned to the shared `--size-*` scale (xs 20 / sm 24 / md 32 / lg 40 px). */
|
|
23
|
+
export type ImageSize = 'xs' | 'sm' | 'md' | 'lg';
|
|
24
|
+
|
|
25
|
+
/** Backdrop behind a loaded image: the muted surface fill, or none. */
|
|
26
|
+
export type ImageBackground = 'muted' | 'none';
|
|
27
|
+
|
|
28
|
+
export interface ImageProps extends Omit<
|
|
29
|
+
ImgHTMLAttributes<HTMLImageElement>,
|
|
30
|
+
'alt' | 'children' | 'src' | 'loading' | 'onClick'
|
|
31
|
+
> {
|
|
32
|
+
/** Image URL. Changing it resets the component to the loading state. */
|
|
33
|
+
src: string;
|
|
34
|
+
/**
|
|
35
|
+
* Alternative text (required). Describe the image's content or function.
|
|
36
|
+
* Pass an empty string (`alt=""`) for purely decorative images.
|
|
37
|
+
*/
|
|
38
|
+
alt: string;
|
|
39
|
+
/**
|
|
40
|
+
* How the image fills its box. Defaults to `'cover'`.
|
|
41
|
+
* - `'cover'` — fill + crop (no distortion). Best for thumbnails / heroes.
|
|
42
|
+
* - `'contain'` — whole image, letterboxed; the bars show the surface, or the muted box with `background="muted"`.
|
|
43
|
+
* - `'fill'` — stretch to the box (may distort).
|
|
44
|
+
* - `'none'` / `'scale-down'` — native size / the smaller of none|contain.
|
|
45
|
+
*/
|
|
46
|
+
objectFit?: ImageObjectFit;
|
|
47
|
+
/**
|
|
48
|
+
* Which part of the image stays in view when `objectFit` crops or letterboxes
|
|
49
|
+
* it. Any CSS `object-position` value. Defaults to `'center'`. Use `'top'` for
|
|
50
|
+
* document / screenshot thumbnails cropped square, so the header stays visible.
|
|
51
|
+
*/
|
|
52
|
+
objectPosition?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Reserve the box at a fixed ratio to prevent layout shift while loading.
|
|
55
|
+
* Number (`1.5`) or CSS string (`'16 / 9'`).
|
|
56
|
+
*/
|
|
57
|
+
aspectRatio?: string | number;
|
|
58
|
+
/**
|
|
59
|
+
* Render a fixed **square** box of this size (from the shared `--size-*`
|
|
60
|
+
* scale: `'xs'` 20 / `'sm'` 24 / `'md'` 32 / `'lg'` 40 px) instead of filling
|
|
61
|
+
* the container's width. Use for dense thumbnails (e.g. a 40px image cell in a
|
|
62
|
+
* table row) so you don't need a consumer-owned fixed-width wrapper. Omit for
|
|
63
|
+
* the default responsive behavior. When set, `aspectRatio` is ignored (the box
|
|
64
|
+
* is already square); pair with `objectFit="cover"` to crop. Note that a
|
|
65
|
+
* sized image's error tile is icon-only and **not retryable** — see the
|
|
66
|
+
* component description.
|
|
67
|
+
*/
|
|
68
|
+
size?: ImageSize;
|
|
69
|
+
/**
|
|
70
|
+
* Corner rounding. Defaults to `'md'`. Pass `'none'` for square corners; for
|
|
71
|
+
* circular profile images use `<Avatar>`.
|
|
72
|
+
*/
|
|
73
|
+
radius?: ImageRadius;
|
|
74
|
+
/**
|
|
75
|
+
* Backdrop behind the loaded image. Defaults to `'none'`, so transparent
|
|
76
|
+
* assets (logos, PNG/SVG) show their surface. Pass `'muted'` for the muted
|
|
77
|
+
* fill (letterboxed `contain` images). The loading skeleton and the error
|
|
78
|
+
* tile keep their fill either way.
|
|
79
|
+
*/
|
|
80
|
+
background?: ImageBackground;
|
|
81
|
+
/**
|
|
82
|
+
* Custom node rendered in place of the default broken-image placeholder when
|
|
83
|
+
* the image fails to load. Overrides the icon + message + retry entirely.
|
|
84
|
+
* This is also the only way to put a control on a failed fixed-`size` image,
|
|
85
|
+
* whose built-in error tile is icon-only. At a fixed `size` the node is
|
|
86
|
+
* rendered in a slot that fills the box (so it cannot flow outside the
|
|
87
|
+
* wrapper's clip); fitting your content into those 20-40px is still yours,
|
|
88
|
+
* and a labelled button does not fit any of them.
|
|
89
|
+
*/
|
|
90
|
+
fallback?: ReactNode;
|
|
91
|
+
/**
|
|
92
|
+
* Native lazy-loading hint. Defaults to `'lazy'`. Pass `'eager'` for
|
|
93
|
+
* above-the-fold / LCP images.
|
|
94
|
+
*/
|
|
95
|
+
loading?: 'eager' | 'lazy';
|
|
96
|
+
/**
|
|
97
|
+
* Make the image a flush, keyboard-accessible click target — renders the image
|
|
98
|
+
* inside a chromeless `<button>` (no padding/border/background; DS focus ring on
|
|
99
|
+
* `:focus-visible`). Implied when `onClick` is set. Use for a thumbnail that opens
|
|
100
|
+
* a preview/lightbox. The broken-image error state is non-interactive (the fluid
|
|
101
|
+
* tile's Retry takes over when its box has room; otherwise there is no control).
|
|
102
|
+
*/
|
|
103
|
+
interactive?: boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Click handler for the interactive trigger. Setting it implies `interactive`.
|
|
106
|
+
* Fires on click and on Enter/Space (native `<button>` keyboard behavior).
|
|
107
|
+
*/
|
|
108
|
+
onClick?: MouseEventHandler<HTMLButtonElement>;
|
|
109
|
+
/**
|
|
110
|
+
* Accessible label for the interactive trigger — action-oriented, e.g.
|
|
111
|
+
* `"Preview report.png"`. Defaults to `alt` when omitted OR empty — an empty
|
|
112
|
+
* string is not an explicit name, so it takes the default too. Only used when
|
|
113
|
+
* interactive. Note:
|
|
114
|
+
* a native `aria-label` passed via `{...rest}` lands on the `<img>`, not the
|
|
115
|
+
* trigger button — use `ariaLabel` to name the trigger.
|
|
116
|
+
*/
|
|
117
|
+
ariaLabel?: string;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
type LoadState = 'loading' | 'loaded' | 'error';
|
|
121
|
+
|
|
122
|
+
const RADIUS_CLASS: Record<ImageRadius, string> = {
|
|
123
|
+
none: styles.radiusNone,
|
|
124
|
+
sm: styles.radiusSm,
|
|
125
|
+
md: styles.radiusMd,
|
|
126
|
+
lg: styles.radiusLg,
|
|
127
|
+
full: styles.radiusFull,
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const SIZE_CLASS: Record<ImageSize, string> = {
|
|
131
|
+
xs: styles.sizeXs,
|
|
132
|
+
sm: styles.sizeSm,
|
|
133
|
+
md: styles.sizeMd,
|
|
134
|
+
lg: styles.sizeLg,
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Displays a remote image with built-in loading and error states.
|
|
139
|
+
* @see docs/components/Image.md
|
|
140
|
+
*/
|
|
141
|
+
export const Image = forwardRef<HTMLImageElement, ImageProps>(function Image(
|
|
142
|
+
{
|
|
143
|
+
src,
|
|
144
|
+
alt,
|
|
145
|
+
objectFit = 'cover',
|
|
146
|
+
objectPosition = 'center',
|
|
147
|
+
aspectRatio,
|
|
148
|
+
size,
|
|
149
|
+
radius = 'md',
|
|
150
|
+
background = 'none',
|
|
151
|
+
fallback,
|
|
152
|
+
loading = 'lazy',
|
|
153
|
+
interactive,
|
|
154
|
+
onClick,
|
|
155
|
+
ariaLabel,
|
|
156
|
+
className,
|
|
157
|
+
style,
|
|
158
|
+
...rest
|
|
159
|
+
},
|
|
160
|
+
ref,
|
|
161
|
+
) {
|
|
162
|
+
const t = useTranslation();
|
|
163
|
+
const [state, setState] = useState<LoadState>('loading');
|
|
164
|
+
const [reloadNonce, setReloadNonce] = useState(0);
|
|
165
|
+
|
|
166
|
+
// Reset to loading when the source changes — during render, not in an
|
|
167
|
+
// effect: a mount-time effect ran AFTER a cached image's `load` and put it
|
|
168
|
+
// back to 'loading' for good (#574).
|
|
169
|
+
const [prevSrc, setPrevSrc] = useState(src);
|
|
170
|
+
if (src !== prevSrc) {
|
|
171
|
+
setPrevSrc(src);
|
|
172
|
+
setState('loading');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const retry = () => {
|
|
176
|
+
setState('loading');
|
|
177
|
+
setReloadNonce((n) => n + 1); // re-key the <img> to force a re-fetch
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const wrapperStyle = {
|
|
181
|
+
// A fixed `size` sets an explicit square box, so aspectRatio is moot.
|
|
182
|
+
aspectRatio:
|
|
183
|
+
size !== undefined || aspectRatio === undefined
|
|
184
|
+
? undefined
|
|
185
|
+
: typeof aspectRatio === 'number'
|
|
186
|
+
? String(aspectRatio)
|
|
187
|
+
: aspectRatio,
|
|
188
|
+
'--image-object-fit': objectFit,
|
|
189
|
+
'--image-object-position': objectPosition,
|
|
190
|
+
...style,
|
|
191
|
+
} as CSSProperties;
|
|
192
|
+
|
|
193
|
+
const isInteractive = interactive || onClick != null;
|
|
194
|
+
|
|
195
|
+
const imgNode = (
|
|
196
|
+
// {...rest} FIRST (Pattern B): the state machine owns src/alt/onLoad/onError,
|
|
197
|
+
// so a careless spread can't break them. `key` stays before the spread (#707).
|
|
198
|
+
<img
|
|
199
|
+
key={`${src}|${reloadNonce}`}
|
|
200
|
+
{...rest}
|
|
201
|
+
ref={ref}
|
|
202
|
+
src={src}
|
|
203
|
+
alt={state === 'error' ? '' : alt}
|
|
204
|
+
aria-hidden={state === 'error' || undefined}
|
|
205
|
+
loading={loading}
|
|
206
|
+
className={styles.img}
|
|
207
|
+
onLoad={() => setState('loaded')}
|
|
208
|
+
onError={() => setState('error')}
|
|
209
|
+
/>
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
const loadingOverlay =
|
|
213
|
+
state === 'loading' ? <Skeleton variant="rectangular" className={styles.overlay} /> : null;
|
|
214
|
+
|
|
215
|
+
return (
|
|
216
|
+
<span
|
|
217
|
+
className={clsx(
|
|
218
|
+
styles.wrapper,
|
|
219
|
+
RADIUS_CLASS[radius],
|
|
220
|
+
size && SIZE_CLASS[size],
|
|
221
|
+
// No box of its own: on error the image goes `display: none` and the
|
|
222
|
+
// tile is out of flow, so nothing is left to give the wrapper height
|
|
223
|
+
// (#542). `.unreserved` gives it an icon-high spacer, error state
|
|
224
|
+
// only. A boxless `fallback` is in flow and sizes the wrapper itself.
|
|
225
|
+
size === undefined && aspectRatio === undefined && fallback == null && styles.unreserved,
|
|
226
|
+
className,
|
|
227
|
+
)}
|
|
228
|
+
style={wrapperStyle}
|
|
229
|
+
data-state={state}
|
|
230
|
+
data-background={background}
|
|
231
|
+
>
|
|
232
|
+
{isInteractive ? (
|
|
233
|
+
<button
|
|
234
|
+
type="button"
|
|
235
|
+
className={styles.trigger}
|
|
236
|
+
onClick={onClick}
|
|
237
|
+
aria-label={ariaLabel || alt}
|
|
238
|
+
disabled={state === 'error'}
|
|
239
|
+
>
|
|
240
|
+
{imgNode}
|
|
241
|
+
{loadingOverlay}
|
|
242
|
+
</button>
|
|
243
|
+
) : (
|
|
244
|
+
<>
|
|
245
|
+
{imgNode}
|
|
246
|
+
{loadingOverlay}
|
|
247
|
+
</>
|
|
248
|
+
)}
|
|
249
|
+
|
|
250
|
+
{state === 'error' &&
|
|
251
|
+
(fallback != null ? (
|
|
252
|
+
/* A fallback stands in for the built-in tile, so wherever the box is
|
|
253
|
+
the wrapper's own it gets the slot the built-in tile has. `.error`
|
|
254
|
+
is `inset: 0`; a bare child is in FLOW, and when the image is also
|
|
255
|
+
interactive it flows after `.trigger` (height: 100%) and lands
|
|
256
|
+
WHOLLY outside the clip — measured at `size="lg"` (box 40..80,
|
|
257
|
+
fallback 80..105) and again at `aspectRatio="16 / 9"` (fallback
|
|
258
|
+
starting exactly on the wrapper's bottom edge). That is #538
|
|
259
|
+
reproduced through the very prop documented as its remedy.
|
|
260
|
+
|
|
261
|
+
The slot bounds the fallback to the box. Fitting content INSIDE
|
|
262
|
+
the box is still the consumer's job — a labelled button is wider
|
|
263
|
+
than 40px and still clips — and the prop's JSDoc says so.
|
|
264
|
+
|
|
265
|
+
Not slotted when the wrapper has NEITHER `size` nor
|
|
266
|
+
`aspectRatio`: there the wrapper takes its height FROM this child
|
|
267
|
+
(measured: a 20px-tall fallback gives a 20px-tall wrapper), so
|
|
268
|
+
pulling it out of flow would collapse the box to zero. (The
|
|
269
|
+
built-in tile, which IS out of flow, gets `.unreserved`'s spacer
|
|
270
|
+
for the same reason — #542.) */
|
|
271
|
+
size !== undefined || aspectRatio !== undefined ? (
|
|
272
|
+
<span className={styles.fallback}>{fallback}</span>
|
|
273
|
+
) : (
|
|
274
|
+
fallback
|
|
275
|
+
)
|
|
276
|
+
) : size ? (
|
|
277
|
+
/* Fixed `size` is a 20/24/32/40px square, and the full tile below
|
|
278
|
+
is over 100px tall. At EVERY one of those sizes the Retry button
|
|
279
|
+
landed 23-42px past the wrapper's bottom edge: outside
|
|
280
|
+
`overflow: hidden`, never painted, and still focusable and in
|
|
281
|
+
the tab order (#538). There is no threshold to tune — the fluid
|
|
282
|
+
tile's 28px icon alone already overflows xs and sm — so a sized
|
|
283
|
+
error tile is the icon, scaled to its box by `.errorIcon`, and
|
|
284
|
+
contains nothing focusable at all. A consumer who needs a
|
|
285
|
+
control at this size passes `fallback`.
|
|
286
|
+
|
|
287
|
+
A11y: the "icon carries only `alt`" reasoning below is a
|
|
288
|
+
consequence of the visible text, not a rule about the icon, and
|
|
289
|
+
this branch has no visible text — so it inverts here. Nothing
|
|
290
|
+
else in the tile can carry the failure, so the icon does: `alt`
|
|
291
|
+
plus the phrase, the same fold `Lightbox` uses on its failed
|
|
292
|
+
stage. It names itself even when `alt=""`, because the fluid
|
|
293
|
+
tile renders its failure text regardless of `alt` too — a
|
|
294
|
+
decorative image that breaks is discoverable there, and the
|
|
295
|
+
sized branch must not be the one place a broken tile is
|
|
296
|
+
silent. */
|
|
297
|
+
<span className={styles.error}>
|
|
298
|
+
<ImageOff
|
|
299
|
+
className={styles.errorIcon}
|
|
300
|
+
role="img"
|
|
301
|
+
aria-label={alt ? `${alt}: ${t('image.loadError')}` : t('image.loadError')}
|
|
302
|
+
/>
|
|
303
|
+
</span>
|
|
304
|
+
) : (
|
|
305
|
+
<span className={styles.error}>
|
|
306
|
+
{/* `role="img"` moved off the container and onto the ICON.
|
|
307
|
+
`img` is Children Presentational, so as a container it pruned
|
|
308
|
+
its own descendants from the accessibility tree — the visible
|
|
309
|
+
error text and, worse, the Retry button were not exposed at
|
|
310
|
+
all: a focusable control with no role and no name (#496).
|
|
311
|
+
Testing Library computes roles from the DOM rather than
|
|
312
|
+
modelling children-presentational, which is why the existing
|
|
313
|
+
`getByRole('button', { name: 'Retry' })` assertion passed
|
|
314
|
+
throughout.
|
|
315
|
+
|
|
316
|
+
On a leaf there is nothing to prune, so the name survives and
|
|
317
|
+
the siblings stay reachable.
|
|
318
|
+
|
|
319
|
+
The icon carries ONLY `alt`, never the failure phrase: the
|
|
320
|
+
sibling below renders that phrase as visible text, so naming
|
|
321
|
+
the icon with it too made a reader say "Failed to load" twice
|
|
322
|
+
in a row. With no `alt` there is nothing left to name, so the
|
|
323
|
+
icon goes decorative and the text carries the message alone.
|
|
324
|
+
Both halves of that hold only while the text is there — see
|
|
325
|
+
the sized branch above, which has none. */}
|
|
326
|
+
{alt ? (
|
|
327
|
+
<ImageOff size={28} role="img" aria-label={alt} />
|
|
328
|
+
) : (
|
|
329
|
+
<ImageOff size={28} aria-hidden />
|
|
330
|
+
)}
|
|
331
|
+
<span className={styles.errorText}>{t('image.loadError')}</span>
|
|
332
|
+
{/* `.retry` exists only to carry the inset focus ring — see the
|
|
333
|
+
rule in Image.module.scss for why an outset one cannot survive
|
|
334
|
+
this wrapper. */}
|
|
335
|
+
<Button variant="secondary" size="sm" onClick={retry} className={styles.retry}>
|
|
336
|
+
{t('image.retry')}
|
|
337
|
+
</Button>
|
|
338
|
+
</span>
|
|
339
|
+
))}
|
|
340
|
+
</span>
|
|
341
|
+
);
|
|
342
|
+
});
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
@use './ImageCrop.tokens';
|
|
2
|
+
@use '../../styles/mixins' as *;
|
|
3
|
+
|
|
4
|
+
.root {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
width: 100%;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.viewport {
|
|
11
|
+
position: relative;
|
|
12
|
+
background: var(--image-crop-viewport-bg);
|
|
13
|
+
border-radius: var(--image-crop-viewport-radius);
|
|
14
|
+
overflow: hidden;
|
|
15
|
+
|
|
16
|
+
// Reserve canvas space before image loads so the layout doesn't shift.
|
|
17
|
+
// Consumer can override via className.
|
|
18
|
+
min-height: 320px;
|
|
19
|
+
|
|
20
|
+
// CSS keyword; prevents browser text selection during drag.
|
|
21
|
+
// stylelint-disable-next-line scale-unlimited/declaration-strict-value -- CSS keyword
|
|
22
|
+
user-select: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.viewport:focus-visible {
|
|
26
|
+
@include focus-ring(var(--image-crop-viewport-focus-color));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.image {
|
|
30
|
+
position: absolute;
|
|
31
|
+
top: 0;
|
|
32
|
+
left: 0;
|
|
33
|
+
transform-origin: 0 0;
|
|
34
|
+
|
|
35
|
+
// The library's reset (src/styles/reset.scss) applies `max-width: 100%`
|
|
36
|
+
// to all <img> for general layout safety. We override here because the
|
|
37
|
+
// image inside ImageCrop must render at its natural pixel size — the
|
|
38
|
+
// crop math depends on `scale = boxW / value.width` driving the CSS
|
|
39
|
+
// transform, and that breaks if the image is also being width-capped by
|
|
40
|
+
// CSS to the parent viewport. Without this override, large source images
|
|
41
|
+
// (e.g. 4080×3072 phone photos) render visibly tiny in the cropper.
|
|
42
|
+
// stylelint-disable-next-line scale-unlimited/declaration-strict-value -- CSS keyword override of the global img reset
|
|
43
|
+
max-width: none;
|
|
44
|
+
|
|
45
|
+
// stylelint-disable-next-line scale-unlimited/declaration-strict-value -- CSS keyword
|
|
46
|
+
max-height: none;
|
|
47
|
+
|
|
48
|
+
// CSS keyword — the crop box owns all pointer interaction.
|
|
49
|
+
// stylelint-disable-next-line scale-unlimited/declaration-strict-value -- CSS keyword
|
|
50
|
+
pointer-events: none;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.cropBox {
|
|
54
|
+
position: absolute;
|
|
55
|
+
border: var(--border-width) solid var(--image-crop-cropbox-border-color);
|
|
56
|
+
|
|
57
|
+
// The box-shadow trick paints a dim overlay everywhere OUTSIDE the box
|
|
58
|
+
// without an extra DOM element. The 9999px spread covers the viewport.
|
|
59
|
+
// We use 50% black rather than --color-bg-overlay (35%) intentionally —
|
|
60
|
+
// the cropper scrim needs higher contrast than Modal's overlay.
|
|
61
|
+
// stylelint-disable-next-line scale-unlimited/declaration-strict-value -- crop scrim needs higher contrast than --color-bg-overlay
|
|
62
|
+
box-shadow: 0 0 0 9999px rgb(0 0 0 / 50%);
|
|
63
|
+
|
|
64
|
+
// CSS keyword.
|
|
65
|
+
// stylelint-disable-next-line scale-unlimited/declaration-strict-value -- CSS keyword
|
|
66
|
+
cursor: move;
|
|
67
|
+
|
|
68
|
+
// CSS keyword; box + handle gestures aren't browser scroll/zoom. The scrim and toolbar still scroll the page.
|
|
69
|
+
// stylelint-disable-next-line scale-unlimited/declaration-strict-value -- CSS keyword
|
|
70
|
+
touch-action: none;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.grid {
|
|
74
|
+
position: absolute;
|
|
75
|
+
inset: 0;
|
|
76
|
+
opacity: var(--image-crop-grid-opacity);
|
|
77
|
+
|
|
78
|
+
// stylelint-disable-next-line scale-unlimited/declaration-strict-value -- thirds lines are gradient stops with literal percentages
|
|
79
|
+
background:
|
|
80
|
+
linear-gradient(
|
|
81
|
+
to right,
|
|
82
|
+
transparent calc(33.333% - var(--border-width)),
|
|
83
|
+
var(--image-crop-grid-color) 0 33.333%,
|
|
84
|
+
transparent 0 calc(66.666% - var(--border-width)),
|
|
85
|
+
var(--image-crop-grid-color) 0 66.666%,
|
|
86
|
+
transparent 0
|
|
87
|
+
),
|
|
88
|
+
linear-gradient(
|
|
89
|
+
to bottom,
|
|
90
|
+
transparent calc(33.333% - var(--border-width)),
|
|
91
|
+
var(--image-crop-grid-color) 0 33.333%,
|
|
92
|
+
transparent 0 calc(66.666% - var(--border-width)),
|
|
93
|
+
var(--image-crop-grid-color) 0 66.666%,
|
|
94
|
+
transparent 0
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
// CSS keyword — grid never intercepts the box's pointer events.
|
|
98
|
+
// stylelint-disable-next-line scale-unlimited/declaration-strict-value -- CSS keyword
|
|
99
|
+
pointer-events: none;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.cropBoxActive .grid {
|
|
103
|
+
opacity: var(--image-crop-grid-opacity-active);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.handle {
|
|
107
|
+
position: absolute;
|
|
108
|
+
width: var(--image-crop-handle-size);
|
|
109
|
+
height: var(--image-crop-handle-size);
|
|
110
|
+
box-sizing: border-box;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Corner hit areas straddle the outline (half outside the box); the visible bracket hugs the box corner.
|
|
114
|
+
.handle_nw,
|
|
115
|
+
.handle_ne,
|
|
116
|
+
.handle_sw,
|
|
117
|
+
.handle_se {
|
|
118
|
+
&::before {
|
|
119
|
+
content: '';
|
|
120
|
+
position: absolute;
|
|
121
|
+
width: calc(var(--image-crop-handle-size) / 2 + var(--image-crop-handle-thickness));
|
|
122
|
+
height: calc(var(--image-crop-handle-size) / 2 + var(--image-crop-handle-thickness));
|
|
123
|
+
box-sizing: border-box;
|
|
124
|
+
border: 0 solid var(--image-crop-handle-color);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.handle_nw {
|
|
129
|
+
top: calc(-0.5 * var(--image-crop-handle-size));
|
|
130
|
+
left: calc(-0.5 * var(--image-crop-handle-size));
|
|
131
|
+
|
|
132
|
+
// stylelint-disable-next-line scale-unlimited/declaration-strict-value -- CSS keyword
|
|
133
|
+
cursor: nwse-resize;
|
|
134
|
+
|
|
135
|
+
&::before {
|
|
136
|
+
top: calc(var(--image-crop-handle-size) / 2 - var(--image-crop-handle-thickness));
|
|
137
|
+
left: calc(var(--image-crop-handle-size) / 2 - var(--image-crop-handle-thickness));
|
|
138
|
+
border-top-width: var(--image-crop-handle-thickness);
|
|
139
|
+
border-left-width: var(--image-crop-handle-thickness);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.handle_ne {
|
|
144
|
+
top: calc(-0.5 * var(--image-crop-handle-size));
|
|
145
|
+
right: calc(-0.5 * var(--image-crop-handle-size));
|
|
146
|
+
|
|
147
|
+
// stylelint-disable-next-line scale-unlimited/declaration-strict-value -- CSS keyword
|
|
148
|
+
cursor: nesw-resize;
|
|
149
|
+
|
|
150
|
+
&::before {
|
|
151
|
+
top: calc(var(--image-crop-handle-size) / 2 - var(--image-crop-handle-thickness));
|
|
152
|
+
right: calc(var(--image-crop-handle-size) / 2 - var(--image-crop-handle-thickness));
|
|
153
|
+
border-top-width: var(--image-crop-handle-thickness);
|
|
154
|
+
border-right-width: var(--image-crop-handle-thickness);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.handle_sw {
|
|
159
|
+
bottom: calc(-0.5 * var(--image-crop-handle-size));
|
|
160
|
+
left: calc(-0.5 * var(--image-crop-handle-size));
|
|
161
|
+
|
|
162
|
+
// stylelint-disable-next-line scale-unlimited/declaration-strict-value -- CSS keyword
|
|
163
|
+
cursor: nesw-resize;
|
|
164
|
+
|
|
165
|
+
&::before {
|
|
166
|
+
bottom: calc(var(--image-crop-handle-size) / 2 - var(--image-crop-handle-thickness));
|
|
167
|
+
left: calc(var(--image-crop-handle-size) / 2 - var(--image-crop-handle-thickness));
|
|
168
|
+
border-bottom-width: var(--image-crop-handle-thickness);
|
|
169
|
+
border-left-width: var(--image-crop-handle-thickness);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.handle_se {
|
|
174
|
+
right: calc(-0.5 * var(--image-crop-handle-size));
|
|
175
|
+
bottom: calc(-0.5 * var(--image-crop-handle-size));
|
|
176
|
+
|
|
177
|
+
// stylelint-disable-next-line scale-unlimited/declaration-strict-value -- CSS keyword
|
|
178
|
+
cursor: nwse-resize;
|
|
179
|
+
|
|
180
|
+
&::before {
|
|
181
|
+
bottom: calc(var(--image-crop-handle-size) / 2 - var(--image-crop-handle-thickness));
|
|
182
|
+
right: calc(var(--image-crop-handle-size) / 2 - var(--image-crop-handle-thickness));
|
|
183
|
+
border-bottom-width: var(--image-crop-handle-thickness);
|
|
184
|
+
border-right-width: var(--image-crop-handle-thickness);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Edge handles are invisible hit strips along the box edges.
|
|
189
|
+
.handle_n,
|
|
190
|
+
.handle_s {
|
|
191
|
+
left: var(--image-crop-handle-size);
|
|
192
|
+
right: var(--image-crop-handle-size);
|
|
193
|
+
width: auto;
|
|
194
|
+
|
|
195
|
+
// stylelint-disable-next-line scale-unlimited/declaration-strict-value -- CSS keyword
|
|
196
|
+
cursor: ns-resize;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.handle_n {
|
|
200
|
+
top: calc(-0.5 * var(--image-crop-handle-size));
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.handle_s {
|
|
204
|
+
bottom: calc(-0.5 * var(--image-crop-handle-size));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.handle_e,
|
|
208
|
+
.handle_w {
|
|
209
|
+
top: var(--image-crop-handle-size);
|
|
210
|
+
bottom: var(--image-crop-handle-size);
|
|
211
|
+
height: auto;
|
|
212
|
+
|
|
213
|
+
// stylelint-disable-next-line scale-unlimited/declaration-strict-value -- CSS keyword
|
|
214
|
+
cursor: ew-resize;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.handle_e {
|
|
218
|
+
right: calc(-0.5 * var(--image-crop-handle-size));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.handle_w {
|
|
222
|
+
left: calc(-0.5 * var(--image-crop-handle-size));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.skeleton {
|
|
226
|
+
position: absolute;
|
|
227
|
+
inset: 0;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.errorState {
|
|
231
|
+
position: absolute;
|
|
232
|
+
inset: 0;
|
|
233
|
+
display: flex;
|
|
234
|
+
flex-direction: column;
|
|
235
|
+
align-items: center;
|
|
236
|
+
justify-content: center;
|
|
237
|
+
gap: var(--image-crop-error-gap);
|
|
238
|
+
padding: var(--image-crop-error-padding);
|
|
239
|
+
color: var(--image-crop-error-fg);
|
|
240
|
+
font-size: var(--image-crop-error-font-size);
|
|
241
|
+
|
|
242
|
+
// CSS keyword — text alignment.
|
|
243
|
+
// stylelint-disable-next-line scale-unlimited/declaration-strict-value -- CSS keyword
|
|
244
|
+
text-align: center;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.disabled .viewport {
|
|
248
|
+
opacity: var(--image-crop-opacity-disabled);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.disabled .cropBox,
|
|
252
|
+
.disabled .handle {
|
|
253
|
+
// CSS keyword.
|
|
254
|
+
// stylelint-disable-next-line scale-unlimited/declaration-strict-value -- CSS keyword
|
|
255
|
+
cursor: not-allowed;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.srOnly {
|
|
259
|
+
@include visually-hidden;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Positioning wrapper over the canvas bottom; sits in the reserved TOOLBAR_RESERVE band.
|
|
263
|
+
.toolbar {
|
|
264
|
+
position: absolute;
|
|
265
|
+
bottom: var(--image-crop-toolbar-offset);
|
|
266
|
+
left: 50%;
|
|
267
|
+
display: flex;
|
|
268
|
+
align-items: center;
|
|
269
|
+
gap: var(--image-crop-toolbar-gap);
|
|
270
|
+
padding: var(--image-crop-toolbar-padding);
|
|
271
|
+
max-width: 100%;
|
|
272
|
+
overflow-x: auto;
|
|
273
|
+
transform: translateX(-50%);
|
|
274
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// ImageCrop.tokens.scss — component-scoped tokens for <ImageCrop>. Covers viewport surface, crop-box border, error state, and disabled mute. Cursor keywords and the scrim's literal 50% black stay raw in .module.scss.
|
|
2
|
+
:root {
|
|
3
|
+
// Viewport surface
|
|
4
|
+
--image-crop-viewport-bg: var(--color-bg-muted);
|
|
5
|
+
--image-crop-viewport-radius: var(--radius-md);
|
|
6
|
+
--image-crop-viewport-focus-color: var(--color-accent);
|
|
7
|
+
|
|
8
|
+
// Crop box outline
|
|
9
|
+
--image-crop-cropbox-border-color: var(--color-accent);
|
|
10
|
+
|
|
11
|
+
// Crop box handles + thirds grid
|
|
12
|
+
--image-crop-handle-size: var(--space-6);
|
|
13
|
+
--image-crop-handle-thickness: var(--border-width-strong);
|
|
14
|
+
--image-crop-handle-color: var(--color-fg-on-overlay);
|
|
15
|
+
--image-crop-grid-color: var(--color-fg-on-overlay);
|
|
16
|
+
--image-crop-grid-opacity: 0;
|
|
17
|
+
--image-crop-grid-opacity-active: 1;
|
|
18
|
+
|
|
19
|
+
// Toolbar positioning
|
|
20
|
+
// Room so overflow-x clipping doesn't cut button focus rings.
|
|
21
|
+
--image-crop-toolbar-padding: var(--space-1);
|
|
22
|
+
--image-crop-toolbar-gap: var(--space-2);
|
|
23
|
+
--image-crop-toolbar-offset: var(--space-3);
|
|
24
|
+
|
|
25
|
+
// Error state
|
|
26
|
+
--image-crop-error-gap: var(--space-2);
|
|
27
|
+
--image-crop-error-padding: var(--space-4);
|
|
28
|
+
--image-crop-error-fg: var(--color-danger);
|
|
29
|
+
--image-crop-error-font-size: var(--font-size-sm);
|
|
30
|
+
|
|
31
|
+
// Disabled mute
|
|
32
|
+
--image-crop-opacity-disabled: var(--opacity-disabled);
|
|
33
|
+
}
|