@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.
Files changed (897) hide show
  1. package/AI-PRIMER.md +341 -0
  2. package/README.md +262 -2
  3. package/docs/components/Accordion.md +114 -0
  4. package/docs/components/AgentAvatar.md +58 -0
  5. package/docs/components/Alert.md +81 -0
  6. package/docs/components/AppLayout.md +70 -0
  7. package/docs/components/Avatar.md +49 -0
  8. package/docs/components/AvatarGroup.md +47 -0
  9. package/docs/components/Badge.md +60 -0
  10. package/docs/components/Banner.md +89 -0
  11. package/docs/components/BrandIcon.md +32 -0
  12. package/docs/components/Breadcrumb.md +72 -0
  13. package/docs/components/Button.md +107 -0
  14. package/docs/components/ButtonGroup.md +78 -0
  15. package/docs/components/Calendar.md +158 -0
  16. package/docs/components/Card.md +165 -0
  17. package/docs/components/CatalogPicker.md +83 -0
  18. package/docs/components/Chart.md +114 -0
  19. package/docs/components/ChatBubble.md +55 -0
  20. package/docs/components/ChatLauncher.md +97 -0
  21. package/docs/components/Checkbox.md +55 -0
  22. package/docs/components/CircularProgress.md +53 -0
  23. package/docs/components/Cluster.md +96 -0
  24. package/docs/components/Code.md +35 -0
  25. package/docs/components/CodeBlock.md +67 -0
  26. package/docs/components/ColorPicker.md +115 -0
  27. package/docs/components/ConfirmationPopover.md +70 -0
  28. package/docs/components/Constrain.md +39 -0
  29. package/docs/components/CurrencySelect.md +57 -0
  30. package/docs/components/CursorPagination.md +43 -0
  31. package/docs/components/DashboardCanvas.md +79 -0
  32. package/docs/components/DashboardWidget.md +131 -0
  33. package/docs/components/DataTable.md +88 -0
  34. package/docs/components/DatePicker.md +68 -0
  35. package/docs/components/DateRangePicker.md +71 -0
  36. package/docs/components/DateStrip.md +56 -0
  37. package/docs/components/DefinitionList.md +82 -0
  38. package/docs/components/Divider.md +57 -0
  39. package/docs/components/Dot.md +26 -0
  40. package/docs/components/Drawer.md +94 -0
  41. package/docs/components/DropdownMenu.md +299 -0
  42. package/docs/components/EmojiPicker.md +84 -0
  43. package/docs/components/EmptyState.md +55 -0
  44. package/docs/components/EntityChip.md +102 -0
  45. package/docs/components/ErrorState.md +72 -0
  46. package/docs/components/Field.md +91 -0
  47. package/docs/components/FileUpload.md +109 -0
  48. package/docs/components/FilterChip.md +88 -0
  49. package/docs/components/FlowCanvas.md +108 -0
  50. package/docs/components/FormRow.md +31 -0
  51. package/docs/components/FormSection.md +37 -0
  52. package/docs/components/Grid.md +103 -0
  53. package/docs/components/Highlight.md +75 -0
  54. package/docs/components/HighlightedText.md +50 -0
  55. package/docs/components/IconPicker.md +134 -0
  56. package/docs/components/IconTile.md +30 -0
  57. package/docs/components/Image.md +84 -0
  58. package/docs/components/ImageCrop.md +163 -0
  59. package/docs/components/Indent.md +31 -0
  60. package/docs/components/InlineDatePicker.md +58 -0
  61. package/docs/components/InlineDateRangePicker.md +57 -0
  62. package/docs/components/Input.md +54 -0
  63. package/docs/components/Kanban.md +122 -0
  64. package/docs/components/Kbd.md +41 -0
  65. package/docs/components/Lightbox.md +105 -0
  66. package/docs/components/Link.md +65 -0
  67. package/docs/components/LinkCard.md +41 -0
  68. package/docs/components/LiquidEditor.md +84 -0
  69. package/docs/components/List.md +68 -0
  70. package/docs/components/LiveRegion.md +29 -0
  71. package/docs/components/LocaleProvider.md +25 -0
  72. package/docs/components/Logo.md +41 -0
  73. package/docs/components/Masonry.md +48 -0
  74. package/docs/components/MediaTile.md +95 -0
  75. package/docs/components/Modal.md +107 -0
  76. package/docs/components/MoneyInput.md +62 -0
  77. package/docs/components/OptionsPicker.md +123 -0
  78. package/docs/components/OtpInput.md +65 -0
  79. package/docs/components/Page.md +35 -0
  80. package/docs/components/PageHeader.md +133 -0
  81. package/docs/components/Pagination.md +44 -0
  82. package/docs/components/Palette.md +32 -0
  83. package/docs/components/PasswordInput.md +45 -0
  84. package/docs/components/PasswordStrengthMeter.md +27 -0
  85. package/docs/components/PersonDisplay.md +153 -0
  86. package/docs/components/PhoneInput.md +54 -0
  87. package/docs/components/PillMenu.md +91 -0
  88. package/docs/components/Popover.md +127 -0
  89. package/docs/components/Progress.md +56 -0
  90. package/docs/components/QrCode.md +34 -0
  91. package/docs/components/Radio.md +37 -0
  92. package/docs/components/RadioGroup.md +56 -0
  93. package/docs/components/Rail.md +191 -0
  94. package/docs/components/RelativeDateInput.md +114 -0
  95. package/docs/components/RichText.md +44 -0
  96. package/docs/components/RichTextEditor.md +112 -0
  97. package/docs/components/Screen.md +37 -0
  98. package/docs/components/ScrollArea.md +39 -0
  99. package/docs/components/Select.md +131 -0
  100. package/docs/components/SettingRow.md +98 -0
  101. package/docs/components/Skeleton.md +68 -0
  102. package/docs/components/Slider.md +92 -0
  103. package/docs/components/SlotGrid.md +55 -0
  104. package/docs/components/SocialButton.md +31 -0
  105. package/docs/components/Sortable.md +127 -0
  106. package/docs/components/SortableGroup.md +52 -0
  107. package/docs/components/Sparkline.md +51 -0
  108. package/docs/components/Split.md +76 -0
  109. package/docs/components/Stack.md +59 -0
  110. package/docs/components/StagePath.md +66 -0
  111. package/docs/components/StatGroup.md +61 -0
  112. package/docs/components/StatTile.md +58 -0
  113. package/docs/components/Sticky.md +69 -0
  114. package/docs/components/Switch.md +89 -0
  115. package/docs/components/Table.md +184 -0
  116. package/docs/components/TableOfContents.md +76 -0
  117. package/docs/components/Tabs.md +94 -0
  118. package/docs/components/Text.md +63 -0
  119. package/docs/components/Textarea.md +59 -0
  120. package/docs/components/Thread.md +52 -0
  121. package/docs/components/TimeField.md +70 -0
  122. package/docs/components/Timeline.md +57 -0
  123. package/docs/components/Title.md +54 -0
  124. package/docs/components/ToastViewport.md +61 -0
  125. package/docs/components/Tooltip.md +63 -0
  126. package/docs/components/TopBar.md +214 -0
  127. package/docs/components/Tour.md +85 -0
  128. package/docs/components/TreeView.md +113 -0
  129. package/docs/components/VisuallyHidden.md +43 -0
  130. package/docs/components/WidgetPreview.md +54 -0
  131. package/docs/components/useBelowBreakpoint.md +11 -0
  132. package/docs/components/useMonth.md +18 -0
  133. package/docs/setup.md +51 -0
  134. package/docs/theming.md +95 -0
  135. package/docs/tokens.md +123 -0
  136. package/docs/transient-state.md +56 -0
  137. package/package.json +82 -4
  138. package/src/_meta/manifest.ts +293 -0
  139. package/src/app/AppProvider.tsx +78 -0
  140. package/src/app/index.ts +3 -0
  141. package/src/app/themeTokens.ts +95 -0
  142. package/src/calendar/dateMath.ts +114 -0
  143. package/src/calendar/formatters.ts +75 -0
  144. package/src/calendar/index.ts +39 -0
  145. package/src/calendar/types.ts +36 -0
  146. package/src/calendar/useAgenda.ts +70 -0
  147. package/src/calendar/useDay.ts +51 -0
  148. package/src/calendar/useMonth.ts +82 -0
  149. package/src/calendar/useWeek.ts +62 -0
  150. package/src/calendar/weekInfo.ts +83 -0
  151. package/src/components/Accordion/Accordion.module.scss +304 -0
  152. package/src/components/Accordion/Accordion.tokens.scss +64 -0
  153. package/src/components/Accordion/Accordion.tsx +272 -0
  154. package/src/components/Accordion/AccordionContent.tsx +36 -0
  155. package/src/components/Accordion/AccordionItem.tsx +66 -0
  156. package/src/components/Accordion/AccordionTrigger.tsx +121 -0
  157. package/src/components/Accordion/context.ts +47 -0
  158. package/src/components/Accordion/index.ts +14 -0
  159. package/src/components/Alert/Alert.module.scss +92 -0
  160. package/src/components/Alert/Alert.tokens.scss +60 -0
  161. package/src/components/Alert/Alert.tsx +136 -0
  162. package/src/components/Alert/index.ts +2 -0
  163. package/src/components/AppLayout/AppLayout.module.scss +130 -0
  164. package/src/components/AppLayout/AppLayout.tokens.scss +27 -0
  165. package/src/components/AppLayout/AppLayout.tsx +211 -0
  166. package/src/components/AppLayout/index.ts +2 -0
  167. package/src/components/Avatar/AgentAvatar.module.scss +117 -0
  168. package/src/components/Avatar/AgentAvatar.tsx +122 -0
  169. package/src/components/Avatar/Avatar.module.scss +181 -0
  170. package/src/components/Avatar/Avatar.tokens.scss +107 -0
  171. package/src/components/Avatar/Avatar.tsx +210 -0
  172. package/src/components/Avatar/AvatarGroup.module.scss +128 -0
  173. package/src/components/Avatar/AvatarGroup.tsx +119 -0
  174. package/src/components/Avatar/AvatarGroupContext.tsx +20 -0
  175. package/src/components/Avatar/index.ts +6 -0
  176. package/src/components/Badge/Badge.module.scss +124 -0
  177. package/src/components/Badge/Badge.tokens.scss +74 -0
  178. package/src/components/Badge/Badge.tsx +164 -0
  179. package/src/components/Badge/index.ts +2 -0
  180. package/src/components/Banner/Banner.module.scss +73 -0
  181. package/src/components/Banner/Banner.tokens.scss +51 -0
  182. package/src/components/Banner/Banner.tsx +138 -0
  183. package/src/components/Banner/index.ts +2 -0
  184. package/src/components/BrandIcon/BrandIcon.module.scss +5 -0
  185. package/src/components/BrandIcon/BrandIcon.tsx +99 -0
  186. package/src/components/BrandIcon/index.ts +2 -0
  187. package/src/components/Breadcrumb/Breadcrumb.module.scss +32 -0
  188. package/src/components/Breadcrumb/Breadcrumb.tokens.scss +9 -0
  189. package/src/components/Breadcrumb/Breadcrumb.tsx +146 -0
  190. package/src/components/Breadcrumb/index.ts +2 -0
  191. package/src/components/Button/Button.module.scss +167 -0
  192. package/src/components/Button/Button.tokens.scss +90 -0
  193. package/src/components/Button/Button.tsx +205 -0
  194. package/src/components/Button/index.ts +2 -0
  195. package/src/components/ButtonGroup/ButtonGroup.module.scss +134 -0
  196. package/src/components/ButtonGroup/ButtonGroup.tokens.scss +42 -0
  197. package/src/components/ButtonGroup/ButtonGroup.tsx +278 -0
  198. package/src/components/ButtonGroup/ButtonGroupItem.tsx +74 -0
  199. package/src/components/ButtonGroup/context.ts +45 -0
  200. package/src/components/ButtonGroup/index.ts +2 -0
  201. package/src/components/Calendar/AgendaView.module.scss +231 -0
  202. package/src/components/Calendar/AgendaView.tsx +214 -0
  203. package/src/components/Calendar/AllDayBand.module.scss +18 -0
  204. package/src/components/Calendar/AllDayBand.tsx +75 -0
  205. package/src/components/Calendar/Calendar.module.scss +23 -0
  206. package/src/components/Calendar/Calendar.tokens.scss +262 -0
  207. package/src/components/Calendar/Calendar.tsx +370 -0
  208. package/src/components/Calendar/DayCell.module.scss +30 -0
  209. package/src/components/Calendar/DayCell.tsx +50 -0
  210. package/src/components/Calendar/DayView.module.scss +10 -0
  211. package/src/components/Calendar/DayView.tsx +163 -0
  212. package/src/components/Calendar/EventChip.module.scss +171 -0
  213. package/src/components/Calendar/EventChip.tsx +115 -0
  214. package/src/components/Calendar/HourGrid.module.scss +123 -0
  215. package/src/components/Calendar/HourGrid.tsx +381 -0
  216. package/src/components/Calendar/MonthView.module.scss +99 -0
  217. package/src/components/Calendar/MonthView.tsx +296 -0
  218. package/src/components/Calendar/TimedEvent.module.scss +205 -0
  219. package/src/components/Calendar/TimedEvent.tsx +247 -0
  220. package/src/components/Calendar/ViewSwitcher.module.scss +3 -0
  221. package/src/components/Calendar/ViewSwitcher.tsx +47 -0
  222. package/src/components/Calendar/WeekView.module.scss +10 -0
  223. package/src/components/Calendar/WeekView.tsx +137 -0
  224. package/src/components/Calendar/eventColor.ts +60 -0
  225. package/src/components/Calendar/index.ts +18 -0
  226. package/src/components/Calendar/types.ts +451 -0
  227. package/src/components/Calendar/useEventDrag.ts +783 -0
  228. package/src/components/Calendar/utils.ts +622 -0
  229. package/src/components/Card/Card.module.scss +264 -0
  230. package/src/components/Card/Card.tokens.scss +55 -0
  231. package/src/components/Card/Card.tsx +170 -0
  232. package/src/components/Card/CardBody.tsx +45 -0
  233. package/src/components/Card/CardHeader.tsx +113 -0
  234. package/src/components/Card/CardList.tsx +24 -0
  235. package/src/components/Card/CardListRow.tsx +24 -0
  236. package/src/components/Card/index.ts +7 -0
  237. package/src/components/CatalogPicker/CatalogPicker.module.scss +193 -0
  238. package/src/components/CatalogPicker/CatalogPicker.tokens.scss +26 -0
  239. package/src/components/CatalogPicker/CatalogPicker.tsx +339 -0
  240. package/src/components/CatalogPicker/index.ts +2 -0
  241. package/src/components/Chart/Chart.module.scss +287 -0
  242. package/src/components/Chart/Chart.tokens.scss +63 -0
  243. package/src/components/Chart/Chart.tsx +607 -0
  244. package/src/components/Chart/ChartLegend.tsx +99 -0
  245. package/src/components/Chart/ChartTable.tsx +62 -0
  246. package/src/components/Chart/ChartTooltip.tsx +91 -0
  247. package/src/components/Chart/chartModel.ts +689 -0
  248. package/src/components/Chart/index.ts +2 -0
  249. package/src/components/ChatBubble/ChatBubble.module.scss +93 -0
  250. package/src/components/ChatBubble/ChatBubble.tokens.scss +17 -0
  251. package/src/components/ChatBubble/ChatBubble.tsx +61 -0
  252. package/src/components/ChatBubble/ChatBubbleList.tsx +27 -0
  253. package/src/components/ChatBubble/index.ts +3 -0
  254. package/src/components/ChatLauncher/ChatLauncher.module.scss +68 -0
  255. package/src/components/ChatLauncher/ChatLauncher.tokens.scss +27 -0
  256. package/src/components/ChatLauncher/ChatLauncher.tsx +202 -0
  257. package/src/components/ChatLauncher/index.ts +2 -0
  258. package/src/components/ChatLauncher/isAtBottom.ts +12 -0
  259. package/src/components/Checkbox/Checkbox.module.scss +147 -0
  260. package/src/components/Checkbox/Checkbox.tokens.scss +44 -0
  261. package/src/components/Checkbox/Checkbox.tsx +188 -0
  262. package/src/components/Checkbox/index.ts +2 -0
  263. package/src/components/CircularProgress/CircularProgress.module.scss +133 -0
  264. package/src/components/CircularProgress/CircularProgress.tokens.scss +40 -0
  265. package/src/components/CircularProgress/CircularProgress.tsx +139 -0
  266. package/src/components/CircularProgress/index.ts +7 -0
  267. package/src/components/Cluster/Cluster.module.scss +145 -0
  268. package/src/components/Cluster/Cluster.tokens.scss +11 -0
  269. package/src/components/Cluster/Cluster.tsx +215 -0
  270. package/src/components/Cluster/index.ts +2 -0
  271. package/src/components/Code/Code.module.scss +28 -0
  272. package/src/components/Code/Code.tokens.scss +15 -0
  273. package/src/components/Code/Code.tsx +44 -0
  274. package/src/components/Code/index.ts +2 -0
  275. package/src/components/CodeBlock/CodeBlock.module.scss +146 -0
  276. package/src/components/CodeBlock/CodeBlock.tokens.scss +27 -0
  277. package/src/components/CodeBlock/CodeBlock.tsx +274 -0
  278. package/src/components/CodeBlock/highlight.ts +179 -0
  279. package/src/components/CodeBlock/index.ts +8 -0
  280. package/src/components/CodeBlock/sampleSync.ts +42 -0
  281. package/src/components/ColorPicker/ColorPicker.module.scss +286 -0
  282. package/src/components/ColorPicker/ColorPicker.tokens.scss +60 -0
  283. package/src/components/ColorPicker/ColorPicker.tsx +367 -0
  284. package/src/components/ColorPicker/ColorPickerPanel.tsx +265 -0
  285. package/src/components/ColorPicker/SVSquare.tsx +189 -0
  286. package/src/components/ColorPicker/colorMath.ts +141 -0
  287. package/src/components/ColorPicker/index.ts +6 -0
  288. package/src/components/ConfirmationPopover/ConfirmationPopover.module.scss +39 -0
  289. package/src/components/ConfirmationPopover/ConfirmationPopover.tokens.scss +13 -0
  290. package/src/components/ConfirmationPopover/ConfirmationPopover.tsx +395 -0
  291. package/src/components/ConfirmationPopover/index.ts +2 -0
  292. package/src/components/Constrain/Constrain.module.scss +99 -0
  293. package/src/components/Constrain/Constrain.tsx +79 -0
  294. package/src/components/Constrain/index.ts +2 -0
  295. package/src/components/CurrencySelect/CurrencySelect.module.scss +7 -0
  296. package/src/components/CurrencySelect/CurrencySelect.tsx +167 -0
  297. package/src/components/CurrencySelect/index.ts +3 -0
  298. package/src/components/CursorPagination/CursorPagination.module.scss +69 -0
  299. package/src/components/CursorPagination/CursorPagination.tokens.scss +32 -0
  300. package/src/components/CursorPagination/CursorPagination.tsx +121 -0
  301. package/src/components/CursorPagination/index.ts +2 -0
  302. package/src/components/DashboardCanvas/DashboardCanvas.module.scss +360 -0
  303. package/src/components/DashboardCanvas/DashboardCanvas.tokens.scss +48 -0
  304. package/src/components/DashboardCanvas/DashboardCanvas.tsx +1270 -0
  305. package/src/components/DashboardCanvas/DashboardCanvasItem.tsx +140 -0
  306. package/src/components/DashboardCanvas/DashboardCanvasSection.tsx +174 -0
  307. package/src/components/DashboardCanvas/engine.ts +363 -0
  308. package/src/components/DashboardCanvas/index.ts +9 -0
  309. package/src/components/DashboardWidget/DashboardWidget.module.scss +100 -0
  310. package/src/components/DashboardWidget/DashboardWidget.tokens.scss +16 -0
  311. package/src/components/DashboardWidget/DashboardWidget.tsx +188 -0
  312. package/src/components/DashboardWidget/index.ts +7 -0
  313. package/src/components/DataTable/BodyRow.tsx +197 -0
  314. package/src/components/DataTable/ColumnVisibilityTrigger.module.scss +7 -0
  315. package/src/components/DataTable/ColumnVisibilityTrigger.tsx +105 -0
  316. package/src/components/DataTable/DataTable.module.scss +511 -0
  317. package/src/components/DataTable/DataTable.tokens.scss +80 -0
  318. package/src/components/DataTable/DataTable.tsx +734 -0
  319. package/src/components/DataTable/HeaderCell.module.scss +215 -0
  320. package/src/components/DataTable/HeaderCell.tsx +440 -0
  321. package/src/components/DataTable/columnShift.ts +117 -0
  322. package/src/components/DataTable/index.ts +23 -0
  323. package/src/components/DataTable/pinStyle.ts +47 -0
  324. package/src/components/DataTable/reorderColumns.ts +66 -0
  325. package/src/components/DataTable/types.ts +289 -0
  326. package/src/components/DataTable/useColumnDragShift.ts +216 -0
  327. package/src/components/DataTable/useDataTable.ts +372 -0
  328. package/src/components/DataTable/useResizeHandle.ts +97 -0
  329. package/src/components/DatePicker/DatePicker.module.scss +180 -0
  330. package/src/components/DatePicker/DatePicker.tokens.scss +152 -0
  331. package/src/components/DatePicker/DatePicker.tsx +664 -0
  332. package/src/components/DatePicker/DatePickerGrid.module.scss +172 -0
  333. package/src/components/DatePicker/DatePickerGrid.tsx +341 -0
  334. package/src/components/DatePicker/InlineDatePicker.module.scss +32 -0
  335. package/src/components/DatePicker/InlineDatePicker.tsx +201 -0
  336. package/src/components/DatePicker/index.ts +4 -0
  337. package/src/components/DatePicker/utils.ts +364 -0
  338. package/src/components/DateRangePicker/DateRangePicker.module.scss +237 -0
  339. package/src/components/DateRangePicker/DateRangePicker.tokens.scss +78 -0
  340. package/src/components/DateRangePicker/DateRangePicker.tsx +720 -0
  341. package/src/components/DateRangePicker/InlineDateRangePicker.module.scss +94 -0
  342. package/src/components/DateRangePicker/InlineDateRangePicker.tsx +376 -0
  343. package/src/components/DateRangePicker/index.ts +5 -0
  344. package/src/components/DateRangePicker/utils.ts +151 -0
  345. package/src/components/DateStrip/DateStrip.module.scss +78 -0
  346. package/src/components/DateStrip/DateStrip.tokens.scss +23 -0
  347. package/src/components/DateStrip/DateStrip.tsx +205 -0
  348. package/src/components/DateStrip/index.ts +2 -0
  349. package/src/components/DefinitionList/DefinitionList.module.scss +102 -0
  350. package/src/components/DefinitionList/DefinitionList.tokens.scss +29 -0
  351. package/src/components/DefinitionList/DefinitionList.tsx +198 -0
  352. package/src/components/DefinitionList/index.ts +9 -0
  353. package/src/components/Divider/Divider.module.scss +144 -0
  354. package/src/components/Divider/Divider.tokens.scss +21 -0
  355. package/src/components/Divider/Divider.tsx +103 -0
  356. package/src/components/Divider/index.ts +2 -0
  357. package/src/components/Dot/Dot.module.scss +40 -0
  358. package/src/components/Dot/Dot.tokens.scss +4 -0
  359. package/src/components/Dot/Dot.tsx +45 -0
  360. package/src/components/Dot/index.ts +2 -0
  361. package/src/components/Drawer/Body.tsx +23 -0
  362. package/src/components/Drawer/Close.tsx +35 -0
  363. package/src/components/Drawer/Content.tsx +93 -0
  364. package/src/components/Drawer/Drawer.module.scss +232 -0
  365. package/src/components/Drawer/Drawer.tokens.scss +38 -0
  366. package/src/components/Drawer/Drawer.tsx +23 -0
  367. package/src/components/Drawer/DrawerRoot.tsx +190 -0
  368. package/src/components/Drawer/Footer.tsx +24 -0
  369. package/src/components/Drawer/Header.tsx +64 -0
  370. package/src/components/Drawer/Overlay.tsx +82 -0
  371. package/src/components/Drawer/context.ts +44 -0
  372. package/src/components/Drawer/index.ts +12 -0
  373. package/src/components/Drawer/useDragToClose.ts +149 -0
  374. package/src/components/DropdownMenu/CheckboxItem.tsx +144 -0
  375. package/src/components/DropdownMenu/Content.tsx +419 -0
  376. package/src/components/DropdownMenu/DropdownMenu.module.scss +280 -0
  377. package/src/components/DropdownMenu/DropdownMenu.tokens.scss +88 -0
  378. package/src/components/DropdownMenu/DropdownMenu.tsx +43 -0
  379. package/src/components/DropdownMenu/Group.tsx +76 -0
  380. package/src/components/DropdownMenu/Item.tsx +148 -0
  381. package/src/components/DropdownMenu/ItemIndicator.tsx +30 -0
  382. package/src/components/DropdownMenu/Radio.tsx +178 -0
  383. package/src/components/DropdownMenu/Root.tsx +100 -0
  384. package/src/components/DropdownMenu/Sub.tsx +332 -0
  385. package/src/components/DropdownMenu/Trigger.tsx +76 -0
  386. package/src/components/DropdownMenu/context.ts +65 -0
  387. package/src/components/DropdownMenu/index.ts +20 -0
  388. package/src/components/EmojiPicker/EmojiPicker.module.scss +84 -0
  389. package/src/components/EmojiPicker/EmojiPicker.tokens.scss +24 -0
  390. package/src/components/EmojiPicker/EmojiPicker.tsx +341 -0
  391. package/src/components/EmojiPicker/emojiData.ts +245 -0
  392. package/src/components/EmojiPicker/index.ts +3 -0
  393. package/src/components/EmptyState/EmptyState.module.scss +102 -0
  394. package/src/components/EmptyState/EmptyState.tokens.scss +28 -0
  395. package/src/components/EmptyState/EmptyState.tsx +112 -0
  396. package/src/components/EmptyState/index.ts +7 -0
  397. package/src/components/EntityChip/EntityChip.module.scss +275 -0
  398. package/src/components/EntityChip/EntityChip.tokens.scss +66 -0
  399. package/src/components/EntityChip/EntityChip.tsx +649 -0
  400. package/src/components/EntityChip/index.ts +10 -0
  401. package/src/components/ErrorState/ErrorState.module.scss +105 -0
  402. package/src/components/ErrorState/ErrorState.tokens.scss +32 -0
  403. package/src/components/ErrorState/ErrorState.tsx +125 -0
  404. package/src/components/ErrorState/index.ts +8 -0
  405. package/src/components/Field/Field.module.scss +46 -0
  406. package/src/components/Field/Field.tsx +185 -0
  407. package/src/components/Field/index.ts +2 -0
  408. package/src/components/FileUpload/FileUpload.module.scss +187 -0
  409. package/src/components/FileUpload/FileUpload.tokens.scss +81 -0
  410. package/src/components/FileUpload/FileUpload.tsx +569 -0
  411. package/src/components/FileUpload/formatBytes.ts +34 -0
  412. package/src/components/FileUpload/iconForFile.ts +40 -0
  413. package/src/components/FileUpload/index.ts +2 -0
  414. package/src/components/FilterChip/FilterChip.module.scss +61 -0
  415. package/src/components/FilterChip/FilterChip.tokens.scss +25 -0
  416. package/src/components/FilterChip/FilterChip.tsx +208 -0
  417. package/src/components/FilterChip/index.ts +5 -0
  418. package/src/components/FlowCanvas/FlowCanvas.module.scss +329 -0
  419. package/src/components/FlowCanvas/FlowCanvas.tokens.scss +45 -0
  420. package/src/components/FlowCanvas/FlowCanvas.tsx +1867 -0
  421. package/src/components/FlowCanvas/FlowControls.tsx +46 -0
  422. package/src/components/FlowCanvas/FlowEdge.tsx +58 -0
  423. package/src/components/FlowCanvas/FlowNode.tsx +76 -0
  424. package/src/components/FlowCanvas/edgePath.ts +85 -0
  425. package/src/components/FlowCanvas/index.ts +4 -0
  426. package/src/components/FlowCanvas/layout.ts +148 -0
  427. package/src/components/FlowCanvas/spatialNav.ts +76 -0
  428. package/src/components/FlowCanvas/types.ts +59 -0
  429. package/src/components/FlowCanvas/useViewport.ts +122 -0
  430. package/src/components/FormRow/FormRow.module.scss +2 -0
  431. package/src/components/FormRow/FormRow.tsx +37 -0
  432. package/src/components/FormRow/index.ts +2 -0
  433. package/src/components/FormSection/FormSection.module.scss +24 -0
  434. package/src/components/FormSection/FormSection.tsx +46 -0
  435. package/src/components/FormSection/index.ts +2 -0
  436. package/src/components/Grid/Grid.module.scss +162 -0
  437. package/src/components/Grid/Grid.tokens.scss +13 -0
  438. package/src/components/Grid/Grid.tsx +226 -0
  439. package/src/components/Grid/GridItem.tsx +77 -0
  440. package/src/components/Grid/index.ts +11 -0
  441. package/src/components/Highlight/Highlight.module.scss +43 -0
  442. package/src/components/Highlight/Highlight.tokens.scss +35 -0
  443. package/src/components/Highlight/Highlight.tsx +164 -0
  444. package/src/components/Highlight/HighlightOverlay.tsx +100 -0
  445. package/src/components/Highlight/index.ts +2 -0
  446. package/src/components/HighlightedText/HighlightedText.module.scss +11 -0
  447. package/src/components/HighlightedText/HighlightedText.tokens.scss +9 -0
  448. package/src/components/HighlightedText/HighlightedText.tsx +50 -0
  449. package/src/components/HighlightedText/highlightRanges.ts +44 -0
  450. package/src/components/HighlightedText/index.ts +2 -0
  451. package/src/components/IconPicker/IconPicker.module.scss +175 -0
  452. package/src/components/IconPicker/IconPicker.tokens.scss +40 -0
  453. package/src/components/IconPicker/IconPicker.tsx +629 -0
  454. package/src/components/IconPicker/index.ts +9 -0
  455. package/src/components/IconTile/IconTile.module.scss +57 -0
  456. package/src/components/IconTile/IconTile.tokens.scss +16 -0
  457. package/src/components/IconTile/IconTile.tsx +91 -0
  458. package/src/components/IconTile/index.ts +2 -0
  459. package/src/components/Image/Image.module.scss +266 -0
  460. package/src/components/Image/Image.tokens.scss +55 -0
  461. package/src/components/Image/Image.tsx +342 -0
  462. package/src/components/Image/index.ts +2 -0
  463. package/src/components/ImageCrop/ImageCrop.module.scss +274 -0
  464. package/src/components/ImageCrop/ImageCrop.tokens.scss +33 -0
  465. package/src/components/ImageCrop/ImageCrop.tsx +542 -0
  466. package/src/components/ImageCrop/cropGeometry.ts +120 -0
  467. package/src/components/ImageCrop/extractCropBlob.ts +140 -0
  468. package/src/components/ImageCrop/index.ts +11 -0
  469. package/src/components/ImageCrop/useCropPreview.ts +161 -0
  470. package/src/components/Indent/Indent.module.scss +33 -0
  471. package/src/components/Indent/Indent.tokens.scss +10 -0
  472. package/src/components/Indent/Indent.tsx +46 -0
  473. package/src/components/Indent/index.ts +2 -0
  474. package/src/components/Input/Input.module.scss +99 -0
  475. package/src/components/Input/Input.tokens.scss +54 -0
  476. package/src/components/Input/Input.tsx +105 -0
  477. package/src/components/Input/Suggestions.tsx +260 -0
  478. package/src/components/Input/index.ts +2 -0
  479. package/src/components/Kanban/Kanban.module.scss +39 -0
  480. package/src/components/Kanban/Kanban.tokens.scss +15 -0
  481. package/src/components/Kanban/Kanban.tsx +951 -0
  482. package/src/components/Kanban/index.ts +7 -0
  483. package/src/components/Kbd/Kbd.module.scss +47 -0
  484. package/src/components/Kbd/Kbd.tokens.scss +26 -0
  485. package/src/components/Kbd/Kbd.tsx +73 -0
  486. package/src/components/Kbd/index.ts +2 -0
  487. package/src/components/Lightbox/Lightbox.module.scss +283 -0
  488. package/src/components/Lightbox/Lightbox.tokens.scss +36 -0
  489. package/src/components/Lightbox/Lightbox.tsx +506 -0
  490. package/src/components/Lightbox/index.ts +2 -0
  491. package/src/components/Link/Link.module.scss +78 -0
  492. package/src/components/Link/Link.tokens.scss +28 -0
  493. package/src/components/Link/Link.tsx +114 -0
  494. package/src/components/Link/index.ts +2 -0
  495. package/src/components/LinkCard/LinkCard.module.scss +92 -0
  496. package/src/components/LinkCard/LinkCard.tokens.scss +9 -0
  497. package/src/components/LinkCard/LinkCard.tsx +72 -0
  498. package/src/components/LinkCard/index.ts +2 -0
  499. package/src/components/LiquidEditor/AutocompleteMenu.tsx +133 -0
  500. package/src/components/LiquidEditor/HighlightLayer.tsx +53 -0
  501. package/src/components/LiquidEditor/InsertVariableMenu.tsx +81 -0
  502. package/src/components/LiquidEditor/LiquidEditor.module.scss +339 -0
  503. package/src/components/LiquidEditor/LiquidEditor.tokens.scss +81 -0
  504. package/src/components/LiquidEditor/LiquidEditor.tsx +412 -0
  505. package/src/components/LiquidEditor/PreviewPane.tsx +29 -0
  506. package/src/components/LiquidEditor/caretCoordinates.ts +97 -0
  507. package/src/components/LiquidEditor/index.ts +7 -0
  508. package/src/components/LiquidEditor/liquidFilters.ts +23 -0
  509. package/src/components/LiquidEditor/liquidTokenizer.ts +235 -0
  510. package/src/components/LiquidEditor/types.ts +101 -0
  511. package/src/components/LiquidEditor/useLiquidAutocomplete.ts +178 -0
  512. package/src/components/List/List.module.scss +105 -0
  513. package/src/components/List/List.tokens.scss +42 -0
  514. package/src/components/List/List.tsx +124 -0
  515. package/src/components/List/index.ts +9 -0
  516. package/src/components/LiveRegion/LiveRegion.module.scss +3 -0
  517. package/src/components/LiveRegion/LiveRegion.tsx +116 -0
  518. package/src/components/LiveRegion/index.ts +2 -0
  519. package/src/components/Logo/Logo.module.scss +139 -0
  520. package/src/components/Logo/Logo.tokens.scss +14 -0
  521. package/src/components/Logo/Logo.tsx +126 -0
  522. package/src/components/Logo/index.ts +2 -0
  523. package/src/components/Masonry/Masonry.module.scss +42 -0
  524. package/src/components/Masonry/Masonry.tokens.scss +8 -0
  525. package/src/components/Masonry/Masonry.tsx +136 -0
  526. package/src/components/Masonry/index.ts +2 -0
  527. package/src/components/Masonry/masonryUtils.ts +42 -0
  528. package/src/components/MediaTile/MediaTile.module.scss +183 -0
  529. package/src/components/MediaTile/MediaTile.tokens.scss +60 -0
  530. package/src/components/MediaTile/MediaTile.tsx +208 -0
  531. package/src/components/MediaTile/index.ts +8 -0
  532. package/src/components/Modal/Body.tsx +27 -0
  533. package/src/components/Modal/Close.tsx +45 -0
  534. package/src/components/Modal/Content.tsx +98 -0
  535. package/src/components/Modal/Footer.tsx +28 -0
  536. package/src/components/Modal/Header.tsx +51 -0
  537. package/src/components/Modal/Modal.module.scss +262 -0
  538. package/src/components/Modal/Modal.tokens.scss +50 -0
  539. package/src/components/Modal/Modal.tsx +23 -0
  540. package/src/components/Modal/ModalRoot.tsx +299 -0
  541. package/src/components/Modal/Overlay.tsx +101 -0
  542. package/src/components/Modal/context.ts +60 -0
  543. package/src/components/Modal/index.ts +11 -0
  544. package/src/components/MoneyInput/MoneyInput.module.scss +57 -0
  545. package/src/components/MoneyInput/MoneyInput.tsx +433 -0
  546. package/src/components/MoneyInput/index.ts +2 -0
  547. package/src/components/OptionsPicker/OptionsPicker.module.scss +216 -0
  548. package/src/components/OptionsPicker/OptionsPicker.tokens.scss +68 -0
  549. package/src/components/OptionsPicker/OptionsPicker.tsx +936 -0
  550. package/src/components/OptionsPicker/index.ts +9 -0
  551. package/src/components/OtpInput/OtpInput.module.scss +69 -0
  552. package/src/components/OtpInput/OtpInput.tokens.scss +45 -0
  553. package/src/components/OtpInput/OtpInput.tsx +368 -0
  554. package/src/components/OtpInput/index.ts +2 -0
  555. package/src/components/Page/Page.module.scss +30 -0
  556. package/src/components/Page/Page.tokens.scss +11 -0
  557. package/src/components/Page/Page.tsx +53 -0
  558. package/src/components/Page/index.ts +2 -0
  559. package/src/components/PageHeader/PageHeader.module.scss +197 -0
  560. package/src/components/PageHeader/PageHeader.tokens.scss +41 -0
  561. package/src/components/PageHeader/PageHeader.tsx +310 -0
  562. package/src/components/PageHeader/index.ts +20 -0
  563. package/src/components/Pagination/Pagination.module.scss +117 -0
  564. package/src/components/Pagination/Pagination.tokens.scss +54 -0
  565. package/src/components/Pagination/Pagination.tsx +165 -0
  566. package/src/components/Pagination/index.ts +4 -0
  567. package/src/components/Pagination/paginationRange.ts +72 -0
  568. package/src/components/PasswordInput/PasswordInput.module.scss +120 -0
  569. package/src/components/PasswordInput/PasswordInput.tokens.scss +44 -0
  570. package/src/components/PasswordInput/PasswordInput.tsx +210 -0
  571. package/src/components/PasswordInput/index.ts +2 -0
  572. package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.module.scss +80 -0
  573. package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tokens.scss +40 -0
  574. package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tsx +96 -0
  575. package/src/components/PasswordStrengthMeter/index.ts +2 -0
  576. package/src/components/PersonDisplay/PersonDisplay.module.scss +180 -0
  577. package/src/components/PersonDisplay/PersonDisplay.tokens.scss +35 -0
  578. package/src/components/PersonDisplay/PersonDisplay.tsx +420 -0
  579. package/src/components/PersonDisplay/index.ts +10 -0
  580. package/src/components/PhoneInput/PhoneInput.module.scss +23 -0
  581. package/src/components/PhoneInput/PhoneInput.tsx +271 -0
  582. package/src/components/PhoneInput/index.ts +4 -0
  583. package/src/components/PhoneInput/phone.ts +128 -0
  584. package/src/components/PillMenu/PillMenu.module.scss +117 -0
  585. package/src/components/PillMenu/PillMenu.tokens.scss +22 -0
  586. package/src/components/PillMenu/PillMenu.tsx +324 -0
  587. package/src/components/PillMenu/index.ts +2 -0
  588. package/src/components/Popover/Anchor.tsx +37 -0
  589. package/src/components/Popover/Close.tsx +45 -0
  590. package/src/components/Popover/Content.tsx +213 -0
  591. package/src/components/Popover/Heading.tsx +33 -0
  592. package/src/components/Popover/Popover.module.scss +177 -0
  593. package/src/components/Popover/Popover.tokens.scss +22 -0
  594. package/src/components/Popover/Popover.tsx +23 -0
  595. package/src/components/Popover/PopoverRoot.tsx +75 -0
  596. package/src/components/Popover/Trigger.tsx +86 -0
  597. package/src/components/Popover/context.ts +22 -0
  598. package/src/components/Popover/index.ts +7 -0
  599. package/src/components/Progress/Progress.module.scss +110 -0
  600. package/src/components/Progress/Progress.tokens.scss +44 -0
  601. package/src/components/Progress/Progress.tsx +129 -0
  602. package/src/components/Progress/index.ts +2 -0
  603. package/src/components/QrCode/QrCode.module.scss +97 -0
  604. package/src/components/QrCode/QrCode.tokens.scss +17 -0
  605. package/src/components/QrCode/QrCode.tsx +233 -0
  606. package/src/components/QrCode/index.ts +2 -0
  607. package/src/components/QrCode/qr.ts +161 -0
  608. package/src/components/Radio/Radio.module.scss +175 -0
  609. package/src/components/Radio/Radio.tokens.scss +59 -0
  610. package/src/components/Radio/Radio.tsx +127 -0
  611. package/src/components/Radio/RadioGroup.module.scss +42 -0
  612. package/src/components/Radio/RadioGroup.tsx +120 -0
  613. package/src/components/Radio/RadioGroupContext.tsx +30 -0
  614. package/src/components/Radio/index.ts +4 -0
  615. package/src/components/Rail/Rail.module.scss +510 -0
  616. package/src/components/Rail/Rail.tokens.scss +92 -0
  617. package/src/components/Rail/Rail.tsx +287 -0
  618. package/src/components/Rail/RailCollapseToggle.tsx +57 -0
  619. package/src/components/Rail/RailFooter.tsx +17 -0
  620. package/src/components/Rail/RailGroup.tsx +728 -0
  621. package/src/components/Rail/RailGroupContext.ts +9 -0
  622. package/src/components/Rail/RailHeader.tsx +23 -0
  623. package/src/components/Rail/RailItem.tsx +119 -0
  624. package/src/components/Rail/RailSection.tsx +39 -0
  625. package/src/components/Rail/RailSpacer.tsx +19 -0
  626. package/src/components/Rail/index.ts +9 -0
  627. package/src/components/RelativeDateInput/RelativeDateInput.module.scss +15 -0
  628. package/src/components/RelativeDateInput/RelativeDateInput.tokens.scss +6 -0
  629. package/src/components/RelativeDateInput/RelativeDateInput.tsx +474 -0
  630. package/src/components/RelativeDateInput/index.ts +10 -0
  631. package/src/components/RelativeDateInput/relativeDate.ts +127 -0
  632. package/src/components/RichText/RichText.module.scss +5 -0
  633. package/src/components/RichText/RichText.tsx +70 -0
  634. package/src/components/RichText/RichTextAttachment.module.scss +82 -0
  635. package/src/components/RichText/RichTextAttachment.tsx +122 -0
  636. package/src/components/RichText/_prose.scss +79 -0
  637. package/src/components/RichText/attachmentIcon.tsx +24 -0
  638. package/src/components/RichText/engine/attachment.ts +154 -0
  639. package/src/components/RichText/engine/autolink.ts +64 -0
  640. package/src/components/RichText/engine/blockUnit.ts +174 -0
  641. package/src/components/RichText/engine/colorMarks.ts +85 -0
  642. package/src/components/RichText/engine/escape.ts +11 -0
  643. package/src/components/RichText/engine/fromHtml.ts +353 -0
  644. package/src/components/RichText/engine/fromMarkdown.ts +20 -0
  645. package/src/components/RichText/engine/inlines.ts +82 -0
  646. package/src/components/RichText/engine/listDepths.ts +32 -0
  647. package/src/components/RichText/engine/marks.ts +80 -0
  648. package/src/components/RichText/engine/mdToHtml.ts +178 -0
  649. package/src/components/RichText/engine/model.ts +157 -0
  650. package/src/components/RichText/engine/position.ts +118 -0
  651. package/src/components/RichText/engine/renderDoc.tsx +395 -0
  652. package/src/components/RichText/engine/renderLink.ts +15 -0
  653. package/src/components/RichText/engine/renderMention.ts +16 -0
  654. package/src/components/RichText/engine/safeHref.ts +22 -0
  655. package/src/components/RichText/engine/toHtml.ts +154 -0
  656. package/src/components/RichText/engine/toMarkdown.ts +97 -0
  657. package/src/components/RichText/engine/transforms.ts +434 -0
  658. package/src/components/RichText/imageMaxHeightStyle.ts +10 -0
  659. package/src/components/RichText/index.ts +31 -0
  660. package/src/components/RichTextEditor/RichTextAttachmentConfig.tsx +264 -0
  661. package/src/components/RichTextEditor/RichTextBlockControls.tsx +365 -0
  662. package/src/components/RichTextEditor/RichTextBlockMenu.tsx +162 -0
  663. package/src/components/RichTextEditor/RichTextColorMenu.tsx +115 -0
  664. package/src/components/RichTextEditor/RichTextEditor.module.scss +298 -0
  665. package/src/components/RichTextEditor/RichTextEditor.tsx +1910 -0
  666. package/src/components/RichTextEditor/RichTextImageResizer.tsx +131 -0
  667. package/src/components/RichTextEditor/RichTextLinkEditor.tsx +151 -0
  668. package/src/components/RichTextEditor/RichTextMentionMenu.tsx +99 -0
  669. package/src/components/RichTextEditor/RichTextToolbar.tsx +379 -0
  670. package/src/components/RichTextEditor/autolinkInput.ts +65 -0
  671. package/src/components/RichTextEditor/blockDrop.ts +9 -0
  672. package/src/components/RichTextEditor/blockReflow.ts +62 -0
  673. package/src/components/RichTextEditor/commands.ts +300 -0
  674. package/src/components/RichTextEditor/history.ts +93 -0
  675. package/src/components/RichTextEditor/icons.tsx +152 -0
  676. package/src/components/RichTextEditor/imageSize.ts +70 -0
  677. package/src/components/RichTextEditor/index.ts +5 -0
  678. package/src/components/RichTextEditor/input.ts +209 -0
  679. package/src/components/RichTextEditor/inputRules.ts +71 -0
  680. package/src/components/RichTextEditor/links.ts +103 -0
  681. package/src/components/RichTextEditor/mentionContext.ts +37 -0
  682. package/src/components/RichTextEditor/mentions.ts +28 -0
  683. package/src/components/RichTextEditor/preventSelectionLoss.ts +15 -0
  684. package/src/components/RichTextEditor/selection.ts +415 -0
  685. package/src/components/RichTextEditor/shortcuts.ts +44 -0
  686. package/src/components/RichTextEditor/useAnchoredFloating.ts +50 -0
  687. package/src/components/RichTextEditor/useAttachmentConfig.ts +134 -0
  688. package/src/components/RichTextEditor/useDismissOnOutsidePointerDown.ts +26 -0
  689. package/src/components/RichTextEditor/useLinkEditor.ts +107 -0
  690. package/src/components/RichTextEditor/useMention.ts +226 -0
  691. package/src/components/RichTextEditor/useOverlayRect.ts +73 -0
  692. package/src/components/RichTextEditor/useUpload.ts +246 -0
  693. package/src/components/Screen/Screen.module.scss +46 -0
  694. package/src/components/Screen/Screen.tokens.scss +20 -0
  695. package/src/components/Screen/Screen.tsx +97 -0
  696. package/src/components/Screen/index.ts +2 -0
  697. package/src/components/ScrollArea/ScrollArea.module.scss +39 -0
  698. package/src/components/ScrollArea/ScrollArea.tokens.scss +15 -0
  699. package/src/components/ScrollArea/ScrollArea.tsx +154 -0
  700. package/src/components/ScrollArea/index.ts +2 -0
  701. package/src/components/Select/Chip.tsx +45 -0
  702. package/src/components/Select/Empty.tsx +39 -0
  703. package/src/components/Select/Error.tsx +51 -0
  704. package/src/components/Select/HiddenInputs.tsx +44 -0
  705. package/src/components/Select/Listbox.tsx +557 -0
  706. package/src/components/Select/Loading.tsx +30 -0
  707. package/src/components/Select/Select.module.scss +512 -0
  708. package/src/components/Select/Select.tokens.scss +140 -0
  709. package/src/components/Select/Select.tsx +685 -0
  710. package/src/components/Select/Trigger.tsx +952 -0
  711. package/src/components/Select/context.ts +101 -0
  712. package/src/components/Select/emptyStateText.ts +19 -0
  713. package/src/components/Select/index.ts +9 -0
  714. package/src/components/Select/useSelectState.ts +157 -0
  715. package/src/components/Select/utils-types.ts +7 -0
  716. package/src/components/Select/utils.ts +122 -0
  717. package/src/components/SettingRow/SettingRow.module.scss +166 -0
  718. package/src/components/SettingRow/SettingRow.tokens.scss +37 -0
  719. package/src/components/SettingRow/SettingRow.tsx +242 -0
  720. package/src/components/SettingRow/index.ts +7 -0
  721. package/src/components/Skeleton/Skeleton.module.scss +55 -0
  722. package/src/components/Skeleton/Skeleton.tokens.scss +17 -0
  723. package/src/components/Skeleton/Skeleton.tsx +131 -0
  724. package/src/components/Skeleton/index.ts +4 -0
  725. package/src/components/Skeleton/useSkeletonVisibility.ts +95 -0
  726. package/src/components/Slider/Slider.module.scss +293 -0
  727. package/src/components/Slider/Slider.tokens.scss +98 -0
  728. package/src/components/Slider/Slider.tsx +624 -0
  729. package/src/components/Slider/index.ts +9 -0
  730. package/src/components/SlotGrid/SlotGrid.module.scss +61 -0
  731. package/src/components/SlotGrid/SlotGrid.tokens.scss +21 -0
  732. package/src/components/SlotGrid/SlotGrid.tsx +111 -0
  733. package/src/components/SlotGrid/index.ts +2 -0
  734. package/src/components/SocialButton/SocialButton.module.scss +4 -0
  735. package/src/components/SocialButton/SocialButton.tsx +40 -0
  736. package/src/components/SocialButton/index.ts +2 -0
  737. package/src/components/Sortable/Sortable.module.scss +177 -0
  738. package/src/components/Sortable/Sortable.tokens.scss +27 -0
  739. package/src/components/Sortable/Sortable.tsx +572 -0
  740. package/src/components/Sortable/containerAwareCollision.ts +125 -0
  741. package/src/components/Sortable/index.ts +13 -0
  742. package/src/components/SortableGroup/SortableGroup.module.scss +23 -0
  743. package/src/components/SortableGroup/SortableGroup.tsx +315 -0
  744. package/src/components/SortableGroup/index.ts +4 -0
  745. package/src/components/SortableGroup/moveSortableItem.ts +39 -0
  746. package/src/components/Sparkline/Sparkline.module.scss +28 -0
  747. package/src/components/Sparkline/Sparkline.tokens.scss +7 -0
  748. package/src/components/Sparkline/Sparkline.tsx +133 -0
  749. package/src/components/Sparkline/index.ts +2 -0
  750. package/src/components/Sparkline/sparklineModel.ts +119 -0
  751. package/src/components/Split/Split.module.scss +158 -0
  752. package/src/components/Split/Split.tokens.scss +10 -0
  753. package/src/components/Split/Split.tsx +231 -0
  754. package/src/components/Split/index.ts +2 -0
  755. package/src/components/Stack/Stack.module.scss +67 -0
  756. package/src/components/Stack/Stack.tokens.scss +11 -0
  757. package/src/components/Stack/Stack.tsx +100 -0
  758. package/src/components/Stack/index.ts +2 -0
  759. package/src/components/StagePath/StagePath.module.scss +255 -0
  760. package/src/components/StagePath/StagePath.tokens.scss +43 -0
  761. package/src/components/StagePath/StagePath.tsx +176 -0
  762. package/src/components/StagePath/index.ts +2 -0
  763. package/src/components/StatGroup/StatGroup.module.scss +6 -0
  764. package/src/components/StatGroup/StatGroup.tsx +70 -0
  765. package/src/components/StatGroup/StatGroupContext.ts +10 -0
  766. package/src/components/StatGroup/StatTile.module.scss +99 -0
  767. package/src/components/StatGroup/StatTile.tokens.scss +35 -0
  768. package/src/components/StatGroup/StatTile.tsx +143 -0
  769. package/src/components/StatGroup/index.ts +4 -0
  770. package/src/components/Sticky/Sticky.module.scss +98 -0
  771. package/src/components/Sticky/Sticky.tokens.scss +17 -0
  772. package/src/components/Sticky/Sticky.tsx +103 -0
  773. package/src/components/Sticky/index.ts +2 -0
  774. package/src/components/Switch/Switch.module.scss +182 -0
  775. package/src/components/Switch/Switch.tokens.scss +59 -0
  776. package/src/components/Switch/Switch.tsx +214 -0
  777. package/src/components/Switch/index.ts +2 -0
  778. package/src/components/Table/Table.module.scss +308 -0
  779. package/src/components/Table/Table.tokens.scss +79 -0
  780. package/src/components/Table/Table.tsx +381 -0
  781. package/src/components/Table/index.ts +15 -0
  782. package/src/components/TableOfContents/TableOfContents.module.scss +83 -0
  783. package/src/components/TableOfContents/TableOfContents.tokens.scss +26 -0
  784. package/src/components/TableOfContents/TableOfContents.tsx +192 -0
  785. package/src/components/TableOfContents/activeSection.ts +18 -0
  786. package/src/components/TableOfContents/index.ts +2 -0
  787. package/src/components/Tabs/Tabs.module.scss +359 -0
  788. package/src/components/Tabs/Tabs.tokens.scss +50 -0
  789. package/src/components/Tabs/Tabs.tsx +538 -0
  790. package/src/components/Tabs/index.ts +2 -0
  791. package/src/components/Text/Text.module.scss +115 -0
  792. package/src/components/Text/Text.tokens.scss +55 -0
  793. package/src/components/Text/Text.tsx +197 -0
  794. package/src/components/Text/index.ts +2 -0
  795. package/src/components/Textarea/Textarea.module.scss +94 -0
  796. package/src/components/Textarea/Textarea.tokens.scss +48 -0
  797. package/src/components/Textarea/Textarea.tsx +246 -0
  798. package/src/components/Textarea/index.ts +2 -0
  799. package/src/components/Thread/Thread.module.scss +161 -0
  800. package/src/components/Thread/Thread.tokens.scss +32 -0
  801. package/src/components/Thread/Thread.tsx +176 -0
  802. package/src/components/Thread/index.ts +2 -0
  803. package/src/components/TimeField/TimeField.module.scss +232 -0
  804. package/src/components/TimeField/TimeField.tsx +793 -0
  805. package/src/components/TimeField/index.ts +2 -0
  806. package/src/components/Timeline/Timeline.module.scss +58 -0
  807. package/src/components/Timeline/Timeline.tokens.scss +13 -0
  808. package/src/components/Timeline/Timeline.tsx +53 -0
  809. package/src/components/Timeline/index.ts +2 -0
  810. package/src/components/Title/Title.module.scss +84 -0
  811. package/src/components/Title/Title.tokens.scss +37 -0
  812. package/src/components/Title/Title.tsx +150 -0
  813. package/src/components/Title/index.ts +2 -0
  814. package/src/components/Toast/Toast.module.scss +299 -0
  815. package/src/components/Toast/Toast.tokens.scss +65 -0
  816. package/src/components/Toast/Toast.tsx +122 -0
  817. package/src/components/Toast/ToastViewport.tsx +166 -0
  818. package/src/components/Toast/api.ts +175 -0
  819. package/src/components/Toast/index.ts +5 -0
  820. package/src/components/Toast/store.ts +133 -0
  821. package/src/components/Toast/useToastTimer.ts +94 -0
  822. package/src/components/Tooltip/Tooltip.module.scss +99 -0
  823. package/src/components/Tooltip/Tooltip.tokens.scss +23 -0
  824. package/src/components/Tooltip/Tooltip.tsx +341 -0
  825. package/src/components/Tooltip/index.ts +2 -0
  826. package/src/components/TopBar/TopBar.module.scss +235 -0
  827. package/src/components/TopBar/TopBar.tokens.scss +79 -0
  828. package/src/components/TopBar/TopBar.tsx +87 -0
  829. package/src/components/TopBar/TopBarEnd.tsx +20 -0
  830. package/src/components/TopBar/TopBarIconButton.tsx +86 -0
  831. package/src/components/TopBar/TopBarSearch.tsx +319 -0
  832. package/src/components/TopBar/TopBarSearchPanel.tsx +268 -0
  833. package/src/components/TopBar/TopBarStart.tsx +20 -0
  834. package/src/components/TopBar/index.ts +11 -0
  835. package/src/components/Tour/Spotlight.tsx +121 -0
  836. package/src/components/Tour/Tour.module.scss +210 -0
  837. package/src/components/Tour/Tour.tokens.scss +58 -0
  838. package/src/components/Tour/Tour.tsx +617 -0
  839. package/src/components/Tour/index.ts +2 -0
  840. package/src/components/Tour/useTourTarget.ts +115 -0
  841. package/src/components/TreeView/TreeView.module.scss +268 -0
  842. package/src/components/TreeView/TreeView.tokens.scss +36 -0
  843. package/src/components/TreeView/TreeView.tsx +536 -0
  844. package/src/components/TreeView/index.ts +3 -0
  845. package/src/components/TreeView/treeModel.ts +224 -0
  846. package/src/components/VisuallyHidden/VisuallyHidden.module.scss +7 -0
  847. package/src/components/VisuallyHidden/VisuallyHidden.tsx +29 -0
  848. package/src/components/VisuallyHidden/index.ts +2 -0
  849. package/src/components/WidgetPreview/WidgetPreview.module.scss +11 -0
  850. package/src/components/WidgetPreview/WidgetPreview.tokens.scss +26 -0
  851. package/src/components/WidgetPreview/WidgetPreview.tsx +36 -0
  852. package/src/components/WidgetPreview/WidgetShape.module.scss +140 -0
  853. package/src/components/WidgetPreview/WidgetShape.tsx +159 -0
  854. package/src/components/WidgetPreview/index.ts +2 -0
  855. package/src/components/_internal/Trend.tsx +27 -0
  856. package/src/components/_internal/choiceTile.scss +74 -0
  857. package/src/components/_internal/collapse.scss +10 -0
  858. package/src/components/_internal/collapse.ts +58 -0
  859. package/src/components/_internal/currency.ts +257 -0
  860. package/src/components/_internal/dragAnnouncements.ts +200 -0
  861. package/src/components/_internal/fieldWiring.ts +225 -0
  862. package/src/components/_internal/gridSpan.ts +54 -0
  863. package/src/components/_internal/isoDay.ts +35 -0
  864. package/src/components/_internal/letterKey.ts +26 -0
  865. package/src/components/_internal/overlay/focusRestore.ts +21 -0
  866. package/src/components/_internal/overlay/index.ts +12 -0
  867. package/src/components/_internal/overlay/tourHold.ts +23 -0
  868. package/src/components/_internal/overlay/useFocusTrap.ts +120 -0
  869. package/src/components/_internal/overlay/useInOverlay.ts +81 -0
  870. package/src/components/_internal/overlay/useOverlayStack.ts +232 -0
  871. package/src/components/_internal/overlay/useScrollLock.ts +112 -0
  872. package/src/components/_internal/refs.ts +48 -0
  873. package/src/components/_internal/statusColor.ts +26 -0
  874. package/src/components/_internal/timeUtils.ts +23 -0
  875. package/src/components/_internal/useAsyncOptions.ts +145 -0
  876. package/src/components/_internal/useClippedTooltip.ts +50 -0
  877. package/src/components/_internal/useControllableState.ts +50 -0
  878. package/src/components.manifest.json +1141 -0
  879. package/src/hooks/useBelowBreakpoint.ts +58 -0
  880. package/src/i18n/I18nProvider.tsx +52 -0
  881. package/src/i18n/LocaleProvider.tsx +17 -0
  882. package/src/i18n/en.ts +648 -0
  883. package/src/i18n/format.ts +71 -0
  884. package/src/i18n/index.ts +13 -0
  885. package/src/i18n/messages.ts +1275 -0
  886. package/src/i18n/ru.ts +677 -0
  887. package/src/i18n/useLocale.ts +19 -0
  888. package/src/i18n/useTranslation.ts +58 -0
  889. package/src/index.ts +913 -0
  890. package/src/palette/index.ts +2 -0
  891. package/src/palette/palette.ts +108 -0
  892. package/src/styles/dark.scss +4 -0
  893. package/src/styles/global.scss +7 -0
  894. package/src/styles/mixins.scss +143 -0
  895. package/src/styles/reset.scss +78 -0
  896. package/src/styles/tokens.scss +18 -0
  897. package/src/styles/typography.scss +44 -0
@@ -0,0 +1,395 @@
1
+ // renderDoc.tsx — pure model → React. Read-only; used by <RichText>. The model
2
+ // is flat; this reconstructs list nesting from `depth` at render time.
3
+ import { Fragment, type ReactElement, type ReactNode } from 'react';
4
+ import type { RichDoc, Block, Inline, Mark, MarkType } from './model';
5
+ import { runsText, runsLength } from './inlines';
6
+ import { safeHref } from './safeHref';
7
+ import { textColorVar, bgColorVar } from './colorMarks';
8
+ import { isListItem, effectiveDepths } from './listDepths';
9
+ import { MARK_ORDER, marksSignature } from './marks';
10
+ import type { RenderLink } from './renderLink';
11
+ import type { RenderMention } from './renderMention';
12
+ import { RichTextAttachment } from '../RichTextAttachment';
13
+
14
+ export interface RenderDocOptions {
15
+ /** Editable surface: add `data-block-id` anchors + render empty blocks with a `<br>`. */
16
+ editable?: boolean;
17
+ /**
18
+ * Replace how a link renders (e.g. a task/member chip). In the read-only viewer
19
+ * the returned node substitutes the `<a>` directly; on an editable surface a
20
+ * substituted node is wrapped in an atomic, non-editable `[data-rich-link]`
21
+ * widget so the caret steps over it as a single unit. Return the supplied
22
+ * default node to keep the standard `<a>`.
23
+ */
24
+ renderLink?: RenderLink;
25
+ /**
26
+ * Replace how a `mention` mark renders (e.g. an interactive member chip /
27
+ * popover trigger). In the read-only viewer the returned node substitutes the
28
+ * default mention span directly; on an editable surface a substituted node is
29
+ * wrapped in an atomic, non-editable `[data-rich-mention]` widget so the caret
30
+ * steps over it as a single unit. Return the supplied default node to keep the
31
+ * standard non-interactive mention span. Composes with `renderLink`.
32
+ */
33
+ renderMention?: RenderMention;
34
+ }
35
+
36
+ // Resolved options threaded through the render call chain (never module state).
37
+ interface ResolvedOptions {
38
+ editable: boolean;
39
+ renderLink?: RenderLink;
40
+ renderMention?: RenderMention;
41
+ }
42
+
43
+ // Per-block element cache for CONTEXT-INDEPENDENT blocks only (paragraph, heading,
44
+ // blockquote, code_block, attachment). The model is immutable: a block keeps its
45
+ // reference across edits unless it changed, so an element built purely from
46
+ // (block + options) can be cached by block reference — reusing the same element
47
+ // lets React bail out of reconciling unchanged blocks (referential equality).
48
+ //
49
+ // Keyed in a WeakMap on the immutable Block object, so entries are GC'd with their
50
+ // block — no leak, no manual invalidation. The render options are part of the
51
+ // stored entry: a change to `editable`/`renderLink`/`renderMention` correctly
52
+ // misses the cache and rebuilds.
53
+ //
54
+ // LIST items (bullet_item/ordered_item) are NEVER cached here: their nested
55
+ // <ul>/<ol>/<li> shape depends on NEIGHBORS (grouping + relative depth), so a
56
+ // sibling change can alter a list item's output while its own reference is
57
+ // unchanged. They render fresh every time via collectList/renderListTree.
58
+ type BlockCacheEntry = {
59
+ editable: boolean;
60
+ renderLink?: RenderLink;
61
+ renderMention?: RenderMention;
62
+ el: ReactElement;
63
+ };
64
+ const blockCache = new WeakMap<Block, BlockCacheEntry>();
65
+
66
+ function cachedBlockEl(
67
+ block: Block,
68
+ editable: boolean,
69
+ renderLink: RenderLink | undefined,
70
+ renderMention: RenderMention | undefined,
71
+ build: () => ReactElement,
72
+ ): ReactElement {
73
+ const hit = blockCache.get(block);
74
+ if (
75
+ hit &&
76
+ hit.editable === editable &&
77
+ hit.renderLink === renderLink &&
78
+ hit.renderMention === renderMention
79
+ ) {
80
+ return hit.el;
81
+ }
82
+ const el = build();
83
+ blockCache.set(block, { editable, renderLink, renderMention, el });
84
+ return el;
85
+ }
86
+
87
+ function wrapMark(type: MarkType, mark: Mark, child: ReactNode): ReactNode {
88
+ switch (type) {
89
+ case 'bold':
90
+ return <strong>{child}</strong>;
91
+ case 'italic':
92
+ return <em>{child}</em>;
93
+ case 'underline':
94
+ return <u>{child}</u>;
95
+ case 'strike':
96
+ return <s>{child}</s>;
97
+ case 'code':
98
+ return <code>{child}</code>;
99
+ case 'textColor': {
100
+ // Resolve the palette key to a token-backed var. An unknown key yields no
101
+ // wrapper (never emit an empty `style`).
102
+ const value = mark.type === 'textColor' ? textColorVar(mark.color) : undefined;
103
+ return value ? <span style={{ color: value }}>{child}</span> : child;
104
+ }
105
+ case 'bgColor': {
106
+ const value = mark.type === 'bgColor' ? bgColorVar(mark.color) : undefined;
107
+ return value ? <span style={{ backgroundColor: value }}>{child}</span> : child;
108
+ }
109
+ case 'link': {
110
+ // The `renderLink` substitution is handled in `renderInlines` (which coalesces
111
+ // contiguous same-href runs into one logical link); here we only emit the
112
+ // default <a> for the unsubstituted path.
113
+ const href = mark.type === 'link' ? safeHref(mark.href) : undefined;
114
+ return (
115
+ <a href={href} rel="noopener noreferrer">
116
+ {child}
117
+ </a>
118
+ );
119
+ }
120
+ case 'mention':
121
+ return (
122
+ <span
123
+ data-mention
124
+ data-mention-id={mark.type === 'mention' ? mark.id : undefined}
125
+ data-mention-label={mark.type === 'mention' ? mark.label : undefined}
126
+ >
127
+ {child}
128
+ </span>
129
+ );
130
+ default:
131
+ return child;
132
+ }
133
+ }
134
+
135
+ function renderRun(run: Inline, key: string): ReactNode {
136
+ const present = MARK_ORDER.filter((t) => run.marks.some((m) => m.type === t));
137
+ let node: ReactNode = run.text;
138
+ // Wrap innermost-first so present[0] (link) ends up outermost.
139
+ for (let i = present.length - 1; i >= 0; i -= 1) {
140
+ const type = present[i];
141
+ const mark = run.marks.find((m) => m.type === type)!;
142
+ node = wrapMark(type, mark, node);
143
+ }
144
+ return <Fragment key={key}>{node}</Fragment>;
145
+ }
146
+
147
+ function renderInlines(inlines: Inline[], opts: ResolvedOptions): ReactNode {
148
+ const out: ReactNode[] = [];
149
+ let i = 0;
150
+ while (i < inlines.length) {
151
+ const run = inlines[i];
152
+ const mm = run.marks.find((m) => m.type === 'mention');
153
+ const mention = mm && mm.type === 'mention' ? { id: mm.id, label: mm.label } : null;
154
+ if (opts.renderMention && mention) {
155
+ // Coalesce contiguous runs that share this exact mention (same id AND label)
156
+ // into ONE logical mention, so a mention split across runs (e.g. internal
157
+ // formatting, HTML import) resolves to a single chip — not one per run.
158
+ let j = i;
159
+ let text = '';
160
+ while (j < inlines.length) {
161
+ const m = inlines[j].marks.find((mk) => mk.type === 'mention');
162
+ if (!m || m.type !== 'mention' || m.id !== mention.id || m.label !== mention.label) break;
163
+ text += inlines[j].text;
164
+ j += 1;
165
+ }
166
+ const fallback = (
167
+ <span data-mention data-mention-id={mention.id} data-mention-label={mention.label}>
168
+ {text}
169
+ </span>
170
+ );
171
+ const custom = opts.renderMention(mention, fallback);
172
+ if (custom !== fallback) {
173
+ // Substituted: one node for the whole span. In the editor it's an atomic,
174
+ // non-editable widget tagged with the span's MODEL length (`data-len`).
175
+ const mkey = `m${i}:${mention.id}:${mention.label}`;
176
+ out.push(
177
+ opts.editable ? (
178
+ <span key={mkey} data-rich-mention data-len={text.length} contentEditable={false}>
179
+ {custom}
180
+ </span>
181
+ ) : (
182
+ <Fragment key={mkey}>{custom}</Fragment>
183
+ ),
184
+ );
185
+ i = j;
186
+ continue;
187
+ }
188
+ // Consumer declined → fall through to the link/default handling below.
189
+ }
190
+ const lm = run.marks.find((m) => m.type === 'link');
191
+ const linkHref = lm && lm.type === 'link' ? lm.href : null;
192
+ const safe = opts.renderLink && linkHref != null ? safeHref(linkHref) : undefined;
193
+ if (safe) {
194
+ // Coalesce contiguous runs that share this exact link href into ONE logical
195
+ // link, so a link split across runs (e.g. internal formatting, HTML import)
196
+ // resolves to a single chip — not one chip per run.
197
+ let j = i;
198
+ let text = '';
199
+ while (j < inlines.length) {
200
+ const m = inlines[j].marks.find((mm) => mm.type === 'link');
201
+ if (!m || m.type !== 'link' || m.href !== linkHref) break;
202
+ text += inlines[j].text;
203
+ j += 1;
204
+ }
205
+ const fallback = (
206
+ <a href={safe} rel="noopener noreferrer">
207
+ {text}
208
+ </a>
209
+ );
210
+ const custom = opts.renderLink!({ href: safe, text }, fallback);
211
+ if (custom !== fallback) {
212
+ // Substituted: one node for the whole span. In the editor it's an atomic,
213
+ // non-editable widget tagged with the span's MODEL length (`data-len`).
214
+ const lkey = `l${i}:${linkHref}`;
215
+ out.push(
216
+ opts.editable ? (
217
+ <span key={lkey} data-rich-link data-len={text.length} contentEditable={false}>
218
+ {custom}
219
+ </span>
220
+ ) : (
221
+ <Fragment key={lkey}>{custom}</Fragment>
222
+ ),
223
+ );
224
+ i = j;
225
+ continue;
226
+ }
227
+ // Consumer declined → fall through to normal per-run rendering (default <a>).
228
+ }
229
+ // Key folds in the run's mark signature (not just its index): when a run's
230
+ // formatting changes, React replaces its subtree cleanly instead of re-wrapping
231
+ // a live contentEditable text node in place (which orphaned text / reset colors).
232
+ out.push(renderRun(run, `${i}:${marksSignature(run.marks)}`));
233
+ i += 1;
234
+ }
235
+ return out;
236
+ }
237
+
238
+ function blockContent(block: Block, opts: ResolvedOptions): ReactNode {
239
+ if (opts.editable && runsLength(block.inlines) === 0) return <br />;
240
+ return renderInlines(block.inlines, opts);
241
+ }
242
+
243
+ // Build the element for a single NON-LIST block. Pure in (block, opts): no
244
+ // position/index/depth/neighbor input (the effective depths computed in renderDoc
245
+ // are consumed only by the list path). Every branch returns a single top-level
246
+ // element carrying `key={block.id}` — so caching + reusing the reference preserves
247
+ // the key and lets React skip reconciling the block.
248
+ function buildBlock(block: Block, opts: ResolvedOptions): ReactElement {
249
+ const anchor = opts.editable ? { 'data-block-id': block.id } : undefined;
250
+ switch (block.type) {
251
+ case 'heading': {
252
+ const Tag = `h${block.level ?? 1}` as 'h1' | 'h2' | 'h3';
253
+ return (
254
+ <Tag key={block.id} {...anchor}>
255
+ {blockContent(block, opts)}
256
+ </Tag>
257
+ );
258
+ }
259
+ case 'blockquote':
260
+ return (
261
+ <blockquote key={block.id} {...anchor}>
262
+ {blockContent(block, opts)}
263
+ </blockquote>
264
+ );
265
+ case 'code_block':
266
+ return (
267
+ <pre key={block.id} {...anchor}>
268
+ <code>
269
+ {opts.editable && runsLength(block.inlines) === 0 ? <br /> : runsText(block.inlines)}
270
+ </code>
271
+ </pre>
272
+ );
273
+ case 'attachment':
274
+ return (
275
+ <figure
276
+ key={block.id}
277
+ {...anchor}
278
+ contentEditable={false}
279
+ data-attachment=""
280
+ data-align={block.align || undefined}
281
+ >
282
+ <RichTextAttachment block={block} editable={opts.editable} />
283
+ </figure>
284
+ );
285
+ case 'paragraph':
286
+ default:
287
+ return (
288
+ <p key={block.id} {...anchor}>
289
+ {blockContent(block, opts)}
290
+ </p>
291
+ );
292
+ }
293
+ }
294
+
295
+ // Cache wrapper for a non-list block: returns the cached element when the block
296
+ // reference AND the relevant options are unchanged, otherwise builds + stores it.
297
+ function renderBlock(block: Block, opts: ResolvedOptions): ReactElement {
298
+ return cachedBlockEl(block, opts.editable, opts.renderLink, opts.renderMention, () =>
299
+ buildBlock(block, opts),
300
+ );
301
+ }
302
+
303
+ interface ListItemNode {
304
+ key: string;
305
+ blockId: string;
306
+ content: ReactNode;
307
+ child: ReactNode | null;
308
+ }
309
+
310
+ // Collect a list starting at `start`, at its base (effective) depth; items one
311
+ // level deeper recurse into a child list attached to the preceding item. Because
312
+ // `eff` is gap-free, a deeper run is always exactly base+1, so every item lands
313
+ // in exactly one list — no item is overwritten. Returns the items + next index.
314
+ function collectList(
315
+ blocks: Block[],
316
+ start: number,
317
+ eff: number[],
318
+ opts: ResolvedOptions,
319
+ ): { tag: 'ul' | 'ol'; items: ListItemNode[]; next: number } {
320
+ const baseDepth = eff[start];
321
+ const tag = blocks[start].type === 'ordered_item' ? 'ol' : 'ul';
322
+ const items: ListItemNode[] = [];
323
+ let i = start;
324
+ while (i < blocks.length && isListItem(blocks[i])) {
325
+ const d = eff[i];
326
+ if (d < baseDepth) break;
327
+ if (d > baseDepth) {
328
+ const sub = collectList(blocks, i, eff, opts);
329
+ if (items.length > 0)
330
+ items[items.length - 1].child = renderListTree(sub.tag, sub.items, opts);
331
+ i = sub.next;
332
+ continue;
333
+ }
334
+ items.push({
335
+ key: blocks[i].id,
336
+ blockId: blocks[i].id,
337
+ content: blockContent(blocks[i], opts),
338
+ child: null,
339
+ });
340
+ i += 1;
341
+ }
342
+ return { tag, items, next: i };
343
+ }
344
+
345
+ function renderListTree(tag: 'ul' | 'ol', items: ListItemNode[], opts: ResolvedOptions): ReactNode {
346
+ const ListTag = tag;
347
+ return (
348
+ <ListTag>
349
+ {items.map((it) => (
350
+ <li key={it.key} {...(opts.editable ? { 'data-block-id': it.blockId } : {})}>
351
+ {it.content}
352
+ {it.child}
353
+ </li>
354
+ ))}
355
+ </ListTag>
356
+ );
357
+ }
358
+
359
+ /**
360
+ * Render a `RichDoc` to React nodes.
361
+ *
362
+ * Blocks map to semantic elements (`<p>`, `<h1|h2|h3>`, `<blockquote>`,
363
+ * `<pre><code>`). Consecutive list-item blocks are grouped back into `<ul>`/`<ol>`
364
+ * trees, with nesting reconstructed from each item's `depth` (the flat model is
365
+ * lossy-free: depths are normalized gap-free first, so malformed depth jumps
366
+ * never drop items). Inline runs render as nested mark tags in a deterministic
367
+ * order (`link` outermost … `code` innermost). Block `id` is the React key. An
368
+ * empty document renders nothing. `code_block` content is treated as plain text.
369
+ *
370
+ * Pass `{ editable: true }` to add `data-block-id` anchors on every block element
371
+ * and render empty blocks with a `<br>` (required for contentEditable caret placement).
372
+ * Read-only output (default) is byte-identical to the pre-options behaviour.
373
+ */
374
+ export function renderDoc(doc: RichDoc, options: RenderDocOptions = {}): ReactNode {
375
+ const opts: ResolvedOptions = {
376
+ editable: options.editable ?? false,
377
+ renderLink: options.renderLink,
378
+ renderMention: options.renderMention,
379
+ };
380
+ const eff = effectiveDepths(doc.blocks);
381
+ const out: ReactNode[] = [];
382
+ let i = 0;
383
+ while (i < doc.blocks.length) {
384
+ if (isListItem(doc.blocks[i])) {
385
+ const startId = doc.blocks[i].id;
386
+ const { tag, items, next } = collectList(doc.blocks, i, eff, opts);
387
+ out.push(<Fragment key={`list-${startId}`}>{renderListTree(tag, items, opts)}</Fragment>);
388
+ i = next;
389
+ } else {
390
+ out.push(renderBlock(doc.blocks[i], opts));
391
+ i += 1;
392
+ }
393
+ }
394
+ return out;
395
+ }
@@ -0,0 +1,15 @@
1
+ import type { ReactNode } from 'react';
2
+
3
+ /** A link encountered while rendering, passed to `renderLink`. */
4
+ export interface RichTextLink {
5
+ /** The sanitized URL. */
6
+ href: string;
7
+ /** The link's visible text in the document. */
8
+ text: string;
9
+ }
10
+
11
+ /**
12
+ * Replace how a link renders. Return your own node (e.g. a task/member chip) to
13
+ * substitute the link, or `defaultNode` for the standard `<a>`.
14
+ */
15
+ export type RenderLink = (link: RichTextLink, defaultNode: ReactNode) => ReactNode;
@@ -0,0 +1,16 @@
1
+ import type { ReactNode } from 'react';
2
+
3
+ /** A mention encountered while rendering, passed to `renderMention`. */
4
+ export interface RichTextMention {
5
+ /** The mention's stable id (from the `mention` mark). */
6
+ id: string;
7
+ /** The mention's display label (without the trigger). */
8
+ label: string;
9
+ }
10
+
11
+ /**
12
+ * Replace how a `mention` mark renders. Return your own node (e.g. an interactive
13
+ * member chip / popover trigger) to substitute the mention, or `defaultNode` for
14
+ * the standard non-interactive mention span. Mirrors {@link RenderLink}.
15
+ */
16
+ export type RenderMention = (mention: RichTextMention, defaultNode: ReactNode) => ReactNode;
@@ -0,0 +1,22 @@
1
+ // safeHref.ts — the canonical, render-independent URL allowlist shared by the
2
+ // renderer (renderDoc) and the HTML importer (fromHtml). It is the SOLE scheme
3
+ // gate for hrefs that enter the model from untrusted input, so it must normalize
4
+ // URLs the way browsers do before resolving a scheme. Allows relative URLs + a
5
+ // small scheme allowlist; blocks javascript:/data:/protocol-relative.
6
+ export function safeHref(href: string): string | undefined {
7
+ // Browsers strip ASCII tab/LF/CR from anywhere in a URL, and drop leading C0
8
+ // controls + spaces, before resolving the scheme — so `java\tscript:` and
9
+ // `\x01javascript:` would both navigate as javascript:. Normalize the same way
10
+ // so the scheme allowlist below can't be smuggled past with embedded or leading
11
+ // control characters.
12
+ const trimmed = href.replace(/[\t\n\r]/g, '').replace(/^[\x00-\x20]+|[\x00-\x20]+$/g, '');
13
+ if (trimmed === '') return undefined;
14
+ // Block protocol-relative URLs (`//host`) — they navigate cross-origin and
15
+ // would otherwise slip through the "relative" branch below.
16
+ if (trimmed.startsWith('//')) return undefined;
17
+ // Has an explicit scheme? Only http(s)/mailto/tel are allowed.
18
+ if (/^[a-z][a-z0-9+.-]*:/i.test(trimmed)) {
19
+ return /^(https?:|mailto:|tel:)/i.test(trimmed) ? trimmed : undefined;
20
+ }
21
+ return trimmed; // relative (/, ./, #, ?, plain path) — safe
22
+ }
@@ -0,0 +1,154 @@
1
+ // toHtml.ts — serialize a RichDoc to a compact HTML string. The inverse of
2
+ // fromHtml; mirrors renderDoc's structure (block elements, mark nesting order,
3
+ // list-depth grouping) but emits a string. Text/attributes are escaped and hrefs
4
+ // run through safeHref, so output is injection-safe. Lossless for the model
5
+ // (underline → <u>), so fromHtml(toHtml(doc)) reproduces the document.
6
+ import type { RichDoc, Block, Inline, Mark, MarkType } from './model';
7
+ import { runsText } from './inlines';
8
+ import { escapeHtml, escapeAttr } from './escape';
9
+ import { safeHref } from './safeHref';
10
+ import { textColorVar, bgColorVar } from './colorMarks';
11
+ import { isListItem, effectiveDepths } from './listDepths';
12
+ import { attachmentIsImage } from './attachment';
13
+ import { MARK_ORDER } from './marks';
14
+
15
+ /** Wrap an already-escaped HTML string in one mark's tag. */
16
+ function wrapMark(type: MarkType, mark: Mark, inner: string): string {
17
+ switch (type) {
18
+ case 'bold':
19
+ return `<strong>${inner}</strong>`;
20
+ case 'italic':
21
+ return `<em>${inner}</em>`;
22
+ case 'underline':
23
+ return `<u>${inner}</u>`;
24
+ case 'strike':
25
+ return `<s>${inner}</s>`;
26
+ case 'code':
27
+ return `<code>${inner}</code>`;
28
+ case 'textColor': {
29
+ // Resolve the palette key to a token-backed var; an unknown key drops the
30
+ // wrapper (never emit an empty/bogus style). The value is from a fixed
31
+ // allowlist, so it needs no attribute escaping.
32
+ const value = mark.type === 'textColor' ? textColorVar(mark.color) : undefined;
33
+ return value ? `<span style="color:${value}">${inner}</span>` : inner;
34
+ }
35
+ case 'bgColor': {
36
+ const value = mark.type === 'bgColor' ? bgColorVar(mark.color) : undefined;
37
+ return value ? `<span style="background-color:${value}">${inner}</span>` : inner;
38
+ }
39
+ case 'link': {
40
+ const safe = mark.type === 'link' ? safeHref(mark.href) : undefined;
41
+ if (safe === undefined) return inner; // unsafe href → drop the anchor, keep text
42
+ return `<a href="${escapeAttr(safe)}" rel="noopener noreferrer">${inner}</a>`;
43
+ }
44
+ case 'mention': {
45
+ if (mark.type !== 'mention') return inner;
46
+ return `<span data-mention-id="${escapeAttr(mark.id)}" data-mention-label="${escapeAttr(mark.label)}">${inner}</span>`;
47
+ }
48
+ default:
49
+ return inner;
50
+ }
51
+ }
52
+
53
+ /** Serialize one inline run: escaped text wrapped innermost-first. */
54
+ function inlineRun(run: Inline): string {
55
+ const present = MARK_ORDER.filter((t) => run.marks.some((m) => m.type === t));
56
+ let html = escapeHtml(run.text);
57
+ for (let i = present.length - 1; i >= 0; i -= 1) {
58
+ const type = present[i];
59
+ const mark = run.marks.find((m) => m.type === type)!;
60
+ html = wrapMark(type, mark, html);
61
+ }
62
+ return html;
63
+ }
64
+
65
+ const inlines = (block: Block): string => block.inlines.map(inlineRun).join('');
66
+
67
+ /** Serialize a contiguous run of list items starting at `start` (its base depth). */
68
+ function listHtml(blocks: Block[], start: number, eff: number[]): [string, number] {
69
+ const base = eff[start];
70
+ const tag = blocks[start].type === 'ordered_item' ? 'ol' : 'ul';
71
+ const items: string[] = [];
72
+ let i = start;
73
+ while (i < blocks.length && isListItem(blocks[i])) {
74
+ const d = eff[i];
75
+ if (d < base) break;
76
+ if (d > base) {
77
+ const [child, next] = listHtml(blocks, i, eff);
78
+ if (items.length > 0) {
79
+ items[items.length - 1] = items[items.length - 1].replace(/<\/li>$/, `${child}</li>`);
80
+ }
81
+ i = next;
82
+ continue;
83
+ }
84
+ items.push(`<li>${inlines(blocks[i])}</li>`);
85
+ i += 1;
86
+ }
87
+ return [`<${tag}>${items.join('')}</${tag}>`, i];
88
+ }
89
+
90
+ function blockHtml(block: Block): string {
91
+ switch (block.type) {
92
+ case 'heading': {
93
+ // Clamp to the model's h1–h3 range so a hand-built doc with an out-of-range
94
+ // level never emits a malformed <undefined>/<h0> tag.
95
+ const tag = `h${Math.min(3, Math.max(1, block.level ?? 1))}`;
96
+ return `<${tag}>${inlines(block)}</${tag}>`;
97
+ }
98
+ case 'blockquote':
99
+ return `<blockquote>${inlines(block)}</blockquote>`;
100
+ case 'code_block':
101
+ return `<pre><code>${escapeHtml(runsText(block.inlines))}</code></pre>`;
102
+ case 'attachment': {
103
+ // Only finalized (ready/absent-status) attachments serialize; in-flight or
104
+ // failed uploads emit nothing.
105
+ if (block.status && block.status !== 'ready') return '';
106
+ const safe = safeHref(block.src ?? '');
107
+ if (safe === undefined) return '';
108
+ if (attachmentIsImage(block)) {
109
+ const alt = escapeAttr(block.alt ?? block.name ?? '');
110
+ const widthAttr = typeof block.width === 'number' ? ` width="${block.width}"` : '';
111
+ const heightAttr = typeof block.height === 'number' ? ` height="${block.height}"` : '';
112
+ const figStyle =
113
+ block.align === 'center' || block.align === 'right'
114
+ ? ` style="text-align:${block.align}"`
115
+ : '';
116
+ return `<figure${figStyle}><img src="${escapeAttr(safe)}" alt="${alt}"${widthAttr}${heightAttr}></figure>`;
117
+ }
118
+ return `<a href="${escapeAttr(safe)}" download>${escapeHtml(block.name ?? safe)}</a>`;
119
+ }
120
+ case 'paragraph':
121
+ default:
122
+ return `<p>${inlines(block)}</p>`;
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Serialize a `RichDoc` to a compact HTML string (the inverse of `fromHtml`).
128
+ * Text and attributes are escaped and hrefs run through `safeHref`, so the output
129
+ * is injection-safe. Lossless for the model — `fromHtml(toHtml(doc))` reproduces
130
+ * the document structurally.
131
+ *
132
+ * @remarks An unsafe href (rejected by `safeHref`) drops the `<a>` wrapper and
133
+ * emits the bare text — unlike `renderDoc`, which keeps a hrefless `<a>`. Both are
134
+ * safe and `fromHtml(toHtml(doc))` stays consistent (neither yields a link mark).
135
+ *
136
+ * @example
137
+ * const html = toHtml(doc); // '<h2>Title</h2><p>Hello <strong>world</strong></p>'
138
+ */
139
+ export function toHtml(doc: RichDoc): string {
140
+ const eff = effectiveDepths(doc.blocks);
141
+ let out = '';
142
+ let i = 0;
143
+ while (i < doc.blocks.length) {
144
+ if (isListItem(doc.blocks[i])) {
145
+ const [html, next] = listHtml(doc.blocks, i, eff);
146
+ out += html;
147
+ i = next;
148
+ } else {
149
+ out += blockHtml(doc.blocks[i]);
150
+ i += 1;
151
+ }
152
+ }
153
+ return out;
154
+ }