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.
This commit is contained in:
19
.eslintrc.json
Normal file
19
.eslintrc.json
Normal file
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -68,7 +68,7 @@ export default async function DocsPage({ params: { slug = [] } }: PageProps) {
|
|||||||
|
|
||||||
if (!res) notFound();
|
if (!res) notFound();
|
||||||
|
|
||||||
const { title, description, image, date } = res.frontmatter;
|
const { title, description, image: _image, date } = res.frontmatter;
|
||||||
|
|
||||||
// File path for edit link
|
// File path for edit link
|
||||||
const filePath = `contents/docs/${slug.join("/") || ""}/index.mdx`;
|
const filePath = `contents/docs/${slug.join("/") || ""}/index.mdx`;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export default function Home() {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<AnimatedShinyText className="inline-flex items-center justify-center px-4 py-1 transition ease-out hover:text-neutral-100 hover:duration-300 hover:dark:text-neutral-200">
|
<AnimatedShinyText className="inline-flex items-center justify-center px-4 py-1 transition ease-out hover:text-neutral-100 hover:duration-300 hover:dark:text-neutral-200">
|
||||||
<span>🚀 New Version - Release v1.13.6</span>
|
<span>🚀 New Version - Release v1.13.9</span>
|
||||||
<ArrowRightIcon className="ml-1 size-3 transition-transform duration-300 ease-in-out group-hover:translate-x-0.5" />
|
<ArrowRightIcon className="ml-1 size-3 transition-transform duration-300 ease-in-out group-hover:translate-x-0.5" />
|
||||||
</AnimatedShinyText>
|
</AnimatedShinyText>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,16 +10,76 @@ interface SponsorItem {
|
|||||||
description?: string;
|
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 {
|
interface DocuConfig {
|
||||||
sponsor?: {
|
sponsor?: {
|
||||||
title?: string;
|
title?: string;
|
||||||
item?: SponsorItem;
|
item?: SponsorItem;
|
||||||
};
|
};
|
||||||
navbar: any; // Anda bisa mendefinisikan tipe yang lebih spesifik jika diperlukan
|
navbar: NavbarConfig;
|
||||||
footer: any;
|
footer: FooterConfig;
|
||||||
meta: any;
|
meta: MetaConfig;
|
||||||
repository: any;
|
repository: RepositoryConfig;
|
||||||
routes: any[];
|
routes: RouteConfig[];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type assertion for docu.json
|
// Type assertion for docu.json
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import * as Icons from "lucide-react";
|
import * as Icons from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
||||||
type IconName = keyof typeof Icons;
|
|
||||||
type ButtonProps = {
|
type ButtonProps = {
|
||||||
icon?: keyof typeof Icons;
|
icon?: keyof typeof Icons;
|
||||||
text?: string;
|
text?: string;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { MDXRemote, MDXRemoteProps } from 'next-mdx-remote/rsc';
|
import { MDXRemote } from 'next-mdx-remote/rsc';
|
||||||
import { Kbd } from './KeyboardMdx';
|
import { Kbd } from './KeyboardMdx';
|
||||||
|
|
||||||
// Define components mapping
|
// Define components mapping
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { useRef, useMemo } from "react";
|
|||||||
import { usePathname } from "next/navigation";
|
import { usePathname } from "next/navigation";
|
||||||
import { Button } from "./ui/button";
|
import { Button } from "./ui/button";
|
||||||
import { motion, AnimatePresence } from "framer-motion";
|
import { motion, AnimatePresence } from "framer-motion";
|
||||||
import { useScrollPosition, useActiveSection } from "@/hooks";
|
import { useActiveSection } from "@/hooks";
|
||||||
import { TocItem } from "@/lib/toc";
|
import { TocItem } from "@/lib/toc";
|
||||||
|
|
||||||
interface MobTocProps {
|
interface MobTocProps {
|
||||||
|
|||||||
@@ -32,9 +32,6 @@ export default function SubLink({
|
|||||||
// Full path including parent's href
|
// Full path including parent's href
|
||||||
const fullHref = `${parentHref}${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)
|
// Check if any child is active (for parent items)
|
||||||
const hasActiveChild = useMemo(() => {
|
const hasActiveChild = useMemo(() => {
|
||||||
if (!items) return false;
|
if (!items) return false;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { getDocsTocs } from "@/lib/markdown";
|
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useState, useRef, useEffect, useCallback } from "react";
|
import { useState, useRef, useEffect, useCallback } from "react";
|
||||||
@@ -110,7 +109,6 @@ export default function TocObserver({
|
|||||||
|
|
||||||
// Calculate scroll progress for the active section
|
// Calculate scroll progress for the active section
|
||||||
const [scrollProgress, setScrollProgress] = useState(0);
|
const [scrollProgress, setScrollProgress] = useState(0);
|
||||||
const [activeSectionIndex, setActiveSectionIndex] = useState(0);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleScroll = () => {
|
const handleScroll = () => {
|
||||||
@@ -137,15 +135,6 @@ export default function TocObserver({
|
|||||||
return () => window.removeEventListener('scroll', handleScroll);
|
return () => window.removeEventListener('scroll', handleScroll);
|
||||||
}, [activeId]);
|
}, [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 (
|
return (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
@@ -155,8 +144,9 @@ export default function TocObserver({
|
|||||||
const id = href.slice(1);
|
const id = href.slice(1);
|
||||||
const isActive = activeId === id;
|
const isActive = activeId === id;
|
||||||
const indent = level > 1 ? (level - 1) * 20 : 0;
|
const indent = level > 1 ? (level - 1) * 20 : 0;
|
||||||
const isParent = hasChildren(id, level);
|
// Prefix with underscore to indicate intentionally unused
|
||||||
const isLastInLevel = index === data.length - 1 || data[index + 1].level <= level;
|
const _isParent = hasChildren(id, level);
|
||||||
|
const _isLastInLevel = index === data.length - 1 || data[index + 1].level <= level;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={href} className="relative">
|
<div key={href} className="relative">
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ function easeOutCubic(t: number): number {
|
|||||||
export function IconCloud({ icons, images }: IconCloudProps) {
|
export function IconCloud({ icons, images }: IconCloudProps) {
|
||||||
const canvasRef = useRef<HTMLCanvasElement>(null);
|
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||||
const [iconPositions, setIconPositions] = useState<Icon[]>([]);
|
const [iconPositions, setIconPositions] = useState<Icon[]>([]);
|
||||||
const [rotation, setRotation] = useState({ x: 0, y: 0 });
|
const [rotation] = useState({ x: 0, y: 0 });
|
||||||
const [isDragging, setIsDragging] = useState(false);
|
const [isDragging, setIsDragging] = useState(false);
|
||||||
const [lastMousePos, setLastMousePos] = useState({ x: 0, y: 0 });
|
const [lastMousePos, setLastMousePos] = useState({ x: 0, y: 0 });
|
||||||
const [mousePos, setMousePos] = useState({ x: 0, y: 0 });
|
const [mousePos, setMousePos] = useState({ x: 0, y: 0 });
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ import * as React from "react"
|
|||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
export interface InputProps
|
export type InputProps = React.InputHTMLAttributes<HTMLInputElement>;
|
||||||
extends React.InputHTMLAttributes<HTMLInputElement> {}
|
|
||||||
|
|
||||||
const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||||
({ className, type, ...props }, ref) => {
|
({ className, type, ...props }, ref) => {
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ import React from "react";
|
|||||||
import { ArrowRight } from "lucide-react";
|
import { ArrowRight } from "lucide-react";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
interface InteractiveHoverButtonProps
|
type InteractiveHoverButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement>;
|
||||||
extends React.ButtonHTMLAttributes<HTMLButtonElement> {}
|
|
||||||
|
|
||||||
export const InteractiveHoverButton = React.forwardRef<
|
export const InteractiveHoverButton = React.forwardRef<
|
||||||
HTMLButtonElement,
|
HTMLButtonElement,
|
||||||
|
|||||||
@@ -8,8 +8,26 @@ import rehypeSlug from "rehype-slug";
|
|||||||
import rehypeCodeTitles from "rehype-code-titles";
|
import rehypeCodeTitles from "rehype-code-titles";
|
||||||
import { page_routes, ROUTES } from "./routes-config";
|
import { page_routes, ROUTES } from "./routes-config";
|
||||||
import { visit } from "unist-util-visit";
|
import { visit } from "unist-util-visit";
|
||||||
|
import type { Node } from "unist";
|
||||||
import matter from "gray-matter";
|
import matter from "gray-matter";
|
||||||
|
|
||||||
|
// Type definitions for unist-util-visit
|
||||||
|
interface Element extends Node {
|
||||||
|
type: string;
|
||||||
|
tagName?: string;
|
||||||
|
properties?: Record<string, unknown> & {
|
||||||
|
raw?: string;
|
||||||
|
};
|
||||||
|
children?: Node[];
|
||||||
|
value?: string;
|
||||||
|
raw?: string; // For internal use in processing
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TextNode extends Node {
|
||||||
|
type: 'text';
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
// custom components imports
|
// custom components imports
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||||
import Pre from "@/components/markdown/PreMdx";
|
import Pre from "@/components/markdown/PreMdx";
|
||||||
@@ -139,11 +157,11 @@ function justGetFrontmatterFromMD<Frontmatter>(rawMd: string): Frontmatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getAllChilds(pathString: string) {
|
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 page_routes_copy = ROUTES;
|
||||||
|
|
||||||
let prevHref = "";
|
let prevHref = "";
|
||||||
for (let it of items) {
|
for (const it of items) {
|
||||||
const found = page_routes_copy.find((innerIt) => innerIt.href == `/${it}`);
|
const found = page_routes_copy.find((innerIt) => innerIt.href == `/${it}`);
|
||||||
if (!found) break;
|
if (!found) break;
|
||||||
prevHref += found.href;
|
prevHref += found.href;
|
||||||
@@ -170,20 +188,28 @@ export async function getAllChilds(pathString: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for copying the code in pre
|
// for copying the code in pre
|
||||||
const preProcess = () => (tree: any) => {
|
const preProcess = () => (tree: Node) => {
|
||||||
visit(tree, (node) => {
|
visit(tree, (node: Node) => {
|
||||||
if (node?.type === "element" && node?.tagName === "pre") {
|
const element = node as Element;
|
||||||
const [codeEl] = node.children;
|
if (element?.type === "element" && element?.tagName === "pre" && element.children) {
|
||||||
if (codeEl.tagName !== "code") return;
|
const [codeEl] = element.children as Element[];
|
||||||
node.raw = codeEl.children?.[0].value;
|
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) => {
|
const postProcess = () => (tree: Node) => {
|
||||||
visit(tree, "element", (node) => {
|
visit(tree, "element", (node: Node) => {
|
||||||
if (node?.type === "element" && node?.tagName === "pre") {
|
const element = node as Element;
|
||||||
node.properties["raw"] = node.raw;
|
if (element?.type === "element" && element?.tagName === "pre") {
|
||||||
|
if (element.properties && element.raw) {
|
||||||
|
element.properties.raw = element.raw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "docubook",
|
"name": "docubook",
|
||||||
"version": "1.13.6",
|
"version": "1.13.9",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
|
|||||||
Reference in New Issue
Block a user