@astryxdesign/core 0.7.8 → 0.7.9-canary.07992bb

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 (403) hide show
  1. package/dist/AppShell/observeMainOverflow.d.ts.map +1 -1
  2. package/dist/AppShell/observeMainOverflow.js +9 -6
  3. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  4. package/dist/BottomSheet/BottomSheet.js +5 -0
  5. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  6. package/dist/BottomSheet/BottomSheetPanel.js +40 -8
  7. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
  8. package/dist/BottomSheet/useSheetGestures.js +61 -21
  9. package/dist/Calendar/Calendar.d.ts +14 -2
  10. package/dist/Calendar/Calendar.d.ts.map +1 -1
  11. package/dist/Calendar/Calendar.js +63 -74
  12. package/dist/Calendar/getInitialFocusDate.d.ts +4 -1
  13. package/dist/Calendar/getInitialFocusDate.d.ts.map +1 -1
  14. package/dist/Calendar/getInitialFocusDate.js +7 -5
  15. package/dist/Calendar/hooks/useCalendarDays.d.ts +19 -2
  16. package/dist/Calendar/hooks/useCalendarDays.d.ts.map +1 -1
  17. package/dist/Calendar/hooks/useCalendarDays.js +57 -64
  18. package/dist/Calendar/hooks/useCalendarNavigation.d.ts +28 -3
  19. package/dist/Calendar/hooks/useCalendarNavigation.d.ts.map +1 -1
  20. package/dist/Calendar/hooks/useCalendarNavigation.js +33 -22
  21. package/dist/Calendar/styles.d.ts +1 -1
  22. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  23. package/dist/CheckboxInput/CheckboxInput.js +54 -11
  24. package/dist/ClickableCard/ClickableCard.d.ts +1 -1
  25. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  26. package/dist/ClickableCard/ClickableCard.js +5 -1
  27. package/dist/DateInput/DateInput.d.ts.map +1 -1
  28. package/dist/DateInput/DateInput.js +4 -1
  29. package/dist/DateInput/PickerWheel.d.ts.map +1 -1
  30. package/dist/DateInput/PickerWheel.js +7 -1
  31. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  32. package/dist/DateRangeInput/DateRangeInput.js +5 -2
  33. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  34. package/dist/DateTimeInput/DateTimeInput.js +4 -1
  35. package/dist/Dialog/Dialog.d.ts +2 -1
  36. package/dist/Dialog/Dialog.d.ts.map +1 -1
  37. package/dist/Dialog/Dialog.js +12 -1
  38. package/dist/Drawer/useDrawerDialogPresence.d.ts +2 -1
  39. package/dist/Drawer/useDrawerDialogPresence.d.ts.map +1 -1
  40. package/dist/Drawer/useDrawerDialogPresence.js +11 -2
  41. package/dist/DropdownMenu/DropdownMenu.d.ts +9 -1
  42. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  43. package/dist/DropdownMenu/DropdownMenu.js +9 -4
  44. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  45. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +3 -2
  46. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  47. package/dist/DropdownMenu/DropdownMenuItem.js +3 -2
  48. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  49. package/dist/DropdownMenu/DropdownMenuRadioItem.js +3 -2
  50. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  51. package/dist/DropdownMenu/DropdownMenuSubMenu.js +3 -2
  52. package/dist/Field/inputDisabledFocus.d.ts +4 -4
  53. package/dist/Field/inputStyles.stylex.d.ts +1 -1
  54. package/dist/FileInput/FileInput.d.ts.map +1 -1
  55. package/dist/FileInput/FileInput.js +16 -2
  56. package/dist/HoverCard/useHoverCard.d.ts +3 -1
  57. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  58. package/dist/Icon/Icon.d.ts +1 -1
  59. package/dist/InfoTip/InfoTip.d.ts +1 -0
  60. package/dist/InfoTip/InfoTip.d.ts.map +1 -1
  61. package/dist/InfoTip/InfoTip.js +1 -0
  62. package/dist/InputGroup/InputGroup.d.ts +4 -3
  63. package/dist/InputGroup/InputGroup.d.ts.map +1 -1
  64. package/dist/InputGroup/InputGroup.js +2 -2
  65. package/dist/InputGroup/groupStyles.d.ts +1 -1
  66. package/dist/InputGroup/groupStyles.d.ts.map +1 -1
  67. package/dist/InputGroup/groupStyles.js +1 -1
  68. package/dist/Item/Item.d.ts +2 -1
  69. package/dist/Item/Item.d.ts.map +1 -1
  70. package/dist/Item/Item.js +29 -6
  71. package/dist/Layer/holdEntranceInput.d.ts +24 -0
  72. package/dist/Layer/holdEntranceInput.d.ts.map +1 -0
  73. package/dist/Layer/holdEntranceInput.js +65 -0
  74. package/dist/Layer/inputHold.d.ts +49 -0
  75. package/dist/Layer/inputHold.d.ts.map +1 -0
  76. package/dist/Layer/inputHold.js +636 -0
  77. package/dist/Layer/preserveAnimations.d.ts +1 -5
  78. package/dist/Layer/preserveAnimations.d.ts.map +1 -1
  79. package/dist/Layer/preserveAnimations.js +12 -214
  80. package/dist/Layer/useLayer.d.ts +3 -1
  81. package/dist/Layer/useLayer.d.ts.map +1 -1
  82. package/dist/Layer/useLayer.js +64 -4
  83. package/dist/Layout/LayoutContent.d.ts +3 -1
  84. package/dist/Layout/LayoutContent.d.ts.map +1 -1
  85. package/dist/Layout/LayoutContent.js +12 -4
  86. package/dist/Layout/LayoutPanel.d.ts +4 -1
  87. package/dist/Layout/LayoutPanel.d.ts.map +1 -1
  88. package/dist/Layout/LayoutPanel.js +13 -4
  89. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  90. package/dist/Lightbox/Lightbox.js +4 -0
  91. package/dist/MetadataList/MetadataList.js +1 -1
  92. package/dist/MobileNav/MobileNav.d.ts +11 -1
  93. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  94. package/dist/MobileNav/MobileNav.js +39 -1
  95. package/dist/MoreMenu/MoreMenu.d.ts +5 -3
  96. package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
  97. package/dist/NumberInput/NumberInput.d.ts +4 -2
  98. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  99. package/dist/NumberInput/NumberInput.js +244 -11
  100. package/dist/Popover/usePopover.d.ts +1 -0
  101. package/dist/Popover/usePopover.d.ts.map +1 -1
  102. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  103. package/dist/PowerSearch/PowerSearch.js +12 -5
  104. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts.map +1 -1
  105. package/dist/PowerSearch/PowerSearchBottomSheet.js +4 -2
  106. package/dist/PowerSearch/PowerSearchToken.d.ts.map +1 -1
  107. package/dist/PowerSearch/PowerSearchToken.js +3 -1
  108. package/dist/PowerSearch/formatFilterValue.d.ts +9 -3
  109. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  110. package/dist/PowerSearch/formatFilterValue.js +14 -11
  111. package/dist/PowerSearch/formatTokenValue.d.ts +6 -2
  112. package/dist/PowerSearch/formatTokenValue.d.ts.map +1 -1
  113. package/dist/PowerSearch/formatTokenValue.js +6 -3
  114. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  115. package/dist/RadioList/RadioListItem.js +22 -4
  116. package/dist/SelectableCard/SelectableCard.d.ts +1 -1
  117. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  118. package/dist/SelectableCard/SelectableCard.js +5 -1
  119. package/dist/Spinner/Spinner.d.ts.map +1 -1
  120. package/dist/Spinner/Spinner.js +14 -71
  121. package/dist/Spinner/index.d.ts +1 -1
  122. package/dist/Spinner/index.d.ts.map +1 -1
  123. package/dist/Spinner/spinnerRotor.d.ts +28 -0
  124. package/dist/Spinner/spinnerRotor.d.ts.map +1 -0
  125. package/dist/Spinner/spinnerRotor.js +98 -0
  126. package/dist/Stack/StackItem.d.ts +8 -4
  127. package/dist/Stack/StackItem.d.ts.map +1 -1
  128. package/dist/Stack/StackItem.js +17 -4
  129. package/dist/Switch/Switch.d.ts.map +1 -1
  130. package/dist/Switch/Switch.js +13 -10
  131. package/dist/Table/plugins/sortable/useTableSortable.js +1 -1
  132. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  133. package/dist/Timestamp/Timestamp.js +14 -8
  134. package/dist/Timestamp/formatInstant.d.ts +10 -1
  135. package/dist/Timestamp/formatInstant.d.ts.map +1 -1
  136. package/dist/Timestamp/formatInstant.js +13 -27
  137. package/dist/Timestamp/tooltipEntries.d.ts +5 -3
  138. package/dist/Timestamp/tooltipEntries.d.ts.map +1 -1
  139. package/dist/Timestamp/tooltipEntries.js +6 -4
  140. package/dist/Token/Token.d.ts.map +1 -1
  141. package/dist/Token/Token.js +9 -0
  142. package/dist/Token/TokenLink.d.ts +1 -1
  143. package/dist/Token/TokenLink.d.ts.map +1 -1
  144. package/dist/Token/TokenLink.js +4 -1
  145. package/dist/Tokenizer/Tokenizer.d.ts +14 -10
  146. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  147. package/dist/Tokenizer/Tokenizer.js +189 -89
  148. package/dist/Tooltip/useTooltip.d.ts +3 -1
  149. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  150. package/dist/Tooltip/useTooltip.js +162 -59
  151. package/dist/TreeList/TreeListItem.d.ts +2 -1
  152. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  153. package/dist/TreeList/TreeListItem.js +27 -3
  154. package/dist/astryx.css +45 -18
  155. package/dist/gestures/GestureHost.d.ts +2 -2
  156. package/dist/gestures/GestureHost.d.ts.map +1 -1
  157. package/dist/gestures/GestureHost.js +21 -6
  158. package/dist/gestures/PanGestureRecognizer.d.ts +11 -1
  159. package/dist/gestures/PanGestureRecognizer.d.ts.map +1 -1
  160. package/dist/gestures/PanGestureRecognizer.js +15 -1
  161. package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts +6 -1
  162. package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts.map +1 -1
  163. package/dist/gestures/nativeScroll.d.ts +3 -6
  164. package/dist/gestures/nativeScroll.d.ts.map +1 -1
  165. package/dist/gestures/nativeScroll.js +7 -52
  166. package/dist/gestures/wheelSegmenter.d.ts +68 -1
  167. package/dist/gestures/wheelSegmenter.d.ts.map +1 -1
  168. package/dist/gestures/wheelSegmenter.js +199 -10
  169. package/dist/hooks/StackItemScrollRegion.d.ts +31 -0
  170. package/dist/hooks/StackItemScrollRegion.d.ts.map +1 -0
  171. package/dist/hooks/StackItemScrollRegion.js +40 -0
  172. package/dist/hooks/menuPressGesture.d.ts +133 -21
  173. package/dist/hooks/menuPressGesture.d.ts.map +1 -1
  174. package/dist/hooks/menuPressGesture.js +155 -30
  175. package/dist/hooks/menuPressValues.d.ts +16 -0
  176. package/dist/hooks/menuPressValues.d.ts.map +1 -0
  177. package/dist/hooks/menuPressValues.js +18 -0
  178. package/dist/hooks/useClickableContainer.d.ts +27 -5
  179. package/dist/hooks/useClickableContainer.d.ts.map +1 -1
  180. package/dist/hooks/useClickableContainer.js +41 -5
  181. package/dist/hooks/useFocusTrap.d.ts +10 -0
  182. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  183. package/dist/hooks/useFocusTrap.js +225 -132
  184. package/dist/hooks/useMenuPress.d.ts +34 -1
  185. package/dist/hooks/useMenuPress.d.ts.map +1 -1
  186. package/dist/hooks/useMenuPress.js +93 -5
  187. package/dist/hooks/usePressFeedback.d.ts +6 -6
  188. package/dist/hooks/usePressFeedback.js +6 -6
  189. package/dist/hooks/useScrollRegionProps.d.ts +35 -0
  190. package/dist/hooks/useScrollRegionProps.d.ts.map +1 -0
  191. package/dist/hooks/useScrollRegionProps.js +51 -0
  192. package/dist/i18n/InternationalizationContext.d.ts +6 -0
  193. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  194. package/dist/i18n/InternationalizationProvider.d.ts +21 -3
  195. package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
  196. package/dist/i18n/InternationalizationProvider.js +8 -3
  197. package/dist/i18n/generated-english/hooks/useScrollRegionProps.generated.d.ts +8 -0
  198. package/dist/i18n/generated-english/hooks/useScrollRegionProps.generated.d.ts.map +1 -0
  199. package/dist/i18n/generated-english/hooks/useScrollRegionProps.generated.js +12 -0
  200. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  201. package/dist/i18n/generated-locales/en.generated.js +1 -0
  202. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  203. package/dist/i18n/generated-locales/pseudo.generated.js +1 -0
  204. package/dist/i18n/index.d.ts +2 -0
  205. package/dist/i18n/index.d.ts.map +1 -1
  206. package/dist/i18n/index.js +1 -0
  207. package/dist/i18n/useCalendarSystem.d.ts +19 -0
  208. package/dist/i18n/useCalendarSystem.d.ts.map +1 -0
  209. package/dist/i18n/useCalendarSystem.js +61 -0
  210. package/dist/internal/spinner-rotor.d.ts +16 -0
  211. package/dist/internal/spinner-rotor.d.ts.map +1 -0
  212. package/dist/internal/spinner-rotor.js +16 -0
  213. package/dist/internal/touch.d.ts +14 -1
  214. package/dist/internal/touch.d.ts.map +1 -1
  215. package/dist/internal/touch.js +20 -2
  216. package/dist/motion/carryAnimations.d.ts +58 -0
  217. package/dist/motion/carryAnimations.d.ts.map +1 -0
  218. package/dist/motion/carryAnimations.js +305 -0
  219. package/dist/motion/transientCopy.d.ts +4 -2
  220. package/dist/motion/transientCopy.d.ts.map +1 -1
  221. package/dist/motion/transientCopy.js +34 -5
  222. package/dist/motion/uikit/gestures.d.ts +41 -0
  223. package/dist/motion/uikit/gestures.d.ts.map +1 -1
  224. package/dist/motion/uikit/gestures.js +25 -0
  225. package/dist/motion/uikit/index.d.ts +1 -1
  226. package/dist/motion/uikit/index.d.ts.map +1 -1
  227. package/dist/motion/uikit/index.js +1 -1
  228. package/dist/motion/uikit/timing.d.ts +14 -10
  229. package/dist/motion/uikit/timing.d.ts.map +1 -1
  230. package/dist/motion/uikit/timing.js +7 -5
  231. package/dist/privateAttributes/menuPressLit.stylex.d.ts +52 -0
  232. package/dist/privateAttributes/menuPressLit.stylex.d.ts.map +1 -0
  233. package/dist/privateAttributes/menuPressLit.stylex.js +99 -0
  234. package/dist/privateAttributes/press.stylex.d.ts +139 -0
  235. package/dist/privateAttributes/press.stylex.d.ts.map +1 -0
  236. package/dist/privateAttributes/press.stylex.js +97 -0
  237. package/dist/theme/themeMotion.d.ts +3 -2
  238. package/dist/theme/themeMotion.d.ts.map +1 -1
  239. package/dist/theme/themeMotion.js +3 -2
  240. package/dist/theme/tokens.stylex.d.ts +2 -2
  241. package/dist/theme/tokens.stylex.js +1 -1
  242. package/dist/utils/calendarSystem.d.ts +114 -0
  243. package/dist/utils/calendarSystem.d.ts.map +1 -0
  244. package/dist/utils/calendarSystem.js +386 -0
  245. package/dist/utils/flatTree.d.ts +6 -3
  246. package/dist/utils/flatTree.d.ts.map +1 -1
  247. package/dist/utils/flatTree.js +13 -3
  248. package/dist/utils/hitArea.d.ts.map +1 -1
  249. package/dist/utils/hitArea.js +82 -5
  250. package/dist/utils/inputStream.d.ts +14 -1
  251. package/dist/utils/inputStream.d.ts.map +1 -1
  252. package/dist/utils/inputStream.js +40 -9
  253. package/dist/utils/interactionOverlay.stylex.d.ts +5 -9
  254. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  255. package/dist/utils/interactionOverlay.stylex.js +29 -31
  256. package/dist/utils/plainDate.d.ts +23 -7
  257. package/dist/utils/plainDate.d.ts.map +1 -1
  258. package/dist/utils/plainDate.js +57 -18
  259. package/dist/utils/pressFeedback.d.ts +10 -2
  260. package/dist/utils/pressFeedback.d.ts.map +1 -1
  261. package/dist/utils/pressFeedback.js +40 -15
  262. package/dist/utils/pressGesture.d.ts +12 -6
  263. package/dist/utils/pressGesture.d.ts.map +1 -1
  264. package/dist/utils/pressGesture.js +26 -8
  265. package/dist/utils/scrollView.d.ts +25 -0
  266. package/dist/utils/scrollView.d.ts.map +1 -0
  267. package/dist/utils/scrollView.js +108 -0
  268. package/dist/utils/selectionLock.d.ts.map +1 -1
  269. package/dist/utils/selectionLock.js +1 -10
  270. package/dist/utils/touchHitArea.stylex.d.ts +35 -0
  271. package/dist/utils/touchHitArea.stylex.d.ts.map +1 -0
  272. package/dist/utils/touchHitArea.stylex.js +32 -0
  273. package/dist/utils/triggerFocus.d.ts +5 -0
  274. package/dist/utils/triggerFocus.d.ts.map +1 -1
  275. package/dist/utils/triggerFocus.js +9 -2
  276. package/locales/en.json +4 -0
  277. package/locales/pseudo.json +3 -0
  278. package/package.json +10 -4
  279. package/src/AppShell/observeMainOverflow.ts +9 -6
  280. package/src/BottomSheet/BottomSheet.tsx +5 -0
  281. package/src/BottomSheet/BottomSheetPanel.tsx +64 -7
  282. package/src/BottomSheet/useSheetGestures.ts +83 -20
  283. package/src/Calendar/Calendar.doc.mjs +76 -6
  284. package/src/Calendar/Calendar.tsx +123 -104
  285. package/src/Calendar/getInitialFocusDate.ts +22 -8
  286. package/src/Calendar/hooks/useCalendarDays.ts +89 -63
  287. package/src/Calendar/hooks/useCalendarNavigation.ts +68 -26
  288. package/src/CheckboxInput/CheckboxInput.doc.mjs +3 -2
  289. package/src/CheckboxInput/CheckboxInput.tsx +71 -9
  290. package/src/ClickableCard/ClickableCard.tsx +8 -1
  291. package/src/DateInput/DateInput.tsx +2 -0
  292. package/src/DateInput/PickerWheel.tsx +7 -2
  293. package/src/DateRangeInput/DateRangeInput.tsx +3 -1
  294. package/src/DateTimeInput/DateTimeInput.tsx +2 -0
  295. package/src/Dialog/Dialog.doc.mjs +1 -1
  296. package/src/Dialog/Dialog.tsx +12 -1
  297. package/src/Drawer/Drawer.doc.mjs +1 -1
  298. package/src/Drawer/useDrawerDialogPresence.ts +9 -2
  299. package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -2
  300. package/src/DropdownMenu/DropdownMenu.tsx +29 -5
  301. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +5 -1
  302. package/src/DropdownMenu/DropdownMenuItem.tsx +8 -4
  303. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +5 -1
  304. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +5 -1
  305. package/src/FileInput/FileInput.tsx +16 -2
  306. package/src/HoverCard/useHoverCard.tsx +3 -1
  307. package/src/InfoTip/InfoTip.doc.mjs +26 -2
  308. package/src/InfoTip/InfoTip.tsx +1 -0
  309. package/src/InputGroup/InputGroup.doc.mjs +4 -3
  310. package/src/InputGroup/InputGroup.tsx +4 -3
  311. package/src/InputGroup/groupStyles.ts +3 -1
  312. package/src/Item/Item.tsx +51 -9
  313. package/src/Layer/holdEntranceInput.ts +84 -0
  314. package/src/Layer/inputHold.ts +734 -0
  315. package/src/Layer/preserveAnimations.ts +12 -275
  316. package/src/Layer/useLayer.tsx +77 -4
  317. package/src/Layout/LayoutContent.doc.mjs +6 -3
  318. package/src/Layout/LayoutContent.tsx +10 -4
  319. package/src/Layout/LayoutPanel.doc.mjs +6 -3
  320. package/src/Layout/LayoutPanel.tsx +11 -4
  321. package/src/Lightbox/Lightbox.tsx +4 -0
  322. package/src/MetadataList/MetadataList.tsx +1 -1
  323. package/src/MobileNav/MobileNav.doc.mjs +3 -3
  324. package/src/MobileNav/MobileNav.tsx +39 -1
  325. package/src/MoreMenu/MoreMenu.doc.mjs +2 -4
  326. package/src/MoreMenu/MoreMenu.tsx +5 -3
  327. package/src/NumberInput/NumberInput.doc.mjs +1 -1
  328. package/src/NumberInput/NumberInput.tsx +259 -11
  329. package/src/Popover/usePopover.tsx +1 -0
  330. package/src/PowerSearch/PowerSearch.doc.mjs +3 -3
  331. package/src/PowerSearch/PowerSearch.tsx +20 -3
  332. package/src/PowerSearch/PowerSearchBottomSheet.tsx +4 -1
  333. package/src/PowerSearch/PowerSearchToken.tsx +3 -0
  334. package/src/PowerSearch/formatFilterValue.ts +21 -11
  335. package/src/PowerSearch/formatTokenValue.ts +7 -1
  336. package/src/RadioList/RadioListItem.doc.mjs +3 -2
  337. package/src/RadioList/RadioListItem.tsx +25 -7
  338. package/src/SelectableCard/SelectableCard.tsx +8 -1
  339. package/src/Spinner/Spinner.tsx +7 -89
  340. package/src/Spinner/index.ts +1 -5
  341. package/src/Spinner/spinnerRotor.ts +113 -0
  342. package/src/Stack/Stack.doc.mjs +1 -1
  343. package/src/Stack/StackItem.tsx +27 -13
  344. package/src/Switch/Switch.tsx +7 -6
  345. package/src/Table/plugins/sortable/useTableSortable.tsx +1 -1
  346. package/src/Timestamp/Timestamp.doc.mjs +3 -3
  347. package/src/Timestamp/Timestamp.tsx +13 -8
  348. package/src/Timestamp/formatInstant.ts +49 -28
  349. package/src/Timestamp/tooltipEntries.ts +7 -3
  350. package/src/Token/Token.tsx +18 -1
  351. package/src/Token/TokenLink.tsx +7 -1
  352. package/src/Tokenizer/Tokenizer.doc.mjs +3 -3
  353. package/src/Tokenizer/Tokenizer.tsx +252 -115
  354. package/src/Tooltip/useTooltip.tsx +178 -80
  355. package/src/TreeList/TreeListItem.tsx +36 -2
  356. package/src/gestures/GestureHost.ts +21 -5
  357. package/src/gestures/PanGestureRecognizer.ts +19 -2
  358. package/src/gestures/README.md +14 -5
  359. package/src/gestures/ScreenEdgePanGestureRecognizer.ts +6 -1
  360. package/src/gestures/nativeScroll.ts +12 -68
  361. package/src/gestures/wheelSegmenter.ts +243 -10
  362. package/src/hooks/StackItemScrollRegion.tsx +57 -0
  363. package/src/hooks/menuPressGesture.ts +244 -38
  364. package/src/hooks/menuPressValues.ts +18 -0
  365. package/src/hooks/useClickableContainer.doc.mjs +8 -2
  366. package/src/hooks/useClickableContainer.ts +72 -6
  367. package/src/hooks/useFocusTrap.ts +268 -151
  368. package/src/hooks/useMenuPress.ts +118 -11
  369. package/src/hooks/usePressFeedback.doc.mjs +3 -3
  370. package/src/hooks/usePressFeedback.ts +6 -6
  371. package/src/hooks/useScrollRegionProps.ts +76 -0
  372. package/src/i18n/InternationalizationContext.ts +6 -0
  373. package/src/i18n/InternationalizationProvider.doc.mjs +29 -1
  374. package/src/i18n/InternationalizationProvider.tsx +33 -3
  375. package/src/i18n/generated-english/hooks/useScrollRegionProps.generated.ts +13 -0
  376. package/src/i18n/generated-locales/en.generated.ts +1 -0
  377. package/src/i18n/generated-locales/pseudo.generated.ts +1 -0
  378. package/src/i18n/index.ts +2 -0
  379. package/src/i18n/useCalendarSystem.ts +95 -0
  380. package/src/internal/spinner-rotor.ts +20 -0
  381. package/src/internal/touch.ts +34 -1
  382. package/src/motion/MEASUREMENTS.md +11 -0
  383. package/src/motion/carryAnimations.ts +389 -0
  384. package/src/motion/transientCopy.ts +45 -5
  385. package/src/motion/uikit/gestures.ts +22 -0
  386. package/src/motion/uikit/index.ts +1 -0
  387. package/src/motion/uikit/timing.ts +7 -5
  388. package/src/privateAttributes/menuPressLit.stylex.ts +104 -0
  389. package/src/privateAttributes/press.stylex.ts +243 -0
  390. package/src/theme/themeMotion.ts +3 -2
  391. package/src/theme/tokens.stylex.ts +1 -1
  392. package/src/utils/calendarSystem.ts +548 -0
  393. package/src/utils/flatTree.ts +15 -3
  394. package/src/utils/hitArea.ts +107 -5
  395. package/src/utils/inputStream.ts +47 -10
  396. package/src/utils/interactionOverlay.stylex.ts +19 -22
  397. package/src/utils/plainDate.ts +84 -19
  398. package/src/utils/pressFeedback.ts +46 -14
  399. package/src/utils/pressGesture.ts +35 -9
  400. package/src/utils/scrollView.ts +135 -0
  401. package/src/utils/selectionLock.ts +5 -10
  402. package/src/utils/touchHitArea.stylex.ts +41 -0
  403. package/src/utils/triggerFocus.ts +17 -4
@@ -8,8 +8,8 @@
8
8
  * useAdaptivePresentation, and TokenizerBottomSheet (lazy)
9
9
  * @output Exports Tokenizer multi-select typeahead component
10
10
  * @position Composed component; forwards DOM ref and exposes focus control via
11
- * handleRef. The `presentation` prop swaps the inline combobox for a
12
- * trigger that opens TokenizerBottomSheet.
11
+ * handleRef. The `presentation` prop swaps the inline combobox for a field
12
+ * box whose trigger opens TokenizerBottomSheet.
13
13
  *
14
14
  * SYNC: When modified, update:
15
15
  * - /packages/core/src/Tokenizer/index.ts
@@ -48,6 +48,7 @@ import {
48
48
  } from '../Field/fieldParts';
49
49
  import {inputDisabledFocusStyles} from '../Field/inputDisabledFocus';
50
50
  import {useMergedRefs} from '../hooks/useMergedRefs';
51
+ import {hasInteractiveAncestor} from '../hooks/useClickableContainer';
51
52
  import {TokenizerClearAllMessageContext} from './TokenizerClearAllMessageContext';
52
53
  import {TokenizerItemRemovableContext} from './TokenizerItemRemovableContext';
53
54
  import {useBusyAnnouncement} from '../hooks/useBusyAnnouncement';
@@ -303,8 +304,8 @@ export interface TokenizerProps<T extends SearchableItem> extends Omit<
303
304
  * How the field presents its choices.
304
305
  * - `'popover'`: the inline combobox with its anchored suggestion menu, on
305
306
  * every device.
306
- * - `'bottom-sheet'`: a trigger showing the selected tokens that opens one
307
- * tall modal sheet: a search row on top, full-width checkbox rows that
307
+ * - `'bottom-sheet'`: a field showing the selected tokens, whose trigger
308
+ * opens one tall modal sheet: a search row on top, full-width checkbox rows that
308
309
  * keep their place while the sheet is open, a create row with
309
310
  * `hasCreate`, and a footer pinned in every state with a confirmed Clear
310
311
  * all and Save. The sheet edits a draft: `onChange` fires once, when Save
@@ -315,12 +316,16 @@ export interface TokenizerProps<T extends SearchableItem> extends Omit<
315
316
  * otherwise the popover — the same resolution Selector uses. The server
316
317
  * render and the hydrating render are the popover.
317
318
  *
318
- * In the sheet presentation the trigger is the control: `ref`, `id`,
319
- * `aria-*`, and `data-*` reach it. `renderItem`, `renderToken`,
320
- * `endContent`, `hasClear`, `hasEntriesOnFocus`, `menuWidth`,
321
- * `tokenOverflowBehavior`, and `hasAutoFocus` have no surface to act on
322
- * and warn once in development. Pass `'popover'` to keep the inline field
323
- * and those props on every device.
319
+ * In the sheet presentation the field's box keeps the inline field's box,
320
+ * theming target and focus ring, and holds the trigger, the tokens and
321
+ * `endContent`. The trigger is the control: `ref`, `id`, `aria-*`, and
322
+ * `data-*` reach it. `endContent` renders at the field's
323
+ * inline end and `renderToken` renders the field's tokens, as in the inline
324
+ * field. `renderItem`, `hasClear` (the sheet has its own Clear all),
325
+ * `hasEntriesOnFocus`, `menuWidth`, `tokenOverflowBehavior` (the field
326
+ * wraps its tokens), and `hasAutoFocus` have no surface to act on and warn
327
+ * once in development. Pass `'popover'` to keep the inline field and those
328
+ * props on every device.
324
329
  * @default 'adaptive'
325
330
  */
326
331
  presentation?: TokenizerPresentation;
@@ -487,20 +492,52 @@ const styles = stylex.create({
487
492
  color: colorVars['--color-text-secondary'],
488
493
  paddingInline: spacingVars['--spacing-1'],
489
494
  },
490
- // The sheet presentation's trigger: the field's own control box, as a
491
- // button. It wraps tokens like the inline field, but there is no input to
492
- // type into, so the cursor says "press".
493
- sheetTrigger: {
495
+ // The sheet presentation's field: the inline field's own control box. A
496
+ // button cannot contain controls, so the trigger, the tokens and the end lane
497
+ // are siblings in this box. `endContent` and a custom token can then hold their
498
+ // own controls. There is no input to type into, so the cursor says "press".
499
+ sheetField: {
494
500
  width: '100%',
501
+ cursor: {
502
+ default: 'pointer',
503
+ ':is(:disabled,[aria-disabled="true"])': 'default',
504
+ },
505
+ },
506
+ // The box carries no aria-disabled: that would expose a caller's operable
507
+ // `endContent` as disabled. The trigger carries it, so the box keys its
508
+ // disabled cursor on the prop.
509
+ sheetFieldDisabled: {
510
+ cursor: 'default',
511
+ },
512
+ // With tokens, the button covers the box beneath them. A tap on a token or
513
+ // on empty space then opens the sheet. The box draws the focus ring, so the
514
+ // button draws none.
515
+ sheetTrigger: {
516
+ appearance: 'none',
517
+ flexGrow: 1,
518
+ alignSelf: 'stretch',
519
+ display: 'flex',
520
+ alignItems: 'center',
521
+ minWidth: 0,
522
+ padding: 0,
523
+ margin: 0,
524
+ borderWidth: 0,
525
+ borderStyle: 'none',
526
+ backgroundColor: 'transparent',
495
527
  fontFamily: 'inherit',
496
528
  fontSize: 'inherit',
529
+ lineHeight: 'inherit',
497
530
  color: 'inherit',
498
531
  textAlign: 'start',
499
- appearance: 'none',
500
532
  cursor: {
501
533
  default: 'pointer',
502
534
  ':is(:disabled,[aria-disabled="true"])': 'default',
503
535
  },
536
+ outline: 'none',
537
+ },
538
+ sheetTriggerWithTokens: {
539
+ position: 'absolute',
540
+ inset: 0,
504
541
  },
505
542
  // An aria-disabled button gets no system disabled paint in forced colors;
506
543
  // GrayText is the platform's disabled affordance there. Defaults repeat the
@@ -906,8 +943,6 @@ export function Tokenizer<T extends SearchableItem>({
906
943
  ? (
907
944
  [
908
945
  ['renderItem', renderItem],
909
- ['renderToken', renderToken],
910
- ['endContent', endContent],
911
946
  ['hasClear', hasClear || undefined],
912
947
  ['hasEntriesOnFocus', hasEntriesOnFocus || undefined],
913
948
  ['menuWidth', menuWidth],
@@ -989,12 +1024,32 @@ export function Tokenizer<T extends SearchableItem>({
989
1024
  [tooltipAnchorRef],
990
1025
  );
991
1026
 
1027
+ // A swap also removes `endContent` and a custom token's remove. If focus is
1028
+ // in the box when it detaches, the new control takes it. The box also anchors
1029
+ // the disabled-message tooltip.
1030
+ const sheetFieldCallbackRef = useCallback(
1031
+ (el: HTMLDivElement | null) => {
1032
+ tooltipAnchorRef(el);
1033
+ if (el == null) {
1034
+ return;
1035
+ }
1036
+ return () => {
1037
+ if (el.contains(el.ownerDocument.activeElement)) {
1038
+ isFocusPendingHandOffRef.current = true;
1039
+ }
1040
+ tooltipAnchorRef(null);
1041
+ };
1042
+ },
1043
+ [tooltipAnchorRef],
1044
+ );
1045
+
992
1046
  // The sheet presentation has no input; the public ref reaches the trigger,
993
- // the control it stands for (`family:input-fields` FR10).
1047
+ // the control it stands for (`family:input-fields` FR10). The
1048
+ // disabled-message tooltip anchors to the field box around it, as it
1049
+ // anchors to the inline field's wrapper.
994
1050
  const triggerMergedRef = useMergedRefs<HTMLButtonElement>(
995
1051
  triggerRef,
996
1052
  ref as React.Ref<HTMLButtonElement> | undefined,
997
- disabledMessageTooltip.ref,
998
1053
  handOffFocusRef,
999
1054
  );
1000
1055
 
@@ -1019,6 +1074,14 @@ export function Tokenizer<T extends SearchableItem>({
1019
1074
  // `endContent`, a clear button, or all three — so its width is measured
1020
1075
  // rather than assumed, and the input reserves it.
1021
1076
  const [laneRef, laneReserve] = useEndLaneReserve(END_LANE_INSET);
1077
+ // `laneRef` publishes the lane's width, so token rows and the placeholder
1078
+ // stop short of it. `sheetLaneRef` tells a tap in the lane from a tap on the
1079
+ // field.
1080
+ const sheetLaneRef = useRef<HTMLDivElement | null>(null);
1081
+ const sheetLaneMergedRef = useMergedRefs<HTMLDivElement>(
1082
+ laneRef,
1083
+ sheetLaneRef,
1084
+ );
1022
1085
  // A composing component can lock tokens (PowerSearch's read-only filters
1023
1086
  // and read-only field). No remove path removes a locked token.
1024
1087
  const isItemRemovable = use(TokenizerItemRemovableContext);
@@ -1556,92 +1619,91 @@ export function Tokenizer<T extends SearchableItem>({
1556
1619
  </div>
1557
1620
  );
1558
1621
 
1622
+ // A `renderToken` token's own remove control in the sheet field removes at
1623
+ // once, as it does in the inline field. Its control leaves with it, so
1624
+ // focus moves to the trigger.
1625
+ const handleSheetTokenRemove = (item: T) => {
1626
+ if (handleRemove(item)) {
1627
+ triggerRef.current?.focus();
1628
+ }
1629
+ };
1630
+ // A tap on a token, the placeholder or empty space opens the sheet, as a tap
1631
+ // on the trigger does. The trigger, `endContent` and a custom token's
1632
+ // controls handle their own clicks.
1633
+ const handleSheetFieldClick = (event: React.MouseEvent<HTMLDivElement>) => {
1634
+ const trigger = triggerRef.current;
1635
+ const target = event.target;
1636
+ if (trigger == null || !(target instanceof Element)) {
1637
+ return;
1638
+ }
1639
+ if (
1640
+ trigger.contains(target) ||
1641
+ sheetLaneRef.current?.contains(target) ||
1642
+ hasInteractiveAncestor(target, event.currentTarget)
1643
+ ) {
1644
+ return;
1645
+ }
1646
+ trigger.click();
1647
+ };
1648
+
1649
+ // The caller's onFocus and onBlur report focus entering and leaving the whole
1650
+ // box, as for the inline wrapper. A move between the trigger, `endContent`
1651
+ // and a custom token's controls stays inside the field.
1652
+ const handleSheetFieldFocus = (event: React.FocusEvent<HTMLDivElement>) => {
1653
+ // BottomSheet focuses the trigger only after its exit completes; that
1654
+ // focus is the signal that the retained sheet can leave. If the
1655
+ // resolution moved to the popover meanwhile, the inline input takes the
1656
+ // focus over once it mounts.
1657
+ const isReturningFromSheet =
1658
+ (event.target as EventTarget) === triggerRef.current &&
1659
+ !isSheetOpen &&
1660
+ isSheetPresented;
1661
+ if (isReturningFromSheet) {
1662
+ setIsSheetPresented(false);
1663
+ }
1664
+ const relatedTarget = event.relatedTarget;
1665
+ if (
1666
+ relatedTarget instanceof Node &&
1667
+ event.currentTarget.contains(relatedTarget)
1668
+ ) {
1669
+ return;
1670
+ }
1671
+ // Focus that returns from the field's own sheet, or that a presentation swap
1672
+ // hands over, does not enter from outside. The caller's onFocus stays quiet
1673
+ // for it (`family:input-fields` FR10).
1674
+ const isInsideTheField =
1675
+ (isReturningFromSheet && hasReportedFocusRef.current) ||
1676
+ isHandingOffFocusRef.current;
1677
+ if (!isInsideTheField) {
1678
+ hasReportedFocusRef.current = true;
1679
+ onFocus?.(event);
1680
+ }
1681
+ };
1682
+ const handleSheetFieldBlur = (event: React.FocusEvent<HTMLDivElement>) => {
1683
+ // Focus moving into the sheet, or to another control in the box, is
1684
+ // still the field's. Only a blur to somewhere else reports.
1685
+ const relatedTarget = event.relatedTarget;
1686
+ if (
1687
+ isSheetOpen ||
1688
+ (relatedTarget instanceof Node &&
1689
+ event.currentTarget.contains(relatedTarget))
1690
+ ) {
1691
+ return;
1692
+ }
1693
+ hasReportedFocusRef.current = false;
1694
+ isFocusPendingHandOffRef.current = false;
1695
+ onBlur?.(event);
1696
+ };
1697
+
1559
1698
  let tokenizerContent: ReactNode;
1560
1699
  if (isSheetPresentation) {
1561
1700
  tokenizerContent = (
1562
1701
  <>
1563
- <button
1564
- // The field-level pass-through props (`data-*`, `aria-*`) were typed
1565
- // for the inline input; here the control is a button.
1566
- {...(restWithoutClick as React.ButtonHTMLAttributes<HTMLButtonElement>)}
1567
- ref={triggerMergedRef}
1568
- type="button"
1569
- id={inputId}
1570
- aria-labelledby={fieldLabelledBy}
1571
- aria-haspopup="dialog"
1572
- aria-expanded={isSheetOpen}
1573
- aria-disabled={isDisabled || undefined}
1574
- // The description is what the inline input's is, in its order —
1575
- // the caller's ids, the field description, the status message, the
1576
- // disabled reason (`spec:AST-085` FR5: a disabled control exposes
1577
- // its description and reason on itself) — then the hidden count and
1578
- // the rendered tokens themselves, each by id: the
1579
- // accessible-description algorithm reads the referenced elements in
1580
- // order and separates them, so every label renders once
1581
- // (`architecture:component-style-authoring` INV7) and no locale's
1582
- // list punctuation is written here (AR6).
1583
- aria-describedby={
1584
- [
1585
- ariaDescribedByProp,
1586
- ariaDescribedBy,
1587
- value.length > 0 ? triggerTokensId : null,
1588
- ...value.map(item => tokenElementId(item.id)),
1589
- ]
1590
- .filter(Boolean)
1591
- .join(' ') || undefined
1592
- }
1593
- // The open runs first and the caller's onClick after it, as the
1594
- // inline input composes its click: a caller observes the click but
1595
- // cannot cancel the field's own handling
1596
- // (`family:input-fields` FR10).
1597
- onClick={composeEventHandlers<React.MouseEvent<HTMLButtonElement>>(
1598
- () => {
1599
- if (isDisabled) {
1600
- return;
1601
- }
1602
- setIsSheetPresented(true);
1603
- setSheetInitialQuery(sheetQueryRef.current);
1604
- setIsSheetOpen(true);
1605
- },
1606
- // Typed for the input by the base props; here the control is the
1607
- // trigger button, and the handler only reads the event.
1608
- callerOnClick as unknown as
1609
- React.MouseEventHandler<HTMLButtonElement> | undefined,
1610
- )}
1611
- onFocus={event => {
1612
- // BottomSheet focuses the trigger only after its exit completes;
1613
- // that focus is the signal that the retained sheet can leave. If
1614
- // the resolution moved to the popover meanwhile, the inline input
1615
- // takes the focus over once it mounts. The field's own sheet is
1616
- // part of the field: focus coming back from it, or handed over by
1617
- // a presentation swap, is not focus entering from outside, so the
1618
- // caller's onFocus — "when focus enters the tokenizer from
1619
- // outside" — stays quiet for it (`family:input-fields` FR10).
1620
- const isReturningFromSheet = !isSheetOpen && isSheetPresented;
1621
- if (isReturningFromSheet) {
1622
- setIsSheetPresented(false);
1623
- }
1624
- const isInsideTheField =
1625
- (isReturningFromSheet && hasReportedFocusRef.current) ||
1626
- isHandingOffFocusRef.current;
1627
- if (!isInsideTheField) {
1628
- hasReportedFocusRef.current = true;
1629
- onFocus?.(event);
1630
- }
1631
- }}
1632
- onBlur={event => {
1633
- // Focus moving into the sheet is still the field's: the flag
1634
- // stays, and the caller's onBlur — "when focus leaves the
1635
- // tokenizer entirely" — stays quiet. Only a blur to somewhere
1636
- // else reports.
1637
- if (isSheetOpen) {
1638
- return;
1639
- }
1640
- hasReportedFocusRef.current = false;
1641
- isFocusPendingHandOffRef.current = false;
1642
- onBlur?.(event);
1643
- }}
1644
- onKeyDown={onKeyDown}
1702
+ <div
1703
+ ref={sheetFieldCallbackRef}
1704
+ onClick={handleSheetFieldClick}
1705
+ onFocus={handleSheetFieldFocus}
1706
+ onBlur={handleSheetFieldBlur}
1645
1707
  {...mergeProps(
1646
1708
  themeProps('tokenizer', {
1647
1709
  size,
@@ -1651,8 +1713,9 @@ export function Tokenizer<T extends SearchableItem>({
1651
1713
  stylex.props(
1652
1714
  inputWrapperStyles.base,
1653
1715
  styles.wrapper,
1654
- styles.sheetTrigger,
1655
- // The trigger keeps the inline field's height for its size step,
1716
+ styles.sheetField,
1717
+ isDisabled && styles.sheetFieldDisabled,
1718
+ // The field keeps the inline field's height for its size step,
1656
1719
  // as Selector's bottom-sheet trigger does; the sheet's own rows
1657
1720
  // and search field carry the touch-sized targets.
1658
1721
  sizeStyles[size],
@@ -1675,8 +1738,77 @@ export function Tokenizer<T extends SearchableItem>({
1675
1738
  {renderIconSlot(startIcon, {size: 'sm', color: 'secondary'})}
1676
1739
  </span>
1677
1740
  )}
1678
- {value.length > 0 ? (
1679
- value.map(item => (
1741
+ <button
1742
+ // The field-level pass-through props (`data-*`, `aria-*`) were typed
1743
+ // for the inline input; here the control is a button.
1744
+ {...(restWithoutClick as React.ButtonHTMLAttributes<HTMLButtonElement>)}
1745
+ ref={triggerMergedRef}
1746
+ type="button"
1747
+ id={inputId}
1748
+ aria-labelledby={fieldLabelledBy}
1749
+ aria-haspopup="dialog"
1750
+ aria-expanded={isSheetOpen}
1751
+ aria-disabled={isDisabled || undefined}
1752
+ // The description follows the inline input's order: the caller's
1753
+ // ids, the field description, the status message, then the
1754
+ // disabled reason (`spec:AST-085` FR5). The hidden count and the
1755
+ // token labels follow, each by id. The algorithm separates
1756
+ // referenced elements, so no list punctuation is written here
1757
+ // (AR6). A default token is display-only and is its own label. A
1758
+ // custom token can hold controls, so a hidden copy of its item
1759
+ // label stands in.
1760
+ aria-describedby={
1761
+ [
1762
+ ariaDescribedByProp,
1763
+ ariaDescribedBy,
1764
+ value.length > 0 ? triggerTokensId : null,
1765
+ ...value.map(item => tokenElementId(item.id)),
1766
+ ]
1767
+ .filter(Boolean)
1768
+ .join(' ') || undefined
1769
+ }
1770
+ // The open runs first and the caller's onClick after it, as the
1771
+ // inline input composes its click: a caller observes the click but
1772
+ // cannot cancel the field's own handling
1773
+ // (`family:input-fields` FR10).
1774
+ onClick={composeEventHandlers<React.MouseEvent<HTMLButtonElement>>(
1775
+ () => {
1776
+ if (isDisabled) {
1777
+ return;
1778
+ }
1779
+ setIsSheetPresented(true);
1780
+ setSheetInitialQuery(sheetQueryRef.current);
1781
+ setIsSheetOpen(true);
1782
+ },
1783
+ // Typed for the input by the base props; here the control is the
1784
+ // trigger button, and the handler only reads the event.
1785
+ callerOnClick as unknown as
1786
+ React.MouseEventHandler<HTMLButtonElement> | undefined,
1787
+ )}
1788
+ onKeyDown={onKeyDown}
1789
+ {...stylex.props(
1790
+ styles.sheetTrigger,
1791
+ value.length > 0 && styles.sheetTriggerWithTokens,
1792
+ // With no token the placeholder stops short of the end lane, as
1793
+ // the inline input's text does.
1794
+ value.length === 0 && laneReserve,
1795
+ )}>
1796
+ {value.length === 0 && (
1797
+ <span
1798
+ {...stylex.props(
1799
+ styles.sheetTriggerPlaceholder,
1800
+ isDisabled && styles.sheetTriggerPlaceholderDisabled,
1801
+ )}>
1802
+ {placeholder ?? ''}
1803
+ </span>
1804
+ )}
1805
+ </button>
1806
+ {value.map(item =>
1807
+ renderToken ? (
1808
+ <span key={item.id} {...stylex.props(styles.token)}>
1809
+ {renderToken(item, () => handleSheetTokenRemove(item))}
1810
+ </span>
1811
+ ) : (
1680
1812
  <Token
1681
1813
  key={item.id}
1682
1814
  id={tokenElementId(item.id)}
@@ -1685,22 +1817,27 @@ export function Tokenizer<T extends SearchableItem>({
1685
1817
  isDisabled={isDisabled}
1686
1818
  xstyle={isDisabled ? styles.sheetTokenDisabled : undefined}
1687
1819
  />
1688
- ))
1689
- ) : (
1690
- <span
1691
- {...stylex.props(
1692
- styles.sheetTriggerPlaceholder,
1693
- isDisabled && styles.sheetTriggerPlaceholderDisabled,
1694
- )}>
1695
- {placeholder ?? ''}
1696
- </span>
1820
+ ),
1821
+ )}
1822
+ {isRenderable(endContent) && (
1823
+ <div
1824
+ ref={sheetLaneMergedRef}
1825
+ {...stylex.props(styles.endSection, endSectionSizeStyles[size])}>
1826
+ {endContent}
1827
+ </div>
1697
1828
  )}
1698
- </button>
1829
+ </div>
1699
1830
  {value.length > 0 && (
1700
1831
  <VisuallyHidden id={triggerTokensId}>
1701
1832
  {t('@astryx.tokenizer.selectedCount', {count: value.length})}
1702
1833
  </VisuallyHidden>
1703
1834
  )}
1835
+ {renderToken != null &&
1836
+ value.map(item => (
1837
+ <span key={item.id} id={tokenElementId(item.id)} hidden>
1838
+ {item.label}
1839
+ </span>
1840
+ ))}
1704
1841
  {/* Form carriers, gated exactly as the inline branch gates its own: a
1705
1842
  disabled field submits nothing. */}
1706
1843
  {htmlName != null &&