diff --git a/.github/COMPONENT-GUIDE.md b/.github/COMPONENT-GUIDE.md index 7446518da8..b9181ab25f 100644 --- a/.github/COMPONENT-GUIDE.md +++ b/.github/COMPONENT-GUIDE.md @@ -9,6 +9,7 @@ * [Ripple Effect](#ripple-effect) * [Example Components](#example-components) * [References](#references) +- [Accessibility](#accessibility) - [Rendering Anchor or Button](#rendering-anchor-or-button) * [Example Components](#example-components-1) * [Component Structure](#component-structure-1) @@ -362,6 +363,130 @@ ion-ripple-effect { - [iOS Buttons](https://developer.apple.com/design/human-interface-guidelines/ios/controls/buttons/) +## Accessibility + +### Checkbox + +#### Example Components + +- [ion-checkbox](https://github.com/ionic-team/ionic/tree/master/core/src/components/checkbox) + +#### VoiceOver + +In order for VoiceOver to work properly with a checkbox component there must be a native `input` with `type="checkbox"`, and `aria-checked` and `role="checkbox"` **must** be on the host element. The `aria-hidden` attribute needs to be added if the checkbox is disabled, preventing iOS users from selecting it: + +```tsx +render() { + const { checked, disabled } = this; + + return ( + + + ... + + ); +} +``` + +#### NVDA + +It is required to have `aria-checked` on the native input for checked to read properly and `disabled` to prevent tabbing to the input: + +```tsx +render() { + const { checked, disabled } = this; + + return ( + + + ... + + ); +} +``` + +#### Labels + +A helper function has been created to get the proper `aria-label` for the checkbox. This can be imported as `getAriaLabel` like the following: + +```tsx +const { label, labelId, labelText } = getAriaLabel(el, inputId); +``` + +where `el` and `inputId` are the following: + +```tsx +private inputId = `ion-cb-${checkboxIds++}`; + +@Element() el!: HTMLElement; +``` + +This can then be added to the `Host` like the following: + +```tsx + +``` + +In addition to that, the checkbox should have a label added: + +```tsx + + + +``` + +#### Hidden Input + +A helper function to render a hidden input has been added, it can be added in the `render`: + +```tsx +renderHiddenInput(true, el, name, (checked ? value : ''), disabled); +``` + +> This is required for the checkbox to work with forms. + +#### Known Issues + +When using VoiceOver on macOS, Chrome will announce the following when you are focused on a checkbox: + +``` +currently on a checkbox inside of a checkbox +``` + +This is a compromise we have to make in order for it to work with the other screen readers & Safari. + + ## Rendering Anchor or Button Certain components can render an `` or a ` + + this.onFocus()} + onBlur={() => this.onBlur()} + ref={focusEl => this.focusEl = focusEl} + /> ); } diff --git a/core/src/components/checkbox/readme.md b/core/src/components/checkbox/readme.md index 2a511fac36..eeb6daa7fe 100644 --- a/core/src/components/checkbox/readme.md +++ b/core/src/components/checkbox/readme.md @@ -266,16 +266,16 @@ export default defineComponent({ | `indeterminate` | `indeterminate` | If `true`, the checkbox will visually appear as indeterminate. | `boolean` | `false` | | `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` | | `name` | `name` | The name of the control, which is submitted with the form data. | `string` | `this.inputId` | -| `value` | `value` | The value of the toggle does not mean if it's checked or not, use the `checked` property for that. The value of a toggle is analogous to the value of a ``, it's only used when the toggle participates in a native ``. | `string` | `'on'` | +| `value` | `value` | The value of the checkbox does not mean if it's checked or not, use the `checked` property for that. The value of a checkbox is analogous to the value of an ``, it's only used when the checkbox participates in a native ``. | `string` | `'on'` | ## Events | Event | Description | Type | | ----------- | ---------------------------------------------- | ---------------------------------------- | -| `ionBlur` | Emitted when the toggle loses focus. | `CustomEvent` | +| `ionBlur` | Emitted when the checkbox loses focus. | `CustomEvent` | | `ionChange` | Emitted when the checked property has changed. | `CustomEvent` | -| `ionFocus` | Emitted when the toggle has focus. | `CustomEvent` | +| `ionFocus` | Emitted when the checkbox has focus. | `CustomEvent` | ## Shadow Parts diff --git a/core/src/components/checkbox/test/basic/index.html b/core/src/components/checkbox/test/basic/index.html index b9d7ce9f2d..63a66d0c76 100644 --- a/core/src/components/checkbox/test/basic/index.html +++ b/core/src/components/checkbox/test/basic/index.html @@ -38,7 +38,7 @@ Secondary - + @@ -103,6 +103,31 @@ + + + diff --git a/core/src/components/checkbox/test/indeterminate/index.html b/core/src/components/checkbox/test/indeterminate/index.html index 714dbd532a..5223301ac2 100644 --- a/core/src/components/checkbox/test/indeterminate/index.html +++ b/core/src/components/checkbox/test/indeterminate/index.html @@ -31,22 +31,22 @@
- +
- +
- +
- +
@@ -81,15 +81,15 @@
- - - - - - - - - + + + + + + + + +
@@ -100,20 +100,20 @@
  • - - + +
    • - - + +
    • - - + +
    • - - + +
  • diff --git a/core/src/components/checkbox/test/standalone/index.html b/core/src/components/checkbox/test/standalone/index.html index f5569c0fe6..b73d0c75dd 100644 --- a/core/src/components/checkbox/test/standalone/index.html +++ b/core/src/components/checkbox/test/standalone/index.html @@ -13,67 +13,67 @@

    Default

    - - - - + + + +

    Colors

    - - - - - - - - - + + + + + + + + +
    - - - - - - - - - + + + + + + + + +
    - - - - - - - - - + + + + + + + + +

    Custom

    - - - - + + + +

    Custom: checked

    - - - - + + + +

    Custom: light

    - - - - + + + +

    Custom: transition

    - - + +