2021-02-04 19:13:47 +01:00
|
|
|
import { h, Fragment } from 'preact';
|
|
|
|
import { Link } from 'preact-router/match';
|
2021-02-09 20:35:33 +01:00
|
|
|
import { useCallback } from 'preact/hooks';
|
2021-02-04 19:13:47 +01:00
|
|
|
import { useDrawer } from '../context';
|
|
|
|
|
|
|
|
export default function NavigationDrawer({ children, header }) {
|
|
|
|
const { showDrawer, setShowDrawer } = useDrawer();
|
|
|
|
|
|
|
|
const handleDismiss = useCallback(() => {
|
|
|
|
setShowDrawer(false);
|
|
|
|
}, [setShowDrawer]);
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Fragment>
|
2021-02-12 23:23:23 +01:00
|
|
|
{showDrawer ? <div data-testid="scrim" key="scrim" className="fixed inset-0 z-20" onClick={handleDismiss} /> : ''}
|
2021-02-04 19:13:47 +01:00
|
|
|
<div
|
2021-02-06 00:52:47 +01:00
|
|
|
key="drawer"
|
2021-02-12 23:23:23 +01:00
|
|
|
data-testid="drawer"
|
2021-02-06 00:52:47 +01:00
|
|
|
className={`fixed left-0 top-0 bottom-0 lg:sticky max-h-screen flex flex-col w-64 text-gray-700 bg-white dark:text-gray-200 dark:bg-gray-900 flex-shrink-0 border-r border-gray-200 dark:border-gray-700 shadow lg:shadow-none z-20 lg:z-0 transform ${
|
|
|
|
!showDrawer ? '-translate-x-full lg:translate-x-0' : 'translate-x-0'
|
|
|
|
} transition-transform duration-300`}
|
2021-02-04 19:13:47 +01:00
|
|
|
onClick={handleDismiss}
|
|
|
|
>
|
|
|
|
{header ? (
|
2021-08-20 13:04:47 +02:00
|
|
|
<div className="flex-shrink-0 p-2 flex flex-row items-center justify-between border-b border-gray-200 dark:border-gray-700">
|
2021-02-04 19:13:47 +01:00
|
|
|
{header}
|
|
|
|
</div>
|
|
|
|
) : null}
|
|
|
|
|
|
|
|
<nav className="flex flex-col flex-grow overflow-hidden overflow-y-auto p-2 space-y-2">{children}</nav>
|
|
|
|
</div>
|
|
|
|
</Fragment>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function Destination({ className = '', href, text, ...other }) {
|
|
|
|
const external = href.startsWith('http');
|
|
|
|
const props = external ? { rel: 'noopener nofollow', target: '_blank' } : {};
|
|
|
|
|
|
|
|
const { setShowDrawer } = useDrawer();
|
|
|
|
|
|
|
|
const handleDismiss = useCallback(() => {
|
|
|
|
setTimeout(() => {
|
|
|
|
setShowDrawer(false);
|
|
|
|
}, 250);
|
|
|
|
}, [setShowDrawer]);
|
|
|
|
|
|
|
|
const styleProps = {
|
|
|
|
[external
|
2022-02-26 20:11:00 +01:00
|
|
|
? className
|
2021-02-04 19:13:47 +01:00
|
|
|
: 'class']: 'block p-2 text-sm font-semibold text-gray-900 rounded hover:bg-blue-500 dark:text-gray-200 hover:text-white dark:hover:text-white focus:outline-none ring-opacity-50 focus:ring-2 ring-blue-300',
|
|
|
|
};
|
|
|
|
|
2021-02-05 00:19:47 +01:00
|
|
|
const El = external ? 'a' : Link;
|
|
|
|
|
2021-02-04 19:13:47 +01:00
|
|
|
return (
|
2021-02-05 00:19:47 +01:00
|
|
|
<El activeClassName="bg-blue-500 bg-opacity-50 text-white" {...styleProps} href={href} {...props} {...other}>
|
2021-02-04 19:13:47 +01:00
|
|
|
<div onClick={handleDismiss}>{text}</div>
|
2021-02-05 00:19:47 +01:00
|
|
|
</El>
|
2021-02-04 19:13:47 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function Separator() {
|
|
|
|
return <div className="border-b border-gray-200 dark:border-gray-700 -mx-2" />;
|
|
|
|
}
|