Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | 26x 55x 55x 55x 55x 55x 55x 55x 44x 1x 1x 11x | import { Box } from "@mui/material";
import { MagnifyingGlassIcon } from "@phosphor-icons/react";
import { useRef, useState } from "react";
import GiveIconButton from "shared/IconButton/GiveIconButton";
import { useCustomThemeV2 } from "@theme/hooks/useCustomThemeV2";
import { useAppTheme } from "@theme/v2/Provider";
import GiveSearchBar from "./GiveSearchBar";
type Props = {
value: string;
onChange?: (value: string) => void;
/** Width of the expanded search field, in px. Defaults to 240. */
width?: number;
};
/**
* Search control that starts collapsed as a magnifying-glass icon and expands
* into a full search field when clicked. When the field is left empty and
* blurred it collapses back to the icon; a non-empty value keeps it expanded.
*
* Extracted from the compact-on-scroll table headers (ManageMoney, Products,
* Developer API, Merchant/Provider action handlers), where this markup was
* duplicated verbatim.
*
* TRA013: below the wide breakpoint (< 1024px — phones and tablet portrait) there
* is room for a real search field and the scroll-header mockup shows one, so it
* renders already-expanded and full-width (never collapsing back to an icon)
* instead of the tap-to-expand icon used on the wider (desktop) inline compact bar.
*/
const GiveExpandingSearch = ({ value, onChange, width = 240 }: Props) => {
const { isWideView } = useCustomThemeV2();
const { palette } = useAppTheme();
const [expanded, setExpanded] = useState(false);
const inputRef = useRef<HTMLInputElement | null>(null);
// Below the wide breakpoint the field is always shown (full-width); only the
// desktop compact bar keeps the tap-to-expand icon.
const isCompact = !isWideView;
const showField = expanded || isCompact;
if (!showField) {
return (
<GiveIconButton
Icon={MagnifyingGlassIcon}
variant="ghost"
onClick={() => {
setExpanded(true);
requestAnimationFrame(() => inputRef.current?.focus());
}}
// TRA013: the collapsed search control keeps a visible outline in its
// rest state (per the mockups), so it reads as a tappable search field
// rather than a bare icon. `ghost` supplies the hover/active fills; the
// border is layered on here via the design-system border token.
sx={{ border: `1px solid ${palette.border?.primary}` }}
/>
);
}
return (
<Box
sx={{
width: isCompact ? "100%" : width,
flex: isCompact ? 1 : undefined,
minWidth: 0,
}}
>
<GiveSearchBar
value={value}
handleChange={onChange}
searchOnEnter
resetOnClose={false}
inputRef={inputRef}
alwaysShowClear={!isCompact}
onInputBlur={() => {
if (!value && !isCompact) setExpanded(false);
}}
/>
</Box>
);
};
export default GiveExpandingSearch;
|