Skip to content

Commit

Permalink
574-refactor: List component (#575)
Browse files Browse the repository at this point in the history
* refactor: 574 - move ListData type to separate file

* refactor: 574 - add additional prop to List

* fix: 574 - components & data-files with new List props

* fix: 574 - after review

* fix: 574 - after review
  • Loading branch information
ansivgit authored Oct 10, 2024
1 parent cef2f22 commit a10d82e
Show file tree
Hide file tree
Showing 12 changed files with 66 additions and 31 deletions.
2 changes: 1 addition & 1 deletion dev-data/courses-data.types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Course } from '@/entities/course';
import { type ListData } from '@/shared/ui/list';
import type { ListData } from '@/shared/types';

export type DataMap = {
courses: Course[];
Expand Down
10 changes: 5 additions & 5 deletions dev-data/training-program.data.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ export const contentMap: ContentMap = {
data={[
'Знакомство со школой, профессией JS/Front-end разработчика и системой контроля версий Git.',
]}
marked={false}
type="unmarked"
/>
</Paragraph>,
<Paragraph key="js / front-end pre-school ru 02">
Expand All @@ -212,7 +212,7 @@ export const contentMap: ContentMap = {
'JavaScript: Основы, функции, объекты, массивы и работа с DOM.',
'Инструменты: Chrome Dev Tools, VS Code, Терминал и Figma.',
]}
marked={false}
type="unmarked"
/>
</Paragraph>,
<Paragraph key="js / front-end pre-school ru 03">
Expand All @@ -224,18 +224,18 @@ export const contentMap: ContentMap = {
'CSS Mem Slider: Продвинутый проект по CSS.',
'Проекты JS-30: Аудиоплеер, галерея изображений и случайная игра.',
]}
marked={false}
type="unmarked"
/>
</Paragraph>,
<Paragraph key="js / front-end pre-school ru 04">
<span>Задачи Codewars:</span>
<List data={['Еженедельные задачи по алгоритмам и структурам данных.']} marked={false} />
<List data={['Еженедельные задачи по алгоритмам и структурам данных.']} type="unmarked" />
</Paragraph>,
<Paragraph key="js / front-end pre-school ru 05">
<span>Итоговая аттестация:</span>
<List
data={['Кросс-чек проектов, тесты и ревью кода. Выдача сертификата.']}
marked={false}
type="unmarked"
/>
</Paragraph>,
],
Expand Down
2 changes: 1 addition & 1 deletion src/pages/javascript-en.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const JavaScriptEn = () => {
<Certification courseName={COURSE_NAME} />
<Communication courseName={COURSE_NAME} />
<AboutVideo />
<StudyPath path="javascript" marked />
<StudyPath path="javascript" type="marked" />
<Required courseName={COURSE_NAME} />
<Trainers trainers={javaScriptEn} />
</>
Expand Down
5 changes: 5 additions & 0 deletions src/shared/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { LinkList } from '@/widgets/required/required.types';

export type ListData = (string | LinkList)[] | [];

export type ListType = 'marked' | 'unmarked';
2 changes: 1 addition & 1 deletion src/shared/ui/list/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { List, type ListData, type ListProps } from './list';
export { List } from './list';
9 changes: 9 additions & 0 deletions src/shared/ui/list/list.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
letter-spacing: 0.5px;
list-style-type: none;

&.compact {
gap: 0;
letter-spacing: 0;

@include media-laptop {
font-size: 16px;
}
}

&.marked {
list-style-type: disc;
}
Expand Down
4 changes: 2 additions & 2 deletions src/shared/ui/list/list.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ describe('List Component', () => {
expect(list).toHaveClass(cx('marked'));
});

it("doesn't have the 'marked' class when marked prop is false", () => {
render(<List data={data} marked={false} />);
it("doesn't have the 'marked' class when 'type' prop is 'unmarked", () => {
render(<List data={data} type="unmarked" />);

items?.forEach((listItem) => {
expect(listItem).not.toHaveClass(cx('marked'));
Expand Down
41 changes: 30 additions & 11 deletions src/shared/ui/list/list.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,46 @@
// todo delete TextWithLink
import { HTMLAttributes } from 'react';
import { type VariantProps, cva } from 'class-variance-authority';
import classNames from 'classnames/bind';
import { TextWithLink } from '../text-with-link';
import { LinkList } from '@/widgets/required/required.types';
import { ListData } from '@/shared/types';

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

export type ListProps = {
data: ListData;
marked?: boolean;
};

export type ListData = (string | LinkList)[] | [] | undefined;
type ListProps = Pick<HTMLAttributes<HTMLElement>, 'className'>
& VariantProps<typeof listVariants>
& { data: ListData };

export const cx = classNames.bind(styles);

export const List = ({ data, marked = true }: ListProps) => {
const listVariants = cva(cx('list'), {
variants: {
size: {
compact: cx('compact'),
medium: cx('medium'),
},
type: {
marked: cx('marked'),
unmarked: cx(''),
},
},
defaultVariants: {
size: 'medium',
type: 'marked',
},
});

export const List = ({ data, className = '', size, type }: ListProps) => {
if (!data?.length) {
return <></>;
return null;
}

return (
<ul
className={cx('list', { marked })}
className={listVariants({
size,
type,
className,
})}
data-testid="list"
>
{data.map((listItem) => {
Expand Down
4 changes: 2 additions & 2 deletions src/widgets/study-path/ui/stage-card/stage-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const StageCard = ({
topics,
imageSrc,
list,
marked,
type,
}: StageCardProps) => {
return (
<div className="stage">
Expand All @@ -27,7 +27,7 @@ export const StageCard = ({
{description && <p className="stage-description">{description}</p>}
{links && <Links links={links} />}
{topics && <Topics topics={topics} />}
{list && <List data={list} marked={marked} />}
{list && <List data={list} type={type} />}
</div>

{logoIcon && <LogoIcon icon={logoIcon} title={title} />}
Expand Down
4 changes: 2 additions & 2 deletions src/widgets/study-path/ui/stage-card/stage-card.types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type ListData } from '@/shared/ui/list';
import type { ListData, ListType } from '@/shared/types';

export interface Stage {
id: number | string;
Expand All @@ -16,5 +16,5 @@ export interface Stage {
}

export interface StageCardProps extends Stage {
marked?: boolean;
type?: ListType;
}
7 changes: 4 additions & 3 deletions src/widgets/study-path/ui/stages/stages.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { type Stage, StageCard } from '../stage-card';
import type { ListType } from '@/shared/types';

import './stages.scss';

export interface StagesProps {
stages: Stage[] | null;
marked?: boolean;
type?: ListType;
}

export const Stages = ({ stages, marked }: StagesProps) => {
export const Stages = ({ stages, type }: StagesProps) => {
if (stages === null || stages.length === 0) {
return null;
}
Expand All @@ -25,7 +26,7 @@ export const Stages = ({ stages, marked }: StagesProps) => {
topics={topics}
imageSrc={imageSrc}
list={list}
marked={marked}
type={type}
/>
))}
</div>
Expand Down
7 changes: 4 additions & 3 deletions src/widgets/study-path/ui/study-path.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createContext } from 'react';
import { Stages } from './stages';
import { useDataByName } from '@/shared/hooks/use-data-by-name';
import type { ListType } from '@/shared/types';
import { Paragraph } from '@/shared/ui/paragraph';
import { WidgetTitle } from '@/shared/ui/widget-title';
import type { DataMap } from 'data';
Expand All @@ -11,7 +12,7 @@ type PathNames = Exclude<keyof DataMap, 'courses'>;

interface StudyPathProps {
path: PathNames;
marked?: boolean;
type?: ListType;
lang?: 'ru' | 'en';
}

Expand All @@ -30,7 +31,7 @@ const localizedContent = {

export const LangContext = createContext<'ru' | 'en'>('en');

export const StudyPath = ({ path, marked, lang = 'en' }: StudyPathProps) => {
export const StudyPath = ({ path, type, lang = 'en' }: StudyPathProps) => {
const { data: coursesPath } = useDataByName<PathNames>(path);

const isAngularOrAwsDev = path === 'angular' || path === 'awsDev';
Expand All @@ -47,7 +48,7 @@ export const StudyPath = ({ path, marked, lang = 'en' }: StudyPathProps) => {
<div className="study-path content upd">
<WidgetTitle size="small" mods="asterisk">{title}</WidgetTitle>
<Paragraph>{paragraph}</Paragraph>
<Stages stages={coursesPath} marked={marked} />
<Stages stages={coursesPath} type={type} />
</div>
</section>
</LangContext.Provider>
Expand Down

0 comments on commit a10d82e

Please sign in to comment.