Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Idea: Flexible component mapping #85

Closed
macrozone opened this issue Jul 27, 2016 · 4 comments
Closed

Idea: Flexible component mapping #85

macrozone opened this issue Jul 27, 2016 · 4 comments
Assignees
Labels
Type: Feature New features and feature requests

Comments

@macrozone
Copy link
Contributor

You can currently implement your own AutoField and do whatever you want there, which is nice. You can also define a property universe.component to pass a react-component directly.

However, if you want to share schemas between server and client, you usually put the schemas in a shared location. But importing components there looks like the wrong place (it's also not possible if your componets resides in /client).

One solution is to simply extend the schema in a container, where you add the universe.component-property, but there is a better solution:

Having something like a mapping function, that can be provided to Autoforms or Autofields would be a good solution:

import {connectField, defaultComponentMapping}  from 'uniforms';
import {createElement} from 'react';

const Auto = ({component = null, componentMapping = defaultComponentMapping, ...props}) => {
    if (!component) {
       component = componentMapping(props);
    }
    return createElement(component, props);
};

export default connectField(Auto, {includeInChain: false});

( i sketched the above code here, so it may contain errors)

defaultComponentMapping could be what we currently have in the AutoField (switch on props.fieldType, etc.)

You could then introduce your own properties on the schema, e.g. simply allow component to be a string:

export default new SimpleSchema({
   file: {
      type: String, // will be an url, .e.g from slingshot
      uniforms: {
        component: "SlingshotFileUploadField" // why not allow strings as well and map somewhere else the real component
      }
   }
});

and in your mappingFunction (somewhere in your client where its fine to import Components):

const myMappingFunction = (props) => {
   switch(props.component) {
     case 'TextField': return MyTextField;
     (...)
    case 'SlingshotFileUploadField': return SlingshotFileUploadField
    default: return defaultComponentMapping(props);
  }
}

Thoughts?

@radekmie radekmie added the Type: Feature New features and feature requests label Jul 27, 2016
@radekmie radekmie self-assigned this Jul 27, 2016
@radekmie
Copy link
Contributor

I don't know, if this suits your needs, but there's autoField prop on QuickForm (and so AutoForm) - you can use it like this:

const CustomAuto = props => {
    const Component = myMappingFunction(props) || AutoField;

    return (
        <Component {...props} />
    );
};

const CustomAutoField = connectField(CustomAuto, {includeInChain: false});

// Then...

<AutoForm schema={schema} autoField={CustomAutoField} />

@macrozone
Copy link
Contributor Author

Yes, this also looks good.

Maybe we put that pattern in the readme?

@radekmie
Copy link
Contributor

Yes, README is still under heavy development. I don't have much spare time right now - either create a PR or give me some time.

@radekmie
Copy link
Contributor

Custom AutoField
Would you be my reviewer, @macrozone?

@radekmie radekmie moved this to Closed in Open Source Nov 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Feature New features and feature requests
Projects
Archived in project
Development

No branches or pull requests

2 participants