@indielayer/ui 1.16.0 → 1.17.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/docs/components/menu/DocsMenu.vue +3 -0
- package/docs/pages/component/infiniteLoader/composable.vue +168 -0
- package/docs/pages/component/infiniteLoader/index.vue +36 -0
- package/docs/pages/component/infiniteLoader/usage.vue +161 -0
- package/docs/pages/component/virtualGrid/index.vue +29 -0
- package/docs/pages/component/virtualGrid/usage.vue +20 -0
- package/docs/pages/component/virtualList/dynamicHeight.vue +75 -0
- package/docs/pages/component/virtualList/index.vue +36 -0
- package/docs/pages/component/virtualList/usage.vue +17 -0
- package/docs/search/components.json +1 -1
- package/lib/components/select/Select.vue.js +35 -35
- package/lib/components/table/Table.vue.js +1 -1
- package/lib/composables/useVirtualList.d.ts +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +88 -76
- package/lib/index.umd.js +4 -4
- package/lib/install.js +15 -7
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/virtual/components/infiniteLoader/InfiniteLoader.test.d.ts +1 -0
- package/lib/virtual/components/infiniteLoader/InfiniteLoader.vue.d.ts +49 -0
- package/lib/virtual/components/infiniteLoader/InfiniteLoader.vue.js +21 -0
- package/lib/virtual/components/infiniteLoader/InfiniteLoader.vue2.js +4 -0
- package/lib/virtual/components/virtualGrid/VirtualGrid.vue.d.ts +185 -0
- package/lib/virtual/components/virtualGrid/VirtualGrid.vue.js +241 -0
- package/lib/virtual/components/virtualGrid/VirtualGrid.vue2.js +4 -0
- package/lib/virtual/components/virtualGrid/types.d.ts +138 -0
- package/lib/virtual/components/virtualList/VirtualList.test.d.ts +1 -0
- package/lib/virtual/components/virtualList/VirtualList.vue.d.ts +135 -0
- package/lib/virtual/components/virtualList/VirtualList.vue.js +157 -0
- package/lib/virtual/components/virtualList/VirtualList.vue2.js +4 -0
- package/lib/virtual/components/virtualList/isDynamicRowHeight.d.ts +2 -0
- package/lib/virtual/components/virtualList/isDynamicRowHeight.js +6 -0
- package/lib/virtual/components/virtualList/types.d.ts +115 -0
- package/lib/virtual/components/virtualList/useDynamicRowHeight.d.ts +7 -0
- package/lib/virtual/components/virtualList/useDynamicRowHeight.js +69 -0
- package/lib/virtual/components/virtualList/useDynamicRowHeight.test.d.ts +1 -0
- package/lib/virtual/composables/infinite-loader/scanForUnloadedIndices.d.ts +8 -0
- package/lib/virtual/composables/infinite-loader/scanForUnloadedIndices.js +41 -0
- package/lib/virtual/composables/infinite-loader/scanForUnloadedIndices.test.d.ts +1 -0
- package/lib/virtual/composables/infinite-loader/types.d.ts +30 -0
- package/lib/virtual/composables/infinite-loader/useInfiniteLoader.d.ts +6 -0
- package/lib/virtual/composables/infinite-loader/useInfiniteLoader.js +42 -0
- package/lib/virtual/composables/infinite-loader/useInfiniteLoader.test.d.ts +1 -0
- package/lib/virtual/core/createCachedBounds.d.ts +6 -0
- package/lib/virtual/core/createCachedBounds.js +55 -0
- package/lib/virtual/core/getEstimatedSize.d.ts +6 -0
- package/lib/virtual/core/getEstimatedSize.js +22 -0
- package/lib/virtual/core/getOffsetForIndex.d.ts +11 -0
- package/lib/virtual/core/getOffsetForIndex.js +40 -0
- package/lib/virtual/core/getStartStopIndices.d.ts +13 -0
- package/lib/virtual/core/getStartStopIndices.js +31 -0
- package/lib/virtual/core/getStartStopIndices.test.d.ts +1 -0
- package/lib/virtual/core/types.d.ts +11 -0
- package/lib/virtual/core/useCachedBounds.d.ts +7 -0
- package/lib/virtual/core/useCachedBounds.js +18 -0
- package/lib/virtual/core/useIsRtl.d.ts +2 -0
- package/lib/virtual/core/useIsRtl.js +15 -0
- package/lib/virtual/core/useItemSize.d.ts +5 -0
- package/lib/virtual/core/useItemSize.js +27 -0
- package/lib/virtual/core/useVirtualizer.d.ts +33 -0
- package/lib/virtual/core/useVirtualizer.js +171 -0
- package/lib/virtual/index.d.ts +9 -0
- package/lib/virtual/test-utils/mockResizeObserver.d.ts +15 -0
- package/lib/virtual/types.d.ts +2 -0
- package/lib/virtual/utils/adjustScrollOffsetForRtl.d.ts +7 -0
- package/lib/virtual/utils/adjustScrollOffsetForRtl.js +24 -0
- package/lib/virtual/utils/areArraysEqual.d.ts +1 -0
- package/lib/virtual/utils/assert.d.ts +1 -0
- package/lib/virtual/utils/assert.js +7 -0
- package/lib/virtual/utils/getRTLOffsetType.d.ts +2 -0
- package/lib/virtual/utils/getRTLOffsetType.js +13 -0
- package/lib/virtual/utils/getScrollbarSize.d.ts +2 -0
- package/lib/virtual/utils/getScrollbarSize.js +11 -0
- package/lib/virtual/utils/isRtl.d.ts +1 -0
- package/lib/virtual/utils/isRtl.js +12 -0
- package/lib/virtual/utils/parseNumericStyleValue.d.ts +2 -0
- package/lib/virtual/utils/parseNumericStyleValue.js +15 -0
- package/lib/virtual/utils/shallowCompare.d.ts +1 -0
- package/lib/virtual/utils/shallowCompare.js +14 -0
- package/package.json +1 -1
- package/src/components/select/Select.vue +3 -2
- package/src/components/table/Table.vue +1 -1
- package/src/composables/useVirtualList.ts +1 -1
- package/src/index.ts +1 -0
- package/src/install.ts +9 -3
- package/src/version.ts +1 -1
- package/src/virtual/README.md +285 -0
- package/src/virtual/components/infiniteLoader/InfiniteLoader.test.ts +96 -0
- package/src/virtual/components/infiniteLoader/InfiniteLoader.vue +18 -0
- package/src/virtual/components/virtualGrid/VirtualGrid.vue +322 -0
- package/src/virtual/components/virtualGrid/types.ts +160 -0
- package/src/virtual/components/virtualList/VirtualList.test.ts +47 -0
- package/src/virtual/components/virtualList/VirtualList.vue +233 -0
- package/src/virtual/components/virtualList/isDynamicRowHeight.ts +13 -0
- package/src/virtual/components/virtualList/types.ts +127 -0
- package/src/virtual/components/virtualList/useDynamicRowHeight.test.ts +183 -0
- package/src/virtual/components/virtualList/useDynamicRowHeight.ts +147 -0
- package/src/virtual/composables/infinite-loader/scanForUnloadedIndices.test.ts +141 -0
- package/src/virtual/composables/infinite-loader/scanForUnloadedIndices.ts +82 -0
- package/src/virtual/composables/infinite-loader/types.ts +36 -0
- package/src/virtual/composables/infinite-loader/useInfiniteLoader.test.ts +236 -0
- package/src/virtual/composables/infinite-loader/useInfiniteLoader.ts +88 -0
- package/src/virtual/core/createCachedBounds.ts +72 -0
- package/src/virtual/core/getEstimatedSize.ts +29 -0
- package/src/virtual/core/getOffsetForIndex.ts +90 -0
- package/src/virtual/core/getStartStopIndices.test.ts +45 -0
- package/src/virtual/core/getStartStopIndices.ts +71 -0
- package/src/virtual/core/types.ts +17 -0
- package/src/virtual/core/useCachedBounds.ts +21 -0
- package/src/virtual/core/useIsRtl.ts +25 -0
- package/src/virtual/core/useItemSize.ts +34 -0
- package/src/virtual/core/useVirtualizer.ts +294 -0
- package/src/virtual/index.ts +25 -0
- package/src/virtual/test-utils/mockResizeObserver.ts +162 -0
- package/src/virtual/types.ts +3 -0
- package/src/virtual/utils/adjustScrollOffsetForRtl.ts +37 -0
- package/src/virtual/utils/areArraysEqual.ts +13 -0
- package/src/virtual/utils/assert.ts +10 -0
- package/src/virtual/utils/getRTLOffsetType.ts +51 -0
- package/src/virtual/utils/getScrollbarSize.ts +24 -0
- package/src/virtual/utils/isRtl.ts +13 -0
- package/src/virtual/utils/parseNumericStyleValue.ts +19 -0
- package/src/virtual/utils/shallowCompare.ts +29 -0
- package/volar.d.ts +3 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { type CSSProperties } from 'vue';
|
|
2
|
+
import type { Align } from '../../types';
|
|
3
|
+
import type { DynamicRowHeight } from './types';
|
|
4
|
+
declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
5
|
+
tag: {
|
|
6
|
+
type: import("vue").PropType<keyof HTMLElementTagNameMap>;
|
|
7
|
+
default: string;
|
|
8
|
+
};
|
|
9
|
+
class: {
|
|
10
|
+
type: import("vue").PropType<string>;
|
|
11
|
+
};
|
|
12
|
+
style: {
|
|
13
|
+
type: import("vue").PropType<CSSProperties>;
|
|
14
|
+
};
|
|
15
|
+
onResize: {
|
|
16
|
+
type: import("vue").PropType<(size: {
|
|
17
|
+
height: number;
|
|
18
|
+
width: number;
|
|
19
|
+
}, prevSize: {
|
|
20
|
+
height: number;
|
|
21
|
+
width: number;
|
|
22
|
+
}) => void>;
|
|
23
|
+
};
|
|
24
|
+
rowCount: {
|
|
25
|
+
type: import("vue").PropType<number>;
|
|
26
|
+
required: true;
|
|
27
|
+
};
|
|
28
|
+
onRowsRendered: {
|
|
29
|
+
type: import("vue").PropType<(visibleRows: {
|
|
30
|
+
startIndex: number;
|
|
31
|
+
stopIndex: number;
|
|
32
|
+
}, allRows: {
|
|
33
|
+
startIndex: number;
|
|
34
|
+
stopIndex: number;
|
|
35
|
+
}) => void>;
|
|
36
|
+
};
|
|
37
|
+
overscanCount: {
|
|
38
|
+
type: import("vue").PropType<number>;
|
|
39
|
+
default: number;
|
|
40
|
+
};
|
|
41
|
+
defaultHeight: {
|
|
42
|
+
type: import("vue").PropType<number>;
|
|
43
|
+
default: number;
|
|
44
|
+
};
|
|
45
|
+
rowHeight: {
|
|
46
|
+
type: import("vue").PropType<string | number | DynamicRowHeight | ((index: number, cellProps: Record<string, unknown>) => number)>;
|
|
47
|
+
required: true;
|
|
48
|
+
};
|
|
49
|
+
rowProps: {
|
|
50
|
+
type: import("vue").PropType<{
|
|
51
|
+
[x: string]: unknown;
|
|
52
|
+
}>;
|
|
53
|
+
};
|
|
54
|
+
}>, {
|
|
55
|
+
element: HTMLDivElement | null;
|
|
56
|
+
scrollToRow({ align, behavior, index, }: {
|
|
57
|
+
align?: Align | undefined;
|
|
58
|
+
behavior?: ScrollBehavior | undefined;
|
|
59
|
+
index: number;
|
|
60
|
+
}): void;
|
|
61
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
62
|
+
tag: {
|
|
63
|
+
type: import("vue").PropType<keyof HTMLElementTagNameMap>;
|
|
64
|
+
default: string;
|
|
65
|
+
};
|
|
66
|
+
class: {
|
|
67
|
+
type: import("vue").PropType<string>;
|
|
68
|
+
};
|
|
69
|
+
style: {
|
|
70
|
+
type: import("vue").PropType<CSSProperties>;
|
|
71
|
+
};
|
|
72
|
+
onResize: {
|
|
73
|
+
type: import("vue").PropType<(size: {
|
|
74
|
+
height: number;
|
|
75
|
+
width: number;
|
|
76
|
+
}, prevSize: {
|
|
77
|
+
height: number;
|
|
78
|
+
width: number;
|
|
79
|
+
}) => void>;
|
|
80
|
+
};
|
|
81
|
+
rowCount: {
|
|
82
|
+
type: import("vue").PropType<number>;
|
|
83
|
+
required: true;
|
|
84
|
+
};
|
|
85
|
+
onRowsRendered: {
|
|
86
|
+
type: import("vue").PropType<(visibleRows: {
|
|
87
|
+
startIndex: number;
|
|
88
|
+
stopIndex: number;
|
|
89
|
+
}, allRows: {
|
|
90
|
+
startIndex: number;
|
|
91
|
+
stopIndex: number;
|
|
92
|
+
}) => void>;
|
|
93
|
+
};
|
|
94
|
+
overscanCount: {
|
|
95
|
+
type: import("vue").PropType<number>;
|
|
96
|
+
default: number;
|
|
97
|
+
};
|
|
98
|
+
defaultHeight: {
|
|
99
|
+
type: import("vue").PropType<number>;
|
|
100
|
+
default: number;
|
|
101
|
+
};
|
|
102
|
+
rowHeight: {
|
|
103
|
+
type: import("vue").PropType<string | number | DynamicRowHeight | ((index: number, cellProps: Record<string, unknown>) => number)>;
|
|
104
|
+
required: true;
|
|
105
|
+
};
|
|
106
|
+
rowProps: {
|
|
107
|
+
type: import("vue").PropType<{
|
|
108
|
+
[x: string]: unknown;
|
|
109
|
+
}>;
|
|
110
|
+
};
|
|
111
|
+
}>> & Readonly<{}>, {
|
|
112
|
+
tag: keyof HTMLElementTagNameMap;
|
|
113
|
+
overscanCount: number;
|
|
114
|
+
defaultHeight: number;
|
|
115
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>, {
|
|
116
|
+
row?(_: {
|
|
117
|
+
index: number;
|
|
118
|
+
style: CSSProperties;
|
|
119
|
+
ariaAttributes: {
|
|
120
|
+
'aria-posinset': number;
|
|
121
|
+
'aria-setsize': number;
|
|
122
|
+
role: 'listitem';
|
|
123
|
+
};
|
|
124
|
+
props: {
|
|
125
|
+
[x: string]: unknown;
|
|
126
|
+
} & Record<string, unknown>;
|
|
127
|
+
}): any;
|
|
128
|
+
default?(_: {}): any;
|
|
129
|
+
}>;
|
|
130
|
+
export default _default;
|
|
131
|
+
type __VLS_WithTemplateSlots<T, S> = T & {
|
|
132
|
+
new (): {
|
|
133
|
+
$slots: S;
|
|
134
|
+
};
|
|
135
|
+
};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { defineComponent as _, ref as $, computed as i, watch as h, openBlock as g, createBlock as k, resolveDynamicComponent as E, normalizeClass as B, normalizeStyle as f, withCtx as D, createElementBlock as V, Fragment as O, renderList as P, renderSlot as w, createElementVNode as L, unref as N } from "vue";
|
|
2
|
+
import { useVirtualizer as X } from "../../core/useVirtualizer.js";
|
|
3
|
+
import { isDynamicRowHeight as Y } from "./isDynamicRowHeight.js";
|
|
4
|
+
import { DATA_ATTRIBUTE_LIST_INDEX as F } from "./useDynamicRowHeight.js";
|
|
5
|
+
const G = {
|
|
6
|
+
name: "XVirtualList"
|
|
7
|
+
}, M = /* @__PURE__ */ _({
|
|
8
|
+
...G,
|
|
9
|
+
props: {
|
|
10
|
+
class: {},
|
|
11
|
+
defaultHeight: { default: 0 },
|
|
12
|
+
onResize: {},
|
|
13
|
+
onRowsRendered: {},
|
|
14
|
+
overscanCount: { default: 3 },
|
|
15
|
+
rowCount: {},
|
|
16
|
+
rowHeight: {},
|
|
17
|
+
rowProps: {},
|
|
18
|
+
style: {},
|
|
19
|
+
tag: { default: "div" }
|
|
20
|
+
},
|
|
21
|
+
setup(v, { expose: y }) {
|
|
22
|
+
const t = v, n = $(null), p = i(() => t.rowProps || {}), H = i(() => t.rowCount), a = i(() => Y(t.rowHeight)), x = i(() => {
|
|
23
|
+
if (a.value) {
|
|
24
|
+
const e = t.rowHeight, o = e.getAverageRowHeight();
|
|
25
|
+
return (r) => e.getRowHeight(r) ?? o;
|
|
26
|
+
}
|
|
27
|
+
return t.rowHeight;
|
|
28
|
+
}), {
|
|
29
|
+
getCellBounds: R,
|
|
30
|
+
getEstimatedSize: C,
|
|
31
|
+
scrollToIndex: b,
|
|
32
|
+
startIndexOverscan: u,
|
|
33
|
+
startIndexVisible: I,
|
|
34
|
+
stopIndexOverscan: c,
|
|
35
|
+
stopIndexVisible: z
|
|
36
|
+
} = X({
|
|
37
|
+
containerElement: n,
|
|
38
|
+
containerStyle: t.style,
|
|
39
|
+
defaultContainerSize: t.defaultHeight,
|
|
40
|
+
direction: "vertical",
|
|
41
|
+
itemCount: H,
|
|
42
|
+
itemProps: p,
|
|
43
|
+
itemSize: x,
|
|
44
|
+
onResize: t.onResize,
|
|
45
|
+
overscanCount: t.overscanCount
|
|
46
|
+
});
|
|
47
|
+
y({
|
|
48
|
+
get element() {
|
|
49
|
+
return n.value;
|
|
50
|
+
},
|
|
51
|
+
scrollToRow({
|
|
52
|
+
align: e = "auto",
|
|
53
|
+
behavior: o = "auto",
|
|
54
|
+
index: r
|
|
55
|
+
}) {
|
|
56
|
+
var d, l;
|
|
57
|
+
const s = b({
|
|
58
|
+
align: e,
|
|
59
|
+
containerScrollOffset: ((d = n.value) == null ? void 0 : d.scrollTop) ?? 0,
|
|
60
|
+
index: r
|
|
61
|
+
});
|
|
62
|
+
typeof ((l = n.value) == null ? void 0 : l.scrollTo) == "function" && s !== void 0 && n.value.scrollTo({
|
|
63
|
+
behavior: o,
|
|
64
|
+
top: s
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}), h(
|
|
68
|
+
[n, u, c, a, () => t.rowHeight],
|
|
69
|
+
([e, o, r, s]) => !e || !s ? void 0 : (() => {
|
|
70
|
+
const l = Array.from(e.children).filter((m, T) => {
|
|
71
|
+
if (m.hasAttribute("aria-hidden"))
|
|
72
|
+
return !1;
|
|
73
|
+
const S = `${o + T}`;
|
|
74
|
+
return m.setAttribute(F, S), !0;
|
|
75
|
+
});
|
|
76
|
+
return t.rowHeight.observeRowElements(l);
|
|
77
|
+
})(),
|
|
78
|
+
{ flush: "post" }
|
|
79
|
+
// Run after DOM updates
|
|
80
|
+
), h(
|
|
81
|
+
[u, I, c, z],
|
|
82
|
+
([e, o, r, s]) => {
|
|
83
|
+
e >= 0 && r >= 0 && t.onRowsRendered && t.onRowsRendered(
|
|
84
|
+
{
|
|
85
|
+
startIndex: o,
|
|
86
|
+
stopIndex: s
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
startIndex: e,
|
|
90
|
+
stopIndex: r
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
const A = i(() => {
|
|
96
|
+
const e = [];
|
|
97
|
+
if (t.rowCount > 0)
|
|
98
|
+
for (let o = u.value; o <= c.value; o++) {
|
|
99
|
+
const r = R(o), s = {
|
|
100
|
+
position: "absolute",
|
|
101
|
+
left: 0,
|
|
102
|
+
transform: `translateY(${r.scrollOffset}px)`,
|
|
103
|
+
// In case of dynamic row heights, don't specify a height style
|
|
104
|
+
height: a.value ? void 0 : `${r.size}px`,
|
|
105
|
+
width: "100%"
|
|
106
|
+
};
|
|
107
|
+
e.push({
|
|
108
|
+
key: o,
|
|
109
|
+
index: o,
|
|
110
|
+
style: s,
|
|
111
|
+
ariaAttributes: {
|
|
112
|
+
"aria-posinset": o + 1,
|
|
113
|
+
"aria-setsize": t.rowCount,
|
|
114
|
+
role: "listitem"
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return e;
|
|
119
|
+
});
|
|
120
|
+
return (e, o) => (g(), k(E(e.tag), {
|
|
121
|
+
ref_key: "element",
|
|
122
|
+
ref: n,
|
|
123
|
+
class: B(e.$props.class),
|
|
124
|
+
style: f({
|
|
125
|
+
position: "relative",
|
|
126
|
+
maxHeight: "100%",
|
|
127
|
+
flexGrow: 1,
|
|
128
|
+
overflowY: "auto",
|
|
129
|
+
...e.style
|
|
130
|
+
}),
|
|
131
|
+
role: "list"
|
|
132
|
+
}, {
|
|
133
|
+
default: D(() => [
|
|
134
|
+
(g(!0), V(O, null, P(A.value, (r) => w(e.$slots, "row", {
|
|
135
|
+
key: r.key,
|
|
136
|
+
index: r.index,
|
|
137
|
+
style: f(r.style),
|
|
138
|
+
ariaAttributes: r.ariaAttributes,
|
|
139
|
+
props: p.value
|
|
140
|
+
})), 128)),
|
|
141
|
+
w(e.$slots, "default"),
|
|
142
|
+
L("div", {
|
|
143
|
+
"aria-hidden": "",
|
|
144
|
+
style: f({
|
|
145
|
+
height: `${N(C)}px`,
|
|
146
|
+
width: "100%",
|
|
147
|
+
zIndex: -1
|
|
148
|
+
})
|
|
149
|
+
}, null, 4)
|
|
150
|
+
]),
|
|
151
|
+
_: 3
|
|
152
|
+
}, 8, ["class", "style"]));
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
export {
|
|
156
|
+
M as default
|
|
157
|
+
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { CSSProperties } from 'vue';
|
|
2
|
+
import type { TagNames } from '../../types';
|
|
3
|
+
export type DynamicRowHeight = {
|
|
4
|
+
getAverageRowHeight(): number;
|
|
5
|
+
getRowHeight(index: number): number | undefined;
|
|
6
|
+
setRowHeight(index: number, size: number): void;
|
|
7
|
+
observeRowElements: (elements: Element[] | NodeListOf<Element>) => () => void;
|
|
8
|
+
cleanup: () => void;
|
|
9
|
+
};
|
|
10
|
+
type ForbiddenKeys = 'ariaAttributes' | 'index' | 'style';
|
|
11
|
+
type ExcludeForbiddenKeys<Type> = {
|
|
12
|
+
[Key in keyof Type]: Key extends ForbiddenKeys ? never : Type[Key];
|
|
13
|
+
};
|
|
14
|
+
export interface VirtualListProps {
|
|
15
|
+
/**
|
|
16
|
+
* CSS class name.
|
|
17
|
+
*/
|
|
18
|
+
class?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Default height of list for initial render.
|
|
21
|
+
* This value is important for server rendering.
|
|
22
|
+
*/
|
|
23
|
+
defaultHeight?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Callback notified when the List's outermost HTMLElement resizes.
|
|
26
|
+
* This may be used to (re)scroll a row into view.
|
|
27
|
+
*/
|
|
28
|
+
onResize?: (size: {
|
|
29
|
+
height: number;
|
|
30
|
+
width: number;
|
|
31
|
+
}, prevSize: {
|
|
32
|
+
height: number;
|
|
33
|
+
width: number;
|
|
34
|
+
}) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Callback notified when the range of visible rows changes.
|
|
37
|
+
*/
|
|
38
|
+
onRowsRendered?: (visibleRows: {
|
|
39
|
+
startIndex: number;
|
|
40
|
+
stopIndex: number;
|
|
41
|
+
}, allRows: {
|
|
42
|
+
startIndex: number;
|
|
43
|
+
stopIndex: number;
|
|
44
|
+
}) => void;
|
|
45
|
+
/**
|
|
46
|
+
* How many additional rows to render outside of the visible area.
|
|
47
|
+
* This can reduce visual flickering near the edges of a list when scrolling.
|
|
48
|
+
*/
|
|
49
|
+
overscanCount?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Number of items to be rendered in the list.
|
|
52
|
+
*/
|
|
53
|
+
rowCount: number;
|
|
54
|
+
/**
|
|
55
|
+
* Row height; the following formats are supported:
|
|
56
|
+
* - number of pixels (number)
|
|
57
|
+
* - percentage of the grid's current height (string)
|
|
58
|
+
* - function that returns the row height (in pixels) given an index and `cellProps`
|
|
59
|
+
* - dynamic row height cache returned by the `useDynamicRowHeight` hook
|
|
60
|
+
*
|
|
61
|
+
* ⚠️ Dynamic row heights are not as efficient as predetermined sizes.
|
|
62
|
+
* It's recommended to provide your own height values if they can be determined ahead of time.
|
|
63
|
+
*/
|
|
64
|
+
rowHeight: number | string | ((index: number, cellProps: Record<string, unknown>) => number) | DynamicRowHeight;
|
|
65
|
+
/**
|
|
66
|
+
* Additional props to be passed to the row-rendering component via slots.
|
|
67
|
+
*/
|
|
68
|
+
rowProps?: ExcludeForbiddenKeys<Record<string, unknown>>;
|
|
69
|
+
/**
|
|
70
|
+
* Optional CSS properties.
|
|
71
|
+
* The list of rows will fill the height defined by this style.
|
|
72
|
+
*/
|
|
73
|
+
style?: CSSProperties;
|
|
74
|
+
/**
|
|
75
|
+
* Can be used to override the root HTML element rendered by the List component.
|
|
76
|
+
* The default value is "div", meaning that List renders an HTMLDivElement as its root.
|
|
77
|
+
*
|
|
78
|
+
* ⚠️ In most use cases the default ARIA roles are sufficient and this prop is not needed.
|
|
79
|
+
*/
|
|
80
|
+
tag?: TagNames;
|
|
81
|
+
}
|
|
82
|
+
export interface RowSlotProps {
|
|
83
|
+
ariaAttributes: {
|
|
84
|
+
'aria-posinset': number;
|
|
85
|
+
'aria-setsize': number;
|
|
86
|
+
role: 'listitem';
|
|
87
|
+
};
|
|
88
|
+
index: number;
|
|
89
|
+
style: CSSProperties;
|
|
90
|
+
props?: Record<string, unknown>;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Imperative List API.
|
|
94
|
+
*/
|
|
95
|
+
export interface VirtualListImperativeAPI {
|
|
96
|
+
/**
|
|
97
|
+
* Outermost HTML element for the list if mounted and null (if not mounted.
|
|
98
|
+
*/
|
|
99
|
+
readonly element: HTMLDivElement | null;
|
|
100
|
+
/**
|
|
101
|
+
* Scrolls the list so that the specified row is visible.
|
|
102
|
+
*
|
|
103
|
+
* @param align Determines the vertical alignment of the element within the list
|
|
104
|
+
* @param behavior Determines whether scrolling is instant or animates smoothly
|
|
105
|
+
* @param index Index of the row to scroll to (0-based)
|
|
106
|
+
*
|
|
107
|
+
* @throws RangeError if an invalid row index is provided
|
|
108
|
+
*/
|
|
109
|
+
scrollToRow(config: {
|
|
110
|
+
align?: 'auto' | 'center' | 'end' | 'smart' | 'start';
|
|
111
|
+
behavior?: 'auto' | 'instant' | 'smooth';
|
|
112
|
+
index: number;
|
|
113
|
+
}): void;
|
|
114
|
+
}
|
|
115
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Ref } from 'vue';
|
|
2
|
+
import type { DynamicRowHeight } from './types';
|
|
3
|
+
export declare const DATA_ATTRIBUTE_LIST_INDEX = "data-virtual-index";
|
|
4
|
+
export declare function useDynamicRowHeight({ defaultRowHeight, key, }: {
|
|
5
|
+
defaultRowHeight: number;
|
|
6
|
+
key?: Ref<string | number | undefined> | string | number;
|
|
7
|
+
}): DynamicRowHeight;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { ref as p, watch as d, onBeforeUnmount as H } from "vue";
|
|
2
|
+
import { assert as R } from "../../utils/assert.js";
|
|
3
|
+
const b = "data-virtual-index";
|
|
4
|
+
function x({
|
|
5
|
+
defaultRowHeight: v,
|
|
6
|
+
key: a
|
|
7
|
+
}) {
|
|
8
|
+
const r = p(/* @__PURE__ */ new Map()), o = p(0);
|
|
9
|
+
a !== void 0 && typeof a == "object" && "value" in a && d(a, () => {
|
|
10
|
+
r.value = /* @__PURE__ */ new Map(), o.value++;
|
|
11
|
+
});
|
|
12
|
+
const w = () => {
|
|
13
|
+
o.value;
|
|
14
|
+
let e = 0;
|
|
15
|
+
return r.value.forEach((t) => {
|
|
16
|
+
e += t;
|
|
17
|
+
}), e === 0 ? v : e / r.value.size;
|
|
18
|
+
}, m = (e) => {
|
|
19
|
+
o.value;
|
|
20
|
+
const t = r.value.get(e);
|
|
21
|
+
return t !== void 0 ? t : v;
|
|
22
|
+
}, A = (e, t) => {
|
|
23
|
+
if (r.value.get(e) === t)
|
|
24
|
+
return;
|
|
25
|
+
const n = new Map(r.value);
|
|
26
|
+
n.set(e, t), r.value = n, o.value++;
|
|
27
|
+
}, E = (e) => {
|
|
28
|
+
if (e.length === 0)
|
|
29
|
+
return;
|
|
30
|
+
let t = !1;
|
|
31
|
+
const n = [];
|
|
32
|
+
if (e.forEach((s) => {
|
|
33
|
+
const { borderBoxSize: i, target: c } = s, h = c.getAttribute(b);
|
|
34
|
+
R(
|
|
35
|
+
h !== null,
|
|
36
|
+
`Invalid ${b} attribute value`
|
|
37
|
+
);
|
|
38
|
+
const g = parseInt(h), { blockSize: l } = i[0];
|
|
39
|
+
if (!l)
|
|
40
|
+
return;
|
|
41
|
+
r.value.get(g) !== l && (n.push({ index: g, height: l }), t = !0);
|
|
42
|
+
}), t) {
|
|
43
|
+
const s = new Map(r.value);
|
|
44
|
+
n.forEach(({ index: i, height: c }) => {
|
|
45
|
+
s.set(i, c);
|
|
46
|
+
}), r.value = s, o.value++;
|
|
47
|
+
}
|
|
48
|
+
}, u = new ResizeObserver(E);
|
|
49
|
+
H(f);
|
|
50
|
+
function f() {
|
|
51
|
+
u.disconnect();
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
getAverageRowHeight: w,
|
|
55
|
+
getRowHeight: m,
|
|
56
|
+
setRowHeight: A,
|
|
57
|
+
observeRowElements: (e) => {
|
|
58
|
+
const t = Array.isArray(e) ? e : Array.from(e);
|
|
59
|
+
return t.forEach((n) => u.observe(n)), () => {
|
|
60
|
+
t.forEach((n) => u.unobserve(n));
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
cleanup: f
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export {
|
|
67
|
+
b as DATA_ATTRIBUTE_LIST_INDEX,
|
|
68
|
+
x as useDynamicRowHeight
|
|
69
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Indices } from './types';
|
|
2
|
+
export declare function scanForUnloadedIndices({ isRowLoaded, minimumBatchSize, rowCount, startIndex, stopIndex, }: {
|
|
3
|
+
isRowLoaded: (index: number) => boolean;
|
|
4
|
+
minimumBatchSize: number;
|
|
5
|
+
rowCount: number;
|
|
6
|
+
startIndex: number;
|
|
7
|
+
stopIndex: number;
|
|
8
|
+
}): Indices[];
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
function o({
|
|
2
|
+
isRowLoaded: x,
|
|
3
|
+
minimumBatchSize: d,
|
|
4
|
+
rowCount: i,
|
|
5
|
+
startIndex: I,
|
|
6
|
+
stopIndex: a
|
|
7
|
+
}) {
|
|
8
|
+
const r = [];
|
|
9
|
+
let s = -1, e = -1;
|
|
10
|
+
for (let t = I; t <= a; t++)
|
|
11
|
+
x(t) ? e >= 0 && (r.push({
|
|
12
|
+
startIndex: s,
|
|
13
|
+
stopIndex: e
|
|
14
|
+
}), s = e = -1) : (e = t, s < 0 && (s = t));
|
|
15
|
+
if (e >= 0) {
|
|
16
|
+
const t = Math.min(
|
|
17
|
+
Math.max(e, s + d - 1),
|
|
18
|
+
i - 1
|
|
19
|
+
);
|
|
20
|
+
for (let n = e + 1; n <= t && !x(n); n++)
|
|
21
|
+
e = n;
|
|
22
|
+
r.push({
|
|
23
|
+
startIndex: s,
|
|
24
|
+
stopIndex: e
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
if (r.length) {
|
|
28
|
+
const t = r[0];
|
|
29
|
+
for (; t.stopIndex - t.startIndex + 1 < d && t.startIndex > 0; ) {
|
|
30
|
+
const n = t.startIndex - 1;
|
|
31
|
+
if (!x(n))
|
|
32
|
+
t.startIndex = n;
|
|
33
|
+
else
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return r;
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
o as scanForUnloadedIndices
|
|
41
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type Indices = {
|
|
2
|
+
startIndex: number;
|
|
3
|
+
stopIndex: number;
|
|
4
|
+
};
|
|
5
|
+
export type OnRowsRendered = (indices: Indices) => void;
|
|
6
|
+
export type InfiniteLoaderProps = {
|
|
7
|
+
/**
|
|
8
|
+
* Function responsible for tracking the loaded state of each item.
|
|
9
|
+
*/
|
|
10
|
+
isRowLoaded: (index: number) => boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Callback to be invoked when more rows must be loaded.
|
|
13
|
+
* It should return a Promise that is resolved once all data has finished loading.
|
|
14
|
+
*/
|
|
15
|
+
loadMoreRows: (startIndex: number, stopIndex: number) => Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Minimum number of rows to be loaded at a time; defaults to 10.
|
|
18
|
+
* This property can be used to batch requests to reduce HTTP requests.
|
|
19
|
+
*/
|
|
20
|
+
minimumBatchSize?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Threshold at which to pre-fetch data; defaults to 15.
|
|
23
|
+
* A threshold of 15 means that data will start loading when a user scrolls within 15 rows.
|
|
24
|
+
*/
|
|
25
|
+
threshold?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Number of rows in list; can be arbitrary high number if actual number is unknown.
|
|
28
|
+
*/
|
|
29
|
+
rowCount: number;
|
|
30
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type MaybeRefOrGetter } from 'vue';
|
|
2
|
+
import type { OnRowsRendered, InfiniteLoaderProps } from './types';
|
|
3
|
+
export declare function useInfiniteLoader(props: MaybeRefOrGetter<InfiniteLoaderProps>): {
|
|
4
|
+
onRowsRendered: OnRowsRendered;
|
|
5
|
+
pendingRowsCache: import("vue").Reactive<Set<number>>;
|
|
6
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { reactive as I, computed as a, toValue as s } from "vue";
|
|
2
|
+
import { scanForUnloadedIndices as v } from "./scanForUnloadedIndices.js";
|
|
3
|
+
function z(d) {
|
|
4
|
+
const e = I(/* @__PURE__ */ new Set()), r = a(
|
|
5
|
+
() => s(d).isRowLoaded
|
|
6
|
+
), m = a(
|
|
7
|
+
() => s(d).loadMoreRows
|
|
8
|
+
), w = a(
|
|
9
|
+
() => s(d).minimumBatchSize ?? 10
|
|
10
|
+
), u = a(
|
|
11
|
+
() => s(d).rowCount
|
|
12
|
+
), c = a(
|
|
13
|
+
() => s(d).threshold ?? 15
|
|
14
|
+
), f = (t) => r.value(t) ? (e.has(t) && e.delete(t), !0) : e.has(t);
|
|
15
|
+
return {
|
|
16
|
+
onRowsRendered: ({ startIndex: t, stopIndex: R }) => {
|
|
17
|
+
if (e.size > 0) {
|
|
18
|
+
const n = [];
|
|
19
|
+
e.forEach((o) => {
|
|
20
|
+
r.value(o) && n.push(o);
|
|
21
|
+
}), n.forEach((o) => e.delete(o));
|
|
22
|
+
}
|
|
23
|
+
const l = v({
|
|
24
|
+
isRowLoaded: f,
|
|
25
|
+
minimumBatchSize: w.value,
|
|
26
|
+
rowCount: u.value,
|
|
27
|
+
startIndex: Math.max(0, t - c.value),
|
|
28
|
+
stopIndex: Math.min(u.value - 1, R + c.value)
|
|
29
|
+
});
|
|
30
|
+
for (let n = 0; n < l.length; n++) {
|
|
31
|
+
const { startIndex: o, stopIndex: h } = l[n];
|
|
32
|
+
for (let i = o; i <= h; i++)
|
|
33
|
+
e.add(i);
|
|
34
|
+
m.value(o, h);
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
pendingRowsCache: e
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export {
|
|
41
|
+
z as useInfiniteLoader
|
|
42
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|