diff --git a/src/fields/boolean-field/Docs.mdx b/src/fields/boolean-field/Docs.mdx index ba9cd1a..96b241b 100644 --- a/src/fields/boolean-field/Docs.mdx +++ b/src/fields/boolean-field/Docs.mdx @@ -1,8 +1,8 @@ -import { Meta, Markdown } from "@storybook/blocks"; - +import { Meta, Markdown, Stories } from "@storybook/blocks"; +import * as BooleanFieldStories from "./booleanField.stories"; import Config from "./config.md?raw"; - + # `booleanField(): ValidatedFieldAtom` @@ -23,3 +23,49 @@ const yesNoAnswer = booleanField({ ## Initial Config {Config} + +## useBooleanFieldProps() + +The `useBooleanFieldProps` will parse the input values as boolean. You can think of it like `valueAsBoolean` which is similar to `valueAsNumber` used in the `useNumberFieldProps`. +Note that the example uses generic `useSelectOptions` hook. + +```tsx +const YesNoOptions = ({ + field, + label, + getValue, + getLabel, + options, +}: SelectFieldProps) => { + const props = useBooleanFieldProps(field); + + const { renderOptions } = useSelectOptions(field, { + getValue, + getLabel, + options, + }); + + return ( +
+ + {renderOptions.map(({ id, value, label, isActive }) => ( +
+ + +
+ ))} +
+ +
+
+ ); +}; +``` + + diff --git a/src/fields/boolean-field/booleanField.stories.tsx b/src/fields/boolean-field/booleanField.stories.tsx new file mode 100644 index 0000000..66ad447 --- /dev/null +++ b/src/fields/boolean-field/booleanField.stories.tsx @@ -0,0 +1,99 @@ +import { booleanField } from "./booleanField"; +import { useBooleanFieldProps } from "./useBooleanFieldProps"; +import { FieldLabel } from "../../components"; +import { FieldErrors } from "../../components/field-errors"; +import { FormStory, fixArgs, meta } from "../../scenarios/StoryForm"; +import { SelectFieldProps, useSelectOptions } from "../select-field"; + +export default { + ...meta, + title: "fields/booleanField", +}; + +const YesNoOptions = ({ + field, + label, + getValue, + getLabel, + options, +}: SelectFieldProps) => { + const props = useBooleanFieldProps(field); + + const { renderOptions } = useSelectOptions(field, { + getValue, + getLabel, + options, + }); + + return ( +
+ + {renderOptions.map(({ id, value, label, isActive }) => ( +
+ + +
+ ))} +
+ +
+
+ ); +}; + +const yesNoOptions = [ + { + label: "Yes, I accept the Funeral terms.", + value: true, + }, + { + label: "No, I don't accept the Funeral terms.", + value: false, + }, +]; +export const Required: FormStory = { + args: fixArgs({ + fields: { + termsOfService: booleanField(), + }, + children: ({ fields }) => ( + label} + getValue={({ value }) => value} + /> + ), + }), +}; + +// export const Optional: FormStory = { +// args: fixArgs({ +// fields: { +// newsletter: checkboxField({ +// optional: true, +// }), +// }, +// children: ({ fields }) => ( +// +// ), +// }), +// parameters: { +// docs: { +// description: { +// story: +// "Optional checkboxField will have true or false value in the submit data.", +// }, +// }, +// }, +// }; diff --git a/src/fields/boolean-field/booleanField.ts b/src/fields/boolean-field/booleanField.ts index e895819..0d33bc2 100644 --- a/src/fields/boolean-field/booleanField.ts +++ b/src/fields/boolean-field/booleanField.ts @@ -1,14 +1,20 @@ import { z } from "zod"; -import { ValidatedFieldAtomConfig, validatedFieldAtom } from ".."; +import { + ValidatedFieldAtom, + ValidatedFieldAtomConfig, + validatedFieldAtom, +} from ".."; import { ZodParams, defaultParams } from "../zodParams"; export type BooleanFieldValue = boolean | undefined; +export type BooleanFieldAtom = ValidatedFieldAtom; + export const booleanField = ({ required_error = defaultParams.required_error, ...config -}: Partial> & ZodParams) => +}: Partial> & ZodParams = {}) => validatedFieldAtom({ value: undefined, schema: z.boolean({ required_error }), diff --git a/src/fields/boolean-field/useBooleanFieldProps.ts b/src/fields/boolean-field/useBooleanFieldProps.ts new file mode 100644 index 0000000..f15a67c --- /dev/null +++ b/src/fields/boolean-field/useBooleanFieldProps.ts @@ -0,0 +1,15 @@ +import { ChangeEvent } from "react"; + +import { BooleanFieldAtom } from "./booleanField"; +import { FieldProps, useFieldProps } from "../../hooks"; + +export type NumberFieldProps = FieldProps; + +const valueAsBoolean = (event: ChangeEvent) => { + const value = JSON.parse(event.currentTarget.value); + + return typeof value === "boolean" ? value : undefined; +}; + +export const useBooleanFieldProps = (field: BooleanFieldAtom) => + useFieldProps(field, valueAsBoolean);