Choice Inputs
ChoiceInput
component allows you to make choices via the checkbox
and radio
elements.
Navigation
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
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
:
Usage
React
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
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
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 (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.