Only wrap URLBar on focus and hotkey to open recent requests

This commit is contained in:
Gregory Schier
2023-10-27 12:40:43 -07:00
parent ede0f1890f
commit 9f2577db66
7 changed files with 42 additions and 22 deletions

View File

@@ -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>
); );

View File

@@ -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>

View File

@@ -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

View File

@@ -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}

View File

@@ -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 {

View File

@@ -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') {

View File

@@ -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}