Compare commits

..

767 Commits

Author SHA1 Message Date
shadcn
cbf7b3708a chore: minor refactor and error message 2026-01-06 13:23:13 +04:00
yeasin2002
9da12c13f9 fix(cli): #9160 updated CLI name validation 2025-12-20 17:36:15 +06:00
Devon Govett
ccafdaf7c6 Add React Aria registry (#9121) 2025-12-19 02:22:27 +04:00
github-actions[bot]
f0d147d581 chore(release): version packages (#9125)
* 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-12-17 22:07:42 +04:00
shadcn
df67e49aac chore: add create command to readme (#9126) 2025-12-17 22:02:28 +04:00
shadcn
c0de90e1a1 ci: update permissions 2025-12-17 21:57:07 +04:00
shadcn
0447708efa Merge branch 'main' of github.com:shadcn-ui/ui 2025-12-17 21:52:50 +04:00
shadcn
4a470fc617 ci: update release 2025-12-17 21:52:29 +04:00
Dominik K.
137b1c12b7 feat(ui): add support for phosphor icons (#9044)
* feat: add phosphor icons to base ui

* feat_ add phosphor to blocks

* feat: add phosphor to radix blocks

* feat: add phosphor to radix ui

* feat: add phosphor to radix example

* feat: add missing phosphor icons

* fix: rename broken icons

* chore: format files

* fix: add missing phosphor icons

* chore: build registry

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-12-17 21:36:46 +04:00
shadcn
73296e79c0 ci: switch to oidc 2025-12-17 21:31:02 +04:00
Hamed.dev
78e5fa2a39 fix(mira): combobox popup background in dark mode (#9039)
* fix(mira): combobox popup background in dark mode

* fix

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-12-17 21:10:40 +04:00
François Best
9cf47dd4a3 fix: preview iframe URL state sync (#9095)
* fix: preview iframe URL state sync

* fix: reset iframe on base change
2025-12-17 21:09:14 +04:00
shadcn
f53400f934 chore: add livekit to directory (#9109) 2025-12-16 19:47:47 +04:00
Brendan Dash
b3d6f872db fix: remove duplicate @ui-layouts entry from registries.json (#9106) 2025-12-16 19:44:40 +04:00
Zaid Mukaddam
2aa5e11f6f Add "Open in Scira" in Copy menu item (#8013)
* Add "Open in Scira" in Copy menu item

* Fix link
2025-12-16 19:43:37 +04:00
Luka Klacar
058ebc5acd Remove duplicate @einui entry from directory.json (#9091)
Removed entry for @einui from the directory.
2025-12-16 03:24:24 +04:00
shadcn
a60683dea5 fix 2025-12-15 15:49:35 +04:00
shadcn
1dc1b8dbfb chore: remove console 2025-12-15 15:49:02 +04:00
shadcn
c6273cca03 fix: hover bug for pickers (#9084)
* fix

* fix
2025-12-15 15:46:16 +04:00
Gravityy
b15d7e8221 feat : add animbits to trusted registries (#8910)
* Add @animbits registry URL to registries.json and directory.json

* Add @animbits registry URL to registries.json and directory.json

* fix

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-12-15 14:38:24 +04:00
shadcn
46e3c26a6e chore: registry build 2025-12-15 14:33:37 +04:00
Bundui.io
f36e25f703 feat(registry): Add BundUI Components to the registry index (#8473)
* feat(registry): Add BundUI Components to the registry index

* fix

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-12-15 14:19:50 +04:00
MUDAVATH KUMAR
55f5d1c7cc feat: add Ein UI to registry directory (#9068)
Add Ein UI registry entry with:
- Registry URL: https://ui.eindev.ir/r/{name}.json
- Homepage: https://ui.eindev.ir
- Description: Beautiful, responsive Shadcn components with frosted glass morphism
- Custom gradient logo with glass theme

Resolves: #9048

Co-authored-by: Clacky <develop@clacky.ai>
2025-12-15 13:44:50 +04:00
Tham Kei Lok
db19605996 feat: add @8starlabs-ui to directory.json and registries.json (#8976) 2025-12-15 13:44:24 +04:00
Agustín Mayol
40012adb14 feat: add @optics to directory.json and registries.json (#8971) 2025-12-15 13:44:10 +04:00
Ali Hussein
ad8104e473 feat: add @cardcn registry #8902 (#8919) 2025-12-15 13:43:52 +04:00
Gildas Garcia
5fb0c4d19a Add shadcn-admin-kit to the registry index (#9018)
This PR adds https://marmelab.com/shadcn-admin-kit to the trusted registries.
2025-12-15 13:43:01 +04:00
Bruno Pérez
31c86f9fd5 feat: add @manifest registry (#9010) (#9011) 2025-12-15 13:42:11 +04:00
Gxuri
aad175ff87 feat: add @skiper-ui to directory.json (#9007)
* feat: add @skiper-ui to directory.json

* fix: update URL format for @skiper-ui in directory.json
2025-12-15 13:41:48 +04:00
Muskri
081c91c461 feat: add new registry entry for @pureui with logo and description (#8911) 2025-12-15 13:40:01 +04:00
Dominik K.
7dbf3688fb fix: rename hugeicons dot icon (#9033)
Renames the hugeicons icon from MoreHorizontalIcon to the actual component name MoreHorizontalCircle01Icon
2025-12-15 13:35:56 +04:00
Manuel
99ad18b389 fix: remove duplicate 'text-left' class from SelectValue component (#9045)
* fix: remove duplicate 'text-left' class from SelectValue component

* fix: select for base

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-12-15 13:33:27 +04:00
Junaid Anjum
fabb886de9 minor typo in the recent changelog (#9024) 2025-12-15 13:29:04 +04:00
ateeb a.
4b561cf050 fix:select color-format component and color copy-to-clipboard (#9056)
* fix:Nuqs adapter scope, select color-format component and color copy-to-clipboard

* chore: remove changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-12-15 13:27:10 +04:00
Mert
0c2373f592 fix(lint): resolve @typescript-eslint/no-unused-vars warns in combobox and scroll-area (#9060) 2025-12-15 13:24:30 +04:00
François Best
ff42c27d41 refactor: nuqs APIs (#9055)
* ref: replace cache with loader + inferParserType

* ref: expose useDesignSystemSearchParams hook

* ref: use loader & exported hook to simplify iframe sync

* ref: remove unused code

* fix: params.size is non-nullable

* ref: move items shallow option to the parser level

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-12-15 13:19:32 +04:00
github-actions[bot]
075b6aef97 chore(release): version packages (#9057)
* chore(release): version packages

* chore(release): version packages

* fix

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-12-14 02:26:21 +04:00
Mert
f4e0f671de fix: add missing options to schema.json (#9051)
* Add new style options to schema.json

The schema at ui.shadcn.com/schema.json is missing newly introduced style variants used by ui.shadcn.com/create.

This causes JSON schema validation errors when generating configs with the new styles.

This updates the style enum to include all currently supported style combinations.

* Add missing menuColor and menuAccent options to schema.json
2025-12-14 02:18:41 +04:00
shadcn
d3156c09ae fix(shadcn): resolver for url (#9054) 2025-12-14 02:16:26 +04:00
KapishDima
46bf4a0f06 Fix Base UI pagination crash (#9027)
* fix(pagination): Added nativeButton=false for a PaginationLink

* feat(registry): run registry:build

---------

Co-authored-by: dev_wandry <dima.development@wandry.com.ua>
2025-12-13 00:40:15 +04:00
shadcn
b61b718727 fix: add use-mobile to registry 2025-12-13 00:20:24 +04:00
shadcn
ee9b6b36ec fix: typo 2025-12-12 21:47:37 +04:00
shadcn
33de348d41 fix 2025-12-12 21:43:50 +04:00
shadcn
edcc96fc73 fix 2025-12-12 21:13:29 +04:00
github-actions[bot]
ef90a97e72 chore(release): version packages (#9023)
* chore(release): version packages

* fix

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-12-12 21:04:25 +04:00
shadcn
86d9b00084 chore: update deps (#9022)
* feat: init

* fix

* fix

* fix

* feat

* feat

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* feat: implement icons

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* feat: update init command

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* feat: dialog

* feat

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* feat: add registry:base item type

* feat: rename frame to canva

* fix

* feat

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fi

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* feat: add all colors

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* feat: add outfit font

* fix

* fix

* fix

* fix

* fix

* chore: changeset

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix
2025-12-12 21:01:44 +04:00
shadcn
672f845322 Merge branch 'main' of github.com:shadcn-ui/ui
# Conflicts:
#	pnpm-lock.yaml
2025-12-12 17:40:57 +04:00
shadcn
d01074deed chore: update 2025-12-12 17:40:21 +04:00
dependabot[bot]
321ceaf1c4 chore(deps): bump next from 16.0.7 to 16.0.9 in /templates/monorepo-next (#9014)
Bumps [next](https://github.com/vercel/next.js) from 16.0.7 to 16.0.9.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v16.0.7...v16.0.9)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 16.0.9
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-12 17:39:03 +04:00
vercel[bot]
32a972f4ce Fix React Server Components CVE vulnerabilities (#9016)
Updated dependencies to fix Next.js and React CVE vulnerabilities.

The fix-react2shell-next tool automatically updated the following packages to their secure versions:
- next
- react-server-dom-webpack
- react-server-dom-parcel  
- react-server-dom-turbopack

All package.json files have been scanned and vulnerable versions have been patched to the correct fixed versions based on the official React advisory.

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
2025-12-12 08:37:44 +04:00
github-actions[bot]
d28e02be1b chore(release): version packages (#8998)
* chore(release): version packages

* chore(release): version packages

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-12-09 21:25:59 +04:00
shadcn
6699158a22 fix: handling of base style for add command (#8997)
* fix: handling of base style for add command

* chore: changeset

* fix: shadow config
2025-12-09 20:55:58 +04:00
Pasquale Vitiello
142cd8ef13 Prevent duplicate keyframes when adding components (#8993)
* fix: prevent duplicate keyframes when adding components

- Check for existing keyframes in @theme inline before adding
- Replace existing keyframes instead of creating duplicates
- Add test to verify keyframe replacement behavior

* chore: changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-12-09 13:01:34 +04:00
shadcn
bdedce2750 feat: add start-app (#8992) 2025-12-09 01:54:22 +04:00
shadcn
4cb283d68e fix 2025-12-09 00:43:17 +04:00
shadcn
480a6cdb37 fix: layout 2025-12-09 00:40:19 +04:00
shadcn
8ba883738e chore: update monorepo-next 2025-12-09 00:31:33 +04:00
shadcn
b022c24825 chore: remove pnpm lock file 2025-12-09 00:27:17 +04:00
shadcn
3587477865 feat: add vite-app template (#8989) 2025-12-08 23:03:13 +04:00
Tommy Lundy
05143a80e6 Add @doras-ui registry (#8966)
* Add @doras-ui registry URL to registries.json

* Add @doras-ui component block details to directory
2025-12-08 23:01:20 +04:00
Jarrod Watts
728d2003b7 Add new component registry entries for @abstract (#8962) 2025-12-08 23:00:58 +04:00
Jarrod Watts
12c9e6b0b5 Add @abstract registry URL to registries.json (#8536)
Added new registry entry for @abstract.

Co-authored-by: shadcn <m@shadcn.com>
2025-12-05 15:39:49 +04:00
I Plan Websites
56cd757c45 @ai-blocks registry (#8956)
* Add AI Blocks registry URL to registries.json

* Add AI components for web to directory.json
2025-12-05 15:37:53 +04:00
Ella
9eb784054f feat: add @lucide-animated to directory.json and registries.json (#8937) 2025-12-05 15:37:41 +04:00
Hin
824577692b feat: add tour to registries and directory (#8917)
Co-authored-by: shadcn <m@shadcn.com>
2025-12-05 15:37:21 +04:00
Antonio Brandao
6be68df08c Add @abui registry to directory and index (#8908) 2025-12-05 15:35:50 +04:00
Admin Mart
cc48808a0d feat: add my custom registry (#8879)
Co-authored-by: wrappixelTeam <wrappixelteam.2016@gmail.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-12-05 15:35:26 +04:00
Admin Mart
a56b3720d1 feat/added my custom registry (#8904)
Co-authored-by: wrappixelTeam <wrappixelteam.2016@gmail.com>
2025-12-05 15:34:33 +04:00
dependabot[bot]
334db11234 chore(deps): bump next from 16.0.0 to 16.0.7 (#8954)
Bumps [next](https://github.com/vercel/next.js) from 16.0.0 to 16.0.7.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v16.0.0...v16.0.7)

---
updated-dependencies:
- dependency-name: next
  dependency-version: 16.0.7
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-04 16:24:46 +04:00
Luis Llanes
8a5027a0cd feat: add @shadcraft to directory.json and registries.json (#8913) 2025-12-01 00:44:28 +04:00
github-actions[bot]
803206305d chore(release): version packages (#8665)
* chore(release): version packages

* chore(release): version packages

* chore: lock

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-11-27 21:16:23 +04:00
shadcn
d0fb73ac0e fix: do not install baseStyle when adding registry:theme (#8900) 2025-11-27 21:13:56 +04:00
shadcn
62218c1c0c feat: update color value detection for cssVars (#8901) 2025-11-27 21:12:31 +04:00
Aditya Mathur
dd1563d57d fix: update author links in documentation for Drawer and Sonner components (#8881) 2025-11-27 13:38:26 +04:00
Amartya Singh
0538384860 Add @nexus-elements registry URL to registries.json and directory.json (#8797)
* Add @nexus-elements registry URL to registries.json

* feat: updated directory.json with nexus-elements

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-11-25 11:08:47 +04:00
shadcn
d43b437abc fix 2025-11-25 10:59:48 +04:00
Burhanuddin S. Tinwala
8fbfacd243 docs: fix typo 'mcpServers' to 'servers' in mcp server setup documentation for vs code (#8864) 2025-11-24 12:51:06 +04:00
Neha Prasad
778cee31ee feat: add @ui-layouts registry to directory (#8878) 2025-11-24 12:49:24 +04:00
Wolfr
73d8b8a817 docs - Move free kits to the top (#8639)
* docs - Move free kits to the top

* fix

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-11-24 12:48:21 +04:00
Phuc Bui
55ab069aca feat: add @phucbm in trusted registries (#8830)
* feat: add @phucbm in trusted registries

* Add @phucbm to registry directory

* fix: change svg quotes from double to single
2025-11-19 16:58:43 +04:00
Ajay Patel
c39925a9be Added shadcn/studio UI Kit to figma docs (#8852)
docs: Added shadcn/studio UI Kit to Figma paid section
2025-11-19 16:48:09 +04:00
shadcn
51179ccd64 fix: directory 2025-11-19 12:26:52 +04:00
Hin
dcfa05e392 feat: add shadcn-map to directory (#8832) 2025-11-19 12:20:20 +04:00
Aryan
541f55df04 feat: add @gaia registry entry to directory and registries.json (#8836)
Co-authored-by: shadcn <m@shadcn.com>
2025-11-19 12:19:53 +04:00
Edu Calvo
69010e0230 feat: add new registry entry for @smoothui with logo and description (#8837) 2025-11-19 12:18:35 +04:00
Rushil
a8025c866e feat: add moleculeui to registries and directories (#8838)
Co-authored-by: shadcn <m@shadcn.com>
2025-11-19 12:18:14 +04:00
Kaiyu Hsu
6e34ec7280 feat: add @uicapsule to registry (#8848)
Co-authored-by: shadcn <m@shadcn.com>
2025-11-19 12:16:42 +04:00
Arif Hossain
10ccb244a1 feat: add @commercn in registry directory (#8842) 2025-11-19 12:15:53 +04:00
Akshay Joshi
16fdb07ccc feat: added @crenspire/glass-ui in trusted registries and directory (#8831)
* feat: added @glass-ui in trusted registries and directory

* fix: svg logo not displayed properly
2025-11-19 12:14:41 +04:00
Moumen Soliman
49da1fae79 Add @uitripled registry (#8834)
* Add @uitripled registry

* Update registries.json

* fix

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-11-19 12:13:09 +04:00
Sepehr Soheili
a2244d42f7 docs: fix typo in documentation (#8793) 2025-11-17 20:06:32 +04:00
Brendan Dash
c2075e2a8b fix: typo (#8800) 2025-11-17 20:06:04 +04:00
Anthony Shew
dd2d8d7ead fix: dependencies for Bun in monorepo-next (#8791) 2025-11-13 09:42:31 +04:00
Akash Moradiya
b6a93b7ec6 feat: add @shadcnui-blocks to registry directory (#8763) 2025-11-12 09:39:21 +04:00
shadcn
4899d3f0da fix: minor directory updates 2025-11-10 15:35:21 +04:00
Pawan Kumar
3d04cb099a Add new registry entry for @taki (#8758)
* add taki ui in registry

* fix

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-11-10 15:27:56 +04:00
François Best
cde343916c ref: refactor nuqs usage in directory search (#8756)
* chore: fix typo

* ref: query is non-nullable (as it has a default value)

* ref: leverage nuqs' clearOnDefault behaviour
2025-11-10 15:27:06 +04:00
LN
c877df07b8 feat: add @square-ui in registries (#8761)
* feat: add new registry entry for @square-ui

* feat: add new registry entry for @square-ui with logo and description
2025-11-10 15:17:01 +04:00
DimaDevelopment
65e5c1c3cf Add search input for Directory list (#8673)
* feat(directory): Added directory search input

* feat(directory): Added nuqs for a search state management. Refactor searchFn - includes the description in the search criteria

* fear(directory): Added default query value. Added useQueryState limitUrlUpdates 250ms

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-11-10 12:24:15 +04:00
Anvarys
8a7f05f670 fix: correct typos in docs/components/chart (#8750) 2025-11-10 11:34:53 +04:00
Miracle Onyenma
db004ce4c0 Add new registry entry for @aevr (#8726)
* Add new registry entry for @aevr

Would like to add Aevr UI, a small collection of focused, production‑ready components and primitives for React/Next.js projects—built on shadcn/ui and complementary libraries—to the shadcn registry. It emphasizes practical, purpose‑specific building blocks with consistent design tokens, accessibility, and copy‑paste examples tailored for real product use.

Website: https://ui.aevr.space 

Repo: https://github.com/aevrhq/ui

* Add new component library entry for @aevr in registry directory

* Update logo SVG format in directory.json

* fix: logo color

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-11-10 11:30:16 +04:00
shadcn
e23698a897 feat: add tracking for directories 2025-11-10 11:27:10 +04:00
preet
5813ef20a3 Add new registry entry for @hextaui (#8715)
* Add new registry entry for @hextaui

* feat: add new registry entry for @HextaUI

* Update directory.json

Co-authored-by: shadcn <m@shadcn.com>

* fix: update directory

* fix: logo

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-11-10 11:20:23 +04:00
Arif Hossain
515024b69e feat: add @commercn in trusted registries (#8751) 2025-11-10 11:12:35 +04:00
Shaban
f7284c5cc3 feat(directory): update the @efferd logo (#8733) 2025-11-10 10:43:54 +04:00
Harshul
c02d00aafc fix(shadcn): Restore two-finger navigation on macOS by adjusting overscroll behavior (#8714)
* fix(shadcn): Tow finger navigation on macOS

* Add smooth scrolling to html element
2025-11-06 10:04:15 +04:00
Bassim Shahidy
df497ad236 feat: add assistant-ui to directory.json (#8720)
* feat: add assistant-ui to directory.json

* update description

* desc
2025-11-06 10:01:33 +04:00
shadcn
1e468e33ac feat: add more registries 2025-11-05 10:15:32 +04:00
dependabot[bot]
ff91c31a71 chore(deps): bump @radix-ui/react-toggle from 1.1.9 to 1.1.10 (#8702)
Bumps [@radix-ui/react-toggle](https://github.com/radix-ui/primitives) from 1.1.9 to 1.1.10.
- [Changelog](https://github.com/radix-ui/primitives/blob/main/release-process.md)
- [Commits](https://github.com/radix-ui/primitives/commits)

---
updated-dependencies:
- dependency-name: "@radix-ui/react-toggle"
  dependency-version: 1.1.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-05 09:51:45 +04:00
dependabot[bot]
25d6a18f6f chore(deps): bump @radix-ui/react-tooltip from 1.2.7 to 1.2.8 (#8701)
Bumps [@radix-ui/react-tooltip](https://github.com/radix-ui/primitives) from 1.2.7 to 1.2.8.
- [Changelog](https://github.com/radix-ui/primitives/blob/main/release-process.md)
- [Commits](https://github.com/radix-ui/primitives/commits)

---
updated-dependencies:
- dependency-name: "@radix-ui/react-tooltip"
  dependency-version: 1.2.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-05 09:51:11 +04:00
dependabot[bot]
c0309510b6 chore(deps): bump @radix-ui/react-accordion from 1.2.11 to 1.2.12 (#8700)
Bumps [@radix-ui/react-accordion](https://github.com/radix-ui/primitives) from 1.2.11 to 1.2.12.
- [Changelog](https://github.com/radix-ui/primitives/blob/main/release-process.md)
- [Commits](https://github.com/radix-ui/primitives/commits)

---
updated-dependencies:
- dependency-name: "@radix-ui/react-accordion"
  dependency-version: 1.2.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-05 09:50:52 +04:00
dependabot[bot]
a3a1574668 chore(deps): bump @commitlint/cli from 17.8.1 to 20.1.0 (#8698)
Bumps [@commitlint/cli](https://github.com/conventional-changelog/commitlint/tree/HEAD/@commitlint/cli) from 17.8.1 to 20.1.0.
- [Release notes](https://github.com/conventional-changelog/commitlint/releases)
- [Changelog](https://github.com/conventional-changelog/commitlint/blob/master/@commitlint/cli/CHANGELOG.md)
- [Commits](https://github.com/conventional-changelog/commitlint/commits/v20.1.0/@commitlint/cli)

---
updated-dependencies:
- dependency-name: "@commitlint/cli"
  dependency-version: 20.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-05 09:50:29 +04:00
shadcn
65d581ea5a chore: remove console 2025-11-04 15:19:45 +04:00
shadcn
fdf80a1d49 fix: gh link 2025-11-04 09:21:43 +04:00
Ajay Patel
86c494c452 feat: add new entry for @shadcn-studio in directory.json (#8692)
* feat: add new entry for @shadcn-studio in directory.json

* [fix]: for @shadcn-studio in directory.json, Updated logo SVG to use CSS variables

Updated logo SVG to use CSS variables for colors.Refactor logo SVG to use CSS variables
2025-11-03 12:48:36 +04:00
Paul Burke
eb158686b9 feat: adds lens-blocks to the registry index (#8687) 2025-11-03 11:45:57 +04:00
shadcn
134cd46edb feat: add hsl and color indicators to theme (#8691) 2025-11-03 11:25:06 +04:00
shadcn
47b0efb20c docs: update tanstack start 2025-11-03 10:46:35 +04:00
shadcn
bd4d09d33e fix 2025-11-03 10:30:18 +04:00
Dylan
14d6265580 docs: fix typos in Empty (#8675) 2025-11-03 08:57:19 +04:00
Ali Imam
68805d29a1 Update directory.json (#8682) 2025-11-03 08:56:03 +04:00
ocavue
c100d5841a feat: add prosekit to directory (#8677) 2025-11-02 15:00:40 +04:00
Ali Imam
7a71da5218 Update directory.json (#8671)
* Update directory.json

* Update registries.json
2025-11-02 14:51:58 +04:00
Mudunuri bhaskara karthikeya varma
e18902039a adding @eldoraui to directory.json (#8670) 2025-10-31 21:54:20 +04:00
Emmanuel Odii
559af6c245 feat(registry): add paykit to directory (#8654)
Co-authored-by: shadcn <m@shadcn.com>
2025-10-31 12:24:15 +04:00
Alex Paduraru
8971be484f feat: add @creative-tim to registries.json, directory.json (#8651)
* feat: add @creative-tim to registries.json, directory.json

* fix: logo color

---------

Co-authored-by: Alexandru Paduraru <axelut@yahoo.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-10-31 12:19:31 +04:00
Tommy D. Rossi
ad6a3c6367 Fix utils import transform when workspace alias does not start with @ (#7557)
* Fix nested src folder for utils import

* remove .only

* Update packages/shadcn/src/utils/transformers/transform-import.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* check for empty utils

* chore: changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-31 12:07:02 +04:00
dependabot[bot]
befa56b5be chore(deps): bump @faker-js/faker from 8.4.1 to 10.1.0 (#8520)
Bumps [@faker-js/faker](https://github.com/faker-js/faker) from 8.4.1 to 10.1.0.
- [Release notes](https://github.com/faker-js/faker/releases)
- [Changelog](https://github.com/faker-js/faker/blob/next/CHANGELOG.md)
- [Commits](https://github.com/faker-js/faker/compare/v8.4.1...v10.1.0)

---
updated-dependencies:
- dependency-name: "@faker-js/faker"
  dependency-version: 10.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-31 11:15:26 +04:00
dependabot[bot]
5d1770e36d chore(deps): bump @radix-ui/react-navigation-menu from 1.2.13 to 1.2.14 (#8519)
Bumps [@radix-ui/react-navigation-menu](https://github.com/radix-ui/primitives) from 1.2.13 to 1.2.14.
- [Changelog](https://github.com/radix-ui/primitives/blob/main/release-process.md)
- [Commits](https://github.com/radix-ui/primitives/commits)

---
updated-dependencies:
- dependency-name: "@radix-ui/react-navigation-menu"
  dependency-version: 1.2.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-31 11:14:27 +04:00
dependabot[bot]
653521725a chore(deps): bump jotai from 2.13.1 to 2.15.0 (#8521)
Bumps [jotai](https://github.com/pmndrs/jotai) from 2.13.1 to 2.15.0.
- [Release notes](https://github.com/pmndrs/jotai/releases)
- [Commits](https://github.com/pmndrs/jotai/compare/v2.13.1...v2.15.0)

---
updated-dependencies:
- dependency-name: jotai
  dependency-version: 2.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-31 11:14:12 +04:00
shadcn
7c0618bf43 feat: add new registries (#8661) 2025-10-31 10:39:29 +04:00
shadcn
854641cea1 fix 2025-10-30 12:51:15 +04:00
shadcn
3a72007f61 fix 2025-10-30 12:04:55 +04:00
shadcn
6b53b238fb fix: spacing 2025-10-30 11:59:50 +04:00
shadcn
b398fea304 feat: add dir action (#8647)
* feat: add mcp config

* feat

* fix
2025-10-30 11:53:24 +04:00
shadcn
f22174a77f feat: add mcp config (#8641) 2025-10-29 22:56:24 +04:00
shadcn
c9a39f1007 docs: update README 2025-10-29 21:38:18 +04:00
shadcn
a8ad21f81f fix: svgs 2025-10-29 21:37:15 +04:00
shadcn
504503c638 feat: add new registries 2025-10-29 21:20:04 +04:00
Pasquale Vitiello
f8df5c95cb docs: update coss logo (#8631) 2025-10-29 20:57:42 +04:00
shadcn
2bfc1c82ba chore: deprecate www (#8629)
* chore: deprecate www

* chore: updates

* fix
2025-10-29 20:50:55 +04:00
shadcn
84bd724d97 feat: refactor registry (#8598)
* feat: refactor registry

* fix: remove components

* refactor: getActiveStyle

* fix: prettier in build-registry

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* fix

* Update apps/v4/scripts/build-registry.mts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix

* Update apps/v4/scripts/build-registry.mts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update apps/v4/components/block-viewer.tsx

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-29 15:07:56 +04:00
shadcn
39fdf94550 feat: add svgl 2025-10-29 14:58:25 +04:00
shadcn
08479cc3db feat: add wigggle-ui 2025-10-29 13:55:50 +04:00
shadcn
02d5ce85ec feat: upgrade to Next.js 16 (#8615)
* feat: upgrade to Next.js 16

* chore: deps

* fix

* fix

* fix

* fix: workaround zod 4 for now

* fix

* fix: copy button

* fix: update apps/v4/hooks/use-is-mac.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix

* fix: remove

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-29 13:37:41 +04:00
shadcn
c0329c86b9 feat: add retroui and reui 2025-10-29 09:53:25 +04:00
shadcn
3b1491f908 fix: typo 2025-10-29 09:30:49 +04:00
shadcn
ca4c1c43ec feat: update registry directory 2025-10-29 00:15:20 +04:00
shadcn
1e840eb53c feat: update directory 2025-10-29 00:05:03 +04:00
shadcn
96ac92e63f fix 2025-10-29 00:00:20 +04:00
shadcn
e11546e692 fix: examples page 2025-10-28 23:56:15 +04:00
shadcn
0b4d62f95c chore: rebuild registry 2025-10-28 22:59:12 +04:00
shadcn
dae80dad65 fix: password field 2025-10-28 22:58:17 +04:00
shadcn
abc09809e8 feat: add blocks to directory 2025-10-28 22:56:29 +04:00
shadcn
8a40fe0ead feat: update registries 2025-10-28 22:45:06 +04:00
shadcn
b3ab304a00 fix: minor styles updates 2025-10-28 21:34:31 +04:00
Elliot Sutton
bb45fd83c3 fix(v4): correction of the Animate UI logo (#8608)
Co-authored-by: shadcn <m@shadcn.com>
2025-10-28 21:03:19 +04:00
Chisom Uma
84678ee1c0 Add new registry entry for @chisom-ui (#8601) 2025-10-28 21:01:08 +04:00
shadcn
33ffb0419c Merge branch 'main' of github.com:shadcn-ui/ui
# Conflicts:
#	apps/v4/registry/directory.json
2025-10-28 20:52:28 +04:00
shadcn
a2f6c031e2 feat: add new registries 2025-10-28 20:49:49 +04:00
shadcn
ac098d8cf0 feat: add new registries (#8600) 2025-10-28 18:28:06 +04:00
shadcn
8160610410 Merge branch 'main' of github.com:shadcn-ui/ui 2025-10-28 11:26:17 +04:00
shadcn
c7901e3a41 chore: update validate-registries script 2025-10-28 11:26:04 +04:00
shadcn
d73ac361b3 feat: add registry directory (#8574)
* feat: add registry directory

* fix: lint

* feat: add more registries

* feat: add nuqs to directory

* feat: add shadcndesign

* feat: add more registries

* feat: add new registries

* chore: remove hooks
2025-10-28 11:25:25 +04:00
François Best
ebad2901ce feat: add nuqs to registries.json (#8579) 2025-10-27 11:16:18 +04:00
shadcn
4f617d59b8 Fix description formatting in registry_directory.yml 2025-10-26 16:22:48 +04:00
shadcn
ed0e103bd6 Refactor checklist validations in registry_directory.yml
Removed individual required validations from checklist items and added a single required validation for the entire checklist.
2025-10-26 16:22:17 +04:00
shadcn
9cab0c9b18 chore: add registry directory issue template 2025-10-26 16:18:46 +04:00
DimaDevelopment
d80e084814 feat: add @wandry-ui to registries.json (#8566) 2025-10-26 15:28:42 +04:00
shadcn
efcf9728c2 feat: add docs for cell size 2025-10-26 14:53:50 +04:00
Lakshya Thakur
8835bacc8b fix: use calendar-05 blocks instead of calendar-02 for range (#8029) 2025-10-26 14:47:06 +04:00
Ian Thorslund
f2556d2386 fix(components): Fix left radius of days when weeks are shown in range calendar (#8570)
* fix(components): Fix left radius of days when weeks are shown in range calendar

* feat: update block to show range

* chore: rebuild registry

* docs: add changelog

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-10-26 14:44:24 +04:00
albertasaftei
75a0000075 Add Pixelact UI registry to registries.json (#8301) 2025-10-25 09:40:38 +04:00
Dillion Verma
ac306c60f5 feat: add magic ui pro registry (#8302)
Co-authored-by: shadcn <m@shadcn.com>
2025-10-24 11:19:25 +04:00
shadcn
5e2ef1f8bd docs: updates 2025-10-24 10:56:23 +04:00
shadcn
7d9b8aefff Merge branch 'main' of github.com:shadcn-ui/ui 2025-10-24 10:44:39 +04:00
shadcn
58208e3802 fix: minor updates 2025-10-24 10:44:21 +04:00
Shaban
a16a77446a feat: rename @efferd-ui -> @efferd (#8557) 2025-10-24 10:37:47 +04:00
github-actions[bot]
39032bb390 chore(release): version packages (#8551)
* chore(release): version packages

* 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-10-23 22:12:05 +04:00
shadcn
d7e0dc3ec8 feat(shadcn): middleware to proxy (#8555)
* feat: implement getFrameworkVersion

* feat(shadcn): add transformNext transformer

* feat(shadcn): rename

* chore: update

* chore: changeset

* fix

* fix: small refactor
2025-10-23 22:00:55 +04:00
shadcn
6bddba986d feat(shadcn): add next 16 to init (#8550)
* feat: add next 16 init

* chore: changeset

* fix: tests

* fix
2025-10-23 17:20:45 +04:00
shadcn
b70059b25b docs: add react-19 docs back 2025-10-23 17:14:09 +04:00
shadcn
37bc2eec1f feat: update code block for component preview (#8549) 2025-10-23 16:24:44 +04:00
mw10013
bb048fb532 feat: add @oui to registries.json (#8541) 2025-10-22 21:35:55 +04:00
Alejandro Wurts
9c373dbd27 feat: add @simple-ai to trusted registries (#8539) 2025-10-22 21:35:03 +04:00
shadcn
d75b092c61 docs: remove legacy docs 2025-10-22 07:02:23 +04:00
Gihan Rangana
be49662bf5 shadix-ui registry added (#8505) 2025-10-21 19:16:23 +04:00
FadilRumasoreng
b2b2e3fc98 docs (security) : add clickable link to security reporting section (#8525)
* docs (security) : add clickable link to security reporting section

* fix(docs): use markdown link format for security section
2025-10-21 17:41:45 +04:00
Neeraj Dalal
188b746074 refactor(field): no duplicate errors (#8514)
* chore: tweaks > field.tsx

apps/v4/registry/new-york-v4/ui/field.tsx

* chore: tweaks > field.tsx

apps/v4/registry/new-york-v4/ui/field.tsx

* chore: tweaks > field.json field.json

apps/www/public/r/styles/new-york-v4/field.json
apps/v4/public/r/styles/new-york-v4/field.json
2025-10-21 16:02:52 +04:00
Joshua Chung
6f093a0f3f Added ha-components registry to registries.json (#8531) 2025-10-21 15:40:03 +04:00
Matt Wierzbicki
f18f1eaff7 Added shadcndesign.com registry to registries.json (#8516)
* Added shadcndesign.com registry to registries.json

* Update registries.json with open source shadcndesign registry
2025-10-21 14:33:40 +04:00
shadcn
9ac1b5c0a5 feat: add native select (#8528)
* feat: add native select

* fix: width
2025-10-21 11:48:25 +04:00
shadcn
f63b70b413 feat: implement search via fumadocs (#8523)
* feat: implement search

* fix: update message when searching
2025-10-21 10:26:29 +04:00
shadcn
54e725d986 feat(toggle-group): add spacing props 2025-10-20 21:28:40 +04:00
shadcn
62dbad36bb fix: theme-customizer 2025-10-20 20:42:55 +04:00
shadcn
a707424fa2 fix: front page blocks 2025-10-20 20:39:01 +04:00
shadcn
e2bfa6bd85 feat(badge): make rounded-full (#8518) 2025-10-20 20:24:45 +04:00
preet
6292464d90 docs(calendar): add timezone fix for date selection offset issue (#8515)
Added a new section to the Calendar documentation explaining how to fix the issue where selecting a date highlights the previous day. The section includes an example showing how to detect the user’s local timezone and pass it as a timeZone prop to the Calendar component to resolve the date offset problem.
2025-10-20 13:17:58 +00:00
shadcn
6617167d6f Merge branch 'main' of github.com:shadcn-ui/ui 2025-10-20 16:05:21 +04:00
shadcn
ca28857d40 fix: themes 2025-10-20 16:05:14 +04:00
Rakesh
343bc941b1 Fix/theme code mismatch (#8368)
* fix/replaced stale theme colors

* fix:missing chart colors added
2025-10-20 15:56:57 +04:00
Pasquale Vitiello
c9311f26fa feat: add @coss to registries.json (#8490) 2025-10-17 15:01:04 +04:00
Ivan Vasilov
4e0871f426 Add supabase registry to trusted registries. (#8161) 2025-10-17 15:00:51 +04:00
shadcn
cb769b7059 fix: navigation menu demo on mobile (#8488) 2025-10-16 14:44:27 +04:00
Dylan Tientcheu
93037dca94 feat: add @algolia in trusted registries (#8485) 2025-10-16 13:05:51 +04:00
github-actions[bot]
ed9d5939e6 chore(release): version packages (#8479)
* chore(release): version packages

* fix

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-10-15 22:55:13 +04:00
shadcn
b52ec12f1e fix(shadcn): universal items handling (#8478)
* fix(shadcn): universal items handling

* chore: add changeset
2025-10-15 22:27:12 +04:00
Igor S. Zizinio
2ab9bff4bb Fix formatting of Badge variant prop in documentation (#8477) 2025-10-15 22:09:06 +04:00
Shaban Haider
2f6b51fa0a feat: add @efferd-ui in trusted registries (#8474) 2025-10-15 22:03:39 +04:00
shadcn
8a4764ed91 chore: registry build 2025-10-15 12:05:03 +04:00
Chisom Uma
e934d4645b feat(registry): Add Austin UI Components to the registry index (#8456)
* feat(registry): Add Austin UI Components to the registry index

* Fix JSON syntax for @austin-ui registry URL

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-10-15 12:02:40 +04:00
shadcn
08b8e499d8 chore: update registries.json (#8470) 2025-10-15 11:52:43 +04:00
shadcn
69402b3579 ci: update deprecated to ignore www/package.json 2025-10-15 11:39:53 +04:00
shadcn
679c852254 Merge branch 'main' of github.com:shadcn-ui/ui 2025-10-15 11:37:26 +04:00
github-actions[bot]
d478412e44 chore(release): version packages (#8453)
* chore(release): version packages

* 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-10-15 11:37:01 +04:00
shadcn
d5c8a25150 Merge branch 'main' of github.com:shadcn-ui/ui 2025-10-15 11:30:53 +04:00
Benjamin
26433a651c Added react-market registry (#8346)
Co-authored-by: shadcn <m@shadcn.com>
2025-10-15 11:30:43 +04:00
shadcn
c3da716e94 debug: ci 2025-10-15 11:30:24 +04:00
dependabot[bot]
b2572d0287 chore(deps): bump tj-actions/changed-files in /.github/workflows (#8466)
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 44 to 46.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/changed-files/compare/v44...v46)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-version: '46'
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-15 11:30:03 +04:00
shadcn
b83f042416 fix: actions 2025-10-15 11:26:28 +04:00
shadcn
6567897393 fix: actions 2025-10-15 11:07:14 +04:00
shadcn
2675fa3941 ci: add deprecated action (#8465)
* ci: add deprecated action

* ci: add label

* Potential fix for code scanning alert no. 12: Workflow does not contain permissions

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-10-15 11:04:30 +04:00
Shodai Suzuki
fbda67c88c docs: remove isolated remix page from installation guides (#7027) 2025-10-15 10:39:15 +04:00
shadcn
e8674ee848 feat(shadcn): allow path to override targets (#8452) 2025-10-15 10:37:58 +04:00
kuzma031
adb66f4d43 fix(components): use type-only import for VariantProps in sidebar component to support verbatimModuleSyntax (#7437)
* fix sidebar variantprops imports

* chore: registry build

---------

Co-authored-by: Djordje Kuzmanovic <djordje@voiced.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-10-15 10:36:32 +04:00
shadcn
3afb46eaf6 feat: add llms.txt (#8460) 2025-10-14 23:30:07 +04:00
shadcn
7cd019ad36 feat(shadcn): add support for color vars (#8459)
* feat(shadcn): add support for color vars

* chore: add changeset
2025-10-14 23:07:27 +04:00
Serhat Arslan
bea7d30536 docs: fix next/link import syntax in component examples (#8427)
Fix incorrect named import syntax for Next.js Link component.

Changed from:
  import { Link } from "next/link"

To correct default import:
  import Link from "next/link"

Next.js Link is a default export, not a named export. The incorrect
syntax causes TypeScript error:
'Module "next/link" has no exported member "Link"'

Affected files:
- Button component docs
- Badge component docs
- Breadcrumb component docs (v4 and www)
- Navigation Menu component docs

Fixes issue where users copying code snippets get immediate errors.

Co-authored-by: serhatx1 <armonikadijital@gmail.com>
2025-10-14 22:38:58 +04:00
Ziad Beyens
40c3ff513a fix(registry): handle universal registry items with no files (#8420)
* fix(registry): handle universal registry items with no files

Allow registry items with registryDependencies but no files to be
considered universal registry items. Previously the function required
files.length to be truthy, which excluded valid items with only
registryDependencies.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-10-14 17:14:05 +04:00
Gildas Garcia
89ebfdce47 feat(registry): Add Shadcn Admin Kit to the registry index (#8442) 2025-10-14 17:12:12 +04:00
Haz
b83023034a fix(cli): fix add registry item with at-property css rule (#8451)
* Add fixture and test

* Handle at-property as regular CSS rules in updateCssPlugin

* Add changeset entry

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-10-14 17:11:29 +04:00
Ujjwal Sharma
6a534d7954 fix(components): use type import for ToasterProps (#8376)
* fix(components): use type import for ToasterProps

* chore: build registry

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-10-14 16:40:17 +04:00
Felix
ef1987ded9 docs(Toast): add deprecation Callout (#6982)
* docs(Toast): add deprecation Callout

* docs(Toast): add tw4 and react19 specifics
2025-10-13 22:21:50 +04:00
Jakob Guddas
77bf7d28b4 feat(components): changed sonner defaults to use lucide icons (#7620)
* feat(components): changed sonner defaults to use lucide icons

* Update new-york-v4 sonner.tsx

* fix: icons and docs

* fix

* fix

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-10-13 22:16:50 +04:00
Ayush Shrestha
41f4f7357d refactor: initialize FormFieldContext and FormItemContext with null values rather empty object with type assertion (#4847) 2025-10-13 21:32:43 +04:00
Carlos Pegueros
bc99818e04 docs(www): fix sonner not showing on first render (#6235) 2025-10-13 21:17:32 +04:00
Shahar Ilany
162ba7b13c Small fixes for installation document (#6623)
* Fix TanStack Start icon color

* Fix a11y for Laravel and TanStack Start
2025-10-13 21:14:11 +04:00
Ryann Mack
f12db1e3a2 fix(sonner): support border radius from theme (#7825)
* fix(sonner): support border radius from theme

* chore: rebuild registry

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-10-13 21:12:00 +04:00
shadcn
ce3e2b1df8 Merge branch 'main' of github.com:shadcn-ui/ui 2025-10-13 12:39:19 +04:00
shadcn
dcfe911b33 docs: button cursor 2025-10-13 12:38:58 +04:00
Jrocam
7210a4919a fix(components): checkbox alignment with grid 🔳 (#4772)
* fix(components): checkbox alignment with grid 🔳

* fix(checkbox): internal checkbox check alignment (default style)

* fix: new-york-v4

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-10-13 12:29:44 +04:00
Krishna Agarwal
d198908510 fix(field): return null when errors are empty (#8419)
Co-authored-by: shadcn <m@shadcn.com>
2025-10-13 12:22:34 +04:00
shadcn
b0b1cd1f0d feat: add dropdown menu dialog example (#8438)
* feat: add dropdown menu dialog example

* chore: remove dropdown-dialog
2025-10-13 11:57:20 +04:00
shadcn
f3d70724b6 chore: remove new-components-01 (#8439) 2025-10-13 11:55:08 +04:00
Dada Khalandar
407e9c6802 fix: correct link to Form documentation in form.mdx (#8416) 2025-10-11 10:15:07 +04:00
shadcn
c67e630521 feat: add docs and examples for react-hook-form and tanstack form (#8412)
* feat: add next forms docs

* feat

* docs: rhf and tsf

* docs: forms

* feat: update react-hook-form docs

* feat: update docs for both lib

* docs: update tanstack docs

* docs: update

* fix

* fix

* fix

* add forms link in sidebar
2025-10-10 21:29:30 +04:00
Daniel Petho
f494411953 feat(registry): add fancy components to registries (#8397) 2025-10-10 16:09:13 +04:00
Mudunuri bhaskara karthikeya varma
a43c1d1342 feat: add @eldoraui registry URL to registries.json (#8379)
Co-authored-by: shadcn <m@shadcn.com>
2025-10-09 11:06:55 +04:00
Hin
607a6fd127 feat: add shadcn map to the registry (#8375) 2025-10-08 20:15:45 +04:00
Irsyad A. Panjaitan
fbcc665b49 Add @intentui registry URL to registries.json (#8380) 2025-10-08 00:07:59 +04:00
Shivam S.
7ddcf31e43 fix(docs): correct Empty component structure in documentation (#8374) 2025-10-07 20:58:15 +04:00
Louis J.
3e39163b08 feat: add @elevenlabs-ui registry URL to registries.json (#8364) 2025-10-07 13:12:24 +04:00
shadcn
e311fdae04 fix(www): dashboard 2025-10-07 10:09:34 +04:00
shadcn
26640d9d88 fix: code 2025-10-06 16:57:33 +04:00
Seoku
3e20c228da fix(input-group-textarea): prevent child elements from overflowing by… (#8341)
* fix(input-group-textarea): prevent child elements from overflowing by adding min-w-0

* chore: run registry:build

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-10-06 16:11:01 +04:00
Morgan Feeney
0810c0e1a2 Add @zippystarter registry URL to registries.json (#8354) 2025-10-06 16:00:28 +04:00
Ahdeetai
1205ea5445 Add @scrollxui in trusted registries (#8322)
* Add @scrollxui in trusted registries

* fix: missing comma

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-10-06 16:00:12 +04:00
Rob Austin
4430ab8bab Add @shadcnblocks registry URL to registries.json (#8344)
Co-authored-by: shadcn <m@shadcn.com>
2025-10-05 20:03:40 +04:00
github-actions[bot]
d6716db9cc chore(release): version packages (#8349)
* chore(release): version packages

* chore: lock

* chore(release): version packages

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-10-05 14:23:43 +04:00
JunHyeok Ha
da8fa6aacd fix(cli): Update package.json name property when init next-monorepo (#7742)
* fix(cli): Update package.json name property when init next-monorepo

* test(cli): Fix failing test

* fix(cli): Remove unnecessary git changes

* chore: add changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-10-05 14:18:31 +04:00
shadcn
e96f9edf02 feat(shadcn): add mcp support for codex (#8348) 2025-10-05 14:05:14 +04:00
Ohh
b19e9cadb2 feat: add @skyrui in trusted registries (#8326) 2025-10-05 13:01:08 +04:00
Nicholas
3bb47bf914 feat: add better-upload to trusted registries (#8345) 2025-10-05 13:00:56 +04:00
Ajay Patel
a72fac6fde Add @shadcn-studio registry URL to registries.json (#8332)
Added https://shadcnstudio.com/ opensource components (https://shadcnstudio.com/components), blocks (https://shadcnstudio.com/blocks), and themes (https://shadcnstudio.com/theme-generator) registry
2025-10-04 11:44:59 +04:00
Ritesh Bucha
4b3186c46b feat: add @bucharitesh in trusted registries (#8330) 2025-10-04 11:44:32 +04:00
Bassim Shahidy
e67e955f2a Add assistant-ui registry URL to registries.json (#8312) 2025-10-04 11:44:05 +04:00
lucas kouzoukian
bf047b9824 correct alignment. (#8337) 2025-10-04 11:34:25 +04:00
shadcn
04432835f9 feat: new components (#8334)
* feat: add field.tsx and update blocks

* feat: add input group

* feat: implement button group

* fix

* fix

* wip

* fix: button group

* feat: update field

* fix

* feat

* feat: cooked

* fix

* chore: build registry

* feat: add kbd component

* chore: update input group demo

* feat: update kbd component

* feat: add empty

* feat: add spinner

* refactor: input group

* feat: blocks

* fix

* fix: app sidebar

* feat: add label to app sidebar

* fix

* fix

* fix

* fix

* fix

* feat

* feat

* fix

* docs: button group

* feat: add docs

* docs: kbd

* docs: empty

* fix

* docs

* docs

* feat: add sink link

* fix

* fix

* docs

* feat: add new page

* fix

* fix

* fix

* fix

* fix

* fix

* feat: add registration form

* fix: chat settings

* fix

* fix preview

* fix examples

* feat: add changelog

* fix

* fix

* fix

* fix

* fix

* feat(www): add t3 versions

* chore: build registry

* fix

* fix

* fix

* feat: inline code examples for llm

* fix

* feat: home

* fix

* fix

* fix

* fix

* fix

* chore: changelog

* fix

* fix

* fix

* fix: callout

* fix
2025-10-03 21:05:22 +04:00
Pablo Hdez
77e6f28e81 feat: add @svgl in trusted registries (#8297) 2025-09-29 16:02:53 +04:00
shadcn
f1e51ec8a1 feat(tooltip): update colors (#8271) 2025-09-22 10:56:50 +04:00
Brandon McConnell
3c525b8305 fix: correct improper JSON syntax (#8256) 2025-09-20 08:40:42 +04:00
shadcn
e7e844ff63 feat(button): remove shadow from buttons except outline (#8252) 2025-09-18 21:04:02 +04:00
shadcn
e14c55ac65 feat(input): remove flex class (#8251)
* feat: remove flex class

* chore: rebuild registry
2025-09-18 21:03:11 +04:00
shadcn
043be944ab fix: build script (#8250)
* fix: registries.json

* fix: chart

* fix: build script
2025-09-18 20:48:40 +04:00
Sahaj Jain
4eb257bc14 Add @tweakcn to trusted registries & Add shadcraft to Figma docs (#8245)
* docs: add shadcraft figma kit

* docs: add tweakcn to trusted registries
2025-09-18 17:39:02 +04:00
github-actions[bot]
1289192d4f chore(release): version packages (#8231)
* 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-17 08:17:57 +04:00
shadcn
75dde2e646 fix(shadcn): deps in cts projects (#8229)
* fix(shadcn): deps in cts projects

* fix: deps

* chore: add changelog
2025-09-16 17:54:44 +04:00
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
github-actions[bot]
c1357982e8 chore(release): version packages (#7591)
* chore(release): version packages

* deps: update

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-06-11 13:57:06 +04:00
shadcn
92cfb9a30e fix(shadcn): flaky create-project tests (#7590)
* fix(shadcn): flaky create-project tests

* fix

* fix
2025-06-11 13:50:35 +04:00
shadcn
c5d90c718a feat: add migrate radix command (#7586)
* feat(shadcn): add migrate-radix command

* feat(shadcn): fix and test edge cases

* test(shadcn): add tests for all primitives

* fix(shadcn): edge cases and add yes option

* fix

* chore(shadcn): add changeset

* style: fix code styles

* docs: update changelog

* fix: format

* feat: update changelog

* fix: format
2025-06-11 13:20:47 +04:00
github-actions[bot]
b1fd13ffb0 chore(release): version packages (#7574)
* chore(release): version packages

* deps: update

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-06-09 16:29:06 +04:00
shadcn
3119f94d47 feat: only show npm flag for react 18 deps (#7573)
* feat: only show npm flag for react 18 deps

* tests: update
2025-06-09 16:17:44 +04:00
shadcn
057d97dd25 docs: changelog 2025-06-09 16:00:30 +04:00
shadcn
a659e09353 feat: update calendar changelog 2025-06-09 15:18:04 +04:00
shadcn
82d94eee38 feat: calendar v2 (#7551)
* feat(v4): upgrade calendar

* feat: more calendar examples

* fix: remove grid

* feat: more examples

* feat: more examples

* fix

* feat: update examples

* fix: dark mode

* fix: calendar in dark mode

* fix: examples

* fix

* docs: update calendar docs

* feat: update cmdk

* fix: block viewer patterns

* feat: update new-york and default

* fix: docs and examples

* fix: command menu

* feat: remove blocks from cmdk

* fix

* fix: calendar 13

* fix: format

* fix

* feat: update calendar default
2025-06-06 20:09:53 +04:00
shadcn
9cbc6641d9 fix: docs nav 2025-05-31 14:42:35 +04:00
shadcn
e0bec146fa fix: async layout 2025-05-31 14:29:56 +04:00
shadcn
65223896da feat: layout toggle (#7515)
* feat: implement fixed layout

* feat: track layout

* fix
2025-05-31 14:21:19 +04:00
shadcn
16ee16b053 fix: themes page 2025-05-30 18:00:51 +04:00
shadcn
b5cf967848 feat: add themes page back (#7503)
* feat: add themes page back

* fix: values

* fix: redirect
2025-05-30 17:45:02 +04:00
shadcn
12b7833d70 fix: remove unused cn 2025-05-30 15:31:34 +04:00
shadcn
ec73150490 feat: add missing links 2025-05-30 15:29:18 +04:00
shadcn
1aa35048a5 feat: v4 updates (#7499)
* feat(v4): update home page

* fix

* fix: cards

* feat(v4): charts page

* feat: update pages

* feat: colors

* fix

* feat: add docs

* feat: mdx work

* fix

* fix

* fix: sidebar

* fix: lint

* feat: updates

* feat: update components

* feat: fix docs

* fix: responsive

* feat: implement cmdk

* fix: update navigation menu demo

* fix: code style

* fix: themes

* feat: implement blocks page

* fix: docs config

* refactor

* fix: outputFileTracingIncludes

* fix

* fix: output

* fix

* fix: registry

* refactor: move docs

* debug: docs

* debug

* revert

* fix: mjs

* deps: pin fumadocs

* debug

* fix: downgrade next

* fix: index page

* refactor: move mdx components

* fix: remove copy button

* fix

* was it zod

* yes it was

* remove copy page

* fix: color page

* fix: colors page

* fix: meta colors

* fix: copy button

* feat: sync registry

* fix: registry build script

* feat: update port

* feat: clean up examples

* fix

* fix: mobile nav

* fix: blur for mobile

* fix: sidebar nav

* feat: update examples

* fix: build scripts

* feat: update components

* feat: restyle

* fix: types

* fix: styles

* fix: margins

* fix: screenshots

* fix

* feat: update theme

* fix: charts nav

* fix: image

* feat: optimize images

* fix: menu

* fix: card

* fix: border

* check

* feat: implement charts page

* fix: charts

* fix: og images

* feat: extend touch

* fix: static

* fix: sizing

* fix: mobile screenshots

* fix: page nav

* fix

* feat: update favicon

* fix: theme selector

* fix: feedback

* fix: sink

* docs: update

* fix: styles

* chore: update registry

* fix: command

* fix

* fix: minor updates

* fix: typography on smaller devices

* fix: format

* fix: remove unused icon

* feat: update favicon

* fix: typography

* docs: typography page

* fix: steps
2025-05-30 11:35:16 +04:00
github-actions[bot]
d85b8eff06 chore(release): version packages (#7415)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-05-30 10:32:54 +04:00
shadcn
df91b52887 feat(shadcn): registry commands (#7497)
* feat: grunt

* feat: add useCache option to fetchRegistry

* feat: wip mcp

* test(shadcn): add tests for build

* feat(shadcn): fix import and implement verbose

* chore(shadcn): add build back for now

* feat(shadcn): resolve css file

* chore(shadcn): add experimental tag

* chore: changeset
2025-05-29 15:49:22 +04:00
Thibault Le Ouay
b84c990e42 fix registry item schema (#7486) 2025-05-28 16:52:24 +04:00
Joshua
2773f9e2e2 fix(tailwind-prefix): resolve prefixing issue for Tailwind CSS v4 compatibility (including tests) (#6885)
* WIP

* fix(tailwind-prefix): resolve prefixing issue for Tailwind CSS v4 compatibility
1. Fixed incorrect prefix application causing issues with Tailwind CSS v4.
2. Optimized implementation using map() for better performance and readability.

* fix(tailwind-prefix): fix test transform-tw-prefixt

* fix(tailwind-prefix): fix test apply-prefix

* fix(tailwind-prefix): add backwards compatibility for applyPrefix

* fix(tailwind-prefix): added changeset

---------

Co-authored-by: Al-Amin Islam Nerob <nerobit.786@gmail.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-05-19 11:31:12 +04:00
shadcn
c41c6ece86 fix: move tw-animate-css to devDependencies (#7251) 2025-04-23 16:45:23 +04:00
github-actions[bot]
11267f2fed chore(release): version packages (#7228)
* chore(release): version packages

* deps: update pnpm lock

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-04-23 16:28:59 +04:00
Richard Szalay
9ad24d6a16 chore(shadcn): add update-dependencies tests (#7067) 2025-04-22 15:20:00 +04:00
shadcn
e8468793fc chore: temporarily move tw-animate-css to dependencies 2025-04-22 05:07:56 +04:00
迷渡
6f702f5fbf fix: Add npm: specifier when install dependencies with Deno (#6899)
* fix: Add `npm:` specifier when install dependencies with Deno

* chore: changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-04-21 23:36:36 +04:00
shadcn
d0306774fe feat(shadcn): resolve imports from anywhere (#7220)
* feat(shadcn): resolve imports from anywhere

* fix: type errors

* fix: add debug

* feat: handle root paths

* fix: src prefix

* fix: tests

* chore: changeset
2025-04-19 13:31:04 +04:00
Neeraj Dalal
f1e5cc4666 🔥 feat(fix): mark "tw-animate-css" as devDep (#6985)
* chore: tweaks to build-registry.mts ~ 1 file 2+ 5-

apps/v4/scripts/build-registry.mts

* chore: tweaks to index.json ~ 1 file 4+ 9-

apps/www/public/r/styles/new-york-v4/index.json

* chore: tweaks to registry.json ~ 1 file 221+ 850-

apps/v4/registry.json

* chore: tweaks to index.json ~ 1 file 47+ 144-

apps/www/public/r/index.json

* chore: tweaks to registry.json ~ 1 file 852+ 221-

apps/v4/registry.json

* chore: tweaks to build-registry.mts ~ 1 file 7+ 2-

apps/v4/scripts/build-registry.mts

* chore: tweaks to build-registry.mts ~ 1 file 2+ 2-

apps/v4/scripts/build-registry.mts

* chore: tweaks to index.json ~ 1 file 11+ 4-

apps/www/public/r/styles/new-york-v4/index.json

* chore: tweaks to index.json ~ 1 file 1+ 1-

apps/www/public/r/index.json

* chore: tweaks to index.json ~ 1 file 143+ 46-

apps/www/public/r/index.json

* chore: tweaks to update-dependencies.ts ~ 1 file 20+

packages/shadcn/src/utils/updaters/update-dependencies.ts

* chore: tweaks to update-dependencies.ts ~ 1 file 1-

packages/shadcn/src/utils/updaters/update-dependencies.ts

* chore: tweaks to update-dependencies.ts ~ 1 file 19-

packages/shadcn/src/utils/updaters/update-dependencies.ts

* chore: tweaks to add-components.ts update-dependencies.ts ~ 2 files 21+ 2-

packages/shadcn/src/utils/add-components.ts
packages/shadcn/src/utils/updaters/update-dependencies.ts

* chore: tweaks to update-dependencies.ts ~ 1 file 29+ 28-

packages/shadcn/src/utils/updaters/update-dependencies.ts

* refactor: remove redundant code

tw-animate-css already has accordion animations

* chore: tweaks > migrate-icons.ts

packages/shadcn/src/migrations/migrate-icons.ts

* fix: formatting > add-components.ts update-dependencies.ts

packages/shadcn/src/utils/add-components.ts
packages/shadcn/src/utils/updaters/update-dependencies.ts

* chore: add changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-04-19 13:05:52 +04:00
Titouan V
e3ca257f6e chore(www): replace shadcn-ui deprecated mentions to shadcn (#7207) 2025-04-18 10:44:46 +04:00
github-actions[bot]
d1a36d3e17 chore(release): version packages (#7198)
* chore(release): version packages

* fix

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-04-15 16:30:10 +04:00
shadcn
617483fe9c fix(shadcn): do not throw for empty dir (#7196)
* fix(shadcn): do not throw for empty dir

* chore: changeset
2025-04-15 15:01:20 +04:00
shadcn
6d2728db2e deps: update 2025-04-07 15:19:36 +04:00
github-actions[bot]
625be136f4 chore(release): version packages (#6505)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-04-07 15:16:43 +04:00
shadcn
1bd209a4db feat: add oklch colors to themes (#7090)
* wip

* feat: add oklch theme

* fix: keys
2025-03-31 10:33:48 +04:00
shadcn
812e2300f1 fix(shadcn): only run preflight check if url 2025-03-30 05:43:29 +04:00
shadcn
b52fa4559c docs(www): update registry examples 2025-03-28 21:05:55 +04:00
shadcn
2fade2326a feat(shadcn): add css props to schema (#7072)
* feat(shadcn): add css props to schema

* fix: types
2025-03-28 17:48:59 +04:00
dependabot[bot]
754a66061d chore(deps): bump sharp from 0.31.3 to 0.32.6 (#7053)
Bumps [sharp](https://github.com/lovell/sharp) from 0.31.3 to 0.32.6.
- [Release notes](https://github.com/lovell/sharp/releases)
- [Changelog](https://github.com/lovell/sharp/blob/v0.32.6/docs/changelog.md)
- [Commits](https://github.com/lovell/sharp/compare/v0.31.3...v0.32.6)

---
updated-dependencies:
- dependency-name: sharp
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-27 22:24:16 +04:00
dependabot[bot]
cc53c2243e chore(deps): bump next from 15.2.0-canary.33 to 15.2.3 in /apps/v4 (#7049)
Bumps [next](https://github.com/vercel/next.js) from 15.2.0-canary.33 to 15.2.3.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v15.2.0-canary.33...v15.2.3)

---
updated-dependencies:
- dependency-name: next
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-03-27 22:24:00 +04:00
nicognaw
99fbf4cb77 fix: code block command overflow (#7031) 2025-03-27 18:15:14 +04:00
dependabot[bot]
a82db8395d chore(deps): bump vite from 5.4.14 to 5.4.15 (#7051)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.4.14 to 5.4.15.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.15/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.15/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-27 18:12:46 +04:00
dependabot[bot]
79eed50e5b chore(deps): bump next from 15.2.0-canary.33 to 15.2.3 (#7052)
Bumps [next](https://github.com/vercel/next.js) from 15.2.0-canary.33 to 15.2.3.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v15.2.0-canary.33...v15.2.3)

---
updated-dependencies:
- dependency-name: next
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-27 18:12:28 +04:00
dependabot[bot]
799a7f8aa7 chore(deps-dev): bump remark-gfm from 4.0.0 to 4.0.1 (#7048)
Bumps [remark-gfm](https://github.com/remarkjs/remark-gfm) from 4.0.0 to 4.0.1.
- [Release notes](https://github.com/remarkjs/remark-gfm/releases)
- [Commits](https://github.com/remarkjs/remark-gfm/compare/4.0.0...4.0.1)

---
updated-dependencies:
- dependency-name: remark-gfm
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-27 17:51:55 +04:00
dependabot[bot]
79a6f54d4e chore(deps): bump @radix-ui/react-scroll-area from 1.2.2 to 1.2.3 (#7045)
Bumps [@radix-ui/react-scroll-area](https://github.com/radix-ui/primitives) from 1.2.2 to 1.2.3.
- [Changelog](https://github.com/radix-ui/primitives/blob/main/release-process.md)
- [Commits](https://github.com/radix-ui/primitives/commits)

---
updated-dependencies:
- dependency-name: "@radix-ui/react-scroll-area"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-27 17:51:19 +04:00
dependabot[bot]
26edb8275e chore(deps-dev): bump esbuild from 0.17.19 to 0.25.0 (#7043)
Bumps [esbuild](https://github.com/evanw/esbuild) from 0.17.19 to 0.25.0.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG-2023.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.17.19...v0.25.0)

---
updated-dependencies:
- dependency-name: esbuild
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-27 17:50:57 +04:00
dependabot[bot]
e15e31e3cb chore(deps): bump vitest from 2.1.8 to 2.1.9 (#7042)
Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 2.1.8 to 2.1.9.
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v2.1.9/packages/vitest)

---
updated-dependencies:
- dependency-name: vitest
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-27 17:50:41 +04:00
dependabot[bot]
d4247d52da chore(deps): bump next from 15.2.0 to 15.2.3 in /templates/monorepo-next (#7041)
Bumps [next](https://github.com/vercel/next.js) from 15.2.0 to 15.2.3.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v15.2.0...v15.2.3)

---
updated-dependencies:
- dependency-name: next
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-27 17:50:22 +04:00
shadcn
9d908ae6ca docs: add security.md 2025-03-27 16:59:19 +04:00
shadcn
883ad8cbc4 chore: create dependabot config 2025-03-27 16:50:16 +04:00
shadcn
074eed5605 feat(shadcn): extend styles (#7033)
* feat(shadcn): extend styles

* fix(shadcn): typecheck
2025-03-26 17:11:08 +04:00
shadcn
ca7fbc3b64 fix(v4): minor focus styles (#7030) 2025-03-26 13:03:23 +04:00
shadcn
b3b2fe2755 feat(shadcn): registry updates (#7016)
* feat(shadcn): registry updates

* tests: fix snapshots

* feat(shadcn): add new theme prop

* fix: handle theme for index

* tests(shadcn): fix

* docs(www): update registry item docs

* chore: add changeset

* docs: update theming docs
2025-03-26 13:03:10 +04:00
shadcn
1fcb318c56 feat: use latest cmdk version 2025-03-24 09:45:59 +04:00
shadcn
2a783175c5 docs: update tanstack start 2025-03-24 08:40:00 +04:00
Jack Herrington
69fc8e23cc fix: allow silent mode with npm on React 19 (#6965)
* fix: allow silent mode with npm on React 19

* chore: changeset

* style: format

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-03-20 13:02:18 +04:00
FatahChan
84ec2f6079 fix(v4): card - css syntax warning in tailwind v4 and vite (#6955)
when building using vite and tailwind vite plugin
this following warning appears 


```
rendering chunks (10)...warnings when minifying css:
▲ [WARNING] Unexpected ")" [css-syntax-error]
 grid-cols-\[1fr_auto\]:has(:is()){grid-template-columns:1fr
                                ^
```


this is fixed by complying to tailwind new way of writing data attribute documented  [here](https://tailwindcss.com/docs/hover-focus-and-other-states#data-attributes)

change

```
[data-slot=card-action]:
```
to 

```
data-[slot=card-action]:
```

resolves https://github.com/shadcn-ui/ui/issues/6930
2025-03-20 09:01:20 +00:00
shadcn
37e5192fe7 fix(shadcn): only add tw-animate-css if no tailwindcss-animate (#6972)
* feat(shadcn): fix existing tailwindcss-animate

* docs: changelog

* tests(shadcn): update snapshots
2025-03-19 15:35:59 +04:00
shadcn
205bfc637e feat(shadcn): replace tailwindcss-animate with tw-animate-css (#6968)
* feat(shadcn): replace tailwindcss-animate with tw-animate-css

* chore: changeset
2025-03-19 10:57:10 +04:00
shadcn
9eae13639c fix(shadcn): only show deprecated message for v4 (#6967)
* fix(shadcn): only show deprecated for v4

* chore: changeset
2025-03-19 10:00:05 +04:00
shadcn
c77ddfc8b7 fix: tailwind config 2025-03-18 13:59:28 +04:00
shadcn
516ed3d17e feat(www): add dashboard-01 (#6961)
* fix(v4): minor fixes

* fix: format

* feat(www): add dashboard-01 block

* chore: capture screenshots
2025-03-18 13:42:39 +04:00
shadcn
bbda8c0b5a fix(v4): minor fixes for dashboard (#6959)
* fix(v4): minor fixes

* fix: format
2025-03-18 11:28:42 +04:00
shadcn
d5be468d32 fix: meta 2025-03-17 22:39:47 +04:00
shadcn
9f094a13b9 fix: meta 2025-03-17 22:34:10 +04:00
shadcn
829ef0cbf6 feat(v4): move dashboard 2025-03-17 22:26:43 +04:00
shadcn
4ebfd6896f Merge branch 'main' of github.com:shadcn-ui/ui 2025-03-17 22:07:10 +04:00
shadcn
911c52022a feat(v4): dashboard demo 2025-03-17 22:07:02 +04:00
Yordan Iliev
61e21e3356 docs: fix typo in CSS selector (#6928)
There was a typo
2025-03-17 11:29:20 +00:00
shadcn
28d97b7fc1 fix: github link 2025-03-17 15:10:44 +04:00
Kian Bazza
5085e48241 feat(components): add origin-aware animations (#6945)
This PR adds origin-aware animations to the following components:

- Context menu
- Dropdown menu
- Hover card
- Menu bar
- Popover
- Select
- Tooltip

This is accomplished with the custom property `--radix-<component>-transform-origin`, exposed by Radix on the following components:

For more information on this custom property, see the Radix docs; context menu as an example: https://www.radix-ui.com/primitives/docs/components/context-menu#origin-aware-animations

You can see a side-by-side comparison in the following video:

https://github.com/user-attachments/assets/ad8d548b-eb8d-4818-acb4-73c7cdaecc3f
2025-03-17 11:04:00 +00:00
shadcn
b7afb5aa1e feat(v4): dashboard 02 (#6950)
* feat(v4): dashboard 02

* fix: lint
2025-03-17 15:00:23 +04:00
t.yang
a6e2d3672f fix(sidebar): update type SidebarContext -> SidebarContextProps (#6926)
Hey, I noticed that the original code triggers the `ts/no-redeclare` ESLint error due to the naming conflict between the `SidebarContext` interface and the `SidebarContext` component.

![image](https://github.com/user-attachments/assets/33e6a8de-02bd-43a0-8279-beac8b051602)

I think `ts/no-redeclare` is a pretty common ESLint rule, I renamed the interface to `SidebarContextProps` to avoid the conflict. This naming style is consistent with the `carousel` component: (0f6efb9769/apps/v4/registry/new-york-v4/ui/carousel.tsx (L24)).

Hope this makes sense!
2025-03-14 12:53:22 +00:00
JEM
0f6efb9769 fix(navigation-menu v4): 6888 - Remove "use client" directive (#6913)
Removes unnecessary "use client" directive from navigation menu components to simplify the code and avoid potential issues.

Co-authored-by: shadcn <m@shadcn.com>
2025-03-13 15:03:20 +04:00
shadcn
415b02b4bc docs: add dark mode changelog (#6918)
* docs: dark mode changelog

* docs: add base colors reference
2025-03-13 14:42:19 +04:00
shadcn
f1dd9c6903 feat: update dark mode colors (#6903)
* feat: update dark colors

* feat(v4): update dark mode colors

* fix

* fix

* fix: slate and stone mismatches

* feat(v4): update skeleton and switch colors

* feat(v4): add dashboard example

* fix(v4): update dashboard components

* fix: themes

* feat: update sonner

* feat(v4): update dashboard buttons

* fix: test new colors

* fix: build commands

* feat(v4): more color updates

* feat(v4): update theme selector

* fix(v4): minor component fixes
2025-03-13 13:06:08 +04:00
shadcn
abde54987b chore: create FUNDING.yml 2025-03-12 23:18:49 +04:00
shadcn
79f2498b28 docs(www): add auth section for registry (#6910) 2025-03-12 18:33:36 +04:00
Valentin Gavran
d999f803a8 fix(select): make select content scrollable if height is limited (#6681)
* fix(select): make select content scrollable if height is limited

Select content now becomes scrollable when the browser window height is too small to display the full menu. This improves usability on smaller screens.

Radix also supports the same behavior for other components. I will also submit PRs for the other components separately.

Added the following properties to the Select Content component:

- `max-h-[--radix-select-content-available-height]`
- `overflow-y-auto` & `overflow-x-hidden` instead of `overflow-hidden` (existed before)

* fix(select): make select content scrollable if height is limited

Select content now becomes scrollable when the browser window height is too small to display the full menu. This improves usability on smaller screens.

Radix also supports the same behavior for other components. I will also submit PRs for the other components separately.

Added the following properties to the Select Content component:

- `max-h-[--radix-select-content-available-height]`
- `overflow-y-auto` & `overflow-x-hidden` instead of `overflow-hidden` (existed before)

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-03-12 11:16:21 +04:00
Valentin Gavran
1d8fe41d64 fix(context-menu): make context menu scrollable if height is limited (#6682)
* fix(context-menu): make context menu scrollable if height is limited

Context menu content now becomes scrollable when the browser window height is too small to display the full menu. This improves usability on smaller screens.

Radix also supports the same behavior for other components. I will also submit PRs for the other components separately.

Added the following properties to the Context Menu Content component:

- `max-h-[--radix-context-menu-content-available-height]`
- `overflow-y-auto` & `overflow-x-hidden` instead of `overflow-hidden` (existed before)

* fix(v4): context menu

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-03-12 10:48:56 +04:00
Kasper Aamodt
33b6146fde docs(www): fix typo in site-header.tsx (#6897)
Fixed a small typo in the site-header.tsx
2025-03-10 17:41:00 +00:00
shadcn
1d55420629 docs(www): add callout for tailwind v3 2025-03-10 21:15:23 +04:00
shadcn
12d4cf2ab0 Merge branch 'main' of github.com:shadcn-ui/ui 2025-03-06 09:46:06 +04:00
shadcn
5466432b01 docs(www): update registry 2025-03-06 09:45:53 +04:00
Hichem Taboukouyout
f9e4991f15 Add @radix-ui/react-slot dependency to badge registry entry (#6841)
* Add dependency to badge registry entry

Added @radix-ui/react-slot as a dependency for the badge component in the registry. This ensures proper functionality and resolves potential missing dependency issues.

- Updated the "badge" registry entry by including "@radix-ui/react-slot" in its dependencies list.
- Fixed the missing newline at the end of the file for better formatting.

* Revert "Add dependency to badge registry entry"

This reverts commit d12ddaa511.

* Add Radix slot dependency to badge registry entry

Included @radix-ui/react-slot as a dependency for the badge component in the registry. This change ensures the component functions as intended and avoids potential runtime errors.

- Updated "badge" registry entry dependencies list.
- Fixed formatting by adding a missing newline at the file end.

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-03-05 20:33:53 +04:00
Denish Navadiya
67e7364b3c fix: registry-item-json link (#6485)
Co-authored-by: shadcn <m@shadcn.com>
2025-03-05 20:15:23 +04:00
shadcn
2f6c3e74bb fix(v4): use tailwind var 2025-03-05 16:58:06 +04:00
Valentin Gavran
a106fc5412 fix(dropdown-menu): make dropdown scrollable if height is limited (#6679)
* fix(dropdown-menu): make dropdown content scrollable if height is limited

Dropdown menu content now becomes scrollable when the browser window height is too small to display the full menu. This improves usability on smaller screens.

Radix also supports the same behavior with other components. I will also submit a PR for the other components separately.

* chore: build registry

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-03-05 16:51:46 +04:00
shadcn
19665adeed feat(shadcn): add --base-color flag (#6864) 2025-03-05 16:14:03 +04:00
omar2205
fc0e8c0c52 use type import in react-hook-form (#4183)
* use type import in react-hook-form

* fix(form): fix type and rebuild registry

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-03-05 15:34:13 +04:00
shadcn
c16c58d0f9 feat(shadcn): add --template flag (#6863)
* feat(shadcn): add --template flag

* chore: changeset

* fix: type
2025-03-05 15:13:34 +04:00
Kaikai
a3fe5074c1 feat(monorepo): use tailwindcss v4 in monorepo example (#6724)
* feat(monorepo): use tailwindcss v4 in monorepo example

* feat(shadcn): add monorepo tailwind detection

* feat: update default monorepo template

* fix: minor fixes

* chore(shadcn): changeset

* docs(www): update monorepo docs

* docs: updates

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-03-05 12:07:50 +04:00
shadcn
3baef994d7 feat(v4): add combobox with checkbox example (#6862)
* feat(v4): add combobox with checkbox example

* fix: remove unused checkbox

* fix: rounded
2025-03-05 11:21:07 +04:00
shadcn
a7b3dbf121 feat(www): site updates (#6854)
* feat(www): site updates

* fix: lint

* docs: add tailwind notice
2025-03-04 16:51:58 +04:00
shadcn
26dc03b545 fix: chart and input-otp lint errors (#6853) 2025-03-04 14:00:25 +04:00
shadcn
be3c1a9a98 chore: minor fixes for registry blocks (#6850) 2025-03-04 13:26:40 +04:00
shadcn
418b2d9e14 fix(v4): misc select and tabs fixes (#6836) 2025-03-03 11:56:29 +04:00
JEM
7eb77fb3b9 fix(navigation-menu): 6825 - Update open state styles and remove unused classes (#6827)
* fix(navigation-menu): 6825 - Update open state styles and remove unused classes

Adjusts navigation menu trigger open styles to apply opacity /50 only when not hover/focused.
Removes unused data-[active] and data-[active=true] classes.

Fixes #6825

* Adds data-[active=true] back to NavigationMenuLink component.

Includes text color changes for open/active states to improve UI consistency.

* v3 registry

* v4 registry
2025-03-03 11:56:15 +04:00
Bryan Lee
f759a25354 docs(www): update Tailwind v4 migration guide with CSS and React changes (#6813)
Co-authored-by: shadcn <m@shadcn.com>
2025-03-03 11:53:09 +04:00
JEM
0b288883d2 fix(sidebar, sidebar-16): 6651 - Resolve unnecessary vertical scroll (#6782)
* fix(sidebar, sidebar-16): 6651 - Resolve unnecessary vertical scroll

Includes "label" in registry dependencies for sidebar-16 components.
Adjusts sidebar and sidebar inset dimensions to eliminate unwanted scroll behavior.

Fixes #6651

* chore: build registry

* Add label component to registry and adjust sidebar styles

Adds 'label' component to the registry.
Corrects sidebar styles and layout for better responsiveness.

* fix(sidebar-09): Add missing Label component dependency

Ensures the Label component is included in the registry dependencies for sidebar-09 to prevent missing component errors.

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-03-02 15:33:09 +04:00
Christian Ivicevic
cf4ccb34e2 docs(www): mention to add suppressHydrationWarning in the dark mode docs for next (#5879)
Users have repeatedly run into hydration errors because they don't read the next-themes readme and don't pay attention to the shadcn/ui docs and miss that the `suppressHydrationWarning` prop must be added.

This commit mentions this explicitly and highlights the line in the snippet (as well as fixing the previously wrong highlighting).
2025-03-02 11:27:48 +00:00
shadcn
dc80a326c2 ci: fix stale bot 2025-03-02 15:24:05 +04:00
Lloyd Richards
92e5c7ab2c ci: fix up stale issue handler (#6457)
Co-authored-by: shadcn <m@shadcn.com>
2025-03-02 14:59:26 +04:00
shadcn
d44971b6c2 feat(v4): add products-01 block 2025-02-28 23:14:59 +04:00
shadcn
8539dd6eec fix(shadcn): do not add outline-ring for v3 (#6814)
* fix(shadcn): do not add ring if tailwind v3

* chore: changeset

* test(shadcn): update snapshots
2025-02-28 21:23:08 +04:00
shadcn
bc7df68620 feat(shadcn): install routes for next-pages, laravel and react-router (#6811)
* feat(shadcn): install routes for next-pages, laravel and react-router

* chore: changeset
2025-02-28 18:06:06 +04:00
迷渡
1832f258bd fix(shadcn): Remove duplicate spaces (#6696) 2025-02-28 17:19:28 +04:00
shadcn
e2730f7276 docs(www): update docs for cli, components.json and theming 2025-02-28 16:38:39 +04:00
shadcn
22ba26152a docs(www): update tanstack docs 2025-02-28 16:21:29 +04:00
shadcn
76d6a59f9f docs(www): update all framework docs (#6809)
* docs(www): update all framework docs

* docs(www): update Tailwind v4 docs
2025-02-28 15:53:04 +04:00
shadcn
3a2a87386f fix(v4): badge overflow 2025-02-28 15:44:04 +04:00
shadcn
1822d95883 docs(www): update docs for vite (#6807) 2025-02-28 14:30:10 +04:00
shadcn
f90f5148eb fix(v4): responsive for the demo (#6803)
* fix(v4): responsive

* fix: type

* fix(v4): remove the login link
2025-02-28 13:31:06 +04:00
shadcn
99b0a5ac90 fix(v4): remove login and sandbox links 2025-02-28 13:29:16 +04:00
shadcn
984cb2a1ea feat(v4): update default ring colors 2025-02-28 13:28:17 +04:00
shadcn
fed2bac1d9 Merge branch 'main' of github.com:shadcn-ui/ui 2025-02-27 15:51:17 +04:00
shadcn
1ebfcd7cd9 feat(registry): update sidebars 2025-02-27 15:51:05 +04:00
Keit Oliveira
535a7d9220 fix(form): avoid undefined message error as string (#6729)
Add validation to prevent converting `undefined` error messages to string in the `FormMessage` component.

This fix addresses issues that occur in complex validation structures, such as validating entire objects.

```ts
const formSchema = z.object({
  location: z.object({
    city: z.string().nonempty(),
    state: z.string().nonempty(),
    country: z.string().nonempty(),
  }).superRefine((data, ctx) => {
    ...
  });
```

```tsx
<FormField
  control={form.control}
  name="location"
  render={() => (
    <FormItem>
      <FormField
        control={form.control}
        name="location.city"
        render={({ field }) => (
          <FormItem>
            <FormLabel>City</FormLabel>
            <FormControl>
              <Input placeholder="Enter city" {...field} />
            </FormControl>
          </FormItem>
        )}
      />

      <FormField
        control={form.control}
        name="location.state"
        render={({ field }) => (
          <FormItem>
            <FormLabel>State</FormLabel>
            <FormControl>
              <Input placeholder="Enter state" {...field} />
            </FormControl>
          </FormItem>
        )}
      />

      <FormField
        control={form.control}
        name="location.country"
        render={({ field }) => (
          <FormItem>
            <FormLabel>Country</FormLabel>
            <FormControl>
              <Input placeholder="Enter country" {...field} />
            </FormControl>
          </FormItem>
        )}
      />

      <FormMessage />
    </FormItem>
  )}
/>
```
2025-02-26 20:35:01 +00:00
Cyrus Zei
e7f8cd4566 chore(www): update the user info to use example instead (#6766) 2025-02-26 20:47:23 +04:00
shadcn
8506977f83 chore: deprecate shadcn-ui (#6780)
* chore: deprecate shadcn-ui

* deps(shadcn-ui): remove unused dependencies

* fix: tests

* deps: bump version
2025-02-26 20:34:51 +04:00
shadcn
575c0214da feat(v4): minor component updates 2025-02-26 17:28:49 +04:00
shadcn
a1ab28bf58 Merge branch 'main' of github.com:shadcn-ui/ui 2025-02-25 16:00:45 +04:00
shadcn
190ae2dcd8 docs(www): link get started to installation 2025-02-25 16:00:19 +04:00
Fin Chen
d5920cc3c1 fix(www): extra semicolon of --radius (#6737) (#6762) 2025-02-25 15:51:38 +04:00
shadcn
89652889db docs(www): update tanstack start docs (#6765) 2025-02-25 15:51:19 +04:00
Pavi
57d15bb2d5 fix(docs): update monorepo docs (#6647)
This pull request includes a small change to the `templates/monorepo-next/README.md` file. The change corrects the import path for the `Button` component to reflect the correct directory structure.

* [`templates/monorepo-next/README.md`](diffhunk://#diff-4f9dc7da681b34ccf99bccdcb804625f61e47afc70a483548b3ae093b564e072L30-R30): Updated the import path for the `Button` component to `@workspace/ui/components/button`.
2025-02-23 07:35:26 +00:00
shadcn
779517a1d4 fix(shadcn): check for empty css vars (#6733)
* fix(shadcn): check for empty css vars

* chore: changeset
2025-02-22 13:44:13 +04:00
Pasquale Vitiello
b567f7a6c1 fix: class name typo (#6633)
Co-authored-by: shadcn <m@shadcn.com>
2025-02-22 13:43:57 +04:00
shadcn
839afa714f feat(shadcn): cache registry calls (#6732)
* fix(shadcn): cache registry calls

* chore: changeset
2025-02-22 13:21:16 +04:00
Aaron
32f0bc0de9 fix(select): make select placeholder text show as faded (#6055)
Use the [data-placeholder] data attribute supplied by radix-ui instead of the `placeholder` state selector, which doesn't do anything for buttons (afaict, which radix-ui renders `SelectTrigger` into).

Reference: https://www.radix-ui.com/primitives/docs/components/select#api-reference

Before:
![Screenshot from 2024-12-12 15-52-50](https://github.com/user-attachments/assets/106c4c44-d6b9-4513-b2a9-77814ae46b8b)

After:
![image](https://github.com/user-attachments/assets/b09556f7-e274-4918-90c4-32c5aa8773cc)
2025-02-22 08:17:56 +00:00
shadcn
7d2499c803 fix(v4): dark mode 2025-02-21 21:08:07 +04:00
shadcn
84b88440c3 fix(v4): login spacing 2025-02-21 21:05:52 +04:00
shadcn
a5122f9029 fix(shadcn): do not override existing vars (#6721)
* fix(shadcn): do not override existing vars

* test(shadcn): update snapshots

* chore: changeset
2025-02-21 20:58:02 +04:00
shadcn
3b90317e3c feat(v4): update cards 2025-02-21 20:44:09 +04:00
shadcn
9d7c7b8978 fix(shadcn): fallback style (#6720) 2025-02-21 20:19:59 +04:00
shadcn
957df8997c fix: misc fixes for v4 components (#6719)
* feat(v4): login tests

* feat(v4): fix button and toggle
2025-02-21 20:07:48 +04:00
shadcn
460240a86c chore: remove console 2025-02-21 19:58:09 +04:00
shadcn
bfffb08f42 fix(shadcn): issue with workspace config (#6712) 2025-02-21 15:18:06 +04:00
shadcn
5282332e52 feat(shadcn): do not ask if file is identical (#6711)
* feat(shadcn): do not ask if file is identical

* fix: add missing files
2025-02-21 15:04:19 +04:00
shadcn
3db8a07b3f feat(shadcn): default to cssVariables: true. add --no-css-variables option (#6707)
* feat(shadcn): default to css vars

* chore: changeset

* fix(shadcn): add command
2025-02-21 11:49:17 +04:00
shadcn
187959435e Merge branch 'main' of github.com:shadcn-ui/ui 2025-02-20 23:41:43 +04:00
shadcn
5953229417 fix(v4): input otp 2025-02-20 23:41:37 +04:00
Zach Warunek
d6159023ed fix(cli): monorepo cn import (#6530)
* fix monorepo cn import

* chore: changeset

* style(shadcn): format

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-02-20 23:41:21 +04:00
shadcn
b0774b0578 fix: slider and demo components 2025-02-20 23:03:39 +04:00
shadcn
7cefabbe98 fix: switch focus 2025-02-20 22:56:33 +04:00
shadcn
3740373f99 feat(v4): update colors (#6693)
* feat(v4): update colors

* fix: sonner button

* feat(shadcn): update base colors to oklch

* fix: button gaps

* fix: sidebar and chart

* feat: update ring colors

* feat(v4): neutral color and fixes

* fix: fonts

* chore: changeset

* fix: revert utils
2025-02-20 19:32:56 +04:00
David Leger
9c4419f249 docs: fix TanStack logo on dark mode (#6695)
Inherit logo color from font color so that it renders properly in dark mode.

### Before
<img width="939" alt="image" src="https://github.com/user-attachments/assets/66327284-354e-4f07-a87b-465c37bac6f3" />


### After
<img width="930" alt="image" src="https://github.com/user-attachments/assets/2cd0b22d-f8be-4993-976e-0b9751400bfc" />
2025-02-20 14:34:51 +00:00
shadcn
ea9b81594d docs(www): update link for vaul 2025-02-17 23:04:58 +04:00
shadcn
4810f744e3 fix(www): misc site fixes 2025-02-16 15:48:54 +04:00
shadcn
38c5fb4ace feat(www): update og (#6658)
* feat(www): update og

* fix: remove export
2025-02-15 14:06:30 +04:00
shadcn
f37425bdb0 feat(shadcn): use canary for create-next-app 2025-02-14 00:21:42 +04:00
Ajay Pawar
592ef33658 style-new-york/mode-toggle button fixed (#6575) 2025-02-12 20:05:58 +04:00
shadcn
1a6da427ff feat(shadcn): add internal_registryResolveItemsTree (#6626) 2025-02-12 16:49:58 +04:00
shadcn
bd8533bd26 (11/n) shadcn: filter out deprecated from --all (#6617)
* fix(shadcn): filter out deprecated from --all

* chore: changeset
2025-02-11 13:28:41 +04:00
Pálmi Þór Valgeirsson
202131cd7b chore(deps): Upgrade @antfu/ni to v23.2.0 (#6414)
* chore(deps): Upgrade @antfu/ni to v23.2.0

* chore: changeset

* test(shadcn): add bun.lock

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-02-11 12:46:53 +04:00
shadcn
7977975c9d fix(www): announcement icon color 2025-02-10 21:20:12 +04:00
shadcn
a23fec1c31 docs(www): typo 2025-02-10 21:12:25 +04:00
shadcn
2af2979cf4 docs(www): typo 2025-02-10 21:10:42 +04:00
HichemTech
aee53d90e2 Update calendar.mdx (#6501)
Expicitly define the version of react-date-picker
2025-02-10 15:43:28 +04:00
shadcn
1a68715048 Merge branch 'main' of github.com:shadcn-ui/ui 2025-02-10 12:00:15 +04:00
shadcn
34c99c1728 fix(www): spacing 2025-02-10 12:00:01 +04:00
shadcn
86642840e2 docs(www): update for tailwind v4 (#6608) 2025-02-10 11:43:03 +04:00
shadcn
fac0daac7b fix(www): code tabs (#6607) 2025-02-10 11:34:02 +04:00
shadcn
13fe24e1f8 docs(www): update introduction (#6605)
* docs(www): update introduction

* feat(www): update vercel cta

* docs(www): minor fixes
2025-02-09 20:43:49 +04:00
Long Zheng
1eb2d74d7c fix: rename sidebar cookie to be valid name (#6558)
* fix: rename sidebar cookie to be valid name

* fix: rename sidebar cookie to underscore

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-02-07 19:40:47 +04:00
Prateek (प्रतीक)
16d4d38f56 fix(tanstack): fix paths value in tsconfig and check for tanstack start in devDeps also (#6590)
* fix(docs): tanstack start guide fix the paths value in tsconfig

* fix(tanstack): check for @tanstack/start in devDependencies as well

* chore: changeset

* fix(shadcn): tanstack detection

---------

Co-authored-by: shadcn <m@shadcn.com>
2025-02-07 14:31:28 +04:00
shadcn
5234c46722 feat(shadcn): add support for TanStack Start (#6507)
* feat(shadcn): add TanStack Start support

* docs(www): add docs for TanStack Start

* chore: changeset
2025-02-06 22:34:16 +04:00
shadcn
f9037239af fix: v4 page 2025-02-06 20:42:21 +04:00
shadcn
14e4726400 feat: misc updates for icons and tooltip (#6584) 2025-02-06 16:44:40 +04:00
shadcn
9f4d65fc8f (9/n) shadcn: add warning for deprecated components (#6576)
* feat(shadcn): add deprecated components warning

* chore: changeset
2025-02-05 22:51:31 +04:00
shadcn
1e357cb20d (8/n) shadcn: default to new-york for v4 (#6574)
* feat(shadcn): handle radius for v4

* feat(shadcn): default to new-york for v4

* chore: changeset
2025-02-05 21:28:49 +04:00
shadcn
6339aaa315 (7/n) shadcn: improve focus-visible for all elements (#6573)
* feat: focus visible colors

* fix: lint

* fix: tabs
2025-02-05 17:49:20 +04:00
shadcn
e2caa3cd35 chore: add v4 to changeset ignore 2025-02-05 15:03:19 +04:00
shadcn
c74a094f14 (6/n) shadcn: handle registry for v4 (#6571)
* feat(shadcn): hotswap registry style for v4

* chore: changeset

* style(shadcn): remove unused import

* chore: registry

* fix(shadcn): cmon
2025-02-05 14:54:24 +04:00
shadcn
bfb5b6357e feat: add vercel analytics 2025-02-05 11:34:14 +04:00
shadcn
ac3d965c6e chore: remove unused code 2025-02-05 11:33:10 +04:00
shadcn
6e7cd11d68 fix(v4): charts 2025-02-05 11:31:50 +04:00
shadcn
a75b4ca80e fix: build 2025-02-05 11:17:48 +04:00
shadcn
475abbbb20 refactor: new-york-v4 2025-02-05 10:38:28 +04:00
shadcn
762cd73554 chore: build registry 2025-02-05 10:17:03 +04:00
shadcn
8c06932800 fix: debug build 2025-02-05 00:37:50 +04:00
shadcn
e516481394 (5/n) shadcn: migrate all components and blocks (#6567)
* feat: add v3

* feat: upgrade lucide-react

* feat: upgrade components to Tailwind v4

* feat(v3): add dark mode

* wip

* feat: components upgrade

* style: format

* feat: add select

* feat: more components

* feat: more components

* fix: shadow

* feat: upgrade sidebar

* refactor: registry

* refactor: internal

* fix: registry

* fix: charts

* chore: build registry

* fix: charts

* feat: form

* feat: clean up

* fix: icons

* fix: command demo

* chore: add new-york-v4 to registry

* fix: revert command in www registry

* fix

* chore: fix tests

* fix: types

* fix: lint errors

* chore: build v4 registry

* fix

* fix: types
2025-02-05 00:15:07 +04:00
shadcn
d1eb24e23a (4/n) shadcn: fix handling of sidebar colors (#6515)
* fix(shadcn): background, foreground and sidebar colors

* chore: changeset

* ci: update artifact
2025-01-30 22:57:57 +04:00
shadcn
9a14c1d092 (3/n) shadcn: tailwind config (#6490)
* feat(shadcn): add tailwind version detection

* chore: changeset

* feat(shadcn): css vars for tailwind v4

* fix(shadcn): handle color space

* fix(shadcn): add oklch support

* feat(shadcn): handle single quote

* feat(shadcn): update tailwind config

* feat(shadcn): add keyframes

* feat(shadcn): add animation vars

* fix: var name

* fix(shadcn): handle color values

* feat(shadcn): handle radius

* feat(shadcn): clean up formatting

* feat(shadcn): update next clean up function

* chore: changeset

* feat(shadcn): fix formatting for v3 and v4

* test(shadcn): update snapshots

* fix(shadcn): update tailwind version handling
2025-01-30 11:59:47 +04:00
shadcn
5ef2bc5f45 (2/n) shadcn: css vars for tailwind v4 (#6487)
* feat(shadcn): add tailwind version detection

* chore: changeset

* feat(shadcn): css vars for tailwind v4

* fix(shadcn): handle color space

* fix(shadcn): add oklch support

* feat(shadcn): handle single quote

* chore: add changeset
2025-01-30 11:55:22 +04:00
shadcn
8f6a64f176 (1/n) shadcn: add tailwind version detection (#6478)
* feat(shadcn): add tailwind version detection

* chore: changeset
2025-01-30 11:49:09 +04:00
Boby Tiwari
e85920c191 Update blocks.mdx (#6477) 2025-01-28 16:25:24 +04:00
github-actions[bot]
c8c4027b6b chore(release): version packages (#6349)
* chore(release): version packages

* chore(release): version packages

* chore: fix version

* deps: update lock file

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2025-01-28 15:26:05 +04:00
shadcn
699195ba77 deps(shadcn): remove unused lodash.template (#6475)
* deps(shadcn): remove unused lodash.template

* chore: changeset
2025-01-28 15:13:39 +04:00
shadcn
9643db42cf feat: add docs for registry (#6380)
* chore: 2.2.0-canary.2

* feat: add docs for registry

* docs(www): update registry docs

* fix: update dep

* docs(www): update docs

* docs(www): update registry docs

* feat: add new label

* fix: lint
2025-01-28 15:06:22 +04:00
JEM
dd71498762 feat(sidebar blocks): adds sidebar-16 block with components and styles (#5889)
Introduces a new sidebar-16 block with an inset sidebar and site header navigation.
Includes components for main navigation, projects, secondary navigation, and user menu.
Updates registry and scripts to include the new sidebar block.

Addresses: #5629

![image](https://github.com/user-attachments/assets/769148aa-ec83-46f4-b4f0-77947e253d28)
![image](https://github.com/user-attachments/assets/38532b4d-21f6-4ce1-9e92-08edc4f72e46)
2025-01-27 12:40:45 +00:00
Jordan Cruz-Correa
ddf761e802 feat: add oklch color format support for /colors (#6441) 2025-01-24 17:53:45 +04:00
shadcn
5f7957ab51 feat(shadcn): add new registry:file type (#6377)
* feat(shadcn): add new registry:file type

* chore: add changeset

* fix: file target
2025-01-16 15:46:33 +04:00
shadcn
f07c7ad5d0 feat(shadcn): handle nested paths for components (#6369)
* feat(shadcn): handle nested paths for components

* chore: add changeset
2025-01-15 18:01:44 +04:00
shadcn
d5aa527f0b docs(www): add block preview image 2025-01-15 15:14:12 +04:00
shadcn
5ec990a474 docs(www): add blocks contribution docs (#6354)
* docs(www): add blocks contrib docs

* docs(www): update intro

* feat: update banner

* docs: add link

* docs: update block types
2025-01-14 21:56:45 +04:00
shadcn
cb742e9825 feat: add new registry build command (#6350)
* feat: implement shadcn/registry

* feat: add schema field

* fix: import

* chore: add changeset

* chore: remove console

* fix: tests

* fix: diff command

* feat: move to schema/registy-item.json

* fix

* ci: switch to node 20

* ci: build packages

* fix: types

* chore: update schema

* chore: update build registry script

* feat(shadcn): add build command
2025-01-14 15:59:41 +04:00
shadcn
254198b4bf feat: add shadcn/registry (#6339)
* feat: implement shadcn/registry

* feat: add schema field

* fix: import

* chore: add changeset

* chore: remove console

* fix: tests

* fix: diff command

* feat: move to schema/registy-item.json

* fix

* ci: switch to node 20

* ci: build packages
2025-01-14 10:50:19 +04:00
shadcn
1081536246 fix: path 2024-12-20 19:12:22 +04:00
shadcn
811bb59a8f feat(shadcn): monorepo support (#6104) 2024-12-20 19:07:17 +04:00
shadcn
ea677cc74e fix: open in v0 2024-12-17 23:14:59 +04:00
github-actions[bot]
9253b43f29 chore(release): version packages (#6094)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-12-16 23:56:28 +04:00
shadcn
c8fda09a63 feat(cli): detect and use next version (#6093)
* feat: detect and use next version

* chore: changeset
2024-12-16 23:53:40 +04:00
shadcn
1ff01b1bb5 fix(www): adjust reading width 2024-12-16 12:43:11 +04:00
shadcn
f10d59fee9 fix(www): themes page 2024-12-16 12:26:48 +04:00
shadcn
2f869a2590 feat(www): code blocks package manager (#6075)
* feat(www): code blocks

* fix: code style
2024-12-14 19:13:06 +04:00
LiuJie
102b0b0c62 fix: calendar icon components' props not use. (#5222)
* fix: calendar icon components' props not use.

* fix: calendar icon components' props not use.

* style: revert the original className order

* fix: calendar icon components' props not use.

---------

Co-authored-by: shadcn <m@shadcn.com>
2024-12-14 15:16:52 +04:00
Ahad Rizvi
387756c4ab Remove unused imports from shadcn chart (#4391)
* Remove unused imports from shadcn chart

* chore: rebuild registry

---------

Co-authored-by: shadcn <m@shadcn.com>
2024-12-14 15:03:01 +04:00
shadcn
05145e66d3 feat: refactor registry (#6071)
* feat(www): add login blocks

* chore(www): restructure for blocks

* chore: build registry

* chore: clean up chunks

* fix(www): chart categories

* feat(www): big registry refactor

* feat(www): update blocks

* feat: complex blocks

* fix: update schema

* feat: sync new-york and default

* fix: lint

* feat: move charts

* fix(www): code

* fix: src path

* chore: rebuild registry

* fix: screenshot

* fix: set new-york as default
2024-12-14 14:52:55 +04:00
shadcn
704991247c fix: ui imports for open in v0 (#6029) 2024-12-10 14:20:50 +04:00
github-actions[bot]
729b9ec8ca chore(release): version packages (#5812)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-12-10 12:17:32 +04:00
Jens Astrup
a1bed464f3 chore(apps): Update lodash (#4397)
* chore(apps): Refactor usage of lodash.template to lodash to address security vulnerability

* chore(cli): Refactor usage of lodash.template to lodash to address security vulnerability

* deps: update lock

* chore: changesets

* style: fix format

* fix: import

* chore: build registry

---------

Co-authored-by: shadcn <m@shadcn.com>
2024-12-09 12:33:28 +04:00
shadcn
805ed4120a feat(www): refactor examples page (#5818) 2024-11-13 16:01:14 +04:00
shadcn
600a593c87 docs(www): update manual installation (#5817) 2024-11-13 15:42:52 +04:00
Braden Corbold
500dbe2664 fix(shadcn) arrays and nested deeply nested spread (#5711)
* fix: tailwind config updater parser

* fix: remove quote around spread element

* fix: specify deepmerge option for array

* fix(shadcn): Nested and spread array elements

* add test case for boolean primitive

---------

Co-authored-by: matsuyoshi30 <sfbgwm30@gmail.com>
Co-authored-by: shadcn <m@shadcn.com>
2024-11-13 15:19:21 +04:00
JEM
c577ee0666 docs(contributing): add CLI usage instructions (#5807)
Introduce a detailed workflow for running the CLI locally, ensuring contributors can easily test and develop enhancements in their local environment. This addition helps maintain consistency between CLI and component updates.
2024-11-13 15:17:11 +04:00
shadcn
d5bf0018fd fix(shadcn): handling of tsconfig aliases (#5813)
* fix(shadcn): handling of tsconfig aliases

* chore: add changeset
2024-11-13 15:15:22 +04:00
Tobbe Lundberg
fb36ca4159 fix(transform): Support aliases that are longer than one character (#5678)
* fix(transform): Support aliases that are longer than one character

* feat(shadcn): update handling of aliases

* chore: add changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2024-11-12 22:13:38 +04:00
JEM
824a35ada1 test(snapshots): update test snapshots for consistency (#5801)
Updated snapshot components to use `React.ComponentProps` instead of custom interfaces for `input` and `Dialog` components. This simplifies the code by leveraging built-in React types, ensuring consistency and reducing potential errors arising from custom definitions.
2024-11-12 12:54:31 +04:00
shadcn
8d520c8d49 fix(www): figma link (#5798) 2024-11-11 20:08:24 +04:00
Temkin Mengsitu
0873835339 fix: ensure block component name is copied in shadcn (#5790) 2024-11-11 12:10:04 +04:00
JEM
4a0d4cfdb9 refactor(components): remove redundant empty interfaces from Input, Command, and Textarea components (#5657)
* refactor(components): remove redundant empty interfaces from Input, Command, and Textarea components

Simplified props handling by removing redundant empty interfaces (`InputProps`, `CommandDialogProps`, `TextareaProps`). Directly extended native HTML attributes/lib for each component, enhancing code clarity and maintainability. This refactor ensures compliance with ESLint rules and streamlines future modifications without altering component functionality.

* updated the registry

* rerun build:registry with updated command

* Refactor input and textarea components to use `React.ComponentProps`

* update registry
2024-11-08 20:26:01 +04:00
shadcn
c4c5d8d419 feat(www): update next-themes 2024-11-08 15:18:32 +04:00
Wing Chung Ng
9253682b87 refactor(www): update ThemeProviderProps type extraction for next-themes v0.4.0 compatibility (#5701)
Since next-themes v0.4.0 no longer provides types in `dist`, replaced the import of `ThemeProviderProps` from `next-themes/dist/types` with a new type extraction using `React.ComponentProps`. This change ensures continued type safety and compatibility with the updated library version.

Co-authored-by: shadcn <m@shadcn.com>
2024-11-08 15:16:10 +04:00
shadcn
c7cd16a637 fix(www): interactive chart 2024-11-07 21:36:19 +04:00
shadcn
eff1918d41 fix: update file handling 2024-11-07 21:21:42 +04:00
shadcn
366d6b656b fix(www): file tracing 2024-11-07 21:05:44 +04:00
shadcn
e489c5e08e fix(www): file tracing 2024-11-07 20:54:26 +04:00
shadcn
d87003e0a4 fix(www): sidebar 2024-11-07 20:40:18 +04:00
shadcn
a8633075f7 fix(www): component source 2024-11-07 20:36:21 +04:00
shadcn
432d5e6e28 fix: code view for mdx 2024-11-07 17:45:34 +04:00
shadcn
8f0c26f22a feat(www): code for blocks (#5756)
* feat: update blocks

* fix: scrollbars

* fix: code viewer

* test(shadcn): fix
2024-11-07 17:09:41 +04:00
shadcn
149b321c1b fix: lint 2024-11-06 17:34:21 +04:00
shadcn
c1ae5a57cc feat(www): nav color 2024-11-06 17:29:53 +04:00
shadcn
b8ed303d8c Merge branch 'main' of github.com:shadcn-ui/ui 2024-11-06 17:19:41 +04:00
shadcn
13c97acf9f fix: font size 2024-11-06 17:16:21 +04:00
shadcn
bed277c54d feat( www): minor updates (#5749)
* feat(www): update mode switcher

* feat(www): update layout

* feat(www): update theme-color handling

* fix(www): docs pages
2024-11-06 17:03:28 +04:00
github-actions[bot]
f7c42169a6 chore(release): version packages (#5733)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-11-06 00:19:13 +04:00
shadcn
2c2fe97eb9 feat: move new-york to lucide-react (#5602)
* feat: move new-york to lucide-react

* fix: mail open

* chore: update registry

* chore: add test:dev

* chore: add changeset

* feat: build an icon registry

* chore: add missing registry icons

* feat: add an icons debug page

* feat: add an icon migration

* chore(www): migrate all radix icons to lucide

* feat: update migration script

* chore: update changeset

* feat(shadcn): implement icons transformer

* fix: missing registry icons

* fix(shadcn): handling of missing icons

* feat: add support for multiple libraries
2024-11-06 00:00:41 +04:00
shadcn
d64374d009 fix(www): chart colors 2024-11-04 23:06:14 +04:00
github-actions[bot]
e24e51a2fa chore(release): version packages (#5709)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-11-04 17:25:59 +04:00
shadcn
cdfecd1d97 Revert "feat: remove npm flags" (#5707)
* Revert "feat: remove npm flags (#5686)"

This reverts commit 4ff64ba818.

* chore: temporarily bring back flag
2024-11-04 17:14:08 +04:00
manfromexistence04
2c043e709f fix: svg props casing to camelCase (#5691) 2024-11-03 19:27:28 +04:00
Ghribi Ouassim
aed19aa911 docs(www): added --all option to add command in cli docs page (#5591) 2024-11-03 14:37:08 +04:00
shadcn
9e35d229ae feat: www updates (#5688)
* feat: www updates

* fix: lint
2024-11-03 14:35:04 +04:00
shadcn
db1975ef4d Merge branch 'main' of github.com:shadcn-ui/ui 2024-11-03 13:27:19 +04:00
shadcn
961e0b62d7 fix: a11y for card and calendar 2024-11-03 13:27:10 +04:00
github-actions[bot]
70c684c224 chore(release): version packages (#5687)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-11-03 12:17:58 +04:00
shadcn
4ff64ba818 feat: remove npm flags (#5686)
* docs: update status table and docs

* feat(shadcn): remove react-19 check

* chore: add changeset
2024-11-03 12:12:41 +04:00
shadcn
500a353816 feat: update home page (#5648) 2024-10-30 21:28:58 +04:00
Nicholas Lim
c830780d62 docs(www): fix diff for peerDependencies (#5640)
Co-authored-by: shadcn <m@shadcn.com>
2024-10-30 17:23:06 +04:00
Felix Lu
debd51a854 refactor(sidebar): improve setOpen callback logic (#5593)
* refactor(sidebar): improve setOpen callback logic
- Simplify state handling
- Ensure consistent cookie setting
- Added ability for users to persist sidebar state via cookies
- Update sidebar.mdx doc with SSR persistence instructions
- Run pnpm registry:build to update component

* docs: updates

---------

Co-authored-by: shadcn <m@shadcn.com>
2024-10-30 17:09:09 +04:00
shadcn
78426dd862 docs: fix diff 2024-10-30 16:31:44 +04:00
shadcn
6e47a94a8f chore: format 2024-10-30 15:40:46 +04:00
Barinderpreet Singh
ab6a856930 Docs: update vite installation docs (#4741)
* docs: update vite installation docs

* Update content config

---------

Co-authored-by: shadcn <m@shadcn.com>
2024-10-30 15:37:32 +04:00
shadcn
b33d3868e9 docs(www): update status for radix icons (#5638) 2024-10-30 11:29:48 +04:00
Maou
9e0a86122a fix(docs): resolve link issue in documentation pages (#5633)
Updated broken link in documentation routing file. 
This ensures that the correct content is loaded based on the slug.
2024-10-30 07:10:15 +00:00
github-actions[bot]
2b276de95a chore(release): version packages (#5625)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-29 21:39:58 +04:00
shadcn
64739f8399 feat: react 19 (#5621)
* feat(shadcn): add flag prompt for npm

* docs: add docs for react 19

* chore: add changeset

* test: update snapshots

* docs: add notes for recharts

* docs: fix

* fix

* fix: linting
2024-10-29 21:30:05 +04:00
shadcn
f0cff7e0eb fix: gaps in command and dropdown-menu (#5570)
* fix: gaps in command and dropdown-menu

* chore: update snapshots
2024-10-25 18:13:13 +04:00
github-actions[bot]
e242adaa9c chore(release): version packages (#5568)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-25 17:52:32 +04:00
Kiyan
986c00ee0e fix: shadcn init with correct packageManager (#5299)
* fix: shadcn init with correct  packageManager

* chore: changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2024-10-25 17:46:48 +04:00
shadcn
d0eece06d4 fix: update registry (#5530) 2024-10-23 17:35:26 +04:00
github-actions[bot]
0a0a566a4e chore(release): version packages (#5526)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-23 11:35:28 +04:00
Braden Corbold
bf5a79c4d4 fix(shadcn): fix transformRsc to account for ' (#5518)
* fix(shadcn): fix transformRsc to account for '

* chore: add changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2024-10-23 11:33:11 +04:00
shadcn
f02b412478 fix(shadcn): temporarily pin create-next-app (#5525)
* feat: temporarily pin create-next-app

* chore: add changeset
2024-10-23 11:30:29 +04:00
DADDOU Mohamed El Amine
0d31293c7b docs: add missing installation step in the sidebar documentation (#5467) 2024-10-22 12:15:03 +04:00
Jacob Paris
3d1d19fc1b fix(sidebar): only apply text-sidebar-foreground to sidebar (#5491)
The text-sidebar-foreground class was applied to the SidebarProvider, which is designed to wrap the whole app, therefore making the whole app inherit its font color. This has been removed. The correct place for it is in the Sidebar component

Of the 3 possible return cases in the Sidebar component, 2 already applied the text-sidebar-foreground and I have added it to the third
2024-10-22 08:02:20 +00:00
BNaushad
e5b56c84a9 docs(sidebar): fix typo in sidebar documentation (#5487) 2024-10-22 11:42:38 +04:00
shadcn
630afe836e fix: sidebar provider 2024-10-21 12:38:51 +04:00
Jakob Ortmann
52c12bc27a fix import in sidebar example (#5438) 2024-10-21 11:46:27 +04:00
JEM
182f2083cd docs(sidebar): Fix sidebar toggle text for consistent behavior (#5428) 2024-10-21 11:45:11 +04:00
Phaired
3febcdc523 docs: fix type in sidebar.mdx (#5452) 2024-10-21 11:43:35 +04:00
EdamAmex
ced2513137 docs: fix prop name (#5460) 2024-10-21 11:43:08 +04:00
shadcn
93ae8bd67f chore: deprecate next-template (#5478)
* chore: deprecate next-template

* chore: tests
2024-10-21 11:40:54 +04:00
shadcn
3259fb7ca1 fix: overflow on icon 2024-10-19 01:28:07 +04:00
shadcn
d8397d80a8 chore: rebuild registry 2024-10-18 23:25:49 +04:00
shadcn
06e74fce78 Merge branch 'shadcn/sidebar-tsx'
# Conflicts:
#	apps/www/public/r/styles/default/use-mobile.json
#	apps/www/public/r/styles/new-york/button.json
#	apps/www/public/r/styles/new-york/dropdown-menu.json
#	apps/www/public/r/styles/new-york/use-mobile.json
#	apps/www/registry/new-york/ui/button.tsx
#	apps/www/registry/new-york/ui/dropdown-menu.tsx
2024-10-18 23:14:27 +04:00
shadcn
bc9e5eaaab test: fix 2024-10-18 22:52:25 +04:00
shadcn
c9b69d0836 docs: remove beta 2024-10-18 22:22:25 +04:00
shadcn
539212c49e feat: add redirect 2024-10-18 15:29:28 +04:00
shadcn
123887c36c fix: blocks 2024-10-18 00:54:19 +04:00
shadcn
35c1ba57c2 feat: add login-01 to v0 2024-10-18 00:34:03 +04:00
shadcn
b34516f471 fix: lint 2024-10-17 22:59:23 +04:00
shadcn
66b95402c1 feat: add v0 registry blocks 2024-10-17 22:58:20 +04:00
shadcn
5460177a7a fix: sidebar-07 2024-10-17 19:49:28 +04:00
shadcn
b0049c2266 fix: data-name 2024-10-17 17:13:47 +04:00
shadcn
4e6e21f094 fix: dark mode blocks 2024-10-17 17:01:24 +04:00
shadcn
3b808c83be fix: lint 2024-10-17 16:33:34 +04:00
shadcn
0e6b37e99a feat: update preview for mobile 2024-10-17 16:28:09 +04:00
shadcn
9ec433838f fix: lint 2024-10-17 01:11:00 +04:00
shadcn
444ff70590 feat: add notice 2024-10-17 01:06:35 +04:00
shadcn
27bc5deff1 docs: beta testers 2024-10-17 00:55:28 +04:00
shadcn
cacd7c8798 fix: use-mobile 2024-10-17 00:36:50 +04:00
shadcn
f227f93742 fix: sidebar 2024-10-17 00:34:50 +04:00
shadcn
87e099a3d7 feat: update button and dropdown menu (#5408) 2024-10-17 00:21:03 +04:00
shadcn
303d65718c chore: registry updates 2024-10-16 23:58:44 +04:00
shadcn
909219df14 docs 2024-10-16 15:33:16 +04:00
shadcn
e8ada4e3c7 docs 2024-10-16 14:33:43 +04:00
shadcn
8fc80836ff docs 2024-10-16 12:54:21 +04:00
shadcn
d0a308cc64 fix: edit in v0 2024-10-16 11:12:58 +04:00
shadcn
e461c02389 feat: update open in v0 2024-10-15 21:28:38 +04:00
shadcn
50c2f6045a chore: fix lint 2024-10-15 12:52:40 +04:00
shadcn
14aca65eee docs: add sidebar docs 2024-10-15 12:49:22 +04:00
shadcn
14c952b594 chore: update registry 2024-10-15 12:41:20 +04:00
shadcn
1e9434e6f9 chore: build registry 2024-10-15 12:38:45 +04:00
shadcn
f3d14c48cb feat(www): update button and tooltip 2024-10-15 12:38:32 +04:00
shadcn
c668c35bb9 feat(www): add sidebar components 2024-10-15 12:37:47 +04:00
shadcn
1297abc882 fix: v0 2024-10-07 21:13:33 +04:00
shadcn
36ebbf26dc docs(www): update figma 2024-09-29 14:52:52 +04:00
github-actions[bot]
a2abc4ad95 chore(release): version packages (#4963)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-27 22:10:05 +04:00
Thomas Raffray
4b546bfb13 fix(cli): remix detection (#4972)
# What

Some remix templates doesn't package a `vite.config.*` file at their root.
It's the case for the recommended starter "stack" templates: blues-stack, indie-stack and grunge-stack.
As recommended in a TODO comment, it's more suitable to check for a `@remix-run/*` dependency in the package dependencies.

# How

- decouple vite and remix checks
- retrieve the `package.json`
- allow passing a `cwd` to the retrieval method
- remove the "empty config file list" that can be empty for a remix stack
- check that the `package.json` contains a `@remix-run/*` dependency

# Test

Added a fixture by running `npx create-remix@latest --template remix-run/indie-stack` in the [frameworks](/Fluf22/shadcn-ui/tree/fix/cli-remix-detection/packages/cli/test/fixtures/frameworks) folder and named it `remix-indie-stack`, if ever we want another stack as a fixture later

---

Fixes shadcn-ui/ui#4967
2024-09-27 17:58:46 +00:00
shadcn
5fc9ade413 chore(cli): add deprecation notice (#4988)
* feat(cli): add deprecation message

* chore: changesets
2024-09-27 17:43:16 +04:00
Nami Sunami
96880e7c9a fix: Fix the typo in error messages (component.jsoncomponents.json) (#4977)
* fix(prompt): fix error message, component.json -> components.json

* fix(config): fix the error message, component.json -> components.json

* chore: changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2024-09-27 16:01:04 +04:00
Artem Zakharchenko
7dfdb029e7 use "?url" suffix in "tailwind.css" import (Remix) (#4945)
Importing `tailwind.css` is incorrect as it will treat that file as a CSS Module, throwing that it has no `default` export. 

Instead, the tutorial relies on the import returning a _URL_ to the stylesheet. Adding `?url` to the import specifier is the way to go.
2024-09-26 12:42:49 +00:00
shadcn
28f34ed3c3 feat(shadcn): recursively resolve registry dependencies (#4961)
* feat(shadcn): recursively resolve registry dependencies

* chore: add changeset

* ci: update actions/upload-artifact
2024-09-25 22:56:39 +04:00
github-actions[bot]
bd54184e60 chore(release): version packages (#4938)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-23 15:21:55 +04:00
Braden Corbold
ce3adfa075 fix(shadcn): Support single quote formatted registry files (#4870) (#4871) 2024-09-23 11:47:37 +04:00
Shivang Rathore
674807c1b4 fix(shadcn): Ensure .scss files are considered in init command (#4866)
Co-authored-by: shadcn <m@shadcn.com>
2024-09-23 11:44:27 +04:00
sapenlei
c62167a449 fix(shadcn): default next styles are not completely cleared (#4922)
* fix(shadcn):  default next styles are not completely cleared

* chore: add changeset

* fix(shadcn): tests

---------

Co-authored-by: shadcn <m@shadcn.com>
2024-09-23 11:38:59 +04:00
github-actions[bot]
061083006f chore(release): version packages (#4857)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-15 13:40:31 +04:00
Jack Herrington
1af66c2d08 Adding support for ~ in target specification (#4848)
* Adding support for ~ in target specification

* test(shadcn): add a test for srcDir false

* chore: changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2024-09-15 13:27:48 +04:00
shadcn
0993d98cc7 ci: update stale config (#4858) 2024-09-15 13:25:06 +04:00
Hichem Fantar
52d223393a (fix Input) choose file text color in dark mode (#4843)
This pull request fixes the issue with the choose file text color in dark mode. The changes ensure that the text color is correctly displayed in dark mode.

the reason this bug doesn't happen in the shadcn website is because it sets `color-scheme:dark` on the document;

this fix makes sure this always works even if color scheme isn't set.

Closes #4842

![image](https://github.com/user-attachments/assets/37cb3f2a-c1a7-49b3-8ef1-77823dd7bd45)

![image](https://github.com/user-attachments/assets/92913fec-5651-4cfc-8e16-2f12c06c33b8)
2024-09-15 09:20:19 +00:00
Shivang Rathore
207b69fe8d fix(cli): Ensure .scss files are considered in getTailwindCssFile (#4797)
* fix(cli): Ensure .scss files are considered in getTailwindCssFile

- Updated getTailwindCssFile function to include .scss files when checking for Tailwind CSS configuration.
- This change ensures that .scss files are properly identified and handled, improving compatibility with projects using SCSS.

* chore: add changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2024-09-15 12:55:08 +04:00
Rana Haris Ali
408760a93b fix: correct grammar in "path does not contain a package.json" message (#4815)
* fix: correct grammar in "path does not contain a package.json" message

* chore: add changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2024-09-15 12:51:23 +04:00
Devansh Mahant
a9ab7afebf Fix Incorrect Hook Import Path in Toast Component Example in ShadCN Docs (#4811)
#### Summary:
This pull request addresses a documentation error found in the ShadCN website's Toast component example. Specifically, the import route for the hook is incorrect in the example. and fixes [#4816](https://github.com/shadcn-ui/ui/issues/4816)

#### Issue:
Upon reviewing the [ShadCN Toast documentation](https://ui.shadcn.com/docs/components/toast), I found that the import path for the Toast component hook was wrongly mentioned as being located in the `components` folder. According to the `component.json` file, the correct location of the hook is within the `hooks` folder inside the main directory.

#### Fix:
- Corrected the import path in the Toast component example from `components` to `hooks`, as per the `component.json` file structure.

#### Example of Fix:
**Before:**
```js
import { useToast } from "@/components/use-toast";
```

**After:**
```js
import { useToast } from "@/hooks/use-toast";
```

#### Testing:
- Verified that the corrected path resolves correctly.
- Ensured the example works as expected after the change.

#### Impact:
This fix prevents confusion for users following the example and ensures that the import path accurately reflects the project structure, improving the overall developer experience.
2024-09-15 08:45:29 +00:00
Quinn Blenkinsop
b6221ea524 fix(www): update broken link to headless ui (#3542)
The link appears to have broken at some point, I've updated it

Co-authored-by: shadcn <m@shadcn.com>
2024-09-15 12:31:28 +04:00
github-actions[bot]
9ef7967b0d chore(release): version packages (#4821)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-12 17:54:41 +04:00
shadcn
64b2f1a5ad feat(shadcn): add experimental docs (#4820)
* feat(shadcn): add cli docs

* chore: add changeset

* fix: tests
2024-09-12 17:51:59 +04:00
github-actions[bot]
f4ca57a79c chore(release): version packages (#4788)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-09 12:34:19 +04:00
shadcn
99ff9caf71 fix(shadcn): add src to content in tailwind config (#4787)
* feat(shadcn): handle src dir

* chore: changeset
2024-09-09 12:32:12 +04:00
github-actions[bot]
cd9a55b76a chore(release): version packages (#4777)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-07 23:42:29 +04:00
shadcn
49373eed96 fix(shadcn): better error handling (#4776)
* fix(shadcn): better error messages

* chore: changeset
2024-09-07 23:35:37 +04:00
shadcn
078dfe6607 docs(www): Open in v0 docs (#4734)
* feat(www): open in v0

* feat: update copy

* fix: sidebar link

* fix(tests): snapshots
2024-09-04 00:37:57 +04:00
xuxucode
77fc5ec8db Fix use-toast module path (#4728) 2024-09-03 18:37:11 +00:00
github-actions[bot]
cfba3fdf70 chore(release): version packages (#4730)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-09-03 22:22:26 +04:00
adrianhelvikspond
4e4118f3cf Fix init command for default style - fixes #4722 (#4724)
* Fix init command for default style

The empty dependency string was tripping up package managers.

* fix(www): registry dependencies for default

---------

Co-authored-by: shadcn <m@shadcn.com>
2024-09-03 22:21:51 +04:00
shadcn
faa7a67fb3 fix(shadcn): init with src (#4731)
* fix(shadcn): init with src

* chore: add changesets
2024-09-03 22:16:59 +04:00
shadcn
701e1160ea feat(shadcn): add support for src dir (#4729)
* feat(shadcn): add support for src dir

* chore: add changesets
2024-09-03 21:47:15 +04:00
shadcn
f5931f8d09 docs(www): update installation docs (#4725) 2024-09-03 16:41:48 +04:00
shadcn
5a28937c6e Merge branch 'main' of github.com:shadcn/ui 2024-09-03 16:35:51 +04:00
shadcn
0b74059d38 docs(www): update laravel docs 2024-09-03 16:35:36 +04:00
shadcn
fab9877586 fix(shadcn): handle quote in theme values (#4726)
* fix(shadcn): handle quote in theme values

* chore(shadcn): fix theme values bug
2024-09-03 16:22:45 +04:00
shadcn
0f7591f67c docs(www): updates docs for Astro (#4723) 2024-09-03 15:35:24 +04:00
shadcn
81c7e44863 fix(www): url 2024-08-31 03:15:10 +04:00
shadcn
2fac3e40c2 fix(www): hide sidebar-01 for now 2024-08-31 03:10:14 +04:00
shadcn
5ad11ff851 docs(www): update callout 2024-08-31 03:01:42 +04:00
shadcn
6b92dd8eaf Merge branch 'main' of github.com:shadcn/ui 2024-08-31 02:57:49 +04:00
shadcn
84540f551d fix: blocks 2024-08-31 02:57:37 +04:00
shadcn
99588fff8f fix: cli (#4669) 2024-08-31 02:09:14 +04:00
8722 changed files with 561193 additions and 100848 deletions

View File

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

View File

@@ -0,0 +1,5 @@
---
"shadcn": patch
---
validate app name on create

View File

@@ -0,0 +1,13 @@
{
"permissions": {
"allow": [
"Bash(npm test:*)",
"Bash(npm run typecheck:*)",
"Bash(ls:*)",
"Bash(cat:*)",
"WebSearch",
"WebFetch(domain:github.com)"
],
"deny": []
}
}

8
.eslintignore Normal file
View File

@@ -0,0 +1,8 @@
node_modules/
target/
.next/
build/
dist/
/templates/
/fixtures/

3
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,3 @@
# These are supported funding model platforms
github: [shadcn]

View File

@@ -0,0 +1,63 @@
name: Add registry to directory
description: Add your registry to the directory
title: "[Registry Directory]: "
labels: ["registry", "directory"]
assignees: []
body:
- type: input
id: name
attributes:
label: Name
description: The name of your registry. This is also the namespace.
placeholder: e.g., "@acme"
validations:
required: true
- type: input
id: url
attributes:
label: URL
description: The URL to your registry index. Use {name} placeholder.
placeholder: https://ui.acme.com/r/{name}.json
validations:
required: true
- type: input
id: homepage
attributes:
label: Homepage
description: The URL to your registry homepage. This is where users can browse your registry.
placeholder: https://ui.acme.com
validations:
required: true
- type: textarea
id: description
attributes:
label: Description
description: Briefly describe what is your registry and what type of components or code it distributes.
placeholder:
validations:
required: true
- type: textarea
id: logo
attributes:
label: Logo
description: Add your SVG logo here.
placeholder:
validations:
required: true
- type: checkboxes
id: requirements
attributes:
label: Checklist
description: Verify that your registry meets the following requirements.
options:
- label: The registry must be open source and publicly accessible.
- label: The registry must be a valid JSON file that conforms to the [registry schema](https://ui.shadcn.com/docs/registry/registry-json) specification.
- label: The `files` array, if present on your registry items, must NOT include a `content` property.
- label: I've attached a square SVG logo to this issue
validations:
required: true

6
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"

View File

@@ -16,7 +16,7 @@ jobs:
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 18
node-version: 20
- uses: pnpm/action-setup@v4
name: Install pnpm
@@ -52,7 +52,7 @@ jobs:
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 18
node-version: 20
- uses: pnpm/action-setup@v4
name: Install pnpm
@@ -90,7 +90,7 @@ jobs:
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 18
node-version: 20
- uses: pnpm/action-setup@v4
name: Install pnpm
@@ -113,4 +113,7 @@ jobs:
- name: Install dependencies
run: pnpm install
- name: Build packages
run: pnpm --filter=shadcn build
- run: pnpm typecheck

78
.github/workflows/deprecated.yml vendored Normal file
View File

@@ -0,0 +1,78 @@
name: Deprecated
on:
pull_request_target:
types: [opened, synchronize]
permissions:
issues: write
contents: read
pull-requests: write
jobs:
deprecated:
runs-on: ubuntu-latest
steps:
- name: Checkout PR
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v46
with:
files: |
apps/www/**
files_ignore: |
apps/www/public/r/**
base_sha: ${{ github.event.pull_request.base.sha }}
sha: ${{ github.event.pull_request.head.sha }}
- name: Comment on PR if www files changed
if: steps.changed-files.outputs.any_changed == 'true'
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const changedFiles = `${{ steps.changed-files.outputs.all_changed_files }}`.split(' ');
const wwwFiles = changedFiles.filter(file =>
file.startsWith('apps/www/') &&
!file.startsWith('apps/www/public/r/') &&
file !== 'apps/www/package.json'
);
if (wwwFiles.length > 0) {
const comment = `Looks like this PR modifies files in \`apps/www\`, which is deprecated.
Consider applying the change to \`apps/v4\` if relevant.`;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment
});
// Add deprecated label
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: ['deprecated']
});
} else {
// Remove deprecated label if no www files are changed
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
name: 'deprecated'
});
} catch (error) {
// Label doesn't exist, which is fine
console.log('Deprecated label not found, skipping removal');
}
}

View File

@@ -1,5 +1,5 @@
# Adapted from vercel/next.js
name: Issue Stale
name: "Stale issue handler"
on:
workflow_dispatch:
schedule:
@@ -11,16 +11,35 @@ jobs:
runs-on: ubuntu-latest
if: github.repository_owner == 'shadcn-ui'
steps:
- uses: actions/stale@v4
id: stale-no-repro
name: "Close stale issues with no reproduction"
- uses: actions/stale@v9
id: issue-stale
name: "Mark stale issues, close stale issues"
with:
repo-token: ${{ secrets.STALE_TOKEN }}
close-issue-message: "This issue has been automatically closed because it received no activity for a while. If you think it was closed by accident, please leave a comment. Thank you."
ascending: true
days-before-issue-close: 7
days-before-issue-stale: 15
stale-pr-label: "stale?"
days-before-pr-close: -1
days-before-issue-stale: 365
days-before-pr-stale: -1
exempt-issue-labels: "roadmap,next,bug"
operations-per-run: 300 # 1 operation per 100 issues, the rest is to label/comment/close
days-before-pr-close: -1
remove-issue-stale-when-updated: true
stale-issue-label: "stale?"
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"
with:
repo-token: ${{ secrets.STALE_TOKEN }}
ascending: true
days-before-issue-close: -1
days-before-issue-stale: -1
days-before-pr-close: 7
days-before-pr-stale: 365
remove-pr-stale-when-updated: true
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. (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

@@ -49,7 +49,7 @@ jobs:
A new prerelease is available for testing:
```sh
npx shadcn@${{ env.BETA_PACKAGE_VERSION }}
pnpm dlx shadcn@${{ env.BETA_PACKAGE_VERSION }}
```
- name: "Remove the autorelease label once published"

View File

@@ -7,6 +7,11 @@ on:
types: [labeled]
branches:
- main
permissions:
id-token: write
contents: read
jobs:
prerelease:
if: |
@@ -18,7 +23,7 @@ jobs:
steps:
- name: Checkout Repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
@@ -27,23 +32,22 @@ jobs:
with:
version: 9.0.6
- name: Use Node.js 18
uses: actions/setup-node@v3
- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
registry-url: "https://registry.npmjs.org"
cache: "pnpm"
- name: Update npm for OIDC support
run: npm install -g npm@latest
- name: Install NPM Dependencies
run: pnpm install
- name: Modify package.json version
run: node .github/version-script-beta.js
- name: Authenticate to NPM
run: echo "//registry.npmjs.org/:_authToken=$NPM_ACCESS_TOKEN" >> packages/shadcn/.npmrc
env:
NPM_ACCESS_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }}
- name: Publish Beta to NPM
run: pnpm pub:beta
@@ -54,7 +58,7 @@ jobs:
path: packages/shadcn
- name: Upload packaged artifact
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: npm-package-shadcn@${{ steps.package-version.outputs.current-version }}-pr-${{ github.event.number }} # encode the PR number into the artifact name
path: packages/shadcn/dist/index.js

View File

@@ -7,6 +7,11 @@ on:
branches:
- main
permissions:
id-token: write
contents: write
pull-requests: write
jobs:
release:
if: ${{ github.repository_owner == 'shadcn-ui' }}
@@ -23,13 +28,16 @@ jobs:
with:
version: 9.0.6
- name: Use Node.js 18
uses: actions/setup-node@v3
- name: Use Node.js 20
uses: actions/setup-node@v4
with:
version: 9.0.6
node-version: 18
node-version: 20
registry-url: "https://registry.npmjs.org"
cache: "pnpm"
- name: Update npm for OIDC support
run: npm install -g npm@latest
- name: Install NPM Dependencies
run: pnpm install
@@ -41,7 +49,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"
@@ -49,5 +57,4 @@ jobs:
publish: npx changeset publish
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }}
NODE_ENV: "production"

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:
@@ -16,7 +19,7 @@ jobs:
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 18
node-version: 20
- uses: pnpm/action-setup@v4
name: Install pnpm
@@ -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

9
.gitignore vendored
View File

@@ -33,4 +33,11 @@ yarn-error.log*
.turbo
.contentlayer
tsconfig.tsbuildinfo
tsconfig.tsbuildinfo
# ide
.idea
.fleet
.vscode
.notes

1
.npmrc
View File

@@ -1 +1,2 @@
auto-install-peers=true
link-workspace-packages=true

View File

@@ -3,5 +3,5 @@ node_modules
.next
build
.contentlayer
apps/www/pages/api/registry.json
**/fixtures
deprecated

15
.vscode/settings.json vendored
View File

@@ -3,13 +3,18 @@
{ "pattern": "apps/*/" },
{ "pattern": "packages/*/" }
],
"tailwindCSS.experimental.classRegex": [
["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
["cn\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
],
"tailwindCSS.classFunctions": ["cva", "cn"],
"vitest.debugExclude": [
"<node_internals>/**",
"**/node_modules/**",
"**/fixtures/**"
]
],
"files.exclude": {
"deprecated": true
},
"search.exclude": {
"apps/v4/registry/radix-*": true,
"apps/v4/public/r/*": true,
"packages/shadcn/test/fixtures/*": true
}
}

View File

@@ -20,28 +20,25 @@ This repository is structured as follows:
```
apps
└── www
└── v4
├── app
├── components
├── content
└── registry
── default
│ ├── example
│ └── ui
└── new-york
── new-york-v4
├── example
└── ui
packages
└── cli
└── shadcn
```
| Path | Description |
| --------------------- | ---------------------------------------- |
| `apps/www/app` | The Next.js application for the website. |
| `apps/www/components` | The React components for the website. |
| `apps/www/content` | The content for the website. |
| `apps/www/registry` | The registry for the components. |
| `packages/cli` | The `shadcn-ui` package. |
| Path | Description |
| -------------------- | ---------------------------------------- |
| `apps/v4/app` | The Next.js application for the website. |
| `apps/v4/components` | The React components for the website. |
| `apps/v4/content` | The content for the website. |
| `apps/v4/registry` | The registry for the components. |
| `packages/shadcn` | The `shadcn` package. |
## Development
@@ -82,37 +79,58 @@ You can use the `pnpm --filter=[WORKSPACE]` command to start the development pro
1. To run the `ui.shadcn.com` website:
```bash
pnpm --filter=www dev
pnpm --filter=v4 dev
```
2. To run the `shadcn-ui` package:
2. To run the `shadcn` package:
```bash
pnpm --filter=shadcn-ui dev
pnpm --filter=shadcn dev
```
## Running the CLI Locally
To run the CLI locally, you can follow the workflow:
1. Start by running the dev server:
```bash
pnpm dev
```
2. In another terminal tab, test the CLI by running:
```bash
pnpm shadcn
```
To test the CLI in a specific app, use a command like:
```bash
pnpm shadcn <init | add | ...> -c ~/Desktop/my-app
```
This workflow ensures that you are running the most recent version of the registry and testing the CLI properly in your local environment.
## Documentation
The documentation for this project is located in the `www` workspace. You can run the documentation locally by running the following command:
The documentation for this project is located in the `v4` workspace. You can run the documentation locally by running the following command:
```bash
pnpm --filter=www dev
pnpm --filter=v4 dev
```
Documentation is written using [MDX](https://mdxjs.com). You can find the documentation files in the `apps/www/content/docs` directory.
Documentation is written using [MDX](https://mdxjs.com). You can find the documentation files in the `apps/v4/content/docs` directory.
## Components
We use a registry system for developing components. You can find the source code for the components under `apps/www/registry`. The components are organized by styles.
We use a registry system for developing components. You can find the source code for the components under `apps/v4/registry`. The components are organized by styles.
```bash
apps
└── www
└── v4
└── registry
── default
│ ├── example
│ └── ui
└── new-york
── new-york-v4
├── example
└── ui
```
@@ -121,7 +139,7 @@ When adding or modifying components, please ensure that:
1. You make the changes for every style.
2. You update the documentation.
3. You run `pnpm build:registry` to update the registry.
3. You run `pnpm registry:build` to update the registry.
## Commit Convention
@@ -160,9 +178,9 @@ If you have a request for a new component, please open a discussion on GitHub. W
## CLI
The `shadcn-ui` package is a CLI for adding components to your project. You can find the documentation for the CLI [here](https://ui.shadcn.com/docs/cli).
The `shadcn` package is a CLI for adding components to your project. You can find the documentation for the CLI [here](https://ui.shadcn.com/docs/cli).
Any changes to the CLI should be made in the `packages/cli` directory. If you can, it would be great if you could add tests for your changes.
Any changes to the CLI should be made in the `packages/shadcn` directory. If you can, it would be great if you could add tests for your changes.
## Testing

View File

@@ -1,8 +1,8 @@
# shadcn/ui
Accessible and customizable components that you can copy and paste into your apps. Free. Open Source. **Use this to build your own component library**.
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. **Use this to build your own component library**.
![hero](apps/www/public/og.jpg)
![hero](apps/v4/public/opengraph-image.png)
## Documentation

9
SECURITY.md Normal file
View File

@@ -0,0 +1,9 @@
# Security Policy
If you believe you have found a security vulnerability, we encourage you to let us know right away.
We will investigate all legitimate reports and do our best to quickly fix the problem.
Our preference is that you make use of GitHub's private vulnerability reporting feature to disclose potential security vulnerabilities in our Open Source Software.
To do this, please visit the security tab of the repository and click the [Report a vulnerability](https://github.com/shadcn-ui/ui/security/advisories/new) button.

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

48
apps/v4/.gitignore vendored Normal file
View File

@@ -0,0 +1,48 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# env files (can opt-in for committing if needed)
.env*
!.env.example
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
# generated content
.contentlayer
.content-collections
.source

7
apps/v4/.prettierignore Normal file
View File

@@ -0,0 +1,7 @@
dist
node_modules
.next
build
.contentlayer
registry/__index__.tsx
content/docs/components/calendar.mdx

1
apps/v4/README.md Normal file
View File

@@ -0,0 +1 @@
This is a wip registry for the `shadcn` canary version. It has React 19 and Tailwind v4 components.

View File

@@ -0,0 +1,138 @@
"use client"
import * as React from "react"
import { IconMinus, IconPlus } from "@tabler/icons-react"
import { Button } from "@/registry/new-york-v4/ui/button"
import { ButtonGroup } from "@/registry/new-york-v4/ui/button-group"
import {
Field,
FieldContent,
FieldDescription,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSeparator,
FieldSet,
FieldTitle,
} from "@/registry/new-york-v4/ui/field"
import { Input } from "@/registry/new-york-v4/ui/input"
import {
RadioGroup,
RadioGroupItem,
} from "@/registry/new-york-v4/ui/radio-group"
import { Switch } from "@/registry/new-york-v4/ui/switch"
export function AppearanceSettings() {
const [gpuCount, setGpuCount] = React.useState(8)
const handleGpuAdjustment = React.useCallback((adjustment: number) => {
setGpuCount((prevCount) =>
Math.max(1, Math.min(99, prevCount + adjustment))
)
}, [])
const handleGpuInputChange = React.useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
const value = parseInt(e.target.value, 10)
if (!isNaN(value) && value >= 1 && value <= 99) {
setGpuCount(value)
}
},
[]
)
return (
<FieldSet>
<FieldGroup>
<FieldSet>
<FieldLegend>Compute Environment</FieldLegend>
<FieldDescription>
Select the compute environment for your cluster.
</FieldDescription>
<RadioGroup defaultValue="kubernetes">
<FieldLabel htmlFor="kubernetes-r2h">
<Field orientation="horizontal">
<FieldContent>
<FieldTitle>Kubernetes</FieldTitle>
<FieldDescription>
Run GPU workloads on a K8s configured cluster. This is the
default.
</FieldDescription>
</FieldContent>
<RadioGroupItem
value="kubernetes"
id="kubernetes-r2h"
aria-label="Kubernetes"
/>
</Field>
</FieldLabel>
<FieldLabel htmlFor="vm-z4k">
<Field orientation="horizontal">
<FieldContent>
<FieldTitle>Virtual Machine</FieldTitle>
<FieldDescription>
Access a VM configured cluster to run workloads. (Coming
soon)
</FieldDescription>
</FieldContent>
<RadioGroupItem
value="vm"
id="vm-z4k"
aria-label="Virtual Machine"
/>
</Field>
</FieldLabel>
</RadioGroup>
</FieldSet>
<FieldSeparator />
<Field orientation="horizontal">
<FieldContent>
<FieldLabel htmlFor="number-of-gpus-f6l">Number of GPUs</FieldLabel>
<FieldDescription>You can add more later.</FieldDescription>
</FieldContent>
<ButtonGroup>
<Input
id="number-of-gpus-f6l"
value={gpuCount}
onChange={handleGpuInputChange}
size={3}
className="h-8 !w-14 font-mono"
maxLength={3}
/>
<Button
variant="outline"
size="icon-sm"
type="button"
aria-label="Decrement"
onClick={() => handleGpuAdjustment(-1)}
disabled={gpuCount <= 1}
>
<IconMinus />
</Button>
<Button
variant="outline"
size="icon-sm"
type="button"
aria-label="Increment"
onClick={() => handleGpuAdjustment(1)}
disabled={gpuCount >= 99}
>
<IconPlus />
</Button>
</ButtonGroup>
</Field>
<FieldSeparator />
<Field orientation="horizontal">
<FieldContent>
<FieldLabel htmlFor="tinting">Wallpaper Tinting</FieldLabel>
<FieldDescription>
Allow the wallpaper to be tinted.
</FieldDescription>
</FieldContent>
<Switch id="tinting" defaultChecked />
</Field>
</FieldGroup>
</FieldSet>
)
}

View File

@@ -0,0 +1,120 @@
"use client"
import * as React from "react"
import {
ArchiveIcon,
ArrowLeftIcon,
CalendarPlusIcon,
ClockIcon,
ListFilterIcon,
MailCheckIcon,
MoreHorizontalIcon,
TagIcon,
Trash2Icon,
} from "lucide-react"
import { Button } from "@/registry/new-york-v4/ui/button"
import { ButtonGroup } from "@/registry/new-york-v4/ui/button-group"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger,
} from "@/registry/new-york-v4/ui/dropdown-menu"
export function ButtonGroupDemo() {
const [label, setLabel] = React.useState("personal")
return (
<ButtonGroup>
<ButtonGroup className="hidden sm:flex">
<Button variant="outline" size="icon-sm" aria-label="Go Back">
<ArrowLeftIcon />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button variant="outline" size="sm">
Archive
</Button>
<Button variant="outline" size="sm">
Report
</Button>
</ButtonGroup>
<ButtonGroup>
<Button variant="outline" size="sm">
Snooze
</Button>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon-sm" aria-label="More Options">
<MoreHorizontalIcon />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-48 [--radius:1rem]">
<DropdownMenuGroup>
<DropdownMenuItem>
<MailCheckIcon />
Mark as Read
</DropdownMenuItem>
<DropdownMenuItem>
<ArchiveIcon />
Archive
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<ClockIcon />
Snooze
</DropdownMenuItem>
<DropdownMenuItem>
<CalendarPlusIcon />
Add to Calendar
</DropdownMenuItem>
<DropdownMenuItem>
<ListFilterIcon />
Add to List
</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<TagIcon />
Label As...
</DropdownMenuSubTrigger>
<DropdownMenuSubContent>
<DropdownMenuRadioGroup
value={label}
onValueChange={setLabel}
>
<DropdownMenuRadioItem value="personal">
Personal
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="work">
Work
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="other">
Other
</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuSubContent>
</DropdownMenuSub>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem variant="destructive">
<Trash2Icon />
Trash
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</ButtonGroup>
</ButtonGroup>
)
}

View File

@@ -0,0 +1,58 @@
"use client"
import * as React from "react"
import { AudioLinesIcon, PlusIcon } from "lucide-react"
import { Button } from "@/registry/new-york-v4/ui/button"
import { ButtonGroup } from "@/registry/new-york-v4/ui/button-group"
import {
InputGroup,
InputGroupAddon,
InputGroupButton,
InputGroupInput,
} from "@/registry/new-york-v4/ui/input-group"
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/registry/new-york-v4/ui/tooltip"
export function ButtonGroupInputGroup() {
const [voiceEnabled, setVoiceEnabled] = React.useState(false)
return (
<ButtonGroup className="[--radius:9999rem]">
<ButtonGroup>
<Button variant="outline" size="icon" aria-label="Add">
<PlusIcon />
</Button>
</ButtonGroup>
<ButtonGroup className="flex-1">
<InputGroup>
<InputGroupInput
placeholder={
voiceEnabled ? "Record and send audio..." : "Send a message..."
}
disabled={voiceEnabled}
/>
<InputGroupAddon align="inline-end">
<Tooltip>
<TooltipTrigger asChild>
<InputGroupButton
onClick={() => setVoiceEnabled(!voiceEnabled)}
data-active={voiceEnabled}
className="data-[active=true]:bg-primary data-[active=true]:text-primary-foreground"
aria-pressed={voiceEnabled}
size="icon-xs"
aria-label="Voice Mode"
>
<AudioLinesIcon />
</InputGroupButton>
</TooltipTrigger>
<TooltipContent>Voice Mode</TooltipContent>
</Tooltip>
</InputGroupAddon>
</InputGroup>
</ButtonGroup>
</ButtonGroup>
)
}

View File

@@ -0,0 +1,32 @@
"use client"
import { ArrowLeftIcon, ArrowRightIcon } from "lucide-react"
import { Button } from "@/registry/new-york-v4/ui/button"
import { ButtonGroup } from "@/registry/new-york-v4/ui/button-group"
export function ButtonGroupNested() {
return (
<ButtonGroup>
<ButtonGroup>
<Button variant="outline" size="sm">
1
</Button>
<Button variant="outline" size="sm">
2
</Button>
<Button variant="outline" size="sm">
3
</Button>
</ButtonGroup>
<ButtonGroup>
<Button variant="outline" size="icon-sm" aria-label="Previous">
<ArrowLeftIcon />
</Button>
<Button variant="outline" size="icon-sm" aria-label="Next">
<ArrowRightIcon />
</Button>
</ButtonGroup>
</ButtonGroup>
)
}

View File

@@ -0,0 +1,45 @@
import { BotIcon, ChevronDownIcon } from "lucide-react"
import { Button } from "@/registry/new-york-v4/ui/button"
import { ButtonGroup } from "@/registry/new-york-v4/ui/button-group"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/registry/new-york-v4/ui/popover"
import { Separator } from "@/registry/new-york-v4/ui/separator"
import { Textarea } from "@/registry/new-york-v4/ui/textarea"
export function ButtonGroupPopover() {
return (
<ButtonGroup>
<Button variant="outline" size="sm">
<BotIcon /> Copilot
</Button>
<Popover>
<PopoverTrigger asChild>
<Button variant="outline" size="icon-sm" aria-label="Open Popover">
<ChevronDownIcon />
</Button>
</PopoverTrigger>
<PopoverContent align="end" className="rounded-xl p-0 text-sm">
<div className="px-4 py-3">
<div className="text-sm font-medium">Agent Tasks</div>
</div>
<Separator />
<div className="p-4 text-sm *:[p:not(:last-child)]:mb-2">
<Textarea
placeholder="Describe your task in natural language."
className="mb-4 resize-none"
/>
<p className="font-medium">Start a new task with Copilot</p>
<p className="text-muted-foreground">
Describe your task in natural language. Copilot will work in the
background and open a pull request for your review.
</p>
</div>
</PopoverContent>
</Popover>
</ButtonGroup>
)
}

View File

@@ -0,0 +1,57 @@
import { PlusIcon } from "lucide-react"
import {
Avatar,
AvatarFallback,
AvatarImage,
} from "@/registry/new-york-v4/ui/avatar"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle,
} from "@/registry/new-york-v4/ui/empty"
export function EmptyAvatarGroup() {
return (
<Empty className="flex-none border">
<EmptyHeader>
<EmptyMedia>
<div className="*:data-[slot=avatar]:ring-background flex -space-x-2 *:data-[slot=avatar]:size-12 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:grayscale">
<Avatar>
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
<AvatarFallback>CN</AvatarFallback>
</Avatar>
<Avatar>
<AvatarImage
src="https://github.com/maxleiter.png"
alt="@maxleiter"
/>
<AvatarFallback>LR</AvatarFallback>
</Avatar>
<Avatar>
<AvatarImage
src="https://github.com/evilrabbit.png"
alt="@evilrabbit"
/>
<AvatarFallback>ER</AvatarFallback>
</Avatar>
</div>
</EmptyMedia>
<EmptyTitle>No Team Members</EmptyTitle>
<EmptyDescription>
Invite your team to collaborate on this project.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<Button size="sm">
<PlusIcon />
Invite Members
</Button>
</EmptyContent>
</Empty>
)
}

View File

@@ -0,0 +1,43 @@
import { SearchIcon } from "lucide-react"
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyTitle,
} from "@/registry/new-york-v4/ui/empty"
import {
InputGroup,
InputGroupAddon,
InputGroupInput,
} from "@/registry/new-york-v4/ui/input-group"
import { Kbd } from "@/registry/new-york-v4/ui/kbd"
export function EmptyInputGroup() {
return (
<Empty>
<EmptyHeader>
<EmptyTitle>404 - Not Found</EmptyTitle>
<EmptyDescription>
The page you&apos;re looking for doesn&apos;t exist. Try searching for
what you need below.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<InputGroup className="w-3/4">
<InputGroupInput placeholder="Try searching for pages..." />
<InputGroupAddon>
<SearchIcon />
</InputGroupAddon>
<InputGroupAddon align="inline-end">
<Kbd>/</Kbd>
</InputGroupAddon>
</InputGroup>
<EmptyDescription>
Need help? <a href="#">Contact support</a>
</EmptyDescription>
</EmptyContent>
</Empty>
)
}

View File

@@ -0,0 +1,15 @@
import { Checkbox } from "@/registry/new-york-v4/ui/checkbox"
import { Field, FieldLabel } from "@/registry/new-york-v4/ui/field"
export function FieldCheckbox() {
return (
<FieldLabel htmlFor="checkbox-demo">
<Field orientation="horizontal">
<Checkbox id="checkbox-demo" defaultChecked />
<FieldLabel htmlFor="checkbox-demo" className="line-clamp-1">
I agree to the terms and conditions
</FieldLabel>
</Field>
</FieldLabel>
)
}

View File

@@ -0,0 +1,62 @@
import {
Field,
FieldContent,
FieldDescription,
FieldGroup,
FieldLabel,
FieldSet,
FieldTitle,
} from "@/registry/new-york-v4/ui/field"
import {
RadioGroup,
RadioGroupItem,
} from "@/registry/new-york-v4/ui/radio-group"
export function FieldChoiceCard() {
return (
<div className="w-full max-w-md">
<FieldGroup>
<FieldSet>
<FieldLabel htmlFor="compute-environment-p8w">
Compute Environment
</FieldLabel>
<FieldDescription>
Select the compute environment for your cluster.
</FieldDescription>
<RadioGroup defaultValue="kubernetes">
<FieldLabel htmlFor="kubernetes-r2h">
<Field orientation="horizontal">
<RadioGroupItem
value="kubernetes"
id="kubernetes-r2h"
aria-label="Kubernetes"
/>
<FieldContent>
<FieldTitle>Kubernetes</FieldTitle>
<FieldDescription>
Run GPU workloads on a K8s configured cluster.
</FieldDescription>
</FieldContent>
</Field>
</FieldLabel>
<FieldLabel htmlFor="vm-z4k">
<Field orientation="horizontal">
<RadioGroupItem
value="vm"
id="vm-z4k"
aria-label="Virtual Machine"
/>
<FieldContent>
<FieldTitle>Virtual Machine</FieldTitle>
<FieldDescription>
Access a VM configured cluster to run workloads.
</FieldDescription>
</FieldContent>
</Field>
</FieldLabel>
</RadioGroup>
</FieldSet>
</FieldGroup>
</div>
)
}

View File

@@ -0,0 +1,153 @@
import { Button } from "@/registry/new-york-v4/ui/button"
import { Checkbox } from "@/registry/new-york-v4/ui/checkbox"
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSeparator,
FieldSet,
} from "@/registry/new-york-v4/ui/field"
import { Input } from "@/registry/new-york-v4/ui/input"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/registry/new-york-v4/ui/select"
import { Textarea } from "@/registry/new-york-v4/ui/textarea"
export function FieldDemo() {
return (
<div className="w-full max-w-md rounded-lg border p-6">
<form>
<FieldGroup>
<FieldSet>
<FieldLegend>Payment Method</FieldLegend>
<FieldDescription>
All transactions are secure and encrypted
</FieldDescription>
<FieldGroup>
<Field>
<FieldLabel htmlFor="checkout-7j9-card-name-43j">
Name on Card
</FieldLabel>
<Input
id="checkout-7j9-card-name-43j"
placeholder="John Doe"
required
/>
</Field>
<div className="grid grid-cols-3 gap-4">
<Field className="col-span-2">
<FieldLabel htmlFor="checkout-7j9-card-number-uw1">
Card Number
</FieldLabel>
<Input
id="checkout-7j9-card-number-uw1"
placeholder="1234 5678 9012 3456"
required
/>
<FieldDescription>
Enter your 16-digit number.
</FieldDescription>
</Field>
<Field className="col-span-1">
<FieldLabel htmlFor="checkout-7j9-cvv">CVV</FieldLabel>
<Input id="checkout-7j9-cvv" placeholder="123" required />
</Field>
</div>
<div className="grid grid-cols-2 gap-4">
<Field>
<FieldLabel htmlFor="checkout-7j9-exp-month-ts6">
Month
</FieldLabel>
<Select defaultValue="">
<SelectTrigger id="checkout-7j9-exp-month-ts6">
<SelectValue placeholder="MM" />
</SelectTrigger>
<SelectContent>
<SelectItem value="01">01</SelectItem>
<SelectItem value="02">02</SelectItem>
<SelectItem value="03">03</SelectItem>
<SelectItem value="04">04</SelectItem>
<SelectItem value="05">05</SelectItem>
<SelectItem value="06">06</SelectItem>
<SelectItem value="07">07</SelectItem>
<SelectItem value="08">08</SelectItem>
<SelectItem value="09">09</SelectItem>
<SelectItem value="10">10</SelectItem>
<SelectItem value="11">11</SelectItem>
<SelectItem value="12">12</SelectItem>
</SelectContent>
</Select>
</Field>
<Field>
<FieldLabel htmlFor="checkout-7j9-exp-year-f59">
Year
</FieldLabel>
<Select defaultValue="">
<SelectTrigger id="checkout-7j9-exp-year-f59">
<SelectValue placeholder="YYYY" />
</SelectTrigger>
<SelectContent>
<SelectItem value="2024">2024</SelectItem>
<SelectItem value="2025">2025</SelectItem>
<SelectItem value="2026">2026</SelectItem>
<SelectItem value="2027">2027</SelectItem>
<SelectItem value="2028">2028</SelectItem>
<SelectItem value="2029">2029</SelectItem>
</SelectContent>
</Select>
</Field>
</div>
</FieldGroup>
</FieldSet>
<FieldSeparator />
<FieldSet>
<FieldLegend>Billing Address</FieldLegend>
<FieldDescription>
The billing address associated with your payment method
</FieldDescription>
<FieldGroup>
<Field orientation="horizontal">
<Checkbox
id="checkout-7j9-same-as-shipping-wgm"
defaultChecked
/>
<FieldLabel
htmlFor="checkout-7j9-same-as-shipping-wgm"
className="font-normal"
>
Same as shipping address
</FieldLabel>
</Field>
</FieldGroup>
</FieldSet>
<FieldSeparator />
<FieldSet>
<FieldGroup>
<Field>
<FieldLabel htmlFor="checkout-7j9-optional-comments">
Comments
</FieldLabel>
<Textarea
id="checkout-7j9-optional-comments"
placeholder="Add any additional comments"
/>
</Field>
</FieldGroup>
</FieldSet>
<Field orientation="horizontal">
<Button type="submit">Submit</Button>
<Button variant="outline" type="button">
Cancel
</Button>
</Field>
</FieldGroup>
</form>
</div>
)
}

View File

@@ -0,0 +1,72 @@
import { Card, CardContent } from "@/registry/new-york-v4/ui/card"
import { Checkbox } from "@/registry/new-york-v4/ui/checkbox"
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSet,
FieldTitle,
} from "@/registry/new-york-v4/ui/field"
const options = [
{
label: "Social Media",
value: "social-media",
},
{
label: "Search Engine",
value: "search-engine",
},
{
label: "Referral",
value: "referral",
},
{
label: "Other",
value: "other",
},
]
export function FieldHear() {
return (
<Card className="py-4 shadow-none">
<CardContent className="px-4">
<form>
<FieldGroup>
<FieldSet className="gap-4">
<FieldLegend>How did you hear about us?</FieldLegend>
<FieldDescription className="line-clamp-1">
Select the option that best describes how you heard about us.
</FieldDescription>
<FieldGroup className="flex flex-row flex-wrap gap-2 [--radius:9999rem]">
{options.map((option) => (
<FieldLabel
htmlFor={option.value}
key={option.value}
className="!w-fit"
>
<Field
orientation="horizontal"
className="gap-1.5 overflow-hidden !px-3 !py-1.5 transition-all duration-100 ease-linear group-has-data-[state=checked]/field-label:!px-2"
>
<Checkbox
value={option.value}
id={option.value}
defaultChecked={option.value === "social-media"}
className="-ml-6 -translate-x-1 rounded-full transition-all duration-100 ease-linear data-[state=checked]:ml-0 data-[state=checked]:translate-x-0"
/>
<FieldTitle>{option.label}</FieldTitle>
</Field>
</FieldLabel>
))}
</FieldGroup>
</FieldSet>
</FieldGroup>
</form>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,35 @@
"use client"
import { useState } from "react"
import {
Field,
FieldDescription,
FieldTitle,
} from "@/registry/new-york-v4/ui/field"
import { Slider } from "@/registry/new-york-v4/ui/slider"
export function FieldSlider() {
const [value, setValue] = useState([200, 800])
return (
<div className="w-full max-w-md">
<Field>
<FieldTitle>Price Range</FieldTitle>
<FieldDescription>
Set your budget range ($
<span className="font-medium tabular-nums">{value[0]}</span> -{" "}
<span className="font-medium tabular-nums">{value[1]}</span>).
</FieldDescription>
<Slider
value={value}
onValueChange={setValue}
max={1000}
min={0}
step={10}
className="mt-2 w-full"
aria-label="Price Range"
/>
</Field>
</div>
)
}

View File

@@ -0,0 +1,52 @@
import { FieldSeparator } from "@/registry/new-york-v4/ui/field"
import { AppearanceSettings } from "./appearance-settings"
import { ButtonGroupDemo } from "./button-group-demo"
import { ButtonGroupInputGroup } from "./button-group-input-group"
import { ButtonGroupNested } from "./button-group-nested"
import { ButtonGroupPopover } from "./button-group-popover"
import { EmptyAvatarGroup } from "./empty-avatar-group"
import { FieldCheckbox } from "./field-checkbox"
import { FieldDemo } from "./field-demo"
import { FieldHear } from "./field-hear"
import { FieldSlider } from "./field-slider"
import { InputGroupButtonExample } from "./input-group-button"
import { InputGroupDemo } from "./input-group-demo"
import { ItemDemo } from "./item-demo"
import { NotionPromptForm } from "./notion-prompt-form"
import { SpinnerBadge } from "./spinner-badge"
import { SpinnerEmpty } from "./spinner-empty"
export function RootComponents() {
return (
<div className="theme-container mx-auto grid gap-8 py-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 xl:gap-6 2xl:gap-8">
<div className="flex flex-col gap-6 *:[div]:w-full *:[div]:max-w-full">
<FieldDemo />
</div>
<div className="flex flex-col gap-6 *:[div]:w-full *:[div]:max-w-full">
<EmptyAvatarGroup />
<SpinnerBadge />
<ButtonGroupInputGroup />
<FieldSlider />
<InputGroupDemo />
</div>
<div className="flex flex-col gap-6 *:[div]:w-full *:[div]:max-w-full">
<InputGroupButtonExample />
<ItemDemo />
<FieldSeparator className="my-4">Appearance Settings</FieldSeparator>
<AppearanceSettings />
</div>
<div className="order-first flex flex-col gap-6 lg:hidden xl:order-last xl:flex *:[div]:w-full *:[div]:max-w-full">
<NotionPromptForm />
<ButtonGroupDemo />
<FieldCheckbox />
<div className="flex justify-between gap-4">
<ButtonGroupNested />
<ButtonGroupPopover />
</div>
<FieldHear />
<SpinnerEmpty />
</div>
</div>
)
}

View File

@@ -0,0 +1,68 @@
"use client"
import * as React from "react"
import { IconInfoCircle, IconStar } from "@tabler/icons-react"
import {
InputGroup,
InputGroupAddon,
InputGroupButton,
InputGroupInput,
} from "@/registry/new-york-v4/ui/input-group"
import { Label } from "@/registry/new-york-v4/ui/label"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/registry/new-york-v4/ui/popover"
export function InputGroupButtonExample() {
const [isFavorite, setIsFavorite] = React.useState(false)
return (
<div className="grid w-full max-w-sm gap-6">
<Label htmlFor="input-secure-19" className="sr-only">
Input Secure
</Label>
<InputGroup className="[--radius:9999px]">
<InputGroupInput id="input-secure-19" className="!pl-0.5" />
<Popover>
<PopoverTrigger asChild>
<InputGroupAddon>
<InputGroupButton
variant="secondary"
size="icon-xs"
aria-label="Info"
>
<IconInfoCircle />
</InputGroupButton>
</InputGroupAddon>
</PopoverTrigger>
<PopoverContent
align="start"
alignOffset={10}
className="flex flex-col gap-1 rounded-xl text-sm"
>
<p className="font-medium">Your connection is not secure.</p>
<p>You should not enter any sensitive information on this site.</p>
</PopoverContent>
</Popover>
<InputGroupAddon className="text-muted-foreground !pl-1">
https://
</InputGroupAddon>
<InputGroupAddon align="inline-end">
<InputGroupButton
onClick={() => setIsFavorite(!isFavorite)}
size="icon-xs"
aria-label="Favorite"
>
<IconStar
data-favorite={isFavorite}
className="data-[favorite=true]:fill-primary data-[favorite=true]:stroke-primary"
/>
</InputGroupButton>
</InputGroupAddon>
</InputGroup>
</div>
)
}

View File

@@ -0,0 +1,102 @@
import { IconCheck, IconInfoCircle, IconPlus } from "@tabler/icons-react"
import { ArrowUpIcon, Search } from "lucide-react"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/registry/new-york-v4/ui/dropdown-menu"
import {
InputGroup,
InputGroupAddon,
InputGroupButton,
InputGroupInput,
InputGroupText,
InputGroupTextarea,
} from "@/registry/new-york-v4/ui/input-group"
import { Separator } from "@/registry/new-york-v4/ui/separator"
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/registry/new-york-v4/ui/tooltip"
export function InputGroupDemo() {
return (
<div className="grid w-full max-w-sm gap-6">
<InputGroup>
<InputGroupInput placeholder="Search..." />
<InputGroupAddon>
<Search />
</InputGroupAddon>
<InputGroupAddon align="inline-end">12 results</InputGroupAddon>
</InputGroup>
<InputGroup>
<InputGroupInput placeholder="example.com" className="!pl-1" />
<InputGroupAddon>
<InputGroupText>https://</InputGroupText>
</InputGroupAddon>
<InputGroupAddon align="inline-end">
<Tooltip>
<TooltipTrigger asChild>
<InputGroupButton
className="rounded-full"
size="icon-xs"
aria-label="Info"
>
<IconInfoCircle />
</InputGroupButton>
</TooltipTrigger>
<TooltipContent>This is content in a tooltip.</TooltipContent>
</Tooltip>
</InputGroupAddon>
</InputGroup>
<InputGroup>
<InputGroupTextarea placeholder="Ask, Search or Chat..." />
<InputGroupAddon align="block-end">
<InputGroupButton
variant="outline"
className="rounded-full"
size="icon-xs"
aria-label="Add"
>
<IconPlus />
</InputGroupButton>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<InputGroupButton variant="ghost">Auto</InputGroupButton>
</DropdownMenuTrigger>
<DropdownMenuContent
side="top"
align="start"
className="[--radius:0.95rem]"
>
<DropdownMenuItem>Auto</DropdownMenuItem>
<DropdownMenuItem>Agent</DropdownMenuItem>
<DropdownMenuItem>Manual</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<InputGroupText className="ml-auto">52% used</InputGroupText>
<Separator orientation="vertical" className="!h-4" />
<InputGroupButton
variant="default"
className="rounded-full"
size="icon-xs"
>
<ArrowUpIcon />
<span className="sr-only">Send</span>
</InputGroupButton>
</InputGroupAddon>
</InputGroup>
<InputGroup>
<InputGroupInput placeholder="@shadcn" />
<InputGroupAddon align="inline-end">
<div className="bg-primary text-foreground flex size-4 items-center justify-center rounded-full">
<IconCheck className="size-3 text-white" />
</div>
</InputGroupAddon>
</InputGroup>
</div>
)
}

View File

@@ -0,0 +1,46 @@
import {
IconBrandJavascript,
IconCopy,
IconCornerDownLeft,
IconRefresh,
} from "@tabler/icons-react"
import {
InputGroup,
InputGroupAddon,
InputGroupButton,
InputGroupText,
InputGroupTextarea,
} from "@/registry/new-york-v4/ui/input-group"
export function InputGroupTextareaExample() {
return (
<div className="grid w-full max-w-md gap-4">
<InputGroup>
<InputGroupTextarea
id="textarea-code-32"
placeholder="console.log('Hello, world!');"
className="min-h-[180px]"
/>
<InputGroupAddon align="block-end" className="border-t">
<InputGroupText>Line 1, Column 1</InputGroupText>
<InputGroupButton size="sm" className="ml-auto" variant="default">
Run <IconCornerDownLeft />
</InputGroupButton>
</InputGroupAddon>
<InputGroupAddon align="block-start" className="border-b">
<InputGroupText className="font-mono font-medium">
<IconBrandJavascript />
script.js
</InputGroupText>
<InputGroupButton className="ml-auto">
<IconRefresh />
</InputGroupButton>
<InputGroupButton variant="ghost">
<IconCopy />
</InputGroupButton>
</InputGroupAddon>
</InputGroup>
</div>
)
}

View File

@@ -0,0 +1,78 @@
import { Plus } from "lucide-react"
import {
Avatar,
AvatarFallback,
AvatarImage,
} from "@/registry/new-york-v4/ui/avatar"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Item,
ItemActions,
ItemContent,
ItemDescription,
ItemMedia,
ItemTitle,
} from "@/registry/new-york-v4/ui/item"
export function ItemAvatar() {
return (
<div className="flex w-full max-w-lg flex-col gap-6">
<Item variant="outline" className="hidden">
<ItemMedia>
<Avatar className="size-10">
<AvatarImage src="https://github.com/maxleiter.png" />
<AvatarFallback>LR</AvatarFallback>
</Avatar>
</ItemMedia>
<ItemContent>
<ItemTitle>Max Leiter</ItemTitle>
<ItemDescription>Last seen 5 months ago</ItemDescription>
</ItemContent>
<ItemActions>
<Button
size="icon-sm"
variant="outline"
className="rounded-full"
aria-label="Invite"
>
<Plus />
</Button>
</ItemActions>
</Item>
<Item variant="outline">
<ItemMedia>
<div className="*:data-[slot=avatar]:ring-background flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:grayscale">
<Avatar className="hidden sm:flex">
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
<AvatarFallback>CN</AvatarFallback>
</Avatar>
<Avatar className="hidden sm:flex">
<AvatarImage
src="https://github.com/maxleiter.png"
alt="@maxleiter"
/>
<AvatarFallback>LR</AvatarFallback>
</Avatar>
<Avatar>
<AvatarImage
src="https://github.com/evilrabbit.png"
alt="@evilrabbit"
/>
<AvatarFallback>ER</AvatarFallback>
</Avatar>
</div>
</ItemMedia>
<ItemContent>
<ItemTitle>No Team Members</ItemTitle>
<ItemDescription>Invite your team to collaborate.</ItemDescription>
</ItemContent>
<ItemActions>
<Button size="sm" variant="outline">
Invite
</Button>
</ItemActions>
</Item>
</div>
)
}

View File

@@ -0,0 +1,42 @@
import { BadgeCheckIcon, ChevronRightIcon } from "lucide-react"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Item,
ItemActions,
ItemContent,
ItemDescription,
ItemMedia,
ItemTitle,
} from "@/registry/new-york-v4/ui/item"
export function ItemDemo() {
return (
<div className="flex w-full max-w-md flex-col gap-6">
<Item variant="outline">
<ItemContent>
<ItemTitle>Two-factor authentication</ItemTitle>
<ItemDescription className="text-pretty xl:hidden 2xl:block">
Verify via email or phone number.
</ItemDescription>
</ItemContent>
<ItemActions>
<Button size="sm">Enable</Button>
</ItemActions>
</Item>
<Item variant="outline" size="sm" asChild>
<a href="#">
<ItemMedia>
<BadgeCheckIcon className="size-5" />
</ItemMedia>
<ItemContent>
<ItemTitle>Your profile has been verified.</ItemTitle>
</ItemContent>
<ItemActions>
<ChevronRightIcon className="size-4" />
</ItemActions>
</a>
</Item>
</div>
)
}

View File

@@ -0,0 +1,456 @@
"use client"
import { useMemo, useState } from "react"
import {
IconApps,
IconArrowUp,
IconAt,
IconBook,
IconCircleDashedPlus,
IconPaperclip,
IconPlus,
IconWorld,
IconX,
} from "@tabler/icons-react"
import {
Avatar,
AvatarFallback,
AvatarImage,
} from "@/registry/new-york-v4/ui/avatar"
import { Badge } from "@/registry/new-york-v4/ui/badge"
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/registry/new-york-v4/ui/command"
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger,
} from "@/registry/new-york-v4/ui/dropdown-menu"
import { Field, FieldLabel } from "@/registry/new-york-v4/ui/field"
import {
InputGroup,
InputGroupAddon,
InputGroupButton,
InputGroupTextarea,
} from "@/registry/new-york-v4/ui/input-group"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/registry/new-york-v4/ui/popover"
import { Switch } from "@/registry/new-york-v4/ui/switch"
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/registry/new-york-v4/ui/tooltip"
const SAMPLE_DATA = {
mentionable: [
{
type: "page",
title: "Meeting Notes",
image: "📝",
},
{
type: "page",
title: "Project Dashboard",
image: "📊",
},
{
type: "page",
title: "Ideas & Brainstorming",
image: "💡",
},
{
type: "page",
title: "Calendar & Events",
image: "📅",
},
{
type: "page",
title: "Documentation",
image: "📚",
},
{
type: "page",
title: "Goals & Objectives",
image: "🎯",
},
{
type: "page",
title: "Budget Planning",
image: "💰",
},
{
type: "page",
title: "Team Directory",
image: "👥",
},
{
type: "page",
title: "Technical Specs",
image: "🔧",
},
{
type: "page",
title: "Analytics Report",
image: "📈",
},
{
type: "user",
title: "shadcn",
image: "https://github.com/shadcn.png",
workspace: "Workspace",
},
{
type: "user",
title: "maxleiter",
image: "https://github.com/maxleiter.png",
workspace: "Workspace",
},
{
type: "user",
title: "evilrabbit",
image: "https://github.com/evilrabbit.png",
workspace: "Workspace",
},
],
models: [
{
name: "Auto",
},
{
name: "Agent Mode",
badge: "Beta",
},
{
name: "Plan Mode",
},
],
}
function MentionableIcon({
item,
}: {
item: (typeof SAMPLE_DATA.mentionable)[0]
}) {
return item.type === "page" ? (
<span className="flex size-4 items-center justify-center">
{item.image}
</span>
) : (
<Avatar className="size-4">
<AvatarImage src={item.image} />
<AvatarFallback>{item.title[0]}</AvatarFallback>
</Avatar>
)
}
export function NotionPromptForm() {
const [mentions, setMentions] = useState<string[]>([])
const [mentionPopoverOpen, setMentionPopoverOpen] = useState(false)
const [modelPopoverOpen, setModelPopoverOpen] = useState(false)
const [selectedModel, setSelectedModel] = useState<
(typeof SAMPLE_DATA.models)[0]
>(SAMPLE_DATA.models[0])
const [scopeMenuOpen, setScopeMenuOpen] = useState(false)
const grouped = useMemo(() => {
return SAMPLE_DATA.mentionable.reduce(
(acc, item) => {
const isAvailable = !mentions.includes(item.title)
if (isAvailable) {
if (!acc[item.type]) {
acc[item.type] = []
}
acc[item.type].push(item)
}
return acc
},
{} as Record<string, typeof SAMPLE_DATA.mentionable>
)
}, [mentions])
const hasMentions = mentions.length > 0
return (
<form className="[--radius:1.2rem]">
<Field>
<FieldLabel htmlFor="notion-prompt" className="sr-only">
Prompt
</FieldLabel>
<InputGroup>
<InputGroupTextarea
id="notion-prompt"
placeholder="Ask, search, or make anything..."
/>
<InputGroupAddon align="block-start">
<Popover
open={mentionPopoverOpen}
onOpenChange={setMentionPopoverOpen}
>
<Tooltip>
<TooltipTrigger
asChild
onFocusCapture={(e) => e.stopPropagation()}
>
<PopoverTrigger asChild>
<InputGroupButton
variant="outline"
size={!hasMentions ? "sm" : "icon-sm"}
className="rounded-full transition-transform"
>
<IconAt /> {!hasMentions && "Add context"}
</InputGroupButton>
</PopoverTrigger>
</TooltipTrigger>
<TooltipContent>Mention a person, page, or date</TooltipContent>
</Tooltip>
<PopoverContent className="p-0 [--radius:1.2rem]" align="start">
<Command>
<CommandInput placeholder="Search pages..." />
<CommandList>
<CommandEmpty>No pages found</CommandEmpty>
{Object.entries(grouped).map(([type, items]) => (
<CommandGroup
key={type}
heading={type === "page" ? "Pages" : "Users"}
>
{items.map((item) => (
<CommandItem
key={item.title}
value={item.title}
onSelect={(currentValue) => {
setMentions((prev) => [...prev, currentValue])
setMentionPopoverOpen(false)
}}
>
<MentionableIcon item={item} />
{item.title}
</CommandItem>
))}
</CommandGroup>
))}
</CommandList>
</Command>
</PopoverContent>
</Popover>
<div className="no-scrollbar -m-1.5 flex gap-1 overflow-y-auto p-1.5">
{mentions.map((mention) => {
const item = SAMPLE_DATA.mentionable.find(
(item) => item.title === mention
)
if (!item) {
return null
}
return (
<InputGroupButton
key={mention}
size="sm"
variant="secondary"
className="rounded-full !pl-2"
onClick={() => {
setMentions((prev) => prev.filter((m) => m !== mention))
}}
>
<MentionableIcon item={item} />
{item.title}
<IconX />
</InputGroupButton>
)
})}
</div>
</InputGroupAddon>
<InputGroupAddon align="block-end" className="gap-1">
<Tooltip>
<TooltipTrigger asChild>
<InputGroupButton
size="icon-sm"
className="rounded-full"
aria-label="Attach file"
>
<IconPaperclip />
</InputGroupButton>
</TooltipTrigger>
<TooltipContent>Attach file</TooltipContent>
</Tooltip>
<DropdownMenu
open={modelPopoverOpen}
onOpenChange={setModelPopoverOpen}
>
<Tooltip>
<TooltipTrigger asChild>
<DropdownMenuTrigger asChild>
<InputGroupButton size="sm" className="rounded-full">
{selectedModel.name}
</InputGroupButton>
</DropdownMenuTrigger>
</TooltipTrigger>
<TooltipContent>Select AI model</TooltipContent>
</Tooltip>
<DropdownMenuContent
side="top"
align="start"
className="[--radius:1rem]"
>
<DropdownMenuGroup className="w-42">
<DropdownMenuLabel className="text-muted-foreground text-xs">
Select Agent Mode
</DropdownMenuLabel>
{SAMPLE_DATA.models.map((model) => (
<DropdownMenuCheckboxItem
key={model.name}
checked={model.name === selectedModel.name}
onCheckedChange={(checked) => {
if (checked) {
setSelectedModel(model)
}
}}
className="pl-2 *:[span:first-child]:right-2 *:[span:first-child]:left-auto"
>
{model.name}
{model.badge && (
<Badge
variant="secondary"
className="h-5 rounded-sm bg-blue-100 px-1 text-xs text-blue-800 dark:bg-blue-900 dark:text-blue-100"
>
{model.badge}
</Badge>
)}
</DropdownMenuCheckboxItem>
))}
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
<DropdownMenu open={scopeMenuOpen} onOpenChange={setScopeMenuOpen}>
<DropdownMenuTrigger asChild>
<InputGroupButton size="sm" className="rounded-full">
<IconWorld /> All Sources
</InputGroupButton>
</DropdownMenuTrigger>
<DropdownMenuContent
side="top"
align="end"
className="[--radius:1rem]"
>
<DropdownMenuGroup>
<DropdownMenuItem
asChild
onSelect={(e) => e.preventDefault()}
>
<label htmlFor="web-search">
<IconWorld /> Web Search{" "}
<Switch
id="web-search"
className="ml-auto"
defaultChecked
/>
</label>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem
asChild
onSelect={(e) => e.preventDefault()}
>
<label htmlFor="apps">
<IconApps /> Apps and Integrations
<Switch id="apps" className="ml-auto" defaultChecked />
</label>
</DropdownMenuItem>
<DropdownMenuItem>
<IconCircleDashedPlus /> All Sources I can access
</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<Avatar className="size-4">
<AvatarImage src="https://github.com/shadcn.png" />
<AvatarFallback>CN</AvatarFallback>
</Avatar>
shadcn
</DropdownMenuSubTrigger>
<DropdownMenuSubContent className="w-72 p-0 [--radius:1rem]">
<Command>
<CommandInput
placeholder="Find or use knowledge in..."
autoFocus
/>
<CommandList>
<CommandEmpty>No knowledge found</CommandEmpty>
<CommandGroup>
{SAMPLE_DATA.mentionable
.filter((item) => item.type === "user")
.map((user) => (
<CommandItem
key={user.title}
value={user.title}
onSelect={() => {
// Handle user selection here
console.log("Selected user:", user.title)
}}
>
<Avatar className="size-4">
<AvatarImage src={user.image} />
<AvatarFallback>
{user.title[0]}
</AvatarFallback>
</Avatar>
{user.title}{" "}
<span className="text-muted-foreground">
- {user.workspace}
</span>
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</DropdownMenuSubContent>
</DropdownMenuSub>
<DropdownMenuItem>
<IconBook /> Help Center
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<IconPlus /> Connect Apps
</DropdownMenuItem>
<DropdownMenuLabel className="text-muted-foreground text-xs">
We&apos;ll only search in the sources selected here.
</DropdownMenuLabel>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
<InputGroupButton
aria-label="Send"
className="ml-auto rounded-full"
variant="default"
size="icon-sm"
>
<IconArrowUp />
</InputGroupButton>
</InputGroupAddon>
</InputGroup>
</Field>
</form>
)
}

View File

@@ -0,0 +1,21 @@
import { Badge } from "@/registry/new-york-v4/ui/badge"
import { Spinner } from "@/registry/new-york-v4/ui/spinner"
export function SpinnerBadge() {
return (
<div className="flex items-center gap-2">
<Badge>
<Spinner />
Syncing
</Badge>
<Badge variant="secondary">
<Spinner />
Updating
</Badge>
<Badge variant="outline">
<Spinner />
Loading
</Badge>
</div>
)
}

View File

@@ -0,0 +1,31 @@
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle,
} from "@/registry/new-york-v4/ui/empty"
import { Spinner } from "@/registry/new-york-v4/ui/spinner"
export function SpinnerEmpty() {
return (
<Empty className="w-full border md:p-6">
<EmptyHeader>
<EmptyMedia variant="icon">
<Spinner />
</EmptyMedia>
<EmptyTitle>Processing your request</EmptyTitle>
<EmptyDescription>
Please wait while we process your request. Do not refresh the page.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<Button variant="outline" size="sm">
Cancel
</Button>
</EmptyContent>
</Empty>
)
}

View File

@@ -0,0 +1,102 @@
import { type Metadata } from "next"
import Image from "next/image"
import Link from "next/link"
import { PlusSignIcon } from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import { Announcement } from "@/components/announcement"
import { ExamplesNav } from "@/components/examples-nav"
import {
PageActions,
PageHeader,
PageHeaderDescription,
PageHeaderHeading,
} from "@/components/page-header"
import { PageNav } from "@/components/page-nav"
import { ThemeSelector } from "@/components/theme-selector"
import { Button } from "@/registry/new-york-v4/ui/button"
import { RootComponents } from "./components"
const title = "The Foundation for your Design System"
const description =
"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
export const metadata: Metadata = {
title,
description,
openGraph: {
images: [
{
url: `/og?title=${encodeURIComponent(
title
)}&description=${encodeURIComponent(description)}`,
},
],
},
twitter: {
card: "summary_large_image",
images: [
{
url: `/og?title=${encodeURIComponent(
title
)}&description=${encodeURIComponent(description)}`,
},
],
},
}
export default function IndexPage() {
return (
<div className="flex flex-1 flex-col">
<PageHeader>
<Announcement />
<PageHeaderHeading className="max-w-4xl">{title}</PageHeaderHeading>
<PageHeaderDescription>{description}</PageHeaderDescription>
<PageActions>
<Button asChild size="sm" className="h-[31px] rounded-lg">
<Link href="/create">
<HugeiconsIcon icon={PlusSignIcon} />
New Project
</Link>
</Button>
<Button asChild size="sm" variant="ghost" className="rounded-lg">
<Link href="/docs/components">View Components</Link>
</Button>
</PageActions>
</PageHeader>
<PageNav className="hidden md:flex">
<ExamplesNav className="[&>a:first-child]:text-primary flex-1 overflow-hidden" />
<ThemeSelector className="mr-4 hidden md:flex" />
</PageNav>
<div className="container-wrapper section-soft flex-1 pb-6">
<div className="container overflow-hidden">
<section className="border-border/50 -mx-4 w-[160vw] overflow-hidden rounded-lg border md:hidden md:w-[150vw]">
<Image
src="/r/styles/new-york-v4/dashboard-01-light.png"
width={1400}
height={875}
alt="Dashboard"
className="block dark:hidden"
priority
/>
<Image
src="/r/styles/new-york-v4/dashboard-01-dark.png"
width={1400}
height={875}
alt="Dashboard"
className="hidden dark:block"
priority
/>
</section>
<section className="theme-container hidden md:block">
<RootComponents />
</section>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,34 @@
import { getAllBlockIds } from "@/lib/blocks"
import { registryCategories } from "@/lib/categories"
import { BlockDisplay } from "@/components/block-display"
import { getActiveStyle } from "@/registry/_legacy-styles"
export const revalidate = false
export const dynamic = "force-static"
export const dynamicParams = false
export async function generateStaticParams() {
return registryCategories.map((category) => ({
categories: [category.slug],
}))
}
export default async function BlocksPage({
params,
}: {
params: Promise<{ categories?: string[] }>
}) {
const [{ categories = [] }, activeStyle] = await Promise.all([
params,
getActiveStyle(),
])
const blocks = await getAllBlockIds(["registry:block"], categories)
return (
<div className="flex flex-col gap-12 md:gap-24">
{blocks.map((name) => (
<BlockDisplay name={name} key={name} styleName={activeStyle.name} />
))}
</div>
)
}

View File

@@ -0,0 +1,79 @@
import { type Metadata } from "next"
import Link from "next/link"
import { Announcement } from "@/components/announcement"
import { BlocksNav } from "@/components/blocks-nav"
import {
PageActions,
PageHeader,
PageHeaderDescription,
PageHeaderHeading,
} from "@/components/page-header"
import { PageNav } from "@/components/page-nav"
import { Button } from "@/registry/new-york-v4/ui/button"
const title = "Building Blocks for the Web"
const description =
"Clean, modern building blocks. Copy and paste into your apps. Works with all React frameworks. Open Source. Free forever."
export const metadata: Metadata = {
title,
description,
openGraph: {
images: [
{
url: `/og?title=${encodeURIComponent(
title
)}&description=${encodeURIComponent(description)}`,
},
],
},
twitter: {
card: "summary_large_image",
images: [
{
url: `/og?title=${encodeURIComponent(
title
)}&description=${encodeURIComponent(description)}`,
},
],
},
}
export default function BlocksLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<>
<PageHeader>
<Announcement />
<PageHeaderHeading>{title}</PageHeaderHeading>
<PageHeaderDescription>{description}</PageHeaderDescription>
<PageActions>
<Button asChild size="sm">
<a href="#blocks">Browse Blocks</a>
</Button>
<Button asChild variant="ghost" size="sm">
<Link href="/docs/blocks">Add a block</Link>
</Button>
</PageActions>
</PageHeader>
<PageNav id="blocks">
<BlocksNav />
<Button
asChild
variant="secondary"
size="sm"
className="mr-7 hidden shadow-none lg:flex"
>
<Link href="/blocks/sidebar">Browse all blocks</Link>
</Button>
</PageNav>
<div className="container-wrapper section-soft flex-1 md:py-12">
<div className="container">{children}</div>
</div>
</>
)
}

View File

@@ -0,0 +1,35 @@
import Link from "next/link"
import { BlockDisplay } from "@/components/block-display"
import { getActiveStyle } from "@/registry/_legacy-styles"
import { Button } from "@/registry/new-york-v4/ui/button"
export const dynamic = "force-static"
export const revalidate = false
const FEATURED_BLOCKS = [
"dashboard-01",
"sidebar-07",
"sidebar-03",
"login-03",
"login-04",
]
export default async function BlocksPage() {
const activeStyle = await getActiveStyle()
return (
<div className="flex flex-col gap-12 md:gap-24">
{FEATURED_BLOCKS.map((name) => (
<BlockDisplay name={name} key={name} styleName={activeStyle.name} />
))}
<div className="container-wrapper">
<div className="container flex justify-center py-6">
<Button asChild variant="outline">
<Link href="/blocks/sidebar">Browse more blocks</Link>
</Button>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,74 @@
import * as React from "react"
import { notFound } from "next/navigation"
import { cn } from "@/lib/utils"
import { ChartDisplay } from "@/components/chart-display"
import { getActiveStyle } from "@/registry/_legacy-styles"
import { charts } from "@/app/(app)/charts/charts"
export const revalidate = false
export const dynamic = "force-static"
export const dynamicParams = false
interface ChartPageProps {
params: Promise<{
type: string
}>
}
const chartTypes = [
"area",
"bar",
"line",
"pie",
"radar",
"radial",
"tooltip",
] as const
type ChartType = (typeof chartTypes)[number]
export async function generateStaticParams() {
return chartTypes.map((type) => ({
type,
}))
}
export default async function ChartPage({ params }: ChartPageProps) {
const { type } = await params
if (!chartTypes.includes(type as ChartType)) {
return notFound()
}
const chartType = type as ChartType
const chartList = charts[chartType]
const activeStyle = await getActiveStyle()
return (
<div className="grid flex-1 gap-12 lg:gap-24">
<h2 className="sr-only">
{type.charAt(0).toUpperCase() + type.slice(1)} Charts
</h2>
<div className="grid flex-1 scroll-mt-20 items-stretch gap-10 md:grid-cols-2 md:gap-6 lg:grid-cols-3 xl:gap-10">
{Array.from({ length: 12 }).map((_, index) => {
const chart = chartList[index]
return chart ? (
<ChartDisplay
key={chart.id}
name={chart.id}
styleName={activeStyle.name}
className={cn(chart.fullWidth && "md:col-span-2 lg:col-span-3")}
>
<chart.component />
</ChartDisplay>
) : (
<div
key={`empty-${index}`}
className="hidden aspect-square w-full rounded-lg border border-dashed xl:block"
/>
)
})}
</div>
</div>
)
}

View File

@@ -0,0 +1,275 @@
import type * as React from "react"
import { ChartAreaAxes } from "@/registry/new-york-v4/charts/chart-area-axes"
import { ChartAreaDefault } from "@/registry/new-york-v4/charts/chart-area-default"
import { ChartAreaGradient } from "@/registry/new-york-v4/charts/chart-area-gradient"
import { ChartAreaIcons } from "@/registry/new-york-v4/charts/chart-area-icons"
import { ChartAreaInteractive } from "@/registry/new-york-v4/charts/chart-area-interactive"
import { ChartAreaLegend } from "@/registry/new-york-v4/charts/chart-area-legend"
import { ChartAreaLinear } from "@/registry/new-york-v4/charts/chart-area-linear"
import { ChartAreaStacked } from "@/registry/new-york-v4/charts/chart-area-stacked"
import { ChartAreaStackedExpand } from "@/registry/new-york-v4/charts/chart-area-stacked-expand"
import { ChartAreaStep } from "@/registry/new-york-v4/charts/chart-area-step"
import { ChartBarActive } from "@/registry/new-york-v4/charts/chart-bar-active"
import { ChartBarDefault } from "@/registry/new-york-v4/charts/chart-bar-default"
import { ChartBarHorizontal } from "@/registry/new-york-v4/charts/chart-bar-horizontal"
import { ChartBarInteractive } from "@/registry/new-york-v4/charts/chart-bar-interactive"
import { ChartBarLabel } from "@/registry/new-york-v4/charts/chart-bar-label"
import { ChartBarLabelCustom } from "@/registry/new-york-v4/charts/chart-bar-label-custom"
import { ChartBarMixed } from "@/registry/new-york-v4/charts/chart-bar-mixed"
import { ChartBarMultiple } from "@/registry/new-york-v4/charts/chart-bar-multiple"
import { ChartBarNegative } from "@/registry/new-york-v4/charts/chart-bar-negative"
import { ChartBarStacked } from "@/registry/new-york-v4/charts/chart-bar-stacked"
import { ChartLineDefault } from "@/registry/new-york-v4/charts/chart-line-default"
import { ChartLineDots } from "@/registry/new-york-v4/charts/chart-line-dots"
import { ChartLineDotsColors } from "@/registry/new-york-v4/charts/chart-line-dots-colors"
import { ChartLineDotsCustom } from "@/registry/new-york-v4/charts/chart-line-dots-custom"
import { ChartLineInteractive } from "@/registry/new-york-v4/charts/chart-line-interactive"
import { ChartLineLabel } from "@/registry/new-york-v4/charts/chart-line-label"
import { ChartLineLabelCustom } from "@/registry/new-york-v4/charts/chart-line-label-custom"
import { ChartLineLinear } from "@/registry/new-york-v4/charts/chart-line-linear"
import { ChartLineMultiple } from "@/registry/new-york-v4/charts/chart-line-multiple"
import { ChartLineStep } from "@/registry/new-york-v4/charts/chart-line-step"
import { ChartPieDonut } from "@/registry/new-york-v4/charts/chart-pie-donut"
import { ChartPieDonutActive } from "@/registry/new-york-v4/charts/chart-pie-donut-active"
import { ChartPieDonutText } from "@/registry/new-york-v4/charts/chart-pie-donut-text"
import { ChartPieInteractive } from "@/registry/new-york-v4/charts/chart-pie-interactive"
import { ChartPieLabel } from "@/registry/new-york-v4/charts/chart-pie-label"
import { ChartPieLabelCustom } from "@/registry/new-york-v4/charts/chart-pie-label-custom"
import { ChartPieLabelList } from "@/registry/new-york-v4/charts/chart-pie-label-list"
import { ChartPieLegend } from "@/registry/new-york-v4/charts/chart-pie-legend"
import { ChartPieSeparatorNone } from "@/registry/new-york-v4/charts/chart-pie-separator-none"
import { ChartPieSimple } from "@/registry/new-york-v4/charts/chart-pie-simple"
import { ChartPieStacked } from "@/registry/new-york-v4/charts/chart-pie-stacked"
import { ChartRadarDefault } from "@/registry/new-york-v4/charts/chart-radar-default"
import { ChartRadarDots } from "@/registry/new-york-v4/charts/chart-radar-dots"
import { ChartRadarGridCircle } from "@/registry/new-york-v4/charts/chart-radar-grid-circle"
import { ChartRadarGridCircleFill } from "@/registry/new-york-v4/charts/chart-radar-grid-circle-fill"
import { ChartRadarGridCircleNoLines } from "@/registry/new-york-v4/charts/chart-radar-grid-circle-no-lines"
import { ChartRadarGridCustom } from "@/registry/new-york-v4/charts/chart-radar-grid-custom"
import { ChartRadarGridFill } from "@/registry/new-york-v4/charts/chart-radar-grid-fill"
import { ChartRadarGridNone } from "@/registry/new-york-v4/charts/chart-radar-grid-none"
import { ChartRadarIcons } from "@/registry/new-york-v4/charts/chart-radar-icons"
import { ChartRadarLabelCustom } from "@/registry/new-york-v4/charts/chart-radar-label-custom"
import { ChartRadarLegend } from "@/registry/new-york-v4/charts/chart-radar-legend"
import { ChartRadarLinesOnly } from "@/registry/new-york-v4/charts/chart-radar-lines-only"
import { ChartRadarMultiple } from "@/registry/new-york-v4/charts/chart-radar-multiple"
import { ChartRadarRadius } from "@/registry/new-york-v4/charts/chart-radar-radius"
import { ChartRadialGrid } from "@/registry/new-york-v4/charts/chart-radial-grid"
import { ChartRadialLabel } from "@/registry/new-york-v4/charts/chart-radial-label"
import { ChartRadialShape } from "@/registry/new-york-v4/charts/chart-radial-shape"
import { ChartRadialSimple } from "@/registry/new-york-v4/charts/chart-radial-simple"
import { ChartRadialStacked } from "@/registry/new-york-v4/charts/chart-radial-stacked"
import { ChartRadialText } from "@/registry/new-york-v4/charts/chart-radial-text"
import { ChartTooltipAdvanced } from "@/registry/new-york-v4/charts/chart-tooltip-advanced"
import { ChartTooltipDefault } from "@/registry/new-york-v4/charts/chart-tooltip-default"
import { ChartTooltipFormatter } from "@/registry/new-york-v4/charts/chart-tooltip-formatter"
import { ChartTooltipIcons } from "@/registry/new-york-v4/charts/chart-tooltip-icons"
import { ChartTooltipIndicatorLine } from "@/registry/new-york-v4/charts/chart-tooltip-indicator-line"
import { ChartTooltipIndicatorNone } from "@/registry/new-york-v4/charts/chart-tooltip-indicator-none"
import { ChartTooltipLabelCustom } from "@/registry/new-york-v4/charts/chart-tooltip-label-custom"
import { ChartTooltipLabelFormatter } from "@/registry/new-york-v4/charts/chart-tooltip-label-formatter"
import { ChartTooltipLabelNone } from "@/registry/new-york-v4/charts/chart-tooltip-label-none"
type ChartComponent = React.ComponentType
interface ChartItem {
id: string
component: ChartComponent
fullWidth?: boolean
}
interface ChartGroups {
area: ChartItem[]
bar: ChartItem[]
line: ChartItem[]
pie: ChartItem[]
radar: ChartItem[]
radial: ChartItem[]
tooltip: ChartItem[]
}
export const charts: ChartGroups = {
area: [
{
id: "chart-area-interactive",
component: ChartAreaInteractive,
fullWidth: true,
},
{ id: "chart-area-default", component: ChartAreaDefault },
{ id: "chart-area-linear", component: ChartAreaLinear },
{ id: "chart-area-step", component: ChartAreaStep },
{ id: "chart-area-legend", component: ChartAreaLegend },
{ id: "chart-area-stacked", component: ChartAreaStacked },
{ id: "chart-area-stacked-expand", component: ChartAreaStackedExpand },
{ id: "chart-area-icons", component: ChartAreaIcons },
{ id: "chart-area-gradient", component: ChartAreaGradient },
{ id: "chart-area-axes", component: ChartAreaAxes },
],
bar: [
{
id: "chart-bar-interactive",
component: ChartBarInteractive,
fullWidth: true,
},
{ id: "chart-bar-default", component: ChartBarDefault },
{ id: "chart-bar-horizontal", component: ChartBarHorizontal },
{ id: "chart-bar-multiple", component: ChartBarMultiple },
{ id: "chart-bar-stacked", component: ChartBarStacked },
{ id: "chart-bar-label", component: ChartBarLabel },
{ id: "chart-bar-label-custom", component: ChartBarLabelCustom },
{ id: "chart-bar-mixed", component: ChartBarMixed },
{ id: "chart-bar-active", component: ChartBarActive },
{ id: "chart-bar-negative", component: ChartBarNegative },
],
line: [
{
id: "chart-line-interactive",
component: ChartLineInteractive,
fullWidth: true,
},
{ id: "chart-line-default", component: ChartLineDefault },
{ id: "chart-line-linear", component: ChartLineLinear },
{ id: "chart-line-step", component: ChartLineStep },
{ id: "chart-line-multiple", component: ChartLineMultiple },
{ id: "chart-line-dots", component: ChartLineDots },
{ id: "chart-line-dots-custom", component: ChartLineDotsCustom },
{ id: "chart-line-dots-colors", component: ChartLineDotsColors },
{ id: "chart-line-label", component: ChartLineLabel },
{ id: "chart-line-label-custom", component: ChartLineLabelCustom },
],
pie: [
{ id: "chart-pie-simple", component: ChartPieSimple },
{ id: "chart-pie-separator-none", component: ChartPieSeparatorNone },
{ id: "chart-pie-label", component: ChartPieLabel },
{ id: "chart-pie-label-custom", component: ChartPieLabelCustom },
{ id: "chart-pie-label-list", component: ChartPieLabelList },
{ id: "chart-pie-legend", component: ChartPieLegend },
{ id: "chart-pie-donut", component: ChartPieDonut },
{ id: "chart-pie-donut-active", component: ChartPieDonutActive },
{ id: "chart-pie-donut-text", component: ChartPieDonutText },
{ id: "chart-pie-stacked", component: ChartPieStacked },
{ id: "chart-pie-interactive", component: ChartPieInteractive },
],
radar: [
{ id: "chart-radar-default", component: ChartRadarDefault },
{ id: "chart-radar-dots", component: ChartRadarDots },
{ id: "chart-radar-lines-only", component: ChartRadarLinesOnly },
{ id: "chart-radar-label-custom", component: ChartRadarLabelCustom },
{ id: "chart-radar-grid-custom", component: ChartRadarGridCustom },
{ id: "chart-radar-grid-none", component: ChartRadarGridNone },
{ id: "chart-radar-grid-circle", component: ChartRadarGridCircle },
{
id: "chart-radar-grid-circle-no-lines",
component: ChartRadarGridCircleNoLines,
},
{ id: "chart-radar-grid-circle-fill", component: ChartRadarGridCircleFill },
{ id: "chart-radar-grid-fill", component: ChartRadarGridFill },
{ id: "chart-radar-multiple", component: ChartRadarMultiple },
{ id: "chart-radar-legend", component: ChartRadarLegend },
{ id: "chart-radar-icons", component: ChartRadarIcons },
{ id: "chart-radar-radius", component: ChartRadarRadius },
],
radial: [
{ id: "chart-radial-simple", component: ChartRadialSimple },
{ id: "chart-radial-label", component: ChartRadialLabel },
{ id: "chart-radial-grid", component: ChartRadialGrid },
{ id: "chart-radial-text", component: ChartRadialText },
{ id: "chart-radial-shape", component: ChartRadialShape },
{ id: "chart-radial-stacked", component: ChartRadialStacked },
],
tooltip: [
{ id: "chart-tooltip-default", component: ChartTooltipDefault },
{
id: "chart-tooltip-indicator-line",
component: ChartTooltipIndicatorLine,
},
{
id: "chart-tooltip-indicator-none",
component: ChartTooltipIndicatorNone,
},
{ id: "chart-tooltip-label-custom", component: ChartTooltipLabelCustom },
{
id: "chart-tooltip-label-formatter",
component: ChartTooltipLabelFormatter,
},
{ id: "chart-tooltip-label-none", component: ChartTooltipLabelNone },
{ id: "chart-tooltip-formatter", component: ChartTooltipFormatter },
{ id: "chart-tooltip-icons", component: ChartTooltipIcons },
{ id: "chart-tooltip-advanced", component: ChartTooltipAdvanced },
],
}
// Export individual components for backward compatibility
export {
ChartAreaDefault,
ChartAreaLinear,
ChartAreaStep,
ChartAreaLegend,
ChartAreaStacked,
ChartAreaStackedExpand,
ChartAreaIcons,
ChartAreaGradient,
ChartAreaAxes,
ChartAreaInteractive,
ChartBarDefault,
ChartBarHorizontal,
ChartBarMultiple,
ChartBarStacked,
ChartBarLabel,
ChartBarLabelCustom,
ChartBarMixed,
ChartBarActive,
ChartBarNegative,
ChartBarInteractive,
ChartLineDefault,
ChartLineLinear,
ChartLineStep,
ChartLineMultiple,
ChartLineDots,
ChartLineDotsCustom,
ChartLineDotsColors,
ChartLineLabel,
ChartLineLabelCustom,
ChartLineInteractive,
ChartPieSimple,
ChartPieSeparatorNone,
ChartPieLabel,
ChartPieLabelCustom,
ChartPieLabelList,
ChartPieLegend,
ChartPieDonut,
ChartPieDonutActive,
ChartPieDonutText,
ChartPieStacked,
ChartPieInteractive,
ChartRadarDefault,
ChartRadarDots,
ChartRadarLinesOnly,
ChartRadarLabelCustom,
ChartRadarGridCustom,
ChartRadarGridNone,
ChartRadarGridCircle,
ChartRadarGridCircleNoLines,
ChartRadarGridCircleFill,
ChartRadarGridFill,
ChartRadarMultiple,
ChartRadarLegend,
ChartRadarIcons,
ChartRadarRadius,
ChartRadialSimple,
ChartRadialLabel,
ChartRadialGrid,
ChartRadialText,
ChartRadialShape,
ChartRadialStacked,
ChartTooltipDefault,
ChartTooltipIndicatorLine,
ChartTooltipIndicatorNone,
ChartTooltipLabelCustom,
ChartTooltipLabelFormatter,
ChartTooltipLabelNone,
ChartTooltipFormatter,
ChartTooltipIcons,
ChartTooltipAdvanced,
}

View File

@@ -0,0 +1,75 @@
import { type Metadata } from "next"
import Link from "next/link"
import { Announcement } from "@/components/announcement"
import { ChartsNav } from "@/components/charts-nav"
import {
PageActions,
PageHeader,
PageHeaderDescription,
PageHeaderHeading,
} from "@/components/page-header"
import { PageNav } from "@/components/page-nav"
import { ThemeSelector } from "@/components/theme-selector"
import { Button } from "@/registry/new-york-v4/ui/button"
const title = "Beautiful Charts & Graphs"
const description =
"A collection of ready-to-use chart components built with Recharts. From basic charts to rich data displays, copy and paste into your apps."
export const metadata: Metadata = {
title,
description,
openGraph: {
images: [
{
url: `/og?title=${encodeURIComponent(
title
)}&description=${encodeURIComponent(description)}`,
},
],
},
twitter: {
card: "summary_large_image",
images: [
{
url: `/og?title=${encodeURIComponent(
title
)}&description=${encodeURIComponent(description)}`,
},
],
},
}
export default function ChartsLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<>
<PageHeader>
<Announcement />
<PageHeaderHeading>{title}</PageHeaderHeading>
<PageHeaderDescription>{description}</PageHeaderDescription>
<PageActions>
<Button asChild size="sm">
<a href="#charts">Browse Charts</a>
</Button>
<Button asChild variant="ghost" size="sm">
<Link href="/docs/components/chart">Documentation</Link>
</Button>
</PageActions>
</PageHeader>
<PageNav id="charts">
<ChartsNav />
<ThemeSelector className="mr-4 hidden md:flex" />
</PageNav>
<div className="container-wrapper section-soft flex-1">
<div className="container pb-6">
<section className="theme-container">{children}</section>
</div>
</div>
</>
)
}

View File

@@ -0,0 +1,78 @@
import { type Metadata } from "next"
import Link from "next/link"
import { Announcement } from "@/components/announcement"
import { ColorsNav } from "@/components/colors-nav"
import {
PageActions,
PageHeader,
PageHeaderDescription,
PageHeaderHeading,
} from "@/components/page-header"
import { Button } from "@/registry/new-york-v4/ui/button"
const title = "Tailwind Colors in Every Format"
const description =
"The complete Tailwind color palette in HEX, RGB, HSL, CSS variables, and classes. Ready to copy and paste into your project."
export const metadata: Metadata = {
title,
description,
openGraph: {
images: [
{
url: `/og?title=${encodeURIComponent(
title
)}&description=${encodeURIComponent(description)}`,
},
],
},
twitter: {
card: "summary_large_image",
images: [
{
url: `/og?title=${encodeURIComponent(
title
)}&description=${encodeURIComponent(description)}`,
},
],
},
}
export default function ColorsLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<div>
<PageHeader>
<Announcement />
<PageHeaderHeading>{title}</PageHeaderHeading>
<PageHeaderDescription>{description}</PageHeaderDescription>
<PageActions>
<Button asChild size="sm">
<a href="#colors">Browse Colors</a>
</Button>
<Button asChild variant="ghost" size="sm">
<Link href="/docs/theming">Documentation</Link>
</Button>
</PageActions>
</PageHeader>
<div className="hidden">
<div className="container-wrapper">
<div className="container flex items-center justify-between gap-8 py-4">
<ColorsNav className="[&>a:first-child]:text-primary flex-1 overflow-hidden" />
</div>
</div>
</div>
<div className="container-wrapper">
<div className="container py-6">
<section id="colors" className="scroll-mt-20">
{children}
</section>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,17 @@
import { getColors } from "@/lib/colors"
import { ColorPalette } from "@/components/color-palette"
export const dynamic = "force-static"
export const revalidate = false
export default function ColorsPage() {
const colors = getColors()
return (
<div className="grid gap-8 lg:gap-16 xl:gap-20">
{colors.map((colorPalette) => (
<ColorPalette key={colorPalette.name} colorPalette={colorPalette} />
))}
</div>
)
}

View File

@@ -0,0 +1,214 @@
import Link from "next/link"
import { notFound } from "next/navigation"
import { mdxComponents } from "@/mdx-components"
import {
IconArrowLeft,
IconArrowRight,
IconArrowUpRight,
} from "@tabler/icons-react"
import fm from "front-matter"
import { findNeighbour } from "fumadocs-core/page-tree"
import z from "zod"
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"
import { Button } from "@/registry/new-york-v4/ui/button"
export const revalidate = false
export const dynamic = "force-static"
export const dynamicParams = false
export function generateStaticParams() {
return source.generateParams()
}
export async function generateMetadata(props: {
params: Promise<{ slug: string[] }>
}) {
const params = await props.params
const page = source.getPage(params.slug)
if (!page) {
notFound()
}
const doc = page.data
if (!doc.title || !doc.description) {
notFound()
}
return {
title: doc.title,
description: doc.description,
openGraph: {
title: doc.title,
description: doc.description,
type: "article",
url: absoluteUrl(page.url),
images: [
{
url: `/og?title=${encodeURIComponent(
doc.title
)}&description=${encodeURIComponent(doc.description)}`,
},
],
},
twitter: {
card: "summary_large_image",
title: doc.title,
description: doc.description,
images: [
{
url: `/og?title=${encodeURIComponent(
doc.title
)}&description=${encodeURIComponent(doc.description)}`,
},
],
creator: "@shadcn",
},
}
}
export default async function Page(props: {
params: Promise<{ slug: string[] }>
}) {
const params = await props.params
const page = source.getPage(params.slug)
if (!page) {
notFound()
}
const doc = page.data
const MDX = doc.body
const neighbours = findNeighbour(source.pageTree, page.url)
const raw = await page.data.getText("raw")
const { attributes } = fm(raw)
const { links } = z
.object({
links: z
.object({
doc: z.string().optional(),
api: z.string().optional(),
})
.optional(),
})
.parse(attributes)
return (
<div className="flex items-stretch text-[1.05rem] sm:text-[15px] xl:w-full">
<div className="flex min-w-0 flex-1 flex-col">
<div className="h-(--top-spacing) shrink-0" />
<div className="mx-auto flex w-full max-w-2xl min-w-0 flex-1 flex-col gap-8 px-4 py-6 text-neutral-800 md:px-0 lg:py-8 dark:text-neutral-300">
<div className="flex flex-col gap-2">
<div className="flex flex-col gap-2">
<div className="flex items-start justify-between">
<h1 className="scroll-m-20 text-4xl font-semibold tracking-tight sm:text-3xl xl:text-4xl">
{doc.title}
</h1>
<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 page={raw} url={absoluteUrl(page.url)} />
{neighbours.previous && (
<Button
variant="secondary"
size="icon"
className="extend-touch-target ml-auto size-8 shadow-none md:size-7"
asChild
>
<Link href={neighbours.previous.url}>
<IconArrowLeft />
<span className="sr-only">Previous</span>
</Link>
</Button>
)}
{neighbours.next && (
<Button
variant="secondary"
size="icon"
className="extend-touch-target size-8 shadow-none md:size-7"
asChild
>
<Link href={neighbours.next.url}>
<span className="sr-only">Next</span>
<IconArrowRight />
</Link>
</Button>
)}
</div>
</div>
{doc.description && (
<p className="text-muted-foreground text-[1.05rem] text-balance sm:text-base">
{doc.description}
</p>
)}
</div>
{links ? (
<div className="flex items-center gap-2 pt-4">
{links?.doc && (
<Badge asChild variant="secondary" className="rounded-full">
<a href={links.doc} target="_blank" rel="noreferrer">
Docs <IconArrowUpRight />
</a>
</Badge>
)}
{links?.api && (
<Badge asChild variant="secondary" className="rounded-full">
<a href={links.api} target="_blank" rel="noreferrer">
API Reference <IconArrowUpRight />
</a>
</Badge>
)}
</div>
) : null}
</div>
<div className="w-full flex-1 *:data-[slot=alert]:first:mt-0">
<MDX components={mdxComponents} />
</div>
</div>
<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"
size="sm"
asChild
className="shadow-none"
>
<Link href={neighbours.previous.url}>
<IconArrowLeft /> {neighbours.previous.name}
</Link>
</Button>
)}
{neighbours.next && (
<Button
variant="secondary"
size="sm"
className="ml-auto shadow-none"
asChild
>
<Link href={neighbours.next.url}>
{neighbours.next.name} <IconArrowRight />
</Link>
</Button>
)}
</div>
</div>
<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" />
{doc.toc?.length ? (
<div className="no-scrollbar overflow-y-auto px-8">
<DocsTableOfContents toc={doc.toc} />
<div className="h-12" />
</div>
) : null}
<div className="flex flex-1 flex-col gap-12 px-6">
<OpenInV0Cta />
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,18 @@
import { source } from "@/lib/source"
import { DocsSidebar } from "@/components/docs-sidebar"
import { SidebarProvider } from "@/registry/new-york-v4/ui/sidebar"
export default function DocsLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<div className="container-wrapper flex flex-1 flex-col px-2">
<SidebarProvider className="3xl:fixed:container 3xl:fixed:px-3 min-h-min flex-1 items-start px-0 [--sidebar-width:220px] [--top-spacing:0] lg:grid lg:grid-cols-[var(--sidebar-width)_minmax(0,1fr)] lg:[--sidebar-width:240px] lg:[--top-spacing:calc(var(--spacing)*4)]">
<DocsSidebar tree={source.pageTree} />
<div className="h-full w-full">{children}</div>
</SidebarProvider>
</div>
)
}

View File

@@ -0,0 +1,65 @@
"use client"
import * as React from "react"
import { cn } from "@/lib/utils"
import { Icons } from "@/components/icons"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Field,
FieldGroup,
FieldLabel,
FieldSeparator,
} from "@/registry/new-york-v4/ui/field"
import { Input } from "@/registry/new-york-v4/ui/input"
import { Spinner } from "@/registry/new-york-v4/ui/spinner"
export function UserAuthForm({
className,
...props
}: React.ComponentProps<"div">) {
const [isLoading, setIsLoading] = React.useState<boolean>(false)
async function onSubmit(event: React.SyntheticEvent) {
event.preventDefault()
setIsLoading(true)
setTimeout(() => {
setIsLoading(false)
}, 3000)
}
return (
<div className={cn("grid gap-6", className)} {...props}>
<form onSubmit={onSubmit}>
<FieldGroup>
<Field>
<FieldLabel className="sr-only" htmlFor="email">
Email
</FieldLabel>
<Input
id="email"
placeholder="name@example.com"
type="email"
autoCapitalize="none"
autoComplete="email"
autoCorrect="off"
disabled={isLoading}
/>
</Field>
<Field>
<Button disabled={isLoading}>
{isLoading && <Spinner />}
Sign In with Email
</Button>
</Field>
</FieldGroup>
</form>
<FieldSeparator>Or continue with</FieldSeparator>
<Button variant="outline" type="button" disabled={isLoading}>
{isLoading ? <Spinner /> : <Icons.gitHub className="mr-2 h-4 w-4" />}{" "}
GitHub
</Button>
</div>
)
}

View File

@@ -0,0 +1,92 @@
import { type Metadata } from "next"
import Image from "next/image"
import Link from "next/link"
import { cn } from "@/lib/utils"
import { buttonVariants } from "@/registry/new-york-v4/ui/button"
import { FieldDescription } from "@/registry/new-york-v4/ui/field"
import { UserAuthForm } from "@/app/(app)/examples/authentication/components/user-auth-form"
export const metadata: Metadata = {
title: "Authentication",
description: "Authentication forms built using the components.",
}
export default function AuthenticationPage() {
return (
<>
<div className="md:hidden">
<Image
src="/examples/authentication-light.png"
width={1280}
height={843}
alt="Authentication"
className="block dark:hidden"
priority
/>
<Image
src="/examples/authentication-dark.png"
width={1280}
height={843}
alt="Authentication"
className="hidden dark:block"
priority
/>
</div>
<div className="relative container hidden flex-1 shrink-0 items-center justify-center md:grid lg:max-w-none lg:grid-cols-2 lg:px-0">
<Link
href="/examples/authentication"
className={cn(
buttonVariants({ variant: "ghost" }),
"absolute top-4 right-4 md:top-8 md:right-8"
)}
>
Login
</Link>
<div className="text-primary relative hidden h-full flex-col p-10 lg:flex dark:border-r">
<div className="bg-primary/5 absolute inset-0" />
<div className="relative z-20 flex items-center text-lg font-medium">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="mr-2 h-6 w-6"
>
<path d="M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3" />
</svg>
Acme Inc
</div>
<div className="relative z-20 mt-auto">
<blockquote className="leading-normal text-balance">
&ldquo;This library has saved me countless hours of work and
helped me deliver stunning designs to my clients faster than ever
before.&rdquo; - Sofia Davis
</blockquote>
</div>
</div>
<div className="flex items-center justify-center lg:h-[1000px] lg:p-8">
<div className="mx-auto flex w-full flex-col justify-center gap-6 sm:w-[350px]">
<div className="flex flex-col gap-2 text-center">
<h1 className="text-2xl font-semibold tracking-tight">
Create an account
</h1>
<p className="text-muted-foreground text-sm">
Enter your email below to create your account
</p>
</div>
<UserAuthForm />
<FieldDescription className="px-6 text-center">
By clicking continue, you agree to our{" "}
<Link href="/terms">Terms of Service</Link> and{" "}
<Link href="/privacy">Privacy Policy</Link>.
</FieldDescription>
</div>
</div>
</div>
</>
)
}

View File

@@ -0,0 +1,182 @@
"use client"
import * as React from "react"
import Link from "next/link"
import {
IconCamera,
IconChartBar,
IconDashboard,
IconDatabase,
IconFileAi,
IconFileDescription,
IconFileWord,
IconFolder,
IconHelp,
IconInnerShadowTop,
IconListDetails,
IconReport,
IconSearch,
IconSettings,
IconUsers,
} from "@tabler/icons-react"
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarHeader,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/registry/new-york-v4/ui/sidebar"
import { NavDocuments } from "@/app/(app)/examples/dashboard/components/nav-documents"
import { NavMain } from "@/app/(app)/examples/dashboard/components/nav-main"
import { NavSecondary } from "@/app/(app)/examples/dashboard/components/nav-secondary"
import { NavUser } from "@/app/(app)/examples/dashboard/components/nav-user"
const data = {
user: {
name: "shadcn",
email: "m@example.com",
avatar: "/avatars/shadcn.jpg",
},
navMain: [
{
title: "Dashboard",
url: "#",
icon: IconDashboard,
},
{
title: "Lifecycle",
url: "#",
icon: IconListDetails,
},
{
title: "Analytics",
url: "#",
icon: IconChartBar,
},
{
title: "Projects",
url: "#",
icon: IconFolder,
},
{
title: "Team",
url: "#",
icon: IconUsers,
},
],
navClouds: [
{
title: "Capture",
icon: IconCamera,
isActive: true,
url: "#",
items: [
{
title: "Active Proposals",
url: "#",
},
{
title: "Archived",
url: "#",
},
],
},
{
title: "Proposal",
icon: IconFileDescription,
url: "#",
items: [
{
title: "Active Proposals",
url: "#",
},
{
title: "Archived",
url: "#",
},
],
},
{
title: "Prompts",
icon: IconFileAi,
url: "#",
items: [
{
title: "Active Proposals",
url: "#",
},
{
title: "Archived",
url: "#",
},
],
},
],
navSecondary: [
{
title: "Settings",
url: "#",
icon: IconSettings,
},
{
title: "Get Help",
url: "#",
icon: IconHelp,
},
{
title: "Search",
url: "#",
icon: IconSearch,
},
],
documents: [
{
name: "Data Library",
url: "#",
icon: IconDatabase,
},
{
name: "Reports",
url: "#",
icon: IconReport,
},
{
name: "Word Assistant",
url: "#",
icon: IconFileWord,
},
],
}
export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
return (
<Sidebar collapsible="none" className="h-auto border-r" {...props}>
<SidebarHeader className="border-b">
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton
asChild
className="data-[slot=sidebar-menu-button]:!p-1.5"
>
<Link href="#">
<IconInnerShadowTop className="!size-5" />
<span className="text-base font-semibold">Acme Inc.</span>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarHeader>
<SidebarContent>
<NavMain items={data.navMain} />
<NavDocuments items={data.documents} />
<NavSecondary items={data.navSecondary} className="mt-auto" />
</SidebarContent>
<SidebarFooter>
<NavUser user={data.user} />
</SidebarFooter>
</Sidebar>
)
}

View File

@@ -0,0 +1,286 @@
"use client"
import * as React from "react"
import { Area, AreaChart, CartesianGrid, XAxis } from "recharts"
import { useIsMobile } from "@/registry/new-york-v4/hooks/use-mobile"
import {
Card,
CardAction,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/registry/new-york-v4/ui/card"
import {
ChartContainer,
ChartTooltip,
ChartTooltipContent,
type ChartConfig,
} from "@/registry/new-york-v4/ui/chart"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/registry/new-york-v4/ui/select"
import {
ToggleGroup,
ToggleGroupItem,
} from "@/registry/new-york-v4/ui/toggle-group"
export const description = "An interactive area chart"
const chartData = [
{ date: "2024-04-01", desktop: 222, mobile: 150 },
{ date: "2024-04-02", desktop: 97, mobile: 180 },
{ date: "2024-04-03", desktop: 167, mobile: 120 },
{ date: "2024-04-04", desktop: 242, mobile: 260 },
{ date: "2024-04-05", desktop: 373, mobile: 290 },
{ date: "2024-04-06", desktop: 301, mobile: 340 },
{ date: "2024-04-07", desktop: 245, mobile: 180 },
{ date: "2024-04-08", desktop: 409, mobile: 320 },
{ date: "2024-04-09", desktop: 59, mobile: 110 },
{ date: "2024-04-10", desktop: 261, mobile: 190 },
{ date: "2024-04-11", desktop: 327, mobile: 350 },
{ date: "2024-04-12", desktop: 292, mobile: 210 },
{ date: "2024-04-13", desktop: 342, mobile: 380 },
{ date: "2024-04-14", desktop: 137, mobile: 220 },
{ date: "2024-04-15", desktop: 120, mobile: 170 },
{ date: "2024-04-16", desktop: 138, mobile: 190 },
{ date: "2024-04-17", desktop: 446, mobile: 360 },
{ date: "2024-04-18", desktop: 364, mobile: 410 },
{ date: "2024-04-19", desktop: 243, mobile: 180 },
{ date: "2024-04-20", desktop: 89, mobile: 150 },
{ date: "2024-04-21", desktop: 137, mobile: 200 },
{ date: "2024-04-22", desktop: 224, mobile: 170 },
{ date: "2024-04-23", desktop: 138, mobile: 230 },
{ date: "2024-04-24", desktop: 387, mobile: 290 },
{ date: "2024-04-25", desktop: 215, mobile: 250 },
{ date: "2024-04-26", desktop: 75, mobile: 130 },
{ date: "2024-04-27", desktop: 383, mobile: 420 },
{ date: "2024-04-28", desktop: 122, mobile: 180 },
{ date: "2024-04-29", desktop: 315, mobile: 240 },
{ date: "2024-04-30", desktop: 454, mobile: 380 },
{ date: "2024-05-01", desktop: 165, mobile: 220 },
{ date: "2024-05-02", desktop: 293, mobile: 310 },
{ date: "2024-05-03", desktop: 247, mobile: 190 },
{ date: "2024-05-04", desktop: 385, mobile: 420 },
{ date: "2024-05-05", desktop: 481, mobile: 390 },
{ date: "2024-05-06", desktop: 498, mobile: 520 },
{ date: "2024-05-07", desktop: 388, mobile: 300 },
{ date: "2024-05-08", desktop: 149, mobile: 210 },
{ date: "2024-05-09", desktop: 227, mobile: 180 },
{ date: "2024-05-10", desktop: 293, mobile: 330 },
{ date: "2024-05-11", desktop: 335, mobile: 270 },
{ date: "2024-05-12", desktop: 197, mobile: 240 },
{ date: "2024-05-13", desktop: 197, mobile: 160 },
{ date: "2024-05-14", desktop: 448, mobile: 490 },
{ date: "2024-05-15", desktop: 473, mobile: 380 },
{ date: "2024-05-16", desktop: 338, mobile: 400 },
{ date: "2024-05-17", desktop: 499, mobile: 420 },
{ date: "2024-05-18", desktop: 315, mobile: 350 },
{ date: "2024-05-19", desktop: 235, mobile: 180 },
{ date: "2024-05-20", desktop: 177, mobile: 230 },
{ date: "2024-05-21", desktop: 82, mobile: 140 },
{ date: "2024-05-22", desktop: 81, mobile: 120 },
{ date: "2024-05-23", desktop: 252, mobile: 290 },
{ date: "2024-05-24", desktop: 294, mobile: 220 },
{ date: "2024-05-25", desktop: 201, mobile: 250 },
{ date: "2024-05-26", desktop: 213, mobile: 170 },
{ date: "2024-05-27", desktop: 420, mobile: 460 },
{ date: "2024-05-28", desktop: 233, mobile: 190 },
{ date: "2024-05-29", desktop: 78, mobile: 130 },
{ date: "2024-05-30", desktop: 340, mobile: 280 },
{ date: "2024-05-31", desktop: 178, mobile: 230 },
{ date: "2024-06-01", desktop: 178, mobile: 200 },
{ date: "2024-06-02", desktop: 470, mobile: 410 },
{ date: "2024-06-03", desktop: 103, mobile: 160 },
{ date: "2024-06-04", desktop: 439, mobile: 380 },
{ date: "2024-06-05", desktop: 88, mobile: 140 },
{ date: "2024-06-06", desktop: 294, mobile: 250 },
{ date: "2024-06-07", desktop: 323, mobile: 370 },
{ date: "2024-06-08", desktop: 385, mobile: 320 },
{ date: "2024-06-09", desktop: 438, mobile: 480 },
{ date: "2024-06-10", desktop: 155, mobile: 200 },
{ date: "2024-06-11", desktop: 92, mobile: 150 },
{ date: "2024-06-12", desktop: 492, mobile: 420 },
{ date: "2024-06-13", desktop: 81, mobile: 130 },
{ date: "2024-06-14", desktop: 426, mobile: 380 },
{ date: "2024-06-15", desktop: 307, mobile: 350 },
{ date: "2024-06-16", desktop: 371, mobile: 310 },
{ date: "2024-06-17", desktop: 475, mobile: 520 },
{ date: "2024-06-18", desktop: 107, mobile: 170 },
{ date: "2024-06-19", desktop: 341, mobile: 290 },
{ date: "2024-06-20", desktop: 408, mobile: 450 },
{ date: "2024-06-21", desktop: 169, mobile: 210 },
{ date: "2024-06-22", desktop: 317, mobile: 270 },
{ date: "2024-06-23", desktop: 480, mobile: 530 },
{ date: "2024-06-24", desktop: 132, mobile: 180 },
{ date: "2024-06-25", desktop: 141, mobile: 190 },
{ date: "2024-06-26", desktop: 434, mobile: 380 },
{ date: "2024-06-27", desktop: 448, mobile: 490 },
{ date: "2024-06-28", desktop: 149, mobile: 200 },
{ date: "2024-06-29", desktop: 103, mobile: 160 },
{ date: "2024-06-30", desktop: 446, mobile: 400 },
]
const chartConfig = {
visitors: {
label: "Visitors",
},
desktop: {
label: "Desktop",
color: "var(--primary)",
},
mobile: {
label: "Mobile",
color: "var(--primary)",
},
} satisfies ChartConfig
export function ChartAreaInteractive() {
const isMobile = useIsMobile()
const [timeRange, setTimeRange] = React.useState("7d")
const filteredData = chartData.filter((item) => {
const date = new Date(item.date)
const referenceDate = new Date("2024-06-30")
let daysToSubtract = 90
if (timeRange === "30d") {
daysToSubtract = 30
} else if (timeRange === "7d") {
daysToSubtract = 7
}
const startDate = new Date(referenceDate)
startDate.setDate(startDate.getDate() - daysToSubtract)
return date >= startDate
})
return (
<Card className="@container/card">
<CardHeader>
<CardTitle>Total Visitors</CardTitle>
<CardDescription>
<span className="hidden @[540px]/card:block">
Total for the last 3 months
</span>
<span className="@[540px]/card:hidden">Last 3 months</span>
</CardDescription>
<CardAction>
<ToggleGroup
type="single"
value={timeRange}
onValueChange={setTimeRange}
variant="outline"
className="hidden *:data-[slot=toggle-group-item]:!px-4 @[767px]/card:flex"
>
<ToggleGroupItem value="90d">Last 3 months</ToggleGroupItem>
<ToggleGroupItem value="30d">Last 30 days</ToggleGroupItem>
<ToggleGroupItem value="7d">Last 7 days</ToggleGroupItem>
</ToggleGroup>
<Select value={timeRange} onValueChange={setTimeRange}>
<SelectTrigger
className="flex w-40 **:data-[slot=select-value]:block **:data-[slot=select-value]:truncate @[767px]/card:hidden"
size="sm"
aria-label="Select a value"
>
<SelectValue placeholder="Last 3 months" />
</SelectTrigger>
<SelectContent className="rounded-xl">
<SelectItem value="90d" className="rounded-lg">
Last 3 months
</SelectItem>
<SelectItem value="30d" className="rounded-lg">
Last 30 days
</SelectItem>
<SelectItem value="7d" className="rounded-lg">
Last 7 days
</SelectItem>
</SelectContent>
</Select>
</CardAction>
</CardHeader>
<CardContent className="px-2 pt-4 sm:px-6 sm:pt-6">
<ChartContainer
config={chartConfig}
className="aspect-auto h-[250px] w-full"
>
<AreaChart data={filteredData}>
<defs>
<linearGradient id="fillDesktop" x1="0" y1="0" x2="0" y2="1">
<stop
offset="5%"
stopColor="var(--color-desktop)"
stopOpacity={1.0}
/>
<stop
offset="95%"
stopColor="var(--color-desktop)"
stopOpacity={0.1}
/>
</linearGradient>
<linearGradient id="fillMobile" x1="0" y1="0" x2="0" y2="1">
<stop
offset="5%"
stopColor="var(--color-mobile)"
stopOpacity={0.8}
/>
<stop
offset="95%"
stopColor="var(--color-mobile)"
stopOpacity={0.1}
/>
</linearGradient>
</defs>
<CartesianGrid vertical={false} />
<XAxis
dataKey="date"
tickLine={false}
axisLine={false}
tickMargin={8}
minTickGap={32}
tickFormatter={(value) => {
const date = new Date(value)
return date.toLocaleDateString("en-US", {
month: "short",
day: "numeric",
})
}}
/>
<ChartTooltip
cursor={false}
defaultIndex={isMobile ? -1 : 10}
content={
<ChartTooltipContent
labelFormatter={(value) => {
return new Date(value).toLocaleDateString("en-US", {
month: "short",
day: "numeric",
})
}}
indicator="dot"
/>
}
/>
<Area
dataKey="mobile"
type="natural"
fill="url(#fillMobile)"
stroke="var(--color-mobile)"
stackId="a"
/>
<Area
dataKey="desktop"
type="natural"
fill="url(#fillDesktop)"
stroke="var(--color-desktop)"
stackId="a"
/>
</AreaChart>
</ChartContainer>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,807 @@
"use client"
import * as React from "react"
import {
closestCenter,
DndContext,
KeyboardSensor,
MouseSensor,
TouchSensor,
useSensor,
useSensors,
type DragEndEvent,
type UniqueIdentifier,
} from "@dnd-kit/core"
import { restrictToVerticalAxis } from "@dnd-kit/modifiers"
import {
arrayMove,
SortableContext,
useSortable,
verticalListSortingStrategy,
} from "@dnd-kit/sortable"
import { CSS } from "@dnd-kit/utilities"
import {
IconChevronDown,
IconChevronLeft,
IconChevronRight,
IconChevronsLeft,
IconChevronsRight,
IconCircleCheckFilled,
IconDotsVertical,
IconGripVertical,
IconLayoutColumns,
IconLoader,
IconPlus,
IconTrendingUp,
} from "@tabler/icons-react"
import {
flexRender,
getCoreRowModel,
getFacetedRowModel,
getFacetedUniqueValues,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
type ColumnDef,
type ColumnFiltersState,
type Row,
type SortingState,
type VisibilityState,
} from "@tanstack/react-table"
import { Area, AreaChart, CartesianGrid, XAxis } from "recharts"
import { toast } from "sonner"
import { z } from "zod"
import { useIsMobile } from "@/registry/new-york-v4/hooks/use-mobile"
import { Badge } from "@/registry/new-york-v4/ui/badge"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
ChartContainer,
ChartTooltip,
ChartTooltipContent,
type ChartConfig,
} from "@/registry/new-york-v4/ui/chart"
import { Checkbox } from "@/registry/new-york-v4/ui/checkbox"
import {
Drawer,
DrawerClose,
DrawerContent,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from "@/registry/new-york-v4/ui/drawer"
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/registry/new-york-v4/ui/dropdown-menu"
import { Input } from "@/registry/new-york-v4/ui/input"
import { Label } from "@/registry/new-york-v4/ui/label"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/registry/new-york-v4/ui/select"
import { Separator } from "@/registry/new-york-v4/ui/separator"
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/registry/new-york-v4/ui/table"
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from "@/registry/new-york-v4/ui/tabs"
export const schema = z.object({
id: z.number(),
header: z.string(),
type: z.string(),
status: z.string(),
target: z.string(),
limit: z.string(),
reviewer: z.string(),
})
// Create a separate component for the drag handle
function DragHandle({ id }: { id: number }) {
const { attributes, listeners } = useSortable({
id,
})
return (
<Button
{...attributes}
{...listeners}
variant="ghost"
size="icon"
className="text-muted-foreground size-7 hover:bg-transparent"
>
<IconGripVertical className="text-muted-foreground size-3" />
<span className="sr-only">Drag to reorder</span>
</Button>
)
}
const columns: ColumnDef<z.infer<typeof schema>>[] = [
{
id: "drag",
header: () => null,
cell: ({ row }) => <DragHandle id={row.original.id} />,
},
{
id: "select",
header: ({ table }) => (
<div className="flex items-center justify-center">
<Checkbox
checked={
table.getIsAllPageRowsSelected() ||
(table.getIsSomePageRowsSelected() && "indeterminate")
}
onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
aria-label="Select all"
/>
</div>
),
cell: ({ row }) => (
<div className="flex items-center justify-center">
<Checkbox
checked={row.getIsSelected()}
onCheckedChange={(value) => row.toggleSelected(!!value)}
aria-label="Select row"
/>
</div>
),
enableSorting: false,
enableHiding: false,
},
{
accessorKey: "header",
header: "Header",
cell: ({ row }) => {
return <TableCellViewer item={row.original} />
},
enableHiding: false,
},
{
accessorKey: "type",
header: "Section Type",
cell: ({ row }) => (
<div className="w-32">
<Badge variant="outline" className="text-muted-foreground px-1.5">
{row.original.type}
</Badge>
</div>
),
},
{
accessorKey: "status",
header: "Status",
cell: ({ row }) => (
<Badge variant="outline" className="text-muted-foreground px-1.5">
{row.original.status === "Done" ? (
<IconCircleCheckFilled className="fill-green-500 dark:fill-green-400" />
) : (
<IconLoader />
)}
{row.original.status}
</Badge>
),
},
{
accessorKey: "target",
header: () => <div className="w-full text-right">Target</div>,
cell: ({ row }) => (
<form
onSubmit={(e) => {
e.preventDefault()
toast.promise(new Promise((resolve) => setTimeout(resolve, 1000)), {
loading: `Saving ${row.original.header}`,
success: "Done",
error: "Error",
})
}}
>
<Label htmlFor={`${row.original.id}-target`} className="sr-only">
Target
</Label>
<Input
className="hover:bg-input/30 focus-visible:bg-background dark:hover:bg-input/30 dark:focus-visible:bg-input/30 h-8 w-16 border-transparent bg-transparent text-right shadow-none focus-visible:border dark:bg-transparent"
defaultValue={row.original.target}
id={`${row.original.id}-target`}
/>
</form>
),
},
{
accessorKey: "limit",
header: () => <div className="w-full text-right">Limit</div>,
cell: ({ row }) => (
<form
onSubmit={(e) => {
e.preventDefault()
toast.promise(new Promise((resolve) => setTimeout(resolve, 1000)), {
loading: `Saving ${row.original.header}`,
success: "Done",
error: "Error",
})
}}
>
<Label htmlFor={`${row.original.id}-limit`} className="sr-only">
Limit
</Label>
<Input
className="hover:bg-input/30 focus-visible:bg-background dark:hover:bg-input/30 dark:focus-visible:bg-input/30 h-8 w-16 border-transparent bg-transparent text-right shadow-none focus-visible:border dark:bg-transparent"
defaultValue={row.original.limit}
id={`${row.original.id}-limit`}
/>
</form>
),
},
{
accessorKey: "reviewer",
header: "Reviewer",
cell: ({ row }) => {
const isAssigned = row.original.reviewer !== "Assign reviewer"
if (isAssigned) {
return row.original.reviewer
}
return (
<>
<Label htmlFor={`${row.original.id}-reviewer`} className="sr-only">
Reviewer
</Label>
<Select>
<SelectTrigger
className="w-38 **:data-[slot=select-value]:block **:data-[slot=select-value]:truncate"
size="sm"
id={`${row.original.id}-reviewer`}
>
<SelectValue placeholder="Assign reviewer" />
</SelectTrigger>
<SelectContent align="end">
<SelectItem value="Eddie Lake">Eddie Lake</SelectItem>
<SelectItem value="Jamik Tashpulatov">
Jamik Tashpulatov
</SelectItem>
</SelectContent>
</Select>
</>
)
},
},
{
id: "actions",
cell: () => (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="ghost"
className="data-[state=open]:bg-muted text-muted-foreground flex size-8"
size="icon"
>
<IconDotsVertical />
<span className="sr-only">Open menu</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-32">
<DropdownMenuItem>Edit</DropdownMenuItem>
<DropdownMenuItem>Make a copy</DropdownMenuItem>
<DropdownMenuItem>Favorite</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive">Delete</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
),
},
]
function DraggableRow({ row }: { row: Row<z.infer<typeof schema>> }) {
const { transform, transition, setNodeRef, isDragging } = useSortable({
id: row.original.id,
})
return (
<TableRow
data-state={row.getIsSelected() && "selected"}
data-dragging={isDragging}
ref={setNodeRef}
className="relative z-0 data-[dragging=true]:z-10 data-[dragging=true]:opacity-80"
style={{
transform: CSS.Transform.toString(transform),
transition: transition,
}}
>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
)
}
export function DataTable({
data: initialData,
}: {
data: z.infer<typeof schema>[]
}) {
const [data, setData] = React.useState(() => initialData)
const [rowSelection, setRowSelection] = React.useState({})
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({})
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
)
const [sorting, setSorting] = React.useState<SortingState>([])
const [pagination, setPagination] = React.useState({
pageIndex: 0,
pageSize: 10,
})
const sortableId = React.useId()
const sensors = useSensors(
useSensor(MouseSensor, {}),
useSensor(TouchSensor, {}),
useSensor(KeyboardSensor, {})
)
const dataIds = React.useMemo<UniqueIdentifier[]>(
() => data?.map(({ id }) => id) || [],
[data]
)
const table = useReactTable({
data,
columns,
state: {
sorting,
columnVisibility,
rowSelection,
columnFilters,
pagination,
},
getRowId: (row) => row.id.toString(),
enableRowSelection: true,
onRowSelectionChange: setRowSelection,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
onColumnVisibilityChange: setColumnVisibility,
onPaginationChange: setPagination,
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFacetedRowModel: getFacetedRowModel(),
getFacetedUniqueValues: getFacetedUniqueValues(),
})
function handleDragEnd(event: DragEndEvent) {
const { active, over } = event
if (active && over && active.id !== over.id) {
setData((data) => {
const oldIndex = dataIds.indexOf(active.id)
const newIndex = dataIds.indexOf(over.id)
return arrayMove(data, oldIndex, newIndex)
})
}
}
return (
<Tabs
defaultValue="outline"
className="w-full flex-col justify-start gap-6"
>
<div className="flex items-center justify-between px-4 lg:px-6">
<Label htmlFor="view-selector" className="sr-only">
View
</Label>
<Select defaultValue="outline">
<SelectTrigger
className="flex w-fit @4xl/main:hidden"
size="sm"
id="view-selector"
>
<SelectValue placeholder="Select a view" />
</SelectTrigger>
<SelectContent>
<SelectItem value="outline">Outline</SelectItem>
<SelectItem value="past-performance">Past Performance</SelectItem>
<SelectItem value="key-personnel">Key Personnel</SelectItem>
<SelectItem value="focus-documents">Focus Documents</SelectItem>
</SelectContent>
</Select>
<TabsList className="**:data-[slot=badge]:bg-muted-foreground/30 hidden **:data-[slot=badge]:size-5 **:data-[slot=badge]:rounded-full **:data-[slot=badge]:px-1 @4xl/main:flex">
<TabsTrigger value="outline">Outline</TabsTrigger>
<TabsTrigger value="past-performance">
Past Performance <Badge variant="secondary">3</Badge>
</TabsTrigger>
<TabsTrigger value="key-personnel">
Key Personnel <Badge variant="secondary">2</Badge>
</TabsTrigger>
<TabsTrigger value="focus-documents">Focus Documents</TabsTrigger>
</TabsList>
<div className="flex items-center gap-2">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="sm">
<IconLayoutColumns />
<span className="hidden lg:inline">Customize Columns</span>
<span className="lg:hidden">Columns</span>
<IconChevronDown />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-56">
{table
.getAllColumns()
.filter(
(column) =>
typeof column.accessorFn !== "undefined" &&
column.getCanHide()
)
.map((column) => {
return (
<DropdownMenuCheckboxItem
key={column.id}
className="capitalize"
checked={column.getIsVisible()}
onCheckedChange={(value) =>
column.toggleVisibility(!!value)
}
>
{column.id}
</DropdownMenuCheckboxItem>
)
})}
</DropdownMenuContent>
</DropdownMenu>
<Button variant="outline" size="sm">
<IconPlus />
<span className="hidden lg:inline">Add Section</span>
</Button>
</div>
</div>
<TabsContent
value="outline"
className="relative flex flex-col gap-4 overflow-auto px-4 lg:px-6"
>
<div className="overflow-hidden rounded-lg border">
<DndContext
collisionDetection={closestCenter}
modifiers={[restrictToVerticalAxis]}
onDragEnd={handleDragEnd}
sensors={sensors}
id={sortableId}
>
<Table>
<TableHeader className="bg-muted sticky top-0 z-10">
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id} colSpan={header.colSpan}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</TableHead>
)
})}
</TableRow>
))}
</TableHeader>
<TableBody className="**:data-[slot=table-cell]:first:w-8">
{table.getRowModel().rows?.length ? (
<SortableContext
items={dataIds}
strategy={verticalListSortingStrategy}
>
{table.getRowModel().rows.map((row) => (
<DraggableRow key={row.id} row={row} />
))}
</SortableContext>
) : (
<TableRow>
<TableCell
colSpan={columns.length}
className="h-24 text-center"
>
No results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</DndContext>
</div>
<div className="flex items-center justify-between px-4">
<div className="text-muted-foreground hidden flex-1 text-sm lg:flex">
{table.getFilteredSelectedRowModel().rows.length} of{" "}
{table.getFilteredRowModel().rows.length} row(s) selected.
</div>
<div className="flex w-full items-center gap-8 lg:w-fit">
<div className="hidden items-center gap-2 lg:flex">
<Label htmlFor="rows-per-page" className="text-sm font-medium">
Rows per page
</Label>
<Select
value={`${table.getState().pagination.pageSize}`}
onValueChange={(value) => {
table.setPageSize(Number(value))
}}
>
<SelectTrigger size="sm" className="w-20" id="rows-per-page">
<SelectValue
placeholder={table.getState().pagination.pageSize}
/>
</SelectTrigger>
<SelectContent side="top">
{[10, 20, 30, 40, 50].map((pageSize) => (
<SelectItem key={pageSize} value={`${pageSize}`}>
{pageSize}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="flex w-fit items-center justify-center text-sm font-medium">
Page {table.getState().pagination.pageIndex + 1} of{" "}
{table.getPageCount()}
</div>
<div className="ml-auto flex items-center gap-2 lg:ml-0">
<Button
variant="outline"
className="hidden h-8 w-8 p-0 lg:flex"
onClick={() => table.setPageIndex(0)}
disabled={!table.getCanPreviousPage()}
>
<span className="sr-only">Go to first page</span>
<IconChevronsLeft />
</Button>
<Button
variant="outline"
className="size-8"
size="icon"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
>
<span className="sr-only">Go to previous page</span>
<IconChevronLeft />
</Button>
<Button
variant="outline"
className="size-8"
size="icon"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
>
<span className="sr-only">Go to next page</span>
<IconChevronRight />
</Button>
<Button
variant="outline"
className="hidden size-8 lg:flex"
size="icon"
onClick={() => table.setPageIndex(table.getPageCount() - 1)}
disabled={!table.getCanNextPage()}
>
<span className="sr-only">Go to last page</span>
<IconChevronsRight />
</Button>
</div>
</div>
</div>
</TabsContent>
<TabsContent
value="past-performance"
className="flex flex-col px-4 lg:px-6"
>
<div className="aspect-video w-full flex-1 rounded-lg border border-dashed"></div>
</TabsContent>
<TabsContent value="key-personnel" className="flex flex-col px-4 lg:px-6">
<div className="aspect-video w-full flex-1 rounded-lg border border-dashed"></div>
</TabsContent>
<TabsContent
value="focus-documents"
className="flex flex-col px-4 lg:px-6"
>
<div className="aspect-video w-full flex-1 rounded-lg border border-dashed"></div>
</TabsContent>
</Tabs>
)
}
const chartData = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
{ month: "April", desktop: 73, mobile: 190 },
{ month: "May", desktop: 209, mobile: 130 },
{ month: "June", desktop: 214, mobile: 140 },
]
const chartConfig = {
desktop: {
label: "Desktop",
color: "var(--primary)",
},
mobile: {
label: "Mobile",
color: "var(--primary)",
},
} satisfies ChartConfig
function TableCellViewer({ item }: { item: z.infer<typeof schema> }) {
const isMobile = useIsMobile()
return (
<Drawer direction={isMobile ? "bottom" : "right"}>
<DrawerTrigger asChild>
<Button variant="link" className="text-foreground w-fit px-0 text-left">
{item.header}
</Button>
</DrawerTrigger>
<DrawerContent>
<DrawerHeader className="gap-1">
<DrawerTitle>{item.header}</DrawerTitle>
<DrawerDescription>
Showing total visitors for the last 6 months
</DrawerDescription>
</DrawerHeader>
<div className="flex flex-col gap-4 overflow-y-auto px-4 text-sm">
{!isMobile && (
<>
<ChartContainer config={chartConfig}>
<AreaChart
accessibilityLayer
data={chartData}
margin={{
left: 0,
right: 10,
}}
>
<CartesianGrid vertical={false} />
<XAxis
dataKey="month"
tickLine={false}
axisLine={false}
tickMargin={8}
tickFormatter={(value) => value.slice(0, 3)}
hide
/>
<ChartTooltip
cursor={false}
content={<ChartTooltipContent indicator="dot" />}
/>
<Area
dataKey="mobile"
type="natural"
fill="var(--color-mobile)"
fillOpacity={0.6}
stroke="var(--color-mobile)"
stackId="a"
/>
<Area
dataKey="desktop"
type="natural"
fill="var(--color-desktop)"
fillOpacity={0.4}
stroke="var(--color-desktop)"
stackId="a"
/>
</AreaChart>
</ChartContainer>
<Separator />
<div className="grid gap-2">
<div className="flex gap-2 leading-none font-medium">
Trending up by 5.2% this month{" "}
<IconTrendingUp className="size-4" />
</div>
<div className="text-muted-foreground">
Showing total visitors for the last 6 months. This is just
some random text to test the layout. It spans multiple lines
and should wrap around.
</div>
</div>
<Separator />
</>
)}
<form className="flex flex-col gap-4">
<div className="flex flex-col gap-3">
<Label htmlFor="header">Header</Label>
<Input id="header" defaultValue={item.header} />
</div>
<div className="grid grid-cols-2 gap-4">
<div className="flex flex-col gap-3">
<Label htmlFor="type">Type</Label>
<Select defaultValue={item.type}>
<SelectTrigger id="type" className="w-full">
<SelectValue placeholder="Select a type" />
</SelectTrigger>
<SelectContent>
<SelectItem value="Table of Contents">
Table of Contents
</SelectItem>
<SelectItem value="Executive Summary">
Executive Summary
</SelectItem>
<SelectItem value="Technical Approach">
Technical Approach
</SelectItem>
<SelectItem value="Design">Design</SelectItem>
<SelectItem value="Capabilities">Capabilities</SelectItem>
<SelectItem value="Focus Documents">
Focus Documents
</SelectItem>
<SelectItem value="Narrative">Narrative</SelectItem>
<SelectItem value="Cover Page">Cover Page</SelectItem>
</SelectContent>
</Select>
</div>
<div className="flex flex-col gap-3">
<Label htmlFor="status">Status</Label>
<Select defaultValue={item.status}>
<SelectTrigger id="status" className="w-full">
<SelectValue placeholder="Select a status" />
</SelectTrigger>
<SelectContent>
<SelectItem value="Done">Done</SelectItem>
<SelectItem value="In Progress">In Progress</SelectItem>
<SelectItem value="Not Started">Not Started</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="flex flex-col gap-3">
<Label htmlFor="target">Target</Label>
<Input id="target" defaultValue={item.target} />
</div>
<div className="flex flex-col gap-3">
<Label htmlFor="limit">Limit</Label>
<Input id="limit" defaultValue={item.limit} />
</div>
</div>
<div className="flex flex-col gap-3">
<Label htmlFor="reviewer">Reviewer</Label>
<Select defaultValue={item.reviewer}>
<SelectTrigger id="reviewer" className="w-full">
<SelectValue placeholder="Select a reviewer" />
</SelectTrigger>
<SelectContent>
<SelectItem value="Eddie Lake">Eddie Lake</SelectItem>
<SelectItem value="Jamik Tashpulatov">
Jamik Tashpulatov
</SelectItem>
<SelectItem value="Emily Whalen">Emily Whalen</SelectItem>
</SelectContent>
</Select>
</div>
</form>
</div>
<DrawerFooter>
<Button>Submit</Button>
<DrawerClose asChild>
<Button variant="outline">Done</Button>
</DrawerClose>
</DrawerFooter>
</DrawerContent>
</Drawer>
)
}

View File

@@ -0,0 +1,92 @@
"use client"
import {
IconDots,
IconFolder,
IconShare3,
IconTrash,
type Icon,
} from "@tabler/icons-react"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/registry/new-york-v4/ui/dropdown-menu"
import {
SidebarGroup,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuAction,
SidebarMenuButton,
SidebarMenuItem,
useSidebar,
} from "@/registry/new-york-v4/ui/sidebar"
export function NavDocuments({
items,
}: {
items: {
name: string
url: string
icon: Icon
}[]
}) {
const { isMobile } = useSidebar()
return (
<SidebarGroup className="group-data-[collapsible=icon]:hidden">
<SidebarGroupLabel>Documents</SidebarGroupLabel>
<SidebarMenu>
{items.map((item) => (
<SidebarMenuItem key={item.name}>
<SidebarMenuButton asChild>
<a href={item.url}>
<item.icon />
<span>{item.name}</span>
</a>
</SidebarMenuButton>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<SidebarMenuAction
showOnHover
className="data-[state=open]:bg-accent rounded-sm"
>
<IconDots />
<span className="sr-only">More</span>
</SidebarMenuAction>
</DropdownMenuTrigger>
<DropdownMenuContent
className="w-24 rounded-lg"
side={isMobile ? "bottom" : "right"}
align={isMobile ? "end" : "start"}
>
<DropdownMenuItem>
<IconFolder />
<span>Open</span>
</DropdownMenuItem>
<DropdownMenuItem>
<IconShare3 />
<span>Share</span>
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive">
<IconTrash />
<span>Delete</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</SidebarMenuItem>
))}
<SidebarMenuItem>
<SidebarMenuButton className="text-sidebar-foreground/70">
<IconDots className="text-sidebar-foreground/70" />
<span>More</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
)
}

View File

@@ -0,0 +1,40 @@
"use client"
import { type Icon } from "@tabler/icons-react"
import {
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/registry/new-york-v4/ui/sidebar"
export function NavMain({
items,
}: {
items: {
title: string
url: string
icon?: Icon
}[]
}) {
return (
<SidebarGroup>
<SidebarGroupContent>
<SidebarGroupLabel>Home</SidebarGroupLabel>
<SidebarMenu>
{items.map((item) => (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton tooltip={item.title}>
{item.icon && <item.icon />}
<span>{item.title}</span>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
)
}

View File

@@ -0,0 +1,42 @@
"use client"
import * as React from "react"
import { type Icon } from "@tabler/icons-react"
import {
SidebarGroup,
SidebarGroupContent,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
} from "@/registry/new-york-v4/ui/sidebar"
export function NavSecondary({
items,
...props
}: {
items: {
title: string
url: string
icon: Icon
}[]
} & React.ComponentPropsWithoutRef<typeof SidebarGroup>) {
return (
<SidebarGroup {...props}>
<SidebarGroupContent>
<SidebarMenu>
{items.map((item) => (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton asChild>
<a href={item.url}>
<item.icon />
<span>{item.title}</span>
</a>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
)
}

View File

@@ -0,0 +1,110 @@
"use client"
import {
IconCreditCard,
IconDotsVertical,
IconLogout,
IconNotification,
IconUserCircle,
} from "@tabler/icons-react"
import {
Avatar,
AvatarFallback,
AvatarImage,
} from "@/registry/new-york-v4/ui/avatar"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/registry/new-york-v4/ui/dropdown-menu"
import {
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
useSidebar,
} from "@/registry/new-york-v4/ui/sidebar"
export function NavUser({
user,
}: {
user: {
name: string
email: string
avatar: string
}
}) {
const { isMobile } = useSidebar()
return (
<SidebarMenu>
<SidebarMenuItem>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<SidebarMenuButton
size="lg"
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
>
<Avatar className="h-8 w-8 rounded-lg grayscale">
<AvatarImage src={user.avatar} alt={user.name} />
<AvatarFallback className="rounded-lg">CN</AvatarFallback>
</Avatar>
<div className="grid flex-1 text-left text-sm leading-tight">
<span className="truncate font-medium">{user.name}</span>
<span className="text-muted-foreground truncate text-xs">
{user.email}
</span>
</div>
<IconDotsVertical className="ml-auto size-4" />
</SidebarMenuButton>
</DropdownMenuTrigger>
<DropdownMenuContent
className="w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg"
side={isMobile ? "bottom" : "right"}
align="end"
sideOffset={4}
>
<DropdownMenuLabel className="p-0 font-normal">
<div className="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
<Avatar className="h-8 w-8 rounded-lg">
<AvatarImage src={user.avatar} alt={user.name} />
<AvatarFallback className="rounded-lg">CN</AvatarFallback>
</Avatar>
<div className="grid flex-1 text-left text-sm leading-tight">
<span className="truncate font-medium">{user.name}</span>
<span className="text-muted-foreground truncate text-xs">
{user.email}
</span>
</div>
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<IconUserCircle />
Account
</DropdownMenuItem>
<DropdownMenuItem>
<IconCreditCard />
Billing
</DropdownMenuItem>
<DropdownMenuItem>
<IconNotification />
Notifications
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>
<IconLogout />
Log out
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</SidebarMenuItem>
</SidebarMenu>
)
}

View File

@@ -0,0 +1,102 @@
import { IconTrendingDown, IconTrendingUp } from "@tabler/icons-react"
import { Badge } from "@/registry/new-york-v4/ui/badge"
import {
Card,
CardAction,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/registry/new-york-v4/ui/card"
export function SectionCards() {
return (
<div className="grid grid-cols-1 gap-4 px-4 *:data-[slot=card]:bg-gradient-to-t *:data-[slot=card]:shadow-xs lg:px-6 @xl/main:grid-cols-2 @5xl/main:grid-cols-4">
<Card className="@container/card">
<CardHeader>
<CardDescription>Total Revenue</CardDescription>
<CardTitle className="text-2xl font-semibold tabular-nums @[250px]/card:text-3xl">
$1,250.00
</CardTitle>
<CardAction>
<Badge variant="outline">
<IconTrendingUp />
+12.5%
</Badge>
</CardAction>
</CardHeader>
<CardFooter className="flex-col items-start gap-1.5 text-sm">
<div className="line-clamp-1 flex gap-2 font-medium">
Trending up this month <IconTrendingUp className="size-4" />
</div>
<div className="text-muted-foreground">
Visitors for the last 6 months
</div>
</CardFooter>
</Card>
<Card className="@container/card">
<CardHeader>
<CardDescription>New Customers</CardDescription>
<CardTitle className="text-2xl font-semibold tabular-nums @[250px]/card:text-3xl">
1,234
</CardTitle>
<CardAction>
<Badge variant="outline">
<IconTrendingDown />
-20%
</Badge>
</CardAction>
</CardHeader>
<CardFooter className="flex-col items-start gap-1.5 text-sm">
<div className="line-clamp-1 flex gap-2 font-medium">
Down 20% this period <IconTrendingDown className="size-4" />
</div>
<div className="text-muted-foreground">
Acquisition needs attention
</div>
</CardFooter>
</Card>
<Card className="@container/card">
<CardHeader>
<CardDescription>Active Accounts</CardDescription>
<CardTitle className="text-2xl font-semibold tabular-nums @[250px]/card:text-3xl">
45,678
</CardTitle>
<CardAction>
<Badge variant="outline">
<IconTrendingUp />
+12.5%
</Badge>
</CardAction>
</CardHeader>
<CardFooter className="flex-col items-start gap-1.5 text-sm">
<div className="line-clamp-1 flex gap-2 font-medium">
Strong user retention <IconTrendingUp className="size-4" />
</div>
<div className="text-muted-foreground">Engagement exceed targets</div>
</CardFooter>
</Card>
<Card className="@container/card">
<CardHeader>
<CardDescription>Growth Rate</CardDescription>
<CardTitle className="text-2xl font-semibold tabular-nums @[250px]/card:text-3xl">
4.5%
</CardTitle>
<CardAction>
<Badge variant="outline">
<IconTrendingUp />
+4.5%
</Badge>
</CardAction>
</CardHeader>
<CardFooter className="flex-col items-start gap-1.5 text-sm">
<div className="line-clamp-1 flex gap-2 font-medium">
Steady performance increase <IconTrendingUp className="size-4" />
</div>
<div className="text-muted-foreground">Meets growth projections</div>
</CardFooter>
</Card>
</div>
)
}

View File

@@ -0,0 +1,19 @@
import { IconCirclePlusFilled } from "@tabler/icons-react"
import { Button } from "@/registry/new-york-v4/ui/button"
export function SiteHeader() {
return (
<header className="bg-background/90 sticky top-0 z-10 flex h-(--header-height) shrink-0 items-center gap-2 border-b transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-(--header-height)">
<div className="flex w-full items-center gap-1 px-4 lg:gap-2 lg:px-6">
<h1 className="text-base font-medium">Documents</h1>
<div className="ml-auto flex items-center gap-2">
<Button size="sm" className="hidden h-7 sm:flex">
<IconCirclePlusFilled />
<span>Quick Create</span>
</Button>
</div>
</div>
</header>
)
}

View File

@@ -0,0 +1,614 @@
[
{
"id": 1,
"header": "Cover page",
"type": "Cover page",
"status": "In Process",
"target": "18",
"limit": "5",
"reviewer": "Eddie Lake"
},
{
"id": 2,
"header": "Table of contents",
"type": "Table of contents",
"status": "Done",
"target": "29",
"limit": "24",
"reviewer": "Eddie Lake"
},
{
"id": 3,
"header": "Executive summary",
"type": "Narrative",
"status": "Done",
"target": "10",
"limit": "13",
"reviewer": "Eddie Lake"
},
{
"id": 4,
"header": "Technical approach",
"type": "Narrative",
"status": "Done",
"target": "27",
"limit": "23",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 5,
"header": "Design",
"type": "Narrative",
"status": "In Process",
"target": "2",
"limit": "16",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 6,
"header": "Capabilities",
"type": "Narrative",
"status": "In Process",
"target": "20",
"limit": "8",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 7,
"header": "Integration with existing systems",
"type": "Narrative",
"status": "In Process",
"target": "19",
"limit": "21",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 8,
"header": "Innovation and Advantages",
"type": "Narrative",
"status": "Done",
"target": "25",
"limit": "26",
"reviewer": "Assign reviewer"
},
{
"id": 9,
"header": "Overview of EMR's Innovative Solutions",
"type": "Technical content",
"status": "Done",
"target": "7",
"limit": "23",
"reviewer": "Assign reviewer"
},
{
"id": 10,
"header": "Advanced Algorithms and Machine Learning",
"type": "Narrative",
"status": "Done",
"target": "30",
"limit": "28",
"reviewer": "Assign reviewer"
},
{
"id": 11,
"header": "Adaptive Communication Protocols",
"type": "Narrative",
"status": "Done",
"target": "9",
"limit": "31",
"reviewer": "Assign reviewer"
},
{
"id": 12,
"header": "Advantages Over Current Technologies",
"type": "Narrative",
"status": "Done",
"target": "12",
"limit": "0",
"reviewer": "Assign reviewer"
},
{
"id": 13,
"header": "Past Performance",
"type": "Narrative",
"status": "Done",
"target": "22",
"limit": "33",
"reviewer": "Assign reviewer"
},
{
"id": 14,
"header": "Customer Feedback and Satisfaction Levels",
"type": "Narrative",
"status": "Done",
"target": "15",
"limit": "34",
"reviewer": "Assign reviewer"
},
{
"id": 15,
"header": "Implementation Challenges and Solutions",
"type": "Narrative",
"status": "Done",
"target": "3",
"limit": "35",
"reviewer": "Assign reviewer"
},
{
"id": 16,
"header": "Security Measures and Data Protection Policies",
"type": "Narrative",
"status": "In Process",
"target": "6",
"limit": "36",
"reviewer": "Assign reviewer"
},
{
"id": 17,
"header": "Scalability and Future Proofing",
"type": "Narrative",
"status": "Done",
"target": "4",
"limit": "37",
"reviewer": "Assign reviewer"
},
{
"id": 18,
"header": "Cost-Benefit Analysis",
"type": "Plain language",
"status": "Done",
"target": "14",
"limit": "38",
"reviewer": "Assign reviewer"
},
{
"id": 19,
"header": "User Training and Onboarding Experience",
"type": "Narrative",
"status": "Done",
"target": "17",
"limit": "39",
"reviewer": "Assign reviewer"
},
{
"id": 20,
"header": "Future Development Roadmap",
"type": "Narrative",
"status": "Done",
"target": "11",
"limit": "40",
"reviewer": "Assign reviewer"
},
{
"id": 21,
"header": "System Architecture Overview",
"type": "Technical content",
"status": "In Process",
"target": "24",
"limit": "18",
"reviewer": "Maya Johnson"
},
{
"id": 22,
"header": "Risk Management Plan",
"type": "Narrative",
"status": "Done",
"target": "15",
"limit": "22",
"reviewer": "Carlos Rodriguez"
},
{
"id": 23,
"header": "Compliance Documentation",
"type": "Legal",
"status": "In Process",
"target": "31",
"limit": "27",
"reviewer": "Sarah Chen"
},
{
"id": 24,
"header": "API Documentation",
"type": "Technical content",
"status": "Done",
"target": "8",
"limit": "12",
"reviewer": "Raj Patel"
},
{
"id": 25,
"header": "User Interface Mockups",
"type": "Visual",
"status": "In Process",
"target": "19",
"limit": "25",
"reviewer": "Leila Ahmadi"
},
{
"id": 26,
"header": "Database Schema",
"type": "Technical content",
"status": "Done",
"target": "22",
"limit": "20",
"reviewer": "Thomas Wilson"
},
{
"id": 27,
"header": "Testing Methodology",
"type": "Technical content",
"status": "In Process",
"target": "17",
"limit": "14",
"reviewer": "Assign reviewer"
},
{
"id": 28,
"header": "Deployment Strategy",
"type": "Narrative",
"status": "Done",
"target": "26",
"limit": "30",
"reviewer": "Eddie Lake"
},
{
"id": 29,
"header": "Budget Breakdown",
"type": "Financial",
"status": "In Process",
"target": "13",
"limit": "16",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 30,
"header": "Market Analysis",
"type": "Research",
"status": "Done",
"target": "29",
"limit": "32",
"reviewer": "Sophia Martinez"
},
{
"id": 31,
"header": "Competitor Comparison",
"type": "Research",
"status": "In Process",
"target": "21",
"limit": "19",
"reviewer": "Assign reviewer"
},
{
"id": 32,
"header": "Maintenance Plan",
"type": "Technical content",
"status": "Done",
"target": "16",
"limit": "23",
"reviewer": "Alex Thompson"
},
{
"id": 33,
"header": "User Personas",
"type": "Research",
"status": "In Process",
"target": "27",
"limit": "24",
"reviewer": "Nina Patel"
},
{
"id": 34,
"header": "Accessibility Compliance",
"type": "Legal",
"status": "Done",
"target": "18",
"limit": "21",
"reviewer": "Assign reviewer"
},
{
"id": 35,
"header": "Performance Metrics",
"type": "Technical content",
"status": "In Process",
"target": "23",
"limit": "26",
"reviewer": "David Kim"
},
{
"id": 36,
"header": "Disaster Recovery Plan",
"type": "Technical content",
"status": "Done",
"target": "14",
"limit": "17",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 37,
"header": "Third-party Integrations",
"type": "Technical content",
"status": "In Process",
"target": "25",
"limit": "28",
"reviewer": "Eddie Lake"
},
{
"id": 38,
"header": "User Feedback Summary",
"type": "Research",
"status": "Done",
"target": "20",
"limit": "15",
"reviewer": "Assign reviewer"
},
{
"id": 39,
"header": "Localization Strategy",
"type": "Narrative",
"status": "In Process",
"target": "12",
"limit": "19",
"reviewer": "Maria Garcia"
},
{
"id": 40,
"header": "Mobile Compatibility",
"type": "Technical content",
"status": "Done",
"target": "28",
"limit": "31",
"reviewer": "James Wilson"
},
{
"id": 41,
"header": "Data Migration Plan",
"type": "Technical content",
"status": "In Process",
"target": "19",
"limit": "22",
"reviewer": "Assign reviewer"
},
{
"id": 42,
"header": "Quality Assurance Protocols",
"type": "Technical content",
"status": "Done",
"target": "30",
"limit": "33",
"reviewer": "Priya Singh"
},
{
"id": 43,
"header": "Stakeholder Analysis",
"type": "Research",
"status": "In Process",
"target": "11",
"limit": "14",
"reviewer": "Eddie Lake"
},
{
"id": 44,
"header": "Environmental Impact Assessment",
"type": "Research",
"status": "Done",
"target": "24",
"limit": "27",
"reviewer": "Assign reviewer"
},
{
"id": 45,
"header": "Intellectual Property Rights",
"type": "Legal",
"status": "In Process",
"target": "17",
"limit": "20",
"reviewer": "Sarah Johnson"
},
{
"id": 46,
"header": "Customer Support Framework",
"type": "Narrative",
"status": "Done",
"target": "22",
"limit": "25",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 47,
"header": "Version Control Strategy",
"type": "Technical content",
"status": "In Process",
"target": "15",
"limit": "18",
"reviewer": "Assign reviewer"
},
{
"id": 48,
"header": "Continuous Integration Pipeline",
"type": "Technical content",
"status": "Done",
"target": "26",
"limit": "29",
"reviewer": "Michael Chen"
},
{
"id": 49,
"header": "Regulatory Compliance",
"type": "Legal",
"status": "In Process",
"target": "13",
"limit": "16",
"reviewer": "Assign reviewer"
},
{
"id": 50,
"header": "User Authentication System",
"type": "Technical content",
"status": "Done",
"target": "28",
"limit": "31",
"reviewer": "Eddie Lake"
},
{
"id": 51,
"header": "Data Analytics Framework",
"type": "Technical content",
"status": "In Process",
"target": "21",
"limit": "24",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 52,
"header": "Cloud Infrastructure",
"type": "Technical content",
"status": "Done",
"target": "16",
"limit": "19",
"reviewer": "Assign reviewer"
},
{
"id": 53,
"header": "Network Security Measures",
"type": "Technical content",
"status": "In Process",
"target": "29",
"limit": "32",
"reviewer": "Lisa Wong"
},
{
"id": 54,
"header": "Project Timeline",
"type": "Planning",
"status": "Done",
"target": "14",
"limit": "17",
"reviewer": "Eddie Lake"
},
{
"id": 55,
"header": "Resource Allocation",
"type": "Planning",
"status": "In Process",
"target": "27",
"limit": "30",
"reviewer": "Assign reviewer"
},
{
"id": 56,
"header": "Team Structure and Roles",
"type": "Planning",
"status": "Done",
"target": "20",
"limit": "23",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 57,
"header": "Communication Protocols",
"type": "Planning",
"status": "In Process",
"target": "15",
"limit": "18",
"reviewer": "Assign reviewer"
},
{
"id": 58,
"header": "Success Metrics",
"type": "Planning",
"status": "Done",
"target": "30",
"limit": "33",
"reviewer": "Eddie Lake"
},
{
"id": 59,
"header": "Internationalization Support",
"type": "Technical content",
"status": "In Process",
"target": "23",
"limit": "26",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 60,
"header": "Backup and Recovery Procedures",
"type": "Technical content",
"status": "Done",
"target": "18",
"limit": "21",
"reviewer": "Assign reviewer"
},
{
"id": 61,
"header": "Monitoring and Alerting System",
"type": "Technical content",
"status": "In Process",
"target": "25",
"limit": "28",
"reviewer": "Daniel Park"
},
{
"id": 62,
"header": "Code Review Guidelines",
"type": "Technical content",
"status": "Done",
"target": "12",
"limit": "15",
"reviewer": "Eddie Lake"
},
{
"id": 63,
"header": "Documentation Standards",
"type": "Technical content",
"status": "In Process",
"target": "27",
"limit": "30",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 64,
"header": "Release Management Process",
"type": "Planning",
"status": "Done",
"target": "22",
"limit": "25",
"reviewer": "Assign reviewer"
},
{
"id": 65,
"header": "Feature Prioritization Matrix",
"type": "Planning",
"status": "In Process",
"target": "19",
"limit": "22",
"reviewer": "Emma Davis"
},
{
"id": 66,
"header": "Technical Debt Assessment",
"type": "Technical content",
"status": "Done",
"target": "24",
"limit": "27",
"reviewer": "Eddie Lake"
},
{
"id": 67,
"header": "Capacity Planning",
"type": "Planning",
"status": "In Process",
"target": "21",
"limit": "24",
"reviewer": "Jamik Tashpulatov"
},
{
"id": 68,
"header": "Service Level Agreements",
"type": "Legal",
"status": "Done",
"target": "26",
"limit": "29",
"reviewer": "Assign reviewer"
}
]

View File

@@ -0,0 +1,63 @@
import Image from "next/image"
import {
SidebarInset,
SidebarProvider,
} from "@/registry/new-york-v4/ui/sidebar"
import { AppSidebar } from "@/app/(app)/examples/dashboard/components/app-sidebar"
import { ChartAreaInteractive } from "@/app/(app)/examples/dashboard/components/chart-area-interactive"
import { DataTable } from "@/app/(app)/examples/dashboard/components/data-table"
import { SectionCards } from "@/app/(app)/examples/dashboard/components/section-cards"
import { SiteHeader } from "@/app/(app)/examples/dashboard/components/site-header"
import data from "./data.json"
export default function Page() {
return (
<>
<div className="md:hidden">
<Image
src="/examples/dashboard-light.png"
width={1280}
height={843}
alt="Authentication"
className="block dark:hidden"
priority
/>
<Image
src="/examples/dashboard-dark.png"
width={1280}
height={843}
alt="Authentication"
className="hidden dark:block"
priority
/>
</div>
<SidebarProvider
className="hidden md:flex"
style={
{
"--sidebar-width": "calc(var(--spacing) * 64)",
"--header-height": "calc(var(--spacing) * 12 + 1px)",
} as React.CSSProperties
}
>
<AppSidebar variant="sidebar" />
<SidebarInset>
<SiteHeader />
<div className="flex flex-1 flex-col">
<div className="@container/main flex flex-1 flex-col gap-2">
<div className="flex flex-col gap-4 py-4 md:gap-6 md:py-6">
<SectionCards />
<div className="px-4 lg:px-6">
<ChartAreaInteractive />
</div>
<DataTable data={data} />
</div>
</div>
</div>
</SidebarInset>
</SidebarProvider>
</>
)
}

View File

@@ -0,0 +1,80 @@
import { type Metadata } from "next"
import Link from "next/link"
import { Announcement } from "@/components/announcement"
import { ExamplesNav } from "@/components/examples-nav"
import {
PageActions,
PageHeader,
PageHeaderDescription,
PageHeaderHeading,
} from "@/components/page-header"
import { PageNav } from "@/components/page-nav"
import { ThemeSelector } from "@/components/theme-selector"
import { Button } from "@/registry/new-york-v4/ui/button"
export const dynamic = "force-static"
export const revalidate = false
const title = "The Foundation for your Design System"
const description =
"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 metadata: Metadata = {
title,
description,
openGraph: {
images: [
{
url: `/og?title=${encodeURIComponent(
title
)}&description=${encodeURIComponent(description)}`,
},
],
},
twitter: {
card: "summary_large_image",
images: [
{
url: `/og?title=${encodeURIComponent(
title
)}&description=${encodeURIComponent(description)}`,
},
],
},
}
export default function ExamplesLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<>
<PageHeader>
<Announcement />
<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="/docs/components">View Components</Link>
</Button>
</PageActions>
</PageHeader>
<PageNav id="examples" className="hidden md:flex">
<ExamplesNav className="[&>a:first-child]:text-primary flex-1 overflow-hidden" />
<ThemeSelector className="mr-4 hidden md:flex" />
</PageNav>
<div className="container-wrapper section-soft flex flex-1 flex-col pb-6">
<div className="theme-container container flex flex-1 scroll-mt-20 flex-col">
<div className="bg-background flex flex-col overflow-hidden rounded-lg border bg-clip-padding md:flex-1 xl:rounded-xl">
{children}
</div>
</div>
</div>
</>
)
}

View File

@@ -0,0 +1,89 @@
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/registry/new-york-v4/ui/dialog"
export function CodeViewer() {
return (
<Dialog>
<DialogTrigger asChild>
<Button variant="secondary">View code</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>View code</DialogTitle>
<DialogDescription>
You can use the following code to start integrating your current
prompt and settings into your application.
</DialogDescription>
</DialogHeader>
<div className="grid gap-4">
<div className="rounded-md bg-black p-6">
<pre>
<code className="grid gap-1 text-sm text-white [&_span]:h-4">
<span>
<span className="text-sky-300">import</span> os
</span>
<span>
<span className="text-sky-300">import</span> openai
</span>
<span />
<span>
openai.api_key = os.getenv(
<span className="text-green-300">
&quot;OPENAI_API_KEY&quot;
</span>
)
</span>
<span />
<span>response = openai.Completion.create(</span>
<span>
{" "}
model=
<span className="text-green-300">&quot;davinci&quot;</span>,
</span>
<span>
{" "}
prompt=<span className="text-amber-300">&quot;&quot;</span>,
</span>
<span>
{" "}
temperature=<span className="text-amber-300">0.9</span>,
</span>
<span>
{" "}
max_tokens=<span className="text-amber-300">5</span>,
</span>
<span>
{" "}
top_p=<span className="text-amber-300">1</span>,
</span>
<span>
{" "}
frequency_penalty=<span className="text-amber-300">0</span>,
</span>
<span>
{" "}
presence_penalty=<span className="text-green-300">0</span>,
</span>
<span>)</span>
</code>
</pre>
</div>
<div>
<p className="text-muted-foreground text-sm">
Your API Key can be found here. You should use environment
variables or a secret management tool to expose your key to your
applications.
</p>
</div>
</div>
</DialogContent>
</Dialog>
)
}

View File

@@ -0,0 +1,54 @@
"use client"
import * as React from "react"
import { type SliderProps } from "@radix-ui/react-slider"
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/registry/new-york-v4/ui/hover-card"
import { Label } from "@/registry/new-york-v4/ui/label"
import { Slider } from "@/registry/new-york-v4/ui/slider"
interface MaxLengthSelectorProps {
defaultValue: SliderProps["defaultValue"]
}
export function MaxLengthSelector({ defaultValue }: MaxLengthSelectorProps) {
const [value, setValue] = React.useState(defaultValue)
return (
<div className="grid gap-2 pt-2">
<HoverCard openDelay={200}>
<HoverCardTrigger asChild>
<div className="grid gap-4">
<div className="flex items-center justify-between">
<Label htmlFor="maxlength">Maximum Length</Label>
<span className="text-muted-foreground hover:border-border w-12 rounded-md border border-transparent px-2 py-0.5 text-right text-sm">
{value}
</span>
</div>
<Slider
id="maxlength"
max={4000}
defaultValue={value}
step={10}
onValueChange={setValue}
aria-label="Maximum Length"
/>
</div>
</HoverCardTrigger>
<HoverCardContent
align="start"
className="w-[260px] text-sm"
side="left"
>
The maximum number of tokens to generate. Requests can use up to 2,048
or 4,000 tokens, shared between prompt and completion. The exact limit
varies by model.
</HoverCardContent>
</HoverCard>
</div>
)
}

View File

@@ -0,0 +1,162 @@
"use client"
import * as React from "react"
import { type PopoverProps } from "@radix-ui/react-popover"
import { Check, ChevronsUpDown } from "lucide-react"
import { cn } from "@/lib/utils"
import { useMutationObserver } from "@/hooks/use-mutation-observer"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/registry/new-york-v4/ui/command"
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/registry/new-york-v4/ui/hover-card"
import { Label } from "@/registry/new-york-v4/ui/label"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/registry/new-york-v4/ui/popover"
import { type Model, type ModelType } from "../data/models"
interface ModelSelectorProps extends PopoverProps {
types: readonly ModelType[]
models: Model[]
}
export function ModelSelector({ models, types, ...props }: ModelSelectorProps) {
const [open, setOpen] = React.useState(false)
const [selectedModel, setSelectedModel] = React.useState<Model>(models[0])
const [peekedModel, setPeekedModel] = React.useState<Model>(models[0])
return (
<div className="grid gap-3">
<HoverCard openDelay={200}>
<HoverCardTrigger asChild>
<Label htmlFor="model">Model</Label>
</HoverCardTrigger>
<HoverCardContent
align="start"
className="w-[260px] text-sm"
side="left"
>
The model which will generate the completion. Some models are suitable
for natural language tasks, others specialize in code. Learn more.
</HoverCardContent>
</HoverCard>
<Popover open={open} onOpenChange={setOpen} {...props}>
<PopoverTrigger asChild>
<Button
variant="outline"
role="combobox"
aria-expanded={open}
aria-label="Select a model"
className="w-full justify-between"
>
{selectedModel ? selectedModel.name : "Select a model..."}
<ChevronsUpDown className="text-muted-foreground" />
</Button>
</PopoverTrigger>
<PopoverContent align="end" className="w-[250px] p-0">
<HoverCard>
<HoverCardContent
side="left"
align="start"
forceMount
className="min-h-[280px]"
>
<div className="grid gap-2">
<h4 className="leading-none font-medium">{peekedModel.name}</h4>
<div className="text-muted-foreground text-sm">
{peekedModel.description}
</div>
{peekedModel.strengths ? (
<div className="mt-4 grid gap-2">
<h5 className="text-sm leading-none font-medium">
Strengths
</h5>
<ul className="text-muted-foreground text-sm">
{peekedModel.strengths}
</ul>
</div>
) : null}
</div>
</HoverCardContent>
<Command loop>
<CommandList className="h-(--cmdk-list-height) max-h-[400px]">
<CommandInput placeholder="Search Models..." />
<CommandEmpty>No Models found.</CommandEmpty>
<HoverCardTrigger />
{types.map((type) => (
<CommandGroup key={type} heading={type}>
{models
.filter((model) => model.type === type)
.map((model) => (
<ModelItem
key={model.id}
model={model}
isSelected={selectedModel?.id === model.id}
onPeek={(model) => setPeekedModel(model)}
onSelect={() => {
setSelectedModel(model)
setOpen(false)
}}
/>
))}
</CommandGroup>
))}
</CommandList>
</Command>
</HoverCard>
</PopoverContent>
</Popover>
</div>
)
}
interface ModelItemProps {
model: Model
isSelected: boolean
onSelect: () => void
onPeek: (model: Model) => void
}
function ModelItem({ model, isSelected, onSelect, onPeek }: ModelItemProps) {
const ref = React.useRef<HTMLDivElement>(null)
useMutationObserver(ref, (mutations) => {
mutations.forEach((mutation) => {
if (
mutation.type === "attributes" &&
mutation.attributeName === "aria-selected" &&
ref.current?.getAttribute("aria-selected") === "true"
) {
onPeek(model)
}
})
})
return (
<CommandItem
key={model.id}
onSelect={onSelect}
ref={ref}
className="data-[selected=true]:bg-primary data-[selected=true]:text-primary-foreground"
>
{model.name}
<Check
className={cn("ml-auto", isSelected ? "opacity-100" : "opacity-0")}
/>
</CommandItem>
)
}

View File

@@ -0,0 +1,121 @@
"use client"
import * as React from "react"
import { Dialog } from "@radix-ui/react-dialog"
import { MoreHorizontal } from "lucide-react"
import { toast } from "sonner"
import {
AlertDialog,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/registry/new-york-v4/ui/alert-dialog"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/registry/new-york-v4/ui/dialog"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/registry/new-york-v4/ui/dropdown-menu"
import { Label } from "@/registry/new-york-v4/ui/label"
import { Switch } from "@/registry/new-york-v4/ui/switch"
export function PresetActions() {
const [open, setIsOpen] = React.useState(false)
const [showDeleteDialog, setShowDeleteDialog] = React.useState(false)
return (
<>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="secondary" size="icon">
<span className="sr-only">Actions</span>
<MoreHorizontal />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onSelect={() => setIsOpen(true)}>
Content filter preferences
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
onSelect={() => setShowDeleteDialog(true)}
className="text-red-600"
>
Delete preset
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<Dialog open={open} onOpenChange={setIsOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle>Content filter preferences</DialogTitle>
<DialogDescription>
The content filter flags text that may violate our content policy.
It&apos;s powered by our moderation endpoint which is free to use
to moderate your OpenAI API traffic. Learn more.
</DialogDescription>
</DialogHeader>
<div className="py-6">
<h4 className="text-muted-foreground text-sm">
Playground Warnings
</h4>
<div className="flex items-start justify-between gap-4 pt-3">
<Switch name="show" id="show" defaultChecked={true} />
<Label className="grid gap-1 font-normal" htmlFor="show">
<span className="font-semibold">
Show a warning when content is flagged
</span>
<span className="text-muted-foreground text-sm">
A warning will be shown when sexual, hateful, violent or
self-harm content is detected.
</span>
</Label>
</div>
</div>
<DialogFooter>
<DialogClose asChild>
<Button variant="secondary">Close</Button>
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
<AlertDialog open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
<AlertDialogDescription>
This action cannot be undone. This preset will no longer be
accessible by you or others you&apos;ve shared it with.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<Button
variant="destructive"
onClick={() => {
setShowDeleteDialog(false)
toast.success("This preset has been deleted.")
}}
>
Delete
</Button>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</>
)
}

View File

@@ -0,0 +1,45 @@
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/registry/new-york-v4/ui/dialog"
import { Input } from "@/registry/new-york-v4/ui/input"
import { Label } from "@/registry/new-york-v4/ui/label"
import { Textarea } from "@/registry/new-york-v4/ui/textarea"
export function PresetSave() {
return (
<Dialog>
<DialogTrigger asChild>
<Button variant="secondary">Save</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Save preset</DialogTitle>
<DialogDescription>
This will save the current playground state as a preset which you
can access later or share with others.
</DialogDescription>
</DialogHeader>
<div className="grid gap-6 py-4">
<div className="grid gap-3">
<Label htmlFor="name">Name</Label>
<Input id="name" autoFocus />
</div>
<div className="grid gap-3">
<Label htmlFor="description">Description</Label>
<Textarea id="description" />
</div>
</div>
<DialogFooter>
<Button type="submit">Save</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}

View File

@@ -0,0 +1,83 @@
"use client"
import * as React from "react"
import { type PopoverProps } from "@radix-ui/react-popover"
import { Check, ChevronsUpDown } from "lucide-react"
import { cn } from "@/lib/utils"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
} from "@/registry/new-york-v4/ui/command"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/registry/new-york-v4/ui/popover"
import { type Preset } from "../data/presets"
interface PresetSelectorProps extends PopoverProps {
presets: Preset[]
}
export function PresetSelector({ presets, ...props }: PresetSelectorProps) {
const [open, setOpen] = React.useState(false)
const [selectedPreset, setSelectedPreset] = React.useState<Preset>()
return (
<Popover open={open} onOpenChange={setOpen} {...props}>
<PopoverTrigger asChild>
<Button
variant="outline"
role="combobox"
aria-label="Load a preset..."
aria-expanded={open}
className="flex-1 justify-between md:max-w-[200px] lg:max-w-[300px]"
>
{selectedPreset ? selectedPreset.name : "Load a preset..."}
<ChevronsUpDown className="opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-[300px] p-0">
<Command>
<CommandInput placeholder="Search presets..." />
<CommandList>
<CommandEmpty>No presets found.</CommandEmpty>
<CommandGroup heading="Examples">
{presets.map((preset) => (
<CommandItem
key={preset.id}
onSelect={() => {
setSelectedPreset(preset)
setOpen(false)
}}
>
{preset.name}
<Check
className={cn(
"ml-auto",
selectedPreset?.id === preset.id
? "opacity-100"
: "opacity-0"
)}
/>
</CommandItem>
))}
</CommandGroup>
<CommandSeparator />
<CommandGroup>
<CommandItem>More examples</CommandItem>
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
)
}

View File

@@ -0,0 +1,49 @@
import { Copy } from "lucide-react"
import { Button } from "@/registry/new-york-v4/ui/button"
import { Input } from "@/registry/new-york-v4/ui/input"
import { Label } from "@/registry/new-york-v4/ui/label"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/registry/new-york-v4/ui/popover"
export function PresetShare() {
return (
<Popover>
<PopoverTrigger asChild>
<Button variant="secondary">Share</Button>
</PopoverTrigger>
<PopoverContent align="end" className="flex w-[520px] flex-col gap-4">
<div className="flex flex-col gap-1 text-center sm:text-left">
<h3 className="text-lg font-semibold">Share preset</h3>
<p className="text-muted-foreground text-sm">
Anyone who has this link and an OpenAI account will be able to view
this.
</p>
</div>
<div className="relative flex-1">
<Label htmlFor="link" className="sr-only">
Link
</Label>
<Input
id="link"
defaultValue="https://platform.openai.com/playground/p/7bbKYQvsVkNmVb8NGcdUOLae?model=text-davinci-003"
readOnly
className="h-9 pr-10"
/>
<Button
type="submit"
size="icon"
variant="ghost"
className="absolute top-1 right-1 size-7"
>
<span className="sr-only">Copy</span>
<Copy className="size-3.5" />
</Button>
</div>
</PopoverContent>
</Popover>
)
}

View File

@@ -0,0 +1,56 @@
"use client"
import * as React from "react"
import { type SliderProps } from "@radix-ui/react-slider"
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/registry/new-york-v4/ui/hover-card"
import { Label } from "@/registry/new-york-v4/ui/label"
import { Slider } from "@/registry/new-york-v4/ui/slider"
interface TemperatureSelectorProps {
defaultValue: SliderProps["defaultValue"]
}
export function TemperatureSelector({
defaultValue,
}: TemperatureSelectorProps) {
const [value, setValue] = React.useState(defaultValue)
return (
<div className="grid gap-2 pt-2">
<HoverCard openDelay={200}>
<HoverCardTrigger asChild>
<div className="grid gap-4">
<div className="flex items-center justify-between">
<Label htmlFor="temperature">Temperature</Label>
<span className="text-muted-foreground hover:border-border w-12 rounded-md border border-transparent px-2 py-0.5 text-right text-sm">
{value}
</span>
</div>
<Slider
id="temperature"
max={1}
defaultValue={value}
step={0.1}
onValueChange={setValue}
aria-label="Temperature"
/>
</div>
</HoverCardTrigger>
<HoverCardContent
align="start"
className="w-[260px] text-sm"
side="left"
>
Controls randomness: lowering results in less random completions. As
the temperature approaches zero, the model will become deterministic
and repetitive.
</HoverCardContent>
</HoverCard>
</div>
)
}

View File

@@ -0,0 +1,53 @@
"use client"
import * as React from "react"
import { type SliderProps } from "@radix-ui/react-slider"
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/registry/new-york-v4/ui/hover-card"
import { Label } from "@/registry/new-york-v4/ui/label"
import { Slider } from "@/registry/new-york-v4/ui/slider"
interface TopPSelectorProps {
defaultValue: SliderProps["defaultValue"]
}
export function TopPSelector({ defaultValue }: TopPSelectorProps) {
const [value, setValue] = React.useState(defaultValue)
return (
<div className="grid gap-2 pt-2">
<HoverCard openDelay={200}>
<HoverCardTrigger asChild>
<div className="grid gap-4">
<div className="flex items-center justify-between">
<Label htmlFor="top-p">Top P</Label>
<span className="text-muted-foreground hover:border-border w-12 rounded-md border border-transparent px-2 py-0.5 text-right text-sm">
{value}
</span>
</div>
<Slider
id="top-p"
max={1}
defaultValue={value}
step={0.1}
onValueChange={setValue}
aria-label="Top P"
/>
</div>
</HoverCardTrigger>
<HoverCardContent
align="start"
className="w-[260px] text-sm"
side="left"
>
Control diversity via nucleus sampling: 0.5 means half of all
likelihood-weighted options are considered.
</HoverCardContent>
</HoverCard>
</div>
)
}

View File

@@ -0,0 +1,332 @@
import { type Metadata } from "next"
import Image from "next/image"
import { RotateCcw } from "lucide-react"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/registry/new-york-v4/ui/hover-card"
import { Label } from "@/registry/new-york-v4/ui/label"
import { Separator } from "@/registry/new-york-v4/ui/separator"
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from "@/registry/new-york-v4/ui/tabs"
import { Textarea } from "@/registry/new-york-v4/ui/textarea"
import { CodeViewer } from "./components/code-viewer"
import { MaxLengthSelector } from "./components/maxlength-selector"
import { ModelSelector } from "./components/model-selector"
import { PresetActions } from "./components/preset-actions"
import { PresetSave } from "./components/preset-save"
import { PresetSelector } from "./components/preset-selector"
import { PresetShare } from "./components/preset-share"
import { TemperatureSelector } from "./components/temperature-selector"
import { TopPSelector } from "./components/top-p-selector"
import { models, types } from "./data/models"
import { presets } from "./data/presets"
export const metadata: Metadata = {
title: "Playground",
description: "The OpenAI Playground built using the components.",
}
export default function PlaygroundPage() {
return (
<>
<div className="md:hidden">
<Image
src="/examples/playground-light.png"
width={1280}
height={916}
alt="Playground"
className="block dark:hidden"
/>
<Image
src="/examples/playground-dark.png"
width={1280}
height={916}
alt="Playground"
className="hidden dark:block"
/>
</div>
<div className="hidden flex-1 flex-col md:flex">
<div className="container flex flex-col items-start justify-between gap-2 py-4 sm:flex-row sm:items-center sm:gap-0 md:h-16">
<h2 className="pl-0.5 text-lg font-semibold">Playground</h2>
<div className="ml-auto flex w-full gap-2 sm:justify-end">
<PresetSelector presets={presets} />
<PresetSave />
<div className="hidden gap-2 md:flex">
<CodeViewer />
<PresetShare />
</div>
<PresetActions />
</div>
</div>
<Separator />
<Tabs defaultValue="complete" className="flex flex-1 flex-col">
<div className="container flex flex-1 flex-col py-6">
<div className="grid flex-1 items-stretch gap-6 md:grid-cols-[1fr_200px]">
<div className="hidden flex-col gap-6 sm:flex md:order-2">
<div className="grid gap-3">
<HoverCard openDelay={200}>
<HoverCardTrigger asChild>
<span className="text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
Mode
</span>
</HoverCardTrigger>
<HoverCardContent className="w-[320px] text-sm" side="left">
Choose the interface that best suits your task. You can
provide: a simple prompt to complete, starting and ending
text to insert a completion within, or some text with
instructions to edit it.
</HoverCardContent>
</HoverCard>
<TabsList className="grid w-full grid-cols-3">
<TabsTrigger value="complete">
<span className="sr-only">Complete</span>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="none"
>
<rect
x="4"
y="3"
width="12"
height="2"
rx="1"
fill="currentColor"
></rect>
<rect
x="4"
y="7"
width="12"
height="2"
rx="1"
fill="currentColor"
></rect>
<rect
x="4"
y="11"
width="3"
height="2"
rx="1"
fill="currentColor"
></rect>
<rect
x="4"
y="15"
width="3"
height="2"
rx="1"
fill="currentColor"
></rect>
<rect
x="8.5"
y="11"
width="3"
height="2"
rx="1"
fill="currentColor"
></rect>
<rect
x="8.5"
y="15"
width="3"
height="2"
rx="1"
fill="currentColor"
></rect>
<rect
x="13"
y="11"
width="3"
height="2"
rx="1"
fill="currentColor"
></rect>
</svg>
</TabsTrigger>
<TabsTrigger value="insert">
<span className="sr-only">Insert</span>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="none"
className="h-5 w-5"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M14.491 7.769a.888.888 0 0 1 .287.648.888.888 0 0 1-.287.648l-3.916 3.667a1.013 1.013 0 0 1-.692.268c-.26 0-.509-.097-.692-.268L5.275 9.065A.886.886 0 0 1 5 8.42a.889.889 0 0 1 .287-.64c.181-.17.427-.267.683-.269.257-.002.504.09.69.258L8.903 9.87V3.917c0-.243.103-.477.287-.649.183-.171.432-.268.692-.268.26 0 .509.097.692.268a.888.888 0 0 1 .287.649V9.87l2.245-2.102c.183-.172.432-.269.692-.269.26 0 .508.097.692.269Z"
fill="currentColor"
></path>
<rect
x="4"
y="15"
width="3"
height="2"
rx="1"
fill="currentColor"
></rect>
<rect
x="8.5"
y="15"
width="3"
height="2"
rx="1"
fill="currentColor"
></rect>
<rect
x="13"
y="15"
width="3"
height="2"
rx="1"
fill="currentColor"
></rect>
</svg>
</TabsTrigger>
<TabsTrigger value="edit">
<span className="sr-only">Edit</span>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="none"
className="h-5 w-5"
>
<rect
x="4"
y="3"
width="12"
height="2"
rx="1"
fill="currentColor"
></rect>
<rect
x="4"
y="7"
width="12"
height="2"
rx="1"
fill="currentColor"
></rect>
<rect
x="4"
y="11"
width="3"
height="2"
rx="1"
fill="currentColor"
></rect>
<rect
x="4"
y="15"
width="4"
height="2"
rx="1"
fill="currentColor"
></rect>
<rect
x="8.5"
y="11"
width="3"
height="2"
rx="1"
fill="currentColor"
></rect>
<path
d="M17.154 11.346a1.182 1.182 0 0 0-1.671 0L11 15.829V17.5h1.671l4.483-4.483a1.182 1.182 0 0 0 0-1.671Z"
fill="currentColor"
></path>
</svg>
</TabsTrigger>
</TabsList>
</div>
<ModelSelector types={types} models={models} />
<TemperatureSelector defaultValue={[0.56]} />
<MaxLengthSelector defaultValue={[256]} />
<TopPSelector defaultValue={[0.9]} />
</div>
<div className="flex flex-1 flex-col *:data-[slot=tab-content]:flex-1 md:order-1">
<TabsContent value="complete" className="mt-0 border-0 p-0">
<div className="flex h-full flex-col gap-4">
<Textarea
placeholder="Write a tagline for an ice cream shop"
className="min-h-[400px] flex-1 p-4 md:min-h-[700px] lg:min-h-[700px]"
/>
<div className="flex items-center gap-2">
<Button>Submit</Button>
<Button variant="secondary">
<span className="sr-only">Show history</span>
<RotateCcw />
</Button>
</div>
</div>
</TabsContent>
<TabsContent
value="insert"
className="mt-0 flex flex-col gap-4 border-0 p-0"
>
<div className="grid h-full grid-rows-2 gap-6 lg:grid-cols-2 lg:grid-rows-1">
<Textarea
placeholder="We're writing to [inset]. Congrats from OpenAI!"
className="h-full min-h-[300px] p-4 lg:min-h-[700px] xl:min-h-[700px]"
/>
<div className="bg-muted rounded-md border"></div>
</div>
<div className="flex items-center gap-2">
<Button>Submit</Button>
<Button variant="secondary">
<span className="sr-only">Show history</span>
<RotateCcw />
</Button>
</div>
</TabsContent>
<TabsContent
value="edit"
className="mt-0 flex flex-col gap-4 border-0 p-0"
>
<div className="grid h-full gap-6 lg:grid-cols-2">
<div className="flex flex-col gap-4">
<div className="flex flex-1 flex-col gap-2">
<Label htmlFor="input" className="sr-only">
Input
</Label>
<Textarea
id="input"
placeholder="We is going to the market."
className="flex-1 p-4 lg:min-h-[580px]"
/>
</div>
<div className="flex flex-col gap-2">
<Label htmlFor="instructions">Instructions</Label>
<Textarea
id="instructions"
placeholder="Fix the grammar."
/>
</div>
</div>
<div className="bg-muted min-h-[400px] rounded-md border lg:min-h-[700px]" />
</div>
<div className="flex items-center gap-2">
<Button>Submit</Button>
<Button variant="secondary">
<span className="sr-only">Show history</span>
<RotateCcw />
</Button>
</div>
</TabsContent>
</div>
</div>
</div>
</Tabs>
</div>
</>
)
}

View File

@@ -0,0 +1,123 @@
"use client"
import { type ColumnDef } from "@tanstack/react-table"
import { Badge } from "@/registry/new-york-v4/ui/badge"
import { Checkbox } from "@/registry/new-york-v4/ui/checkbox"
import { labels, priorities, statuses } from "../data/data"
import { type Task } from "../data/schema"
import { DataTableColumnHeader } from "./data-table-column-header"
import { DataTableRowActions } from "./data-table-row-actions"
export const columns: ColumnDef<Task>[] = [
{
id: "select",
header: ({ table }) => (
<Checkbox
checked={
table.getIsAllPageRowsSelected() ||
(table.getIsSomePageRowsSelected() && "indeterminate")
}
onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
aria-label="Select all"
className="translate-y-[2px]"
/>
),
cell: ({ row }) => (
<Checkbox
checked={row.getIsSelected()}
onCheckedChange={(value) => row.toggleSelected(!!value)}
aria-label="Select row"
className="translate-y-[2px]"
/>
),
enableSorting: false,
enableHiding: false,
},
{
accessorKey: "id",
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Task" />
),
cell: ({ row }) => <div className="w-[80px]">{row.getValue("id")}</div>,
enableSorting: false,
enableHiding: false,
},
{
accessorKey: "title",
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Title" />
),
cell: ({ row }) => {
const label = labels.find((label) => label.value === row.original.label)
return (
<div className="flex gap-2">
{label && <Badge variant="outline">{label.label}</Badge>}
<span className="max-w-[500px] truncate font-medium">
{row.getValue("title")}
</span>
</div>
)
},
},
{
accessorKey: "status",
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Status" />
),
cell: ({ row }) => {
const status = statuses.find(
(status) => status.value === row.getValue("status")
)
if (!status) {
return null
}
return (
<div className="flex w-[100px] items-center gap-2">
{status.icon && (
<status.icon className="text-muted-foreground size-4" />
)}
<span>{status.label}</span>
</div>
)
},
filterFn: (row, id, value) => {
return value.includes(row.getValue(id))
},
},
{
accessorKey: "priority",
header: ({ column }) => (
<DataTableColumnHeader column={column} title="Priority" />
),
cell: ({ row }) => {
const priority = priorities.find(
(priority) => priority.value === row.getValue("priority")
)
if (!priority) {
return null
}
return (
<div className="flex items-center gap-2">
{priority.icon && (
<priority.icon className="text-muted-foreground size-4" />
)}
<span>{priority.label}</span>
</div>
)
},
filterFn: (row, id, value) => {
return value.includes(row.getValue(id))
},
},
{
id: "actions",
cell: ({ row }) => <DataTableRowActions row={row} />,
},
]

View File

@@ -0,0 +1,66 @@
import { type Column } from "@tanstack/react-table"
import { ArrowDown, ArrowUp, ChevronsUpDown, EyeOff } from "lucide-react"
import { cn } from "@/lib/utils"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/registry/new-york-v4/ui/dropdown-menu"
interface DataTableColumnHeaderProps<TData, TValue>
extends React.HTMLAttributes<HTMLDivElement> {
column: Column<TData, TValue>
title: string
}
export function DataTableColumnHeader<TData, TValue>({
column,
title,
className,
}: DataTableColumnHeaderProps<TData, TValue>) {
if (!column.getCanSort()) {
return <div className={cn(className)}>{title}</div>
}
return (
<div className={cn("flex items-center gap-2", className)}>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="ghost"
size="sm"
className="data-[state=open]:bg-accent -ml-3 h-8"
>
<span>{title}</span>
{column.getIsSorted() === "desc" ? (
<ArrowDown />
) : column.getIsSorted() === "asc" ? (
<ArrowUp />
) : (
<ChevronsUpDown />
)}
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<DropdownMenuItem onClick={() => column.toggleSorting(false)}>
<ArrowUp />
Asc
</DropdownMenuItem>
<DropdownMenuItem onClick={() => column.toggleSorting(true)}>
<ArrowDown />
Desc
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => column.toggleVisibility(false)}>
<EyeOff />
Hide
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
)
}

View File

@@ -0,0 +1,147 @@
import * as React from "react"
import { type Column } from "@tanstack/react-table"
import { Check, PlusCircle } from "lucide-react"
import { cn } from "@/lib/utils"
import { Badge } from "@/registry/new-york-v4/ui/badge"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
} from "@/registry/new-york-v4/ui/command"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/registry/new-york-v4/ui/popover"
import { Separator } from "@/registry/new-york-v4/ui/separator"
interface DataTableFacetedFilterProps<TData, TValue> {
column?: Column<TData, TValue>
title?: string
options: {
label: string
value: string
icon?: React.ComponentType<{ className?: string }>
}[]
}
export function DataTableFacetedFilter<TData, TValue>({
column,
title,
options,
}: DataTableFacetedFilterProps<TData, TValue>) {
const facets = column?.getFacetedUniqueValues()
const selectedValues = new Set(column?.getFilterValue() as string[])
return (
<Popover>
<PopoverTrigger asChild>
<Button variant="outline" size="sm" className="h-8 border-dashed">
<PlusCircle />
{title}
{selectedValues?.size > 0 && (
<>
<Separator orientation="vertical" className="mx-2 h-4" />
<Badge
variant="secondary"
className="rounded-sm px-1 font-normal lg:hidden"
>
{selectedValues.size}
</Badge>
<div className="hidden gap-1 lg:flex">
{selectedValues.size > 2 ? (
<Badge
variant="secondary"
className="rounded-sm px-1 font-normal"
>
{selectedValues.size} selected
</Badge>
) : (
options
.filter((option) => selectedValues.has(option.value))
.map((option) => (
<Badge
variant="secondary"
key={option.value}
className="rounded-sm px-1 font-normal"
>
{option.label}
</Badge>
))
)}
</div>
</>
)}
</Button>
</PopoverTrigger>
<PopoverContent className="w-[200px] p-0" align="start">
<Command>
<CommandInput placeholder={title} />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup>
{options.map((option) => {
const isSelected = selectedValues.has(option.value)
return (
<CommandItem
key={option.value}
onSelect={() => {
if (isSelected) {
selectedValues.delete(option.value)
} else {
selectedValues.add(option.value)
}
const filterValues = Array.from(selectedValues)
column?.setFilterValue(
filterValues.length ? filterValues : undefined
)
}}
>
<div
className={cn(
"flex size-4 items-center justify-center rounded-[4px] border",
isSelected
? "bg-primary border-primary text-primary-foreground"
: "border-input [&_svg]:invisible"
)}
>
<Check className="text-primary-foreground size-3.5" />
</div>
{option.icon && (
<option.icon className="text-muted-foreground size-4" />
)}
<span>{option.label}</span>
{facets?.get(option.value) && (
<span className="text-muted-foreground ml-auto flex size-4 items-center justify-center font-mono text-xs">
{facets.get(option.value)}
</span>
)}
</CommandItem>
)
})}
</CommandGroup>
{selectedValues.size > 0 && (
<>
<CommandSeparator />
<CommandGroup>
<CommandItem
onSelect={() => column?.setFilterValue(undefined)}
className="justify-center text-center"
>
Clear filters
</CommandItem>
</CommandGroup>
</>
)}
</CommandList>
</Command>
</PopoverContent>
</Popover>
)
}

View File

@@ -0,0 +1,101 @@
import { type Table } from "@tanstack/react-table"
import {
ChevronLeft,
ChevronRight,
ChevronsLeft,
ChevronsRight,
} from "lucide-react"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/registry/new-york-v4/ui/select"
interface DataTablePaginationProps<TData> {
table: Table<TData>
}
export function DataTablePagination<TData>({
table,
}: DataTablePaginationProps<TData>) {
return (
<div className="flex items-center justify-between px-2">
<div className="text-muted-foreground flex-1 text-sm">
{table.getFilteredSelectedRowModel().rows.length} of{" "}
{table.getFilteredRowModel().rows.length} row(s) selected.
</div>
<div className="flex items-center space-x-6 lg:space-x-8">
<div className="flex items-center space-x-2">
<p className="text-sm font-medium">Rows per page</p>
<Select
value={`${table.getState().pagination.pageSize}`}
onValueChange={(value) => {
table.setPageSize(Number(value))
}}
>
<SelectTrigger className="h-8 w-[70px]">
<SelectValue placeholder={table.getState().pagination.pageSize} />
</SelectTrigger>
<SelectContent side="top">
{[10, 20, 25, 30, 40, 50].map((pageSize) => (
<SelectItem key={pageSize} value={`${pageSize}`}>
{pageSize}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="flex w-[100px] items-center justify-center text-sm font-medium">
Page {table.getState().pagination.pageIndex + 1} of{" "}
{table.getPageCount()}
</div>
<div className="flex items-center space-x-2">
<Button
variant="outline"
size="icon"
className="hidden size-8 lg:flex"
onClick={() => table.setPageIndex(0)}
disabled={!table.getCanPreviousPage()}
>
<span className="sr-only">Go to first page</span>
<ChevronsLeft />
</Button>
<Button
variant="outline"
size="icon"
className="size-8"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
>
<span className="sr-only">Go to previous page</span>
<ChevronLeft />
</Button>
<Button
variant="outline"
size="icon"
className="size-8"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
>
<span className="sr-only">Go to next page</span>
<ChevronRight />
</Button>
<Button
variant="outline"
size="icon"
className="hidden size-8 lg:flex"
onClick={() => table.setPageIndex(table.getPageCount() - 1)}
disabled={!table.getCanNextPage()}
>
<span className="sr-only">Go to last page</span>
<ChevronsRight />
</Button>
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,70 @@
"use client"
import { type Row } from "@tanstack/react-table"
import { MoreHorizontal } from "lucide-react"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger,
} from "@/registry/new-york-v4/ui/dropdown-menu"
import { labels } from "../data/data"
import { taskSchema } from "../data/schema"
interface DataTableRowActionsProps<TData> {
row: Row<TData>
}
export function DataTableRowActions<TData>({
row,
}: DataTableRowActionsProps<TData>) {
const task = taskSchema.parse(row.original)
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="ghost"
size="icon"
className="data-[state=open]:bg-muted size-8"
>
<MoreHorizontal />
<span className="sr-only">Open menu</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-[160px]">
<DropdownMenuItem>Edit</DropdownMenuItem>
<DropdownMenuItem>Make a copy</DropdownMenuItem>
<DropdownMenuItem>Favorite</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuSub>
<DropdownMenuSubTrigger>Labels</DropdownMenuSubTrigger>
<DropdownMenuSubContent>
<DropdownMenuRadioGroup value={task.label}>
{labels.map((label) => (
<DropdownMenuRadioItem key={label.value} value={label.value}>
{label.label}
</DropdownMenuRadioItem>
))}
</DropdownMenuRadioGroup>
</DropdownMenuSubContent>
</DropdownMenuSub>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive">
Delete
<DropdownMenuShortcut></DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)
}

View File

@@ -0,0 +1,64 @@
"use client"
import { type Table } from "@tanstack/react-table"
import { X } from "lucide-react"
import { Button } from "@/registry/new-york-v4/ui/button"
import { Input } from "@/registry/new-york-v4/ui/input"
import { DataTableViewOptions } from "@/app/(app)/examples/tasks/components/data-table-view-options"
import { priorities, statuses } from "../data/data"
import { DataTableFacetedFilter } from "./data-table-faceted-filter"
interface DataTableToolbarProps<TData> {
table: Table<TData>
}
export function DataTableToolbar<TData>({
table,
}: DataTableToolbarProps<TData>) {
const isFiltered = table.getState().columnFilters.length > 0
return (
<div className="flex items-center justify-between">
<div className="flex flex-1 items-center gap-2">
<Input
placeholder="Filter tasks..."
value={(table.getColumn("title")?.getFilterValue() as string) ?? ""}
onChange={(event) =>
table.getColumn("title")?.setFilterValue(event.target.value)
}
className="h-8 w-[150px] lg:w-[250px]"
/>
{table.getColumn("status") && (
<DataTableFacetedFilter
column={table.getColumn("status")}
title="Status"
options={statuses}
/>
)}
{table.getColumn("priority") && (
<DataTableFacetedFilter
column={table.getColumn("priority")}
title="Priority"
options={priorities}
/>
)}
{isFiltered && (
<Button
variant="ghost"
size="sm"
onClick={() => table.resetColumnFilters()}
>
Reset
<X />
</Button>
)}
</div>
<div className="flex items-center gap-2">
<DataTableViewOptions table={table} />
<Button size="sm">Add Task</Button>
</div>
</div>
)
}

View File

@@ -0,0 +1,57 @@
"use client"
import { DropdownMenuTrigger } from "@radix-ui/react-dropdown-menu"
import { type Table } from "@tanstack/react-table"
import { Settings2 } from "lucide-react"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuLabel,
DropdownMenuSeparator,
} from "@/registry/new-york-v4/ui/dropdown-menu"
export function DataTableViewOptions<TData>({
table,
}: {
table: Table<TData>
}) {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="outline"
size="sm"
className="ml-auto hidden h-8 lg:flex"
>
<Settings2 />
View
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-[150px]">
<DropdownMenuLabel>Toggle columns</DropdownMenuLabel>
<DropdownMenuSeparator />
{table
.getAllColumns()
.filter(
(column) =>
typeof column.accessorFn !== "undefined" && column.getCanHide()
)
.map((column) => {
return (
<DropdownMenuCheckboxItem
key={column.id}
className="capitalize"
checked={column.getIsVisible()}
onCheckedChange={(value) => column.toggleVisibility(!!value)}
>
{column.id}
</DropdownMenuCheckboxItem>
)
})}
</DropdownMenuContent>
</DropdownMenu>
)
}

View File

@@ -0,0 +1,131 @@
"use client"
import * as React from "react"
import {
flexRender,
getCoreRowModel,
getFacetedRowModel,
getFacetedUniqueValues,
getFilteredRowModel,
getPaginationRowModel,
getSortedRowModel,
useReactTable,
type ColumnDef,
type ColumnFiltersState,
type SortingState,
type VisibilityState,
} from "@tanstack/react-table"
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/registry/new-york-v4/ui/table"
import { DataTablePagination } from "./data-table-pagination"
import { DataTableToolbar } from "./data-table-toolbar"
interface DataTableProps<TData, TValue> {
columns: ColumnDef<TData, TValue>[]
data: TData[]
}
export function DataTable<TData, TValue>({
columns,
data,
}: DataTableProps<TData, TValue>) {
const [rowSelection, setRowSelection] = React.useState({})
const [columnVisibility, setColumnVisibility] =
React.useState<VisibilityState>({})
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(
[]
)
const [sorting, setSorting] = React.useState<SortingState>([])
const table = useReactTable({
data,
columns,
state: {
sorting,
columnVisibility,
rowSelection,
columnFilters,
},
initialState: {
pagination: {
pageSize: 25,
},
},
enableRowSelection: true,
onRowSelectionChange: setRowSelection,
onSortingChange: setSorting,
onColumnFiltersChange: setColumnFilters,
onColumnVisibilityChange: setColumnVisibility,
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSortedRowModel: getSortedRowModel(),
getFacetedRowModel: getFacetedRowModel(),
getFacetedUniqueValues: getFacetedUniqueValues(),
})
return (
<div className="flex flex-col gap-4">
<DataTableToolbar table={table} />
<div className="overflow-hidden rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id} colSpan={header.colSpan}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext()
)}
</TableHead>
)
})}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && "selected"}
>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
</TableCell>
))}
</TableRow>
))
) : (
<TableRow>
<TableCell
colSpan={columns.length}
className="h-24 text-center"
>
No results.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
<DataTablePagination table={table} />
</div>
)
}

View File

@@ -0,0 +1,62 @@
import {
Avatar,
AvatarFallback,
AvatarImage,
} from "@/registry/new-york-v4/ui/avatar"
import { Button } from "@/registry/new-york-v4/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuTrigger,
} from "@/registry/new-york-v4/ui/dropdown-menu"
export function UserNav() {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="relative h-8 w-8 rounded-full">
<Avatar className="h-9 w-9">
<AvatarImage src="/avatars/03.png" alt="@shadcn" />
<AvatarFallback>SC</AvatarFallback>
</Avatar>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56" align="end" forceMount>
<DropdownMenuLabel className="font-normal">
<div className="flex flex-col space-y-1">
<p className="text-sm leading-none font-medium">shadcn</p>
<p className="text-muted-foreground text-xs leading-none">
m@example.com
</p>
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
Profile
<DropdownMenuShortcut>P</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
Billing
<DropdownMenuShortcut>B</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
Settings
<DropdownMenuShortcut>S</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>New Team</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>
Log out
<DropdownMenuShortcut>Q</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)
}

View File

@@ -0,0 +1,71 @@
import {
ArrowDown,
ArrowRight,
ArrowUp,
CheckCircle,
Circle,
CircleOff,
HelpCircle,
Timer,
} from "lucide-react"
export const labels = [
{
value: "bug",
label: "Bug",
},
{
value: "feature",
label: "Feature",
},
{
value: "documentation",
label: "Documentation",
},
]
export const statuses = [
{
value: "backlog",
label: "Backlog",
icon: HelpCircle,
},
{
value: "todo",
label: "Todo",
icon: Circle,
},
{
value: "in progress",
label: "In Progress",
icon: Timer,
},
{
value: "done",
label: "Done",
icon: CheckCircle,
},
{
value: "canceled",
label: "Canceled",
icon: CircleOff,
},
]
export const priorities = [
{
label: "Low",
value: "low",
icon: ArrowDown,
},
{
label: "Medium",
value: "medium",
icon: ArrowRight,
},
{
label: "High",
value: "high",
icon: ArrowUp,
},
]

View File

@@ -0,0 +1,67 @@
import { promises as fs } from "fs"
import path from "path"
import { type Metadata } from "next"
import Image from "next/image"
import { z } from "zod"
import { columns } from "./components/columns"
import { DataTable } from "./components/data-table"
import { UserNav } from "./components/user-nav"
import { taskSchema } from "./data/schema"
export const metadata: Metadata = {
title: "Tasks",
description: "A task and issue tracker build using Tanstack Table.",
}
// Simulate a database read for tasks.
async function getTasks() {
const data = await fs.readFile(
path.join(process.cwd(), "app/(app)/examples/tasks/data/tasks.json")
)
const tasks = JSON.parse(data.toString())
return z.array(taskSchema).parse(tasks)
}
export default async function TaskPage() {
const tasks = await getTasks()
return (
<>
<div className="md:hidden">
<Image
src="/examples/tasks-light.png"
width={1280}
height={998}
alt="Playground"
className="block dark:hidden"
/>
<Image
src="/examples/tasks-dark.png"
width={1280}
height={998}
alt="Playground"
className="hidden dark:block"
/>
</div>
<div className="hidden h-full flex-1 flex-col gap-8 p-8 md:flex">
<div className="flex items-center justify-between gap-2">
<div className="flex flex-col gap-1">
<h2 className="text-2xl font-semibold tracking-tight">
Welcome back!
</h2>
<p className="text-muted-foreground">
Here&apos;s a list of your tasks for this month.
</p>
</div>
<div className="flex items-center gap-2">
<UserNav />
</div>
</div>
<DataTable data={tasks} columns={columns} />
</div>
</>
)
}

View File

@@ -0,0 +1,15 @@
import { SiteFooter } from "@/components/site-footer"
import { SiteHeader } from "@/components/site-header"
export default function AppLayout({ children }: { children: React.ReactNode }) {
return (
<div
data-slot="layout"
className="bg-background relative z-10 flex min-h-svh flex-col"
>
<SiteHeader />
<main className="flex flex-1 flex-col">{children}</main>
<SiteFooter />
</div>
)
}

View File

@@ -0,0 +1,36 @@
import { notFound } from "next/navigation"
import { NextResponse, type NextRequest } from "next/server"
import { processMdxForLLMs } from "@/lib/llm"
import { source } from "@/lib/source"
import { getActiveStyle } from "@/registry/_legacy-styles"
export const revalidate = false
export async function GET(
_req: NextRequest,
{ params }: { params: Promise<{ slug?: string[] }> }
) {
const [{ slug }, activeStyle] = await Promise.all([params, getActiveStyle()])
const page = source.getPage(slug)
if (!page) {
notFound()
}
const processedContent = processMdxForLLMs(
await page.data.getText("raw"),
activeStyle.name
)
return new NextResponse(processedContent, {
headers: {
"Content-Type": "text/markdown; charset=utf-8",
},
})
}
export function generateStaticParams() {
return source.generateParams()
}

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