mirror of
https://github.com/Shadowfita/docmost.git
synced 2025-11-15 01:01:09 +10:00
make sidebar mobile responsive
This commit is contained in:
41
frontend/src/components/sidebar/sidebar-toggle-button.tsx
Normal file
41
frontend/src/components/sidebar/sidebar-toggle-button.tsx
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useIsMobile } from '@/hooks/use-is-mobile';
|
||||||
|
import {
|
||||||
|
desktopSidebarAtom,
|
||||||
|
mobileSidebarAtom,
|
||||||
|
} from '@/components/sidebar/atoms/sidebar-atom';
|
||||||
|
import { useToggleSidebar } from './hooks/use-toggle-sidebar';
|
||||||
|
import ButtonWithIcon from '../ui/button-with-icon';
|
||||||
|
import {
|
||||||
|
IconLayoutSidebarLeftCollapse,
|
||||||
|
IconLayoutSidebarRightCollapse,
|
||||||
|
} from '@tabler/icons-react';
|
||||||
|
import { useAtom } from 'jotai';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
|
interface SidebarToggleButtonProps {
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function SidebarToggleButton({
|
||||||
|
className,
|
||||||
|
}: SidebarToggleButtonProps) {
|
||||||
|
const isMobile = useIsMobile();
|
||||||
|
const sidebarStateAtom = isMobile ? mobileSidebarAtom : desktopSidebarAtom;
|
||||||
|
|
||||||
|
const [isSidebarOpen] = useAtom(sidebarStateAtom);
|
||||||
|
const toggleSidebar = useToggleSidebar(sidebarStateAtom);
|
||||||
|
|
||||||
|
const SidebarIcon = isSidebarOpen
|
||||||
|
? IconLayoutSidebarLeftCollapse
|
||||||
|
: IconLayoutSidebarRightCollapse;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ButtonWithIcon
|
||||||
|
className={cn(className, 'z-[100]')}
|
||||||
|
icon={<SidebarIcon size={20} />}
|
||||||
|
variant={'ghost'}
|
||||||
|
onClick={toggleSidebar}
|
||||||
|
></ButtonWithIcon>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -12,9 +12,11 @@ import {
|
|||||||
NavigationMenuType,
|
NavigationMenuType,
|
||||||
} from '@/components/sidebar/actions/sidebar-actions';
|
} from '@/components/sidebar/actions/sidebar-actions';
|
||||||
import ButtonWithIcon from '@/components/ui/button-with-icon';
|
import ButtonWithIcon from '@/components/ui/button-with-icon';
|
||||||
|
import SidebarToggleButton from './sidebar-toggle-button';
|
||||||
|
|
||||||
export default function Sidebar() {
|
export default function Sidebar() {
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
const [isSidebarOpen] = useAtom(
|
const [isSidebarOpen] = useAtom(
|
||||||
isMobile ? mobileSidebarAtom : desktopSidebarAtom
|
isMobile ? mobileSidebarAtom : desktopSidebarAtom
|
||||||
);
|
);
|
||||||
@ -22,10 +24,25 @@ export default function Sidebar() {
|
|||||||
return (
|
return (
|
||||||
<nav
|
<nav
|
||||||
className={`${
|
className={`${
|
||||||
isSidebarOpen ? 'w-[270px]' : 'w-[0px]'
|
isSidebarOpen ? (isMobile ? 'w-full' : 'w-[270px]') : 'w-[0px]'
|
||||||
} flex-grow-0 flex-shrink-0 overflow-hidden border-r duration-300 ease-in-out`}
|
} ${
|
||||||
|
isMobile && isSidebarOpen
|
||||||
|
? 'fixed top-0 left-0 h-screen z-[99] bg-background'
|
||||||
|
: ''
|
||||||
|
} flex-grow-0 flex-shrink-0 overflow-hidden border-r duration-500 ease-in-out`}
|
||||||
>
|
>
|
||||||
<div className="flex flex-col flex-shrink-0 gap-0.5 p-[10px]">
|
{isMobile && (
|
||||||
|
<>
|
||||||
|
<SidebarToggleButton
|
||||||
|
className={`absolute top-0 ${
|
||||||
|
isSidebarOpen ? 'right-0' : 'left-0'
|
||||||
|
} right-0 m-4`}
|
||||||
|
/>
|
||||||
|
<div className="mt-[20px]"></div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className={`flex flex-col flex-shrink-0 gap-0.5 p-[10px]`}>
|
||||||
<div className="h-full">
|
<div className="h-full">
|
||||||
<div className="mt-[20px]"></div>
|
<div className="mt-[20px]"></div>
|
||||||
|
|
||||||
|
|||||||
@ -1,35 +1,17 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { ReactNode } from 'react';
|
|
||||||
|
|
||||||
import { useIsMobile } from '@/hooks/use-is-mobile';
|
import { useIsMobile } from '@/hooks/use-is-mobile';
|
||||||
import {
|
import SidebarToggleButton from './sidebar-toggle-button';
|
||||||
desktopSidebarAtom,
|
|
||||||
mobileSidebarAtom,
|
|
||||||
} from '@/components/sidebar/atoms/sidebar-atom';
|
|
||||||
import { useToggleSidebar } from './hooks/use-toggle-sidebar';
|
|
||||||
import ButtonWithIcon from '../ui/button-with-icon';
|
|
||||||
import { IconLayoutSidebarLeftCollapse } from '@tabler/icons-react';
|
|
||||||
|
|
||||||
export default function TopBar() {
|
export default function TopBar() {
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
const sidebarStateAtom = isMobile ? mobileSidebarAtom : desktopSidebarAtom;
|
|
||||||
|
|
||||||
const toggleSidebar = useToggleSidebar(sidebarStateAtom);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="max-w-full z-50 select-none">
|
<header className="max-w-full z-50 select-none">
|
||||||
<div
|
<div className="w-full max-w-full h-[50px] opacity-100 relative duration-700 ease-in">
|
||||||
className="w-full max-w-full h-[50px] opacity-100 relative
|
|
||||||
transition-opacity duration-700 ease-in transition-color duration-700 ease-in"
|
|
||||||
>
|
|
||||||
<div className="flex justify-between items-center h-full overflow-hidden py-0 px-1 gap-2.5 border-b">
|
<div className="flex justify-between items-center h-full overflow-hidden py-0 px-1 gap-2.5 border-b">
|
||||||
<div className="flex items-center leading-tight h-full flex-grow-0 mr-[8px] min-w-0 font-semibold text-sm">
|
<div className="flex items-center leading-tight h-full flex-grow-0 mr-[8px] min-w-0 font-semibold text-sm">
|
||||||
<ButtonWithIcon
|
{!isMobile && <SidebarToggleButton />}
|
||||||
icon={<IconLayoutSidebarLeftCollapse size={20} />}
|
|
||||||
variant={'ghost'}
|
|
||||||
onClick={toggleSidebar}
|
|
||||||
></ButtonWithIcon>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user