Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 35 additions & 84 deletions apps/www/app/blocks/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,10 @@ import { CodeBlock, Pre } from "fumadocs-ui/components/codeblock"
import { DocsLayout } from "fumadocs-ui/layouts/docs"
import { notFound } from "next/navigation"

import { BlockPageShell } from "@/components/blocks/block-page-shell"
import { getBlockShowcase } from "@/components/blocks/block-showcase"
import { BlockTopBar } from "@/components/blocks/breadcrumbs"
import { BlockInfoPane } from "@/components/blocks/info-pane"
import { BlockPreviewPane } from "@/components/blocks/preview-background"
import { getMDXComponents } from "@/components/mdx-components"
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"
import { blocksSource } from "@/lib/blocks-source"

export const revalidate = false
Expand Down Expand Up @@ -48,85 +42,42 @@ export default async function BlockPage(props: BlockPageProps) {
})}
/>
)
const info = (
<BlockInfoPane
content={content}
description={page.data.description}
title={page.data.title}
/>
)
const preview = <PreviewComponent />

return (
<div className="w-full">
<DocsLayout
sidebar={{
enabled: false,
}}
tree={blocksSource.getPageTree()}
>
<main className="relative min-h-screen bg-background">
<div className="flex size-full">
<div
className={`
w-full
lg:hidden
`}
>
<BlockPreviewPane>
<PreviewComponent />
</BlockPreviewPane>
<BlockInfoPane
content={content}
description={page.data.description}
title={page.data.title}
/>
</div>

<div
className={`
hidden h-screen w-full
lg:block
`}
>
<ResizablePanelGroup orientation="horizontal">
<ResizablePanel defaultSize={"35%"} minSize={"30%"}>
<div className="relative h-full overflow-hidden bg-transparent">
<BlockTopBar title={page.data.title} />
<div
aria-hidden="true"
className="pointer-events-none absolute inset-x-0 bottom-0 z-10"
style={{
backdropFilter: "blur(2px)",
background:
"linear-gradient(to top, color-mix(in oklch, var(--background) 100%, transparent) 0%, transparent 100%)",
height: "92px",
maskImage:
"linear-gradient(to top, black 50%, transparent 100%)",
WebkitBackdropFilter: "blur(2px)",
WebkitMaskImage:
"linear-gradient(to top, black 50%, transparent 100%)",
willChange: "backdrop-filter",
}}
/>

<div className="h-full min-w-0 overflow-x-hidden overflow-y-auto pt-16">
<BlockInfoPane
content={content}
description={page.data.description}
title={page.data.title}
/>
</div>
</div>
</ResizablePanel>

<ResizableHandle className="z-20" withHandle />

<ResizablePanel
className="relative"
defaultSize={"65%"}
minSize={"40%"}
>
<PreviewComponent />
</ResizablePanel>
</ResizablePanelGroup>
</div>
</div>
</main>
</DocsLayout>
</div>
<DocsLayout
nav={{
enabled: false,
}}
searchToggle={{
enabled: false,
}}
sidebar={{
enabled: false,
}}
tree={blocksSource.getPageTree()}
>
<main className="relative min-h-svh overflow-x-hidden bg-background">
<script
dangerouslySetInnerHTML={{
__html: `
document.documentElement.dataset.blockPreviewExpanded =
new URLSearchParams(window.location.search).get("expanded") === "true"
? "true"
: "false";
`,
}}
/>
<BlockPageShell info={info} preview={preview} title={page.data.title} />
</main>
</DocsLayout>
)
}

Expand Down
140 changes: 140 additions & 0 deletions apps/www/components/blocks/block-page-shell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
"use client"

import type { ReactNode } from "react"

import { useSyncExternalStore } from "react"

import { BlockTopBar } from "@/components/blocks/breadcrumbs"
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable"

const DESKTOP_QUERY = "(min-width: 1024px)"
const STACKED_QUERY = "(min-width: 768px)"

type BlockPageLayout = "desktop" | "mobile" | "stacked"

type BlockPageShellProps = {
info: ReactNode
preview: ReactNode
title: string
}

export function BlockPageShell({ info, preview, title }: BlockPageShellProps) {
const layout = useBlockPageLayout()

if (layout === "mobile") {
return (
<div className="w-full">
<div className="relative h-[min(70svh,32rem)] min-h-88 w-full overflow-hidden bg-muted">
{preview}
</div>
{info}
</div>
)
}

if (layout === "stacked") {
return (
<div className="w-full">
<div className="relative h-[clamp(26rem,70svh,44rem)] min-h-0 w-full overflow-hidden bg-muted">
{preview}
</div>
{info}
</div>
)
}

return (
<div className="h-screen w-full">
<ResizablePanelGroup orientation="horizontal">
<ResizablePanel
className={`
overflow-hidden opacity-100 transition-[opacity,filter,transform] duration-300 ease-out
in-data-[block-preview-expanded=true]:pointer-events-none in-data-[block-preview-expanded=true]:-translate-x-2
in-data-[block-preview-expanded=true]:opacity-0 in-data-[block-preview-expanded=true]:blur-sm
`}
defaultSize={"35%"}
minSize={"30%"}
>
<div className="relative h-full overflow-hidden bg-transparent">
<BlockTopBar title={title} />
<div
aria-hidden="true"
className="pointer-events-none absolute inset-x-0 bottom-0 z-10"
style={{
backdropFilter: "blur(2px)",
background:
"linear-gradient(to top, color-mix(in oklch, var(--background) 100%, transparent) 0%, transparent 100%)",
height: "92px",
maskImage:
"linear-gradient(to top, black 50%, transparent 100%)",
WebkitBackdropFilter: "blur(2px)",
WebkitMaskImage:
"linear-gradient(to top, black 50%, transparent 100%)",
}}
/>

<div className="h-full min-w-0 overflow-x-hidden overflow-y-auto pt-16">
{info}
</div>
</div>
</ResizablePanel>

<ResizableHandle
className={`
z-20 opacity-100 transition-opacity duration-300 ease-out
in-data-[block-preview-expanded=true]:pointer-events-none in-data-[block-preview-expanded=true]:opacity-0
`}
withHandle
/>

<ResizablePanel
className="relative"
defaultSize={"65%"}
minSize={"40%"}
>
{preview}
</ResizablePanel>
</ResizablePanelGroup>
</div>
)
}

function getBlockPageLayoutSnapshot(): BlockPageLayout {
if (window.matchMedia(DESKTOP_QUERY).matches) return "desktop"
if (window.matchMedia(STACKED_QUERY).matches) return "stacked"

return "mobile"
}

function getServerBlockPageLayoutSnapshot(): BlockPageLayout {
return "desktop"
}

function subscribeToBlockPageLayoutChange(onStoreChange: () => void) {
const mediaQueryLists = [
window.matchMedia(DESKTOP_QUERY),
window.matchMedia(STACKED_QUERY),
]

mediaQueryLists.forEach((mediaQueryList) => {
mediaQueryList.addEventListener("change", onStoreChange)
})

return () => {
mediaQueryLists.forEach((mediaQueryList) => {
mediaQueryList.removeEventListener("change", onStoreChange)
})
}
}

function useBlockPageLayout() {
return useSyncExternalStore(
subscribeToBlockPageLayoutChange,
getBlockPageLayoutSnapshot,
getServerBlockPageLayoutSnapshot
)
}
10 changes: 7 additions & 3 deletions apps/www/components/blocks/block-showcase.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { ReactNode } from "react"

import { AudioPlayerDemo } from "@/components/players/audio-player/demo-player"
import { VIDEO_PLAYER_DEMO_ASSETS } from "@/components/players/video-player/demo-assets"
import { VideoPlayer } from "@/registry/default/blocks/video-player/components/media-player"

import { BlockStreamSync } from "./block-toolbar"
import { BlockPreviewPane } from "./preview-background"
import { BlockPreviewWithToolbar } from "./preview-pane"

Expand All @@ -17,7 +17,9 @@ const blockShowcaseRegistry = {
<BlockPreviewWithToolbar>
<div className="flex size-full items-end">
<BlockPreviewPane>
<AudioPlayerDemo />
<AudioPlayerDemo>
<BlockStreamSync playerType="audio" />
</AudioPlayerDemo>
</BlockPreviewPane>
</div>
</BlockPreviewWithToolbar>
Expand All @@ -28,7 +30,9 @@ const blockShowcaseRegistry = {
<BlockPreviewWithToolbar>
<div className="flex size-full">
<BlockPreviewPane>
<VideoPlayer playlist={VIDEO_PLAYER_DEMO_ASSETS} />
<VideoPlayer>
<BlockStreamSync playerType="video" />
</VideoPlayer>
</BlockPreviewPane>
</div>
</BlockPreviewWithToolbar>
Expand Down
Loading
Loading