mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-17 23:13:51 +01:00
Split up HTTP sending logic (#320)
This commit is contained in:
@@ -61,7 +61,6 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button
|
||||
'x-theme-button',
|
||||
`x-theme-button--${variant}`,
|
||||
`x-theme-button--${variant}--${color}`,
|
||||
'text-text',
|
||||
'border', // They all have borders to ensure the same width
|
||||
'max-w-full min-w-0', // Help with truncation
|
||||
'hocus:opacity-100', // Force opacity for certain hover effects
|
||||
@@ -81,7 +80,7 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button
|
||||
variant === 'solid' && color === 'custom' && 'focus-visible:outline-2 outline-border-focus',
|
||||
variant === 'solid' &&
|
||||
color !== 'custom' &&
|
||||
'enabled:hocus:text-text enabled:hocus:bg-surface-highlight outline-border-subtle',
|
||||
'text-text enabled:hocus:text-text enabled:hocus:bg-surface-highlight outline-border-subtle',
|
||||
variant === 'solid' && color !== 'custom' && color !== 'default' && 'bg-surface',
|
||||
|
||||
// Borders
|
||||
|
||||
@@ -3,11 +3,12 @@ import classNames from 'classnames';
|
||||
|
||||
interface Props {
|
||||
count: number | true;
|
||||
count2?: number | true;
|
||||
className?: string;
|
||||
color?: Color;
|
||||
}
|
||||
|
||||
export function CountBadge({ count, className, color }: Props) {
|
||||
export function CountBadge({ count, count2, className, color }: Props) {
|
||||
if (count === 0) return null;
|
||||
return (
|
||||
<div
|
||||
@@ -30,6 +31,16 @@ export function CountBadge({ count, className, color }: Props) {
|
||||
) : (
|
||||
count
|
||||
)}
|
||||
{count2 != null && (
|
||||
<>
|
||||
/
|
||||
{count2 === true ? (
|
||||
<div aria-hidden className="rounded-full h-1 w-1 bg-[currentColor]" />
|
||||
) : (
|
||||
count2
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,19 +1,48 @@
|
||||
import classNames from 'classnames';
|
||||
import { atom, useAtom } from 'jotai';
|
||||
import type { HTMLAttributes, ReactNode } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import { atomWithKVStorage } from '../../lib/atoms/atomWithKVStorage';
|
||||
import type { BannerProps } from './Banner';
|
||||
import { Banner } from './Banner';
|
||||
|
||||
interface Props extends HTMLAttributes<HTMLDetailsElement> {
|
||||
summary: ReactNode;
|
||||
color?: BannerProps['color'];
|
||||
open?: boolean;
|
||||
defaultOpen?: boolean;
|
||||
storageKey?: string;
|
||||
}
|
||||
|
||||
export function DetailsBanner({ className, color, summary, children, ...extraProps }: Props) {
|
||||
export function DetailsBanner({
|
||||
className,
|
||||
color,
|
||||
summary,
|
||||
children,
|
||||
defaultOpen,
|
||||
storageKey,
|
||||
...extraProps
|
||||
}: Props) {
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: We only want to recompute the atom when storageKey changes
|
||||
const openAtom = useMemo(
|
||||
() =>
|
||||
storageKey
|
||||
? atomWithKVStorage<boolean>(['details_banner', storageKey], defaultOpen ?? false)
|
||||
: atom(defaultOpen ?? false),
|
||||
[storageKey],
|
||||
);
|
||||
|
||||
const [isOpen, setIsOpen] = useAtom(openAtom);
|
||||
|
||||
const handleToggle = (e: React.SyntheticEvent<HTMLDetailsElement>) => {
|
||||
if (storageKey) {
|
||||
setIsOpen(e.currentTarget.open);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Banner color={color} className={className}>
|
||||
<details className="group list-none" {...extraProps}>
|
||||
<summary className="!cursor-default !select-none list-none flex items-center gap-2 focus:outline-none opacity-70 hover:opacity-100 focus:opacity-100">
|
||||
<details className="group list-none" open={isOpen} onToggle={handleToggle} {...extraProps}>
|
||||
<summary className="!cursor-default !select-none list-none flex items-center gap-3 focus:outline-none opacity-70">
|
||||
<div
|
||||
className={classNames(
|
||||
'transition-transform',
|
||||
|
||||
@@ -12,7 +12,9 @@ import {
|
||||
ArrowDownIcon,
|
||||
ArrowDownToDotIcon,
|
||||
ArrowDownToLineIcon,
|
||||
ArrowLeftIcon,
|
||||
ArrowRightCircleIcon,
|
||||
ArrowRightIcon,
|
||||
ArrowUpDownIcon,
|
||||
ArrowUpFromDotIcon,
|
||||
ArrowUpFromLineIcon,
|
||||
@@ -142,6 +144,8 @@ const icons = {
|
||||
arrow_down: ArrowDownIcon,
|
||||
arrow_down_to_dot: ArrowDownToDotIcon,
|
||||
arrow_down_to_line: ArrowDownToLineIcon,
|
||||
arrow_left: ArrowLeftIcon,
|
||||
arrow_right: ArrowRightIcon,
|
||||
arrow_right_circle: ArrowRightCircleIcon,
|
||||
arrow_up: ArrowUpIcon,
|
||||
arrow_up_down: ArrowUpDownIcon,
|
||||
|
||||
@@ -2,11 +2,18 @@ import { formatSize } from '@yaakapp-internal/lib/formatSize';
|
||||
|
||||
interface Props {
|
||||
contentLength: number;
|
||||
contentLengthCompressed?: number | null;
|
||||
}
|
||||
|
||||
export function SizeTag({ contentLength }: Props) {
|
||||
export function SizeTag({ contentLength, contentLengthCompressed }: Props) {
|
||||
return (
|
||||
<span className="font-mono" title={`${contentLength} bytes`}>
|
||||
<span
|
||||
className="font-mono"
|
||||
title={
|
||||
`${contentLength} bytes` +
|
||||
(contentLengthCompressed ? `\n${contentLengthCompressed} bytes compressed` : '')
|
||||
}
|
||||
>
|
||||
{formatSize(contentLength)}
|
||||
</span>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user