diff --git a/.changeset/fix-IndeterminateCheckbox.md b/.changeset/fix-IndeterminateCheckbox.md new file mode 100644 index 000000000..05cf02e7b --- /dev/null +++ b/.changeset/fix-IndeterminateCheckbox.md @@ -0,0 +1,5 @@ +--- +'react-magma-dom': patch +--- + +fix(Indeterminate Checkbox): Fixed issue with voice over not recognizing the mixed state when using keyboard navigation. diff --git a/packages/react-magma-dom/src/components/IndeterminateCheckbox/IndeterminateCheckbox.stories.tsx b/packages/react-magma-dom/src/components/IndeterminateCheckbox/IndeterminateCheckbox.stories.tsx index 9cd4829b0..71000bd74 100644 --- a/packages/react-magma-dom/src/components/IndeterminateCheckbox/IndeterminateCheckbox.stories.tsx +++ b/packages/react-magma-dom/src/components/IndeterminateCheckbox/IndeterminateCheckbox.stories.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Card, CardBody } from '../Card'; +import { Container } from '../Container'; import { Checkbox } from '../Checkbox'; import { FormGroup } from '../FormGroup'; import { @@ -7,121 +7,135 @@ import { IndeterminateCheckboxStatus, } from '../IndeterminateCheckbox'; import { magma } from '../../theme/magma'; -import { Meta } from '@storybook/react/types-6-0'; +import { Story, Meta } from '@storybook/react/types-6-0'; +import { IndeterminateCheckboxProps } from '../../../dist'; + +const Template: Story = args => ( + + + + + +); export default { component: IndeterminateCheckbox, title: 'Indeterminate Checkbox', + argTypes: { + status: { + control: { type: 'select' }, + options: IndeterminateCheckboxStatus, + }, + isInverse: { + control: { + type: 'boolean', + }, + }, + }, + decorators: [ + (Story, context) => ( + + + + ), + ], } as Meta; -export const Default = () => { - return ( - - - - - - ); -}; - -export const Inverse = () => { - return ( - - - - - - - - - - ); -}; +export const Default = Template.bind({}); +Default.args = {}; export const Behavior = () => { const [checkedItems, setCheckedItems] = React.useState>([ true, false, + false, + false, ]); - const status: IndeterminateCheckboxStatus = checkedItems.every(Boolean) - ? IndeterminateCheckboxStatus.checked - : checkedItems.some(Boolean) - ? IndeterminateCheckboxStatus.indeterminate - : IndeterminateCheckboxStatus.unchecked; + const [status, setStatus] = React.useState( + IndeterminateCheckboxStatus.indeterminate + ); + + function getStatus(items: Array) { + return items.every(Boolean) + ? IndeterminateCheckboxStatus.checked + : items.some(Boolean) + ? IndeterminateCheckboxStatus.indeterminate + : IndeterminateCheckboxStatus.unchecked; + } function handleUpdateIndeterminateChecked( event: React.ChangeEvent ) { - setCheckedItems([event.target.checked, event.target.checked]); + const updatedCheckedItems = Array(4).fill(event.target.checked); + setCheckedItems(updatedCheckedItems); + setStatus(getStatus(updatedCheckedItems)); } - function handleUpdateRedChecked(event: React.ChangeEvent) { - setCheckedItems([event.target.checked, checkedItems[1]]); - } - - function handleUpdateBlueChecked(event: React.ChangeEvent) { - setCheckedItems([checkedItems[0], event.target.checked]); + function handleColorChecked( + index: number, + event: React.ChangeEvent + ) { + const updatedCheckedItems = [...checkedItems]; + updatedCheckedItems[index] = event.target.checked; + setCheckedItems(updatedCheckedItems); + setStatus(getStatus(updatedCheckedItems)); } return ( <> - -
- - + -
+
+ handleColorChecked(0, e)} + labelText="Red" + id="Red" + /> + handleColorChecked(1, e)} + labelText="Blue" + id="Blue" + /> + handleColorChecked(2, e)} + labelText="Green" + id="Green" + /> + handleColorChecked(3, e)} + labelText="Yellow" + id="Yellow" + /> +
+ ); }; diff --git a/packages/react-magma-dom/src/components/IndeterminateCheckbox/index.tsx b/packages/react-magma-dom/src/components/IndeterminateCheckbox/index.tsx index f84a87955..b4c945d21 100644 --- a/packages/react-magma-dom/src/components/IndeterminateCheckbox/index.tsx +++ b/packages/react-magma-dom/src/components/IndeterminateCheckbox/index.tsx @@ -76,6 +76,17 @@ export const IndeterminateCheckbox = React.forwardRef< } } + function handleOnKeyDown(event: React.KeyboardEvent) { + if (event.key === ' ' && !disabled) { + event.preventDefault(); + const syntheticEvent = { + ...event, + target: { checked: !isChecked }, + } as unknown as React.ChangeEvent; + handleChange(syntheticEvent); + } + } + const theme = React.useContext(ThemeContext); const i18n = React.useContext(I18nContext); const context = React.useContext(FormGroupContext); @@ -159,7 +170,9 @@ export const IndeterminateCheckbox = React.forwardRef< ref={ref} type="checkbox" onChange={handleChange} + tabIndex={-1} /> +