diff --git a/package.json b/package.json index d65a958..f3888b3 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ }, "devDependencies": { "@emotion/react": "^11.11.1", - "@form-atoms/field": "^4.0.0", + "@form-atoms/field": "^4.0.7", "@mdx-js/react": "^2.3.0", "@semantic-release/changelog": "^6.0.3", "@semantic-release/commit-analyzer": "^11.1.0", diff --git a/src/components/checkbox-field/CheckboxField.stories.tsx b/src/components/checkbox-field/CheckboxField.stories.tsx index b340d91..d2d5211 100644 --- a/src/components/checkbox-field/CheckboxField.stories.tsx +++ b/src/components/checkbox-field/CheckboxField.stories.tsx @@ -39,3 +39,20 @@ export const Optional: FormStory = { ), }, }; + +const imGoing = checkboxField(); + +export const Initialized: FormStory = { + ...optionalField, + args: { + fields: { imGoing }, + children: () => ( + + ), + }, +}; diff --git a/src/components/checkbox-field/CheckboxField.tsx b/src/components/checkbox-field/CheckboxField.tsx index b613f0c..a989078 100644 --- a/src/components/checkbox-field/CheckboxField.tsx +++ b/src/components/checkbox-field/CheckboxField.tsx @@ -1,5 +1,6 @@ import { CheckboxFieldProps, useCheckboxFieldProps } from "@form-atoms/field"; import { Checkbox, CheckboxProps, HelperText, Label } from "flowbite-react"; +import { ReactNode } from "react"; import { useFieldError } from "../../hooks"; @@ -7,9 +8,10 @@ export const CheckboxField = ({ field, label, helperText, + initialValue, ...uiProps -}: CheckboxFieldProps & CheckboxProps) => { - const props = useCheckboxFieldProps(field); +}: CheckboxFieldProps & CheckboxProps & { helperText?: ReactNode }) => { + const props = useCheckboxFieldProps(field, { initialValue }); const { color, error } = useFieldError(field); const help = error ?? helperText; diff --git a/src/components/checkbox-group-field/CheckboxGroupField.stories.tsx b/src/components/checkbox-group-field/CheckboxGroupField.stories.tsx index 15a918a..913e5af 100644 --- a/src/components/checkbox-group-field/CheckboxGroupField.stories.tsx +++ b/src/components/checkbox-group-field/CheckboxGroupField.stories.tsx @@ -44,3 +44,22 @@ export const Optional: FormStory = { ), }, }; + +const langs = stringArrayField(); + +export const Initialized: FormStory = { + ...optionalField, + args: { + fields: { langs }, + children: () => ( + + ), + }, +}; diff --git a/src/components/checkbox-group-field/CheckboxGroupField.tsx b/src/components/checkbox-group-field/CheckboxGroupField.tsx index 23d7b90..5fb6492 100644 --- a/src/components/checkbox-group-field/CheckboxGroupField.tsx +++ b/src/components/checkbox-group-field/CheckboxGroupField.tsx @@ -1,5 +1,4 @@ import { - FieldProps, UseCheckboxGroupProps, ZodArrayField, useCheckboxGroup, @@ -7,7 +6,14 @@ import { import { Checkbox, HelperText, Label } from "flowbite-react"; import { Option as BaseOption, type OptionRenderProp } from "../"; -import { FlowbiteField } from "../field"; +import { FlowbiteField, type FlowbiteFieldProps } from "../field"; + +export type CheckboxGroupFieldProps< + Option, + Field extends ZodArrayField, +> = FlowbiteFieldProps & + UseCheckboxGroupProps & + Partial; export const CheckboxGroupField = ({ field, @@ -17,17 +23,19 @@ export const CheckboxGroupField = ({ label, required, helperText, + initialValue, Option = BaseOption, ...uiProps -}: UseCheckboxGroupProps & - FieldProps & - Partial) => { - const checkboxGroup = useCheckboxGroup({ - field, - options, - getValue, - getLabel, - }); +}: CheckboxGroupFieldProps) => { + const checkboxGroup = useCheckboxGroup( + { + field, + options, + getValue, + getLabel, + }, + { initialValue }, + ); return ( & { id: string; helperText: ReactNode; @@ -20,16 +20,17 @@ type Children = RenderProp< } >; -type FlowbiteFieldProps> = FieldProps & - Children; +export type FlowbiteFieldProps = FieldProps & { + helperText?: ReactNode; +}; -export const FlowbiteField = >({ +export const FlowbiteField = ({ field, required, label, children, ...uiProps -}: FlowbiteFieldProps) => { +}: FlowbiteFieldProps & ChildrenProp) => { const id = `${field}`; const { color, error } = useFieldError(field); const requiredProps = useRequiredProps({ field, required }); diff --git a/src/components/file-field/FilesField.tsx b/src/components/file-field/FilesField.tsx index 87ab7ea..7b4da88 100644 --- a/src/components/file-field/FilesField.tsx +++ b/src/components/file-field/FilesField.tsx @@ -1,10 +1,10 @@ -import { FileFieldProps, useFilesFieldProps } from "@form-atoms/field"; +import { FilesFieldProps, useFilesFieldProps } from "@form-atoms/field"; import { FileInput, FileInputProps } from "flowbite-react"; import { InputColors } from "../../hooks"; import { FlowbiteField } from "../field"; -type FlowbiteFilesFieldProps = FileFieldProps & +type FlowbiteFilesFieldProps = FilesFieldProps & FileInputProps & { colors?: InputColors }; export const FilesField = ({ diff --git a/src/components/number-field/NumberField.stories.tsx b/src/components/number-field/NumberField.stories.tsx index aeb85dd..bd46e86 100644 --- a/src/components/number-field/NumberField.stories.tsx +++ b/src/components/number-field/NumberField.stories.tsx @@ -40,3 +40,14 @@ export const Optional: FormStory = { children: () => , }, }; + +const initialized = numberField(); + +export const Initialized: FormStory = { + args: { + fields: { initialized }, + children: () => ( + + ), + }, +}; diff --git a/src/components/number-field/NumberField.tsx b/src/components/number-field/NumberField.tsx index 90e18f1..a62cb28 100644 --- a/src/components/number-field/NumberField.tsx +++ b/src/components/number-field/NumberField.tsx @@ -8,9 +8,10 @@ export const NumberField = ({ field, helperText, required, + initialValue, ...inputProps }: NumberFieldProps & TextInputProps) => { - const props = useNumberFieldProps(field); + const props = useNumberFieldProps(field, { initialValue }); return ( )} diff --git a/src/components/radio-field/RadioField.stories.tsx b/src/components/radio-field/RadioField.stories.tsx index bf75459..944a526 100644 --- a/src/components/radio-field/RadioField.stories.tsx +++ b/src/components/radio-field/RadioField.stories.tsx @@ -42,3 +42,21 @@ export const Optional: FormStory = { ), }, }; + +const initialized = stringField(); + +export const Initialized: FormStory = { + args: { + fields: { country: initialized }, + children: () => ( + + ), + }, +}; diff --git a/src/components/radio-field/RadioField.tsx b/src/components/radio-field/RadioField.tsx index 8e45deb..298671a 100644 --- a/src/components/radio-field/RadioField.tsx +++ b/src/components/radio-field/RadioField.tsx @@ -1,5 +1,4 @@ import { - FieldProps, RadioGroupProps, SelectField, useOptions, @@ -12,9 +11,19 @@ import { RenderProp } from "react-render-prop-type"; import { Option as BaseOption, FlowbiteField, + FlowbiteFieldProps, type OptionRenderProp, } from "../"; +type ContainerProp = RenderProp; + +export type RadioFieldProps< + Option, + Field extends SelectField, +> = FlowbiteFieldProps & + RadioGroupProps & + Partial; + export const RadioField = ({ field, options, @@ -23,13 +32,15 @@ export const RadioField = ({ label, helperText, required, + initialValue, Container = Fragment, Option = BaseOption, ...uiProps -}: RadioGroupProps & - Omit, "field"> & - Partial & OptionRenderProp>) => { - const props = useSelectFieldProps({ field, options, getValue }); +}: RadioFieldProps) => { + const props = useSelectFieldProps( + { field, options, getValue }, + { initialValue }, + ); const { renderOptions } = useOptions({ field, options, getLabel }); return ( diff --git a/src/components/radio-option/RadioOption.tsx b/src/components/radio-option/RadioOption.tsx index 57e2f6b..2729585 100644 --- a/src/components/radio-option/RadioOption.tsx +++ b/src/components/radio-option/RadioOption.tsx @@ -6,6 +6,7 @@ import { } from "@form-atoms/field"; import { HelperText, Label, Radio } from "flowbite-react"; import { useAtomValue } from "jotai"; +import { ReactNode } from "react"; import { useFieldError } from "../../hooks"; import { RequiredIndicator } from "../required-indicator"; @@ -15,7 +16,7 @@ export const RadioOption = ({ required, label, helperText, -}: FieldProps) => { +}: FieldProps & { helperText?: ReactNode }) => { const id = `${field}`; const props = useCheckboxFieldProps(field); const { error } = useFieldError(field); diff --git a/src/components/rating-field/RatingField.stories.tsx b/src/components/rating-field/RatingField.stories.tsx index 0598177..41b4d7b 100644 --- a/src/components/rating-field/RatingField.stories.tsx +++ b/src/components/rating-field/RatingField.stories.tsx @@ -36,3 +36,19 @@ export const Optional: FormStory = { ), }, }; + +const initial = numberField(); + +export const Initialized: FormStory = { + ...optionalField, + args: { + fields: { initial }, + children: () => ( + + ), + }, +}; diff --git a/src/components/rating-field/RatingField.tsx b/src/components/rating-field/RatingField.tsx index 3f3ab2e..50e5a0e 100644 --- a/src/components/rating-field/RatingField.tsx +++ b/src/components/rating-field/RatingField.tsx @@ -1,20 +1,29 @@ -import { NumberFieldProps, useNumberFieldProps } from "@form-atoms/field"; +import { + NumberField, + NumberFieldProps, + useNumberFieldProps, +} from "@form-atoms/field"; import { HelperText, Rating, RatingProps } from "flowbite-react"; import { useFieldActions } from "form-atoms"; -import { FlowbiteField } from "../field"; +import { FlowbiteField, FlowbiteFieldProps } from "../field"; const options = [1, 2, 3, 4, 5]; +export type RatingFieldProps = FlowbiteFieldProps & + RatingProps & + NumberFieldProps; + export const RatingField = ({ field, size = "md", label, helperText, required, + initialValue, ...uiProps -}: RatingProps & NumberFieldProps) => { - const props = useNumberFieldProps(field); +}: RatingFieldProps) => { + const props = useNumberFieldProps(field, { initialValue }); const actions = useFieldActions(field); return ( diff --git a/src/components/select-field/SelectField.stories.tsx b/src/components/select-field/SelectField.stories.tsx index 6213379..3853398 100644 --- a/src/components/select-field/SelectField.stories.tsx +++ b/src/components/select-field/SelectField.stories.tsx @@ -44,3 +44,22 @@ export const Optional: FormStory = { ), }, }; + +const initial = stringField(); + +export const Initialized: FormStory = { + args: { + fields: { country: initial }, + children: () => ( + + ), + }, +}; diff --git a/src/components/select-field/SelectField.tsx b/src/components/select-field/SelectField.tsx index 5c68cf4..c4f5139 100644 --- a/src/components/select-field/SelectField.tsx +++ b/src/components/select-field/SelectField.tsx @@ -6,10 +6,14 @@ import { useSelectOptions, } from "@form-atoms/field"; import { SelectProps as FlowbiteSelectProps, Select } from "flowbite-react"; -import { ReactNode } from "react"; import { FlowbiteField } from "../field"; +export type SelectFieldProps< + Option, + Field extends SelectZodField, +> = SelectProps & FlowbiteSelectProps; + export const SelectField = ({ field, options, @@ -19,10 +23,13 @@ export const SelectField = ({ label, helperText, required, + initialValue, ...uiProps -}: SelectProps & - FlowbiteSelectProps & { label?: ReactNode }) => { - const props = useSelectFieldProps({ field, options, getValue }); +}: SelectFieldProps) => { + const props = useSelectFieldProps( + { field, options, getValue }, + { initialValue }, + ); const { selectOptions } = useSelectOptions({ field, options, diff --git a/src/components/slider-field/SliderField.stories.tsx b/src/components/slider-field/SliderField.stories.tsx index ec0b35e..eeadadb 100644 --- a/src/components/slider-field/SliderField.stories.tsx +++ b/src/components/slider-field/SliderField.stories.tsx @@ -47,3 +47,25 @@ export const Optional: FormStory = { ), }, }; + +const initial = numberField({ + schema: z + .number({ required_error: "Please adjust your confidence" }) + .min(0) + .max(100), +}).optional(); + +export const Initialized: FormStory = { + args: { + fields: { confidence: initial }, + children: () => ( + + ), + }, +}; diff --git a/src/components/slider-field/SliderField.tsx b/src/components/slider-field/SliderField.tsx index 82ec498..ebd744e 100644 --- a/src/components/slider-field/SliderField.tsx +++ b/src/components/slider-field/SliderField.tsx @@ -1,16 +1,26 @@ import { NumberFieldProps, useNumberFieldProps } from "@form-atoms/field"; -import { HelperText, RangeSlider, RangeSliderProps } from "flowbite-react"; +import { + HelperText, + RangeSlider, + RangeSliderProps, + TextInputProps, +} from "flowbite-react"; import { FlowbiteField } from "../field"; +export type SliderFieldProps = NumberFieldProps & + RangeSliderProps & + Pick; + export const SliderField = ({ field, label, required, helperText, + initialValue, ...inputProps -}: NumberFieldProps & RangeSliderProps) => { - const props = useNumberFieldProps(field); +}: SliderFieldProps) => { + const props = useNumberFieldProps(field, { initialValue }); return ( ( + + ), + }, +}; + const email = textField({ schema: z.string().email(), }); diff --git a/src/components/text-field/TextField.tsx b/src/components/text-field/TextField.tsx index f485238..caab40f 100644 --- a/src/components/text-field/TextField.tsx +++ b/src/components/text-field/TextField.tsx @@ -12,9 +12,10 @@ export const TextField = ({ field, helperText, required, + initialValue, ...uiProps }: FlowbiteTextFieldProps) => { - const props = useTextFieldProps(field); + const props = useTextFieldProps(field, { initialValue }); return ( diff --git a/src/components/textarea-field/TextareaField.stories.tsx b/src/components/textarea-field/TextareaField.stories.tsx index 737de6f..60d6a8c 100644 --- a/src/components/textarea-field/TextareaField.stories.tsx +++ b/src/components/textarea-field/TextareaField.stories.tsx @@ -28,3 +28,18 @@ export const Optional: FormStory = { children: () => , }, }; + +const initial = textField(); + +export const Initialized: FormStory = { + args: { + fields: { initial }, + children: () => ( + + ), + }, +}; diff --git a/src/components/textarea-field/TextareaField.tsx b/src/components/textarea-field/TextareaField.tsx index 23a8c06..311fbaa 100644 --- a/src/components/textarea-field/TextareaField.tsx +++ b/src/components/textarea-field/TextareaField.tsx @@ -12,9 +12,10 @@ export const TextareaField = ({ field, helperText, required, + initialValue, ...uiProps }: FlowbiteTextFieldProps) => { - const props = useTextFieldProps(field); + const props = useTextFieldProps(field, { initialValue }); return ( {(fieldProps) => ( -