63 lines
2.1 KiB
TypeScript
63 lines
2.1 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
import { CloseIcon } from '../ui/icons/CloseIcon';
|
|
import { TabButton } from '../ui/TabButton';
|
|
|
|
type DrawerTab = 'area' | 'properties' | 'pois';
|
|
|
|
interface MobileDrawerProps {
|
|
onClose: () => void;
|
|
renderArea: () => React.ReactNode;
|
|
renderProperties: () => React.ReactNode;
|
|
renderPOIs: () => React.ReactNode;
|
|
}
|
|
|
|
export default function MobileDrawer({
|
|
onClose,
|
|
renderArea,
|
|
renderProperties,
|
|
renderPOIs,
|
|
}: MobileDrawerProps) {
|
|
const [tab, setTab] = useState<DrawerTab>('area');
|
|
|
|
// Close on Escape
|
|
useEffect(() => {
|
|
const handler = (e: KeyboardEvent) => {
|
|
if (e.key === 'Escape') onClose();
|
|
};
|
|
window.addEventListener('keydown', handler);
|
|
return () => window.removeEventListener('keydown', handler);
|
|
}, [onClose]);
|
|
|
|
return (
|
|
<div className="fixed inset-0 z-50 flex flex-col">
|
|
{/* Backdrop — top 10% */}
|
|
<div className="h-[10%] bg-black/50" onClick={onClose} />
|
|
|
|
{/* Panel — bottom 90% */}
|
|
<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="Properties"
|
|
isActive={tab === 'properties'}
|
|
onClick={() => setTab('properties')}
|
|
/>
|
|
<TabButton label="POIs" isActive={tab === 'pois'} onClick={() => setTab('pois')} />
|
|
<button
|
|
onClick={onClose}
|
|
className="ml-auto flex items-center justify-center w-10 h-10 rounded-lg hover:bg-warm-100 dark:hover:bg-navy-800"
|
|
aria-label="Close drawer"
|
|
>
|
|
<CloseIcon className="w-5 h-5 text-warm-500 dark:text-warm-400" />
|
|
</button>
|
|
</div>
|
|
|
|
{/* Content */}
|
|
<div className="flex-1 overflow-hidden">
|
|
{tab === 'area' ? renderArea() : tab === 'properties' ? renderProperties() : renderPOIs()}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|