refactor(Card): drive sidebar border off lg: utilities not a media query

This commit is contained in:
Ilia Mashkov
2026-07-14 16:19:22 +03:00
parent e09fc467ba
commit c0aab42e6c
5 changed files with 20 additions and 25 deletions
@@ -36,25 +36,25 @@ describe('ExperienceCard', () => {
it('period badge is inside the sidebar column', () => {
render(<ExperienceCard {...DEFAULT_PROPS} />);
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(<ExperienceCard {...DEFAULT_PROPS} />);
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(<ExperienceCard {...DEFAULT_PROPS} />);
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(<ExperienceCard {...DEFAULT_PROPS} />);
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(<ExperienceCard {...DEFAULT_PROPS} stack={['React', 'TypeScript']} />);
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');
});
@@ -51,29 +51,29 @@ describe('ProjectCard', () => {
describe('layout', () => {
it('year is inside the sidebar column', () => {
render(<ProjectCard {...DEFAULT_PROPS} />);
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(<ProjectCard {...DEFAULT_PROPS} />);
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(<ProjectCard {...DEFAULT_PROPS} />);
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(<ProjectCard {...DEFAULT_PROPS} />);
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(<ProjectCard {...DEFAULT_PROPS} />);
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();
});
});
-10
View File
@@ -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;
+2 -2
View File
@@ -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(<CardSidebar sidebar={<span>Sidebar</span>}>Main</CardSidebar>);
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', () => {
+6 -1
View File
@@ -109,7 +109,12 @@ interface CardSidebarProps {
export function CardSidebar({ sidebar, children, className }: CardSidebarProps) {
return (
<div className={cn('flex flex-col lg:flex-row', className)}>
<div className="shrink-0 lg:w-64 brutal-border-sidebar pb-6 lg:pb-0 lg:pr-8 mb-6 lg:mb-0">{sidebar}</div>
<div
data-slot="card-sidebar"
className="shrink-0 lg:w-64 brutal-border-bottom lg:border-b-0 lg:brutal-border-right pb-6 lg:pb-0 lg:pr-8 mb-6 lg:mb-0"
>
{sidebar}
</div>
<div className="flex-1 min-w-0 lg:pl-8">{children}</div>
</div>
);