UNPKG

@tomino/dynamic-form-semantic-ui

Version:

Semantic UI form renderer based on dynamic form generation

148 lines 5.81 kB
import React from 'react'; import names from 'classnames'; import { Context } from './context'; import { css } from 'emotion'; import { handle, getValue, isNullOrEmpty, valueSource } from './helpers'; import { ErrorBoundary } from './vanilla/error_boundary'; import { createComponents } from './common'; import { observer } from 'mobx-react'; import { ErrorView } from './semantic/error_view'; export const breakingLabel = css ` display: block; font-weight: bold; margin-top: 3px; margin-bottom: 3px; `; export const nonBreakingLabel = css ` display: inline-block; font-weight: bold; padding-right: 6px; margin-top: 3px; margin-bottom: 3px; `; const defaultMouseEvents = ['onClick', 'onMouseOver', 'onMouseOut', 'onMouseDown', 'onMouseUp']; const defaultFormEvents = ['onChange', 'onInput']; const defaultKeyEvents = ['onKeyDown', 'onKeyUp']; const defaultEvents = [...defaultMouseEvents, ...defaultFormEvents, ...defaultKeyEvents]; const omitKeys = [ 'styleName', 'catalogue', 'children', 'extra', 'formElement', 'handlers', 'owner', 'className', 'readOnly', 'controlProps', 'control', 'ownAddCell', 'EmptyCell', 'Component', 'showError', 'staticContext', 'routerProps', 'dataProps', 'hideLabel' ]; function omit(obj, keys) { var target = {}; for (var i of Object.keys(obj)) { if (keys.indexOf(i) >= 0) continue; target[i] = obj[i]; } return Object.keys(target).length > 0 ? target : null; } const eventCache = []; function getCachedEvent(formElement, event, props, context, extra = null, events = null) { let current = eventCache.find(c => c.props === props); if (!current) { current = { props }; eventCache.push(current); } if (!current[event]) { current[event] = (e, ui) => { if (extra && extra[event]) { extra[event](e, ui); } if (events && events[event]) { events[event](e, ui); } if (formElement.props[event]) { handle(props.handlers, formElement.props[event], props.owner, props, context, { e, ui }); } }; } else { console.log('Using cached ...'); } return current[event]; } export function paintProps(props, context, className, allowedProperties, componentProps) { let result = { id: props.formElement.uid, 'data-control': props.formElement.control }; if (props.formElement.props) { for (let prop of Object.keys(props.formElement.props)) { if (defaultEvents.indexOf(prop) >= 0) { result[prop] = getCachedEvent(props.formElement, prop, props, context, props.extra, componentProps); } else if (allowedProperties && allowedProperties.indexOf(prop) >= 0) { result[prop] = getValue(props, context, prop, undefined); result[prop] = isNullOrEmpty(result[prop]) ? undefined : result[prop]; } } } const controlCss = getValue(props, context, 'css'); if (props.className || controlCss || className || (props.extra && props.extra.className)) { result.className = names(result[className], className, props.className, props.extra ? props.extra.className : undefined, controlCss ? css([controlCss]) : undefined); } if (props.extra) { for (let prop of Object.keys(props.extra)) { if (!result[prop]) { result[prop] = props.extra[prop]; } } } if (componentProps) { for (let prop of Object.keys(componentProps)) { result[prop] = componentProps[prop]; } } return result; } export function renderEmptyCell(props, className) { return (props.formElement.elements.length === 0 && props.EmptyCell && React.createElement(props.EmptyCell, Object.assign({}, props, { className: className }))); } export const DynamicComponent = observer(props => { const context = React.useContext(Context); React.useEffect(() => () => { eventCache.splice(eventCache.findIndex(c => c.props == props), 1); }); let formElement = props.formElement; let currentProps = paintProps(props, context, props.styleName, props.controlProps, omit(props, omitKeys)); if (props.preserveProps) { currentProps = { ...currentProps, ...props }; } currentProps.key = formElement.uid; const label = getValue(props, context, 'label'); if (label) { const { onMouseOver, onMouseOut, className, ...rest } = currentProps; return (React.createElement(ErrorBoundary, null, React.createElement("div", { onMouseOver: onMouseOver, onMouseOut: onMouseOut, className: className, "data-control": currentProps['data-control'] + 'Wrapper' }, !props.hideLabel && (label || formElement.props.formAlign) && (React.createElement("label", { className: formElement.props.inline ? nonBreakingLabel : breakingLabel, htmlFor: formElement.uid }, label || '\xa0')), React.createElement(props.control || 'div', rest, props.children)), props.showError && (React.createElement(ErrorView, { inline: !!formElement.props.inline, owner: props.owner, source: valueSource(formElement) })))); } return (React.createElement(ErrorBoundary, null, React.createElement(props.control || 'div', currentProps, props.children || createComponents(props)), props.showError && (React.createElement(ErrorView, { inline: !!formElement.props.inline, owner: props.owner, source: valueSource(formElement) })))); }); DynamicComponent.displayName = 'DynamicControl'; //# sourceMappingURL=wrapper.js.map