From a12dd019d3bc378b026807f170df1361791bce7e Mon Sep 17 00:00:00 2001 From: shadcn Date: Thu, 12 Feb 2026 11:37:35 +0400 Subject: [PATCH] feat: wip for init --- .../(create)/components/template-picker.tsx | 2 +- .../(create)/components/toolbar-controls.tsx | 58 +- apps/v4/app/(create)/init/route.ts | 2 +- apps/v4/app/(create)/lib/search-params.ts | 1 + apps/v4/registry/config.ts | 4 +- packages/shadcn/package.json | 4 +- packages/shadcn/src/commands/create.ts | 4 +- packages/shadcn/src/commands/init.ts | 32 +- packages/shadcn/src/utils/add-components.ts | 38 +- packages/shadcn/src/utils/create-project.ts | 171 +- packages/shadcn/src/utils/init-monorepo.ts | 116 + .../shadcn/src/utils/updaters/update-files.ts | 13 +- .../tests/src/tests/create-monorepo.test.ts | 209 ++ packages/tests/src/utils/helpers.ts | 8 +- templates/monorepo-next/apps/web/package.json | 1 - .../monorepo-next/packages/ui/package.json | 6 - .../packages/ui/src/components/button.tsx | 60 - .../packages/ui/src/lib/.gitkeep | 0 .../packages/ui/src/lib/utils.ts | 6 - .../packages/ui/src/styles/globals.css | 123 - templates/monorepo-next/pnpm-lock.yaml | 2670 ++++++++--------- 21 files changed, 1860 insertions(+), 1668 deletions(-) create mode 100644 packages/shadcn/src/utils/init-monorepo.ts create mode 100644 packages/tests/src/tests/create-monorepo.test.ts delete mode 100644 templates/monorepo-next/packages/ui/src/components/button.tsx create mode 100644 templates/monorepo-next/packages/ui/src/lib/.gitkeep delete mode 100644 templates/monorepo-next/packages/ui/src/lib/utils.ts diff --git a/apps/v4/app/(create)/components/template-picker.tsx b/apps/v4/app/(create)/components/template-picker.tsx index ebfe977d4..da0071dd3 100644 --- a/apps/v4/app/(create)/components/template-picker.tsx +++ b/apps/v4/app/(create)/components/template-picker.tsx @@ -68,7 +68,7 @@ export function TemplatePicker({ value={params.template} onValueChange={(value) => { setParams({ - template: value as "next" | "start" | "vite", + template: value as "next" | "next-monorepo" | "start" | "vite", }) }} > diff --git a/apps/v4/app/(create)/components/toolbar-controls.tsx b/apps/v4/app/(create)/components/toolbar-controls.tsx index 4b22edbee..685910e70 100644 --- a/apps/v4/app/(create)/components/toolbar-controls.tsx +++ b/apps/v4/app/(create)/components/toolbar-controls.tsx @@ -1,17 +1,17 @@ "use client" -import * as React from "react" -import Link from "next/link" import { ComputerTerminal01Icon, Copy01Icon, Tick02Icon, } from "@hugeicons/core-free-icons" import { HugeiconsIcon } from "@hugeicons/react" +import * as React from "react" import { toast } from "sonner" -import { useConfig } from "@/hooks/use-config" +import { useDesignSystemSearchParams } from "@/app/(create)/lib/search-params" import { copyToClipboardWithMeta } from "@/components/copy-button" +import { useConfig } from "@/hooks/use-config" import { Button } from "@/registry/new-york-v4/ui/button" import { Dialog, @@ -41,12 +41,6 @@ import { TabsList, TabsTrigger, } from "@/registry/new-york-v4/ui/tabs" -import { - Tooltip, - TooltipContent, - TooltipTrigger, -} from "@/registry/new-york-v4/ui/tooltip" -import { useDesignSystemSearchParams } from "@/app/(create)/lib/search-params" const TEMPLATES = [ { @@ -54,6 +48,11 @@ const TEMPLATES = [ title: "Next.js", logo: 'Next.js', }, + { + value: "next-monorepo", + title: "Next.js (Monorepo)", + logo: 'Next.js', + }, { value: "start", title: "TanStack Start", @@ -180,10 +179,10 @@ export function ToolbarControls() { value={params.template} onValueChange={(value) => { setParams({ - template: value as "next" | "start" | "vite", + template: value as "next" | "next-monorepo" | "start" | "vite", }) }} - className="grid grid-cols-3 gap-2" + className="grid grid-cols-2 gap-2" > {TEMPLATES.map((template) => ( Enable RTL -
+
pnpm npm yarn bun - - - - - - {hasCopied ? "Copied!" : "Copy command"} - - +
{Object.entries(commands).map(([key, cmd]) => { return ( diff --git a/apps/v4/app/(create)/init/route.ts b/apps/v4/app/(create)/init/route.ts index 3f590b8e5..606edba2a 100644 --- a/apps/v4/app/(create)/init/route.ts +++ b/apps/v4/app/(create)/init/route.ts @@ -18,7 +18,7 @@ export async function GET(request: NextRequest) { menuAccent: searchParams.get("menuAccent"), menuColor: searchParams.get("menuColor"), radius: searchParams.get("radius"), - template: searchParams.get("template"), + template: searchParams.get("template") ?? undefined, rtl: searchParams.get("rtl") === "true", }) diff --git a/apps/v4/app/(create)/lib/search-params.ts b/apps/v4/app/(create)/lib/search-params.ts index 9d2733845..ab0090456 100644 --- a/apps/v4/app/(create)/lib/search-params.ts +++ b/apps/v4/app/(create)/lib/search-params.ts @@ -63,6 +63,7 @@ const designSystemSearchParams = { ).withDefault("default"), template: parseAsStringLiteral([ "next", + "next-monorepo", "start", "vite", ] as const).withDefault("next"), diff --git a/apps/v4/registry/config.ts b/apps/v4/registry/config.ts index 0fce7ca99..e5e62482c 100644 --- a/apps/v4/registry/config.ts +++ b/apps/v4/registry/config.ts @@ -94,7 +94,7 @@ export const designSystemConfigSchema = z radius: z .enum(RADII.map((r) => r.name) as [RadiusValue, ...RadiusValue[]]) .default("default"), - template: z.enum(["next", "start", "vite"]).default("next").optional(), + template: z.enum(["next", "next-monorepo", "start", "vite"]).default("next").optional(), }) .refine( (data) => { @@ -433,7 +433,7 @@ export function buildRegistryBase(config: DesignSystemConfig) { }, }, ...(config.rtl && { - docs: `To learn how to set up the RTL provider and fonts for your app, see https://ui.shadcn.com/docs/rtl/${config.template ?? "next"}`, + docs: `To learn how to set up the RTL provider and fonts for your app, see https://ui.shadcn.com/docs/rtl/${config.template === "next-monorepo" ? "next" : (config.template ?? "next")}`, }), } } diff --git a/packages/shadcn/package.json b/packages/shadcn/package.json index affb0d7a5..25e348493 100644 --- a/packages/shadcn/package.json +++ b/packages/shadcn/package.json @@ -61,7 +61,7 @@ "build": "tsup", "typecheck": "tsc --noEmit", "clean": "rimraf dist && rimraf components", - "start:dev": "cross-env REGISTRY_URL=http://localhost:4000/r node dist/index.js", + "start:dev": "cross-env REGISTRY_URL=http://localhost:4000/r SHADCN_TEMPLATE_DIR=../../templates node dist/index.js", "start:prod": "cross-env REGISTRY_URL=https://ui.shadcn.com/r node dist/index.js", "start": "node dist/index.js", "format:write": "prettier --write \"**/*.{ts,tsx,mdx}\" --cache", @@ -71,7 +71,7 @@ "pub:next": "pnpm build && pnpm publish --no-git-checks --access public --tag next", "pub:release": "pnpm build && pnpm publish --access public", "test": "vitest run", - "test:dev": "REGISTRY_URL=http://localhost:4000/r vitest run", + "test:dev": "REGISTRY_URL=http://localhost:4000/r SHADCN_TEMPLATE_DIR=../../templates vitest run", "mcp:inspect": "pnpm dlx @modelcontextprotocol/inspector node dist/index.js mcp" }, "dependencies": { diff --git a/packages/shadcn/src/commands/create.ts b/packages/shadcn/src/commands/create.ts index 8247040f8..6316c9383 100644 --- a/packages/shadcn/src/commands/create.ts +++ b/packages/shadcn/src/commands/create.ts @@ -23,6 +23,7 @@ import { initOptionsSchema, runInit } from "./init" const CREATE_TEMPLATES = { next: "Next.js", + "next-monorepo": "Next.js (Monorepo)", vite: "Vite", start: "TanStack Start", } as const @@ -35,7 +36,7 @@ export const create = new Command() .argument("[name]", "the name of your project") .option( "-t, --template