@thorprovider/storefront 0.3.1 → 0.4.0-mvp.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/README.md +321 -152
  2. package/VENDOR.md +69 -0
  3. package/assets/openspec/config.yaml +38 -0
  4. package/assets/templates/AGENTS.md +76 -0
  5. package/assets/templates/app/app/[[...slug]]/page.tsx +54 -2
  6. package/assets/templates/app/app/[[...slug]]/renderer.tsx +13 -2
  7. package/assets/templates/app/app/globals.css +5 -8
  8. package/assets/templates/app/app/layout.tsx +17 -7
  9. package/assets/templates/app/app/robots.ts +19 -0
  10. package/assets/templates/app/app/sitemap.ts +71 -0
  11. package/assets/templates/app/lib/__STOREFRONT__/actions.ts +612 -0
  12. package/assets/templates/app/lib/__STOREFRONT__/cart-state.ts +66 -0
  13. package/assets/templates/app/lib/__STOREFRONT__/catalog.ts +50 -57
  14. package/assets/templates/app/lib/__STOREFRONT__/commerce.ts +679 -0
  15. package/assets/templates/app/lib/__STOREFRONT__/composition.ts +26 -0
  16. package/assets/templates/app/lib/__STOREFRONT__/handlers.core.ts +197 -0
  17. package/assets/templates/app/lib/__STOREFRONT__/handlers.ts +5 -36
  18. package/assets/templates/app/lib/__STOREFRONT__/icon-map.ts +27 -0
  19. package/assets/templates/app/lib/__STOREFRONT__/mappers.ts +13 -11
  20. package/assets/templates/app/lib/__STOREFRONT__/registry.tsx +264 -51
  21. package/assets/templates/app/lib/__STOREFRONT__/runtime.ts +6 -3
  22. package/assets/templates/app/lib/__STOREFRONT__/schema.ts +136 -0
  23. package/assets/templates/app/lib/__STOREFRONT__/section-observation.ts +182 -0
  24. package/assets/templates/app/lib/__STOREFRONT__/section-sources.ts +130 -0
  25. package/assets/templates/app/lib/__STOREFRONT__/session.core.ts +470 -0
  26. package/assets/templates/app/lib/__STOREFRONT__/session.ts +169 -0
  27. package/assets/templates/app/lib/__STOREFRONT__/shell/content.ts +120 -0
  28. package/assets/templates/app/lib/__STOREFRONT__/shell/props.ts +38 -0
  29. package/assets/templates/app/lib/__STOREFRONT__/spec/index.ts +129 -10
  30. package/assets/templates/app/lib/__STOREFRONT__/spec/page-root.ts +5 -1
  31. package/assets/templates/app/lib/__STOREFRONT__/spec/seo.ts +191 -0
  32. package/assets/templates/app/lib/__STOREFRONT__/state.core.ts +257 -0
  33. package/assets/templates/app/lib/__STOREFRONT__/state.ts +7 -31
  34. package/assets/templates/app/lib/__STOREFRONT__/store-context.ts +161 -0
  35. package/assets/templates/app/lib/__STOREFRONT__/views/sections/cta.client.tsx +25 -0
  36. package/assets/templates/app/lib/__STOREFRONT__/views/sections/cta.tsx +16 -0
  37. package/assets/templates/app/lib/__STOREFRONT__/views/sections/faq.client.tsx +24 -0
  38. package/assets/templates/app/lib/__STOREFRONT__/views/sections/faq.tsx +5 -18
  39. package/assets/templates/app/lib/__STOREFRONT__/views/sections/index.ts +18 -0
  40. package/assets/templates/app/lib/__STOREFRONT__/views/sections/logoCloud.tsx +26 -14
  41. package/assets/templates/app/lib/__STOREFRONT__/views/sections/pricing.tsx +36 -18
  42. package/assets/templates/app/lib/__STOREFRONT__/views/sections/products.client.tsx +100 -0
  43. package/assets/templates/app/lib/__STOREFRONT__/views/sections/products.tsx +19 -0
  44. package/assets/templates/app/lib/__STOREFRONT__/views/sections/schema.cta.ts +19 -0
  45. package/assets/templates/app/lib/__STOREFRONT__/views/sections/schema.faq.ts +18 -0
  46. package/assets/templates/app/lib/__STOREFRONT__/views/sections/schema.products.ts +39 -0
  47. package/assets/templates/app/lib/__STOREFRONT__/views/sections/statistics.tsx +35 -14
  48. package/assets/templates/app/lib/__STOREFRONT__/views/sections/testimonials.tsx +31 -13
  49. package/assets/templates/app/lib/__STOREFRONT__/views/types.ts +5 -3
  50. package/assets/templates/features/checkout/handlers.ts +159 -0
  51. package/assets/templates/features/checkout/state.ts +61 -0
  52. package/assets/templates/features/customer-auth/handlers.ts +59 -0
  53. package/assets/templates/features/customer-auth/state.ts +45 -0
  54. package/assets/templates/features/recommendations/state.ts +11 -0
  55. package/assets/templates/views/account/content.ts +35 -0
  56. package/assets/templates/views/account/index.tsx +114 -0
  57. package/assets/templates/views/account/registry.tsx +439 -0
  58. package/assets/templates/views/account/schema.ts +53 -0
  59. package/assets/templates/views/cart/content.ts +11 -0
  60. package/assets/templates/views/cart/data.ts +23 -0
  61. package/assets/templates/views/cart/index.tsx +53 -0
  62. package/assets/templates/views/cart/props.ts +12 -0
  63. package/assets/templates/views/cart/registry.tsx +81 -0
  64. package/assets/templates/views/cart/schema.ts +52 -0
  65. package/assets/templates/views/category/assembly/assembly.json +29 -0
  66. package/assets/templates/views/category/assembly/index.skeleton.tsx +251 -0
  67. package/assets/templates/views/category/assembly/registry.skeleton.tsx +34 -0
  68. package/assets/templates/views/category/assembly/slots/breadcrumb/Breadcrumb/binding.json +5 -0
  69. package/assets/templates/views/category/assembly/slots/breadcrumb/Breadcrumb/catalog.part +4 -0
  70. package/assets/templates/views/category/assembly/slots/breadcrumb/Breadcrumb/element.part +7 -0
  71. package/assets/templates/views/category/assembly/slots/breadcrumb/Breadcrumb/registry.part +18 -0
  72. package/assets/templates/views/category/assembly/slots/filter/CategoryFilter2/catalog.part +5 -0
  73. package/assets/templates/views/category/assembly/slots/filter/CategoryFilter2/element.part +34 -0
  74. package/assets/templates/views/category/assembly/slots/filter/CategoryFilter2/registry.part +71 -0
  75. package/assets/templates/views/category/content.ts +30 -0
  76. package/assets/templates/views/category/data.ts +12 -0
  77. package/assets/templates/views/category/index.tsx +299 -0
  78. package/assets/templates/views/category/props.ts +23 -0
  79. package/assets/templates/views/category/registry.tsx +122 -0
  80. package/assets/templates/views/category/schema.ts +91 -0
  81. package/assets/templates/views/checkout/content.ts +105 -0
  82. package/assets/templates/views/checkout/data.ts +23 -0
  83. package/assets/templates/views/checkout/index.tsx +111 -0
  84. package/assets/templates/views/checkout/props.ts +49 -0
  85. package/assets/templates/views/checkout/registry.tsx +217 -0
  86. package/assets/templates/views/checkout/schema.ts +229 -0
  87. package/assets/templates/views/home/assembly/assembly.json +33 -0
  88. package/assets/templates/views/home/assembly/index.skeleton.tsx +90 -0
  89. package/assets/templates/views/home/assembly/registry.skeleton.tsx +25 -0
  90. package/assets/templates/views/home/assembly/slots/benefits/Feature1/binding.json +5 -0
  91. package/assets/templates/views/home/assembly/slots/benefits/Feature1/catalog.part +4 -0
  92. package/assets/templates/views/home/assembly/slots/benefits/Feature1/element.part +4 -0
  93. package/assets/templates/views/home/assembly/slots/benefits/Feature1/registry.part +11 -0
  94. package/assets/templates/views/home/assembly/slots/benefits/Feature2/binding.json +5 -0
  95. package/assets/templates/views/home/assembly/slots/benefits/Feature2/catalog.part +4 -0
  96. package/assets/templates/views/home/assembly/slots/benefits/Feature2/element.part +4 -0
  97. package/assets/templates/views/home/assembly/slots/benefits/Feature2/registry.part +10 -0
  98. package/assets/templates/views/home/assembly/slots/categories/ProductCategory2/binding.json +5 -0
  99. package/assets/templates/views/home/assembly/slots/categories/ProductCategory2/catalog.part +4 -0
  100. package/assets/templates/views/home/assembly/slots/categories/ProductCategory2/element.part +5 -0
  101. package/assets/templates/views/home/assembly/slots/categories/ProductCategory2/registry.part +16 -0
  102. package/assets/templates/views/home/assembly/slots/hero/StorefrontHero1/binding.json +5 -0
  103. package/assets/templates/views/home/assembly/slots/hero/StorefrontHero1/catalog.part +4 -0
  104. package/assets/templates/views/home/assembly/slots/hero/StorefrontHero1/element.part +5 -0
  105. package/assets/templates/views/home/assembly/slots/hero/StorefrontHero1/registry.part +26 -0
  106. package/assets/templates/views/home/content.ts +70 -0
  107. package/assets/templates/views/home/data.ts +24 -0
  108. package/assets/templates/views/home/index.tsx +57 -85
  109. package/assets/templates/views/home/props.ts +22 -0
  110. package/assets/templates/views/home/registry.tsx +38 -22
  111. package/assets/templates/views/home/schema.ts +93 -0
  112. package/assets/templates/views/product/content.ts +25 -0
  113. package/assets/templates/views/product/data.ts +50 -0
  114. package/assets/templates/views/product/index.tsx +148 -0
  115. package/assets/templates/views/product/props.ts +27 -0
  116. package/assets/templates/views/product/registry.tsx +103 -0
  117. package/assets/templates/views/product/schema.ts +121 -0
  118. package/assets/templates/views/static/content.ts +99 -0
  119. package/assets/templates/views/static/index.tsx +60 -0
  120. package/assets/templates/views/static/registry.tsx +66 -0
  121. package/assets/templates/views/static/schema.ts +45 -0
  122. package/bin/storefront.js +2424 -148
  123. package/examples/merchandising/category-led.json +37 -0
  124. package/examples/merchandising/collection-led.json +37 -0
  125. package/package.json +15 -9
  126. package/recipes/archetypes.json +28 -14
  127. package/recipes/catalog.json +400 -0
  128. package/recipes/catalog.mjs +128 -0
  129. package/recipes/catalog.schema.json +64 -0
  130. package/recipes/feature.schema.json +89 -0
  131. package/recipes/features.json +162 -0
  132. package/recipes/manifest.schema.json +69 -0
  133. package/recipes/operations.schema.json +43 -0
  134. package/recipes/recipe.schema.json +11 -2
  135. package/recipes/recipes.json +76 -19
  136. package/recipes/sections.json +34 -5
  137. package/recipes/validate.mjs +838 -32
  138. package/scripts/candidate.mjs +236 -0
  139. package/scripts/composers.mjs +160 -0
  140. package/scripts/env-file.mjs +86 -0
  141. package/scripts/file-classes.mjs +121 -0
  142. package/scripts/logical-controls.mjs +61 -0
  143. package/scripts/manifest.mjs +298 -0
  144. package/scripts/migrate-english-routes.mjs +276 -0
  145. package/scripts/operation-registry.mjs +256 -0
  146. package/scripts/operations.mjs +720 -0
  147. package/scripts/ownership-conflict.mjs +356 -0
  148. package/scripts/pinning.mjs +573 -0
  149. package/scripts/plan-apply.mjs +987 -0
  150. package/scripts/preflight.mjs +51 -0
  151. package/scripts/reconcile.mjs +549 -0
  152. package/scripts/render-templates.mjs +338 -68
  153. package/scripts/schema-validate.mjs +132 -0
  154. package/scripts/section-compat.mjs +300 -0
  155. package/scripts/section-config.mjs +253 -0
  156. package/scripts/section-operations.mjs +508 -0
  157. package/scripts/starter.mjs +17 -0
  158. package/scripts/sync-assets.mjs +22 -15
  159. package/scripts/theme/color.mjs +185 -0
  160. package/scripts/theme/css-theme.mjs +233 -0
  161. package/scripts/theme/fonts.mjs +123 -0
  162. package/scripts/theme/import-export.mjs +125 -0
  163. package/scripts/theme/preset.mjs +93 -0
  164. package/scripts/theme/theme-plan.mjs +292 -0
  165. package/scripts/theme/tokens.mjs +137 -0
  166. package/scripts/view-assembly.mjs +337 -0
  167. package/scripts/view-selection.mjs +211 -0
  168. package/skills/sf-feature/SKILL.md +80 -0
  169. package/skills/sf-setup/SKILL.md +79 -0
  170. package/skills/sf-theme-gen/SKILL.md +100 -30
  171. package/skills/sf-theme-gen/references/shadcn-theming.md +87 -0
  172. package/skills/{shadcn-theming/references/templates → sf-theme-gen/references}/theme-setup.md +15 -19
  173. package/skills/{shadcn-theming → sf-theme-gen}/references/theming-guide.md +6 -11
  174. package/skills/sf-view-gen/SKILL.md +146 -93
  175. package/skills/sf-view-gen/assets/recipes/archetypes.json +28 -14
  176. package/skills/sf-view-gen/assets/recipes/catalog.json +400 -0
  177. package/skills/sf-view-gen/assets/recipes/catalog.schema.json +64 -0
  178. package/skills/sf-view-gen/assets/recipes/features.json +162 -0
  179. package/skills/sf-view-gen/assets/recipes/recipes.json +76 -19
  180. package/skills/sf-view-gen/assets/recipes/sections.json +34 -5
  181. package/skills/sf-view-gen/assets/templates/views/sections/cta.client.tsx +25 -0
  182. package/skills/sf-view-gen/assets/templates/views/sections/cta.tsx +16 -0
  183. package/skills/sf-view-gen/assets/templates/views/sections/faq.client.tsx +13 -9
  184. package/skills/sf-view-gen/assets/templates/views/sections/faq.tsx +2 -7
  185. package/skills/sf-view-gen/assets/templates/views/sections/logoCloud.client.tsx +12 -8
  186. package/skills/sf-view-gen/assets/templates/views/sections/logoCloud.tsx +2 -7
  187. package/skills/sf-view-gen/assets/templates/views/sections/pricing.client.tsx +14 -10
  188. package/skills/sf-view-gen/assets/templates/views/sections/pricing.tsx +2 -9
  189. package/skills/sf-view-gen/assets/templates/views/sections/products.client.tsx +100 -0
  190. package/skills/sf-view-gen/assets/templates/views/sections/products.tsx +19 -0
  191. package/skills/sf-view-gen/assets/templates/views/sections/schema.cta.ts +19 -0
  192. package/skills/sf-view-gen/assets/templates/views/sections/schema.faq.ts +18 -0
  193. package/skills/sf-view-gen/assets/templates/views/sections/schema.logoCloud.ts +19 -0
  194. package/skills/sf-view-gen/assets/templates/views/sections/schema.pricing.ts +26 -0
  195. package/skills/sf-view-gen/assets/templates/views/sections/schema.products.ts +39 -0
  196. package/skills/sf-view-gen/assets/templates/views/sections/schema.statistics.ts +25 -0
  197. package/skills/sf-view-gen/assets/templates/views/sections/schema.testimonials.ts +23 -0
  198. package/skills/sf-view-gen/assets/templates/views/sections/statistics.client.tsx +16 -8
  199. package/skills/sf-view-gen/assets/templates/views/sections/statistics.tsx +2 -7
  200. package/skills/sf-view-gen/assets/templates/views/sections/testimonials.client.tsx +13 -9
  201. package/skills/sf-view-gen/assets/templates/views/sections/testimonials.tsx +2 -5
  202. package/skills/{json-render-core/SKILL.md → sf-view-gen/references/json-render-core.md} +4 -27
  203. package/skills/{json-render-next/SKILL.md → sf-view-gen/references/json-render-next.md} +5 -8
  204. package/skills/{json-render-react/SKILL.md → sf-view-gen/references/json-render-react.md} +3 -5
  205. package/skills/{json-render-shadcn/SKILL.md → sf-view-gen/references/json-render-shadcn.md} +3 -5
  206. package/skills/sf-view-gen/references/views.md +58 -33
  207. package/skills/sf-view-gen/scripts/catalog.mjs +128 -0
  208. package/skills/sf-view-gen/scripts/schema-validate.mjs +132 -0
  209. package/skills/sf-view-gen/scripts/validate.mjs +838 -32
  210. package/skills/storefront-workflow/SKILL.md +179 -0
  211. package/skills/{storefront-best-practices/reference/design.md → storefront-workflow/references/design-consistency.md} +13 -29
  212. package/CHANGELOG.md +0 -61
  213. package/commands/sf-add-view.md +0 -26
  214. package/commands/sf-theme.md +0 -20
  215. package/commands/sf-view.md +0 -25
  216. package/skills/building-storefronts/SKILL.md +0 -178
  217. package/skills/building-storefronts/references/frontend-integration.md +0 -229
  218. package/skills/json-render-remotion/SKILL.md +0 -111
  219. package/skills/json-render-solid/SKILL.md +0 -204
  220. package/skills/nextjs-shadcn/SKILL.md +0 -367
  221. package/skills/nextjs-shadcn/references/architecture.md +0 -499
  222. package/skills/nextjs-shadcn/references/project-setup.md +0 -162
  223. package/skills/nextjs-shadcn/references/shadcn-platform.md +0 -261
  224. package/skills/nextjs-shadcn/references/sidebar.md +0 -274
  225. package/skills/nextjs-shadcn/references/styling.md +0 -555
  226. package/skills/sf-view-gen/assets/templates/views/category/index.tsx +0 -86
  227. package/skills/sf-view-gen/assets/templates/views/category/registry.tsx +0 -48
  228. package/skills/sf-view-gen/assets/templates/views/checkout/index.tsx +0 -192
  229. package/skills/sf-view-gen/assets/templates/views/checkout/registry.tsx +0 -45
  230. package/skills/sf-view-gen/assets/templates/views/product/index.tsx +0 -122
  231. package/skills/sf-view-gen/assets/templates/views/product/registry.tsx +0 -49
  232. package/skills/sf-view-gen/assets/templates/views/user-panel/index.tsx +0 -168
  233. package/skills/sf-view-gen/assets/templates/views/user-panel/registry.tsx +0 -49
  234. package/skills/shadcn-component-discovery/SKILL.md +0 -273
  235. package/skills/shadcn-component-discovery/references/registries.md +0 -226
  236. package/skills/shadcn-theming/SKILL.md +0 -104
  237. package/skills/storefront-best-practices/SKILL.md +0 -421
  238. package/skills/storefront-best-practices/reference/components/breadcrumbs.md +0 -123
  239. package/skills/storefront-best-practices/reference/components/cart-popup.md +0 -189
  240. package/skills/storefront-best-practices/reference/components/country-selector.md +0 -298
  241. package/skills/storefront-best-practices/reference/components/footer.md +0 -112
  242. package/skills/storefront-best-practices/reference/components/hero.md +0 -241
  243. package/skills/storefront-best-practices/reference/components/megamenu.md +0 -239
  244. package/skills/storefront-best-practices/reference/components/navbar.md +0 -397
  245. package/skills/storefront-best-practices/reference/components/popups.md +0 -221
  246. package/skills/storefront-best-practices/reference/components/product-card.md +0 -125
  247. package/skills/storefront-best-practices/reference/components/product-reviews.md +0 -217
  248. package/skills/storefront-best-practices/reference/components/product-slider.md +0 -174
  249. package/skills/storefront-best-practices/reference/components/search.md +0 -101
  250. package/skills/storefront-best-practices/reference/connecting-to-backend.md +0 -391
  251. package/skills/storefront-best-practices/reference/features/promotions.md +0 -307
  252. package/skills/storefront-best-practices/reference/features/wishlist.md +0 -230
  253. package/skills/storefront-best-practices/reference/layouts/account.md +0 -380
  254. package/skills/storefront-best-practices/reference/layouts/cart.md +0 -316
  255. package/skills/storefront-best-practices/reference/layouts/checkout.md +0 -486
  256. package/skills/storefront-best-practices/reference/layouts/home-page.md +0 -264
  257. package/skills/storefront-best-practices/reference/layouts/order-confirmation.md +0 -231
  258. package/skills/storefront-best-practices/reference/layouts/product-details.md +0 -527
  259. package/skills/storefront-best-practices/reference/layouts/product-listing.md +0 -520
  260. package/skills/storefront-best-practices/reference/layouts/static-pages.md +0 -356
  261. package/skills/storefront-best-practices/reference/medusa.md +0 -307
  262. /package/skills/{storefront-best-practices/reference → storefront-workflow/references}/mobile-responsiveness.md +0 -0
  263. /package/skills/{storefront-best-practices/reference → storefront-workflow/references}/seo.md +0 -0
@@ -1,261 +0,0 @@
1
- # shadcn Platform
2
-
3
- The parts of shadcn that are not individual components: which primitive base to
4
- build on, the CLI verbs worth knowing, and the CSS-level systems (typeset,
5
- shimmer, scroll-fade).
6
-
7
- ## Choosing a base (do this first)
8
-
9
- shadcn components ship on three primitive libraries: Base UI, Radix, and React
10
- Aria. **Base UI is the default.** The choice is per-project and set at `init` —
11
- components installed later inherit it.
12
-
13
- ```bash
14
- # Base UI (default)
15
- yarn dlx shadcn@latest init --template next --base base --preset <preset> --no-monorepo --no-rtl --yes
16
- # Radix (legacy projects)
17
- yarn dlx shadcn@latest init --template next --base radix --preset <preset> --no-monorepo --no-rtl --yes
18
- # React Aria
19
- yarn dlx shadcn@latest init --template next --base aria --preset <preset> --no-monorepo --no-rtl --yes
20
- ```
21
-
22
- | Base | Pick it when |
23
- |------|-------------|
24
- | `base` | New projects. Default since July 2026, most actively developed, gets new components first. |
25
- | `radix` | Existing codebase already on Radix, or a dependency expects Radix primitives. |
26
- | `aria` | Accessibility/interaction requirements beyond the defaults — React Aria's behavior hooks. |
27
-
28
- **Why this matters for generated code:** the same component name has different
29
- props and sub-components per base. Docs are base-scoped too —
30
- `ui.shadcn.com/docs/components/base/sidebar` vs `.../radix/sidebar`. Never write
31
- component code from memory without knowing the project's base.
32
-
33
- The difference that bites most often: **Base UI composes through a `render`
34
- prop, Radix through `asChild`.**
35
-
36
- ```tsx
37
- // Base UI (default) — element goes in render, children stay as children
38
- <SidebarMenuButton render={<Link href="/inbox" />}>
39
- <Inbox />
40
- <span>Inbox</span>
41
- </SidebarMenuButton>
42
-
43
- // Radix — element wraps the children
44
- <SidebarMenuButton asChild>
45
- <Link href="/inbox">
46
- <Inbox />
47
- <span>Inbox</span>
48
- </Link>
49
- </SidebarMenuButton>
50
- ```
51
-
52
- Read the base from `components.json` (or `shadcn info --json`) before editing an
53
- existing project.
54
-
55
- `migrate radix` does **not** switch a project from Radix to Base UI — it rewrites
56
- `@radix-ui/react-*` imports to the single `radix-ui` package. Radix → Base UI is
57
- a component-at-a-time migration driven by the official shadcn skill:
58
-
59
- ```bash
60
- yarn dlx skills add shadcn/ui
61
- # then ask the agent: "migrate accordion to base-ui"
62
- ```
63
-
64
- Both libraries stay installed while you work, each component lands in its own
65
- commit, and every run writes a report to `.migration/<component>.md`.
66
-
67
- ## CLI verbs beyond `add`
68
-
69
- `add` and `init` are the familiar ones. These four are what make the CLI useful
70
- to an agent:
71
-
72
- ```bash
73
- yarn dlx shadcn@latest info --json # project config: framework, base, tailwind, aliases, installed components
74
- yarn dlx shadcn@latest docs button # API reference for a component, resolved to THIS project's base
75
- yarn dlx shadcn@latest docs button --json # machine-readable, for piping into context
76
- yarn dlx shadcn@latest view button card # inspect registry item source before installing
77
- yarn dlx shadcn@latest search @shadcn -q chart # search a registry namespace
78
- ```
79
-
80
- **Prefer `shadcn docs <component>` over recalling props from memory or fetching
81
- `llms.txt`** — it resolves against the project's actual base and version. Use
82
- `shadcn view` before `add` when you are unsure what a registry item pulls in.
83
-
84
- Other verbs: `add <component> --diff` (upstream changes to an installed
85
- component — the standalone `diff` command is deprecated), `apply <preset>`
86
- (apply a preset to an existing project; `--only theme,font` for just those
87
- parts), `preset decode|resolve|url|open` (inspect a preset code), `build`
88
- (generate registry JSON), `migrate` (`icons`, `rtl`, `radix`), `eject` (inline
89
- `shadcn/tailwind.css` and drop the `shadcn` dependency).
90
-
91
- ### `migrate icons`
92
-
93
- Swapping icon libraries across a whole project is a single command:
94
-
95
- ```bash
96
- yarn dlx shadcn@latest migrate icons --from lucide --to phosphor
97
- ```
98
-
99
- ## The official shadcn skill
100
-
101
- shadcn publishes its own agent skill, which injects live project config
102
- (`shadcn info --json`) plus the full CLI and registry reference:
103
-
104
- ```bash
105
- yarn dlx skills add shadcn/ui
106
- ```
107
-
108
- It activates when the project has a `components.json`. It covers CLI mechanics
109
- and registry authoring — **this skill covers project conventions, architecture,
110
- and Next.js integration instead.** Install both; don't duplicate CLI reference
111
- material here.
112
-
113
- There is also an MCP server for registry search and install from within the
114
- editor — wire it into Claude Code with
115
- `yarn dlx shadcn@latest mcp init --client claude`.
116
-
117
- ## Typeset — styling rendered markdown
118
-
119
- One CSS file you own that styles headings, paragraphs, lists, tables and code
120
- inside a wrapper class. Replaces hand-written `prose`-style overrides and
121
- per-context markdown CSS.
122
-
123
- **Use it for:** chat message bodies, docs pages, blog posts, LLM-streamed
124
- markdown — anywhere you render HTML you did not author.
125
-
126
- Typeset is **not** part of `init` and has no `add` command. Generate the file in
127
- the builder at [ui.shadcn.com/typeset](https://ui.shadcn.com/typeset), drop it
128
- next to your main CSS, and import it after Tailwind:
129
-
130
- ```css
131
- /* app/globals.css */
132
- @import "tailwindcss";
133
- @import "./typeset.css";
134
- ```
135
-
136
- Three variables drive the whole rhythm; everything else derives from them:
137
-
138
- ```css
139
- .typeset {
140
- --typeset-font-body: inherit;
141
- --typeset-font-heading: var(--font-heading);
142
- --typeset-font-mono: var(--font-mono);
143
- --typeset-size: 1em; /* base text size */
144
- --typeset-leading: 1.75; /* line-height */
145
- --typeset-flow: 1.25em; /* space between blocks */
146
- }
147
- ```
148
-
149
- Define one preset per context and apply both classes:
150
-
151
- ```css
152
- .typeset-docs {
153
- --typeset-size: 15px;
154
- --typeset-leading: 1.75;
155
- --typeset-flow: 1.25em;
156
- }
157
-
158
- .typeset-chat {
159
- --typeset-leading: 1.6;
160
- --typeset-flow: 1em; /* tighter — chat bubbles are short */
161
- }
162
- ```
163
-
164
- ```tsx
165
- <div className="typeset typeset-chat">
166
- <Response>{message}</Response>
167
- </div>
168
- ```
169
-
170
- It is container-aware (sizes to its container, not just the viewport) and
171
- **streaming-stable**: appending a new block does not restyle blocks already
172
- rendered above it. That property is the reason to prefer it over ad-hoc CSS in
173
- streaming chat UIs.
174
-
175
- ## Shimmer — loading and processing text
176
-
177
- CSS-only animated sweep across text. No component, no JS.
178
-
179
- ```tsx
180
- <p className="shimmer text-muted-foreground">Generating response…</p>
181
- ```
182
-
183
- | Class | Effect |
184
- |-------|--------|
185
- | `shimmer-color-<color>` | Highlight color, e.g. `shimmer-color-blue-500/60` |
186
- | `shimmer-duration-<ms>` | Sweep speed (default 2000) |
187
- | `shimmer-spread-<n>` | Width of the highlight band |
188
- | `shimmer-angle-<deg>` | Tilt (default 20) |
189
- | `shimmer-once` | Single sweep instead of looping |
190
- | `shimmer-reverse` | Reverse direction |
191
-
192
- Adapts to the element's text color, brightens in dark mode, respects
193
- `prefers-reduced-motion` and RTL automatically.
194
-
195
- **Use shimmer for indeterminate text states** ("Thinking…", "Searching…") and
196
- `Skeleton` for layout placeholders with known shape. Don't stack both.
197
-
198
- ## Scroll-fade — soft scroll container edges
199
-
200
- Masks the content itself at the edges of a scroll container rather than
201
- overlaying a gradient, so it works on any background.
202
-
203
- ```tsx
204
- <div className="scroll-fade overflow-y-auto">{/* content */}</div>
205
- ```
206
-
207
- | Class | Effect |
208
- |-------|--------|
209
- | `scroll-fade` / `scroll-fade-y` | Vertical |
210
- | `scroll-fade-x` | Horizontal |
211
- | `scroll-fade-t` / `-b` / `-l` / `-r` | Single edge |
212
- | `scroll-fade-s` / `-e` | Start/end edge (RTL-aware) |
213
- | `scroll-fade-<n>` | Fade depth on the spacing scale |
214
- | `scroll-fade-none` | Disable |
215
-
216
- Scroll-aware: the top edge stays crisp until you scroll away from it.
217
-
218
- Both `shimmer` and `scroll-fade` come from `shadcn/tailwind.css`, which `init`
219
- wires up. In a project that skipped it:
220
-
221
- ```css
222
- @import "tailwindcss";
223
- @import "shadcn/tailwind.css";
224
- ```
225
-
226
- ## RTL support
227
-
228
- Sidebar and the CSS utilities are RTL-aware. Opt in at init with `--rtl`,
229
- retrofit an existing project with `migrate rtl`, and pass `dir` on the `Sidebar`
230
- component. Prefer logical utilities (`ms-`/`me-`, `scroll-fade-s/-e`)
231
- over physical ones (`ml-`/`mr-`) in any project that might need it.
232
-
233
- ## Package imports (alias alternative)
234
-
235
- Projects may use Node package imports instead of `tsconfig.json` paths:
236
-
237
- ```json
238
- // package.json
239
- { "imports": { "#components/*": "./src/components/*.tsx", "#lib/*": "./src/lib/*.ts" } }
240
- ```
241
-
242
- ```tsx
243
- import { Button } from "#components/ui/button";
244
- import { cn } from "#lib/utils";
245
- ```
246
-
247
- Requires `moduleResolution: "bundler"` and `resolvePackageJsonImports: true`, and
248
- the matching `aliases` block in `components.json`. The CLI rewrites imports to
249
- whichever alias style is configured.
250
-
251
- **Default to `@/` for new projects.** In an existing project, read
252
- `components.json` and follow what is already there — never mix both styles.
253
-
254
- ## Registries
255
-
256
- Beyond `@shadcn`, the CLI resolves namespaced registries (`@acme/button`),
257
- including private and GitHub-hosted ones. If you author a registry with more
258
- than a few hundred items, implement
259
- [dynamic search](https://ui.shadcn.com/docs/registry/dynamic-search) so
260
- `shadcn search` filters server-side instead of downloading the whole catalog.
261
- Not needed for consuming registries.
@@ -1,274 +0,0 @@
1
- # Sidebar
2
-
3
- shadcn/ui sidebar with nested layouts for dashboard applications.
4
-
5
- ## Start from a block, not from scratch
6
-
7
- Before hand-writing an `AppSidebar`, check whether a block already matches the
8
- shape you need. A block installs a complete, working sidebar you then edit —
9
- faster and less error-prone than assembling sub-components by hand.
10
-
11
- ```bash
12
- yarn dlx shadcn@latest add sidebar-07
13
- ```
14
-
15
- | Block | Shape |
16
- |-------|-------|
17
- | `sidebar-01` | Navigation grouped by section (simplest) |
18
- | `sidebar-02` | Collapsible sections |
19
- | `sidebar-03` | Submenus |
20
- | `sidebar-04` | Floating sidebar with submenus |
21
- | `sidebar-05` | Collapsible submenus |
22
- | `sidebar-06` | Submenus as dropdowns |
23
- | `sidebar-07` | Collapses to icons — the common dashboard default |
24
- | `sidebar-08` | Inset sidebar with secondary navigation |
25
- | `sidebar-09` | Collapsible nested sidebars |
26
- | `sidebar-10` | Sidebar in a popover |
27
- | `sidebar-11` | Collapsible file tree |
28
- | `sidebar-12` | Sidebar with a calendar |
29
- | `sidebar-13` | Sidebar in a dialog |
30
- | `sidebar-14` | Sidebar on the right |
31
- | `sidebar-15` | Left and right sidebar |
32
- | `sidebar-16` | Sticky site header |
33
-
34
- Preview them at [ui.shadcn.com/blocks/sidebar](https://ui.shadcn.com/blocks/sidebar).
35
- Use `shadcn view sidebar-07` to read the source before installing.
36
-
37
- The patterns below are for when no block fits, or when adapting one.
38
-
39
- ## Installation
40
-
41
- ```bash
42
- yarn dlx shadcn@latest add sidebar
43
- ```
44
-
45
- The sidebar API differs between Base UI, Radix and React Aria. Check the
46
- project's base (`shadcn info --json`) and read
47
- `shadcn docs sidebar` rather than assuming — the examples below target Base UI,
48
- the current default. The difference that shows up in every example: Base UI
49
- composes through a `render` prop (`<SidebarMenuButton render={<Link href="/" />}>`
50
- with the icon and label as children), where Radix wraps the children in `asChild`.
51
-
52
- ## Layout Pattern
53
-
54
- Use nested layouts with SidebarProvider for persistent sidebar state:
55
-
56
- ```
57
- app/
58
- ├── (dashboard)/ # Route group for sidebar pages
59
- │ ├── layout.tsx # SidebarProvider + AppSidebar
60
- │ ├── page.tsx # Dashboard home
61
- │ ├── settings/
62
- │ │ └── page.tsx
63
- │ └── components/ # Route-specific components
64
- ├── (public)/ # Public routes (no sidebar)
65
- │ └── login/
66
- └── layout.tsx # Root layout
67
- ```
68
-
69
- ### Dashboard Layout
70
-
71
- ```tsx
72
- // app/(dashboard)/layout.tsx
73
- import { AppSidebar } from "@/components/layout/app-sidebar"
74
- import {
75
- SidebarInset,
76
- SidebarProvider,
77
- } from "@/components/ui/sidebar"
78
-
79
- export default function DashboardLayout({
80
- children,
81
- }: {
82
- children: React.ReactNode
83
- }) {
84
- return (
85
- <SidebarProvider>
86
- <AppSidebar />
87
- <SidebarInset>{children}</SidebarInset>
88
- </SidebarProvider>
89
- )
90
- }
91
- ```
92
-
93
- ### Page Component
94
-
95
- Keep pages clean - content only, no layout chrome:
96
-
97
- ```tsx
98
- // app/(dashboard)/page.tsx
99
- import { DocumentWorkspace } from "@/components/workspace/document-workspace"
100
- import { Suspense } from "react"
101
-
102
- export default function DashboardPage() {
103
- return (
104
- <Suspense fallback={<DashboardSkeleton />}>
105
- <DocumentWorkspace />
106
- </Suspense>
107
- )
108
- }
109
- ```
110
-
111
- ## AppSidebar Component
112
-
113
- ```tsx
114
- // components/layout/app-sidebar.tsx
115
- import Link from "next/link"
116
- import {
117
- Sidebar,
118
- SidebarContent,
119
- SidebarFooter,
120
- SidebarGroup,
121
- SidebarGroupContent,
122
- SidebarGroupLabel,
123
- SidebarHeader,
124
- SidebarMenu,
125
- SidebarMenuButton,
126
- SidebarMenuItem,
127
- SidebarRail,
128
- SidebarSeparator,
129
- } from "@/components/ui/sidebar"
130
- import { NAV_GROUPS, FOOTER_NAV_ITEMS } from "./nav"
131
-
132
- export function AppSidebar() {
133
- return (
134
- <Sidebar variant="inset" collapsible="icon">
135
- <SidebarHeader>
136
- <SidebarMenu>
137
- <SidebarMenuItem>
138
- <SidebarMenuButton
139
- size="lg"
140
- render={<Link href="/" className="flex items-center gap-3" />}
141
- >
142
- <Logo className="size-8" />
143
- <span className="text-base font-semibold">App Name</span>
144
- </SidebarMenuButton>
145
- </SidebarMenuItem>
146
- </SidebarMenu>
147
- </SidebarHeader>
148
-
149
- <SidebarContent>
150
- {NAV_GROUPS.map((group, index) => (
151
- <div key={group.title}>
152
- <SidebarGroup>
153
- <SidebarGroupLabel>{group.title}</SidebarGroupLabel>
154
- <SidebarGroupContent>
155
- <SidebarMenu>
156
- {group.items.map((item) => (
157
- <SidebarMenuItem key={item.title}>
158
- <SidebarMenuButton render={<Link href={item.href} />}>
159
- <item.icon />
160
- <span>{item.title}</span>
161
- </SidebarMenuButton>
162
- </SidebarMenuItem>
163
- ))}
164
- </SidebarMenu>
165
- </SidebarGroupContent>
166
- </SidebarGroup>
167
- {index < NAV_GROUPS.length - 1 && <SidebarSeparator />}
168
- </div>
169
- ))}
170
- </SidebarContent>
171
-
172
- <SidebarFooter>
173
- <SidebarSeparator />
174
- <SidebarMenu>
175
- {FOOTER_NAV_ITEMS.map((item) => (
176
- <SidebarMenuItem key={item.title}>
177
- <SidebarMenuButton render={<Link href={item.href} />}>
178
- <item.icon />
179
- <span>{item.title}</span>
180
- </SidebarMenuButton>
181
- </SidebarMenuItem>
182
- ))}
183
- </SidebarMenu>
184
- </SidebarFooter>
185
-
186
- <SidebarRail />
187
- </Sidebar>
188
- )
189
- }
190
- ```
191
-
192
- ## Navigation Config
193
-
194
- Separate navigation data from component:
195
-
196
- ```tsx
197
- // components/layout/nav.ts
198
- import { Home, Settings, Users, HelpCircle } from "lucide-react"
199
- import type { LucideIcon } from "lucide-react"
200
-
201
- interface NavItem {
202
- title: string
203
- href: string
204
- icon: LucideIcon
205
- }
206
-
207
- interface NavGroup {
208
- title: string
209
- items: NavItem[]
210
- }
211
-
212
- export const NAV_GROUPS: NavGroup[] = [
213
- {
214
- title: "Main",
215
- items: [
216
- { title: "Dashboard", href: "/", icon: Home },
217
- { title: "Users", href: "/users", icon: Users },
218
- ],
219
- },
220
- ]
221
-
222
- export const FOOTER_NAV_ITEMS: NavItem[] = [
223
- { title: "Settings", href: "/settings", icon: Settings },
224
- { title: "Help", href: "/help", icon: HelpCircle },
225
- ]
226
- ```
227
-
228
- ## Sidebar Variants
229
-
230
- | Variant | Description |
231
- |---------|-------------|
232
- | `sidebar` | Standard sidebar (default) |
233
- | `inset` | Sidebar with padding, content area has rounded corners |
234
- | `floating` | Sidebar floats over content |
235
-
236
- ```tsx
237
- <Sidebar variant="inset" collapsible="icon">
238
- ```
239
-
240
- ## Collapsible Options
241
-
242
- | Option | Behavior |
243
- |--------|----------|
244
- | `icon` | Collapses to icon-only rail |
245
- | `offcanvas` | Slides completely off-screen |
246
- | `none` | Not collapsible |
247
-
248
- ## RTL
249
-
250
- `Sidebar` takes a `dir` prop and positions via `data-side` attributes, so
251
- right-to-left layouts work without JS conditionals — `SidebarTrigger` flips its
252
- icon automatically. Opt in project-wide at `init` with `--rtl`, or retrofit with
253
- `shadcn migrate rtl`. In any project that might need RTL, use logical utilities
254
- (`ms-`/`me-`, `ps-`/`pe-`) instead of `ml-`/`mr-` in sidebar markup.
255
-
256
- ## Persisting open state
257
-
258
- `SidebarProvider` takes `defaultOpen` (uncontrolled) or `open` / `onOpenChange`
259
- (controlled); width comes from the `--sidebar-width` CSS variable. To keep the
260
- sidebar's state across reloads without a hydration mismatch, read a cookie in the
261
- layout Server Component and pass it to `defaultOpen` — don't read it client-side
262
- in an effect.
263
-
264
- For custom triggers, `useSidebar()` exposes `toggleSidebar`, `isMobile`, and the
265
- mobile-specific `openMobile` / `setOpenMobile`.
266
-
267
- ## File Structure
268
-
269
- ```
270
- components/
271
- └── layout/
272
- ├── app-sidebar.tsx # Sidebar component
273
- └── nav.ts # Navigation config
274
- ```