diff --git a/.changepacks/changepack_log_radio_group_a11y.json b/.changepacks/changepack_log_radio_group_a11y.json new file mode 100644 index 000000000..b0c5dad88 --- /dev/null +++ b/.changepacks/changepack_log_radio_group_a11y.json @@ -0,0 +1,7 @@ +{ + "changes": { + "packages/components/package.json": "Patch" + }, + "note": "RadioGroup is a radiogroup with an optional label, its radios share a name (generated when not given) so arrow keys move between them, and it keeps the typed values of its options: false, 0 and '' stay selectable and onChange receives the option's own value rather than a string. Button-variant radios are visually hidden instead of display:none, so they stay focusable and show a focus ring, and the default radio's focus outline is valid CSS and shown on :focus-visible. Checkbox uses an id it is given for its labels as well as its input, where the labels used to point at a generated id", + "date": "2026-10-01T00:00:00.000Z" +} diff --git a/packages/components/src/__tests__/forward-ref.browser.test.tsx b/packages/components/src/__tests__/forward-ref.browser.test.tsx index 59d355290..7b4904913 100644 --- a/packages/components/src/__tests__/forward-ref.browser.test.tsx +++ b/packages/components/src/__tests__/forward-ref.browser.test.tsx @@ -2,9 +2,44 @@ import { describe, expect, it } from 'bun:test' import { render } from 'bun-test-env-dom' import { createRef } from 'react' -import { Button, Input, Radio, Textarea } from '../index' +import { Button, Checkbox, Input, Radio, Textarea } from '../index' describe('forwardRef', () => { + it('links both labels to the forwarded checkbox when a custom id is given', () => { + // Given + const ref = createRef() + + // When + const { container } = render( + + Checkbox + , + ) + + // Then + expect(ref.current?.id).toBe('custom-checkbox') + const labels = container.querySelectorAll('label') + expect(labels).toHaveLength(2) + for (const label of labels) { + expect(label.htmlFor).toBe(ref.current?.id) + } + }) + + it('hands its ref to the native radio when the button variant is used', () => { + // Given + const ref = createRef() + + // When + render( + + Radio + , + ) + + // Then + expect(ref.current?.type).toBe('radio') + }) + it('hands each component ref to its form element', () => { const button = createRef() const input = createRef() diff --git a/packages/components/src/components/Checkbox/__tests__/__snapshots__/index.browser.test.tsx.snap b/packages/components/src/components/Checkbox/__tests__/__snapshots__/index.browser.test.tsx.snap index 9a9418e48..da65dd2fe 100644 --- a/packages/components/src/components/Checkbox/__tests__/__snapshots__/index.browser.test.tsx.snap +++ b/packages/components/src/components/Checkbox/__tests__/__snapshots__/index.browser.test.tsx.snap @@ -3,10 +3,10 @@ exports[`Checkbox should render basic checkbox 1`] = ` "
-