Что выбрать в качестве библиотеки компонентов для React-проекта

Меня зовут Ксюша Луговая. В СберКорусе я занимаюсь поддержкой библиотеки React-компонентов Korus-UI. 

С проблемой выбора библиотеки рано или поздно сталкивается почти каждый разработчик, и порой решение может быть нетривиальным. Возникают вопросы: чем руководствоваться при выборе библиотеки, какие популярные решения предлагает рынок, какие у них плюсы и минусы? Обзоры и отзывы не всегда помогают найти решение.

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

Основные критерии выбора библиотеки

Сценарии использования библиотеки. Это звучит очевидно, но четкое понимание задач — первоочередный критерий выбора.

Типы компонентов приложения. От типа приложения зависит, какие компоненты вам потребуются. Часто достаточно набора кнопок/чекбоксов, базовых полей ввода, списков/меню с готовыми стилями. Значит, можно воспользоваться простыми компонентами с минимальным количеством настроек и готовыми стилями.

Настройки, форматирование и интерактивность в дизайне. Если вам нужно значительно отформатировать и стилизовать свои компоненты, это тоже важно решить заранее.

Когда требования четко сформулированы, ответьте на вопросы:

  • Хорошо ли составлена документация проекта, есть ли интерактивные примеры?

  • Насколько активно поддерживается проект?

  • Сколько в проекте issues и как быстро они решаются?

  • Проект бесплатный или коммерчески лицензированный?

  • Насколько легко настраиваются компоненты?

  • Покрыт ли код библиотеки тестами?

  • Какие браузеры и платформы поддерживает библиотека?

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

Я отобрала следующие библиотеки, чтобы наглядно показать процесс анализа по критериям:

  • Material-UI,

  • Semantic-UI-React,

  • yandex-ui,

  • arui-feather,

  • Korus-UI.

С одной стороны, в этом списке  представлены наиболее популярные проекты — Material-UI и Semantic-UI-React, которые были созданы одним разработчиком и со временем обросли большим сообществом.

С другой стороны — библиотеки, созданные внутри крупных компаний (Яндекс, Альфа Банк) для своих проектов, которые постепенно обрели популярность в качестве opensource решений.

Далее рассмотрим сравнение библиотек в разрезе определенных выше критериев.

Компонентный состав

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

Компоненты библиотек можно разделить на несколько групп.

Layout-компоненты 

Контейнеры, карточки, таблицы, гриды и прочие. Основные характеристики:

  • Отвечают только за отображение;

  • Часто принимают на вход только props.children;

  • Не имеют своего состояния и методов жизненного цикла;

  • Примеры:   h1, section, div, span, Icon, Avatar.

Готовые дизайн-системы библиотек сильно упрощают верстку, если проекту не нужна своя тема стилей. Например, Material-UI и Semantic-UI могут вполне справиться с этой задачей. Однако в крупных коммерческих проектах своя дизайн-система и кастомизация стилей библиотек будет избыточной.

Компоненты-контролы (controls)

Кнопки, чекбоксы, радиокнопки, поля ввода, слайдеры — небольшие базовые компоненты, которые помогают «оживить» контент и обеспечивать взаимодействие с пользователем. 

Основные характеристики:

  • Отвечают за отображение и не имеют внутреннего состояния;

  • Принимают данные и функции обратного вызова в качестве props;

  • Состояние компонентов связано в основном только с UI (disabled, required, isLoading).

Сложные модульные компоненты

Это группа компонентов с более сложной логикой, они расширяют функции базовых компонентов и могут их комбинировать. 

Основные характеристики:

  • Имеют состояние;

  • Предоставляют данные и логику layout-компонентам (валидация, форматирование вывода, автодополнение);

  • Комбинируют другие компоненты.

Layout

Controls

Modules

Количество компонентов

Material-UI

App Bar, Avatars, Badges, Bottom Navigation, Divider, Grid List, Lists, Paper, Progress, Snackbar, Tables,  

Button, Chip, Selection Controls, Text Fields, Pickers*

Dialog, Cards, Drawers, ExpansionPanel, Menu, Stepper, Tabs, Tooltip

26**

Semantic-UI-React

Container, Divider, Flag, Header, Icon, Image, Label, List, Loader, Placeholder, Rail, Reveal, Segment, Step, Breadcrumb, Form, Grid, Menu, Message, Table, Advertisement, Card, Comment, Feed, Item, Statistic

Button, Input, Checkbox, Radio, Select, Text Area

Accordion, Dimmer, Dropdown, Embed, Modal, Popup, Progress, Rating, Search, Sidebar, Sticky, Tab, Transition, Visibility, Confirm, Pagination, Portal, Ref, Transitionable Portal

52

yandex-ui

Badge, Divider, Icon, Image, Text, UserPic, ListTile, Spacer, Link, Spin

Attach, Button, Checkbox, Menu, Radiobox, RadioButton, Select, Slider, Textarea, Textinput, Tumbler

TabsMenu, Drawer, Dropdown, Messagebox, Modal, Popup, TabsPanes, Tooltip, Progress 

30

arui-feather

Amount, CardImage, FlagIcon, Form, GridRow, GridCol, Heading, Icon, InputGroup, Label, Link, List, Paragraph, Spin

Attach, Button, CardInput, CheckBoxGroup, CheckBox, FormField, IconButton, Input, RadioGroup, Radio, Select, TagButton, Textarea, Toggle

CalendatInput, Calendar, Collapse, EmailInput, InputAutocomplete, IntlPhoneInput, Menu, MoneyInput, Notification, PhoneInput, Plate, Popup, ProgressBar, Sidebar, SlideDown, Tabs

44

Korus-UI

HTML tags factory***,

Currency, Tags

Button, Checkbox, Input,   Radio, Rating, Slider, Switcher, Textarea

Autocomplete, ButtonGroup, Collapse, Collapsible,  

DatePicker, DateRange, DateTimePicker, DateTimeRange, Dropdown, DropdownLink, DropdownSelect, Dropzone, FileDrop, FileUpload, Loader, MaskedInput, Modal, MultiSelect, Notifications, NumericRange, NumericTextBox, Pagination, Password, ProgressBar, StatusBar, StickyPanel, Tabs, TimePicker, TimeRange, Tooltip, Tour,   Validation, VStepper, Wizard, form

45

+ Компоненты-обертки для всех основных HTML-тегов

*Material-UI использует нативный календарь браузера в компонентах с выбором даты

**Основные компоненты библиотеки, для которых есть примеры в документации

***Korus-UI создает обертку для всех основных HTML-тегов c единым API

Почти 50% компонентного состава Material-UI и Semantic-UI-React и около 30% в библиотеках yandex-ui и arui-feather — малофункциональные layout-компоненты. В Korus-UI более 70% — сложные модульные компоненты.

Кастомизируемость

Возможность подстраивать компоненты под собственный дизайн экономит много времени и сил в будущем. Сравним подходы к кастомизации визуального отображения компонентов на примерах.

Material-UI

  • С помощью MuiThemeProvider. Компонент использует контекст библиотеки React для передачи объекта с темой всем дочерним компонентам.

  • Через добавление классов. Все компоненты поддерживают атрибут className.

Для кастомизации дочерних компонентов необходимо воспользоваться атрибутом classes.

Библиотека заточена на применение CSS-in-Js, что может вызвать определенные трудности, если стили для приложения содержатся в CSS-файлах. Для внедрения кастомных стилей CSS-in-Js предоставляется HOC withStyles () либо хук makeStyles () для функциональных компонентов.

Semantic-UI-React

У Semantic-UI-React нет своей темы, можно использовать стили  Semantic-UI.

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

Это:

yandex-ui

У библиотеки Яндекса несколько пресетов с темами. Их можно подключить сразу для всего проекта или применить стили для определенных компонентов.

Возможности:

  • Создание кастомной темы с помощью инструмента themekit;  

  • Переопределение значения (токены) в теме;

  • Дизайн-токены в формате yaml или json. Их можно собрать в итоговый файл (css, json, js, ios, android) и подключить к проекту.

arui-feather (Альфа Банк)

У библиотеки Альфа Банка нет руководства по кастомизации стилей в общедоступной документации.  Компоненты поддерживают атрибут className, возможно задать кастомные классы только их оберткам.

Korus-UI (СберКорус)

  • Кастомизация темы с помощью компонента LedaProvider. Он использует контекст библиотеки React для передачи объекта с темой всем дочерним компонентам.

  • Можно написать кастомные стили под имеющуюся вёрстку. Полный список классов  в компонентах находится в разделе API-документации (см. атрибут theme). Их можно переопределять глобально для всех компонентов одного типа или для каждого индивидуально.

Расширяемость

В работе с библиотекой может возникнуть потребность изменить внутренний элемент компонента. Например, добавить картинку или иконку в поле ввода, заменить элемент на новый (в компонент Loader передать кастомный элемент спиннера).

Рассмотрим решения.

Material-UI

Позволяет изменять корневые элементы с помощью атрибута component.

Например, компонент List по дефолту рендерит

    элемент. Его можно заменить другим элементом или React компонентом:

    
      
        
      
      
        
      
    

    Semantic-UI

    Semantic-UI-React компоненты поддерживают схожий по функциональности атрибут as:

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

    yandex-ui

    Предлагает использовать библиотеку render-override.  В ней есть набор хуков и компонентов для реализации переопределения элементов внутри составного компонента. 

    Пример:

    import React from 'react'
    import { useRenderOverride } from '@yandex/ui/lib/render-override'
    
    const ElementOriginal = ({ children }) => 
    {children}
    const MyComponent = ({ renderElement }) => { const Element = useRenderOverride(ElementOriginal, renderElement)   return (     <>       ) }

    В библиотеке yandex-ui расширяемость для существующих компонентов не реализована.

    arui-feather (Альфа Банк)

    Расширяемость компонентов не реализована.

    Korus-UI

    Расширяемость внутренних элементов библиотеки с помощью специального API. На вход компоненту можно передать атрибут из названия элемента и суффикса Render. Атрибуту присваивается функция, возвращающая элемент, которым заменяют существующий.

    Простейший пример:

    labelRender={() => }

    Структура метода позволяет вносить изменения максимально гибко:

    ({ Element, elementProps, componentProps, componentState }) => React.Node
    • Element — сам элемент

    • elementProps — props элемента

    • componentState, componentProps — для удобства дополнительно приходят объекты с props и state всего компонента

    Если мы хотим, чтобы новый элемент принимал на вход те же пропсы, можно отредактировать пример:

     }
    >
      Label
    

    Типизация

    Для типизации React-проектов применяются 2 основных инструмента:

    • Typescript

    • PropTypes

    В документации React для большой кодовой базы отдается предпочтение Typescript. Это инструмент статической типизации, который позволяет отлавливать большинство ошибок еще до исполнения кода. У PropTypes проверка типизации осуществляется только после запуска кода — это существенный недостаток по сравнению с другими инструментами.

    В основном рассматриваемые библиотеки для типизации используют Typescript. У Semantic-UI основная библиотека написана на ванильном JS, а Typescript используется только в Semantic-UI-React, созданной для интеграции с библиотекой React.

    Покрытие тестами

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

    Ради справедливости стоит отметить, что автоматические тесты — не панацея. Высокий процент покрытия не гарантирует качество теста и охват основных пользовательских сценариев.

    Но без покрытия тестами невозможно проверить совместную работу компонентов (интеграционное тестирование) и их работу вообще (модульное тестирование).

    Сравним библиотеки на покрытие тестами.

    Инструменты 

    Типы тестов

    % покрытия

    Material-UI

    Chai, Mocha, Sinon

    Unit

    95.28% Statements

    87.22% Branches

    97.51% Functions

    95.26% Lines

    Semantic-UI

    Jasmine, Karma

    Unit

    Отчет о покрытии отсутствует

    Semantic-UI-React

    Chai, Enzyme

    Unit

    Отчет о покрытии отсутствует

    yandex-ui

    Jest, Enzyme

    Unit

    Запуск тестов приводит к ошибке

    arui-feather

    Jest, Enzyme

    Unit

    88.1% Statements

    73.84% Branches

    66.61% Functions

    87.19% Lines

    Korus-UI

    Cypress, Jest

    Unit, end-to-end

    69.28% Statements

    56.14% Branches

    66.29% Functions

    71.78% Lines

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

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

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

    Наличие интерактивных примеров

    Storybook

    Material-UI

    https://material-ui.com/ru/

    -

    -

    Semantic-UI-React

    https://react.semantic-ui.com/

    +

    -

    yandex-ui

    https://yastatic.net/s3/frontend/lego/storybook/index.html

    -

    +

    arui-feather

    https://digital.alfabank.ru/

    +

    -

    Korus-UI

    https://opensource.esphere.ru/korus-ui/

    +

    +

    Поддержка

    Иногда возникает проблема, которая требует сторонней помощи. Нужно заранее определить, как ее получить.

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

    По этой причине выигрышно смотрятся библиотеки от крупных компаний-разработчиков. У них есть техподдержка и постоянная команда разработки, поэтому больше шансов решить проблему оперативно. Правки от крупных разработчиков поступают в продакшн по графику, закрепленному в релизной политике, а ответы на запросы дают своевременно.

    В разделе Pulse на GitHub можно ознакомиться со статистикой репозитория по количеству Pull Request и коммитов за определенный период времени. Он находится на вкладке Insights каждого репозитория. Рассмотрим статистику по выбранным библиотекам.

    Material-UI

    e5fpd0qllq8u6s-wilbg91dxqty.png

    Semantic-UI

    2etom1mxwjdscp-fjlmkrnvtuik.png

    yandex-ui

    mirakcqwg5cyjpwktwtllzpds_e.png

     arui-feather (Альфа Банк)

    acw-pej8ech22lqxry1-bxvanlc.png

     Korus-UI (СберКорус)

    1xjxqckjvzeihiyzr_knmi1bwhm.png

    Популярность

    Популярность библиотеки принято оценивать по звездам на GitHub и количеству скачиваний npm-пакета. Показатели легко проверить и измерить, они свидетельствуют о доверии разработчиков и наличии сообщества у библиотеки. Это упрощает ее использование и поиск решений для возникающих проблем. 

    Однако стоит помнить, что популярность — это также результат хорошей маркетинговой стратегии и SEO-оптимизации, которые могут обеспечить библиотеке первые места в выдаче поисковика. Поэтому следует изучить обсуждения в блогах и на форумах, например, на Stackoverflow, Medium, DEV. Обсуждения находятся в разделе issues проекта. 

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

    Звезды

    Скачивания за последний год

    Соотношение количества звезд и скачиваний за последний год,   % 

    Material-UI

    63 400

    6 372 353

    0,99

    Semantic-UI

    48 800

    541 299

    9

    Semantic-UI-React

    11 900

    8 620 967

    0,14

    @yandex/ui

    212

    15 902

    1,33

    arui-feather (Альфа Банк)

    559

    26 744

    2

    Работа с формами и валидация данных

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

    При взаимодействии с пользователем возникают разные проблемы: от ввода невалидных данных до попыток внедрения вредоносного кода. Поэтому золотым стандартом является валидация введенных данных до того, как они будут отправлены на сервер. 

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

    Сравним работу с формами в различных библиотеках на конкретном примере.

    Задача: создать базовую форму авторизации с двумя полями для ввода логина и пароля и кнопкой отправки формы. Поля мы хотим сделать обязательными, чтобы незаполненное поле подсвечивалось, а текст ошибки отображался как при потере фокуса, так и после нажатия на кнопку «Отправить».

    Korus-UI

    Посмотреть код

    const BasicForm = () => (
      
        
        
        
          Submit
        
      
    );

    Material-UI

    Посмотреть код

    const BasicForm = () => {
      const [login, setLogin] = React.useState("");
      const [loginError, setLoginError] = React.useState(false);
      const [password, setPassword] = React.useState("");
      const [passwordError, setPasswordError] = React.useState(false);
    
      return (
        
    { e.preventDefault(); setLoginError(!login); setPasswordError(!password); }} >

    { setLoginError(false); setLogin(e.target.value); }} onBlur={(e) => { setLoginError(!login); }} helperText={loginError && "Login is required"} />

    { setPasswordError(false); setPassword(e.target.value); }} onBlur={(e) => { setPasswordError(!password); }} helperText={passwordError && "Password is required"} />

    ); };

    Semantic-UI-React

    Посмотреть код

    const BasicForm = () => {
      const [login, setLogin] = React.useState("");
      const [loginError, setLoginError] = React.useState(false);
      const [password, setPassword] = React.useState("");
      const [passwordError, setPasswordError] = React.useState(false);
    
      return (
        
    { e.preventDefault(); setLoginError(!login); setPasswordError(!password); }} > { setLoginError(false); setLogin(e.target.value); }} onBlur={(e) => { setLoginError(!login); }} /> { setPasswordError(false); setPassword(e.target.value); }} onBlur={(e) => { setPasswordError(!password); }} />
    ); };

    arui-feather

    Посмотреть код

    const BasicForm = () => {
      const [login, setLogin] = React.useState("");
      const [loginError, setLoginError] = React.useState(false);
      const [password, setPassword] = React.useState("");
      const [passwordError, setPasswordError] = React.useState(false);
    
      return (
        
    { e.preventDefault(); setLoginError(!login); setPasswordError(!password); }} > { setLoginError(false); setLogin(value); }} onBlur={(e) => { setLoginError(!login); }} /> { setPasswordError(false); setPassword(value); }} onBlur={(e) => { setPasswordError(!password); }} />
    ); };

    yandex-ui

    Посмотреть код

    const BasicForm = () => {
      const [login, setLogin] = React.useState("");
      const [loginError, setLoginError] = React.useState(false);
      const [password, setPassword] = React.useState("");
      const [passwordError, setPasswordError] = React.useState(false);
    
      return (
        
    { e.preventDefault(); setLoginError(!login); setPasswordError(!password); }} className={cnTheme(theme)} > { setLoginError(false); setLogin(e.target.value); }} onBlur={(e) => { setLoginError(!login); }} hint={loginError && "Login is required"} /> { setPasswordError(false); setPassword(e.target.value); }} onBlur={(e) => { setPasswordError(!login); }} hint={passwordError && "Password is required"} /> ); };

    Как видно из примеров, в Korus-UI задача создания формы с валидацией решается парой дополнительных атрибутов, тогда как в остальных библиотеках требуется достаточно много кода и проверок. 

    В Material-UI и yandex-ui нет компонента формы, в Semantic-UI-React и arui-feather компонент формы является простой оберткой тега

    и не предоставляет никакой дополнительной функциональности.

    Встроенная валидация полей отсутствует во всех рассмотренных библиотеках, кроме Korus-UI. Для реализации более сложной логики понадобится еще одна библиотека.

    Сравнительный анализ библиотек React-компонентов

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

    Korus-UI (СберКорус)

    Material-UI

    Semantic-UI-React

    arui-feather (Альфа Банк)

    yandex-ui

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

    Storybook

    +

    +

    Примеры можно редактировать прямо в документации

    +

    +

    +

    Поддержка

    Количество Pull Request за последний месяц

    70

    241

    2

    0

    0

    Лицензия

    MIT license

    MIT license

    MIT license

    Mozilla Public License 2.0

    Mozilla Public License 2.0

    Покрытие тестами

    Процент покрытия > 50%

    +

    +

    +

    Не удалось выяснить

    E2E тесты

    +

    Поддержка браузеров и платформ 

    Chrome

    85.0.4183.121

    >= 49

    Last 2 v.

    Last 2 v.

    Last 2 v.

    Firefox

    81.0.1

    >= 52

    Last 2 v.

    Last 2 v.

    >= 23

    Edge

    85.0.564.44

    >=14

    12+

    Last 2 v.

    IE

    11

    11

    11+

    11+

    11+

    Safari

    14

    >= 10

    Last 2 v.

    Last 2 v.

    Opera

    Last 2 v.

    >= 12.1

    Yandex

    Last 2 v.

    ?

    Android

    4.4+

    5+

    >= 4

    iOS Safari

    7+

    Last 2 v.

    >= 5.1

    Кастомизируемость

    Возможность подключения кастомной темы

    +

    +

    +

    +

    Расширяемость

    +

    +

    +

    Типизация

    Typescript

    Typescript

    Typescript

    Typescript

    Typescript

    Популярность

    Соотношение звезд на GitHub и количества скачиваний за последний год, %

    0,99

    0,14

    2

    1,33

    Компонентный состав

    Есть компонент для работы с формами

    +

    +

    +

    Наличие встроенной валидации

    +

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

    Далее я расскажу, на какие факторы ориентировались мы в СберКорусе, и как было принято решение о создании своей библиотеки.

    Почему Korus-UI

    Может возникнуть вопрос: зачем нужна еще одна библиотека? На рынке уже существует большое количество библиотек компонентов React на любой вкус.

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

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

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

    На разработку библиотеки Korus-UI ушло 1,5 года. В процессе создания мы ориентировались на лучшие практики разработки opensource-библиотек. 

    Какие преимущества предоставляет Korus-UI

    Формы и валидация

    В Korus-UI подход к построению форм принципиально иной: поля и кнопка отправки формы связываются атрибутом form, в который передается строка с названием формы. Так элементы одной формы могут находиться в разных контейнерах, подключаться динамически, никакие общие обертки им не нужны. При этом создается объект формы, к которому можно получить доступ в обработчиках событий или с помощью метода  L.form(). Есть возможность передать кнопке массив из названий форм, чтобы валидировать и отправлять несколько форм одним кликом.

    У библиотеки Korus-UI удобный обработчик onValidationFail, который позволяет получить объект формы, не прошедшей валидацию. А еще есть приятный бонус — прокрутки к невалидным полям.

    Валидация в Korus-UI — это отдельный компонент. Его основные фичи:

    • Валидация поля функцией или RegExp

    • Готовые валидаторы

    • Один или несколько валидаторов для каждого поля со своими сообщениями

    • Настраиваемые сообщения (текст и внешний вид)

    • Задание валидности поля извне через атрибут isValid

    • Валидация компонентов в состоянии unmounted

    • Валидация полей по потере фокуса, сабмите формы и по событию в приложении

    • Прокрутка к невалидным полям при сабмите формы

    • Валидация нескольких форм одной кнопкой

    • Вспомогательные функции для валидации переданных значений

    Единообразный API

    Все компоненты поддерживают атрибуты, начинающиеся с нижнего подчеркивания _. Такие атрибуты будут преобразованы в имена css-классов:

     -> 

    Атрибут className также поддерживается.

    В каждый компонент можно передать атрибут theme, который содержит набор css-классов для элементов компонента.

    Все компоненты поддерживают атрибуты с суффиксом Render (см. раздел расширяемость).

    Поведение и структура события расширены, соблюдается единый стандарт для всех компонентов:

    {
      …Event, // оригинальное событие, сгенерированное React'ом
                    
      // событие расширено объектом component, которое содержит данные из компонента
      component: {
        isValid?: boolean, // признак валидности компонента, есть только в onBlur
        name?: string, // имя формы, к которой привязан компонент
        value: any, // значение компонента
        … // другие свойства объекта (см. API компонента)
      }
    }

    Названия атрибутов с булевыми значениями начинаются с:

    is: isOpen, isValid, isRequired, isDisabled

    has: hasCloseButton

    should: shouldCorrectValue

    Все компоненты поддерживают атрибут ref.

    Korus-UI расширяет механизм ref, принятый в React.

    Недостатки Korus-UI

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

    Еще можно отметить отсутствие поддержки мобильных платформ iOS и Android. Сейчас библиотека гарантирует поддержку только последних версий популярных браузеров. Подробная информация приведена в сравнительной таблице выше.

    Итоги

    Мы подробно рассмотрели основные критерии выбора библиотеки React-компонентов и проанализировали библиотеки Material-UI, Semantic-UI-React, arui-feather (Альфа Банк), yandex-ui, Korus-UI (СберКорус), опираясь на критерии качества. 

    Вот коротко то, что нужно учесть при выборе библиотеки:  

    • Собственные нужды и требования

    • Кастомизируемость

    • Расширяемость

    • Типизацию

    • Покрытие тестами

    • Наличие техподдержки

    • Документацию

    • Отзывы и активность сообщества библиотеки

    С учетом всех требований мы разработали собственную библиотеку Korus-UI, которая имеет все шансы стать достойным конкурентом существующим на рынке инструментам. Библиотека активно развивается, количество проектов, использующих Korus-UI в компании постоянно растет.

    В ближайшее время мы добавим новые компоненты. Также в планах расширение тестового покрытия, перевод на английский язык документации и актуализация Storybook.

    Библиотека  Korus-UI выложена в opensource и доступна на GitHub. Это первый шаг для нашей компании в opensource, и мы уверены, что не последний:)

    Отдельно хочу выразить благодарность команде разработчиков СберКоруса, отцу и идейному вдохновителю библиотеки Артёму Повольских. Если вам интересно, как устроена фронтенд-разработка в СберКорусе, читайте статью Артёма.

    Делитесь в комментариях своим опытом использования библиотек компонентов. Интересно обсудить, с какими преимуществами и недостатками вы сталкивались на личном опыте и какого функционала вам не хватает в процессе работы. 

    © Habrahabr.ru