mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-21 00:49:17 +01:00
Zoom, better sizes, color picker, sidebar footer
This commit is contained in:
@@ -1,65 +1,57 @@
|
||||
import classnames from 'classnames';
|
||||
import type {
|
||||
ButtonHTMLAttributes,
|
||||
ComponentPropsWithoutRef,
|
||||
ElementType,
|
||||
ForwardedRef,
|
||||
} from 'react';
|
||||
import type { ButtonHTMLAttributes, ForwardedRef } from 'react';
|
||||
import { forwardRef } from 'react';
|
||||
import { Icon } from './Icon';
|
||||
|
||||
const colorStyles = {
|
||||
default: 'hover:bg-gray-700/10 text-gray-700 hover:text-gray-1000',
|
||||
gray: 'text-gray-800 bg-gray-100 hover:bg-gray-500/20 hover:text-gray-1000',
|
||||
primary: 'bg-blue-400 text-white',
|
||||
secondary: 'bg-violet-400 text-white',
|
||||
warning: 'bg-orange-400 text-white',
|
||||
danger: 'bg-red-400 text-white',
|
||||
custom: '',
|
||||
default: 'text-gray-700 enabled:hover:bg-gray-700/10 enabled:hover:text-gray-1000',
|
||||
gray: 'text-gray-800 bg-gray-100 enabled:hover:bg-gray-500/20 enabled:hover:text-gray-1000',
|
||||
primary: 'bg-blue-400 text-white hover:bg-blue-500',
|
||||
secondary: 'bg-violet-400 text-white hover:bg-violet-500',
|
||||
warning: 'bg-orange-400 text-white hover:bg-orange-500',
|
||||
danger: 'bg-red-400 text-white hover:bg-red-500',
|
||||
};
|
||||
|
||||
export type ButtonProps<T extends ElementType> = ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||
export type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||
color?: keyof typeof colorStyles;
|
||||
size?: 'xs' | 'sm' | 'md';
|
||||
size?: 'sm' | 'md';
|
||||
justify?: 'start' | 'center';
|
||||
forDropdown?: boolean;
|
||||
as?: T;
|
||||
};
|
||||
|
||||
export const Button = forwardRef(function Button<T extends ElementType>(
|
||||
export const Button = forwardRef(function Button(
|
||||
{
|
||||
className,
|
||||
as,
|
||||
justify = 'center',
|
||||
children,
|
||||
size = 'md',
|
||||
forDropdown,
|
||||
color,
|
||||
justify = 'center',
|
||||
size = 'md',
|
||||
type = 'button',
|
||||
...props
|
||||
}: ButtonProps<T> & Omit<ComponentPropsWithoutRef<T>, keyof ButtonProps<T>>,
|
||||
}: ButtonProps,
|
||||
ref: ForwardedRef<HTMLButtonElement>,
|
||||
) {
|
||||
const Component = as || 'button';
|
||||
return (
|
||||
<Component
|
||||
<button
|
||||
ref={ref}
|
||||
type="button"
|
||||
type={type}
|
||||
className={classnames(
|
||||
className,
|
||||
'outline-none',
|
||||
'border border-transparent focus-visible:border-blue-300',
|
||||
'transition-all rounded-md flex items-center',
|
||||
'bg-opacity-90 hover:bg-opacity-100',
|
||||
colorStyles[color || 'default'],
|
||||
justify === 'start' && 'justify-start',
|
||||
justify === 'center' && 'justify-center',
|
||||
size === 'md' && 'h-10 px-4',
|
||||
size === 'sm' && 'h-8 px-3 text-sm',
|
||||
size === 'xs' && 'h-7 px-2.5 text-sm',
|
||||
size === 'md' && 'h-9 px-3',
|
||||
size === 'sm' && 'h-7 px-2.5 text-sm',
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
{forDropdown && <Icon icon="triangleDown" className="ml-1 -mr-1" />}
|
||||
</Component>
|
||||
</button>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
import classnames from 'classnames';
|
||||
import type { LinkProps } from 'react-router-dom';
|
||||
import { Link } from 'react-router-dom';
|
||||
import type { ButtonProps } from './Button';
|
||||
import { Button } from './Button';
|
||||
|
||||
type Props = ButtonProps<typeof Link> & LinkProps;
|
||||
type Props = ButtonProps & LinkProps;
|
||||
|
||||
export function ButtonLink({ ...props }: Props) {
|
||||
return <Button as={Link} {...props} />;
|
||||
export function ButtonLink({
|
||||
reloadDocument,
|
||||
replace,
|
||||
state,
|
||||
preventScrollReset,
|
||||
relative,
|
||||
to,
|
||||
className,
|
||||
...buttonProps
|
||||
}: Props) {
|
||||
const linkProps = { reloadDocument, replace, state, preventScrollReset, relative, to };
|
||||
return (
|
||||
<Link {...linkProps}>
|
||||
<Button className={classnames(className, 'w-full')} {...buttonProps} />
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ export function Dialog({
|
||||
<IconButton aria-label="Close" icon="x" size="sm" />
|
||||
</D.Close>
|
||||
<VStack space={3}>
|
||||
<HStack items="center" className="pb-3">
|
||||
<HStack alignItems="center" className="pb-3">
|
||||
<D.Title className="text-xl font-semibold">{title}</D.Title>
|
||||
</HStack>
|
||||
{description && <D.Description>{description}</D.Description>}
|
||||
|
||||
@@ -25,19 +25,15 @@
|
||||
}
|
||||
|
||||
.cm-gutters {
|
||||
@apply border-0 text-gray-500 text-opacity-30;
|
||||
@apply border-0 text-gray-500/60;
|
||||
|
||||
.cm-gutterElement {
|
||||
@apply cursor-default;
|
||||
}
|
||||
}
|
||||
|
||||
&.cm-focused .cm-gutters {
|
||||
@apply text-opacity-60;
|
||||
}
|
||||
|
||||
.placeholder-widget {
|
||||
@apply text-[0.9em] text-gray-800 dark:text-gray-1000 px-1 rounded cursor-default dark:shadow;
|
||||
@apply text-[0.9em] text-gray-800 dark:text-gray-900 px-1 rounded cursor-default dark:shadow;
|
||||
|
||||
/* NOTE: Background and border are translucent so we can see text selection through it */
|
||||
@apply bg-gray-300/40 border border-gray-300 border-opacity-40 hover:border-opacity-80;
|
||||
@@ -105,11 +101,12 @@
|
||||
}
|
||||
|
||||
.cm-editor .fold-gutter-icon:hover {
|
||||
@apply text-gray-400 bg-gray-100/20;
|
||||
@apply text-gray-900 bg-gray-300/50;
|
||||
}
|
||||
|
||||
.cm-editor .cm-foldPlaceholder {
|
||||
@apply px-2 border border-gray-200 bg-gray-100;
|
||||
@apply px-2 border border-gray-400/50 bg-gray-300/50 cursor-default;
|
||||
@apply hover:text-gray-800 hover:border-gray-400;
|
||||
}
|
||||
|
||||
.cm-editor .cm-activeLineGutter,
|
||||
|
||||
@@ -34,7 +34,6 @@ import {
|
||||
} from '@codemirror/view';
|
||||
import { tags as t } from '@lezer/highlight';
|
||||
import { debouncedAutocompletionDisplay } from './autocomplete';
|
||||
import { readOnlyTransactionFilter } from './readOnlyTransactionFilter';
|
||||
import { twig } from './twig/extension';
|
||||
import { url } from './url/extension';
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ function FormRow({
|
||||
defaultValue={value}
|
||||
onChange={onChangeValue}
|
||||
/>
|
||||
{onDelete && <IconButton size="sm" icon="trash" onClick={onDelete} />}
|
||||
{onDelete && <IconButton icon="trash" onClick={onDelete} />}
|
||||
</HStack>
|
||||
{addSubmit && <input type="submit" value="Add" className="sr-only" />}
|
||||
</div>
|
||||
|
||||
@@ -4,11 +4,13 @@ import {
|
||||
CheckIcon,
|
||||
ClockIcon,
|
||||
CodeIcon,
|
||||
ColorWheelIcon,
|
||||
Cross2Icon,
|
||||
EyeOpenIcon,
|
||||
GearIcon,
|
||||
HomeIcon,
|
||||
MoonIcon,
|
||||
ListBulletIcon,
|
||||
PaperPlaneIcon,
|
||||
PlusCircledIcon,
|
||||
PlusIcon,
|
||||
@@ -19,59 +21,40 @@ import {
|
||||
TriangleLeftIcon,
|
||||
TriangleRightIcon,
|
||||
UpdateIcon,
|
||||
RowsIcon,
|
||||
} from '@radix-ui/react-icons';
|
||||
import classnames from 'classnames';
|
||||
import type { NamedExoticComponent } from 'react';
|
||||
|
||||
type IconName =
|
||||
| 'archive'
|
||||
| 'home'
|
||||
| 'camera'
|
||||
| 'gear'
|
||||
| 'eye'
|
||||
| 'triangleDown'
|
||||
| 'triangleLeft'
|
||||
| 'triangleRight'
|
||||
| 'paperPlane'
|
||||
| 'update'
|
||||
| 'question'
|
||||
| 'check'
|
||||
| 'plus'
|
||||
| 'plusCircle'
|
||||
| 'clock'
|
||||
| 'sun'
|
||||
| 'code'
|
||||
| 'x'
|
||||
| 'trash'
|
||||
| 'moon';
|
||||
|
||||
const icons: Record<IconName, NamedExoticComponent<{ className: string }>> = {
|
||||
paperPlane: PaperPlaneIcon,
|
||||
triangleDown: TriangleDownIcon,
|
||||
plus: PlusIcon,
|
||||
plusCircle: PlusCircledIcon,
|
||||
clock: ClockIcon,
|
||||
const icons = {
|
||||
archive: ArchiveIcon,
|
||||
camera: CameraIcon,
|
||||
check: CheckIcon,
|
||||
triangleLeft: TriangleLeftIcon,
|
||||
triangleRight: TriangleRightIcon,
|
||||
clock: ClockIcon,
|
||||
code: CodeIcon,
|
||||
colorWheel: ColorWheelIcon,
|
||||
eye: EyeOpenIcon,
|
||||
gear: GearIcon,
|
||||
home: HomeIcon,
|
||||
update: UpdateIcon,
|
||||
sun: SunIcon,
|
||||
listBullet: ListBulletIcon,
|
||||
moon: MoonIcon,
|
||||
x: Cross2Icon,
|
||||
paperPlane: PaperPlaneIcon,
|
||||
plus: PlusIcon,
|
||||
plusCircle: PlusCircledIcon,
|
||||
question: QuestionMarkIcon,
|
||||
eye: EyeOpenIcon,
|
||||
code: CodeIcon,
|
||||
rows: RowsIcon,
|
||||
sun: SunIcon,
|
||||
trash: TrashIcon,
|
||||
triangleDown: TriangleDownIcon,
|
||||
triangleLeft: TriangleLeftIcon,
|
||||
triangleRight: TriangleRightIcon,
|
||||
update: UpdateIcon,
|
||||
x: Cross2Icon,
|
||||
};
|
||||
|
||||
export interface IconProps {
|
||||
icon: IconName;
|
||||
icon: keyof typeof icons;
|
||||
className?: string;
|
||||
size?: 'md';
|
||||
size?: 'xs' | 'sm' | 'md';
|
||||
spin?: boolean;
|
||||
}
|
||||
|
||||
@@ -83,6 +66,8 @@ export function Icon({ icon, spin, size = 'md', className }: IconProps) {
|
||||
className,
|
||||
'text-gray-800',
|
||||
size === 'md' && 'h-4 w-4',
|
||||
size === 'sm' && 'h-3 w-3',
|
||||
size === 'xs' && 'h-2 w-2',
|
||||
spin && 'animate-spin',
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
import classnames from 'classnames';
|
||||
import { forwardRef } from 'react';
|
||||
import type { IconProps } from './Icon';
|
||||
import { Icon } from './Icon';
|
||||
import type { ButtonProps } from './Button';
|
||||
import { Button } from './Button';
|
||||
import classnames from 'classnames';
|
||||
import type { IconProps } from './Icon';
|
||||
import { Icon } from './Icon';
|
||||
|
||||
type Props = Omit<IconProps, 'size'> &
|
||||
ButtonProps<typeof Button> & {
|
||||
iconClassName?: string;
|
||||
};
|
||||
type Props = IconProps & ButtonProps & { iconClassName?: string; iconSize?: IconProps['size'] };
|
||||
|
||||
export const IconButton = forwardRef<HTMLButtonElement, Props>(function IconButton(
|
||||
{ icon, spin, className, iconClassName, ...props }: Props,
|
||||
{ icon, spin, className, iconClassName, size, iconSize, ...props }: Props,
|
||||
ref,
|
||||
) {
|
||||
return (
|
||||
<Button ref={ref} className={classnames(className, 'group')} {...props}>
|
||||
<Button ref={ref} className={classnames(className, 'group')} size={size} {...props}>
|
||||
<Icon
|
||||
size={iconSize}
|
||||
icon={icon}
|
||||
spin={spin}
|
||||
className={classnames(
|
||||
|
||||
@@ -59,13 +59,13 @@ export function Input({
|
||||
{label}
|
||||
</label>
|
||||
<HStack
|
||||
items="center"
|
||||
alignItems="center"
|
||||
className={classnames(
|
||||
containerClassName,
|
||||
'relative w-full rounded-md text-gray-900',
|
||||
'border border-gray-200 focus-within:border-blue-400/40',
|
||||
size === 'md' && 'h-10',
|
||||
size === 'sm' && 'h-8',
|
||||
size === 'md' && 'h-9',
|
||||
size === 'sm' && 'h-7',
|
||||
)}
|
||||
>
|
||||
{leftSlot}
|
||||
|
||||
@@ -38,9 +38,9 @@ export function RequestPane({ fullHeight, request, className }: Props) {
|
||||
{['JSON', 'Params', 'Headers', 'Auth'].map((label, i) => (
|
||||
<Button
|
||||
key={label}
|
||||
size="xs"
|
||||
color={i === 0 && 'gray'}
|
||||
className={i !== 0 && 'opacity-80 hover:opacity-100'}
|
||||
size="sm"
|
||||
color={i === 0 ? 'gray' : undefined}
|
||||
className={i !== 0 ? 'opacity-80 hover:opacity-100' : undefined}
|
||||
>
|
||||
{label}
|
||||
</Button>
|
||||
|
||||
@@ -61,7 +61,7 @@ export function ResponsePane({ requestId, className }: Props) {
|
||||
{response && (
|
||||
<>
|
||||
<HStack
|
||||
items="center"
|
||||
alignItems="center"
|
||||
className="italic text-gray-600 text-sm w-full mb-1 flex-shrink-0 pl-2"
|
||||
>
|
||||
{response.status > 0 && (
|
||||
@@ -76,7 +76,7 @@ export function ResponsePane({ requestId, className }: Props) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<HStack items="center" className="ml-auto h-8">
|
||||
<HStack alignItems="center" className="ml-auto h-8">
|
||||
{contentType.includes('html') && (
|
||||
<IconButton
|
||||
icon={viewMode === 'pretty' ? 'eye' : 'code'}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import classnames from 'classnames';
|
||||
import type { HTMLAttributes } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { SketchPicker } from 'react-color';
|
||||
import { useRequestCreate } from '../hooks/useRequest';
|
||||
import useTheme from '../hooks/useTheme';
|
||||
import type { HttpRequest } from '../lib/models';
|
||||
import { Button } from './Button';
|
||||
import { ButtonLink } from './ButtonLink';
|
||||
import { Dialog } from './Dialog';
|
||||
import { HeaderEditor } from './HeaderEditor';
|
||||
import { IconButton } from './IconButton';
|
||||
@@ -20,28 +21,27 @@ interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
||||
|
||||
export function Sidebar({ className, activeRequestId, workspaceId, requests, ...props }: Props) {
|
||||
const createRequest = useRequestCreate({ workspaceId, navigateAfter: true });
|
||||
const { appearance, toggleAppearance } = useTheme();
|
||||
const { appearance, toggleAppearance, forceSetTheme } = useTheme();
|
||||
const [open, setOpen] = useState<boolean>(false);
|
||||
const [color, setColor] = useState<string>('blue');
|
||||
const [showPicker, setShowPicker] = useState<boolean>(false);
|
||||
return (
|
||||
<div
|
||||
className={classnames(className, 'w-52 bg-gray-100 h-full border-r border-gray-200')}
|
||||
className={classnames(
|
||||
className,
|
||||
'min-w-[10rem] bg-gray-100 h-full border-r border-gray-200 relative',
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<HStack as={WindowDragRegion} items="center" justify="end">
|
||||
<HStack as={WindowDragRegion} alignItems="center" justifyContent="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(true)} />
|
||||
<IconButton
|
||||
size="sm"
|
||||
icon={appearance === 'dark' ? 'moon' : 'sun'}
|
||||
onClick={toggleAppearance}
|
||||
/>
|
||||
<IconButton
|
||||
size="sm"
|
||||
className="mx-1"
|
||||
icon="plusCircle"
|
||||
onClick={async () => {
|
||||
await createRequest.mutate({ name: 'Test Request' });
|
||||
@@ -53,6 +53,27 @@ export function Sidebar({ className, activeRequestId, workspaceId, requests, ...
|
||||
<SidebarItem key={r.id} request={r} active={r.id === activeRequestId} />
|
||||
))}
|
||||
{/*<Colors />*/}
|
||||
|
||||
<HStack
|
||||
className="absolute bottom-1 left-1 right-0 mx-1"
|
||||
alignItems="center"
|
||||
justifyContent="end"
|
||||
>
|
||||
<IconButton icon="colorWheel" onClick={() => setShowPicker((p) => !p)} />
|
||||
<IconButton icon={appearance === 'dark' ? 'moon' : 'sun'} onClick={toggleAppearance} />
|
||||
<IconButton icon="rows" onClick={() => setOpen(true)} />
|
||||
</HStack>
|
||||
|
||||
{showPicker && (
|
||||
<SketchPicker
|
||||
className="fixed z-10 bottom-2 right-2"
|
||||
color={color}
|
||||
onChange={(c) => {
|
||||
setColor(c.hex);
|
||||
forceSetTheme(c.hex);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</VStack>
|
||||
</div>
|
||||
);
|
||||
@@ -61,15 +82,16 @@ export function Sidebar({ className, activeRequestId, workspaceId, requests, ...
|
||||
function SidebarItem({ request, active }: { request: HttpRequest; active: boolean }) {
|
||||
return (
|
||||
<li key={request.id}>
|
||||
<Button
|
||||
as={Link}
|
||||
<ButtonLink
|
||||
color="custom"
|
||||
to={`/workspaces/${request.workspaceId}/requests/${request.id}`}
|
||||
className={classnames('w-full', active ? 'bg-gray-200/70 text-gray-900' : 'text-gray-500')}
|
||||
size="xs"
|
||||
disabled={active}
|
||||
className={classnames('w-full', active ? 'bg-gray-200/70 text-gray-900' : 'text-gray-600')}
|
||||
size="sm"
|
||||
justify="start"
|
||||
>
|
||||
{request.name || request.url}
|
||||
</Button>
|
||||
</ButtonLink>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { HTMLAttributes, ReactNode } from 'react';
|
||||
import React, { Children, Fragment } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import type { ReactNode } from 'react';
|
||||
import React, { Children, Fragment } from 'react';
|
||||
|
||||
const spaceClassesX = {
|
||||
0: 'pr-0',
|
||||
@@ -78,26 +78,35 @@ export function VStack({ className, space, children, ...props }: VStackProps) {
|
||||
);
|
||||
}
|
||||
|
||||
interface BaseStackProps extends HTMLAttributes<HTMLElement> {
|
||||
items?: 'start' | 'center';
|
||||
justify?: 'start' | 'center' | 'end';
|
||||
interface BaseStackProps {
|
||||
as?: React.ElementType;
|
||||
alignItems?: 'start' | 'center';
|
||||
justifyContent?: 'start' | 'center' | 'end';
|
||||
className?: string;
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
function BaseStack({ className, items, justify, as = 'div', ...props }: BaseStackProps) {
|
||||
function BaseStack({
|
||||
className,
|
||||
alignItems,
|
||||
justifyContent,
|
||||
children,
|
||||
as = 'div',
|
||||
}: BaseStackProps) {
|
||||
const Component = as;
|
||||
return (
|
||||
<Component
|
||||
className={classnames(
|
||||
className,
|
||||
'flex flex-grow-0',
|
||||
items === 'center' && 'items-center',
|
||||
items === 'start' && 'items-start',
|
||||
justify === 'start' && 'justify-start',
|
||||
justify === 'center' && 'justify-center',
|
||||
justify === 'end' && 'justify-end',
|
||||
alignItems === 'center' && 'items-center',
|
||||
alignItems === 'start' && 'items-start',
|
||||
justifyContent === 'start' && 'justify-start',
|
||||
justifyContent === 'center' && 'justify-center',
|
||||
justifyContent === 'end' && 'justify-end',
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
>
|
||||
{children}
|
||||
</Component>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { DropdownMenuRadio } from './Dropdown';
|
||||
import { Button } from './Button';
|
||||
import { Input } from './Input';
|
||||
import type { FormEvent } from 'react';
|
||||
import { Button } from './Button';
|
||||
import { DropdownMenuRadio } from './Dropdown';
|
||||
import { IconButton } from './IconButton';
|
||||
import { Input } from './Input';
|
||||
|
||||
interface Props {
|
||||
sendRequest: () => void;
|
||||
@@ -24,7 +24,6 @@ export function UrlBar({ sendRequest, loading, onMethodChange, method, onUrlChan
|
||||
<Input
|
||||
hideLabel
|
||||
useEditor={{ useTemplating: true, contentType: 'url' }}
|
||||
size="sm"
|
||||
className="font-mono px-0"
|
||||
name="url"
|
||||
label="Enter URL"
|
||||
@@ -46,7 +45,7 @@ export function UrlBar({ sendRequest, loading, onMethodChange, method, onUrlChan
|
||||
{ label: 'HEAD', value: 'HEAD' },
|
||||
]}
|
||||
>
|
||||
<Button type="button" disabled={loading} size="xs" className="mx-0.5" justify="start">
|
||||
<Button type="button" disabled={loading} size="sm" className="mx-0.5" justify="start">
|
||||
{method.toUpperCase()}
|
||||
</Button>
|
||||
</DropdownMenuRadio>
|
||||
@@ -55,7 +54,7 @@ export function UrlBar({ sendRequest, loading, onMethodChange, method, onUrlChan
|
||||
<IconButton
|
||||
type="submit"
|
||||
className="mr-0.5"
|
||||
size="xs"
|
||||
size="sm"
|
||||
icon={loading ? 'update' : 'paperPlane'}
|
||||
spin={loading}
|
||||
disabled={loading}
|
||||
|
||||
@@ -7,7 +7,7 @@ export function WindowDragRegion({ className, ...props }: Props) {
|
||||
return (
|
||||
<div
|
||||
data-tauri-drag-region
|
||||
className={classnames(className, 'w-full h-10 flex-shrink-0')}
|
||||
className={classnames(className, 'w-full h-12 flex-shrink-0')}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user