@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
@@ -15,16 +15,17 @@
15
15
  * - /apps/storybook/stories/Timestamp.stories.tsx
16
16
  * - /packages/cli/templates/blocks/components/Timestamp/ (showcase blocks)
17
17
  */
18
- import { useEffect, useRef, useState, lazy, Suspense } from 'react';
18
+ import { useEffect, useRef, useState, lazy, Suspense, Fragment } from 'react';
19
19
  import * as stylex from '@stylexjs/stylex';
20
20
  import { Text } from "../Text/index.js";
21
21
  import { mergeProps, mergeRefs } from "../utils/index.js";
22
22
  import { useDevWarning } from "../hooks/useDevWarning.js";
23
23
  import { themeProps } from "../utils/themeProps.js";
24
24
  import "../theme/tokens.stylex.js";
25
- import { colorVars } from "../theme/tokens.stylex.js";
26
- import { SHARED_DATE_FORMAT_OPTIONS } from "../utils/plainDate.js";
27
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
25
+ import { colorVars, spacingVars } from "../theme/tokens.stylex.js";
26
+ import { formatInstant } from "./formatInstant.js";
27
+ import { formatTooltipLines } from "./tooltipEntries.js";
28
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
28
29
  const LazyXDSTooltip = /*#__PURE__*/lazy(async () => import('../Tooltip/Tooltip').then(mod => ({
29
30
  default: mod.Tooltip
30
31
  })));
@@ -137,73 +138,6 @@ function getRelativeTimeString(date, now) {
137
138
  const years = Math.floor(diffSeconds / YEAR);
138
139
  return `${years} ${years === 1 ? 'year' : 'years'} ago`;
139
140
  }
140
- function pad(n) {
141
- return String(n).padStart(2, '0');
142
- }
143
- function formatTimestamp(date, format, isTimezoneShown) {
144
- switch (format) {
145
- case 'date':
146
- return new Intl.DateTimeFormat(undefined, SHARED_DATE_FORMAT_OPTIONS.date).format(date);
147
- case 'date_long':
148
- return new Intl.DateTimeFormat(undefined, SHARED_DATE_FORMAT_OPTIONS.date_long).format(date);
149
- case 'date_weekday':
150
- return new Intl.DateTimeFormat(undefined, SHARED_DATE_FORMAT_OPTIONS.date_weekday).format(date);
151
- case 'date_time':
152
- return new Intl.DateTimeFormat(undefined, {
153
- year: 'numeric',
154
- month: 'short',
155
- day: 'numeric',
156
- hour: 'numeric',
157
- minute: '2-digit',
158
- ...(isTimezoneShown ? {
159
- timeZoneName: 'short'
160
- } : {})
161
- }).format(date);
162
- case 'time':
163
- return new Intl.DateTimeFormat(undefined, {
164
- hour: 'numeric',
165
- minute: '2-digit',
166
- ...(isTimezoneShown ? {
167
- timeZoneName: 'short'
168
- } : {})
169
- }).format(date);
170
- case 'system_date':
171
- {
172
- const y = date.getFullYear();
173
- const m = pad(date.getMonth() + 1);
174
- const d = pad(date.getDate());
175
- return `${y}-${m}-${d}`;
176
- }
177
- case 'system_date_time':
178
- {
179
- const y = date.getFullYear();
180
- const m = pad(date.getMonth() + 1);
181
- const d = pad(date.getDate());
182
- const h = pad(date.getHours());
183
- const min = pad(date.getMinutes());
184
- const s = pad(date.getSeconds());
185
- return `${y}-${m}-${d} ${h}:${min}:${s}`;
186
- }
187
- case 'system_time':
188
- {
189
- const h = pad(date.getHours());
190
- const min = pad(date.getMinutes());
191
- const s = pad(date.getSeconds());
192
- return `${h}:${min}:${s}`;
193
- }
194
- }
195
- }
196
- function getFullAbsoluteString(date) {
197
- return new Intl.DateTimeFormat(undefined, {
198
- year: 'numeric',
199
- month: 'long',
200
- day: 'numeric',
201
- hour: 'numeric',
202
- minute: '2-digit',
203
- second: '2-digit',
204
- timeZoneName: 'short'
205
- }).format(date);
206
- }
207
141
 
208
142
  /** Returns the interval (in ms) at which a relative timestamp should update. */
209
143
  function getLiveInterval(diffSeconds) {
@@ -250,6 +184,7 @@ export function Timestamp({
250
184
  format = 'auto',
251
185
  autoThreshold = DEFAULT_AUTO_THRESHOLD,
252
186
  hasTooltip = true,
187
+ tooltipEntries,
253
188
  isTimezoneShown = false,
254
189
  isLive = false,
255
190
  type = 'supporting',
@@ -276,11 +211,14 @@ export function Timestamp({
276
211
  const diffSeconds = Math.round((now.getTime() - date.getTime()) / 1000);
277
212
  const effectiveFormat = format === 'auto' ? Math.abs(diffSeconds) <= autoThreshold ? 'relative' : 'date_time' : format;
278
213
 
279
- // Format the display text
280
- const displayText = !isValidDate ? '' : effectiveFormat === 'relative' ? getRelativeTimeString(date, now) : isAbsoluteFormat(effectiveFormat) ? formatTimestamp(date, effectiveFormat, isTimezoneShown) : '';
214
+ // Format the display text. No time zone is passed: the visible text always
215
+ // reads in the viewer's own zone, and only the tooltip names others.
216
+ const displayText = !isValidDate ? '' : effectiveFormat === 'relative' ? getRelativeTimeString(date, now) : isAbsoluteFormat(effectiveFormat) ? formatInstant(date, effectiveFormat, {
217
+ isTimezoneShown
218
+ }) : '';
281
219
 
282
220
  // Full absolute text for tooltip and aria-label
283
- const fullAbsoluteText = isValidDate ? getFullAbsoluteString(date) : '';
221
+ const fullAbsoluteText = isValidDate ? formatInstant(date, 'full') : '';
284
222
 
285
223
  // Live updates
286
224
  useEffect(() => {
@@ -299,7 +237,16 @@ export function Timestamp({
299
237
  if (!isValidDate) {
300
238
  return null;
301
239
  }
302
- const showTooltip = hasTooltip && effectiveFormat === 'relative';
240
+
241
+ // An empty array is not a second way to spell "off" — `hasTooltip` stays the
242
+ // only on/off axis — so normalize it away before anything reads it.
243
+ const entries = tooltipEntries !== undefined && tooltipEntries.length > 0 ? tooltipEntries : undefined;
244
+
245
+ // Absolute formats have never carried a tooltip. Leaving that gate closed
246
+ // when a consumer has explicitly configured tooltip lines would let `format`
247
+ // silently suppress another prop's output, so entry presence opens it too.
248
+ // With no entries this reduces to the original condition exactly.
249
+ const showTooltip = hasTooltip && (effectiveFormat === 'relative' || entries !== undefined);
303
250
  const timestampProps = mergeProps(themeProps('timestamp', {
304
251
  format: effectiveFormat
305
252
  }), {
@@ -338,12 +285,36 @@ export function Timestamp({
338
285
  })
339
286
  });
340
287
  if (showTooltip) {
288
+ // Built inside the branch so a timestamp without a tooltip allocates none
289
+ // of it. With no entries the content stays the bare string it has always
290
+ // been — no wrapper element is introduced around the default line.
291
+ const tooltipContent = entries === undefined ? fullAbsoluteText : /*#__PURE__*/_jsx("dl", {
292
+ ...{
293
+ className: "xrvj5dj x1pmbctz x1tw44j4 x10im51j xrxpjvj"
294
+ },
295
+ children: formatTooltipLines(date, entries).map((line, index) =>
296
+ /*#__PURE__*/
297
+ // eslint-disable-next-line @eslint-react/no-array-index-key -- tooltip lines are fixed positional slots and two entries may legitimately be identical
298
+ _jsxs(Fragment, {
299
+ children: [/*#__PURE__*/_jsx("dt", {
300
+ ...{
301
+ className: "x10im51j xrxpjvj xyri2b xepvkrk"
302
+ },
303
+ children: line.label ?? ''
304
+ }), /*#__PURE__*/_jsx("dd", {
305
+ ...{
306
+ className: "x10im51j xrxpjvj"
307
+ },
308
+ children: line.value
309
+ })]
310
+ }, index))
311
+ });
341
312
  return /*#__PURE__*/_jsxs(_Fragment, {
342
313
  children: [timeElement, /*#__PURE__*/_jsx(Suspense, {
343
314
  fallback: null,
344
315
  children: /*#__PURE__*/_jsx(LazyXDSTooltip, {
345
316
  anchorRef: timeRef,
346
- content: fullAbsoluteText,
317
+ content: tooltipContent,
347
318
  placement: "above"
348
319
  })
349
320
  })]
@@ -0,0 +1,41 @@
1
+ import type { TimestampFormat } from './Timestamp';
2
+ /**
3
+ * Every format that names a fixed instant, plus `'full'` — the long absolute
4
+ * style ("February 19, 2026 at 5:00:00 PM UTC") that backs a relative
5
+ * timestamp's accessible name and the tooltip's default line.
6
+ *
7
+ * `'relative'` and `'auto'` are excluded: a relative phrase names no instant,
8
+ * so a zone could not change what it says.
9
+ */
10
+ export type InstantFormat = Exclude<TimestampFormat, 'relative' | 'auto'> | 'full';
11
+ export interface FormatInstantOptions {
12
+ /**
13
+ * IANA time zone identifier. Omit for the viewer's own zone — which is what
14
+ * `Intl` already does with no `timeZone`, so the omitted path never
15
+ * constructs an explicit-zone formatter and cannot drift from the host
16
+ * default.
17
+ *
18
+ * Must already be one the platform accepts. An identifier `Intl` does not
19
+ * recognize throws a `RangeError` from its constructor, before any
20
+ * formatting happens; deciding what to do about that belongs to whoever
21
+ * took the identifier from a consumer, not here (tooltipEntries resolves
22
+ * and warns in `resolveTimezoneID`, then passes only what survived).
23
+ */
24
+ timeZone?: string;
25
+ /**
26
+ * Whether to append the zone abbreviation. Honoured by `date_time` and
27
+ * `time` only: `'full'` always carries one because that is the style, and
28
+ * the `system_*` shapes never do — a trailing "PST" would break anything
29
+ * parsing them, which is why `isTimezoneShown` has never applied to them.
30
+ * @default false
31
+ */
32
+ isTimezoneShown?: boolean;
33
+ }
34
+ /**
35
+ * Renders one instant in one absolute format.
36
+ *
37
+ * Pure: the same arguments always produce the same string for a given host
38
+ * locale (and, when no `timeZone` is given, host zone).
39
+ */
40
+ export declare function formatInstant(date: Date, format: InstantFormat, { timeZone, isTimezoneShown }?: FormatInstantOptions): string;
41
+ //# sourceMappingURL=formatInstant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatInstant.d.ts","sourceRoot":"","sources":["../../src/Timestamp/formatInstant.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,aAAa,CAAC;AAMjD;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GACrB,OAAO,CAAC,eAAe,EAAE,UAAU,GAAG,MAAM,CAAC,GAC7C,MAAM,CAAC;AAEX,MAAM,WAAW,oBAAoB;IACnC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AA6ED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,aAAa,EACrB,EAAC,QAAQ,EAAE,eAAuB,EAAC,GAAE,oBAAyB,GAC7D,MAAM,CA0DR"}
@@ -0,0 +1,177 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file formatInstant.ts
5
+ * @input A Date, one absolute format name, and an optional time zone
6
+ * @output That instant rendered as a string
7
+ * @position Leaf shared by Timestamp's visible text and each of its tooltip
8
+ * lines; owns every absolute format Timestamp can produce
9
+ *
10
+ * Timestamp renders the same instant on two surfaces — the visible text and,
11
+ * on hover, one line per configured time zone. They differ only in which zone
12
+ * they name and whether they carry a zone abbreviation, so they are one
13
+ * formatter parameterized by zone rather than two switches that have to be
14
+ * kept in step by hand. Adding a member to `TimestampFormat` now fails to
15
+ * compile in exactly one place.
16
+ *
17
+ * Each caller keeps its own policy for the zone abbreviation: the visible text
18
+ * takes it straight from the `isTimezoneShown` prop, a tooltip line derives it
19
+ * from how many zones are on screen (see tooltipEntries.ts). Only the
20
+ * rendering is shared, not the decision.
21
+ *
22
+ * Omitting `timeZone` means the viewer's own zone. That path hands `Intl` no
23
+ * `timeZone` and keeps `system_*` on plain `Date` getters, so it produces
24
+ * exactly what it produced before this module existed.
25
+ *
26
+ * SYNC: When modified, update these files to stay in sync:
27
+ * - /packages/core/src/Timestamp/Timestamp.tsx
28
+ * - /packages/core/src/Timestamp/tooltipEntries.ts
29
+ * - /packages/core/src/Timestamp/Timestamp.test.tsx
30
+ */
31
+
32
+ import { SHARED_DATE_FORMAT_OPTIONS, getTimeZoneParts } from "../utils/plainDate.js";
33
+
34
+ // =============================================================================
35
+ // Types
36
+ // =============================================================================
37
+
38
+ /**
39
+ * Every format that names a fixed instant, plus `'full'` — the long absolute
40
+ * style ("February 19, 2026 at 5:00:00 PM UTC") that backs a relative
41
+ * timestamp's accessible name and the tooltip's default line.
42
+ *
43
+ * `'relative'` and `'auto'` are excluded: a relative phrase names no instant,
44
+ * so a zone could not change what it says.
45
+ */
46
+
47
+ // =============================================================================
48
+ // Option bags
49
+ // =============================================================================
50
+
51
+ /** The long absolute style, with seconds and a zone name. */
52
+ const FULL_OPTIONS = {
53
+ year: 'numeric',
54
+ month: 'long',
55
+ day: 'numeric',
56
+ hour: 'numeric',
57
+ minute: '2-digit',
58
+ second: '2-digit',
59
+ timeZoneName: 'short'
60
+ };
61
+
62
+ /** The time-of-day part, shared by `time` and `date_time`. */
63
+ const TIME_OPTIONS = {
64
+ hour: 'numeric',
65
+ minute: '2-digit'
66
+ };
67
+
68
+ /**
69
+ * The date part here is spelled out rather than taken from
70
+ * `SHARED_DATE_FORMAT_OPTIONS.date`. That bag is shared with DateInput, and
71
+ * pointing `date_time` at it would mean a change made for date-only fields
72
+ * silently reshaped every date-and-time reading too. The two agree today; they
73
+ * are not the same decision.
74
+ */
75
+ const DATE_TIME_OPTIONS = {
76
+ year: 'numeric',
77
+ month: 'short',
78
+ day: 'numeric',
79
+ ...TIME_OPTIONS
80
+ };
81
+
82
+ // =============================================================================
83
+ // Formatting
84
+ // =============================================================================
85
+
86
+ function pad(n) {
87
+ return String(n).padStart(2, '0');
88
+ }
89
+
90
+ /** The fields a `system_*` string is assembled from. */
91
+
92
+ /**
93
+ * Wall-clock fields for an instant: in the named zone, or — with no zone —
94
+ * the viewer's own, read straight off the `Date`. The zone-less branch
95
+ * deliberately stays on plain getters so the default rendering never gains a
96
+ * dependency on `Intl` zone data it did not have before.
97
+ *
98
+ * The explicit return type is load-bearing: it is what forces the two branches
99
+ * to keep producing the same shape.
100
+ */
101
+ function getWallClock(date, timeZone) {
102
+ return timeZone === undefined ? {
103
+ year: date.getFullYear(),
104
+ month: date.getMonth() + 1,
105
+ day: date.getDate(),
106
+ hour: date.getHours(),
107
+ minute: date.getMinutes(),
108
+ second: date.getSeconds()
109
+ } : getTimeZoneParts(date.getTime(), timeZone);
110
+ }
111
+
112
+ /**
113
+ * Renders one instant in one absolute format.
114
+ *
115
+ * Pure: the same arguments always produce the same string for a given host
116
+ * locale (and, when no `timeZone` is given, host zone).
117
+ */
118
+ export function formatInstant(date, format, {
119
+ timeZone,
120
+ isTimezoneShown = false
121
+ } = {}) {
122
+ const zone = timeZone === undefined ? {} : {
123
+ timeZone
124
+ };
125
+ const zoneName = isTimezoneShown ? {
126
+ timeZoneName: 'short'
127
+ } : {};
128
+ switch (format) {
129
+ case 'full':
130
+ return new Intl.DateTimeFormat(undefined, {
131
+ ...FULL_OPTIONS,
132
+ ...zone
133
+ }).format(date);
134
+ case 'date':
135
+ return new Intl.DateTimeFormat(undefined, {
136
+ ...SHARED_DATE_FORMAT_OPTIONS.date,
137
+ ...zone
138
+ }).format(date);
139
+ case 'date_long':
140
+ return new Intl.DateTimeFormat(undefined, {
141
+ ...SHARED_DATE_FORMAT_OPTIONS.date_long,
142
+ ...zone
143
+ }).format(date);
144
+ case 'date_weekday':
145
+ return new Intl.DateTimeFormat(undefined, {
146
+ ...SHARED_DATE_FORMAT_OPTIONS.date_weekday,
147
+ ...zone
148
+ }).format(date);
149
+ case 'date_time':
150
+ return new Intl.DateTimeFormat(undefined, {
151
+ ...DATE_TIME_OPTIONS,
152
+ ...zoneName,
153
+ ...zone
154
+ }).format(date);
155
+ case 'time':
156
+ return new Intl.DateTimeFormat(undefined, {
157
+ ...TIME_OPTIONS,
158
+ ...zoneName,
159
+ ...zone
160
+ }).format(date);
161
+ case 'system_date':
162
+ {
163
+ const w = getWallClock(date, timeZone);
164
+ return `${w.year}-${pad(w.month)}-${pad(w.day)}`;
165
+ }
166
+ case 'system_date_time':
167
+ {
168
+ const w = getWallClock(date, timeZone);
169
+ return `${w.year}-${pad(w.month)}-${pad(w.day)} ${pad(w.hour)}:${pad(w.minute)}:${pad(w.second)}`;
170
+ }
171
+ case 'system_time':
172
+ {
173
+ const w = getWallClock(date, timeZone);
174
+ return `${pad(w.hour)}:${pad(w.minute)}:${pad(w.second)}`;
175
+ }
176
+ }
177
+ }
@@ -8,4 +8,5 @@
8
8
  */
9
9
  export { Timestamp } from './Timestamp';
10
10
  export type { TimestampProps, TimestampFormat } from './Timestamp';
11
+ export type { TimestampTooltipEntry, TimestampTooltipFormat, } from './tooltipEntries';
11
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Timestamp/index.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AACtC,YAAY,EAAC,cAAc,EAAE,eAAe,EAAC,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Timestamp/index.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AACtC,YAAY,EAAC,cAAc,EAAE,eAAe,EAAC,MAAM,aAAa,CAAC;AACjE,YAAY,EACV,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,56 @@
1
+ import type { InstantFormat } from './formatInstant';
2
+ /**
3
+ * Formats available to a tooltip line.
4
+ *
5
+ * Every `TimestampFormat` that names a fixed instant, plus `'full'` — the long
6
+ * absolute style the tooltip has always shown ("February 19, 2026 at 5:00:00 PM
7
+ * UTC"). `'relative'` and `'auto'` are excluded: a relative phrase ignores any
8
+ * zone, which would make `timezoneID` silently inert on that line.
9
+ *
10
+ * `'full'` lives only in this vocabulary, never in `TimestampFormat` — nothing
11
+ * asked for it as a visible display format, and keeping it out means new
12
+ * members added to `TimestampFormat` become valid tooltip formats for free.
13
+ *
14
+ * The public spelling of {@link InstantFormat}: consumers reading Timestamp's
15
+ * props should not have to know the name of its internal formatter.
16
+ */
17
+ export type TimestampTooltipFormat = InstantFormat;
18
+ /** One line of the Timestamp tooltip. */
19
+ export interface TimestampTooltipEntry {
20
+ /**
21
+ * IANA time zone identifier, e.g. `'UTC'`, `'America/Los_Angeles'`.
22
+ * Omit it — or pass `'local'` — for the viewer's own zone.
23
+ *
24
+ * Prefer region identifiers. Fixed-offset abbreviations such as `'EST'` are
25
+ * accepted by the platform but never observe daylight saving, so they read
26
+ * an hour wrong for half the year — `'America/New_York'` is what people
27
+ * usually mean by "Eastern".
28
+ *
29
+ * An identifier the platform does not recognize falls back to the viewer's
30
+ * zone with a console warning rather than throwing.
31
+ */
32
+ timezoneID?: string;
33
+ /**
34
+ * How this line renders the instant.
35
+ * @default 'full'
36
+ */
37
+ format?: TimestampTooltipFormat;
38
+ /**
39
+ * Text shown beside the time, e.g. `'Local'`, `'UTC'`, `'Pacific'`.
40
+ * Supplied already translated; Timestamp never invents or localizes labels.
41
+ */
42
+ label?: string;
43
+ }
44
+ /** A rendered tooltip line. */
45
+ export interface TimestampTooltipLine {
46
+ label?: string;
47
+ value: string;
48
+ }
49
+ /**
50
+ * Renders one tooltip line per entry, in the order given.
51
+ *
52
+ * Pure: the same `date` and `entries` always produce the same lines for a given
53
+ * host zone and locale.
54
+ */
55
+ export declare function formatTooltipLines(date: Date, entries: ReadonlyArray<TimestampTooltipEntry>): ReadonlyArray<TimestampTooltipLine>;
56
+ //# sourceMappingURL=tooltipEntries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tooltipEntries.d.ts","sourceRoot":"","sources":["../../src/Timestamp/tooltipEntries.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAMnD;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,sBAAsB,GAAG,aAAa,CAAC;AAEnD,yCAAyC;AACzC,MAAM,WAAW,qBAAqB;IACpC;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,MAAM,CAAC,EAAE,sBAAsB,CAAC;IAChC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,+BAA+B;AAC/B,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAqGD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,aAAa,CAAC,qBAAqB,CAAC,GAC5C,aAAa,CAAC,oBAAoB,CAAC,CAoBrC"}
@@ -0,0 +1,163 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file tooltipEntries.ts
5
+ * @input A Date and the consumer's tooltip entry list
6
+ * @output Pure formatting of one tooltip line per entry, plus the entry types
7
+ * @position Leaf module; owns which zone each tooltip line names and whether
8
+ * it needs a zone abbreviation, then defers to formatInstant to render it
9
+ *
10
+ * This module holds only the decisions a tooltip makes that the visible text
11
+ * does not: resolving `timezoneID` (including the `'local'` alias and the
12
+ * fallback for an unknown identifier), and deciding which lines need a zone
13
+ * abbreviation to be told apart. The formatting itself is formatInstant's,
14
+ * shared with the rendered text, so the two surfaces cannot drift.
15
+ *
16
+ * SYNC: When modified, update these files to stay in sync:
17
+ * - /packages/core/src/Timestamp/Timestamp.tsx
18
+ * - /packages/core/src/Timestamp/formatInstant.ts
19
+ * - /packages/core/src/Timestamp/tooltipEntries.test.ts
20
+ * - /packages/core/src/Timestamp/Timestamp.doc.mjs
21
+ * - /packages/core/src/Timestamp/index.ts
22
+ */
23
+
24
+ import { devWarn } from "../utils/devWarning.js";
25
+ import { formatInstant } from "./formatInstant.js";
26
+
27
+ // =============================================================================
28
+ // Types
29
+ // =============================================================================
30
+
31
+ /**
32
+ * Formats available to a tooltip line.
33
+ *
34
+ * Every `TimestampFormat` that names a fixed instant, plus `'full'` — the long
35
+ * absolute style the tooltip has always shown ("February 19, 2026 at 5:00:00 PM
36
+ * UTC"). `'relative'` and `'auto'` are excluded: a relative phrase ignores any
37
+ * zone, which would make `timezoneID` silently inert on that line.
38
+ *
39
+ * `'full'` lives only in this vocabulary, never in `TimestampFormat` — nothing
40
+ * asked for it as a visible display format, and keeping it out means new
41
+ * members added to `TimestampFormat` become valid tooltip formats for free.
42
+ *
43
+ * The public spelling of {@link InstantFormat}: consumers reading Timestamp's
44
+ * props should not have to know the name of its internal formatter.
45
+ */
46
+
47
+ /** One line of the Timestamp tooltip. */
48
+
49
+ /** A rendered tooltip line. */
50
+
51
+ // =============================================================================
52
+ // Zone resolution
53
+ // =============================================================================
54
+
55
+ /** Spelling that means "the viewer's own zone" without naming it. */
56
+ const LOCAL_ZONE_ALIAS = 'local';
57
+
58
+ /**
59
+ * Zone identifiers already reported as unknown.
60
+ *
61
+ * Resolution runs once per entry on every render, so without this a single
62
+ * typo on a live timestamp would emit the same warning every tick, forever.
63
+ * One report per bad identifier is enough to act on.
64
+ */
65
+ const warnedTimezoneIDs = new Set();
66
+
67
+ /**
68
+ * Resolves an entry's zone to something safe to hand to `Intl`.
69
+ *
70
+ * Returns `undefined` for the viewer's own zone, which is also what `Intl`
71
+ * treats as "use the host zone" — so the local path never constructs a
72
+ * formatter with an explicit `timeZone` and cannot drift from today's output.
73
+ */
74
+ function resolveTimezoneID(timezoneID) {
75
+ if (timezoneID === undefined || timezoneID.toLowerCase() === LOCAL_ZONE_ALIAS) {
76
+ return undefined;
77
+ }
78
+
79
+ // An unrecognized identifier makes every Intl.DateTimeFormat constructor
80
+ // throw a RangeError. Rendering a timestamp must never take down the tree —
81
+ // degrade to the viewer's zone and say so, mirroring how an unparseable
82
+ // `value` is handled in Timestamp.tsx.
83
+ try {
84
+ new Intl.DateTimeFormat(undefined, {
85
+ timeZone: timezoneID
86
+ });
87
+ } catch {
88
+ if (!warnedTimezoneIDs.has(timezoneID)) {
89
+ warnedTimezoneIDs.add(timezoneID);
90
+ devWarn('Timestamp', `unknown time zone ${JSON.stringify(timezoneID)} in tooltipEntries. Falling back to the viewer's time zone.`);
91
+ }
92
+ return undefined;
93
+ }
94
+ return timezoneID;
95
+ }
96
+
97
+ /**
98
+ * A stable key for "which zone did the consumer ask for", used to decide
99
+ * whether the tooltip needs zone abbreviations to disambiguate its lines.
100
+ *
101
+ * Deliberately keyed on the *requested* zone, not on the resolved offset: a
102
+ * consumer who asks for two zones gets both labelled even when the viewer
103
+ * happens to be sitting in one of them, so the rendering does not change shape
104
+ * depending on where the reader is. That also keeps this testable under any
105
+ * machine timezone.
106
+ */
107
+ function zoneKey(resolved) {
108
+ return resolved === undefined ? LOCAL_ZONE_ALIAS : resolved.toLowerCase();
109
+ }
110
+
111
+ // =============================================================================
112
+ // Zone marking
113
+ // =============================================================================
114
+
115
+ /**
116
+ * Whether a format should carry a zone abbreviation.
117
+ *
118
+ * `'full'` always has one (that is the style). `system_*` never does — those
119
+ * are machine shapes and a trailing "PST" would break anything parsing them,
120
+ * which is also why `isTimezoneShown` has never applied to them.
121
+ *
122
+ * The two human formats that can carry one do so when either the reader has
123
+ * to tell several lines apart, or the line shows a zone the consumer named
124
+ * explicitly. That second case matters even for a lone entry: the tooltip is
125
+ * the `<time>` element's `aria-describedby`, and that element's accessible
126
+ * name is the absolute time in the *viewer's* zone — so an unmarked foreign
127
+ * time is announced directly after a local one with nothing to distinguish
128
+ * them. A line the consumer did not steer stays unmarked, matching how the
129
+ * visible text reads with `isTimezoneShown` off.
130
+ */
131
+ function shouldShowZoneName(format, hasMultipleZones, isNamedZone) {
132
+ if (format === 'full') {
133
+ return true;
134
+ }
135
+ if (format === 'date_time' || format === 'time') {
136
+ return hasMultipleZones || isNamedZone;
137
+ }
138
+ return false;
139
+ }
140
+
141
+ /**
142
+ * Renders one tooltip line per entry, in the order given.
143
+ *
144
+ * Pure: the same `date` and `entries` always produce the same lines for a given
145
+ * host zone and locale.
146
+ */
147
+ export function formatTooltipLines(date, entries) {
148
+ const resolved = entries.map(entry => resolveTimezoneID(entry.timezoneID));
149
+ const hasMultipleZones = new Set(resolved.map(zoneKey)).size > 1;
150
+ return entries.map((entry, index) => {
151
+ const format = entry.format ?? 'full';
152
+ const timeZone = resolved[index];
153
+ return {
154
+ ...(entry.label === undefined ? {} : {
155
+ label: entry.label
156
+ }),
157
+ value: formatInstant(date, format, {
158
+ timeZone,
159
+ isTimezoneShown: shouldShowZoneName(format, hasMultipleZones, timeZone !== undefined)
160
+ })
161
+ };
162
+ });
163
+ }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @file Token.tsx
3
3
  * @input Uses React, ReactNode, StyleXStyles
4
- * @output Exports Token component, TokenProps, TokenColor types
4
+ * @output Exports Token component, TokenProps, TokenColor, TokenColorMap types
5
5
  * @position Core implementation; consumed by index.ts, tested by Token.test.tsx
6
6
  *
7
7
  * SYNC: When modified, update these files to stay in sync:
@@ -14,9 +14,36 @@
14
14
  import type { ReactNode } from 'react';
15
15
  import type { BaseProps } from '../BaseProps';
16
16
  /**
17
- * Available color variants for the token.
17
+ * Extensible color map for Token.
18
+ *
19
+ * Theme packages can add custom colors via TypeScript module augmentation:
20
+ * @example
21
+ * ```
22
+ * declare module '@astryxdesign/core/Token' {
23
+ * interface TokenColorMap {
24
+ * brand: true;
25
+ * }
26
+ * }
27
+ * ```
28
+ */
29
+ export interface TokenColorMap {
30
+ default: true;
31
+ red: true;
32
+ orange: true;
33
+ yellow: true;
34
+ green: true;
35
+ teal: true;
36
+ cyan: true;
37
+ blue: true;
38
+ purple: true;
39
+ pink: true;
40
+ gray: true;
41
+ }
42
+ /**
43
+ * Token color type derived from TokenColorMap.
44
+ * Extensible via module augmentation of TokenColorMap.
18
45
  */
19
- export type TokenColor = 'default' | 'red' | 'orange' | 'yellow' | 'green' | 'teal' | 'cyan' | 'blue' | 'purple' | 'pink' | 'gray';
46
+ export type TokenColor = keyof TokenColorMap;
20
47
  export type TokenSize = 'sm' | 'md' | 'lg';
21
48
  export interface TokenProps extends BaseProps<HTMLElement> {
22
49
  /** Ref forwarded to the root element */