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", "version": "0.0.0",
"dependencies": { "dependencies": {
"@tailwindcss/vite": "^4.1.16", "@tailwindcss/vite": "^4.1.16",
"clsx": "^2.1.1",
"openapi-fetch": "^0.13.5", "openapi-fetch": "^0.13.5",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
@ -2033,6 +2034,15 @@
"dev": true, "dev": true,
"license": "MIT" "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": { "node_modules/color-convert": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",

View File

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

View File

@ -1,4 +1,5 @@
import type { ButtonHTMLAttributes, ReactNode } from "react"; import type { ButtonHTMLAttributes, ReactNode } from "react";
import clsx from "clsx";
export type ButtonVariant = "primary" | "secondary" | "red" | "green"; export type ButtonVariant = "primary" | "secondary" | "red" | "green";
export type ButtonSize = "sm" | "md" | "lg"; export type ButtonSize = "sm" | "md" | "lg";
@ -10,35 +11,36 @@ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
} }
const variantClasses: Record<ButtonVariant, string> = { const variantClasses: Record<ButtonVariant, string> = {
primary: ` 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 "bg-primary text-base-canvas",
border border-primary "border border-primary",
hover:bg-secondary hover:text-base-canvas "hover:bg-secondary hover:text-base-canvas",
hover:border hover:border-primary "hover:border hover:border-primary",
focus-visible:bg-base-canvas focus-visible:text-base-ink-strong "focus-visible:bg-base-canvas focus-visible:text-base-ink-strong",
focus-visible:border focus-visible:border-primary "focus-visible:border focus-visible:border-primary",
focus-visible:outline focus-visible:outline-[length:var(--border-width-lg)] focus-visible:outline-sky-100 "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 secondary: clsx(
border-solid [border-width:var(--border-width-sm)] border-base-ink-soft "bg-base-canvas text-base-ink-strong",
hover:bg-base-canvas hover:text-base-ink-strong "border-solid [border-width:var(--border-width-sm)] border-base-ink-soft",
hover:border-base-ink-medium "hover:bg-base-canvas hover:text-base-ink-strong",
focus-visible:bg-base-canvas focus-visible:text-base-ink-strong "hover:border-base-ink-medium",
focus-visible:border-primary "focus-visible:bg-base-canvas focus-visible:text-base-ink-strong",
focus-visible:outline focus-visible:outline-[length:var(--border-width-lg)] focus-visible:outline-sky-100 "focus-visible:border-primary",
`.trim(), "focus-visible:outline focus-visible:outline-[length:var(--border-width-lg)] focus-visible:outline-sky-100",
red: ` ),
bg-other-red-100 text-su-white red: clsx(
focus-visible:bg-base-canvas focus-visible:text-base-ink-strong "bg-other-red-100 text-su-white",
focus-visible:border-primary focus-visible:border "focus-visible:bg-base-canvas focus-visible:text-base-ink-strong",
focus-visible:outline focus-visible:outline-[length:var(--border-width-lg)] focus-visible:outline-sky-100 "focus-visible:border-primary focus-visible:border",
`.trim(), "focus-visible:outline focus-visible:outline-[length:var(--border-width-lg)] focus-visible:outline-sky-100",
green: ` ),
bg-other-green text-su-white green: clsx(
focus-visible:bg-base-canvas focus-visible:text-base-ink-strong "bg-other-green text-su-white",
focus-visible:border-primary focus-visible:border "focus-visible:bg-base-canvas focus-visible:text-base-ink-strong",
focus-visible:outline focus-visible:outline-[length:var(--border-width-lg)] focus-visible:outline-sky-100 "focus-visible:border-primary focus-visible:border",
`.trim(), "focus-visible:outline focus-visible:outline-[length:var(--border-width-lg)] focus-visible:outline-sky-100",
),
}; };
const sizeClasses: Record<ButtonSize, string> = { const sizeClasses: Record<ButtonSize, string> = {
@ -62,14 +64,12 @@ export default function Button({
}: ButtonProps) { }: ButtonProps) {
const baseClasses = "inline-flex items-center justify-center cursor-pointer"; const baseClasses = "inline-flex items-center justify-center cursor-pointer";
const classes = [ const classes = clsx(
baseClasses, baseClasses,
variantClasses[variant], variantClasses[variant],
sizeClasses[size], sizeClasses[size],
className, className,
] );
.filter(Boolean) // Filter out empty strings and undefined values so they won't pollute the class list
.join(" ");
return ( return (
<button className={classes} {...props}> <button className={classes} {...props}>