mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-20 15:36:18 +00:00
feat(navigator): search-scope filter chips replace the dropdown (P4 wave 1b)
NavigatorFilterChipsView renders the 5 SearchFilterOptions (anything / room.name / owner / tag / group) as pill chips instead of a <select>. Active chip uses bg-primary; the chips sit on their own row above the search input. Drives the existing searchFilterIndex local state — the debounce effect already rebuilds the query:value string from it, so no behavioural change to how searches are issued. Deferred to wave 1c: saved-search chip row (replacing the 600px sidebar). That one needs care — a saved-search click sends NavigatorSearchComposer directly, which P2's accept-filter (result.code must match currentTabCode) can reject; the chip version must route through setTab/setFilter instead. Wants browser verification. navigator suites 28/28, lint:hooks clean, no new typecheck errors.
This commit is contained in:
@@ -0,0 +1,32 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { LocalizeText, SearchFilterOptions } from '../../../../api';
|
||||||
|
|
||||||
|
interface NavigatorFilterChipsViewProps
|
||||||
|
{
|
||||||
|
value: number;
|
||||||
|
onChange: (index: number) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NavigatorFilterChipsView: FC<NavigatorFilterChipsViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { value, onChange } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-wrap gap-1">
|
||||||
|
{ SearchFilterOptions.map((filter, index) =>
|
||||||
|
{
|
||||||
|
const isActive = (value === index);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
key={ index }
|
||||||
|
type="button"
|
||||||
|
onClick={ () => onChange(index) }
|
||||||
|
className={ `px-2 py-0.5 rounded-full text-[11px] border cursor-pointer transition-colors ${ isActive ? 'bg-primary text-white border-primary' : 'bg-card-grid-item text-gray-600 border-card-grid-item-border hover:bg-primary hover:text-white hover:border-primary' }` }>
|
||||||
|
{ LocalizeText('navigator.filter.' + filter.name) }
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}) }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -4,6 +4,7 @@ import { FaSearch } from 'react-icons/fa';
|
|||||||
import { INavigatorSearchFilter, LocalizeText, SearchFilterOptions } from '../../../../api';
|
import { INavigatorSearchFilter, LocalizeText, SearchFilterOptions } from '../../../../api';
|
||||||
import { Button } from '../../../../common';
|
import { Button } from '../../../../common';
|
||||||
import { useNavigatorData, useNavigatorUiStore } from '../../../../hooks';
|
import { useNavigatorData, useNavigatorUiStore } from '../../../../hooks';
|
||||||
|
import { NavigatorFilterChipsView } from './NavigatorFilterChipsView';
|
||||||
|
|
||||||
interface NavigatorSearchViewProps
|
interface NavigatorSearchViewProps
|
||||||
{
|
{
|
||||||
@@ -77,15 +78,8 @@ export const NavigatorSearchView: FC<NavigatorSearchViewProps> = props =>
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex w-full gap-1">
|
<div className="flex w-full flex-col gap-1">
|
||||||
<div className="flex shrink-0">
|
<NavigatorFilterChipsView value={ searchFilterIndex } onChange={ setSearchFilterIndex } />
|
||||||
<select className="form-select" value={ searchFilterIndex } onChange={ event => setSearchFilterIndex(parseInt(event.target.value)) }>
|
|
||||||
{ SearchFilterOptions.map((filter, index) =>
|
|
||||||
{
|
|
||||||
return <option key={ index } value={ index }>{ LocalizeText('navigator.filter.' + filter.name) }</option>;
|
|
||||||
}) }
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div className="flex w-full gap-1">
|
<div className="flex w-full gap-1">
|
||||||
<input className="w-full form-control" placeholder={ LocalizeText('navigator.filter.input.placeholder') } type="text" value={ inputText } onChange={ event => setInputText(event.target.value) } onKeyDown={ event => handleKeyDown(event) } />
|
<input className="w-full form-control" placeholder={ LocalizeText('navigator.filter.input.placeholder') } type="text" value={ inputText } onChange={ event => setInputText(event.target.value) } onKeyDown={ event => handleKeyDown(event) } />
|
||||||
<Button variant="primary" onClick={ processSearch }>
|
<Button variant="primary" onClick={ processSearch }>
|
||||||
|
|||||||
Reference in New Issue
Block a user