refactor(form): implement options prop for Radio (#147)

This commit is contained in:
Woramat Ngamkham 2022-10-25 14:56:06 +07:00 committed by GitHub
parent c8ace159da
commit ebff4940f2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 75 additions and 10 deletions

View file

@ -27,13 +27,14 @@ const form = new FormGroup([
name: "rating", name: "rating",
label: "Rating", label: "Rating",
type: "radio", type: "radio",
value: ["1", "2", "3", "4", "5"], value: "5",
options: ["1", "2", "3", "4", "5"],
}, },
{ {
name: "agreement", name: "agreement",
label: "Agreement", label: "Agreement",
type: "radio", type: "radio",
value: [ options: [
{ label: "Agree", value: "yes", checked: true }, { label: "Agree", value: "yes", checked: true },
{ label: "Disagree", value: "no" }, { label: "Disagree", value: "no" },
], ],

View file

@ -7,19 +7,19 @@ const baseForm = new FormGroup([
name: "crust", name: "crust",
label: "Crust", label: "Crust",
type: "radio", type: "radio",
value: [{ label: "Garlic", value: "garlic" }], options: [{ label: "Garlic", value: "garlic" }],
}, },
{ {
name: "size", name: "size",
label: "Size", label: "Size",
type: "radio", type: "radio",
value: ["Small", "Medium", "Large"], options: ["Small", "Medium", "Large"],
}, },
{ {
name: "sauce", name: "sauce",
label: "Sauce", label: "Sauce",
type: "radio", type: "radio",
value: ["Tomato", "Barbeque"], options: ["Tomato", "Barbeque"],
}, },
]); ]);

View file

@ -34,6 +34,7 @@ export interface ControlBase {
labelPosition?: "right" | "left"; labelPosition?: "right" | "left";
placeholder?: string; placeholder?: string;
validators?: string[]; // TODO: implement validator type validators?: string[]; // TODO: implement validator type
options?: string[] | RadioOption[]; // prevent build failed
} }
export interface Checkbox extends ControlBase { export interface Checkbox extends ControlBase {
@ -43,13 +44,13 @@ export interface Checkbox extends ControlBase {
export interface Radio extends Omit<ControlBase, "value"> { export interface Radio extends Omit<ControlBase, "value"> {
type: "radio"; type: "radio";
value: string[] | RadioOption[]; value?: string;
options: string[] | RadioOption[];
} }
export interface RadioOption { export interface RadioOption {
label: string; label: string;
value: string; value: string;
checked?: boolean;
} }
export interface Submit extends ControlBase { export interface Submit extends ControlBase {

View file

@ -10,7 +10,7 @@ export interface Props {
const { control } = Astro.props; const { control } = Astro.props;
const options = control.value.map((option) => { const options = control.options.map((option) => {
if (typeof option === 'string') { if (typeof option === 'string') {
return { return {
label: option, label: option,
@ -24,7 +24,7 @@ const options = control.value.map((option) => {
{ {
options.map((option) => ( options.map((option) => (
<div class="radio-option"> <div class="radio-option">
<input type="radio" name={control.name} value={option.value} checked={option.checked} />{' '} <input type="radio" name={control.name} value={option.value} checked={option.value === control.value} />{' '}
{option.label} {option.label}
</div> </div>
)) ))

View file

@ -22,6 +22,7 @@ export class FormControl {
private _placeholder: string | null = null; private _placeholder: string | null = null;
private _validators: string[] = []; private _validators: string[] = [];
private _errors: ValidationError[] = []; private _errors: ValidationError[] = [];
private _options: string[] | RadioOption[] = [];
private validate: (value: string, validators: string[]) => ValidationError[] = ( private validate: (value: string, validators: string[]) => ValidationError[] = (
value: string, value: string,
@ -41,6 +42,7 @@ export class FormControl {
labelPosition = 'left', labelPosition = 'left',
placeholder = null, placeholder = null,
validators = [], validators = [],
options = [],
} = config; } = config;
this._name = name; this._name = name;
@ -50,6 +52,7 @@ export class FormControl {
this._labelPosition = labelPosition; this._labelPosition = labelPosition;
this._placeholder = placeholder; this._placeholder = placeholder;
this._validators = validators; this._validators = validators;
this._options = options;
// TODO: implement independence // TODO: implement independence
// form should try to import validator, // form should try to import validator,
@ -107,6 +110,10 @@ export class FormControl {
return this._errors; return this._errors;
} }
get options() {
return this._options;
}
setValue(value: string) { setValue(value: string) {
this._value = value; this._value = value;
this._isPristine = false; this._isPristine = false;

View file

@ -9,6 +9,7 @@ describe('RadioGroup.astro test', () => {
beforeEach(() => { beforeEach(() => {
component = undefined; component = undefined;
}); });
it('Should render all radio options', async () => { it('Should render all radio options', async () => {
// arrange // arrange
const expectedOptions = 3; const expectedOptions = 3;
@ -18,7 +19,7 @@ describe('RadioGroup.astro test', () => {
label: 'FAKE LABEL', label: 'FAKE LABEL',
name: 'FAKE NAME', name: 'FAKE NAME',
type: 'radio', type: 'radio',
value: ['one', 'two', 'three'], options: ['one', 'two', 'three'],
}, },
showValidationHints: true, showValidationHints: true,
}; };
@ -31,4 +32,59 @@ describe('RadioGroup.astro test', () => {
// assert // assert
expect(matches.length).to.equal(expectedOptions); expect(matches.length).to.equal(expectedOptions);
}); });
it('Should render a checked radio option from string[] correctly', async () => {
const expectedResult = '<inputtype="radio"name="FAKENAME"value="two"checked="true">';
const props = {
control: {
label: 'FAKE LABEL',
name: 'FAKE NAME',
type: 'radio',
value: 'two',
options: ['one', 'two', 'three'],
},
showValidationHints: true,
};
// act
component = await getComponentOutput('./components/controls/RadioGroup.astro', props);
const actualResult = cleanString(component.html);
// assert
expect(actualResult).to.contain(expectedResult);
});
it('Should render a checked radio option from RadioOption[] correctly', async () => {
const expectedResult = '<inputtype="radio"name="FAKENAME"value="three"checked="true">';
const props = {
control: {
label: 'FAKE LABEL',
name: 'FAKE NAME',
type: 'radio',
value: 'three',
options: [
{
value: 'one',
label: '1',
},
{
value: 'two',
label: '2',
},
{
value: 'three',
label: '3',
},
],
},
showValidationHints: true,
};
// act
component = await getComponentOutput('./components/controls/RadioGroup.astro', props);
const actualResult = cleanString(component.html);
// assert
expect(actualResult).to.contain(expectedResult);
});
}); });