@lotics/ui 2.3.1 → 2.3.2
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/package.json
CHANGED
package/src/combobox.tsx
CHANGED
|
@@ -389,7 +389,7 @@ export function Combobox<T extends string = string, D = unknown>(props: Combobox
|
|
|
389
389
|
selected={!multi && !isCustom && single?.value === opt.value}
|
|
390
390
|
disabled={opt.disabled}
|
|
391
391
|
onPress={() => handleSelect(i)}
|
|
392
|
-
onHoverIn={() => setActiveIndex(i)}
|
|
392
|
+
onHoverIn={() => setActiveIndex(i, false)}
|
|
393
393
|
/>
|
|
394
394
|
);
|
|
395
395
|
})
|
|
@@ -103,4 +103,11 @@ describe("useListKeyboardNav", () => {
|
|
|
103
103
|
act(() => void view.result.current.handleKey("ArrowDown"));
|
|
104
104
|
expect(onActiveChange).toHaveBeenCalledWith(1);
|
|
105
105
|
});
|
|
106
|
+
|
|
107
|
+
it("setActiveIndex moves the active row but skips onActiveChange when scrollIntoView is false (mouse hover)", () => {
|
|
108
|
+
const { view, onActiveChange } = setup();
|
|
109
|
+
act(() => view.result.current.setActiveIndex(2, false));
|
|
110
|
+
expect(view.result.current.activeIndex).toBe(2);
|
|
111
|
+
expect(onActiveChange).not.toHaveBeenCalled();
|
|
112
|
+
});
|
|
106
113
|
});
|
|
@@ -17,7 +17,10 @@ export interface ListKeyboardNav {
|
|
|
17
17
|
/** The virtually-focused row. The list stays visually highlighted here while
|
|
18
18
|
* DOM focus remains on the controlling input (ARIA `aria-activedescendant`). */
|
|
19
19
|
activeIndex: number;
|
|
20
|
-
|
|
20
|
+
/** Set the active row. `scrollIntoView` defaults to true (keyboard nav); pass
|
|
21
|
+
* false on mouse hover so it doesn't scroll the row into view — the cursor is
|
|
22
|
+
* already on it, and scrolling would slide a different row under the cursor. */
|
|
23
|
+
setActiveIndex: (index: number, scrollIntoView?: boolean) => void;
|
|
21
24
|
/** Feed a key from the controlling input's `onKeyPress`. Returns true when it
|
|
22
25
|
* handled the key, so the caller can `preventDefault()`. */
|
|
23
26
|
handleKey: (key: string) => boolean;
|
|
@@ -34,9 +37,13 @@ export function useListKeyboardNav(opts: ListKeyboardNavOptions): ListKeyboardNa
|
|
|
34
37
|
const [activeIndex, setActiveIndexState] = useState(0);
|
|
35
38
|
|
|
36
39
|
const setActiveIndex = useCallback(
|
|
37
|
-
(index: number) => {
|
|
40
|
+
(index: number, scrollIntoView = true) => {
|
|
38
41
|
setActiveIndexState(index);
|
|
39
|
-
|
|
42
|
+
// Only scroll for keyboard nav. Mouse hover sets the active row without
|
|
43
|
+
// scrolling — the cursor is already on it, and scrolling it into view
|
|
44
|
+
// would slide a different row under the cursor → onHoverIn → scroll →
|
|
45
|
+
// runaway loop.
|
|
46
|
+
if (scrollIntoView) onActiveChange?.(index);
|
|
40
47
|
},
|
|
41
48
|
[onActiveChange],
|
|
42
49
|
);
|