@tomino/dynamic-form-semantic-ui
Version:
Semantic UI form renderer based on dynamic form generation
154 lines • 8.44 kB
JavaScript
import * as React from 'react';
import * as styles from './properties_common';
import { styledTableRow, addButton, celled } from './properties_common';
import { observer } from 'mobx-react';
import { select, prop } from '../common';
import { ErrorView } from '../semantic/error_view';
import { PropertyHeader } from './group';
import { Dropdown, Input, Icon } from 'semantic-ui-react';
import { Select } from './select';
import { renderControl } from './control_factory';
import { css } from 'emotion';
import { EditorContext } from '../editor/editor_context';
import { getValue } from '../helpers';
import { DragDrop } from '../layouts/drag_drop';
import { dot } from './binding';
const handle = css `
padding-left: 3px;
opacity: 0.5;
cursor: grab;
`;
const Handle = (props) => {
return (React.createElement("div", Object.assign({}, props, { className: handle }),
React.createElement(Icon, { name: "content" })));
};
function dragStart(index, context) {
return function (e) {
const target = e.currentTarget;
context.dragItem = {
from: index,
type: 'table',
node: e.currentTarget
};
setTimeout(() => {
target.style.visibility = 'hidden';
target.style.height = '0px';
target.style.margin = '0px';
}, 1);
};
}
const TableRow = props => {
const context = React.useContext(EditorContext);
const deleteRow = React.useCallback((e) => {
props.data.removeRowIndex(prop(props.formElement), parseInt(e.currentTarget.value));
}, [props.data, props.formElement]);
const onDragStart = React.useCallback(dragStart(props.index, context), [props.index]);
return (React.createElement("div", { className: styledTableRow(context.theme), onDragStart: onDragStart },
React.createElement(Handle, Object.assign({}, props.dragHandleProps, { index: props.index })),
props.formElement.elements.map((e, i) => (React.createElement("div", { className: styles.tableRowFull, key: i, style: {
flex: `1 1 ${(e.props && e.props.width) || '100%'}`
} }, renderControl({ ...props, formElement: e })))),
!props.readOnly && (React.createElement("div", { className: styles.tableRowAuto },
React.createElement("button", { className: addButton(context.theme), onClick: deleteRow, value: props.index }, "x")))));
};
const SimpleTableRow = props => {
const context = React.useContext(EditorContext);
const onDragStart = React.useCallback(dragStart(props.index, context), [props.index]);
const onChange = React.useCallback((_e, props) => props.data.setArrayValue(props.formElement.props.value.source, props.index, props.value), []);
const deleteRow = React.useCallback((e) => {
props.data.removeRowIndex(props.formElement.props.value.source, parseInt(e.currentTarget.value));
}, [props.data, props.formElement.props.value.source]);
function renderControl() {
if (!props.formElement.elements || props.formElement.elements.length === 0) {
throw new Error('You need to define the type of the control for the table row. For example: { elements: [{control: "Input"}] }');
}
const formElement = props.formElement.elements[0];
const value = props.list[props.index];
const type = (formElement.props && formElement.props.type) || 'text';
switch (formElement.control) {
case 'Input':
return React.createElement(Input, { type: type, onChange: onChange, value: value });
case 'Select':
const options = getValue({ ...props, formElement }, context, 'options');
return (React.createElement(Dropdown, { value: value, "data-value": value, search: true, selection: true, fluid: true, name: "type", onChange: onChange, className: `property-search ${select}`, options: options }));
}
}
return (React.createElement("div", { className: styledTableRow(context.theme), onDragStart: onDragStart },
React.createElement(Handle, Object.assign({}, props.dragHandleProps, { index: props.index })),
React.createElement("div", { className: styles.tableRowFull }, renderControl()),
!props.readOnly && (React.createElement("div", { className: styles.tableRowAuto },
React.createElement("button", { className: addButton(context.theme), onClick: deleteRow, value: props.index }, "x")))));
};
let id = 1;
const processor = {
children: props => {
const source = prop(props.formElement);
return props.owner.getValue(source) || [];
},
id: props => {
if (props.value) {
return props.value;
}
if (props.formElement) {
if (!props.formElement.uid) {
props.formElement.uid = id++;
}
return props.formElement.uid;
}
if (props.uid) {
return props.uid;
}
return id++;
throw new Error('Could not determine ID');
},
name: () => ''
};
export const TableComponent = props => {
const context = React.useContext(EditorContext);
const addRow = React.useCallback(() => {
const { formElement, owner } = props;
owner.addRow(prop(formElement));
}, [props]);
const onDrop = React.useCallback((to) => {
if (!context.dragItem || context.dragItem.type !== 'table') {
return;
}
let { formElement, owner } = props;
owner.moveRow(prop(formElement), context.dragItem.from, to);
}, [context.dragItem, props]);
const dragHandleProps = React.useMemo(() => ({
onMouseDown(e) {
e.currentTarget.parentNode.setAttribute('draggable', 'true');
},
onMouseUp(e) {
e.currentTarget.parentNode.setAttribute('draggable', 'false');
}
}), []);
const onEndDrag = React.useCallback(e => {
let item = context.dragItem;
if (item && item.node) {
item.node.style.visibility = 'visible';
item.node.style.height = '';
item.node.style.margin = '';
}
e.target.draggable = false;
context.dragItem = null;
}, [context.dragItem]);
const drag = React.useMemo(() => new DragDrop('column', props, processor, `color: ${context.theme.textColor}!important;`, 'outline', onDrop, onEndDrag, false, 20, context), [context, onDrop, onEndDrag, props]);
const owner = props.owner;
const formElement = props.formElement;
const controlProps = formElement.props;
const source = prop(formElement);
const list = owner.getValue(source) || [];
return (React.createElement(PropertyHeader, { label: formElement.props && formElement.props.text, buttons: React.createElement(React.Fragment, null,
(!controlProps.view || controlProps.view === 'value') && (React.createElement("button", { className: "headerButton", onClick: addRow }, "+")),
formElement.props.bound && (React.createElement("div", { className: dot(controlProps.view), onClick: formElement.props.changeBound, style: { marginRight: '20px' }, title: `Green - Value
Yellow - Bound to data
Red - Handled by a function` }))), bound: formElement.props.bound, changeBound: formElement.props.changeBound },
controlProps.view && controlProps.view !== 'value' && (React.createElement(Select, Object.assign({ extra: controlProps.view }, props))),
!controlProps.view || (controlProps.view === 'value' && list.length > 0) ? (React.createElement(React.Fragment, null,
React.createElement("div", Object.assign({ className: celled(context.theme) }, drag.props()), list.map((row, i) => typeof list[0] === 'object' ? (React.createElement(TableRow, { key: i, index: i, formElement: formElement, owner: row, data: owner, readOnly: props.readOnly, catalogue: props.catalogue, handlers: props.handlers, dragHandleProps: dragHandleProps, uid: props.uid })) : (React.createElement(SimpleTableRow, { key: i, index: i, formElement: formElement, list: list, owner: owner, data: owner, readOnly: props.readOnly, catalogue: props.catalogue, handlers: props.handlers, dragHandleProps: dragHandleProps, uid: props.uid })))),
React.createElement(ErrorView, { owner: props.owner, source: prop(formElement), pointing: "left" }))) : (undefined)));
};
export const TableView = observer(TableComponent);
//# sourceMappingURL=table.js.map