fix: improve rendering menu
This commit is contained in:
@@ -30,11 +30,13 @@ type Props = {
|
|||||||
insertTagsLabel?: string
|
insertTagsLabel?: string
|
||||||
/** Extra content in Node menu (e.g. Export submenu for render nodes), before the separator */
|
/** Extra content in Node menu (e.g. Export submenu for render nodes), before the separator */
|
||||||
nodeMenuExtraContent?: React.ReactNode
|
nodeMenuExtraContent?: React.ReactNode
|
||||||
|
/** When set, renders a top-level "Output" menu with this content (e.g. render node: preview/raw, viewport, export) */
|
||||||
|
outputMenuContent?: React.ReactNode
|
||||||
/** When set, renders a top-level "Data" menu with this content (e.g. data nodes) */
|
/** When set, renders a top-level "Data" menu with this content (e.g. data nodes) */
|
||||||
dataMenuContent?: React.ReactNode
|
dataMenuContent?: React.ReactNode
|
||||||
}
|
}
|
||||||
|
|
||||||
export function NodeMenubar({ nodeId, nodeType, editInputsContent, inputsMenuContent, insertTagsContent, insertMenuLabel = 'Insert', insertContentDirect, insertTagsLabel = 'Tags', nodeMenuExtraContent, dataMenuContent }: Props) {
|
export function NodeMenubar({ nodeId, nodeType, editInputsContent, inputsMenuContent, insertTagsContent, insertMenuLabel = 'Insert', insertContentDirect, insertTagsLabel = 'Tags', nodeMenuExtraContent, outputMenuContent, dataMenuContent }: Props) {
|
||||||
const ctx = useContext(FlowContext)
|
const ctx = useContext(FlowContext)
|
||||||
const nodes = ctx?.nodes ?? []
|
const nodes = ctx?.nodes ?? []
|
||||||
const setNodes = ctx?.setNodes
|
const setNodes = ctx?.setNodes
|
||||||
@@ -73,6 +75,16 @@ export function NodeMenubar({ nodeId, nodeType, editInputsContent, inputsMenuCon
|
|||||||
</MenubarItem>
|
</MenubarItem>
|
||||||
</MenubarContent>
|
</MenubarContent>
|
||||||
</MenubarMenu>
|
</MenubarMenu>
|
||||||
|
{outputMenuContent != null && (
|
||||||
|
<MenubarMenu>
|
||||||
|
<MenubarTrigger className="px-1.5 py-0 text-xs">
|
||||||
|
Output
|
||||||
|
</MenubarTrigger>
|
||||||
|
<MenubarContent className="min-w-[12rem]">
|
||||||
|
{outputMenuContent}
|
||||||
|
</MenubarContent>
|
||||||
|
</MenubarMenu>
|
||||||
|
)}
|
||||||
{dataMenuContent != null && (
|
{dataMenuContent != null && (
|
||||||
<MenubarMenu>
|
<MenubarMenu>
|
||||||
<MenubarTrigger className="px-1.5 py-0 text-xs">
|
<MenubarTrigger className="px-1.5 py-0 text-xs">
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import { NodeFooterEdgeIndicators } from '@/components/graph/NodeFooterEdgeIndic
|
|||||||
import { NodeHeaderTitle } from '@/components/graph/NodeHeaderTitle'
|
import { NodeHeaderTitle } from '@/components/graph/NodeHeaderTitle'
|
||||||
import { NodeMenubar } from '@/components/graph/NodeMenubar'
|
import { NodeMenubar } from '@/components/graph/NodeMenubar'
|
||||||
import { NodeStatusIndicator } from '@/components/graph/NodeStatusIndicator'
|
import { NodeStatusIndicator } from '@/components/graph/NodeStatusIndicator'
|
||||||
import { MenubarItem, MenubarSeparator, MenubarSub, MenubarSubContent, MenubarSubTrigger } from '@/components/ui/menubar'
|
import { MenubarCheckboxItem, MenubarItem, MenubarSeparator, MenubarSub, MenubarSubContent, MenubarSubTrigger } from '@/components/ui/menubar'
|
||||||
import { Sparkles, ZoomIn, ZoomOut, RotateCcw, RotateCw, Copy, Play, ChevronDown } from 'lucide-react'
|
import { Sparkles, ZoomIn, ZoomOut, RotateCcw, RotateCw, Copy, Play, ChevronDown } from 'lucide-react'
|
||||||
import { InputHandle } from '@/components/graph/NodeHandles'
|
import { InputHandle } from '@/components/graph/NodeHandles'
|
||||||
import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch'
|
import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch'
|
||||||
@@ -41,7 +41,6 @@ import {
|
|||||||
DropdownMenuLabel,
|
DropdownMenuLabel,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
} from '@/components/ui/dropdown-menu'
|
} from '@/components/ui/dropdown-menu'
|
||||||
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'
|
|
||||||
import { useTheme } from '@/lib/themeContext'
|
import { useTheme } from '@/lib/themeContext'
|
||||||
import { toast } from 'sonner'
|
import { toast } from 'sonner'
|
||||||
|
|
||||||
@@ -541,40 +540,6 @@ function RenderingNodeComponent({ id, data, width, height, selected }: Props) {
|
|||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
<ToggleGroup
|
|
||||||
type="single"
|
|
||||||
value={viewMode}
|
|
||||||
onValueChange={(v) => {
|
|
||||||
if (v === 'preview' || v === 'raw') setViewMode(v)
|
|
||||||
}}
|
|
||||||
aria-label="View mode"
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
className="gap-0 rounded-md p-0.5 [&>button]:rounded-none [&>button:first-child]:rounded-l-md [&>button:last-child]:rounded-r-md [&>button:not(:first-child)]:border-l-0"
|
|
||||||
>
|
|
||||||
<ToggleGroupItem
|
|
||||||
value="preview"
|
|
||||||
aria-label="Preview"
|
|
||||||
className="gap-1.5 px-2.5 h-7"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation()
|
|
||||||
setViewMode('preview')
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Preview
|
|
||||||
</ToggleGroupItem>
|
|
||||||
<ToggleGroupItem
|
|
||||||
value="raw"
|
|
||||||
aria-label="Raw config"
|
|
||||||
className="gap-1.5 px-2.5 h-7"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation()
|
|
||||||
setViewMode('raw')
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Raw
|
|
||||||
</ToggleGroupItem>
|
|
||||||
</ToggleGroup>
|
|
||||||
</div>
|
</div>
|
||||||
) : undefined
|
) : undefined
|
||||||
}
|
}
|
||||||
@@ -585,11 +550,26 @@ function RenderingNodeComponent({ id, data, width, height, selected }: Props) {
|
|||||||
<NodeMenubar
|
<NodeMenubar
|
||||||
nodeId={id}
|
nodeId={id}
|
||||||
nodeType="render"
|
nodeType="render"
|
||||||
nodeMenuExtraContent={
|
outputMenuContent={
|
||||||
<>
|
<>
|
||||||
|
<MenubarCheckboxItem
|
||||||
|
className="text-xs"
|
||||||
|
checked={viewMode === 'preview'}
|
||||||
|
onCheckedChange={(checked) => checked && setViewMode('preview')}
|
||||||
|
>
|
||||||
|
Preview
|
||||||
|
</MenubarCheckboxItem>
|
||||||
|
<MenubarCheckboxItem
|
||||||
|
className="text-xs"
|
||||||
|
checked={viewMode === 'raw'}
|
||||||
|
onCheckedChange={(checked) => checked && setViewMode('raw')}
|
||||||
|
>
|
||||||
|
Raw
|
||||||
|
</MenubarCheckboxItem>
|
||||||
|
<MenubarSeparator />
|
||||||
{outputType === 'image' && (
|
{outputType === 'image' && (
|
||||||
<MenubarSub>
|
<MenubarSub>
|
||||||
<MenubarSubTrigger className="text-xs">Viewport</MenubarSubTrigger>
|
<MenubarSubTrigger className="text-xs">Viewport size</MenubarSubTrigger>
|
||||||
<MenubarSubContent className="min-w-[12rem] p-2">
|
<MenubarSubContent className="min-w-[12rem] p-2">
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
@@ -631,10 +611,10 @@ function RenderingNodeComponent({ id, data, width, height, selected }: Props) {
|
|||||||
</MenubarSubContent>
|
</MenubarSubContent>
|
||||||
</MenubarSub>
|
</MenubarSub>
|
||||||
)}
|
)}
|
||||||
|
<MenubarSeparator />
|
||||||
<MenubarSub>
|
<MenubarSub>
|
||||||
<MenubarSeparator />
|
|
||||||
<MenubarSubTrigger className="text-xs" disabled={!isSvgOutput}>
|
<MenubarSubTrigger className="text-xs" disabled={!isSvgOutput}>
|
||||||
Export / Copy
|
Export
|
||||||
</MenubarSubTrigger>
|
</MenubarSubTrigger>
|
||||||
<MenubarSubContent className="min-w-[10rem]" aria-label="Export or copy diagram">
|
<MenubarSubContent className="min-w-[10rem]" aria-label="Export or copy diagram">
|
||||||
<MenubarItem className="text-xs" onClick={downloadSvg} disabled={!isSvgOutput}>
|
<MenubarItem className="text-xs" onClick={downloadSvg} disabled={!isSvgOutput}>
|
||||||
|
|||||||
Reference in New Issue
Block a user