UNPKG

wix-style-react

Version:
117 lines 6.6 kB
import React from 'react'; import PropTypes from 'prop-types'; import { StatusAlertSmall } from '@wix/wix-ui-icons-common'; import Input from '../Input'; import LabelledElement from '../LabelledElement/LabelledElement'; import Text from '../Text'; import InputWithOptions from '../InputWithOptions'; import { st, classes } from './AutoCompleteWithLabel.st.css'; import dataHooks from './dataHooks'; import { optionValidator } from '../DropdownLayout/DropdownLayout'; class AutoCompleteWithLabel extends React.PureComponent { constructor(props) { super(props); this.onSelect = option => { const { value } = option; this.setState({ value, }); this.props.onSelect(option); this.setState({ isEditing: false }); }; this.onChange = event => { const { value } = event.target; this.setState({ value, isEditing: true }); this.props.onChange && this.props.onChange(event); }; this._isInputControlled = () => typeof this.props.value !== 'undefined'; this.state = { value: props.value || '', isEditing: false, }; } render() { const { label, dataHook, options, status, suffix, statusMessage, onFocus, name, type, ariaLabel, autoFocus, autocomplete, disabled, className, maxLength, placeholder, native, onBlur, maxHeightPixels, } = this.props; const { value } = this._isInputControlled() ? this.props : this.state; const predicate = this.state.isEditing ? option => option.value.toLowerCase().includes(value.toLowerCase()) : () => true; const filteredOptions = options.filter(predicate); const suffixContainer = suffix ? suffix.map((item, index) => { return (React.createElement("div", { className: classes.suffix, key: `${dataHook}-${index}` }, item)); }) : []; return (React.createElement("div", { "data-hook": dataHook }, React.createElement(LabelledElement, { label: label, dataHook: dataHooks.labelledElement, value: value }, ({ onFocus: inputOnFocus, onBlur: inputOnBlur, onChange: inputOnChange, className: inputClassName, getPlaceholder, ...rest }) => (React.createElement(InputWithOptions, { onChange: e => { inputOnChange(e); this.onChange(e); }, onSelect: this.onSelect, dataHook: dataHooks.inputWithOptions, hideStatusSuffix: true, onFocus: e => { inputOnFocus(e); onFocus?.(e); }, onBlur: e => { inputOnBlur(e); onBlur?.(e); }, size: "large", autocomplete: autocomplete, inputElement: React.createElement(Input, { name: name, type: type, ariaLabel: ariaLabel, autoFocus: autoFocus, disabled: disabled, maxLength: maxLength, placeholder: getPlaceholder(placeholder), dataHook: dataHooks.inputWithLabel, value: value, className: st(inputClassName, className), suffix: suffixContainer, status: status }), options: filteredOptions, native: native, maxHeightPixels: maxHeightPixels, ...rest }))), status === Input.StatusError && statusMessage && (React.createElement(Text, { skin: "error", weight: "normal", size: "small", className: classes.statusMessage }, React.createElement("span", { className: classes.statusMessageIcon }, React.createElement(StatusAlertSmall, null)), React.createElement("span", { "data-hook": dataHooks.errorMessage, className: classes.errorMessageContent }, statusMessage))))); } } AutoCompleteWithLabel.displayName = 'AutoCompleteWithLabel'; AutoCompleteWithLabel.propTypes = { /** Sets a default value for those who want to use this component un-controlled. */ dataHook: PropTypes.string, /** Defines a value label to show inside of a field. */ label: PropTypes.string.isRequired, /** Specify an array of options to display in the dropdown list. */ options: PropTypes.arrayOf(optionValidator).isRequired, /** Pass a component you want to show as the suffix of the input, e.g., text string, icon. */ suffix: PropTypes.arrayOf(PropTypes.element), /** Specify the status of a field. */ status: PropTypes.oneOf(['error']), /** Defines the message to display on status icon hover. If not given or empty there will be no tooltip. */ statusMessage: PropTypes.node, /** Defines a standard input onFocus callback. */ onFocus: PropTypes.func, /** Defines a standard input onBlur callback */ onBlur: PropTypes.func, /** Defines a standard input onChange callback. */ onChange: PropTypes.func, /** Reference element data when a form is submitted. */ name: PropTypes.string, /** Specifies the type of `<input/>` element to display. Default is text string. */ type: PropTypes.string, /** Define a string that labels the current element in case where a text label is not visible on the screen. */ ariaLabel: PropTypes.string, /** Focus the element on mount (standard React input autoFocus). */ autoFocus: PropTypes.bool, /** Sets the value of native autocomplete attribute (check the [HTML spec](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-autocomplete) for possible values */ autocomplete: PropTypes.string, /** Specifies whether input should be disabled or not. */ disabled: PropTypes.bool, /** Specifies a CSS class name to be appended to the component’s root element. */ className: PropTypes.string, /** Sets the maximum number of characters that can be entered into a field. */ maxLength: PropTypes.number, /** Sets a placeholder message to display. */ placeholder: PropTypes.string, /** Defines a callback function which is called whenever user selects a different option in the list. */ onSelect: PropTypes.func, /** Indicates whether to render using the native select element */ native: PropTypes.bool, /** Value of rendered child input */ value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), /** Sets the maximum height of the dropdownLayout in pixels. */ maxHeightPixels: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), }; AutoCompleteWithLabel.defaultProps = { ...Input.defaultProps, autocomplete: 'on', label: '', options: [], onSelect: () => { }, }; export default AutoCompleteWithLabel; //# sourceMappingURL=AutoCompleteWithLabel.js.map