@carbon/react
Version:
React components for the Carbon Design System
201 lines (195 loc) • 6.42 kB
JavaScript
/**
* Copyright IBM Corp. 2016, 2023
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
var cx = require('classnames');
var PropTypes = require('prop-types');
var React = require('react');
var Search = require('../Search/Search.js');
require('../Search/Search.Skeleton.js');
var useId = require('../../internal/useId.js');
var usePrefix = require('../../internal/usePrefix.js');
var noopFn = require('../../internal/noopFn.js');
const translationIds = {
'carbon.table.toolbar.search.label': 'carbon.table.toolbar.search.label',
'carbon.table.toolbar.search.placeholder': 'carbon.table.toolbar.search.placeholder'
};
const defaultTranslations = {
[translationIds['carbon.table.toolbar.search.label']]: 'Filter table',
[translationIds['carbon.table.toolbar.search.placeholder']]: 'Filter table'
};
const defaultTranslateWithId = messageId => {
return defaultTranslations[messageId];
};
const TableToolbarSearch = ({
className,
searchContainerClass,
onChange: onChangeProp,
onClear = noopFn.noopFn,
translateWithId: t = defaultTranslateWithId,
placeholder,
labelText,
expanded: expandedProp,
defaultExpanded,
defaultValue,
disabled,
onExpand,
persistent = false,
id,
onBlur,
onFocus,
size = 'lg',
tabIndex = '0',
...rest
}) => {
const {
current: controlled
} = React.useRef(expandedProp !== undefined);
const [expandedState, setExpandedState] = React.useState(Boolean(defaultExpanded || defaultValue));
const expanded = controlled ? expandedProp : expandedState;
const [value, setValue] = React.useState(defaultValue || '');
const uniqueId = useId.useId('table-toolbar-search');
const [focusTarget, setFocusTarget] = React.useState(null);
const prefix = usePrefix.usePrefix();
React.useEffect(() => {
if (focusTarget) {
focusTarget.current?.querySelector?.('input')?.focus();
setFocusTarget(null);
}
}, [focusTarget]);
React.useEffect(() => {
if (defaultValue) {
onChangeProp?.('', defaultValue);
}
},
//eslint-disable-next-line react-hooks/exhaustive-deps
[]);
const searchClasses = cx(className, {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
[searchContainerClass]: searchContainerClass,
[`${prefix}--toolbar-search-container-active`]: expanded,
[`${prefix}--toolbar-search-container-disabled`]: disabled,
[`${prefix}--toolbar-search-container-expandable`]: !persistent,
[`${prefix}--toolbar-search-container-persistent`]: persistent
});
const handleExpand = (event, value = !expanded) => {
if (!disabled) {
if (!controlled && !persistent) {
setExpandedState(value);
}
if (onExpand) {
onExpand(event, value);
}
}
};
const onChange = e => {
setValue(e.target.value);
if (onChangeProp) {
onChangeProp(e, e.target.value);
}
};
const handleOnFocus = event => handleExpand(event, true);
const handleOnBlur = event => !value && handleExpand(event, false);
return /*#__PURE__*/React.createElement(Search.default, _rollupPluginBabelHelpers.extends({
disabled: disabled,
className: searchClasses,
value: value,
id: typeof id !== 'undefined' ? id : uniqueId,
labelText: labelText || t('carbon.table.toolbar.search.label'),
placeholder: placeholder || t('carbon.table.toolbar.search.placeholder'),
onChange: onChange,
onClear: onClear,
onFocus: onFocus ? event => onFocus(event, handleExpand) : handleOnFocus,
onBlur: onBlur ? event => onBlur(event, handleExpand) : handleOnBlur,
size: size
// HTMLAttributes defines tabIndex as number | undefined but in reality it
// also accepts a string, so we cast here to convince Typescript this is okay.
,
tabIndex: tabIndex
}, rest));
};
TableToolbarSearch.propTypes = {
children: PropTypes.node,
/**
* Provide an optional class name for the search container
*/
className: PropTypes.string,
/**
* Specifies if the search should initially render in an expanded state
*/
defaultExpanded: PropTypes.bool,
/**
* Provide an optional default value for the Search component
*/
defaultValue: PropTypes.string,
/**
* Specifies if the search should be disabled
*/
disabled: PropTypes.bool,
/**
* Specifies if the search should expand
*/
expanded: PropTypes.bool,
/**
* Provide an optional id for the search container
*/
id: PropTypes.string,
/**
* Provide an optional label text for the Search component icon
*/
labelText: PropTypes.string,
/**
* Provide an optional function to be called when the search input loses focus, this will be
* passed the event as the first parameter and a function to handle the expanding of the search
* input as the second
*/
onBlur: PropTypes.func,
/**
* Provide an optional hook that is called each time the input is updated
*/
onChange: PropTypes.func,
/**
* Optional callback called when the search value is cleared.
*/
onClear: PropTypes.func,
/**
* Provide an optional hook that is called each time the input is expanded
*/
onExpand: PropTypes.func,
/**
* Provide an optional function to be called when the search input gains focus, this will be
* passed the event as the first parameter and a function to handle the expanding of the search
* input as the second.
*/
onFocus: PropTypes.func,
/**
* Whether the search should be allowed to expand
*/
persistent: PropTypes.bool,
/**
* Provide an optional placeholder text for the Search component
*/
placeholder: PropTypes.string,
/**
* Provide an optional className for the overall container of the Search
*/
searchContainerClass: PropTypes.string,
/**
* Specify the size of the Search
*/
size: PropTypes.oneOf(['sm', 'md', 'lg']),
/**
* Optional prop to specify the tabIndex of the <Search> (in expanded state) or the container (in collapsed state)
*/
tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
/**
* Translates component strings using your i18n tool.
*/
translateWithId: PropTypes.func
};
exports.default = TableToolbarSearch;