diff --git a/package-lock.json b/package-lock.json index ae1fe83..11b5408 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@fontsource-variable/inter": "5.2.8", "@tabler/icons-react": "3.38.0", "@tanstack/react-table": "8.21.3", - "@vercel/speed-insights": "^2.0.0", + "@vercel/speed-insights": "2.0.0", "apexcharts": "5.10.4", "chrono-node": "2.9.0", "class-variance-authority": "0.7.1", @@ -24,6 +24,7 @@ "framer-motion": "12.34.3", "iconsax-reactjs": "0.0.8", "input-otp": "1.4.2", + "lenis": "1.3.25", "lucide-react": "0.575.0", "next": "16.2.9", "next-themes": "0.4.6", @@ -2953,7 +2954,7 @@ "version": "19.2.17", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "csstype": "^3.2.2" @@ -2963,7 +2964,7 @@ "version": "19.2.3", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "devOptional": true, + "dev": true, "license": "MIT", "peerDependencies": { "@types/react": "^19.2.0" @@ -4579,7 +4580,7 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/d3-array": { @@ -7530,6 +7531,37 @@ "node": ">=0.10" } }, + "node_modules/lenis": { + "version": "1.3.25", + "resolved": "https://registry.npmjs.org/lenis/-/lenis-1.3.25.tgz", + "integrity": "sha512-mOKxayErlaONK8fm4LN3XNd99Qu4plTpn9h9qf8wxzjGrJDzuD84FYzZ81HCd6ZsWp++VWVwOzL286Pf2s2u4A==", + "license": "MIT", + "workspaces": [ + "packages/*", + "playground", + "playground/*" + ], + "funding": { + "type": "github", + "url": "https://github.com/sponsors/darkroomengineering" + }, + "peerDependencies": { + "@nuxt/kit": ">=3.0.0", + "react": ">=17.0.0", + "vue": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + }, + "react": { + "optional": true + }, + "vue": { + "optional": true + } + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -10792,7 +10824,7 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index 1488498..058512a 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "framer-motion": "12.34.3", "iconsax-reactjs": "0.0.8", "input-otp": "1.4.2", + "lenis": "1.3.25", "lucide-react": "0.575.0", "next": "16.2.9", "next-themes": "0.4.6", diff --git a/src/app/page.tsx b/src/app/page.tsx index f65862c..0746344 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,12 +1,9 @@ import { ReactNode } from "react" import { Metadata } from "next" + // project imports import branding from "@/branding.json" -// assets -import { Star } from "@/images/svg/icons" - import { cn } from "@/lib/utils" -// project import Component1 from "@/components/uiable/blocks/landing/component-1/component-1" import Component2 from "@/components/uiable/blocks/landing/component-2/component-2" import Contact from "@/components/uiable/blocks/landing/contact/Contact" @@ -15,6 +12,10 @@ import Featured from "@/components/uiable/blocks/landing/feature/Feature" import Footer from "@/components/uiable/blocks/landing/footer/footer" import Hero from "@/components/uiable/blocks/landing/hero/hero" import Navbar from "@/components/uiable/blocks/landing/navbar/navbar" +import SmoothScroll from "@/components/uiable/blocks/landing/smooth-scroll/smooth-scroll" + +// assets +import { Star } from "@/images/svg/icons" export const metadata: Metadata = { title: `${branding.brandName} - Component Library`, @@ -75,31 +76,33 @@ function BlockArchitecture({ export default function LandingPage() { return ( -
- -
- - - - - - - - - - - - - - - - - + +
+ +
+ + + + + + + + + + + + + + + + + + +
+ +
- -
- -
+ ) } diff --git a/src/components-grid.ts b/src/components-grid.ts index 5734db1..d798b93 100644 --- a/src/components-grid.ts +++ b/src/components-grid.ts @@ -20,21 +20,21 @@ export const NAV_CATEGORIES: NavSection[] = [ { title: "Inputs", items: [ - { title: "Button", slug: "button", breakpoints: { xl: 3, md: 2, xs: 1 } }, + { title: "Button", slug: "button", breakpoints: { xl: 3, lg: 2, xs: 1 } }, { title: "Button Group", slug: "button-group", - breakpoints: { xxl: 3, md: 2, sm: 1, xs: 1 }, + breakpoints: { xxl: 3, lg: 2, sm: 1, xs: 1 }, }, { title: "Checkbox", slug: "checkbox", - breakpoints: { md: 2, sm: 2, xs: 1 }, + breakpoints: { lg: 2, xs: 1 }, }, { title: "Combobox", slug: "combobox", - breakpoints: { xl: 3, lg: 3, md: 2, sm: 1, xs: 1 }, + breakpoints: { xl: 3, lg: 2, xs: 1 }, }, { title: "Command", diff --git a/src/components/animation/TechOrbit.tsx b/src/components/animation/TechOrbit.tsx index 8a0d019..641b4c9 100644 --- a/src/components/animation/TechOrbit.tsx +++ b/src/components/animation/TechOrbit.tsx @@ -97,7 +97,6 @@ export default function TechOrbit() { className="text-muted-foreground" /> - {/* shadcn */} } /> - {/* Tailwind 2 */} } /> - {/* Code/Slash (//) */} } /> + + } + /> + + } + /> + + } + /> {/* Orbit 2 (Middle - radius ~240px) */} @@ -146,7 +164,7 @@ export default function TechOrbit() { {/* React */} } @@ -159,6 +177,20 @@ export default function TechOrbit() { orbitDirection="counter-clockwise" icon={} /> + + } + /> + + } + /> {/* Orbit 1 (Inner - radius ~140px) */} diff --git a/src/components/block-item.tsx b/src/components/block-item.tsx index fb6b00f..b1fcadb 100644 --- a/src/components/block-item.tsx +++ b/src/components/block-item.tsx @@ -2,28 +2,13 @@ import { memo, + SyntheticEvent, useCallback, useEffect, useRef, useState, - type SyntheticEvent, } from "react" -// assets -import { - ArrowUpRight, - Code, - Copy, - Monitor, - RotateCw, - Smartphone, - SquareCheckBig, - Tablet, - Terminal, -} from "lucide-react" -// third party -import { codeToHtml, type BundledLanguage } from "shiki" -import { cn } from "@/lib/utils" // shadcn import { Button, buttonVariants } from "@/components/ui/button" import { Card, CardContent, CardHeader } from "@/components/ui/card" @@ -40,8 +25,27 @@ import { TooltipContent, TooltipTrigger, } from "@/components/ui/tooltip" + +// third party +import { type BundledLanguage, codeToHtml } from "shiki" + // project import Loader from "@/components/Loader" +import { cn } from "@/lib/utils" + +// assets +import { + ArrowUpRight, + Code, + Copy, + Loader2, + Monitor, + RotateCw, + Smartphone, + SquareCheckBig, + Terminal, + Tablet, +} from "lucide-react" export interface Item { name: string @@ -55,15 +59,35 @@ export interface Item { const CodeBlock = memo( ({ children, lang }: { children: string; lang: BundledLanguage }) => { const [html, setHtml] = useState("") + const [isLoading, setIsLoading] = useState(true) + + const [prevProps, setPrevProps] = useState({ children, lang }) + if (prevProps.children !== children || prevProps.lang !== lang) { + setPrevProps({ children, lang }) + setIsLoading(true) + } + useEffect(() => { let mounted = true + setIsLoading(true) codeToHtml(children, { lang, theme: "one-dark-pro" }).then((res) => { - if (mounted) setHtml(res) + if (mounted) { + setHtml(res) + setIsLoading(false) + } }) return () => { mounted = false } }, [children, lang]) + + if (isLoading) { + return ( +
+ +
+ ) + } return (
Copy code

-
- - {/*
-
-
*/} ) } diff --git a/src/components/category-description.tsx b/src/components/category-description.tsx index a3bb69f..cd70768 100644 --- a/src/components/category-description.tsx +++ b/src/components/category-description.tsx @@ -1,9 +1,4 @@ // shadcn - -// project -import branding from "@/branding.json" -import { categoryInfoMap as componentCategoryInfoMap } from "@/data/components" - import { Accordion, AccordionContent, @@ -12,6 +7,10 @@ import { } from "@/components/ui/accordion" import { Card, CardContent } from "@/components/ui/card" +// project +import branding from "@/branding.json" +import { categoryInfoMap as componentCategoryInfoMap } from "@/data/components" + const categoryInfoMap = { ...componentCategoryInfoMap, } diff --git a/src/components/category-view.tsx b/src/components/category-view.tsx index cb9b6a2..99e6179 100644 --- a/src/components/category-view.tsx +++ b/src/components/category-view.tsx @@ -1,20 +1,23 @@ "use client" import { memo, useEffect, useMemo, useState } from "react" -// project -import { categories } from "@/components-grid" -// assets -import { Code, Copy, SquareCheckBig } from "lucide-react" -// third party -import { codeToHtml, type BundledLanguage } from "shiki" -import { cn } from "@/lib/utils" // shadcn import { Button, buttonVariants } from "@/components/ui/button" import { Card, CardContent, CardHeader } from "@/components/ui/card" import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" +// third party +import { type BundledLanguage, codeToHtml } from "shiki" + +// project +import { categories } from "@/components-grid" +import { cn } from "@/lib/utils" + +// assets +import { Code, Copy, Loader2, SquareCheckBig } from "lucide-react" + interface Item { name: string title: string @@ -33,15 +36,36 @@ interface CategoryViewProps { const CodeBlock = memo( ({ children, lang }: { children: string; lang: BundledLanguage }) => { const [html, setHtml] = useState("") + const [isLoading, setIsLoading] = useState(true) + + const [prevProps, setPrevProps] = useState({ children, lang }) + if (prevProps.children !== children || prevProps.lang !== lang) { + setPrevProps({ children, lang }) + setIsLoading(true) + } + useEffect(() => { let mounted = true + setIsLoading(true) codeToHtml(children, { lang, theme: "one-dark-pro" }).then((res) => { - if (mounted) setHtml(res) + if (mounted) { + setHtml(res) + setIsLoading(false) + } }) return () => { mounted = false } }, [children, lang]) + + if (isLoading) { + return ( +
+ +
+ ) + } + return (
-
-
) } diff --git a/src/components/uiable/blocks/landing/smooth-scroll/smooth-scroll.tsx b/src/components/uiable/blocks/landing/smooth-scroll/smooth-scroll.tsx new file mode 100644 index 0000000..3b3dc7c --- /dev/null +++ b/src/components/uiable/blocks/landing/smooth-scroll/smooth-scroll.tsx @@ -0,0 +1,14 @@ +"use client" + +import { ReactNode } from "react" +import { ReactLenis } from "lenis/react" + +// ------------------------------ | COMPONENT - SMOOTH SCROLL | ------------------------------ // + +export default function SmoothScroll({ children }: { children: ReactNode }) { + return ( + + {children} + + ) +} diff --git a/src/metrics/Notify.jsx b/src/metrics/Notify.jsx index ada0c7c..6c2c380 100644 --- a/src/metrics/Notify.jsx +++ b/src/metrics/Notify.jsx @@ -14,7 +14,7 @@ function loadNotifyScript(notifyId) { const script = document.createElement("script") script.id = "notify-script" - script.src = `https://phpstack-207002-5085356.cloudwaysapps.com/pixel/${notifyId}` + script.src = `https://fomo.codedthemes.com/pixel/${notifyId}` script.defer = true script.onload = () => {