import { useId, useRef, useState } from 'react'; import { ArrowLeft, Check, ChevronDown, Filter, Search, X } from 'lucide-react'; export type MobileDimension = { key: string; label: string; options: { value: string; label: string; count?: number }[] }; type Filters = Partial>; type Props = { available: MobileDimension[]; dimensions: string[]; filters: Filters; defaults: string[]; apply: (dimensions: string[], filters: Filters) => void; }; /** Draft all mobile settings together; cancelling never changes the current result. */ export function MobileAnalysisControls({ available, dimensions, filters, defaults, apply }: Props) { const [mode, setMode] = useState<'group' | 'filter' | null>(null); const [draftDimensions, setDraftDimensions] = useState(dimensions); const [draftFilters, setDraftFilters] = useState(filters); const [editing, setEditing] = useState(null); const [query, setQuery] = useState(''); const trigger = useRef(null); const panel = useRef(null); const id = useId(); const selected = available.filter(d => filters[d.key]?.length); const editor = available.find(d => d.key === editing); const options = editor?.options.filter(o => o.label.toLocaleLowerCase().includes(query.toLocaleLowerCase())) || []; const close = () => { setMode(null); trigger.current?.focus(); }; const open = (next: 'group' | 'filter', button: HTMLButtonElement) => { trigger.current = button; setDraftDimensions([...dimensions]); setDraftFilters({ ...filters }); setEditing(null); setQuery(''); setMode(next); requestAnimationFrame(() => panel.current?.focus()); }; const toggle = (key: string, value: string) => { const values = draftFilters[key] || []; setDraftFilters({ ...draftFilters, [key]: values.includes(value) ? values.filter(v => v !== value) : [...values, value] }); }; return
分析维度可多选 · 左右滑动
{available.map(d => )}
{!!selected.length &&
{selected.map(d => )}
} {mode &&
{ if (e.target === e.currentTarget) close(); }}>
}
; }