MDX сочетает возможности Markdown и JSX, позволяя интегрировать интерактивные компоненты в документацию. Одной из наиболее мощных функций является использование live-кода и песочниц, которые предоставляют возможность исполнять React-компоненты прямо в документации.
Для реализации live-кода в MDX применяется компонент
LiveProvider из библиотеки @mdx-js/react
или специализированные решения вроде react-live. Основная
идея заключается в том, чтобы предоставить пользователю поле для
редактирования кода и моментальный просмотр результата его
выполнения.
Пример минимальной конфигурации:
import { LiveProvider, LiveEditor, LiveError, LivePreview } from 'react-live';
import * as React from 'react';
const code = `<button onCl ick={() => alert('Hello!')}>Click me</button>`;
<LiveProvider code={code} scope={{ React }}>
<LiveEditor />
<LiveError />
<LivePreview />
</LiveProvider>
Разбор компонентов:
code) и контекст
(scope) с необходимыми библиотеками.scope – объект, через который live-код получает доступ к
библиотекам и компонентам. Без корректного объявления всех используемых
переменных выполнение кода вызовет ошибку.
Пример с несколькими зависимостями:
import { Button } from '@chakra-ui/react';
import * as React from 'react';
const code = `<Button colorScheme="teal">Click me</Button>`;
<LiveProvider code={code} scope={{ React, Button }}>
<LiveEditor />
<LiveError />
<LivePreview />
</LiveProvider>
Это позволяет безопасно интегрировать сторонние компоненты и стилизованные элементы.
Для создания полноценной песочницы можно использовать свойства
noInline и transformCode:
<React.Fragment>.Пример использования:
<LiveProvider
code={`function Counter() {
const [count, setCount] = React.useState(0);
return <button onCl ick={() => setCount(count + 1)}>{count}</button>;
}`}
scope={{ React }}
noInline
>
<LiveEditor />
<LiveError />
<LivePreview />
</LiveProvider>
Для TypeScript можно настроить компиляцию через babel
или использовать специализированные решения с react-live и
@babel/preset-typescript. Важно указать трансформацию кода
до выполнения:
import { transform } from '@babel/standalone';
import presetTypescript from '@babel/preset-typescript';
const code = `const message: string = "Hello TypeScript"; <div>{message}</div>`;
const transformedCode = transform(code, { presets: [presetTypescript, 'react'] }).code;
<LiveProvider code={transformedCode} scope={{ React }}>
<LiveEditor />
<LiveError />
<LivePreview />
</LiveProvider>
Редактор и preview можно кастомизировать через CSS или свойства компонентов:
Пример кастомного оформления:
<LiveProvider code={code} scope={{ React }}>
<div style={{ border: '1px solid #ddd', padding: '16px', borderRadius: '8px' }}>
<LiveEditor style={{ fontFamily: 'monospace', backgroundColor: '#f5f5f5' }} />
<LiveError style={{ color: 'red', marginTop: '8px' }} />
<LivePreview style={{ marginTop: '16px' }} />
</div>
</LiveProvider>
MDX позволяет вставлять live-код рядом с текстом и Markdown-разметкой, создавая динамическую и интерактивную документацию. Это особенно полезно для демонстрации UI-компонентов и обучения новым API без необходимости запускать отдельное окружение.
Блок live-кода может быть частью любого MDX-документа, что делает его универсальным инструментом для учебников, руководств и песочниц для демонстрации фреймворков и библиотек.