@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,205 @@
1
+ import {
2
+ forwardRef,
3
+ type ComponentPropsWithRef,
4
+ type ComponentPropsWithoutRef,
5
+ type CSSProperties,
6
+ type ElementType,
7
+ type ForwardedRef,
8
+ type ReactElement,
9
+ } from 'react';
10
+ import clsx from 'clsx';
11
+ import { paletteTokens, type PaletteColor } from '../../palette/palette';
12
+ import styles from './Button.module.scss';
13
+
14
+ /** Visual variant. See ButtonProps#variant for when to use each. */
15
+ export type ButtonVariant =
16
+ | 'primary'
17
+ | 'secondary'
18
+ | 'ghost'
19
+ | 'danger'
20
+ | 'danger-outline'
21
+ | 'success';
22
+
23
+ /** Control height. See ButtonProps#size for when to use each. */
24
+ export type ButtonSize = 'xs' | 'sm' | 'md' | 'lg';
25
+
26
+ interface ButtonOwnProps {
27
+ /**
28
+ * Visual variant.
29
+ * - `primary` (default) — the section's main action. Use **one** per page section.
30
+ * - `secondary` — supporting actions like "Cancel", "Export", "Filter".
31
+ * - `ghost` — tertiary actions in dense UIs (toolbar buttons, row actions).
32
+ * - `danger` — destructive operations only (Delete, Revoke, Remove). Pair with a confirmation if irreversible.
33
+ * - `danger-outline` — a destructive action that must not dominate: surface
34
+ * fill, danger text and border. For a Remove repeated on every row, or a
35
+ * destructive action beside a primary one. Use filled `danger` for the
36
+ * confirm step itself.
37
+ * - `success` — **transient confirmation only**, not an initial state. Flip to
38
+ * `success` for ~1.5s after an action resolves (Save → "Saved!"), then
39
+ * flip back. Never render a button as `success` on mount — it has no
40
+ * action-intent meaning, only post-action feedback. See the `@example`
41
+ * below for the timer pattern.
42
+ */
43
+ variant?: ButtonVariant;
44
+ /**
45
+ * Control height (matches the shared `--size-*` scale used by Input and Avatar).
46
+ * - `xs` (20px) — icon-only or very dense inline actions (row controls,
47
+ * chip-adjacent buttons). Pass `aria-label` when icon-only. Below WCAG
48
+ * 2.5.5 Level AAA touch-target guidance; reserve for desktop-first surfaces.
49
+ * - `sm` (24px) — dense toolbars, tables, inline actions.
50
+ * - `md` (32px, default) — most contexts.
51
+ * - `lg` (40px) — marketing-style empty states or emphasized primary actions.
52
+ */
53
+ size?: ButtonSize;
54
+ /**
55
+ * Render the button as a square icon-only target — `aspect-ratio` is forced
56
+ * to 1 so width tracks the size's `height` token (`xs` → 20×20, `sm` → 24×24,
57
+ * `md` → 32×32, `lg` → 40×40) and `padding` is tightened to a small inset
58
+ * (4px) so the icon has breathing room without changing the outer shape.
59
+ *
60
+ * **Always pass `aria-label`** when `iconOnly` is set, otherwise the button
61
+ * has no accessible name. Pass a single icon as `children`.
62
+ *
63
+ * Use for inline density (row controls, chip-adjacent actions, toolbar
64
+ * affordances). For an icon + short text label, leave `iconOnly` off — the
65
+ * button will lay out as a normal rectangle with the existing gap.
66
+ */
67
+ iconOnly?: boolean;
68
+ /**
69
+ * Controlled persistent paint for an applied filter or toolbar value.
70
+ * Selected paint applies only to `secondary` and `ghost` Buttons;
71
+ * `primary`, `danger`, and `success` retain their intent paint. This prop is
72
+ * visual only and does not add toggle-button semantics. Pass native
73
+ * `aria-pressed` explicitly only when activating the Button itself toggles
74
+ * the selected state; menu and disclosure triggers keep their own semantics.
75
+ * The consumer owns the state. Not for transient success feedback or for
76
+ * mutually exclusive `<ButtonGroup>` choices. Defaults to `undefined` (not
77
+ * selected).
78
+ */
79
+ selected?: boolean;
80
+ /**
81
+ * Paint the button with a palette color's soft pair
82
+ * (`--color-palette-<color>-bg` fill, `-fg` text) — the same pair a
83
+ * palette-colored `<PillMenu>` or `<Badge color>` uses, in both themes.
84
+ * For a quick action that moves a record to a status and must look like
85
+ * that status's pill (amber "No show" beside an amber status PillMenu).
86
+ * Not a decorative stand-in for `danger`/`success`: palette colors carry
87
+ * no meaning. When set it wins over `variant` and `selected` (like
88
+ * `<Badge color>` over `tone`). Hover/pressed darken via
89
+ * `filter: brightness()`. Defaults to `undefined` (use `variant`).
90
+ */
91
+ color?: PaletteColor;
92
+ }
93
+
94
+ /**
95
+ * Polymorphic props helper. Intersects the component's own props with the
96
+ * underlying element's props (minus what we own), plus the `as` selector.
97
+ * Mirrors `<Link>`.
98
+ */
99
+ type PolymorphicProps<C extends ElementType, P> = P & {
100
+ /**
101
+ * Render a different element — the case that matters is `as="a"` with
102
+ * `href`, for a link that must LOOK like a button (an external console, a
103
+ * download, an IdP hand-off). The element named here is what actually
104
+ * renders, and its own attributes are typed: `href` is REQUIRED when
105
+ * `as="a"` (an anchor without one is neither focusable nor a link) and
106
+ * rejected otherwise; `target`/`rel`/`download` come through. Never navigate from `onClick`.
107
+ *
108
+ * Reach for `<Link>` first. `<Link>` is link-SHAPED navigation — inline text
109
+ * in a sentence, a table cell, a breadcrumb. `<Button as="a">` is for a
110
+ * destination that sits in a row of buttons and must carry their weight.
111
+ * Either way the element is a real anchor, so assistive tech announces a
112
+ * link and the browser gives middle-click, "open in new tab", and the status
113
+ * bar preview — none of which a `<button onClick={() => navigate()}>` has.
114
+ *
115
+ * `type="button"` is emitted only for a real `<button>`; an anchor never
116
+ * gets it. Everything else — variant, size, `iconOnly`, `selected`, the
117
+ * focus ring — is unchanged.
118
+ *
119
+ * @default 'button'
120
+ */
121
+ as?: C;
122
+ } & Omit<ComponentPropsWithoutRef<C>, keyof P | 'as'> &
123
+ // `href` is optional on every anchor in the DOM typings, so `as="a"` alone
124
+ // would compile to an element that is neither focusable nor a link — the
125
+ // silent shape #530 is about. Required here instead. The conditional is
126
+ // deferred until `C` is known, so `as={RouterLink}` (which names its URL
127
+ // prop `to`) and every non-anchor element are untouched.
128
+ (C extends 'a' ? { href: string } : unknown);
129
+
130
+ /**
131
+ * Public Button prop type. Generic `C` defaults to `'button'`, so a Button
132
+ * with no `as` accepts exactly the `<button>` attributes it always did — and
133
+ * still rejects `href`. With `as="a"`, the anchor's attributes (`href`,
134
+ * `target`, `rel`, `download`) become available instead.
135
+ */
136
+ export type ButtonProps<C extends ElementType = 'button'> = PolymorphicProps<C, ButtonOwnProps>;
137
+
138
+ /**
139
+ * Internal generic-preserving signature. React's `forwardRef` strips the
140
+ * generic from the returned component, so it is re-attached via the cast on
141
+ * the export below.
142
+ */
143
+ type ButtonComponent = {
144
+ <C extends ElementType = 'button'>(
145
+ props: ButtonProps<C> & { ref?: ComponentPropsWithRef<C>['ref'] },
146
+ ): ReactElement | null;
147
+ /** Kept on the type because the cast below would otherwise drop it. */
148
+ displayName?: string;
149
+ };
150
+
151
+ /**
152
+ * Action trigger. Renders a `<button type="button">` and forwards refs and HTML attributes.
153
+ * @see docs/components/Button.md
154
+ */
155
+ export const Button = forwardRef(function Button<C extends ElementType = 'button'>(
156
+ {
157
+ as,
158
+ variant = 'primary',
159
+ size = 'md',
160
+ iconOnly = false,
161
+ selected,
162
+ color,
163
+ className,
164
+ style,
165
+ ...props
166
+ }: ButtonProps<C>,
167
+ ref: ForwardedRef<Element>,
168
+ ) {
169
+ const Component = (as || 'button') as ElementType;
170
+ const palette = color ? paletteTokens(color) : undefined;
171
+ const paintsSelected = !palette && selected && (variant === 'secondary' || variant === 'ghost');
172
+
173
+ // `type="button"` is a <button>-only guarantee — it stops the button
174
+ // submitting an ancestor form. An anchor's `type` is a MIME hint, so
175
+ // emitting the default there would be wrong; #530 rendered a <button> with a
176
+ // dead `href` for the mirror-image reason. A consumer-supplied `type` still
177
+ // wins: it rides along in {...props}, spread last.
178
+ const defaultType = Component === 'button' ? { type: 'button' as const } : undefined;
179
+
180
+ return (
181
+ <Component
182
+ ref={ref}
183
+ {...defaultType}
184
+ className={clsx(
185
+ styles.button,
186
+ palette ? styles.palette : styles[variant],
187
+ styles[size],
188
+ iconOnly && styles.iconOnly,
189
+ paintsSelected && styles.selected,
190
+ className,
191
+ )}
192
+ style={
193
+ palette
194
+ ? ({
195
+ '--button-palette-bg': palette.bg,
196
+ '--button-palette-fg': palette.fg,
197
+ ...style,
198
+ } as CSSProperties)
199
+ : style
200
+ }
201
+ // {...props} last so consumers can supply native semantics such as aria-pressed.
202
+ {...props}
203
+ />
204
+ );
205
+ }) as ButtonComponent;
@@ -0,0 +1,2 @@
1
+ export { Button } from './Button';
2
+ export type { ButtonProps, ButtonVariant, ButtonSize } from './Button';
@@ -0,0 +1,134 @@
1
+ @use '../../styles/mixins' as *;
2
+ @use './ButtonGroup.tokens';
3
+
4
+ // ─── Visual mode ────────────────────────────────────────────────────────
5
+ // Joined Button children: flatten inner borders, round outer corners.
6
+ // Targets the native `> button` element so we don't have to know Button's
7
+ // CSS Module hash.
8
+
9
+ .group[data-mode='visual'] {
10
+ display: inline-flex;
11
+
12
+ // Don't stretch to fill cross-axis when placed inside a flex/grid parent
13
+ // (e.g. Stack with default align="stretch"). A joined button group is an
14
+ // intrinsically compact UI control — like Button itself, like Tabs — and
15
+ // should not expand to container width. Rule 4 disallows align-self in
16
+ // general; this is the documented exception for inline-shaped UI controls.
17
+ // stylelint-disable-next-line property-disallowed-list -- inline control intrinsic shrink
18
+ align-self: flex-start;
19
+ }
20
+
21
+ .group[data-mode='visual'] > button {
22
+ border-radius: 0;
23
+
24
+ // -1px margin pulls each adjacent border into a single line. Rule 4 normally
25
+ // disallows margin on components, but this is the canonical border-collapse
26
+ // technique for joined buttons — transform: translateX doesn't work because
27
+ // it leaves the cumulative seam-to-seam gap uncollapsed past the first pair.
28
+ // stylelint-disable-next-line property-disallowed-list -- border-collapse for joined siblings
29
+ margin-left: calc(var(--border-width) * -1);
30
+ }
31
+
32
+ .group[data-mode='visual'] > button:first-child {
33
+ // stylelint-disable-next-line property-disallowed-list -- counterpart to the join above
34
+ margin-left: 0;
35
+ border-top-left-radius: var(--button-group-radius);
36
+ border-bottom-left-radius: var(--button-group-radius);
37
+ }
38
+
39
+ .group[data-mode='visual'] > button:last-child {
40
+ border-top-right-radius: var(--button-group-radius);
41
+ border-bottom-right-radius: var(--button-group-radius);
42
+ }
43
+
44
+ // Lift on hover/focus. NOT for the ring — an outline paints after every
45
+ // descendant background in its stacking context, so it already draws over a
46
+ // joined sibling unlifted, and the segmented lift added on that false premise
47
+ // was removed. This is for the BORDER: these children collapse their borders
48
+ // with `margin-left: -1px`, so without the lift the later sibling's left border
49
+ // paints over the hovered button's right one.
50
+ .group[data-mode='visual'] > button:hover,
51
+ .group[data-mode='visual'] > button:focus-visible {
52
+ position: relative;
53
+ z-index: 1;
54
+ }
55
+
56
+ // ─── Segmented mode ─────────────────────────────────────────────────────
57
+ // Pill-inset look matching iOS / Material precedent. Owns its own styling
58
+ // — items are NOT Buttons, they're internal radio-role <button>s.
59
+
60
+ .group[data-mode='segmented'] {
61
+ background: var(--button-group-segmented-bg);
62
+ border-radius: var(--button-group-segmented-radius);
63
+ padding: var(--button-group-segmented-padding);
64
+ display: inline-flex;
65
+ gap: var(--button-group-segmented-gap);
66
+
67
+ // Shrink-to-content inside flex/grid parents (e.g. Stack with align=stretch).
68
+ // Documented Rule-4 exception for intrinsically compact inline controls.
69
+ // stylelint-disable-next-line property-disallowed-list -- inline control intrinsic shrink
70
+ align-self: flex-start;
71
+ }
72
+
73
+ .item {
74
+ border: none;
75
+ background: transparent;
76
+ color: var(--button-group-item-fg);
77
+ cursor: pointer;
78
+ font: inherit;
79
+ white-space: nowrap;
80
+ border-radius: calc(var(--button-group-segmented-radius) - var(--button-group-segmented-padding));
81
+ transition:
82
+ background var(--transition-fast),
83
+ color var(--transition-fast);
84
+ }
85
+
86
+ .item[data-selected] {
87
+ background: var(--button-group-item-bg-selected);
88
+ color: var(--button-group-item-fg-selected);
89
+ box-shadow: var(--button-group-item-shadow-selected);
90
+ }
91
+
92
+ .item:hover:not([data-selected], [aria-disabled]) {
93
+ color: var(--button-group-item-fg-hover);
94
+ }
95
+
96
+ .item[aria-disabled] {
97
+ cursor: not-allowed;
98
+ opacity: var(--button-group-item-opacity-disabled);
99
+ }
100
+
101
+ .item:focus-visible {
102
+ @include focus-ring;
103
+ }
104
+
105
+ // Size variants — the TRACK matches Button's --size-* height, so a segmented
106
+ // control lines up with a same-size Button. Items give back the track's
107
+ // padding on both sides.
108
+ .sizeXs {
109
+ height: calc(var(--button-group-item-height-xs) - 2 * var(--button-group-segmented-padding));
110
+ padding: 0 var(--button-group-item-padding-x-xs);
111
+ font-size: var(--button-group-item-font-size-xs);
112
+
113
+ // 16px item: pin the line box so an inherited taller line-height (e.g.
114
+ // 1.5 × 11px = 16.5px from a consumer ancestor) can't overflow it.
115
+ line-height: var(--line-height-none);
116
+ }
117
+
118
+ .sizeSm {
119
+ height: calc(var(--button-group-item-height-sm) - 2 * var(--button-group-segmented-padding));
120
+ padding: 0 var(--button-group-item-padding-x-sm);
121
+ font-size: var(--button-group-item-font-size-sm);
122
+ }
123
+
124
+ .sizeMd {
125
+ height: calc(var(--button-group-item-height-md) - 2 * var(--button-group-segmented-padding));
126
+ padding: 0 var(--button-group-item-padding-x-md);
127
+ font-size: var(--button-group-item-font-size-md);
128
+ }
129
+
130
+ .sizeLg {
131
+ height: calc(var(--button-group-item-height-lg) - 2 * var(--button-group-segmented-padding));
132
+ padding: 0 var(--button-group-item-padding-x-lg);
133
+ font-size: var(--button-group-item-font-size-lg);
134
+ }
@@ -0,0 +1,42 @@
1
+ // ButtonGroup.tokens.scss — component-scoped tokens for <ButtonGroup>. Visual mode joins Button children; segmented mode owns its own pill-inset styling.
2
+ :root {
3
+ // Visual mode — outer-corner radius applied to first/last children
4
+ --button-group-radius: var(--radius-md);
5
+
6
+ // Segmented mode — track surface + shape
7
+ --button-group-segmented-bg: var(--color-bg-muted);
8
+ --button-group-segmented-radius: var(--radius-md);
9
+ --button-group-segmented-padding: var(--space-05);
10
+ --button-group-segmented-gap: var(--space-05);
11
+
12
+ // Segmented item — base appearance
13
+ --button-group-item-fg: var(--color-fg-muted);
14
+ --button-group-item-fg-hover: var(--color-fg);
15
+
16
+ // Segmented item — selected state
17
+ --button-group-item-bg-selected: var(--color-bg);
18
+ --button-group-item-fg-selected: var(--color-fg);
19
+
20
+ // --shadow-xs has never existed; the scale is sm/md/lg, so this resolved to
21
+ // nothing and the selected item rendered with no shadow at all. sm is the
22
+ // smallest step and what "xs" was reaching for.
23
+ --button-group-item-shadow-selected: var(--shadow-sm);
24
+
25
+ // Segmented item — disabled
26
+ --button-group-item-opacity-disabled: var(--opacity-disabled);
27
+
28
+ // Segmented — sizes. Height = the outer TRACK (matches Button --size-*);
29
+ // each item renders at this minus 2 × --button-group-segmented-padding.
30
+ --button-group-item-height-xs: var(--size-xs);
31
+ --button-group-item-height-sm: var(--size-sm);
32
+ --button-group-item-height-md: var(--size-md);
33
+ --button-group-item-height-lg: var(--size-lg);
34
+ --button-group-item-padding-x-xs: var(--space-2);
35
+ --button-group-item-padding-x-sm: var(--space-3);
36
+ --button-group-item-padding-x-md: var(--space-3);
37
+ --button-group-item-padding-x-lg: var(--space-4);
38
+ --button-group-item-font-size-xs: var(--font-size-xs);
39
+ --button-group-item-font-size-sm: var(--font-size-sm);
40
+ --button-group-item-font-size-md: var(--font-size-md);
41
+ --button-group-item-font-size-lg: var(--font-size-md);
42
+ }
@@ -0,0 +1,278 @@
1
+ import {
2
+ Children,
3
+ cloneElement,
4
+ isValidElement,
5
+ useCallback,
6
+ useEffect,
7
+ useMemo,
8
+ useRef,
9
+ useState,
10
+ type CSSProperties,
11
+ type HTMLAttributes,
12
+ type KeyboardEvent,
13
+ type ReactElement,
14
+ } from 'react';
15
+ import clsx from 'clsx';
16
+ import { Button, type ButtonProps } from '../Button';
17
+ import { ButtonGroupContext, type ButtonGroupContextValue, type ButtonGroupSize } from './context';
18
+ import { ButtonGroupItem } from './ButtonGroupItem';
19
+ import styles from './ButtonGroup.module.scss';
20
+
21
+ export type { ButtonGroupSize } from './context';
22
+ export type { ButtonGroupItemProps } from './ButtonGroupItem';
23
+
24
+ interface ButtonGroupBase {
25
+ /**
26
+ * Size propagated to children. Per-child `size` (Button or Item) wins
27
+ * when explicitly set. In visual mode this happens via cloneElement on
28
+ * Button children. In segmented mode, `<ButtonGroup.Item>` reads from
29
+ * context.
30
+ */
31
+ size?: ButtonGroupSize;
32
+ /**
33
+ * Disabled state for the whole group. In segmented mode this is
34
+ * authoritative (all items become aria-disabled, clicks no-op). In
35
+ * visual mode this is a no-op — pass `disabled` per `<Button>` instead.
36
+ */
37
+ disabled?: boolean;
38
+ /**
39
+ * Segmented mode: `aria-invalid` on the radiogroup. Visual mode: consumed
40
+ * and ignored. Field / SettingRow inject it — it used to leak onto the
41
+ * group div as a stray attribute (#568). @default false
42
+ */
43
+ invalid?: boolean;
44
+ /**
45
+ * Segmented mode: `aria-required` on the radiogroup. Visual mode: consumed
46
+ * and ignored. Field / SettingRow inject it (#568). @default false
47
+ */
48
+ required?: boolean;
49
+ className?: string;
50
+ style?: CSSProperties;
51
+ }
52
+
53
+ interface ButtonGroupVisualProps
54
+ extends ButtonGroupBase, Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {
55
+ /** Visual mode marker. Never set; absence flips to visual. */
56
+ value?: never;
57
+ onValueChange?: never;
58
+ /** Accessible name for the group landmark. Optional but recommended. */
59
+ 'aria-label'?: string;
60
+ }
61
+
62
+ interface ButtonGroupSegmentedProps
63
+ extends ButtonGroupBase, Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {
64
+ /** Currently-selected item value. Triggers segmented mode. */
65
+ value: string;
66
+ /**
67
+ * Fired when a different Item is selected.
68
+ *
69
+ * Consumers wanting literal-union narrowing can cast the setter:
70
+ * `onValueChange={(v) => setView(v as 'grid' | 'list')}`.
71
+ */
72
+ onValueChange: (next: string) => void;
73
+ /** Required in segmented mode (radiogroup needs a label). */
74
+ 'aria-label': string;
75
+ /** Alternative to aria-label: id of an external labelling element. */
76
+ 'aria-labelledby'?: string;
77
+ }
78
+
79
+ export type ButtonGroupProps = ButtonGroupVisualProps | ButtonGroupSegmentedProps;
80
+
81
+ /**
82
+ * Compound. Visual mode joins Buttons; segmented mode (`value` + `onValueChange`) is a single-select radiogroup.
83
+ * @see docs/components/ButtonGroup.md
84
+ */
85
+ export function ButtonGroupRoot(props: ButtonGroupProps) {
86
+ const isSegmented = 'value' in props && props.value !== undefined;
87
+ return isSegmented ? (
88
+ <Segmented {...(props as ButtonGroupSegmentedProps)} />
89
+ ) : (
90
+ <Visual {...(props as ButtonGroupVisualProps)} />
91
+ );
92
+ }
93
+
94
+ function Visual({
95
+ size = 'md',
96
+ disabled: _disabled,
97
+ // Consumed so Field-injected props never reach the div (#568).
98
+ invalid: _invalid,
99
+ required: _required,
100
+ children,
101
+ className,
102
+ style,
103
+ 'aria-label': ariaLabel,
104
+ ...rest
105
+ }: ButtonGroupVisualProps) {
106
+ // Inject size into Button children whose size isn't already set.
107
+ const processed = Children.map(children, (child) => {
108
+ if (!isValidElement(child)) return child;
109
+ if (child.type !== Button) return child;
110
+ const childProps = child.props as ButtonProps;
111
+ if (childProps.size !== undefined) return child;
112
+ return cloneElement(child as ReactElement<ButtonProps>, { size });
113
+ });
114
+
115
+ return (
116
+ <div
117
+ {...rest}
118
+ // {...rest} first so the ARIA contract (role, aria-label, data-mode)
119
+ // can't be silently broken by a stray consumer prop.
120
+ role="group"
121
+ aria-label={ariaLabel}
122
+ data-mode="visual"
123
+ className={clsx(styles.group, className)}
124
+ style={style}
125
+ >
126
+ {processed}
127
+ </div>
128
+ );
129
+ }
130
+
131
+ function Segmented({
132
+ size = 'md',
133
+ disabled = false,
134
+ value,
135
+ onValueChange,
136
+ children,
137
+ className,
138
+ style,
139
+ 'aria-label': ariaLabel,
140
+ 'aria-labelledby': ariaLabelledBy,
141
+ invalid = false,
142
+ required = false,
143
+ ...rest
144
+ }: ButtonGroupSegmentedProps) {
145
+ // groupRef enables DOM-order querying for keyboard nav so that consumer-
146
+ // reordered children are always walked in their actual visual order.
147
+ const groupRef = useRef<HTMLDivElement | null>(null);
148
+
149
+ // Dev warning: aria-label or aria-labelledby required in segmented mode.
150
+ useEffect(() => {
151
+ if (process.env.NODE_ENV === 'production') return;
152
+ let cancelled = false;
153
+ queueMicrotask(() => {
154
+ if (cancelled) return;
155
+ if (!ariaLabel && !ariaLabelledBy) {
156
+ console.warn(
157
+ '<ButtonGroup> in segmented mode requires an `aria-label` or `aria-labelledby` prop for screen readers.',
158
+ );
159
+ }
160
+ });
161
+ return () => {
162
+ cancelled = true;
163
+ };
164
+ }, [ariaLabel, ariaLabelledBy]);
165
+
166
+ // Which item holds the tab stop when nothing is selected. Read from the DOM
167
+ // after each commit so consumer-reordered children resolve in visual order,
168
+ // exactly like handleItemKeyDown below. Runs unconditionally but only sets
169
+ // state when the answer actually changes, so it cannot loop.
170
+ const [rovingFallbackValue, setRovingFallbackValue] = useState<string | null>(null);
171
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- runs after every commit by design; the setter bails out when unchanged
172
+ useEffect(() => {
173
+ const root = groupRef.current;
174
+ if (!root) return;
175
+ const items = [...root.querySelectorAll<HTMLButtonElement>('button[role="radio"]')];
176
+ const anySelected = items.some((el) => el.getAttribute('aria-checked') === 'true');
177
+ const firstEnabled = items.find((el) => el.getAttribute('aria-disabled') !== 'true');
178
+ // `?? items[0]` for the all-disabled group. Items carry `aria-disabled`,
179
+ // not the native `disabled`, precisely so they STAY focusable — a user can
180
+ // tab to them and hear why the choice is unavailable. Falling back to null
181
+ // here left every item at `tabIndex={-1}`, so the group vanished from the
182
+ // tab order entirely, which is the behaviour `aria-disabled` was chosen to
183
+ // avoid.
184
+ const next = anySelected ? null : ((firstEnabled ?? items[0])?.dataset.value ?? null);
185
+ setRovingFallbackValue((prev) => (prev === next ? prev : next));
186
+ });
187
+
188
+ const handleItemKeyDown = useCallback(
189
+ (e: KeyboardEvent<HTMLButtonElement>, currentValue: string) => {
190
+ const root = groupRef.current;
191
+ if (!root) return;
192
+ // Query DOM order so reordered children are walked correctly.
193
+ const allButtons = Array.from(
194
+ root.querySelectorAll<HTMLButtonElement>('button[role="radio"]'),
195
+ );
196
+ const enabledButtons = allButtons.filter(
197
+ (btn) => btn.getAttribute('aria-disabled') !== 'true',
198
+ );
199
+ if (enabledButtons.length === 0) return;
200
+
201
+ // Find the focused button in the enabled list. If the currently-selected
202
+ // item is itself disabled (per-item disabled), fall back to the active
203
+ // element so Arrow nav still works from wherever focus is.
204
+ let idx = enabledButtons.findIndex((btn) => btn.dataset.value === currentValue);
205
+ if (idx === -1) {
206
+ // Selected item is disabled — use whichever enabled button is focused.
207
+ idx = enabledButtons.findIndex((btn) => btn === document.activeElement);
208
+ }
209
+ if (idx === -1) return;
210
+
211
+ let nextIdx: number | null = null;
212
+ switch (e.key) {
213
+ case 'ArrowRight':
214
+ case 'ArrowDown':
215
+ nextIdx = (idx + 1) % enabledButtons.length;
216
+ break;
217
+ case 'ArrowLeft':
218
+ case 'ArrowUp':
219
+ nextIdx = (idx - 1 + enabledButtons.length) % enabledButtons.length;
220
+ break;
221
+ case 'Home':
222
+ nextIdx = 0;
223
+ break;
224
+ case 'End':
225
+ nextIdx = enabledButtons.length - 1;
226
+ break;
227
+ default:
228
+ return;
229
+ }
230
+
231
+ e.preventDefault();
232
+ const next = enabledButtons[nextIdx]!;
233
+ if (!disabled) onValueChange(next.dataset.value!);
234
+ next.focus();
235
+ },
236
+ [disabled, onValueChange],
237
+ );
238
+
239
+ const contextValue = useMemo<ButtonGroupContextValue>(
240
+ () => ({
241
+ value,
242
+ onValueChange,
243
+ size,
244
+ disabled,
245
+ handleItemKeyDown,
246
+ rovingFallbackValue,
247
+ }),
248
+ [value, onValueChange, size, disabled, handleItemKeyDown, rovingFallbackValue],
249
+ );
250
+
251
+ return (
252
+ <ButtonGroupContext.Provider value={contextValue}>
253
+ <div
254
+ ref={groupRef}
255
+ {...rest}
256
+ // {...rest} first so the ARIA contract (role, aria-label, data-mode)
257
+ // can't be silently broken by a stray consumer prop.
258
+ role="radiogroup"
259
+ aria-label={ariaLabel}
260
+ aria-labelledby={ariaLabelledBy}
261
+ aria-disabled={disabled || undefined}
262
+ aria-invalid={invalid || undefined}
263
+ aria-required={required || undefined}
264
+ data-mode="segmented"
265
+ className={clsx(styles.group, className)}
266
+ style={style}
267
+ >
268
+ {children}
269
+ </div>
270
+ </ButtonGroupContext.Provider>
271
+ );
272
+ }
273
+
274
+ /**
275
+ * Compound: `<ButtonGroup>` with `<ButtonGroup.Item>` attached.
276
+ * @see docs/components/ButtonGroup.md
277
+ */
278
+ export const ButtonGroup = Object.assign(ButtonGroupRoot, { Item: ButtonGroupItem });