Skip to content

Commit 5d89704

Browse files
committed
Merge remote-tracking branch 'origin/develop' into 036-cookbook-browser--8-11--handler-ref-ui-preview
# Conflicts: # frontend/src/features/cookbook/index.ts # frontend/src/features/cookbook/pages/detail.tsx
2 parents 6cc2b0b + 3f8d0c2 commit 5d89704

7 files changed

Lines changed: 488 additions & 1 deletion

File tree

frontend/package-lock.json

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"@codemirror/view": "^6.39.15",
2929
"@connectrpc/connect": "^2.1.1",
3030
"@connectrpc/connect-web": "^2.1.1",
31+
"@dagrejs/dagre": "^2.0.4",
3132
"@tanstack/react-query": "^5.90.21",
3233
"@tanstack/react-query-devtools": "^5.91.3",
3334
"@tanstack/react-table": "^8.21.3",
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { useState } from 'react'
2+
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
3+
4+
interface PreviewSourceTabsProps {
5+
preview: React.ReactNode
6+
source: string
7+
sourceLabel?: string
8+
className?: string
9+
}
10+
11+
export function PreviewSourceTabs({ preview, source, sourceLabel = 'Source', className }: PreviewSourceTabsProps) {
12+
const [copied, setCopied] = useState(false)
13+
14+
const handleCopy = () => {
15+
navigator.clipboard.writeText(source).then(() => {
16+
setCopied(true)
17+
setTimeout(() => setCopied(false), 2000)
18+
}).catch(() => {
19+
// Silently fail in restricted contexts
20+
})
21+
}
22+
23+
return (
24+
<Tabs defaultValue="preview" className={className}>
25+
<TabsList>
26+
<TabsTrigger value="preview">Preview</TabsTrigger>
27+
<TabsTrigger value="source">{sourceLabel}</TabsTrigger>
28+
</TabsList>
29+
30+
<TabsContent value="preview" className="mt-4">
31+
{preview}
32+
</TabsContent>
33+
34+
<TabsContent value="source" className="mt-4">
35+
<div className="relative">
36+
<button
37+
type="button"
38+
onClick={handleCopy}
39+
className="absolute right-2 top-2 z-10 rounded border bg-background px-2 py-1 text-xs text-muted-foreground hover:bg-accent"
40+
>
41+
{copied ? 'Copied' : 'Copy'}
42+
</button>
43+
<pre className="overflow-auto rounded-lg border bg-muted/50 p-4 text-xs leading-relaxed">
44+
<code>{source}</code>
45+
</pre>
46+
</div>
47+
</TabsContent>
48+
</Tabs>
49+
)
50+
}

0 commit comments

Comments
 (0)