{"version":3,"file":"AutoComplete-VtTlJFlv.js","sources":["../../Client/legacy/Components/AutoComplete.tsx"],"sourcesContent":["import * as Constants from '@shared/Constants';\r\nimport { IAutocompleteMethodProps, IAutocompleteProps } from '@shared/Models';\r\nimport * as React from 'react';\r\nimport { findDOMNode } from 'react-dom';\r\n\r\nexport interface IAutocompleteState<TModel> {\r\n value: string | undefined;\r\n results: TModel[];\r\n visible: boolean;\r\n selectedIndex: number;\r\n left: number;\r\n top: number;\r\n width: number;\r\n loading: boolean;\r\n}\r\n\r\nexport class Autocomplete<TModel, TProps = {}> extends React.Component<\r\n IAutocompleteProps & IAutocompleteMethodProps<TModel> & TProps,\r\n IAutocompleteState<TModel>\r\n> {\r\n component: HTMLDivElement;\r\n timeout: any;\r\n maxLength: number;\r\n hideOnBodyClick: boolean;\r\n input: HTMLInputElement;\r\n mounted: boolean;\r\n\r\n onBodyClickHandler: Function;\r\n\r\n constructor(props: IAutocompleteProps & IAutocompleteMethodProps<TModel> & TProps) {\r\n super(props);\r\n\r\n this.maxLength = (this.props.maxResults || 100) as number;\r\n this.hideOnBodyClick = (\r\n this.props.hideOnBodyClick === undefined ? true : this.props.hideOnBodyClick\r\n ) as boolean;\r\n\r\n this.state = {\r\n value: this.props.defaultValue || '',\r\n results: [],\r\n visible: false,\r\n selectedIndex: 0,\r\n left: 0,\r\n top: 0,\r\n width: 0,\r\n loading: false,\r\n };\r\n }\r\n\r\n componentDidMount() {\r\n this.mounted = true;\r\n this.onBodyClickHandler = this.onBodyClick.bind(this);\r\n (document.querySelector('body') as any).addEventListener('click', this.onBodyClickHandler);\r\n }\r\n\r\n componentWillUnmount() {\r\n this.mounted = false;\r\n (document.querySelector('body') as any).removeEventListener('click', this.onBodyClickHandler);\r\n }\r\n\r\n focus() {\r\n this.input.focus();\r\n }\r\n\r\n clear() {\r\n this.setState({ value: '' });\r\n }\r\n\r\n render() {\r\n return (\r\n <div\r\n ref={c => {\r\n this.component = c as HTMLDivElement;\r\n }}\r\n className={`${this.props.className || ''} autocomplete`}\r\n >\r\n <label className={this.props.labelClassName || ''}>{this.props.label}</label>\r\n <div className={`autocomplete-input-wrapper-cp ${this.props.inputWrapperClassName || ''}`}>\r\n <input\r\n className={this.props.inputClassName || ''}\r\n ref={c => {\r\n this.input = c as HTMLInputElement;\r\n }}\r\n type='text'\r\n placeholder={this.props.placeholder}\r\n value={this.state.value}\r\n id={this.props.id || ''}\r\n autoComplete={new Date().getTime().toString()}\r\n onFocus={this.onFocus.bind(this)}\r\n onBlur={this.onBlur.bind(this)}\r\n onChange={this.onChange.bind(this)}\r\n onKeyDown={this.onKeyDown.bind(this)}\r\n onKeyUp={e => this.props.onKeyUp && this.props.onKeyUp(e)}\r\n />\r\n\r\n <div\r\n className={`autocomplete-input-spinner-cp ${\r\n this.state.loading ? 'autocomplete-input-spinner-shown-cp' : ''\r\n }`}\r\n >\r\n <div />\r\n </div>\r\n\r\n {this.props.customSelector ? (\r\n this.props.customSelector(\r\n this.state.visible,\r\n this.state.results,\r\n this.state.left,\r\n this.state.top,\r\n this.state.width,\r\n this.onSelect.bind(this),\r\n (selectedIndex: number) => this.setState({ selectedIndex }),\r\n this.state.selectedIndex\r\n )\r\n ) : (\r\n <div\r\n className={`selector${\r\n this.state.visible && !this.props.hideCompletions ? '' : ' autocomplete-hidden'\r\n } ${this.props.selectorClassName || ''}`}\r\n >\r\n <div>\r\n {this.state.results.map((result, i) => {\r\n return (\r\n <div\r\n className={`property ${this.state.selectedIndex === i ? 'selected' : ''}`}\r\n key={i}\r\n onClick={this.onSelect.bind(this, result)}\r\n onMouseEnter={this.onHover.bind(this, i)}\r\n >\r\n <span>\r\n {this.props.display ? this.props.display(result) : (result as any)}\r\n </span>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n onHover(selectedIndex) {\r\n this.setState({ selectedIndex });\r\n }\r\n\r\n onBodyClick(e) {\r\n // We need to skip hiding the popup if the user clicks in the autocomplete but it is inside a wrapper element. Any composite components that use this\r\n // pattern will need to include the string below in the id attribute of the wrapper.\r\n if (!this.mounted || (e.target.id || '').includes('autocomplete-wrapper')) {\r\n return;\r\n }\r\n\r\n if (this.hideOnBodyClick && !isAncestor(e.target, 'selector')) {\r\n this.setState({ visible: false });\r\n }\r\n\r\n function isAncestor(element, className) {\r\n while (element.parentNode) {\r\n element = element.parentNode;\r\n\r\n if ((element.className && element.className.includes ? element.className : '').includes(className)) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n }\r\n\r\n onChange(e) {\r\n this.setSelectorPosition();\r\n\r\n let value = e.target.value;\r\n this.setState({ value: value, selectedIndex: 0 });\r\n\r\n if (this.timeout) clearTimeout(this.timeout);\r\n\r\n this.timeout = setTimeout(\r\n () => {\r\n this.performGet();\r\n\r\n if (this.props.onDebouncedChange) this.props.onDebouncedChange(value);\r\n },\r\n this.props.debounceDelay === undefined ? 250 : this.props.debounceDelay\r\n );\r\n\r\n if (this.props.onChange) this.props.onChange(value);\r\n }\r\n\r\n onKeyDown(e) {\r\n if (!this.state.visible) return;\r\n\r\n let selectedIndex = this.state.selectedIndex,\r\n length = this.state.results.length;\r\n\r\n if (Constants.isKeyName(e.key, Constants.KeyName.Enter)) {\r\n this.onSelect(this.state.results[this.state.selectedIndex]);\r\n } else if (Constants.isKeyName(e.key, Constants.KeyName.Down)) {\r\n selectedIndex = Math.min(selectedIndex + 1, length - 1);\r\n } else if (Constants.isKeyName(e.key, Constants.KeyName.Up)) {\r\n selectedIndex = Math.max(0, selectedIndex - 1);\r\n }\r\n\r\n this.setState({ selectedIndex });\r\n }\r\n\r\n onSelect(result) {\r\n this.setState({\r\n visible: false,\r\n selectedIndex: 0,\r\n value: this.props.map ? this.props.map(result) : result,\r\n });\r\n\r\n if (this.props.onSelect) this.props.onSelect(result);\r\n }\r\n\r\n onFocus() {\r\n this.setSelectorPosition();\r\n if (this.props.onFocus) this.props.onFocus();\r\n }\r\n\r\n onBlur() {\r\n if (this.props.onBlur) this.props.onBlur();\r\n }\r\n\r\n performGet() {\r\n if (this.state.value === '')\r\n return this.setState({\r\n results: [],\r\n visible: false,\r\n });\r\n\r\n this.setState({ loading: true });\r\n return this.props.get(this.state.value, this.maxLength).then(results => {\r\n this.setState({\r\n results: results,\r\n visible: results.length > 0,\r\n loading: false,\r\n });\r\n });\r\n }\r\n\r\n private setSelectorPosition() {\r\n const dom = findDOMNode(this.input) as Element;\r\n if (dom) {\r\n const rect = dom.getBoundingClientRect();\r\n this.setState({\r\n top: rect.top + rect.height + (window as any).pageYOffset,\r\n left: rect.left + (window as any).pageXOffset,\r\n width: rect.width,\r\n });\r\n }\r\n }\r\n}\r\n"],"names":["Autocomplete","React.Component","props","__publicField","jsxs","c","jsx","e","selectedIndex","result","i","isAncestor","element","className","value","length","Constants.isKeyName","Constants.KeyName","results","dom","findDOMNode","rect"],"mappings":"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"}