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.
- package/dist/components/autocomplete/autocomplete-root.js +3 -1
- package/dist/components/autocomplete/index.d.ts +3 -0
- package/dist/components/avatar/avatar-image.js +13 -2
- package/dist/components/avatar/avatar.types.d.ts +7 -1
- package/dist/components/breadcrumbs/breadcrumbs-item.js +1 -0
- package/dist/components/breadcrumbs/index.d.ts +1 -0
- package/dist/components/calendar/calendar-header.js +1 -1
- package/dist/components/calendar/index.d.ts +5 -3
- package/dist/components/calendar-year-picker/index.d.ts +4 -2
- package/dist/components/checkbox/checkbox-content.js +1 -1
- package/dist/components/color-field/index.d.ts +3 -2
- package/dist/components/color-input-group/color-input-group-root.js +2 -0
- package/dist/components/color-input-group/color-input-group.types.d.ts +2 -0
- package/dist/components/color-input-group/index.d.ts +2 -0
- package/dist/components/combo-box/combo-box-root.js +9 -2
- package/dist/components/combo-box/combo-box.types.d.ts +3 -0
- package/dist/components/combo-box/index.d.ts +3 -0
- package/dist/components/date-field/index.d.ts +1 -0
- package/dist/components/date-input-group/date-input-group-root.js +2 -0
- package/dist/components/date-input-group/date-input-group-segment.js +1 -1
- package/dist/components/date-input-group/date-input-group.types.d.ts +2 -0
- package/dist/{composables → components/date-input-group}/use-date-segment.d.ts +2 -2
- package/dist/{composables → components/date-input-group}/use-date-segment.js +9 -9
- package/dist/components/date-picker/index.d.ts +3 -2
- package/dist/components/date-picker/index.js +2 -2
- package/dist/components/date-range-picker/date-range-picker-root.js +1 -1
- package/dist/components/date-range-picker/index.d.ts +18 -16
- package/dist/components/date-range-picker/index.js +2 -2
- package/dist/{composables → components/date-range-picker}/use-date-range-picker.d.ts +7 -7
- package/dist/{composables → components/date-range-picker}/use-date-range-picker.js +10 -10
- package/dist/components/drawer/drawer-dialog.js +1 -1
- package/dist/{composables → components/drawer}/use-drawer-drag.d.ts +1 -1
- package/dist/{composables → components/drawer}/use-drawer-drag.js +1 -1
- package/dist/components/dropdown/dropdown-menu.js +3 -1
- package/dist/components/dropdown/dropdown-submenu-trigger.js +1 -1
- package/dist/components/dropdown/dropdown.types.d.ts +3 -3
- package/dist/components/dropdown/index.d.ts +4 -2
- package/dist/{composables → components/dropdown}/use-safely-mouse-to-submenu.js +1 -1
- package/dist/components/icons/icon-overlay-arrow.js +1 -1
- package/dist/components/index.d.ts +5 -0
- package/dist/components/input/index.d.ts +12 -4
- package/dist/components/input/input-root.d.ts +5 -2
- package/dist/components/input/input-root.js +46 -5
- package/dist/components/input/input.types.d.ts +11 -0
- package/dist/components/input-group/index.d.ts +2 -0
- package/dist/components/input-group/input-group-root.js +3 -0
- package/dist/components/input-group/input-group.types.d.ts +5 -0
- package/dist/components/input-otp/index.d.ts +6 -4
- package/dist/components/link/index.d.ts +2 -0
- package/dist/components/link/link-root.js +22 -5
- package/dist/components/link/link.types.d.ts +14 -3
- package/dist/{composables → components/list-box}/drag-collection.d.ts +2 -2
- package/dist/{composables → components/list-box}/drag-collection.js +1 -1
- package/dist/components/list-box/index.d.ts +4 -0
- package/dist/components/list-box/list-box-root.js +60 -35
- package/dist/components/list-box/list-box.types.d.ts +2 -0
- package/dist/components/menu/index.d.ts +4 -0
- package/dist/components/menu/menu-root.js +9 -2
- package/dist/components/menu/menu.types.d.ts +5 -0
- package/dist/components/number-field/index.d.ts +3 -0
- package/dist/components/number-field/number-field-root.js +2 -0
- package/dist/components/number-field/number-field.types.d.ts +2 -0
- package/dist/components/overlay/overlay-arrow.js +64 -11
- package/dist/components/pagination/index.d.ts +2 -0
- package/dist/components/pagination/pagination-root.js +8 -3
- package/dist/components/pagination/pagination.types.d.ts +8 -0
- package/dist/components/popover/popover-trigger.js +14 -7
- package/dist/components/radio/radio-content.js +1 -1
- package/dist/components/range-calendar/index.d.ts +18 -15
- package/dist/components/range-calendar/range-calendar-header.js +1 -1
- package/dist/components/router-provider/index.d.ts +5 -0
- package/dist/components/router-provider/index.js +3 -0
- package/dist/components/router-provider/router-provider.context.d.ts +40 -0
- package/dist/components/router-provider/router-provider.context.js +16 -0
- package/dist/components/router-provider/router-provider.d.ts +21 -0
- package/dist/components/router-provider/router-provider.js +22 -0
- package/dist/components/router-provider/router-provider.types.d.ts +23 -0
- package/dist/components/scroll-shadow/scroll-shadow-root.js +7 -1
- package/dist/components/scroll-shadow/use-scroll-shadow.js +25 -1
- package/dist/components/search-field/index.d.ts +2 -0
- package/dist/components/search-field/search-field-root.js +3 -1
- package/dist/components/search-field/search-field.types.d.ts +2 -0
- package/dist/{composables → components/search-field}/use-search-field.d.ts +2 -2
- package/dist/{composables → components/search-field}/use-search-field.js +3 -3
- package/dist/components/segmented-control/index.d.ts +134 -0
- package/dist/components/segmented-control/index.js +15 -0
- package/dist/components/segmented-control/segmented-control-indicator.d.ts +19 -0
- package/dist/components/segmented-control/segmented-control-indicator.js +36 -0
- package/dist/components/segmented-control/segmented-control-item.d.ts +21 -0
- package/dist/components/segmented-control/segmented-control-item.js +96 -0
- package/dist/components/segmented-control/segmented-control-root.d.ts +25 -0
- package/dist/components/segmented-control/segmented-control-root.js +112 -0
- package/dist/components/segmented-control/segmented-control-separator.d.ts +19 -0
- package/dist/components/segmented-control/segmented-control-separator.js +18 -0
- package/dist/components/segmented-control/segmented-control.context.d.ts +17 -0
- package/dist/components/segmented-control/segmented-control.context.js +12 -0
- package/dist/components/segmented-control/segmented-control.types.d.ts +67 -0
- package/dist/components/select/index.d.ts +3 -0
- package/dist/components/select/select-hidden-select.js +1 -1
- package/dist/components/select/select-root.js +2 -0
- package/dist/components/select/select.types.d.ts +2 -0
- package/dist/components/separator/separator-root.js +11 -5
- package/dist/components/separator/separator.context.d.ts +7 -0
- package/dist/components/sidebar/index.d.ts +544 -0
- package/dist/components/sidebar/index.js +47 -0
- package/dist/components/sidebar/sidebar-collapsible-trigger.d.ts +21 -0
- package/dist/components/sidebar/sidebar-collapsible-trigger.js +70 -0
- package/dist/components/sidebar/sidebar-collapsible.d.ts +24 -0
- package/dist/components/sidebar/sidebar-collapsible.js +78 -0
- package/dist/components/sidebar/sidebar-content.d.ts +21 -0
- package/dist/components/sidebar/sidebar-content.js +37 -0
- package/dist/components/sidebar/sidebar-footer.d.ts +21 -0
- package/dist/components/sidebar/sidebar-footer.js +24 -0
- package/dist/components/sidebar/sidebar-group-label.d.ts +21 -0
- package/dist/components/sidebar/sidebar-group-label.js +32 -0
- package/dist/components/sidebar/sidebar-group.d.ts +21 -0
- package/dist/components/sidebar/sidebar-group.js +48 -0
- package/dist/components/sidebar/sidebar-header.d.ts +21 -0
- package/dist/components/sidebar/sidebar-header.js +24 -0
- package/dist/components/sidebar/sidebar-inset.d.ts +21 -0
- package/dist/components/sidebar/sidebar-inset.js +24 -0
- package/dist/components/sidebar/sidebar-item-icon.d.ts +21 -0
- package/dist/components/sidebar/sidebar-item-icon.js +20 -0
- package/dist/components/sidebar/sidebar-item-indicator.d.ts +21 -0
- package/dist/components/sidebar/sidebar-item-indicator.js +48 -0
- package/dist/components/sidebar/sidebar-item-label.d.ts +21 -0
- package/dist/components/sidebar/sidebar-item-label.js +28 -0
- package/dist/components/sidebar/sidebar-item-tooltip.d.ts +21 -0
- package/dist/components/sidebar/sidebar-item-tooltip.js +38 -0
- package/dist/components/sidebar/sidebar-item-trailing.d.ts +21 -0
- package/dist/components/sidebar/sidebar-item-trailing.js +28 -0
- package/dist/components/sidebar/sidebar-item.d.ts +23 -0
- package/dist/components/sidebar/sidebar-item.js +160 -0
- package/dist/components/sidebar/sidebar-panel.d.ts +21 -0
- package/dist/components/sidebar/sidebar-panel.js +88 -0
- package/dist/components/sidebar/sidebar-rail.d.ts +21 -0
- package/dist/components/sidebar/sidebar-rail.js +210 -0
- package/dist/components/sidebar/sidebar-root.d.ts +31 -0
- package/dist/components/sidebar/sidebar-root.js +138 -0
- package/dist/components/sidebar/sidebar-separator.d.ts +19 -0
- package/dist/components/sidebar/sidebar-separator.js +16 -0
- package/dist/components/sidebar/sidebar-sub-menu.d.ts +23 -0
- package/dist/components/sidebar/sidebar-sub-menu.js +40 -0
- package/dist/components/sidebar/sidebar-trigger.d.ts +21 -0
- package/dist/components/sidebar/sidebar-trigger.js +69 -0
- package/dist/components/sidebar/sidebar.context.d.ts +75 -0
- package/dist/components/sidebar/sidebar.context.js +30 -0
- package/dist/components/sidebar/sidebar.state.d.ts +73 -0
- package/dist/components/sidebar/sidebar.state.js +76 -0
- package/dist/components/sidebar/sidebar.storage.d.ts +8 -0
- package/dist/components/sidebar/sidebar.storage.js +45 -0
- package/dist/components/sidebar/sidebar.types.d.ts +259 -0
- package/dist/components/splitter/index.d.ts +143 -0
- package/dist/components/splitter/index.js +13 -0
- package/dist/components/splitter/splitter-handle.d.ts +21 -0
- package/dist/components/splitter/splitter-handle.js +209 -0
- package/dist/components/splitter/splitter-panel.d.ts +21 -0
- package/dist/components/splitter/splitter-panel.js +70 -0
- package/dist/components/splitter/splitter-root.d.ts +31 -0
- package/dist/components/splitter/splitter-root.js +152 -0
- package/dist/components/splitter/splitter.context.d.ts +15 -0
- package/dist/components/splitter/splitter.context.js +5 -0
- package/dist/components/splitter/splitter.state.d.ts +87 -0
- package/dist/components/splitter/splitter.state.js +322 -0
- package/dist/components/splitter/splitter.storage.d.ts +15 -0
- package/dist/components/splitter/splitter.storage.js +56 -0
- package/dist/components/splitter/splitter.types.d.ts +98 -0
- package/dist/components/switch/switch-content.js +1 -1
- package/dist/components/table/index.d.ts +10 -9
- package/dist/components/table/table-body.js +13 -13
- package/dist/components/table/table-cell.js +49 -46
- package/dist/components/table/table-column-resizer.js +1 -1
- package/dist/components/table/table-column.js +1 -1
- package/dist/components/table/table-content.js +37 -18
- package/dist/{composables → components/table}/table-drag-collection.d.ts +1 -1
- package/dist/{composables → components/table}/table-drag-collection.js +1 -1
- package/dist/components/table/table-drop-indicator.js +3 -1
- package/dist/components/table/table-resizable-container.d.ts +4 -5
- package/dist/components/table/table-row.js +45 -14
- package/dist/components/table/table-virtualizer-item.d.ts +2 -7
- package/dist/components/table/table-virtualizer-item.js +20 -9
- package/dist/components/table/table.context.d.ts +11 -3
- package/dist/components/table/table.types.d.ts +1 -1
- package/dist/{composables → components/table}/use-grid-keyboard.d.ts +3 -3
- package/dist/{composables → components/table}/use-grid-keyboard.js +57 -55
- package/dist/{composables → components/table}/use-grid-selection-announcement.d.ts +2 -2
- package/dist/{composables → components/table}/use-grid-selection-announcement.js +2 -2
- package/dist/{composables → components/table}/use-table-collection.d.ts +2 -2
- package/dist/{composables → components/table}/use-table-collection.js +4 -4
- package/dist/{composables → components/table}/use-table-column-layout.d.ts +13 -20
- package/dist/components/table/use-table-column-layout.js +115 -0
- package/dist/components/tabs/tabs-panel.js +5 -1
- package/dist/components/tabs/tabs-tab.js +1 -1
- package/dist/components/textarea/index.d.ts +12 -4
- package/dist/components/textarea/textarea-root.d.ts +5 -2
- package/dist/components/textarea/textarea-root.js +40 -5
- package/dist/components/textarea/textarea.types.d.ts +11 -0
- package/dist/components/textfield/index.d.ts +2 -0
- package/dist/components/textfield/textfield-root.js +5 -1
- package/dist/components/textfield/textfield.context.d.ts +2 -0
- package/dist/components/textfield/textfield.types.d.ts +5 -0
- package/dist/components/time-field/index.d.ts +1 -0
- package/dist/components/toast/index.d.ts +1 -0
- package/dist/components/toast/toast-default-content.js +1 -1
- package/dist/components/toggle-button-group/toggle-button-group-root.js +3 -3
- package/dist/components/toolbar/index.d.ts +3 -2
- package/dist/components/toolbar/toolbar-root.js +3 -3
- package/dist/components/tooltip/index.js +1 -1
- package/dist/components/tooltip/tooltip-root.js +1 -1
- package/dist/components/tooltip/tooltip-trigger.js +13 -5
- package/dist/components/virtualizer/index.d.ts +3 -1
- package/dist/components/virtualizer/index.js +2 -1
- package/dist/components/virtualizer/use-virtualizer-item.d.ts +23 -0
- package/dist/components/virtualizer/use-virtualizer-item.js +45 -0
- package/dist/components/virtualizer/virtualizer-item.js +7 -41
- package/dist/components/virtualizer/virtualizer-scrollbar-track.d.ts +20 -0
- package/dist/components/virtualizer/virtualizer-scrollbar-track.js +141 -0
- package/dist/components/virtualizer/virtualizer-scrollbar.d.ts +18 -0
- package/dist/components/virtualizer/virtualizer-scrollbar.js +55 -0
- package/dist/components/virtualizer/virtualizer.context.d.ts +17 -1
- package/dist/composables/drag-manager.js +1 -13
- package/dist/composables/index.d.ts +3 -71
- package/dist/composables/use-collection.d.ts +22 -3
- package/dist/composables/use-collection.js +67 -14
- package/dist/composables/use-color-area.js +2 -2
- package/dist/composables/use-color-field.js +1 -1
- package/dist/composables/use-combo-box.js +1 -1
- package/dist/composables/use-date-field.js +1 -1
- package/dist/composables/use-drag-and-drop.js +1 -1
- package/dist/composables/use-drag.d.ts +6 -5
- package/dist/composables/use-draggable-item.d.ts +2 -2
- package/dist/composables/use-droppable-collection.js +2 -2
- package/dist/composables/use-droppable-item.js +1 -1
- package/dist/composables/use-form-reset.d.ts +6 -2
- package/dist/composables/use-form-reset.js +9 -5
- package/dist/composables/use-list-keyboard.js +64 -62
- package/dist/composables/use-menu.d.ts +10 -0
- package/dist/composables/use-menu.js +22 -0
- package/dist/composables/use-number-field.js +1 -1
- package/dist/composables/use-select.js +2 -3
- package/dist/composables/use-selection-manager.js +4 -4
- package/dist/composables/use-single-select-list-state.d.ts +37 -0
- package/dist/composables/use-single-select-list-state.js +110 -0
- package/dist/composables/use-slider-thumb.js +2 -2
- package/dist/composables/use-slider.js +1 -1
- package/dist/composables/use-tab-list-state.d.ts +20 -29
- package/dist/composables/use-tab-list-state.js +20 -99
- package/dist/composables/use-text-field.js +1 -1
- package/dist/composables/use-virtualizer-scroll.d.ts +52 -2
- package/dist/composables/use-virtualizer-scroll.js +79 -13
- package/dist/composables/use-virtualizer.d.ts +24 -4
- package/dist/composables/use-virtualizer.js +40 -6
- package/dist/index.js +58 -80
- package/dist/utils/document-order.d.ts +14 -0
- package/dist/utils/document-order.js +17 -0
- package/dist/utils/flex-sizing.d.ts +41 -0
- package/dist/utils/flex-sizing.js +140 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/open-link.d.ts +31 -0
- package/dist/utils/open-link.js +32 -0
- package/dist/utils/story-truncation.d.ts +20 -0
- package/dist/utils/story-users.d.ts +11 -0
- package/dist/utils/virtualizer-collection.d.ts +14 -4
- package/dist/utils/virtualizer-collection.js +9 -14
- package/dist/utils/virtualizer-layout-info.js +3 -2
- package/dist/utils/virtualizer-list-layout.d.ts +75 -29
- package/dist/utils/virtualizer-list-layout.js +182 -99
- package/dist/utils/virtualizer-offsets.d.ts +111 -0
- package/dist/utils/virtualizer-offsets.js +159 -0
- package/dist/utils/virtualizer-overscan.d.ts +9 -15
- package/dist/utils/virtualizer-overscan.js +14 -33
- package/dist/utils/virtualizer-table-layout.d.ts +50 -21
- package/dist/utils/virtualizer-table-layout.js +130 -89
- package/dist/version.js +1 -1
- package/package.json +19 -3
- package/dist/composables/use-table-column-layout.js +0 -214
- /package/dist/{composables → components/dropdown}/use-safely-mouse-to-submenu.d.ts +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Point, Rect, Size } from "../utils/virtualizer-geometry.js";
|
|
2
|
-
import { computed, onScopeDispose, toValue, watch } from "vue";
|
|
2
|
+
import { computed, onScopeDispose, shallowRef, toValue, watch } from "vue";
|
|
3
3
|
//#region src/composables/use-virtualizer-scroll.ts
|
|
4
4
|
/**
|
|
5
5
|
* Measuring the scroll container a virtualizer lives in, ported from React Aria's `useScrollView`.
|
|
@@ -30,8 +30,44 @@ var useVirtualizerScroll = (options) => {
|
|
|
30
30
|
viewportOffset: new Point(),
|
|
31
31
|
viewportSize: new Size()
|
|
32
32
|
};
|
|
33
|
+
const scrollOffset = shallowRef(new Point());
|
|
34
|
+
const scrollSize = shallowRef(new Size());
|
|
35
|
+
const scrollBox = shallowRef({
|
|
36
|
+
direction: "ltr",
|
|
37
|
+
paddingInlineStart: 0,
|
|
38
|
+
paddingTop: 0,
|
|
39
|
+
scrollsX: false,
|
|
40
|
+
scrollsY: false
|
|
41
|
+
});
|
|
33
42
|
let isMeasuring = false;
|
|
34
43
|
const getElement = () => toValue(options.element) ?? null;
|
|
44
|
+
/** Whether an overflow value is one the browser scrolls, rather than clips or lets out. */
|
|
45
|
+
const scrolls = (overflow) => overflow === "auto" || overflow === "scroll" || overflow === "overlay";
|
|
46
|
+
/** Reads what the container's style says about it, for the scrollbar drawn against it. */
|
|
47
|
+
const readBox = (element) => {
|
|
48
|
+
const style = getComputedStyle(element);
|
|
49
|
+
const next = {
|
|
50
|
+
direction: style.direction === "rtl" ? "rtl" : "ltr",
|
|
51
|
+
paddingInlineStart: Number.parseFloat(style.paddingInlineStart) || 0,
|
|
52
|
+
paddingTop: Number.parseFloat(style.paddingTop) || 0,
|
|
53
|
+
scrollsX: scrolls(style.overflowX),
|
|
54
|
+
scrollsY: scrolls(style.overflowY)
|
|
55
|
+
};
|
|
56
|
+
const current = scrollBox.value;
|
|
57
|
+
if (current.direction !== next.direction || current.paddingInlineStart !== next.paddingInlineStart || current.paddingTop !== next.paddingTop || current.scrollsX !== next.scrollsX || current.scrollsY !== next.scrollsY) scrollBox.value = next;
|
|
58
|
+
};
|
|
59
|
+
/** Reads where the element is scrolled to, and how far it could go. */
|
|
60
|
+
const readScroll = (element) => {
|
|
61
|
+
const scrollWidth = element.scrollWidth;
|
|
62
|
+
const scrollHeight = element.scrollHeight;
|
|
63
|
+
const left = element.scrollLeft;
|
|
64
|
+
const top = element.scrollTop;
|
|
65
|
+
state.scrollPosition = new Point(Math.max(0, Math.min(left, scrollWidth - state.size.width)), Math.max(0, Math.min(top, scrollHeight - state.size.height)));
|
|
66
|
+
if (scrollSize.value.width !== scrollWidth || scrollSize.value.height !== scrollHeight) scrollSize.value = new Size(scrollWidth, scrollHeight);
|
|
67
|
+
const inlineRange = Math.max(0, scrollWidth - state.size.width);
|
|
68
|
+
const offset = new Point(Math.sign(left) * Math.min(Math.abs(left), inlineRange), state.scrollPosition.y);
|
|
69
|
+
if (!scrollOffset.value.equals(offset)) scrollOffset.value = offset;
|
|
70
|
+
};
|
|
35
71
|
const updateVisibleRect = () => {
|
|
36
72
|
const visibleRect = new Rect(state.viewportOffset.x + state.scrollPosition.x, state.viewportOffset.y + state.scrollPosition.y, Math.max(0, Math.min(state.size.width - state.viewportOffset.x, state.viewportSize.width)), Math.max(0, Math.min(state.size.height - state.viewportOffset.y, state.viewportSize.height)));
|
|
37
73
|
if (visibleRect.area > 0 || state.lastVisibleRect.area > 0) {
|
|
@@ -51,14 +87,19 @@ var useVirtualizerScroll = (options) => {
|
|
|
51
87
|
if (state.scrollTimeout != null) clearTimeout(state.scrollTimeout);
|
|
52
88
|
state.scrollTimeout = setTimeout(endScrolling, SCROLL_END_DELAY);
|
|
53
89
|
};
|
|
90
|
+
const markScrolling = () => {
|
|
91
|
+
if (!state.isScrolling) {
|
|
92
|
+
state.isScrolling = true;
|
|
93
|
+
options.onScrollStart?.();
|
|
94
|
+
}
|
|
95
|
+
scheduleScrollEnd();
|
|
96
|
+
};
|
|
54
97
|
const onScroll = (event) => {
|
|
55
98
|
const element = getElement();
|
|
56
99
|
const target = event.target;
|
|
57
100
|
if (!element || !(target instanceof Node) || !target.contains(element)) return;
|
|
58
|
-
if (target === element)
|
|
59
|
-
|
|
60
|
-
state.scrollPosition = new Point(Math.max(0, Math.min(element.scrollLeft, contentSize.width - state.size.width)), Math.max(0, Math.min(element.scrollTop, contentSize.height - state.size.height)));
|
|
61
|
-
} else {
|
|
101
|
+
if (target === element) readScroll(element);
|
|
102
|
+
else {
|
|
62
103
|
const bounds = element.getBoundingClientRect();
|
|
63
104
|
const x = bounds.x < 0 ? -bounds.x : 0;
|
|
64
105
|
const y = bounds.y < 0 ? -bounds.y : 0;
|
|
@@ -66,11 +107,16 @@ var useVirtualizerScroll = (options) => {
|
|
|
66
107
|
state.viewportOffset = new Point(x, y);
|
|
67
108
|
}
|
|
68
109
|
updateVisibleRect();
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
110
|
+
markScrolling();
|
|
111
|
+
};
|
|
112
|
+
const scrollTo = (offset) => {
|
|
113
|
+
const element = getElement();
|
|
114
|
+
if (!element) return;
|
|
115
|
+
if (offset.left != null) element.scrollLeft = offset.left;
|
|
116
|
+
if (offset.top != null) element.scrollTop = offset.top;
|
|
117
|
+
readScroll(element);
|
|
118
|
+
updateVisibleRect();
|
|
119
|
+
markScrolling();
|
|
74
120
|
};
|
|
75
121
|
/**
|
|
76
122
|
* Re-measures the container.
|
|
@@ -87,14 +133,17 @@ var useVirtualizerScroll = (options) => {
|
|
|
87
133
|
const viewportHeight = window.innerHeight;
|
|
88
134
|
const viewportChanged = state.viewportSize.width !== viewportWidth || state.viewportSize.height !== viewportHeight;
|
|
89
135
|
if (viewportChanged) state.viewportSize = new Size(viewportWidth, viewportHeight);
|
|
136
|
+
readBox(element);
|
|
90
137
|
const clientWidth = element.clientWidth;
|
|
91
138
|
const clientHeight = element.clientHeight;
|
|
92
139
|
if (state.size.width !== clientWidth || state.size.height !== clientHeight || viewportChanged) {
|
|
93
140
|
state.size = new Size(clientWidth, clientHeight);
|
|
141
|
+
readScroll(element);
|
|
94
142
|
updateVisibleRect();
|
|
95
143
|
options.onSizeChange(state.size);
|
|
96
144
|
if (element.clientWidth !== clientWidth || element.clientHeight !== clientHeight) {
|
|
97
145
|
state.size = new Size(element.clientWidth, element.clientHeight);
|
|
146
|
+
readScroll(element);
|
|
98
147
|
updateVisibleRect();
|
|
99
148
|
options.onSizeChange(state.size);
|
|
100
149
|
}
|
|
@@ -104,13 +153,16 @@ var useVirtualizerScroll = (options) => {
|
|
|
104
153
|
watch(() => getElement(), (element, _previous, onCleanup) => {
|
|
105
154
|
if (!element) return;
|
|
106
155
|
const document = element.ownerDocument;
|
|
107
|
-
document.addEventListener("scroll", onScroll,
|
|
156
|
+
document.addEventListener("scroll", onScroll, {
|
|
157
|
+
capture: true,
|
|
158
|
+
passive: true
|
|
159
|
+
});
|
|
108
160
|
window.addEventListener("resize", measure);
|
|
109
161
|
const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(() => measure());
|
|
110
162
|
observer?.observe(element, { box: "border-box" });
|
|
111
163
|
measure();
|
|
112
164
|
onCleanup(() => {
|
|
113
|
-
document.removeEventListener("scroll", onScroll, true);
|
|
165
|
+
document.removeEventListener("scroll", onScroll, { capture: true });
|
|
114
166
|
window.removeEventListener("resize", measure);
|
|
115
167
|
observer?.disconnect();
|
|
116
168
|
});
|
|
@@ -118,6 +170,16 @@ var useVirtualizerScroll = (options) => {
|
|
|
118
170
|
flush: "post",
|
|
119
171
|
immediate: true
|
|
120
172
|
});
|
|
173
|
+
watch(() => options.contentSize(), () => {
|
|
174
|
+
const element = getElement();
|
|
175
|
+
if (element) readScroll(element);
|
|
176
|
+
}, { flush: "post" });
|
|
177
|
+
watch(() => options.scrollAdjustment?.() ?? 0, (adjustment) => {
|
|
178
|
+
const element = getElement();
|
|
179
|
+
if (!element || adjustment === 0) return;
|
|
180
|
+
options.takeScrollAdjustment?.();
|
|
181
|
+
element.scrollTop += adjustment;
|
|
182
|
+
}, { flush: "post" });
|
|
121
183
|
onScopeDispose(() => {
|
|
122
184
|
if (state.scrollTimeout != null) clearTimeout(state.scrollTimeout);
|
|
123
185
|
});
|
|
@@ -131,7 +193,11 @@ var useVirtualizerScroll = (options) => {
|
|
|
131
193
|
width: px(contentSize.width)
|
|
132
194
|
};
|
|
133
195
|
}),
|
|
134
|
-
measure
|
|
196
|
+
measure,
|
|
197
|
+
scrollBox: computed(() => scrollBox.value),
|
|
198
|
+
scrollOffset: computed(() => scrollOffset.value),
|
|
199
|
+
scrollSize: computed(() => scrollSize.value),
|
|
200
|
+
scrollTo
|
|
135
201
|
};
|
|
136
202
|
};
|
|
137
203
|
//#endregion
|
|
@@ -11,10 +11,12 @@ import { Rect, Size } from "../utils/virtualizer-geometry.js";
|
|
|
11
11
|
*
|
|
12
12
|
* Two pieces of upstream are deliberately gone:
|
|
13
13
|
*
|
|
14
|
-
* `ReusableView`
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* `ReusableView` as a class. Its idea is kept — see {@link VirtualizerView.slot} — because a
|
|
15
|
+
* keyed `v-for` on its own cannot spare a window that moved wholesale: every key in it is new, so
|
|
16
|
+
* every row mounts anew, and a scrollbar dragged across a long collection lands on nothing for as
|
|
17
|
+
* long as the mounting takes. Reordering is not deferred as React defers it: the rendered set is
|
|
18
|
+
* kept in collection order at every moment, which is what a screen reader walks, and moving an
|
|
19
|
+
* element is cheap next to mounting one.
|
|
18
20
|
*
|
|
19
21
|
* The scroll anchor. Upstream calls `UNSTABLE_getScrollAnchorInfo` on the layout, but no layout
|
|
20
22
|
* implements it, so the whole tracker resolves to nothing for every collection in this build.
|
|
@@ -22,6 +24,15 @@ import { Rect, Size } from "../utils/virtualizer-geometry.js";
|
|
|
22
24
|
/** One rendered element: a layout info, what it was built from, and anything nested inside it. */
|
|
23
25
|
export interface VirtualizerView {
|
|
24
26
|
key: VirtualizerKey;
|
|
27
|
+
/**
|
|
28
|
+
* The element this view is rendered into, as a number that outlives the key.
|
|
29
|
+
*
|
|
30
|
+
* A key that leaves the window frees its slot, and the next key to arrive takes it. A collection
|
|
31
|
+
* that keys its rendered items by this rather than by `key` keeps the element and its component
|
|
32
|
+
* when the window moves and changes what they show — which is what makes a window that moved
|
|
33
|
+
* wholesale cost a screenful of updates rather than a screenful of mounts.
|
|
34
|
+
*/
|
|
35
|
+
slot: number;
|
|
25
36
|
layoutInfo: LayoutInfo;
|
|
26
37
|
parentKey: VirtualizerKey | null;
|
|
27
38
|
node?: VirtualizerNode;
|
|
@@ -48,6 +59,15 @@ export interface UseVirtualizerReturn {
|
|
|
48
59
|
endScrolling: () => void;
|
|
49
60
|
/** Records a measured size, and lays out again when it moved anything. */
|
|
50
61
|
updateItemSize: (key: VirtualizerKey, size: Size) => void;
|
|
62
|
+
/**
|
|
63
|
+
* How far the content under the window has been pushed by rows measured above it.
|
|
64
|
+
*
|
|
65
|
+
* Adding this to the scroll offset is what holds the collection still while the rows above it
|
|
66
|
+
* settle. Nothing here applies it — only whoever owns the scrolling element can.
|
|
67
|
+
*/
|
|
68
|
+
scrollAdjustment: ComputedRef<number>;
|
|
69
|
+
/** Reads the accumulated shift and clears it, so it is applied once. */
|
|
70
|
+
takeScrollAdjustment: () => number;
|
|
51
71
|
getLayoutInfo: (key: VirtualizerKey) => LayoutInfo | null;
|
|
52
72
|
isPersistedKey: (key: VirtualizerKey) => boolean;
|
|
53
73
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Rect, Size } from "../utils/virtualizer-geometry.js";
|
|
2
|
-
import {
|
|
2
|
+
import { overscannedRect } from "../utils/virtualizer-overscan.js";
|
|
3
3
|
import { computed, shallowRef } from "vue";
|
|
4
4
|
//#region src/composables/use-virtualizer.ts
|
|
5
5
|
var useVirtualizer = (options) => {
|
|
@@ -8,7 +8,7 @@ var useVirtualizer = (options) => {
|
|
|
8
8
|
const isScrolling = shallowRef(false);
|
|
9
9
|
/** Bumped when something outside the reactive inputs invalidates the layout. */
|
|
10
10
|
const revision = shallowRef(0);
|
|
11
|
-
const
|
|
11
|
+
const scrollAdjustment = shallowRef(0);
|
|
12
12
|
const persistedKeys = () => options.persistedKeys?.() ?? /* @__PURE__ */ new Set();
|
|
13
13
|
/**
|
|
14
14
|
* Whether a key, or anything containing it, must stay rendered.
|
|
@@ -91,9 +91,33 @@ var useVirtualizer = (options) => {
|
|
|
91
91
|
return {
|
|
92
92
|
contentSize: layout.getContentSize(),
|
|
93
93
|
layout,
|
|
94
|
-
layoutInfos: layout.getVisibleLayoutInfos(
|
|
94
|
+
layoutInfos: layout.getVisibleLayoutInfos(overscannedRect(rect))
|
|
95
95
|
};
|
|
96
96
|
});
|
|
97
|
+
/** Which slot each key of the last pass held. Plain state: it is history, not something derived. */
|
|
98
|
+
let slotByKey = /* @__PURE__ */ new Map();
|
|
99
|
+
let nextSlot = 0;
|
|
100
|
+
/**
|
|
101
|
+
* Hands every key in the pass a slot, keeping the one it had.
|
|
102
|
+
*
|
|
103
|
+
* The slots of the keys that left are handed out in the order their keys were rendered, to the
|
|
104
|
+
* arriving keys in the order they will be: a window that moved wholesale therefore keeps every
|
|
105
|
+
* slot in place, and a window that moved by a row moves one element.
|
|
106
|
+
*/
|
|
107
|
+
const assignSlots = (layoutInfos) => {
|
|
108
|
+
const next = /* @__PURE__ */ new Map();
|
|
109
|
+
const arriving = [];
|
|
110
|
+
for (const { key } of layoutInfos) {
|
|
111
|
+
const slot = slotByKey.get(key);
|
|
112
|
+
if (slot == null) arriving.push(key);
|
|
113
|
+
else next.set(key, slot);
|
|
114
|
+
}
|
|
115
|
+
const freed = [];
|
|
116
|
+
for (const [key, slot] of slotByKey) if (!next.has(key)) freed.push(slot);
|
|
117
|
+
for (const key of arriving) next.set(key, freed.length > 0 ? freed.shift() : nextSlot++);
|
|
118
|
+
slotByKey = next;
|
|
119
|
+
return next;
|
|
120
|
+
};
|
|
97
121
|
/**
|
|
98
122
|
* The layout infos arrive parents first, so a child always finds its parent already built. One
|
|
99
123
|
* whose parent is not in the window is treated as a root rather than dropped — losing it would
|
|
@@ -104,13 +128,15 @@ var useVirtualizer = (options) => {
|
|
|
104
128
|
const collection = options.collection();
|
|
105
129
|
const views = /* @__PURE__ */ new Map();
|
|
106
130
|
const roots = [];
|
|
131
|
+
const slots = assignSlots(layoutInfos);
|
|
107
132
|
for (const layoutInfo of layoutInfos) {
|
|
108
133
|
const view = {
|
|
109
134
|
children: [],
|
|
110
135
|
key: layoutInfo.key,
|
|
111
136
|
layoutInfo,
|
|
112
137
|
node: collection.getNode(layoutInfo.key),
|
|
113
|
-
parentKey: layoutInfo.parentKey
|
|
138
|
+
parentKey: layoutInfo.parentKey,
|
|
139
|
+
slot: slots.get(layoutInfo.key)
|
|
114
140
|
};
|
|
115
141
|
views.set(view.key, view);
|
|
116
142
|
const parent = layoutInfo.parentKey != null ? views.get(layoutInfo.parentKey) : void 0;
|
|
@@ -127,20 +153,28 @@ var useVirtualizer = (options) => {
|
|
|
127
153
|
getLayoutInfo: (key) => pass.value.layout.getLayoutInfo(key),
|
|
128
154
|
isPersistedKey,
|
|
129
155
|
isScrolling: computed(() => isScrolling.value),
|
|
156
|
+
scrollAdjustment: computed(() => scrollAdjustment.value),
|
|
130
157
|
setSize: (next) => {
|
|
131
158
|
if (!size.value.equals(next)) size.value = next;
|
|
132
159
|
},
|
|
133
160
|
setVisibleRect: (rect) => {
|
|
134
161
|
if (visibleRect.value.equals(rect)) return;
|
|
135
|
-
overscan.setVisibleRect(rect);
|
|
136
162
|
visibleRect.value = rect;
|
|
137
163
|
},
|
|
138
164
|
size: computed(() => size.value),
|
|
139
165
|
startScrolling: () => {
|
|
140
166
|
isScrolling.value = true;
|
|
141
167
|
},
|
|
168
|
+
takeScrollAdjustment: () => {
|
|
169
|
+
const pending = scrollAdjustment.value;
|
|
170
|
+
scrollAdjustment.value = 0;
|
|
171
|
+
return pending;
|
|
172
|
+
},
|
|
142
173
|
updateItemSize: (key, measured) => {
|
|
143
|
-
|
|
174
|
+
const layout = attachedLayout ?? pass.value.layout;
|
|
175
|
+
const placed = layout.getLayoutInfo(key)?.rect;
|
|
176
|
+
if (!layout.updateItemSize?.(key, measured)) return;
|
|
177
|
+
if (placed != null && placed.y < visibleRect.value.y) scrollAdjustment.value += measured.height - placed.height;
|
|
144
178
|
pendingItemSizeChange = true;
|
|
145
179
|
revision.value += 1;
|
|
146
180
|
},
|