diff --git a/apps/demo/src/pages/index.astro b/apps/demo/src/pages/index.astro index 07b9f36..2a645c4 100644 --- a/apps/demo/src/pages/index.astro +++ b/apps/demo/src/pages/index.astro @@ -4,6 +4,7 @@ import Form, { FormGroup, FormControl, } from "@astro-reactive/form"; +import type { Submit } from "@astro-reactive/common/types"; import { Validators } from "@astro-reactive/validator"; import Layout from "../components/Layout.astro"; @@ -94,6 +95,11 @@ form.get("email")?.setValue("invalid-email"); // switch between light and dark mode const title = "Form Demo"; const theme = "dark"; + +const submit: Submit = { + name: "submit", + type: "submit", +}; --- @@ -102,5 +108,8 @@ const theme = "dark"; showValidationHints={true} formGroups={form} theme={theme} + submitControl={submit} + action="https://localhost" + method="POST" /> diff --git a/packages/common/types/control.types.ts b/packages/common/types/control.types.ts index 1e62922..ec9720d 100644 --- a/packages/common/types/control.types.ts +++ b/packages/common/types/control.types.ts @@ -27,6 +27,17 @@ export type InputType = | "url" | "week"; +export type HTTPRequestMethodType = + | "GET" + | "POST" + | "PUT" + | "PATCH" + | "DELETE" + | "TRACE" + | "OPTIONS" + | "CONNECT" + | "HEAD"; + export type ControlType = InputType | "dropdown" | "textarea"; export interface ControlBase { diff --git a/packages/form/components/Form.astro b/packages/form/components/Form.astro index f7eedb7..bcc8a41 100644 --- a/packages/form/components/Form.astro +++ b/packages/form/components/Form.astro @@ -1,5 +1,5 @@ --- -import type { Submit } from '@astro-reactive/common'; +import type { HTTPRequestMethodType, Submit } from '@astro-reactive/common'; import { FormGroup, FormControl } from '../core'; import FieldSet from './FieldSet.astro'; import Field from './Field.astro'; @@ -12,6 +12,8 @@ export interface Props { validateOnLoad?: boolean; submitControl?: Submit; theme?: 'light' | 'dark'; + action?: string; + method?: HTTPRequestMethodType; } const { @@ -21,6 +23,8 @@ const { showValidationHints = false, validateOnLoad = false, readOnly = false, + action = "", + method = "GET" } = Astro.props; const uid = new ShortUniqueId({ length: 9 }); @@ -50,6 +54,8 @@ if (validateOnLoad) { name={formName} id={formId} data-validator-hints={showValidationHints.toString()} + action={action} + method={method} > { Array.isArray(formGroups) diff --git a/packages/form/test/Form.astro.test.ts b/packages/form/test/Form.astro.test.ts index 7d0e522..187281c 100644 --- a/packages/form/test/Form.astro.test.ts +++ b/packages/form/test/Form.astro.test.ts @@ -87,6 +87,7 @@ describe('Form.astro test', () => { // assert expect(matches.length).to.equal(expectedCount); }); + it('Should render readOnly fields if the flag is passed as true', async () => { // arrange const expectedCount = 3; @@ -110,5 +111,50 @@ describe('Form.astro test', () => { // assert expect(matches.length).to.equal(expectedCount); }); + + it('Should render a submit button correctly', async () => { + // arrange + const expectedType = 'type="submit"'; + const expectedName = 'name="submitNameTest"'; + const submit = { + name: 'submitNameTest', + type: 'submit', + }; + const props = { submitControl: submit }; + component = await getComponentOutput('./components/Form.astro', props); + + // act + const actualResult = cleanString(component.html); + + // assert + expect(actualResult).to.contain(expectedType); + expect(actualResult).to.contain(expectedName); + }); + + it('Should render an action property correctly', async () => { + // arrange + const expectedResult = 'action="https://localhost"'; + const props = { action: 'https://localhost' }; + component = await getComponentOutput('./components/Form.astro', props); + + // act + const actualResult = cleanString(component.html); + + // assert + expect(actualResult).to.contain(expectedResult); + }); + + it('Should render a method property correctly', async () => { + // arrange + const expectedResult = 'method="GET"'; + const props = { method: 'GET' }; + component = await getComponentOutput('./components/Form.astro', props); + + // act + const actualResult = cleanString(component.html); + + // assert + expect(actualResult).to.contain(expectedResult); + }); }); });