UNPKG

@tomino/dynamic-form-semantic-ui

Version:

Semantic UI form renderer based on dynamic form generation

117 lines (103 loc) 3.54 kB
import { FormComponentProps } from '@tomino/dynamic-form'; import { FormDataSet, SchemaDataSet } from './form_store'; import { GridChildProps } from '../layouts/grid_view'; import { EditorContextType } from './editor_context'; import { bindGetValue } from '../helpers'; export function findConflict( props: FormComponentProps, context: EditorContextType, cells: FormDataSet<GridChildProps>[], start: number, end: number ) { const getValue = bindGetValue(props, context); return cells.find( e => (getValue(e, 'column') >= start && getValue(e, 'column') <= end) || (getValue(e, 'column') + getValue(e, 'width') - 1 >= start && getValue(e, 'column') + getValue(e, 'width') - 1 <= end) ); } export function adjustPosition( props: FormComponentProps, context: EditorContextType, where: string, source: FormDataSet<GridChildProps>, target: FormDataSet<GridChildProps>, parent: FormDataSet<GridChildProps> ) { const getValue = bindGetValue(props, context); if (!parent) { // TODO: fix return getValue(target, 'column'); } let dimensions = parent.elements.reduce( (prev, next) => ({ rows: prev.rows < next.props.row ? next.props.row : prev.rows, columns: prev.columns < next.props.column ? next.props.column : prev.columns }), { rows: 0, columns: 0 } ); // adjust from left or right let column = where === 'left' ? getValue(target, 'column') : getValue(target, 'column') - getValue(target, 'width') + 1; // if (adjust) { // source.props.column = position.props.column - source.props.width + 1; // } // adjust to min width column = column < 1 ? 1 : column; // adjust to max width column = column + source.props.width > dimensions.columns ? dimensions.columns - getValue(source, 'width') + 1 : column; let cells = parent.elements.filter(e => e.props.row === target.props.row && e !== source); // try one adjustment moving the item left or right from the conflict cell let conflict = findConflict(props, context, cells, column, column + source.props.width - 1); // TRYING TO SOLVE IT FOR THE USER // if (conflict) { // column = where === 'left' ? conflict.props.column - source.props.width : conflict.props.column + conflict.props.width; // } // // if it fails again we give up // if (column >= 0) { // conflict = findConflict(cells, column, column + source.props.width - 1); // } if (conflict) { return -1; } return column; } export function bind(formElement: FormDataSet, item: any) { // we can either drop on existing control // or on an empty cell if (formElement.parent) { // find the parent path let parent = formElement.parent; let parentPath = ''; while (parent) { if (parent.props.value && parent.props.value.source) { parentPath = parentPath + parent.props.value + '.'; } parent = parent.parent; } let path = item.name.replace(parentPath, ''); formElement.setValue('source', path); return; } // if it is an empty cell, we will guess the control const schema: SchemaDataSet = item.schema; item.label = item.name; item.source = item.name; if (schema.type === 'boolean') { item.name = 'Checkbox'; } else if (schema.type === 'array') { item.name = 'Table'; } else if (schema.type === 'number' || schema.type === 'integer') { item.name = 'Input'; item.controlProps = { type: 'number' }; } else if (schema.type === 'string') { item.name = 'Input'; } }