mirror of
				https://github.com/blakeblackshear/frigate.git
				synced 2025-10-27 10:52:11 +01:00 
			
		
		
		
	refactor(web): NavigationBar (sidebar) styles
This commit is contained in:
		
							parent
							
								
									ff62338359
								
							
						
					
					
						commit
						ba0338e9d5
					
				@ -11,13 +11,13 @@ import { Router } from 'preact-router';
 | 
				
			|||||||
import Sidebar from './Sidebar';
 | 
					import Sidebar from './Sidebar';
 | 
				
			||||||
import StyleGuide from './StyleGuide';
 | 
					import StyleGuide from './StyleGuide';
 | 
				
			||||||
import Api, { FetchStatus, useConfig } from './api';
 | 
					import Api, { FetchStatus, useConfig } from './api';
 | 
				
			||||||
import { DarkModeProvider, SidebarProvider } from './context';
 | 
					import { DarkModeProvider, DrawerProvider } from './context';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function App() {
 | 
					export default function App() {
 | 
				
			||||||
  const { data, status } = useConfig();
 | 
					  const { data, status } = useConfig();
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <DarkModeProvider>
 | 
					    <DarkModeProvider>
 | 
				
			||||||
      <SidebarProvider>
 | 
					      <DrawerProvider>
 | 
				
			||||||
        <div class="w-full">
 | 
					        <div class="w-full">
 | 
				
			||||||
          <AppBar title="Frigate" />
 | 
					          <AppBar title="Frigate" />
 | 
				
			||||||
          {status !== FetchStatus.LOADED ? (
 | 
					          {status !== FetchStatus.LOADED ? (
 | 
				
			||||||
@ -41,7 +41,7 @@ export default function App() {
 | 
				
			|||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          )}
 | 
					          )}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </SidebarProvider>
 | 
					      </DrawerProvider>
 | 
				
			||||||
    </DarkModeProvider>
 | 
					    </DarkModeProvider>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,56 +1,45 @@
 | 
				
			|||||||
import { h, Fragment } from 'preact';
 | 
					import { h, Fragment } from 'preact';
 | 
				
			||||||
import Link from './components/Link';
 | 
					 | 
				
			||||||
import LinkedLogo from './components/LinkedLogo';
 | 
					import LinkedLogo from './components/LinkedLogo';
 | 
				
			||||||
import { Link as RouterLink } from 'preact-router/match';
 | 
					import { Match } from 'preact-router/match';
 | 
				
			||||||
import { useCallback, useState } from 'preact/hooks';
 | 
					import { memo } from 'preact/compat';
 | 
				
			||||||
import { useSidebar } from './context';
 | 
					import { useConfig } from './api';
 | 
				
			||||||
 | 
					import NavigationDrawer, { Destination, Separator } from './components/NavigationDrawer';
 | 
				
			||||||
function NavLink({ className = '', href, text, ...other }) {
 | 
					import { useCallback, useMemo } from 'preact/hooks';
 | 
				
			||||||
  const external = href.startsWith('http');
 | 
					 | 
				
			||||||
  const El = external ? Link : RouterLink;
 | 
					 | 
				
			||||||
  const props = external ? { rel: 'noopener nofollow', target: '_blank' } : {};
 | 
					 | 
				
			||||||
  return (
 | 
					 | 
				
			||||||
    <El
 | 
					 | 
				
			||||||
      activeClassName="bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-600 dark:focus:bg-gray-600 dark:focus:text-white dark:hover:text-white dark:text-gray-200"
 | 
					 | 
				
			||||||
      className={`block px-4 py-2 mt-2 text-sm font-semibold text-gray-900 bg-transparent rounded-lg dark:bg-transparent dark:hover:bg-gray-600 dark:focus:bg-gray-600 dark:focus:text-white dark:hover:text-white dark:text-gray-200 hover:text-gray-900 focus:text-gray-900 hover:bg-gray-200 focus:bg-gray-200 focus:outline-none focus:shadow-outline self-end ${className}`}
 | 
					 | 
				
			||||||
      href={href}
 | 
					 | 
				
			||||||
      {...other}
 | 
					 | 
				
			||||||
      {...props}
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
      {text}
 | 
					 | 
				
			||||||
    </El>
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function Sidebar() {
 | 
					export default function Sidebar() {
 | 
				
			||||||
  const { showSidebar, setShowSidebar } = useSidebar();
 | 
					  const { data: config } = useConfig();
 | 
				
			||||||
 | 
					  const cameras = useMemo(() => Object.keys(config.cameras), [config]);
 | 
				
			||||||
  const handleDismiss = useCallback(() => {
 | 
					 | 
				
			||||||
    setShowSidebar(false);
 | 
					 | 
				
			||||||
  }, [setShowSidebar]);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <Fragment>
 | 
					    <NavigationDrawer header={<Header />}>
 | 
				
			||||||
      {showSidebar ? <div className="fixed inset-0 z-20" onClick={handleDismiss} /> : ''}
 | 
					      <Destination href="/" text="Cameras" />
 | 
				
			||||||
      <div
 | 
					      <Match path="/cameras/:camera">
 | 
				
			||||||
        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 translate-x-0 ${
 | 
					        {({ matches }) =>
 | 
				
			||||||
          !showSidebar ? '-translate-x-full' : ''
 | 
					          matches ? (
 | 
				
			||||||
        } lg:translate-x-0 transition-transform duration-300`}
 | 
					            <Fragment>
 | 
				
			||||||
      >
 | 
					              <Separator />
 | 
				
			||||||
        <div className="flex-shrink-0 p-4 flex flex-row items-center justify-between">
 | 
					              {cameras.map((camera) => (
 | 
				
			||||||
          <div class="text-gray-500">
 | 
					                <Destination href={`/cameras/${camera}`} text={camera} />
 | 
				
			||||||
            <LinkedLogo />
 | 
					              ))}
 | 
				
			||||||
          </div>
 | 
					              <Separator />
 | 
				
			||||||
        </div>
 | 
					            </Fragment>
 | 
				
			||||||
        <nav className="flex-col flex-grow md:block overflow-hidden px-4 pb-4 md:pb-0 md:overflow-y-auto">
 | 
					          ) : null
 | 
				
			||||||
          <NavLink onClick={handleDismiss} href="/" text="Cameras" />
 | 
					        }
 | 
				
			||||||
          <NavLink onClick={handleDismiss} href="/events" text="Events" />
 | 
					      </Match>
 | 
				
			||||||
          <NavLink onClick={handleDismiss} href="/debug" text="Debug" />
 | 
					      <Destination href="/events" text="Events" />
 | 
				
			||||||
          <hr className="border-solid border-gray-500 mt-2" />
 | 
					      <Destination href="/debug" text="Debug" />
 | 
				
			||||||
          <NavLink className="self-end" href="https://blakeblackshear.github.io/frigate" text="Documentation" />
 | 
					      <Separator />
 | 
				
			||||||
          <NavLink className="self-end" href="https://github.com/blakeblackshear/frigate" text="GitHub" />
 | 
					      <div className="flex flex-grow" />
 | 
				
			||||||
        </nav>
 | 
					      <Destination className="self-end" href="https://blakeblackshear.github.io/frigate" text="Documentation" />
 | 
				
			||||||
      </div>
 | 
					      <Destination className="self-end" href="https://github.com/blakeblackshear/frigate" text="GitHub" />
 | 
				
			||||||
    </Fragment>
 | 
					    </NavigationDrawer>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Header = memo(function Header() {
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <div class="text-gray-500">
 | 
				
			||||||
 | 
					      <LinkedLogo />
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,7 @@ import MoreIcon from '../icons/More';
 | 
				
			|||||||
import AutoAwesomeIcon from '../icons/AutoAwesome';
 | 
					import AutoAwesomeIcon from '../icons/AutoAwesome';
 | 
				
			||||||
import LightModeIcon from '../icons/LightMode';
 | 
					import LightModeIcon from '../icons/LightMode';
 | 
				
			||||||
import DarkModeIcon from '../icons/DarkMode';
 | 
					import DarkModeIcon from '../icons/DarkMode';
 | 
				
			||||||
import { useDarkMode, useSidebar } from '../context';
 | 
					import { useDarkMode, useDrawer } from '../context';
 | 
				
			||||||
import { useLayoutEffect, useCallback, useRef, useState } from 'preact/hooks';
 | 
					import { useLayoutEffect, useCallback, useRef, useState } from 'preact/hooks';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// We would typically preserve these in component state
 | 
					// We would typically preserve these in component state
 | 
				
			||||||
@ -18,10 +18,10 @@ let lastScrollY = window.scrollY;
 | 
				
			|||||||
export default function AppBar({ title }) {
 | 
					export default function AppBar({ title }) {
 | 
				
			||||||
  const [show, setShow] = useState(true);
 | 
					  const [show, setShow] = useState(true);
 | 
				
			||||||
  const [atZero, setAtZero] = useState(window.scrollY === 0);
 | 
					  const [atZero, setAtZero] = useState(window.scrollY === 0);
 | 
				
			||||||
  const [sidebarVisible, setSidebarVisible] = useState(true);
 | 
					  const [_, setDrawerVisible] = useState(true);
 | 
				
			||||||
  const [showMoreMenu, setShowMoreMenu] = useState(false);
 | 
					  const [showMoreMenu, setShowMoreMenu] = useState(false);
 | 
				
			||||||
  const { currentMode, persistedMode, setDarkMode } = useDarkMode();
 | 
					  const { currentMode, persistedMode, setDarkMode } = useDarkMode();
 | 
				
			||||||
  const { showSidebar, setShowSidebar } = useSidebar();
 | 
					  const { showDrawer, setShowDrawer } = useDrawer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const handleSelectDarkMode = useCallback(
 | 
					  const handleSelectDarkMode = useCallback(
 | 
				
			||||||
    (value, label) => {
 | 
					    (value, label) => {
 | 
				
			||||||
@ -65,9 +65,9 @@ export default function AppBar({ title }) {
 | 
				
			|||||||
    setShowMoreMenu(false);
 | 
					    setShowMoreMenu(false);
 | 
				
			||||||
  }, [setShowMoreMenu]);
 | 
					  }, [setShowMoreMenu]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const handleShowSidebar = useCallback(() => {
 | 
					  const handleShowDrawer = useCallback(() => {
 | 
				
			||||||
    setShowSidebar(true);
 | 
					    setShowDrawer(true);
 | 
				
			||||||
  }, [setShowSidebar]);
 | 
					  }, [setShowDrawer]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div
 | 
					    <div
 | 
				
			||||||
@ -76,7 +76,7 @@ export default function AppBar({ title }) {
 | 
				
			|||||||
      } ${!atZero ? 'shadow' : ''}`}
 | 
					      } ${!atZero ? 'shadow' : ''}`}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <div className="lg:hidden">
 | 
					      <div className="lg:hidden">
 | 
				
			||||||
        <Button color="black" className="rounded-full w-12 h-12" onClick={handleShowSidebar} type="text">
 | 
					        <Button color="black" className="rounded-full w-12 h-12" onClick={handleShowDrawer} type="text">
 | 
				
			||||||
          <MenuIcon />
 | 
					          <MenuIcon />
 | 
				
			||||||
        </Button>
 | 
					        </Button>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,9 +1,16 @@
 | 
				
			|||||||
import { h } from 'preact';
 | 
					import { h } from 'preact';
 | 
				
			||||||
 | 
					import { Link as RouterLink } from 'preact-router/match';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function Link({ className, children, href, ...props }) {
 | 
					export default function Link({
 | 
				
			||||||
 | 
					  activeClassName = '',
 | 
				
			||||||
 | 
					  className = 'text-blue-500 hover:underline',
 | 
				
			||||||
 | 
					  children,
 | 
				
			||||||
 | 
					  href,
 | 
				
			||||||
 | 
					  ...props
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <a className={`text-blue-500 dark:text-blue-400 hover:underline ${className}`} href={href} {...props}>
 | 
					    <RouterLink activeClassName={activeClassName} className={className} href={href} {...props}>
 | 
				
			||||||
      {children}
 | 
					      {children}
 | 
				
			||||||
    </a>
 | 
					    </RouterLink>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,7 @@ export default function Menu({ className, children, onDismiss, relativeTo }) {
 | 
				
			|||||||
  return relativeTo ? (
 | 
					  return relativeTo ? (
 | 
				
			||||||
    <RelativeModal
 | 
					    <RelativeModal
 | 
				
			||||||
      children={children}
 | 
					      children={children}
 | 
				
			||||||
      className={`${className || ''} pt-2 pb-2`}
 | 
					      className={`${className || ''} py-2`}
 | 
				
			||||||
      role="listbox"
 | 
					      role="listbox"
 | 
				
			||||||
      onDismiss={onDismiss}
 | 
					      onDismiss={onDismiss}
 | 
				
			||||||
      portalRootID="menus"
 | 
					      portalRootID="menus"
 | 
				
			||||||
@ -48,5 +48,5 @@ export function MenuItem({ focus, icon: Icon, label, onSelect, value }) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function MenuSeparator() {
 | 
					export function MenuSeparator() {
 | 
				
			||||||
  return <div className="border-b border-gray-200 my-2" />;
 | 
					  return <div className="border-b border-gray-200 dark:border-gray-800 my-2" />;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										61
									
								
								web/src/components/NavigationDrawer.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								web/src/components/NavigationDrawer.jsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					import { h, Fragment } from 'preact';
 | 
				
			||||||
 | 
					import { Link } from 'preact-router/match';
 | 
				
			||||||
 | 
					import { useCallback, useState } from 'preact/hooks';
 | 
				
			||||||
 | 
					import { useDrawer } from '../context';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default function NavigationDrawer({ children, header }) {
 | 
				
			||||||
 | 
					  const { showDrawer, setShowDrawer } = useDrawer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const handleDismiss = useCallback(() => {
 | 
				
			||||||
 | 
					    setShowDrawer(false);
 | 
				
			||||||
 | 
					  }, [setShowDrawer]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <Fragment>
 | 
				
			||||||
 | 
					      {showDrawer ? <div className="fixed inset-0 z-20" onClick={handleDismiss} /> : ''}
 | 
				
			||||||
 | 
					      <div
 | 
				
			||||||
 | 
					        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 translate-x-0 ${
 | 
				
			||||||
 | 
					          !showDrawer ? '-translate-x-full' : ''
 | 
				
			||||||
 | 
					        } lg:translate-x-0 transition-transform duration-300`}
 | 
				
			||||||
 | 
					        onClick={handleDismiss}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        {header ? (
 | 
				
			||||||
 | 
					          <div className="flex-shrink-0 p-5 flex flex-row items-center justify-between border-b border-gray-200 dark:border-gray-700">
 | 
				
			||||||
 | 
					            {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
 | 
				
			||||||
 | 
					      ? 'className'
 | 
				
			||||||
 | 
					      : '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',
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <Link activeClassName="bg-blue-500 bg-opacity-50 text-white" {...styleProps} href={href} {...props} {...other}>
 | 
				
			||||||
 | 
					      <div onClick={handleDismiss}>{text}</div>
 | 
				
			||||||
 | 
					    </Link>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function Separator() {
 | 
				
			||||||
 | 
					  return <div className="border-b border-gray-200 dark:border-gray-700 -mx-2" />;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,5 +1,6 @@
 | 
				
			|||||||
import { h, Fragment } from 'preact';
 | 
					import { h, Fragment } from 'preact';
 | 
				
			||||||
import { createPortal } from 'preact/compat';
 | 
					import { createPortal } from 'preact/compat';
 | 
				
			||||||
 | 
					import { DarkModeProvider } from '../context';
 | 
				
			||||||
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'preact/hooks';
 | 
					import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'preact/hooks';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const WINDOW_PADDING = 20;
 | 
					const WINDOW_PADDING = 20;
 | 
				
			||||||
@ -75,7 +76,7 @@ export default function RelativeModal({ className, role = 'dialog', children, on
 | 
				
			|||||||
  }, [show, position.width, ref.current]);
 | 
					  }, [show, position.width, ref.current]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const menu = (
 | 
					  const menu = (
 | 
				
			||||||
    <Fragment>
 | 
					    <DarkModeProvider>
 | 
				
			||||||
      <div className="absolute inset-0" onClick={handleDismiss} />
 | 
					      <div className="absolute inset-0" onClick={handleDismiss} />
 | 
				
			||||||
      <div
 | 
					      <div
 | 
				
			||||||
        className={`z-10 bg-white dark:bg-gray-700 dark:text-white absolute shadow-lg rounded w-auto max-h-48 transition-all duration-75 transform scale-90 opacity-0 ${
 | 
					        className={`z-10 bg-white dark:bg-gray-700 dark:text-white absolute shadow-lg rounded w-auto max-h-48 transition-all duration-75 transform scale-90 opacity-0 ${
 | 
				
			||||||
@ -90,7 +91,7 @@ export default function RelativeModal({ className, role = 'dialog', children, on
 | 
				
			|||||||
      >
 | 
					      >
 | 
				
			||||||
        {children}
 | 
					        {children}
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </Fragment>
 | 
					    </DarkModeProvider>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return portalRoot ? createPortal(menu, portalRoot) : menu;
 | 
					  return portalRoot ? createPortal(menu, portalRoot) : menu;
 | 
				
			||||||
 | 
				
			|||||||
@ -65,14 +65,14 @@ export function useDarkMode() {
 | 
				
			|||||||
  return useContext(DarkMode);
 | 
					  return useContext(DarkMode);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Sidebar = createContext(null);
 | 
					const Drawer = createContext(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function SidebarProvider({ children }) {
 | 
					export function DrawerProvider({ children }) {
 | 
				
			||||||
  const [showSidebar, setShowSidebar] = useState(false);
 | 
					  const [showDrawer, setShowDrawer] = useState(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return <Sidebar.Provider value={{ showSidebar, setShowSidebar }}>{children}</Sidebar.Provider>;
 | 
					  return <Drawer.Provider value={{ showDrawer, setShowDrawer }}>{children}</Drawer.Provider>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function useSidebar() {
 | 
					export function useDrawer() {
 | 
				
			||||||
  return useContext(Sidebar);
 | 
					  return useContext(Drawer);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user