@astryxdesign/core 0.6.2 → 0.6.3-canary.0788c49

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 (558) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/dist/BottomSheet/BottomSheet.d.ts +1 -1
  3. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  4. package/dist/BottomSheet/BottomSheet.js +3 -1
  5. package/dist/BottomSheet/BottomSheetPanel.d.ts +7 -5
  6. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  7. package/dist/BottomSheet/BottomSheetPanel.js +56 -19
  8. package/dist/Button/Button.d.ts.map +1 -1
  9. package/dist/Button/Button.js +13 -28
  10. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  11. package/dist/Chat/ChatComposer.js +10 -5
  12. package/dist/Chat/ChatComposerDrawer.d.ts +19 -5
  13. package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
  14. package/dist/Chat/ChatComposerDrawer.js +48 -23
  15. package/dist/Chat/ChatComposerInput.d.ts +11 -3
  16. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  17. package/dist/Chat/ChatComposerInput.js +63 -16
  18. package/dist/Chat/ChatDictationButton.d.ts +3 -2
  19. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  20. package/dist/Chat/ChatDictationButton.js +6 -4
  21. package/dist/Chat/ChatLayout.d.ts +19 -0
  22. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  23. package/dist/Chat/ChatLayout.js +19 -0
  24. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  25. package/dist/Chat/ChatLayoutScrollButton.js +44 -34
  26. package/dist/Chat/ChatMessageBubble.d.ts +2 -0
  27. package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
  28. package/dist/Chat/ChatMessageBubble.js +5 -3
  29. package/dist/Chat/ChatMessageList.d.ts +2 -1
  30. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  31. package/dist/Chat/ChatMessageList.js +4 -3
  32. package/dist/Chat/ChatMessageMetadata.d.ts +5 -4
  33. package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
  34. package/dist/Chat/ChatMessageMetadata.js +12 -9
  35. package/dist/Chat/ChatSendButton.d.ts +2 -1
  36. package/dist/Chat/ChatSendButton.d.ts.map +1 -1
  37. package/dist/Chat/ChatSendButton.js +6 -4
  38. package/dist/Chat/index.d.ts +1 -1
  39. package/dist/Chat/index.d.ts.map +1 -1
  40. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  41. package/dist/CheckboxInput/CheckboxInput.js +12 -2
  42. package/dist/Citation/Citation.d.ts +1 -1
  43. package/dist/Citation/Citation.d.ts.map +1 -1
  44. package/dist/Citation/Citation.js +3 -2
  45. package/dist/CodeBlock/highlightRanges.d.ts.map +1 -1
  46. package/dist/CodeBlock/highlightRanges.js +14 -3
  47. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  48. package/dist/Collapsible/Collapsible.js +6 -1
  49. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  50. package/dist/CommandPalette/CommandPaletteInput.js +1 -1
  51. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  52. package/dist/ComplexSelector/ComplexSelector.js +1 -1
  53. package/dist/DateInput/DateInput.d.ts.map +1 -1
  54. package/dist/DateInput/DateInput.js +4 -4
  55. package/dist/DateInput/NativeDateField.d.ts.map +1 -1
  56. package/dist/DateInput/NativeDateField.js +16 -16
  57. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  58. package/dist/DateInput/TouchDateField.js +2 -2
  59. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  60. package/dist/DateRangeInput/DateRangeInput.js +4 -4
  61. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  62. package/dist/DateTimeInput/DateTimeInput.js +8 -8
  63. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  64. package/dist/DateTimeInput/TouchDateTimeField.js +4 -4
  65. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts +9 -3
  66. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts.map +1 -1
  67. package/dist/DateTimeInput/nativePickerSegmentStyles.js +3 -3
  68. package/dist/Dialog/DialogHeader.d.ts +8 -1
  69. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  70. package/dist/Dialog/DialogHeader.js +13 -4
  71. package/dist/Field/InputClearButton.d.ts +4 -2
  72. package/dist/Field/InputClearButton.d.ts.map +1 -1
  73. package/dist/Field/InputClearButton.js +4 -2
  74. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  75. package/dist/Field/PanelSearchInput.js +1 -1
  76. package/dist/FileInput/FileInput.d.ts.map +1 -1
  77. package/dist/FileInput/FileInput.js +7 -7
  78. package/dist/Icon/Icon.d.ts +6 -31
  79. package/dist/Icon/Icon.d.ts.map +1 -1
  80. package/dist/Icon/Icon.js +8 -71
  81. package/dist/Icon/IconDefaultSizeContext.d.ts +4 -0
  82. package/dist/Icon/IconDefaultSizeContext.d.ts.map +1 -0
  83. package/dist/Icon/IconDefaultSizeContext.js +18 -0
  84. package/dist/Icon/IconSize.stylex.d.ts +65 -0
  85. package/dist/Icon/IconSize.stylex.d.ts.map +1 -0
  86. package/dist/Icon/IconSize.stylex.js +75 -0
  87. package/dist/Item/Item.d.ts +1 -1
  88. package/dist/Item/Item.d.ts.map +1 -1
  89. package/dist/Item/Item.js +4 -3
  90. package/dist/Kbd/Kbd.d.ts +5 -3
  91. package/dist/Kbd/Kbd.d.ts.map +1 -1
  92. package/dist/Kbd/Kbd.js +36 -42
  93. package/dist/Link/Link.d.ts.map +1 -1
  94. package/dist/Link/Link.js +6 -2
  95. package/dist/Link/useLinkComponent.d.ts +5 -15
  96. package/dist/Link/useLinkComponent.d.ts.map +1 -1
  97. package/dist/Link/useLinkComponent.js +34 -51
  98. package/dist/List/List.d.ts +19 -1
  99. package/dist/List/List.d.ts.map +1 -1
  100. package/dist/List/List.js +9 -2
  101. package/dist/List/ListContext.d.ts +1 -0
  102. package/dist/List/ListContext.d.ts.map +1 -1
  103. package/dist/List/ListContext.js +2 -1
  104. package/dist/List/ListItem.d.ts +1 -1
  105. package/dist/List/ListItem.d.ts.map +1 -1
  106. package/dist/List/ListItem.js +9 -2
  107. package/dist/Markdown/Markdown.d.ts +8 -2
  108. package/dist/Markdown/Markdown.d.ts.map +1 -1
  109. package/dist/Markdown/Markdown.fr23.bench.d.ts +2 -0
  110. package/dist/Markdown/Markdown.fr23.bench.d.ts.map +1 -0
  111. package/dist/Markdown/Markdown.fr23.bench.js +150 -0
  112. package/dist/Markdown/Markdown.fr23.sampling.d.ts +2 -0
  113. package/dist/Markdown/Markdown.fr23.sampling.d.ts.map +1 -0
  114. package/dist/Markdown/Markdown.fr23.sampling.js +43 -0
  115. package/dist/Markdown/Markdown.js +262 -109
  116. package/dist/Markdown/ast.d.ts +162 -0
  117. package/dist/Markdown/ast.d.ts.map +1 -0
  118. package/dist/Markdown/ast.js +74 -0
  119. package/dist/Markdown/index.d.ts +5 -3
  120. package/dist/Markdown/index.d.ts.map +1 -1
  121. package/dist/Markdown/index.js +3 -2
  122. package/dist/Markdown/parser/index.d.ts +10 -0
  123. package/dist/Markdown/parser/index.d.ts.map +1 -0
  124. package/dist/Markdown/parser/index.js +10 -0
  125. package/dist/Markdown/parser.d.ts +126 -58
  126. package/dist/Markdown/parser.d.ts.map +1 -1
  127. package/dist/Markdown/parser.js +726 -177
  128. package/dist/Markdown/plugins/frontmatter.d.ts +32 -0
  129. package/dist/Markdown/plugins/frontmatter.d.ts.map +1 -0
  130. package/dist/Markdown/plugins/frontmatter.js +132 -0
  131. package/dist/Markdown/plugins/index.d.ts +17 -0
  132. package/dist/Markdown/plugins/index.d.ts.map +1 -0
  133. package/dist/Markdown/plugins/index.js +14 -0
  134. package/dist/Markdown/plugins/protocol.d.ts +191 -0
  135. package/dist/Markdown/plugins/protocol.d.ts.map +1 -0
  136. package/dist/Markdown/plugins/protocol.js +957 -0
  137. package/dist/Markdown/plugins/semanticFence.d.ts +36 -0
  138. package/dist/Markdown/plugins/semanticFence.d.ts.map +1 -0
  139. package/dist/Markdown/plugins/semanticFence.js +213 -0
  140. package/dist/Markdown/plugins/softBreaks.d.ts +3 -0
  141. package/dist/Markdown/plugins/softBreaks.d.ts.map +1 -0
  142. package/dist/Markdown/plugins/softBreaks.js +172 -0
  143. package/dist/Markdown/plugins/sourceDecoration.d.ts +76 -0
  144. package/dist/Markdown/plugins/sourceDecoration.d.ts.map +1 -0
  145. package/dist/Markdown/plugins/sourceDecoration.js +393 -0
  146. package/dist/Markdown/plugins/textTransform.d.ts +30 -0
  147. package/dist/Markdown/plugins/textTransform.d.ts.map +1 -0
  148. package/dist/Markdown/plugins/textTransform.js +374 -0
  149. package/dist/Markdown/remark.d.ts +196 -0
  150. package/dist/Markdown/remark.d.ts.map +1 -0
  151. package/dist/Markdown/remark.js +1062 -0
  152. package/dist/Markdown/url.d.ts +6 -0
  153. package/dist/Markdown/url.d.ts.map +1 -0
  154. package/dist/Markdown/url.js +31 -0
  155. package/dist/Markdown/utils.d.ts +4 -2
  156. package/dist/Markdown/utils.d.ts.map +1 -1
  157. package/dist/Markdown/utils.js +2 -1
  158. package/dist/MetadataList/MetadataList.js +3 -3
  159. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  160. package/dist/NumberInput/NumberInput.js +4 -4
  161. package/dist/Outline/index.d.ts +1 -0
  162. package/dist/Outline/index.d.ts.map +1 -1
  163. package/dist/Outline/parseOutlineFromMarkdown.d.ts +7 -1
  164. package/dist/Outline/parseOutlineFromMarkdown.d.ts.map +1 -1
  165. package/dist/Outline/parseOutlineFromMarkdown.js +14 -8
  166. package/dist/Outline/useOutlineFromMarkdown.d.ts +3 -1
  167. package/dist/Outline/useOutlineFromMarkdown.d.ts.map +1 -1
  168. package/dist/Outline/useOutlineFromMarkdown.js +8 -3
  169. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  170. package/dist/PowerSearch/PowerSearchEditPopover.js +46 -30
  171. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  172. package/dist/PowerSearch/PowerSearchValueEditor.js +5 -0
  173. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  174. package/dist/ProgressBar/ProgressBar.js +36 -31
  175. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  176. package/dist/RadioList/RadioListItem.js +13 -1
  177. package/dist/ScrollableArea/ScrollableArea.d.ts +1 -0
  178. package/dist/ScrollableArea/ScrollableArea.d.ts.map +1 -1
  179. package/dist/ScrollableArea/ScrollableArea.js +1 -0
  180. package/dist/SegmentedControl/SegmentedControl.d.ts +1 -1
  181. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  182. package/dist/SegmentedControl/SegmentedControl.js +1 -0
  183. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  184. package/dist/SegmentedControl/SegmentedControlItem.js +5 -5
  185. package/dist/Selector/Selector.d.ts +9 -7
  186. package/dist/Selector/Selector.d.ts.map +1 -1
  187. package/dist/Selector/Selector.js +16 -7
  188. package/dist/SideNav/SideNav.d.ts +2 -1
  189. package/dist/SideNav/SideNav.d.ts.map +1 -1
  190. package/dist/SideNav/SideNav.js +9 -3
  191. package/dist/Slider/Slider.d.ts.map +1 -1
  192. package/dist/Slider/Slider.js +28 -12
  193. package/dist/Spinner/Spinner.d.ts.map +1 -1
  194. package/dist/Spinner/Spinner.js +23 -7
  195. package/dist/Switch/Switch.d.ts.map +1 -1
  196. package/dist/Switch/Switch.js +11 -0
  197. package/dist/TabList/Tab.d.ts +1 -1
  198. package/dist/TabList/Tab.d.ts.map +1 -1
  199. package/dist/TabList/Tab.js +20 -7
  200. package/dist/Table/Table.d.ts +1 -0
  201. package/dist/Table/Table.d.ts.map +1 -1
  202. package/dist/Table/Table.js +29 -13
  203. package/dist/TextArea/TextArea.d.ts.map +1 -1
  204. package/dist/TextArea/TextArea.js +1 -1
  205. package/dist/TextInput/TextInput.d.ts.map +1 -1
  206. package/dist/TextInput/TextInput.js +2 -2
  207. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  208. package/dist/TimeInput/TimeInput.js +4 -4
  209. package/dist/Timer/Timer.d.ts +49 -0
  210. package/dist/Timer/Timer.d.ts.map +1 -0
  211. package/dist/Timer/Timer.js +158 -0
  212. package/dist/Timer/index.d.ts +9 -0
  213. package/dist/Timer/index.d.ts.map +1 -0
  214. package/dist/Timer/index.js +10 -0
  215. package/dist/ToggleButton/ToggleButton.d.ts +9 -6
  216. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  217. package/dist/ToggleButton/ToggleButton.js +15 -27
  218. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  219. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  220. package/dist/TopNav/TopNavMenu.js +3 -2
  221. package/dist/TreeList/TreeList.d.ts.map +1 -1
  222. package/dist/TreeList/TreeList.js +3 -0
  223. package/dist/TreeList/TreeListItem.d.ts +6 -1
  224. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  225. package/dist/TreeList/TreeListItem.js +12 -2
  226. package/dist/TreeList/TreeListTypes.d.ts +8 -1
  227. package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
  228. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  229. package/dist/Typeahead/BaseTypeahead.js +16 -7
  230. package/dist/astryx.css +27 -11
  231. package/dist/hooks/scrollKeyboardDelegation.d.ts +3 -0
  232. package/dist/hooks/scrollKeyboardDelegation.d.ts.map +1 -0
  233. package/dist/hooks/scrollKeyboardDelegation.js +146 -0
  234. package/dist/hooks/useClickableContainer.d.ts +10 -1
  235. package/dist/hooks/useClickableContainer.d.ts.map +1 -1
  236. package/dist/hooks/useClickableContainer.js +15 -4
  237. package/dist/hooks/useScrollableArea.d.ts +6 -2
  238. package/dist/hooks/useScrollableArea.d.ts.map +1 -1
  239. package/dist/hooks/useScrollableArea.js +17 -5
  240. package/dist/index.d.ts +1 -0
  241. package/dist/index.d.ts.map +1 -1
  242. package/dist/index.js +3 -0
  243. package/dist/theme/declarationBoundary.d.ts +17 -0
  244. package/dist/theme/declarationBoundary.d.ts.map +1 -0
  245. package/dist/theme/declarationBoundary.js +343 -0
  246. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  247. package/dist/theme/derivedVarRegistry.js +4 -0
  248. package/dist/theme/generateThemeRules.d.ts +13 -7
  249. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  250. package/dist/theme/generateThemeRules.js +140 -34
  251. package/dist/utils/interactionOverlay.stylex.d.ts +8 -0
  252. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  253. package/dist/utils/interactionOverlay.stylex.js +9 -0
  254. package/dist/utils/safeUrl.d.ts +11 -0
  255. package/dist/utils/safeUrl.d.ts.map +1 -0
  256. package/dist/utils/safeUrl.js +78 -0
  257. package/locales/af-ZA.json +530 -1
  258. package/locales/ar-SA.json +490 -1
  259. package/locales/ca-ES.json +514 -1
  260. package/locales/cs-CZ.json +498 -1
  261. package/locales/da-DK.json +522 -1
  262. package/locales/de-DE.json +522 -1
  263. package/locales/el-GR.json +498 -1
  264. package/locales/es-ES.json +510 -1
  265. package/locales/fi-FI.json +498 -1
  266. package/locales/fr-FR.json +534 -1
  267. package/locales/he-IL.json +498 -1
  268. package/locales/hu-HU.json +498 -1
  269. package/locales/it-IT.json +510 -1
  270. package/locales/ja-JP.json +490 -1
  271. package/locales/ko-KR.json +498 -1
  272. package/locales/nl-NL.json +534 -1
  273. package/locales/no-NO.json +510 -1
  274. package/locales/pl-PL.json +506 -1
  275. package/locales/pt-BR.json +506 -1
  276. package/locales/pt-PT.json +506 -1
  277. package/locales/ro-RO.json +506 -1
  278. package/locales/ru-RU.json +498 -1
  279. package/locales/sr-SP.json +498 -1
  280. package/locales/sv-SE.json +502 -1
  281. package/locales/tr-TR.json +498 -1
  282. package/locales/uk-UA.json +498 -1
  283. package/locales/vi-VN.json +502 -1
  284. package/locales/zh-CN.json +490 -1
  285. package/locales/zh-TW.json +490 -1
  286. package/package.json +24 -4
  287. package/src/BottomSheet/BottomSheet.doc.mjs +8 -1
  288. package/src/BottomSheet/BottomSheet.spec.md +46 -20
  289. package/src/BottomSheet/BottomSheet.test.tsx +6 -3
  290. package/src/BottomSheet/BottomSheet.tsx +3 -1
  291. package/src/BottomSheet/BottomSheetKeyboard.test.tsx +195 -0
  292. package/src/BottomSheet/BottomSheetPanel.test.tsx +11 -1
  293. package/src/BottomSheet/BottomSheetPanel.tsx +49 -16
  294. package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +344 -0
  295. package/src/Button/Button.doc.mjs +5 -5
  296. package/src/Button/Button.tsx +15 -13
  297. package/src/Button/__tests__/Button.a11y.chromium.spec.ts +17 -1
  298. package/src/Button/__tests__/Button.a11y.known-failures.ts +0 -29
  299. package/src/Button/__tests__/Button.a11y.renders.tsx +9 -2
  300. package/src/Button/__tests__/Button.a11y.states.ts +9 -0
  301. package/src/Chat/ChatComposer.doc.mjs +14 -0
  302. package/src/Chat/ChatComposer.spec.md +230 -0
  303. package/src/Chat/ChatComposer.test.tsx +57 -0
  304. package/src/Chat/ChatComposer.tsx +21 -9
  305. package/src/Chat/ChatComposerDrawer.doc.mjs +63 -5
  306. package/src/Chat/ChatComposerDrawer.spec.md +267 -0
  307. package/src/Chat/ChatComposerDrawer.test.tsx +81 -12
  308. package/src/Chat/ChatComposerDrawer.tsx +38 -9
  309. package/src/Chat/ChatComposerInput.doc.mjs +114 -26
  310. package/src/Chat/ChatComposerInput.spec.md +185 -0
  311. package/src/Chat/ChatComposerInput.test.tsx +113 -3
  312. package/src/Chat/ChatComposerInput.tsx +78 -13
  313. package/src/Chat/ChatComposerTokenElement.spec.md +152 -0
  314. package/src/Chat/ChatComposerTokenElement.test.tsx +85 -0
  315. package/src/Chat/ChatDictationButton.doc.mjs +3 -3
  316. package/src/Chat/ChatDictationButton.spec.md +160 -0
  317. package/src/Chat/ChatDictationButton.test.tsx +92 -27
  318. package/src/Chat/ChatDictationButton.tsx +8 -6
  319. package/src/Chat/ChatLayout.doc.mjs +12 -4
  320. package/src/Chat/ChatLayout.spec.md +271 -0
  321. package/src/Chat/ChatLayout.test.tsx +28 -0
  322. package/src/Chat/ChatLayout.tsx +19 -0
  323. package/src/Chat/ChatLayoutScrollButton.spec.md +338 -0
  324. package/src/Chat/ChatLayoutScrollButton.test.tsx +31 -0
  325. package/src/Chat/ChatLayoutScrollButton.tsx +31 -14
  326. package/src/Chat/ChatMessageBubble.doc.mjs +28 -15
  327. package/src/Chat/ChatMessageBubble.spec.md +263 -0
  328. package/src/Chat/ChatMessageBubble.test.tsx +93 -0
  329. package/src/Chat/ChatMessageBubble.tsx +8 -3
  330. package/src/Chat/ChatMessageList.spec.md +222 -0
  331. package/src/Chat/ChatMessageList.test.tsx +64 -2
  332. package/src/Chat/ChatMessageList.tsx +4 -3
  333. package/src/Chat/ChatMessageMetadata.doc.mjs +57 -3
  334. package/src/Chat/ChatMessageMetadata.spec.md +220 -0
  335. package/src/Chat/ChatMessageMetadata.test.tsx +34 -0
  336. package/src/Chat/ChatMessageMetadata.tsx +13 -13
  337. package/src/Chat/ChatSendButton.doc.mjs +32 -0
  338. package/src/Chat/ChatSendButton.spec.md +227 -0
  339. package/src/Chat/ChatSendButton.test.tsx +128 -8
  340. package/src/Chat/ChatSendButton.tsx +6 -4
  341. package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +514 -0
  342. package/src/Chat/__tests__/ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts +740 -0
  343. package/src/Chat/__tests__/ChatMessageBubble.a11y.chromium.spec.ts +457 -0
  344. package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.test.ts +91 -0
  345. package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.ts +91 -0
  346. package/src/Chat/__tests__/ChatMessageList.a11y.chromium.spec.ts +456 -0
  347. package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +413 -0
  348. package/src/Chat/__tests__/ChatSendButton.a11y.chromium.spec.ts +1522 -0
  349. package/src/Chat/index.ts +1 -0
  350. package/src/CheckboxInput/CheckboxInput.doc.mjs +11 -0
  351. package/src/CheckboxInput/CheckboxInput.test.tsx +34 -0
  352. package/src/CheckboxInput/CheckboxInput.tsx +21 -1
  353. package/src/Citation/Citation.doc.mjs +2 -2
  354. package/src/Citation/Citation.test.tsx +17 -0
  355. package/src/Citation/Citation.tsx +4 -2
  356. package/src/ClickableCard/ClickableCard.doc.mjs +2 -2
  357. package/src/ClickableCard/ClickableCard.test.tsx +102 -5
  358. package/src/CodeBlock/highlightRanges.test.ts +143 -1
  359. package/src/CodeBlock/highlightRanges.ts +15 -5
  360. package/src/Collapsible/Collapsible.doc.mjs +11 -0
  361. package/src/Collapsible/Collapsible.test.tsx +21 -0
  362. package/src/Collapsible/Collapsible.tsx +5 -0
  363. package/src/CommandPalette/CommandPaletteInput.tsx +6 -1
  364. package/src/ComplexSelector/ComplexSelector.tsx +6 -1
  365. package/src/DateInput/DateInput.tsx +6 -1
  366. package/src/DateInput/NativeDateField.tsx +24 -8
  367. package/src/DateInput/TouchDateField.tsx +6 -2
  368. package/src/DateRangeInput/DateRangeInput.tsx +6 -1
  369. package/src/DateTimeInput/DateTimeInput.tsx +6 -1
  370. package/src/DateTimeInput/TouchDateTimeField.tsx +6 -1
  371. package/src/DateTimeInput/nativePickerSegmentStyles.ts +24 -8
  372. package/src/Dialog/Dialog.doc.mjs +2 -0
  373. package/src/Dialog/DialogHeader.doc.mjs +22 -0
  374. package/src/Dialog/DialogHeader.test.tsx +167 -3
  375. package/src/Dialog/DialogHeader.tsx +37 -6
  376. package/src/Dialog/modules/DialogHeader.spec.md +101 -42
  377. package/src/DropdownMenu/DropdownMenu.test.tsx +5 -2
  378. package/src/Field/InputClearButton.test.tsx +17 -3
  379. package/src/Field/InputClearButton.tsx +5 -2
  380. package/src/Field/PanelSearchInput.tsx +5 -2
  381. package/src/FieldStatus/__tests__/StatusMessage.a11y.states.ts +1 -1
  382. package/src/FileInput/FileInput.tsx +11 -2
  383. package/src/Icon/Icon.doc.mjs +7 -5
  384. package/src/Icon/Icon.spec.md +81 -40
  385. package/src/Icon/Icon.test.tsx +6 -3
  386. package/src/Icon/Icon.tsx +20 -68
  387. package/src/Icon/IconDefaultSizeContext.ts +23 -0
  388. package/src/Icon/IconSize.stylex.ts +70 -0
  389. package/src/IconButton/IconButton.doc.mjs +3 -3
  390. package/src/IconButton/IconButton.test.tsx +40 -0
  391. package/src/Item/Item.doc.mjs +6 -2
  392. package/src/Item/Item.tsx +9 -3
  393. package/src/Kbd/Kbd.doc.mjs +3 -3
  394. package/src/Kbd/Kbd.test.tsx +57 -1
  395. package/src/Kbd/Kbd.tsx +57 -37
  396. package/src/Layout/LayoutFooter.doc.mjs +17 -0
  397. package/src/Link/Link.doc.mjs +17 -4
  398. package/src/Link/Link.test.tsx +24 -0
  399. package/src/Link/Link.tsx +5 -0
  400. package/src/Link/LinkProvider.doc.mjs +2 -2
  401. package/src/Link/__tests__/Link.navigation.a11y.chromium.spec.ts +261 -0
  402. package/src/Link/useLinkComponent.test.tsx +333 -0
  403. package/src/Link/useLinkComponent.ts +29 -57
  404. package/src/List/List.doc.mjs +6 -0
  405. package/src/List/List.spec.md +200 -0
  406. package/src/List/List.test.tsx +117 -1
  407. package/src/List/List.tsx +22 -2
  408. package/src/List/ListContext.tsx +3 -1
  409. package/src/List/ListItem.doc.mjs +2 -2
  410. package/src/List/ListItem.source-build.test.mjs +41 -0
  411. package/src/List/ListItem.tsx +26 -2
  412. package/src/Markdown/Markdown.doc.mjs +300 -2
  413. package/src/Markdown/Markdown.fr23.bench.ts +174 -0
  414. package/src/Markdown/Markdown.fr23.perf.test.ts +249 -0
  415. package/src/Markdown/Markdown.fr23.sampling.ts +49 -0
  416. package/src/Markdown/Markdown.helpers.perf.test.ts +489 -0
  417. package/src/Markdown/Markdown.public.test.ts +130 -3
  418. package/src/Markdown/Markdown.renderBoundary.test.tsx +72 -0
  419. package/src/Markdown/Markdown.spec.md +210 -45
  420. package/src/Markdown/Markdown.test.tsx +87 -3
  421. package/src/Markdown/Markdown.tsx +414 -135
  422. package/src/Markdown/ast.test.ts +307 -0
  423. package/src/Markdown/ast.ts +337 -0
  424. package/src/Markdown/incremental.test.ts +43 -0
  425. package/src/Markdown/index.ts +37 -1
  426. package/src/Markdown/modules/remark.spec.md +269 -0
  427. package/src/Markdown/modules/softBreaks.spec.md +137 -0
  428. package/src/Markdown/parser/index.ts +64 -0
  429. package/src/Markdown/parser.public.test.ts +103 -0
  430. package/src/Markdown/parser.test.ts +38 -6
  431. package/src/Markdown/parser.ts +1221 -242
  432. package/src/Markdown/plugins/frontmatter.test.tsx +125 -0
  433. package/src/Markdown/plugins/frontmatter.ts +198 -0
  434. package/src/Markdown/plugins/index.ts +54 -0
  435. package/src/Markdown/plugins/protocol.test.tsx +1022 -0
  436. package/src/Markdown/plugins/protocol.ts +1618 -0
  437. package/src/Markdown/plugins/semanticFence.test.tsx +546 -0
  438. package/src/Markdown/plugins/semanticFence.ts +424 -0
  439. package/src/Markdown/plugins/softBreaks.test.tsx +172 -0
  440. package/src/Markdown/plugins/softBreaks.ts +169 -0
  441. package/src/Markdown/plugins/sourceDecoration.test.tsx +799 -0
  442. package/src/Markdown/plugins/sourceDecoration.ts +539 -0
  443. package/src/Markdown/plugins/textTransform.test.ts +467 -0
  444. package/src/Markdown/plugins/textTransform.ts +554 -0
  445. package/src/Markdown/remark.test.tsx +1877 -0
  446. package/src/Markdown/remark.ts +1574 -0
  447. package/src/Markdown/url.ts +36 -0
  448. package/src/Markdown/utils.ts +13 -1
  449. package/src/MetadataList/MetadataList.test.tsx +4 -2
  450. package/src/MetadataList/MetadataList.tsx +3 -3
  451. package/src/MultiSelector/MultiSelector.test.tsx +1 -35
  452. package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +128 -0
  453. package/src/NumberInput/NumberInput.tsx +6 -1
  454. package/src/Outline/Outline.doc.mjs +7 -5
  455. package/src/Outline/Outline.spec.md +1 -1
  456. package/src/Outline/index.ts +1 -0
  457. package/src/Outline/modules/parseOutlineFromMarkdown.spec.md +142 -0
  458. package/src/Outline/parseOutlineFromMarkdown.ts +40 -10
  459. package/src/Outline/useOutlineFromMarkdown.ts +15 -3
  460. package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
  461. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +150 -1
  462. package/src/PowerSearch/PowerSearchEditPopover.tsx +51 -28
  463. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +51 -0
  464. package/src/PowerSearch/PowerSearchValueEditor.tsx +4 -0
  465. package/src/ProgressBar/ProgressBar.test.tsx +29 -11
  466. package/src/ProgressBar/ProgressBar.tsx +59 -72
  467. package/src/RadioList/RadioList.doc.mjs +11 -0
  468. package/src/RadioList/RadioList.test.tsx +32 -0
  469. package/src/RadioList/RadioListItem.tsx +25 -1
  470. package/src/ScrollableArea/ScrollableArea.tsx +1 -0
  471. package/src/ScrollableArea/modules/useScrollableArea.spec.md +50 -22
  472. package/src/SegmentedControl/SegmentedControl.doc.mjs +2 -2
  473. package/src/SegmentedControl/SegmentedControl.test.tsx +61 -0
  474. package/src/SegmentedControl/SegmentedControl.tsx +2 -1
  475. package/src/SegmentedControl/SegmentedControlItem.tsx +6 -9
  476. package/src/Selector/Selector.doc.mjs +3 -3
  477. package/src/Selector/Selector.spec.md +51 -49
  478. package/src/Selector/Selector.test.tsx +61 -55
  479. package/src/Selector/Selector.tsx +34 -15
  480. package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +130 -0
  481. package/src/Selector/__tests__/Listbox.a11y.dom.ts +38 -0
  482. package/src/Selector/__tests__/Listbox.a11y.inventory.test.ts +63 -0
  483. package/src/Selector/__tests__/Listbox.a11y.known-failures.ts +37 -0
  484. package/src/Selector/__tests__/Listbox.a11y.states.ts +232 -0
  485. package/src/Selector/__tests__/Selector.a11y.chromium.spec.ts +45 -0
  486. package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +121 -0
  487. package/src/SideNav/SideNav.doc.mjs +1 -1
  488. package/src/SideNav/SideNav.test.tsx +10 -0
  489. package/src/SideNav/SideNav.tsx +14 -2
  490. package/src/Slider/Slider.doc.mjs +17 -3
  491. package/src/Slider/Slider.test.tsx +221 -0
  492. package/src/Slider/Slider.tsx +40 -9
  493. package/src/Spinner/Spinner.test.tsx +4 -0
  494. package/src/Spinner/Spinner.tsx +31 -18
  495. package/src/Switch/Switch.doc.mjs +11 -0
  496. package/src/Switch/Switch.test.tsx +16 -0
  497. package/src/Switch/Switch.tsx +28 -0
  498. package/src/TabList/Tab.tsx +35 -7
  499. package/src/TabList/TabList.doc.mjs +11 -0
  500. package/src/TabList/TabList.spec.md +204 -0
  501. package/src/TabList/TabList.test.tsx +66 -0
  502. package/src/TabList/__tests__/Tabs.a11y.known-failures.ts +1 -34
  503. package/src/Table/Table.doc.mjs +1 -1
  504. package/src/Table/Table.spec.md +54 -40
  505. package/src/Table/Table.test.tsx +83 -10
  506. package/src/Table/Table.tsx +30 -22
  507. package/src/Table/__tests__/TableScroll.a11y.chromium.spec.ts +137 -0
  508. package/src/TextArea/TextArea.tsx +6 -1
  509. package/src/TextInput/TextInput.test.tsx +20 -1
  510. package/src/TextInput/TextInput.tsx +6 -1
  511. package/src/TimeInput/TimeInput.tsx +6 -1
  512. package/src/Timer/Timer.doc.mjs +183 -0
  513. package/src/Timer/Timer.spec.md +215 -0
  514. package/src/Timer/Timer.test.tsx +302 -0
  515. package/src/Timer/Timer.tsx +258 -0
  516. package/src/Timer/index.ts +11 -0
  517. package/src/ToggleButton/ToggleButton.doc.mjs +3 -3
  518. package/src/ToggleButton/ToggleButton.test.tsx +299 -4
  519. package/src/ToggleButton/ToggleButton.tsx +26 -33
  520. package/src/ToggleButton/ToggleButtonGroup.doc.mjs +3 -3
  521. package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +209 -0
  522. package/src/Token/Token.doc.mjs +2 -2
  523. package/src/Tokenizer/Tokenizer.spec.md +142 -75
  524. package/src/TopNav/TopNavMenu.doc.mjs +2 -2
  525. package/src/TopNav/TopNavMenu.test.tsx +30 -0
  526. package/src/TopNav/TopNavMenu.tsx +7 -2
  527. package/src/TreeList/TreeList.doc.mjs +3 -3
  528. package/src/TreeList/TreeList.spec.md +123 -75
  529. package/src/TreeList/TreeList.test.tsx +29 -0
  530. package/src/TreeList/TreeList.tsx +3 -0
  531. package/src/TreeList/TreeListItem.tsx +15 -1
  532. package/src/TreeList/TreeListTypes.ts +11 -1
  533. package/src/Typeahead/BaseTypeahead.spec.md +4 -3
  534. package/src/Typeahead/BaseTypeahead.tsx +21 -7
  535. package/src/Typeahead/Typeahead.test.tsx +53 -0
  536. package/src/__tests__/PressedState.a11y.chromium.spec.ts +813 -0
  537. package/src/__tests__/pressState.ts +93 -0
  538. package/src/hooks/scrollKeyboardDelegation.test.ts +155 -0
  539. package/src/hooks/scrollKeyboardDelegation.ts +233 -0
  540. package/src/hooks/useClickableContainer.test.tsx +236 -0
  541. package/src/hooks/useClickableContainer.ts +20 -4
  542. package/src/hooks/useScrollableArea.doc.mjs +15 -3
  543. package/src/hooks/useScrollableArea.test.tsx +59 -1
  544. package/src/hooks/useScrollableArea.ts +34 -10
  545. package/src/index.ts +3 -0
  546. package/src/inputFontFloor.test.ts +106 -0
  547. package/src/tailwind-theme.css +0 -6
  548. package/src/theme/Theme.test.tsx +32 -0
  549. package/src/theme/declarationBoundary.test.ts +126 -0
  550. package/src/theme/declarationBoundary.ts +347 -0
  551. package/src/theme/derivedVarRegistry.test.ts +7 -0
  552. package/src/theme/derivedVarRegistry.ts +1 -0
  553. package/src/theme/generateThemeRules.test.ts +526 -1
  554. package/src/theme/generateThemeRules.ts +228 -50
  555. package/src/theme/tokenValueCompat.test.ts +4 -1
  556. package/src/utils/interactionOverlay.stylex.ts +20 -0
  557. package/src/utils/safeUrl.test.ts +88 -0
  558. package/src/utils/safeUrl.ts +85 -0
@@ -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
@@ -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'],
@@ -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'],
@@ -173,9 +173,14 @@ const styles = stylex.create({
173
173
  borderStyle: 'none',
174
174
  padding: 0,
175
175
  fontFamily: typographyVars['--font-family-body'],
176
+ // The 16px floor is iOS-only: iOS Safari zooms the page when a focused
177
+ // control sits under 16px, and only iOS WebKit implements
178
+ // -webkit-touch-callout to key the coarse-pointer floor to it.
176
179
  fontSize: {
177
180
  default: typeScaleVars['--text-body-size'],
178
- '@media (pointer: coarse)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
181
+ '@media (pointer: coarse)': {
182
+ '@supports (-webkit-touch-callout: none)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
183
+ },
179
184
  },
180
185
  lineHeight: typeScaleVars['--text-body-leading'],
181
186
  color: colorVars['--color-text-primary'],
@@ -182,9 +182,14 @@ const styles = stylex.create({
182
182
  borderStyle: 'none',
183
183
  padding: 0,
184
184
  fontFamily: typographyVars['--font-family-body'],
185
+ // The 16px floor is iOS-only: iOS Safari zooms the page when a focused
186
+ // control sits under 16px, and only iOS WebKit implements
187
+ // -webkit-touch-callout to key the coarse-pointer floor to it.
185
188
  fontSize: {
186
189
  default: typeScaleVars['--text-body-size'],
187
- '@media (pointer: coarse)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
190
+ '@media (pointer: coarse)': {
191
+ '@supports (-webkit-touch-callout: none)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
192
+ },
188
193
  },
189
194
  lineHeight: typeScaleVars['--text-body-leading'],
190
195
  color: colorVars['--color-text-primary'],
@@ -42,21 +42,34 @@ export const nativePickerSegmentStyles = stylex.create({
42
42
  borderStyle: 'none',
43
43
  padding: 0,
44
44
  fontFamily: typographyVars['--font-family-body'],
45
- // Below 16px iOS zooms the page when the field takes focus.
45
+ // Below 16px iOS zooms the page when the field takes focus. Only iOS
46
+ // WebKit implements -webkit-touch-callout, so the coarse-pointer floor is
47
+ // keyed to iOS alone.
46
48
  fontSize: {
47
49
  default: typeScaleVars['--text-body-size'],
48
- '@media (pointer: coarse)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
50
+ '@media (pointer: coarse)': {
51
+ '@supports (-webkit-touch-callout: none)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
52
+ },
49
53
  },
50
54
  lineHeight: typeScaleVars['--text-body-leading'],
51
55
  color: colorVars['--color-text-primary'],
52
56
  backgroundColor: 'transparent',
53
57
  outline: 'none',
54
58
  // Native date/time controls size from their internal edit fields. Pin the
55
- // box to one text line so both segments stay aligned.
56
- height: stylex.firstThatWorks(
57
- '1lh',
58
- `calc(max(1rem, ${typeScaleVars['--text-body-size']}) * ${typeScaleVars['--text-body-leading']})`,
59
- ),
59
+ // box to one text line so both segments stay aligned. The calc fallback
60
+ // mirrors the iOS-only floor above; browsers with `1lh` track it for free.
61
+ height: {
62
+ default: stylex.firstThatWorks(
63
+ '1lh',
64
+ `calc(${typeScaleVars['--text-body-size']} * ${typeScaleVars['--text-body-leading']})`,
65
+ ),
66
+ '@media (pointer: coarse)': {
67
+ '@supports (-webkit-touch-callout: none)': stylex.firstThatWorks(
68
+ '1lh',
69
+ `calc(max(1rem, ${typeScaleVars['--text-body-size']}) * ${typeScaleVars['--text-body-leading']})`,
70
+ ),
71
+ },
72
+ },
60
73
  WebkitAppearance: 'none',
61
74
  appearance: 'none',
62
75
  // DateTimeInput renders its own calendar/clock affordances.
@@ -101,9 +114,12 @@ export const nativePickerSegmentStyles = stylex.create({
101
114
  insetInlineEnd: 0,
102
115
  insetBlock: 0,
103
116
  display: 'block',
117
+ // The same iOS-only floor as the input it covers, shared baselines.
104
118
  fontSize: {
105
119
  default: typeScaleVars['--text-body-size'],
106
- '@media (pointer: coarse)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
120
+ '@media (pointer: coarse)': {
121
+ '@supports (-webkit-touch-callout: none)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
122
+ },
107
123
  },
108
124
  lineHeight: typeScaleVars['--text-body-leading'],
109
125
  pointerEvents: 'none',
@@ -31,7 +31,9 @@ export const docs = {
31
31
  targets: [
32
32
  {className: 'astryx-dialog', visualProps: ['variant']},
33
33
  {className: 'astryx-dialog-header'},
34
+ {className: 'astryx-dialog-header-start-content'},
34
35
  {className: 'astryx-dialog-header-title-block'},
36
+ {className: 'astryx-dialog-header-end-content'},
35
37
  {className: 'astryx-dialog-header-close-icon'},
36
38
  ],
37
39
  vars: [
@@ -12,7 +12,9 @@ export const docs = {
12
12
  description: 'Use DialogHeader to give a dialog a labelled title area and optional close control.',
13
13
  anatomy: [
14
14
  {name: 'Header row', required: true, description: 'Arranges the title block, optional start/end content, and close control.'},
15
+ {name: 'Start content', required: false, description: 'Wraps optional leading content.'},
15
16
  {name: 'Title block', required: true, description: 'Groups the title and optional subtitle.'},
17
+ {name: 'End content', required: false, description: 'Groups optional trailing content with the optional close control.'},
16
18
  {name: 'Close icon', required: false, description: 'Visual close glyph inside the close button.'},
17
19
  ],
18
20
  },
@@ -66,6 +68,11 @@ export const docs = {
66
68
  },
67
69
  ],
68
70
  },
71
+ {
72
+ name: 'endContentEdgeCompensation',
73
+ type: "'inline' | 'block' | 'all'",
74
+ description: 'Selects compensation axes for the end-content slot. Omit to preserve automatic close-action compensation.',
75
+ },
69
76
  {
70
77
  name: 'hasDivider',
71
78
  type: 'boolean',
@@ -83,7 +90,9 @@ export const docs = {
83
90
  theming: {
84
91
  targets: [
85
92
  {className: 'astryx-dialog-header'},
93
+ {className: 'astryx-dialog-header-start-content'},
86
94
  {className: 'astryx-dialog-header-title-block'},
95
+ {className: 'astryx-dialog-header-end-content'},
87
96
  {className: 'astryx-dialog-header-close-icon'},
88
97
  ],
89
98
  },
@@ -136,7 +145,9 @@ export const docsZh = {
136
145
  description: '使用 DialogHeader 为对话框提供带标签的标题区和可选的关闭控件。',
137
146
  anatomy: [
138
147
  {name: 'Header row', required: true, description: '排列标题区、可选的首尾内容和关闭控件。'},
148
+ {name: 'Start content', required: false, description: '包装可选的首部内容。'},
139
149
  {name: 'Title block', required: true, description: '组合标题和可选副标题。'},
150
+ {name: 'End content', required: false, description: '组合可选尾部内容和可选关闭控件。'},
140
151
  {name: 'Close icon', required: false, description: '关闭按钮内的关闭图标。'},
141
152
  ],
142
153
  },
@@ -166,6 +177,11 @@ export const docsZh = {
166
177
  type: 'ReactNode',
167
178
  description: '标题之后、关闭按钮之前的内容。',
168
179
  },
180
+ {
181
+ name: 'endContentEdgeCompensation',
182
+ type: "'inline' | 'block' | 'all'",
183
+ description: '选择尾部内容插槽的补偿轴;省略时保留关闭操作的自动补偿。',
184
+ },
169
185
  {
170
186
  name: 'hasDivider',
171
187
  type: 'boolean',
@@ -176,7 +192,9 @@ export const docsZh = {
176
192
  theming: {
177
193
  targets: [
178
194
  {className: 'astryx-dialog-header'},
195
+ {className: 'astryx-dialog-header-start-content'},
179
196
  {className: 'astryx-dialog-header-title-block'},
197
+ {className: 'astryx-dialog-header-end-content'},
180
198
  {className: 'astryx-dialog-header-close-icon'},
181
199
  ],
182
200
  },
@@ -191,7 +209,9 @@ export const docsDense = {
191
209
  description: 'labelled dialog title area + optional close control',
192
210
  anatomy: [
193
211
  {name: 'Header row', required: true, description: 'arranges title block, optional start/end content, close control'},
212
+ {name: 'Start content', required: false, description: 'wraps optional leading content'},
194
213
  {name: 'Title block', required: true, description: 'groups title + optional subtitle'},
214
+ {name: 'End content', required: false, description: 'groups optional trailing content + optional close control'},
195
215
  {name: 'Close icon', required: false, description: 'close glyph inside close button'},
196
216
  ],
197
217
  },
@@ -201,6 +221,8 @@ export const docsDense = {
201
221
  onOpenChange: 'close button callback (omit=no button)',
202
222
  startContent: 'content before title (e.g. back button)',
203
223
  endContent: 'content after title, before close button',
224
+ endContentEdgeCompensation:
225
+ 'end-content slot axes: inline | block | all; omit=automatic close-action compensation',
204
226
  hasDivider: 'bottom border',
205
227
  },
206
228
  };
@@ -22,6 +22,17 @@ function generateThemeTestCSS(theme: Parameters<typeof generateThemeCSS>[0]) {
22
22
  return [prose, component].filter(Boolean).join('\n\n');
23
23
  }
24
24
 
25
+ function getEndSlot(): HTMLElement {
26
+ const child =
27
+ screen.queryByRole('button', {name: 'Action'}) ??
28
+ screen.getByRole('button', {name: /close/i});
29
+ const slot = child.parentElement;
30
+ if (slot == null) {
31
+ throw new Error('Expected DialogHeader end slot');
32
+ }
33
+ return slot;
34
+ }
35
+
25
36
  describe('DialogHeader', () => {
26
37
  it('renders the title', () => {
27
38
  render(<DialogHeader title="My Dialog Title" />);
@@ -60,35 +71,184 @@ describe('DialogHeader', () => {
60
71
 
61
72
  it('renders close button when onOpenChange is provided', () => {
62
73
  render(<DialogHeader title="Title" onOpenChange={() => {}} />);
63
- expect(screen.getByRole('button', {name: /close/i})).toBeInTheDocument();
74
+ const closeButton = screen.getByRole('button', {name: /close/i});
75
+
76
+ expect(closeButton).toBeInTheDocument();
77
+ expect(closeButton.parentElement).toHaveClass(
78
+ 'astryx-dialog-header-end-content',
79
+ );
80
+ });
81
+
82
+ it('preserves automatic end-slot compensation when the close action renders', () => {
83
+ const {rerender} = render(
84
+ <DialogHeader title="Title" onOpenChange={() => {}} />,
85
+ );
86
+ const automaticClassName = getEndSlot().className;
87
+
88
+ rerender(
89
+ <DialogHeader
90
+ title="Title"
91
+ endContent={<button type="button">Action</button>}
92
+ onOpenChange={() => {}}
93
+ />,
94
+ );
95
+ expect(getEndSlot().className).toBe(automaticClassName);
96
+
97
+ rerender(
98
+ <DialogHeader
99
+ title="Title"
100
+ endContent={<button type="button">Action</button>}
101
+ />,
102
+ );
103
+ expect(getEndSlot().className).not.toBe(automaticClassName);
64
104
  });
65
105
 
66
- it('exposes theme targets for the header row, title block, and close icon', () => {
106
+ it('lets endContentEdgeCompensation select inline, block, or all', () => {
107
+ const {rerender} = render(
108
+ <DialogHeader
109
+ title="Title"
110
+ endContent={<button type="button">Action</button>}
111
+ />,
112
+ );
113
+ const noCompensationClassName = getEndSlot().className;
114
+
115
+ rerender(
116
+ <DialogHeader
117
+ title="Title"
118
+ endContent={<button type="button">Action</button>}
119
+ endContentEdgeCompensation="inline"
120
+ />,
121
+ );
122
+ const inlineClassName = getEndSlot().className;
123
+
124
+ rerender(
125
+ <DialogHeader
126
+ title="Title"
127
+ endContent={<button type="button">Action</button>}
128
+ endContentEdgeCompensation="block"
129
+ />,
130
+ );
131
+ const blockClassName = getEndSlot().className;
132
+
133
+ rerender(
134
+ <DialogHeader
135
+ title="Title"
136
+ endContent={<button type="button">Action</button>}
137
+ endContentEdgeCompensation="all"
138
+ />,
139
+ );
140
+ const allClassName = getEndSlot().className;
141
+
142
+ expect(inlineClassName).not.toBe(noCompensationClassName);
143
+ expect(blockClassName).not.toBe(noCompensationClassName);
144
+ expect(inlineClassName).not.toBe(blockClassName);
145
+ expect(allClassName).not.toBe(inlineClassName);
146
+ expect(allClassName).not.toBe(blockClassName);
147
+
148
+ rerender(
149
+ <DialogHeader
150
+ title="Title"
151
+ endContent={<button type="button">Action</button>}
152
+ onOpenChange={() => {}}
153
+ />,
154
+ );
155
+ expect(getEndSlot().className).toBe(allClassName);
156
+
157
+ rerender(
158
+ <DialogHeader
159
+ title="Title"
160
+ endContent={<button type="button">Action</button>}
161
+ endContentEdgeCompensation="inline"
162
+ onOpenChange={() => {}}
163
+ />,
164
+ );
165
+ expect(getEndSlot().className).toBe(inlineClassName);
166
+ });
167
+
168
+ it('exposes theme targets for the header row, title block, both content slots, and close icon', () => {
67
169
  const {container} = render(
68
170
  <DialogHeader
69
171
  title="Title"
70
172
  subtitle="Subtitle"
173
+ startContent={<button type="button">Back</button>}
174
+ endContent={<button type="button">Custom Action</button>}
71
175
  onOpenChange={() => {}}
72
176
  />,
73
177
  );
74
178
 
75
179
  expect(container.querySelector('.astryx-dialog-header')).not.toBeNull();
180
+ expect(
181
+ screen.getByRole('button', {name: 'Back'}).parentElement,
182
+ ).toHaveClass('astryx-dialog-header-start-content');
76
183
  expect(screen.getByRole('heading', {level: 2}).parentElement).toHaveClass(
77
184
  'astryx-dialog-header-title-block',
78
185
  );
79
186
 
187
+ const endContent = screen.getByRole('button', {
188
+ name: 'Custom Action',
189
+ }).parentElement;
190
+ expect(endContent).toHaveClass('astryx-dialog-header-end-content');
191
+ expect(screen.getByRole('button', {name: /close/i}).parentElement).toBe(
192
+ endContent,
193
+ );
194
+
80
195
  const closeIcon = screen
81
196
  .getByRole('button', {name: /close/i})
82
197
  .querySelector('.astryx-dialog-header-close-icon');
83
198
  expect(closeIcon).toHaveClass('astryx-icon');
84
199
  });
85
200
 
86
- it('lets themes set the two internal gaps and close-icon size', () => {
201
+ it('exposes the start-content target when startContent renders', () => {
202
+ const {container} = render(
203
+ <DialogHeader
204
+ title="Title"
205
+ startContent={<button type="button">Back</button>}
206
+ />,
207
+ );
208
+
209
+ expect(
210
+ screen.getByRole('button', {name: 'Back'}).parentElement,
211
+ ).toHaveClass('astryx-dialog-header-start-content');
212
+ expect(
213
+ container.querySelectorAll('.astryx-dialog-header-start-content'),
214
+ ).toHaveLength(1);
215
+ });
216
+
217
+ it('exposes the end-content target when endContent renders without a close button', () => {
218
+ const {container} = render(
219
+ <DialogHeader
220
+ title="Title"
221
+ endContent={<button type="button">Custom Action</button>}
222
+ />,
223
+ );
224
+
225
+ expect(
226
+ screen.getByRole('button', {name: 'Custom Action'}).parentElement,
227
+ ).toHaveClass('astryx-dialog-header-end-content');
228
+ expect(
229
+ container.querySelectorAll('.astryx-dialog-header-end-content'),
230
+ ).toHaveLength(1);
231
+ });
232
+
233
+ it('omits the content-slot targets when their content does not render', () => {
234
+ const {container} = render(<DialogHeader title="Title" />);
235
+
236
+ expect(
237
+ container.querySelector('.astryx-dialog-header-start-content'),
238
+ ).toBeNull();
239
+ expect(
240
+ container.querySelector('.astryx-dialog-header-end-content'),
241
+ ).toBeNull();
242
+ });
243
+
244
+ it('lets themes set the internal gaps and close-icon size', () => {
87
245
  const theme = defineTheme({
88
246
  name: 'dialog-header-targets-test',
89
247
  components: {
90
248
  'dialog-header': {base: {gap: '8px'}},
249
+ 'dialog-header-start-content': {base: {gap: '5px'}},
91
250
  'dialog-header-title-block': {base: {gap: '4px'}},
251
+ 'dialog-header-end-content': {base: {gap: '6px'}},
92
252
  'dialog-header-close-icon': {
93
253
  base: {width: '16px', height: '16px', fontSize: '16px'},
94
254
  },
@@ -98,8 +258,12 @@ describe('DialogHeader', () => {
98
258
 
99
259
  expect(css).toContain('.astryx-dialog-header {');
100
260
  expect(css).toContain('gap: 8px');
261
+ expect(css).toContain('.astryx-dialog-header-start-content {');
262
+ expect(css).toContain('gap: 5px');
101
263
  expect(css).toContain('.astryx-dialog-header-title-block {');
102
264
  expect(css).toContain('gap: 4px');
265
+ expect(css).toContain('.astryx-dialog-header-end-content {');
266
+ expect(css).toContain('gap: 6px');
103
267
  expect(css).toContain('.astryx-dialog-header-close-icon {');
104
268
  expect(css).toContain('width: 16px');
105
269
  expect(css).toContain('height: 16px');
@@ -37,9 +37,11 @@ const styles = stylex.create({
37
37
  justifyContent: 'space-between',
38
38
  gap: spacingVars['--spacing-3'],
39
39
  },
40
- // Compensate for the icon button's visual padding on the actions area
41
- actionsCompensation: {
40
+ // Compensate for the medium icon button's visual padding on the end slot.
41
+ endBlockEdgeCompensation: {
42
42
  marginBlock: `calc(-1 * ${spacingVars['--spacing-2']})`,
43
+ },
44
+ endInlineEdgeCompensation: {
43
45
  marginInlineEnd: `calc(-1 * ${spacingVars['--spacing-2']})`,
44
46
  },
45
47
  titleWrapper: {
@@ -98,6 +100,14 @@ export interface DialogHeaderProps extends BaseProps<HTMLDivElement> {
98
100
  */
99
101
  endContent?: ReactNode;
100
102
 
103
+ /**
104
+ * Overrides automatic end-slot compensation. When omitted, the slot keeps its
105
+ * existing behavior: rendering the close action applies block and logical
106
+ * inline-end compensation. Use `inline`, `block`, or `all` to select the axes
107
+ * explicitly.
108
+ */
109
+ endContentEdgeCompensation?: 'inline' | 'block' | 'all';
110
+
101
111
  /**
102
112
  * Adds a themed border at the bottom edge.
103
113
  * When false, spacing collapse is applied automatically for seamless visual flow.
@@ -134,6 +144,7 @@ export function DialogHeader({
134
144
  onOpenChange,
135
145
  startContent,
136
146
  endContent,
147
+ endContentEdgeCompensation,
137
148
  hasDivider,
138
149
  xstyle,
139
150
  className,
@@ -146,6 +157,16 @@ export function DialogHeader({
146
157
  const dialogContext = useDialogContext();
147
158
  const shouldAutoFocus = dialogContext?.isInline !== true;
148
159
  const titleId = dialogContext?.titleId;
160
+ const shouldCompensateEndBlock =
161
+ endContentEdgeCompensation == null
162
+ ? onOpenChange != null
163
+ : endContentEdgeCompensation === 'block' ||
164
+ endContentEdgeCompensation === 'all';
165
+ const shouldCompensateEndInline =
166
+ endContentEdgeCompensation == null
167
+ ? onOpenChange != null
168
+ : endContentEdgeCompensation === 'inline' ||
169
+ endContentEdgeCompensation === 'all';
149
170
 
150
171
  // Auto-focus the title when mounted for screen reader accessibility.
151
172
  // Inline dialogs are documentation/showcase previews, so suppress focus to
@@ -172,7 +193,13 @@ export function DialogHeader({
172
193
  stylex.props(styles.container),
173
194
  )}>
174
195
  {startContent && (
175
- <div {...stylex.props(styles.actions)}>{startContent}</div>
196
+ <div
197
+ {...mergeProps(
198
+ themeProps('dialog-header-start-content'),
199
+ stylex.props(styles.actions),
200
+ )}>
201
+ {startContent}
202
+ </div>
176
203
  )}
177
204
  <div
178
205
  {...mergeProps(
@@ -195,9 +222,13 @@ export function DialogHeader({
195
222
  </div>
196
223
  {(endContent || onOpenChange) && (
197
224
  <div
198
- {...stylex.props(
199
- styles.actions,
200
- onOpenChange && styles.actionsCompensation,
225
+ {...mergeProps(
226
+ themeProps('dialog-header-end-content'),
227
+ stylex.props(
228
+ styles.actions,
229
+ shouldCompensateEndBlock && styles.endBlockEdgeCompensation,
230
+ shouldCompensateEndInline && styles.endInlineEdgeCompensation,
231
+ ),
201
232
  )}>
202
233
  {endContent}
203
234
  {onOpenChange && (