HextaUI

Checkbox

İşareti çizilerek beliren, belirsiz üst öğeleri, grupları ve hover durumunu paylaşan etiketleri olan bir onay kutusu.

import { Checkbox } from "@/components/ui/checkbox"

export function CheckboxDemo() {
  return (
    <div className="flex flex-col gap-3">
      <label className="flex items-center gap-3 text-sm">
        <Checkbox />
        Email me about product updates
      </label>
      <label className="flex items-center gap-3 text-sm">
        <Checkbox defaultChecked />
        Remember this device
      </label>
      <label className="flex max-w-sm items-start gap-3 text-sm">
        <span className="flex h-5 items-center">
          <Checkbox />
        </span>
        <span className="flex flex-col gap-0.5">
          <span className="leading-5 font-medium">Mentions and replies</span>
          <span className="text-muted-foreground">
            We’ll only notify you about activity on your own posts.
          </span>
        </span>
      </label>
    </div>
  )
}
pnpm dlx shadcn@latest add https://hextaui.com/r/checkbox.json

Bileşeni, HextaUI tema token'larını ve bileşenin bağımlı olduğu tüm HextaUI bileşenlerini ekler.

import { Checkbox, CheckboxGroup } from "@/components/ui/checkbox"
<label className="flex items-center gap-3">
  <Checkbox defaultChecked />
  Remember this device
</label>
CheckboxGroup
└── Checkbox

Durumlar

disabled, readOnly, indeterminate ve aria-invalid. Salt okunur bir kutu değerini korur ve odaklanabilir kalır, ancak tıklamaları ve tuşları yok sayar.

import { Checkbox } from "@/components/ui/checkbox"

export function CheckboxStates() {
  return (
    <div className="flex flex-col gap-3 text-sm">
      <label className="flex items-center gap-3">
        <Checkbox disabled />
        Disabled
      </label>
      <label className="flex items-center gap-3">
        <Checkbox disabled defaultChecked />
        Disabled and checked
      </label>
      <label className="flex items-center gap-3">
        <Checkbox readOnly defaultChecked />
        Read-only
      </label>
      <label className="flex items-center gap-3">
        <Checkbox indeterminate />
        Indeterminate
      </label>
      <label className="flex items-center gap-3">
        <Checkbox aria-invalid />
        Invalid
      </label>
      <label className="flex items-center gap-3">
        <Checkbox aria-invalid defaultChecked />
        Invalid and checked
      </label>
    </div>
  )
}

Tümünü seç

Bir <CheckboxGroup /> içinde, parent olan bir checkbox allValues içindeki her değeri işaretler. Yalnızca bazıları işaretliyken belirsiz (indeterminate) olur.

"use client"

import * as React from "react"

import { Checkbox, CheckboxGroup } from "@/components/ui/checkbox"

const fruits = ["Apple", "Banana", "Cherry", "Mango", "Peach"]

export function CheckboxSelectAll() {
  const [value, setValue] = React.useState<string[]>(["Banana"])

  return (
    <div className="text-sm">
      <CheckboxGroup
        aria-label="Fruits"
        value={value}
        onValueChange={setValue}
        allValues={fruits}
      >
        <label className="flex items-center gap-3">
          <Checkbox parent />
          <span>
            Select all{" "}
            <span className="text-muted-foreground">
              ({value.length}/{fruits.length})
            </span>
          </span>
        </label>
        <div className="flex flex-col gap-3 ps-7">
          {fruits.map((fruit) => (
            <label key={fruit} className="flex items-center gap-3">
              <Checkbox value={fruit} />
              {fruit}
            </label>
          ))}
        </div>
      </CheckboxGroup>
    </div>
  )
}

İç içe gruplar

Gruplar iç içe geçebilir. Her üst öğe hemen altındaki grubun durumunu yansıtır; en üstteki ise her şeyi kapsar.

"use client"

import * as React from "react"

import { Checkbox, CheckboxGroup } from "@/components/ui/checkbox"

const userPermissions = ["users.read", "users.write", "users.delete"]
const billingPermissions = ["billing.read", "billing.write"]

export function CheckboxNestedGroups() {
  const [users, setUsers] = React.useState<string[]>(["users.read"])
  const [billing, setBilling] = React.useState<string[]>([])

  return (
    <div className="text-sm">
      <CheckboxGroup
        aria-label="Permissions"
        value={[...users, ...billing]}
        onValueChange={(next) => {
          setUsers(next.filter((value) => value.startsWith("users.")))
          setBilling(next.filter((value) => value.startsWith("billing.")))
        }}
        allValues={[...userPermissions, ...billingPermissions]}
      >
        <label className="flex items-center gap-3">
          <Checkbox parent />
          All permissions
        </label>
        <div className="flex flex-col gap-3 ps-7">
          <CheckboxGroup
            aria-label="Users"
            value={users}
            onValueChange={setUsers}
            allValues={userPermissions}
          >
            <label className="flex items-center gap-3">
              <Checkbox parent />
              Users
            </label>
            <div className="flex flex-col gap-3 ps-7">
              {userPermissions.map((permission) => (
                <label key={permission} className="flex items-center gap-3">
                  <Checkbox value={permission} />
                  {permission}
                </label>
              ))}
            </div>
          </CheckboxGroup>
          <CheckboxGroup
            aria-label="Billing"
            value={billing}
            onValueChange={setBilling}
            allValues={billingPermissions}
          >
            <label className="flex items-center gap-3">
              <Checkbox parent />
              Billing
            </label>
            <div className="flex flex-col gap-3 ps-7">
              {billingPermissions.map((permission) => (
                <label key={permission} className="flex items-center gap-3">
                  <Checkbox value={permission} />
                  {permission}
                </label>
              ))}
            </div>
          </CheckboxGroup>
        </div>
      </CheckboxGroup>
    </div>
  )
}

Kontrollü

State'i kendi kodunuzda tutmak için checked ve onCheckedChange geçin.

"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"

export function CheckboxControlled() {
  const [checked, setChecked] = React.useState(false)

  return (
    <div className="flex flex-col items-start gap-3">
      <label className="flex items-center gap-3 text-sm">
        <Checkbox checked={checked} onCheckedChange={setChecked} />
        Controlled ({checked ? "on" : "off"})
      </label>
      <Button variant="outline" size="sm" onClick={() => setChecked(!checked)}>
        Toggle from outside
      </Button>
    </div>
  )
}

Form

Gizli bir girdi, yerel bir checkbox gibi name ve value gönderir; required ise işaretlenene kadar göndermeyi engeller.

"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"

export function CheckboxForm() {
  const [submitted, setSubmitted] = React.useState<string>()

  return (
    <form
      className="flex flex-col items-start gap-3 text-sm"
      onSubmit={(event) => {
        event.preventDefault()
        const data = new FormData(event.currentTarget)
        setSubmitted(JSON.stringify(Object.fromEntries(data.entries())))
      }}
    >
      <label className="flex items-center gap-3">
        <Checkbox name="terms" required />I agree to the terms
      </label>
      <label className="flex items-center gap-3">
        <Checkbox name="newsletter" value="weekly" defaultChecked />
        Weekly newsletter
      </label>
      <Button type="submit" size="sm">
        Submit
      </Button>
      <output className="text-muted-foreground">
        {submitted ?? "Nothing submitted yet."}
      </output>
    </form>
  )
}

Kardeş etiket

Etiket kutuyu saramıyorsa, checkbox'ı nativeButton ile bir <button> olarak oluşturun ve etiketi htmlFor ile ona yöneltin.

import { Checkbox } from "@/components/ui/checkbox"

export function CheckboxSiblingLabel() {
  return (
    <div className="flex items-center gap-2 text-sm">
      <Checkbox id="terms" nativeButton render={<button />} />
      <label htmlFor="terms">Accept terms and conditions</label>
    </div>
  )
}

Kartlar

Kartın kendisi tıklama alanı olsun diye tüm kartı etikete sarın ve has-data-checked ile stilleyin.

import { Checkbox, CheckboxGroup } from "@/components/ui/checkbox"

const addOns = [
  { value: "analytics", title: "Analytics", text: "Dashboards and exports." },
  { value: "backups", title: "Backups", text: "Daily snapshots, 30 days." },
]

export function CheckboxCards() {
  return (
    <CheckboxGroup
      aria-label="Add-ons"
      defaultValue={["analytics"]}
      className="w-full max-w-md"
    >
      <div className="grid gap-3 sm:grid-cols-2">
        {addOns.map((addOn) => (
          <label
            key={addOn.value}
            className="flex items-start gap-3 rounded-xl border p-4 text-sm transition-colors has-data-checked:border-primary"
          >
            <span className="flex h-5 items-center">
              <Checkbox value={addOn.value} />
            </span>
            <span className="flex flex-col gap-0.5">
              <span className="leading-5 font-medium">{addOn.title}</span>
              <span className="text-muted-foreground">{addOn.text}</span>
            </span>
          </label>
        ))}
      </div>
    </CheckboxGroup>
  )
}

Uzun içerik

Uzun bir etiket ve kırılmayan metin yanında sararken kutu ilk satırda kalır.

import { Checkbox } from "@/components/ui/checkbox"

export function CheckboxLongContent() {
  return (
    <label className="flex w-64 max-w-full items-start gap-3 text-sm">
      <span className="flex h-5 items-center">
        <Checkbox />
      </span>
      <span className="flex min-w-0 flex-col gap-0.5 wrap-anywhere">
        <span className="leading-5 font-medium">
          A label long enough to wrap onto a second and even a third line in a
          narrow container
        </span>
        <span className="text-muted-foreground">
          averyveryverylongunbrokenstringthatwouldotherwiseescapeitscontainer
        </span>
      </span>
    </label>
  )
}

Sağdan sola

Kutu satır içi başlangıç tarafında durur ve etiket okuma yönünü izler.

import { Checkbox } from "@/components/ui/checkbox"

export function CheckboxRtl() {
  return (
    <div dir="rtl" className="flex flex-col gap-3 text-sm">
      <label className="flex items-center gap-3">
        <Checkbox defaultChecked />
        تذكر هذا الجهاز
      </label>
      <label className="flex max-w-sm items-start gap-3">
        <span className="flex h-5 items-center">
          <Checkbox />
        </span>
        <span className="flex flex-col gap-0.5">
          <span className="leading-5 font-medium">الإشارات والردود</span>
          <span className="text-muted-foreground">
            سنرسل لك إشعارات فقط حول نشاط منشوراتك.
          </span>
        </span>
      </label>
    </div>
  )
}
TuşAction
SpaceCheckbox'ı işaretler veya işaretini kaldırır.
EnterCheckbox'ın ait olduğu formu, yerel bir checkbox gibi gönderir. Kutuyu asla açıp kapatmaz.
TabOdağı sonraki checkbox'a taşır.
  • Checkbox'ı ve metnini bir <label> içine sarın. Etiket checkbox'ı adlandırır; üzerine gelmek veya basmak kutuya, kutunun kendisine gelmekle aynı geri bildirimi verir.
  • Ekran okuyucuların grubun ne için olduğunu duyurması için her <CheckboxGroup /> bileşenine bir aria-label veya aria-labelledby verin.
  • Tıklama alanı 16px'lik kutunun ötesine uzanır ve dokunmatik ekranlarda büyür.
  • İşaretlenince onay işareti çizilir. Azaltılmış harekette çizgi animasyonu olmadan belirir.

Base UI checkbox ve checkbox group üzerine kuruludur. İkisi de sardığı primitive'in prop'larını kabul eder.

PropTürVarsayılan
checked
boolean–
defaultChecked
booleanfalse
onCheckedChange
(checked: boolean, details) => void–
indeterminateBir tire gösterir: ne işaretli ne de işaretsiz.
booleanfalse
disabled
booleanfalse
readOnlyOdaklanabilir, ancak değer değiştirilemez.
booleanfalse
required
booleanfalse
nameİşaretliyken formla birlikte gönderilir.
string–
valueBir grubun içindeki kutuyu tanımlar ve formun gönderdiği değerdir. Önce name'e, sonra “on”a geri döner.
string–
uncheckedValueİşaretsizken gönderilir. Varsayılan olarak hiçbir şey.
string–
parentGrubun allValues içindeki her değeri kontrol eder. Yalnızca bir CheckboxGroup içinde.
booleanfalse
inputRef
Ref<HTMLInputElement>–
nativeButtonrender bir <button> olduğunda true yapın.
booleanfalse
render
ReactElement | (props, state) => ReactElement<span>
ÖznitelikAçıklama
data-slot="checkbox"CSS'te kutuyu hedefleyin.
data-checkedİşaretli olduğunda bulunur.
data-uncheckedİşaretsiz olduğunda bulunur.
data-indeterminateBelirsiz (indeterminate) olduğunda bulunur.
data-disabledDevre dışıyken bulunur.
data-readonlySalt okunur olduğunda bulunur.
data-requiredZorunlu olduğunda bulunur.
data-invalidBir Base UI Field içinde geçersiz olduğunda bulunur.
PropTürVarsayılan
valueİşaretli checkbox'ların değerleri.
string[]–
defaultValue
string[]–
onValueChange
(value: string[], details) => void–
allValuesGruptaki her değer. Bir üst (parent) checkbox için zorunludur.
string[]–
disabled
booleanfalse
render
ReactElement | (props, state) => ReactElement<div>
ÖznitelikAçıklama
data-slot="checkbox-group"CSS'te grubu hedefleyin.
data-disabledGrup devre dışı olduğunda bulunur.

Kullanıldığı bloklar

Checkbox üzerine kurulan bloklar.