mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-20 13:00:39 +00:00
feat: add search clear functionality and improve search input styling
This commit is contained in:
@@ -828,6 +828,7 @@ function folderName(id: string | null | undefined): string {
|
||||
sortMenuRef={sortMenuRef}
|
||||
listPanelRef={listPanelRef}
|
||||
onSearchInput={setSearchInput}
|
||||
onClearSearch={() => setSearchInput('')}
|
||||
onSearchCompositionStart={() => setSearchComposing(true)}
|
||||
onSearchCompositionEnd={(value) => {
|
||||
setSearchComposing(false);
|
||||
|
||||
@@ -37,6 +37,7 @@ interface VaultListPanelProps {
|
||||
sortMenuRef: RefObject<HTMLDivElement>;
|
||||
listPanelRef: RefObject<HTMLDivElement>;
|
||||
onSearchInput: (value: string) => void;
|
||||
onClearSearch: () => void;
|
||||
onSearchCompositionStart: () => void;
|
||||
onSearchCompositionEnd: (value: string) => void;
|
||||
onToggleSortMenu: () => void;
|
||||
@@ -62,6 +63,7 @@ export default function VaultListPanel(props: VaultListPanelProps) {
|
||||
return (
|
||||
<section className="list-col">
|
||||
<div className="list-head">
|
||||
<div className="search-input-wrap">
|
||||
<input
|
||||
className="search-input"
|
||||
placeholder={t('txt_search_your_secure_vault')}
|
||||
@@ -69,7 +71,24 @@ export default function VaultListPanel(props: VaultListPanelProps) {
|
||||
onInput={(e) => props.onSearchInput((e.currentTarget as HTMLInputElement).value)}
|
||||
onCompositionStart={props.onSearchCompositionStart}
|
||||
onCompositionEnd={(e) => props.onSearchCompositionEnd((e.currentTarget as HTMLInputElement).value)}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key !== 'Escape' || !props.searchInput) return;
|
||||
e.preventDefault();
|
||||
props.onClearSearch();
|
||||
}}
|
||||
/>
|
||||
{!!props.searchInput && (
|
||||
<button
|
||||
type="button"
|
||||
className="search-clear-btn"
|
||||
aria-label={t('txt_clear_search')}
|
||||
title={t('txt_clear_search_esc')}
|
||||
onClick={props.onClearSearch}
|
||||
>
|
||||
<X size={14} />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<div className="sort-menu-wrap" ref={props.sortMenuRef}>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -546,6 +546,8 @@ const messages: Record<Locale, Record<string, string>> = {
|
||||
txt_save_profile_failed: "Save profile failed",
|
||||
txt_search_sends: "Search sends...",
|
||||
txt_search_your_secure_vault: "Search your secure vault...",
|
||||
txt_clear_search: "Clear search",
|
||||
txt_clear_search_esc: "Clear search (Esc)",
|
||||
txt_sort: "Sort",
|
||||
txt_sort_last_edited: "Modified",
|
||||
txt_sort_created: "Created",
|
||||
@@ -872,6 +874,8 @@ const zhCNOverrides: Record<string, string> = {
|
||||
txt_loading_nodewarden: '正在加载 NodeWarden...',
|
||||
txt_search_sends: '搜索发送...',
|
||||
txt_search_your_secure_vault: '搜索你的密码库...',
|
||||
txt_clear_search: '清空搜索',
|
||||
txt_clear_search_esc: '清空搜索(Esc)',
|
||||
txt_refresh: '刷新',
|
||||
txt_sync: '同步',
|
||||
txt_sync_vault: '同步',
|
||||
|
||||
+59
-9
@@ -1021,12 +1021,15 @@ input[type='file'].input::file-selector-button:hover {
|
||||
|
||||
.search-input {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 12px;
|
||||
padding: 0 12px;
|
||||
height: 48px;
|
||||
border: 1px solid rgba(74, 103, 150, 0.42);
|
||||
border-radius: 14px;
|
||||
padding: 10px 14px;
|
||||
font-size: 16px;
|
||||
outline: none;
|
||||
color: var(--text);
|
||||
background: var(--panel);
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
|
||||
transition:
|
||||
border-color var(--dur-fast) var(--ease-smooth),
|
||||
box-shadow var(--dur-fast) var(--ease-out-soft),
|
||||
@@ -1034,13 +1037,52 @@ input[type='file'].input::file-selector-button:hover {
|
||||
transform var(--dur-fast) var(--ease-out-soft);
|
||||
}
|
||||
|
||||
.search-input-wrap {
|
||||
position: relative;
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.search-input:focus {
|
||||
border-color: rgba(43, 102, 217, 0.28);
|
||||
background: #fbfdff;
|
||||
box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.08), 0 8px 18px rgba(37, 99, 235, 0.06);
|
||||
border-color: rgba(43, 102, 217, 0.6);
|
||||
background-color: #fbfdff;
|
||||
box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.11), 0 10px 20px rgba(37, 99, 235, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.95);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.search-input-wrap .search-input {
|
||||
padding-right: 42px;
|
||||
}
|
||||
|
||||
.search-clear-btn {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 9px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: none;
|
||||
border-radius: 999px;
|
||||
background: rgba(148, 163, 184, 0.18);
|
||||
color: var(--muted);
|
||||
cursor: pointer;
|
||||
transform: translateY(-50%);
|
||||
transition: background-color var(--dur-fast) var(--ease-out-soft), color var(--dur-fast) var(--ease-out-soft), transform var(--dur-fast) var(--ease-out-soft);
|
||||
}
|
||||
|
||||
.search-clear-btn:hover {
|
||||
background: rgba(59, 130, 246, 0.18);
|
||||
color: var(--brand);
|
||||
transform: translateY(-50%) scale(1.04);
|
||||
}
|
||||
|
||||
.search-clear-btn:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.16);
|
||||
}
|
||||
|
||||
.tree-btn {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
@@ -1151,10 +1193,13 @@ input[type='file'].input::file-selector-button:hover {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.list-head .search-input {
|
||||
.list-head .search-input-wrap {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.list-head .search-input {
|
||||
height: 42px;
|
||||
}
|
||||
|
||||
.list-head .btn {
|
||||
@@ -3733,6 +3778,11 @@ input[type='file'].input::file-selector-button:hover {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.list-head .search-input-wrap {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.list-head .search-input {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
|
||||
Reference in New Issue
Block a user