More subtle layout tweaks

This commit is contained in:
Gregory Schier
2023-03-06 08:57:57 -08:00
parent 986cd56662
commit b48a41aaec
10 changed files with 75 additions and 107 deletions

View File

@@ -1,7 +1,7 @@
use tauri::{Runtime, Window};
const TRAFFIC_LIGHT_OFFSET_X: f64 = 15.0;
const TRAFFIC_LIGHT_OFFSET_Y: f64 = 20.0;
const TRAFFIC_LIGHT_OFFSET_Y: f64 = 18.0;
pub trait WindowExt {
#[cfg(target_os = "macos")]

View File

@@ -1,21 +1,12 @@
import classnames from 'classnames';
import { useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { Button } from './components/Button';
import { Divider } from './components/Divider';
import { Grid } from './components/Grid';
import { IconButton } from './components/IconButton';
import { RequestPane } from './components/RequestPane';
import { ResponsePane } from './components/ResponsePane';
import { Sidebar } from './components/Sidebar';
import { HStack } from './components/Stacks';
import { WindowDragRegion } from './components/WindowDragRegion';
import {
useDeleteRequest,
useRequests,
useRequestUpdate,
useSendRequest,
} from './hooks/useRequest';
import { useRequests } from './hooks/useRequest';
type Params = {
workspaceId: string;
@@ -26,7 +17,6 @@ function App() {
const p = useParams<Params>();
const workspaceId = p.workspaceId ?? '';
const { data: requests } = useRequests(workspaceId);
const navigate = useNavigate();
const request = requests?.find((r) => r.id === p.requestId);
const [screenWidth, setScreenWidth] = useState(window.innerWidth);
@@ -36,40 +26,28 @@ function App() {
const isH = screenWidth > 900;
return (
<div className="grid grid-cols-[auto_1fr] h-full text-gray-900">
<div className="grid grid-cols-[auto_1fr] h-full text-gray-900 overflow-hidden rounded-[11px]">
<Sidebar requests={requests ?? []} workspaceId={workspaceId} activeRequestId={request?.id} />
{request && (
<div className="p-2 h-full">
<div className="grid grid-rows-[auto_1fr] rounded-md h-full overflow-hidden">
<div className="h-full">
<div className="grid grid-rows-[auto_1fr] h-full overflow-hidden">
<HStack
as={WindowDragRegion}
className="pl-1 pr-3 bg-gray-50 text-sm"
justify="center"
className="px-3 bg-gray-50/50 text-sm text-gray-900 border-b border-b-gray-50 pt-[1px]"
items="center"
>
<div className="mr-auto">
<IconButton
size="xs"
icon="x"
onClick={() => navigate(`/workspaces/${workspaceId}`)}
/>
</div>
<div>{request.name}</div>
<div className="ml-auto"></div>
{request.name}
</HStack>
<div
className={classnames(
'py-2 px-1 bg-gray-25 grid overflow-auto',
'bg-gray-25 grid overflow-auto',
isH ? 'grid-cols-[1fr_1fr]' : 'grid-rows-[minmax(0,auto)_minmax(0,100%)]',
)}
>
<RequestPane
fullHeight={isH}
request={request}
className={classnames(
'border-gray-100/50',
isH ? 'pr-0 border-r' : 'pb-3 mb-1 border-b',
)}
className={classnames(isH ? 'pr-0' : 'pb-3 mb-1')}
/>
<ResponsePane requestId={request.id} />
</div>

View File

@@ -52,7 +52,7 @@ export const Button = forwardRef(function Button<T extends ElementType>(
justify === 'center' && 'justify-center',
size === 'md' && 'h-10 px-4',
size === 'sm' && 'h-8 px-3 text-sm',
size === 'xs' && 'h-6 px-3 text-xs',
size === 'xs' && 'h-7 px-2.5 text-sm',
)}
{...props}
>

View File

@@ -12,7 +12,7 @@
}
.cm-editor {
@apply w-full block text-[0.85rem] bg-gray-25;
@apply bg-background w-full block text-[0.85rem];
&.cm-focused {
outline: none !important;
@@ -70,7 +70,7 @@
}
.cm-editor .cm-gutters {
@apply bg-gray-25 border-0 text-gray-200;
@apply bg-background border-0 text-gray-200;
}
.cm-editor .cm-gutterElement {

View File

@@ -4,7 +4,7 @@ import { Compartment, EditorState } from '@codemirror/state';
import { keymap, placeholder as placeholderExt, tooltips } from '@codemirror/view';
import classnames from 'classnames';
import { EditorView } from 'codemirror';
import type { HTMLAttributes } from 'react';
import type { CSSProperties, HTMLAttributes } from 'react';
import { useEffect, useMemo, useRef, useState } from 'react';
import './Editor.css';
import { baseExtensions, getLanguageExtension, multiLineExtensions } from './extensions';
@@ -13,6 +13,7 @@ import { singleLineExt } from './singleLine';
export interface EditorProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onChange'> {
height?: 'auto' | 'full';
contentType?: string;
backgroundColor?: string;
autoFocus?: boolean;
valueKey?: string | number;
defaultValue?: string;
@@ -26,6 +27,7 @@ export interface EditorProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onCha
export default function Editor({
height,
contentType,
backgroundColor,
autoFocus,
placeholder,
valueKey,
@@ -100,6 +102,7 @@ export default function Editor({
height === 'auto' ? 'cm-auto-height' : 'cm-full-height',
singleLine ? 'cm-singleline' : 'cm-multiline',
)}
data-color-background="var(--color-gray-50)"
{...props}
/>
);

View File

@@ -2,7 +2,6 @@ import classnames from 'classnames';
import { useRequestUpdate, useSendRequest } from '../hooks/useRequest';
import type { HttpRequest } from '../lib/models';
import { Button } from './Button';
import { Divider } from './Divider';
import Editor from './Editor/Editor';
import { ScrollArea } from './ScrollArea';
import { HStack } from './Stacks';
@@ -18,10 +17,12 @@ export function RequestPane({ fullHeight, request, className }: Props) {
const updateRequest = useRequestUpdate(request ?? null);
const sendRequest = useSendRequest(request ?? null);
return (
<div className={classnames(className, 'grid grid-rows-[auto_auto_minmax(0,1fr)] grid-cols-1')}>
<div>
<div
className={classnames(className, 'py-2 grid grid-rows-[auto_auto_minmax(0,1fr)] grid-cols-1')}
>
<div className="pl-2">
<UrlBar
className="bg-transparent border-0 mb-1"
className="border-0 mb-1"
key={request.id}
method={request.method}
url={request.url}
@@ -30,9 +31,7 @@ export function RequestPane({ fullHeight, request, className }: Props) {
onUrlChange={(url) => updateRequest.mutate({ url })}
sendRequest={sendRequest.mutate}
/>
<div className="mx-2">
<Divider />
</div>
{/*<Divider />*/}
</div>
{/*<Divider className="mb-2" />*/}
<ScrollArea className="max-w-full pb-2 mx-2">

View File

@@ -1,13 +1,10 @@
import classnames from 'classnames';
import { useEffect, useMemo, useState } from 'react';
import { useDeleteAllResponses, useDeleteResponse, useResponses } from '../hooks/useResponses';
import { Button } from './Button';
import { Divider } from './Divider';
import { Dropdown } from './Dropdown';
import Editor from './Editor/Editor';
import { Icon } from './Icon';
import { IconButton } from './IconButton';
import { ScrollArea } from './ScrollArea';
import { HStack } from './Stacks';
interface Props {
@@ -45,23 +42,23 @@ export function ResponsePane({ requestId, className }: Props) {
}, [response?.body, contentType]);
return (
<div
className={classnames(
className,
'max-h-full h-full grid grid-rows-[auto_auto_minmax(0,1fr)] grid-cols-1',
)}
>
{/*<HStack as={WindowDragRegion} items="center" className="pl-1.5 pr-1">*/}
{/*</HStack>*/}
{response?.error && (
<div className="text-white bg-red-500 px-2 py-1 rounded">{response.error}</div>
)}
{response && (
<>
<div>
<div className="p-2">
<div
className={classnames(
className,
'max-h-full h-full grid grid-rows-[auto_minmax(0,1fr)] grid-cols-1 bg-gray-50/50 rounded-md',
)}
>
{/*<HStack as={WindowDragRegion} items="center" className="pl-1.5 pr-1">*/}
{/*</HStack>*/}
{response?.error && (
<div className="text-white bg-red-500 px-2 py-1 rounded">{response.error}</div>
)}
{response && (
<>
<HStack
items="center"
className="italic text-gray-500 text-sm w-full mb-1 flex-shrink-0 pl-2"
className="italic text-gray-500 text-sm w-full mb-1 flex-shrink-0 pl-2 py-1"
>
<div className="whitespace-nowrap">
{response.status}
@@ -104,43 +101,27 @@ export function ResponsePane({ requestId, className }: Props) {
</Dropdown>
</HStack>
</HStack>
<div className="px-2">
<Divider />
</div>
</div>
<ScrollArea className="max-w-full pb-2 mx-2">
<HStack className="mt-2 hide-scrollbar" space={1}>
{['Preview', 'Headers', 'Cookies', 'Timing'].map((label, i) => (
<Button
key={label}
size="xs"
color={i === 0 && 'gray'}
className={i !== 0 && 'opacity-50 hover:opacity-60'}
>
{label}
</Button>
))}
</HStack>
</ScrollArea>
{viewMode === 'pretty' && contentForIframe !== null ? (
<div className="pl-2">
<iframe
title="Response preview"
srcDoc={contentForIframe}
sandbox="allow-scripts allow-same-origin"
className="h-full w-full rounded-lg"
{viewMode === 'pretty' && contentForIframe !== null ? (
<div className="px-2 pb-2">
<iframe
title="Response preview"
srcDoc={contentForIframe}
sandbox="allow-scripts allow-same-origin"
className="h-full w-full rounded-md border border-gray-100/20"
/>
</div>
) : response?.body ? (
<Editor
backgroundColor="red"
valueKey={`${contentType}:${response.body}`}
defaultValue={response?.body}
contentType={contentType}
/>
</div>
) : response?.body ? (
<Editor
valueKey={`${contentType}:${response.body}`}
defaultValue={response?.body}
contentType={contentType}
/>
) : null}
</>
)}
) : null}
</>
)}
</div>
</div>
);
}

View File

@@ -23,21 +23,24 @@ export function Sidebar({ className, activeRequestId, workspaceId, requests, ...
const { toggleTheme } = useTheme();
const [open, setOpen] = useState<boolean>(false);
return (
<div className={classnames(className, 'w-52 bg-gray-50 h-full px-2')} {...props}>
<HStack as={WindowDragRegion} items="center" className="py-2" justify="end">
<div
className={classnames(className, 'w-52 bg-gray-50 h-full border-gray-100/50 relative z-10')}
{...props}
>
<HStack as={WindowDragRegion} items="center" justify="end">
<Dialog wide open={open} onOpenChange={setOpen} title="Edit Headers">
<HeaderEditor />
<Button className="ml-auto mt-5" color="primary" onClick={() => setOpen(false)}>
Save
</Button>
</Dialog>
<IconButton
size="sm"
icon="camera"
onClick={() => {
setOpen((v) => !v);
}}
/>
{/*<IconButton*/}
{/* size="sm"*/}
{/* icon="camera"*/}
{/* onClick={() => {*/}
{/* setOpen((v) => !v);*/}
{/* }}*/}
{/*/>*/}
<IconButton size="sm" icon="sun" onClick={toggleTheme} />
<IconButton
size="sm"
@@ -47,7 +50,7 @@ export function Sidebar({ className, activeRequestId, workspaceId, requests, ...
}}
/>
</HStack>
<VStack as="ul" className="pb-3" space={1}>
<VStack as="ul" className="py-3 px-2" space={1}>
{requests.map((r) => (
<SidebarItem key={r.id} request={r} active={r.id === activeRequestId} />
))}
@@ -63,7 +66,7 @@ function SidebarItem({ request, active }: { request: HttpRequest; active: boolea
as={Link}
to={`/workspaces/${request.workspaceId}/requests/${request.id}`}
className={classnames('w-full', active && 'bg-gray-500/[0.1] text-gray-900')}
size="sm"
size="xs"
justify="start"
>
{request.name}

View File

@@ -7,7 +7,7 @@ export function WindowDragRegion({ className, ...props }: Props) {
return (
<div
data-tauri-drag-region
className={classnames(className, 'w-full h-8 flex-shrink-0 box-content')}
className={classnames(className, 'w-full h-10 flex-shrink-0')}
{...props}
/>
);

View File

@@ -41,6 +41,10 @@ html, body, #root {
/* }*/
/*}*/
[data-color-background] {
--color-background: attr(data-bg-color);
}
@layer base {
:root, [data-theme="light"] {
/* Colors */