teableio/teable

View on GitHub
apps/nextjs-app/src/features/app/components/sidebar/Sidebar.tsx

Summary

Maintainability
A
0 mins
Test Coverage
import { ChevronsLeft } from '@teable/icons';
import { useIsMobile } from '@teable/sdk';
import { Button, cn } from '@teable/ui-lib';
import type { FC, PropsWithChildren, ReactNode } from 'react';
import { useState } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';
import { SIDE_BAR_WIDTH } from '../toggle-side-bar/constant';
import { HoverWrapper } from '../toggle-side-bar/HoverWrapper';
import { SheetWrapper } from '../toggle-side-bar/SheetWrapper';
import { SidebarHeader } from './SidebarHeader';

interface ISidebarProps {
  headerLeft: ReactNode;
}

export const Sidebar: FC<PropsWithChildren<ISidebarProps>> = (props) => {
  const { headerLeft, children } = props;
  const isMobile = useIsMobile();
  const [leftVisible, setLeftVisible] = useState(true);

  useHotkeys(`meta+b`, () => {
    setLeftVisible(!leftVisible);
  });

  return (
    <>
      {isMobile ? (
        <SheetWrapper>
          <div className="group/sidebar flex size-full flex-col overflow-hidden bg-popover p-5">
            <SidebarHeader headerLeft={headerLeft} />
            {children}
          </div>
        </SheetWrapper>
      ) : (
        <div
          className={cn('flex w-0 border-r flex-shrink-0 h-full', {
            'overflow-hidden': !leftVisible,
            'w-72': leftVisible,
          })}
        >
          <div className="group/sidebar flex size-full flex-col overflow-hidden bg-popover">
            <SidebarHeader headerLeft={headerLeft} onExpand={() => setLeftVisible(!leftVisible)} />
            {leftVisible && children}
          </div>
        </div>
      )}

      {!isMobile && !leftVisible && (
        <HoverWrapper size={SIDE_BAR_WIDTH}>
          <HoverWrapper.Trigger>
            <Button
              className={cn('absolute top-7 p-1 rounded-none -left-0 rounded-r-full z-40')}
              variant={'outline'}
              size="xs"
              onClick={() => {
                setLeftVisible(!leftVisible);
              }}
            >
              <ChevronsLeft className="size-5 rotate-180" />
            </Button>
          </HoverWrapper.Trigger>
          <HoverWrapper.content>
            <div className="group/sidebar flex size-full flex-col overflow-hidden bg-popover">
              <SidebarHeader headerLeft={headerLeft} />
              {children}
            </div>
          </HoverWrapper.content>
        </HoverWrapper>
      )}
    </>
  );
};