@01.software/sdk 0.4.1 → 0.4.3-dev.260324.6dc30aa

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/ui/flow.js CHANGED
@@ -40,7 +40,7 @@ var __async = (__this, __arguments, generator) => {
40
40
  };
41
41
 
42
42
  // src/ui/Flow/index.tsx
43
- import React from "react";
43
+ import React2 from "react";
44
44
  import {
45
45
  ReactFlow,
46
46
  ReactFlowProvider,
@@ -116,7 +116,7 @@ function collectionKeys(collection) {
116
116
 
117
117
  // src/ui/Flow/useFlow.ts
118
118
  function toNodeTypeDef(doc) {
119
- var _a, _b, _c, _d;
119
+ var _a, _b, _c, _d, _e, _f;
120
120
  return {
121
121
  slug: String((_a = doc.slug) != null ? _a : ""),
122
122
  name: String((_b = doc.title) != null ? _b : ""),
@@ -126,7 +126,9 @@ function toNodeTypeDef(doc) {
126
126
  height: 200
127
127
  },
128
128
  fields: Array.isArray(doc.fields) ? doc.fields : [],
129
- transparentBackground: Boolean(doc.transparentBackground)
129
+ transparentBackground: Boolean(doc.transparentBackground),
130
+ template: (_e = doc.template) != null ? _e : null,
131
+ customCSS: (_f = doc.customCSS) != null ? _f : null
130
132
  };
131
133
  }
132
134
  function toEdgeTypeDef(doc) {
@@ -244,37 +246,57 @@ function useFlowData(options) {
244
246
  }
245
247
 
246
248
  // src/ui/Flow/utils.ts
247
- function getNodeBounds(nodes, nodeIds) {
249
+ function getNodeSize(node) {
248
250
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
251
+ return {
252
+ width: (_e = (_d = (_c = (_a = node.style) == null ? void 0 : _a.width) != null ? _c : (_b = node.measured) == null ? void 0 : _b.width) != null ? _d : node.width) != null ? _e : 200,
253
+ height: (_j = (_i = (_h = (_f = node.style) == null ? void 0 : _f.height) != null ? _h : (_g = node.measured) == null ? void 0 : _g.height) != null ? _i : node.height) != null ? _j : 200
254
+ };
255
+ }
256
+ function getAbsolutePosition(node, nodeMap) {
257
+ let x = node.position.x;
258
+ let y = node.position.y;
259
+ let current = node;
260
+ const visited = /* @__PURE__ */ new Set([node.id]);
261
+ while (current.parentId) {
262
+ const parentId = current.parentId;
263
+ if (visited.has(parentId)) break;
264
+ const parent = nodeMap.get(parentId);
265
+ if (!parent) break;
266
+ visited.add(parent.id);
267
+ x += parent.position.x;
268
+ y += parent.position.y;
269
+ current = parent;
270
+ }
271
+ return { x, y };
272
+ }
273
+ function collectDescendants(nodes, rootId) {
274
+ const result = /* @__PURE__ */ new Set([rootId]);
275
+ const queue = [rootId];
276
+ let i = 0;
277
+ while (i < queue.length) {
278
+ const current = queue[i++];
279
+ for (const n of nodes) {
280
+ if (n.parentId === current && !result.has(n.id)) {
281
+ result.add(n.id);
282
+ queue.push(n.id);
283
+ }
284
+ }
285
+ }
286
+ return result;
287
+ }
288
+ function getNodeBounds(nodes, nodeIds) {
249
289
  const idSet = new Set(nodeIds);
250
290
  const targetNodes = nodes.filter((n) => idSet.has(n.id));
251
291
  if (targetNodes.length === 0) return void 0;
252
292
  const nodeMap = new Map(nodes.map((n) => [n.id, n]));
253
- function getAbsolutePosition(node) {
254
- let x = node.position.x;
255
- let y = node.position.y;
256
- let current = node;
257
- const visited = /* @__PURE__ */ new Set([node.id]);
258
- while (current.parentId) {
259
- const parentId = current.parentId;
260
- if (visited.has(parentId)) break;
261
- const parent = nodeMap.get(parentId);
262
- if (!parent) break;
263
- visited.add(parent.id);
264
- x += parent.position.x;
265
- y += parent.position.y;
266
- current = parent;
267
- }
268
- return { x, y };
269
- }
270
293
  let minX = Infinity;
271
294
  let minY = Infinity;
272
295
  let maxX = -Infinity;
273
296
  let maxY = -Infinity;
274
297
  for (const node of targetNodes) {
275
- const abs = getAbsolutePosition(node);
276
- const w = (_e = (_d = (_c = (_a = node.style) == null ? void 0 : _a.width) != null ? _c : (_b = node.measured) == null ? void 0 : _b.width) != null ? _d : node.width) != null ? _e : 200;
277
- const h = (_j = (_i = (_h = (_f = node.style) == null ? void 0 : _f.height) != null ? _h : (_g = node.measured) == null ? void 0 : _g.height) != null ? _i : node.height) != null ? _j : 200;
298
+ const abs = getAbsolutePosition(node, nodeMap);
299
+ const { width: w, height: h } = getNodeSize(node);
278
300
  minX = Math.min(minX, abs.x);
279
301
  minY = Math.min(minY, abs.y);
280
302
  maxX = Math.max(maxX, abs.x + w);
@@ -286,32 +308,140 @@ function getFrames(nodes) {
286
308
  const frames = nodes.filter((n) => n.type === "frame");
287
309
  if (frames.length === 0) return [];
288
310
  const nodeMap = new Map(nodes.map((n) => [n.id, n]));
289
- function getAbsolutePosition(node) {
290
- let x = node.position.x;
291
- let y = node.position.y;
292
- let current = node;
293
- const visited = /* @__PURE__ */ new Set([node.id]);
294
- while (current.parentId) {
295
- const parentId = current.parentId;
296
- if (visited.has(parentId)) break;
297
- const parent = nodeMap.get(parentId);
298
- if (!parent) break;
299
- visited.add(parent.id);
300
- x += parent.position.x;
301
- y += parent.position.y;
302
- current = parent;
303
- }
304
- return { x, y };
305
- }
306
311
  return frames.map((f) => {
307
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
312
+ var _a;
308
313
  const data = f.data;
309
- const abs = getAbsolutePosition(f);
310
- const w = (_e = (_d = (_c = (_a = f.style) == null ? void 0 : _a.width) != null ? _c : (_b = f.measured) == null ? void 0 : _b.width) != null ? _d : f.width) != null ? _e : 200;
311
- const h = (_j = (_i = (_h = (_f = f.style) == null ? void 0 : _f.height) != null ? _h : (_g = f.measured) == null ? void 0 : _g.height) != null ? _i : f.height) != null ? _j : 200;
312
- return { id: f.id, label: (_k = data.label) != null ? _k : "", bounds: { x: abs.x, y: abs.y, width: w, height: h } };
314
+ const abs = getAbsolutePosition(f, nodeMap);
315
+ const { width: w, height: h } = getNodeSize(f);
316
+ return {
317
+ id: f.id,
318
+ label: (_a = data.label) != null ? _a : "",
319
+ bounds: { x: abs.x, y: abs.y, width: w, height: h }
320
+ };
313
321
  }).sort((a, b) => a.bounds.y - b.bounds.y || a.bounds.x - b.bounds.x);
314
322
  }
323
+ function getFrameData(data, frameId) {
324
+ const frame = data.nodes.find((n) => n.id === frameId);
325
+ if (!frame || frame.type !== "frame") return void 0;
326
+ const descendantIds = collectDescendants(data.nodes, frameId);
327
+ const childNodes = data.nodes.filter((n) => descendantIds.has(n.id)).map((n) => __spreadProps(__spreadValues({}, n), { draggable: false }));
328
+ const childEdges = data.edges.filter(
329
+ (e) => descendantIds.has(e.source) && descendantIds.has(e.target)
330
+ );
331
+ const frameBounds = getNodeBounds(data.nodes, [frameId]);
332
+ const { width: w, height: h } = getNodeSize(frame);
333
+ const clampBounds = frameBounds != null ? frameBounds : {
334
+ x: frame.position.x,
335
+ y: frame.position.y,
336
+ width: w,
337
+ height: h
338
+ };
339
+ const contentNodeIds = childNodes.filter((n) => n.id !== frameId).map((n) => n.id);
340
+ const contentBounds = contentNodeIds.length > 0 ? getNodeBounds(data.nodes, contentNodeIds) : void 0;
341
+ const fitBounds = contentBounds != null ? contentBounds : clampBounds;
342
+ return {
343
+ data: {
344
+ nodes: childNodes,
345
+ edges: childEdges,
346
+ viewport: data.viewport
347
+ },
348
+ fitBounds,
349
+ clampBounds,
350
+ bounds: clampBounds
351
+ };
352
+ }
353
+
354
+ // src/ui/Flow/template-compiler.ts
355
+ import React from "react";
356
+ import { transform } from "sucrase";
357
+ var MAX_CACHE_SIZE = 100;
358
+ var componentCache = /* @__PURE__ */ new Map();
359
+ function hashCode(str) {
360
+ let hash = 0;
361
+ for (let i = 0; i < str.length; i++) {
362
+ const char = str.charCodeAt(i);
363
+ hash = (hash << 5) - hash + char | 0;
364
+ }
365
+ return hash.toString(36);
366
+ }
367
+ var BLOCKED_PATTERNS = [
368
+ /\bdocument\s*\./,
369
+ /\bwindow\s*\./,
370
+ /\bwindow\s*\[/,
371
+ /\bglobalThis\s*\./,
372
+ /\bfetch\s*\(/,
373
+ /\bXMLHttpRequest/,
374
+ /\beval\s*\(/,
375
+ /\bFunction\s*\(/,
376
+ /\bimport\s*\(/,
377
+ /\blocalStorage/,
378
+ /\bsessionStorage/,
379
+ /\bcookie/,
380
+ /\bpostMessage\s*\(/,
381
+ /\blocation\s*[.=]/,
382
+ /\bnavigator\s*\./,
383
+ /\bsetTimeout\s*\(/,
384
+ /\bsetInterval\s*\(/,
385
+ /\bsetImmediate\s*\(/,
386
+ /\brequire\s*\(/
387
+ ];
388
+ function validateTemplateCode(code) {
389
+ return !BLOCKED_PATTERNS.some((pattern) => pattern.test(code));
390
+ }
391
+ function compileTemplate(code, slug) {
392
+ const cacheKey = `${slug}:${code.length}:${hashCode(code)}:${code.slice(0, 64)}`;
393
+ if (componentCache.has(cacheKey)) {
394
+ const cached = componentCache.get(cacheKey);
395
+ componentCache.delete(cacheKey);
396
+ componentCache.set(cacheKey, cached);
397
+ return cached;
398
+ }
399
+ if (!validateTemplateCode(code)) {
400
+ console.warn(`[flow] Template "${slug}" contains blocked patterns`);
401
+ return null;
402
+ }
403
+ try {
404
+ const { code: jsCode } = transform(code, {
405
+ transforms: ["typescript", "jsx", "imports"],
406
+ jsxRuntime: "classic",
407
+ jsxPragma: "React.createElement",
408
+ jsxFragmentPragma: "React.Fragment"
409
+ });
410
+ const factory = new Function(
411
+ "React",
412
+ `
413
+ var window = undefined;
414
+ var document = undefined;
415
+ var globalThis = undefined;
416
+ var setTimeout = undefined;
417
+ var setInterval = undefined;
418
+ var setImmediate = undefined;
419
+ var fetch = undefined;
420
+ var XMLHttpRequest = undefined;
421
+ var navigator = undefined;
422
+ var location = undefined;
423
+ var exports = {};
424
+ var module = { exports: exports };
425
+ ${jsCode}
426
+ return module.exports.default || module.exports;
427
+ `
428
+ );
429
+ const Component = factory(React);
430
+ if (typeof Component !== "function") return null;
431
+ if (componentCache.size >= MAX_CACHE_SIZE) {
432
+ const oldestKey = componentCache.keys().next().value;
433
+ if (oldestKey) componentCache.delete(oldestKey);
434
+ }
435
+ componentCache.set(cacheKey, Component);
436
+ return Component;
437
+ } catch (e) {
438
+ console.warn(`[flow] Failed to compile template for "${slug}":`, e);
439
+ return null;
440
+ }
441
+ }
442
+ function clearTemplateCache() {
443
+ componentCache.clear();
444
+ }
315
445
 
316
446
  // src/ui/Flow/index.tsx
317
447
  function sanitizeUrl(url) {
@@ -336,7 +466,7 @@ function renderFieldValue(key, val, fieldDef) {
336
466
  const imgUrl = typeof val === "string" ? val : val == null ? void 0 : val.url;
337
467
  const safeUrl = sanitizeUrl(imgUrl);
338
468
  if (!safeUrl) return null;
339
- return /* @__PURE__ */ React.createElement(
469
+ return /* @__PURE__ */ React2.createElement(
340
470
  "img",
341
471
  {
342
472
  key,
@@ -347,7 +477,7 @@ function renderFieldValue(key, val, fieldDef) {
347
477
  }
348
478
  );
349
479
  }
350
- return /* @__PURE__ */ React.createElement(
480
+ return /* @__PURE__ */ React2.createElement(
351
481
  "div",
352
482
  {
353
483
  key,
@@ -364,7 +494,7 @@ function renderFieldValue(key, val, fieldDef) {
364
494
  }
365
495
  function DefaultDynamicNode({ data }) {
366
496
  const d = data;
367
- return /* @__PURE__ */ React.createElement(
497
+ return /* @__PURE__ */ React2.createElement(
368
498
  "div",
369
499
  {
370
500
  style: {
@@ -377,11 +507,59 @@ function DefaultDynamicNode({ data }) {
377
507
  d.fields && Object.entries(d.fields).filter(([, v]) => v != null && v !== "").map(([key, val]) => renderFieldValue(key, val))
378
508
  );
379
509
  }
510
+ var TemplateErrorBoundary = class extends React2.Component {
511
+ constructor() {
512
+ super(...arguments);
513
+ this.state = { error: null };
514
+ }
515
+ static getDerivedStateFromError(error) {
516
+ return { error };
517
+ }
518
+ componentDidUpdate(prevProps) {
519
+ if (prevProps.resetKey !== this.props.resetKey && this.state.error) {
520
+ this.setState({ error: null });
521
+ }
522
+ }
523
+ render() {
524
+ if (this.state.error) {
525
+ return /* @__PURE__ */ React2.createElement("div", { style: { padding: 8, fontSize: 11, color: "#ef4444" } }, /* @__PURE__ */ React2.createElement("strong", null, "Render error"), /* @__PURE__ */ React2.createElement("pre", { style: { fontSize: 10, whiteSpace: "pre-wrap" } }, this.state.error.message));
526
+ }
527
+ return this.props.children;
528
+ }
529
+ };
380
530
  function EnhancedDynamicNode({
381
531
  data,
382
- typeDef
532
+ typeDef,
533
+ width,
534
+ height
383
535
  }) {
384
- return /* @__PURE__ */ React.createElement(
536
+ if (typeDef.template) {
537
+ const Component = compileTemplate(typeDef.template, typeDef.slug);
538
+ if (Component) {
539
+ return /* @__PURE__ */ React2.createElement(
540
+ "div",
541
+ {
542
+ className: `flow-node flow-node--${typeDef.slug}${typeDef.transparentBackground ? " flow-node--transparent-bg" : ""}`,
543
+ style: {
544
+ width: "100%",
545
+ height: "100%"
546
+ }
547
+ },
548
+ /* @__PURE__ */ React2.createElement(TemplateErrorBoundary, { resetKey: typeDef.template }, /* @__PURE__ */ React2.createElement(
549
+ Component,
550
+ {
551
+ fields: data.fields,
552
+ label: data.label,
553
+ color: typeDef.color,
554
+ nodeTypeSlug: typeDef.slug,
555
+ width: width != null ? width : typeDef.defaultSize.width,
556
+ height: height != null ? height : typeDef.defaultSize.height
557
+ }
558
+ ))
559
+ );
560
+ }
561
+ }
562
+ return /* @__PURE__ */ React2.createElement(
385
563
  "div",
386
564
  {
387
565
  style: {
@@ -410,7 +588,7 @@ function DefaultFrameNode({ data }) {
410
588
  if (m) return `rgba(${m[1]},${m[2]},${m[3]},${opacity})`;
411
589
  return baseColor;
412
590
  })();
413
- return /* @__PURE__ */ React.createElement(
591
+ return /* @__PURE__ */ React2.createElement(
414
592
  "div",
415
593
  {
416
594
  style: {
@@ -421,7 +599,7 @@ function DefaultFrameNode({ data }) {
421
599
  border: borderStyle === "none" ? "none" : `2px ${borderStyle} rgba(128,128,128,0.3)`
422
600
  }
423
601
  },
424
- /* @__PURE__ */ React.createElement(
602
+ /* @__PURE__ */ React2.createElement(
425
603
  "div",
426
604
  {
427
605
  style: {
@@ -443,7 +621,7 @@ function createNodeTypes(nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrap
443
621
  const CustomRenderer = nodeRenderers == null ? void 0 : nodeRenderers[d.nodeTypeSlug];
444
622
  let content;
445
623
  if (CustomRenderer) {
446
- content = /* @__PURE__ */ React.createElement(
624
+ content = /* @__PURE__ */ React2.createElement(
447
625
  CustomRenderer,
448
626
  {
449
627
  id: props.id,
@@ -454,9 +632,9 @@ function createNodeTypes(nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrap
454
632
  }
455
633
  );
456
634
  } else if (typeDef) {
457
- content = /* @__PURE__ */ React.createElement(EnhancedDynamicNode, { data: d, typeDef });
635
+ content = /* @__PURE__ */ React2.createElement(EnhancedDynamicNode, { data: d, typeDef, width: props.width, height: props.height });
458
636
  } else {
459
- content = /* @__PURE__ */ React.createElement(DefaultDynamicNode, __spreadValues({}, props));
637
+ content = /* @__PURE__ */ React2.createElement(DefaultDynamicNode, __spreadValues({}, props));
460
638
  }
461
639
  if (renderNode) {
462
640
  const slotProps = {
@@ -471,7 +649,7 @@ function createNodeTypes(nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrap
471
649
  }
472
650
  if (nodeWrapper) {
473
651
  const Wrapper = nodeWrapper;
474
- content = /* @__PURE__ */ React.createElement(
652
+ content = /* @__PURE__ */ React2.createElement(
475
653
  Wrapper,
476
654
  {
477
655
  id: props.id,
@@ -488,7 +666,7 @@ function createNodeTypes(nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrap
488
666
  types.frame = frameRenderer ? ((props) => {
489
667
  const d = props.data;
490
668
  const Renderer = frameRenderer;
491
- return /* @__PURE__ */ React.createElement(
669
+ return /* @__PURE__ */ React2.createElement(
492
670
  Renderer,
493
671
  {
494
672
  id: props.id,
@@ -509,7 +687,7 @@ function createEdgeTypes(edgeRenderers, edgeTypeDefsMap) {
509
687
  types[slug] = ((props) => {
510
688
  var _a;
511
689
  const def = edgeTypeDefsMap == null ? void 0 : edgeTypeDefsMap.get(slug);
512
- return /* @__PURE__ */ React.createElement(
690
+ return /* @__PURE__ */ React2.createElement(
513
691
  Renderer,
514
692
  {
515
693
  id: props.id,
@@ -529,17 +707,64 @@ function createEdgeTypes(edgeRenderers, edgeTypeDefsMap) {
529
707
  function FocusHandler({
530
708
  bounds,
531
709
  padding,
532
- animation
710
+ animation,
711
+ mode,
712
+ responsive
533
713
  }) {
534
- const { fitBounds } = useReactFlow();
714
+ const { fitBounds, setViewport } = useReactFlow();
715
+ const containerRef = React2.useRef(null);
535
716
  const boundsKey = `${bounds.x},${bounds.y},${bounds.width},${bounds.height}`;
536
- const boundsRef = React.useRef(bounds);
717
+ const boundsRef = React2.useRef(bounds);
537
718
  boundsRef.current = bounds;
538
- React.useEffect(() => {
539
- const duration = animation === true ? 300 : typeof animation === "number" ? animation : 0;
540
- fitBounds(boundsRef.current, { padding, duration });
541
- }, [boundsKey, padding, animation, fitBounds]);
542
- return null;
719
+ const [containerSize, setContainerSize] = React2.useState({ w: 0, h: 0 });
720
+ const prevBoundsKeyRef = React2.useRef(null);
721
+ const prevSizeRef = React2.useRef({ w: 0, h: 0 });
722
+ React2.useEffect(() => {
723
+ const el = containerRef.current;
724
+ if (!el) return;
725
+ const observer = new ResizeObserver((entries) => {
726
+ const entry = entries[0];
727
+ if (!entry) return;
728
+ const { width, height } = entry.contentRect;
729
+ setContainerSize({ w: width, h: height });
730
+ });
731
+ observer.observe(el);
732
+ return () => observer.disconnect();
733
+ }, []);
734
+ React2.useEffect(() => {
735
+ if (containerSize.w === 0 || containerSize.h === 0) return;
736
+ const prevKey = prevBoundsKeyRef.current;
737
+ const prevSize = prevSizeRef.current;
738
+ prevBoundsKeyRef.current = boundsKey;
739
+ prevSizeRef.current = { w: containerSize.w, h: containerSize.h };
740
+ const isBoundsChange = prevKey !== boundsKey;
741
+ const isResizeOnly = !isBoundsChange && (prevSize.w !== containerSize.w || prevSize.h !== containerSize.h);
742
+ const isInitial = prevKey === null;
743
+ if (isResizeOnly && !responsive) return;
744
+ const duration = isInitial || isBoundsChange ? animation === true ? 300 : typeof animation === "number" ? animation : 0 : 0;
745
+ const b = boundsRef.current;
746
+ const padX = padding * b.width;
747
+ const padY = padding * b.height;
748
+ const bw = b.width + padX * 2;
749
+ const bh = b.height + padY * 2;
750
+ if (mode === "cover") {
751
+ const zoom = Math.max(containerSize.w / bw, containerSize.h / bh);
752
+ const cx = b.x + b.width / 2;
753
+ const cy = b.y + b.height / 2;
754
+ const x = containerSize.w / 2 - cx * zoom;
755
+ const y = containerSize.h / 2 - cy * zoom;
756
+ setViewport({ x, y, zoom }, { duration });
757
+ } else {
758
+ fitBounds(boundsRef.current, { padding, duration });
759
+ }
760
+ }, [boundsKey, padding, animation, mode, responsive, containerSize.w, containerSize.h, fitBounds, setViewport]);
761
+ return /* @__PURE__ */ React2.createElement(
762
+ "div",
763
+ {
764
+ ref: containerRef,
765
+ style: { position: "absolute", inset: 0, pointerEvents: "none", visibility: "hidden" }
766
+ }
767
+ );
543
768
  }
544
769
  var EDGE_TYPE_MAP = {
545
770
  step: "step",
@@ -603,27 +828,35 @@ function FlowRenderer({
603
828
  onViewportChange,
604
829
  defaultViewport: defaultViewportProp,
605
830
  bounds,
831
+ clampBounds,
606
832
  focusPadding,
607
- focusAnimation
833
+ focusAnimation,
834
+ focusMode = "contain",
835
+ responsiveFit,
836
+ translateExtent: translateExtentProp
608
837
  }) {
609
838
  var _a;
610
- const nodeTypeDefsMap = React.useMemo(() => {
839
+ const nodeTypeDefsMap = React2.useMemo(() => {
611
840
  if (!(nodeTypeDefs == null ? void 0 : nodeTypeDefs.length)) return void 0;
612
841
  return new Map(nodeTypeDefs.map((d) => [d.slug, d]));
613
842
  }, [nodeTypeDefs]);
614
- const edgeTypeDefsMap = React.useMemo(() => {
843
+ const edgeTypeDefsMap = React2.useMemo(() => {
615
844
  if (!(edgeTypeDefs == null ? void 0 : edgeTypeDefs.length)) return void 0;
616
845
  return new Map(edgeTypeDefs.map((d) => [d.slug, d]));
617
846
  }, [edgeTypeDefs]);
618
- const nodeTypes = React.useMemo(
847
+ const nodeTypes = React2.useMemo(
619
848
  () => createNodeTypes(nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrapper, renderNode),
620
849
  [nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrapper, renderNode]
621
850
  );
622
- const customEdgeTypes = React.useMemo(
851
+ const customEdgeTypes = React2.useMemo(
623
852
  () => createEdgeTypes(edgeRenderers, edgeTypeDefsMap),
624
853
  [edgeRenderers, edgeTypeDefsMap]
625
854
  );
626
- const styledEdges = React.useMemo(() => {
855
+ const mergedCSS = React2.useMemo(() => {
856
+ if (!(nodeTypeDefs == null ? void 0 : nodeTypeDefs.length)) return "";
857
+ return nodeTypeDefs.filter((d) => d.customCSS).map((d) => d.customCSS).join("\n");
858
+ }, [nodeTypeDefs]);
859
+ const styledEdges = React2.useMemo(() => {
627
860
  var _a2;
628
861
  let edges = applyEdgeStyles((_a2 = data == null ? void 0 : data.edges) != null ? _a2 : [], edgeTypeDefsMap);
629
862
  if (edgeRenderers) {
@@ -639,13 +872,23 @@ function FlowRenderer({
639
872
  }, [data == null ? void 0 : data.edges, edgeTypeDefsMap, edgeRenderers]);
640
873
  if (!data) return null;
641
874
  const resolvedDefaultViewport = defaultViewportProp != null ? defaultViewportProp : !fitView && data.viewport ? data.viewport : void 0;
642
- return /* @__PURE__ */ React.createElement(ReactFlowProvider, null, /* @__PURE__ */ React.createElement(
875
+ const pad = focusPadding != null ? focusPadding : 0.1;
876
+ const extentSource = clampBounds != null ? clampBounds : bounds;
877
+ const extentPad = clampBounds ? 0 : pad;
878
+ const translateExtent = translateExtentProp != null ? translateExtentProp : extentSource ? [
879
+ [extentSource.x - extentPad * extentSource.width, extentSource.y - extentPad * extentSource.height],
880
+ [
881
+ extentSource.x + extentSource.width * (1 + extentPad),
882
+ extentSource.y + extentSource.height * (1 + extentPad)
883
+ ]
884
+ ] : void 0;
885
+ return /* @__PURE__ */ React2.createElement(ReactFlowProvider, null, /* @__PURE__ */ React2.createElement(
643
886
  "div",
644
887
  {
645
888
  className,
646
- style: __spreadValues({ width: "100%", height: "100%" }, style)
889
+ style: __spreadValues({ width: "100%", height: "100%", background: "transparent" }, style)
647
890
  },
648
- /* @__PURE__ */ React.createElement(
891
+ /* @__PURE__ */ React2.createElement(
649
892
  ReactFlow,
650
893
  {
651
894
  nodes: (_a = data.nodes) != null ? _a : [],
@@ -653,13 +896,14 @@ function FlowRenderer({
653
896
  nodeTypes,
654
897
  edgeTypes: customEdgeTypes,
655
898
  defaultViewport: resolvedDefaultViewport,
656
- fitView,
899
+ fitView: bounds ? false : fitView,
900
+ translateExtent,
657
901
  onNodeClick,
658
902
  onEdgeClick,
659
903
  onMoveEnd: onViewportChange ? ((_, vp) => {
660
904
  onViewportChange(vp);
661
905
  }) : void 0,
662
- nodesDraggable: interactive ? void 0 : false,
906
+ nodesDraggable: interactive,
663
907
  nodesConnectable: false,
664
908
  elementsSelectable: interactive || !!onNodeClick || !!onEdgeClick,
665
909
  panOnDrag: interactive,
@@ -667,20 +911,23 @@ function FlowRenderer({
667
911
  zoomOnPinch: interactive,
668
912
  zoomOnDoubleClick: false
669
913
  },
670
- background && /* @__PURE__ */ React.createElement(Background, null),
671
- controls && /* @__PURE__ */ React.createElement(Controls, null),
672
- minimap && /* @__PURE__ */ React.createElement(
914
+ mergedCSS && /* @__PURE__ */ React2.createElement("style", { dangerouslySetInnerHTML: { __html: mergedCSS } }),
915
+ background && /* @__PURE__ */ React2.createElement(Background, null),
916
+ controls && /* @__PURE__ */ React2.createElement(Controls, null),
917
+ minimap && /* @__PURE__ */ React2.createElement(
673
918
  MiniMap,
674
919
  {
675
920
  nodeColor: minimapNodeColor
676
921
  }
677
922
  ),
678
- bounds && /* @__PURE__ */ React.createElement(
923
+ bounds && /* @__PURE__ */ React2.createElement(
679
924
  FocusHandler,
680
925
  {
681
926
  bounds,
682
927
  padding: focusPadding != null ? focusPadding : 0.1,
683
- animation: focusAnimation != null ? focusAnimation : true
928
+ animation: focusAnimation != null ? focusAnimation : true,
929
+ mode: focusMode,
930
+ responsive: responsiveFit != null ? responsiveFit : true
684
931
  }
685
932
  ),
686
933
  children
@@ -691,6 +938,9 @@ export {
691
938
  BUILT_IN_EDGE_TYPES,
692
939
  BUILT_IN_NODE_TYPES,
693
940
  FlowRenderer,
941
+ clearTemplateCache,
942
+ compileTemplate,
943
+ getFrameData,
694
944
  getFrames,
695
945
  getNodeBounds,
696
946
  isDynamicNode,