Custom Input Types
Input is one of the most important parts of a webpage so it's no suprise that the <Input> component and its close friend <Form> are very commonly used throughout Socialstack projects. Because of how common input is, it's also important that this particular component is very flexible. As a result, Socialstack supports the ability to add custom input types to this Input component such that you get consistent validation, labels, magically submittable values and so on, but with simply a custom value editor.
Examples
To see a working example, type="html" is specified by the tinymce module and its code can be seen here. As of writing this, the second thing the file does is hook itself up as a custom input type.
Make your own
Create your value editor and add it to the inputTypes lookup like so. When type="x" is used, if x is not one of the default options, then it will check for global.inputTypes.ontypex. If that exists, the function will be invoked with the complete set of props from the input field.
var inputTypes = global.inputTypes = global.inputTypes || {};
// type="html"
inputTypes.ontypehtml = function(props, _this){
return <MyEditor
id={props.id || _this.fieldId}
className={props.className || "form-control"}
{...omit(props, ['id', 'className', 'type', 'inline'])}
/>;
};
export default function MyEditor(props) {
return "custom editor here!";
}
props contains everything <Input> is given, which in turn reflects the fields given to a standard <input> field - placeholder, value, defaultValue and so on.
Outputting a value
So far we've seen how to be given a value but not how to output it. Based on how form submit works, you'll need some sort of <input> field which outputs a value whenever a surrounding form is submitted. Often this input field is type="hidden" for custom editors, but can be visible too. By default though html input fields can only have a textual value which can be quite limiting, so you can specify onGetValue to override the outputted value with anything you'd like based on your own internal state:
export default function MyEditor(props) {
var [someObjectState, setSomeObjectState] = React.useState({hello: 'world'});
return <>
<input type='hidden' ref={e => {
if(e){
e.onGetValue = (val, ele)=>{
if(ele == e){
return someObjectState;
}
};
}
}} />
</>;
}
onGetValue can return a promise if you need to do something slow. The form submit process will wait for your promise to return a value. The value can be anything but will typically be required to serialise to JSON as it will almost always be sent to the web API immediately afterwards.