Skip to content

useFieldProps

Demos

On the consumer side, we can use this custom component like so:

<Form.Handler data={{ sliderValue: 50 }}>
<MySliderComponent
path="/sliderValue"
minimum={50}
maximum={80}
required
info="Info"
/>
</Form.Handler>

Using a Zod schema

It is recommended to use Zod schemas instead of JSON Schemas, as they provide better TypeScript integration.

Info
Code Editor
const MySliderComponent = (props) => {
  const fromInput = React.useCallback(
    (event) => (typeof event === 'number' ? event : event?.value || 0),
    [],
  )
  const errorMessages = React.useMemo(() => {
    return {
      'Field.errorRequired': 'This field is required',
      ...props.errorMessages,
    }
  }, [props.errorMessages])

  // Preferred: Use Zod schemas when possible
  // They work out of the box and provide better TypeScript integration
  const schema =
    props.schema ??
    z
      .number()
      .min(props.minimum || 0)
      .max(props.maximum || 100)
  const preparedProps = {
    fromInput,
    schema,
    ...errorMessages,
    label: 'Label',
    ...props,
  }
  const {
    id,
    label,
    info,
    warning,
    error,
    value,
    width = 'medium',
    minimum = 0,
    maximum = 100,
    step = 1,
    handleChange,
    handleFocus,
    handleBlur,
  } = useFieldProps(preparedProps)
  const steps = {
    minimum,
    maximum,
    step,
  }
  return (
    <FieldBlock
      forId={id}
      label={label}
      info={info}
      warning={warning}
      error={error}
      width={width}
    >
      <Flex.Stack>
        <Field.Number
          id={id}
          value={value}
          showStepControls
          onChange={handleChange}
          onFocus={handleFocus}
          onBlur={handleBlur}
          {...steps}
        />
        <Slider
          value={value}
          onChange={handleChange}
          onDragStart={handleFocus}
          onDragEnd={handleBlur}
          {...steps}
        />
      </Flex.Stack>
    </FieldBlock>
  )
}

// Example with Zod schema (preferred)
// Note: You can pass a Zod schema via props.schema and it will work without AJV
// The component now uses a Zod schema by default: z.number().min(50).max(80)
// Example with Zod schema (preferred)
// Note: You can pass a Zod schema via props.schema and it will work without AJV
// The component now uses a Zod schema by default: z.number().min(50).max(80)
render(
  <Form.Handler
    data={{
      sliderValue: 50,
    }}
  >
    <MySliderComponent
      path="/sliderValue"
      minimum={50}
      maximum={80}
      required
      info="Info"
      // You can override with a custom Zod schema if needed
      // Example: schema={z.number().min(40).max(90).refine(val => val > 60, 'Value must be greater than 60')}
    />
  </Form.Handler>,
)

Using a Ajv schema

Info
Code Editor
const MySliderComponent = (props) => {
  const fromInput = React.useCallback(
    (event) => (typeof event === 'number' ? event : event?.value || 0),
    [],
  )
  const errorMessages = React.useMemo(() => {
    return {
      'Field.errorRequired': 'This field is required',
      ...props.errorMessages,
    }
  }, [props.errorMessages])

  // No schema - uses built-in validation from field props
  const schema = props.schema ?? {
    type: 'number',
    minimum: props.minimum,
    maximum: props.maximum,
  }
  const preparedProps = {
    fromInput,
    schema,
    ...errorMessages,
    label: 'Label',
    ...props,
  }
  const {
    id,
    label,
    info,
    warning,
    error,
    value,
    width = 'medium',
    minimum = 0,
    maximum = 100,
    step = 1,
    handleChange,
    handleFocus,
    handleBlur,
  } = useFieldProps(preparedProps)
  const steps = {
    minimum,
    maximum,
    step,
  }
  return (
    <FieldBlock
      forId={id}
      label={label}
      info={info}
      warning={warning}
      error={error}
      width={width}
    >
      <Flex.Stack>
        <Field.Number
          id={id}
          value={value}
          showStepControls
          onChange={handleChange}
          onFocus={handleFocus}
          onBlur={handleBlur}
          {...steps}
        />
        <Slider
          value={value}
          onChange={handleChange}
          onDragStart={handleFocus}
          onDragEnd={handleBlur}
          {...steps}
        />
      </Flex.Stack>
    </FieldBlock>
  )
}
render(
  <Form.Handler
    data={{
      sliderValue: 50,
    }}
  >
    <MySliderComponent
      path="/sliderValue"
      minimum={50}
      maximum={80}
      required
      info="Info"
    />
  </Form.Handler>,
)