Checkbox

Allows users to select or deselect an option, commonly used in forms and settings where multiple choices are available.

Playground

vue
<script setup lang="ts">
import { ref } from 'vue'
import { Checkbox } from 'frappe-ui'

const value = ref(false)
</script>

<template>
  <Checkbox v-model="value" label="Accept terms and conditions" />
</template>

Sizes

vue
<script setup lang="ts">
import { Checkbox } from 'frappe-ui'
</script>

<template>
  <div class="flex flex-col gap-3 items-start">
    <Checkbox size="sm" label="Small" />
    <Checkbox size="md" label="Medium" />
  </div>
</template>

Labeling

label, description, error, and required are wired into the underlying input via the shared labeling contract. Description and error stack below the row, indented under the label region.

Required to continue.

vue
<script setup lang="ts">
import { computed, ref } from 'vue'
import { Checkbox } from 'frappe-ui'

const accepted = ref(false)
const required = ref(true)
const showError = ref(false)

const error = computed(() =>
  showError.value ? 'You must accept the terms.' : '',
)
</script>

<template>
  <div class="flex gap-8 items-start">
    <Checkbox
      v-model="accepted"
      label="Accept terms"
      description="Required to continue."
      :error="error"
      :required="required"
    />
    <div
      class="flex flex-col gap-2 items-start border-l border-outline-gray-2 pl-6"
    >
      <Checkbox v-model="required" label="required" />
      <Checkbox v-model="showError" label="show error" />
    </div>
  </div>
</template>

States

vue
<script setup lang="ts">
import { Checkbox } from 'frappe-ui'
</script>

<template>
  <div class="flex flex-col gap-3 items-start">
    <Checkbox label="Default" />
    <Checkbox label="Required" required />
    <Checkbox label="Disabled" disabled />
    <Checkbox label="With error" error="Required to continue." />
  </div>
</template>

Group

Stack related options into a vertical settings group.

vue
<script setup lang="ts">
import { reactive } from 'vue'
import { Checkbox } from 'frappe-ui'

const settings = reactive({
  paymentDays: true,
  taxApplicable: true,
  deductFullTax: false,
  roundToInteger: false,
  doNotInclude: true,
  removeIfZero: false,
})
</script>

<template>
  <div class="flex flex-col gap-1 items-start w-80">
    <Checkbox v-model="settings.paymentDays" label="Depends on payment days" />
    <Checkbox v-model="settings.taxApplicable" label="Is Tax Applicable" />
    <Checkbox
      v-model="settings.deductFullTax"
      label="Deduct full tax on selected payroll date"
    />
    <Checkbox v-model="settings.roundToInteger" label="Round to the nearest integer" />
    <Checkbox v-model="settings.doNotInclude" label="Do not include in total" disabled />
    <Checkbox v-model="settings.removeIfZero" label="Remove if zero valued" />
  </div>
</template>

With description

Pair each option with helper text to clarify its effect.

If enabled, the value specified or calculated in this component will not contribute to the earnings or deductions. However, its value can be referenced by other components that can be added or deducted.

If enabled, the value specified or calculated in this component will not contribute to the earnings or deductions. However, its value can be referenced by other components that can be added or deducted.

vue
<script setup lang="ts">
import { reactive } from 'vue'
import { Checkbox } from 'frappe-ui'

const settings = reactive({
  roundToInteger: false,
  removeIfZero: false,
})

const helperText =
  'If enabled, the value specified or calculated in this component will not contribute to the earnings or deductions. However, its value can be referenced by other components that can be added or deducted.'
</script>

<template>
  <div class="flex flex-col gap-3 items-start w-[28rem]">
    <Checkbox
      v-model="settings.roundToInteger"
      label="Round to the nearest integer"
      :description="helperText"
    />
    <Checkbox
      v-model="settings.removeIfZero"
      label="Remove if zero valued"
      :description="helperText"
    />
  </div>
</template>

Horizontal group

Wrap multiple options inline under a section title.

Print settings

vue
<script setup lang="ts">
import { reactive } from 'vue'
import { Checkbox } from 'frappe-ui'

const settings = reactive({
  inclusiveText: false,
  paymentSchedule: false,
  taxesAsTable: true,
})
</script>

<template>
  <div class="flex flex-col gap-4 items-start w-[32rem]">
    <p class="text-lg-medium text-ink-gray-9">Print settings</p>
    <div class="flex flex-wrap gap-x-8 gap-y-2">
      <Checkbox v-model="settings.inclusiveText" label="Show inclusive text in print" />
      <Checkbox
        v-model="settings.paymentSchedule"
        label="Show payment schedule in print"
      />
      <Checkbox v-model="settings.taxesAsTable" label="Show taxes as table in print" />
    </div>
  </div>
</template>

Setting row

Compose a checkbox group as the value side of a label/value row.

Default ticket type

vue
<script setup lang="ts">
import { reactive } from 'vue'
import { Checkbox } from 'frappe-ui'

const ticketTypes = reactive({
  primary: true,
  promotions: true,
  social: true,
  updates: true,
})
</script>

<template>
  <div class="flex gap-3 items-start border-b border-outline-gray-1 py-3 w-[28rem]">
    <p class="text-base text-ink-gray-7 pt-1.5 w-40 shrink-0">Default ticket type</p>
    <div class="flex flex-col gap-1 items-start">
      <Checkbox v-model="ticketTypes.primary" label="Primary" disabled />
      <Checkbox v-model="ticketTypes.promotions" label="Promotions" />
      <Checkbox v-model="ticketTypes.social" label="Social" />
      <Checkbox v-model="ticketTypes.updates" label="Updates" />
    </div>
  </div>
</template>

API Reference

Show types
typescript
import type { ToggleSize } from '../../composables/inputTypes'
import type { InputLabelingProps } from '../../composables/useInputLabeling'

export interface CheckboxProps extends InputLabelingProps {
  /** Controls the size of the checkbox */
  size?: ToggleSize

  /** Disables the checkbox interaction */
  disabled?: boolean

  /**
   * Adds padding around the checkbox.
   * @deprecated Use `data-*` styling hooks instead.
   */
  padding?: boolean

  /** Checked state of the checkbox. `boolean` is canonical; `1`/`0` are kept for v1 backwards compatibility. */
  modelValue?: boolean | 1 | 0
}

export interface CheckboxEmits {
  /** Fired when the checkbox value changes. */
  'update:modelValue': [value: boolean]
}
size
= "sm"
ToggleSize

Controls the size of the checkbox

disabled
boolean

Disables the checkbox interaction

padding
= false

Deprecated — Use `data-*` styling hooks instead.

modelValue
boolean | 0 | 1

Checked state of the checkbox. `boolean` is canonical; `1`/`0` are kept for v1 backwards compatibility.

label
string

Label rendered above (or beside, for binary controls) the input.

description
string

Helper text rendered below the input. Hidden when `error` is set.

error
string | FrappeUIError

Error message rendered below the input. When set, the control receives `aria-invalid="true"` and `data-state="invalid"`. May be either a string or an `Error` object whose `messages?: string[]` is rendered as stacked lines (with `Error.message` as the fallback).

required
boolean

Marks the field as required. Renders an asterisk next to the label and forwards `required` / `aria-required` to the underlying control.

id
string

HTML id of the underlying control. Auto-generated via `useId()` if omitted.

label
{ required: boolean; }

Overrides the rendered label content. Receives `{ required }`.

description

Overrides the rendered description content.

update:modelValue
unknown[]

Fired when the model value changes.