@carbon/ibm-products
Version:
Carbon for IBM Products
167 lines (165 loc) • 6.86 kB
JavaScript
/**
* Copyright IBM Corp. 2020, 2026
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
const require_runtime = require("../../_virtual/_rolldown/runtime.js");
const require_index = require("../../node_modules/classnames/index.js");
const require_settings = require("../../settings.js");
const require_devtools = require("../../global/js/utils/devtools.js");
let react = require("react");
react = require_runtime.__toESM(react);
let prop_types = require("prop-types");
prop_types = require_runtime.__toESM(prop_types);
let _carbon_react = require("@carbon/react");
//#region src/components/SearchBar/SearchBar.tsx
/**
* Copyright IBM Corp. 2024, 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
var import_classnames = /* @__PURE__ */ require_runtime.__toESM(require_index.default);
const blockClass = `${require_settings.pkg.prefix}--search-bar`;
const componentName = "SearchBar";
const defaults = {
onSubmit: () => {},
onChange: () => {},
scopes: [],
selectedScopes: [],
hideScopesLabel: true
};
const SearchBar = react.default.forwardRef(({ className, clearButtonLabelText, hideScopesLabel = defaults.hideScopesLabel, labelText, onChange = defaults.onChange, onSubmit = defaults.onSubmit, placeholderText, scopes = [], scopesTypeLabel, scopeToString, selectedScopes = [], sortItems, submitLabel, translateWithId, value, ...rest }, ref) => {
const [text, setText] = (0, react.useState)(value || "");
const [_selectedScopes, setSelectedScopes] = (0, react.useState)(selectedScopes || []);
const [isInputDirty, setIsInputDirty] = (0, react.useState)(false);
(0, 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 = ({ selectedItems }) => {
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.default.createElement("form", {
...rest,
ref,
...require_devtools.getDevtoolsProps(componentName),
className: (0, import_classnames.default)(blockClass, className, { [`${blockClass}--hide-scopes-label`]: hideScopesLabel }),
onSubmit: handleSubmit
}, scopes?.length ? /* @__PURE__ */ react.default.createElement(_carbon_react.MultiSelect, {
...multiSelectProps,
id: `${blockClass}__multi-select`,
className: `${blockClass}__scopes`,
onChange: handleSearchScopeChange,
size: "lg"
}) : null, /* @__PURE__ */ react.default.createElement(_carbon_react.Search, {
className: `${blockClass}__input`,
closeButtonLabelText: clearButtonLabelText,
labelText,
name: "search-input",
onChange: handleInputChange,
placeholder: placeholderText,
value: text,
size: "lg"
}), /* @__PURE__ */ react.default.createElement(_carbon_react.Button, {
name: "search-submit",
kind: "primary",
type: "submit",
className: `${blockClass}__submit`,
disabled: !isInputDirty
}, submitLabel));
});
SearchBar.displayName = componentName;
const conditionalScopePropValidator = (props, propName, componentName, ...rest) => {
if (props.scopes && props.scopes.length > 0 && !props[propName]) return /* @__PURE__ */ new Error(`Required \`${propName}\` when \`scopes\` prop type is supplied to \`${componentName}\`. Validation failed.`);
/**@ts-ignore */
return prop_types.default.string(props, propName, componentName, ...rest);
};
const deprecatedProps = {
/**
* **Deprecated**
*
* Provide accessible label text for the scopes MultiSelect.
*/
titleText: prop_types.default.string };
SearchBar.propTypes = {
/** @type {string} Optional additional class name. */
className: prop_types.default.string,
/** @type {string} The label text for the search text input. */
clearButtonLabelText: prop_types.default.string.isRequired,
/**
* Whether or not the scopes MultiSelect label is visually hidden.
*/
hideScopesLabel: prop_types.default.bool,
/** @type {string} The label text for the search text input. */
labelText: prop_types.default.string.isRequired,
/** @type {Function} Function handler for when the user changes their query search. */
onChange: prop_types.default.func,
/** @type {Function} Function handler for when the user submits a search. */
onSubmit: prop_types.default.func,
/** @type {string} Placeholder text to be displayed in the search input. */
placeholderText: prop_types.default.string.isRequired,
/** @type {Function} Function to get the text for each scope to display in dropdown. */
scopeToString: prop_types.default.func,
/** @type {Array<any>} Array of allowed search scopes. */
/**@ts-ignore */
scopes: prop_types.default.arrayOf(prop_types.default.oneOfType([prop_types.default.string, prop_types.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: prop_types.default.arrayOf(prop_types.default.oneOfType([prop_types.default.string, prop_types.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: prop_types.default.func,
/** @type {string} The label text for the search submit button. */
submitLabel: prop_types.default.string.isRequired,
/** @type {func} Callback function for translating MultiSelect's child ListBoxMenuIcon SVG title. */
translateWithId: prop_types.default.func,
/** @type {string} Search query value. */
value: prop_types.default.string,
...deprecatedProps
};
//#endregion
exports.SearchBar = SearchBar;