Skip to content
This repository was archived by the owner on Mar 2, 2026. It is now read-only.

feat(docs): add animated framer-style UI, resizable sidebar, and mobile improvements#1

Open
youngcoder45 wants to merge 2 commits intomainfrom
yc45
Open

feat(docs): add animated framer-style UI, resizable sidebar, and mobile improvements#1
youngcoder45 wants to merge 2 commits intomainfrom
yc45

Conversation

@youngcoder45
Copy link
Contributor

SO I HAVE JUST TRIED MY BEST TO ADD REACTBITS TO THE SITE. https://reactbits.dev/

Added components

  • Added animated UI components including an animated background grid, spotlight-style cards, word reveal effects, magnetic hover interactions, and scrambled/decrypted title text.
  • These components are used to enhance visual feedback and interactivity without affecting content structure.

Resizable and mobile UI

  • Implemented resizable panels for desktop layouts to allow flexible sidebar widths.
  • Added a mobile sheet/drawer pattern to replace the sidebar on smaller screens, improving usability and space efficiency.

Layout and integration

  • Updated the main layout to include the animated background component.
  • Integrated a desktop resizable sidebar and a mobile sheet-based menu.
  • Adjusted layout height using a viewport-based calculation so the sidebar remains effectively sticky during scrolling.

Documentation pages

  • Replaced static headers with animated text reveal components.
  • Replaced list-style cards with spotlight-style interactive cards.
  • Wrapped markdown content in a glass-style container for a cleaner and more modern presentation.

Sidebar polish

  • Preserved magnetic hover interactions for sidebar navigation.
  • Replaced bright gradients with a more professional solid or soft tint for active and hover states.
  • Refined the dot indicator to better match the updated visual style.

Copilot AI review requested due to automatic review settings January 25, 2026 09:35
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a set of animated “framer-style” UI components and integrates them into the docs pages, alongside a new resizable desktop sidebar and a mobile sheet-based navigation.

Changes:

  • Introduces new animated UI primitives (text reveal, decrypted text, spotlight cards, retro grid, magnet hover).
  • Reworks /pages layout with desktop resizable panels and a mobile drawer menu.
  • Updates docs index + docs content pages to use the new animated header/cards and adds supporting global CSS animations.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
components/ui/sheet.tsx Adds a Radix-based sheet component for the mobile drawer UI.
components/ui/resizable.tsx Adds wrappers around react-resizable-panels for resizable desktop layout.
components/sidebar-nav.tsx Updates sidebar nav styling/animation using Magnet + Motion.
components/framer/text-reveal.tsx Adds animated word-by-word reveal component for headers.
components/framer/spotlight.tsx Adds spotlight-hover card container used for docs cards.
components/framer/retro-grid.tsx Adds animated background grid used in docs layout.
components/framer/magnet.tsx Adds magnetic hover wrapper used by sidebar nav items.
components/framer/decrypted-text.tsx Adds decrypted/scramble text effect for sidebar headings.
app/pages/page.tsx Updates docs index header/cards to use new animated components.
app/pages/layout.tsx Integrates background, mobile sheet nav, and resizable desktop sidebar.
app/pages/[slug]/page.tsx Updates docs content page header/container styling with animation.
app/globals.css Adds keyframes/classes used by the retro grid / shine effects.
Comments suppressed due to low confidence (2)

components/sidebar-nav.tsx:13

  • SidebarNavProps extends React.HTMLAttributes, but the file does not import React (or import type React from "react"). This will fail TypeScript compilation (Cannot find namespace 'React'). Add the missing React type import or rewrite the types to avoid the React. namespace.
interface SidebarNavProps extends React.HTMLAttributes<HTMLElement> {
  items: {
    href: string;
    title: string;
  }[];

app/pages/layout.tsx:17

  • This layout types children as React.ReactNode but does not import React (or import type React from "react"), which will fail TypeScript compilation (Cannot find namespace 'React'). Also, Link is imported but unused. Add the missing React type import and remove the unused Link import.
import { getAllPages } from '@/lib/pages';
import Link from 'next/link';
import { LandingFooter } from "@/features/landing-page/components/footer";
import { SidebarNav } from "@/components/sidebar-nav";
import { ScrollArea } from "@/components/ui/scroll-area";
import RetroGrid from "@/components/framer/retro-grid";
import DecryptedText from '@/components/framer/decrypted-text';
import { Button } from "@/components/ui/button";
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet";
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "@/components/ui/resizable";
import { Menu } from "lucide-react";

export default function PagesLayout({
  children,
}: {
  children: React.ReactNode;
}) {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +6 to +13
interface MagnetProps {
children: React.ReactNode;
magnetStrength?: number;
active?: boolean;
}

export default function Magnet({ children, magnetStrength = 2, active = false }: MagnetProps) {
const [position, setPosition] = useState({ x: 0, y: 0 });
Copy link

Copilot AI Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This component uses React.ReactNode/React.MouseEvent types but never imports React (or import type React from "react"), which will fail TypeScript compilation. Also, the active prop is declared but unused; either implement its behavior or remove it to avoid a misleading API.

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +36
<motion.div
style={{ position: "relative", display: 'inline-block', width: '100%' }}
ref={ref}
onMouseMove={handleMouseMove}
onMouseLeave={reset}
animate={{ x: x / magnetStrength, y: y / magnetStrength }}
transition={{ type: "spring", stiffness: 150, damping: 15, mass: 0.1 }}
Copy link

Copilot AI Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The wrapper is hard-coded to width: '100%', which forces full-width layout wherever Magnet is used (e.g., SidebarNav in horizontal mode) and can cause overflow/spacing issues. Prefer letting the caller control sizing via className/style, or only apply w-full where it’s actually needed.

Copilot uses AI. Check for mistakes.
Comment on lines +8 to +24
interface DecryptedTextProps {
text: string;
speed?: number;
maxIterations?: number;
className?: string;
animateOnHover?: boolean;
revealDirection?: "start" | "end" | "center";
}

export default function DecryptedText({
text,
speed = 50,
maxIterations = 20,
className,
animateOnHover = true,
revealDirection = "start"
}: DecryptedTextProps) {
Copy link

Copilot AI Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maxIterations and revealDirection are exposed in the props and defaulted in the function signature, but they are never used. This makes the component API misleading and will typically trigger unused-variable lint/TS warnings. Either implement these options (e.g., cap iterations and support reveal direction) or remove them from the public props.

Copilot uses AI. Check for mistakes.
Comment on lines +25 to +63
const [displayText, setDisplayText] = useState(text);
const [isScrambling, setIsScrambling] = useState(false);
const intervalRef = useRef<any>(null);

const scramble = () => {
if (isScrambling) return;
setIsScrambling(true);

let iteration = 0;

clearInterval(intervalRef.current);

intervalRef.current = setInterval(() => {
setDisplayText(
text
.split("")
.map((letter, index) => {
if (index < iteration) {
return text[index];
}
return letters[Math.floor(Math.random() * letters.length)];
})
.join("")
);

if (iteration >= text.length) {
clearInterval(intervalRef.current);
setIsScrambling(false);
}

iteration += 1 / 3;
}, speed);
};

useEffect(() => {
// Optional: Scramble on mount
// scramble();
return () => clearInterval(intervalRef.current);
}, []);
Copy link

Copilot AI Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

intervalRef is typed as any, and displayText is initialized from text but never updated if the text prop changes. This can lead to stale UI and makes it easy to miss interval cleanup issues. Prefer typing the ref as ReturnType<typeof setInterval> | null and add an effect to reset displayText (and clear any running interval) when text changes.

Copilot uses AI. Check for mistakes.
Comment on lines +23 to +30
const handleMouseMove = (e: MouseEvent<HTMLDivElement>) => {
if (!divRef.current || isFocused) return;

const div = divRef.current;
const rect = div.getBoundingClientRect();

setPosition({ x: e.clientX - rect.left, y: e.clientY - rect.top });
};
Copy link

Copilot AI Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handleMouseMove calls setPosition on every mouse move, which forces a React re-render per pointer event and can cause noticeable jank on lower-end devices. Consider using motion values / CSS variables (and updating them via requestAnimationFrame) so pointer tracking doesn’t re-render the whole card each time.

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +17
className={cn(
"pointer-events-none absolute h-full w-full overflow-hidden opacity-50 [perspective:200px]",
className,
)}
style={{ "--grid-angle": `${angle}deg` } as React.CSSProperties}
>
Copy link

Copilot AI Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file casts to React.CSSProperties but does not import React (or import type React from "react"), which will fail TypeScript compilation (Cannot find namespace 'React'). Add the missing type import or avoid the React. namespace by using CSSProperties imported from react.

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +14
<div className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
<TextReveal text="Documentation" />
</div>
Copy link

Copilot AI Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This page replaces the <h1> with a <div>, which removes the semantic top-level heading for the page (hurts accessibility and SEO). Keep an actual <h1> and render/animate TextReveal inside it so the heading semantics remain intact.

Suggested change
<div className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
<TextReveal text="Documentation" />
</div>
<h1 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
<TextReveal text="Documentation" />
</h1>

Copilot uses AI. Check for mistakes.
@@ -2,6 +2,7 @@ import { getPageBySlug, getAllPages } from '@/lib/pages';
import ReactMarkdown from 'react-markdown';
import { notFound } from 'next/navigation';
import { LandingFooter } from "@/features/landing-page/components/footer";
Copy link

Copilot AI Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LandingFooter is imported but no longer used in this file. This will produce an unused import warning/error under common TS/ESLint configs; remove the import.

Suggested change
import { LandingFooter } from "@/features/landing-page/components/footer";

Copilot uses AI. Check for mistakes.
Comment on lines +28 to +30
<div className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl capitalize">
<TextReveal text={page.title} />
</div>
Copy link

Copilot AI Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This page replaces the <h1> with a <div>, which removes the semantic main heading for the page (accessibility/SEO regression). Prefer keeping the <h1> element and placing the TextReveal animation inside it so the document outline remains correct.

Suggested change
<div className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl capitalize">
<TextReveal text={page.title} />
</div>
<h1 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl capitalize">
<TextReveal text={page.title} />
</h1>

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,74 @@
'use client';
import React, { useRef, useState,MouseEvent } from 'react';
import { motion } from 'motion/react';
Copy link

Copilot AI Jan 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import motion.

Suggested change
import { motion } from 'motion/react';

Copilot uses AI. Check for mistakes.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants