diff --git a/apps/v4/components/component-preview-tabs.tsx b/apps/v4/components/component-preview-tabs.tsx
index 79635f08d..ef10986ff 100644
--- a/apps/v4/components/component-preview-tabs.tsx
+++ b/apps/v4/components/component-preview-tabs.tsx
@@ -1,9 +1,9 @@
"use client"
import * as React from "react"
+import { Button } from "@/examples/base/ui/button"
import { cn } from "@/lib/utils"
-import { Button } from "@/registry/new-york-v4/ui/button"
export function ComponentPreviewTabs({
className,
@@ -13,6 +13,7 @@ export function ComponentPreviewTabs({
chromeLessOnMobile = false,
component,
source,
+ sourcePreview,
...props
}: React.ComponentProps<"div"> & {
previewClassName?: string
@@ -21,11 +22,13 @@ export function ComponentPreviewTabs({
chromeLessOnMobile?: boolean
component: React.ReactNode
source: React.ReactNode
+ sourcePreview?: React.ReactNode
}) {
const [isMobileCodeVisible, setIsMobileCodeVisible] = React.useState(false)
return (
- {source}
- {!isMobileCodeVisible && (
-
-
-
+ {isMobileCodeVisible ? (
+ source
+ ) : (
+
+ {sourcePreview}
+
+
+
+
)}
diff --git a/apps/v4/components/component-preview.tsx b/apps/v4/components/component-preview.tsx
index b09cd6897..fe04ec365 100644
--- a/apps/v4/components/component-preview.tsx
+++ b/apps/v4/components/component-preview.tsx
@@ -77,6 +77,14 @@ export function ComponentPreview({
styleName={styleName}
/>
}
+ sourcePreview={
+
+ }
chromeLessOnMobile={chromeLessOnMobile}
{...props}
/>
diff --git a/apps/v4/components/component-source.tsx b/apps/v4/components/component-source.tsx
index a90555724..0721ce23f 100644
--- a/apps/v4/components/component-source.tsx
+++ b/apps/v4/components/component-source.tsx
@@ -18,6 +18,7 @@ export async function ComponentSource({
collapsible = true,
className,
styleName = "new-york-v4",
+ maxLines,
}: React.ComponentProps<"div"> & {
name?: string
src?: string
@@ -25,6 +26,7 @@ export async function ComponentSource({
language?: string
collapsible?: boolean
styleName?: string
+ maxLines?: number
}) {
if (!name && !src) {
return null
@@ -51,6 +53,11 @@ export async function ComponentSource({
code = await formatCode(code, styleName)
code = code.replaceAll("/* eslint-disable react/no-children-prop */\n", "")
+ // Truncate code if maxLines is set.
+ if (maxLines) {
+ code = code.split("\n").slice(0, maxLines).join("\n")
+ }
+
const lang = language ?? title?.split(".").pop() ?? "tsx"
const highlightedCode = await highlightCode(code, lang)
diff --git a/apps/v4/content/docs/changelog/2025-10-new-components.mdx b/apps/v4/content/docs/changelog/2025-10-new-components.mdx
index 643fd262f..f61173533 100644
--- a/apps/v4/content/docs/changelog/2025-10-new-components.mdx
+++ b/apps/v4/content/docs/changelog/2025-10-new-components.mdx
@@ -34,21 +34,21 @@ Here's what it looks like:
Here's what it looks like in a button:
You can edit the code and replace it with your own spinner.
### Kbd
@@ -74,7 +74,7 @@ Use `KbdGroup` to group keyboard keys together.
You can add it to buttons, tooltips, input groups, and more.
@@ -85,7 +85,7 @@ I got a lot of requests for this one: Button Group. It's a container that groups
Here's the code:
@@ -120,14 +120,14 @@ Use `ButtonGroupSeparator` to create split buttons. Classic dropdown pattern.
You can also use it to add prefix or suffix buttons and text to inputs.
```tsx showLineNumbers
diff --git a/apps/v4/examples/base/dropdown-menu-avatar.tsx b/apps/v4/examples/base/dropdown-menu-avatar.tsx
index 9017544b3..6a6b25f34 100644
--- a/apps/v4/examples/base/dropdown-menu-avatar.tsx
+++ b/apps/v4/examples/base/dropdown-menu-avatar.tsx
@@ -1,3 +1,5 @@
+"use client"
+
import { Avatar, AvatarFallback, AvatarImage } from "@/examples/base/ui/avatar"
import { Button } from "@/examples/base/ui/button"
import {
diff --git a/apps/v4/examples/base/dropdown-menu-basic.tsx b/apps/v4/examples/base/dropdown-menu-basic.tsx
index 7008ee7c2..e47a93735 100644
--- a/apps/v4/examples/base/dropdown-menu-basic.tsx
+++ b/apps/v4/examples/base/dropdown-menu-basic.tsx
@@ -1,3 +1,5 @@
+"use client"
+
import { Button } from "@/examples/base/ui/button"
import {
DropdownMenu,
diff --git a/apps/v4/examples/base/dropdown-menu-demo.tsx b/apps/v4/examples/base/dropdown-menu-demo.tsx
index 9c85ad90a..3d7760e60 100644
--- a/apps/v4/examples/base/dropdown-menu-demo.tsx
+++ b/apps/v4/examples/base/dropdown-menu-demo.tsx
@@ -1,3 +1,5 @@
+"use client"
+
import { Button } from "@/examples/base/ui/button"
import {
DropdownMenu,
diff --git a/apps/v4/examples/base/dropdown-menu-destructive.tsx b/apps/v4/examples/base/dropdown-menu-destructive.tsx
index 163c086d3..6b3bd055f 100644
--- a/apps/v4/examples/base/dropdown-menu-destructive.tsx
+++ b/apps/v4/examples/base/dropdown-menu-destructive.tsx
@@ -1,3 +1,5 @@
+"use client"
+
import { Button } from "@/examples/base/ui/button"
import {
DropdownMenu,
diff --git a/apps/v4/examples/base/dropdown-menu-icons.tsx b/apps/v4/examples/base/dropdown-menu-icons.tsx
index 37634b204..b4ae69a84 100644
--- a/apps/v4/examples/base/dropdown-menu-icons.tsx
+++ b/apps/v4/examples/base/dropdown-menu-icons.tsx
@@ -1,3 +1,5 @@
+"use client"
+
import { Button } from "@/examples/base/ui/button"
import {
DropdownMenu,
diff --git a/apps/v4/examples/base/dropdown-menu-shortcuts.tsx b/apps/v4/examples/base/dropdown-menu-shortcuts.tsx
index f7b833154..0f3c72019 100644
--- a/apps/v4/examples/base/dropdown-menu-shortcuts.tsx
+++ b/apps/v4/examples/base/dropdown-menu-shortcuts.tsx
@@ -1,3 +1,5 @@
+"use client"
+
import { Button } from "@/examples/base/ui/button"
import {
DropdownMenu,
diff --git a/apps/v4/examples/base/dropdown-menu-submenu.tsx b/apps/v4/examples/base/dropdown-menu-submenu.tsx
index 468070c8a..e59cd421b 100644
--- a/apps/v4/examples/base/dropdown-menu-submenu.tsx
+++ b/apps/v4/examples/base/dropdown-menu-submenu.tsx
@@ -1,3 +1,5 @@
+"use client"
+
import { Button } from "@/examples/base/ui/button"
import {
DropdownMenu,