Checkbox

Checkbox Row

Чекбокс, у которого мишень — вся строка с подписью и пояснением, а не квадратик в углу. Галка нарисована на CSS, состояние держит нативный input.

  • checkbox
  • form
  • settings
  • toggle

Превью

1440pxHost theme

Использовать с AI

  1. 1. Скопируйте ссылку.
  2. 2. Напишите агенту своими словами и вставьте её в предложение.
  3. 3. Агент откроет ссылку и поставит компонент из registry.

размести это в шапке: https://vibeui.ru/c/checkbox-001

Показать полную инструкцию

То, что лежит по ссылке в развёрнутом виде. Нужна, если агент не может открыть ссылку — тогда вставьте этот текст целиком.

# Установка и размещение «checkbox-001» (Checkbox Row) из VibeUI

## 1. Сначала установка — не пропускай, не пересоздавай
Выполни эту команду до того, как писать код:
npx shadcn@latest add https://vibeui.ru/r/checkbox-001.json

Registry item: https://vibeui.ru/r/checkbox-001.json
Ставится в: components/vibeui/checkbox-001.tsx (точный путь следует алиасам components.json этого проекта).
npm-зависимости: нет.
Registry-зависимости: нет.

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

## 2. Что это
Чекбокс, у которого мишень — вся строка с подписью и пояснением, а не квадратик в углу. Галка нарисована на CSS, состояние держит нативный input.

Чекбокс строкой: подпись, пояснение под ней и квадрат с галкой. Мишень — вся строка, потому что корень компонента это <label>. Галка рисуется двумя гранями и вырастает из нуля, подложка появляется на наведении. Внутри нативный input, поэтому клавиатура и форма работают сами. Ноль зависимостей, один файл, своя палитра.

## 3. Как использовать
import { Checkbox001 } from "@/components/vibeui/checkbox-001"

<Checkbox001
  name="reports"
  defaultChecked
  label="Присылать отчёты"
  description="Раз в неделю, коротким письмом."
/>

Полный список пропсов — в установленном файле.

## 4. Куда поставить
Это мелкий inline-компонент. Поставь его ровно туда, куда просил
пользователь, внутрь существующей разметки. Не создавай ради него
новую страницу, секцию или обёртку. Если на этом месте уже стоит похожий
контрол — замени его, а не добавляй второй.

Куда поставить: ___
(Эту строку заполняет пользователь. Если она осталась пустой — спроси,
а не угадывай.)

## 5. Сохранить как установлено
- локальную палитру --vibeui-checkbox-001-* и не подменять её токенами вашей темы (bg-primary, border-input, text-muted-foreground и подобными)
- корень-<label>: он и делает кликабельной всю строку, включая пояснение
- нативный input[type=checkbox] с appearance:none — состояние, клавиша пробел и отправка в форме держатся на нём
- галку из двух граней с поворотом на 45° и её рост из scale(0.4) при отметке
- outline focus-visible у квадрата: чекбокс переключают с клавиатуры
- отрицательные margin, компенсирующие padding строки: без них компонент выпирает относительно соседних полей формы
- пару правил на :has(input:disabled) — они гасят всю строку, а не только квадрат
- блок <style> внутри компонента — в нём вся палитра, геометрия и анимация галки

## 6. Можно менять
- тексты label и description; description можно не передавать — строка станет однострочной
- акцент через проп accent — цвет залитого квадрата и кольца фокуса
- любые нативные пропсы input: name, checked, defaultChecked, onChange, required, disabled, value
- внешние отступы и ширину через className
- порядок строк: несколько чекбоксов подряд ставятся без обёрток, между ними достаточно gap у родителя

## 7. Правила
- Не оборачивайте компонент в свой <label>: он уже внутри, вложенные label ломают клик.
- Смешанное состояние (indeterminate) не поддержано: это свойство DOM, его нельзя выставить разметкой. Нужен третий вид — берите отдельный компонент.
- Для группы чекбоксов оберните строки в <fieldset> с <legend>: у самой строки заголовка группы нет.
- Не выносите CSS-переменные в globals.css: компонент обязан оставаться одним файлом.

## 8. Проверка
- рендерится без ошибок в консоли;
- выглядит так же, как превью на странице VibeUI, откуда взята ссылка;
- если нет — ты изменил что-то из раздела 5, верни как было.

Для разработчика

npx shadcn@latest add https://vibeui.ru/r/checkbox-001.json
https://vibeui.ru/r/checkbox-001.json

Компонент самодостаточен: один файл, без зависимостей, собственная палитра в локальных переменных --vibeui-checkbox-001-*. Корень — <label>, поэтому кликается вся строка вместе с пояснением. Внутри нативный input[type=checkbox] с appearance:none: состояние, клавиатура и участие в форме остаются нативными. Галка — две грани квадрата, повёрнутые на 45°, и она вырастает из нуля при отметке; иконочная библиотека не нужна. Отрицательные margin компенсируют внутренние отступы строки, чтобы компонент не сдвигался относительно соседей.

Исходник компонента

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

import type { ComponentPropsWithoutRef, CSSProperties } from "react"

export type Checkbox001Props = Omit<
  ComponentPropsWithoutRef<"input">,
  "type" | "size"
> & {
  label?: string
  /** Пояснение под подписью. Кликается вместе с ней. */
  description?: string
  accent?: string
}

// Идея компонента: кликабельна вся строка, а не квадратик 16×16. Галка
// рисуется двумя гранями и появляется прочерком времени, а не картинкой:
// иконочная библиотека не нужна, состояние держит нативный input.
const STYLES = `
:where([data-vibeui-block="checkbox-001"]){
--vibeui-checkbox-001-surface:oklch(1 0 0);
--vibeui-checkbox-001-surface-border:oklch(0.91 0.006 265);
--vibeui-checkbox-001-fg:oklch(0.24 0.016 265);
--vibeui-checkbox-001-muted:oklch(0.54 0.014 265);
--vibeui-checkbox-001-bg:oklch(1 0 0);
--vibeui-checkbox-001-border:oklch(0.82 0.01 265);
--vibeui-checkbox-001-accent:oklch(0.55 0.2 262);
--vibeui-checkbox-001-mark:oklch(1 0 0);
--vibeui-checkbox-001-hover:oklch(0.55 0.02 265 / 7%);
--vibeui-checkbox-001-radius:0.625rem;
--vibeui-checkbox-001-font:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
}
/* Собственная подложка: подпись и пояснение — это текст, и на тёмной
   странице он обязан читаться без правки палитры проекта. */
[data-vibeui-block="checkbox-001"]{
box-sizing:border-box;padding:0.75rem 0.875rem;
background:var(--vibeui-checkbox-001-surface);
border:1px solid var(--vibeui-checkbox-001-surface-border);border-radius:0.875rem;
display:flex;align-items:flex-start;gap:0.6875rem;
padding:0.625rem 0.75rem;margin:-0.625rem -0.75rem;
border-radius:var(--vibeui-checkbox-001-radius);cursor:pointer;
font-family:var(--vibeui-checkbox-001-font);color:var(--vibeui-checkbox-001-fg);
transition:background-color .16s ease;
}
[data-vibeui-block="checkbox-001"]:hover:not(:has(input:disabled)){background:var(--vibeui-checkbox-001-hover)}
[data-vibeui-block="checkbox-001"]:has(input:disabled){cursor:not-allowed;opacity:.55}
[data-vibeui-block="checkbox-001"] input{
appearance:none;-webkit-appearance:none;
flex:none;margin:0.0625rem 0 0;width:1.125rem;height:1.125rem;
border:1.5px solid var(--vibeui-checkbox-001-border);border-radius:0.375rem;
background:var(--vibeui-checkbox-001-bg);cursor:inherit;
transition:background-color .16s ease,border-color .16s ease;
}
[data-vibeui-block="checkbox-001"] input:checked{
background:var(--vibeui-checkbox-001-accent);
border-color:var(--vibeui-checkbox-001-accent);
}
[data-vibeui-block="checkbox-001"] input:focus-visible{
outline:2px solid var(--vibeui-checkbox-001-accent);outline-offset:2px;
}
[data-vibeui-block="checkbox-001"] [data-part="box"]{position:relative;display:flex;flex:none}
/* Галка — две грани квадрата, повёрнутые на 45°; растёт из нуля при отметке. */
[data-vibeui-block="checkbox-001"] [data-part="mark"]{
position:absolute;left:0.375rem;top:0.1875rem;
width:0.3125rem;height:0.5625rem;pointer-events:none;
border-right:2px solid var(--vibeui-checkbox-001-mark);
border-bottom:2px solid var(--vibeui-checkbox-001-mark);
transform:rotate(45deg) scale(0.4);transform-origin:center;
opacity:0;transition:opacity .14s ease,transform .14s ease;
}
[data-vibeui-block="checkbox-001"] input:checked + [data-part="mark"]{opacity:1;transform:rotate(45deg) scale(1)}
[data-vibeui-block="checkbox-001"] [data-part="text"]{display:flex;flex-direction:column;gap:0.125rem}
[data-vibeui-block="checkbox-001"] [data-part="title"]{font-size:0.9375rem;line-height:1.35}
[data-vibeui-block="checkbox-001"] [data-part="description"]{font-size:0.8125rem;line-height:1.4;color:var(--vibeui-checkbox-001-muted)}
@media (prefers-reduced-motion:reduce){[data-vibeui-block="checkbox-001"] *{animation:none!important;transition:none!important}}
`

/**
 * Чекбокс со строкой-мишенью: подпись, пояснение и галка на чистом CSS.
 * Один файл, ноль зависимостей, собственная палитра.
 */
export function Checkbox001({
  label = "Присылать отчёты",
  description = "Раз в неделю, коротким письмом. Отключается в любой момент.",
  accent,
  className,
  style,
  ...props
}: Checkbox001Props) {
  const palette = {
    ...(accent ? { "--vibeui-checkbox-001-accent": accent } : null),
    ...style,
  } as CSSProperties

  return (
    <>
      <style href="vibeui-checkbox-001" precedence="medium">
        {STYLES}
      </style>
      <label
        data-vibeui-block="checkbox-001"
        className={className}
        style={palette}
      >
        <span data-part="box">
          <input {...props} type="checkbox" />
          <span data-part="mark" aria-hidden="true" />
        </span>
        <span data-part="text">
          <span data-part="title">{label}</span>
          {description ? (
            <span data-part="description">{description}</span>
          ) : null}
        </span>
      </label>
    </>
  )
}