More improvements
This commit is contained in:
parent
e0798b24f7
commit
72653a4ddf
7 changed files with 146 additions and 33 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { memo, useState, useMemo, useRef, useCallback } from 'react';
|
||||
import { memo, useState, useMemo, useRef, useCallback, useEffect } from 'react';
|
||||
import { Slider } from '../ui/Slider';
|
||||
import { LightbulbIcon } from '../ui/icons';
|
||||
|
||||
|
|
@ -212,23 +212,27 @@ export default memo(function Filters({
|
|||
|
||||
const activeEntryCount = travelTimeEntries.length;
|
||||
|
||||
const pendingScrollRef = useRef<string | null>(null);
|
||||
|
||||
const handleAddAndScroll = useCallback(
|
||||
(name: string) => {
|
||||
const feature = features.find((f) => f.name === name);
|
||||
if (feature?.group) expandGroup(feature.group);
|
||||
pendingScrollRef.current = name;
|
||||
onAddFilter(name);
|
||||
// Double rAF: first lets React commit the DOM update, second lets layout settle
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
const el = scrollRef.current?.querySelector(`[data-filter-name="${CSS.escape(name)}"]`);
|
||||
if (el) {
|
||||
el.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
[onAddFilter, features, expandGroup]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const name = pendingScrollRef.current;
|
||||
if (!name) return;
|
||||
pendingScrollRef.current = null;
|
||||
const el = scrollRef.current?.querySelector(`[data-filter-name="${CSS.escape(name)}"]`);
|
||||
if (el) {
|
||||
el.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}
|
||||
}, [enabledFeatureList]);
|
||||
const enabledGroups = useMemo(
|
||||
() => groupFeaturesByCategory(enabledFeatureList),
|
||||
[enabledFeatureList]
|
||||
|
|
@ -357,7 +361,7 @@ export default memo(function Filters({
|
|||
<div
|
||||
key={feature.name}
|
||||
data-filter-name={feature.name}
|
||||
className={`space-y-0.5 px-2 py-1.5 rounded ${pinnedFeature === feature.name ? 'ring-2 ring-teal-400 bg-teal-50/50 dark:bg-teal-900/20' : ''}`}
|
||||
className={`scroll-mt-7 space-y-0.5 px-2 py-1.5 rounded ${pinnedFeature === feature.name ? 'ring-2 ring-teal-400 bg-teal-50/50 dark:bg-teal-900/20' : ''}`}
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<FeatureLabel feature={feature} onShowInfo={setActiveInfoFeature} size="sm" />
|
||||
|
|
@ -414,7 +418,7 @@ export default memo(function Filters({
|
|||
<div
|
||||
key={feature.name}
|
||||
data-filter-name={feature.name}
|
||||
className={`space-y-0.5 px-2 py-1.5 rounded ${isActive ? 'ring-2 ring-teal-400 bg-teal-50 dark:bg-teal-900/30' : isPinned ? 'ring-2 ring-teal-400 bg-teal-50/50 dark:bg-teal-900/20' : ''}`}
|
||||
className={`scroll-mt-7 space-y-0.5 px-2 py-1.5 rounded ${isActive ? 'ring-2 ring-teal-400 bg-teal-50 dark:bg-teal-900/30' : isPinned ? 'ring-2 ring-teal-400 bg-teal-50/50 dark:bg-teal-900/20' : ''}`}
|
||||
>
|
||||
<div className="flex items-center justify-between gap-1">
|
||||
<FeatureLabel feature={feature} onShowInfo={setActiveInfoFeature} size="sm" className="min-w-0 shrink" />
|
||||
|
|
|
|||
|
|
@ -1,21 +1,22 @@
|
|||
import { useState, useEffect } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { CloseIcon } from '../ui/icons/CloseIcon';
|
||||
import { TabButton } from '../ui/TabButton';
|
||||
|
||||
type DrawerTab = 'area' | 'properties';
|
||||
|
||||
interface MobileDrawerProps {
|
||||
onClose: () => void;
|
||||
renderArea: () => React.ReactNode;
|
||||
renderProperties: () => React.ReactNode;
|
||||
tab: 'area' | 'properties';
|
||||
onTabChange: (tab: 'area' | 'properties') => void;
|
||||
}
|
||||
|
||||
export default function MobileDrawer({
|
||||
onClose,
|
||||
renderArea,
|
||||
renderProperties,
|
||||
tab,
|
||||
onTabChange,
|
||||
}: MobileDrawerProps) {
|
||||
const [tab, setTab] = useState<DrawerTab>('area');
|
||||
|
||||
// Close on Escape
|
||||
useEffect(() => {
|
||||
|
|
@ -35,11 +36,11 @@ export default function MobileDrawer({
|
|||
<div className="h-[90%] bg-white dark:bg-navy-950 rounded-t-2xl flex flex-col shadow-xl overflow-hidden">
|
||||
{/* Tab bar + close */}
|
||||
<div className="flex border-b border-warm-200 dark:border-navy-700 text-sm shrink-0">
|
||||
<TabButton label="Area" isActive={tab === 'area'} onClick={() => setTab('area')} />
|
||||
<TabButton label="Area" isActive={tab === 'area'} onClick={() => onTabChange('area')} />
|
||||
<TabButton
|
||||
label="Properties"
|
||||
isActive={tab === 'properties'}
|
||||
onClick={() => setTab('properties')}
|
||||
onClick={() => onTabChange('properties')}
|
||||
/>
|
||||
<button
|
||||
onClick={onClose}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue