import { Box, SvgIcon, TextField, styled } from "@mui/material"; import Tooltip from "@mui/material/Tooltip"; import { ChangeEvent, useEffect, useRef, useState } 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"; type SearchProps = { placeholder?: string; matchCase?: boolean; matchWholeWord?: boolean; useRegularExpression?: boolean; onSearch: ( match: (content: string) => boolean, state: { text: string; matchCase: boolean; matchWholeWord: boolean; useRegularExpression: boolean; } ) => void; }; export const BaseSearchBox = styled((props: SearchProps) => { const { t } = useTranslation(); const inputRef = useRef(null); const [matchCase, setMatchCase] = useState(props.matchCase ?? true); 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, }; useEffect(() => { if (!inputRef.current) return; onChange({ target: inputRef.current, } as ChangeEvent); }, [matchCase, matchWholeWord, useRegularExpression]); const onChange = (e: ChangeEvent) => { props.onSearch( (content) => doSearch([content], e.target?.value ?? "").length > 0, { text: e.target?.value ?? "", matchCase, matchWholeWord, useRegularExpression, } ); }; const doSearch = (searchList: string[], searchItem: string) => { setErrorMessage(""); return searchList.filter((item) => { try { let searchItemCopy = searchItem; if (!matchCase) { item = item.toLowerCase(); searchItemCopy = searchItemCopy.toLowerCase(); } if (matchWholeWord) { const regex = new RegExp(`\\b${searchItemCopy}\\b`); if (useRegularExpression) { const regexWithOptions = new RegExp(searchItemCopy); return regexWithOptions.test(item) && regex.test(item); } else { return regex.test(item); } } else if (useRegularExpression) { const regex = new RegExp(searchItemCopy); return regex.test(item); } else { return item.includes(searchItemCopy); } } catch (err) { setErrorMessage(`${err}`); } }); }; return (
{ setMatchCase(!matchCase); }} />
{ setMatchWholeWord(!matchWholeWord); }} />
{ setUseRegularExpression(!useRegularExpression); }} />{" "}
), }} {...props} />
); })(({ theme }) => ({ "& .MuiInputBase-root": { background: theme.palette.mode === "light" ? "#fff" : undefined, "padding-right": "4px", }, "& .MuiInputBase-root svg[aria-label='active'] path": { fill: theme.palette.primary.light, }, "& .MuiInputBase-root svg[aria-label='inactive'] path": { fill: "#A7A7A7", }, }));