{"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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"}