import clsx from "clsx"; import Link from "next/link"; type Variant = "solid" | "line"; /* * Matches site/'s .btn--solid and .btn--line exactly, including the neutral * border on the secondary variant. site/ does not have an accent-outlined * button and this app should not invent one. */ /* * The height every form control resolves to, buttons included. * * Padding alone cannot align them: a select is mono at 0.84rem and a button is * sans at 0.94rem, so identical padding still leaves them ~7px apart and a * filter row looks assembled from two different kits. It is the height the * button's own padding already computed to, so buttons do not move — everything * else comes up to meet them. */ export const CONTROL_HEIGHT = "h-11"; /* * An input or select that sits on a form row with a button. Mono, because in * this product the values typed into these are addresses, UUIDs and price IDs. */ export function controlClass(className?: string) { return clsx( CONTROL_HEIGHT, "w-full rounded border border-rule bg-panel-2 px-2.5 font-mono text-[0.88rem] text-ink", "focus:border-accent focus:outline-none", className, ); } export function buttonClass(variant: Variant = "solid", disabled = false, className?: string) { return clsx( "inline-flex items-center gap-2 rounded border px-4 text-[0.94rem] font-semibold", CONTROL_HEIGHT, "transition-[filter,border-color] duration-150 hover:brightness-110", variant === "solid" ? "border-accent bg-accent text-accent-ink" : "border-rule bg-panel text-ink hover:border-ink-3", disabled && "cursor-not-allowed border-rule bg-panel text-ink-3 hover:brightness-100", className, ); } type Props = React.ButtonHTMLAttributes & { variant?: Variant }; export function Button({ variant = "solid", className, ...rest }: Props) { return