added clear functionality to the Search Component
This commit is contained in:
parent
a3daa45ccb
commit
21e245425a
3 changed files with 52 additions and 17 deletions
|
@ -29,6 +29,17 @@ export const Wrapper = styled.div`
|
||||||
width: 16px;
|
width: 16px;
|
||||||
fill: ${({ theme }) => theme.input.icon.color};
|
fill: ${({ theme }) => theme.input.icon.color};
|
||||||
}
|
}
|
||||||
|
svg:last-child {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
line-height: 0;
|
||||||
|
z-index: 1;
|
||||||
|
left: unset;
|
||||||
|
right: 12px;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const Input = styled.input<InputProps>(
|
export const Input = styled.input<InputProps>(
|
||||||
|
|
|
@ -16,6 +16,7 @@ export interface InputProps
|
||||||
withError?: boolean;
|
withError?: boolean;
|
||||||
label?: React.ReactNode;
|
label?: React.ReactNode;
|
||||||
hint?: React.ReactNode;
|
hint?: React.ReactNode;
|
||||||
|
children?: React.ReactNode;
|
||||||
|
|
||||||
// Some may only accept integer, like `Number of Partitions`
|
// Some may only accept integer, like `Number of Partitions`
|
||||||
// some may accept decimal
|
// some may accept decimal
|
||||||
|
@ -99,7 +100,8 @@ function pasteNumberCheck(
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Input: React.FC<InputProps> = ({
|
const Input = React.forwardRef<HTMLInputElement, InputProps>((props, ref) => {
|
||||||
|
const {
|
||||||
name,
|
name,
|
||||||
hookFormOptions,
|
hookFormOptions,
|
||||||
search,
|
search,
|
||||||
|
@ -110,8 +112,10 @@ const Input: React.FC<InputProps> = ({
|
||||||
withError = false,
|
withError = false,
|
||||||
label,
|
label,
|
||||||
hint,
|
hint,
|
||||||
|
children,
|
||||||
...rest
|
...rest
|
||||||
}) => {
|
} = props;
|
||||||
|
|
||||||
const methods = useFormContext();
|
const methods = useFormContext();
|
||||||
|
|
||||||
const fieldId = React.useId();
|
const fieldId = React.useId();
|
||||||
|
@ -168,7 +172,6 @@ const Input: React.FC<InputProps> = ({
|
||||||
// if the field is a part of react-hook-form form
|
// if the field is a part of react-hook-form form
|
||||||
inputOptions = { ...rest, ...methods.register(name, hookFormOptions) };
|
inputOptions = { ...rest, ...methods.register(name, hookFormOptions) };
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{label && <InputLabel htmlFor={rest.id || fieldId}>{label}</InputLabel>}
|
{label && <InputLabel htmlFor={rest.id || fieldId}>{label}</InputLabel>}
|
||||||
|
@ -181,8 +184,11 @@ const Input: React.FC<InputProps> = ({
|
||||||
type={type}
|
type={type}
|
||||||
onKeyPress={keyPressEventHandler}
|
onKeyPress={keyPressEventHandler}
|
||||||
onPaste={pasteEventHandler}
|
onPaste={pasteEventHandler}
|
||||||
|
ref={ref}
|
||||||
{...inputOptions}
|
{...inputOptions}
|
||||||
/>
|
/>
|
||||||
|
{search && children}
|
||||||
|
|
||||||
{withError && isHookFormField && (
|
{withError && isHookFormField && (
|
||||||
<S.FormError>
|
<S.FormError>
|
||||||
<ErrorMessage name={name} />
|
<ErrorMessage name={name} />
|
||||||
|
@ -192,6 +198,6 @@ const Input: React.FC<InputProps> = ({
|
||||||
</S.Wrapper>
|
</S.Wrapper>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
export default Input;
|
export default Input;
|
||||||
|
|
|
@ -2,6 +2,7 @@ import React from 'react';
|
||||||
import { useDebouncedCallback } from 'use-debounce';
|
import { useDebouncedCallback } from 'use-debounce';
|
||||||
import Input from 'components/common/Input/Input';
|
import Input from 'components/common/Input/Input';
|
||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
|
import CloseIcon from 'components/common/Icons/CloseIcon';
|
||||||
|
|
||||||
interface SearchProps {
|
interface SearchProps {
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
|
@ -17,7 +18,11 @@ const Search: React.FC<SearchProps> = ({
|
||||||
onChange,
|
onChange,
|
||||||
}) => {
|
}) => {
|
||||||
const [searchParams, setSearchParams] = useSearchParams();
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
|
const ref = React.createRef<HTMLInputElement>();
|
||||||
const handleChange = useDebouncedCallback((e) => {
|
const handleChange = useDebouncedCallback((e) => {
|
||||||
|
if (ref.current != null) {
|
||||||
|
ref.current.value = e.target.value;
|
||||||
|
}
|
||||||
if (onChange) {
|
if (onChange) {
|
||||||
onChange(e.target.value);
|
onChange(e.target.value);
|
||||||
} else {
|
} else {
|
||||||
|
@ -28,7 +33,15 @@ const Search: React.FC<SearchProps> = ({
|
||||||
setSearchParams(searchParams);
|
setSearchParams(searchParams);
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
|
const clearSearchValue = () => {
|
||||||
|
if (searchParams.get('q')) {
|
||||||
|
searchParams.set('q', '');
|
||||||
|
setSearchParams(searchParams);
|
||||||
|
}
|
||||||
|
if (ref.current != null) {
|
||||||
|
ref.current.value = '';
|
||||||
|
}
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -37,8 +50,13 @@ const Search: React.FC<SearchProps> = ({
|
||||||
defaultValue={value || searchParams.get('q') || ''}
|
defaultValue={value || searchParams.get('q') || ''}
|
||||||
inputSize="M"
|
inputSize="M"
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
ref={ref}
|
||||||
search
|
search
|
||||||
/>
|
>
|
||||||
|
<div aria-hidden role="button" onClick={clearSearchValue}>
|
||||||
|
<CloseIcon />
|
||||||
|
</div>
|
||||||
|
</Input>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue