diff --git a/.github/workflows/validate-registries.yml b/.github/workflows/validate-registries.yml index f507116a11..fc86ae3317 100644 --- a/.github/workflows/validate-registries.yml +++ b/.github/workflows/validate-registries.yml @@ -16,7 +16,7 @@ jobs: check-registry-sync: if: github.event_name == 'pull_request' runs-on: ubuntu-latest - name: Check registry sync + name: check-registry-sync permissions: contents: read pull-requests: write @@ -66,6 +66,44 @@ jobs: with: node-version: 20 + - name: Block reserved registry namespaces + env: + RESERVED_NAMESPACES: "@shadcn,@ui,@blocks,@components,@block,@component,@util,@utils,@registry,@lib,@hook,@hooks,@theme,@themes,@chart,@charts" + run: | + node <<'EOF' + const fs = require("node:fs") + + const files = [ + "apps/v4/public/r/registries.json", + "apps/v4/registry/directory.json", + ] + const reservedNamespaces = new Set( + process.env.RESERVED_NAMESPACES.split(",").filter(Boolean) + ) + + function readNames(filePath) { + return JSON.parse(fs.readFileSync(filePath, "utf8")).map( + (entry) => entry.name + ) + } + + const violations = files.flatMap((filePath) => { + return readNames(filePath) + .filter((name) => reservedNamespaces.has(name)) + .map((name) => `${filePath}: ${name}`) + }) + + if (violations.length > 0) { + console.error("Reserved registry namespaces are not allowed:") + + for (const violation of violations) { + console.error(`- ${violation}`) + } + + process.exit(1) + } + EOF + - uses: pnpm/action-setup@v4 name: Install pnpm id: pnpm-install diff --git a/apps/v4/content/docs/installation/tanstack.mdx b/apps/v4/content/docs/installation/tanstack.mdx index e5f63ee5be..8d6ed917ab 100644 --- a/apps/v4/content/docs/installation/tanstack.mdx +++ b/apps/v4/content/docs/installation/tanstack.mdx @@ -16,13 +16,13 @@ description: Install and configure shadcn/ui for TanStack Start. Run the following command to create a new TanStack Start project with shadcn/ui: ```bash -npx shadcn@latest init -t tanstack +npx shadcn@latest init -t start ``` **For a monorepo project, use `--monorepo` flag:** ```bash -npx shadcn@latest init -t tanstack --monorepo +npx shadcn@latest init -t start --monorepo ``` ### Add Components diff --git a/apps/v4/package.json b/apps/v4/package.json index 3f5a441df2..af10a7627b 100644 --- a/apps/v4/package.json +++ b/apps/v4/package.json @@ -76,7 +76,7 @@ "rehype-pretty-code": "^0.14.1", "rimraf": "^6.0.1", "server-only": "^0.0.1", - "shadcn": "4.0.7", + "shadcn": "4.0.8", "shiki": "^1.10.1", "sonner": "^2.0.0", "swr": "^2.3.6", diff --git a/apps/v4/public/r/registries-legacy.json b/apps/v4/public/r/registries-legacy.json index 995f92c5a3..1c25f0bd89 100644 --- a/apps/v4/public/r/registries-legacy.json +++ b/apps/v4/public/r/registries-legacy.json @@ -41,7 +41,7 @@ "@gaia": "https://ui.heygaia.io/r/{name}.json", "@glass-ui": "https://glass-ui.crenspire.com/r/{name}.json", "@heseui": "https://www.heseui.com/r/{name}.json", - "@hooks": "https://shadcn-hooks.com/r/{name}.json", + "@shadcnhooks": "https://shadcn-hooks.com/r/{name}.json", "@intentui": "https://intentui.com/r/{name}", "@kibo-ui": "https://www.kibo-ui.com/r/{name}.json", "@kanpeki": "https://kanpeki.vercel.app/r/{name}.json", diff --git a/apps/v4/public/r/registries.json b/apps/v4/public/r/registries.json index f2c0d2e4bc..c3cd581e38 100644 --- a/apps/v4/public/r/registries.json +++ b/apps/v4/public/r/registries.json @@ -252,7 +252,7 @@ "description": "Ready-to-use foundation components/blocks built on top of shadcn/ui." }, { - "name": "@hooks", + "name": "@shadcnhooks", "homepage": "https://shadcn-hooks.com", "url": "https://shadcn-hooks.com/r/{name}.json", "description": "A comprehensive React Hooks Collection built with Shadcn." diff --git a/apps/v4/registry/__index__.tsx b/apps/v4/registry/__index__.tsx index f1f0f65357..2d4efb54ca 100644 --- a/apps/v4/registry/__index__.tsx +++ b/apps/v4/registry/__index__.tsx @@ -4888,6 +4888,44 @@ export const Index: Record> = { categories: undefined, meta: undefined, }, + "form-next-demo": { + name: "form-next-demo", + title: "undefined", + description: "", + type: "registry:example", + registryDependencies: ["field","input","textarea","button","card","spinner"], + files: [{ + path: "registry/new-york-v4/examples/form-next-demo.tsx", + type: "registry:example", + target: "" + }], + component: React.lazy(async () => { + const mod = await import("@/registry/new-york-v4/examples/form-next-demo.tsx") + const exportName = Object.keys(mod).find(key => typeof mod[key] === 'function' || typeof mod[key] === 'object') || item.name + return { default: mod.default || mod[exportName] } + }), + categories: undefined, + meta: undefined, + }, + "form-next-complex": { + name: "form-next-complex", + title: "undefined", + description: "", + type: "registry:example", + registryDependencies: ["field","input","textarea","button","card","spinner","checkbox","dialog","radio-group","select","switch"], + files: [{ + path: "registry/new-york-v4/examples/form-next-complex.tsx", + type: "registry:example", + target: "" + }], + component: React.lazy(async () => { + const mod = await import("@/registry/new-york-v4/examples/form-next-complex.tsx") + const exportName = Object.keys(mod).find(key => typeof mod[key] === 'function' || typeof mod[key] === 'object') || item.name + return { default: mod.default || mod[exportName] } + }), + categories: undefined, + meta: undefined, + }, "form-rhf-demo": { name: "form-rhf-demo", title: "undefined", diff --git a/apps/v4/registry/directory.json b/apps/v4/registry/directory.json index 3ca3c1c4a0..1f8e7605ab 100644 --- a/apps/v4/registry/directory.json +++ b/apps/v4/registry/directory.json @@ -295,7 +295,7 @@ "logo": "" }, { - "name": "@hooks", + "name": "@shadcnhooks", "homepage": "https://shadcn-hooks.com", "url": "https://shadcn-hooks.com/r/{name}.json", "description": "A comprehensive React Hooks Collection built with Shadcn.", diff --git a/apps/v4/registry/new-york-v4/examples/_registry.ts b/apps/v4/registry/new-york-v4/examples/_registry.ts index 43ba976275..48e27e2b12 100644 --- a/apps/v4/registry/new-york-v4/examples/_registry.ts +++ b/apps/v4/registry/new-york-v4/examples/_registry.ts @@ -950,6 +950,40 @@ export const examples: Registry["items"] = [ }, ], }, + { + name: "form-next-demo", + type: "registry:example", + registryDependencies: ["field", "input", "textarea", "button", "card", "spinner"], + files: [ + { + path: "examples/form-next-demo.tsx", + type: "registry:example", + }, + ], + }, + { + name: "form-next-complex", + type: "registry:example", + registryDependencies: [ + "field", + "input", + "textarea", + "button", + "card", + "spinner", + "checkbox", + "dialog", + "radio-group", + "select", + "switch", + ], + files: [ + { + path: "examples/form-next-complex.tsx", + type: "registry:example", + }, + ], + }, { name: "form-rhf-demo", type: "registry:example", diff --git a/packages/shadcn/CHANGELOG.md b/packages/shadcn/CHANGELOG.md index 741fafbbe8..8a9c7bdc3f 100644 --- a/packages/shadcn/CHANGELOG.md +++ b/packages/shadcn/CHANGELOG.md @@ -1,5 +1,11 @@ # @shadcn/ui +## 4.0.8 + +### Patch Changes + +- [#10041](https://github.com/shadcn-ui/ui/pull/10041) [`a97ebe54f1824032d8ad00d1d0c079e3dc6f52d7`](https://github.com/shadcn-ui/ui/commit/a97ebe54f1824032d8ad00d1d0c079e3dc6f52d7) Thanks [@shadcn](https://github.com/shadcn)! - Bundle @antfu/ni and tinyexec to fix missing module error with npx + ## 4.0.7 ### Patch Changes diff --git a/packages/shadcn/package.json b/packages/shadcn/package.json index 3d8390328b..52fe4fed2a 100644 --- a/packages/shadcn/package.json +++ b/packages/shadcn/package.json @@ -1,6 +1,6 @@ { "name": "shadcn", - "version": "4.0.7", + "version": "4.0.8", "description": "Add components to your apps.", "publishConfig": { "access": "public" @@ -79,7 +79,6 @@ "mcp:inspect": "pnpm dlx @modelcontextprotocol/inspector node dist/index.js mcp" }, "dependencies": { - "@antfu/ni": "^25.0.0", "@babel/core": "^7.28.0", "@babel/parser": "^7.28.0", "@babel/plugin-transform-typescript": "^7.28.0", @@ -116,6 +115,7 @@ "zod-to-json-schema": "^3.24.6" }, "devDependencies": { + "@antfu/ni": "^25.0.0", "@types/babel__core": "^7.20.5", "@types/fs-extra": "^11.0.4", "@types/prompts": "^2.4.9", diff --git a/packages/shadcn/tsup.config.ts b/packages/shadcn/tsup.config.ts index 12cb99bf2d..e7a411da60 100644 --- a/packages/shadcn/tsup.config.ts +++ b/packages/shadcn/tsup.config.ts @@ -19,6 +19,9 @@ export default defineConfig({ target: "esnext", outDir: "dist", treeshake: true, + // Bundle @antfu/ni and its dependency tinyexec to avoid + // module resolution failures with npx temporary installs. + noExternal: ["@antfu/ni", "tinyexec"], onSuccess: async () => { copyFileSync("src/tailwind.css", "dist/tailwind.css") }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4f89d549ec..01336aa661 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -278,7 +278,7 @@ importers: specifier: ^0.0.1 version: 0.0.1 shadcn: - specifier: 4.0.7 + specifier: 4.0.8 version: link:../../packages/shadcn shiki: specifier: ^1.10.1 @@ -359,9 +359,6 @@ importers: packages/shadcn: dependencies: - '@antfu/ni': - specifier: ^25.0.0 - version: 25.0.0 '@babel/core': specifier: ^7.28.0 version: 7.28.0 @@ -465,6 +462,9 @@ importers: specifier: ^3.24.6 version: 3.24.6(zod@3.25.76) devDependencies: + '@antfu/ni': + specifier: ^25.0.0 + version: 25.0.0 '@types/babel__core': specifier: ^7.20.5 version: 7.20.5