Files
Docker/Downloads/Voltaserve/ui/src/lib/components/drawer/drawer.tsx
2024-04-21 14:42:52 +02:00

130 lines
3.3 KiB
TypeScript

import { ReactNode, useEffect, useMemo, useState } from 'react'
import { Link } from 'react-router-dom'
import cx from 'classnames'
import { StorageOptions } from '../../types'
import { IconChevronLeft, IconChevronRight } from '../icons'
import { DrawerContext } from './drawer-context'
type DrawerProps = {
children?: ReactNode
logo?: ReactNode
storage?: StorageOptions
}
export const Drawer = ({ children, storage, logo }: DrawerProps) => {
const [isCollapsed, setIsCollapsed] = useState<boolean | undefined>(undefined)
const [isTouched, setIsTouched] = useState(false)
const localStorageCollapsedKey = useMemo(
() =>
`${storage?.prefix || 'app'}_${
storage?.namespace || 'main'
}_drawer_collapsed`,
[storage],
)
useEffect(() => {
let collapse = false
if (typeof localStorage !== 'undefined') {
const value = localStorage.getItem(localStorageCollapsedKey)
if (value) {
collapse = JSON.parse(value)
} else {
localStorage.setItem(localStorageCollapsedKey, JSON.stringify(false))
}
}
if (collapse) {
setIsCollapsed(true)
} else {
setIsCollapsed(false)
}
}, [localStorageCollapsedKey, setIsCollapsed])
if (isCollapsed === undefined) {
return null
}
return (
<DrawerContext.Provider
value={{
isCollapsed,
isTouched,
}}
>
<div
className={cx(
'flex',
'flex-col',
'h-full',
'border-r',
'border-r-gray-200',
'dark:border-r-gray-700',
'shrink-0',
'gap-0',
)}
>
<div
className={cx('flex', 'items-center', 'justify-center', 'h-[80px]')}
>
<Link to="/">
<div className={cx('flex', 'h-[40px]')}>
<div
className={cx(
'flex',
'items-center',
'justify-center',
'w-[40px]',
'h-[40px]',
)}
>
{logo}
</div>
</div>
</Link>
</div>
<div
className={cx(
'flex',
'flex-col',
'items-center',
'gap-0.5',
'pt-0',
'pr-1.5',
'pb-1.5',
'pl-1.5',
)}
>
{children}
</div>
<div className={cx('grow')} />
<div
className={cx(
'flex',
'flex-row',
'items-center',
'gap-0',
{ 'justify-center': isCollapsed, 'justify-end': !isCollapsed },
'h-[50px]',
'w-full',
{ 'px-0': isCollapsed, 'px-1.5': !isCollapsed },
'cursor-pointer',
'hover:bg-gray-100',
'hover:dark:bg-gray-600',
'active:bg-gray-200',
'active:dark:bg-gray-700',
)}
onClick={() => {
setIsCollapsed(!isCollapsed)
setIsTouched(true)
localStorage.setItem(
localStorageCollapsedKey,
JSON.stringify(!isCollapsed),
)
}}
>
{isCollapsed ? <IconChevronRight /> : <IconChevronLeft />}
</div>
</div>
</DrawerContext.Provider>
)
}