diff --git a/apps/demo/src/pages/index.astro b/apps/demo/src/pages/index.astro index 4446289..d72fea0 100644 --- a/apps/demo/src/pages/index.astro +++ b/apps/demo/src/pages/index.astro @@ -39,6 +39,13 @@ const form = new FormGroup([ { label: "Disagree", value: "no" }, ], }, + { + name: "size", + label: "Size", + type: "dropdown", + options: ["S", "M", "L", "XL", "XXL"], + placeholder: "-- Please choose an option --", + }, ]); form.name = "Simple Form"; diff --git a/packages/common/types/control.types.ts b/packages/common/types/control.types.ts index f0f4dd1..423b79b 100644 --- a/packages/common/types/control.types.ts +++ b/packages/common/types/control.types.ts @@ -2,7 +2,7 @@ * `ControlType` determines the type of form control * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types */ -export type ControlType = +export type InputType = | "text" | "checkbox" | "radio" @@ -25,6 +25,8 @@ export type ControlType = | "url" | "week"; +export type ControlType = InputType | "dropdown"; + export interface ControlBase { name: string; id?: string; @@ -34,7 +36,7 @@ export interface ControlBase { labelPosition?: "right" | "left"; placeholder?: string; validators?: string[]; // TODO: implement validator type - options?: string[] | RadioOption[]; // prevent build failed + options?: string[] | ControlOption[]; } export interface Checkbox extends ControlBase { @@ -45,10 +47,16 @@ export interface Checkbox extends ControlBase { export interface Radio extends Omit { type: "radio"; value?: string; - options: string[] | RadioOption[]; + options: string[] | ControlOption[]; } -export interface RadioOption { +export interface Dropdown extends Omit { + type: "dropdown"; + value?: string; + options: string[] | ControlOption[]; +} + +export interface ControlOption { label: string; value: string; } diff --git a/packages/form/components/Field.astro b/packages/form/components/Field.astro index abbc636..f94e105 100644 --- a/packages/form/components/Field.astro +++ b/packages/form/components/Field.astro @@ -2,8 +2,9 @@ /** * DEFAULT CONTROL COMPONENT */ -import type { Radio } from '@astro-reactive/common'; +import type { Radio, Dropdown } from '@astro-reactive/common'; import type { FormControl } from '../core/form-control'; +import DropdownControl from './controls/Dropdown.astro'; import Input from './controls/Input.astro'; import RadioGroup from './controls/RadioGroup.astro'; import Errors from './Errors.astro'; @@ -25,6 +26,9 @@ const hasErrors: boolean | null = !!control.errors?.length; { control.type === 'radio' ? ( + ) : + control.type === 'dropdown' ? ( + ) : ( ) diff --git a/packages/form/components/controls/Dropdown.astro b/packages/form/components/controls/Dropdown.astro new file mode 100644 index 0000000..cfee5ee --- /dev/null +++ b/packages/form/components/controls/Dropdown.astro @@ -0,0 +1,42 @@ +--- +/** + * DROPDOWN COMPONENT + */ +import type { Dropdown, ControlOption } from '@astro-reactive/common'; + +export interface Props { + control: Dropdown; +} + +const { control } = Astro.props; + +const options = control.options.map((option: string | ControlOption) => { + if (typeof option === 'string') { + return { + label: option, + value: option, + }; + } + return option; +}); +--- + + \ No newline at end of file diff --git a/packages/form/components/controls/Input.astro b/packages/form/components/controls/Input.astro index db834fe..5febaa7 100644 --- a/packages/form/components/controls/Input.astro +++ b/packages/form/components/controls/Input.astro @@ -2,6 +2,7 @@ /** * DEFAULT INPUT COMPONENT */ +import type { InputType } from '@astro-reactive/common'; import type { FormControl } from '../../core/form-control'; export interface Props { @@ -29,7 +30,7 @@ const validatorAttributes: Record = validators?.reduce((prev, va { +const options = control.options.map((option: string | ControlOption) => { if (typeof option === 'string') { return { label: option, @@ -22,7 +22,7 @@ const options = control.options.map((option) => { --- { - options.map((option) => ( + options.map((option: ControlOption) => (
ValidationError[] = ( value: string, diff --git a/packages/form/test/Dropdown.astro.test.js b/packages/form/test/Dropdown.astro.test.js new file mode 100644 index 0000000..c9a8f80 --- /dev/null +++ b/packages/form/test/Dropdown.astro.test.js @@ -0,0 +1,152 @@ +import { expect } from 'chai'; +import { describe, beforeEach, it } from 'mocha'; +import { getComponentOutput } from 'astro-component-tester'; +import { cleanString } from './utils/index.js'; + +describe('Dropdown.astro test', () => { + let component; + + beforeEach(() => { + component = undefined; + }); + + it('Should render all dropdown string[] options', async () => { + // arrange + const expectedOptions = 3; + const element = /'; + const expectedOptions = 4; + const element = /