UNPKG

@tomino/dynamic-form-semantic-ui

Version:

Semantic UI form renderer based on dynamic form generation

106 lines 5.13 kB
import * as React from 'react'; import { observer } from 'mobx-react'; import { buildDataSet } from '@tomino/dynamic-form'; import { ErrorView } from '../semantic/error_view'; import { css, prop, valueSource, handlerValue, sourceValue } from '../common'; import { toJS } from 'mobx'; import { handle, getValue, simpleHandle } from '../helpers'; import { Context } from '../context'; const noItems = css ` margin: 6px 0px 12px 0px; `; export const repeaterAddButton = css ` margin-top: 12px !important; `; class RepeaterRow extends React.PureComponent { constructor() { super(...arguments); this.handlers = { ...this.props.handlers, deleteRow: () => { if (handlerValue(this.props.formElement.props.value)) { handle(this.props.handlers, this.props.formElement.props.onDelete, this.props.owner, this.props, this.context, this.props.data); } else { this.props.owner.removeRowData(sourceValue(this.props.formElement.props.value), this.props.data); } }, editRow: () => { this.props.select(this.props.index); } }; } render() { let template = this.props.index === this.props.selectedIndex ? this.props.editorTemplate : this.props.viewTemplate; return this.props.catalogue.createComponent({ ...this.props, handlers: this.handlers, owner: this.props.data }, template, this.context); } } RepeaterRow.contextType = Context; const AddRow = observer(({ addTemplate, props }) => { const context = React.useContext(Context); const boundSource = valueSource(props.formElement); const addDataset = React.useMemo(() => { let schema = props.owner.getSchema(boundSource).originalSchema.items; if (!schema.properties) { schema = { type: 'object', properties: { value: { type: schema.type } } }; } return buildDataSet(schema, {}); }, [boundSource, props.owner]); const handlers = React.useMemo(() => ({ ...props.handlers, addRow: () => { const { formElement, owner } = props; if (formElement.props.onAdd) { simpleHandle(props, props.formElement.props.onAdd, context); } if (prop(formElement)) { owner.addRow(valueSource(formElement), toJS(addDataset)); } } }), [addDataset, context, props]); return (React.createElement("div", { className: repeaterAddButton }, addTemplate && props.catalogue.createComponent({ ...props, owner: addDataset, handlers }, addTemplate, context))); }); class RepeaterComponent extends React.Component { constructor() { super(...arguments); this.state = { selectedIndex: -1 }; this.handleToggleChange = (_e, control) => { this.props.owner.parseValue(prop(this.props.formElement), control.checked); }; } render() { const { formElement, owner } = this.props; const { allowAdd } = formElement.props; const boundSource = valueSource(formElement); const list = owner.getValue(boundSource); let viewTemplate = formElement.elements.length > 0 && formElement.elements[0]; let editorTemplate = formElement.elements.length > 1 && formElement.elements[1]; let addTemplate = formElement.elements.length > 2 && formElement.elements[2]; if (!boundSource) { return React.createElement("div", null, "Please bind the repeater to an array source"); } return (React.createElement(React.Fragment, null, list == null || list.length === 0 ? (React.createElement("div", { className: noItems }, `This collection contains no items ...`)) : (list.map((listItemDataSet, i) => (React.createElement(RepeaterRow, { index: i, key: i + Date.now(), owner: owner, formElement: formElement, data: listItemDataSet, extra: this.props.extra, handlers: this.props.handlers, readOnly: this.props.readOnly, catalogue: this.props.catalogue, editorTemplate: editorTemplate, viewTemplate: viewTemplate || editorTemplate, selectedIndex: this.state.selectedIndex, select: index => this.setState({ selectedIndex: index }) })))), allowAdd && !this.props.readOnly && (React.createElement(AddRow, { addTemplate: addTemplate, addDataset: this.addDataset, props: this.props })), React.createElement(ErrorView, { owner: owner, source: boundSource, pointing: "left" }))); } } export const RepeaterView = { Component: observer(RepeaterComponent), toString: (_owner, props, context, catalogue) => { const repeaterList = getValue(props, context); return repeaterList .map((l, i) => `[${i + 1}] ${props.formElement.elements .map(el => catalogue.components[el.control].toString(l, { ...props, formElement: el }, context, catalogue)) .join('\n ')}`) .join('\n\n'); } }; //# sourceMappingURL=repeater_view.js.map