@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,74 @@
1
+ // Shared look for DateStrip / SlotGrid tiles: a <label> wrapping a visually
2
+ // hidden native radio. Unchecked = Button secondary, checked = Button primary.
3
+ // Consumers of the mixin pass their component tokens so each stays themable.
4
+ @use '../../styles/mixins' as *;
5
+
6
+ @mixin choice-tile(
7
+ $input,
8
+ $bg,
9
+ $bg-hover,
10
+ $fg,
11
+ $border,
12
+ $bg-checked,
13
+ $bg-checked-hover,
14
+ $fg-checked,
15
+ $radius,
16
+ $ring,
17
+ $opacity-disabled
18
+ ) {
19
+ display: flex;
20
+ flex-direction: column;
21
+ align-items: center;
22
+ justify-content: center;
23
+ width: 100%;
24
+ border: var(--border-width) solid $border;
25
+ border-radius: $radius;
26
+ background: $bg;
27
+ color: $fg;
28
+ font: inherit;
29
+ cursor: pointer;
30
+ user-select: none;
31
+ transition:
32
+ background var(--transition-fast),
33
+ border-color var(--transition-fast),
34
+ color var(--transition-fast);
35
+
36
+ #{$input} {
37
+ @include visually-hidden;
38
+ }
39
+
40
+ &:hover:not(:has(#{$input}:disabled)) {
41
+ background: $bg-hover;
42
+ }
43
+
44
+ &:has(#{$input}:checked) {
45
+ border-color: transparent;
46
+ background: $bg-checked;
47
+ color: $fg-checked;
48
+ }
49
+
50
+ &:has(#{$input}:checked):hover {
51
+ background: $bg-checked-hover;
52
+ }
53
+
54
+ &:has(#{$input}:focus-visible) {
55
+ @include focus-ring($ring);
56
+ }
57
+
58
+ &:has(#{$input}:disabled) {
59
+ opacity: $opacity-disabled;
60
+ cursor: not-allowed;
61
+ }
62
+
63
+ // Forced colors (Windows High Contrast) drops backgrounds, which is all
64
+ // that marks the checked tile — add an outline outside its border (text
65
+ // color, forced to a system color) so checked still reads as different.
66
+ // Not while focus-visible: this rule would come after the focus ring and
67
+ // replace it (arrows select as they move, so the focused tile is usually
68
+ // the checked one) — the ring is the stronger signal there.
69
+ @media (forced-colors: active) {
70
+ &:has(#{$input}:checked:not(:focus-visible)) {
71
+ outline: var(--border-width) solid currentcolor;
72
+ }
73
+ }
74
+ }
@@ -0,0 +1,10 @@
1
+ // Container-width collapse thresholds shared by Grid's `collapseBelow` and
2
+ // Sortable's grid-arrangement `collapseBelow`. SCSS constants (not CSS custom
3
+ // properties): container-query conditions can't read custom properties.
4
+ // Keep in sync with the CollapseBreakpoint JSDoc AND the COLLAPSE_BREAKPOINT_PX
5
+ // record in collapse.ts — Rail evaluates the same scale in JS via matchMedia
6
+ // (against the VIEWPORT, since a container query on the rail's own width would
7
+ // be circular), so the two copies of these numbers must not drift.
8
+ $collapse-sm: 480px;
9
+ $collapse-md: 640px;
10
+ $collapse-lg: 768px;
@@ -0,0 +1,58 @@
1
+ import { createContext } from 'react';
2
+
3
+ /**
4
+ * Shared `collapseBelow` threshold scale: `sm` 480px / `md` 640px / `lg` 768px.
5
+ *
6
+ * The scale is shared; **the measurement basis is per-component**:
7
+ *
8
+ * - **Container** (`@container (max-width: …)`) for Grid / Sortable (grid
9
+ * arrangement) / Split / DashboardCanvas / DataTable. Collapsing re-templates
10
+ * content *inside* a box whose width the collapse doesn't change, so querying
11
+ * the box's own width is stable and needs no JS.
12
+ * - **Viewport** (`matchMedia`, via the `useBelowBreakpoint` hook in
13
+ * `src/hooks/`) for Rail and AppLayout's overlay sidebar. A container query
14
+ * there would be circular — the thing being measured IS what the collapse
15
+ * changes (Rail's own width 240px → 56px; the sidebar's presence in
16
+ * AppLayout's row). Rail's collapsed state also drives React behavior (Item
17
+ * tooltips, Group flyouts, section titles), which CSS can't express, so the
18
+ * threshold has to exist in JS regardless.
19
+ */
20
+ export type CollapseBreakpoint = 'sm' | 'md' | 'lg';
21
+
22
+ /**
23
+ * Pixel value of each breakpoint, for components that evaluate the threshold in
24
+ * JS (`matchMedia`) rather than in CSS.
25
+ *
26
+ * **Keep in sync with `collapse.scss`** (`$collapse-sm` / `-md` / `-lg`) — the
27
+ * SCSS constants are the CSS-side copy of these same numbers. Both are
28
+ * inclusive upper bounds: `max-width: 480px` matches AT 480px.
29
+ */
30
+ export const COLLAPSE_BREAKPOINT_PX: Record<CollapseBreakpoint, number> = {
31
+ sm: 480,
32
+ md: 640,
33
+ lg: 768,
34
+ };
35
+
36
+ /**
37
+ * Graduated collapse: breakpoint → column count. Below each breakpoint the
38
+ * grid re-templates to that many equal columns and every item's span is
39
+ * clamped to fit. E.g. `{ md: 6, sm: 1 }` = 12-col grid above 640px, 6-col
40
+ * between 480–640px, single column below 480px. When several breakpoints
41
+ * match, the smallest wins.
42
+ */
43
+ export type CollapseColumnsMap = Partial<Record<CollapseBreakpoint, number>>;
44
+
45
+ /** Largest → smallest; step CSS is declared in this order so the smallest matching breakpoint wins by source order. */
46
+ export const COLLAPSE_BREAKPOINTS: readonly CollapseBreakpoint[] = ['lg', 'md', 'sm'];
47
+
48
+ /**
49
+ * The container's graduated-collapse map, provided by Grid / Sortable (grid
50
+ * arrangement) to their Items so each can stamp per-breakpoint clamped span
51
+ * custom properties. `null` when the container has no map-form collapse.
52
+ */
53
+ export const CollapseColumnsContext = createContext<CollapseColumnsMap | null>(null);
54
+
55
+ /** Track template for a collapse step — mirrors Grid's fixed-column template. */
56
+ export function collapseTrackTemplate(columns: number): string {
57
+ return `repeat(${columns}, minmax(0, 1fr))`;
58
+ }
@@ -0,0 +1,257 @@
1
+ /** Shared currency parse/format helpers for MoneyInput / CurrencySelect. Amounts stay strings (never JS numbers). */
2
+
3
+ export type CurrencyDisplay = 'code' | 'symbol' | 'both';
4
+
5
+ /** Parsed, in-progress amount. `frac === null` → no decimal point typed; `''` → trailing point. */
6
+ export interface AmountDraft {
7
+ negative: boolean;
8
+ int: string;
9
+ frac: string | null;
10
+ }
11
+
12
+ // Callers must guard codes with isValidCurrency; the Intl helpers below assume a valid code.
13
+ export function currencyPrecision(code: string): number {
14
+ return new Intl.NumberFormat('en', { style: 'currency', currency: code }).resolvedOptions()
15
+ .maximumFractionDigits!;
16
+ }
17
+
18
+ export function currencySymbol(code: string, locale: string): string {
19
+ const parts = new Intl.NumberFormat(locale, {
20
+ style: 'currency',
21
+ currency: code,
22
+ currencyDisplay: 'symbol',
23
+ }).formatToParts(0);
24
+ return parts.find((p) => p.type === 'currency')?.value ?? code;
25
+ }
26
+
27
+ export function currencyName(code: string, locale: string): string {
28
+ try {
29
+ return new Intl.DisplayNames(locale, { type: 'currency' }).of(code) ?? code;
30
+ } catch {
31
+ return code;
32
+ }
33
+ }
34
+
35
+ export function currencyDisplayText(
36
+ code: string,
37
+ display: CurrencyDisplay,
38
+ locale: string,
39
+ ): string {
40
+ if (display === 'code') return code;
41
+ const symbol = currencySymbol(code, locale);
42
+ return display === 'symbol' ? symbol : `${code} ${symbol}`;
43
+ }
44
+
45
+ export function isValidCurrency(code: string): boolean {
46
+ try {
47
+ new Intl.NumberFormat('en', { style: 'currency', currency: code });
48
+ return true;
49
+ } catch {
50
+ return false;
51
+ }
52
+ }
53
+
54
+ export function localeSeparators(locale: string): { group: string; decimal: string } {
55
+ const parts = new Intl.NumberFormat(locale).formatToParts(1234.5);
56
+ return {
57
+ group: parts.find((p) => p.type === 'group')?.value ?? ',',
58
+ decimal: parts.find((p) => p.type === 'decimal')?.value ?? '.',
59
+ };
60
+ }
61
+
62
+ /** Space-like grouping chars allowed inside a pasted number (one kind per number). */
63
+ const SPACE_GROUP = /[   '’]/g;
64
+ // One affix token: currency symbols and/or one letter word ('US$', 'руб.', prefix label 'Total:').
65
+ const PREFIX_TOKEN = /^(?:\p{Sc}*\p{L}+[.:]?\p{Sc}*|\p{Sc}+)$/u;
66
+ const SUFFIX_TOKEN = /^(?:\p{Sc}*\p{L}+\.?\p{Sc}*|\p{Sc}+)$/u;
67
+ const SUFFIX_WORDS = new Set(['руб', 'р']);
68
+ let isoCodes: Set<string> | undefined;
69
+ /** A real ISO 4217 code (not merely well-formed), so magnitude words ('K', 'bn', 'млн') never pass. */
70
+ // Without Intl.supportedValuesOf no suffix word counts as a currency (reject, never throw).
71
+ const isIsoCode = (w: string) =>
72
+ (isoCodes ??= new Set(
73
+ typeof Intl.supportedValuesOf === 'function' ? Intl.supportedValuesOf('currency') : [],
74
+ )).has(w.toUpperCase());
75
+
76
+ /**
77
+ * Splits one affix side into sign marks; null when anything but symbols / ONE word / sign remains.
78
+ * A prefix word is a free label ('Total', 'Итого:'); a suffix word must be a currency
79
+ * (ISO code or 'руб'/'р') — anything else may be a magnitude ('5 тыс.', '$2 million').
80
+ */
81
+ function readAffix(side: string, open: string, signs: string, suffix: boolean) {
82
+ const marks = { open: 0, minus: 0, plus: 0 };
83
+ for (const c of side) {
84
+ if (c === open) marks.open++;
85
+ else if (c === '-' && signs.includes('-')) marks.minus++;
86
+ else if (c === '+' && signs.includes('+')) marks.plus++;
87
+ }
88
+ const rest = side.replace(new RegExp(`[\\${open}${signs.replace('-', '\\-')}]`, 'g'), ' ');
89
+ const tokens = rest.split(/[   ]+/).filter(Boolean);
90
+ if (!tokens.every((tk) => (suffix ? SUFFIX_TOKEN : PREFIX_TOKEN).test(tk))) return null;
91
+ const words = tokens.map((tk) => tk.replace(/[^\p{L}]/gu, '')).filter(Boolean);
92
+ if (words.length > 1) return null;
93
+ if (suffix && words.length && !SUFFIX_WORDS.has(words[0].toLowerCase()) && !isIsoCode(words[0]))
94
+ return null;
95
+ return marks;
96
+ }
97
+
98
+ /**
99
+ * Lenient parse of a PASTED segment: exactly one number, with optional currency symbols / one word
100
+ * per side, a sign ('-', '−', '+', trailing '-') or accounting parentheses. Grouping must be
101
+ * unambiguous (first group 1–3 digits, then exactly 3, one group char kind); the cross-locale rules
102
+ * pick the decimal. Anything doubtful → `'invalid'`; no digits at all → `null`.
103
+ */
104
+ export function parseAmount(
105
+ text: string,
106
+ opts: { locale: string; precision: number; allowNegative: boolean },
107
+ ): AmountDraft | null | 'invalid' {
108
+ const t = text.replace(/−/g, '-').trim().replace(/\.$/, ''); // trailing sentence period
109
+ const first = t.search(/\d/);
110
+ if (first < 0) return null;
111
+ let last = t.length - 1;
112
+ while (!/\d/.test(t[last])) last--;
113
+ // '.5' — but a separator glued to a word belongs to it ('Rs.100', 'руб.10').
114
+ const leadingSep = /[.,]/.test(t[first - 1] ?? '') && !/\p{L}/u.test(t[first - 2] ?? '');
115
+ const from = leadingSep ? first - 1 : first;
116
+ // Letters glued to the number ('5K', '3bn', 'USD5') are magnitudes or noise.
117
+ if (/\p{L}/u.test(t[from - 1] ?? '') || /\p{L}/u.test(t[last + 1] ?? '')) return 'invalid';
118
+ const core = t.slice(from, last + 1);
119
+
120
+ const pre = readAffix(t.slice(0, from), '(', '-+', false);
121
+ const post = readAffix(t.slice(last + 1), ')', '-', true);
122
+ if (!pre || !post) return 'invalid';
123
+ const parens = pre.open + post.open;
124
+ const signs = pre.minus + pre.plus + post.minus;
125
+ if (pre.open > 1 || post.open > 1 || parens === 1 || signs > 1 || (parens && signs)) {
126
+ return 'invalid';
127
+ }
128
+ const negative = opts.allowNegative && (parens === 2 || pre.minus + post.minus === 1);
129
+
130
+ if (!/^[\d.,]+$/.test(core.replace(SPACE_GROUP, ''))) return 'invalid'; // tab, newline, '-', letters
131
+ const { group: lg, decimal: ld } = localeSeparators(opts.locale);
132
+ const count = (c: string) => core.split(c).length - 1;
133
+ const dots = count('.');
134
+ const commas = count(',');
135
+ let dec: string | null = null;
136
+ let grp: string | null = null;
137
+ if (dots && commas) {
138
+ dec = core.lastIndexOf('.') > core.lastIndexOf(',') ? '.' : ',';
139
+ grp = dec === '.' ? ',' : '.';
140
+ if (count(dec) > 1) return 'invalid';
141
+ } else if (dots > 1 || commas > 1) {
142
+ grp = dots ? '.' : ',';
143
+ } else if (dots || commas) {
144
+ const c = dots ? '.' : ',';
145
+ const fracLen = core.length - core.indexOf(c) - 1;
146
+ if (c === ld) dec = c;
147
+ // Numpad-dot rule: in a comma-decimal locale, a lone '.' + 1..precision digits is a decimal.
148
+ else if (
149
+ c === '.' &&
150
+ ld === ',' &&
151
+ opts.precision <= 2 &&
152
+ fracLen >= 1 &&
153
+ fracLen <= opts.precision
154
+ )
155
+ dec = c;
156
+ // Neither the locale's group nor its decimal + exactly 3 digits (ru '1.234'): don't guess.
157
+ else if (c !== lg && fracLen === 3) return 'invalid';
158
+ else if (c === lg || c === '.') grp = c;
159
+ else dec = c;
160
+ // '1,234' / '1.234' as a decimal below precision 3 could equally be grouping: don't guess.
161
+ if (dec && fracLen === 3 && opts.precision < 3) return 'invalid';
162
+ }
163
+ const spaces = new Set(core.match(SPACE_GROUP) ?? []);
164
+ if (spaces.size) {
165
+ if (grp || spaces.size > 1) return 'invalid'; // one group char kind
166
+ grp = [...spaces][0];
167
+ }
168
+
169
+ const at = dec ? core.indexOf(dec) : -1;
170
+ const intPart = at < 0 ? core : core.slice(0, at);
171
+ const fracPart = at < 0 ? null : core.slice(at + 1);
172
+ if (fracPart !== null && !/^\d*$/.test(fracPart)) return 'invalid';
173
+ if (grp) {
174
+ const groups = intPart.split(grp);
175
+ if (!/^\d{1,3}$/.test(groups[0]) || !groups.slice(1).every((g) => /^\d{3}$/.test(g))) {
176
+ return 'invalid';
177
+ }
178
+ } else if (!/^\d*$/.test(intPart)) return 'invalid';
179
+
180
+ const int = grp ? intPart.split(grp).join('') : intPart;
181
+ // Full fraction: the caller truncates (whole-value paste) or rejects the overflow (partial paste).
182
+ const frac = fracPart;
183
+ return { negative, int, frac };
184
+ }
185
+
186
+ /**
187
+ * Strict parse of the field's OWN text: only the locale group char is stripped and only the
188
+ * locale decimal is a decimal. No cross-locale or numpad guessing.
189
+ */
190
+ export function parseLocalAmount(
191
+ text: string,
192
+ opts: { locale: string; precision: number; allowNegative: boolean },
193
+ ): AmountDraft | null {
194
+ const { group, decimal } = localeSeparators(opts.locale);
195
+ const s = [...text.split(group).join('')]
196
+ .filter((c) => (c >= '0' && c <= '9') || c === decimal || c === '-')
197
+ .join('');
198
+ if (!s) return null;
199
+ const negative = opts.allowNegative && s.startsWith('-');
200
+ return toDraft(s.replace(/-/g, ''), decimal, opts.precision, negative);
201
+ }
202
+
203
+ function toDraft(s: string, decimal: string, precision: number, negative: boolean) {
204
+ const at = s.indexOf(decimal);
205
+ const digits = (v: string) => v.replace(/\D/g, '');
206
+ const int = digits(at < 0 ? s : s.slice(0, at));
207
+ const frac = at < 0 ? null : digits(s.slice(at + 1)).slice(0, precision);
208
+ if (!int && frac === null && !negative) return null;
209
+ return { negative, int, frac };
210
+ }
211
+
212
+ /** Prefix '-' only for a negative with a non-zero digit (never '-0' / '-0.00'). */
213
+ const signed = (negative: boolean, body: string) =>
214
+ (negative && /[1-9]/.test(body) ? '-' : '') + body;
215
+
216
+ export function draftToCanonical(d: AmountDraft): string | null {
217
+ // A lone decimal separator ('.', ',') is a partial draft, not zero (#663).
218
+ if (!d.int && !d.frac) return null;
219
+ const int = d.int.replace(/^0+(?=\d)/, '') || '0';
220
+ const body = `${int}${d.frac ? `.${d.frac}` : ''}`;
221
+ return signed(d.negative, body);
222
+ }
223
+
224
+ export function canonicalToDraft(s: string | null): AmountDraft | null {
225
+ if (s === null || s === '') return null;
226
+ const negative = s.startsWith('-');
227
+ const [int, frac] = (negative ? s.slice(1) : s).split('.');
228
+ // Strip leading zeros so an external '0012.5' displays like typed input would (#663).
229
+ return { negative, int: int.replace(/^0+(?=\d)/, ''), frac: frac ?? null };
230
+ }
231
+
232
+ export function formatDraft(
233
+ d: AmountDraft,
234
+ opts: { locale: string; precision: number; pad: boolean },
235
+ ): string {
236
+ const { group, decimal } = localeSeparators(opts.locale);
237
+ const sign = d.negative ? '-' : '';
238
+ // A lone separator shows as itself, not '0.': a synthesized 0 would parse back as an amount (#663).
239
+ if (!d.int && !d.frac) return d.frac === null || opts.precision === 0 ? sign : sign + decimal;
240
+ const int = (d.int || '0').replace(/\B(?=(\d{3})+$)/g, group);
241
+ if (opts.precision === 0) return sign + int;
242
+ let frac = d.frac === null ? null : d.frac.slice(0, opts.precision);
243
+ if (opts.pad) frac = (frac ?? '').padEnd(opts.precision, '0');
244
+ return sign + int + (frac === null ? '' : decimal + frac);
245
+ }
246
+
247
+ /** String half-up (away from zero) rounding; never pads. */
248
+ export function roundAmount(canonical: string, precision: number): string {
249
+ const negative = canonical.startsWith('-');
250
+ const [int, frac = ''] = (negative ? canonical.slice(1) : canonical).split('.');
251
+ if (frac.length <= precision) return signed(negative, canonical.slice(negative ? 1 : 0));
252
+ let n = BigInt(int + frac.slice(0, precision));
253
+ if (frac[precision] >= '5') n += 1n;
254
+ const s = n.toString().padStart(precision + 1, '0');
255
+ const cut = s.length - precision;
256
+ return signed(negative, precision ? `${s.slice(0, cut)}.${s.slice(cut)}` : s);
257
+ }
@@ -0,0 +1,200 @@
1
+ // dragAnnouncements.ts — localized screen-reader copy for dnd-kit drags.
2
+ //
3
+ // dnd-kit's built-in announcements are hard-coded English AND interpolate raw
4
+ // ids ("Draggable item deal-7 was moved over droppable area col-3"), which is
5
+ // both a Hard rule 9 violation and useless to a listener. Every `<DndContext>`
6
+ // in the library passes `accessibility={useDragAccessibility(...)}` instead.
7
+ //
8
+ // Internal — not exported from `src/index.ts`.
9
+ import { useMemo, useRef, type RefObject } from 'react';
10
+ import type { Active, Announcements, ScreenReaderInstructions } from '@dnd-kit/core';
11
+ import { useTranslation } from '../../i18n';
12
+
13
+ /** Collapse whitespace and cap the length so an announcement stays listenable. */
14
+ export function tidy(text: string): string {
15
+ const flat = text.replace(/\s+/g, ' ').trim();
16
+ return flat.length > 80 ? `${flat.slice(0, 79)}…` : flat;
17
+ }
18
+
19
+ /**
20
+ * What a draggable publishes on its dnd-kit `data` so the announcements can
21
+ * name it. Read with `dragLabelOf`.
22
+ */
23
+ export interface DragLabelData {
24
+ /** Consumer's explicit `aria-label`. Wins outright when set. */
25
+ dragLabel?: string;
26
+ /** The rendered node to read text from when there is no explicit label. */
27
+ dragNode?: RefObject<HTMLElement | null>;
28
+ }
29
+
30
+ /**
31
+ * The name to announce for a draggable: the consumer's `aria-label` if there is
32
+ * one, else the node's rendered text.
33
+ *
34
+ * Reading the DOM rather than walking the React children is deliberate. A card
35
+ * with a `<DropdownMenu>` / `<Tooltip>` / `<ConfirmationPopover>` in it has the
36
+ * closed panel's contents in its children tree but NOT in the document, so a
37
+ * children walk announces "Draft Q3 OKRs View Archive" while the DOM announces
38
+ * "Draft Q3 OKRs". Collapsed and portalled subtrees drop out by construction.
39
+ */
40
+ export function dragLabelOf(data: Record<string, unknown> | undefined): string | undefined {
41
+ const { dragLabel, dragNode } = (data ?? {}) as DragLabelData;
42
+ if (typeof dragLabel === 'string' && dragLabel.trim()) return tidy(dragLabel);
43
+ const node = dragNode?.current;
44
+ if (!node) return undefined;
45
+ const text = tidy(domText(node));
46
+ return text || undefined;
47
+ }
48
+
49
+ /**
50
+ * `textContent` for announcements: separates element boundaries with a space
51
+ * (raw `textContent` glues siblings — "Acme Corp$50,000") and skips
52
+ * `aria-hidden` subtrees, which are decoration a screen reader is already told
53
+ * to ignore.
54
+ */
55
+ function domText(el: Element): string {
56
+ let out = '';
57
+ for (const child of el.childNodes) {
58
+ if (child.nodeType === 3) out += child.nodeValue ?? '';
59
+ else if (child.nodeType === 1 && (child as Element).getAttribute('aria-hidden') !== 'true')
60
+ out += ` ${domText(child as Element)}`;
61
+ }
62
+ return out;
63
+ }
64
+
65
+ /**
66
+ * The accessible name a consumer gave a container (a Kanban column, a
67
+ * SortableGroup list) — `aria-label`, or the text of whatever `aria-labelledby`
68
+ * points at, since naming a column by its visible `<Title>` is the natural
69
+ * choice. Returns undefined when neither is set; the caller falls back to a
70
+ * positional stand-in.
71
+ */
72
+ export function containerName(props: {
73
+ 'aria-label'?: string;
74
+ 'aria-labelledby'?: string;
75
+ }): string | undefined {
76
+ const label = props['aria-label'];
77
+ if (typeof label === 'string' && label.trim()) return tidy(label);
78
+ const ids = props['aria-labelledby'];
79
+ if (!ids || typeof document === 'undefined') return undefined;
80
+ const text = ids
81
+ .split(/\s+/)
82
+ .map((id) => document.getElementById(id)?.textContent ?? '')
83
+ .join(' ');
84
+ return text.trim() ? tidy(text) : undefined;
85
+ }
86
+
87
+ /** The `active` / `over` shape dnd-kit hands to an announcement callback. */
88
+ export type DragEntry = Pick<Active, 'id' | 'data'>;
89
+
90
+ /** What a component knows about the slot an id occupies (or would land in). */
91
+ export interface DragTarget {
92
+ /** Human name. Empty / omitted → the message says "the item" instead. */
93
+ label?: string;
94
+ /** 1-based slot within `container`. */
95
+ index: number;
96
+ /** Number of slots in `container`, counting the incoming item. */
97
+ total: number;
98
+ /** Human name of the list the slot belongs to. Omit in single-list components. */
99
+ container?: string;
100
+ }
101
+
102
+ /**
103
+ * Default `describe`: the name from `dragLabelOf`, plus the index / items
104
+ * `useSortable` already publishes under `data.sortable`. Returns `null` for
105
+ * anything that is not a sortable item (including a missing entry).
106
+ */
107
+ export function sortableTarget(entry: DragEntry | null): DragTarget | null {
108
+ const data = entry?.data.current;
109
+ const sortable = data?.sortable as { index: number; items: unknown[] } | undefined;
110
+ if (!sortable || sortable.index < 0) return null;
111
+ return {
112
+ label: dragLabelOf(data),
113
+ index: sortable.index + 1,
114
+ total: sortable.items.length,
115
+ };
116
+ }
117
+
118
+ /**
119
+ * Describes the slot an `active` / `over` entry names. `activeId` is passed so
120
+ * a container droppable can answer "where would THIS card land in me" — the
121
+ * multi-list components need it to position a drop onto an empty column.
122
+ *
123
+ * `entry` is null when dnd-kit resolved no `over` at all. Most components
124
+ * return null straight back; a component whose drop has its OWN fallback for
125
+ * that case (DataTable's last-resolved band slot, #383) must answer with that
126
+ * slot here too, or it announces "nothing moved" about a real reorder.
127
+ */
128
+ export type DescribeDragTarget = (
129
+ entry: DragEntry | null,
130
+ activeId: Active['id'],
131
+ ) => DragTarget | null;
132
+
133
+ /**
134
+ * Build the `accessibility` prop for a `<DndContext>`: localized announcements
135
+ * for the whole drag lifecycle plus localized keyboard instructions.
136
+ *
137
+ * @param describe Resolves an entry (or `null` when there is no `over`) to a
138
+ * human slot. Return `null` when nothing would land anywhere
139
+ * — that announces "not over a drop target" / "nothing
140
+ * moved".
141
+ * @param isRejectedDrop Optional. Consulted on drag end BEFORE `over`: return
142
+ * `true` when the component refuses to commit the release, so
143
+ * it announces a cancel rather than a drop that never
144
+ * happened (Kanban's outside-the-board release, #390).
145
+ */
146
+ export function useDragAccessibility(
147
+ describe: DescribeDragTarget,
148
+ isRejectedDrop?: () => boolean,
149
+ ): { announcements: Announcements; screenReaderInstructions: ScreenReaderInstructions } {
150
+ const t = useTranslation();
151
+
152
+ // Latched during render so the returned object can stay stable across the
153
+ // re-renders a live drag causes (dnd-kit re-subscribes its monitor listener
154
+ // whenever `announcements` changes identity). Both writes are idempotent —
155
+ // a StrictMode double render stores the same functions.
156
+ const describeRef = useRef(describe);
157
+ describeRef.current = describe;
158
+ const rejectedRef = useRef(isRejectedDrop);
159
+ rejectedRef.current = isRejectedDrop;
160
+
161
+ return useMemo(() => {
162
+ const nameOf = (entry: DragEntry, activeId: Active['id']) =>
163
+ describeRef.current(entry, activeId)?.label || t('drag.unnamed');
164
+
165
+ const at = (
166
+ key: 'movedOver' | 'dropped',
167
+ item: string,
168
+ target: DragTarget,
169
+ ): string | undefined => {
170
+ const { index, total, container } = target;
171
+ return container == null
172
+ ? t(`drag.${key}`, { item, index, total })
173
+ : t(key === 'movedOver' ? 'drag.movedOverIn' : 'drag.droppedIn', {
174
+ item,
175
+ index,
176
+ total,
177
+ container,
178
+ });
179
+ };
180
+
181
+ return {
182
+ announcements: {
183
+ onDragStart: ({ active }) => t('drag.pickedUp', { item: nameOf(active, active.id) }),
184
+ onDragOver: ({ active, over }) => {
185
+ const item = nameOf(active, active.id);
186
+ const target = describeRef.current(over, active.id);
187
+ return target ? at('movedOver', item, target) : t('drag.movedOutside', { item });
188
+ },
189
+ onDragEnd: ({ active, over }) => {
190
+ const item = nameOf(active, active.id);
191
+ if (rejectedRef.current?.()) return t('drag.cancelled', { item });
192
+ const target = describeRef.current(over, active.id);
193
+ return target ? at('dropped', item, target) : t('drag.droppedNowhere', { item });
194
+ },
195
+ onDragCancel: ({ active }) => t('drag.cancelled', { item: nameOf(active, active.id) }),
196
+ } satisfies Announcements,
197
+ screenReaderInstructions: { draggable: t('drag.instructions') },
198
+ };
199
+ }, [t]);
200
+ }