diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f01326b..a5403feb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +## [1.1.1] - 2026-03-12 + +### Fixed + +- Ensure auto-routed prompts retain correct individual item text +- Add rounded corners to ImageInput image and InlineParameterPanel settings + +### Other + +- Increase ArrayNode top padding to match side padding +- Add top padding and max-width to ArrayNode top fields +- Update ArrayNode layout to match new design language + ## [1.1.0] - 2026-03-12 ### Added diff --git a/package.json b/package.json index 1fe2e27d..33752622 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-banana", - "version": "1.1.0", + "version": "1.1.1", "private": true, "scripts": { "dev": "node server.js", diff --git a/src/components/nodes/ArrayNode.tsx b/src/components/nodes/ArrayNode.tsx index 8fb4b4af..ce6ed0db 100644 --- a/src/components/nodes/ArrayNode.tsx +++ b/src/components/nodes/ArrayNode.tsx @@ -125,12 +125,15 @@ export function ArrayNode({ id, data, selected }: NodeProps) { const promptHeight = 220; const verticalGap = 24; + const promptNodeIds: string[] = []; + items.forEach((item, index) => { const promptNodeId = addNode( "prompt", { x: baseX, y: baseY + index * (promptHeight + verticalGap) }, { prompt: item } ); + promptNodeIds.push(promptNodeId); // Pass the array item index directly as an edge data override // instead of mutating selectedOutputIndex in a loop. @@ -144,7 +147,16 @@ export function ArrayNode({ id, data, selected }: NodeProps) { { arrayItemIndex: index } ); }); - }, [addNode, getNodes, id, onConnect, previewItems]); + + // Deferred fix-up: the PromptNode text-sync effect may overwrite the + // individual item text before the edge arrayItemIndex data is fully + // settled. Re-apply the correct per-item text after effects have run. + setTimeout(() => { + items.forEach((item, index) => { + updateNodeData(promptNodeIds[index], { prompt: item }); + }); + }, 0); + }, [addNode, getNodes, id, onConnect, previewItems, updateNodeData]); // Reset selection if it no longer points to a valid parsed item. useEffect(() => { @@ -156,9 +168,10 @@ export function ArrayNode({ id, data, selected }: NodeProps) { // Auto-resize node height to fit all parsed lines so users don't need to scroll. useEffect(() => { - const baseHeight = 360; - const perItemHeight = 30; - const newHeight = Math.max(baseHeight, 270 + previewItems.length * perItemHeight); + const headerHeight = 180; + const perItemHeight = 28; + const itemsMinHeight = 60; + const newHeight = headerHeight + Math.max(itemsMinHeight, previewItems.length * perItemHeight + 8); setNodes((nodes) => nodes.map((node) => { @@ -174,8 +187,8 @@ export function ArrayNode({ id, data, selected }: NodeProps) { id={id} selected={selected} hasError={!!nodeData.error} - minWidth={320} - minHeight={300} + minWidth={300} + minHeight={220} > @@ -187,7 +200,7 @@ export function ArrayNode({ id, data, selected }: NodeProps) { type="button" onClick={handleAutoRouteToPrompts} disabled={previewItems.length === 0} - className="nodrag nopan absolute top-2 right-2 z-10 shrink-0 p-1 rounded border border-neutral-600 bg-neutral-800/90 text-neutral-300 hover:bg-neutral-700 hover:text-neutral-100 disabled:opacity-50 disabled:cursor-not-allowed" + className="nodrag nopan absolute top-2 right-2 z-10 shrink-0 p-1 bg-[#1a1a1a] rounded-md text-neutral-400 hover:text-neutral-100 transition-colors disabled:opacity-50 disabled:cursor-not-allowed" title="Auto-route to Prompts" > @@ -195,13 +208,13 @@ export function ArrayNode({ id, data, selected }: NodeProps) { -
-
- +
+
+ updateNodeData(id, { delimiter: e.target.value })} placeholder="*" - className="nodrag nopan bg-neutral-900 border border-neutral-700 rounded px-2 py-1 text-[11px] text-neutral-100 focus:outline-none focus:ring-1 focus:ring-neutral-600" + className="nodrag nopan flex-1 min-w-0 text-[11px] py-1 px-2 bg-[#1a1a1a] rounded-md focus:outline-none focus:ring-1 focus:ring-neutral-600 text-white" />
)} {nodeData.splitMode === "regex" && ( -
- +
+ updateNodeData(id, { regexPattern: e.target.value })} placeholder="/\\n+/" - className="nodrag nopan bg-neutral-900 border border-neutral-700 rounded px-2 py-1 text-[11px] text-neutral-100 focus:outline-none focus:ring-1 focus:ring-neutral-600" + className="nodrag nopan flex-1 min-w-0 text-[11px] py-1 px-2 bg-[#1a1a1a] rounded-md focus:outline-none focus:ring-1 focus:ring-neutral-600 text-white" />
)} -
+
{showAdvanced && ( -
-
- - -
+
+ +
)}
-
+
Parsed Items ({previewItems.length})
-
+
{nodeData.error ? (
{nodeData.error}
) : previewItems.length === 0 ? ( @@ -282,24 +295,23 @@ export function ArrayNode({ id, data, selected }: NodeProps) { {previewItems.map((item, index) => { const isSelected = nodeData.selectedOutputIndex === index; return ( -
- -
+ ); })}
diff --git a/src/components/nodes/ImageInputNode.tsx b/src/components/nodes/ImageInputNode.tsx index 71c825c6..efc6faf1 100644 --- a/src/components/nodes/ImageInputNode.tsx +++ b/src/components/nodes/ImageInputNode.tsx @@ -111,7 +111,7 @@ export function ImageInputNode({ id, data, selected }: NodeProps