feat(form): Add radio (#111)

This commit is contained in:
Woramat Ngamkham 2022-10-20 12:58:40 +07:00 committed by GitHub
parent 8d7ef9e879
commit 030752b4cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 83 additions and 21 deletions

View file

@ -23,6 +23,21 @@ const form = new FormGroup([
type: "password", type: "password",
validators: [Validators.required, Validators.minLength(8)], validators: [Validators.required, Validators.minLength(8)],
}, },
{
name: "rating",
label: "Rating",
type: "radio",
value: ["1", "2", "3", "4", "5"]
},
{
name: "agreement",
label: "Agreement",
type: "radio",
value: [
{ label: "Agree", value: "yes" },
{ label: "Disagree", value: "no", labelPosition: "right" }
]
}
]); ]);
form.name = "Simple Form"; form.name = "Simple Form";

View file

@ -1,5 +1,5 @@
--- ---
import { Submit, FormGroup, FormControl } from './core'; import { Submit, FormGroup, FormControl, Radio, RadioOption } from './core';
import Field from './components/Field.astro'; import Field from './components/Field.astro';
import FieldSet from './components/FieldSet.astro'; import FieldSet from './components/FieldSet.astro';
@ -21,7 +21,36 @@ const formName = Array.isArray(form) ? null : form?.name || null;
Array.isArray(form) Array.isArray(form)
? form?.map((group) => <FieldSet showValidationHints={showValidationHints} group={group} />) ? form?.map((group) => <FieldSet showValidationHints={showValidationHints} group={group} />)
: form?.controls.map((control) => ( : form?.controls.map((control) => (
control.type === "radio" ?
(
[
(<Field showValidationHints={showValidationHints} control={control} showOnlyLabel={true} />),
...(control as Radio)?.value?.map((v: string | RadioOption) => (
<Field
showValidationHints={showValidationHints}
control={
(typeof v === "string") ?
new FormControl({
name: control.name,
type: "radio",
id: control.name + v,
label: v,
value: v
}) :
new FormControl({
name: control.name,
type: "radio",
id: control.name + v.label,
...(v as RadioOption)
})
}
/>
))
]
) :
(
<Field showValidationHints={showValidationHints} control={control} /> <Field showValidationHints={showValidationHints} control={control} />
)
)) ))
} }
{ {

View file

@ -4,9 +4,10 @@ import type { FormControl } from '../core/form-control';
export interface Props { export interface Props {
control: FormControl; control: FormControl;
showValidationHints: boolean; showValidationHints: boolean;
showOnlyLabel?: boolean;
} }
const { control, showValidationHints } = Astro.props; const { control, showValidationHints, showOnlyLabel = false } = Astro.props;
const { validators = [] } = control; const { validators = [] } = control;
@ -31,28 +32,32 @@ const validatorAttirbutes: Record<string, string> = validators?.reduce(
<div class="field" data-validator-hints={showValidationHints.toString()}> <div class="field" data-validator-hints={showValidationHints.toString()}>
{ {
control.label && control.labelPosition === 'left' && ( control.label && control.labelPosition === 'left' && (
<label for={control.name}> <label for={control?.id ?? control.name}>
{isRequired && <span>*</span>} {isRequired && <span>*</span>}
{control.label} {control.label}
</label> </label>
) )
} }
{
!showOnlyLabel && (
<input <input
name={control.name} name={control.name}
id={control.name} id={control?.id ?? control.name}
type={control.type} type={control.type}
value={control.value} value={control.value?.toString()}
checked={control.value === 'checked'} checked={control.value === 'checked'}
placeholder={control.placeholder} placeholder={control.placeholder}
data-label={control.label} data-label={control.label}
data-label-position={control.labelPosition} data-label-position={control.labelPosition}
{...validatorAttirbutes} {...validatorAttirbutes}
/> />
)
}
{ {
control.label && control.labelPosition === 'right' && ( control.label && control.labelPosition === 'right' && (
<label for={control.name}> <label for={control?.id ?? control.name}>
{isRequired && <span>*</span>} {isRequired && <span>*</span>}
{control.label} {control.label}
</label> </label>

View file

@ -29,6 +29,7 @@ export type ControlConfig = ControlBase | Checkbox | Radio | Submit | Button;
export interface ControlBase { export interface ControlBase {
name: string; name: string;
id?: string;
type?: ControlType; type?: ControlType;
value?: string | number | string[]; value?: string | number | string[];
label?: string; label?: string;
@ -42,9 +43,15 @@ export interface Checkbox extends ControlBase {
checked: boolean; checked: boolean;
} }
export interface Radio extends ControlBase { export interface Radio extends Omit<ControlBase, 'value'> {
type: 'radio'; type: 'radio';
checked: boolean; value: string[] | RadioOption[];
}
export interface RadioOption extends Omit<ControlBase, 'name'> {
label: string;
value: string;
checked?: boolean;
} }
export interface Submit extends ControlBase { export interface Submit extends ControlBase {

View file

@ -1,9 +1,10 @@
import type { ControlConfig, ControlType } from './form-control-types'; import type { ControlConfig, ControlType, RadioOption } from './form-control-types';
export class FormControl { export class FormControl {
private _name = ''; private _name = '';
private _id = '';
private _type: ControlType = 'text'; private _type: ControlType = 'text';
private _value?: string | number | null | string[]; private _value?: string | number | null | string[] | RadioOption[];
private _label?: string; private _label?: string;
private _labelPosition?: 'right' | 'left' = 'left'; private _labelPosition?: 'right' | 'left' = 'left';
private _isValid = true; private _isValid = true;
@ -12,8 +13,9 @@ export class FormControl {
private _validators?: string[]; private _validators?: string[];
constructor(config: ControlConfig) { constructor(config: ControlConfig) {
const { name, type, value, label, labelPosition, placeholder, validators } = config; const { name, id, type, value, label, labelPosition, placeholder, validators } = config;
this._name = name; this._name = name;
this._id = id ?? name;
this._type = type ?? 'text'; this._type = type ?? 'text';
this._value = value ?? null; this._value = value ?? null;
this._label = label ?? ''; this._label = label ?? '';
@ -26,6 +28,10 @@ export class FormControl {
return this._name; return this._name;
} }
get id() {
return this._id;
}
get type() { get type() {
return this._type; return this._type;
} }