feat(form): Add radio (#111)
This commit is contained in:
parent
8d7ef9e879
commit
030752b4cc
5 changed files with 83 additions and 21 deletions
|
@ -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";
|
||||
|
|
|
@ -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} />
|
||||
)
|
||||
))
|
||||
}
|
||||
{
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue