UNPKG

informed

Version:

A lightweight framework and utility for building powerful forms in React applications

263 lines (230 loc) 9.85 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _rollupPluginBabelHelpers = require('../_virtual/_rollupPluginBabelHelpers.js'); var React = require('react'); var utils = require('../utils.js'); var ObjectMap = require('../ObjectMap.js'); var useFormController = require('../hooks/useFormController.js'); var useScope = require('../hooks/useScope.js'); var useConditional = require('../hooks/useConditional.js'); var debug = require('../debug.js'); var FormFields = require('./FormFields.js'); var Relevant = require('./Relevant.js'); var Scope = require('./Scope.js'); var useFieldApi = require('../hooks/useFieldApi.js'); var useUpdateEffect = require('../hooks/useUpdateEffect.js'); var ArrayField = require('./ArrayField.js'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var React__default = /*#__PURE__*/_interopDefaultLegacy(React); var _excluded = ["name", "schema"]; // import { useForceUpdate } from '../hooks/useForceUpdate'; var logger = debug.Debug('informed:FormField' + '\t'); var FormField = function FormField(_ref) { var _fieldMap$componentTy; var name = _ref.name, schema = _ref.schema, rest = _rollupPluginBabelHelpers.objectWithoutProperties(_ref, _excluded); // Get the field map off the forms context var _useFormController = useFormController.useFormController(), fieldMap = _useFormController.fieldMap, getOptions = _useFormController.getOptions, emitter = _useFormController.emitter; // Name might be scoped var fullName = useScope.useScope(name); // Grab the schema var options = getOptions(); // Grap api var fieldApi = useFieldApi.useFieldApi(name); // For conditional props var _useState = React.useState({}), _useState2 = _rollupPluginBabelHelpers.slicedToArray(_useState, 2), condProp = _useState2[0], setCondProp = _useState2[1]; // IF schema was passed its a sub schema and we lookup via name otherwise we look at whole schema var lookupName = schema ? name : fullName; var lookupSchema = schema !== null && schema !== void 0 ? schema : options.schema; // First find property from the schema via the path to that field // Examples // field = "name" ---> properties.name // field = "brother.name" ---> properties.brother.properties.name // field = "brother.siblings[1].friend.name" ---> properties.brother.properties.siblings.items.properties.friend.properties.name var path = utils.getSchemaPathFromJsonPath(lookupName); var property = ObjectMap.ObjectMap.get(lookupSchema, path); // console.log( // 'Lookup Name:', // lookupName, // '\nSchema Path:', // path, // '\nProperty:', // lookupSchema // ); // If property was not found try to find it in conditions var condition; if (!property) { if (lookupSchema.allOf) { lookupSchema.allOf.forEach(function (item) { if (item["if"]) { property = ObjectMap.ObjectMap.get(item.then, path); condition = item["if"]; } }); } // If property was still not found return null if (!property) { return null; } } // Next compute the field from property var schemaField = React.useMemo(function () { return utils.computeFieldFromProperty(name, property); }, [name]); var schemaProps = schemaField.props, type = schemaField.type, properties = schemaField.properties, items = schemaField.items, componentType = schemaField.componentType, uiBefore = schemaField.uiBefore, uiAfter = schemaField.uiAfter; // Register for events on our field React.useEffect(function () { var updater = function updater(target, property) { // Example // target="foo" // property = // { // oneOf: [ // { const: '', title: '- Select -' }, // { const: 'modelS', title: 'Model S' }, // { const: 'modelX', title: 'Model X' }, // { const: 'model3', title: 'Model 3' } // ] // } if (target === name) { logger("Updating field props for ".concat(target), utils.computeFieldFromProperty(name, property)); setCondProp(utils.computeFieldFromProperty(name, property)); } }; var remover = function remover(target) { if (target === name) { setCondProp({}); } }; emitter.on('update-combine', updater); emitter.on('update-remove', remover); return function () { emitter.removeListener('update-combine', updater); emitter.removeListener('update-remove', remover); }; }, [name]); var hookProps = useConditional.useConditional({ name: schemaProps.name, evaluate: schemaProps.evaluate, evaluateWhen: schemaProps.evaluateWhen, dependsOn: schemaProps.dependsOn }); // Combine any conditional props with the schema props var props = React.useMemo(function () { // Pull new props off of cond property var condProps = condProp.props; // Lay those on top of existing ones var newSchemaProps = utils.sanitize(schemaProps); var newCondProps = utils.sanitize(condProps); var newHookProps = utils.sanitize(hookProps); // Temp fix if (schemaProps !== null && schemaProps !== void 0 && schemaProps.required || newCondProps !== null && newCondProps !== void 0 && newCondProps.required || newHookProps !== null && newHookProps !== void 0 && newHookProps.required) { rest.required = (schemaProps === null || schemaProps === void 0 ? void 0 : schemaProps.required) || (newCondProps === null || newCondProps === void 0 ? void 0 : newCondProps.required) || (newHookProps === null || newHookProps === void 0 ? void 0 : newHookProps.required); } var newProps = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, newSchemaProps), newCondProps), newHookProps), rest); logger("Schema Props for ".concat(name), newSchemaProps); logger("Cond Props for ".concat(name), newCondProps); logger("Hook Props for ".concat(name), newHookProps); logger("New Props for ".concat(name), newProps); return newProps; }, [condProp, hookProps]); useUpdateEffect.useUpdateEffect(function () { if (props.options) { logger('options changed', props.options); fieldApi.reset(); } }, [props.options]); // Component is either on field map or components list passed in var Component = (_fieldMap$componentTy = fieldMap[componentType]) !== null && _fieldMap$componentTy !== void 0 ? _fieldMap$componentTy : options.components ? options.components[componentType] : null; // Maybe its with options // Example adapter: // withOptions: { // array: CheckboxGroup, // }, if (schemaProps.options && fieldMap.withOptions && !items) { Component = fieldMap.withOptions[componentType] || Component; // console.log('HERE!!!!!', componentType, fieldMap.withOptions); } // console.log('WTF', schemaField); logger('Rendering Field', name, schemaField); // Scope for nested if (!Component && type === 'object' && properties) { return /*#__PURE__*/React__default["default"].createElement(Scope.Scope, { scope: name }, /*#__PURE__*/React__default["default"].createElement(FormFields.FormFields, { schema: schemaField })); } // Just component if (Component && type === 'object' && properties) { return /*#__PURE__*/React__default["default"].createElement(Scope.Scope, { scope: name }, /*#__PURE__*/React__default["default"].createElement(Component, props, /*#__PURE__*/React__default["default"].createElement(FormFields.FormFields, { schema: schemaField }))); } // Array field for array ( if none was provided use our default ) if (!Component && type === 'array' && items) { return /*#__PURE__*/React__default["default"].createElement(ArrayField.ArrayField, _rollupPluginBabelHelpers["extends"]({ name: name, items: items, uiBefore: uiBefore, uiAfter: uiAfter }, props)); } // User created custom array field if (Component && componentType === 'array' && items && type === 'array') { return /*#__PURE__*/React__default["default"].createElement(Component, _rollupPluginBabelHelpers["extends"]({ name: name, items: items, uiBefore: uiBefore, uiAfter: uiAfter }, props)); } // If no component return null ( dont render ) if (!Component) { return null; } if (condition) { var _condition = condition, conditions = _condition.properties; var when = function when(_ref2) { var formApi = _ref2.formApi, scope = _ref2.scope; // Example key "married, Example condition: "{ const: 'yes' }" return Object.entries(conditions).every(function (_ref3) { var _ref4 = _rollupPluginBabelHelpers.slicedToArray(_ref3, 2), propertyName = _ref4[0], condition = _ref4[1]; return utils.checkCondition(condition, formApi.getValue(scope ? "".concat(scope, ".").concat(propertyName) : propertyName)); }); }; var Comp = function Comp() { return /*#__PURE__*/React__default["default"].createElement(Relevant.Relevant, { when: when }, /*#__PURE__*/React__default["default"].createElement(Component, _rollupPluginBabelHelpers["extends"]({ name: name }, props))); }; // console.log('WTF', Component); return /*#__PURE__*/React__default["default"].createElement(Comp, null); } // Note we DONT pass in scoped name here because useField is already scoped return /*#__PURE__*/React__default["default"].createElement(Component, _rollupPluginBabelHelpers["extends"]({ name: name }, props)); }; exports.FormField = FormField;