feat(Minimap): add nodeComponent prop

This commit is contained in:
Abbey Yacoe
2025-09-04 11:23:25 +02:00
parent 4783957dbf
commit 24350a70e7
6 changed files with 132 additions and 15 deletions

View File

@@ -7,6 +7,7 @@
'add-node-on-drop',
'color-mode',
'custom-connection-line',
'custom-minimap',
'customnode',
'dagre',
'detached-handle',

View File

@@ -0,0 +1,48 @@
<script lang="ts">
import {
SvelteFlow,
Background,
Controls,
MiniMap,
type Node,
type Edge,
} from '@xyflow/svelte';
import '@xyflow/svelte/dist/style.css';
import CustomMiniMapNode from './CustomMiniMapNode.svelte';
let nodes = $state.raw<Node[]>([]);
let edges = $state.raw<Edge[]>([]);
function addRandomNode() {
const nodeId = (nodes.length + 1).toString();
const newNode: Node = {
id: nodeId,
data: { label: `Node: ${nodeId}` },
position: {
x: Math.random() * (typeof window !== 'undefined' ? window.innerWidth : 800),
y: Math.random() * (typeof window !== 'undefined' ? window.innerHeight : 600),
},
type: 'default'
};
nodes = [...nodes, newNode];
}
</script>
<SvelteFlow
bind:nodes
bind:edges
onlyRenderVisibleElements={true}
>
<Controls />
<Background />
<MiniMap nodeComponent={CustomMiniMapNode} />
<button
type="button"
onclick={addRandomNode}
style="position: absolute; left: 10px; top: 10px; z-index: 4;"
>
add node
</button>
</SvelteFlow>

View File

@@ -0,0 +1,22 @@
<script lang="ts">
let {
x,
y,
width,
height,
selected,
}: {
x: number;
y: number;
width: number;
height: number;
selected?: boolean;
} = $props();
</script>
<circle
cx={x + width / 2}
cy={y + height / 2}
r={Math.min(width, height) - 2}
fill={selected ? "#ff6b6b" : "#ffcc00"}
/>

View File

@@ -27,6 +27,7 @@
nodeClass = '',
nodeBorderRadius = 5,
nodeStrokeWidth = 2,
nodeComponent,
bgColor,
maskColor,
maskStrokeColor,
@@ -127,6 +128,7 @@
y={node.internals.positionAbsolute.y}
{...nodeDimesions}
selected={node.selected}
nodeComponent={nodeComponent}
color={nodeColorFunc?.(node)}
borderRadius={nodeBorderRadius}
strokeColor={nodeStrokeColorFunc(node)}

View File

@@ -1,5 +1,7 @@
<script lang="ts">
import type { ClassValue } from 'svelte/elements';
import type { Component } from 'svelte';
import type { MiniMapNodeProps } from './types';
let {
x,
@@ -12,7 +14,8 @@
strokeColor,
strokeWidth = 2,
selected,
class: className
class: className,
nodeComponent
}: {
x: number;
y: number;
@@ -25,20 +28,39 @@
strokeWidth?: number;
selected?: boolean;
class?: ClassValue;
nodeComponent?: Component<MiniMapNodeProps>;
} = $props();
</script>
<rect
class={['svelte-flow__minimap-node', className]}
class:selected
{x}
{y}
rx={borderRadius}
ry={borderRadius}
{width}
{height}
style:fill={color}
style:stroke={strokeColor}
style:stroke-width={strokeWidth}
shape-rendering={shapeRendering}
/>
{#if nodeComponent}
{@const CustomComponent = nodeComponent}
<CustomComponent
{x}
{y}
{width}
{height}
{borderRadius}
class={className}
{color}
{shapeRendering}
{strokeColor}
{strokeWidth}
{selected}
/>
{:else}
<rect
class={['svelte-flow__minimap-node', className]}
class:selected
{x}
{y}
rx={borderRadius}
ry={borderRadius}
{width}
{height}
style:fill={color}
style:stroke={strokeColor}
style:stroke-width={strokeWidth}
shape-rendering={shapeRendering}
/>
{/if}

View File

@@ -1,9 +1,29 @@
import type { PanelPosition } from '@xyflow/system';
import type { ClassValue, HTMLAttributes } from 'svelte/elements';
import type { Component } from 'svelte';
import type { Node } from '$lib/types';
export type GetMiniMapNodeAttribute = (node: Node) => string;
/**
* The props that are passed to the MiniMapNode component
*
* @public
*/
export type MiniMapNodeProps = {
x: number;
y: number;
width: number;
height: number;
borderRadius?: number;
class?: ClassValue;
color?: string;
shapeRendering?: string;
strokeColor?: string;
strokeWidth?: number;
selected?: boolean;
};
export type MiniMapProps = {
/** Background color of minimap */
bgColor?: string;
@@ -17,6 +37,8 @@ export type MiniMapProps = {
nodeBorderRadius?: number;
/** Stroke width of nodes on the minimap */
nodeStrokeWidth?: number;
/** A custom component to render the nodes in the minimap. This component must render an SVG element! */
nodeComponent?: Component<MiniMapNodeProps>;
/** Color of the mask representing viewport */
maskColor?: string;
/** Stroke color of the mask representing viewport */