Skip to content

Commit 7847450

Browse files
committed
docs
1 parent ebc9de8 commit 7847450

File tree

12 files changed

+1180
-550
lines changed

12 files changed

+1180
-550
lines changed

apps/www/content/docs/(plugins)/(ai)/ai.mdx

Lines changed: 986 additions & 1 deletion
Large diffs are not rendered by default.

apps/www/src/app/(app)/docs/[[...slug]]/page.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { notFound } from "next/navigation"
1313

1414
import { DocContent } from "@/app/(app)/docs/[[...slug]]/doc-content"
1515
import { ComponentInstallation } from "@/components/component-installation"
16-
import { ComponentPreview } from "@/components/component-preview"
16+
import { ComponentPreviewInternal } from "@/components/component-preview-internal"
1717
import { DocsTableOfContents } from "@/components/docs-toc"
1818
import { mdxComponents } from "@/components/mdx-components"
1919
import { badgeVariants } from "@/components/ui/badge"
@@ -239,12 +239,8 @@ export default async function Page(props: DocPageProps) {
239239
usage={file.meta?.usage}
240240
/>
241241
) : (
242-
<ComponentPreview
242+
<ComponentPreviewInternal
243243
name={file.name}
244-
dependencies={dependencies}
245-
highlightedFiles={highlightedFiles}
246-
item={item}
247-
tree={tree}
248244
/>
249245
)}
250246
</DocContent>

apps/www/src/components/block-display.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,21 @@ import type { RegistryItem, registryItemFileSchema } from "shadcn/registry"
44
import type { z } from "zod"
55

66
import { BlockViewer } from "@/components/block-viewer"
7-
import { ComponentPreview } from "@/components/component-preview"
7+
import { ComponentPreviewInternal } from "@/components/component-preview-internal"
88
import { highlightCode } from "@/lib/highlight-code"
99
import { createFileTreeForRegistryItemFiles, getRegistryItem } from "@/lib/rehype-utils"
1010
import { cn } from "@/lib/utils"
1111

12+
export interface BlockDisplayProps {
13+
item: RegistryItem
14+
name: string
15+
block?: boolean
16+
}
1217

13-
export async function BlockDisplay({ item: itemProp, name, ...props }: { id: string, item: RegistryItem; name: string, block?: boolean, }) {
18+
export async function BlockDisplay({ block = true, item: itemProp, name }: BlockDisplayProps) {
1419
const item = itemProp ?? await getCachedRegistryItem(name)
1520

16-
if (!item?.files && !item.meta?.isPro) {
21+
if (!item?.files && !item?.meta?.isPro) {
1722
return null
1823
}
1924

@@ -23,9 +28,9 @@ export async function BlockDisplay({ item: itemProp, name, ...props }: { id: str
2328
]) : [null, null]
2429

2530
return (
26-
<BlockViewer highlightedFiles={highlightedFiles} item={item} tree={tree}
31+
<BlockViewer blocks={block} highlightedFiles={highlightedFiles} item={item} tree={tree}
2732
>
28-
<ComponentPreview
33+
<ComponentPreviewInternal
2934
name={item.name}
3035
className={cn(
3136
"my-0 **:[.preview]:h-auto **:[.preview]:p-4 **:[.preview>.p-6]:p-0",

apps/www/src/components/block-viewer.tsx

Lines changed: 132 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@ import Link from "next/link"
2727

2828
import { Index } from "@/__registry__"
2929
import { getIconForLanguageExtension } from "@/components/icons"
30+
import { siteConfig } from "@/config/site"
3031
import { useCopyToClipboard } from "@/hooks/use-copy-to-clipboard"
3132
import { trackEvent } from "@/lib/events"
33+
import { cn } from "@/lib/utils"
3234

33-
import { Button } from "./ui/button"
35+
import { Button, buttonVariants } from "./ui/button"
3436
import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "./ui/resizable"
3537
import { Sidebar, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarProvider } from "./ui/sidebar"
3638
import { Tabs, TabsList, TabsTrigger } from "./ui/tabs"
@@ -49,6 +51,7 @@ type BlockViewerContext = {
4951
view: "code" | "preview"
5052
setActiveFile: (file: string) => void
5153
setView: (view: "code" | "preview") => void
54+
blocks?: boolean
5255
iframeKey?: number
5356
setIframeKey?: React.Dispatch<React.SetStateAction<number>>
5457
}
@@ -64,11 +67,12 @@ function useBlockViewer() {
6467
}
6568

6669
function BlockViewerProvider({
70+
blocks,
6771
children,
6872
highlightedFiles,
6973
item,
7074
tree,
71-
}: Pick<BlockViewerContext, "highlightedFiles" | "item" | "tree"> & {
75+
}: Pick<BlockViewerContext, "blocks" | "highlightedFiles" | "item" | "tree"> & {
7276
children: React.ReactNode
7377
}) {
7478
const [view, setView] = React.useState<BlockViewerContext["view"]>("preview")
@@ -82,6 +86,7 @@ function BlockViewerProvider({
8286
<BlockViewerContext.Provider
8387
value={{
8488
activeFile,
89+
blocks,
8590
highlightedFiles,
8691
iframeKey,
8792
item,
@@ -110,111 +115,156 @@ function BlockViewerProvider({
110115
}
111116

112117
function BlockViewerToolbar() {
113-
const { item, resizablePanelRef, setIframeKey, setView, view } =
118+
const { blocks, item, resizablePanelRef, setIframeKey, setView, view } =
114119
useBlockViewer()
120+
121+
115122
const { copyToClipboard, isCopied } = useCopyToClipboard()
116123

124+
const isPro = item?.meta?.isPro
125+
117126
return (
118-
<div className="hidden w-full items-center gap-2 pl-2 md:pr-6 lg:flex">
127+
<div className="hidden w-full items-center gap-2 pl-2 py-1 md:pr-6 lg:flex">
119128
<Tabs
120129
value={view}
121130
onValueChange={(value) => setView(value as "code" | "preview")}
122131
>
123-
<TabsList className="grid h-8 grid-cols-2 items-center rounded-md p-1 *:data-[slot=tabs-trigger]:h-6 *:data-[slot=tabs-trigger]:rounded-sm *:data-[slot=tabs-trigger]:px-2 *:data-[slot=tabs-trigger]:text-xs">
132+
<TabsList className={cn("grid h-8 items-center rounded-md p-1 *:data-[slot=tabs-trigger]:h-6 *:data-[slot=tabs-trigger]:rounded-sm *:data-[slot=tabs-trigger]:px-2 *:data-[slot=tabs-trigger]:text-xs",
133+
isPro ? "grid-cols-1" : "grid-cols-2"
134+
)}>
124135
<TabsTrigger value="preview">Preview</TabsTrigger>
125-
<TabsTrigger value="code">Code</TabsTrigger>
136+
{!isPro && <TabsTrigger value="code">Code</TabsTrigger>}
126137
</TabsList>
127138
</Tabs>
128139
<Separator orientation="vertical" className="mx-2 !h-4" />
129-
<a
130-
className="flex-1 text-center text-sm font-medium underline-offset-2 hover:underline md:flex-auto md:text-left"
131-
href={`#${item.name}`}
132-
>
133-
{item.description?.replace(/\.$/, "")}
134-
</a>
135-
<div className="ml-auto flex items-center gap-2">
136-
<div className="h-8 items-center gap-1.5 rounded-md border p-1 shadow-none">
137-
<ToggleGroup
138-
className="gap-1 *:data-[slot=toggle-group-item]:!size-6 *:data-[slot=toggle-group-item]:!rounded-sm"
139-
defaultValue="100"
140-
onValueChange={(value) => {
141-
setView("preview")
142-
if (resizablePanelRef?.current) {
143-
resizablePanelRef.current.resize(Number.parseInt(value))
144-
}
145-
}}
146-
type="single"
140+
141+
{
142+
blocks && (
143+
<a
144+
className="flex-1 text-center text-sm font-medium underline-offset-2 hover:underline md:flex-auto md:text-left"
145+
href={`#${item.name}`}
147146
>
148-
<ToggleGroupItem value="100" title="Desktop">
149-
<Monitor />
150-
</ToggleGroupItem>
151-
<ToggleGroupItem value="60" title="Tablet">
152-
<Tablet />
153-
</ToggleGroupItem>
154-
<ToggleGroupItem value="30" title="Mobile">
155-
<Smartphone />
156-
</ToggleGroupItem>
157-
<Separator orientation="vertical" className="!h-4" />
158-
<Button
159-
asChild
160-
size="icon"
161-
variant="ghost"
162-
className="size-6 rounded-sm p-0"
163-
title="Open in New Tab"
164-
>
165-
<Link href={`/blocks/${item.name}`} target="_blank">
166-
<span className="sr-only">Open in New Tab</span>
167-
<Fullscreen />
168-
</Link>
169-
</Button>
170-
<Separator orientation="vertical" className="!h-4" />
171-
<Button
172-
size="icon"
173-
variant="ghost"
174-
className="size-6 rounded-sm p-0"
175-
onClick={() => {
176-
if (setIframeKey) {
177-
setIframeKey((k) => k + 1)
178-
}
179-
}}
180-
title="Refresh Preview"
181-
>
182-
<RotateCw />
183-
<span className="sr-only">Refresh Preview</span>
184-
</Button>
185-
</ToggleGroup>
186-
</div>
187-
<Separator orientation="vertical" className="mx-1 !h-4" />
188-
<Button
189-
size="sm"
190-
variant="outline"
191-
className="w-fit gap-1 px-2 shadow-none"
192-
onClick={() => {
193-
copyToClipboard(`npx shadcn@latest add ${item.name}`)
194-
}}
147+
{item.description?.replace(/\.$/, "")}
148+
</a>
149+
)
150+
}
151+
152+
{isPro ? (
153+
<Link
154+
className={cn(
155+
buttonVariants(),
156+
'group relative flex justify-start gap-2 overflow-hidden rounded-sm whitespace-pre',
157+
'dark:bg-muted dark:text-foreground',
158+
'hover:ring-2 hover:ring-primary hover:ring-offset-2',
159+
'transition-all duration-300 ease-out',
160+
'h-[26px] px-2 text-xs'
161+
)}
162+
href={item.meta?.descriptionSrc ?? siteConfig.links.potionIframe}
163+
target="_blank"
195164
>
196-
{isCopied ? <Check /> : <Terminal />}
197-
<span>npx shadcn@latest add {item.name}</span>
198-
</Button>
199-
<Separator orientation="vertical" className="mx-1 !h-4" />
200-
</div>
165+
<span
166+
className={cn(
167+
'absolute right-0 -mt-12 h-32 w-8 translate-x-12 rotate-12',
168+
'bg-white opacity-10',
169+
'transition-all duration-1000 ease-out'
170+
)}
171+
/>
172+
Get the code
173+
</Link>
174+
) :
175+
(
176+
<div className="ml-auto flex items-center gap-2">
177+
{
178+
blocks && (
179+
<React.Fragment>
180+
<div className="h-8 items-center gap-1.5 rounded-md border p-1 shadow-none">
181+
<ToggleGroup
182+
className="gap-1 *:data-[slot=toggle-group-item]:!size-6 *:data-[slot=toggle-group-item]:!rounded-sm"
183+
defaultValue="100"
184+
onValueChange={(value) => {
185+
setView("preview")
186+
if (resizablePanelRef?.current) {
187+
resizablePanelRef.current.resize(Number.parseInt(value))
188+
}
189+
}}
190+
type="single"
191+
>
192+
<ToggleGroupItem value="100" title="Desktop">
193+
<Monitor />
194+
</ToggleGroupItem>
195+
<ToggleGroupItem value="60" title="Tablet">
196+
<Tablet />
197+
</ToggleGroupItem>
198+
<ToggleGroupItem value="30" title="Mobile">
199+
<Smartphone />
200+
</ToggleGroupItem>
201+
<Separator orientation="vertical" className="!h-4" />
202+
<Button
203+
asChild
204+
size="icon"
205+
variant="ghost"
206+
className="size-6 rounded-sm p-0"
207+
title="Open in New Tab"
208+
>
209+
<Link href={`/blocks/${item.name}`} target="_blank">
210+
<span className="sr-only">Open in New Tab</span>
211+
<Fullscreen />
212+
</Link>
213+
</Button>
214+
<Separator orientation="vertical" className="!h-4" />
215+
<Button
216+
size="icon"
217+
variant="ghost"
218+
className="size-6 rounded-sm p-0"
219+
onClick={() => {
220+
if (setIframeKey) {
221+
setIframeKey((k) => k + 1)
222+
}
223+
}}
224+
title="Refresh Preview"
225+
>
226+
<RotateCw />
227+
<span className="sr-only">Refresh Preview</span>
228+
</Button>
229+
</ToggleGroup>
230+
</div>
231+
<Separator orientation="vertical" className="mx-1 !h-4" />
232+
233+
<Button
234+
size="sm"
235+
variant="outline"
236+
className="w-fit gap-1 px-2 shadow-none"
237+
onClick={() => {
238+
copyToClipboard(`npx shadcn@latest add ${item.name}`)
239+
}}
240+
>
241+
{isCopied ? <Check /> : <Terminal />}
242+
<span>npx shadcn@latest add {item.name}</span>
243+
</Button>
244+
<Separator orientation="vertical" className="mx-1 !h-4" />
245+
</React.Fragment>
246+
)
247+
}
248+
249+
250+
</div>
251+
)
252+
}
253+
201254
</div>
202255
)
203256
}
204257

205258
function BlockViewerIframe() {
206259
const { iframeKey, item } = useBlockViewer()
207260

208-
console.log("🚀 ~ BlockViewerIframe ~ item:", item)
209-
210-
211261
const Preview = React.useMemo(() => {
212262

213-
if(item.meta?.isPro) return null
263+
if (item.meta?.isPro) return null
214264

215265
const Component = Index[item.name]?.component;
216266

217-
if (!Component ) {
267+
if (!Component) {
218268
return (
219269
<p className="text-sm text-muted-foreground">
220270
Component{' '}
@@ -484,6 +534,7 @@ function BlockViewer({
484534
}) {
485535
return (
486536
<BlockViewerProvider
537+
blocks={blocks}
487538
highlightedFiles={highlightedFiles}
488539
item={item}
489540
tree={tree}

apps/www/src/components/examples/component-preview.tsx renamed to apps/www/src/components/component-preview-internal.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import Image from "next/image"
22

33
import { Index } from "@/__registry__"
4-
import { ComponentPreviewTabs } from "@/components/examples/component-preview-tabs"
5-
import { ComponentSource } from "@/components/examples/component-source"
4+
import { ComponentPreviewTabs } from "@/components/component-preview-tabs"
5+
import { ComponentSource } from "@/components/component-source"
66

7-
export function ComponentPreview({
7+
export function ComponentPreviewInternal({
88
align = "center",
99
className,
1010
hideCode = false,

apps/www/src/components/component-preview-pro.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export function ComponentPreviewPro({
3030
{...props}
3131
>
3232
{description && <Markdown>{description}</Markdown>}
33-
123
33+
3434
<BlockDisplay
3535
id={id}
3636
name={name ?? ''}

0 commit comments

Comments
 (0)