Browse Source
- Add parametersExpanded field to 5 generation node data types (NanoBanana, GenerateVideo, Generate3D, GenerateAudio, LLMGenerate) - Create useInlineParameters hook for localStorage-backed global setting (default: false) - Create InlineParameterPanel component with collapsible UI and chevron toggle - All TypeScript compiles without new errorshandoff-20260429-1057
3 changed files with 91 additions and 0 deletions
@ -0,0 +1,62 @@ |
|||||
|
"use client"; |
||||
|
|
||||
|
import { ReactNode } from "react"; |
||||
|
|
||||
|
interface InlineParameterPanelProps { |
||||
|
expanded: boolean; |
||||
|
onToggle: () => void; |
||||
|
children: ReactNode; |
||||
|
nodeId: string; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Collapsible parameter container for inline display within generation nodes. |
||||
|
* Provides a chevron toggle button and smooth expand/collapse transitions. |
||||
|
*/ |
||||
|
export function InlineParameterPanel({ |
||||
|
expanded, |
||||
|
onToggle, |
||||
|
children, |
||||
|
nodeId, |
||||
|
}: InlineParameterPanelProps) { |
||||
|
return ( |
||||
|
<div className="w-full"> |
||||
|
{/* Chevron toggle button - acts as visual boundary */} |
||||
|
<button |
||||
|
type="button" |
||||
|
onClick={onToggle} |
||||
|
className="nodrag nopan w-full flex items-center justify-center py-1 text-neutral-500 hover:text-neutral-300 transition-colors" |
||||
|
aria-label={expanded ? "Collapse parameters" : "Expand parameters"} |
||||
|
aria-expanded={expanded} |
||||
|
aria-controls={`params-${nodeId}`} |
||||
|
> |
||||
|
<svg |
||||
|
className="w-4 h-4 transition-transform duration-200" |
||||
|
style={{ transform: expanded ? "rotate(180deg)" : "rotate(0deg)" }} |
||||
|
viewBox="0 0 24 24" |
||||
|
fill="none" |
||||
|
stroke="currentColor" |
||||
|
strokeWidth="2" |
||||
|
strokeLinecap="round" |
||||
|
strokeLinejoin="round" |
||||
|
> |
||||
|
<polyline points="6 9 12 15 18 9" /> |
||||
|
</svg> |
||||
|
</button> |
||||
|
|
||||
|
{/* Collapsible content area */} |
||||
|
<div |
||||
|
id={`params-${nodeId}`} |
||||
|
className="overflow-hidden transition-all duration-200" |
||||
|
style={{ |
||||
|
maxHeight: expanded ? "2000px" : "0", |
||||
|
opacity: expanded ? 1 : 0, |
||||
|
}} |
||||
|
> |
||||
|
<div className="nodrag nopan nowheel bg-neutral-900/60 px-3 pb-3"> |
||||
|
<div className="space-y-2">{children}</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
); |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
import { useState, useCallback } from "react"; |
||||
|
|
||||
|
const INLINE_PARAMS_KEY = "node-banana-inline-parameters"; |
||||
|
|
||||
|
export function useInlineParameters() { |
||||
|
const [enabled, setEnabled] = useState(() => { |
||||
|
try { |
||||
|
return localStorage.getItem(INLINE_PARAMS_KEY) === "true"; |
||||
|
} catch { |
||||
|
return false; |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
const setInlineParameters = useCallback((value: boolean) => { |
||||
|
try { |
||||
|
localStorage.setItem(INLINE_PARAMS_KEY, String(value)); |
||||
|
} catch { |
||||
|
// localStorage not available
|
||||
|
} |
||||
|
setEnabled(value); |
||||
|
}, []); |
||||
|
|
||||
|
return { inlineParametersEnabled: enabled, setInlineParameters }; |
||||
|
} |
||||
Loading…
Reference in new issue