uniforms icon indicating copy to clipboard operation
uniforms copied to clipboard

AutoField.componentDetectorContext is bypassed if schema specify a component

Open macrozone opened this issue 3 years ago • 4 comments

in ReactPage a lot of users asked for having conditional fields in the schema, so by default we support an additional prop showIf that can be used in the schema to control whether a field should be shown based on other props. The implementation was fairly easy:

import React from 'react';
import { AutoField } from 'uniforms-material';

const AutofieldContextProvider: React.FC = ({ children }) => (
  <AutoField.componentDetectorContext.Provider
    value={(props, uniforms) => {
      const show = props.showIf?.(uniforms.model) ?? true;
      return show
        ? AutoField.defaultComponentDetector(props, uniforms)
        : () => null;
    }}
  >
    {children}
  </AutoField.componentDetectorContext.Provider>
);

export default AutofieldContextProvider;

unfortunalty a user noticed that this does not work when you specify a custom component in the schema using uniforms.component prop.

the provider above is never called for these fields.

I think it makes sense at first glance that any custom detector is bypassed when a component is specified, but still, it removes a lot of flexibility like the case above. Since autoField gets removed (https://github.com/vazco/uniforms/issues/980), I actually ran out of ideas how to implement the showIf usecase properly.

the problematic code line is this: https://github.com/vazco/uniforms/blob/master/packages/uniforms/src/createAutoField.tsx#L35

it would probably better if the componentDetector is responsible of handling the case where component is defined on the field

macrozone avatar May 16 '22 19:05 macrozone

changing that is probably a breaking change, maybe there is a way to opt-in that the componentDetector is always called? Some flag?

macrozone avatar May 16 '22 19:05 macrozone

maybe that could be a property of the bridge?

componentDetectorMode: "ifNotSet" | "always"

ifNotSet: calls the dector only if field does not specify component (default behavior like now) always: always calls the detector, detector has to include handling of specifying a component

macrozone avatar May 16 '22 19:05 macrozone

Hey @macrozone. Indeed, making AutoField always call the componentDetector sounds like a good idea. However, it is a breaking change, so we'll probably have to postpone it to v4. It's easily solvable and it won't break anything, so maybe... I have to think about it.

radekmie avatar May 20 '22 11:05 radekmie

A summary from the v4 planning session for this ticket is we will move the props.component to the defaultComponentDetector.

Monteth avatar Sep 02 '22 12:09 Monteth