@astryxdesign/core 0.1.9-canary.d2d84f8 → 0.1.9-canary.e00a241

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 (414) hide show
  1. package/dist/Avatar/Avatar.d.ts +6 -1
  2. package/dist/Avatar/Avatar.d.ts.map +1 -1
  3. package/dist/Avatar/Avatar.js +46 -12
  4. package/dist/Avatar/AvatarStatusDot.d.ts +6 -4
  5. package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
  6. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  7. package/dist/Breadcrumbs/BreadcrumbItem.js +11 -4
  8. package/dist/Breadcrumbs/index.d.ts +1 -0
  9. package/dist/Breadcrumbs/index.d.ts.map +1 -1
  10. package/dist/Breadcrumbs/index.js +2 -1
  11. package/dist/Calendar/Calendar.d.ts.map +1 -1
  12. package/dist/Calendar/Calendar.js +50 -9
  13. package/dist/Calendar/dayCellUtils.d.ts +4 -4
  14. package/dist/Calendar/dayCellUtils.js +2 -2
  15. package/dist/Calendar/styles.d.ts +30 -31
  16. package/dist/Calendar/styles.d.ts.map +1 -1
  17. package/dist/Calendar/styles.js +30 -31
  18. package/dist/Card/Card.js +1 -1
  19. package/dist/Carousel/Carousel.d.ts.map +1 -1
  20. package/dist/Carousel/Carousel.js +22 -12
  21. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  22. package/dist/Chat/ChatDictationButton.js +3 -1
  23. package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
  24. package/dist/Chat/ChatMessageBubble.js +8 -8
  25. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  26. package/dist/Chat/ChatToolCalls.js +10 -3
  27. package/dist/CheckboxInput/CheckboxInput.js +4 -4
  28. package/dist/Citation/Citation.d.ts +22 -1
  29. package/dist/Citation/Citation.d.ts.map +1 -1
  30. package/dist/Citation/Citation.js +20 -6
  31. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  32. package/dist/CodeBlock/CodeBlock.js +13 -7
  33. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  34. package/dist/Collapsible/Collapsible.js +3 -1
  35. package/dist/CommandPalette/CommandPalette.d.ts +1 -1
  36. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  37. package/dist/CommandPalette/CommandPalette.js +42 -3
  38. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  39. package/dist/ContextMenu/ContextMenu.js +14 -5
  40. package/dist/ContextMenu/index.d.ts +1 -0
  41. package/dist/ContextMenu/index.d.ts.map +1 -1
  42. package/dist/ContextMenu/index.js +3 -1
  43. package/dist/DateInput/DateInput.d.ts +1 -0
  44. package/dist/DateInput/DateInput.d.ts.map +1 -1
  45. package/dist/DateInput/DateInput.js +31 -19
  46. package/dist/DateRangeInput/DateRangeInput.d.ts +1 -0
  47. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  48. package/dist/DateRangeInput/DateRangeInput.js +20 -19
  49. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  50. package/dist/DateTimeInput/DateTimeInput.js +23 -18
  51. package/dist/Divider/Divider.d.ts +2 -2
  52. package/dist/Divider/Divider.d.ts.map +1 -1
  53. package/dist/Divider/Divider.js +13 -0
  54. package/dist/DropdownMenu/DropdownMenu.d.ts +6 -0
  55. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  56. package/dist/DropdownMenu/DropdownMenu.js +22 -5
  57. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  58. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +4 -1
  59. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  60. package/dist/DropdownMenu/DropdownMenuItem.js +4 -1
  61. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  62. package/dist/DropdownMenu/DropdownMenuRadioItem.js +4 -1
  63. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +104 -0
  64. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -0
  65. package/dist/DropdownMenu/DropdownMenuSubMenu.js +427 -0
  66. package/dist/DropdownMenu/index.d.ts +10 -0
  67. package/dist/DropdownMenu/index.d.ts.map +1 -1
  68. package/dist/DropdownMenu/index.js +13 -0
  69. package/dist/DropdownMenu/menuItemHover.d.ts +23 -0
  70. package/dist/DropdownMenu/menuItemHover.d.ts.map +1 -0
  71. package/dist/DropdownMenu/menuItemHover.js +33 -0
  72. package/dist/DropdownMenu/menuItemRoles.d.ts +8 -0
  73. package/dist/DropdownMenu/menuItemRoles.d.ts.map +1 -1
  74. package/dist/DropdownMenu/menuItemRoles.js +10 -1
  75. package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
  76. package/dist/DropdownMenu/renderDropdownItems.js +21 -6
  77. package/dist/Field/Field.d.ts +3 -1
  78. package/dist/Field/Field.d.ts.map +1 -1
  79. package/dist/Field/Field.js +4 -1
  80. package/dist/Field/inputStyles.stylex.d.ts +1 -0
  81. package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
  82. package/dist/Field/inputStyles.stylex.js +1 -0
  83. package/dist/FieldStatus/FieldStatus.d.ts +4 -1
  84. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  85. package/dist/FieldStatus/FieldStatus.js +4 -2
  86. package/dist/FileInput/FileInput.d.ts +1 -0
  87. package/dist/FileInput/FileInput.d.ts.map +1 -1
  88. package/dist/FileInput/FileInput.js +91 -65
  89. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  90. package/dist/HoverCard/useHoverCard.js +10 -4
  91. package/dist/Icon/Icon.d.ts +15 -1
  92. package/dist/Icon/Icon.d.ts.map +1 -1
  93. package/dist/Icon/Icon.js +19 -3
  94. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  95. package/dist/Lightbox/Lightbox.js +15 -9
  96. package/dist/List/List.d.ts.map +1 -1
  97. package/dist/List/List.js +6 -3
  98. package/dist/Markdown/Markdown.d.ts.map +1 -1
  99. package/dist/Markdown/Markdown.js +7 -0
  100. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  101. package/dist/MultiSelector/MultiSelector.js +65 -40
  102. package/dist/NumberInput/NumberInput.d.ts +1 -0
  103. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  104. package/dist/NumberInput/NumberInput.js +20 -17
  105. package/dist/Outline/Outline.js +2 -2
  106. package/dist/RadioList/RadioList.d.ts +2 -2
  107. package/dist/RadioList/RadioListItem.js +4 -4
  108. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  109. package/dist/Resizable/ResizeHandle.js +49 -19
  110. package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
  111. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  112. package/dist/SegmentedControl/SegmentedControlItem.js +2 -1
  113. package/dist/Selector/Selector.d.ts.map +1 -1
  114. package/dist/Selector/Selector.js +58 -16
  115. package/dist/SideNav/SideNav.d.ts.map +1 -1
  116. package/dist/SideNav/SideNav.js +5 -5
  117. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  118. package/dist/SideNav/SideNavCollapseButton.js +13 -10
  119. package/dist/SideNav/SideNavItem.d.ts +1 -1
  120. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  121. package/dist/SideNav/SideNavItem.js +12 -10
  122. package/dist/Slider/Slider.d.ts.map +1 -1
  123. package/dist/Slider/Slider.js +87 -34
  124. package/dist/Spinner/Spinner.d.ts +3 -2
  125. package/dist/Spinner/Spinner.d.ts.map +1 -1
  126. package/dist/Spinner/Spinner.js +11 -2
  127. package/dist/Switch/Switch.d.ts +8 -1
  128. package/dist/Switch/Switch.d.ts.map +1 -1
  129. package/dist/Switch/Switch.js +160 -91
  130. package/dist/TabList/TabList.d.ts +2 -11
  131. package/dist/TabList/TabList.d.ts.map +1 -1
  132. package/dist/TabList/TabList.js +5 -9
  133. package/dist/TabList/TabListContext.d.ts +0 -5
  134. package/dist/TabList/TabListContext.d.ts.map +1 -1
  135. package/dist/TabList/TabListContext.js +0 -5
  136. package/dist/Table/BaseTable.d.ts.map +1 -1
  137. package/dist/Table/BaseTable.js +30 -4
  138. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  139. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +15 -11
  140. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  141. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +36 -26
  142. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  143. package/dist/Table/plugins/selection/useTableSelection.js +3 -0
  144. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  145. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +14 -6
  146. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
  147. package/dist/Table/plugins/tree/useTableTreeData.js +29 -23
  148. package/dist/Table/types.d.ts +32 -0
  149. package/dist/Table/types.d.ts.map +1 -1
  150. package/dist/TextArea/TextArea.d.ts +1 -0
  151. package/dist/TextArea/TextArea.d.ts.map +1 -1
  152. package/dist/TextArea/TextArea.js +16 -19
  153. package/dist/TextInput/TextInput.d.ts +1 -0
  154. package/dist/TextInput/TextInput.d.ts.map +1 -1
  155. package/dist/TextInput/TextInput.js +18 -17
  156. package/dist/TimeInput/TimeInput.d.ts +1 -0
  157. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  158. package/dist/TimeInput/TimeInput.js +15 -17
  159. package/dist/Timestamp/Timestamp.d.ts +31 -3
  160. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  161. package/dist/Timestamp/Timestamp.js +47 -76
  162. package/dist/Timestamp/formatInstant.d.ts +41 -0
  163. package/dist/Timestamp/formatInstant.d.ts.map +1 -0
  164. package/dist/Timestamp/formatInstant.js +177 -0
  165. package/dist/Timestamp/index.d.ts +1 -0
  166. package/dist/Timestamp/index.d.ts.map +1 -1
  167. package/dist/Timestamp/tooltipEntries.d.ts +56 -0
  168. package/dist/Timestamp/tooltipEntries.d.ts.map +1 -0
  169. package/dist/Timestamp/tooltipEntries.js +163 -0
  170. package/dist/Token/Token.d.ts +30 -3
  171. package/dist/Token/Token.d.ts.map +1 -1
  172. package/dist/Token/Token.js +17 -2
  173. package/dist/Token/index.d.ts +1 -1
  174. package/dist/Token/index.d.ts.map +1 -1
  175. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  176. package/dist/Tokenizer/Tokenizer.js +2 -2
  177. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  178. package/dist/Tooltip/useTooltip.js +17 -1
  179. package/dist/TopNav/TopNavItem.d.ts +3 -1
  180. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  181. package/dist/TopNav/TopNavItem.js +30 -3
  182. package/dist/TreeList/TreeList.d.ts.map +1 -1
  183. package/dist/TreeList/TreeList.js +1 -0
  184. package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
  185. package/dist/TreeList/TreeListBranches.js +8 -6
  186. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  187. package/dist/TreeList/TreeListItem.js +32 -14
  188. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  189. package/dist/Typeahead/BaseTypeahead.js +19 -10
  190. package/dist/Typeahead/Typeahead.js +1 -1
  191. package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
  192. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  193. package/dist/Typeahead/TypeaheadItem.js +20 -10
  194. package/dist/astryx.css +38 -14
  195. package/dist/astryx.umd.js +52 -52
  196. package/dist/astryx.umd.js.map +4 -4
  197. package/dist/hooks/index.d.ts +2 -0
  198. package/dist/hooks/index.d.ts.map +1 -1
  199. package/dist/hooks/index.js +1 -0
  200. package/dist/hooks/isRtlElement.d.ts +18 -0
  201. package/dist/hooks/isRtlElement.d.ts.map +1 -0
  202. package/dist/hooks/isRtlElement.js +27 -0
  203. package/dist/hooks/useAnnounce.d.ts +3 -0
  204. package/dist/hooks/useAnnounce.d.ts.map +1 -1
  205. package/dist/hooks/useAnnounce.js +39 -1
  206. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  207. package/dist/hooks/useFocusTrap.js +52 -11
  208. package/dist/hooks/useGridFocus.d.ts +6 -1
  209. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  210. package/dist/hooks/useGridFocus.js +12 -9
  211. package/dist/hooks/useHotkeys.d.ts +9 -0
  212. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  213. package/dist/hooks/useHotkeys.js +9 -0
  214. package/dist/hooks/useInputStatusIcon.d.ts +38 -0
  215. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -0
  216. package/dist/hooks/useInputStatusIcon.js +158 -0
  217. package/dist/hooks/useListFocus.d.ts +39 -1
  218. package/dist/hooks/useListFocus.d.ts.map +1 -1
  219. package/dist/hooks/useListFocus.js +54 -9
  220. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  221. package/dist/theme/derivedVarRegistry.js +13 -0
  222. package/dist/utils/index.d.ts +1 -0
  223. package/dist/utils/index.d.ts.map +1 -1
  224. package/dist/utils/index.js +2 -1
  225. package/dist/utils/plainDate.d.ts +17 -0
  226. package/dist/utils/plainDate.d.ts.map +1 -1
  227. package/dist/utils/plainDate.js +23 -4
  228. package/dist/utils/rtlStyles.d.ts +24 -0
  229. package/dist/utils/rtlStyles.d.ts.map +1 -0
  230. package/dist/utils/rtlStyles.js +27 -0
  231. package/locales/en.json +76 -0
  232. package/locales/pseudo.json +57 -0
  233. package/package.json +6 -1
  234. package/src/Avatar/Avatar.doc.mjs +18 -4
  235. package/src/Avatar/Avatar.test.tsx +106 -0
  236. package/src/Avatar/Avatar.tsx +62 -10
  237. package/src/Avatar/AvatarStatusDot.doc.mjs +4 -4
  238. package/src/Avatar/AvatarStatusDot.tsx +6 -4
  239. package/src/AvatarGroup/AvatarGroup.test.tsx +16 -1
  240. package/src/Breadcrumbs/BreadcrumbItem.tsx +10 -10
  241. package/src/Breadcrumbs/Breadcrumbs.test.tsx +51 -0
  242. package/src/Breadcrumbs/index.ts +4 -0
  243. package/src/Button/Button.doc.mjs +0 -4
  244. package/src/Calendar/Calendar.test.tsx +170 -20
  245. package/src/Calendar/Calendar.tsx +73 -16
  246. package/src/Calendar/dayCellUtils.test.ts +18 -18
  247. package/src/Calendar/dayCellUtils.ts +2 -2
  248. package/src/Calendar/styles.ts +33 -39
  249. package/src/Card/Card.tsx +1 -1
  250. package/src/Carousel/Carousel.tsx +25 -6
  251. package/src/Chat/ChatComposer.doc.mjs +2 -2
  252. package/src/Chat/ChatComposerInput.doc.mjs +1 -1
  253. package/src/Chat/ChatDictationButton.tsx +7 -1
  254. package/src/Chat/ChatMessageBubble.tsx +15 -10
  255. package/src/Chat/ChatSystemMessage.test.tsx +5 -0
  256. package/src/Chat/ChatToolCalls.tsx +9 -2
  257. package/src/CheckboxInput/CheckboxInput.doc.mjs +6 -0
  258. package/src/CheckboxInput/CheckboxInput.tsx +4 -4
  259. package/src/CheckboxList/CheckboxList.doc.mjs +6 -0
  260. package/src/Citation/Citation.doc.mjs +4 -3
  261. package/src/Citation/Citation.test.tsx +97 -0
  262. package/src/Citation/Citation.tsx +43 -11
  263. package/src/CodeBlock/CodeBlock.tsx +35 -8
  264. package/src/Collapsible/Collapsible.doc.mjs +1 -0
  265. package/src/Collapsible/Collapsible.test.tsx +7 -0
  266. package/src/Collapsible/Collapsible.tsx +16 -6
  267. package/src/CommandPalette/CommandPalette.test.tsx +95 -1
  268. package/src/CommandPalette/CommandPalette.tsx +41 -2
  269. package/src/ContextMenu/ContextMenu.test.tsx +42 -0
  270. package/src/ContextMenu/ContextMenu.tsx +13 -11
  271. package/src/ContextMenu/index.ts +5 -0
  272. package/src/DateInput/DateInput.doc.mjs +15 -5
  273. package/src/DateInput/DateInput.test.tsx +210 -3
  274. package/src/DateInput/DateInput.tsx +41 -29
  275. package/src/DateRangeInput/DateRangeInput.doc.mjs +11 -3
  276. package/src/DateRangeInput/DateRangeInput.test.tsx +120 -3
  277. package/src/DateRangeInput/DateRangeInput.tsx +29 -27
  278. package/src/DateTimeInput/DateTimeInput.doc.mjs +22 -1
  279. package/src/DateTimeInput/DateTimeInput.test.tsx +112 -0
  280. package/src/DateTimeInput/DateTimeInput.tsx +44 -39
  281. package/src/Divider/Divider.test.tsx +32 -8
  282. package/src/Divider/Divider.tsx +14 -1
  283. package/src/DropdownMenu/DropdownMenu.test.tsx +60 -0
  284. package/src/DropdownMenu/DropdownMenu.tsx +31 -12
  285. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +8 -2
  286. package/src/DropdownMenu/DropdownMenuItem.tsx +8 -2
  287. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +8 -2
  288. package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +88 -0
  289. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +635 -0
  290. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +553 -0
  291. package/src/DropdownMenu/index.ts +16 -0
  292. package/src/DropdownMenu/menuItemHover.ts +39 -0
  293. package/src/DropdownMenu/menuItemRoles.ts +9 -0
  294. package/src/DropdownMenu/renderDropdownItems.tsx +29 -15
  295. package/src/Field/Field.tsx +14 -9
  296. package/src/Field/inputStyles.stylex.ts +2 -0
  297. package/src/FieldStatus/FieldStatus.tsx +10 -4
  298. package/src/FileInput/FileInput.doc.mjs +13 -7
  299. package/src/FileInput/FileInput.test.tsx +84 -16
  300. package/src/FileInput/FileInput.tsx +96 -79
  301. package/src/HoverCard/useHoverCard.tsx +15 -3
  302. package/src/Icon/Icon.doc.mjs +13 -0
  303. package/src/Icon/Icon.test.tsx +89 -0
  304. package/src/Icon/Icon.tsx +51 -3
  305. package/src/Lightbox/Lightbox.tsx +11 -3
  306. package/src/List/List.test.tsx +17 -29
  307. package/src/List/List.tsx +6 -1
  308. package/src/Markdown/Markdown.test.tsx +21 -0
  309. package/src/Markdown/Markdown.tsx +4 -0
  310. package/src/MultiSelector/MultiSelector.doc.mjs +11 -0
  311. package/src/MultiSelector/MultiSelector.test.tsx +306 -3
  312. package/src/MultiSelector/MultiSelector.tsx +88 -57
  313. package/src/NumberInput/NumberInput.doc.mjs +11 -5
  314. package/src/NumberInput/NumberInput.test.tsx +48 -0
  315. package/src/NumberInput/NumberInput.tsx +25 -26
  316. package/src/Outline/Outline.test.tsx +12 -12
  317. package/src/Outline/Outline.tsx +2 -2
  318. package/src/RadioList/RadioList.doc.mjs +6 -0
  319. package/src/RadioList/RadioList.tsx +2 -2
  320. package/src/RadioList/RadioListItem.tsx +4 -4
  321. package/src/Resizable/ResizeHandle.test.tsx +94 -0
  322. package/src/Resizable/ResizeHandle.tsx +70 -20
  323. package/src/SegmentedControl/SegmentedControlItem.tsx +2 -0
  324. package/src/Selector/Selector.doc.mjs +8 -0
  325. package/src/Selector/Selector.test.tsx +328 -3
  326. package/src/Selector/Selector.tsx +70 -19
  327. package/src/SideNav/SideNav.tsx +1 -8
  328. package/src/SideNav/SideNavCollapseButton.tsx +9 -7
  329. package/src/SideNav/SideNavItem.tsx +5 -3
  330. package/src/Slider/Slider.doc.mjs +6 -0
  331. package/src/Slider/Slider.test.tsx +240 -12
  332. package/src/Slider/Slider.tsx +96 -23
  333. package/src/Spinner/Spinner.test.tsx +10 -8
  334. package/src/Spinner/Spinner.tsx +15 -5
  335. package/src/Switch/Switch.doc.mjs +142 -42
  336. package/src/Switch/Switch.test.tsx +22 -0
  337. package/src/Switch/Switch.tsx +90 -33
  338. package/src/TabList/TabList.doc.mjs +0 -6
  339. package/src/TabList/TabList.test.tsx +3 -15
  340. package/src/TabList/TabList.tsx +6 -17
  341. package/src/TabList/TabListContext.ts +0 -6
  342. package/src/Table/BaseTable.tsx +34 -2
  343. package/src/Table/Table.doc.mjs +11 -0
  344. package/src/Table/Table.test.tsx +85 -0
  345. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +9 -6
  346. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +24 -17
  347. package/src/Table/plugins/selection/useTableSelection.test.tsx +61 -3
  348. package/src/Table/plugins/selection/useTableSelection.tsx +3 -0
  349. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +37 -8
  350. package/src/Table/plugins/tree/useTableTreeData.tsx +17 -13
  351. package/src/Table/types.ts +33 -0
  352. package/src/Table/useTableRowStatus.doc.mjs +1 -1
  353. package/src/TextArea/TextArea.doc.mjs +11 -5
  354. package/src/TextArea/TextArea.tsx +17 -26
  355. package/src/TextInput/TextInput.doc.mjs +11 -5
  356. package/src/TextInput/TextInput.test.tsx +130 -3
  357. package/src/TextInput/TextInput.tsx +18 -25
  358. package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
  359. package/src/TimeInput/TimeInput.doc.mjs +11 -5
  360. package/src/TimeInput/TimeInput.tsx +14 -25
  361. package/src/Timestamp/Timestamp.doc.mjs +32 -6
  362. package/src/Timestamp/Timestamp.test.tsx +371 -0
  363. package/src/Timestamp/Timestamp.tsx +96 -93
  364. package/src/Timestamp/formatInstant.ts +218 -0
  365. package/src/Timestamp/index.ts +4 -0
  366. package/src/Timestamp/tooltipEntries.test.ts +552 -0
  367. package/src/Timestamp/tooltipEntries.ts +210 -0
  368. package/src/Token/Token.test.tsx +21 -15
  369. package/src/Token/Token.tsx +31 -14
  370. package/src/Token/index.ts +1 -1
  371. package/src/Tokenizer/Tokenizer.doc.mjs +8 -1
  372. package/src/Tokenizer/Tokenizer.tsx +4 -2
  373. package/src/Tooltip/Tooltip.test.tsx +46 -0
  374. package/src/Tooltip/useTooltip.tsx +20 -0
  375. package/src/TopNav/TopNav.test.tsx +93 -2
  376. package/src/TopNav/TopNavItem.doc.mjs +3 -3
  377. package/src/TopNav/TopNavItem.tsx +35 -6
  378. package/src/TopNav/TopNavMegaMenuFeaturedCard.doc.mjs +1 -1
  379. package/src/TreeList/TreeList.doc.mjs +6 -0
  380. package/src/TreeList/TreeList.test.tsx +50 -10
  381. package/src/TreeList/TreeList.tsx +5 -0
  382. package/src/TreeList/TreeListBranches.tsx +8 -6
  383. package/src/TreeList/TreeListItem.tsx +33 -11
  384. package/src/Typeahead/BaseTypeahead.tsx +29 -14
  385. package/src/Typeahead/Typeahead.doc.mjs +6 -0
  386. package/src/Typeahead/Typeahead.test.tsx +27 -0
  387. package/src/Typeahead/Typeahead.tsx +1 -1
  388. package/src/Typeahead/TypeaheadItem.tsx +2 -1
  389. package/src/__tests__/inputWidthContract.test.tsx +62 -0
  390. package/src/doc-mjs.d.ts +19 -0
  391. package/src/hooks/index.ts +6 -0
  392. package/src/hooks/isRtlElement.ts +27 -0
  393. package/src/hooks/useAnnounce.test.tsx +75 -2
  394. package/src/hooks/useAnnounce.ts +47 -1
  395. package/src/hooks/useFocusTrap.test.tsx +104 -0
  396. package/src/hooks/useFocusTrap.ts +61 -12
  397. package/src/hooks/useGridFocus.doc.mjs +3 -3
  398. package/src/hooks/useGridFocus.test.tsx +41 -0
  399. package/src/hooks/useGridFocus.ts +21 -10
  400. package/src/hooks/useHotkeys.ts +9 -0
  401. package/src/hooks/useInputStatusIcon.test.tsx +162 -0
  402. package/src/hooks/useInputStatusIcon.tsx +224 -0
  403. package/src/hooks/useListFocus.doc.mjs +25 -3
  404. package/src/hooks/useListFocus.test.tsx +153 -1
  405. package/src/hooks/useListFocus.ts +102 -9
  406. package/src/reset.css +0 -26
  407. package/src/reset.test.ts +60 -0
  408. package/src/theme/derivedVarRegistry.test.ts +1 -0
  409. package/src/theme/derivedVarRegistry.ts +6 -0
  410. package/src/theme/generateThemeRules.test.ts +42 -0
  411. package/src/utils/index.ts +2 -0
  412. package/src/utils/plainDate.test.ts +24 -6
  413. package/src/utils/plainDate.ts +18 -4
  414. package/src/utils/rtlStyles.ts +27 -0
@@ -136,35 +136,23 @@ describe('List', () => {
136
136
  expect(container.querySelector('ul')).toBeInTheDocument();
137
137
  });
138
138
 
139
- it('adds role="list" when listStyle is none (Safari fix)', () => {
140
- const {container} = render(
141
- <List>
142
- <ListItem label="Item" />
143
- </List>,
144
- );
145
- const ul = container.querySelector('ul');
146
- expect(ul).toHaveAttribute('role', 'list');
147
- });
148
-
149
- it('does not add role="list" when listStyle is disc', () => {
150
- const {container} = render(
151
- <List listStyle="disc">
152
- <ListItem label="Item" />
153
- </List>,
154
- );
155
- const ul = container.querySelector('ul');
156
- expect(ul).not.toHaveAttribute('role');
157
- });
158
-
159
- it('does not add role="list" when listStyle is decimal', () => {
160
- const {container} = render(
161
- <List listStyle="decimal">
162
- <ListItem label="Item" />
163
- </List>,
164
- );
165
- const ol = container.querySelector('ol');
166
- expect(ol).not.toHaveAttribute('role');
167
- });
139
+ it.each(['none', 'disc', 'circle', 'decimal'] as const)(
140
+ 'adds an explicit role="list" when listStyle is %s (Safari fix)',
141
+ listStyle => {
142
+ // The base list style always sets list-style-type: none (markers are
143
+ // custom-rendered by ListItem), so Safari/VoiceOver drops the implicit
144
+ // list role for EVERY variant — the explicit role must always be there.
145
+ render(
146
+ <List listStyle={listStyle}>
147
+ <ListItem label="Item 1" />
148
+ <ListItem label="Item 2" />
149
+ </List>,
150
+ );
151
+ const list = screen.getByRole('list');
152
+ expect(list).toHaveAttribute('role', 'list');
153
+ expect(screen.getAllByRole('listitem')).toHaveLength(2);
154
+ },
155
+ );
168
156
 
169
157
  it('renders items as <li> elements', () => {
170
158
  const {container} = render(
package/src/List/List.tsx CHANGED
@@ -168,7 +168,12 @@ export function List({
168
168
  data-testid={testId}
169
169
  aria-labelledby={header != null ? headerId : undefined}
170
170
  {...(isOrdered && start != null && start !== 1 ? {start} : {})}
171
- {...(listStyle === 'none' && !isOrdered ? {role: 'list'} : {})}
171
+ // The base list style always sets list-style-type: none (markers are
172
+ // custom-rendered by ListItem), and Safari/VoiceOver drops implicit
173
+ // list semantics for lists styled with list-style: none. The explicit
174
+ // role restores "list, N items" announcements for every listStyle
175
+ // variant.
176
+ role="list"
172
177
  {...mergeProps(
173
178
  themeProps('list', {density, listStyle}),
174
179
  stylex.props(
@@ -236,6 +236,27 @@ describe('Markdown', () => {
236
236
  expect(img!.getAttribute('src')).toBe('image.png');
237
237
  });
238
238
 
239
+ it('uses the components.image override for a standalone (block) image', () => {
240
+ // A standalone image line parses as a block image; its render path must
241
+ // honor components.image just like the inline image path does.
242
+ render(
243
+ <Markdown
244
+ components={{
245
+ image: ({src, alt}) => (
246
+ <span data-testid="custom-image" data-src={src}>
247
+ {alt}
248
+ </span>
249
+ ),
250
+ }}>
251
+ {'![alt text](image.png)'}
252
+ </Markdown>,
253
+ );
254
+ expect(document.querySelector('img')).not.toBeInTheDocument();
255
+ const custom = screen.getByTestId('custom-image');
256
+ expect(custom).toHaveTextContent('alt text');
257
+ expect(custom.getAttribute('data-src')).toBe('image.png');
258
+ });
259
+
239
260
  it('shifts heading levels with headingLevelStart', () => {
240
261
  render(<Markdown headingLevelStart={3}>{'# Heading 1'}</Markdown>);
241
262
  expect(screen.getByText('Heading 1').tagName).toBe('H3');
@@ -1523,6 +1523,10 @@ function renderBlock(
1523
1523
  </div>
1524
1524
  );
1525
1525
  }
1526
+ const ImageComp = components?.image;
1527
+ if (ImageComp) {
1528
+ return <ImageComp key={index} src={safeSrc} alt={node.alt} />;
1529
+ }
1526
1530
  return (
1527
1531
  <div
1528
1532
  key={index}
@@ -21,6 +21,11 @@ export const docs = {
21
21
  theming: {
22
22
  targets: [
23
23
  {className: 'astryx-multi-selector', visualProps: ['size', 'status']},
24
+ {className: 'astryx-multi-selector-clear-icon'},
25
+ {
26
+ className: 'astryx-multi-selector-indicator-icon',
27
+ states: ['state'],
28
+ },
24
29
  ],
25
30
  },
26
31
  components: [
@@ -168,6 +173,12 @@ export const docs = {
168
173
  description:
169
174
  'Custom render function for each selectable option in the dropdown. Not called for dividers, sections, or the select-all row.',
170
175
  },
176
+ {
177
+ name: 'width',
178
+ type: 'SizeValue',
179
+ description:
180
+ 'Width of the field (number = pixels, string used as-is, e.g. "100%"). Sizes the whole field (label, control, and status) so they stay aligned.',
181
+ },
171
182
  {
172
183
  name: 'xstyle',
173
184
  type: 'StyleXStyles',
@@ -19,7 +19,10 @@ import {
19
19
  } from '@testing-library/react';
20
20
  import userEvent from '@testing-library/user-event';
21
21
  import {MultiSelector} from './MultiSelector';
22
+ import {Icon} from '../Icon';
22
23
  import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
24
+ import {defineTheme} from '../theme/defineTheme';
25
+ import {generateThemeCSSFlat} from '../theme/generateThemeRules';
23
26
 
24
27
  // Module-level constants to satisfy @eslint-react/no-unstable-default-props.
25
28
  const ANNOUNCE_OPTIONS = ['Apple', 'Banana', 'Orange'] as const;
@@ -565,6 +568,72 @@ describe('MultiSelector', () => {
565
568
  expect(options).toHaveLength(1);
566
569
  });
567
570
 
571
+ describe('grouped search', () => {
572
+ const GROUPED = [
573
+ {
574
+ type: 'section' as const,
575
+ title: 'Citrus',
576
+ options: [
577
+ {value: 'orange', label: 'Orange'},
578
+ {value: 'lemon', label: 'Lemon'},
579
+ ],
580
+ },
581
+ {
582
+ type: 'section' as const,
583
+ title: 'Berries',
584
+ options: [
585
+ {value: 'strawberry', label: 'Strawberry'},
586
+ {value: 'blueberry', label: 'Blueberry'},
587
+ ],
588
+ },
589
+ ];
590
+
591
+ it('keeps the group header above matching items while searching', async () => {
592
+ const user = userEvent.setup();
593
+ render(
594
+ <MultiSelector
595
+ label="Fruit"
596
+ options={GROUPED}
597
+ value={[]}
598
+ onChange={() => {}}
599
+ hasSearch
600
+ />,
601
+ );
602
+ await user.click(screen.getByRole('button', {name: 'Fruit'}));
603
+ await user.type(screen.getByRole('combobox', h), 'orange');
604
+
605
+ expect(
606
+ screen.getByRole('group', {name: 'Citrus', ...h}),
607
+ ).toBeInTheDocument();
608
+ const options = screen.getAllByRole('option', h);
609
+ expect(options).toHaveLength(1);
610
+ expect(options[0]).toHaveTextContent('Orange');
611
+ });
612
+
613
+ it('hides a group whose items have no match', async () => {
614
+ const user = userEvent.setup();
615
+ render(
616
+ <MultiSelector
617
+ label="Fruit"
618
+ options={GROUPED}
619
+ value={[]}
620
+ onChange={() => {}}
621
+ hasSearch
622
+ />,
623
+ );
624
+ await user.click(screen.getByRole('button', {name: 'Fruit'}));
625
+ await user.type(screen.getByRole('combobox', h), 'berry');
626
+
627
+ expect(
628
+ screen.getByRole('group', {name: 'Berries', ...h}),
629
+ ).toBeInTheDocument();
630
+ expect(
631
+ screen.queryByRole('group', {name: 'Citrus', ...h}),
632
+ ).not.toBeInTheDocument();
633
+ expect(screen.getAllByRole('option', h)).toHaveLength(2);
634
+ });
635
+ });
636
+
568
637
  it('PageDown/PageUp jump the highlight to the last/first filtered option', async () => {
569
638
  const user = userEvent.setup();
570
639
  render(
@@ -1246,11 +1315,16 @@ describe('MultiSelector', () => {
1246
1315
  });
1247
1316
  });
1248
1317
 
1249
-
1250
1318
  describe('MultiSelector statusVariant forwarding', () => {
1251
1319
  it('defaults to attached (status renders with data-variant="attached")', () => {
1252
1320
  const {container} = render(
1253
- <MultiSelector label="Fruit" options={['Apple', 'Banana']} value={[]} onChange={() => {}} status={{type: 'error', message: 'Required'}} />,
1321
+ <MultiSelector
1322
+ label="Fruit"
1323
+ options={['Apple', 'Banana']}
1324
+ value={[]}
1325
+ onChange={() => {}}
1326
+ status={{type: 'error', message: 'Required'}}
1327
+ />,
1254
1328
  );
1255
1329
  expect(container.querySelector('.astryx-field-status')).toHaveAttribute(
1256
1330
  'data-variant',
@@ -1260,7 +1334,14 @@ describe('MultiSelector statusVariant forwarding', () => {
1260
1334
 
1261
1335
  it('forwards statusVariant="detached" to the underlying Field status', () => {
1262
1336
  const {container} = render(
1263
- <MultiSelector label="Fruit" options={['Apple', 'Banana']} value={[]} onChange={() => {}} status={{type: 'error', message: 'Required'}} statusVariant="detached" />,
1337
+ <MultiSelector
1338
+ label="Fruit"
1339
+ options={['Apple', 'Banana']}
1340
+ value={[]}
1341
+ onChange={() => {}}
1342
+ status={{type: 'error', message: 'Required'}}
1343
+ statusVariant="detached"
1344
+ />,
1264
1345
  );
1265
1346
  expect(container.querySelector('.astryx-field-status')).toHaveAttribute(
1266
1347
  'data-variant',
@@ -1268,3 +1349,225 @@ describe('MultiSelector statusVariant forwarding', () => {
1268
1349
  );
1269
1350
  });
1270
1351
  });
1352
+
1353
+ describe('MultiSelector clear icon theme target', () => {
1354
+ const ICON_OPTIONS = ['Apple', 'Banana', 'Orange'];
1355
+
1356
+ // Resolve the clear glyph span (the astryx-icon element inside the clear
1357
+ // button), independent of the theme target class.
1358
+ const getClearIcon = (): HTMLElement => {
1359
+ const button = screen.getByRole('button', {name: 'Clear all Fruit'});
1360
+ const icon = button.querySelector('.astryx-icon');
1361
+ if (icon == null) {
1362
+ throw new Error('clear icon not found');
1363
+ }
1364
+ return icon as HTMLElement;
1365
+ };
1366
+
1367
+ it('renders the astryx-multi-selector-clear-icon target on the clear glyph', () => {
1368
+ render(
1369
+ <MultiSelector
1370
+ label="Fruit"
1371
+ options={ICON_OPTIONS}
1372
+ value={['Banana']}
1373
+ onChange={() => {}}
1374
+ hasClear
1375
+ />,
1376
+ );
1377
+ // The stable theme target lands on the icon element itself (not the
1378
+ // button), so a theme can restyle just this glyph (color, size, hover)
1379
+ // via `defineTheme` — a button-level target could not reach the icon's
1380
+ // own color/size.
1381
+ const icon = getClearIcon();
1382
+ expect(icon).toHaveClass('astryx-multi-selector-clear-icon');
1383
+ expect(icon).toHaveClass('astryx-icon');
1384
+ });
1385
+
1386
+ it('keeps the clear button functional alongside the target', () => {
1387
+ const onChange = vi.fn();
1388
+ render(
1389
+ <MultiSelector
1390
+ label="Fruit"
1391
+ options={ICON_OPTIONS}
1392
+ value={['Banana']}
1393
+ onChange={onChange}
1394
+ hasClear
1395
+ />,
1396
+ );
1397
+ const clear = screen.getByRole('button', {name: 'Clear all Fruit'});
1398
+ expect(clear.tagName).toBe('BUTTON');
1399
+ fireEvent.click(clear);
1400
+ expect(onChange).toHaveBeenCalledWith([]);
1401
+ });
1402
+
1403
+ it('renders the default icon (secondary color, sm size) byte-identically', () => {
1404
+ // Pixel-identical default guard: the clear glyph must carry the exact same
1405
+ // StyleX color/size classes as a standalone secondary/sm icon. The added
1406
+ // target class is purely additive — it changes nothing until a theme
1407
+ // targets it.
1408
+ render(
1409
+ <MultiSelector
1410
+ label="Fruit"
1411
+ options={ICON_OPTIONS}
1412
+ value={['Banana']}
1413
+ onChange={() => {}}
1414
+ hasClear
1415
+ />,
1416
+ );
1417
+ const icon = getClearIcon();
1418
+
1419
+ const {container: refContainer} = render(
1420
+ <Icon icon="close" size="sm" color="secondary" />,
1421
+ );
1422
+ const refIcon = refContainer.querySelector('.astryx-icon') as HTMLElement;
1423
+
1424
+ const styleClasses = (el: HTMLElement) =>
1425
+ el.className
1426
+ .split(' ')
1427
+ .filter(c => c !== 'astryx-multi-selector-clear-icon')
1428
+ .sort();
1429
+
1430
+ expect(styleClasses(icon)).toEqual(styleClasses(refIcon));
1431
+ });
1432
+
1433
+ it('exposes multi-selector-clear-icon so a theme reaches the icon color, size, and hover', () => {
1434
+ // jsdom cannot resolve the @layer cascade, so the DOM-class assertion above
1435
+ // (target lands on the icon element) plus this generation assertion (the
1436
+ // theme emits same-element icon rules in @layer astryx-theme) together
1437
+ // prove the seam: a same-element theme rule wins over the icon's own
1438
+ // base-layer color/size.
1439
+ const theme = defineTheme({
1440
+ name: 'multi-selector-clear-icon-test',
1441
+ components: {
1442
+ 'multi-selector-clear-icon': {
1443
+ base: {
1444
+ width: '12px',
1445
+ height: '12px',
1446
+ fontSize: '12px',
1447
+ color: 'var(--color-icon-secondary)',
1448
+ ':hover': {color: 'var(--color-icon-primary)'},
1449
+ },
1450
+ },
1451
+ },
1452
+ });
1453
+ const css = generateThemeCSSFlat(theme);
1454
+ expect(css).toContain('.astryx-multi-selector-clear-icon {');
1455
+ expect(css).toContain('width: 12px');
1456
+ expect(css).toContain('height: 12px');
1457
+ expect(css).toContain('.astryx-multi-selector-clear-icon:hover {');
1458
+ expect(css).toContain('color: var(--color-icon-primary)');
1459
+ });
1460
+ });
1461
+
1462
+ describe('MultiSelector indicator (chevron) icon theme target', () => {
1463
+ const ICON_OPTIONS = ['Apple', 'Banana', 'Orange'];
1464
+
1465
+ const getIndicatorIcon = (container: HTMLElement): HTMLElement => {
1466
+ // The chevron is the only glyph carrying the indicator target class.
1467
+ const icon = container.querySelector(
1468
+ '.astryx-multi-selector-indicator-icon',
1469
+ );
1470
+ if (icon == null) {
1471
+ throw new Error('indicator icon not found');
1472
+ }
1473
+ return icon as HTMLElement;
1474
+ };
1475
+
1476
+ it('renders the astryx-multi-selector-indicator-icon target on the chevron glyph', () => {
1477
+ const {container} = render(
1478
+ <MultiSelector
1479
+ label="Fruit"
1480
+ options={ICON_OPTIONS}
1481
+ value={[]}
1482
+ onChange={() => {}}
1483
+ />,
1484
+ );
1485
+ // The stable theme target lands on the icon element itself (not the trigger
1486
+ // button), so a theme can restyle just this glyph (color, size, hover) —
1487
+ // and each open/closed state — via `defineTheme`. A button-level target
1488
+ // could not reach the icon's own color/size.
1489
+ const icon = getIndicatorIcon(container);
1490
+ expect(icon).toHaveClass('astryx-multi-selector-indicator-icon');
1491
+ expect(icon).toHaveClass('astryx-icon');
1492
+ // Open/closed state is reflected so a theme can target each state alone.
1493
+ expect(icon).toHaveAttribute('data-state', 'collapsed');
1494
+ });
1495
+
1496
+ it('reflects the expanded state on the chevron when the popover is open', async () => {
1497
+ const user = userEvent.setup();
1498
+ const {container} = render(
1499
+ <MultiSelector
1500
+ label="Fruit"
1501
+ options={ICON_OPTIONS}
1502
+ value={[]}
1503
+ onChange={() => {}}
1504
+ />,
1505
+ );
1506
+ await user.click(screen.getByRole('combobox'));
1507
+ await waitFor(() => {
1508
+ expect(getIndicatorIcon(container)).toHaveAttribute(
1509
+ 'data-state',
1510
+ 'expanded',
1511
+ );
1512
+ });
1513
+ });
1514
+
1515
+ it('renders the default icon (inherit color, sm size) byte-identically', () => {
1516
+ // Pixel-identical default guard: the chevron glyph must carry the exact
1517
+ // same StyleX color/size classes as a standalone inherit/sm icon. The added
1518
+ // target class + data-state are purely additive — they change nothing until
1519
+ // a theme targets them.
1520
+ const {container} = render(
1521
+ <MultiSelector
1522
+ label="Fruit"
1523
+ options={ICON_OPTIONS}
1524
+ value={[]}
1525
+ onChange={() => {}}
1526
+ />,
1527
+ );
1528
+ const icon = getIndicatorIcon(container);
1529
+
1530
+ const {container: refContainer} = render(
1531
+ <Icon icon="chevronDown" size="sm" color="inherit" />,
1532
+ );
1533
+ const refIcon = refContainer.querySelector('.astryx-icon') as HTMLElement;
1534
+
1535
+ // Exclude the additive theme-target classes (the stable target + its
1536
+ // reflected state class) so only the StyleX color/size classes remain.
1537
+ const themeTargetClasses = new Set([
1538
+ 'astryx-multi-selector-indicator-icon',
1539
+ 'collapsed',
1540
+ 'expanded',
1541
+ ]);
1542
+ const styleClasses = (el: HTMLElement) =>
1543
+ el.className
1544
+ .split(' ')
1545
+ .filter(c => !themeTargetClasses.has(c))
1546
+ .sort();
1547
+
1548
+ expect(styleClasses(icon)).toEqual(styleClasses(refIcon));
1549
+ });
1550
+
1551
+ it('exposes multi-selector-indicator-icon so a theme reaches the icon size and per-state color', () => {
1552
+ // jsdom cannot resolve the @layer cascade, so the DOM-class assertions
1553
+ // above (target lands on the icon element) plus this generation assertion
1554
+ // (the theme emits same-element icon rules in @layer astryx-theme) together
1555
+ // prove the seam: a same-element theme rule wins over the icon's own
1556
+ // base-layer color/size.
1557
+ const theme = defineTheme({
1558
+ name: 'multi-selector-indicator-icon-test',
1559
+ components: {
1560
+ 'multi-selector-indicator-icon': {
1561
+ base: {width: '14px', height: '14px', fontSize: '14px'},
1562
+ 'state:expanded': {color: 'var(--color-icon-primary)'},
1563
+ },
1564
+ },
1565
+ });
1566
+ const css = generateThemeCSSFlat(theme);
1567
+ expect(css).toContain('.astryx-multi-selector-indicator-icon {');
1568
+ expect(css).toContain('width: 14px');
1569
+ expect(css).toContain('height: 14px');
1570
+ expect(css).toContain('.astryx-multi-selector-indicator-icon.expanded');
1571
+ expect(css).toContain('color: var(--color-icon-primary)');
1572
+ });
1573
+ });