fix: search input clearable component (#3465)
This commit is contained in:
parent
52aa87a7ac
commit
000110359e
@ -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(
|
||||||
|
|||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user