diff --git a/CHANGELOG.md b/CHANGELOG.md index 60c8bbf30e..ad8f7b3af6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Add `useStyles()` hook to use theming capabilities in custom components @layershifter, @mnajdova ([#2217](https://github.com/microsoft/fluent-ui-react/pull/2217)) - Add optional wrapper function to `List` which can be used to inject custom scrollbars to `Dropdown` @jurokapsiar ([#2092](https://github.com/microsoft/fluent-ui-react/pull/2092)) - Add `useTelemetry()` hook for adding telemetry information for the Fluent components and improve return types for the `useStyles` and `useStateManager` hooks @mnajdova ([#2257](https://github.com/microsoft/fluent-ui-react/pull/2257)) +- Add `checkboxMultiselect` behavior and example @jurokapsiar ([#2264](https://github.com/microsoft/fluent-ui-react/pull/2264)) ### Documentation - Add per-component performance charts @miroslavstastny ([#2240](https://github.com/microsoft/fluent-ui-react/pull/2240)) diff --git a/docs/src/examples/components/Checkbox/Types/CheckboxListboxExample.shorthand.tsx b/docs/src/examples/components/Checkbox/Types/CheckboxListboxExample.shorthand.tsx new file mode 100644 index 0000000000..0f70f134d8 --- /dev/null +++ b/docs/src/examples/components/Checkbox/Types/CheckboxListboxExample.shorthand.tsx @@ -0,0 +1,13 @@ +import { List, Checkbox, checkboxMultiselectBehavior } from '@fluentui/react' +import * as React from 'react' + +const CheckboxLisboxExample = () => ( + + + + + + +) + +export default CheckboxLisboxExample diff --git a/docs/src/examples/components/Checkbox/Types/index.tsx b/docs/src/examples/components/Checkbox/Types/index.tsx index 6e2c9545e4..1de8426fad 100644 --- a/docs/src/examples/components/Checkbox/Types/index.tsx +++ b/docs/src/examples/components/Checkbox/Types/index.tsx @@ -15,6 +15,11 @@ const Types = () => ( description="A checkbox can be formatted to show an on or off choice." examplePath="components/Checkbox/Types/CheckboxExampleToggle" /> + ) diff --git a/packages/accessibility/src/behaviors/Checkbox/checkboxMultiselectBehavior.ts b/packages/accessibility/src/behaviors/Checkbox/checkboxMultiselectBehavior.ts new file mode 100644 index 0000000000..af3c7fd60f --- /dev/null +++ b/packages/accessibility/src/behaviors/Checkbox/checkboxMultiselectBehavior.ts @@ -0,0 +1,40 @@ +import * as keyboardKey from 'keyboard-key' +import { Accessibility } from '../../types' +import { IS_FOCUSABLE_ATTRIBUTE } from '../../attributes' + +/** + * @description + * Allows grouping of related checkboxes + * Use inside of a container with `role='listbox'` and `aria-multiselectable='true'` + * @specification + * Adds role='option'. This allows screen readers to handle the component as an option in listbox. + * Adds attribute 'aria-selected=true' based on the property 'checked'. + * Adds attribute 'aria-disabled=true' based on the property 'disabled'. + * Adds attribute 'data-is-focusable=true' to 'root' slot. + */ +const checkboxMultiselectBehavior: Accessibility = props => ({ + attributes: { + root: { + 'aria-selected': !!props.checked, + 'aria-disabled': props.disabled, + role: 'option', + [IS_FOCUSABLE_ATTRIBUTE]: true, + }, + }, + keyActions: { + root: { + performClick: { + keyCombinations: [{ keyCode: keyboardKey.Spacebar }], + }, + }, + }, +}) + +export default checkboxMultiselectBehavior + +type CheckboxMultiselectBehaviorProps = { + /** Whether or not item is checked. */ + checked: boolean + /** If the checkbox is in disabled state. */ + disabled?: boolean +} diff --git a/packages/accessibility/src/behaviors/index.ts b/packages/accessibility/src/behaviors/index.ts index a8584fe8dc..06456a74e6 100644 --- a/packages/accessibility/src/behaviors/index.ts +++ b/packages/accessibility/src/behaviors/index.ts @@ -50,6 +50,7 @@ export { default as accordionBehavior } from './Accordion/accordionBehavior' export { default as accordionTitleBehavior } from './Accordion/accordionTitleBehavior' export { default as accordionContentBehavior } from './Accordion/accordionContentBehavior' export { default as checkboxBehavior } from './Checkbox/checkboxBehavior' +export { default as checkboxMultiselectBehavior } from './Checkbox/checkboxMultiselectBehavior' export { default as tooltipAsDescriptionBehavior } from './Tooltip/tooltipAsDescriptionBehavior' export { default as tooltipAsLabelBehavior } from './Tooltip/tooltipAsLabelBehavior' export { default as sliderBehavior } from './Slider/sliderBehavior' diff --git a/packages/accessibility/test/behaviors/behavior-test.tsx b/packages/accessibility/test/behaviors/behavior-test.tsx index 32125a553e..d117f86ef8 100644 --- a/packages/accessibility/test/behaviors/behavior-test.tsx +++ b/packages/accessibility/test/behaviors/behavior-test.tsx @@ -10,6 +10,7 @@ import { basicListItemBehavior, buttonBehavior, checkboxBehavior, + checkboxMultiselectBehavior, embedBehavior, iconBehavior, imageBehavior, @@ -93,6 +94,7 @@ testHelper.addBehavior('basicListBehavior', basicListBehavior) testHelper.addBehavior('basicListItemBehavior', basicListItemBehavior) testHelper.addBehavior('buttonBehavior', buttonBehavior) testHelper.addBehavior('checkboxBehavior', checkboxBehavior) +testHelper.addBehavior('checkboxMultiselectBehavior', checkboxMultiselectBehavior) testHelper.addBehavior('embedBehavior', embedBehavior) testHelper.addBehavior('iconBehavior', iconBehavior) testHelper.addBehavior('inputBehavior', inputBehavior)