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",
|
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";
|
||||||
|
|
|
@ -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} />
|
||||||
|
)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue