react-zeugma 6.9.12 → 7.0.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.
@@ -20,7 +20,6 @@ interface PaneNode {
20
20
  tabIds: string[];
21
21
  activeTabId: string;
22
22
  locked?: boolean;
23
- tabsMetadata?: Record<string, Record<string, unknown>>;
24
23
  }
25
24
  type TreeNode = SplitNode | PaneNode;
26
25
  interface TabDetails {
@@ -53,6 +52,12 @@ interface UseZeugmaOptions {
53
52
  layout?: TreeNode | null;
54
53
  /** Callback triggered when the layout changes via drag-and-drop actions, splits, moves, or resizes. */
55
54
  onChange?: (newLayout: TreeNode | null) => void;
55
+ /** Initial metadata map for all tabs/widgets in uncontrolled mode. */
56
+ initialMetadata?: Record<string, Record<string, unknown>>;
57
+ /** Controlled metadata map for all tabs/widgets. */
58
+ metadata?: Record<string, Record<string, unknown>>;
59
+ /** Callback triggered when tab/widget metadata changes. */
60
+ onMetadataChange?: (metadata: Record<string, Record<string, unknown>>) => void;
56
61
  /** The ID of the pane that is currently taking up the full dashboard area. Null if no pane is fullscreen. */
57
62
  fullscreenPaneId?: string | null;
58
63
  /** Callback triggered when a pane is toggled to/from fullscreen mode. Passes the active fullscreen paneId or null. */
@@ -116,6 +121,16 @@ interface ZeugmaQueries {
116
121
  /** Get the metadata of the active tab in a specific pane by the pane ID. */
117
122
  getActiveTabMetadata: (paneId: string) => Record<string, unknown> | undefined;
118
123
  }
124
+ interface MetadataStore {
125
+ get: (tabId: string) => Record<string, unknown> | undefined;
126
+ getAll: () => Record<string, Record<string, unknown>>;
127
+ set: (tabId: string, metadata: Record<string, unknown> | undefined) => void;
128
+ update: (tabId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined) => void;
129
+ remove: (tabId: string) => void;
130
+ setAll: (newMap: Record<string, Record<string, unknown>> | undefined) => void;
131
+ subscribe: (tabId: string, listener: () => void) => () => void;
132
+ subscribeAll: (listener: () => void) => () => void;
133
+ }
119
134
  interface ZeugmaController extends ZeugmaState, ZeugmaStateSetters, ZeugmaActions, ZeugmaQueries {
120
135
  }
121
136
  interface ZeugmaClassNames {
@@ -229,8 +244,10 @@ interface BaseZeugmaProps {
229
244
  interface ZeugmaPersistOptions {
230
245
  /** Whether to enable persistence. Defaults to true if the object is provided. */
231
246
  enabled?: boolean;
232
- /** The key used for localStorage persistence. Defaults to 'zeugma-layout'. */
247
+ /** The key used for layout localStorage persistence. Defaults to 'zeugma-layout'. */
233
248
  key?: string;
249
+ /** The key used for metadata localStorage persistence. Defaults to `${key}-metadata`. */
250
+ metadataKey?: string;
234
251
  }
235
252
  type ZeugmaProps = (BaseZeugmaProps & {
236
253
  children?: never;
@@ -242,4 +259,4 @@ type ZeugmaProps = (BaseZeugmaProps & {
242
259
  renderPane?: never;
243
260
  });
244
261
 
245
- export type { DragOverlayActiveItem as D, PaneNode as P, RenderTabProps as R, SplitDirection as S, TreeNode as T, UseZeugmaOptions as U, ZeugmaController as Z, ZeugmaProps as a, SplitNode as b, TabDetails as c, ZeugmaClassNames as d };
262
+ export type { DragOverlayActiveItem as D, MetadataStore as M, PaneNode as P, RenderTabProps as R, SplitDirection as S, TreeNode as T, UseZeugmaOptions as U, ZeugmaController as Z, ZeugmaProps as a, SplitNode as b, TabDetails as c, ZeugmaClassNames as d };
@@ -20,7 +20,6 @@ interface PaneNode {
20
20
  tabIds: string[];
21
21
  activeTabId: string;
22
22
  locked?: boolean;
23
- tabsMetadata?: Record<string, Record<string, unknown>>;
24
23
  }
25
24
  type TreeNode = SplitNode | PaneNode;
26
25
  interface TabDetails {
@@ -53,6 +52,12 @@ interface UseZeugmaOptions {
53
52
  layout?: TreeNode | null;
54
53
  /** Callback triggered when the layout changes via drag-and-drop actions, splits, moves, or resizes. */
55
54
  onChange?: (newLayout: TreeNode | null) => void;
55
+ /** Initial metadata map for all tabs/widgets in uncontrolled mode. */
56
+ initialMetadata?: Record<string, Record<string, unknown>>;
57
+ /** Controlled metadata map for all tabs/widgets. */
58
+ metadata?: Record<string, Record<string, unknown>>;
59
+ /** Callback triggered when tab/widget metadata changes. */
60
+ onMetadataChange?: (metadata: Record<string, Record<string, unknown>>) => void;
56
61
  /** The ID of the pane that is currently taking up the full dashboard area. Null if no pane is fullscreen. */
57
62
  fullscreenPaneId?: string | null;
58
63
  /** Callback triggered when a pane is toggled to/from fullscreen mode. Passes the active fullscreen paneId or null. */
@@ -116,6 +121,16 @@ interface ZeugmaQueries {
116
121
  /** Get the metadata of the active tab in a specific pane by the pane ID. */
117
122
  getActiveTabMetadata: (paneId: string) => Record<string, unknown> | undefined;
118
123
  }
124
+ interface MetadataStore {
125
+ get: (tabId: string) => Record<string, unknown> | undefined;
126
+ getAll: () => Record<string, Record<string, unknown>>;
127
+ set: (tabId: string, metadata: Record<string, unknown> | undefined) => void;
128
+ update: (tabId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined) => void;
129
+ remove: (tabId: string) => void;
130
+ setAll: (newMap: Record<string, Record<string, unknown>> | undefined) => void;
131
+ subscribe: (tabId: string, listener: () => void) => () => void;
132
+ subscribeAll: (listener: () => void) => () => void;
133
+ }
119
134
  interface ZeugmaController extends ZeugmaState, ZeugmaStateSetters, ZeugmaActions, ZeugmaQueries {
120
135
  }
121
136
  interface ZeugmaClassNames {
@@ -229,8 +244,10 @@ interface BaseZeugmaProps {
229
244
  interface ZeugmaPersistOptions {
230
245
  /** Whether to enable persistence. Defaults to true if the object is provided. */
231
246
  enabled?: boolean;
232
- /** The key used for localStorage persistence. Defaults to 'zeugma-layout'. */
247
+ /** The key used for layout localStorage persistence. Defaults to 'zeugma-layout'. */
233
248
  key?: string;
249
+ /** The key used for metadata localStorage persistence. Defaults to `${key}-metadata`. */
250
+ metadataKey?: string;
234
251
  }
235
252
  type ZeugmaProps = (BaseZeugmaProps & {
236
253
  children?: never;
@@ -242,4 +259,4 @@ type ZeugmaProps = (BaseZeugmaProps & {
242
259
  renderPane?: never;
243
260
  });
244
261
 
245
- export type { DragOverlayActiveItem as D, PaneNode as P, RenderTabProps as R, SplitDirection as S, TreeNode as T, UseZeugmaOptions as U, ZeugmaController as Z, ZeugmaProps as a, SplitNode as b, TabDetails as c, ZeugmaClassNames as d };
262
+ export type { DragOverlayActiveItem as D, MetadataStore as M, PaneNode as P, RenderTabProps as R, SplitDirection as S, TreeNode as T, UseZeugmaOptions as U, ZeugmaController as Z, ZeugmaProps as a, SplitNode as b, TabDetails as c, ZeugmaClassNames as d };
package/dist/utils.cjs CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';function M(){return "pane-"+Math.random().toString(36).substring(2,11)}function x(n,t){if(n===null)return null;if(n.type==="pane")return n.id===t?null:n;let e=x(n.first,t),i=x(n.second,t);return e===null?i:i===null?e:{...n,first:e,second:i}}function P(n,t){if(n===null)return null;if(n.type==="pane"){if(n.tabIds.includes(t)){let s=n.tabIds.filter(o=>o!==t);if(s.length===0)return null;let l=n.activeTabId;n.activeTabId===t&&(l=s[0]);let u={...n.tabsMetadata};return delete u[t],{...n,tabIds:s,activeTabId:l,tabsMetadata:Object.keys(u).length>0?u:void 0}}return n}let e=P(n.first,t),i=P(n.second,t);return e===null?i:i===null?e:{...n,first:e,second:i}}function v(n,t,e,i,s){if(n===null)return typeof s=="string"?{type:"pane",id:M(),tabIds:[s],activeTabId:s}:s;if(n.type==="pane"){if(n.id===t){let l=typeof s=="string"?{type:"pane",id:M(),tabIds:[s],activeTabId:s}:s,u=i==="left"||i==="top";return {type:"split",direction:e,first:u?l:n,second:u?n:l,splitPercentage:50}}return n}return {...n,first:v(n.first,t,e,i,s)||n.first,second:v(n.second,t,e,i,s)||n.second}}function D(n,t){if(n===null)return t;function e(i,s){return i.type==="pane"?{type:"split",direction:s==="row"?"column":"row",splitPercentage:50,first:i,second:t}:{...i,second:e(i.second,i.direction)}}return e(n,null)}function h(n,t,e,i){if(n===null)return {type:"pane",id:M(),tabIds:[e],activeTabId:e,tabsMetadata:i?{[e]:i}:void 0};let s=t?y(n,t):null;if(s&&s.type==="pane"){let o=function(r){if(r.type==="pane"&&r.id===t){let f=[...r.tabIds];f.includes(e)||f.push(e);let a=r.tabsMetadata;return i&&(a={...r.tabsMetadata,[e]:i}),{...r,tabIds:f,activeTabId:e,tabsMetadata:a}}return r.type==="split"?{...r,first:o(r.first),second:o(r.second)}:r};return o(n)}let l={type:"pane",id:M(),tabIds:[e],activeTabId:e,tabsMetadata:i?{[e]:i}:void 0};return D(n,l)}function w(n,t,e){return n===null?null:n===t?{...n,splitPercentage:e}:n.type==="split"?{...n,first:w(n.first,t,e)||n.first,second:w(n.second,t,e)||n.second}:n}function y(n,t){return n===null?null:n.type==="pane"?n.id===t?n:null:n.type==="split"?y(n.first,t)??y(n.second,t):null}function N(n,t){return n===null?null:n.type==="pane"?n.tabIds.includes(t)?n:null:n.type==="split"?N(n.first,t)??N(n.second,t):null}function j(n,t){let e=N(n,t);if(!e)return null;let i=e.tabIds.indexOf(t);return {id:t,paneId:e.id,isActive:e.activeTabId===t,index:i,metadata:e.tabsMetadata?.[t]}}function R(n,t){return N(n,t)?.tabsMetadata?.[t]}function $(n,t){let e=y(n,t);return e?.tabsMetadata?.[e.activeTabId]}function S(n,t,e){if(n===null)return null;if(n.type==="pane"){if(n.tabIds.includes(t)){let i=n.tabsMetadata||{},s=i[t],l=e(s),u={...i};return l===void 0?delete u[t]:u[t]=l,{...n,tabsMetadata:Object.keys(u).length>0?u:void 0}}return n}return n.type==="split"?{...n,first:S(n.first,t,e)??n.first,second:S(n.second,t,e)??n.second}:n}function O(n,t,e){if(n===null)return null;if(n.type==="pane"){if(n.id===t){if(e===false){let{locked:i,...s}=n;return s}return {...n,locked:e}}return n}return n.type==="split"?{...n,first:O(n.first,t,e)??n.first,second:O(n.second,t,e)??n.second}:n}function C(n,t,e){return n===null?null:n.type==="pane"?n.id===t?n.activeTabId===e?n:{...n,activeTabId:e}:n:n.type==="split"?{...n,first:C(n.first,t,e)??n.first,second:C(n.second,t,e)??n.second}:n}function B(n,t,e){if(n===null)return null;let s=N(n,t)?.tabsMetadata?.[t],l=P(n,t);if(l===null)return {type:"pane",id:M(),tabIds:[t],activeTabId:t,tabsMetadata:s?{[t]:s}:void 0};function u(o){if(o.type==="pane"){if(o.id===e){let r=[...o.tabIds];r.includes(t)||r.push(t);let f={...o.tabsMetadata};return s&&(f[t]=s),{...o,tabIds:r,activeTabId:t,tabsMetadata:Object.keys(f).length>0?f:void 0}}return o}return o.type==="split"?{...o,first:u(o.first),second:u(o.second)}:o}return u(l)}function L(n,t,e){if(n===null)return null;if(t===e)return n;let i=N(n,t),s=N(n,e);if(!i||!s)return n;let l=i.id,u=s.id,o=i.tabsMetadata?.[t],r=s.tabsMetadata?.[e];function f(a){if(a.type==="pane"){let T=false,c=[...a.tabIds],p=a.activeTabId,d=a.tabsMetadata?{...a.tabsMetadata}:{};if(l===u){if(a.id===l){let b=c.indexOf(t),k=c.indexOf(e);b!==-1&&k!==-1&&(c[b]=e,c[k]=t),p=t,T=true;}}else a.id===l&&(c=c.map(b=>b===t?e:b),p===t&&(p=e),delete d[t],r&&(d[e]=r),T=true),a.id===u&&(c=c.map(b=>b===e?t:b),p===e&&(p=t),delete d[e],o&&(d[t]=o),T=true);return T?{...a,tabIds:c,activeTabId:p,tabsMetadata:Object.keys(d).length>0?d:void 0}:a}return a.type==="split"?{...a,first:f(a.first),second:f(a.second)}:a}return f(n)}function H(n,t,e,i="before"){if(n===null)return null;if(t===e)return n;if(i==="center")return L(n,t,e);let l=N(n,t)?.tabsMetadata?.[t],u=P(n,t);if(u===null)return {type:"pane",id:M(),tabIds:[t],activeTabId:t,tabsMetadata:l?{[t]:l}:void 0};function o(r){if(r.type==="pane"){if(r.tabIds.includes(e)){let a=[...r.tabIds].filter(p=>p!==t),T=a.indexOf(e);T<0&&(T=0),i==="after"&&(T+=1),a.splice(T,0,t);let c={...r.tabsMetadata};return l&&(c[t]=l),{...r,tabIds:a,activeTabId:t,tabsMetadata:Object.keys(c).length>0?c:void 0}}return r}return r.type==="split"?{...r,first:o(r.first),second:o(r.second)}:r}return o(u)}function m(n,t=0,e=0,i=100,s=100,l="root"){if(n===null)return {panes:[],splitters:[]};if(n.type==="pane")return {panes:[{paneId:n.id,left:t,top:e,width:i,height:s,node:n}],splitters:[]};let{direction:u,splitPercentage:o,first:r,second:f}=n,T={id:`splitter-${l}-${u}`,currentNode:n,direction:u,left:u==="row"?t+i*(o/100):t,top:u==="column"?e+s*(o/100):e,width:u==="row"?0:i,height:u==="column"?0:s,parentLeft:t,parentTop:e,parentWidth:i,parentHeight:s},c={panes:[],splitters:[]},p={panes:[],splitters:[]};if(u==="row"){let d=i*(o/100);c=m(r,t,e,d,s,`${l}-L`),p=m(f,t+d,e,i-d,s,`${l}-R`);}else {let d=s*(o/100);c=m(r,t,e,i,d,`${l}-T`),p=m(f,t,e+d,i,s-d,`${l}-B`);}return {panes:[...c.panes,...p.panes],splitters:[T,...c.splitters,...p.splitters]}}function F(n,t,e,i="before"){if(n===null)return null;let s=y(n,t);if(!s)return n;let l=s.tabIds,u=s.activeTabId,o=s.tabsMetadata||{},r=x(n,t);if(r===null)return s;function f(a){if(a.type==="pane"){if(a.tabIds.includes(e)){let c=[...a.tabIds].filter(b=>!l.includes(b)),p=c.indexOf(e);p<0&&(p=0),i==="after"&&(p+=1),c.splice(p,0,...l);let d={...a.tabsMetadata};for(let b of l)o[b]&&(d[b]=o[b]);return {...a,tabIds:c,activeTabId:u,tabsMetadata:Object.keys(d).length>0?d:void 0}}return a}return a.type==="split"?{...a,first:f(a.first),second:f(a.second)}:a}return f(r)}function W(n,t,e,i){if(!((t==="tab"||t==="pane")&&e&&n.includes(e))||!i)return -1;let u=n.indexOf(e);return i==="before"?u:u+1}exports.addTab=h;exports.calculateTabDropIndex=W;exports.computeLayout=m;exports.findPaneById=y;exports.findPaneContainingTab=N;exports.findTabById=j;exports.generateUniqueId=M;exports.getActiveTabMetadata=$;exports.getTabMetadata=R;exports.insertLeaf=D;exports.mergeTab=B;exports.movePaneTabs=F;exports.moveTab=H;exports.removePane=x;exports.removeTab=P;exports.selectTab=C;exports.splitPane=v;exports.swapTabs=L;exports.updateMetadata=S;exports.updatePaneLock=O;exports.updateSplitPercentage=w;//# sourceMappingURL=utils.cjs.map
1
+ 'use strict';function b(){return "pane-"+Math.random().toString(36).substring(2,11)}function x(n,e){if(n===null)return null;if(n.type==="pane")return n.id===e?null:n;let t=x(n.first,e),r=x(n.second,e);return t===null?r:r===null?t:{...n,first:t,second:r}}function m(n,e){if(n===null)return null;if(n.type==="pane"){if(n.tabIds.includes(e)){let i=n.tabIds.filter(s=>s!==e);if(i.length===0)return null;let u=n.activeTabId;return n.activeTabId===e&&(u=i[0]),{...n,tabIds:i,activeTabId:u}}return n}let t=m(n.first,e),r=m(n.second,e);return t===null?r:r===null?t:{...n,first:t,second:r}}function v(n,e,t,r,i){if(n===null)return typeof i=="string"?{type:"pane",id:b(),tabIds:[i],activeTabId:i}:i;if(n.type==="pane"){if(n.id===e){let u=typeof i=="string"?{type:"pane",id:b(),tabIds:[i],activeTabId:i}:i,s=r==="left"||r==="top";return {type:"split",direction:t,first:s?u:n,second:s?n:u,splitPercentage:50}}return n}return {...n,first:v(n.first,e,t,r,i)||n.first,second:v(n.second,e,t,r,i)||n.second}}function C(n,e){if(n===null)return e;function t(r,i){return r.type==="pane"?{type:"split",direction:i==="row"?"column":"row",splitPercentage:50,first:r,second:e}:{...r,second:t(r.second,r.direction)}}return t(n,null)}function D(n,e,t){if(n===null)return {type:"pane",id:b(),tabIds:[t],activeTabId:t};let r=e?P(n,e):null;if(r&&r.type==="pane"){let s=function(f){if(f.type==="pane"&&f.id===e){let l=[...f.tabIds];return l.includes(t)||l.push(t),{...f,tabIds:l,activeTabId:t}}return f.type==="split"?{...f,first:s(f.first),second:s(f.second)}:f};return s(n)}let i={type:"pane",id:b(),tabIds:[t],activeTabId:t};return C(n,i)}function w(n,e,t){return n===null?null:n===e?{...n,splitPercentage:t}:n.type==="split"?{...n,first:w(n.first,e,t)||n.first,second:w(n.second,e,t)||n.second}:n}function P(n,e){return n===null?null:n.type==="pane"?n.id===e?n:null:n.type==="split"?P(n.first,e)??P(n.second,e):null}function N(n,e){return n===null?null:n.type==="pane"?n.tabIds.includes(e)?n:null:n.type==="split"?N(n.first,e)??N(n.second,e):null}function j(n,e){let t=N(n,e);if(!t)return null;let r=t.tabIds.indexOf(e);return {id:e,paneId:t.id,isActive:t.activeTabId===e,index:r,metadata:void 0}}function S(n,e,t){if(n===null)return null;if(n.type==="pane"){if(n.id===e){if(t===false){let{locked:r,...i}=n;return i}return {...n,locked:t}}return n}return n.type==="split"?{...n,first:S(n.first,e,t)??n.first,second:S(n.second,e,t)??n.second}:n}function O(n,e,t){return n===null?null:n.type==="pane"?n.id===e?n.activeTabId===t?n:{...n,activeTabId:t}:n:n.type==="split"?{...n,first:O(n.first,e,t)??n.first,second:O(n.second,e,t)??n.second}:n}function I(n,e,t){if(n===null)return null;let r=m(n,e);if(r===null)return {type:"pane",id:b(),tabIds:[e],activeTabId:e};function i(u){if(u.type==="pane"){if(u.id===t){let s=[...u.tabIds];return s.includes(e)||s.push(e),{...u,tabIds:s,activeTabId:e}}return u}return u.type==="split"?{...u,first:i(u.first),second:i(u.second)}:u}return i(r)}function L(n,e,t){if(n===null)return null;if(e===t)return n;let r=N(n,e),i=N(n,t);if(!r||!i)return n;let u=r.id,s=i.id;function f(l){if(l.type==="pane"){let o=false,a=[...l.tabIds],p=l.activeTabId;if(u===s){if(l.id===u){let c=a.indexOf(e),d=a.indexOf(t);c!==-1&&d!==-1&&(a[c]=t,a[d]=e),p=e,o=true;}}else l.id===u&&(a=a.map(c=>c===e?t:c),p===e&&(p=t),o=true),l.id===s&&(a=a.map(c=>c===t?e:c),p===t&&(p=e),o=true);return o?{...l,tabIds:a,activeTabId:p}:l}return l.type==="split"?{...l,first:f(l.first),second:f(l.second)}:l}return f(n)}function h(n,e,t,r="before"){if(n===null)return null;if(e===t)return n;if(r==="center")return L(n,e,t);let i=m(n,e);if(i===null)return {type:"pane",id:b(),tabIds:[e],activeTabId:e};function u(s){if(s.type==="pane"){if(s.tabIds.includes(t)){let l=[...s.tabIds].filter(a=>a!==e),o=l.indexOf(t);return o<0&&(o=0),r==="after"&&(o+=1),l.splice(o,0,e),{...s,tabIds:l,activeTabId:e}}return s}return s.type==="split"?{...s,first:u(s.first),second:u(s.second)}:s}return u(i)}function y(n,e=0,t=0,r=100,i=100,u="root"){if(n===null)return {panes:[],splitters:[]};if(n.type==="pane")return {panes:[{paneId:n.id,left:e,top:t,width:r,height:i,node:n}],splitters:[]};let{direction:s,splitPercentage:f,first:l,second:o}=n,p={id:`splitter-${u}-${s}`,currentNode:n,direction:s,left:s==="row"?e+r*(f/100):e,top:s==="column"?t+i*(f/100):t,width:s==="row"?0:r,height:s==="column"?0:i,parentLeft:e,parentTop:t,parentWidth:r,parentHeight:i},c={panes:[],splitters:[]},d={panes:[],splitters:[]};if(s==="row"){let T=r*(f/100);c=y(l,e,t,T,i,`${u}-L`),d=y(o,e+T,t,r-T,i,`${u}-R`);}else {let T=i*(f/100);c=y(l,e,t,r,T,`${u}-T`),d=y(o,e,t+T,r,i-T,`${u}-B`);}return {panes:[...c.panes,...d.panes],splitters:[p,...c.splitters,...d.splitters]}}function R(n,e,t,r="before"){if(n===null)return null;let i=P(n,e);if(!i)return n;let u=i.tabIds,s=i.activeTabId,f=x(n,e);if(f===null)return i;function l(o){if(o.type==="pane"){if(o.tabIds.includes(t)){let p=[...o.tabIds].filter(d=>!u.includes(d)),c=p.indexOf(t);return c<0&&(c=0),r==="after"&&(c+=1),p.splice(c,0,...u),{...o,tabIds:p,activeTabId:s}}return o}return o.type==="split"?{...o,first:l(o.first),second:l(o.second)}:o}return l(f)}function q(n,e,t,r){if(!((e==="tab"||e==="pane")&&t&&n.includes(t))||!r)return -1;let s=n.indexOf(t);return r==="before"?s:s+1}function g(n,e){if(n===e)return true;if(!n||!e)return false;let t=Object.keys(n),r=Object.keys(e);if(t.length!==r.length)return false;for(let i of t){if(!Object.prototype.hasOwnProperty.call(e,i))return false;let u=n[i],s=e[i];if(typeof u=="object"&&u!==null&&typeof s=="object"&&s!==null){if(!g(u,s))return false}else if(u!==s)return false}return true}function B(n,e){if(n===e)return true;if(!n||!e)return false;let t=Object.keys(n),r=Object.keys(e);if(t.length!==r.length)return false;for(let i of t)if(!Object.prototype.hasOwnProperty.call(e,i)||!g(n[i],e[i]))return false;return true}function k(n,e){if(n===e)return true;if(!n||!e||n.type!==e.type)return false;if(n.type==="split"){let t=e;return n.direction===t.direction&&n.splitPercentage===t.splitPercentage&&k(n.first,t.first)&&k(n.second,t.second)}else {let t=e;if(n.id!==t.id||n.activeTabId!==t.activeTabId||n.locked!==t.locked||n.tabIds.length!==t.tabIds.length)return false;for(let r=0;r<n.tabIds.length;r++)if(n.tabIds[r]!==t.tabIds[r])return false;return true}}exports.addTab=D;exports.areLayoutsEqual=k;exports.areMetadataEqual=B;exports.areObjectsEqual=g;exports.calculateTabDropIndex=q;exports.computeLayout=y;exports.findPaneById=P;exports.findPaneContainingTab=N;exports.findTabById=j;exports.generateUniqueId=b;exports.insertLeaf=C;exports.mergeTab=I;exports.movePaneTabs=R;exports.moveTab=h;exports.removePane=x;exports.removeTab=m;exports.selectTab=O;exports.splitPane=v;exports.swapTabs=L;exports.updatePaneLock=S;exports.updateSplitPercentage=w;//# sourceMappingURL=utils.cjs.map
2
2
  //# sourceMappingURL=utils.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shared/lib/tree/tree-helpers.ts"],"names":["generateUniqueId","removePane","tree","paneId","newFirst","newSecond","removeTab","tabId","newTabs","t","newActive","newTabsMetadata","splitPane","targetId","direction","splitType","paneToAdd","addedNode","isFirst","insertLeaf","leafNode","insert","node","parentDirection","addTab","targetPaneId","metadata","targetPane","findPaneById","appendTabToTarget","newPane","updateSplitPercentage","target","newPercentage","findPaneContainingTab","findTabById","pane","index","getTabMetadata","getActiveTabMetadata","updateMetadata","id","updater","currentTabsMetadata","currentTabMeta","newTabMeta","updatePaneLock","locked","_","rest","selectTab","mergeTab","draggedTabId","sourceMetadata","cleanTree","swapTabs","targetTabId","sourcePane","sourcePaneId","targetMetadata","swap","changed","newTabIds","newActiveTabId","dragIdx","targetIdx","moveTab","position","filteredTabs","insertIndex","computeLayout","left","top","width","height","path","splitPercentage","first","second","currentSplitter","firstLayout","secondLayout","firstWidth","firstHeight","movePaneTabs","draggedPaneId","draggedTabIds","draggedActiveTabId","draggedTabsMetadata","tid","calculateTabDropIndex","tabIds","activeType","overTabId","overTabPosition"],"mappings":"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","file":"utils.cjs","sourcesContent":["import { TreeNode, SplitNode, SplitDirection, PaneNode, TabDetails } from '../../model'\n\nexport function generateUniqueId(): string {\n return 'pane-' + Math.random().toString(36).substring(2, 11)\n}\n\n/**\n * Tree Helper: Remove a pane container and consolidate the tree structure.\n */\nexport function removePane(tree: TreeNode | null, paneId: string): TreeNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n if (tree.id === paneId) return null\n return tree\n }\n const newFirst = removePane(tree.first, paneId)\n const newSecond = removePane(tree.second, paneId)\n if (newFirst === null) return newSecond\n if (newSecond === null) return newFirst\n return { ...tree, first: newFirst, second: newSecond }\n}\n\n/**\n * Tree Helper: Remove a tab from a pane and consolidate the tree structure if no tabs remain.\n */\nexport function removeTab(tree: TreeNode | null, tabId: string): TreeNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n if (tree.tabIds.includes(tabId)) {\n const newTabs = tree.tabIds.filter((t) => t !== tabId)\n if (newTabs.length === 0) return null\n let newActive = tree.activeTabId\n if (tree.activeTabId === tabId) {\n newActive = newTabs[0]\n }\n const newTabsMetadata = { ...tree.tabsMetadata }\n delete newTabsMetadata[tabId]\n return {\n ...tree,\n tabIds: newTabs,\n activeTabId: newActive,\n tabsMetadata: Object.keys(newTabsMetadata).length > 0 ? newTabsMetadata : undefined,\n }\n }\n return tree\n }\n const newFirst = removeTab(tree.first, tabId)\n const newSecond = removeTab(tree.second, tabId)\n if (newFirst === null) return newSecond\n if (newSecond === null) return newFirst\n return { ...tree, first: newFirst, second: newSecond }\n}\n\n/**\n * Tree Helper: Insert a pane or widget by splitting an existing target node.\n */\nexport function splitPane(\n tree: TreeNode | null,\n targetId: string,\n direction: SplitDirection,\n splitType: 'left' | 'right' | 'top' | 'bottom',\n paneToAdd: string | PaneNode,\n): TreeNode | null {\n if (tree === null) {\n if (typeof paneToAdd === 'string') {\n return { type: 'pane', id: generateUniqueId(), tabIds: [paneToAdd], activeTabId: paneToAdd }\n }\n return paneToAdd\n }\n if (tree.type === 'pane') {\n if (tree.id === targetId) {\n const addedNode: PaneNode =\n typeof paneToAdd === 'string'\n ? { type: 'pane', id: generateUniqueId(), tabIds: [paneToAdd], activeTabId: paneToAdd }\n : paneToAdd\n const isFirst = splitType === 'left' || splitType === 'top'\n return {\n type: 'split',\n direction,\n first: isFirst ? addedNode : tree,\n second: isFirst ? tree : addedNode,\n splitPercentage: 50,\n }\n }\n return tree\n }\n return {\n ...tree,\n first: splitPane(tree.first, targetId, direction, splitType, paneToAdd) || tree.first,\n second: splitPane(tree.second, targetId, direction, splitType, paneToAdd) || tree.second,\n }\n}\n\n/**\n * Helper to insert a leaf node (PaneNode or WidgetNode) into the layout tree.\n */\nexport function insertLeaf(tree: TreeNode | null, leafNode: PaneNode): TreeNode {\n if (tree === null) {\n return leafNode\n }\n\n function insert(node: TreeNode, parentDirection: SplitDirection | null): TreeNode {\n if (node.type === 'pane') {\n const direction: SplitDirection = parentDirection === 'row' ? 'column' : 'row'\n return {\n type: 'split',\n direction,\n splitPercentage: 50,\n first: node,\n second: leafNode,\n }\n }\n\n return {\n ...node,\n second: insert(node.second, node.direction),\n }\n }\n\n return insert(tree, null)\n}\n\n/**\n * Tree Helper: Add a tab into a target pane node, or splits/creates a new pane if no target pane ID is provided.\n */\nexport function addTab(\n tree: TreeNode | null,\n targetPaneId: string | undefined | null,\n tabId: string,\n metadata?: Record<string, unknown>,\n): TreeNode | null {\n if (tree === null) {\n return {\n type: 'pane',\n id: generateUniqueId(),\n tabIds: [tabId],\n activeTabId: tabId,\n tabsMetadata: metadata ? { [tabId]: metadata } : undefined,\n }\n }\n\n const targetPane = targetPaneId ? findPaneById(tree, targetPaneId) : null\n if (targetPane && targetPane.type === 'pane') {\n function appendTabToTarget(node: TreeNode): TreeNode {\n if (node.type === 'pane' && node.id === targetPaneId) {\n const newTabs = [...node.tabIds]\n if (!newTabs.includes(tabId)) {\n newTabs.push(tabId)\n }\n let newTabsMetadata = node.tabsMetadata\n if (metadata) {\n newTabsMetadata = {\n ...node.tabsMetadata,\n [tabId]: metadata,\n }\n }\n return {\n ...node,\n tabIds: newTabs,\n activeTabId: tabId,\n tabsMetadata: newTabsMetadata,\n }\n }\n if (node.type === 'split') {\n return {\n ...node,\n first: appendTabToTarget(node.first),\n second: appendTabToTarget(node.second),\n }\n }\n return node\n }\n return appendTabToTarget(tree)\n }\n\n const newPane: PaneNode = {\n type: 'pane',\n id: generateUniqueId(),\n tabIds: [tabId],\n activeTabId: tabId,\n tabsMetadata: metadata ? { [tabId]: metadata } : undefined,\n }\n return insertLeaf(tree, newPane)\n}\n\n/**\n * Tree Helper: Update split percentage recursively.\n */\nexport function updateSplitPercentage(\n tree: TreeNode | null,\n target: SplitNode,\n newPercentage: number,\n): TreeNode | null {\n if (tree === null) return null\n if (tree === target) {\n return { ...tree, splitPercentage: newPercentage }\n }\n if (tree.type === 'split') {\n return {\n ...tree,\n first: updateSplitPercentage(tree.first, target, newPercentage) || tree.first,\n second: updateSplitPercentage(tree.second, target, newPercentage) || tree.second,\n }\n }\n return tree\n}\n\n/**\n * Find a PaneNode or WidgetNode by its ID.\n */\nexport function findPaneById(tree: TreeNode | null, paneId: string): PaneNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n return tree.id === paneId ? tree : null\n }\n if (tree.type === 'split') {\n return findPaneById(tree.first, paneId) ?? findPaneById(tree.second, paneId)\n }\n return null\n}\n\n/**\n * Find a PaneNode containing the given tab ID.\n */\nexport function findPaneContainingTab(tree: TreeNode | null, tabId: string): PaneNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n return tree.tabIds.includes(tabId) ? tree : null\n }\n if (tree.type === 'split') {\n return findPaneContainingTab(tree.first, tabId) ?? findPaneContainingTab(tree.second, tabId)\n }\n return null\n}\n\n/**\n * Find a PaneNode by its own ID, or by a tab ID it contains.\n */\nexport function findPaneOrContainingTab(tree: TreeNode | null, id: string): PaneNode | null {\n return findPaneById(tree, id) ?? findPaneContainingTab(tree, id)\n}\n\n/**\n * Find the details of a tab by its ID.\n */\nexport function findTabById(tree: TreeNode | null, tabId: string): TabDetails | null {\n const pane = findPaneContainingTab(tree, tabId)\n if (!pane) return null\n const index = pane.tabIds.indexOf(tabId)\n return {\n id: tabId,\n paneId: pane.id,\n isActive: pane.activeTabId === tabId,\n index,\n metadata: pane.tabsMetadata?.[tabId],\n }\n}\n\n/**\n * Get the metadata for a specific tab by its ID.\n */\nexport function getTabMetadata(\n tree: TreeNode | null,\n tabId: string,\n): Record<string, unknown> | undefined {\n const pane = findPaneContainingTab(tree, tabId)\n return pane?.tabsMetadata?.[tabId]\n}\n\n/**\n * Get the metadata of the active item (either tab or pane).\n */\n/**\n * Get the metadata of the active tab in a specific pane.\n */\nexport function getActiveTabMetadata(\n tree: TreeNode | null,\n paneId: string,\n): Record<string, unknown> | undefined {\n const pane = findPaneById(tree, paneId)\n return pane?.tabsMetadata?.[pane.activeTabId]\n}\n\n/**\n * Update metadata on a specific tab or widget node using an updater function.\n */\nexport function updateMetadata(\n tree: TreeNode | null,\n id: string,\n updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined,\n): TreeNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n if (tree.tabIds.includes(id)) {\n const currentTabsMetadata = tree.tabsMetadata || {}\n const currentTabMeta = currentTabsMetadata[id]\n const newTabMeta = updater(currentTabMeta)\n\n const newTabsMetadata = { ...currentTabsMetadata }\n if (newTabMeta === undefined) {\n delete newTabsMetadata[id]\n } else {\n newTabsMetadata[id] = newTabMeta\n }\n\n return {\n ...tree,\n tabsMetadata: Object.keys(newTabsMetadata).length > 0 ? newTabsMetadata : undefined,\n }\n }\n return tree\n }\n if (tree.type === 'split') {\n return {\n ...tree,\n first: updateMetadata(tree.first, id, updater) ?? tree.first,\n second: updateMetadata(tree.second, id, updater) ?? tree.second,\n }\n }\n return tree\n}\n\n/**\n * Update the locked status on a specific pane or widget node in the layout tree.\n */\nexport function updatePaneLock(\n tree: TreeNode | null,\n paneId: string,\n locked: boolean,\n): TreeNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n if (tree.id === paneId) {\n if (locked === false) {\n const { locked: _, ...rest } = tree\n return rest as PaneNode\n }\n return { ...tree, locked }\n }\n return tree\n }\n if (tree.type === 'split') {\n return {\n ...tree,\n first: updatePaneLock(tree.first, paneId, locked) ?? tree.first,\n second: updatePaneLock(tree.second, paneId, locked) ?? tree.second,\n }\n }\n return tree\n}\n\n/**\n * Tree Helper: Activate a tab within a pane.\n */\nexport function selectTab(tree: TreeNode | null, paneId: string, tabId: string): TreeNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n if (tree.id === paneId) {\n if (tree.activeTabId === tabId) return tree\n return { ...tree, activeTabId: tabId }\n }\n return tree\n }\n if (tree.type === 'split') {\n return {\n ...tree,\n first: selectTab(tree.first, paneId, tabId) ?? tree.first,\n second: selectTab(tree.second, paneId, tabId) ?? tree.second,\n }\n }\n return tree\n}\n\n/**\n * Tree Helper: Merge a tab into a target pane node.\n */\nexport function mergeTab(\n tree: TreeNode | null,\n draggedTabId: string,\n targetPaneId: string,\n): TreeNode | null {\n if (tree === null) return null\n\n const sourcePane = findPaneContainingTab(tree, draggedTabId)\n const sourceMetadata = sourcePane?.tabsMetadata?.[draggedTabId]\n\n const cleanTree = removeTab(tree, draggedTabId)\n if (cleanTree === null) {\n return {\n type: 'pane',\n id: generateUniqueId(),\n tabIds: [draggedTabId],\n activeTabId: draggedTabId,\n tabsMetadata: sourceMetadata ? { [draggedTabId]: sourceMetadata } : undefined,\n }\n }\n\n function insert(node: TreeNode): TreeNode {\n if (node.type === 'pane') {\n if (node.id === targetPaneId) {\n const newTabs = [...node.tabIds]\n if (!newTabs.includes(draggedTabId)) {\n newTabs.push(draggedTabId)\n }\n const newTabsMetadata = { ...node.tabsMetadata }\n if (sourceMetadata) {\n newTabsMetadata[draggedTabId] = sourceMetadata\n }\n return {\n ...node,\n tabIds: newTabs,\n activeTabId: draggedTabId,\n tabsMetadata: Object.keys(newTabsMetadata).length > 0 ? newTabsMetadata : undefined,\n }\n }\n return node\n }\n if (node.type === 'split') {\n return {\n ...node,\n first: insert(node.first),\n second: insert(node.second),\n }\n }\n return node\n }\n\n return insert(cleanTree)\n}\n\nexport function swapTabs(\n tree: TreeNode | null,\n draggedTabId: string,\n targetTabId: string,\n): TreeNode | null {\n if (tree === null) return null\n if (draggedTabId === targetTabId) return tree\n\n const sourcePane = findPaneContainingTab(tree, draggedTabId)\n const targetPane = findPaneContainingTab(tree, targetTabId)\n\n if (!sourcePane || !targetPane) return tree\n\n const sourcePaneId = sourcePane.id\n const targetPaneId = targetPane.id\n const sourceMetadata = sourcePane.tabsMetadata?.[draggedTabId]\n const targetMetadata = targetPane.tabsMetadata?.[targetTabId]\n\n function swap(node: TreeNode): TreeNode {\n if (node.type === 'pane') {\n let changed = false\n let newTabIds = [...node.tabIds]\n let newActiveTabId = node.activeTabId\n const newTabsMetadata = node.tabsMetadata ? { ...node.tabsMetadata } : {}\n\n if (sourcePaneId === targetPaneId) {\n if (node.id === sourcePaneId) {\n const dragIdx = newTabIds.indexOf(draggedTabId)\n const targetIdx = newTabIds.indexOf(targetTabId)\n if (dragIdx !== -1 && targetIdx !== -1) {\n newTabIds[dragIdx] = targetTabId\n newTabIds[targetIdx] = draggedTabId\n }\n newActiveTabId = draggedTabId\n changed = true\n }\n } else {\n if (node.id === sourcePaneId) {\n newTabIds = newTabIds.map((id) => (id === draggedTabId ? targetTabId : id))\n if (newActiveTabId === draggedTabId) {\n newActiveTabId = targetTabId\n }\n delete newTabsMetadata[draggedTabId]\n if (targetMetadata) {\n newTabsMetadata[targetTabId] = targetMetadata\n }\n changed = true\n }\n if (node.id === targetPaneId) {\n newTabIds = newTabIds.map((id) => (id === targetTabId ? draggedTabId : id))\n if (newActiveTabId === targetTabId) {\n newActiveTabId = draggedTabId\n }\n delete newTabsMetadata[targetTabId]\n if (sourceMetadata) {\n newTabsMetadata[draggedTabId] = sourceMetadata\n }\n changed = true\n }\n }\n\n if (changed) {\n return {\n ...node,\n tabIds: newTabIds,\n activeTabId: newActiveTabId,\n tabsMetadata: Object.keys(newTabsMetadata).length > 0 ? newTabsMetadata : undefined,\n }\n }\n return node\n }\n if (node.type === 'split') {\n return {\n ...node,\n first: swap(node.first),\n second: swap(node.second),\n }\n }\n return node\n }\n\n return swap(tree)\n}\n\n/**\n * Tree Helper: Move/reorder a tab inside or to a target pane next to a target tab.\n */\nexport function moveTab(\n tree: TreeNode | null,\n draggedTabId: string,\n targetTabId: string,\n position: 'before' | 'after' | 'center' = 'before',\n): TreeNode | null {\n if (tree === null) return null\n if (draggedTabId === targetTabId) return tree\n\n if (position === 'center') {\n return swapTabs(tree, draggedTabId, targetTabId)\n }\n\n const sourcePane = findPaneContainingTab(tree, draggedTabId)\n const sourceMetadata = sourcePane?.tabsMetadata?.[draggedTabId]\n\n const cleanTree = removeTab(tree, draggedTabId)\n if (cleanTree === null) {\n return {\n type: 'pane',\n id: generateUniqueId(),\n tabIds: [draggedTabId],\n activeTabId: draggedTabId,\n tabsMetadata: sourceMetadata ? { [draggedTabId]: sourceMetadata } : undefined,\n }\n }\n\n function insert(node: TreeNode): TreeNode {\n if (node.type === 'pane') {\n if (node.tabIds.includes(targetTabId)) {\n const newTabs = [...node.tabIds]\n const filteredTabs = newTabs.filter((t) => t !== draggedTabId)\n let insertIndex = filteredTabs.indexOf(targetTabId)\n if (insertIndex < 0) {\n insertIndex = 0\n }\n if (position === 'after') {\n insertIndex += 1\n }\n filteredTabs.splice(insertIndex, 0, draggedTabId)\n\n const newTabsMetadata = { ...node.tabsMetadata }\n if (sourceMetadata) {\n newTabsMetadata[draggedTabId] = sourceMetadata\n }\n return {\n ...node,\n tabIds: filteredTabs,\n activeTabId: draggedTabId,\n tabsMetadata: Object.keys(newTabsMetadata).length > 0 ? newTabsMetadata : undefined,\n }\n }\n return node\n }\n if (node.type === 'split') {\n return {\n ...node,\n first: insert(node.first),\n second: insert(node.second),\n }\n }\n return node\n }\n\n return insert(cleanTree)\n}\n\nexport interface ComputedPane {\n paneId: string\n left: number\n top: number\n width: number\n height: number\n node: PaneNode\n}\n\nexport interface ComputedSplitter {\n id: string\n currentNode: SplitNode\n direction: SplitDirection\n left: number\n top: number\n width: number\n height: number\n parentLeft: number\n parentTop: number\n parentWidth: number\n parentHeight: number\n}\n\nexport function computeLayout(\n node: TreeNode | null,\n left = 0,\n top = 0,\n width = 100,\n height = 100,\n path = 'root',\n): { panes: ComputedPane[]; splitters: ComputedSplitter[] } {\n if (node === null) return { panes: [], splitters: [] }\n if (node.type === 'pane') {\n return {\n panes: [{ paneId: node.id, left, top, width, height, node }],\n splitters: [],\n }\n }\n\n const { direction, splitPercentage, first, second } = node\n const splitterId = `splitter-${path}-${direction}`\n\n const currentSplitter: ComputedSplitter = {\n id: splitterId,\n currentNode: node,\n direction,\n left: direction === 'row' ? left + width * (splitPercentage / 100) : left,\n top: direction === 'column' ? top + height * (splitPercentage / 100) : top,\n width: direction === 'row' ? 0 : width,\n height: direction === 'column' ? 0 : height,\n parentLeft: left,\n parentTop: top,\n parentWidth: width,\n parentHeight: height,\n }\n\n let firstLayout = { panes: [] as ComputedPane[], splitters: [] as ComputedSplitter[] }\n let secondLayout = { panes: [] as ComputedPane[], splitters: [] as ComputedSplitter[] }\n\n if (direction === 'row') {\n const firstWidth = width * (splitPercentage / 100)\n firstLayout = computeLayout(first, left, top, firstWidth, height, `${path}-L`)\n secondLayout = computeLayout(\n second,\n left + firstWidth,\n top,\n width - firstWidth,\n height,\n `${path}-R`,\n )\n } else {\n const firstHeight = height * (splitPercentage / 100)\n firstLayout = computeLayout(first, left, top, width, firstHeight, `${path}-T`)\n secondLayout = computeLayout(\n second,\n left,\n top + firstHeight,\n width,\n height - firstHeight,\n `${path}-B`,\n )\n }\n\n return {\n panes: [...firstLayout.panes, ...secondLayout.panes],\n splitters: [currentSplitter, ...firstLayout.splitters, ...secondLayout.splitters],\n }\n}\n\n/**\n * Tree Helper: Move/insert all tabs of a dragged pane next to a target tab in another pane.\n */\nexport function movePaneTabs(\n tree: TreeNode | null,\n draggedPaneId: string,\n targetTabId: string,\n position: 'before' | 'after' = 'before',\n): TreeNode | null {\n if (tree === null) return null\n\n // 1. Find the dragged pane to get its tabs, activeTabId, and tabsMetadata\n const sourcePane = findPaneById(tree, draggedPaneId)\n if (!sourcePane) return tree\n\n const draggedTabIds = sourcePane.tabIds\n const draggedActiveTabId = sourcePane.activeTabId\n const draggedTabsMetadata = sourcePane.tabsMetadata || {}\n\n // 2. Remove the dragged pane from the layout tree\n const cleanTree = removePane(tree, draggedPaneId)\n if (cleanTree === null) {\n return sourcePane\n }\n\n // 3. Insert the dragged pane's tabs into the target pane next to targetTabId\n function insert(node: TreeNode): TreeNode {\n if (node.type === 'pane') {\n if (node.tabIds.includes(targetTabId)) {\n const newTabs = [...node.tabIds]\n // Filter out any of the dragged tabs if they somehow already existed\n const filteredTabs = newTabs.filter((t) => !draggedTabIds.includes(t))\n let insertIndex = filteredTabs.indexOf(targetTabId)\n if (insertIndex < 0) {\n insertIndex = 0\n }\n if (position === 'after') {\n insertIndex += 1\n }\n filteredTabs.splice(insertIndex, 0, ...draggedTabIds)\n\n const newTabsMetadata = { ...node.tabsMetadata }\n for (const tid of draggedTabIds) {\n if (draggedTabsMetadata[tid]) {\n newTabsMetadata[tid] = draggedTabsMetadata[tid]\n }\n }\n return {\n ...node,\n tabIds: filteredTabs,\n activeTabId: draggedActiveTabId,\n tabsMetadata: Object.keys(newTabsMetadata).length > 0 ? newTabsMetadata : undefined,\n }\n }\n return node\n }\n if (node.type === 'split') {\n return {\n ...node,\n first: insert(node.first),\n second: insert(node.second),\n }\n }\n return node\n }\n\n return insert(cleanTree)\n}\n\n/**\n * Calculates the target drop insertion index in a list of tabs during a drag.\n * Returns -1 if the drop target is not in the list.\n */\nexport function calculateTabDropIndex(\n tabIds: string[],\n activeType: string | null,\n overTabId: string | null,\n overTabPosition: 'before' | 'after' | null,\n): number {\n const isDraggingTabOrPane = activeType === 'tab' || activeType === 'pane'\n const isHoveredTabInThisPane = isDraggingTabOrPane && overTabId && tabIds.includes(overTabId)\n if (!isHoveredTabInThisPane || !overTabPosition) {\n return -1\n }\n const index = tabIds.indexOf(overTabId)\n return overTabPosition === 'before' ? index : index + 1\n}\n"]}
1
+ {"version":3,"sources":["../src/shared/lib/tree/tree-helpers.ts","../src/shared/lib/tree/compare.ts"],"names":["generateUniqueId","removePane","tree","paneId","newFirst","newSecond","removeTab","tabId","newTabs","t","newActive","splitPane","targetId","direction","splitType","paneToAdd","addedNode","isFirst","insertLeaf","leafNode","insert","node","parentDirection","addTab","targetPaneId","targetPane","findPaneById","appendTabToTarget","newPane","updateSplitPercentage","target","newPercentage","findPaneContainingTab","findTabById","pane","index","updatePaneLock","locked","_","rest","selectTab","mergeTab","draggedTabId","cleanTree","swapTabs","targetTabId","sourcePane","sourcePaneId","swap","changed","newTabIds","newActiveTabId","dragIdx","targetIdx","id","moveTab","position","filteredTabs","insertIndex","computeLayout","left","top","width","height","path","splitPercentage","first","second","currentSplitter","firstLayout","secondLayout","firstWidth","firstHeight","movePaneTabs","draggedPaneId","draggedTabIds","draggedActiveTabId","calculateTabDropIndex","tabIds","activeType","overTabId","overTabPosition","areObjectsEqual","a","b","keysA","keysB","key","valA","valB","areMetadataEqual","areLayoutsEqual","sb","pb","i"],"mappings":"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","file":"utils.cjs","sourcesContent":["import { TreeNode, SplitNode, SplitDirection, PaneNode, TabDetails } from '../../model'\n\nexport function generateUniqueId(): string {\n return 'pane-' + Math.random().toString(36).substring(2, 11)\n}\n\n/**\n * Tree Helper: Remove a pane container and consolidate the tree structure.\n */\nexport function removePane(tree: TreeNode | null, paneId: string): TreeNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n if (tree.id === paneId) return null\n return tree\n }\n const newFirst = removePane(tree.first, paneId)\n const newSecond = removePane(tree.second, paneId)\n if (newFirst === null) return newSecond\n if (newSecond === null) return newFirst\n return { ...tree, first: newFirst, second: newSecond }\n}\n\n/**\n * Tree Helper: Remove a tab from a pane and consolidate the tree structure if no tabs remain.\n */\nexport function removeTab(tree: TreeNode | null, tabId: string): TreeNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n if (tree.tabIds.includes(tabId)) {\n const newTabs = tree.tabIds.filter((t) => t !== tabId)\n if (newTabs.length === 0) return null\n let newActive = tree.activeTabId\n if (tree.activeTabId === tabId) {\n newActive = newTabs[0]\n }\n return {\n ...tree,\n tabIds: newTabs,\n activeTabId: newActive,\n }\n }\n return tree\n }\n const newFirst = removeTab(tree.first, tabId)\n const newSecond = removeTab(tree.second, tabId)\n if (newFirst === null) return newSecond\n if (newSecond === null) return newFirst\n return { ...tree, first: newFirst, second: newSecond }\n}\n\n/**\n * Tree Helper: Insert a pane or widget by splitting an existing target node.\n */\nexport function splitPane(\n tree: TreeNode | null,\n targetId: string,\n direction: SplitDirection,\n splitType: 'left' | 'right' | 'top' | 'bottom',\n paneToAdd: string | PaneNode,\n): TreeNode | null {\n if (tree === null) {\n if (typeof paneToAdd === 'string') {\n return { type: 'pane', id: generateUniqueId(), tabIds: [paneToAdd], activeTabId: paneToAdd }\n }\n return paneToAdd\n }\n if (tree.type === 'pane') {\n if (tree.id === targetId) {\n const addedNode: PaneNode =\n typeof paneToAdd === 'string'\n ? { type: 'pane', id: generateUniqueId(), tabIds: [paneToAdd], activeTabId: paneToAdd }\n : paneToAdd\n const isFirst = splitType === 'left' || splitType === 'top'\n return {\n type: 'split',\n direction,\n first: isFirst ? addedNode : tree,\n second: isFirst ? tree : addedNode,\n splitPercentage: 50,\n }\n }\n return tree\n }\n return {\n ...tree,\n first: splitPane(tree.first, targetId, direction, splitType, paneToAdd) || tree.first,\n second: splitPane(tree.second, targetId, direction, splitType, paneToAdd) || tree.second,\n }\n}\n\n/**\n * Helper to insert a leaf node (PaneNode or WidgetNode) into the layout tree.\n */\nexport function insertLeaf(tree: TreeNode | null, leafNode: PaneNode): TreeNode {\n if (tree === null) {\n return leafNode\n }\n\n function insert(node: TreeNode, parentDirection: SplitDirection | null): TreeNode {\n if (node.type === 'pane') {\n const direction: SplitDirection = parentDirection === 'row' ? 'column' : 'row'\n return {\n type: 'split',\n direction,\n splitPercentage: 50,\n first: node,\n second: leafNode,\n }\n }\n\n return {\n ...node,\n second: insert(node.second, node.direction),\n }\n }\n\n return insert(tree, null)\n}\n\n/**\n * Tree Helper: Add a tab into a target pane node, or splits/creates a new pane if no target pane ID is provided.\n */\nexport function addTab(\n tree: TreeNode | null,\n targetPaneId: string | undefined | null,\n tabId: string,\n): TreeNode | null {\n if (tree === null) {\n return {\n type: 'pane',\n id: generateUniqueId(),\n tabIds: [tabId],\n activeTabId: tabId,\n }\n }\n\n const targetPane = targetPaneId ? findPaneById(tree, targetPaneId) : null\n if (targetPane && targetPane.type === 'pane') {\n function appendTabToTarget(node: TreeNode): TreeNode {\n if (node.type === 'pane' && node.id === targetPaneId) {\n const newTabs = [...node.tabIds]\n if (!newTabs.includes(tabId)) {\n newTabs.push(tabId)\n }\n return {\n ...node,\n tabIds: newTabs,\n activeTabId: tabId,\n }\n }\n if (node.type === 'split') {\n return {\n ...node,\n first: appendTabToTarget(node.first),\n second: appendTabToTarget(node.second),\n }\n }\n return node\n }\n return appendTabToTarget(tree)\n }\n\n const newPane: PaneNode = {\n type: 'pane',\n id: generateUniqueId(),\n tabIds: [tabId],\n activeTabId: tabId,\n }\n return insertLeaf(tree, newPane)\n}\n\n/**\n * Tree Helper: Update split percentage recursively.\n */\nexport function updateSplitPercentage(\n tree: TreeNode | null,\n target: SplitNode,\n newPercentage: number,\n): TreeNode | null {\n if (tree === null) return null\n if (tree === target) {\n return { ...tree, splitPercentage: newPercentage }\n }\n if (tree.type === 'split') {\n return {\n ...tree,\n first: updateSplitPercentage(tree.first, target, newPercentage) || tree.first,\n second: updateSplitPercentage(tree.second, target, newPercentage) || tree.second,\n }\n }\n return tree\n}\n\n/**\n * Find a PaneNode or WidgetNode by its ID.\n */\nexport function findPaneById(tree: TreeNode | null, paneId: string): PaneNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n return tree.id === paneId ? tree : null\n }\n if (tree.type === 'split') {\n return findPaneById(tree.first, paneId) ?? findPaneById(tree.second, paneId)\n }\n return null\n}\n\n/**\n * Find a PaneNode containing the given tab ID.\n */\nexport function findPaneContainingTab(tree: TreeNode | null, tabId: string): PaneNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n return tree.tabIds.includes(tabId) ? tree : null\n }\n if (tree.type === 'split') {\n return findPaneContainingTab(tree.first, tabId) ?? findPaneContainingTab(tree.second, tabId)\n }\n return null\n}\n\n/**\n * Find a PaneNode by its own ID, or by a tab ID it contains.\n */\nexport function findPaneOrContainingTab(tree: TreeNode | null, id: string): PaneNode | null {\n return findPaneById(tree, id) ?? findPaneContainingTab(tree, id)\n}\n\n/**\n * Find the details of a tab by its ID.\n */\nexport function findTabById(tree: TreeNode | null, tabId: string): TabDetails | null {\n const pane = findPaneContainingTab(tree, tabId)\n if (!pane) return null\n const index = pane.tabIds.indexOf(tabId)\n return {\n id: tabId,\n paneId: pane.id,\n isActive: pane.activeTabId === tabId,\n index,\n metadata: undefined,\n }\n}\n\n/**\n * Update the locked status on a specific pane or widget node in the layout tree.\n */\nexport function updatePaneLock(\n tree: TreeNode | null,\n paneId: string,\n locked: boolean,\n): TreeNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n if (tree.id === paneId) {\n if (locked === false) {\n const { locked: _, ...rest } = tree\n return rest as PaneNode\n }\n return { ...tree, locked }\n }\n return tree\n }\n if (tree.type === 'split') {\n return {\n ...tree,\n first: updatePaneLock(tree.first, paneId, locked) ?? tree.first,\n second: updatePaneLock(tree.second, paneId, locked) ?? tree.second,\n }\n }\n return tree\n}\n\n/**\n * Tree Helper: Activate a tab within a pane.\n */\nexport function selectTab(tree: TreeNode | null, paneId: string, tabId: string): TreeNode | null {\n if (tree === null) return null\n if (tree.type === 'pane') {\n if (tree.id === paneId) {\n if (tree.activeTabId === tabId) return tree\n return { ...tree, activeTabId: tabId }\n }\n return tree\n }\n if (tree.type === 'split') {\n return {\n ...tree,\n first: selectTab(tree.first, paneId, tabId) ?? tree.first,\n second: selectTab(tree.second, paneId, tabId) ?? tree.second,\n }\n }\n return tree\n}\n\n/**\n * Tree Helper: Merge a tab into a target pane node.\n */\nexport function mergeTab(\n tree: TreeNode | null,\n draggedTabId: string,\n targetPaneId: string,\n): TreeNode | null {\n if (tree === null) return null\n\n const cleanTree = removeTab(tree, draggedTabId)\n if (cleanTree === null) {\n return {\n type: 'pane',\n id: generateUniqueId(),\n tabIds: [draggedTabId],\n activeTabId: draggedTabId,\n }\n }\n\n function insert(node: TreeNode): TreeNode {\n if (node.type === 'pane') {\n if (node.id === targetPaneId) {\n const newTabs = [...node.tabIds]\n if (!newTabs.includes(draggedTabId)) {\n newTabs.push(draggedTabId)\n }\n return {\n ...node,\n tabIds: newTabs,\n activeTabId: draggedTabId,\n }\n }\n return node\n }\n if (node.type === 'split') {\n return {\n ...node,\n first: insert(node.first),\n second: insert(node.second),\n }\n }\n return node\n }\n\n return insert(cleanTree)\n}\n\nexport function swapTabs(\n tree: TreeNode | null,\n draggedTabId: string,\n targetTabId: string,\n): TreeNode | null {\n if (tree === null) return null\n if (draggedTabId === targetTabId) return tree\n\n const sourcePane = findPaneContainingTab(tree, draggedTabId)\n const targetPane = findPaneContainingTab(tree, targetTabId)\n\n if (!sourcePane || !targetPane) return tree\n\n const sourcePaneId = sourcePane.id\n const targetPaneId = targetPane.id\n\n function swap(node: TreeNode): TreeNode {\n if (node.type === 'pane') {\n let changed = false\n let newTabIds = [...node.tabIds]\n let newActiveTabId = node.activeTabId\n\n if (sourcePaneId === targetPaneId) {\n if (node.id === sourcePaneId) {\n const dragIdx = newTabIds.indexOf(draggedTabId)\n const targetIdx = newTabIds.indexOf(targetTabId)\n if (dragIdx !== -1 && targetIdx !== -1) {\n newTabIds[dragIdx] = targetTabId\n newTabIds[targetIdx] = draggedTabId\n }\n newActiveTabId = draggedTabId\n changed = true\n }\n } else {\n if (node.id === sourcePaneId) {\n newTabIds = newTabIds.map((id) => (id === draggedTabId ? targetTabId : id))\n if (newActiveTabId === draggedTabId) {\n newActiveTabId = targetTabId\n }\n changed = true\n }\n if (node.id === targetPaneId) {\n newTabIds = newTabIds.map((id) => (id === targetTabId ? draggedTabId : id))\n if (newActiveTabId === targetTabId) {\n newActiveTabId = draggedTabId\n }\n changed = true\n }\n }\n\n if (changed) {\n return {\n ...node,\n tabIds: newTabIds,\n activeTabId: newActiveTabId,\n }\n }\n return node\n }\n if (node.type === 'split') {\n return {\n ...node,\n first: swap(node.first),\n second: swap(node.second),\n }\n }\n return node\n }\n\n return swap(tree)\n}\n\n/**\n * Tree Helper: Move/reorder a tab inside or to a target pane next to a target tab.\n */\nexport function moveTab(\n tree: TreeNode | null,\n draggedTabId: string,\n targetTabId: string,\n position: 'before' | 'after' | 'center' = 'before',\n): TreeNode | null {\n if (tree === null) return null\n if (draggedTabId === targetTabId) return tree\n\n if (position === 'center') {\n return swapTabs(tree, draggedTabId, targetTabId)\n }\n\n const cleanTree = removeTab(tree, draggedTabId)\n if (cleanTree === null) {\n return {\n type: 'pane',\n id: generateUniqueId(),\n tabIds: [draggedTabId],\n activeTabId: draggedTabId,\n }\n }\n\n function insert(node: TreeNode): TreeNode {\n if (node.type === 'pane') {\n if (node.tabIds.includes(targetTabId)) {\n const newTabs = [...node.tabIds]\n const filteredTabs = newTabs.filter((t) => t !== draggedTabId)\n let insertIndex = filteredTabs.indexOf(targetTabId)\n if (insertIndex < 0) {\n insertIndex = 0\n }\n if (position === 'after') {\n insertIndex += 1\n }\n filteredTabs.splice(insertIndex, 0, draggedTabId)\n\n return {\n ...node,\n tabIds: filteredTabs,\n activeTabId: draggedTabId,\n }\n }\n return node\n }\n if (node.type === 'split') {\n return {\n ...node,\n first: insert(node.first),\n second: insert(node.second),\n }\n }\n return node\n }\n\n return insert(cleanTree)\n}\n\nexport interface ComputedPane {\n paneId: string\n left: number\n top: number\n width: number\n height: number\n node: PaneNode\n}\n\nexport interface ComputedSplitter {\n id: string\n currentNode: SplitNode\n direction: SplitDirection\n left: number\n top: number\n width: number\n height: number\n parentLeft: number\n parentTop: number\n parentWidth: number\n parentHeight: number\n}\n\nexport function computeLayout(\n node: TreeNode | null,\n left = 0,\n top = 0,\n width = 100,\n height = 100,\n path = 'root',\n): { panes: ComputedPane[]; splitters: ComputedSplitter[] } {\n if (node === null) return { panes: [], splitters: [] }\n if (node.type === 'pane') {\n return {\n panes: [{ paneId: node.id, left, top, width, height, node }],\n splitters: [],\n }\n }\n\n const { direction, splitPercentage, first, second } = node\n const splitterId = `splitter-${path}-${direction}`\n\n const currentSplitter: ComputedSplitter = {\n id: splitterId,\n currentNode: node,\n direction,\n left: direction === 'row' ? left + width * (splitPercentage / 100) : left,\n top: direction === 'column' ? top + height * (splitPercentage / 100) : top,\n width: direction === 'row' ? 0 : width,\n height: direction === 'column' ? 0 : height,\n parentLeft: left,\n parentTop: top,\n parentWidth: width,\n parentHeight: height,\n }\n\n let firstLayout = { panes: [] as ComputedPane[], splitters: [] as ComputedSplitter[] }\n let secondLayout = { panes: [] as ComputedPane[], splitters: [] as ComputedSplitter[] }\n\n if (direction === 'row') {\n const firstWidth = width * (splitPercentage / 100)\n firstLayout = computeLayout(first, left, top, firstWidth, height, `${path}-L`)\n secondLayout = computeLayout(\n second,\n left + firstWidth,\n top,\n width - firstWidth,\n height,\n `${path}-R`,\n )\n } else {\n const firstHeight = height * (splitPercentage / 100)\n firstLayout = computeLayout(first, left, top, width, firstHeight, `${path}-T`)\n secondLayout = computeLayout(\n second,\n left,\n top + firstHeight,\n width,\n height - firstHeight,\n `${path}-B`,\n )\n }\n\n return {\n panes: [...firstLayout.panes, ...secondLayout.panes],\n splitters: [currentSplitter, ...firstLayout.splitters, ...secondLayout.splitters],\n }\n}\n\n/**\n * Tree Helper: Move/insert all tabs of a dragged pane next to a target tab in another pane.\n */\nexport function movePaneTabs(\n tree: TreeNode | null,\n draggedPaneId: string,\n targetTabId: string,\n position: 'before' | 'after' = 'before',\n): TreeNode | null {\n if (tree === null) return null\n\n // 1. Find the dragged pane to get its tabs and activeTabId\n const sourcePane = findPaneById(tree, draggedPaneId)\n if (!sourcePane) return tree\n\n const draggedTabIds = sourcePane.tabIds\n const draggedActiveTabId = sourcePane.activeTabId\n\n // 2. Remove the dragged pane from the layout tree\n const cleanTree = removePane(tree, draggedPaneId)\n if (cleanTree === null) {\n return sourcePane\n }\n\n // 3. Insert the dragged pane's tabs into the target pane next to targetTabId\n function insert(node: TreeNode): TreeNode {\n if (node.type === 'pane') {\n if (node.tabIds.includes(targetTabId)) {\n const newTabs = [...node.tabIds]\n // Filter out any of the dragged tabs if they somehow already existed\n const filteredTabs = newTabs.filter((t) => !draggedTabIds.includes(t))\n let insertIndex = filteredTabs.indexOf(targetTabId)\n if (insertIndex < 0) {\n insertIndex = 0\n }\n if (position === 'after') {\n insertIndex += 1\n }\n filteredTabs.splice(insertIndex, 0, ...draggedTabIds)\n\n return {\n ...node,\n tabIds: filteredTabs,\n activeTabId: draggedActiveTabId,\n }\n }\n return node\n }\n if (node.type === 'split') {\n return {\n ...node,\n first: insert(node.first),\n second: insert(node.second),\n }\n }\n return node\n }\n\n return insert(cleanTree)\n}\n\n/**\n * Calculates the target drop insertion index in a list of tabs during a drag.\n * Returns -1 if the drop target is not in the list.\n */\nexport function calculateTabDropIndex(\n tabIds: string[],\n activeType: string | null,\n overTabId: string | null,\n overTabPosition: 'before' | 'after' | null,\n): number {\n const isDraggingTabOrPane = activeType === 'tab' || activeType === 'pane'\n const isHoveredTabInThisPane = isDraggingTabOrPane && overTabId && tabIds.includes(overTabId)\n if (!isHoveredTabInThisPane || !overTabPosition) {\n return -1\n }\n const index = tabIds.indexOf(overTabId)\n return overTabPosition === 'before' ? index : index + 1\n}\n","import { TreeNode, SplitNode, PaneNode } from '../../model/types'\n\nexport function areObjectsEqual(\n a: Record<string, unknown> | undefined,\n b: Record<string, unknown> | undefined,\n): boolean {\n if (a === b) return true\n if (!a || !b) return false\n const keysA = Object.keys(a)\n const keysB = Object.keys(b)\n if (keysA.length !== keysB.length) return false\n for (const key of keysA) {\n if (!Object.prototype.hasOwnProperty.call(b, key)) return false\n const valA = a[key]\n const valB = b[key]\n if (typeof valA === 'object' && valA !== null && typeof valB === 'object' && valB !== null) {\n if (!areObjectsEqual(valA as Record<string, unknown>, valB as Record<string, unknown>)) {\n return false\n }\n } else if (valA !== valB) {\n return false\n }\n }\n return true\n}\n\nexport function areMetadataEqual(\n a: Record<string, Record<string, unknown>> | undefined,\n b: Record<string, Record<string, unknown>> | undefined,\n): boolean {\n if (a === b) return true\n if (!a || !b) return false\n const keysA = Object.keys(a)\n const keysB = Object.keys(b)\n if (keysA.length !== keysB.length) return false\n for (const key of keysA) {\n if (!Object.prototype.hasOwnProperty.call(b, key)) return false\n if (!areObjectsEqual(a[key], b[key])) return false\n }\n return true\n}\n\n/**\n * Perform a fast deep equality comparison of two layout tree nodes,\n * short-circuiting as soon as a difference is found and avoiding costly\n * JSON stringification on every render.\n */\nexport function areLayoutsEqual(a: TreeNode | null, b: TreeNode | null): boolean {\n if (a === b) return true\n if (!a || !b) return false\n if (a.type !== b.type) return false\n\n if (a.type === 'split') {\n const sb = b as SplitNode\n return (\n a.direction === sb.direction &&\n a.splitPercentage === sb.splitPercentage &&\n areLayoutsEqual(a.first, sb.first) &&\n areLayoutsEqual(a.second, sb.second)\n )\n } else {\n const pb = b as PaneNode\n if (a.id !== pb.id) return false\n if (a.activeTabId !== pb.activeTabId) return false\n if (a.locked !== pb.locked) return false\n if (a.tabIds.length !== pb.tabIds.length) return false\n for (let i = 0; i < a.tabIds.length; i++) {\n if (a.tabIds[i] !== pb.tabIds[i]) return false\n }\n return true\n }\n}\n"]}
package/dist/utils.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { P as PaneNode, b as SplitNode, S as SplitDirection, T as TreeNode, c as TabDetails } from './types-D7fO-n0A.cjs';
1
+ import { P as PaneNode, b as SplitNode, S as SplitDirection, T as TreeNode, c as TabDetails } from './types-TTO4dDzX.cjs';
2
2
  import 'react';
3
3
 
4
4
  declare function generateUniqueId(): string;
@@ -21,7 +21,7 @@ declare function insertLeaf(tree: TreeNode | null, leafNode: PaneNode): TreeNode
21
21
  /**
22
22
  * Tree Helper: Add a tab into a target pane node, or splits/creates a new pane if no target pane ID is provided.
23
23
  */
24
- declare function addTab(tree: TreeNode | null, targetPaneId: string | undefined | null, tabId: string, metadata?: Record<string, unknown>): TreeNode | null;
24
+ declare function addTab(tree: TreeNode | null, targetPaneId: string | undefined | null, tabId: string): TreeNode | null;
25
25
  /**
26
26
  * Tree Helper: Update split percentage recursively.
27
27
  */
@@ -38,21 +38,6 @@ declare function findPaneContainingTab(tree: TreeNode | null, tabId: string): Pa
38
38
  * Find the details of a tab by its ID.
39
39
  */
40
40
  declare function findTabById(tree: TreeNode | null, tabId: string): TabDetails | null;
41
- /**
42
- * Get the metadata for a specific tab by its ID.
43
- */
44
- declare function getTabMetadata(tree: TreeNode | null, tabId: string): Record<string, unknown> | undefined;
45
- /**
46
- * Get the metadata of the active item (either tab or pane).
47
- */
48
- /**
49
- * Get the metadata of the active tab in a specific pane.
50
- */
51
- declare function getActiveTabMetadata(tree: TreeNode | null, paneId: string): Record<string, unknown> | undefined;
52
- /**
53
- * Update metadata on a specific tab or widget node using an updater function.
54
- */
55
- declare function updateMetadata(tree: TreeNode | null, id: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined): TreeNode | null;
56
41
  /**
57
42
  * Update the locked status on a specific pane or widget node in the layout tree.
58
43
  */
@@ -105,4 +90,13 @@ declare function movePaneTabs(tree: TreeNode | null, draggedPaneId: string, targ
105
90
  */
106
91
  declare function calculateTabDropIndex(tabIds: string[], activeType: string | null, overTabId: string | null, overTabPosition: 'before' | 'after' | null): number;
107
92
 
108
- export { type ComputedPane, type ComputedSplitter, addTab, calculateTabDropIndex, computeLayout, findPaneById, findPaneContainingTab, findTabById, generateUniqueId, getActiveTabMetadata, getTabMetadata, insertLeaf, mergeTab, movePaneTabs, moveTab, removePane, removeTab, selectTab, splitPane, swapTabs, updateMetadata, updatePaneLock, updateSplitPercentage };
93
+ declare function areObjectsEqual(a: Record<string, unknown> | undefined, b: Record<string, unknown> | undefined): boolean;
94
+ declare function areMetadataEqual(a: Record<string, Record<string, unknown>> | undefined, b: Record<string, Record<string, unknown>> | undefined): boolean;
95
+ /**
96
+ * Perform a fast deep equality comparison of two layout tree nodes,
97
+ * short-circuiting as soon as a difference is found and avoiding costly
98
+ * JSON stringification on every render.
99
+ */
100
+ declare function areLayoutsEqual(a: TreeNode | null, b: TreeNode | null): boolean;
101
+
102
+ export { type ComputedPane, type ComputedSplitter, addTab, areLayoutsEqual, areMetadataEqual, areObjectsEqual, calculateTabDropIndex, computeLayout, findPaneById, findPaneContainingTab, findTabById, generateUniqueId, insertLeaf, mergeTab, movePaneTabs, moveTab, removePane, removeTab, selectTab, splitPane, swapTabs, updatePaneLock, updateSplitPercentage };
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { P as PaneNode, b as SplitNode, S as SplitDirection, T as TreeNode, c as TabDetails } from './types-D7fO-n0A.js';
1
+ import { P as PaneNode, b as SplitNode, S as SplitDirection, T as TreeNode, c as TabDetails } from './types-TTO4dDzX.js';
2
2
  import 'react';
3
3
 
4
4
  declare function generateUniqueId(): string;
@@ -21,7 +21,7 @@ declare function insertLeaf(tree: TreeNode | null, leafNode: PaneNode): TreeNode
21
21
  /**
22
22
  * Tree Helper: Add a tab into a target pane node, or splits/creates a new pane if no target pane ID is provided.
23
23
  */
24
- declare function addTab(tree: TreeNode | null, targetPaneId: string | undefined | null, tabId: string, metadata?: Record<string, unknown>): TreeNode | null;
24
+ declare function addTab(tree: TreeNode | null, targetPaneId: string | undefined | null, tabId: string): TreeNode | null;
25
25
  /**
26
26
  * Tree Helper: Update split percentage recursively.
27
27
  */
@@ -38,21 +38,6 @@ declare function findPaneContainingTab(tree: TreeNode | null, tabId: string): Pa
38
38
  * Find the details of a tab by its ID.
39
39
  */
40
40
  declare function findTabById(tree: TreeNode | null, tabId: string): TabDetails | null;
41
- /**
42
- * Get the metadata for a specific tab by its ID.
43
- */
44
- declare function getTabMetadata(tree: TreeNode | null, tabId: string): Record<string, unknown> | undefined;
45
- /**
46
- * Get the metadata of the active item (either tab or pane).
47
- */
48
- /**
49
- * Get the metadata of the active tab in a specific pane.
50
- */
51
- declare function getActiveTabMetadata(tree: TreeNode | null, paneId: string): Record<string, unknown> | undefined;
52
- /**
53
- * Update metadata on a specific tab or widget node using an updater function.
54
- */
55
- declare function updateMetadata(tree: TreeNode | null, id: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined): TreeNode | null;
56
41
  /**
57
42
  * Update the locked status on a specific pane or widget node in the layout tree.
58
43
  */
@@ -105,4 +90,13 @@ declare function movePaneTabs(tree: TreeNode | null, draggedPaneId: string, targ
105
90
  */
106
91
  declare function calculateTabDropIndex(tabIds: string[], activeType: string | null, overTabId: string | null, overTabPosition: 'before' | 'after' | null): number;
107
92
 
108
- export { type ComputedPane, type ComputedSplitter, addTab, calculateTabDropIndex, computeLayout, findPaneById, findPaneContainingTab, findTabById, generateUniqueId, getActiveTabMetadata, getTabMetadata, insertLeaf, mergeTab, movePaneTabs, moveTab, removePane, removeTab, selectTab, splitPane, swapTabs, updateMetadata, updatePaneLock, updateSplitPercentage };
93
+ declare function areObjectsEqual(a: Record<string, unknown> | undefined, b: Record<string, unknown> | undefined): boolean;
94
+ declare function areMetadataEqual(a: Record<string, Record<string, unknown>> | undefined, b: Record<string, Record<string, unknown>> | undefined): boolean;
95
+ /**
96
+ * Perform a fast deep equality comparison of two layout tree nodes,
97
+ * short-circuiting as soon as a difference is found and avoiding costly
98
+ * JSON stringification on every render.
99
+ */
100
+ declare function areLayoutsEqual(a: TreeNode | null, b: TreeNode | null): boolean;
101
+
102
+ export { type ComputedPane, type ComputedSplitter, addTab, areLayoutsEqual, areMetadataEqual, areObjectsEqual, calculateTabDropIndex, computeLayout, findPaneById, findPaneContainingTab, findTabById, generateUniqueId, insertLeaf, mergeTab, movePaneTabs, moveTab, removePane, removeTab, selectTab, splitPane, swapTabs, updatePaneLock, updateSplitPercentage };
package/dist/utils.js CHANGED
@@ -1,2 +1,2 @@
1
- function M(){return "pane-"+Math.random().toString(36).substring(2,11)}function x(n,t){if(n===null)return null;if(n.type==="pane")return n.id===t?null:n;let e=x(n.first,t),i=x(n.second,t);return e===null?i:i===null?e:{...n,first:e,second:i}}function P(n,t){if(n===null)return null;if(n.type==="pane"){if(n.tabIds.includes(t)){let s=n.tabIds.filter(o=>o!==t);if(s.length===0)return null;let l=n.activeTabId;n.activeTabId===t&&(l=s[0]);let u={...n.tabsMetadata};return delete u[t],{...n,tabIds:s,activeTabId:l,tabsMetadata:Object.keys(u).length>0?u:void 0}}return n}let e=P(n.first,t),i=P(n.second,t);return e===null?i:i===null?e:{...n,first:e,second:i}}function v(n,t,e,i,s){if(n===null)return typeof s=="string"?{type:"pane",id:M(),tabIds:[s],activeTabId:s}:s;if(n.type==="pane"){if(n.id===t){let l=typeof s=="string"?{type:"pane",id:M(),tabIds:[s],activeTabId:s}:s,u=i==="left"||i==="top";return {type:"split",direction:e,first:u?l:n,second:u?n:l,splitPercentage:50}}return n}return {...n,first:v(n.first,t,e,i,s)||n.first,second:v(n.second,t,e,i,s)||n.second}}function D(n,t){if(n===null)return t;function e(i,s){return i.type==="pane"?{type:"split",direction:s==="row"?"column":"row",splitPercentage:50,first:i,second:t}:{...i,second:e(i.second,i.direction)}}return e(n,null)}function h(n,t,e,i){if(n===null)return {type:"pane",id:M(),tabIds:[e],activeTabId:e,tabsMetadata:i?{[e]:i}:void 0};let s=t?y(n,t):null;if(s&&s.type==="pane"){let o=function(r){if(r.type==="pane"&&r.id===t){let f=[...r.tabIds];f.includes(e)||f.push(e);let a=r.tabsMetadata;return i&&(a={...r.tabsMetadata,[e]:i}),{...r,tabIds:f,activeTabId:e,tabsMetadata:a}}return r.type==="split"?{...r,first:o(r.first),second:o(r.second)}:r};return o(n)}let l={type:"pane",id:M(),tabIds:[e],activeTabId:e,tabsMetadata:i?{[e]:i}:void 0};return D(n,l)}function w(n,t,e){return n===null?null:n===t?{...n,splitPercentage:e}:n.type==="split"?{...n,first:w(n.first,t,e)||n.first,second:w(n.second,t,e)||n.second}:n}function y(n,t){return n===null?null:n.type==="pane"?n.id===t?n:null:n.type==="split"?y(n.first,t)??y(n.second,t):null}function N(n,t){return n===null?null:n.type==="pane"?n.tabIds.includes(t)?n:null:n.type==="split"?N(n.first,t)??N(n.second,t):null}function j(n,t){let e=N(n,t);if(!e)return null;let i=e.tabIds.indexOf(t);return {id:t,paneId:e.id,isActive:e.activeTabId===t,index:i,metadata:e.tabsMetadata?.[t]}}function R(n,t){return N(n,t)?.tabsMetadata?.[t]}function $(n,t){let e=y(n,t);return e?.tabsMetadata?.[e.activeTabId]}function S(n,t,e){if(n===null)return null;if(n.type==="pane"){if(n.tabIds.includes(t)){let i=n.tabsMetadata||{},s=i[t],l=e(s),u={...i};return l===void 0?delete u[t]:u[t]=l,{...n,tabsMetadata:Object.keys(u).length>0?u:void 0}}return n}return n.type==="split"?{...n,first:S(n.first,t,e)??n.first,second:S(n.second,t,e)??n.second}:n}function O(n,t,e){if(n===null)return null;if(n.type==="pane"){if(n.id===t){if(e===false){let{locked:i,...s}=n;return s}return {...n,locked:e}}return n}return n.type==="split"?{...n,first:O(n.first,t,e)??n.first,second:O(n.second,t,e)??n.second}:n}function C(n,t,e){return n===null?null:n.type==="pane"?n.id===t?n.activeTabId===e?n:{...n,activeTabId:e}:n:n.type==="split"?{...n,first:C(n.first,t,e)??n.first,second:C(n.second,t,e)??n.second}:n}function B(n,t,e){if(n===null)return null;let s=N(n,t)?.tabsMetadata?.[t],l=P(n,t);if(l===null)return {type:"pane",id:M(),tabIds:[t],activeTabId:t,tabsMetadata:s?{[t]:s}:void 0};function u(o){if(o.type==="pane"){if(o.id===e){let r=[...o.tabIds];r.includes(t)||r.push(t);let f={...o.tabsMetadata};return s&&(f[t]=s),{...o,tabIds:r,activeTabId:t,tabsMetadata:Object.keys(f).length>0?f:void 0}}return o}return o.type==="split"?{...o,first:u(o.first),second:u(o.second)}:o}return u(l)}function L(n,t,e){if(n===null)return null;if(t===e)return n;let i=N(n,t),s=N(n,e);if(!i||!s)return n;let l=i.id,u=s.id,o=i.tabsMetadata?.[t],r=s.tabsMetadata?.[e];function f(a){if(a.type==="pane"){let T=false,c=[...a.tabIds],p=a.activeTabId,d=a.tabsMetadata?{...a.tabsMetadata}:{};if(l===u){if(a.id===l){let b=c.indexOf(t),k=c.indexOf(e);b!==-1&&k!==-1&&(c[b]=e,c[k]=t),p=t,T=true;}}else a.id===l&&(c=c.map(b=>b===t?e:b),p===t&&(p=e),delete d[t],r&&(d[e]=r),T=true),a.id===u&&(c=c.map(b=>b===e?t:b),p===e&&(p=t),delete d[e],o&&(d[t]=o),T=true);return T?{...a,tabIds:c,activeTabId:p,tabsMetadata:Object.keys(d).length>0?d:void 0}:a}return a.type==="split"?{...a,first:f(a.first),second:f(a.second)}:a}return f(n)}function H(n,t,e,i="before"){if(n===null)return null;if(t===e)return n;if(i==="center")return L(n,t,e);let l=N(n,t)?.tabsMetadata?.[t],u=P(n,t);if(u===null)return {type:"pane",id:M(),tabIds:[t],activeTabId:t,tabsMetadata:l?{[t]:l}:void 0};function o(r){if(r.type==="pane"){if(r.tabIds.includes(e)){let a=[...r.tabIds].filter(p=>p!==t),T=a.indexOf(e);T<0&&(T=0),i==="after"&&(T+=1),a.splice(T,0,t);let c={...r.tabsMetadata};return l&&(c[t]=l),{...r,tabIds:a,activeTabId:t,tabsMetadata:Object.keys(c).length>0?c:void 0}}return r}return r.type==="split"?{...r,first:o(r.first),second:o(r.second)}:r}return o(u)}function m(n,t=0,e=0,i=100,s=100,l="root"){if(n===null)return {panes:[],splitters:[]};if(n.type==="pane")return {panes:[{paneId:n.id,left:t,top:e,width:i,height:s,node:n}],splitters:[]};let{direction:u,splitPercentage:o,first:r,second:f}=n,T={id:`splitter-${l}-${u}`,currentNode:n,direction:u,left:u==="row"?t+i*(o/100):t,top:u==="column"?e+s*(o/100):e,width:u==="row"?0:i,height:u==="column"?0:s,parentLeft:t,parentTop:e,parentWidth:i,parentHeight:s},c={panes:[],splitters:[]},p={panes:[],splitters:[]};if(u==="row"){let d=i*(o/100);c=m(r,t,e,d,s,`${l}-L`),p=m(f,t+d,e,i-d,s,`${l}-R`);}else {let d=s*(o/100);c=m(r,t,e,i,d,`${l}-T`),p=m(f,t,e+d,i,s-d,`${l}-B`);}return {panes:[...c.panes,...p.panes],splitters:[T,...c.splitters,...p.splitters]}}function F(n,t,e,i="before"){if(n===null)return null;let s=y(n,t);if(!s)return n;let l=s.tabIds,u=s.activeTabId,o=s.tabsMetadata||{},r=x(n,t);if(r===null)return s;function f(a){if(a.type==="pane"){if(a.tabIds.includes(e)){let c=[...a.tabIds].filter(b=>!l.includes(b)),p=c.indexOf(e);p<0&&(p=0),i==="after"&&(p+=1),c.splice(p,0,...l);let d={...a.tabsMetadata};for(let b of l)o[b]&&(d[b]=o[b]);return {...a,tabIds:c,activeTabId:u,tabsMetadata:Object.keys(d).length>0?d:void 0}}return a}return a.type==="split"?{...a,first:f(a.first),second:f(a.second)}:a}return f(r)}function W(n,t,e,i){if(!((t==="tab"||t==="pane")&&e&&n.includes(e))||!i)return -1;let u=n.indexOf(e);return i==="before"?u:u+1}export{h as addTab,W as calculateTabDropIndex,m as computeLayout,y as findPaneById,N as findPaneContainingTab,j as findTabById,M as generateUniqueId,$ as getActiveTabMetadata,R as getTabMetadata,D as insertLeaf,B as mergeTab,F as movePaneTabs,H as moveTab,x as removePane,P as removeTab,C as selectTab,v as splitPane,L as swapTabs,S as updateMetadata,O as updatePaneLock,w as updateSplitPercentage};//# sourceMappingURL=utils.js.map
1
+ function b(){return "pane-"+Math.random().toString(36).substring(2,11)}function x(n,e){if(n===null)return null;if(n.type==="pane")return n.id===e?null:n;let t=x(n.first,e),r=x(n.second,e);return t===null?r:r===null?t:{...n,first:t,second:r}}function m(n,e){if(n===null)return null;if(n.type==="pane"){if(n.tabIds.includes(e)){let i=n.tabIds.filter(s=>s!==e);if(i.length===0)return null;let u=n.activeTabId;return n.activeTabId===e&&(u=i[0]),{...n,tabIds:i,activeTabId:u}}return n}let t=m(n.first,e),r=m(n.second,e);return t===null?r:r===null?t:{...n,first:t,second:r}}function v(n,e,t,r,i){if(n===null)return typeof i=="string"?{type:"pane",id:b(),tabIds:[i],activeTabId:i}:i;if(n.type==="pane"){if(n.id===e){let u=typeof i=="string"?{type:"pane",id:b(),tabIds:[i],activeTabId:i}:i,s=r==="left"||r==="top";return {type:"split",direction:t,first:s?u:n,second:s?n:u,splitPercentage:50}}return n}return {...n,first:v(n.first,e,t,r,i)||n.first,second:v(n.second,e,t,r,i)||n.second}}function C(n,e){if(n===null)return e;function t(r,i){return r.type==="pane"?{type:"split",direction:i==="row"?"column":"row",splitPercentage:50,first:r,second:e}:{...r,second:t(r.second,r.direction)}}return t(n,null)}function D(n,e,t){if(n===null)return {type:"pane",id:b(),tabIds:[t],activeTabId:t};let r=e?P(n,e):null;if(r&&r.type==="pane"){let s=function(f){if(f.type==="pane"&&f.id===e){let l=[...f.tabIds];return l.includes(t)||l.push(t),{...f,tabIds:l,activeTabId:t}}return f.type==="split"?{...f,first:s(f.first),second:s(f.second)}:f};return s(n)}let i={type:"pane",id:b(),tabIds:[t],activeTabId:t};return C(n,i)}function w(n,e,t){return n===null?null:n===e?{...n,splitPercentage:t}:n.type==="split"?{...n,first:w(n.first,e,t)||n.first,second:w(n.second,e,t)||n.second}:n}function P(n,e){return n===null?null:n.type==="pane"?n.id===e?n:null:n.type==="split"?P(n.first,e)??P(n.second,e):null}function N(n,e){return n===null?null:n.type==="pane"?n.tabIds.includes(e)?n:null:n.type==="split"?N(n.first,e)??N(n.second,e):null}function j(n,e){let t=N(n,e);if(!t)return null;let r=t.tabIds.indexOf(e);return {id:e,paneId:t.id,isActive:t.activeTabId===e,index:r,metadata:void 0}}function S(n,e,t){if(n===null)return null;if(n.type==="pane"){if(n.id===e){if(t===false){let{locked:r,...i}=n;return i}return {...n,locked:t}}return n}return n.type==="split"?{...n,first:S(n.first,e,t)??n.first,second:S(n.second,e,t)??n.second}:n}function O(n,e,t){return n===null?null:n.type==="pane"?n.id===e?n.activeTabId===t?n:{...n,activeTabId:t}:n:n.type==="split"?{...n,first:O(n.first,e,t)??n.first,second:O(n.second,e,t)??n.second}:n}function I(n,e,t){if(n===null)return null;let r=m(n,e);if(r===null)return {type:"pane",id:b(),tabIds:[e],activeTabId:e};function i(u){if(u.type==="pane"){if(u.id===t){let s=[...u.tabIds];return s.includes(e)||s.push(e),{...u,tabIds:s,activeTabId:e}}return u}return u.type==="split"?{...u,first:i(u.first),second:i(u.second)}:u}return i(r)}function L(n,e,t){if(n===null)return null;if(e===t)return n;let r=N(n,e),i=N(n,t);if(!r||!i)return n;let u=r.id,s=i.id;function f(l){if(l.type==="pane"){let o=false,a=[...l.tabIds],p=l.activeTabId;if(u===s){if(l.id===u){let c=a.indexOf(e),d=a.indexOf(t);c!==-1&&d!==-1&&(a[c]=t,a[d]=e),p=e,o=true;}}else l.id===u&&(a=a.map(c=>c===e?t:c),p===e&&(p=t),o=true),l.id===s&&(a=a.map(c=>c===t?e:c),p===t&&(p=e),o=true);return o?{...l,tabIds:a,activeTabId:p}:l}return l.type==="split"?{...l,first:f(l.first),second:f(l.second)}:l}return f(n)}function h(n,e,t,r="before"){if(n===null)return null;if(e===t)return n;if(r==="center")return L(n,e,t);let i=m(n,e);if(i===null)return {type:"pane",id:b(),tabIds:[e],activeTabId:e};function u(s){if(s.type==="pane"){if(s.tabIds.includes(t)){let l=[...s.tabIds].filter(a=>a!==e),o=l.indexOf(t);return o<0&&(o=0),r==="after"&&(o+=1),l.splice(o,0,e),{...s,tabIds:l,activeTabId:e}}return s}return s.type==="split"?{...s,first:u(s.first),second:u(s.second)}:s}return u(i)}function y(n,e=0,t=0,r=100,i=100,u="root"){if(n===null)return {panes:[],splitters:[]};if(n.type==="pane")return {panes:[{paneId:n.id,left:e,top:t,width:r,height:i,node:n}],splitters:[]};let{direction:s,splitPercentage:f,first:l,second:o}=n,p={id:`splitter-${u}-${s}`,currentNode:n,direction:s,left:s==="row"?e+r*(f/100):e,top:s==="column"?t+i*(f/100):t,width:s==="row"?0:r,height:s==="column"?0:i,parentLeft:e,parentTop:t,parentWidth:r,parentHeight:i},c={panes:[],splitters:[]},d={panes:[],splitters:[]};if(s==="row"){let T=r*(f/100);c=y(l,e,t,T,i,`${u}-L`),d=y(o,e+T,t,r-T,i,`${u}-R`);}else {let T=i*(f/100);c=y(l,e,t,r,T,`${u}-T`),d=y(o,e,t+T,r,i-T,`${u}-B`);}return {panes:[...c.panes,...d.panes],splitters:[p,...c.splitters,...d.splitters]}}function R(n,e,t,r="before"){if(n===null)return null;let i=P(n,e);if(!i)return n;let u=i.tabIds,s=i.activeTabId,f=x(n,e);if(f===null)return i;function l(o){if(o.type==="pane"){if(o.tabIds.includes(t)){let p=[...o.tabIds].filter(d=>!u.includes(d)),c=p.indexOf(t);return c<0&&(c=0),r==="after"&&(c+=1),p.splice(c,0,...u),{...o,tabIds:p,activeTabId:s}}return o}return o.type==="split"?{...o,first:l(o.first),second:l(o.second)}:o}return l(f)}function q(n,e,t,r){if(!((e==="tab"||e==="pane")&&t&&n.includes(t))||!r)return -1;let s=n.indexOf(t);return r==="before"?s:s+1}function g(n,e){if(n===e)return true;if(!n||!e)return false;let t=Object.keys(n),r=Object.keys(e);if(t.length!==r.length)return false;for(let i of t){if(!Object.prototype.hasOwnProperty.call(e,i))return false;let u=n[i],s=e[i];if(typeof u=="object"&&u!==null&&typeof s=="object"&&s!==null){if(!g(u,s))return false}else if(u!==s)return false}return true}function B(n,e){if(n===e)return true;if(!n||!e)return false;let t=Object.keys(n),r=Object.keys(e);if(t.length!==r.length)return false;for(let i of t)if(!Object.prototype.hasOwnProperty.call(e,i)||!g(n[i],e[i]))return false;return true}function k(n,e){if(n===e)return true;if(!n||!e||n.type!==e.type)return false;if(n.type==="split"){let t=e;return n.direction===t.direction&&n.splitPercentage===t.splitPercentage&&k(n.first,t.first)&&k(n.second,t.second)}else {let t=e;if(n.id!==t.id||n.activeTabId!==t.activeTabId||n.locked!==t.locked||n.tabIds.length!==t.tabIds.length)return false;for(let r=0;r<n.tabIds.length;r++)if(n.tabIds[r]!==t.tabIds[r])return false;return true}}export{D as addTab,k as areLayoutsEqual,B as areMetadataEqual,g as areObjectsEqual,q as calculateTabDropIndex,y as computeLayout,P as findPaneById,N as findPaneContainingTab,j as findTabById,b as generateUniqueId,C as insertLeaf,I as mergeTab,R as movePaneTabs,h as moveTab,x as removePane,m as removeTab,O as selectTab,v as splitPane,L as swapTabs,S as updatePaneLock,w as updateSplitPercentage};//# sourceMappingURL=utils.js.map
2
2
  //# sourceMappingURL=utils.js.map