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",
label: "Rating",
type: "radio",
value: ["1", "2", "3", "4", "5"],
value: "5",
options: ["1", "2", "3", "4", "5"],
},
{
name: "agreement",
label: "Agreement",
type: "radio",
value: [
options: [
{ label: "Agree", value: "yes", checked: true },
{ label: "Disagree", value: "no" },
],

View file

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

View file

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

View file

@ -10,7 +10,7 @@ export interface Props {
const { control } = Astro.props;
const options = control.value.map((option) => {
const options = control.options.map((option) => {
if (typeof option === 'string') {
return {
label: option,
@ -24,7 +24,7 @@ const options = control.value.map((option) => {
{
options.map((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}
</div>
))

View file

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

View file

@ -9,6 +9,7 @@ describe('RadioGroup.astro test', () => {
beforeEach(() => {
component = undefined;
});
it('Should render all radio options', async () => {
// arrange
const expectedOptions = 3;
@ -18,7 +19,7 @@ describe('RadioGroup.astro test', () => {
label: 'FAKE LABEL',
name: 'FAKE NAME',
type: 'radio',
value: ['one', 'two', 'three'],
options: ['one', 'two', 'three'],
},
showValidationHints: true,
};
@ -31,4 +32,59 @@ describe('RadioGroup.astro test', () => {
// assert
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);
});
});