diff --git a/pages/lesson-1/_meta.ru.json b/pages/lesson-1/_meta.ru.json index 9976b05..e5adb63 100644 --- a/pages/lesson-1/_meta.ru.json +++ b/pages/lesson-1/_meta.ru.json @@ -1,4 +1,5 @@ { "chapter-1": "1. Создание и настройка проекта", - "chapter-2": "2. Storybook и css переменные" + "chapter-2": "2. Storybook и css переменные", + "chapter-3": "3. Полиморфные компоненты" } diff --git a/pages/lesson-1/chapter-3.en.mdx b/pages/lesson-1/chapter-3.en.mdx new file mode 100644 index 0000000..922266a --- /dev/null +++ b/pages/lesson-1/chapter-3.en.mdx @@ -0,0 +1 @@ +# Under construction diff --git a/pages/lesson-1/chapter-3.ru.mdx b/pages/lesson-1/chapter-3.ru.mdx new file mode 100644 index 0000000..8473de9 --- /dev/null +++ b/pages/lesson-1/chapter-3.ru.mdx @@ -0,0 +1,327 @@ +import { Callout } from 'nextra/components' + +# Компоненты, полиморфные компоненты + +## Button + +### Подготовка + +- Создайте папку _src/components/ui_ + +- Создайте папку _button_ в _src/components/ui_ со следующей структурой: + +{/* prettier-ignore */} +```markdown +src +└── components + └── ui + └── button + └── button.tsx + └── button.module.scss + └── button.stories.ts + └── index.ts +``` + +### Дизайн и варианты + +После рассмотрения дизайна стало понятно, что у нас будет несколько вариантов кнопок, а именно: + +![Button](./images/Button.png) + +- Стандартная, она же основная, она же `primary` +- Второстепенная, она же `secondary` +- Третьестепенная, она же `tertiary`, иногда ее называют `outlined` +- Кнопка, занимающая всю ширину родителя, она же `fullWidth` +- Кнопка, которая выглядит как ссылка, она же `link` +- Ссылка, которая выглядит как кнопка + +### Варианты реализации + +Какие варианты реализации у нас есть? + +1. Создать один компонент, который будет принимать все возможные пропсы и в зависимости от них будет рендериться тот или иной вариант кнопки +2. Создать отдельный компонент для каждого варианта кнопки + +Мы отдадим предпочтение **первому варианту**, так как он более гибкий и позволит нам легко добавлять новые варианты кнопок в будущем. + +### Props + +Опишем пропсы, которые будет принимать наш компонент: + +```tsx filename="button.tsx" +import { ComponentPropsWithoutRef } from 'react' + +export type ButtonProps = { + variant?: 'primary' | 'secondary' | 'tertiary' | 'link' + fullWidth?: boolean +} & ComponentPropsWithoutRef<'button'> +``` + +`ComponentPropsWithoutRef<'button'>` - это пропсы, которые принимает стандартный html-тег button, мы их расширяем своими пропсами. + +### Реализация + +Создадим сам компонент: + +```tsx +import s from './button.module.scss' + +export const Button = ({ variant = 'primary', fullWidth, className, ...rest }: ButtonProps) => { + return ( +