feat(console-web): add variant-based UI primitives

Introduce cva-driven Button, form, card, table, and segmented controls.

Use clsx and tailwind-merge through a shared cn helper so callers can override component defaults without relying on global semantic CSS. Control sizes define minimum heights while icon-only actions retain stable square dimensions.
This commit is contained in:
Maofeng
2026-07-30 15:16:02 +08:00
parent 868da49a52
commit 23fa6137ff
11 changed files with 513 additions and 92 deletions
@@ -0,0 +1,43 @@
import { cva, type VariantProps } from "class-variance-authority";
import { splitProps, type JSX } from "solid-js";
import { cn } from "../../lib/cn";
export const textareaVariants = cva(
"min-h-36 w-full rounded-md border border-line bg-white px-3 py-3 text-sm text-ink outline-none transition-colors focus:border-brand disabled:cursor-not-allowed disabled:opacity-45 aria-invalid:border-coral-strong",
{
variants: {
resize: {
vertical: "resize-y",
none: "resize-none",
},
typography: {
mono: "font-mono",
sans: "font-sans",
},
},
defaultVariants: {
resize: "vertical",
typography: "mono",
},
},
);
export type TextareaProps = JSX.TextareaHTMLAttributes<HTMLTextAreaElement> &
VariantProps<typeof textareaVariants>;
/** Standard multiline input with explicit resize and typography variants. */
export function Textarea(props: TextareaProps) {
const [local, rest] = splitProps(props, ["resize", "typography", "class", "children"]);
return (
<textarea
{...rest}
data-slot="textarea"
class={cn(
textareaVariants({ resize: local.resize, typography: local.typography }),
local.class,
)}
>
{local.children}
</textarea>
);
}