CBtn
Кнопка. Два варианта отрисовки, окраска через утилитарные классы платформы, состояние загрузки со слотом-лоадером и полная поддержка системы пресетов.
Базовое использование
Обычная кнопка эмитит click, disabled отключает её нативно, block растягивает на всю ширину контейнера.
Показать код
<template>
<c-btn @click="count++">Click me</c-btn>
<c-btn disabled>Disabled</c-btn>
<c-btn block @click="count++">Block button</c-btn>
</template>Варианты
variant переключает отрисовку: flat (по умолчанию) — залитая кнопка, outlined — прозрачная с рамкой. У outlined рамка рисуется currentColor, поэтому всегда совпадает с цветом текста.
Показать код
<c-btn>Flat</c-btn> <c-btn variant="outlined">Outlined</c-btn>Цвет
color принимает любой цвет платформы — предопределённого набора нет:
- палитровый токен —
red-darken-1,teal,deep-purple-lighten-1— превращается в статическую утилиту (bg-teal); - сырое CSS-значение —
#7C4DFF,rgb(0,150,136),var(--my-color)— превращается в arbitrary-класс (bg-[#7C4DFF]), который генерирует utils-jit.
Куда ложится цвет, решает вариант: у flat это фон, у outlined — текст и рамка (через currentColor).
Показать код
<c-btn color="red-darken-1">red-darken-1</c-btn>
<c-btn color="teal">teal</c-btn>
<c-btn color="#7C4DFF">#7C4DFF</c-btn>
<c-btn color="rgb(0,150,136)">rgb(0,150,136)</c-btn>
<c-btn variant="outlined" color="red-darken-1">outlined red</c-btn>
<c-btn variant="outlined" color="#7C4DFF">outlined #7C4DFF</c-btn>Сырой цвет должен быть литералом
Arbitrary-классы генерируются статическим сканом исходников: color="#7C4DFF" и :color="'#7C4DFF'" сработают, а :color="someVar" с сырым значением — нет. Палитровых токенов это не касается — их классы всегда есть в CSS. Подробнее — в Custom attrs.
Цвет текста у залитой кнопки остаётся on-primary (белый). Если фон требует тёмного текста — добавьте text-* класс:
<c-btn color="amber-lighten-3" class="text-black">Light button</c-btn>Загрузка
loading показывает лоадер вместо лейбла (размеры кнопки сохраняются), ставит aria-busy и глушит click. Дефолтный лоадер — CProgressCircular, слот loader заменяет его на что угодно.
Показать код
<template>
<c-btn :loading="loading" @click="submit">Submit</c-btn>
<c-btn :loading="loading" color="teal" @click="submit">
Custom loader
<template #loader>
<span>Saving…</span>
</template>
</c-btn>
</template>Пресеты
CBtn поддерживает систему пресетов. Зоны: root (кнопка), label (лейбл), loader (контейнер лоадера). Состояния: disabled, loading, active, focused. В каждый момент работает ровно один пресет состояния (если он задан) — его зоны подменяют одноимённые зоны base.
Показать код
// main.ts — пресет регистрируется один раз
createVuelandUI({
presets: {
button: {
save: {
base: { root: ['bg-indigo', 'hover:bg-indigo-darken-1', 'text-white', 'elevation-2'] },
active: { root: ['bg-indigo-darken-2', 'text-white', 'elevation-0'] },
loading: { root: ['bg-indigo-lighten-2', 'text-white', 'elevation-0'] },
disabled: { root: ['bg-grey-lighten-1', 'text-grey-darken-1'] },
},
},
},
})<template>
<c-btn preset="button.save" :loading="loading" :disabled="disabled" @click="save"> Save </c-btn>
</template>Пресет и color вместе
Оба механизма делают одно и то же — добавляют утилитарные классы на зоны кнопки. Они аддитивны и хорошо сочетаются, пока отвечают за разное: в примере ниже пресет задаёт форму, отступы и тень, а цвет каждой кнопки — проп color.
Показать код
createVuelandUI({
presets: {
button: {
pill: {
base: { root: ['radius-16', 'px-6', 'text-uppercase', 'elevation-3'] },
},
},
},
})<c-btn preset="button.pill" color="teal">teal</c-btn>
<c-btn preset="button.pill" color="red-darken-1">red</c-btn>
<c-btn preset="button.pill" color="#7C4DFF">#7C4DFF</c-btn>Не задавайте один аспект дважды
Если и пресет, и color красят одно и то же свойство одной зоны (например, оба ставят bg-* на корень), победителя определяет не порядок в шаблоне, а порядок правил в подключённом CSS: все утилиты равны по специфичности и оба с !important. На практике arbitrary-классы (bg-[#7C4DFF]) обычно подключаются после статических утилит и перекрывают их, но это деталь порядка импортов, а не контракт.
Правило простое: цвет живёт либо в пресете (системное решение с состояниями), либо в color (точечная окраска конкретной кнопки). Пресету при этом остаются форма, тень, типографика и поведение состояний.
Доступность
Рендерится нативный <button>: клавиатура и фокус работают из коробки. В состоянии loading ставится aria-busy="true", а click не эмитится. disabled использует нативный атрибут.
По умолчанию кнопка рендерится с type="button" — внутри формы она не триггерит submit. Для сабмит-кнопки передайте атрибут явно:
<c-form @submit="onSubmit">
<c-btn type="submit">Отправить</c-btn>
</c-form>API
Props
variant'flat' | 'outlined''flat'colorstringred-darken-1) или сырой цвет (#7C4DFF, rgb(...), var(...))blockbooleanfalsedisabledbooleanfalsedisabled)loadingbooleanfalseclick, ставит aria-busypresetstringSlots
defaultloaderCProgressCircular) при loadingEvents
click(e: MouseEvent)loadingCSS-переменные
--c-btn-bg-colorvar(--c-sys-color-primary)--c-btn-text-colorvar(--c-sys-color-on-primary)--c-btn-loader-colorvar(--c-sys-color-on-primary)--c-btn-container-colorvar(--c-sys-color-primary-container)--c-btn-on-container-colorvar(--c-sys-color-on-primary-container)--c-btn-border-colorcurrentColor--c-btn-border-widthvar(--c-sys-border-width-thin)--c-btn-border-radiusvar(--c-sys-shape-md)--c-btn-hover-bg-colorcurrentColor--c-btn-focus-bg-colorvar(--c-sys-state-focus-color)--c-btn-pressed-bg-colorcurrentColor--c-btn-transition-duration.3s--c-btn-disabled-text-colorvar(--c-sys-color-disabled)--c-btn-disabled-bg-colorvar(--c-sys-color-disabled-container)--c-btn-disabled-opacityvar(--c-sys-state-disabled-opacity)--c-btn-paddingsvar(--c-sys-space-2) var(--c-sys-space-3)--c-btn-min-width80px--c-btn-min-heightvar(--c-sys-control-height-sm)--c-btn-font-sizevar(--c-sys-typography-body-size)Hover/pressed-оверлеи рисуются псевдоэлементом поверх фона: currentColor с небольшой прозрачностью, поэтому подсветка состояний автоматически подстраивается под цвет кнопки.
