@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
package/README.md CHANGED
@@ -1,3 +1,267 @@
1
- # Temporary Holding Version
1
+ # @eocrm/design-system
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ React 19 design system for the EOCRM. Source-distributed (consumers' bundlers process `.tsx` and `.module.scss` directly — no compile step in this package).
4
+
5
+ Its web tokens are generated and versioned by `@eocrm/design-tokens`. Existing
6
+ consumer imports remain unchanged: the design-system Sass entry points forward
7
+ to the token package.
8
+
9
+ Component contracts live in **[`docs/components/<Name>.md`](./docs/components)** (props table, anti-patterns). AI agents consuming this package should read **[AI-PRIMER.md](./AI-PRIMER.md)** first.
10
+
11
+ **Live playground** (every component, demoed against `main`): <https://eocrm.github.io/design-system/components>
12
+
13
+ ---
14
+
15
+ ## Install
16
+
17
+ ### 1. Registry
18
+
19
+ `@eocrm/design-system` and `@eocrm/design-tokens` are public on npmjs, so no
20
+ `.npmrc` or token is needed. Every release is also published, with identical
21
+ tarballs, to GitHub Packages (`@eocrm:registry=https://npm.pkg.github.com` plus a
22
+ `read:packages` token) for consumers that have not switched yet. Point the whole
23
+ `@eocrm` scope at one registry — the design system pins `@eocrm/design-tokens` to
24
+ its exact version.
25
+
26
+ ### 2. Install
27
+
28
+ ```bash
29
+ npm install @eocrm/design-system
30
+ ```
31
+
32
+ ### 3. Use
33
+
34
+ ```ts
35
+ // Once, at the app's root (e.g. main.tsx):
36
+ import '@eocrm/design-system/styles/global.scss';
37
+
38
+ // Anywhere:
39
+ import {
40
+ Avatar,
41
+ Badge,
42
+ Button,
43
+ Card,
44
+ Cluster,
45
+ DropdownMenu,
46
+ Input,
47
+ Stack,
48
+ Tabs,
49
+ } from '@eocrm/design-system';
50
+ ```
51
+
52
+ ---
53
+
54
+ ## What `global.scss` does
55
+
56
+ Importing `@eocrm/design-system/styles/global.scss` once at your app root applies three things:
57
+
58
+ 1. **Tokens** — defines every `--color-*`, `--space-*`, `--radius-*`, `--font-*`, `--shadow-*` etc. on `:root`. Required.
59
+ 2. **Modern reset** — including `* { margin: 0 }`. **All default browser margins on every element are zeroed.** Headings, paragraphs, lists have no intrinsic vertical rhythm; space them via `Stack`/`Cluster` or with the parent's own margin in CSS. The document background uses `--document-background` (default `var(--color-bg-subtle)`) so route transitions between full-screen surfaces do not flash a different base color; override that token after the global import for a different application canvas. The reset also applies `scrollbar-width: thin` + a token-colored `scrollbar-color` to every element, so **every** scroll container — library components and your own — gets a thin themed scrollbar instead of the OS default. (One deliberate exception: a collapsed `<Rail>` hides its bar entirely, since a gutter is about a quarter of the 56px rail's inner width.) It's declared at specificity 0-0-0; opt a scroller out with its own `scrollbar-width: auto` / `scrollbar-color: auto`. Note that Chromium ignores `::-webkit-scrollbar` rules on any scroller where these standard properties are set — if you already style scrollbars that way, they'll stop applying.
60
+ 3. **Base typography** — `body` font + size, `h1`–`h4` sizes, link color. Global rules, not scoped.
61
+
62
+ If you need only the tokens (you're providing your own reset), import `@eocrm/design-system/styles/tokens.scss` directly. Other available subpath imports: `./styles/reset.scss`, `./styles/typography.scss`, `./styles/mixins.scss`.
63
+
64
+ ---
65
+
66
+ ## Accent
67
+
68
+ The accent family defaults to blue. To switch the whole app to **Teal pine**, set `data-accent="tealpine"` on `<html>` (omit the attribute for blue):
69
+
70
+ ```html
71
+ <html data-accent="tealpine" data-theme="dark"></html>
72
+ ```
73
+
74
+ It swaps `--color-accent`, `-hover`, `-pressed`, `-fg`, `-bg-subtle`, `-subtle-bg` and `--ring-accent`, plus the default `Link` colour (`--color-link-fg` / `-hover`), in light, forced dark (`data-theme="dark"`) and OS dark. It ships in the existing `tokens.scss` / `dark.scss`, so there is no new import. `AppProvider`'s `tokens` / `darkTokens` overrides win over `data-accent` in every theme (see [docs/setup.md](docs/setup.md)). Info colours stay blue under any accent; DropdownMenu checked items, the OptionsPicker selected row and StagePath done states follow the accent. In light theme, default `Link`s use a slightly brighter teal than the accent (`#007676`, AA on every grey surface) at medium weight (not inside headings, `<strong>` or `<th>`), because the accent alone sits too close to the navy body text to read as a link.
75
+
76
+ Compose: `EocrmTealPineLightTokens` / `EocrmTealPineDarkTokens` sit beside `EocrmLightTokens` / `EocrmDarkTokens`; only accent colours differ. The link colour tokens are web-only (Compose has no `Link`), so Compose links keep the accent colour.
77
+
78
+ **Known issue:** in light theme, Teal pine and `--color-success` are close in hue (both green-teal). Review success/accent pairings visually before switching the CRM.
79
+
80
+ ---
81
+
82
+ ## Bundler notes
83
+
84
+ The package ships **source files** (`.tsx`, `.module.scss`). Your bundler compiles them.
85
+
86
+ - **Vite**: works out of the box.
87
+ - **Next.js**: add `transpilePackages: ['@eocrm/design-system']` to `next.config.js`.
88
+ - **Webpack 5**: ensure your TS/SCSS loaders don't `exclude: /node_modules/` for this package.
89
+ - **Create React App (ejected)**: same as Webpack.
90
+
91
+ If TypeScript can't resolve types, set `moduleResolution: "bundler"` (or `"node16"`) in your `tsconfig.json`.
92
+
93
+ **Tests.** Vitest works out of the box. Jest (CommonJS) must transform this package (TSX source) and its ESM-only dependencies (`d3-*`, `internmap`, used by `Chart`), and map `.module.scss` imports:
94
+
95
+ ```js
96
+ // jest.config.js — the pattern covers npm/yarn and pnpm (node_modules/.pnpm/<name>@<version>/…) layouts
97
+ transformIgnorePatterns: [
98
+ '/node_modules/(?!(\\.pnpm/)?(@eocrm[/+]design-system|d3-[^/@]+|internmap)[/@])',
99
+ ],
100
+ moduleNameMapper: { '\\.module\\.scss$': 'identity-obj-proxy' },
101
+ ```
102
+
103
+ - Install `identity-obj-proxy` as a dev dependency.
104
+ - The transformer must compile TSX and convert ESM to CommonJS inside `node_modules`:
105
+ - `babel-jest`: a root `babel.config.js` (a `.babelrc` does not apply to `node_modules`) with `@babel/preset-env` (`targets: { node: 'current' }`, which converts `import`/`export`), `@babel/preset-react` (`runtime: 'automatic'`) and `@babel/preset-typescript`.
106
+ - `ts-jest`: `preset: 'ts-jest/presets/js-with-ts'` (so `.js` files are transformed too), with `allowJs: true`, `jsx: 'react-jsx'` and `module: 'commonjs'` in the tsconfig it uses, and `isolatedModules: true` (transpile only). The package does not ship a `*.module.scss` type declaration, so a type-checking ts-jest reports TS2307 on its style imports unless you declare `*.module.scss` yourself.
107
+
108
+ ---
109
+
110
+ ## Components
111
+
112
+ Grouped for navigation. Per-component contracts are in `docs/components/<Name>.md`; [AI-PRIMER.md](./AI-PRIMER.md) indexes them with the tokens table.
113
+
114
+ **Typography**
115
+
116
+ - `Title` — semantic heading
117
+ - `Text` — body / inline text
118
+ - `Code` — inline `<code>` chip
119
+ - `Kbd` — keyboard key hint
120
+
121
+ **Actions**
122
+
123
+ - `Button` — action triggers
124
+ - `ButtonGroup` — joined Buttons + segmented control
125
+ - `SocialButton` — provider sign-in button
126
+ - `Link` — polymorphic styled anchor
127
+ - `DropdownMenu` — action menu from a trigger
128
+
129
+ **Form controls**
130
+
131
+ - `Input` — single-line text
132
+ - `Textarea` — multi-line text
133
+ - `OtpInput` — one-time-code entry, single-character boxes
134
+ - `PasswordInput` — password field with eye toggle + optional warnings
135
+ - `PasswordStrengthMeter` — 4-segment strength visualization
136
+ - `Select` — value picker (single, multi, searchable, async, creatable)
137
+ - `OptionsPicker` — filter picker (multi/single, grouped, searchable)
138
+ - `Checkbox` — checkbox with native input + custom paint
139
+ - `Radio` / `RadioGroup` — single radio + fieldset wrapper
140
+ - `Switch` — binary toggle
141
+ - `Slider` — controlled slider (single + range, horizontal + vertical)
142
+ - `ColorPicker` — controlled HEX color picker (popover + inline)
143
+ - `IconPicker` — controlled icon picker with a popover radio grid
144
+ - `FileUpload` — controlled file picker with dropzone
145
+ - `ImageCrop` — controlled image cropper
146
+
147
+ **Form layout**
148
+
149
+ - `Field` — labeled-control unit
150
+ - `FormSection` — titled group of fields
151
+ - `FormRow` — fields side by side
152
+ - `SettingRow` / `SettingRow.List` — settings-screen row with a shared label column, adornments and a footer slot
153
+
154
+ **Date & time**
155
+
156
+ - `Calendar` — month / week / day / agenda views
157
+ - `DatePicker` / `InlineDatePicker` — single-date input + popover, or in flow
158
+ - `DateRangePicker` / `InlineDateRangePicker` — date-range input + popover, or in flow
159
+ - `TimeField` — standalone time-of-day input
160
+
161
+ **Layout & structure**
162
+
163
+ - `Stack` — vertical layout
164
+ - `Cluster` — horizontal layout that wraps
165
+ - `Grid` — 2D layout primitive
166
+ - `Masonry` — height-balanced masonry layout
167
+ - `Constrain` — width / height / flex constraint
168
+ - `Divider` — separator primitive
169
+ - `Page` — page-root layout primitive
170
+ - `Screen` — full-bleed / centered screen layout
171
+ - `AppLayout` — viewport-filling app shell
172
+ - `PageHeader` — top-of-page heading area
173
+
174
+ **Navigation & app chrome**
175
+
176
+ - `Rail` — collapsible left-side navigation
177
+ - `TopBar` — sticky application top bar
178
+ - `Tabs` — horizontal tab strip
179
+ - `Breadcrumb` — navigation trail
180
+ - `Pagination` — numbered nav with windowing
181
+ - `CursorPagination` — prev / next for streams without a total
182
+
183
+ **Overlays**
184
+
185
+ - `Modal` — focus-locked dialog
186
+ - `Drawer` — edge-anchored slide-in panel
187
+ - `Popover` — non-modal floating panel for interactive content
188
+ - `ConfirmationPopover` — opinionated "Are you sure?" preset
189
+ - `Tooltip` — small floating label on hover / keyboard focus
190
+
191
+ **Feedback & status**
192
+
193
+ - `Alert` — persistent in-flow notification
194
+ - `Toast` (`ToastViewport` + `toast`) — transient notifications
195
+ - `Progress` — linear progress bar
196
+ - `CircularProgress` — circular progress / spinner
197
+ - `Skeleton` — loading placeholder
198
+ - `EmptyState` — "nothing here" container
199
+ - `ErrorState` — page-level status / result screen
200
+ - `Badge` — status / category pill
201
+ - `FilterChip` — dismissible "active filter" pill
202
+
203
+ **Data display**
204
+
205
+ - `Card` — bordered container
206
+ - `LinkCard` — clickable, full-surface Card
207
+ - `DefinitionList` — semantic key/value pairs (`dl` / `dt` / `dd`)
208
+ - `Table` — tabular data primitive
209
+ - `DataTable` — server-driven data table with column features
210
+ - `Accordion` — vertically-stacked collapsible panels
211
+ - `Kanban` — multi-column board (drag-to-reorder + cross-column drag)
212
+ - `Sortable` — drag-to-reorder list (single column)
213
+ - `Image` — image with loading + error states
214
+
215
+ **Identity & media**
216
+
217
+ - `Avatar` / `AvatarGroup` — profile circle / Slack-style stacked row
218
+ - `PersonDisplay` — Avatar + name (+ optional description lines)
219
+ - `Logo` — brand logo lockup
220
+ - `BrandIcon` — third-party brand marks
221
+ - `IconTile` — palette-colored icon frame
222
+
223
+ > The library also ships an `AppProvider` (theme + i18n + locale wiring), `LocaleProvider` / `I18nProvider`, the `useTranslation` / `useLocale` hooks, the `palette` helpers, and Calendar primitive hooks (`useMonth`, `useWeek`, `useDay`, `useAgenda`). See [AI-PRIMER.md](./AI-PRIMER.md) for those.
224
+
225
+ ---
226
+
227
+ ## Releasing a new version
228
+
229
+ Releases are **automatic**. Merging to `main` triggers the `Release` workflow (`.github/workflows/release.yml`), which:
230
+
231
+ 1. Runs the quality gate (typecheck, test, lint, build, tarball-contents check).
232
+ 2. If the library actually changed, computes the next version from the latest `v*` git tag (patch bump by default) and refuses if that tag already exists.
233
+ 3. Synchronizes `@eocrm/design-tokens`, `@eocrm/design-system`, and the generated token contract to one version.
234
+ 4. Publishes the token npm package, then the design-system npm package, then `com.eocrm.design:design-tokens-compose`.
235
+ 5. Verifies all three registry versions before creating and pushing the `v<version>` git tag.
236
+ 6. Re-deploys the playground (see below).
237
+
238
+ There is no manual "Run workflow" button — merging to `main` is the only way to release. Playground-only changes skip the publish step (no version bump for a demo tweak) but still redeploy the playground.
239
+
240
+ **Forcing a minor/major bump**: edit `BUMP` (`patch` → `minor` / `major`) in `release.yml` on a branch and merge. There is no other override by design.
241
+
242
+ **One-time repo setup**: Settings → Actions → General → Workflow permissions → "Read and write permissions".
243
+
244
+ The package name `@eocrm/design-system` must match an organization (or user) you have publish access to on GitHub. If your org isn't `eocrm`, rename the package in `package.json` and the `scope:` in the workflow.
245
+
246
+ ---
247
+
248
+ ## Playground deployment
249
+
250
+ The playground (live component gallery) deploys to GitHub Pages automatically as the final step of the `Release` workflow, so the live site at <https://eocrm.github.io/design-system/> always reflects `main`. It redeploys whenever the quality gate passes — even on playground-only changes, and even if a publish hiccups.
251
+
252
+ **This repo and its Pages site are public.** The playground bakes the library's source into its bundle via `?raw` imports, so the source is world-readable — that's intentional for a source-distributed library.
253
+
254
+ **One-time setup**: Settings → Pages → Source = "GitHub Actions" (not "Deploy from a branch").
255
+
256
+ ---
257
+
258
+ ## Where docs live (so you don't have to grep)
259
+
260
+ - **README.md** (this file) — install, setup, bundler notes, publishing/deploy ops.
261
+ - **[AI-PRIMER.md](./AI-PRIMER.md)** — concise primer for AI coding agents. Token table and component index.
262
+ - **`docs/components/<Name>.md`** — per-component contract: props table, examples, anti-patterns. Also `docs/setup.md`, `docs/theming.md`, `docs/transient-state.md`.
263
+ - **[CLAUDE.md](./CLAUDE.md)** — rules for someone **modifying this library** (not for consumers).
264
+
265
+ ## License
266
+
267
+ [Apache License 2.0](./LICENSE).
@@ -0,0 +1,114 @@
1
+ # `<Accordion>` — vertically-stacked collapsible panels
2
+
3
+ Compound component for FAQ-style content, settings sections, and any case where you have a list of headings with optional drill-down detail. Two modes: `single` (one open at a time) or `multiple` (any combination).
4
+
5
+ ```tsx
6
+ import { Accordion } from '@eocrm/design-system';
7
+
8
+ // Single-open with collapsible (FAQ-style)
9
+ <Accordion type="single" collapsible defaultValue="faq-2">
10
+ <Accordion.Item value="faq-1">
11
+ <Accordion.Trigger>How do I reset my password?</Accordion.Trigger>
12
+ <Accordion.Content>Visit Settings → Security → Reset.</Accordion.Content>
13
+ </Accordion.Item>
14
+ <Accordion.Item value="faq-2">
15
+ <Accordion.Trigger>How do I export my data?</Accordion.Trigger>
16
+ <Accordion.Content>Use the gear icon → Export → CSV.</Accordion.Content>
17
+ </Accordion.Item>
18
+ </Accordion>
19
+
20
+ // Multiple — independent sections
21
+ <Accordion type="multiple" defaultValue={['account', 'notifications']}>
22
+ <Accordion.Item value="account">...</Accordion.Item>
23
+ <Accordion.Item value="notifications">...</Accordion.Item>
24
+ </Accordion>
25
+
26
+ // Disabled item
27
+ <Accordion.Item value="advanced" disabled>...</Accordion.Item>
28
+
29
+ // Controlled
30
+ <Accordion type="single" value={open} onValueChange={setOpen}>...</Accordion>
31
+
32
+ // Borderless + large, e.g. hero FAQ sections
33
+ <Accordion type="single" collapsible variant="borderless" size="lg">...</Accordion>
34
+ ```
35
+
36
+ <!-- props:start -->
37
+
38
+ ## Props
39
+
40
+ ### `AccordionProps`
41
+
42
+ <!-- prettier-ignore -->
43
+ | Prop | Type | Required | Description |
44
+ |---|---|---|---|
45
+ | `variant` | `'bordered' \| 'borderless'` | no | Visual variant. Defaults to `'bordered'`. |
46
+ | `size` | `'sm' \| 'md' \| 'lg'` | no | Trigger size (font + padding). Defaults to `'md'`. |
47
+ | `gap` | `'sm' \| 'md' \| 'lg'` | no | Gap between items → separated "card" look (each item gets its own border + radius; the outer container chrome is dropped). Omit for the joined default. |
48
+ | `indicatorSide` | `'left' \| 'right'` | no | Which side the chevron indicator sits on. Defaults to `'right'`. |
49
+ | `actionsWhenClosed` | `'show' \| 'hide'` | no | Whether `Accordion.Trigger` `actions` stay visible when the item is collapsed. Defaults to `'show'`; `'hide'` fades them out (and drops them from focus order) while closed. |
50
+ | `children` | `ReactNode` | yes | |
51
+ | `type` | `"single" \| "multiple"` | yes | |
52
+ | `value` | `string \| string[]` | no | Controlled open item value. `''` = nothing open (only meaningful when `collapsible`). |
53
+ | `defaultValue` | `string \| string[]` | no | Initial open item for uncontrolled use. |
54
+ | `onValueChange` | `((next: string) => void) \| ((next: string[]) => void)` | no | Fires when the open item changes. |
55
+ | `collapsible` | `boolean` | no | When true, clicking the currently-open item closes it. Default: `false` (matches Radix; prevents accidentally closing the only available content). |
56
+ | …native | | | plus native HTML attributes |
57
+
58
+ ### `AccordionContentProps`
59
+
60
+ <!-- prettier-ignore -->
61
+ | Prop | Type | Required | Description |
62
+ |---|---|---|---|
63
+ | `children` | `ReactNode` | yes | |
64
+ | …native | | | plus native `<div>` attributes |
65
+
66
+ ### `AccordionItemProps`
67
+
68
+ <!-- prettier-ignore -->
69
+ | Prop | Type | Required | Description |
70
+ |---|---|---|---|
71
+ | `value` | `string` | yes | Unique value used to identify the item in the root's `value`/`onValueChange`. |
72
+ | `disabled` | `boolean` | no | When true, the trigger is non-interactive and keyboard nav skips this item. |
73
+ | `headerLevel` | `'h2' \| 'h3' \| 'h4' \| 'h5' \| 'h6'` | no | Heading level wrapping the trigger. WAI-ARIA APG requires triggers to live inside a heading element. Defaults to `'h3'`. |
74
+ | `children` | `ReactNode` | yes | |
75
+ | …native | | | plus native `<div>` attributes |
76
+
77
+ ### `AccordionTriggerProps`
78
+
79
+ <!-- prettier-ignore -->
80
+ | Prop | Type | Required | Description |
81
+ |---|---|---|---|
82
+ | `icon` | `ReactNode` | no | Override the default trigger indicator icon (rotates 180° when open). Pass `null` to suppress the icon entirely. Default: `<ChevronDown />`. |
83
+ | `actions` | `ReactNode` | no | Controls rendered at the **right of the header**, OUTSIDE the toggle button — so their buttons/menus are clickable without toggling the section, and the heading's accessible name stays just the title. Keep it to a few small controls (`<Button iconOnly>`, a `<DropdownMenu>` trigger, a `<Switch>`). |
84
+ | `children` | `ReactNode` | yes | |
85
+ | …native | | | plus native `<button>` attributes |
86
+
87
+ <!-- props:end -->
88
+
89
+ - **`type="single"`** + `collapsible={true}` — one item open at a time, click to close.
90
+ - **`type="multiple"`** — any combination.
91
+ - **`variant`** — `"bordered"` (default; outer border + radius + item dividers) or `"borderless"` (no chrome; for nesting inside Cards or as a quiet section divider).
92
+ - **`size`** — `"sm"` / `"md"` (default) / `"lg"` controls trigger font-size + padding (and content padding).
93
+ - **`gap`** — `"sm"` / `"md"` / `"lg"` separates items into **collapsible cards** (each gets its own border + radius; the joined container chrome is dropped). Omit for the default joined look.
94
+ - **`indicatorSide`** — `"right"` (default) or `"left"` to put the chevron before the title.
95
+ - **`<Accordion.Trigger actions={…}>`** — a controls slot at the **right of the header**, rendered OUTSIDE the toggle button so its buttons/menus are clickable without toggling the section (and don't pollute the heading's accessible name). Keep it to a few small controls.
96
+ - **`actionsWhenClosed`** — `"show"` (default) keeps `actions` always visible; `"hide"` fades them out (and drops them from focus order) while the item is collapsed — for dense sidebars of collapsed cards.
97
+ - **Smooth animation** via CSS `grid-template-rows: 0fr → 1fr`. No JS measurement.
98
+ - **Heading wrapping** — Trigger is wrapped in `<h3>` by default per WAI-ARIA APG. Override via `headerLevel` on Item.
99
+ - **Keyboard**: ArrowDown/Up cycles between triggers, Home/End jumps to ends, Space/Enter toggles. Disabled items are skipped.
100
+ - **Anatomy**: Content is `role="region"` with `aria-labelledby` pointing at its trigger. The Trigger's default indicator is a `<ChevronDown>` that rotates 180° when open.
101
+
102
+ #### When NOT to use
103
+
104
+ - ❌ Mutually-exclusive view switchers → `<Tabs>` (tabs imply parallel content; accordions imply hierarchy).
105
+ - ❌ A simple show/hide toggle for a single section → use a `<Button>` + conditional render.
106
+ - ❌ Step-by-step wizard flows → a dedicated Stepper (not shipped).
107
+
108
+ #### Anti-patterns
109
+
110
+ - ❌ Nesting `<Accordion.Trigger>` inside a heading the consumer also renders manually. Trigger ALREADY wraps itself in a heading.
111
+ - ❌ Setting `aria-expanded` manually on the Trigger via `{...props}`. The component owns the ARIA contract.
112
+ - ❌ Using `headerLevel="h1"`. There should only be one `<h1>` per page; Accordion lives below it.
113
+
114
+ - ❌ Putting bulky or primary content in the Trigger `actions` slot. It is for a few small header controls (an icon `<Button>`, a `<DropdownMenu>` trigger, a `<Switch>`); the section's real content belongs in `<Accordion.Content>`.
@@ -0,0 +1,58 @@
1
+ # `<AgentAvatar>` — AI agent tile with the acting member
2
+
3
+ **TL;DR:** a neutral tile with the agent's mark, plus a badge of the member it acts for. Use it where the agent is the actor and stands alone, such as a Thread or activity node. In a row with a name, use `PersonDisplay.AgentAvatar` instead (see [PersonDisplay](PersonDisplay.md)).
4
+
5
+ ```tsx
6
+ // Agent acting for a member: neutral tile + the member's avatar as a badge
7
+ <AgentAvatar name="Scout" member={{ name: 'Sarah Chen', src: '/avatars/sarah.png' }} />
8
+
9
+ // Agent alone (no `member`): no badge
10
+ <AgentAvatar name="Scout" />
11
+
12
+ // Erased member (`null` or an empty name): placeholder badge, "former member" label
13
+ <AgentAvatar name="Scout" member={null} />
14
+
15
+ // Custom mark; inherits currentColor in the tile
16
+ <AgentAvatar name="Scout" mark={<ScoutLogo />} member={{ name: 'Sarah Chen' }} size="lg" />
17
+
18
+ // Thread node beside a visible byline that already names both: decorative
19
+ <Thread.Item node={<AgentAvatar name="Scout" member={{ name: 'Sarah Chen' }} size="sm" decorative />}>
20
+ <PersonDisplay size="inline">
21
+ <PersonDisplay.Name>Scout</PersonDisplay.Name>
22
+ <PersonDisplay.OnBehalfOf>Sarah Chen</PersonDisplay.OnBehalfOf>
23
+ </PersonDisplay>
24
+ …
25
+ </Thread.Item>
26
+ ```
27
+
28
+ <!-- props:start -->
29
+
30
+ ## Props
31
+
32
+ <!-- prettier-ignore -->
33
+ | Prop | Type | Required | Description |
34
+ |---|---|---|---|
35
+ | `name` | `string` | yes | Agent label; drives the accessible name (an empty label reads as "?", like `Avatar`). Unused when `decorative`. |
36
+ | `mark` | `ReactNode` | no | Agent mark, inherits `currentColor` (a neutral foreground), so pass a glyph drawn with `fill`/`stroke="currentColor"`; marks with hard-coded fills keep their colours (the app's responsibility). Defaults to a lucide `Bot`. |
37
+ | `member` | `AgentAvatarMember \| null` | no | The member the agent acts for. Omit for an agent alone (no badge); `null` or an empty name for an erased member (placeholder badge). |
38
+ | `size` | `'inline' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | no | Diameter, same scale as `Avatar`. The member badge is hidden at `inline`. |
39
+ | `decorative` | `boolean` | no | Hide the avatar from assistive tech (`aria-hidden`, no role or label). Use when visible text next to it already names the agent and the member, e.g. a Thread node beside a "Scout for Sarah Chen" byline; otherwise both are announced. Without such text keep the default: a `role="img"` named "{agent}, on behalf of {member}". `PersonDisplay.AgentAvatar` always sets it. Defaults to `false`. |
40
+ | …native | | | plus native `<span>` attributes |
41
+
42
+ <!-- props:end -->
43
+
44
+ - Same `size` scale as [`Avatar`](Avatar.md). At `inline` the member badge is hidden (too small to read); the label still names the member.
45
+ - Accessible name: `role="img"` with `"{agent}, on behalf of {member}"` (localized), `"{agent}, on behalf of a former member"` when erased, or just the agent name when `member` is omitted. An empty `name` reads as `"?"`, as with `Avatar`.
46
+ - `decorative`: set it when visible text next to the avatar already names the agent and the member (a Thread node beside a byline). It renders `aria-hidden` with no role or label, so nothing is announced twice. With no such text, keep the default `role="img"`. `PersonDisplay.AgentAvatar` always sets it.
47
+
48
+ #### When NOT to use
49
+
50
+ - For a human. A person is an [`Avatar`](Avatar.md) (or `PersonDisplay.Avatar`).
51
+ - Next to an agent name in a row. Use `PersonDisplay.AgentAvatar` + `PersonDisplay.OnBehalfOf`, which localize "for {member}" and truncate it.
52
+
53
+ #### Anti-patterns
54
+
55
+ - ❌ Leaving the default `role="img"` beside a visible "Scout for Sarah Chen" byline. Screen readers announce the agent and member twice; pass `decorative`.
56
+ - ❌ `decorative` with no visible text naming the agent. The avatar then says nothing at all.
57
+ - ❌ Passing a multi-colour brand `mark` and expecting it to come out neutral. The tile only sets `color` (a neutral foreground); draw the glyph with `fill`/`stroke="currentColor"`. Hard-coded fills keep their colours, which is the app's responsibility.
58
+ - ❌ Deriving the brand `mark` from a client-chosen name. Pick the mark from a trusted, server-known agent identity, or an agent can impersonate another product.
@@ -0,0 +1,81 @@
1
+ # `<Alert>` — persistent in-flow notification
2
+
3
+ Tone-driven banner for messages that need to stay visible while the user reads the page (subscription warnings, save failures, "update available" notices). Complements `<Toast>` (transient).
4
+
5
+ ```tsx
6
+ import { Alert } from '@eocrm/design-system';
7
+
8
+ // Basic
9
+ <Alert tone="info" title="Synced 5 minutes ago" />
10
+ <Alert tone="warning">Your storage is at 85% capacity.</Alert>
11
+
12
+ // With actions
13
+ <Alert tone="warning" title="Update available" actions={<Button size="sm">Reload</Button>}>
14
+ A new version is ready. Reload to apply.
15
+ </Alert>
16
+
17
+ // Dismissible (controlled by consumer)
18
+ const [show, setShow] = useState(true);
19
+ {show && (
20
+ <Alert tone="success" onDismiss={() => setShow(false)}>
21
+ Changes saved.
22
+ </Alert>
23
+ )}
24
+
25
+ // Static callout that is part of the page, not a status change (no live region)
26
+ <Alert tone="warning" live={false} title="Needs action">
27
+ The client asked for a revised quote by Friday.
28
+ </Alert>
29
+
30
+ // Custom icon / suppressed icon
31
+ <Alert tone="info" icon={<Bell size={16} />} title="New mention" />
32
+ <Alert tone="info" icon={null}>Quietly informative.</Alert>
33
+ ```
34
+
35
+ <!-- props:start -->
36
+
37
+ ## Props
38
+
39
+ <!-- prettier-ignore -->
40
+ | Prop | Type | Required | Description |
41
+ |---|---|---|---|
42
+ | `tone` | `'info' \| 'success' \| 'warning' \| 'error'` | no | Tone. Defaults to `'info'`. See `AlertTone` for full descriptions. |
43
+ | `title` | `ReactNode` | no | Optional bold heading. Renders above the description. ReactNode so you can embed inline emphasis (`<>Update <strong>1.2.3</strong> available</>`). The native HTML `title` attribute (tooltip-on-hover) is collapsed by this prop. Use `aria-label` if you need that. |
44
+ | `children` | `ReactNode` | no | Description body. Rendered below the title in muted color. |
45
+ | `icon` | `ReactNode` | no | Override the tone's default icon. Pass any ReactNode (typically a lucide-react icon). Pass `null` to hide the icon entirely. Defaults: `info` → `Info`, `success` → `CheckCircle2`, `warning` → `AlertTriangle`, `error` → `XCircle`. |
46
+ | `actions` | `ReactNode` | no | Optional action row rendered below the description. Typically a single Button or a Cluster of two ("Retry", "Dismiss"). The component doesn't manage the action row's layout — pass a pre-laid-out node. |
47
+ | `live` | `boolean` | no | Whether the Alert is a live region. Defaults to `true`: `role="status"` (polite), or `role="alert"` (assertive) for `tone="error"` — right for a message that APPEARS in response to something (a save failed, an update arrived). Pass `false` for a callout that is simply part of the page when it opens — a "Needs action" note in each card of a list, a standing warning in a form. It renders `role="note"` with the same visuals and no live semantics, so screen readers read it in place instead of announcing it. N live Alerts mounting together can queue N announcements. The tone is shown by the icon's shape and the colour only; it is not exposed to assistive tech in either mode (the icon is decorative). With `live={false}`, `tone="error"` also loses the "alert" role that browse-mode readers speak. So put the urgency in `title` ("Needs action"). Decide it at mount: flipping `false` → `true` on a mounted Alert turns content that is already there into a live region, which announces nothing. |
48
+ | `onDismiss` | `(() => void)` | no | Called when the user clicks the close (×) button. When set, the close button renders; when omitted, no close button. Alert is **controlled** — the component does NOT manage internal hidden state. Hide via conditional render in the consumer: (example below) |
49
+ | …native | | | plus native HTML attributes |
50
+
51
+ **`onDismiss`** example:
52
+
53
+ <!-- prettier-ignore -->
54
+ ```tsx
55
+ const [show, setShow] = useState(true);
56
+ {show && <Alert tone="success" onDismiss={() => setShow(false)}>Saved</Alert>}
57
+ ```
58
+
59
+ <!-- props:end -->
60
+
61
+ - **Four tones** (`info` / `success` / `warning` / `error`). Default icon + accent stripe per tone.
62
+ - **`role="alert"`** only for `error` (assertive, interrupts SR). Others use `role="status"` (polite). Both only while `live` (the default).
63
+ - **`live={false}`** for a static callout that is part of the page when it opens (a "Needs action" note in each card of a list): renders `role="note"`, the same visuals, and no live region, so N of them don't queue N announcements. Keep the default for messages that appear in response to something. The tone (icon + colour) is never exposed to assistive tech, and `tone="error" live={false}` also loses the spoken "alert" role, so put the urgency in `title`. Decide `live` at mount: flipping it later announces nothing.
64
+ - **Persistent** — no auto-dismiss. Use Toast for transient messages.
65
+ - **Controlled dismiss** — `onDismiss` callback fires on × click; consumer hides via conditional render.
66
+ - **`icon={null}`** suppresses the icon entirely; any ReactNode overrides the default.
67
+
68
+ #### When NOT to use
69
+
70
+ - ❌ Transient confirmations → `<Toast>` / `toast.success(...)`.
71
+ - ❌ Empty-state placeholders ("No deals yet") → `<EmptyState>`.
72
+ - ❌ Form-field validation messages → inline error text + `aria-describedby`.
73
+ - ❌ Destructive confirmations needing yes/no → `<ConfirmationPopover>` or `<Modal>`.
74
+
75
+ #### Anti-patterns
76
+
77
+ - ❌ Auto-dismissing the Alert with a `setTimeout` — that's what Toast is for.
78
+ - ❌ Using `tone="error"` for non-critical warnings. Reserve `error` for genuine failures; `role="alert"` interrupts screen readers.
79
+ - ❌ Multiple stacked Alerts above a page — pick one (most urgent tone) or compose into the page layout with explicit hierarchy.
80
+ - ❌ A live Alert (the default) for content that exists when the page opens, especially one per list item — each is a live region and some screen readers queue an announcement per item. Pass `live={false}`.
81
+ - ❌ `live={false}` for a message that appears in response to an action (a failed save) — it is never announced. For a must-hear reactive message use `tone="error"` (`role="alert"` is announced on insertion) or a Toast. A polite live Alert that mounts together with its text is not reliably announced either.
@@ -0,0 +1,70 @@
1
+ # `<AppLayout>` — viewport-filling app shell
2
+
3
+ ```tsx
4
+ <AppLayout topBar={<TopBar />} sidebar={<Rail>{nav}</Rail>}>
5
+ <Page>{content}</Page>
6
+ </AppLayout>
7
+
8
+ // No sidebar — top bar + content only
9
+ <AppLayout topBar={<TopBar />}>
10
+ <Page>{content}</Page>
11
+ </AppLayout>
12
+
13
+ // Tall pages: pin the sidebar so a Rail's footer/CollapseToggle stays at the viewport bottom
14
+ <AppLayout sidebar={<Rail>{nav}<Rail.Footer>{footer}</Rail.Footer></Rail>} sidebarPinned>
15
+ <Page>{content}</Page>
16
+ </AppLayout>
17
+
18
+ // System banner above everything + a module-scoped one under the top bar
19
+ <AppLayout
20
+ banner={<Banner tone="info" title="Maintenance Saturday 22:00.">CRM will be read-only.</Banner>}
21
+ contextBanner={suspended && <Banner tone="danger" title="Email sending suspended." />}
22
+ topBar={<TopBar />}
23
+ sidebar={<Rail>{nav}</Rail>}
24
+ >
25
+ <Page>{content}</Page>
26
+ </AppLayout>
27
+ ```
28
+
29
+ <!-- props:start -->
30
+
31
+ ## Props
32
+
33
+ <!-- prettier-ignore -->
34
+ | Prop | Type | Required | Description |
35
+ |---|---|---|---|
36
+ | `banner` | `ReactNode` | no | System-wide banner slot — full WINDOW width, above the sidebar + content row. For messages that apply wherever the user is: maintenance, billing overdue, impersonation. Pass a `<Banner>` (or several, most severe first). Not sticky: it scrolls away with the page while the `topBar` stays pinned. Omit (or pass `null` / `false`) for no wrapper. With `sidebarPinned`, the pinned sidebar starts below this banner, so at scroll position 0 its bottom (a `Rail.Footer`) sits up to one banner height below the fold until the page scrolls past the banner. This is accepted — banners are temporary. |
37
+ | `contextBanner` | `ReactNode` | no | Context banner slot — inside the content column, between the `topBar` and the padded content region, full-bleed within the column. For messages scoped to a module or route ("Email sending suspended" on the Email pages); the app decides which routes render it. Pass a `<Banner>`. Not sticky. Page-level messages belong in the content as `<Alert>` instead. |
38
+ | `topBar` | `ReactNode` | no | Top bar slot — sits above the main content, spanning the content column to the right of the sidebar (not the full window width). Omit for no top bar. |
39
+ | `sidebar` | `ReactNode` | no | Sidebar slot — runs the full height down the left, alongside both the top bar and the content. Sets its own width (intrinsic). Omit for no sidebar. |
40
+ | `sidebarPinned` | `boolean` | no | Pin the sidebar to the viewport: `position: sticky; top: 0; height: 100dvh` with internal overflow scrolling. On pages taller than the viewport the sidebar (and a `Rail` inside it — including its `Rail.Footer` / CollapseToggle) spans exactly the SCREEN, keeping the footer glued to the viewport bottom instead of the page bottom. Default `false` (sidebar stretches to the full row/page height — the original behavior). Prefer this over wrapping the sidebar slot in `Sticky` — the rail pins its footer by filling its own `height: 100%` box, which needs a DEFINITE height to resolve against. `Sticky` sets `align-self: start`, which drops the row stretch that made it definite, so the footer stops pinning. `100dvh` is always relative to the real browser viewport, never to a nested scroll container — so this only pins correctly when AppLayout is the actual outermost, page-scroll shell (its documented top-level use). Nest it inside another scrollable region and the sidebar will size to the whole window, not that region, and overflow it. |
41
+ | `sidebarOverlayBelow` | `'sm' \| 'md' \| 'lg'` | no | Move the sidebar out of the flow and into a left-anchored `<Drawer>` while the **viewport** is at or below a width threshold: `'sm'` 480px / `'md'` 640px / `'lg'` 768px. Omit for no responsive behavior (the default) — the sidebar always renders in the flow. Below the threshold the content column claims the full viewport width, and the sidebar is reachable only by opening the drawer. Render your own trigger (a hamburger in the `topBar`) and drive it with `sidebarOpen` + `onSidebarOpenChange` — AppLayout deliberately renders no trigger of its own, since where it belongs in the bar is the consumer's call, which means both props are effectively required together (see `sidebarOpen`'s doc). Use the exported `useBelowBreakpoint` hook to show that trigger only while the overlay mode is active. `sidebarPinned` is ignored below the threshold: the drawer owns the sidebar's box there, and a `sticky; height: 100dvh` wrapper inside it would size the rail to the window instead of the drawer. Measures the viewport (`matchMedia`), not a container — the sidebar's presence in the row is exactly what the threshold changes, so a container query would be circular. Same scale and same basis as `<Rail collapseBelow>`. The `sidebar` node moves between the in-flow slot and the `Drawer`, remounting it, so a `Rail`'s internal state (expanded `Rail.Group`s, scroll position) resets each time, by design. A `<Rail>` in the drawer scrolls its own body while its footer stays visible; a custom non-`Rail` sidebar needs its own height-filling scroll container, especially on short viewports (phone landscape, ~380px). |
42
+ | `sidebarOpen` | `boolean` | no | Open state of the overlay sidebar. Technically optional, but effectively required together with `onSidebarOpenChange` whenever `sidebarOverlayBelow` is set — AppLayout renders no trigger of its own (see `sidebarOverlayBelow`), so with both omitted nothing can ever open the drawer; Esc/backdrop close it, but there's no way in. Has no effect unless `sidebarOverlayBelow` is set and the viewport is below it. |
43
+ | `onSidebarOpenChange` | `((open: boolean) => void)` | no | Fires whenever the overlay sidebar opens or closes — close button, Esc, backdrop click, swipe, or programmatic. Pair with `sidebarOpen` — see its doc. |
44
+ | `mainLandmark` | `boolean` | no | Render the content region as a `<main>` landmark instead of a plain `<div>`. Pass it on the outermost app shell so the page gets its single `main` landmark without a wrapper element. Leave it off (default) for nested use — demos, documentation previews — so the page never gets two `main`s. |
45
+ | `children` | `ReactNode` | yes | Main content slot — fills the remaining space below the top bar. |
46
+ | …native | | | plus native `<div>` attributes |
47
+
48
+ <!-- props:end -->
49
+
50
+ - Top-level shell layout, mounted **once** at the app root. Matches the CRM shell topology: a **full-height `sidebar`** down the left, an optional `topBar` **over the content column** (not full window width), and the main `children` below it. Root is `min-height: 100vh`.
51
+ - Layout-owning primitive (the `<Page>` / `<Screen>` / `<Rail>` exception to "no layout properties"). Its only own-styling is the main region's gutter + subtle canvas (both token-driven, below); the slots bring their own surfaces. Don't nest inside `<Page>` / `<Screen>`, and don't nest inside another `AppLayout` **in product code** — the only sanctioned AppLayout-in-AppLayout nesting is a demo/documentation preview (see the landmark note below); for a chromeless page use `<Screen>`, for in-page layout use `<Stack>` / `<Cluster>`.
52
+ - **Content padding (default):** the main region ships the canonical shell gutter (`--app-layout-content-padding`, default `var(--space-6)`, stepping down to `var(--space-4)` at ≤640px viewport width) — routed content is padded with **no prop and no raw CSS**. For a full-bleed main region, override the token (`--app-layout-content-padding: 0`) in your scope; there is no prop. Scope the override to a class or `body`, not another `:root` rule — the narrow-viewport step-down is itself a `:root` rule at the same specificity, so two `:root` rules fight on load order below 640px. _Migration:_ if you previously shimmed this gutter with your own `padding: var(--space-6)` wrapper, remove that shim now or the padding doubles.
53
+ - **Content canvas (default):** the main region paints a subtle canvas (`--app-layout-content-background`, default `var(--color-bg-subtle)`) so white `<Card>`s lift off it — matches every mockup, **no prop, no raw CSS**. For a flat content area, override the token (`--app-layout-content-background: transparent`); there is no prop. _Migration:_ if you shimmed your own `background: var(--color-bg-subtle)` on the content region, remove it.
54
+ - **Page-scroll shell:** `min-height: 100vh` means tall content scrolls the whole window, but the chrome doesn't scroll away with it — `topBar` is always pinned (`position: sticky`), and `sidebar` pins too when `sidebarPinned` is set. Only the main content region scrolls. For fixed chrome + independently-scrolling content, override the root to a fixed `height: 100vh` / `100dvh` via `className`.
55
+ - **`sidebarPinned`** (default `false`): on pages taller than the viewport, pins the sidebar wrapper (`position: sticky; top: 0; height: 100dvh; overflow-y: auto`) so a `Rail`'s footer/`CollapseToggle` stays glued to the viewport bottom instead of scrolling away with the page. Don't reach for wrapping the sidebar slot in `<Sticky>` instead — the Rail pins its footer by filling its own `height: 100%` box, and `Sticky`'s `align-self: start` drops the row stretch that made that height definite, so the footer-pinning doesn't work. `100dvh` is always relative to the real browser viewport, not a nested scroll container — only use it when AppLayout is the outermost, page-scroll shell (its documented top-level use); nested inside another scrollable region, the sidebar sizes to the whole window and overflows it.
56
+ - **`sidebarOverlayBelow`** (default: none): below a **viewport** threshold (`'sm'` 480 / `'md'` 640 / `'lg'` 768) the sidebar leaves the flow and renders in a left `<Drawer>`, so the content column gets the full viewport width — the fix for a 240px rail eating a phone screen. **AppLayout renders no trigger** — put a hamburger in your `topBar` and gate it with the `useBelowBreakpoint` hook (see below) so it only shows while the overlay is active. Because there's no built-in trigger, `sidebarOpen` + `onSidebarOpenChange` are technically optional props but **effectively required together**: with both omitted nothing can ever open the drawer. Once open, the drawer has a visible close button and a header that can be swiped left to dismiss, in addition to Esc/backdrop dismissal. `sidebarPinned` is ignored below the threshold (the drawer owns the sidebar's box there).
57
+ - The `children` slot renders inside a plain `<div>` by default, not a `<main>` — `AppLayout` can be nested in a demo or documentation preview (never in product code, see above), so it must not unilaterally claim the page's `main` landmark. The outermost app shell passes **`mainLandmark`** so the content region itself becomes the page's single `<main>` (no wrapper element, same styling); nested previews keep the default. Never set it on more than one `AppLayout` per page.
58
+
59
+ - A `<Sticky>` inside the main region must clear the pinned `topBar`: use `<Sticky top="topbar">`, which resolves to the standard top-bar height plus the normal content gap. Override `--sticky-top-topbar` when your chrome uses a custom height or clearance.
60
+
61
+ #### When NOT to use
62
+
63
+ - ❌ In-page content layout: use `<Stack>` / `<Cluster>` / `<Grid>`.
64
+ - ❌ A chromeless full-bleed page (sign-in / 404 / error): use `<Screen>`.
65
+
66
+ #### Anti-patterns
67
+
68
+ - ❌ Setting `sidebarOverlayBelow` without rendering a trigger: the sidebar becomes unreachable below the threshold.
69
+ - ❌ Duplicating the threshold as a raw media query in consumer CSS to hide the trigger. Use `useBelowBreakpoint(bp)` with the same token so the two can't drift.
70
+ - ❌ `<Rail collapseBelow>` and `sidebarOverlayBelow` at the same breakpoint: the rail would render icon-only inside a drawer that already has room for labels. Pick one behavior per width.