mirror of
https://github.com/vale981/Vulcan
synced 2025-03-06 01:51:40 -05:00
Cleaning up FormComponent props
This commit is contained in:
parent
9d5963da12
commit
5675b50fb5
18 changed files with 119 additions and 137 deletions
|
@ -110,7 +110,7 @@ class Upload extends PureComponent {
|
|||
|
||||
*/
|
||||
enableMultiple() {
|
||||
return this.props.datatype.definitions[0].type === Array;
|
||||
return this.props.datatype && this.props.datatype[0].type === Array;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Alert from 'react-bootstrap/lib/Alert'
|
||||
import { registerComponent } from 'meteor/vulcan:core';
|
||||
// import React from 'react';
|
||||
// import PropTypes from 'prop-types';
|
||||
// import Alert from 'react-bootstrap/lib/Alert'
|
||||
// import { registerComponent } from 'meteor/vulcan:core';
|
||||
|
||||
const Flash = ({message, type}) => {
|
||||
// const Flash = ({message, type}) => {
|
||||
|
||||
type = type === "error" ? "danger" : type; // if type is "error", use "danger" instead
|
||||
// type = type === "error" ? "danger" : type; // if type is "error", use "danger" instead
|
||||
|
||||
return (
|
||||
<Alert className="flash-message" bsStyle={type}>
|
||||
{Array.isArray(message) ?
|
||||
<ul>
|
||||
{message.map((message, index) =>
|
||||
<li key={index}>{message.content}</li>
|
||||
)}
|
||||
</ul>
|
||||
: <span>{message.content}</span>
|
||||
}
|
||||
</Alert>
|
||||
)
|
||||
}
|
||||
// return (
|
||||
// <Alert className="flash-message" bsStyle={type}>
|
||||
// {Array.isArray(message) ?
|
||||
// <ul>
|
||||
// {message.map((message, index) =>
|
||||
// <li key={index}>{message.content}</li>
|
||||
// )}
|
||||
// </ul>
|
||||
// : <span>{message.content}</span>
|
||||
// }
|
||||
// </Alert>
|
||||
// )
|
||||
// }
|
||||
|
||||
Flash.propTypes = {
|
||||
message: PropTypes.oneOfType([PropTypes.object.isRequired, PropTypes.array.isRequired])
|
||||
}
|
||||
// Flash.propTypes = {
|
||||
// message: PropTypes.oneOfType([PropTypes.object.isRequired, PropTypes.array.isRequired])
|
||||
// }
|
||||
|
||||
registerComponent('FormFlash', Flash);
|
||||
// registerComponent('FormFlash', Flash);
|
|
@ -22,7 +22,7 @@ This component expects:
|
|||
|
||||
*/
|
||||
|
||||
import { Components, runCallbacks, getCollection } from 'meteor/vulcan:core';
|
||||
import { registerComponent, Components, runCallbacks, getCollection } from 'meteor/vulcan:core';
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { intlShape } from 'meteor/vulcan:i18n';
|
||||
|
@ -73,14 +73,12 @@ class Form extends Component {
|
|||
|
||||
// the initial document passed as props
|
||||
this.initialDocument = merge({}, this.props.prefilledProps, this.props.document);
|
||||
|
||||
}
|
||||
|
||||
submitFormCallbacks = [];
|
||||
successFormCallbacks = [];
|
||||
failureFormCallbacks = [];
|
||||
|
||||
|
||||
// --------------------------------------------------------------------- //
|
||||
// ------------------------------- Helpers ----------------------------- //
|
||||
// --------------------------------------------------------------------- //
|
||||
|
@ -109,7 +107,6 @@ class Form extends Component {
|
|||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Get the current document (for edit forms)
|
||||
|
@ -122,13 +119,8 @@ class Form extends Component {
|
|||
|
||||
*/
|
||||
getDocument = () => {
|
||||
const document = merge(
|
||||
{},
|
||||
this.initialDocument,
|
||||
this.state.autofilledValues,
|
||||
this.state.currentValues,
|
||||
);
|
||||
|
||||
const document = merge({}, this.initialDocument, this.state.autofilledValues, this.state.currentValues);
|
||||
|
||||
return document;
|
||||
};
|
||||
|
||||
|
@ -240,7 +232,6 @@ class Form extends Component {
|
|||
return relevantFields;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Given a field's name, the containing schema, and parent, create the
|
||||
|
@ -248,7 +239,6 @@ class Form extends Component {
|
|||
|
||||
*/
|
||||
createField = (fieldName, schema, parentFieldName, parentPath) => {
|
||||
|
||||
const fieldPath = parentPath ? `${parentPath}.${fieldName}` : fieldName;
|
||||
const fieldSchema = schema[fieldName];
|
||||
|
||||
|
@ -284,17 +274,14 @@ class Form extends Component {
|
|||
field.options = field.options.call(fieldSchema, this.props);
|
||||
}
|
||||
|
||||
// add any properties specified in fieldProperties or form as extra props passed on
|
||||
// to the form component
|
||||
const fieldProperties = fieldSchema.fieldProperties || fieldSchema.form;
|
||||
if (fieldProperties) {
|
||||
for (const prop in fieldProperties) {
|
||||
if (prop !== 'prefill' && prop !== 'options' && fieldProperties.hasOwnProperty(prop)) {
|
||||
field[prop] =
|
||||
typeof fieldProperties[prop] === 'function'
|
||||
? fieldProperties[prop].call(fieldSchema)
|
||||
: fieldProperties[prop];
|
||||
}
|
||||
// add any properties specified in fieldSchema.form as extra props passed on
|
||||
// to the form component, calling them if they are functions
|
||||
if (fieldSchema.form) {
|
||||
for (const prop in fieldSchema.form) {
|
||||
field[prop] =
|
||||
typeof fieldSchema.form[prop] === 'function'
|
||||
? fieldSchema.form[prop].call(fieldSchema, this.props)
|
||||
: fieldSchema.form[prop];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -661,7 +648,12 @@ class Form extends Component {
|
|||
<Components.FormErrors errors={this.state.errors} />
|
||||
|
||||
{fieldGroups.map(group => (
|
||||
<Components.FormGroup key={group.name} {...group} updateCurrentValues={this.updateCurrentValues} formType={this.getFormType()}/>
|
||||
<Components.FormGroup
|
||||
key={group.name}
|
||||
{...group}
|
||||
updateCurrentValues={this.updateCurrentValues}
|
||||
formType={this.getFormType()}
|
||||
/>
|
||||
))}
|
||||
|
||||
{this.props.repeatErrors && this.renderErrors()}
|
||||
|
@ -752,3 +744,5 @@ Form.childContextTypes = {
|
|||
};
|
||||
|
||||
module.exports = Form;
|
||||
|
||||
registerComponent('Form', Form);
|
|
@ -7,7 +7,6 @@ import { registerComponent } from 'meteor/vulcan:core';
|
|||
import debounce from 'lodash.debounce';
|
||||
import get from 'lodash/get';
|
||||
import { isEmptyValue } from '../modules/utils.js';
|
||||
import { formProperties } from '../modules/schema_utils';
|
||||
|
||||
class FormComponent extends PureComponent {
|
||||
constructor(props, context) {
|
||||
|
@ -15,15 +14,15 @@ class FormComponent extends PureComponent {
|
|||
|
||||
const value = this.getValue(props, context);
|
||||
|
||||
if (props.limit) {
|
||||
if (this.showCharsRemaining(props)) {
|
||||
const characterCount = value ? value.length : 0;
|
||||
this.state = {
|
||||
limit: value ? props.limit - value.length : props.limit,
|
||||
charsRemaining: props.max - characterCount,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
handleChange = (name, value) => {
|
||||
|
||||
if (!!value) {
|
||||
// if this is a number field, convert value before sending it up to Form
|
||||
if (this.getType() === 'number') {
|
||||
|
@ -35,7 +34,7 @@ class FormComponent extends PureComponent {
|
|||
}
|
||||
|
||||
// for text fields, update character count on change
|
||||
if (['number', 'url', 'email', 'textarea', 'text'].includes(this.getType())) {
|
||||
if (this.showCharsRemaining()) {
|
||||
this.updateCharacterCount(value);
|
||||
}
|
||||
};
|
||||
|
@ -49,12 +48,10 @@ class FormComponent extends PureComponent {
|
|||
handleChangeDebounced = debounce(this.handleChange, 500, { leading: true });
|
||||
|
||||
updateCharacterCount = (value) => {
|
||||
if (this.props.limit) {
|
||||
const characterCount = value ? value.length : 0;
|
||||
this.setState({
|
||||
limit: this.props.limit - characterCount,
|
||||
});
|
||||
}
|
||||
const characterCount = value ? value.length : 0;
|
||||
this.setState({
|
||||
charsRemaining: this.props.max - characterCount,
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -72,14 +69,24 @@ class FormComponent extends PureComponent {
|
|||
// replace empty value, which has not been prefilled, by the default value from the schema
|
||||
// keep defaultValue for backwards compatibility even though it doesn't actually work
|
||||
if (isEmptyValue(value)) {
|
||||
if (this.props.defaultValue) value = this.props.defaultValue;
|
||||
if (this.props.default) value = this.props.default;
|
||||
if (p.defaultValue) value = p.defaultValue;
|
||||
if (p.default) value = p.default;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
Whether to keep track of and show remaining chars
|
||||
|
||||
*/
|
||||
showCharsRemaining = (props) => {
|
||||
const p = props || this.props;
|
||||
return p.max && ['url', 'email', 'textarea', 'text'].includes(this.getType(p));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Get errors from Form state through context
|
||||
|
||||
*/
|
||||
|
@ -94,43 +101,48 @@ class FormComponent extends PureComponent {
|
|||
based on form field type
|
||||
|
||||
*/
|
||||
getType = () => {
|
||||
return this.props.control || 'text';
|
||||
getType = (props) => {
|
||||
const p = props || this.props;
|
||||
const fieldType = p.datatype && p.datatype[0].type;
|
||||
const autoType =
|
||||
fieldType === Number ? 'number' : fieldType === Boolean ? 'checkbox' : fieldType === Date ? 'date' : 'text';
|
||||
return p.control || autoType;
|
||||
};
|
||||
|
||||
renderComponent() {
|
||||
// see https://facebook.github.io/react/warnings/unknown-prop.html
|
||||
const {
|
||||
control,
|
||||
group,
|
||||
updateCurrentValues,
|
||||
document,
|
||||
beforeComponent,
|
||||
afterComponent,
|
||||
limit,
|
||||
errors,
|
||||
nestedSchema,
|
||||
nestedFields,
|
||||
datatype,
|
||||
parentFieldName,
|
||||
itemIndex,
|
||||
options,
|
||||
path,
|
||||
name,
|
||||
label,
|
||||
form,
|
||||
formType,
|
||||
optional,
|
||||
...rest
|
||||
} = this.props; // eslint-disable-line
|
||||
} = this.props;
|
||||
|
||||
const properties = {
|
||||
...rest,
|
||||
// onBlur: this.handleChange,
|
||||
// these properties are whitelisted so that they can be safely passed to the actual form input
|
||||
// and avoid https://facebook.github.io/react/warnings/unknown-prop.html warnings
|
||||
const inputProperties = {
|
||||
name,
|
||||
options,
|
||||
label,
|
||||
onChange: this.handleChange,
|
||||
document,
|
||||
value: this.getValue(),
|
||||
...form,
|
||||
};
|
||||
|
||||
const properties = { ...this.props, inputProperties };
|
||||
|
||||
// if control is a React component, use it
|
||||
if (typeof this.props.control === 'function') {
|
||||
return <this.props.control {...properties} />;
|
||||
if (typeof control === 'function') {
|
||||
const ControlComponent = control;
|
||||
return <ControlComponent {...properties} />;
|
||||
} else {
|
||||
// else pick a predefined component
|
||||
|
||||
|
@ -174,7 +186,7 @@ class FormComponent extends PureComponent {
|
|||
|
||||
// in case of checkbox groups, check "checked" option to populate value if this is a "new document" form
|
||||
const checkedValues = _.where(properties.options, { checked: true }).map(option => option.value);
|
||||
if (checkedValues.length && !properties.value && this.props.formType === 'new') {
|
||||
if (checkedValues.length && !properties.value && formType === 'new') {
|
||||
properties.value = checkedValues;
|
||||
}
|
||||
return <Components.FormComponentCheckboxGroup {...properties} />;
|
||||
|
@ -215,7 +227,7 @@ class FormComponent extends PureComponent {
|
|||
return <Components.FormComponentDefault {...properties} />;
|
||||
|
||||
default:
|
||||
const CustomComponent = Components[this.props.control];
|
||||
const CustomComponent = Components[control];
|
||||
return CustomComponent ? (
|
||||
<CustomComponent {...properties} />
|
||||
) : (
|
||||
|
@ -253,24 +265,24 @@ class FormComponent extends PureComponent {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { beforeComponent, afterComponent, max, name, control } = this.props;
|
||||
|
||||
const hasErrors = this.getErrors() && this.getErrors().length;
|
||||
const inputClass = classNames(
|
||||
'form-input',
|
||||
`input-${this.props.name}`,
|
||||
`form-component-${this.props.control || 'default'}`,
|
||||
`input-${name}`,
|
||||
`form-component-${control || 'default'}`,
|
||||
{ 'input-error': hasErrors }
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={inputClass}>
|
||||
{this.props.beforeComponent ? this.props.beforeComponent : null}
|
||||
{beforeComponent ? beforeComponent : null}
|
||||
{this.renderComponent()}
|
||||
{hasErrors ? <Components.FieldErrors errors={this.getErrors()} /> : null}
|
||||
{this.showClear() ? this.renderClear() : null}
|
||||
{this.props.limit ? (
|
||||
<div className={classNames('form-control-limit', { danger: this.state.limit < 10 })}>{this.state.limit}</div>
|
||||
) : null}
|
||||
{this.props.afterComponent ? this.props.afterComponent : null}
|
||||
{this.showCharsRemaining() && <div className={classNames('form-control-limit', { danger: this.state.charsRemaining < 10 })}>{this.state.charsRemaining}</div>}
|
||||
{afterComponent ? afterComponent : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ import {
|
|||
getFragment,
|
||||
getCollection,
|
||||
} from 'meteor/vulcan:core';
|
||||
import Form from './Form.jsx';
|
||||
import gql from 'graphql-tag';
|
||||
import { withDocument } from 'meteor/vulcan:core';
|
||||
import { graphql } from 'react-apollo';
|
||||
|
@ -177,7 +176,7 @@ class FormWrapper extends PureComponent {
|
|||
const { document, loading } = props;
|
||||
return loading ?
|
||||
<Components.Loading /> :
|
||||
<Form
|
||||
<Components.Form
|
||||
document={document}
|
||||
loading={loading}
|
||||
{...childProps}
|
||||
|
@ -224,7 +223,7 @@ class FormWrapper extends PureComponent {
|
|||
} else {
|
||||
WrappedComponent = compose(
|
||||
withNew(mutationOptions)
|
||||
)(Form);
|
||||
)(Components.Form);
|
||||
}
|
||||
|
||||
return <WrappedComponent {...childProps} />;
|
||||
|
|
|
@ -2,6 +2,6 @@ import React from 'react';
|
|||
import { Checkbox } from 'formsy-react-components';
|
||||
import { registerComponent } from 'meteor/vulcan:core';
|
||||
|
||||
const CheckboxComponent = ({refFunction, ...properties}) => <Checkbox {...properties} ref={refFunction} />
|
||||
const CheckboxComponent = ({refFunction, inputProperties, ...properties}) => <Checkbox {...inputProperties} ref={refFunction} />
|
||||
|
||||
registerComponent('FormComponentCheckbox', CheckboxComponent);
|
|
@ -2,6 +2,6 @@ import React from 'react';
|
|||
import { CheckboxGroup } from 'formsy-react-components';
|
||||
import { registerComponent } from 'meteor/vulcan:core';
|
||||
|
||||
const CheckboxGroupComponent = ({refFunction, ...properties}) => <CheckboxGroup {...properties} ref={refFunction} />
|
||||
const CheckboxGroupComponent = ({refFunction, inputProperties, ...properties}) => <CheckboxGroup {...inputProperties} ref={refFunction} />
|
||||
|
||||
registerComponent('FormComponentCheckboxGroup', CheckboxGroupComponent);
|
|
@ -2,6 +2,6 @@ import React from 'react';
|
|||
import { Input } from 'formsy-react-components';
|
||||
import { registerComponent } from 'meteor/vulcan:core';
|
||||
|
||||
const Default = ({refFunction, ...properties}) => <Input {...properties} ref={refFunction} type="text" />
|
||||
const Default = ({refFunction, inputProperties, ...properties}) => <Input {...inputProperties} ref={refFunction} type="text" />
|
||||
|
||||
registerComponent('FormComponentDefault', Default);
|
|
@ -2,6 +2,6 @@ import React from 'react';
|
|||
import { Input } from 'formsy-react-components';
|
||||
import { registerComponent } from 'meteor/vulcan:core';
|
||||
|
||||
const EmailComponent = ({refFunction, ...properties}) => <Input {...properties} ref={refFunction} type="email" />
|
||||
const EmailComponent = ({refFunction, inputProperties, ...properties}) => <Input {...inputProperties} ref={refFunction} type="email" />
|
||||
|
||||
registerComponent('FormComponentEmail', EmailComponent);
|
|
@ -2,6 +2,6 @@ import React from 'react';
|
|||
import { Input } from 'formsy-react-components';
|
||||
import { registerComponent } from 'meteor/vulcan:core';
|
||||
|
||||
const NumberComponent = ({refFunction, ...properties}) => <Input {...properties} ref={refFunction} type="number" />
|
||||
const NumberComponent = ({refFunction, inputProperties, ...properties}) => <Input {...inputProperties} ref={refFunction} type="number" />
|
||||
|
||||
registerComponent('FormComponentNumber', NumberComponent);
|
|
@ -2,6 +2,6 @@ import React from 'react';
|
|||
import { RadioGroup } from 'formsy-react-components';
|
||||
import { registerComponent } from 'meteor/vulcan:core';
|
||||
|
||||
const RadioGroupComponent = ({refFunction, ...properties}) => <RadioGroup {...properties} ref={refFunction}/>
|
||||
const RadioGroupComponent = ({refFunction, inputProperties, ...properties}) => <RadioGroup {...inputProperties} ref={refFunction}/>
|
||||
|
||||
registerComponent('FormComponentRadioGroup', RadioGroupComponent);
|
|
@ -2,6 +2,6 @@ import React from 'react';
|
|||
import { Select } from 'formsy-react-components';
|
||||
import { registerComponent } from 'meteor/vulcan:core';
|
||||
|
||||
const SelectComponent = ({refFunction, ...properties}) => <Select {...properties} ref={refFunction}/>
|
||||
const SelectComponent = ({refFunction, inputProperties, ...properties}) => <Select {...inputProperties} ref={refFunction}/>
|
||||
|
||||
registerComponent('FormComponentSelect', SelectComponent);
|
|
@ -2,6 +2,6 @@ import React from 'react';
|
|||
import { Textarea } from 'formsy-react-components';
|
||||
import { registerComponent } from 'meteor/vulcan:core';
|
||||
|
||||
const TextareaComponent = ({refFunction, ...properties}) => <Textarea ref={refFunction} {...properties}/>
|
||||
const TextareaComponent = ({refFunction, inputProperties, ...properties}) => <Textarea ref={refFunction} {...inputProperties}/>
|
||||
|
||||
registerComponent('FormComponentTextarea', TextareaComponent);
|
|
@ -2,6 +2,6 @@ import React from 'react';
|
|||
import { Input } from 'formsy-react-components';
|
||||
import { registerComponent } from 'meteor/vulcan:core';
|
||||
|
||||
const UrlComponent = ({refFunction, ...properties}) => <Input ref={refFunction} {...properties} type="url" />
|
||||
const UrlComponent = ({refFunction, inputProperties, ...properties}) => <Input ref={refFunction} {...inputProperties} type="url" />
|
||||
|
||||
registerComponent('FormComponentUrl', UrlComponent);
|
|
@ -19,3 +19,4 @@ import '../components/FormNested.jsx';
|
|||
import '../components/FormGroup.jsx';
|
||||
import '../components/FormSubmit.jsx';
|
||||
import '../components/FormWrapper.jsx';
|
||||
import '../components/Form.jsx';
|
||||
|
|
|
@ -1,21 +1,5 @@
|
|||
import SimpleSchema from 'simpl-schema';
|
||||
import { registerComponent } from 'meteor/vulcan:core';
|
||||
|
||||
import './components.js';
|
||||
|
||||
if (typeof SimpleSchema !== "undefined") {
|
||||
SimpleSchema.extendOptions([
|
||||
'control', // SmartForm control (String or React component)
|
||||
'order', // order in the form
|
||||
'group', // form fieldset group
|
||||
'hidden',
|
||||
'beforeComponent',
|
||||
'afterComponent',
|
||||
'placeholder',
|
||||
'options',
|
||||
'query',
|
||||
'fieldProperties',
|
||||
]);
|
||||
}
|
||||
|
||||
export {default as FormWrapper} from '../components/FormWrapper.jsx';
|
|
@ -80,8 +80,6 @@ export const schemaProperties = [
|
|||
'custom',
|
||||
'defaultValue',
|
||||
'autoValue',
|
||||
'private',
|
||||
'editable', // editable: true means the field can be edited by the document's owner
|
||||
'hidden', // hidden: true means the field is never shown in a form no matter what
|
||||
'mustComplete', // mustComplete: true means the field is required to have a complete profile
|
||||
'profile', // profile: true means the field is shown on user profiles
|
||||
|
@ -98,9 +96,7 @@ export const schemaProperties = [
|
|||
'insertableBy',
|
||||
'editableBy',
|
||||
'resolveAs',
|
||||
'limit',
|
||||
'searchable',
|
||||
'default',
|
||||
'description',
|
||||
'beforeComponent',
|
||||
'afterComponent',
|
||||
|
@ -131,8 +127,6 @@ export const formProperties = [
|
|||
'control', // SmartForm control (String or React component)
|
||||
'order', // position in the form
|
||||
'group', // form fieldset group
|
||||
'limit',
|
||||
'default',
|
||||
'description',
|
||||
'beforeComponent',
|
||||
'afterComponent',
|
||||
|
|
|
@ -14,28 +14,26 @@ Vulcan.VERSION = '1.8.11';
|
|||
// ------------------------------------- Schemas -------------------------------- //
|
||||
|
||||
SimpleSchema.extendOptions([
|
||||
'private',
|
||||
'editable', // editable: true means the field can be edited by the document's owner
|
||||
'hidden', // hidden: true means the field is never shown in a form no matter what
|
||||
'mustComplete', // mustComplete: true means the field is required to have a complete profile
|
||||
'profile', // profile: true means the field is shown on user profiles
|
||||
'template', // legacy template used to display the field; backward compatibility (not used anymore)
|
||||
'form', // form placeholder
|
||||
'autoform', // legacy form placeholder; backward compatibility (not used anymore)
|
||||
'form', // extra form properties
|
||||
'control', // SmartForm control (String or React component)
|
||||
'order', // position in the form
|
||||
'group', // form fieldset group
|
||||
'onInsert', // field insert callback
|
||||
'onEdit', // field edit callback
|
||||
'onRemove', // field remove callback
|
||||
'viewableBy',
|
||||
'insertableBy',
|
||||
'editableBy',
|
||||
'resolveAs',
|
||||
'limit',
|
||||
'searchable',
|
||||
'default',
|
||||
'description',
|
||||
'viewableBy', // who can view the field
|
||||
'insertableBy', // who can insert the field
|
||||
'editableBy', // who can edit the field
|
||||
'resolveAs', // field-level resolver
|
||||
'searchable', // whether a field is searchable
|
||||
'description', // description/help
|
||||
'beforeComponent', // before form component
|
||||
'afterComponent', // after form component
|
||||
'placeholder', // form field placeholder value
|
||||
'options', // form options
|
||||
'query', // field-specific data loading query
|
||||
]);
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
|
|
Loading…
Add table
Reference in a new issue