Skip to content

Commit

Permalink
Add screen reader support to several form inputs (#766)
Browse files Browse the repository at this point in the history
- Add screen reader support to RadioButtonWithLabel, CheckboxWithLabel and SwitchWithLabel.
  • Loading branch information
mattias800 authored Aug 16, 2024
1 parent 8e565cd commit 4253238
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 11 deletions.
26 changes: 19 additions & 7 deletions packages/forms/src/components/ui/checkbox/CheckboxWithLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { Row, Space, Text } from "@stenajs-webui/core";
import { Row, ScreenReaderOnlyText, Space, Text } from "@stenajs-webui/core";
import * as React from "react";
import { Ref } from "react";
import { Checkbox, CheckboxProps } from "./Checkbox";

export interface CheckboxWithLabelProps extends CheckboxProps {
label?: string;
label: string;
/**
* If set, this label is used by screen readers instead of label prop.
* For example, label could be "male", while screenReaderLabel is "Gender male".
* If not set, screen readers will use label prop.
*/
screenReaderLabel?: string;
textColor?: string;
wrapperRef?: Ref<HTMLDivElement>;
inputRef?: Ref<HTMLInputElement>;
Expand All @@ -16,6 +22,7 @@ export const CheckboxWithLabel: React.FC<CheckboxWithLabelProps> = ({
inputRef,
wrapperRef,
textColor,
screenReaderLabel,
...checkboxProps
}) => {
return (
Expand All @@ -24,11 +31,16 @@ export const CheckboxWithLabel: React.FC<CheckboxWithLabelProps> = ({
<Row alignItems={"center"}>
<Checkbox {...checkboxProps} ref={inputRef} />
<Space />
{label && (
<Text userSelect={"none"} color={textColor}>
{label}
</Text>
)}
{screenReaderLabel ? (
<ScreenReaderOnlyText>{screenReaderLabel}</ScreenReaderOnlyText>
) : null}
<Text
color={textColor}
aria-hidden={Boolean(screenReaderLabel)}
userSelect={"none"}
>
{label}
</Text>
{children}
</Row>
</label>
Expand Down
18 changes: 16 additions & 2 deletions packages/forms/src/components/ui/radio/RadioButtonWithLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { Row, Space, Text } from "@stenajs-webui/core";
import { Row, ScreenReaderOnlyText, Space, Text } from "@stenajs-webui/core";
import * as React from "react";
import { Ref } from "react";
import { RadioButton, RadioButtonProps } from "./RadioButton";

export interface RadioButtonWithLabelProps extends RadioButtonProps {
label: string;
/**
* If set, this label is used by screen readers instead of label prop.
* For example, label could be "male", while screenReaderLabel is "Gender male".
* If not set, screen readers will use label prop.
*/
screenReaderLabel?: string;
textColor?: string;
wrapperRef?: Ref<HTMLDivElement>;
inputRef?: Ref<HTMLInputElement>;
Expand All @@ -15,6 +21,7 @@ export const RadioButtonWithLabel: React.FC<RadioButtonWithLabelProps> = ({
inputRef,
wrapperRef,
textColor,
screenReaderLabel,
...radioButtonProps
}) => {
return (
Expand All @@ -23,7 +30,14 @@ export const RadioButtonWithLabel: React.FC<RadioButtonWithLabelProps> = ({
<Row alignItems={"center"}>
<RadioButton ref={inputRef} {...radioButtonProps} />
<Space />
<Text color={textColor} userSelect={"none"}>
{screenReaderLabel ? (
<ScreenReaderOnlyText>{screenReaderLabel}</ScreenReaderOnlyText>
) : null}
<Text
color={textColor}
aria-hidden={Boolean(screenReaderLabel)}
userSelect={"none"}
>
{label}
</Text>
</Row>
Expand Down
18 changes: 16 additions & 2 deletions packages/forms/src/components/ui/switch/SwitchWithLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { Box, Space, Text } from "@stenajs-webui/core";
import { Box, ScreenReaderOnlyText, Space, Text } from "@stenajs-webui/core";
import * as React from "react";
import { Switch, SwitchProps } from "./Switch";

export interface SwitchWithLabelProps extends SwitchProps {
label: string;
/**
* If set, this label is used by screen readers instead of label prop.
* For example, label could be "male", while screenReaderLabel is "Gender male".
* If not set, screen readers will use label prop.
*/
screenReaderLabel?: string;
textColor?: string;
}

Expand All @@ -12,6 +18,7 @@ export const SwitchWithLabel: React.FC<SwitchWithLabelProps> = ({
disabled,
textColor,
wrapperRef,
screenReaderLabel,
...switchProps
}) => {
return (
Expand All @@ -20,7 +27,14 @@ export const SwitchWithLabel: React.FC<SwitchWithLabelProps> = ({
<Box row alignItems={"center"}>
<Switch disabled={disabled} {...switchProps} />
<Space />
<Text userSelect={"none"} color={textColor}>
{screenReaderLabel ? (
<ScreenReaderOnlyText>{screenReaderLabel}</ScreenReaderOnlyText>
) : null}
<Text
color={textColor}
aria-hidden={Boolean(screenReaderLabel)}
userSelect={"none"}
>
{label}
</Text>
</Box>
Expand Down

0 comments on commit 4253238

Please sign in to comment.