feat: replace SearchBox with Input component in SearchBoxWrapper for improved search functionality

This commit is contained in:
yessenia
2026-02-06 01:53:37 +08:00
parent 9a698eaad9
commit f96fbbe03a
4 changed files with 25 additions and 21 deletions

View File

@ -1,6 +1,6 @@
import { render, screen } from '@testing-library/react' import { render, screen } from '@testing-library/react'
import { beforeEach, describe, expect, it, vi } from 'vitest' import { beforeEach, describe, expect, it, vi } from 'vitest'
import Description from './index' import { Description } from './index'
// ================================ // ================================
// Mock external dependencies // Mock external dependencies

View File

@ -5,6 +5,7 @@ import { useTranslation } from '#i18n'
import { useDebounce } from 'ahooks' import { useDebounce } from 'ahooks'
import { useSetAtom } from 'jotai' import { useSetAtom } from 'jotai'
import { useMemo, useState } from 'react' import { useMemo, useState } from 'react'
import Input from '@/app/components/base/input'
import { import {
PortalToFollowElem, PortalToFollowElem,
PortalToFollowElemContent, PortalToFollowElemContent,
@ -21,7 +22,6 @@ import {
import { PLUGIN_TYPE_SEARCH_MAP } from '../constants' import { PLUGIN_TYPE_SEARCH_MAP } from '../constants'
import { useMarketplacePlugins } from '../query' import { useMarketplacePlugins } from '../query'
import { getMarketplaceListFilterType } from '../utils' import { getMarketplaceListFilterType } from '../utils'
import SearchBox from './index'
import SearchDropdown from './search-dropdown' import SearchDropdown from './search-dropdown'
type SearchBoxWrapperProps = { type SearchBoxWrapperProps = {
@ -34,7 +34,7 @@ const SearchBoxWrapper = ({
}: SearchBoxWrapperProps) => { }: SearchBoxWrapperProps) => {
const { t } = useTranslation() const { t } = useTranslation()
const [searchPluginText, handleSearchPluginTextChange] = useSearchPluginText() const [searchPluginText, handleSearchPluginTextChange] = useSearchPluginText()
const [filterPluginTags, handleFilterPluginTagsChange] = useFilterPluginTags() const [filterPluginTags] = useFilterPluginTags()
const [activePluginType] = useActivePluginType() const [activePluginType] = useActivePluginType()
const sort = useMarketplaceSortValue() const sort = useMarketplaceSortValue()
const setSearchMode = useSetAtom(searchModeAtom) const setSearchMode = useSetAtom(searchModeAtom)
@ -84,24 +84,27 @@ const SearchBoxWrapper = ({
> >
<PortalToFollowElemTrigger asChild> <PortalToFollowElemTrigger asChild>
<div> <div>
<SearchBox <Input
wrapperClassName={cn('z-[11] mx-auto w-[640px] shrink-0', wrapperClassName)} wrapperClassName={cn('w-[200px] rounded-lg lg:w-[300px]', wrapperClassName)}
inputClassName={cn('w-full', inputClassName)} className={cn('h-9 bg-components-input-bg-normal', inputClassName)}
search={inputValue} showLeftIcon
onSearchChange={setDraftSearch} value={inputValue}
onSearchSubmit={handleSubmit} placeholder={t('searchPlugins', { ns: 'plugin' })}
onSearchFocus={() => { onChange={(e) => {
setDraftSearch(e.target.value)
}}
onFocus={() => {
setDraftSearch(committedSearch) setDraftSearch(committedSearch)
setIsFocused(true) setIsFocused(true)
}} }}
onSearchBlur={() => { onBlur={() => {
if (!isHoveringDropdown) if (!isHoveringDropdown)
setIsFocused(false) setIsFocused(false)
}} }}
tags={filterPluginTags} onKeyDown={(e) => {
onTagsChange={handleFilterPluginTagsChange} if (e.key === 'Enter')
placeholder={t('searchPlugins', { ns: 'plugin' })} handleSubmit()
usedInMarketplace }}
/> />
</div> </div>
</PortalToFollowElemTrigger> </PortalToFollowElemTrigger>

View File

@ -147,7 +147,7 @@ const PluginPage = ({
onChange={setActiveTab} onChange={setActiveTab}
options={options} options={options}
/> />
{!isPluginsTab && <SearchBoxWrapper wrapperClassName="w-[360px] mx-0" inputClassName="p-0" />} {!isPluginsTab && <SearchBoxWrapper />}
</div> </div>
<div className="flex shrink-0 items-center gap-1"> <div className="flex shrink-0 items-center gap-1">
{isExploringMarketplace && <SubmitRequestDropdown />} {isExploringMarketplace && <SubmitRequestDropdown />}

View File

@ -1,5 +1,5 @@
'use client' 'use client'
import { RiBookOpenLine, RiGithubLine, RiLayoutGridLine, RiPuzzle2Line } from '@remixicon/react' import { RiAddLine, RiBookOpenLine, RiGithubLine, RiLayoutGridLine, RiPuzzle2Line } from '@remixicon/react'
import Link from 'next/link' import Link from 'next/link'
import { useSearchParams } from 'next/navigation' import { useSearchParams } from 'next/navigation'
import { useState } from 'react' import { useState } from 'react'
@ -53,7 +53,8 @@ export const SubmitRequestDropdown = () => {
open && 'bg-state-base-hover text-text-secondary', open && 'bg-state-base-hover text-text-secondary',
)} )}
> >
<span className="system-sm-medium"> <RiAddLine className="h-4 w-4 shrink-0 lg:hidden" />
<span className="system-sm-medium hidden lg:inline">
{t('requestSubmitPlugin', { ns: 'plugin' })} {t('requestSubmitPlugin', { ns: 'plugin' })}
</span> </span>
</Button> </Button>
@ -98,7 +99,7 @@ export const CreationTypeTabs = ({ creationType: creationTypeProp }: CreationTyp
)} )}
> >
<RiPuzzle2Line className="h-4 w-4 shrink-0" /> <RiPuzzle2Line className="h-4 w-4 shrink-0" />
<span className="system-sm-medium"> <span className="system-sm-medium hidden md:inline">
{t('plugins', { ns: 'plugin' })} {t('plugins', { ns: 'plugin' })}
</span> </span>
</Link> </Link>
@ -111,10 +112,10 @@ export const CreationTypeTabs = ({ creationType: creationTypeProp }: CreationTyp
)} )}
> >
<RiLayoutGridLine className="h-4 w-4 shrink-0" /> <RiLayoutGridLine className="h-4 w-4 shrink-0" />
<span className="system-sm-medium"> <span className="system-sm-medium hidden md:inline">
{t('templates', { ns: 'plugin' })} {t('templates', { ns: 'plugin' })}
</span> </span>
<Badge className="ml-1 h-4 rounded-[4px] border-none bg-saas-dify-blue-accessible px-1 text-[10px] font-bold leading-[14px] text-text-primary-on-surface"> <Badge className="ml-1 hidden h-4 rounded-[4px] border-none bg-saas-dify-blue-accessible px-1 text-[10px] font-bold leading-[14px] text-text-primary-on-surface md:inline-flex">
NEW NEW
</Badge> </Badge>
</Link> </Link>