fix: move debounce to text input and enhance

This commit is contained in:
Mohamed Marrouchi
2025-05-28 17:06:23 +01:00
parent 0c31d3047e
commit 0f8f0dd27f
3 changed files with 66 additions and 18 deletions

View File

@@ -1,31 +1,80 @@
/*
* Copyright © 2024 Hexastack. All rights reserved.
* Copyright © 2025 Hexastack. All rights reserved.
*
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
*/
import ClearIcon from "@mui/icons-material/Clear";
import SearchIcon from "@mui/icons-material/Search";
import { TextFieldProps } from "@mui/material";
import {
debounce,
IconButton,
InputAdornment,
TextFieldProps,
} from "@mui/material";
import { useCallback, useMemo, useState } from "react";
import { useTranslate } from "@/hooks/useTranslate";
import { Adornment } from "./Adornment";
import { Input } from "./Input";
export const FilterTextfield = (props: TextFieldProps) => {
const { t } = useTranslate();
export interface FilterTextFieldProps
extends Omit<TextFieldProps, "value" | "onChange"> {
onChange: (value: string) => void;
delay?: number;
clearable: boolean;
defaultValue?: string;
}
export const FilterTextfield = ({
onChange: onSearch,
defaultValue = "",
delay = 500,
clearable = true,
...props
}) => {
const { t } = useTranslate();
const [inputValue, setInputValue] = useState(defaultValue);
const debouncedSearch = useMemo(
() =>
debounce((value: string) => {
onSearch?.(value);
}, delay),
[onSearch, delay],
);
const handleChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
const value = event.target.value;
setInputValue(value);
debouncedSearch(value);
},
[debouncedSearch],
);
const handleClear = useCallback(() => {
setInputValue("");
debouncedSearch("");
}, [debouncedSearch]);
//TODO: replace the native delete text button by a styled custom button
return (
<Input
type="search"
InputProps={{
startAdornment: <Adornment Icon={SearchIcon} />,
endAdornment: clearable && (
<InputAdornment position="end" onClick={handleClear}>
<IconButton size="small" sx={{ marginRight: -1 }}>
<ClearIcon fontSize="small" />
</IconButton>
</InputAdornment>
),
}}
placeholder={t("placeholder.keywords")}
{...props}
value={inputValue}
onChange={handleChange}
/>
);
};