npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fiscozen/checkbox

v3.0.0

Published

Design System Checkbox and Checkbox Group component

Readme

@fiscozen/checkbox

A fully accessible, WCAG 2.1 AA compliant checkbox component library for Vue 3 applications. Built with enterprise-grade accessibility features, support for single and multi-selection patterns, hierarchical checkbox groups with automatic indeterminate state management, and comprehensive keyboard navigation.

Features

  • WCAG 2.1 AA Compliant - Full accessibility support with comprehensive ARIA attributes
  • Flexible Data Models - Support for boolean (single) and array (multi-select) v-model binding
  • Hierarchical Structures - Parent-child checkbox relationships with automatic indeterminate state
  • Card-style Checkboxes - Rich selection cards with images, titles, subtitles, and tooltips
  • Keyboard Navigation - Complete keyboard accessibility with visible focus indicators
  • Screen Reader Optimized - Proper semantic markup and live region announcements
  • Error Handling - Built-in validation states with accessible error messages
  • Customizable - Multiple size variants, emphasis mode, and tooltip support

Installation

npm install @fiscozen/checkbox

Peer Dependencies: This package requires Vue 3.x and the following Fiscozen Design System packages:

  • @fiscozen/icons - Icon system
  • @fiscozen/tooltip - Tooltip component for contextual help
  • @fiscozen/alert - Alert component for error messages

Basic Usage

Single Checkbox (Boolean Model)

<script setup lang="ts">
import { ref } from 'vue';
import { FzCheckbox } from '@fiscozen/checkbox';

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

<template>
  <div>
    <FzCheckbox 
      v-model="accepted" 
      label="I accept the terms and conditions" 
    />
    
    <p v-if="accepted">Terms accepted!</p>
  </div>
</template>

Multiple Checkboxes (Array Model)

<script setup lang="ts">
import { ref } from 'vue';
import { FzCheckbox } from '@fiscozen/checkbox';

const selectedFeatures = ref<string[]>([]);
</script>

<template>
  <div>
    <h3>Select Features:</h3>
    
    <FzCheckbox 
      v-model="selectedFeatures" 
      value="feature-a" 
      label="Feature A" 
    />
    
    <FzCheckbox 
      v-model="selectedFeatures" 
      value="feature-b" 
      label="Feature B" 
    />
    
    <FzCheckbox 
      v-model="selectedFeatures" 
      value="feature-c" 
      label="Feature C" 
    />
    
    <p>Selected: {{ selectedFeatures.join(', ') }}</p>
  </div>
</template>

Checkbox Group

<script setup lang="ts">
import { ref } from 'vue';
import { FzCheckboxGroup } from '@fiscozen/checkbox';

const selectedOptions = ref<string[]>([]);

const options = [
  { label: 'Option 1', value: 'opt1' },
  { label: 'Option 2', value: 'opt2' },
  { label: 'Option 3', value: 'opt3' },
];
</script>

<template>
  <FzCheckboxGroup
    v-model="selectedOptions"
    label="Choose your options"
    :options="options"
  >
    <template #help>
      <span>Select one or more options</span>
    </template>
  </FzCheckboxGroup>
</template>

Checkbox Card

<script setup lang="ts">
import { ref } from 'vue';
import { FzCheckboxCard } from '@fiscozen/checkbox';

const selected = ref<(string | number)[]>([]);
</script>

<template>
  <div style="display: flex; gap: 12px;">
    <FzCheckboxCard
      v-model="selected"
      label="option-a"
      value="option-a"
      title="Option A"
      subtitle="Description for option A"
    />

    <FzCheckboxCard
      v-model="selected"
      label="option-b"
      value="option-b"
      title="Option B"
      subtitle="Description for option B"
    />
  </div>
</template>

API Reference

FzCheckbox

Core checkbox component supporting both single and multi-selection patterns. Can be used standalone or composed within checkbox groups.

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | label | string | required | Checkbox label text | | value | string \| number \| boolean | label | Value when used in array model | | indeterminate | boolean | false | Shows indeterminate state (partial selection) | | emphasis | boolean | false | Applies emphasis styling (blue when checked) | | disabled | boolean | false | Disables the checkbox | | error | boolean | false | Shows error state | | required | boolean | false | Marks field as required | | standalone | boolean | false | Renders only icon without label text | | tooltip | FzTooltipProps | undefined | Tooltip configuration | | ariaOwns | string | undefined | Space-separated child IDs for hierarchical structures | | checkboxId | string | auto-generated | Custom ID for the input element |

v-model

// Single checkbox
v-model: boolean | null | undefined

// Multi-select checkbox
v-model: (string | number | boolean)[]

Events

| Event | Payload | Description | |-------|---------|-------------| | change | Event | Emitted when checkbox state changes |

Slots

| Slot | Description | |------|-------------| | error | Error message content | | children | Child checkboxes (used internally by hierarchical structures) |


FzCheckboxGroup

Container component for managing multiple related checkboxes with shared labeling, validation, and accessibility features.

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | label | string | required | Group label | | options | ParentCheckbox[] | required | Array of checkbox options | | emphasis | boolean | false | Applies to all checkboxes | | disabled | boolean | false | Disables all checkboxes | | error | boolean | false | Shows error state | | required | boolean | false | Marks group as required | | horizontal | boolean | false | Arranges checkboxes horizontally |

v-model

v-model: string[]

Slots

| Slot | Description | |------|-------------| | help | Help text displayed below the label | | error | Error message content |


FzCheckboxCard

A card-style checkbox component with support for title, subtitle, optional image, and tooltip. Available in horizontal and vertical layout variants. Uses array v-model for multi-select patterns.

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | label | string | required | Accessible label for the underlying checkbox input | | value | string \| number | label | Value tracked in the array v-model | | title | string | required | Primary title text displayed in the card | | subtitle | string | undefined | Optional secondary text below the title | | variant | 'horizontal' \| 'vertical' | 'horizontal' | Layout direction of the card | | imageUrl | string | undefined | URL of the card image (required when variant is 'vertical') | | imageAlt | string | undefined | Alt text for the card image | | hasCheckbox | boolean | true | Whether to show the checkbox icon inside the card | | emphasis | boolean | false | Applies emphasis styling (blue icon when checked) | | disabled | boolean | false | Disables the card | | error | boolean | false | Shows error state (red checkbox icon) | | required | boolean | false | Marks the input as required | | tooltip | string | undefined | Text to display in the info tooltip | | tooltipStatus | FzTooltipStatus | 'neutral' | Tooltip color/status variant | | name | string | undefined | Input name attribute for form submission |

Note: When variant is 'vertical', the imageUrl prop is required since the vertical layout is designed around a full-width image.

v-model

v-model: (string | number | boolean)[]

Variant Layouts

  • Horizontal (default) — Checkbox icon, optional thumbnail image (58×58), and text are arranged in a row. Compact layout suited for lists.
  • Vertical — Full-width 16:9 image on top, checkbox icon overlaid, and text below. Designed for visually rich selections.

Advanced Usage

With Error Validation

<script setup lang="ts">
import { ref, computed } from 'vue';
import { FzCheckbox } from '@fiscozen/checkbox';

const agreedToTerms = ref(false);
const submitted = ref(false);

const hasError = computed(() => submitted.value && !agreedToTerms.value);

function handleSubmit() {
  submitted.value = true;
  if (!agreedToTerms.value) {
    // Handle validation error
    return;
  }
  // Process form
}
</script>

<template>
  <div>
    <FzCheckbox
      v-model="agreedToTerms"
      label="I agree to the terms"
      required
      :error="hasError"
    >
      <template #error>
        <p>You must accept the terms to continue</p>
      </template>
    </FzCheckbox>
    
    <button @click="handleSubmit">Submit</button>
  </div>
</template>

With Tooltip

<script setup lang="ts">
import { ref } from 'vue';
import { FzCheckbox } from '@fiscozen/checkbox';

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

<template>
  <FzCheckbox
    v-model="enableFeature"
    label="Enable advanced mode"
    :tooltip="{
      text: 'This enables experimental features that may be unstable',
      status: 'informative'
    }"
  />
</template>

Emphasis Mode

<script setup lang="ts">
import { ref } from 'vue';
import { FzCheckbox } from '@fiscozen/checkbox';

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

<template>
  <FzCheckbox
    v-model="isPrimary"
    label="Primary selection"
    emphasis
  />
</template>

Standalone (Icon Only)

<script setup lang="ts">
import { ref } from 'vue';
import { FzCheckbox } from '@fiscozen/checkbox';

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

<template>
  <div>
    <label for="custom-checkbox">Select this item:</label>
    <FzCheckbox
      v-model="selected"
      label="Select item"
      standalone
    />
  </div>
</template>

Hierarchical Checkbox Group

<script setup lang="ts">
import { ref } from 'vue';
import { FzCheckboxGroup } from '@fiscozen/checkbox';

const selectedPermissions = ref<string[]>([]);

const permissionOptions = [
  {
    label: 'Admin Access',
    value: 'admin',
    children: [
      { label: 'User Management', value: 'admin.users' },
      { label: 'System Settings', value: 'admin.settings' },
      { label: 'View Logs', value: 'admin.logs' },
    ]
  },
  {
    label: 'Content Access',
    value: 'content',
    children: [
      { label: 'Create Content', value: 'content.create' },
      { label: 'Edit Content', value: 'content.edit' },
      { label: 'Delete Content', value: 'content.delete' },
    ]
  }
];
</script>

<template>
  <FzCheckboxGroup
    v-model="selectedPermissions"
    label="Select Permissions"
    :options="permissionOptions"
  >
    <template #help>
      <span>Parent checkboxes show indeterminate state when partially selected</span>
    </template>
  </FzCheckboxGroup>
</template>

Horizontal Layout

<script setup lang="ts">
import { ref } from 'vue';
import { FzCheckboxGroup } from '@fiscozen/checkbox';

const selectedDays = ref<string[]>([]);

const dayOptions = [
  { label: 'Mon', value: 'monday' },
  { label: 'Tue', value: 'tuesday' },
  { label: 'Wed', value: 'wednesday' },
  { label: 'Thu', value: 'thursday' },
  { label: 'Fri', value: 'friday' },
];
</script>

<template>
  <FzCheckboxGroup
    v-model="selectedDays"
    label="Working Days"
    :options="dayOptions"
    horizontal
  />
</template>

Checkbox Card — Vertical with Image

<script setup lang="ts">
import { ref } from 'vue';
import { FzCheckboxCard } from '@fiscozen/checkbox';

const selected = ref<(string | number)[]>([]);
</script>

<template>
  <div style="display: flex; gap: 16px; max-width: 720px;">
    <FzCheckboxCard
      v-model="selected"
      label="plan-basic"
      value="basic"
      variant="vertical"
      image-url="/images/basic-plan.jpg"
      image-alt="Basic plan illustration"
      title="Basic Plan"
      subtitle="For individuals getting started"
      tooltip="Includes 5 GB storage"
    />

    <FzCheckboxCard
      v-model="selected"
      label="plan-pro"
      value="pro"
      variant="vertical"
      image-url="/images/pro-plan.jpg"
      image-alt="Pro plan illustration"
      title="Pro Plan"
      subtitle="For growing teams"
      tooltip="Includes 50 GB storage"
    />
  </div>
</template>

Checkbox Card — Without Checkbox Icon

<script setup lang="ts">
import { ref } from 'vue';
import { FzCheckboxCard } from '@fiscozen/checkbox';

const selected = ref<(string | number)[]>([]);
</script>

<template>
  <FzCheckboxCard
    v-model="selected"
    label="option"
    value="option"
    title="Selectable Card"
    subtitle="The card border highlights on selection"
    :has-checkbox="false"
  />
</template>

Disabled State

<script setup lang="ts">
import { ref } from 'vue';
import { FzCheckbox, FzCheckboxGroup } from '@fiscozen/checkbox';

const checked = ref(true);
const groupSelection = ref<string[]>(['opt1']);

const options = [
  { label: 'Option 1', value: 'opt1' },
  { label: 'Option 2', value: 'opt2' },
];
</script>

<template>
  <div>
    <!-- Disabled single checkbox -->
    <FzCheckbox
      v-model="checked"
      label="This is disabled"
      disabled
    />
    
    <!-- Disabled group -->
    <FzCheckboxGroup
      v-model="groupSelection"
      label="Disabled Group"
      :options="options"
      disabled
    />
  </div>
</template>

With Form Validation

<script setup lang="ts">
import { ref, computed } from 'vue';
import { FzCheckboxGroup } from '@fiscozen/checkbox';

const selectedOptions = ref<string[]>([]);
const touched = ref(false);

const options = [
  { label: 'Option A', value: 'a' },
  { label: 'Option B', value: 'b' },
  { label: 'Option C', value: 'c' },
];

const hasError = computed(() => 
  touched.value && selectedOptions.value.length === 0
);

function handleBlur() {
  touched.value = true;
}
</script>

<template>
  <div @blur="handleBlur">
    <FzCheckboxGroup
      v-model="selectedOptions"
      label="Required Selection"
      :options="options"
      required
      :error="hasError"
    >
      <template #help>
        <span>Select at least one option</span>
      </template>
      
      <template #error>
        <span>Please select at least one option to continue</span>
      </template>
    </FzCheckboxGroup>
  </div>
</template>

TypeScript Support

This package is written in TypeScript and provides full type definitions.

import type { 
  FzCheckboxProps, 
  FzCheckboxGroupProps,
  FzCheckboxCardProps,
  ParentCheckbox,
  ChildCheckbox 
} from '@fiscozen/checkbox';

// Example: Typed options array
const options: ParentCheckbox[] = [
  {
    label: 'Parent Option',
    value: 'parent',
    children: [
      { label: 'Child 1', value: 'child1' },
      { label: 'Child 2', value: 'child2' }
    ]
  }
];

// Example: Typed card props (vertical variant requires imageUrl)
const verticalCard: FzCheckboxCardProps = {
  label: 'card',
  title: 'Card Title',
  subtitle: 'Description',
  variant: 'vertical',
  imageUrl: '/images/card.jpg',
};

Accessibility Features

WCAG 2.1 AA Compliance

This component implements comprehensive accessibility features following WCAG 2.1 Level AA guidelines:

  • Keyboard Navigation - Full support for Tab and Space key interactions
  • Screen Reader Support - Proper ARIA roles, labels, and state announcements
  • Focus Management - Visible focus indicators meeting 3:1 contrast ratio requirements
  • Error Handling - Live region announcements for dynamic validation messages
  • Semantic Markup - Native checkbox inputs with accessible label associations

Keyboard Interactions

| Key | Action | |-----|--------| | Tab | Move focus to next checkbox | | Shift + Tab | Move focus to previous checkbox | | Space | Toggle checkbox state |

Screen Reader Behavior

The component provides rich semantic information to assistive technologies:

  • State Announcements - "checked", "unchecked", or "mixed" (indeterminate)
  • Label Associations - aria-labelledby and aria-label for proper identification
  • Error Messages - aria-describedby linking to error content with role="alert"
  • Group Context - role="group" with aria-labelledby for related checkbox sets
  • Hierarchical Relationships - aria-owns establishing parent-child checkbox connections
  • Required Fields - aria-required indicating mandatory selections
  • Validation State - aria-invalid signaling validation errors

Focus Indicators

  • Focus ring appears as blue border around checkbox icon
  • Meets WCAG 3:1 contrast ratio requirement against background
  • Visible in all states: default, hover, checked, indeterminate
  • Tab order follows logical DOM structure