reflex-xyflow 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- reflex_xyflow/__init__.py +147 -0
- reflex_xyflow/_base.py +29 -0
- reflex_xyflow/components.py +141 -0
- reflex_xyflow/custom.py +124 -0
- reflex_xyflow/enums.py +76 -0
- reflex_xyflow/flow.py +212 -0
- reflex_xyflow/imperative.py +133 -0
- reflex_xyflow/utils.py +259 -0
- reflex_xyflow-0.0.1.dist-info/METADATA +191 -0
- reflex_xyflow-0.0.1.dist-info/RECORD +13 -0
- reflex_xyflow-0.0.1.dist-info/WHEEL +5 -0
- reflex_xyflow-0.0.1.dist-info/licenses/LICENSE +201 -0
- reflex_xyflow-0.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"""reflex-xyflow: a Reflex custom component wrapping ``@xyflow/react``.
|
|
2
|
+
|
|
3
|
+
Import the factory functions to build node-based UIs in pure Python::
|
|
4
|
+
|
|
5
|
+
import reflex as rx
|
|
6
|
+
import reflex_xyflow as xyflow
|
|
7
|
+
|
|
8
|
+
def index():
|
|
9
|
+
return rx.box(
|
|
10
|
+
xyflow.react_flow(
|
|
11
|
+
xyflow.background(),
|
|
12
|
+
xyflow.controls(),
|
|
13
|
+
xyflow.mini_map(),
|
|
14
|
+
nodes=State.nodes,
|
|
15
|
+
edges=State.edges,
|
|
16
|
+
on_nodes_change=State.on_nodes_change,
|
|
17
|
+
on_connect=State.on_connect,
|
|
18
|
+
fit_view=True,
|
|
19
|
+
),
|
|
20
|
+
width="100vw",
|
|
21
|
+
height="100vh",
|
|
22
|
+
)
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
from ._base import XYFLOW_NPM_PACKAGE, XYFLOW_NPM_VERSION
|
|
28
|
+
from .components import (
|
|
29
|
+
Background,
|
|
30
|
+
Controls,
|
|
31
|
+
Handle,
|
|
32
|
+
MiniMap,
|
|
33
|
+
NodeResizer,
|
|
34
|
+
NodeToolbar,
|
|
35
|
+
Panel,
|
|
36
|
+
background,
|
|
37
|
+
controls,
|
|
38
|
+
handle,
|
|
39
|
+
mini_map,
|
|
40
|
+
node_resizer,
|
|
41
|
+
node_toolbar,
|
|
42
|
+
panel,
|
|
43
|
+
)
|
|
44
|
+
from .custom import XYFlowCustomTypes, custom_types, js_component
|
|
45
|
+
from .enums import (
|
|
46
|
+
BackgroundVariant,
|
|
47
|
+
ColorMode,
|
|
48
|
+
ConnectionLineType,
|
|
49
|
+
ConnectionMode,
|
|
50
|
+
HandleType,
|
|
51
|
+
MarkerType,
|
|
52
|
+
PanOnScrollMode,
|
|
53
|
+
Position,
|
|
54
|
+
SelectionMode,
|
|
55
|
+
)
|
|
56
|
+
from .flow import (
|
|
57
|
+
ReactFlow,
|
|
58
|
+
ReactFlowProvider,
|
|
59
|
+
react_flow,
|
|
60
|
+
react_flow_provider,
|
|
61
|
+
)
|
|
62
|
+
from .imperative import (
|
|
63
|
+
XYFlowController,
|
|
64
|
+
download_image,
|
|
65
|
+
fit_view,
|
|
66
|
+
flow_controller,
|
|
67
|
+
get_edges,
|
|
68
|
+
get_nodes,
|
|
69
|
+
get_viewport,
|
|
70
|
+
set_center,
|
|
71
|
+
set_viewport,
|
|
72
|
+
zoom_in,
|
|
73
|
+
zoom_out,
|
|
74
|
+
)
|
|
75
|
+
from .utils import (
|
|
76
|
+
add_edge,
|
|
77
|
+
apply_edge_changes,
|
|
78
|
+
apply_node_changes,
|
|
79
|
+
deserialize_graph,
|
|
80
|
+
layout_nodes,
|
|
81
|
+
reconnect_edge,
|
|
82
|
+
serialize_graph,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
__version__ = "0.0.1"
|
|
86
|
+
|
|
87
|
+
__all__ = [
|
|
88
|
+
# version / package metadata
|
|
89
|
+
"__version__",
|
|
90
|
+
"XYFLOW_NPM_PACKAGE",
|
|
91
|
+
"XYFLOW_NPM_VERSION",
|
|
92
|
+
# core flow
|
|
93
|
+
"ReactFlow",
|
|
94
|
+
"ReactFlowProvider",
|
|
95
|
+
"react_flow",
|
|
96
|
+
"react_flow_provider",
|
|
97
|
+
# components (classes)
|
|
98
|
+
"Background",
|
|
99
|
+
"Controls",
|
|
100
|
+
"MiniMap",
|
|
101
|
+
"Panel",
|
|
102
|
+
"Handle",
|
|
103
|
+
"NodeResizer",
|
|
104
|
+
"NodeToolbar",
|
|
105
|
+
# components (factories)
|
|
106
|
+
"background",
|
|
107
|
+
"controls",
|
|
108
|
+
"mini_map",
|
|
109
|
+
"panel",
|
|
110
|
+
"handle",
|
|
111
|
+
"node_resizer",
|
|
112
|
+
"node_toolbar",
|
|
113
|
+
# enums
|
|
114
|
+
"Position",
|
|
115
|
+
"HandleType",
|
|
116
|
+
"BackgroundVariant",
|
|
117
|
+
"ConnectionMode",
|
|
118
|
+
"ConnectionLineType",
|
|
119
|
+
"MarkerType",
|
|
120
|
+
"PanOnScrollMode",
|
|
121
|
+
"SelectionMode",
|
|
122
|
+
"ColorMode",
|
|
123
|
+
# utils
|
|
124
|
+
"apply_node_changes",
|
|
125
|
+
"apply_edge_changes",
|
|
126
|
+
"add_edge",
|
|
127
|
+
"reconnect_edge",
|
|
128
|
+
"serialize_graph",
|
|
129
|
+
"deserialize_graph",
|
|
130
|
+
"layout_nodes",
|
|
131
|
+
# imperative useReactFlow API
|
|
132
|
+
"XYFlowController",
|
|
133
|
+
"flow_controller",
|
|
134
|
+
"fit_view",
|
|
135
|
+
"zoom_in",
|
|
136
|
+
"zoom_out",
|
|
137
|
+
"set_viewport",
|
|
138
|
+
"set_center",
|
|
139
|
+
"get_nodes",
|
|
140
|
+
"get_edges",
|
|
141
|
+
"get_viewport",
|
|
142
|
+
"download_image",
|
|
143
|
+
# custom node/edge types
|
|
144
|
+
"js_component",
|
|
145
|
+
"custom_types",
|
|
146
|
+
"XYFlowCustomTypes",
|
|
147
|
+
]
|
reflex_xyflow/_base.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Base component for the reflex-xyflow wrapper.
|
|
2
|
+
|
|
3
|
+
All wrapped React Flow components inherit from :class:`XYFlowBase`, which pins
|
|
4
|
+
the ``@xyflow/react`` npm dependency and injects the required stylesheet once
|
|
5
|
+
per page.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import reflex as rx
|
|
11
|
+
|
|
12
|
+
# Pin the wrapped npm package version. Bump this together with the Python
|
|
13
|
+
# package version when adopting a new React Flow release.
|
|
14
|
+
XYFLOW_NPM_PACKAGE = "@xyflow/react"
|
|
15
|
+
XYFLOW_NPM_VERSION = "12.8.6"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class XYFlowBase(rx.Component):
|
|
19
|
+
"""Base class for every component wrapped from ``@xyflow/react``."""
|
|
20
|
+
|
|
21
|
+
# The npm dependency installed into the compiled frontend.
|
|
22
|
+
library = f"{XYFLOW_NPM_PACKAGE}@{XYFLOW_NPM_VERSION}"
|
|
23
|
+
|
|
24
|
+
# React Flow is a default export-less ESM module: every public component is
|
|
25
|
+
# a named export, so ``is_default`` stays False (the Reflex default).
|
|
26
|
+
|
|
27
|
+
def add_custom_code(self) -> list[str]:
|
|
28
|
+
"""Import the React Flow base stylesheet exactly once per page."""
|
|
29
|
+
return ['import "@xyflow/react/dist/style.css";']
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"""Supporting React Flow components: Background, Controls, MiniMap, Panel,
|
|
2
|
+
Handle, NodeResizer and NodeToolbar.
|
|
3
|
+
|
|
4
|
+
All of these are named exports of ``@xyflow/react`` (v12), so they share the
|
|
5
|
+
:class:`XYFlowBase` base and only declare the props we surface to Python.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
import reflex as rx
|
|
11
|
+
from reflex.vars import Var
|
|
12
|
+
|
|
13
|
+
from ._base import XYFlowBase
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# -- Event-handler argument specs --------------------------------------------
|
|
17
|
+
def _no_args_spec() -> tuple:
|
|
18
|
+
return ()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _interactive_spec(is_interactive: Var[bool]) -> tuple[Var[bool]]:
|
|
22
|
+
return (is_interactive,)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _resize_spec(event: Var, params: Var[dict]) -> tuple[Var[dict]]:
|
|
26
|
+
"""NodeResizer resize handlers: forward the ``{x, y, width, height}`` params."""
|
|
27
|
+
return (params,)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Background(XYFlowBase):
|
|
31
|
+
"""Renders the dotted / lined / cross background pattern of the canvas."""
|
|
32
|
+
|
|
33
|
+
tag = "Background"
|
|
34
|
+
|
|
35
|
+
variant: Var[str] # "dots" | "lines" | "cross"
|
|
36
|
+
color: Var[str]
|
|
37
|
+
bg_color: Var[str]
|
|
38
|
+
gap: Var[int]
|
|
39
|
+
size: Var[float]
|
|
40
|
+
offset: Var[float]
|
|
41
|
+
line_width: Var[float]
|
|
42
|
+
# Multiple backgrounds may be layered; an id keeps their patterns distinct.
|
|
43
|
+
id: Var[str]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class Controls(XYFlowBase):
|
|
47
|
+
"""Zoom in / out, fit-view and interactivity-lock control panel."""
|
|
48
|
+
|
|
49
|
+
tag = "Controls"
|
|
50
|
+
|
|
51
|
+
show_zoom: Var[bool]
|
|
52
|
+
show_fit_view: Var[bool]
|
|
53
|
+
show_interactive: Var[bool]
|
|
54
|
+
fit_view_options: Var[dict[str, Any]]
|
|
55
|
+
position: Var[str]
|
|
56
|
+
orientation: Var[str] # "horizontal" | "vertical"
|
|
57
|
+
|
|
58
|
+
on_zoom_in: rx.EventHandler[_no_args_spec]
|
|
59
|
+
on_zoom_out: rx.EventHandler[_no_args_spec]
|
|
60
|
+
on_fit_view: rx.EventHandler[_no_args_spec]
|
|
61
|
+
on_interactive_change: rx.EventHandler[_interactive_spec]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class MiniMap(XYFlowBase):
|
|
65
|
+
"""Overview map of the whole graph."""
|
|
66
|
+
|
|
67
|
+
tag = "MiniMap"
|
|
68
|
+
|
|
69
|
+
pannable: Var[bool]
|
|
70
|
+
zoomable: Var[bool]
|
|
71
|
+
node_color: Var[str]
|
|
72
|
+
node_stroke_color: Var[str]
|
|
73
|
+
node_border_radius: Var[int]
|
|
74
|
+
node_stroke_width: Var[float]
|
|
75
|
+
mask_color: Var[str]
|
|
76
|
+
mask_stroke_color: Var[str]
|
|
77
|
+
position: Var[str]
|
|
78
|
+
aria_label: Var[str]
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class Panel(XYFlowBase):
|
|
82
|
+
"""Absolutely-positioned overlay (e.g. for toolbars/buttons on the canvas)."""
|
|
83
|
+
|
|
84
|
+
tag = "Panel"
|
|
85
|
+
|
|
86
|
+
position: Var[str] # "top-left" | "top-right" | "bottom-left" ...
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class Handle(XYFlowBase):
|
|
90
|
+
"""Connection point rendered inside a custom node component."""
|
|
91
|
+
|
|
92
|
+
tag = "Handle"
|
|
93
|
+
|
|
94
|
+
type: Var[str] # "source" | "target"
|
|
95
|
+
position: Var[str] # "top" | "right" | "bottom" | "left"
|
|
96
|
+
id: Var[str]
|
|
97
|
+
is_connectable: Var[bool]
|
|
98
|
+
is_connectable_start: Var[bool]
|
|
99
|
+
is_connectable_end: Var[bool]
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class NodeResizer(XYFlowBase):
|
|
103
|
+
"""Adds resize handles around a custom node."""
|
|
104
|
+
|
|
105
|
+
tag = "NodeResizer"
|
|
106
|
+
|
|
107
|
+
color: Var[str]
|
|
108
|
+
handle_class_name: Var[str]
|
|
109
|
+
line_class_name: Var[str]
|
|
110
|
+
is_visible: Var[bool]
|
|
111
|
+
min_width: Var[int]
|
|
112
|
+
min_height: Var[int]
|
|
113
|
+
max_width: Var[int]
|
|
114
|
+
max_height: Var[int]
|
|
115
|
+
keep_aspect_ratio: Var[bool]
|
|
116
|
+
|
|
117
|
+
on_resize_start: rx.EventHandler[_resize_spec]
|
|
118
|
+
on_resize: rx.EventHandler[_resize_spec]
|
|
119
|
+
on_resize_end: rx.EventHandler[_resize_spec]
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class NodeToolbar(XYFlowBase):
|
|
123
|
+
"""Floating toolbar attached to a node (shown on selection by default)."""
|
|
124
|
+
|
|
125
|
+
tag = "NodeToolbar"
|
|
126
|
+
|
|
127
|
+
node_id: Var[str]
|
|
128
|
+
is_visible: Var[bool]
|
|
129
|
+
position: Var[str]
|
|
130
|
+
offset: Var[float]
|
|
131
|
+
align: Var[str] # "center" | "start" | "end"
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
# Convenience factory aliases -------------------------------------------------
|
|
135
|
+
background = Background.create
|
|
136
|
+
controls = Controls.create
|
|
137
|
+
mini_map = MiniMap.create
|
|
138
|
+
panel = Panel.create
|
|
139
|
+
handle = Handle.create
|
|
140
|
+
node_resizer = NodeResizer.create
|
|
141
|
+
node_toolbar = NodeToolbar.create
|
reflex_xyflow/custom.py
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""Custom node & edge type registration (Phase 3).
|
|
2
|
+
|
|
3
|
+
React Flow renders custom nodes/edges by mapping a *type* string to a React
|
|
4
|
+
component via the ``nodeTypes`` / ``edgeTypes`` props. Those values must be
|
|
5
|
+
component *functions*, not strings. Authoring full JSX renderers in Python is a
|
|
6
|
+
documented non-goal, so this module ships:
|
|
7
|
+
|
|
8
|
+
* :func:`js_component` — wrap a JS identifier as a raw Var so it compiles to a
|
|
9
|
+
bare reference (``BadgeNode``) instead of a string (``"BadgeNode"``);
|
|
10
|
+
* :func:`custom_types` — a headless component that injects two ready-made JS
|
|
11
|
+
templates whose content is driven by each element's Python ``data``:
|
|
12
|
+
|
|
13
|
+
- ``BadgeNode`` — a pill node with left/right :class:`Handle`s rendering
|
|
14
|
+
``data.label``;
|
|
15
|
+
- ``ButtonEdge`` — a custom edge using ``getBezierPath`` + ``BaseEdge`` with
|
|
16
|
+
an ``EdgeLabelRenderer`` label from ``data.label``.
|
|
17
|
+
|
|
18
|
+
Register them on the flow::
|
|
19
|
+
|
|
20
|
+
xyflow.react_flow(
|
|
21
|
+
xyflow.custom_types(),
|
|
22
|
+
node_types={"badge": xyflow.js_component("BadgeNode")},
|
|
23
|
+
edge_types={"button": xyflow.js_component("ButtonEdge")},
|
|
24
|
+
nodes=[{"id": "1", "type": "badge", "data": {"label": "Hi"}, ...}],
|
|
25
|
+
)
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from __future__ import annotations
|
|
29
|
+
|
|
30
|
+
from typing import Any
|
|
31
|
+
|
|
32
|
+
import reflex as rx
|
|
33
|
+
from reflex.vars import Var
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def js_component(name: str) -> Var:
|
|
37
|
+
"""Reference a JS component by name as a raw Var (unquoted identifier)."""
|
|
38
|
+
return Var(_js_expr=name, _var_type=Any)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# JSX templates injected into the page module. They are transformed by the
|
|
42
|
+
# frontend bundler (the page is a .jsx file). Content comes from each element's
|
|
43
|
+
# ``data`` so Python state drives what they show.
|
|
44
|
+
_CUSTOM_TYPES_CODE = """
|
|
45
|
+
function BadgeNode({ data, selected }) {
|
|
46
|
+
return (
|
|
47
|
+
<div
|
|
48
|
+
className="xyflow-badge-node"
|
|
49
|
+
style={{
|
|
50
|
+
padding: "10px 18px",
|
|
51
|
+
borderRadius: "9999px",
|
|
52
|
+
border: "2px solid " + (selected ? "#ec4899" : "#6366f1"),
|
|
53
|
+
background: "var(--xyflow-badge-bg, #ffffff)",
|
|
54
|
+
color: "var(--xyflow-badge-fg, #1f2937)",
|
|
55
|
+
fontSize: "12px",
|
|
56
|
+
fontWeight: 600,
|
|
57
|
+
boxShadow: "0 1px 3px rgba(0,0,0,0.12)",
|
|
58
|
+
}}
|
|
59
|
+
>
|
|
60
|
+
<Handle type="target" position={Position.Left} />
|
|
61
|
+
{data?.label ?? ""}
|
|
62
|
+
<Handle type="source" position={Position.Right} />
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function ButtonEdge({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, markerEnd, style, data }) {
|
|
68
|
+
const [edgePath, labelX, labelY] = getBezierPath({
|
|
69
|
+
sourceX, sourceY, sourcePosition, targetX, targetY, targetPosition,
|
|
70
|
+
});
|
|
71
|
+
return (
|
|
72
|
+
<>
|
|
73
|
+
<BaseEdge id={id} path={edgePath} markerEnd={markerEnd} style={style} />
|
|
74
|
+
<EdgeLabelRenderer>
|
|
75
|
+
<div
|
|
76
|
+
className="nodrag nopan"
|
|
77
|
+
style={{
|
|
78
|
+
position: "absolute",
|
|
79
|
+
transform: "translate(-50%, -50%) translate(" + labelX + "px," + labelY + "px)",
|
|
80
|
+
pointerEvents: "all",
|
|
81
|
+
background: "#ffffff",
|
|
82
|
+
border: "1px solid #6366f1",
|
|
83
|
+
borderRadius: "6px",
|
|
84
|
+
padding: "2px 6px",
|
|
85
|
+
fontSize: "11px",
|
|
86
|
+
fontWeight: 600,
|
|
87
|
+
}}
|
|
88
|
+
>
|
|
89
|
+
{data?.label ?? "edge"}
|
|
90
|
+
</div>
|
|
91
|
+
</EdgeLabelRenderer>
|
|
92
|
+
</>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
""".strip()
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class XYFlowCustomTypes(rx.Component):
|
|
99
|
+
"""Headless component that defines the bundled custom node/edge templates.
|
|
100
|
+
|
|
101
|
+
Place it once inside (or alongside) a flow; it renders nothing and only
|
|
102
|
+
injects the ``BadgeNode`` / ``ButtonEdge`` JS definitions and the React Flow
|
|
103
|
+
helpers they import.
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
tag = "XYFlowCustomTypes"
|
|
107
|
+
library = None # local component defined in custom code
|
|
108
|
+
|
|
109
|
+
def add_imports(self) -> dict[str, list[str]]:
|
|
110
|
+
return {
|
|
111
|
+
"@xyflow/react": [
|
|
112
|
+
"Handle",
|
|
113
|
+
"Position",
|
|
114
|
+
"BaseEdge",
|
|
115
|
+
"EdgeLabelRenderer",
|
|
116
|
+
"getBezierPath",
|
|
117
|
+
],
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
def add_custom_code(self) -> list[str]:
|
|
121
|
+
return [_CUSTOM_TYPES_CODE + "\n\nfunction XYFlowCustomTypes() { return null; }"]
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
custom_types = XYFlowCustomTypes.create
|
reflex_xyflow/enums.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""String enums mirroring the ``@xyflow/react`` literal-union props.
|
|
2
|
+
|
|
3
|
+
These are plain ``str`` enums so they serialize transparently to the JS values
|
|
4
|
+
React Flow expects (``"top"``, ``"dots"``, ``"smoothstep"`` ...).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from enum import Enum
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Position(str, Enum):
|
|
13
|
+
"""Handle / toolbar placement on a node."""
|
|
14
|
+
|
|
15
|
+
TOP = "top"
|
|
16
|
+
RIGHT = "right"
|
|
17
|
+
BOTTOM = "bottom"
|
|
18
|
+
LEFT = "left"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class HandleType(str, Enum):
|
|
22
|
+
"""Whether a handle starts (source) or receives (target) a connection."""
|
|
23
|
+
|
|
24
|
+
SOURCE = "source"
|
|
25
|
+
TARGET = "target"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class BackgroundVariant(str, Enum):
|
|
29
|
+
"""Pattern rendered by the :class:`Background` component."""
|
|
30
|
+
|
|
31
|
+
DOTS = "dots"
|
|
32
|
+
LINES = "lines"
|
|
33
|
+
CROSS = "cross"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ConnectionMode(str, Enum):
|
|
37
|
+
"""Strictness of which handles may be connected together."""
|
|
38
|
+
|
|
39
|
+
STRICT = "strict"
|
|
40
|
+
LOOSE = "loose"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ConnectionLineType(str, Enum):
|
|
44
|
+
"""Shape of the line drawn while creating a connection."""
|
|
45
|
+
|
|
46
|
+
BEZIER = "default"
|
|
47
|
+
STRAIGHT = "straight"
|
|
48
|
+
STEP = "step"
|
|
49
|
+
SMOOTHSTEP = "smoothstep"
|
|
50
|
+
SIMPLEBEZIER = "simplebezier"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class MarkerType(str, Enum):
|
|
54
|
+
"""Arrow head style for edge markers."""
|
|
55
|
+
|
|
56
|
+
ARROW = "arrow"
|
|
57
|
+
ARROWCLOSED = "arrowclosed"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class PanOnScrollMode(str, Enum):
|
|
61
|
+
FREE = "free"
|
|
62
|
+
VERTICAL = "vertical"
|
|
63
|
+
HORIZONTAL = "horizontal"
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class SelectionMode(str, Enum):
|
|
67
|
+
PARTIAL = "partial"
|
|
68
|
+
FULL = "full"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class ColorMode(str, Enum):
|
|
72
|
+
"""Built-in theming mode for React Flow 12."""
|
|
73
|
+
|
|
74
|
+
LIGHT = "light"
|
|
75
|
+
DARK = "dark"
|
|
76
|
+
SYSTEM = "system"
|