@saas-ui/forms 2.0.0-next.3 → 2.0.0-next.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
 - package/README.md +53 -6
 - package/dist/ajv/index.d.ts +1 -1
 - package/dist/ajv/index.js.map +1 -1
 - package/dist/ajv/index.mjs.map +1 -1
 - package/dist/index.d.ts +265 -166
 - package/dist/index.js +2821 -556
 - package/dist/index.js.map +1 -1
 - package/dist/index.mjs +2814 -555
 - package/dist/index.mjs.map +1 -1
 - package/dist/yup/index.d.ts +98 -6
 - package/dist/yup/index.js.map +1 -1
 - package/dist/yup/index.mjs.map +1 -1
 - package/dist/zod/index.d.ts +97 -4
 - package/dist/zod/index.js.map +1 -1
 - package/dist/zod/index.mjs.map +1 -1
 - package/package.json +5 -3
 - package/src/array-field.tsx +50 -30
 - package/src/auto-form.tsx +7 -3
 - package/src/base-field.tsx +59 -0
 - package/src/create-field.tsx +143 -0
 - package/src/create-form.tsx +31 -0
 - package/src/default-fields.tsx +146 -0
 - package/src/display-field.tsx +8 -9
 - package/src/display-if.tsx +6 -5
 - package/src/field-resolver.ts +1 -1
 - package/src/field.tsx +14 -444
 - package/src/fields-context.tsx +23 -0
 - package/src/fields.tsx +18 -8
 - package/src/form.tsx +27 -37
 - package/src/index.ts +38 -0
 - package/src/input-right-button/input-right-button.stories.tsx +1 -1
 - package/src/input-right-button/input-right-button.tsx +0 -2
 - package/src/layout.tsx +16 -11
 - package/src/number-input/number-input.tsx +9 -5
 - package/src/object-field.tsx +8 -7
 - package/src/password-input/password-input.stories.tsx +23 -2
 - package/src/password-input/password-input.tsx +5 -5
 - package/src/pin-input/pin-input.tsx +1 -5
 - package/src/radio/radio-input.stories.tsx +1 -1
 - package/src/radio/radio-input.tsx +12 -10
 - package/src/select/native-select.tsx +1 -4
 - package/src/select/select.test.tsx +1 -1
 - package/src/select/select.tsx +18 -14
 - package/src/step-form.tsx +29 -11
 - package/src/submit-button.tsx +5 -1
 - package/src/types.ts +91 -0
 - package/src/utils.ts +15 -0
 - /package/src/radio/{radio.test.tsx → radio-input.test.tsx} +0 -0
 
| 
         @@ -0,0 +1,59 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import * as React from 'react'
         
     | 
| 
      
 2 
     | 
    
         
            +
            import {
         
     | 
| 
      
 3 
     | 
    
         
            +
              useFormContext,
         
     | 
| 
      
 4 
     | 
    
         
            +
              FormState,
         
     | 
| 
      
 5 
     | 
    
         
            +
              get,
         
     | 
| 
      
 6 
     | 
    
         
            +
              RegisterOptions,
         
     | 
| 
      
 7 
     | 
    
         
            +
              FieldValues,
         
     | 
| 
      
 8 
     | 
    
         
            +
            } from 'react-hook-form'
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            import {
         
     | 
| 
      
 11 
     | 
    
         
            +
              Box,
         
     | 
| 
      
 12 
     | 
    
         
            +
              FormControl,
         
     | 
| 
      
 13 
     | 
    
         
            +
              FormLabel,
         
     | 
| 
      
 14 
     | 
    
         
            +
              FormHelperText,
         
     | 
| 
      
 15 
     | 
    
         
            +
              FormErrorMessage,
         
     | 
| 
      
 16 
     | 
    
         
            +
            } from '@chakra-ui/react'
         
     | 
| 
      
 17 
     | 
    
         
            +
            import { FocusableElement } from '@chakra-ui/utils'
         
     | 
| 
      
 18 
     | 
    
         
            +
            import { useField } from './fields-context'
         
     | 
| 
      
 19 
     | 
    
         
            +
            import { BaseFieldProps, FieldProps } from './types'
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            const getError = (name: string, formState: FormState<{ [x: string]: any }>) => {
         
     | 
| 
      
 22 
     | 
    
         
            +
              return get(formState.errors, name)
         
     | 
| 
      
 23 
     | 
    
         
            +
            }
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            const isTouched = (
         
     | 
| 
      
 26 
     | 
    
         
            +
              name: string,
         
     | 
| 
      
 27 
     | 
    
         
            +
              formState: FormState<{ [x: string]: any }>
         
     | 
| 
      
 28 
     | 
    
         
            +
            ) => {
         
     | 
| 
      
 29 
     | 
    
         
            +
              return get(formState.touchedFields, name)
         
     | 
| 
      
 30 
     | 
    
         
            +
            }
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            /**
         
     | 
| 
      
 33 
     | 
    
         
            +
             * The default BaseField component
         
     | 
| 
      
 34 
     | 
    
         
            +
             * Composes the Chakra UI FormControl component, with FormLabel, FormHelperText and FormErrorMessage.
         
     | 
| 
      
 35 
     | 
    
         
            +
             */
         
     | 
| 
      
 36 
     | 
    
         
            +
            export const BaseField: React.FC<BaseFieldProps> = (props) => {
         
     | 
| 
      
 37 
     | 
    
         
            +
              const { name, label, help, hideLabel, children, ...controlProps } = props
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
              const { formState } = useFormContext()
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              const error = getError(name, formState)
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
              return (
         
     | 
| 
      
 44 
     | 
    
         
            +
                <FormControl {...controlProps} isInvalid={!!error}>
         
     | 
| 
      
 45 
     | 
    
         
            +
                  {label && !hideLabel ? <FormLabel>{label}</FormLabel> : null}
         
     | 
| 
      
 46 
     | 
    
         
            +
                  <Box>
         
     | 
| 
      
 47 
     | 
    
         
            +
                    {children}
         
     | 
| 
      
 48 
     | 
    
         
            +
                    {help && !error?.message ? (
         
     | 
| 
      
 49 
     | 
    
         
            +
                      <FormHelperText>{help}</FormHelperText>
         
     | 
| 
      
 50 
     | 
    
         
            +
                    ) : null}
         
     | 
| 
      
 51 
     | 
    
         
            +
                    {error?.message && (
         
     | 
| 
      
 52 
     | 
    
         
            +
                      <FormErrorMessage>{error?.message}</FormErrorMessage>
         
     | 
| 
      
 53 
     | 
    
         
            +
                    )}
         
     | 
| 
      
 54 
     | 
    
         
            +
                  </Box>
         
     | 
| 
      
 55 
     | 
    
         
            +
                </FormControl>
         
     | 
| 
      
 56 
     | 
    
         
            +
              )
         
     | 
| 
      
 57 
     | 
    
         
            +
            }
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            BaseField.displayName = 'BaseField'
         
     | 
| 
         @@ -0,0 +1,143 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import * as React from 'react'
         
     | 
| 
      
 2 
     | 
    
         
            +
            import { useFormContext, Controller } from 'react-hook-form'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            import { forwardRef, useMergeRefs } from '@chakra-ui/react'
         
     | 
| 
      
 5 
     | 
    
         
            +
            import { callAllHandlers } from '@chakra-ui/utils'
         
     | 
| 
      
 6 
     | 
    
         
            +
            import { BaseFieldProps, FieldProps } from './types'
         
     | 
| 
      
 7 
     | 
    
         
            +
            import { BaseField } from './base-field'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            interface CreateFieldProps {
         
     | 
| 
      
 10 
     | 
    
         
            +
              displayName: string
         
     | 
| 
      
 11 
     | 
    
         
            +
              hideLabel?: boolean
         
     | 
| 
      
 12 
     | 
    
         
            +
              BaseField: React.FC<any>
         
     | 
| 
      
 13 
     | 
    
         
            +
            }
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            const _createField = (
         
     | 
| 
      
 16 
     | 
    
         
            +
              InputComponent: React.FC<any>,
         
     | 
| 
      
 17 
     | 
    
         
            +
              { displayName, hideLabel, BaseField }: CreateFieldProps
         
     | 
| 
      
 18 
     | 
    
         
            +
            ) => {
         
     | 
| 
      
 19 
     | 
    
         
            +
              const Field = forwardRef((props, ref) => {
         
     | 
| 
      
 20 
     | 
    
         
            +
                const {
         
     | 
| 
      
 21 
     | 
    
         
            +
                  id,
         
     | 
| 
      
 22 
     | 
    
         
            +
                  name,
         
     | 
| 
      
 23 
     | 
    
         
            +
                  label,
         
     | 
| 
      
 24 
     | 
    
         
            +
                  help,
         
     | 
| 
      
 25 
     | 
    
         
            +
                  isDisabled,
         
     | 
| 
      
 26 
     | 
    
         
            +
                  isInvalid,
         
     | 
| 
      
 27 
     | 
    
         
            +
                  isReadOnly,
         
     | 
| 
      
 28 
     | 
    
         
            +
                  isRequired,
         
     | 
| 
      
 29 
     | 
    
         
            +
                  rules,
         
     | 
| 
      
 30 
     | 
    
         
            +
                  ...inputProps
         
     | 
| 
      
 31 
     | 
    
         
            +
                } = props
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                const inputRules = {
         
     | 
| 
      
 34 
     | 
    
         
            +
                  required: isRequired,
         
     | 
| 
      
 35 
     | 
    
         
            +
                  ...rules,
         
     | 
| 
      
 36 
     | 
    
         
            +
                }
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                return (
         
     | 
| 
      
 39 
     | 
    
         
            +
                  <BaseField
         
     | 
| 
      
 40 
     | 
    
         
            +
                    id={id}
         
     | 
| 
      
 41 
     | 
    
         
            +
                    name={name}
         
     | 
| 
      
 42 
     | 
    
         
            +
                    label={label}
         
     | 
| 
      
 43 
     | 
    
         
            +
                    help={help}
         
     | 
| 
      
 44 
     | 
    
         
            +
                    hideLabel={hideLabel}
         
     | 
| 
      
 45 
     | 
    
         
            +
                    isDisabled={isDisabled}
         
     | 
| 
      
 46 
     | 
    
         
            +
                    isInvalid={isInvalid}
         
     | 
| 
      
 47 
     | 
    
         
            +
                    isReadOnly={isReadOnly}
         
     | 
| 
      
 48 
     | 
    
         
            +
                    isRequired={isRequired}
         
     | 
| 
      
 49 
     | 
    
         
            +
                  >
         
     | 
| 
      
 50 
     | 
    
         
            +
                    <InputComponent
         
     | 
| 
      
 51 
     | 
    
         
            +
                      ref={ref}
         
     | 
| 
      
 52 
     | 
    
         
            +
                      id={id}
         
     | 
| 
      
 53 
     | 
    
         
            +
                      name={name}
         
     | 
| 
      
 54 
     | 
    
         
            +
                      label={hideLabel ? label : undefined} // Only pass down the label when it should be inline.
         
     | 
| 
      
 55 
     | 
    
         
            +
                      rules={inputRules}
         
     | 
| 
      
 56 
     | 
    
         
            +
                      {...inputProps}
         
     | 
| 
      
 57 
     | 
    
         
            +
                    />
         
     | 
| 
      
 58 
     | 
    
         
            +
                  </BaseField>
         
     | 
| 
      
 59 
     | 
    
         
            +
                )
         
     | 
| 
      
 60 
     | 
    
         
            +
              })
         
     | 
| 
      
 61 
     | 
    
         
            +
              Field.displayName = displayName
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
              return Field
         
     | 
| 
      
 64 
     | 
    
         
            +
            }
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            const withControlledInput = (InputComponent: React.FC<any>) => {
         
     | 
| 
      
 67 
     | 
    
         
            +
              return forwardRef<FieldProps, typeof InputComponent>(
         
     | 
| 
      
 68 
     | 
    
         
            +
                ({ name, rules, ...inputProps }, ref) => {
         
     | 
| 
      
 69 
     | 
    
         
            +
                  const { control } = useFormContext()
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                  return (
         
     | 
| 
      
 72 
     | 
    
         
            +
                    <Controller
         
     | 
| 
      
 73 
     | 
    
         
            +
                      name={name}
         
     | 
| 
      
 74 
     | 
    
         
            +
                      control={control}
         
     | 
| 
      
 75 
     | 
    
         
            +
                      rules={rules}
         
     | 
| 
      
 76 
     | 
    
         
            +
                      render={({ field: { ref: _ref, ...field } }) => (
         
     | 
| 
      
 77 
     | 
    
         
            +
                        <InputComponent
         
     | 
| 
      
 78 
     | 
    
         
            +
                          {...field}
         
     | 
| 
      
 79 
     | 
    
         
            +
                          {...inputProps}
         
     | 
| 
      
 80 
     | 
    
         
            +
                          onChange={callAllHandlers(inputProps.onChange, field.onChange)}
         
     | 
| 
      
 81 
     | 
    
         
            +
                          onBlur={callAllHandlers(inputProps.onBlur, field.onBlur)}
         
     | 
| 
      
 82 
     | 
    
         
            +
                          ref={useMergeRefs(ref, _ref)}
         
     | 
| 
      
 83 
     | 
    
         
            +
                        />
         
     | 
| 
      
 84 
     | 
    
         
            +
                      )}
         
     | 
| 
      
 85 
     | 
    
         
            +
                    />
         
     | 
| 
      
 86 
     | 
    
         
            +
                  )
         
     | 
| 
      
 87 
     | 
    
         
            +
                }
         
     | 
| 
      
 88 
     | 
    
         
            +
              )
         
     | 
| 
      
 89 
     | 
    
         
            +
            }
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
            const withUncontrolledInput = (InputComponent: React.FC<any>) => {
         
     | 
| 
      
 92 
     | 
    
         
            +
              return forwardRef<FieldProps, typeof InputComponent>(
         
     | 
| 
      
 93 
     | 
    
         
            +
                ({ name, rules, ...inputProps }, ref) => {
         
     | 
| 
      
 94 
     | 
    
         
            +
                  const { register } = useFormContext()
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                  const { ref: _ref, ...field } = register(name, rules)
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                  return (
         
     | 
| 
      
 99 
     | 
    
         
            +
                    <InputComponent
         
     | 
| 
      
 100 
     | 
    
         
            +
                      {...field}
         
     | 
| 
      
 101 
     | 
    
         
            +
                      {...inputProps}
         
     | 
| 
      
 102 
     | 
    
         
            +
                      onChange={callAllHandlers(inputProps.onChange, field.onChange)}
         
     | 
| 
      
 103 
     | 
    
         
            +
                      onBlur={callAllHandlers(inputProps.onBlur, field.onBlur)}
         
     | 
| 
      
 104 
     | 
    
         
            +
                      ref={useMergeRefs(ref, _ref)}
         
     | 
| 
      
 105 
     | 
    
         
            +
                    />
         
     | 
| 
      
 106 
     | 
    
         
            +
                  )
         
     | 
| 
      
 107 
     | 
    
         
            +
                }
         
     | 
| 
      
 108 
     | 
    
         
            +
              )
         
     | 
| 
      
 109 
     | 
    
         
            +
            }
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
            export interface CreateFieldOptions {
         
     | 
| 
      
 112 
     | 
    
         
            +
              isControlled?: boolean
         
     | 
| 
      
 113 
     | 
    
         
            +
              hideLabel?: boolean
         
     | 
| 
      
 114 
     | 
    
         
            +
              BaseField?: React.FC<any>
         
     | 
| 
      
 115 
     | 
    
         
            +
            }
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
            /**
         
     | 
| 
      
 118 
     | 
    
         
            +
             * Register a new field type
         
     | 
| 
      
 119 
     | 
    
         
            +
             * @param type The name for this field in kebab-case, eg `email` or `array-field`
         
     | 
| 
      
 120 
     | 
    
         
            +
             * @param component The React component
         
     | 
| 
      
 121 
     | 
    
         
            +
             * @param options
         
     | 
| 
      
 122 
     | 
    
         
            +
             * @param options.isControlled Set this to true if this is a controlled field.
         
     | 
| 
      
 123 
     | 
    
         
            +
             * @param options.hideLabel Hide the field label, for example for the checkbox field.
         
     | 
| 
      
 124 
     | 
    
         
            +
             */
         
     | 
| 
      
 125 
     | 
    
         
            +
            export const createField = <TProps extends object>(
         
     | 
| 
      
 126 
     | 
    
         
            +
              component: React.FC<TProps>,
         
     | 
| 
      
 127 
     | 
    
         
            +
              options?: CreateFieldOptions
         
     | 
| 
      
 128 
     | 
    
         
            +
            ) => {
         
     | 
| 
      
 129 
     | 
    
         
            +
              let InputComponent
         
     | 
| 
      
 130 
     | 
    
         
            +
              if (options?.isControlled) {
         
     | 
| 
      
 131 
     | 
    
         
            +
                InputComponent = withControlledInput(component)
         
     | 
| 
      
 132 
     | 
    
         
            +
              } else {
         
     | 
| 
      
 133 
     | 
    
         
            +
                InputComponent = withUncontrolledInput(component)
         
     | 
| 
      
 134 
     | 
    
         
            +
              }
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
              const Field = _createField(InputComponent, {
         
     | 
| 
      
 137 
     | 
    
         
            +
                displayName: `${component.displayName ?? 'Custom'}Field`,
         
     | 
| 
      
 138 
     | 
    
         
            +
                hideLabel: options?.hideLabel,
         
     | 
| 
      
 139 
     | 
    
         
            +
                BaseField: options?.BaseField || BaseField,
         
     | 
| 
      
 140 
     | 
    
         
            +
              }) as React.FC<TProps & BaseFieldProps>
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
              return Field
         
     | 
| 
      
 143 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import React from 'react'
         
     | 
| 
      
 2 
     | 
    
         
            +
            import { FieldsProvider } from './fields-context'
         
     | 
| 
      
 3 
     | 
    
         
            +
            import { Form, FieldValues, FormProps, GetResolver } from './form'
         
     | 
| 
      
 4 
     | 
    
         
            +
            import { WithFields } from './types'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            export interface CreateFormProps<FieldDefs> {
         
     | 
| 
      
 7 
     | 
    
         
            +
              resolver?: GetResolver
         
     | 
| 
      
 8 
     | 
    
         
            +
              fields?: FieldDefs extends Record<string, React.FC<any>> ? FieldDefs : never
         
     | 
| 
      
 9 
     | 
    
         
            +
            }
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            export function createForm<FieldDefs, Schema = any>({
         
     | 
| 
      
 12 
     | 
    
         
            +
              resolver,
         
     | 
| 
      
 13 
     | 
    
         
            +
              fields,
         
     | 
| 
      
 14 
     | 
    
         
            +
            }: CreateFormProps<FieldDefs> = {}) {
         
     | 
| 
      
 15 
     | 
    
         
            +
              const CreateForm = <
         
     | 
| 
      
 16 
     | 
    
         
            +
                TFieldValues extends FieldValues,
         
     | 
| 
      
 17 
     | 
    
         
            +
                TContext extends object = object,
         
     | 
| 
      
 18 
     | 
    
         
            +
                TSchema extends Schema = Schema
         
     | 
| 
      
 19 
     | 
    
         
            +
              >(
         
     | 
| 
      
 20 
     | 
    
         
            +
                props: WithFields<FormProps<TFieldValues, TContext, TSchema>, FieldDefs>
         
     | 
| 
      
 21 
     | 
    
         
            +
              ) => {
         
     | 
| 
      
 22 
     | 
    
         
            +
                const { schema, ...rest } = props
         
     | 
| 
      
 23 
     | 
    
         
            +
                return (
         
     | 
| 
      
 24 
     | 
    
         
            +
                  <FieldsProvider value={fields || {}}>
         
     | 
| 
      
 25 
     | 
    
         
            +
                    <Form resolver={resolver?.(props.schema)} {...rest} />
         
     | 
| 
      
 26 
     | 
    
         
            +
                  </FieldsProvider>
         
     | 
| 
      
 27 
     | 
    
         
            +
                )
         
     | 
| 
      
 28 
     | 
    
         
            +
              }
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              return CreateForm
         
     | 
| 
      
 31 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,146 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import * as React from 'react'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            import {
         
     | 
| 
      
 4 
     | 
    
         
            +
              forwardRef,
         
     | 
| 
      
 5 
     | 
    
         
            +
              Input,
         
     | 
| 
      
 6 
     | 
    
         
            +
              Textarea,
         
     | 
| 
      
 7 
     | 
    
         
            +
              Checkbox,
         
     | 
| 
      
 8 
     | 
    
         
            +
              Switch,
         
     | 
| 
      
 9 
     | 
    
         
            +
              InputGroup,
         
     | 
| 
      
 10 
     | 
    
         
            +
              InputProps,
         
     | 
| 
      
 11 
     | 
    
         
            +
              TextareaProps,
         
     | 
| 
      
 12 
     | 
    
         
            +
              SwitchProps,
         
     | 
| 
      
 13 
     | 
    
         
            +
              CheckboxProps,
         
     | 
| 
      
 14 
     | 
    
         
            +
              PinInputField,
         
     | 
| 
      
 15 
     | 
    
         
            +
              HStack,
         
     | 
| 
      
 16 
     | 
    
         
            +
              PinInput,
         
     | 
| 
      
 17 
     | 
    
         
            +
              UsePinInputProps,
         
     | 
| 
      
 18 
     | 
    
         
            +
              SystemProps,
         
     | 
| 
      
 19 
     | 
    
         
            +
            } from '@chakra-ui/react'
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            import { NumberInput, NumberInputProps } from './number-input'
         
     | 
| 
      
 22 
     | 
    
         
            +
            import { PasswordInput, PasswordInputProps } from './password-input'
         
     | 
| 
      
 23 
     | 
    
         
            +
            import { RadioInput, RadioInputProps } from './radio'
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            import { Select, SelectProps, NativeSelect, NativeSelectProps } from './select'
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            import { createField } from './create-field'
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            export interface InputFieldProps extends InputProps {
         
     | 
| 
      
 30 
     | 
    
         
            +
              type?: string
         
     | 
| 
      
 31 
     | 
    
         
            +
              leftAddon?: React.ReactNode
         
     | 
| 
      
 32 
     | 
    
         
            +
              rightAddon?: React.ReactNode
         
     | 
| 
      
 33 
     | 
    
         
            +
            }
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            export const InputField = createField<InputFieldProps>(
         
     | 
| 
      
 36 
     | 
    
         
            +
              forwardRef(({ type = 'text', leftAddon, rightAddon, size, ...rest }, ref) => {
         
     | 
| 
      
 37 
     | 
    
         
            +
                const input = <Input type={type} size={size} {...rest} ref={ref} />
         
     | 
| 
      
 38 
     | 
    
         
            +
                if (leftAddon || rightAddon) {
         
     | 
| 
      
 39 
     | 
    
         
            +
                  return (
         
     | 
| 
      
 40 
     | 
    
         
            +
                    <InputGroup size={size}>
         
     | 
| 
      
 41 
     | 
    
         
            +
                      {leftAddon}
         
     | 
| 
      
 42 
     | 
    
         
            +
                      {input}
         
     | 
| 
      
 43 
     | 
    
         
            +
                      {rightAddon}
         
     | 
| 
      
 44 
     | 
    
         
            +
                    </InputGroup>
         
     | 
| 
      
 45 
     | 
    
         
            +
                  )
         
     | 
| 
      
 46 
     | 
    
         
            +
                }
         
     | 
| 
      
 47 
     | 
    
         
            +
                return input
         
     | 
| 
      
 48 
     | 
    
         
            +
              })
         
     | 
| 
      
 49 
     | 
    
         
            +
            )
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            export interface NumberInputFieldProps extends NumberInputProps {
         
     | 
| 
      
 52 
     | 
    
         
            +
              type: 'number'
         
     | 
| 
      
 53 
     | 
    
         
            +
            }
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            export const NumberInputField = createField<NumberInputFieldProps>(
         
     | 
| 
      
 56 
     | 
    
         
            +
              NumberInput,
         
     | 
| 
      
 57 
     | 
    
         
            +
              {
         
     | 
| 
      
 58 
     | 
    
         
            +
                isControlled: true,
         
     | 
| 
      
 59 
     | 
    
         
            +
              }
         
     | 
| 
      
 60 
     | 
    
         
            +
            )
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
            export const PasswordInputField = createField<PasswordInputProps>(
         
     | 
| 
      
 63 
     | 
    
         
            +
              forwardRef((props, ref) => <PasswordInput ref={ref} {...props} />)
         
     | 
| 
      
 64 
     | 
    
         
            +
            )
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            export const TextareaField = createField<TextareaProps>(Textarea)
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            export const SwitchField = createField<SwitchProps>(
         
     | 
| 
      
 69 
     | 
    
         
            +
              forwardRef(({ type, value, ...rest }, ref) => {
         
     | 
| 
      
 70 
     | 
    
         
            +
                return <Switch isChecked={!!value} {...rest} ref={ref} />
         
     | 
| 
      
 71 
     | 
    
         
            +
              }),
         
     | 
| 
      
 72 
     | 
    
         
            +
              {
         
     | 
| 
      
 73 
     | 
    
         
            +
                isControlled: true,
         
     | 
| 
      
 74 
     | 
    
         
            +
              }
         
     | 
| 
      
 75 
     | 
    
         
            +
            )
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
            export const SelectField = createField<SelectProps>(Select, {
         
     | 
| 
      
 78 
     | 
    
         
            +
              isControlled: true,
         
     | 
| 
      
 79 
     | 
    
         
            +
            })
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
            export const CheckboxField = createField<CheckboxProps>(
         
     | 
| 
      
 82 
     | 
    
         
            +
              forwardRef(({ label, type, ...props }, ref) => {
         
     | 
| 
      
 83 
     | 
    
         
            +
                return (
         
     | 
| 
      
 84 
     | 
    
         
            +
                  <Checkbox ref={ref} {...props}>
         
     | 
| 
      
 85 
     | 
    
         
            +
                    {label}
         
     | 
| 
      
 86 
     | 
    
         
            +
                  </Checkbox>
         
     | 
| 
      
 87 
     | 
    
         
            +
                )
         
     | 
| 
      
 88 
     | 
    
         
            +
              }),
         
     | 
| 
      
 89 
     | 
    
         
            +
              {
         
     | 
| 
      
 90 
     | 
    
         
            +
                hideLabel: true,
         
     | 
| 
      
 91 
     | 
    
         
            +
              }
         
     | 
| 
      
 92 
     | 
    
         
            +
            )
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            export const RadioField = createField<RadioInputProps>(RadioInput, {
         
     | 
| 
      
 95 
     | 
    
         
            +
              isControlled: true,
         
     | 
| 
      
 96 
     | 
    
         
            +
            })
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
            export const NativeSelectField = createField<NativeSelectProps>(NativeSelect, {
         
     | 
| 
      
 99 
     | 
    
         
            +
              isControlled: true,
         
     | 
| 
      
 100 
     | 
    
         
            +
            })
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
            export interface PinFieldProps extends Omit<UsePinInputProps, 'type'> {
         
     | 
| 
      
 103 
     | 
    
         
            +
              pinLength?: number
         
     | 
| 
      
 104 
     | 
    
         
            +
              pinType?: 'alphanumeric' | 'number'
         
     | 
| 
      
 105 
     | 
    
         
            +
              spacing?: SystemProps['margin']
         
     | 
| 
      
 106 
     | 
    
         
            +
            }
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
            export const PinField = createField<PinFieldProps>(
         
     | 
| 
      
 109 
     | 
    
         
            +
              forwardRef((props, ref) => {
         
     | 
| 
      
 110 
     | 
    
         
            +
                const { pinLength = 4, pinType, spacing, ...inputProps } = props
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                const inputs: React.ReactNode[] = []
         
     | 
| 
      
 113 
     | 
    
         
            +
                for (let i = 0; i < pinLength; i++) {
         
     | 
| 
      
 114 
     | 
    
         
            +
                  inputs.push(<PinInputField key={i} ref={ref} />)
         
     | 
| 
      
 115 
     | 
    
         
            +
                }
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                return (
         
     | 
| 
      
 118 
     | 
    
         
            +
                  <HStack spacing={spacing}>
         
     | 
| 
      
 119 
     | 
    
         
            +
                    <PinInput {...inputProps} type={pinType}>
         
     | 
| 
      
 120 
     | 
    
         
            +
                      {inputs}
         
     | 
| 
      
 121 
     | 
    
         
            +
                    </PinInput>
         
     | 
| 
      
 122 
     | 
    
         
            +
                  </HStack>
         
     | 
| 
      
 123 
     | 
    
         
            +
                )
         
     | 
| 
      
 124 
     | 
    
         
            +
              }),
         
     | 
| 
      
 125 
     | 
    
         
            +
              {
         
     | 
| 
      
 126 
     | 
    
         
            +
                isControlled: true,
         
     | 
| 
      
 127 
     | 
    
         
            +
              }
         
     | 
| 
      
 128 
     | 
    
         
            +
            )
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
            export const defaultFieldTypes = {
         
     | 
| 
      
 131 
     | 
    
         
            +
              text: InputField,
         
     | 
| 
      
 132 
     | 
    
         
            +
              email: InputField,
         
     | 
| 
      
 133 
     | 
    
         
            +
              url: InputField,
         
     | 
| 
      
 134 
     | 
    
         
            +
              phone: InputField,
         
     | 
| 
      
 135 
     | 
    
         
            +
              number: NumberInputField,
         
     | 
| 
      
 136 
     | 
    
         
            +
              password: PasswordInputField,
         
     | 
| 
      
 137 
     | 
    
         
            +
              textarea: TextareaField,
         
     | 
| 
      
 138 
     | 
    
         
            +
              switch: SwitchField,
         
     | 
| 
      
 139 
     | 
    
         
            +
              select: SelectField,
         
     | 
| 
      
 140 
     | 
    
         
            +
              checkbox: CheckboxField,
         
     | 
| 
      
 141 
     | 
    
         
            +
              radio: RadioField,
         
     | 
| 
      
 142 
     | 
    
         
            +
              pin: PinField,
         
     | 
| 
      
 143 
     | 
    
         
            +
              'native-select': NativeSelectField,
         
     | 
| 
      
 144 
     | 
    
         
            +
            }
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
            export type DefaultFields = typeof defaultFieldTypes
         
     | 
    
        package/src/display-field.tsx
    CHANGED
    
    | 
         @@ -1,5 +1,4 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            import * as React from 'react'
         
     | 
| 
       2 
     | 
    
         
            -
            import { __DEV__ } from '@chakra-ui/utils'
         
     | 
| 
       3 
2 
     | 
    
         
             
            import { useFormContext } from 'react-hook-form'
         
     | 
| 
       4 
3 
     | 
    
         | 
| 
       5 
4 
     | 
    
         
             
            import {
         
     | 
| 
         @@ -9,12 +8,16 @@ import { 
     | 
|
| 
       9 
8 
     | 
    
         
             
              FormLabel,
         
     | 
| 
       10 
9 
     | 
    
         
             
            } from '@chakra-ui/react'
         
     | 
| 
       11 
10 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
            import { FieldProps } from './ 
     | 
| 
      
 11 
     | 
    
         
            +
            import { FieldProps } from './types'
         
     | 
| 
       13 
12 
     | 
    
         | 
| 
       14 
13 
     | 
    
         
             
            export interface DisplayFieldProps
         
     | 
| 
       15 
14 
     | 
    
         
             
              extends FormControlProps,
         
     | 
| 
       16 
15 
     | 
    
         
             
                Omit<FieldProps, 'type' | 'label'> {}
         
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
      
 16 
     | 
    
         
            +
            /**
         
     | 
| 
      
 17 
     | 
    
         
            +
             *
         
     | 
| 
      
 18 
     | 
    
         
            +
             *
         
     | 
| 
      
 19 
     | 
    
         
            +
             * @see Docs https://saas-ui.dev/
         
     | 
| 
      
 20 
     | 
    
         
            +
             */
         
     | 
| 
       18 
21 
     | 
    
         
             
            export const DisplayField: React.FC<DisplayFieldProps> = ({
         
     | 
| 
       19 
22 
     | 
    
         
             
              name,
         
     | 
| 
       20 
23 
     | 
    
         
             
              label,
         
     | 
| 
         @@ -31,15 +34,11 @@ export const DisplayField: React.FC<DisplayFieldProps> = ({ 
     | 
|
| 
       31 
34 
     | 
    
         
             
              )
         
     | 
| 
       32 
35 
     | 
    
         
             
            }
         
     | 
| 
       33 
36 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
              DisplayField.displayName = 'DisplayField'
         
     | 
| 
       36 
     | 
    
         
            -
            }
         
     | 
| 
      
 37 
     | 
    
         
            +
            DisplayField.displayName = 'DisplayField'
         
     | 
| 
       37 
38 
     | 
    
         | 
| 
       38 
39 
     | 
    
         
             
            export const FormValue: React.FC<{ name: string }> = ({ name }) => {
         
     | 
| 
       39 
40 
     | 
    
         
             
              const { getValues } = useFormContext()
         
     | 
| 
       40 
41 
     | 
    
         
             
              return getValues(name) || null
         
     | 
| 
       41 
42 
     | 
    
         
             
            }
         
     | 
| 
       42 
43 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
              FormValue.displayName = 'FormValue'
         
     | 
| 
       45 
     | 
    
         
            -
            }
         
     | 
| 
      
 44 
     | 
    
         
            +
            FormValue.displayName = 'FormValue'
         
     | 
    
        package/src/display-if.tsx
    CHANGED
    
    | 
         @@ -1,5 +1,4 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            import * as React from 'react'
         
     | 
| 
       2 
     | 
    
         
            -
            import { __DEV__ } from '@chakra-ui/utils'
         
     | 
| 
       3 
2 
     | 
    
         
             
            import {
         
     | 
| 
       4 
3 
     | 
    
         
             
              useFormContext,
         
     | 
| 
       5 
4 
     | 
    
         
             
              useWatch,
         
     | 
| 
         @@ -17,7 +16,11 @@ export interface DisplayIfProps< 
     | 
|
| 
       17 
16 
     | 
    
         
             
              isExact?: boolean
         
     | 
| 
       18 
17 
     | 
    
         
             
              condition?: (value: unknown, context: UseFormReturn<TFieldValues>) => boolean
         
     | 
| 
       19 
18 
     | 
    
         
             
            }
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
      
 19 
     | 
    
         
            +
            /**
         
     | 
| 
      
 20 
     | 
    
         
            +
             * Conditionally render parts of a form.
         
     | 
| 
      
 21 
     | 
    
         
            +
             *
         
     | 
| 
      
 22 
     | 
    
         
            +
             * @see Docs https://saas-ui.dev/docs/components/forms/form
         
     | 
| 
      
 23 
     | 
    
         
            +
             */
         
     | 
| 
       21 
24 
     | 
    
         
             
            export const DisplayIf = <TFieldValues extends FieldValues = FieldValues>({
         
     | 
| 
       22 
25 
     | 
    
         
             
              children,
         
     | 
| 
       23 
26 
     | 
    
         
             
              name,
         
     | 
| 
         @@ -36,6 +39,4 @@ export const DisplayIf = <TFieldValues extends FieldValues = FieldValues>({ 
     | 
|
| 
       36 
39 
     | 
    
         
             
              return condition(value, context) ? children : null
         
     | 
| 
       37 
40 
     | 
    
         
             
            }
         
     | 
| 
       38 
41 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
              DisplayIf.displayName = 'DisplayIf'
         
     | 
| 
       41 
     | 
    
         
            -
            }
         
     | 
| 
      
 42 
     | 
    
         
            +
            DisplayIf.displayName = 'DisplayIf'
         
     | 
    
        package/src/field-resolver.ts
    CHANGED