Files
shadcn-ui/apps/v4/app/(create)/components/create-project-dialog.tsx
shadcn 86d9b00084 chore: update deps (#9022)
* feat: init

* fix

* fix

* fix

* feat

* feat

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* feat: implement icons

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* feat: update init command

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* feat: dialog

* feat

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* feat: add registry:base item type

* feat: rename frame to canva

* fix

* feat

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fi

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* feat: add all colors

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* feat: add outfit font

* fix

* fix

* fix

* fix

* fix

* chore: changeset

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix
2025-12-12 21:01:44 +04:00

127 lines
3.8 KiB
TypeScript

"use client"
import * as React from "react"
import { IconCheck, IconCopy } from "@tabler/icons-react"
import { useQueryStates } from "nuqs"
import { copyToClipboardWithMeta } from "@/components/copy-button"
import { Icons } from "@/components/icons"
import { DEFAULT_CONFIG } from "@/registry/config"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/registry/new-york-v4/ui/dialog"
import { designSystemSearchParams } from "@/app/(create)/lib/search-params"
export function ToolbarControls() {
const [open, setOpen] = React.useState(false)
const [params, setParams] = useQueryStates(designSystemSearchParams, {
shallow: false,
})
const [hasCopied, setHasCopied] = React.useState(false)
const command = React.useMemo(() => {
const origin = process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000"
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}`
return `pnpm shadcn create --preset ${url} -c ~/Playground`
}, [
params.base,
params.style,
params.baseColor,
params.theme,
params.iconLibrary,
params.font,
params.menuAccent,
params.menuColor,
params.radius,
])
React.useEffect(() => {
if (hasCopied) {
const timer = setTimeout(() => setHasCopied(false), 2000)
return () => clearTimeout(timer)
}
}, [hasCopied])
const handleCopy = React.useCallback(() => {
copyToClipboardWithMeta(command, {
name: "copy_npm_command",
properties: {
command,
},
})
setOpen(false)
setHasCopied(true)
}, [command, setOpen])
const handleReset = React.useCallback(() => {
setParams({
item: "cover",
iconLibrary: DEFAULT_CONFIG.iconLibrary,
style: DEFAULT_CONFIG.style,
theme: DEFAULT_CONFIG.theme,
font: DEFAULT_CONFIG.font,
baseColor: DEFAULT_CONFIG.baseColor,
menuAccent: DEFAULT_CONFIG.menuAccent,
menuColor: DEFAULT_CONFIG.menuColor,
radius: DEFAULT_CONFIG.radius,
size: 100,
custom: false,
})
}, [setParams])
return (
<div className="bg-background sticky bottom-0 flex gap-2">
<Button
size="sm"
variant="outline"
className="h-[31px] rounded-lg"
onClick={handleReset}
>
Reset
</Button>
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button size="sm" className="h-[31px] flex-1 rounded-lg">
Create Project
</Button>
</DialogTrigger>
<DialogContent className="dialog-ring sm:max-w-[600px]">
<DialogHeader>
<DialogTitle>Install shadcn/ui</DialogTitle>
<DialogDescription>
Run this command to start a new shadcn/ui project with your
selected configuration.
</DialogDescription>
</DialogHeader>
<div className="bg-surface text-surface-foreground relative overflow-hidden rounded-lg p-4">
<div className="no-scrollbar overflow-x-auto pr-10">
<code className="font-mono text-sm whitespace-nowrap">
{command}
</code>
</div>
</div>
<DialogFooter>
<Button
size="sm"
variant="secondary"
onClick={() => setOpen(false)}
>
Open in <Icons.v0 className="size-5" />
</Button>
<Button size="sm" onClick={handleCopy}>
Copy Command
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</div>
)
}