@rescui/tab-list 0.18.5-RUI-308-Fix-select-issues-405b9fa40.12 → 0.19.1
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/lib/_virtual/index.css.js +12 -12
- package/lib/_virtual/left-outline.js +294 -63
- package/lib/_virtual/right-outline.js +294 -63
- package/lib/index.css +79 -79
- package/lib/parts/separator.p.module.css.js +3 -3
- package/lib/parts/tab-list-context.js +3 -1
- package/lib/parts/tab-list.p.module.css.js +25 -25
- package/lib/parts/tab-separator.js +30 -6
- package/lib/parts/tab.js +191 -47
- package/lib/parts/use-indicator.js +130 -44
- package/lib/parts/use-roving-tab-index.js +51 -27
- package/lib/parts/use-scrollable-list.js +272 -131
- package/lib/tab-list.d.ts +1 -1
- package/lib/tab-list.js +377 -79
- package/package.json +13 -12
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import
|
|
2
|
+
import { c } from 'react-compiler-runtime';
|
|
3
|
+
import React, { useRef, useState, useEffect, cloneElement } from 'react';
|
|
3
4
|
import { useResizeObserver } from '@rescui/use-resize-observer';
|
|
4
|
-
import { deepMap } from './deep-map.js';
|
|
5
|
-
|
|
5
|
+
import { deepMap } from './deep-map.js';
|
|
6
6
|
const ARROW_AREA_WIDTH_IN_PX = 54;
|
|
7
7
|
|
|
8
8
|
function patchItemIfNeeded(_ref) {
|
|
@@ -109,18 +109,79 @@ function scrollIntoView(activeNode, parentNode) {
|
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
let
|
|
112
|
+
function getChildrenWithValues(children, compareValues, value, CompareItem, onFocus, createTabRef) {
|
|
113
|
+
let counter = 0;
|
|
114
|
+
let currentSelectedItemId = null;
|
|
115
|
+
const items = deepMap(children, child => {
|
|
116
|
+
if (child.type === CompareItem) {
|
|
117
|
+
const {
|
|
118
|
+
value: childValue = counter,
|
|
119
|
+
onFocus: onFocusFromProps,
|
|
120
|
+
...restProps
|
|
121
|
+
} = child.props;
|
|
122
|
+
const hasAlreadySelectedItem = currentSelectedItemId === null;
|
|
123
|
+
const isSelectedItem = hasAlreadySelectedItem && compareValues(value, childValue);
|
|
124
|
+
|
|
125
|
+
if (isSelectedItem) {
|
|
126
|
+
currentSelectedItemId = counter;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const setTabRef = createTabRef(counter, isSelectedItem);
|
|
130
|
+
const patchedItem = patchItemIfNeeded({
|
|
131
|
+
child,
|
|
132
|
+
itemId: counter,
|
|
133
|
+
childValue,
|
|
134
|
+
...restProps,
|
|
135
|
+
onFocus: event => {
|
|
136
|
+
if (onFocusFromProps) {
|
|
137
|
+
onFocusFromProps(event);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
onFocus(event);
|
|
141
|
+
},
|
|
142
|
+
ref: node => {
|
|
143
|
+
setTabRef(node);
|
|
144
|
+
const childRef = child.ref;
|
|
145
|
+
|
|
146
|
+
if (typeof childRef === 'function') {
|
|
147
|
+
childRef(node);
|
|
148
|
+
} else if (childRef) {
|
|
149
|
+
childRef.current = node;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
counter += 1;
|
|
154
|
+
return patchedItem;
|
|
155
|
+
} else {
|
|
156
|
+
return child;
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
return {
|
|
160
|
+
childrenWithValues: React.Children.toArray(items),
|
|
161
|
+
selectedId: currentSelectedItemId
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const useScrollableList = t0 => {
|
|
166
|
+
const $ = c(32);
|
|
167
|
+
const {
|
|
114
168
|
children,
|
|
115
169
|
compareValues,
|
|
116
170
|
value,
|
|
117
171
|
CompareItem,
|
|
118
172
|
scrollableRef,
|
|
119
173
|
containerRef
|
|
120
|
-
} =
|
|
121
|
-
|
|
122
|
-
// so on window resize there wouldn't scroll to it
|
|
174
|
+
} = t0;
|
|
175
|
+
let t1;
|
|
123
176
|
|
|
177
|
+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
178
|
+
t1 = new Map();
|
|
179
|
+
$[0] = t1;
|
|
180
|
+
} else {
|
|
181
|
+
t1 = $[0];
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const tabRefs = useRef(t1);
|
|
124
185
|
const [targetedEl, setTargetedEl] = useState(null);
|
|
125
186
|
const [activeNode, setActiveNode] = useState(null);
|
|
126
187
|
const [prevActiveNode, setPrevActiveNode] = useState(null);
|
|
@@ -130,144 +191,224 @@ const useScrollableList = _ref2 => {
|
|
|
130
191
|
setTargetedEl(activeNode);
|
|
131
192
|
}
|
|
132
193
|
|
|
133
|
-
|
|
194
|
+
let t2;
|
|
195
|
+
|
|
196
|
+
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
|
197
|
+
t2 = {
|
|
198
|
+
showLeftArrow: false,
|
|
199
|
+
showRightArrow: false
|
|
200
|
+
};
|
|
201
|
+
$[1] = t2;
|
|
202
|
+
} else {
|
|
203
|
+
t2 = $[1];
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const [t3, setShowArrows] = useState(t2);
|
|
207
|
+
const {
|
|
134
208
|
showLeftArrow,
|
|
135
209
|
showRightArrow
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
showRightArrow: false
|
|
139
|
-
});
|
|
140
|
-
const onFocus = useCallback(e => {
|
|
141
|
-
setTargetedEl(e.target);
|
|
142
|
-
}, []);
|
|
143
|
-
const createTabRef = useCallback((itemId, isSelectedItem) => node => {
|
|
144
|
-
if (node) {
|
|
145
|
-
tabRefs.current.set(itemId, node);
|
|
146
|
-
} else {
|
|
147
|
-
tabRefs.current.delete(itemId);
|
|
148
|
-
}
|
|
210
|
+
} = t3;
|
|
211
|
+
let t4;
|
|
149
212
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const [childrenWithValues, selectedId] = useMemo(() => {
|
|
155
|
-
let counter = 0;
|
|
156
|
-
let currentSelectedItemId = null;
|
|
157
|
-
/*
|
|
158
|
-
* deepMap invokes its callback synchronously. The callback ref is created
|
|
159
|
-
* during render, but accesses tabRefs.current only when React invokes it
|
|
160
|
-
* during commit.
|
|
161
|
-
*/
|
|
162
|
-
// eslint-disable-next-line react-hooks/refs
|
|
163
|
-
|
|
164
|
-
const items = deepMap(children, child => {
|
|
165
|
-
if (child.type === CompareItem) {
|
|
166
|
-
const {
|
|
167
|
-
value: childValue = counter,
|
|
168
|
-
onFocus: onFocusFromProps,
|
|
169
|
-
...restProps
|
|
170
|
-
} = child.props;
|
|
171
|
-
const hasAlreadySelectedItem = currentSelectedItemId === null;
|
|
172
|
-
const isSelectedItem = hasAlreadySelectedItem && compareValues(value, childValue);
|
|
173
|
-
|
|
174
|
-
if (isSelectedItem) {
|
|
175
|
-
// same explanation as above
|
|
176
|
-
// eslint-disable-next-line react-hooks/immutability
|
|
177
|
-
currentSelectedItemId = counter;
|
|
178
|
-
}
|
|
213
|
+
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
214
|
+
t4 = e => {
|
|
215
|
+
setTargetedEl(e.target);
|
|
216
|
+
};
|
|
179
217
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
},
|
|
193
|
-
ref: node => {
|
|
194
|
-
setTabRef(node);
|
|
195
|
-
const childRef = child.ref;
|
|
196
|
-
|
|
197
|
-
if (typeof childRef === 'function') {
|
|
198
|
-
childRef(node);
|
|
199
|
-
} else if (childRef) {
|
|
200
|
-
childRef.current = node;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
counter += 1;
|
|
205
|
-
return patchedItem;
|
|
218
|
+
$[2] = t4;
|
|
219
|
+
} else {
|
|
220
|
+
t4 = $[2];
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const onFocus = t4;
|
|
224
|
+
let t5;
|
|
225
|
+
|
|
226
|
+
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
|
|
227
|
+
t5 = (itemId, isSelectedItem) => node => {
|
|
228
|
+
if (node) {
|
|
229
|
+
tabRefs.current.set(itemId, node);
|
|
206
230
|
} else {
|
|
207
|
-
|
|
231
|
+
tabRefs.current.delete(itemId);
|
|
208
232
|
}
|
|
209
|
-
});
|
|
210
|
-
return [React.Children.toArray(items), currentSelectedItemId];
|
|
211
|
-
}, [children, value, compareValues, onFocus, CompareItem, createTabRef]);
|
|
212
|
-
const prepareDirectionScroller = useCallback(direction => () => {
|
|
213
|
-
const {
|
|
214
|
-
current
|
|
215
|
-
} = scrollableRef;
|
|
216
|
-
const left = Math.max(current.clientWidth - 2 * ARROW_AREA_WIDTH_IN_PX, 30) * (direction === 'right' ? 1 : -1);
|
|
217
|
-
setTargetedEl(null);
|
|
218
|
-
scrollElementBy(current, left);
|
|
219
|
-
}, [scrollableRef]);
|
|
220
|
-
const setArrowsVisibility = useCallback(() => {
|
|
221
|
-
if (!scrollableRef.current) {
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
233
|
|
|
225
|
-
|
|
226
|
-
|
|
234
|
+
if (isSelectedItem) {
|
|
235
|
+
setActiveNode(node);
|
|
236
|
+
}
|
|
237
|
+
};
|
|
227
238
|
|
|
228
|
-
|
|
229
|
-
|
|
239
|
+
$[3] = t5;
|
|
240
|
+
} else {
|
|
241
|
+
t5 = $[3];
|
|
242
|
+
}
|
|
230
243
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
244
|
+
const createTabRef = t5;
|
|
245
|
+
let t6;
|
|
234
246
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
247
|
+
if ($[4] !== CompareItem || $[5] !== children || $[6] !== compareValues || $[7] !== value) {
|
|
248
|
+
t6 = getChildrenWithValues(children, compareValues, value, CompareItem, onFocus, createTabRef);
|
|
249
|
+
$[4] = CompareItem;
|
|
250
|
+
$[5] = children;
|
|
251
|
+
$[6] = compareValues;
|
|
252
|
+
$[7] = value;
|
|
253
|
+
$[8] = t6;
|
|
254
|
+
} else {
|
|
255
|
+
t6 = $[8];
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const {
|
|
259
|
+
childrenWithValues,
|
|
260
|
+
selectedId
|
|
261
|
+
} = t6;
|
|
262
|
+
let t7;
|
|
263
|
+
|
|
264
|
+
if ($[9] !== scrollableRef) {
|
|
265
|
+
t7 = direction => () => {
|
|
266
|
+
const {
|
|
267
|
+
current
|
|
268
|
+
} = scrollableRef;
|
|
269
|
+
const left = Math.max(current.clientWidth - 2 * ARROW_AREA_WIDTH_IN_PX, 30) * (direction === "right" ? 1 : -1);
|
|
270
|
+
setTargetedEl(null);
|
|
271
|
+
scrollElementBy(current, left);
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
$[9] = scrollableRef;
|
|
275
|
+
$[10] = t7;
|
|
276
|
+
} else {
|
|
277
|
+
t7 = $[10];
|
|
278
|
+
}
|
|
240
279
|
|
|
241
|
-
const
|
|
242
|
-
|
|
280
|
+
const prepareDirectionScroller = t7;
|
|
281
|
+
let t8;
|
|
243
282
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
283
|
+
if ($[11] !== scrollableRef) {
|
|
284
|
+
t8 = () => {
|
|
285
|
+
if (!scrollableRef.current) {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
247
288
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
289
|
+
setShowArrows(calculateArrowsVisibility(scrollableRef.current));
|
|
290
|
+
};
|
|
251
291
|
|
|
252
|
-
|
|
253
|
-
|
|
292
|
+
$[11] = scrollableRef;
|
|
293
|
+
$[12] = t8;
|
|
294
|
+
} else {
|
|
295
|
+
t8 = $[12];
|
|
296
|
+
}
|
|
254
297
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
298
|
+
const setArrowsVisibility = t8;
|
|
299
|
+
let t10;
|
|
300
|
+
let t9;
|
|
301
|
+
|
|
302
|
+
if ($[13] !== scrollableRef || $[14] !== setArrowsVisibility) {
|
|
303
|
+
t9 = () => {
|
|
304
|
+
const scrollContainer = scrollableRef.current;
|
|
305
|
+
|
|
306
|
+
if (!scrollContainer) {
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
scrollContainer.addEventListener("scroll", setArrowsVisibility, {
|
|
311
|
+
passive: true
|
|
312
|
+
});
|
|
313
|
+
return () => scrollContainer.removeEventListener("scroll", setArrowsVisibility);
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
t10 = [scrollableRef, setArrowsVisibility];
|
|
317
|
+
$[13] = scrollableRef;
|
|
318
|
+
$[14] = setArrowsVisibility;
|
|
319
|
+
$[15] = t10;
|
|
320
|
+
$[16] = t9;
|
|
321
|
+
} else {
|
|
322
|
+
t10 = $[15];
|
|
323
|
+
t9 = $[16];
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
useEffect(t9, t10);
|
|
327
|
+
let t11;
|
|
328
|
+
|
|
329
|
+
if ($[17] !== scrollableRef || $[18] !== setArrowsVisibility || $[19] !== targetedEl) {
|
|
330
|
+
t11 = () => {
|
|
331
|
+
const scrollableEl = scrollableRef.current;
|
|
332
|
+
|
|
333
|
+
if (!scrollableEl) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (targetedEl) {
|
|
338
|
+
scrollIntoView(targetedEl, scrollableEl);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
setArrowsVisibility();
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
$[17] = scrollableRef;
|
|
345
|
+
$[18] = setArrowsVisibility;
|
|
346
|
+
$[19] = targetedEl;
|
|
347
|
+
$[20] = t11;
|
|
348
|
+
} else {
|
|
349
|
+
t11 = $[20];
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const updateScrollState = t11;
|
|
353
|
+
let t12;
|
|
354
|
+
|
|
355
|
+
if ($[21] === Symbol.for("react.memo_cache_sentinel")) {
|
|
356
|
+
t12 = {
|
|
357
|
+
ignoreFirstCall: true
|
|
358
|
+
};
|
|
359
|
+
$[21] = t12;
|
|
360
|
+
} else {
|
|
361
|
+
t12 = $[21];
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
useResizeObserver(containerRef, updateScrollState, t12);
|
|
365
|
+
let t13;
|
|
366
|
+
|
|
367
|
+
if ($[22] === Symbol.for("react.memo_cache_sentinel")) {
|
|
368
|
+
t13 = {
|
|
369
|
+
ignoreFirstCall: true
|
|
370
|
+
};
|
|
371
|
+
$[22] = t13;
|
|
372
|
+
} else {
|
|
373
|
+
t13 = $[22];
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
useResizeObserver(scrollableRef, updateScrollState, t13);
|
|
377
|
+
let t14;
|
|
378
|
+
|
|
379
|
+
if ($[23] !== updateScrollState) {
|
|
380
|
+
t14 = [updateScrollState];
|
|
381
|
+
$[23] = updateScrollState;
|
|
382
|
+
$[24] = t14;
|
|
383
|
+
} else {
|
|
384
|
+
t14 = $[24];
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
useEffect(updateScrollState, t14);
|
|
388
|
+
let t15;
|
|
389
|
+
|
|
390
|
+
if ($[25] !== activeNode || $[26] !== childrenWithValues || $[27] !== prepareDirectionScroller || $[28] !== selectedId || $[29] !== showLeftArrow || $[30] !== showRightArrow) {
|
|
391
|
+
t15 = {
|
|
392
|
+
selectedId,
|
|
393
|
+
activeNode,
|
|
394
|
+
prepareDirectionScroller,
|
|
395
|
+
tabRefs,
|
|
396
|
+
childrenWithValues,
|
|
397
|
+
showLeftArrow,
|
|
398
|
+
showRightArrow
|
|
399
|
+
};
|
|
400
|
+
$[25] = activeNode;
|
|
401
|
+
$[26] = childrenWithValues;
|
|
402
|
+
$[27] = prepareDirectionScroller;
|
|
403
|
+
$[28] = selectedId;
|
|
404
|
+
$[29] = showLeftArrow;
|
|
405
|
+
$[30] = showRightArrow;
|
|
406
|
+
$[31] = t15;
|
|
407
|
+
} else {
|
|
408
|
+
t15 = $[31];
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return t15;
|
|
271
412
|
};
|
|
272
413
|
|
|
273
414
|
export { useScrollableList };
|
package/lib/tab-list.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export type TabListProps<T extends TabListValueType> = {
|
|
|
25
25
|
compareValues?: ScrollableListCompareValueType<T>;
|
|
26
26
|
};
|
|
27
27
|
declare const TabList: {
|
|
28
|
-
<T extends TabListValueType>({ size, sparse, className, mode, short,
|
|
28
|
+
<T extends TabListValueType>({ size, sparse, className, mode, short, "data-e2e": e2eId, compareValues, value, onChange, children, theme: themeFromProps, ...restProps }: TabListProps<T>): React.JSX.Element;
|
|
29
29
|
displayName: string;
|
|
30
30
|
propTypes: {
|
|
31
31
|
size: PropTypes.Requireable<string>;
|