Skip to content

CBtn

Кнопка. Два варианта отрисовки, окраска через утилитарные классы платформы, состояние загрузки со слотом-лоадером и полная поддержка системы пресетов.

Базовое использование

Обычная кнопка эмитит click, disabled отключает её нативно, block растягивает на всю ширину контейнера.

Clicks: 0
Показать код
vue
<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, поэтому всегда совпадает с цветом текста.

Показать код
html
<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).

Показать код
html
<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-* класс:

html
<c-btn color="amber-lighten-3" class="text-black">Light button</c-btn>

Загрузка

loading показывает лоадер вместо лейбла (размеры кнопки сохраняются), ставит aria-busy и глушит click. Дефолтный лоадер — CProgressCircular, слот loader заменяет его на что угодно.

Показать код
vue
<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.

Показать код
ts
// 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'] },
      },
    },
  },
})
vue
<template>
  <c-btn preset="button.save" :loading="loading" :disabled="disabled" @click="save"> Save </c-btn>
</template>

Пресет и color вместе

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

Показать код
ts
createVuelandUI({
  presets: {
    button: {
      pill: {
        base: { root: ['radius-16', 'px-6', 'text-uppercase', 'elevation-3'] },
      },
    },
  },
})
html
<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. Для сабмит-кнопки передайте атрибут явно:

html
<c-form @submit="onSubmit">
  <c-btn type="submit">Отправить</c-btn>
</c-form>

API

Props

Проп
Тип
По умолчанию
Описание
variant
'flat' | 'outlined'
'flat'
Вариант отрисовки
color
string
Палитровый токен (red-darken-1) или сырой цвет (#7C4DFF, rgb(...), var(...))
block
boolean
false
Кнопка на всю ширину контейнера
disabled
boolean
false
Отключает кнопку (нативный disabled)
loading
boolean
false
Показывает лоадер, глушит click, ставит aria-busy
preset
string
Имя пресета (путь через точку) из реестра

Slots

Слот
Описание
default
Содержимое кнопки (лейбл)
loader
Замена дефолтного лоадера (CProgressCircular) при loading

Events

Событие
Аргументы
Описание
click
(e: MouseEvent)
Клик по кнопке; не эмитится при loading

CSS-переменные

Переменная
По умолчанию
--c-btn-bg-color
var(--c-sys-color-primary)
--c-btn-text-color
var(--c-sys-color-on-primary)
--c-btn-loader-color
var(--c-sys-color-on-primary)
--c-btn-container-color
var(--c-sys-color-primary-container)
--c-btn-on-container-color
var(--c-sys-color-on-primary-container)
--c-btn-border-color
currentColor
--c-btn-border-width
var(--c-sys-border-width-thin)
--c-btn-border-radius
var(--c-sys-shape-md)
--c-btn-hover-bg-color
currentColor
--c-btn-focus-bg-color
var(--c-sys-state-focus-color)
--c-btn-pressed-bg-color
currentColor
--c-btn-transition-duration
.3s
--c-btn-disabled-text-color
var(--c-sys-color-disabled)
--c-btn-disabled-bg-color
var(--c-sys-color-disabled-container)
--c-btn-disabled-opacity
var(--c-sys-state-disabled-opacity)
--c-btn-paddings
var(--c-sys-space-2) var(--c-sys-space-3)
--c-btn-min-width
80px
--c-btn-min-height
var(--c-sys-control-height-sm)
--c-btn-font-size
var(--c-sys-typography-body-size)

Hover/pressed-оверлеи рисуются псевдоэлементом поверх фона: currentColor с небольшой прозрачностью, поэтому подсветка состояний автоматически подстраивается под цвет кнопки.