@rudra-studio/rudra-layout 1.0.18 → 1.0.19
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/components/VirtualList/index.d.ts +94 -0
- package/components/VirtualList/index.js +127 -0
- package/index.d.ts +2 -0
- package/index.js +2 -1
- package/package.json +1 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export interface VirtualListRenderContext {
|
|
3
|
+
item: any;
|
|
4
|
+
index: number;
|
|
5
|
+
}
|
|
6
|
+
export interface VirtualListProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children" | "className"> {
|
|
7
|
+
/**
|
|
8
|
+
* List data.
|
|
9
|
+
*
|
|
10
|
+
* @type|json
|
|
11
|
+
*/
|
|
12
|
+
items?: any[];
|
|
13
|
+
/**
|
|
14
|
+
* Item renderer.
|
|
15
|
+
*
|
|
16
|
+
* @nodeFunction
|
|
17
|
+
*/
|
|
18
|
+
children?: React.ReactNode | ((context: VirtualListRenderContext) => React.ReactNode);
|
|
19
|
+
/**
|
|
20
|
+
* Height of one item in pixels.
|
|
21
|
+
*/
|
|
22
|
+
itemHeight?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Visible list height.
|
|
25
|
+
*/
|
|
26
|
+
height?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Additional items rendered above
|
|
29
|
+
* and below the viewport.
|
|
30
|
+
*/
|
|
31
|
+
overscan?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Gap between rows.
|
|
34
|
+
*/
|
|
35
|
+
gap?: number;
|
|
36
|
+
/**
|
|
37
|
+
* Index to scroll to.
|
|
38
|
+
*
|
|
39
|
+
* Updating this prop scrolls
|
|
40
|
+
* the list to that item.
|
|
41
|
+
*/
|
|
42
|
+
scrollToIndex?: number;
|
|
43
|
+
/**
|
|
44
|
+
* @select|start|center|end
|
|
45
|
+
*/
|
|
46
|
+
scrollAlignment?: "start" | "center" | "end";
|
|
47
|
+
/**
|
|
48
|
+
* Initial scroll index.
|
|
49
|
+
*/
|
|
50
|
+
initialScrollIndex?: number;
|
|
51
|
+
/**
|
|
52
|
+
* Trigger onEndReached when this many
|
|
53
|
+
* items remain below the visible range.
|
|
54
|
+
*/
|
|
55
|
+
endReachedThreshold?: number;
|
|
56
|
+
/**
|
|
57
|
+
* Empty builder message.
|
|
58
|
+
*/
|
|
59
|
+
emptyText?: string;
|
|
60
|
+
/**
|
|
61
|
+
* @type|class
|
|
62
|
+
*/
|
|
63
|
+
className?: string;
|
|
64
|
+
/**
|
|
65
|
+
* @type|class
|
|
66
|
+
*/
|
|
67
|
+
itemClassName?: string;
|
|
68
|
+
/**
|
|
69
|
+
* @type|class
|
|
70
|
+
*/
|
|
71
|
+
contentClassName?: string;
|
|
72
|
+
/**
|
|
73
|
+
* @type|complex
|
|
74
|
+
* @schema {"type":"object"}
|
|
75
|
+
*/
|
|
76
|
+
customAttributes?: Record<string, string>;
|
|
77
|
+
/**
|
|
78
|
+
* @type|function
|
|
79
|
+
*/
|
|
80
|
+
onScrollChange?: (scrollTop: number) => void;
|
|
81
|
+
/**
|
|
82
|
+
* @type|function
|
|
83
|
+
*/
|
|
84
|
+
onVisibleRangeChange?: (startIndex: number, endIndex: number) => void;
|
|
85
|
+
/**
|
|
86
|
+
* @type|function
|
|
87
|
+
*/
|
|
88
|
+
onEndReached?: () => void;
|
|
89
|
+
/**
|
|
90
|
+
* @type|function
|
|
91
|
+
*/
|
|
92
|
+
onItemClick?: (item: any, index: number) => void;
|
|
93
|
+
}
|
|
94
|
+
export default function VirtualList({ items, children, itemHeight, height, overscan, gap, scrollToIndex, scrollAlignment, initialScrollIndex, endReachedThreshold, emptyText, className, itemClassName, contentClassName, customAttributes, onScrollChange, onVisibleRangeChange, onEndReached, onItemClick, style, ...props }: VirtualListProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { useEffect as e, useMemo as t, useRef as n, useState as r } from "react";
|
|
2
|
+
import { jsx as i } from "react/jsx-runtime";
|
|
3
|
+
//#region src/components/VirtualList/index.tsx
|
|
4
|
+
function a(e, t, n) {
|
|
5
|
+
return Math.max(t, Math.min(n, e));
|
|
6
|
+
}
|
|
7
|
+
function o({ items: o = [], children: s, itemHeight: c = 56, height: l = 400, overscan: u = 3, gap: d = 0, scrollToIndex: f, scrollAlignment: p = "start", initialScrollIndex: m = 0, endReachedThreshold: h = 3, emptyText: g = "Add list items", className: _ = "w-full", itemClassName: v = "", contentClassName: y = "", customAttributes: b = {}, onScrollChange: x, onVisibleRangeChange: S, onEndReached: C, onItemClick: w, style: T, ...E }) {
|
|
8
|
+
let D = n(null), O = n(!1), [k, A] = r(0), j = Math.max(1, c), M = Math.max(0, d), N = j + M, P = o.length > 0 ? o.length * N - M : 0, F = Math.max(1, Math.ceil(l / N)), I = Math.floor(k / N), L = a(I - Math.max(0, u), 0, Math.max(0, o.length - 1)), R = a(I + F + Math.max(0, u), 0, Math.max(0, o.length - 1)), z = t(() => {
|
|
9
|
+
if (o.length === 0) return [];
|
|
10
|
+
let e = [];
|
|
11
|
+
for (let t = L; t <= R; t++) e.push({
|
|
12
|
+
item: o[t],
|
|
13
|
+
index: t
|
|
14
|
+
});
|
|
15
|
+
return e;
|
|
16
|
+
}, [
|
|
17
|
+
o,
|
|
18
|
+
L,
|
|
19
|
+
R
|
|
20
|
+
]), B = (e) => {
|
|
21
|
+
let t = a(e, 0, Math.max(0, o.length - 1)) * N;
|
|
22
|
+
return p === "center" ? Math.max(0, t - l / 2 + j / 2) : p === "end" ? Math.max(0, t - l + j) : t;
|
|
23
|
+
}, V = (e, t = "auto") => {
|
|
24
|
+
let n = D.current;
|
|
25
|
+
!n || o.length === 0 || n.scrollTo({
|
|
26
|
+
top: B(e),
|
|
27
|
+
behavior: t
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
return e(() => {
|
|
31
|
+
if (o.length === 0 || m <= 0) return;
|
|
32
|
+
let e = requestAnimationFrame(() => {
|
|
33
|
+
V(m);
|
|
34
|
+
});
|
|
35
|
+
return () => {
|
|
36
|
+
cancelAnimationFrame(e);
|
|
37
|
+
};
|
|
38
|
+
}, []), e(() => {
|
|
39
|
+
f !== void 0 && V(f, "smooth");
|
|
40
|
+
}, [
|
|
41
|
+
f,
|
|
42
|
+
o.length,
|
|
43
|
+
N,
|
|
44
|
+
l,
|
|
45
|
+
p
|
|
46
|
+
]), e(() => {
|
|
47
|
+
if (o.length === 0) return;
|
|
48
|
+
let e = a(I, 0, o.length - 1), t = a(I + F - 1, 0, o.length - 1);
|
|
49
|
+
S?.(e, t), o.length - 1 - t <= Math.max(0, h) ? O.current || (O.current = !0, C?.()) : O.current = !1;
|
|
50
|
+
}, [
|
|
51
|
+
I,
|
|
52
|
+
F,
|
|
53
|
+
o.length,
|
|
54
|
+
h
|
|
55
|
+
]), o.length === 0 ? /* @__PURE__ */ i("div", {
|
|
56
|
+
className: _,
|
|
57
|
+
...b,
|
|
58
|
+
...E,
|
|
59
|
+
style: {
|
|
60
|
+
width: "100%",
|
|
61
|
+
height: l,
|
|
62
|
+
display: "flex",
|
|
63
|
+
alignItems: "center",
|
|
64
|
+
justifyContent: "center",
|
|
65
|
+
padding: 16,
|
|
66
|
+
border: "1px dashed #d1d5db",
|
|
67
|
+
borderRadius: 8,
|
|
68
|
+
color: "#9ca3af",
|
|
69
|
+
fontSize: 13,
|
|
70
|
+
boxSizing: "border-box",
|
|
71
|
+
...T
|
|
72
|
+
},
|
|
73
|
+
children: typeof s == "function" ? s({
|
|
74
|
+
item: null,
|
|
75
|
+
index: 0
|
|
76
|
+
}) : g
|
|
77
|
+
}) : /* @__PURE__ */ i("div", {
|
|
78
|
+
ref: D,
|
|
79
|
+
className: _,
|
|
80
|
+
...b,
|
|
81
|
+
...E,
|
|
82
|
+
onScroll: (e) => {
|
|
83
|
+
let t = e.currentTarget.scrollTop;
|
|
84
|
+
A(t), x?.(t);
|
|
85
|
+
},
|
|
86
|
+
style: {
|
|
87
|
+
position: "relative",
|
|
88
|
+
width: "100%",
|
|
89
|
+
height: l,
|
|
90
|
+
overflowY: "auto",
|
|
91
|
+
overflowX: "hidden",
|
|
92
|
+
WebkitOverflowScrolling: "touch",
|
|
93
|
+
boxSizing: "border-box",
|
|
94
|
+
...T
|
|
95
|
+
},
|
|
96
|
+
children: /* @__PURE__ */ i("div", {
|
|
97
|
+
className: y,
|
|
98
|
+
style: {
|
|
99
|
+
position: "relative",
|
|
100
|
+
width: "100%",
|
|
101
|
+
height: P,
|
|
102
|
+
minHeight: P,
|
|
103
|
+
boxSizing: "border-box"
|
|
104
|
+
},
|
|
105
|
+
children: z.map(({ item: e, index: t }) => /* @__PURE__ */ i("div", {
|
|
106
|
+
className: v,
|
|
107
|
+
"data-index": t,
|
|
108
|
+
onClick: () => w?.(e, t),
|
|
109
|
+
style: {
|
|
110
|
+
position: "absolute",
|
|
111
|
+
top: t * N,
|
|
112
|
+
left: 0,
|
|
113
|
+
right: 0,
|
|
114
|
+
height: j,
|
|
115
|
+
overflow: "hidden",
|
|
116
|
+
boxSizing: "border-box"
|
|
117
|
+
},
|
|
118
|
+
children: typeof s == "function" ? s({
|
|
119
|
+
item: e,
|
|
120
|
+
index: t
|
|
121
|
+
}) : s
|
|
122
|
+
}, e?.id ?? t))
|
|
123
|
+
})
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
//#endregion
|
|
127
|
+
export { o as default };
|
package/index.d.ts
CHANGED
|
@@ -26,3 +26,5 @@ export type { ComplexGridProps } from './components/StructuredGrid';
|
|
|
26
26
|
export { default as ComplexGrid } from './components/StructuredGrid';
|
|
27
27
|
export type { DataTableProps } from './components/Table';
|
|
28
28
|
export { default as DataTable } from './components/Table';
|
|
29
|
+
export type { VirtualListProps, VirtualListRenderContext } from './components/VirtualList';
|
|
30
|
+
export { default as VirtualList } from './components/VirtualList';
|
package/index.js
CHANGED
|
@@ -12,4 +12,5 @@ import u from "./components/Section/index.js";
|
|
|
12
12
|
import d from "./components/Stack/index.js";
|
|
13
13
|
import f from "./components/StructuredGrid/index.js";
|
|
14
14
|
import p from "./components/Table/index.js";
|
|
15
|
-
|
|
15
|
+
import m from "./components/VirtualList/index.js";
|
|
16
|
+
export { e as AspectRatio, t as Box, f as ComplexGrid, r as Container, p as DataTable, a as Flex, o as Grid, s as Repeater, i as RepeaterCarousel, c as RepeaterTable, n as RudraCarousel, l as ScrollArea, u as Section, d as Stack, m as VirtualList };
|
package/package.json
CHANGED