Fix the registryBlock component.

This commit is contained in:
Ivan Vasilov
2025-03-22 00:13:43 +01:00
parent 540a5d600b
commit 3e9b676e99
5 changed files with 83 additions and 8 deletions
@@ -3,9 +3,10 @@
import { RegistryNode } from '@/lib/process-registry'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@ui/components/shadcn/ui/tabs'
import { DynamicCodeBlock } from 'fumadocs-ui/components/dynamic-codeblock'
import { File, Folder } from 'fumadocs-ui/components/files'
import { useState } from 'react'
import supabaseTheme from '../lib/themes/supabase-2.json' assert { type: 'json' }
import { BlockItemPreview } from './block-item'
import { File, Folder } from './files'
interface BlockItemCodeProps {
files: RegistryNode[]
@@ -101,7 +102,12 @@ export function BlockItemCode({ files }: BlockItemCodeProps) {
value="code"
className="rounded-none [&_figure]:rounded-none [&_figure]:h-full [&_div[data-radix-scroll-area-viewport]]:min-h-[600px]"
>
<DynamicCodeBlock lang={selectedFileExtension} code={selectedFile?.content} />
<DynamicCodeBlock
lang={selectedFileExtension}
code={selectedFile?.content}
/* the component supports a theme prop, but it's typed badly */
options={{ theme: supabaseTheme } as any}
/>
</TabsContent>
<TabsContent value="preview" className="h-full flex-1">
{selectedFileDemoUrl && <BlockItemPreview title="" src={selectedFileDemoUrl} />}
+66
View File
@@ -0,0 +1,66 @@
'use client'
import { cva } from 'class-variance-authority'
import { FileIcon, FolderIcon, FolderOpen } from 'lucide-react'
import { useState, type HTMLAttributes, type ReactNode } from 'react'
import { cn, Collapsible_Shadcn_, CollapsibleContent_Shadcn_, CollapsibleTrigger_Shadcn_ } from 'ui'
const itemVariants = cva(
'flex flex-row items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-fd-accent hover:text-fd-accent-foreground [&_svg]:size-4'
)
export function Files({ className, ...props }: HTMLAttributes<HTMLDivElement>): React.ReactElement {
return (
<div className={cn('not-prose rounded-md border bg-fd-card p-2', className)} {...props}>
{props.children}
</div>
)
}
export interface FileProps extends HTMLAttributes<HTMLDivElement> {
name: string
icon?: ReactNode
}
export interface FolderProps extends HTMLAttributes<HTMLDivElement> {
name: string
disabled?: boolean
/**
* Open folder by default
*
* @defaultValue false
*/
defaultOpen?: boolean
}
export function File({
name,
icon = <FileIcon />,
className,
...rest
}: FileProps): React.ReactElement {
return (
<div className={cn(itemVariants({ className }))} {...rest}>
{icon}
{name}
</div>
)
}
export function Folder({ name, defaultOpen = false, ...props }: FolderProps): React.ReactElement {
const [open, setOpen] = useState(defaultOpen)
return (
<Collapsible_Shadcn_ open={open} onOpenChange={setOpen} {...props}>
<CollapsibleTrigger_Shadcn_ className={cn(itemVariants({ className: 'w-full' }))}>
{open ? <FolderOpen /> : <FolderIcon />}
{name}
</CollapsibleTrigger_Shadcn_>
<CollapsibleContent_Shadcn_>
<div className="ms-2 flex flex-col border-l ps-2">{props.children}</div>
</CollapsibleContent_Shadcn_>
</Collapsible_Shadcn_>
)
}
@@ -6,7 +6,7 @@ import { BlockItemCode } from './block-item-code'
export async function RegistryBlock({ itemName }: { itemName: string }) {
const registryPath = path.join(process.cwd(), 'public', 'r', `${itemName}.json`)
const tree = generateRegistryTree(itemName, registryPath)
const tree = generateRegistryTree(registryPath)
return <BlockItemCode files={tree} />
}
+7 -4
View File
@@ -25,7 +25,7 @@ const DEFAULT_PATHS = {
/**
* Converts a flat registry array into a hierarchical file tree structure
*/
export function generateRegistryTree(blockName: string, registryPath: string): RegistryNode[] {
export function generateRegistryTree(registryPath: string): RegistryNode[] {
const registry = JSON.parse(fs.readFileSync(registryPath, 'utf-8')) as { files: RegistryFile[] }
const tree: RegistryNode[] = []
@@ -45,8 +45,9 @@ export function generateRegistryTree(blockName: string, registryPath: string): R
// Remove any paths in the file content that point to the block directory.
const content = file.content
.replaceAll(/@\/registry\/blocks\/.+?\//gi, '@/')
.replaceAll(/@\/registry\//gi, '@/')
.replaceAll(/@\/registry\/default\/blocks\/.+?\//gi, '@/')
.replaceAll(/@\/registry\/default\//gi, '@/')
.replaceAll(/@\/clients\/.+?\//gi, '@/')
if (!node) {
node = {
@@ -76,7 +77,9 @@ function getDefaultPath(item: RegistryFile): string {
const type = item.type.toLowerCase() || ''
const basePath = DEFAULT_PATHS[type as keyof typeof DEFAULT_PATHS] || ''
// clean all paths that start with paths specific to this repo organization
const filePath = item.path.replace(/src\/registry\/blocks\/.+?\//, '')
const filePath = item.path
.replace(/registry\/default\/blocks\/.+?\//, '')
.replace(/registry\/default\/clients\/.+?\//, '')
return `${basePath}/${filePath}`
}
+1 -1
View File
@@ -3,7 +3,7 @@
"displayName": "Supabase Theme",
"semanticHighlighting": true,
"colors": {
"editor.background": "var(--code-highlight-color)",
"editor.background": "var(--background-surface-75) / 0.75",
"editor.foreground": "var(--code-foreground)",
"editor.lineHighlightBackground": "var(--code-highlight-color)",
"editorCursor.foreground": "var(--code-foreground)",