ToggleButton
A ToggleButton is a button that can be toggled on and off.
Guidelines
When to use toggle buttons
Toggle buttons feature a normal and an “on” state. They generally contain a label and can also include an icon. For icon-only buttons, the label will be visually hidden while still available to screen reader users.
There are two types of toggle buttons: normal and quiet. There is no toggle button variant designed for progressive or destructive actions.
Use the ToggleButton component for options that require state persistence and are longer or more involved than a typical button click action. Avoid using ToggleButton if you need to trigger an immediate action or toggle something within the current user context; in this case use a Button instead.
Specifications
ToggleButton may include the following elements:
- Icon (optional)
Icons simplify user recognition and provide the ability to shorten button labels to a minimum. - Label
Button labels should be as short as possible, with text that clearly states what state is changed when toggling the button (eg. show/hide). Note that the label text should not change depending on the button’s toggled state.
Component limitations
The minimum width and height for both icon and text toggle buttons is min-size-interactive-pointer
token (equivalent to 32px
in the default Codex theme). The toggle button will adjust to fit the expanding text but will halt growth at a maximum width of max-width-button
(equivalent to 448px
in the default Codex theme). An ellipsis will appear to accommodate the text if necessary.
On mobile, toggle buttons should span the full-width of the container, except for icon-only buttons, which will maintain their fixed square proportions.
Refer to the ToggleButton component in Codex Figma.
Types
Depending on the style of the button, there are two types of toggle buttons:
- Normal toggle buttons. They are the default choice for simplified recognition.
- Quiet toggle buttons (frameless). Only use quiet toggle buttons for an easily recognizable action that does not detract focus from the content.
Depending on the button's content, it can have one of the following formats:
- Icon and text
- Text-only
- Icon-only
Interaction states
Buttons have the following visually separate states:
Neutral buttons
Quiet buttons
- Toggled-off default
- Toggled-off hover
- Toggled-off active
- Toggled-off focus
- Toggled-off disabled
- Toggled-on default
- Toggled-on hover
- Toggled-on active
- Toggled-on focus
- Toggled-on disabled
Best practices
Consider the following recommendations when working with toggle buttons.
Icon
- Ensure that icons used in buttons are relevant to the action they represent.
- Use icons only when they are clear and easily recognizable.
- Use icons that are difficult to understand or do not clearly convey their purpose.
Toggle state
- Maintain consistent text and icon representation across both default and toggled button states to indicate state changes solely through button color.
- Alter the icon and/or text when the button is toggled.
Keyboard navigation
Key | Function |
---|---|
Tab | It moves the focus to the next interactive element. |
Shift + Tab | It moves the focus to the previous interactive element. |
Enter / Space | If the focus is placed on the button, it toggles the button on and off. |
Demos
Configurable
<cdx-toggle-button v-model="buttonValue">Button text</cdx-toggle-button>
Name | Value |
---|---|
Props | |
disabled | |
quiet | |
Slots | |
default | |
View | |
Reading direction |
Default
Press the ToggleButton to see the value change. Open up the console to see emitted events.
ToggleButtons should always have a static label. This helps indicate to the user (including users of assistive technology) what it means for the button to be on or off. If you want a button with a label that changes when it is pressed, use the Button component instead.
Toggle button value: false
<template>
<div>
<p class="cdx-docs-demo-text">
Toggle button value: {{ buttonValue }}
</p>
<cdx-toggle-button
v-model="buttonValue"
@update:model-value="onUpdate"
>
<cdx-icon :icon="cdxIconPlay" />
Play
</cdx-toggle-button>
</div>
</template>
<script>
import { defineComponent, ref } from 'vue';
import { CdxToggleButton, CdxIcon } from '@wikimedia/codex';
import { cdxIconPlay } from '@wikimedia/codex-icons';
export default defineComponent( {
name: 'SingleButton',
components: { CdxToggleButton, CdxIcon },
setup() {
const buttonValue = ref( false );
const onUpdate = function ( value ) {
// eslint-disable-next-line no-console
console.log( 'update:modelValue event emitted with value: ' + value );
};
return {
buttonValue,
onUpdate,
cdxIconPlay
};
}
} );
</script>
<template>
<div>
<p class="cdx-docs-demo-text">
Toggle button value: {{ buttonValue }}
</p>
<cdx-toggle-button
v-model="buttonValue"
@update:model-value="onUpdate"
>
<cdx-icon :icon="cdxIconPlay"></cdx-icon>
Play
</cdx-toggle-button>
</div>
</template>
<script>
const { defineComponent, ref } = require( 'vue' );
const { CdxToggleButton, CdxIcon } = require( '@wikimedia/codex' );
const { cdxIconPlay } = require( './icons.json' );
module.exports = defineComponent( {
name: 'SingleButton',
components: { CdxToggleButton, CdxIcon },
setup() {
const buttonValue = ref( false );
const onUpdate = function ( value ) {
// eslint-disable-next-line no-console
console.log( 'update:modelValue event emitted with value: ' + value );
};
return {
buttonValue,
onUpdate,
cdxIconPlay
};
}
} );
</script>
Icon only
When the ToggleButton includes only an icon and no text, add an aria-label
to the ToggleButton to ensure the button is understandable to those using assistive technology.
<template>
<div>
<cdx-toggle-button
v-model="buttonValue"
aria-label="Play"
>
<cdx-icon :icon="cdxIconPlay" />
</cdx-toggle-button>
</div>
</template>
<script>
import { defineComponent, ref } from 'vue';
import { CdxToggleButton, CdxIcon } from '@wikimedia/codex';
import { cdxIconPlay } from '@wikimedia/codex-icons';
export default defineComponent( {
name: 'IconOnlyButton',
components: { CdxToggleButton, CdxIcon },
setup() {
const buttonValue = ref( false );
return {
buttonValue,
cdxIconPlay
};
}
} );
</script>
<template>
<div>
<cdx-toggle-button
v-model="buttonValue"
aria-label="Play"
>
<cdx-icon :icon="cdxIconPlay"></cdx-icon>
</cdx-toggle-button>
</div>
</template>
<script>
const { defineComponent, ref } = require( 'vue' );
const { CdxToggleButton, CdxIcon } = require( '@wikimedia/codex' );
const { cdxIconPlay } = require( './icons.json' );
module.exports = defineComponent( {
name: 'IconOnlyButton',
components: { CdxToggleButton, CdxIcon },
setup() {
const buttonValue = ref( false );
return {
buttonValue,
cdxIconPlay
};
}
} );
</script>
Vue usage
The v-model
value will be a boolean, it is true
if the button is currently toggled ("on") and false
otherwise ("off").
Props
Prop name | Description | Type | Default |
---|---|---|---|
modelValue | Whether the button should be set to "on" (true) or "off" (false). Provided by v-model binding in the parent component. | boolean | false |
disabled | Whether the disabled attribute should be added to the button, which prevents it from being clicked. | boolean | false |
quiet | Whether the toggle button should be "quiet", which renders more minimally. | boolean | false |
Events
Event name | Properties | Description |
---|---|---|
update:modelValue | modelValue boolean - The new model value | Emitted when modelValue changes (i.e. when the state is toggled) |
Slots
Name | Description | Bindings |
---|---|---|
default | Button content |