@01.software/sdk 0.44.0 → 0.46.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/CHANGELOG.md +366 -2
- package/MIGRATION.md +108 -10
- package/README.md +486 -98
- package/dist/{server-nXOezi4b.d.cts → catalog-mappers-sIshKNb3.d.cts} +14 -3
- package/dist/{server-nXOezi4b.d.ts → catalog-mappers-sIshKNb3.d.ts} +14 -3
- package/dist/client.cjs +2693 -345
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +10 -7
- package/dist/client.d.ts +10 -7
- package/dist/client.js +2693 -345
- package/dist/client.js.map +1 -1
- package/dist/{collection-client-DWooaiTr.d.ts → collection-client-D6kKrYdq.d.ts} +8 -5
- package/dist/{collection-client-Dyl-CDcj.d.cts → collection-client-DolMjCoC.d.cts} +8 -5
- package/dist/{const-pGDnsy0o.d.ts → const-BAG0MH0u.d.cts} +13 -10
- package/dist/{const-1vleZ6ov.d.cts → const-CaPq2AE4.d.ts} +13 -10
- package/dist/errors.cjs +74 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +38 -1
- package/dist/errors.d.ts +38 -1
- package/dist/errors.js +74 -1
- package/dist/errors.js.map +1 -1
- package/dist/{index-DUNySyxV.d.ts → index-BNICJxBL.d.ts} +4 -4
- package/dist/{index-a6g7vqAD.d.cts → index-YGrZrxNn.d.cts} +4 -4
- package/dist/index.cjs +2754 -368
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -19
- package/dist/index.d.ts +18 -19
- package/dist/index.js +2754 -368
- package/dist/index.js.map +1 -1
- package/dist/{payload-types-CDsuOEfM.d.cts → payload-types-CJZuXcgF.d.cts} +6671 -4001
- package/dist/{payload-types-CDsuOEfM.d.ts → payload-types-CJZuXcgF.d.ts} +6671 -4001
- package/dist/query.cjs +558 -101
- package/dist/query.cjs.map +1 -1
- package/dist/query.d.cts +43 -45
- package/dist/query.d.ts +43 -45
- package/dist/query.js +558 -101
- package/dist/query.js.map +1 -1
- package/dist/realtime.cjs.map +1 -1
- package/dist/realtime.d.cts +2 -2
- package/dist/realtime.d.ts +2 -2
- package/dist/realtime.js.map +1 -1
- package/dist/server.cjs +2343 -437
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +11 -10
- package/dist/server.d.ts +11 -10
- package/dist/server.js +2343 -437
- package/dist/server.js.map +1 -1
- package/dist/storefront-cache.cjs +65 -1
- package/dist/storefront-cache.cjs.map +1 -1
- package/dist/storefront-cache.js +65 -1
- package/dist/storefront-cache.js.map +1 -1
- package/dist/types-BC6rVmJa.d.ts +47 -0
- package/dist/{types-CDND3hzq.d.cts → types-C60vHIkY.d.ts} +1134 -509
- package/dist/types-D5p7-m1l.d.cts +47 -0
- package/dist/{types-Dt9FJisi.d.ts → types-xlqBeW2N.d.cts} +1134 -509
- package/dist/ui/canvas/server.cjs +244 -2
- package/dist/ui/canvas/server.cjs.map +1 -1
- package/dist/ui/canvas/server.d.cts +27 -1
- package/dist/ui/canvas/server.d.ts +27 -1
- package/dist/ui/canvas/server.js +244 -2
- package/dist/ui/canvas/server.js.map +1 -1
- package/dist/ui/canvas.cjs +419 -103
- package/dist/ui/canvas.cjs.map +1 -1
- package/dist/ui/canvas.d.cts +19 -7
- package/dist/ui/canvas.d.ts +19 -7
- package/dist/ui/canvas.js +419 -103
- package/dist/ui/canvas.js.map +1 -1
- package/dist/ui/form.d.cts +1 -1
- package/dist/ui/form.d.ts +1 -1
- package/dist/ui/video.d.cts +1 -1
- package/dist/ui/video.d.ts +1 -1
- package/dist/webhook.cjs +2 -1
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.d.cts +4 -4
- package/dist/webhook.d.ts +4 -4
- package/dist/webhook.js +2 -1
- package/dist/webhook.js.map +1 -1
- package/package.json +10 -9
- package/dist/types-SoXsbKhj.d.cts +0 -33
- package/dist/types-oiae_LMm.d.ts +0 -33
package/dist/ui/canvas.js
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/ui/Canvas/types.ts
|
|
4
|
+
var CANVAS_SHAPE_TYPES = [
|
|
5
|
+
"terminator",
|
|
6
|
+
"process",
|
|
7
|
+
"decision",
|
|
8
|
+
"io",
|
|
9
|
+
"subprocess"
|
|
10
|
+
];
|
|
4
11
|
function isDynamicNode(node) {
|
|
5
12
|
return node.type === "dynamic";
|
|
6
13
|
}
|
|
7
14
|
function isFrameNode(node) {
|
|
8
15
|
return node.type === "frame";
|
|
9
16
|
}
|
|
17
|
+
function isShapeNode(node) {
|
|
18
|
+
return node.type === "shape";
|
|
19
|
+
}
|
|
10
20
|
|
|
11
21
|
// src/ui/Canvas/useCanvas.ts
|
|
12
22
|
import { useQuery } from "@tanstack/react-query";
|
|
@@ -30,10 +40,13 @@ function collectionKeys(collection) {
|
|
|
30
40
|
}
|
|
31
41
|
|
|
32
42
|
// src/ui/Canvas/query-options.ts
|
|
43
|
+
var CANVAS_STALE_TIME_MS = 6e4;
|
|
44
|
+
var CANVAS_CATALOG_STALE_TIME_MS = 5 * 6e4;
|
|
33
45
|
function canvasQueryOptions(client, slug, id) {
|
|
34
46
|
const identifier = id ?? slug ?? "";
|
|
35
47
|
return {
|
|
36
48
|
queryKey: collectionKeys("canvases").detail(identifier),
|
|
49
|
+
staleTime: CANVAS_STALE_TIME_MS,
|
|
37
50
|
queryFn: async () => {
|
|
38
51
|
if (id) return client.collections.from("canvases").findById(id);
|
|
39
52
|
const result = await client.collections.from("canvases").find({
|
|
@@ -49,8 +62,9 @@ function canvasQueryOptions(client, slug, id) {
|
|
|
49
62
|
function nodeTypesQueryOptions(client) {
|
|
50
63
|
return {
|
|
51
64
|
queryKey: collectionKeys("canvas-node-types").lists(),
|
|
65
|
+
staleTime: CANVAS_CATALOG_STALE_TIME_MS,
|
|
52
66
|
queryFn: async () => {
|
|
53
|
-
const result = await client.collections.from("canvas-node-types").find({ limit:
|
|
67
|
+
const result = await client.collections.from("canvas-node-types").find({ limit: 100 });
|
|
54
68
|
return result.docs;
|
|
55
69
|
}
|
|
56
70
|
};
|
|
@@ -58,8 +72,9 @@ function nodeTypesQueryOptions(client) {
|
|
|
58
72
|
function edgeTypesQueryOptions(client) {
|
|
59
73
|
return {
|
|
60
74
|
queryKey: collectionKeys("canvas-edge-types").lists(),
|
|
75
|
+
staleTime: CANVAS_CATALOG_STALE_TIME_MS,
|
|
61
76
|
queryFn: async () => {
|
|
62
|
-
const result = await client.collections.from("canvas-edge-types").find({ limit:
|
|
77
|
+
const result = await client.collections.from("canvas-edge-types").find({ limit: 100 });
|
|
63
78
|
return result.docs;
|
|
64
79
|
}
|
|
65
80
|
};
|
|
@@ -328,10 +343,9 @@ function getFrameData(data, frameId) {
|
|
|
328
343
|
// src/ui/Canvas/template-compiler.ts
|
|
329
344
|
import React from "react";
|
|
330
345
|
import { transform } from "sucrase";
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
var
|
|
334
|
-
var ALLOWED_ELEMENTS = /* @__PURE__ */ new Set([
|
|
346
|
+
|
|
347
|
+
// src/ui/Canvas/template-security.ts
|
|
348
|
+
var ALLOWED_TEMPLATE_ELEMENTS = [
|
|
335
349
|
"div",
|
|
336
350
|
"span",
|
|
337
351
|
"p",
|
|
@@ -365,33 +379,188 @@ var ALLOWED_ELEMENTS = /* @__PURE__ */ new Set([
|
|
|
365
379
|
"g",
|
|
366
380
|
"circle",
|
|
367
381
|
"rect"
|
|
368
|
-
]);
|
|
369
|
-
var BLOCKED_PATTERNS = [
|
|
370
|
-
/\bdocument\s*\./,
|
|
371
|
-
/\bwindow\s*\./,
|
|
372
|
-
/\bwindow\s*\[/,
|
|
373
|
-
/\bglobalThis\s*\./,
|
|
374
|
-
/\bfetch\s*\(/,
|
|
375
|
-
/\bXMLHttpRequest/,
|
|
376
|
-
/\beval\s*\(/,
|
|
377
|
-
/\bFunction\s*\(/,
|
|
378
|
-
/\bimport\s*\(/,
|
|
379
|
-
/\blocalStorage/,
|
|
380
|
-
/\bsessionStorage/,
|
|
381
|
-
/\bcookie/,
|
|
382
|
-
/\bpostMessage\s*\(/,
|
|
383
|
-
/\blocation\s*[.=]/,
|
|
384
|
-
/\bnavigator\s*\./,
|
|
385
|
-
/\bsetTimeout\s*\(/,
|
|
386
|
-
/\bsetInterval\s*\(/,
|
|
387
|
-
/\bsetImmediate\s*\(/,
|
|
388
|
-
/\brequire\s*\(/,
|
|
389
|
-
/\bself\b/,
|
|
390
|
-
/\bconstructor\s*\.\s*constructor/,
|
|
391
|
-
/\bReflect\b/,
|
|
392
|
-
/\bProxy\b/,
|
|
393
|
-
/\b__proto__\b/
|
|
394
382
|
];
|
|
383
|
+
var ALLOWED_TEMPLATE_ELEMENT_SET = new Set(ALLOWED_TEMPLATE_ELEMENTS);
|
|
384
|
+
function isAllowedTemplateElement(value) {
|
|
385
|
+
return ALLOWED_TEMPLATE_ELEMENT_SET.has(value.toLowerCase());
|
|
386
|
+
}
|
|
387
|
+
var TEMPLATE_BLOCKED_PATTERNS = [
|
|
388
|
+
{ pattern: /\bdocument\s*\./, hint: "document API" },
|
|
389
|
+
{ pattern: /\bwindow\s*\./, hint: "window API" },
|
|
390
|
+
{ pattern: /\bwindow\s*\[/, hint: "window indexer" },
|
|
391
|
+
{ pattern: /\bglobalThis\s*\./, hint: "globalThis" },
|
|
392
|
+
{ pattern: /\bfetch\s*\(/, hint: "fetch()" },
|
|
393
|
+
{ pattern: /\bXMLHttpRequest/, hint: "XMLHttpRequest" },
|
|
394
|
+
{ pattern: /\beval\s*\(/, hint: "eval()" },
|
|
395
|
+
{ pattern: /\bFunction\s*\(/, hint: "Function constructor" },
|
|
396
|
+
{ pattern: /\bimport\s*\(/, hint: "dynamic import()" },
|
|
397
|
+
{ pattern: /\blocalStorage/, hint: "localStorage" },
|
|
398
|
+
{ pattern: /\bsessionStorage/, hint: "sessionStorage" },
|
|
399
|
+
{ pattern: /\bcookie/, hint: "cookie access" },
|
|
400
|
+
{ pattern: /\bpostMessage\s*\(/, hint: "postMessage()" },
|
|
401
|
+
{ pattern: /\blocation\s*[.=]/, hint: "location API" },
|
|
402
|
+
{ pattern: /\bnavigator\s*\./, hint: "navigator API" },
|
|
403
|
+
{ pattern: /\bsetTimeout\s*\(/, hint: "setTimeout()" },
|
|
404
|
+
{ pattern: /\bsetInterval\s*\(/, hint: "setInterval()" },
|
|
405
|
+
{ pattern: /\bsetImmediate\s*\(/, hint: "setImmediate()" },
|
|
406
|
+
{ pattern: /\brequire\s*\(/, hint: "require()" },
|
|
407
|
+
{ pattern: /\bself\b/, hint: "self alias" },
|
|
408
|
+
{
|
|
409
|
+
pattern: /\bconstructor\s*\.\s*constructor/,
|
|
410
|
+
hint: "constructor.constructor escape"
|
|
411
|
+
},
|
|
412
|
+
{ pattern: /\bReflect\b/, hint: "Reflect" },
|
|
413
|
+
{ pattern: /\bProxy\b/, hint: "Proxy" },
|
|
414
|
+
{ pattern: /\b__proto__\b/, hint: "__proto__" }
|
|
415
|
+
];
|
|
416
|
+
function findBlockedTemplatePattern(code) {
|
|
417
|
+
for (const { pattern, hint } of TEMPLATE_BLOCKED_PATTERNS) {
|
|
418
|
+
if (pattern.test(code)) return { hint };
|
|
419
|
+
}
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
var SAFE_DATA_URI_PREFIXES = [
|
|
423
|
+
"data:image/png;",
|
|
424
|
+
"data:image/jpeg;",
|
|
425
|
+
"data:image/gif;",
|
|
426
|
+
"data:image/webp;",
|
|
427
|
+
"data:image/avif;"
|
|
428
|
+
];
|
|
429
|
+
function isSafeTemplateUrl(value) {
|
|
430
|
+
if (typeof value !== "string") return false;
|
|
431
|
+
if (value.startsWith("/") || value.startsWith("./") || value.startsWith("../") || value.startsWith("#")) {
|
|
432
|
+
return true;
|
|
433
|
+
}
|
|
434
|
+
if (SAFE_DATA_URI_PREFIXES.some((prefix) => value.startsWith(prefix))) {
|
|
435
|
+
return true;
|
|
436
|
+
}
|
|
437
|
+
try {
|
|
438
|
+
const url = new URL(value);
|
|
439
|
+
return url.protocol === "http:" || url.protocol === "https:";
|
|
440
|
+
} catch {
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
var URL_PROPS = /* @__PURE__ */ new Set([
|
|
445
|
+
"src",
|
|
446
|
+
"href",
|
|
447
|
+
"xlinkhref",
|
|
448
|
+
"xlink:href",
|
|
449
|
+
// Obsolete but still implemented URL-bearing attributes on allowed elements.
|
|
450
|
+
"background",
|
|
451
|
+
"longdesc",
|
|
452
|
+
"usemap"
|
|
453
|
+
]);
|
|
454
|
+
function isTemplateUrlProp(name) {
|
|
455
|
+
return URL_PROPS.has(name.toLowerCase());
|
|
456
|
+
}
|
|
457
|
+
var SRCSET_PROPS = /* @__PURE__ */ new Set([
|
|
458
|
+
"srcset",
|
|
459
|
+
// React spells the preload attribute `imageSrcSet`; keep it guarded if the
|
|
460
|
+
// element allowlist ever expands to include `link`.
|
|
461
|
+
"imagesrcset"
|
|
462
|
+
]);
|
|
463
|
+
function isTemplateSrcSetProp(name) {
|
|
464
|
+
return SRCSET_PROPS.has(name.toLowerCase());
|
|
465
|
+
}
|
|
466
|
+
function isSafeTemplateSrcSet(value) {
|
|
467
|
+
if (typeof value !== "string" || value.trim() === "") return false;
|
|
468
|
+
return value.split(",").every((candidate) => {
|
|
469
|
+
const parts = candidate.trim().split(/\s+/);
|
|
470
|
+
if (parts.length === 0 || parts.length > 2 || !isSafeTemplateUrl(parts[0])) {
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
const descriptor = parts[1];
|
|
474
|
+
if (descriptor === void 0) return true;
|
|
475
|
+
if (/^[1-9]\d*w$/.test(descriptor)) return true;
|
|
476
|
+
if (/^(?:\d+(?:\.\d+)?|\.\d+)x$/.test(descriptor)) {
|
|
477
|
+
return Number.parseFloat(descriptor) > 0;
|
|
478
|
+
}
|
|
479
|
+
return false;
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
var URL_FUNCTION_PATTERN = /url\s*\(/i;
|
|
483
|
+
var SVG_URL_FUNCTION_PROPS = /* @__PURE__ */ new Set([
|
|
484
|
+
"clip-path",
|
|
485
|
+
"clippath",
|
|
486
|
+
"color-profile",
|
|
487
|
+
"colorprofile",
|
|
488
|
+
"cursor",
|
|
489
|
+
"fill",
|
|
490
|
+
"filter",
|
|
491
|
+
"marker",
|
|
492
|
+
"marker-end",
|
|
493
|
+
"marker-mid",
|
|
494
|
+
"marker-start",
|
|
495
|
+
"markerend",
|
|
496
|
+
"markermid",
|
|
497
|
+
"markerstart",
|
|
498
|
+
"mask",
|
|
499
|
+
"stroke"
|
|
500
|
+
]);
|
|
501
|
+
function isTemplatePaintProp(name) {
|
|
502
|
+
return SVG_URL_FUNCTION_PROPS.has(name.toLowerCase());
|
|
503
|
+
}
|
|
504
|
+
function isSafeTemplatePaintValue(value) {
|
|
505
|
+
if (typeof value === "string") return !URL_FUNCTION_PATTERN.test(value);
|
|
506
|
+
if (!Array.isArray(value) || value.length === 0) return false;
|
|
507
|
+
return value.every(
|
|
508
|
+
(candidate) => typeof candidate === "string" && !URL_FUNCTION_PATTERN.test(candidate)
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
var BLOCKED_STYLE_PROPS = /* @__PURE__ */ new Set([
|
|
512
|
+
"backgroundImage",
|
|
513
|
+
"background",
|
|
514
|
+
"listStyleImage",
|
|
515
|
+
"content",
|
|
516
|
+
"borderImage",
|
|
517
|
+
"borderImageSource",
|
|
518
|
+
"maskImage",
|
|
519
|
+
"mask",
|
|
520
|
+
"filter",
|
|
521
|
+
"cursor"
|
|
522
|
+
]);
|
|
523
|
+
function sanitizeTemplateStyle(style) {
|
|
524
|
+
if (!style || typeof style !== "object" || Array.isArray(style)) return {};
|
|
525
|
+
const safe = {};
|
|
526
|
+
for (const [key, value] of Object.entries(style)) {
|
|
527
|
+
if (BLOCKED_STYLE_PROPS.has(key)) continue;
|
|
528
|
+
if (typeof value === "string" && URL_FUNCTION_PATTERN.test(value)) continue;
|
|
529
|
+
if (key === "position" && typeof value === "string" && /fixed|sticky/i.test(value)) {
|
|
530
|
+
continue;
|
|
531
|
+
}
|
|
532
|
+
if (key === "zIndex") {
|
|
533
|
+
const numericValue = typeof value === "number" ? value : parseInt(String(value), 10);
|
|
534
|
+
if (isNaN(numericValue) || numericValue > 9998) continue;
|
|
535
|
+
}
|
|
536
|
+
safe[key] = value;
|
|
537
|
+
}
|
|
538
|
+
return safe;
|
|
539
|
+
}
|
|
540
|
+
function sanitizeTemplateProps(props) {
|
|
541
|
+
const safeProps = {};
|
|
542
|
+
for (const [key, value] of Object.entries(props)) {
|
|
543
|
+
const normalizedKey = key.toLowerCase();
|
|
544
|
+
if (normalizedKey.startsWith("on")) continue;
|
|
545
|
+
if (key === "dangerouslySetInnerHTML" || key === "ref") continue;
|
|
546
|
+
if (isTemplateUrlProp(key) && !isSafeTemplateUrl(value)) continue;
|
|
547
|
+
if (isTemplateSrcSetProp(key) && !isSafeTemplateSrcSet(value)) continue;
|
|
548
|
+
if (isTemplatePaintProp(key) && !isSafeTemplatePaintValue(value)) {
|
|
549
|
+
continue;
|
|
550
|
+
}
|
|
551
|
+
if (normalizedKey === "style") {
|
|
552
|
+
safeProps.style = sanitizeTemplateStyle(value);
|
|
553
|
+
continue;
|
|
554
|
+
}
|
|
555
|
+
safeProps[key] = value;
|
|
556
|
+
}
|
|
557
|
+
return safeProps;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// src/ui/Canvas/template-compiler.ts
|
|
561
|
+
var WIRE_FORMAT_VERSION = 1;
|
|
562
|
+
var MAX_CACHE_SIZE = 100;
|
|
563
|
+
var MAX_MATERIALIZE_DEPTH = 20;
|
|
395
564
|
var VM_SETUP = `
|
|
396
565
|
var React = {
|
|
397
566
|
createElement: function(type, props) {
|
|
@@ -428,52 +597,7 @@ function hashCode(str) {
|
|
|
428
597
|
return hash.toString(36);
|
|
429
598
|
}
|
|
430
599
|
function validateTemplateCode(code) {
|
|
431
|
-
return
|
|
432
|
-
}
|
|
433
|
-
var SAFE_DATA_URI_PREFIXES = [
|
|
434
|
-
"data:image/png;",
|
|
435
|
-
"data:image/jpeg;",
|
|
436
|
-
"data:image/gif;",
|
|
437
|
-
"data:image/webp;",
|
|
438
|
-
"data:image/avif;"
|
|
439
|
-
];
|
|
440
|
-
function isSafeUrl(value) {
|
|
441
|
-
if (typeof value !== "string") return false;
|
|
442
|
-
if (value.startsWith("/") || value.startsWith("./") || value.startsWith("../")) return true;
|
|
443
|
-
if (SAFE_DATA_URI_PREFIXES.some((p) => value.startsWith(p))) return true;
|
|
444
|
-
try {
|
|
445
|
-
const url = new URL(value);
|
|
446
|
-
return url.protocol === "http:" || url.protocol === "https:";
|
|
447
|
-
} catch {
|
|
448
|
-
return false;
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
var BLOCKED_STYLE_PROPS = /* @__PURE__ */ new Set([
|
|
452
|
-
"backgroundImage",
|
|
453
|
-
"background",
|
|
454
|
-
"listStyleImage",
|
|
455
|
-
"content",
|
|
456
|
-
"borderImage",
|
|
457
|
-
"borderImageSource",
|
|
458
|
-
"maskImage",
|
|
459
|
-
"mask",
|
|
460
|
-
"filter",
|
|
461
|
-
"cursor"
|
|
462
|
-
]);
|
|
463
|
-
function sanitizeStyle(style) {
|
|
464
|
-
if (!style || typeof style !== "object" || Array.isArray(style)) return {};
|
|
465
|
-
const safe = {};
|
|
466
|
-
for (const [k, v] of Object.entries(style)) {
|
|
467
|
-
if (BLOCKED_STYLE_PROPS.has(k)) continue;
|
|
468
|
-
if (typeof v === "string" && /url\s*\(/i.test(v)) continue;
|
|
469
|
-
if (k === "position" && typeof v === "string" && /fixed|sticky/i.test(v)) continue;
|
|
470
|
-
if (k === "zIndex") {
|
|
471
|
-
const n = typeof v === "number" ? v : parseInt(String(v), 10);
|
|
472
|
-
if (isNaN(n) || n > 9998) continue;
|
|
473
|
-
}
|
|
474
|
-
safe[k] = v;
|
|
475
|
-
}
|
|
476
|
-
return safe;
|
|
600
|
+
return findBlockedTemplatePattern(code) === null;
|
|
477
601
|
}
|
|
478
602
|
function materialize(node, depth = 0) {
|
|
479
603
|
if (depth > MAX_MATERIALIZE_DEPTH) return null;
|
|
@@ -501,18 +625,8 @@ function materialize(node, depth = 0) {
|
|
|
501
625
|
const type = String(d.type ?? "");
|
|
502
626
|
const props = d.props && typeof d.props === "object" ? d.props : {};
|
|
503
627
|
const ch = Array.isArray(d.ch) ? d.ch : [];
|
|
504
|
-
if (!
|
|
505
|
-
const safeProps =
|
|
506
|
-
for (const [k, v] of Object.entries(props)) {
|
|
507
|
-
if (k.startsWith("on")) continue;
|
|
508
|
-
if (k === "dangerouslySetInnerHTML" || k === "ref") continue;
|
|
509
|
-
if ((k === "src" || k === "href") && !isSafeUrl(v)) continue;
|
|
510
|
-
if (k === "style") {
|
|
511
|
-
safeProps[k] = sanitizeStyle(v);
|
|
512
|
-
continue;
|
|
513
|
-
}
|
|
514
|
-
safeProps[k] = v;
|
|
515
|
-
}
|
|
628
|
+
if (!isAllowedTemplateElement(type)) return null;
|
|
629
|
+
const safeProps = sanitizeTemplateProps(props);
|
|
516
630
|
const children = ch.map((c) => materialize(c, depth + 1));
|
|
517
631
|
return React.createElement(type, safeProps, ...children);
|
|
518
632
|
}
|
|
@@ -796,19 +910,22 @@ function sanitizeImageData(image, safeUrl) {
|
|
|
796
910
|
) : image.sizes
|
|
797
911
|
};
|
|
798
912
|
}
|
|
799
|
-
function renderFieldValue(key, val, fieldDef) {
|
|
913
|
+
function renderFieldValue(key, val, fieldDef, imageAlt) {
|
|
800
914
|
if (val == null || val === "") return null;
|
|
801
915
|
const fieldType = fieldDef?.fieldType;
|
|
802
916
|
if (fieldType === "image" || typeof val === "object" && val !== null && "url" in val) {
|
|
803
917
|
const imgUrl = typeof val === "string" ? val : val?.url;
|
|
804
918
|
const safeUrl = sanitizeUrl(imgUrl);
|
|
805
919
|
if (!safeUrl) return null;
|
|
920
|
+
const embeddedAlt = typeof val === "object" && val !== null && "alt" in val && typeof val.alt === "string" ? val.alt : void 0;
|
|
921
|
+
const alt = imageAlt?.authored !== void 0 ? imageAlt.authored : embeddedAlt !== void 0 ? embeddedAlt : imageAlt?.fallback ?? "";
|
|
806
922
|
if (fieldType === "image" && typeof val === "object" && val !== null) {
|
|
807
923
|
return /* @__PURE__ */ React3.createElement(
|
|
808
924
|
Image,
|
|
809
925
|
{
|
|
810
926
|
key,
|
|
811
927
|
image: sanitizeImageData(val, safeUrl),
|
|
928
|
+
alt,
|
|
812
929
|
fill: true,
|
|
813
930
|
objectFit: "contain",
|
|
814
931
|
style: { flex: 1, minHeight: 0, width: "100%" }
|
|
@@ -820,7 +937,7 @@ function renderFieldValue(key, val, fieldDef) {
|
|
|
820
937
|
{
|
|
821
938
|
key,
|
|
822
939
|
src: safeUrl,
|
|
823
|
-
alt
|
|
940
|
+
alt,
|
|
824
941
|
draggable: false,
|
|
825
942
|
style: { flex: 1, minHeight: 0, width: "100%", objectFit: "contain" }
|
|
826
943
|
}
|
|
@@ -843,6 +960,7 @@ function renderFieldValue(key, val, fieldDef) {
|
|
|
843
960
|
}
|
|
844
961
|
function DefaultDynamicNode({ data }) {
|
|
845
962
|
const d = data;
|
|
963
|
+
const authoredImageAlt = typeof d.fields?.alt === "string" ? d.fields.alt : void 0;
|
|
846
964
|
return /* @__PURE__ */ React3.createElement(
|
|
847
965
|
"div",
|
|
848
966
|
{
|
|
@@ -853,7 +971,12 @@ function DefaultDynamicNode({ data }) {
|
|
|
853
971
|
flexDirection: "column"
|
|
854
972
|
}
|
|
855
973
|
},
|
|
856
|
-
d.fields && Object.entries(d.fields).filter(([, v]) => v != null && v !== "").map(
|
|
974
|
+
d.fields && Object.entries(d.fields).filter(([, v]) => v != null && v !== "").map(
|
|
975
|
+
([key, val]) => renderFieldValue(key, val, void 0, {
|
|
976
|
+
authored: authoredImageAlt,
|
|
977
|
+
fallback: d.label
|
|
978
|
+
})
|
|
979
|
+
)
|
|
857
980
|
);
|
|
858
981
|
}
|
|
859
982
|
var TemplateErrorBoundary = class extends React3.Component {
|
|
@@ -883,13 +1006,14 @@ function EnhancedDynamicNode({
|
|
|
883
1006
|
height
|
|
884
1007
|
}) {
|
|
885
1008
|
useQuickJS();
|
|
1009
|
+
const authoredImageAlt = typeof data.fields?.alt === "string" ? data.fields.alt : void 0;
|
|
886
1010
|
if (typeDef.template) {
|
|
887
1011
|
const Component = compileTemplate(typeDef.template, typeDef.slug);
|
|
888
1012
|
if (Component) {
|
|
889
1013
|
return /* @__PURE__ */ React3.createElement(
|
|
890
1014
|
"div",
|
|
891
1015
|
{
|
|
892
|
-
className: `flow-node flow-node--${typeDef.slug}${typeDef.transparentBackground ? "
|
|
1016
|
+
className: `flow-node flow-node--${typeDef.slug}${typeDef.transparentBackground ? "flow-node--transparent-bg" : ""}`,
|
|
893
1017
|
style: { width: "100%", height: "100%" }
|
|
894
1018
|
},
|
|
895
1019
|
/* @__PURE__ */ React3.createElement(TemplateErrorBoundary, { resetKey: typeDef.template }, /* @__PURE__ */ React3.createElement(
|
|
@@ -920,7 +1044,10 @@ function EnhancedDynamicNode({
|
|
|
920
1044
|
typeDef.fields.map((f) => {
|
|
921
1045
|
const val = data.fields[f.name];
|
|
922
1046
|
if (val == null || val === "") return null;
|
|
923
|
-
return renderFieldValue(f.name, val, f
|
|
1047
|
+
return renderFieldValue(f.name, val, f, {
|
|
1048
|
+
authored: authoredImageAlt,
|
|
1049
|
+
fallback: data.label
|
|
1050
|
+
});
|
|
924
1051
|
})
|
|
925
1052
|
);
|
|
926
1053
|
}
|
|
@@ -966,6 +1093,90 @@ function DefaultFrameNode({ data }) {
|
|
|
966
1093
|
)
|
|
967
1094
|
);
|
|
968
1095
|
}
|
|
1096
|
+
var DEFAULT_SHAPE_COLOR = "#dbeafe";
|
|
1097
|
+
var SHAPE_STROKE = "#334155";
|
|
1098
|
+
function ShapeGeometry({ shape, color }) {
|
|
1099
|
+
const common = {
|
|
1100
|
+
fill: color,
|
|
1101
|
+
stroke: SHAPE_STROKE,
|
|
1102
|
+
strokeWidth: 2,
|
|
1103
|
+
vectorEffect: "non-scaling-stroke"
|
|
1104
|
+
};
|
|
1105
|
+
switch (shape) {
|
|
1106
|
+
case "terminator":
|
|
1107
|
+
return /* @__PURE__ */ React3.createElement("rect", { x: "1", y: "1", width: "198", height: "98", rx: "49", ...common });
|
|
1108
|
+
case "decision":
|
|
1109
|
+
return /* @__PURE__ */ React3.createElement("polygon", { points: "100,1 199,50 100,99 1,50", ...common });
|
|
1110
|
+
case "io":
|
|
1111
|
+
return /* @__PURE__ */ React3.createElement("polygon", { points: "25,1 199,1 175,99 1,99", ...common });
|
|
1112
|
+
case "subprocess":
|
|
1113
|
+
return /* @__PURE__ */ React3.createElement("g", null, /* @__PURE__ */ React3.createElement("rect", { x: "1", y: "1", width: "198", height: "98", rx: "3", ...common }), /* @__PURE__ */ React3.createElement(
|
|
1114
|
+
"path",
|
|
1115
|
+
{
|
|
1116
|
+
d: "M20 1V99M180 1V99",
|
|
1117
|
+
fill: "none",
|
|
1118
|
+
stroke: SHAPE_STROKE,
|
|
1119
|
+
strokeWidth: "2",
|
|
1120
|
+
vectorEffect: "non-scaling-stroke"
|
|
1121
|
+
}
|
|
1122
|
+
));
|
|
1123
|
+
case "process":
|
|
1124
|
+
default:
|
|
1125
|
+
return /* @__PURE__ */ React3.createElement("rect", { x: "1", y: "1", width: "198", height: "98", rx: "3", ...common });
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
function DefaultShapeNode({ data }) {
|
|
1129
|
+
const shapeData = data;
|
|
1130
|
+
return /* @__PURE__ */ React3.createElement(
|
|
1131
|
+
"div",
|
|
1132
|
+
{
|
|
1133
|
+
className: `flow-node flow-node--shape flow-node--shape-${shapeData.shape}`,
|
|
1134
|
+
style: { width: "100%", height: "100%", position: "relative" },
|
|
1135
|
+
"data-shape": shapeData.shape
|
|
1136
|
+
},
|
|
1137
|
+
/* @__PURE__ */ React3.createElement(
|
|
1138
|
+
"svg",
|
|
1139
|
+
{
|
|
1140
|
+
"aria-hidden": "true",
|
|
1141
|
+
focusable: "false",
|
|
1142
|
+
viewBox: "0 0 200 100",
|
|
1143
|
+
preserveAspectRatio: "none",
|
|
1144
|
+
style: {
|
|
1145
|
+
position: "absolute",
|
|
1146
|
+
inset: 0,
|
|
1147
|
+
width: "100%",
|
|
1148
|
+
height: "100%"
|
|
1149
|
+
}
|
|
1150
|
+
},
|
|
1151
|
+
/* @__PURE__ */ React3.createElement(
|
|
1152
|
+
ShapeGeometry,
|
|
1153
|
+
{
|
|
1154
|
+
shape: shapeData.shape,
|
|
1155
|
+
color: shapeData.color ?? DEFAULT_SHAPE_COLOR
|
|
1156
|
+
}
|
|
1157
|
+
)
|
|
1158
|
+
),
|
|
1159
|
+
/* @__PURE__ */ React3.createElement(
|
|
1160
|
+
"div",
|
|
1161
|
+
{
|
|
1162
|
+
style: {
|
|
1163
|
+
position: "absolute",
|
|
1164
|
+
inset: "12%",
|
|
1165
|
+
display: "flex",
|
|
1166
|
+
alignItems: "center",
|
|
1167
|
+
justifyContent: "center",
|
|
1168
|
+
overflow: "hidden",
|
|
1169
|
+
color: "#0f172a",
|
|
1170
|
+
fontSize: 12,
|
|
1171
|
+
fontWeight: 600,
|
|
1172
|
+
textAlign: "center",
|
|
1173
|
+
wordBreak: "break-word"
|
|
1174
|
+
}
|
|
1175
|
+
},
|
|
1176
|
+
shapeData.label
|
|
1177
|
+
)
|
|
1178
|
+
);
|
|
1179
|
+
}
|
|
969
1180
|
|
|
970
1181
|
// src/ui/Canvas/field-helpers.ts
|
|
971
1182
|
function getImageField(fields, name) {
|
|
@@ -1184,9 +1395,12 @@ import {
|
|
|
1184
1395
|
|
|
1185
1396
|
// src/ui/Canvas/node-types-factory.tsx
|
|
1186
1397
|
import React4 from "react";
|
|
1398
|
+
function areNodePropsEqual(prev, next) {
|
|
1399
|
+
return prev.id === next.id && prev.data === next.data && prev.selected === next.selected && prev.dragging === next.dragging && prev.width === next.width && prev.height === next.height;
|
|
1400
|
+
}
|
|
1187
1401
|
function createNodeTypes(nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrapper, renderNode) {
|
|
1188
1402
|
const types = {};
|
|
1189
|
-
|
|
1403
|
+
const DynamicNode = (props) => {
|
|
1190
1404
|
const d = props.data;
|
|
1191
1405
|
const typeDef = nodeTypeDefsMap?.get(d.nodeTypeSlug);
|
|
1192
1406
|
const CustomRenderer = nodeRenderers?.[d.nodeTypeSlug];
|
|
@@ -1235,8 +1449,12 @@ function createNodeTypes(nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrap
|
|
|
1235
1449
|
);
|
|
1236
1450
|
}
|
|
1237
1451
|
return content;
|
|
1238
|
-
}
|
|
1239
|
-
types.
|
|
1452
|
+
};
|
|
1453
|
+
types.dynamic = React4.memo(
|
|
1454
|
+
DynamicNode,
|
|
1455
|
+
areNodePropsEqual
|
|
1456
|
+
);
|
|
1457
|
+
const FrameNode = frameRenderer ? (props) => {
|
|
1240
1458
|
const d = props.data;
|
|
1241
1459
|
const Renderer = frameRenderer;
|
|
1242
1460
|
return /* @__PURE__ */ React4.createElement(
|
|
@@ -1252,7 +1470,10 @@ function createNodeTypes(nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrap
|
|
|
1252
1470
|
height: props.height
|
|
1253
1471
|
}
|
|
1254
1472
|
);
|
|
1255
|
-
}
|
|
1473
|
+
} : DefaultFrameNode;
|
|
1474
|
+
types.frame = React4.memo(FrameNode, areNodePropsEqual);
|
|
1475
|
+
const ShapeNode = (props) => /* @__PURE__ */ React4.createElement(DefaultShapeNode, { ...props });
|
|
1476
|
+
types.shape = React4.memo(ShapeNode, areNodePropsEqual);
|
|
1256
1477
|
return types;
|
|
1257
1478
|
}
|
|
1258
1479
|
function createEdgeTypes(edgeRenderers, edgeTypeDefsMap) {
|
|
@@ -1462,18 +1683,82 @@ function FocusHandler({
|
|
|
1462
1683
|
);
|
|
1463
1684
|
}
|
|
1464
1685
|
|
|
1686
|
+
// src/ui/Canvas/accessibility.ts
|
|
1687
|
+
var CANVAS_ACCESSIBILITY_LABELS = {
|
|
1688
|
+
ko: {
|
|
1689
|
+
canvas: "\uCE94\uBC84\uC2A4 \uB2E4\uC774\uC5B4\uADF8\uB7A8",
|
|
1690
|
+
node: "\uB178\uB4DC",
|
|
1691
|
+
frame: "\uD504\uB808\uC784",
|
|
1692
|
+
ariaLabelConfig: {
|
|
1693
|
+
"node.a11yDescription.default": "\uCE94\uBC84\uC2A4 \uB2E4\uC774\uC5B4\uADF8\uB7A8\uC758 \uB178\uB4DC\uC785\uB2C8\uB2E4.",
|
|
1694
|
+
"node.a11yDescription.keyboardDisabled": "\uCE94\uBC84\uC2A4 \uB2E4\uC774\uC5B4\uADF8\uB7A8\uC758 \uB178\uB4DC\uC785\uB2C8\uB2E4.",
|
|
1695
|
+
"edge.a11yDescription.default": "\uCE94\uBC84\uC2A4 \uB2E4\uC774\uC5B4\uADF8\uB7A8\uC758 \uC5F0\uACB0\uC120\uC785\uB2C8\uB2E4.",
|
|
1696
|
+
"controls.ariaLabel": "\uCE94\uBC84\uC2A4 \uC81C\uC5B4\uD310",
|
|
1697
|
+
"controls.zoomIn.ariaLabel": "\uD655\uB300",
|
|
1698
|
+
"controls.zoomOut.ariaLabel": "\uCD95\uC18C",
|
|
1699
|
+
"controls.fitView.ariaLabel": "\uD654\uBA74\uC5D0 \uB9DE\uCD94\uAE30",
|
|
1700
|
+
"controls.interactive.ariaLabel": "\uC0C1\uD638\uC791\uC6A9 \uC804\uD658",
|
|
1701
|
+
"minimap.ariaLabel": "\uBBF8\uB2C8\uB9F5",
|
|
1702
|
+
"handle.ariaLabel": "\uC5F0\uACB0\uC810"
|
|
1703
|
+
}
|
|
1704
|
+
},
|
|
1705
|
+
en: {
|
|
1706
|
+
canvas: "Canvas diagram",
|
|
1707
|
+
node: "Node",
|
|
1708
|
+
frame: "Frame",
|
|
1709
|
+
ariaLabelConfig: {
|
|
1710
|
+
"node.a11yDescription.default": "A node in the canvas diagram.",
|
|
1711
|
+
"node.a11yDescription.keyboardDisabled": "A node in the canvas diagram.",
|
|
1712
|
+
"edge.a11yDescription.default": "A connection in the canvas diagram.",
|
|
1713
|
+
"controls.ariaLabel": "Canvas controls",
|
|
1714
|
+
"controls.zoomIn.ariaLabel": "Zoom in",
|
|
1715
|
+
"controls.zoomOut.ariaLabel": "Zoom out",
|
|
1716
|
+
"controls.fitView.ariaLabel": "Fit view",
|
|
1717
|
+
"controls.interactive.ariaLabel": "Toggle interactivity",
|
|
1718
|
+
"minimap.ariaLabel": "Mini map",
|
|
1719
|
+
"handle.ariaLabel": "Handle"
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
};
|
|
1723
|
+
function nodeAriaLabel(node, labels) {
|
|
1724
|
+
const explicitLabel = typeof node.ariaLabel === "string" ? node.ariaLabel.trim() : "";
|
|
1725
|
+
if (explicitLabel) return explicitLabel;
|
|
1726
|
+
const isFrame = node.type === "frame";
|
|
1727
|
+
const label = node.data?.label?.trim();
|
|
1728
|
+
if (!label) return isFrame ? labels.frame : labels.node;
|
|
1729
|
+
return isFrame ? `${label} (${labels.frame})` : label;
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1465
1732
|
// src/ui/Canvas/CanvasRenderer.tsx
|
|
1733
|
+
function usePrefersReducedMotion() {
|
|
1734
|
+
const query = "(prefers-reduced-motion: reduce)";
|
|
1735
|
+
const [prefersReducedMotion, setPrefersReducedMotion] = React6.useState(
|
|
1736
|
+
() => typeof window !== "undefined" && window.matchMedia?.(query).matches
|
|
1737
|
+
);
|
|
1738
|
+
React6.useEffect(() => {
|
|
1739
|
+
if (typeof window === "undefined" || !window.matchMedia) return;
|
|
1740
|
+
const mediaQuery = window.matchMedia(query);
|
|
1741
|
+
const handleChange = (event) => setPrefersReducedMotion(event.matches);
|
|
1742
|
+
setPrefersReducedMotion(mediaQuery.matches);
|
|
1743
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
1744
|
+
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
1745
|
+
}, []);
|
|
1746
|
+
return prefersReducedMotion;
|
|
1747
|
+
}
|
|
1466
1748
|
var NullFrameRenderer = () => null;
|
|
1467
1749
|
function CanvasRenderer({
|
|
1468
1750
|
data,
|
|
1469
1751
|
className,
|
|
1470
1752
|
style,
|
|
1753
|
+
ariaLabel,
|
|
1754
|
+
locale = "en",
|
|
1471
1755
|
nodeRenderers,
|
|
1472
1756
|
nodeTypeDefs,
|
|
1473
1757
|
edgeTypeDefs,
|
|
1474
1758
|
background = false,
|
|
1475
1759
|
interactive = false,
|
|
1476
1760
|
fitView = true,
|
|
1761
|
+
onlyRenderVisibleElements = true,
|
|
1477
1762
|
onNodeClick,
|
|
1478
1763
|
onNodeDoubleClick,
|
|
1479
1764
|
onNodeContextMenu,
|
|
@@ -1501,6 +1786,8 @@ function CanvasRenderer({
|
|
|
1501
1786
|
minZoom: minZoomProp,
|
|
1502
1787
|
maxZoom: maxZoomProp
|
|
1503
1788
|
}) {
|
|
1789
|
+
const prefersReducedMotion = usePrefersReducedMotion();
|
|
1790
|
+
const accessibilityLabels = CANVAS_ACCESSIBILITY_LABELS[locale];
|
|
1504
1791
|
const resolvedFrameRenderer = hideFrames ? NullFrameRenderer : frameRenderer;
|
|
1505
1792
|
const nodeTypeDefsMap = React6.useMemo(() => {
|
|
1506
1793
|
if (!nodeTypeDefs?.length) return void 0;
|
|
@@ -1518,7 +1805,13 @@ function CanvasRenderer({
|
|
|
1518
1805
|
nodeWrapper,
|
|
1519
1806
|
renderNode
|
|
1520
1807
|
),
|
|
1521
|
-
[
|
|
1808
|
+
[
|
|
1809
|
+
nodeRenderers,
|
|
1810
|
+
nodeTypeDefsMap,
|
|
1811
|
+
resolvedFrameRenderer,
|
|
1812
|
+
nodeWrapper,
|
|
1813
|
+
renderNode
|
|
1814
|
+
]
|
|
1522
1815
|
);
|
|
1523
1816
|
const customEdgeTypes = React6.useMemo(
|
|
1524
1817
|
() => createEdgeTypes(edgeRenderers, edgeTypeDefsMap),
|
|
@@ -1541,6 +1834,21 @@ function CanvasRenderer({
|
|
|
1541
1834
|
}
|
|
1542
1835
|
return edges;
|
|
1543
1836
|
}, [data?.edges, edgeTypeDefsMap, edgeRenderers]);
|
|
1837
|
+
const accessibleNodes = React6.useMemo(
|
|
1838
|
+
() => (data?.nodes ?? []).map((node) => ({
|
|
1839
|
+
...node,
|
|
1840
|
+
...node.type === "shape" ? {
|
|
1841
|
+
style: {
|
|
1842
|
+
...node.style,
|
|
1843
|
+
background: "transparent",
|
|
1844
|
+
border: "none",
|
|
1845
|
+
padding: 0
|
|
1846
|
+
}
|
|
1847
|
+
} : {},
|
|
1848
|
+
ariaLabel: nodeAriaLabel(node, accessibilityLabels)
|
|
1849
|
+
})),
|
|
1850
|
+
[data?.nodes, accessibilityLabels]
|
|
1851
|
+
);
|
|
1544
1852
|
const translateExtent = React6.useMemo(() => {
|
|
1545
1853
|
if (translateExtentProp) return translateExtentProp;
|
|
1546
1854
|
const es = clampBounds ?? bounds;
|
|
@@ -1575,6 +1883,8 @@ function CanvasRenderer({
|
|
|
1575
1883
|
return /* @__PURE__ */ React6.createElement(ReactFlowProvider, null, /* @__PURE__ */ React6.createElement(
|
|
1576
1884
|
"div",
|
|
1577
1885
|
{
|
|
1886
|
+
role: "region",
|
|
1887
|
+
"aria-label": ariaLabel ?? accessibilityLabels.canvas,
|
|
1578
1888
|
className,
|
|
1579
1889
|
style: {
|
|
1580
1890
|
width: "100%",
|
|
@@ -1586,12 +1896,13 @@ function CanvasRenderer({
|
|
|
1586
1896
|
/* @__PURE__ */ React6.createElement(
|
|
1587
1897
|
ReactFlow,
|
|
1588
1898
|
{
|
|
1589
|
-
nodes:
|
|
1899
|
+
nodes: accessibleNodes,
|
|
1590
1900
|
edges: styledEdges,
|
|
1591
1901
|
nodeTypes,
|
|
1592
1902
|
edgeTypes: customEdgeTypes,
|
|
1593
1903
|
defaultViewport: resolvedDefaultViewport,
|
|
1594
1904
|
fitView: bounds ? false : fitView,
|
|
1905
|
+
onlyRenderVisibleElements,
|
|
1595
1906
|
translateExtent: activeExtent,
|
|
1596
1907
|
onNodeClick,
|
|
1597
1908
|
onNodeDoubleClick,
|
|
@@ -1605,13 +1916,15 @@ function CanvasRenderer({
|
|
|
1605
1916
|
nodesDraggable: interactive,
|
|
1606
1917
|
nodesConnectable: false,
|
|
1607
1918
|
elementsSelectable: interactive || !!onNodeClick || !!onNodeDoubleClick || !!onEdgeClick,
|
|
1919
|
+
autoPanOnSelection: false,
|
|
1608
1920
|
panOnDrag: interactive,
|
|
1609
1921
|
zoomOnScroll: interactive,
|
|
1610
1922
|
zoomOnPinch: interactive,
|
|
1611
1923
|
zoomOnDoubleClick: false,
|
|
1612
1924
|
minZoom: minZoomProp,
|
|
1613
1925
|
maxZoom: maxZoomProp,
|
|
1614
|
-
proOptions: { hideAttribution: true }
|
|
1926
|
+
proOptions: { hideAttribution: true },
|
|
1927
|
+
ariaLabelConfig: accessibilityLabels.ariaLabelConfig
|
|
1615
1928
|
},
|
|
1616
1929
|
mergedCSS && /* @__PURE__ */ React6.createElement("style", { dangerouslySetInnerHTML: { __html: mergedCSS } }),
|
|
1617
1930
|
background && /* @__PURE__ */ React6.createElement(Background, null),
|
|
@@ -1627,7 +1940,7 @@ function CanvasRenderer({
|
|
|
1627
1940
|
{
|
|
1628
1941
|
bounds,
|
|
1629
1942
|
padding: focusPadding ?? 0.1,
|
|
1630
|
-
animation: focusAnimation ?? true,
|
|
1943
|
+
animation: prefersReducedMotion ? false : focusAnimation ?? true,
|
|
1631
1944
|
mode: focusMode,
|
|
1632
1945
|
responsive: responsiveFit ?? true,
|
|
1633
1946
|
extent: translateExtent,
|
|
@@ -1697,8 +2010,10 @@ function CanvasFrame({
|
|
|
1697
2010
|
);
|
|
1698
2011
|
}
|
|
1699
2012
|
export {
|
|
2013
|
+
CANVAS_SHAPE_TYPES,
|
|
1700
2014
|
CanvasFrame,
|
|
1701
2015
|
CanvasRenderer,
|
|
2016
|
+
DefaultShapeNode,
|
|
1702
2017
|
clearTemplateCache,
|
|
1703
2018
|
compileTemplate,
|
|
1704
2019
|
getBooleanField,
|
|
@@ -1710,6 +2025,7 @@ export {
|
|
|
1710
2025
|
getTextField,
|
|
1711
2026
|
isDynamicNode,
|
|
1712
2027
|
isFrameNode,
|
|
2028
|
+
isShapeNode,
|
|
1713
2029
|
prefetchCanvas,
|
|
1714
2030
|
renderFieldValue,
|
|
1715
2031
|
sanitizeCSS,
|