diff --git a/.changeset/mighty-rings-repair.md b/.changeset/mighty-rings-repair.md new file mode 100644 index 0000000000..55cad67dbf --- /dev/null +++ b/.changeset/mighty-rings-repair.md @@ -0,0 +1,5 @@ +--- +"shadcn": major +--- + +add shadcn docs command diff --git a/packages/shadcn/src/commands/docs.ts b/packages/shadcn/src/commands/docs.ts new file mode 100644 index 0000000000..798c9bdb0f --- /dev/null +++ b/packages/shadcn/src/commands/docs.ts @@ -0,0 +1,90 @@ +import path from "path" +import { getShadcnRegistryIndex } from "@/src/registry/api" +import { getBase, getConfig } from "@/src/utils/get-config" +import { handleError } from "@/src/utils/handle-error" +import { highlighter } from "@/src/utils/highlighter" +import { logger } from "@/src/utils/logger" +import { Command } from "commander" + +export const docs = new Command() + .name("docs") + .description("get docs, api references and usage examples for components") + .argument("", "component names") + .option( + "-c, --cwd ", + "the working directory. defaults to the current directory.", + process.cwd() + ) + .option( + "-b, --base ", + "the base to use either 'base' or 'radix'. defaults to project base." + ) + .option("--json", "output as JSON.", false) + .action(async (components, opts) => { + try { + const cwd = path.resolve(opts.cwd) + const config = await getConfig(cwd) + const base = opts.base ?? getBase(config?.style) + + const index = await getShadcnRegistryIndex() + + if (!index) { + logger.error("Failed to fetch the registry index.") + process.exit(1) + } + + const results: { + component: string + base: string + links: Record + }[] = [] + + for (const component of components) { + const item = index.find((entry) => entry.name === component) + + if (!item) { + logger.error( + `Component ${highlighter.info( + component + )} not found in the shadcn registry.` + ) + process.exit(1) + } + + const links = ( + item.meta?.links as Record> + )?.[base] + + if (!links || Object.keys(links).length === 0) { + logger.warn( + `No documentation links available for ${highlighter.info( + component + )}.` + ) + continue + } + + results.push({ component, base, links }) + } + + if (opts.json) { + console.log(JSON.stringify({ base, results }, null, 2)) + return + } + + // Compute max key length across all results for consistent alignment. + const maxKeyLength = Math.max( + ...results.flatMap((r) => Object.keys(r.links).map((k) => k.length)) + ) + + for (const { component, links } of results) { + logger.log(highlighter.info(component)) + for (const [key, value] of Object.entries(links)) { + logger.log(` - ${key.padEnd(maxKeyLength + 2)}${value}`) + } + logger.break() + } + } catch (error) { + handleError(error) + } + }) diff --git a/packages/shadcn/src/index.ts b/packages/shadcn/src/index.ts index aee080319c..71632973e6 100644 --- a/packages/shadcn/src/index.ts +++ b/packages/shadcn/src/index.ts @@ -2,6 +2,7 @@ import { add } from "@/src/commands/add" import { build } from "@/src/commands/build" import { diff } from "@/src/commands/diff" +import { docs } from "@/src/commands/docs" import { info } from "@/src/commands/info" import { init } from "@/src/commands/init" import { mcp } from "@/src/commands/mcp" @@ -32,6 +33,7 @@ async function main() { .addCommand(init) .addCommand(add) .addCommand(diff) + .addCommand(docs) .addCommand(view) .addCommand(search) .addCommand(migrate)