@eocrm/design-system 0.0.0-stage → 0.6.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI-PRIMER.md +341 -0
- package/README.md +262 -2
- package/docs/components/Accordion.md +114 -0
- package/docs/components/AgentAvatar.md +58 -0
- package/docs/components/Alert.md +81 -0
- package/docs/components/AppLayout.md +70 -0
- package/docs/components/Avatar.md +49 -0
- package/docs/components/AvatarGroup.md +47 -0
- package/docs/components/Badge.md +60 -0
- package/docs/components/Banner.md +89 -0
- package/docs/components/BrandIcon.md +32 -0
- package/docs/components/Breadcrumb.md +72 -0
- package/docs/components/Button.md +107 -0
- package/docs/components/ButtonGroup.md +78 -0
- package/docs/components/Calendar.md +158 -0
- package/docs/components/Card.md +165 -0
- package/docs/components/CatalogPicker.md +83 -0
- package/docs/components/Chart.md +114 -0
- package/docs/components/ChatBubble.md +55 -0
- package/docs/components/ChatLauncher.md +97 -0
- package/docs/components/Checkbox.md +55 -0
- package/docs/components/CircularProgress.md +53 -0
- package/docs/components/Cluster.md +96 -0
- package/docs/components/Code.md +35 -0
- package/docs/components/CodeBlock.md +67 -0
- package/docs/components/ColorPicker.md +115 -0
- package/docs/components/ConfirmationPopover.md +70 -0
- package/docs/components/Constrain.md +39 -0
- package/docs/components/CurrencySelect.md +57 -0
- package/docs/components/CursorPagination.md +43 -0
- package/docs/components/DashboardCanvas.md +79 -0
- package/docs/components/DashboardWidget.md +131 -0
- package/docs/components/DataTable.md +88 -0
- package/docs/components/DatePicker.md +68 -0
- package/docs/components/DateRangePicker.md +71 -0
- package/docs/components/DateStrip.md +56 -0
- package/docs/components/DefinitionList.md +82 -0
- package/docs/components/Divider.md +57 -0
- package/docs/components/Dot.md +26 -0
- package/docs/components/Drawer.md +94 -0
- package/docs/components/DropdownMenu.md +299 -0
- package/docs/components/EmojiPicker.md +84 -0
- package/docs/components/EmptyState.md +55 -0
- package/docs/components/EntityChip.md +102 -0
- package/docs/components/ErrorState.md +72 -0
- package/docs/components/Field.md +91 -0
- package/docs/components/FileUpload.md +109 -0
- package/docs/components/FilterChip.md +88 -0
- package/docs/components/FlowCanvas.md +108 -0
- package/docs/components/FormRow.md +31 -0
- package/docs/components/FormSection.md +37 -0
- package/docs/components/Grid.md +103 -0
- package/docs/components/Highlight.md +75 -0
- package/docs/components/HighlightedText.md +50 -0
- package/docs/components/IconPicker.md +134 -0
- package/docs/components/IconTile.md +30 -0
- package/docs/components/Image.md +84 -0
- package/docs/components/ImageCrop.md +163 -0
- package/docs/components/Indent.md +31 -0
- package/docs/components/InlineDatePicker.md +58 -0
- package/docs/components/InlineDateRangePicker.md +57 -0
- package/docs/components/Input.md +54 -0
- package/docs/components/Kanban.md +122 -0
- package/docs/components/Kbd.md +41 -0
- package/docs/components/Lightbox.md +105 -0
- package/docs/components/Link.md +65 -0
- package/docs/components/LinkCard.md +41 -0
- package/docs/components/LiquidEditor.md +84 -0
- package/docs/components/List.md +68 -0
- package/docs/components/LiveRegion.md +29 -0
- package/docs/components/LocaleProvider.md +25 -0
- package/docs/components/Logo.md +41 -0
- package/docs/components/Masonry.md +48 -0
- package/docs/components/MediaTile.md +95 -0
- package/docs/components/Modal.md +107 -0
- package/docs/components/MoneyInput.md +62 -0
- package/docs/components/OptionsPicker.md +123 -0
- package/docs/components/OtpInput.md +65 -0
- package/docs/components/Page.md +35 -0
- package/docs/components/PageHeader.md +133 -0
- package/docs/components/Pagination.md +44 -0
- package/docs/components/Palette.md +32 -0
- package/docs/components/PasswordInput.md +45 -0
- package/docs/components/PasswordStrengthMeter.md +27 -0
- package/docs/components/PersonDisplay.md +153 -0
- package/docs/components/PhoneInput.md +54 -0
- package/docs/components/PillMenu.md +91 -0
- package/docs/components/Popover.md +127 -0
- package/docs/components/Progress.md +56 -0
- package/docs/components/QrCode.md +34 -0
- package/docs/components/Radio.md +37 -0
- package/docs/components/RadioGroup.md +56 -0
- package/docs/components/Rail.md +191 -0
- package/docs/components/RelativeDateInput.md +114 -0
- package/docs/components/RichText.md +44 -0
- package/docs/components/RichTextEditor.md +112 -0
- package/docs/components/Screen.md +37 -0
- package/docs/components/ScrollArea.md +39 -0
- package/docs/components/Select.md +131 -0
- package/docs/components/SettingRow.md +98 -0
- package/docs/components/Skeleton.md +68 -0
- package/docs/components/Slider.md +92 -0
- package/docs/components/SlotGrid.md +55 -0
- package/docs/components/SocialButton.md +31 -0
- package/docs/components/Sortable.md +127 -0
- package/docs/components/SortableGroup.md +52 -0
- package/docs/components/Sparkline.md +51 -0
- package/docs/components/Split.md +76 -0
- package/docs/components/Stack.md +59 -0
- package/docs/components/StagePath.md +66 -0
- package/docs/components/StatGroup.md +61 -0
- package/docs/components/StatTile.md +58 -0
- package/docs/components/Sticky.md +69 -0
- package/docs/components/Switch.md +89 -0
- package/docs/components/Table.md +184 -0
- package/docs/components/TableOfContents.md +76 -0
- package/docs/components/Tabs.md +94 -0
- package/docs/components/Text.md +63 -0
- package/docs/components/Textarea.md +59 -0
- package/docs/components/Thread.md +52 -0
- package/docs/components/TimeField.md +70 -0
- package/docs/components/Timeline.md +57 -0
- package/docs/components/Title.md +54 -0
- package/docs/components/ToastViewport.md +61 -0
- package/docs/components/Tooltip.md +63 -0
- package/docs/components/TopBar.md +214 -0
- package/docs/components/Tour.md +85 -0
- package/docs/components/TreeView.md +113 -0
- package/docs/components/VisuallyHidden.md +43 -0
- package/docs/components/WidgetPreview.md +54 -0
- package/docs/components/useBelowBreakpoint.md +11 -0
- package/docs/components/useMonth.md +18 -0
- package/docs/setup.md +51 -0
- package/docs/theming.md +95 -0
- package/docs/tokens.md +123 -0
- package/docs/transient-state.md +56 -0
- package/package.json +82 -4
- package/src/_meta/manifest.ts +293 -0
- package/src/app/AppProvider.tsx +78 -0
- package/src/app/index.ts +3 -0
- package/src/app/themeTokens.ts +95 -0
- package/src/calendar/dateMath.ts +114 -0
- package/src/calendar/formatters.ts +75 -0
- package/src/calendar/index.ts +39 -0
- package/src/calendar/types.ts +36 -0
- package/src/calendar/useAgenda.ts +70 -0
- package/src/calendar/useDay.ts +51 -0
- package/src/calendar/useMonth.ts +82 -0
- package/src/calendar/useWeek.ts +62 -0
- package/src/calendar/weekInfo.ts +83 -0
- package/src/components/Accordion/Accordion.module.scss +304 -0
- package/src/components/Accordion/Accordion.tokens.scss +64 -0
- package/src/components/Accordion/Accordion.tsx +272 -0
- package/src/components/Accordion/AccordionContent.tsx +36 -0
- package/src/components/Accordion/AccordionItem.tsx +66 -0
- package/src/components/Accordion/AccordionTrigger.tsx +121 -0
- package/src/components/Accordion/context.ts +47 -0
- package/src/components/Accordion/index.ts +14 -0
- package/src/components/Alert/Alert.module.scss +92 -0
- package/src/components/Alert/Alert.tokens.scss +60 -0
- package/src/components/Alert/Alert.tsx +136 -0
- package/src/components/Alert/index.ts +2 -0
- package/src/components/AppLayout/AppLayout.module.scss +130 -0
- package/src/components/AppLayout/AppLayout.tokens.scss +27 -0
- package/src/components/AppLayout/AppLayout.tsx +211 -0
- package/src/components/AppLayout/index.ts +2 -0
- package/src/components/Avatar/AgentAvatar.module.scss +117 -0
- package/src/components/Avatar/AgentAvatar.tsx +122 -0
- package/src/components/Avatar/Avatar.module.scss +181 -0
- package/src/components/Avatar/Avatar.tokens.scss +107 -0
- package/src/components/Avatar/Avatar.tsx +210 -0
- package/src/components/Avatar/AvatarGroup.module.scss +128 -0
- package/src/components/Avatar/AvatarGroup.tsx +119 -0
- package/src/components/Avatar/AvatarGroupContext.tsx +20 -0
- package/src/components/Avatar/index.ts +6 -0
- package/src/components/Badge/Badge.module.scss +124 -0
- package/src/components/Badge/Badge.tokens.scss +74 -0
- package/src/components/Badge/Badge.tsx +164 -0
- package/src/components/Badge/index.ts +2 -0
- package/src/components/Banner/Banner.module.scss +73 -0
- package/src/components/Banner/Banner.tokens.scss +51 -0
- package/src/components/Banner/Banner.tsx +138 -0
- package/src/components/Banner/index.ts +2 -0
- package/src/components/BrandIcon/BrandIcon.module.scss +5 -0
- package/src/components/BrandIcon/BrandIcon.tsx +99 -0
- package/src/components/BrandIcon/index.ts +2 -0
- package/src/components/Breadcrumb/Breadcrumb.module.scss +32 -0
- package/src/components/Breadcrumb/Breadcrumb.tokens.scss +9 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +146 -0
- package/src/components/Breadcrumb/index.ts +2 -0
- package/src/components/Button/Button.module.scss +167 -0
- package/src/components/Button/Button.tokens.scss +90 -0
- package/src/components/Button/Button.tsx +205 -0
- package/src/components/Button/index.ts +2 -0
- package/src/components/ButtonGroup/ButtonGroup.module.scss +134 -0
- package/src/components/ButtonGroup/ButtonGroup.tokens.scss +42 -0
- package/src/components/ButtonGroup/ButtonGroup.tsx +278 -0
- package/src/components/ButtonGroup/ButtonGroupItem.tsx +74 -0
- package/src/components/ButtonGroup/context.ts +45 -0
- package/src/components/ButtonGroup/index.ts +2 -0
- package/src/components/Calendar/AgendaView.module.scss +231 -0
- package/src/components/Calendar/AgendaView.tsx +214 -0
- package/src/components/Calendar/AllDayBand.module.scss +18 -0
- package/src/components/Calendar/AllDayBand.tsx +75 -0
- package/src/components/Calendar/Calendar.module.scss +23 -0
- package/src/components/Calendar/Calendar.tokens.scss +262 -0
- package/src/components/Calendar/Calendar.tsx +370 -0
- package/src/components/Calendar/DayCell.module.scss +30 -0
- package/src/components/Calendar/DayCell.tsx +50 -0
- package/src/components/Calendar/DayView.module.scss +10 -0
- package/src/components/Calendar/DayView.tsx +163 -0
- package/src/components/Calendar/EventChip.module.scss +171 -0
- package/src/components/Calendar/EventChip.tsx +115 -0
- package/src/components/Calendar/HourGrid.module.scss +123 -0
- package/src/components/Calendar/HourGrid.tsx +381 -0
- package/src/components/Calendar/MonthView.module.scss +99 -0
- package/src/components/Calendar/MonthView.tsx +296 -0
- package/src/components/Calendar/TimedEvent.module.scss +205 -0
- package/src/components/Calendar/TimedEvent.tsx +247 -0
- package/src/components/Calendar/ViewSwitcher.module.scss +3 -0
- package/src/components/Calendar/ViewSwitcher.tsx +47 -0
- package/src/components/Calendar/WeekView.module.scss +10 -0
- package/src/components/Calendar/WeekView.tsx +137 -0
- package/src/components/Calendar/eventColor.ts +60 -0
- package/src/components/Calendar/index.ts +18 -0
- package/src/components/Calendar/types.ts +451 -0
- package/src/components/Calendar/useEventDrag.ts +783 -0
- package/src/components/Calendar/utils.ts +622 -0
- package/src/components/Card/Card.module.scss +264 -0
- package/src/components/Card/Card.tokens.scss +55 -0
- package/src/components/Card/Card.tsx +170 -0
- package/src/components/Card/CardBody.tsx +45 -0
- package/src/components/Card/CardHeader.tsx +113 -0
- package/src/components/Card/CardList.tsx +24 -0
- package/src/components/Card/CardListRow.tsx +24 -0
- package/src/components/Card/index.ts +7 -0
- package/src/components/CatalogPicker/CatalogPicker.module.scss +193 -0
- package/src/components/CatalogPicker/CatalogPicker.tokens.scss +26 -0
- package/src/components/CatalogPicker/CatalogPicker.tsx +339 -0
- package/src/components/CatalogPicker/index.ts +2 -0
- package/src/components/Chart/Chart.module.scss +287 -0
- package/src/components/Chart/Chart.tokens.scss +63 -0
- package/src/components/Chart/Chart.tsx +607 -0
- package/src/components/Chart/ChartLegend.tsx +99 -0
- package/src/components/Chart/ChartTable.tsx +62 -0
- package/src/components/Chart/ChartTooltip.tsx +91 -0
- package/src/components/Chart/chartModel.ts +689 -0
- package/src/components/Chart/index.ts +2 -0
- package/src/components/ChatBubble/ChatBubble.module.scss +93 -0
- package/src/components/ChatBubble/ChatBubble.tokens.scss +17 -0
- package/src/components/ChatBubble/ChatBubble.tsx +61 -0
- package/src/components/ChatBubble/ChatBubbleList.tsx +27 -0
- package/src/components/ChatBubble/index.ts +3 -0
- package/src/components/ChatLauncher/ChatLauncher.module.scss +68 -0
- package/src/components/ChatLauncher/ChatLauncher.tokens.scss +27 -0
- package/src/components/ChatLauncher/ChatLauncher.tsx +202 -0
- package/src/components/ChatLauncher/index.ts +2 -0
- package/src/components/ChatLauncher/isAtBottom.ts +12 -0
- package/src/components/Checkbox/Checkbox.module.scss +147 -0
- package/src/components/Checkbox/Checkbox.tokens.scss +44 -0
- package/src/components/Checkbox/Checkbox.tsx +188 -0
- package/src/components/Checkbox/index.ts +2 -0
- package/src/components/CircularProgress/CircularProgress.module.scss +133 -0
- package/src/components/CircularProgress/CircularProgress.tokens.scss +40 -0
- package/src/components/CircularProgress/CircularProgress.tsx +139 -0
- package/src/components/CircularProgress/index.ts +7 -0
- package/src/components/Cluster/Cluster.module.scss +145 -0
- package/src/components/Cluster/Cluster.tokens.scss +11 -0
- package/src/components/Cluster/Cluster.tsx +215 -0
- package/src/components/Cluster/index.ts +2 -0
- package/src/components/Code/Code.module.scss +28 -0
- package/src/components/Code/Code.tokens.scss +15 -0
- package/src/components/Code/Code.tsx +44 -0
- package/src/components/Code/index.ts +2 -0
- package/src/components/CodeBlock/CodeBlock.module.scss +146 -0
- package/src/components/CodeBlock/CodeBlock.tokens.scss +27 -0
- package/src/components/CodeBlock/CodeBlock.tsx +274 -0
- package/src/components/CodeBlock/highlight.ts +179 -0
- package/src/components/CodeBlock/index.ts +8 -0
- package/src/components/CodeBlock/sampleSync.ts +42 -0
- package/src/components/ColorPicker/ColorPicker.module.scss +286 -0
- package/src/components/ColorPicker/ColorPicker.tokens.scss +60 -0
- package/src/components/ColorPicker/ColorPicker.tsx +367 -0
- package/src/components/ColorPicker/ColorPickerPanel.tsx +265 -0
- package/src/components/ColorPicker/SVSquare.tsx +189 -0
- package/src/components/ColorPicker/colorMath.ts +141 -0
- package/src/components/ColorPicker/index.ts +6 -0
- package/src/components/ConfirmationPopover/ConfirmationPopover.module.scss +39 -0
- package/src/components/ConfirmationPopover/ConfirmationPopover.tokens.scss +13 -0
- package/src/components/ConfirmationPopover/ConfirmationPopover.tsx +395 -0
- package/src/components/ConfirmationPopover/index.ts +2 -0
- package/src/components/Constrain/Constrain.module.scss +99 -0
- package/src/components/Constrain/Constrain.tsx +79 -0
- package/src/components/Constrain/index.ts +2 -0
- package/src/components/CurrencySelect/CurrencySelect.module.scss +7 -0
- package/src/components/CurrencySelect/CurrencySelect.tsx +167 -0
- package/src/components/CurrencySelect/index.ts +3 -0
- package/src/components/CursorPagination/CursorPagination.module.scss +69 -0
- package/src/components/CursorPagination/CursorPagination.tokens.scss +32 -0
- package/src/components/CursorPagination/CursorPagination.tsx +121 -0
- package/src/components/CursorPagination/index.ts +2 -0
- package/src/components/DashboardCanvas/DashboardCanvas.module.scss +360 -0
- package/src/components/DashboardCanvas/DashboardCanvas.tokens.scss +48 -0
- package/src/components/DashboardCanvas/DashboardCanvas.tsx +1270 -0
- package/src/components/DashboardCanvas/DashboardCanvasItem.tsx +140 -0
- package/src/components/DashboardCanvas/DashboardCanvasSection.tsx +174 -0
- package/src/components/DashboardCanvas/engine.ts +363 -0
- package/src/components/DashboardCanvas/index.ts +9 -0
- package/src/components/DashboardWidget/DashboardWidget.module.scss +100 -0
- package/src/components/DashboardWidget/DashboardWidget.tokens.scss +16 -0
- package/src/components/DashboardWidget/DashboardWidget.tsx +188 -0
- package/src/components/DashboardWidget/index.ts +7 -0
- package/src/components/DataTable/BodyRow.tsx +197 -0
- package/src/components/DataTable/ColumnVisibilityTrigger.module.scss +7 -0
- package/src/components/DataTable/ColumnVisibilityTrigger.tsx +105 -0
- package/src/components/DataTable/DataTable.module.scss +511 -0
- package/src/components/DataTable/DataTable.tokens.scss +80 -0
- package/src/components/DataTable/DataTable.tsx +734 -0
- package/src/components/DataTable/HeaderCell.module.scss +215 -0
- package/src/components/DataTable/HeaderCell.tsx +440 -0
- package/src/components/DataTable/columnShift.ts +117 -0
- package/src/components/DataTable/index.ts +23 -0
- package/src/components/DataTable/pinStyle.ts +47 -0
- package/src/components/DataTable/reorderColumns.ts +66 -0
- package/src/components/DataTable/types.ts +289 -0
- package/src/components/DataTable/useColumnDragShift.ts +216 -0
- package/src/components/DataTable/useDataTable.ts +372 -0
- package/src/components/DataTable/useResizeHandle.ts +97 -0
- package/src/components/DatePicker/DatePicker.module.scss +180 -0
- package/src/components/DatePicker/DatePicker.tokens.scss +152 -0
- package/src/components/DatePicker/DatePicker.tsx +664 -0
- package/src/components/DatePicker/DatePickerGrid.module.scss +172 -0
- package/src/components/DatePicker/DatePickerGrid.tsx +341 -0
- package/src/components/DatePicker/InlineDatePicker.module.scss +32 -0
- package/src/components/DatePicker/InlineDatePicker.tsx +201 -0
- package/src/components/DatePicker/index.ts +4 -0
- package/src/components/DatePicker/utils.ts +364 -0
- package/src/components/DateRangePicker/DateRangePicker.module.scss +237 -0
- package/src/components/DateRangePicker/DateRangePicker.tokens.scss +78 -0
- package/src/components/DateRangePicker/DateRangePicker.tsx +720 -0
- package/src/components/DateRangePicker/InlineDateRangePicker.module.scss +94 -0
- package/src/components/DateRangePicker/InlineDateRangePicker.tsx +376 -0
- package/src/components/DateRangePicker/index.ts +5 -0
- package/src/components/DateRangePicker/utils.ts +151 -0
- package/src/components/DateStrip/DateStrip.module.scss +78 -0
- package/src/components/DateStrip/DateStrip.tokens.scss +23 -0
- package/src/components/DateStrip/DateStrip.tsx +205 -0
- package/src/components/DateStrip/index.ts +2 -0
- package/src/components/DefinitionList/DefinitionList.module.scss +102 -0
- package/src/components/DefinitionList/DefinitionList.tokens.scss +29 -0
- package/src/components/DefinitionList/DefinitionList.tsx +198 -0
- package/src/components/DefinitionList/index.ts +9 -0
- package/src/components/Divider/Divider.module.scss +144 -0
- package/src/components/Divider/Divider.tokens.scss +21 -0
- package/src/components/Divider/Divider.tsx +103 -0
- package/src/components/Divider/index.ts +2 -0
- package/src/components/Dot/Dot.module.scss +40 -0
- package/src/components/Dot/Dot.tokens.scss +4 -0
- package/src/components/Dot/Dot.tsx +45 -0
- package/src/components/Dot/index.ts +2 -0
- package/src/components/Drawer/Body.tsx +23 -0
- package/src/components/Drawer/Close.tsx +35 -0
- package/src/components/Drawer/Content.tsx +93 -0
- package/src/components/Drawer/Drawer.module.scss +232 -0
- package/src/components/Drawer/Drawer.tokens.scss +38 -0
- package/src/components/Drawer/Drawer.tsx +23 -0
- package/src/components/Drawer/DrawerRoot.tsx +190 -0
- package/src/components/Drawer/Footer.tsx +24 -0
- package/src/components/Drawer/Header.tsx +64 -0
- package/src/components/Drawer/Overlay.tsx +82 -0
- package/src/components/Drawer/context.ts +44 -0
- package/src/components/Drawer/index.ts +12 -0
- package/src/components/Drawer/useDragToClose.ts +149 -0
- package/src/components/DropdownMenu/CheckboxItem.tsx +144 -0
- package/src/components/DropdownMenu/Content.tsx +419 -0
- package/src/components/DropdownMenu/DropdownMenu.module.scss +280 -0
- package/src/components/DropdownMenu/DropdownMenu.tokens.scss +88 -0
- package/src/components/DropdownMenu/DropdownMenu.tsx +43 -0
- package/src/components/DropdownMenu/Group.tsx +76 -0
- package/src/components/DropdownMenu/Item.tsx +148 -0
- package/src/components/DropdownMenu/ItemIndicator.tsx +30 -0
- package/src/components/DropdownMenu/Radio.tsx +178 -0
- package/src/components/DropdownMenu/Root.tsx +100 -0
- package/src/components/DropdownMenu/Sub.tsx +332 -0
- package/src/components/DropdownMenu/Trigger.tsx +76 -0
- package/src/components/DropdownMenu/context.ts +65 -0
- package/src/components/DropdownMenu/index.ts +20 -0
- package/src/components/EmojiPicker/EmojiPicker.module.scss +84 -0
- package/src/components/EmojiPicker/EmojiPicker.tokens.scss +24 -0
- package/src/components/EmojiPicker/EmojiPicker.tsx +341 -0
- package/src/components/EmojiPicker/emojiData.ts +245 -0
- package/src/components/EmojiPicker/index.ts +3 -0
- package/src/components/EmptyState/EmptyState.module.scss +102 -0
- package/src/components/EmptyState/EmptyState.tokens.scss +28 -0
- package/src/components/EmptyState/EmptyState.tsx +112 -0
- package/src/components/EmptyState/index.ts +7 -0
- package/src/components/EntityChip/EntityChip.module.scss +275 -0
- package/src/components/EntityChip/EntityChip.tokens.scss +66 -0
- package/src/components/EntityChip/EntityChip.tsx +649 -0
- package/src/components/EntityChip/index.ts +10 -0
- package/src/components/ErrorState/ErrorState.module.scss +105 -0
- package/src/components/ErrorState/ErrorState.tokens.scss +32 -0
- package/src/components/ErrorState/ErrorState.tsx +125 -0
- package/src/components/ErrorState/index.ts +8 -0
- package/src/components/Field/Field.module.scss +46 -0
- package/src/components/Field/Field.tsx +185 -0
- package/src/components/Field/index.ts +2 -0
- package/src/components/FileUpload/FileUpload.module.scss +187 -0
- package/src/components/FileUpload/FileUpload.tokens.scss +81 -0
- package/src/components/FileUpload/FileUpload.tsx +569 -0
- package/src/components/FileUpload/formatBytes.ts +34 -0
- package/src/components/FileUpload/iconForFile.ts +40 -0
- package/src/components/FileUpload/index.ts +2 -0
- package/src/components/FilterChip/FilterChip.module.scss +61 -0
- package/src/components/FilterChip/FilterChip.tokens.scss +25 -0
- package/src/components/FilterChip/FilterChip.tsx +208 -0
- package/src/components/FilterChip/index.ts +5 -0
- package/src/components/FlowCanvas/FlowCanvas.module.scss +329 -0
- package/src/components/FlowCanvas/FlowCanvas.tokens.scss +45 -0
- package/src/components/FlowCanvas/FlowCanvas.tsx +1867 -0
- package/src/components/FlowCanvas/FlowControls.tsx +46 -0
- package/src/components/FlowCanvas/FlowEdge.tsx +58 -0
- package/src/components/FlowCanvas/FlowNode.tsx +76 -0
- package/src/components/FlowCanvas/edgePath.ts +85 -0
- package/src/components/FlowCanvas/index.ts +4 -0
- package/src/components/FlowCanvas/layout.ts +148 -0
- package/src/components/FlowCanvas/spatialNav.ts +76 -0
- package/src/components/FlowCanvas/types.ts +59 -0
- package/src/components/FlowCanvas/useViewport.ts +122 -0
- package/src/components/FormRow/FormRow.module.scss +2 -0
- package/src/components/FormRow/FormRow.tsx +37 -0
- package/src/components/FormRow/index.ts +2 -0
- package/src/components/FormSection/FormSection.module.scss +24 -0
- package/src/components/FormSection/FormSection.tsx +46 -0
- package/src/components/FormSection/index.ts +2 -0
- package/src/components/Grid/Grid.module.scss +162 -0
- package/src/components/Grid/Grid.tokens.scss +13 -0
- package/src/components/Grid/Grid.tsx +226 -0
- package/src/components/Grid/GridItem.tsx +77 -0
- package/src/components/Grid/index.ts +11 -0
- package/src/components/Highlight/Highlight.module.scss +43 -0
- package/src/components/Highlight/Highlight.tokens.scss +35 -0
- package/src/components/Highlight/Highlight.tsx +164 -0
- package/src/components/Highlight/HighlightOverlay.tsx +100 -0
- package/src/components/Highlight/index.ts +2 -0
- package/src/components/HighlightedText/HighlightedText.module.scss +11 -0
- package/src/components/HighlightedText/HighlightedText.tokens.scss +9 -0
- package/src/components/HighlightedText/HighlightedText.tsx +50 -0
- package/src/components/HighlightedText/highlightRanges.ts +44 -0
- package/src/components/HighlightedText/index.ts +2 -0
- package/src/components/IconPicker/IconPicker.module.scss +175 -0
- package/src/components/IconPicker/IconPicker.tokens.scss +40 -0
- package/src/components/IconPicker/IconPicker.tsx +629 -0
- package/src/components/IconPicker/index.ts +9 -0
- package/src/components/IconTile/IconTile.module.scss +57 -0
- package/src/components/IconTile/IconTile.tokens.scss +16 -0
- package/src/components/IconTile/IconTile.tsx +91 -0
- package/src/components/IconTile/index.ts +2 -0
- package/src/components/Image/Image.module.scss +266 -0
- package/src/components/Image/Image.tokens.scss +55 -0
- package/src/components/Image/Image.tsx +342 -0
- package/src/components/Image/index.ts +2 -0
- package/src/components/ImageCrop/ImageCrop.module.scss +274 -0
- package/src/components/ImageCrop/ImageCrop.tokens.scss +33 -0
- package/src/components/ImageCrop/ImageCrop.tsx +542 -0
- package/src/components/ImageCrop/cropGeometry.ts +120 -0
- package/src/components/ImageCrop/extractCropBlob.ts +140 -0
- package/src/components/ImageCrop/index.ts +11 -0
- package/src/components/ImageCrop/useCropPreview.ts +161 -0
- package/src/components/Indent/Indent.module.scss +33 -0
- package/src/components/Indent/Indent.tokens.scss +10 -0
- package/src/components/Indent/Indent.tsx +46 -0
- package/src/components/Indent/index.ts +2 -0
- package/src/components/Input/Input.module.scss +99 -0
- package/src/components/Input/Input.tokens.scss +54 -0
- package/src/components/Input/Input.tsx +105 -0
- package/src/components/Input/Suggestions.tsx +260 -0
- package/src/components/Input/index.ts +2 -0
- package/src/components/Kanban/Kanban.module.scss +39 -0
- package/src/components/Kanban/Kanban.tokens.scss +15 -0
- package/src/components/Kanban/Kanban.tsx +951 -0
- package/src/components/Kanban/index.ts +7 -0
- package/src/components/Kbd/Kbd.module.scss +47 -0
- package/src/components/Kbd/Kbd.tokens.scss +26 -0
- package/src/components/Kbd/Kbd.tsx +73 -0
- package/src/components/Kbd/index.ts +2 -0
- package/src/components/Lightbox/Lightbox.module.scss +283 -0
- package/src/components/Lightbox/Lightbox.tokens.scss +36 -0
- package/src/components/Lightbox/Lightbox.tsx +506 -0
- package/src/components/Lightbox/index.ts +2 -0
- package/src/components/Link/Link.module.scss +78 -0
- package/src/components/Link/Link.tokens.scss +28 -0
- package/src/components/Link/Link.tsx +114 -0
- package/src/components/Link/index.ts +2 -0
- package/src/components/LinkCard/LinkCard.module.scss +92 -0
- package/src/components/LinkCard/LinkCard.tokens.scss +9 -0
- package/src/components/LinkCard/LinkCard.tsx +72 -0
- package/src/components/LinkCard/index.ts +2 -0
- package/src/components/LiquidEditor/AutocompleteMenu.tsx +133 -0
- package/src/components/LiquidEditor/HighlightLayer.tsx +53 -0
- package/src/components/LiquidEditor/InsertVariableMenu.tsx +81 -0
- package/src/components/LiquidEditor/LiquidEditor.module.scss +339 -0
- package/src/components/LiquidEditor/LiquidEditor.tokens.scss +81 -0
- package/src/components/LiquidEditor/LiquidEditor.tsx +412 -0
- package/src/components/LiquidEditor/PreviewPane.tsx +29 -0
- package/src/components/LiquidEditor/caretCoordinates.ts +97 -0
- package/src/components/LiquidEditor/index.ts +7 -0
- package/src/components/LiquidEditor/liquidFilters.ts +23 -0
- package/src/components/LiquidEditor/liquidTokenizer.ts +235 -0
- package/src/components/LiquidEditor/types.ts +101 -0
- package/src/components/LiquidEditor/useLiquidAutocomplete.ts +178 -0
- package/src/components/List/List.module.scss +105 -0
- package/src/components/List/List.tokens.scss +42 -0
- package/src/components/List/List.tsx +124 -0
- package/src/components/List/index.ts +9 -0
- package/src/components/LiveRegion/LiveRegion.module.scss +3 -0
- package/src/components/LiveRegion/LiveRegion.tsx +116 -0
- package/src/components/LiveRegion/index.ts +2 -0
- package/src/components/Logo/Logo.module.scss +139 -0
- package/src/components/Logo/Logo.tokens.scss +14 -0
- package/src/components/Logo/Logo.tsx +126 -0
- package/src/components/Logo/index.ts +2 -0
- package/src/components/Masonry/Masonry.module.scss +42 -0
- package/src/components/Masonry/Masonry.tokens.scss +8 -0
- package/src/components/Masonry/Masonry.tsx +136 -0
- package/src/components/Masonry/index.ts +2 -0
- package/src/components/Masonry/masonryUtils.ts +42 -0
- package/src/components/MediaTile/MediaTile.module.scss +183 -0
- package/src/components/MediaTile/MediaTile.tokens.scss +60 -0
- package/src/components/MediaTile/MediaTile.tsx +208 -0
- package/src/components/MediaTile/index.ts +8 -0
- package/src/components/Modal/Body.tsx +27 -0
- package/src/components/Modal/Close.tsx +45 -0
- package/src/components/Modal/Content.tsx +98 -0
- package/src/components/Modal/Footer.tsx +28 -0
- package/src/components/Modal/Header.tsx +51 -0
- package/src/components/Modal/Modal.module.scss +262 -0
- package/src/components/Modal/Modal.tokens.scss +50 -0
- package/src/components/Modal/Modal.tsx +23 -0
- package/src/components/Modal/ModalRoot.tsx +299 -0
- package/src/components/Modal/Overlay.tsx +101 -0
- package/src/components/Modal/context.ts +60 -0
- package/src/components/Modal/index.ts +11 -0
- package/src/components/MoneyInput/MoneyInput.module.scss +57 -0
- package/src/components/MoneyInput/MoneyInput.tsx +433 -0
- package/src/components/MoneyInput/index.ts +2 -0
- package/src/components/OptionsPicker/OptionsPicker.module.scss +216 -0
- package/src/components/OptionsPicker/OptionsPicker.tokens.scss +68 -0
- package/src/components/OptionsPicker/OptionsPicker.tsx +936 -0
- package/src/components/OptionsPicker/index.ts +9 -0
- package/src/components/OtpInput/OtpInput.module.scss +69 -0
- package/src/components/OtpInput/OtpInput.tokens.scss +45 -0
- package/src/components/OtpInput/OtpInput.tsx +368 -0
- package/src/components/OtpInput/index.ts +2 -0
- package/src/components/Page/Page.module.scss +30 -0
- package/src/components/Page/Page.tokens.scss +11 -0
- package/src/components/Page/Page.tsx +53 -0
- package/src/components/Page/index.ts +2 -0
- package/src/components/PageHeader/PageHeader.module.scss +197 -0
- package/src/components/PageHeader/PageHeader.tokens.scss +41 -0
- package/src/components/PageHeader/PageHeader.tsx +310 -0
- package/src/components/PageHeader/index.ts +20 -0
- package/src/components/Pagination/Pagination.module.scss +117 -0
- package/src/components/Pagination/Pagination.tokens.scss +54 -0
- package/src/components/Pagination/Pagination.tsx +165 -0
- package/src/components/Pagination/index.ts +4 -0
- package/src/components/Pagination/paginationRange.ts +72 -0
- package/src/components/PasswordInput/PasswordInput.module.scss +120 -0
- package/src/components/PasswordInput/PasswordInput.tokens.scss +44 -0
- package/src/components/PasswordInput/PasswordInput.tsx +210 -0
- package/src/components/PasswordInput/index.ts +2 -0
- package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.module.scss +80 -0
- package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tokens.scss +40 -0
- package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tsx +96 -0
- package/src/components/PasswordStrengthMeter/index.ts +2 -0
- package/src/components/PersonDisplay/PersonDisplay.module.scss +180 -0
- package/src/components/PersonDisplay/PersonDisplay.tokens.scss +35 -0
- package/src/components/PersonDisplay/PersonDisplay.tsx +420 -0
- package/src/components/PersonDisplay/index.ts +10 -0
- package/src/components/PhoneInput/PhoneInput.module.scss +23 -0
- package/src/components/PhoneInput/PhoneInput.tsx +271 -0
- package/src/components/PhoneInput/index.ts +4 -0
- package/src/components/PhoneInput/phone.ts +128 -0
- package/src/components/PillMenu/PillMenu.module.scss +117 -0
- package/src/components/PillMenu/PillMenu.tokens.scss +22 -0
- package/src/components/PillMenu/PillMenu.tsx +324 -0
- package/src/components/PillMenu/index.ts +2 -0
- package/src/components/Popover/Anchor.tsx +37 -0
- package/src/components/Popover/Close.tsx +45 -0
- package/src/components/Popover/Content.tsx +213 -0
- package/src/components/Popover/Heading.tsx +33 -0
- package/src/components/Popover/Popover.module.scss +177 -0
- package/src/components/Popover/Popover.tokens.scss +22 -0
- package/src/components/Popover/Popover.tsx +23 -0
- package/src/components/Popover/PopoverRoot.tsx +75 -0
- package/src/components/Popover/Trigger.tsx +86 -0
- package/src/components/Popover/context.ts +22 -0
- package/src/components/Popover/index.ts +7 -0
- package/src/components/Progress/Progress.module.scss +110 -0
- package/src/components/Progress/Progress.tokens.scss +44 -0
- package/src/components/Progress/Progress.tsx +129 -0
- package/src/components/Progress/index.ts +2 -0
- package/src/components/QrCode/QrCode.module.scss +97 -0
- package/src/components/QrCode/QrCode.tokens.scss +17 -0
- package/src/components/QrCode/QrCode.tsx +233 -0
- package/src/components/QrCode/index.ts +2 -0
- package/src/components/QrCode/qr.ts +161 -0
- package/src/components/Radio/Radio.module.scss +175 -0
- package/src/components/Radio/Radio.tokens.scss +59 -0
- package/src/components/Radio/Radio.tsx +127 -0
- package/src/components/Radio/RadioGroup.module.scss +42 -0
- package/src/components/Radio/RadioGroup.tsx +120 -0
- package/src/components/Radio/RadioGroupContext.tsx +30 -0
- package/src/components/Radio/index.ts +4 -0
- package/src/components/Rail/Rail.module.scss +510 -0
- package/src/components/Rail/Rail.tokens.scss +92 -0
- package/src/components/Rail/Rail.tsx +287 -0
- package/src/components/Rail/RailCollapseToggle.tsx +57 -0
- package/src/components/Rail/RailFooter.tsx +17 -0
- package/src/components/Rail/RailGroup.tsx +728 -0
- package/src/components/Rail/RailGroupContext.ts +9 -0
- package/src/components/Rail/RailHeader.tsx +23 -0
- package/src/components/Rail/RailItem.tsx +119 -0
- package/src/components/Rail/RailSection.tsx +39 -0
- package/src/components/Rail/RailSpacer.tsx +19 -0
- package/src/components/Rail/index.ts +9 -0
- package/src/components/RelativeDateInput/RelativeDateInput.module.scss +15 -0
- package/src/components/RelativeDateInput/RelativeDateInput.tokens.scss +6 -0
- package/src/components/RelativeDateInput/RelativeDateInput.tsx +474 -0
- package/src/components/RelativeDateInput/index.ts +10 -0
- package/src/components/RelativeDateInput/relativeDate.ts +127 -0
- package/src/components/RichText/RichText.module.scss +5 -0
- package/src/components/RichText/RichText.tsx +70 -0
- package/src/components/RichText/RichTextAttachment.module.scss +82 -0
- package/src/components/RichText/RichTextAttachment.tsx +122 -0
- package/src/components/RichText/_prose.scss +79 -0
- package/src/components/RichText/attachmentIcon.tsx +24 -0
- package/src/components/RichText/engine/attachment.ts +154 -0
- package/src/components/RichText/engine/autolink.ts +64 -0
- package/src/components/RichText/engine/blockUnit.ts +174 -0
- package/src/components/RichText/engine/colorMarks.ts +85 -0
- package/src/components/RichText/engine/escape.ts +11 -0
- package/src/components/RichText/engine/fromHtml.ts +353 -0
- package/src/components/RichText/engine/fromMarkdown.ts +20 -0
- package/src/components/RichText/engine/inlines.ts +82 -0
- package/src/components/RichText/engine/listDepths.ts +32 -0
- package/src/components/RichText/engine/marks.ts +80 -0
- package/src/components/RichText/engine/mdToHtml.ts +178 -0
- package/src/components/RichText/engine/model.ts +157 -0
- package/src/components/RichText/engine/position.ts +118 -0
- package/src/components/RichText/engine/renderDoc.tsx +395 -0
- package/src/components/RichText/engine/renderLink.ts +15 -0
- package/src/components/RichText/engine/renderMention.ts +16 -0
- package/src/components/RichText/engine/safeHref.ts +22 -0
- package/src/components/RichText/engine/toHtml.ts +154 -0
- package/src/components/RichText/engine/toMarkdown.ts +97 -0
- package/src/components/RichText/engine/transforms.ts +434 -0
- package/src/components/RichText/imageMaxHeightStyle.ts +10 -0
- package/src/components/RichText/index.ts +31 -0
- package/src/components/RichTextEditor/RichTextAttachmentConfig.tsx +264 -0
- package/src/components/RichTextEditor/RichTextBlockControls.tsx +365 -0
- package/src/components/RichTextEditor/RichTextBlockMenu.tsx +162 -0
- package/src/components/RichTextEditor/RichTextColorMenu.tsx +115 -0
- package/src/components/RichTextEditor/RichTextEditor.module.scss +298 -0
- package/src/components/RichTextEditor/RichTextEditor.tsx +1910 -0
- package/src/components/RichTextEditor/RichTextImageResizer.tsx +131 -0
- package/src/components/RichTextEditor/RichTextLinkEditor.tsx +151 -0
- package/src/components/RichTextEditor/RichTextMentionMenu.tsx +99 -0
- package/src/components/RichTextEditor/RichTextToolbar.tsx +379 -0
- package/src/components/RichTextEditor/autolinkInput.ts +65 -0
- package/src/components/RichTextEditor/blockDrop.ts +9 -0
- package/src/components/RichTextEditor/blockReflow.ts +62 -0
- package/src/components/RichTextEditor/commands.ts +300 -0
- package/src/components/RichTextEditor/history.ts +93 -0
- package/src/components/RichTextEditor/icons.tsx +152 -0
- package/src/components/RichTextEditor/imageSize.ts +70 -0
- package/src/components/RichTextEditor/index.ts +5 -0
- package/src/components/RichTextEditor/input.ts +209 -0
- package/src/components/RichTextEditor/inputRules.ts +71 -0
- package/src/components/RichTextEditor/links.ts +103 -0
- package/src/components/RichTextEditor/mentionContext.ts +37 -0
- package/src/components/RichTextEditor/mentions.ts +28 -0
- package/src/components/RichTextEditor/preventSelectionLoss.ts +15 -0
- package/src/components/RichTextEditor/selection.ts +415 -0
- package/src/components/RichTextEditor/shortcuts.ts +44 -0
- package/src/components/RichTextEditor/useAnchoredFloating.ts +50 -0
- package/src/components/RichTextEditor/useAttachmentConfig.ts +134 -0
- package/src/components/RichTextEditor/useDismissOnOutsidePointerDown.ts +26 -0
- package/src/components/RichTextEditor/useLinkEditor.ts +107 -0
- package/src/components/RichTextEditor/useMention.ts +226 -0
- package/src/components/RichTextEditor/useOverlayRect.ts +73 -0
- package/src/components/RichTextEditor/useUpload.ts +246 -0
- package/src/components/Screen/Screen.module.scss +46 -0
- package/src/components/Screen/Screen.tokens.scss +20 -0
- package/src/components/Screen/Screen.tsx +97 -0
- package/src/components/Screen/index.ts +2 -0
- package/src/components/ScrollArea/ScrollArea.module.scss +39 -0
- package/src/components/ScrollArea/ScrollArea.tokens.scss +15 -0
- package/src/components/ScrollArea/ScrollArea.tsx +154 -0
- package/src/components/ScrollArea/index.ts +2 -0
- package/src/components/Select/Chip.tsx +45 -0
- package/src/components/Select/Empty.tsx +39 -0
- package/src/components/Select/Error.tsx +51 -0
- package/src/components/Select/HiddenInputs.tsx +44 -0
- package/src/components/Select/Listbox.tsx +557 -0
- package/src/components/Select/Loading.tsx +30 -0
- package/src/components/Select/Select.module.scss +512 -0
- package/src/components/Select/Select.tokens.scss +140 -0
- package/src/components/Select/Select.tsx +685 -0
- package/src/components/Select/Trigger.tsx +952 -0
- package/src/components/Select/context.ts +101 -0
- package/src/components/Select/emptyStateText.ts +19 -0
- package/src/components/Select/index.ts +9 -0
- package/src/components/Select/useSelectState.ts +157 -0
- package/src/components/Select/utils-types.ts +7 -0
- package/src/components/Select/utils.ts +122 -0
- package/src/components/SettingRow/SettingRow.module.scss +166 -0
- package/src/components/SettingRow/SettingRow.tokens.scss +37 -0
- package/src/components/SettingRow/SettingRow.tsx +242 -0
- package/src/components/SettingRow/index.ts +7 -0
- package/src/components/Skeleton/Skeleton.module.scss +55 -0
- package/src/components/Skeleton/Skeleton.tokens.scss +17 -0
- package/src/components/Skeleton/Skeleton.tsx +131 -0
- package/src/components/Skeleton/index.ts +4 -0
- package/src/components/Skeleton/useSkeletonVisibility.ts +95 -0
- package/src/components/Slider/Slider.module.scss +293 -0
- package/src/components/Slider/Slider.tokens.scss +98 -0
- package/src/components/Slider/Slider.tsx +624 -0
- package/src/components/Slider/index.ts +9 -0
- package/src/components/SlotGrid/SlotGrid.module.scss +61 -0
- package/src/components/SlotGrid/SlotGrid.tokens.scss +21 -0
- package/src/components/SlotGrid/SlotGrid.tsx +111 -0
- package/src/components/SlotGrid/index.ts +2 -0
- package/src/components/SocialButton/SocialButton.module.scss +4 -0
- package/src/components/SocialButton/SocialButton.tsx +40 -0
- package/src/components/SocialButton/index.ts +2 -0
- package/src/components/Sortable/Sortable.module.scss +177 -0
- package/src/components/Sortable/Sortable.tokens.scss +27 -0
- package/src/components/Sortable/Sortable.tsx +572 -0
- package/src/components/Sortable/containerAwareCollision.ts +125 -0
- package/src/components/Sortable/index.ts +13 -0
- package/src/components/SortableGroup/SortableGroup.module.scss +23 -0
- package/src/components/SortableGroup/SortableGroup.tsx +315 -0
- package/src/components/SortableGroup/index.ts +4 -0
- package/src/components/SortableGroup/moveSortableItem.ts +39 -0
- package/src/components/Sparkline/Sparkline.module.scss +28 -0
- package/src/components/Sparkline/Sparkline.tokens.scss +7 -0
- package/src/components/Sparkline/Sparkline.tsx +133 -0
- package/src/components/Sparkline/index.ts +2 -0
- package/src/components/Sparkline/sparklineModel.ts +119 -0
- package/src/components/Split/Split.module.scss +158 -0
- package/src/components/Split/Split.tokens.scss +10 -0
- package/src/components/Split/Split.tsx +231 -0
- package/src/components/Split/index.ts +2 -0
- package/src/components/Stack/Stack.module.scss +67 -0
- package/src/components/Stack/Stack.tokens.scss +11 -0
- package/src/components/Stack/Stack.tsx +100 -0
- package/src/components/Stack/index.ts +2 -0
- package/src/components/StagePath/StagePath.module.scss +255 -0
- package/src/components/StagePath/StagePath.tokens.scss +43 -0
- package/src/components/StagePath/StagePath.tsx +176 -0
- package/src/components/StagePath/index.ts +2 -0
- package/src/components/StatGroup/StatGroup.module.scss +6 -0
- package/src/components/StatGroup/StatGroup.tsx +70 -0
- package/src/components/StatGroup/StatGroupContext.ts +10 -0
- package/src/components/StatGroup/StatTile.module.scss +99 -0
- package/src/components/StatGroup/StatTile.tokens.scss +35 -0
- package/src/components/StatGroup/StatTile.tsx +143 -0
- package/src/components/StatGroup/index.ts +4 -0
- package/src/components/Sticky/Sticky.module.scss +98 -0
- package/src/components/Sticky/Sticky.tokens.scss +17 -0
- package/src/components/Sticky/Sticky.tsx +103 -0
- package/src/components/Sticky/index.ts +2 -0
- package/src/components/Switch/Switch.module.scss +182 -0
- package/src/components/Switch/Switch.tokens.scss +59 -0
- package/src/components/Switch/Switch.tsx +214 -0
- package/src/components/Switch/index.ts +2 -0
- package/src/components/Table/Table.module.scss +308 -0
- package/src/components/Table/Table.tokens.scss +79 -0
- package/src/components/Table/Table.tsx +381 -0
- package/src/components/Table/index.ts +15 -0
- package/src/components/TableOfContents/TableOfContents.module.scss +83 -0
- package/src/components/TableOfContents/TableOfContents.tokens.scss +26 -0
- package/src/components/TableOfContents/TableOfContents.tsx +192 -0
- package/src/components/TableOfContents/activeSection.ts +18 -0
- package/src/components/TableOfContents/index.ts +2 -0
- package/src/components/Tabs/Tabs.module.scss +359 -0
- package/src/components/Tabs/Tabs.tokens.scss +50 -0
- package/src/components/Tabs/Tabs.tsx +538 -0
- package/src/components/Tabs/index.ts +2 -0
- package/src/components/Text/Text.module.scss +115 -0
- package/src/components/Text/Text.tokens.scss +55 -0
- package/src/components/Text/Text.tsx +197 -0
- package/src/components/Text/index.ts +2 -0
- package/src/components/Textarea/Textarea.module.scss +94 -0
- package/src/components/Textarea/Textarea.tokens.scss +48 -0
- package/src/components/Textarea/Textarea.tsx +246 -0
- package/src/components/Textarea/index.ts +2 -0
- package/src/components/Thread/Thread.module.scss +161 -0
- package/src/components/Thread/Thread.tokens.scss +32 -0
- package/src/components/Thread/Thread.tsx +176 -0
- package/src/components/Thread/index.ts +2 -0
- package/src/components/TimeField/TimeField.module.scss +232 -0
- package/src/components/TimeField/TimeField.tsx +793 -0
- package/src/components/TimeField/index.ts +2 -0
- package/src/components/Timeline/Timeline.module.scss +58 -0
- package/src/components/Timeline/Timeline.tokens.scss +13 -0
- package/src/components/Timeline/Timeline.tsx +53 -0
- package/src/components/Timeline/index.ts +2 -0
- package/src/components/Title/Title.module.scss +84 -0
- package/src/components/Title/Title.tokens.scss +37 -0
- package/src/components/Title/Title.tsx +150 -0
- package/src/components/Title/index.ts +2 -0
- package/src/components/Toast/Toast.module.scss +299 -0
- package/src/components/Toast/Toast.tokens.scss +65 -0
- package/src/components/Toast/Toast.tsx +122 -0
- package/src/components/Toast/ToastViewport.tsx +166 -0
- package/src/components/Toast/api.ts +175 -0
- package/src/components/Toast/index.ts +5 -0
- package/src/components/Toast/store.ts +133 -0
- package/src/components/Toast/useToastTimer.ts +94 -0
- package/src/components/Tooltip/Tooltip.module.scss +99 -0
- package/src/components/Tooltip/Tooltip.tokens.scss +23 -0
- package/src/components/Tooltip/Tooltip.tsx +341 -0
- package/src/components/Tooltip/index.ts +2 -0
- package/src/components/TopBar/TopBar.module.scss +235 -0
- package/src/components/TopBar/TopBar.tokens.scss +79 -0
- package/src/components/TopBar/TopBar.tsx +87 -0
- package/src/components/TopBar/TopBarEnd.tsx +20 -0
- package/src/components/TopBar/TopBarIconButton.tsx +86 -0
- package/src/components/TopBar/TopBarSearch.tsx +319 -0
- package/src/components/TopBar/TopBarSearchPanel.tsx +268 -0
- package/src/components/TopBar/TopBarStart.tsx +20 -0
- package/src/components/TopBar/index.ts +11 -0
- package/src/components/Tour/Spotlight.tsx +121 -0
- package/src/components/Tour/Tour.module.scss +210 -0
- package/src/components/Tour/Tour.tokens.scss +58 -0
- package/src/components/Tour/Tour.tsx +617 -0
- package/src/components/Tour/index.ts +2 -0
- package/src/components/Tour/useTourTarget.ts +115 -0
- package/src/components/TreeView/TreeView.module.scss +268 -0
- package/src/components/TreeView/TreeView.tokens.scss +36 -0
- package/src/components/TreeView/TreeView.tsx +536 -0
- package/src/components/TreeView/index.ts +3 -0
- package/src/components/TreeView/treeModel.ts +224 -0
- package/src/components/VisuallyHidden/VisuallyHidden.module.scss +7 -0
- package/src/components/VisuallyHidden/VisuallyHidden.tsx +29 -0
- package/src/components/VisuallyHidden/index.ts +2 -0
- package/src/components/WidgetPreview/WidgetPreview.module.scss +11 -0
- package/src/components/WidgetPreview/WidgetPreview.tokens.scss +26 -0
- package/src/components/WidgetPreview/WidgetPreview.tsx +36 -0
- package/src/components/WidgetPreview/WidgetShape.module.scss +140 -0
- package/src/components/WidgetPreview/WidgetShape.tsx +159 -0
- package/src/components/WidgetPreview/index.ts +2 -0
- package/src/components/_internal/Trend.tsx +27 -0
- package/src/components/_internal/choiceTile.scss +74 -0
- package/src/components/_internal/collapse.scss +10 -0
- package/src/components/_internal/collapse.ts +58 -0
- package/src/components/_internal/currency.ts +257 -0
- package/src/components/_internal/dragAnnouncements.ts +200 -0
- package/src/components/_internal/fieldWiring.ts +225 -0
- package/src/components/_internal/gridSpan.ts +54 -0
- package/src/components/_internal/isoDay.ts +35 -0
- package/src/components/_internal/letterKey.ts +26 -0
- package/src/components/_internal/overlay/focusRestore.ts +21 -0
- package/src/components/_internal/overlay/index.ts +12 -0
- package/src/components/_internal/overlay/tourHold.ts +23 -0
- package/src/components/_internal/overlay/useFocusTrap.ts +120 -0
- package/src/components/_internal/overlay/useInOverlay.ts +81 -0
- package/src/components/_internal/overlay/useOverlayStack.ts +232 -0
- package/src/components/_internal/overlay/useScrollLock.ts +112 -0
- package/src/components/_internal/refs.ts +48 -0
- package/src/components/_internal/statusColor.ts +26 -0
- package/src/components/_internal/timeUtils.ts +23 -0
- package/src/components/_internal/useAsyncOptions.ts +145 -0
- package/src/components/_internal/useClippedTooltip.ts +50 -0
- package/src/components/_internal/useControllableState.ts +50 -0
- package/src/components.manifest.json +1141 -0
- package/src/hooks/useBelowBreakpoint.ts +58 -0
- package/src/i18n/I18nProvider.tsx +52 -0
- package/src/i18n/LocaleProvider.tsx +17 -0
- package/src/i18n/en.ts +648 -0
- package/src/i18n/format.ts +71 -0
- package/src/i18n/index.ts +13 -0
- package/src/i18n/messages.ts +1275 -0
- package/src/i18n/ru.ts +677 -0
- package/src/i18n/useLocale.ts +19 -0
- package/src/i18n/useTranslation.ts +58 -0
- package/src/index.ts +913 -0
- package/src/palette/index.ts +2 -0
- package/src/palette/palette.ts +108 -0
- package/src/styles/dark.scss +4 -0
- package/src/styles/global.scss +7 -0
- package/src/styles/mixins.scss +143 -0
- package/src/styles/reset.scss +78 -0
- package/src/styles/tokens.scss +18 -0
- package/src/styles/typography.scss +44 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// inlines.ts — Layer B. Pure helpers over an Inline[]. Never mutate inputs.
|
|
2
|
+
import type { Inline, Mark } from './model';
|
|
3
|
+
import { marksEqual } from './marks';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Concatenate the text of all inline runs, discarding mark information. Tolerates a
|
|
7
|
+
* missing `inlines` (a void block like `attachment` carries none) — a block with no
|
|
8
|
+
* runs contributes no text.
|
|
9
|
+
*/
|
|
10
|
+
export function runsText(inlines: Inline[] | undefined): string {
|
|
11
|
+
return (inlines ?? []).map((r) => r.text).join('');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Total character count across all inline runs (sum of run text lengths). Tolerates a
|
|
16
|
+
* missing `inlines` (void blocks like `attachment` carry none) → length 0, so the
|
|
17
|
+
* caret/length math never crashes on an attachment-containing doc.
|
|
18
|
+
*/
|
|
19
|
+
export function runsLength(inlines: Inline[] | undefined): number {
|
|
20
|
+
return (inlines ?? []).reduce((n, r) => n + r.text.length, 0);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Canonical form: adjacent equal-mark runs merged, empty runs dropped, ≥1 run. */
|
|
24
|
+
export function normalizeInlines(inlines: Inline[]): Inline[] {
|
|
25
|
+
const out: Inline[] = [];
|
|
26
|
+
for (const run of inlines) {
|
|
27
|
+
if (run.text === '') continue;
|
|
28
|
+
const last = out[out.length - 1];
|
|
29
|
+
if (last && marksEqual(last.marks, run.marks)) {
|
|
30
|
+
out[out.length - 1] = { text: last.text + run.text, marks: last.marks };
|
|
31
|
+
} else {
|
|
32
|
+
out.push({ text: run.text, marks: run.marks });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return out.length === 0 ? [{ text: '', marks: [] }] : out;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Extract the character sub-range [start, end). Returns a normalized Inline[]. */
|
|
39
|
+
export function sliceInlines(inlines: Inline[], start: number, end: number): Inline[] {
|
|
40
|
+
const out: Inline[] = [];
|
|
41
|
+
let pos = 0;
|
|
42
|
+
for (const run of inlines) {
|
|
43
|
+
const runStart = pos;
|
|
44
|
+
const runEnd = pos + run.text.length;
|
|
45
|
+
pos = runEnd;
|
|
46
|
+
const from = Math.max(start, runStart);
|
|
47
|
+
const to = Math.min(end, runEnd);
|
|
48
|
+
if (to > from) {
|
|
49
|
+
out.push({ text: run.text.slice(from - runStart, to - runStart), marks: run.marks });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return normalizeInlines(out);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Apply `fn` to the mark set of every character in [start, end), splitting runs
|
|
57
|
+
* at the boundaries. Characters outside the range keep their marks. Re-normalizes.
|
|
58
|
+
*/
|
|
59
|
+
export function mapMarksOverRange(
|
|
60
|
+
inlines: Inline[],
|
|
61
|
+
start: number,
|
|
62
|
+
end: number,
|
|
63
|
+
fn: (marks: Mark[]) => Mark[],
|
|
64
|
+
): Inline[] {
|
|
65
|
+
const out: Inline[] = [];
|
|
66
|
+
let pos = 0;
|
|
67
|
+
for (const run of inlines) {
|
|
68
|
+
const runStart = pos;
|
|
69
|
+
const runEnd = pos + run.text.length;
|
|
70
|
+
pos = runEnd;
|
|
71
|
+
const from = Math.max(start, runStart);
|
|
72
|
+
const to = Math.min(end, runEnd);
|
|
73
|
+
if (to <= from) {
|
|
74
|
+
out.push(run); // entirely outside the range
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (from > runStart) out.push({ text: run.text.slice(0, from - runStart), marks: run.marks });
|
|
78
|
+
out.push({ text: run.text.slice(from - runStart, to - runStart), marks: fn(run.marks) });
|
|
79
|
+
if (to < runEnd) out.push({ text: run.text.slice(to - runStart), marks: run.marks });
|
|
80
|
+
}
|
|
81
|
+
return normalizeInlines(out);
|
|
82
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// listDepths.ts — list-item detection + gap-free depth normalization, shared by
|
|
2
|
+
// the renderer (renderDoc) and the HTML serializer (toHtml) so both reconstruct
|
|
3
|
+
// list nesting identically.
|
|
4
|
+
import type { Block } from './model';
|
|
5
|
+
|
|
6
|
+
/** True for the flat list-item block types. */
|
|
7
|
+
export function isListItem(block: Block): boolean {
|
|
8
|
+
return block.type === 'bullet_item' || block.type === 'ordered_item';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Effective render depth per block. `depth` is a free integer on the model, but
|
|
13
|
+
* nesting needs gap-free levels — within each run of consecutive list items,
|
|
14
|
+
* clamp each item to at most one level deeper than the previous (never below 0).
|
|
15
|
+
* Non-list blocks get 0 and reset the run. Lossless: no item is dropped during
|
|
16
|
+
* grouping.
|
|
17
|
+
*/
|
|
18
|
+
export function effectiveDepths(blocks: Block[]): number[] {
|
|
19
|
+
const eff = new Array<number>(blocks.length).fill(0);
|
|
20
|
+
let prev = -1; // effective depth of the previous list item in the current run
|
|
21
|
+
for (let i = 0; i < blocks.length; i += 1) {
|
|
22
|
+
if (!isListItem(blocks[i])) {
|
|
23
|
+
prev = -1;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const raw = blocks[i].depth ?? 0;
|
|
27
|
+
const e = Math.max(0, Math.min(raw, prev + 1));
|
|
28
|
+
eff[i] = e;
|
|
29
|
+
prev = e;
|
|
30
|
+
}
|
|
31
|
+
return eff;
|
|
32
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// marks.ts — Layer A. Pure helpers over a Mark[]. Never mutate inputs.
|
|
2
|
+
import type { Mark, MarkType } from './model';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Inline-mark nesting order, outermost first. Shared by renderDoc + toHtml so
|
|
6
|
+
* render and serialize nest identically. Color spans sit just inside link/mention
|
|
7
|
+
* (so a colored link reads `<a><span style>…`) but outside the text-formatting tags.
|
|
8
|
+
*/
|
|
9
|
+
export const MARK_ORDER: MarkType[] = [
|
|
10
|
+
'mention',
|
|
11
|
+
'link',
|
|
12
|
+
'textColor',
|
|
13
|
+
'bgColor',
|
|
14
|
+
'bold',
|
|
15
|
+
'italic',
|
|
16
|
+
'underline',
|
|
17
|
+
'strike',
|
|
18
|
+
'code',
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
/** Canonical key for set comparison (link by href, mention by id+label, color by key). */
|
|
22
|
+
function markKey(m: Mark): string {
|
|
23
|
+
if (m.type === 'link') return `link:${m.href}`;
|
|
24
|
+
if (m.type === 'mention') return `mention:${m.id}:${m.label}`;
|
|
25
|
+
if (m.type === 'textColor' || m.type === 'bgColor') return `${m.type}:${m.color}`;
|
|
26
|
+
return m.type;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Order-insensitive string signature of a mark SET. Two runs with the same
|
|
31
|
+
* signature carry identical formatting. Used by the editor's renderer to fold the
|
|
32
|
+
* run's formatting into its React key, so that when a run's MARK STRUCTURE changes
|
|
33
|
+
* (e.g. bold/italic/underline added over an already-colored run) React replaces
|
|
34
|
+
* the run's subtree cleanly instead of surgically re-wrapping an existing
|
|
35
|
+
* `contentEditable` text node in place — which can orphan the node (stray leftover
|
|
36
|
+
* text) or re-point its color span.
|
|
37
|
+
*/
|
|
38
|
+
export function marksSignature(marks: Mark[]): string {
|
|
39
|
+
if (marks.length === 0) return '';
|
|
40
|
+
// Sorted so order doesn't matter. A theoretical separator collision (a mark key can
|
|
41
|
+
// embed free-form href/label text) is harmless: this signature is only ever combined
|
|
42
|
+
// with the run's index in a React key, which already guarantees uniqueness — at worst
|
|
43
|
+
// a collision would miss a remount (the pre-fix behavior), never break rendering.
|
|
44
|
+
return marks.map(markKey).sort().join(' ');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Order-insensitive set equality (link href included). */
|
|
48
|
+
export function marksEqual(a: Mark[], b: Mark[]): boolean {
|
|
49
|
+
if (a === b) return true;
|
|
50
|
+
if (a.length !== b.length) return false;
|
|
51
|
+
if (a.length === 0) return true;
|
|
52
|
+
if (a.length === 1) return markKey(a[0]) === markKey(b[0]);
|
|
53
|
+
const ka = a.map(markKey).sort();
|
|
54
|
+
const kb = b.map(markKey).sort();
|
|
55
|
+
return ka.every((k, i) => k === kb[i]);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Returns `true` iff `marks` contains a mark of the given `type`. */
|
|
59
|
+
export function hasMark(marks: Mark[], type: MarkType): boolean {
|
|
60
|
+
return marks.some((m) => m.type === type);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Immutable add; replaces an existing mark of the same type (e.g. new link href). */
|
|
64
|
+
export function withMark(marks: Mark[], mark: Mark): Mark[] {
|
|
65
|
+
return [...marks.filter((m) => m.type !== mark.type), mark];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Immutable remove; returns a new array with all marks of `type` filtered out. */
|
|
69
|
+
export function withoutMark(marks: Mark[], type: MarkType): Mark[] {
|
|
70
|
+
return marks.filter((m) => m.type !== type);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Immutable toggle: if `marks` already contains `mark.type`, removes it;
|
|
75
|
+
* otherwise adds `mark` (replacing any existing mark of the same type).
|
|
76
|
+
* Returns a new array — never mutates the input.
|
|
77
|
+
*/
|
|
78
|
+
export function toggleMark(marks: Mark[], mark: Mark): Mark[] {
|
|
79
|
+
return hasMark(marks, mark.type) ? withoutMark(marks, mark.type) : withMark(marks, mark);
|
|
80
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// mdToHtml.ts — minimal Markdown → HTML-subset converter (INTERNAL). Emits only
|
|
2
|
+
// the tags fromHtml understands (h1-6, p, pre>code, blockquote, ul/ol/li, and
|
|
3
|
+
// inline strong/em/del/code/a), so fromMarkdown = fromHtml(mdToHtml(md)) reuses
|
|
4
|
+
// one mapping. CommonMark + GFM strikethrough subset. Never throws.
|
|
5
|
+
|
|
6
|
+
import { escapeHtml, escapeAttr } from './escape';
|
|
7
|
+
|
|
8
|
+
const LIST_RE = /^(\s*)([-*+]|\d+[.)])\s+(.*)$/;
|
|
9
|
+
|
|
10
|
+
/** Convert inline Markdown to HTML. Unbalanced markers degrade to literal text. */
|
|
11
|
+
function inline(src: string): string {
|
|
12
|
+
let out = '';
|
|
13
|
+
let i = 0;
|
|
14
|
+
while (i < src.length) {
|
|
15
|
+
const c = src[i];
|
|
16
|
+
if (c === '\\' && i + 1 < src.length) {
|
|
17
|
+
out += escapeHtml(src[i + 1]);
|
|
18
|
+
i += 2;
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (c === '`') {
|
|
22
|
+
const end = src.indexOf('`', i + 1);
|
|
23
|
+
if (end !== -1) {
|
|
24
|
+
out += '<code>' + escapeHtml(src.slice(i + 1, end)) + '</code>';
|
|
25
|
+
i = end + 1;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (c === '!' && src[i + 1] === '[') {
|
|
30
|
+
const m = /^!\[([^\]]*)\]\(([^)]*)\)/.exec(src.slice(i));
|
|
31
|
+
if (m) {
|
|
32
|
+
out += inline(m[1]); // image → its alt text (not a link, not an <img>)
|
|
33
|
+
i += m[0].length;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (c === '[') {
|
|
38
|
+
// Allow backslash-escaped `]` inside the link text (toMarkdown escapes a
|
|
39
|
+
// literal `]` to `\]`); a plain `[^\]]*` would stop at it and lose the link.
|
|
40
|
+
const m = /^\[((?:[^\]\\]|\\.)*)\]\(([^)]*)\)/.exec(src.slice(i));
|
|
41
|
+
if (m) {
|
|
42
|
+
out += '<a href="' + escapeAttr(m[2].trim()) + '">' + inline(m[1]) + '</a>';
|
|
43
|
+
i += m[0].length;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Triple marker → bold+italic. Checked before the double marker so `***x***`
|
|
48
|
+
// isn't mis-split into `**` + a stray `*`.
|
|
49
|
+
if ((c === '*' || c === '_') && src[i + 1] === c && src[i + 2] === c) {
|
|
50
|
+
const marker = c + c + c;
|
|
51
|
+
const end = src.indexOf(marker, i + 3);
|
|
52
|
+
if (end > i + 3) {
|
|
53
|
+
out += '<strong><em>' + inline(src.slice(i + 3, end)) + '</em></strong>';
|
|
54
|
+
i = end + 3;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if ((c === '*' || c === '_') && src[i + 1] === c) {
|
|
59
|
+
const marker = c + c;
|
|
60
|
+
const end = src.indexOf(marker, i + 2);
|
|
61
|
+
if (end !== -1) {
|
|
62
|
+
out += '<strong>' + inline(src.slice(i + 2, end)) + '</strong>';
|
|
63
|
+
i = end + 2;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (c === '~' && src[i + 1] === '~') {
|
|
68
|
+
const end = src.indexOf('~~', i + 2);
|
|
69
|
+
if (end !== -1) {
|
|
70
|
+
out += '<del>' + inline(src.slice(i + 2, end)) + '</del>';
|
|
71
|
+
i = end + 2;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Emphasis: require non-space immediately inside the markers (a minimal
|
|
76
|
+
// CommonMark flanking check) so `a _ b _ c` stays literal instead of
|
|
77
|
+
// wrapping whitespace in <em>.
|
|
78
|
+
if ((c === '*' || c === '_') && src[i + 1] !== ' ') {
|
|
79
|
+
const end = src.indexOf(c, i + 1);
|
|
80
|
+
if (end > i + 1 && src[end - 1] !== ' ') {
|
|
81
|
+
out += '<em>' + inline(src.slice(i + 1, end)) + '</em>';
|
|
82
|
+
i = end + 1;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
out += escapeHtml(c);
|
|
87
|
+
i += 1;
|
|
88
|
+
}
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Parse one list starting at `lines[start]` whose marker indent is `indent`. */
|
|
93
|
+
function parseList(lines: string[], start: number, indent: number): [string, number] {
|
|
94
|
+
const ordered = /\d/.test(LIST_RE.exec(lines[start])![2]);
|
|
95
|
+
const tag = ordered ? 'ol' : 'ul';
|
|
96
|
+
let i = start;
|
|
97
|
+
let html = `<${tag}>`;
|
|
98
|
+
while (i < lines.length) {
|
|
99
|
+
const m = LIST_RE.exec(lines[i]);
|
|
100
|
+
if (!m || m[1].length < indent) break;
|
|
101
|
+
if (m[1].length > indent) break; // deeper line handled as nested below
|
|
102
|
+
let item = '<li>' + inline(m[3].trim());
|
|
103
|
+
i += 1;
|
|
104
|
+
while (i < lines.length) {
|
|
105
|
+
const deeper = LIST_RE.exec(lines[i]);
|
|
106
|
+
if (deeper && deeper[1].length > indent) {
|
|
107
|
+
const [nested, consumed] = parseList(lines, i, deeper[1].length);
|
|
108
|
+
item += nested;
|
|
109
|
+
i = consumed;
|
|
110
|
+
} else break;
|
|
111
|
+
}
|
|
112
|
+
item += '</li>';
|
|
113
|
+
html += item;
|
|
114
|
+
}
|
|
115
|
+
return [html + `</${tag}>`, i];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Convert a Markdown string to the HTML subset fromHtml understands. */
|
|
119
|
+
export function mdToHtml(md: string): string {
|
|
120
|
+
const lines = md.replace(/\r\n?/g, '\n').split('\n');
|
|
121
|
+
const out: string[] = [];
|
|
122
|
+
let i = 0;
|
|
123
|
+
while (i < lines.length) {
|
|
124
|
+
const line = lines[i];
|
|
125
|
+
if (line.trim() === '') {
|
|
126
|
+
i += 1;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const fence = /^(```|~~~)/.exec(line);
|
|
130
|
+
if (fence) {
|
|
131
|
+
i += 1;
|
|
132
|
+
const code: string[] = [];
|
|
133
|
+
while (i < lines.length && !lines[i].startsWith(fence[1])) {
|
|
134
|
+
code.push(lines[i]);
|
|
135
|
+
i += 1;
|
|
136
|
+
}
|
|
137
|
+
if (i < lines.length) i += 1; // skip closing fence
|
|
138
|
+
out.push('<pre><code>' + escapeHtml(code.join('\n')) + '</code></pre>');
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const h = /^(#{1,6})\s+(.*)$/.exec(line);
|
|
142
|
+
if (h) {
|
|
143
|
+
const level = h[1].length;
|
|
144
|
+
out.push(`<h${level}>` + inline(h[2].trim()) + `</h${level}>`);
|
|
145
|
+
i += 1;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (/^>\s?/.test(line)) {
|
|
149
|
+
const quote: string[] = [];
|
|
150
|
+
while (i < lines.length && /^>\s?/.test(lines[i])) {
|
|
151
|
+
quote.push(lines[i].replace(/^>\s?/, ''));
|
|
152
|
+
i += 1;
|
|
153
|
+
}
|
|
154
|
+
out.push('<blockquote>' + mdToHtml(quote.join('\n')) + '</blockquote>');
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (LIST_RE.test(line)) {
|
|
158
|
+
const [html, consumed] = parseList(lines, i, LIST_RE.exec(line)![1].length);
|
|
159
|
+
out.push(html);
|
|
160
|
+
i = consumed;
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
const buf: string[] = [];
|
|
164
|
+
while (
|
|
165
|
+
i < lines.length &&
|
|
166
|
+
lines[i].trim() !== '' &&
|
|
167
|
+
!/^(```|~~~)/.test(lines[i]) &&
|
|
168
|
+
!/^#{1,6}\s/.test(lines[i]) &&
|
|
169
|
+
!/^>\s?/.test(lines[i]) &&
|
|
170
|
+
!LIST_RE.test(lines[i])
|
|
171
|
+
) {
|
|
172
|
+
buf.push(lines[i].trim());
|
|
173
|
+
i += 1;
|
|
174
|
+
}
|
|
175
|
+
out.push('<p>' + inline(buf.join(' ')) + '</p>');
|
|
176
|
+
}
|
|
177
|
+
return out.join('');
|
|
178
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// model.ts — RichText document model types + constructors. Pure data; no DOM.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* All supported block-level content types. `heading` requires a `level`; list
|
|
5
|
+
* types (`bullet_item`, `ordered_item`) accept a `depth` for nesting.
|
|
6
|
+
*/
|
|
7
|
+
export type BlockType =
|
|
8
|
+
| 'paragraph'
|
|
9
|
+
| 'heading'
|
|
10
|
+
| 'bullet_item'
|
|
11
|
+
| 'ordered_item'
|
|
12
|
+
| 'blockquote'
|
|
13
|
+
| 'code_block'
|
|
14
|
+
| 'attachment';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* All supported inline mark types. `link` carries `href`; `mention` carries `id` + `label`;
|
|
18
|
+
* `textColor`/`bgColor` carry a palette `color` KEY (e.g. `'red'`), never a raw hex — see
|
|
19
|
+
* `colorMarks.ts` for the key → CSS-custom-property resolution.
|
|
20
|
+
*/
|
|
21
|
+
export type MarkType =
|
|
22
|
+
| 'bold'
|
|
23
|
+
| 'italic'
|
|
24
|
+
| 'underline'
|
|
25
|
+
| 'strike'
|
|
26
|
+
| 'code'
|
|
27
|
+
| 'link'
|
|
28
|
+
| 'mention'
|
|
29
|
+
| 'textColor'
|
|
30
|
+
| 'bgColor';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* A formatting mark. Flags carry no data; `link` carries an href; `mention` an id + label.
|
|
34
|
+
* `textColor`/`bgColor` carry a palette `color` KEY (e.g. `'red'`), not a raw value — the key
|
|
35
|
+
* resolves to a token-backed CSS custom property via `colorMarks.ts`.
|
|
36
|
+
*/
|
|
37
|
+
export type Mark =
|
|
38
|
+
| { type: 'bold' }
|
|
39
|
+
| { type: 'italic' }
|
|
40
|
+
| { type: 'underline' }
|
|
41
|
+
| { type: 'strike' }
|
|
42
|
+
| { type: 'code' }
|
|
43
|
+
| { type: 'link'; href: string }
|
|
44
|
+
| { type: 'mention'; id: string; label: string }
|
|
45
|
+
| { type: 'textColor'; color: string }
|
|
46
|
+
| { type: 'bgColor'; color: string };
|
|
47
|
+
|
|
48
|
+
/** A run of text sharing exactly one mark set. */
|
|
49
|
+
export interface Inline {
|
|
50
|
+
text: string;
|
|
51
|
+
marks: Mark[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** One line-level block. Lists are flat items addressed by `depth` (no tree). */
|
|
55
|
+
export interface Block {
|
|
56
|
+
/** Stable id → React keys + position stability. */
|
|
57
|
+
id: string;
|
|
58
|
+
type: BlockType;
|
|
59
|
+
/** Heading level, only for `type: 'heading'`. */
|
|
60
|
+
level?: 1 | 2 | 3;
|
|
61
|
+
/** List nesting depth (0-based), only for list items. */
|
|
62
|
+
depth?: number;
|
|
63
|
+
/** Inline content. An empty block holds a single empty run. */
|
|
64
|
+
inlines: Inline[];
|
|
65
|
+
/** Attachment block only (type === 'attachment'). The uploaded URL — absent while uploading. */
|
|
66
|
+
src?: string;
|
|
67
|
+
/** Attachment filename / chip label. */
|
|
68
|
+
name?: string;
|
|
69
|
+
/** Attachment MIME — `image/*` renders a preview, else a file chip. */
|
|
70
|
+
mime?: string;
|
|
71
|
+
/** Natural image dimensions (layout hints). */
|
|
72
|
+
width?: number;
|
|
73
|
+
height?: number;
|
|
74
|
+
/**
|
|
75
|
+
* Image alt text. Unlike every label prop in this library, an EMPTY string
|
|
76
|
+
* is honoured rather than treated as unset: `alt=""` is HTML's own marker
|
|
77
|
+
* for a decorative image, so it renders literally instead of falling back to
|
|
78
|
+
* the filename.
|
|
79
|
+
*/
|
|
80
|
+
alt?: string;
|
|
81
|
+
/** Attachment image alignment within the editor width. Absent = left. */
|
|
82
|
+
align?: 'left' | 'center' | 'right';
|
|
83
|
+
/** Attachment upload state. `ready`/absent = final. */
|
|
84
|
+
status?: 'uploading' | 'ready' | 'error';
|
|
85
|
+
/**
|
|
86
|
+
* Why the last upload failed, shown on the `error` block. Set only from an
|
|
87
|
+
* `UploadError` rejection; cleared on retry. Transient like `status` — an
|
|
88
|
+
* error block never serializes to HTML/Markdown.
|
|
89
|
+
*/
|
|
90
|
+
uploadError?: string;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** A rich-text document: an ordered list of blocks. */
|
|
94
|
+
export interface RichDoc {
|
|
95
|
+
blocks: Block[];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** A point in the document: a character offset within a block. */
|
|
99
|
+
export interface Point {
|
|
100
|
+
blockId: string;
|
|
101
|
+
/** 0..blockLength */
|
|
102
|
+
offset: number;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** A selection / span. `anchor` may come before or after `focus`. */
|
|
106
|
+
export interface Range {
|
|
107
|
+
anchor: Point;
|
|
108
|
+
focus: Point;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Module-local monotonic id source. NOT Math.random/Date.now (unavailable in
|
|
112
|
+
// some contexts + non-deterministic). Unique within a session — enough for keys.
|
|
113
|
+
let idCounter = 0;
|
|
114
|
+
/**
|
|
115
|
+
* Generate a session-unique block id. Ids are monotonically incrementing strings
|
|
116
|
+
* (`rt1`, `rt2`, …) — deterministic within a session but NOT across page reloads.
|
|
117
|
+
* Use the `id` field in `CreateBlockAttrs` to pin ids in tests.
|
|
118
|
+
*/
|
|
119
|
+
export function nextId(): string {
|
|
120
|
+
idCounter += 1;
|
|
121
|
+
return `rt${idCounter}`;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Optional attributes for `createBlock`. All fields are optional.
|
|
126
|
+
* - `level` — heading level (1–3); only meaningful for `type: 'heading'`.
|
|
127
|
+
* - `depth` — list nesting depth (0-based); only meaningful for list items.
|
|
128
|
+
* - `marks` — marks applied to the initial text run.
|
|
129
|
+
* - `id` — pin the block id (useful for tests and deterministic seeding).
|
|
130
|
+
*/
|
|
131
|
+
export interface CreateBlockAttrs {
|
|
132
|
+
level?: 1 | 2 | 3;
|
|
133
|
+
depth?: number;
|
|
134
|
+
marks?: Mark[];
|
|
135
|
+
/** Pin the id (tests / deterministic construction). */
|
|
136
|
+
id?: string;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** Build a block. Empty `text` → a single empty run. */
|
|
140
|
+
export function createBlock(type: BlockType, text = '', attrs: CreateBlockAttrs = {}): Block {
|
|
141
|
+
const { level, depth, marks = [], id } = attrs;
|
|
142
|
+
const inlines: Inline[] = text === '' ? [{ text: '', marks: [] }] : [{ text, marks }];
|
|
143
|
+
const block: Block = { id: id ?? nextId(), type, inlines };
|
|
144
|
+
if (level !== undefined) block.level = level;
|
|
145
|
+
if (depth !== undefined) block.depth = depth;
|
|
146
|
+
return block;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** A document with one empty paragraph. */
|
|
150
|
+
export function emptyDoc(): RichDoc {
|
|
151
|
+
return { blocks: [createBlock('paragraph')] };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Build a paragraph-per-line document from plain text (a demo/seed helper). */
|
|
155
|
+
export function docFromText(text: string): RichDoc {
|
|
156
|
+
return { blocks: text.split('\n').map((line) => createBlock('paragraph', line)) };
|
|
157
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// position.ts — Layer C. Point/range helpers over a RichDoc.
|
|
2
|
+
import type { RichDoc, Block, Point, Range, Mark } from './model';
|
|
3
|
+
import { runsLength } from './inlines';
|
|
4
|
+
|
|
5
|
+
/** Total character length of a block (sum of all inline run lengths). */
|
|
6
|
+
export function blockLength(block: Block): number {
|
|
7
|
+
return runsLength(block.inlines);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The `Range` spanning an entire block — `offset 0` to its full length. Returns
|
|
12
|
+
* `null` when `blockId` is not found. Used by block-level actions (e.g. coloring
|
|
13
|
+
* a whole block from the block menu) that target a block rather than an explicit
|
|
14
|
+
* text selection.
|
|
15
|
+
*/
|
|
16
|
+
export function wholeBlockRange(doc: RichDoc, blockId: string): Range | null {
|
|
17
|
+
const idx = findBlockIndex(doc, blockId);
|
|
18
|
+
if (idx === -1) return null;
|
|
19
|
+
const block = doc.blocks[idx];
|
|
20
|
+
return {
|
|
21
|
+
anchor: { blockId, offset: 0 },
|
|
22
|
+
focus: { blockId, offset: blockLength(block) },
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Returns the index of the block with `blockId` in `doc.blocks`, or `-1` if
|
|
28
|
+
* not found. Used by transforms to locate blocks before mutation.
|
|
29
|
+
*/
|
|
30
|
+
export function findBlockIndex(doc: RichDoc, blockId: string): number {
|
|
31
|
+
return doc.blocks.findIndex((b) => b.id === blockId);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Document order: -1 if a before b, 1 if after, 0 if equal. */
|
|
35
|
+
export function comparePoints(doc: RichDoc, a: Point, b: Point): -1 | 0 | 1 {
|
|
36
|
+
if (a.blockId === b.blockId) {
|
|
37
|
+
return a.offset < b.offset ? -1 : a.offset > b.offset ? 1 : 0;
|
|
38
|
+
}
|
|
39
|
+
const ia = findBlockIndex(doc, a.blockId);
|
|
40
|
+
const ib = findBlockIndex(doc, b.blockId);
|
|
41
|
+
return ia < ib ? -1 : ia > ib ? 1 : 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The marks carried by the character immediately before `point` (raw — includes
|
|
46
|
+
* `mention`). Empty (`[]`) at a block start (`offset <= 0`) or when the block is
|
|
47
|
+
* not found. This primitive stays mark-agnostic; typing-inheritance paths use
|
|
48
|
+
* {@link marksForTypedText}, which applies the exclusions.
|
|
49
|
+
*/
|
|
50
|
+
export function marksBeforeCaret(doc: RichDoc, point: Point): Mark[] {
|
|
51
|
+
const idx = findBlockIndex(doc, point.blockId);
|
|
52
|
+
if (idx === -1 || point.offset <= 0) return [];
|
|
53
|
+
let pos = 0;
|
|
54
|
+
for (const run of doc.blocks[idx].inlines ?? []) {
|
|
55
|
+
const end = pos + run.text.length;
|
|
56
|
+
if (point.offset - 1 >= pos && point.offset - 1 < end) return run.marks;
|
|
57
|
+
pos = end;
|
|
58
|
+
}
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* The marks carried by the character immediately AFTER `point` (raw, like
|
|
64
|
+
* {@link marksBeforeCaret}). Empty (`[]`) at a block end, where no character
|
|
65
|
+
* follows. Typing-inheritance paths pair it with `marksBeforeCaret` to tell a
|
|
66
|
+
* caret INSIDE a run from one resting against its trailing edge.
|
|
67
|
+
*/
|
|
68
|
+
export function marksAfterCaret(doc: RichDoc, point: Point): Mark[] {
|
|
69
|
+
const idx = findBlockIndex(doc, point.blockId);
|
|
70
|
+
if (idx === -1 || point.offset < 0) return [];
|
|
71
|
+
let pos = 0;
|
|
72
|
+
for (const run of doc.blocks[idx].inlines ?? []) {
|
|
73
|
+
const end = pos + run.text.length;
|
|
74
|
+
if (point.offset >= pos && point.offset < end) return run.marks;
|
|
75
|
+
pos = end;
|
|
76
|
+
}
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The marks text typed at `point` inherits — those of the preceding character,
|
|
82
|
+
* minus the two that must not grow when the caret merely abuts them:
|
|
83
|
+
* - `mention`, never (typed text never extends a mention chip);
|
|
84
|
+
* - `link`, unless the FOLLOWING character carries the same href, i.e. the caret
|
|
85
|
+
* sits strictly inside the link rather than against its trailing edge.
|
|
86
|
+
*
|
|
87
|
+
* Without the `link` rule, typing after a link appends into the link's TEXT while
|
|
88
|
+
* its href stays put. Under `renderLink` that is invisible — the widget renders
|
|
89
|
+
* from the href — so the characters vanish and the caret appears frozen.
|
|
90
|
+
*
|
|
91
|
+
* The single source of this rule: both `insertText` and the editor's pending-mark
|
|
92
|
+
* staging read it, so a mark toggled at a link's edge can't reinstate the link.
|
|
93
|
+
*/
|
|
94
|
+
export function marksForTypedText(doc: RichDoc, point: Point): Mark[] {
|
|
95
|
+
const after = marksAfterCaret(doc, point);
|
|
96
|
+
return marksBeforeCaret(doc, point).filter((m) => {
|
|
97
|
+
if (m.type === 'mention') return false;
|
|
98
|
+
if (m.type === 'link') return after.some((a) => a.type === 'link' && a.href === m.href);
|
|
99
|
+
return true;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** A collapsed range at a single point. */
|
|
104
|
+
export function collapsedRange(blockId: string, offset = 0): Range {
|
|
105
|
+
return { anchor: { blockId, offset }, focus: { blockId, offset } };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Returns `true` iff `range` is collapsed — anchor and focus point to the same position. */
|
|
109
|
+
export function isCollapsed(range: Range): boolean {
|
|
110
|
+
return range.anchor.blockId === range.focus.blockId && range.anchor.offset === range.focus.offset;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Normalize a range so `start` ≤ `end` in document order. */
|
|
114
|
+
export function orderedRange(doc: RichDoc, range: Range): { start: Point; end: Point } {
|
|
115
|
+
return comparePoints(doc, range.anchor, range.focus) <= 0
|
|
116
|
+
? { start: range.anchor, end: range.focus }
|
|
117
|
+
: { start: range.focus, end: range.anchor };
|
|
118
|
+
}
|