From 611a9c1a5a4b5a0c05bf4122beda2fffa7fa25ce Mon Sep 17 00:00:00 2001 From: Ilia Mashkov Date: Tue, 14 Jul 2026 18:02:21 +0300 Subject: [PATCH] refactor(Button): distinct solid/outline variants, drop redundant secondary --- .../project/ui/ProjectCard/ProjectCard.tsx | 2 +- src/shared/ui/Button/ui/Button.stories.tsx | 15 ++++++--------- src/shared/ui/Button/ui/Button.test.tsx | 8 ++------ src/shared/ui/Button/ui/Button.tsx | 17 ++++++++--------- 4 files changed, 17 insertions(+), 25 deletions(-) diff --git a/src/entities/project/ui/ProjectCard/ProjectCard.tsx b/src/entities/project/ui/ProjectCard/ProjectCard.tsx index efc5e99..748dfac 100644 --- a/src/entities/project/ui/ProjectCard/ProjectCard.tsx +++ b/src/entities/project/ui/ProjectCard/ProjectCard.tsx @@ -56,7 +56,7 @@ export function ProjectCard({ title, year, description, tags, url, imageUrl, pri ))} )} - diff --git a/src/shared/ui/Button/ui/Button.stories.tsx b/src/shared/ui/Button/ui/Button.stories.tsx index 26225f2..5ed6393 100644 --- a/src/shared/ui/Button/ui/Button.stories.tsx +++ b/src/shared/ui/Button/ui/Button.stories.tsx @@ -13,11 +13,8 @@ type Story = StoryObj; export const AllVariants: Story = { render: () => (
- - - -
@@ -47,7 +44,7 @@ export const Sizes: Story = { export const Disabled: Story = { args: { - variant: 'primary', + variant: 'solid', disabled: true, children: 'Disabled', }, diff --git a/src/shared/ui/Button/ui/Button.test.tsx b/src/shared/ui/Button/ui/Button.test.tsx index 78ee56b..26e99f7 100644 --- a/src/shared/ui/Button/ui/Button.test.tsx +++ b/src/shared/ui/Button/ui/Button.test.tsx @@ -14,14 +14,10 @@ describe('Button', () => { }); }); describe('variants', () => { - it('applies primary variant by default', () => { + it('applies solid variant by default', () => { render(); expect(screen.getByRole('button')).toHaveClass('bg-blue'); }); - it('applies secondary variant', () => { - render(); - expect(screen.getByRole('button')).toHaveClass('bg-blue'); - }); it('applies outline variant', () => { render(); expect(screen.getByRole('button')).toHaveClass('bg-cream'); @@ -82,7 +78,7 @@ describe('Button', () => { }); it('applies the same variant and size classes as button', () => { render( - , ); diff --git a/src/shared/ui/Button/ui/Button.tsx b/src/shared/ui/Button/ui/Button.tsx index d5a71ee..d2eaad0 100644 --- a/src/shared/ui/Button/ui/Button.tsx +++ b/src/shared/ui/Button/ui/Button.tsx @@ -1,13 +1,13 @@ import type { AnchorHTMLAttributes, ButtonHTMLAttributes, ReactNode } from 'react'; import { cn } from '$shared/lib'; -export type ButtonVariant = 'primary' | 'secondary' | 'outline' | 'ghost'; +export type ButtonVariant = 'solid' | 'outline' | 'ghost'; export type ButtonSize = 'sm' | 'md' | 'lg'; type BaseProps = { /** * Visual variant - * @default 'primary' + * @default 'solid' */ variant?: ButtonVariant; /** @@ -41,10 +41,9 @@ function isAnchorProps(props: RestButton | RestAnchor): props is RestAnchor { } const VARIANTS = { - primary: 'brutal-border bg-blue text-cream btn-shadow', - secondary: 'brutal-border bg-blue text-cream btn-shadow', - outline: - 'brutal-border border-blue/35 bg-cream text-blue hover:border-blue hover:bg-blue/10 active:bg-blue active:text-cream', + solid: 'brutal-border bg-blue text-cream btn-shadow', + // Reversed solid: same border + offset-block animation, cream fill instead of blue + outline: 'brutal-border bg-cream text-blue btn-shadow', ghost: 'brutal-border bg-transparent text-blue btn-transition hover:-translate-x-0.5 hover:-translate-y-0.5 active:translate-x-0.5 active:translate-y-0.5', } as const satisfies Record; @@ -55,15 +54,15 @@ const SIZES = { lg: 'px-8 py-4 text-lg', } as const satisfies Record; -/* Elevation lives per-variant: primary/secondary use btn-shadow (static offset - * block, button moves), ghost uses btn-transition + translate. */ +/* Elevation lives per-variant: solid uses btn-shadow (static offset block, + * button moves), ghost uses btn-transition + translate. */ const BASE = 'cursor-pointer uppercase tracking-wider'; /** * Brutalist button with variants and sizes. * Renders as when href is provided,