UNPKG

@tomino/dynamic-form-semantic-ui

Version:

Semantic UI form renderer based on dynamic form generation

135 lines 5.45 kB
import * as tslib_1 from "tslib"; import * as React from 'react'; import { observer } from 'mobx-react'; import { Search } from 'semantic-ui-react'; import { debounce } from '@tomino/toolbelt'; import { handle, css } from '../common'; import { Context } from '../context'; import { getValue, setValue, valueSource } from '../helpers'; import { DynamicComponent } from '../wrapper'; const style = css ` .input { display: block !important; } .result:first-of-type:hover, .result:first-of-type { background: #dedede !important; font-weight: bold; } `; export const SearchComponent = props => { const ctx = React.useContext(Context); return React.createElement(SearchWithContext, Object.assign({}, props, { context: ctx })); }; const controlProps = ['fluid']; let SearchWithContext = class SearchWithContext extends React.Component { constructor() { super(...arguments); this.state = { isLoading: false, options: [], value: '' }; this.resetComponent = () => this.setState({ isLoading: false, options: [], value: '' }); this.handleResultSelect = (_event, { result }) => { if (result.key === '-1') { return false; } this.setState({ value: result.title }); setValue(this.props, this.context, result.value); }; this.handleSearchChange = (_event, { value }) => { this.setState({ isLoading: true, value }); if (value.length < 1) return this.resetComponent(); this.getResults(value); }; this.resultRenderer = (option) => { let control = this.props.formElement.props.renderTemplate; let titles = option.titles || [option.title]; if (control[0] && control[0].match(/\d/)) { control = control .split('\n') .map((s, i) => `<div style="width: ${s};display: inline-block">{${i}}</div>`) .join('\n'); } titles.forEach((t, i) => (control = control.replace(`{${i}}`, t))); return React.createElement("div", { dangerouslySetInnerHTML: { __html: control } }); }; this.getResults = debounce((value) => { if (!value) { return []; } if (!this.props.formElement.props.searchName) { throw new Error('You need to define a search name!'); } let props = this.props.formElement.props; handle(this.props.handlers, props.search || 'lookup', this.props.owner, this.props, this.props.formElement, this.context, { lookup: props.searchName, single: props.single, limit: props.limit, value, context: this.props.context }).then((options) => { this.createTitles(options); this.setState({ isLoading: false, options }); }); }, 500); } async componentDidMount() { this.resetComponent(); let props = this.props.formElement.props; let value = getValue(this.props, this.context); if (!value) { return; } if (value != null) { this.setState({ isLoading: true }); handle(this.props.handlers, props.search || 'lookup', this.props.owner, this.props, this.props.formElement, this.context, { lookup: props.searchName, single: props.single, limit: props.limit, value, context: this.props.context, searchByValue: true }).then((options) => { this.createTitles(options); this.setState({ isLoading: false, value: options && options.length ? options[options.length - 1].title : '' }); }); } } createTitles(options) { for (let option of options) { if (!option.title) { if (option.titles) { option.title = option.titles.join(' - '); } else { console.error('You need to provide title!'); } } } } render() { const { isLoading, value, options } = this.state; if (!valueSource(this.props.formElement)) { return React.createElement("span", null, "Component not bound ;("); } if (this.props.readOnly || this.props.formElement.props.single) { return value; } return (React.createElement(DynamicComponent, Object.assign({}, this.props, { control: Search, controlProps: controlProps, className: style, loading: isLoading, fluid: true, showNoResults: this.state.isLoading ? false : true, showError: true, onResultSelect: this.handleResultSelect, onSearchChange: this.handleSearchChange, resultRenderer: this.props.formElement.props.renderTemplate ? this.resultRenderer : undefined, results: options, value: value }))); } }; SearchWithContext.contextType = Context; SearchWithContext = tslib_1.__decorate([ observer ], SearchWithContext); export { SearchWithContext }; export const SearchView = { Component: SearchComponent, toString: () => '' }; //# sourceMappingURL=search_view.js.map