@astryxdesign/core 0.5.2-canary.2da7a39 → 0.5.2-canary.2e51213

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 (375) hide show
  1. package/dist/AppShell/AppShell.d.ts +2 -2
  2. package/dist/AppShell/AppShell.d.ts.map +1 -1
  3. package/dist/AppShell/AppShell.js +10 -7
  4. package/dist/Banner/Banner.d.ts +5 -0
  5. package/dist/Banner/Banner.d.ts.map +1 -1
  6. package/dist/Banner/Banner.js +7 -2
  7. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +3 -2
  8. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  9. package/dist/Breadcrumbs/BreadcrumbItem.js +22 -15
  10. package/dist/Carousel/Carousel.d.ts.map +1 -1
  11. package/dist/Carousel/Carousel.js +2 -2
  12. package/dist/Chat/ChatComposer.d.ts +2 -2
  13. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  14. package/dist/Chat/ChatComposer.js +21 -2
  15. package/dist/Chat/ChatToolCalls.d.ts +1 -1
  16. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  17. package/dist/Chat/ChatToolCalls.js +12 -34
  18. package/dist/Chat/useChatNewMessages.js +3 -3
  19. package/dist/CheckboxList/CheckboxListItem.d.ts +5 -3
  20. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  21. package/dist/DateTimeInput/DateTimeInput.d.ts +47 -13
  22. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  23. package/dist/DateTimeInput/DateTimeInput.js +269 -162
  24. package/dist/DateTimeInput/NativeDateSegment.d.ts +24 -0
  25. package/dist/DateTimeInput/NativeDateSegment.d.ts.map +1 -0
  26. package/dist/DateTimeInput/NativeDateSegment.js +235 -0
  27. package/dist/DateTimeInput/NativeTimeSegment.d.ts +30 -0
  28. package/dist/DateTimeInput/NativeTimeSegment.d.ts.map +1 -0
  29. package/dist/DateTimeInput/NativeTimeSegment.js +248 -0
  30. package/dist/DateTimeInput/index.d.ts +1 -1
  31. package/dist/DateTimeInput/index.d.ts.map +1 -1
  32. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts +95 -0
  33. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts.map +1 -0
  34. package/dist/DateTimeInput/nativePickerSegmentStyles.js +103 -0
  35. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  36. package/dist/DropdownMenu/DropdownMenu.js +2 -4
  37. package/dist/Field/Field.d.ts.map +1 -1
  38. package/dist/Field/Field.js +10 -4
  39. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  40. package/dist/Field/PanelSearchInput.js +3 -5
  41. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  42. package/dist/FieldStatus/FieldStatus.js +4 -2
  43. package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
  44. package/dist/Layer/useTouchTrigger.js +2 -4
  45. package/dist/Layout/Layout.d.ts +7 -8
  46. package/dist/Layout/Layout.d.ts.map +1 -1
  47. package/dist/Layout/Layout.js +7 -8
  48. package/dist/MultiSelector/MultiSelector.d.ts +11 -1
  49. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  50. package/dist/MultiSelector/MultiSelector.js +89 -45
  51. package/dist/RadioList/RadioListItem.d.ts +30 -5
  52. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  53. package/dist/RadioList/RadioListItem.js +17 -4
  54. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  55. package/dist/Resizable/ResizeHandle.js +102 -44
  56. package/dist/Resizable/index.d.ts +2 -0
  57. package/dist/Resizable/index.d.ts.map +1 -1
  58. package/dist/Resizable/index.js +1 -0
  59. package/dist/Resizable/useResizable.d.ts +89 -8
  60. package/dist/Resizable/useResizable.d.ts.map +1 -1
  61. package/dist/Resizable/useResizable.js +521 -38
  62. package/dist/Resizable/utils.d.ts +35 -0
  63. package/dist/Resizable/utils.d.ts.map +1 -0
  64. package/dist/Resizable/utils.js +27 -0
  65. package/dist/Selector/Selector.d.ts +10 -0
  66. package/dist/Selector/Selector.d.ts.map +1 -1
  67. package/dist/Selector/Selector.js +105 -57
  68. package/dist/Selector/useSelectorPresentation.d.ts +1 -0
  69. package/dist/Selector/useSelectorPresentation.d.ts.map +1 -1
  70. package/dist/Selector/useSelectorPresentation.js +17 -2
  71. package/dist/Slider/Slider.d.ts.map +1 -1
  72. package/dist/Slider/Slider.js +3 -5
  73. package/dist/Spinner/Spinner.d.ts.map +1 -1
  74. package/dist/Spinner/Spinner.js +9 -10
  75. package/dist/Stepper/Step.d.ts +2 -1
  76. package/dist/Stepper/Step.d.ts.map +1 -1
  77. package/dist/Stepper/Step.js +75 -11
  78. package/dist/Stepper/Stepper.d.ts.map +1 -1
  79. package/dist/Stepper/Stepper.js +1 -0
  80. package/dist/TabList/TabList.d.ts.map +1 -1
  81. package/dist/TabList/TabList.js +2 -3
  82. package/dist/Table/index.d.ts +16 -1
  83. package/dist/Table/index.d.ts.map +1 -1
  84. package/dist/Table/index.js +4 -0
  85. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  86. package/dist/Table/plugins/columnResize/useTableColumnResize.js +8 -9
  87. package/dist/Table/plugins/rowStatus/index.d.ts +1 -1
  88. package/dist/Table/plugins/rowStatus/index.d.ts.map +1 -1
  89. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts +11 -30
  90. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -1
  91. package/dist/Table/plugins/rowStatus/useTableRowStatus.js +108 -62
  92. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  93. package/dist/Table/plugins/sortable/useTableSortable.js +9 -1
  94. package/dist/Text/useTruncation.d.ts +1 -1
  95. package/dist/Text/useTruncation.d.ts.map +1 -1
  96. package/dist/Text/useTruncation.js +8 -7
  97. package/dist/TimeInput/TimeInput.d.ts +16 -1
  98. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  99. package/dist/TimeInput/TimeInput.js +98 -60
  100. package/dist/TimeInput/index.d.ts +1 -1
  101. package/dist/TimeInput/index.d.ts.map +1 -1
  102. package/dist/Timestamp/Timestamp.d.ts +2 -2
  103. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  104. package/dist/Timestamp/Timestamp.js +4 -145
  105. package/dist/Timestamp/formatRelativeTime.d.ts +20 -0
  106. package/dist/Timestamp/formatRelativeTime.d.ts.map +1 -0
  107. package/dist/Timestamp/formatRelativeTime.js +81 -0
  108. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  109. package/dist/Toast/ToastViewport.js +125 -77
  110. package/dist/Tokenizer/Tokenizer.d.ts +0 -38
  111. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  112. package/dist/Tokenizer/Tokenizer.js +94 -26
  113. package/dist/Tokenizer/useEndLaneReserve.d.ts +31 -0
  114. package/dist/Tokenizer/useEndLaneReserve.d.ts.map +1 -0
  115. package/dist/Tokenizer/useEndLaneReserve.js +136 -0
  116. package/dist/Tooltip/useTooltip.d.ts +1 -1
  117. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  118. package/dist/Tooltip/useTooltip.js +53 -42
  119. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  120. package/dist/Typeahead/BaseTypeahead.js +85 -30
  121. package/dist/Typeahead/Typeahead.d.ts +0 -21
  122. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  123. package/dist/Typeahead/Typeahead.js +108 -67
  124. package/dist/Typeahead/busyIndicatorLane.d.ts +62 -0
  125. package/dist/Typeahead/busyIndicatorLane.d.ts.map +1 -0
  126. package/dist/Typeahead/busyIndicatorLane.js +98 -0
  127. package/dist/astryx.css +25 -7
  128. package/dist/hooks/useFocusReturnVisibility.d.ts.map +1 -1
  129. package/dist/hooks/useFocusReturnVisibility.js +3 -5
  130. package/dist/hooks/useIsomorphicLayoutEffect.d.ts +2 -2
  131. package/dist/hooks/useIsomorphicLayoutEffect.d.ts.map +1 -1
  132. package/dist/hooks/useOverflow.js +11 -11
  133. package/dist/hooks/useScrollOverflow.d.ts.map +1 -1
  134. package/dist/hooks/useScrollOverflow.js +7 -4
  135. package/dist/theme/defineTheme.d.ts +13 -0
  136. package/dist/theme/defineTheme.d.ts.map +1 -1
  137. package/dist/theme/defineTheme.js +7 -0
  138. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  139. package/dist/theme/generateThemeRules.js +1 -1
  140. package/dist/theme/localTokens.d.ts +18 -0
  141. package/dist/theme/localTokens.d.ts.map +1 -0
  142. package/dist/theme/localTokens.js +162 -0
  143. package/dist/utils/interactionModality.d.ts +6 -28
  144. package/dist/utils/interactionModality.d.ts.map +1 -1
  145. package/dist/utils/interactionModality.js +72 -37
  146. package/dist/utils/sharedResizeObserver.d.ts +17 -9
  147. package/dist/utils/sharedResizeObserver.d.ts.map +1 -1
  148. package/dist/utils/sharedResizeObserver.js +54 -12
  149. package/locales/en.json +8 -0
  150. package/locales/pseudo.json +6 -0
  151. package/package.json +7 -2
  152. package/src/AlertDialog/useImperativeAlertDialog.test.tsx +163 -0
  153. package/src/AppShell/AppShell.doc.mjs +4 -3
  154. package/src/AppShell/AppShell.test.tsx +21 -0
  155. package/src/AppShell/AppShell.tsx +12 -7
  156. package/src/Banner/Banner.doc.mjs +5 -1
  157. package/src/Banner/Banner.tsx +12 -1
  158. package/src/BottomSheet/BottomSheet.doc.mjs +31 -0
  159. package/src/BottomSheet/BottomSheet.spec.md +178 -0
  160. package/src/Breadcrumbs/BreadcrumbItem.tsx +18 -9
  161. package/src/Breadcrumbs/Breadcrumbs.doc.mjs +4 -1
  162. package/src/Breadcrumbs/Breadcrumbs.test.tsx +12 -0
  163. package/src/Button/Button.doc.mjs +56 -0
  164. package/src/ButtonGroup/ButtonGroup.doc.mjs +47 -0
  165. package/src/Calendar/hooks/useCalendarConstraints.test.ts +153 -0
  166. package/src/Calendar/hooks/useCalendarDays.test.ts +265 -0
  167. package/src/Calendar/hooks/useCalendarNavigation.test.ts +252 -0
  168. package/src/Carousel/Carousel.test.tsx +83 -0
  169. package/src/Carousel/Carousel.tsx +8 -2
  170. package/src/Chat/ChatComposer.doc.mjs +7 -4
  171. package/src/Chat/ChatComposer.test.tsx +84 -2
  172. package/src/Chat/ChatComposer.tsx +45 -3
  173. package/src/Chat/ChatSendButton.test.tsx +189 -0
  174. package/src/Chat/ChatToolCalls.doc.mjs +1 -1
  175. package/src/Chat/ChatToolCalls.test.tsx +33 -1
  176. package/src/Chat/ChatToolCalls.tsx +13 -34
  177. package/src/Chat/useChatNewMessages.ts +3 -3
  178. package/src/Chat/useChatPasteAsToken.test.ts +191 -0
  179. package/src/CheckboxList/CheckboxList.doc.mjs +172 -31
  180. package/src/CheckboxList/CheckboxList.spec.md +215 -0
  181. package/src/CheckboxList/CheckboxList.test.tsx +45 -0
  182. package/src/CheckboxList/CheckboxListItem.doc.mjs +11 -9
  183. package/src/CheckboxList/CheckboxListItem.tsx +5 -3
  184. package/src/Collapsible/useCollapsible.test.tsx +236 -0
  185. package/src/CommandPalette/CommandPalette.doc.mjs +72 -0
  186. package/src/CommandPalette/CommandPalette.spec.md +224 -0
  187. package/src/CommandPalette/CommandPaletteEmpty.test.tsx +101 -0
  188. package/src/ComplexSelector/ComplexSelector.doc.mjs +42 -0
  189. package/src/ComplexSelector/ComplexSelector.spec.md +190 -0
  190. package/src/ContextMenu/ContextMenu.doc.mjs +48 -0
  191. package/src/ContextMenu/ContextMenu.spec.md +207 -0
  192. package/src/DateTimeInput/DateTimeInput.doc.mjs +43 -23
  193. package/src/DateTimeInput/DateTimeInput.tsx +388 -181
  194. package/src/DateTimeInput/DateTimeInputTouch.test.tsx +10 -2
  195. package/src/DateTimeInput/NativeDateSegment.tsx +308 -0
  196. package/src/DateTimeInput/NativePickerSegments.test.tsx +626 -0
  197. package/src/DateTimeInput/NativeTimeSegment.tsx +331 -0
  198. package/src/DateTimeInput/index.ts +1 -0
  199. package/src/DateTimeInput/nativePickerSegmentStyles.ts +120 -0
  200. package/src/Divider/Divider.doc.mjs +24 -0
  201. package/src/Divider/Divider.spec.md +157 -0
  202. package/src/DropdownMenu/DropdownMenu.doc.mjs +104 -0
  203. package/src/DropdownMenu/DropdownMenu.spec.md +246 -0
  204. package/src/DropdownMenu/DropdownMenu.tsx +2 -4
  205. package/src/Field/Field.doc.mjs +1 -0
  206. package/src/Field/Field.test.tsx +39 -0
  207. package/src/Field/Field.tsx +18 -1
  208. package/src/Field/InputClearButton.test.tsx +68 -6
  209. package/src/Field/PanelSearchInput.tsx +3 -5
  210. package/src/FieldStatus/FieldStatus.doc.mjs +21 -0
  211. package/src/FieldStatus/FieldStatus.spec.md +213 -0
  212. package/src/FieldStatus/FieldStatus.test.tsx +17 -0
  213. package/src/FieldStatus/FieldStatus.tsx +7 -2
  214. package/src/Grid/Grid.doc.mjs +19 -0
  215. package/src/Grid/Grid.spec.md +162 -0
  216. package/src/Icon/Icon.doc.mjs +196 -48
  217. package/src/Icon/Icon.spec.md +192 -0
  218. package/src/IconButton/IconButton.doc.mjs +38 -0
  219. package/src/Kbd/Kbd.doc.mjs +18 -0
  220. package/src/Kbd/Kbd.spec.md +142 -0
  221. package/src/Layer/useTouchTrigger.ts +2 -4
  222. package/src/Layout/Layout.doc.mjs +57 -17
  223. package/src/Layout/Layout.spec.md +235 -0
  224. package/src/Layout/Layout.test.tsx +1 -1
  225. package/src/Layout/Layout.tsx +7 -8
  226. package/src/Layout/LayoutHeader.doc.mjs +9 -0
  227. package/src/Layout/LayoutPanel.doc.mjs +4 -3
  228. package/src/Lightbox/Lightbox.doc.mjs +149 -33
  229. package/src/Lightbox/Lightbox.spec.md +198 -0
  230. package/src/Lightbox/useLightbox.test.tsx +263 -0
  231. package/src/Markdown/Markdown.doc.mjs +60 -0
  232. package/src/Markdown/Markdown.spec.md +207 -0
  233. package/src/MobileNav/MobileNav.doc.mjs +140 -32
  234. package/src/MobileNav/MobileNav.spec.md +209 -0
  235. package/src/MoreMenu/MoreMenu.doc.mjs +42 -0
  236. package/src/MoreMenu/MoreMenu.spec.md +222 -0
  237. package/src/MultiSelector/MultiSelector.doc.mjs +124 -1
  238. package/src/MultiSelector/MultiSelector.spec.md +293 -0
  239. package/src/MultiSelector/MultiSelector.test.tsx +305 -2
  240. package/src/MultiSelector/MultiSelector.tsx +124 -55
  241. package/src/NavIcon/NavIcon.doc.mjs +17 -0
  242. package/src/NavIcon/NavIcon.spec.md +134 -0
  243. package/src/NavMenu/NavHeadingMenu.spec.md +210 -0
  244. package/src/NavMenu/NavMenu.doc.mjs +37 -0
  245. package/src/Outline/Outline.doc.mjs +35 -0
  246. package/src/Outline/Outline.spec.md +162 -0
  247. package/src/OverflowList/OverflowList.doc.mjs +24 -0
  248. package/src/OverflowList/OverflowList.spec.md +157 -0
  249. package/src/Pagination/Pagination.doc.mjs +74 -0
  250. package/src/Pagination/Pagination.spec.md +226 -0
  251. package/src/Popover/Popover.doc.mjs +264 -65
  252. package/src/Popover/Popover.spec.md +421 -0
  253. package/src/Popover/usePopover.doc.mjs +208 -33
  254. package/src/PowerSearch/PowerSearch.spec.md +291 -0
  255. package/src/PowerSearch/PowerSearchFilterEditor.test.tsx +253 -0
  256. package/src/PowerSearch/PowerSearchToken.test.tsx +228 -0
  257. package/src/ProgressBar/ProgressBar.doc.mjs +198 -38
  258. package/src/ProgressBar/ProgressBar.spec.md +261 -0
  259. package/src/RadioList/RadioList.test.tsx +136 -2
  260. package/src/RadioList/RadioListItem.doc.mjs +30 -11
  261. package/src/RadioList/RadioListItem.tsx +44 -8
  262. package/src/Resizable/Resizable.doc.mjs +130 -24
  263. package/src/Resizable/Resizable.spec.md +246 -0
  264. package/src/Resizable/ResizeHandle.test.tsx +177 -56
  265. package/src/Resizable/ResizeHandle.tsx +128 -45
  266. package/src/Resizable/index.ts +2 -0
  267. package/src/Resizable/shippedDirections.test.ts +462 -0
  268. package/src/Resizable/useResizable.doc.mjs +124 -29
  269. package/src/Resizable/useResizable.test.ts +1277 -3
  270. package/src/Resizable/useResizable.ts +760 -48
  271. package/src/Resizable/utils.test.ts +74 -0
  272. package/src/Resizable/utils.ts +35 -0
  273. package/src/Section/Section.doc.mjs +17 -0
  274. package/src/Section/Section.spec.md +139 -0
  275. package/src/SegmentedControl/SegmentedControl.doc.mjs +83 -0
  276. package/src/SegmentedControl/SegmentedControl.spec.md +152 -0
  277. package/src/Selector/Selector.doc.mjs +133 -97
  278. package/src/Selector/Selector.spec.md +300 -0
  279. package/src/Selector/Selector.test.tsx +318 -1
  280. package/src/Selector/Selector.tsx +127 -60
  281. package/src/Selector/useSelectorPresentation.ts +24 -4
  282. package/src/SideNav/SideNav.test.tsx +3 -3
  283. package/src/SideNav/SideNavCollapseButton.doc.mjs +8 -0
  284. package/src/SideNav/SideNavItem.doc.mjs +1 -1
  285. package/src/Skeleton/Skeleton.doc.mjs +12 -0
  286. package/src/Skeleton/Skeleton.spec.md +127 -0
  287. package/src/Slider/Slider.doc.mjs +184 -30
  288. package/src/Slider/Slider.spec.md +224 -0
  289. package/src/Slider/Slider.tsx +2 -5
  290. package/src/Spinner/Spinner.doc.mjs +5 -5
  291. package/src/Spinner/Spinner.test.tsx +32 -7
  292. package/src/Spinner/Spinner.tsx +46 -14
  293. package/src/Stack/Stack.doc.mjs +22 -0
  294. package/src/Stack/Stack.spec.md +155 -0
  295. package/src/StatusDot/StatusDot.doc.mjs +17 -0
  296. package/src/StatusDot/StatusDot.spec.md +138 -0
  297. package/src/Stepper/Step.doc.mjs +1 -1
  298. package/src/Stepper/Step.tsx +118 -5
  299. package/src/Stepper/Stepper.doc.mjs +51 -1
  300. package/src/Stepper/Stepper.spec.md +245 -0
  301. package/src/Stepper/Stepper.test.tsx +315 -0
  302. package/src/Stepper/Stepper.tsx +8 -0
  303. package/src/Switch/Switch.doc.mjs +40 -0
  304. package/src/Switch/Switch.spec.md +175 -0
  305. package/src/TabList/TabList.tsx +2 -3
  306. package/src/Table/Table.doc.mjs +102 -24
  307. package/src/Table/Table.perf.test.tsx +51 -1
  308. package/src/Table/Table.spec.md +325 -0
  309. package/src/Table/TableHeaderCell.test.tsx +291 -0
  310. package/src/Table/index.ts +19 -4
  311. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +8 -12
  312. package/src/Table/plugins/filtering/useTableFilterState.test.tsx +143 -0
  313. package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +2 -1
  314. package/src/Table/plugins/rowStatus/index.ts +1 -4
  315. package/src/Table/plugins/rowStatus/useTableRowStatus.public.test.ts +92 -0
  316. package/src/Table/plugins/rowStatus/useTableRowStatus.spec.md +354 -0
  317. package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +431 -56
  318. package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +155 -84
  319. package/src/Table/plugins/sortable/useTableSortable.test.tsx +72 -0
  320. package/src/Table/plugins/sortable/useTableSortable.tsx +18 -1
  321. package/src/Table/useTableGroupedRows.doc.mjs +2 -2
  322. package/src/Table/useTableRowStatus.doc.mjs +5 -5
  323. package/src/Text/Text.doc.mjs +190 -43
  324. package/src/Text/Text.spec.md +206 -0
  325. package/src/Text/useTruncation.ts +8 -7
  326. package/src/TextArea/TextArea.doc.mjs +255 -45
  327. package/src/TextArea/TextArea.spec.md +205 -0
  328. package/src/TimeInput/NativeTimeInput.test.tsx +269 -0
  329. package/src/TimeInput/TimeInput.doc.mjs +47 -23
  330. package/src/TimeInput/TimeInput.tsx +109 -50
  331. package/src/TimeInput/index.ts +1 -0
  332. package/src/Timestamp/Timestamp.doc.mjs +2 -2
  333. package/src/Timestamp/Timestamp.test.tsx +75 -3
  334. package/src/Timestamp/Timestamp.tsx +7 -153
  335. package/src/Timestamp/formatRelativeTime.ts +96 -0
  336. package/src/Toast/ToastViewport.test.tsx +194 -0
  337. package/src/Toast/ToastViewport.tsx +136 -58
  338. package/src/ToggleButton/ToggleButton.doc.mjs +56 -0
  339. package/src/Tokenizer/Tokenizer.doc.mjs +2 -0
  340. package/src/Tokenizer/Tokenizer.spec.md +293 -0
  341. package/src/Tokenizer/Tokenizer.test.tsx +335 -1
  342. package/src/Tokenizer/Tokenizer.tsx +129 -46
  343. package/src/Tokenizer/useEndLaneReserve.ts +146 -0
  344. package/src/Toolbar/Toolbar.doc.mjs +19 -0
  345. package/src/Toolbar/Toolbar.spec.md +174 -0
  346. package/src/Tooltip/Tooltip.doc.mjs +17 -0
  347. package/src/Tooltip/Tooltip.spec.md +142 -0
  348. package/src/Tooltip/Tooltip.test.tsx +21 -1
  349. package/src/Tooltip/useTooltip.test.tsx +318 -0
  350. package/src/Tooltip/useTooltip.tsx +60 -39
  351. package/src/TreeList/TreeList.doc.mjs +58 -0
  352. package/src/TreeList/TreeList.spec.md +224 -0
  353. package/src/Typeahead/BaseTypeahead.tsx +96 -25
  354. package/src/Typeahead/Typeahead.doc.mjs +89 -1
  355. package/src/Typeahead/Typeahead.spec.md +257 -0
  356. package/src/Typeahead/Typeahead.test.tsx +502 -1
  357. package/src/Typeahead/Typeahead.tsx +187 -69
  358. package/src/Typeahead/TypeaheadItem.test.tsx +93 -2
  359. package/src/Typeahead/busyIndicatorLane.tsx +109 -0
  360. package/src/__tests__/stylexDeclarations.ts +51 -0
  361. package/src/hooks/useFocusReturnVisibility.ts +3 -5
  362. package/src/hooks/useOverflow.ts +11 -11
  363. package/src/hooks/useScrollLock.test.ts +103 -0
  364. package/src/hooks/useScrollOverflow.ts +7 -4
  365. package/src/i18n/useTranslator.test.tsx +197 -0
  366. package/src/theme/defineTheme.test.ts +227 -0
  367. package/src/theme/defineTheme.ts +30 -0
  368. package/src/theme/derivedVarRegistry.test.ts +6 -0
  369. package/src/theme/generateThemeRules.ts +4 -1
  370. package/src/theme/localTokens.ts +272 -0
  371. package/src/theme/themingTargets.test.ts +126 -28
  372. package/src/utils/interactionModality.test.ts +83 -0
  373. package/src/utils/interactionModality.ts +88 -36
  374. package/src/utils/sharedResizeObserver.test.ts +124 -5
  375. package/src/utils/sharedResizeObserver.ts +60 -14
@@ -0,0 +1,235 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file NativeDateSegment.tsx
7
+ * @input Uses React, Icon, nativeDateSegments, and DateTimeInput's date state
8
+ * @output Exports NativeDateSegment — the OS-picker date half of DateTimeInput
9
+ * @position Internal DateTimeInput surface selected by `nativePicker`
10
+ *
11
+ * Hands date picking to the platform through `<input type="date">`. Its
12
+ * sibling NativeTimeSegment hands time picking to `<input type="time">`, so
13
+ * both halves of DateTimeInput follow the same `nativePicker` choice.
14
+ *
15
+ * The input is deliberately uncontrolled and observed through native event
16
+ * listeners. On iOS, writing its value while the picker sheet is open can
17
+ * detach the sheet, and React's synthetic change event does not reliably see
18
+ * picker edits. External values therefore reconcile only while unfocused.
19
+ *
20
+ * SYNC: When modified, update these files to stay in sync:
21
+ * - /packages/core/src/DateTimeInput/DateTimeInput.tsx (surface selection)
22
+ * - /packages/core/src/DateTimeInput/NativePickerSegments.test.tsx (tests)
23
+ * - /packages/core/src/DateTimeInput/DateTimeInput.doc.mjs (prop docs)
24
+ */
25
+ import { useCallback, useEffect, useRef, useState } from 'react';
26
+ import * as stylex from '@stylexjs/stylex';
27
+ import { hasEditableDateSegments } from "../DateInput/nativeDateSegments.js";
28
+ import { useMediaQuery } from "../hooks/useMediaQuery.js";
29
+ import { useMergedRefs } from "../hooks/useMergedRefs.js";
30
+ import { Icon } from "../Icon/index.js";
31
+ import { useLocale, useTranslator } from "../i18n/index.js";
32
+ import { VisuallyHidden } from "../VisuallyHidden/index.js";
33
+ import { focusOutlineStyles, formatSharedDate, parseDateInput, plainDateFromISO, plainDateToISO, themeProps } from "../utils/index.js";
34
+ import { nativePickerSegmentStyles as styles } from "./nativePickerSegmentStyles.js";
35
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
36
+ const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
37
+ /** The native date half rendered inside DateTimeInput's date wrapper. */
38
+ export function NativeDateSegment({
39
+ id,
40
+ inputRef,
41
+ value,
42
+ onChange,
43
+ placeholder,
44
+ min,
45
+ max,
46
+ isDateDisabled,
47
+ isEffectivelyDisabled,
48
+ hasDisabledMessage,
49
+ isEffectivelyRequired,
50
+ isBusy,
51
+ statusType,
52
+ ariaDescribedBy
53
+ }) {
54
+ const t = useTranslator();
55
+ const locale = useLocale();
56
+ const isTouchPointer = useMediaQuery('(pointer: coarse)');
57
+ const internalInputRef = useRef(null);
58
+ const mergedInputRef = useMergedRefs(inputRef, internalInputRef);
59
+ const [rejectedValue, setRejectedValue] = useState(null);
60
+ const [isFocused, setIsFocused] = useState(false);
61
+ const [isSegmentEditable, setIsSegmentEditable] = useState(false);
62
+ const valueAtFocusRef = useRef(null);
63
+ const lastCommitRef = useRef(null);
64
+ const prevValueRef = useRef(value);
65
+ if (value !== prevValueRef.current) {
66
+ prevValueRef.current = value;
67
+ // Keep the accepted DOM value cached while a native picker is open. An
68
+ // optimistic rollback changes the prop but leaves the focused control alone;
69
+ // clearing this cache would replay that rejected edit on blur.
70
+ if (!isFocused) {
71
+ lastCommitRef.current = null;
72
+ }
73
+ if (rejectedValue !== null) {
74
+ setRejectedValue(null);
75
+ }
76
+ }
77
+ const nativeValue = value && ISO_DATE.test(value) ? value : '';
78
+ const isInputValid = rejectedValue === null;
79
+ const overlayText = nativeValue ? formatSharedDate(plainDateFromISO(nativeValue), 'date_long', locale) : placeholder;
80
+ const showsOverlay = !!overlayText && !(isFocused && isSegmentEditable);
81
+ const commitValue = useCallback(newValue => {
82
+ if (isEffectivelyDisabled) {
83
+ return;
84
+ }
85
+ if (lastCommitRef.current === newValue) {
86
+ return;
87
+ }
88
+ if (!newValue) {
89
+ lastCommitRef.current = newValue;
90
+ setRejectedValue(null);
91
+ if (value !== undefined) {
92
+ onChange(undefined);
93
+ }
94
+ return;
95
+ }
96
+ const parsed = parseDateInput(newValue, locale);
97
+ if (!parsed) {
98
+ return;
99
+ }
100
+ if (isDateDisabled(parsed)) {
101
+ setRejectedValue(newValue);
102
+ return;
103
+ }
104
+ setRejectedValue(null);
105
+ lastCommitRef.current = newValue;
106
+ const parsedISO = plainDateToISO(parsed);
107
+ if (parsedISO !== value) {
108
+ onChange(parsedISO);
109
+ }
110
+ }, [isDateDisabled, isEffectivelyDisabled, locale, onChange, value]);
111
+ const handleChange = useCallback(event => {
112
+ commitValue(event.target.value);
113
+ }, [commitValue]);
114
+
115
+ // React's synthetic change system does not reliably observe iOS picker edits.
116
+ const commitRef = useRef(commitValue);
117
+ useEffect(() => {
118
+ commitRef.current = commitValue;
119
+ });
120
+ useEffect(() => {
121
+ const input = internalInputRef.current;
122
+ if (!input) {
123
+ return;
124
+ }
125
+ const handleNative = () => commitRef.current(input.value);
126
+ input.addEventListener('input', handleNative);
127
+ input.addEventListener('change', handleNative);
128
+ return () => {
129
+ input.removeEventListener('input', handleNative);
130
+ input.removeEventListener('change', handleNative);
131
+ };
132
+ }, []);
133
+
134
+ // React touches defaultValue after mount when the prop changes, so capture it
135
+ // once. The effect below owns every later write and skips focused controls.
136
+ const initialValueRef = useRef(null);
137
+ if (initialValueRef.current === null) {
138
+ initialValueRef.current = nativeValue;
139
+ }
140
+ useEffect(() => {
141
+ if (isFocused) {
142
+ return;
143
+ }
144
+ const input = internalInputRef.current;
145
+ if (input && input.value !== nativeValue) {
146
+ input.value = nativeValue;
147
+ }
148
+ }, [isFocused, nativeValue]);
149
+ const handleFocus = useCallback(() => {
150
+ valueAtFocusRef.current = nativeValue;
151
+ setIsSegmentEditable(hasEditableDateSegments(isTouchPointer));
152
+ setIsFocused(true);
153
+ }, [isTouchPointer, nativeValue]);
154
+ const handleBlur = useCallback(() => {
155
+ const domValue = internalInputRef.current?.value;
156
+ const valueChangedWhileFocused = valueAtFocusRef.current !== null && valueAtFocusRef.current !== nativeValue;
157
+ const wasRejected = rejectedValue !== null;
158
+ valueAtFocusRef.current = null;
159
+ setIsFocused(false);
160
+ setRejectedValue(null);
161
+ if (!valueChangedWhileFocused && !wasRejected && domValue !== undefined && domValue !== nativeValue) {
162
+ commitValue(domValue);
163
+ }
164
+ lastCommitRef.current = null;
165
+ }, [commitValue, nativeValue, rejectedValue]);
166
+ const openPicker = useCallback(() => {
167
+ if (isEffectivelyDisabled) {
168
+ return;
169
+ }
170
+ const input = internalInputRef.current;
171
+ if (!input) {
172
+ return;
173
+ }
174
+ input.focus();
175
+ if (typeof input.showPicker === 'function') {
176
+ try {
177
+ input.showPicker();
178
+ } catch {
179
+ // Focus is the fallback when showPicker needs user activation or the
180
+ // browser does not expose it for date controls.
181
+ }
182
+ }
183
+ }, [isEffectivelyDisabled]);
184
+ return /*#__PURE__*/_jsxs(_Fragment, {
185
+ children: [/*#__PURE__*/_jsx("button", {
186
+ type: "button",
187
+ onClick: openPicker,
188
+ disabled: isEffectivelyDisabled,
189
+ "aria-label": t('@astryx.dateInput.openCalendar'),
190
+ tabIndex: -1,
191
+ ...stylex.props(focusOutlineStyles.focusVisible, styles.iconButton, isEffectivelyDisabled && styles.iconButtonDisabled),
192
+ children: /*#__PURE__*/_jsx(Icon, {
193
+ icon: "calendar",
194
+ size: "sm",
195
+ color: "secondary",
196
+ ...themeProps('date-time-input-toggle-icon', {
197
+ state: 'collapsed'
198
+ })
199
+ })
200
+ }), /*#__PURE__*/_jsxs("span", {
201
+ ...stylex.props(styles.slot),
202
+ children: [/*#__PURE__*/_jsx("input", {
203
+ ref: mergedInputRef,
204
+ id: id,
205
+ type: "date"
206
+ // UNCONTROLLED on purpose; see initialValueRef and the sync effect.
207
+ ,
208
+ defaultValue: initialValueRef.current ?? '',
209
+ onChange: handleChange,
210
+ onFocus: handleFocus,
211
+ onBlur: handleBlur,
212
+ min: min,
213
+ max: max,
214
+ disabled: isEffectivelyDisabled && !hasDisabledMessage,
215
+ "aria-disabled": hasDisabledMessage ? 'true' : undefined,
216
+ readOnly: hasDisabledMessage || undefined,
217
+ "aria-describedby": ariaDescribedBy,
218
+ "aria-required": isEffectivelyRequired ? 'true' : undefined,
219
+ "aria-invalid": statusType === 'error' || !isInputValid ? 'true' : undefined,
220
+ "aria-busy": isBusy || undefined,
221
+ ...stylex.props(styles.input, showsOverlay && styles.inputTextHidden, isEffectivelyDisabled && styles.inputDisabled, !isInputValid && styles.inputInvalid)
222
+ }), showsOverlay && /*#__PURE__*/_jsx("span", {
223
+ "aria-hidden": "true",
224
+ ...stylex.props(styles.overlay, nativeValue ? styles.overlayValue : styles.overlayPlaceholder, isEffectivelyDisabled && styles.inputDisabled, !isInputValid && !!nativeValue && styles.inputInvalid),
225
+ children: overlayText
226
+ })]
227
+ }), /*#__PURE__*/_jsx(VisuallyHidden, {
228
+ as: "div",
229
+ role: "alert",
230
+ "aria-live": "assertive",
231
+ children: !isInputValid ? t('@astryx.dateInput.invalidDate') : ''
232
+ })]
233
+ });
234
+ }
235
+ NativeDateSegment.displayName = 'NativeDateSegment';
@@ -0,0 +1,30 @@
1
+ import type { InputStatusType } from '../Field';
2
+ import type { ThemeProps } from '../utils/themeProps';
3
+ import { type ISOTimeString } from '../utils';
4
+ export type NativeTimeSegmentProps = {
5
+ id: string;
6
+ inputRef: React.Ref<HTMLInputElement>;
7
+ value?: ISOTimeString;
8
+ onChange: (value: ISOTimeString | undefined) => void;
9
+ placeholder: string;
10
+ inputLabel?: string;
11
+ openPickerLabel: string;
12
+ ariaLabelledBy?: string;
13
+ iconThemeProps?: ThemeProps;
14
+ hasAutoFocus?: boolean;
15
+ min?: ISOTimeString;
16
+ max?: ISOTimeString;
17
+ hourFormat: '12h' | '24h';
18
+ isEffectivelyDisabled: boolean;
19
+ hasDisabledMessage: boolean;
20
+ isEffectivelyRequired: boolean;
21
+ isBusy: boolean;
22
+ statusType?: InputStatusType;
23
+ ariaDescribedBy?: string;
24
+ };
25
+ /** The shared native time control rendered inside Astryx field chrome. */
26
+ export declare function NativeTimeSegment({ id, inputRef, value, onChange, placeholder, inputLabel, openPickerLabel, ariaLabelledBy, iconThemeProps, hasAutoFocus, min, max, hourFormat, isEffectivelyDisabled, hasDisabledMessage, isEffectivelyRequired, isBusy, statusType, ariaDescribedBy, }: NativeTimeSegmentProps): import("react").JSX.Element;
27
+ export declare namespace NativeTimeSegment {
28
+ var displayName: string;
29
+ }
30
+ //# sourceMappingURL=NativeTimeSegment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeTimeSegment.d.ts","sourceRoot":"","sources":["../../src/DateTimeInput/NativeTimeSegment.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,UAAU,CAAC;AAK9C,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAOL,KAAK,aAAa,EACnB,MAAM,UAAU,CAAC;AAmBlB,MAAM,MAAM,sBAAsB,GAAG;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACtC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,GAAG,SAAS,KAAK,IAAI,CAAC;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,UAAU,CAAC;IAC5B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,GAAG,CAAC,EAAE,aAAa,CAAC;IACpB,GAAG,CAAC,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,KAAK,GAAG,KAAK,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,EAChC,EAAE,EACF,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,WAAW,EACX,UAAU,EACV,eAAe,EACf,cAAc,EACd,cAAc,EACd,YAAoB,EACpB,GAAG,EACH,GAAG,EACH,UAAU,EACV,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,EACrB,MAAM,EACN,UAAU,EACV,eAAe,GAChB,EAAE,sBAAsB,+BA+NxB;yBAnPe,iBAAiB"}
@@ -0,0 +1,248 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file NativeTimeSegment.tsx
7
+ * @input Uses React, native picker segment styles, and shared time utilities
8
+ * @output Exports NativeTimeSegment — the shared OS-picker time control
9
+ * @position Internal native control used by DateTimeInput and TimeInput
10
+ *
11
+ * Hands time picking to the platform through `<input type="time">`. The input
12
+ * is deliberately uncontrolled and observed through native event listeners,
13
+ * matching NativeDateSegment's iOS-safe value ownership: external values only
14
+ * reconcile while the picker is unfocused, and native edits do not depend on
15
+ * React's synthetic change event.
16
+ *
17
+ * SYNC: When modified, update these files to stay in sync:
18
+ * - /packages/core/src/DateTimeInput/DateTimeInput.tsx (DateTimeInput integration)
19
+ * - /packages/core/src/TimeInput/TimeInput.tsx (TimeInput integration)
20
+ * - /packages/core/src/DateTimeInput/NativePickerSegments.test.tsx (DateTimeInput tests)
21
+ * - /packages/core/src/TimeInput/NativeTimeInput.test.tsx (TimeInput tests)
22
+ * - /packages/core/src/DateTimeInput/DateTimeInput.doc.mjs (DateTimeInput prop docs)
23
+ * - /packages/core/src/TimeInput/TimeInput.doc.mjs (TimeInput prop docs)
24
+ */
25
+ import { useCallback, useEffect, useRef, useState } from 'react';
26
+ import * as stylex from '@stylexjs/stylex';
27
+ import { hasEditableDateSegments } from "../DateInput/nativeDateSegments.js";
28
+ import { useMediaQuery } from "../hooks/useMediaQuery.js";
29
+ import { useMergedRefs } from "../hooks/useMergedRefs.js";
30
+ import { Icon } from "../Icon/index.js";
31
+ import { useTranslator } from "../i18n/index.js";
32
+ import { VisuallyHidden } from "../VisuallyHidden/index.js";
33
+ import { focusOutlineStyles, formatDisplayTime12h, formatDisplayTime24h, formatISOTime, isTimeInRange, parseISOTime } from "../utils/index.js";
34
+ import { nativePickerSegmentStyles as styles } from "./nativePickerSegmentStyles.js";
35
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
36
+ const FRACTIONAL_SECONDS = /\.\d+$/;
37
+ function normalizeNativeTime(value) {
38
+ if (!value) {
39
+ return undefined;
40
+ }
41
+ const withoutFraction = value.replace(FRACTIONAL_SECONDS, '');
42
+ const parsed = parseISOTime(withoutFraction);
43
+ return parsed ? formatISOTime(parsed, false) : undefined;
44
+ }
45
+ /** The shared native time control rendered inside Astryx field chrome. */
46
+ export function NativeTimeSegment({
47
+ id,
48
+ inputRef,
49
+ value,
50
+ onChange,
51
+ placeholder,
52
+ inputLabel,
53
+ openPickerLabel,
54
+ ariaLabelledBy,
55
+ iconThemeProps,
56
+ hasAutoFocus = false,
57
+ min,
58
+ max,
59
+ hourFormat,
60
+ isEffectivelyDisabled,
61
+ hasDisabledMessage,
62
+ isEffectivelyRequired,
63
+ isBusy,
64
+ statusType,
65
+ ariaDescribedBy
66
+ }) {
67
+ const t = useTranslator();
68
+ const isTouchPointer = useMediaQuery('(pointer: coarse)');
69
+ const internalInputRef = useRef(null);
70
+ const mergedInputRef = useMergedRefs(inputRef, internalInputRef);
71
+ const [rejectedValue, setRejectedValue] = useState(null);
72
+ const [isFocused, setIsFocused] = useState(false);
73
+ const [isSegmentEditable, setIsSegmentEditable] = useState(false);
74
+ const valueAtFocusRef = useRef(null);
75
+ const lastCommitRef = useRef(null);
76
+ const prevValueRef = useRef(value);
77
+ if (value !== prevValueRef.current) {
78
+ prevValueRef.current = value;
79
+ // Preserve the accepted DOM value while the OS wheel is open so an
80
+ // optimistic rollback cannot replay that edit when the field blurs.
81
+ if (!isFocused) {
82
+ lastCommitRef.current = null;
83
+ }
84
+ if (rejectedValue !== null) {
85
+ setRejectedValue(null);
86
+ }
87
+ }
88
+ const nativeValue = normalizeNativeTime(value) ?? '';
89
+ const isInputValid = rejectedValue === null;
90
+ const formatDisplayTime = hourFormat === '12h' ? formatDisplayTime12h : formatDisplayTime24h;
91
+ const overlayText = nativeValue ? formatDisplayTime(nativeValue, false) : placeholder;
92
+ const showsOverlay = !!overlayText && !(isFocused && isSegmentEditable);
93
+ const commitValue = useCallback(newValue => {
94
+ if (isEffectivelyDisabled || lastCommitRef.current === newValue) {
95
+ return;
96
+ }
97
+ if (!newValue) {
98
+ lastCommitRef.current = newValue;
99
+ setRejectedValue(null);
100
+ if (value !== undefined) {
101
+ onChange(undefined);
102
+ }
103
+ return;
104
+ }
105
+ const normalized = normalizeNativeTime(newValue);
106
+ if (!normalized) {
107
+ return;
108
+ }
109
+ if (!isTimeInRange(normalized, min, max)) {
110
+ setRejectedValue(newValue);
111
+ return;
112
+ }
113
+ setRejectedValue(null);
114
+ lastCommitRef.current = newValue;
115
+ if (normalized !== value) {
116
+ onChange(normalized);
117
+ }
118
+ }, [isEffectivelyDisabled, max, min, onChange, value]);
119
+ const handleChange = useCallback(event => {
120
+ commitValue(event.target.value);
121
+ }, [commitValue]);
122
+
123
+ // React's synthetic change system does not reliably observe iOS picker edits.
124
+ const commitRef = useRef(commitValue);
125
+ useEffect(() => {
126
+ commitRef.current = commitValue;
127
+ });
128
+ useEffect(() => {
129
+ const input = internalInputRef.current;
130
+ if (!input) {
131
+ return;
132
+ }
133
+ const handleNative = () => commitRef.current(input.value);
134
+ input.addEventListener('input', handleNative);
135
+ input.addEventListener('change', handleNative);
136
+ return () => {
137
+ input.removeEventListener('input', handleNative);
138
+ input.removeEventListener('change', handleNative);
139
+ };
140
+ }, []);
141
+
142
+ // React touches defaultValue after mount when the prop changes. Capture it
143
+ // once, then reconcile through the unfocused-only effect below.
144
+ const initialValueRef = useRef(null);
145
+ if (initialValueRef.current === null) {
146
+ initialValueRef.current = nativeValue;
147
+ }
148
+ useEffect(() => {
149
+ if (isFocused) {
150
+ return;
151
+ }
152
+ const input = internalInputRef.current;
153
+ if (input && input.value !== nativeValue) {
154
+ input.value = nativeValue;
155
+ }
156
+ }, [isFocused, nativeValue]);
157
+ const handleFocus = useCallback(() => {
158
+ valueAtFocusRef.current = nativeValue;
159
+ // The engine probe classifies whether WebKit/Blink exposes editable native
160
+ // segments. Date and time controls share that engine-level behavior.
161
+ setIsSegmentEditable(hasEditableDateSegments(isTouchPointer));
162
+ setIsFocused(true);
163
+ }, [isTouchPointer, nativeValue]);
164
+ const handleBlur = useCallback(() => {
165
+ const domValue = internalInputRef.current?.value;
166
+ const valueChangedWhileFocused = valueAtFocusRef.current !== null && valueAtFocusRef.current !== nativeValue;
167
+ const wasRejected = rejectedValue !== null;
168
+ valueAtFocusRef.current = null;
169
+ setIsFocused(false);
170
+ setRejectedValue(null);
171
+ if (!valueChangedWhileFocused && !wasRejected && domValue !== undefined && domValue !== nativeValue) {
172
+ commitValue(domValue);
173
+ }
174
+ lastCommitRef.current = null;
175
+ }, [commitValue, nativeValue, rejectedValue]);
176
+ const openPicker = useCallback(() => {
177
+ if (isEffectivelyDisabled) {
178
+ return;
179
+ }
180
+ const input = internalInputRef.current;
181
+ if (!input) {
182
+ return;
183
+ }
184
+ input.focus();
185
+ if (typeof input.showPicker === 'function') {
186
+ try {
187
+ input.showPicker();
188
+ } catch {
189
+ // Focus raises the iOS picker and is the fallback when showPicker needs
190
+ // user activation or is unavailable.
191
+ }
192
+ }
193
+ }, [isEffectivelyDisabled]);
194
+ return /*#__PURE__*/_jsxs(_Fragment, {
195
+ children: [/*#__PURE__*/_jsx("button", {
196
+ type: "button",
197
+ onClick: openPicker,
198
+ disabled: isEffectivelyDisabled,
199
+ "aria-label": openPickerLabel,
200
+ tabIndex: -1,
201
+ ...stylex.props(focusOutlineStyles.focusVisible, styles.iconButton, isEffectivelyDisabled && styles.iconButtonDisabled),
202
+ children: /*#__PURE__*/_jsx(Icon, {
203
+ icon: "clock",
204
+ size: "sm",
205
+ color: "secondary",
206
+ ...iconThemeProps
207
+ })
208
+ }), /*#__PURE__*/_jsxs("span", {
209
+ ...stylex.props(styles.slot),
210
+ children: [/*#__PURE__*/_jsx("input", {
211
+ ref: mergedInputRef,
212
+ id: id,
213
+ type: "time"
214
+ // UNCONTROLLED on purpose; see initialValueRef and the sync effect.
215
+ ,
216
+ defaultValue: initialValueRef.current ?? '',
217
+ onChange: handleChange,
218
+ onFocus: handleFocus,
219
+ onBlur: handleBlur,
220
+ min: min,
221
+ max: max,
222
+ step: 60,
223
+ disabled: isEffectivelyDisabled && !hasDisabledMessage,
224
+ "aria-disabled": hasDisabledMessage ? 'true' : undefined,
225
+ readOnly: hasDisabledMessage || undefined,
226
+ "aria-label": ariaLabelledBy ? undefined : inputLabel,
227
+ "aria-labelledby": ariaLabelledBy,
228
+ "aria-describedby": ariaDescribedBy,
229
+ autoFocus: hasAutoFocus,
230
+ "data-autofocus": hasAutoFocus || undefined,
231
+ "aria-required": isEffectivelyRequired ? 'true' : undefined,
232
+ "aria-invalid": statusType === 'error' || !isInputValid ? 'true' : undefined,
233
+ "aria-busy": isBusy || undefined,
234
+ ...stylex.props(styles.input, showsOverlay && styles.inputTextHidden, isEffectivelyDisabled && styles.inputDisabled, !isInputValid && styles.inputInvalid)
235
+ }), showsOverlay && /*#__PURE__*/_jsx("span", {
236
+ "aria-hidden": "true",
237
+ ...stylex.props(styles.overlay, nativeValue ? styles.overlayValue : styles.overlayPlaceholder, isEffectivelyDisabled && styles.inputDisabled, !isInputValid && !!nativeValue && styles.inputInvalid),
238
+ children: overlayText
239
+ })]
240
+ }), /*#__PURE__*/_jsx(VisuallyHidden, {
241
+ as: "div",
242
+ role: "alert",
243
+ "aria-live": "assertive",
244
+ children: !isInputValid ? t('@astryx.timeInput.invalidTime') : ''
245
+ })]
246
+ });
247
+ }
248
+ NativeTimeSegment.displayName = 'NativeTimeSegment';
@@ -5,5 +5,5 @@
5
5
  * @position Package entry point for DateTimeInput
6
6
  */
7
7
  export { DateTimeInput } from './DateTimeInput';
8
- export type { DateTimeInputProps, DateTimeInputSize, DateTimeInputHourFormat, DateTimeInputTimeIncrement, DateTimeInputTimeOptionInterval, DateTimeInputStatus, DateTimeInputStatusType, ISODateTimeString, } from './DateTimeInput';
8
+ export type { DateTimeInputProps, DateTimeInputSize, DateTimeInputHourFormat, DateTimeInputNativePicker, DateTimeInputTimeIncrement, DateTimeInputTimeOptionInterval, DateTimeInputStatus, DateTimeInputStatusType, ISODateTimeString, } from './DateTimeInput';
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/DateTimeInput/index.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAC9C,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACvB,0BAA0B,EAC1B,+BAA+B,EAC/B,mBAAmB,EACnB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/DateTimeInput/index.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAC9C,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACvB,yBAAyB,EACzB,0BAA0B,EAC1B,+BAA+B,EAC/B,mBAAmB,EACnB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * @file nativePickerSegmentStyles.ts
3
+ * @input Uses StyleX and Astryx typography, color, and radius tokens
4
+ * @output Exports styles shared by DateTimeInput's native date and time controls
5
+ * @position Internal styling shared by NativeDateSegment and NativeTimeSegment
6
+ */
7
+ import * as stylex from '@stylexjs/stylex';
8
+ export declare const nativePickerSegmentStyles: Readonly<{
9
+ readonly iconButton: Readonly<{
10
+ readonly display: stylex.StyleXClassNameFor<"display", "flex">;
11
+ readonly alignItems: stylex.StyleXClassNameFor<"alignItems", "center">;
12
+ readonly justifyContent: stylex.StyleXClassNameFor<"justifyContent", "center">;
13
+ readonly padding: stylex.StyleXClassNameFor<"padding", 0>;
14
+ readonly margin: stylex.StyleXClassNameFor<"margin", 0>;
15
+ readonly borderWidth: stylex.StyleXClassNameFor<"borderWidth", 0>;
16
+ readonly borderStyle: stylex.StyleXClassNameFor<"borderStyle", "none">;
17
+ readonly backgroundColor: stylex.StyleXClassNameFor<"backgroundColor", "transparent">;
18
+ readonly cursor: stylex.StyleXClassNameFor<"cursor", "default" | "pointer">;
19
+ readonly borderRadius: stylex.StyleXClassNameFor<"borderRadius", "8px">;
20
+ }>;
21
+ readonly iconButtonDisabled: Readonly<{
22
+ readonly cursor: stylex.StyleXClassNameFor<"cursor", "default">;
23
+ }>;
24
+ readonly input: Readonly<{
25
+ readonly display: stylex.StyleXClassNameFor<"display", "block">;
26
+ readonly flex: stylex.StyleXClassNameFor<"flex", 1>;
27
+ readonly minWidth: stylex.StyleXClassNameFor<"minWidth", 0>;
28
+ readonly borderWidth: stylex.StyleXClassNameFor<"borderWidth", 0>;
29
+ readonly borderStyle: stylex.StyleXClassNameFor<"borderStyle", "none">;
30
+ readonly padding: stylex.StyleXClassNameFor<"padding", 0>;
31
+ readonly fontFamily: stylex.StyleXClassNameFor<"fontFamily", "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif">;
32
+ readonly fontSize: stylex.StyleXClassNameFor<"fontSize", "var(--font-size-base)" | `max(1rem, ${stylex.StyleXVar<"var(--font-size-base)">})`>;
33
+ readonly lineHeight: stylex.StyleXClassNameFor<"lineHeight", "1.4286">;
34
+ readonly color: stylex.StyleXClassNameFor<"color", "light-dark(#0A1317, #DFE2E5)">;
35
+ readonly backgroundColor: stylex.StyleXClassNameFor<"backgroundColor", "transparent">;
36
+ readonly outline: stylex.StyleXClassNameFor<"outline", "none">;
37
+ readonly height: stylex.StyleXClassNameFor<"height", "1lh" | `calc(max(1rem, ${stylex.StyleXVar<"var(--font-size-base)">}) * ${stylex.StyleXVar<"1.4286">})`>;
38
+ readonly WebkitAppearance: stylex.StyleXClassNameFor<"WebkitAppearance", "none">;
39
+ readonly appearance: stylex.StyleXClassNameFor<"appearance", "none">;
40
+ readonly '::-webkit-calendar-picker-indicator': stylex.StyleXClassNameFor<"::-webkit-calendar-picker-indicator", {
41
+ readonly display: "none";
42
+ }>;
43
+ readonly '::-webkit-date-and-time-value': stylex.StyleXClassNameFor<"::-webkit-date-and-time-value", {
44
+ readonly textAlign: "start";
45
+ readonly marginBlock: 0;
46
+ readonly marginInline: 0;
47
+ readonly paddingBlock: 0;
48
+ readonly paddingInline: 0;
49
+ readonly lineHeight: "inherit";
50
+ readonly minHeight: 0;
51
+ }>;
52
+ readonly '::-webkit-datetime-edit': stylex.StyleXClassNameFor<"::-webkit-datetime-edit", {
53
+ readonly paddingBlock: 0;
54
+ readonly paddingInline: 0;
55
+ readonly lineHeight: "inherit";
56
+ }>;
57
+ }>;
58
+ readonly inputDisabled: Readonly<{
59
+ readonly cursor: stylex.StyleXClassNameFor<"cursor", "default">;
60
+ }>;
61
+ readonly inputInvalid: Readonly<{
62
+ readonly color: stylex.StyleXClassNameFor<"color", "light-dark(#4E606F, #AAAFB5)">;
63
+ }>;
64
+ readonly inputTextHidden: Readonly<{
65
+ readonly color: stylex.StyleXClassNameFor<"color", "transparent">;
66
+ readonly WebkitTextFillColor: stylex.StyleXClassNameFor<"WebkitTextFillColor", "transparent">;
67
+ }>;
68
+ readonly slot: Readonly<{
69
+ readonly position: stylex.StyleXClassNameFor<"position", "relative">;
70
+ readonly display: stylex.StyleXClassNameFor<"display", "flex">;
71
+ readonly alignItems: stylex.StyleXClassNameFor<"alignItems", "center">;
72
+ readonly flex: stylex.StyleXClassNameFor<"flex", 1>;
73
+ readonly minInlineSize: stylex.StyleXClassNameFor<"minInlineSize", 0>;
74
+ }>;
75
+ readonly overlay: Readonly<{
76
+ readonly position: stylex.StyleXClassNameFor<"position", "absolute">;
77
+ readonly insetInlineStart: stylex.StyleXClassNameFor<"insetInlineStart", 0>;
78
+ readonly insetInlineEnd: stylex.StyleXClassNameFor<"insetInlineEnd", 0>;
79
+ readonly insetBlock: stylex.StyleXClassNameFor<"insetBlock", 0>;
80
+ readonly display: stylex.StyleXClassNameFor<"display", "block">;
81
+ readonly fontSize: stylex.StyleXClassNameFor<"fontSize", "var(--font-size-base)" | `max(1rem, ${stylex.StyleXVar<"var(--font-size-base)">})`>;
82
+ readonly lineHeight: stylex.StyleXClassNameFor<"lineHeight", "1.4286">;
83
+ readonly pointerEvents: stylex.StyleXClassNameFor<"pointerEvents", "none">;
84
+ readonly overflow: stylex.StyleXClassNameFor<"overflow", "hidden">;
85
+ readonly whiteSpace: stylex.StyleXClassNameFor<"whiteSpace", "nowrap">;
86
+ readonly textOverflow: stylex.StyleXClassNameFor<"textOverflow", "ellipsis">;
87
+ }>;
88
+ readonly overlayValue: Readonly<{
89
+ readonly color: stylex.StyleXClassNameFor<"color", "light-dark(#0A1317, #DFE2E5)">;
90
+ }>;
91
+ readonly overlayPlaceholder: Readonly<{
92
+ readonly color: stylex.StyleXClassNameFor<"color", "light-dark(#4E606F, #AAAFB5)">;
93
+ }>;
94
+ }>;
95
+ //# sourceMappingURL=nativePickerSegmentStyles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nativePickerSegmentStyles.d.ts","sourceRoot":"","sources":["../../src/DateTimeInput/nativePickerSegmentStyles.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAQ3C,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsGpC,CAAC"}