Skip to content
This repository has been archived by the owner on Dec 27, 2022. It is now read-only.

Commit

Permalink
feat: enable dynamic validation (#510)
Browse files Browse the repository at this point in the history
* feat: enable dynamic validation

* refactor: rename custom useField to useFormField
  • Loading branch information
baptisteArno authored Oct 7, 2022
1 parent 2f54878 commit aac01bd
Show file tree
Hide file tree
Showing 15 changed files with 173 additions and 133 deletions.
16 changes: 4 additions & 12 deletions src/components/CheckboxField/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { Checkbox } from '@scaleway/ui'
import { FieldState } from 'final-form'
import { ComponentProps, ReactNode, Ref, forwardRef } from 'react'
import { useField } from 'react-final-form'
import { pickValidators } from '../../helpers'
import { useValidation } from '../../hooks'
import { useFormField } from '../../hooks'
import { useErrors } from '../../providers/ErrorContext'
import { BaseFieldProps } from '../../types'

Expand Down Expand Up @@ -50,16 +48,10 @@ export const CheckboxField = forwardRef(
): JSX.Element => {
const { getError } = useErrors()

const validateFn = useValidation<CheckboxValue>({
validate,
validators: pickValidators({
required,
}),
})

const { input, meta } = useField(name, {
const { input, meta } = useFormField(name, {
required,
type: 'checkbox',
validate: validateFn,
validate,
value,
})

Expand Down
19 changes: 6 additions & 13 deletions src/components/DateField/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { DateInput } from '@scaleway/ui'
import { FieldState } from 'final-form'
import { ComponentProps, FocusEvent } from 'react'
import { useField } from 'react-final-form'
import { pickValidators } from '../../helpers'
import { useValidation } from '../../hooks'
import { useFormField } from '../../hooks'
import { useErrors } from '../../providers/ErrorContext'
import { BaseFieldProps } from '../../types'

Expand Down Expand Up @@ -58,19 +56,14 @@ export const DateField = ({
autoFocus = false,
}: DateFieldProps) => {
const { getError } = useErrors()
const validateFn = useValidation<Date>({
validate,
validators: pickValidators<Date>({
maxDate,
minDate,
required,
}),
})

const { input, meta } = useField<Date>(name, {
const { input, meta } = useFormField<Date>(name, {
formatOnBlur,
initialValue,
validate: validateFn,
maxDate,
minDate,
required,
validate,
value: inputVal,
})

Expand Down
16 changes: 4 additions & 12 deletions src/components/RadioField/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { Radio } from '@scaleway/ui'
import { FieldState } from 'final-form'
import { ComponentProps, ReactNode } from 'react'
import { useField } from 'react-final-form'
import { pickValidators } from '../../helpers'
import { useValidation } from '../../hooks'
import { useFormField } from '../../hooks'
import { useErrors } from '../../providers/ErrorContext'
import { BaseFieldProps } from '../../types'

Expand Down Expand Up @@ -40,16 +38,10 @@ export const RadioField = ({
}: RadioFieldProps): JSX.Element => {
const { getError } = useErrors()

const validateFn = useValidation<RadioValue>({
validate,
validators: pickValidators({
required,
}),
})

const { input, meta } = useField(name, {
const { input, meta } = useFormField(name, {
required,
type: 'radio',
validate: validateFn,
validate,
value,
})

Expand Down
17 changes: 5 additions & 12 deletions src/components/RichSelectField/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import {
useCallback,
useMemo,
} from 'react'
import { useField } from 'react-final-form'
import { pickValidators } from '../../helpers'
import { useValidation } from '../../hooks'
import { useFormField } from '../../hooks'
import { useErrors } from '../../providers/ErrorContext'
import { BaseFieldProps } from '../../types'

Expand Down Expand Up @@ -92,13 +90,6 @@ export const RichSelectField = <
noTopLabel,
}: RichSelectFieldProps<T>) => {
const { getError } = useErrors()
const validate = useValidation({
validators: pickValidators<T>({
maxLength,
minLength: minLength || required ? 1 : undefined,
required,
}),
})

const options = useMemo(
() =>
Expand Down Expand Up @@ -164,12 +155,14 @@ export const RichSelectField = <
[formatProp, multiple, name, options],
)

const { input, meta } = useField<T, HTMLElement, RichSelectOption>(name, {
const { input, meta } = useFormField<T, HTMLElement, RichSelectOption>(name, {
format,
formatOnBlur,
maxLength,
minLength: minLength || required ? 1 : undefined,
multiple,
parse,
validate,
required,
value,
})

Expand Down
16 changes: 4 additions & 12 deletions src/components/SelectNumberField/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { SelectNumber } from '@scaleway/ui'
import { ComponentProps, FocusEvent, FocusEventHandler } from 'react'
import { useField } from 'react-final-form'
import { pickValidators } from '../../helpers'
import { useValidation } from '../../hooks'
import { useFormField } from '../../hooks'
import { BaseFieldProps } from '../../types'

type SelectNumberValue = NonNullable<
Expand Down Expand Up @@ -53,16 +51,10 @@ export const SelectNumberField = ({
value,
className,
}: SelectNumberValueFieldProps) => {
const validateFn = useValidation<SelectNumberValue>({
validate,
validators: pickValidators({
required,
}),
})

const { input } = useField(name, {
const { input } = useFormField(name, {
required,
type: 'number',
validate: validateFn,
validate,
value,
})

Expand Down
16 changes: 4 additions & 12 deletions src/components/SelectableCardField/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { SelectableCard } from '@scaleway/ui'
import { FieldState } from 'final-form'
import { ComponentProps } from 'react'
import { useField } from 'react-final-form'
import { pickValidators } from '../../helpers'
import { useValidation } from '../../hooks'
import { useFormField } from '../../hooks'
import { useErrors } from '../../providers/ErrorContext'
import { BaseFieldProps } from '../../types'

Expand Down Expand Up @@ -56,16 +54,10 @@ export const SelectableCardField = ({
}: SelectableCardFieldProps): JSX.Element => {
const { getError } = useErrors()

const validateFn = useValidation<SelectableCardValue>({
validate,
validators: pickValidators({
required,
}),
})

const { input, meta } = useField(name, {
const { input, meta } = useFormField(name, {
required,
type: type ?? 'radio',
validate: validateFn,
validate,
value,
})

Expand Down
16 changes: 4 additions & 12 deletions src/components/TagsField/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { Tags } from '@scaleway/ui'
import { ComponentProps } from 'react'
import { useField } from 'react-final-form'
import { pickValidators } from '../../helpers'
import { useValidation } from '../../hooks'
import { useFormField } from '../../hooks'
import { BaseFieldProps } from '../../types'

export type TagsFieldProps<T = unknown, K = string> = BaseFieldProps<T, K> &
Expand All @@ -29,16 +27,10 @@ export const TagsField = ({
validate,
variant,
}: TagsFieldProps): JSX.Element => {
const validateFn = useValidation({
validate,
validators: pickValidators({
required,
}),
})

const { input } = useField(name, {
const { input } = useFormField(name, {
required,
type: 'text',
validate: validateFn,
validate,
})

return (
Expand Down
28 changes: 27 additions & 1 deletion src/components/TextBoxField/__stories__/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Checkbox } from '@scaleway/ui'
import { Meta, Story } from '@storybook/react'
import { ComponentProps } from 'react'
import { ComponentProps, useState } from 'react'
import { Form, Submit, TextBoxField } from '../..'
import { mockErrors } from '../../../mocks/mockErrors'

Expand Down Expand Up @@ -53,6 +54,31 @@ Required.args = {
required: true,
}

export const DynamicRequired: Story<
ComponentProps<typeof TextBoxField>
> = args => {
const [isRequired, setIsRequired] = useState(true)

return (
<>
<Checkbox
checked={isRequired}
onChange={() => setIsRequired(!isRequired)}
>
Is field required?
</Checkbox>
<TextBoxField {...args} required={isRequired} />
<div style={{ marginTop: 8 }}>
<Submit>Submit</Submit>
</div>
</>
)
}

DynamicRequired.args = {
name: 'required',
}

export const MinMaxLength: Story<
ComponentProps<typeof TextBoxField>
> = args => (
Expand Down
28 changes: 9 additions & 19 deletions src/components/TextBoxField/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { TextBox } from '@scaleway/ui'
import { FieldState } from 'final-form'
import { ComponentProps, FocusEvent, Ref, forwardRef } from 'react'
import { useField } from 'react-final-form'
import { pickValidators } from '../../helpers'
import { useValidation } from '../../hooks'
import { useFormField } from '../../hooks'
import { useErrors } from '../../providers/ErrorContext'
import { BaseFieldProps } from '../../types'

Expand Down Expand Up @@ -66,7 +64,6 @@ export const TextBoxField = forwardRef(
beforeSubmit,
className,
cols,
data,
defaultValue,
disabled,
fillAvailable,
Expand Down Expand Up @@ -111,33 +108,26 @@ export const TextBoxField = forwardRef(
): JSX.Element => {
const { getError } = useErrors()

const validateFn = useValidation<TextBoxValue>({
validate,
validators: pickValidators({
max,
maxLength,
min,
minLength,
regex,
required,
}),
})

const { input, meta } = useField(name, {
const { input, meta } = useFormField(name, {
afterSubmit,
allowNull,
beforeSubmit,
data,
defaultValue,
format,
formatOnBlur,
initialValue,
isEqual,
max,
maxLength,
min,
minLength,
multiple,
parse,
regex,
required,
subscription,
type,
validate: validateFn,
validate,
validateFields,
value,
})
Expand Down
16 changes: 4 additions & 12 deletions src/components/TimeField/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { TimeInput } from '@scaleway/ui'
import { ComponentProps, useMemo } from 'react'
import { useField } from 'react-final-form'
import { pickValidators } from '../../helpers'
import { useValidation } from '../../hooks'
import { useFormField } from '../../hooks'
import { BaseFieldProps } from '../../types'

const parseTime = (date?: Date | string): { label: string; value: string } => {
Expand Down Expand Up @@ -47,17 +45,11 @@ export const TimeField = ({
isSearchable,
options,
}: TimeFieldProps) => {
const validateFn = useValidation<Date>({
validate,
validators: pickValidators<Date>({
required,
}),
})

const { input, meta } = useField<Date>(name, {
const { input, meta } = useFormField<Date>(name, {
formatOnBlur,
initialValue,
validate: validateFn,
required,
validate,
value,
})

Expand Down
14 changes: 4 additions & 10 deletions src/components/ToggleField/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { Toggle } from '@scaleway/ui'
import { ComponentProps } from 'react'
import { useField } from 'react-final-form'
import { pickValidators } from '../../helpers'
import { useValidation } from '../../hooks'
import { useFormField } from '../../hooks'
import { BaseFieldProps } from '../../types'

type ToggleFieldProps<T = unknown, K = unknown> = BaseFieldProps<T, K> &
Expand Down Expand Up @@ -46,12 +44,7 @@ export const ToggleField = ({
value,
labelPosition,
}: ToggleFieldProps) => {
const validateFn = useValidation({
validate,
validators: pickValidators({ required }),
})

const { input } = useField(name, {
const { input } = useFormField(name, {
afterSubmit,
allowNull,
beforeSubmit,
Expand All @@ -63,9 +56,10 @@ export const ToggleField = ({
isEqual,
multiple,
parse,
required,
subscription,
type: 'checkbox',
validate: validateFn,
validate,
validateFields,
value,
})
Expand Down
Loading

0 comments on commit aac01bd

Please sign in to comment.