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