mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-23 00:58:32 +02:00
Only wrap URLBar on focus and hotkey to open recent requests
This commit is contained in:
@@ -112,25 +112,28 @@ export const EnvironmentActionsDropdown = memo(function EnvironmentActionsDropdo
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
}, [
|
}, [
|
||||||
// deleteEnvironment.mutate,
|
|
||||||
activeEnvironment,
|
activeEnvironment,
|
||||||
createEnvironment,
|
createEnvironment,
|
||||||
|
deleteEnvironment,
|
||||||
dialog,
|
dialog,
|
||||||
environments,
|
environments,
|
||||||
prompt,
|
prompt,
|
||||||
updateEnvironment,
|
|
||||||
deleteEnvironment,
|
|
||||||
routes,
|
routes,
|
||||||
|
updateEnvironment,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown items={items}>
|
<Dropdown items={items}>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
|
||||||
className={classNames(className, 'text-gray-800 !px-2 truncate')}
|
|
||||||
forDropdown
|
forDropdown
|
||||||
|
size="sm"
|
||||||
|
className={classNames(
|
||||||
|
className,
|
||||||
|
'text-gray-800 !px-2 truncate',
|
||||||
|
activeEnvironment == null && 'text-opacity-disabled italic',
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
{activeEnvironment?.name ?? <span className="italic text-gray-500">No Environment</span>}
|
{activeEnvironment?.name ?? 'No Environment'}
|
||||||
</Button>
|
</Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { Button } from './core/Button';
|
|||||||
import { CountBadge } from './core/CountBadge';
|
import { CountBadge } from './core/CountBadge';
|
||||||
import type { DropdownItem, DropdownRef } from './core/Dropdown';
|
import type { DropdownItem, DropdownRef } from './core/Dropdown';
|
||||||
import { Dropdown } from './core/Dropdown';
|
import { Dropdown } from './core/Dropdown';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
export function RecentRequestsDropdown() {
|
export function RecentRequestsDropdown() {
|
||||||
const dropdownRef = useRef<DropdownRef>(null);
|
const dropdownRef = useRef<DropdownRef>(null);
|
||||||
@@ -18,8 +19,16 @@ export function RecentRequestsDropdown() {
|
|||||||
const requests = useRequests();
|
const requests = useRequests();
|
||||||
const routes = useAppRoutes();
|
const routes = useAppRoutes();
|
||||||
|
|
||||||
|
// Toggle the menu on Cmd+k
|
||||||
|
useKey('k', (e) => {
|
||||||
|
if (e.metaKey) {
|
||||||
|
e.preventDefault();
|
||||||
|
dropdownRef.current?.toggle(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle key-up
|
||||||
useKeyPressEvent('Control', undefined, () => {
|
useKeyPressEvent('Control', undefined, () => {
|
||||||
// Key up
|
|
||||||
dropdownRef.current?.select?.();
|
dropdownRef.current?.select?.();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -29,8 +38,8 @@ export function RecentRequestsDropdown() {
|
|||||||
if (!e.ctrlKey || recentRequestIds.length === 0) return;
|
if (!e.ctrlKey || recentRequestIds.length === 0) return;
|
||||||
|
|
||||||
if (!dropdownRef.current?.isOpen) {
|
if (!dropdownRef.current?.isOpen) {
|
||||||
// Set to 1 because the first item is the active request
|
|
||||||
dropdownRef.current?.open(e.shiftKey ? -1 : 0);
|
dropdownRef.current?.open(e.shiftKey ? -1 : 0);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.shiftKey) dropdownRef.current?.prev?.();
|
if (e.shiftKey) dropdownRef.current?.prev?.();
|
||||||
@@ -72,9 +81,11 @@ export function RecentRequestsDropdown() {
|
|||||||
return (
|
return (
|
||||||
<Dropdown ref={dropdownRef} items={items}>
|
<Dropdown ref={dropdownRef} items={items}>
|
||||||
<Button
|
<Button
|
||||||
disabled={activeRequest === null}
|
|
||||||
size="sm"
|
size="sm"
|
||||||
className="flex-[2] text-center text-gray-800 text-sm truncate pointer-events-none"
|
className={classNames(
|
||||||
|
'flex-[2] text-center text-gray-800 text-sm truncate pointer-events-none',
|
||||||
|
activeRequest === null && 'text-opacity-disabled italic',
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
{activeRequest?.name ?? 'No Request'}
|
{activeRequest?.name ?? 'No Request'}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ export const Sidebar = memo(function Sidebar({ className }: Props) {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<HStack
|
<HStack
|
||||||
className="mt-1 mb-2 pt-1 mx-2"
|
className="mt-1 pt-1 mx-2"
|
||||||
justifyContent="between"
|
justifyContent="between"
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
space={1}
|
space={1}
|
||||||
@@ -181,7 +181,7 @@ export const Sidebar = memo(function Sidebar({ className }: Props) {
|
|||||||
</HStack>
|
</HStack>
|
||||||
<VStack
|
<VStack
|
||||||
as="ul"
|
as="ul"
|
||||||
className="relative pb-3 overflow-y-auto overflow-x-visible"
|
className="relative pb-3 overflow-y-auto overflow-x-visible pt-2"
|
||||||
draggable={false}
|
draggable={false}
|
||||||
>
|
>
|
||||||
<SidebarItems
|
<SidebarItems
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import type { EditorView } from 'codemirror';
|
import type { EditorView } from 'codemirror';
|
||||||
import type { FormEvent } from 'react';
|
import type { FormEvent } from 'react';
|
||||||
import { memo, useCallback, useRef } from 'react';
|
import { memo, useCallback, useRef, useState } from 'react';
|
||||||
import { useIsResponseLoading } from '../hooks/useIsResponseLoading';
|
import { useIsResponseLoading } from '../hooks/useIsResponseLoading';
|
||||||
import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
|
import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
|
||||||
import { useSendRequest } from '../hooks/useSendRequest';
|
import { useSendRequest } from '../hooks/useSendRequest';
|
||||||
@@ -20,6 +20,7 @@ export const UrlBar = memo(function UrlBar({ id: requestId, url, method, classNa
|
|||||||
const inputRef = useRef<EditorView>(null);
|
const inputRef = useRef<EditorView>(null);
|
||||||
const sendRequest = useSendRequest(requestId);
|
const sendRequest = useSendRequest(requestId);
|
||||||
const updateRequest = useUpdateRequest(requestId);
|
const updateRequest = useUpdateRequest(requestId);
|
||||||
|
const [isFocused, setIsFocused] = useState<boolean>(false);
|
||||||
const handleMethodChange = useCallback(
|
const handleMethodChange = useCallback(
|
||||||
(method: string) => updateRequest.mutate({ method }),
|
(method: string) => updateRequest.mutate({ method }),
|
||||||
[updateRequest],
|
[updateRequest],
|
||||||
@@ -47,7 +48,7 @@ export const UrlBar = memo(function UrlBar({ id: requestId, url, method, classNa
|
|||||||
<form onSubmit={handleSubmit} className={classNames('url-bar', className)}>
|
<form onSubmit={handleSubmit} className={classNames('url-bar', className)}>
|
||||||
<Input
|
<Input
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
size="auto"
|
size={isFocused ? 'auto' : 'sm'}
|
||||||
hideLabel
|
hideLabel
|
||||||
useTemplating
|
useTemplating
|
||||||
contentType="url"
|
contentType="url"
|
||||||
@@ -55,6 +56,8 @@ export const UrlBar = memo(function UrlBar({ id: requestId, url, method, classNa
|
|||||||
name="url"
|
name="url"
|
||||||
label="Enter URL"
|
label="Enter URL"
|
||||||
forceUpdateKey={updateKey}
|
forceUpdateKey={updateKey}
|
||||||
|
onFocus={() => setIsFocused(true)}
|
||||||
|
onBlur={() => setIsFocused(false)}
|
||||||
containerClassName="shadow shadow-gray-100 dark:shadow-gray-50"
|
containerClassName="shadow shadow-gray-100 dark:shadow-gray-50"
|
||||||
onChange={handleUrlChange}
|
onChange={handleUrlChange}
|
||||||
defaultValue={url}
|
defaultValue={url}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export interface DropdownProps {
|
|||||||
export interface DropdownRef {
|
export interface DropdownRef {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
open: (activeIndex?: number) => void;
|
open: (activeIndex?: number) => void;
|
||||||
toggle: () => void;
|
toggle: (activeIndex?: number) => void;
|
||||||
close?: () => void;
|
close?: () => void;
|
||||||
next?: () => void;
|
next?: () => void;
|
||||||
prev?: () => void;
|
prev?: () => void;
|
||||||
@@ -65,8 +65,11 @@ export const Dropdown = forwardRef<DropdownRef, DropdownProps>(function Dropdown
|
|||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
...menuRef.current,
|
...menuRef.current,
|
||||||
isOpen: open,
|
isOpen: open,
|
||||||
toggle: () => setOpen(!open),
|
toggle (activeIndex?: number) {
|
||||||
open: (activeIndex?: number) => {
|
if (!open) this.open(activeIndex);
|
||||||
|
else setOpen(false);
|
||||||
|
},
|
||||||
|
open(activeIndex?: number) {
|
||||||
if (activeIndex === undefined) {
|
if (activeIndex === undefined) {
|
||||||
setDefaultSelectedIndex(undefined);
|
setDefaultSelectedIndex(undefined);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -259,10 +259,6 @@ function getExtensions({
|
|||||||
...(singleLine
|
...(singleLine
|
||||||
? [
|
? [
|
||||||
EditorView.domEventHandlers({
|
EditorView.domEventHandlers({
|
||||||
focus: (_, view) => {
|
|
||||||
// select all text on focus, like a regular input does
|
|
||||||
view.dispatch({ selection: { anchor: 0, head: view.state.doc.length } });
|
|
||||||
},
|
|
||||||
keydown: (e) => {
|
keydown: (e) => {
|
||||||
// Submit nearest form on enter if there is one
|
// Submit nearest form on enter if there is one
|
||||||
if (onEnter != null && e.key === 'Enter') {
|
if (onEnter != null && e.key === 'Enter') {
|
||||||
|
|||||||
@@ -124,7 +124,11 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
|
|||||||
{leftSlot}
|
{leftSlot}
|
||||||
<HStack
|
<HStack
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
className={classNames('w-full', leftSlot && 'pl-0.5 -ml-2', rightSlot && 'pr-0.5 -mr-2')}
|
className={classNames(
|
||||||
|
'w-full min-w-0',
|
||||||
|
leftSlot && 'pl-0.5 -ml-2',
|
||||||
|
rightSlot && 'pr-0.5 -mr-2',
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<Editor
|
<Editor
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
|||||||
Reference in New Issue
Block a user