@rainbow-oh/yee-c 0.6.3 → 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.
Files changed (131) hide show
  1. package/dist/cjs/Button/style/index.less +5 -4
  2. package/dist/cjs/Checkbox/style/index.less +1 -1
  3. package/dist/cjs/Drawer/drawer.js +1 -1
  4. package/dist/cjs/Drawer/interface.d.ts +1 -1
  5. package/dist/cjs/Drawer/style/index.less +1 -0
  6. package/dist/cjs/List/demo/virtual.d.ts +3 -0
  7. package/dist/cjs/List/demo/virtual.js +53 -0
  8. package/dist/cjs/List/hooks/useListKeyboard.d.ts +28 -0
  9. package/dist/cjs/List/hooks/useListKeyboard.js +188 -0
  10. package/dist/cjs/List/interface.d.ts +29 -2
  11. package/dist/cjs/List/list.js +141 -21
  12. package/dist/cjs/List/style/index.less +24 -0
  13. package/dist/cjs/Select/demo/columns.d.ts +3 -0
  14. package/dist/cjs/Select/demo/columns.js +62 -0
  15. package/dist/cjs/Select/hooks/useSelectKeyboard.d.ts +13 -1
  16. package/dist/cjs/Select/hooks/useSelectKeyboard.js +81 -10
  17. package/dist/cjs/Select/interface.d.ts +30 -3
  18. package/dist/cjs/Select/option.js +4 -3
  19. package/dist/cjs/Select/options.js +90 -8
  20. package/dist/cjs/Select/select.js +32 -8
  21. package/dist/cjs/Select/style/index.less +14 -0
  22. package/dist/cjs/Selector/interface.d.ts +4 -0
  23. package/dist/cjs/Selector/selector.js +5 -3
  24. package/dist/cjs/Table/interface.d.ts +1 -1
  25. package/dist/cjs/Table/style/index.less +1 -1
  26. package/dist/cjs/Tree/demo/draggable.js +2 -0
  27. package/dist/cjs/Tree/interface.d.ts +46 -23
  28. package/dist/cjs/Tree/tree-node.d.ts +1 -1
  29. package/dist/cjs/Tree/tree-node.js +30 -23
  30. package/dist/cjs/Tree/tree.d.ts +13 -12
  31. package/dist/cjs/Tree/tree.js +452 -227
  32. package/dist/cjs/Tree/utils/tree-tools.d.ts +43 -10
  33. package/dist/cjs/Tree/utils/tree-tools.js +129 -91
  34. package/dist/cjs/locale/context.d.ts +5 -4
  35. package/dist/cjs/locale/context.js +15 -8
  36. package/dist/cjs/locale/interface.d.ts +20 -0
  37. package/dist/cjs/locale/util.d.ts +3 -3
  38. package/dist/cjs/style/color.css +1 -0
  39. package/dist/cjs/style/size.css +2 -1
  40. package/dist/cjs/style/themes.css +1 -1
  41. package/dist/cjs/style/variables.css +4 -2
  42. package/dist/cjs/utils/isEqual.d.ts +1 -1
  43. package/dist/cjs/utils/isEqual.js +24 -13
  44. package/dist/cjs/version.d.ts +1 -1
  45. package/dist/cjs/version.js +1 -1
  46. package/dist/esm/Button/style/index.less +5 -4
  47. package/dist/esm/Checkbox/style/index.less +1 -1
  48. package/dist/esm/Drawer/drawer.js +2 -1
  49. package/dist/esm/Drawer/interface.d.ts +1 -1
  50. package/dist/esm/Drawer/style/index.less +1 -0
  51. package/dist/esm/List/demo/virtual.d.ts +3 -0
  52. package/dist/esm/List/demo/virtual.js +22 -0
  53. package/dist/esm/List/hooks/useListKeyboard.d.ts +28 -0
  54. package/dist/esm/List/hooks/useListKeyboard.js +173 -0
  55. package/dist/esm/List/interface.d.ts +29 -2
  56. package/dist/esm/List/list.js +171 -14
  57. package/dist/esm/List/style/index.less +24 -0
  58. package/dist/esm/Select/demo/columns.d.ts +3 -0
  59. package/dist/esm/Select/demo/columns.js +36 -0
  60. package/dist/esm/Select/hooks/useSelectKeyboard.d.ts +13 -1
  61. package/dist/esm/Select/hooks/useSelectKeyboard.js +91 -14
  62. package/dist/esm/Select/interface.d.ts +30 -3
  63. package/dist/esm/Select/option.js +6 -2
  64. package/dist/esm/Select/options.js +114 -32
  65. package/dist/esm/Select/select.js +40 -11
  66. package/dist/esm/Select/style/index.less +14 -0
  67. package/dist/esm/Selector/interface.d.ts +4 -0
  68. package/dist/esm/Selector/selector.js +10 -4
  69. package/dist/esm/Table/interface.d.ts +1 -1
  70. package/dist/esm/Table/style/index.less +1 -1
  71. package/dist/esm/Tree/demo/draggable.js +2 -0
  72. package/dist/esm/Tree/interface.d.ts +46 -23
  73. package/dist/esm/Tree/tree-node.d.ts +1 -1
  74. package/dist/esm/Tree/tree-node.js +26 -31
  75. package/dist/esm/Tree/tree.d.ts +13 -12
  76. package/dist/esm/Tree/tree.js +572 -163
  77. package/dist/esm/Tree/utils/tree-tools.d.ts +43 -10
  78. package/dist/esm/Tree/utils/tree-tools.js +219 -104
  79. package/dist/esm/locale/context.d.ts +5 -4
  80. package/dist/esm/locale/context.js +25 -9
  81. package/dist/esm/locale/interface.d.ts +20 -0
  82. package/dist/esm/locale/util.d.ts +3 -3
  83. package/dist/esm/style/color.css +1 -0
  84. package/dist/esm/style/size.css +2 -1
  85. package/dist/esm/style/themes.css +1 -1
  86. package/dist/esm/style/variables.css +4 -2
  87. package/dist/esm/utils/isEqual.d.ts +1 -1
  88. package/dist/esm/utils/isEqual.js +31 -15
  89. package/dist/esm/version.d.ts +1 -1
  90. package/dist/esm/version.js +1 -1
  91. package/dist/umd/yee-c.min.css +2 -2
  92. package/dist/umd/yee-c.min.js +1 -1
  93. package/package.json +1 -1
  94. package/src/Button/style/index.less +5 -4
  95. package/src/Checkbox/style/index.less +1 -1
  96. package/src/Drawer/drawer.tsx +1 -1
  97. package/src/Drawer/interface.ts +1 -0
  98. package/src/Drawer/style/index.less +1 -0
  99. package/src/List/demo/virtual.tsx +20 -0
  100. package/src/List/hooks/useListKeyboard.ts +235 -0
  101. package/src/List/index.en-US.md +6 -0
  102. package/src/List/index.zh-CN.md +6 -0
  103. package/src/List/interface.ts +29 -2
  104. package/src/List/list.tsx +157 -19
  105. package/src/List/style/index.less +24 -0
  106. package/src/Select/demo/columns.tsx +35 -0
  107. package/src/Select/hooks/useSelectKeyboard.ts +112 -15
  108. package/src/Select/index.en-US.md +4 -0
  109. package/src/Select/index.zh-CN.md +4 -0
  110. package/src/Select/interface.ts +31 -4
  111. package/src/Select/option.tsx +9 -3
  112. package/src/Select/options.tsx +119 -26
  113. package/src/Select/select.tsx +41 -8
  114. package/src/Select/style/index.less +14 -0
  115. package/src/Selector/interface.ts +4 -0
  116. package/src/Selector/selector.tsx +8 -3
  117. package/src/Table/interface.ts +1 -1
  118. package/src/Table/style/index.less +1 -1
  119. package/src/Tree/demo/draggable.tsx +2 -0
  120. package/src/Tree/interface.ts +46 -23
  121. package/src/Tree/tree-node.tsx +26 -29
  122. package/src/Tree/tree.tsx +573 -274
  123. package/src/Tree/utils/tree-tools.ts +231 -125
  124. package/src/locale/_README.md +22 -13
  125. package/src/locale/context.tsx +33 -16
  126. package/src/locale/interface.ts +24 -0
  127. package/src/locale/util.ts +6 -6
  128. package/src/style/color.css +1 -0
  129. package/src/style/size.css +2 -1
  130. package/src/utils/isEqual.ts +35 -14
  131. package/src/version.ts +1 -1
@@ -171,7 +171,7 @@
171
171
  --m-btn-hover-color: var(--yee-primary-color-hover);
172
172
  --m-btn-active-color: var(--yee-primary-color-active);
173
173
  --m-btn-bg-color: var(--yee-btn-primary-bg-color);
174
- --m-btn-hover-bg-color: var(--yee-primary-color-hover);
174
+ --m-btn-hover-bg-color: var(--yee-primary-color-border);
175
175
  --m-btn-active-bg-color: var(--yee-primary-color-active);
176
176
  --m-btn-border-color: var(--yee-primary-color);
177
177
  --m-btn-border-hover-color: var(--yee-primary-color-hover);
@@ -186,7 +186,7 @@
186
186
  --m-btn-border-color: var(--yee-success-color);
187
187
  --m-btn-border-hover-color: var(--yee-success-color-hover);
188
188
  --m-btn-border-active-color: var(--yee-success-color-active);
189
- --m-btn-hover-bg-color: var(--yee-success-color-hover);
189
+ --m-btn-hover-bg-color: var(--yee-success-color-border);
190
190
  --m-btn-active-bg-color: var(--yee-success-color-active);
191
191
  --m-btn-active-shadow-color: var(--yee-success-color-active);
192
192
  }
@@ -198,7 +198,8 @@
198
198
  --m-btn-border-color: var(--yee-error-color);
199
199
  --m-btn-border-hover-color: var(--yee-error-color-hover);
200
200
  --m-btn-border-active-color: var(--yee-error-color-active);
201
- --m-btn-hover-bg-color: var(--yee-error-color-hover);
201
+ // --m-btn-hover-bg-color: var(--yee-error-color-hover);
202
+ --m-btn-hover-bg-color: var(--yee-error-color-border);
202
203
  --m-btn-active-bg-color: var(--yee-error-color-active);
203
204
  --m-btn-active-shadow-color: var(--yee-error-color-active);
204
205
  }
@@ -210,7 +211,7 @@
210
211
  --m-btn-border-color: var(--yee-warning-color);
211
212
  --m-btn-border-hover-color: var(--yee-warning-color-hover);
212
213
  --m-btn-border-active-color: var(--yee-warning-color-active);
213
- --m-btn-hover-bg-color: var(--yee-warning-color-hover);
214
+ --m-btn-hover-bg-color: var(--yee-warning-color-border);
214
215
  --m-btn-active-bg-color: var(--yee-warning-color-active);
215
216
  --m-btn-active-shadow-color: var(--yee-warning-color-active);
216
217
  }
@@ -63,7 +63,7 @@
63
63
  border-color: var(--yee-checkbox-border-color);
64
64
  }
65
65
 
66
- &&-checked {
66
+ &@{pls}-checked {
67
67
  @{pls}-inner {
68
68
  --ye-checkbox-checked-border-color: var(
69
69
  --yee-checkbox-disabled-checked-border-color
@@ -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
@@ -38,6 +38,7 @@
38
38
  }
39
39
 
40
40
  &-title {
41
+ font-size: var(--yee-drawer-title-font-size);
41
42
  font-weight: var(--yee-drawer-title-font-weight);
42
43
  }
43
44
 
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const _default: () => React.JSX.Element;
3
+ export default _default;
@@ -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;
@@ -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
- focusedKey = props.focusedKey,
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 cls = clsx(prefixCls, _defineProperty({}, "".concat(prefixCls, "-bordered"), bordered), className);
30
- var itemRenders = function itemRenders() {
31
- return Array.isArray(items) ? items.map(function (item, index) {
32
- if (typeof itemRender === 'function') {
33
- return itemRender(item);
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
- return /*#__PURE__*/React.createElement(ListItem, _extends({}, item, {
36
- $key: item.key,
37
- key: item.key || index
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
- }) : null;
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
- }, itemRenders()));
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,3 @@
1
+ import React from 'react';
2
+ declare const _default: () => React.JSX.Element;
3
+ export default _default;
@@ -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
+ });