Closes #3448. New ui/ primitives: FormField (shared label+control wrapper), TextField, SelectField, Button — each with a min-height touch target (2.75em ~= 44px, WCAG 2.5.5) per mara's #3447 ask, and a max-width instead of a fixed width so the control caps on desktop without overflowing a narrow/touch viewport. CreateAgentPage's name field + submit button now come from the kit instead of page-scoped CSS; ComponentsPage gets a section for each new primitive with an editable sample.
46 lines
1.2 KiB
TypeScript
46 lines
1.2 KiB
TypeScript
// <SelectField> — a labelled `<select>`, `TextField`'s sibling for the
|
|
// "pick one of these" shape (the hive-choice dropdown the create-agent
|
|
// form needs is the motivating caller). Options are plain
|
|
// value/label pairs, not `ComponentChildren` — every real caller so far
|
|
// has flat string options, and generic children would need a second
|
|
// primitive (`SelectField.Option`) for zero real benefit today.
|
|
import { FormField } from '../form-field/FormField.js';
|
|
|
|
export interface SelectOption {
|
|
value: string;
|
|
label: string;
|
|
}
|
|
|
|
export function SelectField({
|
|
id,
|
|
label,
|
|
value,
|
|
onChange,
|
|
options,
|
|
required,
|
|
}: {
|
|
id: string;
|
|
label: string;
|
|
value: string;
|
|
onChange: (value: string) => void;
|
|
options: SelectOption[];
|
|
required?: boolean;
|
|
}) {
|
|
return (
|
|
<FormField label={label} htmlFor={id}>
|
|
<select
|
|
id={id}
|
|
class="ui-form-control"
|
|
value={value}
|
|
required={required}
|
|
onChange={(e) => onChange((e.target as HTMLSelectElement).value)}
|
|
>
|
|
{options.map((o) => (
|
|
<option key={o.value} value={o.value}>
|
|
{o.label}
|
|
</option>
|
|
))}
|
|
</select>
|
|
</FormField>
|
|
);
|
|
}
|