Choice Inputs

ChoiceInput component allows you to make choices via the checkbox and radio elements.

As a baseline, let's have a look at some examples from the Web Accessibility Initiative

Checkboxes

Looking at the wai-aria practices checkbox example we see that the TAB key is used to tab into the group of checkbox elements, but, is also used to navigate within those checkbox elements.

Radios

Looking at the wai-aria-practices radio example we see that the TAB key is used to tab into the group of radio elements; but then, the Arrow keys are used to navigate within those radio elements.

AgnosticUI's ChoiceInput uses the same keyboard navigation strategy as above.

Examples

Radio
Large
Checkbox with specific options disabled

Pass false to :is-fieldset (Vue) or isFieldset (React, Svelte) to hide the fieldset from sighted users. Also, we can use a reactive boolean ref to toggle button's isDisabled:

Large

Usage

astro logo

React, Vue, and Svelte examples on a single playground page 🚀 💥

react logoReact

View source
import "agnostic-react/dist/common.min.css";
import "agnostic-react/dist/esm/index.css";
import { ChoiceInput } from "agnostic-react";

const opts = [
  {
    value: "daily",
    label: "Daily",
  },
  {
    value: "weekly",
    label: "Weekly",
  },
  {
    value: "monthly",
    label: "Monthly",
  },
];
const optionNames = ['frequency', 'schedule', 'howoften', 'when', 'letmeknow', 'whenz', 'often', 'freq', 'frekuency', 'whattimes']
const options = []
for (let i = 0; i < optionNames.length; i += 1) {
  const optionName = optionNames[i];
  const optionsWithNames = []
  opts.forEach(o => {
    const copy = Object.assign({}, o, { name: optionName })
    optionsWithNames.push(copy);
  })
  options.push(optionsWithNames);
}
const disabledOptions = ['weekly', 'monthly'];

export const YourComponent = () => (

  const handleChange = checkedItems => console.log(checkedItems)

  <section>
    <ChoiceInput
      id="1"
      type="checkbox"
      options={options[0]}
      legendLabel="Checkbox legend"
      onChange={ handleChange }
    />
    <ChoiceInput
      id="2"
      isDisabled
      type="checkbox"
      options={options[1]}
      legendLabel="Checkbox disabled"
      onChange={ handleChange }
    />
    <ChoiceInput
      id="3"
      disabledOptions={disabledOptions}
      type="checkbox"
      options={options[2]}
      legendLabel="Checkbox specific options disabled"
      onChange={ handleChange }
    />
    <ChoiceInput
      id="4"
      type="checkbox"
      isFieldset={false}
      options={options[3]}
      legendLabel="Checkbox fieldset hidden"
      onChange={ handleChange }
    />
    <ChoiceInput
      id="5"
      type="checkbox"
      isInline
      options={options[4]}
      legendLabel="Checkbox inline"
      onChange={ handleChange }
    />
    <ChoiceInput
      id="6"
      type="checkbox"
      isInline
      size="small"
      options={options[5]}
      legendLabel="Checkbox small"
      onChange={ handleChange }
    />
    <ChoiceInput
      id="7"
      type="checkbox"
      isInline
      size="large"
      options={options[6]}
      legendLabel="Checkbox large"
      onChange={ handleChange }
    />
    <ChoiceInput
      id="8"
      type="checkbox"
      isInline
      size="large"
      checkedOptions={["daily", "weekly"]}
      options={options[7]}
      legendLabel="Checkbox prechecked options"
      onChange={ handleChange }
    />
    <ChoiceInput
      id="10"
      type="radio"
      options={options[8]}
      legendLabel="Radio legend"
      onChange={ handleChange }
    />
    <ChoiceInput
      id="11"
      isDisabled
      type="radio"
      options={options[9]}
      legendLabel="Radio disabled"
      onChange={ handleChange }
    />
    <ChoiceInput
      id="12"
      disabledOptions={['two']}
      type="radio"
      options={[
        {
          name: 'numbers',
          value: 'one',
          label: 'one',
        },
        {
          name: 'numbers',
          value: 'two',
          label: 'two',
        },
        {
          name: 'numbers',
          value: 'three',
          label: 'three',
        },
      ]}
      legendLabel="Radio specific options disabled"
      onChange={ handleChange }
    />
    <ChoiceInput
      id="14"
      type="radio"
      isInline
      size="small"
      options={[
        {
          name: 'shape',
          value: 'square',
          label: 'Square',
        },
        {
          name: 'shape',
          value: 'circle',
          label: 'Circle',
        },
      ]}
      legendLabel="Radio small"
      onChange={ handleChange }
    />
    <ChoiceInput
      id="15"
      type="radio"
      isInline
      size="large"
      options={[
        {
          name: 'bands',
          value: 'bonjovi',
          label: 'Bon Jovi',
        },
        {
          name: 'bands',
          value: 'stones',
          label: 'Rolling Stones',
        },
        {
          name: 'bands',
          value: 'isleybros',
          label: 'Isley Brothers',
        },
      ]}
      legendLabel="Radio large"
      onChange={ handleChange }
    />
  </section>
);

React: component source, storybook tests

Vue 3 logoVue 3

View source
<script setup>
// Import AgnosticUI global common & component CSS
import "agnostic-vue/dist/common.min.css";
import "agnostic-vue/dist/index.css";
import { ChoiceInput } from "agnostic-vue";
const log = (message, extra) => console.log(message, extra)
</script>
<template>
  <section>
    <ChoiceInput
      id="r1"
      type="radio"
      legend-label="Radio"
      @change="(checkedOptions) => log('ChoiceInput (radio) checkedOptions:', checkedOptions)"
      :options="[
        { name: 'solo', value: 'stevie', label: 'Stevie Wonder' },
        { name: 'solo', value: 'whitney', label: 'Whitney Houston' },
        { name: 'solo', value: 'charlie', label: 'Charlie Wilson' },
      ]"
    />
    <ChoiceInput
      id="c1"
      type="checkbox"
      :options="[
        { name: 'bands', value: 'bonjovi', label: 'Bon Jovi' },
        { name: 'bands', value: 'stones', label: 'Rolling Stones' },
        { name: 'bands', value: 'isleybros', label: 'Isley Brothers' },
      ]"
      legend-label="Large"
      size="large"
      is-inline
    />
    <ChoiceInput
      id="c2"
      type="checkbox"
      legend-label="Checkbox with disabled options"
      :disabledOptions="['stones', 'isleybros']"
      @change="(checkedOptions) => log('ChoiceInput (checkbox) checkedOptions:', checkedOptions)"
      :options="[
        { name: 'bands', value: 'bonjovi', label: 'Bon Jovi'},
        { name: 'bands', value: 'stones', label: 'Rolling Stones' },
        { name: 'bands', value: 'isleybros', label: 'Isley Brothers' }
        { name: 'bands', value: 'parliament', label: 'Parliament-Funkadelic' }
      ]"
    />
  </section>
</template>

Vue 3: component source, storybook tests

Svelte logoSvelte

View source
<script>
  import "agnostic-svelte/css/common.min.css";
  import { ChoiceInput } from "agnostic-svelte";
  let disabledOptions = ["monthly", "weekly"];
  const opts = [
		{
			value: "daily",
			label: "Daily",
		},
		{
			value: "weekly",
			label: "Weekly",
		},
		{
			value: "monthly",
			label: "Monthly",
		},
	];
  const optionNames = ['frequency', 'schedule', 'howoften']
  const options = []
  for (let i = 0; i < optionNames.length; i += 1) {
    const optionName = optionNames[i];
    const optionsWithNames = []
    opts.forEach(o => {
      const copy = Object.assign({}, o, { name: optionName })
      optionsWithNames.push(copy);
    })
    options.push(optionsWithNames);
  }
</script>
<section>
  <ChoiceInput type="checkbox" isInline options={options[0]} />
  <ChoiceInput type="checkbox" options={options[1]}
    disabledOptions=["daily"] legendLabel="Checkbox with specific options disabled" />
  <ChoiceInput type="radio" isInline options={options[2]} />
  <ChoiceInput type="radio" size="large" legendLabel="Radio large"
    options={options[3]} checkedOptions=["weekly"] disabledOptions=["daily", "monthly"] />
</section>

Svelte: component source, storybook tests

Angular logoAngular (Experimental)

View source

In your Angular configuration (likely angular.json) ensure you're including the common AgnosticUI styles:

"styles": ["agnostic-angular/common.min.css"],

Add AgnosticUI's AgModule module:



 





 





import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AgModule } from 'agnostic-angular';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, AgModule],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

Now you can use in your components:

import { Component } from '@angular/core';

@Component({
  selector: 'your-component',
  template: `<section>
    <ag-choice-input
      type="checkbox"
      [options]="testOptions"
      legendLabel="Legend"
      (selected)="handleChange"
    ></ag-choice-input>
    <ag-choice-input
      type="checkbox"
      [isDisabled]="true"
      [options]="testOptions"
      legendLabel="Disabled"
      (selected)="handleChange"
    ></ag-choice-input>
    <ag-choice-input
      type="checkbox"
      [options]="testOptions"
      [disabledOptions]="disabledOptions"
      legendLabel="Specific options disabled"
      (selected)="handleChange"
    ></ag-choice-input>
    <ag-choice-input
      type="checkbox"
      [options]="testOptions"
      [disabledOptions]="disabledOptions"
      [isFieldset]="false"
      legendLabel="Fieldset hidden"
      (selected)="handleChange"
    ></ag-choice-input>
    <ag-choice-input
      type="checkbox"
      [options]="testOptions"
      [isInline]="true"
      legendLabel="Inline"
      (selected)="handleChange"
    ></ag-choice-input>
    <ag-choice-input
      type="checkbox"
      [options]="testOptions"
      [isInline]="true"
      size="small"
      legendLabel="Small"
      (selected)="handleChange"
    ></ag-choice-input>
    <ag-choice-input
      type="checkbox"
      [options]="testOptions"
      [isInline]="true"
      size="large"
      legendLabel="Large"
      (selected)="handleChange"
    ></ag-choice-input>
    <ag-choice-input
      type="checkbox"
      [options]="testOptions"
      checkedOptions="['daily', 'weekly']"
      [isInline]="true"
      size="large"
      legendLabel="Prechecked options"
      (selected)="handleChange"
    ></ag-choice-input>
    <ag-choice-input
      [options]="testOptions"
      [isSkinned]="false"
      [isInline]="true"
      legendLabel="Checkbox unskinned (fieldset and legend unstyled)"
      (selected)="handleChange"
    ></ag-choice-input>
    <h1 style="margin: 1rem 0;">Radios</h1>
    <ag-choice-input
      type="radio"
      [options]="testOptions"
      legendLabel="Radio legend"
      (selected)="handleChange"
    ></ag-choice-input>
    <ag-choice-input
      type="radio"
      [options]="testOptions"
      [isDisabled]="true"
      legendLabel="Disabled"
      (selected)="handleChange"
    ></ag-choice-input>
    <ag-choice-input
      type="radio"
      [options]="[{ name: 'numbers', value: 'one', label: 'one'}, { name: 'numbers', value: 'two', label: 'two' }, { name: 'numbers', value: 'three', label: 'three' }]"
      [disabledOptions]="['two']"
      legendLabel="Specific options disabled"
      (selected)="handleChange"
    ></ag-choice-input>
    <ag-choice-input
      type="radio"
      [options]="[{ name: 'es', value: 'uno', label: 'uno'}, { name: 'es', value: 'dos', label: 'dos' }, { name: 'es', value: 'tres', label: 'tres' }]"
      legendLabel="Fieldset hidden"
      [isFieldset]="false"
      (selected)="handleChange"
    ></ag-choice-input>
    <ag-choice-input
      type="radio"
      [options]="[{ name: 'colors', value: 'blue', label: 'Blue'}, { name: 'colors', value: 'red', label: 'Red' }, { name: 'colors', value: 'silver', label: 'Silver' }]"
      legendLabel="Inline"
      [isInline]="true"
      (selected)="handleChange"
    ></ag-choice-input>
    <ag-choice-input
      type="radio"
      [options]="[{ name: 'bands', value: 'bonjovi', label: 'Bon Jovi'}, { name: 'bands', value: 'stones', label: 'Rolling Stones' }, { name: 'bands', value: 'isleybros', label: 'Isley Brothers' }]"
      legendLabel="Large"
      size="large"
      [isInline]="true"
      (selected)="handleChange"
    ></ag-choice-input>
    <ag-choice-input
      type="radio"
      [options]="[{ name: 'solo', value: 'stevie', label: 'Stevie Wonder'}, { name: 'solo', value: 'whitney', label: 'Whitney Houston' }, { name: 'solo', value: 'charlie', label: 'Charlie Wilson' }]"
      [checkedOptions]="['charlie']"
      legendLabel="Prechecked option"
      size="large"
      [isInline]="true"
      (selected)="handleChange"
    ></ag-choice-input>
  </section>`
})
export class YourComponent {
  private disabledOptions: string[] = ['weekly', 'monthly'];
  private testOptions: string[] = [
    {
      name: 'frequency',
      value: 'daily',
      label: 'Daily',
    },
    {
      name: 'frequency',
      value: 'weekly',
      label: 'Weekly',
    },
    {
      name: 'frequency',
      value: 'monthly',
      label: 'Monthly',
    },
  ];
  handleChange(changedItems: string[]) {}
}

Angular: component source, storybook tests

Storybook

You can run the framework Storybooks and see live examples for React, Vue 3, Svelte, Astro, and Angular (experimental). The following will set up Storybook and run locally:

How to run Storybook
git clone git@github.com:AgnosticUI/agnosticui.git
cd agnosticui/<PACKAGE_NAME> && npm i # e.g. cd agnosticui/agnostic-react && npm i
npm run storybook

See Running Storybook.