From c0aab42e6c0cc9d3bd2abd63c6e44ad48b8752b9 Mon Sep 17 00:00:00 2001 From: Ilia Mashkov Date: Tue, 14 Jul 2026 16:19:22 +0300 Subject: [PATCH] refactor(Card): drive sidebar border off lg: utilities not a media query --- .../ui/ExperienceCard/ExperienceCard.test.tsx | 12 ++++++------ .../project/ui/ProjectCard/ProjectCard.test.tsx | 12 ++++++------ src/shared/styles/theme.css | 10 ---------- src/shared/ui/Card/ui/Card.test.tsx | 4 ++-- src/shared/ui/Card/ui/Card.tsx | 7 ++++++- 5 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/entities/experience/ui/ExperienceCard/ExperienceCard.test.tsx b/src/entities/experience/ui/ExperienceCard/ExperienceCard.test.tsx index 8b5158d..9bdad95 100644 --- a/src/entities/experience/ui/ExperienceCard/ExperienceCard.test.tsx +++ b/src/entities/experience/ui/ExperienceCard/ExperienceCard.test.tsx @@ -36,25 +36,25 @@ describe('ExperienceCard', () => { it('period badge is inside the sidebar column', () => { render(); const badge = screen.getByText('2021 – 2024'); - expect(badge.closest('.brutal-border-sidebar')).toBeInTheDocument(); + expect(badge.closest('[data-slot="card-sidebar"]')).toBeInTheDocument(); }); it('company name is inside the sidebar column', () => { render(); const company = screen.getByText('Acme Corp'); - expect(company.closest('.brutal-border-sidebar')).toBeInTheDocument(); + expect(company.closest('[data-slot="card-sidebar"]')).toBeInTheDocument(); }); it('title is outside the sidebar column', () => { render(); const title = screen.getByText('Senior Developer'); - expect(title.closest('.brutal-border-sidebar')).toBeNull(); + expect(title.closest('[data-slot="card-sidebar"]')).toBeNull(); }); it('description is outside the sidebar column', () => { render(); const desc = screen.getByText('Built scalable frontend systems.'); - expect(desc.closest('.brutal-border-sidebar')).toBeNull(); + expect(desc.closest('[data-slot="card-sidebar"]')).toBeNull(); }); }); @@ -88,8 +88,8 @@ describe('ExperienceCard', () => { render(); const react = screen.getByText('React'); const ts = screen.getByText('TypeScript'); - expect(react.closest('.brutal-border-sidebar')).toBeInTheDocument(); - expect(ts.closest('.brutal-border-sidebar')).toBeInTheDocument(); + expect(react.closest('[data-slot="card-sidebar"]')).toBeInTheDocument(); + expect(ts.closest('[data-slot="card-sidebar"]')).toBeInTheDocument(); expect(react).toHaveClass('brutal-border', 'bg-transparent', 'px-2'); }); diff --git a/src/entities/project/ui/ProjectCard/ProjectCard.test.tsx b/src/entities/project/ui/ProjectCard/ProjectCard.test.tsx index 9d3db95..d9aff04 100644 --- a/src/entities/project/ui/ProjectCard/ProjectCard.test.tsx +++ b/src/entities/project/ui/ProjectCard/ProjectCard.test.tsx @@ -51,29 +51,29 @@ describe('ProjectCard', () => { describe('layout', () => { it('year is inside the sidebar column', () => { render(); - expect(screen.getByText('2024').closest('.brutal-border-sidebar')).toBeInTheDocument(); + expect(screen.getByText('2024').closest('[data-slot="card-sidebar"]')).toBeInTheDocument(); }); it('tags are inside the sidebar column', () => { render(); - expect(screen.getByText('React').closest('.brutal-border-sidebar')).toBeInTheDocument(); - expect(screen.getByText('Node').closest('.brutal-border-sidebar')).toBeInTheDocument(); + expect(screen.getByText('React').closest('[data-slot="card-sidebar"]')).toBeInTheDocument(); + expect(screen.getByText('Node').closest('[data-slot="card-sidebar"]')).toBeInTheDocument(); }); it('View Project button is inside the sidebar column', () => { render(); const btn = screen.getByRole('link', { name: /view project/i }); - expect(btn.closest('.brutal-border-sidebar')).toBeInTheDocument(); + expect(btn.closest('[data-slot="card-sidebar"]')).toBeInTheDocument(); }); it('title is outside the sidebar column', () => { render(); - expect(screen.getByText('My Project').closest('.brutal-border-sidebar')).toBeNull(); + expect(screen.getByText('My Project').closest('[data-slot="card-sidebar"]')).toBeNull(); }); it('description is outside the sidebar column', () => { render(); - expect(screen.getByText('A cool project description').closest('.brutal-border-sidebar')).toBeNull(); + expect(screen.getByText('A cool project description').closest('[data-slot="card-sidebar"]')).toBeNull(); }); }); diff --git a/src/shared/styles/theme.css b/src/shared/styles/theme.css index 09f6425..6208b3c 100644 --- a/src/shared/styles/theme.css +++ b/src/shared/styles/theme.css @@ -332,16 +332,6 @@ "SOFT" var(--fraunces-soft); } -.brutal-border-sidebar { - border-bottom: var(--border-width) solid var(--blue); -} -@media (min-width: 1024px) { - .brutal-border-sidebar { - border-bottom: none; - border-right: var(--border-width) solid var(--blue); - } -} - /* Editorial rich-text typography */ .rich-text { max-width: 65ch; diff --git a/src/shared/ui/Card/ui/Card.test.tsx b/src/shared/ui/Card/ui/Card.test.tsx index 4f48ced..4c4bbed 100644 --- a/src/shared/ui/Card/ui/Card.test.tsx +++ b/src/shared/ui/Card/ui/Card.test.tsx @@ -91,10 +91,10 @@ describe('CardSidebar', () => { expect(container.firstChild).toHaveClass('flex'); }); - it('sidebar column has brutal-border-sidebar class', () => { + it('marks the sidebar column with a data-slot hook', () => { render(Sidebar}>Main); const sidebar = screen.getByText('Sidebar').parentElement; - expect(sidebar).toHaveClass('brutal-border-sidebar'); + expect(sidebar).toHaveAttribute('data-slot', 'card-sidebar'); }); it('sidebar column has fixed width on lg', () => { diff --git a/src/shared/ui/Card/ui/Card.tsx b/src/shared/ui/Card/ui/Card.tsx index 8e73a82..2a2a3a2 100644 --- a/src/shared/ui/Card/ui/Card.tsx +++ b/src/shared/ui/Card/ui/Card.tsx @@ -109,7 +109,12 @@ interface CardSidebarProps { export function CardSidebar({ sidebar, children, className }: CardSidebarProps) { return (
-
{sidebar}
+
+ {sidebar} +
{children}
);