CONTRIBUTING.md

April 6, 2026 · View on GitHub

Разработка

В проекте используется yarn workspaces.

Ознакомиться можно по ссылке Workspaces | Yarn.

Быстрый старт

  1. Склонируйте репозиторий и перейти в созданную директорию.
  2. Установите последнюю LTS версию Node.js. Если у вас есть nvm, запустите nvm install && nvm use в корневой папке репозитория.
  3. Включите corepack: corepack enable
  4. Установите зависимости: yarn install.
  5. Поднимите локально документацию с лайврелоадом: yarn docs:storybook.

Storybook будет доступен на http://localhost:6006. В ней ведётся вся разработка.

Дополнительные настройки по желанию

Добавить файл .git-blame-ignore-revs в свой git-конфиг:

git config blame.ignoreRevsFile .git-blame-ignore-revs

Это поможет игнорировать коммиты, связанные с изменениями стиля кода. git blame будет чище.

Чеклист для компонента

Организационные моменты

  • Один PR — одна фича/багфикс (рефакторинги выносим в отдельный PR)
  • Дизайн компонента описан в Figma
  • Компонент находится в своей папке в src/components и не делит её с другими публичными компонентами (один файл — один компонент)
  • У компонента есть понятная документация, описанная в директории компонента в файле website/content/components. Файл подключается в website/content/components/_meta.tsx и в website/components/mdx/Playground/scope.ts.
  • Вся документация и предупреждения в коде компонента (warnOnce) написаны на русском языке

Требования к Storybook

1. Создание stories

  • Каждый компонент должен иметь файл *.stories.tsx в своей директории
  • При необходимости можно добавлять дополнительные стори для демонстрации различных состояний компонента

2. Добавление на страницу "Components Overview"

  • Каждый новый компонент должен быть представлен на странице "Components Overview"
  • Обязательно должно быть стори с названием "Playground", чтобы корректно работала навигация к странице компонента в сторибуке
  • Подключение осуществляется через файл docs/components-overview/config.tsx
    • По умолчанию превью берется из стори компонента (обычно из "Playground")
    • Для сложных компонентов можно создать кастомное превью:
      • Кастомные превью размещаются в директории docs/components-overview/custom-components-preview
      • В config.tsx нужно указать использование кастомного превью вместо стандартного

Требования к разработке

  • В проекте используется CSS Modules (примеры можно увидить ниже).

    ⚠️ Composition

    Не используем композицию, т.к. в ней нет необходимости, а также в будущем она может усложнить переход на другое решение.

  • CSS-классы должны быть в формате camelCase: elementNameModification. Гайд по написанию стилей

  • Свойства className и style навешиваются на корневой элемент компонента

  • Свойства, не используемые в коде компонента, навешиваются на главный элемент компонента. По умолчанию главным является корневой элемент:

    const Component = (props) => <div {...props} className={styles.Component} />;
    

    Бывают случаи, например, поле ввода, когда главным является именно input, а не обёртка:

    import styles from './Input.module.css';
    
    const Input = ({ mode, style, className, ...restProps }) => {
      return (
        <div
          className={classNames(className, styles.host, mode === 'default' && styles.modeDefault)}
          style={style}
        >
          <input {...restProps} />
        </div>
      );
    };
    
  • Компонент корректно отрисовывается, если не передавать никаких свойств. Вместо defaultProps, deprecated для функциональных компонентов, используем спред:

    import styles from './Component.module.css';
    
    const Component = ({ mode = 'default', className, ...restProps }) => (
      <div
        className={classNames(className, styles.host, mode === 'default' && styles.modeDefault)}
        {...restProps}
      />
    );
    
  • Для цветов, скруглений, размеров, отступов и теней используются css-переменные из vkui-tokens

  • Для типографии используются компоненты Typography там, где это возможно

  • Добавлен export компонента и его свойств в packages/vkui/src/index.ts

  • При описании свойств для тестирования (data-testid) следует придерживаться следующего соглашения:

    • Шаблон JSDoc комментария: "Передает атрибут data-testid для <кого>"
    • Пример:
      type AlertProps = {
        /**
         * Передает атрибут `data-testid` для кнопки закрытия
         */
        dismissButtonTestId?: string | undefined;
      };
      
  • Компонент покрыт юнит- и скриншотными тестами. Гайд по тестированию

  • Компонент корректно отображается на всех платформах, размерах и цветовых схемах. В документации, включая Storybook, для всех этих параметров есть переключатели

  • Код корректно работает на поддерживаемых нами браузерах

  • Для поддержки адаптивности следует придерживаться гайда по написанию адаптивных компонентов

  • a11y (см. пример хорошего PR с внедрением доступности, на который можно равняться #3337):

    • Компонент соответствует требованиям a11y

    • Написаны юнит-тесты на кейсы связанные с a11y

    • В документации компонента есть раздел про a11y (если необходимо)

    • Анимации, которые могут вызвать утомляемость у людей с нарушением вестибулярного аппарата, учитывают запрос @media (prefers-reduced-motion: reduce). Зачастую это анимации появления/исчезновения. В них передвижения, по типу transform: translate(), и/или изменения размера, по типу transform: scale(), должны быть приведены к анимации через прозрачность, например, как сделано в Alert. Есть исключение, когда пользователь сам изменяет объект, например, swipe-back в компоненте View, или анимация совсем незначительная, например, как в Switch или в <Cell mode="removable" />iOS).

      В PR #6979 можно посмотреть больше примеров таких упрощений.