<commit_before>import PropTypes from 'prop-types'
import React from 'react'
import ReactDOM from 'react-dom'
import Select, {components} from 'react-select'
import {connect, select} from 'store'
import {msg} from 'translate'
import Icon from 'widget/icon'
import styles from './comboBox.css'


const mapStateToProps = () => ({
    appDimensions: select('dimensions')
})

class ComboBox extends React.Component {
    state = {}
    element = React.createRef()
    menuPortalTarget = React.createRef()

    render() {
        const {
            input,
            validate = 'onBlur',
            isClearable = true,
            isLoading,
            showChevron = true,
            showCurrentSelection = true,
            menuPlacement = 'bottom',
            controlClassName,
            menuClassName,
            onChange,
            onBlur,
            children,
            ...props
        } = this.props
        const components = {LoadingIndicator}
        if (!showChevron)
            components.DropdownIndicator = null
        if (children)
            components.SingleValue = createSingleValue(children)
        return (
            <div className={[styles.comboBox, controlClassName, input.error ? 'error' : null].join(' ')} ref={this.element}>
                {ReactDOM.createPortal(
                    <div ref={this.menuPortalTarget} className={[menuClassName, 'portalTarget'].join(' ')}/>,
                    document.body
                )}
                <Select
                    {...props}
                    name={input.name}
                    value={showCurrentSelection ? this.state.selectedOption : null}
                    classNamePrefix='comboBox'
                    maxMenuHeight={this.state.maxMenuHeight}
                    menuPlacement={menuPlacement}
                    menuPortalTarget={this.menuPortalTarget.current}
                    isClearable={isClearable}
                    isLoading={!!isLoading}
                    loadingMessage={() => msg('widget.comboBox.loading')}
                    components={components}
                    onChange={(e) => {
                        input.handleChange({target: {value: e ? e.value : '', name: input.name}})
                        if (onChange)
                            onChange(e)
                        if (validate === 'onChange')
                            input.validate()
                    }}
                    onBlur={(e) => {
                        if (onBlur)
                            onBlur(e)
                        if (validate === 'onBlur')
                            input.validate()
                    }}
                />
            </div>
        )
    }

    componentDidMount() {
        this.updateSelectedOption()
        this.updateMaxMenuHeight()
    }

    componentDidUpdate(prevProps) {
        const value = this.props.input.value
        if (prevProps.input.value !== value)
            this.updateSelectedOption()

        const appHeight = this.props.appDimensions.height
        if (this.element.current && prevProps.appDimensions.height !== appHeight)
            this.updateMaxMenuHeight()
    }

    updateMaxMenuHeight() {
        const appHeight = this.props.appDimensions.height
        const comboBoxBox = this.element.current.getBoundingClientRect()
        const availableSpace = (
            this.props.menuPlacement === 'top'
                ? comboBoxBox.top
                : appHeight - comboBoxBox.bottom
        ) - 10

        let maxMenuHeightProp = this.props.maxMenuHeight || '20rem'
        if (maxMenuHeightProp.toString().toLowerCase().endsWith('rem'))
            maxMenuHeightProp = parseFloat(maxMenuHeightProp) * parseFloat(getComputedStyle(document.documentElement).fontSize)<commit_msg>Updated selection option on options update.<commit_after>import PropTypes from 'prop-types'
import React from 'react'
import ReactDOM from 'react-dom'
import Select, {components} from 'react-select'
import {connect, select} from 'store'
import {msg} from 'translate'
import Icon from 'widget/icon'
import styles from './comboBox.css'


const mapStateToProps = () => ({
    appDimensions: select('dimensions')
})

class ComboBox extends React.Component {
    state = {}
    element = React.createRef()
    menuPortalTarget = React.createRef()

    render() {
        const {
            input,
            validate = 'onBlur',
            isClearable = true,
            isLoading,
            showChevron = true,
            showCurrentSelection = true,
            menuPlacement = 'bottom',
            controlClassName,
            menuClassName,
            onChange,
            onBlur,
            children,
            ...props
        } = this.props
        const components = {LoadingIndicator}
        if (!showChevron)
            components.DropdownIndicator = null
        if (children)
            components.SingleValue = createSingleValue(children)
        return (
            <div className={[styles.comboBox, controlClassName, input.error ? 'error' : null].join(' ')} ref={this.element}>
                {ReactDOM.createPortal(
                    <div ref={this.menuPortalTarget} className={[menuClassName, 'portalTarget'].join(' ')}/>,
                    document.body
                )}
                <Select
                    {...props}
                    name={input.name}
                    value={showCurrentSelection ? this.state.selectedOption : null}
                    classNamePrefix='comboBox'
                    maxMenuHeight={this.state.maxMenuHeight}
                    menuPlacement={menuPlacement}
                    menuPortalTarget={this.menuPortalTarget.current}
                    isClearable={isClearable}
                    isLoading={!!isLoading}
                    loadingMessage={() => msg('widget.comboBox.loading')}
                    components={components}
                    onChange={(e) => {
                        input.handleChange({target: {value: e ? e.value : '', name: input.name}})
                        if (onChange)
                            onChange(e)
                        if (validate === 'onChange')
                            input.validate()
                    }}
                    onBlur={(e) => {
                        if (onBlur)
                            onBlur(e)
                        if (validate === 'onBlur')
                            input.validate()
                    }}
                />
            </div>
        )
    }

    componentDidMount() {
        this.updateSelectedOption()
        this.updateMaxMenuHeight()
    }

    componentDidUpdate(prevProps) {
        const value = this.props.input.value
        if (prevProps.input.value !== value || prevProps.options !== this.props.options)
            this.updateSelectedOption()

        const appHeight = this.props.appDimensions.height
        if (this.element.current && prevProps.appDimensions.height !== appHeight)
            this.updateMaxMenuHeight()
    }

    updateMaxMenuHeight() {
        const appHeight = this.props.appDimensions.height
        const comboBoxBox = this.element.current.getBoundingClientRect()
        const availableSpace = (
            this.props.menuPlacement === 'top'
                ? comboBoxBox.top
                : appHeight - comboBoxBox.bottom
        ) - 10

        let maxMenuHeightProp = this.props.maxMenuHeight || '20rem'
        if (maxMenuHeightProp.toString().toLowerCase().endsWith('rem'))
            maxMenuHeightProp = parseFloat(maxMenuHeightProp) * parseFloat(getComputedStyle(document.documentElement).fontSize)
{'fraction_non_alphanumeric': 0.10351613749672002, 'fraction_numerical': 0.0010495932826029913, 'mean_word_length': 1.6231933929800413, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5005487', 'n_tokens_mistral': 1917, 'n_tokens_neox': 1843, 'n_words': 354}