Заканчиваются рабочие дни уходящего года, а значит, самое время подводить итоги наших трудов. За 2023 год у проекта Taiga UI появилось более пятидесяти релизов, больше двух тысяч вмерженных PR-ов и свыше пятисот закрытых issue.
Taiga UI — это огромный Angular UI Kit, который активно используется в сотне продуктов компании Тинькофф и популярен за ее пределами. Разработка проекта много лет идет в Open Source, собирая свою аудиторию по всему миру.
Продолжу ежегодную традицию и напомню пользователям библиотек о самых интересных изменениях за последний год.
Больше трех лет в Open Source
Вопреки всем трудностям развития отечественного Open Source, мы не отказываемся от публичного развития нашего продукта.
Нам важно, чтобы пользователи всегда могли изучить открытый исходный код и самостоятельно внести в него правки с улучшениями продукта. В 2023 году больше 20 внешних контрибьюторов принесли нам PR-ы разного уровня сложности: от небольших корректировок документации до починки серьезных багов или даже целых крупных фич. Например, BreakpointService или декларативный роутинг диалогов.
Суммарно за три года в Open Source количество контрибьюторов превысило отметку в полторы сотни человек! Мы никогда не устанем повторять, что очень ценим их вклад и рады любым улучшениям ❤️
Этим летом произошло важное изменение в истории Taiga UI. Она стала чем-то большим, чем просто UI Kit. Теперь Taiga UI — часть целого семейства продуктов, объединенных под общим названием Taiga Family.
Мы переехали в отдельную Github-организацию, в которой собрали лучшие технические наработки, используемые для развития Taiga UI: ng‑web‑apis, maskito, ng‑polymorpheus, ng‑morph, ng‑event‑plugins и другие. Среди них вы наверняка найдете что-нибудь полезное для вашего Angular-приложения или библиотеки. А подробнее про каждый продукт писал мой коллега:
Нам приятно, что публичность Taiga UI растет. За 2023 год мы стали популярнее на гитхабе в виде звезд на 17%, а количество скачиваний через npm превысило 350 тысяч. Для сравнения, в 2022 году это значение было чуть менее 200 тысяч.
Новая маска для текстовых полей
В конце 2022 года произошло знаменательное событие, наметив крупную задачу для нас в 2023-м. В бэклоге Taiga UI несколько лет висела задача по поиску альтернативы используемой библиотеки по маскированию текстовых полей. После многочисленных исследований и обсуждений наша команда разработала собственную библиотеку для этих целей — Maskito.
В начале этого лета вышел первый стабильный мажорный релиз. К тому моменту Maskito была уже не просто одиночной библиотекой, а целой коллекцией. Новая разработка включала в себя фреймворк‑агностик пакет @maskito/core, опциональный пакет @maskito/kit
с набором готовых и конфигурируемых масок, а еще отдельные пакеты под популярные JS-фреймворки React, Angular и Vue.
Если вам интересно узнать подробнее про историю развития Maskito и посмотреть все преимущества в действии, то я писал об этом раньше. Заходите почитать:
Мы до последнего сомневались, получилось ли у нас разработать гибкий и удобный инструмент, который бы избежал ошибок своих предшественников. Положительная реакция сообщества развеяла наши опасения.
21 июня широко используемый фреймворк Ionic выпустил анонс, в котором назвал Maskito официальной рекомендацией для работы с маской в их компонентах. И теперь на странице документации Ionic вы всегда сможете найти инструкцию по использованию Maskito внутри вашего Ionic-приложения.
Сообщество проявляло интерес к новому продукту, и к концу года количество суммарных скачиваний на npm превысило отметку в 300 тысяч. Особенно порадовало, что Maskito взял на вооружение даже крупный энтерпрайз. Известно, например, что Тинькофф стал не единственным российским банком, в дизайн-системе которого начали применять Maskito для маскирования текстовых полей. Надеемся, что список компаний будет только расти!
Мы полностью пересадили все маскированные текстовые поля из библиотеки Taiga UI на новую маску и решили много накопившихся проблем. Но мы не планируем на этом останавливаться! У Maskito еще есть точки роста, и мы будем ее развивать. Уже совсем скоро ждите второй мажорный релиз!
InputPhoneInternational и @maskito/phone
Есть у нас один замечательный компонент, который можно дорабатывать бесконечно. Как бы мы ни старались, сколько бы часов на его проектирование ни потратили — правки рано или поздно все равно появятся. Имя ему — InputPhoneInternational.
Дело тут не в нашей лени или миграции рук в другие места. Дело в том, что этот компонент представляет собой замаскированное текстовое поле для ввода международных телефонных номеров. А паттерны международных телефонных номеров имеют свойства меняться и дополняться в течение всей своей истории.
Долгое время маски с форматом телефонных номеров разных стран мы хранили как константу в репозитории. Разумеется, актуализация этой константы не всегда происходила своевременно и доставляла много хлопот. Но, к счастью, нас спасало главное преимущество Open Source — баг-репорты от сообщества. Было заведено немало issue в таком духе #3102.
Нам не нравилось постоянно актуализировать форматы телефонных номеров и хотелось переложить ответственность на кого-то другого. Мы нашли крайнего — Google. У компании есть библиотека libphonenumber
, которая хранит в себе паттерны телефонных номеров всех стран мира, и они всегда в актуальном состоянии! Мы сразу поняли — это то, что нам нужно.
К сожалению, все оказалось не так просто. Перед началом использования нужно было совладать с огромным объемом данных — их формат совсем не подходил под то, чтобы с легкостью использовать данные для построения маски текстового поля. Тогда мы создали дополнительный пакет @maskito/phone, который на базе Maskito и пакета libphonenumber‑js (JavaScript-порт гугловской библиотеки) предоставит удобный API, чтобы в пару строк создать замаскированное текстовое поле для телефонного номера любой страны.
В сентябре 2023 года разработка пакета завершилась и состоялся первый релиз. Пакет получился удобным и гибким в использовании. Например, пользователь библиотеки способен регулировать размер бандла, выбирая разные наборы с метадатой (max
, min
или mobile
). Подробнее обо всех фичах нового пакета можно прочесть в нашей документации.
Совсем скоро в релизе Taiga UI 4.0.0 новый пакет @maskito/phone
станет частью компонента InputPhoneInternational
, навсегда закрывая заботы по актуализации международных телефонных номеров. Нашему пользователю будет достаточно поднимать версию библиотеки libphonenumber-js
.
Нативные контролы мобильных устройств
Еще в конце 2022 года мы решили внедрить возможность использования системных мобильных контролов на некоторых наших компонентах-инпутах. Например, нативные выпадающие списки или календари.
Первой такая фича появилась для компонента Select в октябре 2022. А в 2023 году такая фича зарелизилась уже у целого списка наших компонентов: MultiSelect, InputDate, InputTime, InputDateTime, InputMonth. Публичный API новых возможностей может различаться у компонентов, но суть внутри одинаковая: десктопное представление компонента использует стилизованные тайговые контролы, а мобильная версия подключает нативные инструменты системы. Разные мобильные платформы будут стилизовать контролы под собственный стиль.
Покажу, что собой представляет новая фича, на примере. Если открыть его на компьютере, то окажется, что InputDate
при фокусе распахивает стилизованный тайговый календарь.
Но если этот же пример открыть с реального мобильного устройства, то при клике на иконку календаря текстовое поле откроет нативный календарь в стиле операционной системы устройства.
Нативные контролы имеют ряд преимуществ, которых никакими усилиями не получится достичь у кастомных аналогов. Например, нативные календари и выпадающие списки способны выходить за границы окна браузера, что может быть полезно на маленьких мобильных устройствах. Еще такой нативный контрол будет автоматически стилизоваться под разные операционные системы, что гармонично сочетается с общим дизайном устройства и выглядит привычным в глазах пользователя.
Если пренебречь всеми техническими преимуществами, есть еще один смысловой пункт о важности данной фичи. В разработке продуктов иногда присутствует такой хак, когда бизнес в качестве временного решения откладывает разработку полноценного iOS- или Android-приложения для своего продукта, а использует готовую версию веб-приложения, которую упаковывает внутрь оболочки мобильного приложения. В рамках этой статьи не будем обсуждать, насколько вебвью хорошо или плохо. Отмечу только, что грамотное использование такого подхода подразумевает, что веб-версия сайта должна хорошо мимикрировать под нативное мобильное приложение. Оно должно вести себя так же и так же выглядеть. Использование нативных мобильных контролов может быть неплохим решением в рамках такого подхода, хотя при этом на десктопе компонент сохраняет свое особенное поведение.
Инструкция по подключению фичи делится на две группы:
Для текстовых полей с вводом дат, времени и месяца это происходит через DI-конфигурацию:
import {tuiInputDateOptionsProvider} from '@taiga-ui/kit';
// ...
providers: [tuiInputDateOptionsProvider({nativePicker: true})]
Для компонентов с выбором элементов из выпадающего списка достаточно внутрь уже привычных тегов <tui‑select />
/ <tui‑multi‑select />
вложить нативный тег <select />
, дополненный атрибутом tuiSelect
. А дальше кодовая база сделает всю нужную магию самостоятельно.
<tui-select [formControl]="control">
Character
<select
tuiSelect
[items]="items"
></select>
</tui-select>
Editor: еще больше фич
Долгое время компонент Editor
развивался внутри монорепозитория с прочими пакетами Taiga UI и имел лишь одну страничку с документацией. Но со временем этому компоненту становилось тесновато. Да и язык уже не поворачивался называть наш огромный редактор просто «компонентом». Настало время ему покинуть родительское гнездышко и пуститься в свободный полет…
С июня Editor
живет в отдельном репозитории, со своей отдельной документацией и отвязанным версионированием от остальных пакетов Тайги. Теперь это пакет @tinkoff/tui‑editor
.
В 2023 году наш редактор обзавелся новыми интересными фичами: у него есть поддержка нативных audio/video‑тегов, а внутрь редактора можно встроить целый YouTube‑плеер или даже регулируемый по ширине Iframe c любым содержимым внутри. И, разумеется, мы не планируем на этом останавливаться — и продолжим развивать редактор дальше!
Еще больше компонентов и новый пакет @taiga-ui/experimental
До недавних пор при развитии Taiga UI мы стремились фокусироваться на конструировании атомарных компонентов, стараясь избегать сложных организмов. Но на фоне массовых блокировок нативных приложений в сторах резко возрос спрос на веб-приложения, а особенно на их мобильное представление или вовсе полноценные PWA. Стало крайне важно создавать качественные веб-приложения в сжатые сроки. На фоне новых тенденций мы отошли от своих старых правил и начали подготавливать готовые популярные «мини-организмы» (или, как мы называем их в команде, layout-компоненты).
Так появились на свет компоненты TabBar и AppBar, которые реализуют популярный паттерн мобильных приложений для навигации между разделами.
Еще мы создали компонент BlockStatus, который упрощает создание страниц состояний. Например, для создания знаменитой 404-страницы, существующей почти в каждом приложении. А осенью 2023 года пакет @taiga-ui/experimental
пополнился множеством других полезных layout-компонентов: Card, Cell, Title и Surface.
@taiga-ui/experimental
— это пакет с компонентами, которые еще не имеют строго зафиксированного публичного API, он может меняться, игнорируя правила версионирования. В ближайшем мажорном релизе эти компоненты переезжают в стабильные пакеты, их публичный API фиксируется и начинает следовать семантическому версионированию.
Новые layout-компоненты в @taiga-ui/experimental
— не единственные новинки этого пакета. В нем есть множество обновленных и улучшенных версий старых компонентов — и даже кое-что совершенно новое.
Например, обновленные Checkbox, Radio и Toggle. Новые версии стали атрибутными компонентами и теперь навешиваются напрямую на нативные <input />
. В ближайшем мажорном релизе из верстки исчезнет <tui-checkbox />
, и ему на смену придет <input tuiCheckbox type="checkbox" />
. То есть в новой версии компонента будет полный доступ ко всем нативным атрибутам инпута, легковесность компонента и более чистая верстка. Это получилось благодаря CSS-свойству mask! А еще новые версии компонентов всего лишь в одну строчку кода позволяют опционально застилизовать компоненты так, чтобы они выглядели идентично аналогичным системным iOS- или Android-контроллерам.
Появился компонент Sensitive, который скрывает часть контента от пользователя. Например, в приложениях Тинькофф такая фича активно применяется, чтобы пользователь мог спрятать свои чувствительные данные — значение баланса или банковского счета, — когда делает запись экрана или показывает что-то лично своим знакомым. Секрет успеха компонента опять же в CSS-маске.
Многоточие в конце — популярный способ отображать переполнение текста. Если такой вариант наскучил, есть новый — компонент Fade. Угадайте, как удается достичь такого эффекта? Правильно, опять тут не обошлось без уже знакомой нам CSS-маски!
Устали от упоминаний CSS-маски? А это только начало! В 2023 году свойство стало одним из главных спонсоров пакета @taiga-ui/experimental
. С помощью одного лишь этого свойства мы обновили версию компонента ProgressSegmented, наложив маску поверх компонента ProgressBar.
Глубокое погружение в технические тонкости реализации стольких вещей с использованием одной и той же CSS-маски заслуживает отдельной статьи. Если у нашей команды будут силы и время, а у читателей — интерес, то мы обязательно подготовим ее со всеми деталями!
Маска сыграла значимую роль и в обновленной версии компонента Button. Пересмотр архитектуры новых кнопок позволил облегчить кодовую базу компонента и сохранить прошлую функциональность.
Последний по счету, но не по значимости, новый компонент для работы с иконками — Icon. Он отображает иконки через CSS-маску, что открывает новые горизонты:
Возможность хранить иконки на CDN и отображать их без манипуляций с DOM и санитайзера.
Упрощенный способ масштабирования иконок. Достаточно менять размеры хоста компонента — иконка масштабируется автоматически, а свойство vector‑effect="non‑scaling‑stroke" позволит реализовать это масштабирование без потери деталей и ненужного уменьшения/увеличения толщины линий.
Браузер автоматически реализует кэширование иконок.
Все это позволяет нам «отправить на пенсию» значительную часть кодовой базы, упростив работу с Taiga UI.
Грядущий релиз 4.0.0. Taiga Renaissance
С последнего мажорного релиза Тайги уже прошло больше года. Мы долгое время не поднимали версию Angular, чтобы подольше сохранять совместимость для ваших проектов на старых версиях фреймворка. Мы долгое время не вносили ломающих изменений, чтобы вы могли безболезненно обновляться до свежих версий наших пакетов. И долгое время продолжали поддерживать некоторые чересчур древние браузеры.
Это дается нелегко и порой не идет на пользу нашей кодовой базе, а значит, и качеству библиотек. Поэтому команда Тайги сейчас активно обсуждает идею по увеличению частотности мажорных релизов и желание приблизить поддержку минимальной версии Angular в наших библиотеках к тем же циклам, которые заявляет core-команда фреймворка.
А пока в начале 2024 года зреет новый — четвертый — мажорный релиз Тайги. Мы обновим минимальные версии поддержки браузеров, начнем использовать больше современных браузерных фич, а значит, наши библиотеки станут еще легче и еще надежнее. Мы обновим Angular до 15-й версии, и нам наконец-то откроются возможности по внедрению standalone‑компонентов и Directive Composition API. Мы зафиксируем публичное API наших новых экспериментальных компонентов и сделаем их частью других стабильных пакетов.
Подготовку к предстоящему релизу вы можете начинать уже сейчас: поднимите Angular в своем приложении минимум до 15+ и обновите Тайгу до актуальной версии. А дальше наши схематики возьмут большую часть забот на себя!
Если все приготовления уже завершены, то самое время сделать себе чашку какао с маршмеллоу, сесть в мягкое кресло напротив украшенной елки и в полной мере окунуться в новогоднее настроение. Команда Taiga UI поздравляет всех с наступающим Новым годом!