Skip to content

Conversation

@nevehallon
Copy link

@nevehallon nevehallon commented Dec 2, 2025

🚀 What's changed?

  • Added generic type support to the VueFlow component using Vue 3.3+ generic attribute (<script setup generic="Data = ElementData">).
  • This allows consumers to pass a custom data type to VueFlow, enabling strict typing and IntelliSense for element data within the template (e.g., in scoped slots).

Example Usage:

<script setup lang="ts">
import { VueFlow } from '@vue-flow/core'

interface CustomData {
  test: string
  test2?: number
}

defineProps<{
  nodes: CustomData[],
  edges: CustomData[],
}>()

// Define a typed version of the component
const TypedVueFlow = VueFlow<CustomData>
</script>

<template>
  <TypedVueFlow
    :nodes="nodes"
    :edges="edges"
  >
    <template #node-test="{ data }">
      {{ data.test }}
      <!-- auto-complete/intellisense now works here -->
    </template>
  </TypedVueFlow>
</template>

🐛 DX

  • Support optional generic parameter of the FlowProps data (this affects the following prop-types modelValue, nodes, edges)

🪴 To-Dos

  • Explore inferring the Generic type automatically from the provided nodes and edges props instead of requiring explicit definition.
  • Add another 2 optional generics (CustomEvents and Type )

@codesandbox
Copy link

codesandbox bot commented Dec 2, 2025

Review or Edit in CodeSandbox

Open the branch in Web EditorVS CodeInsiders

Open Preview

@changeset-bot
Copy link

changeset-bot bot commented Dec 2, 2025

⚠️ No Changeset found

Latest commit: 3a26f19

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Dec 2, 2025

@nevehallon is attempting to deploy a commit to the Burak Cakmakoglu's projects Team on Vercel.

A member of the Team first needs to authorize it.

@nevehallon nevehallon changed the title feat: add optional Data generic type VueFlow container Component feat: add optional Data generic type for VueFlow container component Dec 2, 2025
@nevehallon nevehallon changed the title feat: add optional Data generic type for VueFlow container component feat: add optional Data generic type for VueFlow container component Dec 2, 2025
@bcakmakoglu
Copy link
Owner

thank you for the PR, appreciate it.
Alas, currently I've locked down VueFlow 1.x since 2.x is actively being worked on and this will be possible in the next major version, similar to how it works in ReactFlow already :)

@nevehallon
Copy link
Author

nevehallon commented Dec 3, 2025

Here is a v1 workaround — not ideal, not exhaustive, but might be useful until v2 lands:

import { VueFlow } from '@vue-flow/core';
import type { Elements, Node, NodeProps } from '@vue-flow/core';
import type { DefineComponent, SlotsType } from 'vue';

// Define your custom data interfaces
interface CustomData {
  label: string
  count: number
}
interface CustomData2 {
  label2: string
  count2: number
}

// Define your specific Node types
type MyCustomNode = Node<CustomData, any, 'custom'>
type MyCustomNode2 = Node<CustomData2, any, 'custom2'>

type FlowNodeUnion = MyCustomNode | MyCustomNode2
type FlowNodeType = 'custom' | 'custom2'

// Define the Slots you want to strictly type
type MyCustomSlots = {
  'node-custom': (props: NodeProps<CustomData, any, 'custom'>) => any
  'node-custom2': (props: NodeProps<CustomData2, any, 'custom2'>) => any
}

/**
 * ---------------------------------------------------------------------
 * MONKEY PATCH
 * ---------------------------------------------------------------------
 */

type OgVueFlowComponentT = typeof VueFlow
type OgVueFlowInstanceT = InstanceType<OgVueFlowComponentT>

type PropsWithOverrides = OgVueFlowInstanceT['$props'] & {
      nodes?: Node<FlowNodeUnion['data'], any, FlowNodeType>[];
      modelValue?: Elements<FlowNodeUnion['data']>;
    }

type SlotsWithoutOverrides = OgVueFlowInstanceT['$slots'] & SlotsType<MyCustomSlots>

type VueFlowTypedOverload = OgVueFlowComponentT &
  DefineComponent<
    PropsWithOverrides,
    {},
    {},
    {},
    {},
    {},
    {},
    {},
    string,
    {},
    {},
    {},
    SlotsWithoutOverrides
  >

export const VueFlowWithTypedSlots = VueFlow as VueFlowTypedOverload

@nevehallon nevehallon closed this Dec 3, 2025
@bcakmakoglu
Copy link
Owner

Thanks for posting a workaround =)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants