diff --git a/apps/v4/app/(create)/components/toolbar-controls.tsx b/apps/v4/app/(create)/components/project-form.tsx similarity index 83% rename from apps/v4/app/(create)/components/toolbar-controls.tsx rename to apps/v4/app/(create)/components/project-form.tsx index 685910e703..4140527e74 100644 --- a/apps/v4/app/(create)/components/toolbar-controls.tsx +++ b/apps/v4/app/(create)/components/project-form.tsx @@ -1,17 +1,15 @@ "use client" +import * as React from "react" import { ComputerTerminal01Icon, Copy01Icon, Tick02Icon, } from "@hugeicons/core-free-icons" import { HugeiconsIcon } from "@hugeicons/react" -import * as React from "react" -import { toast } from "sonner" -import { useDesignSystemSearchParams } from "@/app/(create)/lib/search-params" -import { copyToClipboardWithMeta } from "@/components/copy-button" import { useConfig } from "@/hooks/use-config" +import { copyToClipboardWithMeta } from "@/components/copy-button" import { Button } from "@/registry/new-york-v4/ui/button" import { Dialog, @@ -41,6 +39,7 @@ import { TabsList, TabsTrigger, } from "@/registry/new-york-v4/ui/tabs" +import { useDesignSystemSearchParams } from "@/app/(create)/lib/search-params" const TEMPLATES = [ { @@ -65,7 +64,7 @@ const TEMPLATES = [ }, ] as const -export function ToolbarControls() { +export function ProjectForm() { const [open, setOpen] = React.useState(false) const [params, setParams] = useDesignSystemSearchParams() const [config, setConfig] = useConfig() @@ -76,15 +75,40 @@ export function ToolbarControls() { const commands = React.useMemo(() => { const origin = process.env.NEXT_PUBLIC_APP_URL || "http://localhost:4000" const url = `${origin}/init?base=${params.base}&style=${params.style}&baseColor=${params.baseColor}&theme=${params.theme}&iconLibrary=${params.iconLibrary}&font=${params.font}&menuAccent=${params.menuAccent}&menuColor=${params.menuColor}&radius=${params.radius}&template=${params.template}&rtl=${params.rtl}` - const templateFlag = params.template ? ` --template ${params.template}` : "" const rtlFlag = params.rtl ? " --rtl" : "" - return { - pnpm: `pnpm dlx shadcn@latest create${rtlFlag} --preset "${url}"${templateFlag}`, - npm: `npx shadcn@latest create${rtlFlag} --preset "${url}"${templateFlag}`, - yarn: `yarn dlx shadcn@latest create${rtlFlag} --preset "${url}"${templateFlag}`, - bun: `bunx --bun shadcn@latest create${rtlFlag} --preset "${url}"${templateFlag}`, + const templateFlag = params.template ? ` --template ${params.template}` : "" + const isLocalDev = origin.includes("localhost") + + if (!params.new) { + return isLocalDev + ? { + pnpm: `pnpm shadcn init${rtlFlag} --preset "${url}"${templateFlag}`, + npm: `pnpm shadcn init${rtlFlag} --preset "${url}"${templateFlag}`, + yarn: `pnpm shadcn init${rtlFlag} --preset "${url}"${templateFlag}`, + bun: `pnpm shadcn init${rtlFlag} --preset "${url}"${templateFlag}`, + } + : { + pnpm: `pnpm dlx shadcn@latest init${rtlFlag} --preset "${url}"${templateFlag}`, + npm: `npx shadcn@latest init${rtlFlag} --preset "${url}"${templateFlag}`, + yarn: `yarn dlx shadcn@latest init${rtlFlag} --preset "${url}"${templateFlag}`, + bun: `bunx --bun shadcn@latest init${rtlFlag} --preset "${url}"${templateFlag}`, + } } + return isLocalDev + ? { + pnpm: `pnpm shadcn create${rtlFlag} --preset "${url}"${templateFlag}`, + npm: `pnpm shadcn create${rtlFlag} --preset "${url}"${templateFlag}`, + yarn: `pnpm shadcn create${rtlFlag} --preset "${url}"${templateFlag}`, + bun: `pnpm shadcn create${rtlFlag} --preset "${url}"${templateFlag}`, + } + : { + pnpm: `pnpm dlx shadcn@latest create${rtlFlag} --preset "${url}"${templateFlag}`, + npm: `npx shadcn@latest create${rtlFlag} --preset "${url}"${templateFlag}`, + yarn: `yarn dlx shadcn@latest create${rtlFlag} --preset "${url}"${templateFlag}`, + bun: `bunx --bun shadcn@latest create${rtlFlag} --preset "${url}"${templateFlag}`, + } }, [ + params.new, params.base, params.style, params.baseColor, @@ -108,31 +132,6 @@ export function ToolbarControls() { }, [hasCopied]) const handleCopy = React.useCallback(() => { - const properties: Record = { - command, - } - if (params.template) { - properties.template = params.template - } - copyToClipboardWithMeta(command, { - name: "copy_npm_command", - properties, - }) - setOpen(false) - setHasCopied(true) - toast("Command copied to clipboard.", { - description: - "Paste and run the command in your terminal to create a new shadcn/ui project.", - position: "bottom-center", - classNames: { - content: "rounded-xl", - toast: "rounded-xl!", - description: "text-sm/leading-normal!", - }, - }) - }, [command, params.template, setOpen]) - - const handleCopyFromTabs = React.useCallback(() => { const properties: Record = { command, } @@ -163,23 +162,33 @@ export function ToolbarControls() { - Create Project + + {params.new + ? "Create Project" + : "Initialize Project"} + - Select a template and run this command to create a{" "} - {selectedTemplate?.title} + shadcn/ui project. + Run this command to initialize shadcn/ui in your project. - - Template + + Select a template + + Which template would you like to use? + { setParams({ - template: value as "next" | "next-monorepo" | "start" | "vite", + template: value as + | "next" + | "next-monorepo" + | "start" + | "vite", }) }} className="grid grid-cols-2 gap-2" @@ -210,6 +219,24 @@ export function ToolbarControls() { ))} + + + + Existing Project + + Initialize shadcn/ui in an existing project. + + + + setParams({ new: !checked }) + } + className="shadow-none" + /> + + + @@ -232,6 +259,9 @@ export function ToolbarControls() { /> + + + { @@ -253,7 +283,7 @@ export function ToolbarControls() { size="icon-sm" variant="ghost" className="ml-auto size-7 rounded-lg" - onClick={handleCopyFromTabs} + onClick={handleCopy} > {hasCopied ? ( @@ -277,8 +307,6 @@ export function ToolbarControls() { ) })} - - - - )