From 240ca79960c8399605ff42d4a6ee5936f512129b Mon Sep 17 00:00:00 2001 From: Yashwanth1906 Date: Thu, 24 Apr 2025 11:53:32 +0530 Subject: [PATCH] [FEAT] : Added Adjustable Vertical Seperated for ContentViewer and Editor --- .../ContentViewer/ContentViewer.module.css | 14 ++-- .../EditorNOutput/EditorNOutput.module.css | 8 +- app/components/ResizableContent.tsx | 81 +++++++++++++++++++ app/content/[...markdownPath]/page.module.css | 38 ++++++++- app/content/[...markdownPath]/page.tsx | 28 +++---- 5 files changed, 140 insertions(+), 29 deletions(-) create mode 100644 app/components/ResizableContent.tsx diff --git a/app/components/ContentViewer/ContentViewer.module.css b/app/components/ContentViewer/ContentViewer.module.css index 8e98663..95b8bad 100644 --- a/app/components/ContentViewer/ContentViewer.module.css +++ b/app/components/ContentViewer/ContentViewer.module.css @@ -1,20 +1,18 @@ .content { display: flex; flex-direction: column; - overflow-y: auto; flex: 1; - padding-right: 14px; - padding-bottom: 12px; - padding-left: 14px; + padding: 14px; + height: 100%; + width: 100%; } + .contentWrapper { border-right: 1px solid hsl(var(--border-color)); - display: flex; flex-direction: column; - - height: 100%; - flex: 1; height: 100%; + width: 100%; + overflow: hidden; } diff --git a/app/components/EditorNOutput/EditorNOutput.module.css b/app/components/EditorNOutput/EditorNOutput.module.css index 79a8640..c670801 100644 --- a/app/components/EditorNOutput/EditorNOutput.module.css +++ b/app/components/EditorNOutput/EditorNOutput.module.css @@ -3,14 +3,12 @@ height: 100%; display: flex; flex-direction: column; - - max-width: 50%; + width: 100%; + overflow: hidden; } .outputWrapper { width: 100%; - - /* padding: 16px; */ display: flex; flex-direction: column; align-items: flex-start; @@ -19,11 +17,13 @@ border-left: none; height: 100%; } + .divider { width: 100%; height: 6px; background-color: hsl(var(--border-color)); cursor: row-resize; + flex-shrink: 0; } .divider:hover, diff --git a/app/components/ResizableContent.tsx b/app/components/ResizableContent.tsx new file mode 100644 index 0000000..b41815e --- /dev/null +++ b/app/components/ResizableContent.tsx @@ -0,0 +1,81 @@ +"use client"; + +import React, { useState, useRef, useEffect } from "react"; +import styles from "@/app/content/[...markdownPath]/page.module.css"; +import ContentViewer from "./ContentViewer"; +import EditorNOutput from "./EditorNOutput"; + +interface ResizableContentProps { + content: React.ReactNode; + codeFile: any; + nextStepPath: string | undefined; + stepIndex: number; + chapterIndex: number; +} + +export default function ResizableContent({ + content, + codeFile, + nextStepPath, + stepIndex, + chapterIndex, +}: ResizableContentProps) { + const [leftWidth, setLeftWidth] = useState(600); + const containerRef = useRef(null); + const isDraggingRef = useRef(false); + + const handleMouseDown = () => { + isDraggingRef.current = true; + }; + + const handleMouseUp = () => { + isDraggingRef.current = false; + }; + + const handleMouseMove = ( + e: React.MouseEvent | MouseEvent, + ) => { + if (!isDraggingRef.current) return; + + const containerRect = containerRef.current!.getBoundingClientRect(); + const newLeftWidth = e.clientX - containerRect.left; + + const minWidth = 300; + const maxWidth = containerRect.width * 0.7; + + if (newLeftWidth >= minWidth && newLeftWidth <= maxWidth) { + setLeftWidth(newLeftWidth); + localStorage.setItem("horizontalLeftWidth", String(newLeftWidth)); + } + }; + + useEffect(() => { + const savedWidth = localStorage.getItem("horizontalLeftWidth"); + if (savedWidth) { + setLeftWidth(Number(savedWidth)); + } + }, []); + + return ( +
+
+ {content} +
+
+
+ +
+
+ ); +} diff --git a/app/content/[...markdownPath]/page.module.css b/app/content/[...markdownPath]/page.module.css index 7669d38..10e3323 100644 --- a/app/content/[...markdownPath]/page.module.css +++ b/app/content/[...markdownPath]/page.module.css @@ -1,7 +1,41 @@ .mainArea { display: flex; flex-direction: row; - flex: 12; + height: calc(100vh - 60px); + width: 100%; + overflow: hidden; + position: relative; +} + +.leftPane { height: 100%; - overflow-y: auto; + overflow: hidden; + min-width: 300px; + max-width: 70%; + display: flex; +} + +.rightPane { + flex: 1; + height: 100%; + min-width: 300px; + overflow: hidden; + display: flex; +} + +.divider { + width: 4px; + height: 100%; + background-color: hsl(var(--border-color)); + cursor: col-resize; + transition: background-color 0.2s ease; + flex-shrink: 0; +} + +.divider:hover { + background-color: hsl(var(--primary) / 0.75); +} + +.divider:active { + background-color: hsl(var(--primary) / 0.75); } diff --git a/app/content/[...markdownPath]/page.tsx b/app/content/[...markdownPath]/page.tsx index c2b94a4..b2e3e4d 100644 --- a/app/content/[...markdownPath]/page.tsx +++ b/app/content/[...markdownPath]/page.tsx @@ -1,9 +1,7 @@ import { contentManager } from "@/lib/contentManager"; -import styles from "./page.module.css"; import React from "react"; import { parseLessonFolder } from "@/lib/server-functions"; -import ContentViewer from "@/app/components/ContentViewer"; -import EditorNOutput from "@/app/components/EditorNOutput"; +import ResizableContent from "@/app/components/ResizableContent"; export function generateMetadata({ params, @@ -38,28 +36,28 @@ export default async function Content({ contentManager.getPageMeta(urlPath); const { Page, metadata, codeFile } = parseLessonFolder(mdPath, codePath); + const pageContent = ; + return ( -
- - - - -
+ ); } + export async function generateStaticParams() { const outline = contentManager.getOutline(); const pathList: { markdownPath: string[] }[] = []; outline.map((item) => { item.steps.map((step) => { + const pathSegments = step.fullPath.split("/"); pathList.push({ - markdownPath: [item.folderName, step.fileName], + markdownPath: pathSegments, }); }); });