Ультрамодульная библиотека — это не библиотека в традиционном понимании, а скорее набор независимых компонентов. Такая архитектура обладает множеством преимуществ.

Вот перечень того, что содержит ультрамодульная библиотека:

  • Полная поддержка типов.
  • Предварительные просмотры (аналогично SB Stories) и автодокументация по каждому компоненту.
  •  Пользовательский компонент “Create theme” (“Создать тему”), расширяемый за счет дополнительного варианта компонента “Typography” (“Типографика”).
  • Пользовательская тема “Default” (“По умолчанию”), “Dark theme” (“Темная тема”), “Theme provider” (“Провайдер тем”) и “Dark mode toggle” (“Переключатель темного режима”).
  • Компоненты “Button” (“Кнопка”), “Typography” (“Типографика”) и многие другие.
  • Пользовательская многократно используемая среда разработки React (“React development environment”).

Под “независимыми компонентами” обычно подразумеваются Bit-компоненты. Поэтому убедитесь, что у вас установлена программа Bit и инициализировано рабочее пространство Bit.

npx @teambit/bvm install
bit new basic my-workspace

Клонирование полного решения в рабочее пространство Bit

Чтобы быстро начать работу, форкните (клонируйте) компоненты из этой области в свое рабочее пространство Bit (обязательно создайте рабочее пространство Bit и войдите в него с помощью CD).

Замените MY_BIT_PLATFORM_ACCOUNT на свое имя пользователя или название Bit-организации на платформе Bit. Замените  MY_SCOPE на имя вашей области видимости. Создайте новую область, если она еще не настроена.

cd my-workspace
bit scope fork learnbit-react.custom-mui-lib MY_BIT_PLATFORM_ACCOUNT.MY_SCOPE

Выполните следующие действия, чтобы изучить компоненты в пользовательском интерфейсе рабочей области:

bit start

Теперь в рабочем пространстве должны быть доступны все компоненты для изменения и экспорта (добавления) в вашу область на Bit-платформе.

bit tag -m "first version"
bit export 

Рассмотрим компоненты и разберемся с тем, что лежит в основе их применения.

Button

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

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

/**
* @componentId: learnbit-react.custom-mui-lib/actions/button
* @filename: button.tsx
*/

import {
Button as BaseButton,
type ButtonProps as BaseButtonProps,
} from '@mui/material';

export type ButtonProps = {} & BaseButtonProps;

export function Button({ children, ...rest }: ButtonProps) {
return <BaseButton {...rest}>{children}</BaseButton>;
}

Предварительный просмотр компонента

Для предварительного просмотра компонента “Button” предлагается несколько вариантов:

/**
* @componentId: learnbit-react.custom-mui-lib/actions/button
* @filename: button.compositions.tsx
*/

import { Button } from './button.js';

export const DefaultButton = () => {
return <Button>Click me</Button>;
};

export const ContainedButton = () => {
return <Button variant="contained">Click me</Button>;
};

export const OutlineddButton = () => {
return <Button variant="outlined">Click me</Button>;
};

Документация по компоненту

Bit автоматически генерирует ссылку на API компонента (см. вкладку “API Reference” на странице компонента локально или на Bit-платформе). Автогенерируемая документация может быть дополнена документацией, написанной вручную. Для создания этой документации используется живая экспериментальная площадка, позволяющая демонстрировать различные варианты использования компонента “Button”.

/**
* @componentId: learnbit-react.custom-mui-lib/actions/button
*
@filename: button.docs.mdx
*/

---
description: An MUI button
---

import { Button } from './button.js';

Введите текст, который хотите отобразить внутри компонента Button:

```jsx live
() => <Button>Click me</Button>;
```

Независимое версионирование

Поскольку создаваемая библиотека будет представлять собой набор независимых Bit-компонентов, изменения в каждом компоненте будут отражаться в журнале истории компонента и семантическом версионировании (MAJORE.MINOR.PATCH).

Пример релиза нового компонента “Button”:

bit tag actions/button -m "add custom docs" --patch
bit export

Typography

Предварительный просмотр вариантов компонента “Typography”

Компонент “Typography” расширяет стандартные разновидности типографики MUI дополнительным вариантом: handwriting (“Рукописный текст”).

Поскольку данная библиотека построена по модульно-композитному принципу, вам не придется помещать в корень проекта объявления типов (d.ts), поддерживающих это расширение. Достаточно дать команду компоненту, отвечающему за эту функцию, расширить тип “Default”. При этом гарантируется, что все будет работать гладко независимо от того, в каком именно проекте используются компоненты.

/**
* @componentId: learnbit-react.custom-mui-lib/typography/typography
* @filename: create-theme.ts
*/

import type { CSSProperties } from 'react';
import {
Typography as BaseTypography,
type TypographyProps as TypographyPropsMUI,
type TypographyVariant as BaseTypographyVariant,
type TypographyVariantsOptions as BaseTypographyVariantsOptions,
} from '@mui/material';

/**
* Компонент "Typography" расширен вариантом "handwriting".
*/

export type TypographyVariant = 'handwriting' | BaseTypographyVariant;

declare module '@mui/material/Typography' {
interface TypographyPropsVariantOverrides {
handwriting: true;
}
}

export interface TypographyProps extends TypographyPropsMUI {
variant?: TypographyVariant;
}

export function Typography({ children, ...rest }: TypographyProps) {
return <BaseTypography {...rest}>{children}</BaseTypography>;
}

/**
* Этот интерфейс может быть использован темой для определения вариантов компонента "Typography"
*/
export interface TypographyVariantsOptions
extends BaseTypographyVariantsOptions {
handwriting?: CSSProperties;
}

Create theme

Пользовательский компонент “Create theme” расширяет ресурсы MUI дополнительными тематическими вариантами (в данном случае новым вариантом типографики). Это позволяет пользователям генерировать новые темы в соответствии с расширенной схемой.

/**
 * @componentId: learnbit-react.custom-mui-lib/theme/create-theme
 * @filename: create-theme.ts
 */

import type { Theme } from "@mui/material";
import { createTheme as createThemeBase } from "@mui/material/styles";
import type { ThemeOptions } from "./theme-options.js";

export function createTheme(options: ThemeOptions, ...args: object[]): Theme {
  return createThemeBase(options, ...args);
}

Возможности выбора темы расширены вариантами, которые предлагает компонент “Typography”.

/**
* @componentId: learnbit-react.custom-mui-lib/theme/create-theme
* @filename: theme-options.ts
*/

import type { ThemeOptions as BaseThemeOptions } from "@mui/material";
import type { TypographyVariantsOptions } from "@learnbit-react/custom-mui-lib.typography.typography";

/**
* extend the options of the theme with an additional typography variants
*/
export interface ThemeOptions extends BaseThemeOptions {
typography?: TypographyVariantsOptions;
}

Пользовательская тема “Default”

Пользовательская тема использует компонент “Create theme” для создания темы с дополнительными свойствами (новый тип типографики):

/**
* @componentId: learnbit-react.custom-mui-lib/theme/default-theme
* @filename: default-theme.ts
*/

import {
createTheme,
type ThemeOptions,
} from "@learnbit-react/custom-mui-lib.theme.create-theme";
/** возвращает утверждения `@import`, которые загружают шрифты */
import { getDefaultFonts } from "@learnbit-react/custom-mui-lib.typography.get-default-fonts";

export function defaultTheme(): ThemeOptions {
return createTheme({
components: {
MuiCssBaseline: {
/**
* Глобальные переопределения CSS;
* немедленная загрузка шрифтов по умолчанию
* */
styleOverrides: getDefaultFonts(),
},
},
palette: {
mode: "light",
primary: {
main: "#4d64a8",
// ...
},
typography: {
fontFamily: "Outfit, sans-serif",
/* Это наш личный вариант типографики */
handwriting: {
fontFamily: "Handlee, cursive",
},
},
});
}

Пользовательская тема “Dark”

Тема “Dark” состоит из значений/дизайн-токенов, которые должны быть переопределены в теме, которую она расширяет и настраивает. В данном случае тема “Default” расширена темой “Dark”, но тот же шаблон может быть использован для расширения (причем неоднократного) любой темы на любой вкус.

/**
* @componentId: learnbit-react.custom-mui-lib/theme/dark-theme
* @filename: dark-theme.ts
*/

/* импортируйте тему для настройки и расширения */
import { defaultTheme } from "@learnbit-react/custom-mui-lib.theme.default-theme";
import {
createTheme,
type ThemeOptions,
} from "@learnbit-react/custom-mui-lib.theme.create-theme";

export function darkTheme(): ThemeOptions {
return createTheme(
/* тема для расширения */
defaultTheme(),
/* пользовательские значения для этой темы */
{
palette: {
type: "dark",
primary: {
main: "#6580f9",
},
// ...
},
});
}

Многократно используемая среда React-разработки 

Создание компонентов Bit поддерживается многократно используемыми средами разработки (“env”) с помощью компиляторов, линтеров, тестеров и т. д. Такая специальная среда разработки компонентов расширяет установочную среду React-разработки в Bit.

В данном случае не требуется изменять какие-либо дефолтные конфигурации. Однако мы хотели бы, чтобы наша многократно используемая среда (env) обертывала темой каждый предварительный просмотр компонентов. Это должно сэкономить время на ручную настройку “Theme provider” при каждом предварительном просмотре (а также обеспечить стандартный контекст предварительного просмотра).

/**
 * @componentId: learnbit-react.custom-mui-lib/dev/react-mui
 * @filename: preview/mounter.ts
 */

import React from 'react';
import { createMounter } from '@teambit/react.mounter';
/* импортируйте пользовательский провайдер тем */
import { ThemeProvider } from '@learnbit-react/custom-mui-lib.theme.theme-provider';

/**
 * предоставьте предварительный просмотр компонентов    
 * с контекстом, который им нужен для запуска
 * (в данном случае - пользовательская тема MUI)
 */
export function MyReactProvider({ children }: { children: React.ReactNode }) {
  return <ThemeProvider>{children}</ThemeProvider>;
}

Можно задать среду разработки (env) в файле конфигурации workspace.jsonc, чтобы новые компоненты создавались по шаблону, предоставленному этой средой (а также для автоматической настройки их с использованием этой среды):

/**
 * @filename: {workspace-root}/workspace.jsonc
 */

{
  // ...
    "teambit.generator/generator": {
    "envs": [
      /**
       * ОБЯЗАТЕЛЬНО ЗАМЕНИТЕ `learnbit-react.custom-mui-lib` 
       * НА СВОЙ `BIT_CLOUD_ACCOUNT.SCOPE_NAME`.
      "learnbit-react.custom-mui-lib/dev/react-mui"
    ]
  },
}

Например, компонент “Slider” будет создан с помощью этой среды разработки:

$ bit create react actions/slider

Результат должен подтвердить, что компонент был создан с использованием соответствующей среды разработки:

1 component(s) were created

learnbit-react.custom-mui-lib/actions/slider
    location: custom-mui-lib/actions/slider
    env:      learnbit-react.custom-mui-lib/dev/[email protected] (set by template)
    package:  @learnbit-react/custom-mui-lib.actions.slider

Подробнее о системах проектирования с помощью Bit можно найти здесь.

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи Bits and Pieces: Customize Material UI Components and Theme: A Modern Approach

Предыдущая статьяКак заработать с помощью бесплатного генератора артов на базе ИИ
Следующая статьяПонимание и реализация смарт-указателя Arc и мьютекса на Rust