UNPKG

@talend/react-components

Version:
253 lines (252 loc) 6.9 kB
import { useEffect, useState } from 'react'; import DebounceInput from 'react-debounce-input'; import { useTranslation } from 'react-i18next'; import classNames from 'classnames'; import PropTypes from 'prop-types'; import { FormControl } from '@talend/react-bootstrap'; import { Action } from '../Actions'; import I18N_DOMAIN_COMPONENTS from '../constants'; import Icon from '../Icon'; import theme from './FilterBar.module.scss'; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; function forceBlur(event) { event.target.blur(); } function onKeyDown(event, escAction, enterAction) { switch (event.key) { case 'Enter': if (enterAction) { enterAction(event); } break; case 'Esc': case 'Escape': if (escAction) { escAction(event); } break; default: break; } } function FilterInput(props) { const { id, debounceMinLength, debounceTimeout, onBlur, onClear, onFocus, onFilter, autoFocus, placeholder, value, disabled, ...rest } = props; const { t } = useTranslation(I18N_DOMAIN_COMPONENTS); const placeholderLabel = placeholder || t('LIST_FILTER_LABEL', { defaultValue: 'Filter' }); const inputProps = { 'data-test': rest['data-test'], 'data-feature': rest['data-feature'], id, name: 'search', type: 'search', value, placeholder: placeholderLabel, autoComplete: 'off', disabled, className: classNames(theme.search), 'aria-label': placeholderLabel, onBlur: onBlur && (event => { onBlur(event, event.target.value); }), onFocus: onFocus && (event => onFocus(event, event.target.value)), onChange: event => onFilter(event, event.target.value), onKeyDown: event => onKeyDown(event, onClear, forceBlur), autoFocus, role: 'searchbox' }; if (debounceMinLength || debounceTimeout) { return /*#__PURE__*/_jsx(DebounceInput, { ...inputProps, element: FormControl, minLength: debounceMinLength, debounceTimeout: debounceTimeout }); } return /*#__PURE__*/_jsx(FormControl, { ...inputProps }); } FilterInput.propTypes = { autoFocus: PropTypes.bool, id: PropTypes.string, debounceMinLength: PropTypes.number, debounceTimeout: PropTypes.number, onBlur: PropTypes.func, onClear: PropTypes.func, onFocus: PropTypes.func, onFilter: PropTypes.func.isRequired, placeholder: PropTypes.string, value: PropTypes.string, 'data-test': PropTypes.string, 'data-feature': PropTypes.string, disabled: PropTypes.bool }; /** * @param {object} props react props * @example <FilterBar id="my-filter" docked="false" onFilter="filter()"></Filter> */ export default function FilterBar(props) { const { onFocus, onBlur, onToggle, onFilter } = props; const [focus, setFocus] = useState(); const [value, setValue] = useState(); const { t } = useTranslation(I18N_DOMAIN_COMPONENTS); useEffect(() => { // in controlled mode, if the value changes, replace the current value setValue(props.value); }, [props.value]); const onFocusCallback = event => { setFocus(true); if (onFocus) { onFocus(event); } }; const onBlurCallback = event => { setFocus(false); if (onBlur) { onBlur(event); } if (!value && onToggle) { onToggle(event); } }; const onFilterCallback = event => { setValue(event.target.value); if (onFilter) { onFilter(event, event.target.value); } }; const onClearCallback = event => { // needed to avoid blur of the input event.preventDefault(); onFilterCallback({ target: { value: '' } }); }; const onSubmit = event => { event.preventDefault(); return onFilterCallback(event); }; if (props.dockable && props.docked) { return /*#__PURE__*/_jsx(Action, { id: props.id, className: classNames(props.className, theme['button-docked']), onClick: props.onToggle, label: t('LIST_FILTER_TOGGLE', { defaultValue: 'Toggle filter' }), hideLabel: true, icon: "talend-search", "data-feature": props['data-feature'], tooltipPlacement: props.tooltipPlacement, role: "search" }); } const classes = classNames(theme.filter, props.className, { [theme.highlight]: props.highlight, [theme.navbar]: props.navbar }); return /*#__PURE__*/_jsx("form", { className: classes, role: "search", onSubmit: onSubmit, children: /*#__PURE__*/_jsxs("div", { className: classNames('form-group', { [theme.animate]: props.dockable }), children: [/*#__PURE__*/_jsx(Icon, { name: "talend-search", className: classNames(theme['search-icon'], { [theme['search-focused']]: focus }) }), /*#__PURE__*/_jsx(FilterInput, { disabled: props.disabled, "data-feature": props['data-feature'], "data-test": props['data-test'] // eslint-disable-next-line jsx-a11y/no-autofocus , autoFocus: props.autoFocus, id: props.id && `${props.id}-input`, debounceMinLength: props.debounceMinLength, debounceTimeout: props.debounceTimeout, onBlur: onBlurCallback, onClear: onClearCallback, onFocus: onFocusCallback, onFilter: onFilterCallback, onToggle: props.onToggle, placeholder: props.placeholder, value: value, dockable: props.dockable, t: t }), value ? /*#__PURE__*/_jsx(Action, { className: theme.remove, id: props.id && `${props.id}-cross-icon`, "data-test": props['data-test'] && `${props['data-test']}-reset`, "data-feature": props['data-feature'] && `${props['data-feature']}-reset`, icon: "talend-cross", label: t('LIST_FILTER_REMOVE', { defaultValue: 'Remove filter' }), hideLabel: true, tooltipPlacement: props.tooltipPlacement, onMouseDown: onClearCallback }) : null] }) }); } FilterBar.propTypes = { autoFocus: PropTypes.bool, id: PropTypes.string, className: PropTypes.string, 'data-test': PropTypes.string, 'data-feature': PropTypes.string, debounceMinLength: PropTypes.number, debounceTimeout: PropTypes.number, docked: PropTypes.bool, dockable: PropTypes.bool, navbar: PropTypes.bool, onBlur: PropTypes.func, onFocus: PropTypes.func, onFilter: PropTypes.func.isRequired, onToggle: PropTypes.func, highlight: PropTypes.bool, placeholder: PropTypes.string, value: PropTypes.string, tooltipPlacement: PropTypes.string, disabled: PropTypes.bool }; FilterBar.defaultProps = { autoFocus: true, dockable: true, docked: true, navbar: true, disabled: false, className: '' }; //# sourceMappingURL=FilterBar.component.js.map