@eocrm/design-system 0.0.0-stage → 0.6.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (897) hide show
  1. package/AI-PRIMER.md +341 -0
  2. package/README.md +262 -2
  3. package/docs/components/Accordion.md +114 -0
  4. package/docs/components/AgentAvatar.md +58 -0
  5. package/docs/components/Alert.md +81 -0
  6. package/docs/components/AppLayout.md +70 -0
  7. package/docs/components/Avatar.md +49 -0
  8. package/docs/components/AvatarGroup.md +47 -0
  9. package/docs/components/Badge.md +60 -0
  10. package/docs/components/Banner.md +89 -0
  11. package/docs/components/BrandIcon.md +32 -0
  12. package/docs/components/Breadcrumb.md +72 -0
  13. package/docs/components/Button.md +107 -0
  14. package/docs/components/ButtonGroup.md +78 -0
  15. package/docs/components/Calendar.md +158 -0
  16. package/docs/components/Card.md +165 -0
  17. package/docs/components/CatalogPicker.md +83 -0
  18. package/docs/components/Chart.md +114 -0
  19. package/docs/components/ChatBubble.md +55 -0
  20. package/docs/components/ChatLauncher.md +97 -0
  21. package/docs/components/Checkbox.md +55 -0
  22. package/docs/components/CircularProgress.md +53 -0
  23. package/docs/components/Cluster.md +96 -0
  24. package/docs/components/Code.md +35 -0
  25. package/docs/components/CodeBlock.md +67 -0
  26. package/docs/components/ColorPicker.md +115 -0
  27. package/docs/components/ConfirmationPopover.md +70 -0
  28. package/docs/components/Constrain.md +39 -0
  29. package/docs/components/CurrencySelect.md +57 -0
  30. package/docs/components/CursorPagination.md +43 -0
  31. package/docs/components/DashboardCanvas.md +79 -0
  32. package/docs/components/DashboardWidget.md +131 -0
  33. package/docs/components/DataTable.md +88 -0
  34. package/docs/components/DatePicker.md +68 -0
  35. package/docs/components/DateRangePicker.md +71 -0
  36. package/docs/components/DateStrip.md +56 -0
  37. package/docs/components/DefinitionList.md +82 -0
  38. package/docs/components/Divider.md +57 -0
  39. package/docs/components/Dot.md +26 -0
  40. package/docs/components/Drawer.md +94 -0
  41. package/docs/components/DropdownMenu.md +299 -0
  42. package/docs/components/EmojiPicker.md +84 -0
  43. package/docs/components/EmptyState.md +55 -0
  44. package/docs/components/EntityChip.md +102 -0
  45. package/docs/components/ErrorState.md +72 -0
  46. package/docs/components/Field.md +91 -0
  47. package/docs/components/FileUpload.md +109 -0
  48. package/docs/components/FilterChip.md +88 -0
  49. package/docs/components/FlowCanvas.md +108 -0
  50. package/docs/components/FormRow.md +31 -0
  51. package/docs/components/FormSection.md +37 -0
  52. package/docs/components/Grid.md +103 -0
  53. package/docs/components/Highlight.md +75 -0
  54. package/docs/components/HighlightedText.md +50 -0
  55. package/docs/components/IconPicker.md +134 -0
  56. package/docs/components/IconTile.md +30 -0
  57. package/docs/components/Image.md +84 -0
  58. package/docs/components/ImageCrop.md +163 -0
  59. package/docs/components/Indent.md +31 -0
  60. package/docs/components/InlineDatePicker.md +58 -0
  61. package/docs/components/InlineDateRangePicker.md +57 -0
  62. package/docs/components/Input.md +54 -0
  63. package/docs/components/Kanban.md +122 -0
  64. package/docs/components/Kbd.md +41 -0
  65. package/docs/components/Lightbox.md +105 -0
  66. package/docs/components/Link.md +65 -0
  67. package/docs/components/LinkCard.md +41 -0
  68. package/docs/components/LiquidEditor.md +84 -0
  69. package/docs/components/List.md +68 -0
  70. package/docs/components/LiveRegion.md +29 -0
  71. package/docs/components/LocaleProvider.md +25 -0
  72. package/docs/components/Logo.md +41 -0
  73. package/docs/components/Masonry.md +48 -0
  74. package/docs/components/MediaTile.md +95 -0
  75. package/docs/components/Modal.md +107 -0
  76. package/docs/components/MoneyInput.md +62 -0
  77. package/docs/components/OptionsPicker.md +123 -0
  78. package/docs/components/OtpInput.md +65 -0
  79. package/docs/components/Page.md +35 -0
  80. package/docs/components/PageHeader.md +133 -0
  81. package/docs/components/Pagination.md +44 -0
  82. package/docs/components/Palette.md +32 -0
  83. package/docs/components/PasswordInput.md +45 -0
  84. package/docs/components/PasswordStrengthMeter.md +27 -0
  85. package/docs/components/PersonDisplay.md +153 -0
  86. package/docs/components/PhoneInput.md +54 -0
  87. package/docs/components/PillMenu.md +91 -0
  88. package/docs/components/Popover.md +127 -0
  89. package/docs/components/Progress.md +56 -0
  90. package/docs/components/QrCode.md +34 -0
  91. package/docs/components/Radio.md +37 -0
  92. package/docs/components/RadioGroup.md +56 -0
  93. package/docs/components/Rail.md +191 -0
  94. package/docs/components/RelativeDateInput.md +114 -0
  95. package/docs/components/RichText.md +44 -0
  96. package/docs/components/RichTextEditor.md +112 -0
  97. package/docs/components/Screen.md +37 -0
  98. package/docs/components/ScrollArea.md +39 -0
  99. package/docs/components/Select.md +131 -0
  100. package/docs/components/SettingRow.md +98 -0
  101. package/docs/components/Skeleton.md +68 -0
  102. package/docs/components/Slider.md +92 -0
  103. package/docs/components/SlotGrid.md +55 -0
  104. package/docs/components/SocialButton.md +31 -0
  105. package/docs/components/Sortable.md +127 -0
  106. package/docs/components/SortableGroup.md +52 -0
  107. package/docs/components/Sparkline.md +51 -0
  108. package/docs/components/Split.md +76 -0
  109. package/docs/components/Stack.md +59 -0
  110. package/docs/components/StagePath.md +66 -0
  111. package/docs/components/StatGroup.md +61 -0
  112. package/docs/components/StatTile.md +58 -0
  113. package/docs/components/Sticky.md +69 -0
  114. package/docs/components/Switch.md +89 -0
  115. package/docs/components/Table.md +184 -0
  116. package/docs/components/TableOfContents.md +76 -0
  117. package/docs/components/Tabs.md +94 -0
  118. package/docs/components/Text.md +63 -0
  119. package/docs/components/Textarea.md +59 -0
  120. package/docs/components/Thread.md +52 -0
  121. package/docs/components/TimeField.md +70 -0
  122. package/docs/components/Timeline.md +57 -0
  123. package/docs/components/Title.md +54 -0
  124. package/docs/components/ToastViewport.md +61 -0
  125. package/docs/components/Tooltip.md +63 -0
  126. package/docs/components/TopBar.md +214 -0
  127. package/docs/components/Tour.md +85 -0
  128. package/docs/components/TreeView.md +113 -0
  129. package/docs/components/VisuallyHidden.md +43 -0
  130. package/docs/components/WidgetPreview.md +54 -0
  131. package/docs/components/useBelowBreakpoint.md +11 -0
  132. package/docs/components/useMonth.md +18 -0
  133. package/docs/setup.md +51 -0
  134. package/docs/theming.md +95 -0
  135. package/docs/tokens.md +123 -0
  136. package/docs/transient-state.md +56 -0
  137. package/package.json +82 -4
  138. package/src/_meta/manifest.ts +293 -0
  139. package/src/app/AppProvider.tsx +78 -0
  140. package/src/app/index.ts +3 -0
  141. package/src/app/themeTokens.ts +95 -0
  142. package/src/calendar/dateMath.ts +114 -0
  143. package/src/calendar/formatters.ts +75 -0
  144. package/src/calendar/index.ts +39 -0
  145. package/src/calendar/types.ts +36 -0
  146. package/src/calendar/useAgenda.ts +70 -0
  147. package/src/calendar/useDay.ts +51 -0
  148. package/src/calendar/useMonth.ts +82 -0
  149. package/src/calendar/useWeek.ts +62 -0
  150. package/src/calendar/weekInfo.ts +83 -0
  151. package/src/components/Accordion/Accordion.module.scss +304 -0
  152. package/src/components/Accordion/Accordion.tokens.scss +64 -0
  153. package/src/components/Accordion/Accordion.tsx +272 -0
  154. package/src/components/Accordion/AccordionContent.tsx +36 -0
  155. package/src/components/Accordion/AccordionItem.tsx +66 -0
  156. package/src/components/Accordion/AccordionTrigger.tsx +121 -0
  157. package/src/components/Accordion/context.ts +47 -0
  158. package/src/components/Accordion/index.ts +14 -0
  159. package/src/components/Alert/Alert.module.scss +92 -0
  160. package/src/components/Alert/Alert.tokens.scss +60 -0
  161. package/src/components/Alert/Alert.tsx +136 -0
  162. package/src/components/Alert/index.ts +2 -0
  163. package/src/components/AppLayout/AppLayout.module.scss +130 -0
  164. package/src/components/AppLayout/AppLayout.tokens.scss +27 -0
  165. package/src/components/AppLayout/AppLayout.tsx +211 -0
  166. package/src/components/AppLayout/index.ts +2 -0
  167. package/src/components/Avatar/AgentAvatar.module.scss +117 -0
  168. package/src/components/Avatar/AgentAvatar.tsx +122 -0
  169. package/src/components/Avatar/Avatar.module.scss +181 -0
  170. package/src/components/Avatar/Avatar.tokens.scss +107 -0
  171. package/src/components/Avatar/Avatar.tsx +210 -0
  172. package/src/components/Avatar/AvatarGroup.module.scss +128 -0
  173. package/src/components/Avatar/AvatarGroup.tsx +119 -0
  174. package/src/components/Avatar/AvatarGroupContext.tsx +20 -0
  175. package/src/components/Avatar/index.ts +6 -0
  176. package/src/components/Badge/Badge.module.scss +124 -0
  177. package/src/components/Badge/Badge.tokens.scss +74 -0
  178. package/src/components/Badge/Badge.tsx +164 -0
  179. package/src/components/Badge/index.ts +2 -0
  180. package/src/components/Banner/Banner.module.scss +73 -0
  181. package/src/components/Banner/Banner.tokens.scss +51 -0
  182. package/src/components/Banner/Banner.tsx +138 -0
  183. package/src/components/Banner/index.ts +2 -0
  184. package/src/components/BrandIcon/BrandIcon.module.scss +5 -0
  185. package/src/components/BrandIcon/BrandIcon.tsx +99 -0
  186. package/src/components/BrandIcon/index.ts +2 -0
  187. package/src/components/Breadcrumb/Breadcrumb.module.scss +32 -0
  188. package/src/components/Breadcrumb/Breadcrumb.tokens.scss +9 -0
  189. package/src/components/Breadcrumb/Breadcrumb.tsx +146 -0
  190. package/src/components/Breadcrumb/index.ts +2 -0
  191. package/src/components/Button/Button.module.scss +167 -0
  192. package/src/components/Button/Button.tokens.scss +90 -0
  193. package/src/components/Button/Button.tsx +205 -0
  194. package/src/components/Button/index.ts +2 -0
  195. package/src/components/ButtonGroup/ButtonGroup.module.scss +134 -0
  196. package/src/components/ButtonGroup/ButtonGroup.tokens.scss +42 -0
  197. package/src/components/ButtonGroup/ButtonGroup.tsx +278 -0
  198. package/src/components/ButtonGroup/ButtonGroupItem.tsx +74 -0
  199. package/src/components/ButtonGroup/context.ts +45 -0
  200. package/src/components/ButtonGroup/index.ts +2 -0
  201. package/src/components/Calendar/AgendaView.module.scss +231 -0
  202. package/src/components/Calendar/AgendaView.tsx +214 -0
  203. package/src/components/Calendar/AllDayBand.module.scss +18 -0
  204. package/src/components/Calendar/AllDayBand.tsx +75 -0
  205. package/src/components/Calendar/Calendar.module.scss +23 -0
  206. package/src/components/Calendar/Calendar.tokens.scss +262 -0
  207. package/src/components/Calendar/Calendar.tsx +370 -0
  208. package/src/components/Calendar/DayCell.module.scss +30 -0
  209. package/src/components/Calendar/DayCell.tsx +50 -0
  210. package/src/components/Calendar/DayView.module.scss +10 -0
  211. package/src/components/Calendar/DayView.tsx +163 -0
  212. package/src/components/Calendar/EventChip.module.scss +171 -0
  213. package/src/components/Calendar/EventChip.tsx +115 -0
  214. package/src/components/Calendar/HourGrid.module.scss +123 -0
  215. package/src/components/Calendar/HourGrid.tsx +381 -0
  216. package/src/components/Calendar/MonthView.module.scss +99 -0
  217. package/src/components/Calendar/MonthView.tsx +296 -0
  218. package/src/components/Calendar/TimedEvent.module.scss +205 -0
  219. package/src/components/Calendar/TimedEvent.tsx +247 -0
  220. package/src/components/Calendar/ViewSwitcher.module.scss +3 -0
  221. package/src/components/Calendar/ViewSwitcher.tsx +47 -0
  222. package/src/components/Calendar/WeekView.module.scss +10 -0
  223. package/src/components/Calendar/WeekView.tsx +137 -0
  224. package/src/components/Calendar/eventColor.ts +60 -0
  225. package/src/components/Calendar/index.ts +18 -0
  226. package/src/components/Calendar/types.ts +451 -0
  227. package/src/components/Calendar/useEventDrag.ts +783 -0
  228. package/src/components/Calendar/utils.ts +622 -0
  229. package/src/components/Card/Card.module.scss +264 -0
  230. package/src/components/Card/Card.tokens.scss +55 -0
  231. package/src/components/Card/Card.tsx +170 -0
  232. package/src/components/Card/CardBody.tsx +45 -0
  233. package/src/components/Card/CardHeader.tsx +113 -0
  234. package/src/components/Card/CardList.tsx +24 -0
  235. package/src/components/Card/CardListRow.tsx +24 -0
  236. package/src/components/Card/index.ts +7 -0
  237. package/src/components/CatalogPicker/CatalogPicker.module.scss +193 -0
  238. package/src/components/CatalogPicker/CatalogPicker.tokens.scss +26 -0
  239. package/src/components/CatalogPicker/CatalogPicker.tsx +339 -0
  240. package/src/components/CatalogPicker/index.ts +2 -0
  241. package/src/components/Chart/Chart.module.scss +287 -0
  242. package/src/components/Chart/Chart.tokens.scss +63 -0
  243. package/src/components/Chart/Chart.tsx +607 -0
  244. package/src/components/Chart/ChartLegend.tsx +99 -0
  245. package/src/components/Chart/ChartTable.tsx +62 -0
  246. package/src/components/Chart/ChartTooltip.tsx +91 -0
  247. package/src/components/Chart/chartModel.ts +689 -0
  248. package/src/components/Chart/index.ts +2 -0
  249. package/src/components/ChatBubble/ChatBubble.module.scss +93 -0
  250. package/src/components/ChatBubble/ChatBubble.tokens.scss +17 -0
  251. package/src/components/ChatBubble/ChatBubble.tsx +61 -0
  252. package/src/components/ChatBubble/ChatBubbleList.tsx +27 -0
  253. package/src/components/ChatBubble/index.ts +3 -0
  254. package/src/components/ChatLauncher/ChatLauncher.module.scss +68 -0
  255. package/src/components/ChatLauncher/ChatLauncher.tokens.scss +27 -0
  256. package/src/components/ChatLauncher/ChatLauncher.tsx +202 -0
  257. package/src/components/ChatLauncher/index.ts +2 -0
  258. package/src/components/ChatLauncher/isAtBottom.ts +12 -0
  259. package/src/components/Checkbox/Checkbox.module.scss +147 -0
  260. package/src/components/Checkbox/Checkbox.tokens.scss +44 -0
  261. package/src/components/Checkbox/Checkbox.tsx +188 -0
  262. package/src/components/Checkbox/index.ts +2 -0
  263. package/src/components/CircularProgress/CircularProgress.module.scss +133 -0
  264. package/src/components/CircularProgress/CircularProgress.tokens.scss +40 -0
  265. package/src/components/CircularProgress/CircularProgress.tsx +139 -0
  266. package/src/components/CircularProgress/index.ts +7 -0
  267. package/src/components/Cluster/Cluster.module.scss +145 -0
  268. package/src/components/Cluster/Cluster.tokens.scss +11 -0
  269. package/src/components/Cluster/Cluster.tsx +215 -0
  270. package/src/components/Cluster/index.ts +2 -0
  271. package/src/components/Code/Code.module.scss +28 -0
  272. package/src/components/Code/Code.tokens.scss +15 -0
  273. package/src/components/Code/Code.tsx +44 -0
  274. package/src/components/Code/index.ts +2 -0
  275. package/src/components/CodeBlock/CodeBlock.module.scss +146 -0
  276. package/src/components/CodeBlock/CodeBlock.tokens.scss +27 -0
  277. package/src/components/CodeBlock/CodeBlock.tsx +274 -0
  278. package/src/components/CodeBlock/highlight.ts +179 -0
  279. package/src/components/CodeBlock/index.ts +8 -0
  280. package/src/components/CodeBlock/sampleSync.ts +42 -0
  281. package/src/components/ColorPicker/ColorPicker.module.scss +286 -0
  282. package/src/components/ColorPicker/ColorPicker.tokens.scss +60 -0
  283. package/src/components/ColorPicker/ColorPicker.tsx +367 -0
  284. package/src/components/ColorPicker/ColorPickerPanel.tsx +265 -0
  285. package/src/components/ColorPicker/SVSquare.tsx +189 -0
  286. package/src/components/ColorPicker/colorMath.ts +141 -0
  287. package/src/components/ColorPicker/index.ts +6 -0
  288. package/src/components/ConfirmationPopover/ConfirmationPopover.module.scss +39 -0
  289. package/src/components/ConfirmationPopover/ConfirmationPopover.tokens.scss +13 -0
  290. package/src/components/ConfirmationPopover/ConfirmationPopover.tsx +395 -0
  291. package/src/components/ConfirmationPopover/index.ts +2 -0
  292. package/src/components/Constrain/Constrain.module.scss +99 -0
  293. package/src/components/Constrain/Constrain.tsx +79 -0
  294. package/src/components/Constrain/index.ts +2 -0
  295. package/src/components/CurrencySelect/CurrencySelect.module.scss +7 -0
  296. package/src/components/CurrencySelect/CurrencySelect.tsx +167 -0
  297. package/src/components/CurrencySelect/index.ts +3 -0
  298. package/src/components/CursorPagination/CursorPagination.module.scss +69 -0
  299. package/src/components/CursorPagination/CursorPagination.tokens.scss +32 -0
  300. package/src/components/CursorPagination/CursorPagination.tsx +121 -0
  301. package/src/components/CursorPagination/index.ts +2 -0
  302. package/src/components/DashboardCanvas/DashboardCanvas.module.scss +360 -0
  303. package/src/components/DashboardCanvas/DashboardCanvas.tokens.scss +48 -0
  304. package/src/components/DashboardCanvas/DashboardCanvas.tsx +1270 -0
  305. package/src/components/DashboardCanvas/DashboardCanvasItem.tsx +140 -0
  306. package/src/components/DashboardCanvas/DashboardCanvasSection.tsx +174 -0
  307. package/src/components/DashboardCanvas/engine.ts +363 -0
  308. package/src/components/DashboardCanvas/index.ts +9 -0
  309. package/src/components/DashboardWidget/DashboardWidget.module.scss +100 -0
  310. package/src/components/DashboardWidget/DashboardWidget.tokens.scss +16 -0
  311. package/src/components/DashboardWidget/DashboardWidget.tsx +188 -0
  312. package/src/components/DashboardWidget/index.ts +7 -0
  313. package/src/components/DataTable/BodyRow.tsx +197 -0
  314. package/src/components/DataTable/ColumnVisibilityTrigger.module.scss +7 -0
  315. package/src/components/DataTable/ColumnVisibilityTrigger.tsx +105 -0
  316. package/src/components/DataTable/DataTable.module.scss +511 -0
  317. package/src/components/DataTable/DataTable.tokens.scss +80 -0
  318. package/src/components/DataTable/DataTable.tsx +734 -0
  319. package/src/components/DataTable/HeaderCell.module.scss +215 -0
  320. package/src/components/DataTable/HeaderCell.tsx +440 -0
  321. package/src/components/DataTable/columnShift.ts +117 -0
  322. package/src/components/DataTable/index.ts +23 -0
  323. package/src/components/DataTable/pinStyle.ts +47 -0
  324. package/src/components/DataTable/reorderColumns.ts +66 -0
  325. package/src/components/DataTable/types.ts +289 -0
  326. package/src/components/DataTable/useColumnDragShift.ts +216 -0
  327. package/src/components/DataTable/useDataTable.ts +372 -0
  328. package/src/components/DataTable/useResizeHandle.ts +97 -0
  329. package/src/components/DatePicker/DatePicker.module.scss +180 -0
  330. package/src/components/DatePicker/DatePicker.tokens.scss +152 -0
  331. package/src/components/DatePicker/DatePicker.tsx +664 -0
  332. package/src/components/DatePicker/DatePickerGrid.module.scss +172 -0
  333. package/src/components/DatePicker/DatePickerGrid.tsx +341 -0
  334. package/src/components/DatePicker/InlineDatePicker.module.scss +32 -0
  335. package/src/components/DatePicker/InlineDatePicker.tsx +201 -0
  336. package/src/components/DatePicker/index.ts +4 -0
  337. package/src/components/DatePicker/utils.ts +364 -0
  338. package/src/components/DateRangePicker/DateRangePicker.module.scss +237 -0
  339. package/src/components/DateRangePicker/DateRangePicker.tokens.scss +78 -0
  340. package/src/components/DateRangePicker/DateRangePicker.tsx +720 -0
  341. package/src/components/DateRangePicker/InlineDateRangePicker.module.scss +94 -0
  342. package/src/components/DateRangePicker/InlineDateRangePicker.tsx +376 -0
  343. package/src/components/DateRangePicker/index.ts +5 -0
  344. package/src/components/DateRangePicker/utils.ts +151 -0
  345. package/src/components/DateStrip/DateStrip.module.scss +78 -0
  346. package/src/components/DateStrip/DateStrip.tokens.scss +23 -0
  347. package/src/components/DateStrip/DateStrip.tsx +205 -0
  348. package/src/components/DateStrip/index.ts +2 -0
  349. package/src/components/DefinitionList/DefinitionList.module.scss +102 -0
  350. package/src/components/DefinitionList/DefinitionList.tokens.scss +29 -0
  351. package/src/components/DefinitionList/DefinitionList.tsx +198 -0
  352. package/src/components/DefinitionList/index.ts +9 -0
  353. package/src/components/Divider/Divider.module.scss +144 -0
  354. package/src/components/Divider/Divider.tokens.scss +21 -0
  355. package/src/components/Divider/Divider.tsx +103 -0
  356. package/src/components/Divider/index.ts +2 -0
  357. package/src/components/Dot/Dot.module.scss +40 -0
  358. package/src/components/Dot/Dot.tokens.scss +4 -0
  359. package/src/components/Dot/Dot.tsx +45 -0
  360. package/src/components/Dot/index.ts +2 -0
  361. package/src/components/Drawer/Body.tsx +23 -0
  362. package/src/components/Drawer/Close.tsx +35 -0
  363. package/src/components/Drawer/Content.tsx +93 -0
  364. package/src/components/Drawer/Drawer.module.scss +232 -0
  365. package/src/components/Drawer/Drawer.tokens.scss +38 -0
  366. package/src/components/Drawer/Drawer.tsx +23 -0
  367. package/src/components/Drawer/DrawerRoot.tsx +190 -0
  368. package/src/components/Drawer/Footer.tsx +24 -0
  369. package/src/components/Drawer/Header.tsx +64 -0
  370. package/src/components/Drawer/Overlay.tsx +82 -0
  371. package/src/components/Drawer/context.ts +44 -0
  372. package/src/components/Drawer/index.ts +12 -0
  373. package/src/components/Drawer/useDragToClose.ts +149 -0
  374. package/src/components/DropdownMenu/CheckboxItem.tsx +144 -0
  375. package/src/components/DropdownMenu/Content.tsx +419 -0
  376. package/src/components/DropdownMenu/DropdownMenu.module.scss +280 -0
  377. package/src/components/DropdownMenu/DropdownMenu.tokens.scss +88 -0
  378. package/src/components/DropdownMenu/DropdownMenu.tsx +43 -0
  379. package/src/components/DropdownMenu/Group.tsx +76 -0
  380. package/src/components/DropdownMenu/Item.tsx +148 -0
  381. package/src/components/DropdownMenu/ItemIndicator.tsx +30 -0
  382. package/src/components/DropdownMenu/Radio.tsx +178 -0
  383. package/src/components/DropdownMenu/Root.tsx +100 -0
  384. package/src/components/DropdownMenu/Sub.tsx +332 -0
  385. package/src/components/DropdownMenu/Trigger.tsx +76 -0
  386. package/src/components/DropdownMenu/context.ts +65 -0
  387. package/src/components/DropdownMenu/index.ts +20 -0
  388. package/src/components/EmojiPicker/EmojiPicker.module.scss +84 -0
  389. package/src/components/EmojiPicker/EmojiPicker.tokens.scss +24 -0
  390. package/src/components/EmojiPicker/EmojiPicker.tsx +341 -0
  391. package/src/components/EmojiPicker/emojiData.ts +245 -0
  392. package/src/components/EmojiPicker/index.ts +3 -0
  393. package/src/components/EmptyState/EmptyState.module.scss +102 -0
  394. package/src/components/EmptyState/EmptyState.tokens.scss +28 -0
  395. package/src/components/EmptyState/EmptyState.tsx +112 -0
  396. package/src/components/EmptyState/index.ts +7 -0
  397. package/src/components/EntityChip/EntityChip.module.scss +275 -0
  398. package/src/components/EntityChip/EntityChip.tokens.scss +66 -0
  399. package/src/components/EntityChip/EntityChip.tsx +649 -0
  400. package/src/components/EntityChip/index.ts +10 -0
  401. package/src/components/ErrorState/ErrorState.module.scss +105 -0
  402. package/src/components/ErrorState/ErrorState.tokens.scss +32 -0
  403. package/src/components/ErrorState/ErrorState.tsx +125 -0
  404. package/src/components/ErrorState/index.ts +8 -0
  405. package/src/components/Field/Field.module.scss +46 -0
  406. package/src/components/Field/Field.tsx +185 -0
  407. package/src/components/Field/index.ts +2 -0
  408. package/src/components/FileUpload/FileUpload.module.scss +187 -0
  409. package/src/components/FileUpload/FileUpload.tokens.scss +81 -0
  410. package/src/components/FileUpload/FileUpload.tsx +569 -0
  411. package/src/components/FileUpload/formatBytes.ts +34 -0
  412. package/src/components/FileUpload/iconForFile.ts +40 -0
  413. package/src/components/FileUpload/index.ts +2 -0
  414. package/src/components/FilterChip/FilterChip.module.scss +61 -0
  415. package/src/components/FilterChip/FilterChip.tokens.scss +25 -0
  416. package/src/components/FilterChip/FilterChip.tsx +208 -0
  417. package/src/components/FilterChip/index.ts +5 -0
  418. package/src/components/FlowCanvas/FlowCanvas.module.scss +329 -0
  419. package/src/components/FlowCanvas/FlowCanvas.tokens.scss +45 -0
  420. package/src/components/FlowCanvas/FlowCanvas.tsx +1867 -0
  421. package/src/components/FlowCanvas/FlowControls.tsx +46 -0
  422. package/src/components/FlowCanvas/FlowEdge.tsx +58 -0
  423. package/src/components/FlowCanvas/FlowNode.tsx +76 -0
  424. package/src/components/FlowCanvas/edgePath.ts +85 -0
  425. package/src/components/FlowCanvas/index.ts +4 -0
  426. package/src/components/FlowCanvas/layout.ts +148 -0
  427. package/src/components/FlowCanvas/spatialNav.ts +76 -0
  428. package/src/components/FlowCanvas/types.ts +59 -0
  429. package/src/components/FlowCanvas/useViewport.ts +122 -0
  430. package/src/components/FormRow/FormRow.module.scss +2 -0
  431. package/src/components/FormRow/FormRow.tsx +37 -0
  432. package/src/components/FormRow/index.ts +2 -0
  433. package/src/components/FormSection/FormSection.module.scss +24 -0
  434. package/src/components/FormSection/FormSection.tsx +46 -0
  435. package/src/components/FormSection/index.ts +2 -0
  436. package/src/components/Grid/Grid.module.scss +162 -0
  437. package/src/components/Grid/Grid.tokens.scss +13 -0
  438. package/src/components/Grid/Grid.tsx +226 -0
  439. package/src/components/Grid/GridItem.tsx +77 -0
  440. package/src/components/Grid/index.ts +11 -0
  441. package/src/components/Highlight/Highlight.module.scss +43 -0
  442. package/src/components/Highlight/Highlight.tokens.scss +35 -0
  443. package/src/components/Highlight/Highlight.tsx +164 -0
  444. package/src/components/Highlight/HighlightOverlay.tsx +100 -0
  445. package/src/components/Highlight/index.ts +2 -0
  446. package/src/components/HighlightedText/HighlightedText.module.scss +11 -0
  447. package/src/components/HighlightedText/HighlightedText.tokens.scss +9 -0
  448. package/src/components/HighlightedText/HighlightedText.tsx +50 -0
  449. package/src/components/HighlightedText/highlightRanges.ts +44 -0
  450. package/src/components/HighlightedText/index.ts +2 -0
  451. package/src/components/IconPicker/IconPicker.module.scss +175 -0
  452. package/src/components/IconPicker/IconPicker.tokens.scss +40 -0
  453. package/src/components/IconPicker/IconPicker.tsx +629 -0
  454. package/src/components/IconPicker/index.ts +9 -0
  455. package/src/components/IconTile/IconTile.module.scss +57 -0
  456. package/src/components/IconTile/IconTile.tokens.scss +16 -0
  457. package/src/components/IconTile/IconTile.tsx +91 -0
  458. package/src/components/IconTile/index.ts +2 -0
  459. package/src/components/Image/Image.module.scss +266 -0
  460. package/src/components/Image/Image.tokens.scss +55 -0
  461. package/src/components/Image/Image.tsx +342 -0
  462. package/src/components/Image/index.ts +2 -0
  463. package/src/components/ImageCrop/ImageCrop.module.scss +274 -0
  464. package/src/components/ImageCrop/ImageCrop.tokens.scss +33 -0
  465. package/src/components/ImageCrop/ImageCrop.tsx +542 -0
  466. package/src/components/ImageCrop/cropGeometry.ts +120 -0
  467. package/src/components/ImageCrop/extractCropBlob.ts +140 -0
  468. package/src/components/ImageCrop/index.ts +11 -0
  469. package/src/components/ImageCrop/useCropPreview.ts +161 -0
  470. package/src/components/Indent/Indent.module.scss +33 -0
  471. package/src/components/Indent/Indent.tokens.scss +10 -0
  472. package/src/components/Indent/Indent.tsx +46 -0
  473. package/src/components/Indent/index.ts +2 -0
  474. package/src/components/Input/Input.module.scss +99 -0
  475. package/src/components/Input/Input.tokens.scss +54 -0
  476. package/src/components/Input/Input.tsx +105 -0
  477. package/src/components/Input/Suggestions.tsx +260 -0
  478. package/src/components/Input/index.ts +2 -0
  479. package/src/components/Kanban/Kanban.module.scss +39 -0
  480. package/src/components/Kanban/Kanban.tokens.scss +15 -0
  481. package/src/components/Kanban/Kanban.tsx +951 -0
  482. package/src/components/Kanban/index.ts +7 -0
  483. package/src/components/Kbd/Kbd.module.scss +47 -0
  484. package/src/components/Kbd/Kbd.tokens.scss +26 -0
  485. package/src/components/Kbd/Kbd.tsx +73 -0
  486. package/src/components/Kbd/index.ts +2 -0
  487. package/src/components/Lightbox/Lightbox.module.scss +283 -0
  488. package/src/components/Lightbox/Lightbox.tokens.scss +36 -0
  489. package/src/components/Lightbox/Lightbox.tsx +506 -0
  490. package/src/components/Lightbox/index.ts +2 -0
  491. package/src/components/Link/Link.module.scss +78 -0
  492. package/src/components/Link/Link.tokens.scss +28 -0
  493. package/src/components/Link/Link.tsx +114 -0
  494. package/src/components/Link/index.ts +2 -0
  495. package/src/components/LinkCard/LinkCard.module.scss +92 -0
  496. package/src/components/LinkCard/LinkCard.tokens.scss +9 -0
  497. package/src/components/LinkCard/LinkCard.tsx +72 -0
  498. package/src/components/LinkCard/index.ts +2 -0
  499. package/src/components/LiquidEditor/AutocompleteMenu.tsx +133 -0
  500. package/src/components/LiquidEditor/HighlightLayer.tsx +53 -0
  501. package/src/components/LiquidEditor/InsertVariableMenu.tsx +81 -0
  502. package/src/components/LiquidEditor/LiquidEditor.module.scss +339 -0
  503. package/src/components/LiquidEditor/LiquidEditor.tokens.scss +81 -0
  504. package/src/components/LiquidEditor/LiquidEditor.tsx +412 -0
  505. package/src/components/LiquidEditor/PreviewPane.tsx +29 -0
  506. package/src/components/LiquidEditor/caretCoordinates.ts +97 -0
  507. package/src/components/LiquidEditor/index.ts +7 -0
  508. package/src/components/LiquidEditor/liquidFilters.ts +23 -0
  509. package/src/components/LiquidEditor/liquidTokenizer.ts +235 -0
  510. package/src/components/LiquidEditor/types.ts +101 -0
  511. package/src/components/LiquidEditor/useLiquidAutocomplete.ts +178 -0
  512. package/src/components/List/List.module.scss +105 -0
  513. package/src/components/List/List.tokens.scss +42 -0
  514. package/src/components/List/List.tsx +124 -0
  515. package/src/components/List/index.ts +9 -0
  516. package/src/components/LiveRegion/LiveRegion.module.scss +3 -0
  517. package/src/components/LiveRegion/LiveRegion.tsx +116 -0
  518. package/src/components/LiveRegion/index.ts +2 -0
  519. package/src/components/Logo/Logo.module.scss +139 -0
  520. package/src/components/Logo/Logo.tokens.scss +14 -0
  521. package/src/components/Logo/Logo.tsx +126 -0
  522. package/src/components/Logo/index.ts +2 -0
  523. package/src/components/Masonry/Masonry.module.scss +42 -0
  524. package/src/components/Masonry/Masonry.tokens.scss +8 -0
  525. package/src/components/Masonry/Masonry.tsx +136 -0
  526. package/src/components/Masonry/index.ts +2 -0
  527. package/src/components/Masonry/masonryUtils.ts +42 -0
  528. package/src/components/MediaTile/MediaTile.module.scss +183 -0
  529. package/src/components/MediaTile/MediaTile.tokens.scss +60 -0
  530. package/src/components/MediaTile/MediaTile.tsx +208 -0
  531. package/src/components/MediaTile/index.ts +8 -0
  532. package/src/components/Modal/Body.tsx +27 -0
  533. package/src/components/Modal/Close.tsx +45 -0
  534. package/src/components/Modal/Content.tsx +98 -0
  535. package/src/components/Modal/Footer.tsx +28 -0
  536. package/src/components/Modal/Header.tsx +51 -0
  537. package/src/components/Modal/Modal.module.scss +262 -0
  538. package/src/components/Modal/Modal.tokens.scss +50 -0
  539. package/src/components/Modal/Modal.tsx +23 -0
  540. package/src/components/Modal/ModalRoot.tsx +299 -0
  541. package/src/components/Modal/Overlay.tsx +101 -0
  542. package/src/components/Modal/context.ts +60 -0
  543. package/src/components/Modal/index.ts +11 -0
  544. package/src/components/MoneyInput/MoneyInput.module.scss +57 -0
  545. package/src/components/MoneyInput/MoneyInput.tsx +433 -0
  546. package/src/components/MoneyInput/index.ts +2 -0
  547. package/src/components/OptionsPicker/OptionsPicker.module.scss +216 -0
  548. package/src/components/OptionsPicker/OptionsPicker.tokens.scss +68 -0
  549. package/src/components/OptionsPicker/OptionsPicker.tsx +936 -0
  550. package/src/components/OptionsPicker/index.ts +9 -0
  551. package/src/components/OtpInput/OtpInput.module.scss +69 -0
  552. package/src/components/OtpInput/OtpInput.tokens.scss +45 -0
  553. package/src/components/OtpInput/OtpInput.tsx +368 -0
  554. package/src/components/OtpInput/index.ts +2 -0
  555. package/src/components/Page/Page.module.scss +30 -0
  556. package/src/components/Page/Page.tokens.scss +11 -0
  557. package/src/components/Page/Page.tsx +53 -0
  558. package/src/components/Page/index.ts +2 -0
  559. package/src/components/PageHeader/PageHeader.module.scss +197 -0
  560. package/src/components/PageHeader/PageHeader.tokens.scss +41 -0
  561. package/src/components/PageHeader/PageHeader.tsx +310 -0
  562. package/src/components/PageHeader/index.ts +20 -0
  563. package/src/components/Pagination/Pagination.module.scss +117 -0
  564. package/src/components/Pagination/Pagination.tokens.scss +54 -0
  565. package/src/components/Pagination/Pagination.tsx +165 -0
  566. package/src/components/Pagination/index.ts +4 -0
  567. package/src/components/Pagination/paginationRange.ts +72 -0
  568. package/src/components/PasswordInput/PasswordInput.module.scss +120 -0
  569. package/src/components/PasswordInput/PasswordInput.tokens.scss +44 -0
  570. package/src/components/PasswordInput/PasswordInput.tsx +210 -0
  571. package/src/components/PasswordInput/index.ts +2 -0
  572. package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.module.scss +80 -0
  573. package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tokens.scss +40 -0
  574. package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tsx +96 -0
  575. package/src/components/PasswordStrengthMeter/index.ts +2 -0
  576. package/src/components/PersonDisplay/PersonDisplay.module.scss +180 -0
  577. package/src/components/PersonDisplay/PersonDisplay.tokens.scss +35 -0
  578. package/src/components/PersonDisplay/PersonDisplay.tsx +420 -0
  579. package/src/components/PersonDisplay/index.ts +10 -0
  580. package/src/components/PhoneInput/PhoneInput.module.scss +23 -0
  581. package/src/components/PhoneInput/PhoneInput.tsx +271 -0
  582. package/src/components/PhoneInput/index.ts +4 -0
  583. package/src/components/PhoneInput/phone.ts +128 -0
  584. package/src/components/PillMenu/PillMenu.module.scss +117 -0
  585. package/src/components/PillMenu/PillMenu.tokens.scss +22 -0
  586. package/src/components/PillMenu/PillMenu.tsx +324 -0
  587. package/src/components/PillMenu/index.ts +2 -0
  588. package/src/components/Popover/Anchor.tsx +37 -0
  589. package/src/components/Popover/Close.tsx +45 -0
  590. package/src/components/Popover/Content.tsx +213 -0
  591. package/src/components/Popover/Heading.tsx +33 -0
  592. package/src/components/Popover/Popover.module.scss +177 -0
  593. package/src/components/Popover/Popover.tokens.scss +22 -0
  594. package/src/components/Popover/Popover.tsx +23 -0
  595. package/src/components/Popover/PopoverRoot.tsx +75 -0
  596. package/src/components/Popover/Trigger.tsx +86 -0
  597. package/src/components/Popover/context.ts +22 -0
  598. package/src/components/Popover/index.ts +7 -0
  599. package/src/components/Progress/Progress.module.scss +110 -0
  600. package/src/components/Progress/Progress.tokens.scss +44 -0
  601. package/src/components/Progress/Progress.tsx +129 -0
  602. package/src/components/Progress/index.ts +2 -0
  603. package/src/components/QrCode/QrCode.module.scss +97 -0
  604. package/src/components/QrCode/QrCode.tokens.scss +17 -0
  605. package/src/components/QrCode/QrCode.tsx +233 -0
  606. package/src/components/QrCode/index.ts +2 -0
  607. package/src/components/QrCode/qr.ts +161 -0
  608. package/src/components/Radio/Radio.module.scss +175 -0
  609. package/src/components/Radio/Radio.tokens.scss +59 -0
  610. package/src/components/Radio/Radio.tsx +127 -0
  611. package/src/components/Radio/RadioGroup.module.scss +42 -0
  612. package/src/components/Radio/RadioGroup.tsx +120 -0
  613. package/src/components/Radio/RadioGroupContext.tsx +30 -0
  614. package/src/components/Radio/index.ts +4 -0
  615. package/src/components/Rail/Rail.module.scss +510 -0
  616. package/src/components/Rail/Rail.tokens.scss +92 -0
  617. package/src/components/Rail/Rail.tsx +287 -0
  618. package/src/components/Rail/RailCollapseToggle.tsx +57 -0
  619. package/src/components/Rail/RailFooter.tsx +17 -0
  620. package/src/components/Rail/RailGroup.tsx +728 -0
  621. package/src/components/Rail/RailGroupContext.ts +9 -0
  622. package/src/components/Rail/RailHeader.tsx +23 -0
  623. package/src/components/Rail/RailItem.tsx +119 -0
  624. package/src/components/Rail/RailSection.tsx +39 -0
  625. package/src/components/Rail/RailSpacer.tsx +19 -0
  626. package/src/components/Rail/index.ts +9 -0
  627. package/src/components/RelativeDateInput/RelativeDateInput.module.scss +15 -0
  628. package/src/components/RelativeDateInput/RelativeDateInput.tokens.scss +6 -0
  629. package/src/components/RelativeDateInput/RelativeDateInput.tsx +474 -0
  630. package/src/components/RelativeDateInput/index.ts +10 -0
  631. package/src/components/RelativeDateInput/relativeDate.ts +127 -0
  632. package/src/components/RichText/RichText.module.scss +5 -0
  633. package/src/components/RichText/RichText.tsx +70 -0
  634. package/src/components/RichText/RichTextAttachment.module.scss +82 -0
  635. package/src/components/RichText/RichTextAttachment.tsx +122 -0
  636. package/src/components/RichText/_prose.scss +79 -0
  637. package/src/components/RichText/attachmentIcon.tsx +24 -0
  638. package/src/components/RichText/engine/attachment.ts +154 -0
  639. package/src/components/RichText/engine/autolink.ts +64 -0
  640. package/src/components/RichText/engine/blockUnit.ts +174 -0
  641. package/src/components/RichText/engine/colorMarks.ts +85 -0
  642. package/src/components/RichText/engine/escape.ts +11 -0
  643. package/src/components/RichText/engine/fromHtml.ts +353 -0
  644. package/src/components/RichText/engine/fromMarkdown.ts +20 -0
  645. package/src/components/RichText/engine/inlines.ts +82 -0
  646. package/src/components/RichText/engine/listDepths.ts +32 -0
  647. package/src/components/RichText/engine/marks.ts +80 -0
  648. package/src/components/RichText/engine/mdToHtml.ts +178 -0
  649. package/src/components/RichText/engine/model.ts +157 -0
  650. package/src/components/RichText/engine/position.ts +118 -0
  651. package/src/components/RichText/engine/renderDoc.tsx +395 -0
  652. package/src/components/RichText/engine/renderLink.ts +15 -0
  653. package/src/components/RichText/engine/renderMention.ts +16 -0
  654. package/src/components/RichText/engine/safeHref.ts +22 -0
  655. package/src/components/RichText/engine/toHtml.ts +154 -0
  656. package/src/components/RichText/engine/toMarkdown.ts +97 -0
  657. package/src/components/RichText/engine/transforms.ts +434 -0
  658. package/src/components/RichText/imageMaxHeightStyle.ts +10 -0
  659. package/src/components/RichText/index.ts +31 -0
  660. package/src/components/RichTextEditor/RichTextAttachmentConfig.tsx +264 -0
  661. package/src/components/RichTextEditor/RichTextBlockControls.tsx +365 -0
  662. package/src/components/RichTextEditor/RichTextBlockMenu.tsx +162 -0
  663. package/src/components/RichTextEditor/RichTextColorMenu.tsx +115 -0
  664. package/src/components/RichTextEditor/RichTextEditor.module.scss +298 -0
  665. package/src/components/RichTextEditor/RichTextEditor.tsx +1910 -0
  666. package/src/components/RichTextEditor/RichTextImageResizer.tsx +131 -0
  667. package/src/components/RichTextEditor/RichTextLinkEditor.tsx +151 -0
  668. package/src/components/RichTextEditor/RichTextMentionMenu.tsx +99 -0
  669. package/src/components/RichTextEditor/RichTextToolbar.tsx +379 -0
  670. package/src/components/RichTextEditor/autolinkInput.ts +65 -0
  671. package/src/components/RichTextEditor/blockDrop.ts +9 -0
  672. package/src/components/RichTextEditor/blockReflow.ts +62 -0
  673. package/src/components/RichTextEditor/commands.ts +300 -0
  674. package/src/components/RichTextEditor/history.ts +93 -0
  675. package/src/components/RichTextEditor/icons.tsx +152 -0
  676. package/src/components/RichTextEditor/imageSize.ts +70 -0
  677. package/src/components/RichTextEditor/index.ts +5 -0
  678. package/src/components/RichTextEditor/input.ts +209 -0
  679. package/src/components/RichTextEditor/inputRules.ts +71 -0
  680. package/src/components/RichTextEditor/links.ts +103 -0
  681. package/src/components/RichTextEditor/mentionContext.ts +37 -0
  682. package/src/components/RichTextEditor/mentions.ts +28 -0
  683. package/src/components/RichTextEditor/preventSelectionLoss.ts +15 -0
  684. package/src/components/RichTextEditor/selection.ts +415 -0
  685. package/src/components/RichTextEditor/shortcuts.ts +44 -0
  686. package/src/components/RichTextEditor/useAnchoredFloating.ts +50 -0
  687. package/src/components/RichTextEditor/useAttachmentConfig.ts +134 -0
  688. package/src/components/RichTextEditor/useDismissOnOutsidePointerDown.ts +26 -0
  689. package/src/components/RichTextEditor/useLinkEditor.ts +107 -0
  690. package/src/components/RichTextEditor/useMention.ts +226 -0
  691. package/src/components/RichTextEditor/useOverlayRect.ts +73 -0
  692. package/src/components/RichTextEditor/useUpload.ts +246 -0
  693. package/src/components/Screen/Screen.module.scss +46 -0
  694. package/src/components/Screen/Screen.tokens.scss +20 -0
  695. package/src/components/Screen/Screen.tsx +97 -0
  696. package/src/components/Screen/index.ts +2 -0
  697. package/src/components/ScrollArea/ScrollArea.module.scss +39 -0
  698. package/src/components/ScrollArea/ScrollArea.tokens.scss +15 -0
  699. package/src/components/ScrollArea/ScrollArea.tsx +154 -0
  700. package/src/components/ScrollArea/index.ts +2 -0
  701. package/src/components/Select/Chip.tsx +45 -0
  702. package/src/components/Select/Empty.tsx +39 -0
  703. package/src/components/Select/Error.tsx +51 -0
  704. package/src/components/Select/HiddenInputs.tsx +44 -0
  705. package/src/components/Select/Listbox.tsx +557 -0
  706. package/src/components/Select/Loading.tsx +30 -0
  707. package/src/components/Select/Select.module.scss +512 -0
  708. package/src/components/Select/Select.tokens.scss +140 -0
  709. package/src/components/Select/Select.tsx +685 -0
  710. package/src/components/Select/Trigger.tsx +952 -0
  711. package/src/components/Select/context.ts +101 -0
  712. package/src/components/Select/emptyStateText.ts +19 -0
  713. package/src/components/Select/index.ts +9 -0
  714. package/src/components/Select/useSelectState.ts +157 -0
  715. package/src/components/Select/utils-types.ts +7 -0
  716. package/src/components/Select/utils.ts +122 -0
  717. package/src/components/SettingRow/SettingRow.module.scss +166 -0
  718. package/src/components/SettingRow/SettingRow.tokens.scss +37 -0
  719. package/src/components/SettingRow/SettingRow.tsx +242 -0
  720. package/src/components/SettingRow/index.ts +7 -0
  721. package/src/components/Skeleton/Skeleton.module.scss +55 -0
  722. package/src/components/Skeleton/Skeleton.tokens.scss +17 -0
  723. package/src/components/Skeleton/Skeleton.tsx +131 -0
  724. package/src/components/Skeleton/index.ts +4 -0
  725. package/src/components/Skeleton/useSkeletonVisibility.ts +95 -0
  726. package/src/components/Slider/Slider.module.scss +293 -0
  727. package/src/components/Slider/Slider.tokens.scss +98 -0
  728. package/src/components/Slider/Slider.tsx +624 -0
  729. package/src/components/Slider/index.ts +9 -0
  730. package/src/components/SlotGrid/SlotGrid.module.scss +61 -0
  731. package/src/components/SlotGrid/SlotGrid.tokens.scss +21 -0
  732. package/src/components/SlotGrid/SlotGrid.tsx +111 -0
  733. package/src/components/SlotGrid/index.ts +2 -0
  734. package/src/components/SocialButton/SocialButton.module.scss +4 -0
  735. package/src/components/SocialButton/SocialButton.tsx +40 -0
  736. package/src/components/SocialButton/index.ts +2 -0
  737. package/src/components/Sortable/Sortable.module.scss +177 -0
  738. package/src/components/Sortable/Sortable.tokens.scss +27 -0
  739. package/src/components/Sortable/Sortable.tsx +572 -0
  740. package/src/components/Sortable/containerAwareCollision.ts +125 -0
  741. package/src/components/Sortable/index.ts +13 -0
  742. package/src/components/SortableGroup/SortableGroup.module.scss +23 -0
  743. package/src/components/SortableGroup/SortableGroup.tsx +315 -0
  744. package/src/components/SortableGroup/index.ts +4 -0
  745. package/src/components/SortableGroup/moveSortableItem.ts +39 -0
  746. package/src/components/Sparkline/Sparkline.module.scss +28 -0
  747. package/src/components/Sparkline/Sparkline.tokens.scss +7 -0
  748. package/src/components/Sparkline/Sparkline.tsx +133 -0
  749. package/src/components/Sparkline/index.ts +2 -0
  750. package/src/components/Sparkline/sparklineModel.ts +119 -0
  751. package/src/components/Split/Split.module.scss +158 -0
  752. package/src/components/Split/Split.tokens.scss +10 -0
  753. package/src/components/Split/Split.tsx +231 -0
  754. package/src/components/Split/index.ts +2 -0
  755. package/src/components/Stack/Stack.module.scss +67 -0
  756. package/src/components/Stack/Stack.tokens.scss +11 -0
  757. package/src/components/Stack/Stack.tsx +100 -0
  758. package/src/components/Stack/index.ts +2 -0
  759. package/src/components/StagePath/StagePath.module.scss +255 -0
  760. package/src/components/StagePath/StagePath.tokens.scss +43 -0
  761. package/src/components/StagePath/StagePath.tsx +176 -0
  762. package/src/components/StagePath/index.ts +2 -0
  763. package/src/components/StatGroup/StatGroup.module.scss +6 -0
  764. package/src/components/StatGroup/StatGroup.tsx +70 -0
  765. package/src/components/StatGroup/StatGroupContext.ts +10 -0
  766. package/src/components/StatGroup/StatTile.module.scss +99 -0
  767. package/src/components/StatGroup/StatTile.tokens.scss +35 -0
  768. package/src/components/StatGroup/StatTile.tsx +143 -0
  769. package/src/components/StatGroup/index.ts +4 -0
  770. package/src/components/Sticky/Sticky.module.scss +98 -0
  771. package/src/components/Sticky/Sticky.tokens.scss +17 -0
  772. package/src/components/Sticky/Sticky.tsx +103 -0
  773. package/src/components/Sticky/index.ts +2 -0
  774. package/src/components/Switch/Switch.module.scss +182 -0
  775. package/src/components/Switch/Switch.tokens.scss +59 -0
  776. package/src/components/Switch/Switch.tsx +214 -0
  777. package/src/components/Switch/index.ts +2 -0
  778. package/src/components/Table/Table.module.scss +308 -0
  779. package/src/components/Table/Table.tokens.scss +79 -0
  780. package/src/components/Table/Table.tsx +381 -0
  781. package/src/components/Table/index.ts +15 -0
  782. package/src/components/TableOfContents/TableOfContents.module.scss +83 -0
  783. package/src/components/TableOfContents/TableOfContents.tokens.scss +26 -0
  784. package/src/components/TableOfContents/TableOfContents.tsx +192 -0
  785. package/src/components/TableOfContents/activeSection.ts +18 -0
  786. package/src/components/TableOfContents/index.ts +2 -0
  787. package/src/components/Tabs/Tabs.module.scss +359 -0
  788. package/src/components/Tabs/Tabs.tokens.scss +50 -0
  789. package/src/components/Tabs/Tabs.tsx +538 -0
  790. package/src/components/Tabs/index.ts +2 -0
  791. package/src/components/Text/Text.module.scss +115 -0
  792. package/src/components/Text/Text.tokens.scss +55 -0
  793. package/src/components/Text/Text.tsx +197 -0
  794. package/src/components/Text/index.ts +2 -0
  795. package/src/components/Textarea/Textarea.module.scss +94 -0
  796. package/src/components/Textarea/Textarea.tokens.scss +48 -0
  797. package/src/components/Textarea/Textarea.tsx +246 -0
  798. package/src/components/Textarea/index.ts +2 -0
  799. package/src/components/Thread/Thread.module.scss +161 -0
  800. package/src/components/Thread/Thread.tokens.scss +32 -0
  801. package/src/components/Thread/Thread.tsx +176 -0
  802. package/src/components/Thread/index.ts +2 -0
  803. package/src/components/TimeField/TimeField.module.scss +232 -0
  804. package/src/components/TimeField/TimeField.tsx +793 -0
  805. package/src/components/TimeField/index.ts +2 -0
  806. package/src/components/Timeline/Timeline.module.scss +58 -0
  807. package/src/components/Timeline/Timeline.tokens.scss +13 -0
  808. package/src/components/Timeline/Timeline.tsx +53 -0
  809. package/src/components/Timeline/index.ts +2 -0
  810. package/src/components/Title/Title.module.scss +84 -0
  811. package/src/components/Title/Title.tokens.scss +37 -0
  812. package/src/components/Title/Title.tsx +150 -0
  813. package/src/components/Title/index.ts +2 -0
  814. package/src/components/Toast/Toast.module.scss +299 -0
  815. package/src/components/Toast/Toast.tokens.scss +65 -0
  816. package/src/components/Toast/Toast.tsx +122 -0
  817. package/src/components/Toast/ToastViewport.tsx +166 -0
  818. package/src/components/Toast/api.ts +175 -0
  819. package/src/components/Toast/index.ts +5 -0
  820. package/src/components/Toast/store.ts +133 -0
  821. package/src/components/Toast/useToastTimer.ts +94 -0
  822. package/src/components/Tooltip/Tooltip.module.scss +99 -0
  823. package/src/components/Tooltip/Tooltip.tokens.scss +23 -0
  824. package/src/components/Tooltip/Tooltip.tsx +341 -0
  825. package/src/components/Tooltip/index.ts +2 -0
  826. package/src/components/TopBar/TopBar.module.scss +235 -0
  827. package/src/components/TopBar/TopBar.tokens.scss +79 -0
  828. package/src/components/TopBar/TopBar.tsx +87 -0
  829. package/src/components/TopBar/TopBarEnd.tsx +20 -0
  830. package/src/components/TopBar/TopBarIconButton.tsx +86 -0
  831. package/src/components/TopBar/TopBarSearch.tsx +319 -0
  832. package/src/components/TopBar/TopBarSearchPanel.tsx +268 -0
  833. package/src/components/TopBar/TopBarStart.tsx +20 -0
  834. package/src/components/TopBar/index.ts +11 -0
  835. package/src/components/Tour/Spotlight.tsx +121 -0
  836. package/src/components/Tour/Tour.module.scss +210 -0
  837. package/src/components/Tour/Tour.tokens.scss +58 -0
  838. package/src/components/Tour/Tour.tsx +617 -0
  839. package/src/components/Tour/index.ts +2 -0
  840. package/src/components/Tour/useTourTarget.ts +115 -0
  841. package/src/components/TreeView/TreeView.module.scss +268 -0
  842. package/src/components/TreeView/TreeView.tokens.scss +36 -0
  843. package/src/components/TreeView/TreeView.tsx +536 -0
  844. package/src/components/TreeView/index.ts +3 -0
  845. package/src/components/TreeView/treeModel.ts +224 -0
  846. package/src/components/VisuallyHidden/VisuallyHidden.module.scss +7 -0
  847. package/src/components/VisuallyHidden/VisuallyHidden.tsx +29 -0
  848. package/src/components/VisuallyHidden/index.ts +2 -0
  849. package/src/components/WidgetPreview/WidgetPreview.module.scss +11 -0
  850. package/src/components/WidgetPreview/WidgetPreview.tokens.scss +26 -0
  851. package/src/components/WidgetPreview/WidgetPreview.tsx +36 -0
  852. package/src/components/WidgetPreview/WidgetShape.module.scss +140 -0
  853. package/src/components/WidgetPreview/WidgetShape.tsx +159 -0
  854. package/src/components/WidgetPreview/index.ts +2 -0
  855. package/src/components/_internal/Trend.tsx +27 -0
  856. package/src/components/_internal/choiceTile.scss +74 -0
  857. package/src/components/_internal/collapse.scss +10 -0
  858. package/src/components/_internal/collapse.ts +58 -0
  859. package/src/components/_internal/currency.ts +257 -0
  860. package/src/components/_internal/dragAnnouncements.ts +200 -0
  861. package/src/components/_internal/fieldWiring.ts +225 -0
  862. package/src/components/_internal/gridSpan.ts +54 -0
  863. package/src/components/_internal/isoDay.ts +35 -0
  864. package/src/components/_internal/letterKey.ts +26 -0
  865. package/src/components/_internal/overlay/focusRestore.ts +21 -0
  866. package/src/components/_internal/overlay/index.ts +12 -0
  867. package/src/components/_internal/overlay/tourHold.ts +23 -0
  868. package/src/components/_internal/overlay/useFocusTrap.ts +120 -0
  869. package/src/components/_internal/overlay/useInOverlay.ts +81 -0
  870. package/src/components/_internal/overlay/useOverlayStack.ts +232 -0
  871. package/src/components/_internal/overlay/useScrollLock.ts +112 -0
  872. package/src/components/_internal/refs.ts +48 -0
  873. package/src/components/_internal/statusColor.ts +26 -0
  874. package/src/components/_internal/timeUtils.ts +23 -0
  875. package/src/components/_internal/useAsyncOptions.ts +145 -0
  876. package/src/components/_internal/useClippedTooltip.ts +50 -0
  877. package/src/components/_internal/useControllableState.ts +50 -0
  878. package/src/components.manifest.json +1141 -0
  879. package/src/hooks/useBelowBreakpoint.ts +58 -0
  880. package/src/i18n/I18nProvider.tsx +52 -0
  881. package/src/i18n/LocaleProvider.tsx +17 -0
  882. package/src/i18n/en.ts +648 -0
  883. package/src/i18n/format.ts +71 -0
  884. package/src/i18n/index.ts +13 -0
  885. package/src/i18n/messages.ts +1275 -0
  886. package/src/i18n/ru.ts +677 -0
  887. package/src/i18n/useLocale.ts +19 -0
  888. package/src/i18n/useTranslation.ts +58 -0
  889. package/src/index.ts +913 -0
  890. package/src/palette/index.ts +2 -0
  891. package/src/palette/palette.ts +108 -0
  892. package/src/styles/dark.scss +4 -0
  893. package/src/styles/global.scss +7 -0
  894. package/src/styles/mixins.scss +143 -0
  895. package/src/styles/reset.scss +78 -0
  896. package/src/styles/tokens.scss +18 -0
  897. package/src/styles/typography.scss +44 -0
@@ -0,0 +1,538 @@
1
+ import {
2
+ forwardRef,
3
+ useEffect,
4
+ useId,
5
+ useLayoutEffect,
6
+ useRef,
7
+ useState,
8
+ type HTMLAttributes,
9
+ type KeyboardEvent,
10
+ type ReactNode,
11
+ } from 'react';
12
+ import clsx from 'clsx';
13
+ import styles from './Tabs.module.scss';
14
+
15
+ /** One tab in the tablist. */
16
+ export interface TabItem {
17
+ /** Stable identifier — used for `activeId`/`onChange` and id generation. Must be unique within the items array. */
18
+ id: string;
19
+ /** Visible label for the tab. */
20
+ label: string;
21
+ /** Optional count chip shown next to the label (e.g. "Activity · 12"). */
22
+ count?: number;
23
+ /**
24
+ * Optional leading icon rendered before the label. Typically a `lucide-react`
25
+ * icon. Sized via CSS to match the label's line height. Rendered with
26
+ * `aria-hidden="true"` (decorative — the label carries the accessible name).
27
+ */
28
+ icon?: ReactNode;
29
+ /**
30
+ * Optional leading adornment rendered before the icon/label (e.g. a status
31
+ * dot). Rendered as-is (NOT `aria-hidden`): if purely decorative mark your
32
+ * node `aria-hidden`; if meaningful, give it accessible text so it joins the
33
+ * tab's accessible name. Distinct from `icon`, which is always decorative.
34
+ */
35
+ leading?: ReactNode;
36
+ /**
37
+ * Optional trailing adornment rendered at the end of the tab (e.g. an
38
+ * unsaved-changes badge or status `Badge`). In `vertical` orientation it is
39
+ * pinned to the row's far-right edge; in `horizontal` it follows the label/
40
+ * count. Rendered as-is (NOT `aria-hidden`) — same a11y note as `leading`.
41
+ */
42
+ trailing?: ReactNode;
43
+ /**
44
+ * Interactive control(s) for this tab (a `Switch`, a close button, a `⋯`
45
+ * menu), rendered OUTSIDE the tab's `role="tab"` button so the markup is
46
+ * valid and the control is focusable and keyboard-operable. For STATIC
47
+ * adornments (a `Badge`, a status dot, a numeric count) use
48
+ * `leading`/`trailing`/`count` — those render inside the button. Not
49
+ * `aria-hidden`; give controls an accessible label. Adds a Tab stop.
50
+ */
51
+ actions?: ReactNode;
52
+ /**
53
+ * Extra `data-*` attributes spread onto this tab's `role="tab"` button
54
+ * (e.g. `{ 'data-tour': 'security-tab' }` to target it from a `Tour`, or a
55
+ * test/analytics id). Spread first, so a key here can't override the
56
+ * `id` / `role` / `aria-*` / handlers Tabs owns on the button.
57
+ */
58
+ attrs?: Record<`data-${string}`, string>;
59
+ }
60
+
61
+ /**
62
+ * A trailing action rendered after the tab items in the same strip (e.g. a
63
+ * `+ New deal` pseudo-tab). Rendered as a real `<button type="button">`, NOT
64
+ * `role="tab"` — it has no tabpanel to control, is excluded from the
65
+ * arrow-key roving order, and the animated selection indicator never targets
66
+ * it. Reachable via the Tab key like any ordinary button, right after the
67
+ * currently-focusable tab.
68
+ */
69
+ export interface TabsAction {
70
+ /** Visible label. Also the button's accessible name — no separate aria-label needed. */
71
+ label: string;
72
+ /** Optional decorative icon rendered before the label. Rendered `aria-hidden` — the label carries the accessible name. */
73
+ icon?: ReactNode;
74
+ /** Called when the button is clicked. Never changes `activeId` or fires `onChange` — wire up your own state (e.g. append a new tab) in the handler. */
75
+ onClick: () => void;
76
+ /** Disables the button (dimmed, non-interactive). Default `false`. */
77
+ disabled?: boolean;
78
+ }
79
+
80
+ /**
81
+ * Determines what happens when Arrow keys move focus between tabs.
82
+ * - `auto` (default) — focus and onChange both fire on Arrow. Best for cheap, eager-rendered panels.
83
+ * - `manual` — Arrow only moves focus; Enter/Space activates via native button click. Best for lazy-loaded panels.
84
+ */
85
+ export type TabsActivationMode = 'auto' | 'manual';
86
+
87
+ /**
88
+ * Tablist layout and `aria-orientation` value. Use `'horizontal'` (the
89
+ * default) for a conventional tab strip or `'vertical'` for a fixed
90
+ * master–detail rail. `'auto'` starts vertical and switches from vertical to
91
+ * horizontal when the available tab-strip width reaches a configurable
92
+ * breakpoint (320px by default); it is for a `Split` rail that becomes a
93
+ * full-width strip when the panes stack.
94
+ */
95
+ export type TabsOrientation = 'horizontal' | 'vertical' | 'auto';
96
+
97
+ type EffectiveTabsOrientation = Exclude<TabsOrientation, 'auto'>;
98
+
99
+ export interface TabsProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {
100
+ /** The tabs to render. Each item must have a unique `id`. */
101
+ items: TabItem[];
102
+ /** The id of the currently-active tab. If it doesn't match any item, the strip still stays keyboard-reachable (first tab gets tabindex=0). */
103
+ activeId: string;
104
+ /** Called with the tab id when the user activates a different tab. Won't fire when re-clicking the already-active tab. */
105
+ onChange: (id: string) => void;
106
+ /**
107
+ * Optional id prefix for controlled tabpanels. When set, the ACTIVE tab gets
108
+ * `aria-controls="${panelIdPrefix}-${itemId}-panel"` — the consumer must
109
+ * render the matching panel with that id. When omitted, NO tab carries
110
+ * `aria-controls` at all — the internal id (sanitized React `useId`) named
111
+ * below is the tab's own id, not a panel's, and pointing at it would be the
112
+ * dangling IDREF that was removed.
113
+ *
114
+ * Only the active tab carries it, because consumers render only the active
115
+ * panel; stamping every tab would point N-1 of them at elements that do not
116
+ * exist. Inactive tabs keep their own `id` for the panel's
117
+ * `aria-labelledby` to reference.
118
+ */
119
+ panelIdPrefix?: string;
120
+ /**
121
+ * `'auto'` (default): arrow keys move focus AND fire onChange — the visible
122
+ * panel changes with each keystroke. Best for cheap, eager-rendered panels.
123
+ *
124
+ * `'manual'`: arrow keys only move focus; Enter/Space (the native button
125
+ * activation keys) then commits via onChange. Use this when panels are
126
+ * expensive (lazy-load, network) so the user can scan tab labels without
127
+ * triggering loads.
128
+ */
129
+ activationMode?: TabsActivationMode;
130
+ /**
131
+ * `'horizontal'` (default) — a horizontal strip with a sliding underline.
132
+ * `'vertical'` — a stacked master–detail rail: full-width rows, a left accent
133
+ * bar + tinted background on the active row, and ArrowUp/ArrowDown navigation.
134
+ * `'auto'` — measures available Tabs/tab-strip width: vertical below
135
+ * `autoOrientationBreakpoint` and horizontal at or above it. It starts
136
+ * vertical during SSR and whenever `ResizeObserver` is unavailable. Use it
137
+ * with a collapsing `Split`: the fixed-width aside remains a vertical rail,
138
+ * then the full-width stacked tablist becomes horizontal. `aria-orientation`,
139
+ * keyboard navigation, and presentation always follow the effective orientation.
140
+ */
141
+ orientation?: TabsOrientation;
142
+ /**
143
+ * Available tab-strip width in px where `orientation="auto"` switches from
144
+ * vertical to horizontal. Defaults to `320`. Set this per Tabs instance to
145
+ * align automatic orientation with the surrounding layout's threshold.
146
+ * @default 320
147
+ */
148
+ autoOrientationBreakpoint?: number;
149
+ /**
150
+ * A trailing action rendered after the tab items, inside the same strip
151
+ * (e.g. `{ label: 'New deal', icon: <Plus/>, onClick: addDeal }`). Styled
152
+ * tab-like but visibly muted, never becomes the selected tab, and is
153
+ * skipped by arrow-key roving — reachable via the Tab key instead. For
154
+ * controls that apply to the whole bar but aren't shaped like a tab (a
155
+ * filter toggle), use `endContent`. For a control on a single tab, use
156
+ * `TabItem.actions`.
157
+ */
158
+ action?: TabsAction;
159
+ /**
160
+ * Controls for the whole tab bar (e.g. an "add tab" button, a filter
161
+ * toggle), rendered at the end of the strip OUTSIDE the tablist so it never
162
+ * scrolls with the tabs and is not part of tab keyboard navigation. For a
163
+ * control attached to a single tab, use `TabItem.actions` instead.
164
+ */
165
+ endContent?: ReactNode;
166
+ }
167
+
168
+ // React 19's useId() can include characters that are valid HTML id values but
169
+ // break CSS selectors (`:r0:` → `#:r0:` is not a valid selector). Sanitize to
170
+ // `[a-zA-Z0-9_-]` so the generated panel ids stay CSS-queryable.
171
+ function sanitizeId(raw: string): string {
172
+ return raw.replace(/[^a-zA-Z0-9_-]/g, '_');
173
+ }
174
+
175
+ // Some consumer environments (RSC, edge runtimes) don't define `process`.
176
+ // Read NODE_ENV defensively so the library never throws at module init.
177
+ const IS_DEV = typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production';
178
+
179
+ /**
180
+ * Responsive controlled tab strip (horizontal, vertical or auto) with count chips and leading/trailing adornments, following the WAI-ARIA Tabs pattern.
181
+ * @see docs/components/Tabs.md
182
+ */
183
+ export const Tabs = forwardRef<HTMLDivElement, TabsProps>(function Tabs(
184
+ {
185
+ items,
186
+ activeId,
187
+ onChange,
188
+ panelIdPrefix,
189
+ activationMode = 'auto',
190
+ orientation = 'horizontal',
191
+ autoOrientationBreakpoint = 320,
192
+ action,
193
+ endContent,
194
+ className,
195
+ ...props
196
+ },
197
+ ref,
198
+ ) {
199
+ const reactId = useId();
200
+ const prefix = panelIdPrefix ?? sanitizeId(reactId);
201
+ const tabRefs = useRef<Record<string, HTMLButtonElement | null>>({});
202
+ const scrollWrapRef = useRef<HTMLDivElement>(null);
203
+ const rootRef = useRef<HTMLDivElement>(null);
204
+ const endContentRef = useRef<HTMLDivElement>(null);
205
+ const indicatorRef = useRef<HTMLSpanElement>(null);
206
+ const firstMeasureRef = useRef(true);
207
+ const hasEndContent = endContent != null;
208
+ const [automaticOrientation, setAutomaticOrientation] =
209
+ useState<EffectiveTabsOrientation>('vertical');
210
+ const effectiveOrientation: EffectiveTabsOrientation =
211
+ orientation === 'auto' ? automaticOrientation : orientation;
212
+
213
+ useLayoutEffect(() => {
214
+ if (orientation !== 'auto') return;
215
+ // Measure the box that receives the available layout width, rather than
216
+ // the tablist's intrinsic inline-flex width. With end content, the strip
217
+ // shares a stable root row with controls at its end, so its horizontal
218
+ // budget is root width minus the end region's border-box width (including
219
+ // the gap padding). The end region keeps that footprint in both
220
+ // orientations, so the same measurement cannot bounce the mode at the
221
+ // boundary.
222
+ const root = hasEndContent ? rootRef.current : scrollWrapRef.current;
223
+ const end = hasEndContent ? endContentRef.current : null;
224
+ if (!root || (hasEndContent && !end) || typeof ResizeObserver === 'undefined') return;
225
+
226
+ let rootWidth = root.getBoundingClientRect().width;
227
+ let endContentWidth = end?.getBoundingClientRect().width ?? 0;
228
+ const update = () => {
229
+ const availableWidth = Math.max(0, rootWidth - endContentWidth);
230
+ setAutomaticOrientation(
231
+ availableWidth >= autoOrientationBreakpoint ? 'horizontal' : 'vertical',
232
+ );
233
+ };
234
+ const observer = new ResizeObserver((entries) => {
235
+ for (const entry of entries) {
236
+ // contentRect excludes padding, but the end-content gap consumes real
237
+ // horizontal strip space. Read the border box from the observed target.
238
+ const width = entry.target.getBoundingClientRect().width;
239
+ if (entry.target === root) rootWidth = width;
240
+ if (entry.target === end) endContentWidth = width;
241
+ }
242
+ update();
243
+ });
244
+
245
+ update();
246
+ observer.observe(root);
247
+ if (end) observer.observe(end);
248
+ return () => observer.disconnect();
249
+ }, [orientation, hasEndContent, autoOrientationBreakpoint]);
250
+
251
+ // Scroll only on real overflow. A strip sized to its own content (a
252
+ // shrink-to-fit flex item) has a fractional width, and at non-integer DPRs
253
+ // scrollWidth rounds 1px past clientWidth, so the UA shows a scrollbar for
254
+ // nothing (#710). Within 1px counts as fitting: `data-fits` turns the
255
+ // scrollbar off. Without ResizeObserver the strip simply stays scrollable.
256
+ useLayoutEffect(() => {
257
+ const wrap = scrollWrapRef.current;
258
+ const list = wrap?.firstElementChild;
259
+ if (!wrap || !list || typeof ResizeObserver === 'undefined') return;
260
+ const update = () => {
261
+ wrap.toggleAttribute('data-fits', list.getBoundingClientRect().width - wrap.clientWidth <= 1);
262
+ };
263
+ const observer = new ResizeObserver(update);
264
+ update();
265
+ observer.observe(list);
266
+ observer.observe(wrap);
267
+ return () => observer.disconnect();
268
+ // endContent re-parents the strip, which remounts the wrapper.
269
+ }, [hasEndContent]);
270
+
271
+ // Dev-only: warn on duplicate ids. The ref map would silently collapse them
272
+ // and roving tabindex would behave unpredictably. Run as an effect (not in
273
+ // render) so it fires once per items change and doesn't double-warn in
274
+ // StrictMode dev.
275
+ useEffect(() => {
276
+ if (!IS_DEV) return;
277
+ const ids = items.map((i) => i.id);
278
+ if (new Set(ids).size !== ids.length) {
279
+ console.warn('[Tabs] items contains duplicate ids:', ids);
280
+ }
281
+ }, [items]);
282
+
283
+ // Position the shared indicator. Reads layout metrics from the active tab's
284
+ // button and writes them as inline styles on the indicator. In horizontal
285
+ // mode it's an underline driven by translateX + width; in vertical mode it's
286
+ // a left accent bar driven by translateY + height. The cross-axis dimension
287
+ // is cleared each pass so a runtime orientation flip can't leave a stale
288
+ // width/height behind. useLayoutEffect (not useEffect) so the bar's new
289
+ // position is committed before paint — avoids a one-frame flash at the old
290
+ // location.
291
+ useLayoutEffect(() => {
292
+ const indicator = indicatorRef.current;
293
+ if (!indicator) return;
294
+ const node = tabRefs.current[activeId];
295
+ if (!node) {
296
+ // activeId doesn't match any item, or items is empty — hide the bar
297
+ // rather than leave it stranded mid-slide. Important: we return BEFORE
298
+ // touching firstMeasureRef, so a later "missing → valid" transition
299
+ // still gets the no-animation first-paint treatment.
300
+ indicator.style.opacity = '0';
301
+ return;
302
+ }
303
+ indicator.style.opacity = '1';
304
+
305
+ // When the active tab is wrapped in a per-tab `actions` cell
306
+ // (role="presentation"), measure the CELL so the underline spans the whole
307
+ // tab — label AND its controls — instead of just the button. Bare tabs
308
+ // (no actions) measure the button, unchanged.
309
+ const cell = node.parentElement;
310
+ const measureNode = cell && cell.getAttribute('role') === 'presentation' ? cell : node;
311
+
312
+ const vertical = effectiveOrientation === 'vertical';
313
+ const write = () => {
314
+ if (vertical) {
315
+ indicator.style.transform = `translateY(${measureNode.offsetTop}px)`;
316
+ indicator.style.height = `${measureNode.offsetHeight}px`;
317
+ indicator.style.width = ''; // CSS owns the bar thickness in vertical
318
+ } else {
319
+ indicator.style.transform = `translateX(${measureNode.offsetLeft}px)`;
320
+ indicator.style.width = `${measureNode.offsetWidth}px`;
321
+ indicator.style.height = ''; // CSS owns the bar thickness in horizontal
322
+ }
323
+ };
324
+
325
+ if (firstMeasureRef.current) {
326
+ // First paint: disable the transition for one frame so the indicator
327
+ // doesn't slide in from (0, 0) on mount.
328
+ indicator.style.transition = 'none';
329
+ write();
330
+ // Force a reflow before clearing the inline transition override so the
331
+ // first measurement lands without animation.
332
+ void indicator.offsetWidth;
333
+ indicator.style.transition = '';
334
+ firstMeasureRef.current = false;
335
+ return;
336
+ }
337
+
338
+ write();
339
+ }, [activeId, items, effectiveOrientation]);
340
+
341
+ // Focused tab can drift from activeId in manual activation mode. In auto
342
+ // mode they stay in sync because focusTab also calls onChange.
343
+ const [focusedId, setFocusedId] = useState<string>(activeId);
344
+ useEffect(() => {
345
+ setFocusedId(activeId);
346
+ }, [activeId]);
347
+
348
+ // The effective focused id ALWAYS resolves to an item (or null when items is
349
+ // empty). When `focusedId` doesn't match any item — e.g. activeId is invalid
350
+ // or the active item was just deleted — we fall back to items[0] so the
351
+ // tablist stays keyboard-reachable.
352
+ const effectiveFocusedId = items.find((i) => i.id === focusedId)?.id ?? items[0]?.id ?? null;
353
+
354
+ const focusTab = (id: string) => {
355
+ setFocusedId(id);
356
+ tabRefs.current[id]?.focus();
357
+ if (activationMode === 'auto') {
358
+ onChange(id);
359
+ }
360
+ };
361
+
362
+ const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {
363
+ // Only rove when the key originates on a tab (or the tablist itself). This
364
+ // stops Arrow/Home/End inside a per-tab `actions` control from hijacking
365
+ // tab navigation. Real roving focus always lands on a role="tab".
366
+ if (
367
+ event.target !== event.currentTarget &&
368
+ (event.target as HTMLElement).getAttribute('role') !== 'tab'
369
+ ) {
370
+ return;
371
+ }
372
+ if (items.length === 0 || effectiveFocusedId === null) return;
373
+ const currentIndex = items.findIndex((i) => i.id === effectiveFocusedId);
374
+ // Vertical strips navigate with Up/Down; horizontal with Left/Right. The
375
+ // matching `case nextKey:` below reads the active axis's keys.
376
+ const vertical = effectiveOrientation === 'vertical';
377
+ const nextKey = vertical ? 'ArrowDown' : 'ArrowRight';
378
+ const prevKey = vertical ? 'ArrowUp' : 'ArrowLeft';
379
+ let nextIndex = -1;
380
+ switch (event.key) {
381
+ case nextKey:
382
+ nextIndex = (currentIndex + 1) % items.length;
383
+ break;
384
+ case prevKey:
385
+ nextIndex = (currentIndex - 1 + items.length) % items.length;
386
+ break;
387
+ case 'Home':
388
+ nextIndex = 0;
389
+ break;
390
+ case 'End':
391
+ nextIndex = items.length - 1;
392
+ break;
393
+ default:
394
+ return;
395
+ }
396
+ event.preventDefault();
397
+ focusTab(items[nextIndex].id);
398
+ };
399
+
400
+ const strip = (
401
+ // The scroll wrapper owns overflow-x so the tablist itself stays an
402
+ // overflow-visible box — that keeps the indicator span (positioned just
403
+ // below the tablist's baseline) from being clipped by the auto-promoted
404
+ // overflow-y.
405
+ <div
406
+ ref={scrollWrapRef}
407
+ className={clsx(
408
+ styles.scrollWrap,
409
+ effectiveOrientation === 'vertical' && styles.scrollWrapVertical,
410
+ )}
411
+ >
412
+ <div
413
+ // Consumer-controlled props come first so component-owned attrs below
414
+ // (role, aria-orientation, onKeyDown, className) always win.
415
+ {...props}
416
+ ref={ref}
417
+ role="tablist"
418
+ aria-orientation={effectiveOrientation}
419
+ onKeyDown={onKeyDown}
420
+ className={clsx(
421
+ styles.tabs,
422
+ effectiveOrientation === 'vertical' && styles.vertical,
423
+ className,
424
+ )}
425
+ >
426
+ {items.map((item) => {
427
+ const active = item.id === activeId;
428
+ const focused = item.id === effectiveFocusedId;
429
+ const tabId = `${prefix}-${item.id}-tab`;
430
+ // Only meaningful with a consumer-supplied prefix — without one no
431
+ // panel carries the id, so building it would just re-create #501's
432
+ // dangling IDREF.
433
+ const panelId = panelIdPrefix ? `${prefix}-${item.id}-panel` : undefined;
434
+ const tab = (
435
+ <button
436
+ key={item.id}
437
+ // attrs first so they can't override the component-owned id/role/aria/handlers below
438
+ {...item.attrs}
439
+ ref={(el) => {
440
+ tabRefs.current[item.id] = el;
441
+ // React 19 ref-callback cleanup — runs when the element unmounts
442
+ // or this callback identity changes (i.e. when items change).
443
+ return () => {
444
+ delete tabRefs.current[item.id];
445
+ };
446
+ }}
447
+ id={tabId}
448
+ type="button"
449
+ role="tab"
450
+ aria-selected={active}
451
+ // ONLY on the active tab. Consumers render just the active
452
+ // panel — that is what this API's shape implies and what the
453
+ // docs describe — so stamping every tab shipped N-1 dangling
454
+ // IDREFs that no consumer could fix without eagerly mounting
455
+ // every panel and firing every panel's queries on first paint
456
+ // (#501). Inactive tabs keep their `id`, which is what the
457
+ // panel's `aria-labelledby` points back to, so the relationship
458
+ // is still expressed in both directions for the pair that
459
+ // actually exists.
460
+ // Also requires panelIdPrefix. Without it the prefix is a
461
+ // generated useId that no consumer can know, Tabs renders no
462
+ // panel itself, and nothing else can — so the id is not merely
463
+ // absent, it CANNOT exist. Stamping it there left the default
464
+ // configuration with exactly the dangling IDREF this fixes.
465
+ aria-controls={active && panelIdPrefix ? panelId : undefined}
466
+ tabIndex={focused ? 0 : -1}
467
+ className={clsx(styles.tab, active && styles.active)}
468
+ // Skip the onChange call when clicking the already-active tab —
469
+ // avoids unnecessary parent re-renders.
470
+ onClick={() => {
471
+ if (item.id !== activeId) onChange(item.id);
472
+ }}
473
+ >
474
+ <span className={styles.main}>
475
+ {item.leading != null && <span className={styles.leading}>{item.leading}</span>}
476
+ {item.icon != null && (
477
+ <span className={styles.icon} aria-hidden="true">
478
+ {item.icon}
479
+ </span>
480
+ )}
481
+ <span className={styles.label}>{item.label}</span>
482
+ {item.count !== undefined && <span className={styles.count}>{item.count}</span>}
483
+ </span>
484
+ {item.trailing != null && <span className={styles.trailing}>{item.trailing}</span>}
485
+ </button>
486
+ );
487
+
488
+ if (item.actions == null) return tab;
489
+ return (
490
+ <span key={item.id} role="presentation" className={styles.cell}>
491
+ {tab}
492
+ <span className={styles.tabActions}>{item.actions}</span>
493
+ </span>
494
+ );
495
+ })}
496
+ {action != null && (
497
+ // Plain button — deliberately NOT role="tab": no tabpanel to
498
+ // control, excluded from the arrow-key roving above (which only
499
+ // ever reads `items`/`tabRefs`), and never measured by the
500
+ // indicator effect (which only looks up `tabRefs[activeId]`).
501
+ // Known, accepted `aria-required-children` deviation: this leaves
502
+ // one non-"tab" child in a `role="tablist"` container, same as the
503
+ // `TabItem.actions` button above already does. A real `<button>`
504
+ // still announces correctly to AT regardless of its parent's role.
505
+ <button
506
+ type="button"
507
+ className={styles.action}
508
+ onClick={action.onClick}
509
+ disabled={action.disabled}
510
+ >
511
+ {action.icon != null && (
512
+ <span className={styles.icon} aria-hidden="true">
513
+ {action.icon}
514
+ </span>
515
+ )}
516
+ <span className={styles.label}>{action.label}</span>
517
+ </button>
518
+ )}
519
+ <span ref={indicatorRef} className={styles.indicator} aria-hidden="true" />
520
+ </div>
521
+ </div>
522
+ );
523
+
524
+ if (!hasEndContent) return strip;
525
+
526
+ return (
527
+ <div
528
+ ref={rootRef}
529
+ className={clsx(styles.root, effectiveOrientation === 'vertical' && styles.rootVertical)}
530
+ >
531
+ {strip}
532
+ {/* data-tabs-end is an internal test hook (module classes are hashed), not public API. */}
533
+ <div ref={endContentRef} data-tabs-end="" className={styles.endContent}>
534
+ {endContent}
535
+ </div>
536
+ </div>
537
+ );
538
+ });
@@ -0,0 +1,2 @@
1
+ export { Tabs } from './Tabs';
2
+ export type { TabsProps, TabItem, TabsAction, TabsActivationMode, TabsOrientation } from './Tabs';
@@ -0,0 +1,115 @@
1
+ @use './Text.tokens';
2
+
3
+ .text {
4
+ // stylelint-disable-next-line property-disallowed-list -- native <p> margin reset (component-internal, not at the boundary)
5
+ margin: 0;
6
+ font-family: var(--font-family-sans);
7
+ font-weight: var(--text-font-weight);
8
+ line-height: var(--text-line-height);
9
+ color: var(--text-fg);
10
+ }
11
+
12
+ .sizeXs {
13
+ font-size: var(--text-font-size-xs);
14
+ }
15
+
16
+ .sizeSm {
17
+ font-size: var(--text-font-size-sm);
18
+ }
19
+
20
+ .sizeMd {
21
+ font-size: var(--text-font-size-md);
22
+ }
23
+
24
+ .sizeLg {
25
+ font-size: var(--text-font-size-lg);
26
+ }
27
+
28
+ .sizeXl {
29
+ font-size: var(--text-font-size-xl);
30
+ }
31
+
32
+ // `inherit` — no fixed size: font-size AND line-height come from the parent
33
+ // (inline runs inside headings). Line-height must inherit too or Text's
34
+ // base 1.5 would inflate a tight heading's line box.
35
+ .sizeInherit {
36
+ font-size: inherit;
37
+ line-height: inherit;
38
+ }
39
+
40
+ .weightRegular {
41
+ font-weight: var(--text-font-weight-regular);
42
+ }
43
+
44
+ .weightMedium {
45
+ font-weight: var(--text-font-weight-medium);
46
+ }
47
+
48
+ .weightSemibold {
49
+ font-weight: var(--text-font-weight-semibold);
50
+ }
51
+
52
+ .weightBold {
53
+ font-weight: var(--text-font-weight-bold);
54
+ }
55
+
56
+ .toneDefault {
57
+ color: var(--text-fg-default);
58
+ }
59
+
60
+ .toneMuted {
61
+ color: var(--text-fg-muted);
62
+ }
63
+
64
+ .toneSubtle {
65
+ color: var(--text-fg-subtle);
66
+ }
67
+
68
+ .toneAccent {
69
+ color: var(--text-fg-accent);
70
+ }
71
+
72
+ .toneDanger {
73
+ color: var(--text-fg-danger);
74
+ }
75
+
76
+ .toneSuccess {
77
+ color: var(--text-fg-success);
78
+ }
79
+
80
+ .toneWarning {
81
+ color: var(--text-fg-warning);
82
+ }
83
+
84
+ .alignLeft {
85
+ // stylelint-disable-next-line scale-unlimited/declaration-strict-value -- text-align keywords don't have tokens
86
+ text-align: left;
87
+ }
88
+
89
+ .alignCenter {
90
+ // stylelint-disable-next-line scale-unlimited/declaration-strict-value -- text-align keywords don't have tokens
91
+ text-align: center;
92
+ }
93
+
94
+ .alignRight {
95
+ // stylelint-disable-next-line scale-unlimited/declaration-strict-value -- text-align keywords don't have tokens
96
+ text-align: right;
97
+ }
98
+
99
+ .truncate {
100
+ overflow: hidden;
101
+ text-overflow: ellipsis;
102
+ white-space: nowrap;
103
+
104
+ // Allow shrinkage below intrinsic size inside flex/grid parents — without
105
+ // this, the truncate has no effect when the heading is a flex/grid child.
106
+ min-width: 0;
107
+ }
108
+
109
+ .lineClamp {
110
+ display: -webkit-box;
111
+ -webkit-box-orient: vertical;
112
+ overflow: hidden;
113
+
114
+ // -webkit-line-clamp value is set inline via style (dynamic), not a class.
115
+ }