mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 15:06:20 +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 { Button } from '../../../../common';
|
||||
import { useNavigatorData, useNavigatorUiStore } from '../../../../hooks';
|
||||
import { NavigatorFilterChipsView } from './NavigatorFilterChipsView';
|
||||
|
||||
interface NavigatorSearchViewProps
|
||||
{
|
||||
@@ -77,15 +78,8 @@ export const NavigatorSearchView: FC<NavigatorSearchViewProps> = props =>
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex w-full gap-1">
|
||||
<div className="flex shrink-0">
|
||||
<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 flex-col gap-1">
|
||||
<NavigatorFilterChipsView value={ searchFilterIndex } onChange={ setSearchFilterIndex } />
|
||||
<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) } />
|
||||
<Button variant="primary" onClick={ processSearch }>
|
||||
|
||||
Reference in New Issue
Block a user