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(
|
||||||
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