@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,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output MIME type and encoding options for `extractCropBlob`.
|
|
3
|
+
*/
|
|
4
|
+
export interface ExtractCropOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Output MIME type. Default `'image/png'` (lossless).
|
|
7
|
+
* - `'image/png'` — lossless, larger file size, supports transparency.
|
|
8
|
+
* - `'image/jpeg'` — smaller, lossy, no transparency. Use for photos.
|
|
9
|
+
* - `'image/webp'` — smaller than JPEG at similar quality, good browser support since 2020.
|
|
10
|
+
*/
|
|
11
|
+
type?: 'image/png' | 'image/jpeg' | 'image/webp';
|
|
12
|
+
/**
|
|
13
|
+
* Encoding quality for lossy formats (0..1). Default `0.92`. Ignored for
|
|
14
|
+
* PNG. Lower values = smaller file + more artifacts.
|
|
15
|
+
*/
|
|
16
|
+
quality?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Resize the output to this width in pixels (height proportional). Omit
|
|
19
|
+
* to keep the source-pixel crop dimensions (no resize). Useful for capping
|
|
20
|
+
* avatar uploads (e.g. `outputWidth: 512` for a 512×512 max). The height
|
|
21
|
+
* is computed from the source crop aspect ratio.
|
|
22
|
+
*/
|
|
23
|
+
outputWidth?: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Crop region in SOURCE-IMAGE pixel coordinates (not viewport pixels). Re-
|
|
28
|
+
* exported from `./ImageCrop` to keep `extractCropBlob`'s signature self-
|
|
29
|
+
* contained (consumers can import this utility without importing the
|
|
30
|
+
* component).
|
|
31
|
+
*/
|
|
32
|
+
export interface CropArea {
|
|
33
|
+
/** Top-left X in source-image pixels. */
|
|
34
|
+
x: number;
|
|
35
|
+
/** Top-left Y in source-image pixels. */
|
|
36
|
+
y: number;
|
|
37
|
+
/** Crop width in source-image pixels. */
|
|
38
|
+
width: number;
|
|
39
|
+
/** Crop height in source-image pixels. */
|
|
40
|
+
height: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Internal helper — load an image source (string URL, File, or Blob) into
|
|
45
|
+
* an HTMLImageElement and resolve when it's ready for canvas operations.
|
|
46
|
+
*
|
|
47
|
+
* Object URLs created from File/Blob are revoked after load to avoid leaks.
|
|
48
|
+
*/
|
|
49
|
+
function loadImage(src: string | File | Blob): Promise<HTMLImageElement> {
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
let createdObjectUrl = false;
|
|
52
|
+
const url =
|
|
53
|
+
typeof src === 'string' ? src : ((createdObjectUrl = true), URL.createObjectURL(src));
|
|
54
|
+
const img = new Image();
|
|
55
|
+
// crossOrigin: 'anonymous' lets us read pixels from cross-origin images
|
|
56
|
+
// IF the server returns the right CORS headers. Same-origin / data: /
|
|
57
|
+
// blob: URLs are unaffected. Without this, drawImage on cross-origin
|
|
58
|
+
// sources taints the canvas and toBlob() throws SecurityError.
|
|
59
|
+
img.crossOrigin = 'anonymous';
|
|
60
|
+
img.onload = () => {
|
|
61
|
+
if (createdObjectUrl) URL.revokeObjectURL(url);
|
|
62
|
+
resolve(img);
|
|
63
|
+
};
|
|
64
|
+
img.onerror = () => {
|
|
65
|
+
if (createdObjectUrl) URL.revokeObjectURL(url);
|
|
66
|
+
reject(new Error('Failed to load image for cropping'));
|
|
67
|
+
};
|
|
68
|
+
img.src = url;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Extract the cropped region of an image as a Blob via an off-screen canvas.
|
|
74
|
+
*
|
|
75
|
+
* Accepts the same `src` shape as `<ImageCrop>` (string URL, File, or Blob)
|
|
76
|
+
* and a `CropArea` in source-image pixel coordinates. Returns a Promise
|
|
77
|
+
* resolving to a Blob with the configured type/quality/resize.
|
|
78
|
+
*
|
|
79
|
+
* The canonical "Save handler" recipe — the consumer's submit code calls
|
|
80
|
+
* this to produce the cropped Blob, then uploads to their backend / S3 /
|
|
81
|
+
* etc.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* const handleSave = async () => {
|
|
85
|
+
* if (!crop) return;
|
|
86
|
+
* const blob = await extractCropBlob(file, crop, {
|
|
87
|
+
* type: 'image/jpeg',
|
|
88
|
+
* quality: 0.9,
|
|
89
|
+
* outputWidth: 512,
|
|
90
|
+
* });
|
|
91
|
+
* await uploadToS3(blob);
|
|
92
|
+
* };
|
|
93
|
+
*
|
|
94
|
+
* @remarks Cross-origin sources require the server to send
|
|
95
|
+
* `Access-Control-Allow-Origin` headers. Without them, the browser taints
|
|
96
|
+
* the canvas and `toBlob` rejects with a SecurityError. Same-origin URLs,
|
|
97
|
+
* `data:` URLs, `blob:` URLs (from File/Blob), and properly CORS-enabled
|
|
98
|
+
* third-party images are all safe.
|
|
99
|
+
*
|
|
100
|
+
* @throws Error if the image fails to load OR the canvas's `toBlob` returns
|
|
101
|
+
* `null` (typically a CORS tainting failure — see `@remarks`).
|
|
102
|
+
*/
|
|
103
|
+
export async function extractCropBlob(
|
|
104
|
+
src: string | File | Blob,
|
|
105
|
+
area: CropArea,
|
|
106
|
+
options: ExtractCropOptions = {},
|
|
107
|
+
): Promise<Blob> {
|
|
108
|
+
const { type = 'image/png', quality = 0.92, outputWidth } = options;
|
|
109
|
+
const img = await loadImage(src);
|
|
110
|
+
|
|
111
|
+
// Determine output dimensions. If outputWidth is set, scale proportionally;
|
|
112
|
+
// otherwise keep source-pixel crop dimensions.
|
|
113
|
+
const outW = outputWidth ?? area.width;
|
|
114
|
+
const outH = outputWidth ? outputWidth * (area.height / area.width) : area.height;
|
|
115
|
+
|
|
116
|
+
const canvas = document.createElement('canvas');
|
|
117
|
+
canvas.width = outW;
|
|
118
|
+
canvas.height = outH;
|
|
119
|
+
const ctx = canvas.getContext('2d');
|
|
120
|
+
if (!ctx) {
|
|
121
|
+
throw new Error('Failed to get 2D canvas context');
|
|
122
|
+
}
|
|
123
|
+
// drawImage(src, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) — the
|
|
124
|
+
// 9-arg form crops + scales in one call.
|
|
125
|
+
ctx.drawImage(img, area.x, area.y, area.width, area.height, 0, 0, outW, outH);
|
|
126
|
+
|
|
127
|
+
return new Promise((resolve, reject) => {
|
|
128
|
+
canvas.toBlob(
|
|
129
|
+
(blob) => {
|
|
130
|
+
if (blob) {
|
|
131
|
+
resolve(blob);
|
|
132
|
+
} else {
|
|
133
|
+
reject(new Error('Canvas toBlob returned null'));
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
type,
|
|
137
|
+
quality,
|
|
138
|
+
);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { ImageCrop } from './ImageCrop';
|
|
2
|
+
export type {
|
|
3
|
+
ImageCropProps,
|
|
4
|
+
ImageCropAspectOption,
|
|
5
|
+
ImageCropAspectRatio,
|
|
6
|
+
CropArea,
|
|
7
|
+
} from './ImageCrop';
|
|
8
|
+
export { extractCropBlob } from './extractCropBlob';
|
|
9
|
+
export type { ExtractCropOptions } from './extractCropBlob';
|
|
10
|
+
export { useCropPreview } from './useCropPreview';
|
|
11
|
+
export type { UseCropPreviewOptions, UseCropPreviewResult } from './useCropPreview';
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { extractCropBlob, type CropArea, type ExtractCropOptions } from './extractCropBlob';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Options for `useCropPreview`. All optional; sensible defaults match the
|
|
6
|
+
* canonical "avatar picker" recipe (JPEG, q=0.9, 256-wide preview).
|
|
7
|
+
*/
|
|
8
|
+
export interface UseCropPreviewOptions extends ExtractCropOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Milliseconds to wait after the latest crop change before encoding.
|
|
11
|
+
* Default `120`. Set higher for very large source images (4K phone
|
|
12
|
+
* photos can spend ~100ms inside `drawImage` + `toBlob`); set to `0` to
|
|
13
|
+
* encode synchronously on every change (useful in tests).
|
|
14
|
+
*/
|
|
15
|
+
debounceMs?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Result of `useCropPreview`. `encoding` is `true` between a crop change
|
|
20
|
+
* and the matching preview's arrival; consumers can fade the `<img>` or
|
|
21
|
+
* overlay a spinner during that window.
|
|
22
|
+
*/
|
|
23
|
+
export interface UseCropPreviewResult {
|
|
24
|
+
/**
|
|
25
|
+
* Object URL of the latest preview Blob. `null` until the first encode
|
|
26
|
+
* completes (or when `src`/`crop` is null). The URL is owned by the
|
|
27
|
+
* hook — it auto-revokes the previous URL whenever a new one is set
|
|
28
|
+
* AND on unmount. Do NOT call `URL.revokeObjectURL` on it yourself.
|
|
29
|
+
*/
|
|
30
|
+
previewUrl: string | null;
|
|
31
|
+
/**
|
|
32
|
+
* The latest encoded Blob itself. Same content as the URL; useful when
|
|
33
|
+
* the Save handler needs to POST the cropped result — no need to call
|
|
34
|
+
* `extractCropBlob` a second time, just `formData.append('file', previewBlob, 'cropped.jpg')`.
|
|
35
|
+
* `null` before the first encode completes.
|
|
36
|
+
*/
|
|
37
|
+
previewBlob: Blob | null;
|
|
38
|
+
/** Latest preview's encoded byte size, or `null` before the first encode. */
|
|
39
|
+
previewSize: number | null;
|
|
40
|
+
/**
|
|
41
|
+
* `true` from the moment `crop` (or any option) changes until the new
|
|
42
|
+
* preview lands. Use to drive a loading affordance (CircularProgress,
|
|
43
|
+
* opacity fade, "Re-encoding…" label).
|
|
44
|
+
*/
|
|
45
|
+
encoding: boolean;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Live-encoded preview of a cropped image. Produces a Blob via
|
|
50
|
+
* `extractCropBlob` on every `crop` change (debounced), exposes the
|
|
51
|
+
* resulting object URL, byte size, and an `encoding` flag for loading UI.
|
|
52
|
+
*
|
|
53
|
+
* Designed for the canonical CRM "avatar / cover photo" pick → crop → save
|
|
54
|
+
* flow: the user sees the cropped result update live as they drag/zoom,
|
|
55
|
+
* and the consumer's Save handler can `await extractCropBlob(...)` once
|
|
56
|
+
* the user confirms (the hook does NOT keep the Blob around — only the
|
|
57
|
+
* URL — so the Save call re-encodes; that's fine because the user only
|
|
58
|
+
* Saves once per session).
|
|
59
|
+
*
|
|
60
|
+
* Internally:
|
|
61
|
+
* - Debounces the encode by `debounceMs` (default 120) so rapid drags/zooms
|
|
62
|
+
* don't spam the encoder.
|
|
63
|
+
* - Uses a generation counter to discard stale in-flight encodes — without
|
|
64
|
+
* this, a slow encode from an older crop could resolve AFTER a newer one
|
|
65
|
+
* and overwrite the preview img with the wrong frame.
|
|
66
|
+
* - Auto-revokes its object URLs on replacement and on unmount.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* // Avatar picker:
|
|
70
|
+
* const [file, setFile] = useState<File | null>(null);
|
|
71
|
+
* const [crop, setCrop] = useState<CropArea | null>(null);
|
|
72
|
+
* const { previewUrl, encoding } = useCropPreview(file, crop, {
|
|
73
|
+
* type: 'image/jpeg',
|
|
74
|
+
* quality: 0.9,
|
|
75
|
+
* outputWidth: 256,
|
|
76
|
+
* });
|
|
77
|
+
*
|
|
78
|
+
* return (
|
|
79
|
+
* <Stack gap="md">
|
|
80
|
+
* <FileUpload onFilesAdded={([f]) => setFile(f)} ... />
|
|
81
|
+
* {file && (
|
|
82
|
+
* <>
|
|
83
|
+
* <ImageCrop src={file} value={crop} onChange={setCrop} aspectRatio={1} />
|
|
84
|
+
* {previewUrl && (
|
|
85
|
+
* <img src={previewUrl} style={{ opacity: encoding ? 0.5 : 1 }} />
|
|
86
|
+
* )}
|
|
87
|
+
* </>
|
|
88
|
+
* )}
|
|
89
|
+
* </Stack>
|
|
90
|
+
* );
|
|
91
|
+
*
|
|
92
|
+
* @remarks When NOT to use
|
|
93
|
+
* - For one-shot extraction (the user clicks "Save" and you need the Blob
|
|
94
|
+
* once). Call `extractCropBlob` directly in the Save handler.
|
|
95
|
+
* - For server-side cropping. Send the `crop` coordinates instead.
|
|
96
|
+
*
|
|
97
|
+
* @remarks Anti-patterns
|
|
98
|
+
* - ❌ Calling `URL.revokeObjectURL(previewUrl)` manually. The hook owns
|
|
99
|
+
* the URL lifecycle. Revoking it yourself produces broken-image renders.
|
|
100
|
+
* - ❌ Using the hook with `outputWidth` matching the source image (e.g.,
|
|
101
|
+
* 4080 for a 4080×3072 photo). The encode becomes expensive on every
|
|
102
|
+
* drag tick; cap `outputWidth` at the display size you actually need.
|
|
103
|
+
*/
|
|
104
|
+
export function useCropPreview(
|
|
105
|
+
src: string | File | Blob | null | undefined,
|
|
106
|
+
crop: CropArea | null,
|
|
107
|
+
options: UseCropPreviewOptions = {},
|
|
108
|
+
): UseCropPreviewResult {
|
|
109
|
+
const { type = 'image/jpeg', quality = 0.9, outputWidth, debounceMs = 120 } = options;
|
|
110
|
+
|
|
111
|
+
const [previewUrl, setPreviewUrl] = useState<string | null>(null);
|
|
112
|
+
const [previewBlob, setPreviewBlob] = useState<Blob | null>(null);
|
|
113
|
+
const [previewSize, setPreviewSize] = useState<number | null>(null);
|
|
114
|
+
const [encoding, setEncoding] = useState(false);
|
|
115
|
+
|
|
116
|
+
const urlRef = useRef<string | null>(null);
|
|
117
|
+
const genRef = useRef(0);
|
|
118
|
+
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
if (!src || !crop) {
|
|
121
|
+
if (urlRef.current) {
|
|
122
|
+
URL.revokeObjectURL(urlRef.current);
|
|
123
|
+
urlRef.current = null;
|
|
124
|
+
}
|
|
125
|
+
setPreviewUrl(null);
|
|
126
|
+
setPreviewBlob(null);
|
|
127
|
+
setPreviewSize(null);
|
|
128
|
+
setEncoding(false);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const gen = ++genRef.current;
|
|
132
|
+
setEncoding(true);
|
|
133
|
+
const handle = setTimeout(async () => {
|
|
134
|
+
try {
|
|
135
|
+
const blob = await extractCropBlob(src, crop, { type, quality, outputWidth });
|
|
136
|
+
if (gen !== genRef.current) return; // a newer crop has superseded us
|
|
137
|
+
if (urlRef.current) URL.revokeObjectURL(urlRef.current);
|
|
138
|
+
const url = URL.createObjectURL(blob);
|
|
139
|
+
urlRef.current = url;
|
|
140
|
+
setPreviewUrl(url);
|
|
141
|
+
setPreviewBlob(blob);
|
|
142
|
+
setPreviewSize(blob.size);
|
|
143
|
+
setEncoding(false);
|
|
144
|
+
} catch {
|
|
145
|
+
if (gen !== genRef.current) return;
|
|
146
|
+
setEncoding(false);
|
|
147
|
+
}
|
|
148
|
+
}, debounceMs);
|
|
149
|
+
return () => clearTimeout(handle);
|
|
150
|
+
}, [src, crop, type, quality, outputWidth, debounceMs]);
|
|
151
|
+
|
|
152
|
+
// Cleanup on unmount.
|
|
153
|
+
useEffect(
|
|
154
|
+
() => () => {
|
|
155
|
+
if (urlRef.current) URL.revokeObjectURL(urlRef.current);
|
|
156
|
+
},
|
|
157
|
+
[],
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
return { previewUrl, previewBlob, previewSize, encoding };
|
|
161
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
@use './Indent.tokens';
|
|
2
|
+
|
|
3
|
+
// No base layout of children — Indent only pads its OWN box (mirrors Constrain,
|
|
4
|
+
// which only sizes its own box). `padding-inline-start` is a logical property:
|
|
5
|
+
// left gutter in LTR, right in RTL, for free. padding (not margin) is allowed
|
|
6
|
+
// under Hard rule 4.
|
|
7
|
+
.indent {
|
|
8
|
+
padding-inline-start: calc(var(--indent-level, 1) * var(--indent-gutter));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.gutter-xs {
|
|
12
|
+
--indent-gutter: var(--indent-gutter-xs);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.gutter-sm {
|
|
16
|
+
--indent-gutter: var(--indent-gutter-sm);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.gutter-md {
|
|
20
|
+
--indent-gutter: var(--indent-gutter-md);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.gutter-lg {
|
|
24
|
+
--indent-gutter: var(--indent-gutter-lg);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.gutter-xl {
|
|
28
|
+
--indent-gutter: var(--indent-gutter-xl);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.gutter-2xl {
|
|
32
|
+
--indent-gutter: var(--indent-gutter-2xl);
|
|
33
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Component tokens for <Indent> — default to the --space-* primitives. Same
|
|
2
|
+
// name→px mapping as Stack's gap, so an Indent gutter reads at the same scale.
|
|
3
|
+
:root {
|
|
4
|
+
--indent-gutter-xs: var(--space-1); // 4px
|
|
5
|
+
--indent-gutter-sm: var(--space-2); // 8px
|
|
6
|
+
--indent-gutter-md: var(--space-3); // 12px
|
|
7
|
+
--indent-gutter-lg: var(--space-4); // 16px
|
|
8
|
+
--indent-gutter-xl: var(--space-6); // 24px
|
|
9
|
+
--indent-gutter-2xl: var(--space-8); // 32px
|
|
10
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { forwardRef, type CSSProperties, type HTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import styles from './Indent.module.scss';
|
|
4
|
+
|
|
5
|
+
/** Per-level indent size — a spacing step. */
|
|
6
|
+
export type IndentGutter = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
|
|
7
|
+
|
|
8
|
+
export interface IndentProps extends HTMLAttributes<HTMLDivElement> {
|
|
9
|
+
/**
|
|
10
|
+
* Nesting depth — multiplies the gutter. `0` = flush (no indent, e.g. a
|
|
11
|
+
* root-level comment). Defaults to `1` (one gutter). Negative values clamp to `0`.
|
|
12
|
+
*/
|
|
13
|
+
level?: number;
|
|
14
|
+
/**
|
|
15
|
+
* Per-level indent size — a spacing step. Defaults to `'lg'` (16px per level).
|
|
16
|
+
* - `xs` 4px · `sm` 8px · `md` 12px · `lg` 16px · `xl` 24px · `2xl` 32px
|
|
17
|
+
*/
|
|
18
|
+
gutter?: IndentGutter;
|
|
19
|
+
/** The nested content to indent. Required — an Indent with nothing inside indents nothing. */
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Indentation primitive — indents its own box by `level × gutter`.
|
|
25
|
+
* @see docs/components/Indent.md
|
|
26
|
+
*/
|
|
27
|
+
// {...rest} last so consumer attrs win (Pattern A). But `style` is spread FIRST in
|
|
28
|
+
// the merge below so the internal --indent-level wins — depth is set via the `level`
|
|
29
|
+
// prop, not a raw style var (same var-protection as Grid's --grid-columns).
|
|
30
|
+
export const Indent = forwardRef<HTMLDivElement, IndentProps>(function Indent(
|
|
31
|
+
{ level = 1, gutter = 'lg', className, style, children, ...rest },
|
|
32
|
+
ref,
|
|
33
|
+
) {
|
|
34
|
+
// Clamp to a non-negative, finite depth (a NaN/∞ level would yield an invalid calc()).
|
|
35
|
+
const indentLevel = Number.isFinite(level) ? Math.max(0, level) : 0;
|
|
36
|
+
return (
|
|
37
|
+
<div
|
|
38
|
+
ref={ref}
|
|
39
|
+
className={clsx(styles.indent, styles[`gutter-${gutter}`], className)}
|
|
40
|
+
style={{ ...style, ['--indent-level' as string]: indentLevel } as CSSProperties}
|
|
41
|
+
{...rest}
|
|
42
|
+
>
|
|
43
|
+
{children}
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
});
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
@use '../../styles/mixins' as *;
|
|
2
|
+
@use './Input.tokens';
|
|
3
|
+
|
|
4
|
+
.input {
|
|
5
|
+
display: block;
|
|
6
|
+
width: 100%;
|
|
7
|
+
border: var(--border-width) solid var(--input-border-color);
|
|
8
|
+
border-radius: var(--input-radius);
|
|
9
|
+
background: var(--input-bg);
|
|
10
|
+
color: var(--input-fg);
|
|
11
|
+
font-family: inherit;
|
|
12
|
+
line-height: var(--input-line-height);
|
|
13
|
+
transition:
|
|
14
|
+
border-color var(--transition-fast),
|
|
15
|
+
box-shadow var(--transition-fast);
|
|
16
|
+
|
|
17
|
+
&::placeholder {
|
|
18
|
+
color: var(--input-placeholder-fg);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
&:focus-visible {
|
|
22
|
+
border-color: var(--input-border-color-focus);
|
|
23
|
+
|
|
24
|
+
@include focus-ring(var(--input-ring-focus));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&:disabled {
|
|
28
|
+
background: var(--input-bg-disabled);
|
|
29
|
+
border-color: var(--input-border-color-disabled);
|
|
30
|
+
color: var(--input-fg-disabled);
|
|
31
|
+
cursor: not-allowed;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Size modifiers. md is the default — match the previous hard-coded values.
|
|
36
|
+
.size-sm {
|
|
37
|
+
height: var(--input-height-sm);
|
|
38
|
+
padding: 0 var(--input-padding-x-sm);
|
|
39
|
+
font-size: var(--input-font-size-sm);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.size-md {
|
|
43
|
+
height: var(--input-height-md);
|
|
44
|
+
padding: 0 var(--input-padding-x-md);
|
|
45
|
+
font-size: var(--input-font-size-md);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.size-lg {
|
|
49
|
+
height: var(--input-height-lg);
|
|
50
|
+
padding: 0 var(--input-padding-x-lg);
|
|
51
|
+
font-size: var(--input-font-size-lg);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.invalid {
|
|
55
|
+
border-color: var(--input-border-color-invalid);
|
|
56
|
+
|
|
57
|
+
&:focus-visible {
|
|
58
|
+
border-color: var(--input-border-color-invalid);
|
|
59
|
+
|
|
60
|
+
@include focus-ring(var(--input-ring-invalid));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// `suggestions` popup. Width and the viewport room for max-height are written
|
|
65
|
+
// by Suggestions.tsx's Floating UI `size` middleware; position comes from its
|
|
66
|
+
// inline floating styles. Mirrors Select's option list.
|
|
67
|
+
.suggestions {
|
|
68
|
+
z-index: var(--z-popover);
|
|
69
|
+
box-sizing: border-box;
|
|
70
|
+
max-height: min(
|
|
71
|
+
var(--input-suggestions-max-height),
|
|
72
|
+
var(--input-suggestions-available-height, 100vh)
|
|
73
|
+
);
|
|
74
|
+
overflow-y: auto;
|
|
75
|
+
overscroll-behavior: contain;
|
|
76
|
+
padding: var(--input-suggestions-padding);
|
|
77
|
+
list-style: none;
|
|
78
|
+
background: var(--input-suggestions-bg);
|
|
79
|
+
border: var(--border-width) solid var(--input-suggestions-border-color);
|
|
80
|
+
border-radius: var(--input-suggestions-radius);
|
|
81
|
+
box-shadow: var(--input-suggestions-shadow);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.suggestions[data-in-overlay] {
|
|
85
|
+
z-index: var(--z-overlay-floating);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.suggestion {
|
|
89
|
+
padding: var(--input-suggestion-padding-y) var(--input-suggestion-padding-x);
|
|
90
|
+
font-size: var(--input-suggestion-font-size);
|
|
91
|
+
color: var(--input-suggestion-fg);
|
|
92
|
+
cursor: pointer;
|
|
93
|
+
border-radius: var(--input-suggestion-radius);
|
|
94
|
+
overflow-wrap: anywhere;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.suggestionActive {
|
|
98
|
+
background: var(--input-suggestion-bg-active);
|
|
99
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Input.tokens.scss — component-scoped tokens for <Input>. Defaults preserve byte-identical visual output. Sister field components (DatePicker, DateRangePicker, Select) own their own wrappers but mirror these values.
|
|
2
|
+
:root {
|
|
3
|
+
// Surface
|
|
4
|
+
--input-bg: var(--color-bg);
|
|
5
|
+
--input-fg: var(--color-fg);
|
|
6
|
+
--input-border-color: var(--color-border-strong);
|
|
7
|
+
--input-radius: var(--radius-md);
|
|
8
|
+
--input-line-height: var(--line-height-normal);
|
|
9
|
+
|
|
10
|
+
// Placeholder
|
|
11
|
+
--input-placeholder-fg: var(--color-fg-subtle);
|
|
12
|
+
|
|
13
|
+
// Focus
|
|
14
|
+
--input-border-color-focus: var(--color-accent);
|
|
15
|
+
--input-ring-focus: var(--ring-accent);
|
|
16
|
+
|
|
17
|
+
// Disabled
|
|
18
|
+
--input-bg-disabled: var(--color-bg-subtle);
|
|
19
|
+
--input-border-color-disabled: var(--color-border);
|
|
20
|
+
--input-fg-disabled: var(--color-fg-subtle);
|
|
21
|
+
|
|
22
|
+
// Invalid
|
|
23
|
+
--input-border-color-invalid: var(--color-danger);
|
|
24
|
+
--input-ring-invalid: var(--ring-danger);
|
|
25
|
+
|
|
26
|
+
// Size — height per size
|
|
27
|
+
--input-height-sm: var(--size-sm);
|
|
28
|
+
--input-height-md: var(--size-md);
|
|
29
|
+
--input-height-lg: var(--size-lg);
|
|
30
|
+
|
|
31
|
+
// Size — horizontal padding per size
|
|
32
|
+
--input-padding-x-sm: var(--space-2);
|
|
33
|
+
--input-padding-x-md: var(--space-3);
|
|
34
|
+
--input-padding-x-lg: var(--space-3);
|
|
35
|
+
|
|
36
|
+
// Size — font-size per size
|
|
37
|
+
--input-font-size-sm: var(--font-size-sm);
|
|
38
|
+
--input-font-size-md: var(--font-size-md);
|
|
39
|
+
--input-font-size-lg: var(--font-size-lg);
|
|
40
|
+
|
|
41
|
+
// Suggestions popup — same values as Select's listbox + option rows.
|
|
42
|
+
--input-suggestions-bg: var(--color-bg);
|
|
43
|
+
--input-suggestions-border-color: var(--color-border);
|
|
44
|
+
--input-suggestions-radius: var(--radius-md);
|
|
45
|
+
--input-suggestions-shadow: var(--shadow-md);
|
|
46
|
+
--input-suggestions-padding: var(--space-1);
|
|
47
|
+
--input-suggestions-max-height: 320px;
|
|
48
|
+
--input-suggestion-padding-y: var(--space-2);
|
|
49
|
+
--input-suggestion-padding-x: var(--space-3);
|
|
50
|
+
--input-suggestion-font-size: var(--font-size-md);
|
|
51
|
+
--input-suggestion-fg: var(--color-fg);
|
|
52
|
+
--input-suggestion-radius: var(--radius-sm);
|
|
53
|
+
--input-suggestion-bg-active: var(--color-bg-muted);
|
|
54
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { forwardRef, useMemo, type InputHTMLAttributes } from 'react';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { mergeRefs } from '../_internal/refs';
|
|
4
|
+
import { useSuggestions } from './Suggestions';
|
|
5
|
+
import styles from './Input.module.scss';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Field height + type scale. Pairs with `<Button>` and `<Select>` sizes.
|
|
9
|
+
*/
|
|
10
|
+
export type InputSize = 'sm' | 'md' | 'lg';
|
|
11
|
+
|
|
12
|
+
export interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {
|
|
13
|
+
/**
|
|
14
|
+
* Toggles the error visual (red border + focus ring) and sets `aria-invalid="true"`.
|
|
15
|
+
* Pair with a visible error message and `aria-describedby` pointing at the message id.
|
|
16
|
+
*/
|
|
17
|
+
invalid?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Visual size. Defaults to `'md'`.
|
|
20
|
+
* - `'sm'` — 24px tall; toolbars, secondary forms.
|
|
21
|
+
* - `'md'` — 32px tall (default); most form contexts.
|
|
22
|
+
* - `'lg'` — 40px tall; hero search, mobile-friendly forms.
|
|
23
|
+
*
|
|
24
|
+
* Same scale as `<Select>`; fields have no `xs` (unlike `<Button>`).
|
|
25
|
+
*
|
|
26
|
+
* Note: this shadows the native HTML `<input size>` attribute (visible
|
|
27
|
+
* character count). If you need that legacy attribute, set width via
|
|
28
|
+
* `style` or a parent container.
|
|
29
|
+
*/
|
|
30
|
+
size?: InputSize;
|
|
31
|
+
/**
|
|
32
|
+
* Block browser autofill AND password managers from offering to fill
|
|
33
|
+
* this input. Applies the standard set of opt-out hints:
|
|
34
|
+
* - `autoComplete="off"`
|
|
35
|
+
* - `data-1p-ignore` (1Password)
|
|
36
|
+
* - `data-lpignore="true"` (LastPass)
|
|
37
|
+
* - `data-form-type="other"` (generic "not a login field")
|
|
38
|
+
*
|
|
39
|
+
* **Smart default**: when omitted, the input blocks autofill iff `autoComplete`
|
|
40
|
+
* is also omitted (or `'off'`). Explicit autocomplete hints
|
|
41
|
+
* (`autoComplete="email"`, `"current-password"`, `"username"`, etc.) opt back
|
|
42
|
+
* IN to autofill — the assumption is that a consumer specifying autoComplete
|
|
43
|
+
* actually wants password-manager interaction. Pass `disableAutofill={true}`
|
|
44
|
+
* to force-block even with an autocomplete hint, or `false` to force-allow
|
|
45
|
+
* (except while `suggestions` is active, which always blocks).
|
|
46
|
+
*/
|
|
47
|
+
disableAutofill?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Values to suggest while the value stays free text (e.g. the user's other
|
|
50
|
+
* workspace slugs). Makes the input an ARIA combobox with a suggestion list:
|
|
51
|
+
* it opens on focus, click or ↓ showing every suggestion, then filters by
|
|
52
|
+
* case-insensitive substring once the user types. ↑/↓ + Enter or a click
|
|
53
|
+
* fills the value and fires `onChange` exactly as typing would. Ignored when
|
|
54
|
+
* empty or `readOnly`. Browser autofill is forced off while active (even with
|
|
55
|
+
* an `autoComplete` hint) so its dropdown can't stack on this one. Default:
|
|
56
|
+
* none (a plain textbox). For a fixed set of allowed values use `<Select>`
|
|
57
|
+
* instead.
|
|
58
|
+
*/
|
|
59
|
+
suggestions?: readonly string[];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const AUTOFILL_DISABLED_PROPS = {
|
|
63
|
+
autoComplete: 'off' as const,
|
|
64
|
+
'data-1p-ignore': '' as const,
|
|
65
|
+
'data-lpignore': 'true' as const,
|
|
66
|
+
'data-form-type': 'other' as const,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Single-line text input that forwards all native `<input>` attributes.
|
|
71
|
+
* @see docs/components/Input.md
|
|
72
|
+
*/
|
|
73
|
+
export const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
|
|
74
|
+
{ invalid, size = 'md', disableAutofill, suggestions, className, ...props },
|
|
75
|
+
ref,
|
|
76
|
+
) {
|
|
77
|
+
const combobox = useSuggestions(suggestions, props.readOnly, props);
|
|
78
|
+
const mergedRef = useMemo(() => mergeRefs(ref, combobox.inputRef), [ref, combobox.inputRef]);
|
|
79
|
+
|
|
80
|
+
// Smart default: when `disableAutofill` is undefined, block autofill iff
|
|
81
|
+
// the consumer hasn't set a meaningful `autoComplete`. Explicit `true` /
|
|
82
|
+
// `false` always wins over the heuristic (except while `suggestions` is active).
|
|
83
|
+
const hasAutocompleteHint =
|
|
84
|
+
typeof props.autoComplete === 'string' && props.autoComplete !== 'off';
|
|
85
|
+
const blockAutofill = disableAutofill ?? !hasAutocompleteHint;
|
|
86
|
+
|
|
87
|
+
return (
|
|
88
|
+
<>
|
|
89
|
+
<input
|
|
90
|
+
// Plain consumer ref unless it's a combobox (no extra commit either way).
|
|
91
|
+
ref={combobox.enabled ? mergedRef : ref}
|
|
92
|
+
aria-invalid={invalid || undefined}
|
|
93
|
+
{...(blockAutofill ? AUTOFILL_DISABLED_PROPS : {})}
|
|
94
|
+
{...props}
|
|
95
|
+
// Suggestions force autofill off, beating any consumer autoComplete.
|
|
96
|
+
{...(combobox.enabled ? AUTOFILL_DISABLED_PROPS : {})}
|
|
97
|
+
// After {...props} so the combobox ARIA contract wins; its handlers
|
|
98
|
+
// already chain the consumer's.
|
|
99
|
+
{...combobox.inputProps}
|
|
100
|
+
className={clsx(styles.input, styles[`size-${size}`], invalid && styles.invalid, className)}
|
|
101
|
+
/>
|
|
102
|
+
{combobox.popup}
|
|
103
|
+
</>
|
|
104
|
+
);
|
|
105
|
+
});
|