button-component #29
10
frontend/package-lock.json
generated
10
frontend/package-lock.json
generated
@ -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",
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
@ -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
|
|||||||
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}>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user
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 ofhover:a hover:b hover:c?