Command Palette

Search for a command to run...

TreegeEditor

The TreegeEditor component provides a visual drag-and-drop interface for building workflow.

Import

import { TreegeEditor } from "treege/editor"

Props

onSave (optional)

Callback function called when the user saves the flow.

onSave?: (flow: Flow) => void

The Save button only appears when this prop is provided — wire it only if you want an explicit save action. It is no longer disabled on an empty canvas, so a cleared flow can be saved (e.g. to persist a reset).

onChange (optional)

Called (debounced ~150 ms) on every canvas change with the current flow. Use it for live preview or autosave: feed it straight to a TreegeRenderer to render the form as the user edits.

onChange?: (flow: Flow) => void

Unlike onSave, onChange is not gated on having input nodes, so it also reports an emptied canvas after Clear. It does not strip sensitive headers (live consumers like the renderer need the real flow), so don't persist its output verbatim if that matters to you.

import { useState } from "react"
import { TreegeEditor } from "treege/editor"
import { TreegeRenderer } from "treege/renderer"
import type { Flow } from "treege"
 
export default function LivePreview() {
  const [flow, setFlow] = useState<Flow | null>(null)
 
  return (
    <div className="flex h-screen">
      <TreegeEditor onChange={setFlow} />         {/* live, no Save button */}
      <TreegeRenderer flow={flow} onSubmit={console.log} />
    </div>
  )
}

flow (optional)

Initial flow data to load in the editor.

flow?: Flow | null

theme (optional)

Theme for the editor interface.

theme?: "light" | "dark"

Default: "dark"

language (optional)

Language for the editor interface.

language?: string

Default: "en"

aiConfig (optional)

AI configuration for natural-language tree generation. Supports multiple providers (Gemini, OpenAI, DeepSeek, Claude).

aiConfig?: AIConfig

AIConfig structure:

type AIConfig = {
  provider?: "gemini" | "openai" | "deepseek" | "claude" // default: "gemini"
  apiKey: string
  model?: string       // optional model override (provider default used otherwise)
  temperature?: number // 0–1, default 0.7
}

When provided, enables AI-powered tree generation in the editor.

onExportJson (optional)

Callback function triggered when exporting JSON data.

onExportJson?: () => { nodes: Node[]; edges: Edge[] } | undefined

className (optional)

Additional CSS class names for custom styling.

className?: string

extraMenuItems (optional)

Extra entries appended to the actions panel "more" dropdown.

extraMenuItems?: ExtraMenuItem[] // { label: ReactNode; icon?: ReactNode; onClick?: () => void; destructive?: boolean }[]

openApi (optional)

OpenAPI 3.x source used to power URL/route suggestions (in HTTP and options-source forms) and the Authorize flow. Accepts a pre-parsed document or a URL string (the editor fetches it on mount and toasts on failure).

openApi?: OpenApiDocument | string

baseUrl (optional)

Base URL the produced tree is meant to run against — pass the same value you give to TreegeRenderer's baseUrl. HTTP and options-source urls are stored relative to it (so the exported JSON stays environment-agnostic), it's shown as a read-only prefix on URL fields, and it's used to resolve the "Detect fields" probe so editor-time previews hit a real host. When an OpenAPI document is loaded, its servers[0].url (or the Authorize override) takes precedence for route resolution.

baseUrl?: string

headers (optional)

Global HTTP headers applied to in-editor requests (e.g. the "Detect fields" button). Pass the same value you give to TreegeRenderer so editor previews use the same auth/headers as runtime.

headers?: HttpHeaders

onAuthorize (optional)

Called when the user submits the Authorize dialog. Forward the resulting headers to TreegeRenderer (or TreegeRendererProvider) so every form request is authenticated.

onAuthorize?: (headers: HttpHeaders) => void

onHeadersChange (optional)

Called when the user edits headers in the built-in "Global headers" dialog. The component is controlled — update your headers state in response and pass the new object back via the headers prop.

onHeadersChange?: (headers: HttpHeaders) => void

Example

Basic Usage

import { useState } from "react"
import { TreegeEditor } from "treege/editor"
import type { Flow } from "treege"
 
export default function Editor() {
  const [flow, setFlow] = useState<Flow | null>(null)
 
  const handleSave = async (flowData: Flow) => {
    await fetch("/api/flow", {
      method: "POST",
      body: JSON.stringify(flowData)
    })
    setFlow(flowData)
  }
 
  return (
    <div className="h-screen">
      <TreegeEditor
        flow={flow}
        onSave={handleSave}
        theme="dark"
        language="en"
      />
    </div>
  )
}

With AI Configuration

import { useState } from "react"
import { TreegeEditor } from "treege/editor"
import type { Flow } from "treege"
 
export default function AIEditor() {
  const [flow, setFlow] = useState<Flow | null>(null)
 
  return (
    <div className="h-screen">
      <TreegeEditor
        flow={flow}
        onSave={(flowData) => setFlow(flowData)}
        theme="dark"
        language="en"
        aiConfig={{
          provider: "gemini",
          // Read the key from a client-exposed env var — e.g.
          // process.env.NEXT_PUBLIC_GEMINI_API_KEY (Next.js) or
          // import.meta.env.VITE_GEMINI_API_KEY (Vite). Never hardcode it.
          apiKey: process.env.NEXT_PUBLIC_GEMINI_API_KEY || ""
        }}
      />
    </div>
  )
}