diff options
| author | Haishan <[email protected]> | 2020-11-21 23:31:14 +0800 |
|---|---|---|
| committer | Haishan <[email protected]> | 2020-11-21 23:31:14 +0800 |
| commit | 10f6e708e5a5b7fe68d30b86aeaf455d1e1d7daa (patch) | |
| tree | be1006dc9820658a33efd4487da4b28f0aadb5ea /src/components | |
| parent | 71646e2881ba221788c0ca16d05137ed8f191fae (diff) | |
chore: improve a11y of traffic chart style selection
Diffstat (limited to 'src/components')
| -rw-r--r-- | src/components/Config.tsx | 4 | ||||
| -rw-r--r-- | src/components/Root.css | 12 | ||||
| -rw-r--r-- | src/components/Selection.module.css | 21 | ||||
| -rw-r--r-- | src/components/Selection.tsx | 39 |
4 files changed, 48 insertions, 28 deletions
diff --git a/src/components/Config.tsx b/src/components/Config.tsx index 16fc6b1..2bbfbee 100644 --- a/src/components/Config.tsx +++ b/src/components/Config.tsx @@ -12,7 +12,7 @@ import Button from './Button'; import s0 from './Config.module.css'; import ContentHeader from './ContentHeader'; import Input, { SelfControlledInput } from './Input'; -import Selection from './Selection'; +import { Selection2 } from './Selection'; import { connect, useStoreActions } from './StateProvider'; import Switch from './SwitchThemed'; import ToggleSwitch from './ToggleSwitch'; @@ -243,7 +243,7 @@ function ConfigImpl({ <div className={s0.section}> <div> <div className={s0.label}>Chart Style</div> - <Selection + <Selection2 OptionComponent={TrafficChartSample} optionPropsList={propsList} selectedIndex={selectedChartStyleIndex} diff --git a/src/components/Root.css b/src/components/Root.css index fe837de..39562cf 100644 --- a/src/components/Root.css +++ b/src/components/Root.css @@ -156,10 +156,20 @@ body.light { justify-content: center; } -/* TODO remove fabgrp in component css files */ .fabgrp { position: fixed; z-index: 3; right: 20px; bottom: 20px; } + +.visually-hidden { + position: absolute; + overflow: hidden; + clip: rect(0 0 0 0); + width: 1px; + height: 1px; + margin: -1px; + border: 0; + padding: 0; +} diff --git a/src/components/Selection.module.css b/src/components/Selection.module.css index c5181ca..ba47089 100644 --- a/src/components/Selection.module.css +++ b/src/components/Selection.module.css @@ -1,16 +1,23 @@ -.root { +.fieldset { + margin: 0; + padding: 0; + border: 0; display: flex; flex-wrap: wrap; } -.item { - flex-grow: 0; - margin-right: 10px; - margin-bottom: 10px; +.input + .cnt { + border: 1px solid transparent; + border-radius: 8px; cursor: pointer; - border: 2px solid transparent; + margin-right: 5px; + margin-bottom: 5px; } -.itemActive { +.input:focus + .cnt { + border-color: #387cec; +} + +.input:checked + .cnt { border-color: #387cec; } diff --git a/src/components/Selection.tsx b/src/components/Selection.tsx index 92360c7..27e5e0e 100644 --- a/src/components/Selection.tsx +++ b/src/components/Selection.tsx @@ -10,34 +10,37 @@ type SelectionProps = { onChange?: (...args: any[]) => any; }; -export default function Selection({ +export function Selection2({ OptionComponent, optionPropsList, selectedIndex, onChange, }: SelectionProps) { + const inputCx = cx('visually-hidden', s.input); + const onInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { + onChange(e.target.value); + }; return ( - <div className={s.root}> + <fieldset className={s.fieldset}> {optionPropsList.map((props, idx) => { - const className = cx(s.item, { [s.itemActive]: idx === selectedIndex }); - const doSelect = (ev) => { - ev.preventDefault(); - if (idx !== selectedIndex) onChange(idx); - }; return ( - <div - key={idx} - className={className} - tabIndex={0} - role="menuitem" - onKeyDown={doSelect} - onClick={doSelect} - > - <OptionComponent {...props} /> - </div> + <label key={idx}> + <input + type="radio" + checked={selectedIndex === idx} + name="selection" + value={idx} + aria-labelledby={'traffic chart type ' + idx} + onChange={onInputChange} + className={inputCx} + /> + <div className={s.cnt}> + <OptionComponent {...props} /> + </div> + </label> ); })} - </div> + </fieldset> ); } |
