@almadar/ui 5.146.2 → 5.146.3

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.
@@ -55863,7 +55863,9 @@ function FlowCanvasInner({
55863
55863
  behaviorEntries,
55864
55864
  behaviorWires,
55865
55865
  userType = "builder",
55866
- themeManifest
55866
+ themeManifest,
55867
+ nodePositions,
55868
+ onPositionsChange
55867
55869
  }) {
55868
55870
  const { t } = hooks.useTranslate();
55869
55871
  const NODE_TYPES2 = React94.useMemo(() => ({
@@ -55950,9 +55952,15 @@ function FlowCanvasInner({
55950
55952
  const [nodes, setNodes, onNodesChange] = react.useNodesState(activeNodes);
55951
55953
  const [edges, setEdges, onEdgesChange] = react.useEdgesState(activeEdges);
55952
55954
  const reactFlow = react.useReactFlow();
55955
+ const savedPositionsRef = React94__namespace.default.useRef(nodePositions);
55956
+ savedPositionsRef.current = nodePositions;
55957
+ const nodesRef = React94__namespace.default.useRef(nodes);
55958
+ nodesRef.current = nodes;
55953
55959
  React94.useEffect(() => {
55954
55960
  setEdges([]);
55955
- setNodes(activeNodes);
55961
+ const saved = savedPositionsRef.current;
55962
+ const merged = saved ? activeNodes.map((n) => saved[n.id] ? { ...n, position: saved[n.id] } : n) : activeNodes;
55963
+ setNodes(merged);
55956
55964
  setEdges(activeEdges);
55957
55965
  requestAnimationFrame(() => {
55958
55966
  reactFlow.fitView({ duration: 300, padding: 0.25 });
@@ -56102,6 +56110,14 @@ function FlowCanvasInner({
56102
56110
  targetTraitName: tgtData.traitName
56103
56111
  });
56104
56112
  }, [nodes, onEventWire, eventBus]);
56113
+ const handleNodeDragStop = React94.useCallback(() => {
56114
+ if (!onPositionsChange) return;
56115
+ const positions = {};
56116
+ for (const n of nodesRef.current) {
56117
+ positions[n.id] = { x: n.position.x, y: n.position.y };
56118
+ }
56119
+ onPositionsChange(positions);
56120
+ }, [onPositionsChange]);
56105
56121
  const screenSizeKeys = ["mobile", "tablet", "laptop", "wide"];
56106
56122
  const traitCardSelectionValue = React94.useMemo(() => ({
56107
56123
  selectTransition: (sel) => {
@@ -56133,6 +56149,7 @@ function FlowCanvasInner({
56133
56149
  onNodeDoubleClick: handleNodeDoubleClick,
56134
56150
  onNodeClick: handleNodeClick,
56135
56151
  onConnect: handleConnect,
56152
+ onNodeDragStop: handleNodeDragStop,
56136
56153
  minZoom: 0.1,
56137
56154
  maxZoom: 2,
56138
56155
  fitView: true,
@@ -1655,6 +1655,24 @@ interface FlowCanvasProps {
1655
1655
  * originates from the synthesized `__design_system__` schema.
1656
1656
  */
1657
1657
  themeManifest?: ThemeDefinition;
1658
+ /**
1659
+ * Persisted node positions keyed by node id. When the node set changes
1660
+ * (level/schema switch), any id present here overrides the computed layout
1661
+ * position, restoring a user's manual drag arrangement. Node ids are unique
1662
+ * per view level, so a single flat map covers overview + expanded.
1663
+ */
1664
+ nodePositions?: Record<string, {
1665
+ x: number;
1666
+ y: number;
1667
+ }>;
1668
+ /**
1669
+ * Fired on node drag-stop with the full {id → position} map of the current
1670
+ * node set, so the consumer can persist the arrangement across reloads.
1671
+ */
1672
+ onPositionsChange?: (positions: Record<string, {
1673
+ x: number;
1674
+ y: number;
1675
+ }>) => void;
1658
1676
  }
1659
1677
  declare const FlowCanvas: React__default.FC<FlowCanvasProps>;
1660
1678
 
@@ -1655,6 +1655,24 @@ interface FlowCanvasProps {
1655
1655
  * originates from the synthesized `__design_system__` schema.
1656
1656
  */
1657
1657
  themeManifest?: ThemeDefinition;
1658
+ /**
1659
+ * Persisted node positions keyed by node id. When the node set changes
1660
+ * (level/schema switch), any id present here overrides the computed layout
1661
+ * position, restoring a user's manual drag arrangement. Node ids are unique
1662
+ * per view level, so a single flat map covers overview + expanded.
1663
+ */
1664
+ nodePositions?: Record<string, {
1665
+ x: number;
1666
+ y: number;
1667
+ }>;
1668
+ /**
1669
+ * Fired on node drag-stop with the full {id → position} map of the current
1670
+ * node set, so the consumer can persist the arrangement across reloads.
1671
+ */
1672
+ onPositionsChange?: (positions: Record<string, {
1673
+ x: number;
1674
+ y: number;
1675
+ }>) => void;
1658
1676
  }
1659
1677
  declare const FlowCanvas: React__default.FC<FlowCanvasProps>;
1660
1678
 
package/dist/avl/index.js CHANGED
@@ -55787,7 +55787,9 @@ function FlowCanvasInner({
55787
55787
  behaviorEntries,
55788
55788
  behaviorWires,
55789
55789
  userType = "builder",
55790
- themeManifest
55790
+ themeManifest,
55791
+ nodePositions,
55792
+ onPositionsChange
55791
55793
  }) {
55792
55794
  const { t } = useTranslate();
55793
55795
  const NODE_TYPES2 = useMemo(() => ({
@@ -55874,9 +55876,15 @@ function FlowCanvasInner({
55874
55876
  const [nodes, setNodes, onNodesChange] = useNodesState(activeNodes);
55875
55877
  const [edges, setEdges, onEdgesChange] = useEdgesState(activeEdges);
55876
55878
  const reactFlow = useReactFlow();
55879
+ const savedPositionsRef = React94__default.useRef(nodePositions);
55880
+ savedPositionsRef.current = nodePositions;
55881
+ const nodesRef = React94__default.useRef(nodes);
55882
+ nodesRef.current = nodes;
55877
55883
  useEffect(() => {
55878
55884
  setEdges([]);
55879
- setNodes(activeNodes);
55885
+ const saved = savedPositionsRef.current;
55886
+ const merged = saved ? activeNodes.map((n) => saved[n.id] ? { ...n, position: saved[n.id] } : n) : activeNodes;
55887
+ setNodes(merged);
55880
55888
  setEdges(activeEdges);
55881
55889
  requestAnimationFrame(() => {
55882
55890
  reactFlow.fitView({ duration: 300, padding: 0.25 });
@@ -56026,6 +56034,14 @@ function FlowCanvasInner({
56026
56034
  targetTraitName: tgtData.traitName
56027
56035
  });
56028
56036
  }, [nodes, onEventWire, eventBus]);
56037
+ const handleNodeDragStop = useCallback(() => {
56038
+ if (!onPositionsChange) return;
56039
+ const positions = {};
56040
+ for (const n of nodesRef.current) {
56041
+ positions[n.id] = { x: n.position.x, y: n.position.y };
56042
+ }
56043
+ onPositionsChange(positions);
56044
+ }, [onPositionsChange]);
56029
56045
  const screenSizeKeys = ["mobile", "tablet", "laptop", "wide"];
56030
56046
  const traitCardSelectionValue = useMemo(() => ({
56031
56047
  selectTransition: (sel) => {
@@ -56057,6 +56073,7 @@ function FlowCanvasInner({
56057
56073
  onNodeDoubleClick: handleNodeDoubleClick,
56058
56074
  onNodeClick: handleNodeClick,
56059
56075
  onConnect: handleConnect,
56076
+ onNodeDragStop: handleNodeDragStop,
56060
56077
  minZoom: 0.1,
56061
56078
  maxZoom: 2,
56062
56079
  fitView: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "5.146.2",
3
+ "version": "5.146.3",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [