@astryxdesign/core 0.6.2 → 0.6.3-canary.039a67e

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 (621) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/dist/Avatar/Avatar.d.ts.map +1 -1
  3. package/dist/Avatar/Avatar.js +33 -12
  4. package/dist/BottomSheet/BottomSheet.d.ts +1 -1
  5. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  6. package/dist/BottomSheet/BottomSheet.js +3 -1
  7. package/dist/BottomSheet/BottomSheetPanel.d.ts +7 -5
  8. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  9. package/dist/BottomSheet/BottomSheetPanel.js +56 -19
  10. package/dist/Button/Button.d.ts.map +1 -1
  11. package/dist/Button/Button.js +13 -28
  12. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  13. package/dist/Chat/ChatComposer.js +10 -5
  14. package/dist/Chat/ChatComposerDrawer.d.ts +19 -5
  15. package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
  16. package/dist/Chat/ChatComposerDrawer.js +48 -23
  17. package/dist/Chat/ChatComposerInput.d.ts +11 -3
  18. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  19. package/dist/Chat/ChatComposerInput.js +63 -16
  20. package/dist/Chat/ChatDictationButton.d.ts +3 -2
  21. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  22. package/dist/Chat/ChatDictationButton.js +6 -4
  23. package/dist/Chat/ChatLayout.d.ts +19 -0
  24. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  25. package/dist/Chat/ChatLayout.js +19 -0
  26. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  27. package/dist/Chat/ChatLayoutScrollButton.js +44 -34
  28. package/dist/Chat/ChatMessageBubble.d.ts +2 -0
  29. package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
  30. package/dist/Chat/ChatMessageBubble.js +5 -3
  31. package/dist/Chat/ChatMessageList.d.ts +2 -1
  32. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  33. package/dist/Chat/ChatMessageList.js +4 -3
  34. package/dist/Chat/ChatMessageMetadata.d.ts +5 -4
  35. package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
  36. package/dist/Chat/ChatMessageMetadata.js +12 -9
  37. package/dist/Chat/ChatSendButton.d.ts +2 -1
  38. package/dist/Chat/ChatSendButton.d.ts.map +1 -1
  39. package/dist/Chat/ChatSendButton.js +6 -4
  40. package/dist/Chat/ChatSystemMessage.d.ts +3 -3
  41. package/dist/Chat/ChatSystemMessage.d.ts.map +1 -1
  42. package/dist/Chat/ChatSystemMessage.js +2 -2
  43. package/dist/Chat/ChatTokenizedText.d.ts +6 -6
  44. package/dist/Chat/ChatTokenizedText.js +10 -6
  45. package/dist/Chat/ChatToolCalls.d.ts +7 -9
  46. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  47. package/dist/Chat/ChatToolCalls.js +43 -26
  48. package/dist/Chat/index.d.ts +1 -1
  49. package/dist/Chat/index.d.ts.map +1 -1
  50. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  51. package/dist/CheckboxInput/CheckboxInput.js +12 -2
  52. package/dist/Citation/Citation.d.ts +1 -1
  53. package/dist/Citation/Citation.d.ts.map +1 -1
  54. package/dist/Citation/Citation.js +3 -2
  55. package/dist/CodeBlock/highlightRanges.d.ts.map +1 -1
  56. package/dist/CodeBlock/highlightRanges.js +14 -3
  57. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  58. package/dist/Collapsible/Collapsible.js +6 -1
  59. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  60. package/dist/CommandPalette/CommandPaletteInput.js +1 -1
  61. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  62. package/dist/ComplexSelector/ComplexSelector.js +1 -1
  63. package/dist/DateInput/DateInput.d.ts +25 -5
  64. package/dist/DateInput/DateInput.d.ts.map +1 -1
  65. package/dist/DateInput/DateInput.js +29 -17
  66. package/dist/DateInput/NativeDateField.d.ts.map +1 -1
  67. package/dist/DateInput/NativeDateField.js +16 -16
  68. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  69. package/dist/DateInput/TouchDateField.js +2 -2
  70. package/dist/DateInput/index.d.ts +1 -1
  71. package/dist/DateInput/index.d.ts.map +1 -1
  72. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  73. package/dist/DateRangeInput/DateRangeInput.js +4 -4
  74. package/dist/DateTimeInput/DateTimeInput.d.ts +32 -15
  75. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  76. package/dist/DateTimeInput/DateTimeInput.js +55 -30
  77. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  78. package/dist/DateTimeInput/TouchDateTimeField.js +4 -4
  79. package/dist/DateTimeInput/index.d.ts +1 -1
  80. package/dist/DateTimeInput/index.d.ts.map +1 -1
  81. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts +9 -3
  82. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts.map +1 -1
  83. package/dist/DateTimeInput/nativePickerSegmentStyles.js +3 -3
  84. package/dist/Dialog/DialogHeader.d.ts +8 -1
  85. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  86. package/dist/Dialog/DialogHeader.js +13 -4
  87. package/dist/Field/InputClearButton.d.ts +4 -2
  88. package/dist/Field/InputClearButton.d.ts.map +1 -1
  89. package/dist/Field/InputClearButton.js +4 -2
  90. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  91. package/dist/Field/PanelSearchInput.js +1 -1
  92. package/dist/FileInput/FileInput.d.ts.map +1 -1
  93. package/dist/FileInput/FileInput.js +7 -7
  94. package/dist/Icon/Icon.d.ts +6 -31
  95. package/dist/Icon/Icon.d.ts.map +1 -1
  96. package/dist/Icon/Icon.js +8 -71
  97. package/dist/Icon/IconDefaultSizeContext.d.ts +4 -0
  98. package/dist/Icon/IconDefaultSizeContext.d.ts.map +1 -0
  99. package/dist/Icon/IconDefaultSizeContext.js +18 -0
  100. package/dist/Icon/IconSize.stylex.d.ts +65 -0
  101. package/dist/Icon/IconSize.stylex.d.ts.map +1 -0
  102. package/dist/Icon/IconSize.stylex.js +75 -0
  103. package/dist/Item/Item.d.ts +1 -1
  104. package/dist/Item/Item.d.ts.map +1 -1
  105. package/dist/Item/Item.js +4 -3
  106. package/dist/Kbd/Kbd.d.ts +5 -3
  107. package/dist/Kbd/Kbd.d.ts.map +1 -1
  108. package/dist/Kbd/Kbd.js +36 -42
  109. package/dist/Link/Link.d.ts.map +1 -1
  110. package/dist/Link/Link.js +6 -2
  111. package/dist/Link/useLinkComponent.d.ts +5 -15
  112. package/dist/Link/useLinkComponent.d.ts.map +1 -1
  113. package/dist/Link/useLinkComponent.js +34 -51
  114. package/dist/List/List.d.ts +19 -1
  115. package/dist/List/List.d.ts.map +1 -1
  116. package/dist/List/List.js +9 -2
  117. package/dist/List/ListContext.d.ts +1 -0
  118. package/dist/List/ListContext.d.ts.map +1 -1
  119. package/dist/List/ListContext.js +2 -1
  120. package/dist/List/ListItem.d.ts +1 -1
  121. package/dist/List/ListItem.d.ts.map +1 -1
  122. package/dist/List/ListItem.js +9 -2
  123. package/dist/Markdown/Markdown.d.ts +8 -2
  124. package/dist/Markdown/Markdown.d.ts.map +1 -1
  125. package/dist/Markdown/Markdown.fr23.bench.d.ts +2 -0
  126. package/dist/Markdown/Markdown.fr23.bench.d.ts.map +1 -0
  127. package/dist/Markdown/Markdown.fr23.bench.js +150 -0
  128. package/dist/Markdown/Markdown.fr23.sampling.d.ts +2 -0
  129. package/dist/Markdown/Markdown.fr23.sampling.d.ts.map +1 -0
  130. package/dist/Markdown/Markdown.fr23.sampling.js +43 -0
  131. package/dist/Markdown/Markdown.js +262 -109
  132. package/dist/Markdown/ast.d.ts +162 -0
  133. package/dist/Markdown/ast.d.ts.map +1 -0
  134. package/dist/Markdown/ast.js +74 -0
  135. package/dist/Markdown/index.d.ts +5 -3
  136. package/dist/Markdown/index.d.ts.map +1 -1
  137. package/dist/Markdown/index.js +3 -2
  138. package/dist/Markdown/parser/index.d.ts +10 -0
  139. package/dist/Markdown/parser/index.d.ts.map +1 -0
  140. package/dist/Markdown/parser/index.js +10 -0
  141. package/dist/Markdown/parser.d.ts +126 -58
  142. package/dist/Markdown/parser.d.ts.map +1 -1
  143. package/dist/Markdown/parser.js +726 -177
  144. package/dist/Markdown/plugins/frontmatter.d.ts +32 -0
  145. package/dist/Markdown/plugins/frontmatter.d.ts.map +1 -0
  146. package/dist/Markdown/plugins/frontmatter.js +132 -0
  147. package/dist/Markdown/plugins/index.d.ts +17 -0
  148. package/dist/Markdown/plugins/index.d.ts.map +1 -0
  149. package/dist/Markdown/plugins/index.js +14 -0
  150. package/dist/Markdown/plugins/protocol.d.ts +191 -0
  151. package/dist/Markdown/plugins/protocol.d.ts.map +1 -0
  152. package/dist/Markdown/plugins/protocol.js +957 -0
  153. package/dist/Markdown/plugins/semanticFence.d.ts +36 -0
  154. package/dist/Markdown/plugins/semanticFence.d.ts.map +1 -0
  155. package/dist/Markdown/plugins/semanticFence.js +213 -0
  156. package/dist/Markdown/plugins/softBreaks.d.ts +3 -0
  157. package/dist/Markdown/plugins/softBreaks.d.ts.map +1 -0
  158. package/dist/Markdown/plugins/softBreaks.js +172 -0
  159. package/dist/Markdown/plugins/sourceDecoration.d.ts +76 -0
  160. package/dist/Markdown/plugins/sourceDecoration.d.ts.map +1 -0
  161. package/dist/Markdown/plugins/sourceDecoration.js +393 -0
  162. package/dist/Markdown/plugins/textTransform.d.ts +30 -0
  163. package/dist/Markdown/plugins/textTransform.d.ts.map +1 -0
  164. package/dist/Markdown/plugins/textTransform.js +374 -0
  165. package/dist/Markdown/remark.d.ts +196 -0
  166. package/dist/Markdown/remark.d.ts.map +1 -0
  167. package/dist/Markdown/remark.js +1062 -0
  168. package/dist/Markdown/url.d.ts +6 -0
  169. package/dist/Markdown/url.d.ts.map +1 -0
  170. package/dist/Markdown/url.js +31 -0
  171. package/dist/Markdown/utils.d.ts +4 -2
  172. package/dist/Markdown/utils.d.ts.map +1 -1
  173. package/dist/Markdown/utils.js +2 -1
  174. package/dist/MetadataList/MetadataList.js +3 -3
  175. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  176. package/dist/NumberInput/NumberInput.js +4 -4
  177. package/dist/Outline/index.d.ts +1 -0
  178. package/dist/Outline/index.d.ts.map +1 -1
  179. package/dist/Outline/parseOutlineFromMarkdown.d.ts +7 -1
  180. package/dist/Outline/parseOutlineFromMarkdown.d.ts.map +1 -1
  181. package/dist/Outline/parseOutlineFromMarkdown.js +14 -8
  182. package/dist/Outline/useOutlineFromMarkdown.d.ts +3 -1
  183. package/dist/Outline/useOutlineFromMarkdown.d.ts.map +1 -1
  184. package/dist/Outline/useOutlineFromMarkdown.js +8 -3
  185. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  186. package/dist/PowerSearch/PowerSearchEditPopover.js +46 -30
  187. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  188. package/dist/PowerSearch/PowerSearchValueEditor.js +5 -0
  189. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  190. package/dist/ProgressBar/ProgressBar.js +36 -31
  191. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  192. package/dist/RadioList/RadioListItem.js +13 -1
  193. package/dist/ScrollableArea/ScrollableArea.d.ts +1 -0
  194. package/dist/ScrollableArea/ScrollableArea.d.ts.map +1 -1
  195. package/dist/ScrollableArea/ScrollableArea.js +1 -0
  196. package/dist/SegmentedControl/SegmentedControl.d.ts +1 -1
  197. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  198. package/dist/SegmentedControl/SegmentedControl.js +1 -0
  199. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  200. package/dist/SegmentedControl/SegmentedControlItem.js +5 -5
  201. package/dist/Selector/Selector.d.ts +9 -7
  202. package/dist/Selector/Selector.d.ts.map +1 -1
  203. package/dist/Selector/Selector.js +16 -7
  204. package/dist/SideNav/SideNav.d.ts +2 -1
  205. package/dist/SideNav/SideNav.d.ts.map +1 -1
  206. package/dist/SideNav/SideNav.js +9 -3
  207. package/dist/Slider/Slider.d.ts.map +1 -1
  208. package/dist/Slider/Slider.js +28 -12
  209. package/dist/Spinner/Spinner.d.ts.map +1 -1
  210. package/dist/Spinner/Spinner.js +23 -7
  211. package/dist/Switch/Switch.d.ts.map +1 -1
  212. package/dist/Switch/Switch.js +11 -0
  213. package/dist/TabList/Tab.d.ts +1 -1
  214. package/dist/TabList/Tab.d.ts.map +1 -1
  215. package/dist/TabList/Tab.js +20 -7
  216. package/dist/Table/Table.d.ts +1 -0
  217. package/dist/Table/Table.d.ts.map +1 -1
  218. package/dist/Table/Table.js +29 -13
  219. package/dist/TextArea/TextArea.d.ts.map +1 -1
  220. package/dist/TextArea/TextArea.js +1 -1
  221. package/dist/TextInput/TextInput.d.ts.map +1 -1
  222. package/dist/TextInput/TextInput.js +2 -2
  223. package/dist/TimeInput/TimeInput.d.ts +30 -14
  224. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  225. package/dist/TimeInput/TimeInput.js +61 -13
  226. package/dist/TimeInput/TouchTimeField.d.ts +11 -0
  227. package/dist/TimeInput/TouchTimeField.d.ts.map +1 -0
  228. package/dist/TimeInput/TouchTimeField.js +417 -0
  229. package/dist/TimeInput/index.d.ts +1 -1
  230. package/dist/TimeInput/index.d.ts.map +1 -1
  231. package/dist/Timer/Timer.d.ts +49 -0
  232. package/dist/Timer/Timer.d.ts.map +1 -0
  233. package/dist/Timer/Timer.js +158 -0
  234. package/dist/Timer/index.d.ts +9 -0
  235. package/dist/Timer/index.d.ts.map +1 -0
  236. package/dist/Timer/index.js +10 -0
  237. package/dist/ToggleButton/ToggleButton.d.ts +9 -6
  238. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  239. package/dist/ToggleButton/ToggleButton.js +15 -27
  240. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  241. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  242. package/dist/TopNav/TopNavMenu.js +3 -2
  243. package/dist/TreeList/TreeList.d.ts.map +1 -1
  244. package/dist/TreeList/TreeList.js +3 -0
  245. package/dist/TreeList/TreeListItem.d.ts +6 -1
  246. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  247. package/dist/TreeList/TreeListItem.js +12 -2
  248. package/dist/TreeList/TreeListTypes.d.ts +8 -1
  249. package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
  250. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  251. package/dist/Typeahead/BaseTypeahead.js +16 -7
  252. package/dist/astryx.css +27 -11
  253. package/dist/hooks/scrollKeyboardDelegation.d.ts +3 -0
  254. package/dist/hooks/scrollKeyboardDelegation.d.ts.map +1 -0
  255. package/dist/hooks/scrollKeyboardDelegation.js +146 -0
  256. package/dist/hooks/useClickableContainer.d.ts +10 -1
  257. package/dist/hooks/useClickableContainer.d.ts.map +1 -1
  258. package/dist/hooks/useClickableContainer.js +15 -4
  259. package/dist/hooks/useScrollableArea.d.ts +6 -2
  260. package/dist/hooks/useScrollableArea.d.ts.map +1 -1
  261. package/dist/hooks/useScrollableArea.js +17 -5
  262. package/dist/index.d.ts +1 -0
  263. package/dist/index.d.ts.map +1 -1
  264. package/dist/index.js +3 -0
  265. package/dist/theme/declarationBoundary.d.ts +17 -0
  266. package/dist/theme/declarationBoundary.d.ts.map +1 -0
  267. package/dist/theme/declarationBoundary.js +343 -0
  268. package/dist/theme/defineTheme.d.ts +3 -0
  269. package/dist/theme/defineTheme.d.ts.map +1 -1
  270. package/dist/theme/defineTheme.js +4 -1
  271. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  272. package/dist/theme/derivedVarRegistry.js +4 -0
  273. package/dist/theme/generateThemeRules.d.ts +15 -7
  274. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  275. package/dist/theme/generateThemeRules.js +143 -35
  276. package/dist/theme/themeAdaptations.d.ts +5 -3
  277. package/dist/theme/themeAdaptations.d.ts.map +1 -1
  278. package/dist/theme/themeAdaptations.js +33 -5
  279. package/dist/utils/inputPresentation.d.ts +55 -0
  280. package/dist/utils/inputPresentation.d.ts.map +1 -0
  281. package/dist/utils/inputPresentation.js +108 -0
  282. package/dist/utils/interactionOverlay.stylex.d.ts +8 -0
  283. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  284. package/dist/utils/interactionOverlay.stylex.js +9 -0
  285. package/dist/utils/safeUrl.d.ts +11 -0
  286. package/dist/utils/safeUrl.d.ts.map +1 -0
  287. package/dist/utils/safeUrl.js +78 -0
  288. package/locales/af-ZA.json +530 -1
  289. package/locales/ar-SA.json +490 -1
  290. package/locales/ca-ES.json +514 -1
  291. package/locales/cs-CZ.json +498 -1
  292. package/locales/da-DK.json +522 -1
  293. package/locales/de-DE.json +522 -1
  294. package/locales/el-GR.json +498 -1
  295. package/locales/es-ES.json +510 -1
  296. package/locales/fi-FI.json +498 -1
  297. package/locales/fr-FR.json +534 -1
  298. package/locales/he-IL.json +498 -1
  299. package/locales/hu-HU.json +498 -1
  300. package/locales/it-IT.json +510 -1
  301. package/locales/ja-JP.json +490 -1
  302. package/locales/ko-KR.json +498 -1
  303. package/locales/nl-NL.json +534 -1
  304. package/locales/no-NO.json +510 -1
  305. package/locales/pl-PL.json +506 -1
  306. package/locales/pt-BR.json +506 -1
  307. package/locales/pt-PT.json +506 -1
  308. package/locales/ro-RO.json +506 -1
  309. package/locales/ru-RU.json +498 -1
  310. package/locales/sr-SP.json +498 -1
  311. package/locales/sv-SE.json +502 -1
  312. package/locales/tr-TR.json +498 -1
  313. package/locales/uk-UA.json +498 -1
  314. package/locales/vi-VN.json +502 -1
  315. package/locales/zh-CN.json +490 -1
  316. package/locales/zh-TW.json +490 -1
  317. package/package.json +24 -4
  318. package/src/Avatar/Avatar.doc.mjs +1 -1
  319. package/src/Avatar/Avatar.test.tsx +30 -0
  320. package/src/Avatar/Avatar.tsx +38 -14
  321. package/src/BottomSheet/BottomSheet.doc.mjs +8 -1
  322. package/src/BottomSheet/BottomSheet.spec.md +46 -20
  323. package/src/BottomSheet/BottomSheet.test.tsx +6 -3
  324. package/src/BottomSheet/BottomSheet.tsx +3 -1
  325. package/src/BottomSheet/BottomSheetKeyboard.test.tsx +195 -0
  326. package/src/BottomSheet/BottomSheetPanel.test.tsx +11 -1
  327. package/src/BottomSheet/BottomSheetPanel.tsx +49 -16
  328. package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +344 -0
  329. package/src/Button/Button.doc.mjs +5 -5
  330. package/src/Button/Button.tsx +15 -13
  331. package/src/Button/__tests__/Button.a11y.chromium.spec.ts +17 -1
  332. package/src/Button/__tests__/Button.a11y.known-failures.ts +0 -29
  333. package/src/Button/__tests__/Button.a11y.renders.tsx +9 -2
  334. package/src/Button/__tests__/Button.a11y.states.ts +9 -0
  335. package/src/Chat/ChatComposer.doc.mjs +14 -0
  336. package/src/Chat/ChatComposer.spec.md +230 -0
  337. package/src/Chat/ChatComposer.test.tsx +57 -0
  338. package/src/Chat/ChatComposer.tsx +21 -9
  339. package/src/Chat/ChatComposerDrawer.doc.mjs +63 -5
  340. package/src/Chat/ChatComposerDrawer.spec.md +267 -0
  341. package/src/Chat/ChatComposerDrawer.test.tsx +81 -12
  342. package/src/Chat/ChatComposerDrawer.tsx +38 -9
  343. package/src/Chat/ChatComposerInput.doc.mjs +114 -26
  344. package/src/Chat/ChatComposerInput.spec.md +185 -0
  345. package/src/Chat/ChatComposerInput.test.tsx +113 -3
  346. package/src/Chat/ChatComposerInput.tsx +78 -13
  347. package/src/Chat/ChatComposerTokenElement.spec.md +152 -0
  348. package/src/Chat/ChatComposerTokenElement.test.tsx +85 -0
  349. package/src/Chat/ChatDictationButton.doc.mjs +3 -3
  350. package/src/Chat/ChatDictationButton.spec.md +160 -0
  351. package/src/Chat/ChatDictationButton.test.tsx +92 -27
  352. package/src/Chat/ChatDictationButton.tsx +8 -6
  353. package/src/Chat/ChatLayout.doc.mjs +12 -4
  354. package/src/Chat/ChatLayout.spec.md +271 -0
  355. package/src/Chat/ChatLayout.test.tsx +28 -0
  356. package/src/Chat/ChatLayout.tsx +19 -0
  357. package/src/Chat/ChatLayoutScrollButton.spec.md +338 -0
  358. package/src/Chat/ChatLayoutScrollButton.test.tsx +31 -0
  359. package/src/Chat/ChatLayoutScrollButton.tsx +31 -14
  360. package/src/Chat/ChatMessageBubble.doc.mjs +28 -15
  361. package/src/Chat/ChatMessageBubble.spec.md +263 -0
  362. package/src/Chat/ChatMessageBubble.test.tsx +93 -0
  363. package/src/Chat/ChatMessageBubble.tsx +8 -3
  364. package/src/Chat/ChatMessageList.spec.md +222 -0
  365. package/src/Chat/ChatMessageList.test.tsx +64 -2
  366. package/src/Chat/ChatMessageList.tsx +4 -3
  367. package/src/Chat/ChatMessageMetadata.doc.mjs +57 -3
  368. package/src/Chat/ChatMessageMetadata.spec.md +220 -0
  369. package/src/Chat/ChatMessageMetadata.test.tsx +34 -0
  370. package/src/Chat/ChatMessageMetadata.tsx +13 -13
  371. package/src/Chat/ChatSendButton.doc.mjs +32 -0
  372. package/src/Chat/ChatSendButton.spec.md +227 -0
  373. package/src/Chat/ChatSendButton.test.tsx +128 -8
  374. package/src/Chat/ChatSendButton.tsx +6 -4
  375. package/src/Chat/ChatSystemMessage.doc.mjs +115 -12
  376. package/src/Chat/ChatSystemMessage.spec.md +225 -0
  377. package/src/Chat/ChatSystemMessage.test.tsx +112 -20
  378. package/src/Chat/ChatSystemMessage.tsx +4 -6
  379. package/src/Chat/ChatTokenizedText.doc.mjs +96 -9
  380. package/src/Chat/ChatTokenizedText.spec.md +190 -0
  381. package/src/Chat/ChatTokenizedText.test.tsx +60 -1
  382. package/src/Chat/ChatTokenizedText.tsx +14 -8
  383. package/src/Chat/ChatToolCalls.doc.mjs +4 -1
  384. package/src/Chat/ChatToolCalls.spec.md +194 -0
  385. package/src/Chat/ChatToolCalls.test.tsx +83 -0
  386. package/src/Chat/ChatToolCalls.tsx +46 -21
  387. package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +514 -0
  388. package/src/Chat/__tests__/ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts +740 -0
  389. package/src/Chat/__tests__/ChatMessageBubble.a11y.chromium.spec.ts +457 -0
  390. package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.test.ts +91 -0
  391. package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.ts +91 -0
  392. package/src/Chat/__tests__/ChatMessageList.a11y.chromium.spec.ts +456 -0
  393. package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +413 -0
  394. package/src/Chat/__tests__/ChatSendButton.a11y.chromium.spec.ts +1522 -0
  395. package/src/Chat/__tests__/ChatSystemMessage.a11y.chromium.spec.ts +1004 -0
  396. package/src/Chat/__tests__/ChatTokenizedText.a11y.chromium.spec.ts +573 -0
  397. package/src/Chat/index.ts +1 -0
  398. package/src/CheckboxInput/CheckboxInput.doc.mjs +11 -0
  399. package/src/CheckboxInput/CheckboxInput.test.tsx +34 -0
  400. package/src/CheckboxInput/CheckboxInput.tsx +21 -1
  401. package/src/Citation/Citation.doc.mjs +2 -2
  402. package/src/Citation/Citation.test.tsx +17 -0
  403. package/src/Citation/Citation.tsx +4 -2
  404. package/src/ClickableCard/ClickableCard.doc.mjs +2 -2
  405. package/src/ClickableCard/ClickableCard.test.tsx +102 -5
  406. package/src/CodeBlock/highlightRanges.test.ts +143 -1
  407. package/src/CodeBlock/highlightRanges.ts +15 -5
  408. package/src/Collapsible/Collapsible.doc.mjs +11 -0
  409. package/src/Collapsible/Collapsible.test.tsx +21 -0
  410. package/src/Collapsible/Collapsible.tsx +5 -0
  411. package/src/CommandPalette/CommandPaletteInput.tsx +6 -1
  412. package/src/ComplexSelector/ComplexSelector.tsx +6 -1
  413. package/src/DateInput/DateInput.doc.mjs +38 -9
  414. package/src/DateInput/DateInput.tsx +59 -17
  415. package/src/DateInput/NativeDateField.tsx +24 -8
  416. package/src/DateInput/Presentation.test.tsx +121 -0
  417. package/src/DateInput/TouchDateField.tsx +6 -2
  418. package/src/DateInput/index.ts +1 -0
  419. package/src/DateRangeInput/DateRangeInput.tsx +6 -1
  420. package/src/DateTimeInput/DateTimeInput.doc.mjs +28 -12
  421. package/src/DateTimeInput/DateTimeInput.tsx +93 -37
  422. package/src/DateTimeInput/Presentation.test.tsx +89 -0
  423. package/src/DateTimeInput/TouchDateTimeField.tsx +6 -1
  424. package/src/DateTimeInput/index.ts +1 -0
  425. package/src/DateTimeInput/nativePickerSegmentStyles.ts +24 -8
  426. package/src/Dialog/Dialog.doc.mjs +2 -0
  427. package/src/Dialog/DialogHeader.doc.mjs +22 -0
  428. package/src/Dialog/DialogHeader.test.tsx +167 -3
  429. package/src/Dialog/DialogHeader.tsx +37 -6
  430. package/src/Dialog/modules/DialogHeader.spec.md +101 -42
  431. package/src/DropdownMenu/DropdownMenu.test.tsx +5 -2
  432. package/src/Field/InputClearButton.test.tsx +17 -3
  433. package/src/Field/InputClearButton.tsx +5 -2
  434. package/src/Field/PanelSearchInput.tsx +5 -2
  435. package/src/FieldStatus/__tests__/StatusMessage.a11y.states.ts +1 -1
  436. package/src/FileInput/FileInput.tsx +11 -2
  437. package/src/Icon/Icon.doc.mjs +7 -5
  438. package/src/Icon/Icon.spec.md +81 -40
  439. package/src/Icon/Icon.test.tsx +6 -3
  440. package/src/Icon/Icon.tsx +20 -68
  441. package/src/Icon/IconDefaultSizeContext.ts +23 -0
  442. package/src/Icon/IconSize.stylex.ts +70 -0
  443. package/src/IconButton/IconButton.doc.mjs +3 -3
  444. package/src/IconButton/IconButton.test.tsx +40 -0
  445. package/src/Item/Item.doc.mjs +6 -2
  446. package/src/Item/Item.tsx +9 -3
  447. package/src/Kbd/Kbd.doc.mjs +3 -3
  448. package/src/Kbd/Kbd.test.tsx +57 -1
  449. package/src/Kbd/Kbd.tsx +57 -37
  450. package/src/Layout/LayoutFooter.doc.mjs +17 -0
  451. package/src/Link/Link.doc.mjs +17 -4
  452. package/src/Link/Link.test.tsx +24 -0
  453. package/src/Link/Link.tsx +5 -0
  454. package/src/Link/LinkProvider.doc.mjs +2 -2
  455. package/src/Link/__tests__/Link.navigation.a11y.chromium.spec.ts +261 -0
  456. package/src/Link/useLinkComponent.test.tsx +333 -0
  457. package/src/Link/useLinkComponent.ts +29 -57
  458. package/src/List/List.doc.mjs +6 -0
  459. package/src/List/List.spec.md +200 -0
  460. package/src/List/List.test.tsx +117 -1
  461. package/src/List/List.tsx +22 -2
  462. package/src/List/ListContext.tsx +3 -1
  463. package/src/List/ListItem.doc.mjs +2 -2
  464. package/src/List/ListItem.source-build.test.mjs +41 -0
  465. package/src/List/ListItem.tsx +26 -2
  466. package/src/Markdown/Markdown.doc.mjs +300 -2
  467. package/src/Markdown/Markdown.fr23.bench.ts +174 -0
  468. package/src/Markdown/Markdown.fr23.perf.test.ts +249 -0
  469. package/src/Markdown/Markdown.fr23.sampling.ts +49 -0
  470. package/src/Markdown/Markdown.helpers.perf.test.ts +489 -0
  471. package/src/Markdown/Markdown.public.test.ts +130 -3
  472. package/src/Markdown/Markdown.renderBoundary.test.tsx +72 -0
  473. package/src/Markdown/Markdown.spec.md +210 -45
  474. package/src/Markdown/Markdown.test.tsx +87 -3
  475. package/src/Markdown/Markdown.tsx +414 -135
  476. package/src/Markdown/ast.test.ts +307 -0
  477. package/src/Markdown/ast.ts +337 -0
  478. package/src/Markdown/incremental.test.ts +43 -0
  479. package/src/Markdown/index.ts +37 -1
  480. package/src/Markdown/modules/remark.spec.md +269 -0
  481. package/src/Markdown/modules/softBreaks.spec.md +137 -0
  482. package/src/Markdown/parser/index.ts +64 -0
  483. package/src/Markdown/parser.public.test.ts +103 -0
  484. package/src/Markdown/parser.test.ts +38 -6
  485. package/src/Markdown/parser.ts +1221 -242
  486. package/src/Markdown/plugins/frontmatter.test.tsx +125 -0
  487. package/src/Markdown/plugins/frontmatter.ts +198 -0
  488. package/src/Markdown/plugins/index.ts +54 -0
  489. package/src/Markdown/plugins/protocol.test.tsx +1022 -0
  490. package/src/Markdown/plugins/protocol.ts +1618 -0
  491. package/src/Markdown/plugins/semanticFence.test.tsx +546 -0
  492. package/src/Markdown/plugins/semanticFence.ts +424 -0
  493. package/src/Markdown/plugins/softBreaks.test.tsx +172 -0
  494. package/src/Markdown/plugins/softBreaks.ts +169 -0
  495. package/src/Markdown/plugins/sourceDecoration.test.tsx +799 -0
  496. package/src/Markdown/plugins/sourceDecoration.ts +539 -0
  497. package/src/Markdown/plugins/textTransform.test.ts +467 -0
  498. package/src/Markdown/plugins/textTransform.ts +554 -0
  499. package/src/Markdown/remark.test.tsx +1877 -0
  500. package/src/Markdown/remark.ts +1574 -0
  501. package/src/Markdown/url.ts +36 -0
  502. package/src/Markdown/utils.ts +13 -1
  503. package/src/MetadataList/MetadataList.test.tsx +4 -2
  504. package/src/MetadataList/MetadataList.tsx +3 -3
  505. package/src/MultiSelector/MultiSelector.test.tsx +1 -35
  506. package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +128 -0
  507. package/src/NumberInput/NumberInput.tsx +6 -1
  508. package/src/Outline/Outline.doc.mjs +7 -5
  509. package/src/Outline/Outline.spec.md +1 -1
  510. package/src/Outline/index.ts +1 -0
  511. package/src/Outline/modules/parseOutlineFromMarkdown.spec.md +142 -0
  512. package/src/Outline/parseOutlineFromMarkdown.ts +40 -10
  513. package/src/Outline/useOutlineFromMarkdown.ts +15 -3
  514. package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
  515. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +150 -1
  516. package/src/PowerSearch/PowerSearchEditPopover.tsx +51 -28
  517. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +51 -0
  518. package/src/PowerSearch/PowerSearchValueEditor.tsx +4 -0
  519. package/src/ProgressBar/ProgressBar.test.tsx +29 -11
  520. package/src/ProgressBar/ProgressBar.tsx +59 -72
  521. package/src/RadioList/RadioList.doc.mjs +11 -0
  522. package/src/RadioList/RadioList.test.tsx +32 -0
  523. package/src/RadioList/RadioListItem.tsx +25 -1
  524. package/src/ScrollableArea/ScrollableArea.tsx +1 -0
  525. package/src/ScrollableArea/modules/useScrollableArea.spec.md +50 -22
  526. package/src/SegmentedControl/SegmentedControl.doc.mjs +2 -2
  527. package/src/SegmentedControl/SegmentedControl.test.tsx +61 -0
  528. package/src/SegmentedControl/SegmentedControl.tsx +2 -1
  529. package/src/SegmentedControl/SegmentedControlItem.tsx +6 -9
  530. package/src/Selector/Selector.doc.mjs +3 -3
  531. package/src/Selector/Selector.spec.md +51 -49
  532. package/src/Selector/Selector.test.tsx +61 -55
  533. package/src/Selector/Selector.tsx +34 -15
  534. package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +130 -0
  535. package/src/Selector/__tests__/Listbox.a11y.dom.ts +38 -0
  536. package/src/Selector/__tests__/Listbox.a11y.inventory.test.ts +63 -0
  537. package/src/Selector/__tests__/Listbox.a11y.known-failures.ts +37 -0
  538. package/src/Selector/__tests__/Listbox.a11y.states.ts +232 -0
  539. package/src/Selector/__tests__/Selector.a11y.chromium.spec.ts +45 -0
  540. package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +121 -0
  541. package/src/SideNav/SideNav.doc.mjs +1 -1
  542. package/src/SideNav/SideNav.test.tsx +10 -0
  543. package/src/SideNav/SideNav.tsx +14 -2
  544. package/src/Slider/Slider.doc.mjs +17 -3
  545. package/src/Slider/Slider.test.tsx +221 -0
  546. package/src/Slider/Slider.tsx +40 -9
  547. package/src/Spinner/Spinner.test.tsx +4 -0
  548. package/src/Spinner/Spinner.tsx +31 -18
  549. package/src/Switch/Switch.doc.mjs +11 -0
  550. package/src/Switch/Switch.test.tsx +16 -0
  551. package/src/Switch/Switch.tsx +28 -0
  552. package/src/TabList/Tab.tsx +35 -7
  553. package/src/TabList/TabList.doc.mjs +11 -0
  554. package/src/TabList/TabList.spec.md +204 -0
  555. package/src/TabList/TabList.test.tsx +66 -0
  556. package/src/TabList/__tests__/Tabs.a11y.known-failures.ts +1 -34
  557. package/src/Table/Table.doc.mjs +1 -1
  558. package/src/Table/Table.spec.md +54 -40
  559. package/src/Table/Table.test.tsx +83 -10
  560. package/src/Table/Table.tsx +30 -22
  561. package/src/Table/__tests__/TableScroll.a11y.chromium.spec.ts +137 -0
  562. package/src/TextArea/TextArea.tsx +6 -1
  563. package/src/TextInput/TextInput.test.tsx +20 -1
  564. package/src/TextInput/TextInput.tsx +6 -1
  565. package/src/TimeInput/NativeTimeInput.test.tsx +36 -3
  566. package/src/TimeInput/Presentation.test.tsx +148 -0
  567. package/src/TimeInput/TimeInput.doc.mjs +21 -5
  568. package/src/TimeInput/TimeInput.tsx +102 -11
  569. package/src/TimeInput/TouchTimeField.tsx +572 -0
  570. package/src/TimeInput/index.ts +1 -0
  571. package/src/Timer/Timer.doc.mjs +183 -0
  572. package/src/Timer/Timer.spec.md +215 -0
  573. package/src/Timer/Timer.test.tsx +302 -0
  574. package/src/Timer/Timer.tsx +258 -0
  575. package/src/Timer/index.ts +11 -0
  576. package/src/ToggleButton/ToggleButton.doc.mjs +3 -3
  577. package/src/ToggleButton/ToggleButton.test.tsx +299 -4
  578. package/src/ToggleButton/ToggleButton.tsx +26 -33
  579. package/src/ToggleButton/ToggleButtonGroup.doc.mjs +3 -3
  580. package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +209 -0
  581. package/src/Token/Token.doc.mjs +2 -2
  582. package/src/Tokenizer/Tokenizer.spec.md +142 -75
  583. package/src/TopNav/TopNavMenu.doc.mjs +2 -2
  584. package/src/TopNav/TopNavMenu.test.tsx +30 -0
  585. package/src/TopNav/TopNavMenu.tsx +7 -2
  586. package/src/TreeList/TreeList.doc.mjs +3 -3
  587. package/src/TreeList/TreeList.spec.md +123 -75
  588. package/src/TreeList/TreeList.test.tsx +29 -0
  589. package/src/TreeList/TreeList.tsx +3 -0
  590. package/src/TreeList/TreeListItem.tsx +15 -1
  591. package/src/TreeList/TreeListTypes.ts +11 -1
  592. package/src/Typeahead/BaseTypeahead.spec.md +4 -3
  593. package/src/Typeahead/BaseTypeahead.tsx +21 -7
  594. package/src/Typeahead/Typeahead.test.tsx +53 -0
  595. package/src/__tests__/PressedState.a11y.chromium.spec.ts +813 -0
  596. package/src/__tests__/pressState.ts +93 -0
  597. package/src/hooks/scrollKeyboardDelegation.test.ts +155 -0
  598. package/src/hooks/scrollKeyboardDelegation.ts +233 -0
  599. package/src/hooks/useClickableContainer.test.tsx +236 -0
  600. package/src/hooks/useClickableContainer.ts +20 -4
  601. package/src/hooks/useScrollableArea.doc.mjs +15 -3
  602. package/src/hooks/useScrollableArea.test.tsx +59 -1
  603. package/src/hooks/useScrollableArea.ts +34 -10
  604. package/src/index.ts +3 -0
  605. package/src/inputFontFloor.test.ts +106 -0
  606. package/src/tailwind-theme.css +0 -6
  607. package/src/theme/Theme.test.tsx +32 -0
  608. package/src/theme/declarationBoundary.test.ts +126 -0
  609. package/src/theme/declarationBoundary.ts +347 -0
  610. package/src/theme/defineTheme.ts +4 -0
  611. package/src/theme/derivedVarRegistry.test.ts +7 -0
  612. package/src/theme/derivedVarRegistry.ts +1 -0
  613. package/src/theme/generateThemeRules.test.ts +526 -1
  614. package/src/theme/generateThemeRules.ts +231 -50
  615. package/src/theme/themeAdaptations.test.ts +211 -1
  616. package/src/theme/themeAdaptations.ts +50 -4
  617. package/src/theme/tokenValueCompat.test.ts +4 -1
  618. package/src/utils/inputPresentation.ts +143 -0
  619. package/src/utils/interactionOverlay.stylex.ts +20 -0
  620. package/src/utils/safeUrl.test.ts +88 -0
  621. package/src/utils/safeUrl.ts +85 -0
@@ -71,6 +71,12 @@ import {
71
71
  formatSharedDate,
72
72
  } from '../utils/plainDate';
73
73
  import type {TimestampFormat} from '../Timestamp';
74
+ import {
75
+ effectivePickerPresentation,
76
+ resolvePickerPresentation,
77
+ type PickerPresentation,
78
+ } from '../utils/inputPresentation';
79
+ import {useDevWarning} from '../hooks/useDevWarning';
74
80
 
75
81
  const styles = stylex.create({
76
82
  iconButton: {
@@ -99,9 +105,14 @@ const styles = stylex.create({
99
105
  borderStyle: 'none',
100
106
  padding: 0,
101
107
  fontFamily: typographyVars['--font-family-body'],
108
+ // The 16px floor is iOS-only: iOS Safari zooms the page when a focused
109
+ // control sits under 16px, and only iOS WebKit implements
110
+ // -webkit-touch-callout to key the coarse-pointer floor to it.
102
111
  fontSize: {
103
112
  default: typeScaleVars['--text-body-size'],
104
- '@media (pointer: coarse)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
113
+ '@media (pointer: coarse)': {
114
+ '@supports (-webkit-touch-callout: none)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
115
+ },
105
116
  },
106
117
  lineHeight: typeScaleVars['--text-body-leading'],
107
118
  color: colorVars['--color-text-primary'],
@@ -159,8 +170,12 @@ export type DateInputSize = keyof typeof sizeStyles;
159
170
  * - `'always'`: native wherever the browser supports `<input type="date">`
160
171
  * - `'never'`: Astryx's own pickers everywhere
161
172
  */
173
+ /** @deprecated Use {@link DateInputPresentation} via the `presentation` prop. */
162
174
  export type DateInputNativePicker = 'touch' | 'always' | 'never';
163
175
 
176
+ /** Which surface collects the date (`spec:AST-043` FR1; no `text-input` — TimeInput-only). */
177
+ export type DateInputPresentation = PickerPresentation;
178
+
164
179
  export type DateInputFormat = Extract<
165
180
  TimestampFormat,
166
181
  'date' | 'date_long' | 'date_weekday' | 'system_date'
@@ -399,13 +414,30 @@ export interface DateInputProps extends Omit<
399
414
  * reason enough to prefer `'never'` on a field that uses it.
400
415
  *
401
416
  * @default 'touch'
402
- * @example
403
- * ```
404
- * // Astryx's own touch picker instead of the platform's
405
- * <DateInput label="Event date" value={date} onChange={setDate} nativePicker="never" />
406
- * ```
417
+ * @deprecated Use `presentation` (`spec:AST-043` FR3):
418
+ * `'touch'` → `'adaptive-native'`, `'always'` → `'native'`,
419
+ * `'never'` → `'adaptive-bottom-sheet'`. Still works exactly as released;
420
+ * `presentation` wins when both are set.
407
421
  */
408
422
  nativePicker?: DateInputNativePicker;
423
+
424
+ /**
425
+ * Which surface collects the date (`spec:AST-043` FR1). Every value opens
426
+ * a picker; the typed-field-only `'text-input'` belongs to `TimeInput`.
427
+ *
428
+ * - `'popover'`: Astryx's typed field + calendar popover on every pointer
429
+ * - `'bottom-sheet'`: Astryx's bottom-sheet calendar on every pointer
430
+ * - `'native'`: the browser/OS picker on every pointer, with no Astryx
431
+ * fallback (FR2)
432
+ * - `'adaptive-bottom-sheet'`: popover on a fine pointer, bottom sheet on
433
+ * a coarse pointer
434
+ * - `'adaptive-native'` (default): popover on a fine pointer, browser/OS
435
+ * picker on a coarse pointer, keeping the released Astryx fallbacks
436
+ * where a native control cannot express the value (FR2)
437
+ *
438
+ * @default 'adaptive-native'
439
+ */
440
+ presentation?: DateInputPresentation;
409
441
  }
410
442
 
411
443
  /**
@@ -943,18 +975,28 @@ PointerDateField.displayName = 'PointerDateField';
943
975
  */
944
976
  export function DateInput(props: DateInputProps) {
945
977
  const isTouch = useMediaQuery(TOUCH_POINTER_QUERY);
946
- const nativePicker = props.nativePicker ?? 'touch';
947
-
948
- // The platform's picker, where the consumer asked for it — see the
949
- // `nativePicker` prop for what that trades away.
950
- if (nativePicker === 'always' || (nativePicker === 'touch' && isTouch)) {
951
- return <NativeDateField {...props} />;
952
- }
953
- return isTouch ? (
954
- <TouchDateField {...props} />
955
- ) : (
956
- <PointerDateField {...props} />
978
+ useDevWarning(
979
+ 'DateInput',
980
+ '`nativePicker` is deprecated; use `presentation` instead (`touch` → `adaptive-native`, `always` → `native`, `never` → `adaptive-bottom-sheet`). `presentation` wins when both are set.',
981
+ props.nativePicker !== undefined,
982
+ );
983
+ const surface = resolvePickerPresentation(
984
+ effectivePickerPresentation(props.presentation, props.nativePicker),
985
+ isTouch,
957
986
  );
987
+ const {
988
+ presentation: _presentation,
989
+ nativePicker: _nativePicker,
990
+ ...rest
991
+ } = props;
992
+ switch (surface) {
993
+ case 'native':
994
+ return <NativeDateField {...rest} />;
995
+ case 'sheet':
996
+ return <TouchDateField {...rest} />;
997
+ case 'desktop':
998
+ return <PointerDateField {...rest} />;
999
+ }
958
1000
  }
959
1001
 
960
1002
  DateInput.displayName = 'DateInput';
@@ -100,10 +100,14 @@ const styles = stylex.create({
100
100
  borderStyle: 'none',
101
101
  padding: 0,
102
102
  fontFamily: typographyVars['--font-family-body'],
103
- // Below 16px iOS zooms the page when the field takes focus.
103
+ // Below 16px iOS zooms the page when the field takes focus. Only iOS
104
+ // WebKit implements -webkit-touch-callout, so the coarse-pointer floor is
105
+ // keyed to iOS alone.
104
106
  fontSize: {
105
107
  default: typeScaleVars['--text-body-size'],
106
- '@media (pointer: coarse)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
108
+ '@media (pointer: coarse)': {
109
+ '@supports (-webkit-touch-callout: none)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
110
+ },
107
111
  },
108
112
  lineHeight: typeScaleVars['--text-body-leading'],
109
113
  color: colorVars['--color-text-primary'],
@@ -112,11 +116,20 @@ const styles = stylex.create({
112
116
  // A date control's intrinsic height comes from its inner edit fields, not
113
117
  // from `line-height`, so it renders ~2px taller than a text input and its
114
118
  // value sits off the shared baseline inside the same flex row. One line
115
- // box is exactly what the text field occupies.
116
- height: stylex.firstThatWorks(
117
- '1lh',
118
- `calc(max(1rem, ${typeScaleVars['--text-body-size']}) * ${typeScaleVars['--text-body-leading']})`,
119
- ),
119
+ // box is exactly what the text field occupies. The calc fallback mirrors
120
+ // the iOS-only floor above; browsers with `1lh` track it for free.
121
+ height: {
122
+ default: stylex.firstThatWorks(
123
+ '1lh',
124
+ `calc(${typeScaleVars['--text-body-size']} * ${typeScaleVars['--text-body-leading']})`,
125
+ ),
126
+ '@media (pointer: coarse)': {
127
+ '@supports (-webkit-touch-callout: none)': stylex.firstThatWorks(
128
+ '1lh',
129
+ `calc(max(1rem, ${typeScaleVars['--text-body-size']}) * ${typeScaleVars['--text-body-leading']})`,
130
+ ),
131
+ },
132
+ },
120
133
  // iOS gives date controls their own button-like chrome, with inner
121
134
  // spacing and a centred value that no reset of ours can reach.
122
135
  WebkitAppearance: 'none',
@@ -187,9 +200,12 @@ const styles = stylex.create({
187
200
  // covers — one line of that leading fills its height exactly, which puts
188
201
  // the glyphs on the input's own baseline.
189
202
  display: 'block',
203
+ // ...with the input's own iOS floor, so the two baselines stay shared.
190
204
  fontSize: {
191
205
  default: typeScaleVars['--text-body-size'],
192
- '@media (pointer: coarse)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
206
+ '@media (pointer: coarse)': {
207
+ '@supports (-webkit-touch-callout: none)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
208
+ },
193
209
  },
194
210
  lineHeight: typeScaleVars['--text-body-leading'],
195
211
  // A tap has to reach the control underneath — that is what raises the
@@ -0,0 +1,121 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file Presentation.test.tsx
5
+ * @input Uses vitest, Testing Library, and DateInput
6
+ * @output Tests for the `presentation` prop (`spec:AST-043` FR1–FR4)
7
+ * @position Testing; covers surface resolution and precedence
8
+ */
9
+
10
+ import {afterEach, describe, expect, it, vi} from 'vitest';
11
+ import {render, screen} from '@testing-library/react';
12
+ import {DateInput} from './DateInput';
13
+ import {resetDateSegmentProbe} from './nativeDateSegments';
14
+
15
+ const HOVER_CAPABLE = /\(\s*hover\s*:\s*hover\s*\)/;
16
+
17
+ class MockResizeObserver {
18
+ observe() {}
19
+ unobserve() {}
20
+ disconnect() {}
21
+ }
22
+
23
+ function stubPointer(isCoarse: boolean): void {
24
+ vi.stubGlobal('matchMedia', (query: string) => ({
25
+ matches: /pointer:\s*coarse/.test(query)
26
+ ? isCoarse
27
+ : /pointer:\s*fine/.test(query)
28
+ ? !isCoarse
29
+ : HOVER_CAPABLE.test(query),
30
+ media: query,
31
+ onchange: null,
32
+ addListener: () => {},
33
+ removeListener: () => {},
34
+ addEventListener: () => {},
35
+ removeEventListener: () => {},
36
+ dispatchEvent: () => false,
37
+ }));
38
+ vi.stubGlobal('ResizeObserver', MockResizeObserver);
39
+ }
40
+
41
+ afterEach(() => {
42
+ vi.unstubAllGlobals();
43
+ vi.restoreAllMocks();
44
+ resetDateSegmentProbe();
45
+ });
46
+
47
+ describe('DateInput presentation', () => {
48
+ it('popover forces the calendar field on a coarse pointer', () => {
49
+ stubPointer(true);
50
+ render(
51
+ <DateInput
52
+ label="Ship date"
53
+ presentation="popover"
54
+ onChange={() => {}}
55
+ />,
56
+ );
57
+ expect(
58
+ screen.getByRole('button', {name: 'Open calendar'}),
59
+ ).toBeInTheDocument();
60
+ expect(document.querySelector('input[type="date"]')).toBeNull();
61
+ });
62
+
63
+ it('bottom-sheet forces the sheet field on a fine pointer', () => {
64
+ stubPointer(false);
65
+ render(
66
+ <DateInput
67
+ label="Ship date"
68
+ presentation="bottom-sheet"
69
+ onChange={() => {}}
70
+ />,
71
+ );
72
+ const input = screen.getByRole('combobox', {name: 'Ship date'});
73
+ expect(input).toHaveAttribute('readonly');
74
+ expect(document.querySelector('input[type="date"]')).toBeNull();
75
+ });
76
+
77
+ it('native forces the native field on a fine pointer', () => {
78
+ stubPointer(false);
79
+ render(
80
+ <DateInput label="Ship date" presentation="native" onChange={() => {}} />,
81
+ );
82
+ expect(document.querySelector('input[type="date"]')).not.toBeNull();
83
+ });
84
+
85
+ it('presentation wins over nativePicker (FR4)', () => {
86
+ stubPointer(false);
87
+ render(
88
+ <DateInput
89
+ label="Ship date"
90
+ presentation="bottom-sheet"
91
+ nativePicker="always"
92
+ onChange={() => {}}
93
+ />,
94
+ );
95
+ // A sheet on a fine pointer can only come from `presentation`: the
96
+ // deprecated `always` alone would have rendered the native field.
97
+ expect(screen.getByRole('combobox', {name: 'Ship date'})).toHaveAttribute(
98
+ 'readonly',
99
+ );
100
+ expect(document.querySelector('input[type="date"]')).toBeNull();
101
+ });
102
+
103
+ it('deprecated nativePicker="never" keeps popover/sheet by pointer (FR3)', () => {
104
+ stubPointer(false);
105
+ const {unmount} = render(
106
+ <DateInput label="Ship date" nativePicker="never" onChange={() => {}} />,
107
+ );
108
+ expect(
109
+ screen.getByRole('button', {name: 'Open calendar'}),
110
+ ).toBeInTheDocument();
111
+ unmount();
112
+
113
+ stubPointer(true);
114
+ render(
115
+ <DateInput label="Ship date" nativePicker="never" onChange={() => {}} />,
116
+ );
117
+ expect(screen.getByRole('combobox', {name: 'Ship date'})).toHaveAttribute(
118
+ 'readonly',
119
+ );
120
+ });
121
+ });
@@ -194,10 +194,14 @@ const styles = stylex.create({
194
194
  padding: 0,
195
195
  fontFamily: typographyVars['--font-family-body'],
196
196
  // Below 16px iOS zooms the page on focus. The field is focusable even
197
- // though it is not typable, so it needs the same floor DateInput has.
197
+ // though it is not typable, so it needs the same floor DateInput has —
198
+ // keyed to iOS alone, since only iOS WebKit implements
199
+ // -webkit-touch-callout.
198
200
  fontSize: {
199
201
  default: typeScaleVars['--text-body-size'],
200
- '@media (pointer: coarse)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
202
+ '@media (pointer: coarse)': {
203
+ '@supports (-webkit-touch-callout: none)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
204
+ },
201
205
  },
202
206
  lineHeight: typeScaleVars['--text-body-leading'],
203
207
  color: colorVars['--color-text-primary'],
@@ -15,6 +15,7 @@ export type {
15
15
  DateInputSize,
16
16
  DateInputFormat,
17
17
  DateInputNativePicker,
18
+ DateInputPresentation,
18
19
  DateInputStatus,
19
20
  DateInputStatusType,
20
21
  } from './DateInput';
@@ -92,9 +92,14 @@ const styles = stylex.create({
92
92
  borderStyle: 'none',
93
93
  padding: 0,
94
94
  fontFamily: typographyVars['--font-family-body'],
95
+ // The 16px floor is iOS-only: iOS Safari zooms the page when a focused
96
+ // control sits under 16px, and only iOS WebKit implements
97
+ // -webkit-touch-callout to key the coarse-pointer floor to it.
95
98
  fontSize: {
96
99
  default: typeScaleVars['--text-body-size'],
97
- '@media (pointer: coarse)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
100
+ '@media (pointer: coarse)': {
101
+ '@supports (-webkit-touch-callout: none)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
102
+ },
98
103
  },
99
104
  lineHeight: typeScaleVars['--text-body-leading'],
100
105
  color: colorVars['--color-text-primary'],
@@ -121,14 +121,14 @@ export const docs = {
121
121
  name: 'timeIncrement',
122
122
  type: '1 | 5 | 10 | 15 | 30',
123
123
  description:
124
- 'Minute step for arrow keys in Astryx\'s typed time field. A non-default value keeps the Astryx time field in nativePicker modes because iOS treats native step as validation, not picker cadence. Ignored by the Astryx touch sheet, which uses wheels.',
124
+ "Minute step for arrow keys in Astryx's typed time field. A non-default value keeps the Astryx time field in nativePicker modes because iOS treats native step as validation, not picker cadence. Ignored by the Astryx touch sheet, which uses wheels.",
125
125
  default: '1',
126
126
  },
127
127
  {
128
128
  name: 'timeOptionInterval',
129
129
  type: '5 | 10 | 15 | 30 | 60',
130
130
  description:
131
- 'Minute cadence for the preset-time combobox on Astryx\'s fine-pointer time field. Setting it keeps that Astryx time field even in nativePicker modes because the OS picker has no equivalent preset list. The Astryx touch sheet uses wheels.',
131
+ "Minute cadence for the preset-time combobox on Astryx's fine-pointer time field. Setting it keeps that Astryx time field even in nativePicker modes because the OS picker has no equivalent preset list. The Astryx touch sheet uses wheels.",
132
132
  },
133
133
  {
134
134
  name: 'hasClear',
@@ -188,11 +188,18 @@ export const docs = {
188
188
  'First day of week in Astryx calendars. A number (0 = Sunday to 6 = Saturday) or a three-letter day name. Ignored by native date controls.',
189
189
  default: '0',
190
190
  },
191
+ {
192
+ name: 'presentation',
193
+ type: "'popover' | 'bottom-sheet' | 'native' | 'adaptive-bottom-sheet' | 'adaptive-native'",
194
+ description:
195
+ "Which surfaces draw the date and time pickers. 'adaptive-native' (the default) uses Astryx's typed fields and popovers on a fine pointer and browser/OS controls on a coarse pointer — with per-segment Astryx fallbacks: hasSeconds, non-default timeIncrement, or timeOptionInterval retain Astryx's time field because iOS cannot express them faithfully; 'native' always uses both browser/OS controls with no fallback; 'adaptive-bottom-sheet' uses popovers on a fine pointer and Astryx's coordinated bottom sheet on a coarse pointer; 'popover' and 'bottom-sheet' force that Astryx surface on every pointer. Every value opens pickers; typed-only fields are TimeInput's alone. Use a non-native presentation when numberOfMonths, weekStartsOn, or visible dateConstraints behavior matters. Constraints are enforced on commit; min/max are forwarded as hints. hourFormat formats the closed time, while the OS picker follows the user's locale.",
196
+ default: "'adaptive-native'",
197
+ },
191
198
  {
192
199
  name: 'nativePicker',
193
200
  type: "'touch' | 'always' | 'never'",
194
201
  description:
195
- "Which surfaces draw the date and time pickers. 'touch' (the default) uses browser/OS controls on a coarse primary pointer; 'always' uses them wherever input type=date/time are supported; 'never' keeps Astryx's own surfaces everywhere. The native time control is used only for the default minute-precision contract: hasSeconds, non-default timeIncrement, or timeOptionInterval retain Astryx's time field because iOS cannot express them faithfully. Use 'never' when numberOfMonths, weekStartsOn, or visible dateConstraints behavior matters. Constraints are enforced on commit; min/max are forwarded as hints. hourFormat formats the closed time, while the OS picker follows the user's locale.",
202
+ "Deprecated: use presentation ('touch' = 'adaptive-native', 'always' = 'native', 'never' = 'adaptive-bottom-sheet'). Still works exactly as released; presentation wins when both are set.",
196
203
  default: "'touch'",
197
204
  },
198
205
  {
@@ -231,7 +238,7 @@ export const docs = {
231
238
  },
232
239
  usage: {
233
240
  description:
234
- 'DateTimeInput combines date and time selection in one field. With nativePicker="touch" (the default), mouse/trackpad devices use Astryx typed fields and popovers, while coarse-pointer devices use browser/OS date and time controls in the same two-segment field. nativePicker="always" uses both native controls on every pointer; nativePicker="never" keeps Astryx\'s own surfaces — pointer fields on fine pointers and the coordinated Date/Time bottom sheet on coarse pointers. The closed segments stay side by side when at least 400px is available and wrap into full-width rows below 400px, independent of viewport width. Use it for scheduling, event creation, deadline setting, or any form field that needs a specific datetime.',
241
+ 'DateTimeInput combines date and time selection in one field. With presentation="adaptive-native" (the default), mouse/trackpad devices use Astryx typed fields and popovers, while coarse-pointer devices use browser/OS date and time controls in the same two-segment field. presentation="native" uses both native controls on every pointer; presentation="adaptive-bottom-sheet" keeps Astryx\'s own surfaces — pointer fields on fine pointers and the coordinated Date/Time bottom sheet on coarse pointers; "popover" and "bottom-sheet" force one Astryx surface on every pointer. The closed segments stay side by side when at least 400px is available and wrap into full-width rows below 400px, independent of viewport width. Use it for scheduling, event creation, deadline setting, or any form field that needs a specific datetime.',
235
242
  bestPractices: [
236
243
  {
237
244
  guidance: true,
@@ -285,7 +292,7 @@ export const docs = {
285
292
  name: 'Date input',
286
293
  required: true,
287
294
  description:
288
- 'A typed date field with calendar popover on the fine-pointer Astryx surface, a real input type=date in native modes, or a read-only segment opening the Astryx touch sheet when nativePicker is never on a coarse pointer.',
295
+ 'A typed date field with calendar popover on the fine-pointer Astryx surface, a real input type=date in native modes, or a read-only segment opening the Astryx touch sheet under presentation="adaptive-bottom-sheet" on a coarse pointer.',
289
296
  },
290
297
  {
291
298
  name: 'Calendar icon',
@@ -297,19 +304,19 @@ export const docs = {
297
304
  name: 'Date picker',
298
305
  required: false,
299
306
  description:
300
- 'The browser/OS picker in native modes, an Astryx month-grid popover on a fine pointer, or the Date panel of the Astryx bottom sheet on a coarse pointer with nativePicker="never".',
307
+ 'The browser/OS picker in native modes, an Astryx month-grid popover on a fine pointer, or the Date panel of the Astryx bottom sheet on a coarse pointer with presentation="adaptive-bottom-sheet".',
301
308
  },
302
309
  {
303
310
  name: 'Time input',
304
311
  required: true,
305
312
  description:
306
- 'A real input type=time for the default minute-precision native mode, a text/combobox time field when seconds, custom increments, or preset options are requested, or a read-only segment opening accessible time wheels when nativePicker is never on a coarse pointer.',
313
+ 'A real input type=time for the default minute-precision native mode, a text/combobox time field when seconds, custom increments, or preset options are requested, or a read-only segment opening accessible time wheels under presentation="adaptive-bottom-sheet" on a coarse pointer.',
307
314
  },
308
315
  {
309
316
  name: 'Time options popover',
310
317
  required: false,
311
318
  description:
312
- 'A list of preset times at the timeOptionInterval cadence. Setting the prop retains Astryx\'s text/combobox time field even when nativePicker otherwise selects native controls; the Astryx touch sheet uses wheels instead.',
319
+ "A list of preset times at the timeOptionInterval cadence. Setting the prop retains Astryx's text/combobox time field even when nativePicker otherwise selects native controls; the Astryx touch sheet uses wheels instead.",
313
320
  },
314
321
  {
315
322
  name: 'Clear button',
@@ -331,7 +338,7 @@ export const docsZh = {
331
338
  displayName: 'Date Time Input',
332
339
  usage: {
333
340
  description:
334
- 'DateTimeInput combines date and time selection in one field. With nativePicker="touch" (the default), mouse/trackpad devices use Astryx typed fields and popovers, while coarse-pointer devices use browser/OS date and time controls in the same two-segment field. nativePicker="always" uses both native controls on every pointer; nativePicker="never" keeps Astryx\'s own surfaces — pointer fields on fine pointers and the coordinated Date/Time bottom sheet on coarse pointers. The closed segments stay side by side when at least 400px is available and wrap into full-width rows below 400px, independent of viewport width. Use it for scheduling, event creation, deadline setting, or any form field that needs a specific datetime.',
341
+ 'DateTimeInput combines date and time selection in one field. With presentation="adaptive-native" (the default), mouse/trackpad devices use Astryx typed fields and popovers, while coarse-pointer devices use browser/OS date and time controls in the same two-segment field. presentation="native" uses both native controls on every pointer; presentation="adaptive-bottom-sheet" keeps Astryx\'s own surfaces — pointer fields on fine pointers and the coordinated Date/Time bottom sheet on coarse pointers; "popover" and "bottom-sheet" force one Astryx surface on every pointer. The closed segments stay side by side when at least 400px is available and wrap into full-width rows below 400px, independent of viewport width. Use it for scheduling, event creation, deadline setting, or any form field that needs a specific datetime.',
335
342
  bestPractices: [
336
343
  {
337
344
  guidance: true,
@@ -525,11 +532,18 @@ export const docsZh = {
525
532
  'Astryx 日历中每周的起始日。可为数字(0=周日……6=周六)或三字母星期缩写。原生日期控件会忽略此属性。',
526
533
  default: '0',
527
534
  },
535
+ {
536
+ name: 'presentation',
537
+ type: "'popover' | 'bottom-sheet' | 'native' | 'adaptive-bottom-sheet' | 'adaptive-native'",
538
+ description:
539
+ "选择由哪些界面绘制日期和时间选择器。'adaptive-native'(默认)在精细指针上使用 Astryx 文本字段与弹出层、在粗指针上使用浏览器/操作系统控件,并按段回退:hasSeconds、非默认 timeIncrement 或 timeOptionInterval 会保留 Astryx 时间字段;'native' 始终使用两个原生控件且不回退;'adaptive-bottom-sheet' 在精细指针上用弹出层、在粗指针上用 Astryx 协调底部面板;'popover' 与 'bottom-sheet' 在任何指针上强制使用对应 Astryx 界面。每个值都会打开选择器;仅文本字段的呈现只属于 TimeInput。需要 numberOfMonths、weekStartsOn 或可见 dateConstraints 行为时请使用非原生呈现。约束会在提交时执行,min/max 作为提示传给原生控件。hourFormat 格式化关闭状态的时间,而操作系统选择器遵循用户区域设置。",
540
+ default: "'adaptive-native'",
541
+ },
528
542
  {
529
543
  name: 'nativePicker',
530
544
  type: "'touch' | 'always' | 'never'",
531
545
  description:
532
- "选择由哪些界面绘制日期和时间选择器。'touch'(默认)在粗略主指针设备上使用浏览器/操作系统的原生控件;'always' 在支持 input type=date/time 的浏览器中始终使用原生控件;'never' 始终使用 Astryx 自带的界面。原生时间控件仅用于默认的分钟精度:hasSeconds、非默认 timeIncrement 或 timeOptionInterval 会保留 Astryx 时间字段,因为 iOS 无法忠实表达这些行为。需要 numberOfMonths、weekStartsOn 或可见 dateConstraints 行为时请使用 'never'。约束会在提交时执行,min/max 作为提示传给原生控件。hourFormat 格式化关闭状态的时间,而操作系统选择器遵循用户区域设置。",
546
+ "已弃用:请使用 presentation('touch'='adaptive-native'、'always'='native'、'never'='adaptive-bottom-sheet')。仍按已发布行为工作;同时设置时以 presentation 为准。",
533
547
  default: "'touch'",
534
548
  },
535
549
  {
@@ -568,7 +582,7 @@ export const docsDense = {
568
582
  'combined date + time picker with calendar popover and time input',
569
583
  usage: {
570
584
  description:
571
- 'DateTimeInput combines date and time selection. nativePicker="touch" (default) uses browser/OS date+time controls on coarse pointers and Astryx pointer fields on fine pointers; "always" uses both native controls everywhere; "never" uses Astryx\'s coordinated bottom sheet on coarse pointers and pointer fields on fine pointers. Closed segments stay side by side when at least 400px is available and wrap below 400px.',
585
+ 'DateTimeInput combines date and time selection. presentation="adaptive-native" (default) uses browser/OS date+time controls on coarse pointers and Astryx pointer fields on fine pointers; "native" uses both native controls everywhere; "adaptive-bottom-sheet" uses Astryx\'s coordinated bottom sheet on coarse pointers and pointer fields on fine pointers; "popover"/"bottom-sheet" force one Astryx surface everywhere. Closed segments stay side by side when at least 400px is available and wrap below 400px.',
572
586
  bestPractices: [
573
587
  {
574
588
  guidance: true,
@@ -648,8 +662,10 @@ export const docsDense = {
648
662
  'Astryx pointer-calendar months shown simultaneously; ignored by native date controls and the mobile touch sheet',
649
663
  weekStartsOn:
650
664
  'first day of week in Astryx calendars (0=Sunday, or name e.g. "mon"); ignored by native date controls',
665
+ presentation:
666
+ "date+time surfaces: 'adaptive-native' (default) = Astryx popovers fine / browser/OS coarse w/ per-segment fallbacks (seconds/timeIncrement/timeOptionInterval); 'native' = browser/OS always, no fallback; 'adaptive-bottom-sheet' = popovers fine / coordinated sheet coarse; 'popover'/'bottom-sheet' force Astryx. every value opens pickers (no typed-only value; that is TimeInput's).",
651
667
  nativePicker:
652
- "date+time surfaces: 'touch' (default) = browser/OS controls on a coarse pointer, 'always' = native on every pointer, 'never' = Astryx calendar/time popovers on fine pointers and coordinated bottom sheet on coarse pointers. use 'never' for numberOfMonths/weekStartsOn/visible dateConstraints/timeOptionInterval; native mode enforces constraints on commit and forwards min/max.",
668
+ "deprecated, use presentation: 'touch'='adaptive-native', 'always'='native', 'never'='adaptive-bottom-sheet'. still works as released; presentation wins if both set.",
653
669
  xstyle: 'StyleX styles for layout; must be stylex.create() value',
654
670
  },
655
671
  };