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",
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";

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 FieldSet from './components/FieldSet.astro';
@ -21,7 +21,36 @@ const formName = Array.isArray(form) ? null : form?.name || null;
Array.isArray(form)
? form?.map((group) => <FieldSet showValidationHints={showValidationHints} group={group} />)
: 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} />
)
))
}
{

View file

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

View file

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

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 {
private _name = '';
private _id = '';
private _type: ControlType = 'text';
private _value?: string | number | null | string[];
private _value?: string | number | null | string[] | RadioOption[];
private _label?: string;
private _labelPosition?: 'right' | 'left' = 'left';
private _isValid = true;
@ -12,8 +13,9 @@ export class FormControl {
private _validators?: string[];
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._id = id ?? name;
this._type = type ?? 'text';
this._value = value ?? null;
this._label = label ?? '';
@ -26,6 +28,10 @@ export class FormControl {
return this._name;
}
get id() {
return this._id;
}
get type() {
return this._type;
}