@carbon/react
Version:
React components for the Carbon Design System
68 lines (66 loc) • 2.65 kB
JavaScript
/**
* Copyright IBM Corp. 2016, 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.
*/
import { usePrefix } from "../../internal/usePrefix.js";
import { Escape } from "../../internal/keyboard/keys.js";
import { match } from "../../internal/keyboard/match.js";
import { composeEventHandlers } from "../../tools/events.js";
import { mergeRefs } from "../../tools/mergeRefs.js";
import { isSearchValuePresent } from "../Search/utils.js";
import Search_default from "../Search/index.js";
import classNames from "classnames";
import { forwardRef, useEffect, useRef, useState } from "react";
import { jsx } from "react/jsx-runtime";
//#region src/components/ExpandableSearch/ExpandableSearch.tsx
/**
* Copyright IBM Corp. 2021, 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 ExpandableSearch = forwardRef((props, forwardedRef) => {
const { onBlur, onChange, onExpand, onKeyDown, defaultValue, isExpanded, ...rest } = props;
const [expanded, setExpanded] = useState(isExpanded || false);
const [hasContent, setHasContent] = useState(isSearchValuePresent(defaultValue));
const searchRef = useRef(null);
const prefix = usePrefix();
function handleBlur(evt) {
const relatedTargetIsAllowed = evt.relatedTarget && evt.relatedTarget.classList.contains(`${prefix}--search-close`);
if (expanded && !relatedTargetIsAllowed && !hasContent && !isExpanded) setExpanded(false);
}
useEffect(() => {
setExpanded(!!isExpanded);
}, [isExpanded]);
function handleChange(evt) {
setHasContent(evt.target.value !== "");
}
function handleExpand() {
setExpanded(true);
searchRef.current?.focus?.();
}
function handleKeyDown(evt) {
if (expanded && match(evt, Escape)) {
evt.stopPropagation();
if (!evt.target?.value && !isExpanded) setExpanded(false);
}
}
const classes = classNames(`${prefix}--search--expandable`, { [`${prefix}--search--expanded`]: expanded }, rest.className);
return /* @__PURE__ */ jsx(Search_default, {
...rest,
defaultValue,
isExpanded: expanded,
ref: mergeRefs(searchRef, forwardedRef),
className: classes,
onBlur: composeEventHandlers([onBlur, handleBlur]),
onChange: composeEventHandlers([onChange, handleChange]),
onExpand: composeEventHandlers([onExpand, handleExpand]),
onKeyDown: composeEventHandlers([onKeyDown, handleKeyDown])
});
});
ExpandableSearch.propTypes = Search_default.propTypes;
ExpandableSearch.displayName = "ExpandableSearch";
//#endregion
export { ExpandableSearch as default };