Custom font sizes and better zoom

This commit is contained in:
Gregory Schier
2024-05-29 12:10:01 -07:00
parent 5eb2e2b5a2
commit 8cd3961f87
55 changed files with 487 additions and 217 deletions

View File

@@ -71,7 +71,7 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button
justify === 'start' && 'justify-start',
justify === 'center' && 'justify-center',
size === 'md' && 'h-md px-3 rounded-md',
size === 'sm' && 'h-sm px-2.5 text-sm rounded-md',
size === 'sm' && 'h-sm px-2.5 rounded-md',
size === 'xs' && 'h-xs px-2 text-sm rounded-md',
size === '2xs' && 'h-5 px-1 text-xs rounded',

View File

@@ -28,7 +28,7 @@ export function Checkbox({
as="label"
space={2}
alignItems="center"
className={classNames(className, 'text-fg text-sm', disabled && 'opacity-disabled')}
className={classNames(className, 'text-fg', disabled && 'opacity-disabled')}
>
<div className={classNames(inputWrapperClassName, 'x-theme-input', 'relative flex')}>
<input

View File

@@ -448,16 +448,14 @@ const Menu = forwardRef<Omit<DropdownRef, 'open' | 'isOpen' | 'toggle'>, MenuPro
<HStack
space={2}
alignItems="center"
className="pb-0.5 px-1.5 mb-2 text-xs border border-background-highlight-secondary mx-2 rounded font-mono h-2xs"
className="pb-0.5 px-1.5 mb-2 text-sm border border-background-highlight-secondary mx-2 rounded font-mono h-2xs"
>
<Icon icon="search" size="xs" className="text-fg-subtle" />
<div className="text-fg">{filter}</div>
</HStack>
)}
{filteredItems.length === 0 && (
<span className="text-fg-subtler text-sm text-center px-2 py-1">
No matches
</span>
<span className="text-fg-subtler text-center px-2 py-1">No matches</span>
)}
{filteredItems.map((item, i) => {
if (item.type === 'separator') {
@@ -531,14 +529,18 @@ function MenuItem({ className, focused, onFocus, item, onSelect, ...props }: Men
onFocus={handleFocus}
onClick={handleClick}
justify="start"
leftSlot={item.leftSlot && <div className="pr-2 flex justify-start">{item.leftSlot}</div>}
leftSlot={
item.leftSlot && (
<div className="pr-2 flex justify-start text-fg-subtle">{item.leftSlot}</div>
)
}
rightSlot={rightSlot && <div className="ml-auto pl-3">{rightSlot}</div>}
innerClassName="!text-left"
color="custom"
className={classNames(
className,
'h-xs', // More compact
'min-w-[8rem] outline-none px-2 mx-1.5 flex text-sm whitespace-nowrap',
'min-w-[8rem] outline-none px-2 mx-1.5 flex whitespace-nowrap',
'focus:bg-background-highlight focus:text-fg rounded',
item.variant === 'default' && 'text-fg-subtle',
item.variant === 'danger' && 'text-fg-danger',

View File

@@ -104,8 +104,7 @@
}
.cm-scroller {
@apply font-mono text-[0.75rem];
@apply font-mono text-editor;
/*
* Round corners or they'll stick out of the editor bounds of editor is rounded.
* Could potentially be pushed up from the editor like we do with bg color but this
@@ -185,7 +184,7 @@
}
.cm-tooltip.cm-tooltip-hover {
@apply shadow-lg bg-background rounded text-fg-subtle border border-fg-subtler z-50 pointer-events-auto text-xs;
@apply shadow-lg bg-background rounded text-fg-subtle border border-fg-subtler z-50 pointer-events-auto text-sm;
@apply px-2 py-1;
a {
@@ -208,7 +207,7 @@
/* NOTE: Extra selector required to override default styles */
.cm-tooltip.cm-tooltip-autocomplete,
.cm-tooltip.cm-completionInfo {
@apply shadow-lg bg-background rounded text-fg-subtle border border-background-highlight z-50 pointer-events-auto text-xs;
@apply shadow-lg bg-background rounded text-fg-subtle border border-background-highlight z-50 pointer-events-auto text-sm;
.cm-completionIcon {
@apply italic font-mono;
@@ -267,7 +266,7 @@
}
&.cm-completionInfo-right {
@apply ml-1 -mt-0.5 text-sm;
@apply ml-1 -mt-0.5;
}
&.cm-completionInfo-right-narrow {
@@ -279,12 +278,14 @@
}
&.cm-tooltip-autocomplete {
@apply font-mono text-editor;
& > ul {
@apply p-1 max-h-[40vh];
}
& > ul > li {
@apply cursor-default px-2 rounded-sm text-fg-subtle h-7 flex items-center;
@apply cursor-default px-2 py-1.5 rounded-sm text-fg-subtle flex items-center;
}
& > ul > li[aria-selected] {
@@ -292,7 +293,7 @@
}
.cm-completionIcon {
@apply text-xs flex items-center pb-0.5 flex-shrink-0;
@apply text-sm flex items-center pb-0.5 flex-shrink-0;
}
.cm-completionLabel {

View File

@@ -9,7 +9,7 @@ export function FormattedError({ children }: Props) {
return (
<pre
className={classNames(
'w-full text-sm select-auto cursor-text bg-gray-100 p-3 rounded',
'w-full select-auto cursor-text bg-gray-100 p-3 rounded',
'whitespace-pre-wrap border border-fg-danger border-dashed overflow-x-auto',
)}
>

View File

@@ -7,5 +7,5 @@ interface Props {
export function HotKeyLabel({ action }: Props) {
const label = useHotKeyLabel(action);
return <span className="text-fg-subtle">{label}</span>;
return <span className="text-fg-subtle whitespace-nowrap">{label}</span>;
}

View File

@@ -11,7 +11,7 @@ interface Props {
export const HotKeyList = ({ hotkeys, bottomSlot }: Props) => {
return (
<div className="h-full flex items-center justify-center text-sm">
<div className="h-full flex items-center justify-center">
<VStack space={2}>
{hotkeys.map((hotkey) => (
<HStack key={hotkey} className="grid grid-cols-2">

View File

@@ -27,7 +27,7 @@ export function HttpMethodTag({ request, className }: Props) {
const m = method.toLowerCase();
return (
<span className={classNames(className, 'text-2xs font-mono text-fg-subtle')}>
<span className={classNames(className, 'text-xs font-mono text-fg-subtle')}>
{methodMap[m] ?? m.slice(0, 3).toUpperCase()}
</span>
);

View File

@@ -6,8 +6,8 @@ export function InlineCode({ className, ...props }: HTMLAttributes<HTMLSpanEleme
<code
className={classNames(
className,
'font-mono text-xs bg-background-highlight-secondary border border-background-highlight',
'px-1.5 py-0.5 rounded text-fg-info shadow-inner',
'font-mono text-shrink bg-background-highlight-secondary border border-background-highlight',
'px-1.5 py-0.5 rounded text-fg shadow-inner',
)}
{...props}
/>

View File

@@ -133,11 +133,7 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
>
<label
htmlFor={id}
className={classNames(
labelClassName,
'text-sm text-fg whitespace-nowrap',
hideLabel && 'sr-only',
)}
className={classNames(labelClassName, 'text-fg whitespace-nowrap', hideLabel && 'sr-only')}
>
{label}
</label>

View File

@@ -80,7 +80,7 @@ export const JsonAttributeTree = ({ depth = 0, attrKey, attrValue, attrKeyJsonPa
<span className={classNames(labelClassName, 'select-text group-hover:text-fg')}>{label}</span>
);
return (
<div className={classNames(/*depth === 0 && '-ml-4',*/ 'font-mono text-2xs')}>
<div className={classNames(/*depth === 0 && '-ml-4',*/ 'font-mono text-xs')}>
<div className="flex items-center">
{isExpandable ? (
<button className="group relative flex items-center pl-4 w-full" onClick={toggleExpanded}>

View File

@@ -389,7 +389,7 @@ function PairEditorRow({
<Button
size="xs"
color="secondary"
className="font-mono text-xs"
className="font-mono text-sm"
onClick={async (e) => {
e.preventDefault();
const selected = await open({

View File

@@ -0,0 +1,148 @@
import classNames from 'classnames';
import { forwardRef, useCallback, useMemo, useRef, useState } from 'react';
import { useStateWithDeps } from '../../hooks/useStateWithDeps';
import { IconButton } from './IconButton';
import type { InputProps } from './Input';
import { HStack } from './Stacks';
export type PlainInputProps = Omit<InputProps, 'wrapLines' | 'onKeyDown' | 'type'> & {
type: 'text' | 'password' | 'number';
};
export const PlainInput = forwardRef<HTMLInputElement, PlainInputProps>(function Input(
{
className,
containerClassName,
defaultValue,
forceUpdateKey,
hideLabel,
label,
labelClassName,
labelPosition = 'top',
leftSlot,
name,
onBlur,
onChange,
onFocus,
onPaste,
placeholder,
require,
rightSlot,
size = 'md',
type = 'text',
validate,
...props
}: PlainInputProps,
ref,
) {
const [obscured, setObscured] = useStateWithDeps(type === 'password', [type]);
const [currentValue, setCurrentValue] = useState(defaultValue ?? '');
const [focused, setFocused] = useState(false);
const handleFocus = useCallback(() => {
setFocused(true);
onFocus?.();
}, [onFocus]);
const handleBlur = useCallback(() => {
setFocused(false);
onBlur?.();
}, [onBlur]);
const id = `input-${name}`;
const inputClassName = classNames(
className,
'!bg-transparent min-w-0 h-auto w-full focus:outline-none placeholder:text-placeholder',
'px-1.5 text-xs font-mono',
);
const isValid = useMemo(() => {
if (require && !validateRequire(currentValue)) return false;
if (validate && !validate(currentValue)) return false;
return true;
}, [currentValue, validate, require]);
const handleChange = useCallback(
(value: string) => {
setCurrentValue(value);
onChange?.(value);
},
[onChange],
);
const wrapperRef = useRef<HTMLDivElement>(null);
return (
<div
ref={wrapperRef}
className={classNames(
'w-full',
'pointer-events-auto', // Just in case we're placing in disabled parent
labelPosition === 'left' && 'flex items-center gap-2',
labelPosition === 'top' && 'flex-row gap-0.5',
)}
>
<label
htmlFor={id}
className={classNames(labelClassName, 'text-fg whitespace-nowrap', hideLabel && 'sr-only')}
>
{label}
</label>
<HStack
alignItems="stretch"
className={classNames(
containerClassName,
'x-theme-input',
'relative w-full rounded-md text-fg',
'border',
focused ? 'border-border-focus' : 'border-background-highlight',
!isValid && '!border-fg-danger',
size === 'md' && 'min-h-md',
size === 'sm' && 'min-h-sm',
size === 'xs' && 'min-h-xs',
)}
>
{leftSlot}
<HStack
alignItems="center"
className={classNames(
'w-full min-w-0',
leftSlot && 'pl-0.5 -ml-2',
rightSlot && 'pr-0.5 -mr-2',
)}
>
<input
ref={ref}
key={forceUpdateKey}
id={id}
type={type === 'password' && !obscured ? 'text' : type}
defaultValue={defaultValue}
placeholder={placeholder}
onChange={(e) => handleChange(e.target.value)}
onPaste={(e) => onPaste?.(e.clipboardData.getData('Text'))}
className={inputClassName}
onFocus={handleFocus}
onBlur={handleBlur}
{...props}
/>
</HStack>
{type === 'password' && (
<IconButton
title={obscured ? `Show ${label}` : `Obscure ${label}`}
size="xs"
className="mr-0.5 group/obscure !h-auto my-0.5"
iconClassName="text-fg-subtle group-hover/obscure:text-fg"
iconSize="sm"
icon={obscured ? 'eye' : 'eyeClosed'}
onClick={() => setObscured((o) => !o)}
/>
)}
{rightSlot}
</HStack>
</div>
);
});
function validateRequire(v: string) {
return v.length > 0;
}

View File

@@ -45,11 +45,7 @@ export function Select<T extends string>({
>
<label
htmlFor={id}
className={classNames(
labelClassName,
'text-sm text-fg whitespace-nowrap',
hideLabel && 'sr-only',
)}
className={classNames(labelClassName, 'text-fg whitespace-nowrap', hideLabel && 'sr-only')}
>
{label}
</label>
@@ -58,7 +54,7 @@ export function Select<T extends string>({
style={selectBackgroundStyles}
onChange={(e) => onChange(e.target.value as T)}
className={classNames(
'font-mono text-xs border w-full outline-none bg-transparent pl-2 pr-7',
'font-mono text-sm border w-full outline-none bg-transparent pl-2 pr-7',
'bg-background-highlight-secondary border-background-highlight focus:border-border-focus',
size === 'xs' && 'h-xs',
size === 'sm' && 'h-sm',

View File

@@ -11,7 +11,7 @@ interface Props {
export function Separator({ className, orientation = 'horizontal', children }: Props) {
return (
<div role="separator" className={classNames(className, 'flex items-center')}>
{children && <div className="text-xs text-fg-subtler mr-2 whitespace-nowrap">{children}</div>}
{children && <div className="text-sm text-fg-subtler mr-2 whitespace-nowrap">{children}</div>}
<div
className={classNames(
'bg-background-highlight',

View File

@@ -84,7 +84,7 @@ export function Tabs({
{tabs.map((t) => {
const isActive = t.value === value;
const btnClassName = classNames(
'h-full flex items-center text-sm rounded',
'h-full flex items-center rounded',
'!px-2 ml-[1px]',
addBorders && 'border',
isActive ? 'text-fg' : 'text-fg-subtle hover:text-fg',