forked from crowetic/commerce
.vscode
packages
site
assets
components
auth
cart
checkout
common
icons
product
ui
Button
Collapse
Container
Grid
Hero
Input
Link
LoadingDots
Logo
Marquee
Modal
Quantity
Rating
Sidebar
Sidebar.module.css
Sidebar.tsx
index.ts
Skeleton
Text
README.md
context.tsx
index.ts
wishlist
search.tsx
config
lib
pages
public
.env.template
.eslintrc
.gitignore
.prettierignore
.prettierrc
commerce-config.js
commerce.config.json
global.d.ts
next-env.d.ts
next.config.js
package.json
postcss.config.js
tailwind.config.js
tsconfig.json
.editorconfig
.gitignore
.prettierignore
.prettierrc
README.md
license.md
package.json
turbo.json
yarn.lock
59 lines
1.5 KiB
TypeScript
59 lines
1.5 KiB
TypeScript
import { FC, useEffect, useRef } from 'react'
|
|
import s from './Sidebar.module.css'
|
|
import cn from 'clsx'
|
|
import { disableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock'
|
|
|
|
interface SidebarProps {
|
|
children: any
|
|
onClose: () => void
|
|
}
|
|
|
|
const Sidebar: FC<SidebarProps> = ({ children, onClose }) => {
|
|
const sidebarRef = useRef() as React.MutableRefObject<HTMLDivElement>
|
|
const contentRef = useRef() as React.MutableRefObject<HTMLDivElement>
|
|
|
|
const onKeyDownSidebar = (event: React.KeyboardEvent<HTMLDivElement>) => {
|
|
if (event.code === 'Escape') {
|
|
onClose()
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (sidebarRef.current) {
|
|
sidebarRef.current.focus()
|
|
}
|
|
|
|
const contentElement = contentRef.current
|
|
|
|
if (contentElement) {
|
|
disableBodyScroll(contentElement, { reserveScrollBarGap: true })
|
|
}
|
|
|
|
return () => {
|
|
clearAllBodyScrollLocks()
|
|
}
|
|
}, [])
|
|
|
|
return (
|
|
<div
|
|
className={cn(s.root)}
|
|
ref={sidebarRef}
|
|
onKeyDown={onKeyDownSidebar}
|
|
tabIndex={1}
|
|
>
|
|
<div className="absolute inset-0 overflow-hidden">
|
|
<div className={s.backdrop} onClick={onClose} />
|
|
<section className="absolute inset-y-0 right-0 w-full md:w-auto max-w-full flex outline-none md:pl-10">
|
|
<div className="h-full w-full md:w-screen md:max-w-md">
|
|
<div className={s.sidebar} ref={contentRef}>
|
|
{children}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default Sidebar
|