Skip to content
Open
Show file tree
Hide file tree
Changes from 76 commits
Commits
Show all changes
158 commits
Select commit Hold shift + click to select a range
e993b26
feat: 786 - add merch page
YulikK Mar 12, 2025
2e66950
feat: 786 - add fetch data and hero banner
YulikK Mar 19, 2025
9eafcbe
feat: 786 - add id and view
YulikK Mar 27, 2025
109650d
feat: 786 - add merch catalog widget with item list and styles
YulikK Apr 28, 2025
0647f7b
refactor: 786 - update merch button link to use relative path
YulikK Apr 30, 2025
bacb488
feat: 786 - merge main
YulikK May 8, 2025
ed4c779
refactor: 786 - restructure merch module and improve component reusab…
YulikK May 8, 2025
ef8479a
refactor: 786 - remove hardcoded CDN URL and use base URL from env
YulikK May 8, 2025
098bc07
feat: 786 - add archive download functionality for merch items
YulikK May 9, 2025
b647fbc
refactor: 786 - replace ROUTES.MERCH with LINKS.MERCH for consistency
YulikK May 9, 2025
3cacc8f
refactor: 786 - change product ID from string to number and remove uu…
YulikK May 14, 2025
451f808
fix: 786 - update merch button link in test constants
YulikK May 14, 2025
b4eb099
feat: 788 - add layout for filter title input and clear button
antonina220590 May 14, 2025
eb3e9b0
refactor: 786 - improve image handling and structure
YulikK May 14, 2025
070a452
feat: 788 - add custom checkbox
antonina220590 May 16, 2025
e7b66a3
feat: 788 - add props to filter controls
antonina220590 May 16, 2025
44fbb78
feat: 788 - add client-side filtering logic for merch catalog
antonina220590 May 17, 2025
104400c
feat: 788 - add useMediaQuery hook for responsive logic
antonina220590 May 20, 2025
f21c63f
feat: 788 - add responsive layout
antonina220590 May 20, 2025
38716c9
feat: 788 - add use memo to merch card component
antonina220590 May 20, 2025
f52c3d4
feat: 788 - add tests
antonina220590 May 20, 2025
e9feef7
feat: 788 - merge parent branch into current branch
antonina220590 May 21, 2025
2c627e1
feat: 788 - update merch filters to read from and write to URL params
antonina220590 May 22, 2025
59c698b
refactor: 788 - apply PR suggestions for filter styling
antonina220590 May 28, 2025
ff1e958
fix: 788 - prevent merch list from collapsing with single item
antonina220590 May 28, 2025
c74342c
fix: 788 - prevent delayed appearance of filter tags by server-side c…
antonina220590 May 28, 2025
efd3913
refactor: 788 - change p tag to Paragraph component
antonina220590 May 28, 2025
c110b6c
fix: 788 - resolve merge conflicts
antonina220590 Sep 8, 2025
56370fb
fix: 788 - integrate merch filters with main
antonina220590 Sep 8, 2025
10e879f
refactor: 788 - use constants for style values
antonina220590 Sep 8, 2025
3397741
refactor: 788 - use constants for padding values
antonina220590 Sep 8, 2025
259929a
fix: 788 - Update package-lock.json to fix build issues
antonina220590 Sep 8, 2025
9d65fe1
chore: 788 - merge main into current branch
antonina220590 Sep 8, 2025
557fc02
fix: 788 - add visible focus style to search input
antonina220590 Sep 9, 2025
5a21bdc
fix: 788 - stabilize FilterControls tests by isolating mock state
antonina220590 Sep 9, 2025
c24c321
fix: 788 - improve accessibility of filter controls
antonina220590 Sep 9, 2025
5aa6bbe
refactor: 788 - deduplicate FilterControls mock implementation
antonina220590 Sep 9, 2025
0788559
fix: 788 - correct state synchronization and test reliability
antonina220590 Sep 9, 2025
f4093e5
fix: 788 - improve accessibility and styles for controls
antonina220590 Sep 10, 2025
8d66e3a
feat: 788 - merge parent branch into current branch and resolve confl…
antonina220590 Sep 21, 2025
4661af6
fix: 788 - improve accessible focus for search input
antonina220590 Sep 21, 2025
721f47c
fix: 788 - improve accessibility of filter controls
antonina220590 Sep 21, 2025
ac9facc
fix: 788 - eliminate re-render loop by simplifying state handling
antonina220590 Sep 21, 2025
8393739
fix: 788 - refactor tests to align with URL-based state
antonina220590 Sep 21, 2025
d04327c
fix: 788 - attempt to fix sharp build error
antonina220590 Sep 21, 2025
f3c3abb
fix: 788 - try new strategy to resolve sharp build error
antonina220590 Sep 21, 2025
dd6d294
chore: 788 - regenerate package-lock.json
antonina220590 Sep 21, 2025
7e11672
refactor: 788 - extract search input to a separate component
antonina220590 Sep 29, 2025
2daf47e
refactor: 788 - extarct tag filters to a separate component
antonina220590 Sep 30, 2025
d5d137f
refactor: 788 - unify and improve clear button styles
antonina220590 Sep 30, 2025
75ecdb3
refactor: 788 - extract input to a reusable component
antonina220590 Sep 30, 2025
b677394
refactor: 788 - devide split FilterControls into desktop and mobile c…
antonina220590 Oct 1, 2025
0a0e99d
refactor: 788 - update styles for desktop and mobile controls components
antonina220590 Oct 1, 2025
183ba6f
refactor: 788 - improve readability of conditional rendering in Filte…
antonina220590 Oct 1, 2025
d46541e
refactor: 788 - simplify and add types to tag generation logic
antonina220590 Oct 1, 2025
54c14c1
refactor: 788 - make initialAvailableTags prop required
antonina220590 Oct 1, 2025
3ec6252
refactor: 788 - change tag rendering test to use it.each
antonina220590 Oct 1, 2025
67107a1
fix: 788 - add name attribute to Input component
antonina220590 Oct 1, 2025
cd91693
refactor: 788 - simplify transition property
antonina220590 Oct 1, 2025
f28b0e2
feat: 788 - add tests for the separated components
antonina220590 Oct 2, 2025
93de97a
refactor: 788 - update tests for filtered-catalog component
antonina220590 Oct 2, 2025
6e6037e
refactor: 788 - remove useEffect for allAvailableTags
antonina220590 Oct 2, 2025
eb16ce9
refactor: 788 - centralize catalog empty state logic
antonina220590 Oct 2, 2025
de8702c
refactor: 788 - return native input to docs search component
antonina220590 Oct 2, 2025
602865e
refactor: 788 - rename input component
antonina220590 Oct 2, 2025
c06df4e
chore: 788 - merge main branch
antonina220590 Oct 3, 2025
4f91993
fix: 788 - delete deprecated clip property
antonina220590 Oct 3, 2025
2513a78
fix: 788 - normalize search term to handle whitespace
antonina220590 Oct 3, 2025
4eb9fcb
refactor: 788 - align mobile accordion with nav menu
antonina220590 Oct 7, 2025
2e5a05b
refactor: 788 - revert empty state logic to parent component
antonina220590 Oct 7, 2025
54fb4fb
refactor: 788 - simplify unique tag extraction
antonina220590 Oct 7, 2025
7ec328c
refactor: 788 - simplify content rendering logic
antonina220590 Oct 7, 2025
e9afa06
refactor: 788 - implement composition to solve prop drilling
antonina220590 Oct 8, 2025
9163d3e
refactor: 788 - update tests for DesktopMerchFilters
antonina220590 Oct 8, 2025
038c5ad
refactor: 788 - update for MobileMerchFilters
antonina220590 Oct 8, 2025
08f9764
refactor: 788 - update tests for MerchCatalog and TagFilters
antonina220590 Oct 8, 2025
17635a4
refactor: 788 - update styles names
antonina220590 Oct 8, 2025
a11807c
refactor: 788 - standardize SearchInput component
antonina220590 Oct 13, 2025
cbd277d
feat: 788 - add test for SearchInput component
antonina220590 Oct 13, 2025
323c5d8
refactor: 788 - move loader component to shared components
antonina220590 Oct 13, 2025
3efe1d5
refactor: 788 - extract merch not found to separate component
antonina220590 Oct 14, 2025
b41a734
feat: 788 - add tests for merchNotFound component
antonina220590 Oct 14, 2025
45aecd9
refactor: 788 - rename MerchNotFound component to NoMerch
antonina220590 Oct 14, 2025
78b3ceb
refactor: 788 - extract tag processing logic into a helper
antonina220590 Oct 14, 2025
7350e09
refactor: 788 - move mockedProducts from merchCatalog tests file to c…
antonina220590 Oct 14, 2025
6310c48
feat: 788 - add tests for getTags helper
antonina220590 Oct 15, 2025
99c07d5
refactor: 788 - delete unused class from merchSection component
antonina220590 Oct 15, 2025
dd602a2
refactor: 788 - unify mobile and desktop merch filters into merchFilt…
antonina220590 Oct 15, 2025
7a17877
refactor: 788 - move TagToggleButtton to separate component and updat…
antonina220590 Oct 15, 2025
5596d8b
refactor: 788 - move tag accordion logic to merchFilter component
antonina220590 Oct 15, 2025
ce8cff2
refactor: 788 - rename merchFilter child components
antonina220590 Oct 15, 2025
bf68d8b
feat: 788 - add tests for MerchTagsToggle component
antonina220590 Oct 15, 2025
9cbbd07
feat: 788 - extract custom checkbox to reusable component
antonina220590 Oct 15, 2025
a35a717
feat: 788 - add tests for Checkbox component
antonina220590 Oct 16, 2025
2bd7b77
refactor: 788 - move search logic to MerchSearch component
antonina220590 Oct 16, 2025
3c206f5
fix: 788 - reset pagination when search filter changes
antonina220590 Oct 16, 2025
3828ae9
refactor: 788 - move tag filter logic to MerchTags component
antonina220590 Oct 16, 2025
e5970a9
refactor: 788 - add debounce to search input to improve performance
antonina220590 Oct 16, 2025
69c1988
refactor: 788 - move the rendering of MerchSearch and MerchTags to Me…
antonina220590 Oct 16, 2025
6bce762
fix: 788 - add search by tags functionality
antonina220590 Oct 16, 2025
cff58ee
refactor: 788 - change components structure
antonina220590 Oct 16, 2025
e6beba4
fix: 788 - resolve race condition problem in search component
antonina220590 Oct 16, 2025
8580b04
refactor: 788 - delete unused svg icon
antonina220590 Oct 16, 2025
186e3f6
refactor: 788 - delete unused useMediaQuery hook
antonina220590 Oct 16, 2025
3111766
refactor: 788 - update NoMerch component and reuse it in MerchCatalog…
antonina220590 Oct 16, 2025
8704931
refactor: 788 - delete unused styles
antonina220590 Oct 17, 2025
3c94901
refactor: 788 - rename props
antonina220590 Oct 17, 2025
15ffda1
feat: 788 - add tests for MerchSearch component
antonina220590 Oct 17, 2025
1648d5f
feat: 788 - update tests for MerchTags
antonina220590 Oct 17, 2025
b52966e
refactor: 788 - change class name in MerchTagsToggle component
antonina220590 Oct 17, 2025
f49bb1c
feat: 788 - add tests for MerchFilter component
antonina220590 Oct 17, 2025
7777cd5
refactor: 788 - update tests for MerchCatalog
antonina220590 Oct 17, 2025
5da143f
refactor: 788 - update tests for NoMerch component
antonina220590 Oct 17, 2025
862ed92
refactor: 788 - update alt in NoMerch
antonina220590 Oct 17, 2025
76ceffd
fix: 788 - add vi import to constants file
antonina220590 Oct 17, 2025
99e7efd
refactor: 788 - update constant
antonina220590 Oct 17, 2025
e2fb541
refactor: 788 - simplify conditional render for product list
antonina220590 Oct 23, 2025
721c5b5
refactor: 788 - replace span with div element for rendering children …
antonina220590 Oct 23, 2025
bfe7d5e
refactor: 788 - delete the shared file with types
antonina220590 Oct 23, 2025
d6c5b54
refactor: 788 - use scss nesting for MerchFilter component
antonina220590 Oct 23, 2025
ed53bc4
refactor: 788 - change clear button styles to rounded
antonina220590 Oct 23, 2025
727411a
refactor: 788 - change prop definition to type
antonina220590 Oct 23, 2025
c945c44
refactor: 788 - simplify NoMerch component by removing router logic a…
antonina220590 Oct 24, 2025
ee870b6
refactor: 788 - update tests for NoMerch component
antonina220590 Oct 24, 2025
c8e0952
refactor: 788 - rename MerchTagsToggle component to MerchTagsDropdown
antonina220590 Oct 24, 2025
bfa5e25
refactor: 788 - rename merchTagsToggle component to merchTagsDropdown
antonina220590 Oct 24, 2025
8ac199a
refactor: 788 - update tests for SearchInput component
antonina220590 Oct 24, 2025
aa23fb5
refactor: 788 - update tests for Checkbox component
antonina220590 Oct 24, 2025
abd47c7
fix: 788 - add conditional rendering of tags list
antonina220590 Oct 24, 2025
413ee5a
refactor: 788 - extract filter logic to helpers
antonina220590 Oct 24, 2025
b1baeb6
refactor: 788 - rename MerchTagsDropdown folder
antonina220590 Oct 24, 2025
39c523a
refactor: 788 - rename MerchTagsDropdown folder
antonina220590 Oct 24, 2025
1acca22
refactor: 788 - update MerchProduct type
antonina220590 Oct 24, 2025
f966d26
feat: 788 - add tests for merch filter helpers
antonina220590 Oct 24, 2025
fb13147
refactor: 788 - move url params to constants and update testsfor Merc…
antonina220590 Oct 25, 2025
93bc735
refactor: 788 - update tests for MerchTags component and use constants
antonina220590 Oct 25, 2025
e54a06c
refactor: 788 - update tests for MerchTagsDropdown component
antonina220590 Oct 25, 2025
b18310f
refactor: 788 - update MerchFilter component and tests
antonina220590 Oct 25, 2025
02a1a75
refactor: 788 - use camelCase for router mock variable in all test files
antonina220590 Oct 25, 2025
06fe2d1
refactor: 788 - update tests for NoMerch component
antonina220590 Oct 25, 2025
219ea8b
refactor: 788 - update logic of NoMerch compponent rendering
antonina220590 Oct 25, 2025
c938f37
refactor: 788 - update type for constant
antonina220590 Oct 25, 2025
1a579d3
refactor: 788 - delete irrelevant check from MerchTagsDropdown test
antonina220590 Oct 25, 2025
51172c0
refactor: 788 - add formatting to tests
antonina220590 Oct 25, 2025
fd5f74d
fix: 788 - fix type in test name
antonina220590 Oct 28, 2025
6493835
refactor: 788 - delete import of router type from nextjs internal paths
antonina220590 Oct 28, 2025
1f9f40c
fix: 788 - add missing flex context on button
antonina220590 Oct 28, 2025
ae1dcb0
refactor: 788 - memoize tags extraction for better performance
antonina220590 Oct 28, 2025
c46a631
refactor: 788 - add sizing for next images
antonina220590 Oct 28, 2025
05b0f1a
refactor: 788 - remove redundant assertions
antonina220590 Oct 28, 2025
84d9be9
refactor: 788 - use data-testid for tags list instead of parentElement
antonina220590 Oct 28, 2025
07ed6aa
fix: 788 - move data-testid to correct list container
antonina220590 Oct 28, 2025
aa85120
refactor: 788 - move userEvent setup into beforeEach for proper test …
antonina220590 Oct 28, 2025
f323d5a
refactor: 788 - delete conflicting accessibility attribute from dropd…
antonina220590 Oct 28, 2025
0552f74
refactor: 788 - use toHaveClass instead of classList contains for bet…
antonina220590 Oct 28, 2025
112be4f
refactor: 788 - normalize search query and update tests
antonina220590 Oct 28, 2025
984e590
refactor: 788 - centralize all search query normalization in MerchSearch
antonina220590 Oct 28, 2025
1911092
fix: 788 - fix usePathname mock to include leading slash
antonina220590 Oct 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference path="./.next/types/routes.d.ts" />
/// <reference path="./build/types/routes.d.ts" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
4 changes: 3 additions & 1 deletion src/app/docs/components/search/search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ function Result({ result }: { result: PagefindSearchResult }) {
return (
<div>
<Link href={removeHtmlExtension(data.url)}>
<Subtitle size="extra-small" weight="bold">{data.meta.title}</Subtitle>
<Subtitle size="extra-small" weight="bold">
{data.meta.title}
</Subtitle>
<p dangerouslySetInnerHTML={{ __html: data.excerpt }} />
</Link>

Expand Down
14 changes: 14 additions & 0 deletions src/shared/__tests__/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Course } from '@/entities/course';
import type { Trainer } from '@/entities/trainer';
import { COURSE_LINKS, COURSE_TITLES, ROUTES } from '@/shared/constants';
import { Paragraph } from '@/shared/ui/paragraph';
import { MerchCatalogProps } from '@/widgets/merch-section/ui/merch-catalog/types';

export const MOCKED_IMAGE_PATH: StaticImageData = {
src: 'mocked-image-path.webp',
Expand Down Expand Up @@ -227,3 +228,16 @@ export const MOCKED_VIDEOS: Video[] = [
thumbnail: 'thumb3.jpg',
},
];

export const getMockedProps = (overrides: Partial<MerchCatalogProps> = {}): MerchCatalogProps => ({
allAvailableTags: ['tag1', 'tag2', 'tag3'],
searchTerm: '',
selectedTags: [],
hasActiveFilters: false,
areTagsExpanded: false,
onSearchChange: vi.fn(),
onTagChange: vi.fn(),
onClearFilters: vi.fn(),
onToggleTagsExpansion: vi.fn(),
...overrides,
});
5 changes: 5 additions & 0 deletions src/shared/assets/svg/search-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions src/shared/hooks/use-media-query/use-media-query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useEffect, useState } from 'react';

export const useMediaQuery = (query: string): boolean => {
const [matches, setMatches] = useState(false);

useEffect(() => {
if (typeof window === 'undefined') {
return;
}
const media = window.matchMedia(query);
const listener = () => setMatches(media.matches);

listener();
media.addEventListener('change', listener);
return () => media.removeEventListener('change', listener);
}, [query]);
return matches;
};
13 changes: 13 additions & 0 deletions src/shared/ui/search-input/search-input.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.input {
width: 100%;
height: 35px;
padding: $gap-xxs $gap-xs;
border: 1px solid $color-gray-400;
border-radius: $border-radius-xxs;

outline-offset: -2px;

&:focus {
outline: 2px solid $color-blue-500;
}
}
33 changes: 33 additions & 0 deletions src/shared/ui/search-input/search-input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import classNames from 'classnames/bind';

import styles from './search-input.module.scss';

const cx = classNames.bind(styles);

type SearchInputProps = {
value: string;
onChange: (value: string) => void;
placeholder?: string;
ariaLabel?: string;
name?: string;
};

export default function SearchInput({
value,
onChange,
placeholder,
ariaLabel,
name,
}: SearchInputProps) {
return (
<input
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're using data-testid for component search and testing

className={cx('input')}
type="text"
placeholder={placeholder}
value={value}
onChange={(e) => onChange(e.target.value)}
aria-label={ariaLabel}
name={name}
/>
);
}
6 changes: 3 additions & 3 deletions src/views/merch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import { Suspense } from 'react';
import welcome from '@/shared/assets/welcome.webp';
import { Breadcrumbs } from '@/widgets/breadcrumbs';
import { Hero } from '@/widgets/hero';
import { MerchCatalog } from '@/widgets/merch-catalog';
import { Loader } from '@/widgets/merch-catalog/ui/loader/loader';
import { MerchSection } from '@/widgets/merch-section';
import { Loader } from '@/widgets/merch-section/ui/loader/loader';

export const Merch = async () => {
return (
<>
<Hero heading="Merch" subHeading="Free assets for your design" image={welcome} />
<Breadcrumbs />
<Suspense fallback={<Loader />}>
<MerchCatalog />
<MerchSection />
</Suspense>
</>
);
Expand Down
1 change: 0 additions & 1 deletion src/widgets/merch-catalog/index.ts

This file was deleted.

1 change: 1 addition & 0 deletions src/widgets/merch-section/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { MerchSection } from './ui/merch-section';
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { describe, expect, it, vi } from 'vitest';

import { DesktopMerchFilters } from './desktop-merch-filters';

vi.mock('@/shared/ui/subtitle', () => ({ Subtitle: (props: { children: React.ReactNode }) => <div>{props.children}</div> }));

describe('DesktopMerchFilters', () => {
const user = userEvent.setup();

const mockSearchFilters = <div data-testid="search-filters">Mock Search</div>;
const mockTagFilters = <div data-testid="tag-filters">Mock Tags</div>;

it('should render the title and the provided filter slots', () => {
render(
<DesktopMerchFilters
searchFilters={mockSearchFilters}
tagFilters={mockTagFilters}
hasActiveFilters={false}
onClearFilters={() => {}}
/>,
);

expect(screen.getByText('Filter merch')).toBeInTheDocument();
expect(screen.getByTestId('search-filters')).toBeInTheDocument();
expect(screen.getByTestId('tag-filters')).toBeInTheDocument();
});

it('should render the "Clear" button without "active" class if filters are not active', () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could combine this and the previous test-cases.

render(
<DesktopMerchFilters
searchFilters={mockSearchFilters}
tagFilters={mockTagFilters}
hasActiveFilters={false}
onClearFilters={() => {}}
/>,
);

const clearButton = screen.getByRole('button', { name: /Clear/i });

expect(clearButton).toBeInTheDocument();
expect(clearButton).not.toHaveClass('active');
});

it('should render the "Clear" button with "active" class if filters are active', () => {
render(
<DesktopMerchFilters
searchFilters={mockSearchFilters}
tagFilters={mockTagFilters}
hasActiveFilters={true}
onClearFilters={() => {}}
/>,
);

const clearButton = screen.getByRole('button', { name: /Clear/i });

expect(clearButton).toBeInTheDocument();
expect(clearButton).toHaveClass('active');
});

it('should call onClearFilters when the "Clear" button is clicked', async () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could combine this and the previous test-cases.

const handleClearFiltersMock = vi.fn();

render(
<DesktopMerchFilters
searchFilters={mockSearchFilters}
tagFilters={mockTagFilters}
hasActiveFilters={true}
onClearFilters={handleClearFiltersMock}
/>,
);

const clearButton = screen.getByRole('button', { name: /Clear/i });

await user.click(clearButton);

expect(handleClearFiltersMock).toHaveBeenCalledTimes(1);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import classNames from 'classnames/bind';

import { LayoutProps } from '../../types';
import { Subtitle } from '@/shared/ui/subtitle';

import styles from '../layouts.module.scss';

const cx = classNames.bind(styles);

export const DesktopMerchFilters = ({
hasActiveFilters,
searchFilters,
tagFilters,
onClearFilters,
}: LayoutProps) => {
return (
<div className={cx('controls-wrapper')}>
<div className={cx('desktop-actions-wrapper')}>
<Subtitle size="extra-small" weight="bold">
Filter merch
</Subtitle>
<button
type="button"
className={cx('button', 'secondary', { active: hasActiveFilters })}
onClick={onClearFilters}
>
Clear
</button>
</div>

{searchFilters}

{tagFilters}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we pass these components as props? The same about mobile version

</div>
);
};
120 changes: 120 additions & 0 deletions src/widgets/merch-section/ui/merch-catalog/layouts/layouts.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
.controls-wrapper {
display: flex;
flex-direction: column;
gap: $gap-xs;
}

.desktop-actions-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
}

.filter-accordion {
display: flex;
flex-direction: column;
gap: $gap-xs;
}

.button {
@extend %transition-all;

cursor: pointer;

gap: $gap-xs;
place-content: center center;
align-items: center;

font-weight: $font-weight-medium;
letter-spacing: 0;
white-space: pre;
}

.secondary {
width: max-content;
padding: $gap-xxs $gap-s;
border: 1px solid $color-gray-900;

font-size: $font-size-xxs;
color: $color-gray-900;

visibility: hidden;
opacity: 0;
background: none;

&:hover {
background-color: $color-gray-100;
}

&.active {
visibility: visible;
opacity: $opacity-100;
transition-delay: 0s;
}

@include media-tablet-large {
width: 10%;

&.active {
max-height: 35px;
padding: $gap-xs;
}
}

@include media-mobile-landscape {
width: 20%;
}
}

.tablet-actions-wrapper {
display: flex;
gap: $gap-xs;
}

.tablet-toggle-button {
cursor: pointer;

position: relative;

display: inline-flex;
gap: $gap-xs;
align-items: center;
justify-content: space-between;

width: 100%;
padding: $gap-s;
border: none;
border-radius: $border-radius-xxs;

font-size: $font-size-s;
font-weight: $font-weight-medium;

background-color: transparent;

transition: background-color 0.2s ease;

&.expanded {
background-color: $color-gray-50;
}

&:focus-visible {
outline: 1px solid $color-gray-600;
outline-offset: 1px;
}

&.has-active-filters::after {
content: '';
display: block;
width: 6px;
height: 6px;
}
}

.filter-toggle-arrow {
margin-left: auto;
transition: transform 0.2s ease-in-out;

&.rotate {
transform: rotate(180deg);
}
}
Loading
Loading