fix: search input clearable component (#3465)

This commit is contained in:
Faisal Amir 2024-08-27 13:08:28 +07:00 committed by GitHub
parent 52aa87a7ac
commit 000110359e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 37 additions and 1 deletions

View File

@ -2,17 +2,30 @@ import React, { ReactNode, forwardRef } from 'react'
import { twMerge } from 'tailwind-merge' import { twMerge } from 'tailwind-merge'
import './styles.scss' import './styles.scss'
import { Cross2Icon } from '@radix-ui/react-icons'
export interface Props extends React.InputHTMLAttributes<HTMLInputElement> { export interface Props extends React.InputHTMLAttributes<HTMLInputElement> {
textAlign?: 'left' | 'right' textAlign?: 'left' | 'right'
prefixIcon?: ReactNode prefixIcon?: ReactNode
suffixIcon?: ReactNode suffixIcon?: ReactNode
onCLick?: () => void onCLick?: () => void
clearable?: boolean
onClear?: () => void
} }
const Input = forwardRef<HTMLInputElement, Props>( const Input = forwardRef<HTMLInputElement, Props>(
( (
{ className, type, textAlign, prefixIcon, suffixIcon, onClick, ...props }, {
className,
type,
textAlign,
prefixIcon,
suffixIcon,
onClick,
onClear,
clearable,
...props
},
ref ref
) => { ) => {
return ( return (
@ -27,6 +40,11 @@ const Input = forwardRef<HTMLInputElement, Props>(
{suffixIcon} {suffixIcon}
</div> </div>
)} )}
{clearable && (
<div className="input__clear-icon" onClick={onClear}>
<Cross2Icon className="text-red-200" />
</div>
)}
<input <input
type={type} type={type}
className={twMerge( className={twMerge(

View File

@ -40,4 +40,11 @@
padding-right: 32px; padding-right: 32px;
} }
} }
&__clear-icon {
@apply absolute right-3 top-1/2 -translate-y-1/2 cursor-pointer;
color: hsla(var(--input-icon));
+ .input {
padding: 0 32px;
}
}
} }

View File

@ -64,6 +64,11 @@ const ModelSearch = ({ onSearchLocal }: Props) => {
[debounced] [debounced]
) )
const onClear = useCallback(() => {
setSearchText('')
debounced()
}, [debounced])
const onKeyDown = useCallback( const onKeyDown = useCallback(
(e: React.KeyboardEvent<HTMLInputElement>) => { (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) { if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) {
@ -80,6 +85,9 @@ const ModelSearch = ({ onSearchLocal }: Props) => {
placeholder="Search or paste Hugging Face URL" placeholder="Search or paste Hugging Face URL"
onChange={onSearchChanged} onChange={onSearchChanged}
onKeyDown={onKeyDown} onKeyDown={onKeyDown}
value={searchText}
clearable={searchText.length > 0}
onClear={onClear}
/> />
) )
} }

View File

@ -138,7 +138,10 @@ const ExtensionCatalog = () => {
<Input <Input
prefixIcon={<SearchIcon size={16} />} prefixIcon={<SearchIcon size={16} />}
placeholder="Search" placeholder="Search"
value={searchText}
onChange={(e) => setSearchText(e.target.value)} onChange={(e) => setSearchText(e.target.value)}
clearable={searchText.length > 0}
onClear={() => setSearchText('')}
/> />
</div> </div>
<div> <div>