|
|
|
@@ -115,48 +115,29 @@ const Button = memo<ButtonProps>(
|
|
|
|
|
|
|
|
|
|
const variantStyles: Record<string, string> = {
|
|
|
|
|
filled:
|
|
|
|
|
"bg-[var(--color-surface-inverse-primary)] text-[var(--color-content-inverse-primary)] border-[1.5px] border-transparent hover:bg-[var(--color-surface-inverse-primary)] hover:text-[var(--color-content-invert-brand-primary)] hover:border-[var(--color-border-invert-brand-primary)] hover:scale-[1.02] focus-visible:bg-[var(--color-surface-inverse-primary)] focus-visible:text-[var(--color-content-invert-brand-primary)] focus-visible:outline-none focus-visible:border-transparent focus-visible:shadow-[0_0_0px_2px_var(--color-border-default-primary),0_0_0px_4px_var(--color-border-invert-primary)] focus-visible:scale-[1.02] active:bg-[var(--color-surface-invert-brand-primary)] active:text-[var(--color-content-invert-primary)] active:border-[var(--color-border-invert-brand-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-default-secondary)] disabled:text-[var(--color-content-invert-tertiary)] disabled:border-transparent disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100",
|
|
|
|
|
"bg-[var(--color-surface-inverse-primary)] text-[var(--color-content-inverse-primary)] border-[1.5px] border-transparent hover:bg-[var(--color-surface-inverse-primary)] hover:text-[var(--color-content-invert-brand-primary)] hover:border-[var(--color-border-invert-brand-primary)] focus-visible:bg-[var(--color-surface-inverse-primary)] focus-visible:text-[var(--color-content-invert-brand-primary)] focus-visible:outline-none focus-visible:border-transparent focus-visible:shadow-[0_0_0px_2px_var(--color-border-default-primary),0_0_0px_4px_var(--color-border-invert-primary)] active:bg-[var(--color-surface-invert-brand-primary)] active:text-[var(--color-content-invert-primary)] active:border-[var(--color-border-invert-brand-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-default-secondary)] disabled:text-[var(--color-content-invert-tertiary)] disabled:border-transparent disabled:cursor-not-allowed disabled:opacity-50 disabled:active:scale-100",
|
|
|
|
|
"filled-inverse":
|
|
|
|
|
"bg-[var(--color-surface-default-primary)] text-[var(--color-content-default-primary)] border-[1.5px] border-transparent hover:bg-[var(--color-surface-default-primary)] hover:text-[var(--color-content-default-brand-primary)] hover:border-[var(--color-border-default-brand-primary)] hover:scale-[1.02] focus-visible:bg-[var(--color-surface-default-primary)] focus-visible:text-[var(--color-content-default-brand-primary)] focus-visible:outline-none focus-visible:border-transparent focus-visible:shadow-[0_0_0px_2px_var(--color-border-invert-primary),0_0_0px_4px_var(--color-border-default-primary)] focus-visible:scale-[1.02] active:bg-[var(--color-surface-default-brand-primary)] active:text-[var(--color-content-default-primary)] active:border-[var(--color-border-default-brand-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-invert-secondary)] disabled:text-[var(--color-content-default-tertiary)] disabled:border-transparent disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100",
|
|
|
|
|
"bg-[var(--color-surface-default-primary)] text-[var(--color-content-default-primary)] border-[1.5px] border-transparent hover:bg-[var(--color-surface-default-primary)] hover:text-[var(--color-content-default-brand-primary)] hover:border-[var(--color-border-default-brand-primary)] focus-visible:bg-[var(--color-surface-default-primary)] focus-visible:text-[var(--color-content-default-brand-primary)] focus-visible:outline-none focus-visible:border-transparent focus-visible:shadow-[0_0_0px_2px_var(--color-border-invert-primary),0_0_0px_4px_var(--color-border-default-primary)] active:bg-[var(--color-surface-default-brand-primary)] active:text-[var(--color-content-default-primary)] active:border-[var(--color-border-default-brand-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-invert-secondary)] disabled:text-[var(--color-content-default-tertiary)] disabled:border-transparent disabled:cursor-not-allowed disabled:opacity-50 disabled:active:scale-100",
|
|
|
|
|
outline:
|
|
|
|
|
"bg-transparent text-[var(--color-content-default-primary)] border-[1.5px] border-[var(--color-border-invert-primary)] hover:bg-transparent hover:text-[var(--color-content-default-brand-primary)] hover:border-[1.5px] hover:border-[var(--color-border-default-brand-primary)] hover:scale-[1.02] focus-visible:bg-transparent focus-visible:text-[var(--color-content-default-primary)] focus-visible:outline-none focus-visible:border-[1.5px] focus-visible:border-[var(--color-border-invert-primary)] focus-visible:shadow-[0_0_0px_2px_var(--color-border-default-primary),0_0_0px_4px_var(--color-border-invert-primary)] focus-visible:scale-[1.02] active:bg-transparent active:text-[var(--color-content-default-primary)] active:border-[1.5px] active:border-[var(--color-border-default-brand-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-default-secondary)] disabled:text-[var(--color-content-invert-tertiary)] disabled:border-[1.5px] disabled:border-transparent disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100",
|
|
|
|
|
"bg-transparent text-[var(--color-content-default-primary)] border-[1.5px] border-[var(--color-border-invert-primary)] hover:bg-transparent hover:text-[var(--color-content-default-brand-primary)] hover:border-[1.5px] hover:border-[var(--color-border-default-brand-primary)] focus-visible:bg-transparent focus-visible:text-[var(--color-content-default-primary)] focus-visible:outline-none focus-visible:border-[1.5px] focus-visible:border-[var(--color-border-invert-primary)] focus-visible:shadow-[0_0_0px_2px_var(--color-border-default-primary),0_0_0px_4px_var(--color-border-invert-primary)] active:bg-transparent active:text-[var(--color-content-default-primary)] active:border-[1.5px] active:border-[var(--color-border-default-brand-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-default-secondary)] disabled:text-[var(--color-content-invert-tertiary)] disabled:border-[1.5px] disabled:border-transparent disabled:cursor-not-allowed disabled:opacity-50 disabled:active:scale-100",
|
|
|
|
|
"outline-inverse":
|
|
|
|
|
"bg-transparent text-[var(--color-content-invert-primary)] border-[1.5px] border-[var(--color-border-default-primary)] hover:bg-transparent hover:text-[var(--color-content-invert-brand-primary)] hover:border-[1.5px] hover:border-[var(--color-border-invert-brand-primary)] hover:scale-[1.02] focus-visible:bg-transparent focus-visible:text-[var(--color-content-invert-primary)] focus-visible:outline-none focus-visible:border-[1.5px] focus-visible:border-[var(--color-border-default-primary)] focus-visible:shadow-[0_0_0px_2px_var(--color-border-invert-primary),0_0_0px_4px_var(--color-border-default-primary)] focus-visible:scale-[1.02] active:bg-transparent active:text-[var(--color-content-invert-primary)] active:border-[1.5px] active:border-[var(--color-border-invert-brand-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-invert-secondary)] disabled:text-[var(--color-content-default-tertiary)] disabled:border-[1.5px] disabled:border-transparent disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100",
|
|
|
|
|
"bg-transparent text-[var(--color-content-invert-primary)] border-[1.5px] border-[var(--color-border-default-primary)] hover:bg-transparent hover:text-[var(--color-content-invert-brand-primary)] hover:border-[1.5px] hover:border-[var(--color-border-invert-brand-primary)] focus-visible:bg-transparent focus-visible:text-[var(--color-content-invert-primary)] focus-visible:outline-none focus-visible:border-[1.5px] focus-visible:border-[var(--color-border-default-primary)] focus-visible:shadow-[0_0_0px_2px_var(--color-border-invert-primary),0_0_0px_4px_var(--color-border-default-primary)] active:bg-transparent active:text-[var(--color-content-invert-primary)] active:border-[1.5px] active:border-[var(--color-border-invert-brand-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-invert-secondary)] disabled:text-[var(--color-content-default-tertiary)] disabled:border-[1.5px] disabled:border-transparent disabled:cursor-not-allowed disabled:opacity-50 disabled:active:scale-100",
|
|
|
|
|
ghost:
|
|
|
|
|
"bg-transparent text-[var(--color-content-default-brand-primary)] border-[1.5px] border-transparent hover:bg-transparent hover:text-[var(--color-content-default-primary)] hover:border-transparent hover:scale-[1.02] focus-visible:bg-transparent focus-visible:text-[var(--color-content-default-brand-primary)] focus-visible:outline-none focus-visible:border-transparent focus-visible:shadow-[0_0_0px_2px_var(--color-border-default-primary),0_0_0px_4px_var(--color-border-invert-primary)] focus-visible:scale-[1.02] active:bg-transparent active:text-[var(--color-content-default-primary)] active:border-[var(--color-border-default-brand-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-default-secondary)] disabled:text-[var(--color-content-invert-tertiary)] disabled:border-transparent disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100",
|
|
|
|
|
"bg-transparent text-[var(--color-content-default-brand-primary)] border-[1.5px] border-transparent hover:bg-transparent hover:text-[var(--color-content-default-primary)] hover:border-transparent focus-visible:bg-transparent focus-visible:text-[var(--color-content-default-brand-primary)] focus-visible:outline-none focus-visible:border-transparent focus-visible:shadow-[0_0_0px_2px_var(--color-border-default-primary),0_0_0px_4px_var(--color-border-invert-primary)] active:bg-transparent active:text-[var(--color-content-default-primary)] active:border-[var(--color-border-default-brand-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-default-secondary)] disabled:text-[var(--color-content-invert-tertiary)] disabled:border-transparent disabled:cursor-not-allowed disabled:opacity-50 disabled:active:scale-100",
|
|
|
|
|
"ghost-inverse":
|
|
|
|
|
"bg-transparent text-[var(--color-content-invert-primary)] border-[1.5px] border-transparent hover:bg-transparent hover:text-[var(--color-content-invert-primary)] hover:border-transparent hover:scale-[1.02] focus-visible:bg-transparent focus-visible:text-[var(--color-content-invert-brand-primary)] focus-visible:outline-none focus-visible:border-transparent focus-visible:shadow-[0_0_0px_2px_var(--color-border-invert-primary),0_0_0px_4px_var(--color-border-default-primary)] focus-visible:scale-[1.02] active:bg-[var(--color-surface-invert-brand-primary)] active:text-[var(--color-content-invert-primary)] active:border-[var(--color-border-invert-brand-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-invert-secondary)] disabled:text-[var(--color-content-default-tertiary)] disabled:border-transparent disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100",
|
|
|
|
|
"bg-transparent text-[var(--color-content-invert-primary)] border-[1.5px] border-transparent hover:bg-transparent hover:text-[var(--color-content-invert-primary)] hover:border-transparent focus-visible:bg-transparent focus-visible:text-[var(--color-content-invert-brand-primary)] focus-visible:outline-none focus-visible:border-transparent focus-visible:shadow-[0_0_0px_2px_var(--color-border-invert-primary),0_0_0px_4px_var(--color-border-default-primary)] active:bg-[var(--color-surface-invert-brand-primary)] active:text-[var(--color-content-invert-primary)] active:border-[var(--color-border-invert-brand-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-invert-secondary)] disabled:text-[var(--color-content-default-tertiary)] disabled:border-transparent disabled:cursor-not-allowed disabled:opacity-50 disabled:active:scale-100",
|
|
|
|
|
danger:
|
|
|
|
|
"bg-transparent text-[var(--color-border-default-negative-primary)] border border-[var(--color-border-default-negative-primary)] hover:bg-[var(--color-surface-invert-negative-secondary)] hover:text-[var(--color-border-default-negative-primary)] hover:border-[var(--color-border-default-negative-primary)] hover:scale-[1.02] focus-visible:bg-transparent focus-visible:text-[var(--color-border-default-negative-primary)] focus-visible:outline-none focus-visible:border-[var(--color-border-default-negative-primary)] focus-visible:shadow-[0_0_0px_2px_var(--color-border-default-primary),0_0_0px_4px_var(--color-border-invert-primary)] focus-visible:scale-[1.02] active:bg-[var(--color-surface-invert-negative-primary)] active:text-[var(--color-content-invert-negative-primary)] active:border-[1.5px] active:border-[var(--color-border-default-negative-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-default-secondary)] disabled:text-[var(--color-content-inverse-tertiary)] disabled:border-transparent disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100",
|
|
|
|
|
"bg-transparent text-[var(--color-border-default-negative-primary)] border border-[var(--color-border-default-negative-primary)] hover:bg-[var(--color-surface-invert-negative-secondary)] hover:text-[var(--color-border-default-negative-primary)] hover:border-[var(--color-border-default-negative-primary)] focus-visible:bg-transparent focus-visible:text-[var(--color-border-default-negative-primary)] focus-visible:outline-none focus-visible:border-[var(--color-border-default-negative-primary)] focus-visible:shadow-[0_0_0px_2px_var(--color-border-default-primary),0_0_0px_4px_var(--color-border-invert-primary)] active:bg-[var(--color-surface-invert-negative-primary)] active:text-[var(--color-content-invert-negative-primary)] active:border-[1.5px] active:border-[var(--color-border-default-negative-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-default-secondary)] disabled:text-[var(--color-content-inverse-tertiary)] disabled:border-transparent disabled:cursor-not-allowed disabled:opacity-50 disabled:active:scale-100",
|
|
|
|
|
"danger-inverse":
|
|
|
|
|
"bg-transparent text-[var(--color-content-invert-negative-primary)] border border-[var(--color-border-invert-negative-primary)] hover:bg-transparent hover:text-[var(--color-content-invert-negative-primary)] hover:border-[var(--color-border-invert-negative-primary)] hover:scale-[1.02] focus-visible:bg-transparent focus-visible:text-[var(--color-content-invert-negative-primary)] focus-visible:outline-none focus-visible:border-[var(--color-border-invert-negative-primary)] focus-visible:shadow-[0_0_0px_2px_var(--color-border-invert-primary),0_0_0px_4px_var(--color-border-default-primary)] focus-visible:scale-[1.02] active:bg-[var(--color-surface-default-negative-primary)] active:text-[var(--color-content-default-primary)] active:border-[1.5px] active:border-[var(--color-border-default-negative-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-inverse-secondary)] disabled:text-[var(--color-content-default-tertiary)] disabled:border-transparent disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100",
|
|
|
|
|
"bg-transparent text-[var(--color-content-invert-negative-primary)] border border-[var(--color-border-invert-negative-primary)] hover:bg-transparent hover:text-[var(--color-content-invert-negative-primary)] hover:border-[var(--color-border-invert-negative-primary)] focus-visible:bg-transparent focus-visible:text-[var(--color-content-invert-negative-primary)] focus-visible:outline-none focus-visible:border-[var(--color-border-invert-negative-primary)] focus-visible:shadow-[0_0_0px_2px_var(--color-border-invert-primary),0_0_0px_4px_var(--color-border-default-primary)] active:bg-[var(--color-surface-default-negative-primary)] active:text-[var(--color-content-default-primary)] active:border-[1.5px] active:border-[var(--color-border-default-negative-primary)] active:shadow-none active:scale-[0.98] disabled:bg-[var(--color-surface-inverse-secondary)] disabled:text-[var(--color-content-default-tertiary)] disabled:border-transparent disabled:cursor-not-allowed disabled:opacity-50 disabled:active:scale-100",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const hoverOutlineStyles: Record<string, string> = {
|
|
|
|
|
xsmall: "hover:outline-1",
|
|
|
|
|
small: "hover:outline-1",
|
|
|
|
|
medium: "hover:outline-1",
|
|
|
|
|
large: "hover:outline-2",
|
|
|
|
|
xlarge: "hover:outline-[2.5px]",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Only apply outline styles to filled variant, not filled-inverse, outline, outline-inverse, ghost, ghost-inverse, danger, or danger-inverse
|
|
|
|
|
const outlineStyles =
|
|
|
|
|
variant === "filled-inverse" ||
|
|
|
|
|
variant === "outline" ||
|
|
|
|
|
variant === "outline-inverse" ||
|
|
|
|
|
variant === "ghost" ||
|
|
|
|
|
variant === "ghost-inverse" ||
|
|
|
|
|
variant === "danger" ||
|
|
|
|
|
variant === "danger-inverse"
|
|
|
|
|
? ""
|
|
|
|
|
: hoverOutlineStyles[size];
|
|
|
|
|
|
|
|
|
|
// Apply state-based styles if state prop is provided (overrides default hover/focus/active)
|
|
|
|
|
// Note: State prop is informational for Figma alignment - actual state is handled by CSS pseudo-classes
|
|
|
|
|
// For now, we maintain existing behavior and state prop is for documentation/alignment purposes
|
|
|
|
|
|
|
|
|
|
const baseStyles = `inline-flex items-center justify-start box-border whitespace-nowrap shrink-0 touch-manipulation [-webkit-tap-highlight-color:transparent] ${sizeStyles[size]} rounded-[var(--radius-measures-radius-full)] ${fontStyles[size]} transition-[transform,color,background-color,border-color,box-shadow,outline-color] duration-150 ease-out cursor-pointer ${variantStyles[variant]} ${outlineStyles}`;
|
|
|
|
|
// Hover/focus: color + border only — no scale and no extra outline (those
|
|
|
|
|
// enlarge the label). Press: active:scale-[0.98]. Same rule for nav items
|
|
|
|
|
// and cards: color, opacity, or shadow on hover; scale only on press.
|
|
|
|
|
// State prop is informational for Figma alignment; CSS pseudo-classes own
|
|
|
|
|
// the actual interaction states.
|
|
|
|
|
const baseStyles = `inline-flex items-center justify-start box-border whitespace-nowrap shrink-0 touch-manipulation [-webkit-tap-highlight-color:transparent] ${sizeStyles[size]} rounded-[var(--radius-measures-radius-full)] ${fontStyles[size]} transition-[transform,color,background-color,border-color,box-shadow] duration-150 ease-out cursor-pointer ${variantStyles[variant]}`;
|
|
|
|
|
const combinedStyles = `${baseStyles} ${className}`;
|
|
|
|
|
|
|
|
|
|
const sharedA11y = {
|
|
|
|
|