UNPKG

lucid-ui

Version:

A UI component library from Xandr.

155 lines 5.84 kB
/* eslint-disable react/prop-types */ import _ from 'lodash'; import React, { createElement } from 'react'; import PropTypes from 'prop-types'; import { lucidClassNames } from '../../util/style-helpers'; import { getFirst } from '../../util/component-types'; import { buildModernHybridComponent } from '../../util/state-management'; import TextField from '../TextField/TextField'; import SearchIcon from '../Icon/SearchIcon/SearchIcon'; import reducers from './SearchField.reducers'; const cx = lucidClassNames.bind('&-SearchField'); const { bool, func, node, number, oneOfType, string } = PropTypes; const SearchFieldIcon = (_props) => null; SearchFieldIcon.peek = { description: `Icon this is displayed on the right side of the SearchField. Any of the lucid \`*Icon\` components should work.`, }; SearchFieldIcon.displayName = 'SearchField.Icon'; SearchFieldIcon.propName = 'Icon'; const SearchFieldTextField = (_props) => null; SearchFieldTextField.peek = { description: `Icon this is displayed on the right side of the SearchField. Any of the lucid \`*Icon\` components should work.`, }; SearchFieldTextField.displayName = 'SearchField.TextField'; SearchFieldTextField.propName = 'TextField'; /** TODO: Remove the nonPassThroughs when the component is converted to a functional component */ const nonPassThroughs = [ 'onChange', 'onChangeDebounced', 'debounceLevel', 'onSubmit', 'value', 'isValid', 'isDisabled', 'placeholder', 'className', 'Icon', 'TextField', 'initialState', 'callbackId', ]; class SearchField extends React.Component { constructor() { super(...arguments); this.textFieldElement = React.createRef(); this.focus = (options) => { this.textFieldElement.current && this.textFieldElement.current.focus(options); }; } render() { const { props, props: { className, isDisabled, isValid, onChange, onChangeDebounced, debounceLevel, onSubmit, placeholder, value, autoComplete, ...passThroughs }, } = this; const { Icon } = SearchField; const textFieldProps = _.get(getFirst(props, SearchField.TextField), 'props') || { isDisabled, onChange, onChangeDebounced, debounceLevel, onSubmit, placeholder, isMultiLine: false, value, autoComplete, }; const textFieldElement = (React.createElement(TextField, { ref: this.textFieldElement, ...textFieldProps })); const isIconActive = _.isUndefined(isValid) ? !_.isEmpty(_.get(textFieldElement, 'props.value')) : isValid; const defaultIcon = (React.createElement(SearchIcon, { size: 12, className: cx('&-Icon', { '&-Icon-active': isIconActive }) })); const iconElement = getFirst(props, Icon); const iconChildren = _.get(iconElement, 'props.children'); const icon = iconChildren ? createElement(iconChildren.type, { ...iconChildren.props, className: cx('&-Icon', { '&-Icon-active': isIconActive }, iconChildren.props.className), }) : defaultIcon; return (React.createElement("div", { ..._.omit(passThroughs, nonPassThroughs), className: cx('&', className) }, textFieldElement, React.createElement("div", { className: cx('&-Icon-container', { '&-Icon-is-disabled': isDisabled, }) }, icon))); } } SearchField.displayName = 'SearchField'; SearchField.TextField = SearchFieldTextField; SearchField.Icon = SearchFieldIcon; SearchField.peek = { description: `A wrapper around \`TextField\` that styles it for a search use-case. The icon and TextField are customizable through child components.`, categories: ['controls', 'text'], madeFrom: ['TextField', 'SearchIcon'], }; SearchField.reducers = reducers; SearchField.propTypes = { /** Fires an event every time the user types text into the TextField. Signature: \`(value, { event, props }) => {}\` */ onChange: func, /** Fires an event, debounced by \`debounceLevel\`, when the user types text into the TextField. Signature: \`(value, { event, props }) => {}\` */ onChangeDebounced: func, /** Number of milliseconds to debounce the \`onChangeDebounced\` callback. Only useful if you provide an \`onChangeDebounced\` handler. */ debounceLevel: number, /** Fires an event when the user hits "enter" from the SearchField. Signature: \`(value, { event, props }) => {}\` */ onSubmit: func, /** Set the value of the input. */ value: oneOfType([number, string]), /** Controls the highlighting of the search icon. Should be passed \`true\` when the search text is valid, e.g. contains enough characters to perform a search. */ isValid: bool, /** Disables the SearchField by greying it out. */ isDisabled: bool, /** placeholder value */ placeholder: string, /** Appended to the component-specific class names set on the root element. */ className: string, Icon: node /** Icon this is displayed on the right side of the SearchField. Any of the lucid \`*Icon\` components should work. */, /** The TextField that Searchfield is composed of. */ TextField: node, }; SearchField.defaultProps = { isDisabled: false, onChange: _.noop, onChangeDebounced: _.noop, debounceLevel: 500, onSubmit: _.noop, value: '', }; export default buildModernHybridComponent(SearchField, { reducers }); export { SearchField as SearchFieldDumb }; //# sourceMappingURL=SearchField.js.map