@application-kit/ui
Vue-обёртки над UI-вендором, мост токенов оформления (--p-* → --ui-*) и помощники спеков.
Пакет не знает ни одного имени иконки и feature-flag'а продукта: их приложение передаёт при установке плагина.
Тексты обёрток и локаль вендора для ru и en — в пакете, приложение может их переопределить.
import { UiVendorPlugin } from '@application-kit/ui'
import '@application-kit/ui/style.css'
app.use(new UiVendorPlugin({
darkModeSelector: 'dark-theme',
describeRequestError: (error, fallbackMessage, messages) => describe(error, fallbackMessage, i18n.global.t, messages),
iconClass: (name) => `app-icon app-icon--${name}`,
locale: { reference: (vue) => localeRef },
}))
Все три обязательные опции (darkModeSelector, describeRequestError, iconClass) проверяются
типом и при создании плагина: без них конструктор бросает ошибку на старте приложения.
Тексты и локаль
Без опции messages обёртки берут DEFAULT_UI_MESSAGES по локали из locale.reference; неизвестная локаль и
приложение без locale получают английские. Переданная messages заменяет их целиком, для другого языка или одной
фразы её удобно собрать из пакетных:
messages: () => ({ ...defaultUiMessages(localeRef.value), table: { ...defaultUiMessages(localeRef.value).table, empty: '—' } })
Подписи самого вендора (календарь, кнопки подтверждения) для ru тоже в пакете; locale.overrides перекрывает их
поштучно: { reference, overrides: { ru: { accept: 'Ок' } } }.
Тёмная тема
useDarkMode() отдаёт { isDark, toggle }. Источник правды — класс darkModeSelector на <html>, состояние одно на
приложение. Класс читается при монтировании, поэтому первый рендер (сервер и гидрация) идёт со светлой темой.
LayoutTopbarThemeSwitcher — готовая кнопка темы для слота действий топбара. У иконочных кнопок топбара (LayoutTopbarIconButton,
LayoutTopbarSubmenu) label обязателен: это доступное имя кнопки, а не видимая подпись.
Ошибка запроса
globalErrorToast.show(messageKey, supportId)— страховочный тост для кода вне setup-контекста (транспортный слой).messageKey— ключ словаря приложения,null— общий текстrequestError.unexpected. До подключения ошибки копятся.useGlobalErrorToastConnection(translate)— подключение в корневом компоненте, при монтировании.withSupportId(message, supportId, supportIdLine)— формат «текст + код обращения», общий сdescribeRequestErrorприложения.useErrorStore()— факт ошибки рендера и код обращения для страницы ошибки.
Имена иконок
Реестр пустой — приложение расширяет его своими именами, и без этого ни одна иконка не компилируется:
declare module '@application-kit/ui' {
interface UiIconRegistryInterface { refresh: true }
}
Входы
.— компоненты, composables (действия с флагом ожидания —useAsyncAction,useOptimisticRowActions: текст отказа собираетdescribeRequestErrorприложения, ключи сообщений — параметром),UiVendorPlugin, листинговые сторы, типы;/testing—installVendorPlugins,submitForm, заглушки браузерных API для jsdom, гейт токенов продуктаassertTokensDeclared({ sourceRoot });/lint— данные вендора для ESLint потребителя без Vue и стилей: шаблоны импорта и CSS-класса, подпути вендора, имена обёрток полей дляlabel-has-for(их собирает@application-kit/lint-config);/style.css— стили компонентов и их анимации (подключить один раз);/styles/tokens.scss— мост токенов: приложение сверяет по нему своиvar(--ui-*);/styles/base.scss— база документа: reset, корневые стилиhtml/body, типографика;/styles/icons.scss— миксиныboxиmaskдля своих иконок приложения, без вывода CSS;/styles/variables.scss— масштаб, брейкпойнт и шрифт для стилей приложения.
Порядок стилей
Глобальная таблица приложения подключает мост токенов первым и один раз, за ним — базу, затем своё:
база читает --ui-* и должна стоять раньше правил приложения, которые её переопределяют.
@use "@application-kit/ui/styles/tokens";
@use "@application-kit/ui/styles/base";
// дальше — шрифты и иконки продукта
style.css от этой таблицы не зависит: правила компонентов сильнее элементных селекторов базы.
Peer-зависимости
vue, pinia, vue-router, openvue — по одному экземпляру на приложение; vitest нужен только для /testing.