@eocrm/design-system 0.0.0-stage → 0.6.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (898) hide show
  1. package/AI-PRIMER.md +341 -0
  2. package/LICENSE +202 -0
  3. package/README.md +266 -2
  4. package/docs/components/Accordion.md +114 -0
  5. package/docs/components/AgentAvatar.md +58 -0
  6. package/docs/components/Alert.md +81 -0
  7. package/docs/components/AppLayout.md +70 -0
  8. package/docs/components/Avatar.md +49 -0
  9. package/docs/components/AvatarGroup.md +47 -0
  10. package/docs/components/Badge.md +60 -0
  11. package/docs/components/Banner.md +89 -0
  12. package/docs/components/BrandIcon.md +32 -0
  13. package/docs/components/Breadcrumb.md +72 -0
  14. package/docs/components/Button.md +107 -0
  15. package/docs/components/ButtonGroup.md +78 -0
  16. package/docs/components/Calendar.md +158 -0
  17. package/docs/components/Card.md +165 -0
  18. package/docs/components/CatalogPicker.md +83 -0
  19. package/docs/components/Chart.md +114 -0
  20. package/docs/components/ChatBubble.md +55 -0
  21. package/docs/components/ChatLauncher.md +97 -0
  22. package/docs/components/Checkbox.md +55 -0
  23. package/docs/components/CircularProgress.md +53 -0
  24. package/docs/components/Cluster.md +96 -0
  25. package/docs/components/Code.md +35 -0
  26. package/docs/components/CodeBlock.md +67 -0
  27. package/docs/components/ColorPicker.md +115 -0
  28. package/docs/components/ConfirmationPopover.md +70 -0
  29. package/docs/components/Constrain.md +39 -0
  30. package/docs/components/CurrencySelect.md +57 -0
  31. package/docs/components/CursorPagination.md +43 -0
  32. package/docs/components/DashboardCanvas.md +79 -0
  33. package/docs/components/DashboardWidget.md +131 -0
  34. package/docs/components/DataTable.md +88 -0
  35. package/docs/components/DatePicker.md +68 -0
  36. package/docs/components/DateRangePicker.md +71 -0
  37. package/docs/components/DateStrip.md +56 -0
  38. package/docs/components/DefinitionList.md +82 -0
  39. package/docs/components/Divider.md +57 -0
  40. package/docs/components/Dot.md +26 -0
  41. package/docs/components/Drawer.md +94 -0
  42. package/docs/components/DropdownMenu.md +299 -0
  43. package/docs/components/EmojiPicker.md +84 -0
  44. package/docs/components/EmptyState.md +55 -0
  45. package/docs/components/EntityChip.md +102 -0
  46. package/docs/components/ErrorState.md +72 -0
  47. package/docs/components/Field.md +91 -0
  48. package/docs/components/FileUpload.md +109 -0
  49. package/docs/components/FilterChip.md +88 -0
  50. package/docs/components/FlowCanvas.md +108 -0
  51. package/docs/components/FormRow.md +31 -0
  52. package/docs/components/FormSection.md +37 -0
  53. package/docs/components/Grid.md +103 -0
  54. package/docs/components/Highlight.md +75 -0
  55. package/docs/components/HighlightedText.md +50 -0
  56. package/docs/components/IconPicker.md +134 -0
  57. package/docs/components/IconTile.md +30 -0
  58. package/docs/components/Image.md +84 -0
  59. package/docs/components/ImageCrop.md +163 -0
  60. package/docs/components/Indent.md +31 -0
  61. package/docs/components/InlineDatePicker.md +58 -0
  62. package/docs/components/InlineDateRangePicker.md +57 -0
  63. package/docs/components/Input.md +54 -0
  64. package/docs/components/Kanban.md +122 -0
  65. package/docs/components/Kbd.md +41 -0
  66. package/docs/components/Lightbox.md +105 -0
  67. package/docs/components/Link.md +65 -0
  68. package/docs/components/LinkCard.md +41 -0
  69. package/docs/components/LiquidEditor.md +84 -0
  70. package/docs/components/List.md +68 -0
  71. package/docs/components/LiveRegion.md +29 -0
  72. package/docs/components/LocaleProvider.md +25 -0
  73. package/docs/components/Logo.md +41 -0
  74. package/docs/components/Masonry.md +48 -0
  75. package/docs/components/MediaTile.md +95 -0
  76. package/docs/components/Modal.md +107 -0
  77. package/docs/components/MoneyInput.md +62 -0
  78. package/docs/components/OptionsPicker.md +123 -0
  79. package/docs/components/OtpInput.md +65 -0
  80. package/docs/components/Page.md +35 -0
  81. package/docs/components/PageHeader.md +133 -0
  82. package/docs/components/Pagination.md +44 -0
  83. package/docs/components/Palette.md +32 -0
  84. package/docs/components/PasswordInput.md +45 -0
  85. package/docs/components/PasswordStrengthMeter.md +27 -0
  86. package/docs/components/PersonDisplay.md +153 -0
  87. package/docs/components/PhoneInput.md +54 -0
  88. package/docs/components/PillMenu.md +91 -0
  89. package/docs/components/Popover.md +127 -0
  90. package/docs/components/Progress.md +56 -0
  91. package/docs/components/QrCode.md +34 -0
  92. package/docs/components/Radio.md +37 -0
  93. package/docs/components/RadioGroup.md +56 -0
  94. package/docs/components/Rail.md +191 -0
  95. package/docs/components/RelativeDateInput.md +114 -0
  96. package/docs/components/RichText.md +44 -0
  97. package/docs/components/RichTextEditor.md +112 -0
  98. package/docs/components/Screen.md +37 -0
  99. package/docs/components/ScrollArea.md +39 -0
  100. package/docs/components/Select.md +131 -0
  101. package/docs/components/SettingRow.md +98 -0
  102. package/docs/components/Skeleton.md +68 -0
  103. package/docs/components/Slider.md +92 -0
  104. package/docs/components/SlotGrid.md +55 -0
  105. package/docs/components/SocialButton.md +31 -0
  106. package/docs/components/Sortable.md +127 -0
  107. package/docs/components/SortableGroup.md +52 -0
  108. package/docs/components/Sparkline.md +51 -0
  109. package/docs/components/Split.md +76 -0
  110. package/docs/components/Stack.md +59 -0
  111. package/docs/components/StagePath.md +66 -0
  112. package/docs/components/StatGroup.md +61 -0
  113. package/docs/components/StatTile.md +58 -0
  114. package/docs/components/Sticky.md +69 -0
  115. package/docs/components/Switch.md +89 -0
  116. package/docs/components/Table.md +184 -0
  117. package/docs/components/TableOfContents.md +76 -0
  118. package/docs/components/Tabs.md +94 -0
  119. package/docs/components/Text.md +63 -0
  120. package/docs/components/Textarea.md +59 -0
  121. package/docs/components/Thread.md +52 -0
  122. package/docs/components/TimeField.md +70 -0
  123. package/docs/components/Timeline.md +57 -0
  124. package/docs/components/Title.md +54 -0
  125. package/docs/components/ToastViewport.md +61 -0
  126. package/docs/components/Tooltip.md +63 -0
  127. package/docs/components/TopBar.md +214 -0
  128. package/docs/components/Tour.md +85 -0
  129. package/docs/components/TreeView.md +113 -0
  130. package/docs/components/VisuallyHidden.md +43 -0
  131. package/docs/components/WidgetPreview.md +54 -0
  132. package/docs/components/useBelowBreakpoint.md +11 -0
  133. package/docs/components/useMonth.md +18 -0
  134. package/docs/setup.md +51 -0
  135. package/docs/theming.md +95 -0
  136. package/docs/tokens.md +123 -0
  137. package/docs/transient-state.md +56 -0
  138. package/package.json +86 -4
  139. package/src/_meta/manifest.ts +293 -0
  140. package/src/app/AppProvider.tsx +78 -0
  141. package/src/app/index.ts +3 -0
  142. package/src/app/themeTokens.ts +95 -0
  143. package/src/calendar/dateMath.ts +114 -0
  144. package/src/calendar/formatters.ts +75 -0
  145. package/src/calendar/index.ts +39 -0
  146. package/src/calendar/types.ts +36 -0
  147. package/src/calendar/useAgenda.ts +70 -0
  148. package/src/calendar/useDay.ts +51 -0
  149. package/src/calendar/useMonth.ts +82 -0
  150. package/src/calendar/useWeek.ts +62 -0
  151. package/src/calendar/weekInfo.ts +83 -0
  152. package/src/components/Accordion/Accordion.module.scss +304 -0
  153. package/src/components/Accordion/Accordion.tokens.scss +64 -0
  154. package/src/components/Accordion/Accordion.tsx +272 -0
  155. package/src/components/Accordion/AccordionContent.tsx +36 -0
  156. package/src/components/Accordion/AccordionItem.tsx +66 -0
  157. package/src/components/Accordion/AccordionTrigger.tsx +121 -0
  158. package/src/components/Accordion/context.ts +47 -0
  159. package/src/components/Accordion/index.ts +14 -0
  160. package/src/components/Alert/Alert.module.scss +92 -0
  161. package/src/components/Alert/Alert.tokens.scss +60 -0
  162. package/src/components/Alert/Alert.tsx +136 -0
  163. package/src/components/Alert/index.ts +2 -0
  164. package/src/components/AppLayout/AppLayout.module.scss +130 -0
  165. package/src/components/AppLayout/AppLayout.tokens.scss +27 -0
  166. package/src/components/AppLayout/AppLayout.tsx +211 -0
  167. package/src/components/AppLayout/index.ts +2 -0
  168. package/src/components/Avatar/AgentAvatar.module.scss +117 -0
  169. package/src/components/Avatar/AgentAvatar.tsx +122 -0
  170. package/src/components/Avatar/Avatar.module.scss +181 -0
  171. package/src/components/Avatar/Avatar.tokens.scss +107 -0
  172. package/src/components/Avatar/Avatar.tsx +210 -0
  173. package/src/components/Avatar/AvatarGroup.module.scss +128 -0
  174. package/src/components/Avatar/AvatarGroup.tsx +119 -0
  175. package/src/components/Avatar/AvatarGroupContext.tsx +20 -0
  176. package/src/components/Avatar/index.ts +6 -0
  177. package/src/components/Badge/Badge.module.scss +124 -0
  178. package/src/components/Badge/Badge.tokens.scss +74 -0
  179. package/src/components/Badge/Badge.tsx +164 -0
  180. package/src/components/Badge/index.ts +2 -0
  181. package/src/components/Banner/Banner.module.scss +73 -0
  182. package/src/components/Banner/Banner.tokens.scss +51 -0
  183. package/src/components/Banner/Banner.tsx +138 -0
  184. package/src/components/Banner/index.ts +2 -0
  185. package/src/components/BrandIcon/BrandIcon.module.scss +5 -0
  186. package/src/components/BrandIcon/BrandIcon.tsx +99 -0
  187. package/src/components/BrandIcon/index.ts +2 -0
  188. package/src/components/Breadcrumb/Breadcrumb.module.scss +32 -0
  189. package/src/components/Breadcrumb/Breadcrumb.tokens.scss +9 -0
  190. package/src/components/Breadcrumb/Breadcrumb.tsx +146 -0
  191. package/src/components/Breadcrumb/index.ts +2 -0
  192. package/src/components/Button/Button.module.scss +167 -0
  193. package/src/components/Button/Button.tokens.scss +90 -0
  194. package/src/components/Button/Button.tsx +205 -0
  195. package/src/components/Button/index.ts +2 -0
  196. package/src/components/ButtonGroup/ButtonGroup.module.scss +134 -0
  197. package/src/components/ButtonGroup/ButtonGroup.tokens.scss +42 -0
  198. package/src/components/ButtonGroup/ButtonGroup.tsx +278 -0
  199. package/src/components/ButtonGroup/ButtonGroupItem.tsx +74 -0
  200. package/src/components/ButtonGroup/context.ts +45 -0
  201. package/src/components/ButtonGroup/index.ts +2 -0
  202. package/src/components/Calendar/AgendaView.module.scss +231 -0
  203. package/src/components/Calendar/AgendaView.tsx +214 -0
  204. package/src/components/Calendar/AllDayBand.module.scss +18 -0
  205. package/src/components/Calendar/AllDayBand.tsx +75 -0
  206. package/src/components/Calendar/Calendar.module.scss +23 -0
  207. package/src/components/Calendar/Calendar.tokens.scss +262 -0
  208. package/src/components/Calendar/Calendar.tsx +370 -0
  209. package/src/components/Calendar/DayCell.module.scss +30 -0
  210. package/src/components/Calendar/DayCell.tsx +50 -0
  211. package/src/components/Calendar/DayView.module.scss +10 -0
  212. package/src/components/Calendar/DayView.tsx +163 -0
  213. package/src/components/Calendar/EventChip.module.scss +171 -0
  214. package/src/components/Calendar/EventChip.tsx +115 -0
  215. package/src/components/Calendar/HourGrid.module.scss +123 -0
  216. package/src/components/Calendar/HourGrid.tsx +381 -0
  217. package/src/components/Calendar/MonthView.module.scss +99 -0
  218. package/src/components/Calendar/MonthView.tsx +296 -0
  219. package/src/components/Calendar/TimedEvent.module.scss +205 -0
  220. package/src/components/Calendar/TimedEvent.tsx +247 -0
  221. package/src/components/Calendar/ViewSwitcher.module.scss +3 -0
  222. package/src/components/Calendar/ViewSwitcher.tsx +47 -0
  223. package/src/components/Calendar/WeekView.module.scss +10 -0
  224. package/src/components/Calendar/WeekView.tsx +137 -0
  225. package/src/components/Calendar/eventColor.ts +60 -0
  226. package/src/components/Calendar/index.ts +18 -0
  227. package/src/components/Calendar/types.ts +451 -0
  228. package/src/components/Calendar/useEventDrag.ts +783 -0
  229. package/src/components/Calendar/utils.ts +622 -0
  230. package/src/components/Card/Card.module.scss +264 -0
  231. package/src/components/Card/Card.tokens.scss +55 -0
  232. package/src/components/Card/Card.tsx +170 -0
  233. package/src/components/Card/CardBody.tsx +45 -0
  234. package/src/components/Card/CardHeader.tsx +113 -0
  235. package/src/components/Card/CardList.tsx +24 -0
  236. package/src/components/Card/CardListRow.tsx +24 -0
  237. package/src/components/Card/index.ts +7 -0
  238. package/src/components/CatalogPicker/CatalogPicker.module.scss +193 -0
  239. package/src/components/CatalogPicker/CatalogPicker.tokens.scss +26 -0
  240. package/src/components/CatalogPicker/CatalogPicker.tsx +339 -0
  241. package/src/components/CatalogPicker/index.ts +2 -0
  242. package/src/components/Chart/Chart.module.scss +287 -0
  243. package/src/components/Chart/Chart.tokens.scss +63 -0
  244. package/src/components/Chart/Chart.tsx +607 -0
  245. package/src/components/Chart/ChartLegend.tsx +99 -0
  246. package/src/components/Chart/ChartTable.tsx +62 -0
  247. package/src/components/Chart/ChartTooltip.tsx +91 -0
  248. package/src/components/Chart/chartModel.ts +689 -0
  249. package/src/components/Chart/index.ts +2 -0
  250. package/src/components/ChatBubble/ChatBubble.module.scss +93 -0
  251. package/src/components/ChatBubble/ChatBubble.tokens.scss +17 -0
  252. package/src/components/ChatBubble/ChatBubble.tsx +61 -0
  253. package/src/components/ChatBubble/ChatBubbleList.tsx +27 -0
  254. package/src/components/ChatBubble/index.ts +3 -0
  255. package/src/components/ChatLauncher/ChatLauncher.module.scss +68 -0
  256. package/src/components/ChatLauncher/ChatLauncher.tokens.scss +27 -0
  257. package/src/components/ChatLauncher/ChatLauncher.tsx +202 -0
  258. package/src/components/ChatLauncher/index.ts +2 -0
  259. package/src/components/ChatLauncher/isAtBottom.ts +12 -0
  260. package/src/components/Checkbox/Checkbox.module.scss +147 -0
  261. package/src/components/Checkbox/Checkbox.tokens.scss +44 -0
  262. package/src/components/Checkbox/Checkbox.tsx +188 -0
  263. package/src/components/Checkbox/index.ts +2 -0
  264. package/src/components/CircularProgress/CircularProgress.module.scss +133 -0
  265. package/src/components/CircularProgress/CircularProgress.tokens.scss +40 -0
  266. package/src/components/CircularProgress/CircularProgress.tsx +139 -0
  267. package/src/components/CircularProgress/index.ts +7 -0
  268. package/src/components/Cluster/Cluster.module.scss +145 -0
  269. package/src/components/Cluster/Cluster.tokens.scss +11 -0
  270. package/src/components/Cluster/Cluster.tsx +215 -0
  271. package/src/components/Cluster/index.ts +2 -0
  272. package/src/components/Code/Code.module.scss +28 -0
  273. package/src/components/Code/Code.tokens.scss +15 -0
  274. package/src/components/Code/Code.tsx +44 -0
  275. package/src/components/Code/index.ts +2 -0
  276. package/src/components/CodeBlock/CodeBlock.module.scss +146 -0
  277. package/src/components/CodeBlock/CodeBlock.tokens.scss +27 -0
  278. package/src/components/CodeBlock/CodeBlock.tsx +274 -0
  279. package/src/components/CodeBlock/highlight.ts +179 -0
  280. package/src/components/CodeBlock/index.ts +8 -0
  281. package/src/components/CodeBlock/sampleSync.ts +42 -0
  282. package/src/components/ColorPicker/ColorPicker.module.scss +286 -0
  283. package/src/components/ColorPicker/ColorPicker.tokens.scss +60 -0
  284. package/src/components/ColorPicker/ColorPicker.tsx +367 -0
  285. package/src/components/ColorPicker/ColorPickerPanel.tsx +265 -0
  286. package/src/components/ColorPicker/SVSquare.tsx +189 -0
  287. package/src/components/ColorPicker/colorMath.ts +141 -0
  288. package/src/components/ColorPicker/index.ts +6 -0
  289. package/src/components/ConfirmationPopover/ConfirmationPopover.module.scss +39 -0
  290. package/src/components/ConfirmationPopover/ConfirmationPopover.tokens.scss +13 -0
  291. package/src/components/ConfirmationPopover/ConfirmationPopover.tsx +395 -0
  292. package/src/components/ConfirmationPopover/index.ts +2 -0
  293. package/src/components/Constrain/Constrain.module.scss +99 -0
  294. package/src/components/Constrain/Constrain.tsx +79 -0
  295. package/src/components/Constrain/index.ts +2 -0
  296. package/src/components/CurrencySelect/CurrencySelect.module.scss +7 -0
  297. package/src/components/CurrencySelect/CurrencySelect.tsx +167 -0
  298. package/src/components/CurrencySelect/index.ts +3 -0
  299. package/src/components/CursorPagination/CursorPagination.module.scss +69 -0
  300. package/src/components/CursorPagination/CursorPagination.tokens.scss +32 -0
  301. package/src/components/CursorPagination/CursorPagination.tsx +121 -0
  302. package/src/components/CursorPagination/index.ts +2 -0
  303. package/src/components/DashboardCanvas/DashboardCanvas.module.scss +360 -0
  304. package/src/components/DashboardCanvas/DashboardCanvas.tokens.scss +48 -0
  305. package/src/components/DashboardCanvas/DashboardCanvas.tsx +1270 -0
  306. package/src/components/DashboardCanvas/DashboardCanvasItem.tsx +140 -0
  307. package/src/components/DashboardCanvas/DashboardCanvasSection.tsx +174 -0
  308. package/src/components/DashboardCanvas/engine.ts +363 -0
  309. package/src/components/DashboardCanvas/index.ts +9 -0
  310. package/src/components/DashboardWidget/DashboardWidget.module.scss +100 -0
  311. package/src/components/DashboardWidget/DashboardWidget.tokens.scss +16 -0
  312. package/src/components/DashboardWidget/DashboardWidget.tsx +188 -0
  313. package/src/components/DashboardWidget/index.ts +7 -0
  314. package/src/components/DataTable/BodyRow.tsx +197 -0
  315. package/src/components/DataTable/ColumnVisibilityTrigger.module.scss +7 -0
  316. package/src/components/DataTable/ColumnVisibilityTrigger.tsx +105 -0
  317. package/src/components/DataTable/DataTable.module.scss +511 -0
  318. package/src/components/DataTable/DataTable.tokens.scss +80 -0
  319. package/src/components/DataTable/DataTable.tsx +734 -0
  320. package/src/components/DataTable/HeaderCell.module.scss +215 -0
  321. package/src/components/DataTable/HeaderCell.tsx +440 -0
  322. package/src/components/DataTable/columnShift.ts +117 -0
  323. package/src/components/DataTable/index.ts +23 -0
  324. package/src/components/DataTable/pinStyle.ts +47 -0
  325. package/src/components/DataTable/reorderColumns.ts +66 -0
  326. package/src/components/DataTable/types.ts +289 -0
  327. package/src/components/DataTable/useColumnDragShift.ts +216 -0
  328. package/src/components/DataTable/useDataTable.ts +372 -0
  329. package/src/components/DataTable/useResizeHandle.ts +97 -0
  330. package/src/components/DatePicker/DatePicker.module.scss +180 -0
  331. package/src/components/DatePicker/DatePicker.tokens.scss +152 -0
  332. package/src/components/DatePicker/DatePicker.tsx +664 -0
  333. package/src/components/DatePicker/DatePickerGrid.module.scss +172 -0
  334. package/src/components/DatePicker/DatePickerGrid.tsx +341 -0
  335. package/src/components/DatePicker/InlineDatePicker.module.scss +32 -0
  336. package/src/components/DatePicker/InlineDatePicker.tsx +201 -0
  337. package/src/components/DatePicker/index.ts +4 -0
  338. package/src/components/DatePicker/utils.ts +364 -0
  339. package/src/components/DateRangePicker/DateRangePicker.module.scss +237 -0
  340. package/src/components/DateRangePicker/DateRangePicker.tokens.scss +78 -0
  341. package/src/components/DateRangePicker/DateRangePicker.tsx +720 -0
  342. package/src/components/DateRangePicker/InlineDateRangePicker.module.scss +94 -0
  343. package/src/components/DateRangePicker/InlineDateRangePicker.tsx +376 -0
  344. package/src/components/DateRangePicker/index.ts +5 -0
  345. package/src/components/DateRangePicker/utils.ts +151 -0
  346. package/src/components/DateStrip/DateStrip.module.scss +78 -0
  347. package/src/components/DateStrip/DateStrip.tokens.scss +23 -0
  348. package/src/components/DateStrip/DateStrip.tsx +205 -0
  349. package/src/components/DateStrip/index.ts +2 -0
  350. package/src/components/DefinitionList/DefinitionList.module.scss +102 -0
  351. package/src/components/DefinitionList/DefinitionList.tokens.scss +29 -0
  352. package/src/components/DefinitionList/DefinitionList.tsx +198 -0
  353. package/src/components/DefinitionList/index.ts +9 -0
  354. package/src/components/Divider/Divider.module.scss +144 -0
  355. package/src/components/Divider/Divider.tokens.scss +21 -0
  356. package/src/components/Divider/Divider.tsx +103 -0
  357. package/src/components/Divider/index.ts +2 -0
  358. package/src/components/Dot/Dot.module.scss +40 -0
  359. package/src/components/Dot/Dot.tokens.scss +4 -0
  360. package/src/components/Dot/Dot.tsx +45 -0
  361. package/src/components/Dot/index.ts +2 -0
  362. package/src/components/Drawer/Body.tsx +23 -0
  363. package/src/components/Drawer/Close.tsx +35 -0
  364. package/src/components/Drawer/Content.tsx +93 -0
  365. package/src/components/Drawer/Drawer.module.scss +232 -0
  366. package/src/components/Drawer/Drawer.tokens.scss +38 -0
  367. package/src/components/Drawer/Drawer.tsx +23 -0
  368. package/src/components/Drawer/DrawerRoot.tsx +190 -0
  369. package/src/components/Drawer/Footer.tsx +24 -0
  370. package/src/components/Drawer/Header.tsx +64 -0
  371. package/src/components/Drawer/Overlay.tsx +82 -0
  372. package/src/components/Drawer/context.ts +44 -0
  373. package/src/components/Drawer/index.ts +12 -0
  374. package/src/components/Drawer/useDragToClose.ts +149 -0
  375. package/src/components/DropdownMenu/CheckboxItem.tsx +144 -0
  376. package/src/components/DropdownMenu/Content.tsx +419 -0
  377. package/src/components/DropdownMenu/DropdownMenu.module.scss +280 -0
  378. package/src/components/DropdownMenu/DropdownMenu.tokens.scss +88 -0
  379. package/src/components/DropdownMenu/DropdownMenu.tsx +43 -0
  380. package/src/components/DropdownMenu/Group.tsx +76 -0
  381. package/src/components/DropdownMenu/Item.tsx +148 -0
  382. package/src/components/DropdownMenu/ItemIndicator.tsx +30 -0
  383. package/src/components/DropdownMenu/Radio.tsx +178 -0
  384. package/src/components/DropdownMenu/Root.tsx +100 -0
  385. package/src/components/DropdownMenu/Sub.tsx +332 -0
  386. package/src/components/DropdownMenu/Trigger.tsx +76 -0
  387. package/src/components/DropdownMenu/context.ts +65 -0
  388. package/src/components/DropdownMenu/index.ts +20 -0
  389. package/src/components/EmojiPicker/EmojiPicker.module.scss +84 -0
  390. package/src/components/EmojiPicker/EmojiPicker.tokens.scss +24 -0
  391. package/src/components/EmojiPicker/EmojiPicker.tsx +341 -0
  392. package/src/components/EmojiPicker/emojiData.ts +245 -0
  393. package/src/components/EmojiPicker/index.ts +3 -0
  394. package/src/components/EmptyState/EmptyState.module.scss +102 -0
  395. package/src/components/EmptyState/EmptyState.tokens.scss +28 -0
  396. package/src/components/EmptyState/EmptyState.tsx +112 -0
  397. package/src/components/EmptyState/index.ts +7 -0
  398. package/src/components/EntityChip/EntityChip.module.scss +275 -0
  399. package/src/components/EntityChip/EntityChip.tokens.scss +66 -0
  400. package/src/components/EntityChip/EntityChip.tsx +649 -0
  401. package/src/components/EntityChip/index.ts +10 -0
  402. package/src/components/ErrorState/ErrorState.module.scss +105 -0
  403. package/src/components/ErrorState/ErrorState.tokens.scss +32 -0
  404. package/src/components/ErrorState/ErrorState.tsx +125 -0
  405. package/src/components/ErrorState/index.ts +8 -0
  406. package/src/components/Field/Field.module.scss +46 -0
  407. package/src/components/Field/Field.tsx +185 -0
  408. package/src/components/Field/index.ts +2 -0
  409. package/src/components/FileUpload/FileUpload.module.scss +187 -0
  410. package/src/components/FileUpload/FileUpload.tokens.scss +81 -0
  411. package/src/components/FileUpload/FileUpload.tsx +569 -0
  412. package/src/components/FileUpload/formatBytes.ts +34 -0
  413. package/src/components/FileUpload/iconForFile.ts +40 -0
  414. package/src/components/FileUpload/index.ts +2 -0
  415. package/src/components/FilterChip/FilterChip.module.scss +61 -0
  416. package/src/components/FilterChip/FilterChip.tokens.scss +25 -0
  417. package/src/components/FilterChip/FilterChip.tsx +208 -0
  418. package/src/components/FilterChip/index.ts +5 -0
  419. package/src/components/FlowCanvas/FlowCanvas.module.scss +329 -0
  420. package/src/components/FlowCanvas/FlowCanvas.tokens.scss +45 -0
  421. package/src/components/FlowCanvas/FlowCanvas.tsx +1867 -0
  422. package/src/components/FlowCanvas/FlowControls.tsx +46 -0
  423. package/src/components/FlowCanvas/FlowEdge.tsx +58 -0
  424. package/src/components/FlowCanvas/FlowNode.tsx +76 -0
  425. package/src/components/FlowCanvas/edgePath.ts +85 -0
  426. package/src/components/FlowCanvas/index.ts +4 -0
  427. package/src/components/FlowCanvas/layout.ts +148 -0
  428. package/src/components/FlowCanvas/spatialNav.ts +76 -0
  429. package/src/components/FlowCanvas/types.ts +59 -0
  430. package/src/components/FlowCanvas/useViewport.ts +122 -0
  431. package/src/components/FormRow/FormRow.module.scss +2 -0
  432. package/src/components/FormRow/FormRow.tsx +37 -0
  433. package/src/components/FormRow/index.ts +2 -0
  434. package/src/components/FormSection/FormSection.module.scss +24 -0
  435. package/src/components/FormSection/FormSection.tsx +46 -0
  436. package/src/components/FormSection/index.ts +2 -0
  437. package/src/components/Grid/Grid.module.scss +162 -0
  438. package/src/components/Grid/Grid.tokens.scss +13 -0
  439. package/src/components/Grid/Grid.tsx +226 -0
  440. package/src/components/Grid/GridItem.tsx +77 -0
  441. package/src/components/Grid/index.ts +11 -0
  442. package/src/components/Highlight/Highlight.module.scss +43 -0
  443. package/src/components/Highlight/Highlight.tokens.scss +35 -0
  444. package/src/components/Highlight/Highlight.tsx +164 -0
  445. package/src/components/Highlight/HighlightOverlay.tsx +100 -0
  446. package/src/components/Highlight/index.ts +2 -0
  447. package/src/components/HighlightedText/HighlightedText.module.scss +11 -0
  448. package/src/components/HighlightedText/HighlightedText.tokens.scss +9 -0
  449. package/src/components/HighlightedText/HighlightedText.tsx +50 -0
  450. package/src/components/HighlightedText/highlightRanges.ts +44 -0
  451. package/src/components/HighlightedText/index.ts +2 -0
  452. package/src/components/IconPicker/IconPicker.module.scss +175 -0
  453. package/src/components/IconPicker/IconPicker.tokens.scss +40 -0
  454. package/src/components/IconPicker/IconPicker.tsx +629 -0
  455. package/src/components/IconPicker/index.ts +9 -0
  456. package/src/components/IconTile/IconTile.module.scss +57 -0
  457. package/src/components/IconTile/IconTile.tokens.scss +16 -0
  458. package/src/components/IconTile/IconTile.tsx +91 -0
  459. package/src/components/IconTile/index.ts +2 -0
  460. package/src/components/Image/Image.module.scss +266 -0
  461. package/src/components/Image/Image.tokens.scss +55 -0
  462. package/src/components/Image/Image.tsx +342 -0
  463. package/src/components/Image/index.ts +2 -0
  464. package/src/components/ImageCrop/ImageCrop.module.scss +274 -0
  465. package/src/components/ImageCrop/ImageCrop.tokens.scss +33 -0
  466. package/src/components/ImageCrop/ImageCrop.tsx +542 -0
  467. package/src/components/ImageCrop/cropGeometry.ts +120 -0
  468. package/src/components/ImageCrop/extractCropBlob.ts +140 -0
  469. package/src/components/ImageCrop/index.ts +11 -0
  470. package/src/components/ImageCrop/useCropPreview.ts +161 -0
  471. package/src/components/Indent/Indent.module.scss +33 -0
  472. package/src/components/Indent/Indent.tokens.scss +10 -0
  473. package/src/components/Indent/Indent.tsx +46 -0
  474. package/src/components/Indent/index.ts +2 -0
  475. package/src/components/Input/Input.module.scss +99 -0
  476. package/src/components/Input/Input.tokens.scss +54 -0
  477. package/src/components/Input/Input.tsx +105 -0
  478. package/src/components/Input/Suggestions.tsx +260 -0
  479. package/src/components/Input/index.ts +2 -0
  480. package/src/components/Kanban/Kanban.module.scss +39 -0
  481. package/src/components/Kanban/Kanban.tokens.scss +15 -0
  482. package/src/components/Kanban/Kanban.tsx +951 -0
  483. package/src/components/Kanban/index.ts +7 -0
  484. package/src/components/Kbd/Kbd.module.scss +47 -0
  485. package/src/components/Kbd/Kbd.tokens.scss +26 -0
  486. package/src/components/Kbd/Kbd.tsx +73 -0
  487. package/src/components/Kbd/index.ts +2 -0
  488. package/src/components/Lightbox/Lightbox.module.scss +283 -0
  489. package/src/components/Lightbox/Lightbox.tokens.scss +36 -0
  490. package/src/components/Lightbox/Lightbox.tsx +506 -0
  491. package/src/components/Lightbox/index.ts +2 -0
  492. package/src/components/Link/Link.module.scss +78 -0
  493. package/src/components/Link/Link.tokens.scss +28 -0
  494. package/src/components/Link/Link.tsx +114 -0
  495. package/src/components/Link/index.ts +2 -0
  496. package/src/components/LinkCard/LinkCard.module.scss +92 -0
  497. package/src/components/LinkCard/LinkCard.tokens.scss +9 -0
  498. package/src/components/LinkCard/LinkCard.tsx +72 -0
  499. package/src/components/LinkCard/index.ts +2 -0
  500. package/src/components/LiquidEditor/AutocompleteMenu.tsx +133 -0
  501. package/src/components/LiquidEditor/HighlightLayer.tsx +53 -0
  502. package/src/components/LiquidEditor/InsertVariableMenu.tsx +81 -0
  503. package/src/components/LiquidEditor/LiquidEditor.module.scss +339 -0
  504. package/src/components/LiquidEditor/LiquidEditor.tokens.scss +81 -0
  505. package/src/components/LiquidEditor/LiquidEditor.tsx +412 -0
  506. package/src/components/LiquidEditor/PreviewPane.tsx +29 -0
  507. package/src/components/LiquidEditor/caretCoordinates.ts +97 -0
  508. package/src/components/LiquidEditor/index.ts +7 -0
  509. package/src/components/LiquidEditor/liquidFilters.ts +23 -0
  510. package/src/components/LiquidEditor/liquidTokenizer.ts +235 -0
  511. package/src/components/LiquidEditor/types.ts +101 -0
  512. package/src/components/LiquidEditor/useLiquidAutocomplete.ts +178 -0
  513. package/src/components/List/List.module.scss +105 -0
  514. package/src/components/List/List.tokens.scss +42 -0
  515. package/src/components/List/List.tsx +124 -0
  516. package/src/components/List/index.ts +9 -0
  517. package/src/components/LiveRegion/LiveRegion.module.scss +3 -0
  518. package/src/components/LiveRegion/LiveRegion.tsx +116 -0
  519. package/src/components/LiveRegion/index.ts +2 -0
  520. package/src/components/Logo/Logo.module.scss +139 -0
  521. package/src/components/Logo/Logo.tokens.scss +14 -0
  522. package/src/components/Logo/Logo.tsx +126 -0
  523. package/src/components/Logo/index.ts +2 -0
  524. package/src/components/Masonry/Masonry.module.scss +42 -0
  525. package/src/components/Masonry/Masonry.tokens.scss +8 -0
  526. package/src/components/Masonry/Masonry.tsx +136 -0
  527. package/src/components/Masonry/index.ts +2 -0
  528. package/src/components/Masonry/masonryUtils.ts +42 -0
  529. package/src/components/MediaTile/MediaTile.module.scss +183 -0
  530. package/src/components/MediaTile/MediaTile.tokens.scss +60 -0
  531. package/src/components/MediaTile/MediaTile.tsx +208 -0
  532. package/src/components/MediaTile/index.ts +8 -0
  533. package/src/components/Modal/Body.tsx +27 -0
  534. package/src/components/Modal/Close.tsx +45 -0
  535. package/src/components/Modal/Content.tsx +98 -0
  536. package/src/components/Modal/Footer.tsx +28 -0
  537. package/src/components/Modal/Header.tsx +51 -0
  538. package/src/components/Modal/Modal.module.scss +262 -0
  539. package/src/components/Modal/Modal.tokens.scss +50 -0
  540. package/src/components/Modal/Modal.tsx +23 -0
  541. package/src/components/Modal/ModalRoot.tsx +299 -0
  542. package/src/components/Modal/Overlay.tsx +101 -0
  543. package/src/components/Modal/context.ts +60 -0
  544. package/src/components/Modal/index.ts +11 -0
  545. package/src/components/MoneyInput/MoneyInput.module.scss +57 -0
  546. package/src/components/MoneyInput/MoneyInput.tsx +433 -0
  547. package/src/components/MoneyInput/index.ts +2 -0
  548. package/src/components/OptionsPicker/OptionsPicker.module.scss +216 -0
  549. package/src/components/OptionsPicker/OptionsPicker.tokens.scss +68 -0
  550. package/src/components/OptionsPicker/OptionsPicker.tsx +936 -0
  551. package/src/components/OptionsPicker/index.ts +9 -0
  552. package/src/components/OtpInput/OtpInput.module.scss +69 -0
  553. package/src/components/OtpInput/OtpInput.tokens.scss +45 -0
  554. package/src/components/OtpInput/OtpInput.tsx +368 -0
  555. package/src/components/OtpInput/index.ts +2 -0
  556. package/src/components/Page/Page.module.scss +30 -0
  557. package/src/components/Page/Page.tokens.scss +11 -0
  558. package/src/components/Page/Page.tsx +53 -0
  559. package/src/components/Page/index.ts +2 -0
  560. package/src/components/PageHeader/PageHeader.module.scss +197 -0
  561. package/src/components/PageHeader/PageHeader.tokens.scss +41 -0
  562. package/src/components/PageHeader/PageHeader.tsx +310 -0
  563. package/src/components/PageHeader/index.ts +20 -0
  564. package/src/components/Pagination/Pagination.module.scss +117 -0
  565. package/src/components/Pagination/Pagination.tokens.scss +54 -0
  566. package/src/components/Pagination/Pagination.tsx +165 -0
  567. package/src/components/Pagination/index.ts +4 -0
  568. package/src/components/Pagination/paginationRange.ts +72 -0
  569. package/src/components/PasswordInput/PasswordInput.module.scss +120 -0
  570. package/src/components/PasswordInput/PasswordInput.tokens.scss +44 -0
  571. package/src/components/PasswordInput/PasswordInput.tsx +210 -0
  572. package/src/components/PasswordInput/index.ts +2 -0
  573. package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.module.scss +80 -0
  574. package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tokens.scss +40 -0
  575. package/src/components/PasswordStrengthMeter/PasswordStrengthMeter.tsx +96 -0
  576. package/src/components/PasswordStrengthMeter/index.ts +2 -0
  577. package/src/components/PersonDisplay/PersonDisplay.module.scss +180 -0
  578. package/src/components/PersonDisplay/PersonDisplay.tokens.scss +35 -0
  579. package/src/components/PersonDisplay/PersonDisplay.tsx +420 -0
  580. package/src/components/PersonDisplay/index.ts +10 -0
  581. package/src/components/PhoneInput/PhoneInput.module.scss +23 -0
  582. package/src/components/PhoneInput/PhoneInput.tsx +271 -0
  583. package/src/components/PhoneInput/index.ts +4 -0
  584. package/src/components/PhoneInput/phone.ts +128 -0
  585. package/src/components/PillMenu/PillMenu.module.scss +117 -0
  586. package/src/components/PillMenu/PillMenu.tokens.scss +22 -0
  587. package/src/components/PillMenu/PillMenu.tsx +324 -0
  588. package/src/components/PillMenu/index.ts +2 -0
  589. package/src/components/Popover/Anchor.tsx +37 -0
  590. package/src/components/Popover/Close.tsx +45 -0
  591. package/src/components/Popover/Content.tsx +213 -0
  592. package/src/components/Popover/Heading.tsx +33 -0
  593. package/src/components/Popover/Popover.module.scss +177 -0
  594. package/src/components/Popover/Popover.tokens.scss +22 -0
  595. package/src/components/Popover/Popover.tsx +23 -0
  596. package/src/components/Popover/PopoverRoot.tsx +75 -0
  597. package/src/components/Popover/Trigger.tsx +86 -0
  598. package/src/components/Popover/context.ts +22 -0
  599. package/src/components/Popover/index.ts +7 -0
  600. package/src/components/Progress/Progress.module.scss +110 -0
  601. package/src/components/Progress/Progress.tokens.scss +44 -0
  602. package/src/components/Progress/Progress.tsx +129 -0
  603. package/src/components/Progress/index.ts +2 -0
  604. package/src/components/QrCode/QrCode.module.scss +97 -0
  605. package/src/components/QrCode/QrCode.tokens.scss +17 -0
  606. package/src/components/QrCode/QrCode.tsx +233 -0
  607. package/src/components/QrCode/index.ts +2 -0
  608. package/src/components/QrCode/qr.ts +161 -0
  609. package/src/components/Radio/Radio.module.scss +175 -0
  610. package/src/components/Radio/Radio.tokens.scss +59 -0
  611. package/src/components/Radio/Radio.tsx +127 -0
  612. package/src/components/Radio/RadioGroup.module.scss +42 -0
  613. package/src/components/Radio/RadioGroup.tsx +120 -0
  614. package/src/components/Radio/RadioGroupContext.tsx +30 -0
  615. package/src/components/Radio/index.ts +4 -0
  616. package/src/components/Rail/Rail.module.scss +510 -0
  617. package/src/components/Rail/Rail.tokens.scss +92 -0
  618. package/src/components/Rail/Rail.tsx +287 -0
  619. package/src/components/Rail/RailCollapseToggle.tsx +57 -0
  620. package/src/components/Rail/RailFooter.tsx +17 -0
  621. package/src/components/Rail/RailGroup.tsx +728 -0
  622. package/src/components/Rail/RailGroupContext.ts +9 -0
  623. package/src/components/Rail/RailHeader.tsx +23 -0
  624. package/src/components/Rail/RailItem.tsx +119 -0
  625. package/src/components/Rail/RailSection.tsx +39 -0
  626. package/src/components/Rail/RailSpacer.tsx +19 -0
  627. package/src/components/Rail/index.ts +9 -0
  628. package/src/components/RelativeDateInput/RelativeDateInput.module.scss +15 -0
  629. package/src/components/RelativeDateInput/RelativeDateInput.tokens.scss +6 -0
  630. package/src/components/RelativeDateInput/RelativeDateInput.tsx +474 -0
  631. package/src/components/RelativeDateInput/index.ts +10 -0
  632. package/src/components/RelativeDateInput/relativeDate.ts +127 -0
  633. package/src/components/RichText/RichText.module.scss +5 -0
  634. package/src/components/RichText/RichText.tsx +70 -0
  635. package/src/components/RichText/RichTextAttachment.module.scss +82 -0
  636. package/src/components/RichText/RichTextAttachment.tsx +122 -0
  637. package/src/components/RichText/_prose.scss +79 -0
  638. package/src/components/RichText/attachmentIcon.tsx +24 -0
  639. package/src/components/RichText/engine/attachment.ts +154 -0
  640. package/src/components/RichText/engine/autolink.ts +64 -0
  641. package/src/components/RichText/engine/blockUnit.ts +174 -0
  642. package/src/components/RichText/engine/colorMarks.ts +85 -0
  643. package/src/components/RichText/engine/escape.ts +11 -0
  644. package/src/components/RichText/engine/fromHtml.ts +353 -0
  645. package/src/components/RichText/engine/fromMarkdown.ts +20 -0
  646. package/src/components/RichText/engine/inlines.ts +82 -0
  647. package/src/components/RichText/engine/listDepths.ts +32 -0
  648. package/src/components/RichText/engine/marks.ts +80 -0
  649. package/src/components/RichText/engine/mdToHtml.ts +178 -0
  650. package/src/components/RichText/engine/model.ts +157 -0
  651. package/src/components/RichText/engine/position.ts +118 -0
  652. package/src/components/RichText/engine/renderDoc.tsx +395 -0
  653. package/src/components/RichText/engine/renderLink.ts +15 -0
  654. package/src/components/RichText/engine/renderMention.ts +16 -0
  655. package/src/components/RichText/engine/safeHref.ts +22 -0
  656. package/src/components/RichText/engine/toHtml.ts +154 -0
  657. package/src/components/RichText/engine/toMarkdown.ts +97 -0
  658. package/src/components/RichText/engine/transforms.ts +434 -0
  659. package/src/components/RichText/imageMaxHeightStyle.ts +10 -0
  660. package/src/components/RichText/index.ts +31 -0
  661. package/src/components/RichTextEditor/RichTextAttachmentConfig.tsx +264 -0
  662. package/src/components/RichTextEditor/RichTextBlockControls.tsx +365 -0
  663. package/src/components/RichTextEditor/RichTextBlockMenu.tsx +162 -0
  664. package/src/components/RichTextEditor/RichTextColorMenu.tsx +115 -0
  665. package/src/components/RichTextEditor/RichTextEditor.module.scss +298 -0
  666. package/src/components/RichTextEditor/RichTextEditor.tsx +1910 -0
  667. package/src/components/RichTextEditor/RichTextImageResizer.tsx +131 -0
  668. package/src/components/RichTextEditor/RichTextLinkEditor.tsx +151 -0
  669. package/src/components/RichTextEditor/RichTextMentionMenu.tsx +99 -0
  670. package/src/components/RichTextEditor/RichTextToolbar.tsx +379 -0
  671. package/src/components/RichTextEditor/autolinkInput.ts +65 -0
  672. package/src/components/RichTextEditor/blockDrop.ts +9 -0
  673. package/src/components/RichTextEditor/blockReflow.ts +62 -0
  674. package/src/components/RichTextEditor/commands.ts +300 -0
  675. package/src/components/RichTextEditor/history.ts +93 -0
  676. package/src/components/RichTextEditor/icons.tsx +152 -0
  677. package/src/components/RichTextEditor/imageSize.ts +70 -0
  678. package/src/components/RichTextEditor/index.ts +5 -0
  679. package/src/components/RichTextEditor/input.ts +209 -0
  680. package/src/components/RichTextEditor/inputRules.ts +71 -0
  681. package/src/components/RichTextEditor/links.ts +103 -0
  682. package/src/components/RichTextEditor/mentionContext.ts +37 -0
  683. package/src/components/RichTextEditor/mentions.ts +28 -0
  684. package/src/components/RichTextEditor/preventSelectionLoss.ts +15 -0
  685. package/src/components/RichTextEditor/selection.ts +415 -0
  686. package/src/components/RichTextEditor/shortcuts.ts +44 -0
  687. package/src/components/RichTextEditor/useAnchoredFloating.ts +50 -0
  688. package/src/components/RichTextEditor/useAttachmentConfig.ts +134 -0
  689. package/src/components/RichTextEditor/useDismissOnOutsidePointerDown.ts +26 -0
  690. package/src/components/RichTextEditor/useLinkEditor.ts +107 -0
  691. package/src/components/RichTextEditor/useMention.ts +226 -0
  692. package/src/components/RichTextEditor/useOverlayRect.ts +73 -0
  693. package/src/components/RichTextEditor/useUpload.ts +246 -0
  694. package/src/components/Screen/Screen.module.scss +46 -0
  695. package/src/components/Screen/Screen.tokens.scss +20 -0
  696. package/src/components/Screen/Screen.tsx +97 -0
  697. package/src/components/Screen/index.ts +2 -0
  698. package/src/components/ScrollArea/ScrollArea.module.scss +39 -0
  699. package/src/components/ScrollArea/ScrollArea.tokens.scss +15 -0
  700. package/src/components/ScrollArea/ScrollArea.tsx +154 -0
  701. package/src/components/ScrollArea/index.ts +2 -0
  702. package/src/components/Select/Chip.tsx +45 -0
  703. package/src/components/Select/Empty.tsx +39 -0
  704. package/src/components/Select/Error.tsx +51 -0
  705. package/src/components/Select/HiddenInputs.tsx +44 -0
  706. package/src/components/Select/Listbox.tsx +557 -0
  707. package/src/components/Select/Loading.tsx +30 -0
  708. package/src/components/Select/Select.module.scss +512 -0
  709. package/src/components/Select/Select.tokens.scss +140 -0
  710. package/src/components/Select/Select.tsx +685 -0
  711. package/src/components/Select/Trigger.tsx +952 -0
  712. package/src/components/Select/context.ts +101 -0
  713. package/src/components/Select/emptyStateText.ts +19 -0
  714. package/src/components/Select/index.ts +9 -0
  715. package/src/components/Select/useSelectState.ts +157 -0
  716. package/src/components/Select/utils-types.ts +7 -0
  717. package/src/components/Select/utils.ts +122 -0
  718. package/src/components/SettingRow/SettingRow.module.scss +166 -0
  719. package/src/components/SettingRow/SettingRow.tokens.scss +37 -0
  720. package/src/components/SettingRow/SettingRow.tsx +242 -0
  721. package/src/components/SettingRow/index.ts +7 -0
  722. package/src/components/Skeleton/Skeleton.module.scss +55 -0
  723. package/src/components/Skeleton/Skeleton.tokens.scss +17 -0
  724. package/src/components/Skeleton/Skeleton.tsx +131 -0
  725. package/src/components/Skeleton/index.ts +4 -0
  726. package/src/components/Skeleton/useSkeletonVisibility.ts +95 -0
  727. package/src/components/Slider/Slider.module.scss +293 -0
  728. package/src/components/Slider/Slider.tokens.scss +98 -0
  729. package/src/components/Slider/Slider.tsx +624 -0
  730. package/src/components/Slider/index.ts +9 -0
  731. package/src/components/SlotGrid/SlotGrid.module.scss +61 -0
  732. package/src/components/SlotGrid/SlotGrid.tokens.scss +21 -0
  733. package/src/components/SlotGrid/SlotGrid.tsx +111 -0
  734. package/src/components/SlotGrid/index.ts +2 -0
  735. package/src/components/SocialButton/SocialButton.module.scss +4 -0
  736. package/src/components/SocialButton/SocialButton.tsx +40 -0
  737. package/src/components/SocialButton/index.ts +2 -0
  738. package/src/components/Sortable/Sortable.module.scss +177 -0
  739. package/src/components/Sortable/Sortable.tokens.scss +27 -0
  740. package/src/components/Sortable/Sortable.tsx +572 -0
  741. package/src/components/Sortable/containerAwareCollision.ts +125 -0
  742. package/src/components/Sortable/index.ts +13 -0
  743. package/src/components/SortableGroup/SortableGroup.module.scss +23 -0
  744. package/src/components/SortableGroup/SortableGroup.tsx +315 -0
  745. package/src/components/SortableGroup/index.ts +4 -0
  746. package/src/components/SortableGroup/moveSortableItem.ts +39 -0
  747. package/src/components/Sparkline/Sparkline.module.scss +28 -0
  748. package/src/components/Sparkline/Sparkline.tokens.scss +7 -0
  749. package/src/components/Sparkline/Sparkline.tsx +133 -0
  750. package/src/components/Sparkline/index.ts +2 -0
  751. package/src/components/Sparkline/sparklineModel.ts +119 -0
  752. package/src/components/Split/Split.module.scss +158 -0
  753. package/src/components/Split/Split.tokens.scss +10 -0
  754. package/src/components/Split/Split.tsx +231 -0
  755. package/src/components/Split/index.ts +2 -0
  756. package/src/components/Stack/Stack.module.scss +67 -0
  757. package/src/components/Stack/Stack.tokens.scss +11 -0
  758. package/src/components/Stack/Stack.tsx +100 -0
  759. package/src/components/Stack/index.ts +2 -0
  760. package/src/components/StagePath/StagePath.module.scss +255 -0
  761. package/src/components/StagePath/StagePath.tokens.scss +43 -0
  762. package/src/components/StagePath/StagePath.tsx +176 -0
  763. package/src/components/StagePath/index.ts +2 -0
  764. package/src/components/StatGroup/StatGroup.module.scss +6 -0
  765. package/src/components/StatGroup/StatGroup.tsx +70 -0
  766. package/src/components/StatGroup/StatGroupContext.ts +10 -0
  767. package/src/components/StatGroup/StatTile.module.scss +99 -0
  768. package/src/components/StatGroup/StatTile.tokens.scss +35 -0
  769. package/src/components/StatGroup/StatTile.tsx +143 -0
  770. package/src/components/StatGroup/index.ts +4 -0
  771. package/src/components/Sticky/Sticky.module.scss +98 -0
  772. package/src/components/Sticky/Sticky.tokens.scss +17 -0
  773. package/src/components/Sticky/Sticky.tsx +103 -0
  774. package/src/components/Sticky/index.ts +2 -0
  775. package/src/components/Switch/Switch.module.scss +182 -0
  776. package/src/components/Switch/Switch.tokens.scss +59 -0
  777. package/src/components/Switch/Switch.tsx +214 -0
  778. package/src/components/Switch/index.ts +2 -0
  779. package/src/components/Table/Table.module.scss +308 -0
  780. package/src/components/Table/Table.tokens.scss +79 -0
  781. package/src/components/Table/Table.tsx +381 -0
  782. package/src/components/Table/index.ts +15 -0
  783. package/src/components/TableOfContents/TableOfContents.module.scss +83 -0
  784. package/src/components/TableOfContents/TableOfContents.tokens.scss +26 -0
  785. package/src/components/TableOfContents/TableOfContents.tsx +192 -0
  786. package/src/components/TableOfContents/activeSection.ts +18 -0
  787. package/src/components/TableOfContents/index.ts +2 -0
  788. package/src/components/Tabs/Tabs.module.scss +359 -0
  789. package/src/components/Tabs/Tabs.tokens.scss +50 -0
  790. package/src/components/Tabs/Tabs.tsx +538 -0
  791. package/src/components/Tabs/index.ts +2 -0
  792. package/src/components/Text/Text.module.scss +115 -0
  793. package/src/components/Text/Text.tokens.scss +55 -0
  794. package/src/components/Text/Text.tsx +197 -0
  795. package/src/components/Text/index.ts +2 -0
  796. package/src/components/Textarea/Textarea.module.scss +94 -0
  797. package/src/components/Textarea/Textarea.tokens.scss +48 -0
  798. package/src/components/Textarea/Textarea.tsx +246 -0
  799. package/src/components/Textarea/index.ts +2 -0
  800. package/src/components/Thread/Thread.module.scss +161 -0
  801. package/src/components/Thread/Thread.tokens.scss +32 -0
  802. package/src/components/Thread/Thread.tsx +176 -0
  803. package/src/components/Thread/index.ts +2 -0
  804. package/src/components/TimeField/TimeField.module.scss +232 -0
  805. package/src/components/TimeField/TimeField.tsx +793 -0
  806. package/src/components/TimeField/index.ts +2 -0
  807. package/src/components/Timeline/Timeline.module.scss +58 -0
  808. package/src/components/Timeline/Timeline.tokens.scss +13 -0
  809. package/src/components/Timeline/Timeline.tsx +53 -0
  810. package/src/components/Timeline/index.ts +2 -0
  811. package/src/components/Title/Title.module.scss +84 -0
  812. package/src/components/Title/Title.tokens.scss +37 -0
  813. package/src/components/Title/Title.tsx +150 -0
  814. package/src/components/Title/index.ts +2 -0
  815. package/src/components/Toast/Toast.module.scss +299 -0
  816. package/src/components/Toast/Toast.tokens.scss +65 -0
  817. package/src/components/Toast/Toast.tsx +122 -0
  818. package/src/components/Toast/ToastViewport.tsx +166 -0
  819. package/src/components/Toast/api.ts +175 -0
  820. package/src/components/Toast/index.ts +5 -0
  821. package/src/components/Toast/store.ts +133 -0
  822. package/src/components/Toast/useToastTimer.ts +94 -0
  823. package/src/components/Tooltip/Tooltip.module.scss +99 -0
  824. package/src/components/Tooltip/Tooltip.tokens.scss +23 -0
  825. package/src/components/Tooltip/Tooltip.tsx +341 -0
  826. package/src/components/Tooltip/index.ts +2 -0
  827. package/src/components/TopBar/TopBar.module.scss +235 -0
  828. package/src/components/TopBar/TopBar.tokens.scss +79 -0
  829. package/src/components/TopBar/TopBar.tsx +87 -0
  830. package/src/components/TopBar/TopBarEnd.tsx +20 -0
  831. package/src/components/TopBar/TopBarIconButton.tsx +86 -0
  832. package/src/components/TopBar/TopBarSearch.tsx +319 -0
  833. package/src/components/TopBar/TopBarSearchPanel.tsx +268 -0
  834. package/src/components/TopBar/TopBarStart.tsx +20 -0
  835. package/src/components/TopBar/index.ts +11 -0
  836. package/src/components/Tour/Spotlight.tsx +121 -0
  837. package/src/components/Tour/Tour.module.scss +210 -0
  838. package/src/components/Tour/Tour.tokens.scss +58 -0
  839. package/src/components/Tour/Tour.tsx +617 -0
  840. package/src/components/Tour/index.ts +2 -0
  841. package/src/components/Tour/useTourTarget.ts +115 -0
  842. package/src/components/TreeView/TreeView.module.scss +268 -0
  843. package/src/components/TreeView/TreeView.tokens.scss +36 -0
  844. package/src/components/TreeView/TreeView.tsx +536 -0
  845. package/src/components/TreeView/index.ts +3 -0
  846. package/src/components/TreeView/treeModel.ts +224 -0
  847. package/src/components/VisuallyHidden/VisuallyHidden.module.scss +7 -0
  848. package/src/components/VisuallyHidden/VisuallyHidden.tsx +29 -0
  849. package/src/components/VisuallyHidden/index.ts +2 -0
  850. package/src/components/WidgetPreview/WidgetPreview.module.scss +11 -0
  851. package/src/components/WidgetPreview/WidgetPreview.tokens.scss +26 -0
  852. package/src/components/WidgetPreview/WidgetPreview.tsx +36 -0
  853. package/src/components/WidgetPreview/WidgetShape.module.scss +140 -0
  854. package/src/components/WidgetPreview/WidgetShape.tsx +159 -0
  855. package/src/components/WidgetPreview/index.ts +2 -0
  856. package/src/components/_internal/Trend.tsx +27 -0
  857. package/src/components/_internal/choiceTile.scss +74 -0
  858. package/src/components/_internal/collapse.scss +10 -0
  859. package/src/components/_internal/collapse.ts +58 -0
  860. package/src/components/_internal/currency.ts +257 -0
  861. package/src/components/_internal/dragAnnouncements.ts +200 -0
  862. package/src/components/_internal/fieldWiring.ts +225 -0
  863. package/src/components/_internal/gridSpan.ts +54 -0
  864. package/src/components/_internal/isoDay.ts +35 -0
  865. package/src/components/_internal/letterKey.ts +26 -0
  866. package/src/components/_internal/overlay/focusRestore.ts +21 -0
  867. package/src/components/_internal/overlay/index.ts +12 -0
  868. package/src/components/_internal/overlay/tourHold.ts +23 -0
  869. package/src/components/_internal/overlay/useFocusTrap.ts +120 -0
  870. package/src/components/_internal/overlay/useInOverlay.ts +81 -0
  871. package/src/components/_internal/overlay/useOverlayStack.ts +232 -0
  872. package/src/components/_internal/overlay/useScrollLock.ts +112 -0
  873. package/src/components/_internal/refs.ts +48 -0
  874. package/src/components/_internal/statusColor.ts +26 -0
  875. package/src/components/_internal/timeUtils.ts +23 -0
  876. package/src/components/_internal/useAsyncOptions.ts +145 -0
  877. package/src/components/_internal/useClippedTooltip.ts +50 -0
  878. package/src/components/_internal/useControllableState.ts +50 -0
  879. package/src/components.manifest.json +1141 -0
  880. package/src/hooks/useBelowBreakpoint.ts +58 -0
  881. package/src/i18n/I18nProvider.tsx +52 -0
  882. package/src/i18n/LocaleProvider.tsx +17 -0
  883. package/src/i18n/en.ts +648 -0
  884. package/src/i18n/format.ts +71 -0
  885. package/src/i18n/index.ts +13 -0
  886. package/src/i18n/messages.ts +1275 -0
  887. package/src/i18n/ru.ts +677 -0
  888. package/src/i18n/useLocale.ts +19 -0
  889. package/src/i18n/useTranslation.ts +58 -0
  890. package/src/index.ts +913 -0
  891. package/src/palette/index.ts +2 -0
  892. package/src/palette/palette.ts +108 -0
  893. package/src/styles/dark.scss +4 -0
  894. package/src/styles/global.scss +7 -0
  895. package/src/styles/mixins.scss +143 -0
  896. package/src/styles/reset.scss +78 -0
  897. package/src/styles/tokens.scss +18 -0
  898. package/src/styles/typography.scss +44 -0
@@ -0,0 +1,793 @@
1
+ import {
2
+ forwardRef,
3
+ useCallback,
4
+ useEffect,
5
+ useId,
6
+ useMemo,
7
+ useRef,
8
+ useState,
9
+ type FocusEvent,
10
+ type HTMLAttributes,
11
+ type KeyboardEvent as ReactKeyboardEvent,
12
+ } from 'react';
13
+ import { createPortal } from 'react-dom';
14
+ import { isTourHeld, overlayStack, useFloatingSurface, useInOverlay } from '../_internal/overlay';
15
+ import clsx from 'clsx';
16
+ import { autoUpdate, flip, offset, shift, useFloating } from '@floating-ui/react-dom';
17
+ import { Check, ChevronDown } from 'lucide-react';
18
+ import { useLocale } from '../../i18n/useLocale';
19
+ import { useTranslation } from '../../i18n/useTranslation';
20
+ import {
21
+ formatTime,
22
+ parseTime,
23
+ resolveHourCycle,
24
+ roundTimeToStep,
25
+ type HourCycle,
26
+ type TimeValue,
27
+ } from '../_internal/timeUtils';
28
+ import styles from './TimeField.module.scss';
29
+
30
+ export type { TimeValue, HourCycle };
31
+
32
+ /**
33
+ * Props for the public `<TimeField>` primitive — a standalone time-of-day
34
+ * input with a popover containing hour / minute (and AM/PM in 12h locales)
35
+ * lists. Used internally by the DatePicker family, exposed publicly for
36
+ * consumers who need a time input without a date.
37
+ */
38
+ export interface TimeFieldProps extends Omit<
39
+ HTMLAttributes<HTMLDivElement>,
40
+ 'onChange' | 'defaultValue'
41
+ > {
42
+ /**
43
+ * Selected time. `null` disables the field — the field cannot be
44
+ * activated until the parent supplies a value (used by the picker family
45
+ * to gate time selection on a date being chosen first).
46
+ */
47
+ value: TimeValue | null;
48
+ /**
49
+ * Fired when the user commits a new time, either by typing + focus
50
+ * leaving the field (input, chevron or clock) / Enter, by clicking a row in the popover, or by clicking the Now button.
51
+ * The emitted value is always 24-hour internal regardless of display cycle.
52
+ */
53
+ onChange: (value: TimeValue) => void;
54
+ /**
55
+ * Minutes step. Default `15`. Controls the row count in the minutes
56
+ * column (e.g., 15 → 4 rows: 00/15/30/45) AND rounds typed input on
57
+ * commit. Set `1` to disable rounding.
58
+ */
59
+ step?: number;
60
+ /**
61
+ * Display + parse cycle.
62
+ * - `'24'` — hour list 00–23, text input shows `HH:mm`, no AM/PM column.
63
+ * - `'12'` — hour list `12, 1, 2, …, 11` with an AM/PM column; text
64
+ * input shows `h:mm AM/PM`.
65
+ * - `'auto'` (default) — reads the active locale via
66
+ * `Intl.DateTimeFormat`; en-US → 12h, ru-RU → 24h.
67
+ *
68
+ * Typed input is lenient regardless of cycle — both 24h (`14:30`) and
69
+ * AM/PM (`2:30 PM`) shapes parse in either mode.
70
+ */
71
+ hourCycle?: HourCycle;
72
+ /**
73
+ * Locale override for `hourCycle='auto'` detection + text formatting.
74
+ * Defaults to the active `<LocaleProvider>` / browser locale.
75
+ */
76
+ locale?: string;
77
+ /**
78
+ * Hide the "Now" quick-pick button in the popover footer. Default `false`
79
+ * (button shown).
80
+ */
81
+ hideNowButton?: boolean;
82
+ /**
83
+ * Accessible label. Optional, but the control MUST be named: pass `aria-label`
84
+ * for a standalone TimeField, OR `aria-labelledby` when an external element
85
+ * (e.g. a `<Field>` label) names it. If both are given, `aria-labelledby` wins.
86
+ */
87
+ 'aria-label'?: string;
88
+ /**
89
+ * Id(s) of element(s) that label this control — forwarded onto the inner
90
+ * `<input>` so a `<Field label>` names it. Takes precedence over `aria-label`.
91
+ */
92
+ 'aria-labelledby'?: string;
93
+ /**
94
+ * Id(s) of element(s) that describe this control (e.g. a `<Field>` error or
95
+ * helper message) — forwarded onto the inner `<input>`, not the wrapper, so
96
+ * the description is announced when the input is focused.
97
+ */
98
+ 'aria-describedby'?: string;
99
+ /** Disables the input + popover trigger. */
100
+ disabled?: boolean;
101
+ /**
102
+ * Toggles the error visual and sets `aria-invalid="true"` on the text input.
103
+ * Pair with a visible message and `aria-describedby` pointing at its id,
104
+ * exactly like `Input` / `Textarea` / `Select`.
105
+ *
106
+ * TimeField was the only form control in the library without this — 15 other
107
+ * controls set `aria-invalid` and it set nothing, so a TimeField inside a
108
+ * `<Field error=…>` looked wrong and announced valid (#494).
109
+ */
110
+ invalid?: boolean;
111
+ /**
112
+ * Sets `aria-required` on the text input. Field / SettingRow inject it; it
113
+ * used to fall through onto the wrapper div as a stray `required` attribute (#568).
114
+ */
115
+ required?: boolean;
116
+ /** Stable id for the input (so an external `<label htmlFor>` can target it). */
117
+ id?: string;
118
+ /** Additional className on the wrapper. */
119
+ className?: string;
120
+ }
121
+
122
+ type FocusColumn = 'hours' | 'minutes' | 'period';
123
+
124
+ /**
125
+ * Standalone time-of-day input: a text input plus a popover with scrollable hour / minute (and AM/PM) lists.
126
+ * @see docs/components/TimeField.md
127
+ */
128
+ export const TimeField = forwardRef<HTMLDivElement, TimeFieldProps>(function TimeField(
129
+ {
130
+ value,
131
+ onChange,
132
+ step = 15,
133
+ hourCycle = 'auto',
134
+ locale: localeProp,
135
+ hideNowButton = false,
136
+ 'aria-label': ariaLabel,
137
+ 'aria-labelledby': ariaLabelledBy,
138
+ 'aria-describedby': ariaDescribedBy,
139
+ disabled = false,
140
+ invalid = false,
141
+ required = false,
142
+ id: idProp,
143
+ className,
144
+ onBlur,
145
+ ...rest
146
+ },
147
+ ref,
148
+ ) {
149
+ const t = useTranslation();
150
+ const localeFromContext = useLocale();
151
+ const locale = localeProp ?? localeFromContext;
152
+ const resolvedCycle = resolveHourCycle(hourCycle, locale);
153
+
154
+ const generatedId = useId();
155
+ const inputId = idProp ?? generatedId;
156
+
157
+ // Field is effectively disabled when there is no time to mutate.
158
+ const isDisabled = disabled || value == null;
159
+
160
+ // ---- Derived current values + display strings ----
161
+ const currentHour = value?.hours ?? 0;
162
+ const currentMinute = value?.minutes ?? 0;
163
+ const currentPeriod: 0 | 1 = currentHour >= 12 ? 1 : 0; // 0 = AM, 1 = PM
164
+
165
+ const placeholder =
166
+ resolvedCycle === '24' ? t('datePicker.timePlaceholder24') : t('datePicker.timePlaceholder12');
167
+ // "12:00 AM" = 8 chars; "HH:mm" = 5. Bump for 12h.
168
+ const inputMaxLength = resolvedCycle === '24' ? 5 : 8;
169
+
170
+ // Local draft so partial keystrokes don't immediately mutate state.
171
+ const formattedValue = value ? formatTime(value.hours, value.minutes, resolvedCycle) : '';
172
+ const [draft, setDraft] = useState<string>(formattedValue);
173
+ useEffect(() => {
174
+ setDraft(formattedValue);
175
+ // formattedValue is derived from value + resolvedCycle — re-sync on both.
176
+ }, [formattedValue]);
177
+
178
+ const [open, setOpen] = useState(false);
179
+ const wrapperRef = useRef<HTMLDivElement>(null);
180
+ const inputRef = useRef<HTMLInputElement>(null);
181
+
182
+ const { refs, floatingStyles } = useFloating({
183
+ open,
184
+ placement: 'bottom-start',
185
+ transform: false,
186
+ middleware: [offset(4), flip(), shift({ padding: 8 })],
187
+ whileElementsMounted: autoUpdate,
188
+ });
189
+
190
+ const setWrapperRef = useCallback(
191
+ (node: HTMLDivElement | null) => {
192
+ wrapperRef.current = node;
193
+ refs.setReference(node);
194
+ if (typeof ref === 'function') ref(node);
195
+ else if (ref != null) (ref as { current: HTMLDivElement | null }).current = node;
196
+ },
197
+ [refs, ref],
198
+ );
199
+
200
+ // Force-close whenever the field becomes disabled.
201
+ useEffect(() => {
202
+ if (isDisabled && open) setOpen(false);
203
+ }, [isDisabled, open]);
204
+
205
+ // ---- Commit (text → onChange) ----
206
+ const commit = useCallback(() => {
207
+ if (value == null) return;
208
+ const parsed = parseTime(draft);
209
+ if (parsed == null) {
210
+ // Revert to last-known good.
211
+ setDraft(formattedValue);
212
+ return;
213
+ }
214
+ const rounded = roundTimeToStep(parsed.hours, parsed.minutes, step);
215
+ if (rounded.hours === value.hours && rounded.minutes === value.minutes) {
216
+ // No-op — but re-normalize the visible draft so e.g. "230pm" snaps
217
+ // back to the canonical formatted value.
218
+ setDraft(formattedValue);
219
+ return;
220
+ }
221
+ onChange({ hours: rounded.hours, minutes: rounded.minutes });
222
+ }, [draft, formattedValue, onChange, step, value]);
223
+
224
+ // Commit when focus leaves the whole field (input, chevron, or the portaled
225
+ // clock — React bubbles its focus-out here too), not just the input:
226
+ // input → Tab → chevron → Tab away must still commit the typed time.
227
+ const handleFocusOut = useCallback(
228
+ (e: FocusEvent<HTMLDivElement>) => {
229
+ // Focus moved to a known element outside the field — commit now, before
230
+ // that element's click handler runs (it may unmount or clear us).
231
+ const to = e.relatedTarget;
232
+ if (
233
+ to instanceof Node &&
234
+ !wrapperRef.current?.contains(to) &&
235
+ !refs.floating.current?.contains(to)
236
+ ) {
237
+ commit();
238
+ onBlur?.(e);
239
+ return;
240
+ }
241
+ // Destination unknown (relatedTarget null: click on something
242
+ // non-focusable, Safari / Firefox-mac button clicks, window blur) or
243
+ // inside the field — defer so popover interactions (which move focus
244
+ // into the listbox) don't fire a commit-and-revert before the click
245
+ // handler runs.
246
+ window.setTimeout(() => {
247
+ if (!wrapperRef.current) return; // unmounted meanwhile — no onChange
248
+ const active = document.activeElement;
249
+ const insideWrapper = wrapperRef.current.contains(active);
250
+ const insideFloating = refs.floating.current?.contains(active);
251
+ if (!insideWrapper && !insideFloating) {
252
+ commit();
253
+ }
254
+ }, 0);
255
+ onBlur?.(e);
256
+ },
257
+ [commit, onBlur, refs.floating],
258
+ );
259
+
260
+ const handleInputKeyDown = useCallback(
261
+ (e: ReactKeyboardEvent<HTMLInputElement>) => {
262
+ if (e.key === 'Enter') {
263
+ e.preventDefault();
264
+ commit();
265
+ return;
266
+ }
267
+ if (e.key === 'Escape' && open) {
268
+ e.preventDefault();
269
+ setOpen(false);
270
+ return;
271
+ }
272
+ if (e.key === 'ArrowDown' && !isDisabled) {
273
+ e.preventDefault();
274
+ setOpen(true);
275
+ }
276
+ },
277
+ [commit, isDisabled, open],
278
+ );
279
+
280
+ // ---- Popover toggle ----
281
+ // #272: elevate the clock above Modal/Drawer hosts — and, transitively,
282
+ // above an elevated DatePicker calendar this field may be embedded in.
283
+ const inOverlay = useInOverlay(wrapperRef, open);
284
+ // #274: hosts yield Escape while we're open — our own capture/element
285
+ // handler closes us on the same press instead of the Modal/Drawer.
286
+ useFloatingSurface(open);
287
+
288
+ const handleToggle = useCallback(() => {
289
+ if (isDisabled) return;
290
+ setOpen((v) => {
291
+ const next = !v;
292
+ if (next) {
293
+ // Move focus to the input so the popover Escape / Arrow contracts
294
+ // remain intuitive on close. The arrow-nav effect below will then
295
+ // transfer focus into the listbox.
296
+ inputRef.current?.focus();
297
+ }
298
+ return next;
299
+ });
300
+ }, [isDisabled]);
301
+
302
+ // ---- Outside click + Escape ----
303
+ useEffect(() => {
304
+ if (!open) return;
305
+ const onPointerDown = (e: PointerEvent) => {
306
+ const target = e.target as Node | null;
307
+ const floating = refs.floating.current;
308
+ if (
309
+ target &&
310
+ !wrapperRef.current?.contains(target) &&
311
+ !floating?.contains(target) &&
312
+ // #684: a tour pointing into the clock doesn't dismiss it.
313
+ !isTourHeld(target, floating, wrapperRef.current)
314
+ ) {
315
+ commit();
316
+ setOpen(false);
317
+ }
318
+ };
319
+ document.addEventListener('pointerdown', onPointerDown, true);
320
+ return () => document.removeEventListener('pointerdown', onPointerDown, true);
321
+ }, [open, refs.floating, commit]);
322
+
323
+ useEffect(() => {
324
+ if (!open) return;
325
+ const onKey = (e: KeyboardEvent) => {
326
+ if (e.key === 'Escape') {
327
+ e.preventDefault();
328
+ overlayStack.consumeEscape(e); // hosts yield even if we ran first (#274)
329
+ setOpen(false);
330
+ inputRef.current?.focus();
331
+ }
332
+ };
333
+ document.addEventListener('keydown', onKey, true);
334
+ return () => document.removeEventListener('keydown', onKey, true);
335
+ }, [open]);
336
+
337
+ // ---- Row sets ----
338
+ const minuteCount = Math.max(1, Math.floor(60 / Math.max(1, step)));
339
+ const minuteRows: readonly number[] = useMemo(
340
+ () => Array.from({ length: minuteCount }, (_, i) => i * step),
341
+ [minuteCount, step],
342
+ );
343
+
344
+ // 24h: 0..23 displayed as "00".."23"; 12h: [12, 1, 2, ..., 11] displayed verbatim.
345
+ // Internal storage is always 24h — the 12h displayed value is mapped via
346
+ // `currentPeriod` when a row is clicked.
347
+ const hoursRows: readonly number[] = useMemo(
348
+ () =>
349
+ resolvedCycle === '24'
350
+ ? Array.from({ length: 24 }, (_, i) => i)
351
+ : [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
352
+ [resolvedCycle],
353
+ );
354
+
355
+ // Map current internal hour → display hour (used to find the current row
356
+ // in the popover's hours column, and to flag aria-selected / data-current).
357
+ const currentDisplayHour =
358
+ resolvedCycle === '24' ? currentHour : currentHour % 12 === 0 ? 12 : currentHour % 12;
359
+
360
+ // ---- Column structure for arrow nav ----
361
+ const columns: readonly FocusColumn[] = useMemo(
362
+ () =>
363
+ resolvedCycle === '12'
364
+ ? (['hours', 'minutes', 'period'] as const)
365
+ : (['hours', 'minutes'] as const),
366
+ [resolvedCycle],
367
+ );
368
+
369
+ const columnLength = useCallback(
370
+ (col: FocusColumn): number => {
371
+ if (col === 'hours') return hoursRows.length;
372
+ if (col === 'minutes') return minuteRows.length;
373
+ return 2; // period
374
+ },
375
+ [hoursRows.length, minuteRows.length],
376
+ );
377
+
378
+ // Return the row index of the currently-committed value within a column.
379
+ // Used both for the initial focus on popover open AND when ArrowLeft /
380
+ // ArrowRight switches columns — the destination column lands on its own
381
+ // current row, not on the source column's index.
382
+ const defaultFocusedIndexFor = useCallback(
383
+ (col: FocusColumn): number => {
384
+ if (col === 'hours') {
385
+ const i = hoursRows.indexOf(currentDisplayHour);
386
+ return i === -1 ? 0 : i;
387
+ }
388
+ if (col === 'minutes') {
389
+ const i = minuteRows.indexOf(currentMinute);
390
+ return i === -1 ? 0 : i;
391
+ }
392
+ return currentPeriod;
393
+ },
394
+ [currentDisplayHour, currentMinute, currentPeriod, hoursRows, minuteRows],
395
+ );
396
+
397
+ // ---- Roving tabIndex + arrow nav ----
398
+ const [focused, setFocused] = useState<{ column: FocusColumn; index: number }>({
399
+ column: 'hours',
400
+ index: 0,
401
+ });
402
+
403
+ // Refs to each row, keyed by "column-index", so the post-state-change
404
+ // effect can call .focus() on the row that now has tabIndex=0.
405
+ const rowRefs = useRef(new Map<string, HTMLLIElement | null>());
406
+ const setRowRef = useCallback(
407
+ (key: string) => (el: HTMLLIElement | null) => {
408
+ if (el === null) rowRefs.current.delete(key);
409
+ else rowRefs.current.set(key, el);
410
+ },
411
+ [],
412
+ );
413
+
414
+ // When the popover opens, set focused to the current hour row. Defer the
415
+ // .focus() via rAF — the focus effect below runs after the next render,
416
+ // by which time the portaled DOM is mounted and the row ref is attached.
417
+ useEffect(() => {
418
+ if (!open) return;
419
+ setFocused({ column: 'hours', index: defaultFocusedIndexFor('hours') });
420
+ // Intentionally don't depend on defaultFocusedIndexFor — we only want
421
+ // to snap-focus once per open transition, not every time the row index
422
+ // shifts because the user clicked a different value.
423
+ // eslint-disable-next-line react-hooks/exhaustive-deps
424
+ }, [open]);
425
+
426
+ // If the cycle flips 12 → 24 while the popover is open and focus had landed
427
+ // on the Period column, the Period listbox unmounts and arrow nav would
428
+ // operate on a zero-row column — user gets stuck. Clamp focus back to the
429
+ // Minutes column on its current row.
430
+ useEffect(() => {
431
+ if (focused.column === 'period' && resolvedCycle === '24') {
432
+ const i = minuteRows.indexOf(currentMinute);
433
+ setFocused({ column: 'minutes', index: i === -1 ? 0 : i });
434
+ }
435
+ // Narrow deps: this guard only needs to re-evaluate when the cycle or the
436
+ // currently focused column changes. Tracking minuteRows/currentMinute here
437
+ // would re-fire whenever the user clicks another minute, which is wrong —
438
+ // we only want to fire the one-time clamp on cycle shrink.
439
+ // eslint-disable-next-line react-hooks/exhaustive-deps
440
+ }, [resolvedCycle, focused.column]);
441
+
442
+ // Focus the row currently flagged with tabIndex=0. Runs after every
443
+ // focused-state change while the popover is open. The rAF defer mirrors
444
+ // the existing scrollIntoView pattern — the portaled `<li>` may not be
445
+ // in the DOM yet on the same tick as the open transition.
446
+ useEffect(() => {
447
+ if (!open) return;
448
+ const id = window.requestAnimationFrame(() => {
449
+ const el = rowRefs.current.get(`${focused.column}-${focused.index}`);
450
+ el?.focus();
451
+ });
452
+ return () => window.cancelAnimationFrame(id);
453
+ }, [focused, open]);
454
+
455
+ const moveColumn = useCallback(
456
+ (delta: number) => {
457
+ setFocused((f) => {
458
+ const i = columns.indexOf(f.column);
459
+ const nextIndex = Math.min(Math.max(0, i + delta), columns.length - 1);
460
+ const next = columns[nextIndex];
461
+ if (next === f.column) return f;
462
+ return { column: next, index: defaultFocusedIndexFor(next) };
463
+ });
464
+ },
465
+ [columns, defaultFocusedIndexFor],
466
+ );
467
+
468
+ const handlePopoverKeyDown = useCallback(
469
+ (e: ReactKeyboardEvent<HTMLDivElement>) => {
470
+ // Don't hijack the Now button's natural Tab / Enter behavior — its
471
+ // own click handler commits via onChange; arrow keys on it have no
472
+ // listbox semantics.
473
+ const target = e.target as HTMLElement | null;
474
+ if (target?.dataset.timefieldNowButton === 'true') return;
475
+
476
+ if (e.key === 'ArrowDown') {
477
+ e.preventDefault();
478
+ setFocused((f) => ({ ...f, index: Math.min(f.index + 1, columnLength(f.column) - 1) }));
479
+ } else if (e.key === 'ArrowUp') {
480
+ e.preventDefault();
481
+ setFocused((f) => ({ ...f, index: Math.max(f.index - 1, 0) }));
482
+ } else if (e.key === 'ArrowRight') {
483
+ e.preventDefault();
484
+ moveColumn(+1);
485
+ } else if (e.key === 'ArrowLeft') {
486
+ e.preventDefault();
487
+ moveColumn(-1);
488
+ } else if (e.key === 'Home') {
489
+ e.preventDefault();
490
+ setFocused((f) => ({ ...f, index: 0 }));
491
+ } else if (e.key === 'End') {
492
+ e.preventDefault();
493
+ setFocused((f) => ({ ...f, index: columnLength(f.column) - 1 }));
494
+ }
495
+ },
496
+ [columnLength, moveColumn],
497
+ );
498
+
499
+ // ---- Auto-scroll current row into view on open ----
500
+ const hoursColumnRef = useRef<HTMLUListElement>(null);
501
+ const minutesColumnRef = useRef<HTMLUListElement>(null);
502
+ const periodColumnRef = useRef<HTMLUListElement>(null);
503
+ useEffect(() => {
504
+ if (!open) return;
505
+ const scrollCurrent = (col: HTMLUListElement | null) => {
506
+ if (!col) return;
507
+ const current = col.querySelector<HTMLElement>('[data-current="true"]');
508
+ // jsdom doesn't implement scrollIntoView; feature-test before calling.
509
+ if (current && typeof current.scrollIntoView === 'function') {
510
+ current.scrollIntoView({ block: 'center' });
511
+ }
512
+ };
513
+ const id = window.requestAnimationFrame(() => {
514
+ scrollCurrent(hoursColumnRef.current);
515
+ scrollCurrent(minutesColumnRef.current);
516
+ scrollCurrent(periodColumnRef.current);
517
+ });
518
+ return () => window.cancelAnimationFrame(id);
519
+ }, [open]);
520
+
521
+ // ---- Row click handlers ----
522
+ // 12h hours-column click: map the displayed hour (12, 1..11) to a 24h
523
+ // internal hour given the CURRENT period (so flipping AM ↔ PM is a
524
+ // separate operation on the period column).
525
+ const display12ToInternal = useCallback((displayHour: number, isPm: boolean): number => {
526
+ // 12 AM → 0; 12 PM → 12; 1..11 AM → 1..11; 1..11 PM → 13..23.
527
+ const base = displayHour === 12 ? 0 : displayHour;
528
+ return isPm ? base + 12 : base;
529
+ }, []);
530
+
531
+ const handleHourPick = useCallback(
532
+ (rowValue: number) => {
533
+ if (value == null) return;
534
+ const internalHour =
535
+ resolvedCycle === '24' ? rowValue : display12ToInternal(rowValue, currentPeriod === 1);
536
+ const rounded = roundTimeToStep(internalHour, currentMinute, step);
537
+ onChange({ hours: rounded.hours, minutes: rounded.minutes });
538
+ },
539
+ [currentMinute, currentPeriod, display12ToInternal, onChange, resolvedCycle, step, value],
540
+ );
541
+
542
+ const handleMinutePick = useCallback(
543
+ (m: number) => {
544
+ if (value == null) return;
545
+ // Minute rows already align to `step`, but pass through roundTimeToStep
546
+ // for defensive consistency (cheap, idempotent for aligned values).
547
+ const rounded = roundTimeToStep(currentHour, m, step);
548
+ onChange({ hours: rounded.hours, minutes: rounded.minutes });
549
+ },
550
+ [currentHour, onChange, step, value],
551
+ );
552
+
553
+ const handlePeriodPick = useCallback(
554
+ (period: 0 | 1) => {
555
+ if (value == null) return;
556
+ // AM (0): clear PM bit if currently PM; else no-op.
557
+ // PM (1): set PM bit if currently AM; else no-op.
558
+ if (period === 0 && currentHour >= 12) {
559
+ onChange({ hours: currentHour - 12, minutes: currentMinute });
560
+ } else if (period === 1 && currentHour < 12) {
561
+ onChange({ hours: currentHour + 12, minutes: currentMinute });
562
+ }
563
+ // Same-period click is a no-op (no onChange) — clicking AM when
564
+ // already AM, or PM when already PM, doesn't churn the controlled
565
+ // value. Consumers relying on every click firing onChange should
566
+ // use the Now button instead.
567
+ },
568
+ [currentHour, currentMinute, onChange, value],
569
+ );
570
+
571
+ // ---- Now button ----
572
+ const handleNow = useCallback(() => {
573
+ const now = new Date();
574
+ const rounded = roundTimeToStep(now.getHours(), now.getMinutes(), step);
575
+ onChange({ hours: rounded.hours, minutes: rounded.minutes });
576
+ // Popover stays open — user can fine-tune from the snapped Now value.
577
+ }, [onChange, step]);
578
+
579
+ const popoverId = `${inputId}-popover`;
580
+
581
+ // Label helpers for the period rows (12h only).
582
+ const periodLabels = useMemo(
583
+ () => [t('datePicker.timePeriodAm'), t('datePicker.timePeriodPm')],
584
+ [t],
585
+ );
586
+
587
+ return (
588
+ // Wrapper is the public element — Pattern A (props last so consumer wins),
589
+ // but role/aria-label are spread BEFORE so the group semantics survive
590
+ // an unrelated wrapper-class override.
591
+ <div
592
+ role="group"
593
+ aria-label={ariaLabel}
594
+ aria-labelledby={ariaLabelledBy}
595
+ {...rest}
596
+ ref={setWrapperRef}
597
+ onBlur={handleFocusOut}
598
+ className={clsx(styles.timeField, isDisabled && styles.disabled, className)}
599
+ >
600
+ <input
601
+ ref={inputRef}
602
+ id={inputId}
603
+ type="text"
604
+ aria-invalid={invalid || undefined}
605
+ aria-required={required || undefined}
606
+ className={styles.timeInputCore}
607
+ placeholder={placeholder}
608
+ inputMode="numeric"
609
+ maxLength={inputMaxLength}
610
+ value={draft}
611
+ autoComplete="off"
612
+ aria-label={ariaLabel}
613
+ aria-labelledby={ariaLabelledBy}
614
+ aria-describedby={ariaDescribedBy}
615
+ aria-haspopup="listbox"
616
+ aria-expanded={open}
617
+ aria-controls={open ? popoverId : undefined}
618
+ disabled={isDisabled}
619
+ onChange={(e) => setDraft(e.target.value)}
620
+ onKeyDown={handleInputKeyDown}
621
+ />
622
+ <button
623
+ type="button"
624
+ className={styles.timeToggle}
625
+ // The toggle needs its OWN distinct name (the open-list action), never
626
+ // the field label — otherwise the input and toggle would share an
627
+ // identical accessible name. With a self-label, suffix the action; when
628
+ // only a Field labels the control (no aria-label), use the action text
629
+ // alone and DON'T forward aria-labelledby (which would duplicate the
630
+ // input's name on the toggle).
631
+ aria-label={
632
+ ariaLabel ? `${ariaLabel}, ${t('datePicker.timeOpenList')}` : t('datePicker.timeOpenList')
633
+ }
634
+ aria-haspopup="listbox"
635
+ aria-expanded={open}
636
+ aria-controls={open ? popoverId : undefined}
637
+ disabled={isDisabled}
638
+ onClick={handleToggle}
639
+ // Don't steal focus from the input on mousedown — the click handler
640
+ // explicitly focuses the input after toggling.
641
+ onMouseDown={(e) => e.preventDefault()}
642
+ >
643
+ <ChevronDown size={14} aria-hidden="true" />
644
+ </button>
645
+ {open &&
646
+ createPortal(
647
+ <div
648
+ ref={refs.setFloating}
649
+ id={popoverId}
650
+ style={floatingStyles}
651
+ className={styles.timePopover}
652
+ // Marker attribute: TimeField may be embedded inside a parent
653
+ // popover (the DatePicker's calendar dialog) whose own outside-
654
+ // click handler also listens on document/capture. The parent
655
+ // checks for `[data-timefield-popover]` and treats those clicks
656
+ // as "inside" so the parent doesn't auto-close mid-interaction.
657
+ data-timefield-popover="true"
658
+ data-in-overlay={inOverlay ? '' : undefined}
659
+ onKeyDown={handlePopoverKeyDown}
660
+ // Don't steal focus when clicking inside the popover (rows).
661
+ onMouseDown={(e) => e.preventDefault()}
662
+ >
663
+ <div className={styles.timeColumns}>
664
+ <ul
665
+ ref={hoursColumnRef}
666
+ className={styles.timeColumn}
667
+ role="listbox"
668
+ aria-label={t('datePicker.timeHoursLabel')}
669
+ >
670
+ {hoursRows.map((h, i) => {
671
+ const isCurrent = h === currentDisplayHour;
672
+ const isFocused = focused.column === 'hours' && focused.index === i;
673
+ const label = resolvedCycle === '24' ? String(h).padStart(2, '0') : String(h);
674
+ return (
675
+ <li
676
+ key={h}
677
+ ref={setRowRef(`hours-${i}`)}
678
+ role="option"
679
+ aria-selected={isCurrent}
680
+ data-current={isCurrent ? 'true' : undefined}
681
+ tabIndex={isFocused ? 0 : -1}
682
+ className={clsx(styles.timeRow, isCurrent && styles.timeRowCurrent)}
683
+ onClick={() => handleHourPick(h)}
684
+ onKeyDown={(e) => {
685
+ if (e.key === 'Enter' || e.key === ' ') {
686
+ e.preventDefault();
687
+ handleHourPick(h);
688
+ }
689
+ }}
690
+ >
691
+ <span className={styles.timeRowLabel}>{label}</span>
692
+ {isCurrent && (
693
+ <Check size={12} aria-hidden="true" className={styles.timeRowCheck} />
694
+ )}
695
+ </li>
696
+ );
697
+ })}
698
+ </ul>
699
+ <div className={styles.timeColumnDivider} aria-hidden="true" />
700
+ <ul
701
+ ref={minutesColumnRef}
702
+ className={styles.timeColumn}
703
+ role="listbox"
704
+ aria-label={t('datePicker.timeMinutesLabel')}
705
+ >
706
+ {minuteRows.map((m, i) => {
707
+ const isCurrent = m === currentMinute;
708
+ const isFocused = focused.column === 'minutes' && focused.index === i;
709
+ return (
710
+ <li
711
+ key={m}
712
+ ref={setRowRef(`minutes-${i}`)}
713
+ role="option"
714
+ aria-selected={isCurrent}
715
+ data-current={isCurrent ? 'true' : undefined}
716
+ tabIndex={isFocused ? 0 : -1}
717
+ className={clsx(styles.timeRow, isCurrent && styles.timeRowCurrent)}
718
+ onClick={() => handleMinutePick(m)}
719
+ onKeyDown={(e) => {
720
+ if (e.key === 'Enter' || e.key === ' ') {
721
+ e.preventDefault();
722
+ handleMinutePick(m);
723
+ }
724
+ }}
725
+ >
726
+ <span className={styles.timeRowLabel}>{String(m).padStart(2, '0')}</span>
727
+ {isCurrent && (
728
+ <Check size={12} aria-hidden="true" className={styles.timeRowCheck} />
729
+ )}
730
+ </li>
731
+ );
732
+ })}
733
+ </ul>
734
+ {resolvedCycle === '12' && (
735
+ <>
736
+ <div className={styles.timeColumnDivider} aria-hidden="true" />
737
+ <ul
738
+ ref={periodColumnRef}
739
+ className={clsx(styles.timeColumn, styles.timeColumnPeriod)}
740
+ role="listbox"
741
+ aria-label={t('datePicker.timePeriodLabel')}
742
+ >
743
+ {[0, 1].map((p) => {
744
+ const isCurrent = p === currentPeriod;
745
+ const isFocused = focused.column === 'period' && focused.index === p;
746
+ return (
747
+ <li
748
+ key={p}
749
+ ref={setRowRef(`period-${p}`)}
750
+ role="option"
751
+ aria-selected={isCurrent}
752
+ data-current={isCurrent ? 'true' : undefined}
753
+ tabIndex={isFocused ? 0 : -1}
754
+ className={clsx(styles.timeRow, isCurrent && styles.timeRowCurrent)}
755
+ onClick={() => handlePeriodPick(p as 0 | 1)}
756
+ onKeyDown={(e) => {
757
+ if (e.key === 'Enter' || e.key === ' ') {
758
+ e.preventDefault();
759
+ handlePeriodPick(p as 0 | 1);
760
+ }
761
+ }}
762
+ >
763
+ <span className={styles.timeRowLabel}>{periodLabels[p]}</span>
764
+ {isCurrent && (
765
+ <Check size={12} aria-hidden="true" className={styles.timeRowCheck} />
766
+ )}
767
+ </li>
768
+ );
769
+ })}
770
+ </ul>
771
+ </>
772
+ )}
773
+ </div>
774
+ {!hideNowButton && (
775
+ <div className={styles.timeFooter}>
776
+ <button
777
+ type="button"
778
+ className={styles.timeNowButton}
779
+ data-timefield-now-button="true"
780
+ onClick={handleNow}
781
+ >
782
+ {t('datePicker.timeNow')}
783
+ </button>
784
+ </div>
785
+ )}
786
+ </div>,
787
+ document.body,
788
+ )}
789
+ </div>
790
+ );
791
+ });
792
+
793
+ TimeField.displayName = 'TimeField';