mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-23 09:18:30 +02:00
Fix dropdown open index
This commit is contained in:
@@ -20,7 +20,7 @@ import React, {
|
|||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { useKey, useKeyPressEvent, useWindowSize } from 'react-use';
|
import { useKey, useWindowSize } from 'react-use';
|
||||||
import type { HotkeyAction } from '../../hooks/useHotKey';
|
import type { HotkeyAction } from '../../hooks/useHotKey';
|
||||||
import { useHotKey } from '../../hooks/useHotKey';
|
import { useHotKey } from '../../hooks/useHotKey';
|
||||||
import { Overlay } from '../Overlay';
|
import { Overlay } from '../Overlay';
|
||||||
@@ -60,8 +60,8 @@ export interface DropdownProps {
|
|||||||
|
|
||||||
export interface DropdownRef {
|
export interface DropdownRef {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
open: (activeIndex?: number) => void;
|
open: () => void;
|
||||||
toggle: (activeIndex?: number) => void;
|
toggle: () => void;
|
||||||
close?: () => void;
|
close?: () => void;
|
||||||
next?: () => void;
|
next?: () => void;
|
||||||
prev?: () => void;
|
prev?: () => void;
|
||||||
@@ -88,21 +88,17 @@ export const Dropdown = forwardRef<DropdownRef, DropdownProps>(function Dropdown
|
|||||||
|
|
||||||
useHotKey(openOnHotKeyAction ?? null, () => {
|
useHotKey(openOnHotKeyAction ?? null, () => {
|
||||||
setIsOpen(true);
|
setIsOpen(true);
|
||||||
|
menuRef.current?.next?.();
|
||||||
});
|
});
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
...menuRef.current,
|
...menuRef.current,
|
||||||
isOpen: isOpen,
|
isOpen: isOpen,
|
||||||
toggle(activeIndex?: number) {
|
toggle() {
|
||||||
if (!isOpen) this.open(activeIndex);
|
if (!isOpen) this.open();
|
||||||
else setIsOpen(false);
|
else setIsOpen(false);
|
||||||
},
|
},
|
||||||
open(activeIndex?: number) {
|
open() {
|
||||||
if (activeIndex === undefined) {
|
|
||||||
setDefaultSelectedIndex(undefined);
|
|
||||||
} else {
|
|
||||||
setDefaultSelectedIndex(activeIndex >= 0 ? activeIndex : items.length + activeIndex);
|
|
||||||
}
|
|
||||||
setIsOpen(true);
|
setIsOpen(true);
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
@@ -225,21 +221,23 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
|
|||||||
setMenuStyles({ maxHeight: windowBox.height - menuBox.top - 5 });
|
setMenuStyles({ maxHeight: windowBox.height - menuBox.top - 5 });
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const handleClose = useCallback(() => {
|
||||||
|
onClose();
|
||||||
|
setSelectedIndex(null);
|
||||||
|
}, [onClose]);
|
||||||
|
|
||||||
// Close menu on space bar
|
// Close menu on space bar
|
||||||
const handleMenuKeyDown = useCallback(
|
const handleMenuKeyDown = useCallback(
|
||||||
(e: React.KeyboardEvent<HTMLDivElement>) => {
|
(e: React.KeyboardEvent<HTMLDivElement>) => {
|
||||||
if (e.key === ' ') {
|
if (e.key === ' ') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
onClose();
|
handleClose();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[onClose],
|
[handleClose],
|
||||||
);
|
);
|
||||||
|
|
||||||
useKeyPressEvent('Escape', (e) => {
|
useHotKey('dropdown.close', handleClose);
|
||||||
e.preventDefault();
|
|
||||||
onClose();
|
|
||||||
});
|
|
||||||
|
|
||||||
const handlePrev = useCallback(() => {
|
const handlePrev = useCallback(() => {
|
||||||
setSelectedIndex((currIndex) => {
|
setSelectedIndex((currIndex) => {
|
||||||
@@ -287,19 +285,19 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
|
|||||||
|
|
||||||
const handleSelect = useCallback(
|
const handleSelect = useCallback(
|
||||||
(i: DropdownItem) => {
|
(i: DropdownItem) => {
|
||||||
onClose();
|
handleClose();
|
||||||
setSelectedIndex(null);
|
setSelectedIndex(null);
|
||||||
if (i.type !== 'separator') {
|
if (i.type !== 'separator') {
|
||||||
i.onSelect?.();
|
i.onSelect?.();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[onClose],
|
[handleClose],
|
||||||
);
|
);
|
||||||
|
|
||||||
useImperativeHandle(
|
useImperativeHandle(
|
||||||
ref,
|
ref,
|
||||||
() => ({
|
() => ({
|
||||||
close: onClose,
|
close: handleClose,
|
||||||
prev: handlePrev,
|
prev: handlePrev,
|
||||||
next: handleNext,
|
next: handleNext,
|
||||||
select: () => {
|
select: () => {
|
||||||
@@ -308,7 +306,7 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
|
|||||||
handleSelect(item);
|
handleSelect(item);
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
[handleNext, handlePrev, handleSelect, items, onClose, selectedIndex],
|
[handleClose, handleNext, handlePrev, handleSelect, items, selectedIndex],
|
||||||
);
|
);
|
||||||
|
|
||||||
const { containerStyles, triangleStyles } = useMemo<{
|
const { containerStyles, triangleStyles } = useMemo<{
|
||||||
@@ -365,7 +363,7 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
|
|||||||
{isOpen && (
|
{isOpen && (
|
||||||
<Overlay open variant="transparent" portalName="dropdown" zIndex={50}>
|
<Overlay open variant="transparent" portalName="dropdown" zIndex={50}>
|
||||||
<div>
|
<div>
|
||||||
<div tabIndex={-1} aria-hidden className="fixed inset-0 z-30" onClick={onClose} />
|
<div tabIndex={-1} aria-hidden className="fixed inset-0 z-30" onClick={handleClose} />
|
||||||
<motion.div
|
<motion.div
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
onKeyDown={handleMenuKeyDown}
|
onKeyDown={handleMenuKeyDown}
|
||||||
|
|||||||
Reference in New Issue
Block a user