@particle-academy/fancy-flow 0.15.1 → 0.17.0

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.
package/dist/index.d.cts CHANGED
@@ -12,7 +12,7 @@ export { UseFlowRunOptions, UseFlowRunReturn, UseFlowStateReturn, applyStatusesT
12
12
  export { BUILTIN_KINDS, RegistryNode, RichInputAdapter, RichInputPreview, buildNodeTypes, categoryAccent, defaultConfigFor, getNodeKind, getRichInputAdapter, isRichInputEnabled, listNodeKinds, onNodeKindsChanged, onRichInputAdapterChanged, registerBuiltinKinds, registerNodeKind, registerRichInputAdapter, resolveNodePorts, resolvePortSpec, validateConfig } from './registry/index.cjs';
13
13
  export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-VKm57Hcj.cjs';
14
14
  export { L as LEGACY_PAUSE_PREFIXES, a as PAUSE_PREFIX, P as PauseAwaiting, b as PauseSignal, d as decodePause, e as encodePause, i as isPause, p as pauseForHuman } from './pause-9iT4tCEV.cjs';
15
- import './capabilities-BEbLqnJU.cjs';
15
+ import './capabilities-ChE3Xi8R.cjs';
16
16
 
17
17
  type FlowCanvasProps = Omit<ReactFlowProps<FlowNode, Edge>, "nodes" | "edges" | "height"> & {
18
18
  nodes: FlowNode[];
@@ -243,6 +243,15 @@ type NodeConfigPanelProps = {
243
243
  node: FlowNode | null;
244
244
  /** Called when the user edits the node label, description, or config. */
245
245
  onChange: (next: FlowNode) => void;
246
+ /**
247
+ * Called when the user deletes the node from the panel. When provided, the
248
+ * panel renders a "Delete node" button while a node is selected — so the
249
+ * delete affordance lives WITH the panel (a dev composing their own editor
250
+ * gets it for free), rather than in a host toolbar it has to re-implement.
251
+ */
252
+ onDelete?: (node: FlowNode) => void;
253
+ /** Label for the delete button. Default "Delete node". */
254
+ deleteLabel?: string;
246
255
  /** Optional header content (e.g. close button). */
247
256
  header?: ReactNode;
248
257
  /** Optional credential picker hook — host renders the picker. */
@@ -268,7 +277,7 @@ type NodeConfigPanelProps = {
268
277
  * NodeConfigPanel — schema-driven form for the selected node. Defers to
269
278
  * `kind.renderPanel` if the kind opts out of the auto-form.
270
279
  */
271
- declare function NodeConfigPanel({ node, onChange, header, renderCredentialField, renderDocumentField, className, style, }: NodeConfigPanelProps): react.JSX.Element;
280
+ declare function NodeConfigPanel({ node, onChange, onDelete, deleteLabel, header, renderCredentialField, renderDocumentField, className, style, }: NodeConfigPanelProps): react.JSX.Element;
272
281
 
273
282
  type ConfigFieldRendererProps = {
274
283
  field: ConfigField;
package/dist/index.d.ts CHANGED
@@ -12,7 +12,7 @@ export { UseFlowRunOptions, UseFlowRunReturn, UseFlowStateReturn, applyStatusesT
12
12
  export { BUILTIN_KINDS, RegistryNode, RichInputAdapter, RichInputPreview, buildNodeTypes, categoryAccent, defaultConfigFor, getNodeKind, getRichInputAdapter, isRichInputEnabled, listNodeKinds, onNodeKindsChanged, onRichInputAdapterChanged, registerBuiltinKinds, registerNodeKind, registerRichInputAdapter, resolveNodePorts, resolvePortSpec, validateConfig } from './registry/index.js';
13
13
  export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-ChBi6q-W.js';
14
14
  export { L as LEGACY_PAUSE_PREFIXES, a as PAUSE_PREFIX, P as PauseAwaiting, b as PauseSignal, d as decodePause, e as encodePause, i as isPause, p as pauseForHuman } from './pause-9iT4tCEV.js';
15
- import './capabilities-CI3gw0C7.js';
15
+ import './capabilities-DUhAc-EJ.js';
16
16
 
17
17
  type FlowCanvasProps = Omit<ReactFlowProps<FlowNode, Edge>, "nodes" | "edges" | "height"> & {
18
18
  nodes: FlowNode[];
@@ -243,6 +243,15 @@ type NodeConfigPanelProps = {
243
243
  node: FlowNode | null;
244
244
  /** Called when the user edits the node label, description, or config. */
245
245
  onChange: (next: FlowNode) => void;
246
+ /**
247
+ * Called when the user deletes the node from the panel. When provided, the
248
+ * panel renders a "Delete node" button while a node is selected — so the
249
+ * delete affordance lives WITH the panel (a dev composing their own editor
250
+ * gets it for free), rather than in a host toolbar it has to re-implement.
251
+ */
252
+ onDelete?: (node: FlowNode) => void;
253
+ /** Label for the delete button. Default "Delete node". */
254
+ deleteLabel?: string;
246
255
  /** Optional header content (e.g. close button). */
247
256
  header?: ReactNode;
248
257
  /** Optional credential picker hook — host renders the picker. */
@@ -268,7 +277,7 @@ type NodeConfigPanelProps = {
268
277
  * NodeConfigPanel — schema-driven form for the selected node. Defers to
269
278
  * `kind.renderPanel` if the kind opts out of the auto-form.
270
279
  */
271
- declare function NodeConfigPanel({ node, onChange, header, renderCredentialField, renderDocumentField, className, style, }: NodeConfigPanelProps): react.JSX.Element;
280
+ declare function NodeConfigPanel({ node, onChange, onDelete, deleteLabel, header, renderCredentialField, renderDocumentField, className, style, }: NodeConfigPanelProps): react.JSX.Element;
272
281
 
273
282
  type ConfigFieldRendererProps = {
274
283
  field: ConfigField;
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { useFlowState, useFlowRun, applyStatusesToNodes } from './chunk-MFMRTRPO.js';
2
2
  export { applyStatusesToNodes, useFlowRun, useFlowState } from './chunk-MFMRTRPO.js';
3
- import { buildNodeTypes, registerBuiltinKinds } from './chunk-ZQBWPYTI.js';
4
- export { BUILTIN_KINDS, RegistryNode, buildNodeTypes, registerBuiltinKinds } from './chunk-ZQBWPYTI.js';
3
+ import { buildNodeTypes, registerBuiltinKinds } from './chunk-532A5QA3.js';
4
+ export { BUILTIN_KINDS, RegistryNode, buildNodeTypes, registerBuiltinKinds } from './chunk-532A5QA3.js';
5
5
  import { ReactFlowProvider, useReactFlow, addEdge, applyEdgeChanges, applyNodeChanges, Position, Handle, index, BackgroundVariant, Background, Controls, MiniMap } from './chunk-NF6NPY5N.js';
6
6
  export { LEGACY_PAUSE_PREFIXES, PAUSE_PREFIX, decodePause, encodePause, isPause, pauseForHuman } from './chunk-UEOE6B52.js';
7
7
  export { runFlow } from './chunk-L4AX73Q6.js';
@@ -12,7 +12,7 @@ import { onNodeKindsChanged, listNodeKinds, getNodeKind, defaultConfigFor, valid
12
12
  export { categoryAccent, defaultConfigFor, getNodeKind, listNodeKinds, onNodeKindsChanged, registerNodeKind, validateConfig } from './chunk-U5F22BHV.js';
13
13
  import { getRichInputAdapter } from './chunk-F5RPRB7A.js';
14
14
  export { RichInputPreview, getRichInputAdapter, isRichInputEnabled, onRichInputAdapterChanged, registerRichInputAdapter } from './chunk-F5RPRB7A.js';
15
- import './chunk-BB45F6S3.js';
15
+ import './chunk-USL4FMFU.js';
16
16
  import { memo, createContext, forwardRef, useState, useEffect, useMemo, useCallback, useImperativeHandle, useRef, useContext } from 'react';
17
17
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
18
18
 
@@ -649,6 +649,8 @@ function JsonField({ value, onChange, rows }) {
649
649
  function NodeConfigPanel({
650
650
  node,
651
651
  onChange,
652
+ onDelete,
653
+ deleteLabel = "Delete node",
652
654
  header,
653
655
  renderCredentialField,
654
656
  renderDocumentField,
@@ -670,7 +672,21 @@ function NodeConfigPanel({
670
672
  /* @__PURE__ */ jsxs("p", { className: "ff-panel__empty", children: [
671
673
  "Unknown kind: ",
672
674
  kindName
673
- ] })
675
+ ] }),
676
+ onDelete && /* @__PURE__ */ jsx("div", { className: "ff-panel__actions", children: /* @__PURE__ */ jsxs(
677
+ "button",
678
+ {
679
+ type: "button",
680
+ className: "ff-panel__delete",
681
+ "data-action": "delete-node",
682
+ onClick: () => onDelete(node),
683
+ title: "Delete this node (Del / Backspace)",
684
+ children: [
685
+ "\u2715 ",
686
+ deleteLabel
687
+ ]
688
+ }
689
+ ) })
674
690
  ] });
675
691
  }
676
692
  const setLabel = (label) => onChange({ ...node, data: { ...node.data, label } });
@@ -736,7 +752,21 @@ function NodeConfigPanel({
736
752
  issues.length > 0 && /* @__PURE__ */ jsx("div", { className: "ff-panel__issues", children: issues.map((iss) => /* @__PURE__ */ jsxs("p", { className: "ff-panel__issue", children: [
737
753
  "\u26A0 ",
738
754
  iss.message
739
- ] }, iss.key)) })
755
+ ] }, iss.key)) }),
756
+ onDelete && /* @__PURE__ */ jsx("div", { className: "ff-panel__actions", children: /* @__PURE__ */ jsxs(
757
+ "button",
758
+ {
759
+ type: "button",
760
+ className: "ff-panel__delete",
761
+ "data-action": "delete-node",
762
+ onClick: () => onDelete(node),
763
+ title: "Delete this node (Del / Backspace)",
764
+ children: [
765
+ "\u2715 ",
766
+ deleteLabel
767
+ ]
768
+ }
769
+ ) })
740
770
  ] });
741
771
  }
742
772
  function FlowRunControls({ running, onRun, onCancel, onReset, className, style }) {
@@ -993,18 +1023,7 @@ function FlowEditorInner({
993
1023
  const toolbar = slots.toolbar ? slots.toolbar(api) : /* @__PURE__ */ jsxs(Fragment, { children: [
994
1024
  startActions.map((a) => renderAction(a, api)),
995
1025
  builtins.run !== false && /* @__PURE__ */ jsx(FlowRunControls, { running: api.running, onRun: api.run, onCancel: api.cancel, onReset: api.reset }),
996
- (builtins.delete !== false || builtins.export !== false || builtins.import !== false) && /* @__PURE__ */ jsx("span", { className: "ff-editor__sep" }),
997
- builtins.delete !== false && /* @__PURE__ */ jsx(
998
- "button",
999
- {
1000
- className: "ff-editor__btn",
1001
- "data-action": "delete",
1002
- onClick: api.deleteSelected,
1003
- disabled: api.selected === null,
1004
- title: "Delete the selected node (Del / Backspace)",
1005
- children: "\u2715 Delete"
1006
- }
1007
- ),
1026
+ (builtins.export !== false || builtins.import !== false) && /* @__PURE__ */ jsx("span", { className: "ff-editor__sep" }),
1008
1027
  builtins.export !== false && /* @__PURE__ */ jsx("button", { className: "ff-editor__btn", "data-action": "export", onClick: api.exportWorkflow, children: "\u2193 Export" }),
1009
1028
  builtins.import !== false && /* @__PURE__ */ jsx("button", { className: "ff-editor__btn", "data-action": "import", onClick: api.importWorkflow, children: "\u2191 Import" }),
1010
1029
  endActions.map((a) => renderAction(a, api)),
@@ -1135,7 +1154,15 @@ function FlowEditorInner({
1135
1154
  showFeed && (slots.feed ? slots.feed(api) : /* @__PURE__ */ jsx(FlowRunFeed, { entries: runner.feed, className: "ff-editor__feed" }))
1136
1155
  ] }),
1137
1156
  showPanel && (slots.panel ? slots.panel(api) : /* @__PURE__ */ jsxs("div", { className: "ff-editor__panel-wrap", children: [
1138
- /* @__PURE__ */ jsx(NodeConfigPanel, { className: "ff-editor__panel", node: api.selected, onChange: api.updateNode }),
1157
+ /* @__PURE__ */ jsx(
1158
+ NodeConfigPanel,
1159
+ {
1160
+ className: "ff-editor__panel",
1161
+ node: api.selected,
1162
+ onChange: api.updateNode,
1163
+ onDelete: builtins.delete === false ? void 0 : (n) => api.deleteNodes([n.id])
1164
+ }
1165
+ ),
1139
1166
  slots.panelFooter && /* @__PURE__ */ jsx("div", { className: "ff-editor__panel-footer", children: slots.panelFooter(api) })
1140
1167
  ] }))
1141
1168
  ] });