Skip to content

Commit 10488d2

Browse files
committed
feat: implements new ResponsiveLayout component
1 parent 623ce7e commit 10488d2

File tree

3 files changed

+75
-34
lines changed

3 files changed

+75
-34
lines changed

src/components/ResponsiveLayout.tsx

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { cn } from "@/lib/utils.ts";
2-
import React, { useRef } from "react";
2+
import React, { forwardRef, useImperativeHandle, useRef } from "react";
33
import { Menu, X } from "lucide-react";
44

55
interface ResponsiveLayoutProps {
@@ -8,11 +8,12 @@ interface ResponsiveLayoutProps {
88
title?: string;
99
}
1010

11-
const ResponsiveLayout: React.FC<ResponsiveLayoutProps> = ({
12-
leftContent,
13-
rightContent,
14-
title,
15-
}) => {
11+
interface ResponsiveLayoutRef {
12+
closeSidebar: () => void;
13+
}
14+
15+
const ResponsiveLayout = forwardRef<ResponsiveLayoutRef, ResponsiveLayoutProps>((props, ref) => {
16+
const { leftContent, rightContent, title } = props;
1617
const sidebarRef = useRef<HTMLDivElement>(null);
1718
const backdropRef = useRef<HTMLDivElement>(null);
1819

@@ -38,12 +39,21 @@ const ResponsiveLayout: React.FC<ResponsiveLayoutProps> = ({
3839
}
3940
};
4041

42+
useImperativeHandle(
43+
ref,
44+
() => ({
45+
closeSidebar: handleClose,
46+
}),
47+
[],
48+
);
49+
4150
return (
4251
<div className="flex relative min-h-[400px]">
52+
{/* Backdrop */}
4353
<div
4454
ref={backdropRef}
4555
onClick={handleClose}
46-
className="absolute inset-0 bg-black opacity-0 pointer-events-none transition-opacity duration-100 z-[5] lg:hidden"
56+
className="fixed inset-0 bg-black opacity-0 pointer-events-none transition-opacity duration-100 z-[5] lg:hidden"
4757
/>
4858

4959
<div
@@ -55,10 +65,7 @@ const ResponsiveLayout: React.FC<ResponsiveLayoutProps> = ({
5565
)}
5666
>
5767
<div className="flex justify-end lg:hidden">
58-
<button
59-
onClick={handleClose}
60-
className="hover:bg-destructive/50 rounded p-1 transition-colors"
61-
>
68+
<button onClick={handleClose} className="hover:bg-red-300 rounded p-1 transition-colors">
6269
<X className="h-5 w-5" />
6370
</button>
6471
</div>
@@ -69,7 +76,7 @@ const ResponsiveLayout: React.FC<ResponsiveLayoutProps> = ({
6976
<div className="flex items-center gap-3 mb-4">
7077
<button
7178
onClick={handleToggle}
72-
className="lg:hidden shadow hover:shadow-md transition-all hover:bg-success/50"
79+
className="lg:hidden shadow hover:shadow-md transition-all"
7380
>
7481
<Menu className="w-4 h-4" />
7582
</button>
@@ -83,6 +90,9 @@ const ResponsiveLayout: React.FC<ResponsiveLayoutProps> = ({
8390
</div>
8491
</div>
8592
);
86-
};
93+
});
94+
95+
ResponsiveLayout.displayName = "ResponsiveLayout";
8796

8897
export default ResponsiveLayout;
98+
export type { ResponsiveLayoutRef };
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { cn } from "@/lib/utils.ts";
2+
import React from "react";
3+
4+
interface ResponsiveLayoutSidebarItem {
5+
id: string;
6+
label: string;
7+
level?: number;
8+
}
9+
10+
interface ResponsiveLayoutSidebarProps {
11+
items: ResponsiveLayoutSidebarItem[];
12+
onItemClick: (id: string) => void;
13+
title?: string;
14+
description?: string;
15+
}
16+
17+
const ResponsiveLayoutSidebar = (props: ResponsiveLayoutSidebarProps) => {
18+
const { items, onItemClick, title = "", description = "" } = props;
19+
20+
return (
21+
<>
22+
<div>{title}</div>
23+
<p>{description}</p>
24+
{items.map(item => (
25+
<button
26+
key={item.id}
27+
onClick={() => onItemClick(item.id)}
28+
className={cn(
29+
"block w-full text-left transition-colors py-1 hover:text-primary",
30+
item.level === 1 ? "ml-3 text-xs text-muted-foreground" : "text-sm",
31+
)}
32+
>
33+
{item.level === 1 ? `• ${item.label}` : item.label}
34+
</button>
35+
))}
36+
</>
37+
);
38+
};
39+
40+
ResponsiveLayoutSidebar.displayName = "ResponsiveLayout";
41+
export default ResponsiveLayoutSidebar;
42+
export type { ResponsiveLayoutSidebarItem };

src/pages/Docs/Introduction.tsx

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
1-
import { type SidebarItem } from "@/components/DocsResponsiveSidebar";
2-
import ResponsiveLayout from "@/components/ResponsiveLayout.tsx";
1+
import ResponsiveLayout, { ResponsiveLayoutRef } from "@/components/ResponsiveLayout.tsx";
2+
import ResponsiveLayoutSidebar, {
3+
ResponsiveLayoutSidebarItem,
4+
} from "@/components/ResponsiveLayoutSidebar.tsx";
35
import { Badge } from "@/components/ui/badge";
46
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
5-
import { cn } from "@/lib/utils.ts";
67
import { Layers, Package, Wrench } from "lucide-react";
7-
import React from "react";
8+
import React, { useRef } from "react";
89

910
const Introduction = () => {
11+
const layoutRef = useRef<ResponsiveLayoutRef>(null);
1012
const scrollToSection = (id: string) => {
1113
const element = document.getElementById(id);
1214
if (element) {
1315
element.scrollIntoView({ behavior: "smooth" });
1416
}
17+
layoutRef.current?.closeSidebar();
1518
};
1619

17-
const sidebarItems: SidebarItem[] = [
20+
const sidebarItems: ResponsiveLayoutSidebarItem[] = [
1821
{ id: "requisitos", label: "Começando do Começo", level: 0 },
1922
{ id: "pacotes", label: "Pacotes Principais", level: 0 },
2023
{ id: "constructo", label: "Constructo", level: 1 },
@@ -25,23 +28,9 @@ const Introduction = () => {
2528

2629
return (
2730
<ResponsiveLayout
31+
ref={layoutRef}
2832
title={"Começando do Começo"}
29-
leftContent={
30-
<div>
31-
{sidebarItems.map(item => (
32-
<button
33-
key={item.id}
34-
onClick={() => scrollToSection(item.id)}
35-
className={cn(
36-
"block w-full text-left transition-colors py-1 hover:text-primary",
37-
item.level === 1 ? "ml-3 text-xs text-muted-foreground" : "text-sm",
38-
)}
39-
>
40-
{item.level === 1 ? `• ${item.label}` : item.label}
41-
</button>
42-
))}
43-
</div>
44-
}
33+
leftContent={<ResponsiveLayoutSidebar items={sidebarItems} onItemClick={scrollToSection} />}
4534
rightContent={
4635
<div className="space-y-8">
4736
<div className="space-y-4">

0 commit comments

Comments
 (0)