ropav 0.3.1 → 0.5.0

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 (277) hide show
  1. package/dist/components/autocomplete/autocomplete-root.js +3 -1
  2. package/dist/components/autocomplete/index.d.ts +3 -0
  3. package/dist/components/avatar/avatar-image.js +13 -2
  4. package/dist/components/avatar/avatar.types.d.ts +7 -1
  5. package/dist/components/breadcrumbs/breadcrumbs-item.js +1 -0
  6. package/dist/components/breadcrumbs/index.d.ts +1 -0
  7. package/dist/components/calendar/calendar-header.js +1 -1
  8. package/dist/components/calendar/index.d.ts +5 -3
  9. package/dist/components/calendar-year-picker/index.d.ts +4 -2
  10. package/dist/components/checkbox/checkbox-content.js +1 -1
  11. package/dist/components/color-field/index.d.ts +3 -2
  12. package/dist/components/color-input-group/color-input-group-root.js +2 -0
  13. package/dist/components/color-input-group/color-input-group.types.d.ts +2 -0
  14. package/dist/components/color-input-group/index.d.ts +2 -0
  15. package/dist/components/combo-box/combo-box-root.js +9 -2
  16. package/dist/components/combo-box/combo-box.types.d.ts +3 -0
  17. package/dist/components/combo-box/index.d.ts +3 -0
  18. package/dist/components/date-field/index.d.ts +1 -0
  19. package/dist/components/date-input-group/date-input-group-root.js +2 -0
  20. package/dist/components/date-input-group/date-input-group-segment.js +1 -1
  21. package/dist/components/date-input-group/date-input-group.types.d.ts +2 -0
  22. package/dist/{composables → components/date-input-group}/use-date-segment.d.ts +2 -2
  23. package/dist/{composables → components/date-input-group}/use-date-segment.js +9 -9
  24. package/dist/components/date-picker/index.d.ts +3 -2
  25. package/dist/components/date-picker/index.js +2 -2
  26. package/dist/components/date-range-picker/date-range-picker-root.js +1 -1
  27. package/dist/components/date-range-picker/index.d.ts +18 -16
  28. package/dist/components/date-range-picker/index.js +2 -2
  29. package/dist/{composables → components/date-range-picker}/use-date-range-picker.d.ts +7 -7
  30. package/dist/{composables → components/date-range-picker}/use-date-range-picker.js +10 -10
  31. package/dist/components/drawer/drawer-dialog.js +1 -1
  32. package/dist/{composables → components/drawer}/use-drawer-drag.d.ts +1 -1
  33. package/dist/{composables → components/drawer}/use-drawer-drag.js +1 -1
  34. package/dist/components/dropdown/dropdown-menu.js +3 -1
  35. package/dist/components/dropdown/dropdown-submenu-trigger.js +1 -1
  36. package/dist/components/dropdown/dropdown.types.d.ts +3 -3
  37. package/dist/components/dropdown/index.d.ts +4 -2
  38. package/dist/{composables → components/dropdown}/use-safely-mouse-to-submenu.js +1 -1
  39. package/dist/components/icons/icon-overlay-arrow.js +1 -1
  40. package/dist/components/index.d.ts +5 -0
  41. package/dist/components/input/index.d.ts +12 -4
  42. package/dist/components/input/input-root.d.ts +5 -2
  43. package/dist/components/input/input-root.js +46 -5
  44. package/dist/components/input/input.types.d.ts +11 -0
  45. package/dist/components/input-group/index.d.ts +2 -0
  46. package/dist/components/input-group/input-group-root.js +3 -0
  47. package/dist/components/input-group/input-group.types.d.ts +5 -0
  48. package/dist/components/input-otp/index.d.ts +6 -4
  49. package/dist/components/link/index.d.ts +2 -0
  50. package/dist/components/link/link-root.js +22 -5
  51. package/dist/components/link/link.types.d.ts +14 -3
  52. package/dist/{composables → components/list-box}/drag-collection.d.ts +2 -2
  53. package/dist/{composables → components/list-box}/drag-collection.js +1 -1
  54. package/dist/components/list-box/index.d.ts +4 -0
  55. package/dist/components/list-box/list-box-root.js +60 -35
  56. package/dist/components/list-box/list-box.types.d.ts +2 -0
  57. package/dist/components/menu/index.d.ts +4 -0
  58. package/dist/components/menu/menu-root.js +9 -2
  59. package/dist/components/menu/menu.types.d.ts +5 -0
  60. package/dist/components/number-field/index.d.ts +3 -0
  61. package/dist/components/number-field/number-field-root.js +2 -0
  62. package/dist/components/number-field/number-field.types.d.ts +2 -0
  63. package/dist/components/overlay/overlay-arrow.js +64 -11
  64. package/dist/components/pagination/index.d.ts +2 -0
  65. package/dist/components/pagination/pagination-root.js +8 -3
  66. package/dist/components/pagination/pagination.types.d.ts +8 -0
  67. package/dist/components/popover/popover-trigger.js +14 -7
  68. package/dist/components/radio/radio-content.js +1 -1
  69. package/dist/components/range-calendar/index.d.ts +18 -15
  70. package/dist/components/range-calendar/range-calendar-header.js +1 -1
  71. package/dist/components/router-provider/index.d.ts +5 -0
  72. package/dist/components/router-provider/index.js +3 -0
  73. package/dist/components/router-provider/router-provider.context.d.ts +40 -0
  74. package/dist/components/router-provider/router-provider.context.js +16 -0
  75. package/dist/components/router-provider/router-provider.d.ts +21 -0
  76. package/dist/components/router-provider/router-provider.js +22 -0
  77. package/dist/components/router-provider/router-provider.types.d.ts +23 -0
  78. package/dist/components/scroll-shadow/scroll-shadow-root.js +7 -1
  79. package/dist/components/scroll-shadow/use-scroll-shadow.js +25 -1
  80. package/dist/components/search-field/index.d.ts +2 -0
  81. package/dist/components/search-field/search-field-root.js +3 -1
  82. package/dist/components/search-field/search-field.types.d.ts +2 -0
  83. package/dist/{composables → components/search-field}/use-search-field.d.ts +2 -2
  84. package/dist/{composables → components/search-field}/use-search-field.js +3 -3
  85. package/dist/components/segmented-control/index.d.ts +134 -0
  86. package/dist/components/segmented-control/index.js +15 -0
  87. package/dist/components/segmented-control/segmented-control-indicator.d.ts +19 -0
  88. package/dist/components/segmented-control/segmented-control-indicator.js +36 -0
  89. package/dist/components/segmented-control/segmented-control-item.d.ts +21 -0
  90. package/dist/components/segmented-control/segmented-control-item.js +96 -0
  91. package/dist/components/segmented-control/segmented-control-root.d.ts +25 -0
  92. package/dist/components/segmented-control/segmented-control-root.js +112 -0
  93. package/dist/components/segmented-control/segmented-control-separator.d.ts +19 -0
  94. package/dist/components/segmented-control/segmented-control-separator.js +18 -0
  95. package/dist/components/segmented-control/segmented-control.context.d.ts +17 -0
  96. package/dist/components/segmented-control/segmented-control.context.js +12 -0
  97. package/dist/components/segmented-control/segmented-control.types.d.ts +67 -0
  98. package/dist/components/select/index.d.ts +3 -0
  99. package/dist/components/select/select-hidden-select.js +1 -1
  100. package/dist/components/select/select-root.js +2 -0
  101. package/dist/components/select/select.types.d.ts +2 -0
  102. package/dist/components/separator/separator-root.js +11 -5
  103. package/dist/components/separator/separator.context.d.ts +7 -0
  104. package/dist/components/sidebar/index.d.ts +544 -0
  105. package/dist/components/sidebar/index.js +47 -0
  106. package/dist/components/sidebar/sidebar-collapsible-trigger.d.ts +21 -0
  107. package/dist/components/sidebar/sidebar-collapsible-trigger.js +70 -0
  108. package/dist/components/sidebar/sidebar-collapsible.d.ts +24 -0
  109. package/dist/components/sidebar/sidebar-collapsible.js +78 -0
  110. package/dist/components/sidebar/sidebar-content.d.ts +21 -0
  111. package/dist/components/sidebar/sidebar-content.js +37 -0
  112. package/dist/components/sidebar/sidebar-footer.d.ts +21 -0
  113. package/dist/components/sidebar/sidebar-footer.js +24 -0
  114. package/dist/components/sidebar/sidebar-group-label.d.ts +21 -0
  115. package/dist/components/sidebar/sidebar-group-label.js +32 -0
  116. package/dist/components/sidebar/sidebar-group.d.ts +21 -0
  117. package/dist/components/sidebar/sidebar-group.js +48 -0
  118. package/dist/components/sidebar/sidebar-header.d.ts +21 -0
  119. package/dist/components/sidebar/sidebar-header.js +24 -0
  120. package/dist/components/sidebar/sidebar-inset.d.ts +21 -0
  121. package/dist/components/sidebar/sidebar-inset.js +24 -0
  122. package/dist/components/sidebar/sidebar-item-icon.d.ts +21 -0
  123. package/dist/components/sidebar/sidebar-item-icon.js +20 -0
  124. package/dist/components/sidebar/sidebar-item-indicator.d.ts +21 -0
  125. package/dist/components/sidebar/sidebar-item-indicator.js +48 -0
  126. package/dist/components/sidebar/sidebar-item-label.d.ts +21 -0
  127. package/dist/components/sidebar/sidebar-item-label.js +28 -0
  128. package/dist/components/sidebar/sidebar-item-tooltip.d.ts +21 -0
  129. package/dist/components/sidebar/sidebar-item-tooltip.js +38 -0
  130. package/dist/components/sidebar/sidebar-item-trailing.d.ts +21 -0
  131. package/dist/components/sidebar/sidebar-item-trailing.js +28 -0
  132. package/dist/components/sidebar/sidebar-item.d.ts +23 -0
  133. package/dist/components/sidebar/sidebar-item.js +160 -0
  134. package/dist/components/sidebar/sidebar-panel.d.ts +21 -0
  135. package/dist/components/sidebar/sidebar-panel.js +88 -0
  136. package/dist/components/sidebar/sidebar-rail.d.ts +21 -0
  137. package/dist/components/sidebar/sidebar-rail.js +210 -0
  138. package/dist/components/sidebar/sidebar-root.d.ts +31 -0
  139. package/dist/components/sidebar/sidebar-root.js +138 -0
  140. package/dist/components/sidebar/sidebar-separator.d.ts +19 -0
  141. package/dist/components/sidebar/sidebar-separator.js +16 -0
  142. package/dist/components/sidebar/sidebar-sub-menu.d.ts +23 -0
  143. package/dist/components/sidebar/sidebar-sub-menu.js +40 -0
  144. package/dist/components/sidebar/sidebar-trigger.d.ts +21 -0
  145. package/dist/components/sidebar/sidebar-trigger.js +69 -0
  146. package/dist/components/sidebar/sidebar.context.d.ts +75 -0
  147. package/dist/components/sidebar/sidebar.context.js +30 -0
  148. package/dist/components/sidebar/sidebar.state.d.ts +73 -0
  149. package/dist/components/sidebar/sidebar.state.js +76 -0
  150. package/dist/components/sidebar/sidebar.storage.d.ts +8 -0
  151. package/dist/components/sidebar/sidebar.storage.js +45 -0
  152. package/dist/components/sidebar/sidebar.types.d.ts +259 -0
  153. package/dist/components/splitter/index.d.ts +143 -0
  154. package/dist/components/splitter/index.js +13 -0
  155. package/dist/components/splitter/splitter-handle.d.ts +21 -0
  156. package/dist/components/splitter/splitter-handle.js +209 -0
  157. package/dist/components/splitter/splitter-panel.d.ts +21 -0
  158. package/dist/components/splitter/splitter-panel.js +70 -0
  159. package/dist/components/splitter/splitter-root.d.ts +31 -0
  160. package/dist/components/splitter/splitter-root.js +152 -0
  161. package/dist/components/splitter/splitter.context.d.ts +15 -0
  162. package/dist/components/splitter/splitter.context.js +5 -0
  163. package/dist/components/splitter/splitter.state.d.ts +87 -0
  164. package/dist/components/splitter/splitter.state.js +322 -0
  165. package/dist/components/splitter/splitter.storage.d.ts +15 -0
  166. package/dist/components/splitter/splitter.storage.js +56 -0
  167. package/dist/components/splitter/splitter.types.d.ts +98 -0
  168. package/dist/components/switch/switch-content.js +1 -1
  169. package/dist/components/table/index.d.ts +10 -9
  170. package/dist/components/table/table-body.js +13 -13
  171. package/dist/components/table/table-cell.js +49 -46
  172. package/dist/components/table/table-column-resizer.js +1 -1
  173. package/dist/components/table/table-column.js +1 -1
  174. package/dist/components/table/table-content.js +37 -18
  175. package/dist/{composables → components/table}/table-drag-collection.d.ts +1 -1
  176. package/dist/{composables → components/table}/table-drag-collection.js +1 -1
  177. package/dist/components/table/table-drop-indicator.js +3 -1
  178. package/dist/components/table/table-resizable-container.d.ts +4 -5
  179. package/dist/components/table/table-row.js +45 -14
  180. package/dist/components/table/table-virtualizer-item.d.ts +2 -7
  181. package/dist/components/table/table-virtualizer-item.js +20 -9
  182. package/dist/components/table/table.context.d.ts +11 -3
  183. package/dist/components/table/table.types.d.ts +1 -1
  184. package/dist/{composables → components/table}/use-grid-keyboard.d.ts +3 -3
  185. package/dist/{composables → components/table}/use-grid-keyboard.js +57 -55
  186. package/dist/{composables → components/table}/use-grid-selection-announcement.d.ts +2 -2
  187. package/dist/{composables → components/table}/use-grid-selection-announcement.js +2 -2
  188. package/dist/{composables → components/table}/use-table-collection.d.ts +2 -2
  189. package/dist/{composables → components/table}/use-table-collection.js +4 -4
  190. package/dist/{composables → components/table}/use-table-column-layout.d.ts +13 -20
  191. package/dist/components/table/use-table-column-layout.js +115 -0
  192. package/dist/components/tabs/tabs-panel.js +5 -1
  193. package/dist/components/tabs/tabs-tab.js +1 -1
  194. package/dist/components/textarea/index.d.ts +12 -4
  195. package/dist/components/textarea/textarea-root.d.ts +5 -2
  196. package/dist/components/textarea/textarea-root.js +40 -5
  197. package/dist/components/textarea/textarea.types.d.ts +11 -0
  198. package/dist/components/textfield/index.d.ts +2 -0
  199. package/dist/components/textfield/textfield-root.js +5 -1
  200. package/dist/components/textfield/textfield.context.d.ts +2 -0
  201. package/dist/components/textfield/textfield.types.d.ts +5 -0
  202. package/dist/components/time-field/index.d.ts +1 -0
  203. package/dist/components/toast/index.d.ts +1 -0
  204. package/dist/components/toast/toast-default-content.js +1 -1
  205. package/dist/components/toggle-button-group/toggle-button-group-root.js +3 -3
  206. package/dist/components/toolbar/index.d.ts +3 -2
  207. package/dist/components/toolbar/toolbar-root.js +3 -3
  208. package/dist/components/tooltip/index.js +1 -1
  209. package/dist/components/tooltip/tooltip-root.js +1 -1
  210. package/dist/components/tooltip/tooltip-trigger.js +13 -5
  211. package/dist/components/virtualizer/index.d.ts +3 -1
  212. package/dist/components/virtualizer/index.js +2 -1
  213. package/dist/components/virtualizer/use-virtualizer-item.d.ts +23 -0
  214. package/dist/components/virtualizer/use-virtualizer-item.js +45 -0
  215. package/dist/components/virtualizer/virtualizer-item.js +7 -41
  216. package/dist/components/virtualizer/virtualizer-scrollbar-track.d.ts +20 -0
  217. package/dist/components/virtualizer/virtualizer-scrollbar-track.js +141 -0
  218. package/dist/components/virtualizer/virtualizer-scrollbar.d.ts +18 -0
  219. package/dist/components/virtualizer/virtualizer-scrollbar.js +55 -0
  220. package/dist/components/virtualizer/virtualizer.context.d.ts +17 -1
  221. package/dist/composables/drag-manager.js +1 -13
  222. package/dist/composables/index.d.ts +3 -71
  223. package/dist/composables/use-collection.d.ts +22 -3
  224. package/dist/composables/use-collection.js +67 -14
  225. package/dist/composables/use-color-area.js +2 -2
  226. package/dist/composables/use-color-field.js +1 -1
  227. package/dist/composables/use-combo-box.js +1 -1
  228. package/dist/composables/use-date-field.js +1 -1
  229. package/dist/composables/use-drag-and-drop.js +1 -1
  230. package/dist/composables/use-drag.d.ts +6 -5
  231. package/dist/composables/use-draggable-item.d.ts +2 -2
  232. package/dist/composables/use-droppable-collection.js +2 -2
  233. package/dist/composables/use-droppable-item.js +1 -1
  234. package/dist/composables/use-form-reset.d.ts +6 -2
  235. package/dist/composables/use-form-reset.js +9 -5
  236. package/dist/composables/use-list-keyboard.js +64 -62
  237. package/dist/composables/use-menu.d.ts +10 -0
  238. package/dist/composables/use-menu.js +22 -0
  239. package/dist/composables/use-number-field.js +1 -1
  240. package/dist/composables/use-select.js +2 -3
  241. package/dist/composables/use-selection-manager.js +4 -4
  242. package/dist/composables/use-single-select-list-state.d.ts +37 -0
  243. package/dist/composables/use-single-select-list-state.js +110 -0
  244. package/dist/composables/use-slider-thumb.js +2 -2
  245. package/dist/composables/use-slider.js +1 -1
  246. package/dist/composables/use-tab-list-state.d.ts +20 -29
  247. package/dist/composables/use-tab-list-state.js +20 -99
  248. package/dist/composables/use-text-field.js +1 -1
  249. package/dist/composables/use-virtualizer-scroll.d.ts +52 -2
  250. package/dist/composables/use-virtualizer-scroll.js +79 -13
  251. package/dist/composables/use-virtualizer.d.ts +24 -4
  252. package/dist/composables/use-virtualizer.js +40 -6
  253. package/dist/index.js +58 -80
  254. package/dist/utils/document-order.d.ts +14 -0
  255. package/dist/utils/document-order.js +17 -0
  256. package/dist/utils/flex-sizing.d.ts +41 -0
  257. package/dist/utils/flex-sizing.js +140 -0
  258. package/dist/utils/index.d.ts +2 -0
  259. package/dist/utils/open-link.d.ts +31 -0
  260. package/dist/utils/open-link.js +32 -0
  261. package/dist/utils/story-truncation.d.ts +20 -0
  262. package/dist/utils/story-users.d.ts +11 -0
  263. package/dist/utils/virtualizer-collection.d.ts +14 -4
  264. package/dist/utils/virtualizer-collection.js +9 -14
  265. package/dist/utils/virtualizer-layout-info.js +3 -2
  266. package/dist/utils/virtualizer-list-layout.d.ts +75 -29
  267. package/dist/utils/virtualizer-list-layout.js +182 -99
  268. package/dist/utils/virtualizer-offsets.d.ts +111 -0
  269. package/dist/utils/virtualizer-offsets.js +159 -0
  270. package/dist/utils/virtualizer-overscan.d.ts +9 -15
  271. package/dist/utils/virtualizer-overscan.js +14 -33
  272. package/dist/utils/virtualizer-table-layout.d.ts +50 -21
  273. package/dist/utils/virtualizer-table-layout.js +130 -89
  274. package/dist/version.js +1 -1
  275. package/package.json +19 -3
  276. package/dist/composables/use-table-column-layout.js +0 -214
  277. /package/dist/{composables → components/dropdown}/use-safely-mouse-to-submenu.d.ts +0 -0
@@ -7,6 +7,14 @@ export interface UseMenuOptions {
7
7
  id?: MaybeRefOrGetter<string | undefined>;
8
8
  /** The id of the element naming the menu, normally the trigger. */
9
9
  labelledBy?: MaybeRefOrGetter<string | undefined>;
10
+ /**
11
+ * Names the menu when there is no element to point `labelledBy` at.
12
+ *
13
+ * A menu inside a trigger is named by it and never needs this; a menu standing on its own has
14
+ * nothing to borrow a name from, and a name is not something axe checks for `role="menu"` — so
15
+ * without a string to pass, a standalone menu ships unnamed and nothing says so.
16
+ */
17
+ label?: MaybeRefOrGetter<string | undefined>;
10
18
  selectionMode?: MaybeRefOrGetter<SelectionMode | undefined>;
11
19
  selectionBehavior?: MaybeRefOrGetter<SelectionBehavior | undefined>;
12
20
  selectedKeys?: MaybeRefOrGetter<"all" | Iterable<CollectionKey> | undefined>;
@@ -33,6 +41,8 @@ export interface UseMenuReturn {
33
41
  collectionId: ComputedRef<string>;
34
42
  /** Attributes the menu element renders, beside its own class and `data-slot`. */
35
43
  menuAttributes: ComputedRef<Record<string, string | number | boolean | undefined>>;
44
+ /** Attributes the wrapper around the empty slot renders. */
45
+ emptyAttributes: ComputedRef<Record<string, string | number | boolean | undefined>>;
36
46
  onKeydown: (event: KeyboardEvent) => void;
37
47
  onKeydownCapture: (event: KeyboardEvent) => void;
38
48
  onFocusin: (event: FocusEvent) => void;
@@ -84,8 +84,30 @@ var useMenu = (options = {}) => {
84
84
  return {
85
85
  collectionId,
86
86
  element,
87
+ /**
88
+ * The empty slot is a disabled item of the menu, not a bare wrapper inside it.
89
+ *
90
+ * `role="menu"` may only own `menuitem`, `menuitemradio`, `menuitemcheckbox` or `group`, and
91
+ * the empty state's content is the caller's, carrying no role at all. A `presentation` wrapper
92
+ * does not help: it flattens out of the tree, so what the menu ends up owning is that content
93
+ * — which is why the virtualizer's `presentation` wrapper is fine and this one was not. It
94
+ * holds real items; this holds prose.
95
+ *
96
+ * Measured against axe: `presentation`, `none`, `status`, `group` alone and a bare `div` all
97
+ * fail, while a disabled `menuitem` passes — and so does a menu with no children whatsoever. It
98
+ * is the unallowed child that breaks it rather than the missing item.
99
+ *
100
+ * A disabled item is also the truer reading. The menu still is a menu, it has one thing in it,
101
+ * and that thing says there is nothing to choose and cannot be chosen. It never registers with
102
+ * the collection, so the keyboard never reaches it either.
103
+ */
104
+ emptyAttributes: computed(() => ({
105
+ "aria-disabled": true,
106
+ role: "menuitem"
107
+ })),
87
108
  isEmpty: computed(() => collection.size.value === 0),
88
109
  menuAttributes: computed(() => ({
110
+ "aria-label": toValue(options.label),
89
111
  "aria-labelledby": toValue(options.labelledBy),
90
112
  "data-collection": collectionId.value,
91
113
  "data-empty": collection.size.value === 0 ? "true" : void 0,
@@ -128,7 +128,7 @@ var useNumberField = (options = {}) => {
128
128
  setInputValue: state.setInputValue,
129
129
  validate: state.validate
130
130
  });
131
- useFormReset(element, () => state.defaultNumberValue.value, state.setNumberValue);
131
+ useFormReset(element, () => state.defaultNumberValue.value, state.setNumberValue, options.form);
132
132
  /**
133
133
  * Range validation borrowed from a real number input.
134
134
  *
@@ -46,7 +46,7 @@ var useSelect = (options, state) => {
46
46
  sensitivity: "base",
47
47
  usage: "search"
48
48
  });
49
- const getKeyForSearch = (search, fromKey) => {
49
+ const getKeyForSearch = (search, fromKey) => state.collection.withOrder(() => {
50
50
  let key = fromKey ?? state.collection.getFirstKey();
51
51
  while (key != null) {
52
52
  const item = state.collection.getItem(key);
@@ -56,7 +56,7 @@ var useSelect = (options, state) => {
56
56
  key = state.collection.getKeyAfter(key);
57
57
  }
58
58
  return null;
59
- };
59
+ });
60
60
  const typeahead = useTypeahead({
61
61
  focusedKey: () => state.selectedKey.value,
62
62
  getKeyForSearch,
@@ -120,7 +120,6 @@ var useSelect = (options, state) => {
120
120
  "aria-invalid": isInvalid.value || void 0,
121
121
  "aria-label": toValue(options.ariaLabel),
122
122
  "aria-labelledby": [valueId.value, toValue(options.ariaLabelledby) ?? fieldIds.labelId.value].filter(Boolean).join(" "),
123
- "aria-required": toValue(options.isRequired) || void 0,
124
123
  disabled: toValue(options.isDisabled) || void 0,
125
124
  id: trigger.triggerId.value,
126
125
  type: "button"
@@ -73,13 +73,13 @@ var useSelectionManager = (options) => {
73
73
  commit(next);
74
74
  };
75
75
  /** The keys from `from` to `to` inclusive, in document order whichever way round they are. */
76
- const keyRange = (from, to) => {
76
+ const keyRange = (from, to) => collection.withOrder(() => {
77
77
  const keys = collection.orderedKeys();
78
- const start = keys.indexOf(from);
79
- const end = keys.indexOf(to);
78
+ const start = collection.getIndex(from);
79
+ const end = collection.getIndex(to);
80
80
  if (start === -1 || end === -1) return [];
81
81
  return keys.slice(Math.min(start, end), Math.max(start, end) + 1);
82
- };
82
+ });
83
83
  const extendSelection = (key) => {
84
84
  if (selectionMode.value === "none") return;
85
85
  if (selectionMode.value === "single") {
@@ -0,0 +1,37 @@
1
+ import type { CollectionKey, UseCollectionReturn } from "./use-collection.js";
2
+ import type { UseSelectionManagerReturn } from "./use-selection-manager.js";
3
+ import type { ComputedRef, MaybeRefOrGetter } from "vue";
4
+ export interface UseSingleSelectListStateOptions {
5
+ /** The selected item, when the caller drives it. */
6
+ selectedKey?: MaybeRefOrGetter<CollectionKey | undefined>;
7
+ /** The initially selected item. Falls back to the first item that is not disabled. */
8
+ defaultSelectedKey?: CollectionKey;
9
+ onSelectionChange?: (key: CollectionKey) => void;
10
+ disabledKeys?: MaybeRefOrGetter<Iterable<CollectionKey> | undefined>;
11
+ /** Whether the whole list is disabled: a selection that exists but cannot be changed. */
12
+ isDisabled?: MaybeRefOrGetter<boolean | undefined>;
13
+ }
14
+ export interface UseSingleSelectListStateReturn {
15
+ collection: UseCollectionReturn;
16
+ selection: UseSelectionManagerReturn;
17
+ /** The selected item, with the default resolved against the collection. */
18
+ selectedKey: ComputedRef<CollectionKey | null>;
19
+ setSelectedKey: (key: CollectionKey) => void;
20
+ isDisabled: ComputedRef<boolean>;
21
+ }
22
+ /**
23
+ * Which item of a collection is selected, for a list that always has exactly one.
24
+ *
25
+ * Ported from React Stately's `useSingleSelectListState`
26
+ * (`react-stately/src/list/useSingleSelectListState.ts`, react-stately 3.49.0).
27
+ *
28
+ * "Always exactly one" is `disallowEmptySelection` plus a fallback for the case where nothing says
29
+ * which. The selection behaviour is deliberately left at toggle: whether the arrow keys choose is a
30
+ * question about how activation works, asked by the caller through `selectOnFocus`, not a question
31
+ * about what a press means.
32
+ *
33
+ * The three pieces have to be built in one order — the collection, then the fallback that reads it,
34
+ * then the selection manager the fallback feeds — which is the reason this is a composable rather
35
+ * than a few lines in the root component.
36
+ */
37
+ export declare const useSingleSelectListState: (options?: UseSingleSelectListStateOptions) => UseSingleSelectListStateReturn;
@@ -0,0 +1,110 @@
1
+ import { useControllableState } from "./use-controllable-state.js";
2
+ import { useCollection } from "./use-collection.js";
3
+ import { useSelectionManager } from "./use-selection-manager.js";
4
+ import { computed, toValue, watch } from "vue";
5
+ //#region src/composables/use-single-select-list-state.ts
6
+ /**
7
+ * Which item of a collection is selected, for a list that always has exactly one.
8
+ *
9
+ * Ported from React Stately's `useSingleSelectListState`
10
+ * (`react-stately/src/list/useSingleSelectListState.ts`, react-stately 3.49.0).
11
+ *
12
+ * "Always exactly one" is `disallowEmptySelection` plus a fallback for the case where nothing says
13
+ * which. The selection behaviour is deliberately left at toggle: whether the arrow keys choose is a
14
+ * question about how activation works, asked by the caller through `selectOnFocus`, not a question
15
+ * about what a press means.
16
+ *
17
+ * The three pieces have to be built in one order — the collection, then the fallback that reads it,
18
+ * then the selection manager the fallback feeds — which is the reason this is a composable rather
19
+ * than a few lines in the root component.
20
+ */
21
+ var useSingleSelectListState = (options = {}) => {
22
+ const collection = useCollection();
23
+ const disabledKeySet = computed(() => new Set(toValue(options.disabledKeys) ?? []));
24
+ /**
25
+ * Whether an item can be selected, asked of the collection rather than of the selection manager.
26
+ *
27
+ * Two reasons, and either alone would be enough: the fallback below runs before the manager
28
+ * exists, and React Stately asks the same question the same way — an item's own disabled state
29
+ * or the group's disabled keys, with no `disabledBehavior` in it.
30
+ */
31
+ const isKeyDisabled = (key) => disabledKeySet.value.has(key) || Boolean(collection.getItem(key)?.isDisabled());
32
+ /** The first item that can be selected, or the first item when none of them can. */
33
+ const findDefaultSelectedKey = () => collection.withOrder(() => {
34
+ let key = collection.getFirstKey();
35
+ while (key != null && isKeyDisabled(key) && key !== collection.getLastKey()) key = collection.getKeyAfter(key);
36
+ if (key != null && isKeyDisabled(key) && key === collection.getLastKey()) key = collection.getFirstKey();
37
+ return key;
38
+ });
39
+ const stored = useControllableState({
40
+ defaultValue: options.defaultSelectedKey ?? null,
41
+ onValueChange: (key) => {
42
+ if (key != null) options.onSelectionChange?.(key);
43
+ },
44
+ value: () => toValue(options.selectedKey)
45
+ });
46
+ /**
47
+ * The selected item, with the fallback resolved as a read rather than written back.
48
+ *
49
+ * React Stately can resolve it before the first render, because the collection is built by a
50
+ * pass that runs before it. Rendering is what creates the collection here, so writing the
51
+ * fallback into the selection would report a selection change nobody made, on every mount of
52
+ * every uncontrolled list.
53
+ *
54
+ * `collection.size` is read for its own sake: the fallback walks the collection through
55
+ * calls that stay outside reactivity on purpose, so without it this would resolve against the
56
+ * empty collection of the first render and keep that answer.
57
+ */
58
+ const selectedKey = computed(() => {
59
+ const key = stored.state.value;
60
+ if (stored.isControlled.value) return key ?? null;
61
+ if (key != null && collection.getItem(key)) return key;
62
+ return findDefaultSelectedKey();
63
+ });
64
+ const selection = useSelectionManager({
65
+ collection,
66
+ disabledKeys: () => toValue(options.disabledKeys),
67
+ disallowEmptySelection: true,
68
+ onSelectionChange: (keys) => {
69
+ if (keys === "all") return;
70
+ const [key] = [...keys];
71
+ if (key != null) stored.setState(key);
72
+ },
73
+ selectedKeys: () => selectedKey.value != null ? [selectedKey.value] : [],
74
+ selectionMode: "single"
75
+ });
76
+ let lastSelectedKey = selectedKey.value;
77
+ /**
78
+ * The selection places focus, because on a list like this it is the only thing that can.
79
+ *
80
+ * React Aria's tab list element ends up with no tab index of its own, so the roving index on
81
+ * the selected item is the only way in — and with no focused key nothing inside is tabbable
82
+ * either, which would put the whole list out of the tab order.
83
+ *
84
+ * Post-flush and keyed on the collection's size, because setting a focused key the collection
85
+ * does not hold is refused: the first attempt runs before the items have registered, and the
86
+ * registration is what makes the retry land.
87
+ */
88
+ watch([
89
+ selectedKey,
90
+ collection.size,
91
+ () => selection.focusedKey.value == null
92
+ ], () => {
93
+ const key = selectedKey.value;
94
+ if (key == null) return;
95
+ if (selection.focusedKey.value == null || !selection.isFocused.value && key !== lastSelectedKey) selection.setFocusedKey(key);
96
+ lastSelectedKey = key;
97
+ }, {
98
+ flush: "post",
99
+ immediate: true
100
+ });
101
+ return {
102
+ collection,
103
+ isDisabled: computed(() => Boolean(toValue(options.isDisabled))),
104
+ selectedKey,
105
+ selection,
106
+ setSelectedKey: (key) => stored.setState(key)
107
+ };
108
+ };
109
+ //#endregion
110
+ export { useSingleSelectListState };
@@ -1,7 +1,7 @@
1
+ import { useMove } from "./use-move.js";
1
2
  import { useFormReset } from "./use-form-reset.js";
2
3
  import { setFormValue } from "../utils/form-value.js";
3
4
  import { clamp } from "../utils/number.js";
4
- import { useMove } from "./use-move.js";
5
5
  import { computed, nextTick, onScopeDispose, toValue, watch, watchEffect } from "vue";
6
6
  //#region src/composables/use-slider-thumb.ts
7
7
  /**
@@ -110,7 +110,7 @@ var useSliderThumb = (options) => {
110
110
  nextTick(() => {
111
111
  setFormValue(inputEl.value, String(state.getThumbValue(index.value)));
112
112
  });
113
- });
113
+ }, options.form);
114
114
  watch([inputEl, () => state.getThumbValue(index.value)], ([input, value]) => setFormValue(input, String(value)), {
115
115
  flush: "post",
116
116
  immediate: true
@@ -1,6 +1,6 @@
1
1
  import { setInteractionModality } from "./use-interaction-states.js";
2
- import { clamp } from "../utils/number.js";
3
2
  import { useMove } from "./use-move.js";
3
+ import { clamp } from "../utils/number.js";
4
4
  import { computed, onScopeDispose, toValue } from "vue";
5
5
  //#region src/composables/use-slider.ts
6
6
  /**
@@ -1,45 +1,36 @@
1
- import type { CollectionKey, UseCollectionReturn } from "./use-collection.js";
2
- import type { UseSelectionManagerReturn } from "./use-selection-manager.js";
1
+ import type { CollectionKey } from "./use-collection.js";
2
+ import type { UseSingleSelectListStateOptions, UseSingleSelectListStateReturn } from "./use-single-select-list-state.js";
3
3
  import type { ComputedRef, MaybeRefOrGetter } from "vue";
4
- export interface UseTabListStateOptions {
5
- /** The selected tab, when the caller drives it. */
6
- selectedKey?: MaybeRefOrGetter<CollectionKey | undefined>;
7
- /** The initially selected tab. Falls back to the first tab that is not disabled. */
8
- defaultSelectedKey?: CollectionKey;
9
- onSelectionChange?: (key: CollectionKey) => void;
10
- disabledKeys?: MaybeRefOrGetter<Iterable<CollectionKey> | undefined>;
11
- /** Whether the whole tab list is disabled: a selection that exists but cannot be changed. */
12
- isDisabled?: MaybeRefOrGetter<boolean | undefined>;
4
+ export interface UseTabListStateOptions extends UseSingleSelectListStateOptions {
13
5
  /** A base the tab and panel ids are derived from. Generated when absent. */
14
6
  id?: MaybeRefOrGetter<string | undefined>;
15
7
  }
16
- export interface UseTabListStateReturn {
17
- collection: UseCollectionReturn;
18
- selection: UseSelectionManagerReturn;
19
- /** The selected tab, with the default resolved against the collection. */
20
- selectedKey: ComputedRef<CollectionKey | null>;
21
- setSelectedKey: (key: CollectionKey) => void;
22
- isDisabled: ComputedRef<boolean>;
8
+ export interface UseTabListStateReturn extends UseSingleSelectListStateReturn {
23
9
  /** The tab list's own id, which the tab and panel ids hang off. */
24
10
  tabsId: ComputedRef<string>;
25
11
  /** `undefined` for a key that does not exist, so no attribute points at nothing. */
26
12
  tabId: (key: CollectionKey | null | undefined) => string | undefined;
27
13
  tabPanelId: (key: CollectionKey | null | undefined) => string | undefined;
14
+ /**
15
+ * Whether a panel for this key is in the document.
16
+ *
17
+ * Tabs are usable without panels - driving something rendered elsewhere on the page is a normal
18
+ * arrangement - and a tab that points `aria-controls` at an element that was never rendered is
19
+ * worse than one that points nowhere.
20
+ */
21
+ hasPanel: (key: CollectionKey | null | undefined) => boolean;
22
+ /** Called by a panel while it is mounted. Returns the matching unregister. */
23
+ registerPanel: (key: CollectionKey) => () => void;
28
24
  }
29
25
  /**
30
26
  * Which tab is selected, and the ids that tie each tab to its panel.
31
27
  *
32
- * Ported from React Stately's `useTabListState` and the `useSingleSelectListState` layer beneath
33
- * it (`react-stately/src/tabs/useTabListState.ts`, react-stately 3.49.0), together with the id
34
- * scheme from `react-aria/src/tabs/utils.ts` (react-aria 3.51.0).
28
+ * Ported from React Stately's `useTabListState` (`react-stately/src/tabs/useTabListState.ts`,
29
+ * react-stately 3.49.0), together with the id scheme from `react-aria/src/tabs/utils.ts`
30
+ * (react-aria 3.51.0).
35
31
  *
36
- * A tab list always has exactly one tab selected, which is `disallowEmptySelection` plus a
37
- * fallback for the case where nothing says which. The selection behaviour is deliberately left at
38
- * toggle: whether the arrow keys choose is a question about how activation works, asked by the
39
- * caller through `selectOnFocus`, not a question about what a press means.
40
- *
41
- * The three pieces have to be built in one order — the collection, then the fallback that reads
42
- * it, then the selection manager the fallback feeds — which is the reason this is a composable
43
- * rather than a few lines in the root component.
32
+ * The selection itself is {@link useSingleSelectListState}, the layer React Stately builds this
33
+ * one on. What is left here is what makes a tab list a tab list rather than any other list with
34
+ * one selection: the ids, and the panels they point at.
44
35
  */
45
36
  export declare const useTabListState: (options?: UseTabListStateOptions) => UseTabListStateReturn;
@@ -1,114 +1,35 @@
1
1
  import { useId as useId$1 } from "./use-id.js";
2
- import { useControllableState } from "./use-controllable-state.js";
3
- import { useCollection } from "./use-collection.js";
4
- import { useSelectionManager } from "./use-selection-manager.js";
5
- import { computed, toValue, watch } from "vue";
2
+ import { useSingleSelectListState } from "./use-single-select-list-state.js";
3
+ import { shallowRef, toValue } from "vue";
6
4
  //#region src/composables/use-tab-list-state.ts
7
5
  /**
8
6
  * Which tab is selected, and the ids that tie each tab to its panel.
9
7
  *
10
- * Ported from React Stately's `useTabListState` and the `useSingleSelectListState` layer beneath
11
- * it (`react-stately/src/tabs/useTabListState.ts`, react-stately 3.49.0), together with the id
12
- * scheme from `react-aria/src/tabs/utils.ts` (react-aria 3.51.0).
8
+ * Ported from React Stately's `useTabListState` (`react-stately/src/tabs/useTabListState.ts`,
9
+ * react-stately 3.49.0), together with the id scheme from `react-aria/src/tabs/utils.ts`
10
+ * (react-aria 3.51.0).
13
11
  *
14
- * A tab list always has exactly one tab selected, which is `disallowEmptySelection` plus a
15
- * fallback for the case where nothing says which. The selection behaviour is deliberately left at
16
- * toggle: whether the arrow keys choose is a question about how activation works, asked by the
17
- * caller through `selectOnFocus`, not a question about what a press means.
18
- *
19
- * The three pieces have to be built in one order — the collection, then the fallback that reads
20
- * it, then the selection manager the fallback feeds — which is the reason this is a composable
21
- * rather than a few lines in the root component.
12
+ * The selection itself is {@link useSingleSelectListState}, the layer React Stately builds this
13
+ * one on. What is left here is what makes a tab list a tab list rather than any other list with
14
+ * one selection: the ids, and the panels they point at.
22
15
  */
23
16
  var useTabListState = (options = {}) => {
24
- const collection = useCollection();
25
- const disabledKeySet = computed(() => new Set(toValue(options.disabledKeys) ?? []));
26
- /**
27
- * Whether a tab can be selected, asked of the collection rather than of the selection manager.
28
- *
29
- * Two reasons, and either alone would be enough: the fallback below runs before the manager
30
- * exists, and React Stately asks the same question the same way — an item's own disabled state
31
- * or the group's disabled keys, with no `disabledBehavior` in it.
32
- */
33
- const isKeyDisabled = (key) => disabledKeySet.value.has(key) || Boolean(collection.getItem(key)?.isDisabled());
34
- /** The first tab that can be selected, or the first tab when none of them can. */
35
- const findDefaultSelectedKey = () => {
36
- let key = collection.getFirstKey();
37
- while (key != null && isKeyDisabled(key) && key !== collection.getLastKey()) key = collection.getKeyAfter(key);
38
- if (key != null && isKeyDisabled(key) && key === collection.getLastKey()) key = collection.getFirstKey();
39
- return key;
40
- };
41
- const stored = useControllableState({
42
- defaultValue: options.defaultSelectedKey ?? null,
43
- onValueChange: (key) => {
44
- if (key != null) options.onSelectionChange?.(key);
45
- },
46
- value: () => toValue(options.selectedKey)
47
- });
48
- /**
49
- * The selected tab, with the fallback resolved as a read rather than written back.
50
- *
51
- * React Stately can resolve it before the first render, because the collection is built by a
52
- * pass that runs before it. Rendering is what creates the collection here, so writing the
53
- * fallback into the selection would report a selection change nobody made, on every mount of
54
- * every uncontrolled tab list.
55
- *
56
- * `collection.size` is read for its own sake: the fallback walks the collection through
57
- * calls that stay outside reactivity on purpose, so without it this would resolve against the
58
- * empty collection of the first render and keep that answer.
59
- */
60
- const selectedKey = computed(() => {
61
- const key = stored.state.value;
62
- if (stored.isControlled.value) return key ?? null;
63
- if (key != null && collection.getItem(key)) return key;
64
- return findDefaultSelectedKey();
65
- });
66
- const selection = useSelectionManager({
67
- collection,
68
- disabledKeys: () => toValue(options.disabledKeys),
69
- disallowEmptySelection: true,
70
- onSelectionChange: (keys) => {
71
- if (keys === "all") return;
72
- const [key] = [...keys];
73
- if (key != null) stored.setState(key);
74
- },
75
- selectedKeys: () => selectedKey.value != null ? [selectedKey.value] : [],
76
- selectionMode: "single"
77
- });
78
- let lastSelectedKey = selectedKey.value;
79
- /**
80
- * The selection places focus, because on a tab list it is the only thing that can.
81
- *
82
- * React Aria's tab list element ends up with no tab index of its own, so the roving index on
83
- * the selected tab is the only way in — and with no focused key nothing inside is tabbable
84
- * either, which would put the whole tab list out of the tab order.
85
- *
86
- * Post-flush and keyed on the collection's size, because setting a focused key the collection
87
- * does not hold is refused: the first attempt runs before the tabs have registered, and the
88
- * registration is what makes the retry land.
89
- */
90
- watch([
91
- selectedKey,
92
- collection.size,
93
- () => selection.focusedKey.value == null
94
- ], () => {
95
- const key = selectedKey.value;
96
- if (key == null) return;
97
- if (selection.focusedKey.value == null || !selection.isFocused.value && key !== lastSelectedKey) selection.setFocusedKey(key);
98
- lastSelectedKey = key;
99
- }, {
100
- flush: "post",
101
- immediate: true
102
- });
17
+ const list = useSingleSelectListState(options);
103
18
  const tabsId = useId$1(() => toValue(options.id));
104
19
  /** React Aria strips whitespace out of a string key so the id stays a single token. */
105
20
  const idFor = (key, role) => key == null ? void 0 : `${tabsId.value}-${role}-${String(key).replace(/\s+/g, "")}`;
21
+ const panelKeys = shallowRef(/* @__PURE__ */ new Set());
106
22
  return {
107
- collection,
108
- isDisabled: computed(() => Boolean(toValue(options.isDisabled))),
109
- selectedKey,
110
- selection,
111
- setSelectedKey: (key) => stored.setState(key),
23
+ ...list,
24
+ hasPanel: (key) => key != null && panelKeys.value.has(key),
25
+ registerPanel: (key) => {
26
+ panelKeys.value = new Set(panelKeys.value).add(key);
27
+ return () => {
28
+ const next = new Set(panelKeys.value);
29
+ next.delete(key);
30
+ panelKeys.value = next;
31
+ };
32
+ },
112
33
  tabId: (key) => idFor(key, "tab"),
113
34
  tabPanelId: (key) => idFor(key, "tabpanel"),
114
35
  tabsId
@@ -91,7 +91,7 @@ var useTextField = (options = {}) => {
91
91
  reassert();
92
92
  };
93
93
  const initialValue = value.value;
94
- if (!options.skipFormReset) useFormReset(element, () => toValue(options.defaultValue) ?? initialValue, setState);
94
+ if (!options.skipFormReset) useFormReset(element, () => toValue(options.defaultValue) ?? initialValue, setState, options.form);
95
95
  useFormValidation(element, validation, { commitOnBlur: () => toValue(options.commitOnBlur) });
96
96
  watch(element, (control, previous) => {
97
97
  if (control && !previous && toValue(options.autoFocus)) control.focus();
@@ -1,22 +1,72 @@
1
1
  import type { Size } from "../utils/virtualizer-geometry.js";
2
2
  import type { ComputedRef, MaybeRefOrGetter } from "vue";
3
- import { Rect } from "../utils/virtualizer-geometry.js";
3
+ import { Point, Rect } from "../utils/virtualizer-geometry.js";
4
4
  export interface UseVirtualizerScrollOptions {
5
5
  /** The element that scrolls — the collection itself. */
6
6
  element: MaybeRefOrGetter<HTMLElement | null | undefined>;
7
- /** The size of everything the layout produced, used to clamp an over-scroll. */
7
+ /** The size of everything the layout produced, which is what gives the container its scroll. */
8
8
  contentSize: () => Size;
9
9
  /** Whether the collection is mid-scroll, which the content wrapper turns off pointers for. */
10
10
  isScrolling: () => boolean;
11
11
  onVisibleRectChange: (rect: Rect) => void;
12
12
  onSizeChange: (size: Size) => void;
13
+ /**
14
+ * How far rows measured above the window have pushed the content under it, and a way to say the
15
+ * shift has been applied.
16
+ *
17
+ * Rows of a height nobody declared are placed at an estimate and corrected once they are in the
18
+ * DOM. A correction above the window moves everything below it — so without putting the shift
19
+ * back into the scroll offset, the collection slides under the pointer while it is read.
20
+ */
21
+ scrollAdjustment?: () => number;
22
+ takeScrollAdjustment?: () => number;
13
23
  onScrollStart?: () => void;
14
24
  onScrollEnd?: () => void;
15
25
  }
26
+ /** Where to scroll the container to. An axis left out stays where it is. */
27
+ export interface ScrollToOffset {
28
+ left?: number;
29
+ top?: number;
30
+ }
31
+ /** What the container's own style says about it, as far as a scrollbar drawn for it has to know. */
32
+ export interface ScrollBoxInfo {
33
+ /** Which way the inline axis runs, which decides which edge the content starts at. */
34
+ direction: "ltr" | "rtl";
35
+ /** How far the content sits in from the container's top edge. */
36
+ paddingTop: number;
37
+ /** How far the content sits in from the container's inline start edge. */
38
+ paddingInlineStart: number;
39
+ /** Whether the container scrolls along the inline axis, rather than clipping or letting content out. */
40
+ scrollsX: boolean;
41
+ /** Whether the container scrolls along the block axis. */
42
+ scrollsY: boolean;
43
+ }
16
44
  export interface UseVirtualizerScrollReturn {
17
45
  /** The style for the wrapper that gives the container something to scroll. */
18
46
  contentStyle: ComputedRef<Record<string, string | undefined>>;
19
47
  /** Re-measures the container. Called on mount, on resize, and by tests. */
20
48
  measure: () => void;
49
+ /** The container's padding and which of its axes scroll, read whenever it is measured. */
50
+ scrollBox: ComputedRef<ScrollBoxInfo>;
51
+ /**
52
+ * How far the container is scrolled, as the element reports it.
53
+ *
54
+ * Along the block axis the offset is clamped into the content, as the visible rectangle is.
55
+ * Along the inline axis it keeps its sign: a right-to-left box scrolls into negative offsets,
56
+ * and a scrollbar drawn for it has to know which way the content ran.
57
+ */
58
+ scrollOffset: ComputedRef<Point>;
59
+ /** The container's scrollable overflow, per axis — what the offset runs up to, less the box. */
60
+ scrollSize: ComputedRef<Size>;
61
+ /**
62
+ * Scrolls the container from here, and moves the window in the same task.
63
+ *
64
+ * A scroll the browser makes on its own reaches this composable a frame after the offset moved,
65
+ * and the compositor has already drawn that frame with the rows built for the old offset. A
66
+ * scroll made here is read back at once, so the offset and the rows it calls for are committed
67
+ * by the same frame — which is what lets a scrollbar the collection draws itself never show an
68
+ * empty window.
69
+ */
70
+ scrollTo: (offset: ScrollToOffset) => void;
21
71
  }
22
72
  export declare const useVirtualizerScroll: (options: UseVirtualizerScrollOptions) => UseVirtualizerScrollReturn;