Skip to content

Commit

Permalink
chore(aria): ♿️ improve progress, meter & accordion accessibility
Browse files Browse the repository at this point in the history
  • Loading branch information
navin-moorthy committed Oct 21, 2020
1 parent e91a07f commit 3d6a77f
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 9 deletions.
35 changes: 32 additions & 3 deletions src/accordion/AccordionTrigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@ export const useAccordionTrigger = createHook<

useProps(
options,
{ onClick: htmlOnClick, onFocus: htmlOnFocus, ...htmlProps },
{
onClick: htmlOnClick,
onKeyDown: htmlOnKeyDown,
onFocus: htmlOnFocus,
...htmlProps
},
) {
const {
manual,
Expand All @@ -61,9 +66,30 @@ export const useAccordionTrigger = createHook<
} = options;
const selected = isAccordionSelected(options);
const accordionPanelId = useAccordionPanelId(options);
const onKeyDownRef = useLiveRef(htmlOnKeyDown);
const onClickRef = useLiveRef(htmlOnClick);
const onFocusRef = useLiveRef(htmlOnFocus);

const onKeyDown = React.useCallback(
(event: React.KeyboardEvent) => {
const first = options.first && (() => setTimeout(options.first));
const last = options.last && (() => setTimeout(options.last));
const keyMap = { Home: first, End: last };
const action = keyMap[event.key as keyof typeof keyMap];
if (action) {
event.preventDefault();
event.stopPropagation();
action();
return;
}

onKeyDownRef.current?.(event);
},

// eslint-disable-next-line react-hooks/exhaustive-deps
[options.first, options.last],
);

const handleSelection = React.useCallback(() => {
if (disabled) return;
if (!id) return;
Expand Down Expand Up @@ -91,7 +117,8 @@ export const useAccordionTrigger = createHook<
handleSelection();
},

[handleSelection, onClickRef],
// eslint-disable-next-line react-hooks/exhaustive-deps
[handleSelection],
);

const onFocus = React.useCallback(
Expand All @@ -103,7 +130,8 @@ export const useAccordionTrigger = createHook<
handleSelection();
},

[onFocusRef, manual, handleSelection],
// eslint-disable-next-line react-hooks/exhaustive-deps
[manual, handleSelection],
);

return {
Expand All @@ -112,6 +140,7 @@ export const useAccordionTrigger = createHook<
"aria-disabled": ariaAttr(!allowToggle && selected),
onClick,
onFocus,
onKeyDown,
...htmlProps,
};
},
Expand Down
13 changes: 10 additions & 3 deletions src/meter/Meter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useWarning } from "reakit-warning";
import { BoxHTMLProps, BoxOptions, useBox } from "reakit";
import { createHook, createComponent } from "reakit-system";
import { createHook, createComponent, useCreateElement } from "reakit-system";

import { METER_KEYS } from "./__keys";
import { MeterStateReturn } from "./MeterState";
Expand All @@ -18,7 +19,6 @@ const useMeter = createHook<MeterOptions, MeterHTMLProps>({

useProps(options, htmlProps) {
const { value, max, min, ariaValueText } = options;
console.log("%c ariaValueText", "color: #99adcc", ariaValueText);

// Use the meter role if available, but fall back to progressbar if not
// Chrome currently falls back from meter automatically, and Firefox
Expand All @@ -30,7 +30,7 @@ const useMeter = createHook<MeterOptions, MeterHTMLProps>({
role: "meter progressbar",
"aria-valuemax": max,
"aria-valuemin": min,
"aria-valuenow": value == null ? undefined : value,
"aria-valuenow": value,
"aria-valuetext": `${ariaValueText}`,
...htmlProps,
};
Expand All @@ -41,4 +41,11 @@ export const Meter = createComponent({
as: "div",
memo: true,
useHook: useMeter,
useCreateElement: (type, props, children) => {
useWarning(
!props["aria-label"] && !props["aria-labelledby"],
"You should provide either `aria-label` or `aria-labelledby` props.",
);
return useCreateElement(type, props, children);
},
});
10 changes: 9 additions & 1 deletion src/progress/Progress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
* We improved the Progress Component [Progress](https://github.com/chakra-ui/chakra-ui/tree/develop/packages/progress)
* to work with Reakit System
*/
import { useWarning } from "reakit-warning";
import { BoxHTMLProps, BoxOptions, useBox } from "reakit";
import { createHook, createComponent } from "reakit-system";
import { createHook, createComponent, useCreateElement } from "reakit-system";

import { dataAttr } from "../utils";
import { PROGRESS_KEYS } from "./__keys";
Expand Down Expand Up @@ -45,4 +46,11 @@ export const Progress = createComponent({
as: "div",
memo: true,
useHook: useProgress,
useCreateElement: (type, props, children) => {
useWarning(
!props["aria-label"] && !props["aria-labelledby"],
"You should provide either `aria-label` or `aria-labelledby` props.",
);
return useCreateElement(type, props, children);
},
});
6 changes: 4 additions & 2 deletions src/progress/ProgressState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,12 @@ export function useProgressState(
value: initialValue = 0,
min = 0,
max = 100,
ariaValueText,
isIndeterminate = false,
ariaValueText,
} = useSealedState(initialState);
const [value, setValue] = React.useState(initialValue);
const [value, setValue] = React.useState(
initialValue == null ? 0 : initialValue,
);
const percent = valueToPercent(value, min, max);

return {
Expand Down

0 comments on commit 3d6a77f

Please sign in to comment.