Skip to content

Checkbox

Experimental Alpha

This library is a work-in-progress. We are releasing it early to gather feedback, but it is not ready for production.

Checkbox allows a user to select one or more options from a set. It's ideal for forms, settings panels, and multi-select interfaces.

Examples

Vue
Lit
React
Live Preview

Default Checkbox

Basic checkbox with default theme (primary)

Checkbox Group

Multiple checkboxes grouped together with a fieldset

Indeterminate State

Used for "select all" scenarios where some items are selected. Simply supply the indeterminate attribute to activate.

Size Variants

Three size options: small, medium (default), and large

Theme Variants

Choose from default (green), primary (blue), or monochrome (black/white) themes

Disabled State

Checkboxes can be disabled to prevent interaction

Label Position

Labels can be positioned at the end (default) or start of the checkbox

External Label Support

Checkboxes support optional external labels, helper text, and error messages for validation feedback.

CSS Shadow Parts Customization

Use CSS Shadow Parts to customize the component's appearance.

View Vue Code
<template>
  <section>
    <div class="mbe4">
      <h2>Default Checkbox</h2>
      <p class="mbs2 mbe3">Basic checkbox with default theme (primary)</p>
    </div>
    <div class="stacked-mobile mbe4">
      <VueCheckbox
        name="example"
        value="1"
        label-text="I agree to the terms and conditions"
      />
      <VueCheckbox
        name="example"
        value="2"
        label-text="Subscribe to newsletter"
        :checked="true"
      />
    </div>

    <div class="mbe4">
      <h2>Checkbox Group</h2>
      <p class="mbs2 mbe3">Multiple checkboxes grouped together with a fieldset</p>
    </div>
    <VueFieldset
      legend="Select your interests"
      class="mbe4"
    >
      <div style="display: flex; flex-direction: column; gap: 0.75rem;">
        <VueCheckbox
          name="interests"
          value="tech"
          label-text="Technology"
          :checked="true"
        />
        <VueCheckbox
          name="interests"
          value="design"
          label-text="Design"
        />
        <VueCheckbox
          name="interests"
          value="business"
          label-text="Business"
          :checked="true"
        />
        <VueCheckbox
          name="interests"
          value="science"
          label-text="Science"
        />
      </div>
    </VueFieldset>

    <div class="mbe4">
      <h2>Indeterminate State</h2>
      <p class="mbs2 mbe3">Used for "select all" scenarios where some items are selected. Simply supply the <i>indeterminate</i> attribute to activate.</p>
    </div>
    <div
      class="mbe4"
      style="display: flex; flex-direction: column; gap: 0.75rem;"
    >
      <VueCheckbox
        name="select-all"
        value="all"
        :indeterminate="true"
        label-text="Select All (Some selected)"
      />
      <div style="padding-left: 1.5rem; display: flex; flex-direction: column; gap: 0.5rem;">
        <VueCheckbox
          name="items"
          value="item1"
          label-text="Item 1"
          :checked="true"
        />
        <VueCheckbox
          name="items"
          value="item2"
          label-text="Item 2"
        />
        <VueCheckbox
          name="items"
          value="item3"
          label-text="Item 3"
          :checked="true"
        />
      </div>
    </div>

    <div class="mbe4">
      <h2>Size Variants</h2>
      <p class="mbs2 mbe3">Three size options: small, medium (default), and large</p>
    </div>
    <div
      class="mbe4"
      style="display: flex; gap: 2rem; align-items: center;"
    >
      <VueCheckbox
        name="size"
        value="small"
        size="small"
        label-text="Small"
        :checked="true"
      />
      <VueCheckbox
        name="size"
        value="medium"
        size="medium"
        label-text="Medium"
        :checked="true"
      />
      <VueCheckbox
        name="size"
        value="large"
        size="large"
        label-text="Large"
        :checked="true"
      />
    </div>

    <div class="mbe4">
      <h2>Theme Variants</h2>
      <p class="mbs2 mbe3">Choose from default (green), primary (blue), or monochrome (black/white) themes</p>
    </div>
    <div
      class="mbe4"
      style="display: flex; flex-direction: column; gap: 1.5rem;"
    >
      <VueFieldset legend="Default Theme (Blue)">
        <div style="display: flex; gap: 1rem;">
          <VueCheckbox
            name="theme-default"
            value="1"
            theme="default"
            label-text="Unchecked"
          />
          <VueCheckbox
            name="theme-default"
            value="2"
            theme="default"
            label-text="Checked"
            :checked="true"
          />
          <VueCheckbox
            name="theme-default"
            value="3"
            theme="default"
            label-text="Indeterminate"
            :indeterminate="true"
          />
        </div>
      </VueFieldset>
      <VueFieldset legend="Primary Theme (Blue)">
        <div style="display: flex; gap: 1rem;">
          <VueCheckbox
            name="theme-primary"
            value="1"
            theme="primary"
            label-text="Unchecked"
          />
          <VueCheckbox
            name="theme-primary"
            value="2"
            theme="primary"
            label-text="Checked"
            :checked="true"
          />
          <VueCheckbox
            name="theme-primary"
            value="3"
            theme="primary"
            label-text="Indeterminate"
            :indeterminate="true"
          />
        </div>
      </VueFieldset>
      <VueFieldset legend="Success Theme (Green)">
        <div style="display: flex; gap: 1rem;">
          <VueCheckbox
            name="theme-success"
            value="1"
            theme="success"
            label-text="Unchecked"
          />
          <VueCheckbox
            name="theme-success"
            value="2"
            theme="success"
            label-text="Checked"
            :checked="true"
          />
          <VueCheckbox
            name="theme-success"
            value="3"
            theme="success"
            label-text="Indeterminate"
            :indeterminate="true"
          />
        </div>
      </VueFieldset>

      <VueFieldset legend="Monochrome Theme (Black/White)">
        <div style="display: flex; gap: 1rem;">
          <VueCheckbox
            name="theme-mono"
            value="1"
            theme="monochrome"
            label-text="Unchecked"
          />
          <VueCheckbox
            name="theme-mono"
            value="2"
            theme="monochrome"
            label-text="Checked"
            :checked="true"
          />
          <VueCheckbox
            name="theme-mono"
            value="3"
            theme="monochrome"
            label-text="Indeterminate"
            :indeterminate="true"
          />
        </div>
      </VueFieldset>
    </div>

    <div class="mbe4">
      <h2>Disabled State</h2>
      <p class="mbs2 mbe3">Checkboxes can be disabled to prevent interaction</p>
    </div>
    <div
      class="mbe4"
      style="display: flex; gap: 1rem;"
    >
      <VueCheckbox
        name="disabled"
        value="1"
        label-text="Disabled Unchecked"
        :disabled="true"
      />
      <VueCheckbox
        name="disabled"
        value="2"
        label-text="Disabled Checked"
        :checked="true"
        :disabled="true"
      />
      <VueCheckbox
        name="disabled"
        value="3"
        label-text="Disabled Indeterminate"
        :indeterminate="true"
        :disabled="true"
      />
    </div>

    <div class="mbe4">
      <h2>Label Position</h2>
      <p class="mbs2 mbe3">Labels can be positioned at the end (default) or start of the checkbox</p>
    </div>
    <div
      class="mbe4"
      style="display: flex; flex-direction: column; gap: 1rem;"
    >
      <VueCheckbox
        name="position"
        value="1"
        label-text="Label on End (Default)"
        label-position="end"
        :checked="true"
      />
      <VueCheckbox
        name="position"
        value="2"
        label-text="Label on Start"
        label-position="start"
        :checked="true"
      />
    </div>

    <div class="mbe4">
      <h2>External Label Support</h2>
      <p class="mbs2 mbe3">
        Checkboxes support optional external labels, helper text, and error messages for validation feedback.
      </p>
    </div>
    <div class="stacked mbe4">
      <VueCheckbox
        name="terms"
        value="agreed"
        label="Terms and Conditions"
        label-text="I agree to the terms and conditions"
        class="mbe2"
      />

      <VueCheckbox
        name="newsletter"
        value="subscribed"
        label="Newsletter Subscription"
        label-text="Send me weekly updates"
        help-text="You can unsubscribe at any time"
        class="mbe2"
      />

      <VueCheckbox
        name="required-check"
        value="yes"
        label="Required Agreement"
        label-text="I acknowledge I have read the privacy policy"
        :required="true"
        help-text="This field is required to proceed"
        class="mbe2"
      />

      <VueCheckbox
        name="age-verify"
        value="yes"
        label="Age Verification"
        label-text="I confirm I am 18 years or older"
        :required="true"
        :invalid="true"
        error-message="You must confirm you are 18 or older"
        class="mbe2"
      />
    </div>

    <div class="mbe4">
      <h2>CSS Shadow Parts Customization</h2>
      <p class="mbs2 mbe3">
        Use CSS Shadow Parts to customize the component's appearance.
      </p>
    </div>
    <div class="stacked-mobile mbe4">
      <VueCheckbox
        name="custom"
        value="1"
        label-text="Customized with rounded indicator"
        :checked="true"
        class="custom-checkbox-1"
      />
      <VueCheckbox
        name="custom"
        value="3"
        label-text="Fully customized"
        :checked="true"
        theme="primary"
        class="custom-checkbox-3"
      />
    </div>
  </section>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { VueCheckbox } from "agnosticui-core/checkbox/vue";
import { VueFieldset } from "agnosticui-core/fieldset/vue";

export default defineComponent({
  name: "CheckboxExamples",
  components: {
    VueCheckbox,
    VueFieldset,
  },
});
</script>

<style>
/* CSS Shadow Parts customization examples */
.custom-checkbox-1::part(ag-checkbox-indicator) {
  border-radius: 50%;
  border-width: 3px;
}

.custom-checkbox-3::part(ag-checkbox-indicator) {
  border-radius: var(--ag-radius-md);
  transform: scale(1.2);
}

.custom-checkbox-3::part(ag-checkbox-wrapper) {
  padding: 0.75rem;
  background: linear-gradient(
    135deg,
    var(--ag-primary-background) 0%,
    var(--ag-background-secondary) 100%
  );
  border-radius: var(--ag-radius-lg);
  border: 2px solid var(--ag-primary-border);
}

.custom-checkbox-3::part(ag-checkbox-label) {
  font-weight: 700;
  font-size: 1.1rem;
  color: var(--ag-primary);
}
</style>
Live Preview
View Lit / Web Component Code
import { LitElement, html } from 'lit';
import 'agnosticui-core/checkbox';
import 'agnosticui-core/fieldset';

export class CheckboxLitExamples extends LitElement {
  // Render in light DOM to access global utility classes
  createRenderRoot() {
    return this;
  }

  render() {
    return html`
      <section>
        <!-- Default Checkbox -->
        <div class="mbe4">
          <h2>Default Checkbox</h2>
          <p class="mbs2 mbe3">Basic checkbox with default theme (primary)</p>
        </div>
        <div class="stacked-mobile mbe4">
          <ag-checkbox
            name="example"
            value="1"
            label-text="I agree to the terms and conditions"
          ></ag-checkbox>
          <ag-checkbox
            name="example"
            value="2"
            label-text="Subscribe to newsletter"
            checked
          ></ag-checkbox>
        </div>

        <!-- Checkbox Group -->
        <div class="mbe4">
          <h2>Checkbox Group</h2>
          <p class="mbs2 mbe3">Multiple checkboxes grouped together with a fieldset</p>
        </div>
        <ag-fieldset legend="Select your interests" class="mbe4">
          <div style="display: flex; flex-direction: column; gap: 0.75rem;">
            <ag-checkbox
              name="interests"
              value="tech"
              label-text="Technology"
              checked
            ></ag-checkbox>
            <ag-checkbox
              name="interests"
              value="design"
              label-text="Design"
            ></ag-checkbox>
            <ag-checkbox
              name="interests"
              value="business"
              label-text="Business"
              checked
            ></ag-checkbox>
            <ag-checkbox
              name="interests"
              value="science"
              label-text="Science"
            ></ag-checkbox>
          </div>
        </ag-fieldset>

        <!-- Indeterminate State -->
        <div class="mbe4">
          <h2>Indeterminate State</h2>
          <p class="mbs2 mbe3">Used for "select all" scenarios where some items are selected. Simply supply the <i>indeterminate</i> attribute to activate.</p>
        </div>
        <div class="mbe4" style="display: flex; flex-direction: column; gap: 0.75rem;">
          <ag-checkbox
            name="select-all"
            value="all"
            indeterminate
            label-text="Select All (Some selected)"
          ></ag-checkbox>
          <div style="padding-left: 1.5rem; display: flex; flex-direction: column; gap: 0.5rem;">
            <ag-checkbox
              name="items"
              value="item1"
              label-text="Item 1"
              checked
            ></ag-checkbox>
            <ag-checkbox
              name="items"
              value="item2"
              label-text="Item 2"
            ></ag-checkbox>
            <ag-checkbox
              name="items"
              value="item3"
              label-text="Item 3"
              checked
            ></ag-checkbox>
          </div>
        </div>

        <!-- Size Variants -->
        <div class="mbe4">
          <h2>Size Variants</h2>
          <p class="mbs2 mbe3">Three size options: small, medium (default), and large</p>
        </div>
        <div class="mbe4" style="display: flex; gap: 2rem; align-items: center;">
          <ag-checkbox
            name="size"
            value="small"
            size="small"
            label-text="Small"
            checked
          ></ag-checkbox>
          <ag-checkbox
            name="size"
            value="medium"
            size="medium"
            label-text="Medium"
            checked
          ></ag-checkbox>
          <ag-checkbox
            name="size"
            value="large"
            size="large"
            label-text="Large"
            checked
          ></ag-checkbox>
        </div>

        <!-- Theme Variants -->
        <div class="mbe4">
          <h2>Theme Variants</h2>
          <p class="mbs2 mbe3">Choose from default (green), primary (blue), or monochrome (black/white) themes</p>
        </div>
        <div class="mbe4" style="display: flex; flex-direction: column; gap: 1.5rem;">
          <ag-fieldset legend="Default Theme (Blue)">
            <div style="display: flex; gap: 1rem;">
              <ag-checkbox
                name="theme-default"
                value="1"
                theme="default"
                label-text="Unchecked"
              ></ag-checkbox>
              <ag-checkbox
                name="theme-default"
                value="2"
                theme="default"
                label-text="Checked"
                checked
              ></ag-checkbox>
              <ag-checkbox
                name="theme-default"
                value="3"
                theme="default"
                label-text="Indeterminate"
                indeterminate
              ></ag-checkbox>
            </div>
          </ag-fieldset>
          <ag-fieldset legend="Primary Theme (Blue)">
            <div style="display: flex; gap: 1rem;">
              <ag-checkbox
                name="theme-primary"
                value="1"
                theme="primary"
                label-text="Unchecked"
              ></ag-checkbox>
              <ag-checkbox
                name="theme-primary"
                value="2"
                theme="primary"
                label-text="Checked"
                checked
              ></ag-checkbox>
              <ag-checkbox
                name="theme-primary"
                value="3"
                theme="primary"
                label-text="Indeterminate"
                indeterminate
              ></ag-checkbox>
            </div>
          </ag-fieldset>
          <ag-fieldset legend="Success Theme (Green)">
            <div style="display: flex; gap: 1rem;">
              <ag-checkbox
                name="theme-success"
                value="1"
                theme="success"
                label-text="Unchecked"
              ></ag-checkbox>
              <ag-checkbox
                name="theme-success"
                value="2"
                theme="success"
                label-text="Checked"
                checked
              ></ag-checkbox>
              <ag-checkbox
                name="theme-success"
                value="3"
                theme="success"
                label-text="Indeterminate"
                indeterminate
              ></ag-checkbox>
            </div>
          </ag-fieldset>
          <ag-fieldset legend="Monochrome Theme (Black/White)">
            <div style="display: flex; gap: 1rem;">
              <ag-checkbox
                name="theme-mono"
                value="1"
                theme="monochrome"
                label-text="Unchecked"
              ></ag-checkbox>
              <ag-checkbox
                name="theme-mono"
                value="2"
                theme="monochrome"
                label-text="Checked"
                checked
              ></ag-checkbox>
              <ag-checkbox
                name="theme-mono"
                value="3"
                theme="monochrome"
                label-text="Indeterminate"
                indeterminate
              ></ag-checkbox>
            </div>
          </ag-fieldset>
        </div>

        <!-- Disabled State -->
        <div class="mbe4">
          <h2>Disabled State</h2>
          <p class="mbs2 mbe3">Checkboxes can be disabled to prevent interaction</p>
        </div>
        <div class="mbe4" style="display: flex; gap: 1rem;">
          <ag-checkbox
            name="disabled"
            value="1"
            label-text="Disabled Unchecked"
            disabled
          ></ag-checkbox>
          <ag-checkbox
            name="disabled"
            value="2"
            label-text="Disabled Checked"
            checked
            disabled
          ></ag-checkbox>
          <ag-checkbox
            name="disabled"
            value="3"
            label-text="Disabled Indeterminate"
            indeterminate
            disabled
          ></ag-checkbox>
        </div>

        <!-- Label Position -->
        <div class="mbe4">
          <h2>Label Position</h2>
          <p class="mbs2 mbe3">Labels can be positioned at the end (default) or start of the checkbox</p>
        </div>
        <div class="mbe4" style="display: flex; flex-direction: column; gap: 1rem;">
          <ag-checkbox
            name="position"
            value="1"
            label-text="Label on End (Default)"
            label-position="end"
            checked
          ></ag-checkbox>
          <ag-checkbox
            name="position"
            value="2"
            label-text="Label on Start"
            label-position="start"
            checked
          ></ag-checkbox>
        </div>

        <!-- External Label Support -->
        <div class="mbe4">
          <h2>External Label Support</h2>
          <p class="mbs2 mbe3">
            Checkboxes support optional external labels, helper text, and error messages for validation feedback.
          </p>
        </div>
        <div class="stacked mbe4">
          <ag-checkbox
            name="terms"
            value="agreed"
            label="Terms and Conditions"
            label-text="I agree to the terms and conditions"
            class="mbe2"
          ></ag-checkbox>

          <ag-checkbox
            name="newsletter"
            value="subscribed"
            label="Newsletter Subscription"
            label-text="Send me weekly updates"
            help-text="You can unsubscribe at any time"
            class="mbe2"
          ></ag-checkbox>

          <ag-checkbox
            name="required-check"
            value="yes"
            label="Required Agreement"
            label-text="I acknowledge I have read the privacy policy"
            required
            help-text="This field is required to proceed"
            class="mbe2"
          ></ag-checkbox>

          <ag-checkbox
            name="age-verify"
            value="yes"
            label="Age Verification"
            label-text="I confirm I am 18 years or older"
            required
            invalid
            error-message="You must confirm you are 18 or older"
            class="mbe2"
          ></ag-checkbox>
        </div>

        <!-- CSS Shadow Parts Customization -->
        <div class="mbe4">
          <h2>CSS Shadow Parts Customization</h2>
          <p class="mbs2 mbe3">
            Use CSS Shadow Parts to customize the component's appearance.
          </p>
        </div>
        <div class="stacked-mobile mbe4">
          <ag-checkbox
            name="custom"
            value="1"
            label-text="Customized with rounded indicator"
            checked
            class="custom-checkbox-1"
          ></ag-checkbox>
          <ag-checkbox
            name="custom"
            value="3"
            label-text="Fully customized"
            checked
            theme="primary"
            class="custom-checkbox-3"
          ></ag-checkbox>
        </div>
      </section>
    `;
  }
}

// Register the custom element
customElements.define('checkbox-lit-examples', CheckboxLitExamples);

Interactive Preview: Click the "Open in StackBlitz" button below to see this example running live in an interactive playground.

View React Code
import { ReactCheckbox } from "agnosticui-core/checkbox/react";
import { ReactFieldset } from "agnosticui-core/fieldset/react";

export default function CheckboxReactExamples() {
  return (
    <section>
      {/* Default Checkbox */}
      <div className="mbe4">
        <h2>Default Checkbox</h2>
        <p className="mbs2 mbe3">Basic checkbox with default theme (primary)</p>
      </div>
      <div className="stacked-mobile mbe4">
        <ReactCheckbox
          name="example"
          value="1"
          labelText="I agree to the terms and conditions"
        />
        <ReactCheckbox
          name="example"
          value="2"
          labelText="Subscribe to newsletter"
          checked
        />
      </div>

      {/* Checkbox Group */}
      <div className="mbe4">
        <h2>Checkbox Group</h2>
        <p className="mbs2 mbe3">Multiple checkboxes grouped together with a fieldset</p>
      </div>
      <ReactFieldset legend="Select your interests" className="mbe4">
        <div style={{ display: "flex", flexDirection: "column", gap: "0.75rem" }}>
          <ReactCheckbox
            name="interests"
            value="tech"
            labelText="Technology"
            checked
          />
          <ReactCheckbox
            name="interests"
            value="design"
            labelText="Design"
          />
          <ReactCheckbox
            name="interests"
            value="business"
            labelText="Business"
            checked
          />
          <ReactCheckbox
            name="interests"
            value="science"
            labelText="Science"
          />
        </div>
      </ReactFieldset>

      {/* Indeterminate State */}
      <div className="mbe4">
        <h2>Indeterminate State</h2>
        <p className="mbs2 mbe3">Used for "select all" scenarios where some items are selected. Simply supply the <i>indeterminate</i> attribute to activate.</p>
      </div>
      <div className="mbe4" style={{ display: "flex", flexDirection: "column", gap: "0.75rem" }}>
        <ReactCheckbox
          name="select-all"
          value="all"
          indeterminate
          labelText="Select All (Some selected)"
        />
        <div style={{ paddingLeft: "1.5rem", display: "flex", flexDirection: "column", gap: "0.5rem" }}>
          <ReactCheckbox
            name="items"
            value="item1"
            labelText="Item 1"
            checked
          />
          <ReactCheckbox
            name="items"
            value="item2"
            labelText="Item 2"
          />
          <ReactCheckbox
            name="items"
            value="item3"
            labelText="Item 3"
            checked
          />
        </div>
      </div>

      {/* Size Variants */}
      <div className="mbe4">
        <h2>Size Variants</h2>
        <p className="mbs2 mbe3">Three size options: small, medium (default), and large</p>
      </div>
      <div className="mbe4" style={{ display: "flex", gap: "2rem", alignItems: "center" }}>
        <ReactCheckbox
          name="size"
          value="small"
          size="small"
          labelText="Small"
          checked
        />
        <ReactCheckbox
          name="size"
          value="medium"
          size="medium"
          labelText="Medium"
          checked
        />
        <ReactCheckbox
          name="size"
          value="large"
          size="large"
          labelText="Large"
          checked
        />
      </div>

      {/* Theme Variants */}
      <div className="mbe4">
        <h2>Theme Variants</h2>
        <p className="mbs2 mbe3">Choose from default (green), primary (blue), or monochrome (black/white) themes</p>
      </div>
      <div className="mbe4" style={{ display: "flex", flexDirection: "column", gap: "1.5rem" }}>
        <ReactFieldset legend="Default Theme (Blue)">
          <div style={{ display: "flex", gap: "1rem" }}>
            <ReactCheckbox
              name="theme-default"
              value="1"
              theme="default"
              labelText="Unchecked"
            />
            <ReactCheckbox
              name="theme-default"
              value="2"
              theme="default"
              labelText="Checked"
              checked
            />
            <ReactCheckbox
              name="theme-default"
              value="3"
              theme="default"
              labelText="Indeterminate"
              indeterminate
            />
          </div>
        </ReactFieldset>
        <ReactFieldset legend="Primary Theme (Blue)">
          <div style={{ display: "flex", gap: "1rem" }}>
            <ReactCheckbox
              name="theme-primary"
              value="1"
              theme="primary"
              labelText="Unchecked"
            />
            <ReactCheckbox
              name="theme-primary"
              value="2"
              theme="primary"
              labelText="Checked"
              checked
            />
            <ReactCheckbox
              name="theme-primary"
              value="3"
              theme="primary"
              labelText="Indeterminate"
              indeterminate
            />
          </div>
        </ReactFieldset>
        <ReactFieldset legend="Success Theme (Green)">
          <div style={{ display: "flex", gap: "1rem" }}>
            <ReactCheckbox
              name="theme-success"
              value="1"
              theme="success"
              labelText="Unchecked"
            />
            <ReactCheckbox
              name="theme-success"
              value="2"
              theme="success"
              labelText="Checked"
              checked
            />
            <ReactCheckbox
              name="theme-success"
              value="3"
              theme="success"
              labelText="Indeterminate"
              indeterminate
            />
          </div>
        </ReactFieldset>
        <ReactFieldset legend="Monochrome Theme (Black/White)">
          <div style={{ display: "flex", gap: "1rem" }}>
            <ReactCheckbox
              name="theme-mono"
              value="1"
              theme="monochrome"
              labelText="Unchecked"
            />
            <ReactCheckbox
              name="theme-mono"
              value="2"
              theme="monochrome"
              labelText="Checked"
              checked
            />
            <ReactCheckbox
              name="theme-mono"
              value="3"
              theme="monochrome"
              labelText="Indeterminate"
              indeterminate
            />
          </div>
        </ReactFieldset>
      </div>

      {/* Disabled State */}
      <div className="mbe4">
        <h2>Disabled State</h2>
        <p className="mbs2 mbe3">Checkboxes can be disabled to prevent interaction</p>
      </div>
      <div className="mbe4" style={{ display: "flex", gap: "1rem" }}>
        <ReactCheckbox
          name="disabled"
          value="1"
          labelText="Disabled Unchecked"
          disabled
        />
        <ReactCheckbox
          name="disabled"
          value="2"
          labelText="Disabled Checked"
          checked
          disabled
        />
        <ReactCheckbox
          name="disabled"
          value="3"
          labelText="Disabled Indeterminate"
          indeterminate
          disabled
        />
      </div>

      {/* Label Position */}
      <div className="mbe4">
        <h2>Label Position</h2>
        <p className="mbs2 mbe3">Labels can be positioned at the end (default) or start of the checkbox</p>
      </div>
      <div className="mbe4" style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
        <ReactCheckbox
          name="position"
          value="1"
          labelText="Label on End (Default)"
          labelPosition="end"
          checked
        />
        <ReactCheckbox
          name="position"
          value="2"
          labelText="Label on Start"
          labelPosition="start"
          checked
        />
      </div>

      {/* External Label Support */}
      <div className="mbe4">
        <h2>External Label Support</h2>
        <p className="mbs2 mbe3">
          Checkboxes support optional external labels, helper text, and error messages for validation feedback.
        </p>
      </div>
      <div className="stacked mbe4">
        <ReactCheckbox
          name="terms"
          value="agreed"
          label="Terms and Conditions"
          labelText="I agree to the terms and conditions"
          className="mbe2"
        />

        <ReactCheckbox
          name="newsletter"
          value="subscribed"
          label="Newsletter Subscription"
          labelText="Send me weekly updates"
          helpText="You can unsubscribe at any time"
          className="mbe2"
        />

        <ReactCheckbox
          name="required-check"
          value="yes"
          label="Required Agreement"
          labelText="I acknowledge I have read the privacy policy"
          required
          helpText="This field is required to proceed"
          className="mbe2"
        />

        <ReactCheckbox
          name="age-verify"
          value="yes"
          label="Age Verification"
          labelText="I confirm I am 18 years or older"
          required
          invalid
          errorMessage="You must confirm you are 18 or older"
          className="mbe2"
        />
      </div>

      {/* CSS Shadow Parts Customization */}
      <div className="mbe4">
        <h2>CSS Shadow Parts Customization</h2>
        <p className="mbs2 mbe3">
          Use CSS Shadow Parts to customize the component's appearance.
        </p>
      </div>
      <div className="stacked-mobile mbe4">
        <ReactCheckbox
          name="custom"
          value="1"
          labelText="Customized with rounded indicator"
          checked
          className="custom-checkbox-1"
        />
        <ReactCheckbox
          name="custom"
          value="3"
          labelText="Fully customized"
          checked
          theme="primary"
          className="custom-checkbox-3"
        />
      </div>
    </section>
  );
}
Open in StackBlitz

Usage

TIP

The framework examples below import AgnosticUI as an npm package. Alternatively, you can use the CLI for complete control, AI/LLM visibility, and full code ownership:

bash
npx ag init --framework FRAMEWORK # react, vue, lit, svelte, etc.
npx ag add Checkbox

The CLI copies source code directly into your project, giving you full visibility and control. After running npx ag add, you'll receive exact import instructions.

Vue
vue
<template>
  <section>
    <VueCheckbox
      name="terms"
      value="agree"
      label-text="I agree to the terms and conditions"
    />

    <VueFieldset legend="Select your interests">
      <VueCheckbox
        name="interests"
        value="tech"
        label-text="Technology"
        :checked="true"
      />
      <VueCheckbox
        name="interests"
        value="design"
        label-text="Design"
      />
      <VueCheckbox
        name="interests"
        value="business"
        label-text="Business"
      />
    </VueFieldset>

    <VueCheckbox
      name="example"
      value="1"
      theme="primary"
      label-text="Primary theme"
      :checked="true"
    />
    <VueCheckbox
      name="example"
      value="2"
      theme="monochrome"
      label-text="Monochrome theme"
      :checked="true"
    />
  </section>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { VueCheckbox } from "agnosticui-core/checkbox/vue";
import { VueFieldset } from "agnosticui-core/fieldset/vue";

export default defineComponent({
  components: { VueCheckbox, VueFieldset }
});
</script>
React
tsx
import { ReactCheckbox } from "agnosticui-core/checkbox/react";
import { ReactFieldset } from "agnosticui-core/fieldset/react";

export default function Example() {
  return (
    <section>
      <ReactCheckbox
        name="terms"
        value="agree"
        labelText="I agree to the terms and conditions"
      />

      <ReactFieldset legend="Select your interests">
        <ReactCheckbox
          name="interests"
          value="tech"
          labelText="Technology"
          checked
        />
        <ReactCheckbox
          name="interests"
          value="design"
          labelText="Design"
        />
        <ReactCheckbox
          name="interests"
          value="business"
          labelText="Business"
        />
      </ReactFieldset>

      <ReactCheckbox
        name="example"
        value="1"
        theme="primary"
        labelText="Primary theme"
        checked
      />
      <ReactCheckbox
        name="example"
        value="2"
        theme="monochrome"
        labelText="Monochrome theme"
        checked
      />
    </section>
  );
}
Lit (Web Components)
html
<script type="module">
  import "agnosticui-core/checkbox";
  import "agnosticui-core/fieldset";
</script>

<section>
  <ag-checkbox
    name="terms"
    value="agree"
    label-text="I agree to the terms and conditions"
  ></ag-checkbox>

  <ag-fieldset legend="Select your interests">
    <ag-checkbox
      name="interests"
      value="tech"
      label-text="Technology"
      checked
    ></ag-checkbox>
    <ag-checkbox
      name="interests"
      value="design"
      label-text="Design"
    ></ag-checkbox>
    <ag-checkbox
      name="interests"
      value="business"
      label-text="Business"
    ></ag-checkbox>
  </ag-fieldset>

  <ag-checkbox
    name="example"
    value="1"
    theme="primary"
    label-text="Primary theme"
    checked
  ></ag-checkbox>
  <ag-checkbox
    name="example"
    value="2"
    theme="monochrome"
    label-text="Monochrome theme"
    checked
  ></ag-checkbox>
</section>

Label Position

The labelPosition prop controls where the internal label text appears relative to the checkbox. This affects the labelText (the label that wraps the checkbox), not the external label prop.

vue
<VueCheckbox
  name="option"
  value="1"
  label-text="Label on end (default)"
  label-position="end"
/>

<VueCheckbox
  name="option"
  value="2"
  label-text="Label on start"
  label-position="start"
/>

External Label Support

Checkboxes now support optional external labels, helper text, and error messages using the shared form control utilities. This is useful for:

  • Checkbox groups that need a descriptive label above them
  • Standalone checkboxes that require validation feedback
  • Forms where consistent label/helper/error patterns are needed

Basic External Label

vue
<VueCheckbox
  name="terms"
  value="agreed"
  label="Terms and Conditions"
  label-text="I agree to the terms and conditions"
/>

With Helper Text

vue
<VueCheckbox
  name="newsletter"
  value="subscribed"
  label="Newsletter Subscription"
  label-text="Send me weekly updates"
  help-text="You can unsubscribe at any time"
/>

With Validation

vue
<VueCheckbox
  name="age-verify"
  value="confirmed"
  label="Age Verification"
  label-text="I confirm I am 18 years or older"
  :required="true"
  :invalid="!ageVerified"
  error-message="You must confirm you are 18 or older"
/>

Checkbox Groups with External Label

vue
<template>
  <div>
    <VueCheckbox
      name="features"
      value="email"
      label="Select Features"
      label-text="Email notifications"
      help-text="Choose the features you want to enable"
    />
    <VueCheckbox
      name="features"
      value="sms"
      label-text="SMS notifications"
    />
    <VueCheckbox
      name="features"
      value="push"
      label-text="Push notifications"
    />
  </div>
</template>

Note: The label prop creates an external label above the checkbox, while labelText is the internal label that wraps the checkbox itself. Most checkboxes use only labelText, but external labels are useful for groups or when you need validation feedback.

Props

PropTypeDefaultDescription
namestring''Name attribute for the checkbox input (used for form submission)
valuestring''Value of the checkbox input
checkedbooleanfalseWhether the checkbox is checked
indeterminatebooleanfalseWhether the checkbox is in indeterminate state (used for "select all" scenarios)
disabledbooleanfalseWhether the checkbox is disabled
size'small' | 'medium' | 'large''medium'Size of the checkbox
theme'default' | 'primary' | 'success' | 'monochrome''primary'Color theme variant (default=blue alias to primary, primary=blue, success=green, monochrome=black/white)
labelTextstring''Label text for the checkbox (internal label that wraps the checkbox)
labelPosition'end' | 'start''end'Position of labelText relative to checkbox (end = after checkbox, start = before checkbox)
labelstring''Optional external label displayed above the checkbox (useful for groups or standalone with context)
labelHiddenbooleanfalseVisually hides the external label while keeping it accessible to screen readers
noLabelbooleanfalseCompletely removes the external label element
requiredbooleanfalseMarks the checkbox as required. Displays an asterisk (*) after the external label
invalidbooleanfalseMarks the checkbox as invalid. Sets aria-invalid and can display error message
errorMessagestring''Error message displayed when invalid. Linked via aria-describedby
helpTextstring''Helper text displayed below the checkbox. Linked via aria-describedby

Events

EventFrameworkDetailDescription
clickVue: @click
React: onClick
Lit: @click
MouseEventFired when the checkbox is clicked.
changeVue: @change
React: onChange
Lit: @change
{ checked: boolean, value: string, name: string, indeterminate: boolean }Fired when checkbox state changes. Contains the new checked state and form integration data.

Note: The Checkbox component supports dual-dispatch event propagation: it dispatches both DOM CustomEvents (usable with addEventListener) and invokes callback props (.onChange), giving you flexibility in how you handle events.

Event Usage Examples

Vue
vue
<template>
  <section>
    <VueCheckbox
      name="terms"
      value="agree"
      label-text="I agree to the terms"
      @change="handleChange"
    />

    <VueCheckbox
      name="newsletter"
      value="subscribed"
      label-text="Subscribe to newsletter"
      v-model:checked="isSubscribed"
    />

    <VueCheckbox
      name="select-all"
      value="all"
      label-text="Select All"
      v-model:indeterminate="isIndeterminate"
      v-model:checked="allChecked"
    />

    <VueCheckbox
      name="notifications"
      value="enabled"
      label-text="Enable notifications"
      v-model:checked="notificationsEnabled"
      @change="handleNotificationChange"
    />
  </section>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { VueCheckbox } from "agnosticui-core/checkbox/vue";

const isSubscribed = ref(false);
const isIndeterminate = ref(false);
const allChecked = ref(false);
const notificationsEnabled = ref(false);

const handleChange = (detail) => {
  console.log("Checkbox changed:", detail);
};

const handleNotificationChange = (detail) => {
  console.log("Notifications:", detail.checked ? "enabled" : "disabled");
};
</script>
React
tsx
import { useState } from "react";
import { ReactCheckbox } from "agnosticui-core/checkbox/react";

export default function Example() {
  const [isChecked, setIsChecked] = useState(false);

  return (
    <section>
      <ReactCheckbox
        name="terms"
        value="agree"
        labelText="I agree to the terms"
        onChange={(e) => {
          console.log("Checkbox changed:", (e.target as HTMLInputElement).checked);
        }}
      />

      <ReactCheckbox
        name="newsletter"
        value="subscribed"
        labelText="Subscribe to newsletter"
        checked={isChecked}
        onChange={(e) => {
          setIsChecked((e.target as HTMLInputElement).checked);
        }}
      />

      <ReactCheckbox
        name="notifications"
        value="enabled"
        labelText="Enable notifications"
        onClick={(e) => console.log("Clicked:", e)}
        onChange={(e) => console.log("Changed:", (e.target as HTMLInputElement).checked)}
      />

      <ReactCheckbox
        name="select-all"
        value="all"
        labelText="Select All"
        indeterminate
        onChange={(e) => {
          console.log("Indeterminate cleared on click:", (e.target as HTMLInputElement).checked);
        }}
      />
    </section>
  );
}
Lit (Web Components)
html
<script type="module">
  import "agnosticui-core/checkbox";

  const checkbox1 = document.querySelector("#checkbox1");
  checkbox1.addEventListener("change", (e) => {
    console.log("Event listener:", e.detail);
  });

  const checkbox2 = document.querySelector("#checkbox2");
  checkbox2.onChange = (e) => {
    console.log("Callback prop:", e.detail);
  };

  const checkbox3 = document.querySelector("#checkbox3");
  checkbox3.addEventListener("change", (e) => {
    console.log("DOM event:", e.detail);
  });
  checkbox3.onChange = (e) => {
    console.log("Callback also fired:", e.detail);
  };

  const checkbox4 = document.querySelector("#checkbox4");
  checkbox4.addEventListener("click", (e) => {
    console.log("Click event:", e);
  });
  checkbox4.onClick = (e) => {
    console.log("Click callback:", e);
  };
</script>

<section>
  <ag-checkbox
    id="checkbox1"
    name="example1"
    value="1"
    label-text="addEventListener pattern"
  ></ag-checkbox>

  <ag-checkbox
    id="checkbox2"
    name="example2"
    value="2"
    label-text="Callback prop pattern"
  ></ag-checkbox>

  <ag-checkbox
    id="checkbox3"
    name="example3"
    value="3"
    label-text="Dual-dispatch (both patterns)"
  ></ag-checkbox>

  <ag-checkbox
    id="checkbox4"
    name="example4"
    value="4"
    label-text="With click handlers"
  ></ag-checkbox>
</section>

Type:

ts
export type CheckboxChangeEvent = CustomEvent<CheckboxChangeEventDetail>;

export interface CheckboxChangeEventDetail {
  checked: boolean;
  value: string;
  name: string;
  indeterminate: boolean;
}

CSS Shadow Parts

Shadow Parts allow you to style internal elements of the checkbox from outside the shadow DOM using the ::part() CSS selector.

PartDescription
ag-checkbox-wrapperThe outer wrapper label element
ag-checkbox-inputThe native checkbox input element (visually hidden)
ag-checkbox-indicatorThe custom visual checkbox indicator (box with checkmark)
ag-checkbox-labelThe label text span

Customization Examples

css
ag-checkbox::part(ag-checkbox-indicator) {
  border-radius: 50%;
  border-width: 3px;
}

ag-checkbox::part(ag-checkbox-wrapper) {
  padding: 0.5rem;
  background: #6366f1;
  border-radius: #6366f1;
}

ag-checkbox::part(ag-checkbox-label) {
  font-weight: 600;
  color: #12623e;
}

Accessibility

  • Checkbox uses native <input type="checkbox"> for proper form integration
  • Proper aria-checked state for assistive technologies ("true", "false", or "mixed" for indeterminate)
  • Keyboard navigable (Tab to focus, Space to toggle)
  • Focus visible with customizable focus ring using design tokens
  • Always wrap checkbox groups with AgFieldset (ag-fieldset / ReactFieldset / VueFieldset) for proper semantic grouping and screen reader support
  • Disabled state prevents interaction and is communicated to assistive technologies

Theme Support

All themes automatically support dark mode through CSS design tokens:

  • Default theme: Alias to primary theme - uses --ag-primary (blue) which adapts to dark mode
  • Primary theme: Uses --ag-primary (blue) which adapts to dark mode
  • Success theme: Uses --ag-success (green) which adapts to dark mode
  • Monochrome theme: Uses --ag-black and --ag-white which invert in dark mode

Notes

  • Indeterminate state: Useful for "select all" checkboxes when only some items are selected
  • Form integration: Checkboxes work seamlessly with standard HTML forms
  • Lit: Properties can be set via attributes or via property binding (e.g., .checked=${true})
  • All three implementations (Lit, React, Vue) share the same underlying styles and behavior