wcz-layout
Version:
86 lines (71 loc) • 2.27 kB
Markdown
---
name: forms
description: Best practices for building forms including validation and field types.
---
## Rules
- Always use `useLayoutForm` with pre-defined components.
- Define `width` for all form fields based on the expected content length.
- Derive Zod schemas from Drizzle table schemas using `createSelectSchema` with `t()` for validation messages.
## File Placement
```
src/routes/features/-components — Form components scoped to a feature
src/lib/schemas/ — Zod schemas
wcz-layout/hooks — shared hooks from npm package
```
## Examples
```ts
// Imports
import { useLayoutForm } from "wcz-layout/hooks";
import { LibrarySchema } from "~/lib/schemas/library";
// Form Component
interface FormProps {
defaultValues: Library;
onSubmit: (value: Library) => Promise<void>;
}
export const Form: FC<FormProps> = ({ defaultValues, onSubmit }) => {
const { t } = useTranslation();
const form = useLayoutForm({
defaultValues,
validators: { onChange: LibrarySchema },
onSubmit: async ({ value, formApi }) => {
await onSubmit(value);
formApi.reset();
},
});
return (
<form
onSubmit={(event) => {
event.preventDefault();
event.stopPropagation();
form.handleSubmit();
}}
>
{/* some styling */}
<form.AppField name="name">
{(field) => <field.TextField label={t("Library.Name")} required sx={{ width: 420 }} />}
</form.AppField>
{/* some styling */}
<form.AppForm>
<form.SubmitButton variant="contained">{t("Submit")}</form.SubmitButton>
</form.AppForm>
</form>
);
};
// Autocomplete
<field.Autocomplete
options={options}
sx={{ width: 250 }}
autoHighlight
autoSelect
autoComplete
loading={isLoading}
textFieldProps={{
label: t("Customer"),
required: true,
}}
/>
// Checkbox
<field.Checkbox label={t("IsThisTrue")} />
```
## Field Types
`Autocomplete` · `Checkbox` · `DatePicker` · `DateRangePicker` · `DateTimePicker` · `DateTimeRangePicker` · `NumberField` · `RadioGroup` · `Slider` · `SubmitButton` · `Switch` · `TextField` · `TimePicker` · `TimeRangePicker`