button-component #29

Merged
stne3960 merged 22 commits from button-component into main 2025-12-12 11:52:31 +01:00
3 changed files with 44 additions and 33 deletions
Showing only changes of commit 3368565fb1 - Show all commits

View File

@ -9,6 +9,7 @@
"version": "0.0.0",
"dependencies": {
"@tailwindcss/vite": "^4.1.16",
"clsx": "^2.1.1",
"openapi-fetch": "^0.13.5",
"react": "^19.0.0",
"react-dom": "^19.0.0",
@ -2033,6 +2034,15 @@
"dev": true,
"license": "MIT"
},
"node_modules/clsx": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",

View File

@ -13,6 +13,7 @@
},
"dependencies": {
"@tailwindcss/vite": "^4.1.16",
"clsx": "^2.1.1",
"openapi-fetch": "^0.13.5",
"react": "^19.0.0",
"react-dom": "^19.0.0",

View File

@ -1,4 +1,5 @@
import type { ButtonHTMLAttributes, ReactNode } from "react";
import clsx from "clsx";
export type ButtonVariant = "primary" | "secondary" | "red" | "green";
export type ButtonSize = "sm" | "md" | "lg";
@ -10,35 +11,36 @@ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
}
const variantClasses: Record<ButtonVariant, string> = {
primary: `
bg-primary text-base-canvas
border border-primary
hover:bg-secondary hover:text-base-canvas
hover:border hover:border-primary
focus-visible:bg-base-canvas focus-visible:text-base-ink-strong
focus-visible:border focus-visible:border-primary
focus-visible:outline focus-visible:outline-[length:var(--border-width-lg)] focus-visible:outline-sky-100
`.trim(),
secondary: `bg-base-canvas text-base-ink-strong
border-solid [border-width:var(--border-width-sm)] border-base-ink-soft
hover:bg-base-canvas hover:text-base-ink-strong
hover:border-base-ink-medium
focus-visible:bg-base-canvas focus-visible:text-base-ink-strong
focus-visible:border-primary
focus-visible:outline focus-visible:outline-[length:var(--border-width-lg)] focus-visible:outline-sky-100
`.trim(),
red: `
bg-other-red-100 text-su-white
focus-visible:bg-base-canvas focus-visible:text-base-ink-strong
focus-visible:border-primary focus-visible:border
focus-visible:outline focus-visible:outline-[length:var(--border-width-lg)] focus-visible:outline-sky-100
`.trim(),
green: `
bg-other-green text-su-white
focus-visible:bg-base-canvas focus-visible:text-base-ink-strong
focus-visible:border-primary focus-visible:border
focus-visible:outline focus-visible:outline-[length:var(--border-width-lg)] focus-visible:outline-sky-100
`.trim(),
primary: clsx(
stne3960 marked this conversation as resolved Outdated

This is unwieldy. Any way to break it down or group them somehow? Like the border styles, focus styles, colors, and so on.

Is it necessary to repeat the prefix or can you do something like hover:[a, b, c] instead of hover:a hover:b hover:c?

This is unwieldy. Any way to break it down or group them somehow? Like the border styles, focus styles, colors, and so on. Is it necessary to repeat the prefix or can you do something like `hover:[a, b, c]` instead of `hover:a hover:b hover:c`?
"bg-primary text-base-canvas",
"border border-primary",
"hover:bg-secondary hover:text-base-canvas",
"hover:border hover:border-primary",
"focus-visible:bg-base-canvas focus-visible:text-base-ink-strong",
"focus-visible:border focus-visible:border-primary",
"focus-visible:outline focus-visible:outline-[length:var(--border-width-lg)] focus-visible:outline-sky-100",
),
secondary: clsx(
"bg-base-canvas text-base-ink-strong",
"border-solid [border-width:var(--border-width-sm)] border-base-ink-soft",
"hover:bg-base-canvas hover:text-base-ink-strong",
"hover:border-base-ink-medium",
"focus-visible:bg-base-canvas focus-visible:text-base-ink-strong",
"focus-visible:border-primary",
"focus-visible:outline focus-visible:outline-[length:var(--border-width-lg)] focus-visible:outline-sky-100",
),
red: clsx(
"bg-other-red-100 text-su-white",
"focus-visible:bg-base-canvas focus-visible:text-base-ink-strong",
"focus-visible:border-primary focus-visible:border",
"focus-visible:outline focus-visible:outline-[length:var(--border-width-lg)] focus-visible:outline-sky-100",
),
green: clsx(
"bg-other-green text-su-white",
"focus-visible:bg-base-canvas focus-visible:text-base-ink-strong",
"focus-visible:border-primary focus-visible:border",
"focus-visible:outline focus-visible:outline-[length:var(--border-width-lg)] focus-visible:outline-sky-100",
),
};
const sizeClasses: Record<ButtonSize, string> = {
@ -62,14 +64,12 @@ export default function Button({
}: ButtonProps) {
const baseClasses = "inline-flex items-center justify-center cursor-pointer";
const classes = [
const classes = clsx(
baseClasses,
variantClasses[variant],
sizeClasses[size],
className,
]
.filter(Boolean) // Filter out empty strings and undefined values so they won't pollute the class list
.join(" ");
);
return (
<button className={classes} {...props}>