refactor(form): implement options
prop for Radio (#147)
This commit is contained in:
parent
c8ace159da
commit
ebff4940f2
6 changed files with 75 additions and 10 deletions
|
@ -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" },
|
||||||
],
|
],
|
||||||
|
|
|
@ -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"],
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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>
|
||||||
))
|
))
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue