Декораторы компонентов

Декораторы компонентов в MDX представляют собой мощный механизм для оборачивания и модификации визуальных компонентов на уровне документации. Они позволяют добавлять общие обертки, стили или функциональные возможности к компонентам без изменения их исходного кода. В контексте использования MDX в React-документации декораторы обеспечивают единообразие и повышают повторное использование кода.

Основы использования декораторов

Декоратор — это функция, которая принимает компонент и возвращает модифицированный компонент. В MDX декораторы применяются через объект parameters или с использованием функции addDecorator, если речь идет о Storybook. Типичный синтаксис в MDX выглядит так:

import { Meta, Story } from '@storybook/addon-docs';

export const decorators = [
  (Story) => (
    <div style={{ margin: '3em', border: '1px solid #eee', padding: '1em' }}>
      <Story />
    </div>
  ),
];

Здесь каждый компонент, используемый внутри MDX, будет автоматически обернут в div с заданными стилями. Такой подход особенно удобен для унификации отступов, фреймов или темной/светлой темы.

Локальные и глобальные декораторы

Глобальные декораторы задаются один раз для всего проекта и применяются ко всем сториз или компонентам MDX:

// .storybook/preview.js
export const decorators = [
  (Story) => <ThemeProvider theme={defaultTheme}><Story /></ThemeProvider>,
];

Локальные декораторы применяются только к конкретному MDX-документу или отдельной сториз:

<Meta title="Button" decorators={[(Story) => <div className="local-wrapper"><Story /></div>]} />

Разделение на глобальные и локальные декораторы позволяет управлять контекстом компонентов гибко, избегая дублирования кода.

Комбинирование нескольких декораторов

MDX поддерживает последовательное применение нескольких декораторов. Каждый последующий оборачивает результат предыдущего:

export const decorators = [
  (Story) => <div style={{ padding: '10px' }}><Story /></div>,
  (Story) => <div style={{ border: '2px dashed red' }}><Story /></div>,
];

В результате компонент будет сначала обернут в div с отступами, а затем в div с рамкой. Порядок декораторов имеет значение: последний применяется самым наружным слоем.

Декораторы и контексты

Декораторы идеально подходят для подключения провайдеров контекста, таких как Redux Provider или React Router. Например:

import { Provider } from 'react-redux';
import store from './store';

export const decorators = [
  (Story) => <Provider store={store}><Story /></Provider>,
];

В этом случае все компоненты внутри MDX-документа автоматически получают доступ к состоянию Redux без необходимости вручную оборачивать каждый компонент.

Динамические декораторы

Можно создавать декораторы, которые принимают параметры и изменяют поведение компонента в зависимости от этих параметров:

const withPadding = (padding) => (Story) => (
  <div style={{ padding }}>{<Story />}</div>
);

export const decorators = [withPadding('20px')];

Такой подход облегчает создание повторно используемых стилей и логики.

Особенности интеграции с Storybook

В Storybook для MDX декораторы могут комбинироваться с другими параметрами, такими как parameters и args. Важно учитывать, что:

  • Декораторы применяются до передачи args компоненту. Это позволяет корректно работать с контекстом и пропсами.
  • Декораторы можно применять как на уровне всего документа, так и на уровне отдельной сториз, используя синтаксис <Story decorators={...} />.

Советы по организации

  • Для крупных проектов рекомендуется хранить общие декораторы в отдельном файле и импортировать их в MDX-документы.
  • Локальные декораторы использовать только для уникальных сценариев, чтобы не нарушать общую консистентность дизайна.
  • Всегда учитывать порядок применения декораторов, особенно если используются провайдеры контекста или темы.

Практическая демонстрация

<Meta title="Card" decorators={[
  (Story) => <div style={{ maxWidth: '400px', margin: '0 auto' }}><Story /></div>,
  (Story) => <ThemeProvider theme={darkTheme}><Story /></ThemeProvider>,
]} />

<Story name="Default Card">
  <Card title="Пример карточки" content="Содержимое карточки" />
</Story>

В этом примере карточка будет отображаться с максимальной шириной и по центру, при этом будет применена темная тема, обеспечивая сразу два уровня обертки через декораторы.

Декораторы компонентов в MDX — это ключевой инструмент для стандартизации внешнего вида и функциональности компонентов, обеспечения единого контекста и повышения переиспользуемости кода в документации и сториз.