Skip to content

Commit 3580ea6

Browse files
authored
fix: update overall layout due to scroll-lock bug (#66)
Resolves #65
1 parent ed77023 commit 3580ea6

File tree

6 files changed

+58
-52
lines changed

6 files changed

+58
-52
lines changed

index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242

4343
<meta name="theme-color" content="#fff" />
4444
</head>
45-
<body>
45+
<body class="group/body">
4646
<div id="root"></div>
4747
<script type="module" src="/src/main.tsx"></script>
4848
</body>

src/components/layout/header.tsx

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,46 @@ import { cn } from '@/lib/utils'
33
import { Separator } from '@/components/ui/separator'
44
import { SidebarTrigger } from '@/components/ui/sidebar'
55

6-
interface HeaderProps extends React.HTMLAttributes<React.ElementRef<'header'>> {
7-
sticky?: boolean
6+
interface HeaderProps extends React.HTMLAttributes<HTMLElement> {
7+
fixed?: boolean
8+
ref?: React.Ref<HTMLElement>
89
}
910

10-
export const Header = React.forwardRef<React.ElementRef<'header'>, HeaderProps>(
11-
({ className, sticky, children, ...props }, ref) => {
12-
const [offset, setOffset] = React.useState(0)
11+
export const Header = ({
12+
className,
13+
fixed,
14+
children,
15+
...props
16+
}: HeaderProps) => {
17+
const [offset, setOffset] = React.useState(0)
1318

14-
React.useEffect(() => {
15-
const onScroll = () => {
16-
setOffset(document.body.scrollTop || document.documentElement.scrollTop)
17-
}
19+
React.useEffect(() => {
20+
const onScroll = () => {
21+
setOffset(document.body.scrollTop || document.documentElement.scrollTop)
22+
}
1823

19-
// Add scroll listener to the body
20-
document.addEventListener('scroll', onScroll, { passive: true })
24+
// Add scroll listener to the body
25+
document.addEventListener('scroll', onScroll, { passive: true })
2126

22-
// Clean up the event listener on unmount
23-
return () => document.removeEventListener('scroll', onScroll)
24-
}, [])
27+
// Clean up the event listener on unmount
28+
return () => document.removeEventListener('scroll', onScroll)
29+
}, [])
30+
31+
return (
32+
<header
33+
className={cn(
34+
'flex items-center gap-3 sm:gap-4 bg-background p-4 h-16',
35+
fixed && 'header-fixed peer/header w-[inherit] fixed z-50 rounded-md',
36+
offset > 10 && fixed ? 'shadow' : 'shadow-none',
37+
className
38+
)}
39+
{...props}
40+
>
41+
<SidebarTrigger variant='outline' className='scale-125 sm:scale-100' />
42+
<Separator orientation='vertical' className='h-6' />
43+
{children}
44+
</header>
45+
)
46+
}
2547

26-
return (
27-
<header
28-
ref={ref}
29-
className={cn(
30-
'flex items-center gap-3 sm:gap-4 bg-background p-4 h-16',
31-
sticky && 'sticky top-0 z-20',
32-
offset > 10 && sticky ? 'shadow' : 'shadow-none',
33-
className
34-
)}
35-
{...props}
36-
>
37-
<SidebarTrigger variant='outline' className='scale-125 sm:scale-100' />
38-
<Separator orientation='vertical' className='h-6' />
39-
{children}
40-
</header>
41-
)
42-
}
43-
)
4448
Header.displayName = 'Header'

src/components/layout/main.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
import React from 'react'
22
import { cn } from '@/lib/utils'
33

4-
interface MainProps extends React.HTMLAttributes<React.ElementRef<'main'>> {
4+
interface MainProps extends React.HTMLAttributes<HTMLElement> {
55
fixed?: boolean
6+
ref?: React.Ref<HTMLElement>
7+
}
8+
9+
export const Main = ({ fixed, ...props }: MainProps) => {
10+
return (
11+
<main
12+
className={cn(
13+
'peer-[.header-fixed]/header:mt-16',
14+
'px-4 py-6',
15+
fixed && 'fixed-main flex flex-col flex-grow overflow-hidden'
16+
)}
17+
{...props}
18+
/>
19+
)
620
}
721

8-
export const Main = React.forwardRef<React.ElementRef<'main'>, MainProps>(
9-
({ fixed, ...props }, ref) => {
10-
return (
11-
<main
12-
ref={ref}
13-
className={cn(
14-
'px-4 py-6',
15-
fixed && 'flex flex-col flex-grow overflow-hidden'
16-
)}
17-
{...props}
18-
/>
19-
)
20-
}
21-
)
2222
Main.displayName = 'Main'

src/features/tasks/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export default function Tasks() {
2525
return (
2626
<TasksContextProvider value={{ open, setOpen, currentRow, setCurrentRow }}>
2727
{/* ===== Top Heading ===== */}
28-
<Header sticky>
28+
<Header fixed>
2929
<Search />
3030
<div className='ml-auto flex items-center space-x-4'>
3131
<ThemeSwitch />

src/features/users/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default function Users() {
2929
return (
3030
<UsersContextProvider value={{ open, setOpen, currentRow, setCurrentRow }}>
3131
{/* ===== Top Heading ===== */}
32-
<Header sticky>
32+
<Header fixed>
3333
<Search />
3434
<div className='ml-auto flex items-center space-x-4'>
3535
<ThemeSwitch />

src/routes/_authenticated/route.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ function RouteComponent() {
2121
id='content'
2222
className={cn(
2323
'max-w-full w-full ml-auto',
24-
'peer-data-[state=collapsed]:w-[calc(100%-var(--sidebar-width-icon))]',
24+
'peer-data-[state=collapsed]:w-[calc(100%-var(--sidebar-width-icon)-1rem)]',
2525
'peer-data-[state=expanded]:w-[calc(100%-var(--sidebar-width))]',
2626
'transition-[width] ease-linear duration-200',
27-
'h-svh flex flex-col'
27+
'h-svh flex flex-col',
28+
'group-data-[scroll-locked=1]/body:h-full',
29+
'group-data-[scroll-locked=1]/body:has-[main.fixed-main]:h-svh'
2830
)}
2931
>
3032
<Outlet />

0 commit comments

Comments
 (0)