@talend/react-components
Version:
Set of react components.
253 lines (252 loc) • 6.9 kB
JavaScript
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