@rc-component/listy 1.1.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 (41) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +110 -0
  3. package/assets/index.css +36 -0
  4. package/assets/index.less +44 -0
  5. package/es/GroupHeader.d.ts +15 -0
  6. package/es/GroupHeader.js +32 -0
  7. package/es/List.d.ts +49 -0
  8. package/es/List.js +33 -0
  9. package/es/RawList/index.d.ts +5 -0
  10. package/es/RawList/index.js +90 -0
  11. package/es/RawList/useRawListScroll.d.ts +3 -0
  12. package/es/RawList/useRawListScroll.js +71 -0
  13. package/es/VirtualList/index.d.ts +5 -0
  14. package/es/VirtualList/index.js +151 -0
  15. package/es/VirtualList/useFlattenRows.d.ts +21 -0
  16. package/es/VirtualList/useFlattenRows.js +62 -0
  17. package/es/VirtualList/useStickyGroupHeader.d.ts +14 -0
  18. package/es/VirtualList/useStickyGroupHeader.js +82 -0
  19. package/es/hooks/useGroupSegments.d.ts +16 -0
  20. package/es/hooks/useGroupSegments.js +39 -0
  21. package/es/index.d.ts +3 -0
  22. package/es/index.js +2 -0
  23. package/lib/GroupHeader.d.ts +15 -0
  24. package/lib/GroupHeader.js +40 -0
  25. package/lib/List.d.ts +49 -0
  26. package/lib/List.js +41 -0
  27. package/lib/RawList/index.d.ts +5 -0
  28. package/lib/RawList/index.js +98 -0
  29. package/lib/RawList/useRawListScroll.d.ts +3 -0
  30. package/lib/RawList/useRawListScroll.js +79 -0
  31. package/lib/VirtualList/index.d.ts +5 -0
  32. package/lib/VirtualList/index.js +159 -0
  33. package/lib/VirtualList/useFlattenRows.d.ts +21 -0
  34. package/lib/VirtualList/useFlattenRows.js +69 -0
  35. package/lib/VirtualList/useStickyGroupHeader.d.ts +14 -0
  36. package/lib/VirtualList/useStickyGroupHeader.js +90 -0
  37. package/lib/hooks/useGroupSegments.d.ts +16 -0
  38. package/lib/hooks/useGroupSegments.js +46 -0
  39. package/lib/index.d.ts +3 -0
  40. package/lib/index.js +9 -0
  41. package/package.json +76 -0
@@ -0,0 +1,21 @@
1
+ import * as React from 'react';
2
+ import type { Group, GroupSegmentItem } from '../hooks/useGroupSegments';
3
+ export type Row<T, K extends React.Key = React.Key> = {
4
+ type: 'header';
5
+ groupKey: K;
6
+ } | {
7
+ type: 'item';
8
+ item: T;
9
+ index: number;
10
+ };
11
+ export interface FlattenRowsResult<T, K extends React.Key = React.Key> {
12
+ rows: Row<T, K>[];
13
+ groupKeys: K[];
14
+ groupKeyToItems: Map<K, T[]>;
15
+ }
16
+ /**
17
+ * Flatten grouped data into header and item rows.
18
+ * When grouping is enabled, items follow the insertion order of the group map
19
+ * while preserving their original indexes.
20
+ */
21
+ export default function useFlattenRows<T, K extends React.Key = React.Key>(data: T[], groupData: Map<K, GroupSegmentItem<T>[]>, group?: Group<T, K>): FlattenRowsResult<T, K>;
@@ -0,0 +1,62 @@
1
+ import * as React from 'react';
2
+
3
+ // ============================== Types ===============================
4
+
5
+ /**
6
+ * Flatten grouped data into header and item rows.
7
+ * When grouping is enabled, items follow the insertion order of the group map
8
+ * while preserving their original indexes.
9
+ */
10
+ export default function useFlattenRows(data, groupData, group) {
11
+ return React.useMemo(() => {
12
+ // ============================== Init ================================
13
+ const flatRows = [];
14
+ const groupKeys = [];
15
+ const groupKeyToItems = new Map();
16
+
17
+ // ============================ No Group ==============================
18
+ if (!group) {
19
+ data.forEach((item, index) => {
20
+ flatRows.push({
21
+ type: 'item',
22
+ item,
23
+ index
24
+ });
25
+ });
26
+ return {
27
+ rows: flatRows,
28
+ groupKeys,
29
+ groupKeyToItems
30
+ };
31
+ }
32
+
33
+ // ============================= Flatten ==============================
34
+ groupData.forEach((groupItems, groupKey) => {
35
+ groupKeyToItems.set(groupKey, groupItems.map(({
36
+ item
37
+ }) => item));
38
+ groupKeys.push(groupKey);
39
+ flatRows.push({
40
+ type: 'header',
41
+ groupKey
42
+ });
43
+ groupItems.forEach(({
44
+ item,
45
+ index
46
+ }) => {
47
+ flatRows.push({
48
+ type: 'item',
49
+ item,
50
+ index
51
+ });
52
+ });
53
+ });
54
+
55
+ // ============================== Return ==============================
56
+ return {
57
+ rows: flatRows,
58
+ groupKeys,
59
+ groupKeyToItems
60
+ };
61
+ }, [data, group, groupData]);
62
+ }
@@ -0,0 +1,14 @@
1
+ import * as React from 'react';
2
+ import type { ListProps as VirtualListProps, ListRef as RcVirtualListRef } from '@rc-component/virtual-list';
3
+ import type { Group } from '../hooks/useGroupSegments';
4
+ type ExtraRenderInfo = Parameters<NonNullable<VirtualListProps<unknown>['extraRender']>>[0];
5
+ export interface StickyHeaderParams<T, K extends React.Key = React.Key> {
6
+ enabled: boolean;
7
+ group: Group<T, K> | undefined;
8
+ groupKeys: K[];
9
+ groupKeyToItems: Map<K, T[]>;
10
+ prefixCls: string;
11
+ listRef: React.RefObject<RcVirtualListRef | null>;
12
+ }
13
+ export default function useStickyGroupHeader<T, K extends React.Key = React.Key>(params: StickyHeaderParams<T, K>): (info: ExtraRenderInfo) => React.JSX.Element;
14
+ export {};
@@ -0,0 +1,82 @@
1
+ import * as React from 'react';
2
+ import Portal from '@rc-component/portal';
3
+ import GroupHeader from "../GroupHeader";
4
+
5
+ // ============================== Types ===============================
6
+
7
+ // ============================== Utils ===============================
8
+ const HEADER_TOP_TOLERANCE = 1;
9
+ function findActiveHeaderIndex(groupKeys, getHeaderTop, scrollTop) {
10
+ let left = 0;
11
+ let right = groupKeys.length - 1;
12
+ let activeIndex = 0;
13
+ while (left <= right) {
14
+ const mid = Math.floor((left + right) / 2);
15
+ if (getHeaderTop(groupKeys[mid]) <= scrollTop + HEADER_TOP_TOLERANCE) {
16
+ activeIndex = mid;
17
+ left = mid + 1;
18
+ } else {
19
+ right = mid - 1;
20
+ }
21
+ }
22
+ return activeIndex;
23
+ }
24
+
25
+ // ============================== Params ==============================
26
+
27
+ export default function useStickyGroupHeader(params) {
28
+ // ============================== Props ==============================
29
+ const {
30
+ enabled,
31
+ group,
32
+ groupKeys,
33
+ groupKeyToItems,
34
+ prefixCls,
35
+ listRef
36
+ } = params;
37
+
38
+ // ============================ Extra Render ==========================
39
+ const extraRender = React.useCallback(info => {
40
+ const {
41
+ getSize,
42
+ scrollTop,
43
+ virtual
44
+ } = info;
45
+ if (!enabled || !group || !groupKeys.length || !virtual) {
46
+ return null;
47
+ }
48
+ const container = listRef.current?.nativeElement;
49
+ if (!container) {
50
+ return null;
51
+ }
52
+
53
+ // The sticky header is the group whose section the viewport top sits in.
54
+ const activeHeaderIdx = findActiveHeaderIndex(groupKeys, groupKey => getSize(groupKey).top, scrollTop);
55
+ const currGroupKey = groupKeys[activeHeaderIdx];
56
+ const groupItems = groupKeyToItems.get(currGroupKey) || [];
57
+ const currentSize = getSize(currGroupKey);
58
+ const headerHeight = currentSize.bottom - currentSize.top;
59
+ const nextGroupKey = groupKeys[activeHeaderIdx + 1];
60
+ const top = nextGroupKey ? Math.min(0, getSize(nextGroupKey).top - headerHeight - scrollTop) : 0;
61
+
62
+ // Render a cloned header pinned over the virtual list.
63
+ return /*#__PURE__*/React.createElement(Portal, {
64
+ open: true,
65
+ getContainer: () => container
66
+ }, /*#__PURE__*/React.createElement("div", {
67
+ className: `${prefixCls}-group-header-holder`
68
+ }, /*#__PURE__*/React.createElement(GroupHeader, {
69
+ fixed: true,
70
+ group: group,
71
+ groupKey: currGroupKey,
72
+ groupItems: groupItems,
73
+ prefixCls: prefixCls,
74
+ style: {
75
+ top
76
+ }
77
+ })));
78
+ }, [enabled, group, groupKeys, groupKeyToItems, prefixCls, listRef]);
79
+
80
+ // ============================== Return ==============================
81
+ return extraRender;
82
+ }
@@ -0,0 +1,16 @@
1
+ import * as React from 'react';
2
+ export interface Group<T, K extends React.Key = React.Key> {
3
+ key: (item: T) => K;
4
+ title: (groupKey: K, items: T[]) => React.ReactNode;
5
+ }
6
+ export interface GroupSegmentItem<T> {
7
+ item: T;
8
+ index: number;
9
+ }
10
+ /**
11
+ * Build a lookup map from group key to all matching data items and their
12
+ * original indexes.
13
+ * This groups by key across the full data set and does not require items with
14
+ * the same key to be contiguous.
15
+ */
16
+ export default function useGroupSegments<T, K extends React.Key = React.Key>(data: T[], group?: Group<T, K>): Map<K, GroupSegmentItem<T>[]>;
@@ -0,0 +1,39 @@
1
+ import * as React from 'react';
2
+
3
+ // ============================== Types ===============================
4
+
5
+ /**
6
+ * Build a lookup map from group key to all matching data items and their
7
+ * original indexes.
8
+ * This groups by key across the full data set and does not require items with
9
+ * the same key to be contiguous.
10
+ */
11
+ export default function useGroupSegments(data, group) {
12
+ return React.useMemo(() => {
13
+ // ============================== Init ================================
14
+ const map = new Map();
15
+
16
+ // ============================ No Group ==============================
17
+ if (!group) {
18
+ return map;
19
+ }
20
+
21
+ // ============================= Collect ==============================
22
+ data.forEach((item, index) => {
23
+ const groupKey = group.key(item);
24
+ const groupItems = map.get(groupKey);
25
+ const groupSegmentItem = {
26
+ item,
27
+ index
28
+ };
29
+ if (groupItems) {
30
+ groupItems.push(groupSegmentItem);
31
+ } else {
32
+ map.set(groupKey, [groupSegmentItem]);
33
+ }
34
+ });
35
+
36
+ // ============================== Return ==============================
37
+ return map;
38
+ }, [data, group]);
39
+ }
package/es/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import Listy from './List';
2
+ export type { ListyRef, ListyProps } from './List';
3
+ export default Listy;
package/es/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import Listy from "./List";
2
+ export default Listy;
@@ -0,0 +1,15 @@
1
+ import * as React from 'react';
2
+ import type { Group } from './hooks/useGroupSegments';
3
+ export interface GroupHeaderProps<T, K extends React.Key = React.Key> {
4
+ group: Group<T, K>;
5
+ groupKey: K;
6
+ groupItems: T[];
7
+ prefixCls: string;
8
+ fixed?: boolean;
9
+ sticky?: boolean;
10
+ style?: React.CSSProperties;
11
+ }
12
+ declare const GroupHeaderWithRef: <T, K extends React.Key = React.Key>(props: GroupHeaderProps<T, K> & {
13
+ ref?: React.Ref<HTMLDivElement>;
14
+ }) => React.ReactElement;
15
+ export default GroupHeaderWithRef;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _clsx = _interopRequireDefault(require("clsx"));
9
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
11
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
12
+ // ============================== Types ===============================
13
+
14
+ function GroupHeader(props, ref) {
15
+ // ============================== Props ==============================
16
+ const {
17
+ group,
18
+ groupKey,
19
+ groupItems,
20
+ prefixCls,
21
+ fixed,
22
+ sticky,
23
+ style
24
+ } = props;
25
+
26
+ // ============================= Classes =============================
27
+ const className = (0, _clsx.default)(`${prefixCls}-group-header`, {
28
+ [`${prefixCls}-group-header-sticky`]: sticky,
29
+ [`${prefixCls}-group-header-fixed`]: fixed
30
+ });
31
+
32
+ // ============================== Render ==============================
33
+ return /*#__PURE__*/React.createElement("div", {
34
+ ref: ref,
35
+ className: className,
36
+ style: style
37
+ }, group.title(groupKey, groupItems));
38
+ }
39
+ const GroupHeaderWithRef = /*#__PURE__*/React.forwardRef(GroupHeader);
40
+ var _default = exports.default = GroupHeaderWithRef;
package/lib/List.d.ts ADDED
@@ -0,0 +1,49 @@
1
+ import * as React from 'react';
2
+ import type { Group } from './hooks/useGroupSegments';
3
+ export type RowKey<T> = keyof T | ((item: T) => React.Key);
4
+ export type ScrollAlign = 'top' | 'bottom' | 'auto';
5
+ export interface GroupScrollToConfig {
6
+ groupKey: React.Key;
7
+ align?: ScrollAlign;
8
+ offset?: number;
9
+ }
10
+ export interface KeyScrollToConfig {
11
+ key: React.Key;
12
+ align?: ScrollAlign;
13
+ offset?: number;
14
+ }
15
+ export interface PositionScrollToConfig {
16
+ left?: number;
17
+ top?: number;
18
+ }
19
+ export type ListyScrollToConfig = number | null | KeyScrollToConfig | PositionScrollToConfig | GroupScrollToConfig;
20
+ export interface ListyRef {
21
+ scrollTo: (config?: ListyScrollToConfig) => void;
22
+ }
23
+ export interface ListyProps<T, K extends React.Key = React.Key> {
24
+ items?: T[];
25
+ sticky?: boolean;
26
+ itemHeight?: number;
27
+ height?: number;
28
+ group?: Group<T, K>;
29
+ virtual?: boolean;
30
+ prefixCls?: string;
31
+ rowKey: RowKey<T>;
32
+ onScroll?: React.UIEventHandler<HTMLElement>;
33
+ itemRender: (item: T, index: number) => React.ReactNode;
34
+ }
35
+ export interface ListComponentProps<T, K extends React.Key = React.Key> {
36
+ data: T[];
37
+ sticky?: boolean;
38
+ itemHeight?: number;
39
+ height?: number;
40
+ group?: Group<T, K>;
41
+ prefixCls: string;
42
+ rowKey: RowKey<T>;
43
+ onScroll?: React.UIEventHandler<HTMLElement>;
44
+ itemRender: (item: T, index: number) => React.ReactNode;
45
+ }
46
+ declare const ListyWithForwardRef: <T, K extends React.Key = React.Key>(props: ListyProps<T, K> & {
47
+ ref?: React.Ref<ListyRef>;
48
+ }) => React.ReactElement;
49
+ export default ListyWithForwardRef;
package/lib/List.js ADDED
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var React = _react;
9
+ var _RawList = _interopRequireDefault(require("./RawList"));
10
+ var _VirtualList = _interopRequireDefault(require("./VirtualList"));
11
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
13
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
14
+ // ============================== Types ===============================
15
+
16
+ function Listy(props, ref) {
17
+ // ============================== Props ==============================
18
+ const {
19
+ items,
20
+ virtual = true,
21
+ prefixCls = 'rc-listy',
22
+ ...restProps
23
+ } = props;
24
+
25
+ // =============================== Data ===============================
26
+ const data = React.useMemo(() => items || [], [items]);
27
+
28
+ // ============================== Render ===============================
29
+ const sharedListProps = {
30
+ ...restProps,
31
+ data,
32
+ prefixCls,
33
+ ref
34
+ };
35
+ const listNode = virtual ? /*#__PURE__*/React.createElement(_VirtualList.default, sharedListProps) : /*#__PURE__*/React.createElement(_RawList.default, sharedListProps);
36
+ return listNode;
37
+ }
38
+
39
+ // Const to support generic with forwardRef
40
+ const ListyWithForwardRef = /*#__PURE__*/(0, _react.forwardRef)(Listy);
41
+ var _default = exports.default = ListyWithForwardRef;
@@ -0,0 +1,5 @@
1
+ import * as React from 'react';
2
+ import type { ListComponentProps } from '../List';
3
+ export type RawListProps<T, K extends React.Key = React.Key> = ListComponentProps<T, K>;
4
+ declare const RawListWithRef: any;
5
+ export default RawListWithRef;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _util = require("@rc-component/util");
9
+ var _GroupHeader = _interopRequireDefault(require("../GroupHeader"));
10
+ var _useGroupSegments = _interopRequireDefault(require("../hooks/useGroupSegments"));
11
+ var _useRawListScroll = _interopRequireDefault(require("./useRawListScroll"));
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
14
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
15
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
16
+ // ============================== Types ===============================
17
+
18
+ function RawList(props, ref) {
19
+ // ============================== Props ==============================
20
+ const {
21
+ data,
22
+ group,
23
+ height,
24
+ itemRender,
25
+ onScroll,
26
+ prefixCls,
27
+ rowKey,
28
+ sticky
29
+ } = props;
30
+
31
+ // =============================== Refs ===============================
32
+ const holderRef = (0, _useRawListScroll.default)(ref, prefixCls, !!(sticky && group));
33
+
34
+ // =============================== Data ===============================
35
+ const groupData = (0, _useGroupSegments.default)(data, group);
36
+
37
+ // ============================== Utils ===============================
38
+ const getItemKey = (0, _util.useEvent)(item => {
39
+ if (typeof rowKey === 'function') {
40
+ return rowKey(item);
41
+ }
42
+ return item[rowKey];
43
+ });
44
+ const getScrollTargetProps = React.useCallback(key => ({
45
+ 'data-key': String(key)
46
+ }), []);
47
+
48
+ // ============================ Render Item ===========================
49
+ const renderItem = React.useCallback((item, index, groupKey) => {
50
+ const key = getItemKey(item);
51
+ const scrollTargetProps = getScrollTargetProps(key);
52
+ return /*#__PURE__*/React.createElement("div", _extends({
53
+ key: key,
54
+ className: `${prefixCls}-item`,
55
+ style: sticky && groupKey !== undefined ? {
56
+ scrollMarginTop: `var(--${prefixCls}-item-scroll-margin-top, 0px)`
57
+ } : undefined
58
+ }, scrollTargetProps), itemRender(item, index));
59
+ }, [getItemKey, getScrollTargetProps, itemRender, prefixCls, sticky]);
60
+
61
+ // ============================= Content ==============================
62
+ const rawContent = group ? Array.from(groupData, ([groupKey, groupItems]) => {
63
+ const currentGroupItems = groupItems.map(({
64
+ item
65
+ }) => item);
66
+ return /*#__PURE__*/React.createElement("div", _extends({
67
+ key: groupKey,
68
+ className: `${prefixCls}-group-section`
69
+ }, getScrollTargetProps(groupKey)), /*#__PURE__*/React.createElement(_GroupHeader.default, {
70
+ group: group,
71
+ groupKey: groupKey,
72
+ groupItems: currentGroupItems,
73
+ prefixCls: prefixCls,
74
+ sticky: sticky
75
+ }), groupItems.map(({
76
+ item,
77
+ index
78
+ }) => {
79
+ return renderItem(item, index, groupKey);
80
+ }));
81
+ }) : data.map((item, index) => {
82
+ return renderItem(item, index);
83
+ });
84
+
85
+ // ============================== Render ==============================
86
+ return /*#__PURE__*/React.createElement("div", {
87
+ ref: holderRef,
88
+ className: prefixCls,
89
+ style: {
90
+ maxHeight: height,
91
+ overflowY: height === undefined ? undefined : 'auto',
92
+ overflowAnchor: 'none'
93
+ },
94
+ onScroll: onScroll
95
+ }, rawContent);
96
+ }
97
+ const RawListWithRef = /*#__PURE__*/React.forwardRef(RawList);
98
+ var _default = exports.default = RawListWithRef;
@@ -0,0 +1,3 @@
1
+ import * as React from 'react';
2
+ import type { ListyRef } from '../List';
3
+ export default function useRawListScroll(ref: React.Ref<ListyRef>, prefixCls: string, stickyGroup: boolean): React.RefObject<HTMLDivElement>;
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = useRawListScroll;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
9
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
10
+ function useRawListScroll(ref, prefixCls, stickyGroup) {
11
+ // =============================== Refs ===============================
12
+ const holderRef = React.useRef(null);
13
+
14
+ // ============================== Utils ===============================
15
+ const getStickyHeaderHeight = React.useCallback(targetElement => {
16
+ if (!stickyGroup) {
17
+ return 0;
18
+ }
19
+ const groupSection = targetElement.closest(`.${CSS.escape(`${prefixCls}-group-section`)}`);
20
+ const groupHeader = groupSection?.querySelector(`.${CSS.escape(`${prefixCls}-group-header`)}`);
21
+ if (!groupHeader) {
22
+ return 0;
23
+ }
24
+ const rect = groupHeader.getBoundingClientRect();
25
+ const height = rect.height || rect.bottom - rect.top || groupHeader.offsetHeight;
26
+ return Number.isFinite(height) ? height : 0;
27
+ }, [prefixCls, stickyGroup]);
28
+ const setTargetScrollMargin = React.useCallback((targetElement, align) => {
29
+ const marginTop = align === 'top' ? getStickyHeaderHeight(targetElement) : 0;
30
+ targetElement.style.setProperty(`--${prefixCls}-item-scroll-margin-top`, `${marginTop}px`);
31
+ }, [getStickyHeaderHeight, prefixCls]);
32
+
33
+ // ============================== Scroll ==============================
34
+ const scrollTo = React.useCallback(config => {
35
+ const holder = holderRef.current;
36
+ if (!holder || config == null) {
37
+ return;
38
+ }
39
+ if (typeof config === 'number') {
40
+ holder.scrollTop = config;
41
+ return;
42
+ }
43
+ if ('key' in config || 'groupKey' in config) {
44
+ const {
45
+ align = 'top'
46
+ } = config;
47
+ const targetKey = 'groupKey' in config ? config.groupKey : config.key;
48
+ const targetElement = holder.querySelector(`[data-key="${CSS.escape(String(targetKey))}"]`);
49
+ if (targetElement) {
50
+ if ('key' in config) {
51
+ setTargetScrollMargin(targetElement, align);
52
+ }
53
+ targetElement.scrollIntoView({
54
+ block: align === 'bottom' ? 'end' : align === 'auto' ? 'nearest' : 'start',
55
+ inline: 'nearest'
56
+ });
57
+ }
58
+ return;
59
+ }
60
+ const {
61
+ left,
62
+ top
63
+ } = config;
64
+ if (left !== undefined) {
65
+ holder.scrollLeft = left;
66
+ }
67
+ if (top !== undefined) {
68
+ holder.scrollTop = top;
69
+ }
70
+ }, [setTargetScrollMargin]);
71
+
72
+ // ============================ Imperative ============================
73
+ React.useImperativeHandle(ref, () => ({
74
+ scrollTo
75
+ }), [scrollTo]);
76
+
77
+ // ============================== Return ==============================
78
+ return holderRef;
79
+ }
@@ -0,0 +1,5 @@
1
+ import * as React from 'react';
2
+ import type { ListComponentProps } from '../List';
3
+ export type VirtualListProps<T, K extends React.Key = React.Key> = ListComponentProps<T, K>;
4
+ declare const VirtualListWithRef: any;
5
+ export default VirtualListWithRef;