Phi
Checkbox
@dicehub/phiv1.0.0-beta.1

Checkbox

A control that allows the user to toggle between checked and not checked.

<script setup>
import { ref } from "vue";
import { Checkbox } from "@dicehub/phi/components/checkbox";

const checked = ref(false);
</script>

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

Installation

Barrel

import { Checkbox } from "@dicehub/phi";

Granular

import { Checkbox } from "@dicehub/phi/components/checkbox";

Usage

<script setup>
import { ref } from "vue";
import { Checkbox } from "@dicehub/phi/components/checkbox";

const checked = ref(false);
</script>

<template>
  <Checkbox v-model:checked="checked" label="Accept terms" />
</template>

Examples

Default

Checkbox with built-in label. The label automatically displays in a horizontal layout.

<script setup>
import { ref } from "vue";
import { Checkbox } from "@dicehub/phi/components/checkbox";

const checked = ref(false);
</script>

<template>
  <Checkbox v-model:checked="checked" label="Enable notifications" />
</template>

Checked

<script setup>
import { ref } from "vue";
import { Checkbox } from "@dicehub/phi/components/checkbox";

const checked = ref(true);
</script>

<template>
  <Checkbox v-model:checked="checked" label="I agree" />
</template>

Indeterminate

Used for select all patterns when some but not all items are selected.

<script setup>
import { ref } from "vue";
import { Checkbox } from "@dicehub/phi/components/checkbox";

const checked = ref("indeterminate");
</script>

<template>
  <Checkbox v-model:checked="checked" label="Select all" />
</template>

Label First Layout

Use :control-first="false" to place the label before the checkbox.

<script setup>
import { ref } from "vue";
import { Checkbox } from "@dicehub/phi/components/checkbox";

const checked = ref(false);
</script>

<template>
  <Checkbox
    v-model:checked="checked"
    label="Remember me"
    :control-first="false"
  />
</template>

Disabled

<script setup>
import { Checkbox } from "@dicehub/phi/components/checkbox";
</script>

<template>
  <Checkbox label="Disabled option" disabled />
</template>

Error

Error variant provides visual styling. For error messages, use Checkbox.Group.

<script setup>
import { Checkbox } from "@dicehub/phi/components/checkbox";
</script>

<template>
  <Checkbox label="Invalid option" variant="error" />
</template>

Checkbox Group

Group multiple checkboxes with a legend, description, and shared error messages.

<script setup>
import { ref } from "vue";
import { Checkbox } from "@dicehub/phi/components/checkbox";

const preferences = ref(["email"]);
</script>

<template>
  <Checkbox.Group
    v-model="preferences"
    legend="Email preferences"
    description="Choose how you'd like to receive updates"
  >
    <Checkbox.Item value="email" label="Email notifications" />
    <Checkbox.Item value="sms" label="SMS notifications" />
    <Checkbox.Item value="push" label="Push notifications" />
  </Checkbox.Group>
</template>

Checkbox Group with Error

Show validation errors at the group level. Error replaces description when present.

<script setup>
import { Checkbox } from "@dicehub/phi/components/checkbox";
</script>

<template>
  <Checkbox.Group
    legend="Required preferences"
    error="Please select at least one notification method"
    :model-value="[]"
  >
    <Checkbox.Item value="email" label="Email" variant="error" />
    <Checkbox.Item value="sms" label="SMS" variant="error" />
  </Checkbox.Group>
</template>

Visually Hidden Legend

Use Checkbox.Legend with class="phi-sr-only" to keep the legend accessible to screen readers while hiding it visually.

<script setup>
import { ref } from "vue";
import { Checkbox } from "@dicehub/phi/components/checkbox";

const preferences = ref(["email"]);
</script>

<template>
  <Checkbox.Group v-model="preferences" appearance="card" orientation="horizontal">
    <Checkbox.Legend class="phi-sr-only">
      Notification preferences
    </Checkbox.Legend>
    <Checkbox.Item value="email" label="Email notifications" />
    <Checkbox.Item value="sms" label="SMS notifications" />
    <Checkbox.Item value="push" label="Push notifications" />
  </Checkbox.Group>
</template>

Custom Legend Styling

Checkbox.Legend accepts normal Vue attributes for custom legend presentation.

<script setup>
import { ref } from "vue";
import { Checkbox } from "@dicehub/phi/components/checkbox";

const preferences = ref(["email"]);
</script>

<template>
  <Checkbox.Group v-model="preferences">
    <Checkbox.Legend style="font-size: 0.875rem; font-weight: 400; color: var(--phi-subtle);">
      Notification preferences
    </Checkbox.Legend>
    <Checkbox.Item value="email" label="Email notifications" />
    <Checkbox.Item value="sms" label="SMS notifications" />
    <Checkbox.Item value="push" label="Push notifications" />
  </Checkbox.Group>

  <Checkbox.Group v-model="preferences" appearance="card" orientation="horizontal">
    <Checkbox.Legend style="font-size: 0.875rem; font-weight: 400; color: var(--phi-subtle);">
      Notification preferences
    </Checkbox.Legend>
    <Checkbox.Item value="email" label="Email notifications" />
    <Checkbox.Item value="sms" label="SMS notifications" appearance="default" />
    <Checkbox.Item value="push" label="Push notifications" />
  </Checkbox.Group>
</template>

Checkbox Card

Use appearance="card" to join items inside one outline with dividers. Items can include a description prop or slot. The checkbox follows the label by default.

<script setup>
import { ref } from "vue";
import { Checkbox } from "@dicehub/phi/components/checkbox";

const products = ref(["web"]);
</script>

<template>
  <Checkbox.Group v-model="products" legend="Products" name="products" appearance="card">
    <Checkbox.Item value="web" label="Web traffic" description="Inspect HTTP requests." />
    <Checkbox.Item value="ai" label="AI prompts" description="Inspect prompts and responses." />
    <Checkbox.Item value="email" label="Outbound email" description="Inspect outgoing messages." />
  </Checkbox.Group>
</template>

Checkbox Card (Horizontal)

Horizontal card groups use two columns with row and column dividers. Below 641px, the items form one column.

<script setup>
import { ref } from "vue";
import { Checkbox } from "@dicehub/phi/components/checkbox";

const products = ref(["web"]);
</script>

<template>
  <Checkbox.Group v-model="products" legend="Products" name="products" appearance="card" orientation="horizontal">
    <Checkbox.Item value="web" label="Web traffic" description="Inspect HTTP requests." />
    <Checkbox.Item value="ai" label="AI prompts" description="Inspect prompts and responses." />
    <Checkbox.Item value="email" label="Outbound email" description="Inspect outgoing messages." />
  </Checkbox.Group>
</template>

Checkbox Card (Control First)

Set control-first on the group to place the checkbox before the label. Items can override the group order and appearance.

<Checkbox.Group appearance="card" legend="Notification channels" control-first :default-value="['email']">
  <Checkbox.Item value="email" label="Email" description="Receive email updates." />
  <Checkbox.Item value="sms" label="SMS" description="Not available on this plan." disabled />
</Checkbox.Group>

Standalone Checkbox Card

A card item outside a card group keeps its own border. Use default-checked for its initial state or v-model:checked to control it.

<Checkbox.Item
  appearance="card"
  label="Usage alerts"
  description="Receive a message before you reach your limit."
  :default-checked="true"
/>

API Reference

Checkbox

Single checkbox component with built-in label and horizontal layout.

PropTypeDefaultDescription
variant"default" | "error""default"Sets the visual variant. Use error for validation styling.
labelstring-Visible label rendered next to the checkbox.
controlFirstbooleantruePlaces the checkbox before the label. Set false for label-first layout.
checkedboolean | "indeterminate"-Controlled checked state. Use v-model:checked in Vue.
defaultCheckedboolean | "indeterminate"-Initial checked state for uncontrolled usage.
indeterminateboolean-Compatibility prop that renders the mixed state.
disabledboolean-Disables pointer and keyboard interaction.
namestring-Native checkbox name for form submission.
requiredboolean-Marks the checkbox as required.

Checkbox.Group

Wrapper for multiple checkboxes with legend, description, and error support.

PropTypeDefaultDescription
appearance"default" | "card""default"Card groups share one outline with internal dividers. Items can override the appearance; default items retain padding inside the card.
orientation"vertical" | "horizontal""vertical"Layout direction. Horizontal card groups use two columns, or one column below 641px.
legendstring-Visible legend above the items. For custom styling, omit this prop and pass Checkbox.Legend as a direct child. This prop takes precedence.
descriptionstring-Helper text displayed below the group.
errorstring-Validation message. Replaces description when present.
modelValuestring[]-Controlled selected values. Use v-model in Vue.
defaultValuestring[][]Initial selected values for uncontrolled usage.
disabledboolean-Disables every item in the group.
controlFirstboolean-Sets the label/control order. Defaults to true for default items and false for card items.
namestring-Native checkbox name passed to group items.

Checkbox.Legend

Composable legend sub-component for Checkbox.Group.

PropTypeDefaultDescription
default slotunknown-Legend content. Pass class or style for custom presentation.

Checkbox.Item

Individual checkbox within Checkbox.Group.

PropTypeDefaultDescription
appearance"default" | "card"-Overrides the group appearance. A card outside a card group keeps its own border.
descriptionstring-Helper text below the label in card appearance.
description slotunknown-Rich helper content in card appearance.
controlFirstboolean-Overrides the group control order. Without an explicit order, card items place the control last.
valuestring-Item value used by Checkbox.Group.
labelstring-Visible label rendered next to the checkbox item.
variant"default" | "error""default"Sets the visual variant for the item.
checkedboolean | "indeterminate"-Controlled checked state when used outside a group.
disabledboolean-Disables this checkbox item.

Accessibility

Label Requirement

Single checkboxes require a label, default slot, aria-label, oraria-labelledby for an accessible name.

Keyboard Navigation

Space toggles the checkbox. Tab moves focus between checkboxes.

Screen Readers

Checkbox.Group renders a semantic fieldset and supports a visible or visually hidden legend.