@tomino/dynamic-form-semantic-ui
Version:
Semantic UI form renderer based on dynamic form generation
148 lines • 5.81 kB
JavaScript
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