mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-18 07:23:51 +01:00
Fix selection of HTTP Request on create dropdown hotkey
This commit is contained in:
@@ -2,12 +2,15 @@ import { useCreateDropdownItems } from '../hooks/useCreateDropdownItems';
|
||||
import type { DropdownProps } from './core/Dropdown';
|
||||
import { Dropdown } from './core/Dropdown';
|
||||
|
||||
interface Props {
|
||||
interface Props extends Omit<DropdownProps, 'items'> {
|
||||
hideFolder?: boolean;
|
||||
children: DropdownProps['children'];
|
||||
}
|
||||
|
||||
export function CreateDropdown({ hideFolder, children }: Props) {
|
||||
export function CreateDropdown({ hideFolder, children, ...props }: Props) {
|
||||
const items = useCreateDropdownItems({ hideFolder, hideIcons: true });
|
||||
return <Dropdown items={items}>{children}</Dropdown>;
|
||||
return (
|
||||
<Dropdown items={items} {...props}>
|
||||
{children}
|
||||
</Dropdown>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -34,13 +34,8 @@ export function SidebarActions() {
|
||||
hotkeyAction="sidebar.toggle"
|
||||
icon={hidden ? 'leftPanelHidden' : 'leftPanelVisible'}
|
||||
/>
|
||||
<CreateDropdown>
|
||||
<IconButton
|
||||
size="sm"
|
||||
icon="plusCircle"
|
||||
title="Add Resource"
|
||||
hotkeyAction="http_request.create"
|
||||
/>
|
||||
<CreateDropdown hotKeyAction="http_request.create">
|
||||
<IconButton size="sm" icon="plusCircle" title="Add Resource" />
|
||||
</CreateDropdown>
|
||||
</HStack>
|
||||
);
|
||||
|
||||
@@ -30,6 +30,7 @@ import { HotKey } from './HotKey';
|
||||
import { Separator } from './Separator';
|
||||
import { HStack, VStack } from './Stacks';
|
||||
import { Icon } from './Icon';
|
||||
import { useStateWithDeps } from '../../hooks/useStateWithDeps';
|
||||
|
||||
export type DropdownItemSeparator = {
|
||||
type: 'separator';
|
||||
@@ -58,6 +59,7 @@ export interface DropdownProps {
|
||||
items: DropdownItem[];
|
||||
onOpen?: () => void;
|
||||
onClose?: () => void;
|
||||
hotKeyAction?: HotkeyAction;
|
||||
}
|
||||
|
||||
export interface DropdownRef {
|
||||
@@ -71,7 +73,7 @@ export interface DropdownRef {
|
||||
}
|
||||
|
||||
export const Dropdown = forwardRef<DropdownRef, DropdownProps>(function Dropdown(
|
||||
{ children, items, onOpen, onClose }: DropdownProps,
|
||||
{ children, items, onOpen, onClose, hotKeyAction }: DropdownProps,
|
||||
ref,
|
||||
) {
|
||||
const [isOpen, _setIsOpen] = useState<boolean>(false);
|
||||
@@ -88,18 +90,33 @@ export const Dropdown = forwardRef<DropdownRef, DropdownProps>(function Dropdown
|
||||
[onClose, onOpen],
|
||||
);
|
||||
|
||||
const handleClose = useCallback(() => {
|
||||
setIsOpen(false);
|
||||
buttonRef.current?.focus();
|
||||
// Reset so it triggers a render if opening sets to 0, for example
|
||||
setDefaultSelectedIndex(undefined);
|
||||
}, [setIsOpen]);
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
...menuRef.current,
|
||||
isOpen: isOpen,
|
||||
toggle() {
|
||||
if (!isOpen) this.open();
|
||||
else setIsOpen(false);
|
||||
else this.close();
|
||||
},
|
||||
open() {
|
||||
setIsOpen(true);
|
||||
},
|
||||
close() {
|
||||
handleClose();
|
||||
},
|
||||
}));
|
||||
|
||||
useHotKey(hotKeyAction ?? null, () => {
|
||||
setDefaultSelectedIndex(0);
|
||||
setIsOpen(true);
|
||||
});
|
||||
|
||||
const child = useMemo(() => {
|
||||
const existingChild = Children.only(children);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
@@ -119,11 +136,6 @@ export const Dropdown = forwardRef<DropdownRef, DropdownProps>(function Dropdown
|
||||
return cloneElement(existingChild, props);
|
||||
}, [children, setIsOpen]);
|
||||
|
||||
const handleClose = useCallback(() => {
|
||||
setIsOpen(false);
|
||||
buttonRef.current?.focus();
|
||||
}, [setIsOpen]);
|
||||
|
||||
useEffect(() => {
|
||||
buttonRef.current?.setAttribute('aria-expanded', isOpen.toString());
|
||||
}, [isOpen]);
|
||||
@@ -206,7 +218,10 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
|
||||
}: MenuProps,
|
||||
ref,
|
||||
) {
|
||||
const [selectedIndex, setSelectedIndex] = useState<number | null>(defaultSelectedIndex ?? null);
|
||||
const [selectedIndex, setSelectedIndex] = useStateWithDeps<number | null>(
|
||||
defaultSelectedIndex ?? null,
|
||||
[defaultSelectedIndex],
|
||||
);
|
||||
const [menuStyles, setMenuStyles] = useState<CSSProperties>({});
|
||||
const [filter, setFilter] = useState<string>('');
|
||||
const [containerWidth, setContainerWidth] = useState<number | null>(null);
|
||||
@@ -223,7 +238,7 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
|
||||
onClose();
|
||||
setSelectedIndex(null);
|
||||
setFilter('');
|
||||
}, [onClose]);
|
||||
}, [onClose, setSelectedIndex]);
|
||||
|
||||
// Close menu on space bar
|
||||
const handleMenuKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
|
||||
@@ -265,7 +280,7 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
|
||||
}
|
||||
return nextIndex;
|
||||
});
|
||||
}, [items]);
|
||||
}, [items, setSelectedIndex]);
|
||||
|
||||
const handleNext = useCallback(() => {
|
||||
setSelectedIndex((currIndex) => {
|
||||
@@ -282,7 +297,7 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
|
||||
}
|
||||
return nextIndex;
|
||||
});
|
||||
}, [items]);
|
||||
}, [items, setSelectedIndex]);
|
||||
|
||||
useKey(
|
||||
'ArrowUp',
|
||||
@@ -316,7 +331,7 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
|
||||
i.onSelect();
|
||||
}
|
||||
},
|
||||
[handleClose],
|
||||
[handleClose, setSelectedIndex],
|
||||
);
|
||||
|
||||
useImperativeHandle(
|
||||
@@ -377,7 +392,7 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
|
||||
const index = filteredItems.findIndex((item) => item === i) ?? null;
|
||||
setSelectedIndex(index);
|
||||
},
|
||||
[filteredItems],
|
||||
[filteredItems, setSelectedIndex],
|
||||
);
|
||||
|
||||
if (items.length === 0) return null;
|
||||
|
||||
Reference in New Issue
Block a user