
* chore: project clean up * feat(form): update Form properties * docs: update documentation for the Form properties * fix(demo): update form method demo
133 lines
3.6 KiB
Text
133 lines
3.6 KiB
Text
---
|
|
import type { HTTPSubmitMethod, Submit } from '@astro-reactive/common';
|
|
import { FormGroup, FormControl } from '../core';
|
|
import FieldSet from './FieldSet.astro';
|
|
import Field from './Field.astro';
|
|
import ShortUniqueId from 'short-unique-id';
|
|
|
|
export interface Props {
|
|
/**
|
|
* Determines how the form is rendered
|
|
*/
|
|
formGroups: FormGroup | FormGroup[];
|
|
|
|
/**
|
|
* Sets the `action` attribute for the form. Set this to the URL that processes the form submission.
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-method
|
|
*/
|
|
action?: string;
|
|
|
|
/**
|
|
* Sets the `method` attribute for the form. Set this to the HTTP method to submit the form: 'post', 'get', or 'dialog'.
|
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-method
|
|
*/
|
|
method?: HTTPSubmitMethod;
|
|
|
|
/**
|
|
* Sets the whole form as read-only.
|
|
*/
|
|
readOnly?: boolean;
|
|
|
|
/**
|
|
* When used with our `validator` package, the `Form` component is able to render validation hints when `showValidationHints` is set to true:
|
|
* - asterisks on required controls' labels
|
|
* - controls with validation errors are colored red
|
|
*/
|
|
showValidationHints?: boolean;
|
|
|
|
/**
|
|
* A special button that triggers the submit event for a form.
|
|
*/
|
|
submitControl?: Submit;
|
|
|
|
/**
|
|
* Sets the form to use light or dark mode.
|
|
*/
|
|
theme?: 'light' | 'dark';
|
|
|
|
/**
|
|
* When used with our `validator` package, the `Form` component is able to render validation errors on server-side rendering when `validateOnLoad` is set to true. Otherwise, the validation errors will only be rendered on the client-side upon user interaction.
|
|
*/
|
|
validateOnLoad?: boolean;
|
|
}
|
|
|
|
const {
|
|
submitControl,
|
|
formGroups = [],
|
|
theme,
|
|
showValidationHints = false,
|
|
validateOnLoad = false,
|
|
readOnly = false,
|
|
action = '',
|
|
method = 'get',
|
|
} = Astro.props;
|
|
|
|
const uid = new ShortUniqueId({ length: 9 });
|
|
const formTheme = theme ?? 'light';
|
|
const formName = Array.isArray(formGroups) ? null : formGroups?.name || null;
|
|
const formId = Array.isArray(formGroups) ? uid() : formGroups?.id || null;
|
|
|
|
// if `validateOnLoad` prop is true,
|
|
// it should forced all FormControl to validate on load
|
|
if (validateOnLoad) {
|
|
if (Array.isArray(formGroups)) {
|
|
formGroups.forEach((group) =>
|
|
group.controls.forEach((control) => control.setValidateOnLoad(validateOnLoad))
|
|
);
|
|
} else {
|
|
formGroups.controls.forEach((control) => control.setValidateOnLoad(validateOnLoad));
|
|
}
|
|
}
|
|
---
|
|
|
|
<form
|
|
class={formTheme}
|
|
name={formName}
|
|
id={formId}
|
|
data-validator-hints={showValidationHints.toString()}
|
|
action={action}
|
|
method={method}
|
|
>
|
|
{
|
|
Array.isArray(formGroups)
|
|
? formGroups?.map((group) => (
|
|
<FieldSet showValidationHints={showValidationHints} group={group} readOnly={readOnly} />
|
|
))
|
|
: formGroups?.controls.map((control) => (
|
|
<Field showValidationHints={showValidationHints} control={control} readOnly={readOnly} />
|
|
))
|
|
}
|
|
{
|
|
submitControl && (
|
|
<Field showValidationHints={showValidationHints} control={new FormControl(submitControl)} />
|
|
)
|
|
}
|
|
</form>
|
|
|
|
<style>
|
|
.light {
|
|
color-scheme: light;
|
|
}
|
|
|
|
.dark {
|
|
color-scheme: dark;
|
|
}
|
|
</style>
|
|
|
|
<style is:global>
|
|
[data-validator-hints='true'][data-validator-error='true'],
|
|
[data-validator-hints='true'] [data-validator-error='true'] {
|
|
color: red;
|
|
border-color: red;
|
|
}
|
|
[data-validator-hints='true'][data-validator-warn='true'],
|
|
[data-validator-hints='true'] [data-validator-warn='true'] {
|
|
color: orange;
|
|
border-color: orange;
|
|
}
|
|
[data-validator-hints='true'][data-validator-info='true'],
|
|
[data-validator-hints='true'] [data-validator-info='true'] {
|
|
color: green;
|
|
border-color: green;
|
|
}
|
|
</style>
|