@lensui/lens-table 0.1.76 → 0.1.77
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/index.cjs +33 -6
- package/dist/index.js +33 -6
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -336,6 +336,8 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
336
336
|
const editorRef = (0, import_react2.useRef)(null);
|
|
337
337
|
const popupRef = (0, import_react2.useRef)(null);
|
|
338
338
|
const activeOptionRef = (0, import_react2.useRef)(null);
|
|
339
|
+
const popupReadyRef = (0, import_react2.useRef)(false);
|
|
340
|
+
const navigationSourceRef = (0, import_react2.useRef)(null);
|
|
339
341
|
const originalValueRef = (0, import_react2.useRef)(value);
|
|
340
342
|
const listboxId = (0, import_react2.useId)();
|
|
341
343
|
const originalValue = originalValueRef.current;
|
|
@@ -344,7 +346,10 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
344
346
|
const selectedIndex = options.findIndex((option) => option.value === value);
|
|
345
347
|
return selectedIndex >= 0 ? selectedIndex : 0;
|
|
346
348
|
});
|
|
347
|
-
const [popupStyle, setPopupStyle] = (0, import_react2.useState)({
|
|
349
|
+
const [popupStyle, setPopupStyle] = (0, import_react2.useState)({
|
|
350
|
+
position: "fixed",
|
|
351
|
+
visibility: "hidden"
|
|
352
|
+
});
|
|
348
353
|
const filteredOptions = (0, import_react2.useMemo)(() => {
|
|
349
354
|
const query = inputValue.trim().toLocaleLowerCase();
|
|
350
355
|
if (!query || query === originalValue.toLocaleLowerCase()) return options;
|
|
@@ -362,7 +367,8 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
362
367
|
bottom: window.innerHeight - rect.top + 4,
|
|
363
368
|
left: rect.left,
|
|
364
369
|
width: rect.width,
|
|
365
|
-
maxHeight: Math.min(maxDropdownHeight, availableAbove)
|
|
370
|
+
maxHeight: Math.min(maxDropdownHeight, availableAbove),
|
|
371
|
+
visibility: popupReadyRef.current ? "visible" : "hidden"
|
|
366
372
|
});
|
|
367
373
|
return;
|
|
368
374
|
}
|
|
@@ -371,7 +377,8 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
371
377
|
top: rect.bottom + 4,
|
|
372
378
|
left: rect.left,
|
|
373
379
|
width: rect.width,
|
|
374
|
-
maxHeight: Math.min(maxDropdownHeight, Math.max(80, availableBelow))
|
|
380
|
+
maxHeight: Math.min(maxDropdownHeight, Math.max(80, availableBelow)),
|
|
381
|
+
visibility: popupReadyRef.current ? "visible" : "hidden"
|
|
375
382
|
});
|
|
376
383
|
};
|
|
377
384
|
positionPopup();
|
|
@@ -383,8 +390,22 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
383
390
|
};
|
|
384
391
|
}, [maxDropdownHeight]);
|
|
385
392
|
(0, import_react2.useLayoutEffect)(() => {
|
|
386
|
-
|
|
387
|
-
|
|
393
|
+
if (popupReadyRef.current) return;
|
|
394
|
+
if (popupStyle.top === void 0 && popupStyle.bottom === void 0) return;
|
|
395
|
+
const selectedOption = popupRef.current?.querySelector('[aria-selected="true"]') ?? activeOptionRef.current;
|
|
396
|
+
selectedOption?.scrollIntoView?.({ block: "center", inline: "nearest" });
|
|
397
|
+
popupReadyRef.current = true;
|
|
398
|
+
setPopupStyle((current) => ({ ...current, visibility: "visible" }));
|
|
399
|
+
}, [popupStyle.bottom, popupStyle.top]);
|
|
400
|
+
(0, import_react2.useLayoutEffect)(() => {
|
|
401
|
+
if (!popupReadyRef.current) return;
|
|
402
|
+
if (navigationSourceRef.current === "keyboard") {
|
|
403
|
+
activeOptionRef.current?.scrollIntoView?.({ block: "nearest", inline: "nearest" });
|
|
404
|
+
} else if (navigationSourceRef.current === "filter" && popupRef.current) {
|
|
405
|
+
popupRef.current.scrollTop = 0;
|
|
406
|
+
}
|
|
407
|
+
navigationSourceRef.current = null;
|
|
408
|
+
}, [activeIndex, filteredOptions]);
|
|
388
409
|
(0, import_react2.useEffect)(() => {
|
|
389
410
|
const handleOutsidePointer = (event) => {
|
|
390
411
|
const target = event.target;
|
|
@@ -404,10 +425,12 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
404
425
|
if (event.key === "Escape") onCancel();
|
|
405
426
|
if (event.key === "ArrowDown") {
|
|
406
427
|
event.preventDefault();
|
|
428
|
+
navigationSourceRef.current = "keyboard";
|
|
407
429
|
setActiveIndex((index) => Math.min(filteredOptions.length - 1, index + 1));
|
|
408
430
|
}
|
|
409
431
|
if (event.key === "ArrowUp") {
|
|
410
432
|
event.preventDefault();
|
|
433
|
+
navigationSourceRef.current = "keyboard";
|
|
411
434
|
setActiveIndex((index) => Math.max(0, index - 1));
|
|
412
435
|
}
|
|
413
436
|
if (event.key === "Enter") {
|
|
@@ -430,6 +453,7 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
430
453
|
onChange: (event) => {
|
|
431
454
|
setInputValue(event.target.value);
|
|
432
455
|
onChange(event.target.value);
|
|
456
|
+
navigationSourceRef.current = "filter";
|
|
433
457
|
setActiveIndex(0);
|
|
434
458
|
},
|
|
435
459
|
onKeyDown: handleKeyDown
|
|
@@ -445,7 +469,10 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
445
469
|
"aria-selected": option.value === originalValue,
|
|
446
470
|
className: `rvg-choice-item${index === activeIndex ? " is-active" : ""}${option.value === originalValue ? " is-selected" : ""}`,
|
|
447
471
|
onPointerDown: (event) => event.preventDefault(),
|
|
448
|
-
onMouseEnter: () =>
|
|
472
|
+
onMouseEnter: () => {
|
|
473
|
+
navigationSourceRef.current = "pointer";
|
|
474
|
+
setActiveIndex(index);
|
|
475
|
+
},
|
|
449
476
|
onClick: () => selectOption(option),
|
|
450
477
|
children: [
|
|
451
478
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: option.label }),
|
package/dist/index.js
CHANGED
|
@@ -306,6 +306,8 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
306
306
|
const editorRef = useRef(null);
|
|
307
307
|
const popupRef = useRef(null);
|
|
308
308
|
const activeOptionRef = useRef(null);
|
|
309
|
+
const popupReadyRef = useRef(false);
|
|
310
|
+
const navigationSourceRef = useRef(null);
|
|
309
311
|
const originalValueRef = useRef(value);
|
|
310
312
|
const listboxId = useId2();
|
|
311
313
|
const originalValue = originalValueRef.current;
|
|
@@ -314,7 +316,10 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
314
316
|
const selectedIndex = options.findIndex((option) => option.value === value);
|
|
315
317
|
return selectedIndex >= 0 ? selectedIndex : 0;
|
|
316
318
|
});
|
|
317
|
-
const [popupStyle, setPopupStyle] = useState({
|
|
319
|
+
const [popupStyle, setPopupStyle] = useState({
|
|
320
|
+
position: "fixed",
|
|
321
|
+
visibility: "hidden"
|
|
322
|
+
});
|
|
318
323
|
const filteredOptions = useMemo(() => {
|
|
319
324
|
const query = inputValue.trim().toLocaleLowerCase();
|
|
320
325
|
if (!query || query === originalValue.toLocaleLowerCase()) return options;
|
|
@@ -332,7 +337,8 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
332
337
|
bottom: window.innerHeight - rect.top + 4,
|
|
333
338
|
left: rect.left,
|
|
334
339
|
width: rect.width,
|
|
335
|
-
maxHeight: Math.min(maxDropdownHeight, availableAbove)
|
|
340
|
+
maxHeight: Math.min(maxDropdownHeight, availableAbove),
|
|
341
|
+
visibility: popupReadyRef.current ? "visible" : "hidden"
|
|
336
342
|
});
|
|
337
343
|
return;
|
|
338
344
|
}
|
|
@@ -341,7 +347,8 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
341
347
|
top: rect.bottom + 4,
|
|
342
348
|
left: rect.left,
|
|
343
349
|
width: rect.width,
|
|
344
|
-
maxHeight: Math.min(maxDropdownHeight, Math.max(80, availableBelow))
|
|
350
|
+
maxHeight: Math.min(maxDropdownHeight, Math.max(80, availableBelow)),
|
|
351
|
+
visibility: popupReadyRef.current ? "visible" : "hidden"
|
|
345
352
|
});
|
|
346
353
|
};
|
|
347
354
|
positionPopup();
|
|
@@ -353,8 +360,22 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
353
360
|
};
|
|
354
361
|
}, [maxDropdownHeight]);
|
|
355
362
|
useLayoutEffect(() => {
|
|
356
|
-
|
|
357
|
-
|
|
363
|
+
if (popupReadyRef.current) return;
|
|
364
|
+
if (popupStyle.top === void 0 && popupStyle.bottom === void 0) return;
|
|
365
|
+
const selectedOption = popupRef.current?.querySelector('[aria-selected="true"]') ?? activeOptionRef.current;
|
|
366
|
+
selectedOption?.scrollIntoView?.({ block: "center", inline: "nearest" });
|
|
367
|
+
popupReadyRef.current = true;
|
|
368
|
+
setPopupStyle((current) => ({ ...current, visibility: "visible" }));
|
|
369
|
+
}, [popupStyle.bottom, popupStyle.top]);
|
|
370
|
+
useLayoutEffect(() => {
|
|
371
|
+
if (!popupReadyRef.current) return;
|
|
372
|
+
if (navigationSourceRef.current === "keyboard") {
|
|
373
|
+
activeOptionRef.current?.scrollIntoView?.({ block: "nearest", inline: "nearest" });
|
|
374
|
+
} else if (navigationSourceRef.current === "filter" && popupRef.current) {
|
|
375
|
+
popupRef.current.scrollTop = 0;
|
|
376
|
+
}
|
|
377
|
+
navigationSourceRef.current = null;
|
|
378
|
+
}, [activeIndex, filteredOptions]);
|
|
358
379
|
useEffect(() => {
|
|
359
380
|
const handleOutsidePointer = (event) => {
|
|
360
381
|
const target = event.target;
|
|
@@ -374,10 +395,12 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
374
395
|
if (event.key === "Escape") onCancel();
|
|
375
396
|
if (event.key === "ArrowDown") {
|
|
376
397
|
event.preventDefault();
|
|
398
|
+
navigationSourceRef.current = "keyboard";
|
|
377
399
|
setActiveIndex((index) => Math.min(filteredOptions.length - 1, index + 1));
|
|
378
400
|
}
|
|
379
401
|
if (event.key === "ArrowUp") {
|
|
380
402
|
event.preventDefault();
|
|
403
|
+
navigationSourceRef.current = "keyboard";
|
|
381
404
|
setActiveIndex((index) => Math.max(0, index - 1));
|
|
382
405
|
}
|
|
383
406
|
if (event.key === "Enter") {
|
|
@@ -400,6 +423,7 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
400
423
|
onChange: (event) => {
|
|
401
424
|
setInputValue(event.target.value);
|
|
402
425
|
onChange(event.target.value);
|
|
426
|
+
navigationSourceRef.current = "filter";
|
|
403
427
|
setActiveIndex(0);
|
|
404
428
|
},
|
|
405
429
|
onKeyDown: handleKeyDown
|
|
@@ -415,7 +439,10 @@ function SearchableChoiceEditor({ value, options, allowCustomValue, maxDropdownH
|
|
|
415
439
|
"aria-selected": option.value === originalValue,
|
|
416
440
|
className: `rvg-choice-item${index === activeIndex ? " is-active" : ""}${option.value === originalValue ? " is-selected" : ""}`,
|
|
417
441
|
onPointerDown: (event) => event.preventDefault(),
|
|
418
|
-
onMouseEnter: () =>
|
|
442
|
+
onMouseEnter: () => {
|
|
443
|
+
navigationSourceRef.current = "pointer";
|
|
444
|
+
setActiveIndex(index);
|
|
445
|
+
},
|
|
419
446
|
onClick: () => selectOption(option),
|
|
420
447
|
children: [
|
|
421
448
|
/* @__PURE__ */ jsx3("span", { children: option.label }),
|