UNPKG

@tomino/dynamic-form-semantic-ui

Version:

Semantic UI form renderer based on dynamic form generation

283 lines 9.68 kB
import React from 'react'; import { toJS } from 'mobx'; import { Context } from './context'; export function merge(...catalogues) { if (!catalogues.some(c => c.createComponent)) { throw new Error('The catalogue needs to define a createComponent function!'); } return { createComponent: catalogues.find(c => c.createComponent).createComponent, cssClass: catalogues.map(c => (c.cssClass ? c.cssClass + ' ' : '')).join(''), components: Object.assign({}, ...catalogues.map(c => c.components)) }; } const composites = ['definitions', 'properties', 'items']; export function schemaDatasetToJS(schema, faker = true) { let result = cleanSchemaDataset(toJS(schema), faker); if (!result) { return null; } if (result.type === 'object' && !result.properties) { result.properties = {}; } return result; } export function formDatasetToJS(form) { return cleanForm(toJS(form)); } function cleanForm(form) { if (!form) { return null; } let result = {}; for (let key of Object.getOwnPropertyNames(form)) { if (key === 'parent' || key === 'isSelected') { continue; } let value = form[key]; if (Array.isArray(value)) { if (value.length > 0) { result[key] = value.map(v => (typeof v === 'object' ? cleanForm(v) : v)); } } else if (value != null && typeof value === 'object') { if (Object.getOwnPropertyNames(value).length > 0) { result[key] = cleanForm(value); } } else if (value) { result[key] = value; } } if (Object.keys(result).length === 0) { return undefined; } return result; } function cleanSchemaDataset(schema, faker) { const cleaned = {}; if (schema == null) { return; } let keys = Object.getOwnPropertyNames(schema || {}); for (let key of keys) { let value = schema[key]; if (value == null || value === '') { continue; } if (key === 'errors' || key === 'imports' || typeof schema[key] === 'function') { } else if (key === 'reference') { if (faker) { cleaned.properties = cleanSchemaDataset(schema.reference.properties, faker); } } else if (composites.indexOf(key) >= 0) { if ((faker || !schema.$ref) && value && Object.getOwnPropertyNames(value).length > 0) { cleaned[key] = cleanSchemaDataset(schema[key], faker); } } else if (key === '$enum') { if (schema.$enum.length > 0) { cleaned.enum = schema.$enum.map((e) => e.value); cleaned.$enum = schema.$enum.map((e) => ({ text: e.text, value: e.value, icon: e.icon })); } } else if (Array.isArray(value)) { if (value.length > 0) { cleaned[key] = value.map(v => (typeof v === 'object' ? cleanSchemaDataset(v, faker) : v)); } } else if (typeof value === 'object') { if (Object.getOwnPropertyNames(value).length > 0) { cleaned[key] = cleanSchemaDataset(value, faker); } } else { cleaned[key] = value; } } if (faker) { if (schema.properties) { cleaned.required = Object.getOwnPropertyNames(schema.properties); } } return cleaned; } export function simpleHandle(props, handleName, context, args) { return handle(props.handlers, handleName, props.owner, props, props.formElement, context, args); } export function handle(handlers, handle, owner, props, formElement, context, args) { if (!handlers[handle]) { console.error('Handler does not exist: ' + handle); return; } return handle && handlers[handle] ? handlers[handle]({ owner, props, formElement, context, args }) : null; } export function bindGetValue(props, context) { return function (element, propName, defaultValue) { return getPropValue(props, element, context, propName, defaultValue); }; } export function getValues(props, ...propNames) { const context = React.useContext(Context); return propNames.map(p => getPropValue(props, props.formElement, context, p)); } export function getValue(props, context, propName, defaultValue, path = '') { return getPropValue(props, props.formElement, context, propName, defaultValue, path); } export function getPropValue(props, formElement, context, propName = undefined, defaultValue = undefined, path = '') { if (!propName) { propName = 'value'; } let prop = formElement.props ? formElement.props[propName] : null; if (prop == null) { return defaultValue; } if (typeof prop !== 'object' || Array.isArray(prop)) { return prop; } if (prop.value != null) { return prop.value; } else if (prop.handler) { return handle(props.handlers, prop.handler, props.owner, props, props.formElement, context); } else if (prop.source) { return props.owner.getValue ? props.owner.getValue(prop.source + path) : props.owner[prop.source]; } return defaultValue === null ? '' : defaultValue; } export function safeGetValue(props, context, propName = null, defaultValue = null) { let value = getValue(props, context, propName, defaultValue); if (value == null) { return value; } return value.toString(); } export function setValue(props, context, value, propName = undefined, path = '') { setPropValue(props, props.owner, context, value, propName, path); } export function setPropValue(props, owner, context, value, propName = undefined, path = '') { if (!propName) { propName = 'value'; } let prop = props.formElement.props[propName]; if (prop == null) { return; } if (typeof prop !== 'object') { owner.setValue(propName, value); } if (prop.parse) { handle(props.handlers, prop.parse, props.owner, props, props.formElement, context, { current: value, previous: getValue(props, context, propName) }); return; } if (prop.source) { owner.setValue(prop.source, path ? { [path.substring(1)]: value } : value, prop.validate ? props.handlers[prop.validate] : undefined); } else if (prop.handler) { handle(props.handlers, prop.handler, props.owner, props, context, value); } } export function prop(formElement, propName = 'value', type = 'source') { return formElement && formElement.props && formElement.props[propName] ? formElement.props[propName][type] : null; } export function isNullOrEmpty(val) { return val == null || val == ''; } export function valueSource(formElement) { return prop(formElement, 'value', 'source'); } export function valueHandler(formElement) { return prop(formElement, 'value', 'handler'); } export function value(formElement) { return prop(formElement, 'value', 'value'); } function stripUid(obj) { if (obj.uid) { delete obj.uid; } for (let key of Object.keys(obj)) { let property = obj[key]; if (property.uid) { delete property.uid; } if (Array.isArray(property)) { for (let e of property) { stripUid(e); } } else if (typeof property === 'object') { stripUid(property); } } return obj; } export function clone(dataset) { return stripUid(formDatasetToJS(dataset)); } export function parseProps(props, context) { const value = getValue(props, context, undefined, undefined) || ''; const controlSource = valueSource(props.formElement); let error = ''; let disabled = false; const label = getValue(props, context, 'label'); if (controlSource !== '' && props.owner.getSchema(controlSource, false) != null) { error = controlSource ? props.owner.getError(controlSource) : null; disabled = props.readOnly || (controlSource && props.owner.getSchema(controlSource).readOnly); } return { value, label, error, disabled }; } export function processControl(props, createCallback = true) { const context = React.useContext(Context); const { formElement, owner } = props; let handleChange; if (createCallback) { handleChange = React.useCallback((e, uiProps) => { const source = valueSource(formElement); if (!source) { return; } setValue(props, context, uiProps.checked != null ? uiProps.checked : uiProps.value != null ? uiProps.value : e.currentTarget.checked !== undefined ? e.currentTarget.checked : e.currentTarget.value); const changeHandler = props.formElement.props.onChange; if (changeHandler) { simpleHandle(props, changeHandler, context); } }, [context, formElement, props]); } const { error, value, disabled } = parseProps(props, context); const source = valueSource(formElement); return { context, owner, formElement, error, value, disabled, source, handleChange, controlProps: formElement.props }; } //# sourceMappingURL=helpers.js.map