@rainbow-oh/yee-c 0.6.4 → 0.7.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/cjs/Button/style/index.less +5 -4
- package/dist/cjs/Drawer/drawer.js +1 -1
- package/dist/cjs/Drawer/interface.d.ts +1 -1
- package/dist/cjs/Drawer/style/index.less +1 -0
- package/dist/cjs/List/demo/virtual.d.ts +3 -0
- package/dist/cjs/List/demo/virtual.js +53 -0
- package/dist/cjs/List/hooks/useListKeyboard.d.ts +28 -0
- package/dist/cjs/List/hooks/useListKeyboard.js +188 -0
- package/dist/cjs/List/interface.d.ts +29 -2
- package/dist/cjs/List/list.js +141 -21
- package/dist/cjs/List/style/index.less +24 -0
- package/dist/cjs/Select/demo/columns.d.ts +3 -0
- package/dist/cjs/Select/demo/columns.js +62 -0
- package/dist/cjs/Select/hooks/useSelectKeyboard.d.ts +13 -1
- package/dist/cjs/Select/hooks/useSelectKeyboard.js +81 -10
- package/dist/cjs/Select/interface.d.ts +30 -3
- package/dist/cjs/Select/option.js +4 -3
- package/dist/cjs/Select/options.js +90 -8
- package/dist/cjs/Select/select.js +32 -8
- package/dist/cjs/Select/style/index.less +14 -0
- package/dist/cjs/Selector/interface.d.ts +4 -0
- package/dist/cjs/Selector/selector.js +5 -3
- package/dist/cjs/Table/interface.d.ts +1 -1
- package/dist/cjs/Tree/demo/draggable.js +2 -0
- package/dist/cjs/Tree/interface.d.ts +46 -23
- package/dist/cjs/Tree/tree-node.d.ts +1 -1
- package/dist/cjs/Tree/tree-node.js +30 -23
- package/dist/cjs/Tree/tree.d.ts +13 -12
- package/dist/cjs/Tree/tree.js +452 -227
- package/dist/cjs/Tree/utils/tree-tools.d.ts +43 -10
- package/dist/cjs/Tree/utils/tree-tools.js +129 -91
- package/dist/cjs/locale/context.d.ts +5 -4
- package/dist/cjs/locale/context.js +15 -8
- package/dist/cjs/locale/interface.d.ts +20 -0
- package/dist/cjs/locale/util.d.ts +3 -3
- package/dist/cjs/style/color.css +1 -0
- package/dist/cjs/style/size.css +2 -1
- package/dist/cjs/style/themes.css +1 -1
- package/dist/cjs/style/variables.css +4 -2
- package/dist/cjs/utils/isEqual.js +5 -7
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/Button/style/index.less +5 -4
- package/dist/esm/Drawer/drawer.js +2 -1
- package/dist/esm/Drawer/interface.d.ts +1 -1
- package/dist/esm/Drawer/style/index.less +1 -0
- package/dist/esm/List/demo/virtual.d.ts +3 -0
- package/dist/esm/List/demo/virtual.js +22 -0
- package/dist/esm/List/hooks/useListKeyboard.d.ts +28 -0
- package/dist/esm/List/hooks/useListKeyboard.js +173 -0
- package/dist/esm/List/interface.d.ts +29 -2
- package/dist/esm/List/list.js +171 -14
- package/dist/esm/List/style/index.less +24 -0
- package/dist/esm/Select/demo/columns.d.ts +3 -0
- package/dist/esm/Select/demo/columns.js +36 -0
- package/dist/esm/Select/hooks/useSelectKeyboard.d.ts +13 -1
- package/dist/esm/Select/hooks/useSelectKeyboard.js +91 -14
- package/dist/esm/Select/interface.d.ts +30 -3
- package/dist/esm/Select/option.js +6 -2
- package/dist/esm/Select/options.js +114 -32
- package/dist/esm/Select/select.js +40 -11
- package/dist/esm/Select/style/index.less +14 -0
- package/dist/esm/Selector/interface.d.ts +4 -0
- package/dist/esm/Selector/selector.js +10 -4
- package/dist/esm/Table/interface.d.ts +1 -1
- package/dist/esm/Tree/demo/draggable.js +2 -0
- package/dist/esm/Tree/interface.d.ts +46 -23
- package/dist/esm/Tree/tree-node.d.ts +1 -1
- package/dist/esm/Tree/tree-node.js +26 -31
- package/dist/esm/Tree/tree.d.ts +13 -12
- package/dist/esm/Tree/tree.js +572 -163
- package/dist/esm/Tree/utils/tree-tools.d.ts +43 -10
- package/dist/esm/Tree/utils/tree-tools.js +219 -104
- package/dist/esm/locale/context.d.ts +5 -4
- package/dist/esm/locale/context.js +25 -9
- package/dist/esm/locale/interface.d.ts +20 -0
- package/dist/esm/locale/util.d.ts +3 -3
- package/dist/esm/style/color.css +1 -0
- package/dist/esm/style/size.css +2 -1
- package/dist/esm/style/themes.css +1 -1
- package/dist/esm/style/variables.css +4 -2
- package/dist/esm/utils/isEqual.js +5 -7
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/umd/yee-c.min.css +2 -2
- package/dist/umd/yee-c.min.js +1 -1
- package/package.json +1 -1
- package/src/Button/style/index.less +5 -4
- package/src/Drawer/drawer.tsx +1 -1
- package/src/Drawer/interface.ts +1 -0
- package/src/Drawer/style/index.less +1 -0
- package/src/List/demo/virtual.tsx +20 -0
- package/src/List/hooks/useListKeyboard.ts +235 -0
- package/src/List/index.en-US.md +6 -0
- package/src/List/index.zh-CN.md +6 -0
- package/src/List/interface.ts +29 -2
- package/src/List/list.tsx +157 -19
- package/src/List/style/index.less +24 -0
- package/src/Select/demo/columns.tsx +35 -0
- package/src/Select/hooks/useSelectKeyboard.ts +112 -15
- package/src/Select/index.en-US.md +4 -0
- package/src/Select/index.zh-CN.md +4 -0
- package/src/Select/interface.ts +31 -4
- package/src/Select/option.tsx +9 -3
- package/src/Select/options.tsx +119 -26
- package/src/Select/select.tsx +41 -8
- package/src/Select/style/index.less +14 -0
- package/src/Selector/interface.ts +4 -0
- package/src/Selector/selector.tsx +8 -3
- package/src/Table/interface.ts +1 -1
- package/src/Tree/demo/draggable.tsx +2 -0
- package/src/Tree/interface.ts +46 -23
- package/src/Tree/tree-node.tsx +26 -29
- package/src/Tree/tree.tsx +573 -274
- package/src/Tree/utils/tree-tools.ts +231 -125
- package/src/locale/_README.md +22 -13
- package/src/locale/context.tsx +33 -16
- package/src/locale/interface.ts +24 -0
- package/src/locale/util.ts +6 -6
- package/src/style/color.css +1 -0
- package/src/style/size.css +2 -1
- package/src/utils/isEqual.ts +5 -7
- package/src/version.ts +1 -1
|
@@ -228,7 +228,8 @@ var Drawer = function Drawer(baseprops) {
|
|
|
228
228
|
className: clsx("".concat(prefixCls, "-header"), classNames === null || classNames === void 0 ? void 0 : classNames.header),
|
|
229
229
|
style: styles === null || styles === void 0 ? void 0 : styles.header
|
|
230
230
|
}, /*#__PURE__*/React.createElement("div", {
|
|
231
|
-
className: "".concat(prefixCls, "-title")
|
|
231
|
+
className: clsx("".concat(prefixCls, "-title"), classNames === null || classNames === void 0 ? void 0 : classNames.title),
|
|
232
|
+
style: styles === null || styles === void 0 ? void 0 : styles.title
|
|
232
233
|
}, title)) : null, /*#__PURE__*/React.createElement("div", {
|
|
233
234
|
className: clsx("".concat(prefixCls, "-body"), classNames === null || classNames === void 0 ? void 0 : classNames.body),
|
|
234
235
|
style: styles === null || styles === void 0 ? void 0 : styles.body
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import type { DataAttributeProps } from '../utils/types';
|
|
3
|
-
export type SemanticDOM = 'mask' | 'wrapper' | 'close' | 'header' | 'content' | 'body' | 'footer';
|
|
3
|
+
export type SemanticDOM = 'mask' | 'wrapper' | 'close' | 'header' | 'title' | 'content' | 'body' | 'footer';
|
|
4
4
|
export interface DrawerProps extends DataAttributeProps {
|
|
5
5
|
/**
|
|
6
6
|
* Custom prefix class name
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { List } from "../..";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
var items = Array.from({
|
|
4
|
+
length: 10000
|
|
5
|
+
}, function (_, i) {
|
|
6
|
+
return {
|
|
7
|
+
key: String(i),
|
|
8
|
+
label: "List item ".concat(i + 1),
|
|
9
|
+
value: String(i)
|
|
10
|
+
};
|
|
11
|
+
});
|
|
12
|
+
export default (function () {
|
|
13
|
+
return /*#__PURE__*/React.createElement(List, {
|
|
14
|
+
virtual: true,
|
|
15
|
+
height: 300,
|
|
16
|
+
itemHeight: 32,
|
|
17
|
+
items: items,
|
|
18
|
+
onClick: function onClick(item) {
|
|
19
|
+
return console.log('Clicked:', item.label);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ListItemProps } from '../interface';
|
|
2
|
+
interface UseListKeyboardParams {
|
|
3
|
+
items: Array<ListItemProps>;
|
|
4
|
+
/**
|
|
5
|
+
* Number of columns in the grid layout.
|
|
6
|
+
* Affects ArrowUp/Down (jump by columns) and ArrowLeft/Right behavior.
|
|
7
|
+
* @default 1
|
|
8
|
+
*/
|
|
9
|
+
columns?: number;
|
|
10
|
+
/**
|
|
11
|
+
* Controlled focused key from the parent.
|
|
12
|
+
* When provided, the hook uses this value instead of internal state.
|
|
13
|
+
*/
|
|
14
|
+
focusedKey?: string | number;
|
|
15
|
+
/**
|
|
16
|
+
* Callback when focused key changes.
|
|
17
|
+
*/
|
|
18
|
+
onFocusChange?: (key: string | number) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Callback when Enter is pressed on a focused item.
|
|
21
|
+
*/
|
|
22
|
+
onClick?: (item: ListItemProps) => void;
|
|
23
|
+
}
|
|
24
|
+
export default function useListKeyboard({ items, columns, focusedKey: controlledFocusedKey, onFocusChange, onClick, }: UseListKeyboardParams): {
|
|
25
|
+
focusedKey: string | number;
|
|
26
|
+
onKeyDown: (event: React.KeyboardEvent) => void;
|
|
27
|
+
};
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
2
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
4
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
5
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
6
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
7
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
8
|
+
export default function useListKeyboard(_ref) {
|
|
9
|
+
var items = _ref.items,
|
|
10
|
+
_ref$columns = _ref.columns,
|
|
11
|
+
columns = _ref$columns === void 0 ? 1 : _ref$columns,
|
|
12
|
+
controlledFocusedKey = _ref.focusedKey,
|
|
13
|
+
onFocusChange = _ref.onFocusChange,
|
|
14
|
+
onClick = _ref.onClick;
|
|
15
|
+
var _useState = useState(''),
|
|
16
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
17
|
+
internalFocusedKey = _useState2[0],
|
|
18
|
+
setInternalFocusedKey = _useState2[1];
|
|
19
|
+
var isControlled = controlledFocusedKey !== undefined;
|
|
20
|
+
var focusedKey = isControlled ? controlledFocusedKey : internalFocusedKey;
|
|
21
|
+
var setFocusedKey = useCallback(function (key) {
|
|
22
|
+
if (!isControlled) {
|
|
23
|
+
setInternalFocusedKey(key);
|
|
24
|
+
}
|
|
25
|
+
onFocusChange === null || onFocusChange === void 0 || onFocusChange(key);
|
|
26
|
+
}, [isControlled, onFocusChange]);
|
|
27
|
+
|
|
28
|
+
// Reset internal focused key if it no longer exists in items
|
|
29
|
+
useEffect(function () {
|
|
30
|
+
if (!isControlled && internalFocusedKey !== '' && !items.some(function (item) {
|
|
31
|
+
return item.key === internalFocusedKey;
|
|
32
|
+
})) {
|
|
33
|
+
setInternalFocusedKey('');
|
|
34
|
+
}
|
|
35
|
+
}, [items, isControlled, internalFocusedKey]);
|
|
36
|
+
var getFocusedIndex = function getFocusedIndex() {
|
|
37
|
+
if (focusedKey === '' || focusedKey === undefined) return -1;
|
|
38
|
+
return items.findIndex(function (item) {
|
|
39
|
+
return item.key === focusedKey;
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
var findNextEnabledIndex = function findNextEnabledIndex(startIndex, direction) {
|
|
43
|
+
var count = items.length;
|
|
44
|
+
if (count === 0) return -1;
|
|
45
|
+
var next = direction === 1 ? startIndex + 1 >= count ? 0 : startIndex + 1 : startIndex - 1 < 0 ? count - 1 : startIndex - 1;
|
|
46
|
+
|
|
47
|
+
// Guard against infinite loop if all items are disabled
|
|
48
|
+
var attempts = 0;
|
|
49
|
+
while (items[next].disabled && attempts < count) {
|
|
50
|
+
next = direction === 1 ? next + 1 >= count ? 0 : next + 1 : next - 1 < 0 ? count - 1 : next - 1;
|
|
51
|
+
attempts++;
|
|
52
|
+
}
|
|
53
|
+
return items[next].disabled ? -1 : next;
|
|
54
|
+
};
|
|
55
|
+
var handleArrowUp = function handleArrowUp() {
|
|
56
|
+
var focusedIndex = getFocusedIndex();
|
|
57
|
+
var nextIndex;
|
|
58
|
+
if (columns > 1) {
|
|
59
|
+
if (focusedIndex === -1) {
|
|
60
|
+
nextIndex = findNextEnabledIndex(items.length - 1, -1);
|
|
61
|
+
} else {
|
|
62
|
+
var target = focusedIndex - columns;
|
|
63
|
+
if (target >= 0) {
|
|
64
|
+
nextIndex = items[target].disabled ? findNextEnabledIndex(target, -1) : target;
|
|
65
|
+
} else {
|
|
66
|
+
var _items$wrapTarget;
|
|
67
|
+
// Wrap to last row, same column
|
|
68
|
+
var lastRowStart = Math.floor((items.length - 1) / columns) * columns;
|
|
69
|
+
var col = focusedIndex % columns;
|
|
70
|
+
var wrapTarget = Math.min(lastRowStart + col, items.length - 1);
|
|
71
|
+
nextIndex = (_items$wrapTarget = items[wrapTarget]) !== null && _items$wrapTarget !== void 0 && _items$wrapTarget.disabled ? findNextEnabledIndex(wrapTarget, -1) : wrapTarget;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
if (focusedIndex === -1) {
|
|
76
|
+
nextIndex = findNextEnabledIndex(items.length - 1, -1);
|
|
77
|
+
} else {
|
|
78
|
+
nextIndex = findNextEnabledIndex(focusedIndex, -1);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (nextIndex !== -1) {
|
|
82
|
+
setFocusedKey(items[nextIndex].key);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
var handleArrowDown = function handleArrowDown() {
|
|
86
|
+
var focusedIndex = getFocusedIndex();
|
|
87
|
+
var nextIndex;
|
|
88
|
+
if (columns > 1) {
|
|
89
|
+
if (focusedIndex === -1) {
|
|
90
|
+
nextIndex = findNextEnabledIndex(-1, 1);
|
|
91
|
+
} else {
|
|
92
|
+
var target = focusedIndex + columns;
|
|
93
|
+
if (target < items.length) {
|
|
94
|
+
nextIndex = items[target].disabled ? findNextEnabledIndex(target, 1) : target;
|
|
95
|
+
} else {
|
|
96
|
+
var _items$wrapTarget2;
|
|
97
|
+
// Wrap to first row, same column
|
|
98
|
+
var col = focusedIndex % columns;
|
|
99
|
+
var wrapTarget = col;
|
|
100
|
+
nextIndex = (_items$wrapTarget2 = items[wrapTarget]) !== null && _items$wrapTarget2 !== void 0 && _items$wrapTarget2.disabled ? findNextEnabledIndex(wrapTarget, 1) : wrapTarget;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
if (focusedIndex === -1) {
|
|
105
|
+
nextIndex = findNextEnabledIndex(-1, 1);
|
|
106
|
+
} else {
|
|
107
|
+
nextIndex = findNextEnabledIndex(focusedIndex, 1);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (nextIndex !== -1) {
|
|
111
|
+
setFocusedKey(items[nextIndex].key);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
var handleArrowLeft = function handleArrowLeft() {
|
|
115
|
+
var focusedIndex = getFocusedIndex();
|
|
116
|
+
if (focusedIndex <= 0) return;
|
|
117
|
+
var nextIndex = findNextEnabledIndex(focusedIndex, -1);
|
|
118
|
+
if (nextIndex !== -1) {
|
|
119
|
+
setFocusedKey(items[nextIndex].key);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
var handleArrowRight = function handleArrowRight() {
|
|
123
|
+
var focusedIndex = getFocusedIndex();
|
|
124
|
+
if (focusedIndex >= items.length - 1 && focusedIndex !== -1) return;
|
|
125
|
+
var nextIndex = findNextEnabledIndex(focusedIndex === -1 ? -1 : focusedIndex, 1);
|
|
126
|
+
if (nextIndex !== -1) {
|
|
127
|
+
setFocusedKey(items[nextIndex].key);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
var handleEnter = function handleEnter() {
|
|
131
|
+
if (focusedKey === '' || focusedKey === undefined) return;
|
|
132
|
+
var item = items.find(function (i) {
|
|
133
|
+
return i.key === focusedKey;
|
|
134
|
+
});
|
|
135
|
+
if (item && !item.disabled) {
|
|
136
|
+
onClick === null || onClick === void 0 || onClick(item);
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
var onKeyDown = function onKeyDown(event) {
|
|
140
|
+
if (!items || items.length === 0) return;
|
|
141
|
+
switch (event.key) {
|
|
142
|
+
case 'ArrowUp':
|
|
143
|
+
event.preventDefault();
|
|
144
|
+
handleArrowUp();
|
|
145
|
+
break;
|
|
146
|
+
case 'ArrowDown':
|
|
147
|
+
event.preventDefault();
|
|
148
|
+
handleArrowDown();
|
|
149
|
+
break;
|
|
150
|
+
case 'ArrowLeft':
|
|
151
|
+
if (columns > 1) {
|
|
152
|
+
event.preventDefault();
|
|
153
|
+
handleArrowLeft();
|
|
154
|
+
}
|
|
155
|
+
break;
|
|
156
|
+
case 'ArrowRight':
|
|
157
|
+
if (columns > 1) {
|
|
158
|
+
event.preventDefault();
|
|
159
|
+
handleArrowRight();
|
|
160
|
+
}
|
|
161
|
+
break;
|
|
162
|
+
case 'Enter':
|
|
163
|
+
event.preventDefault();
|
|
164
|
+
handleEnter();
|
|
165
|
+
break;
|
|
166
|
+
default:
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
return {
|
|
170
|
+
focusedKey: focusedKey,
|
|
171
|
+
onKeyDown: onKeyDown
|
|
172
|
+
};
|
|
173
|
+
}
|
|
@@ -47,8 +47,8 @@ export interface ListProps extends Omit<React.HTMLAttributes<HTMLUListElement>,
|
|
|
47
47
|
*/
|
|
48
48
|
bordered?: boolean;
|
|
49
49
|
/**
|
|
50
|
-
* Set the focused item
|
|
51
|
-
|
|
50
|
+
* Set the focused item (controlled)
|
|
51
|
+
*/
|
|
52
52
|
focusedKey?: string | number;
|
|
53
53
|
/**
|
|
54
54
|
* Render list item as a function
|
|
@@ -58,6 +58,33 @@ export interface ListProps extends Omit<React.HTMLAttributes<HTMLUListElement>,
|
|
|
58
58
|
* Click event for list items
|
|
59
59
|
*/
|
|
60
60
|
onClick?: (item: ListItemProps) => void;
|
|
61
|
+
/**
|
|
62
|
+
* Callback when focused item changes via keyboard navigation
|
|
63
|
+
*/
|
|
64
|
+
onFocusChange?: (key: string | number) => void;
|
|
65
|
+
/**
|
|
66
|
+
* Enable virtual scrolling for large lists.
|
|
67
|
+
* Requires `height` to be set.
|
|
68
|
+
* @default false
|
|
69
|
+
*/
|
|
70
|
+
virtual?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Height of the scrollable container in pixels.
|
|
73
|
+
* Required when `virtual` is true.
|
|
74
|
+
*/
|
|
75
|
+
height?: number;
|
|
76
|
+
/**
|
|
77
|
+
* Fixed height of each list item row in pixels.
|
|
78
|
+
* Used for virtual scroll calculation.
|
|
79
|
+
* @default 32
|
|
80
|
+
*/
|
|
81
|
+
itemHeight?: number;
|
|
82
|
+
/**
|
|
83
|
+
* Number of columns in the list layout.
|
|
84
|
+
* When greater than 1, items are displayed in a grid.
|
|
85
|
+
* @default 1
|
|
86
|
+
*/
|
|
87
|
+
columns?: number;
|
|
61
88
|
}
|
|
62
89
|
export type ListCtxType = {
|
|
63
90
|
prefixCls: string;
|
package/dist/esm/List/list.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
-
var _excluded = ["prefixCls", "className", "items", "bordered", "focusedKey", "itemRender", "onClick"];
|
|
2
|
+
var _excluded = ["prefixCls", "className", "style", "items", "bordered", "focusedKey", "itemRender", "onClick", "onFocusChange", "virtual", "height", "itemHeight", "columns"];
|
|
3
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
4
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
3
5
|
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); }
|
|
4
6
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
5
7
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
@@ -9,7 +11,9 @@ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) r
|
|
|
9
11
|
import clsx from 'clsx';
|
|
10
12
|
import React, { createContext, forwardRef, useContext } from 'react';
|
|
11
13
|
import { GlobalContext } from "../Config-Provider";
|
|
14
|
+
import useVirtualList from "../hooks/useVirtualList";
|
|
12
15
|
import mergeContextToProps from "../utils/mergeContextToProps";
|
|
16
|
+
import useListKeyboard from "./hooks/useListKeyboard";
|
|
13
17
|
import ListItem from "./list-item";
|
|
14
18
|
import "./style/index.less";
|
|
15
19
|
export var ListCtx = /*#__PURE__*/createContext({});
|
|
@@ -20,36 +24,189 @@ var List = /*#__PURE__*/forwardRef(function (baseprops, ref) {
|
|
|
20
24
|
var _props$prefixCls = props.prefixCls,
|
|
21
25
|
prefixCls = _props$prefixCls === void 0 ? 'yee-list' : _props$prefixCls,
|
|
22
26
|
className = props.className,
|
|
27
|
+
style = props.style,
|
|
23
28
|
items = props.items,
|
|
24
29
|
bordered = props.bordered,
|
|
25
|
-
|
|
30
|
+
controlledFocusedKey = props.focusedKey,
|
|
26
31
|
itemRender = props.itemRender,
|
|
27
32
|
onClick = props.onClick,
|
|
33
|
+
onFocusChange = props.onFocusChange,
|
|
34
|
+
_props$virtual = props.virtual,
|
|
35
|
+
virtual = _props$virtual === void 0 ? false : _props$virtual,
|
|
36
|
+
height = props.height,
|
|
37
|
+
_props$itemHeight = props.itemHeight,
|
|
38
|
+
itemHeight = _props$itemHeight === void 0 ? 32 : _props$itemHeight,
|
|
39
|
+
_props$columns = props.columns,
|
|
40
|
+
columns = _props$columns === void 0 ? 1 : _props$columns,
|
|
28
41
|
rest = _objectWithoutProperties(props, _excluded);
|
|
29
|
-
var
|
|
30
|
-
var
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
42
|
+
var multiColumn = columns > 1;
|
|
43
|
+
var useVirtual = virtual && height !== null && height !== undefined && Array.isArray(items);
|
|
44
|
+
var safeItems = Array.isArray(items) ? items : [];
|
|
45
|
+
|
|
46
|
+
// Keyboard navigation
|
|
47
|
+
var _useListKeyboard = useListKeyboard({
|
|
48
|
+
items: safeItems,
|
|
49
|
+
columns: columns,
|
|
50
|
+
focusedKey: controlledFocusedKey,
|
|
51
|
+
onFocusChange: onFocusChange,
|
|
52
|
+
onClick: onClick
|
|
53
|
+
}),
|
|
54
|
+
focusedKey = _useListKeyboard.focusedKey,
|
|
55
|
+
onKeyDown = _useListKeyboard.onKeyDown;
|
|
56
|
+
|
|
57
|
+
// Virtual scroll — in multi-column mode, track rows not individual items
|
|
58
|
+
var rowCount = multiColumn ? Math.ceil(safeItems.length / columns) : safeItems.length;
|
|
59
|
+
var _useVirtualList = useVirtualList({
|
|
60
|
+
itemCount: useVirtual ? rowCount : 0,
|
|
61
|
+
itemHeight: itemHeight,
|
|
62
|
+
overscan: 4
|
|
63
|
+
}),
|
|
64
|
+
start = _useVirtualList.start,
|
|
65
|
+
end = _useVirtualList.end,
|
|
66
|
+
offsetY = _useVirtualList.offsetY,
|
|
67
|
+
totalHeight = _useVirtualList.totalHeight,
|
|
68
|
+
viewportRef = _useVirtualList.viewportRef,
|
|
69
|
+
onScroll = _useVirtualList.onScroll;
|
|
70
|
+
var cls = clsx(prefixCls, _defineProperty(_defineProperty({}, "".concat(prefixCls, "-bordered"), bordered), "".concat(prefixCls, "-grid"), multiColumn && !useVirtual), className);
|
|
71
|
+
var renderItem = function renderItem(item, index) {
|
|
72
|
+
if (typeof itemRender === 'function') {
|
|
73
|
+
return itemRender(item);
|
|
74
|
+
}
|
|
75
|
+
return /*#__PURE__*/React.createElement(ListItem, _extends({}, item, {
|
|
76
|
+
$key: item.key,
|
|
77
|
+
key: item.key || index
|
|
78
|
+
}));
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// ----- Virtual + multi-column: render rows of N items -----
|
|
82
|
+
if (useVirtual && multiColumn) {
|
|
83
|
+
var visibleRows = [];
|
|
84
|
+
for (var rowIdx = start; rowIdx < end; rowIdx++) {
|
|
85
|
+
var rowItems = [];
|
|
86
|
+
for (var col = 0; col < columns; col++) {
|
|
87
|
+
var flatIdx = rowIdx * columns + col;
|
|
88
|
+
if (flatIdx < safeItems.length) {
|
|
89
|
+
rowItems.push({
|
|
90
|
+
item: safeItems[flatIdx],
|
|
91
|
+
flatIdx: flatIdx
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
visibleRows.push({
|
|
96
|
+
rowIdx: rowIdx,
|
|
97
|
+
rowItems: rowItems
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return /*#__PURE__*/React.createElement("ul", _extends({
|
|
101
|
+
ref: ref,
|
|
102
|
+
className: cls,
|
|
103
|
+
tabIndex: 0,
|
|
104
|
+
"aria-label": "list",
|
|
105
|
+
onKeyDown: onKeyDown
|
|
106
|
+
}, rest), /*#__PURE__*/React.createElement(ListCtx.Provider, {
|
|
107
|
+
value: {
|
|
108
|
+
prefixCls: prefixCls,
|
|
109
|
+
focusedKey: focusedKey,
|
|
110
|
+
onClick: onClick
|
|
111
|
+
}
|
|
112
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
113
|
+
ref: viewportRef,
|
|
114
|
+
onScroll: onScroll,
|
|
115
|
+
style: {
|
|
116
|
+
height: height,
|
|
117
|
+
overflowY: 'auto'
|
|
34
118
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
119
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
120
|
+
style: {
|
|
121
|
+
height: totalHeight,
|
|
122
|
+
position: 'relative'
|
|
123
|
+
}
|
|
124
|
+
}, visibleRows.map(function (_ref, ri) {
|
|
125
|
+
var rowIdx = _ref.rowIdx,
|
|
126
|
+
rowItems = _ref.rowItems;
|
|
127
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
128
|
+
key: rowIdx,
|
|
129
|
+
className: "".concat(prefixCls, "-grid-row"),
|
|
130
|
+
style: {
|
|
131
|
+
position: 'absolute',
|
|
132
|
+
top: 0,
|
|
133
|
+
left: 0,
|
|
134
|
+
right: 0,
|
|
135
|
+
height: itemHeight,
|
|
136
|
+
transform: "translateY(".concat(offsetY + ri * itemHeight, "px)"),
|
|
137
|
+
display: 'grid',
|
|
138
|
+
gridTemplateColumns: "repeat(".concat(columns, ", 1fr)")
|
|
139
|
+
}
|
|
140
|
+
}, rowItems.map(function (_ref2) {
|
|
141
|
+
var item = _ref2.item,
|
|
142
|
+
flatIdx = _ref2.flatIdx;
|
|
143
|
+
return renderItem(item, flatIdx);
|
|
38
144
|
}));
|
|
39
|
-
})
|
|
40
|
-
}
|
|
145
|
+
})))));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// ----- Virtual single-column -----
|
|
149
|
+
if (useVirtual) {
|
|
150
|
+
var slicedItems = safeItems.slice(start, end);
|
|
151
|
+
return /*#__PURE__*/React.createElement("ul", _extends({
|
|
152
|
+
ref: ref,
|
|
153
|
+
className: cls,
|
|
154
|
+
tabIndex: 0,
|
|
155
|
+
"aria-label": "list",
|
|
156
|
+
onKeyDown: onKeyDown
|
|
157
|
+
}, rest), /*#__PURE__*/React.createElement(ListCtx.Provider, {
|
|
158
|
+
value: {
|
|
159
|
+
prefixCls: prefixCls,
|
|
160
|
+
focusedKey: focusedKey,
|
|
161
|
+
onClick: onClick
|
|
162
|
+
}
|
|
163
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
164
|
+
ref: viewportRef,
|
|
165
|
+
onScroll: onScroll,
|
|
166
|
+
style: {
|
|
167
|
+
height: height,
|
|
168
|
+
overflowY: 'auto'
|
|
169
|
+
}
|
|
170
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
171
|
+
style: {
|
|
172
|
+
height: totalHeight,
|
|
173
|
+
position: 'relative'
|
|
174
|
+
}
|
|
175
|
+
}, slicedItems.map(function (item, i) {
|
|
176
|
+
var element = renderItem(item, start + i);
|
|
177
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
178
|
+
key: item.key || start + i,
|
|
179
|
+
style: {
|
|
180
|
+
position: 'absolute',
|
|
181
|
+
top: 0,
|
|
182
|
+
left: 0,
|
|
183
|
+
width: '100%',
|
|
184
|
+
height: itemHeight,
|
|
185
|
+
transform: "translateY(".concat(offsetY + i * itemHeight, "px)")
|
|
186
|
+
}
|
|
187
|
+
}, element);
|
|
188
|
+
})))));
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// ----- Default mode (non-virtual) -----
|
|
41
192
|
return /*#__PURE__*/React.createElement("ul", _extends({
|
|
42
193
|
ref: ref,
|
|
43
194
|
className: cls,
|
|
44
195
|
tabIndex: 0,
|
|
45
|
-
"aria-label": "list"
|
|
196
|
+
"aria-label": "list",
|
|
197
|
+
onKeyDown: onKeyDown,
|
|
198
|
+
style: multiColumn ? _objectSpread({
|
|
199
|
+
'--yee-list-columns': columns
|
|
200
|
+
}, style) : style
|
|
46
201
|
}, rest), /*#__PURE__*/React.createElement(ListCtx.Provider, {
|
|
47
202
|
value: {
|
|
48
203
|
prefixCls: prefixCls,
|
|
49
204
|
focusedKey: focusedKey,
|
|
50
205
|
onClick: onClick
|
|
51
206
|
}
|
|
52
|
-
},
|
|
207
|
+
}, safeItems.map(function (item, index) {
|
|
208
|
+
return renderItem(item, index);
|
|
209
|
+
})));
|
|
53
210
|
});
|
|
54
211
|
List.displayName = 'List';
|
|
55
212
|
export default List;
|
|
@@ -6,18 +6,42 @@
|
|
|
6
6
|
list-style: none;
|
|
7
7
|
background-color: var(--yee-list-bg-color);
|
|
8
8
|
|
|
9
|
+
&:focus {
|
|
10
|
+
outline: none;
|
|
11
|
+
}
|
|
12
|
+
|
|
9
13
|
&-item {
|
|
10
14
|
padding: var(--yee-list-item-padding);
|
|
11
15
|
|
|
12
16
|
&:hover:not(&-disabled) {
|
|
13
17
|
background-color: var(--yee-list-item-bg-hover-color);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&-disabled {
|
|
14
21
|
cursor: not-allowed;
|
|
22
|
+
opacity: 0.5;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
&-clickable:not(&-disabled) {
|
|
26
|
+
cursor: pointer;
|
|
15
27
|
}
|
|
16
28
|
|
|
17
29
|
&-focused {
|
|
18
30
|
background-color: var(--yee-list-item-bg-hover-color);
|
|
19
31
|
}
|
|
20
32
|
}
|
|
33
|
+
|
|
34
|
+
// Multi-column grid layout (non-virtual mode).
|
|
35
|
+
// Column count driven by CSS custom property --yee-list-columns set inline.
|
|
36
|
+
&-grid {
|
|
37
|
+
display: grid;
|
|
38
|
+
grid-template-columns: repeat(var(--yee-list-columns, 1), 1fr);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Virtual multi-column: each row is already a grid via inline style.
|
|
42
|
+
&-grid-row {
|
|
43
|
+
align-items: center;
|
|
44
|
+
}
|
|
21
45
|
}
|
|
22
46
|
|
|
23
47
|
@{pls}-bordered {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Select } from "../..";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
var options = Array.from({
|
|
4
|
+
length: 24
|
|
5
|
+
}, function (_, i) {
|
|
6
|
+
return {
|
|
7
|
+
label: "Option ".concat(i + 1),
|
|
8
|
+
value: "opt-".concat(i + 1)
|
|
9
|
+
};
|
|
10
|
+
});
|
|
11
|
+
export default (function () {
|
|
12
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
13
|
+
style: {
|
|
14
|
+
display: 'flex',
|
|
15
|
+
flexDirection: 'column',
|
|
16
|
+
gap: 24
|
|
17
|
+
}
|
|
18
|
+
}, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("p", null, "3 columns:"), /*#__PURE__*/React.createElement(Select, {
|
|
19
|
+
columns: 3,
|
|
20
|
+
popupWidth: 360,
|
|
21
|
+
options: options,
|
|
22
|
+
placeholder: "Select an option",
|
|
23
|
+
style: {
|
|
24
|
+
width: 200
|
|
25
|
+
}
|
|
26
|
+
})), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("p", null, "4 columns with multiple selection:"), /*#__PURE__*/React.createElement(Select, {
|
|
27
|
+
columns: 4,
|
|
28
|
+
popupWidth: 480,
|
|
29
|
+
mode: "multiple",
|
|
30
|
+
options: options,
|
|
31
|
+
placeholder: "Select options",
|
|
32
|
+
style: {
|
|
33
|
+
width: 300
|
|
34
|
+
}
|
|
35
|
+
})));
|
|
36
|
+
});
|
|
@@ -7,6 +7,18 @@ interface UseSelectKeyboardParams {
|
|
|
7
7
|
}>;
|
|
8
8
|
open: boolean;
|
|
9
9
|
selectedKeys: Array<string | number>;
|
|
10
|
+
/**
|
|
11
|
+
* Number of columns in multi-column mode.
|
|
12
|
+
* Affects ArrowLeft/ArrowRight and ArrowUp/ArrowDown behavior.
|
|
13
|
+
* @default 1
|
|
14
|
+
*/
|
|
15
|
+
columns?: number;
|
|
16
|
+
/**
|
|
17
|
+
* Whether loose value matching is enabled.
|
|
18
|
+
* Affects initial focus resolution when selectedKeys types differ from option values.
|
|
19
|
+
* @default false
|
|
20
|
+
*/
|
|
21
|
+
looseMatch?: boolean;
|
|
10
22
|
onSelect: (value: string | number) => void;
|
|
11
23
|
onClose?: () => void;
|
|
12
24
|
onOpenChange?: (open: boolean) => void;
|
|
@@ -18,7 +30,7 @@ interface UseSelectKeyboardParams {
|
|
|
18
30
|
*/
|
|
19
31
|
scrollToIndex?: (index: number) => void;
|
|
20
32
|
}
|
|
21
|
-
export default function useSelectKeyboard({ options, open, selectedKeys, onSelect, onClose, onOpenChange, containerRef, scrollToIndex, }: UseSelectKeyboardParams): {
|
|
33
|
+
export default function useSelectKeyboard({ options, open, selectedKeys, columns, looseMatch, onSelect, onClose, onOpenChange, containerRef, scrollToIndex, }: UseSelectKeyboardParams): {
|
|
22
34
|
focusedKey: string | number;
|
|
23
35
|
onKeyDown: (event: React.KeyboardEvent) => void;
|
|
24
36
|
};
|