import { Box, SvgIcon, TextField, styled } from "@mui/material"; import Tooltip from "@mui/material/Tooltip"; import { ChangeEvent, useEffect, useRef, useState, useMemo } from "react"; import { useTranslation } from "react-i18next"; import matchCaseIcon from "@/assets/image/component/match_case.svg?react"; import matchWholeWordIcon from "@/assets/image/component/match_whole_word.svg?react"; import useRegularExpressionIcon from "@/assets/image/component/use_regular_expression.svg?react"; export type SearchState = { text: string; matchCase: boolean; matchWholeWord: boolean; useRegularExpression: boolean; }; type SearchProps = { placeholder?: string; matchCase?: boolean; matchWholeWord?: boolean; useRegularExpression?: boolean; onSearch: (match: (content: string) => boolean, state: SearchState) => void; }; const StyledTextField = styled(TextField)(({ theme }) => ({ "& .MuiInputBase-root": { background: theme.palette.mode === "light" ? "#fff" : undefined, paddingRight: "4px", }, "& .MuiInputBase-root svg[aria-label='active'] path": { fill: theme.palette.primary.light, }, "& .MuiInputBase-root svg[aria-label='inactive'] path": { fill: "#A7A7A7", }, })); export const BaseSearchBox = (props: SearchProps) => { const { t } = useTranslation(); const inputRef = useRef(null); const [matchCase, setMatchCase] = useState(props.matchCase ?? false); const [matchWholeWord, setMatchWholeWord] = useState( props.matchWholeWord ?? false, ); const [useRegularExpression, setUseRegularExpression] = useState( props.useRegularExpression ?? false, ); const [errorMessage, setErrorMessage] = useState(""); const iconStyle = { style: { height: "24px", width: "24px", cursor: "pointer", } as React.CSSProperties, inheritViewBox: true, }; const createMatcher = useMemo(() => { return (searchText: string) => { try { return (content: string) => { if (!searchText) return true; let item = !matchCase ? content.toLowerCase() : content; let searchItem = !matchCase ? searchText.toLowerCase() : searchText; if (useRegularExpression) { return new RegExp(searchItem).test(item); } if (matchWholeWord) { return new RegExp(`\\b${searchItem}\\b`).test(item); } return item.includes(searchItem); }; } catch (err) { setErrorMessage(`${err}`); return () => true; } }; }, [matchCase, matchWholeWord, useRegularExpression]); useEffect(() => { if (!inputRef.current) return; const value = inputRef.current.value; setErrorMessage(""); props.onSearch(createMatcher(value), { text: value, matchCase, matchWholeWord, useRegularExpression, }); }, [matchCase, matchWholeWord, useRegularExpression, createMatcher]); const onChange = (e: ChangeEvent) => { const value = e.target?.value ?? ""; setErrorMessage(""); props.onSearch(createMatcher(value), { text: value, matchCase, matchWholeWord, useRegularExpression, }); }; return (
setMatchCase(!matchCase)} />
setMatchWholeWord(!matchWholeWord)} />
setUseRegularExpression(!useRegularExpression) } />{" "}
), }} />
); };