学習ガイドカスタムノード

カスタムノード

Svelte Flowの強力な機能の一つは、カスタムノードを追加できることです。カスタムノードには、必要なものをすべてレンダリングできます。複数のソースハンドルとターゲットハンドルを定義したり、フォーム入力やインタラクティブなチャートをレンダリングしたりできます。このガイドでは、フローの背景色を更新するカラー入力フィールドを持つ2つのノードを実装します。

カスタムノードコンポーネントの作成

カスタムノードは、単なるSvelteコンポーネントです。内部的には、ドラッグや選択などの基本的な機能を提供するためにラップされます。ラッパーコンポーネントからは、その他のプロパティに加えて、位置やデータなどのプロパティが渡されます。

ColorPickerNodeの実装を始めましょう。カスタムノードを他のノードに接続するためにHandleコンポーネントを使用し、type="color"の入力フィールドをノードに追加します。

ColorPickerNode.svelte
<script lang="ts">
  import { Handle, Position, type NodeProps } from '@xyflow/svelte';
  import type { Writable } from 'svelte/store';
 
  type $$Props = NodeProps;
 
  export let data: { color: Writable<string> };
 
  const { color } = data;
</script>
 
<div class="colorpicker">
  <Handle type="target" position={Position.Left} />
  <div>
    color: <strong>{$color}</strong>
  </div>
  <input
    class="nodrag"
    type="color"
    on:input={(evt) => data.color.set(evt.target?.value)}
    value={$color}
  />
  <Handle type="source" position={Position.Right} />
</div>
 

ご覧のとおり、入力にクラス名「nodrag」を追加しました。これにより、入力フィールド内でのドラッグが防止され、この場合はノード内のテキストを選択できるようになります。

新しいノードタイプの追加

nodeTypesプロパティに追加することで、Svelte Flowに新しいノードタイプを追加できます。nodeTypesプロパティはオブジェクトであり、キーはノードタイプの名前で、値はこのノードタイプに対してレンダリングされるコンポーネントです。ColorPickerNodenodeTypesプロパティに追加してみましょう。

App.svelte
<script>
  import { SvelteFlow } from '@xyflow/svelte';
  import ColorPickerNode from './ColorPickerNode.svelte';
 
  const nodeTypes = {
    'color-picker': ColorPickerNode
  };
</script>
 
<SvelteFlow {nodeTypes} />

「colorPicker」ノードタイプを定義したら、typeノードオプションを設定することで、ノードに適用できます。

const nodes = writable([
  {
    id: 'node-1',
    // this type needs to match the newly defined node type
    type: 'color-picker',
    position: { x: 0, y: 0 },
    // data is used to store the current color value
    data: { color: writable('#ff4000') },
  },
]);

ノードのdataフィールドは、好きなデータを保存するために使用できます。この例では、現在のカラー値をwritable storeに保存しています。これにより、後でカスタムノード内から簡単に更新できます。すべてをまとめ、基本的なスタイルを追加すると、カラーピッカー付きの素敵なカスタムノードが完成します。

<script lang="ts">
const data: string = "world";
</script>

<h1>Hello {data}</h1>

<style>
h1 {
  font-size: 1.5rem;
}
</style>
読み取り専用

フローの背景色の調整

カラーピッカー付きのカスタムノードができたので、フローの背景色を更新してみましょう。これを少し面白くするために、別のノードを追加し、CSSのcolor-mix記法を使用して両方の色を混ぜます。このために、別のノードをnodes配列に追加し、両方のノードのカラーストアをサブスクライブします。いずれかの色が変わるたびに、フローの背景色を更新します。

<script lang="ts">
const data: string = "world";
</script>

<h1>Hello {data}</h1>

<style>
h1 {
  font-size: 1.5rem;
}
</style>
読み取り専用

不明なpropに関する警告の抑制

このガイドに従うと、ブラウザのコンソールに次のような警告が大量に表示される理由を不思議に思うでしょう。

<CustomNode /> was created with unknown prop 'height'

これは、ラッパーコンポーネントが、svelteコンポーネントに実装されているかどうかに関係なく、すべてのpropをカスタムノードコンポーネントに常に渡すためです。それらを抑制するには、次のように$$restPropsを1行追加するだけです。

CustomNode.svelte
<script>
    // Your svelte flow code...
 
    $$restProps;
</script>