Compare commits

..

1298 Commits

Author SHA1 Message Date
rajtripathi99
ea9d371a2d Add @untld registry to the directory (#10903)
Registry URL: https://ui.untldlabs.com/r/{name}.json
Homepage: https://ui.untldlabs.com
2026-06-11 20:46:21 +04:00
JOE MON
d15f17d717 feat(registry): add braaile loader registry (#10923) 2026-06-11 20:44:29 +04:00
Saurabh
46ca8c5d4b feat(registry): add beui (#10887) 2026-06-11 20:41:01 +04:00
q32757468
a5eb279650 feat(registry): add gpt-vis registry (#10794) 2026-06-11 19:03:21 +04:00
shadcn
1994caba0b perf: dev server (#10904)
* perf: dev server

* fix
2026-06-10 11:10:01 +04:00
Koishore Roy
1450bea8d6 Add @delego to the registry directory (#10901) 2026-06-10 10:12:19 +04:00
Aniket Pawar
ced2a5beb5 Add new entry for @ogimagecn in directory.json (#10896) 2026-06-09 17:03:32 +04:00
Terra
10f1717a3e Add Saaskit component to directory.json (#10494)
* Add Saaskit component to directory.json

Added Saaskit component with description, URL, author, and logo.

* Update Saaskit entry in directory.json

* Add new registry entry for @saaskit

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 10:00:24 +04:00
Benedict Umeozor
deba036d50 fix(docs): disable ligatures in code blocks (#10809) 2026-06-08 23:51:25 +04:00
shadcn
5bd81beebf docs: add API reference for shadcn 2026-06-08 20:17:12 +04:00
github-actions[bot]
3f2ff18157 chore(release): version packages (#10873)
Co-authored-by: shadcn <m@shadcn.com>
2026-06-08 17:48:39 +04:00
shadcn
05eb2b968b feat(cli): improve search command (#10886)
- Search across multiple registries and make the registry argument
  optional: omit it to search every registry configured in components.json
  (builtins like @shadcn excluded). Without a components.json or configured
  registries, a clear usage error is printed.
- Add a --type filter (accepts "ui" or "registry:ui", comma-separated)
  with validation against the known item types.
- Fetch registries concurrently with a capped worker pool, preserving
  result order.
- Tolerate per-registry failures when searching all configured registries
  (reported in a structured `errors` field); exit non-zero when every
  registry fails. Usage errors print directly instead of routing through
  handleError.
- MCP parity: optional registries (search-all), a `types` filter, and type
  validation across the search/list/examples tools.
- Keep the public registry surface to `searchRegistries` and make it
  self-contained (clears its own context, useCache defaults to false).
- Consolidate search formatting into registry/search, add the `errors`
  field to searchResultsSchema, and update the skill docs.
2026-06-08 17:46:00 +04:00
Truong Giang
a721cc08e5 feat: add @soralabs registry (#10884)
* feat(registry): add @sora-ui to community registry directory

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(registry): rename @sora-ui to @soralabs in community registry directory

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-08 12:08:49 +04:00
shadcn
8da4592308 feat: update registry build commands (#10880)
* feat: update registry build commands

* fix
2026-06-06 23:19:46 +04:00
Sadman Sakib
f47d48f316 feat(registry): update diceui registry url to support style (#10881) 2026-06-06 23:19:34 +04:00
Franco Zeta
e6d9d6023b feat(registry): update @stepper logo (#10875) 2026-06-06 22:52:49 +04:00
Harshitha Sompura
7dfd933102 fix(cli): move msw to devDependencies (#10851)
* fix: move msw to devDependencies

* chore: update lockfile after moving msw to devDependencies

* chore: add changeset for msw devDependency fix

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-06-05 21:01:37 +04:00
Andrew Luo
9c6a5ee1b1 add extend to registry directory (#10850) 2026-06-05 19:49:46 +04:00
Anish K Srinivasan
c87897b2a5 feat(registry): add @gamekitui to community registry directory (#10864)
Drop-in, themeable browser games for shadcn (Snake, 2048, Minesweeper, and
more) — each a single self-contained file with zero dependencies.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 19:46:49 +04:00
joncoronel
c61197f627 Add new UI component libraries to directory.json (#10858) 2026-06-05 19:45:13 +04:00
shadcn
a1fb619cef feat(card): add spacing and edge-to-edge variants (#10872) 2026-06-05 19:32:28 +04:00
Subhadip Jana
d84c4a8ca5 feat(registry): add @grootstudio to community registry directory (#10698) 2026-06-04 10:24:24 +04:00
Ajay Patel
cd54e0927f registry: updated shadcnstudio registry url with style support (#10847) 2026-06-01 20:22:30 +04:00
github-actions[bot]
adac7cae1f chore(release): version packages (#10845)
Co-authored-by: shadcn <m@shadcn.com>
2026-06-01 14:58:03 +04:00
shadcn
7c63c46736 feat(registry): add GitHub registry support (#10842)
* feat: add github scheme

* fix

* fix: validate and search

* docs: update docs for GitHub registries

* docs: add changelog

* fix

* chore: update announcement

* docs(skills): update GitHub registry guidance

* fix(registry): reject option-like GitHub refs

* fix(registry): limit search registry discovery

* fix(registry): bound GitHub validation concurrency

* fix(registry): reject whitespace in GitHub refs

* fix(registry): track URL dependency sources

* test(registry): cover local dependency sources
2026-06-01 14:53:34 +04:00
shadcn
916c012132 Sort registry directory entries alphabetically by name. (#10836) 2026-06-01 11:44:56 +04:00
github-actions[bot]
460ad60d84 chore(release): version packages (#10835)
Co-authored-by: shadcn <m@shadcn.com>
2026-05-31 16:18:29 +04:00
shadcn
8e2d2d1439 feat: add shadcn eject (#10834) 2026-05-31 16:11:01 +04:00
shadcn
67cef8fcb9 fix(v4): update homepage mobile demo fallback images (#10810)
* fix(v4): update homepage mobile demo fallback images

Replace registry dashboard screenshots with compressed CardsDemo captures and narrow the mobile bleed width to 140vw.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(v4): remove container-wrapper padding on homepage

Use p-0 on the demo section wrapper so the mobile preview image aligns flush without extra horizontal inset.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(v4): drop redundant md:p-0 on homepage wrapper

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 20:21:35 +04:00
shadcn
4ff43ba694 fix(styles): use color-mix for secondary button hover (#10808)
Align secondary button hover with Rhea: mix 5% foreground into
secondary in OKLCH instead of opacity. Updates registry CSS,
shipped button sources, and public registry JSON. Badges unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 16:37:28 +04:00
shadcn
efdec3ca45 fix(styles): restore primary button hover for Nova and Lyra (#10807)
The default button variant used [a]:hover, which only applies to anchor
elements. Buttons render as <button>, so hover had no effect on create
and in installed projects. Use hover:bg-primary/80 to match other styles.

Fixes #10798

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 16:13:58 +04:00
shadcn
5c849297d0 feat(release): add beta and rc prerelease labels (#10806) 2026-05-29 15:13:21 +04:00
github-actions[bot]
2baa86081d chore(release): version packages (#10791)
Co-authored-by: shadcn <m@shadcn.com>
2026-05-29 12:10:45 +04:00
shadcn
980f288149 ci(templates): test pnpm 11 (#10790) 2026-05-29 11:15:40 +04:00
Raashish Aggarwal
07900769d9 fix(cli): update template handling for pnpm 11 (#10659)
* fix(cli): allow esbuild builds in Vite templates

* fix(cli): extend pnpm 11 build-script allowlists across app templates

- Add packages: [] to single-app pnpm-workspace.yaml so pnpm 9 does
  not reject the file with "packages field missing or empty".
- Add astro-app, react-router-app, start-app, next-app workspace
  yamls with the build-script allowlist each template needs
  (esbuild, sharp, unrs-resolver as applicable).
- Set msw: false across all app allowlists so the registry component
  install runs cleanly under pnpm 11 without executing msw's
  service-worker postinstall.
- Add a scaffold test pinning the packages:[] + allowBuilds shape
  so the parser keeps treating it as single-app.

* chore: changeset

* fix(templates): allow monorepo pnpm builds

* ci(templates): validate app workspace conversion

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-05-29 08:24:31 +04:00
Artyom Konoplyov
360e8a19c3 fix(transform-rtl): preserve quotes in transformed className literals (#10495)
* fix(transform-rtl): preserve string literal escapes

* chore(changeset): add rtl quote preservation note

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-05-27 22:29:44 +04:00
github-actions[bot]
e2fa0101e3 chore(release): version packages (#10789)
Co-authored-by: shadcn <m@shadcn.com>
2026-05-27 21:09:59 +04:00
shadcn
55ea86f252 chore: update templates (#10786)
* chore: update templates

* fix(cli): parse pnpm workspace packages

* chore(changeset): add shadcn patch

* chore(changeset): update description

* ci(templates): validate bun and npx init

* ci(templates): expand package manager validation

* ci(templates): parallelize validation

* ci(templates): allow yarn template lockfiles

* fix(cli): allow yarn template installs in ci
2026-05-27 21:08:26 +04:00
shadcn
f584f05489 fix: padding 2026-05-27 19:43:38 +04:00
shadcn
a06ba18dcc Revert "chore: update templates (#10784)" (#10785)
This reverts commit f3e16e7db7.
2026-05-27 19:06:53 +04:00
shadcn
f3e16e7db7 chore: update templates (#10784)
* chore: update templates

* ci(templates): validate generated starters

* fix

* fix(templates): support pnpm 9 workspace config

* ci(templates): test supported pnpm version
2026-05-27 19:04:17 +04:00
shadcn
64afddefd9 chore(v4): update base-ui to 1.5.0 (#10783) 2026-05-27 15:27:43 +04:00
shadcn
c873713992 fix(v4): serve registries from directory (#10781)
* fix(v4): serve registries from directory

* fix(v4): statically cache registries route

* fix
2026-05-27 09:16:59 +04:00
shadcn
3751fdfa4c fix(create): update lock state during render (#10782) 2026-05-26 23:56:45 +04:00
github-actions[bot]
c824d6b78d chore(release): version packages (#10780)
Co-authored-by: shadcn <m@shadcn.com>
2026-05-26 22:58:26 +04:00
shadcn
df1752dfe0 feat: rhea (#10779)
* feat: add rhea

* fix: blocks

* feat: build chat example

* fix

* fix: sidebar

* fix

* feat: update home

* fix

* fix

* fix

* feat: optimizine fonts

* feat

* fix

* fix

* fix

* fix

* fix

* fix

* fix: font in preview

* fix
2026-05-26 22:54:07 +04:00
Dominik K.
e826e543f2 fix(registry): restore missing @blockus object in registry JSON (#10778)
The dominik-ui registry entry accidentally dropped the opening brace for @blockus, leaving invalid JSON in both registry files.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 22:11:01 +04:00
Dominik K.
f7eecafb45 chore(registry): add dominik-ui (#10776)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 21:44:26 +04:00
LN
6e6cf9ee96 Feat/add registry directory blockus (#10711)
* feat: add new registry entry for blockus with logo and description

* chore: rebuild registries.json with blockus entry
2026-05-26 21:18:51 +04:00
Antunes
5b628e23e3 feat(registry): add @toc-cn directory entry (#10759) 2026-05-25 21:38:57 +04:00
shadcn
4a4dc8eb0f Update pnpm release age settings (#10719)
* chore: update pnpm release age settings

* fix: declare pnpm 10 tool dependencies

* fix: align template pnpm versions
2026-05-22 20:10:00 +04:00
Shuta Kumano
a33becad35 feat(registry): add @gymnopedies registry (#10728)
* feat(registry): add @gymnopedies to directory

* chore(registry): rebuild registries.json
2026-05-22 16:25:16 +04:00
KapishDima
d60e8b6ce3 fix: wrap DirectoryList with React.Suspense (#10727) 2026-05-22 15:56:12 +04:00
github-actions[bot]
072c27fcd5 chore(release): version packages (#10568)
Co-authored-by: shadcn <m@shadcn.com>
2026-05-21 17:57:06 +04:00
shadcn
194dcc4571 docs: update changelog 2026-05-21 17:48:36 +04:00
shadcn
51e3cfaf32 feat(registry): add validate command (#10715)
* feat: implement registry include

* feat: updates

* fix

* refactor: implementation

* fix(registry): correct directory registry json

* fix(registry): stop warning for external registry dependencies

* feat(registry): add validate command
2026-05-21 17:32:34 +04:00
shadcn
c8ab3801ec feat: add include to registry.json (#10708)
* feat: implement registry include

* feat: updates

* fix

* refactor: implementation

* fix(registry): correct directory registry json

* fix(registry): stop warning for external registry dependencies

* fix(registry): address include review feedback
2026-05-21 17:13:04 +04:00
shadcn
731e6dd8a2 fix 2026-05-20 17:27:42 +04:00
Tushar Jolly
d7066f4a2d feat: add @next-ui registry (#10693)
* feat: add @next-ui registry

## New Registry: @next-ui

- **Homepage:** https://nexus-ui.com
- **Registry URL:** https://nexus-ui.com/r/{name}.json
- **Registry index:** https://nexus-ui.com/registry.json
- **Components:** 57 motion-native components for Next.js

### Checklist
- [x] registry.json live at https://nexus-ui.com/registry.json
- [x] Component files live at https://nexus-ui.com/r/{name}.json
- [x] Open source
- [x] Works with shadcn CLI

* Add Nexus Labs registry entry to registries.json
2026-05-20 16:49:50 +04:00
Matt
5274de83d6 feat(registry): add @bklit registry (#10707)
Add Bklit UI to the open source registry index (directory.json and
registries.json) for shadcn add and shadcn search.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-20 16:44:20 +04:00
Fabian Hiller
7e4dac7f31 feat: add Formisch (form library) examples to docs (#10342)
* feat: add Formisch (form library) examples to docs

* docs: update Formisch docs with additional form methods and examples

* chore: update valibot dependency to version 1.4.0

* style(docs): format formisch imports

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-05-20 15:18:41 +04:00
Charlie Hopkins-Brinicombe
28122dba18 feat: add @trophy-ui registry (#10700) 2026-05-20 09:44:13 +04:00
Parth Sharma
93cde61946 feat(registry): add Wensity (#10676) 2026-05-18 22:13:41 +04:00
lcorrigan704
c2dc06a99c add ui.corr.sh registry (#10675) 2026-05-18 18:57:42 +04:00
shadcn
c9930b7fda fix(toggle-group): update default spacing (#10681) 2026-05-17 12:52:42 +04:00
shadcn
d1149454a8 fix(create): preserve settings when changing style (#10680) 2026-05-17 12:31:37 +04:00
Michael McGovern
36139f6200 feat(registry): add @paddle registry (#10643)
* Add Paddle UI to directory

* Update description for @ncdai #10591
2026-05-14 15:45:15 +04:00
shadcn
15ac1be92b feat: shadcn/create for existing projects (#10622)
* feat: update project form

* feat: switch to toggle

* fix

* fix: color
2026-05-12 15:15:07 +04:00
Sergey Kuznetsov
8ca30ed32c feat(registry): add @turbopills-ui registry (#10579) 2026-05-10 20:34:04 +04:00
Alex Kostyniuk
e2605bc7c2 Update glasscn registry URL (#10597) 2026-05-10 20:33:38 +04:00
Chánh Đại
b8608d0976 Update description for @ncdai (#10591) 2026-05-09 16:50:22 +04:00
shadcn
fc1ca40af4 fix(v4): revert next dependency bump (#10584) 2026-05-08 10:28:15 +04:00
Yasuhiro Yamada
f454f6e4d1 fix(sidebar): use oklch sidebar tokens in outline shadows (#10577)
Co-authored-by: Yasuhiro Yamada <7986171+galoi@users.noreply.github.com>
2026-05-08 05:27:41 +04:00
Aniket Pawar
8cc7073aec feat(registry): add @framecn (#10558)
* Add new registry entry for @framecn

* Add new entry for @framecn with video components

* Fix JSON formatting in registries.json

* revert @text-ui in registries.json
2026-05-08 05:27:02 +04:00
shadcn
031387a471 deps: update next (#10581)
* deps: update next

* deps
2026-05-08 05:26:02 +04:00
Alexandre Schrammel
dd3567c39d feat(registry): add @amplo registry (#10573) 2026-05-07 10:27:07 +04:00
joe
ad2b8891a5 adds text-ui to the registry (#10571) 2026-05-06 23:23:40 +04:00
shadcn
f6e18c65cf perf: isr preview and llm (#10566)
* perf(create): limit preview prerender params

* perf(llm): generate markdown routes on demand
2026-05-06 14:57:42 +04:00
shadcn
1c4a53a37a test(shadcn): derive previous minor assertion (#10567)
* test(shadcn): derive previous minor assertion

* chore(changeset): add previous minor assertion

* chore: update changeset
2026-05-06 14:29:02 +04:00
shadcn
bc2db187aa feat(docs): add clickable mdx heading anchors 2026-05-06 13:27:03 +04:00
Krishna Agarwal
92b4927a80 feat(registry): add @indiacn registry (#10548) 2026-05-06 13:10:45 +04:00
Matheus Lima
3cbabe012e feat(registry): add @cognicatch to the ecosystem directory (#10217)
* feat(registry): add @cognicatch to directory

* feat(registry): add @cognicatch to directory

* build: update registries.json

* build: update registries.json

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-05-06 13:09:20 +04:00
github-actions[bot]
1137b24a97 chore(release): version packages (#10556)
Co-authored-by: shadcn <m@shadcn.com>
2026-05-05 16:56:17 +04:00
shadcn
bb251e2ab6 docs: add changelog 2026-05-05 16:52:06 +04:00
shadcn
28b3e5f360 fix(cli): suggest previous minor on errors (#10559) 2026-05-05 16:15:58 +04:00
shadcn
309d95017f feat(shadcn): alias placeholders in target (#10528)
* feat: add support for package imports

* fix

* test(cli): surface add command failures

* test(cli): remove stale pnpm pin from fixture

* fix(cli): reject invalid package import targets

* fix(cli): address package import review feedback

* feat(shadcn): alias placeholders in target

* docs: update docs for alias and examples

* chore: remove lockfile drift

* chore: clean up

* fix(shadcn): route target aliases by workspace

* docs(registry): document target subdirectories
2026-05-05 14:55:47 +04:00
shadcn
eb42ae25fd feat: add support for package imports (#10519)
* feat: add support for package imports

* fix

* test(cli): surface add command failures

* test(cli): remove stale pnpm pin from fixture

* fix(cli): reject invalid package import targets

* fix(cli): address package import review feedback

* test: expand coverage

* docs: add package imports docs
2026-05-05 12:24:21 +04:00
Franco Zeta
3977fb9ace feat(registry): add @stepper registry (#10552) 2026-05-04 19:04:54 +04:00
Jay Sharma
7865621397 feat: add @evilbuttons registry with animated button components (#10536)
* feat: add @evilbuttons registry with animated button components

* feat(registry): add @delta registry (#10476)

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

* Added @nordaun registry (#10537)

* feat: add @evilbuttons registry with animated button components

* feat(fix): fix mismatched dis...

---------

Co-authored-by: Patrick Prunty <58374462+pprunty@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
Co-authored-by: Nordaun <admin@nordaun.com>
2026-04-30 17:02:03 +04:00
Nordaun
b07070cd07 Added @nordaun registry (#10537) 2026-04-29 22:30:23 +04:00
Patrick Prunty
ad68a44717 feat(registry): add @delta registry (#10476)
Co-authored-by: shadcn <m@shadcn.com>
2026-04-29 21:09:28 +04:00
Justin Levine
56161142f1 feat: add @shieldcn registry (#10487) 2026-04-28 21:30:30 +04:00
github-actions[bot]
c2e1a5793f chore(release): version packages (#10517)
Co-authored-by: shadcn <m@shadcn.com>
2026-04-28 20:45:27 +04:00
shadcn
ea6086cbcc feat: add preset commands (#10530)
* feat(cli): add preset commands

* docs(skill): update preset command guidance

* docs(cli): document preset commands

* chore: changeset

* fix(cli): refine preset command output

* fix(cli): align preset decode output

* fix(cli): update preset output fields

* docs(changelog): add preset commands entry

* docs(changelog): show preset command output

* docs(changelog): clarify preset resolve examples

* docs(changelog): refine preset examples

* docs(changelog): add preset command sections

* docs(changelog): show preset resolve output

* docs(changelog): clarify preset open example

* docs(changelog): update preset resolve example

* docs: update preset announcement

* docs: link preset announcement to changelog

* test: increase next init timeout
2026-04-28 20:43:16 +04:00
shadcn
68a69d81f7 chore: add devl registry (#10529) 2026-04-28 12:28:07 +04:00
shadcn
55fd4dc71b feat(shadcn): add code redirect (#10526) 2026-04-28 10:32:29 +04:00
shadcn
6dea65ebcb fix(shadcn): apply for monorepo (#10524)
* fix(shadcn): apply for monorepo

* fix
2026-04-28 09:52:10 +04:00
Gurbinder
ba10089b8d feat(registry): Add @evilcharts registry (#10502) 2026-04-27 15:41:47 +04:00
shadcn
8a814f926b ci: fix signed commits permissions (#10518) 2026-04-27 15:13:07 +04:00
shadcn
c236d0c009 feat: add preset code to shadcn info (#10516)
* feat: shadcn info preset code

* chore: changeset

* refactor(shadcn): simplify color catalog

* refactor(shadcn): clean up preset resolver

* chore: format
2026-04-27 12:17:33 +04:00
Shawn.
fd0e0c369b chore: add @dotmatrix to registry directory (#10504) 2026-04-27 10:54:52 +04:00
shadcn
07d14abde1 ci: check signed commits (#10506) 2026-04-27 10:54:04 +04:00
shadcn
8dd51c49f8 fix(registry): use https for xcn homepage 2026-04-26 19:05:42 +04:00
Alex Kostyniuk
c20e0cc596 feat(registry): add @glasscn registry (#10491)
* feat(registry): add @glasscn registry

* chore(registry): remove unrelated @xcn diff
2026-04-26 19:02:23 +04:00
github-actions[bot]
0126502236 chore(release): version packages (#10489)
Co-authored-by: shadcn <m@shadcn.com>
2026-04-25 14:39:56 +04:00
shadcn
94074e4bb2 ci: release 2026-04-25 14:36:50 +04:00
shadcn
eb6e783fb3 feat: add --pointer option (#10488) 2026-04-25 14:24:25 +04:00
Wolfr
f785bfab44 docs(figma): replace Obra Studio entry with Pro edition (#10474)
- Remove free Obra shadcn/ui entry from Free section
- Add Obra shadcn/ui Pro under Paid
2026-04-25 11:26:31 +04:00
shadcn
cc20c8a794 chore: changelog 2026-04-23 10:15:13 +04:00
Mason James
05948dce8e Update shadcnblocks registry description (#10463) 2026-04-22 15:38:03 +04:00
Ray
5d23df4e35 fix(templates): add notFoundComponent to start root route (#10369) 2026-04-22 10:56:23 +04:00
akazwz
abbdd32953 fix(v4): add missing sera styles to public schema (#10452)
* Add Sera styles to v4 public schema

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

* test(v4): tighten public schema style assertion

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2026-04-22 09:50:30 +04:00
Jay Sharma
3f14ffa632 Update URL for @xcn entry in directory.json 2026-04-21 19:27:34 +04:00
ericzakariasson
5927f6de80 chore: update cursor plugin description
Made-with: Cursor
2026-04-21 17:47:35 +04:00
shadcn
39eb34104b Merge pull request #10444 from shadcn-ui/changeset-release/main
chore(release): version packages
2026-04-21 16:28:15 +04:00
github-actions[bot]
7cbc7e8d53 chore(release): version packages 2026-04-21 12:26:54 +00:00
shadcn
d0ac558ce2 Merge pull request #10396 from ramonclaudio/docs/dark-mode-tanstack-start
docs(dark-mode): add tanstack start guide
2026-04-21 16:25:48 +04:00
shadcn
bc0c46a93c Merge pull request #10445 from ericzakariasson/add-cursor-plugin-manifest
feat: add Cursor plugin manifest
2026-04-21 16:23:46 +04:00
shadcn
a64575d8a4 Merge pull request #10454 from Bartek532/feat/loading-ui-registry
feat: add loading-ui registry to index
2026-04-21 16:22:16 +04:00
shadcn
5d0cd7819b Merge pull request #10449 from radiumcoders/main
Add @xcn registry entry
2026-04-21 16:21:23 +04:00
shadcn
13478b26b6 Merge pull request #10451 from shadcn-ui/shadcn/apply-only
feat: add apply --only
2026-04-21 16:20:14 +04:00
Jay Sharma
aee8a71679 Merge branch 'main' into main 2026-04-21 17:18:34 +05:30
Bartek532
4507f1c794 chore: refine loading-ui registry description
Update the Loading UI directory description copy and regenerate the public registries index to keep generated metadata in sync.
2026-04-21 13:22:24 +02:00
Bartosz Zagrodzki
81cd2266aa Merge branch 'main' into feat/loading-ui-registry 2026-04-21 13:20:14 +02:00
Bartek532
cf756b1b55 feat: add loading-ui registry to index
Add the Loading UI registry to the curated directory and regenerate registries.json so the new source appears in the public registry index.
2026-04-21 13:19:18 +02:00
shadcn
5e61f9c4a4 test: ensure --radius is coming through 2026-04-21 13:03:40 +04:00
shadcn
c4def9305f docs: update 2026-04-21 13:03:25 +04:00
shadcn
e456fed9d3 feat: add apply --only 2026-04-21 12:57:56 +04:00
Ray
b95cd29508 Merge branch 'main' into docs/dark-mode-tanstack-start 2026-04-21 03:46:24 -04:00
shadcn
11cbc32840 refactor: caching for build registry 2026-04-21 11:25:56 +04:00
shadcn
01539fb4d7 refactor: add getThemeScript 2026-04-21 10:35:34 +04:00
Radiumcoders
e47ee89dcf Add @xcn registry entry 2026-04-20 20:16:26 +05:30
Ray
2f5c32c0b1 Merge branch 'main' into docs/dark-mode-tanstack-start 2026-04-20 10:22:34 -04:00
ericzakariasson
fbfe9f34bb feat: add Cursor plugin manifest
Adds .cursor-plugin/plugin.json so this repo installs as a Cursor
plugin via /add-plugin shadcn-ui/ui.

- Loads the existing skills/shadcn/SKILL.md skill (auto-discovered
  via the manifest's skills field).
- Registers the shadcn MCP server (npx shadcn@latest mcp) inline so
  users get the same MCP config already documented for every other
  client without hand-editing .cursor/mcp.json.
- Reuses skills/shadcn/assets/shadcn.png as the plugin logo.

No skill content or MCP changes — purely manifest wiring.

Made-with: Cursor
2026-04-20 10:40:32 +02:00
shadcn
d55e059fda Merge pull request #10440 from uiNerd16/add-aicanvas-registry
feat: add @aicanvas registry
2026-04-20 12:37:59 +04:00
shadcn
9c572ab778 fix: chartColor in presets 2026-04-20 12:29:55 +04:00
shadcn
91403eeb63 Merge pull request #10439 from shadcn-ui/changeset-release/main
chore(release): version packages
2026-04-20 12:18:33 +04:00
github-actions[bot]
3411d53856 chore(release): version packages 2026-04-20 08:16:18 +00:00
shadcn
efa2b38d07 Merge pull request #10179 from EthanThatOneKid/fix/accept-header-issue-10164
fix(cli): add Accept: application/json header to registry fetch
2026-04-20 12:15:20 +04:00
shadcn
d00605c5fb chore: changeset 2026-04-20 11:55:18 +04:00
shadcn
4bdeea4c63 docs: update docs 2026-04-20 11:55:13 +04:00
shadcn
f632f5d798 feat: rename header 2026-04-20 11:55:06 +04:00
Ethan Davidson
7d6d489f83 Merge branch 'main' into fix/accept-header-issue-10164 2026-04-19 15:59:29 -07:00
uiNerd16
e8b1be1f22 feat: add @aicanvas registry 2026-04-19 22:10:56 +02:00
shadcn
d987955893 Merge pull request #10399 from ysds/registry-exabase
chore(registry): add @exabase registry
2026-04-19 20:54:40 +04:00
shadcn
7b5435ac0b Merge pull request #10436 from shadcn-ui/shadcn/fix-init-git-new-project-only
fix: ensure git init runs for new projects only
2026-04-19 20:49:03 +04:00
shadcn
f289497e35 Merge branch 'main' into shadcn/fix-init-git-new-project-only 2026-04-19 15:06:58 +04:00
shadcn
0d266984e6 Merge pull request #10438 from shadcn-ui/shadcn/release-workflows
Consolidate release workflows and clarify run names
2026-04-19 15:06:49 +04:00
shadcn
cf92d4f8f2 Consolidate release workflows and beta comment handling 2026-04-19 14:59:14 +04:00
shadcn
b7cfc364ac chore: changeset 2026-04-19 13:11:24 +04:00
shadcn
de385d04fc fix: ensure git init runs for new projects only 2026-04-19 12:55:07 +04:00
shadcn
b9f78c8a35 Merge pull request #10418 from shadcn-ui/changeset-release/main
chore(release): version packages
2026-04-16 20:56:50 +04:00
github-actions[bot]
97b9e7b0ae chore(release): version packages 2026-04-16 16:56:01 +00:00
shadcn
e4b25981bf Merge pull request #10416 from shadcn-ui/shadcn/style-sera
feat: sera
2026-04-16 20:54:32 +04:00
shadcn
1017410468 chore: changeset 2026-04-16 20:51:21 +04:00
shadcn
fa71bb8624 fix 2026-04-16 15:52:36 +04:00
shadcn
d99839ec2a fix 2026-04-16 15:15:30 +04:00
shadcn
70b6bfd687 fix 2026-04-16 14:32:05 +04:00
shadcn
541c08f112 fix 2026-04-16 14:22:28 +04:00
shadcn
420433ae6f Merge branch 'main' into shadcn/style-sera 2026-04-16 14:17:19 +04:00
shadcn
a7d77e0cf7 fix 2026-04-16 13:38:49 +04:00
shadcn
7ec2acc87d fix 2026-04-15 21:04:08 +04:00
ysds
eeb5d22fe5 chore(registry): add @exabase registry 2026-04-15 12:08:19 +09:00
Ray
a757e80242 docs(dark-mode): add tanstack start guide 2026-04-14 15:31:40 -04:00
shadcn
84d1d476b1 Merge pull request #9728 from htmujahid/main
Update URL for @shadcn-editor in registries.json
2026-04-14 21:03:02 +04:00
shadcn
a52a606fb5 Merge branch 'main' into shadcn/style-sera 2026-04-14 00:04:39 +04:00
shadcn
6ba39bb720 fix 2026-04-14 00:03:30 +04:00
shadcn
dd4b5c287c fix 2026-04-13 17:15:11 +04:00
shadcn
aa534e5875 fix 2026-04-13 12:59:38 +04:00
shadcn
2be9640c88 feat: build registry 2026-04-10 11:35:48 +04:00
shadcn
56567ae21a fix 2026-04-10 05:37:42 +04:00
shadcn
429e258322 fix 2026-04-09 16:12:35 +04:00
shadcn
2f57100061 feat: init 2026-04-09 13:49:02 +04:00
shadcn
fc62d5781d Merge pull request #10337 from ramonclaudio/docs/llms-txt-drift
docs(llms.txt): fix 404 and backfill missing routes
2026-04-09 05:13:18 +04:00
shadcn
d86c5e5939 Merge pull request #9484 from ramonclaudio/fix/docs-copy-page-components-list
fix(docs): replace <ComponentsList /> in copy-page and markdown output
2026-04-08 22:02:29 +04:00
shadcn
8006dd1c93 Merge branch 'main' into fix/docs-copy-page-components-list 2026-04-08 21:43:08 +04:00
Ray
1dcbb4c88a docs(llms.txt): fix 404 and backfill missing routes
llms.txt was added in #8460 and hasn't kept up with the docs tree.
Audited every URL against apps/v4/content/docs and fixed the drift
in one pass.

Removed:
- About (/docs/about): returns 404, no about.mdx exists
- Form (/docs/components/form): points at a phantom. No radix/form.mdx
  exists post-#9304. URL only resolves because of a redirect in
  next.config.mjs, which lands at /docs/forms. That page is already
  listed as 'Forms Overview' in the ## Forms section, and the real
  form library docs (React Hook Form, TanStack Form, Next.js) are
  listed there too. The Form component entry is a stale duplicate.

Added to Overview:
- Skills (/docs/skills)
- Directory (/docs/directory)

Added whole RTL section (new since #8460):
- RTL (/docs/rtl)
- RTL - Next.js
- RTL - Vite
- RTL - TanStack Start

Added to Components:
- Direction (Misc)
- Native Select (Form & Input, after Select)
- Sonner (Feedback & Status, after Toast, since Sonner has its own
  docs page even though Toast already uses it under the hood)

Added to Registry:
- Namespaces
- Add a Registry (open source registry index)
- Open in v0 integration
- registry.json schema docs
- registry-item.json spec docs

Descriptions match the short curated style of the rest of the file.
Noticed while working on #9484.
2026-04-08 12:36:44 -04:00
shadcn
4f4ffde4aa chore: update registries 2026-04-08 20:01:13 +04:00
Ray
6d7a0ed93b fix(docs): replace <ComponentsList /> in copy-page and markdown output
The <ComponentsList /> tag on /docs/components was emitted as-is by
the Copy Page button and the /llm/[slug] markdown endpoint because
getComponentsList() walked components.children for pages directly.
After #9304 restructured the folder into components/radix/ and
components/base/ subfolders, the filter always returned [] and the
tag was replaced with an empty string (or, in the copy-page case,
never replaced at all).

- Reuse getPagesFromFolder() from lib/page-tree so the walker stays
  in sync with the on-screen ComponentsList React component.
- Match the existing llms.txt format: flat absolute URLs (the
  /docs/components/:name -> /docs/components/radix/:name redirect in
  next.config.mjs is the canonical form) plus the frontmatter
  description pulled via source.getPage() on each page.
- Export replaceComponentsList() and call it from
  docs/[[...slug]]/page.tsx so the Copy Page button goes through the
  same replacement path as processMdxForLLMs.
2026-04-08 11:50:07 -04:00
shadcn
b909b0363f Merge pull request #10324 from wrappixelTeam/feat/added-shadcn-dashboard
feat(registry): added new registry ( @shadcn-dashboard )
2026-04-08 19:15:16 +04:00
shadcn
a6fa6893eb Merge pull request #10333 from kapishdima/feat/remocn
feat: added @remocn to directory.json
2026-04-08 19:08:48 +04:00
KapishDima
561586bd98 Merge branch 'main' into feat/remocn 2026-04-08 16:41:56 +03:00
kapishdima
7ddb30aade feat: added @remocn to directory.json 2026-04-08 16:38:33 +03:00
shadcn
024425d45a fix: directory pager 2026-04-08 17:05:50 +04:00
Mihir Koshti
4bdaf48f9b Merge branch 'main' into feat/added-shadcn-dashboard 2026-04-08 18:15:55 +05:30
shadcn
e9546e87ff Merge pull request #10332 from shadcn-ui/shadcn/open-preset
feat: add open preset
2026-04-08 16:43:39 +04:00
shadcn
0b34d581f9 feat: add open preset 2026-04-08 16:33:32 +04:00
shadcn
5c2ed5e90e Merge branch 'main' of github.com:shadcn-ui/ui 2026-04-08 14:42:57 +04:00
shadcn
e9443ccd4a docs: add apply changelog 2026-04-08 14:42:52 +04:00
shadcn
1fe0fe65e8 Merge pull request #10331 from shadcn-ui/shadcn/directory-refactor
refactor: directory
2026-04-08 12:31:58 +04:00
shadcn
6823bad998 refactor: directory 2026-04-08 12:23:34 +04:00
shadcn
398e6c3406 fix: formatting in registries.json 2026-04-08 11:52:03 +04:00
shadcn
710cc27de7 Merge pull request #10330 from Aniket-508/feat/termcn-directory
feat(registry): add @termcn
2026-04-08 10:42:26 +04:00
Aniket Pawar
08212a478d feat(registry): add @termcn 2026-04-08 02:47:14 +00:00
shadcn
d718a8045f Merge pull request #10328 from shadcn-ui/changeset-release/main
chore(release): version packages
2026-04-07 22:13:37 +04:00
github-actions[bot]
2c4678c8c8 chore(release): version packages 2026-04-07 17:48:58 +00:00
shadcn
2466a300f4 Merge pull request #10313 from shadcn-ui/shadcn/apply-preset
feat: add apply
2026-04-07 21:47:54 +04:00
shadcn
66fcf1e853 Merge branch 'shadcn/apply-preset' of github.com:shadcn-ui/ui into shadcn/apply-preset 2026-04-07 21:36:15 +04:00
shadcn
5ebd54198d fix 2026-04-07 21:36:09 +04:00
shadcn
3a2d812510 fix
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-07 21:24:14 +04:00
shadcn
7811557088 fix
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-07 21:23:59 +04:00
shadcn
575f1602a1 fix 2026-04-07 21:05:08 +04:00
htmujahid
50dc9b506b fix: update URL for @shadcn-editor to point to raw GitHub content 2026-04-07 19:10:12 +05:00
shadcn
ae70ecc2f3 Merge branch 'shadcn/apply-preset' of github.com:shadcn-ui/ui into shadcn/apply-preset 2026-04-07 18:02:20 +04:00
shadcn
42284f4e64 test: update rtl 2026-04-07 18:02:05 +04:00
Mihir Koshti
6b5aa16668 updated name to @shadcndashboard 2026-04-07 18:31:07 +05:30
Mihir Koshti
706806a207 feat(registry): added new registry ( @shadcn-dashboard ) 2026-04-07 18:07:26 +05:30
Talha Mujahid
8a7502d7fa Merge branch 'shadcn-ui:main' into main 2026-04-07 17:34:11 +05:00
shadcn
abc65a4871 Merge branch 'main' into shadcn/apply-preset 2026-04-07 16:27:29 +04:00
shadcn
7d5af61468 style: fix code block 2026-04-07 16:11:26 +04:00
shadcn
2badcdc31f Merge pull request #10323 from shadcn-ui/docs/component-composition-sections
docs: add composition section
2026-04-07 15:57:44 +04:00
shadcn
64b8263450 docs: add changelog 2026-04-07 15:49:54 +04:00
shadcn
13b4593f37 fix 2026-04-07 15:49:26 +04:00
shadcn
7dc65da6b2 fix 2026-04-07 15:28:19 +04:00
shadcn
98e56b773c Merge branch 'shadcn/apply-preset' of github.com:shadcn-ui/ui into shadcn/apply-preset 2026-04-07 15:27:56 +04:00
shadcn
7ff9778ff0 fix 2026-04-07 15:27:33 +04:00
shadcn
4af7bbf4ba Merge branch 'main' into docs/component-composition-sections 2026-04-07 15:25:02 +04:00
shadcn
f00a94d9e5 docs: add composition section 2026-04-07 15:23:27 +04:00
shadcn
187ae44fa7 Merge pull request #10318 from shadcn-ui/dependabot/npm_and_yarn/templates/start-monorepo/vite-7.3.2
chore(deps-dev): bump vite from 7.3.1 to 7.3.2 in /templates/start-monorepo
2026-04-07 14:40:02 +04:00
shadcn
034178bf7d Merge pull request #10317 from shadcn-ui/dependabot/npm_and_yarn/templates/react-router-monorepo/vite-7.3.2
chore(deps-dev): bump vite from 7.3.1 to 7.3.2 in /templates/react-router-monorepo
2026-04-07 14:39:46 +04:00
shadcn
4064c78bc7 Merge pull request #10316 from shadcn-ui/dependabot/npm_and_yarn/templates/vite-monorepo/vite-7.3.2
chore(deps-dev): bump vite from 7.3.1 to 7.3.2 in /templates/vite-monorepo
2026-04-07 14:39:28 +04:00
shadcn
943b023b7c Merge pull request #10314 from shadcn-ui/dependabot/npm_and_yarn/vite-7.3.2
chore(deps): bump vite from 7.1.12 to 7.3.2
2026-04-07 14:39:12 +04:00
shadcn
e3d654fd26 fix
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-07 14:01:23 +04:00
dependabot[bot]
71d0470be1 chore(deps-dev): bump vite in /templates/start-monorepo
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.3.1 to 7.3.2.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v7.3.2/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.3.2/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.3.2
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-06 22:12:00 +00:00
dependabot[bot]
53bbdc738f chore(deps-dev): bump vite in /templates/react-router-monorepo
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.3.1 to 7.3.2.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v7.3.2/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.3.2/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.3.2
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-06 21:45:55 +00:00
dependabot[bot]
97707ec08e chore(deps-dev): bump vite in /templates/vite-monorepo
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.3.1 to 7.3.2.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v7.3.2/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.3.2/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.3.2
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-06 21:45:51 +00:00
dependabot[bot]
b9ce2f10c3 chore(deps): bump vite from 7.1.12 to 7.3.2
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.1.12 to 7.3.2.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v7.3.2/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.3.2/packages/vite)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-06 20:17:13 +00:00
shadcn
7cb3b13a33 fix 2026-04-06 23:32:48 +04:00
shadcn
e3d2b14911 fix 2026-04-06 23:27:15 +04:00
shadcn
58c9dc2a7e fix 2026-04-06 23:27:09 +04:00
shadcn
3bdf60340d fix 2026-04-06 23:19:37 +04:00
shadcn
c1e29824cd feat: add apply command 2026-04-06 23:14:57 +04:00
shadcn
62f6df75f2 Merge pull request #10310 from shadcn-ui/shadcn/create-cls
fix: page cls
2026-04-06 17:51:50 +04:00
shadcn
62bae86e86 fix: page cls 2026-04-06 17:37:56 +04:00
shadcn
aa69fbf85a Merge pull request #10309 from shadcn-ui/shadcn/create-perf
fix: create page perf
2026-04-06 16:56:13 +04:00
shadcn
8d41295f2c fix: create page perf 2026-04-06 16:45:17 +04:00
shadcn
2b053d916d Merge pull request #10285 from vzkiss/add-flowkit-ui-registry
feat(registry): add @flowkit-ui
2026-04-06 15:22:32 +04:00
shadcn
0d1309f322 Merge branch 'main' of github.com:shadcn-ui/ui 2026-04-06 15:15:59 +04:00
shadcn
c26250dcfe docs: changelog updates 2026-04-06 15:15:42 +04:00
vzkiss
07c5c36be8 Merge branch 'main' into add-flowkit-ui-registry 2026-04-06 08:51:51 +02:00
shadcn
21c9cc5246 Merge pull request #10303 from oliviertassinari/keywords
fix: add base-ui keyword to match GitHub topic
2026-04-06 10:41:35 +04:00
shadcn
058960046a Merge pull request #10167 from oliviertassinari/fix-base-ui-use-client-v2
fix: remove unnecessary Base UI use client
2026-04-06 10:41:17 +04:00
Olivier Tassinari
be80c18ea9 fix: add base-ui keyword to match GitHub topic 2026-04-06 00:29:21 +02:00
vzkiss
3c59a0cd95 Merge branch 'main' into add-flowkit-ui-registry 2026-04-05 23:16:10 +02:00
shadcn
26d0228ee9 fix 2026-04-04 13:51:50 +04:00
shadcn
9050646893 chore: rebuild registry 2026-04-04 13:44:23 +04:00
shadcn
3ca09b9647 Merge branch 'main' into fix-base-ui-use-client-v2
# Conflicts:
#	apps/v4/examples/base/button-render.tsx
#	apps/v4/public/r/styles/base-lyra/button.json
#	apps/v4/public/r/styles/base-mira/slider.json
#	apps/v4/public/r/styles/base-nova/button.json
#	apps/v4/public/r/styles/base-vega/button.json
#	apps/v4/styles/base-luma/ui/slider.tsx
#	apps/v4/styles/base-lyra/ui/accordion.tsx
#	apps/v4/styles/base-lyra/ui/slider.tsx
#	apps/v4/styles/base-nova/ui-rtl/accordion.tsx
#	apps/v4/styles/base-nova/ui-rtl/button.tsx
#	apps/v4/styles/base-nova/ui/button.tsx
2026-04-04 13:42:29 +04:00
shadcn
720ccca653 Merge pull request #10242 from Yngesh-Raman-QED42/fix/native-select-option-colors
fix(native-select): use system colors for option and optgroup
2026-04-04 13:33:45 +04:00
shadcn
1e3dff8daa chore: rebuild registry 2026-04-04 13:21:15 +04:00
shadcn
c116b325ab Merge branch 'main' into fix/native-select-option-colors 2026-04-04 13:11:50 +04:00
shadcn
5b266d3fc9 Merge pull request #10229 from MKSinghDev/patch-1
Add @mksingh to the directory registry
2026-04-04 13:10:25 +04:00
shadcn
6095e6272d Merge pull request #10272 from vinihvc/feat/add-shark-ui-registry
Add @shark to open source registry index
2026-04-04 13:00:14 +04:00
shadcn
f3fc5a62f2 Merge pull request #10241 from glsee/gamifykit-patch-2
chore: update GamifyKit logo
2026-04-04 12:55:24 +04:00
shadcn
ef7507cc9a Merge pull request #10263 from ridemountainpig/add-flightcn-registry
feature: add @flightcn registry
2026-04-04 12:52:27 +04:00
vzkiss
16b7bea50d feat(registry): build @flowkit-ui to registries.json 2026-04-04 01:36:16 +02:00
vzkiss
ccc4caad9c feat(registry): add @flowkit-ui to directory.json 2026-04-04 01:13:04 +02:00
Mukesh Singh
ba2c4fc586 added @mksingh in public registries 2026-04-03 09:39:54 +05:30
Mukesh Singh
bb5afb2df1 Merge branch 'shadcn-ui:main' into patch-1 2026-04-02 21:07:47 -07:00
Vinicius Vicentini
53f45f5f6f running pnpm registry:build 2026-04-02 15:43:11 -06:00
Vinicius Vicentini
990040691c Update directory.json 2026-04-02 12:44:52 -07:00
Vinicius Vicentini
83857679cb Rename registry entry from '@shark-ui' to '@shark' 2026-04-02 12:40:37 -07:00
Vinicius Vicentini
61989da8ec chore(registry): add @shark-ui to open source registry index
Adds Shark UI (Ark UI + Tailwind) to directory.json and regenerates
public/r/registries.json per registry index workflow.

Homepage: https://shark.vini.one
Registry template: https://shark.vini.one/r/{name}.json
Source: https://github.com/vinihvc/shark-ui

Made-with: Cursor
2026-04-02 13:32:45 -06:00
shadcn
768d8a808f Merge pull request #10268 from shadcn-ui/claude/update-schema-luma-atRnG 2026-04-02 18:47:23 +04:00
Claude
95479a06bb Add radix-luma and base-luma styles to schema.json
https://claude.ai/code/session_01UBbkLbn8ihvnnzw62FpBax
2026-04-02 10:32:47 +00:00
ridemountainpig
4289d5fe02 feature: add @flightcn registry 2026-04-02 09:14:21 +08:00
shadcn
5a6702845d feat: adjust slider for mira 2026-04-01 05:14:28 +04:00
github-actions[bot]
ebf2192d98 chore(release): version packages (#10247)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-31 22:27:14 +04:00
shadcn
44c09a19b0 feat: luma (#10246)
* feat: init style-luma

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* chore: changeset

* fix

* fix
2026-03-31 22:24:48 +04:00
shadcn
4101ec98af fix: colors 2026-03-31 11:53:03 +04:00
Yngesh Raman
a7c3300d7a fix(native-select): use system colors for option and optgroup 2026-03-31 13:11:40 +05:30
Kaiden See (Github-verified)
b50acc9d21 chore: update GamifyKit logo 2026-03-31 15:37:54 +08:00
shadcn
fc76a9ada2 fix: customizer 2026-03-31 04:55:01 +04:00
Johurul Haque
d6b4bf8ddc Add @tailgrids to registry directory (#10062)
* feat: add @tailgrids to the registry directory.

* chore: run registry:build script
2026-03-30 16:55:32 +04:00
Mukesh Singh
2c334c3c2d Add @mksingh to the registry
#10228 
Added new registry entry for @mksingh with details and logo.
2026-03-29 03:19:27 -07:00
shadcn
d3de6aa760 refactor: clean up unused files (#10227)
* refactor: clean up unused files

* fix
2026-03-29 12:04:18 +04:00
shadcn
23b2ac4dcf refactor: create page (#10212)
* refactor: create page

* fix
2026-03-29 11:17:39 +04:00
shadcn
e56c476105 fix: debug e2es (#10204)
* fix

* fix

* fix

* fix

* fix

* fix

* Revert "fix"

This reverts commit 98cbe82048.

* fix
2026-03-27 19:37:47 +04:00
github-actions[bot]
14bb486174 chore(release): version packages (#10203)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-27 11:37:12 +04:00
shadcn
12b49c986f fix: packageManager in package.json (#10202)
* fix: packageManager in package.json

* fix
2026-03-27 11:25:05 +04:00
Jamie Davenport
64c8cd99ee feat(registry): adds openpolicy components (#10196) 2026-03-27 10:52:23 +04:00
shadcn
7d718ddaa9 fix: refactor styles (#10190)
* feat: refactor styles handling across v4

* fix

* fix

* fix

* fix

* fix

* fix
2026-03-26 14:36:00 +04:00
shadcn
5570b3e24a Revert "deps: update next to 16.2.1 (#10180)" (#10189)
This reverts commit 8bd161d453.
2026-03-26 14:23:24 +04:00
Ethan Davidson
945298ed2d Merge branch 'main' into fix/accept-header-issue-10164 2026-03-26 00:29:45 -07:00
Ethan Davidson
f9b216af77 docs(registry): document content negotiation with Express example 2026-03-26 00:24:48 -07:00
Ethan Davidson
6525227036 fix(cli): add Accept and User-Agent headers to support content negotiation (fixes #10164) 2026-03-26 00:24:48 -07:00
shadcn
214b1b8479 Revert "feat: refactor styles handling across v4 (#10176)" (#10185)
This reverts commit 64b88b6cdb.
2026-03-26 11:14:52 +04:00
shadcn
8bd161d453 deps: update next to 16.2.1 (#10180)
* deps: update next to 16.2.1

* fix
2026-03-26 10:10:50 +04:00
shadcn
64b88b6cdb feat: refactor styles handling across v4 (#10176)
* feat: refactor styles handling across v4

* fix

* fix

* fix

* fix

* fix

* fix
2026-03-26 09:50:58 +04:00
Olivier Tassinari
0c25e712e1 pnpm registry:build 2026-03-25 11:55:07 +01:00
shadcn
6a070bf8c5 docs: update theming 2026-03-25 12:50:08 +04:00
shadcn
124495f0df fix: yarn (#10173) 2026-03-25 12:04:25 +04:00
shadcn
43f64065b7 docs: rewrite installation docs (#10172) 2026-03-25 11:35:14 +04:00
Olivier Tassinari
4f421aba65 fix: remove unnecessary Base UI use client 2026-03-25 01:35:03 +01:00
shadcn
8bec9c1234 Merge branch 'main' of github.com:shadcn-ui/ui 2026-03-24 22:52:22 +04:00
shadcn
ba6ac6ec63 fix: button 2026-03-24 22:51:51 +04:00
shadcn
b75796ed76 fix: navigation menu (#10162) 2026-03-24 22:29:59 +04:00
shadcn
d82b4a7d98 fix: radial charts for v3 2026-03-24 17:15:45 +04:00
Luis Llanes
5b79499d23 fix(registry): update @shadcncraft entry in directory (#10151)
* fix(registry): update @shadcncraft entry in directory with new homepage, description, and logo

* fix(registry): update @shadcncraft entry in `registries.json` after running `pnpm registry:build` command
2026-03-24 12:12:37 +04:00
shadcn
d78ff8b858 feat: update colors for popovers (#10155)
* feat: update colors for popovers

* fix: project form
2026-03-24 12:12:01 +04:00
shadcn
ef78384bfd feat: replace "Add a block" button with "View Components" linking to /docs/components (#10154)
https://claude.ai/code/session_01NnmghguJjhqSxuHE8PBLNi

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-24 10:13:30 +04:00
Ray
d3ab7fb00b feat(registry): add @ramonclaudio-coderabbit to directory (#9331) 2026-03-23 20:08:25 +04:00
shadcn
bebc4356af fix: chart types (#10147) 2026-03-23 15:58:15 +04:00
shadcn
14bc966fee feat: recharts docs (#10146)
* feat: recharts docs

* docs: update
2026-03-23 15:26:55 +04:00
shadcn
6a4b27b80d fix 2026-03-23 13:30:05 +04:00
shadcn
c5b4080649 fix(v4): restore active chart demos 2026-03-23 13:14:10 +04:00
shadcn
408b25c82a fix(v4): stabilize chart legend keys 2026-03-23 12:29:31 +04:00
shadcn
228b0e3ecd feat(v4): support Recharts v3 2026-03-23 12:16:35 +04:00
shadcn
f900bd57d0 feat: implement reset shortcut (#10145)
* feat: implement reset shortcut

* fix

* fix
2026-03-23 11:31:45 +04:00
Kaiden / GL
6b190c6a18 chore: add GamifyKit to directory (#9286) (#9289)
Co-authored-by: shadcn <m@shadcn.com>
2026-03-23 11:11:14 +04:00
Aryan Gupta
c43bc4f5d6 chore(registry): add @launchui registry (#9332)
Co-authored-by: shadcn <m@shadcn.com>
2026-03-23 11:07:11 +04:00
Sina Bayandorian
9cd14a684f chore: @react-slot added to the list of registries (#9522)
Co-authored-by: shadcn <m@shadcn.com>
2026-03-23 10:58:26 +04:00
shadcn
fc1675e54d Revert "Registry: Add @code-blocks to open registry directory (#9639)" (#10144)
This reverts commit a5abe1aa0f.
2026-03-23 10:52:10 +04:00
Pablo Hdez
a5abe1aa0f Registry: Add @code-blocks to open registry directory (#9639)
* feat: add code-blocks to registries data

* feat: add ``code-blocks`` to directory json file

* feat: add code-blocks to registries file

* Fix @code-blocks registry logo

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-03-23 10:51:38 +04:00
Pulkit
031998436f feat: add pulkitxm's components (#9775)
* chore: add pulkitxm's shadcn component ref.

* Update apps/v4/registry/directory.json

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

* feat: add animated shadcn components by pulkitxm with updated descriptions

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2026-03-23 10:26:37 +04:00
DSikeres1
29cb65c26b feat(registry): add @dsikeres1 registry (#10044)
* feat(registry): add @dsikeres1 registry (react-date-range-picker)

* chore: add @dsikeres1 entry to registries.json

Run registry:build output — adds the public-facing entry
(without logo) to match directory.json.

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-03-23 10:16:23 +04:00
Alexandre Joly
179c0c0b23 Add @react-easy-modals registry (#10064)
* Add @react-easy-modals registry

Add react-easy-modals to the registry directory. Provides a Modal component that integrates with shadcn Dialog for a simple, powerful modal system with TypeScript support and promise-based API.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* use {style} URL for auto Radix/Base UI resolution

* build: run registry:build to update registries.json

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: shadcn <m@shadcn.com>
2026-03-23 10:06:15 +04:00
Petar Stoev
03430e03bf feat(registry): add @w3-kit Web3 components registry (#10081)
* feat(registry): add @w3-kit Web3 components registry

* build: regenerate registries.json

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-03-23 09:54:56 +04:00
Shrey Kuvera
169682d87a Add @odysseyui to directory (#10083)
Co-authored-by: shadcn <m@shadcn.com>
2026-03-23 09:35:08 +04:00
Paul Tsnobiladzé
336eee688e add @rescript-shadcn registry (#10103) 2026-03-23 09:20:35 +04:00
Luis Llanes
32e4827559 docs(figma): update shadcncraft UI Kit entry to reflect new branding and features (#10138) 2026-03-23 09:05:24 +04:00
OrcDev
7a81328b23 feat: update 8bitcn logo to new pixel-art design (#10142) 2026-03-23 09:04:50 +04:00
shadcn
5b40b9de5a Revert "feat: update customizer (#10129)" (#10130)
This reverts commit e327cef2c1.
2026-03-20 16:56:57 +04:00
shadcn
e327cef2c1 feat: update customizer (#10129) 2026-03-20 16:46:40 +04:00
github-actions[bot]
563d572ba0 chore(release): version packages (#10120)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-19 23:36:28 +04:00
shadcn
687f09817b feat: chartColor and fontHeading (#10115)
* feat: chart color

* fix

* fix

* fix: chart color

* chore: changeset

* chore: restore directory registry formatting

* feat: add fontHeading

* feat: rebuild registry

* fix: v0

* refactor

* fix

* fix

* fix

* fix

* fix

* fix: refactor preset handling

* fix

* fix

* fix
2026-03-19 23:35:01 +04:00
shadcn
31dbc6fc91 Merge branch 'main' of github.com:shadcn-ui/ui 2026-03-18 10:53:27 +04:00
Victor Williams
8db2be8b09 feat: add @nexus-ui registry to public directory (#10067) 2026-03-18 10:11:15 +04:00
shadcn
a8bd00466a chore(templates): bump minor dependencies (#10076)
* fix: Update import path for Button component in react-router-app template

* chore(templates): bump minor dependencies

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Aboubakary Cissé <58236609+Aboubakary833@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 09:56:02 +04:00
shadcn
e78bb7b4f3 feat: move base picker to project form (#10077)
* feat: move base picker to project form

* fix: format
2026-03-17 09:55:37 +04:00
Aboubakary Cissé
acaa0953df fix: Update import path for Button component in react-router-app template (#10073) 2026-03-17 08:43:46 +04:00
shadcn
632e2c012e fix: update skill and add allowed-tools (#10075) 2026-03-17 08:26:13 +04:00
Danila Yudin
78f6a8b0f0 Add @sabraman ui registry (#10054)
* Add new UI component entry for @sabraman

* fix: update registries.json
2026-03-17 08:07:46 +04:00
Aboubakary Cissé
a9f997d00a fix: Update import path for Button component in react-router-app template 2026-03-17 02:25:06 +00:00
shadcn
dbe1fa76b3 fix(tests): fix e2e sleep (#10061)
* fix(tests): wait for registry readiness in global setup instead of per-test sleep

The first e2e test was flaky on CI because `start-server-and-test` only
checks that the root URL (http://localhost:4000) responds before running
tests, not the /r registry endpoint. The existing 2-second hardcoded sleep
in the first test was unreliable on slower CI runners.

Move the readiness check into the vitest globalSetup so all tests wait for
the registry /r endpoint to actually be reachable before any test starts.

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

* fix(tests): fix race condition in global setup - poll correct URL and CLI binary

Two issues caused the previous fix to fail:

1. Was polling `http://localhost:4000/r` which is a directory → always 404.
   Now polls `{REGISTRY_URL}/index.json`, a real static file that returns 200.

2. The v4 dev script (`pnpm --filter=shadcn build && pnpm icons:dev & next dev`)
   runs the shadcn CLI build in the background while next dev starts immediately.
   On fast CI runs start-server-and-test can detect the server as ready before
   the CLI binary (packages/shadcn/dist/index.js) has been built, causing the
   first test to fail when it tries to invoke the CLI.
   Now explicitly waits for the binary to exist before any test runs.

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

* fix(tests): warm up /init route in global setup to prevent first-test timeout

The CLI's first request during `shadcn init` hits the dynamic Next.js /init
route. On a cold dev server this route takes ~1.8s to compile. Combined with
the rest of what init does (pnpm install, file writes), this pushes the first
test over the 30s CLI timeout on CI. Subsequent tests pass because the route
is already warm.

Polling /init in global setup ensures the route is compiled before any test
runs, making the first test's CLI invocation as fast as all subsequent ones.

Also replaced the /r/index.json poll (a static file that responds immediately
and doesn't reflect real route readiness) with the actual /init route poll,
which also naturally verifies the registry server is up.

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

* fix(tests): warm up 404 route and increase default CLI timeout

Two more issues found in CI logs:

1. The CLI requests font files that don't exist (e.g. /r/styles/new-york-v4/
   font-geist.json), causing Next.js to compile /_not-found/page on the first
   404 response. That compilation takes ~4-5s on a cold dev server and is
   another hidden cost on the first test. Now triggering a 404 in global setup
   so the not-found page is compiled before any test runs.

2. The default CLI timeout of 30s is too tight for CI. Even with the /init and
   404 routes pre-warmed, pnpm install inside the fixture takes ~25s, leaving
   only ~5s of headroom. Increasing the default from 30s to 60s gives a
   comfortable buffer without masking real hangs.

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 16:16:16 +04:00
shadcn
74c4c7508b docs: review all docs (#10058)
* docs: review all docs

* fix

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

* docs(spinner): reintroduce data-icon attribute guidance in radix spinner docs (#10059)

* Initial plan

* docs: add data-icon attribute instructions to radix/spinner.mdx button and badge sections

Co-authored-by: shadcn <124599+shadcn@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: shadcn <124599+shadcn@users.noreply.github.com>

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
2026-03-16 13:29:23 +04:00
atyb a.
4809da6f9c feat(colors): add mauve, olive, mist, and taupe color palettes (#10049)
* fix:Nuqs adapter scope, select color-format component and color copy-to-clipboard

* chore: remove changeset

* feat(colors): add mauve, olive, mist, and taupe color palettes

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-03-16 08:36:19 +04:00
léo
7ffefce9e0 feat: add @0unlumen-ui registry (#9970)
* feat: add @0unlumen-ui registry

* fix: consistent registry name from @0unlumen-ui to @unlumen-ui
2026-03-15 15:21:09 +04:00
shadcn
6cad522930 chore: rebuild registry 2026-03-15 13:02:35 +04:00
shadcn
d683b05d7f chore: remove tooltip from mode switcher (#10047)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 12:58:00 +04:00
Frank
e000e17856 fix(registry): register next form examples (#10021) 2026-03-15 11:50:47 +04:00
shadcn
1be8f98c46 feat: add namespace validation for registries (#10033) 2026-03-15 11:07:13 +04:00
Copilot
6e476e4756 Rename @hooks registry to @shadcnhooks (#10036)
* Initial plan

* Rename @hooks registry to @shadcnhooks

Co-authored-by: shadcn <124599+shadcn@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: shadcn <124599+shadcn@users.noreply.github.com>
2026-03-15 11:06:56 +04:00
github-actions[bot]
e2d36a3a7d chore(release): version packages (#10046)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-03-15 10:07:48 +04:00
shadcn
a97ebe54f1 fix: bundle @antfu/ni to resolve tinyexec missing module error (#10041)
* fix: bundle @antfu/ni to resolve tinyexec missing module error

Fixes #10028.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: changeset

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 10:01:15 +04:00
Ahmed Zougari
b2cc0dfe59 fix(docs): update tanstack commands (#10045) 2026-03-15 10:00:58 +04:00
github-actions[bot]
af99d4ebd3 chore(release): version packages (#10037) 2026-03-14 18:50:45 +04:00
shadcn
a0a072dcdd Merge pull request #9929 from kapishdima/fix/registry-font
Add fontsource and support override for registry:font install
2026-03-14 18:30:41 +04:00
KapishDima
447c7aac06 Merge branch 'main' into fix/registry-font 2026-03-14 16:29:44 +02:00
shadcn
752615f231 Merge pull request #10032 from shadcn-ui/codex/rename-blocks-so-registry
chore: rename @blocks registry to @blocks-so
2026-03-14 18:21:18 +04:00
shadcn
f9b365bc7f chore: changeset 2026-03-14 16:13:05 +04:00
shadcn
17a1a9093a Merge branch 'fix/registry-font' of github.com:kapishdima/ui into fix/registry-font 2026-03-14 16:12:34 +04:00
shadcn
8159e98075 feat: update schema 2026-03-14 16:12:27 +04:00
shadcn
6a527b3e75 chore: rebuild registry 2026-03-14 16:12:18 +04:00
shadcn
ebe689e85c docs: update font examples 2026-03-14 16:12:07 +04:00
shadcn
8b683b44e6 Merge branch 'main' into fix/registry-font 2026-03-14 15:56:54 +04:00
shadcn
725ca574f6 Rename test to clarify non-variable font coverage.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 15:37:06 +04:00
shadcn
1dc39e2484 Add dependency field to font schema for explicit fontsource package control.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 15:34:33 +04:00
shadcn
090556691c Revert "fix: added fountsource, @support ovveride when registry:font install, monorepo init"
This reverts commit ad99fc9a73.
2026-03-14 15:33:15 +04:00
shadcn
8e9f781cdb Merge pull request #9911 from lior-pesoa/main
Add @paletteui entry to directory.json
2026-03-14 14:13:34 +04:00
shadcn
9d7c205442 Merge branch 'main' into pr-9911 and resolve conflicts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 13:56:31 +04:00
shadcn
902379fa3e Merge pull request #9932 from felipemenezes098/feat/registry-add-flx
feat(registry): add @flx
2026-03-14 13:53:57 +04:00
shadcn
94dcf37add Rename @blocks registry to @blocks‑s 2026-03-14 12:39:37 +04:00
felipemenezes098
843a5e2334 feat(registry): add @flx 2026-03-13 16:57:36 -03:00
shadcn
cdaad392ae Merge pull request #10025 from Ziane-Badreddine/main
fix: swap homepage and url fields for @waves-cn registry
2026-03-13 20:53:35 +04:00
shadcn
49abe0d594 Merge branch 'main' into main 2026-03-13 20:52:16 +04:00
shadcn
eeb33ae9c9 fix: homepage and url order in registries.json 2026-03-13 20:47:35 +04:00
Ziane-Badreddine
55fa1bb7cc fix: correct homepage url in waves-cn registry entry 2026-03-13 12:45:26 +00:00
KapishDima
90bbbb7993 Merge branch 'main' into fix/registry-font 2026-03-13 09:19:02 +02:00
shadcn
fc9705665c Merge pull request #9976 from withden/patch-4
Add @pacekit-gsap registry information
2026-03-13 09:49:34 +04:00
Denish Navadiya
52c477e118 Merge branch 'main' into patch-4 2026-03-13 10:59:00 +05:30
withden
41a4573002 Add @pacekit-gsap to registry directory 2026-03-13 10:58:23 +05:30
shadcn
f813fb5884 Merge pull request #10024 from shadcn-ui/chore/remove-deprecated
chore: remove deprecated/ directory and related workflow
2026-03-13 09:24:37 +04:00
shadcn
429c001412 chore: remove deprecated/ directory and related workflow
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:19:17 +04:00
shadcn
cd7743cbc1 Merge pull request #9923 from tsubasakong/lucas/fix-shadcn-ui-9914-preserve-base-on-preset-switch
docs: preserve current base when switching preset codes
2026-03-13 09:00:27 +04:00
shadcn
cadc3f96de chore: small nit in phrasing 2026-03-13 08:59:07 +04:00
shadcn
a74515d6e1 Merge pull request #9973 from jal-co/add-jalco-registry
feat(registry): add @jalco registry
2026-03-13 08:56:28 +04:00
shadcn
0df9af0d75 Merge pull request #9935 from Ziane-Badreddine/main
feat: add @waves-cn registry
2026-03-13 08:56:04 +04:00
shadcn
e653c1a833 Merge pull request #10023 from shadcn-ui/changeset-release/main
chore(release): version packages
2026-03-13 08:40:36 +04:00
github-actions[bot]
8b819e1db4 chore(release): version packages 2026-03-13 04:35:24 +00:00
shadcn
5236bfdf07 Merge pull request #10022 from shadcn-ui/chore/monorepo-pm-changeset
chore: add changeset for monorepo package manager fix
2026-03-13 08:34:26 +04:00
shadcn
7e93eb81ea chore: changeset 2026-03-13 08:33:28 +04:00
shadcn
abf1555a65 Merge pull request #9962 from devinscodebase/fix/monorepo-package-manager-detection
fix: monorepo templates ignore the user's package manager
2026-03-13 08:25:53 +04:00
shadcn
584db77fee Merge branch 'main' into fix/monorepo-package-manager-detection 2026-03-13 08:17:12 +04:00
shadcn
3faa91d670 tests: add more tests coverage 2026-03-13 08:15:56 +04:00
Justin Levine
2bf8ef86b9 fix: revert unintended changes and run registry:build 2026-03-12 21:12:44 -07:00
shadcn
624a4fe320 Merge branch 'main' into patch-4 2026-03-13 08:03:23 +04:00
shadcn
5508b5e4ec Merge branch 'main' into add-jalco-registry 2026-03-13 08:01:39 +04:00
shadcn
3af2ba80e8 Merge pull request #9967 from thomasyuill-livekit/update-agents-ui-registry-domain-to-dot-com
update agents-ui registry from livekit.io to livekit.com
2026-03-13 08:01:27 +04:00
Justin Levine
40a00278ab Merge branch 'main' into add-jalco-registry 2026-03-12 14:08:03 -07:00
Denish Navadiya
5ab89f3ae3 Add @pacekit-gsap registry information 2026-03-12 17:10:30 +05:30
KapishDima
40dc195fad Merge branch 'main' into fix/registry-font 2026-03-12 09:19:14 +02:00
Devin Alexander
ca374ad0a0 Merge branch 'main' into fix/monorepo-package-manager-detection 2026-03-12 08:49:11 +02:00
shadcn
bc9f556c38 docs: fix headings in changelog 2026-03-12 08:00:37 +04:00
Justin Levine
d06e54d2bb feat(registry): add @jalco registry 2026-03-11 18:53:23 -07:00
Ziane-Badreddine
65ddce2886 chore: rebase on main 2026-03-11 19:45:55 +00:00
Thomas Yuill
f413598ba3 update agents-ui registry from livekit.io to livekit.com 2026-03-11 14:17:06 -04:00
Devin Alexander
34c04d5f01 style: fix prettier formatting in create-template.ts 2026-03-11 16:27:30 +02:00
Devin Alexander
0029b3b6f7 fix: respect detected package manager for monorepo templates
All monorepo templates hardcoded `packageManager: "pnpm"` which
meant running `bunx --bun shadcn@latest init --monorepo` would
still shell out to `pnpm install`, triggering Corepack and crashing
under Bun because `process.mainModule` is readonly there.

This removes the hardcoded pnpm override from every monorepo template
config so `getPackageManager()` can actually detect what the user is
running. The scaffold step now adapts the cloned template on the fly:

- strips the `packageManager` field from package.json (avoids Corepack)
- converts pnpm-workspace.yaml to a `"workspaces"` array in package.json
- removes pnpm-lock.yaml
- rewrites `workspace:*` refs to `"*"` when the detected PM is npm
  (npm doesn't support the workspace: protocol)
- picks the right install flags per PM (`--no-frozen-lockfile` for pnpm,
  nothing extra for bun/npm/yarn)

pnpm behavior is completely unchanged — `adaptWorkspaceConfig` early-
returns when the detected PM is pnpm.
2026-03-11 14:52:39 +02:00
KapishDima
75cc35272a Merge branch 'main' into fix/registry-font 2026-03-11 10:32:27 +02:00
shadcn
821ac7ee4d Merge pull request #9961 from shadcn-ui/changeset-release/main
chore(release): version packages
2026-03-11 12:15:13 +04:00
github-actions[bot]
8df46c4ded chore(release): version packages 2026-03-11 08:14:30 +00:00
shadcn
2303ce2372 Merge pull request #9960 from shadcn-ui/shadcn/update-track
feat: update handling of init urls
2026-03-11 12:13:34 +04:00
shadcn
cf672a9575 fix 2026-03-11 12:10:25 +04:00
shadcn
5ee4567353 feat: update handling of init urls 2026-03-11 12:07:18 +04:00
shadcn
6f72dba9c4 Merge pull request #9449 from mazyar-kawa02/main
feat: add @gammaui registry with homepage, URL, description, and logo
2026-03-11 11:56:45 +04:00
shadcn
cd717896fa Merge branch 'main' into main 2026-03-11 11:56:34 +04:00
shadcn
d47562cc08 Merge pull request #9910 from LGLabGreg/feat/@shadcnmaps
feat(registry): add @shadcnmaps
2026-03-11 11:56:01 +04:00
mazyar-kawa02
aff5d7f0c1 feat: add @gammaui registry with homepage, URL, description, and logo 2026-03-11 09:58:32 +03:00
LGLabGreg
4c0be13dcc feat(registry): add @shadcnmaps 2026-03-11 06:56:21 +00:00
shadcn
afa410e47f Merge pull request #9958 from shadcn-ui/changeset-release/main
chore(release): version packages
2026-03-11 10:51:11 +04:00
github-actions[bot]
7ee55e8bd3 chore(release): version packages 2026-03-11 06:50:39 +00:00
shadcn
e3c9a3f9dc Merge pull request #9957 from shadcn-ui/shadcn/fix-resolve-init-url
fix: cache in resolveRegistryBaseConfig
2026-03-11 10:49:43 +04:00
shadcn
aa841e35cf fix: cache in resolveRegistryBaseConfig 2026-03-11 10:48:08 +04:00
shadcn
598fb2f55a feat: track preset code 2026-03-11 10:35:46 +04:00
KapishDima
aa786280a3 Merge branch 'main' into fix/registry-font 2026-03-11 08:29:16 +02:00
shadcn
07fd9d0ea4 Merge pull request #9956 from shadcn-ui/shadcn/button-active
feat: add button active state
2026-03-11 10:28:01 +04:00
KapishDima
6ad0590d87 Merge branch 'main' into fix/registry-font 2026-03-11 08:26:52 +02:00
shadcn
ff51e9ca3c feat: add button active state 2026-03-11 10:18:00 +04:00
shadcn
7958cc6a33 Merge pull request #9688 from niculistana/add-kapwa-registry-to-directory
feat: add @kapwa to registry
2026-03-11 08:20:08 +04:00
shadcn
2871e15418 Merge pull request #9465 from codewithmehmet/add-nessra-registry
feat(registry): add @nessra-ui registry
2026-03-11 08:19:02 +04:00
shadcn
c7d57548e5 Merge pull request #9438 from monab/main
feat(registry): added new @shadcnstore registry
2026-03-11 08:18:41 +04:00
KapishDima
dac13c90f2 Merge branch 'main' into fix/registry-font 2026-03-10 20:39:50 +02:00
shadcn
50d8b764a9 Merge pull request #9951 from shadcn-ui/changeset-release/main
chore(release): version packages
2026-03-10 22:08:45 +04:00
github-actions[bot]
90fc0b2dff chore(release): version packages 2026-03-10 18:08:00 +00:00
shadcn
d9d43d5b3b Merge pull request #9950 from shadcn-ui/shadcn/translucent-preset
chore: changeset
2026-03-10 22:07:02 +04:00
shadcn
ce2c3ca688 chore: changeset 2026-03-10 22:05:58 +04:00
shadcn
3bd1bbe858 Merge pull request #9941 from shadcn-ui/shadcn/translucent
feat: menu appearance
2026-03-10 22:01:58 +04:00
shadcn
448fb0bc06 fix 2026-03-10 21:05:02 +04:00
shadcn
09a84892d9 Merge branch 'shadcn/translucent' of github.com:shadcn-ui/ui into shadcn/translucent 2026-03-10 17:06:43 +04:00
shadcn
16da5f2a56 fix 2026-03-10 17:06:29 +04:00
shadcn
f5f2a02eda Merge branch 'main' into shadcn/translucent 2026-03-10 16:58:09 +04:00
shadcn
dad006aa1e fix 2026-03-10 16:55:09 +04:00
shadcn
20a94ddb77 fix 2026-03-10 16:28:51 +04:00
shadcn
ae733168cd fix 2026-03-10 13:29:15 +04:00
shadcn
49616d2e16 fix 2026-03-10 13:25:21 +04:00
tsubasakong
7bc47bb858 Merge remote-tracking branch 'upstream/main' into sync/pr-9923 2026-03-10 00:29:48 -07:00
KapishDima
e149aac756 Merge branch 'main' into fix/registry-font 2026-03-10 08:54:20 +02:00
shadcn
62abc6be99 Merge pull request #9936 from shadcn-ui/shadcn/fix-animations
fix: animations for sheets and navigation-menu
2026-03-10 10:45:13 +04:00
shadcn
0072c9801f Merge branch 'main' into shadcn/fix-animations 2026-03-10 10:28:42 +04:00
KapishDima
729708ad2e Merge branch 'main' into fix/registry-font 2026-03-10 08:26:03 +02:00
shadcn
a4c6504c96 Merge pull request #9698 from mickadesign/add-fluid-functionalism-registry
Add @fluid registry (Fluid Functionalism)
2026-03-10 10:13:26 +04:00
shadcn
1bd5f3d7c8 fix: animations for sheets and navigation-menu 2026-03-10 10:12:03 +04:00
Micka.design
3d6ea09c50 Merge upstream/main and resolve conflicts 2026-03-09 21:14:45 -07:00
shadcn
f45b8f3066 feat: init 2026-03-09 17:18:12 +04:00
kapishdima
ad99fc9a73 fix: added fountsource, @support ovveride when registry:font install, monorepo init 2026-03-09 12:39:36 +02:00
Lior Pesoa
da05ee321c fix: run registry:build and fix directory.json syntax
- Fix missing comma between entries in directory.json
- Fix multiline SVG logo string
- Regenerate registries.json with @paletteui entry

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-09 10:56:16 +02:00
shadcn
de497a36bb Merge branch 'main' of github.com:shadcn-ui/ui 2026-03-09 09:11:54 +04:00
shadcn
882a9cb145 fix: mode switcher toggle 2026-03-09 09:11:47 +04:00
shadcn
65cb5b49ff ci: add script to check registry 2026-03-09 09:11:34 +04:00
shadcn
ae6f2e67aa Merge pull request #9922 from shadcn-ui/fix/login-02-separator-bg
fix: separator color in blocks
2026-03-09 08:57:51 +04:00
Frank
d13d42d434 docs: preserve base when switching preset codes 2026-03-08 21:54:17 -07:00
shadcn
67c99dd33c fix: separator color in blocks 2026-03-09 08:53:25 +04:00
Nicu Listana
ce012faf1e Merge branch 'main' into add-kapwa-registry-to-directory 2026-03-08 17:50:11 -07:00
lior-pesoa
554a1a69a7 Add @paletteui entry to directory.json 2026-03-08 18:50:13 +02:00
shadcn
e489552614 Merge pull request #9907 from edwinvakayil/feat/iconiq-registry
feat: updating my existing registry
2026-03-08 16:15:04 +04:00
shadcn
8386198073 Merge pull request #9904 from shadcn-ui/changeset-release/main
chore(release): version packages
2026-03-08 16:12:35 +04:00
Edwin Vakayil
9c570f1435 Merge branch 'main' into feat/iconiq-registry 2026-03-08 17:11:41 +05:30
edwiee
ed2d9a6728 feat: updating my existing registry 2026-03-08 17:09:58 +05:30
github-actions[bot]
f336513d18 chore(release): version packages 2026-03-08 10:36:11 +00:00
shadcn
5755d6aa1f Merge pull request #9903 from shadcn-ui/shadcn/fix-template-scaffold
feat(shadcn): scaffold projects from github remote
2026-03-08 14:35:15 +04:00
shadcn
e363e343b7 chore 2026-03-08 14:29:09 +04:00
shadcn
fe955258c3 fix 2026-03-08 14:21:58 +04:00
shadcn
f5ac4a0d2a feat(shadcn): scaffold projects from github remote 2026-03-08 14:17:30 +04:00
shadcn
97ed7eb35c Merge pull request #9864 from kapishdima/fix/laravel-init
fix: added laravel to validation schema
2026-03-08 13:11:35 +04:00
KapishDima
6909385aea Merge branch 'main' into fix/laravel-init 2026-03-08 11:01:25 +02:00
shadcn
8dabe113fa fix: registries 2026-03-08 12:54:48 +04:00
shadcn
f5556230f1 Merge pull request #9757 from harshjdhv/feat/registry-add-componentry
Feat/registry add componentry
2026-03-08 12:45:46 +04:00
shadcn
327551f8b6 Merge branch 'main' into feat/registry-add-componentry 2026-03-08 12:45:26 +04:00
shadcn
cdb4a4547f Merge pull request #9899 from shadcn-ui/changeset-release/main
chore(release): version packages
2026-03-08 12:44:39 +04:00
Harsh Jadhav
52f72b9cf7 Merge branch 'main' into feat/registry-add-componentry 2026-03-08 14:13:54 +05:30
github-actions[bot]
048dac9359 chore(release): version packages 2026-03-08 08:41:12 +00:00
shadcn
f93d44730e Merge pull request #9897 from shadcn-ui/shadcn/fix-cli
fix(shadcn): fallback style resolving issue
2026-03-08 12:40:17 +04:00
shadcn
21c64cb561 fix 2026-03-08 12:39:47 +04:00
shadcn
7e405f1568 fix: --base in project form 2026-03-08 12:39:38 +04:00
shadcn
04248d752e Merge pull request #9883 from kapishdima/feat/fonttrio
feat: added fonttrio to directory.json
2026-03-08 12:33:44 +04:00
shadcn
15f6a0fe49 Merge branch 'main' into feat/fonttrio 2026-03-08 12:33:20 +04:00
shadcn
54d254100d fix 2026-03-08 12:32:58 +04:00
shadcn
6d7f3479d1 Merge pull request #9896 from shadcn-ui/fix/exclude-appledouble-from-template-archives
fix(shadcn): apple metadata files in tar
2026-03-08 12:29:09 +04:00
shadcn
5e1fca8b4e fix 2026-03-08 12:27:37 +04:00
shadcn
30229bfd14 Merge pull request #9888 from llanesluis/chore/update-registry-item-supported-types
chore(docs): update registry item types table
2026-03-08 12:26:16 +04:00
shadcn
1ce9c2dd6a fix(shadcn): apple metadata files in tar 2026-03-08 12:14:24 +04:00
shadcn
5edf9c95b7 fix(shadcn): fallback style resolving issue 2026-03-08 12:05:55 +04:00
Micka.design
35657b4d5f Add @fluid registry (Fluid Functionalism)
Adds Fluid Functionalism to the registry directory.

- Registry URL: https://fluid-functionalism.vercel.app/r/{name}.json
- Homepage: https://fluid-functionalism.vercel.app
- Open source: https://github.com/mickadesign/fluid-functionalism

Fluid components with proximity hover, spring animations, font-weight
transitions, and animated focus rings. Built on Radix primitives,
Framer Motion, and CVA.
2026-03-07 18:31:22 -08:00
Luis Llanes
b7786c4b42 chore(docs): update registry item types to include registry:base and registry:font 2026-03-07 13:27:55 -07:00
kapishdima
6ca3784b67 feat: added fonttrio to directory.json 2026-03-07 19:42:15 +02:00
KapishDima
c1b92c3175 Merge branch 'main' into fix/laravel-init 2026-03-07 09:12:30 +02:00
Harsh Jadhav
b7afa9ba73 Merge branch 'main' into feat/registry-add-componentry 2026-03-07 12:24:09 +05:30
shadcn
119d534e85 Merge pull request #9798 from ncdai/fix/block-viewer-toolbar-device-type-switch 2026-03-07 09:08:16 +04:00
kapishdima
4e416dea5e fix: added laravel to validation schema 2026-03-06 21:54:53 +02:00
shadcn
b600dd7091 Merge pull request #9862 from kapishdima/fix/changelog-command 2026-03-06 22:41:36 +04:00
kapishdima
d59e5be214 fix: added shadcn@latest to command 2026-03-06 20:37:13 +02:00
shadcn
cddbc1f3ff Merge pull request #9802 from edwinvakayil/feat/iconiq-registry
feat: add @iconiq registry
2026-03-06 22:14:01 +04:00
shadcn
7c0d413e3c Merge pull request #9801 from xxtomm/add-spell-registry
feat: add @spell registry
2026-03-06 22:13:28 +04:00
shadcn
00de8addfe Merge pull request #9861 from kapishdima/fix/docs-link
fix: fixed registry link in changelog page
2026-03-06 22:11:47 +04:00
kapishdima
869e7bb17f fix: fixed registry link in changelog page 2026-03-06 20:07:38 +02:00
Edwin Vakayil
8491d4207a Merge branch 'main' into feat/iconiq-registry 2026-03-06 23:07:08 +05:30
shadcn
6f31c22f11 Merge pull request #9733 from shadcn-ui/changeset-release/main
chore(release): version packages
2026-03-06 21:28:32 +04:00
github-actions[bot]
a4c806ec26 chore(release): version packages 2026-03-06 17:25:54 +00:00
shadcn
1445fb769d Merge pull request #9804 from shadcn-ui/shadcn/v4
feat
2026-03-06 21:24:43 +04:00
shadcn
a6bdaa6776 Merge branch 'main' into shadcn/v4 2026-03-06 17:15:52 +04:00
shadcn
b44ca370f1 fix 2026-03-06 17:13:13 +04:00
shadcn
d2776903c2 fix 2026-03-06 17:04:18 +04:00
shadcn
936ee754b1 chore: update skills 2026-03-06 17:03:27 +04:00
edwiee
3a431547bb feat: add @iconiq registry 2026-03-06 18:19:28 +05:30
shadcn
066e1e9abd docs: add changelog 2026-03-06 16:05:21 +04:00
shadcn
b19fa88dec fix: update tracking 2026-03-06 16:05:11 +04:00
shadcn
3aa50ddc9d feat: update create page 2026-03-06 16:05:01 +04:00
xxtomm
f26db39334 feat: add @spell registry 2026-03-06 19:47:00 +09:00
shadcn
3003e9e67a chore: remove 2026-03-06 11:09:45 +04:00
shadcn
ee1303198a chore: add temporary skills 2026-03-06 11:06:27 +04:00
shadcn
acb92a8df9 Merge pull request #9799 from JugglerX/main
Added Shadcnblocks UI Kit to figma docs
2026-03-06 10:00:59 +04:00
Rob Austin
78410f9738 Added Shadcnblocks UI Kit to figma docs
docs: Added Shadcnblocks UI Kit to Figma paid section
2026-03-06 11:17:07 +10:00
shadcn
edf571debd fix 2026-03-05 21:49:44 +04:00
shadcn
257448bead fix 2026-03-05 16:40:21 +04:00
Nguyễn Chánh Đại
e9f4cfb010 fix(BlockViewerToolbar): fix device type switching not working 2026-03-05 19:25:48 +07:00
shadcn
3c5f594b94 chore: remove flags 2026-03-05 15:40:05 +04:00
shadcn
cf3f9f134a feat: add demo component 2026-03-05 15:25:53 +04:00
shadcn
a643dc6ab5 fix 2026-03-05 11:44:10 +04:00
shadcn
8c705f8af9 fix 2026-03-05 11:21:58 +04:00
shadcn
28104c684d fix 2026-03-05 10:11:39 +04:00
shadcn
eccf6a2522 fix 2026-03-05 10:07:51 +04:00
shadcn
8ba3d50d7d feat: add selector to fonts 2026-03-05 10:02:45 +04:00
shadcn
75031d4461 fix 2026-03-05 08:55:34 +04:00
shadcn
13e64ea341 fix: v0 tailwind import 2026-03-04 22:10:00 +04:00
shadcn
6034ffcd3c chore: update skills rc 2026-03-04 17:13:18 +04:00
shadcn
a749633d51 fix: rc 2026-03-04 17:03:42 +04:00
shadcn
dad8a74ab4 fix 2026-03-04 16:52:04 +04:00
shadcn
3f03d30ce5 fix: fonts 2026-03-04 15:52:02 +04:00
shadcn
3365f4ebb2 deps: configure dependabot for templates 2026-03-04 15:18:34 +04:00
shadcn
68b8932406 feat: update template 2026-03-04 14:21:03 +04:00
shadcn
a24351838a fix 2026-03-04 13:49:33 +04:00
shadcn
67b1083f3a fix 2026-03-04 13:08:07 +04:00
shadcn
aa4a97730a feat: use REGISTRY_URL 2026-03-04 13:01:04 +04:00
shadcn
02f34a3b31 fix 2026-03-04 12:14:28 +04:00
shadcn
7cebd74ce5 fix 2026-03-04 11:57:54 +04:00
shadcn
bd1d93bbbc fix 2026-03-04 10:55:10 +04:00
shadcn
37ff1a3d12 fix 2026-03-04 10:50:57 +04:00
shadcn
308ebdbd3b refactor: skills updates 2026-03-04 10:34:45 +04:00
shadcn
cb6e798b90 fix: rework v0 init route 2026-03-04 08:49:23 +04:00
shadcn
2224411358 feat: update layout 2026-03-03 21:48:46 +04:00
shadcn
586f09a0c0 fix: tests 2026-03-03 17:48:00 +04:00
shadcn
475ae744e6 Merge pull request #9644 from binnodon/add-gc-solid-registry
feat: add @gc-solid registry for SolidJS components
2026-03-03 17:15:14 +04:00
shadcn
553b6454f1 Merge branch 'main' into add-gc-solid-registry 2026-03-03 17:14:49 +04:00
shadcn
5805be2a2a Merge pull request #9745 from Shatlyk1011/patch-2
feat: add emerald-ui to registry
2026-03-03 17:14:30 +04:00
shadcn
c44d89a742 Merge branch 'main' into patch-2 2026-03-03 17:14:03 +04:00
shadcn
ce3fc7625a Merge pull request #9746 from SiphoChris/main
feat(registry): add @lmscn
2026-03-03 17:13:38 +04:00
shadcn
2532aeaa1d fix 2026-03-03 17:09:10 +04:00
shadcn
a4dafd1b32 fix 2026-03-03 16:38:10 +04:00
shadcn
07c87ff431 fix 2026-03-03 14:08:21 +04:00
shadcn
4a4b379f21 fix 2026-03-03 14:05:04 +04:00
shadcn
837e2bcc93 feat: rework create page 2026-03-03 13:57:18 +04:00
Binnodon
33dc7ea273 chore: add logo SVG to @gc-solid registry entry
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 17:07:05 -06:00
shadcn
b8da7ce8b8 fix 2026-03-02 22:10:52 +04:00
shadcn
da3c255575 fix 2026-03-02 21:01:52 +04:00
shadcn
5eaad6ea6c refactor: use twmerge for css 2026-03-02 20:55:46 +04:00
shadcn
f68e240293 fix 2026-03-02 20:55:27 +04:00
Binnodon
ddc68e480a Merge remote-tracking branch 'upstream/main' into add-gc-solid-registry 2026-03-02 10:51:56 -06:00
Binnodon
c31ebfaf6b chore: rebuild registries.json with @gc-solid entry
Run `pnpm registry:build` to generate the built registry JSON
as requested by maintainer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 10:48:33 -06:00
shadcn
e79f6e74bb feat: update --diff and --view 2026-03-02 16:15:48 +04:00
shadcn
57f9d875be fix 2026-03-02 14:22:31 +04:00
shadcn
a59144d8e1 style: format 2026-03-02 14:01:31 +04:00
shadcn
3d8837bddb Merge branch 'main' into shadcn/v4
# Conflicts:
#	apps/v4/app/(create)/components/customizer.tsx
#	apps/v4/app/(create)/components/item-picker.tsx
#	apps/v4/app/(create)/components/lock-button.tsx
#	apps/v4/app/(create)/components/picker.tsx
#	apps/v4/app/(create)/components/preview-controls.tsx
#	apps/v4/app/(create)/components/preview.tsx
#	apps/v4/app/(create)/components/random-button.tsx
#	apps/v4/app/(create)/components/reset-button.tsx
#	apps/v4/app/(create)/components/toolbar-controls.tsx
#	apps/v4/app/(create)/create/page.tsx
#	apps/v4/components/docs-sidebar.tsx
#	apps/v4/components/site-header.tsx
#	apps/v4/examples/base/ui-rtl/tooltip.tsx
#	apps/v4/examples/base/ui/tooltip.tsx
#	apps/v4/examples/radix/ui-rtl/tooltip.tsx
#	apps/v4/examples/radix/ui/tooltip.tsx
#	apps/v4/package.json
#	apps/v4/public/r/styles/base-lyra/chatgpt.json
#	apps/v4/public/r/styles/base-lyra/elevenlabs.json
#	apps/v4/public/r/styles/base-lyra/github.json
#	apps/v4/public/r/styles/base-lyra/input-group.json
#	apps/v4/public/r/styles/base-lyra/preview.json
#	apps/v4/public/r/styles/base-lyra/tooltip-example.json
#	apps/v4/public/r/styles/base-lyra/tooltip.json
#	apps/v4/public/r/styles/base-lyra/vercel.json
#	apps/v4/public/r/styles/base-maia/chatgpt.json
#	apps/v4/public/r/styles/base-maia/elevenlabs.json
#	apps/v4/public/r/styles/base-maia/github.json
#	apps/v4/public/r/styles/base-maia/preview.json
#	apps/v4/public/r/styles/base-maia/tooltip-example.json
#	apps/v4/public/r/styles/base-maia/tooltip.json
#	apps/v4/public/r/styles/base-maia/vercel.json
#	apps/v4/public/r/styles/base-mira/chatgpt.json
#	apps/v4/public/r/styles/base-mira/elevenlabs.json
#	apps/v4/public/r/styles/base-mira/github.json
#	apps/v4/public/r/styles/base-mira/input-group.json
#	apps/v4/public/r/styles/base-mira/preview.json
#	apps/v4/public/r/styles/base-mira/tooltip-example.json
#	apps/v4/public/r/styles/base-mira/tooltip.json
#	apps/v4/public/r/styles/base-mira/vercel.json
#	apps/v4/public/r/styles/base-nova/chatgpt.json
#	apps/v4/public/r/styles/base-nova/elevenlabs.json
#	apps/v4/public/r/styles/base-nova/github.json
#	apps/v4/public/r/styles/base-nova/preview.json
#	apps/v4/public/r/styles/base-nova/tooltip-example.json
#	apps/v4/public/r/styles/base-nova/tooltip.json
#	apps/v4/public/r/styles/base-nova/vercel.json
#	apps/v4/public/r/styles/base-vega/chatgpt.json
#	apps/v4/public/r/styles/base-vega/elevenlabs.json
#	apps/v4/public/r/styles/base-vega/github.json
#	apps/v4/public/r/styles/base-vega/preview.json
#	apps/v4/public/r/styles/base-vega/tooltip-example.json
#	apps/v4/public/r/styles/base-vega/tooltip.json
#	apps/v4/public/r/styles/base-vega/vercel.json
#	apps/v4/public/r/styles/radix-lyra/chatgpt.json
#	apps/v4/public/r/styles/radix-lyra/elevenlabs.json
#	apps/v4/public/r/styles/radix-lyra/github.json
#	apps/v4/public/r/styles/radix-lyra/input-group.json
#	apps/v4/public/r/styles/radix-lyra/preview.json
#	apps/v4/public/r/styles/radix-lyra/tooltip-example.json
#	apps/v4/public/r/styles/radix-lyra/tooltip.json
#	apps/v4/public/r/styles/radix-lyra/vercel.json
#	apps/v4/public/r/styles/radix-maia/chatgpt.json
#	apps/v4/public/r/styles/radix-maia/elevenlabs.json
#	apps/v4/public/r/styles/radix-maia/github.json
#	apps/v4/public/r/styles/radix-maia/preview.json
#	apps/v4/public/r/styles/radix-maia/tooltip-example.json
#	apps/v4/public/r/styles/radix-maia/tooltip.json
#	apps/v4/public/r/styles/radix-maia/vercel.json
#	apps/v4/public/r/styles/radix-mira/chatgpt.json
#	apps/v4/public/r/styles/radix-mira/elevenlabs.json
#	apps/v4/public/r/styles/radix-mira/github.json
#	apps/v4/public/r/styles/radix-mira/input-group.json
#	apps/v4/public/r/styles/radix-mira/preview.json
#	apps/v4/public/r/styles/radix-mira/tooltip-example.json
#	apps/v4/public/r/styles/radix-mira/tooltip.json
#	apps/v4/public/r/styles/radix-mira/vercel.json
#	apps/v4/public/r/styles/radix-nova/chatgpt.json
#	apps/v4/public/r/styles/radix-nova/elevenlabs.json
#	apps/v4/public/r/styles/radix-nova/github.json
#	apps/v4/public/r/styles/radix-nova/preview.json
#	apps/v4/public/r/styles/radix-nova/tooltip-example.json
#	apps/v4/public/r/styles/radix-nova/tooltip.json
#	apps/v4/public/r/styles/radix-nova/vercel.json
#	apps/v4/public/r/styles/radix-vega/chatgpt.json
#	apps/v4/public/r/styles/radix-vega/elevenlabs.json
#	apps/v4/public/r/styles/radix-vega/github.json
#	apps/v4/public/r/styles/radix-vega/preview.json
#	apps/v4/public/r/styles/radix-vega/tooltip-example.json
#	apps/v4/public/r/styles/radix-vega/tooltip.json
#	apps/v4/public/r/styles/radix-vega/vercel.json
#	apps/v4/registry/bases/base/blocks/chatgpt.tsx
#	apps/v4/registry/bases/base/blocks/elevenlabs.tsx
#	apps/v4/registry/bases/base/blocks/github.tsx
#	apps/v4/registry/bases/base/blocks/preview.tsx
#	apps/v4/registry/bases/base/blocks/vercel.tsx
#	apps/v4/registry/bases/radix/blocks/chatgpt.tsx
#	apps/v4/registry/bases/radix/blocks/elevenlabs.tsx
#	apps/v4/registry/bases/radix/blocks/github.tsx
#	apps/v4/registry/bases/radix/blocks/preview.tsx
#	apps/v4/registry/bases/radix/blocks/vercel.tsx
2026-03-02 14:00:50 +04:00
shadcn
4d89b13e6f fix 2026-03-02 13:57:42 +04:00
shadcn
7d9689ba01 Merge pull request #9768 from shadcn-ui/shadcn/fix-prettier
style: run format on all components
2026-03-02 13:55:40 +04:00
shadcn
81a1dde380 fix 2026-03-02 13:47:25 +04:00
shadcn
8448acdf90 fix 2026-03-02 13:42:11 +04:00
shadcn
51b867e5dc fix 2026-03-02 13:32:12 +04:00
shadcn
c97ab6ee18 fix 2026-03-02 13:18:27 +04:00
shadcn
9584703534 fix 2026-03-02 13:08:24 +04:00
shadcn
f31ed81983 style: run format on all components 2026-03-02 12:49:00 +04:00
shadcn
e85a698821 fix: handling of fonts 2026-03-02 12:41:50 +04:00
shadcn
2bb09a50a1 refactor: theme colors 2026-03-02 12:41:23 +04:00
shadcn
17ed9baedb fix 2026-03-02 12:30:49 +04:00
shadcn
b40685050d refactor: presets 2026-03-02 11:19:59 +04:00
shadcn
0dab4f92ac fix: esling config for start-monorepo 2026-03-02 11:19:35 +04:00
shadcn
0ddc3503a5 feat: add new serif fonts 2026-03-02 11:19:19 +04:00
Shatlyk
29ea3a7d67 feat: add Emerald UI registry 2026-03-02 11:54:29 +05:00
sinkecpt025
823a1a42b4 feat: add @lmscn registry 2026-03-02 08:25:17 +02:00
shadcn
0b66b1c473 feat: new menu links 2026-03-02 10:15:13 +04:00
shadcn
934afbcf15 docs: review and update docs 2026-03-02 10:14:31 +04:00
shadcn
e0c924d2f4 Merge pull request #9705 from Debbl/feat/update-shadcn-hooks-link
feat: update shadcn-hooks link
2026-03-02 09:40:48 +04:00
shadcn
a92b56491e fix: sidebar demo 2026-03-02 09:37:28 +04:00
shadcn
6dcd9f4fef Merge pull request #9758 from nkurunziza-saddy/fix/base-sidebar-tooltip-render-link
fix(base-sidebar): fix tooltip rendering with render prop
2026-03-02 09:09:37 +04:00
shadcn
f5c36e520e Merge branch 'main' into fix/base-sidebar-tooltip-render-link 2026-03-02 08:59:05 +04:00
shadcn
fb2a3433e2 Merge pull request #9755 from Shitanshukumar607/fix-missing-items
fix the missing items in select page (base ui)
2026-03-01 11:32:42 +04:00
Shitanshu Kumar
87ddddf41e Merge branch 'main' into fix-missing-items 2026-03-01 11:09:13 +05:30
Shatlyk
45c8c1b873 Merge branch 'main' into patch-2 2026-03-01 09:01:06 +05:00
nkurunziza-saddy
68c9ada079 fix(base-sidebar): fix tooltip rendering with render prop 2026-02-28 15:23:27 +02:00
jadhavharshh
16a0473b10 feat: add @componentry registry to available registries and directory. 2026-02-28 17:18:52 +05:30
jadhavharshh
4210d1ab05 add new registry componentry 2026-02-28 17:10:11 +05:30
shadcn
bb7cf2c425 Merge pull request #9749 from alamenai/feat/add-terrae-registry
feat: add @terrae registry
2026-02-28 13:07:31 +04:00
Shitanshu Kumar
1a67379f57 fix the missing items in select page (base ui) 2026-02-28 12:55:48 +05:30
Nicu Listana
d99fcf4a1c Merge branch 'main' into add-kapwa-registry-to-directory 2026-02-27 12:56:04 -08:00
shadcn
9954e2b014 feat: update skill 2026-02-27 21:53:16 +04:00
shadcn
7d28dfdb15 fix: ensure templates are not overwritten 2026-02-27 21:53:07 +04:00
shadcn
fd9c64f416 fix: issue with fonts 2026-02-27 21:52:51 +04:00
shadcn
7e766f4714 faet: add support for laravel in init 2026-02-27 21:52:41 +04:00
shadcn
9dc307f7cc fix: new colors 2026-02-27 18:35:52 +04:00
shadcn
47c0330610 fix: issue with font updates 2026-02-27 18:35:12 +04:00
shadcn
ded8a4086f style: fixes 2026-02-27 18:34:58 +04:00
Ala Eddine
f6dc35c9a1 feat: add @terrae registry
Add Terrae - composable, animated map components for React built with
TypeScript, Tailwind CSS, Mapbox GL JS, and MapLibre GL.
2026-02-27 15:34:42 +01:00
shadcn
408d15f73f feat: add serif fonts 2026-02-27 15:58:51 +04:00
shadcn
a50f6795cc feat: update skills 2026-02-27 12:21:18 +04:00
shadcn
da10396f2b feat: add new base colors: mauve, olive, mist and taupe 2026-02-27 11:46:38 +04:00
shadcn
c2f28e3ef5 feat: update skills 2026-02-27 11:45:50 +04:00
shadcn
40ab22fded fix: bug in registries 2026-02-27 11:45:30 +04:00
sinkecpt025
db0482ed1f feat(registry): add @lmscn 2026-02-27 08:34:20 +02:00
shadcn
9f8a877e8f refactor: clean up formatter 2026-02-27 10:03:18 +04:00
Shatlyk
331fe02c2a feat: add emerald-ui to registry 2026-02-27 11:01:43 +05:00
shadcn
34ee2a17c2 format 2026-02-27 09:39:15 +04:00
shadcn
8dbb61cdd4 Merge branch 'main' into shadcn/init-preset
# Conflicts:
#	apps/v4/public/r/styles/base-lyra/input-group.json
#	apps/v4/public/r/styles/base-lyra/preview.json
#	apps/v4/public/r/styles/base-lyra/registry.json
#	apps/v4/public/r/styles/base-lyra/tooltip.json
#	apps/v4/public/r/styles/base-maia/preview.json
#	apps/v4/public/r/styles/base-maia/registry.json
#	apps/v4/public/r/styles/base-maia/tooltip.json
#	apps/v4/public/r/styles/base-mira/input-group.json
#	apps/v4/public/r/styles/base-mira/preview.json
#	apps/v4/public/r/styles/base-mira/registry.json
#	apps/v4/public/r/styles/base-mira/tooltip.json
#	apps/v4/public/r/styles/base-nova/preview.json
#	apps/v4/public/r/styles/base-nova/registry.json
#	apps/v4/public/r/styles/base-nova/tooltip.json
#	apps/v4/public/r/styles/base-vega/preview.json
#	apps/v4/public/r/styles/base-vega/registry.json
#	apps/v4/public/r/styles/base-vega/tooltip.json
#	apps/v4/public/r/styles/radix-lyra/input-group.json
#	apps/v4/public/r/styles/radix-lyra/registry.json
#	apps/v4/public/r/styles/radix-lyra/tooltip.json
#	apps/v4/public/r/styles/radix-maia/registry.json
#	apps/v4/public/r/styles/radix-maia/tooltip.json
#	apps/v4/public/r/styles/radix-mira/input-group.json
#	apps/v4/public/r/styles/radix-mira/registry.json
#	apps/v4/public/r/styles/radix-mira/tooltip.json
#	apps/v4/public/r/styles/radix-nova/registry.json
#	apps/v4/public/r/styles/radix-nova/tooltip.json
#	apps/v4/public/r/styles/radix-vega/registry.json
#	apps/v4/public/r/styles/radix-vega/tooltip.json
2026-02-27 09:31:02 +04:00
shadcn
cc86750dfb fix: bugs 2026-02-27 09:30:06 +04:00
shadcn
646f884e8f feat: implement dry-run 2026-02-27 09:30:01 +04:00
shadcn
fbdf6c02c1 Merge pull request #9737 from myusubov/fix/notion-prompt-model-dropdown-min-width
fix(notion-prompt-form): replace w-48 with min-w-48 on model dropdown
2026-02-27 09:28:43 +04:00
shadcn
8ab757be8d Merge branch 'main' into fix/notion-prompt-model-dropdown-min-width 2026-02-27 09:28:30 +04:00
shadcn
b557df5840 Merge pull request #9744 from shadcn-ui/shadcn/fix-formatting
feat: ensure bases are formatted before build
2026-02-27 09:28:06 +04:00
shadcn
8271bb7f40 style 2026-02-27 09:22:59 +04:00
shadcn
0008c487e9 feat: ensure bases are formatted before build 2026-02-27 09:18:23 +04:00
shadcn
ae68204542 Merge branch 'main' into fix/notion-prompt-model-dropdown-min-width 2026-02-27 08:13:37 +04:00
Binnodon
e68e081d7f Merge remote-tracking branch 'upstream/main' into add-gc-solid-registry 2026-02-26 14:41:12 -06:00
shadcn
006dc8f9d0 feat: add shadcnuikit to registry 2026-02-26 23:42:59 +04:00
shadcn
b9b30a23e6 feat: add shadcn skills 2026-02-26 22:17:32 +04:00
shadcn
8af3cfd031 fix 2026-02-26 17:27:02 +04:00
shadcn
fae5e78292 feat: add astro template 2026-02-26 17:11:56 +04:00
shadcn
a13adf8f3a fix 2026-02-26 16:15:51 +04:00
Murad
dc89adf190 chore: run prettier format:write 2026-02-26 15:06:18 +03:00
shadcn
3fc793287b fix 2026-02-26 16:03:56 +04:00
shadcn
7d4dd65acd fix 2026-02-26 15:27:34 +04:00
shadcn
d4a2a5fe80 chore: update next 2026-02-26 15:01:15 +04:00
shadcn
d9a01999e8 fix 2026-02-26 13:42:50 +04:00
shadcn
6bb4060686 feat: add --monorepo flag and rework monorepo 2026-02-26 13:33:36 +04:00
shadcn
605246f93b feat: update variable fonts 2026-02-26 13:18:58 +04:00
shadcn
5ef76dece1 feat: add new monorepo templates 2026-02-26 13:17:43 +04:00
shadcn
d24d2e6fd0 feat: add /new page 2026-02-26 13:12:53 +04:00
shadcn
9546f3ad1e refactor: rework create page 2026-02-26 13:12:35 +04:00
Murad
6d2c00376e fix(notion-prompt-form): replace w-48 with min-w-48 on model dropdown to prevent hover clipping 2026-02-26 11:54:42 +03:00
shadcn
117136ada3 fix 2026-02-25 21:08:44 +04:00
shadcn
f130d4d8c7 fix 2026-02-25 18:10:56 +04:00
shadcn
a46eea77a6 Merge pull request #9690 from albertasaftei/patch-pixelart
chore: modified pixelact-ui description
2026-02-25 17:46:14 +04:00
shadcn
0b42927d38 Merge pull request #9708 from shadcn-ui/fix/apply-inside-utility
fix: handling of @apply inside @utility
2026-02-25 17:45:15 +04:00
shadcn
b979ca6e79 feat: rework create 2026-02-25 16:47:15 +04:00
Talha Mujahid
b57e192965 Update URL for @shadcn-editor in registries.json 2026-02-25 08:01:05 +05:00
shadcn
91ce4cc854 feat: new create page 2026-02-24 17:26:48 +04:00
shadcn
b58195e154 Merge pull request #9717 from harishsundar-okta/feat/add-auth0-registry
[Registry Directory]: add auth0 to registry directory
2026-02-24 11:20:17 +04:00
shadcn
0d3f6a0812 chore: deprecate registry:build and registry:mcp 2026-02-23 14:55:11 +04:00
shadcn
22ce4605d8 fix: exit code 2026-02-23 13:20:21 +04:00
harish-sundar_akto
474d461b1c feat(registry): add auth0 to registry directory 2026-02-23 13:30:54 +05:30
shadcn
339de90b8a fix: refactor 2026-02-23 09:58:55 +04:00
shadcn
048313aefa Merge pull request #9710 from ncdai/docs/registry-item-json
docs: add devDependencies section to registry-item-json.mdx
2026-02-22 15:02:23 +04:00
Nguyễn Chánh Đại
805f73582f fix: update husky dependency to name@1.2.0 in registry-item-json.mdx 2026-02-22 06:44:42 +07:00
Nguyễn Chánh Đại
a6ab998e5c docs: add devDependencies section to registry-item-json.mdx 2026-02-22 06:40:48 +07:00
alburt
92075c8426 Merge branch 'main' into patch-pixelart 2026-02-22 00:03:03 +01:00
shadcn
751c520865 feat: refactor 2026-02-21 22:28:47 +04:00
shadcn
4fa2ef66ed feat: add shadcn docs command 2026-02-21 22:28:26 +04:00
shadcn
aa735ef562 feat: add links to ui primitives 2026-02-21 22:27:48 +04:00
shadcn
a927f9c458 Merge branch 'main' into fix/apply-inside-utility 2026-02-21 21:48:24 +04:00
shadcn
82f03d0f1d chore: changeset 2026-02-21 21:41:37 +04:00
shadcn
40aca13fb0 fix: handling of apply directive inside utility 2026-02-21 21:41:01 +04:00
Brendan Dash
e2832bac7c feat: update shadcn-hooks link 2026-02-21 22:31:27 +08:00
shadcn
5f96916701 feat: refactor shadcn info command to output llm-friendly output 2026-02-21 15:18:05 +04:00
shadcn
4a96d95bde chore: changeset 2026-02-21 15:17:26 +04:00
shadcn
dc3eb9081a fix: radius values 2026-02-21 15:17:15 +04:00
shadcn
2ddd920e4d feat: warn if in monorepo 2026-02-21 15:17:06 +04:00
shadcn
e1e9940a04 fix: tooltip 2026-02-21 15:15:48 +04:00
Nicu Listana
bc8626c6f8 Merge branch 'main' into add-kapwa-registry-to-directory 2026-02-20 22:36:08 -08:00
shadcn
f2817b7c49 Merge pull request #9674 from dkroderos/patch-1 2026-02-21 04:21:13 +04:00
Ronny Badilla
fc79e82108 feat(shadcn): add HTTP 410 (Gone) support to registry fetcher 2026-02-21 04:09:47 +04:00
shadcn
58052634fa fix 2026-02-20 23:20:45 +04:00
shadcn
c1374c5592 fix 2026-02-20 22:49:00 +04:00
Binnodon
3a5d636345 Merge upstream main to resolve conflicts
- Resolved conflicts in apps/v4/registry/directory.json
- Kept @gc-solid registry entry in alphabetical order
- Merged upstream changes including new registries (@abui, @arc, @uicapsule, @ui-layouts, @pureui)
- Updated registry components and styles from upstream
2026-02-20 10:01:26 -06:00
shadcn
642d802eee chore: changesets 2026-02-20 16:44:37 +04:00
shadcn
76ba624dce fix 2026-02-20 16:40:41 +04:00
Albert Asaftei
01d5f034b9 chore: modified pixelact-ui description 2026-02-20 09:58:43 +01:00
shadcn
b7ced9f289 Merge branch 'main' into shadcn/init-preset 2026-02-20 10:11:36 +04:00
Nicu Listana
1df2bf4d9b feat: add kapwa to registry 2026-02-19 21:47:23 -08:00
emir
9c39e1ddc9 feat: arc registry 2026-02-19 23:03:36 +04:00
shadcn
bbac1cb663 fix 2026-02-19 20:13:49 +04:00
shadcn
3bc23a60c7 feat: create alias 2026-02-19 15:46:48 +04:00
shadcn
c171ae4761 fix 2026-02-19 13:45:00 +04:00
shadcn
b530f4928e Merge branch 'main' into shadcn/v4-init-preset 2026-02-19 12:46:42 +04:00
shadcn
9fc6afd181 fix 2026-02-19 12:46:16 +04:00
shadcn
eb3d88afbf Merge pull request #9641 from shadcn-ui/shadcn/fix-lint
fix: eslint config
2026-02-19 12:45:57 +04:00
shadcn
8ded0658d4 fix 2026-02-19 12:44:06 +04:00
shadcn
d032f81fd6 fix 2026-02-19 11:53:47 +04:00
shadcn
75becccf78 Merge branch 'main' into shadcn/v4-init-preset
# Conflicts:
#	apps/v4/registry/styles/style-maia.css
#	apps/v4/registry/styles/style-mira.css
#	apps/v4/registry/styles/style-nova.css
#	apps/v4/registry/styles/style-vega.css
2026-02-19 11:36:18 +04:00
shadcn
bfb84e2960 Merge pull request #9676 from shadcn-ui/shadcn/radio-group-icon
feat: update style of radio groups
2026-02-19 11:35:15 +04:00
shadcn
2f64c5a407 fix 2026-02-19 11:32:29 +04:00
shadcn
9e6765f4e2 feat: update style of radio groups 2026-02-19 11:28:01 +04:00
shadcn
d77c84b7c9 Merge branch 'main' into shadcn/v4-init-preset 2026-02-19 10:52:11 +04:00
shadcn
7172f787ac feat 2026-02-19 10:51:37 +04:00
David King Roderos
77f66d5357 Fix highlighted changes
On the sorting section, I've included the closing brackets of state of useReactTable() on the highlighted changes
2026-02-19 14:08:31 +08:00
shadcn
4307815c0f chore: changeset 2026-02-19 09:10:36 +04:00
shadcn
b484f36a22 feat: add preset code 2026-02-19 09:09:59 +04:00
shadcn
360a649d2a fix: base handling 2026-02-17 23:03:19 +04:00
shadcn
4bdd23291c chore: changeset 2026-02-17 22:47:16 +04:00
shadcn
1ee480122b fix 2026-02-17 22:46:50 +04:00
shadcn
382a5220e0 feat(shadcn): implement --reinstall flag 2026-02-17 22:39:49 +04:00
shadcn
627155b13c Merge pull request #9660 from shadcn-ui/shadcn/issue-9657
docs: add shadcn dependency in manual docs
2026-02-17 22:26:25 +04:00
shadcn
0ca4dd1b32 docs: add shadcn dependency in manual docs 2026-02-17 22:21:54 +04:00
shadcn
383bcc4fc1 fix 2026-02-17 15:22:53 +04:00
shadcn
8028a0d75d feat: add react-router template 2026-02-17 15:21:13 +04:00
shadcn
31c1c5eb56 fix 2026-02-17 14:47:50 +04:00
shadcn
ca9295016a Merge branch 'shadcn/init-preset' of github.com:shadcn-ui/ui into shadcn/init-preset 2026-02-17 14:45:32 +04:00
shadcn
7b90fe9833 fix 2026-02-17 14:45:26 +04:00
shadcn
330786352c Merge branch 'main' into shadcn/init-preset 2026-02-17 14:29:34 +04:00
shadcn
da309ae929 debug 2026-02-17 14:29:20 +04:00
shadcn
3877ae5328 fix 2026-02-17 14:10:35 +04:00
shadcn
9c99070d54 Merge pull request #9645 from albertasaftei/patch-1
chore: added Pixelact UI to registry
2026-02-17 14:00:59 +04:00
shadcn
5751250a7f Merge pull request #9654 from shadcn-ui/shadcn/issue-9651
fix: aria-disabled for accordion for base-ui
2026-02-17 14:00:03 +04:00
shadcn
f97ff8124c Merge branch 'main' into shadcn/issue-9651 2026-02-17 13:56:03 +04:00
shadcn
7f37ed96d1 Merge branch 'main' of github.com:shadcn-ui/ui 2026-02-17 13:55:26 +04:00
shadcn
7ff7049018 style: format 2026-02-17 13:55:10 +04:00
shadcn
ae895787c1 fix: aria-disabled for accordion for base-ui 2026-02-17 13:54:19 +04:00
shadcn
305f5c7d47 Merge pull request #9650 from shadcn-ui/shadcn/style-fixes
fix: nova dropdown sub menu radius
2026-02-17 13:50:23 +04:00
shadcn
f0d3984376 Merge branch 'main' into shadcn/style-fixes 2026-02-17 13:46:36 +04:00
shadcn
b8f355ac4f fix 2026-02-17 13:42:15 +04:00
shadcn
29195a17a7 fix 2026-02-17 13:39:34 +04:00
shadcn
e90efd4fa9 fix: nova dropdown sub menu radius 2026-02-17 13:31:13 +04:00
shadcn
70c158990d Merge pull request #9273 from dhwani1806/fix/alt-d-theme-toggle-9198
fix: update theme toggle key detection to exclude Alt key
2026-02-17 13:22:32 +04:00
Albert Asaftei
6e2efb4b55 feat: pixelact-ui registries.json file 2026-02-17 09:59:45 +01:00
shadcn
18db1a78ab fix 2026-02-17 12:53:10 +04:00
shadcn
bd87d729fd Merge branch 'main' into shadcn/init-preset 2026-02-17 12:35:00 +04:00
shadcn
a6f3ef591f test: update to use mock server 2026-02-17 12:34:45 +04:00
shadcn
aaed0a186c docs: update manual installation 2026-02-17 11:45:33 +04:00
alburt
2b74bbca5c added Pixelact UI to registry 2026-02-17 00:11:31 +01:00
Binnodon
36758f61b4 feat: add @gc-solid registry for SolidJS components
Adds gc-solid registry providing shadcn-ui components ported to SolidJS.

Registry Details:
- 57 UI components built with Kobalte primitives
- Full TypeScript support
- Vega theme
- Deployed at https://binnodon.github.io/gc-solid-ui

Registry Validation:
 Open source (MIT license)
 Valid JSON conforming to registry schema
 Flat structure with registry.json at root
 Files array does not include content property
 All components tested with direct URL installation

Documentation: https://binnodon.github.io/gc-solid-ui
Repository: https://github.com/binnodon/gc-solid-ui
2026-02-16 16:42:25 -06:00
shadcn
f9de81f032 Merge pull request #9587 from romeu-maleiane/fix/add-type-to-SidebarProvider-style-example
add React.CSSProperties type annotation to SidebarProvider style example
2026-02-16 23:34:04 +04:00
shadcn
444aa53803 Merge pull request #9585 from pavan-sh/fix/readme-links
docs: fix README links
2026-02-16 23:32:19 +04:00
shadcn
4e9f3e6e05 Merge pull request #9642 from shadcn-ui/shadcn/issue-9595
fix: remove link to calendar blocks
2026-02-16 23:30:19 +04:00
shadcn
3fc4482d7c fix: remove link to calendar blocks 2026-02-16 23:24:33 +04:00
shadcn
ad851375dd fix 2026-02-16 23:12:04 +04:00
shadcn
dd3e942057 fix 2026-02-16 23:10:24 +04:00
shadcn
dd4439c34a fix: eslint config 2026-02-16 22:58:28 +04:00
shadcn
e81d850438 Merge pull request #9640 from shadcn-ui/shadcn/issue-9614
fix: document buttonVariants for base button
2026-02-16 22:54:58 +04:00
shadcn
779453be26 fix 2026-02-16 22:44:50 +04:00
shadcn
867d341182 fix: document buttonVariants for base button 2026-02-16 22:38:37 +04:00
shadcn
78b51f9a11 fix 2026-02-16 17:54:43 +04:00
shadcn
417772dd9c Merge pull request #9638 from shadcn-ui/shadcn/issue-9635
fix: move className in badgeVariants
2026-02-16 17:44:39 +04:00
shadcn
b86885512f fix: move className in badgeVariants 2026-02-16 16:56:24 +04:00
shadcn
65381cd614 fix 2026-02-16 16:07:21 +04:00
shadcn
e3f11d8fe1 Merge branch 'main' into shadcn/init-preset 2026-02-16 15:24:17 +04:00
shadcn
093eb419a8 fix 2026-02-16 15:23:55 +04:00
shadcn
ad25490cf9 Merge pull request #9616 from shadcn-ui/changeset-release/main
chore(release): version packages
2026-02-16 14:45:15 +04:00
github-actions[bot]
e94d3d80fa chore(release): version packages 2026-02-16 10:40:02 +00:00
shadcn
0e6b6d90bc Merge pull request #9493 from ANIBIT14/add-boldkit-registry
feat(registry): add @boldkit neubrutalism components
2026-02-16 14:39:04 +04:00
shadcn
ce1f9259bf chore: update changesets 2026-02-16 14:37:08 +04:00
shadcn
8cec12b98b feat: deprecate --css-variables flag for add 2026-02-16 14:37:02 +04:00
shadcn
028b1b2d93 feat: refactor add command 2026-02-16 14:15:24 +04:00
shadcn
d8e5d0d4f1 Merge branch 'main' into shadcn/init-preset 2026-02-16 12:28:00 +04:00
shadcn
0da9826821 Merge pull request #9624 from hongaar/clean-up-path-collisions
chore(v4): clean up path collisions
2026-02-16 11:50:44 +04:00
shadcn
b416e09e8b Merge branch 'main' into shadcn/init-preset 2026-02-15 20:32:21 +04:00
shadcn
2ef58bd75d Merge pull request #9634 from kapishdima/feat/soundcn
feat: added soundcn to directory
2026-02-15 20:30:34 +04:00
shadcn
cac794208e Merge branch 'main' into feat/soundcn 2026-02-15 20:30:11 +04:00
shadcn
a22aec8694 chore: rebuild 2026-02-15 20:29:58 +04:00
shadcn
6f11e820b5 wip 2026-02-15 20:28:01 +04:00
kapishdima
6a75b60b4f feat: added soundcn to directory 2026-02-15 17:00:30 +02:00
Aniruddha Agarwal
c494adbd87 Merge branch 'main' into add-boldkit-registry 2026-02-15 19:31:45 +05:30
anibit14
3aa0f13869 chore: run registry:build and update BoldKit description
- Updated component count: 43 components, 42 SVG shapes
- Added Vue and Nuxt framework support to description
- Regenerated registries.json as requested
2026-02-15 19:30:14 +05:30
shadcn
e9af9efaf3 fix 2026-02-14 23:16:30 +04:00
shadcn
1ecc8066db fix 2026-02-14 21:03:06 +04:00
shadcn
525775fb36 feat 2026-02-14 18:36:56 +04:00
shadcn
3e4c608aca feat: refactor to templates 2026-02-14 10:24:34 +04:00
shadcn
bd5028e331 fix 2026-02-13 17:24:38 +04:00
shadcn
4207614600 Merge branch 'main' into shadcn/init-preset 2026-02-13 16:19:07 +04:00
shadcn
e1af950724 Merge pull request #9625 from shadcn-ui/shadcn/debug-react-hook-form
fix: checkbox demo for rhf and tanstack form
2026-02-13 16:11:03 +04:00
shadcn
e91388a010 fix 2026-02-13 16:07:57 +04:00
shadcn
8648ddb528 fix 2026-02-13 16:03:19 +04:00
shadcn
feff5b6a57 fix: checkbox example for forms 2026-02-13 15:59:10 +04:00
shadcn
32198910ce wip 2026-02-13 15:19:52 +04:00
Joram van den Boezem
07f7147ff3 chore: clean up path collisions 2026-02-13 11:09:59 +01:00
shadcn
0e8a006adc Merge pull request #9615 from pavan-sh/docs/fix-available-typo
docs: fix typo in December 2023 changelog
2026-02-13 14:05:44 +04:00
codewithmehmet
4193e3c78f Merge branch 'main' into add-nessra-registry 2026-02-13 08:53:58 +01:00
Pavan Shinde
d2f91d6f1e Merge branch 'main' into docs/fix-available-typo 2026-02-12 21:22:56 +05:30
shadcn
9ed5093474 Merge branch 'main' into shadcn/init-preset 2026-02-12 11:37:50 +04:00
shadcn
a12dd019d3 feat: wip for init 2026-02-12 11:37:35 +04:00
shadcn
e53bc92f41 Merge pull request #9599 from shadcn-ui/shadcn/fix-nested-aschild
fix: handling of nested aschild transforms
2026-02-12 11:36:49 +04:00
shadcn
597a8db2d9 Merge pull request #9592 from shadcn-ui/shadcn/fix-base-layer-handling
feat: update handling of base styles
2026-02-12 11:36:32 +04:00
shadcn
0b0f639cd0 Merge pull request #9609 from prithvi-rajan-222/add-slide-cn
chore: Adding slide-cn to the registry
2026-02-12 09:30:35 +04:00
shadcn
6b4ba6bca1 Merge pull request #9613 from petekp/codex/add-tool-ui-registry-directory
registry: add @tool-ui to registry directory
2026-02-12 09:30:08 +04:00
Pavan Shinde
3cdd67b5b4 docs: fix typo in December 2023 changelog 2026-02-12 02:14:52 +00:00
Pete Petrash
2b03bc7a53 registry: add @tool-ui to open registry directory 2026-02-11 11:19:08 -08:00
Aniruddha Agarwal
f6447b8936 Merge branch 'main' into add-boldkit-registry 2026-02-11 23:15:54 +05:30
Prithvi Rajan
4069c33671 Adding slide-cn to the registry 2026-02-10 23:16:46 -08:00
shadcn
4dbc5581a5 fix 2026-02-10 18:51:25 +04:00
shadcn
3fc5c1c995 fix 2026-02-10 17:10:37 +04:00
shadcn
f123057ae5 Merge pull request #9600 from sean0205/reui-package-update
ReUI Registry Update
2026-02-10 12:24:47 +04:00
shadcn
5025ec818f fix: failing tests 2026-02-10 12:16:38 +04:00
sean0205
65c6c8146d reui registry update 2026-02-10 13:03:08 +05:00
shadcn
b93745f24a Merge branch 'main' into shadcn/init-preset 2026-02-10 11:58:17 +04:00
shadcn
bbb59c9fe1 fix: handling of nested aschild transforms 2026-02-10 11:23:36 +04:00
shadcn
fb56f6571a Merge pull request #9598 from AnmolSaini16/AnmolSaini16/add-mapcn-registry
feature: add @mapcn registry
2026-02-10 10:56:09 +04:00
Anmoldeep Singh
082af1f82c feature: add @mapcn registry 2026-02-10 12:09:05 +05:30
shadcn
f5b3a0cbad chore: changeset 2026-02-10 10:38:20 +04:00
shadcn
d602ccc224 feat: fix preset handling and templates 2026-02-10 10:34:38 +04:00
shadcn
ab54e7b7bd feat: update prompt for preset 2026-02-10 10:15:49 +04:00
shadcn
0137b07f66 feat: init 2026-02-10 09:48:17 +04:00
shadcn
ae95fbd1be Merge pull request #9591 from Rhysjosmin/patch-1
Docs:Update Sonner API Reference link in Radix UI
2026-02-09 17:25:48 +04:00
shadcn
625bd97d8b Merge branch 'shadcn/fix-base-layer-handling' of github.com:shadcn-ui/ui into shadcn/fix-base-layer-handling 2026-02-09 17:15:31 +04:00
shadcn
603fce7cd3 Merge branch 'main' into shadcn/fix-base-layer-handling 2026-02-09 17:15:23 +04:00
shadcn
c759f460d5 feat: add docs 2026-02-09 17:13:49 +04:00
shadcn
e1c00667f7 Merge branch 'main' into shadcn/fix-base-layer-handling 2026-02-09 17:05:02 +04:00
shadcn
46631fc4d4 chore: rebuild 2026-02-09 17:04:26 +04:00
shadcn
f235a5d951 feat: update handling of base styles 2026-02-09 16:31:56 +04:00
RhysJosmin
b0b711f181 Update Sonner API Reference link
fixes the same issue solved here
https://github.com/shadcn-ui/ui/pull/9440
but for radix
2026-02-09 17:10:15 +05:30
shadcn
f1b7102583 Merge branch 'main' of github.com:shadcn-ui/ui 2026-02-09 13:19:46 +04:00
shadcn
f076420e68 fix 2026-02-09 13:19:40 +04:00
shadcn
4ce0a7eaa1 Merge pull request #9577 from rezaaa/feat/calendar_hijri_font
feat(calendar): add Vazirmatn font to Persian examples
2026-02-09 12:53:11 +04:00
Reza Mahmoudi
270b730c21 Merge branch 'main' into feat/calendar_hijri_font 2026-02-09 11:52:06 +03:30
shadcn
14a6cc5999 fix: position of command menu 2026-02-09 12:10:41 +04:00
shadcn
0067873f60 fix: block viewer 2026-02-09 12:08:10 +04:00
shadcn
fc16e1461f ci: update validate registries workflow 2026-02-09 11:41:34 +04:00
shadcn
8f01916bb2 Merge pull request #9586 from mxkaske/registries/openstatus
feat(registry): add @openstatus registry
2026-02-09 11:30:45 +04:00
Romeu Maleiane
87d522f249 add React.CSSProperties type annotation to SidebarProvider style example 2026-02-09 00:21:17 +02:00
Maximilian Kaske
ead138b4cd chore: add openstatus registry 2026-02-08 21:28:57 +01:00
Pavan Shinde
ef39979548 docs: fix README links 2026-02-08 14:45:55 +00:00
Reza Mahmoudi
ab6c8caf2f Merge branch 'main' into feat/calendar_hijri_font 2026-02-08 12:05:21 +03:30
shadcn
ba9206bded chore: rebuild registry 2026-02-08 12:08:47 +04:00
Reza Mahmoudi
c5838cf955 Merge branch 'main' into feat/calendar_hijri_font 2026-02-08 00:29:42 +03:30
shadcn
0c41fc30e4 Merge pull request #9426 from inference-sh/add-inferencesh-registry
registry: add @inferencesh
2026-02-07 13:39:54 +04:00
Aniruddha Agarwal
8270cfa39e Merge branch 'main' into add-boldkit-registry 2026-02-07 14:04:03 +05:30
Reza Mahmoudi
06e356cab9 feat(calendar): add Vazirmatn font to Persian examples 2026-02-06 22:04:50 +03:30
shadcn
f24631dc48 Merge pull request #9573 from educlopez/add-thegridcn-registry
feat: add @thegridcn registry
2026-02-06 17:21:55 +04:00
Edu Calvo
ec936bcd06 feat: add @thegridcn registry
Add The Gridcn (thegridcn.com) - a Tron-inspired shadcn/ui theme system with Greek god color schemes, glow intensity levels, and sci-fi components.
2026-02-06 10:47:37 +01:00
shadcn
6c7975e400 feat: default to nova 2026-02-06 13:19:30 +04:00
shadcn
8acef7ab66 docs: add changelog 2026-02-06 13:10:12 +04:00
shadcn
4ddfd39b0d Merge pull request #9440 from rahman-D3V/fix-sonner-doc-link
fix: correct Sonner documentation link
2026-02-06 12:50:31 +04:00
shadcn
3ba37cc24c Merge pull request #9570 from shadcn-ui/shadcn/init-new-york
feat: add shadcn as a dependency for init
2026-02-06 12:49:35 +04:00
shadcn
da080118b0 feat: add shadcn as a dependency for init 2026-02-06 12:35:51 +04:00
shadcn
e8897ea80a Merge pull request #9255 from PhilemonChiro/fix/tanstack-form-performance
fix(docs): improve TanStack Form example performance
2026-02-06 12:27:54 +04:00
shadcn
9d26f582fa Merge pull request #9569 from shadcn-ui/changeset-release/main
chore(release): version packages
2026-02-06 11:23:29 +04:00
github-actions[bot]
0a2ad2176c chore(release): version packages 2026-02-06 07:21:44 +00:00
shadcn
7c36439836 Merge pull request #9568 from shadcn-ui/shadcn/remove-block-message
feat: remove restricted block message
2026-02-06 11:20:44 +04:00
shadcn
a1e3afed06 chore: changeset 2026-02-06 11:14:54 +04:00
shadcn
be5b1bbae3 feat: remove restricted blocks 2026-02-06 11:14:30 +04:00
shadcn
52de23bf95 Merge pull request #9567 from shadcn-ui/shadcn/blocks-for-base
feat: create blocks for new styles
2026-02-06 11:06:19 +04:00
shadcn
1d16fe46cd Merge pull request #9555 from shadcn-ui/dependabot/npm_and_yarn/modelcontextprotocol/sdk-1.26.0
chore(deps): bump @modelcontextprotocol/sdk from 1.17.2 to 1.26.0
2026-02-06 11:01:53 +04:00
shadcn
cbecda13f9 fix 2026-02-06 10:55:44 +04:00
shadcn
24649ec103 fix 2026-02-06 10:51:42 +04:00
shadcn
b9f62a8399 feat: create blocks for new styles 2026-02-06 10:47:18 +04:00
shadcn
689d45e095 Merge branch 'main' of github.com:shadcn-ui/ui 2026-02-05 12:29:31 +04:00
shadcn
33f7b3f2bb fix: minor style updates 2026-02-05 12:29:21 +04:00
shadcn
2cce072393 Merge pull request #9558 from Dinil-Thilakarathne/feat/add-sona-ui-registry
feat: Add @sona-ui to registries and directory.
2026-02-05 12:25:14 +04:00
shadcn
d64bdec2f9 Merge branch 'main' into feat/add-sona-ui-registry 2026-02-05 12:25:02 +04:00
shadcn
5adacdecad Merge pull request #9550 from rgbkrk/add-nteract-to-registry
feat(registry): added new nteract registry
2026-02-05 12:23:11 +04:00
Dinil Thilakarathne
f2552d3f3b feat: Add @sona-ui to registries and directory. 2026-02-05 04:18:30 +05:30
dependabot[bot]
b435e01199 chore(deps): bump @modelcontextprotocol/sdk from 1.17.2 to 1.26.0
Bumps [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk) from 1.17.2 to 1.26.0.
- [Release notes](https://github.com/modelcontextprotocol/typescript-sdk/releases)
- [Commits](https://github.com/modelcontextprotocol/typescript-sdk/compare/1.17.2...v1.26.0)

---
updated-dependencies:
- dependency-name: "@modelcontextprotocol/sdk"
  dependency-version: 1.26.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-04 20:27:49 +00:00
Kyle Kelley
cd576df6e4 feat(registry): added new nteract registry 2026-02-04 10:55:41 -08:00
shadcn
9fbd3b1a72 Merge pull request #9552 from shadcn-ui/changeset-release/main
chore(release): version packages
2026-02-04 21:10:30 +04:00
github-actions[bot]
c6dd35a092 chore(release): version packages 2026-02-04 17:07:09 +00:00
shadcn
470c6f42b0 Merge pull request #9539 from shadcn-ui/shadcn/fix-canonical-classes
fix: canonical classes in bases
2026-02-04 21:05:56 +04:00
shadcn
e6956e45ac Merge branch 'main' into shadcn/fix-canonical-classes 2026-02-04 20:44:08 +04:00
shadcn
a2b9dedbb7 fix: resizable version in registry 2026-02-04 19:52:12 +04:00
shadcn
384129609f fix 2026-02-04 19:48:14 +04:00
shadcn
5be0811f01 fix 2026-02-04 19:23:20 +04:00
shadcn
1a10b4671a Merge branch 'main' into shadcn/fix-canonical-classes
# Conflicts:
#	apps/v4/public/r/styles/base-lyra/tooltip.json
#	apps/v4/public/r/styles/base-maia/tooltip.json
#	apps/v4/public/r/styles/base-mira/tooltip.json
#	apps/v4/public/r/styles/base-nova/tooltip.json
#	apps/v4/public/r/styles/base-vega/tooltip.json
#	apps/v4/public/r/styles/radix-lyra/tooltip.json
#	apps/v4/public/r/styles/radix-maia/tooltip.json
#	apps/v4/public/r/styles/radix-mira/tooltip.json
#	apps/v4/public/r/styles/radix-nova/tooltip.json
#	apps/v4/public/r/styles/radix-vega/tooltip.json
2026-02-04 18:25:27 +04:00
shadcn
e7d36b7e21 Merge pull request #9548 from shadcn-ui/shadcn/fix-code-blocks
feat: update tooltip provider handling
2026-02-04 18:14:54 +04:00
shadcn
290fac9115 Merge branch 'main' into shadcn/fix-code-blocks 2026-02-04 18:09:22 +04:00
shadcn
0633333db4 chore: rebuild registry 2026-02-04 18:06:46 +04:00
shadcn
630323ad47 feat: update TooltipProvider handling 2026-02-04 18:04:19 +04:00
Mona Brahmakshatriya
51fc7f5457 Merge branch 'main' into main 2026-02-04 17:10:33 +05:30
shadcn
44a9b3bd12 fix 2026-02-04 15:18:05 +04:00
shadcn
2b879a5ec8 Merge branch 'shadcn/fix-canonical-classes' of github.com:shadcn-ui/ui into shadcn/fix-canonical-classes 2026-02-04 15:11:48 +04:00
shadcn
381f2ef165 fix 2026-02-04 15:11:30 +04:00
shadcn
825ebca3f0 Merge branch 'main' into shadcn/fix-canonical-classes 2026-02-04 13:15:17 +04:00
shadcn
e0063070a6 feat: add a test:apps script 2026-02-04 13:14:04 +04:00
shadcn
013ae51d10 Merge pull request #9541 from francescopesoli/fix/rtl-password-link-margin
fix(rtl): use logical margin for password link alignment
2026-02-04 11:02:36 +04:00
okaris
08e54510ed rebuild registry 2026-02-03 21:54:23 +01:00
okaris
a95606cee9 add missing logo and rebuild registry 2026-02-03 21:54:23 +01:00
okaris
c990476d99 registry: add @inferencesh 2026-02-03 21:54:23 +01:00
Francesco
44c8f02d06 fix(rtl): use logical margin for password link in RTL examples
Change ml-auto to ms-auto (margin-inline-start) so the Forgot your
  password link aligns correctly in both LTR and RTL layouts.

  Fixes #9515
2026-02-03 18:36:19 +01:00
shadcn
a012542015 fix: duplicate classes 2026-02-03 17:37:11 +04:00
shadcn
926df433a7 fix 2026-02-03 16:43:17 +04:00
shadcn
5c09e0d8fa chore: update canonical classes across styles 2026-02-03 16:41:44 +04:00
shadcn
dba86053f5 fix: canonical classes in base 2026-02-03 14:08:56 +04:00
shadcn
cd188b267d Merge branch 'main' into shadcn/fix-canonical-classes 2026-02-03 11:14:09 +04:00
shadcn
8a09fbaac9 deps: upgrade tailwind 2026-02-03 11:10:54 +04:00
shadcn
9676c8f4ee Merge pull request #9461 from jaem0629/fix/resizable-v4-upgrade
fix(resizable): upgrade to react-resizable-panels v4
2026-02-03 11:09:34 +04:00
Jaem
9b5aeab889 Merge branch 'main' into fix/resizable-v4-upgrade 2026-02-03 09:16:53 +09:00
shadcn
28ebf1b88a Merge pull request #9531 from WebDevSimplified/add-wds-registry
fix: Re-add WDS registry
2026-02-02 21:10:46 +04:00
shadcn
f922e82f53 fix: ring for focus visible 2026-02-02 21:09:10 +04:00
Web Dev Simplified
beec1e060e Add WDS registry 2026-02-02 07:15:58 -06:00
shadcn
26a24d3d5c Merge branch 'fix/resizable-v4-upgrade' of github.com:jaem0629/ui into fix/resizable-v4-upgrade 2026-02-02 16:33:55 +04:00
shadcn
c3c7f03f04 fix: update props, migrate components and add changelog 2026-02-02 16:33:35 +04:00
Jaem
4af29d6c20 Update pnpm-lock.yaml 2026-02-02 21:05:38 +09:00
shadcn
b28f77f893 Merge branch 'main' into fix/resizable-v4-upgrade 2026-02-02 15:57:45 +04:00
shadcn
b8c7ae8088 Merge pull request #9528 from shadcn-ui/changeset-release/main
chore(release): version packages
2026-02-02 15:29:24 +04:00
github-actions[bot]
d21c74fb3a chore(release): version packages 2026-02-02 11:25:41 +00:00
shadcn
d6548b4ae8 Merge pull request #9507 from shadcn-ui/ny-radix-ui
feat: update new-york to radix-ui
2026-02-02 15:24:41 +04:00
shadcn
110a4ec10b docs: add changelog 2026-02-02 15:15:02 +04:00
shadcn
851562f4f2 Merge branch 'ny-radix-ui' of github.com:shadcn-ui/ui into ny-radix-ui 2026-02-02 14:32:21 +04:00
shadcn
b7b839ebc2 chore: changeset 2026-02-02 14:32:01 +04:00
shadcn
8d9be074a3 feat: update migrate radix command 2026-02-02 14:31:40 +04:00
shadcn
a0c077da9e Merge branch 'main' into ny-radix-ui 2026-02-02 13:15:42 +04:00
shadcn
540cd031c3 fix 2026-02-02 13:14:09 +04:00
Jaem
4d9720449f Merge branch 'main' into fix/resizable-v4-upgrade 2026-02-02 15:43:50 +09:00
shadcn
f1e10f3da8 Merge pull request #9495 from withden/patch-3 2026-02-02 08:40:02 +04:00
Denish Navadiya
e2225d4a93 Rename @paceui to @pacekit with updated details
Updated '@paceui' to '@pacekit' with new homepage, URL, and description.
2026-02-02 10:07:22 +05:30
Jaem
444f6889c8 Merge remote-tracking branch 'upstream/main' into fix/resizable-v4-upgrade 2026-02-02 01:16:10 +09:00
Copilot
03a7804c42 Update callout component to use rounded-xl (#9512)
* Initial plan

* Fix callout component to use rounded-lg in style-lyra.css

Co-authored-by: shadcn <124599+shadcn@users.noreply.github.com>

* Revert CSS change - callout.tsx already has rounded-lg

Co-authored-by: shadcn <124599+shadcn@users.noreply.github.com>

* Change callout rounded class from rounded-lg to rounded-xl

Co-authored-by: shadcn <124599+shadcn@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: shadcn <124599+shadcn@users.noreply.github.com>
2026-02-01 15:44:23 +04:00
Chad Bell
acc847bed3 docs(select): add SelectGroup to usage examples (#9508) 2026-02-01 10:19:59 +04:00
shadcn
abfa2ddb74 Merge branch 'main' into ny-radix-ui 2026-01-31 21:19:59 +04:00
shadcn
5e92c160dd feat: update new-york to radix-ui 2026-01-31 21:18:49 +04:00
shadcn
d41e857ba3 fix: select group in field-demo (#9504) 2026-01-31 15:32:07 +04:00
dependabot[bot]
99651191cc chore(deps): bump next in /templates/monorepo-next/apps/web (#9499)
Bumps [next](https://github.com/vercel/next.js) from 16.0.10 to 16.1.5.
- [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.10...v16.1.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-31 15:25:45 +04:00
dependabot[bot]
712285f60e chore(deps): bump eslint from 8.57.1 to 9.26.0 (#9500)
Bumps [eslint](https://github.com/eslint/eslint) from 8.57.1 to 9.26.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/v9.26.0/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.57.1...v9.26.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-version: 9.26.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-31 15:25:21 +04:00
github-actions[bot]
aed95086e0 chore(release): version packages (#9503)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-31 15:10:28 +04:00
shadcn
1990280d66 ci: update changesets 2026-01-31 15:04:54 +04:00
shadcn
2bf55c9133 feat: add geist fonts (#9502) 2026-01-31 14:52:43 +04:00
shadcn
3192a3db55 fix: registry script 2026-01-31 11:34:35 +04:00
shadcn
afa2a7adf2 fix 2026-01-30 22:14:48 +04:00
github-actions[bot]
728d8af275 chore(release): version packages (#9363)
* 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>
2026-01-30 21:13:27 +04:00
shadcn
38de7fddc2 feat: rtl (#9498)
* feat: rtl

* feat

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* feat: add sidebar

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* chore: changeset

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix
2026-01-30 21:08:39 +04:00
Aniruddha Agarwal
c719d24f3a Merge branch 'main' into add-boldkit-registry 2026-01-30 19:31:09 +05:30
shadcn
4479965555 fix: directory.json 2026-01-30 16:41:57 +04:00
Denish Navadiya
7ea124b25d Rename @paceui to @pacekit with updated details 2026-01-30 17:42:39 +05:30
anibit14
f746368369 chore: update component count to 45 2026-01-30 12:14:39 +05:30
anibit14
164b6ff6c1 feat(registry): add @boldkit neubrutalism components 2026-01-30 12:04:00 +05:30
Mehmet Cinar
7ae522e610 feat(registry): add @nessra-ui to registries.json 2026-01-27 22:26:05 +01:00
Mona Brahmakshatriya
e1a0ec3061 Merge branch 'shadcn-ui:main' into main 2026-01-27 16:24:22 +05:30
monab
f8222528eb fix(registry): updated @shadcnstore description for @registries.json 2026-01-27 16:23:39 +05:30
Jaem
759003c781 Merge branch 'main' into fix/resizable-v4-upgrade 2026-01-27 15:11:00 +09:00
Jaem
6d467d2e1d fix: allow vertical scroll pass-through on code blocks (#9454) 2026-01-27 09:57:47 +04:00
Harit
893cddd2dc add satoriui registry (#9432)
* add satoriui registry

* updated registries.json file

---------

Co-authored-by: Harit Patel <harit.ptl.business.com>
2026-01-27 09:50:14 +04:00
Nicolas Vargas
1781186def fix(docs): update navigation-menu docs package name and add styleName (#9455) 2026-01-27 09:48:54 +04:00
Wolfr
89b9a76368 fix - Update copy (#9453) 2026-01-27 09:47:58 +04:00
Jaem
6529256e98 Merge branch 'main' into fix/resizable-v4-upgrade 2026-01-27 11:57:41 +09:00
Mehmet Cinar
b142bd2fd5 feat(registry): add @nessra-ui registry 2026-01-26 23:10:56 +01:00
Saullo Bretas Silva
0266253841 Fix JSON formatting in registries.json (#9464) 2026-01-27 00:49:18 +04:00
Jaem
4a39de5c56 Merge branch 'main' into fix/resizable-v4-upgrade 2026-01-27 03:30:02 +09:00
Nirav joshi
e5fda2c139 Fixed: directory json issue for shadcnspace (#9460)
* feat(registry): add my custom registry

* Feat: Added Shadcnspace into  registries.json

* Updated directory.json

---------

Co-authored-by: ShadcnSpace <shadcnspace@gmail.com>
2026-01-26 22:28:06 +04:00
Jaem
d53f7489ce Merge branch 'main' into fix/resizable-v4-upgrade 2026-01-27 03:19:30 +09:00
Jaem
dfe784b44a fix(resizable): upgrade to react-resizable-panels v4
- Update component API: PanelGroup → Group, PanelResizeHandle → Separator
- Update prop: direction → orientation
- Update size values: number → string with units (e.g., "50%")
- Update CSS selectors: data-[panel-group-direction] → aria-[orientation]
- Update controlled component: onLayout → onLayoutChange with Layout type

Closes #9118, #9136, #9200
2026-01-27 03:10:54 +09:00
Usman Sabuwala
40b9de46e9 Fix Base UI dropdown menu links (#9457)
Base UI does not have a `dropdown-menu` but rather just `menu`
This PR fixes the link that lead to Base UI docs
2026-01-26 22:01:09 +04:00
shadcn
6d97ab0b9b Revert "feat(registry): added new registry(@shadcn-space , @shadcn-dashboard)…" (#9458)
This reverts commit d06e84a007.
2026-01-26 21:03:04 +04:00
ShadcnSpace
d06e84a007 feat(registry): added new registry(@shadcn-space , @shadcn-dashboard) (#9102)
* feat(registry): add my custom registry

* Feat: Added Shadcnspace into  registries.json

---------

Co-authored-by: ShadcnSpace <shadcnspace@gmail.com>
Co-authored-by: Nirav joshi <31440272+Niravjoshi-Wrappixel@users.noreply.github.com>
2026-01-26 20:56:47 +04:00
Akash Moradiya
a29185c9cf fix(directory): basecn registry url typo (#9452) 2026-01-26 09:20:03 +04:00
Sitsiilia
84c801ac67 docs(figma): add shadcn/ui components kit by Sitsiilia Bergmann (#9416)
* docs(figma): add shadcn/ui components kit by Sitsiilia Bergmann

* docs: updates

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-01-26 09:06:35 +04:00
rahman-D3V
3dbe9e6a3e fix: correct Sonner documentation link 2026-01-24 18:32:59 +05:30
Mona Brahmakshatriya
4fa8f9b4c2 Merge branch 'shadcn-ui:main' into main 2026-01-24 17:28:33 +05:30
monab
24205601e1 feat(registry): added new @shadcnstore registry 2026-01-24 17:11:16 +05:30
shadcn
267d45ac7a docs: update changelog 2026-01-23 20:59:49 +04:00
shadcn
caadc3d7e8 feat: update new-york-v4 components to match new styles (#9434) 2026-01-23 20:35:04 +04:00
shadcn
a4ee54836e feat: add inline-start and inline-end support for base-ui (#9430) 2026-01-23 15:26:35 +04:00
shadcn
7b5c919eae fix: format 2026-01-23 15:20:11 +04:00
Hayden Bleasel
f1cacdc051 Update AI Elements Registry URL (#9425)
* Update directory.json

* chore: rebuild registry

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-01-23 11:18:35 +04:00
dependabot[bot]
8cb8fb66b3 chore(deps): bump lodash from 4.17.21 to 4.17.23 (#9415)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.17.23.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

---
updated-dependencies:
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-23 11:12:08 +04:00
Dallas Carraher
ef01cd4315 fix(components): use DialogOverlay in CommandMenu to fix button interactions (#9410)
Replace DialogPrimitive.Overlay with the standard DialogOverlay component
to properly manage the overlay lifecycle with correct animation state
classes. This fixes issue #9403 where buttons on documentation pages
were not working due to react-remove-scroll getting into a corrupted
global state.
2026-01-23 11:10:45 +04:00
shadcn
6cb2a1fd65 fix: sidebar 2026-01-22 23:55:06 +04:00
shadcn
ee88d296f4 feat: refactor component preview 2026-01-22 20:59:59 +04:00
shadcn
598f17812d feat: rss for changelog (#9420)
* feat: init

* fix

* fix
2026-01-22 17:43:45 +04:00
Aron Hafner
0ae734bdb2 docs: Update to correct url for vaul docs (#9406) 2026-01-22 09:58:42 +04:00
shadcn
18bd8f07cb fix: improve perf of v0 route (#9392) 2026-01-20 23:14:52 +04:00
shadcn
5fc9ced0fd fix 2026-01-20 21:53:52 +04:00
shadcn
b5dff005f6 fix 2026-01-20 21:53:00 +04:00
shadcn
c5c08bb773 Merge branch 'main' of github.com:shadcn-ui/ui 2026-01-20 21:33:57 +04:00
shadcn
5998e59839 fix 2026-01-20 21:33:40 +04:00
Ronny Badilla
4b7e38ab42 feat(registry): add @pastecn to the registry (#9390) 2026-01-20 20:53:55 +04:00
shadcn
e2ba2d241e fix: format 2026-01-20 20:51:57 +04:00
shadcn
13e2a6c598 fix: root components 2026-01-20 19:38:04 +04:00
shadcn
47c47eaed2 feat: add docs for base-ui components (#9304)
* feat: add base and radix docs

* feat: transform code for display

* fix

* fix

* fix

* fix

* fix

* chore: remove claude files

* fix

* fix

* fix

* chore: run format:write

* fix

* feat: add more examples

* fix

* feat: add aspect-ratio

* feat: add avatar

* feat: add badge

* feat: add breadcrumb

* fix

* feat: add button

* fix

* fix

* fix

* feat: add calendar and card

* feat: add carousel

* fix: chart

* feat: add checkbox

* feat: add collapsible

* feat: add combobox

* feat: add command

* feat: add context menu

* feat: add data-table dialog and drawer

* feat: dropdown-menu

* feat: add date-picker

* feat: add empty

* feat: add field and hover-card

* fix: input

* feat: add input

* feat: add input-group

* feat: add input-otp

* feat: add item

* feat: add kbd and label

* feat: add menubar

* feat: add native-select

* feat: add more components

* feat: more components

* feat: more components

* feat: add skeleton, slider and sonner

* feat: add spinner and switch

* feat: add more components

* fix: tabs

* fix: tabs

* feat: add docs for sidebar

* fix

* fix

* fi

* docs: update

* fix: create page

* fix

* fix

* chore: add changelog

* fix
2026-01-20 19:31:38 +04:00
shadcn
25e88fe4e9 Revert "Refactor Tooltip component to remove TooltipProvider (#9329)" (#9388)
This reverts commit d3590ceff9.
2026-01-20 12:58:22 +04:00
Francois Botha
d3590ceff9 Refactor Tooltip component to remove TooltipProvider (#9329) 2026-01-20 11:38:32 +04:00
phjjj
d04bc84a51 fix(registry): add missing {name} placeholder to motion-primitives url (#9381)
Co-authored-by: 박해준 <aaagowns@viewlingo.com>
2026-01-19 11:34:29 +04:00
Sunny Patel
f68465e815 docs(theming): add missing destructive-foreground CSS variable (#9379)
Fixes #9337

The `destructive-foreground` variable is used in components but was
missing from the theming documentation. Added the variable to all
color schemes (Neutral, Stone, Zinc, Gray, Slate) in both light and
dark modes.
2026-01-19 11:32:01 +04:00
shadcn
094edfcfe6 fix: charts 2026-01-18 12:11:20 +04:00
shadcn
5a42652c41 fix: theme for charts 2026-01-18 12:02:49 +04:00
shadcn
3409681949 fix: iframe display in dark mode 2026-01-18 11:53:59 +04:00
shadcn
1c989f9155 feat: inline component list on components page (#9368)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 18:40:11 +04:00
shadcn
0aea23013c fix: debug charts (#9364)
* fix: ts-morph for charts

* fix

* perf: parallelize chart loading and add LRU caching

- Prefetch all chart data in parallel using Promise.all()
- Add LRU cache for syntax highlighting (cross-request caching)
- Add LRU cache for registry items (cross-request caching)
- Parallelize file reads within registry items

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

* fix

* fix

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-17 18:28:51 +04:00
shadcn
bfce3031a3 Merge branch 'main' of github.com:shadcn-ui/ui 2026-01-17 13:49:37 +04:00
shadcn
cfb81c61de docs: add shadcn/create callout 2026-01-17 13:49:30 +04:00
Luis Llanes
7860ab83d1 chore(registry): update @shadcraft registry url (#9348)
* chore(registry): update @shadcraft registry url

* fix

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-01-17 13:30:24 +04:00
Паламар Роман
2acaf954d7 Fix: Preserve 'use client' directive in universal registry items (#8798)
* fix: preserve 'use client' directive in universal registry items

Universal items (registry:file and registry:item) are framework-agnostic
components that can be installed without shadcn project initialization.
However, the RSC transformer was incorrectly removing 'use client'
directives from these files when config.rsc was false/undefined, breaking
client-side functionality.

This fix ensures transformers are skipped for universal items, preserving
their original content including 'use client' directives, while regular
shadcn components continue to have transformers applied as expected.

Changes:
- Skip all transformers for registry:file and registry:item types
- Add tests to verify 'use client' preservation in universal items
- Ensure regular components still have transformers applied

Fixes issue where universal items would lose 'use client' directives when
copied without a full shadcn project setup.

* chore: changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-01-17 13:12:01 +04:00
github-actions[bot]
1e9e337923 chore(release): version packages (#9352)
* 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>
2026-01-16 18:07:12 +04:00
Neeraj Dalal
66d2400784 feat(icons): the icons we all love and adore - remixicon (#9156)
* feat: remixicon

* chore: update deps

* chore: update icon

* chore: fix issues

* chore: build registry

* chore: changeset

* deps

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-01-16 18:00:06 +04:00
shadcn
682c98989d feat: registry add command (#9351)
* feat: implement registry add

* chore: changeset

* fix: registries docs

* feat: update add command

* fix
2026-01-16 17:55:48 +04:00
shadcn
77d7b39ef7 chore: rebuild registry 2026-01-16 17:07:32 +04:00
Huy Hoàng
5b3ba49aec fix(calendar): fix typo 'elative' to 'relative' in range_start classname (#9292)
Fixes #9278
2026-01-14 20:43:36 +04:00
shadcn
54edfd228d feat: add new registries (#9325)
* add new registries

* fix

* fix

* docs: add warning

* fix
2026-01-13 16:19:15 +04:00
Aniket Pawar
fd3e5515f3 feat: add @heroicons-animated to directory.json and registries.json (#9268)
* Add new registry for heroicons-animated

* Add '@heroicons-animated' collection to directory

Added new animated icon collection '@heroicons-animated' with homepage, URL, description, and logo.

* Update URL for @heroicons-animated registry

* Update directory.json

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-01-12 18:07:44 +04:00
Amarnath Dhumal
65ad910bca Add Chamaac registry (#9208)
Co-authored-by: shadcn <m@shadcn.com>
2026-01-12 18:05:47 +04:00
Md Kawsar Islam Yeasin
d4a1c89e8e feat: add neobrutalism to registry directory (#9168) 2026-01-12 18:01:59 +04:00
LN
78023693c6 Feat/add registry directory icons animated (#9143)
* feat: add new registry entry for icons-animated

* feat: add new registry entry for icons-animated with logo and description

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-01-12 18:01:37 +04:00
Aman Shakya
0fc52a7f4d Add new registry entry for @forgeui (#9074)
* added forgeui in registries

* Remove duplicate entries in registries.json

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-01-12 17:59:54 +04:00
github-actions[bot]
8fcfc563a9 chore(release): version packages (#9283)
* chore(release): version packages

* deps: update lock

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: shadcn <m@shadcn.com>
2026-01-06 14:40:12 +04:00
shadcn
f393c251fe test: revisit --force (#9287) 2026-01-06 14:29:27 +04:00
Md Kawsar Islam Yeasin
f2583391ea fix(cli): validate project name using npm package name rules (#9161)
* fix(cli): #9160 updated   CLI name validation

* chore: minor refactor and error message

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-01-06 13:28:31 +04:00
sam
c2fd847d65 feat: add OpenCode MCP client support (#8422)
* feat: add OpenCode MCP client support

* chore: changeset

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-01-06 12:16:05 +04:00
Phuc Bui
f6f2dfa5b2 Update URL for @phucbm registry (#9250)
* Fix URL for '@phucbm' in registries.json

Updated the URL for the '@phucbm' registry entry.

* Update homepage and URL in directory.json
2026-01-06 11:33:08 +04:00
shadcn
d07a7af82b chore: add bundui to directory (#9280) 2026-01-05 23:25:04 +04:00
Vitalii Rainchuk
b6d845f8a6 fix(base-ui): resolve pagination example and button client boundary issues (#9207)
* fix(pagination-example): mark example as client component

* fix(button): mark wrapper as client since Base UI button is a client component

* chore: rebuild registry

---------

Co-authored-by: shadcn <m@shadcn.com>
2026-01-05 21:19:49 +04:00
Dhwani Popat
bd29630e4e fix: update Claude Code MCP documentation link (#9272) 2026-01-05 21:03:26 +04:00
shadcn
93ad19e4da chore: refactor shuffle button (#9276)
* chore: refactor shuffle button

* chore: format
2026-01-05 21:00:06 +04:00
dhwani1806
31f8af8409 fix: update theme toggle key detection to exclude Alt key 2026-01-05 18:40:25 +05:30
Philemon Chiro
9317a93152 fix(docs): improve TanStack Form example performance
Change validation strategy from onChange to onBlur to prevent
validation on every keystroke, which causes input lag in textareas.
2026-01-02 13:41:26 +02: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
11110 changed files with 655058 additions and 293306 deletions

View File

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

View File

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

View File

@@ -0,0 +1,41 @@
{
"name": "shadcn",
"displayName": "shadcn/ui",
"version": "1.0.0",
"description": "UI component and design system framework. Search registries, install components as source code, and audit your project.",
"author": {
"name": "shadcn"
},
"homepage": "https://ui.shadcn.com",
"repository": "https://github.com/shadcn-ui/ui",
"license": "MIT",
"logo": "skills/shadcn/assets/shadcn.png",
"keywords": [
"shadcn",
"shadcn-ui",
"ui",
"components",
"tailwind",
"tailwindcss",
"radix",
"react",
"design-system",
"registry",
"mcp"
],
"category": "developer-tools",
"tags": [
"ui",
"components",
"design-system",
"react",
"tailwind"
],
"skills": "./skills/",
"mcpServers": {
"shadcn": {
"command": "npx",
"args": ["shadcn@latest", "mcp"]
}
}
}

View File

@@ -0,0 +1,22 @@
---
description: Keep registry base and radix trees in sync when editing shared UI
globs: apps/v4/registry/bases/**/*
alwaysApply: false
---
# Registry bases: Base UI ↔ Radix parity
`apps/v4/registry/bases/base` and `apps/v4/registry/bases/radix` are **parallel registries**. Anything that exists in both trees for the same purpose (preview blocks, mirrored examples, shared card layouts, etc.) **must stay in sync**.
## When editing
- If you change a file under **`bases/base/...`**, apply the **same behavioral and visual change** to the matching path under **`bases/radix/...`** (and the reverse).
- Only diverge where APIs differ (e.g. import paths like `@/registry/bases/base/ui/*` vs `@/registry/bases/radix/ui/*`, or Base UI vs Radix component props).
- Do **not** update only one side unless the user explicitly asks for a single-base change.
## Typical mirrored paths
- `blocks/preview/**` — preview cards and blocks
- Parallel `ui/*` components when both exist for the same component
After edits, briefly confirm both trees were updated (or state why one side is intentionally unchanged).

View File

@@ -1,12 +1,12 @@
// ORIGINALLY FROM CLOUDFLARE WRANGLER:
// https://github.com/cloudflare/wrangler2/blob/main/.github/changeset-version.js
import { exec } from "child_process"
import { execSync } from "child_process"
// This script is used by the `release.yml` workflow to update the version of the packages being released.
// The standard step is only to run `changeset version` but this does not update the package-lock.json file.
// So we also run `npm install`, which does this update.
// The standard step is only to run `changeset version` but this does not update the pnpm-lock.yaml file.
// So we also run `pnpm install`, which does this update.
// This is a workaround until this is handled automatically by `changeset version`.
// See https://github.com/changesets/changesets/issues/421.
exec("npx changeset version")
exec("npm install")
execSync("npx changeset version", { stdio: "inherit" })
execSync("pnpm install --lockfile-only", { stdio: "inherit" })

View File

@@ -4,3 +4,43 @@ updates:
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directory: "/templates/astro-app"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directory: "/templates/astro-monorepo"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directory: "/templates/next-app"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directory: "/templates/next-monorepo"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directory: "/templates/react-router-app"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directory: "/templates/react-router-monorepo"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directory: "/templates/start-app"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directory: "/templates/start-monorepo"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directory: "/templates/vite-app"
schedule:
interval: "weekly"
- package-ecosystem: "npm"
directory: "/templates/vite-monorepo"
schedule:
interval: "weekly"

View File

@@ -1,21 +0,0 @@
// ORIGINALLY FROM CLOUDFLARE WRANGLER:
// https://github.com/cloudflare/wrangler2/blob/main/.github/version-script.js
import { exec } from "child_process"
import fs from "fs"
const pkgJsonPath = "packages/shadcn/package.json"
try {
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath))
exec("git rev-parse --short HEAD", (err, stdout) => {
if (err) {
console.log(err)
process.exit(1)
}
pkg.version = "0.0.0-beta." + stdout.trim()
fs.writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, "\t") + "\n")
})
} catch (error) {
console.error(error)
process.exit(1)
}

37
.github/version-script-prerelease.js vendored Normal file
View File

@@ -0,0 +1,37 @@
import fs from "fs"
const pkgJsonPath = "packages/shadcn/package.json"
const channel = process.argv[2]
const headSha = process.argv[3]
if (!["beta", "rc"].includes(channel)) {
console.error(
`Expected prerelease channel to be "beta" or "rc", got "${channel}".`
)
process.exit(1)
}
if (!headSha) {
console.error("Expected pull request head SHA.")
process.exit(1)
}
try {
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf8"))
const shortSha = headSha.trim().slice(0, 7)
const baseVersion = channel === "beta" ? "0.0.0" : pkg.version
if (channel === "rc" && baseVersion.includes("-")) {
console.error(
`Expected a stable planned version for rc, got "${baseVersion}".`
)
process.exit(1)
}
pkg.version = `${baseVersion}-${channel}.${shortSha}`
fs.writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, "\t") + "\n")
console.log(`Prepared shadcn@${pkg.version}`)
} catch (error) {
console.error(error)
process.exit(1)
}

View File

@@ -22,7 +22,7 @@ jobs:
name: Install pnpm
id: pnpm-install
with:
version: 9.0.6
version: 10.33.4
run_install: false
- name: Get pnpm store directory
@@ -58,7 +58,7 @@ jobs:
name: Install pnpm
id: pnpm-install
with:
version: 9.0.6
version: 10.33.4
run_install: false
- name: Get pnpm store directory
@@ -77,6 +77,9 @@ jobs:
- name: Install dependencies
run: pnpm install
- name: Build packages
run: pnpm --filter=shadcn build
- run: pnpm format:check
tsc:
@@ -96,7 +99,7 @@ jobs:
name: Install pnpm
id: pnpm-install
with:
version: 9.0.6
version: 10.33.4
run_install: false
- name: Get pnpm store directory

View File

@@ -1,9 +1,9 @@
# Adapted from create-t3-app.
name: Write Beta Release comment
name: Write Prerelease comment
on:
workflow_run:
workflows: ["Release - Beta"]
workflows: ["Release"]
types:
- completed
@@ -11,12 +11,13 @@ jobs:
comment:
if: |
github.repository_owner == 'shadcn-ui' &&
${{ github.event.workflow_run.conclusion == 'success' }}
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
name: Write comment to the PR
steps:
- name: "Comment on PR"
uses: actions/github-script@v6
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
@@ -31,9 +32,13 @@ jobs:
const match = /^npm-package-shadcn@(.*?)-pr-(\d+)/.exec(artifact.name);
if (match) {
const version = match[1];
const channel = version.includes("-rc.") ? "rc" : "beta";
require("fs").appendFileSync(
process.env.GITHUB_ENV,
`\nBETA_PACKAGE_VERSION=${match[1]}` +
`\nPRERELEASE_PACKAGE_VERSION=${version}` +
`\nPRERELEASE_CHANNEL=${channel}` +
`\nPRERELEASE_LABEL=release: ${channel}` +
`\nWORKFLOW_RUN_PR=${match[2]}` +
`\nWORKFLOW_RUN_ID=${context.payload.workflow_run.id}`
);
@@ -46,20 +51,30 @@ jobs:
with:
number: ${{ env.WORKFLOW_RUN_PR }}
message: |
A new prerelease is available for testing:
A new ${{ env.PRERELEASE_CHANNEL }} prerelease is available for testing:
```sh
pnpm dlx shadcn@${{ env.BETA_PACKAGE_VERSION }}
pnpm dlx shadcn@${{ env.PRERELEASE_PACKAGE_VERSION }}
```
- name: "Remove the autorelease label once published"
uses: actions/github-script@v6
View on npm: https://www.npmjs.com/package/shadcn/v/${{ env.PRERELEASE_PACKAGE_VERSION }}
- name: "Remove the prerelease label once published"
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: '${{ env.WORKFLOW_RUN_PR }}',
name: '🚀 autorelease',
});
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: '${{ env.WORKFLOW_RUN_PR }}',
name: '${{ env.PRERELEASE_LABEL }}',
});
} catch (error) {
if (error.status !== 404) {
throw error;
}
core.info("The prerelease label was already removed.");
}

View File

@@ -1,60 +0,0 @@
# Adapted from create-t3-app.
name: Release - Beta
on:
pull_request:
types: [labeled]
branches:
- main
jobs:
prerelease:
if: |
github.repository_owner == 'shadcn-ui' &&
contains(github.event.pull_request.labels.*.name, '🚀 autorelease')
name: Build & Publish a beta release to NPM
runs-on: ubuntu-latest
environment: Preview
steps:
- name: Checkout Repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Use PNPM
uses: pnpm/action-setup@v4
with:
version: 9.0.6
- name: Use Node.js 18
uses: actions/setup-node@v3
with:
node-version: 18
cache: "pnpm"
- 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
- name: get-npm-version
id: package-version
uses: martinbeentjes/npm-get-version-action@main
with:
path: packages/shadcn
- name: Upload packaged artifact
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

@@ -2,34 +2,152 @@
name: Release
run-name: ${{ github.event_name == 'pull_request' && format('Release Prerelease - PR {0}', github.event.number) || 'Release Stable' }}
on:
pull_request:
types: [labeled]
branches:
- main
push:
branches:
- main
jobs:
release:
if: ${{ github.repository_owner == 'shadcn-ui' }}
name: Create a PR for release workflow
prerelease:
if: "${{ github.event_name == 'pull_request' && github.repository_owner == 'shadcn-ui' && (contains(github.event.pull_request.labels.*.name, 'release: beta') || contains(github.event.pull_request.labels.*.name, 'release: rc')) }}"
name: Publish Prerelease to NPM
runs-on: ubuntu-latest
environment: Preview
permissions:
id-token: write
contents: read
steps:
- name: Select prerelease channel
id: prerelease
uses: actions/github-script@v7
with:
script: |
const prereleaseLabels = [
{ name: "release: beta", channel: "beta" },
{ name: "release: rc", channel: "rc" },
];
const labels = context.payload.pull_request.labels.map((label) => label.name);
const selectedLabels = prereleaseLabels.filter((label) =>
labels.includes(label.name)
);
if (selectedLabels.length !== 1) {
throw new Error(
`Expected exactly one prerelease label, found: ${
selectedLabels.map((label) => label.name).join(", ") || "none"
}.`
);
}
const selected = selectedLabels[0];
const pullRequest = context.payload.pull_request;
if (
selected.channel === "rc" &&
(pullRequest.head.ref !== "changeset-release/main" ||
pullRequest.title !== "chore(release): version packages")
) {
throw new Error(
"The release: rc label can only be used on the Changesets version PR from changeset-release/main."
);
}
core.setOutput("channel", selected.channel);
core.setOutput("label", selected.name);
- name: Checkout Repo
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Use PNPM
uses: pnpm/action-setup@v4
with:
version: 10.33.4
- name: Use Node.js 20
uses: actions/setup-node@v4
with:
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-prerelease.js ${{ steps.prerelease.outputs.channel }} ${{ github.event.pull_request.head.sha }}
- name: get-npm-version
id: package-version
uses: martinbeentjes/npm-get-version-action@main
with:
path: packages/shadcn
- name: Check package version on NPM
id: package-exists
run: |
if npm view "shadcn@${{ steps.package-version.outputs.current-version }}" version >/dev/null 2>&1; then
echo "exists=true" >> "$GITHUB_OUTPUT"
else
echo "exists=false" >> "$GITHUB_OUTPUT"
fi
- name: Publish Prerelease to NPM
if: ${{ steps.package-exists.outputs.exists == 'false' }}
run: pnpm pub:${{ steps.prerelease.outputs.channel }}
- name: Build packaged artifact
if: ${{ steps.package-exists.outputs.exists == 'true' }}
run: pnpm shadcn:build
- name: Upload packaged artifact
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
release:
if: ${{ github.event_name == 'push' && github.repository_owner == 'shadcn-ui' }}
name: Create Version PR or Publish Stable Release
runs-on: ubuntu-latest
permissions:
id-token: write
contents: write
pull-requests: write
steps:
- name: Checkout Repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Use PNPM
uses: pnpm/action-setup@v4
with:
version: 9.0.6
version: 10.33.4
- 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
@@ -39,15 +157,23 @@ jobs:
- name: Build the package
run: pnpm shadcn:build
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.RELEASE_GPG_PRIVATE_KEY }}
git_user_signingkey: true
git_commit_gpgsign: true
git_tag_gpgsign: true
- name: Create Version PR or Publish to NPM
id: changesets
uses: changesets/action@v1
with:
setupGitUser: false
commit: "chore(release): version packages"
title: "chore(release): version packages"
version: node .github/changeset-version.js
publish: npx changeset publish
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }}
NODE_ENV: "production"

75
.github/workflows/signed-commits.yml vendored Normal file
View File

@@ -0,0 +1,75 @@
name: Signed commits
on:
pull_request_target:
types:
- opened
- reopened
- synchronize
- ready_for_review
permissions:
pull-requests: write
jobs:
signed-commits:
if: github.repository_owner == 'shadcn-ui'
runs-on: ubuntu-latest
name: Signed commits
steps:
- name: Check PR commits
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const body = "Can you sign the commits please? See https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits. Thank you."
const { owner, repo } = context.repo
const pullNumber = context.payload.pull_request.number
const commits = await github.paginate(github.rest.pulls.listCommits, {
owner,
repo,
pull_number: pullNumber,
per_page: 100,
})
const unsignedCommits = commits.filter((commit) => {
return commit.commit.verification?.reason === "unsigned"
})
const comments = await github.paginate(github.rest.issues.listComments, {
owner,
repo,
issue_number: pullNumber,
per_page: 100,
})
const existingComments = comments.filter((comment) => {
return comment.user.type === "Bot" && comment.body.trim() === body
})
if (unsignedCommits.length > 0) {
core.info(`Found ${unsignedCommits.length} unsigned commits.`)
if (existingComments.length === 0) {
await github.rest.issues.createComment({
owner,
repo,
issue_number: pullNumber,
body,
})
}
return
}
core.info("All commits are signed.")
for (const comment of existingComments) {
await github.rest.issues.deleteComment({
owner,
repo,
comment_id: comment.id,
})
}

314
.github/workflows/templates.yml vendored Normal file
View File

@@ -0,0 +1,314 @@
name: Templates
on:
pull_request:
branches: ["*"]
paths:
- ".github/workflows/templates.yml"
- "apps/v4/registry/**"
- "package.json"
- "packages/shadcn/src/commands/add.ts"
- "packages/shadcn/src/commands/init.ts"
- "packages/shadcn/src/templates/**"
- "packages/shadcn/src/utils/create-project.ts"
- "packages/shadcn/src/utils/get-monorepo-info.ts"
- "packages/shadcn/src/utils/get-package-manager.ts"
- "pnpm-lock.yaml"
- "templates/**"
jobs:
validate:
runs-on: ubuntu-latest
name: ${{ matrix.package-manager == 'pnpm' && format('pnpm {0}', matrix.pnpm-version) || matrix.package-manager }} ${{ matrix.template }}
permissions:
contents: read
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
template: [next, vite, astro, start, react-router]
package-manager: [pnpm, bun, npm, yarn]
pnpm-version: [10.33.4, 11]
exclude:
- package-manager: bun
pnpm-version: 11
- package-manager: npm
pnpm-version: 11
- package-manager: yarn
pnpm-version: 11
env:
NEXT_PUBLIC_APP_URL: http://localhost:4000
NEXT_PUBLIC_V0_URL: https://v0.dev
REGISTRY_URL: http://localhost:4000/r
ROOT_PNPM_VERSION: 10.33.4
TEMPLATE_PNPM_VERSION: ${{ matrix.pnpm-version }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 22
- uses: pnpm/action-setup@v4
name: Install pnpm
id: pnpm-install
with:
version: ${{ env.ROOT_PNPM_VERSION }}
run_install: false
- name: Install Bun
uses: oven-sh/setup-bun@v2
- name: Install Yarn
if: matrix.package-manager == 'yarn'
run: |
corepack enable
COREPACK_ENABLE_PROJECT_SPEC=0 corepack prepare yarn@4.12.0 --activate
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "pnpm_cache_dir=$(pnpm store path)" >> "$GITHUB_OUTPUT"
- uses: actions/cache@v4
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 --filter=shadcn build
pnpm --filter=v4 registry:build
- name: Validate templates
env:
TEMPLATE: ${{ matrix.template }}
TEMPLATE_PACKAGE_MANAGER: ${{ matrix.package-manager }}
SHADCN_TEMPLATE_DIR: ${{ github.workspace }}/templates
run: |
set -euo pipefail
root_pnpm="$(command -v pnpm)"
validation_script="$RUNNER_TEMP/validate-templates.sh"
cat > "$validation_script" <<'BASH'
set -euo pipefail
bin_dir="$RUNNER_TEMP/template-pnpm-bin"
mkdir -p "$bin_dir"
cat > "$bin_dir/pnpm" <<'PNPM'
#!/usr/bin/env bash
exec npx -y "pnpm@${TEMPLATE_PNPM_VERSION}" "$@"
PNPM
chmod +x "$bin_dir/pnpm"
export PATH="$bin_dir:$PATH"
echo "Using template pnpm $(pnpm --version)"
cli="$GITHUB_WORKSPACE/packages/shadcn/dist/index.js"
template_root="$RUNNER_TEMP/generated-template-${TEMPLATE_PACKAGE_MANAGER}-${TEMPLATE}"
rm -rf "$template_root"
mkdir -p "$template_root"
modes=(app monorepo)
has_script() {
node -e "const pkg = require('./package.json'); process.exit(pkg.scripts && pkg.scripts[process.argv[1]] ? 0 : 1)" "$1"
}
run_script_if_present() {
local script="$1"
if has_script "$script"; then
pnpm run "$script"
else
echo "No $script script found; skipping."
fi
}
validate_non_pnpm_project() {
local package_manager="$1"
local project_path="$2"
local check_workspace_protocol="$3"
local is_monorepo="$4"
cd "$project_path"
test ! -f pnpm-workspace.yaml
test ! -f pnpm-lock.yaml
EXPECTED_PACKAGE_MANAGER="$package_manager" \
CHECK_WORKSPACE_PROTOCOL="$check_workspace_protocol" \
IS_MONOREPO="$is_monorepo" \
node <<'NODE'
const fs = require("node:fs")
const path = require("node:path")
const expectedPackageManager = process.env.EXPECTED_PACKAGE_MANAGER
const checkWorkspaceProtocol =
process.env.CHECK_WORKSPACE_PROTOCOL === "true"
const isMonorepo = process.env.IS_MONOREPO === "true"
const pkg = JSON.parse(fs.readFileSync("package.json", "utf8"))
if (isMonorepo) {
const workspaces = pkg.workspaces ?? []
if (!Array.isArray(workspaces)) {
throw new Error("Expected package.json workspaces to be an array.")
}
if (workspaces.length === 0) {
throw new Error("Expected package.json workspaces to have entries.")
}
for (const workspace of ["sharp", "unrs-resolver", "esbuild"]) {
if (workspaces.includes(workspace)) {
throw new Error(`Unexpected workspace entry: ${workspace}`)
}
}
if (!pkg.packageManager?.startsWith(`${expectedPackageManager}@`)) {
throw new Error(
`Expected packageManager to use ${expectedPackageManager}, got ${pkg.packageManager}`
)
}
} else {
if (pkg.workspaces !== undefined) {
throw new Error("Did not expect package.json workspaces for app template.")
}
if (pkg.packageManager !== undefined) {
throw new Error(
`Did not expect packageManager for app template, got ${pkg.packageManager}`
)
}
}
if (checkWorkspaceProtocol) {
const packageJsonFiles = []
function collectPackageJsonFiles(dir) {
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
if (entry.name === "node_modules") {
continue
}
const fullPath = path.join(dir, entry.name)
if (entry.isDirectory()) {
collectPackageJsonFiles(fullPath)
} else if (entry.name === "package.json") {
packageJsonFiles.push(fullPath)
}
}
}
collectPackageJsonFiles(process.cwd())
for (const file of packageJsonFiles) {
const json = fs.readFileSync(file, "utf8")
if (json.includes("workspace:")) {
throw new Error(`Unexpected workspace: protocol in ${file}`)
}
}
}
NODE
}
for mode in "${modes[@]}"; do
project="test-${TEMPLATE}-${mode}-${TEMPLATE_PACKAGE_MANAGER}"
project_path="$template_root/$project"
echo "::group::${TEMPLATE} ${mode} ${TEMPLATE_PACKAGE_MANAGER}"
args=(
init
--defaults
--name "$project"
--template "$TEMPLATE"
--cwd "$template_root"
--silent
)
if [ "$mode" = "monorepo" ]; then
args+=(--monorepo)
is_monorepo="true"
else
args+=(--no-monorepo)
is_monorepo="false"
fi
case "$TEMPLATE_PACKAGE_MANAGER" in
pnpm)
SHADCN_TEMPLATE_DIR="$SHADCN_TEMPLATE_DIR" \
REGISTRY_URL="$REGISTRY_URL" \
npm_config_user_agent="pnpm/${TEMPLATE_PNPM_VERSION}" \
node "$cli" "${args[@]}"
cd "$project_path"
pnpm install --frozen-lockfile
run_script_if_present typecheck
run_script_if_present build
;;
bun)
(
cd "$template_root"
SHADCN_TEMPLATE_DIR="$SHADCN_TEMPLATE_DIR" \
REGISTRY_URL="$REGISTRY_URL" \
npm_config_user_agent="bun/$(bun --version)" \
bunx --bun --package "$GITHUB_WORKSPACE/packages/shadcn" \
shadcn "${args[@]}"
)
validate_non_pnpm_project \
"bun" \
"$project_path" \
"false" \
"$is_monorepo"
;;
npm)
(
cd "$template_root"
SHADCN_TEMPLATE_DIR="$SHADCN_TEMPLATE_DIR" \
REGISTRY_URL="$REGISTRY_URL" \
npm_config_user_agent="npm/$(npm --version)" \
npx --yes --package "$GITHUB_WORKSPACE/packages/shadcn" \
shadcn "${args[@]}"
)
validate_non_pnpm_project \
"npm" \
"$project_path" \
"true" \
"$is_monorepo"
;;
yarn)
(
cd "$template_root"
SHADCN_TEMPLATE_DIR="$SHADCN_TEMPLATE_DIR" \
REGISTRY_URL="$REGISTRY_URL" \
COREPACK_ENABLE_PROJECT_SPEC=0 \
npm_config_user_agent="yarn/$(COREPACK_ENABLE_PROJECT_SPEC=0 yarn --version)" \
yarn dlx --package "$GITHUB_WORKSPACE/packages/shadcn" \
shadcn "${args[@]}"
)
validate_non_pnpm_project \
"yarn" \
"$project_path" \
"false" \
"$is_monorepo"
;;
esac
echo "::endgroup::"
done
BASH
"$root_pnpm" exec start-server-and-test \
"$root_pnpm v4:dev" \
http://localhost:4000 \
"bash $validation_script"

View File

@@ -19,13 +19,13 @@ jobs:
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 18
node-version: 22
- uses: pnpm/action-setup@v4
name: Install pnpm
id: pnpm-install
with:
version: 9.0.6
version: 10.33.4
run_install: false
- name: Get pnpm store directory
@@ -39,10 +39,10 @@ jobs:
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install Bun
uses: oven-sh/setup-bun@v2
- name: Install dependencies
run: pnpm install
- name: Build packages
run: pnpm build --filter=shadcn
- run: pnpm test

View File

@@ -3,12 +3,12 @@ name: Validate Registries
on:
pull_request:
paths:
- "apps/v4/public/r/registries.json"
- "apps/v4/registry/directory.json"
push:
branches:
- main
paths:
- "apps/v4/public/r/registries.json"
- "apps/v4/registry/directory.json"
jobs:
validate:
@@ -26,11 +26,44 @@ jobs:
with:
node-version: 20
- name: Block reserved registry namespaces
env:
RESERVED_NAMESPACES: "@shadcn,@ui,@blocks,@components,@block,@component,@util,@utils,@registry,@lib,@hook,@hooks,@theme,@themes,@chart,@charts"
run: |
node <<'EOF'
const fs = require("node:fs")
const file = "apps/v4/registry/directory.json"
const reservedNamespaces = new Set(
process.env.RESERVED_NAMESPACES.split(",").filter(Boolean)
)
function readNames() {
return JSON.parse(fs.readFileSync(file, "utf8")).map(
(entry) => entry.name
)
}
const violations = readNames()
.filter((name) => reservedNamespaces.has(name))
.map((name) => `${file}: ${name}`)
if (violations.length > 0) {
console.error("Reserved registry namespaces are not allowed:")
for (const violation of violations) {
console.error(`- ${violation}`)
}
process.exit(1)
}
EOF
- uses: pnpm/action-setup@v4
name: Install pnpm
id: pnpm-install
with:
version: 9.0.6
version: 10.33.4
run_install: false
- name: Get pnpm store directory
@@ -47,8 +80,5 @@ jobs:
- name: Install dependencies
run: pnpm install
- name: Build packages
run: pnpm build --filter=shadcn
- name: Validate registries
run: pnpm --filter=v4 validate:registries

7
.gitignore vendored
View File

@@ -15,6 +15,7 @@ build
# misc
.DS_Store
.eslintcache
*.pem
# debug
@@ -39,3 +40,9 @@ tsconfig.tsbuildinfo
.idea
.fleet
.vscode
.notes
.playwright-mcp
.playwright-cli
shadcn-workspace
.codex-artifacts

View File

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

10
.vscode/settings.json vendored
View File

@@ -8,5 +8,13 @@
"<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,32 +79,26 @@ 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 registry (main site) to make sure the components are up to date:
1. Start by running the dev server:
```bash
pnpm v4:dev
pnpm dev
```
2. Run the development script for the CLI:
```bash
pnpm shadcn:dev
```
3. In another terminal tab, test the CLI by running:
2. In another terminal tab, test the CLI by running:
```bash
pnpm shadcn
@@ -119,36 +110,27 @@ To run the CLI locally, you can follow the workflow:
pnpm shadcn <init | add | ...> -c ~/Desktop/my-app
```
4. To run the tests for the CLI:
```bash
pnpm --filter=shadcn test
```
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
```
@@ -157,7 +139,12 @@ 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.
See [`apps/v4/registry/README.md`](apps/v4/registry/README.md) for how the
registry pipeline is structured and for the faster targeted build modes
(`--style`, `--registry`, `--examples`, `--indexes`) you can use while
iterating locally. Always run the full `pnpm registry:build` before committing.
## Commit Convention
@@ -196,9 +183,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,12 +1,12 @@
# 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
Visit http://ui.shadcn.com/docs to view the documentation.
Visit https://ui.shadcn.com/docs to view the documentation.
## Contributing
@@ -14,4 +14,4 @@ Please read the [contributing guide](/CONTRIBUTING.md).
## License
Licensed under the [MIT license](https://github.com/shadcn/ui/blob/main/LICENSE.md).
Licensed under the [MIT license](./LICENSE.md).

View File

@@ -6,4 +6,4 @@ We will investigate all legitimate reports and do our best to quickly fix the pr
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" button.
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.

View File

@@ -5,3 +5,4 @@ build
.contentlayer
registry/__index__.tsx
content/docs/components/calendar.mdx
registry/styles/**/*.css

View File

@@ -0,0 +1,94 @@
import {
AlertCircleIcon,
ArrowRight01Icon,
SquareLock02Icon,
} from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import { Button } from "@/styles/base-rhea/ui/button"
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import { Field, FieldGroup, FieldLabel } from "@/styles/base-rhea/ui/field"
import { Input } from "@/styles/base-rhea/ui/input"
import {
Item,
ItemContent,
ItemDescription,
ItemMedia,
ItemTitle,
} from "@/styles/base-rhea/ui/item"
export function AccountAccess() {
return (
<Card>
<CardHeader>
<CardTitle>Account Access</CardTitle>
<CardDescription>
Update your credentials or re-authenticate.
</CardDescription>
</CardHeader>
<CardContent>
<FieldGroup>
<Field>
<FieldLabel htmlFor="email-address">Email Address</FieldLabel>
<Input
id="email-address"
type="email"
placeholder="artist@studio.inc"
/>
</Field>
<Field>
<div className="flex items-center justify-between">
<FieldLabel htmlFor="current-password">
Current Password
</FieldLabel>
<a
href="#"
className="text-xs font-medium tracking-wider text-muted-foreground uppercase hover:text-foreground"
>
Forgot?
</a>
</div>
<Input
id="current-password"
type="password"
placeholder="••••••••••••••••••••••••"
/>
</Field>
</FieldGroup>
</CardContent>
<CardFooter className="flex-col gap-4">
<Button className="w-full">
<HugeiconsIcon icon={SquareLock02Icon} strokeWidth={2} />
Update Security
</Button>
<Item variant="muted" render={<a href="#" />}>
<ItemMedia variant="icon">
<HugeiconsIcon
icon={AlertCircleIcon}
className="text-destructive"
strokeWidth={2}
/>
</ItemMedia>
<ItemContent>
<ItemTitle>Danger Zone</ItemTitle>
<ItemDescription className="line-clamp-1">
Archive account and remove catalog
</ItemDescription>
</ItemContent>
<HugeiconsIcon
icon={ArrowRight01Icon}
className="size-4"
strokeWidth={2}
/>
</Item>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,46 @@
import { Badge } from "@/styles/base-rhea/ui/badge"
import { Button } from "@/styles/base-rhea/ui/button"
import {
Card,
CardAction,
CardDescription,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
const areaPath = "M0 52L18 40L36 46L54 70L72 50L100 49V86H0Z"
const strokePath = "M0 52L18 40L36 46L54 70L72 50L100 49"
export function AnalyticsCard() {
return (
<Card className="mx-auto w-full max-w-sm data-[size=sm]:pb-0" size="sm">
<CardHeader>
<CardTitle>Analytics</CardTitle>
<CardDescription>
418.2K Visitors <Badge>+10%</Badge>
</CardDescription>
<CardAction>
<Button variant="outline" size="sm">
View Analytics
</Button>
</CardAction>
</CardHeader>
<svg
viewBox="0 0 100 86"
preserveAspectRatio="none"
className="aspect-[1/0.35] w-full text-chart-1"
role="img"
aria-label="Visitor trend"
>
<path d={areaPath} fill="currentColor" opacity="0.28" />
<path
d={strokePath}
fill="none"
stroke="currentColor"
strokeWidth="1.5"
vectorEffect="non-scaling-stroke"
/>
</svg>
</Card>
)
}

View File

@@ -0,0 +1,75 @@
import { Badge } from "@/styles/base-rhea/ui/badge"
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import { Item, ItemContent } from "@/styles/base-rhea/ui/item"
import { Separator } from "@/styles/base-rhea/ui/separator"
const netRoyalties = 1248.75
const processingFee = 37.46
const totalClaimable = netRoyalties - processingFee
const formatCurrency = (amount: number) =>
amount.toLocaleString("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})
export function ClaimableBalance() {
return (
<Card>
<CardHeader>
<CardDescription>Claimable Balance</CardDescription>
<CardTitle className="text-4xl tabular-nums">
${formatCurrency(totalClaimable)}
</CardTitle>
<Badge variant="outline">
<span className="size-2 rounded-full bg-yellow-500" />
Pending Setup
</Badge>
</CardHeader>
<CardContent className="flex flex-1 flex-col justify-end">
<Item variant="muted" className="flex-col items-stretch">
<ItemContent className="gap-3">
<div className="flex items-center justify-between">
<span className="text-sm text-muted-foreground">
Net Royalties
</span>
<span className="text-sm font-medium tabular-nums">
${formatCurrency(netRoyalties)}
</span>
</div>
<div className="flex items-center justify-between">
<span className="text-sm text-muted-foreground">
Processing Fee
</span>
<span className="text-sm font-medium tabular-nums">
-${formatCurrency(processingFee)}
</span>
</div>
<Separator />
<div className="flex items-center justify-between">
<span className="text-sm text-muted-foreground">
Total Ready to Claim
</span>
<span className="text-sm font-semibold tabular-nums">
${formatCurrency(totalClaimable)} USD
</span>
</div>
</ItemContent>
</Item>
</CardContent>
<CardFooter>
<CardDescription>
Once your bank is connected, balances over $10.00 are automatically
eligible for monthly distribution on the 15th of each month.
</CardDescription>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,88 @@
import { Badge } from "@/styles/base-rhea/ui/badge"
import { Button } from "@/styles/base-rhea/ui/button"
import {
Card,
CardAction,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import { Item, ItemContent, ItemDescription } from "@/styles/base-rhea/ui/item"
const chartData = [
{ month: "Dec", amount: 800 },
{ month: "Jan", amount: 1100 },
{ month: "Feb", amount: 900 },
{ month: "Mar", amount: 1300 },
{ month: "Apr", amount: 750 },
{ month: "May", amount: 1400 },
]
export function ContributionHistory() {
const maxAmount = Math.max(...chartData.map((item) => item.amount))
return (
<Card>
<CardHeader>
<CardTitle>Contribution History</CardTitle>
<CardDescription>Last 6 months of activity</CardDescription>
</CardHeader>
<CardContent>
<div
className="flex h-[200px] w-full items-end gap-3"
role="img"
aria-label="Last 6 months of contribution activity"
>
{chartData.map((item) => (
<div
key={item.month}
className="flex h-full flex-1 flex-col justify-end gap-2"
>
<div
className="min-h-2 rounded-t-md bg-chart-2"
style={{ height: `${(item.amount / maxAmount) * 100}%` }}
/>
<span className="text-center text-xs text-muted-foreground">
{item.month}
</span>
</div>
))}
</div>
</CardContent>
<CardContent>
<div className="grid w-full grid-cols-1 gap-3 xl:grid-cols-2">
<Item variant="muted" className="flex-col items-stretch">
<ItemContent className="gap-1">
<ItemDescription className="text-xs font-medium tracking-wider text-muted-foreground uppercase">
Upcoming
</ItemDescription>
<span className="cn-font-heading text-base font-semibold">
May 2024
</span>
<span className="text-sm text-muted-foreground">Scheduled</span>
</ItemContent>
</Item>
<Item
variant="muted"
className="hidden flex-col items-stretch xl:flex"
>
<ItemContent className="gap-1">
<ItemDescription className="text-xs font-medium tracking-wider text-muted-foreground uppercase">
Savings Plan
</ItemDescription>
<span className="cn-font-heading text-base font-semibold">
Accelerated
</span>
<span className="text-sm text-muted-foreground">Recurring</span>
</ItemContent>
</Item>
</div>
</CardContent>
<CardFooter>
<Button className="w-full">View Full Report</Button>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,116 @@
import { Cancel01Icon } from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import { Button } from "@/styles/base-rhea/ui/button"
import {
Card,
CardAction,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import {
Item,
ItemContent,
ItemDescription,
ItemGroup,
ItemTitle,
} from "@/styles/base-rhea/ui/item"
const HOLDINGS = [
{
name: "Vanguard",
shares: "450 Shares",
amount: "$1,842.10",
data: [
{ q: "Q1", value: 380 },
{ q: "Q2", value: 420 },
{ q: "Q3", value: 390 },
{ q: "Q4", value: 652 },
],
},
{
name: "S&P 500 VOO",
shares: "112 Shares",
amount: "$928.40",
data: [
{ q: "Q1", value: 180 },
{ q: "Q2", value: 210 },
{ q: "Q3", value: 320 },
{ q: "Q4", value: 218 },
],
},
{
name: "Apple AAPL",
shares: "85 Shares",
amount: "$340.00",
data: [
{ q: "Q1", value: 60 },
{ q: "Q2", value: 70 },
{ q: "Q3", value: 120 },
{ q: "Q4", value: 90 },
],
},
{
name: "Realty Income",
shares: "320 Shares",
amount: "$1,139.50",
data: [
{ q: "Q1", value: 240 },
{ q: "Q2", value: 260 },
{ q: "Q3", value: 280 },
{ q: "Q4", value: 360 },
],
},
]
export function DividendIncome() {
return (
<Card>
<CardHeader>
<CardTitle>Q2 Dividend Income</CardTitle>
<CardDescription>
Quarterly dividend payouts across your portfolio holdings.
</CardDescription>
<CardAction>
<Button
variant="ghost"
size="icon-sm"
className="bg-muted"
aria-label="Dismiss dividend income"
>
<HugeiconsIcon icon={Cancel01Icon} strokeWidth={2} />
</Button>
</CardAction>
</CardHeader>
<CardContent>
<ItemGroup>
{HOLDINGS.map((holding) => (
<Item key={holding.name} role="listitem" variant="muted">
<ItemContent>
<ItemTitle>{holding.name}</ItemTitle>
<ItemDescription>{holding.shares}</ItemDescription>
</ItemContent>
<div
className="hidden h-8 w-24 items-end gap-1 md:flex"
role="img"
aria-label={`${holding.name} quarterly dividends`}
>
{holding.data.map((item) => (
<div
key={item.q}
className="min-h-1 flex-1 rounded-t-sm bg-chart-2"
style={{
height: `${(item.value / Math.max(...holding.data.map((point) => point.value))) * 100}%`,
}}
/>
))}
</div>
</Item>
))}
</ItemGroup>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,37 @@
import { Add01Icon } from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import { Button } from "@/styles/base-rhea/ui/button"
import { Card, CardContent } from "@/styles/base-rhea/ui/card"
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle,
} from "@/styles/base-rhea/ui/empty"
export function EmptyDistributeTrack() {
return (
<Card>
<CardContent>
<Empty className="p-4">
<EmptyMedia variant="icon">
<HugeiconsIcon icon={Add01Icon} strokeWidth={2} />
</EmptyMedia>
<EmptyHeader>
<EmptyTitle>Distribute Track</EmptyTitle>
<EmptyDescription>
Upload your first master to start reaching listeners on Spotify,
Apple Music, and more.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<Button>Create Release</Button>
</EmptyContent>
</Empty>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,117 @@
import { AccountAccess } from "./account-access"
import { AnalyticsCard } from "./analytics-card"
import { ClaimableBalance } from "./claimable-balance"
import { ContributionHistory } from "./contribution-history"
import { DividendIncome } from "./dividend-income"
import { EmptyDistributeTrack } from "./empty-distribute-track"
import { NewMilestone } from "./new-milestone"
import { NotificationSettings } from "./notification-settings"
import { Payments } from "./payments"
import { PayoutThreshold } from "./payout-threshold"
import { PowerUsage } from "./power-usage"
import { QrConnect } from "./qr-connect"
import { SavingsTargets } from "./savings-targets"
import { SidebarNav } from "./sidebar-nav"
import { AccountAccess as SkeletonAccountAccess } from "./skeleton/account-access"
import { AnalyticsCard as SkeletonAnalyticsCard } from "./skeleton/analytics-card"
import { ClaimableBalance as SkeletonClaimableBalance } from "./skeleton/claimable-balance"
import { ContributionHistory as SkeletonContributionHistory } from "./skeleton/contribution-history"
import { DividendIncome as SkeletonDividendIncome } from "./skeleton/dividend-income"
import { EmptyDistributeTrack as SkeletonEmptyDistributeTrack } from "./skeleton/empty-distribute-track"
import { NewMilestone as SkeletonNewMilestone } from "./skeleton/new-milestone"
import { NotificationSettings as SkeletonNotificationSettings } from "./skeleton/notification-settings"
import { Payments as SkeletonPayments } from "./skeleton/payments"
import { PayoutThreshold as SkeletonPayoutThreshold } from "./skeleton/payout-threshold"
import { PowerUsage as SkeletonPowerUsage } from "./skeleton/power-usage"
import { QrConnect as SkeletonQrConnect } from "./skeleton/qr-connect"
import { SavingsTargets as SkeletonSavingsTargets } from "./skeleton/savings-targets"
import { TransferFunds as SkeletonTransferFunds } from "./skeleton/transfer-funds"
import { UIElements as SkeletonUIElements } from "./skeleton/ui-elements"
import { TransferFunds } from "./transfer-funds"
import { UIElements } from "./ui-elements"
function CardsSkeletonRails() {
return (
<div
aria-hidden="true"
className="pointer-events-none absolute inset-x-0 top-12 z-10 hidden min-[2200px]:block [&_[data-slot=skeleton]:nth-child(even)]:hidden"
>
<div className="absolute top-0 left-[calc(50%-950px-var(--rail-width)-var(--gap))] grid w-(--rail-width) grid-cols-[repeat(2,var(--rail-column))] gap-(--gap) opacity-50 [--rail-column:20rem] [--rail-width:calc(var(--rail-column)*2+var(--gap))]">
<div className="flex flex-col gap-(--gap)">
<SkeletonContributionHistory />
<SkeletonClaimableBalance />
<SkeletonDividendIncome />
<SkeletonPayoutThreshold />
</div>
<div className="flex flex-col gap-(--gap)">
<SkeletonUIElements />
<SkeletonSavingsTargets />
<SkeletonNewMilestone />
<SkeletonPayoutThreshold />
<SkeletonAccountAccess />
</div>
</div>
<div className="absolute top-0 right-[calc(50%-950px-var(--rail-width)-var(--gap))] grid w-(--rail-width) grid-cols-[repeat(2,var(--rail-column))] gap-(--gap) opacity-50 [--rail-column:20rem] [--rail-width:calc(var(--rail-column)*2+var(--gap))]">
<div className="flex flex-col gap-(--gap)">
<SkeletonNewMilestone />
<SkeletonPayoutThreshold />
<SkeletonAccountAccess />
<SkeletonQrConnect />
<SkeletonTransferFunds />
<SkeletonPayments />
<SkeletonEmptyDistributeTrack />
</div>
<div className="flex flex-col gap-(--gap)">
<SkeletonQrConnect />
<SkeletonTransferFunds />
<SkeletonPayments />
<SkeletonEmptyDistributeTrack />
<SkeletonAnalyticsCard />
<SkeletonNotificationSettings />
<SkeletonPowerUsage />
</div>
</div>
</div>
)
}
export function CardsDemo() {
return (
<div
data-slot="demo"
className="theme-neutral relative flex w-full max-w-none flex-col gap-(--gap) overflow-hidden bg-muted p-12 pb-0! [--gap:--spacing(8)] 3xl:[--gap:--spacing(8)] min-[1900px]:p-12 min-[1900px]:[--gap:--spacing(10)]! lg:p-6 lg:[--gap:--spacing(6)] dark:bg-background"
>
<CardsSkeletonRails />
<div className="relative z-10 mx-auto grid gap-(--gap) **:data-[slot=card]:w-full min-[1400px]:grid-cols-4! min-[1900px]:grid-cols-5! md:max-w-3xl md:grid-cols-2 lg:max-w-none lg:grid-cols-3 xl:max-w-[1600px] 2xl:max-w-[1900px]">
<div className="flex flex-col items-start gap-(--gap)">
<UIElements />
<SidebarNav />
<SavingsTargets />
</div>
<div className="hidden flex-col gap-(--gap) lg:flex">
<ContributionHistory />
<ClaimableBalance />
<DividendIncome />
</div>
<div className="hidden flex-col gap-(--gap) 3xl:flex!">
<NewMilestone />
<PayoutThreshold />
<AccountAccess />
</div>
<div className="hidden flex-col gap-(--gap) md:flex">
<QrConnect />
<TransferFunds />
<Payments />
</div>
<div className="hidden flex-col gap-(--gap) min-[1400px]:flex">
<EmptyDistributeTrack />
<AnalyticsCard />
<NotificationSettings />
<PowerUsage />
</div>
</div>
<div className="absolute inset-x-0 top-0 z-1 h-120 bg-linear-to-b from-background via-muted to-transparent dark:hidden" />
<div className="absolute inset-x-0 bottom-0 z-20 h-48 bg-linear-to-t from-background via-muted/80 to-transparent lg:h-80 xl:h-64 dark:via-background/80" />
</div>
)
}

View File

@@ -0,0 +1,52 @@
import { Button } from "@/styles/base-rhea/ui/button"
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import { Field, FieldGroup, FieldLabel } from "@/styles/base-rhea/ui/field"
import { Input } from "@/styles/base-rhea/ui/input"
export function NewMilestone() {
return (
<Card>
<CardHeader>
<CardTitle>Set a new milestone</CardTitle>
<CardDescription>
Define your financial target and we&apos;ll help you pace your
savings.
</CardDescription>
</CardHeader>
<CardContent>
<FieldGroup>
<Field>
<FieldLabel htmlFor="goal-name">Goal Name</FieldLabel>
<Input
id="goal-name"
placeholder="e.g. New Car, Home Downpayment"
/>
</Field>
<div className="grid grid-cols-2 gap-3">
<Field>
<FieldLabel htmlFor="target-amount">Target Amount</FieldLabel>
<Input id="target-amount" defaultValue="$15,000" />
</Field>
<Field>
<FieldLabel htmlFor="target-date">Target Date</FieldLabel>
<Input id="target-date" defaultValue="Dec 2025" />
</Field>
</div>
</FieldGroup>
</CardContent>
<CardFooter className="flex-col gap-2">
<Button className="w-full">Create Goal</Button>
<Button variant="outline" className="w-full">
Cancel
</Button>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,76 @@
import { Button } from "@/styles/base-rhea/ui/button"
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import { Checkbox } from "@/styles/base-rhea/ui/checkbox"
import {
Field,
FieldContent,
FieldDescription,
FieldGroup,
FieldLabel,
} from "@/styles/base-rhea/ui/field"
const NOTIFICATIONS = [
{
id: "transactions",
label: "Transaction alerts",
description: "Deposits, withdrawals, and transfers.",
defaultChecked: true,
},
{
id: "security",
label: "Security alerts",
description: "Login attempts and account changes.",
defaultChecked: true,
},
{
id: "goals",
label: "Goal milestones",
description: "Updates at 25%, 50%, 75%, and 100%.",
defaultChecked: false,
},
{
id: "market",
label: "Market updates",
description: "Daily portfolio summary and price alerts.",
defaultChecked: false,
},
]
export function NotificationSettings() {
return (
<Card>
<CardHeader>
<CardTitle>Notifications</CardTitle>
<CardDescription>
Choose which email and push alerts you want to receive.
</CardDescription>
</CardHeader>
<CardContent>
<FieldGroup>
{NOTIFICATIONS.map((n) => (
<Field key={n.id} orientation="horizontal">
<Checkbox
id={`notify-${n.id}`}
defaultChecked={n.defaultChecked}
/>
<FieldContent>
<FieldLabel htmlFor={`notify-${n.id}`}>{n.label}</FieldLabel>
<FieldDescription>{n.description}</FieldDescription>
</FieldContent>
</Field>
))}
</FieldGroup>
</CardContent>
<CardFooter>
<Button className="w-full">Save Preferences</Button>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,139 @@
import {
ArrowRight01Icon,
Calendar03Icon,
MoreHorizontalCircle01Icon,
RefreshIcon,
Settings01Icon,
} from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/styles/base-rhea/ui/breadcrumb"
import { Button } from "@/styles/base-rhea/ui/button"
import { Card, CardContent, CardHeader } from "@/styles/base-rhea/ui/card"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/styles/base-rhea/ui/dropdown-menu"
import {
Item,
ItemContent,
ItemDescription,
ItemGroup,
ItemMedia,
ItemTitle,
} from "@/styles/base-rhea/ui/item"
export function Payments() {
return (
<Card>
<CardHeader className="flex flex-col gap-3">
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="#">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<DropdownMenu>
<DropdownMenuTrigger
render={
<Button
size="icon-sm"
variant="ghost"
aria-label="Account options"
/>
}
>
<HugeiconsIcon
icon={MoreHorizontalCircle01Icon}
strokeWidth={2}
/>
<span className="sr-only">Account options</span>
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<DropdownMenuGroup>
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Statements</DropdownMenuItem>
<DropdownMenuItem>Documents</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>Payments</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</CardHeader>
<CardContent>
<ItemGroup>
<div role="listitem" className="w-full">
<Item variant="muted" render={<a href="#" />}>
<ItemMedia variant="icon">
<HugeiconsIcon icon={Settings01Icon} strokeWidth={2} />
</ItemMedia>
<ItemContent>
<ItemTitle>Change transfer limit</ItemTitle>
<ItemDescription>
Adjust how much you can send from your balance.
</ItemDescription>
</ItemContent>
<HugeiconsIcon
icon={ArrowRight01Icon}
className="size-4 shrink-0 text-muted-foreground"
strokeWidth={2}
/>
</Item>
</div>
<div role="listitem" className="w-full">
<Item variant="muted" render={<a href="#" />}>
<ItemMedia variant="icon">
<HugeiconsIcon icon={Calendar03Icon} strokeWidth={2} />
</ItemMedia>
<ItemContent>
<ItemTitle>Scheduled transfers</ItemTitle>
<ItemDescription>
Set up a transfer to send at a later date.
</ItemDescription>
</ItemContent>
<HugeiconsIcon
icon={ArrowRight01Icon}
className="size-4 shrink-0 text-muted-foreground"
strokeWidth={2}
/>
</Item>
</div>
<div role="listitem" className="w-full">
<Item variant="muted" render={<a href="#" />}>
<ItemMedia variant="icon">
<HugeiconsIcon icon={RefreshIcon} strokeWidth={2} />
</ItemMedia>
<ItemContent>
<ItemTitle>Recurring card payments</ItemTitle>
<ItemDescription>
Manage your repeated card transactions.
</ItemDescription>
</ItemContent>
<HugeiconsIcon
icon={ArrowRight01Icon}
className="size-4 shrink-0 text-muted-foreground"
strokeWidth={2}
/>
</Item>
</div>
</ItemGroup>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,112 @@
import { Cancel01Icon } from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import { Button } from "@/styles/base-rhea/ui/button"
import {
Card,
CardAction,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import {
Field,
FieldDescription,
FieldGroup,
FieldLabel,
} from "@/styles/base-rhea/ui/field"
import { Progress } from "@/styles/base-rhea/ui/progress"
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/styles/base-rhea/ui/select"
import { Textarea } from "@/styles/base-rhea/ui/textarea"
const CURRENCIES = [
{ label: "USD — United States Dollar", value: "usd" },
{ label: "EUR — Euro", value: "eur" },
{ label: "GBP — British Pound", value: "gbp" },
{ label: "JPY — Japanese Yen", value: "jpy" },
]
export function PayoutThreshold() {
return (
<Card>
<CardHeader>
<CardTitle>Payout Threshold</CardTitle>
<CardDescription>
Set the minimum balance required before a payout is triggered.
</CardDescription>
<CardAction>
<Button
variant="ghost"
size="icon-sm"
className="bg-muted"
aria-label="Dismiss payout threshold"
>
<HugeiconsIcon icon={Cancel01Icon} strokeWidth={2} />
</Button>
</CardAction>
</CardHeader>
<CardContent>
<FieldGroup>
<Field>
<FieldLabel htmlFor="preferred-currency">
Preferred Currency
</FieldLabel>
<Select items={CURRENCIES} defaultValue="usd">
<SelectTrigger id="preferred-currency" className="w-full">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{CURRENCIES.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</Field>
<Field>
<div className="flex items-baseline justify-between">
<FieldLabel id="min-payout-label">
Minimum Payout Amount
</FieldLabel>
<span className="text-2xl font-semibold tabular-nums">
$2500.00
</span>
</div>
<Progress
value={25}
aria-labelledby="min-payout-label"
aria-valuetext="$2,500 of $10,000"
/>
<div className="flex items-center justify-between">
<FieldDescription>$50 (MIN)</FieldDescription>
<FieldDescription>$10,000 (MAX)</FieldDescription>
</div>
</Field>
<Field>
<FieldLabel htmlFor="payout-notes">Notes</FieldLabel>
<Textarea
id="payout-notes"
placeholder="Add any notes for this payout configuration..."
className="min-h-[100px]"
/>
</Field>
</FieldGroup>
</CardContent>
<CardFooter>
<Button className="w-full">Save Threshold</Button>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,67 @@
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import { Separator } from "@/styles/base-rhea/ui/separator"
const chartData = [
{ hour: "6a", usage: 1.2 },
{ hour: "8a", usage: 2.8 },
{ hour: "10a", usage: 3.1 },
{ hour: "12p", usage: 2.4 },
{ hour: "2p", usage: 3.4 },
{ hour: "4p", usage: 2.9 },
{ hour: "6p", usage: 3.8 },
{ hour: "8p", usage: 3.2 },
]
export function PowerUsage() {
const maxUsage = Math.max(...chartData.map((item) => item.usage))
return (
<Card>
<CardHeader>
<CardTitle>Power Usage</CardTitle>
<CardDescription>Whole Home</CardDescription>
</CardHeader>
<CardContent className="flex flex-col gap-4">
<div
className="flex h-[140px] w-full items-end gap-2"
role="img"
aria-label="Power usage by hour"
>
{chartData.map((item) => (
<div
key={item.hour}
className="flex h-full flex-1 flex-col justify-end gap-1.5"
>
<div
className="min-h-2 rounded-t bg-chart-2"
style={{ height: `${(item.usage / maxUsage) * 100}%` }}
/>
<span className="text-center text-xs text-muted-foreground">
{item.hour}
</span>
</div>
))}
</div>
<Separator />
<div className="grid grid-cols-2 gap-4">
<div className="flex flex-col gap-0.5">
<span className="text-sm text-muted-foreground">
Currently Using
</span>
<span className="text-lg font-semibold tabular-nums">3.4 kW</span>
</div>
<div className="flex flex-col gap-0.5">
<span className="text-sm text-muted-foreground">Solar Gen</span>
<span className="text-lg font-semibold tabular-nums">+1.2 kW</span>
</div>
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,64 @@
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
const qrCells = [
"111111100101101111111",
"100000101001001000001",
"101110101111101011101",
"101110100100001011101",
"101110101010101011101",
"100000100111001000001",
"111111101010101111111",
"000000001101000000000",
"101011111001111010110",
"010100001110010101001",
"111010111011101111010",
"001101000101000010101",
"110111101111010111011",
"000000001001010001010",
"111111101101111101001",
"100000100010001001111",
"101110101011101110100",
"101110100110100010011",
"101110101000111101110",
"100000101101000011001",
"111111101011101101111",
]
export function QrConnect() {
return (
<Card>
<CardContent className="flex justify-center pt-6">
<div className="rounded-xl border bg-white p-4">
<svg
viewBox="0 0 21 21"
className="size-40 text-black"
role="img"
aria-label="Connect device QR code"
shapeRendering="crispEdges"
>
<rect width="21" height="21" fill="white" />
{qrCells.map((row, y) =>
[...row].map((cell, x) =>
cell === "1" ? (
<rect key={`${x}-${y}`} x={x} y={y} width="1" height="1" />
) : null
)
)}
</svg>
</div>
</CardContent>
<CardHeader className="text-center">
<CardTitle>Scan to connect your mobile device</CardTitle>
<CardDescription className="text-balance">
Open the Ledger mobile app and scan this code to link your device.
</CardDescription>
</CardHeader>
</Card>
)
}

View File

@@ -0,0 +1,81 @@
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import {
Item,
ItemContent,
ItemDescription,
ItemFooter,
ItemGroup,
} from "@/styles/base-rhea/ui/item"
import { Progress } from "@/styles/base-rhea/ui/progress"
export function SavingsTargets() {
return (
<Card>
<CardHeader>
<CardTitle>Savings Targets</CardTitle>
<CardDescription>
Active milestones for 2024 across your portfolio. Monitor how close
you are to each savings goal.
</CardDescription>
</CardHeader>
<CardContent>
<ItemGroup className="gap-3">
<Item
role="listitem"
variant="muted"
className="flex-col items-stretch"
>
<ItemContent className="gap-3">
<ItemDescription className="cn-font-heading text-xs font-medium tracking-wider text-muted-foreground uppercase">
Retirement
</ItemDescription>
<span className="text-3xl font-semibold tabular-nums">
$420,000
</span>
<Progress value={65} aria-label="Retirement savings progress" />
</ItemContent>
<ItemFooter>
<span className="text-sm text-muted-foreground">
65% achieved
</span>
<span className="text-sm font-medium tabular-nums">$273,000</span>
</ItemFooter>
</Item>
<Item
role="listitem"
variant="muted"
className="flex-col items-stretch"
>
<ItemContent className="gap-3">
<ItemDescription className="cn-font-heading text-xs font-medium tracking-wider text-muted-foreground uppercase">
Real Estate
</ItemDescription>
<span className="text-3xl font-semibold tabular-nums">
$85,000
</span>
<Progress value={32} aria-label="Real estate savings progress" />
</ItemContent>
<ItemFooter>
<span className="text-sm text-muted-foreground">
32% achieved
</span>
<span className="text-sm font-medium tabular-nums">$27,200</span>
</ItemFooter>
</Item>
</ItemGroup>
</CardContent>
<CardFooter>
<CardDescription className="text-center">
You have not met your targets for this year.
</CardDescription>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,218 @@
import * as React from "react"
import {
ActivityIcon,
Analytics01Icon,
AnalyticsUpIcon,
ArrowDataTransferHorizontalIcon,
BankIcon,
BookOpen02Icon,
Calendar03Icon,
ChartBarLineIcon,
CreditCardIcon,
File02Icon,
Globe02Icon,
HelpCircleIcon,
Message01Icon,
Notification03Icon,
PaintBoardIcon,
PieChartIcon,
ShieldIcon,
Target02Icon,
UserIcon,
Wallet01Icon,
} from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import { cn } from "@/lib/utils"
import { Card } from "@/styles/base-rhea/ui/card"
import {
Sidebar,
SidebarContent,
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarProvider,
} from "@/styles/base-rhea/ui/sidebar"
function SidebarSection({
label,
children,
className,
}: {
label: string
children: React.ReactNode
className?: string
}) {
return (
<Card className={cn("w-full overflow-hidden rounded-3xl py-0", className)}>
<SidebarProvider className="min-h-0">
<Sidebar collapsible="none" className="w-full bg-transparent">
<SidebarContent className="gap-0 overflow-hidden">
<SidebarGroup>
<SidebarGroupLabel>{label}</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu className="gap-1">{children}</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
</SidebarContent>
</Sidebar>
</SidebarProvider>
</Card>
)
}
export function SidebarNav() {
return (
<div className="grid w-full grid-cols-2 gap-4 xl:gap-6">
<SidebarSection
label="Overview"
className="xl:col-start-1 xl:row-start-2"
>
<SidebarMenuItem>
<SidebarMenuButton isActive>
<HugeiconsIcon icon={Analytics01Icon} strokeWidth={2} />
Analytics
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon
icon={ArrowDataTransferHorizontalIcon}
strokeWidth={2}
/>
Transactions
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={AnalyticsUpIcon} strokeWidth={2} />
Investments
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={BankIcon} strokeWidth={2} />
Accounts
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={PieChartIcon} strokeWidth={2} />
Spending
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarSection>
<SidebarSection
label="Planning"
className="xl:col-start-1 xl:row-start-1"
>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={File02Icon} strokeWidth={2} />
Documents
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={Wallet01Icon} strokeWidth={2} />
Budget
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={ChartBarLineIcon} strokeWidth={2} />
Reports
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={Target02Icon} strokeWidth={2} />
Goals
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={Calendar03Icon} strokeWidth={2} />
Calendar
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarSection>
<SidebarSection
label="Support"
className="flex xl:col-start-2 xl:row-start-1"
>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={HelpCircleIcon} strokeWidth={2} />
Help Center
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={BookOpen02Icon} strokeWidth={2} />
Docs
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={Message01Icon} strokeWidth={2} />
Contact Us
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={ActivityIcon} strokeWidth={2} />
Status
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={Globe02Icon} strokeWidth={2} />
Community
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarSection>
<SidebarSection
label="Account"
className="flex xl:col-start-2 xl:row-start-2"
>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={UserIcon} strokeWidth={2} />
Profile
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton isActive>
<HugeiconsIcon icon={CreditCardIcon} strokeWidth={2} />
Billing
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={Notification03Icon} strokeWidth={2} />
Notifications
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={ShieldIcon} strokeWidth={2} />
Security
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>
<HugeiconsIcon icon={PaintBoardIcon} strokeWidth={2} />
Appearance
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarSection>
</div>
)
}

View File

@@ -0,0 +1,35 @@
import {
Card,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function AccountAccess() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-36 rounded-md" />
<Skeleton className="h-4 w-64 rounded-md" />
</CardHeader>
<CardContent className="flex flex-col gap-6">
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-24 rounded-md" />
<Skeleton className="h-9 w-full rounded-lg" />
</div>
<div className="flex flex-col gap-2">
<div className="flex items-center justify-between">
<Skeleton className="h-3 w-32 rounded-md" />
<Skeleton className="h-3 w-12 rounded-md" />
</div>
<Skeleton className="h-9 w-full rounded-lg" />
</div>
</CardContent>
<CardFooter className="flex-col gap-4">
<Skeleton className="h-9 w-full rounded-lg" />
<Skeleton className="h-14 w-full rounded-xl" />
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,17 @@
import { Card, CardAction, CardHeader } from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function AnalyticsCard() {
return (
<Card className="mx-auto w-full max-w-sm data-[size=sm]:pb-0" size="sm">
<CardHeader className="gap-2">
<Skeleton className="h-5 w-24 rounded-md" />
<Skeleton className="h-4 w-40 rounded-md" />
<CardAction>
<Skeleton className="h-7 w-28 rounded-lg" />
</CardAction>
</CardHeader>
<Skeleton className="mx-6 mb-6 aspect-[1/0.35] w-auto rounded-lg" />
</Card>
)
}

View File

@@ -0,0 +1,41 @@
import {
Card,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function ClaimableBalance() {
return (
<Card>
<CardHeader className="gap-3">
<Skeleton className="h-4 w-36 rounded-md" />
<Skeleton className="h-12 w-56 rounded-lg" />
<Skeleton className="h-6 w-32 rounded-full" />
</CardHeader>
<CardContent className="flex flex-1 flex-col justify-end">
<div className="flex flex-col gap-3 rounded-xl bg-muted p-4">
<div className="flex items-center justify-between">
<Skeleton className="h-4 w-28 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-4 w-20 rounded-md bg-muted-foreground/15" />
</div>
<div className="flex items-center justify-between">
<Skeleton className="h-4 w-32 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-4 w-16 rounded-md bg-muted-foreground/15" />
</div>
<Skeleton className="h-px w-full rounded-none bg-muted-foreground/15" />
<div className="flex items-center justify-between">
<Skeleton className="h-4 w-36 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-4 w-24 rounded-md bg-muted-foreground/15" />
</div>
</div>
</CardContent>
<CardFooter className="flex-col gap-2">
<Skeleton className="h-3 w-full rounded-md" />
<Skeleton className="h-3 w-11/12 rounded-md" />
<Skeleton className="h-3 w-3/4 rounded-md" />
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,53 @@
import {
Card,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
const bars = [60, 80, 65, 95, 50, 100]
export function ContributionHistory() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-44 rounded-md" />
<Skeleton className="h-4 w-52 rounded-md" />
</CardHeader>
<CardContent>
<div className="flex h-[200px] w-full items-end gap-3">
{bars.map((height, i) => (
<div
key={i}
className="flex h-full flex-1 flex-col justify-end gap-2"
>
<Skeleton
className="w-full rounded-t-md rounded-b-none"
style={{ height: `${height}%` }}
/>
<Skeleton className="mx-auto h-3 w-6 rounded-md" />
</div>
))}
</div>
</CardContent>
<CardContent>
<div className="grid w-full grid-cols-1 gap-3 xl:grid-cols-2">
<div className="flex flex-col gap-2 rounded-xl bg-muted p-4">
<Skeleton className="h-3 w-20 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-5 w-28 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-3 w-24 rounded-md bg-muted-foreground/15" />
</div>
<div className="hidden flex-col gap-2 rounded-xl bg-muted p-4 xl:flex">
<Skeleton className="h-3 w-24 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-5 w-32 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-3 w-28 rounded-md bg-muted-foreground/15" />
</div>
</div>
</CardContent>
<CardFooter>
<Skeleton className="h-9 w-full rounded-lg" />
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,49 @@
import {
Card,
CardAction,
CardContent,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
const rows = [0, 1, 2, 3]
const miniBars = [40, 60, 80, 50]
export function DividendIncome() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-48 rounded-md" />
<Skeleton className="h-4 w-64 rounded-md" />
<CardAction>
<Skeleton className="size-8 rounded-md" />
</CardAction>
</CardHeader>
<CardContent>
<div className="flex flex-col gap-2">
{rows.map((row) => (
<div
key={row}
className="flex items-center gap-3 rounded-xl bg-muted p-3"
>
<div className="flex flex-1 flex-col gap-2">
<Skeleton className="h-4 w-28 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-3 w-20 rounded-md bg-muted-foreground/15" />
</div>
<div className="hidden h-8 w-24 items-end gap-1 md:flex">
{miniBars.map((h, i) => (
<Skeleton
key={i}
className="flex-1 rounded-t-sm rounded-b-none bg-muted-foreground/15"
style={{ height: `${h}%` }}
/>
))}
</div>
<Skeleton className="hidden h-4 w-16 rounded-md bg-muted-foreground/15 md:block" />
</div>
))}
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,20 @@
import { Card, CardContent } from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function EmptyDistributeTrack() {
return (
<Card>
<CardContent>
<div className="flex flex-col items-center gap-4 p-4">
<Skeleton className="size-12 rounded-xl" />
<div className="flex flex-col items-center gap-2">
<Skeleton className="h-5 w-40 rounded-md" />
<Skeleton className="h-3 w-64 rounded-md" />
<Skeleton className="h-3 w-48 rounded-md" />
</div>
<Skeleton className="h-9 w-32 rounded-lg" />
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,56 @@
import { AccountAccess } from "./account-access"
import { AnalyticsCard } from "./analytics-card"
import { ClaimableBalance } from "./claimable-balance"
import { ContributionHistory } from "./contribution-history"
import { DividendIncome } from "./dividend-income"
import { EmptyDistributeTrack } from "./empty-distribute-track"
import { NewMilestone } from "./new-milestone"
import { NotificationSettings } from "./notification-settings"
import { Payments } from "./payments"
import { PayoutThreshold } from "./payout-threshold"
import { PowerUsage } from "./power-usage"
import { QrConnect } from "./qr-connect"
import { SavingsTargets } from "./savings-targets"
import { SidebarNav } from "./sidebar-nav"
import { TransferFunds } from "./transfer-funds"
import { UIElements } from "./ui-elements"
export function CardsSkeletonDemo() {
return (
<div
data-slot="demo"
className="theme-neutral relative flex w-full max-w-none flex-col gap-(--gap) bg-muted p-12 pb-0! [--gap:--spacing(8)] 3xl:[--gap:--spacing(8)] min-[1900px]:[--gap:--spacing(10)]! lg:p-8 lg:[--gap:--spacing(6)] xl:p-12 dark:bg-muted/30"
>
<div className="relative z-10 mx-auto grid gap-(--gap) **:data-[slot=card]:w-full min-[1900px]:grid-cols-5! md:max-w-3xl md:grid-cols-2 lg:max-w-none lg:grid-cols-3 xl:max-w-[1600px] xl:grid-cols-4 2xl:max-w-[1900px]">
<div className="flex flex-col items-start gap-(--gap)">
<UIElements />
<SidebarNav />
<SavingsTargets />
</div>
<div className="hidden flex-col gap-(--gap) lg:flex">
<ContributionHistory />
<ClaimableBalance />
<DividendIncome />
</div>
<div className="hidden flex-col gap-(--gap) 3xl:flex!">
<NewMilestone />
<PayoutThreshold />
<AccountAccess />
</div>
<div className="hidden flex-col gap-(--gap) md:flex">
<QrConnect />
<TransferFunds />
<Payments />
</div>
<div className="hidden flex-col gap-(--gap) xl:flex">
<EmptyDistributeTrack />
<AnalyticsCard />
<NotificationSettings />
<PowerUsage />
</div>
</div>
<div className="absolute inset-x-0 top-0 z-1 h-80 bg-linear-to-b from-background via-muted to-transparent dark:via-muted/30" />
<div className="absolute inset-x-0 bottom-0 z-20 h-80 bg-linear-to-t from-background via-muted to-transparent dark:via-muted/30" />
</div>
)
}

View File

@@ -0,0 +1,38 @@
import {
Card,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function NewMilestone() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-44 rounded-md" />
<Skeleton className="h-4 w-72 rounded-md" />
</CardHeader>
<CardContent className="flex flex-col gap-4">
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-20 rounded-md" />
<Skeleton className="h-9 w-full rounded-lg" />
</div>
<div className="grid grid-cols-2 gap-3">
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-24 rounded-md" />
<Skeleton className="h-9 w-full rounded-lg" />
</div>
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-20 rounded-md" />
<Skeleton className="h-9 w-full rounded-lg" />
</div>
</div>
</CardContent>
<CardFooter className="flex-col gap-2">
<Skeleton className="h-9 w-full rounded-lg" />
<Skeleton className="h-9 w-full rounded-lg" />
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,34 @@
import {
Card,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
const rows = [0, 1, 2, 3]
export function NotificationSettings() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-32 rounded-md" />
<Skeleton className="h-4 w-64 rounded-md" />
</CardHeader>
<CardContent className="flex flex-col gap-4">
{rows.map((row) => (
<div key={row} className="flex items-start gap-3">
<Skeleton className="size-4 rounded-sm" />
<div className="flex flex-1 flex-col gap-2">
<Skeleton className="h-4 w-40 rounded-md" />
<Skeleton className="h-3 w-56 rounded-md" />
</div>
</div>
))}
</CardContent>
<CardFooter>
<Skeleton className="h-9 w-full rounded-lg" />
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,37 @@
import { Card, CardContent, CardHeader } from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
const rows = [0, 1, 2]
export function Payments() {
return (
<Card>
<CardHeader className="flex flex-col gap-3">
<div className="flex items-center gap-2">
<Skeleton className="h-4 w-12 rounded-md" />
<Skeleton className="size-1.5 rounded-full" />
<Skeleton className="size-7 rounded-md" />
<Skeleton className="size-1.5 rounded-full" />
<Skeleton className="h-4 w-20 rounded-md" />
</div>
</CardHeader>
<CardContent>
<div className="flex flex-col gap-2">
{rows.map((row) => (
<div
key={row}
className="flex items-center gap-3 rounded-xl bg-muted p-3"
>
<Skeleton className="size-9 rounded-lg bg-muted-foreground/15" />
<div className="flex flex-1 flex-col gap-2">
<Skeleton className="h-4 w-40 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-3 w-56 rounded-md bg-muted-foreground/15" />
</div>
<Skeleton className="size-4 rounded-md bg-muted-foreground/15" />
</div>
))}
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,43 @@
import {
Card,
CardAction,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function PayoutThreshold() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-44 rounded-md" />
<Skeleton className="h-4 w-72 rounded-md" />
</CardHeader>
<CardContent className="flex flex-col gap-4">
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-32 rounded-md" />
<Skeleton className="h-9 w-full rounded-lg" />
</div>
<div className="flex flex-col gap-3">
<div className="flex items-baseline justify-between">
<Skeleton className="h-3 w-40 rounded-md" />
<Skeleton className="h-7 w-24 rounded-md" />
</div>
<Skeleton className="h-2 w-full rounded-full" />
<div className="flex items-center justify-between">
<Skeleton className="h-3 w-16 rounded-md" />
<Skeleton className="h-3 w-20 rounded-md" />
</div>
</div>
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-16 rounded-md" />
<Skeleton className="h-[100px] w-full rounded-lg" />
</div>
</CardContent>
<CardFooter>
<Skeleton className="h-9 w-full rounded-lg" />
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,54 @@
import {
Card,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
const bars = [30, 70, 80, 60, 90, 75, 100, 85]
export function PowerUsage() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-32 rounded-md" />
<Skeleton className="h-4 w-24 rounded-md" />
</CardHeader>
<CardContent className="flex flex-col gap-4">
<div className="flex h-[140px] w-full items-end gap-2">
{bars.map((height, i) => (
<div
key={i}
className="flex h-full flex-1 flex-col justify-end gap-1.5"
>
<Skeleton
className="w-full rounded-t rounded-b-none"
style={{ height: `${height}%` }}
/>
<Skeleton className="mx-auto h-3 w-5 rounded-md" />
</div>
))}
</div>
<Skeleton className="h-px w-full rounded-none" />
<div className="grid grid-cols-2 gap-4">
<div className="flex flex-col gap-1.5">
<Skeleton className="h-3 w-28 rounded-md" />
<Skeleton className="h-5 w-20 rounded-md" />
</div>
<div className="flex flex-col gap-1.5">
<Skeleton className="h-3 w-20 rounded-md" />
<Skeleton className="h-5 w-24 rounded-md" />
</div>
</div>
</CardContent>
<CardFooter className="flex-col items-start gap-2">
<Skeleton className="h-3 w-24 rounded-md" />
<div className="flex w-full items-center gap-2">
<Skeleton className="h-2 flex-1 rounded-full" />
<Skeleton className="h-3 w-10 rounded-md" />
</div>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,17 @@
import { Card, CardContent, CardHeader } from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function QrConnect() {
return (
<Card>
<CardContent className="flex justify-center pt-6">
<Skeleton className="size-44 rounded-xl" />
</CardContent>
<CardHeader className="items-center gap-2 text-center">
<Skeleton className="h-5 w-56 rounded-md" />
<Skeleton className="h-4 w-64 rounded-md" />
<Skeleton className="h-4 w-48 rounded-md" />
</CardHeader>
</Card>
)
}

View File

@@ -0,0 +1,44 @@
import {
Card,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
const rows = [0, 1]
export function SavingsTargets() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-36 rounded-md" />
<div className="flex flex-col gap-1.5">
<Skeleton className="h-4 w-full max-w-64 rounded-md" />
<Skeleton className="h-4 w-48 rounded-md" />
</div>
</CardHeader>
<CardContent>
<div className="flex flex-col gap-3">
{rows.map((row) => (
<div
key={row}
className="flex flex-col gap-3 rounded-xl bg-muted p-4"
>
<Skeleton className="h-3 w-24 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-8 w-36 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-2 w-full rounded-full bg-muted-foreground/15" />
<div className="flex items-center justify-between">
<Skeleton className="h-3 w-24 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-3 w-20 rounded-md bg-muted-foreground/15" />
</div>
</div>
))}
</div>
</CardContent>
<CardFooter className="justify-center">
<Skeleton className="h-3 w-56 rounded-md" />
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,39 @@
import { Card } from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
const groupA = [0, 1, 2, 3, 4]
const groupB = [0, 1, 2, 3, 4]
function NavSkeleton({ groups }: { groups: number[][] }) {
return (
<div className="flex flex-col gap-1 p-2">
{groups.map((items, gi) => (
<div key={gi} className="flex flex-col gap-1 px-2 py-1.5">
<Skeleton className="mb-1 h-3 w-20 rounded-md" />
{items.map((item) => (
<div key={item} className="flex items-center gap-2 px-2 py-2">
<Skeleton className="size-4 rounded-md" />
<Skeleton className="h-3 w-24 rounded-md" />
</div>
))}
{gi < groups.length - 1 && (
<Skeleton className="my-1 h-px w-full rounded-none" />
)}
</div>
))}
</div>
)
}
export function SidebarNav() {
return (
<div className="grid w-full items-start gap-4 xl:grid-cols-2 xl:gap-6">
<Card className="w-full overflow-hidden rounded-3xl py-0">
<NavSkeleton groups={[groupA, groupB]} />
</Card>
<Card className="hidden w-full overflow-hidden rounded-3xl py-0 xl:flex">
<NavSkeleton groups={[groupA, groupB]} />
</Card>
</div>
)
}

View File

@@ -0,0 +1,55 @@
import {
Card,
CardAction,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function TransferFunds() {
return (
<Card>
<CardHeader className="gap-2">
<Skeleton className="h-5 w-36 rounded-md" />
<Skeleton className="h-4 w-64 rounded-md" />
<CardAction>
<Skeleton className="size-8 rounded-md" />
</CardAction>
</CardHeader>
<CardContent className="flex flex-col gap-4">
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-32 rounded-md" />
<Skeleton className="h-9 w-full rounded-lg" />
</div>
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-24 rounded-md" />
<Skeleton className="h-9 w-full rounded-lg" />
</div>
<div className="flex flex-col gap-2">
<Skeleton className="h-3 w-20 rounded-md" />
<Skeleton className="h-9 w-full rounded-lg" />
</div>
<div className="flex flex-col gap-3 rounded-xl bg-muted p-4">
<div className="flex items-center justify-between">
<Skeleton className="h-4 w-28 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-4 w-24 rounded-md bg-muted-foreground/15" />
</div>
<Skeleton className="h-px w-full rounded-none bg-muted-foreground/15" />
<div className="flex items-center justify-between">
<Skeleton className="h-4 w-28 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-4 w-12 rounded-md bg-muted-foreground/15" />
</div>
<Skeleton className="h-px w-full rounded-none bg-muted-foreground/15" />
<div className="flex items-center justify-between">
<Skeleton className="h-4 w-24 rounded-md bg-muted-foreground/15" />
<Skeleton className="h-4 w-20 rounded-md bg-muted-foreground/15" />
</div>
</div>
</CardContent>
<CardFooter>
<Skeleton className="h-9 w-full rounded-lg" />
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,45 @@
import { Card, CardContent } from "@/styles/base-rhea/ui/card"
import { Skeleton } from "@/styles/base-rhea/ui/skeleton"
export function UIElements() {
return (
<Card className="w-full">
<CardContent className="flex flex-col gap-6">
<Skeleton className="h-8 w-full rounded-2xl" />
<div className="flex flex-wrap gap-2">
<Skeleton className="h-9 w-20 rounded-lg" />
<Skeleton className="h-9 w-24 rounded-lg" />
<Skeleton className="h-9 w-20 rounded-lg" />
</div>
<div className="flex flex-col gap-3">
<Skeleton className="h-9 w-full rounded-lg" />
<Skeleton className="h-20 w-full rounded-lg" />
</div>
<div className="flex items-center gap-2">
<div className="flex gap-2">
<Skeleton className="h-5 w-12 rounded-full" />
<Skeleton className="h-5 w-16 rounded-full" />
<Skeleton className="hidden h-5 w-14 rounded-full 4xl:block" />
</div>
<div className="ml-auto flex gap-3">
<Skeleton className="size-4 rounded-full" />
<Skeleton className="size-4 rounded-full" />
</div>
<div className="flex gap-3">
<Skeleton className="size-4 rounded-sm" />
<Skeleton className="hidden size-4 rounded-sm 4xl:block" />
</div>
<Skeleton className="ml-auto h-5 w-9 rounded-full 4xl:hidden" />
</div>
<div className="flex items-center gap-4">
<Skeleton className="h-9 w-24 rounded-lg" />
<div className="flex">
<Skeleton className="h-9 w-28 rounded-l-lg rounded-r-none" />
<Skeleton className="ml-px h-9 w-9 rounded-l-none rounded-r-lg" />
</div>
<Skeleton className="ml-auto hidden h-5 w-9 rounded-full 4xl:block" />
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,139 @@
import { Cancel01Icon } from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import { Button } from "@/styles/base-rhea/ui/button"
import {
Card,
CardAction,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-rhea/ui/card"
import { Field, FieldGroup, FieldLabel } from "@/styles/base-rhea/ui/field"
import {
InputGroup,
InputGroupAddon,
InputGroupInput,
InputGroupText,
} from "@/styles/base-rhea/ui/input-group"
import { Item, ItemContent } from "@/styles/base-rhea/ui/item"
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/styles/base-rhea/ui/select"
import { Separator } from "@/styles/base-rhea/ui/separator"
const FROM_ACCOUNTS = [
{ label: "Main Checking (··8402) — $12,450.00", value: "checking" },
{ label: "Business (··7731) — $8,920.00", value: "business" },
]
const TO_ACCOUNTS = [
{ label: "High Yield Savings (··1192) — $42,100.00", value: "savings" },
{ label: "Investment (··3349) — $18,200.00", value: "investment" },
]
export function TransferFunds() {
return (
<Card>
<CardHeader>
<CardTitle>Transfer Funds</CardTitle>
<CardDescription>
Move money between your connected accounts.
</CardDescription>
<CardAction>
<Button
variant="ghost"
size="icon-sm"
className="bg-muted"
aria-label="Dismiss transfer funds"
>
<HugeiconsIcon icon={Cancel01Icon} strokeWidth={2} />
</Button>
</CardAction>
</CardHeader>
<CardContent>
<FieldGroup>
<Field>
<FieldLabel htmlFor="transfer-amount">
Amount to Transfer
</FieldLabel>
<InputGroup>
<InputGroupAddon>
<InputGroupText>$</InputGroupText>
</InputGroupAddon>
<InputGroupInput id="transfer-amount" defaultValue="1,200.00" />
</InputGroup>
</Field>
<Field>
<FieldLabel htmlFor="from-account">From Account</FieldLabel>
<Select items={FROM_ACCOUNTS} defaultValue="checking">
<SelectTrigger id="from-account" className="w-full">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{FROM_ACCOUNTS.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</Field>
<Field>
<FieldLabel htmlFor="to-account">To Account</FieldLabel>
<Select items={TO_ACCOUNTS} defaultValue="savings">
<SelectTrigger id="to-account" className="w-full">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{TO_ACCOUNTS.map((item) => (
<SelectItem key={item.value} value={item.value}>
{item.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</Field>
<Item variant="muted" className="flex-col items-stretch">
<ItemContent className="gap-3">
<div className="flex items-center justify-between">
<span className="text-sm text-muted-foreground">
Estimated arrival
</span>
<span className="text-sm font-medium">Today, Apr 14</span>
</div>
<Separator />
<div className="flex items-center justify-between">
<span className="text-sm text-muted-foreground">
Transaction fee
</span>
<span className="text-sm font-medium tabular-nums">$0.00</span>
</div>
<Separator />
<div className="flex items-center justify-between">
<span className="text-sm font-medium">Total amount</span>
<span className="text-sm font-semibold tabular-nums">
$1,200.00
</span>
</div>
</ItemContent>
</Item>
</FieldGroup>
</CardContent>
<CardFooter>
<Button className="w-full">Confirm Transfer</Button>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,176 @@
"use client"
import {
ArrowRight02Icon,
ArrowUp01Icon,
Search01Icon,
} from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/styles/base-rhea/ui/alert-dialog"
import { Badge } from "@/styles/base-rhea/ui/badge"
import { Button } from "@/styles/base-rhea/ui/button"
import { ButtonGroup } from "@/styles/base-rhea/ui/button-group"
import { Card, CardContent } from "@/styles/base-rhea/ui/card"
import { Checkbox } from "@/styles/base-rhea/ui/checkbox"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/styles/base-rhea/ui/dropdown-menu"
import { Field, FieldGroup } from "@/styles/base-rhea/ui/field"
import {
InputGroup,
InputGroupAddon,
InputGroupInput,
InputGroupText,
} from "@/styles/base-rhea/ui/input-group"
import { RadioGroup, RadioGroupItem } from "@/styles/base-rhea/ui/radio-group"
import { Switch } from "@/styles/base-rhea/ui/switch"
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from "@/styles/base-rhea/ui/tabs"
import { Textarea } from "@/styles/base-rhea/ui/textarea"
export function UIElements() {
return (
<Card className="w-full">
<CardContent className="flex flex-col gap-6">
<div className="flex gap-2">
<Button>
Button{" "}
<HugeiconsIcon
icon={ArrowRight02Icon}
strokeWidth={2}
data-icon="inline-end"
/>
</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="outline">Outline</Button>
</div>
<FieldGroup>
<Field>
<InputGroup>
<InputGroupInput placeholder="Name" />
<InputGroupAddon align="inline-end">
<InputGroupText>
<HugeiconsIcon icon={Search01Icon} strokeWidth={2} />
</InputGroupText>
</InputGroupAddon>
</InputGroup>
</Field>
<Field className="flex-1">
<Textarea placeholder="Message" className="resize-none" />
</Field>
</FieldGroup>
<div className="flex items-center gap-2">
<div className="flex gap-2">
<Badge>Badge</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="outline" className="hidden 4xl:flex">
Outline
</Badge>
</div>
<RadioGroup
defaultValue="apple"
className="ml-auto flex w-fit gap-3"
aria-label="Fruit preference"
>
<RadioGroupItem value="apple" aria-label="Apple" />
<RadioGroupItem value="banana" aria-label="Banana" />
</RadioGroup>
<div className="flex gap-3">
<Checkbox defaultChecked aria-label="Enable email alerts" />
<Checkbox
className="hidden 4xl:flex"
aria-label="Enable push alerts"
/>
</div>
<Switch
defaultChecked
className="flex 4xl:hidden"
aria-label="Enable compact notifications"
/>
</div>
<div className="flex items-center gap-4">
<AlertDialog>
<AlertDialogTrigger render={<Button variant="outline" />}>
<span className="hidden md:flex style-sera:md:hidden">
Alert Dialog
</span>
<span className="flex md:hidden style-sera:md:flex">Dialog</span>
</AlertDialogTrigger>
<AlertDialogContent size="sm">
<AlertDialogHeader>
<AlertDialogTitle>Allow accessory to connect?</AlertDialogTitle>
<AlertDialogDescription>
Do you want to allow the USB accessory to connect to this
device and your data?
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Don&apos;t allow</AlertDialogCancel>
<AlertDialogAction>Allow</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
<ButtonGroup className="ml-auto">
<Button variant="outline">
<span className="style-sera:hidden">Button Group</span>
<span className="hidden style-sera:block">Group</span>
</Button>
<DropdownMenu>
<DropdownMenuTrigger
render={
<Button
variant="outline"
size="icon"
aria-label="Open quick actions"
/>
}
>
<HugeiconsIcon icon={ArrowUp01Icon} strokeWidth={2} />
</DropdownMenuTrigger>
<DropdownMenuContent align="end" side="top" className="w-40">
<DropdownMenuGroup>
<DropdownMenuLabel>Quick Actions</DropdownMenuLabel>
<DropdownMenuItem>Mute Conversation</DropdownMenuItem>
<DropdownMenuItem>Mark as Read</DropdownMenuItem>
<DropdownMenuItem>Block User</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem variant="destructive">
Delete Conversation
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</ButtonGroup>
<Switch
defaultChecked
className="hidden 4xl:flex"
aria-label="Enable advanced setting"
/>
</div>
</CardContent>
</Card>
)
}

View File

@@ -1,19 +1,18 @@
import { Metadata } from "next"
import { type Metadata } from "next"
import Image from "next/image"
import Link from "next/link"
import { IconArrowRight } from "@tabler/icons-react"
import { Announcement } from "@/components/announcement"
import { CardsDemo } from "@/components/cards"
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 { Button } from "@/styles/radix-nova/ui/button"
import { CardsDemo } from "./cards"
const title = "The Foundation for your Design System"
const description =
@@ -49,44 +48,39 @@ export const metadata: Metadata = {
export default function IndexPage() {
return (
<div className="flex flex-1 flex-col">
<PageHeader>
<PageHeader className="md:**:[.container]:pb-8 lg:**:[.container]:pb-12">
<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 asChild className="h-[31px] rounded-lg">
<Link href="/create?preset=b27GcrRo">
Build Your Own <IconArrowRight data-icon="inline-end" />
</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]">
<div className="container-wrapper flex-1 p-0">
<div className="container overflow-hidden md:px-0 lg:max-w-none">
<section className="-mx-4 w-[140vw] overflow-hidden md:hidden">
<Image
src="/r/styles/new-york-v4/dashboard-01-light.png"
width={1400}
height={875}
src="/images/full-light.png"
width={2560}
height={2764}
alt="Dashboard"
className="block dark:hidden"
className="block h-auto w-full dark:hidden"
priority
/>
<Image
src="/r/styles/new-york-v4/dashboard-01-dark.png"
width={1400}
height={875}
src="/images/full-dark.png"
width={2560}
height={2764}
alt="Dashboard"
className="hidden dark:block"
className="hidden h-auto w-full dark:block"
priority
/>
</section>
<section className="theme-container hidden md:block">
<section className="hidden md:block">
<CardsDemo />
</section>
</div>

View File

@@ -0,0 +1,216 @@
"use client"
import { ChevronLeftIcon, ChevronRightIcon, SearchIcon } from "lucide-react"
import { cn } from "@/lib/utils"
import { Badge } from "@/styles/base-sera/ui/badge"
import {
Card,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-sera/ui/card"
import {
InputGroup,
InputGroupAddon,
InputGroupInput,
} from "@/styles/base-sera/ui/input-group"
import {
Pagination,
PaginationContent,
PaginationItem,
PaginationLink,
} from "@/styles/base-sera/ui/pagination"
import { Progress, ProgressValue } from "@/styles/base-sera/ui/progress"
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/styles/base-sera/ui/table"
const ARTICLE_ROWS = [
{
title: "The Future of Sustainable Architecture",
wordProgress: "1.4k / 2.6k words",
author: "Elena Rostova",
issue: "Summer 2024",
status: "in-revision",
statusLabel: "In revision",
progress: 45,
},
{
title: "Brutalism's Second Act",
wordProgress: "2.1k / 2.5k words",
author: "Marcus Chen",
issue: "Summer 2024",
status: "final-edit",
statusLabel: "Final edit",
progress: 90,
},
{
title: "The Typography of Public Spaces",
wordProgress: "0.5k / 1.5k words",
author: "Sarah Jenkins",
issue: "Autumn 2024",
status: "drafting",
statusLabel: "Drafting",
progress: 20,
},
{
title: "Rethinking Urban Canopies",
wordProgress: "1.8k / 1.8k words",
author: "David O'Connor",
issue: "Summer 2024",
status: "published",
statusLabel: "Published",
progress: 100,
},
{
title: "Light, Glass, and the Modern Museum",
wordProgress: "1.2k / 2.0k words",
author: "Amara Osei",
issue: "Autumn 2024",
status: "in-revision",
statusLabel: "In revision",
progress: 55,
},
{
title: "Concrete Utopias: Housing in the 21st Century",
wordProgress: "3.0k / 3.0k words",
author: "Tomás Herrera",
issue: "Summer 2024",
status: "published",
statusLabel: "Published",
progress: 100,
},
{
title: "Designing for Silence",
wordProgress: "0.8k / 2.2k words",
author: "Ingrid Solberg",
issue: "Winter 2024",
status: "drafting",
statusLabel: "Drafting",
progress: 30,
},
{
title: "The Invisible Infrastructure of Cities",
wordProgress: "2.4k / 2.8k words",
author: "James Whitfield",
issue: "Autumn 2024",
status: "final-edit",
statusLabel: "Final edit",
progress: 85,
},
] as const
const STATUS_BADGE_VARIANT = {
"in-revision": "outline",
"final-edit": "default",
drafting: "ghost",
published: "secondary",
} as const
const STATUS_DOT_CLASSNAME = {
"in-revision": "bg-amber-600/80",
"final-edit": "bg-foreground/90",
drafting: "bg-muted-foreground/60",
published: "bg-emerald-600/80",
}
export function ArticleDirectory() {
return (
<Card>
<CardHeader>
<InputGroup>
<InputGroupAddon>
<SearchIcon />
</InputGroupAddon>
<InputGroupInput type="search" placeholder="Search articles..." />
</InputGroup>
</CardHeader>
<CardContent>
<Table>
<TableHeader>
<TableRow className="hover:bg-transparent">
<TableHead>Title</TableHead>
<TableHead className="w-[170px]">Author</TableHead>
<TableHead className="w-[150px]">Issue</TableHead>
<TableHead className="w-[180px]">Status</TableHead>
<TableHead className="w-[140px]">Progress</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{ARTICLE_ROWS.map((row) => (
<TableRow key={row.title}>
<TableCell>
<div className="flex flex-col gap-1">
<p className="font-heading text-xl tracking-tight text-foreground">
{row.title}
</p>
<p className="text-xs text-muted-foreground">
{row.wordProgress}
</p>
</div>
</TableCell>
<TableCell>{row.author}</TableCell>
<TableCell>{row.issue}</TableCell>
<TableCell>
<Badge variant={STATUS_BADGE_VARIANT[row.status]}>
<span
className={cn(
"size-1.5 rounded-full",
STATUS_DOT_CLASSNAME[row.status]
)}
/>
{row.statusLabel}
</Badge>
</TableCell>
<TableCell>
<Progress
value={row.progress}
aria-label={`${row.progress}% complete`}
className="flex flex-row-reverse items-center **:data-[slot=progress-track]:w-16"
>
<ProgressValue>
{(formattedValue) => `${formattedValue}`}
</ProgressValue>
</Progress>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</CardContent>
<CardFooter>
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationLink
href="#"
size="icon-sm"
aria-label="Previous page"
>
<ChevronLeftIcon className="cn-rtl-flip" />
</PaginationLink>
</PaginationItem>
{[1, 2, 3].map((page) => (
<PaginationItem key={page}>
<PaginationLink href="#" size="icon-sm" isActive={page === 1}>
{page}
</PaginationLink>
</PaginationItem>
))}
<PaginationItem>
<PaginationLink href="#" size="icon-sm" aria-label="Next page">
<ChevronRightIcon className="cn-rtl-flip" />
</PaginationLink>
</PaginationItem>
</PaginationContent>
</Pagination>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,47 @@
import { ArrowLeftIcon, PlusIcon } from "lucide-react"
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/styles/base-sera/ui/breadcrumb"
import { Button } from "@/styles/base-sera/ui/button"
import { ButtonGroup } from "@/styles/base-sera/ui/button-group"
export function PreviewHeader() {
return (
<header>
<div className="container flex flex-col items-center justify-center gap-(--gap) py-(--gap) sm:flex-row sm:justify-between">
<div className="flex flex-col gap-2 text-center sm:text-left">
<Breadcrumb>
<BreadcrumbList className="justify-center md:justify-start">
<BreadcrumbItem>
<BreadcrumbLink
href="#"
className="inline-flex items-center gap-1.5"
>
<ArrowLeftIcon className="size-3" />
Editorial Dashboard
</BreadcrumbLink>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
<h1 className="line-clamp-1 font-heading text-3xl tracking-wide uppercase md:text-3xl lg:text-4xl">
Article Directory
</h1>
</div>
<div>
<ButtonGroup className="gap-2 sm:ml-auto md:gap-4">
<Button>
<PlusIcon data-icon="inline-start" />
New Article
</Button>
</ButtonGroup>
</div>
</div>
</header>
)
}

View File

@@ -0,0 +1,16 @@
import { Separator } from "@/styles/base-sera/ui/separator"
import { ArticleDirectory as ArticleDirectoryList } from "./components/article-directory"
import { PreviewHeader } from "./components/preview-header"
export function ArticleDirectory() {
return (
<div className="preview theme-taupe @container/preview w-full flex-1 bg-muted pt-4 font-sans ring-1 ring-foreground/5 [--gap:--spacing(4)] sm:pt-0 md:[--gap:--spacing(6)] xl:[--gap:--spacing(8)] 2xl:py-8 **:[.container]:px-(--gap)">
<PreviewHeader />
<Separator className="hidden sm:block" />
<div className="container py-(--gap)">
<ArticleDirectoryList />
</div>
</div>
)
}

View File

@@ -0,0 +1,56 @@
"use client"
import * as React from "react"
import { MoveRightIcon } from "lucide-react"
import { Button } from "@/styles/base-sera/ui/button"
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-sera/ui/card"
import {
Progress,
ProgressLabel,
ProgressValue,
} from "@/styles/base-sera/ui/progress"
const DEMOGRAPHIC_DATA = [
{ age: "18 - 24", percentage: 22 },
{ age: "25 - 34", percentage: 64 },
{ age: "35 - 44", percentage: 12 },
{ age: "45+", percentage: 5 },
]
export function Demographics({ ...props }: React.ComponentProps<typeof Card>) {
return (
<Card {...props}>
<CardHeader>
<CardTitle className="text-2xl">Demographics</CardTitle>
<CardDescription>Reader Profile</CardDescription>
</CardHeader>
<CardContent className="flex flex-col gap-10">
{DEMOGRAPHIC_DATA.map((item) => (
<Progress
key={item.age}
value={item.percentage}
aria-label={item.age}
>
<ProgressLabel>{item.age}</ProgressLabel>
<ProgressValue>
{(formattedValue) => `${formattedValue}`}
</ProgressValue>
</Progress>
))}
</CardContent>
<CardFooter>
<Button variant="link" className="w-full">
View all source <MoveRightIcon data-icon="inline-end" />
</Button>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,93 @@
import { TrendingDownIcon, TrendingUpIcon } from "lucide-react"
import { cn } from "@/lib/utils"
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/styles/base-sera/ui/card"
type Metric = {
label: string
value: string
comparison: string
change: string
trend: "up" | "down"
}
const METRIC_CARDS: Metric[] = [
{
label: "Total visitors",
value: "248.5k",
comparison: "12.4%",
change: "vs last period",
trend: "up",
},
{
label: "Unique readers",
value: "182.1k",
comparison: "8.7%",
change: "vs last period",
trend: "up",
},
{
label: "Avg. time on page",
value: "3m 42s",
comparison: "1.2%",
change: "vs last period",
trend: "down",
},
{
label: "Bounce rate",
value: "42.8%",
comparison: "3.5%",
change: "vs last period",
trend: "down",
},
]
export function MetricsGrid() {
return (
<>
{METRIC_CARDS.map((metric) => (
<MetricCard
key={metric.label}
metric={metric}
className="col-span-full md:col-span-6 lg:col-span-3"
/>
))}
</>
)
}
function MetricCard({
metric,
className,
}: {
metric: Metric
className: string
}) {
return (
<Card className={cn("gap-0", className)}>
<CardContent className="flex flex-col gap-2">
<CardDescription className="text-xs uppercase">
{metric.label}
</CardDescription>
<CardTitle className="text-5xl tracking-tight lowercase">
{metric.value}
</CardTitle>
<CardDescription>
{metric.trend === "up" ? (
<TrendingUpIcon className="inline-block size-2.5 text-muted-foreground" />
) : (
<TrendingDownIcon className="inline-block size-2.5 text-muted-foreground" />
)}{" "}
<span className="text-foreground">{metric.comparison}</span>{" "}
<span>{metric.change}</span>
</CardDescription>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,103 @@
"use client"
import * as React from "react"
import { ChevronDownIcon, DownloadIcon } from "lucide-react"
import { Button } from "@/styles/base-sera/ui/button"
import { ButtonGroup } from "@/styles/base-sera/ui/button-group"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuTrigger,
} from "@/styles/base-sera/ui/dropdown-menu"
const EXPORT_DATE_OPTIONS = [
{
label: "Last 7 days",
value: "last-7-days",
},
{
label: "Last 30 days",
value: "last-30-days",
},
{
label: "This month",
value: "this-month",
},
{
label: "Last month",
value: "last-month",
},
]
export function PreviewHeader() {
const [selectedDateRange, setSelectedDateRange] =
React.useState("last-30-days")
const selectedDateRangeLabel = React.useMemo(() => {
const selectedOption = EXPORT_DATE_OPTIONS.find(
(option) => option.value === selectedDateRange
)
if (!selectedOption) {
return "Last 30 days"
}
return selectedOption.label
}, [selectedDateRange])
return (
<header>
<div className="container flex flex-col items-center justify-center gap-(--gap) py-(--gap) sm:flex-row sm:justify-between">
<div className="flex flex-col gap-2 text-center sm:text-left">
<h1 className="line-clamp-1 font-heading text-3xl tracking-wide uppercase md:text-3xl lg:text-4xl">
Audience Analytics
</h1>
<div className="line-clamp-1 text-sm font-medium tracking-wider text-muted-foreground uppercase">
Editorial Performance Dashboard
</div>
</div>
<ButtonGroup className="gap-2 sm:ml-auto md:gap-4">
<DropdownMenu>
<DropdownMenuTrigger
render={
<Button
variant="outline"
className="bg-background hover:bg-background/80 data-popup-open:bg-background"
/>
}
>
{selectedDateRangeLabel}{" "}
<ChevronDownIcon data-icon="inline-end" />
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuGroup>
<DropdownMenuRadioGroup
value={selectedDateRange}
onValueChange={setSelectedDateRange}
>
{EXPORT_DATE_OPTIONS.map((option) => (
<DropdownMenuRadioItem
key={option.value}
value={option.value}
>
{option.label}
</DropdownMenuRadioItem>
))}
</DropdownMenuRadioGroup>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
<Button>
<DownloadIcon data-icon="inline-start" />
<span className="lg:hidden">Export</span>
<span className="hidden lg:inline">Export Report</span>
</Button>
</ButtonGroup>
</div>
</header>
)
}

View File

@@ -0,0 +1,257 @@
"use client"
import * as React from "react"
import { ArrowDownIcon, MoreHorizontalIcon } from "lucide-react"
import { Button } from "@/styles/base-sera/ui/button"
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-sera/ui/card"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/styles/base-sera/ui/dropdown-menu"
import { Spinner } from "@/styles/base-sera/ui/spinner"
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/styles/base-sera/ui/table"
import {
ToggleGroup,
ToggleGroupItem,
} from "@/styles/base-sera/ui/toggle-group"
type EditorialMetric = "views" | "time" | "shares"
type EditorialRow = {
rank: number
title: string
author: string
published: string
pageviews: string
avgTime: string
}
const METRIC_LABEL: Record<EditorialMetric, string> = {
views: "VIEWS",
time: "TIME",
shares: "SHARES",
}
const EDITORIAL_ROWS: EditorialRow[] = [
{
rank: 1,
title: "The New Vanguard of Minimalist Architecture",
author: "Elena Rostova",
published: "Oct 12",
pageviews: "45.2k",
avgTime: "04:15",
},
{
rank: 2,
title: "Autumn Sartorial Code: Deconstructed Classics",
author: "Julian Vance",
published: "Oct 05",
pageviews: "38.9k",
avgTime: "03:42",
},
{
rank: 3,
title: "Interview: Director Sofia Coppola on The Aesthetics of Isolation",
author: "Marcus Trent",
published: "Sep 28",
pageviews: "31.4k",
avgTime: "06:20",
},
{
rank: 4,
title: "Sourcing Ceramics from Kyoto's Oldest Kilns",
author: "Sarah Lin",
published: "Oct 18",
pageviews: "22.1k",
avgTime: "02:55",
},
{
rank: 5,
title: "Field Notes from Copenhagen Design Week",
author: "Noah Bennett",
published: "Oct 21",
pageviews: "19.7k",
avgTime: "03:18",
},
{
rank: 6,
title: "A Studio Visit with Milan's Most Elusive Lighting Designer",
author: "Claire Duval",
published: "Oct 09",
pageviews: "17.4k",
avgTime: "04:02",
},
{
rank: 7,
title: "Collecting the New Avant-Garde in Contemporary Furniture",
author: "Tommy Rhodes",
published: "Sep 30",
pageviews: "15.9k",
avgTime: "03:36",
},
{
rank: 8,
title: "Inside Lisbon's Quiet Culinary Renaissance",
author: "Amara Iqbal",
published: "Oct 14",
pageviews: "14.2k",
avgTime: "05:08",
},
{
rank: 9,
title: "Why Slow Interiors Are Defining the Next Luxury Wave",
author: "Henry Vale",
published: "Oct 03",
pageviews: "12.7k",
avgTime: "03:11",
},
{
rank: 10,
title: "The Return of Print: Independent Magazine Covers to Watch",
author: "Mina Okafor",
published: "Sep 26",
pageviews: "11.3k",
avgTime: "02:49",
},
]
type TopEditorialProps = React.ComponentProps<typeof Card> & {
selectedMetric?: EditorialMetric
}
export function TopEditorial({
selectedMetric = "views",
...props
}: TopEditorialProps) {
const [visibleCount, setVisibleCount] = React.useState(5)
const [isLoadingMore, setIsLoadingMore] = React.useState(false)
const hasMoreRows = visibleCount < EDITORIAL_ROWS.length
const visibleRows = EDITORIAL_ROWS.slice(0, visibleCount)
const handleLoadMore = React.useCallback(() => {
if (!hasMoreRows || isLoadingMore) {
return
}
setIsLoadingMore(true)
window.setTimeout(() => {
setVisibleCount(EDITORIAL_ROWS.length)
setIsLoadingMore(false)
}, 2000)
}, [hasMoreRows, isLoadingMore])
return (
<Card {...props}>
<CardHeader>
<div className="flex flex-col gap-(--gap) sm:flex-row">
<div className="flex flex-col gap-1.5">
<CardTitle className="text-2xl">Top Editorials</CardTitle>
<CardDescription>Ranked by engagement</CardDescription>
</div>
<ToggleGroup
aria-label="Top editorials metric selector"
value={[selectedMetric]}
variant="outline"
className="w-full sm:ml-auto sm:w-fit"
>
{(["views", "time", "shares"] as const).map((metric) => {
return (
<ToggleGroupItem key={metric} value={metric} className="flex-1">
{METRIC_LABEL[metric]}
</ToggleGroupItem>
)
})}
</ToggleGroup>
</div>
</CardHeader>
<CardContent className="flex-1 **:data-[slot=table-container]:no-scrollbar **:data-[slot=table-container]:overflow-y-hidden">
<Table>
<TableHeader>
<TableRow>
<TableHead>#</TableHead>
<TableHead>Title</TableHead>
<TableHead>Published</TableHead>
<TableHead>Page Views</TableHead>
<TableHead>Read Time</TableHead>
<TableHead className="text-right">Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{visibleRows.map((row) => (
<TableRow key={row.rank}>
<TableCell className="translate-y-1 align-text-top">
{row.rank}
</TableCell>
<TableCell>
<div className="flex flex-col gap-2">
<p className="font-heading text-xl tracking-tight text-foreground">
{row.title}
</p>
<p className="text-xs font-semibold tracking-wide text-muted-foreground uppercase">
By {row.author}
</p>
</div>
</TableCell>
<TableCell>{row.published}</TableCell>
<TableCell>{row.pageviews}</TableCell>
<TableCell>{row.avgTime}</TableCell>
<TableCell className="text-right">
<DropdownMenu>
<DropdownMenuTrigger
render={<Button variant="ghost" size="icon-xs" />}
aria-label={`Open actions for ${row.title}`}
>
<MoreHorizontalIcon />
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>Edit</DropdownMenuItem>
<DropdownMenuItem>Publish</DropdownMenuItem>
<DropdownMenuItem variant="destructive">
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</CardContent>
<CardFooter className="justify-center">
{hasMoreRows ? (
<Button
type="button"
variant="outline"
onClick={handleLoadMore}
disabled={isLoadingMore}
>
Load more content{" "}
{isLoadingMore ? (
<Spinner data-icon="inline-end" />
) : (
<ArrowDownIcon data-icon="inline-end" />
)}
</Button>
) : null}
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,57 @@
"use client"
import * as React from "react"
import dynamic from "next/dynamic"
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/styles/base-sera/ui/card"
const TrafficOverviewContent = dynamic(
() => import("./traffic-overview").then((mod) => mod.TrafficOverview),
{
ssr: false,
loading: () => <TrafficOverviewFallback />,
}
)
export function TrafficOverviewDeferred({
className,
...props
}: React.ComponentProps<typeof Card>) {
return (
<div className={className}>
<TrafficOverviewContent {...props} />
</div>
)
}
function TrafficOverviewFallback() {
return (
<Card>
<CardHeader>
<CardTitle className="text-2xl">Traffic Overview</CardTitle>
<CardDescription>
Traffic for the last 30 days has increased by 12.4% compared to the
previous period.
</CardDescription>
</CardHeader>
<CardContent>
<div
aria-hidden="true"
className="flex h-82 w-full flex-col justify-end gap-6 overflow-hidden bg-muted/40 p-5"
>
<div className="h-px w-full bg-border" />
<div className="h-px w-full bg-border" />
<div className="h-px w-full bg-border" />
<div className="h-px w-full bg-border" />
<div className="h-px w-full bg-border" />
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,155 @@
"use client"
import { TrendingUpIcon } from "lucide-react"
import {
CartesianGrid,
Line,
LineChart,
ReferenceDot,
XAxis,
YAxis,
} from "recharts"
import { Badge } from "@/styles/base-sera/ui/badge"
import {
Card,
CardAction,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/styles/base-sera/ui/card"
import {
ChartContainer,
ChartTooltip,
ChartTooltipContent,
type ChartConfig,
} from "@/styles/base-sera/ui/chart"
const TRAFFIC_OVERVIEW_DATA = [
{ date: "2025-10-01", views: 2600, unique: 1600 },
{ date: "2025-10-04", views: 4500, unique: 3000 },
{ date: "2025-10-08", views: 3500, unique: 2500 },
{ date: "2025-10-10", views: 6400, unique: 4500 },
{ date: "2025-10-13", views: 5400, unique: 4000 },
{ date: "2025-10-15", views: 8300, unique: 6500 },
{ date: "2025-10-17", views: 7400, unique: 6000 },
{ date: "2025-10-18", views: 9240, unique: 7105 },
{ date: "2025-10-22", views: 7700, unique: 6400 },
{ date: "2025-10-26", views: 8800, unique: 7000 },
{ date: "2025-10-29", views: 9800, unique: 8400 },
]
const TRAFFIC_CHART_CONFIG = {
views: {
label: "Views",
theme: {
light: "var(--chart-5)",
dark: "var(--chart-1)",
},
},
unique: {
label: "Unique",
theme: {
light: "var(--chart-1)",
dark: "var(--chart-2)",
},
},
} satisfies ChartConfig
const X_AXIS_DATE_FORMATTER = new Intl.DateTimeFormat("en-US", {
month: "short",
day: "numeric",
timeZone: "UTC",
})
function formatYAxisTick(value: number) {
if (value === 0) {
return "0"
}
if (value % 1000 === 0) {
return `${value / 1000}k`
}
return `${value / 1000}k`
}
function formatXAxisTick(value: string) {
const date = new Date(`${value}T00:00:00Z`)
if (Number.isNaN(date.getTime())) {
return value
}
return X_AXIS_DATE_FORMATTER.format(date)
}
export function TrafficOverview({
...props
}: React.ComponentProps<typeof Card>) {
return (
<Card {...props}>
<CardHeader>
<CardTitle className="text-2xl">Traffic Overview</CardTitle>
<CardDescription>
Traffic for the last 30 days has increased by 12.4% compared to the
previous period.
</CardDescription>
</CardHeader>
<CardContent>
<ChartContainer config={TRAFFIC_CHART_CONFIG} className="h-82 w-full">
<LineChart data={TRAFFIC_OVERVIEW_DATA}>
<CartesianGrid
vertical={false}
strokeDasharray="3 6"
stroke="var(--border)"
/>
<XAxis
dataKey="date"
tickLine={false}
axisLine={false}
interval="preserveStartEnd"
tickMargin={10}
tickFormatter={formatXAxisTick}
/>
<YAxis
tickLine={false}
axisLine={false}
width={44}
domain={[0, 10000]}
ticks={[0, 2500, 5000, 7500, 10000]}
tickFormatter={formatYAxisTick}
hide
/>
<ChartTooltip content={<ChartTooltipContent />} />
<Line
type="linear"
dataKey="views"
stroke="var(--color-views)"
strokeWidth={2.2}
dot={false}
activeDot={{ r: 3.5, fill: "var(--color-views)" }}
/>
<Line
type="linear"
dataKey="unique"
stroke="var(--color-unique)"
strokeWidth={2}
strokeDasharray="4 6"
dot={false}
activeDot={false}
/>
<ReferenceDot
x="2025-10-18"
y={9240}
r={2.5}
fill="var(--color-views)"
stroke="var(--color-views)"
/>
</LineChart>
</ChartContainer>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,22 @@
import { Separator } from "@/styles/base-sera/ui/separator"
import { Demographics } from "./components/demographics"
import { MetricsGrid } from "./components/metrics-grid"
import { PreviewHeader } from "./components/preview-header"
import { TopEditorial } from "./components/top-editorial"
import { TrafficOverviewDeferred } from "./components/traffic-overview-deferred"
export function AudienceAnalytics() {
return (
<div className="preview theme-taupe @container/preview w-full flex-1 bg-muted pt-4 font-sans ring-1 ring-foreground/5 [--gap:--spacing(4)] sm:pt-0 md:[--gap:--spacing(6)] xl:[--gap:--spacing(8)] 2xl:py-8 **:[.container]:px-(--gap)">
<PreviewHeader />
<Separator className="hidden sm:block" />
<div className="container grid grid-cols-12 gap-(--gap) py-(--gap)">
<MetricsGrid />
<TrafficOverviewDeferred className="col-span-full md:col-span-6 lg:col-span-8" />
<Demographics className="col-span-full md:col-span-6 lg:col-span-4" />
<TopEditorial className="col-span-full" />
</div>
</div>
)
}

View File

@@ -0,0 +1,46 @@
import Image from "next/image"
import { cn } from "@/lib/utils"
export function ImagePreview() {
return (
<div className="mt-8 flex flex-col overflow-hidden md:hidden">
<ImagePreviewItem name="sera-01" />
<ImagePreviewItem name="sera-03" />
<ImagePreviewItem name="sera-02" />
<ImagePreviewItem name="sera-06" />
</div>
)
}
function ImagePreviewItem({
name,
className,
}: {
name: string
className?: string
}) {
return (
<div
className={cn(
"theme-taupe overflow-hidden bg-muted px-4 py-2 first:pt-4 last:pb-4",
className
)}
>
<Image
src={`/images/${name}-light.png`}
alt={name}
width={1440}
height={900}
className="dark:hidden"
/>
<Image
src={`/images/${name}-dark.png`}
alt={name}
width={1440}
height={900}
className="hidden dark:block"
/>
</div>
)
}

View File

@@ -0,0 +1,148 @@
"use client"
import * as React from "react"
import dynamic from "next/dynamic"
type LazyPreviewName =
| "articleDirectory"
| "emptyState"
| "editArticle"
| "mediaLibrary"
| "mediaLibraryTable"
const PREVIEW_MIN_HEIGHTS: Record<LazyPreviewName, number> = {
articleDirectory: 760,
emptyState: 560,
editArticle: 980,
mediaLibrary: 880,
mediaLibraryTable: 980,
}
const ArticleDirectoryPreview = dynamic(
() => import("../article-directory").then((mod) => mod.ArticleDirectory),
{
ssr: false,
loading: () => (
<PreviewPlaceholder minHeight={PREVIEW_MIN_HEIGHTS.articleDirectory} />
),
}
)
const EmptyStatePreview = dynamic(
() => import("../empty-state").then((mod) => mod.EmptyState),
{
ssr: false,
loading: () => (
<PreviewPlaceholder minHeight={PREVIEW_MIN_HEIGHTS.emptyState} />
),
}
)
const EditArticlePreview = dynamic(
() => import("../edit-article").then((mod) => mod.EditArticle),
{
ssr: false,
loading: () => (
<PreviewPlaceholder minHeight={PREVIEW_MIN_HEIGHTS.editArticle} />
),
}
)
const MediaLibraryPreview = dynamic(
() => import("../media-library").then((mod) => mod.MediaLibrary),
{
ssr: false,
loading: () => (
<PreviewPlaceholder minHeight={PREVIEW_MIN_HEIGHTS.mediaLibrary} />
),
}
)
const MediaLibraryTablePreview = dynamic(
() => import("../media-library-table").then((mod) => mod.MediaLibraryTable),
{
ssr: false,
loading: () => (
<PreviewPlaceholder minHeight={PREVIEW_MIN_HEIGHTS.mediaLibraryTable} />
),
}
)
const PREVIEW_COMPONENTS: Record<LazyPreviewName, React.ComponentType> = {
articleDirectory: ArticleDirectoryPreview,
emptyState: EmptyStatePreview,
editArticle: EditArticlePreview,
mediaLibrary: MediaLibraryPreview,
mediaLibraryTable: MediaLibraryTablePreview,
}
export function LazyPreview({ name }: { name: LazyPreviewName }) {
const containerRef = React.useRef<HTMLDivElement>(null)
const [shouldRender, setShouldRender] = React.useState(false)
const PreviewComponent = PREVIEW_COMPONENTS[name]
React.useEffect(() => {
if (shouldRender) {
return
}
const container = containerRef.current
if (!container || !("IntersectionObserver" in window)) {
setShouldRender(true)
return
}
const observer = new IntersectionObserver(
(entries) => {
if (!entries.some((entry) => entry.isIntersecting)) {
return
}
setShouldRender(true)
observer.disconnect()
},
{
rootMargin: "800px 0px",
}
)
observer.observe(container)
return () => observer.disconnect()
}, [shouldRender])
return (
<div ref={containerRef}>
{shouldRender ? (
<PreviewComponent />
) : (
<PreviewPlaceholder minHeight={PREVIEW_MIN_HEIGHTS[name]} />
)}
</div>
)
}
function PreviewPlaceholder({ minHeight }: { minHeight: number }) {
return (
<div
aria-hidden="true"
className="preview theme-taupe @container/preview w-full flex-1 bg-muted p-4 font-sans ring-1 ring-foreground/5 [--gap:--spacing(4)] sm:p-6 md:[--gap:--spacing(6)] xl:[--gap:--spacing(8)]"
style={{ minHeight }}
>
<div className="container flex flex-col gap-(--gap) py-(--gap)">
<div className="flex items-center justify-between gap-4">
<div className="flex flex-col gap-3">
<div className="h-5 w-44 bg-background/80" />
<div className="h-3 w-56 max-w-full bg-background/60" />
</div>
<div className="hidden h-8 w-28 bg-background/70 sm:block" />
</div>
<div className="grid grid-cols-1 gap-(--gap) md:grid-cols-3">
<div className="min-h-48 bg-background/70 md:col-span-2" />
<div className="min-h-48 bg-background/70" />
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,59 @@
"use client"
import * as React from "react"
import { cn } from "@/lib/utils"
const THEME_OPTIONS = [
{ label: "Taupe", value: "theme-taupe" },
{ label: "Neutral", value: "theme-neutral" },
{ label: "Stone", value: "theme-stone" },
{ label: "Zinc", value: "theme-zinc" },
{ label: "Mauve", value: "theme-mauve" },
{ label: "Olive", value: "theme-olive" },
{ label: "Mist", value: "theme-mist" },
] as const
const DEFAULT_THEME = "theme-taupe"
function applyThemeToPreviews(theme: string) {
const previewElements = document.querySelectorAll<HTMLElement>(".preview")
previewElements.forEach((element) => {
THEME_OPTIONS.forEach((option) => {
element.classList.remove(option.value)
})
element.classList.add(theme)
})
}
export function ThemeSwitcher() {
const [theme, setTheme] = React.useState<string>(DEFAULT_THEME)
React.useEffect(() => {
applyThemeToPreviews(theme)
}, [theme])
return (
<div className="fixed inset-x-0 bottom-8 z-50 flex justify-center px-4">
<div className="w-full max-w-[60vw] rounded-full border-0 bg-neutral-950/50 p-1.5 shadow-xl backdrop-blur-xl sm:max-w-fit">
<div className="no-scrollbar flex snap-x snap-mandatory items-center overflow-x-auto">
{THEME_OPTIONS.map((option) => (
<button
data-active={theme === option.value}
key={option.value}
type="button"
onClick={() => {
setTheme(option.value)
}}
className="shrink-0 snap-center rounded-full px-3 py-1.5 text-sm font-medium text-neutral-300 outline-hidden transition-colors select-none hover:text-neutral-100 data-active:bg-neutral-500 data-active:text-neutral-100"
>
{option.label}
</button>
))}
</div>
</div>
</div>
)
}

View File

@@ -0,0 +1,337 @@
"use client"
import {
AlignCenterIcon,
AlignLeftIcon,
AlignRightIcon,
BoldIcon,
ChevronDownIcon,
Code2Icon,
Heading1Icon,
Heading2Icon,
Heading3Icon,
ImageIcon,
ItalicIcon,
LinkIcon,
ListIcon,
ListOrderedIcon,
RedoIcon,
StrikethroughIcon,
TypeIcon,
UnderlineIcon,
UndoIcon,
} from "lucide-react"
import { Button } from "@/styles/base-sera/ui/button"
import {
ButtonGroup,
ButtonGroupSeparator,
} from "@/styles/base-sera/ui/button-group"
import {
Card,
CardContent,
CardHeader,
CardTitle,
} from "@/styles/base-sera/ui/card"
import { Checkbox } from "@/styles/base-sera/ui/checkbox"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/styles/base-sera/ui/dropdown-menu"
import {
Field,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSet,
} from "@/styles/base-sera/ui/field"
import { Input } from "@/styles/base-sera/ui/input"
import {
Progress,
ProgressLabel,
ProgressValue,
} from "@/styles/base-sera/ui/progress"
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/styles/base-sera/ui/select"
import { Textarea } from "@/styles/base-sera/ui/textarea"
type Milestone = {
name: string
complete: boolean
note?: string
}
const MILESTONES: Milestone[] = [
{
name: "Outline & Commissioning",
complete: true,
},
{
name: "First Draft Submitted",
complete: true,
},
{
name: "Review & Revisions",
complete: false,
note: "Waiting on editor",
},
{
name: "Final Copy Edit",
complete: false,
},
{
name: "Art Direction & Layout",
complete: false,
},
]
const ISSUES = [
{ label: "Spring Issue 2024", value: "spring-2024" },
{ label: "Summer Issue 2024", value: "summer-2024" },
{ label: "Autumn Issue 2024", value: "autumn-2024" },
{ label: "Winter Issue 2024", value: "winter-2024" },
]
export function EditorWorkspace() {
return (
<div className="grid grid-cols-1 items-start gap-6 xl:grid-cols-[minmax(0,1fr)_300px]">
<section className="flex flex-col border border-border/70 bg-background">
<div className="flex border-b p-2">
<ButtonGroup>
<DropdownMenu>
<DropdownMenuTrigger
render={
<Button variant="ghost" size="sm">
Normal Text
<ChevronDownIcon data-icon="inline-end" />
</Button>
}
/>
<DropdownMenuContent>
<DropdownMenuItem>
<TypeIcon />
Normal Text
</DropdownMenuItem>
<DropdownMenuItem>
<Heading1Icon />
Heading 1
</DropdownMenuItem>
<DropdownMenuItem>
<Heading2Icon />
Heading 2
</DropdownMenuItem>
<DropdownMenuItem>
<Heading3Icon />
Heading 3
</DropdownMenuItem>
<DropdownMenuItem>
<ListIcon />
Bullet List
</DropdownMenuItem>
<DropdownMenuItem>
<ListOrderedIcon />
Numbered List
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<ButtonGroupSeparator className="mx-2 data-vertical:h-4 data-vertical:self-center" />
<Button variant="ghost" size="icon-sm" aria-label="Bold">
<BoldIcon />
</Button>
<Button variant="ghost" size="icon-sm" aria-label="Italic">
<ItalicIcon />
</Button>
<Button variant="ghost" size="icon-sm" aria-label="Underline">
<UnderlineIcon />
</Button>
<Button
variant="ghost"
size="icon-sm"
aria-label="Strikethrough"
className="hidden md:flex"
>
<StrikethroughIcon />
</Button>
<Button
variant="ghost"
size="icon-sm"
aria-label="Code"
className="hidden md:flex"
>
<Code2Icon />
</Button>
<ButtonGroupSeparator className="mx-2 hidden md:flex data-vertical:h-4 data-vertical:self-center" />
<Button
variant="ghost"
size="icon-sm"
aria-label="Align Left"
className="hidden md:flex"
>
<AlignLeftIcon />
</Button>
<Button
variant="ghost"
size="icon-sm"
aria-label="Align Center"
className="hidden md:flex"
>
<AlignCenterIcon />
</Button>
<Button
variant="ghost"
size="icon-sm"
aria-label="Align Right"
className="hidden md:flex"
>
<AlignRightIcon />
</Button>
<ButtonGroupSeparator className="mx-2 hidden md:flex data-vertical:h-4 data-vertical:self-center" />
<Button
variant="ghost"
size="icon-sm"
aria-label="Link"
className="hidden md:flex"
>
<LinkIcon />
</Button>
<Button
variant="ghost"
size="icon-sm"
aria-label="Image"
className="hidden md:flex"
>
<ImageIcon />
</Button>
</ButtonGroup>
<ButtonGroup className="ml-auto">
<Button variant="ghost" size="icon-sm" aria-label="Undo">
<UndoIcon />
</Button>
<Button variant="ghost" size="icon-sm" aria-label="Redo">
<RedoIcon />
</Button>
</ButtonGroup>
</div>
<div className="mx-auto flex max-w-2xl flex-1 flex-col gap-8 px-10 py-10 leading-loose md:px-14 lg:py-18">
<h1 className="font-heading text-4xl leading-12 font-medium tracking-wide uppercase">
The Future of Sustainable Architecture
</h1>
<p>
As cities continue to expand at an unprecedented rate, the
architectural paradigm is shifting from mere expansion to
sustainable integration. The concrete jungles of the 20th century
are making way for structures that breathe, adapt, and give back to
their environments.
</p>
<p>
Historically, urban development has been a zero-sum game with
nature.
</p>
<h2 className="font-heading text-2xl tracking-wide uppercase">
The Living Building Challenge
</h2>
<p>
Sterling&apos;s latest project in downtown Seattle is a testament to
this new philosophy. &quot;We are no longer designing static
structures,&quot; Sterling explained during a recent site visit.
&quot;We are engineering localized ecosystems.&quot;
</p>
<p>
The building features a facade of responsive biomaterials that
adjust their porosity based on humidity and temperature,
significantly reducing the need for artificial climate control.
Rainwater is not merely channeled away but captured, filtered
through a series of integrated rooftop wetlands, and reused within
the building&apos;s greywater system.
</p>
<p className="text-sm text-muted-foreground">
This shift requires more than just innovative materials; it demands
a fundamental change in how we value space. Check with engineering
team for specific stats.
</p>
</div>
</section>
<aside className="grid grid-cols-12 gap-(--gap) xl:flex xl:flex-col">
<Card className="col-span-full md:col-span-6 lg:col-span-4">
<CardHeader>
<CardTitle>Article Details</CardTitle>
</CardHeader>
<CardContent>
<FieldGroup>
<Field>
<FieldLabel>Issue</FieldLabel>
<Select items={ISSUES} defaultValue="summer-2024">
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectGroup>
{ISSUES.map((issue) => (
<SelectItem key={issue.value} value={issue.value}>
{issue.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</Field>
<Field>
<FieldLabel>Author</FieldLabel>
<Input defaultValue="Elena Rostova" />
</Field>
</FieldGroup>
</CardContent>
</Card>
<Card className="col-span-full md:col-span-6 lg:col-span-4">
<CardHeader>
<CardTitle>Publication Flow</CardTitle>
</CardHeader>
<CardContent>
<FieldGroup>
<FieldSet>
<FieldLegend>Required Milestones</FieldLegend>
<Field>
{MILESTONES.map((milestone) => (
<Field key={milestone.name} orientation="horizontal">
<Checkbox
defaultChecked={milestone.complete}
name={milestone.name}
id={milestone.name}
/>
<FieldLabel htmlFor={milestone.name}>
{milestone.name}
</FieldLabel>
</Field>
))}
</Field>
</FieldSet>
<Field>
<FieldLabel>Add note for editor</FieldLabel>
<Textarea placeholder="This article needs to be revised for clarity and accuracy." />
</Field>
</FieldGroup>
</CardContent>
</Card>
<Card className="col-span-full lg:col-span-4">
<CardHeader>
<CardTitle>Word Count</CardTitle>
</CardHeader>
<CardContent>
<Progress value={70}>
<ProgressLabel>1,402 / 2,000 words</ProgressLabel>
<ProgressValue />
</Progress>
</CardContent>
</Card>
</aside>
</div>
)
}

View File

@@ -0,0 +1,45 @@
import { ArrowLeftIcon, ExternalLinkIcon } from "lucide-react"
import { Badge } from "@/styles/base-sera/ui/badge"
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
} from "@/styles/base-sera/ui/breadcrumb"
import { Button } from "@/styles/base-sera/ui/button"
import { ButtonGroup } from "@/styles/base-sera/ui/button-group"
export function PreviewHeader() {
return (
<header>
<div className="container flex flex-col items-center justify-center gap-(--gap) py-(--gap) sm:flex-row sm:justify-between">
<div className="flex flex-col gap-2 text-center sm:text-left">
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="#" className="flex items-center gap-1.5">
<ArrowLeftIcon className="size-3.5" />
Back to articles
</BreadcrumbLink>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
<h1 className="line-clamp-1 font-heading text-3xl tracking-wide uppercase md:text-3xl lg:text-4xl">
EDIT ARTICLE
</h1>
</div>
<ButtonGroup className="gap-2 md:gap-4">
<Badge title="2 minutes ago">Autosaved</Badge>
<ButtonGroup className="gap-2 md:gap-4">
<Button variant="link">
Preview
<ExternalLinkIcon data-icon="inline-end" />
</Button>
<Button>Submit Draft</Button>
</ButtonGroup>
</ButtonGroup>
</div>
</header>
)
}

View File

@@ -0,0 +1,16 @@
import { Separator } from "@/styles/base-sera/ui/separator"
import { EditorWorkspace } from "./components/editor-workspace"
import { PreviewHeader } from "./components/preview-header"
export function EditArticle() {
return (
<div className="preview theme-taupe @container/preview w-full flex-1 bg-muted pt-4 font-sans ring-1 ring-foreground/5 [--gap:--spacing(4)] sm:pt-0 md:[--gap:--spacing(6)] xl:[--gap:--spacing(8)] 2xl:py-8 **:[.container]:px-(--gap)">
<PreviewHeader />
<Separator className="hidden sm:block" />
<div className="container py-(--gap)">
<EditorWorkspace />
</div>
</div>
)
}

View File

@@ -0,0 +1,95 @@
import { FileTextIcon, PlusIcon } from "lucide-react"
import { Badge } from "@/styles/base-sera/ui/badge"
import { Button } from "@/styles/base-sera/ui/button"
import { Card, CardContent } from "@/styles/base-sera/ui/card"
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle,
} from "@/styles/base-sera/ui/empty"
import { Separator } from "@/styles/base-sera/ui/separator"
type Stage = {
id: string
label: string
description: string
dotClassName: string
}
const STAGES: Stage[] = [
{
id: "drafting",
label: "Drafting",
description:
"Start the writing process. Articles here are works in progress, visible only to editors and authors.",
dotClassName: "bg-amber-600",
},
{
id: "in-revision",
label: "In Revision",
description:
"Content undergoing editorial review. Track changes and word counts as pieces take shape.",
dotClassName: "bg-orange-700",
},
{
id: "final-edit",
label: "Final Edit",
description:
"The final polish before publication. Ensure all styling and factual checks are complete.",
dotClassName: "bg-foreground",
},
]
export function EmptyDirectory() {
return (
<Card className="py-24">
<CardContent className="flex flex-col items-center gap-10">
<Empty className="min-h-96">
<EmptyHeader>
<EmptyMedia
variant="icon"
className="size-14 rounded-full bg-muted/70 text-muted-foreground"
>
<FileTextIcon className="size-5" />
</EmptyMedia>
<EmptyTitle className="font-heading text-2xl tracking-normal normal-case">
A Blank Canvas
</EmptyTitle>
<EmptyDescription>
Your editorial directory is currently empty. Start building your
publication&apos;s next issue by drafting the first piece.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<Button>
<PlusIcon data-icon="inline-start" />
Create first article
</Button>
</EmptyContent>
</Empty>
<Separator className="max-w-2xl" />
<div className="grid w-full max-w-2xl grid-cols-1 gap-8 sm:grid-cols-3">
{STAGES.map((stage) => (
<div key={stage.id} className="flex flex-col gap-2">
<Badge>
<span
aria-hidden
className={`size-1.5 rounded-full ${stage.dotClassName}`}
/>
{stage.label}
</Badge>
<p className="text-xs leading-relaxed text-muted-foreground">
{stage.description}
</p>
</div>
))}
</div>
</CardContent>
</Card>
)
}

View File

@@ -0,0 +1,37 @@
import { ArrowLeftIcon, PlusIcon } from "lucide-react"
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
} from "@/styles/base-sera/ui/breadcrumb"
import { Button } from "@/styles/base-sera/ui/button"
export function PreviewHeader() {
return (
<header>
<div className="container flex flex-col items-center justify-center gap-(--gap) py-(--gap) sm:flex-row sm:justify-between">
<div className="flex flex-col gap-2 text-center sm:text-left">
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="#" className="flex items-center gap-1.5">
<ArrowLeftIcon className="size-3.5" />
Editorial Dashboard
</BreadcrumbLink>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
<h1 className="line-clamp-1 font-heading text-3xl tracking-wide uppercase md:text-3xl lg:text-4xl">
Article Directory
</h1>
</div>
<Button className="sm:ml-auto">
<PlusIcon data-icon="inline-start" />
New Article
</Button>
</div>
</header>
)
}

View File

@@ -0,0 +1,16 @@
import { Separator } from "@/styles/base-sera/ui/separator"
import { EmptyDirectory } from "./components/empty-directory"
import { PreviewHeader } from "./components/preview-header"
export function EmptyState() {
return (
<div className="preview theme-taupe @container/preview w-full flex-1 bg-muted pt-4 font-sans ring-1 ring-foreground/5 [--gap:--spacing(4)] sm:pt-0 md:[--gap:--spacing(6)] xl:[--gap:--spacing(8)] 2xl:py-8 **:[.container]:px-(--gap)">
<PreviewHeader />
<Separator className="hidden sm:block" />
<div className="container py-(--gap)">
<EmptyDirectory />
</div>
</div>
)
}

View File

@@ -0,0 +1,211 @@
"use client"
import * as React from "react"
import {
FileTextIcon,
ImageIcon,
MoreVerticalIcon,
SearchIcon,
VideoIcon,
} from "lucide-react"
import { Badge } from "@/styles/base-sera/ui/badge"
import { Button } from "@/styles/base-sera/ui/button"
import {
Card,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-sera/ui/card"
import { Checkbox } from "@/styles/base-sera/ui/checkbox"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/styles/base-sera/ui/dropdown-menu"
import {
InputGroup,
InputGroupAddon,
InputGroupInput,
} from "@/styles/base-sera/ui/input-group"
import {
Pagination,
PaginationContent,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@/styles/base-sera/ui/pagination"
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/styles/base-sera/ui/table"
import { ASSETS, type AssetType } from "../../media-library/data"
function AssetTypeIcon({
type,
className,
}: {
type: AssetType
className?: string
}) {
if (type === "MP4") {
return <VideoIcon className={className} />
}
if (type === "PDF") {
return <FileTextIcon className={className} />
}
return <ImageIcon className={className} />
}
export function AssetTable() {
const [selectedIds, setSelectedIds] = React.useState<Set<string>>(
new Set(["1"])
)
const toggleSelection = React.useCallback((id: string) => {
setSelectedIds((previous) => {
const next = new Set(previous)
if (next.has(id)) {
next.delete(id)
} else {
next.add(id)
}
return next
})
}, [])
return (
<Card>
<CardHeader>
<InputGroup className="w-full">
<InputGroupAddon>
<SearchIcon />
</InputGroupAddon>
<InputGroupInput placeholder="Search files, tags, or metadata..." />
</InputGroup>
</CardHeader>
<CardContent className="px-0 py-0">
<Table>
<TableHeader>
<TableRow>
<TableHead className="w-10 pl-6" aria-label="Select" />
<TableHead className="w-20" aria-label="Preview" />
<TableHead>Filename</TableHead>
<TableHead>Type</TableHead>
<TableHead>Dimensions</TableHead>
<TableHead>Size</TableHead>
<TableHead>Uploaded By</TableHead>
<TableHead>Date</TableHead>
<TableHead className="w-10 pr-6" aria-label="Actions" />
</TableRow>
</TableHeader>
<TableBody>
{ASSETS.map((asset) => {
const isSelected = selectedIds.has(asset.id)
return (
<TableRow
key={asset.id}
data-state={isSelected ? "selected" : undefined}
className="cursor-pointer"
onClick={() => toggleSelection(asset.id)}
>
<TableCell className="pl-6">
<Checkbox
checked={isSelected}
aria-label={`Select ${asset.name}`}
onClick={(event) => event.stopPropagation()}
onCheckedChange={() => toggleSelection(asset.id)}
/>
</TableCell>
<TableCell>
<div className="relative flex aspect-4/3 w-16 items-center justify-center bg-muted/60 ring-1 ring-border/70 ring-inset">
{asset.duration ? (
<span className="absolute right-1 bottom-1 bg-foreground/90 px-1 text-[0.5rem] font-semibold tracking-wider text-background">
{asset.duration}
</span>
) : null}
<AssetTypeIcon
type={asset.type}
className="size-4 text-muted-foreground/60"
/>
</div>
</TableCell>
<TableCell className="text-sm font-medium text-foreground">
{asset.name}
</TableCell>
<TableCell>
<Badge
variant="outline"
className="border px-2 py-0.5 text-[0.625rem]"
>
{asset.type}
</Badge>
</TableCell>
<TableCell className="text-sm">{asset.dimensions}</TableCell>
<TableCell className="text-sm">{asset.size}</TableCell>
<TableCell>{asset.uploadedBy}</TableCell>
<TableCell className="text-xs font-semibold tracking-wider text-muted-foreground uppercase">
{asset.date}
</TableCell>
<TableCell className="pr-6 text-right">
<DropdownMenu>
<DropdownMenuTrigger
render={<Button variant="ghost" size="icon-xs" />}
aria-label={`Open actions for ${asset.name}`}
onClick={(event) => event.stopPropagation()}
>
<MoreVerticalIcon />
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>Preview</DropdownMenuItem>
<DropdownMenuItem>Download</DropdownMenuItem>
<DropdownMenuItem variant="destructive">
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</TableCell>
</TableRow>
)
})}
</TableBody>
</Table>
</CardContent>
<CardFooter className="justify-center py-4">
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="#" text="" />
</PaginationItem>
<PaginationItem>
<PaginationLink href="#" isActive>
1
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">2</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">3</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationNext href="#" text="" />
</PaginationItem>
</PaginationContent>
</Pagination>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,233 @@
"use client"
import * as React from "react"
import { addDays, format } from "date-fns"
import { CalendarIcon, FilterIcon, XIcon } from "lucide-react"
import { type DateRange } from "react-day-picker"
import { Button } from "@/styles/base-sera/ui/button"
import { Calendar } from "@/styles/base-sera/ui/calendar"
import {
Card,
CardContent,
CardFooter,
CardHeader,
CardTitle,
} from "@/styles/base-sera/ui/card"
import { Checkbox } from "@/styles/base-sera/ui/checkbox"
import {
Combobox,
ComboboxChip,
ComboboxChips,
ComboboxChipsInput,
ComboboxContent,
ComboboxEmpty,
ComboboxItem,
ComboboxList,
ComboboxValue,
useComboboxAnchor,
} from "@/styles/base-sera/ui/combobox"
import {
Field,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSet,
} from "@/styles/base-sera/ui/field"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/styles/base-sera/ui/popover"
import { RadioGroup, RadioGroupItem } from "@/styles/base-sera/ui/radio-group"
import { Slider } from "@/styles/base-sera/ui/slider"
const FILE_TYPES = [
{
id: "images",
label: "Images (JPEG, PNG, WEBP)",
defaultChecked: true,
},
{
id: "video",
label: "Video (MP4, MOV)",
defaultChecked: false,
},
{
id: "documents",
label: "Documents (PDF)",
defaultChecked: false,
},
{
id: "audio",
label: "Audio (MP3, WAV)",
defaultChecked: false,
},
]
const DATE_OPTIONS = [
{ value: "any", label: "Any time" },
{ value: "24h", label: "Past 24 hours" },
{ value: "week", label: "Past week" },
{ value: "month", label: "Past month" },
]
const TAGS = [
"architecture",
"brutalism",
"ceramics",
"design-week",
"editorial",
"exterior",
"film",
"food",
"furniture",
"interior",
"kyoto",
"minimalism",
"print",
"sustainability",
"summer-issue",
"video",
] as const
export function FilterLibrary() {
const tagAnchor = useComboboxAnchor()
const [dateRange, setDateRange] = React.useState<DateRange | undefined>({
from: new Date(new Date().getFullYear(), new Date().getMonth(), 1),
to: addDays(
new Date(new Date().getFullYear(), new Date().getMonth(), 1),
21
),
})
return (
<Card>
<CardHeader className="border-b">
<CardTitle>Filter Library</CardTitle>
</CardHeader>
<CardContent>
<FieldGroup>
<FieldSet>
<FieldLegend>File Type</FieldLegend>
<Field>
{FILE_TYPES.map((type) => (
<Field key={type.id} orientation="horizontal">
<Checkbox id={type.id} defaultChecked={type.defaultChecked} />
<FieldLabel htmlFor={type.id}>{type.label}</FieldLabel>
</Field>
))}
</Field>
</FieldSet>
<FieldSet>
<FieldLegend>Date Uploaded</FieldLegend>
<RadioGroup defaultValue="any">
{DATE_OPTIONS.map((option) => (
<Field key={option.value} orientation="horizontal">
<RadioGroupItem
value={option.value}
id={`date-${option.value}`}
/>
<FieldLabel htmlFor={`date-${option.value}`}>
{option.label}
</FieldLabel>
</Field>
))}
</RadioGroup>
</FieldSet>
<Field>
<FieldLabel htmlFor="custom-range">Custom Range</FieldLabel>
<Popover>
<PopoverTrigger
render={
<Button
variant="outline"
id="custom-range"
className="w-full"
/>
}
>
<CalendarIcon data-icon="inline-start" />
{dateRange?.from ? (
dateRange.to ? (
<>
{format(dateRange.from, "LLL dd, y")} {" "}
{format(dateRange.to, "LLL dd, y")}
</>
) : (
format(dateRange.from, "LLL dd, y")
)
) : (
<span>Pick a date range</span>
)}
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="end">
<Calendar
mode="range"
defaultMonth={dateRange?.from}
selected={dateRange}
onSelect={setDateRange}
numberOfMonths={2}
/>
</PopoverContent>
</Popover>
</Field>
<FieldSet>
<FieldLegend>File Size</FieldLegend>
<div className="flex flex-col gap-3">
<div className="flex items-center justify-between text-xs font-medium tracking-wider text-muted-foreground uppercase">
<span>0 MB</span>
<span>500+ MB</span>
</div>
<Slider defaultValue={[0, 60]} max={100} step={1} />
<div className="flex items-center justify-between text-xs font-medium">
<span>Min: 0 MB</span>
<span>Max: 300 MB</span>
</div>
</div>
</FieldSet>
<FieldSet>
<FieldLegend>Tags</FieldLegend>
<Field>
<Combobox
multiple
autoHighlight
items={TAGS}
defaultValue={["architecture", "brutalism"]}
>
<ComboboxChips ref={tagAnchor}>
<ComboboxValue>
{(values) => (
<React.Fragment>
{values.map((value: string) => (
<ComboboxChip key={value}>{value}</ComboboxChip>
))}
<ComboboxChipsInput placeholder="Filter by tag..." />
</React.Fragment>
)}
</ComboboxValue>
</ComboboxChips>
<ComboboxContent anchor={tagAnchor}>
<ComboboxEmpty>No tags found.</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item} value={item}>
{item}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
</Field>
</FieldSet>
</FieldGroup>
</CardContent>
<CardFooter className="flex flex-col gap-2 border-t">
<Button className="w-full">Apply Filters</Button>
<Button variant="ghost" className="w-full">
Reset
</Button>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,47 @@
import { ArrowLeftIcon, SlidersHorizontalIcon, UploadIcon } from "lucide-react"
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
} from "@/styles/base-sera/ui/breadcrumb"
import { Button } from "@/styles/base-sera/ui/button"
import { ButtonGroup } from "@/styles/base-sera/ui/button-group"
export function PreviewHeader() {
return (
<header>
<div className="container flex flex-col items-center justify-center gap-(--gap) py-(--gap) sm:flex-row sm:justify-between">
<div className="flex flex-col gap-2 text-center sm:text-left">
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="#" className="flex items-center gap-1.5">
<ArrowLeftIcon className="size-3.5" />
Asset management
</BreadcrumbLink>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
<h1 className="line-clamp-1 font-heading text-3xl tracking-wide uppercase md:text-3xl lg:text-4xl">
Media Library
</h1>
</div>
<ButtonGroup className="gap-2 sm:ml-auto md:gap-4">
<Button
variant="outline"
className="bg-background hover:bg-background/80"
>
<SlidersHorizontalIcon data-icon="inline-start" />
Filters
</Button>
<Button>
<UploadIcon data-icon="inline-start" />
Upload Assets
</Button>
</ButtonGroup>
</div>
</header>
)
}

View File

@@ -0,0 +1,18 @@
import { Separator } from "@/styles/base-sera/ui/separator"
import { AssetTable } from "./components/asset-table"
import { FilterLibrary } from "./components/filter-library"
import { PreviewHeader } from "./components/preview-header"
export function MediaLibraryTable() {
return (
<div className="preview theme-taupe @container/preview w-full flex-1 bg-muted pt-4 font-sans ring-1 ring-foreground/5 [--gap:--spacing(4)] sm:pt-0 md:[--gap:--spacing(6)] xl:[--gap:--spacing(8)] 2xl:py-8 **:[.container]:px-(--gap)">
<PreviewHeader />
<Separator className="hidden sm:block" />
<div className="container grid grid-cols-1 items-start gap-(--gap) py-(--gap) xl:grid-cols-[minmax(0,1fr)_320px]">
<AssetTable />
<FilterLibrary />
</div>
</div>
)
}

View File

@@ -0,0 +1,110 @@
import {
DownloadIcon,
FileTextIcon,
ImageIcon,
PlusIcon,
VideoIcon,
} from "lucide-react"
import { Badge } from "@/styles/base-sera/ui/badge"
import { Button } from "@/styles/base-sera/ui/button"
import { Card, CardContent, CardFooter } from "@/styles/base-sera/ui/card"
import {
Item,
ItemContent,
ItemDescription,
ItemTitle,
} from "@/styles/base-sera/ui/item"
import { Separator } from "@/styles/base-sera/ui/separator"
import { type Asset, type AssetType } from "../data"
const TYPE_LABEL: Record<AssetType, string> = {
JPEG: "Image / JPEG",
PNG: "Image / PNG",
WEBP: "Image / WEBP",
MP4: "Video / MP4",
PDF: "Document / PDF",
}
export function AssetDetails({ asset }: { asset: Asset }) {
return (
<Card className="gap-0">
<CardContent className="flex flex-col gap-6">
<div className="flex aspect-5/4 items-center justify-center bg-muted/60 text-muted-foreground/60 ring-1 ring-border/70 ring-inset">
{asset.type === "MP4" ? (
<VideoIcon className="size-8" />
) : asset.type === "PDF" ? (
<FileTextIcon className="size-8" />
) : (
<ImageIcon className="size-8" />
)}
</div>
<h2 className="line-clamp-2 font-heading text-xl tracking-wide">
{asset.name}
</h2>
<Separator />
<dl className="flex flex-col gap-5 text-sm">
<div className="flex flex-col gap-1.5">
<dt className="text-[0.625rem] font-semibold tracking-widest text-muted-foreground uppercase">
Asset Type
</dt>
<dd>{TYPE_LABEL[asset.type]}</dd>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="flex flex-col gap-1.5">
<dt className="text-[0.625rem] font-semibold tracking-widest text-muted-foreground uppercase">
Dimensions
</dt>
<dd>{asset.dimensions}</dd>
</div>
<div className="flex flex-col gap-1.5">
<dt className="text-[0.625rem] font-semibold tracking-widest text-muted-foreground uppercase">
File Size
</dt>
<dd>{asset.size}</dd>
</div>
</div>
</dl>
<Separator />
<div className="flex flex-col gap-3">
<div className="flex items-center justify-between">
<h3 className="text-[0.625rem] font-semibold tracking-widest text-muted-foreground uppercase">
Tags
</h3>
<Button variant="ghost" size="icon-xs" aria-label="Add tag">
<PlusIcon />
</Button>
</div>
<div className="flex flex-wrap gap-x-4 gap-y-2">
{asset.tags.map((tag) => (
<Badge key={tag}>{tag}</Badge>
))}
</div>
</div>
<Separator />
<div className="flex flex-col gap-3">
<h3 className="text-[0.625rem] font-semibold tracking-widest text-muted-foreground uppercase">
Used In
</h3>
<div className="flex flex-col gap-2">
{asset.usedIn.map((usage) => (
<Item key={usage.title} variant="outline">
<ItemContent>
<ItemTitle>{usage.title}</ItemTitle>
<ItemDescription>{usage.role}</ItemDescription>
</ItemContent>
</Item>
))}
</div>
</div>
</CardContent>
<CardFooter className="mt-6 border-t pt-6">
<Button className="w-full">
<DownloadIcon data-icon="inline-start" />
Download
</Button>
</CardFooter>
</Card>
)
}

View File

@@ -0,0 +1,160 @@
"use client"
import {
CheckIcon,
FileTextIcon,
ImageIcon,
SearchIcon,
VideoIcon,
} from "lucide-react"
import { cn } from "@/lib/utils"
import { Badge } from "@/styles/base-sera/ui/badge"
import {
Card,
CardContent,
CardFooter,
CardHeader,
} from "@/styles/base-sera/ui/card"
import {
InputGroup,
InputGroupAddon,
InputGroupInput,
} from "@/styles/base-sera/ui/input-group"
import {
Pagination,
PaginationContent,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@/styles/base-sera/ui/pagination"
import { ASSETS, type Asset, type AssetType } from "../data"
function AssetTypeIcon({
type,
className,
}: {
type: AssetType
className?: string
}) {
if (type === "MP4") {
return <VideoIcon className={className} />
}
if (type === "PDF") {
return <FileTextIcon className={className} />
}
return <ImageIcon className={className} />
}
export function AssetGrid({
selectedId,
onSelect,
}: {
selectedId: string
onSelect: (id: string) => void
}) {
return (
<Card>
<CardHeader>
<InputGroup className="w-full">
<InputGroupAddon>
<SearchIcon />
</InputGroupAddon>
<InputGroupInput placeholder="Search files, tags, or metadata..." />
</InputGroup>
</CardHeader>
<CardContent>
<div className="grid grid-cols-2 gap-6 sm:grid-cols-3 lg:grid-cols-4">
{ASSETS.map((asset) => (
<AssetGridItem
key={asset.id}
asset={asset}
selected={asset.id === selectedId}
onSelect={() => onSelect(asset.id)}
/>
))}
</div>
</CardContent>
<CardFooter className="justify-center">
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="#" />
</PaginationItem>
<PaginationItem>
<PaginationLink href="#" isActive>
1
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">2</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">3</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationNext href="#" />
</PaginationItem>
</PaginationContent>
</Pagination>
</CardFooter>
</Card>
)
}
function AssetGridItem({
asset,
selected,
onSelect,
}: {
asset: Asset
selected: boolean
onSelect: () => void
}) {
return (
<button
type="button"
onClick={onSelect}
aria-pressed={selected}
className="group flex flex-col gap-2.5 text-left outline-none focus-visible:[&>div:first-child]:ring-2 focus-visible:[&>div:first-child]:ring-ring"
>
<div
className={cn(
"relative flex aspect-4/3 items-center justify-center bg-muted/60 ring-1 ring-border/70 transition-shadow ring-inset group-hover:ring-foreground/40",
selected && "ring-2 ring-foreground group-hover:ring-foreground"
)}
>
{selected ? (
<div className="absolute top-2 left-2 flex size-5 items-center justify-center bg-foreground text-background">
<CheckIcon className="size-3" />
</div>
) : null}
<Badge
variant="outline"
className="absolute top-2 right-2 border bg-background px-2 py-1 text-[0.625rem]"
>
{asset.type}
</Badge>
{asset.duration ? (
<Badge className="absolute bottom-2 left-2 bg-foreground px-2 py-1 text-background">
{asset.duration}
</Badge>
) : null}
<AssetTypeIcon
type={asset.type}
className="size-7 text-muted-foreground/60"
/>
</div>
<div className="flex flex-col gap-0.5 px-0.5">
<p className="line-clamp-1 text-sm font-medium">{asset.name}</p>
<p className="text-[0.625rem] font-semibold tracking-wider text-muted-foreground uppercase">
{asset.date} · {asset.size}
</p>
</div>
</button>
)
}

View File

@@ -0,0 +1,47 @@
import { ArrowLeftIcon, SlidersHorizontalIcon, UploadIcon } from "lucide-react"
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
} from "@/styles/base-sera/ui/breadcrumb"
import { Button } from "@/styles/base-sera/ui/button"
import { ButtonGroup } from "@/styles/base-sera/ui/button-group"
export function PreviewHeader() {
return (
<header>
<div className="container flex flex-col items-center justify-center gap-(--gap) py-(--gap) sm:flex-row sm:justify-between">
<div className="flex flex-col gap-2 text-center sm:text-left">
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="#" className="flex items-center gap-1.5">
<ArrowLeftIcon className="size-3.5" />
Asset management
</BreadcrumbLink>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
<h1 className="line-clamp-1 font-heading text-3xl tracking-wide uppercase md:text-3xl lg:text-4xl">
Media Library
</h1>
</div>
<ButtonGroup className="gap-2 sm:ml-auto md:gap-4">
<Button
variant="outline"
className="bg-background hover:bg-background/80"
>
<SlidersHorizontalIcon data-icon="inline-start" />
Filters
</Button>
<Button>
<UploadIcon data-icon="inline-start" />
Upload Assets
</Button>
</ButtonGroup>
</div>
</header>
)
}

View File

@@ -0,0 +1,188 @@
export type AssetType = "JPEG" | "PNG" | "WEBP" | "MP4" | "PDF"
export type Asset = {
id: string
name: string
date: string
size: string
type: AssetType
dimensions: string
duration?: string
uploadedBy: string
uploadedByInitials: string
uploadedOn: string
tags: string[]
usedIn: { title: string; role: string }[]
}
export const ASSETS: Asset[] = [
{
id: "1",
name: "brutalism-facade-01.jpg",
date: "Oct 24",
size: "4.2 MB",
type: "JPEG",
dimensions: "4000 × 3000",
uploadedBy: "Marcus Chen",
uploadedByInitials: "MC",
uploadedOn: "Oct 24, 2024",
tags: ["architecture", "brutalism", "exterior", "summer-issue"],
usedIn: [
{ title: "Brutalism's Second Act", role: "Cover Image" },
{ title: "Autumn Sartorial Code", role: "Inline Gallery" },
],
},
{
id: "2",
name: "brutalism-interior-raw.jpg",
date: "Oct 24",
size: "3.8 MB",
type: "JPEG",
dimensions: "3800 × 2850",
uploadedBy: "Marcus Chen",
uploadedByInitials: "MC",
uploadedOn: "Oct 24, 2024",
tags: ["architecture", "brutalism", "interior"],
usedIn: [{ title: "Brutalism's Second Act", role: "Inline Gallery" }],
},
{
id: "3",
name: "seattle-living-building-diagram.png",
date: "Oct 22",
size: "1.1 MB",
type: "PNG",
dimensions: "2000 × 1500",
uploadedBy: "Sarah Jenkins",
uploadedByInitials: "SJ",
uploadedOn: "Oct 22, 2024",
tags: ["diagram", "sustainability", "seattle"],
usedIn: [
{ title: "The Future of Sustainable Architecture", role: "Diagram" },
],
},
{
id: "4",
name: "interview-sofia-coppola-clip1.mp4",
date: "Oct 18",
size: "45.0 MB",
type: "MP4",
dimensions: "1920 × 1080",
duration: "0:45",
uploadedBy: "Emma Ross",
uploadedByInitials: "ER",
uploadedOn: "Oct 18, 2024",
tags: ["video", "interview", "film"],
usedIn: [{ title: "The Aesthetics of Isolation", role: "Featured Video" }],
},
{
id: "5",
name: "kyoto-kilns-pottery-detail.jpg",
date: "Oct 15",
size: "5.6 MB",
type: "JPEG",
dimensions: "4500 × 3000",
uploadedBy: "Marcus Chen",
uploadedByInitials: "MC",
uploadedOn: "Oct 15, 2024",
tags: ["ceramics", "kyoto", "craft"],
usedIn: [{ title: "Kyoto's Oldest Kilns", role: "Hero Image" }],
},
{
id: "6",
name: "copenhagen-design-week-street.jpg",
date: "Oct 12",
size: "3.2 MB",
type: "JPEG",
dimensions: "3600 × 2400",
uploadedBy: "Noah Bennett",
uploadedByInitials: "NB",
uploadedOn: "Oct 12, 2024",
tags: ["copenhagen", "design-week", "street"],
usedIn: [{ title: "Field Notes from Copenhagen", role: "Inline Gallery" }],
},
{
id: "7",
name: "minimalist-chair-render.webp",
date: "Oct 10",
size: "0.8 MB",
type: "WEBP",
dimensions: "2400 × 1600",
uploadedBy: "Claire Duval",
uploadedByInitials: "CD",
uploadedOn: "Oct 10, 2024",
tags: ["furniture", "minimalism", "render"],
usedIn: [{ title: "The New Vanguard", role: "Product Shot" }],
},
{
id: "8",
name: "autumn-issue-style-guide.pdf",
date: "Oct 05",
size: "12.4 MB",
type: "PDF",
dimensions: "N/A",
uploadedBy: "Emma Ross",
uploadedByInitials: "ER",
uploadedOn: "Oct 05, 2024",
tags: ["guidelines", "internal", "autumn"],
usedIn: [{ title: "Autumn Issue 2024", role: "Reference" }],
},
{
id: "9",
name: "milan-lighting-studio-visit.jpg",
date: "Oct 09",
size: "6.1 MB",
type: "JPEG",
dimensions: "5200 × 3466",
uploadedBy: "Claire Duval",
uploadedByInitials: "CD",
uploadedOn: "Oct 09, 2024",
tags: ["milan", "lighting", "studio"],
usedIn: [
{ title: "Milan's Most Elusive Lighting Designer", role: "Hero Image" },
],
},
{
id: "10",
name: "lisbon-culinary-scene-raw.webp",
date: "Oct 14",
size: "2.4 MB",
type: "WEBP",
dimensions: "3000 × 2000",
uploadedBy: "Amara Iqbal",
uploadedByInitials: "AI",
uploadedOn: "Oct 14, 2024",
tags: ["lisbon", "food", "editorial"],
usedIn: [
{ title: "Lisbon's Quiet Culinary Renaissance", role: "Inline Gallery" },
],
},
{
id: "11",
name: "print-magazine-covers-mo...",
date: "Sep 26",
size: "8.9 MB",
type: "PNG",
dimensions: "3200 × 2400",
uploadedBy: "Mina Okafor",
uploadedByInitials: "MO",
uploadedOn: "Sep 26, 2024",
tags: ["print", "magazine", "covers"],
usedIn: [{ title: "The Return of Print", role: "Cover Image" }],
},
{
id: "12",
name: "avant-garde-furniture-trailer.mp4",
date: "Sep 30",
size: "78.2 MB",
type: "MP4",
dimensions: "3840 × 2160",
duration: "1:12",
uploadedBy: "Tommy Rhodes",
uploadedByInitials: "TR",
uploadedOn: "Sep 30, 2024",
tags: ["video", "furniture", "trailer"],
usedIn: [
{ title: "Collecting the New Avant-Garde", role: "Featured Video" },
],
},
]

View File

@@ -0,0 +1,30 @@
"use client"
import * as React from "react"
import { Separator } from "@/styles/base-sera/ui/separator"
import { AssetDetails } from "./components/asset-details"
import { AssetGrid } from "./components/asset-grid"
import { PreviewHeader } from "./components/preview-header"
import { ASSETS } from "./data"
export function MediaLibrary() {
const [selectedId, setSelectedId] = React.useState<string>(ASSETS[0].id)
const selectedAsset = React.useMemo(
() => ASSETS.find((asset) => asset.id === selectedId) ?? ASSETS[0],
[selectedId]
)
return (
<div className="preview theme-taupe @container/preview w-full flex-1 bg-muted pt-4 font-sans ring-1 ring-foreground/5 [--gap:--spacing(4)] sm:pt-0 md:[--gap:--spacing(6)] xl:[--gap:--spacing(8)] 2xl:py-8 **:[.container]:px-(--gap)">
<PreviewHeader />
<Separator className="hidden sm:block" />
<div className="container grid grid-cols-1 items-start gap-(--gap) py-(--gap) xl:grid-cols-[minmax(0,1fr)_320px]">
<AssetGrid selectedId={selectedId} onSelect={setSelectedId} />
<AssetDetails asset={selectedAsset} />
</div>
</div>
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@@ -0,0 +1,72 @@
import { type Metadata } from "next"
import Link from "next/link"
import {
PageActions,
PageHeader,
PageHeaderDescription,
PageHeaderHeading,
} from "@/components/page-header"
import { Button } from "@/styles/radix-sera/ui/button"
import { AudienceAnalytics } from "./audience-analytics"
import { LazyPreview } from "./components/lazy-preview"
import "./style.css"
import { ArrowRightIcon } from "lucide-react"
import { ImagePreview } from "./components/image-preview"
const title = "Introducing Sera"
const description =
"Minimal. Editorial. Typographic. Underline Controls and Uppercase Headings. Shaped by Print Design Principles."
export const metadata: Metadata = {
title,
description,
openGraph: {
title,
description,
},
twitter: {
card: "summary_large_image",
title,
description,
},
}
export default function SeraPage() {
return (
<>
<PageHeader>
<PageHeaderHeading className="font-(family-name:--font-playfair-display) text-[2.875rem] tracking-tight!">
{title}
</PageHeaderHeading>
<PageHeaderDescription className="max-w-2xl text-pretty md:text-balance">
{description}
</PageHeaderDescription>
<PageActions className="**:[.container]:justify-start">
<Button asChild size="sm">
<Link href="/create?preset=b4xFeBLg4O">
Open in shadcn/create
<ArrowRightIcon data-icon="inline-end" />
</Link>
</Button>
</PageActions>
</PageHeader>
<ImagePreview />
<div className="container-wrapper hidden flex-1 flex-col section-soft px-0 md:flex md:px-2 md:py-12">
<div className="container flex flex-1 flex-col gap-10 px-0 3xl:max-w-[2000px] md:px-6">
<AudienceAnalytics />
<LazyPreview name="articleDirectory" />
<LazyPreview name="emptyState" />
<LazyPreview name="editArticle" />
<LazyPreview name="mediaLibrary" />
<LazyPreview name="mediaLibraryTable" />
</div>
</div>
{/* <ThemeSwitcher /> */}
</>
)
}

View File

@@ -0,0 +1,495 @@
@layer base {
.preview {
--font-sans: var(--font-noto-sans);
--font-heading: var(--font-playfair-display);
contain-intrinsic-size: auto 900px;
content-visibility: auto;
}
.theme-taupe {
--radius: 0;
--background: oklch(1 0 0);
--foreground: oklch(0.147 0.004 49.3);
--card: oklch(1 0 0);
--card-foreground: oklch(0.147 0.004 49.3);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.147 0.004 49.3);
--primary: oklch(0.214 0.009 43.1);
--primary-foreground: oklch(0.986 0.002 67.8);
--secondary: oklch(0.96 0.002 17.2);
--secondary-foreground: oklch(0.214 0.009 43.1);
--muted: oklch(0.96 0.002 17.2);
--muted-foreground: oklch(0.547 0.021 43.1);
--accent: oklch(0.96 0.002 17.2);
--accent-foreground: oklch(0.214 0.009 43.1);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0.005 34.3);
--input: oklch(0.922 0.005 34.3);
--ring: oklch(0.714 0.014 41.2);
--chart-1: oklch(0.868 0.007 39.5);
--chart-2: oklch(0.547 0.021 43.1);
--chart-3: oklch(0.438 0.017 39.3);
--chart-4: oklch(0.367 0.016 35.7);
--chart-5: oklch(0.268 0.011 36.5);
--sidebar: oklch(0.986 0.002 67.8);
--sidebar-foreground: oklch(0.147 0.004 49.3);
--sidebar-primary: oklch(0.214 0.009 43.1);
--sidebar-primary-foreground: oklch(0.986 0.002 67.8);
--sidebar-accent: oklch(0.96 0.002 17.2);
--sidebar-accent-foreground: oklch(0.214 0.009 43.1);
--sidebar-border: oklch(0.922 0.005 34.3);
--sidebar-ring: oklch(0.714 0.014 41.2);
.dark & {
--background: oklch(0.147 0.004 49.3);
--foreground: oklch(0.986 0.002 67.8);
--card: oklch(0.214 0.009 43.1);
--card-foreground: oklch(0.986 0.002 67.8);
--popover: oklch(0.214 0.009 43.1);
--popover-foreground: oklch(0.986 0.002 67.8);
--primary: oklch(0.922 0.005 34.3);
--primary-foreground: oklch(0.214 0.009 43.1);
--secondary: oklch(0.268 0.011 36.5);
--secondary-foreground: oklch(0.986 0.002 67.8);
--muted: oklch(0.268 0.011 36.5);
--muted-foreground: oklch(0.714 0.014 41.2);
--accent: oklch(0.268 0.011 36.5);
--accent-foreground: oklch(0.986 0.002 67.8);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.547 0.021 43.1);
--chart-1: oklch(0.868 0.007 39.5);
--chart-2: oklch(0.547 0.021 43.1);
--chart-3: oklch(0.438 0.017 39.3);
--chart-4: oklch(0.367 0.016 35.7);
--chart-5: oklch(0.268 0.011 36.5);
--sidebar: oklch(0.214 0.009 43.1);
--sidebar-foreground: oklch(0.986 0.002 67.8);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.986 0.002 67.8);
--sidebar-accent: oklch(0.268 0.011 36.5);
--sidebar-accent-foreground: oklch(0.986 0.002 67.8);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.547 0.021 43.1);
}
}
.theme-neutral {
--radius: 0;
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.87 0 0);
--chart-2: oklch(0.556 0 0);
--chart-3: oklch(0.439 0 0);
--chart-4: oklch(0.371 0 0);
--chart-5: oklch(0.269 0 0);
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
.dark & {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.87 0 0);
--chart-2: oklch(0.556 0 0);
--chart-3: oklch(0.439 0 0);
--chart-4: oklch(0.371 0 0);
--chart-5: oklch(0.269 0 0);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
}
}
.theme-stone {
--radius: 0;
--background: oklch(1 0 0);
--foreground: oklch(0.147 0.004 49.25);
--card: oklch(1 0 0);
--card-foreground: oklch(0.147 0.004 49.25);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.147 0.004 49.25);
--primary: oklch(0.216 0.006 56.043);
--primary-foreground: oklch(0.985 0.001 106.423);
--secondary: oklch(0.97 0.001 106.424);
--secondary-foreground: oklch(0.216 0.006 56.043);
--muted: oklch(0.97 0.001 106.424);
--muted-foreground: oklch(0.553 0.013 58.071);
--accent: oklch(0.97 0.001 106.424);
--accent-foreground: oklch(0.216 0.006 56.043);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.923 0.003 48.717);
--input: oklch(0.923 0.003 48.717);
--ring: oklch(0.709 0.01 56.259);
--chart-1: oklch(0.869 0.005 56.366);
--chart-2: oklch(0.553 0.013 58.071);
--chart-3: oklch(0.444 0.011 73.639);
--chart-4: oklch(0.374 0.01 67.558);
--chart-5: oklch(0.268 0.007 34.298);
--sidebar: oklch(0.985 0.001 106.423);
--sidebar-foreground: oklch(0.147 0.004 49.25);
--sidebar-primary: oklch(0.216 0.006 56.043);
--sidebar-primary-foreground: oklch(0.985 0.001 106.423);
--sidebar-accent: oklch(0.97 0.001 106.424);
--sidebar-accent-foreground: oklch(0.216 0.006 56.043);
--sidebar-border: oklch(0.923 0.003 48.717);
--sidebar-ring: oklch(0.709 0.01 56.259);
.dark & {
--background: oklch(0.147 0.004 49.25);
--foreground: oklch(0.985 0.001 106.423);
--card: oklch(0.216 0.006 56.043);
--card-foreground: oklch(0.985 0.001 106.423);
--popover: oklch(0.216 0.006 56.043);
--popover-foreground: oklch(0.985 0.001 106.423);
--primary: oklch(0.923 0.003 48.717);
--primary-foreground: oklch(0.216 0.006 56.043);
--secondary: oklch(0.268 0.007 34.298);
--secondary-foreground: oklch(0.985 0.001 106.423);
--muted: oklch(0.268 0.007 34.298);
--muted-foreground: oklch(0.709 0.01 56.259);
--accent: oklch(0.268 0.007 34.298);
--accent-foreground: oklch(0.985 0.001 106.423);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.553 0.013 58.071);
--chart-1: oklch(0.869 0.005 56.366);
--chart-2: oklch(0.553 0.013 58.071);
--chart-3: oklch(0.444 0.011 73.639);
--chart-4: oklch(0.374 0.01 67.558);
--chart-5: oklch(0.268 0.007 34.298);
--sidebar: oklch(0.216 0.006 56.043);
--sidebar-foreground: oklch(0.985 0.001 106.423);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0.001 106.423);
--sidebar-accent: oklch(0.268 0.007 34.298);
--sidebar-accent-foreground: oklch(0.985 0.001 106.423);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.553 0.013 58.071);
}
}
.theme-zinc {
--radius: 0;
--background: oklch(1 0 0);
--foreground: oklch(0.141 0.005 285.823);
--card: oklch(1 0 0);
--card-foreground: oklch(0.141 0.005 285.823);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.141 0.005 285.823);
--primary: oklch(0.21 0.006 285.885);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.967 0.001 286.375);
--secondary-foreground: oklch(0.21 0.006 285.885);
--muted: oklch(0.967 0.001 286.375);
--muted-foreground: oklch(0.552 0.016 285.938);
--accent: oklch(0.967 0.001 286.375);
--accent-foreground: oklch(0.21 0.006 285.885);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.92 0.004 286.32);
--input: oklch(0.92 0.004 286.32);
--ring: oklch(0.705 0.015 286.067);
--chart-1: oklch(0.871 0.006 286.286);
--chart-2: oklch(0.552 0.016 285.938);
--chart-3: oklch(0.442 0.017 285.786);
--chart-4: oklch(0.37 0.013 285.805);
--chart-5: oklch(0.274 0.006 286.033);
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.141 0.005 285.823);
--sidebar-primary: oklch(0.21 0.006 285.885);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.967 0.001 286.375);
--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
--sidebar-border: oklch(0.92 0.004 286.32);
--sidebar-ring: oklch(0.705 0.015 286.067);
.dark & {
--background: oklch(0.141 0.005 285.823);
--foreground: oklch(0.985 0 0);
--card: oklch(0.21 0.006 285.885);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.21 0.006 285.885);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.92 0.004 286.32);
--primary-foreground: oklch(0.21 0.006 285.885);
--secondary: oklch(0.274 0.006 286.033);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.274 0.006 286.033);
--muted-foreground: oklch(0.705 0.015 286.067);
--accent: oklch(0.274 0.006 286.033);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.552 0.016 285.938);
--chart-1: oklch(0.871 0.006 286.286);
--chart-2: oklch(0.552 0.016 285.938);
--chart-3: oklch(0.442 0.017 285.786);
--chart-4: oklch(0.37 0.013 285.805);
--chart-5: oklch(0.274 0.006 286.033);
--sidebar: oklch(0.21 0.006 285.885);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.274 0.006 286.033);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.552 0.016 285.938);
}
}
.theme-mauve {
--radius: 0;
--background: oklch(1 0 0);
--foreground: oklch(0.145 0.008 326);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0.008 326);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0.008 326);
--primary: oklch(0.212 0.019 322.12);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.96 0.003 325.6);
--secondary-foreground: oklch(0.212 0.019 322.12);
--muted: oklch(0.96 0.003 325.6);
--muted-foreground: oklch(0.542 0.034 322.5);
--accent: oklch(0.96 0.003 325.6);
--accent-foreground: oklch(0.212 0.019 322.12);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0.005 325.62);
--input: oklch(0.922 0.005 325.62);
--ring: oklch(0.711 0.019 323.02);
--chart-1: oklch(0.865 0.012 325.68);
--chart-2: oklch(0.542 0.034 322.5);
--chart-3: oklch(0.435 0.029 321.78);
--chart-4: oklch(0.364 0.029 323.89);
--chart-5: oklch(0.263 0.024 320.12);
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0.008 326);
--sidebar-primary: oklch(0.212 0.019 322.12);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.96 0.003 325.6);
--sidebar-accent-foreground: oklch(0.212 0.019 322.12);
--sidebar-border: oklch(0.922 0.005 325.62);
--sidebar-ring: oklch(0.711 0.019 323.02);
.dark & {
--background: oklch(0.145 0.008 326);
--foreground: oklch(0.985 0 0);
--card: oklch(0.212 0.019 322.12);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.212 0.019 322.12);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0.005 325.62);
--primary-foreground: oklch(0.212 0.019 322.12);
--secondary: oklch(0.263 0.024 320.12);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.263 0.024 320.12);
--muted-foreground: oklch(0.711 0.019 323.02);
--accent: oklch(0.263 0.024 320.12);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.542 0.034 322.5);
--chart-1: oklch(0.865 0.012 325.68);
--chart-2: oklch(0.542 0.034 322.5);
--chart-3: oklch(0.435 0.029 321.78);
--chart-4: oklch(0.364 0.029 323.89);
--chart-5: oklch(0.263 0.024 320.12);
--sidebar: oklch(0.212 0.019 322.12);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.263 0.024 320.12);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.542 0.034 322.5);
}
}
.theme-olive {
--radius: 0;
--background: oklch(1 0 0);
--foreground: oklch(0.153 0.006 107.1);
--card: oklch(1 0 0);
--card-foreground: oklch(0.153 0.006 107.1);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.153 0.006 107.1);
--primary: oklch(0.228 0.013 107.4);
--primary-foreground: oklch(0.988 0.003 106.5);
--secondary: oklch(0.966 0.005 106.5);
--secondary-foreground: oklch(0.228 0.013 107.4);
--muted: oklch(0.966 0.005 106.5);
--muted-foreground: oklch(0.58 0.031 107.3);
--accent: oklch(0.966 0.005 106.5);
--accent-foreground: oklch(0.228 0.013 107.4);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.93 0.007 106.5);
--input: oklch(0.93 0.007 106.5);
--ring: oklch(0.737 0.021 106.9);
--chart-1: oklch(0.88 0.011 106.6);
--chart-2: oklch(0.58 0.031 107.3);
--chart-3: oklch(0.466 0.025 107.3);
--chart-4: oklch(0.394 0.023 107.4);
--chart-5: oklch(0.286 0.016 107.4);
--sidebar: oklch(0.988 0.003 106.5);
--sidebar-foreground: oklch(0.153 0.006 107.1);
--sidebar-primary: oklch(0.228 0.013 107.4);
--sidebar-primary-foreground: oklch(0.988 0.003 106.5);
--sidebar-accent: oklch(0.966 0.005 106.5);
--sidebar-accent-foreground: oklch(0.228 0.013 107.4);
--sidebar-border: oklch(0.93 0.007 106.5);
--sidebar-ring: oklch(0.737 0.021 106.9);
.dark & {
--background: oklch(0.153 0.006 107.1);
--foreground: oklch(0.988 0.003 106.5);
--card: oklch(0.228 0.013 107.4);
--card-foreground: oklch(0.988 0.003 106.5);
--popover: oklch(0.228 0.013 107.4);
--popover-foreground: oklch(0.988 0.003 106.5);
--primary: oklch(0.93 0.007 106.5);
--primary-foreground: oklch(0.228 0.013 107.4);
--secondary: oklch(0.286 0.016 107.4);
--secondary-foreground: oklch(0.988 0.003 106.5);
--muted: oklch(0.286 0.016 107.4);
--muted-foreground: oklch(0.737 0.021 106.9);
--accent: oklch(0.286 0.016 107.4);
--accent-foreground: oklch(0.988 0.003 106.5);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.58 0.031 107.3);
--chart-1: oklch(0.88 0.011 106.6);
--chart-2: oklch(0.58 0.031 107.3);
--chart-3: oklch(0.466 0.025 107.3);
--chart-4: oklch(0.394 0.023 107.4);
--chart-5: oklch(0.286 0.016 107.4);
--sidebar: oklch(0.228 0.013 107.4);
--sidebar-foreground: oklch(0.988 0.003 106.5);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.988 0.003 106.5);
--sidebar-accent: oklch(0.286 0.016 107.4);
--sidebar-accent-foreground: oklch(0.988 0.003 106.5);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.58 0.031 107.3);
}
}
.theme-mist {
--radius: 0;
--background: oklch(1 0 0);
--foreground: oklch(0.148 0.004 228.8);
--card: oklch(1 0 0);
--card-foreground: oklch(0.148 0.004 228.8);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.148 0.004 228.8);
--primary: oklch(0.218 0.008 223.9);
--primary-foreground: oklch(0.987 0.002 197.1);
--secondary: oklch(0.963 0.002 197.1);
--secondary-foreground: oklch(0.218 0.008 223.9);
--muted: oklch(0.963 0.002 197.1);
--muted-foreground: oklch(0.56 0.021 213.5);
--accent: oklch(0.963 0.002 197.1);
--accent-foreground: oklch(0.218 0.008 223.9);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.925 0.005 214.3);
--input: oklch(0.925 0.005 214.3);
--ring: oklch(0.723 0.014 214.4);
--chart-1: oklch(0.872 0.007 219.6);
--chart-2: oklch(0.56 0.021 213.5);
--chart-3: oklch(0.45 0.017 213.2);
--chart-4: oklch(0.378 0.015 216);
--chart-5: oklch(0.275 0.011 216.9);
--sidebar: oklch(0.987 0.002 197.1);
--sidebar-foreground: oklch(0.148 0.004 228.8);
--sidebar-primary: oklch(0.218 0.008 223.9);
--sidebar-primary-foreground: oklch(0.987 0.002 197.1);
--sidebar-accent: oklch(0.963 0.002 197.1);
--sidebar-accent-foreground: oklch(0.218 0.008 223.9);
--sidebar-border: oklch(0.925 0.005 214.3);
--sidebar-ring: oklch(0.723 0.014 214.4);
.dark & {
--background: oklch(0.148 0.004 228.8);
--foreground: oklch(0.987 0.002 197.1);
--card: oklch(0.218 0.008 223.9);
--card-foreground: oklch(0.987 0.002 197.1);
--popover: oklch(0.218 0.008 223.9);
--popover-foreground: oklch(0.987 0.002 197.1);
--primary: oklch(0.925 0.005 214.3);
--primary-foreground: oklch(0.218 0.008 223.9);
--secondary: oklch(0.275 0.011 216.9);
--secondary-foreground: oklch(0.987 0.002 197.1);
--muted: oklch(0.275 0.011 216.9);
--muted-foreground: oklch(0.723 0.014 214.4);
--accent: oklch(0.275 0.011 216.9);
--accent-foreground: oklch(0.987 0.002 197.1);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.56 0.021 213.5);
--chart-1: oklch(0.872 0.007 219.6);
--chart-2: oklch(0.56 0.021 213.5);
--chart-3: oklch(0.45 0.017 213.2);
--chart-4: oklch(0.378 0.015 216);
--chart-5: oklch(0.275 0.011 216.9);
--sidebar: oklch(0.218 0.008 223.9);
--sidebar-foreground: oklch(0.987 0.002 197.1);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.987 0.002 197.1);
--sidebar-accent: oklch(0.275 0.011 216.9);
--sidebar-accent-foreground: oklch(0.987 0.002 197.1);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.56 0.021 213.5);
}
}
}
@utility font-heading {
font-family: var(--font-serif);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@@ -1,6 +1,7 @@
import { getAllBlockIds } from "@/lib/blocks"
import { registryCategories } from "@/lib/categories"
import { BlockDisplay } from "@/components/block-display"
import { registryCategories } from "@/registry/registry-categories"
import { getActiveStyle } from "@/registry/_legacy-styles"
export const revalidate = false
export const dynamic = "force-static"
@@ -17,13 +18,16 @@ export default async function BlocksPage({
}: {
params: Promise<{ categories?: string[] }>
}) {
const { categories = [] } = await params
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} />
<BlockDisplay name={name} key={name} styleName={activeStyle.name} />
))}
</div>
)

View File

@@ -1,4 +1,4 @@
import { Metadata } from "next"
import { type Metadata } from "next"
import Link from "next/link"
import { Announcement } from "@/components/announcement"
@@ -56,7 +56,7 @@ export default function BlocksLayout({
<a href="#blocks">Browse Blocks</a>
</Button>
<Button asChild variant="ghost" size="sm">
<Link href="/docs/blocks">Add a block</Link>
<Link href="/docs/components">View Components</Link>
</Button>
</PageActions>
</PageHeader>
@@ -71,7 +71,7 @@ export default function BlocksLayout({
<Link href="/blocks/sidebar">Browse all blocks</Link>
</Button>
</PageNav>
<div className="container-wrapper section-soft flex-1 md:py-12">
<div className="container-wrapper flex-1 section-soft md:py-12">
<div className="container">{children}</div>
</div>
</>

View File

@@ -1,6 +1,7 @@
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"
@@ -15,10 +16,12 @@ const FEATURED_BLOCKS = [
]
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} />
<BlockDisplay name={name} key={name} styleName={activeStyle.name} />
))}
<div className="container-wrapper">
<div className="container flex justify-center py-6">

View File

@@ -2,7 +2,12 @@ import * as React from "react"
import { notFound } from "next/navigation"
import { cn } from "@/lib/utils"
import { ChartDisplay } from "@/components/chart-display"
import {
ChartDisplay,
getCachedRegistryItem,
getChartHighlightedCode,
} from "@/components/chart-display"
import { getActiveStyle } from "@/registry/_legacy-styles"
import { charts } from "@/app/(app)/charts/charts"
export const revalidate = false
@@ -41,6 +46,27 @@ export default async function ChartPage({ params }: ChartPageProps) {
const chartType = type as ChartType
const chartList = charts[chartType]
const activeStyle = await getActiveStyle()
// Prefetch all chart data in parallel for better performance.
// Charts are rendered via iframes, so we only need the metadata and highlighted code.
const chartDataPromises = chartList.map(async (chart) => {
const registryItem = await getCachedRegistryItem(chart.id, activeStyle.name)
if (!registryItem) return null
const highlightedCode = await getChartHighlightedCode(
registryItem.files?.[0]?.content ?? ""
)
if (!highlightedCode) return null
return {
...registryItem,
highlightedCode,
fullWidth: chart.fullWidth,
}
})
const prefetchedCharts = await Promise.all(chartDataPromises)
return (
<div className="grid flex-1 gap-12 lg:gap-24">
@@ -49,15 +75,14 @@ export default async function ChartPage({ params }: ChartPageProps) {
</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]
const chart = prefetchedCharts[index]
return chart ? (
<ChartDisplay
key={chart.id}
name={chart.id}
key={chart.name}
chart={chart}
style={activeStyle.name}
className={cn(chart.fullWidth && "md:col-span-2 lg:col-span-3")}
>
<chart.component />
</ChartDisplay>
/>
) : (
<div
key={`empty-${index}`}

View File

@@ -1,4 +1,4 @@
import * as React from "react"
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"

View File

@@ -1,4 +1,4 @@
import { Metadata } from "next"
import { type Metadata } from "next"
import Link from "next/link"
import { Announcement } from "@/components/announcement"
@@ -63,9 +63,8 @@ export default function ChartsLayout({
</PageHeader>
<PageNav id="charts">
<ChartsNav />
<ThemeSelector className="mr-4 hidden md:flex" />
</PageNav>
<div className="container-wrapper section-soft flex-1">
<div className="container-wrapper flex-1">
<div className="container pb-6">
<section className="theme-container">{children}</section>
</div>

View File

@@ -1,4 +1,4 @@
import { Metadata } from "next"
import { type Metadata } from "next"
import Link from "next/link"
import { Announcement } from "@/components/announcement"
@@ -62,7 +62,7 @@ export default function ColorsLayout({
<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" />
<ColorsNav className="flex-1 overflow-hidden [&>a:first-child]:text-primary" />
</div>
</div>
</div>

View File

@@ -0,0 +1,104 @@
"use client"
import { MENU_ACCENTS, type MenuAccentValue } from "@/registry/config"
import { LockButton } from "@/app/(app)/create/components/lock-button"
import {
Picker,
PickerContent,
PickerGroup,
PickerRadioGroup,
PickerRadioItem,
PickerTrigger,
} from "@/app/(app)/create/components/picker"
import { useDesignSystemSearchParams } from "@/app/(app)/create/lib/search-params"
export function MenuAccentPicker({
isMobile,
anchorRef,
}: {
isMobile: boolean
anchorRef: React.RefObject<HTMLDivElement | null>
}) {
const [params, setParams] = useDesignSystemSearchParams()
const currentAccent = MENU_ACCENTS.find(
(accent) => accent.value === params.menuAccent
)
return (
<div className="group/picker relative pr-3 md:pr-0">
<Picker>
<PickerTrigger>
<div className="flex flex-col justify-start text-left">
<div className="text-xs text-muted-foreground">Menu Accent</div>
<div className="text-sm font-medium text-foreground">
{currentAccent?.label}
</div>
</div>
<div className="pointer-events-none absolute top-1/2 right-4 flex size-4 -translate-y-1/2 items-center justify-center text-base text-foreground select-none md:right-2.5">
<svg
xmlns="http://www.w3.org/2000/svg"
width="128"
height="128"
viewBox="0 0 24 24"
fill="none"
className="size-4 text-foreground"
>
<path
d="M19 12.1294L12.9388 18.207C11.1557 19.9949 10.2641 20.8889 9.16993 20.9877C8.98904 21.0041 8.80705 21.0041 8.62616 20.9877C7.53195 20.8889 6.64039 19.9949 4.85726 18.207L2.83687 16.1811C1.72104 15.0622 1.72104 13.2482 2.83687 12.1294M19 12.1294L10.9184 4.02587M19 12.1294H2.83687M10.9184 4.02587L2.83687 12.1294M10.9184 4.02587L8.89805 2"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
data-accent={currentAccent?.value}
className="fill-muted-foreground/30 data-[accent=bold]:fill-foreground"
></path>
<path
d="M22 20C22 21.1046 21.1046 22 20 22C18.8954 22 18 21.1046 18 20C18 18.8954 20 17 20 17C20 17 22 18.8954 22 20Z"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
data-accent={currentAccent?.value}
className="fill-muted-foreground/30 data-[accent=bold]:fill-foreground"
></path>
</svg>
</div>
</PickerTrigger>
<PickerContent
anchor={isMobile ? anchorRef : undefined}
side={isMobile ? "top" : "right"}
align={isMobile ? "center" : "start"}
>
<PickerRadioGroup
value={currentAccent?.value}
onValueChange={(value) => {
setParams({ menuAccent: value as MenuAccentValue })
}}
>
<PickerGroup>
{MENU_ACCENTS.map((accent) => (
<PickerRadioItem
key={accent.value}
value={accent.value}
closeOnClick={isMobile}
disabled={
accent.value === "bold" &&
(params.menuColor === "default-translucent" ||
params.menuColor === "inverted-translucent")
}
>
{accent.label}
</PickerRadioItem>
))}
</PickerGroup>
</PickerRadioGroup>
</PickerContent>
</Picker>
<LockButton
param="menuAccent"
className="absolute top-1/2 right-8 -translate-y-1/2"
/>
</div>
)
}

View File

@@ -0,0 +1,88 @@
"use client"
import Script from "next/script"
import { type RegistryItem } from "shadcn/schema"
import {
Command,
CommandDialog,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
} from "@/styles/base-nova/ui/command"
import { useActionMenu } from "@/app/(app)/create/hooks/use-action-menu"
export const CMD_K_FORWARD_TYPE = "cmd-k-forward"
export function ActionMenu({
itemsByBase,
}: {
itemsByBase: Record<string, Pick<RegistryItem, "name" | "title" | "type">[]>
}) {
const {
activeRegistryName,
getCommandValue,
groups,
handleSelect,
open,
setOpen,
} = useActionMenu(itemsByBase)
return (
<CommandDialog open={open} onOpenChange={setOpen} className="animate-none!">
<Command loop>
<CommandInput placeholder="Search" />
<CommandList>
<CommandEmpty>No items found.</CommandEmpty>
<CommandGroup>
{groups.map((group) =>
group.items.map((item) => (
<CommandItem
key={item.id}
value={getCommandValue(item)}
data-checked={activeRegistryName === item.registryName}
className="px-2"
onSelect={() => {
handleSelect(item.registryName)
}}
>
{item.label}
</CommandItem>
))
)}
</CommandGroup>
</CommandList>
</Command>
</CommandDialog>
)
}
export function ActionMenuScript() {
return (
<Script
id="design-system-listener"
strategy="beforeInteractive"
dangerouslySetInnerHTML={{
__html: `
(function() {
// Forward Cmd/Ctrl + K (and P) to parent
document.addEventListener('keydown', function(e) {
if ((e.key === 'k' || e.key === 'p') && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
if (window.parent && window.parent !== window) {
window.parent.postMessage({
type: '${CMD_K_FORWARD_TYPE}',
key: e.key
}, '*');
}
}
});
})();
`,
}}
/>
)
}

View File

@@ -0,0 +1,86 @@
"use client"
import * as React from "react"
import { useMounted } from "@/hooks/use-mounted"
import { BASE_COLORS, type BaseColorName } from "@/registry/config"
import { LockButton } from "@/app/(app)/create/components/lock-button"
import {
Picker,
PickerContent,
PickerGroup,
PickerRadioGroup,
PickerRadioItem,
PickerTrigger,
} from "@/app/(app)/create/components/picker"
import { useDesignSystemSearchParams } from "@/app/(app)/create/lib/search-params"
export function BaseColorPicker({
isMobile,
anchorRef,
}: {
isMobile: boolean
anchorRef: React.RefObject<HTMLDivElement | null>
}) {
const mounted = useMounted()
const [params, setParams] = useDesignSystemSearchParams()
const currentBaseColor = React.useMemo(
() => BASE_COLORS.find((baseColor) => baseColor.name === params.baseColor),
[params.baseColor]
)
return (
<div className="group/picker relative">
<Picker>
<PickerTrigger>
<div className="flex flex-col justify-start text-left">
<div className="text-xs text-muted-foreground">Base Color</div>
<div className="text-sm font-medium text-foreground">
{currentBaseColor?.title}
</div>
</div>
{mounted && (
<div
style={
{
"--color":
currentBaseColor?.cssVars?.dark?.["muted-foreground"],
} as React.CSSProperties
}
className="pointer-events-none absolute top-1/2 right-4 size-4 -translate-y-1/2 rounded-full bg-(--color) select-none md:right-2.5"
/>
)}
</PickerTrigger>
<PickerContent
anchor={isMobile ? anchorRef : undefined}
side={isMobile ? "top" : "right"}
align={isMobile ? "center" : "start"}
>
<PickerRadioGroup
value={currentBaseColor?.name}
onValueChange={(value) => {
setParams({ baseColor: value as BaseColorName })
}}
>
<PickerGroup>
{BASE_COLORS.map((baseColor) => (
<PickerRadioItem
key={baseColor.name}
value={baseColor.name}
closeOnClick={isMobile}
>
{baseColor.title}
</PickerRadioItem>
))}
</PickerGroup>
</PickerRadioGroup>
</PickerContent>
</Picker>
<LockButton
param="baseColor"
className="absolute top-1/2 right-8 -translate-y-1/2"
/>
</div>
)
}

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