From aecc6eea12d1315da4127f6665971351929d5576 Mon Sep 17 00:00:00 2001 From: gitfromwildan <> Date: Sun, 27 Jul 2025 01:44:20 +0700 Subject: [PATCH] The version bump from 1.13.6 to 1.13.9 suggests these are mostly internal improvements and bug fixes rather than major feature additions. --- .eslintrc.json | 19 ++++++ app/docs/[[...slug]]/page.tsx | 2 +- app/page.tsx | 2 +- components/Sponsor.tsx | 70 ++++++++++++++++++++-- components/markdown/ButtonMdx.tsx | 2 - components/markdown/mdx-provider.tsx | 2 +- components/mob-toc.tsx | 2 +- components/sublink.tsx | 3 - components/toc-observer.tsx | 16 +---- components/ui/icon-cloud.tsx | 2 +- components/ui/input.tsx | 3 +- components/ui/interactive-hover-button.tsx | 3 +- lib/markdown.ts | 50 ++++++++++++---- package.json | 2 +- 14 files changed, 133 insertions(+), 45 deletions(-) create mode 100644 .eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..0851bea --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,19 @@ +{ + "extends": [ + "next/core-web-vitals", + "next/typescript", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@typescript-eslint/no-explicit-any": "warn", + "@typescript-eslint/no-unused-vars": [ + "warn", + { + "argsIgnorePattern": "^_", + "varsIgnorePattern": "^_", + "caughtErrorsIgnorePattern": "^_" + } + ], + "@typescript-eslint/no-empty-object-type": "off" + } +} diff --git a/app/docs/[[...slug]]/page.tsx b/app/docs/[[...slug]]/page.tsx index e765173..c4f6f05 100644 --- a/app/docs/[[...slug]]/page.tsx +++ b/app/docs/[[...slug]]/page.tsx @@ -68,7 +68,7 @@ export default async function DocsPage({ params: { slug = [] } }: PageProps) { if (!res) notFound(); - const { title, description, image, date } = res.frontmatter; + const { title, description, image: _image, date } = res.frontmatter; // File path for edit link const filePath = `contents/docs/${slug.join("/") || ""}/index.mdx`; diff --git a/app/page.tsx b/app/page.tsx index 2a1152d..9a0a5c8 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -25,7 +25,7 @@ export default function Home() { )} > - 🚀 New Version - Release v1.13.6 + 🚀 New Version - Release v1.13.9 diff --git a/components/Sponsor.tsx b/components/Sponsor.tsx index 783192d..def5ce0 100644 --- a/components/Sponsor.tsx +++ b/components/Sponsor.tsx @@ -10,16 +10,76 @@ interface SponsorItem { description?: string; } +interface NavbarConfig { + title?: string; + logo?: { + light?: string; + dark?: string; + }; + links?: Array<{ + title: string; + href: string; + external?: boolean; + }>; +} + +interface FooterConfig { + text?: string; + links?: Array<{ + title: string; + href: string; + external?: boolean; + }>; +} + +interface MetaConfig { + title?: string; + description?: string; + favicon?: string; + socialBanner?: string; +} + +interface RepositoryConfig { + url: string; + editUrl?: string; + branch?: string; + directory?: string; +} + +interface RouteItem { + title: string; + href: string; + noLink?: boolean; + context?: { + icon: string; + description: string; + title: string; + }; + items?: RouteItem[]; +} + +interface RouteConfig { + title: string; + href: string; + noLink?: boolean; + context?: { + icon: string; + description: string; + title: string; + }; + items?: RouteItem[]; +} + interface DocuConfig { sponsor?: { title?: string; item?: SponsorItem; }; - navbar: any; // Anda bisa mendefinisikan tipe yang lebih spesifik jika diperlukan - footer: any; - meta: any; - repository: any; - routes: any[]; + navbar: NavbarConfig; + footer: FooterConfig; + meta: MetaConfig; + repository: RepositoryConfig; + routes: RouteConfig[]; } // Type assertion for docu.json diff --git a/components/markdown/ButtonMdx.tsx b/components/markdown/ButtonMdx.tsx index e0a5a72..eee7404 100644 --- a/components/markdown/ButtonMdx.tsx +++ b/components/markdown/ButtonMdx.tsx @@ -1,8 +1,6 @@ import React from "react"; import * as Icons from "lucide-react"; import Link from "next/link"; - -type IconName = keyof typeof Icons; type ButtonProps = { icon?: keyof typeof Icons; text?: string; diff --git a/components/markdown/mdx-provider.tsx b/components/markdown/mdx-provider.tsx index 8265b8f..b2e6e0d 100644 --- a/components/markdown/mdx-provider.tsx +++ b/components/markdown/mdx-provider.tsx @@ -1,6 +1,6 @@ 'use client'; -import { MDXRemote, MDXRemoteProps } from 'next-mdx-remote/rsc'; +import { MDXRemote } from 'next-mdx-remote/rsc'; import { Kbd } from './KeyboardMdx'; // Define components mapping diff --git a/components/mob-toc.tsx b/components/mob-toc.tsx index 6a23a0a..625e5e6 100644 --- a/components/mob-toc.tsx +++ b/components/mob-toc.tsx @@ -7,7 +7,7 @@ import { useRef, useMemo } from "react"; import { usePathname } from "next/navigation"; import { Button } from "./ui/button"; import { motion, AnimatePresence } from "framer-motion"; -import { useScrollPosition, useActiveSection } from "@/hooks"; +import { useActiveSection } from "@/hooks"; import { TocItem } from "@/lib/toc"; interface MobTocProps { diff --git a/components/sublink.tsx b/components/sublink.tsx index 68f5897..eb5a425 100644 --- a/components/sublink.tsx +++ b/components/sublink.tsx @@ -32,9 +32,6 @@ export default function SubLink({ // Full path including parent's href const fullHref = `${parentHref}${href}`; - // Check if current path exactly matches this link's href - const isExactActive = useMemo(() => path === fullHref, [path, fullHref]); - // Check if any child is active (for parent items) const hasActiveChild = useMemo(() => { if (!items) return false; diff --git a/components/toc-observer.tsx b/components/toc-observer.tsx index b0d8a4f..1d595db 100644 --- a/components/toc-observer.tsx +++ b/components/toc-observer.tsx @@ -1,6 +1,5 @@ "use client"; -import { getDocsTocs } from "@/lib/markdown"; import clsx from "clsx"; import Link from "next/link"; import { useState, useRef, useEffect, useCallback } from "react"; @@ -110,7 +109,6 @@ export default function TocObserver({ // Calculate scroll progress for the active section const [scrollProgress, setScrollProgress] = useState(0); - const [activeSectionIndex, setActiveSectionIndex] = useState(0); useEffect(() => { const handleScroll = () => { @@ -137,15 +135,6 @@ export default function TocObserver({ return () => window.removeEventListener('scroll', handleScroll); }, [activeId]); - // Update active section index when activeId changes - useEffect(() => { - if (activeId) { - const index = data.findIndex(item => item.href.slice(1) === activeId); - if (index !== -1) { - setActiveSectionIndex(index); - } - } - }, [activeId, data]); return (
@@ -155,8 +144,9 @@ export default function TocObserver({ const id = href.slice(1); const isActive = activeId === id; const indent = level > 1 ? (level - 1) * 20 : 0; - const isParent = hasChildren(id, level); - const isLastInLevel = index === data.length - 1 || data[index + 1].level <= level; + // Prefix with underscore to indicate intentionally unused + const _isParent = hasChildren(id, level); + const _isLastInLevel = index === data.length - 1 || data[index + 1].level <= level; return (
diff --git a/components/ui/icon-cloud.tsx b/components/ui/icon-cloud.tsx index c151d60..1f6136e 100644 --- a/components/ui/icon-cloud.tsx +++ b/components/ui/icon-cloud.tsx @@ -24,7 +24,7 @@ function easeOutCubic(t: number): number { export function IconCloud({ icons, images }: IconCloudProps) { const canvasRef = useRef(null); const [iconPositions, setIconPositions] = useState([]); - const [rotation, setRotation] = useState({ x: 0, y: 0 }); + const [rotation] = useState({ x: 0, y: 0 }); const [isDragging, setIsDragging] = useState(false); const [lastMousePos, setLastMousePos] = useState({ x: 0, y: 0 }); const [mousePos, setMousePos] = useState({ x: 0, y: 0 }); diff --git a/components/ui/input.tsx b/components/ui/input.tsx index 677d05f..aba38dc 100644 --- a/components/ui/input.tsx +++ b/components/ui/input.tsx @@ -2,8 +2,7 @@ import * as React from "react" import { cn } from "@/lib/utils" -export interface InputProps - extends React.InputHTMLAttributes {} +export type InputProps = React.InputHTMLAttributes; const Input = React.forwardRef( ({ className, type, ...props }, ref) => { diff --git a/components/ui/interactive-hover-button.tsx b/components/ui/interactive-hover-button.tsx index 46cf526..e150f87 100644 --- a/components/ui/interactive-hover-button.tsx +++ b/components/ui/interactive-hover-button.tsx @@ -2,8 +2,7 @@ import React from "react"; import { ArrowRight } from "lucide-react"; import { cn } from "@/lib/utils"; -interface InteractiveHoverButtonProps - extends React.ButtonHTMLAttributes {} +type InteractiveHoverButtonProps = React.ButtonHTMLAttributes; export const InteractiveHoverButton = React.forwardRef< HTMLButtonElement, diff --git a/lib/markdown.ts b/lib/markdown.ts index f4f4764..341bf23 100644 --- a/lib/markdown.ts +++ b/lib/markdown.ts @@ -8,8 +8,26 @@ import rehypeSlug from "rehype-slug"; import rehypeCodeTitles from "rehype-code-titles"; import { page_routes, ROUTES } from "./routes-config"; import { visit } from "unist-util-visit"; +import type { Node } from "unist"; import matter from "gray-matter"; +// Type definitions for unist-util-visit +interface Element extends Node { + type: string; + tagName?: string; + properties?: Record & { + raw?: string; + }; + children?: Node[]; + value?: string; + raw?: string; // For internal use in processing +} + +interface TextNode extends Node { + type: 'text'; + value: string; +} + // custom components imports import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import Pre from "@/components/markdown/PreMdx"; @@ -139,11 +157,11 @@ function justGetFrontmatterFromMD(rawMd: string): Frontmatter { } export async function getAllChilds(pathString: string) { - const items = pathString.split("/").filter((it) => it != ""); + const items = pathString.split("/").filter((it) => it !== ""); let page_routes_copy = ROUTES; let prevHref = ""; - for (let it of items) { + for (const it of items) { const found = page_routes_copy.find((innerIt) => innerIt.href == `/${it}`); if (!found) break; prevHref += found.href; @@ -170,20 +188,28 @@ export async function getAllChilds(pathString: string) { } // for copying the code in pre -const preProcess = () => (tree: any) => { - visit(tree, (node) => { - if (node?.type === "element" && node?.tagName === "pre") { - const [codeEl] = node.children; - if (codeEl.tagName !== "code") return; - node.raw = codeEl.children?.[0].value; +const preProcess = () => (tree: Node) => { + visit(tree, (node: Node) => { + const element = node as Element; + if (element?.type === "element" && element?.tagName === "pre" && element.children) { + const [codeEl] = element.children as Element[]; + if (codeEl.tagName !== "code" || !codeEl.children?.[0]) return; + + const textNode = codeEl.children[0] as TextNode; + if (textNode.type === 'text' && textNode.value) { + element.raw = textNode.value; + } } }); }; -const postProcess = () => (tree: any) => { - visit(tree, "element", (node) => { - if (node?.type === "element" && node?.tagName === "pre") { - node.properties["raw"] = node.raw; +const postProcess = () => (tree: Node) => { + visit(tree, "element", (node: Node) => { + const element = node as Element; + if (element?.type === "element" && element?.tagName === "pre") { + if (element.properties && element.raw) { + element.properties.raw = element.raw; + } } }); }; diff --git a/package.json b/package.json index 4ba5e8d..67e142b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "docubook", - "version": "1.13.6", + "version": "1.13.9", "private": true, "scripts": { "dev": "next dev",