|
- "use client";
-
- import ClearIcon from "@mui/icons-material/Clear";
- import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
- import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
- import SearchIcon from "@mui/icons-material/Search";
- import {
- Box,
- IconButton,
- InputAdornment,
- Paper,
- TextField,
- Tooltip,
- Typography,
- } from "@mui/material";
- import { useTranslation } from "react-i18next";
-
- type Props = {
- query: string;
- matchCount: number;
- activeIndex: number;
- onQueryChange: (value: string) => void;
- onPrev: () => void;
- onNext: () => void;
- onClear: () => void;
- };
-
- /** FP-MTMS Version Checklist | Functions Ref. No. 15 | v1.0.0 | 2026-07-17 */
- const ItemTracingFlowGraphSearch: React.FC<Props> = ({
- query,
- matchCount,
- activeIndex,
- onQueryChange,
- onPrev,
- onNext,
- onClear,
- }) => {
- const { t } = useTranslation("itemTracing");
- const trimmed = query.trim();
- const hasQuery = trimmed.length > 0;
- const matchLabel =
- matchCount > 0
- ? t("flowGraphSearchMatch", { current: activeIndex + 1, total: matchCount })
- : hasQuery
- ? t("flowGraphSearchNoMatch")
- : "";
-
- const handleKeyDown = (event: React.KeyboardEvent) => {
- if (event.key === "Enter") {
- event.preventDefault();
- if (event.shiftKey) onPrev();
- else onNext();
- } else if (event.key === "Escape") {
- event.preventDefault();
- onClear();
- }
- };
-
- return (
- <Paper
- elevation={2}
- sx={{
- p: 1,
- minWidth: 280,
- maxWidth: 360,
- bgcolor: "background.paper",
- }}
- >
- <TextField
- size="small"
- fullWidth
- value={query}
- placeholder={t("flowGraphSearchPlaceholder")}
- onChange={(e) => onQueryChange(e.target.value)}
- onKeyDown={handleKeyDown}
- InputProps={{
- startAdornment: (
- <InputAdornment position="start" sx={{ mr: 0.5 }}>
- <SearchIcon fontSize="small" sx={{ color: "text.secondary" }} />
- </InputAdornment>
- ),
- endAdornment: hasQuery ? (
- <InputAdornment position="end">
- <Tooltip title={t("flowGraphSearchClear")}>
- <IconButton size="small" edge="end" onClick={onClear} aria-label={t("flowGraphSearchClear")}>
- <ClearIcon fontSize="small" />
- </IconButton>
- </Tooltip>
- </InputAdornment>
- ) : undefined,
- }}
- sx={{
- "& .MuiOutlinedInput-root": {
- alignItems: "center",
- },
- "& .MuiOutlinedInput-input": {
- color: "text.secondary",
- py: "8.5px",
- lineHeight: 1.4375,
- },
- "& .MuiOutlinedInput-input::placeholder": {
- color: "text.disabled",
- opacity: 1,
- },
- "& .MuiInputAdornment-root": {
- height: "100%",
- maxHeight: "none",
- alignItems: "center",
- },
- }}
- />
- {hasQuery && (
- <Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between", mt: 0.75, gap: 1 }}>
- <Typography variant="caption" color={matchCount > 0 ? "text.secondary" : "error"} noWrap>
- {matchLabel}
- </Typography>
- <Box sx={{ display: "flex", flexShrink: 0 }}>
- <Tooltip title={t("flowGraphSearchPrev")}>
- <span>
- <IconButton
- size="small"
- onClick={onPrev}
- disabled={matchCount === 0}
- aria-label={t("flowGraphSearchPrev")}
- >
- <KeyboardArrowUpIcon fontSize="small" />
- </IconButton>
- </span>
- </Tooltip>
- <Tooltip title={t("flowGraphSearchNext")}>
- <span>
- <IconButton
- size="small"
- onClick={onNext}
- disabled={matchCount === 0}
- aria-label={t("flowGraphSearchNext")}
- >
- <KeyboardArrowDownIcon fontSize="small" />
- </IconButton>
- </span>
- </Tooltip>
- </Box>
- </Box>
- )}
- </Paper>
- );
- };
-
- export default ItemTracingFlowGraphSearch;
|