Compare commits

...

141 Commits

Author SHA1 Message Date
github-actions[bot]
b9f3ce1988 chore(release): version packages (#8217)
* chore(release): version packages

* chore(release): version packages

* ci: deps

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-09-15 16:27:20 +04:00
Elliot Sutton
cdf58be7e1 feat(shadcn): fix transformCssVars function (#8186)
* feat(shadcn): fix transformCssVars function

* test(shadcn): update snapshots

* chore: add changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-09-15 16:08:56 +04:00
Fuma Nama
fae1a81add fix(shadcn): fix async imports not being transformed (#8036)
* fix(shadcn): fix async imports not being transformed when installing components

* fix(shadcn): improve performance

* test(shadcn): add tests for transform import

* test: update timeout

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-09-15 14:55:18 +04:00
shadcn
fc6d909ba2 add getRegistriesIndex (#8216)
* feat: add getRegistriesIndex

* chore: changeset

* fix: formatting
2025-09-15 14:55:05 +04:00
shadcn
590b9be610 fix: toc 2025-09-15 10:52:27 +04:00
Dillion Verma
41eb9d5c46 fix: update magicui registry name (#8214)
Co-authored-by: shadcn <m@shadcn.com>
2025-09-15 10:48:43 +04:00
shadcn
b7c28199be docs: add import and plugin examples (#8215) 2025-09-15 10:46:58 +04:00
Maximilian Kaske
7869defd42 feat(charts): support legend and tooltip type none (#8082)
* feat(charts): support legend and tooltip type none

* fix: format

* chore: run registry:build

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-09-15 09:14:47 +04:00
Itzik Sokolov
6daa5215cc Add 97cn to registrries.json (#8207) 2025-09-15 08:34:42 +04:00
WebDevSimplified
722fb81b95 Add WDS registry URL to registries.json (#8193)
I am attempting to add the [Web Dev Simplified Shadcn Registry](https://wds-shadcn-registry.netlify.app) as an indexed registry.
2025-09-11 15:56:28 +04:00
Elliot Hesp
543be31722 docs: fix bad link to registry index (#8184) 2025-09-09 20:19:58 +04:00
Talha Mujahid
09b90cd5c2 Add @shadcn-editor registry URL to registries.json (#8177)
Co-authored-by: shadcn <m@shadcn.com>
2025-09-09 17:09:09 +04:00
Nitish
c95959a9b3 added rigidui to trusted registries (#8180)
Co-authored-by: shadcn <m@shadcn.com>
2025-09-09 17:06:31 +04:00
Sean
08820ce5ee feat: add @reui in trusted registries (#8181) 2025-09-09 17:04:45 +04:00
Arif Hossain
cb96e58992 feat: add @retroui in trusted registries (#8167)
* feat: add @retroui in trusted registries

* merge conflict resolve
2025-09-09 17:02:28 +04:00
Ali Hussein
fce5926265 Add formcn.dev to trusted registries (#8163)
Co-authored-by: shadcn <m@shadcn.com>
2025-09-08 16:04:47 +04:00
Rohan Gupta
f7c0f81258 feat: added limeplay registry (#8174)
Co-authored-by: shadcn <m@shadcn.com>
2025-09-08 15:40:36 +04:00
Gxuri
960b22b301 feat: add @skiper-ui to trusted registries (#8170)
* feat: add @skiper-ui to trusted registries

* Fix URL for @skiper-ui registry

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-09-08 15:37:32 +04:00
Elliot Sutton
6f057c9cc3 feat(v4): add @animate-ui to trusted registries (#8162) 2025-09-08 15:31:51 +04:00
shadcn
615a32d97a Merge branch 'main' of github.com:shadcn-ui/ui 2025-09-04 20:42:21 +04:00
shadcn
bfe6e1946c docs: update changelog 2025-09-04 20:41:50 +04:00
Railly Hugo
baaa82e4e7 feat: add @elements to trusted registries (#8155)
Co-authored-by: shadcn <m@shadcn.com>
2025-09-04 20:29:52 +04:00
Alex Carpenter
caeed7bd65 feat: Add @alexcarpenter registry to known registries (#8154) 2025-09-04 20:26:49 +04:00
Alex Carpenter
61254f0c3f feat: add clerk to known registries (#8153)
Co-authored-by: shadcn <m@shadcn.com>
2025-09-04 20:24:38 +04:00
Edu Calvo
3dcd797f2c feat: add @smoothui to trusted registries (#8152)
Co-authored-by: shadcn <m@shadcn.com>
2025-09-04 20:24:24 +04:00
Théo Ribbi
b76f5cdbf7 feat: add @nativeui to trusted registries (#8146)
Co-authored-by: shadcn <m@shadcn.com>
2025-09-04 20:20:15 +04:00
Ephraim Duncan
fcb1e2ca50 Add blocks registry URL to registries.json (#8145) 2025-09-04 20:18:48 +04:00
Sahil Tiwaskar
df94537e0f add billingsdk registry (#8148) 2025-09-04 16:01:35 +04:00
github-actions[bot]
275e3a2d59 chore(release): version packages (#8151)
* chore(release): version packages

* chore: deps

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-09-04 15:58:06 +04:00
shadcn
e5402f9a20 feat(shadcn): implement recursive registry namespaces (#8147)
* feat(shadcn): implement recursive registry namespaces

* fix
2025-09-04 15:40:18 +04:00
OrcDev
04668da018 feat: add @8bitcn to trusted registries (#8144) 2025-09-04 12:11:35 +04:00
github-actions[bot]
0805751703 chore(release): version packages (#8143)
* chore(release): version packages

* chore(release): version packages

* deps: update

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-09-04 11:43:40 +04:00
Denish Navadiya
9ecb19cf2e feat: add @paceui-ui in trusted registries (#8140)
* feat: add @paceui-ui in trusted registries

* feat: add @paceui-ui in trusted registries

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-09-04 11:30:42 +04:00
shadcn
9c5eb0d20f feat(shadcn): add support for registries index (#8128)
* feat(shadcn): add support for registries index

* fix

* fix

* chore: changeset

* feat(shadcn): update handling of add commands

* feat: add support for known registries

* docs: update index docs
2025-09-04 11:27:45 +04:00
Akash Moradiya
2752ce11d8 feat: add @basecn in trusted registries (#8142)
Co-authored-by: shadcn <m@shadcn.com>
2025-09-04 11:20:32 +04:00
Chánh Đại
d972caa853 feat: add @ncdai in trusted registries (#8141) 2025-09-04 10:30:58 +04:00
preet
00b2f0796e feat: add @hesaui in trusted registries (#8136)
Co-authored-by: shadcn <m@shadcn.com>
2025-09-03 20:27:25 +04:00
shadcn
3ed9af5757 ci: update registries workflow (#8135)
* ci: update registries workflow

* chore: remove invalid
2025-09-03 20:04:28 +04:00
Kokonut
a4237e38f7 feat: add kokonutui to open source registry (#8133) 2025-09-03 19:09:42 +04:00
David
1178d40352 feat: add @react-bits to registries.json (#8132) 2025-09-03 16:34:37 +04:00
shadcn
cc612359ee feat: add known open source registries (#8130)
* feat: add known open source registries

* feat: remove invalid registries
2025-09-03 12:14:23 +04:00
shadcn
4d0272a659 chore: add symlink 2025-09-03 11:50:08 +04:00
shadcn
a15534bdb7 feat: add ai-elements registry (#8129)
* feat: add ai-elements registry

* Fix URL for @ai-elements in registries.json
2025-09-03 10:47:08 +04:00
shadcn
62c41c3271 feat: add registries index (#8126)
* feat: add registries index

* ci: update workflow

* ci: update

* fix

* debug

* ci: debug

* debug

* fix: build

* refactor
2025-09-03 08:24:02 +04:00
github-actions[bot]
851c0fa0d1 chore(release): version packages (#8111)
* chore(release): version packages

* chore: deps

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-09-01 21:30:39 +04:00
shadcn
e84c819977 feat(shadcn): update handling of import and apply at rules (#8109)
* fix: plugin imports

* fix(shadcn): import in css

* feat(shadcn): allow empty body for apply rules

* chore: changeset

* fix: type issue
2025-09-01 20:02:26 +04:00
shadcn
64f8baf9aa feat(shadcn): allow empty files items (#8110)
* feat(shadcn): allow no files items

* feat(v4): add themes

* chore: changeset

* fix
2025-09-01 20:00:02 +04:00
Ahmed Zougari
4b44c6489a fix: update tailwindcss intellisense settings (#8095) 2025-08-31 14:25:19 +04:00
shadcn
f9021e9388 fix 2025-08-28 21:18:18 +04:00
shadcn
b1e3d4b740 feat: mcp 2025-08-28 20:58:03 +04:00
Nicolas Vargas
084fb927a1 Docs: Fix link to namespaced registries documentation (#8091)
Corrected the link to the namespaced registries documentation.
2025-08-27 21:46:19 +04:00
shadcn
7304ef2105 docs: add registry docs (#8080)
* docs(www): namespaced registries

* fix

* docs(www): add cli command to docs

* fix

* docs(www): update registry docs

* feat(shadcn): add mcp init command

* docs: restructure mcp docs

* chore: add changesets

* fix: formatting

* fix(shadcn): dependencies

* debug

* fix

* docs: add more troubleshooting docs

* docs: update registry docs

* feat(shadcn): add audit checklist tool

* chore: add mcp flag

* fix: format

* docs: replace beta with latest

* docs: add changelog

* fix
2025-08-27 19:25:21 +04:00
github-actions[bot]
b34f3fdc4f chore(release): version packages (#7941)
* chore(release): version packages

* chore: deps

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-08-27 19:10:35 +04:00
shadcn
2ecf876fa1 chore: beta to latest 2025-08-27 12:35:02 +04:00
shadcn
dcd2c3ef14 chore: beta to latest 2025-08-27 12:27:10 +04:00
shadcn
17422714f6 feat(shadcn): mcp init (#8086) 2025-08-27 12:05:21 +04:00
shadcn
fc27ba2692 fix(shadcn): fix --defaults options (#8081)
* fix(shadcn): fix defaults options

* chore: changeset
2025-08-26 15:49:43 +04:00
shadcn
f854190b53 fix(shadcn): load env (#8061) 2025-08-25 14:05:12 +04:00
shadcn
396275e46a feat(www): switch to md from mdx (#8019)
* feat(www): switch to md from mdx

* feat(www): update url
2025-08-13 16:08:20 +04:00
shadcn
296feb28a2 feat(shadcn): new mcp server (#8012)
* feat(shadcn): add getRegistriesConfig api

* feat(shadcn): add new mcp command

* feat(shadcn): add get_item_examples_from_registries and get_add_command_for_items

* feat: remove getRegistriesConfig

* chore: changeset
2025-08-13 11:15:26 +04:00
shadcn
a941287411 deps(shadcn): bump all dependencies (#8004)
* deps(shadcn): bump all dependencies

* chore: pin deps for fumadocs
2025-08-11 20:21:40 +04:00
shadcn
2e34c95c4e feat(shadcn): update search results format (#8003) 2025-08-11 15:52:02 +04:00
shadcn
fed7e3bfdc feat(shadcn): update signatures of apis (#8001)
* feat(shadcn): improve apis signature

* feat(shadcn): update signature of apis

* fix: tests snapshot
2025-08-11 14:34:10 +04:00
shadcn
4f5333ea7a feat(shadcn): add view command (#7994)
* feat(shadcn): add view command

* test(shadcn): add tests for view command

* feat(shadcn): allow shadow config in view command

* chore: changeset

* test(shadcn): skip view

* test(shadcn): update view port number

* feat(shadcn): add list command

* fix

* feat(shadcn): implement search command

* fix: tests

* fix

* chore: update changesets
2025-08-11 13:01:05 +04:00
shadcn
b5b8deedde chore: update changesets 2025-08-10 18:48:43 +04:00
shadcn
7d71b02fb1 feat(shadcn): add getRegistry (#7992) 2025-08-10 18:13:50 +04:00
shadcn
b3639227d0 feat(shadcn): deprecate fetchRegistry and resolveRegistryTree (#7990) 2025-08-10 16:25:04 +04:00
shadcn
a4a3600757 feat: move schema exports to shadcn/schema (#7989) 2025-08-10 16:05:53 +04:00
shadcn
a426fea941 refactor(shadcn): add getRegistryItems and resolveRegistryItems (#7983)
* feat(shadcn): refactor fetchFromRegistry

* refactor(shadcn): better api

* chore: changeset

* fix

* fix

* refactor

* refactor(shadcn): update getRegistryItems

* refactor(shadcn): error handling

* fix: getRegistryItems header context

* fix: tests

* feat(shadcn): export errors

* refactor(shadcn): getRegistryItems getRegistry

* fix

* fix

* fix

* fix

* chore: changeset

* chore: remove minor changeset
2025-08-10 15:20:38 +04:00
shadcn
6e870c3993 feat(shadcn): copy registry.json for build command (#7972)
* feat(shadcn): copy registry.json on build

* chore: changeset
2025-08-07 20:48:59 +04:00
shadcn
68aa3389de tests(shadcn): add more tests to cover registryResolveItemTree (#7971)
* tests(shadcn): add more registryResolveItemTree tests

* tests(shadcn): add more tests to cover registryResolveItemTree
2025-08-07 15:44:23 +04:00
shadcn
2e9ccede8f feat(shadcn): deduplicate files by target (#7969) 2025-08-07 14:33:17 +04:00
shadcn
fc8927a1f9 fix(shadcn): monorepo in nix system (#7962)
* debug: do not cd after init

* chore: changeset
2025-08-07 14:25:23 +04:00
shadcn
ccfd14946b feat: update schema.json to allow registries field (#7959) 2025-08-06 16:55:02 +04:00
shadcn
01c02b289a feat: add registry.json for all styles (#7958)
* feat: add style to registry

* feat: build registry.json for all styles
2025-08-06 16:22:32 +04:00
shadcn
a80ab37483 feat(shadcn): update file handling for monorepo (#7955)
* feat(shadcn): update monorepo handling

* feat(shadcn): update file handling for monorepo

* chore: changeset
2025-08-06 15:13:51 +04:00
shadcn
469250115f feat: update dependencies in monorepo (#7956) 2025-08-06 15:03:28 +04:00
shadcn
2c164b0f22 feat(shadcn): update registry dependencies resolution algorithm (#7948)
* feat(shadcn): update dependency resolution algorithm

* feat(shadcn): rename style to base-style

* feat(shadcn): init from namespaced

* fix(shadcn): force validation early

* chore: changeset

* fix(shadcn): headers

* fix: smh

* fix(shadcn): restore backup on exit and error
2025-08-06 13:38:08 +04:00
shadcn
578f83cbef chore: changeset (#7940) 2025-08-04 14:40:36 +04:00
shadcn
07eda36b13 feat(shadcn): add namespaced registries support (#7919)
* chore(shadcn): implement registries poc

* feat(shadcn): refactor our initial implementation

* feat(shadcn): properly resolve namespaced registryDependencies

* feat(shadcn): resolve namespaced registries recursively

* fix

* feat(shadcn): implement dotenv support

* test(shadcn): mock shadcn registry

* fix

* fix

* fix

* refactor(shadcn): update functions and tests

* refactor(shadcn): add fetchFromRegistry (#7937)

* fix

* feat(shadcn): add shadcn as a built-in registry

* fix

* feat(shadcn): update no framework and shadcn
2025-08-04 14:35:41 +04:00
shadcn
0eccdc9c5f docs: add docs for envVars 2025-07-30 12:22:40 +04:00
shadcn
0940c6aec7 chore: update deps 2025-07-30 12:11:45 +04:00
github-actions[bot]
e244952500 chore(release): version packages (#7909)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-30 12:10:45 +04:00
shadcn
0e3d6b24d3 test: fix flaky remote registry test (#7910)
* test: fix flaky remote registry test

* fix

* fix: test

* fix

* fix

* fix

* fix

* fix

* tests: cleanup
2025-07-30 12:06:13 +04:00
shadcn
cef5af9ed3 ci: bump version for changeset action 2025-07-29 17:08:48 +04:00
shadcn
6deb0fdbb6 chore: remove tests form changesets 2025-07-29 17:01:45 +04:00
shadcn
e9ae79f874 ci: fix 2025-07-29 16:57:16 +04:00
shadcn
d891132f2a test: remove init tests (#7908)
* test(shadcn): remove init test

* chore: changeset
2025-07-29 16:45:52 +04:00
shadcn
873f7f2773 feat: add tests package (#7907)
* feat: add tests package

* fix

* fix

* debug

* debug

* debug

* fix

* debug

* fix: no concurrent

* fix

* test: add vite-app tests

* test: add tests
2025-07-29 16:31:10 +04:00
shadcn
e6778dee87 feat(shadcn): add envVars to schema (#7902)
* feat(shadcn): add envVars to schema

* fix(shadcn): tests

* chore: changeset
2025-07-28 12:14:46 +04:00
shadcn
97a8de1c1b feat: update handling of env files in registry (#7896)
* feat: handle env update

* tests(shadcn): add tests for env helpers

* test(shadcn): update files test

* feat(shadcn): implement file alternatives

* test(shadcn): fix alternative handling

* fix(shadcn): env var logging

* test(shadcn): add tests for multi line env

* chore: changeset

* ci: update
2025-07-27 12:28:39 +04:00
shadcn
19d7fbb731 Use v4 blocks for Open in v0 (#7898)
* feat(www): use v4 blocks for v0

* fix: defaultIndex
2025-07-27 11:34:07 +04:00
shadcn
a9ab05ad83 Merge branch 'main' of github.com:shadcn-ui/ui 2025-07-23 11:57:19 +04:00
shadcn
6ac114ae68 feat: update hero 2025-07-23 11:57:05 +04:00
Mohit Khatri
d5770e4350 fix: resolve table overflow styling issues (#7874) 2025-07-23 11:32:05 +04:00
shadcn
4730276256 fix: spacing 2025-07-23 11:30:23 +04:00
shadcn
4e04567b07 deps: lock file 2025-07-23 10:58:45 +04:00
github-actions[bot]
6f63b04d28 chore(release): version packages (#7866)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-07-23 10:57:12 +04:00
shadcn
e38228b574 feat: implement open in (#7875)
* feat: implement open in

* fix: display
2025-07-23 10:30:32 +04:00
shadcn
8807103586 fix: index 2025-07-22 21:18:33 +04:00
shadcn
3424ab709e feat: add docs copy page (#7872) 2025-07-22 21:06:27 +04:00
shadcn
4a86a55cac feat(www): implement llm routes (#7868) 2025-07-22 19:59:38 +04:00
shadcn
2926574d0e fix(shadcn): universal item files type (#7867)
* fix(shadcn): universal item files type

* chore: changeset

* fix: style
2025-07-22 14:58:54 +04:00
shadcn
20e913d8e1 fix: handling of themes in registry (#7837) 2025-07-22 11:13:37 +04:00
github-actions[bot]
3433aaffaa chore(release): version packages (#7834)
* chore(release): version packages

* deps: lock

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-07-16 18:26:52 +04:00
shadcn
d9cdc3f7ae Revert "fix: handling of shouldOverwriteCssVars" (#7833)
* Revert "fix: handling of shouldOverwriteCssVars (#7829)"

This reverts commit ed5237c231.

* fix: revert
2025-07-16 18:22:40 +04:00
github-actions[bot]
e75e7b3866 chore(release): version packages (#7830)
* chore(release): version packages

* deps: update lock

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-07-16 17:52:23 +04:00
shadcn
ed5237c231 fix: handling of shouldOverwriteCssVars (#7829)
* fix(shadcn): handling of shouldOverwriteCssVars

* chore: changeset
2025-07-16 17:44:25 +04:00
shadcn
f85ca066dc deps: update 2025-07-11 18:41:06 +04:00
github-actions[bot]
54e66d4450 chore(release): version packages (#7758)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-07-11 18:23:59 +04:00
shadcn
6c341c16ae feat: fix safe target and add docs (#7795)
* feat: fix safe target and add docs

* chore: add changeset

* fix: changelog
2025-07-11 18:19:34 +04:00
shadcn
06d03d64f4 feat(shadcn): add support for universal registry item (#7782)
* feat(shadcn): add support for universal registry item

* chore: changeset
2025-07-10 20:17:45 +04:00
shadcn
6407a3b330 fix: chart 2025-07-09 15:52:31 +04:00
shadcn
96b15f6090 feat: update command menu pages and filtering (#7771) 2025-07-09 12:43:50 +04:00
shadcn
2fe9cf6d26 fix: pin recharts until we upgrade to v3 (#7769)
* fix: pin recharts

* docs: add v3 callout
2025-07-09 12:10:40 +04:00
Ehsanullah Haidary
728cb4cfa5 fix(component) Date Picker Dropdown values not visible in chrome, opera and edge (#7724)
* fix(component) Date Picker Dropdown values not visible in chrome, opera and edge

* fix(component) bg-popover added to dropdown in calendar.tsx to fix Date Picker Dropdown values not visible

* chore: build registry

* style: fix

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-07-09 11:43:15 +04:00
shadcn
db93787712 feat(shadcn): implement registry safe path (#7757)
* feat(shadcn): implement registry safe path

* chore: changeset

* style(shadcn): formatting

* fix
2025-07-08 20:25:14 +04:00
shadcn
1cdd6c1645 Merge branch 'main' of github.com:shadcn-ui/ui 2025-07-07 21:03:25 +04:00
shadcn
4983c6e1f4 chore: changelog 2025-07-07 21:03:06 +04:00
github-actions[bot]
7443edcfb0 chore(release): version packages (#7719)
* chore(release): version packages

* deps: lock

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-07-07 20:52:36 +04:00
shadcn
9d9a33be52 fix: margin 2025-07-07 15:10:32 +04:00
shadcn
d544a7f7a5 feat: refactor registryDependencies resolution (#7720)
* feat(shadcn): refactor registry dependencies resolution

* chore: changeset

* fix

* style: fix some code style
2025-07-01 17:56:50 +04:00
shadcn
48fe0d709f feat(shadcn): add file support (#7717)
* feat(shadcn): add file support

* fix: format

* fix: types

* feat(shadcn): update init and add description

* docs: update docs for cli

* chore: add changeset
2025-07-01 17:06:17 +04:00
Kitsune
ed244ea0b5 fix(cli): detect vinxi-based frameworks (@tanstack/start, SolidStart, ...) (#6330)
* fix(cli): detect vinxi-based frameworks

* chore: add changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-07-01 16:58:07 +04:00
Wolfr
b8fede1742 docs(v4): link to obra figma kit (#7643) 2025-06-30 11:45:49 +04:00
github-actions[bot]
84d6c83bad chore(release): version packages (#7626)
* chore(release): version packages

* chore(release): version packages

* deps: update lock

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-06-18 16:01:20 +04:00
xabierlameiro.com
5b8ee41511 fix(cli): correct function name typo unnsetSpreadElements to unsetSpreadElements (#7609)
* fix(cli): correct function name typo unnsetSpreadElements to unsetSpreadElements

* chore: add changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-06-18 11:44:59 +04:00
shadcn
7c3d34cdc9 chore: fix changeset (#7640)
* fix(shadcn): update plugin handling

* style(shadcn): format fix

* docs(www): add docs for plugins

* chore: add changeset
2025-06-18 11:29:23 +04:00
shadcn
56c4c83511 fix(shadcn): update plugin handling (#7632)
* fix(shadcn): update plugin handling

* style(shadcn): format fix

* docs(www): add docs for plugins
2025-06-18 11:03:36 +04:00
shadcn
2821cb0e39 chore: move cli to deprecated (#7631) 2025-06-17 12:32:10 +04:00
Wolfr
3c87402de2 Add newly available Figma kit to docs (#7604)
Co-authored-by: shadcn <m@shadcn.com>
2025-06-16 16:21:26 +04:00
xabierlameiro.com
20a88e1f15 fix(components): resolve duplicate id conflict in calendar-24 component (#7611)
* fix(components): resolve duplicate id conflict in calendar-24 component

- Changed Button id from 'date' to 'date-picker'
- Changed Input id from 'time' to 'time-picker'
- Updated corresponding Label htmlFor attributes to match new unique IDs

Fixes #7561

* chore: rebuild registry after calendar-24 fixes
2025-06-16 16:13:51 +04:00
Zach Nugent
cb19ab8464 feat(shadcn): add support for updating dependencies with expo-cli for RN compatibility (#7540)
* feat(shadcn): add support for updating dependencies with expo-cli for RN compatibility

* feat(shadcn): add expo as a framework

* fix: update the contributing command for registry

* refactor(shadcn): update dependencies install functionality

* chore: changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-06-16 16:05:41 +04:00
github-actions[bot]
cf1851ca09 chore(release): version packages (#7625)
* chore(release): version packages

* deps: update lock

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-06-16 15:45:23 +04:00
Manuel Schiller
c86c27a2ff fix TanStack Start detection (#7601)
* fix tanstack start detection

* chore: changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-06-16 15:24:41 +04:00
Gaëtan H
8847126c65 chore(vscode): set custom Tailwind config path for monorepo UI (#7618)
Co-authored-by: shadcn <m@shadcn.com>
2025-06-16 15:18:27 +04:00
shadcn
65350857a4 ci: fix stale bot (#7624) 2025-06-16 15:02:53 +04:00
shadcn
40c7473c7e fix(www): update open-in-v0-cta.tsx 2025-06-14 06:20:16 +04:00
Taesu
4698ee960f chore: update react-day-picker version to match updated calendar component (#7585)
Co-authored-by: shadcn <m@shadcn.com>
2025-06-12 15:44:40 +04:00
github-actions[bot]
2ae0e5a07b chore(release): version packages (#7595)
* chore(release): version packages

* deps: install

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-06-11 20:06:18 +04:00
shadcn
431af4f7ff fix(shadcn): semicolon in code style (#7594)
* fix(shadcn): handle semicolon in code style

* chore: changeset

* fix: format
2025-06-11 19:54:04 +04:00
328 changed files with 73535 additions and 9268 deletions

View File

@@ -7,5 +7,5 @@
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": ["www", "v4"]
"ignore": ["www", "v4", "tests"]
}

View File

@@ -0,0 +1,9 @@
{
"permissions": {
"allow": [
"Bash(npm test:*)",
"Bash(npm run typecheck:*)"
],
"deny": []
}
}

View File

@@ -18,15 +18,15 @@ jobs:
repo-token: ${{ secrets.STALE_TOKEN }}
ascending: true
days-before-issue-close: 7
days-before-issue-stale: 365 # ~2 years
days-before-issue-stale: 365
days-before-pr-stale: -1
days-before-pr-close: -1
remove-issue-stale-when-updated: true
stale-issue-label: "stale?"
exempt-issue-labels: "roadmap,next,bug"
stale-issue-message: "This issue has been automatically marked as stale due to one year of inactivity. It will be closed in 7 days unless theres further input. If you believe this issue is still relevant, please leave a comment or provide updated details. Thank you."
close-issue-message: "This issue has been automatically closed due to one year of inactivity. If youre still experiencing a similar problem or have additional details to share, please open a new issue following our current issue template. Your updated report helps us investigate and address concerns more efficiently. Thank you for your understanding!"
operations-per-run: 300 # 1 operation per 100 issues, the rest is to label/comment/close
exempt-issue-labels: "roadmap,next"
stale-issue-message: "This issue has been automatically marked as stale due to one year of inactivity. It will be closed in 7 days unless theres further input. If you believe this issue is still relevant, please leave a comment or provide updated details. Thank you. (This is an automated message)"
close-issue-message: "This issue has been automatically closed due to one year of inactivity. If youre still experiencing a similar problem or have additional details to share, please open a new issue following our current issue template. Your updated report helps us investigate and address concerns more efficiently. Thank you for your understanding! (This is an automated message)"
operations-per-run: 300
- uses: actions/stale@v9
id: pr-state
name: "Mark stale PRs, close stale PRs"
@@ -36,10 +36,10 @@ jobs:
days-before-issue-close: -1
days-before-issue-stale: -1
days-before-pr-close: 7
days-before-pr-stale: 365 # PRs with no activity in over 90 days will be marked as stale
days-before-pr-stale: 365
remove-pr-stale-when-updated: true
exempt-pr-labels: "roadmap,nex,awaiting-approval,work-in-progress"
exempt-pr-labels: "roadmap,next,bug"
stale-pr-label: "stale?"
stale-pr-message: "This PR has been automatically marked as stale due to one year of inactivity. It will be closed in 7 days unless theres further input. If you believe this PR is still relevant, please leave a comment or provide updated details. Thank you."
close-pr-message: "This PR has been automatically closed due to one year of inactivity. Thank you for your understanding!"
operations-per-run: 300 # 1 operation per 100 issues, the rest is to label/comment/close
stale-pr-message: "This PR has been automatically marked as stale due to one year of inactivity. It will be closed in 7 days unless theres further input. If you believe this PR is still relevant, please leave a comment or provide updated details. Thank you. (This is an automated message)"
close-pr-message: "This PR has been automatically closed due to one year of inactivity. Thank you for your understanding! (This is an automated message)"
operations-per-run: 300

View File

@@ -41,7 +41,7 @@ jobs:
- name: Create Version PR or Publish to NPM
id: changesets
uses: changesets/action@v1.4.1
uses: changesets/action@v1
with:
commit: "chore(release): version packages"
title: "chore(release): version packages"

View File

@@ -8,6 +8,9 @@ jobs:
test:
runs-on: ubuntu-latest
name: pnpm test
env:
NEXT_PUBLIC_APP_URL: http://localhost:4000
NEXT_PUBLIC_V0_URL: https://v0.dev
steps:
- uses: actions/checkout@v3
with:
@@ -39,4 +42,7 @@ jobs:
- name: Install dependencies
run: pnpm install
- name: Build packages
run: pnpm build --filter=shadcn
- run: pnpm test

View File

@@ -0,0 +1,54 @@
name: Validate Registries
on:
pull_request:
paths:
- "apps/v4/public/r/registries.json"
push:
branches:
- main
paths:
- "apps/v4/public/r/registries.json"
jobs:
validate:
runs-on: ubuntu-latest
name: pnpm validate:registries
permissions:
contents: read
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 20
- uses: pnpm/action-setup@v4
name: Install pnpm
id: pnpm-install
with:
version: 9.0.6
run_install: false
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install
- name: Build packages
run: pnpm build --filter=shadcn
- name: Validate registries
run: pnpm --filter=v4 validate:registries

View File

@@ -3,12 +3,7 @@
{ "pattern": "apps/*/" },
{ "pattern": "packages/*/" }
],
"tailwindCSS.experimental.classRegex": [
["cva\\(((?:[^()]|\\([^()]*\\))*)\\)", "[\"'`]?([^\"'`]+)[\"'`]?"],
["cn\\(((?:[^()]|\\([^()]*\\))*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
// "cva\\(([^)]*)\\)",
// "[\"'`]([^\"'`]*).*?[\"'`]"
],
"tailwindCSS.classFunctions": ["cva", "cn"],
"vitest.debugExclude": [
"<node_internals>/**",
"**/node_modules/**",

View File

@@ -98,7 +98,7 @@ To run the CLI locally, you can follow the workflow:
1. Start by running the registry (main site) to make sure the components are up to date:
```bash
pnpm www:dev
pnpm v4:dev
```
2. Run the development script for the CLI:

2
apps/v4/.env.example Normal file
View File

@@ -0,0 +1,2 @@
NEXT_PUBLIC_V0_URL=https://v0.dev
NEXT_PUBLIC_APP_URL=http://localhost:4000

1
apps/v4/.gitignore vendored
View File

@@ -32,6 +32,7 @@ yarn-error.log*
# env files (can opt-in for committing if needed)
.env*
!.env.example
# vercel
.vercel

View File

@@ -15,9 +15,9 @@ import { PageNav } from "@/components/page-nav"
import { ThemeSelector } from "@/components/theme-selector"
import { Button } from "@/registry/new-york-v4/ui/button"
const title = "Build your Component Library"
const title = "The Foundation for your Design System"
const description =
"A set of beautifully-designed, accessible components and a code distribution platform. Works with your favorite frameworks. Open Source. Open Code."
"A set of beautifully designed components that you can customize, extend, and build on. Start here then make it your own. Open Source. Open Code."
export const dynamic = "force-static"
export const revalidate = false
@@ -51,14 +51,14 @@ export default function IndexPage() {
<div className="flex flex-1 flex-col">
<PageHeader>
<Announcement />
<PageHeaderHeading>{title}</PageHeaderHeading>
<PageHeaderHeading className="max-w-4xl">{title}</PageHeaderHeading>
<PageHeaderDescription>{description}</PageHeaderDescription>
<PageActions>
<Button asChild size="sm">
<Link href="/docs/installation">Get Started</Link>
</Button>
<Button asChild size="sm" variant="ghost">
<Link href="/blocks">Browse Blocks</Link>
<Link href="/docs/components">View Components</Link>
</Button>
</PageActions>
</PageHeader>

View File

@@ -10,6 +10,7 @@ import { findNeighbour } from "fumadocs-core/server"
import { source } from "@/lib/source"
import { absoluteUrl } from "@/lib/utils"
import { DocsCopyPage } from "@/components/docs-copy-page"
import { DocsTableOfContents } from "@/components/docs-toc"
import { OpenInV0Cta } from "@/components/open-in-v0-cta"
import { Badge } from "@/registry/new-york-v4/ui/badge"
@@ -102,12 +103,17 @@ export default async function Page(props: {
<h1 className="scroll-m-20 text-4xl font-semibold tracking-tight sm:text-3xl xl:text-4xl">
{doc.title}
</h1>
<div className="flex items-center gap-2 pt-1.5">
<div className="docs-nav bg-background/80 border-border/50 fixed inset-x-0 bottom-0 isolate z-50 flex items-center gap-2 border-t px-6 py-4 backdrop-blur-sm sm:static sm:z-0 sm:border-t-0 sm:bg-transparent sm:px-0 sm:pt-1.5 sm:backdrop-blur-none">
<DocsCopyPage
// @ts-expect-error - revisit fumadocs types.
page={doc.content}
url={absoluteUrl(page.url)}
/>
{neighbours.previous && (
<Button
variant="secondary"
size="icon"
className="extend-touch-target size-8 shadow-none md:size-7"
className="extend-touch-target ml-auto size-8 shadow-none md:size-7"
asChild
>
<Link href={neighbours.previous.url}>
@@ -160,7 +166,7 @@ export default async function Page(props: {
<MDX components={mdxComponents} />
</div>
</div>
<div className="mx-auto flex h-16 w-full max-w-2xl items-center gap-2 px-4 md:px-0">
<div className="mx-auto hidden h-16 w-full max-w-2xl items-center gap-2 px-4 sm:flex md:px-0">
{neighbours.previous && (
<Button
variant="secondary"
@@ -187,7 +193,7 @@ export default async function Page(props: {
)}
</div>
</div>
<div className="sticky top-[calc(var(--header-height)+1px)] z-30 ml-auto hidden h-[calc(100svh-var(--header-height)-var(--footer-height))] w-72 flex-col gap-4 overflow-hidden overscroll-none pb-8 xl:flex">
<div className="sticky top-[calc(var(--header-height)+1px)] z-30 ml-auto hidden h-[calc(100svh-var(--footer-height)+2rem)] w-72 flex-col gap-4 overflow-hidden overscroll-none pb-8 xl:flex">
<div className="h-(--top-spacing) shrink-0" />
{/* @ts-expect-error - revisit fumadocs types. */}
{doc.toc?.length ? (

View File

@@ -75,7 +75,7 @@ export function DataTable<TData, TValue>({
return (
<div className="flex flex-col gap-4">
<DataTableToolbar table={table} />
<div className="rounded-md border">
<div className="overflow-hidden rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (

View File

@@ -0,0 +1,29 @@
import { notFound } from "next/navigation"
import { NextResponse, type NextRequest } from "next/server"
import { source } from "@/lib/source"
export const revalidate = false
export async function GET(
_req: NextRequest,
{ params }: { params: Promise<{ slug: string[] }> }
) {
const slug = (await params).slug
const page = source.getPage(slug)
if (!page) {
notFound()
}
// @ts-expect-error - revisit fumadocs types.
return new NextResponse(page.data.content, {
headers: {
"Content-Type": "text/markdown; charset=utf-8",
},
})
}
export function generateStaticParams() {
return source.generateParams()
}

View File

@@ -1,7 +1,7 @@
import * as React from "react"
import { Metadata } from "next"
import { notFound } from "next/navigation"
import { registryItemSchema } from "shadcn/registry"
import { registryItemSchema } from "shadcn/schema"
import { z } from "zod"
import { siteConfig } from "@/lib/config"

View File

@@ -6,8 +6,8 @@ import { Badge } from "@/registry/new-york-v4/ui/badge"
export function Announcement() {
return (
<Badge asChild variant="secondary" className="rounded-full">
<Link href="/docs/components/calendar">
New Calendar Component <ArrowRightIcon />
<Link href="/docs/changelog">
Now available: shadcn CLI 3.0 and MCP Server <ArrowRightIcon />
</Link>
</Badge>
)

View File

@@ -1,5 +1,5 @@
import * as React from "react"
import { registryItemFileSchema } from "shadcn/registry"
import { registryItemFileSchema } from "shadcn/schema"
import { z } from "zod"
import { highlightCode } from "@/lib/highlight-code"

View File

@@ -17,7 +17,7 @@ import {
Terminal,
} from "lucide-react"
import { ImperativePanelHandle } from "react-resizable-panels"
import { registryItemFileSchema, registryItemSchema } from "shadcn/registry"
import { registryItemFileSchema, registryItemSchema } from "shadcn/schema"
import { z } from "zod"
import { trackEvent } from "@/lib/events"

View File

@@ -15,7 +15,7 @@ export function Callout({
return (
<Alert
className={cn(
"bg-surface text-surface-foreground mt-6 w-auto border-none md:-mx-4",
"bg-surface text-surface-foreground mt-6 w-auto border-none md:-mx-1",
className
)}
{...props}

View File

@@ -209,7 +209,7 @@ export function CardsPayments() {
</CardAction>
</CardHeader>
<CardContent className="flex flex-col gap-4">
<div className="rounded-md border">
<div className="overflow-hidden rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (

View File

@@ -1,5 +1,5 @@
import * as React from "react"
import { registryItemSchema } from "shadcn/registry"
import { registryItemSchema } from "shadcn/schema"
import { z } from "zod"
import { highlightCode } from "@/lib/highlight-code"

View File

@@ -22,7 +22,7 @@ export function CodeCollapsibleWrapper({
<Collapsible
open={isOpened}
onOpenChange={setIsOpened}
className={cn("group/collapsible relative md:-mx-4", className)}
className={cn("group/collapsible relative md:-mx-1", className)}
{...props}
>
<CollapsibleTrigger asChild>

View File

@@ -7,6 +7,7 @@ import { IconArrowRight } from "@tabler/icons-react"
import { CornerDownLeftIcon, SquareDashedIcon } from "lucide-react"
import { type Color, type ColorPalette } from "@/lib/colors"
import { showMcpDocs } from "@/lib/flags"
import { source } from "@/lib/source"
import { cn } from "@/lib/utils"
import { useConfig } from "@/hooks/use-config"
@@ -36,11 +37,13 @@ export function CommandMenu({
tree,
colors,
blocks,
navItems,
...props
}: DialogProps & {
tree: typeof source.pageTree
colors: ColorPalette[]
blocks?: { name: string; description: string; categories: string[] }[]
navItems?: { href: string; label: string }[]
}) {
const router = useRouter()
const isMac = useIsMac()
@@ -162,12 +165,45 @@ export function CommandMenu({
<DialogTitle>Search documentation...</DialogTitle>
<DialogDescription>Search for a command to run...</DialogDescription>
</DialogHeader>
<Command className="**:data-[slot=command-input-wrapper]:bg-input/50 **:data-[slot=command-input-wrapper]:border-input rounded-none bg-transparent **:data-[slot=command-input]:!h-9 **:data-[slot=command-input]:py-0 **:data-[slot=command-input-wrapper]:mb-0 **:data-[slot=command-input-wrapper]:!h-9 **:data-[slot=command-input-wrapper]:rounded-md **:data-[slot=command-input-wrapper]:border">
<Command
className="**:data-[slot=command-input-wrapper]:bg-input/50 **:data-[slot=command-input-wrapper]:border-input rounded-none bg-transparent **:data-[slot=command-input]:!h-9 **:data-[slot=command-input]:py-0 **:data-[slot=command-input-wrapper]:mb-0 **:data-[slot=command-input-wrapper]:!h-9 **:data-[slot=command-input-wrapper]:rounded-md **:data-[slot=command-input-wrapper]:border"
filter={(value, search, keywords) => {
const extendValue = value + " " + (keywords?.join(" ") || "")
if (extendValue.toLowerCase().includes(search.toLowerCase())) {
return 1
}
return 0
}}
>
<CommandInput placeholder="Search documentation..." />
<CommandList className="no-scrollbar min-h-80 scroll-pt-2 scroll-pb-1.5">
<CommandEmpty className="text-muted-foreground py-12 text-center text-sm">
No results found.
</CommandEmpty>
{navItems && navItems.length > 0 && (
<CommandGroup
heading="Pages"
className="!p-0 [&_[cmdk-group-heading]]:scroll-mt-16 [&_[cmdk-group-heading]]:!p-3 [&_[cmdk-group-heading]]:!pb-1"
>
{navItems.map((item) => (
<CommandMenuItem
key={item.href}
value={`Navigation ${item.label}`}
keywords={["nav", "navigation", item.label.toLowerCase()]}
onHighlight={() => {
setSelectedType("page")
setCopyPayload("")
}}
onSelect={() => {
runCommand(() => router.push(item.href))
}}
>
<IconArrowRight />
{item.label}
</CommandMenuItem>
))}
</CommandGroup>
)}
{tree.children.map((group) => (
<CommandGroup
key={group.$id}
@@ -179,6 +215,10 @@ export function CommandMenu({
if (item.type === "page") {
const isComponent = item.url.includes("/components/")
if (!showMcpDocs && item.url.includes("/mcp")) {
return null
}
return (
<CommandMenuItem
key={item.url}

View File

@@ -51,7 +51,7 @@ export function ComponentPreviewTabs({
</Tabs>
<div
data-tab={tab}
className="data-[tab=code]:border-code relative rounded-lg border md:-mx-4"
className="data-[tab=code]:border-code relative rounded-lg border md:-mx-1"
>
<div
data-slot="preview"

View File

@@ -34,7 +34,7 @@ export function ComponentPreview({
if (type === "block") {
return (
<div className="relative aspect-[4/2.5] w-full overflow-hidden rounded-md border md:-mx-4">
<div className="relative aspect-[4/2.5] w-full overflow-hidden rounded-md border md:-mx-1">
<Image
src={`/r/styles/new-york-v4/${name}-light.png`}
alt={name}

View File

@@ -1,33 +1,156 @@
"use client"
import { IconCheck, IconCopy } from "@tabler/icons-react"
import { IconCheck, IconChevronDown, IconCopy } from "@tabler/icons-react"
import { useCopyToClipboard } from "@/hooks/use-copy-to-clipboard"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/registry/new-york-v4/ui/tooltip"
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/registry/new-york-v4/ui/dropdown-menu"
import {
Popover,
PopoverAnchor,
PopoverContent,
PopoverTrigger,
} from "@/registry/new-york-v4/ui/popover"
import { Separator } from "@/registry/new-york-v4/ui/separator"
export function DocsCopyPage({ page }: { page: string }) {
function getPromptUrl(baseURL: string, url: string) {
return `${baseURL}?q=${encodeURIComponent(
`Im looking at this shadcn/ui documentation: ${url}.
Help me understand how to use it. Be ready to explain concepts, give examples, or help debug based on it.
`
)}`
}
const menuItems = {
markdown: (url: string) => (
<a href={`${url}.md`} target="_blank" rel="noopener noreferrer">
<svg strokeLinejoin="round" viewBox="0 0 22 16">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M19.5 2.25H2.5C1.80964 2.25 1.25 2.80964 1.25 3.5V12.5C1.25 13.1904 1.80964 13.75 2.5 13.75H19.5C20.1904 13.75 20.75 13.1904 20.75 12.5V3.5C20.75 2.80964 20.1904 2.25 19.5 2.25ZM2.5 1C1.11929 1 0 2.11929 0 3.5V12.5C0 13.8807 1.11929 15 2.5 15H19.5C20.8807 15 22 13.8807 22 12.5V3.5C22 2.11929 20.8807 1 19.5 1H2.5ZM3 4.5H4H4.25H4.6899L4.98715 4.82428L7 7.02011L9.01285 4.82428L9.3101 4.5H9.75H10H11V5.5V11.5H9V7.79807L7.73715 9.17572L7 9.97989L6.26285 9.17572L5 7.79807V11.5H3V5.5V4.5ZM15 8V4.5H17V8H19.5L17 10.5L16 11.5L15 10.5L12.5 8H15Z"
fill="currentColor"
/>
</svg>
View as Markdown
</a>
),
v0: (url: string) => (
<a
href={getPromptUrl("https://v0.dev", url)}
target="_blank"
rel="noopener noreferrer"
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 147 70"
className="size-4.5 -translate-x-px"
>
<path d="M56 50.203V14h14v46.156C70 65.593 65.593 70 60.156 70c-2.596 0-5.158-1-7-2.843L0 14h19.797L56 50.203ZM147 56h-14V23.953L100.953 56H133v14H96.687C85.814 70 77 61.186 77 50.312V14h14v32.156L123.156 14H91V0h36.312C138.186 0 147 8.814 147 19.688V56Z" />
</svg>
<span className="-translate-x-[2px]">Open in v0</span>
</a>
),
chatgpt: (url: string) => (
<a
href={getPromptUrl("https://chatgpt.com", url)}
target="_blank"
rel="noopener noreferrer"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
d="M22.282 9.821a5.985 5.985 0 0 0-.516-4.91 6.046 6.046 0 0 0-6.51-2.9A6.065 6.065 0 0 0 4.981 4.18a5.985 5.985 0 0 0-3.998 2.9 6.046 6.046 0 0 0 .743 7.097 5.98 5.98 0 0 0 .51 4.911 6.051 6.051 0 0 0 6.515 2.9A5.985 5.985 0 0 0 13.26 24a6.056 6.056 0 0 0 5.772-4.206 5.99 5.99 0 0 0 3.997-2.9 6.056 6.056 0 0 0-.747-7.073zM13.26 22.43a4.476 4.476 0 0 1-2.876-1.04l.141-.081 4.779-2.758a.795.795 0 0 0 .392-.681v-6.737l2.02 1.168a.071.071 0 0 1 .038.052v5.583a4.504 4.504 0 0 1-4.494 4.494zM3.6 18.304a4.47 4.47 0 0 1-.535-3.014l.142.085 4.783 2.759a.771.771 0 0 0 .78 0l5.843-3.369v2.332a.08.08 0 0 1-.033.062L9.74 19.95a4.5 4.5 0 0 1-6.14-1.646zM2.34 7.896a4.485 4.485 0 0 1 2.366-1.973V11.6a.766.766 0 0 0 .388.676l5.815 3.355-2.02 1.168a.076.076 0 0 1-.071 0l-4.83-2.786A4.504 4.504 0 0 1 2.34 7.872zm16.597 3.855-5.833-3.387L15.119 7.2a.076.076 0 0 1 .071 0l4.83 2.791a4.494 4.494 0 0 1-.676 8.105v-5.678a.79.79 0 0 0-.407-.667zm2.01-3.023-.141-.085-4.774-2.782a.776.776 0 0 0-.785 0L9.409 9.23V6.897a.066.066 0 0 1 .028-.061l4.83-2.787a4.5 4.5 0 0 1 6.68 4.66zm-12.64 4.135-2.02-1.164a.08.08 0 0 1-.038-.057V6.075a4.5 4.5 0 0 1 7.375-3.453l-.142.08-4.778 2.758a.795.795 0 0 0-.393.681zm1.097-2.365 2.602-1.5 2.607 1.5v2.999l-2.597 1.5-2.607-1.5Z"
fill="currentColor"
/>
</svg>
Open in ChatGPT
</a>
),
claude: (url: string) => (
<a
href={getPromptUrl("https://claude.ai/new", url)}
target="_blank"
rel="noopener noreferrer"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path
d="m4.714 15.956 4.718-2.648.079-.23-.08-.128h-.23l-.79-.048-2.695-.073-2.337-.097-2.265-.122-.57-.121-.535-.704.055-.353.48-.321.685.06 1.518.104 2.277.157 1.651.098 2.447.255h.389l.054-.158-.133-.097-.103-.098-2.356-1.596-2.55-1.688-1.336-.972-.722-.491L2 6.223l-.158-1.008.655-.722.88.06.225.061.893.686 1.906 1.476 2.49 1.833.364.304.146-.104.018-.072-.164-.274-1.354-2.446-1.445-2.49-.644-1.032-.17-.619a2.972 2.972 0 0 1-.103-.729L6.287.133 6.7 0l.995.134.42.364.619 1.415L9.735 4.14l1.555 3.03.455.898.243.832.09.255h.159V9.01l.127-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.583.28.48.685-.067.444-.286 1.851-.558 2.903-.365 1.942h.213l.243-.242.983-1.306 1.652-2.064.728-.82.85-.904.547-.431h1.032l.759 1.129-.34 1.166-1.063 1.347-.88 1.142-1.263 1.7-.79 1.36.074.11.188-.02 2.853-.606 1.542-.28 1.84-.315.832.388.09.395-.327.807-1.967.486-2.307.462-3.436.813-.043.03.049.061 1.548.146.662.036h1.62l3.018.225.79.522.473.638-.08.485-1.213.62-1.64-.389-3.825-.91-1.31-.329h-.183v.11l1.093 1.068 2.003 1.81 2.508 2.33.127.578-.321.455-.34-.049-2.204-1.657-.85-.747-1.925-1.62h-.127v.17l.443.649 2.343 3.521.122 1.08-.17.353-.607.213-.668-.122-1.372-1.924-1.415-2.168-1.141-1.943-.14.08-.674 7.254-.316.37-.728.28-.607-.461-.322-.747.322-1.476.388-1.924.316-1.53.285-1.9.17-.632-.012-.042-.14.018-1.432 1.967-2.18 2.945-1.724 1.845-.413.164-.716-.37.066-.662.401-.589 2.386-3.036 1.439-1.882.929-1.086-.006-.158h-.055L4.138 18.56l-1.13.146-.485-.456.06-.746.231-.243 1.907-1.312Z"
fill="currentColor"
/>
</svg>
Open in Claude
</a>
),
}
export function DocsCopyPage({ page, url }: { page: string; url: string }) {
const { copyToClipboard, isCopied } = useCopyToClipboard()
const trigger = (
<Button
variant="secondary"
size="sm"
className="peer -ml-0.5 size-8 shadow-none md:size-7 md:text-[0.8rem]"
>
<IconChevronDown className="rotate-180 sm:rotate-0" />
</Button>
)
return (
<Tooltip>
<TooltipTrigger asChild>
<Popover>
<div className="bg-secondary group/buttons relative flex rounded-lg *:[[data-slot=button]]:focus-visible:relative *:[[data-slot=button]]:focus-visible:z-10">
<PopoverAnchor />
<Button
variant="outline"
variant="secondary"
size="sm"
className="h-8 pl-1.5 md:h-7 [&>svg]:size-3.5"
className="h-8 shadow-none md:h-7 md:text-[0.8rem]"
onClick={() => copyToClipboard(page)}
>
{isCopied ? <IconCheck /> : <IconCopy />} Copy Page
{isCopied ? <IconCheck /> : <IconCopy />}
Copy Page
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Copy as Markdown</p>
</TooltipContent>
</Tooltip>
<DropdownMenu>
<DropdownMenuTrigger asChild className="hidden sm:flex">
{trigger}
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="shadow-none">
{Object.entries(menuItems).map(([key, value]) => (
<DropdownMenuItem key={key} asChild>
{value(url)}
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
<Separator
orientation="vertical"
className="!bg-foreground/10 absolute top-0 right-8 z-0 !h-8 peer-focus-visible:opacity-0 sm:right-7 sm:!h-7"
/>
<PopoverTrigger asChild className="flex sm:hidden">
{trigger}
</PopoverTrigger>
<PopoverContent
className="bg-background/70 dark:bg-background/60 w-52 !origin-center rounded-lg p-1 shadow-sm backdrop-blur-sm"
align="start"
>
{Object.entries(menuItems).map(([key, value]) => (
<Button
variant="ghost"
size="lg"
asChild
key={key}
className="*:[svg]:text-muted-foreground w-full justify-start text-base font-normal"
>
{value(url)}
</Button>
))}
</PopoverContent>
</div>
</Popover>
)
}

View File

@@ -3,6 +3,7 @@
import Link from "next/link"
import { usePathname } from "next/navigation"
import { showMcpDocs } from "@/lib/flags"
import type { source } from "@/lib/source"
import {
Sidebar,
@@ -15,6 +16,28 @@ import {
SidebarMenuItem,
} from "@/registry/new-york-v4/ui/sidebar"
const TOP_LEVEL_SECTIONS = [
{ name: "Get Started", href: "/docs" },
{
name: "Components",
href: "/docs/components",
},
{
name: "Registry",
href: "/docs/registry",
},
{
name: "MCP Server",
href: "/docs/mcp",
},
{
name: "Changelog",
href: "/docs/changelog",
},
]
const EXCLUDED_SECTIONS = ["installation", "dark-mode"]
const EXCLUDED_PAGES = ["/docs", "/docs/changelog"]
export function DocsSidebar({
tree,
...props
@@ -23,40 +46,90 @@ export function DocsSidebar({
return (
<Sidebar
className="sticky top-[calc(var(--header-height)+1px)] z-30 hidden h-[calc(100svh-var(--header-height)-var(--footer-height))] bg-transparent lg:flex"
className="sticky top-[calc(var(--header-height)+1px)] z-30 hidden h-[calc(100svh-var(--footer-height)+2rem)] bg-transparent lg:flex"
collapsible="none"
{...props}
>
<SidebarContent className="no-scrollbar px-2 pb-12">
<SidebarContent className="no-scrollbar overflow-x-hidden px-2 pb-12">
<div className="h-(--top-spacing) shrink-0" />
{tree.children.map((item) => (
<SidebarGroup key={item.$id}>
<SidebarGroupLabel className="text-muted-foreground font-medium">
{item.name}
</SidebarGroupLabel>
<SidebarGroupContent>
{item.type === "folder" && (
<SidebarMenu className="gap-0.5">
{item.children.map((item) => {
return (
item.type === "page" && (
<SidebarMenuItem key={item.url}>
<SidebarMenuButton
asChild
isActive={item.url === pathname}
className="data-[active=true]:bg-accent data-[active=true]:border-accent 3xl:fixed:w-full 3xl:fixed:max-w-48 relative h-[30px] w-fit overflow-visible border border-transparent text-[0.8rem] font-medium after:absolute after:inset-x-0 after:-inset-y-1 after:z-0 after:rounded-md"
>
<Link href={item.url}>{item.name}</Link>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarGroup>
<SidebarGroupLabel className="text-muted-foreground font-medium">
Sections
</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
{TOP_LEVEL_SECTIONS.map(({ name, href }) => {
if (!showMcpDocs && href.includes("/mcp")) {
return null
}
return (
<SidebarMenuItem key={name}>
<SidebarMenuButton
asChild
isActive={
href === "/docs"
? pathname === href
: pathname.startsWith(href)
}
className="data-[active=true]:bg-accent data-[active=true]:border-accent 3xl:fixed:w-full 3xl:fixed:max-w-48 relative h-[30px] w-fit overflow-visible border border-transparent text-[0.8rem] font-medium after:absolute after:inset-x-0 after:-inset-y-1 after:z-0 after:rounded-md"
>
<Link href={href}>
<span className="absolute inset-0 flex w-(--sidebar-width) bg-transparent" />
{name}
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
)
})}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
{tree.children.map((item) => {
if (EXCLUDED_SECTIONS.includes(item.$id ?? "")) {
return null
}
return (
<SidebarGroup key={item.$id}>
<SidebarGroupLabel className="text-muted-foreground font-medium">
{item.name}
</SidebarGroupLabel>
<SidebarGroupContent>
{item.type === "folder" && (
<SidebarMenu className="gap-0.5">
{item.children.map((item) => {
if (
!showMcpDocs &&
item.type === "page" &&
item.url?.includes("/mcp")
) {
return null
}
return (
item.type === "page" &&
!EXCLUDED_PAGES.includes(item.url) && (
<SidebarMenuItem key={item.url}>
<SidebarMenuButton
asChild
isActive={item.url === pathname}
className="data-[active=true]:bg-accent data-[active=true]:border-accent 3xl:fixed:w-full 3xl:fixed:max-w-48 relative h-[30px] w-fit overflow-visible border border-transparent text-[0.8rem] font-medium after:absolute after:inset-x-0 after:-inset-y-1 after:z-0 after:rounded-md"
>
<Link href={item.url}>
<span className="absolute inset-0 flex w-(--sidebar-width) bg-transparent" />
{item.name}
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
)
)
)
})}
</SidebarMenu>
)}
</SidebarGroupContent>
</SidebarGroup>
))}
})}
</SidebarMenu>
)}
</SidebarGroupContent>
</SidebarGroup>
)
})}
</SidebarContent>
</Sidebar>
)

View File

@@ -4,6 +4,7 @@ import * as React from "react"
import Link, { LinkProps } from "next/link"
import { useRouter } from "next/navigation"
import { showMcpDocs } from "@/lib/flags"
import { source } from "@/lib/source"
import { cn } from "@/lib/utils"
import { Button } from "@/registry/new-york-v4/ui/button"
@@ -13,6 +14,26 @@ import {
PopoverTrigger,
} from "@/registry/new-york-v4/ui/popover"
const TOP_LEVEL_SECTIONS = [
{ name: "Get Started", href: "/docs" },
{
name: "Components",
href: "/docs/components",
},
{
name: "Registry",
href: "/docs/registry",
},
{
name: "MCP Server",
href: "/docs/mcp",
},
{
name: "Changelog",
href: "/docs/changelog",
},
]
export function MobileNav({
tree,
items,
@@ -79,6 +100,23 @@ export function MobileNav({
))}
</div>
</div>
<div className="flex flex-col gap-4">
<div className="text-muted-foreground text-sm font-medium">
Sections
</div>
<div className="flex flex-col gap-3">
{TOP_LEVEL_SECTIONS.map(({ name, href }) => {
if (!showMcpDocs && href.includes("/mcp")) {
return null
}
return (
<MobileLink key={name} href={href} onOpenChange={setOpen}>
{name}
</MobileLink>
)
})}
</div>
</div>
<div className="flex flex-col gap-8">
{tree?.children?.map((group, index) => {
if (group.type === "folder") {
@@ -90,6 +128,9 @@ export function MobileNav({
<div className="flex flex-col gap-3">
{group.children.map((item) => {
if (item.type === "page") {
if (!showMcpDocs && item.url.includes("/mcp")) {
return null
}
return (
<MobileLink
key={`${item.url}-${index}`}

View File

@@ -3,7 +3,7 @@ import { Icons } from "@/components/icons"
import { Button } from "@/registry/new-york-v4/ui/button"
// v0 uses the default style.
const V0_STYLE = "default"
const V0_STYLE = "new-york-v4"
export function OpenInV0Button({
name,

View File

@@ -13,7 +13,7 @@ export function OpenInV0Cta({ className }: React.ComponentProps<"div">) {
Deploy your shadcn/ui app on Vercel
</div>
<div className="text-muted-foreground">
Trusted by OpenAI, Sonos, Chick-fil-A, and more.
Trusted by OpenAI, Sonos, Adobe, and more.
</div>
<div className="text-muted-foreground">
Vercel provides tools and infrastructure to deploy apps and features at

View File

@@ -2,10 +2,10 @@ import { siteConfig } from "@/lib/config"
export function SiteFooter() {
return (
<footer className="group-has-[.section-soft]/body:bg-surface/40 3xl:fixed:bg-transparent dark:bg-transparent">
<footer className="group-has-[.section-soft]/body:bg-surface/40 3xl:fixed:bg-transparent group-has-[.docs-nav]/body:pb-20 group-has-[.docs-nav]/body:sm:pb-0 dark:bg-transparent">
<div className="container-wrapper px-4 xl:px-6">
<div className="flex h-(--footer-height) items-center justify-between">
<div className="text-muted-foreground w-full text-center text-xs leading-loose sm:text-sm">
<div className="text-muted-foreground w-full px-1 text-center text-xs leading-loose sm:text-sm">
Built by{" "}
<a
href={siteConfig.links.twitter}

View File

@@ -41,7 +41,11 @@ export function SiteHeader() {
<MainNav items={siteConfig.navItems} className="hidden lg:flex" />
<div className="ml-auto flex items-center gap-2 md:flex-1 md:justify-end">
<div className="hidden w-full flex-1 md:flex md:w-auto md:flex-none">
<CommandMenu tree={pageTree} colors={colors} />
<CommandMenu
tree={pageTree}
colors={colors}
navItems={siteConfig.navItems}
/>
</div>
<Separator
orientation="vertical"

View File

@@ -4,6 +4,260 @@ description: Latest updates and announcements.
toc: false
---
## September 2025 - Registry Index
We've created an index of open source registries that you can install items from.
You can search, view and add items from the registry index without configuring the `.components.json` file.
They'll be automatically added to your `components.json` file for you.
```bash
npx shadcn add @ai-elements/prompt-input
```
The full list of registries is available at [https://ui.shadcn.com/r/registries.json](https://ui.shadcn.com/r/registries.json).
To add a registry to the index, submit a PR to the `shadcn/ui` repository. See the [registry index documentation](/docs/registry/registry-index) for more details.
---
## August 2025 - shadcn CLI 3.0 and MCP Server
We just shipped shadcn CLI 3.0 with support for namespaced registries, advanced authentication, new commands and a completely rewritten registry engine.
### What's New
- [Namespaced Registries](#namespaced-registries) - Install components using `@registry/name` format.
- [Private Registries](#private-registries) - Secure your registry with advanced authentication.
- [Search & Discovery](#search--discovery) - New commands to find and view code before installing.
- [MCP Server](#mcp-server) - MCP server for all registries.
- [Faster Everything](#faster-everything) - Completely rewritten registry resolution.
- [Improved Error Handling](#improved-error-handling) - Better error messages for users and LLMs.
- [Upgrade Guide](#upgrade-guide) - Migration notes for existing users.
### Namespaced Registries
The biggest change in 3.0 is namespaced registries. You can now install components from registries: a community registry, your company's private registry or internal registry, using the `@registry/name` format.
This makes it easier to distribute code across teams and projects.
Configure registries in your `components.json`:
```json title="components.json"
{
"registries": {
"@acme": "https://acme.com/r/{name}.json",
"@internal": {
"url": "https://registry.company.com/{name}",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}"
}
}
}
}
```
Then use the `@registry/name` format to install components:
```bash
npx shadcn add @acme/button @internal/auth-system
```
It's completely decentralized. There's no central registrar. Create any namespace you want and organize components however makes sense for your team.
```json title="components.json" showLineNumbers
{
"registries": {
"@design": "https://registry.company.com/design/{name}.json",
"@engineering": "https://registry.company.com/eng/{name}.json",
"@marketing": "https://registry.company.com/marketing/{name}.json"
}
}
```
Components can even depend on resources from different registries. Everything gets resolved and installed automatically from the right sources.
```json title="registry-item.json" showLineNumbers
{
"name": "dashboard",
"type": "registry:block",
"registryDependencies": [
"@shadcn/card", // From default registry
"@v0/chart", // From v0 registry
"@acme/data-table", // From acme registry
"@lib/data-fetcher", // Utility library
"@ai/analytics-prompt" // AI prompt resource
]
}
```
### Private Registries
Need to keep your components private? We've got you covered. Configure authentication with tokens, API keys, or custom headers:
```json title="components.json"
{
"registries": {
"@private": {
"url": "https://registry.company.com/{name}.json",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}"
}
}
}
}
```
Your private components stay private. Perfect for enterprise teams with proprietary UI libraries.
We support all major authentication methods: basic auth, bearer token, api key query params and custom headers.
See the [authentication docs](/docs/registry/authentication) for more details.
### Search & Discovery
Three new commands make it easy to find exactly what you need:
1. View items from the registry before installing
```bash
npx shadcn view @acme/auth-system
```
2. Search items from registries
```bash
npx shadcn search @tweakcn -q "dark"
```
3. List all items from a registry
```bash
npx shadcn list @acme
```
Preview components before installing them. Search across multiple registries. See the code and all dependencies upfront.
### MCP Server
<Image
src="/images/mcp.jpeg"
width="1432"
height="1050"
alt="Lift Mode"
className="mt-6 w-full overflow-hidden rounded-lg border"
/>
Back in April, we [introduced](https://x.com/shadcn/status/1917597228513853603) the first version of the MCP server. Since then, we've taken everything we learned and built a better MCP server.
Here's what's new:
- Works with all registries. Zero config
- One command to add to your favorite MCP clients
- We improved the underlying tools
- Better integration with the CLI and registries
- Support for multiple registries in the same project
Add the MCP server to your project:
```bash
npx shadcn@latest mcp init
```
See the [docs](/docs/mcp) for more details.
### Faster Everything
We completely rewrote the registry resolution engine from scratch. It's faster, smarter, and handles even the trickiest dependency trees.
- Up to 3x faster dependency resolution
- Smarter file deduplication and merging
- Better monorepo support out of the box
- Updated `build` command for registry authors
### Improved Error Handling
Registry developers can now provide custom error messages to help guide users (and LLMs) when things go wrong. The CLI displays helpful, actionable errors for common issues:
```txt
Unknown registry "@acme". Make sure it is defined in components.json as follows:
{
"registries": {
"@acme": "[URL_TO_REGISTRY]"
}
}
```
Missing environment variables? The CLI tells you exactly what's needed:
```txt
Registry "@private" requires the following environment variables:
• REGISTRY_TOKEN
Set the required environment variables to your .env or .env.local file.
```
Registry authors can provide custom error messages in their responses to help users and AI agents understand and fix issues quickly.
```txt
Error:
You are not authorized to access the item at http://example.com/r/component.
Message:
[Unauthorized] Your API key has expired. Renew it at https://example.com/api/renew-key.
```
### Upgrade Guide
Here's the best part: there are no breaking changes for users. Your existing `components.json` works exactly the same. All your installed components work exactly the same.
For developers, if you're using the programmatic APIs directly, we've deprecated a few functions in favor of better ones:
- `fetchRegistry` → `getRegistry`
- `resolveRegistryTree` → `resolveRegistryItems`
- Schema moved from `shadcn/registry` to `shadcn/schema` package
```diff
- import { registryItemSchema } from "shadcn/registry"
+ import { registryItemSchema } from "shadcn/schema"
```
That's it. Seriously. Everything else just works.
---
## July 2025 - Universal Registry Items
We've added support for universal registry items. This allows you to create registry items that can be distributed to any project i.e. no framework, no components.json, no tailwind, no react required.
This new registry item type unlocks a lot of new workflows. You can now distribute code, config, rules, docs, anything to any code project.
See the [docs](/docs/registry/examples) for more details and examples.
---
## July 2025 - Local File Support
The shadcn CLI now supports local files. Initialize projects and add components, themes, hooks, utils and more from local JSON files.
```bash
# Initialize a project from a local file
npx shadcn init ./template.json
# Add a component from a local file
npx shadcn add ./block.json
```
This feature enables powerful new workflows:
- **Zero setup** - No remote registries required
- **Faster development** - Test registry items locally before publishing
- **Enhanced workflow for agents and MCP** - Generate and run registry items locally
- **Private components** - Keep proprietary components local and private.
---
## June 2025 - `radix-ui`
We've added a new command to migrate to the new `radix-ui` package. This command will replace all `@radix-ui/react-*` imports with `radix-ui`.
@@ -55,7 +309,7 @@ We're working on zero-config MCP support for shadcn/ui registry. One command `np
className="mt-6 w-full overflow-hidden rounded-lg border"
/>
Learn more in the thread here: https://x.com/shadcn/status/1917597228513853603
Learn more in the [thread here](https://x.com/shadcn/status/1917597228513853603).
## March 2025 - shadcn 2.5.0

View File

@@ -13,7 +13,7 @@ The `init` command installs dependencies, adds the `cn` util and configures CSS
npx shadcn@latest init
```
### Options
**Options**
```bash
Usage: shadcn init [options] [components...]
@@ -21,23 +21,25 @@ Usage: shadcn init [options] [components...]
initialize your project and install dependencies
Arguments:
components the components to add or a url to the component.
components name, url or local path to component
Options:
-t, --template <template> the template to use. (next, next-monorepo)
-b, --base-color <base-color> the base color to use. (neutral, gray, zinc, stone, slate)
-y, --yes skip confirmation prompt. (default: true)
-f, --force force overwrite of existing configuration. (default: false)
-c, --cwd <cwd> the working directory. defaults to the current directory. (default:
"/Users/shadcn/Code/shadcn/ui/packages/shadcn")
-c, --cwd <cwd> the working directory. defaults to the current directory.
-s, --silent mute output. (default: false)
--src-dir use the src directory when creating a new project. (default: false)
--no-src-dir do not use the src directory when creating a new project.
--css-variables use css variables for theming. (default: true)
--no-css-variables do not use css variables for theming.
--no-base-style do not install the base shadcn style
-h, --help display help for command
```
---
## add
Use the `add` command to add components and dependencies to your project.
@@ -46,7 +48,7 @@ Use the `add` command to add components and dependencies to your project.
npx shadcn@latest add [component]
```
### Options
**Options**
```bash
Usage: shadcn add [options] [components...]
@@ -54,12 +56,12 @@ Usage: shadcn add [options] [components...]
add a component to your project
Arguments:
components the components to add or a url to the component.
components name, url or local path to component
Options:
-y, --yes skip confirmation prompt. (default: false)
-o, --overwrite overwrite existing files. (default: false)
-c, --cwd <cwd> the working directory. defaults to the current directory. (default: "/Users/shadcn/Desktop")
-c, --cwd <cwd> the working directory. defaults to the current directory.
-a, --all add all available components (default: false)
-p, --path <path> the path to add the component to.
-s, --silent mute output. (default: false)
@@ -70,6 +72,126 @@ Options:
-h, --help display help for command
```
---
## view
Use the `view` command to view items from the registry before installing them.
```bash
npx shadcn@latest view [item]
```
You can view multiple items at once:
```bash
npx shadcn@latest view button card dialog
```
Or view items from namespaced registries:
```bash
npx shadcn@latest view @acme/auth @v0/dashboard
```
**Options**
```bash
Usage: shadcn view [options] <items...>
view items from the registry
Arguments:
items the item names or URLs to view
Options:
-c, --cwd <cwd> the working directory. defaults to the current directory.
-h, --help display help for command
```
---
## search
Use the `search` command to search for items from registries.
```bash
npx shadcn@latest search [registry]
```
You can search with a query:
```bash
npx shadcn@latest search @shadcn -q "button"
```
Or search multiple registries at once:
```bash
npx shadcn@latest search @shadcn @v0 @acme
```
The `list` command is an alias for `search`:
```bash
npx shadcn@latest list @acme
```
**Options**
```bash
Usage: shadcn search|list [options] <registries...>
search items from registries
Arguments:
registries the registry names or urls to search items from. Names
must be prefixed with @.
Options:
-c, --cwd <cwd> the working directory. defaults to the current directory.
-q, --query <query> query string
-l, --limit <number> maximum number of items to display per registry (default: "100")
-o, --offset <number> number of items to skip (default: "0")
-h, --help display help for command
```
---
## list
Use the `list` command to list all items from a registry.
```bash
npx shadcn@latest list @acme
```
**Options**
```bash
Usage: shadcn list [options] <registries...>
list items from registries
Arguments:
registries the registry names or urls to list items from. Names
must be prefixed with @.
```
**Options**
```bash
Usage: shadcn list [options] <registries...>
list items from registries
Arguments:
registries the registry names or urls to list items from. Names
must be prefixed with @.
```
---
## build
Use the `build` command to generate the registry JSON files.
@@ -80,7 +202,7 @@ npx shadcn@latest build
This command reads the `registry.json` file and generates the registry JSON files in the `public/r` directory.
### Options
**Options**
```bash
Usage: shadcn build [options] [registry]
@@ -92,8 +214,7 @@ Arguments:
Options:
-o, --output <path> destination directory for json files (default: "./public/r")
-c, --cwd <cwd> the working directory. defaults to the current directory. (default:
"/Users/shadcn/Code/shadcn/ui/packages/shadcn")
-c, --cwd <cwd> the working directory. defaults to the current directory.
-h, --help display help for command
```

View File

@@ -210,3 +210,94 @@ Import alias for `hooks` such as `use-media-query` or `use-toast`.
}
}
```
## registries
Configure multiple resource registries for your project. This allows you to install components, libraries, utilities, and other resources from various sources including private registries.
See the <Link href="/docs/registry/namespace">Namespaced Registries</Link> documentation for detailed information.
### Basic Configuration
Configure registries with URL templates:
```json title="components.json"
{
"registries": {
"@v0": "https://v0.dev/chat/b/{name}",
"@acme": "https://registry.acme.com/{name}.json",
"@internal": "https://internal.company.com/{name}.json"
}
}
```
The `{name}` placeholder is replaced with the resource name when installing.
### Advanced Configuration with Authentication
For private registries that require authentication:
```json title="components.json"
{
"registries": {
"@private": {
"url": "https://api.company.com/registry/{name}.json",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}",
"X-API-Key": "${API_KEY}"
},
"params": {
"version": "latest"
}
}
}
}
```
Environment variables in the format `${VAR_NAME}` are automatically expanded from your environment.
### Using Namespaced Registries
Once configured, install resources using the namespace syntax:
```bash
# Install from a configured registry
npx shadcn@latest add @v0/dashboard
# Install from private registry
npx shadcn@latest add @private/button
# Install multiple resources
npx shadcn@latest add @acme/header @internal/auth-utils
```
### Example: Multiple Registry Setup
```json title="components.json"
{
"registries": {
"@shadcn": "https://ui.shadcn.com/r/{name}.json",
"@company-ui": {
"url": "https://registry.company.com/ui/{name}.json",
"headers": {
"Authorization": "Bearer ${COMPANY_TOKEN}"
}
},
"@team": {
"url": "https://team.company.com/{name}.json",
"params": {
"team": "frontend",
"version": "${REGISTRY_VERSION}"
}
}
}
}
```
This configuration allows you to:
- Install public components from shadcn/ui
- Access private company UI components with authentication
- Use team-specific resources with versioning
For more information about authentication, see the <Link href="/docs/registry/authentication">Authentication</Link> documentation.

View File

@@ -15,3 +15,4 @@ description: Every component recreated in Figma. With customizable props, typogr
## Free
- [shadcn/ui design system](https://www.figma.com/community/file/1203061493325953101) by [Pietro Schirano](https://twitter.com/skirano) - A design companion for shadcn/ui. Each component was painstakingly crafted to perfectly match the code implementation.
- [Obra shadcn/ui](https://www.figma.com/community/file/1514746685758799870/obra-shadcn-ui) by [Obra Studio](https://obra.studio/) - Carefully crafted kit designed in the philosophy of shadcn, tracks v4, MIT licensed

View File

@@ -0,0 +1,281 @@
---
title: MCP Server
description: Use the shadcn MCP server to browse, search, and install components from registries.
---
The shadcn MCP Server allows AI assistants to interact with items from registries. You can browse available components, search for specific ones, and install them directly into your project using natural language.
For example, you can ask an AI assistant to "Build a landing page using components from the acme registry" or "Find me a login form from the shadcn registry".
Registries are configured in your project's `components.json` file.
```json title="components.json" showLineNumbers
{
"registries": {
"@acme": "https://acme.com/r/{name}.json"
}
}
```
---
## Quick Start
Select your MCP client and follow the instructions to configure the shadcn MCP server. If you'd like to do it manually, see the [Configuration](#configuration) section.
<Tabs defaultValue="claude">
<TabsList>
<TabsTrigger value="claude">Claude Code</TabsTrigger>
<TabsTrigger value="cursor">Cursor</TabsTrigger>
<TabsTrigger value="vscode">VS Code</TabsTrigger>
</TabsList>
<TabsContent value="claude" className="mt-4">
**Run the following command** in your project:
```bash
npx shadcn@latest mcp init --client claude
```
**Restart Claude Code** and try the following prompts:
- Show me all available components in the shadcn registry
- Add the button, dialog and card components to my project
- Create a contact form using components from the shadcn registry
**Note:** You can use `/mcp` command in Claude Code to debug the MCP server.
</TabsContent>
<TabsContent value="cursor" className="mt-4">
**Run the following command** in your project:
```bash
npx shadcn@latest mcp init --client cursor
```
Open **Cursor Settings** and **Enable the MCP server** for shadcn. Then try the following prompts:
- Show me all available components in the shadcn registry
- Add the button, dialog and card components to my project
- Create a contact form using components from the shadcn registry
</TabsContent>
<TabsContent value="vscode" className="mt-4">
**Run the following command** in your project:
```bash
npx shadcn@latest mcp init --client vscode
```
Open `.vscode/mcp.json` and click **Start** next to the shadcn server. Then try the following prompts with GitHub Copilot:
- Show me all available components in the shadcn registry
- Add the button, dialog and card components to my project
- Create a contact form using components from the shadcn registry
</TabsContent>
</Tabs>
---
## What is MCP?
[Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open protocol that enables AI assistants to securely connect to external data sources and tools. With the shadcn MCP server, your AI assistant gains direct access to:
- **Browse Components** - List all available components, blocks, and templates from any configured registry
- **Search Across Registries** - Find specific components by name or functionality across multiple sources
- **Install with Natural Language** - Add components using simple conversational prompts like "add a login form"
- **Support for Multiple Registries** - Access public registries, private company libraries, and third-party sources
---
## How It Works
The MCP server acts as a bridge between your AI assistant, component registries and the shadcn CLI.
1. **Registry Connection** - MCP connects to configured registries (shadcn/ui, private registries, third-party sources)
2. **Natural Language** - You describe what you need in plain English
3. **AI Processing** - The assistant translates your request into registry commands
4. **Component Delivery** - Resources are fetched and installed in your project
---
## Supported Registries
The shadcn MCP server works out of the box with any shadcn-compatible registry.
- **shadcn/ui Registry** - The default registry with all shadcn/ui components
- **Third-Party Registries** - Any registry following the shadcn registry specification
- **Private Registries** - Your company's internal component libraries
- **Namespaced Registries** - Multiple registries configured with `@namespace` syntax
---
## Configuration
You can use any MCP client to interact with the shadcn MCP server. Here are the instructions for the most popular ones.
### Claude Code
To use the shadcn MCP server with Claude Code, add the following configuration to your project's `.mcp.json` file:
```json title=".mcp.json" showLineNumbers
{
"mcpServers": {
"shadcn": {
"command": "npx",
"args": ["shadcn@latest", "mcp"]
}
}
}
```
After adding the configuration, restart Claude Code and run `/mcp` to see the shadcn MCP server in the list. If you see `Connected`, you're good to go.
See the [Claude Code MCP documentation](https://docs.anthropic.com/en/docs/claude-code/mcp) for more details.
### Cursor
To configure MCP in Cursor, add the shadcn server to your project's `.cursor/mcp.json` configuration file:
```json title=".cursor/mcp.json" showLineNumbers
{
"mcpServers": {
"shadcn": {
"command": "npx",
"args": ["shadcn@latest", "mcp"]
}
}
}
```
After adding the configuration, enable the shadcn MCP server in Cursor Settings.
Once enabled, you should see a green dot next to the shadcn server in the MCP server list and a list of available tools.
See the [Cursor MCP documentation](https://docs.cursor.com/en/context/mcp#using-mcp-json) for more details.
### VS Code
To configure MCP in VS Code with GitHub Copilot, add the shadcn server to your project's `.vscode/mcp.json` configuration file:
```json title=".vscode/mcp.json" showLineNumbers
{
"mcpServers": {
"shadcn": {
"command": "npx",
"args": ["shadcn@latest", "mcp"]
}
}
}
```
After adding the configuration, open `.vscode/mcp.json` and click **Start** next to the shadcn server.
See the [VS Code MCP documentation](https://code.visualstudio.com/docs/copilot/chat/mcp-servers) for more details.
---
## Configuring Registries
The MCP server supports multiple registries through your project's `components.json` configuration. This allows you to access components from various sources including private registries and third-party providers.
Configure additional registries in your `components.json`:
```json title="components.json" showLineNumbers
{
"registries": {
"@acme": "https://registry.acme.com/{name}.json",
"@internal": {
"url": "https://internal.company.com/{name}.json",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}"
}
}
}
}
```
<Callout>
**Note:** No configuration is needed to access the standard shadcn/ui
registry.
</Callout>
---
## Authentication
For private registries requiring authentication, set environment variables in your `.env.local`:
```bash title=".env.local"
REGISTRY_TOKEN=your_token_here
API_KEY=your_api_key_here
```
For more details on registry authentication, see the [Authentication documentation](/docs/registry/authentication).
---
## Example Prompts
Once the MCP server is configured, you can use natural language to interact with registries. Try one of the following prompts:
### Browse & Search
- Show me all available components in the shadcn registry
- Find me a login form from the shadcn registry
### Install Items
- Add the button component to my project
- Create a login form using shadcn components
- Install the Cursor rules from the acme registry
### Work with Namespaces
- Show me components from acme registry
- Install @internal/auth-form
- Build me a landing page using hero, features and testimonials sections from the acme registry
---
## Troubleshooting
### MCP Not Responding
If the MCP server isn't responding to prompts:
1. **Check Configuration** - Verify the MCP server is properly configured and enabled in your MCP client
2. **Restart MCP Client** - Restart your MCP client after configuration changes
3. **Verify Installation** - Ensure `shadcn` is installed in your project
4. **Check Network** - Confirm you can access the configured registries
### Registry Access Issues
If components aren't loading from registries:
1. **Check components.json** - Verify registry URLs are correct
2. **Test Authentication** - Ensure environment variables are set for private registries
3. **Verify Registry** - Confirm the registry is online and accessible
4. **Check Namespace** - Ensure namespace syntax is correct (`@namespace/component`)
### Installation Failures
If components fail to install:
1. **Check Project Setup** - Ensure you have a valid `components.json` file
2. **Verify Paths** - Confirm the target directories exist
3. **Check Permissions** - Ensure write permissions for component directories
4. **Review Dependencies** - Check that required dependencies are installed
### No Tools or Prompts
If you see the `No tools or prompts` message, try the following:
1. **Clear the npx cache** - Run `npx clear-npx-cache`
2. **Re-enable the MCP server** - Try to re-enable the MCP server in your MCP client
3. **Check Logs** - In Cursor, you can see the logs under View -> Output and select `MCP: project-*` in the dropdown.
---
## Learn More
- [Registry Documentation](/docs/registry) - Complete guide to shadcn registries
- [Namespaces](/docs/registry/namespace) - Configure multiple registry sources
- [Authentication](/docs/registry/authentication) - Secure your private registries
- [MCP Specification](https://modelcontextprotocol.io) - Learn about Model Context Protocol

View File

@@ -41,7 +41,7 @@ npx shadcn@latest add calendar
<Step>Install the following dependencies:</Step>
```bash
npm install react-day-picker@8.10.1 date-fns
npm install react-day-picker date-fns
```
<Step>Add the `Button` component to your project.</Step>

View File

@@ -4,9 +4,15 @@ description: Beautiful charts. Built using Recharts. Copy and paste into your ap
component: true
---
<Callout>
**Note:** We're working on upgrading to Recharts v3. In the meantime, if you'd like to start testing v3, see the code in the comment [here](https://github.com/shadcn-ui/ui/issues/7669#issuecomment-2998299159). We'll have an official release soon.
</Callout>
<ComponentPreview
name="chart-bar-interactive"
className="theme-blue -mt-4 [&_.preview]:p-0 [&_.preview]:lg:min-h-[404px] [&_.preview>div]:w-full [&_.preview>div]:border-none [&_.preview>div]:shadow-none"
className="theme-blue [&_.preview]:h-auto [&_.preview]:p-0 [&_.preview]:lg:min-h-[404px] [&_.preview>div]:w-full [&_.preview>div]:border-none [&_.preview>div]:shadow-none"
hideCode
/>

View File

@@ -185,7 +185,7 @@ export function DataTable<TData, TValue>({
})
return (
<div className="rounded-md border">
<div className="overflow-hidden rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
@@ -425,7 +425,7 @@ export function DataTable<TData, TValue>({
return (
<div>
<div className="rounded-md border">
<div className="overflow-hidden rounded-md border">
<Table>
{ // .... }
</Table>
@@ -499,7 +499,7 @@ export function DataTable<TData, TValue>({
return (
<div>
<div className="rounded-md border">
<div className="overflow-hidden rounded-md border">
<Table>{ ... }</Table>
</div>
</div>
@@ -602,7 +602,7 @@ export function DataTable<TData, TValue>({
className="max-w-sm"
/>
</div>
<div className="rounded-md border">
<div className="overflow-hidden rounded-md border">
<Table>{ ... }</Table>
</div>
</div>
@@ -715,7 +715,7 @@ export function DataTable<TData, TValue>({
</DropdownMenuContent>
</DropdownMenu>
</div>
<div className="rounded-md border">
<div className="overflow-hidden rounded-md border">
<Table>{ ... }</Table>
</div>
</div>
@@ -805,7 +805,7 @@ export function DataTable<TData, TValue>({
return (
<div>
<div className="rounded-md border">
<div className="overflow-hidden rounded-md border">
<Table />
</div>
</div>

View File

@@ -5,7 +5,7 @@ description: Adding dark mode to your vite app.
## Create a theme provider
```tsx title="components/theme-provider.tsx"
```tsx title="components/theme-provider.tsx" showLineNumbers
import { createContext, useContext, useEffect, useState } from "react"
type Theme = "dark" | "light" | "system"
@@ -85,7 +85,7 @@ export const useTheme = () => {
Add the `ThemeProvider` to your root layout.
```tsx {1,5-7} title="App.tsx"
```tsx {1,5-7} title="App.tsx" showLineNumbers
import { ThemeProvider } from "@/components/theme-provider"
function App() {
@@ -103,7 +103,7 @@ export default App
Place a mode toggle on your site to toggle between light and dark mode.
```tsx title="components/mode-toggle.tsx"
```tsx title="components/mode-toggle.tsx" showLineNumbers
import { Moon, Sun } from "lucide-react"
import { Button } from "@/components/ui/button"

View File

@@ -0,0 +1,399 @@
---
title: Authentication
description: Secure your registry with authentication for private and personalized components.
---
Authentication lets you run private registries, control who can access your components, and give different teams or users different content. This guide shows common authentication patterns and how to set them up.
Authentication enables these use cases:
- **Private Components**: Keep your business logic and internal components secure
- **Team-Specific Resources**: Give different teams different components
- **Access Control**: Limit who can see sensitive or experimental components
- **Usage Analytics**: See who's using which components in your organization
- **Licensing**: Control who gets premium or licensed components
## Common Authentication Patterns
### Token-Based Authentication
The most common approach uses Bearer tokens or API keys:
```json title="components.json"
{
"registries": {
"@private": {
"url": "https://registry.company.com/{name}.json",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}"
}
}
}
}
```
Set your token in environment variables:
```bash title=".env.local"
REGISTRY_TOKEN=your_secret_token_here
```
### API Key Authentication
Some registries use API keys in headers:
```json title="components.json"
{
"registries": {
"@company": {
"url": "https://api.company.com/registry/{name}.json",
"headers": {
"X-API-Key": "${API_KEY}",
"X-Workspace-Id": "${WORKSPACE_ID}"
}
}
}
}
```
### Query Parameter Authentication
For simpler setups, use query parameters:
```json title="components.json"
{
"registries": {
"@internal": {
"url": "https://registry.company.com/{name}.json",
"params": {
"token": "${ACCESS_TOKEN}"
}
}
}
}
```
This creates: `https://registry.company.com/button.json?token=your_token`
## Server-Side Implementation
Here's how to add authentication to your registry server:
### Next.js API Route Example
```typescript title="app/api/registry/[name]/route.ts"
import { NextRequest, NextResponse } from "next/server"
export async function GET(
request: NextRequest,
{ params }: { params: { name: string } }
) {
// Get token from Authorization header.
const authHeader = request.headers.get("authorization")
const token = authHeader?.replace("Bearer ", "")
// Or from query parameters.
const queryToken = request.nextUrl.searchParams.get("token")
// Check if token is valid.
if (!isValidToken(token || queryToken)) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 })
}
// Check if token can access this component.
if (!hasAccessToComponent(token, params.name)) {
return NextResponse.json({ error: "Forbidden" }, { status: 403 })
}
// Return the component.
const component = await getComponent(params.name)
return NextResponse.json(component)
}
function isValidToken(token: string | null) {
// Add your token validation logic here.
// Check against database, JWT validation, etc.
return token === process.env.VALID_TOKEN
}
function hasAccessToComponent(token: string, componentName: string) {
// Add role-based access control here.
// Check if token can access specific component.
return true // Your logic here.
}
```
### Express.js Example
```javascript title="server.js"
app.get("/registry/:name.json", (req, res) => {
const token = req.headers.authorization?.replace("Bearer ", "")
if (!isValidToken(token)) {
return res.status(401).json({ error: "Unauthorized" })
}
const component = getComponent(req.params.name)
if (!component) {
return res.status(404).json({ error: "Component not found" })
}
res.json(component)
})
```
## Advanced Authentication Patterns
### Team-Based Access
Give different teams different components:
```typescript title="api/registry/route.ts"
async function GET(request: NextRequest) {
const token = extractToken(request)
const team = await getTeamFromToken(token)
// Get components for this team.
const components = await getComponentsForTeam(team)
return NextResponse.json(components)
}
```
### User-Personalized Registries
Give users components based on their preferences:
```typescript
async function GET(request: NextRequest) {
const user = await authenticateUser(request)
// Get user's style and framework preferences.
const preferences = await getUserPreferences(user.id)
// Get personalized component version.
const component = await getPersonalizedComponent(params.name, preferences)
return NextResponse.json(component)
}
```
### Temporary Access Tokens
Use expiring tokens for better security:
```typescript
interface TemporaryToken {
token: string
expiresAt: Date
scope: string[]
}
async function validateTemporaryToken(token: string) {
const tokenData = await getTokenData(token)
if (!tokenData) return false
if (new Date() > tokenData.expiresAt) return false
return true
}
```
## Multi-Registry Authentication
With [namespaced registries](/docs/registry/namespace), you can set up multiple registries with different authentication:
```json title="components.json"
{
"registries": {
"@public": "https://public.company.com/{name}.json",
"@internal": {
"url": "https://internal.company.com/{name}.json",
"headers": {
"Authorization": "Bearer ${INTERNAL_TOKEN}"
}
},
"@premium": {
"url": "https://premium.company.com/{name}.json",
"headers": {
"X-License-Key": "${LICENSE_KEY}"
}
}
}
}
```
This lets you:
- Mix public and private registries
- Use different authentication per registry
- Organize components by access level
## Security Best Practices
### Use Environment Variables
Never commit tokens to version control. Always use environment variables:
```bash title=".env.local"
REGISTRY_TOKEN=your_secret_token_here
API_KEY=your_api_key_here
```
Then reference them in `components.json`:
```json
{
"registries": {
"@private": {
"url": "https://registry.company.com/{name}.json",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}"
}
}
}
}
```
### Use HTTPS
Always use HTTPS URLs for registries to protect your tokens in transit:
```json
{
"@secure": "https://registry.company.com/{name}.json" // ✅
"@insecure": "http://registry.company.com/{name}.json" // ❌
}
```
### Add Rate Limiting
Protect your registry from abuse:
```typescript
import rateLimit from "express-rate-limit"
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
})
app.use("/registry", limiter)
```
### Rotate Tokens
Change access tokens regularly:
```typescript
// Create new token with expiration.
function generateToken() {
const token = crypto.randomBytes(32).toString("hex")
const expiresAt = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000) // 30 days.
return { token, expiresAt }
}
```
### Log Access
Track registry access for security and analytics:
```typescript
async function logAccess(request: Request, component: string, userId: string) {
await db.accessLog.create({
timestamp: new Date(),
userId,
component,
ip: request.ip,
userAgent: request.headers["user-agent"],
})
}
```
## Testing Authentication
Test your authenticated registry locally:
```bash
# Test with curl.
curl -H "Authorization: Bearer your_token" \
https://registry.company.com/button.json
# Test with the CLI.
REGISTRY_TOKEN=your_token npx shadcn@latest add @private/button
```
## Error Handling
The shadcn CLI handles authentication errors gracefully:
- **401 Unauthorized**: Token is invalid or missing
- **403 Forbidden**: Token lacks permission for this resource
- **429 Too Many Requests**: Rate limit exceeded
### Custom Error Messages
Your registry server can return custom error messages in the response body, and the CLI will display them to users:
```typescript
// Registry server returns custom error
return NextResponse.json(
{
error: "Unauthorized",
message:
"Your subscription has expired. Please renew at company.com/billing",
},
{ status: 403 }
)
```
The user will see:
```txt
Your subscription has expired. Please renew at company.com/billing
```
This helps provide context-specific guidance:
```typescript
// Different error messages for different scenarios
if (!token) {
return NextResponse.json(
{
error: "Unauthorized",
message:
"Authentication required. Set REGISTRY_TOKEN in your .env.local file",
},
{ status: 401 }
)
}
if (isExpiredToken(token)) {
return NextResponse.json(
{
error: "Unauthorized",
message: "Token expired. Request a new token at company.com/tokens",
},
{ status: 401 }
)
}
if (!hasTeamAccess(token, component)) {
return NextResponse.json(
{
error: "Forbidden",
message: `Component '${component}' is restricted to the Design team`,
},
{ status: 403 }
)
}
```
## Next Steps
To set up authentication with multiple registries and advanced patterns, see the [Namespaced Registries](/docs/registry/namespace) documentation. It covers:
- Setting up multiple authenticated registries
- Using different authentication per namespace
- Cross-registry dependency resolution
- Advanced authentication patterns

View File

@@ -328,6 +328,157 @@ Add custom theme variables to the `theme` object.
}
```
## Add CSS imports
Use `@import` to add CSS imports to your registry item. The imports will be placed at the top of the CSS file.
### Basic import
```json title="example-import.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-import",
"type": "registry:component",
"css": {
"@import \"tailwindcss\"": {},
"@import \"./styles/base.css\"": {}
}
}
```
### Import with url() syntax
```json title="example-url-import.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "font-import",
"type": "registry:item",
"css": {
"@import url(\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap\")": {},
"@import url('./local-styles.css')": {}
}
}
```
### Import with media queries
```json title="example-media-import.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "responsive-import",
"type": "registry:item",
"css": {
"@import \"print-styles.css\" print": {},
"@import url(\"mobile.css\") screen and (max-width: 768px)": {}
}
}
```
## Add custom plugins
Use `@plugin` to add Tailwind plugins to your registry item. Plugins will be automatically placed after imports and before other content.
**Important:** When using plugins from npm packages, you must also add them to the `dependencies` array.
### Basic plugin usage
```json title="example-plugin.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-plugin",
"type": "registry:item",
"css": {
"@plugin \"@tailwindcss/typography\"": {},
"@plugin \"foo\"": {}
}
}
```
### Plugin with npm dependency
When using plugins from npm packages like `@tailwindcss/typography`, include them in the dependencies.
```json title="example-typography.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "typography-component",
"type": "registry:item",
"dependencies": ["@tailwindcss/typography"],
"css": {
"@plugin \"@tailwindcss/typography\"": {},
"@layer components": {
".prose": {
"max-width": "65ch"
}
}
}
}
```
### Scoped and file-based plugins
```json title="example-scoped-plugin.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "scoped-plugins",
"type": "registry:component",
"css": {
"@plugin \"@headlessui/tailwindcss\"": {},
"@plugin \"tailwindcss/plugin\"": {},
"@plugin \"./custom-plugin.js\"": {}
}
}
```
### Multiple plugins with automatic ordering
When you add multiple plugins, they are automatically grouped together and deduplicated.
```json title="example-multiple-plugins.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "multiple-plugins",
"type": "registry:item",
"dependencies": [
"@tailwindcss/typography",
"@tailwindcss/forms",
"tw-animate-css"
],
"css": {
"@plugin \"@tailwindcss/typography\"": {},
"@plugin \"@tailwindcss/forms\"": {},
"@plugin \"tw-animate-css\"": {}
}
}
```
## Combined imports and plugins
When using both `@import` and `@plugin` directives, imports are placed first, followed by plugins, then other CSS content.
```json title="example-combined.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "combined-example",
"type": "registry:item",
"dependencies": ["@tailwindcss/typography", "tw-animate-css"],
"css": {
"@import \"tailwindcss\"": {},
"@import url(\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap\")": {},
"@plugin \"@tailwindcss/typography\"": {},
"@plugin \"tw-animate-css\"": {},
"@layer base": {
"body": {
"font-family": "Inter, sans-serif"
}
},
"@utility content-auto": {
"content-visibility": "auto"
}
}
}
```
## Add custom animations
Note: you need to define both `@keyframes` in css and `theme` in cssVars to use animations.
@@ -354,3 +505,95 @@ Note: you need to define both `@keyframes` in css and `theme` in cssVars to use
}
}
```
## Add environment variables
You can add environment variables using the `envVars` field.
```json title="example-item.json" showLineNumbers {5-9}
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "custom-item",
"type": "registry:item",
"envVars": {
"NEXT_PUBLIC_APP_URL": "http://localhost:4000",
"DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/postgres",
"OPENAI_API_KEY": ""
}
}
```
Environment variables are added to the `.env.local` or `.env` file. Existing variables are not overwritten.
<Callout>
**IMPORTANT:** Use `envVars` to add development or example variables. Do NOT use it to add production variables.
</Callout>
## Universal Items
As of `2.9.0`, you can create universal items that can be installed without framework detection or components.json.
To make an item universal i.e framework agnostic, all the files in the item must have an explicit target.
Here's an example of a registry item that installs custom Cursor rules for _python_:
```json title=".cursor/rules/custom-python.mdc" showLineNumbers {9}
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "python-rules",
"type": "registry:item",
"files": [
{
"path": "/path/to/your/registry/default/custom-python.mdc",
"type": "registry:file",
"target": "~/.cursor/rules/custom-python.mdc",
"content": "..."
}
]
}
```
Here's another example for installation custom ESLint config:
```json title=".eslintrc.json" showLineNumbers {9}
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "my-eslint-config",
"type": "registry:item",
"files": [
{
"path": "/path/to/your/registry/default/custom-eslint.json",
"type": "registry:file",
"target": "~/.eslintrc.json",
"content": "..."
}
]
}
```
You can also have a universal item that installs multiple files:
```json title="my-custom-starter-template.json" showLineNumbers {9}
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "my-custom-start-template",
"type": "registry:item",
dependencies: ["better-auth"]
"files": [
{
"path": "/path/to/file-01.json",
"type": "registry:file",
"target": "~/file-01.json",
"content": "..."
},
{
"path": "/path/to/file-02.vue",
"type": "registry:file",
"target": "~/pages/file-02.vue",
"content": "..."
}
]
}
```

View File

@@ -3,23 +3,27 @@ title: Getting Started
description: Learn how to get setup and run your own component registry.
---
This guide will walk you through the process of setting up your own component registry.
It assumes you already have a project with components and would like to turn it into a registry.
This guide will walk you through the process of setting up your own component registry. It assumes you already have a project with components and would like to turn it into a registry.
If you're starting a new registry project, you can use the [registry template](https://github.com/shadcn-ui/registry-template) as a starting point. We have already configured it for you.
## Requirements
You are free to design and host your custom registry as you see fit. The only requirement is that your registry items must be valid JSON files that conform to the [registry-item schema specification](/docs/registry/registry-item-json).
If you'd like to see an example of a registry, we have a [template project](https://github.com/shadcn-ui/registry-template) for you to use as a starting point.
## registry.json
The `registry.json` file is only required if you're using the `shadcn` CLI to build your registry.
The `registry.json` is the entry point for the registry. It contains the registry's name, homepage, and defines all the items present in the registry.
If you're using a different build system, you can skip this step as long as your build system produces valid JSON files that conform to the [registry-item schema specification](/docs/registry/registry-item-json).
Your registry must have this file (or JSON payload) present at the root of the registry endpoint. The registry endpoint is the URL where your registry is hosted.
<Steps>
The `shadcn` CLI will automatically generate this file for you when you run the `build` command.
### Add a registry.json file
## Add a registry.json file
Create a `registry.json` file in the root of your project. Your project can be a Next.js, Remix, Vite, or any other project that supports React.
Create a `registry.json` file in the root of your project. Your project can be a Next.js, Vite, Vue, Svelte, PHP or any other framework as long as it supports serving JSON over HTTP.
```json title="registry.json" showLineNumbers
{
@@ -34,12 +38,8 @@ Create a `registry.json` file in the root of your project. Your project can be a
This `registry.json` file must conform to the [registry schema specification](/docs/registry/registry-json).
</Steps>
## Add a registry item
<Steps>
### Create your component
Add your first component. Here's an example of a simple `<HelloWorld />` component:
@@ -98,16 +98,10 @@ For every file you add, you must specify the `path` and `type` of the file. The
You can read more about the registry item schema and file types in the [registry item schema docs](/docs/registry/registry-item-json).
</Steps>
## Build your registry
<Steps>
### Install the shadcn CLI
Note: the `build` command is currently only available in the `shadcn@canary` version of the CLI.
```bash
npm install shadcn@canary
```
@@ -140,8 +134,6 @@ You can change the output directory by passing the `--output` option. See the [s
</Callout>
</Steps>
## Serve your registry
If you're running your registry on Next.js, you can now serve your registry by running the `next` server. The command might differ for other frameworks.
@@ -156,24 +148,13 @@ Your files will now be served at `http://localhost:3000/r/[NAME].json` eg. `http
To make your registry available to other developers, you can publish it by deploying your project to a public URL.
## Adding Auth
The `shadcn` CLI does not offer a built-in way to add auth to your registry. We recommend handling authorization on your registry server.
A common simple approach is to use a `token` query parameter to authenticate requests to your registry. e.g. `http://localhost:3000/r/hello-world.json?token=[SECURE_TOKEN_HERE]`.
Use the secure token to authenticate requests and return a 401 Unauthorized response if the token is invalid. Both the `shadcn` CLI and `Open in v0` will handle the 401 response and display a message to the user.
<Callout className="mt-6">
**Note:** Make sure to encrypt and expire tokens.
</Callout>
## Guidelines
Here are some guidelines to follow when building components for a registry.
- Place your registry item in the `registry/[STYLE]/[NAME]` directory. I'm using `new-york` as an example. It can be anything you want as long as it's nested under the `registry` directory.
- The following properties are required for the block definition: `name`, `description`, `type` and `files`.
- It is recommended to add a proper name and description to your registry item. This helps LLMs understand the component and its purpose.
- Make sure to list all registry dependencies in `registryDependencies`. A registry dependency is the name of the component in the registry eg. `input`, `button`, `card`, etc or a URL to a registry item eg. `http://localhost:3000/r/editor.json`.
- Make sure to list all dependencies in `dependencies`. A dependency is the name of the package in the registry eg. `zod`, `sonner`, etc. To set a version, you can use the `name@version` format eg. `zod@^3.20.0`.
- **Imports should always use the `@/registry` path.** eg. `import { HelloWorld } from "@/registry/new-york/hello-world/hello-world"`
@@ -186,3 +167,7 @@ To install a registry item using the `shadcn` CLI, use the `add` command followe
```bash
npx shadcn@latest add http://localhost:3000/r/hello-world.json
```
See the [Namespaced
Registries](/docs/registry/namespace) docs for more information on
how to install registry items from a namespaced registry.

View File

@@ -1,16 +1,15 @@
---
title: Registry
description: Run your own component registry.
title: Introduction
description: Run your own code registry.
---
You can use the `shadcn` CLI to run your own code registry. Running your own registry allows you to distribute your custom components, hooks, pages, config, rules and other files to any project.
<Callout>
**Note:** This feature is currently experimental. Help us improve it by
testing it out and sending feedback. If you have any questions, please [reach
out to us](https://github.com/shadcn-ui/ui/discussions).
**Note:** The registry works with any project type and any framework, and is
not limited to React.
</Callout>
You can use the `shadcn` CLI to run your own component registry. Running your own registry allows you to distribute your custom components, hooks, pages, and other files to any React project.
<figure className="flex flex-col gap-4">
<Image
src="/images/registry-light.png"
@@ -27,14 +26,54 @@ You can use the `shadcn` CLI to run your own component registry. Running your ow
className="mt-6 hidden w-full overflow-hidden rounded-lg border shadow-sm dark:block"
/>
<figcaption className="text-center text-sm text-gray-500">
Distribute code to any React project.
A distribution system for code
</figcaption>
</figure>
Registry items are automatically compatible with the `shadcn` CLI and `Open in v0`.
Ready to create your own registry? In the next section, we'll walk you through setting up your own custom registry step-by-step, from creating your first component to publishing it for others to use.
## Requirements
<div className="mt-6 grid gap-4 sm:grid-cols-2">
<LinkedCard href="/docs/registry/getting-started" className="items-start text-sm md:p-6">
<div className="font-medium">Getting Started</div>
<div className="text-muted-foreground">
Set up and build your own registry
</div>
</LinkedCard>
You are free to design and host your custom registry as you see fit. The only requirement is that your registry items must be valid JSON files that conform to the [registry-item schema specification](/docs/registry/registry-item-json).
If you'd like to see an example of a registry, we have a [template project](https://github.com/shadcn-ui/registry-template) for you to use as a starting point.
<LinkedCard
href="/docs/registry/authentication"
className="items-start text-sm md:p-6"
>
<div className="font-medium">Authentication</div>
<div className="text-muted-foreground">
Secure your registry with authentication
</div>
</LinkedCard>
<LinkedCard
href="/docs/registry/namespace"
className="items-start text-sm md:p-6"
>
<div className="font-medium">Namespaces</div>
<div className="text-muted-foreground">
Configure registries with namespaces
</div>
</LinkedCard>
<LinkedCard
href="/docs/registry/examples"
className="items-start text-sm md:p-6"
>
<div className="font-medium">Examples</div>
<div className="text-muted-foreground">
Registry item examples and configurations
</div>
</LinkedCard>
<LinkedCard
href="/docs/registry/registry-json"
className="items-start text-sm md:p-6"
>
<div className="font-medium">Schema</div>
<div className="text-muted-foreground">
Schema specification for registry.json
</div>
</LinkedCard>
</div>

View File

@@ -0,0 +1,109 @@
---
title: MCP Server
description: MCP support for registry developers
---
The [shadcn MCP server](/docs/mcp) works out of the box with any shadcn-compatible registry. You do not need to do anything special to enable MCP support for your registry.
---
## Prerequisites
The MCP server works by requesting your registry index. Make sure you have a registry item file at the root of your registry named `registry`.
For example, if your registry is hosted at `https://acme.com/r/[name].json`, you should have a file at `https://acme.com/r/registry.json` or `https://acme.com/r/registry` if you're using a JSON file extension.
This file must be a valid JSON file that conforms to the [registry schema](/docs/registry/registry-json).
---
## Configuring MCP
Ask your registry consumers to configure your registry in their `components.json` file and install the shadcn MCP server:
<Tabs defaultValue="claude">
<TabsList>
<TabsTrigger value="claude">Claude Code</TabsTrigger>
<TabsTrigger value="cursor">Cursor</TabsTrigger>
<TabsTrigger value="vscode">VS Code</TabsTrigger>
</TabsList>
<TabsContent value="claude" className="mt-4">
**Configure your registry** in your `components.json` file:
```json title="components.json" showLineNumbers
{
"registries": {
"@acme": "https://acme.com/r/{name}.json"
}
}
```
**Run the following command** in your project:
```bash
npx shadcn@latest mcp init --client claude
```
**Restart Claude Code** and try the following prompts:
- Show me the components in the acme registry
- Create a landing page using items from the acme registry
**Note:** You can use `/mcp` command in Claude Code to debug the MCP server.
</TabsContent>
<TabsContent value="cursor" className="mt-4">
**Configure your registry** in your `components.json` file:
```json title="components.json" showLineNumbers
{
"registries": {
"@acme": "https://acme.com/r/{name}.json"
}
}
```
**Run the following command** in your project:
```bash
npx shadcn@latest mcp init --client cursor
```
Open **Cursor Settings** and **Enable the MCP server** for shadcn. Then try the following prompts:
- Show me the components in the acme registry
- Create a landing page using items from the acme registry
</TabsContent>
<TabsContent value="vscode" className="mt-4">
**Configure your registry** in your `components.json` file:
```json title="components.json" showLineNumbers
{
"registries": {
"@acme": "https://acme.com/r/{name}.json"
}
}
```
**Run the following command** in your project:
```bash
npx shadcn@latest mcp init --client vscode
```
Open `.vscode/mcp.json` and click **Start** next to the shadcn server. Then try the following prompts with GitHub Copilot:
- Show me the components in the acme registry
- Create a landing page using items from the acme registry
</TabsContent>
</Tabs>
You can read more about the MCP server in the [MCP documentation](/docs/mcp).
---
## Best Practices
Here are some best practices for MCP-compatible registries:
1. **Clear Descriptions**: Add concise, informative descriptions that help AI assistants understand what a registry item is for and how to use it.
2. **Proper Dependencies**: List all `dependencies` accurately so MCP can install them automatically.
3. **Registry Dependencies**: Use `registryDependencies` to indicate relationships between items.
4. **Consistent Naming**: Use kebab-case for component names and maintain consistency across your registry.

View File

@@ -1,10 +1,14 @@
{
"title": "Registry",
"pages": [
"index",
"getting-started",
"faq",
"open-in-v0",
"namespace",
"authentication",
"examples",
"mcp",
"registry-index",
"open-in-v0",
"registry-json",
"registry-item-json"
]

View File

@@ -0,0 +1,913 @@
---
title: Namespaces
description: Configure and use multiple resource registries with namespace support.
---
Namespaced registries let you configure multiple resource sources in one project. This means you can install components, libraries, utilities, AI prompts, configuration files, and other resources from various registries, whether they're public, third-party, or your own custom private libraries.
## Table of Contents
- [Overview](#overview)
- [Decentralized Namespace System](#decentralized-namespace-system)
- [Getting Started](#getting-started)
- [Registry Naming Convention](#registry-naming-convention)
- [Configuration](#configuration)
- [Authentication & Security](#authentication--security)
- [Versioning](#versioning)
- [Dependency Resolution](#dependency-resolution)
- [Built-in Registries](#built-in-registries)
- [CLI Commands](#cli-commands)
- [Error Handling](#error-handling)
- [Creating Your Own Registry](#creating-your-own-registry)
- [Example Configurations](#example-configurations)
- [Technical Details](#technical-details)
- [Best Practices](#best-practices)
- [Troubleshooting](#troubleshooting)
---
## Overview
Registry namespaces are prefixed with `@` and provide a way to organize and reference resources from different sources. Resources can be any type of content: components, libraries, utilities, hooks, AI prompts, configuration files, themes, and more. For example:
- `@shadcn/button` - UI component from the shadcn registry
- `@v0/dashboard` - Dashboard component from the v0 registry
- `@ai-elements/input` - AI prompt input from an AI elements registry
- `@acme/auth-utils` - Authentication utilities from your company's private registry
- `@ai/chatbot-rules` - AI prompt rules from an AI resources registry
- `@themes/dark-mode` - Theme configuration from a themes registry
---
## Decentralized Namespace System
We intentionally designed the namespace system to be decentralized. There is a [central open source registry index](/docs/registry/registry-index) for open source namespaces but you are free to create and use any namespace you want.
This decentralized approach gives you complete flexibility to organize your resources however makes sense for your organization.
You can create multiple registries for different purposes:
```json title="components.json" showLineNumbers
{
"registries": {
"@acme-ui": "https://registry.acme.com/ui/{name}.json",
"@acme-docs": "https://registry.acme.com/docs/{name}.json",
"@acme-ai": "https://registry.acme.com/ai/{name}.json",
"@acme-themes": "https://registry.acme.com/themes/{name}.json",
"@acme-internal": {
"url": "https://internal.acme.com/registry/{name}.json",
"headers": {
"Authorization": "Bearer ${INTERNAL_TOKEN}"
}
}
}
}
```
This allows you to:
- **Organize by type**: Separate UI components, documentation, AI resources, etc.
- **Organize by team**: Different teams can maintain their own registries
- **Organize by visibility**: Public vs. private resources
- **Organize by version**: Stable vs. experimental registries
- **No naming conflicts**: Since there's no central authority, you don't need to worry about namespace collisions
### Examples of Multi-Registry Setups
#### By Resource Type
```json title="components.json" showLineNumbers
{
"@components": "https://cdn.company.com/components/{name}.json",
"@hooks": "https://cdn.company.com/hooks/{name}.json",
"@utils": "https://cdn.company.com/utils/{name}.json",
"@prompts": "https://cdn.company.com/ai-prompts/{name}.json"
}
```
#### By Team or Department
```json title="components.json" showLineNumbers
{
"@design": "https://design.company.com/registry/{name}.json",
"@engineering": "https://eng.company.com/registry/{name}.json",
"@marketing": "https://marketing.company.com/registry/{name}.json"
}
```
#### By Stability
```json title="components.json" showLineNumbers
{
"@stable": "https://registry.company.com/stable/{name}.json",
"@latest": "https://registry.company.com/beta/{name}.json",
"@experimental": "https://registry.company.com/experimental/{name}.json"
}
```
---
## Getting Started
### Installing Resources
Once configured, you can install resources using the namespace syntax:
```bash
npx shadcn@latest add @v0/dashboard
```
or multiple resources at once:
```bash
npx shadcn@latest add @acme/header @lib/auth-utils @ai/chatbot-rules
```
### Quick Configuration
Add registries to your `components.json`:
```json title="components.json"
{
"registries": {
"@v0": "https://v0.dev/chat/b/{name}",
"@acme": "https://registry.acme.com/resources/{name}.json"
}
}
```
Then start installing:
```bash
npx shadcn@latest add @acme/button
```
---
## Registry Naming Convention
Registry names must follow these rules:
- Start with `@` symbol
- Contain only alphanumeric characters, hyphens, and underscores
- Examples of valid names: `@v0`, `@acme-ui`, `@my_company`
The pattern for referencing resources is: `@namespace/resource-name`
---
## Configuration
Namespaced registries are configured in your `components.json` file under the `registries` field.
### Basic Configuration
The simplest way to configure a registry is with a URL template string:
```json title="components.json"
{
"registries": {
"@v0": "https://v0.dev/chat/b/{name}",
"@acme": "https://registry.acme.com/resources/{name}.json",
"@lib": "https://lib.company.com/utilities/{name}",
"@ai": "https://ai-resources.com/r/{name}.json"
}
}
```
> **Note:** The `{name}` placeholder in the URL is automatically parsed and replaced with the resource name when you run `npx shadcn@latest add @namespace/resource-name`. For example, `@acme/button` becomes `https://registry.acme.com/resources/button.json`. See [URL Pattern System](#url-pattern-system) for more details.
### Advanced Configuration
For registries that require authentication or additional parameters, use the object format:
```json title="components.json"
{
"registries": {
"@private": {
"url": "https://api.company.com/registry/{name}.json",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}",
"X-API-Key": "${API_KEY}"
},
"params": {
"version": "latest",
"format": "json"
}
}
}
}
```
> **Note:** Environment variables in the format `${VAR_NAME}` are automatically expanded from your environment (process.env). This works in URLs, headers, and params. For example, `${REGISTRY_TOKEN}` will be replaced with the value of `process.env.REGISTRY_TOKEN`. See [Authentication & Security](#authentication--security) for more details on using environment variables.
---
### URL Pattern System
Registry URLs support the following placeholders:
### `{name}` Placeholder (required)
The `{name}` placeholder is replaced with the resource name:
```json title="components.json" showLineNumbers
{
"@acme": "https://registry.acme.com/{name}.json"
}
```
When installing `@acme/button`, the URL becomes: `https://registry.acme.com/button.json`
When installing `@acme/auth-utils`, the URL becomes: `https://registry.acme.com/auth-utils.json`
### `{style}` Placeholder (optional)
The `{style}` placeholder is replaced with the current style configuration:
```json
{
"@themes": "https://registry.example.com/{style}/{name}.json"
}
```
With style set to `new-york`, installing `@themes/card` resolves to: `https://registry.example.com/new-york/card.json`
The style placeholder is optional. Use this when you want to serve different versions of the same resource. For example, you can serve a different version of a component for each style.
---
## Authentication & Security
### Environment Variables
Use environment variables to securely store credentials:
```json title="components.json"
{
"registries": {
"@private": {
"url": "https://api.company.com/registry/{name}.json",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}"
}
}
}
}
```
Then set the environment variable:
```bash title=".env.local"
REGISTRY_TOKEN=your_secret_token_here
```
### Authentication Methods
#### Bearer Token (OAuth 2.0)
```json
{
"@github": {
"url": "https://api.github.com/repos/org/registry/contents/{name}.json",
"headers": {
"Authorization": "Bearer ${GITHUB_TOKEN}"
}
}
}
```
#### API Key in Headers
```json title="components.json" showLineNumbers
{
"@private": {
"url": "https://api.company.com/registry/{name}",
"headers": {
"X-API-Key": "${API_KEY}"
}
}
}
```
#### Basic Authentication
```json title="components.json" showLineNumbers
{
"@internal": {
"url": "https://registry.company.com/{name}.json",
"headers": {
"Authorization": "Basic ${BASE64_CREDENTIALS}"
}
}
}
```
#### Query Parameter Authentication
```json title="components.json" showLineNumbers
{
"@secure": {
"url": "https://registry.example.com/{name}.json",
"params": {
"api_key": "${API_KEY}",
"client_id": "${CLIENT_ID}",
"signature": "${REQUEST_SIGNATURE}"
}
}
}
```
#### Multiple Authentication Methods
Some registries require multiple authentication methods:
```json title="components.json" showLineNumbers
{
"@enterprise": {
"url": "https://api.enterprise.com/v2/registry/{name}",
"headers": {
"Authorization": "Bearer ${ACCESS_TOKEN}",
"X-API-Key": "${API_KEY}",
"X-Workspace-Id": "${WORKSPACE_ID}"
},
"params": {
"version": "latest"
}
}
}
```
### Security Considerations
When working with namespaced registries, especially third-party or public ones, security is paramount. Here's how we handle security:
### Resource Validation
All resources fetched from registries are validated against our registry item schema before installation. This ensures:
- **Structure validation**: Resources must conform to the expected JSON schema
- **Type safety**: Resource types are validated (`registry:ui`, `registry:lib`, etc.)
- **No arbitrary code execution**: Resources are data files, not executable scripts
### Environment Variable Security
Environment variables used for authentication are:
- **Never logged**: The CLI never logs or displays environment variable values
- **Expanded at runtime**: Variables are only expanded when needed, not stored
- **Isolated per registry**: Each registry maintains its own authentication context
Example of secure configuration:
```json title="components.json" showLineNumbers
{
"registries": {
"@private": {
"url": "https://api.company.com/registry/{name}.json",
"headers": {
"Authorization": "Bearer ${PRIVATE_REGISTRY_TOKEN}"
}
}
}
}
```
Never commit actual tokens to version control. Use `.env.local`:
```bash title=".env.local"
PRIVATE_REGISTRY_TOKEN=actual_token_here
```
### HTTPS Enforcement
We strongly recommend using HTTPS for all registry URLs:
- **Encrypted transport**: Prevents man-in-the-middle attacks
- **Certificate validation**: Ensures you're connecting to the legitimate registry
- **Credential protection**: Headers and tokens are encrypted in transit
```json title="components.json" showLineNumbers
{
"registries": {
"@secure": "https://registry.example.com/{name}.json", // ✅ Good
"@insecure": "http://registry.example.com/{name}.json" // ❌ Avoid
}
}
```
### Content Security
Resources from registries are treated as data, not code:
1. **JSON parsing only**: Resources must be valid JSON
2. **Schema validation**: Must match the registry item schema
3. **File path restrictions**: Files can only be written to configured paths
4. **No script execution**: The CLI doesn't execute any code from registry resources
### Registry Trust Model
The namespace system operates on a trust model:
- **You trust what you install**: Only add registries you trust to your configuration
- **Explicit configuration**: Registries must be explicitly configured in `components.json`
- **No automatic registry discovery**: The CLI never automatically adds registries
- **Dependency transparency**: All dependencies are clearly listed in registry items
### Best Practices for Registry Operators
If you're running your own registry:
1. **Use HTTPS always**: Never serve registry content over HTTP
2. **Implement authentication**: Require API keys or tokens for private registries
3. **Rate limiting**: Protect your registry from abuse
4. **Content validation**: Validate resources before serving them
Example secure registry setup:
```json title="components.json" showLineNumbers
{
"@company": {
"url": "https://registry.company.com/v1/{name}.json",
"headers": {
"Authorization": "Bearer ${COMPANY_TOKEN}",
"X-Registry-Version": "1.0"
}
}
}
```
### Inspecting Resources Before Installation
The CLI provides transparency about what's being installed. You can see the payload of a registry item using the following command:
```bash
npx shadcn@latest view @acme/button
```
This will output the payload of the registry item to the console.
---
## Dependency Resolution
### Basic Dependency Resolution
Resources can have dependencies across different registries:
```json title="registry-item.json" showLineNumbers
{
"name": "dashboard",
"type": "registry:block",
"registryDependencies": [
"@shadcn/card", // From default registry
"@v0/chart", // From v0 registry
"@acme/data-table", // From acme registry
"@lib/data-fetcher", // Utility library
"@ai/analytics-prompt" // AI prompt resource
]
}
```
The CLI automatically resolves and installs all dependencies from their respective registries.
### Advanced Dependency Resolution
Understanding how dependencies are resolved internally is important if you're developing registries or need to customize third-party resources.
### How Resolution Works
When you run `npx shadcn@latest add @namespace/resource`, the CLI does the following:
1. **Clears registry context** to start fresh
2. **Fetches the main resource** from the specified registry
3. **Recursively resolves dependencies** from their respective registries
4. **Applies topological sorting** to ensure proper installation order
5. **Deduplicates files** based on target paths (last one wins)
6. **Deep merges configurations** (tailwind, cssVars, css, envVars)
This means that if you run the following command:
```bash
npx shadcn@latest add @acme/auth @custom/login-form
```
The `login-form.ts` from `@custom/login-form` will override the `login-form.ts` from `@acme/auth` because it's resolved last.
### Overriding Third-Party Resources
You can leverage the dependency resolution process to override any third-party resource by adding them to your custom resource under `registryDependencies` and overriding with your own custom values.
#### Example: Customizing a Third-Party Button
Let's say you want to customize a button from a vendor registry:
**1. Original vendor button** (`@vendor/button`):
```json title="button.json" showLineNumbers
{
"name": "button",
"type": "registry:ui",
"files": [
{
"path": "components/ui/button.tsx",
"type": "registry:ui",
"content": "// Vendor's button implementation\nexport function Button() { ... }"
}
],
"cssVars": {
"light": {
"--button-bg": "blue"
}
}
}
```
**2. Create your custom override** (`@my-company/custom-button`):
```json title="custom-button.json" showLineNumbers
{
"name": "custom-button",
"type": "registry:ui",
"registryDependencies": [
"@vendor/button" // Import original first
],
"cssVars": {
"light": {
"--button-bg": "purple" // Override the color
}
}
}
```
**3. Install your custom version**:
```bash
npx shadcn@latest add @my-company/custom-button
```
This installs the original button from `@vendor/button` and then overrides the `cssVars` with your own custom values.
### Advanced Override Patterns
#### Extending Without Replacing
Keep the original and add extensions:
```json title="extended-table.json" showLineNumbers
{
"name": "extended-table",
"registryDependencies": ["@vendor/table"],
"files": [
{
"path": "components/ui/table-extended.tsx",
"content": "import { Table } from '@vendor/table'\n// Add your extensions\nexport function ExtendedTable() { ... }"
}
]
}
```
This will install the original table from `@vendor/table` and then add your extensions to `components/ui/table-extended.tsx`.
#### Partial Override (Multi-file Resources)
Override only specific files from a complex component:
```json title="custom-auth.json" showLineNumbers
{
"name": "custom-auth",
"registryDependencies": [
"@vendor/auth" // Has multiple files
],
"files": [
{
"path": "lib/auth-server.ts",
"type": "registry:lib",
"content": "// Your custom auth server"
}
]
}
```
### Resolution Order Example
When you install `@custom/dashboard` that depends on multiple resources:
```json title="dashboard.json" showLineNumbers
{
"name": "dashboard",
"registryDependencies": [
"@shadcn/card", // 1. Resolved first
"@vendor/chart", // 2. Resolved second
"@custom/card" // 3. Resolved last (overrides @shadcn/card)
]
}
```
Resolution order:
1. `@shadcn/card` - installs to `components/ui/card.tsx`
2. `@vendor/chart` - installs to `components/ui/chart.tsx`
3. `@custom/card` - overwrites `components/ui/card.tsx` (if same target)
### Key Resolution Features
1. **Source Tracking**: Each resource knows which registry it came from, avoiding naming conflicts
2. **Circular Dependency Prevention**: Automatically detects and prevents circular dependencies
3. **Smart Installation Order**: Dependencies are installed first, then the resources that use them
---
## Versioning
You can implement versioning for your registry resources using query parameters. This allows users to pin specific versions or use different release channels.
### Basic Version Parameter
```json title="components.json" showLineNumbers
{
"@versioned": {
"url": "https://registry.example.com/{name}",
"params": {
"version": "v2"
}
}
}
```
This resolves `@versioned/button` to: `https://registry.example.com/button?version=v2`
### Dynamic Version Selection
Use environment variables to control versions across your project:
```json title="components.json" showLineNumbers
{
"@stable": {
"url": "https://registry.company.com/{name}",
"params": {
"version": "${REGISTRY_VERSION}"
}
}
}
```
This allows you to:
- Set `REGISTRY_VERSION=v1.2.3` in production
- Override per environment (dev, staging, prod)
### Semantic Versioning
Implement semantic versioning with range support:
```json title="components.json" showLineNumbers
{
"@npm-style": {
"url": "https://registry.example.com/{name}",
"params": {
"semver": "^2.0.0",
"prerelease": "${ALLOW_PRERELEASE}"
}
}
}
```
### Version Resolution Best Practices
1. **Use environment variables** for version control across environments
2. **Provide sensible defaults** using the `${VAR:-default}` syntax
3. **Document version schemes** clearly for registry users
4. **Support version pinning** for reproducible builds
5. **Implement version discovery** endpoints (e.g., `/versions/{name}`)
6. **Cache versioned resources** appropriately with proper cache headers
---
## CLI Commands
The shadcn CLI provides several commands for working with namespaced registries:
### Adding Resources
Install resources from any configured registry:
```bash
# Install from a specific registry
npx shadcn@latest add @v0/dashboard
# Install multiple resources
npx shadcn@latest add @acme/button @lib/utils @ai/prompt
# Install from URL directly
npx shadcn@latest add https://registry.example.com/button.json
# Install from local file
npx shadcn@latest add ./local-registry/button.json
```
### Viewing Resources
Inspect registry items before installation:
```bash
# View a resource from a registry
npx shadcn@latest view @acme/button
# View multiple resources
npx shadcn@latest view @v0/dashboard @shadcn/card
# View from URL
npx shadcn@latest view https://registry.example.com/button.json
```
The `view` command displays:
- Resource metadata (name, type, description)
- Dependencies and registry dependencies
- File contents that will be installed
- CSS variables and Tailwind configuration
- Required environment variables
### Searching Registries
Search for available resources in registries:
```bash
# Search a specific registry
npx shadcn@latest search @v0
# Search with query
npx shadcn@latest search @acme --query "auth"
# Search multiple registries
npx shadcn@latest search @v0 @acme @lib
# Limit results
npx shadcn@latest search @v0 --limit 10 --offset 20
# List all items (alias for search)
npx shadcn@latest list @acme
```
Search results include:
- Resource name and type
- Description
- Registry source
---
## Error Handling
### Registry Not Configured
If you reference a registry that isn't configured:
```bash
npx shadcn@latest add @non-existent/component
```
Error:
```txt
Unknown registry "@non-existent". Make sure it is defined in components.json as follows:
{
"registries": {
"@non-existent": "[URL_TO_REGISTRY]"
}
}
```
### Missing Environment Variables
If required environment variables are not set:
```txt
Registry "@private" requires the following environment variables:
• REGISTRY_TOKEN
Set the required environment variables to your .env or .env.local file.
```
### Resource Not Found
404 Not Found:
```txt
The item at https://registry.company.com/button.json was not found. It may not exist at the registry.
```
This usually means:
- The resource name is misspelled
- The resource doesn't exist in the registry
- The registry URL pattern is incorrect
### Authentication Failures
401 Unauthorized:
```txt
You are not authorized to access the item at https://api.company.com/button.json
Check your authentication credentials and environment variables.
```
403 Forbidden:
```txt
Access forbidden for https://api.company.com/button.json
Verify your API key has the necessary permissions.
```
---
## Creating Your Own Registry
To make your registry compatible with the namespace system, you can serve any type of resource - components, libraries, utilities, AI prompts, themes, configurations, or any other shareable code/content:
1. **Implement the registry item schema**: Your registry must return JSON that conforms to the [registry item schema](/docs/registry/registry-item-json).
2. **Support the URL pattern**: Include `{name}` in your URL template where the resource name will be inserted.
3. **Define resource types**: Use appropriate `type` fields to identify your resources (e.g., `registry:ui`, `registry:lib`, `registry:ai`, `registry:theme`, etc.).
4. **Handle authentication** (if needed): Accept authentication via headers or query parameters.
5. **Document your namespace**: Provide clear instructions for users to configure your registry:
```json title="components.json" showLineNumbers
{
"registries": {
"@your-registry": "https://your-domain.com/r/{name}.json"
}
}
```
---
## Technical Details
### Parser Pattern
The namespace parser uses the following regex pattern:
```regex title="namespace-parser.js"
/^(@[a-zA-Z0-9](?:[a-zA-Z0-9-_]*[a-zA-Z0-9])?)\/(.+)$/
```
This ensures valid namespace formatting and proper component name extraction.
### Resolution Process
1. **Parse**: Extract namespace and component name from `@namespace/component`
2. **Lookup**: Find registry configuration for `@namespace`
3. **Build URL**: Replace placeholders with actual values
4. **Set Headers**: Apply authentication headers if configured
5. **Fetch**: Retrieve component from the resolved URL
6. **Validate**: Ensure response matches registry item schema
7. **Resolve Dependencies**: Recursively fetch any registry dependencies
### Cross-Registry Dependencies
When a component has dependencies from different registries, the resolver:
1. Maintains separate authentication contexts for each registry
2. Resolves each dependency from its respective source
3. Deduplicates files based on target paths
4. Merges configurations (tailwind, cssVars, etc.) from all sources
---
## Best Practices
1. **Use environment variables** for sensitive data like API keys and tokens
2. **Namespace your registry** with a unique, descriptive name
3. **Document authentication requirements** clearly for users
4. **Implement proper error responses** with helpful messages
5. **Cache registry responses** when possible to improve performance
6. **Support style variants** if your components have multiple themes
---
## Troubleshooting
### Resources not found
- Verify the registry URL is correct and accessible
- Check that the `{name}` placeholder is included in the URL
- Ensure the resource exists in the registry
- Confirm the resource type matches what the registry provides
### Authentication issues
- Confirm environment variables are set correctly
- Verify API keys/tokens are valid and not expired
- Check that headers are being sent in the correct format
### Dependency conflicts
- Review resources with the same name from different registries
- Use fully qualified names (`@namespace/resource`) to avoid ambiguity
- Check for circular dependencies between registries
- Ensure resource types are compatible when mixing registries

View File

@@ -8,8 +8,8 @@ If your registry is hosted and publicly accessible via a URL, you can open a reg
eg. [https://v0.dev/chat/api/open?url=https://ui.shadcn.com/r/styles/new-york/login-01.json](https://v0.dev/chat/api/open?url=https://ui.shadcn.com/r/styles/new-york/login-01.json)
<Callout className="mt-6">
**Note:** The `Open in v0` button does not support `cssVars` and `tailwind`
properties.
**Important:** `Open in v0` does not support `cssVars`, `css`, `envVars`,
namespaced registries, or advanced authentication methods.
</Callout>
## Button
@@ -61,4 +61,46 @@ export function OpenInV0Button({ url }: { url: string }) {
## Authentication
See the [Adding Auth](/docs/registry/getting-started#adding-auth) section for more information on how to authenticate requests to your registry and Open in v0.
Open in v0 only supports query parameter authentication. It does not support namespaced registries or advanced authentication methods like Bearer tokens or API keys in headers.
### Using Query Parameter Authentication
To add authentication to your registry for Open in v0, use a `token` query parameter:
```
https://registry.company.com/r/hello-world.json?token=your_secure_token_here
```
When implementing this on your registry server:
1. Check for the `token` query parameter
2. Validate the token against your authentication system
3. Return a `401 Unauthorized` response if the token is invalid or missing
4. Both the shadcn CLI and Open in v0 will handle the 401 response and display an appropriate message to users
### Example Implementation
```typescript
// Next.js API route example
export async function GET(request: NextRequest) {
const token = request.nextUrl.searchParams.get("token")
if (!isValidToken(token)) {
return NextResponse.json(
{
error: "Unauthorized",
message: "Invalid or missing token",
},
{ status: 401 }
)
}
// Return the registry item
return NextResponse.json(registryItem)
}
```
<Callout className="mt-6">
**Security Note:** Make sure to encrypt and expire tokens. Never expose
production tokens in documentation or examples.
</Callout>

View File

@@ -0,0 +1,79 @@
---
title: Index
description: Open Source Registry Index
---
The open source registry index is a list of all the open source registries that are available to use out of the box.
When you run `shadcn add` or `shadcn search`, the CLI will automatically check the registry index for the registry you are looking for and add it to your `components.json` file.
You can see the full list at [https://ui.shadcn.com/r/registries.json](https://ui.shadcn.com/r/registries.json).
## Adding a Registry
You can submit a PR to add a registry to the index by adding it to the [registries.json](https://github.com/shadcn-ui/ui/blob/main/apps/v4/public/r/registries.json) file.
Here's an example of how to add a registry to the index:
```json title="registries.json" showLineNumbers
{
"@acme": "https://registry.acme.com/r/{name}.json",
"@example": "https://example.com/r/{name}"
}
```
### Requirements
1. The registry must be open source and publicly accessible.
2. The registry must be a valid JSON file that conforms to the [registry schema specification](/docs/registry/registry-json).
3. The registry is expected to be a flat registry with no nested items i.e `/registry.json` and `/component-name.json` files are expected to be in the root of the registry.
4. The `files` array, if present, must NOT include a `content` property.
Here's an example of a valid registry:
```json title="registry.json" showLineNumbers
{
"$schema": "https://ui.shadcn.com/schema/registry.json",
"name": "acme",
"homepage": "https://acme.com",
"items": [
{
"name": "login-form",
"type": "registry:component",
"title": "Login Form",
"description": "A login form component.",
"files": [
{
"path": "registry/new-york/auth/login-form.tsx",
"type": "registry:component"
}
]
},
{
"name": "example-login-form",
"type": "registry:component",
"title": "Example Login Form",
"description": "An example showing how to use the login form component.",
"files": [
{
"path": "registry/new-york/examples/example-login-form.tsx",
"type": "registry:component"
}
]
}
}
]
}
```
### Validation
At the root of the `shadcn/ui` project, you can run the following command to validate the `registries.json` file.
```bash
pnpm validate:registries
```
This will validate the registries.json file and output any errors.
Once you have submitted your PR, it will be validated and reviewed by the team.

View File

@@ -12,6 +12,12 @@ The `registry-item.json` schema is used to define your custom registry items.
"type": "registry:block",
"title": "Hello World",
"description": "A simple hello world component.",
"registryDependencies": [
"button",
"@acme/input-form",
"https://example.com/r/foo"
],
"dependencies": ["is-even@3.0.0", "motion"],
"files": [
{
"path": "registry/new-york/hello-world/hello-world.tsx",
@@ -107,6 +113,7 @@ The following types are supported:
| `registry:file` | Use for miscellaneous files. |
| `registry:style` | Use for registry styles. eg. `new-york` |
| `registry:theme` | Use for themes. |
| `registry:item` | Use for universal registry items. |
### author
@@ -139,17 +146,17 @@ Use `@version` to specify the version of your registry item.
### registryDependencies
Used for registry dependencies. Can be names or URLs. Use the name of the item to reference shadcn/ui components and urls to reference other registries.
Used for registry dependencies. Can be names, namespaced or URLs.
- For `shadcn/ui` registry items such as `button`, `input`, `select`, etc use the name eg. `['button', 'input', 'select']`.
- For namespaced registry items such as `@acme` use the name eg. `['@acme/input-form']`.
- For custom registry items use the URL of the registry item eg. `['https://example.com/r/hello-world.json']`.
```json title="registry-item.json" showLineNumbers
{
"registryDependencies": [
"button",
"input",
"select",
"@acme/input-form",
"https://example.com/r/editor.json"
]
}
@@ -260,11 +267,13 @@ Use to define CSS variables for your registry item.
### css
Use `css` to add new rules to the project's CSS file eg. `@layer base`, `@layer components`, `@utility`, `@keyframes`, etc.
Use `css` to add new rules to the project's CSS file eg. `@layer base`, `@layer components`, `@utility`, `@keyframes`, `@plugin`, etc.
```json title="registry-item.json" showLineNumbers
{
"css": {
"@plugin @tailwindcss/typography": {},
"@plugin foo": {},
"@layer base": {
"body": {
"font-size": "var(--text-base)",
@@ -293,13 +302,35 @@ Use `css` to add new rules to the project's CSS file eg. `@layer base`, `@layer
}
```
### envVars
Use `envVars` to add environment variables to your registry item.
```json title="registry-item.json" showLineNumbers
{
"envVars": {
"NEXT_PUBLIC_APP_URL": "http://localhost:4000",
"DATABASE_URL": "postgresql://postgres:postgres@localhost:5432/postgres",
"OPENAI_API_KEY": ""
}
}
```
Environment variables are added to the `.env.local` or `.env` file. Existing variables are not overwritten.
<Callout>
**IMPORTANT:** Use `envVars` to add development or example variables. Do NOT use it to add production variables.
</Callout>
### docs
Use `docs` to show custom documentation or message when installing your registry item via the CLI.
```json title="registry-item.json" showLineNumbers
{
"docs": "Remember to add the FOO_BAR environment variable to your .env file."
"docs": "To get an OPENAI_API_KEY, sign up for an account at https://platform.openai.com."
}
```

View File

@@ -16,6 +16,12 @@ The `registry.json` schema is used to define your custom component registry.
"type": "registry:block",
"title": "Hello World",
"description": "A simple hello world component.",
"registryDependencies": [
"button",
"@acme/input-form",
"https://example.com/r/foo"
],
"dependencies": ["is-even@3.0.0", "motion"],
"files": [
{
"path": "registry/new-york/hello-world/hello-world.tsx",
@@ -73,6 +79,12 @@ The `items` in your registry. Each item must implement the [registry-item schema
"type": "registry:block",
"title": "Hello World",
"description": "A simple hello world component.",
"registryDependencies": [
"button",
"@acme/input-form",
"https://example.com/r/foo"
],
"dependencies": ["is-even@3.0.0", "motion"],
"files": [
{
"path": "registry/new-york/hello-world/hello-world.tsx",

View File

@@ -1,6 +1,6 @@
"use server"
import { registryItemSchema } from "shadcn/registry"
import { registryItemSchema } from "shadcn/schema"
import { z } from "zod"
export async function getAllBlockIds(

View File

@@ -3,7 +3,7 @@ export const siteConfig = {
url: "https://ui.shadcn.com",
ogImage: "https://ui.shadcn.com/og.jpg",
description:
"A set of beautifully-designed, accessible components and a code distribution platform. Works with your favorite frameworks. Open Source. Open Code.",
"A set of beautifully designed components that you can customize, extend, and build on. Start here then make it your own. Open Source. Open Code.",
links: {
twitter: "https://twitter.com/shadcn",
github: "https://github.com/shadcn-ui/ui",

1
apps/v4/lib/flags.ts Normal file
View File

@@ -0,0 +1 @@
export const showMcpDocs = true

View File

@@ -1,7 +1,7 @@
import { promises as fs } from "fs"
import { tmpdir } from "os"
import path from "path"
import { registryItemFileSchema, registryItemSchema } from "shadcn/registry"
import { registryItemFileSchema, registryItemSchema } from "shadcn/schema"
import { Project, ScriptKind } from "ts-morph"
import { z } from "zod"

View File

@@ -52,7 +52,7 @@ export const mdxComponents = {
.replace(/\?/g, "")
.toLowerCase()}
className={cn(
"font-heading mt-12 scroll-m-28 text-2xl font-medium tracking-tight first:mt-0 lg:mt-20 [&+p]:!mt-4 *:[code]:text-2xl",
"font-heading mt-8 scroll-m-28 text-xl font-medium tracking-tight first:mt-0 lg:mt-8 [&+p]:!mt-4 *:[code]:text-xl",
className
)}
{...props}
@@ -62,7 +62,7 @@ export const mdxComponents = {
h3: ({ className, ...props }: React.ComponentProps<"h3">) => (
<h3
className={cn(
"font-heading mt-8 scroll-m-28 text-xl font-semibold tracking-tight *:[code]:text-xl",
"font-heading mt-8 scroll-m-28 text-lg font-medium tracking-tight *:[code]:text-xl",
className
)}
{...props}
@@ -71,7 +71,7 @@ export const mdxComponents = {
h4: ({ className, ...props }: React.ComponentProps<"h4">) => (
<h4
className={cn(
"font-heading mt-8 scroll-m-28 text-lg font-medium tracking-tight",
"font-heading mt-8 scroll-m-28 text-base font-medium tracking-tight",
className
)}
{...props}
@@ -80,7 +80,7 @@ export const mdxComponents = {
h5: ({ className, ...props }: React.ComponentProps<"h5">) => (
<h5
className={cn(
"mt-8 scroll-m-28 text-lg font-medium tracking-tight",
"mt-8 scroll-m-28 text-base font-medium tracking-tight",
className
)}
{...props}
@@ -228,7 +228,7 @@ export const mdxComponents = {
return (
<code
className={cn(
"bg-muted relative rounded-md px-[0.3rem] py-[0.2rem] font-mono text-[0.8rem] outline-none",
"bg-muted relative rounded-md px-[0.3rem] py-[0.2rem] font-mono text-[0.8rem] break-words outline-none",
className
)}
{...props}
@@ -298,7 +298,7 @@ export const mdxComponents = {
}: React.ComponentProps<typeof TabsList>) => (
<TabsList
className={cn(
"justify-start gap-4 rounded-none bg-transparent px-2 md:px-0",
"justify-start gap-4 rounded-none bg-transparent px-0",
className
)}
{...props}
@@ -310,7 +310,7 @@ export const mdxComponents = {
}: React.ComponentProps<typeof TabsTrigger>) => (
<TabsTrigger
className={cn(
"text-muted-foreground data-[state=active]:text-foreground px-0 text-base data-[state=active]:shadow-none dark:data-[state=active]:border-transparent dark:data-[state=active]:bg-transparent",
"text-muted-foreground data-[state=active]:text-foreground data-[state=active]:border-primary dark:data-[state=active]:border-primary hover:text-primary rounded-none border-0 border-b-2 border-transparent bg-transparent px-0 pb-3 text-base data-[state=active]:bg-transparent data-[state=active]:shadow-none dark:data-[state=active]:bg-transparent",
className
)}
{...props}

View File

@@ -68,6 +68,24 @@ const nextConfig = {
destination: "/view/:name",
permanent: true,
},
{
source: "/docs/:path*.mdx",
destination: "/docs/:path*.md",
permanent: true,
},
{
source: "/mcp",
destination: "/docs/mcp",
permanent: false,
},
]
},
rewrites() {
return [
{
source: "/docs/:path*.md",
destination: "/llm/:path*",
},
]
},
}

View File

@@ -14,6 +14,7 @@
"format:check": "prettier --check \"**/*.{ts,tsx,mdx}\" --cache",
"registry:build": "tsx --tsconfig ./tsconfig.scripts.json ./scripts/build-registry.mts && prettier --log-level silent --write \"registry/**/*.{ts,tsx,json,mdx}\" --cache",
"registry:capture": "tsx --tsconfig ./tsconfig.scripts.json ./scripts/capture-registry.mts",
"validate:registries": "tsx --tsconfig ./tsconfig.scripts.json ./scripts/validate-registries.mts",
"postinstall": "fumadocs-mdx"
},
"dependencies": {
@@ -54,7 +55,7 @@
"@radix-ui/react-toggle-group": "^1.1.1",
"@radix-ui/react-tooltip": "^1.1.7",
"@tabler/icons-react": "^3.31.0",
"@tailwindcss/postcss": "^4.0.1",
"@tailwindcss/postcss": "^4.1.11",
"@tanstack/react-table": "^8.9.1",
"@vercel/analytics": "^1.4.1",
"change-case": "^5.4.4",
@@ -65,10 +66,10 @@
"date-fns": "^4.1.0",
"embla-carousel-autoplay": "8.5.2",
"embla-carousel-react": "8.5.2",
"fumadocs-core": "^15.3.1",
"fumadocs-docgen": "^2.0.0",
"fumadocs-mdx": "^11.6.3",
"fumadocs-ui": "^15.3.1",
"fumadocs-core": "15.3.1",
"fumadocs-docgen": "2.0.0",
"fumadocs-mdx": "11.6.3",
"fumadocs-ui": "15.3.1",
"input-otp": "^1.4.2",
"jotai": "^2.1.0",
"little-date": "^1.0.0",
@@ -86,7 +87,7 @@
"recharts": "2.15.1",
"rehype-pretty-code": "^0.14.1",
"rimraf": "^6.0.1",
"shadcn": "2.6.2",
"shadcn": "3.3.0",
"shiki": "^1.10.1",
"sonner": "^2.0.0",
"tailwind-merge": "^3.0.1",
@@ -108,7 +109,7 @@
"eslint-config-next": "15.3.1",
"prettier": "^3.4.2",
"prettier-plugin-tailwindcss": "^0.6.11",
"tailwindcss": "^4.1.7",
"tailwindcss": "^4.1.11",
"tw-animate-css": "^1.2.4",
"typescript": "^5",
"unist-builder": "3.0.0",

View File

@@ -180,7 +180,7 @@
"name": "chart",
"type": "registry:ui",
"dependencies": [
"recharts",
"recharts@2.15.4",
"lucide-react"
],
"registryDependencies": [

View File

@@ -0,0 +1,36 @@
{
"@aceternity": "https://ui.aceternity.com/registry/{name}.json",
"@ai-elements": "https://registry.ai-sdk.dev/{name}.json",
"@alexcarpenter": "https://ui.alexcarpenter.me/r/{name}.json",
"@alpine": "https://alpine-registry.vercel.app/r/{name}.json",
"@animate-ui": "https://animate-ui.com/r/{name}.json",
"@blocks": "https://blocks.so/r/{name}.json",
"@clerk": "https://clerk.com/r/{name}.json",
"@cult-ui": "https://cult-ui.com/r/{name}.json",
"@kibo-ui": "https://www.kibo-ui.com/r/{name}.json",
"@kokonutui": "https://kokonutui.com/r/{name}.json",
"@magicui": "https://magicui.design/r/{name}.json",
"@motion-primitives": "https://motion-primitives.com/c/{name}.json",
"@originui": "https://originui.com/r/{name}.json",
"@prompt-kit": "https://prompt-kit.com/c/{name}.json",
"@tailark": "https://tailark.com/r/{name}.json",
"@react-bits": "https://reactbits.dev/r/{name}.json",
"@reui": "https://reui.io/r/{name}.json",
"@heseui": "https://www.heseui.com/r/{name}.json",
"@paceui-ui": "https://ui.paceui.com/r/{name}.json",
"@basecn": "https://basecn.dev/r/{name}.json",
"@ncdai": "https://chanhdai.com/r/{name}.json",
"@8bitcn": "https://8bitcn.com/r/{name}.json",
"@billingsdk": "https://billingsdk.com/r/{name}.json",
"@elements": "https://tryelements.dev/r/{name}.json",
"@nativeui": "https://nativeui.io/registry/{name}.json",
"@smoothui": "https://smoothui.dev/r/{name}.json",
"@formcn": "https://formcn.dev/r/{name}.json",
"@limeplay": "https://limeplay.winoffrg.dev/r/{name}.json",
"@skiper-ui": "https://skiper-ui.com/registry/{name}.json",
"@shadcn-editor": "https://shadcn-editor.vercel.app/r/{name}.json",
"@rigidui": "https://rigidui.com/r/{name}.json",
"@retroui": "https://retroui.dev/r/{name}.json",
"@wds": "https://wds-shadcn-registry.netlify.app/r/{name}.json",
"@97cn": "https://97cn.itzik.co/r/{name}.json"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,8 @@
{
"name": "default",
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "index",
"type": "registry:style",
"author": "shadcn (https://ui.shadcn.com)",
"dependencies": [
"tailwindcss-animate",
"class-variance-authority",
@@ -9,6 +11,7 @@
"registryDependencies": [
"utils"
],
"files": [],
"tailwind": {
"config": {
"plugins": [
@@ -16,6 +19,5 @@
]
}
},
"cssVars": {},
"files": []
"cssVars": {}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "style",
"type": "registry:style",
"author": "shadcn (https://ui.shadcn.com)",
"dependencies": [
"tailwindcss-animate",
"class-variance-authority",
"lucide-react"
],
"registryDependencies": [
"utils"
],
"files": [],
"tailwind": {
"config": {
"plugins": [
"require(\"tailwindcss-animate\")"
]
}
},
"cssVars": {}
}

View File

@@ -12,7 +12,7 @@
"files": [
{
"path": "registry/new-york-v4/blocks/calendar-24.tsx",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronDownIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport { Input } from \"@/registry/new-york-v4/ui/input\"\nimport { Label } from \"@/registry/new-york-v4/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/new-york-v4/ui/popover\"\n\nexport default function Calendar24() {\n const [open, setOpen] = React.useState(false)\n const [date, setDate] = React.useState<Date | undefined>(undefined)\n\n return (\n <div className=\"flex gap-4\">\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"date\" className=\"px-1\">\n Date\n </Label>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"date\"\n className=\"w-32 justify-between font-normal\"\n >\n {date ? date.toLocaleDateString() : \"Select date\"}\n <ChevronDownIcon />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto overflow-hidden p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={date}\n captionLayout=\"dropdown\"\n onSelect={(date) => {\n setDate(date)\n setOpen(false)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"time\" className=\"px-1\">\n Time\n </Label>\n <Input\n type=\"time\"\n id=\"time\"\n step=\"1\"\n defaultValue=\"10:30:00\"\n className=\"bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n </div>\n )\n}\n",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronDownIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/new-york-v4/ui/button\"\nimport { Calendar } from \"@/registry/new-york-v4/ui/calendar\"\nimport { Input } from \"@/registry/new-york-v4/ui/input\"\nimport { Label } from \"@/registry/new-york-v4/ui/label\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/new-york-v4/ui/popover\"\n\nexport default function Calendar24() {\n const [open, setOpen] = React.useState(false)\n const [date, setDate] = React.useState<Date | undefined>(undefined)\n\n return (\n <div className=\"flex gap-4\">\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"date-picker\" className=\"px-1\">\n Date\n </Label>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n id=\"date-picker\"\n className=\"w-32 justify-between font-normal\"\n >\n {date ? date.toLocaleDateString() : \"Select date\"}\n <ChevronDownIcon />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-auto overflow-hidden p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={date}\n captionLayout=\"dropdown\"\n onSelect={(date) => {\n setDate(date)\n setOpen(false)\n }}\n />\n </PopoverContent>\n </Popover>\n </div>\n <div className=\"flex flex-col gap-3\">\n <Label htmlFor=\"time-picker\" className=\"px-1\">\n Time\n </Label>\n <Input\n type=\"time\"\n id=\"time-picker\"\n step=\"1\"\n defaultValue=\"10:30:00\"\n className=\"bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none\"\n />\n </div>\n </div>\n )\n}\n",
"type": "registry:component"
}
],

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "style",
"type": "registry:style",
"dependencies": [
"class-variance-authority",
"lucide-react"
],
"devDependencies": [
"tw-animate-css"
],
"registryDependencies": [
"utils"
],
"files": [],
"cssVars": {}
}

View File

@@ -0,0 +1,74 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "theme-gray",
"type": "registry:theme",
"cssVars": {
"light": {
"background": "oklch(1 0 0)",
"foreground": "oklch(0.13 0.028 261.692)",
"card": "oklch(1 0 0)",
"card-foreground": "oklch(0.13 0.028 261.692)",
"popover": "oklch(1 0 0)",
"popover-foreground": "oklch(0.13 0.028 261.692)",
"primary": "oklch(0.21 0.034 264.665)",
"primary-foreground": "oklch(0.985 0.002 247.839)",
"secondary": "oklch(0.967 0.003 264.542)",
"secondary-foreground": "oklch(0.21 0.034 264.665)",
"muted": "oklch(0.967 0.003 264.542)",
"muted-foreground": "oklch(0.551 0.027 264.364)",
"accent": "oklch(0.967 0.003 264.542)",
"accent-foreground": "oklch(0.21 0.034 264.665)",
"destructive": "oklch(0.577 0.245 27.325)",
"border": "oklch(0.928 0.006 264.531)",
"input": "oklch(0.928 0.006 264.531)",
"ring": "oklch(0.707 0.022 261.325)",
"chart-1": "oklch(0.646 0.222 41.116)",
"chart-2": "oklch(0.6 0.118 184.704)",
"chart-3": "oklch(0.398 0.07 227.392)",
"chart-4": "oklch(0.828 0.189 84.429)",
"chart-5": "oklch(0.769 0.188 70.08)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0.002 247.839)",
"sidebar-foreground": "oklch(0.13 0.028 261.692)",
"sidebar-primary": "oklch(0.21 0.034 264.665)",
"sidebar-primary-foreground": "oklch(0.985 0.002 247.839)",
"sidebar-accent": "oklch(0.967 0.003 264.542)",
"sidebar-accent-foreground": "oklch(0.21 0.034 264.665)",
"sidebar-border": "oklch(0.928 0.006 264.531)",
"sidebar-ring": "oklch(0.707 0.022 261.325)"
},
"dark": {
"background": "oklch(0.13 0.028 261.692)",
"foreground": "oklch(0.985 0.002 247.839)",
"card": "oklch(0.21 0.034 264.665)",
"card-foreground": "oklch(0.985 0.002 247.839)",
"popover": "oklch(0.21 0.034 264.665)",
"popover-foreground": "oklch(0.985 0.002 247.839)",
"primary": "oklch(0.928 0.006 264.531)",
"primary-foreground": "oklch(0.21 0.034 264.665)",
"secondary": "oklch(0.278 0.033 256.848)",
"secondary-foreground": "oklch(0.985 0.002 247.839)",
"muted": "oklch(0.278 0.033 256.848)",
"muted-foreground": "oklch(0.707 0.022 261.325)",
"accent": "oklch(0.278 0.033 256.848)",
"accent-foreground": "oklch(0.985 0.002 247.839)",
"destructive": "oklch(0.704 0.191 22.216)",
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.551 0.027 264.364)",
"chart-1": "oklch(0.488 0.243 264.376)",
"chart-2": "oklch(0.696 0.17 162.48)",
"chart-3": "oklch(0.769 0.188 70.08)",
"chart-4": "oklch(0.627 0.265 303.9)",
"chart-5": "oklch(0.645 0.246 16.439)",
"sidebar": "oklch(0.21 0.034 264.665)",
"sidebar-foreground": "oklch(0.985 0.002 247.839)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
"sidebar-primary-foreground": "oklch(0.985 0.002 247.839)",
"sidebar-accent": "oklch(0.278 0.033 256.848)",
"sidebar-accent-foreground": "oklch(0.985 0.002 247.839)",
"sidebar-border": "oklch(1 0 0 / 10%)",
"sidebar-ring": "oklch(0.551 0.027 264.364)"
}
}
}

View File

@@ -0,0 +1,74 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "theme-neutral",
"type": "registry:theme",
"cssVars": {
"light": {
"background": "oklch(1 0 0)",
"foreground": "oklch(0.145 0 0)",
"card": "oklch(1 0 0)",
"card-foreground": "oklch(0.145 0 0)",
"popover": "oklch(1 0 0)",
"popover-foreground": "oklch(0.145 0 0)",
"primary": "oklch(0.205 0 0)",
"primary-foreground": "oklch(0.985 0 0)",
"secondary": "oklch(0.97 0 0)",
"secondary-foreground": "oklch(0.205 0 0)",
"muted": "oklch(0.97 0 0)",
"muted-foreground": "oklch(0.556 0 0)",
"accent": "oklch(0.97 0 0)",
"accent-foreground": "oklch(0.205 0 0)",
"destructive": "oklch(0.577 0.245 27.325)",
"border": "oklch(0.922 0 0)",
"input": "oklch(0.922 0 0)",
"ring": "oklch(0.708 0 0)",
"chart-1": "oklch(0.646 0.222 41.116)",
"chart-2": "oklch(0.6 0.118 184.704)",
"chart-3": "oklch(0.398 0.07 227.392)",
"chart-4": "oklch(0.828 0.189 84.429)",
"chart-5": "oklch(0.769 0.188 70.08)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0 0)",
"sidebar-foreground": "oklch(0.145 0 0)",
"sidebar-primary": "oklch(0.205 0 0)",
"sidebar-primary-foreground": "oklch(0.985 0 0)",
"sidebar-accent": "oklch(0.97 0 0)",
"sidebar-accent-foreground": "oklch(0.205 0 0)",
"sidebar-border": "oklch(0.922 0 0)",
"sidebar-ring": "oklch(0.708 0 0)"
},
"dark": {
"background": "oklch(0.145 0 0)",
"foreground": "oklch(0.985 0 0)",
"card": "oklch(0.205 0 0)",
"card-foreground": "oklch(0.985 0 0)",
"popover": "oklch(0.205 0 0)",
"popover-foreground": "oklch(0.985 0 0)",
"primary": "oklch(0.922 0 0)",
"primary-foreground": "oklch(0.205 0 0)",
"secondary": "oklch(0.269 0 0)",
"secondary-foreground": "oklch(0.985 0 0)",
"muted": "oklch(0.269 0 0)",
"muted-foreground": "oklch(0.708 0 0)",
"accent": "oklch(0.269 0 0)",
"accent-foreground": "oklch(0.985 0 0)",
"destructive": "oklch(0.704 0.191 22.216)",
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.556 0 0)",
"chart-1": "oklch(0.488 0.243 264.376)",
"chart-2": "oklch(0.696 0.17 162.48)",
"chart-3": "oklch(0.769 0.188 70.08)",
"chart-4": "oklch(0.627 0.265 303.9)",
"chart-5": "oklch(0.645 0.246 16.439)",
"sidebar": "oklch(0.205 0 0)",
"sidebar-foreground": "oklch(0.985 0 0)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
"sidebar-primary-foreground": "oklch(0.985 0 0)",
"sidebar-accent": "oklch(0.269 0 0)",
"sidebar-accent-foreground": "oklch(0.985 0 0)",
"sidebar-border": "oklch(1 0 0 / 10%)",
"sidebar-ring": "oklch(0.556 0 0)"
}
}
}

View File

@@ -0,0 +1,74 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "theme-slate",
"type": "registry:theme",
"cssVars": {
"light": {
"background": "oklch(1 0 0)",
"foreground": "oklch(0.129 0.042 264.695)",
"card": "oklch(1 0 0)",
"card-foreground": "oklch(0.129 0.042 264.695)",
"popover": "oklch(1 0 0)",
"popover-foreground": "oklch(0.129 0.042 264.695)",
"primary": "oklch(0.208 0.042 265.755)",
"primary-foreground": "oklch(0.984 0.003 247.858)",
"secondary": "oklch(0.968 0.007 247.896)",
"secondary-foreground": "oklch(0.208 0.042 265.755)",
"muted": "oklch(0.968 0.007 247.896)",
"muted-foreground": "oklch(0.554 0.046 257.417)",
"accent": "oklch(0.968 0.007 247.896)",
"accent-foreground": "oklch(0.208 0.042 265.755)",
"destructive": "oklch(0.577 0.245 27.325)",
"border": "oklch(0.929 0.013 255.508)",
"input": "oklch(0.929 0.013 255.508)",
"ring": "oklch(0.704 0.04 256.788)",
"chart-1": "oklch(0.646 0.222 41.116)",
"chart-2": "oklch(0.6 0.118 184.704)",
"chart-3": "oklch(0.398 0.07 227.392)",
"chart-4": "oklch(0.828 0.189 84.429)",
"chart-5": "oklch(0.769 0.188 70.08)",
"radius": "0.625rem",
"sidebar": "oklch(0.984 0.003 247.858)",
"sidebar-foreground": "oklch(0.129 0.042 264.695)",
"sidebar-primary": "oklch(0.208 0.042 265.755)",
"sidebar-primary-foreground": "oklch(0.984 0.003 247.858)",
"sidebar-accent": "oklch(0.968 0.007 247.896)",
"sidebar-accent-foreground": "oklch(0.208 0.042 265.755)",
"sidebar-border": "oklch(0.929 0.013 255.508)",
"sidebar-ring": "oklch(0.704 0.04 256.788)"
},
"dark": {
"background": "oklch(0.129 0.042 264.695)",
"foreground": "oklch(0.984 0.003 247.858)",
"card": "oklch(0.208 0.042 265.755)",
"card-foreground": "oklch(0.984 0.003 247.858)",
"popover": "oklch(0.208 0.042 265.755)",
"popover-foreground": "oklch(0.984 0.003 247.858)",
"primary": "oklch(0.929 0.013 255.508)",
"primary-foreground": "oklch(0.208 0.042 265.755)",
"secondary": "oklch(0.279 0.041 260.031)",
"secondary-foreground": "oklch(0.984 0.003 247.858)",
"muted": "oklch(0.279 0.041 260.031)",
"muted-foreground": "oklch(0.704 0.04 256.788)",
"accent": "oklch(0.279 0.041 260.031)",
"accent-foreground": "oklch(0.984 0.003 247.858)",
"destructive": "oklch(0.704 0.191 22.216)",
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.551 0.027 264.364)",
"chart-1": "oklch(0.488 0.243 264.376)",
"chart-2": "oklch(0.696 0.17 162.48)",
"chart-3": "oklch(0.769 0.188 70.08)",
"chart-4": "oklch(0.627 0.265 303.9)",
"chart-5": "oklch(0.645 0.246 16.439)",
"sidebar": "oklch(0.208 0.042 265.755)",
"sidebar-foreground": "oklch(0.984 0.003 247.858)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
"sidebar-primary-foreground": "oklch(0.984 0.003 247.858)",
"sidebar-accent": "oklch(0.279 0.041 260.031)",
"sidebar-accent-foreground": "oklch(0.984 0.003 247.858)",
"sidebar-border": "oklch(1 0 0 / 10%)",
"sidebar-ring": "oklch(0.551 0.027 264.364)"
}
}
}

View File

@@ -0,0 +1,74 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "theme-stone",
"type": "registry:theme",
"cssVars": {
"light": {
"background": "oklch(1 0 0)",
"foreground": "oklch(0.147 0.004 49.25)",
"card": "oklch(1 0 0)",
"card-foreground": "oklch(0.147 0.004 49.25)",
"popover": "oklch(1 0 0)",
"popover-foreground": "oklch(0.147 0.004 49.25)",
"primary": "oklch(0.216 0.006 56.043)",
"primary-foreground": "oklch(0.985 0.001 106.423)",
"secondary": "oklch(0.97 0.001 106.424)",
"secondary-foreground": "oklch(0.216 0.006 56.043)",
"muted": "oklch(0.97 0.001 106.424)",
"muted-foreground": "oklch(0.553 0.013 58.071)",
"accent": "oklch(0.97 0.001 106.424)",
"accent-foreground": "oklch(0.216 0.006 56.043)",
"destructive": "oklch(0.577 0.245 27.325)",
"border": "oklch(0.923 0.003 48.717)",
"input": "oklch(0.923 0.003 48.717)",
"ring": "oklch(0.709 0.01 56.259)",
"chart-1": "oklch(0.646 0.222 41.116)",
"chart-2": "oklch(0.6 0.118 184.704)",
"chart-3": "oklch(0.398 0.07 227.392)",
"chart-4": "oklch(0.828 0.189 84.429)",
"chart-5": "oklch(0.769 0.188 70.08)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0.001 106.423)",
"sidebar-foreground": "oklch(0.147 0.004 49.25)",
"sidebar-primary": "oklch(0.216 0.006 56.043)",
"sidebar-primary-foreground": "oklch(0.985 0.001 106.423)",
"sidebar-accent": "oklch(0.97 0.001 106.424)",
"sidebar-accent-foreground": "oklch(0.216 0.006 56.043)",
"sidebar-border": "oklch(0.923 0.003 48.717)",
"sidebar-ring": "oklch(0.709 0.01 56.259)"
},
"dark": {
"background": "oklch(0.147 0.004 49.25)",
"foreground": "oklch(0.985 0.001 106.423)",
"card": "oklch(0.216 0.006 56.043)",
"card-foreground": "oklch(0.985 0.001 106.423)",
"popover": "oklch(0.216 0.006 56.043)",
"popover-foreground": "oklch(0.985 0.001 106.423)",
"primary": "oklch(0.923 0.003 48.717)",
"primary-foreground": "oklch(0.216 0.006 56.043)",
"secondary": "oklch(0.268 0.007 34.298)",
"secondary-foreground": "oklch(0.985 0.001 106.423)",
"muted": "oklch(0.268 0.007 34.298)",
"muted-foreground": "oklch(0.709 0.01 56.259)",
"accent": "oklch(0.268 0.007 34.298)",
"accent-foreground": "oklch(0.985 0.001 106.423)",
"destructive": "oklch(0.704 0.191 22.216)",
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.553 0.013 58.071)",
"chart-1": "oklch(0.488 0.243 264.376)",
"chart-2": "oklch(0.696 0.17 162.48)",
"chart-3": "oklch(0.769 0.188 70.08)",
"chart-4": "oklch(0.627 0.265 303.9)",
"chart-5": "oklch(0.645 0.246 16.439)",
"sidebar": "oklch(0.216 0.006 56.043)",
"sidebar-foreground": "oklch(0.985 0.001 106.423)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
"sidebar-primary-foreground": "oklch(0.985 0.001 106.423)",
"sidebar-accent": "oklch(0.268 0.007 34.298)",
"sidebar-accent-foreground": "oklch(0.985 0.001 106.423)",
"sidebar-border": "oklch(1 0 0 / 10%)",
"sidebar-ring": "oklch(0.553 0.013 58.071)"
}
}
}

View File

@@ -0,0 +1,74 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "theme-zinc",
"type": "registry:theme",
"cssVars": {
"light": {
"background": "oklch(1 0 0)",
"foreground": "oklch(0.141 0.005 285.823)",
"card": "oklch(1 0 0)",
"card-foreground": "oklch(0.141 0.005 285.823)",
"popover": "oklch(1 0 0)",
"popover-foreground": "oklch(0.141 0.005 285.823)",
"primary": "oklch(0.21 0.006 285.885)",
"primary-foreground": "oklch(0.985 0 0)",
"secondary": "oklch(0.967 0.001 286.375)",
"secondary-foreground": "oklch(0.21 0.006 285.885)",
"muted": "oklch(0.967 0.001 286.375)",
"muted-foreground": "oklch(0.552 0.016 285.938)",
"accent": "oklch(0.967 0.001 286.375)",
"accent-foreground": "oklch(0.21 0.006 285.885)",
"destructive": "oklch(0.577 0.245 27.325)",
"border": "oklch(0.92 0.004 286.32)",
"input": "oklch(0.92 0.004 286.32)",
"ring": "oklch(0.705 0.015 286.067)",
"chart-1": "oklch(0.646 0.222 41.116)",
"chart-2": "oklch(0.6 0.118 184.704)",
"chart-3": "oklch(0.398 0.07 227.392)",
"chart-4": "oklch(0.828 0.189 84.429)",
"chart-5": "oklch(0.769 0.188 70.08)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0 0)",
"sidebar-foreground": "oklch(0.141 0.005 285.823)",
"sidebar-primary": "oklch(0.21 0.006 285.885)",
"sidebar-primary-foreground": "oklch(0.985 0 0)",
"sidebar-accent": "oklch(0.967 0.001 286.375)",
"sidebar-accent-foreground": "oklch(0.21 0.006 285.885)",
"sidebar-border": "oklch(0.92 0.004 286.32)",
"sidebar-ring": "oklch(0.705 0.015 286.067)"
},
"dark": {
"background": "oklch(0.141 0.005 285.823)",
"foreground": "oklch(0.985 0 0)",
"card": "oklch(0.21 0.006 285.885)",
"card-foreground": "oklch(0.985 0 0)",
"popover": "oklch(0.21 0.006 285.885)",
"popover-foreground": "oklch(0.985 0 0)",
"primary": "oklch(0.92 0.004 286.32)",
"primary-foreground": "oklch(0.21 0.006 285.885)",
"secondary": "oklch(0.274 0.006 286.033)",
"secondary-foreground": "oklch(0.985 0 0)",
"muted": "oklch(0.274 0.006 286.033)",
"muted-foreground": "oklch(0.705 0.015 286.067)",
"accent": "oklch(0.274 0.006 286.033)",
"accent-foreground": "oklch(0.985 0 0)",
"destructive": "oklch(0.704 0.191 22.216)",
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.552 0.016 285.938)",
"chart-1": "oklch(0.488 0.243 264.376)",
"chart-2": "oklch(0.696 0.17 162.48)",
"chart-3": "oklch(0.769 0.188 70.08)",
"chart-4": "oklch(0.627 0.265 303.9)",
"chart-5": "oklch(0.645 0.246 16.439)",
"sidebar": "oklch(0.21 0.006 285.885)",
"sidebar-foreground": "oklch(0.985 0 0)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
"sidebar-primary-foreground": "oklch(0.985 0 0)",
"sidebar-accent": "oklch(0.274 0.006 286.033)",
"sidebar-accent-foreground": "oklch(0.985 0 0)",
"sidebar-border": "oklch(1 0 0 / 10%)",
"sidebar-ring": "oklch(0.552 0.016 285.938)"
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,8 @@
{
"name": "new-york",
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "index",
"type": "registry:style",
"author": "shadcn (https://ui.shadcn.com)",
"dependencies": [
"tailwindcss-animate",
"class-variance-authority",
@@ -9,6 +11,7 @@
"registryDependencies": [
"utils"
],
"files": [],
"tailwind": {
"config": {
"plugins": [
@@ -16,6 +19,5 @@
]
}
},
"cssVars": {},
"files": []
"cssVars": {}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "style",
"type": "registry:style",
"author": "shadcn (https://ui.shadcn.com)",
"dependencies": [
"tailwindcss-animate",
"class-variance-authority",
"lucide-react"
],
"registryDependencies": [
"utils"
],
"files": [],
"tailwind": {
"config": {
"plugins": [
"require(\"tailwindcss-animate\")"
]
}
},
"cssVars": {}
}

View File

@@ -56,6 +56,42 @@
}
},
"required": ["utils", "components"]
},
"registries": {
"type": "object",
"patternProperties": {
"^@": {
"oneOf": [
{
"type": "string",
"pattern": "\\{name\\}"
},
{
"type": "object",
"properties": {
"url": {
"type": "string",
"pattern": "\\{name\\}"
},
"params": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"headers": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"required": ["url"]
}
]
}
},
"additionalProperties": false
}
},
"required": ["style", "tailwind", "rsc", "aliases"]

View File

@@ -17,7 +17,8 @@
"registry:theme",
"registry:page",
"registry:file",
"registry:style"
"registry:style",
"registry:item"
],
"description": "The type of the item. This is used to determine the type and target path of the item when resolved for a project."
},
@@ -79,7 +80,8 @@
"registry:theme",
"registry:page",
"registry:file",
"registry:style"
"registry:style",
"registry:item"
],
"description": "The type of the file. This is used to determine the type of the file when resolved for a project."
},
@@ -161,32 +163,14 @@
"type": "object",
"description": "CSS definitions to be added to the project's CSS file. Supports at-rules, selectors, nested rules, utilities, layers, and more.",
"additionalProperties": {
"oneOf": [
{
"type": "string",
"description": "Direct CSS string (e.g., 'font-family: sans-serif; line-height: 1.5;')"
},
{
"type": "object",
"description": "CSS properties or nested selectors",
"additionalProperties": {
"oneOf": [
{
"type": "string",
"description": "CSS property value (e.g., 'blue', 'var(--color-primary)')"
},
{
"type": "object",
"description": "Nested selector or rule with properties",
"additionalProperties": {
"type": "string",
"description": "CSS property value for nested rule"
}
}
]
}
}
]
"$ref": "#/definitions/cssValue"
}
},
"envVars": {
"type": "object",
"description": "Environment variables required by the registry item. Key-value pairs that will be added to the project's .env file.",
"additionalProperties": {
"type": "string"
}
},
"meta": {
@@ -210,5 +194,22 @@
"description": "The name of the registry item to extend. This is used to extend the base shadcn/ui style. Set to none to start fresh. This is available for registry:style items only."
}
},
"required": ["name", "type"]
"required": ["name", "type"],
"definitions": {
"cssValue": {
"oneOf": [
{
"type": "string",
"description": "CSS property value or direct CSS string"
},
{
"type": "object",
"description": "Nested CSS properties, selectors, or at-rules. Empty objects are allowed for at-rules with no body.",
"additionalProperties": {
"$ref": "#/definitions/cssValue"
}
}
]
}
}
}

View File

@@ -18,6 +18,22 @@
"files": [],
"cssVars": {}
},
{
"name": "style",
"type": "registry:style",
"dependencies": [
"class-variance-authority",
"lucide-react"
],
"devDependencies": [
"tw-animate-css"
],
"registryDependencies": [
"utils"
],
"files": [],
"cssVars": {}
},
{
"name": "accordion",
"type": "registry:ui",
@@ -169,7 +185,7 @@
"name": "chart",
"type": "registry:ui",
"dependencies": [
"recharts",
"recharts@2.15.4",
"lucide-react"
],
"registryDependencies": [
@@ -3577,176 +3593,367 @@
]
},
{
"name": "theme-daylight",
"name": "theme-stone",
"type": "registry:theme",
"cssVars": {
"light": {
"background": "36 39% 88%",
"foreground": "36 45% 15%",
"primary": "36 45% 70%",
"primary-foreground": "36 45% 11%",
"secondary": "40 35% 77%",
"secondary-foreground": "36 45% 25%",
"accent": "36 64% 57%",
"accent-foreground": "36 72% 17%",
"destructive": "0 84% 37%",
"destructive-foreground": "0 0% 98%",
"muted": "36 33% 75%",
"muted-foreground": "36 45% 25%",
"card": "36 46% 82%",
"card-foreground": "36 45% 20%",
"popover": "0 0% 100%",
"popover-foreground": "240 10% 3.9%",
"border": "36 45% 60%",
"input": "36 45% 60%",
"ring": "36 45% 30%",
"chart-1": "25 34% 28%",
"chart-2": "26 36% 34%",
"chart-3": "28 40% 40%",
"chart-4": "31 41% 48%",
"chart-5": "35 43% 53%"
"background": "oklch(1 0 0)",
"foreground": "oklch(0.147 0.004 49.25)",
"card": "oklch(1 0 0)",
"card-foreground": "oklch(0.147 0.004 49.25)",
"popover": "oklch(1 0 0)",
"popover-foreground": "oklch(0.147 0.004 49.25)",
"primary": "oklch(0.216 0.006 56.043)",
"primary-foreground": "oklch(0.985 0.001 106.423)",
"secondary": "oklch(0.97 0.001 106.424)",
"secondary-foreground": "oklch(0.216 0.006 56.043)",
"muted": "oklch(0.97 0.001 106.424)",
"muted-foreground": "oklch(0.553 0.013 58.071)",
"accent": "oklch(0.97 0.001 106.424)",
"accent-foreground": "oklch(0.216 0.006 56.043)",
"destructive": "oklch(0.577 0.245 27.325)",
"border": "oklch(0.923 0.003 48.717)",
"input": "oklch(0.923 0.003 48.717)",
"ring": "oklch(0.709 0.01 56.259)",
"chart-1": "oklch(0.646 0.222 41.116)",
"chart-2": "oklch(0.6 0.118 184.704)",
"chart-3": "oklch(0.398 0.07 227.392)",
"chart-4": "oklch(0.828 0.189 84.429)",
"chart-5": "oklch(0.769 0.188 70.08)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0.001 106.423)",
"sidebar-foreground": "oklch(0.147 0.004 49.25)",
"sidebar-primary": "oklch(0.216 0.006 56.043)",
"sidebar-primary-foreground": "oklch(0.985 0.001 106.423)",
"sidebar-accent": "oklch(0.97 0.001 106.424)",
"sidebar-accent-foreground": "oklch(0.216 0.006 56.043)",
"sidebar-border": "oklch(0.923 0.003 48.717)",
"sidebar-ring": "oklch(0.709 0.01 56.259)"
},
"dark": {
"background": "36 39% 88%",
"foreground": "36 45% 15%",
"primary": "36 45% 70%",
"primary-foreground": "36 45% 11%",
"secondary": "40 35% 77%",
"secondary-foreground": "36 45% 25%",
"accent": "36 64% 57%",
"accent-foreground": "36 72% 17%",
"destructive": "0 84% 37%",
"destructive-foreground": "0 0% 98%",
"muted": "36 33% 75%",
"muted-foreground": "36 45% 25%",
"card": "36 46% 82%",
"card-foreground": "36 45% 20%",
"popover": "0 0% 100%",
"popover-foreground": "240 10% 3.9%",
"border": "36 45% 60%",
"input": "36 45% 60%",
"ring": "36 45% 30%",
"chart-1": "25 34% 28%",
"chart-2": "26 36% 34%",
"chart-3": "28 40% 40%",
"chart-4": "31 41% 48%",
"chart-5": "35 43% 53%"
"background": "oklch(0.147 0.004 49.25)",
"foreground": "oklch(0.985 0.001 106.423)",
"card": "oklch(0.216 0.006 56.043)",
"card-foreground": "oklch(0.985 0.001 106.423)",
"popover": "oklch(0.216 0.006 56.043)",
"popover-foreground": "oklch(0.985 0.001 106.423)",
"primary": "oklch(0.923 0.003 48.717)",
"primary-foreground": "oklch(0.216 0.006 56.043)",
"secondary": "oklch(0.268 0.007 34.298)",
"secondary-foreground": "oklch(0.985 0.001 106.423)",
"muted": "oklch(0.268 0.007 34.298)",
"muted-foreground": "oklch(0.709 0.01 56.259)",
"accent": "oklch(0.268 0.007 34.298)",
"accent-foreground": "oklch(0.985 0.001 106.423)",
"destructive": "oklch(0.704 0.191 22.216)",
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.553 0.013 58.071)",
"chart-1": "oklch(0.488 0.243 264.376)",
"chart-2": "oklch(0.696 0.17 162.48)",
"chart-3": "oklch(0.769 0.188 70.08)",
"chart-4": "oklch(0.627 0.265 303.9)",
"chart-5": "oklch(0.645 0.246 16.439)",
"sidebar": "oklch(0.216 0.006 56.043)",
"sidebar-foreground": "oklch(0.985 0.001 106.423)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
"sidebar-primary-foreground": "oklch(0.985 0.001 106.423)",
"sidebar-accent": "oklch(0.268 0.007 34.298)",
"sidebar-accent-foreground": "oklch(0.985 0.001 106.423)",
"sidebar-border": "oklch(1 0 0 / 10%)",
"sidebar-ring": "oklch(0.553 0.013 58.071)"
}
}
},
{
"name": "theme-midnight",
"name": "theme-zinc",
"type": "registry:theme",
"cssVars": {
"light": {
"background": "240 5% 6%",
"foreground": "60 5% 90%",
"primary": "240 0% 90%",
"primary-foreground": "60 0% 0%",
"secondary": "240 4% 15%",
"secondary-foreground": "60 5% 85%",
"accent": "240 0% 13%",
"accent-foreground": "60 0% 100%",
"destructive": "0 60% 50%",
"destructive-foreground": "0 0% 98%",
"muted": "240 5% 25%",
"muted-foreground": "60 5% 85%",
"card": "240 4% 10%",
"card-foreground": "60 5% 90%",
"popover": "240 5% 15%",
"popover-foreground": "60 5% 85%",
"border": "240 6% 20%",
"input": "240 6% 20%",
"ring": "240 5% 90%",
"chart-1": "359 2% 90%",
"chart-2": "240 1% 74%",
"chart-3": "240 1% 58%",
"chart-4": "240 1% 42%",
"chart-5": "240 2% 26%"
"background": "oklch(1 0 0)",
"foreground": "oklch(0.141 0.005 285.823)",
"card": "oklch(1 0 0)",
"card-foreground": "oklch(0.141 0.005 285.823)",
"popover": "oklch(1 0 0)",
"popover-foreground": "oklch(0.141 0.005 285.823)",
"primary": "oklch(0.21 0.006 285.885)",
"primary-foreground": "oklch(0.985 0 0)",
"secondary": "oklch(0.967 0.001 286.375)",
"secondary-foreground": "oklch(0.21 0.006 285.885)",
"muted": "oklch(0.967 0.001 286.375)",
"muted-foreground": "oklch(0.552 0.016 285.938)",
"accent": "oklch(0.967 0.001 286.375)",
"accent-foreground": "oklch(0.21 0.006 285.885)",
"destructive": "oklch(0.577 0.245 27.325)",
"border": "oklch(0.92 0.004 286.32)",
"input": "oklch(0.92 0.004 286.32)",
"ring": "oklch(0.705 0.015 286.067)",
"chart-1": "oklch(0.646 0.222 41.116)",
"chart-2": "oklch(0.6 0.118 184.704)",
"chart-3": "oklch(0.398 0.07 227.392)",
"chart-4": "oklch(0.828 0.189 84.429)",
"chart-5": "oklch(0.769 0.188 70.08)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0 0)",
"sidebar-foreground": "oklch(0.141 0.005 285.823)",
"sidebar-primary": "oklch(0.21 0.006 285.885)",
"sidebar-primary-foreground": "oklch(0.985 0 0)",
"sidebar-accent": "oklch(0.967 0.001 286.375)",
"sidebar-accent-foreground": "oklch(0.21 0.006 285.885)",
"sidebar-border": "oklch(0.92 0.004 286.32)",
"sidebar-ring": "oklch(0.705 0.015 286.067)"
},
"dark": {
"background": "240 5% 6%",
"foreground": "60 5% 90%",
"primary": "240 0% 90%",
"primary-foreground": "60 0% 0%",
"secondary": "240 4% 15%",
"secondary-foreground": "60 5% 85%",
"accent": "240 0% 13%",
"accent-foreground": "60 0% 100%",
"destructive": "0 60% 50%",
"destructive-foreground": "0 0% 98%",
"muted": "240 5% 25%",
"muted-foreground": "60 5% 85%",
"card": "240 4% 10%",
"card-foreground": "60 5% 90%",
"popover": "240 5% 15%",
"popover-foreground": "60 5% 85%",
"border": "240 6% 20%",
"input": "240 6% 20%",
"ring": "240 5% 90%",
"chart-1": "359 2% 90%",
"chart-2": "240 1% 74%",
"chart-3": "240 1% 58%",
"chart-4": "240 1% 42%",
"chart-5": "240 2% 26%"
"background": "oklch(0.141 0.005 285.823)",
"foreground": "oklch(0.985 0 0)",
"card": "oklch(0.21 0.006 285.885)",
"card-foreground": "oklch(0.985 0 0)",
"popover": "oklch(0.21 0.006 285.885)",
"popover-foreground": "oklch(0.985 0 0)",
"primary": "oklch(0.92 0.004 286.32)",
"primary-foreground": "oklch(0.21 0.006 285.885)",
"secondary": "oklch(0.274 0.006 286.033)",
"secondary-foreground": "oklch(0.985 0 0)",
"muted": "oklch(0.274 0.006 286.033)",
"muted-foreground": "oklch(0.705 0.015 286.067)",
"accent": "oklch(0.274 0.006 286.033)",
"accent-foreground": "oklch(0.985 0 0)",
"destructive": "oklch(0.704 0.191 22.216)",
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.552 0.016 285.938)",
"chart-1": "oklch(0.488 0.243 264.376)",
"chart-2": "oklch(0.696 0.17 162.48)",
"chart-3": "oklch(0.769 0.188 70.08)",
"chart-4": "oklch(0.627 0.265 303.9)",
"chart-5": "oklch(0.645 0.246 16.439)",
"sidebar": "oklch(0.21 0.006 285.885)",
"sidebar-foreground": "oklch(0.985 0 0)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
"sidebar-primary-foreground": "oklch(0.985 0 0)",
"sidebar-accent": "oklch(0.274 0.006 286.033)",
"sidebar-accent-foreground": "oklch(0.985 0 0)",
"sidebar-border": "oklch(1 0 0 / 10%)",
"sidebar-ring": "oklch(0.552 0.016 285.938)"
}
}
},
{
"name": "theme-emerald",
"name": "theme-neutral",
"type": "registry:theme",
"cssVars": {
"light": {
"background": "0 0% 100%",
"foreground": "240 10% 3.9%",
"card": "0 0% 100%",
"card-foreground": "240 10% 3.9%",
"popover": "0 0% 100%",
"popover-foreground": "240 10% 3.9%",
"primary": "142 86% 28%",
"primary-foreground": "356 29% 98%",
"secondary": "240 4.8% 95.9%",
"secondary-foreground": "240 5.9% 10%",
"muted": "240 4.8% 95.9%",
"muted-foreground": "240 3.8% 45%",
"accent": "240 4.8% 95.9%",
"accent-foreground": "240 5.9% 10%",
"destructive": "0 72% 51%",
"destructive-foreground": "0 0% 98%",
"border": "240 5.9% 90%",
"input": "240 5.9% 90%",
"ring": "142 86% 28%",
"chart-1": "139 65% 20%",
"chart-2": "140 74% 44%",
"chart-3": "142 88% 28%",
"chart-4": "137 55% 15%",
"chart-5": "141 40% 9%"
"background": "oklch(1 0 0)",
"foreground": "oklch(0.145 0 0)",
"card": "oklch(1 0 0)",
"card-foreground": "oklch(0.145 0 0)",
"popover": "oklch(1 0 0)",
"popover-foreground": "oklch(0.145 0 0)",
"primary": "oklch(0.205 0 0)",
"primary-foreground": "oklch(0.985 0 0)",
"secondary": "oklch(0.97 0 0)",
"secondary-foreground": "oklch(0.205 0 0)",
"muted": "oklch(0.97 0 0)",
"muted-foreground": "oklch(0.556 0 0)",
"accent": "oklch(0.97 0 0)",
"accent-foreground": "oklch(0.205 0 0)",
"destructive": "oklch(0.577 0.245 27.325)",
"border": "oklch(0.922 0 0)",
"input": "oklch(0.922 0 0)",
"ring": "oklch(0.708 0 0)",
"chart-1": "oklch(0.646 0.222 41.116)",
"chart-2": "oklch(0.6 0.118 184.704)",
"chart-3": "oklch(0.398 0.07 227.392)",
"chart-4": "oklch(0.828 0.189 84.429)",
"chart-5": "oklch(0.769 0.188 70.08)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0 0)",
"sidebar-foreground": "oklch(0.145 0 0)",
"sidebar-primary": "oklch(0.205 0 0)",
"sidebar-primary-foreground": "oklch(0.985 0 0)",
"sidebar-accent": "oklch(0.97 0 0)",
"sidebar-accent-foreground": "oklch(0.205 0 0)",
"sidebar-border": "oklch(0.922 0 0)",
"sidebar-ring": "oklch(0.708 0 0)"
},
"dark": {
"background": "240 10% 3.9%",
"foreground": "0 0% 98%",
"card": "240 10% 3.9%",
"card-foreground": "0 0% 98%",
"popover": "240 10% 3.9%",
"popover-foreground": "0 0% 98%",
"primary": "142 86% 28%",
"primary-foreground": "356 29% 98%",
"secondary": "240 4.8% 95.9%",
"secondary-foreground": "240 5.9% 10%",
"muted": "240 3.7% 15.9%",
"muted-foreground": "240 5% 64.9%",
"accent": "240 3.7% 15.9%",
"accent-foreground": "0 0% 98%",
"destructive": "0 72% 51%",
"destructive-foreground": "0 0% 98%",
"border": "240 3.7% 15.9%",
"input": "240 3.7% 15.9%",
"ring": "142 86% 28%",
"chart-1": "142 88% 28%",
"chart-2": "139 65% 20%",
"chart-3": "140 74% 24%",
"chart-4": "137 55% 15%",
"chart-5": "141 40% 9%"
"background": "oklch(0.145 0 0)",
"foreground": "oklch(0.985 0 0)",
"card": "oklch(0.205 0 0)",
"card-foreground": "oklch(0.985 0 0)",
"popover": "oklch(0.205 0 0)",
"popover-foreground": "oklch(0.985 0 0)",
"primary": "oklch(0.922 0 0)",
"primary-foreground": "oklch(0.205 0 0)",
"secondary": "oklch(0.269 0 0)",
"secondary-foreground": "oklch(0.985 0 0)",
"muted": "oklch(0.269 0 0)",
"muted-foreground": "oklch(0.708 0 0)",
"accent": "oklch(0.269 0 0)",
"accent-foreground": "oklch(0.985 0 0)",
"destructive": "oklch(0.704 0.191 22.216)",
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.556 0 0)",
"chart-1": "oklch(0.488 0.243 264.376)",
"chart-2": "oklch(0.696 0.17 162.48)",
"chart-3": "oklch(0.769 0.188 70.08)",
"chart-4": "oklch(0.627 0.265 303.9)",
"chart-5": "oklch(0.645 0.246 16.439)",
"sidebar": "oklch(0.205 0 0)",
"sidebar-foreground": "oklch(0.985 0 0)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
"sidebar-primary-foreground": "oklch(0.985 0 0)",
"sidebar-accent": "oklch(0.269 0 0)",
"sidebar-accent-foreground": "oklch(0.985 0 0)",
"sidebar-border": "oklch(1 0 0 / 10%)",
"sidebar-ring": "oklch(0.556 0 0)"
}
}
},
{
"name": "theme-gray",
"type": "registry:theme",
"cssVars": {
"light": {
"background": "oklch(1 0 0)",
"foreground": "oklch(0.13 0.028 261.692)",
"card": "oklch(1 0 0)",
"card-foreground": "oklch(0.13 0.028 261.692)",
"popover": "oklch(1 0 0)",
"popover-foreground": "oklch(0.13 0.028 261.692)",
"primary": "oklch(0.21 0.034 264.665)",
"primary-foreground": "oklch(0.985 0.002 247.839)",
"secondary": "oklch(0.967 0.003 264.542)",
"secondary-foreground": "oklch(0.21 0.034 264.665)",
"muted": "oklch(0.967 0.003 264.542)",
"muted-foreground": "oklch(0.551 0.027 264.364)",
"accent": "oklch(0.967 0.003 264.542)",
"accent-foreground": "oklch(0.21 0.034 264.665)",
"destructive": "oklch(0.577 0.245 27.325)",
"border": "oklch(0.928 0.006 264.531)",
"input": "oklch(0.928 0.006 264.531)",
"ring": "oklch(0.707 0.022 261.325)",
"chart-1": "oklch(0.646 0.222 41.116)",
"chart-2": "oklch(0.6 0.118 184.704)",
"chart-3": "oklch(0.398 0.07 227.392)",
"chart-4": "oklch(0.828 0.189 84.429)",
"chart-5": "oklch(0.769 0.188 70.08)",
"radius": "0.625rem",
"sidebar": "oklch(0.985 0.002 247.839)",
"sidebar-foreground": "oklch(0.13 0.028 261.692)",
"sidebar-primary": "oklch(0.21 0.034 264.665)",
"sidebar-primary-foreground": "oklch(0.985 0.002 247.839)",
"sidebar-accent": "oklch(0.967 0.003 264.542)",
"sidebar-accent-foreground": "oklch(0.21 0.034 264.665)",
"sidebar-border": "oklch(0.928 0.006 264.531)",
"sidebar-ring": "oklch(0.707 0.022 261.325)"
},
"dark": {
"background": "oklch(0.13 0.028 261.692)",
"foreground": "oklch(0.985 0.002 247.839)",
"card": "oklch(0.21 0.034 264.665)",
"card-foreground": "oklch(0.985 0.002 247.839)",
"popover": "oklch(0.21 0.034 264.665)",
"popover-foreground": "oklch(0.985 0.002 247.839)",
"primary": "oklch(0.928 0.006 264.531)",
"primary-foreground": "oklch(0.21 0.034 264.665)",
"secondary": "oklch(0.278 0.033 256.848)",
"secondary-foreground": "oklch(0.985 0.002 247.839)",
"muted": "oklch(0.278 0.033 256.848)",
"muted-foreground": "oklch(0.707 0.022 261.325)",
"accent": "oklch(0.278 0.033 256.848)",
"accent-foreground": "oklch(0.985 0.002 247.839)",
"destructive": "oklch(0.704 0.191 22.216)",
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.551 0.027 264.364)",
"chart-1": "oklch(0.488 0.243 264.376)",
"chart-2": "oklch(0.696 0.17 162.48)",
"chart-3": "oklch(0.769 0.188 70.08)",
"chart-4": "oklch(0.627 0.265 303.9)",
"chart-5": "oklch(0.645 0.246 16.439)",
"sidebar": "oklch(0.21 0.034 264.665)",
"sidebar-foreground": "oklch(0.985 0.002 247.839)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
"sidebar-primary-foreground": "oklch(0.985 0.002 247.839)",
"sidebar-accent": "oklch(0.278 0.033 256.848)",
"sidebar-accent-foreground": "oklch(0.985 0.002 247.839)",
"sidebar-border": "oklch(1 0 0 / 10%)",
"sidebar-ring": "oklch(0.551 0.027 264.364)"
}
}
},
{
"name": "theme-slate",
"type": "registry:theme",
"cssVars": {
"light": {
"background": "oklch(1 0 0)",
"foreground": "oklch(0.129 0.042 264.695)",
"card": "oklch(1 0 0)",
"card-foreground": "oklch(0.129 0.042 264.695)",
"popover": "oklch(1 0 0)",
"popover-foreground": "oklch(0.129 0.042 264.695)",
"primary": "oklch(0.208 0.042 265.755)",
"primary-foreground": "oklch(0.984 0.003 247.858)",
"secondary": "oklch(0.968 0.007 247.896)",
"secondary-foreground": "oklch(0.208 0.042 265.755)",
"muted": "oklch(0.968 0.007 247.896)",
"muted-foreground": "oklch(0.554 0.046 257.417)",
"accent": "oklch(0.968 0.007 247.896)",
"accent-foreground": "oklch(0.208 0.042 265.755)",
"destructive": "oklch(0.577 0.245 27.325)",
"border": "oklch(0.929 0.013 255.508)",
"input": "oklch(0.929 0.013 255.508)",
"ring": "oklch(0.704 0.04 256.788)",
"chart-1": "oklch(0.646 0.222 41.116)",
"chart-2": "oklch(0.6 0.118 184.704)",
"chart-3": "oklch(0.398 0.07 227.392)",
"chart-4": "oklch(0.828 0.189 84.429)",
"chart-5": "oklch(0.769 0.188 70.08)",
"radius": "0.625rem",
"sidebar": "oklch(0.984 0.003 247.858)",
"sidebar-foreground": "oklch(0.129 0.042 264.695)",
"sidebar-primary": "oklch(0.208 0.042 265.755)",
"sidebar-primary-foreground": "oklch(0.984 0.003 247.858)",
"sidebar-accent": "oklch(0.968 0.007 247.896)",
"sidebar-accent-foreground": "oklch(0.208 0.042 265.755)",
"sidebar-border": "oklch(0.929 0.013 255.508)",
"sidebar-ring": "oklch(0.704 0.04 256.788)"
},
"dark": {
"background": "oklch(0.129 0.042 264.695)",
"foreground": "oklch(0.984 0.003 247.858)",
"card": "oklch(0.208 0.042 265.755)",
"card-foreground": "oklch(0.984 0.003 247.858)",
"popover": "oklch(0.208 0.042 265.755)",
"popover-foreground": "oklch(0.984 0.003 247.858)",
"primary": "oklch(0.929 0.013 255.508)",
"primary-foreground": "oklch(0.208 0.042 265.755)",
"secondary": "oklch(0.279 0.041 260.031)",
"secondary-foreground": "oklch(0.984 0.003 247.858)",
"muted": "oklch(0.279 0.041 260.031)",
"muted-foreground": "oklch(0.704 0.04 256.788)",
"accent": "oklch(0.279 0.041 260.031)",
"accent-foreground": "oklch(0.984 0.003 247.858)",
"destructive": "oklch(0.704 0.191 22.216)",
"border": "oklch(1 0 0 / 10%)",
"input": "oklch(1 0 0 / 15%)",
"ring": "oklch(0.551 0.027 264.364)",
"chart-1": "oklch(0.488 0.243 264.376)",
"chart-2": "oklch(0.696 0.17 162.48)",
"chart-3": "oklch(0.769 0.188 70.08)",
"chart-4": "oklch(0.627 0.265 303.9)",
"chart-5": "oklch(0.645 0.246 16.439)",
"sidebar": "oklch(0.208 0.042 265.755)",
"sidebar-foreground": "oklch(0.984 0.003 247.858)",
"sidebar-primary": "oklch(0.488 0.243 264.376)",
"sidebar-primary-foreground": "oklch(0.984 0.003 247.858)",
"sidebar-accent": "oklch(0.279 0.041 260.031)",
"sidebar-accent-foreground": "oklch(0.984 0.003 247.858)",
"sidebar-border": "oklch(1 0 0 / 10%)",
"sidebar-ring": "oklch(0.551 0.027 264.364)"
}
}
},

View File

@@ -16,6 +16,16 @@ export const Index: Record<string, any> = {
categories: undefined,
meta: undefined,
},
"style": {
name: "style",
description: "",
type: "registry:style",
registryDependencies: ["utils"],
files: [],
component: null,
categories: undefined,
meta: undefined,
},
"accordion": {
name: "accordion",
description: "",

View File

@@ -1,4 +1,4 @@
import { registryItemSchema, type Registry } from "shadcn/registry"
import { registryItemSchema, type Registry } from "shadcn/schema"
import { z } from "zod"
import { blocks } from "@/registry/registry-blocks"
@@ -19,6 +19,16 @@ const DEPRECATED_ITEMS = [
"toast-with-title",
]
// Shared between index and style for backward compatibility.
const NEW_YORK_V4_STYLE = {
type: "registry:style",
dependencies: ["class-variance-authority", "lucide-react"],
devDependencies: ["tw-animate-css"],
registryDependencies: ["utils"],
cssVars: {},
files: [],
}
export const registry = {
name: "shadcn/ui",
homepage: "https://ui.shadcn.com",
@@ -26,12 +36,11 @@ export const registry = {
[
{
name: "index",
type: "registry:style",
dependencies: ["class-variance-authority", "lucide-react"],
devDependencies: ["tw-animate-css"],
registryDependencies: ["utils"],
cssVars: {},
files: [],
...NEW_YORK_V4_STYLE,
},
{
name: "style",
...NEW_YORK_V4_STYLE,
},
...ui,
...blocks,

View File

@@ -20,14 +20,14 @@ export default function Calendar24() {
return (
<div className="flex gap-4">
<div className="flex flex-col gap-3">
<Label htmlFor="date" className="px-1">
<Label htmlFor="date-picker" className="px-1">
Date
</Label>
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button
variant="outline"
id="date"
id="date-picker"
className="w-32 justify-between font-normal"
>
{date ? date.toLocaleDateString() : "Select date"}
@@ -48,12 +48,12 @@ export default function Calendar24() {
</Popover>
</div>
<div className="flex flex-col gap-3">
<Label htmlFor="time" className="px-1">
<Label htmlFor="time-picker" className="px-1">
Time
</Label>
<Input
type="time"
id="time"
id="time-picker"
step="1"
defaultValue="10:30:00"
className="bg-background appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none"

View File

@@ -257,7 +257,6 @@ export function ChartAreaInteractive() {
/>
<ChartTooltip
cursor={false}
defaultIndex={isMobile ? -1 : 10}
content={
<ChartTooltipContent
labelFormatter={(value) => {

View File

@@ -233,7 +233,7 @@ export default function DataTableDemo() {
</DropdownMenuContent>
</DropdownMenu>
</div>
<div className="rounded-md border">
<div className="overflow-hidden rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (

View File

@@ -73,7 +73,10 @@ function Calendar({
"relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md",
defaultClassNames.dropdown_root
),
dropdown: cn("absolute inset-0 opacity-0", defaultClassNames.dropdown),
dropdown: cn(
"absolute bg-popover inset-0 opacity-0",
defaultClassNames.dropdown
),
caption_label: cn(
"select-none font-medium",
captionLayout === "label"

View File

@@ -179,70 +179,72 @@ function ChartTooltipContent({
>
{!nestLabel ? tooltipLabel : null}
<div className="grid gap-1.5">
{payload.map((item, index) => {
const key = `${nameKey || item.name || item.dataKey || "value"}`
const itemConfig = getPayloadConfigFromPayload(config, item, key)
const indicatorColor = color || item.payload.fill || item.color
{payload
.filter((item) => item.type !== "none")
.map((item, index) => {
const key = `${nameKey || item.name || item.dataKey || "value"}`
const itemConfig = getPayloadConfigFromPayload(config, item, key)
const indicatorColor = color || item.payload.fill || item.color
return (
<div
key={item.dataKey}
className={cn(
"[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5",
indicator === "dot" && "items-center"
)}
>
{formatter && item?.value !== undefined && item.name ? (
formatter(item.value, item.name, item, index, item.payload)
) : (
<>
{itemConfig?.icon ? (
<itemConfig.icon />
) : (
!hideIndicator && (
<div
className={cn(
"shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)",
{
"h-2.5 w-2.5": indicator === "dot",
"w-1": indicator === "line",
"w-0 border-[1.5px] border-dashed bg-transparent":
indicator === "dashed",
"my-0.5": nestLabel && indicator === "dashed",
return (
<div
key={item.dataKey}
className={cn(
"[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5",
indicator === "dot" && "items-center"
)}
>
{formatter && item?.value !== undefined && item.name ? (
formatter(item.value, item.name, item, index, item.payload)
) : (
<>
{itemConfig?.icon ? (
<itemConfig.icon />
) : (
!hideIndicator && (
<div
className={cn(
"shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)",
{
"h-2.5 w-2.5": indicator === "dot",
"w-1": indicator === "line",
"w-0 border-[1.5px] border-dashed bg-transparent":
indicator === "dashed",
"my-0.5": nestLabel && indicator === "dashed",
}
)}
style={
{
"--color-bg": indicatorColor,
"--color-border": indicatorColor,
} as React.CSSProperties
}
)}
style={
{
"--color-bg": indicatorColor,
"--color-border": indicatorColor,
} as React.CSSProperties
}
/>
)
)}
<div
className={cn(
"flex flex-1 justify-between leading-none",
nestLabel ? "items-end" : "items-center"
/>
)
)}
>
<div className="grid gap-1.5">
{nestLabel ? tooltipLabel : null}
<span className="text-muted-foreground">
{itemConfig?.label || item.name}
</span>
<div
className={cn(
"flex flex-1 justify-between leading-none",
nestLabel ? "items-end" : "items-center"
)}
>
<div className="grid gap-1.5">
{nestLabel ? tooltipLabel : null}
<span className="text-muted-foreground">
{itemConfig?.label || item.name}
</span>
</div>
{item.value && (
<span className="text-foreground font-mono font-medium tabular-nums">
{item.value.toLocaleString()}
</span>
)}
</div>
{item.value && (
<span className="text-foreground font-mono font-medium tabular-nums">
{item.value.toLocaleString()}
</span>
)}
</div>
</>
)}
</div>
)
})}
</>
)}
</div>
)
})}
</div>
</div>
)
@@ -275,31 +277,33 @@ function ChartLegendContent({
className
)}
>
{payload.map((item) => {
const key = `${nameKey || item.dataKey || "value"}`
const itemConfig = getPayloadConfigFromPayload(config, item, key)
{payload
.filter((item) => item.type !== "none")
.map((item) => {
const key = `${nameKey || item.dataKey || "value"}`
const itemConfig = getPayloadConfigFromPayload(config, item, key)
return (
<div
key={item.value}
className={cn(
"[&>svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3"
)}
>
{itemConfig?.icon && !hideIcon ? (
<itemConfig.icon />
) : (
<div
className="h-2 w-2 shrink-0 rounded-[2px]"
style={{
backgroundColor: item.color,
}}
/>
)}
{itemConfig?.label}
</div>
)
})}
return (
<div
key={item.value}
className={cn(
"[&>svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3"
)}
>
{itemConfig?.icon && !hideIcon ? (
<itemConfig.icon />
) : (
<div
className="h-2 w-2 shrink-0 rounded-[2px]"
style={{
backgroundColor: item.color,
}}
/>
)}
{itemConfig?.label}
</div>
)
})}
</div>
)
}

View File

@@ -1,4 +1,4 @@
import { type Registry } from "shadcn/registry"
import { type Registry } from "shadcn/schema"
export const blocks: Registry["items"] = [
{

View File

@@ -1,4 +1,4 @@
import { type Registry } from "shadcn/registry"
import { type Registry } from "shadcn/schema"
export const charts: Registry["items"] = [
// Area Charts

View File

@@ -1,4 +1,4 @@
import { type Registry } from "shadcn/registry"
import { type Registry } from "shadcn/schema"
export const examples: Registry["items"] = [
{

View File

@@ -1,4 +1,4 @@
import { type Registry } from "shadcn/registry"
import { type Registry } from "shadcn/schema"
export const hooks: Registry["items"] = [
{

View File

@@ -1,4 +1,4 @@
import { type Registry } from "shadcn/registry"
import { type Registry } from "shadcn/schema"
export const internal: Registry["items"] = [
// Do not move this. They are intentionally here for registry capture.

Some files were not shown because too many files have changed in this diff Show More