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