소스 검색

added clear functionality to the Search Component

davitbejanyan 2 년 전
부모
커밋
21e245425a

+ 11 - 0
kafka-ui-react-app/src/components/common/Input/Input.styled.ts

@@ -29,6 +29,17 @@ export const Wrapper = styled.div`
     width: 16px;
     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>(

+ 21 - 15
kafka-ui-react-app/src/components/common/Input/Input.tsx

@@ -16,6 +16,7 @@ export interface InputProps
   withError?: boolean;
   label?: React.ReactNode;
   hint?: React.ReactNode;
+  children?: React.ReactNode;
 
   // Some may only accept integer, like `Number of Partitions`
   // some may accept decimal
@@ -99,19 +100,22 @@ function pasteNumberCheck(
   return value;
 }
 
-const Input: React.FC<InputProps> = ({
-  name,
-  hookFormOptions,
-  search,
-  inputSize = 'L',
-  type,
-  positiveOnly,
-  integerOnly,
-  withError = false,
-  label,
-  hint,
-  ...rest
-}) => {
+const Input = React.forwardRef<HTMLInputElement, InputProps>((props, ref) => {
+  const {
+    name,
+    hookFormOptions,
+    search,
+    inputSize = 'L',
+    type,
+    positiveOnly,
+    integerOnly,
+    withError = false,
+    label,
+    hint,
+    children,
+    ...rest
+  } = props;
+
   const methods = useFormContext();
 
   const fieldId = React.useId();
@@ -168,7 +172,6 @@ const Input: React.FC<InputProps> = ({
     // if the field is a part of react-hook-form form
     inputOptions = { ...rest, ...methods.register(name, hookFormOptions) };
   }
-
   return (
     <div>
       {label && <InputLabel htmlFor={rest.id || fieldId}>{label}</InputLabel>}
@@ -181,8 +184,11 @@ const Input: React.FC<InputProps> = ({
           type={type}
           onKeyPress={keyPressEventHandler}
           onPaste={pasteEventHandler}
+          ref={ref}
           {...inputOptions}
         />
+        {search && children}
+
         {withError && isHookFormField && (
           <S.FormError>
             <ErrorMessage name={name} />
@@ -192,6 +198,6 @@ const Input: React.FC<InputProps> = ({
       </S.Wrapper>
     </div>
   );
-};
+});
 
 export default Input;

+ 20 - 2
kafka-ui-react-app/src/components/common/Search/Search.tsx

@@ -2,6 +2,7 @@ import React from 'react';
 import { useDebouncedCallback } from 'use-debounce';
 import Input from 'components/common/Input/Input';
 import { useSearchParams } from 'react-router-dom';
+import CloseIcon from 'components/common/Icons/CloseIcon';
 
 interface SearchProps {
   placeholder?: string;
@@ -17,7 +18,11 @@ const Search: React.FC<SearchProps> = ({
   onChange,
 }) => {
   const [searchParams, setSearchParams] = useSearchParams();
+  const ref = React.createRef<HTMLInputElement>();
   const handleChange = useDebouncedCallback((e) => {
+    if (ref.current != null) {
+      ref.current.value = e.target.value;
+    }
     if (onChange) {
       onChange(e.target.value);
     } else {
@@ -28,7 +33,15 @@ const Search: React.FC<SearchProps> = ({
       setSearchParams(searchParams);
     }
   }, 500);
-
+  const clearSearchValue = () => {
+    if (searchParams.get('q')) {
+      searchParams.set('q', '');
+      setSearchParams(searchParams);
+    }
+    if (ref.current != null) {
+      ref.current.value = '';
+    }
+  };
   return (
     <Input
       type="text"
@@ -37,8 +50,13 @@ const Search: React.FC<SearchProps> = ({
       defaultValue={value || searchParams.get('q') || ''}
       inputSize="M"
       disabled={disabled}
+      ref={ref}
       search
-    />
+    >
+      <div aria-hidden role="button" onClick={clearSearchValue}>
+        <CloseIcon />
+      </div>
+    </Input>
   );
 };