mirror of
https://github.com/LukeHagar/jsdoc-cheatsheet.git
synced 2025-12-09 20:47:46 +00:00
Initialized repository for project JSDoc cheatsheet
Co-authored-by: Luke Hagar <5702154+LukeHagar@users.noreply.github.com>
This commit is contained in:
93
app/globals.css
Normal file
93
app/globals.css
Normal file
@@ -0,0 +1,93 @@
|
||||
@import "tailwindcss";
|
||||
@import "tw-animate-css";
|
||||
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
:root {
|
||||
/* Updated to blue dark theme only - removing light theme variables */
|
||||
--background: #0f172a;
|
||||
--foreground: #f1f5f9;
|
||||
--card: #1e293b;
|
||||
--card-foreground: #f1f5f9;
|
||||
--popover: #1e293b;
|
||||
--popover-foreground: #f1f5f9;
|
||||
--primary: #3b82f6;
|
||||
--primary-foreground: #ffffff;
|
||||
--secondary: #1e40af;
|
||||
--secondary-foreground: #ffffff;
|
||||
--muted: #334155;
|
||||
--muted-foreground: #cbd5e1;
|
||||
--accent: #2563eb;
|
||||
--accent-foreground: #ffffff;
|
||||
--destructive: #dc2626;
|
||||
--destructive-foreground: #ffffff;
|
||||
--border: #475569;
|
||||
--input: #334155;
|
||||
--ring: #3b82f6;
|
||||
--chart-1: #3b82f6;
|
||||
--chart-2: #1d4ed8;
|
||||
--chart-3: #2563eb;
|
||||
--chart-4: #1e40af;
|
||||
--chart-5: #1e3a8a;
|
||||
--radius: 0.5rem;
|
||||
--sidebar: #1e293b;
|
||||
--sidebar-foreground: #f1f5f9;
|
||||
--sidebar-primary: #3b82f6;
|
||||
--sidebar-primary-foreground: #ffffff;
|
||||
--sidebar-accent: #2563eb;
|
||||
--sidebar-accent-foreground: #ffffff;
|
||||
--sidebar-border: #475569;
|
||||
--sidebar-ring: #3b82f6;
|
||||
}
|
||||
|
||||
/* Removed .dark class since we're dark theme only */
|
||||
|
||||
@theme inline {
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--color-card: var(--card);
|
||||
--color-card-foreground: var(--card-foreground);
|
||||
--color-popover: var(--popover);
|
||||
--color-popover-foreground: var(--popover-foreground);
|
||||
--color-primary: var(--primary);
|
||||
--color-primary-foreground: var(--primary-foreground);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-secondary-foreground: var(--secondary-foreground);
|
||||
--color-muted: var(--muted);
|
||||
--color-muted-foreground: var(--muted-foreground);
|
||||
--color-accent: var(--accent);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-destructive-foreground: var(--destructive-foreground);
|
||||
--color-border: var(--border);
|
||||
--color-input: var(--input);
|
||||
--color-ring: var(--ring);
|
||||
--color-chart-1: var(--chart-1);
|
||||
--color-chart-2: var(--chart-2);
|
||||
--color-chart-3: var(--chart-3);
|
||||
--color-chart-4: var(--chart-4);
|
||||
--color-chart-5: var(--chart-5);
|
||||
--radius-sm: calc(var(--radius) - 4px);
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-xl: calc(var(--radius) + 4px);
|
||||
--color-sidebar: var(--sidebar);
|
||||
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||
--color-sidebar-primary: var(--sidebar-primary);
|
||||
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||
--color-sidebar-accent: var(--sidebar-accent);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--color-sidebar-ring: var(--sidebar-ring);
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
26
app/layout.tsx
Normal file
26
app/layout.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { Metadata } from 'next'
|
||||
import { GeistSans } from 'geist/font/sans'
|
||||
import { GeistMono } from 'geist/font/mono'
|
||||
import { Analytics } from '@vercel/analytics/next'
|
||||
import './globals.css'
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'v0 App',
|
||||
description: 'Created with v0',
|
||||
generator: 'v0.app',
|
||||
}
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={`font-sans ${GeistSans.variable} ${GeistMono.variable}`}>
|
||||
{children}
|
||||
<Analytics />
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
672
app/page.tsx
Normal file
672
app/page.tsx
Normal file
@@ -0,0 +1,672 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { ScrollArea } from "@/components/ui/scroll-area"
|
||||
import { Separator } from "@/components/ui/separator"
|
||||
import { BookOpen, Code, FileText, Hash, Info, Settings, Tag, Users, ChevronRight } from "lucide-react"
|
||||
|
||||
const sections = [
|
||||
{
|
||||
id: "basic",
|
||||
title: "Basic Tags",
|
||||
icon: Tag,
|
||||
subsections: ["@description", "@author", "@version", "@since", "@deprecated"],
|
||||
},
|
||||
{
|
||||
id: "parameters",
|
||||
title: "Parameters & Returns",
|
||||
icon: Code,
|
||||
subsections: ["@param", "@returns", "@throws", "@yields"],
|
||||
},
|
||||
{
|
||||
id: "types",
|
||||
title: "Type Definitions",
|
||||
icon: Hash,
|
||||
subsections: ["@typedef", "@property", "@enum", "@type"],
|
||||
},
|
||||
{
|
||||
id: "functions",
|
||||
title: "Functions & Classes",
|
||||
icon: Settings,
|
||||
subsections: ["@function", "@class", "@constructor", "@method", "@static", "@override"],
|
||||
},
|
||||
{
|
||||
id: "modules",
|
||||
title: "Modules & Namespaces",
|
||||
icon: FileText,
|
||||
subsections: ["@module", "@namespace", "@memberof", "@exports", "@requires"],
|
||||
},
|
||||
{
|
||||
id: "advanced",
|
||||
title: "Advanced Tags",
|
||||
icon: BookOpen,
|
||||
subsections: ["@callback", "@event", "@fires", "@listens", "@mixes", "@abstract"],
|
||||
},
|
||||
{
|
||||
id: "objects",
|
||||
title: "Objects & Interfaces",
|
||||
icon: Hash,
|
||||
subsections: ["@interface", "@implements", "@extends", "@mixin"],
|
||||
},
|
||||
{
|
||||
id: "documentation",
|
||||
title: "Documentation Tags",
|
||||
icon: Info,
|
||||
subsections: ["@example", "@see", "@link", "@tutorial", "@todo"],
|
||||
},
|
||||
{
|
||||
id: "examples",
|
||||
title: "Complete Examples",
|
||||
icon: Info,
|
||||
subsections: ["Function Example", "Class Example", "Module Example"],
|
||||
},
|
||||
{
|
||||
id: "best-practices",
|
||||
title: "Best Practices",
|
||||
icon: Users,
|
||||
subsections: ["Consistency", "Completeness", "Clarity", "Type Safety", "Examples"],
|
||||
},
|
||||
]
|
||||
|
||||
const jsdocData = {
|
||||
basic: {
|
||||
title: "Basic Tags",
|
||||
description: "Essential JSDoc tags for documenting your code",
|
||||
items: [
|
||||
{
|
||||
tag: "@description",
|
||||
syntax: "@description {string} Description text",
|
||||
example: "/**\n * @description Calculates the sum of two numbers\n */",
|
||||
description: "Provides a description of the function, class, or variable",
|
||||
},
|
||||
{
|
||||
tag: "@author",
|
||||
syntax: "@author {string} Author name <email>",
|
||||
example: "/**\n * @author John Doe <john@example.com>\n */",
|
||||
description: "Specifies the author of the code",
|
||||
},
|
||||
{
|
||||
tag: "@version",
|
||||
syntax: "@version {string} Version number",
|
||||
example: "/**\n * @version 1.2.0\n */",
|
||||
description: "Indicates the version of the code",
|
||||
},
|
||||
{
|
||||
tag: "@since",
|
||||
syntax: "@since {string} Version when added",
|
||||
example: "/**\n * @since 1.0.0\n */",
|
||||
description: "Specifies when the feature was added",
|
||||
},
|
||||
{
|
||||
tag: "@deprecated",
|
||||
syntax: "@deprecated {string} Deprecation message",
|
||||
example: "/**\n * @deprecated Use newFunction() instead\n */",
|
||||
description: "Marks code as deprecated",
|
||||
},
|
||||
],
|
||||
},
|
||||
parameters: {
|
||||
title: "Parameters & Returns",
|
||||
description: "Document function parameters, return values, and exceptions",
|
||||
items: [
|
||||
{
|
||||
tag: "@param",
|
||||
syntax: "@param {type} name Description",
|
||||
example: "/**\n * @param {number} x - The first number\n * @param {number} y - The second number\n */",
|
||||
description: "Documents function parameters",
|
||||
},
|
||||
{
|
||||
tag: "@returns",
|
||||
syntax: "@returns {type} Description",
|
||||
example: "/**\n * @returns {number} The sum of x and y\n */",
|
||||
description: "Documents the return value",
|
||||
},
|
||||
{
|
||||
tag: "@throws",
|
||||
syntax: "@throws {ErrorType} Description",
|
||||
example: "/**\n * @throws {TypeError} When input is not a number\n */",
|
||||
description: "Documents exceptions that may be thrown",
|
||||
},
|
||||
{
|
||||
tag: "@yields",
|
||||
syntax: "@yields {type} Description",
|
||||
example: "/**\n * @yields {number} The next number in sequence\n */",
|
||||
description: "Documents what a generator function yields",
|
||||
},
|
||||
],
|
||||
},
|
||||
types: {
|
||||
title: "Type Definitions",
|
||||
description: "Define and document custom types and interfaces",
|
||||
items: [
|
||||
{
|
||||
tag: "@typedef",
|
||||
syntax: "@typedef {Object} TypeName",
|
||||
example: "/**\n * @typedef {Object} User\n * @property {string} name\n * @property {number} age\n */",
|
||||
description: "Defines a custom type",
|
||||
},
|
||||
{
|
||||
tag: "@property",
|
||||
syntax: "@property {type} name Description",
|
||||
example: "/**\n * @property {string} email - User email address\n */",
|
||||
description: "Documents object properties",
|
||||
},
|
||||
{
|
||||
tag: "@enum",
|
||||
syntax: "@enum {type}",
|
||||
example: '/**\n * @enum {string}\n */\nconst Status = {\n PENDING: "pending",\n COMPLETE: "complete"\n}',
|
||||
description: "Documents enumeration values",
|
||||
},
|
||||
{
|
||||
tag: "@type",
|
||||
syntax: "@type {type}",
|
||||
example: "/**\n * @type {string|number}\n */\nlet value;",
|
||||
description: "Specifies the type of a variable",
|
||||
},
|
||||
],
|
||||
},
|
||||
functions: {
|
||||
title: "Functions & Classes",
|
||||
description: "Document functions, classes, constructors, and methods",
|
||||
items: [
|
||||
{
|
||||
tag: "@function",
|
||||
syntax: "@function",
|
||||
example: "/**\n * @function calculateTotal\n * @description Calculates order total\n */",
|
||||
description: "Explicitly marks something as a function",
|
||||
},
|
||||
{
|
||||
tag: "@class",
|
||||
syntax: "@class",
|
||||
example: "/**\n * @class\n * @description Represents a user account\n */",
|
||||
description: "Documents a class",
|
||||
},
|
||||
{
|
||||
tag: "@constructor",
|
||||
syntax: "@constructor",
|
||||
example: "/**\n * @constructor\n * @param {string} name - User name\n */",
|
||||
description: "Documents a constructor function",
|
||||
},
|
||||
{
|
||||
tag: "@method",
|
||||
syntax: "@method",
|
||||
example: "/**\n * @method getName\n * @returns {string} The user name\n */",
|
||||
description: "Documents a method",
|
||||
},
|
||||
{
|
||||
tag: "@static",
|
||||
syntax: "@static",
|
||||
example: "/**\n * @static\n * @method createUser\n */",
|
||||
description: "Indicates a static method or property",
|
||||
},
|
||||
{
|
||||
tag: "@override",
|
||||
syntax: "@override",
|
||||
example: "/**\n * @override\n * @method toString\n */",
|
||||
description: "Indicates method overrides parent method",
|
||||
},
|
||||
],
|
||||
},
|
||||
modules: {
|
||||
title: "Modules & Namespaces",
|
||||
description: "Organize code with modules, namespaces, and membership",
|
||||
items: [
|
||||
{
|
||||
tag: "@module",
|
||||
syntax: "@module ModuleName",
|
||||
example: "/**\n * @module UserUtils\n * @description Utilities for user management\n */",
|
||||
description: "Documents a module",
|
||||
},
|
||||
{
|
||||
tag: "@namespace",
|
||||
syntax: "@namespace NamespaceName",
|
||||
example: "/**\n * @namespace MyApp.Utils\n */",
|
||||
description: "Documents a namespace",
|
||||
},
|
||||
{
|
||||
tag: "@memberof",
|
||||
syntax: "@memberof ParentName",
|
||||
example: "/**\n * @memberof MyApp.Utils\n * @function formatName\n */",
|
||||
description: "Indicates membership in a parent",
|
||||
},
|
||||
{
|
||||
tag: "@exports",
|
||||
syntax: "@exports ModuleName",
|
||||
example: "/**\n * @exports UserService\n */",
|
||||
description: "Documents what a module exports",
|
||||
},
|
||||
{
|
||||
tag: "@requires",
|
||||
syntax: "@requires ModuleName",
|
||||
example: "/**\n * @requires lodash\n */",
|
||||
description: "Documents module dependencies",
|
||||
},
|
||||
],
|
||||
},
|
||||
advanced: {
|
||||
title: "Advanced Tags",
|
||||
description: "Advanced JSDoc features for complex documentation needs",
|
||||
items: [
|
||||
{
|
||||
tag: "@callback",
|
||||
syntax: "@callback CallbackName",
|
||||
example: "/**\n * @callback RequestCallback\n * @param {Error} error\n * @param {Object} response\n */",
|
||||
description: "Documents a callback function type",
|
||||
},
|
||||
{
|
||||
tag: "@event",
|
||||
syntax: "@event EventName",
|
||||
example: "/**\n * @event MyClass#dataLoaded\n * @type {Object}\n */",
|
||||
description: "Documents an event",
|
||||
},
|
||||
{
|
||||
tag: "@fires",
|
||||
syntax: "@fires EventName",
|
||||
example: "/**\n * @fires MyClass#dataLoaded\n */",
|
||||
description: "Indicates function fires an event",
|
||||
},
|
||||
{
|
||||
tag: "@listens",
|
||||
syntax: "@listens EventName",
|
||||
example: "/**\n * @listens MyClass#dataLoaded\n */",
|
||||
description: "Indicates function listens to an event",
|
||||
},
|
||||
{
|
||||
tag: "@mixes",
|
||||
syntax: "@mixes MixinName",
|
||||
example: "/**\n * @mixes EventEmitter\n */",
|
||||
description: "Documents that class mixes in another",
|
||||
},
|
||||
{
|
||||
tag: "@abstract",
|
||||
syntax: "@abstract",
|
||||
example: "/**\n * @abstract\n * @method process\n */",
|
||||
description: "Indicates abstract method or class",
|
||||
},
|
||||
],
|
||||
},
|
||||
examples: {
|
||||
title: "Complete Examples",
|
||||
description: "Real-world JSDoc documentation examples",
|
||||
items: [
|
||||
{
|
||||
tag: "Function Example",
|
||||
syntax: "Complete function documentation",
|
||||
example: `/**
|
||||
* Calculates the area of a rectangle
|
||||
* @function calculateArea
|
||||
* @param {number} width - The width of the rectangle
|
||||
* @param {number} height - The height of the rectangle
|
||||
* @returns {number} The area of the rectangle
|
||||
* @throws {TypeError} When width or height is not a number
|
||||
* @example
|
||||
* // Calculate area of 5x3 rectangle
|
||||
* const area = calculateArea(5, 3);
|
||||
* console.log(area); // 15
|
||||
* @since 1.0.0
|
||||
* @author Jane Smith <jane@example.com>
|
||||
*/
|
||||
function calculateArea(width, height) {
|
||||
if (typeof width !== 'number' || typeof height !== 'number') {
|
||||
throw new TypeError('Width and height must be numbers');
|
||||
}
|
||||
return width * height;
|
||||
}`,
|
||||
description: "Complete function documentation with all common tags",
|
||||
},
|
||||
{
|
||||
tag: "Class Example",
|
||||
syntax: "Complete class documentation",
|
||||
example: `/**
|
||||
* Represents a user in the system
|
||||
* @class User
|
||||
* @param {string} name - The user's name
|
||||
* @param {string} email - The user's email address
|
||||
* @example
|
||||
* const user = new User('John Doe', 'john@example.com');
|
||||
* console.log(user.getName()); // 'John Doe'
|
||||
*/
|
||||
class User {
|
||||
/**
|
||||
* Create a user
|
||||
* @constructor
|
||||
* @param {string} name - The user's name
|
||||
* @param {string} email - The user's email address
|
||||
*/
|
||||
constructor(name, email) {
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user's name
|
||||
* @method getName
|
||||
* @returns {string} The user's name
|
||||
*/
|
||||
getName() {
|
||||
return this.name;
|
||||
}
|
||||
}`,
|
||||
description: "Complete class documentation with constructor and methods",
|
||||
},
|
||||
{
|
||||
tag: "Module Example",
|
||||
syntax: "Complete module documentation",
|
||||
example: `/**
|
||||
* User management module
|
||||
* @module UserManagement
|
||||
* @description Handles user creation and deletion
|
||||
* @requires Database
|
||||
* @exports createUser
|
||||
* @exports deleteUser
|
||||
* @example
|
||||
* // Create a user
|
||||
* const user = createUser('John Doe', 'john@example.com');
|
||||
* console.log(user);
|
||||
*
|
||||
* // Delete a user
|
||||
* deleteUser(user.id);
|
||||
*/
|
||||
const Database = require('./Database');
|
||||
|
||||
function createUser(name, email) {
|
||||
// Implementation here
|
||||
}
|
||||
|
||||
function deleteUser(userId) {
|
||||
// Implementation here
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createUser,
|
||||
deleteUser
|
||||
};`,
|
||||
description: "Complete module documentation with dependencies and exports",
|
||||
},
|
||||
],
|
||||
},
|
||||
"best-practices": {
|
||||
title: "Best Practices",
|
||||
description: "Guidelines for writing effective JSDoc documentation",
|
||||
items: [
|
||||
{
|
||||
tag: "Consistency",
|
||||
syntax: "Use consistent formatting and style",
|
||||
example:
|
||||
"// Always use the same format for similar tags\n// Good: @param {string} name - User name\n// Good: @param {number} age - User age",
|
||||
description: "Maintain consistent formatting across your documentation",
|
||||
},
|
||||
{
|
||||
tag: "Completeness",
|
||||
syntax: "Document all public APIs",
|
||||
example: "// Document all parameters, return values, and exceptions\n// Include examples for complex functions",
|
||||
description: "Ensure all public functions, classes, and modules are documented",
|
||||
},
|
||||
{
|
||||
tag: "Clarity",
|
||||
syntax: "Write clear, concise descriptions",
|
||||
example: "// Good: Calculates user age from birth date\n// Bad: Does age stuff",
|
||||
description: "Use clear, descriptive language that explains purpose and behavior",
|
||||
},
|
||||
{
|
||||
tag: "Type Safety",
|
||||
syntax: "Always specify types for parameters and returns",
|
||||
example:
|
||||
"// Always include types\n@param {string|null} name - User name or null\n@returns {Promise<User>} Promise resolving to user object",
|
||||
description: "Include detailed type information to improve code reliability",
|
||||
},
|
||||
{
|
||||
tag: "Examples",
|
||||
syntax: "Include usage examples for complex functions",
|
||||
example:
|
||||
"/**\n * @example\n * // Basic usage\n * const result = myFunction('input');\n * \n * @example\n * // Advanced usage\n * const result = myFunction('input', { option: true });\n */",
|
||||
description: "Provide practical examples showing how to use the code",
|
||||
},
|
||||
],
|
||||
},
|
||||
objects: {
|
||||
title: "Objects & Interfaces",
|
||||
description: "Document object structures, interfaces, and inheritance",
|
||||
items: [
|
||||
{
|
||||
tag: "@interface",
|
||||
syntax: "@interface InterfaceName",
|
||||
example: "/**\n * @interface Drawable\n * @description Interface for drawable objects\n */",
|
||||
description: "Documents an interface that classes can implement",
|
||||
},
|
||||
{
|
||||
tag: "@implements",
|
||||
syntax: "@implements {InterfaceName}",
|
||||
example: "/**\n * @class Circle\n * @implements {Drawable}\n */",
|
||||
description: "Indicates that a class implements an interface",
|
||||
},
|
||||
{
|
||||
tag: "@extends",
|
||||
syntax: "@extends ParentClass",
|
||||
example: "/**\n * @class ColoredCircle\n * @extends Circle\n */",
|
||||
description: "Documents class inheritance",
|
||||
},
|
||||
{
|
||||
tag: "@mixin",
|
||||
syntax: "@mixin MixinName",
|
||||
example: "/**\n * @mixin EventEmitter\n * @description Adds event handling capabilities\n */",
|
||||
description: "Documents a mixin that can be mixed into classes",
|
||||
},
|
||||
],
|
||||
},
|
||||
documentation: {
|
||||
title: "Documentation Tags",
|
||||
description: "Tags for linking, examples, and additional documentation",
|
||||
items: [
|
||||
{
|
||||
tag: "@example",
|
||||
syntax: "@example\n// Example code here",
|
||||
example:
|
||||
"/**\n * @example\n * // Basic usage\n * const result = myFunction('test');\n * console.log(result);\n */",
|
||||
description: "Provides usage examples",
|
||||
},
|
||||
{
|
||||
tag: "@see",
|
||||
syntax: "@see {reference}",
|
||||
example: "/**\n * @see {@link MyClass#method}\n * @see https://example.com/docs\n */",
|
||||
description: "References related documentation or code",
|
||||
},
|
||||
{
|
||||
tag: "@link",
|
||||
syntax: "{@link reference}",
|
||||
example: "/**\n * Uses {@link MyClass} for processing\n */",
|
||||
description: "Creates inline links to other documentation",
|
||||
},
|
||||
{
|
||||
tag: "@tutorial",
|
||||
syntax: "@tutorial TutorialName",
|
||||
example: "/**\n * @tutorial getting-started\n */",
|
||||
description: "Links to a tutorial document",
|
||||
},
|
||||
{
|
||||
tag: "@todo",
|
||||
syntax: "@todo Description of what needs to be done",
|
||||
example: "/**\n * @todo Add input validation\n * @todo Optimize performance\n */",
|
||||
description: "Documents future improvements or fixes needed",
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
export default function JSDocCheatsheet() {
|
||||
const [activeSection, setActiveSection] = useState("basic")
|
||||
const [expandedSections, setExpandedSections] = useState<string[]>(["basic"])
|
||||
|
||||
const toggleSection = (sectionId: string) => {
|
||||
setExpandedSections((prev) =>
|
||||
prev.includes(sectionId) ? prev.filter((id) => id !== sectionId) : [...prev, sectionId],
|
||||
)
|
||||
}
|
||||
|
||||
const scrollToTag = (tag: string) => {
|
||||
const element = document.getElementById(tag.replace("@", "").replace(/[^a-zA-Z0-9]/g, "-"))
|
||||
if (element) {
|
||||
element.scrollIntoView({ behavior: "smooth", block: "start" })
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
{/* Header */}
|
||||
<header className="border-b border-border bg-card/50 backdrop-blur-sm sticky top-0 z-50">
|
||||
<div className="w-full px-6 py-6">
|
||||
<div className="text-center">
|
||||
<h1 className="text-4xl font-bold text-foreground mb-2">JSDoc Cheatsheet</h1>
|
||||
<p className="text-muted-foreground text-lg">Complete Reference for JavaScript Documentation</p>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div className="w-full px-6 py-8">
|
||||
<div className="flex gap-8">
|
||||
{/* Sidebar Navigation */}
|
||||
<aside className="w-80 shrink-0">
|
||||
<div className="sticky top-32">
|
||||
<Card className="bg-sidebar border-sidebar-border">
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle className="text-sidebar-foreground text-lg">Navigation</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="p-0">
|
||||
<ScrollArea className="h-[calc(100vh-200px)]">
|
||||
<nav className="space-y-1 p-3">
|
||||
{sections.map((section) => {
|
||||
const Icon = section.icon
|
||||
const isExpanded = expandedSections.includes(section.id)
|
||||
const isActive = activeSection === section.id
|
||||
|
||||
return (
|
||||
<div key={section.id} className="space-y-1">
|
||||
<Button
|
||||
variant={isActive ? "secondary" : "ghost"}
|
||||
className={`w-full justify-between gap-2 ${
|
||||
isActive
|
||||
? "bg-sidebar-primary text-sidebar-primary-foreground hover:bg-sidebar-primary/90"
|
||||
: "text-sidebar-foreground hover:bg-sidebar-accent/10"
|
||||
}`}
|
||||
onClick={() => {
|
||||
setActiveSection(section.id)
|
||||
toggleSection(section.id)
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<Icon className="h-4 w-4" />
|
||||
{section.title}
|
||||
</div>
|
||||
<ChevronRight
|
||||
className={`h-4 w-4 transition-transform ${isExpanded ? "rotate-90" : ""}`}
|
||||
/>
|
||||
</Button>
|
||||
|
||||
{isExpanded && section.subsections && (
|
||||
<div className="ml-6 space-y-1">
|
||||
{section.subsections.map((subsection) => (
|
||||
<Button
|
||||
key={subsection}
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="w-full justify-start text-xs text-muted-foreground hover:text-foreground hover:bg-sidebar-accent/5"
|
||||
onClick={() => scrollToTag(subsection)}
|
||||
>
|
||||
{subsection}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</nav>
|
||||
</ScrollArea>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
{/* Main Content */}
|
||||
<main className="flex-1 min-w-0">
|
||||
<div className="space-y-6">
|
||||
{/* Section Header */}
|
||||
<div className="text-center mb-8">
|
||||
<h2 className="text-3xl font-bold text-foreground mb-2">
|
||||
{jsdocData[activeSection as keyof typeof jsdocData]?.title || "Section"}
|
||||
</h2>
|
||||
<p className="text-muted-foreground text-lg">
|
||||
{jsdocData[activeSection as keyof typeof jsdocData]?.description || "Documentation section"}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Content Cards */}
|
||||
<div className="grid gap-6">
|
||||
{jsdocData[activeSection as keyof typeof jsdocData]?.items.map((item, index) => (
|
||||
<Card
|
||||
key={index}
|
||||
id={item.tag.replace("@", "").replace(/[^a-zA-Z0-9]/g, "-")}
|
||||
className="border-border hover:shadow-lg transition-shadow hover:border-primary/50"
|
||||
>
|
||||
<CardHeader className="pb-3">
|
||||
<div className="flex items-center justify-between">
|
||||
<CardTitle className="text-xl text-foreground flex items-center gap-2">
|
||||
<Badge variant="secondary" className="bg-primary text-primary-foreground">
|
||||
{item.tag}
|
||||
</Badge>
|
||||
</CardTitle>
|
||||
</div>
|
||||
<CardDescription className="text-muted-foreground text-base">{item.description}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
{/* Syntax */}
|
||||
<div>
|
||||
<h4 className="font-semibold text-foreground mb-2">Syntax:</h4>
|
||||
<code className="block bg-muted text-muted-foreground p-3 rounded-md text-sm font-mono">
|
||||
{item.syntax}
|
||||
</code>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
{/* Example */}
|
||||
<div>
|
||||
<h4 className="font-semibold text-foreground mb-2">Example:</h4>
|
||||
<pre className="bg-card text-card-foreground p-4 rounded-md text-sm font-mono overflow-x-auto border border-border">
|
||||
<code>{item.example}</code>
|
||||
</pre>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)) || []}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Footer */}
|
||||
<footer className="border-t border-border bg-card/50 mt-16">
|
||||
<div className="w-full px-6 py-8">
|
||||
<div className="text-center text-muted-foreground">
|
||||
<p className="mb-2">
|
||||
For more information, visit the{" "}
|
||||
<a
|
||||
href="https://jsdoc.app/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-primary hover:underline"
|
||||
>
|
||||
official JSDoc documentation
|
||||
</a>
|
||||
</p>
|
||||
<p className="text-sm">This cheatsheet covers the most commonly used JSDoc tags and patterns.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user