@almadar/ui 4.39.0 → 4.39.1

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.
@@ -51913,12 +51913,17 @@ function FlowCanvasInner({
51913
51913
  const [edges, setEdges, onEdgesChange] = react.useEdgesState(activeEdges);
51914
51914
  const reactFlow = react.useReactFlow();
51915
51915
  React119.useEffect(() => {
51916
+ setEdges([]);
51916
51917
  setNodes(activeNodes);
51917
51918
  setEdges(activeEdges);
51918
51919
  requestAnimationFrame(() => {
51919
51920
  reactFlow.fitView({ duration: 300, padding: 0.15 });
51920
51921
  });
51921
51922
  }, [activeNodes, activeEdges, setNodes, setEdges, reactFlow]);
51923
+ const visibleEdges = React119.useMemo(() => {
51924
+ const nodeIds = new Set(nodes.map((n) => n.id));
51925
+ return edges.filter((e) => nodeIds.has(e.source) && nodeIds.has(e.target));
51926
+ }, [nodes, edges]);
51922
51927
  const handleNodeDoubleClick = React119.useCallback((_, node) => {
51923
51928
  if (atBehaviorLevel && composeLevel === "behavior") {
51924
51929
  const d = node.data;
@@ -52052,7 +52057,7 @@ function FlowCanvasInner({
52052
52057
  react.ReactFlow,
52053
52058
  {
52054
52059
  nodes,
52055
- edges,
52060
+ edges: visibleEdges,
52056
52061
  nodeTypes: NODE_TYPES,
52057
52062
  edgeTypes: EDGE_TYPES,
52058
52063
  defaultEdgeOptions: DEFAULT_EDGE_OPTIONS,
@@ -52727,7 +52732,10 @@ var EventWireOverlay = ({
52727
52732
  const y1 = fromPos.cy + ny * orbitalR;
52728
52733
  const x2 = toPos.cx - nx * (orbitalR + 6);
52729
52734
  const y2 = toPos.cy - ny * (orbitalR + 6);
52730
- const offset = 25 + wireIdx * 18;
52735
+ const total = links.length;
52736
+ const span = Math.min(90, Math.max(0, total - 1) * 14);
52737
+ const step = total > 1 ? span / (total - 1) : 0;
52738
+ const offset = 25 + (wireIdx - (total - 1) / 2) * step;
52731
52739
  const { cpx, cpy } = curveControlPoint(x1, y1, x2, y2, offset);
52732
52740
  const pathD = `M${x1},${y1} Q${cpx},${cpy} ${x2},${y2}`;
52733
52741
  if (!Number.isFinite(x1) || !Number.isFinite(y1) || !Number.isFinite(x2) || !Number.isFinite(y2) || !Number.isFinite(cpx) || !Number.isFinite(cpy)) {
package/dist/avl/index.js CHANGED
@@ -51867,12 +51867,17 @@ function FlowCanvasInner({
51867
51867
  const [edges, setEdges, onEdgesChange] = useEdgesState(activeEdges);
51868
51868
  const reactFlow = useReactFlow();
51869
51869
  useEffect(() => {
51870
+ setEdges([]);
51870
51871
  setNodes(activeNodes);
51871
51872
  setEdges(activeEdges);
51872
51873
  requestAnimationFrame(() => {
51873
51874
  reactFlow.fitView({ duration: 300, padding: 0.15 });
51874
51875
  });
51875
51876
  }, [activeNodes, activeEdges, setNodes, setEdges, reactFlow]);
51877
+ const visibleEdges = useMemo(() => {
51878
+ const nodeIds = new Set(nodes.map((n) => n.id));
51879
+ return edges.filter((e) => nodeIds.has(e.source) && nodeIds.has(e.target));
51880
+ }, [nodes, edges]);
51876
51881
  const handleNodeDoubleClick = useCallback((_, node) => {
51877
51882
  if (atBehaviorLevel && composeLevel === "behavior") {
51878
51883
  const d = node.data;
@@ -52006,7 +52011,7 @@ function FlowCanvasInner({
52006
52011
  ReactFlow,
52007
52012
  {
52008
52013
  nodes,
52009
- edges,
52014
+ edges: visibleEdges,
52010
52015
  nodeTypes: NODE_TYPES,
52011
52016
  edgeTypes: EDGE_TYPES,
52012
52017
  defaultEdgeOptions: DEFAULT_EDGE_OPTIONS,
@@ -52681,7 +52686,10 @@ var EventWireOverlay = ({
52681
52686
  const y1 = fromPos.cy + ny * orbitalR;
52682
52687
  const x2 = toPos.cx - nx * (orbitalR + 6);
52683
52688
  const y2 = toPos.cy - ny * (orbitalR + 6);
52684
- const offset = 25 + wireIdx * 18;
52689
+ const total = links.length;
52690
+ const span = Math.min(90, Math.max(0, total - 1) * 14);
52691
+ const step = total > 1 ? span / (total - 1) : 0;
52692
+ const offset = 25 + (wireIdx - (total - 1) / 2) * step;
52685
52693
  const { cpx, cpy } = curveControlPoint(x1, y1, x2, y2, offset);
52686
52694
  const pathD = `M${x1},${y1} Q${cpx},${cpy} ${x2},${y2}`;
52687
52695
  if (!Number.isFinite(x1) || !Number.isFinite(y1) || !Number.isFinite(x2) || !Number.isFinite(y2) || !Number.isFinite(cpx) || !Number.isFinite(cpy)) {
@@ -26895,6 +26895,16 @@ function nextBlockId(prefix = "blk") {
26895
26895
  const random = Math.random().toString(36).slice(2, 8);
26896
26896
  return `${prefix}-${Date.now().toString(36)}-${_idSeq}-${random}`;
26897
26897
  }
26898
+ function normalizeBlocks(raw) {
26899
+ if (!raw || raw.length === 0) return [createBlock("paragraph")];
26900
+ return raw.map((row) => {
26901
+ const r = row;
26902
+ const rawType = r.type;
26903
+ const type = typeof rawType === "string" && BLOCK_TYPES.has(rawType) ? rawType : "paragraph";
26904
+ const id = typeof r.id === "string" && r.id ? r.id : nextBlockId(type);
26905
+ return { ...r, id, type };
26906
+ });
26907
+ }
26898
26908
  function createBlock(type) {
26899
26909
  switch (type) {
26900
26910
  case "bullet-list":
@@ -27445,7 +27455,7 @@ function BlockRow({
27445
27455
  }
27446
27456
  );
27447
27457
  }
27448
- var TOOLBAR_ENTRIES, BLOCK_TYPE_LABEL, CHANGEABLE_TYPES, _idSeq; exports.RichBlockEditor = void 0;
27458
+ var TOOLBAR_ENTRIES, BLOCK_TYPE_LABEL, CHANGEABLE_TYPES, _idSeq, BLOCK_TYPES; exports.RichBlockEditor = void 0;
27449
27459
  var init_RichBlockEditor = __esm({
27450
27460
  "components/molecules/RichBlockEditor.tsx"() {
27451
27461
  "use client";
@@ -27492,6 +27502,18 @@ var init_RichBlockEditor = __esm({
27492
27502
  "code"
27493
27503
  ];
27494
27504
  _idSeq = 0;
27505
+ BLOCK_TYPES = /* @__PURE__ */ new Set([
27506
+ "paragraph",
27507
+ "heading-1",
27508
+ "heading-2",
27509
+ "heading-3",
27510
+ "bullet-list",
27511
+ "numbered-list",
27512
+ "quote",
27513
+ "code",
27514
+ "divider",
27515
+ "image"
27516
+ ]);
27495
27517
  exports.RichBlockEditor = ({
27496
27518
  initialBlocks,
27497
27519
  onChange,
@@ -27502,7 +27524,7 @@ var init_RichBlockEditor = __esm({
27502
27524
  className
27503
27525
  }) => {
27504
27526
  const [blocks, setBlocks] = React121.useState(
27505
- () => initialBlocks ?? [createBlock("paragraph")]
27527
+ () => normalizeBlocks(initialBlocks)
27506
27528
  );
27507
27529
  const onChangeRef = React121.useRef(onChange);
27508
27530
  React121.useEffect(() => {
@@ -26850,6 +26850,16 @@ function nextBlockId(prefix = "blk") {
26850
26850
  const random = Math.random().toString(36).slice(2, 8);
26851
26851
  return `${prefix}-${Date.now().toString(36)}-${_idSeq}-${random}`;
26852
26852
  }
26853
+ function normalizeBlocks(raw) {
26854
+ if (!raw || raw.length === 0) return [createBlock("paragraph")];
26855
+ return raw.map((row) => {
26856
+ const r = row;
26857
+ const rawType = r.type;
26858
+ const type = typeof rawType === "string" && BLOCK_TYPES.has(rawType) ? rawType : "paragraph";
26859
+ const id = typeof r.id === "string" && r.id ? r.id : nextBlockId(type);
26860
+ return { ...r, id, type };
26861
+ });
26862
+ }
26853
26863
  function createBlock(type) {
26854
26864
  switch (type) {
26855
26865
  case "bullet-list":
@@ -27400,7 +27410,7 @@ function BlockRow({
27400
27410
  }
27401
27411
  );
27402
27412
  }
27403
- var TOOLBAR_ENTRIES, BLOCK_TYPE_LABEL, CHANGEABLE_TYPES, _idSeq, RichBlockEditor;
27413
+ var TOOLBAR_ENTRIES, BLOCK_TYPE_LABEL, CHANGEABLE_TYPES, _idSeq, BLOCK_TYPES, RichBlockEditor;
27404
27414
  var init_RichBlockEditor = __esm({
27405
27415
  "components/molecules/RichBlockEditor.tsx"() {
27406
27416
  "use client";
@@ -27447,6 +27457,18 @@ var init_RichBlockEditor = __esm({
27447
27457
  "code"
27448
27458
  ];
27449
27459
  _idSeq = 0;
27460
+ BLOCK_TYPES = /* @__PURE__ */ new Set([
27461
+ "paragraph",
27462
+ "heading-1",
27463
+ "heading-2",
27464
+ "heading-3",
27465
+ "bullet-list",
27466
+ "numbered-list",
27467
+ "quote",
27468
+ "code",
27469
+ "divider",
27470
+ "image"
27471
+ ]);
27450
27472
  RichBlockEditor = ({
27451
27473
  initialBlocks,
27452
27474
  onChange,
@@ -27457,7 +27479,7 @@ var init_RichBlockEditor = __esm({
27457
27479
  className
27458
27480
  }) => {
27459
27481
  const [blocks, setBlocks] = useState(
27460
- () => initialBlocks ?? [createBlock("paragraph")]
27482
+ () => normalizeBlocks(initialBlocks)
27461
27483
  );
27462
27484
  const onChangeRef = useRef(onChange);
27463
27485
  useEffect(() => {
@@ -8,7 +8,7 @@
8
8
  * scope for the Phase 10 scaffold.
9
9
  */
10
10
  import React from "react";
11
- import type { EventEmit, EventPayloadValue } from '@almadar/core';
11
+ import type { EntityRow, EventEmit, EventPayloadValue } from '@almadar/core';
12
12
  export type BlockType = "paragraph" | "heading-1" | "heading-2" | "heading-3" | "bullet-list" | "numbered-list" | "quote" | "code" | "divider" | "image";
13
13
  export interface RichBlock {
14
14
  id: string;
@@ -19,7 +19,14 @@ export interface RichBlock {
19
19
  [key: string]: EventPayloadValue;
20
20
  }
21
21
  export interface RichBlockEditorProps {
22
- initialBlocks?: RichBlock[];
22
+ /**
23
+ * Initial block payload. Accepts strongly-typed RichBlock[] from native
24
+ * callers and the wider EntityRow[] shape that orb-bound traits emit
25
+ * (orb `[object]` lowers to `Record<string, FieldValue | undefined>[]`,
26
+ * which is structurally EntityRow[]). Items missing id/type are normalized
27
+ * into paragraph blocks at mount.
28
+ */
29
+ initialBlocks?: readonly RichBlock[] | readonly EntityRow[];
23
30
  onChange?: (blocks: RichBlock[]) => void;
24
31
  changeEvent?: EventEmit<{
25
32
  blocks: RichBlock[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "4.39.0",
3
+ "version": "4.39.1",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [