UNPKG

@carbon/ibm-products

Version:

Carbon for IBM Products

217 lines (205 loc) 7.57 kB
/** * Copyright IBM Corp. 2020, 2025 * * 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'; var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js'); var react = require('@carbon/react'); var React = require('react'); var index = require('../../_virtual/index.js'); var cx = require('classnames'); var devtools = require('../../global/js/utils/devtools.js'); var settings = require('../../settings.js'); // The block part of our conventional BEM class names (blockClass__E--M). const blockClass = `${settings.pkg.prefix}--search-bar`; const componentName = 'SearchBar'; // NOTE: the component SCSS is not imported here: it is rolled up separately. // Default values for props const defaults = { onSubmit: () => {}, onChange: () => {}, hideScopesLabel: true }; exports.SearchBar = /*#__PURE__*/React.forwardRef((_ref, ref) => { let { // The component props, in alphabetical order (for consistency). className, clearButtonLabelText, hideScopesLabel = defaults.hideScopesLabel, labelText, onChange = defaults.onChange, onSubmit = defaults.onSubmit, placeholderText, scopes = [], scopesTypeLabel, scopeToString, selectedScopes = [], sortItems, submitLabel, translateWithId, value, // Collect any other property values passed in. ...rest } = _ref; const [text, setText] = React.useState(value || ''); const [_selectedScopes, setSelectedScopes] = React.useState(selectedScopes || []); const [isInputDirty, setIsInputDirty] = React.useState(false); React.useEffect(() => { if (!text || !text.length) { setIsInputDirty(false); } else { setIsInputDirty(true); } }, [text]); /** * Handler for form submit that calls onSubmit prop. * @param {Event} event Submit event generated. */ const handleSubmit = event => { event.preventDefault(); const eventObject = { value: text }; if (scopes.length > 0) { eventObject.selectedScopes = _selectedScopes; } onSubmit(eventObject); }; /** * Handler for when scope selection changes that calls onChangeProp. * @param {{selectedItems: Array<any>}} {selectedItems} Object containing array of selected items. */ const handleSearchScopeChange = _ref2 => { let { selectedItems } = _ref2; setSelectedScopes(selectedItems); onChange({ selectedScopes: selectedItems, value: text }); }; /** * Handler for search input changes that calls onChange prop. * @param {KeyboardEvent} event Event object from input change. */ const handleInputChange = event => { const { value } = event.target; const eventObject = { value }; if (scopes.length > 0) { eventObject.selectedScopes = selectedScopes; } setText(value); onChange(eventObject); }; const multiSelectProps = { initialSelectedItems: selectedScopes, items: scopes, itemToString: scopeToString, label: scopesTypeLabel, sortItems, translateWithId }; return /*#__PURE__*/React.createElement("form", _rollupPluginBabelHelpers.extends({}, rest, { ref: ref }, devtools.getDevtoolsProps(componentName), { className: cx(blockClass, className, { [`${blockClass}--hide-scopes-label`]: hideScopesLabel }), onSubmit: handleSubmit }), scopes?.length ? /*#__PURE__*/React.createElement(react.MultiSelect, _rollupPluginBabelHelpers.extends({}, multiSelectProps, { id: `${blockClass}__multi-select`, className: `${blockClass}__scopes`, onChange: handleSearchScopeChange, size: "lg" })) : null, /*#__PURE__*/React.createElement(react.Search, { className: `${blockClass}__input`, closeButtonLabelText: clearButtonLabelText, labelText: labelText, name: 'search-input', onChange: handleInputChange, placeholder: placeholderText, value: text, size: "lg" }), /*#__PURE__*/React.createElement(react.Button, { name: "search-submit", kind: "primary", type: "submit", className: `${blockClass}__submit`, disabled: !isInputDirty }, submitLabel)); }); // Return a placeholder if not released and not enabled by feature flag exports.SearchBar = settings.pkg.checkComponentEnabled(exports.SearchBar, componentName); // The display name of the component, used by React. Note that displayName // is used in preference to relying on function.name. exports.SearchBar.displayName = componentName; const conditionalScopePropValidator = function (props, propName, componentName) { if (props.scopes && props.scopes.length > 0 && !props[propName]) { return new Error(`Required \`${propName}\` when \`scopes\` prop type is supplied to \`${componentName}\`. Validation failed.`); } /**@ts-ignore */ for (var _len = arguments.length, rest = new Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) { rest[_key - 3] = arguments[_key]; } return index.default.string(props, propName, componentName, ...rest); }; const deprecatedProps = { /** * **Deprecated** * * Provide accessible label text for the scopes MultiSelect. */ titleText: index.default.string }; // The types and DocGen commentary for the component props, // in alphabetical order (for consistency). // See https://www.npmjs.com/package/prop-types#usage. exports.SearchBar.propTypes = { /** @type {string} Optional additional class name. */ className: index.default.string, /** @type {string} The label text for the search text input. */ clearButtonLabelText: index.default.string.isRequired, /** * Whether or not the scopes MultiSelect label is visually hidden. */ hideScopesLabel: index.default.bool, /** @type {string} The label text for the search text input. */ labelText: index.default.string.isRequired, /** @type {Function} Function handler for when the user changes their query search. */ onChange: index.default.func, /** @type {Function} Function handler for when the user submits a search. */ onSubmit: index.default.func, /** @type {string} Placeholder text to be displayed in the search input. */ placeholderText: index.default.string.isRequired, /** @type {Function} Function to get the text for each scope to display in dropdown. */ scopeToString: index.default.func, /** @type {Array<any>} Array of allowed search scopes. */ /**@ts-ignore */ scopes: index.default.arrayOf(index.default.oneOfType([index.default.string, index.default.object])), /** @type {string} The name text for the search scope type. */ scopesTypeLabel: conditionalScopePropValidator, /** @type {Array<any> Array of initially selected search scopes. */ /**@ts-ignore */ selectedScopes: index.default.arrayOf(index.default.oneOfType([index.default.string, index.default.object])), /** * Optional custom sorting algorithm for an array of scope items. * By default, scope items are sorted in ascending alphabetical order, * with "selected" items moved to the start of the scope items array. */ sortItems: index.default.func, /** @type {string} The label text for the search submit button. */ submitLabel: index.default.string.isRequired, /** @type {func} Callback function for translating MultiSelect's child ListBoxMenuIcon SVG title. */ translateWithId: index.default.func, /** @type {string} Search query value. */ value: index.default.string, ...deprecatedProps }; exports.deprecatedProps = deprecatedProps;