Skip to content

Commit 12e9ec5

Browse files
authored
Issue #444: Add RadioField form component (#447)
1 parent fdc9a98 commit 12e9ec5

1 file changed

Lines changed: 70 additions & 0 deletions

File tree

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
export type RadioOption = {
3+
/** Unique id for input + label */
4+
id: string;
5+
/** Label text */
6+
label: string;
7+
/** Radio value */
8+
value: string;
9+
/** Optional description text */
10+
description?: string;
11+
/** Disabled state */
12+
disabled?: boolean;
13+
};
14+
15+
export interface Props {
16+
/** Group label */
17+
legend: string;
18+
/** Shared name for radio inputs */
19+
name: string;
20+
/** Radio options */
21+
options: RadioOption[];
22+
/** Pre-selected value */
23+
selected?: string;
24+
/** Optional help text */
25+
helpText?: string;
26+
/** Optional error text */
27+
errorText?: string;
28+
/** Optional class */
29+
className?: string;
30+
}
31+
32+
const { legend, name, options, selected, helpText, errorText, className } = Astro.props;
33+
34+
const helpId = helpText ? `${name}-help` : undefined;
35+
const errorId = errorText ? `${name}-error` : undefined;
36+
const describedBy = [errorId, helpId].filter(Boolean).join(" ") || undefined;
37+
---
38+
39+
<fieldset class={className} aria-describedby={describedBy}>
40+
<legend>{legend}</legend>
41+
42+
{errorText && (
43+
<p id={errorId} role="alert">
44+
{errorText}
45+
</p>
46+
)}
47+
48+
{helpText && <p id={helpId}>{helpText}</p>}
49+
50+
{options.map((opt) => {
51+
const descId = opt.description ? `${opt.id}-desc` : undefined;
52+
const inputDescribedBy = [descId].filter(Boolean).join(" ") || undefined;
53+
54+
return (
55+
<div>
56+
<input
57+
type="radio"
58+
id={opt.id}
59+
name={name}
60+
value={opt.value}
61+
checked={selected === opt.value}
62+
disabled={opt.disabled}
63+
aria-describedby={inputDescribedBy}
64+
/>
65+
<label for={opt.id}>{opt.label}</label>
66+
{opt.description && <div id={descId}>{opt.description}</div>}
67+
</div>
68+
);
69+
})}
70+
</fieldset>

0 commit comments

Comments
 (0)