mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-15 08:33:03 +00:00
Name labeled toggle controls
This commit is contained in:
@@ -51,4 +51,15 @@ describe('Toggle', () => {
|
||||
expect(screen.getByText('Enabled')).toBeInTheDocument();
|
||||
expect(screen.getByText('Turns it on')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('uses the visible label and description for the primitive button semantics', () => {
|
||||
render(() => (
|
||||
<Toggle checked={true} label={<span>Enabled</span>} description={<span>Turns it on</span>} />
|
||||
));
|
||||
|
||||
const button = screen.getByRole('button', { name: 'Enabled' });
|
||||
expect(button).toHaveAttribute('aria-labelledby');
|
||||
expect(button).toHaveAttribute('aria-describedby');
|
||||
expect(button).toHaveAccessibleDescription('Turns it on');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { JSX } from 'solid-js';
|
||||
import { JSX, createUniqueId } from 'solid-js';
|
||||
import {
|
||||
getToggleContainerClass,
|
||||
getToggleDescriptionClass,
|
||||
@@ -9,16 +9,15 @@ import {
|
||||
type ToggleSize,
|
||||
} from '@/components/shared/toggleModel';
|
||||
export type { ToggleChangeEvent } from '@/components/shared/toggleModel';
|
||||
import {
|
||||
type ToggleRuntimeProps,
|
||||
useToggleState,
|
||||
} from '@/components/shared/useToggleState';
|
||||
import { type ToggleRuntimeProps, useToggleState } from '@/components/shared/useToggleState';
|
||||
|
||||
interface BaseToggleProps extends ToggleRuntimeProps {
|
||||
size?: ToggleSize;
|
||||
class?: string;
|
||||
title?: string;
|
||||
ariaLabel?: string;
|
||||
ariaLabelledBy?: string;
|
||||
ariaDescribedBy?: string;
|
||||
}
|
||||
|
||||
export function TogglePrimitive(props: BaseToggleProps): JSX.Element {
|
||||
@@ -34,6 +33,8 @@ export function TogglePrimitive(props: BaseToggleProps): JSX.Element {
|
||||
title={props.title}
|
||||
aria-pressed={props.checked ? 'true' : 'false'}
|
||||
aria-label={props.ariaLabel}
|
||||
aria-labelledby={props.ariaLabel ? undefined : props.ariaLabelledBy}
|
||||
aria-describedby={props.ariaDescribedBy}
|
||||
>
|
||||
<span class={getToggleKnobClass(size, props.checked, state.isDisabled())} />
|
||||
</button>
|
||||
@@ -50,14 +51,25 @@ interface LabeledToggleProps extends BaseToggleProps {
|
||||
|
||||
export function Toggle(props: LabeledToggleProps) {
|
||||
const size = resolveToggleSize(props.size, 'md');
|
||||
const labelId = createUniqueId();
|
||||
const descriptionId = createUniqueId();
|
||||
|
||||
return (
|
||||
<div class={getToggleContainerClass(props.containerClass)}>
|
||||
<TogglePrimitive {...props} size={size} />
|
||||
<TogglePrimitive
|
||||
{...props}
|
||||
size={size}
|
||||
ariaLabelledBy={props.label ? labelId : undefined}
|
||||
ariaDescribedBy={props.description ? descriptionId : undefined}
|
||||
/>
|
||||
{(props.label || props.description) && (
|
||||
<span class={getToggleLabelClass()}>
|
||||
{props.label}
|
||||
{props.description && <span class={getToggleDescriptionClass()}>{props.description}</span>}
|
||||
{props.label && <span id={labelId}>{props.label}</span>}
|
||||
{props.description && (
|
||||
<span id={descriptionId} class={getToggleDescriptionClass()}>
|
||||
{props.description}
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user