@astryxdesign/core 0.7.1-canary.ff40b78 → 0.7.1

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 (348) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/dist/Button/Button.d.ts +1 -1
  3. package/dist/Button/Button.d.ts.map +1 -1
  4. package/dist/Button/Button.js +5 -2
  5. package/dist/Calendar/Calendar.d.ts.map +1 -1
  6. package/dist/Calendar/Calendar.js +191 -32
  7. package/dist/Chat/ChatComposerInput.d.ts +9 -0
  8. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  9. package/dist/Chat/ChatComposerInput.js +5 -0
  10. package/dist/Chat/ChatMessage.d.ts +11 -0
  11. package/dist/Chat/ChatMessage.d.ts.map +1 -1
  12. package/dist/Chat/ChatMessage.js +18 -9
  13. package/dist/Chat/useTriggerMenu.d.ts +9 -2
  14. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  15. package/dist/Chat/useTriggerMenu.js +222 -50
  16. package/dist/CodeBlock/CodeBlock.d.ts +10 -1
  17. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  18. package/dist/CodeBlock/CodeBlock.js +158 -38
  19. package/dist/CodeBlock/tokenizer.d.ts +39 -0
  20. package/dist/CodeBlock/tokenizer.d.ts.map +1 -1
  21. package/dist/CodeBlock/tokenizer.js +108 -0
  22. package/dist/CommandPalette/CommandPalette.d.ts +9 -5
  23. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  24. package/dist/CommandPalette/CommandPalette.js +38 -20
  25. package/dist/CommandPalette/CommandPaletteEmpty.d.ts +4 -3
  26. package/dist/CommandPalette/CommandPaletteEmpty.d.ts.map +1 -1
  27. package/dist/CommandPalette/CommandPaletteEmpty.js +4 -3
  28. package/dist/CommandPalette/CommandPaletteInput.d.ts +5 -4
  29. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  30. package/dist/CommandPalette/CommandPaletteInput.js +35 -18
  31. package/dist/CommandPalette/CommandPaletteItem.d.ts +11 -6
  32. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  33. package/dist/CommandPalette/CommandPaletteItem.js +8 -9
  34. package/dist/CommandPalette/CommandPaletteList.d.ts +4 -2
  35. package/dist/CommandPalette/CommandPaletteList.d.ts.map +1 -1
  36. package/dist/CommandPalette/CommandPaletteList.js +10 -5
  37. package/dist/ComplexSelector/ComplexSelector.d.ts +8 -5
  38. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  39. package/dist/ComplexSelector/ComplexSelector.js +12 -3
  40. package/dist/ContextMenu/ContextMenu.d.ts +3 -3
  41. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  42. package/dist/ContextMenu/ContextMenu.js +62 -48
  43. package/dist/DateInput/DateInput.js +1 -1
  44. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  45. package/dist/DateInput/MonthScroller.js +12 -4
  46. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  47. package/dist/DateRangeInput/DateRangeInput.js +12 -2
  48. package/dist/Dialog/Dialog.d.ts +1 -1
  49. package/dist/Dialog/Dialog.d.ts.map +1 -1
  50. package/dist/Dialog/Dialog.js +16 -5
  51. package/dist/Dialog/DialogHeader.d.ts +1 -1
  52. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  53. package/dist/Dialog/DialogHeader.js +7 -7
  54. package/dist/Divider/Divider.d.ts +1 -0
  55. package/dist/Divider/Divider.d.ts.map +1 -1
  56. package/dist/Divider/Divider.js +5 -4
  57. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  58. package/dist/DropdownMenu/DropdownMenu.js +161 -65
  59. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +7 -5
  60. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  61. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +12 -5
  62. package/dist/Field/InputClearButton.d.ts +8 -4
  63. package/dist/Field/InputClearButton.d.ts.map +1 -1
  64. package/dist/Field/InputClearButton.js +23 -7
  65. package/dist/FormLayout/FormLayout.d.ts.map +1 -1
  66. package/dist/FormLayout/FormLayout.js +1 -0
  67. package/dist/Grid/Grid.d.ts +13 -4
  68. package/dist/Grid/Grid.d.ts.map +1 -1
  69. package/dist/Grid/Grid.js +7 -1
  70. package/dist/HoverCard/useHoverCard.d.ts +1 -1
  71. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  72. package/dist/HoverCard/useHoverCard.js +67 -49
  73. package/dist/InputGroup/InputGroup.d.ts +2 -4
  74. package/dist/InputGroup/InputGroup.d.ts.map +1 -1
  75. package/dist/InputGroup/InputGroup.js +2 -4
  76. package/dist/InputGroup/groupStyles.d.ts +10 -2
  77. package/dist/InputGroup/groupStyles.d.ts.map +1 -1
  78. package/dist/InputGroup/groupStyles.js +19 -2
  79. package/dist/Layer/useLayerDismissal.d.ts +9 -9
  80. package/dist/Layer/useLayerDismissal.js +9 -9
  81. package/dist/Markdown/Markdown.d.ts.map +1 -1
  82. package/dist/Markdown/Markdown.js +25 -4
  83. package/dist/MobileNav/MobileNav.d.ts +7 -0
  84. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  85. package/dist/MobileNav/MobileNav.js +45 -2
  86. package/dist/MultiSelector/MultiSelector.d.ts +7 -4
  87. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  88. package/dist/MultiSelector/MultiSelector.js +24 -3
  89. package/dist/NumberInput/NumberInput.js +1 -1
  90. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  91. package/dist/PowerSearch/PowerSearchEditPopover.js +6 -0
  92. package/dist/Resizable/ResizeHandle.d.ts +1 -1
  93. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  94. package/dist/Resizable/ResizeHandle.js +83 -15
  95. package/dist/Resizable/useResizable.d.ts +23 -0
  96. package/dist/Resizable/useResizable.d.ts.map +1 -1
  97. package/dist/Resizable/useResizable.js +78 -0
  98. package/dist/Selector/Selector.d.ts +6 -3
  99. package/dist/Selector/Selector.d.ts.map +1 -1
  100. package/dist/Selector/Selector.js +28 -6
  101. package/dist/SideNav/SideNav.d.ts.map +1 -1
  102. package/dist/SideNav/SideNav.js +10 -2
  103. package/dist/Slider/Slider.d.ts.map +1 -1
  104. package/dist/Slider/Slider.js +18 -7
  105. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  106. package/dist/Tokenizer/Tokenizer.js +16 -4
  107. package/dist/Toolbar/Toolbar.d.ts +2 -1
  108. package/dist/Toolbar/Toolbar.d.ts.map +1 -1
  109. package/dist/Toolbar/Toolbar.js +3 -1
  110. package/dist/TreeList/TreeList.d.ts.map +1 -1
  111. package/dist/TreeList/TreeList.js +6 -3
  112. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  113. package/dist/TreeList/TreeListItem.js +7 -1
  114. package/dist/astryx.css +22 -0
  115. package/dist/hooks/useScrollOverflow.d.ts.map +1 -1
  116. package/dist/hooks/useScrollOverflow.js +55 -12
  117. package/dist/hooks/useTreeFocus.d.ts +21 -0
  118. package/dist/hooks/useTreeFocus.d.ts.map +1 -1
  119. package/dist/hooks/useTreeFocus.js +40 -2
  120. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  121. package/dist/i18n/generated-locales/en.generated.js +3 -0
  122. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  123. package/dist/i18n/generated-locales/pseudo.generated.js +3 -0
  124. package/dist/reset.a11y.chromium.spec.js +6 -1
  125. package/dist/reset.until-found.a11y.browser.spec.d.ts +2 -0
  126. package/dist/reset.until-found.a11y.browser.spec.d.ts.map +1 -0
  127. package/dist/reset.until-found.a11y.browser.spec.js +71 -0
  128. package/dist/theme/syntax/SyntaxTheme.d.ts.map +1 -1
  129. package/dist/theme/syntax/SyntaxTheme.js +43 -2
  130. package/dist/theme/syntax/defineSyntaxTheme.d.ts +18 -5
  131. package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
  132. package/dist/theme/syntax/defineSyntaxTheme.js +38 -9
  133. package/dist/theme/syntax/index.d.ts +1 -1
  134. package/dist/theme/syntax/index.d.ts.map +1 -1
  135. package/dist/theme/syntax/tokens.d.ts +12 -2
  136. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  137. package/dist/theme/syntax/tokens.js +25 -4
  138. package/dist/utils/plainDate.d.ts +12 -0
  139. package/dist/utils/plainDate.d.ts.map +1 -1
  140. package/dist/utils/plainDate.js +63 -10
  141. package/locales/en.json +13 -1
  142. package/locales/pseudo.json +9 -0
  143. package/package.json +4 -4
  144. package/src/AlertDialog/AlertDialog.doc.mjs +6 -0
  145. package/src/AlertDialog/AlertDialog.spec.md +205 -0
  146. package/src/AlertDialog/AlertDialog.test.tsx +3 -14
  147. package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +115 -0
  148. package/src/AlertDialog/__tests__/AlertDialog.a11y.renders.tsx +52 -0
  149. package/src/AlertDialog/__tests__/AlertDialog.a11y.states.ts +68 -0
  150. package/src/AlertDialog/__tests__/AlertDialog.a11y.test.tsx +144 -0
  151. package/src/Button/Button.test.tsx +37 -0
  152. package/src/Button/Button.tsx +5 -1
  153. package/src/Calendar/Calendar.doc.mjs +234 -60
  154. package/src/Calendar/Calendar.spec.md +209 -0
  155. package/src/Calendar/Calendar.test.tsx +559 -20
  156. package/src/Calendar/Calendar.tsx +258 -41
  157. package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +126 -0
  158. package/src/Calendar/__tests__/Calendar.a11y.known-failures.ts +12 -0
  159. package/src/Calendar/__tests__/Calendar.a11y.renders.tsx +57 -0
  160. package/src/Calendar/__tests__/Calendar.a11y.states.ts +139 -0
  161. package/src/Calendar/__tests__/Calendar.a11y.test.tsx +137 -0
  162. package/src/Carousel/Carousel.test.tsx +54 -71
  163. package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +192 -0
  164. package/src/Carousel/__tests__/Carousel.a11y.known-failures.ts +27 -0
  165. package/src/Carousel/__tests__/Carousel.a11y.renders.tsx +39 -0
  166. package/src/Carousel/__tests__/Carousel.a11y.states.ts +139 -0
  167. package/src/Carousel/__tests__/Carousel.a11y.test.tsx +127 -0
  168. package/src/Chat/ChatComposerInput.doc.mjs +1 -1
  169. package/src/Chat/ChatComposerInput.spec.md +94 -55
  170. package/src/Chat/ChatComposerInput.test.tsx +202 -1
  171. package/src/Chat/ChatComposerInput.tsx +13 -0
  172. package/src/Chat/ChatMessage.doc.mjs +31 -16
  173. package/src/Chat/ChatMessage.spec.md +265 -0
  174. package/src/Chat/ChatMessage.test.tsx +246 -0
  175. package/src/Chat/ChatMessage.tsx +30 -7
  176. package/src/Chat/ChatSystemMessage.spec.md +36 -37
  177. package/src/Chat/ChatSystemMessage.test.tsx +4 -4
  178. package/src/Chat/useTriggerMenu.test.tsx +994 -0
  179. package/src/Chat/useTriggerMenu.tsx +278 -46
  180. package/src/CodeBlock/CodeBlock.doc.mjs +7 -0
  181. package/src/CodeBlock/CodeBlock.spec.md +40 -41
  182. package/src/CodeBlock/CodeBlock.test.tsx +89 -9
  183. package/src/CodeBlock/CodeBlock.tsx +205 -25
  184. package/src/CodeBlock/__tests__/CodeBlockOverflowStop.a11y.chromium.spec.ts +125 -0
  185. package/src/CodeBlock/__tests__/DiffRowPaint.a11y.chromium.spec.ts +93 -0
  186. package/src/CodeBlock/tokenizer.test.ts +112 -0
  187. package/src/CodeBlock/tokenizer.ts +106 -0
  188. package/src/Collapsible/CollapsibleGroup.spec.md +17 -8
  189. package/src/Collapsible/__tests__/CollapsibleGroup.a11y.renders.tsx +45 -0
  190. package/src/Collapsible/__tests__/CollapsibleGroup.a11y.states.ts +139 -0
  191. package/src/Collapsible/__tests__/CollapsibleGroup.a11y.test.tsx +135 -0
  192. package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +128 -0
  193. package/src/CommandPalette/CommandPalette.doc.mjs +126 -23
  194. package/src/CommandPalette/CommandPalette.spec.md +100 -49
  195. package/src/CommandPalette/CommandPalette.test.tsx +241 -2
  196. package/src/CommandPalette/CommandPalette.tsx +47 -21
  197. package/src/CommandPalette/CommandPaletteEmpty.tsx +4 -3
  198. package/src/CommandPalette/CommandPaletteInput.doc.mjs +61 -4
  199. package/src/CommandPalette/CommandPaletteInput.spec.md +215 -0
  200. package/src/CommandPalette/CommandPaletteInput.test.tsx +375 -51
  201. package/src/CommandPalette/CommandPaletteInput.tsx +74 -21
  202. package/src/CommandPalette/CommandPaletteItem.doc.mjs +73 -22
  203. package/src/CommandPalette/CommandPaletteItem.spec.md +223 -0
  204. package/src/CommandPalette/CommandPaletteItem.test.tsx +200 -5
  205. package/src/CommandPalette/CommandPaletteItem.tsx +16 -11
  206. package/src/CommandPalette/CommandPaletteList.doc.mjs +3 -3
  207. package/src/CommandPalette/CommandPaletteList.spec.md +41 -36
  208. package/src/CommandPalette/CommandPaletteList.test.tsx +80 -0
  209. package/src/CommandPalette/CommandPaletteList.tsx +10 -5
  210. package/src/CommandPalette/__tests__/CommandPalette.a11y.chromium.spec.ts +599 -0
  211. package/src/ComplexSelector/ComplexSelector.doc.mjs +10 -8
  212. package/src/ComplexSelector/ComplexSelector.spec.md +14 -9
  213. package/src/ComplexSelector/ComplexSelector.test.tsx +64 -16
  214. package/src/ComplexSelector/ComplexSelector.tsx +37 -8
  215. package/src/ContextMenu/ContextMenu.doc.mjs +6 -0
  216. package/src/ContextMenu/ContextMenu.spec.md +51 -53
  217. package/src/ContextMenu/ContextMenu.test.tsx +132 -1
  218. package/src/ContextMenu/ContextMenu.tsx +78 -48
  219. package/src/DateInput/DateInput.doc.mjs +52 -0
  220. package/src/DateInput/DateInput.spec.md +27 -15
  221. package/src/DateInput/DateInput.test.tsx +38 -0
  222. package/src/DateInput/DateInput.tsx +1 -1
  223. package/src/DateInput/DateInputTouch.test.tsx +22 -0
  224. package/src/DateInput/MonthScroller.tsx +12 -4
  225. package/src/DateRangeInput/DateRangeInput.test.tsx +49 -0
  226. package/src/DateRangeInput/DateRangeInput.tsx +20 -2
  227. package/src/Dialog/Dialog.test.tsx +27 -1
  228. package/src/Dialog/Dialog.tsx +16 -5
  229. package/src/Dialog/DialogHeader.test.tsx +27 -2
  230. package/src/Dialog/DialogHeader.tsx +7 -8
  231. package/src/Dialog/__tests__/Dialog.a11y.chromium.spec.ts +21 -14
  232. package/src/Divider/Divider.doc.mjs +5 -3
  233. package/src/Divider/Divider.spec.md +140 -54
  234. package/src/Divider/Divider.test.tsx +15 -0
  235. package/src/Divider/Divider.tsx +6 -4
  236. package/src/DropdownMenu/DropdownMenu.doc.mjs +2 -2
  237. package/src/DropdownMenu/DropdownMenu.spec.md +121 -45
  238. package/src/DropdownMenu/DropdownMenu.test.tsx +288 -23
  239. package/src/DropdownMenu/DropdownMenu.tsx +212 -81
  240. package/src/DropdownMenu/DropdownMenuCheckboxItem.doc.mjs +38 -2
  241. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +32 -18
  242. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +146 -1
  243. package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +136 -0
  244. package/src/DropdownMenu/__tests__/MenuButton.a11y.known-failures.ts +12 -0
  245. package/src/DropdownMenu/__tests__/MenuButton.a11y.renders.tsx +67 -0
  246. package/src/DropdownMenu/__tests__/MenuButton.a11y.states.ts +141 -0
  247. package/src/DropdownMenu/__tests__/MenuButton.a11y.test.tsx +138 -0
  248. package/src/DropdownMenu/__tests__/MenuHeaderFooter.a11y.chromium.spec.ts +40 -5
  249. package/src/Field/InputClearButton.test.tsx +29 -4
  250. package/src/Field/InputClearButton.tsx +26 -8
  251. package/src/FieldStatus/__tests__/StatusMessage.a11y.chromium.spec.ts +21 -14
  252. package/src/FormLayout/FormLayout.tsx +1 -0
  253. package/src/FormLayout/__snapshots__/FormLayout.test.tsx.snap +1 -1
  254. package/src/Grid/Grid.doc.mjs +14 -11
  255. package/src/Grid/Grid.spec.md +50 -32
  256. package/src/Grid/Grid.tsx +13 -4
  257. package/src/HoverCard/HoverCard.test.tsx +46 -1
  258. package/src/HoverCard/useHoverCard.tsx +68 -48
  259. package/src/InputGroup/InputGroup.doc.mjs +11 -1
  260. package/src/InputGroup/InputGroup.tsx +2 -4
  261. package/src/InputGroup/groupStyles.ts +40 -2
  262. package/src/Layer/useLayerDismissal.ts +9 -9
  263. package/src/Link/__tests__/Link.a11y.chromium.spec.ts +142 -0
  264. package/src/Link/__tests__/Link.a11y.renders.tsx +97 -0
  265. package/src/Link/__tests__/Link.a11y.states.ts +104 -0
  266. package/src/Link/__tests__/Link.a11y.test.tsx +127 -0
  267. package/src/Markdown/Markdown.doc.mjs +1 -1
  268. package/src/Markdown/Markdown.fr23.perf.test.ts +161 -40
  269. package/src/Markdown/Markdown.spec.md +45 -23
  270. package/src/Markdown/Markdown.test.tsx +38 -0
  271. package/src/Markdown/Markdown.tsx +24 -2
  272. package/src/Markdown/plugins/semanticFence.test.tsx +3 -2
  273. package/src/MobileNav/MobileNav.tsx +50 -2
  274. package/src/MobileNav/MobileNavFocus.test.tsx +553 -0
  275. package/src/MoreMenu/MoreMenu.spec.md +18 -7
  276. package/src/MoreMenu/MoreMenu.test.tsx +38 -0
  277. package/src/MultiSelector/MultiSelector.doc.mjs +8 -8
  278. package/src/MultiSelector/MultiSelector.spec.md +1 -1
  279. package/src/MultiSelector/MultiSelector.test.tsx +188 -21
  280. package/src/MultiSelector/MultiSelector.tsx +50 -11
  281. package/src/NumberInput/NumberInput.test.tsx +24 -0
  282. package/src/NumberInput/NumberInput.tsx +1 -1
  283. package/src/NumberInput/__tests__/NumberInput.a11y.chromium.spec.ts +22 -15
  284. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +78 -0
  285. package/src/PowerSearch/PowerSearchEditPopover.tsx +6 -0
  286. package/src/Resizable/Resizable.spec.md +41 -9
  287. package/src/Resizable/ResizeHandle.test.tsx +565 -2
  288. package/src/Resizable/ResizeHandle.tsx +126 -21
  289. package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +119 -0
  290. package/src/Resizable/__tests__/ResizeHandle.a11y.known-failures.ts +39 -0
  291. package/src/Resizable/__tests__/ResizeHandle.a11y.renders.tsx +80 -0
  292. package/src/Resizable/__tests__/ResizeHandle.a11y.states.ts +197 -0
  293. package/src/Resizable/__tests__/ResizeHandle.a11y.test.tsx +123 -0
  294. package/src/Resizable/useResizable.ts +95 -0
  295. package/src/Selector/Selector.doc.mjs +7 -6
  296. package/src/Selector/Selector.spec.md +37 -24
  297. package/src/Selector/Selector.test.tsx +176 -10
  298. package/src/Selector/Selector.tsx +59 -14
  299. package/src/Selector/__tests__/Combobox.a11y.known-failures.ts +27 -0
  300. package/src/Selector/__tests__/Combobox.a11y.states.ts +145 -0
  301. package/src/Selector/__tests__/Selector.combobox.a11y.chromium.spec.ts +108 -0
  302. package/src/Selector/__tests__/Selector.combobox.a11y.test.tsx +126 -0
  303. package/src/SideNav/SideNav.test.tsx +35 -0
  304. package/src/SideNav/SideNav.tsx +16 -2
  305. package/src/Slider/Slider.spec.md +43 -17
  306. package/src/Slider/Slider.test.tsx +134 -0
  307. package/src/Slider/Slider.tsx +29 -6
  308. package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +112 -0
  309. package/src/Slider/__tests__/Slider.a11y.known-failures.ts +12 -0
  310. package/src/Slider/__tests__/Slider.a11y.renders.tsx +42 -0
  311. package/src/Slider/__tests__/Slider.a11y.states.ts +106 -0
  312. package/src/Slider/__tests__/Slider.a11y.test.tsx +105 -0
  313. package/src/Switch/__tests__/Switch.a11y.chromium.spec.ts +25 -18
  314. package/src/TabList/__tests__/Tabs.a11y.chromium.spec.ts +19 -12
  315. package/src/TextInput/__tests__/TextInput.a11y.chromium.spec.ts +21 -14
  316. package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +18 -11
  317. package/src/Tokenizer/Tokenizer.test.tsx +87 -0
  318. package/src/Tokenizer/Tokenizer.tsx +31 -3
  319. package/src/Toolbar/Toolbar.test.tsx +131 -4
  320. package/src/Toolbar/Toolbar.tsx +3 -1
  321. package/src/TreeList/TreeList.spec.md +33 -8
  322. package/src/TreeList/TreeList.test.tsx +72 -0
  323. package/src/TreeList/TreeList.tsx +10 -6
  324. package/src/TreeList/TreeListItem.tsx +5 -0
  325. package/src/TreeList/__tests__/TreeList.a11y.chromium.spec.ts +125 -0
  326. package/src/TreeList/__tests__/TreeList.a11y.renders.tsx +44 -0
  327. package/src/TreeList/__tests__/TreeList.a11y.states.ts +164 -0
  328. package/src/TreeList/__tests__/TreeList.a11y.test.tsx +138 -0
  329. package/src/TreeList/__tests__/TreeListRowNames.a11y.chromium.spec.ts +82 -0
  330. package/src/hooks/useScrollOverflow.test.tsx +222 -0
  331. package/src/hooks/useScrollOverflow.ts +55 -13
  332. package/src/hooks/useTreeFocus.test.tsx +37 -0
  333. package/src/hooks/useTreeFocus.ts +55 -2
  334. package/src/i18n/generated-locales/en.generated.ts +3 -0
  335. package/src/i18n/generated-locales/pseudo.generated.ts +3 -0
  336. package/src/reset.a11y.chromium.spec.ts +9 -1
  337. package/src/reset.css +8 -3
  338. package/src/reset.until-found.a11y.browser.spec.ts +75 -0
  339. package/src/reset.until-found.test.ts +32 -0
  340. package/src/stylexValidation.source-build.test.mjs +42 -0
  341. package/src/theme/syntax/SyntaxTheme.tsx +46 -5
  342. package/src/theme/syntax/defineSyntaxTheme.diff.test.ts +91 -0
  343. package/src/theme/syntax/defineSyntaxTheme.ts +75 -15
  344. package/src/theme/syntax/index.ts +5 -1
  345. package/src/theme/syntax/tokens.ts +32 -2
  346. package/src/theme/syntax/useSyntaxTheme.diff.test.tsx +40 -0
  347. package/src/utils/plainDate.test.ts +147 -0
  348. package/src/utils/plainDate.ts +75 -10
@@ -0,0 +1,68 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file AlertDialog.a11y.states.ts
5
+ * @input AlertDialog's representative modal states and the facts ALERT_DIALOG_PATTERN reads
6
+ * @output ALERT_DIALOG_BINDING_STATES, the shared labels, and the explicit ownership exclusions for this binding
7
+ * @position Binding inventory shared by the jsdom test, the Chromium spec, and the story (component:AlertDialog AR1)
8
+ */
9
+
10
+ import type {AlertDialogStateFacts} from '@astryxdesign/a11y-spec';
11
+
12
+ export const ALERT_DIALOG_OPEN_LABEL = 'Delete report';
13
+ export const ALERT_DIALOG_TITLE = 'Delete this report?';
14
+ export const ALERT_DIALOG_MESSAGE =
15
+ 'This permanently deletes the report and its 12 comments.';
16
+ export const ALERT_DIALOG_CANCEL_LABEL = 'Keep report';
17
+ export const ALERT_DIALOG_ACTION_LABEL = 'Delete';
18
+
19
+ export interface AlertDialogBindingState {
20
+ readonly id: string;
21
+ readonly summary: string;
22
+ readonly storyId: string;
23
+ readonly facts: AlertDialogStateFacts;
24
+ readonly isActionLoading?: boolean;
25
+ }
26
+
27
+ const facts: AlertDialogStateFacts = {
28
+ modal: true,
29
+ // Dialog `purpose="form"`: Escape closes, a backdrop click does nothing.
30
+ dismissesOnEscape: true,
31
+ dismissesOnBackdrop: false,
32
+ };
33
+
34
+ const story = (id: string) => `a11y-alertdialog--${id}`;
35
+
36
+ export const ALERT_DIALOG_BINDING_STATES = [
37
+ {
38
+ id: 'modal-confirm',
39
+ summary:
40
+ 'a modal AlertDialog with a destructive action, opened from a button',
41
+ storyId: story('modal-confirm'),
42
+ facts,
43
+ },
44
+ {
45
+ id: 'modal-action-loading',
46
+ summary:
47
+ 'the same AlertDialog while its action is loading: Cancel stays the first focus and Escape still cancels',
48
+ storyId: story('modal-action-loading'),
49
+ facts,
50
+ isActionLoading: true,
51
+ },
52
+ ] as const satisfies ReadonlyArray<AlertDialogBindingState>;
53
+
54
+ export const ALERT_DIALOG_EXCLUSIONS = [
55
+ {
56
+ id: 'modal-mechanics',
57
+ owner:
58
+ 'MODAL_DIALOG_PATTERN bound by Dialog (Dialog.a11y.test.tsx and its Chromium spec)',
59
+ reason:
60
+ 'AlertDialog composes Dialog for the top layer, the inert page behind it, focus entering after modal presentation, and focus returning to the opener on close. Those outcomes are proven once on Dialog; this binding proves only what the alert dialog adds: its role, references, modality claim, initial focus on Cancel, and its dismissal rules.',
61
+ },
62
+ {
63
+ id: 'inline-preview',
64
+ owner: 'AlertDialog.test.tsx (inline preview suite)',
65
+ reason:
66
+ 'The `isInline` preview renders the same anatomy as a plain `role="group"` without modality; it is not an alert dialog and makes none of this pattern\'s claims, so it is not a binding state.',
67
+ },
68
+ ] as const;
@@ -0,0 +1,144 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ /** @vitest-environment jsdom */
3
+
4
+ /**
5
+ * @file AlertDialog.a11y.test.tsx
6
+ * @input ALERT_DIALOG_PATTERN bound to AlertDialog's representative states
7
+ * @output jsdom-lane proof of the DOM expectation (the description reference) and an honest "unrun" report for the browser layers
8
+ * @position Binding test for component:AlertDialog AR1 (the Chromium spec covers the rest)
9
+ */
10
+
11
+ import {cleanup, fireEvent, render, screen} from '@testing-library/react';
12
+ import {beforeEach, describe, expect, it, vi} from 'vitest';
13
+ import {
14
+ ALERT_DIALOG_PATTERN,
15
+ checkAccessibilitySpec,
16
+ createJsdomHarness,
17
+ expectAccessibilitySpec,
18
+ summarize,
19
+ type BindingResult,
20
+ } from '@astryxdesign/a11y-spec';
21
+ import {renderAlertDialogState} from './AlertDialog.a11y.renders';
22
+ import {
23
+ ALERT_DIALOG_BINDING_STATES,
24
+ ALERT_DIALOG_CANCEL_LABEL,
25
+ ALERT_DIALOG_EXCLUSIONS,
26
+ ALERT_DIALOG_OPEN_LABEL,
27
+ type AlertDialogBindingState,
28
+ } from './AlertDialog.a11y.states';
29
+
30
+ // jsdom has no native dialog methods; the DOM lane only needs the open flag.
31
+ beforeEach(() => {
32
+ HTMLDialogElement.prototype.showModal = vi.fn(function (
33
+ this: HTMLDialogElement,
34
+ ) {
35
+ this.setAttribute('open', '');
36
+ });
37
+ HTMLDialogElement.prototype.close = vi.fn(function (this: HTMLDialogElement) {
38
+ this.removeAttribute('open');
39
+ });
40
+ });
41
+
42
+ function surface(): HTMLElement {
43
+ const element = document.querySelector('dialog');
44
+ if (element == null) {
45
+ throw new Error('no dialog element rendered');
46
+ }
47
+ return element;
48
+ }
49
+
50
+ function related(): Record<string, HTMLElement> {
51
+ const message = document.getElementById(
52
+ surface().getAttribute('aria-describedby') ?? '',
53
+ );
54
+ const cancel = screen.getByRole('button', {
55
+ name: ALERT_DIALOG_CANCEL_LABEL,
56
+ hidden: true,
57
+ });
58
+ return {
59
+ message: message ?? document.body,
60
+ cancel,
61
+ };
62
+ }
63
+
64
+ function openSurface(): void {
65
+ fireEvent.click(screen.getByRole('button', {name: ALERT_DIALOG_OPEN_LABEL}));
66
+ }
67
+
68
+ async function checkState(
69
+ state: AlertDialogBindingState,
70
+ ): Promise<BindingResult> {
71
+ return checkAccessibilitySpec({
72
+ spec: ALERT_DIALOG_PATTERN,
73
+ binding: 'AlertDialog',
74
+ state: state.id,
75
+ facts: state.facts,
76
+ mount: async () => {
77
+ render(renderAlertDialogState(state));
78
+ openSurface();
79
+ return createJsdomHarness({subject: surface(), related: related()});
80
+ },
81
+ unmount: cleanup,
82
+ });
83
+ }
84
+
85
+ describe('AlertDialog — alert dialog pattern, jsdom lane', () => {
86
+ it.each(
87
+ ALERT_DIALOG_BINDING_STATES.map(
88
+ state => [state.id, state.summary, state] as const,
89
+ ),
90
+ )('%s — %s', async (_id, _summary, state) => {
91
+ await expectAccessibilitySpec({
92
+ spec: ALERT_DIALOG_PATTERN,
93
+ binding: 'AlertDialog',
94
+ state: state.id,
95
+ facts: state.facts,
96
+ render: () => {
97
+ render(renderAlertDialogState(state));
98
+ },
99
+ subject: () => surface(),
100
+ related: () => related(),
101
+ cleanup,
102
+ });
103
+ });
104
+
105
+ it('runs the DOM layer and reports the browser-owned outcomes as unrun', async () => {
106
+ const results: BindingResult[] = [];
107
+ for (const state of ALERT_DIALOG_BINDING_STATES) {
108
+ results.push(await checkState(state));
109
+ }
110
+ const report = summarize(ALERT_DIALOG_PATTERN, results);
111
+ expect(report.counts.pass).toBeGreaterThan(0);
112
+ expect(report.unrunLayers).toEqual(['accessibility-tree', 'real-browser']);
113
+ expect(report.counts.unexpectedPass).toBe(0);
114
+ });
115
+ });
116
+
117
+ describe('AlertDialog binding inventory', () => {
118
+ it('gives every representative state a distinct checked-in story', () => {
119
+ const stories = ALERT_DIALOG_BINDING_STATES.map(state => state.storyId);
120
+ expect(new Set(stories).size).toBe(stories.length);
121
+ });
122
+
123
+ it('keeps modal mechanics and the inline preview explicitly owned elsewhere', () => {
124
+ expect(ALERT_DIALOG_EXCLUSIONS.map(exclusion => exclusion.id)).toEqual([
125
+ 'modal-mechanics',
126
+ 'inline-preview',
127
+ ]);
128
+ for (const exclusion of ALERT_DIALOG_EXCLUSIONS) {
129
+ expect(exclusion.owner.length, exclusion.id).toBeGreaterThan(20);
130
+ expect(exclusion.reason.length, exclusion.id).toBeGreaterThan(80);
131
+ }
132
+ });
133
+
134
+ it('renders the opener, the surface, its message and Cancel for every state', () => {
135
+ for (const state of ALERT_DIALOG_BINDING_STATES) {
136
+ render(renderAlertDialogState(state));
137
+ openSurface();
138
+ expect(surface(), state.id).toBeTruthy();
139
+ expect(related().message, state.id).not.toBe(document.body);
140
+ expect(related().cancel, state.id).toBeTruthy();
141
+ cleanup();
142
+ }
143
+ });
144
+ });
@@ -9,6 +9,7 @@
9
9
  * SYNC: When Button.tsx changes, update tests to match new behavior
10
10
  */
11
11
 
12
+ import {readFileSync} from 'node:fs';
12
13
  import {describe, it, expect, vi} from 'vitest';
13
14
  import {render, screen, fireEvent, act} from '@testing-library/react';
14
15
  import userEvent from '@testing-library/user-event';
@@ -21,6 +22,8 @@ import {
21
22
  } from '../__tests__/pressState';
22
23
  import {Badge} from '../Badge/Badge';
23
24
  import {ButtonGroup} from '../ButtonGroup';
25
+ import {InputGroup} from '../InputGroup';
26
+ import {TextInput} from '../TextInput';
24
27
  import {IconButton} from '../IconButton';
25
28
  import {InternationalizationProvider} from '../i18n';
26
29
 
@@ -39,6 +42,40 @@ describe('Button', () => {
39
42
  expect(screen.getByRole('button')).toHaveTextContent('Click me');
40
43
  });
41
44
 
45
+ it('uses InputGroup end-cap geometry and keeps its keyboard ring above adjacent members', () => {
46
+ const {rerender} = render(
47
+ <InputGroup label="Visibility">
48
+ <TextInput
49
+ label="Audience"
50
+ isLabelHidden
51
+ value="Members"
52
+ onChange={() => {}}
53
+ />
54
+ <Button label="Save" />
55
+ </InputGroup>,
56
+ );
57
+
58
+ const addon = screen.getByRole('button', {name: 'Save'});
59
+ expect(addon.className).toContain('groupStyles.buttonAddon');
60
+
61
+ // jsdom cannot resolve this compound StyleX focus selector. Keep the
62
+ // direct-child keyboard stacking rule explicit at its definition instead.
63
+ const groupStylesSource = readFileSync(
64
+ 'packages/core/src/InputGroup/groupStyles.ts',
65
+ 'utf8',
66
+ );
67
+ expect(groupStylesSource).toContain(
68
+ "':where(.astryx-input-group > *):focus-visible'",
69
+ );
70
+ expect(groupStylesSource).toMatch(
71
+ /zIndex:\s*\{\s*default: null,\s*\[DIRECT_INPUT_GROUP_ADDON_FOCUS_VISIBLE\]: 2,/,
72
+ );
73
+
74
+ rerender(<Button label="Save" />);
75
+ const standalone = screen.getByRole('button', {name: 'Save'});
76
+ expect(standalone.className).not.toContain('groupStyles.buttonAddon');
77
+ });
78
+
42
79
  it('renders children instead of label when provided', () => {
43
80
  render(<Button label="Accessible name">Custom content</Button>);
44
81
  const button = screen.getByRole('button');
@@ -4,7 +4,7 @@
4
4
 
5
5
  /**
6
6
  * @file Button.tsx
7
- * @input Uses React, ButtonHTMLAttributes, ReactNode, i18n (useTranslator)
7
+ * @input Uses React, ButtonHTMLAttributes, ReactNode, i18n (useTranslator), group contexts
8
8
  * @output Exports Button component, ButtonProps, ButtonVariant types
9
9
  * @position Core implementation; consumed by index.ts, tested by Button.test.tsx
10
10
  *
@@ -44,6 +44,8 @@ import {iconBoxSizeStyles, type IconSize} from '../Icon/IconSize.stylex';
44
44
  import {EDGE_COMP_ATTR} from '../Layout/edgeCompensation.stylex';
45
45
  import {useSize} from '../SizeContext/SizeContext';
46
46
  import {useButtonGroup} from '../ButtonGroup/ButtonGroupContext';
47
+ import {useInputGroup} from '../InputGroup/InputGroupContext';
48
+ import {groupStyles as inputGroupStyles} from '../InputGroup/groupStyles';
47
49
  import {mergeProps} from '../utils';
48
50
  import {useMergedRefs} from '../hooks/useMergedRefs';
49
51
  import {useLinkComponent} from '../Link/useLinkComponent';
@@ -576,6 +578,7 @@ export function Button({
576
578
  const t = useTranslator();
577
579
  const size = useSize(sizeProp, 'md');
578
580
  const buttonGroup = useButtonGroup();
581
+ const inputGroup = useInputGroup();
579
582
 
580
583
  const [isPending, startTransition] = useTransition();
581
584
  // clickAction is normally fire-once (submit/save/pay), so a same-tick
@@ -674,6 +677,7 @@ export function Button({
674
677
  (buttonGroup.orientation === 'horizontal'
675
678
  ? groupStyles.horizontal
676
679
  : groupStyles.vertical),
680
+ inputGroup != null && buttonGroup == null && inputGroupStyles.buttonAddon,
677
681
  buttonGroup &&
678
682
  (variant === 'primary' || variant === 'destructive') &&
679
683
  (buttonGroup.orientation === 'horizontal'
@@ -6,23 +6,85 @@ export const docs = {
6
6
  name: 'Calendar',
7
7
  displayName: 'Calendar',
8
8
  category: 'Form Controls',
9
- keywords: ["calendar","datepicker","date picker","rangepicker","date range","monthview","daypicker"],
9
+ keywords: [
10
+ 'calendar',
11
+ 'datepicker',
12
+ 'date picker',
13
+ 'rangepicker',
14
+ 'date range',
15
+ 'monthview',
16
+ 'daypicker',
17
+ ],
10
18
  usage: {
11
19
  description:
12
20
  'Calendar lets the user pick a date or date range from a month grid. Use it in booking flows, scheduling UIs, date filters, or anywhere the user needs to see surrounding dates for context.',
13
21
  bestPractices: [
14
- {guidance: true, description: 'Set min and max dates to limit selection to a valid window, like only future dates for a booking or the current quarter for a report.'},
15
- {guidance: true, description: 'Use range mode when the user needs to pick a start and end date, like a trip or a time-off request.'},
16
- {guidance: true, description: 'Use dateConstraints to disable specific dates like weekends or holidays, and explain why they are unavailable.'},
17
- {guidance: true, description: 'Show two months side by side when the user frequently selects dates that span a month boundary.'},
18
- {guidance: false, description: 'Use a calendar for dates far in the past or future like a birth date. A text input is faster for open-ended entry.'},
19
- {guidance: false, description: 'Disable large blocks of dates without context. The user should understand why dates are unavailable.'},
22
+ {
23
+ guidance: true,
24
+ description:
25
+ 'Set min and max dates to limit selection to a valid window, like only future dates for a booking or the current quarter for a report.',
26
+ },
27
+ {
28
+ guidance: true,
29
+ description:
30
+ 'Use range mode when the user needs to pick a start and end date, like a trip or a time-off request.',
31
+ },
32
+ {
33
+ guidance: true,
34
+ description:
35
+ 'Use dateConstraints to disable specific dates like weekends or holidays, and explain why they are unavailable.',
36
+ },
37
+ {
38
+ guidance: true,
39
+ description:
40
+ 'Show two months side by side when the user frequently selects dates that span a month boundary.',
41
+ },
42
+ {
43
+ guidance: false,
44
+ description:
45
+ 'Use a calendar for dates far in the past or future like a birth date. A text input is faster for open-ended entry.',
46
+ },
47
+ {
48
+ guidance: false,
49
+ description:
50
+ 'Disable large blocks of dates without context. The user should understand why dates are unavailable.',
51
+ },
20
52
  ],
21
53
  anatomy: [
22
- {name: 'Month header', required: true, description: 'The month name and year with navigation arrows to move between months. The arrows mirror automatically under dir="rtl".'},
23
- {name: 'Day grid', required: true, description: 'A 7-column grid of days with column headers for the day names.'},
24
- {name: 'Selected day', required: false, description: 'The currently selected date, highlighted. In range mode, the start and end dates plus the days between them.'},
25
- {name: 'Today marker', required: false, description: 'A subtle indicator on the current date for orientation.'},
54
+ {
55
+ name: 'Calendar root',
56
+ required: true,
57
+ description:
58
+ 'The container that holds the month header and the day grid.',
59
+ },
60
+ {
61
+ name: 'Month header',
62
+ required: true,
63
+ description:
64
+ 'The month name and year with navigation arrows to move between months. The arrows mirror automatically under dir="rtl".',
65
+ },
66
+ {
67
+ name: 'Day grid',
68
+ required: true,
69
+ description:
70
+ 'A 7-column grid of days with column headers for the day names.',
71
+ },
72
+ {
73
+ name: 'Day button',
74
+ required: true,
75
+ description: 'One day in the grid; the control a date is picked with.',
76
+ },
77
+ {
78
+ name: 'Selected day',
79
+ required: false,
80
+ description:
81
+ 'The currently selected date, highlighted. In range mode, the start and end dates plus the days between them.',
82
+ },
83
+ {
84
+ name: 'Today marker',
85
+ required: false,
86
+ description: 'A subtle indicator on the current date for orientation.',
87
+ },
26
88
  ],
27
89
  },
28
90
  props: [
@@ -35,7 +97,8 @@ export const docs = {
35
97
  {
36
98
  name: 'value',
37
99
  type: 'ISODateString | DateRange | null',
38
- description: 'Controlled selected value. Use null for no selection; omit value or pass undefined for uncontrolled mode.',
100
+ description:
101
+ 'Controlled selected value. Use null for no selection; omit value or pass undefined for uncontrolled mode.',
39
102
  },
40
103
  {
41
104
  name: 'defaultValue',
@@ -94,7 +157,8 @@ export const docs = {
94
157
  {
95
158
  name: 'handleRef',
96
159
  type: 'React.Ref<CalendarHandle>',
97
- description: 'Imperative handle for calendar navigation, including navigateTo().',
160
+ description:
161
+ 'Imperative handle for calendar navigation, including navigateTo().',
98
162
  },
99
163
  {
100
164
  name: 'hasOutsideDays',
@@ -117,15 +181,23 @@ export const docs = {
117
181
  {
118
182
  name: 'weekStartsOn',
119
183
  type: "0 | 1 | 2 | 3 | 4 | 5 | 6 | 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'",
120
- description: 'First day of week. Accepts a number (0=Sunday) or a three-letter day name (e.g. "mon").',
184
+ description:
185
+ 'First day of week. Accepts a number (0=Sunday) or a three-letter day name (e.g. "mon").',
121
186
  default: '0',
122
187
  },
123
188
  ],
124
189
  theming: {
125
190
  targets: [
126
191
  {className: 'astryx-calendar', visualProps: ['mode']},
127
- {className: 'astryx-calendar-nav', visualProps: ['nav'], states: ['disabled']},
128
- {className: 'astryx-calendar-day', states: ['selected', 'today', 'disabled', 'in-range', 'marker']},
192
+ {
193
+ className: 'astryx-calendar-nav',
194
+ visualProps: ['nav'],
195
+ states: ['disabled'],
196
+ },
197
+ {
198
+ className: 'astryx-calendar-day',
199
+ states: ['selected', 'today', 'disabled', 'in-range', 'marker'],
200
+ },
129
201
  ],
130
202
  },
131
203
  };
@@ -138,59 +210,138 @@ export const docsZh = {
138
210
  description:
139
211
  'Calendar lets the user pick a date or date range from a month grid. Use it in booking flows, scheduling UIs, date filters, or anywhere the user needs to see surrounding dates for context.',
140
212
  bestPractices: [
141
- {guidance: true, description: 'Set min and max dates to limit selection to a valid window, like only future dates for a booking or the current quarter for a report.'},
142
- {guidance: true, description: 'Use range mode when the user needs to pick a start and end date, like a trip or a time-off request.'},
143
- {guidance: true, description: 'Use dateConstraints to disable specific dates like weekends or holidays, and explain why they are unavailable.'},
144
- {guidance: true, description: 'Show two months side by side when the user frequently selects dates that span a month boundary.'},
145
- {guidance: false, description: 'Use a calendar for dates far in the past or future like a birth date. A text input is faster for open-ended entry.'},
146
- {guidance: false, description: 'Disable large blocks of dates without context. The user should understand why dates are unavailable.'},
213
+ {
214
+ guidance: true,
215
+ description:
216
+ 'Set min and max dates to limit selection to a valid window, like only future dates for a booking or the current quarter for a report.',
217
+ },
218
+ {
219
+ guidance: true,
220
+ description:
221
+ 'Use range mode when the user needs to pick a start and end date, like a trip or a time-off request.',
222
+ },
223
+ {
224
+ guidance: true,
225
+ description:
226
+ 'Use dateConstraints to disable specific dates like weekends or holidays, and explain why they are unavailable.',
227
+ },
228
+ {
229
+ guidance: true,
230
+ description:
231
+ 'Show two months side by side when the user frequently selects dates that span a month boundary.',
232
+ },
233
+ {
234
+ guidance: false,
235
+ description:
236
+ 'Use a calendar for dates far in the past or future like a birth date. A text input is faster for open-ended entry.',
237
+ },
238
+ {
239
+ guidance: false,
240
+ description:
241
+ 'Disable large blocks of dates without context. The user should understand why dates are unavailable.',
242
+ },
147
243
  ],
148
244
  },
149
245
  props: [
150
- {name: 'mode', type: "'single' | 'range'", description: '选择模式。', default: "'single'"},
151
- {name: 'value', type: 'ISODateString | DateRange | null', description: '受控选中值。null 表示没有选中值;省略或传入 undefined 为非受控模式。'},
152
- {name: 'defaultValue', type: 'ISODateString | DateRange', description: '非受控默认值。'},
246
+ {
247
+ name: 'mode',
248
+ type: "'single' | 'range'",
249
+ description: '选择模式。',
250
+ default: "'single'",
251
+ },
252
+ {
253
+ name: 'value',
254
+ type: 'ISODateString | DateRange | null',
255
+ description:
256
+ '受控选中值。null 表示没有选中值;省略或传入 undefined 为非受控模式。',
257
+ },
258
+ {
259
+ name: 'defaultValue',
260
+ type: 'ISODateString | DateRange',
261
+ description: '非受控默认值。',
262
+ },
153
263
  {name: 'onChange', type: 'Function', description: '选择回调函数。'},
154
- {name: 'numberOfMonths', type: '1 | 2', description: '显示的月份数量。', default: '1'},
264
+ {
265
+ name: 'numberOfMonths',
266
+ type: '1 | 2',
267
+ description: '显示的月份数量。',
268
+ default: '1',
269
+ },
155
270
  {name: 'min', type: 'ISODateString', description: '可选择的最早日期。'},
156
271
  {name: 'max', type: 'ISODateString', description: '可选择的最晚日期。'},
157
- {name: 'dateConstraints', type: 'Array<(date: Date) => boolean>', description: '自定义约束函数。'},
158
- {name: 'maxRangeSpan', type: 'number', description: '范围模式:范围最多可跨越的天数,含首尾两端(7 = 7 天窗口)。选定起始日后限制窗口大小。'},
159
- {name: 'minRangeSpan', type: 'number', description: '范围模式:范围最少需跨越的天数,含首尾两端(2 表示禁止单日范围)。再次点击开始日期时,若最小范围允许则提交单日范围;否则取消进行中的选择。默认为 1。'},
160
- {name: 'focusDate', type: 'ISODateString', description: '受控可见月份。未设置时,日历打开时显示已选日期所在月份;若无选中值,则显示今天,并将其限制在 min/max 范围内。'},
161
- {name: 'onFocusDateChange', type: '(focusDate: ISODateString) => void', description: '导航回调函数。'},
162
- {name: 'handleRef', type: 'React.Ref<CalendarHandle>', description: '日历导航的命令式句柄,包括 navigateTo()。'},
163
- {name: 'hasOutsideDays', type: 'boolean', description: '显示相邻月份的日期。', default: 'true'},
164
- {name: 'hasWeekNumbers', type: 'boolean', description: '显示 ISO 周数。', default: 'false'},
165
- {name: 'hasVariableRowCount', type: 'boolean', description: '可变行数与固定 6 行网格。', default: 'false'},
166
- {name: 'weekStartsOn', type: "0 | 1 | 2 | 3 | 4 | 5 | 6 | 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'", description: '每周起始日。可为数字(0=周日)或三字母星期缩写(如 "mon")。', default: '0'},
272
+ {
273
+ name: 'dateConstraints',
274
+ type: 'Array<(date: Date) => boolean>',
275
+ description: '自定义约束函数。',
276
+ },
277
+ {
278
+ name: 'maxRangeSpan',
279
+ type: 'number',
280
+ description:
281
+ '范围模式:范围最多可跨越的天数,含首尾两端(7 = 7 天窗口)。选定起始日后限制窗口大小。',
282
+ },
283
+ {
284
+ name: 'minRangeSpan',
285
+ type: 'number',
286
+ description:
287
+ '范围模式:范围最少需跨越的天数,含首尾两端(2 表示禁止单日范围)。再次点击开始日期时,若最小范围允许则提交单日范围;否则取消进行中的选择。默认为 1。',
288
+ },
289
+ {
290
+ name: 'focusDate',
291
+ type: 'ISODateString',
292
+ description:
293
+ '受控可见月份。未设置时,日历打开时显示已选日期所在月份;若无选中值,则显示今天,并将其限制在 min/max 范围内。',
294
+ },
295
+ {
296
+ name: 'onFocusDateChange',
297
+ type: '(focusDate: ISODateString) => void',
298
+ description: '导航回调函数。',
299
+ },
300
+ {
301
+ name: 'handleRef',
302
+ type: 'React.Ref<CalendarHandle>',
303
+ description: '日历导航的命令式句柄,包括 navigateTo()。',
304
+ },
305
+ {
306
+ name: 'hasOutsideDays',
307
+ type: 'boolean',
308
+ description: '显示相邻月份的日期。',
309
+ default: 'true',
310
+ },
311
+ {
312
+ name: 'hasWeekNumbers',
313
+ type: 'boolean',
314
+ description: '显示 ISO 周数。',
315
+ default: 'false',
316
+ },
317
+ {
318
+ name: 'hasVariableRowCount',
319
+ type: 'boolean',
320
+ description: '可变行数与固定 6 行网格。',
321
+ default: 'false',
322
+ },
323
+ {
324
+ name: 'weekStartsOn',
325
+ type: "0 | 1 | 2 | 3 | 4 | 5 | 6 | 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'",
326
+ description:
327
+ '每周起始日。可为数字(0=周日)或三字母星期缩写(如 "mon")。',
328
+ default: '0',
329
+ },
167
330
  ],
168
331
  theming: {
169
332
  targets: [
170
333
  {
171
334
  className: 'astryx-calendar',
172
- visualProps: [
173
- 'mode',
174
- ],
335
+ visualProps: ['mode'],
175
336
  },
176
337
  {
177
338
  className: 'astryx-calendar-nav',
178
- visualProps: [
179
- 'nav',
180
- ],
181
- states: [
182
- 'disabled',
183
- ],
339
+ visualProps: ['nav'],
340
+ states: ['disabled'],
184
341
  },
185
342
  {
186
343
  className: 'astryx-calendar-day',
187
- states: [
188
- 'selected',
189
- 'today',
190
- 'disabled',
191
- 'in-range',
192
- 'marker',
193
- ],
344
+ states: ['selected', 'today', 'disabled', 'in-range', 'marker'],
194
345
  },
195
346
  ],
196
347
  },
@@ -203,11 +354,31 @@ export const docsDense = {
203
354
  description:
204
355
  'Calendar lets the user pick a date or date range from a month grid. Use in booking, scheduling, date filters.',
205
356
  bestPractices: [
206
- {guidance: true, description: 'Set min/max to limit selection to a valid window: only future dates for booking, current quarter for a report.'},
207
- {guidance: true, description: 'Use range mode when user picks start + end dates: trip, time-off request.'},
208
- {guidance: true, description: 'Use dateConstraints to disable specific dates (weekends/holidays); explain why unavailable.'},
209
- {guidance: true, description: 'Show two months side by side when user frequently selects dates spanning a month boundary.'},
210
- {guidance: false, description: 'Use for dates far in the past/future; text input is faster.'},
357
+ {
358
+ guidance: true,
359
+ description:
360
+ 'Set min/max to limit selection to a valid window: only future dates for booking, current quarter for a report.',
361
+ },
362
+ {
363
+ guidance: true,
364
+ description:
365
+ 'Use range mode when user picks start + end dates: trip, time-off request.',
366
+ },
367
+ {
368
+ guidance: true,
369
+ description:
370
+ 'Use dateConstraints to disable specific dates (weekends/holidays); explain why unavailable.',
371
+ },
372
+ {
373
+ guidance: true,
374
+ description:
375
+ 'Show two months side by side when user frequently selects dates spanning a month boundary.',
376
+ },
377
+ {
378
+ guidance: false,
379
+ description:
380
+ 'Use for dates far in the past/future; text input is faster.',
381
+ },
211
382
  {guidance: false, description: 'Disable dates without explaining why.'},
212
383
  ],
213
384
  },
@@ -220,9 +391,12 @@ export const docsDense = {
220
391
  min: 'minimum selectable date',
221
392
  max: 'maximum selectable date',
222
393
  dateConstraints: 'custom constraint fns',
223
- maxRangeSpan: 'range mode: max days a range may span, both ends counted (7 = 7-day window)',
224
- minRangeSpan: 'range mode: min days a range must span, both ends counted; repeated start click commits one day when allowed, otherwise cancels (default 1)',
225
- focusDate: 'controlled visible month (default: selected date, else today clamped into min/max)',
394
+ maxRangeSpan:
395
+ 'range mode: max days a range may span, both ends counted (7 = 7-day window)',
396
+ minRangeSpan:
397
+ 'range mode: min days a range must span, both ends counted; repeated start click commits one day when allowed, otherwise cancels (default 1)',
398
+ focusDate:
399
+ 'controlled visible month (default: selected date, else today clamped into min/max)',
226
400
  onFocusDateChange: 'navigation callback',
227
401
  handleRef: 'imperative navigation handle',
228
402
  hasOutsideDays: 'show days from adjacent months',