chore: improve a11y of traffic chart style selection
This commit is contained in:
parent
71646e2881
commit
10f6e708e5
5 changed files with 52 additions and 30 deletions
|
@ -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}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -123,10 +123,12 @@ export function switchTheme() {
|
|||
};
|
||||
}
|
||||
|
||||
export function selectChartStyleIndex(selectedChartStyleIndex: number) {
|
||||
export function selectChartStyleIndex(
|
||||
selectedChartStyleIndex: number | string
|
||||
) {
|
||||
return (dispatch: DispatchFn, getState: GetStateFn) => {
|
||||
dispatch('appSelectChartStyleIndex', (s) => {
|
||||
s.app.selectedChartStyleIndex = selectedChartStyleIndex;
|
||||
s.app.selectedChartStyleIndex = Number(selectedChartStyleIndex);
|
||||
});
|
||||
// side effect
|
||||
saveState(getState().app);
|
||||
|
|
Loading…
Reference in a new issue