@eocrm/design-system 0.0.0-stage → 0.6.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (898) hide show
  1. package/AI-PRIMER.md +341 -0
  2. package/LICENSE +202 -0
  3. package/README.md +266 -2
  4. package/docs/components/Accordion.md +114 -0
  5. package/docs/components/AgentAvatar.md +58 -0
  6. package/docs/components/Alert.md +81 -0
  7. package/docs/components/AppLayout.md +70 -0
  8. package/docs/components/Avatar.md +49 -0
  9. package/docs/components/AvatarGroup.md +47 -0
  10. package/docs/components/Badge.md +60 -0
  11. package/docs/components/Banner.md +89 -0
  12. package/docs/components/BrandIcon.md +32 -0
  13. package/docs/components/Breadcrumb.md +72 -0
  14. package/docs/components/Button.md +107 -0
  15. package/docs/components/ButtonGroup.md +78 -0
  16. package/docs/components/Calendar.md +158 -0
  17. package/docs/components/Card.md +165 -0
  18. package/docs/components/CatalogPicker.md +83 -0
  19. package/docs/components/Chart.md +114 -0
  20. package/docs/components/ChatBubble.md +55 -0
  21. package/docs/components/ChatLauncher.md +97 -0
  22. package/docs/components/Checkbox.md +55 -0
  23. package/docs/components/CircularProgress.md +53 -0
  24. package/docs/components/Cluster.md +96 -0
  25. package/docs/components/Code.md +35 -0
  26. package/docs/components/CodeBlock.md +67 -0
  27. package/docs/components/ColorPicker.md +115 -0
  28. package/docs/components/ConfirmationPopover.md +70 -0
  29. package/docs/components/Constrain.md +39 -0
  30. package/docs/components/CurrencySelect.md +57 -0
  31. package/docs/components/CursorPagination.md +43 -0
  32. package/docs/components/DashboardCanvas.md +79 -0
  33. package/docs/components/DashboardWidget.md +131 -0
  34. package/docs/components/DataTable.md +88 -0
  35. package/docs/components/DatePicker.md +68 -0
  36. package/docs/components/DateRangePicker.md +71 -0
  37. package/docs/components/DateStrip.md +56 -0
  38. package/docs/components/DefinitionList.md +82 -0
  39. package/docs/components/Divider.md +57 -0
  40. package/docs/components/Dot.md +26 -0
  41. package/docs/components/Drawer.md +94 -0
  42. package/docs/components/DropdownMenu.md +299 -0
  43. package/docs/components/EmojiPicker.md +84 -0
  44. package/docs/components/EmptyState.md +55 -0
  45. package/docs/components/EntityChip.md +102 -0
  46. package/docs/components/ErrorState.md +72 -0
  47. package/docs/components/Field.md +91 -0
  48. package/docs/components/FileUpload.md +109 -0
  49. package/docs/components/FilterChip.md +88 -0
  50. package/docs/components/FlowCanvas.md +108 -0
  51. package/docs/components/FormRow.md +31 -0
  52. package/docs/components/FormSection.md +37 -0
  53. package/docs/components/Grid.md +103 -0
  54. package/docs/components/Highlight.md +75 -0
  55. package/docs/components/HighlightedText.md +50 -0
  56. package/docs/components/IconPicker.md +134 -0
  57. package/docs/components/IconTile.md +30 -0
  58. package/docs/components/Image.md +84 -0
  59. package/docs/components/ImageCrop.md +163 -0
  60. package/docs/components/Indent.md +31 -0
  61. package/docs/components/InlineDatePicker.md +58 -0
  62. package/docs/components/InlineDateRangePicker.md +57 -0
  63. package/docs/components/Input.md +54 -0
  64. package/docs/components/Kanban.md +122 -0
  65. package/docs/components/Kbd.md +41 -0
  66. package/docs/components/Lightbox.md +105 -0
  67. package/docs/components/Link.md +65 -0
  68. package/docs/components/LinkCard.md +41 -0
  69. package/docs/components/LiquidEditor.md +84 -0
  70. package/docs/components/List.md +68 -0
  71. package/docs/components/LiveRegion.md +29 -0
  72. package/docs/components/LocaleProvider.md +25 -0
  73. package/docs/components/Logo.md +41 -0
  74. package/docs/components/Masonry.md +48 -0
  75. package/docs/components/MediaTile.md +95 -0
  76. package/docs/components/Modal.md +107 -0
  77. package/docs/components/MoneyInput.md +62 -0
  78. package/docs/components/OptionsPicker.md +123 -0
  79. package/docs/components/OtpInput.md +65 -0
  80. package/docs/components/Page.md +35 -0
  81. package/docs/components/PageHeader.md +133 -0
  82. package/docs/components/Pagination.md +44 -0
  83. package/docs/components/Palette.md +32 -0
  84. package/docs/components/PasswordInput.md +45 -0
  85. package/docs/components/PasswordStrengthMeter.md +27 -0
  86. package/docs/components/PersonDisplay.md +153 -0
  87. package/docs/components/PhoneInput.md +54 -0
  88. package/docs/components/PillMenu.md +91 -0
  89. package/docs/components/Popover.md +127 -0
  90. package/docs/components/Progress.md +56 -0
  91. package/docs/components/QrCode.md +34 -0
  92. package/docs/components/Radio.md +37 -0
  93. package/docs/components/RadioGroup.md +56 -0
  94. package/docs/components/Rail.md +191 -0
  95. package/docs/components/RelativeDateInput.md +114 -0
  96. package/docs/components/RichText.md +44 -0
  97. package/docs/components/RichTextEditor.md +112 -0
  98. package/docs/components/Screen.md +37 -0
  99. package/docs/components/ScrollArea.md +39 -0
  100. package/docs/components/Select.md +131 -0
  101. package/docs/components/SettingRow.md +98 -0
  102. package/docs/components/Skeleton.md +68 -0
  103. package/docs/components/Slider.md +92 -0
  104. package/docs/components/SlotGrid.md +55 -0
  105. package/docs/components/SocialButton.md +31 -0
  106. package/docs/components/Sortable.md +127 -0
  107. package/docs/components/SortableGroup.md +52 -0
  108. package/docs/components/Sparkline.md +51 -0
  109. package/docs/components/Split.md +76 -0
  110. package/docs/components/Stack.md +59 -0
  111. package/docs/components/StagePath.md +66 -0
  112. package/docs/components/StatGroup.md +61 -0
  113. package/docs/components/StatTile.md +58 -0
  114. package/docs/components/Sticky.md +69 -0
  115. package/docs/components/Switch.md +89 -0
  116. package/docs/components/Table.md +184 -0
  117. package/docs/components/TableOfContents.md +76 -0
  118. package/docs/components/Tabs.md +94 -0
  119. package/docs/components/Text.md +63 -0
  120. package/docs/components/Textarea.md +59 -0
  121. package/docs/components/Thread.md +52 -0
  122. package/docs/components/TimeField.md +70 -0
  123. package/docs/components/Timeline.md +57 -0
  124. package/docs/components/Title.md +54 -0
  125. package/docs/components/ToastViewport.md +61 -0
  126. package/docs/components/Tooltip.md +63 -0
  127. package/docs/components/TopBar.md +214 -0
  128. package/docs/components/Tour.md +85 -0
  129. package/docs/components/TreeView.md +113 -0
  130. package/docs/components/VisuallyHidden.md +43 -0
  131. package/docs/components/WidgetPreview.md +54 -0
  132. package/docs/components/useBelowBreakpoint.md +11 -0
  133. package/docs/components/useMonth.md +18 -0
  134. package/docs/setup.md +51 -0
  135. package/docs/theming.md +95 -0
  136. package/docs/tokens.md +123 -0
  137. package/docs/transient-state.md +56 -0
  138. package/package.json +86 -4
  139. package/src/_meta/manifest.ts +293 -0
  140. package/src/app/AppProvider.tsx +78 -0
  141. package/src/app/index.ts +3 -0
  142. package/src/app/themeTokens.ts +95 -0
  143. package/src/calendar/dateMath.ts +114 -0
  144. package/src/calendar/formatters.ts +75 -0
  145. package/src/calendar/index.ts +39 -0
  146. package/src/calendar/types.ts +36 -0
  147. package/src/calendar/useAgenda.ts +70 -0
  148. package/src/calendar/useDay.ts +51 -0
  149. package/src/calendar/useMonth.ts +82 -0
  150. package/src/calendar/useWeek.ts +62 -0
  151. package/src/calendar/weekInfo.ts +83 -0
  152. package/src/components/Accordion/Accordion.module.scss +304 -0
  153. package/src/components/Accordion/Accordion.tokens.scss +64 -0
  154. package/src/components/Accordion/Accordion.tsx +272 -0
  155. package/src/components/Accordion/AccordionContent.tsx +36 -0
  156. package/src/components/Accordion/AccordionItem.tsx +66 -0
  157. package/src/components/Accordion/AccordionTrigger.tsx +121 -0
  158. package/src/components/Accordion/context.ts +47 -0
  159. package/src/components/Accordion/index.ts +14 -0
  160. package/src/components/Alert/Alert.module.scss +92 -0
  161. package/src/components/Alert/Alert.tokens.scss +60 -0
  162. package/src/components/Alert/Alert.tsx +136 -0
  163. package/src/components/Alert/index.ts +2 -0
  164. package/src/components/AppLayout/AppLayout.module.scss +130 -0
  165. package/src/components/AppLayout/AppLayout.tokens.scss +27 -0
  166. package/src/components/AppLayout/AppLayout.tsx +211 -0
  167. package/src/components/AppLayout/index.ts +2 -0
  168. package/src/components/Avatar/AgentAvatar.module.scss +117 -0
  169. package/src/components/Avatar/AgentAvatar.tsx +122 -0
  170. package/src/components/Avatar/Avatar.module.scss +181 -0
  171. package/src/components/Avatar/Avatar.tokens.scss +107 -0
  172. package/src/components/Avatar/Avatar.tsx +210 -0
  173. package/src/components/Avatar/AvatarGroup.module.scss +128 -0
  174. package/src/components/Avatar/AvatarGroup.tsx +119 -0
  175. package/src/components/Avatar/AvatarGroupContext.tsx +20 -0
  176. package/src/components/Avatar/index.ts +6 -0
  177. package/src/components/Badge/Badge.module.scss +124 -0
  178. package/src/components/Badge/Badge.tokens.scss +74 -0
  179. package/src/components/Badge/Badge.tsx +164 -0
  180. package/src/components/Badge/index.ts +2 -0
  181. package/src/components/Banner/Banner.module.scss +73 -0
  182. package/src/components/Banner/Banner.tokens.scss +51 -0
  183. package/src/components/Banner/Banner.tsx +138 -0
  184. package/src/components/Banner/index.ts +2 -0
  185. package/src/components/BrandIcon/BrandIcon.module.scss +5 -0
  186. package/src/components/BrandIcon/BrandIcon.tsx +99 -0
  187. package/src/components/BrandIcon/index.ts +2 -0
  188. package/src/components/Breadcrumb/Breadcrumb.module.scss +32 -0
  189. package/src/components/Breadcrumb/Breadcrumb.tokens.scss +9 -0
  190. package/src/components/Breadcrumb/Breadcrumb.tsx +146 -0
  191. package/src/components/Breadcrumb/index.ts +2 -0
  192. package/src/components/Button/Button.module.scss +167 -0
  193. package/src/components/Button/Button.tokens.scss +90 -0
  194. package/src/components/Button/Button.tsx +205 -0
  195. package/src/components/Button/index.ts +2 -0
  196. package/src/components/ButtonGroup/ButtonGroup.module.scss +134 -0
  197. package/src/components/ButtonGroup/ButtonGroup.tokens.scss +42 -0
  198. package/src/components/ButtonGroup/ButtonGroup.tsx +278 -0
  199. package/src/components/ButtonGroup/ButtonGroupItem.tsx +74 -0
  200. package/src/components/ButtonGroup/context.ts +45 -0
  201. package/src/components/ButtonGroup/index.ts +2 -0
  202. package/src/components/Calendar/AgendaView.module.scss +231 -0
  203. package/src/components/Calendar/AgendaView.tsx +214 -0
  204. package/src/components/Calendar/AllDayBand.module.scss +18 -0
  205. package/src/components/Calendar/AllDayBand.tsx +75 -0
  206. package/src/components/Calendar/Calendar.module.scss +23 -0
  207. package/src/components/Calendar/Calendar.tokens.scss +262 -0
  208. package/src/components/Calendar/Calendar.tsx +370 -0
  209. package/src/components/Calendar/DayCell.module.scss +30 -0
  210. package/src/components/Calendar/DayCell.tsx +50 -0
  211. package/src/components/Calendar/DayView.module.scss +10 -0
  212. package/src/components/Calendar/DayView.tsx +163 -0
  213. package/src/components/Calendar/EventChip.module.scss +171 -0
  214. package/src/components/Calendar/EventChip.tsx +115 -0
  215. package/src/components/Calendar/HourGrid.module.scss +123 -0
  216. package/src/components/Calendar/HourGrid.tsx +381 -0
  217. package/src/components/Calendar/MonthView.module.scss +99 -0
  218. package/src/components/Calendar/MonthView.tsx +296 -0
  219. package/src/components/Calendar/TimedEvent.module.scss +205 -0
  220. package/src/components/Calendar/TimedEvent.tsx +247 -0
  221. package/src/components/Calendar/ViewSwitcher.module.scss +3 -0
  222. package/src/components/Calendar/ViewSwitcher.tsx +47 -0
  223. package/src/components/Calendar/WeekView.module.scss +10 -0
  224. package/src/components/Calendar/WeekView.tsx +137 -0
  225. package/src/components/Calendar/eventColor.ts +60 -0
  226. package/src/components/Calendar/index.ts +18 -0
  227. package/src/components/Calendar/types.ts +451 -0
  228. package/src/components/Calendar/useEventDrag.ts +783 -0
  229. package/src/components/Calendar/utils.ts +622 -0
  230. package/src/components/Card/Card.module.scss +264 -0
  231. package/src/components/Card/Card.tokens.scss +55 -0
  232. package/src/components/Card/Card.tsx +170 -0
  233. package/src/components/Card/CardBody.tsx +45 -0
  234. package/src/components/Card/CardHeader.tsx +113 -0
  235. package/src/components/Card/CardList.tsx +24 -0
  236. package/src/components/Card/CardListRow.tsx +24 -0
  237. package/src/components/Card/index.ts +7 -0
  238. package/src/components/CatalogPicker/CatalogPicker.module.scss +193 -0
  239. package/src/components/CatalogPicker/CatalogPicker.tokens.scss +26 -0
  240. package/src/components/CatalogPicker/CatalogPicker.tsx +339 -0
  241. package/src/components/CatalogPicker/index.ts +2 -0
  242. package/src/components/Chart/Chart.module.scss +287 -0
  243. package/src/components/Chart/Chart.tokens.scss +63 -0
  244. package/src/components/Chart/Chart.tsx +607 -0
  245. package/src/components/Chart/ChartLegend.tsx +99 -0
  246. package/src/components/Chart/ChartTable.tsx +62 -0
  247. package/src/components/Chart/ChartTooltip.tsx +91 -0
  248. package/src/components/Chart/chartModel.ts +689 -0
  249. package/src/components/Chart/index.ts +2 -0
  250. package/src/components/ChatBubble/ChatBubble.module.scss +93 -0
  251. package/src/components/ChatBubble/ChatBubble.tokens.scss +17 -0
  252. package/src/components/ChatBubble/ChatBubble.tsx +61 -0
  253. package/src/components/ChatBubble/ChatBubbleList.tsx +27 -0
  254. package/src/components/ChatBubble/index.ts +3 -0
  255. package/src/components/ChatLauncher/ChatLauncher.module.scss +68 -0
  256. package/src/components/ChatLauncher/ChatLauncher.tokens.scss +27 -0
  257. package/src/components/ChatLauncher/ChatLauncher.tsx +202 -0
  258. package/src/components/ChatLauncher/index.ts +2 -0
  259. package/src/components/ChatLauncher/isAtBottom.ts +12 -0
  260. package/src/components/Checkbox/Checkbox.module.scss +147 -0
  261. package/src/components/Checkbox/Checkbox.tokens.scss +44 -0
  262. package/src/components/Checkbox/Checkbox.tsx +188 -0
  263. package/src/components/Checkbox/index.ts +2 -0
  264. package/src/components/CircularProgress/CircularProgress.module.scss +133 -0
  265. package/src/components/CircularProgress/CircularProgress.tokens.scss +40 -0
  266. package/src/components/CircularProgress/CircularProgress.tsx +139 -0
  267. package/src/components/CircularProgress/index.ts +7 -0
  268. package/src/components/Cluster/Cluster.module.scss +145 -0
  269. package/src/components/Cluster/Cluster.tokens.scss +11 -0
  270. package/src/components/Cluster/Cluster.tsx +215 -0
  271. package/src/components/Cluster/index.ts +2 -0
  272. package/src/components/Code/Code.module.scss +28 -0
  273. package/src/components/Code/Code.tokens.scss +15 -0
  274. package/src/components/Code/Code.tsx +44 -0
  275. package/src/components/Code/index.ts +2 -0
  276. package/src/components/CodeBlock/CodeBlock.module.scss +146 -0
  277. package/src/components/CodeBlock/CodeBlock.tokens.scss +27 -0
  278. package/src/components/CodeBlock/CodeBlock.tsx +274 -0
  279. package/src/components/CodeBlock/highlight.ts +179 -0
  280. package/src/components/CodeBlock/index.ts +8 -0
  281. package/src/components/CodeBlock/sampleSync.ts +42 -0
  282. package/src/components/ColorPicker/ColorPicker.module.scss +286 -0
  283. package/src/components/ColorPicker/ColorPicker.tokens.scss +60 -0
  284. package/src/components/ColorPicker/ColorPicker.tsx +367 -0
  285. package/src/components/ColorPicker/ColorPickerPanel.tsx +265 -0
  286. package/src/components/ColorPicker/SVSquare.tsx +189 -0
  287. package/src/components/ColorPicker/colorMath.ts +141 -0
  288. package/src/components/ColorPicker/index.ts +6 -0
  289. package/src/components/ConfirmationPopover/ConfirmationPopover.module.scss +39 -0
  290. package/src/components/ConfirmationPopover/ConfirmationPopover.tokens.scss +13 -0
  291. package/src/components/ConfirmationPopover/ConfirmationPopover.tsx +395 -0
  292. package/src/components/ConfirmationPopover/index.ts +2 -0
  293. package/src/components/Constrain/Constrain.module.scss +99 -0
  294. package/src/components/Constrain/Constrain.tsx +79 -0
  295. package/src/components/Constrain/index.ts +2 -0
  296. package/src/components/CurrencySelect/CurrencySelect.module.scss +7 -0
  297. package/src/components/CurrencySelect/CurrencySelect.tsx +167 -0
  298. package/src/components/CurrencySelect/index.ts +3 -0
  299. package/src/components/CursorPagination/CursorPagination.module.scss +69 -0
  300. package/src/components/CursorPagination/CursorPagination.tokens.scss +32 -0
  301. package/src/components/CursorPagination/CursorPagination.tsx +121 -0
  302. package/src/components/CursorPagination/index.ts +2 -0
  303. package/src/components/DashboardCanvas/DashboardCanvas.module.scss +360 -0
  304. package/src/components/DashboardCanvas/DashboardCanvas.tokens.scss +48 -0
  305. package/src/components/DashboardCanvas/DashboardCanvas.tsx +1270 -0
  306. package/src/components/DashboardCanvas/DashboardCanvasItem.tsx +140 -0
  307. package/src/components/DashboardCanvas/DashboardCanvasSection.tsx +174 -0
  308. package/src/components/DashboardCanvas/engine.ts +363 -0
  309. package/src/components/DashboardCanvas/index.ts +9 -0
  310. package/src/components/DashboardWidget/DashboardWidget.module.scss +100 -0
  311. package/src/components/DashboardWidget/DashboardWidget.tokens.scss +16 -0
  312. package/src/components/DashboardWidget/DashboardWidget.tsx +188 -0
  313. package/src/components/DashboardWidget/index.ts +7 -0
  314. package/src/components/DataTable/BodyRow.tsx +197 -0
  315. package/src/components/DataTable/ColumnVisibilityTrigger.module.scss +7 -0
  316. package/src/components/DataTable/ColumnVisibilityTrigger.tsx +105 -0
  317. package/src/components/DataTable/DataTable.module.scss +511 -0
  318. package/src/components/DataTable/DataTable.tokens.scss +80 -0
  319. package/src/components/DataTable/DataTable.tsx +734 -0
  320. package/src/components/DataTable/HeaderCell.module.scss +215 -0
  321. package/src/components/DataTable/HeaderCell.tsx +440 -0
  322. package/src/components/DataTable/columnShift.ts +117 -0
  323. package/src/components/DataTable/index.ts +23 -0
  324. package/src/components/DataTable/pinStyle.ts +47 -0
  325. package/src/components/DataTable/reorderColumns.ts +66 -0
  326. package/src/components/DataTable/types.ts +289 -0
  327. package/src/components/DataTable/useColumnDragShift.ts +216 -0
  328. package/src/components/DataTable/useDataTable.ts +372 -0
  329. package/src/components/DataTable/useResizeHandle.ts +97 -0
  330. package/src/components/DatePicker/DatePicker.module.scss +180 -0
  331. package/src/components/DatePicker/DatePicker.tokens.scss +152 -0
  332. package/src/components/DatePicker/DatePicker.tsx +664 -0
  333. package/src/components/DatePicker/DatePickerGrid.module.scss +172 -0
  334. package/src/components/DatePicker/DatePickerGrid.tsx +341 -0
  335. package/src/components/DatePicker/InlineDatePicker.module.scss +32 -0
  336. package/src/components/DatePicker/InlineDatePicker.tsx +201 -0
  337. package/src/components/DatePicker/index.ts +4 -0
  338. package/src/components/DatePicker/utils.ts +364 -0
  339. package/src/components/DateRangePicker/DateRangePicker.module.scss +237 -0
  340. package/src/components/DateRangePicker/DateRangePicker.tokens.scss +78 -0
  341. package/src/components/DateRangePicker/DateRangePicker.tsx +720 -0
  342. package/src/components/DateRangePicker/InlineDateRangePicker.module.scss +94 -0
  343. package/src/components/DateRangePicker/InlineDateRangePicker.tsx +376 -0
  344. package/src/components/DateRangePicker/index.ts +5 -0
  345. package/src/components/DateRangePicker/utils.ts +151 -0
  346. package/src/components/DateStrip/DateStrip.module.scss +78 -0
  347. package/src/components/DateStrip/DateStrip.tokens.scss +23 -0
  348. package/src/components/DateStrip/DateStrip.tsx +205 -0
  349. package/src/components/DateStrip/index.ts +2 -0
  350. package/src/components/DefinitionList/DefinitionList.module.scss +102 -0
  351. package/src/components/DefinitionList/DefinitionList.tokens.scss +29 -0
  352. package/src/components/DefinitionList/DefinitionList.tsx +198 -0
  353. package/src/components/DefinitionList/index.ts +9 -0
  354. package/src/components/Divider/Divider.module.scss +144 -0
  355. package/src/components/Divider/Divider.tokens.scss +21 -0
  356. package/src/components/Divider/Divider.tsx +103 -0
  357. package/src/components/Divider/index.ts +2 -0
  358. package/src/components/Dot/Dot.module.scss +40 -0
  359. package/src/components/Dot/Dot.tokens.scss +4 -0
  360. package/src/components/Dot/Dot.tsx +45 -0
  361. package/src/components/Dot/index.ts +2 -0
  362. package/src/components/Drawer/Body.tsx +23 -0
  363. package/src/components/Drawer/Close.tsx +35 -0
  364. package/src/components/Drawer/Content.tsx +93 -0
  365. package/src/components/Drawer/Drawer.module.scss +232 -0
  366. package/src/components/Drawer/Drawer.tokens.scss +38 -0
  367. package/src/components/Drawer/Drawer.tsx +23 -0
  368. package/src/components/Drawer/DrawerRoot.tsx +190 -0
  369. package/src/components/Drawer/Footer.tsx +24 -0
  370. package/src/components/Drawer/Header.tsx +64 -0
  371. package/src/components/Drawer/Overlay.tsx +82 -0
  372. package/src/components/Drawer/context.ts +44 -0
  373. package/src/components/Drawer/index.ts +12 -0
  374. package/src/components/Drawer/useDragToClose.ts +149 -0
  375. package/src/components/DropdownMenu/CheckboxItem.tsx +144 -0
  376. package/src/components/DropdownMenu/Content.tsx +419 -0
  377. package/src/components/DropdownMenu/DropdownMenu.module.scss +280 -0
  378. package/src/components/DropdownMenu/DropdownMenu.tokens.scss +88 -0
  379. package/src/components/DropdownMenu/DropdownMenu.tsx +43 -0
  380. package/src/components/DropdownMenu/Group.tsx +76 -0
  381. package/src/components/DropdownMenu/Item.tsx +148 -0
  382. package/src/components/DropdownMenu/ItemIndicator.tsx +30 -0
  383. package/src/components/DropdownMenu/Radio.tsx +178 -0
  384. package/src/components/DropdownMenu/Root.tsx +100 -0
  385. package/src/components/DropdownMenu/Sub.tsx +332 -0
  386. package/src/components/DropdownMenu/Trigger.tsx +76 -0
  387. package/src/components/DropdownMenu/context.ts +65 -0
  388. package/src/components/DropdownMenu/index.ts +20 -0
  389. package/src/components/EmojiPicker/EmojiPicker.module.scss +84 -0
  390. package/src/components/EmojiPicker/EmojiPicker.tokens.scss +24 -0
  391. package/src/components/EmojiPicker/EmojiPicker.tsx +341 -0
  392. package/src/components/EmojiPicker/emojiData.ts +245 -0
  393. package/src/components/EmojiPicker/index.ts +3 -0
  394. package/src/components/EmptyState/EmptyState.module.scss +102 -0
  395. package/src/components/EmptyState/EmptyState.tokens.scss +28 -0
  396. package/src/components/EmptyState/EmptyState.tsx +112 -0
  397. package/src/components/EmptyState/index.ts +7 -0
  398. package/src/components/EntityChip/EntityChip.module.scss +275 -0
  399. package/src/components/EntityChip/EntityChip.tokens.scss +66 -0
  400. package/src/components/EntityChip/EntityChip.tsx +649 -0
  401. package/src/components/EntityChip/index.ts +10 -0
  402. package/src/components/ErrorState/ErrorState.module.scss +105 -0
  403. package/src/components/ErrorState/ErrorState.tokens.scss +32 -0
  404. package/src/components/ErrorState/ErrorState.tsx +125 -0
  405. package/src/components/ErrorState/index.ts +8 -0
  406. package/src/components/Field/Field.module.scss +46 -0
  407. package/src/components/Field/Field.tsx +185 -0
  408. package/src/components/Field/index.ts +2 -0
  409. package/src/components/FileUpload/FileUpload.module.scss +187 -0
  410. package/src/components/FileUpload/FileUpload.tokens.scss +81 -0
  411. package/src/components/FileUpload/FileUpload.tsx +569 -0
  412. package/src/components/FileUpload/formatBytes.ts +34 -0
  413. package/src/components/FileUpload/iconForFile.ts +40 -0
  414. package/src/components/FileUpload/index.ts +2 -0
  415. package/src/components/FilterChip/FilterChip.module.scss +61 -0
  416. package/src/components/FilterChip/FilterChip.tokens.scss +25 -0
  417. package/src/components/FilterChip/FilterChip.tsx +208 -0
  418. package/src/components/FilterChip/index.ts +5 -0
  419. package/src/components/FlowCanvas/FlowCanvas.module.scss +329 -0
  420. package/src/components/FlowCanvas/FlowCanvas.tokens.scss +45 -0
  421. package/src/components/FlowCanvas/FlowCanvas.tsx +1867 -0
  422. package/src/components/FlowCanvas/FlowControls.tsx +46 -0
  423. package/src/components/FlowCanvas/FlowEdge.tsx +58 -0
  424. package/src/components/FlowCanvas/FlowNode.tsx +76 -0
  425. package/src/components/FlowCanvas/edgePath.ts +85 -0
  426. package/src/components/FlowCanvas/index.ts +4 -0
  427. package/src/components/FlowCanvas/layout.ts +148 -0
  428. package/src/components/FlowCanvas/spatialNav.ts +76 -0
  429. package/src/components/FlowCanvas/types.ts +59 -0
  430. package/src/components/FlowCanvas/useViewport.ts +122 -0
  431. package/src/components/FormRow/FormRow.module.scss +2 -0
  432. package/src/components/FormRow/FormRow.tsx +37 -0
  433. package/src/components/FormRow/index.ts +2 -0
  434. package/src/components/FormSection/FormSection.module.scss +24 -0
  435. package/src/components/FormSection/FormSection.tsx +46 -0
  436. package/src/components/FormSection/index.ts +2 -0
  437. package/src/components/Grid/Grid.module.scss +162 -0
  438. package/src/components/Grid/Grid.tokens.scss +13 -0
  439. package/src/components/Grid/Grid.tsx +226 -0
  440. package/src/components/Grid/GridItem.tsx +77 -0
  441. package/src/components/Grid/index.ts +11 -0
  442. package/src/components/Highlight/Highlight.module.scss +43 -0
  443. package/src/components/Highlight/Highlight.tokens.scss +35 -0
  444. package/src/components/Highlight/Highlight.tsx +164 -0
  445. package/src/components/Highlight/HighlightOverlay.tsx +100 -0
  446. package/src/components/Highlight/index.ts +2 -0
  447. package/src/components/HighlightedText/HighlightedText.module.scss +11 -0
  448. package/src/components/HighlightedText/HighlightedText.tokens.scss +9 -0
  449. package/src/components/HighlightedText/HighlightedText.tsx +50 -0
  450. package/src/components/HighlightedText/highlightRanges.ts +44 -0
  451. package/src/components/HighlightedText/index.ts +2 -0
  452. package/src/components/IconPicker/IconPicker.module.scss +175 -0
  453. package/src/components/IconPicker/IconPicker.tokens.scss +40 -0
  454. package/src/components/IconPicker/IconPicker.tsx +629 -0
  455. package/src/components/IconPicker/index.ts +9 -0
  456. package/src/components/IconTile/IconTile.module.scss +57 -0
  457. package/src/components/IconTile/IconTile.tokens.scss +16 -0
  458. package/src/components/IconTile/IconTile.tsx +91 -0
  459. package/src/components/IconTile/index.ts +2 -0
  460. package/src/components/Image/Image.module.scss +266 -0
  461. package/src/components/Image/Image.tokens.scss +55 -0
  462. package/src/components/Image/Image.tsx +342 -0
  463. package/src/components/Image/index.ts +2 -0
  464. package/src/components/ImageCrop/ImageCrop.module.scss +274 -0
  465. package/src/components/ImageCrop/ImageCrop.tokens.scss +33 -0
  466. package/src/components/ImageCrop/ImageCrop.tsx +542 -0
  467. package/src/components/ImageCrop/cropGeometry.ts +120 -0
  468. package/src/components/ImageCrop/extractCropBlob.ts +140 -0
  469. package/src/components/ImageCrop/index.ts +11 -0
  470. package/src/components/ImageCrop/useCropPreview.ts +161 -0
  471. package/src/components/Indent/Indent.module.scss +33 -0
  472. package/src/components/Indent/Indent.tokens.scss +10 -0
  473. package/src/components/Indent/Indent.tsx +46 -0
  474. package/src/components/Indent/index.ts +2 -0
  475. package/src/components/Input/Input.module.scss +99 -0
  476. package/src/components/Input/Input.tokens.scss +54 -0
  477. package/src/components/Input/Input.tsx +105 -0
  478. package/src/components/Input/Suggestions.tsx +260 -0
  479. package/src/components/Input/index.ts +2 -0
  480. package/src/components/Kanban/Kanban.module.scss +39 -0
  481. package/src/components/Kanban/Kanban.tokens.scss +15 -0
  482. package/src/components/Kanban/Kanban.tsx +951 -0
  483. package/src/components/Kanban/index.ts +7 -0
  484. package/src/components/Kbd/Kbd.module.scss +47 -0
  485. package/src/components/Kbd/Kbd.tokens.scss +26 -0
  486. package/src/components/Kbd/Kbd.tsx +73 -0
  487. package/src/components/Kbd/index.ts +2 -0
  488. package/src/components/Lightbox/Lightbox.module.scss +283 -0
  489. package/src/components/Lightbox/Lightbox.tokens.scss +36 -0
  490. package/src/components/Lightbox/Lightbox.tsx +506 -0
  491. package/src/components/Lightbox/index.ts +2 -0
  492. package/src/components/Link/Link.module.scss +78 -0
  493. package/src/components/Link/Link.tokens.scss +28 -0
  494. package/src/components/Link/Link.tsx +114 -0
  495. package/src/components/Link/index.ts +2 -0
  496. package/src/components/LinkCard/LinkCard.module.scss +92 -0
  497. package/src/components/LinkCard/LinkCard.tokens.scss +9 -0
  498. package/src/components/LinkCard/LinkCard.tsx +72 -0
  499. package/src/components/LinkCard/index.ts +2 -0
  500. package/src/components/LiquidEditor/AutocompleteMenu.tsx +133 -0
  501. package/src/components/LiquidEditor/HighlightLayer.tsx +53 -0
  502. package/src/components/LiquidEditor/InsertVariableMenu.tsx +81 -0
  503. package/src/components/LiquidEditor/LiquidEditor.module.scss +339 -0
  504. package/src/components/LiquidEditor/LiquidEditor.tokens.scss +81 -0
  505. package/src/components/LiquidEditor/LiquidEditor.tsx +412 -0
  506. package/src/components/LiquidEditor/PreviewPane.tsx +29 -0
  507. package/src/components/LiquidEditor/caretCoordinates.ts +97 -0
  508. package/src/components/LiquidEditor/index.ts +7 -0
  509. package/src/components/LiquidEditor/liquidFilters.ts +23 -0
  510. package/src/components/LiquidEditor/liquidTokenizer.ts +235 -0
  511. package/src/components/LiquidEditor/types.ts +101 -0
  512. package/src/components/LiquidEditor/useLiquidAutocomplete.ts +178 -0
  513. package/src/components/List/List.module.scss +105 -0
  514. package/src/components/List/List.tokens.scss +42 -0
  515. package/src/components/List/List.tsx +124 -0
  516. package/src/components/List/index.ts +9 -0
  517. package/src/components/LiveRegion/LiveRegion.module.scss +3 -0
  518. package/src/components/LiveRegion/LiveRegion.tsx +116 -0
  519. package/src/components/LiveRegion/index.ts +2 -0
  520. package/src/components/Logo/Logo.module.scss +139 -0
  521. package/src/components/Logo/Logo.tokens.scss +14 -0
  522. package/src/components/Logo/Logo.tsx +126 -0
  523. package/src/components/Logo/index.ts +2 -0
  524. package/src/components/Masonry/Masonry.module.scss +42 -0
  525. package/src/components/Masonry/Masonry.tokens.scss +8 -0
  526. package/src/components/Masonry/Masonry.tsx +136 -0
  527. package/src/components/Masonry/index.ts +2 -0
  528. package/src/components/Masonry/masonryUtils.ts +42 -0
  529. package/src/components/MediaTile/MediaTile.module.scss +183 -0
  530. package/src/components/MediaTile/MediaTile.tokens.scss +60 -0
  531. package/src/components/MediaTile/MediaTile.tsx +208 -0
  532. package/src/components/MediaTile/index.ts +8 -0
  533. package/src/components/Modal/Body.tsx +27 -0
  534. package/src/components/Modal/Close.tsx +45 -0
  535. package/src/components/Modal/Content.tsx +98 -0
  536. package/src/components/Modal/Footer.tsx +28 -0
  537. package/src/components/Modal/Header.tsx +51 -0
  538. package/src/components/Modal/Modal.module.scss +262 -0
  539. package/src/components/Modal/Modal.tokens.scss +50 -0
  540. package/src/components/Modal/Modal.tsx +23 -0
  541. package/src/components/Modal/ModalRoot.tsx +299 -0
  542. package/src/components/Modal/Overlay.tsx +101 -0
  543. package/src/components/Modal/context.ts +60 -0
  544. package/src/components/Modal/index.ts +11 -0
  545. package/src/components/MoneyInput/MoneyInput.module.scss +57 -0
  546. package/src/components/MoneyInput/MoneyInput.tsx +433 -0
  547. package/src/components/MoneyInput/index.ts +2 -0
  548. package/src/components/OptionsPicker/OptionsPicker.module.scss +216 -0
  549. package/src/components/OptionsPicker/OptionsPicker.tokens.scss +68 -0
  550. package/src/components/OptionsPicker/OptionsPicker.tsx +936 -0
  551. package/src/components/OptionsPicker/index.ts +9 -0
  552. package/src/components/OtpInput/OtpInput.module.scss +69 -0
  553. package/src/components/OtpInput/OtpInput.tokens.scss +45 -0
  554. package/src/components/OtpInput/OtpInput.tsx +368 -0
  555. package/src/components/OtpInput/index.ts +2 -0
  556. package/src/components/Page/Page.module.scss +30 -0
  557. package/src/components/Page/Page.tokens.scss +11 -0
  558. package/src/components/Page/Page.tsx +53 -0
  559. package/src/components/Page/index.ts +2 -0
  560. package/src/components/PageHeader/PageHeader.module.scss +197 -0
  561. package/src/components/PageHeader/PageHeader.tokens.scss +41 -0
  562. package/src/components/PageHeader/PageHeader.tsx +310 -0
  563. package/src/components/PageHeader/index.ts +20 -0
  564. package/src/components/Pagination/Pagination.module.scss +117 -0
  565. package/src/components/Pagination/Pagination.tokens.scss +54 -0
  566. package/src/components/Pagination/Pagination.tsx +165 -0
  567. package/src/components/Pagination/index.ts +4 -0
  568. package/src/components/Pagination/paginationRange.ts +72 -0
  569. package/src/components/PasswordInput/PasswordInput.module.scss +120 -0
  570. package/src/components/PasswordInput/PasswordInput.tokens.scss +44 -0
  571. package/src/components/PasswordInput/PasswordInput.tsx +210 -0
  572. package/src/components/PasswordInput/index.ts +2 -0
  573. package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.module.scss +80 -0
  574. package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tokens.scss +40 -0
  575. package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tsx +96 -0
  576. package/src/components/PasswordStrengthMeter/index.ts +2 -0
  577. package/src/components/PersonDisplay/PersonDisplay.module.scss +180 -0
  578. package/src/components/PersonDisplay/PersonDisplay.tokens.scss +35 -0
  579. package/src/components/PersonDisplay/PersonDisplay.tsx +420 -0
  580. package/src/components/PersonDisplay/index.ts +10 -0
  581. package/src/components/PhoneInput/PhoneInput.module.scss +23 -0
  582. package/src/components/PhoneInput/PhoneInput.tsx +271 -0
  583. package/src/components/PhoneInput/index.ts +4 -0
  584. package/src/components/PhoneInput/phone.ts +128 -0
  585. package/src/components/PillMenu/PillMenu.module.scss +117 -0
  586. package/src/components/PillMenu/PillMenu.tokens.scss +22 -0
  587. package/src/components/PillMenu/PillMenu.tsx +324 -0
  588. package/src/components/PillMenu/index.ts +2 -0
  589. package/src/components/Popover/Anchor.tsx +37 -0
  590. package/src/components/Popover/Close.tsx +45 -0
  591. package/src/components/Popover/Content.tsx +213 -0
  592. package/src/components/Popover/Heading.tsx +33 -0
  593. package/src/components/Popover/Popover.module.scss +177 -0
  594. package/src/components/Popover/Popover.tokens.scss +22 -0
  595. package/src/components/Popover/Popover.tsx +23 -0
  596. package/src/components/Popover/PopoverRoot.tsx +75 -0
  597. package/src/components/Popover/Trigger.tsx +86 -0
  598. package/src/components/Popover/context.ts +22 -0
  599. package/src/components/Popover/index.ts +7 -0
  600. package/src/components/Progress/Progress.module.scss +110 -0
  601. package/src/components/Progress/Progress.tokens.scss +44 -0
  602. package/src/components/Progress/Progress.tsx +129 -0
  603. package/src/components/Progress/index.ts +2 -0
  604. package/src/components/QrCode/QrCode.module.scss +97 -0
  605. package/src/components/QrCode/QrCode.tokens.scss +17 -0
  606. package/src/components/QrCode/QrCode.tsx +233 -0
  607. package/src/components/QrCode/index.ts +2 -0
  608. package/src/components/QrCode/qr.ts +161 -0
  609. package/src/components/Radio/Radio.module.scss +175 -0
  610. package/src/components/Radio/Radio.tokens.scss +59 -0
  611. package/src/components/Radio/Radio.tsx +127 -0
  612. package/src/components/Radio/RadioGroup.module.scss +42 -0
  613. package/src/components/Radio/RadioGroup.tsx +120 -0
  614. package/src/components/Radio/RadioGroupContext.tsx +30 -0
  615. package/src/components/Radio/index.ts +4 -0
  616. package/src/components/Rail/Rail.module.scss +510 -0
  617. package/src/components/Rail/Rail.tokens.scss +92 -0
  618. package/src/components/Rail/Rail.tsx +287 -0
  619. package/src/components/Rail/RailCollapseToggle.tsx +57 -0
  620. package/src/components/Rail/RailFooter.tsx +17 -0
  621. package/src/components/Rail/RailGroup.tsx +728 -0
  622. package/src/components/Rail/RailGroupContext.ts +9 -0
  623. package/src/components/Rail/RailHeader.tsx +23 -0
  624. package/src/components/Rail/RailItem.tsx +119 -0
  625. package/src/components/Rail/RailSection.tsx +39 -0
  626. package/src/components/Rail/RailSpacer.tsx +19 -0
  627. package/src/components/Rail/index.ts +9 -0
  628. package/src/components/RelativeDateInput/RelativeDateInput.module.scss +15 -0
  629. package/src/components/RelativeDateInput/RelativeDateInput.tokens.scss +6 -0
  630. package/src/components/RelativeDateInput/RelativeDateInput.tsx +474 -0
  631. package/src/components/RelativeDateInput/index.ts +10 -0
  632. package/src/components/RelativeDateInput/relativeDate.ts +127 -0
  633. package/src/components/RichText/RichText.module.scss +5 -0
  634. package/src/components/RichText/RichText.tsx +70 -0
  635. package/src/components/RichText/RichTextAttachment.module.scss +82 -0
  636. package/src/components/RichText/RichTextAttachment.tsx +122 -0
  637. package/src/components/RichText/_prose.scss +79 -0
  638. package/src/components/RichText/attachmentIcon.tsx +24 -0
  639. package/src/components/RichText/engine/attachment.ts +154 -0
  640. package/src/components/RichText/engine/autolink.ts +64 -0
  641. package/src/components/RichText/engine/blockUnit.ts +174 -0
  642. package/src/components/RichText/engine/colorMarks.ts +85 -0
  643. package/src/components/RichText/engine/escape.ts +11 -0
  644. package/src/components/RichText/engine/fromHtml.ts +353 -0
  645. package/src/components/RichText/engine/fromMarkdown.ts +20 -0
  646. package/src/components/RichText/engine/inlines.ts +82 -0
  647. package/src/components/RichText/engine/listDepths.ts +32 -0
  648. package/src/components/RichText/engine/marks.ts +80 -0
  649. package/src/components/RichText/engine/mdToHtml.ts +178 -0
  650. package/src/components/RichText/engine/model.ts +157 -0
  651. package/src/components/RichText/engine/position.ts +118 -0
  652. package/src/components/RichText/engine/renderDoc.tsx +395 -0
  653. package/src/components/RichText/engine/renderLink.ts +15 -0
  654. package/src/components/RichText/engine/renderMention.ts +16 -0
  655. package/src/components/RichText/engine/safeHref.ts +22 -0
  656. package/src/components/RichText/engine/toHtml.ts +154 -0
  657. package/src/components/RichText/engine/toMarkdown.ts +97 -0
  658. package/src/components/RichText/engine/transforms.ts +434 -0
  659. package/src/components/RichText/imageMaxHeightStyle.ts +10 -0
  660. package/src/components/RichText/index.ts +31 -0
  661. package/src/components/RichTextEditor/RichTextAttachmentConfig.tsx +264 -0
  662. package/src/components/RichTextEditor/RichTextBlockControls.tsx +365 -0
  663. package/src/components/RichTextEditor/RichTextBlockMenu.tsx +162 -0
  664. package/src/components/RichTextEditor/RichTextColorMenu.tsx +115 -0
  665. package/src/components/RichTextEditor/RichTextEditor.module.scss +298 -0
  666. package/src/components/RichTextEditor/RichTextEditor.tsx +1910 -0
  667. package/src/components/RichTextEditor/RichTextImageResizer.tsx +131 -0
  668. package/src/components/RichTextEditor/RichTextLinkEditor.tsx +151 -0
  669. package/src/components/RichTextEditor/RichTextMentionMenu.tsx +99 -0
  670. package/src/components/RichTextEditor/RichTextToolbar.tsx +379 -0
  671. package/src/components/RichTextEditor/autolinkInput.ts +65 -0
  672. package/src/components/RichTextEditor/blockDrop.ts +9 -0
  673. package/src/components/RichTextEditor/blockReflow.ts +62 -0
  674. package/src/components/RichTextEditor/commands.ts +300 -0
  675. package/src/components/RichTextEditor/history.ts +93 -0
  676. package/src/components/RichTextEditor/icons.tsx +152 -0
  677. package/src/components/RichTextEditor/imageSize.ts +70 -0
  678. package/src/components/RichTextEditor/index.ts +5 -0
  679. package/src/components/RichTextEditor/input.ts +209 -0
  680. package/src/components/RichTextEditor/inputRules.ts +71 -0
  681. package/src/components/RichTextEditor/links.ts +103 -0
  682. package/src/components/RichTextEditor/mentionContext.ts +37 -0
  683. package/src/components/RichTextEditor/mentions.ts +28 -0
  684. package/src/components/RichTextEditor/preventSelectionLoss.ts +15 -0
  685. package/src/components/RichTextEditor/selection.ts +415 -0
  686. package/src/components/RichTextEditor/shortcuts.ts +44 -0
  687. package/src/components/RichTextEditor/useAnchoredFloating.ts +50 -0
  688. package/src/components/RichTextEditor/useAttachmentConfig.ts +134 -0
  689. package/src/components/RichTextEditor/useDismissOnOutsidePointerDown.ts +26 -0
  690. package/src/components/RichTextEditor/useLinkEditor.ts +107 -0
  691. package/src/components/RichTextEditor/useMention.ts +226 -0
  692. package/src/components/RichTextEditor/useOverlayRect.ts +73 -0
  693. package/src/components/RichTextEditor/useUpload.ts +246 -0
  694. package/src/components/Screen/Screen.module.scss +46 -0
  695. package/src/components/Screen/Screen.tokens.scss +20 -0
  696. package/src/components/Screen/Screen.tsx +97 -0
  697. package/src/components/Screen/index.ts +2 -0
  698. package/src/components/ScrollArea/ScrollArea.module.scss +39 -0
  699. package/src/components/ScrollArea/ScrollArea.tokens.scss +15 -0
  700. package/src/components/ScrollArea/ScrollArea.tsx +154 -0
  701. package/src/components/ScrollArea/index.ts +2 -0
  702. package/src/components/Select/Chip.tsx +45 -0
  703. package/src/components/Select/Empty.tsx +39 -0
  704. package/src/components/Select/Error.tsx +51 -0
  705. package/src/components/Select/HiddenInputs.tsx +44 -0
  706. package/src/components/Select/Listbox.tsx +557 -0
  707. package/src/components/Select/Loading.tsx +30 -0
  708. package/src/components/Select/Select.module.scss +512 -0
  709. package/src/components/Select/Select.tokens.scss +140 -0
  710. package/src/components/Select/Select.tsx +685 -0
  711. package/src/components/Select/Trigger.tsx +952 -0
  712. package/src/components/Select/context.ts +101 -0
  713. package/src/components/Select/emptyStateText.ts +19 -0
  714. package/src/components/Select/index.ts +9 -0
  715. package/src/components/Select/useSelectState.ts +157 -0
  716. package/src/components/Select/utils-types.ts +7 -0
  717. package/src/components/Select/utils.ts +122 -0
  718. package/src/components/SettingRow/SettingRow.module.scss +166 -0
  719. package/src/components/SettingRow/SettingRow.tokens.scss +37 -0
  720. package/src/components/SettingRow/SettingRow.tsx +242 -0
  721. package/src/components/SettingRow/index.ts +7 -0
  722. package/src/components/Skeleton/Skeleton.module.scss +55 -0
  723. package/src/components/Skeleton/Skeleton.tokens.scss +17 -0
  724. package/src/components/Skeleton/Skeleton.tsx +131 -0
  725. package/src/components/Skeleton/index.ts +4 -0
  726. package/src/components/Skeleton/useSkeletonVisibility.ts +95 -0
  727. package/src/components/Slider/Slider.module.scss +293 -0
  728. package/src/components/Slider/Slider.tokens.scss +98 -0
  729. package/src/components/Slider/Slider.tsx +624 -0
  730. package/src/components/Slider/index.ts +9 -0
  731. package/src/components/SlotGrid/SlotGrid.module.scss +61 -0
  732. package/src/components/SlotGrid/SlotGrid.tokens.scss +21 -0
  733. package/src/components/SlotGrid/SlotGrid.tsx +111 -0
  734. package/src/components/SlotGrid/index.ts +2 -0
  735. package/src/components/SocialButton/SocialButton.module.scss +4 -0
  736. package/src/components/SocialButton/SocialButton.tsx +40 -0
  737. package/src/components/SocialButton/index.ts +2 -0
  738. package/src/components/Sortable/Sortable.module.scss +177 -0
  739. package/src/components/Sortable/Sortable.tokens.scss +27 -0
  740. package/src/components/Sortable/Sortable.tsx +572 -0
  741. package/src/components/Sortable/containerAwareCollision.ts +125 -0
  742. package/src/components/Sortable/index.ts +13 -0
  743. package/src/components/SortableGroup/SortableGroup.module.scss +23 -0
  744. package/src/components/SortableGroup/SortableGroup.tsx +315 -0
  745. package/src/components/SortableGroup/index.ts +4 -0
  746. package/src/components/SortableGroup/moveSortableItem.ts +39 -0
  747. package/src/components/Sparkline/Sparkline.module.scss +28 -0
  748. package/src/components/Sparkline/Sparkline.tokens.scss +7 -0
  749. package/src/components/Sparkline/Sparkline.tsx +133 -0
  750. package/src/components/Sparkline/index.ts +2 -0
  751. package/src/components/Sparkline/sparklineModel.ts +119 -0
  752. package/src/components/Split/Split.module.scss +158 -0
  753. package/src/components/Split/Split.tokens.scss +10 -0
  754. package/src/components/Split/Split.tsx +231 -0
  755. package/src/components/Split/index.ts +2 -0
  756. package/src/components/Stack/Stack.module.scss +67 -0
  757. package/src/components/Stack/Stack.tokens.scss +11 -0
  758. package/src/components/Stack/Stack.tsx +100 -0
  759. package/src/components/Stack/index.ts +2 -0
  760. package/src/components/StagePath/StagePath.module.scss +255 -0
  761. package/src/components/StagePath/StagePath.tokens.scss +43 -0
  762. package/src/components/StagePath/StagePath.tsx +176 -0
  763. package/src/components/StagePath/index.ts +2 -0
  764. package/src/components/StatGroup/StatGroup.module.scss +6 -0
  765. package/src/components/StatGroup/StatGroup.tsx +70 -0
  766. package/src/components/StatGroup/StatGroupContext.ts +10 -0
  767. package/src/components/StatGroup/StatTile.module.scss +99 -0
  768. package/src/components/StatGroup/StatTile.tokens.scss +35 -0
  769. package/src/components/StatGroup/StatTile.tsx +143 -0
  770. package/src/components/StatGroup/index.ts +4 -0
  771. package/src/components/Sticky/Sticky.module.scss +98 -0
  772. package/src/components/Sticky/Sticky.tokens.scss +17 -0
  773. package/src/components/Sticky/Sticky.tsx +103 -0
  774. package/src/components/Sticky/index.ts +2 -0
  775. package/src/components/Switch/Switch.module.scss +182 -0
  776. package/src/components/Switch/Switch.tokens.scss +59 -0
  777. package/src/components/Switch/Switch.tsx +214 -0
  778. package/src/components/Switch/index.ts +2 -0
  779. package/src/components/Table/Table.module.scss +308 -0
  780. package/src/components/Table/Table.tokens.scss +79 -0
  781. package/src/components/Table/Table.tsx +381 -0
  782. package/src/components/Table/index.ts +15 -0
  783. package/src/components/TableOfContents/TableOfContents.module.scss +83 -0
  784. package/src/components/TableOfContents/TableOfContents.tokens.scss +26 -0
  785. package/src/components/TableOfContents/TableOfContents.tsx +192 -0
  786. package/src/components/TableOfContents/activeSection.ts +18 -0
  787. package/src/components/TableOfContents/index.ts +2 -0
  788. package/src/components/Tabs/Tabs.module.scss +359 -0
  789. package/src/components/Tabs/Tabs.tokens.scss +50 -0
  790. package/src/components/Tabs/Tabs.tsx +538 -0
  791. package/src/components/Tabs/index.ts +2 -0
  792. package/src/components/Text/Text.module.scss +115 -0
  793. package/src/components/Text/Text.tokens.scss +55 -0
  794. package/src/components/Text/Text.tsx +197 -0
  795. package/src/components/Text/index.ts +2 -0
  796. package/src/components/Textarea/Textarea.module.scss +94 -0
  797. package/src/components/Textarea/Textarea.tokens.scss +48 -0
  798. package/src/components/Textarea/Textarea.tsx +246 -0
  799. package/src/components/Textarea/index.ts +2 -0
  800. package/src/components/Thread/Thread.module.scss +161 -0
  801. package/src/components/Thread/Thread.tokens.scss +32 -0
  802. package/src/components/Thread/Thread.tsx +176 -0
  803. package/src/components/Thread/index.ts +2 -0
  804. package/src/components/TimeField/TimeField.module.scss +232 -0
  805. package/src/components/TimeField/TimeField.tsx +793 -0
  806. package/src/components/TimeField/index.ts +2 -0
  807. package/src/components/Timeline/Timeline.module.scss +58 -0
  808. package/src/components/Timeline/Timeline.tokens.scss +13 -0
  809. package/src/components/Timeline/Timeline.tsx +53 -0
  810. package/src/components/Timeline/index.ts +2 -0
  811. package/src/components/Title/Title.module.scss +84 -0
  812. package/src/components/Title/Title.tokens.scss +37 -0
  813. package/src/components/Title/Title.tsx +150 -0
  814. package/src/components/Title/index.ts +2 -0
  815. package/src/components/Toast/Toast.module.scss +299 -0
  816. package/src/components/Toast/Toast.tokens.scss +65 -0
  817. package/src/components/Toast/Toast.tsx +122 -0
  818. package/src/components/Toast/ToastViewport.tsx +166 -0
  819. package/src/components/Toast/api.ts +175 -0
  820. package/src/components/Toast/index.ts +5 -0
  821. package/src/components/Toast/store.ts +133 -0
  822. package/src/components/Toast/useToastTimer.ts +94 -0
  823. package/src/components/Tooltip/Tooltip.module.scss +99 -0
  824. package/src/components/Tooltip/Tooltip.tokens.scss +23 -0
  825. package/src/components/Tooltip/Tooltip.tsx +341 -0
  826. package/src/components/Tooltip/index.ts +2 -0
  827. package/src/components/TopBar/TopBar.module.scss +235 -0
  828. package/src/components/TopBar/TopBar.tokens.scss +79 -0
  829. package/src/components/TopBar/TopBar.tsx +87 -0
  830. package/src/components/TopBar/TopBarEnd.tsx +20 -0
  831. package/src/components/TopBar/TopBarIconButton.tsx +86 -0
  832. package/src/components/TopBar/TopBarSearch.tsx +319 -0
  833. package/src/components/TopBar/TopBarSearchPanel.tsx +268 -0
  834. package/src/components/TopBar/TopBarStart.tsx +20 -0
  835. package/src/components/TopBar/index.ts +11 -0
  836. package/src/components/Tour/Spotlight.tsx +121 -0
  837. package/src/components/Tour/Tour.module.scss +210 -0
  838. package/src/components/Tour/Tour.tokens.scss +58 -0
  839. package/src/components/Tour/Tour.tsx +617 -0
  840. package/src/components/Tour/index.ts +2 -0
  841. package/src/components/Tour/useTourTarget.ts +115 -0
  842. package/src/components/TreeView/TreeView.module.scss +268 -0
  843. package/src/components/TreeView/TreeView.tokens.scss +36 -0
  844. package/src/components/TreeView/TreeView.tsx +536 -0
  845. package/src/components/TreeView/index.ts +3 -0
  846. package/src/components/TreeView/treeModel.ts +224 -0
  847. package/src/components/VisuallyHidden/VisuallyHidden.module.scss +7 -0
  848. package/src/components/VisuallyHidden/VisuallyHidden.tsx +29 -0
  849. package/src/components/VisuallyHidden/index.ts +2 -0
  850. package/src/components/WidgetPreview/WidgetPreview.module.scss +11 -0
  851. package/src/components/WidgetPreview/WidgetPreview.tokens.scss +26 -0
  852. package/src/components/WidgetPreview/WidgetPreview.tsx +36 -0
  853. package/src/components/WidgetPreview/WidgetShape.module.scss +140 -0
  854. package/src/components/WidgetPreview/WidgetShape.tsx +159 -0
  855. package/src/components/WidgetPreview/index.ts +2 -0
  856. package/src/components/_internal/Trend.tsx +27 -0
  857. package/src/components/_internal/choiceTile.scss +74 -0
  858. package/src/components/_internal/collapse.scss +10 -0
  859. package/src/components/_internal/collapse.ts +58 -0
  860. package/src/components/_internal/currency.ts +257 -0
  861. package/src/components/_internal/dragAnnouncements.ts +200 -0
  862. package/src/components/_internal/fieldWiring.ts +225 -0
  863. package/src/components/_internal/gridSpan.ts +54 -0
  864. package/src/components/_internal/isoDay.ts +35 -0
  865. package/src/components/_internal/letterKey.ts +26 -0
  866. package/src/components/_internal/overlay/focusRestore.ts +21 -0
  867. package/src/components/_internal/overlay/index.ts +12 -0
  868. package/src/components/_internal/overlay/tourHold.ts +23 -0
  869. package/src/components/_internal/overlay/useFocusTrap.ts +120 -0
  870. package/src/components/_internal/overlay/useInOverlay.ts +81 -0
  871. package/src/components/_internal/overlay/useOverlayStack.ts +232 -0
  872. package/src/components/_internal/overlay/useScrollLock.ts +112 -0
  873. package/src/components/_internal/refs.ts +48 -0
  874. package/src/components/_internal/statusColor.ts +26 -0
  875. package/src/components/_internal/timeUtils.ts +23 -0
  876. package/src/components/_internal/useAsyncOptions.ts +145 -0
  877. package/src/components/_internal/useClippedTooltip.ts +50 -0
  878. package/src/components/_internal/useControllableState.ts +50 -0
  879. package/src/components.manifest.json +1141 -0
  880. package/src/hooks/useBelowBreakpoint.ts +58 -0
  881. package/src/i18n/I18nProvider.tsx +52 -0
  882. package/src/i18n/LocaleProvider.tsx +17 -0
  883. package/src/i18n/en.ts +648 -0
  884. package/src/i18n/format.ts +71 -0
  885. package/src/i18n/index.ts +13 -0
  886. package/src/i18n/messages.ts +1275 -0
  887. package/src/i18n/ru.ts +677 -0
  888. package/src/i18n/useLocale.ts +19 -0
  889. package/src/i18n/useTranslation.ts +58 -0
  890. package/src/index.ts +913 -0
  891. package/src/palette/index.ts +2 -0
  892. package/src/palette/palette.ts +108 -0
  893. package/src/styles/dark.scss +4 -0
  894. package/src/styles/global.scss +7 -0
  895. package/src/styles/mixins.scss +143 -0
  896. package/src/styles/reset.scss +78 -0
  897. package/src/styles/tokens.scss +18 -0
  898. package/src/styles/typography.scss +44 -0
@@ -0,0 +1,46 @@
1
+ import { Maximize, ZoomIn, ZoomOut } from 'lucide-react';
2
+ import { Button } from '../Button';
3
+ import { useTranslation } from '../../i18n/useTranslation';
4
+ import styles from './FlowCanvas.module.scss';
5
+
6
+ interface FlowControlsProps {
7
+ onZoomIn: () => void;
8
+ onZoomOut: () => void;
9
+ onFit: () => void;
10
+ }
11
+
12
+ /** Internal: the bottom-left zoom control cluster. */
13
+ export function FlowControls({ onZoomIn, onZoomOut, onFit }: FlowControlsProps) {
14
+ const t = useTranslation();
15
+ return (
16
+ <div className={styles.controls} data-flow-controls="">
17
+ <Button
18
+ variant="secondary"
19
+ size="sm"
20
+ iconOnly
21
+ aria-label={t('flowCanvas.zoomIn')}
22
+ onClick={onZoomIn}
23
+ >
24
+ <ZoomIn size={16} aria-hidden="true" />
25
+ </Button>
26
+ <Button
27
+ variant="secondary"
28
+ size="sm"
29
+ iconOnly
30
+ aria-label={t('flowCanvas.zoomOut')}
31
+ onClick={onZoomOut}
32
+ >
33
+ <ZoomOut size={16} aria-hidden="true" />
34
+ </Button>
35
+ <Button
36
+ variant="secondary"
37
+ size="sm"
38
+ iconOnly
39
+ aria-label={t('flowCanvas.zoomToFit')}
40
+ onClick={onFit}
41
+ >
42
+ <Maximize size={16} aria-hidden="true" />
43
+ </Button>
44
+ </div>
45
+ );
46
+ }
@@ -0,0 +1,58 @@
1
+ import { memo } from 'react';
2
+ import type { MouseEvent as ReactMouseEvent, PointerEvent as ReactPointerEvent } from 'react';
3
+ import type { EdgeGeometry } from './edgePath';
4
+ import type { FlowCanvasEdge } from './types';
5
+ import styles from './FlowCanvas.module.scss';
6
+
7
+ interface FlowEdgeProps {
8
+ edge: FlowCanvasEdge;
9
+ geometry: EdgeGeometry;
10
+ active: boolean; // selected or focused — thicker accent stroke
11
+ markerId: string;
12
+ markerActiveId: string;
13
+ ariaLabel: string;
14
+ roleDescription: string;
15
+ registerEl: (id: string, el: SVGPathElement | null) => void;
16
+ onEdgePointerDown: (id: string, event: ReactPointerEvent<SVGPathElement>) => void;
17
+ onEdgeDoubleClick: (id: string, event: ReactMouseEvent<SVGPathElement>) => void;
18
+ }
19
+
20
+ /** Internal: one edge — visible path plus a wide transparent hit/focus path. */
21
+ export const FlowEdge = memo(function FlowEdge({
22
+ edge,
23
+ geometry,
24
+ active,
25
+ markerId,
26
+ markerActiveId,
27
+ ariaLabel,
28
+ roleDescription,
29
+ registerEl,
30
+ onEdgePointerDown,
31
+ onEdgeDoubleClick,
32
+ }: FlowEdgeProps) {
33
+ return (
34
+ <g>
35
+ <path
36
+ className={styles.edgePath}
37
+ d={geometry.path}
38
+ data-active={active || undefined}
39
+ markerEnd={`url(#${active ? markerActiveId : markerId})`}
40
+ />
41
+ <path
42
+ ref={(el) => registerEl(edge.id, el)}
43
+ className={styles.edgeHit}
44
+ d={geometry.path}
45
+ role="button"
46
+ tabIndex={-1}
47
+ aria-roledescription={roleDescription}
48
+ aria-label={ariaLabel}
49
+ data-flow-edge={edge.id}
50
+ onPointerDown={(event) => onEdgePointerDown(edge.id, event)}
51
+ onDoubleClick={(event) => {
52
+ event.stopPropagation();
53
+ onEdgeDoubleClick(edge.id, event);
54
+ }}
55
+ />
56
+ </g>
57
+ );
58
+ });
@@ -0,0 +1,76 @@
1
+ import { memo } from 'react';
2
+ import type {
3
+ CSSProperties,
4
+ MouseEvent as ReactMouseEvent,
5
+ PointerEvent as ReactPointerEvent,
6
+ } from 'react';
7
+ import type { FlowCanvasNode, FlowCanvasPoint } from './types';
8
+ import styles from './FlowCanvas.module.scss';
9
+
10
+ interface FlowNodeProps {
11
+ node: FlowCanvasNode;
12
+ position: FlowCanvasPoint;
13
+ selected: boolean;
14
+ dragging: boolean;
15
+ connectTarget: boolean;
16
+ /** Whether connecting is enabled — gates the connect handle. */
17
+ canConnect: boolean;
18
+ roleDescription: string;
19
+ registerEl: (id: string, el: HTMLDivElement | null) => void;
20
+ onNodePointerDown: (id: string, event: ReactPointerEvent<HTMLDivElement>) => void;
21
+ onNodeDoubleClick: (id: string, event: ReactMouseEvent<HTMLDivElement>) => void;
22
+ onHandlePointerDown: (id: string, event: ReactPointerEvent<HTMLElement>) => void;
23
+ }
24
+
25
+ /** Internal: one node card. Positioned absolutely on the stage. */
26
+ export const FlowNode = memo(function FlowNode({
27
+ node,
28
+ position,
29
+ selected,
30
+ dragging,
31
+ connectTarget,
32
+ canConnect,
33
+ roleDescription,
34
+ registerEl,
35
+ onNodePointerDown,
36
+ onNodeDoubleClick,
37
+ onHandlePointerDown,
38
+ }: FlowNodeProps) {
39
+ const style: CSSProperties = { left: position.x, top: position.y };
40
+ if (node.color) (style as Record<string, string | number>)['--flow-node-color'] = node.color;
41
+ return (
42
+ // role=button: activatable via Enter (open); roledescription localizes "node".
43
+ <div
44
+ ref={(el) => registerEl(node.id, el)}
45
+ role="button"
46
+ tabIndex={-1}
47
+ aria-roledescription={roleDescription}
48
+ aria-label={node.label}
49
+ data-flow-node={node.id}
50
+ data-selected={selected || undefined}
51
+ data-dragging={dragging || undefined}
52
+ data-connect-target={connectTarget || undefined}
53
+ className={styles.node}
54
+ style={style}
55
+ onPointerDown={(event) => onNodePointerDown(node.id, event)}
56
+ onDoubleClick={(event) => {
57
+ event.stopPropagation();
58
+ onNodeDoubleClick(node.id, event);
59
+ }}
60
+ >
61
+ <span className={styles.nodeLabel}>{node.label}</span>
62
+ {node.adornment != null ? <span>{node.adornment}</span> : null}
63
+ {canConnect ? (
64
+ <span
65
+ aria-hidden="true"
66
+ className={styles.handle}
67
+ data-flow-handle=""
68
+ onPointerDown={(event) => {
69
+ event.stopPropagation();
70
+ onHandlePointerDown(node.id, event);
71
+ }}
72
+ />
73
+ ) : null}
74
+ </div>
75
+ );
76
+ });
@@ -0,0 +1,85 @@
1
+ /** Axis-aligned rectangle in canvas coordinates. */
2
+ export interface Rect {
3
+ x: number;
4
+ y: number;
5
+ width: number;
6
+ height: number;
7
+ }
8
+
9
+ /** Point in canvas coordinates. */
10
+ export interface Point {
11
+ x: number;
12
+ y: number;
13
+ }
14
+
15
+ /** SVG path plus the chip anchor point for one edge. */
16
+ export interface EdgeGeometry {
17
+ /** `d` attribute for the SVG `<path>`. */
18
+ path: string;
19
+ /** True cubic midpoint (t = 0.5) — where the label chip is anchored. */
20
+ midpoint: Point;
21
+ /** Source anchor point (on the source node's facing side). */
22
+ source: Point;
23
+ /** Target anchor point (on the target node's facing side). */
24
+ target: Point;
25
+ }
26
+
27
+ const MIN_STRENGTH = 40; // minimum control-point pull so short edges still curve
28
+ const PAIR_SHIFT = 8; // endpoint offset when a reverse edge exists
29
+ const PAIR_BOW = 24; // extra control-point bow for reverse pairs
30
+
31
+ function cubic(p0: Point, c1: Point, c2: Point, p3: Point): EdgeGeometry {
32
+ return {
33
+ path: `M ${p0.x} ${p0.y} C ${c1.x} ${c1.y}, ${c2.x} ${c2.y}, ${p3.x} ${p3.y}`,
34
+ // De Casteljau at t = 0.5: (p0 + 3·c1 + 3·c2 + p3) / 8
35
+ midpoint: {
36
+ x: (p0.x + 3 * c1.x + 3 * c2.x + p3.x) / 8,
37
+ y: (p0.y + 3 * c1.y + 3 * c2.y + p3.y) / 8,
38
+ },
39
+ source: p0,
40
+ target: p3,
41
+ };
42
+ }
43
+
44
+ /**
45
+ * Bezier between two node rects. Anchors on the facing sides (horizontal when
46
+ * |dx| ≥ |dy|, else vertical). `curvature` (±1) separates an A→B / B→A pair:
47
+ * pass opposite signs so the two edges bow apart; 0 for a lone edge.
48
+ */
49
+ export function edgeGeometry(source: Rect, target: Rect, curvature: -1 | 0 | 1 = 0): EdgeGeometry {
50
+ const sc = { x: source.x + source.width / 2, y: source.y + source.height / 2 };
51
+ const tc = { x: target.x + target.width / 2, y: target.y + target.height / 2 };
52
+ const dx = tc.x - sc.x;
53
+ const dy = tc.y - sc.y;
54
+ const bow = curvature * PAIR_BOW;
55
+
56
+ if (Math.abs(dx) >= Math.abs(dy)) {
57
+ const sign = dx >= 0 ? 1 : -1;
58
+ const p0 = { x: sc.x + (sign * source.width) / 2, y: sc.y + curvature * PAIR_SHIFT };
59
+ const p3 = { x: tc.x - (sign * target.width) / 2, y: tc.y + curvature * PAIR_SHIFT };
60
+ const strength = Math.max(MIN_STRENGTH, Math.abs(p3.x - p0.x) / 2);
61
+ return cubic(
62
+ p0,
63
+ { x: p0.x + sign * strength, y: p0.y + bow },
64
+ { x: p3.x - sign * strength, y: p3.y + bow },
65
+ p3,
66
+ );
67
+ }
68
+ const sign = dy >= 0 ? 1 : -1;
69
+ const p0 = { x: sc.x + curvature * PAIR_SHIFT, y: sc.y + (sign * source.height) / 2 };
70
+ const p3 = { x: tc.x + curvature * PAIR_SHIFT, y: tc.y - (sign * target.height) / 2 };
71
+ const strength = Math.max(MIN_STRENGTH, Math.abs(p3.y - p0.y) / 2);
72
+ return cubic(
73
+ p0,
74
+ { x: p0.x + bow, y: p0.y + sign * strength },
75
+ { x: p3.x + bow, y: p3.y - sign * strength },
76
+ p3,
77
+ );
78
+ }
79
+
80
+ /** Small loop arcing over a node's top-right corner, for self-referencing edges. */
81
+ export function selfLoopGeometry(rect: Rect): EdgeGeometry {
82
+ const p0 = { x: rect.x + rect.width * 0.75, y: rect.y };
83
+ const p3 = { x: rect.x + rect.width, y: rect.y + rect.height * 0.25 };
84
+ return cubic(p0, { x: p0.x + 10, y: p0.y - 48 }, { x: p3.x + 48, y: p3.y - 10 }, p3);
85
+ }
@@ -0,0 +1,4 @@
1
+ export { FlowCanvas } from './FlowCanvas';
2
+ export { arrangeNodes } from './layout';
3
+ export type { FlowCanvasProps } from './FlowCanvas';
4
+ export type { FlowCanvasPoint, FlowCanvasNode, FlowCanvasEdge, FlowCanvasSelection } from './types';
@@ -0,0 +1,148 @@
1
+ import type { FlowCanvasEdge, FlowCanvasNode, FlowCanvasPoint } from './types';
2
+
3
+ /** Measured (or estimated) rendered size of a node, in canvas units. */
4
+ export interface NodeSize {
5
+ width: number;
6
+ height: number;
7
+ }
8
+
9
+ /** Fallback node size used before ResizeObserver reports real ones (and in jsdom). */
10
+ export const ESTIMATED_NODE_SIZE: NodeSize = { width: 160, height: 40 };
11
+
12
+ const RANK_GAP = 96; // horizontal gap between rank columns
13
+ const NODE_GAP = 32; // vertical gap between nodes within a rank
14
+
15
+ /**
16
+ * Layered auto-layout: longest-path ranks from the graph's sources flow
17
+ * left → right; one barycenter pass orders nodes within a rank to reduce edge
18
+ * crossings; ranks are vertically centered against the tallest rank.
19
+ * Pure, deterministic, and cycle-safe (back-edges to on-stack nodes are
20
+ * skipped). Self-loops and edges to unknown nodes are ignored.
21
+ * Only nodes without an explicit `position` are laid out; a node WITH a
22
+ * `position` is pinned by the consumer and is ignored here — it neither
23
+ * occupies layout space nor anchors edges, so it never shifts the others.
24
+ */
25
+ export function computeLayout(
26
+ nodes: readonly FlowCanvasNode[],
27
+ edges: readonly FlowCanvasEdge[],
28
+ sizes?: ReadonlyMap<string, NodeSize>,
29
+ ): Map<string, FlowCanvasPoint> {
30
+ const result = new Map<string, FlowCanvasPoint>();
31
+ if (nodes.length === 0) return result;
32
+
33
+ // Only nodes WITHOUT an explicit position participate in auto-layout. Pinned
34
+ // nodes are placed by the consumer and must not perturb the others' ranking
35
+ // or centering; edges touching a pinned node fall through the unknown-node
36
+ // guard below (the pinned id is absent from `ids`).
37
+ const autoNodes = nodes.filter((node) => node.position === undefined);
38
+ if (autoNodes.length === 0) return result;
39
+
40
+ const ids = new Set(autoNodes.map((node) => node.id));
41
+ const out = new Map<string, string[]>();
42
+ const incoming = new Map<string, string[]>();
43
+ const indegree = new Map<string, number>();
44
+ for (const node of autoNodes) {
45
+ out.set(node.id, []);
46
+ incoming.set(node.id, []);
47
+ indegree.set(node.id, 0);
48
+ }
49
+ for (const edge of edges) {
50
+ if (!ids.has(edge.from) || !ids.has(edge.to) || edge.from === edge.to) continue;
51
+ out.get(edge.from)!.push(edge.to);
52
+ incoming.get(edge.to)!.push(edge.from);
53
+ indegree.set(edge.to, indegree.get(edge.to)! + 1);
54
+ }
55
+
56
+ // Longest-path ranks, cycle-safe.
57
+ const rank = new Map<string, number>();
58
+ const onStack = new Set<string>();
59
+ const visit = (id: string, r: number): void => {
60
+ if (onStack.has(id)) return; // back-edge in a cycle
61
+ const prev = rank.get(id);
62
+ if (prev !== undefined && prev >= r) return;
63
+ rank.set(id, r);
64
+ onStack.add(id);
65
+ for (const next of out.get(id)!) visit(next, r + 1);
66
+ onStack.delete(id);
67
+ };
68
+ const sources = autoNodes.filter((node) => indegree.get(node.id) === 0);
69
+ for (const source of sources.length > 0 ? sources : [autoNodes[0]]) visit(source.id, 0);
70
+ // Cycle components unreachable from any source: seed a DFS from each still-
71
+ // unranked node so their internal edges keep flowing left → right.
72
+ for (const node of autoNodes) if (!rank.has(node.id)) visit(node.id, 0);
73
+
74
+ // Bucket by rank in input order.
75
+ const ranks: FlowCanvasNode[][] = [];
76
+ for (const node of autoNodes) {
77
+ const r = rank.get(node.id)!;
78
+ (ranks[r] ??= []).push(node);
79
+ }
80
+ const orderIndex = new Map<string, number>();
81
+ for (const bucket of ranks) bucket?.forEach((node, i) => orderIndex.set(node.id, i));
82
+
83
+ // One barycenter pass: order each rank by the average order of predecessors.
84
+ for (let r = 1; r < ranks.length; r++) {
85
+ const bucket = ranks[r];
86
+ if (!bucket) continue;
87
+ const score = (node: FlowCanvasNode): number => {
88
+ const preds = incoming.get(node.id)!;
89
+ if (preds.length === 0) return orderIndex.get(node.id)!;
90
+ return preds.reduce((sum, p) => sum + (orderIndex.get(p) ?? 0), 0) / preds.length;
91
+ };
92
+ bucket.sort((a, b) => score(a) - score(b) || orderIndex.get(a.id)! - orderIndex.get(b.id)!);
93
+ bucket.forEach((node, i) => orderIndex.set(node.id, i));
94
+ }
95
+
96
+ // Position: x per rank column, y stacked and centered per rank.
97
+ const sizeOf = (id: string): NodeSize => sizes?.get(id) ?? ESTIMATED_NODE_SIZE;
98
+ const rankHeights = ranks.map((bucket) =>
99
+ (bucket ?? []).reduce(
100
+ (sum, node, i) => sum + sizeOf(node.id).height + (i > 0 ? NODE_GAP : 0),
101
+ 0,
102
+ ),
103
+ );
104
+ const maxHeight = Math.max(0, ...rankHeights);
105
+ let x = 0;
106
+ for (let r = 0; r < ranks.length; r++) {
107
+ const bucket = ranks[r] ?? [];
108
+ let y = (maxHeight - (rankHeights[r] ?? 0)) / 2;
109
+ let maxWidth = 0;
110
+ for (const node of bucket) {
111
+ result.set(node.id, { x, y });
112
+ y += sizeOf(node.id).height + NODE_GAP;
113
+ maxWidth = Math.max(maxWidth, sizeOf(node.id).width);
114
+ }
115
+ x += (maxWidth || ESTIMATED_NODE_SIZE.width) + RANK_GAP;
116
+ }
117
+ return result;
118
+ }
119
+
120
+ /**
121
+ * Lay out every node into the layered left→right auto-layout and return the
122
+ * nodes with `position` filled in — for a consumer-driven "re-arrange / tidy"
123
+ * action. Unlike {@link computeLayout} (which only places nodes without an
124
+ * explicit `position`), this re-flows ALL nodes, overwriting any existing
125
+ * `position`. Pure and deterministic; every other node field is preserved.
126
+ *
127
+ * Uses estimated node sizes, so vertical centering can differ by a few pixels
128
+ * from the live in-canvas layout (a standalone function cannot measure the
129
+ * rendered DOM). Fine for a tidy action.
130
+ *
131
+ * @example
132
+ * // A "Re-arrange" button in your own UI (e.g. the FlowCanvas `controls` slot):
133
+ * <Button onClick={() => setNodes((prev) => arrangeNodes(prev, edges))}>Re-arrange</Button>
134
+ */
135
+ export function arrangeNodes(
136
+ nodes: readonly FlowCanvasNode[],
137
+ edges: readonly FlowCanvasEdge[],
138
+ ): FlowCanvasNode[] {
139
+ // Strip positions so the whole graph is treated as auto and re-laid-out.
140
+ const layout = computeLayout(
141
+ nodes.map((node) => ({ ...node, position: undefined })),
142
+ edges,
143
+ );
144
+ return nodes.map((node) => {
145
+ const position = layout.get(node.id);
146
+ return position ? { ...node, position } : node;
147
+ });
148
+ }
@@ -0,0 +1,76 @@
1
+ import type { Rect } from './edgePath';
2
+
3
+ /** Arrow-key direction for spatial node navigation. */
4
+ export type NavDirection = 'up' | 'down' | 'left' | 'right';
5
+
6
+ function center(rect: Rect): { x: number; y: number } {
7
+ return { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 };
8
+ }
9
+
10
+ /**
11
+ * Nearest node in an arrow direction, judged by rect centers. Candidates must
12
+ * lie strictly in that direction; off-axis distance is penalized 2× so
13
+ * aligned neighbors win over closer diagonal ones. Returns null when nothing
14
+ * lies that way.
15
+ */
16
+ export function nearestInDirection(
17
+ currentId: string,
18
+ rects: ReadonlyMap<string, Rect>,
19
+ direction: NavDirection,
20
+ ): string | null {
21
+ const current = rects.get(currentId);
22
+ if (!current) return null;
23
+ const cc = center(current);
24
+ let best: string | null = null;
25
+ let bestScore = Infinity;
26
+ for (const [id, rect] of rects) {
27
+ if (id === currentId) continue;
28
+ const c = center(rect);
29
+ const dx = c.x - cc.x;
30
+ const dy = c.y - cc.y;
31
+ let primary: number;
32
+ let secondary: number;
33
+ switch (direction) {
34
+ case 'right':
35
+ primary = dx;
36
+ secondary = Math.abs(dy);
37
+ break;
38
+ case 'left':
39
+ primary = -dx;
40
+ secondary = Math.abs(dy);
41
+ break;
42
+ case 'down':
43
+ primary = dy;
44
+ secondary = Math.abs(dx);
45
+ break;
46
+ case 'up':
47
+ primary = -dy;
48
+ secondary = Math.abs(dx);
49
+ break;
50
+ }
51
+ if (primary <= 0.5) continue;
52
+ const score = primary + secondary * 2;
53
+ if (score < bestScore) {
54
+ bestScore = score;
55
+ best = id;
56
+ }
57
+ }
58
+ return best;
59
+ }
60
+
61
+ /** Topmost node, ties broken by leftmost — the initial arrow-key focus target. */
62
+ export function topLeftMost(rects: ReadonlyMap<string, Rect>): string | null {
63
+ let best: string | null = null;
64
+ let bestRect: Rect | null = null;
65
+ for (const [id, rect] of rects) {
66
+ if (
67
+ bestRect === null ||
68
+ rect.y < bestRect.y ||
69
+ (rect.y === bestRect.y && rect.x < bestRect.x)
70
+ ) {
71
+ best = id;
72
+ bestRect = rect;
73
+ }
74
+ }
75
+ return best;
76
+ }
@@ -0,0 +1,59 @@
1
+ import type { ReactNode } from 'react';
2
+
3
+ /** A point in canvas coordinates (px at zoom 1, origin at the stage's top-left). */
4
+ export interface FlowCanvasPoint {
5
+ /** Horizontal offset in canvas units. */
6
+ x: number;
7
+ /** Vertical offset in canvas units. */
8
+ y: number;
9
+ }
10
+
11
+ /** One node (vertex) on the canvas. */
12
+ export interface FlowCanvasNode {
13
+ /** Stable unique id. Referenced by edges and every intent callback. */
14
+ id: string;
15
+ /**
16
+ * Plain-text label rendered inside the node. Also used verbatim for
17
+ * screen-reader announcements — keep it human-readable.
18
+ */
19
+ label: string;
20
+ /**
21
+ * Accent color for the node's left bar as a CSS color (typically `#RRGGBB`).
22
+ * Defaults to the accent token when omitted.
23
+ */
24
+ color?: string;
25
+ /**
26
+ * Position in canvas coordinates. When omitted the node is auto-laid-out
27
+ * (layered, left → right) and remains user-draggable for the session.
28
+ * A node with an explicit `position` is *pinned*: it stays where you place it
29
+ * and does not participate in — or perturb — the auto-layout of the other
30
+ * nodes. Use `arrangeNodes(nodes, edges)` to re-flow the whole graph.
31
+ */
32
+ position?: FlowCanvasPoint;
33
+ /**
34
+ * Slot rendered after the label — badges, icons, counters. Not announced to
35
+ * screen readers; keep essential state in `label` or the consumer's own UI.
36
+ * Avoid interactive elements (buttons, inputs): the node itself is a
37
+ * `role="button"`, so nested controls are invisible to assistive tech
38
+ * (nested-interactive) even though their keystrokes are let through.
39
+ */
40
+ adornment?: ReactNode;
41
+ }
42
+
43
+ /** One directed edge between two nodes. */
44
+ export interface FlowCanvasEdge {
45
+ /** Stable unique id. Referenced by selection and intent callbacks. */
46
+ id: string;
47
+ /** Source node id. */
48
+ from: string;
49
+ /** Target node id. */
50
+ to: string;
51
+ /**
52
+ * Slot rendered as a chip at the edge midpoint (e.g. a "Guard" badge).
53
+ * Not announced to screen readers.
54
+ */
55
+ label?: ReactNode;
56
+ }
57
+
58
+ /** Current single selection: a node, an edge, or nothing. */
59
+ export type FlowCanvasSelection = { type: 'node' | 'edge'; id: string } | null;
@@ -0,0 +1,122 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react';
2
+ import type { RefObject } from 'react';
3
+
4
+ /** Stage transform: translation in px plus a uniform scale. */
5
+ export interface Viewport {
6
+ tx: number;
7
+ ty: number;
8
+ z: number;
9
+ }
10
+
11
+ export const MIN_ZOOM = 0.25;
12
+ export const MAX_ZOOM = 2;
13
+ export const ZOOM_STEP = 1.2;
14
+ export const PAN_STEP = 40;
15
+
16
+ /** Canvas-space bounding box that {@link useViewport}'s `fitTo` centers on. */
17
+ export interface FitBounds {
18
+ x: number;
19
+ y: number;
20
+ width: number;
21
+ height: number;
22
+ }
23
+
24
+ // Wheel deltas arrive in pixels (Chrome, deltaMode 0), lines (Firefox mouse
25
+ // wheels, deltaMode 1, ~3 per notch), or pages (deltaMode 2). Normalize to
26
+ // pixels so pan/zoom speed matches across browsers.
27
+ const WHEEL_LINE_PX = 16;
28
+ const WHEEL_PAGE_PX = 800;
29
+ const wheelDeltaToPixels = (delta: number, deltaMode: number): number => {
30
+ if (deltaMode === 1) return delta * WHEEL_LINE_PX;
31
+ if (deltaMode === 2) return delta * WHEEL_PAGE_PX;
32
+ return delta;
33
+ };
34
+
35
+ // Continuous ctrl/cmd-wheel zoom: one mouse notch (~100px) multiplies the
36
+ // zoom by ZOOM_STEP, while a trackpad pinch (a rapid stream of small
37
+ // fractional ctrlKey deltas) scales proportionally per event instead of
38
+ // slamming a full step each time.
39
+ const WHEEL_ZOOM_SENSITIVITY = Math.log(ZOOM_STEP) / 100;
40
+
41
+ /**
42
+ * Pan/zoom state for the canvas stage. Wheel: plain scroll pans, ctrl/cmd
43
+ * zooms toward the cursor (native non-passive listener — React's onWheel
44
+ * can't preventDefault reliably). `fitTo` returns whether it applied — it's
45
+ * a no-op returning `false` when the root or bounds have no measurable size
46
+ * (jsdom, display: none), so callers can retry once measurable.
47
+ */
48
+ export function useViewport(rootRef: RefObject<HTMLDivElement | null>) {
49
+ const [viewport, setViewport] = useState<Viewport>({ tx: 0, ty: 0, z: 1 });
50
+
51
+ const panBy = useCallback((dx: number, dy: number) => {
52
+ setViewport((v) => ({ ...v, tx: v.tx + dx, ty: v.ty + dy }));
53
+ }, []);
54
+
55
+ const zoomBy = useCallback(
56
+ (factor: number, clientCenter?: { x: number; y: number }) => {
57
+ const rect = rootRef.current?.getBoundingClientRect();
58
+ setViewport((v) => {
59
+ const z = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, v.z * factor));
60
+ if (z === v.z) return v;
61
+ const cx = clientCenter && rect ? clientCenter.x - rect.left : (rect?.width ?? 0) / 2;
62
+ const cy = clientCenter && rect ? clientCenter.y - rect.top : (rect?.height ?? 0) / 2;
63
+ // Keep the canvas point under (cx, cy) stationary while scaling.
64
+ const px = (cx - v.tx) / v.z;
65
+ const py = (cy - v.ty) / v.z;
66
+ return { tx: cx - px * z, ty: cy - py * z, z };
67
+ });
68
+ },
69
+ [rootRef],
70
+ );
71
+
72
+ const fitTo = useCallback(
73
+ (bounds: FitBounds | null): boolean => {
74
+ const rect = rootRef.current?.getBoundingClientRect();
75
+ if (!bounds || !rect || rect.width === 0 || rect.height === 0) return false;
76
+ if (bounds.width === 0 || bounds.height === 0) return false;
77
+ const pad = 32;
78
+ const z = Math.min(
79
+ 1,
80
+ Math.max(
81
+ MIN_ZOOM,
82
+ Math.min((rect.width - pad * 2) / bounds.width, (rect.height - pad * 2) / bounds.height),
83
+ ),
84
+ );
85
+ setViewport({
86
+ tx: (rect.width - bounds.width * z) / 2 - bounds.x * z,
87
+ ty: (rect.height - bounds.height * z) / 2 - bounds.y * z,
88
+ z,
89
+ });
90
+ return true;
91
+ },
92
+ [rootRef],
93
+ );
94
+
95
+ // Native wheel listener: React attaches wheel passively, so preventDefault
96
+ // (needed to stop page scroll/browser zoom) requires a manual listener.
97
+ const zoomByRef = useRef(zoomBy);
98
+ zoomByRef.current = zoomBy;
99
+ const panByRef = useRef(panBy);
100
+ panByRef.current = panBy;
101
+ useEffect(() => {
102
+ const el = rootRef.current;
103
+ if (!el) return;
104
+ const onWheel = (event: WheelEvent) => {
105
+ event.preventDefault();
106
+ const deltaX = wheelDeltaToPixels(event.deltaX, event.deltaMode);
107
+ const deltaY = wheelDeltaToPixels(event.deltaY, event.deltaMode);
108
+ if (event.ctrlKey || event.metaKey) {
109
+ zoomByRef.current(Math.exp(-deltaY * WHEEL_ZOOM_SENSITIVITY), {
110
+ x: event.clientX,
111
+ y: event.clientY,
112
+ });
113
+ } else {
114
+ panByRef.current(-deltaX, -deltaY);
115
+ }
116
+ };
117
+ el.addEventListener('wheel', onWheel, { passive: false });
118
+ return () => el.removeEventListener('wheel', onWheel);
119
+ }, [rootRef]);
120
+
121
+ return { viewport, panBy, zoomBy, fitTo, setViewport };
122
+ }
@@ -0,0 +1,2 @@
1
+ // FormRow delegates all grid layout to <Grid> — no additional styles needed.
2
+ // This file exists to satisfy the repo's four-file rule (structure.test.ts).