regular-layout 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,21 @@
1
- # `<regular-layout>`
1
+ <br />
2
+ <a href="https://perspective-dev.github.io">
3
+ <p align="center">
4
+ <picture>
5
+ <source media="(prefers-color-scheme: dark)" srcset="./logo.svg">
6
+ <img width="260" src="./logo.svg">
7
+ </picture>
8
+ <br/>
9
+ <br/>
10
+ <a href="https://www.npmjs.com/package/regular-table"><img alt="NPM Version" src="https://img.shields.io/github/actions/workflow/status/texodus/regular-layout/build.yaml?event=push&style=flat-square"></a>
11
+ <a href="https://www.npmjs.com/package/regular-table"><img alt="NPM Version" src="https://img.shields.io/npm/v/regular-layout.svg?color=brightgreen&style=flat-square"></a>
12
+ <a href="https://www.npmjs.com/package/regular-table"><img alt="Bundlephobia (Minified)" src="https://img.shields.io/bundlephobia/min/regular-layout?style=flat-square"></a>
13
+ <!-- <a href="https://www.npmjs.com/package/regular-table"><img alt="Bundlephobia (Minzipped)" src="https://img.shields.io/bundlephobia/minzip/regular-layout?style=flat-square"></a> -->
14
+ <br/>
15
+ <br/>
16
+ </p>
17
+
2
18
 
3
- [![Build Status](https://img.shields.io/github/actions/workflow/status/texodus/regular-layout/build.yaml?event=push&style=for-the-badge)](https://github.com/texodus/regular-layout/actions/workflows/build.yaml)
4
- [![npm](https://img.shields.io/npm/v/regular-layout.svg?style=for-the-badge)](https://www.npmjs.com/package/regular-layout)
5
19
 
6
20
  A library for resizable & repositionable panel layouts, using
7
21
  [CSS `grid`](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Grid_layout).
@@ -1,4 +1,4 @@
1
- import { type Layout, type LayoutPath } from "./layout_config";
1
+ import type { Layout, LayoutPath } from "./layout_config";
2
2
  /**
3
3
  * Calculates an insertion point (which may involve splitting a single
4
4
  * `"child-panel"` into a new `"split-panel"`), based on the cursor position.
@@ -12,4 +12,4 @@ import { type Layout, type LayoutPath } from "./layout_config";
12
12
  * @returns A new `LayoutPath` reflecting the updated (maybe) `"split-panel"`,
13
13
  * which is enough to draw the overlay.
14
14
  */
15
- export declare function calculate_split(col: number, row: number, panel: Layout, slot: string, drop_target: LayoutPath): LayoutPath;
15
+ export declare function calculate_edge(col: number, row: number, panel: Layout, slot: string, drop_target: LayoutPath): LayoutPath;
@@ -0,0 +1,29 @@
1
+ import type { OverlayMode } from "./layout_config";
2
+ /**
3
+ * The minimum number of pixels the mouse must move to be considered a drag.
4
+ */
5
+ export declare const MIN_DRAG_DISTANCE = 10;
6
+ /**
7
+ * Class name to use for child elements in overlay position (dragging).
8
+ */
9
+ export declare const OVERLAY_CLASSNAME = "overlay";
10
+ /**
11
+ * The percentage of the maximum resize distance that will be clamped.
12
+ *
13
+ */
14
+ export declare const MINIMUM_REDISTRIBUTION_SIZE_THRESHOLD = 0.15;
15
+ /**
16
+ * Threshold from panel edge that is considered a split vs drop action.
17
+ */
18
+ export declare const SPLIT_EDGE_TOLERANCE = 0.25;
19
+ /**
20
+ * Tolerance threshold for considering two grid track positions as identical.
21
+ *
22
+ * When collecting and deduplicating track positions, any positions closer than
23
+ * this value are treated as the same position to avoid redundant grid tracks.
24
+ */
25
+ export declare const GRID_TRACK_COLLAPSE_TOLERANCE = 0.001;
26
+ /**
27
+ * The overlay default behavior.
28
+ */
29
+ export declare const OVERLAY_DEFAULT: OverlayMode;
@@ -1,4 +1,4 @@
1
- import { type Layout } from "./layout_config.ts";
1
+ import type { Layout } from "./layout_config.ts";
2
2
  /**
3
3
  * Generates CSS Grid styles to render a layout tree.
4
4
  * Creates grid-template-rows, grid-template-columns, and positioning rules for
@@ -1,2 +1,2 @@
1
1
  import type { LayoutPath } from "./layout_config";
2
- export declare function updateOverlaySheet({ view_window: { row_start, row_end, col_start, col_end }, box, }: LayoutPath<DOMRect>): string;
2
+ export declare function updateOverlaySheet(slot: string, { view_window: { row_start, row_end, col_start, col_end }, box, }: LayoutPath<DOMRect>): string;
@@ -1,27 +1,7 @@
1
- /**
2
- * The percentage of the maximum resize distance that will be clamped.
3
- *
4
- */
5
- export declare const MINIMUM_REDISTRIBUTION_SIZE_THRESHOLD = 0.15;
6
- /**
7
- * Threshold from panel edge that is considered a split vs drop action.
8
- */
9
- export declare const SPLIT_EDGE_TOLERANCE = 0.25;
10
- /**
11
- * Tolerance threshold for considering two grid track positions as identical.
12
- *
13
- * When collecting and deduplicating track positions, any positions closer than
14
- * this value are treated as the same position to avoid redundant grid tracks.
15
- */
16
- export declare const GRID_TRACK_COLLAPSE_TOLERANCE = 0.001;
17
- /**
18
- * The overlay default behavior.
19
- */
20
- export declare const OVERLAY_DEFAULT: OverlayMode;
21
1
  /**
22
2
  * The overlay behavior type.
23
3
  */
24
- export type OverlayMode = "grid" | "absolute" | "interactive";
4
+ export type OverlayMode = "grid" | "absolute";
25
5
  /**
26
6
  * The representation of a CSS grid, in JSON form.
27
7
  */
@@ -83,6 +63,8 @@ export interface LayoutPath<T = undefined> {
83
63
  panel: TabLayout;
84
64
  path: number[];
85
65
  view_window: ViewWindow;
66
+ column: number;
67
+ row: number;
86
68
  column_offset: number;
87
69
  row_offset: number;
88
70
  orientation: Orientation;
@@ -1,4 +1,4 @@
1
- import { type Layout } from "./layout_config.ts";
1
+ import type { Layout } from "./layout_config.ts";
2
2
  /**
3
3
  * Adjusts panel sizes during a drag operation on a divider.
4
4
  *
@@ -1,6 +1,6 @@
1
1
  import { RegularLayout } from "./regular-layout.ts";
2
2
  import { RegularLayoutFrame } from "./regular-layout-frame.ts";
3
- import { Layout } from "./common/layout_config.ts";
3
+ import type { Layout } from "./common/layout_config.ts";
4
4
  declare global {
5
5
  interface Document {
6
6
  createElement(tagName: "regular-layout", options?: ElementCreationOptions): RegularLayout;
@@ -17,15 +17,13 @@ declare global {
17
17
  addEventListener(name: "regular-layout-update", cb: (e: RegularLayoutEvent) => void, options?: {
18
18
  signal: AbortSignal;
19
19
  }): void;
20
- removeEventListener(name: "regular-layout-update", cb: any): void;
20
+ addEventListener(name: "regular-layout-before-update", cb: (e: RegularLayoutEvent) => void, options?: {
21
+ signal: AbortSignal;
22
+ }): void;
23
+ removeEventListener(name: "regular-layout-update", cb: (e: RegularLayoutEvent) => void): void;
24
+ removeEventListener(name: "regular-layout-before-update", cb: (e: RegularLayoutEvent) => void): void;
21
25
  }
22
26
  }
23
27
  export interface RegularLayoutEvent extends CustomEvent {
24
28
  detail: Layout;
25
29
  }
26
- export interface PerspectiveViewerElementExt {
27
- addEventListener(name: "regular-layout-update", cb: (e: RegularLayoutEvent) => void, options?: {
28
- signal: AbortSignal;
29
- }): void;
30
- removeEventListener(name: "regular-layout-update", cb: any): void;
31
- }
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
- var S="absolute";function*C(i){if(i.type==="split-panel")for(let t of i.children)yield*C(t);else yield*i.child}var g={type:"split-panel",orientation:"horizontal",sizes:[],children:[]};function m(i,t){if(i.type==="child-panel"){if(i.child.includes(t)){let n=i.child.filter(l=>l!==t);return n.length===0?structuredClone(g):{type:"child-panel",child:n}}return structuredClone(i)}let o=structuredClone(i),r=o.children.findIndex(n=>n.type==="child-panel"?n.child.includes(t):!1);if(r!==-1){let n=o.children[r];if(n.child.length===1){let l=o.children.filter((u,h)=>h!==r),c=A(o.sizes,r);if(l.length===1)return l[0];o.children=l,o.sizes=c}else n.child.splice(n.child.indexOf(t),1),n.selected&&n.selected>=n.child.length&&n.selected--;return o}let e=!1,s=o.children.map(n=>{if(n.type==="split-panel"){let l=m(n,t);return l!==n&&(e=!0),l}return n});return e&&(o.children=s),o}function A(i,t){let o=[],r=i[t],e=0;for(let s=0;s<i.length;s++)s!==t&&(e+=i[s]);for(let s=0;s<i.length;s++)if(s!==t){let n=i[s]/e;o.push(i[s]+r*n)}return o}function D(i){if(i.length===0)return[];let t=i.sort((r,e)=>r-e),o=[t[0]];for(let r=1;r<t.length;r++)Math.abs(t[r]-o[o.length-1])>.001&&o.push(t[r]);return o}function P(i,t,o,r){if(i.type==="child-panel")return[o,r];if(i.orientation===t){let e=[o,r],s=o;for(let n=0;n<i.children.length;n++){let l=i.sizes[n],c=P(i.children[n],t,s,s+l*(r-o));e.push(...c),s=s+l*(r-o)}return D(e)}else{let e=[o,r];for(let s of i.children){let n=P(s,t,o,r);e.push(...n)}return D(e)}}function E(i,t){for(let o=0;o<i.length;o++)if(Math.abs(i[o]-t)<.001)return o;throw new Error(`Position ${t} not found in ${i}`)}function z(i,t,o,r,e,s,n){if(i.type==="child-panel"){let a=i.selected??0;return[{child:i.child[a],colStart:E(t,r),colEnd:E(t,e),rowStart:E(o,s),rowEnd:E(o,n)}]}let l=[],{children:c,sizes:u,orientation:h}=i;if(h==="horizontal"){let a=r;for(let d=0;d<c.length;d++){let _=a+u[d]*(e-r);l.push(...z(c[d],t,o,a,_,s,n)),a=_}}else{let a=s;for(let d=0;d<c.length;d++){let _=a+u[d]*(n-s);l.push(...z(c[d],t,o,r,e,a,_)),a=_}}return l}var O=(i,t)=>`:host { display: grid; gap: 0px; grid-template-rows: ${i}; grid-template-columns: ${t}; }`,T=(i,t,o)=>`:host ::slotted([slot=${i}]) { grid-column: ${o}; grid-row: ${t}; }`;function b(i,t=!1,o){if(o&&(i=m(i,o[0])),i.type==="child-panel"){let a=i.selected??0;return`${O("100%","100%")}
2
- ${T(i.child[a],"1","1")}`}let r=P(i,"horizontal",0,1),e=[];for(let a=0;a<r.length-1;a++)e.push(r[a+1]-r[a]);let s=e.map(a=>`${t?Math.round(a*100):a*100}%`).join(" "),n=P(i,"vertical",0,1),l=[];for(let a=0;a<n.length-1;a++)l.push(n[a+1]-n[a]);let c=l.map(a=>`${t?Math.round(a*100):a*100}%`).join(" "),u=z(i,r,n,0,1,0,1),h=[O(c,s)];for(let a of u){let d=a.colEnd-a.colStart===1?`${a.colStart+1}`:`${a.colStart+1} / ${a.colEnd+1}`,_=a.rowEnd-a.rowStart===1?`${a.rowStart+1}`:`${a.rowStart+1} / ${a.rowEnd+1}`;h.push(`${T(a.child,_,d)}`),a.child===o?.[1]&&(h.push(`${T(o[0],_,d)}`),h.push(`:host ::slotted([slot=${o[0]}]) { z-index: 1; }`))}return h.join(`
3
- `)}function p(i,t,o,r=!0){return R(i,t,o,r)}var N={row_start:0,row_end:1,col_start:0,col_end:1};function R(i,t,o,r,e=null,s=structuredClone(N),n=[]){if(i<0||t<0||i>1||t>1)return null;if(o.type==="child-panel"){let l=o.selected??0,c=(i-s.col_start)/(s.col_end-s.col_start),u=(t-s.row_start)/(s.row_end-s.row_start);return{type:"layout-path",box:void 0,slot:o.child[l],panel:structuredClone(o),path:n,view_window:s,is_edge:!1,column_offset:c,row_offset:u,orientation:e||"horizontal"}}if(o.orientation==="vertical"){let l=s.row_start;for(let c=0;c<o.children.length;c++){let h=(s.row_end-s.row_start)*o.sizes[c]+l;if(r&&Math.abs(t-h)<.01)return{path:[...n,c],type:"vertical",view_window:{...s,row_start:l,row_end:h}};if(t>=l&&t<h)return R(i,t,o.children[c],r,"vertical",{...s,row_start:l,row_end:h},[...n,c]);l=h}}else{let l=s.col_start;for(let c=0;c<o.children.length;c++){let u=s.col_end-s.col_start,h=l+u*o.sizes[c];if(r&&Math.abs(i-h)<.01)return{path:[...n,c],type:"horizontal",view_window:{...s,col_start:l,col_end:h}};if(i>=l&&i<h)return R(i,t,o.children[c],r,"horizontal",{...s,col_start:l,col_end:h},[...n,c]);l=h}}return null}function f(i,t,o,r="horizontal",e){if(o.length===0){if(i.type==="child-panel")return{type:"child-panel",child:[t,...i.child]};{let h=[...i.children,{type:"child-panel",child:[t]}],a=h.length,d=Array(a).fill(1/a);return{...i,children:h,sizes:d}}}let[s,...n]=o;if(i.type==="child-panel")return f({type:"split-panel",orientation:r,children:[i],sizes:[1]},t,o,r,e);if(n.length===0||s===i.children.length){if(e&&i.children[s]?.type==="child-panel")return i.children[s].child.unshift(t),i;let h=[...i.children];h.splice(s,0,{type:"child-panel",child:[t]});let a=h.length,d=Array(a).fill(1/a);return{...i,children:h,sizes:d}}let l=i.children[s];if(l.type==="child-panel"&&n.length>0){let h=i.orientation==="horizontal"?"vertical":"horizontal",a=f(l,t,n,h,e),d=[...i.children];return d[s]=a,{...i,children:d}}let c=f(l,t,n,r,e),u=[...i.children];return u[s]=c,{...i,children:u}}function w(i,t,o){let r=structuredClone(i),e=r,s={horizontal:o,vertical:o};for(let n=0;n<t.length-1;n++)e.type==="split-panel"&&(s[e.orientation]/=e.sizes[t[n]],e=e.children[t[n]]);if(e.type==="split-panel"){let n=s[e.orientation],l=t[t.length-1];l<e.sizes.length-1&&(e.sizes=H(e.sizes,l,n))}return r}function H(i,t,o){let r=[...i],e=0;for(let n=0;n<=t;n++)e+=i[n];let s=0;for(let n=t+1;n<i.length;n++)s+=i[n];o=Math.sign(o)*Math.min(Math.abs(o),(1-.15)*(o>0?e:s));for(let n=0;n<=t;n++){let l=i[n]/e;r[n]=i[n]-o*l}for(let n=t+1;n<i.length;n++){let l=i[n]/s;r[n]=i[n]+o*l}return r}function $({view_window:{row_start:i,row_end:t,col_start:o,col_end:r},box:e}){let n=i*e.height+0,l=o*e.width+0/2,c=(t-i)*e.height-0,u=(r-o)*e.width-0;return`::slotted(:not([slot])){${`position:absolute!important;z-index:1;top:${n}px;left:${l}px;height:${c}px;width:${u}px;`}}`}function M(i,t,o,r,e){if(e.column_offset<.25||e.column_offset>1-.25){if(e.orientation==="horizontal"){let s=e.column_offset<.25;if(e.path.length===0){let l=f(o,r,[s?0:1]);s?e=p(i,t,l,!1):e={...p(i,t,l,!1),path:[0]}}else{let n=e.path.slice(0,-1),l=e.path[e.path.length-1],c=s?l:l+1,u=f(o,r,[...n,c]);s?e=p(i,t,u,!1):e={...p(i,t,u,!1),path:[...n,l]}}}else{let s=e.column_offset<.25?0:1,n=e.path,l=f(o,r,[...n,s],"horizontal");e=p(i,t,l,!1),e={...e,slot:r,path:[...n,s]}}e&&(e.is_edge=!0)}else if(e.row_offset<.25||e.row_offset>1-.25){if(e.orientation==="vertical"){let s=e.row_offset<.25;if(e.path.length===0){let l=f(o,r,[s?0:1]);s?e=p(i,t,l,!1):e={...p(i,t,l,!1),path:[0]}}else{let n=e.path.slice(0,-1),l=e.path[e.path.length-1],c=s?l:l+1,u=f(o,r,[...n,c]);s?e=p(i,t,u,!1):e={...p(i,t,u,!1),path:[...n,l]}}}else{let s=e.row_offset<.25?0:1,n=e.path,l=f(o,r,[...n,s],"vertical");e=p(i,t,l,!1),e={...e,slot:r,path:[...n,s]}}e&&(e.is_edge=!0)}return e}function x(i){if(i.type==="child-panel")return i;let t=[],o=[];for(let r=0;r<i.children.length;r++){let e=i.children[r],s=i.sizes[r],n=x(e);if(n.type==="split-panel"&&n.orientation===i.orientation)for(let l=0;l<n.children.length;l++)t.push(n.children[l]),o.push(n.sizes[l]*s);else t.push(n),o.push(s)}return t.length===1?t[0]:{type:"split-panel",orientation:i.orientation,children:t,sizes:o}}var L=class extends HTMLElement{_shadowRoot;_panel;_stylesheet;_dragPath;_slots;_unslotted_slot;constructor(){super(),this._panel=structuredClone(g),this._stylesheet=new CSSStyleSheet,this._unslotted_slot=document.createElement("slot"),this._shadowRoot=this.attachShadow({mode:"open"}),this._shadowRoot.adoptedStyleSheets=[this._stylesheet],this._shadowRoot.appendChild(this._unslotted_slot),this._slots=new Map,this.onPointerDown=this.onPointerDown.bind(this),this.onPointerMove=this.onPointerMove.bind(this),this.onPointerUp=this.onPointerUp.bind(this)}connectedCallback(){this.addEventListener("pointerdown",this.onPointerDown),this.addEventListener("pointerup",this.onPointerUp),this.addEventListener("pointermove",this.onPointerMove)}disconnectedCallback(){this.removeEventListener("pointerdown",this.onPointerDown),this.removeEventListener("pointerup",this.onPointerUp),this.removeEventListener("pointermove",this.onPointerMove)}setOverlayState(t,o,{slot:r},e=S){let s=this._panel;e==="absolute"&&(s=m(s,r),this._slots.get(r)?.assignedElements()[0]?.removeAttribute("slot"));let[n,l,c]=this.relativeCoordinates(t,o),u=p(n,l,s,!1);if(u){if(u=M(n,l,s,r,u),e==="interactive"){let a=m(this._panel,r);a=x(f(a,r,u.path));let d=b(a);this._stylesheet.replaceSync(d)}else if(e==="grid"){let a=[r,u.slot],d=b(this._panel,!1,a);this._stylesheet.replaceSync(d)}else if(e==="absolute"){let a=`${b(s)}
4
- ${$({...u,box:c})}`;this._stylesheet.replaceSync(a)}}else{let a=`${b(s)}}`;this._stylesheet.replaceSync(a)}let h=new CustomEvent("regular-layout-update",{detail:s});this.dispatchEvent(h)}clearOverlayState(t,o,r,e=S){let s=this._panel;e==="absolute"&&(s=m(s,r.slot),this._unslotted_slot.assignedElements()[0]?.setAttribute("slot",r.slot));let[n,l,c]=this.relativeCoordinates(t,o),u=p(n,l,s,!1);u&&(u=M(n,l,s,r.slot,u));let{path:h,orientation:a}=u||r;this.restore(f(s,r.slot,h,a,!u?.is_edge))}insertPanel(t,o=[]){this.restore(f(this._panel,t,o))}removePanel(t){this.restore(m(this._panel,t))}getPanel(t,o=this._panel){if(o.type==="child-panel")return o.child.includes(t)?o:null;for(let r of o.children){let e=this.getPanel(t,r);if(e)return e}return null}calculateIntersect(t,o,r=!1){let[e,s,n]=this.relativeCoordinates(t,o),l=p(e,s,this._panel,r);return l?.type==="layout-path"?{...l,box:n}:null}clear(){this.restore(g)}restore(t,o=!1){this._panel=o?t:x(t);let r=b(t);this._stylesheet.replaceSync(r);let e=new Set(this._slots.keys());for(let n of C(t))if(e.delete(n),!this._slots.has(n)){let l=document.createElement("slot");l.setAttribute("name",n),this._shadowRoot.appendChild(l),this._slots.set(n,l)}for(let n of e){let l=this._slots.get(n);l&&(this._shadowRoot.removeChild(l),this._slots.delete(n))}let s=new CustomEvent("regular-layout-update",{detail:t});this.dispatchEvent(s)}save(){return structuredClone(this._panel)}relativeCoordinates(t,o){let r=this.getBoundingClientRect(),e=(t-r.left)/(r.right-r.left),s=(o-r.top)/(r.bottom-r.top);return[e,s,r]}onPointerDown(t){if(t.target===this){let[o,r]=this.relativeCoordinates(t.clientX,t.clientY),e=p(o,r,this._panel);e&&e.type!=="layout-path"&&(this._dragPath=[e,o,r],this.setPointerCapture(t.pointerId))}}onPointerMove(t){if(this._dragPath){let[o,r]=this.relativeCoordinates(t.clientX,t.clientY),e=this._panel,[{path:s,type:n},l,c]=this._dragPath,u=n==="horizontal"?l-o:c-r,h=w(e,s,u);this._stylesheet.replaceSync(b(h))}}onPointerUp(t){if(this._dragPath){this.releasePointerCapture(t.pointerId);let[o,r]=this.relativeCoordinates(t.clientX,t.clientY),e=this._panel,[{path:s},n,l]=this._dragPath;if(this._dragPath[0].type==="horizontal"){let c=w(e,s,n-o);this.restore(c,!0)}else{let c=w(e,s,l-r);this.restore(c,!0)}this._dragPath=void 0}}};var k=`
1
+ function*C(r){if(r.type==="split-panel")for(let t of r.children)yield*C(t);else yield r.child[r.selected||0]}var b={type:"split-panel",orientation:"horizontal",sizes:[],children:[]};var m="overlay";var x="absolute";function y(r,t){if(r.type==="child-panel"){if(r.child.includes(t)){let o=r.child.filter(a=>a!==t);return o.length===0?structuredClone(b):{type:"child-panel",child:o}}return structuredClone(r)}let e=structuredClone(r),i=e.children.findIndex(o=>o.type==="child-panel"?o.child.includes(t):!1);if(i!==-1){let o=e.children[i];if(o.child.length===1){let a=e.children.filter((h,c)=>c!==i),u=H(e.sizes,i);if(a.length===1)return a[0];e.children=a,e.sizes=u}else o.child.splice(o.child.indexOf(t),1),o.selected&&o.selected>=o.child.length&&o.selected--;return e}let n=!1,s=e.children.map(o=>{if(o.type==="split-panel"){let a=y(o,t);return a!==o&&(n=!0),a}return o});return n&&(e.children=s),e}function H(r,t){let e=[],i=r[t],n=0;for(let s=0;s<r.length;s++)s!==t&&(n+=r[s]);for(let s=0;s<r.length;s++)if(s!==t){let o=r[s]/n;e.push(r[s]+i*o)}return e}function D(r){if(r.length===0)return[];let t=r.sort((i,n)=>i-n),e=[t[0]];for(let i=1;i<t.length;i++)Math.abs(t[i]-e[e.length-1])>.001&&e.push(t[i]);return e}function S(r,t,e,i){if(r.type==="child-panel")return[e,i];if(r.orientation===t){let n=[e,i],s=e;for(let o=0;o<r.children.length;o++){let a=r.sizes[o],u=S(r.children[o],t,s,s+a*(i-e));n.push(...u),s=s+a*(i-e)}return D(n)}else{let n=[e,i];for(let s of r.children){let o=S(s,t,e,i);n.push(...o)}return D(n)}}function P(r,t){for(let e=0;e<r.length;e++)if(Math.abs(r[e]-t)<.001)return e;throw new Error(`Position ${t} not found in ${r}`)}function M(r,t,e,i,n,s,o){if(r.type==="child-panel"){let l=r.selected??0;return[{child:r.child[l],colStart:P(t,i),colEnd:P(t,n),rowStart:P(e,s),rowEnd:P(e,o)}]}let a=[],{children:u,sizes:h,orientation:c}=r;if(c==="horizontal"){let l=i;for(let d=0;d<u.length;d++){let p=l+h[d]*(n-i);a.push(...M(u[d],t,e,l,p,s,o)),l=p}}else{let l=s;for(let d=0;d<u.length;d++){let p=l+h[d]*(o-s);a.push(...M(u[d],t,e,i,n,l,p)),l=p}}return a}var A=(r,t)=>`:host { display: grid; gap: 0px; grid-template-rows: ${r}; grid-template-columns: ${t}; }`,T=(r,t,e)=>`:host ::slotted([slot=${r}]) { grid-column: ${e}; grid-row: ${t}; }`;function g(r,t=!1,e){if(e&&(r=y(r,e[0])),r.type==="child-panel"){let l=r.selected??0;return`${A("100%","100%")}
2
+ ${T(r.child[l],"1","1")}`}let i=S(r,"horizontal",0,1),n=[];for(let l=0;l<i.length-1;l++)n.push(i[l+1]-i[l]);let s=n.map(l=>`${t?Math.round(l*100):l*100}%`).join(" "),o=S(r,"vertical",0,1),a=[];for(let l=0;l<o.length-1;l++)a.push(o[l+1]-o[l]);let u=a.map(l=>`${t?Math.round(l*100):l*100}%`).join(" "),h=M(r,i,o,0,1,0,1),c=[A(u,s)];for(let l of h){let d=l.colEnd-l.colStart===1?`${l.colStart+1}`:`${l.colStart+1} / ${l.colEnd+1}`,p=l.rowEnd-l.rowStart===1?`${l.rowStart+1}`:`${l.rowStart+1} / ${l.rowEnd+1}`;c.push(`${T(l.child,p,d)}`),l.child===e?.[1]&&(c.push(`${T(e[0],p,d)}`),c.push(`:host ::slotted([slot=${e[0]}]) { z-index: 1; }`))}return c.join(`
3
+ `)}function f(r,t,e,i=!0){return R(r,t,e,i)}var k={row_start:0,row_end:1,col_start:0,col_end:1};function R(r,t,e,i,n=null,s=structuredClone(k),o=[]){if(r<0||t<0||r>1||t>1)return null;if(e.type==="child-panel"){let a=e.selected??0,u=(r-s.col_start)/(s.col_end-s.col_start),h=(t-s.row_start)/(s.row_end-s.row_start);return{type:"layout-path",box:void 0,slot:e.child[a],panel:structuredClone(e),path:o,view_window:s,is_edge:!1,column:r,row:t,column_offset:u,row_offset:h,orientation:n||"horizontal"}}if(e.orientation==="vertical"){let a=s.row_start;for(let u=0;u<e.children.length;u++){let c=(s.row_end-s.row_start)*e.sizes[u]+a;if(i&&Math.abs(t-c)<.01)return{path:[...o,u],type:"vertical",view_window:{...s,row_start:a,row_end:c}};if(t>=a&&t<c)return R(r,t,e.children[u],i,"vertical",{...s,row_start:a,row_end:c},[...o,u]);a=c}}else{let a=s.col_start;for(let u=0;u<e.children.length;u++){let h=s.col_end-s.col_start,c=a+h*e.sizes[u];if(i&&Math.abs(r-c)<.01)return{path:[...o,u],type:"horizontal",view_window:{...s,col_start:a,col_end:c}};if(r>=a&&r<c)return R(r,t,e.children[u],i,"horizontal",{...s,col_start:a,col_end:c},[...o,u]);a=c}}return null}function _(r,t,e,i="horizontal",n){if(e.length===0){if(r.type==="child-panel")return{type:"child-panel",child:[t,...r.child]};{let c=[...r.children,{type:"child-panel",child:[t]}],l=c.length,d=Array(l).fill(1/l);return{...r,children:c,sizes:d}}}let[s,...o]=e;if(r.type==="child-panel")return _({type:"split-panel",orientation:i,children:[r],sizes:[1]},t,e,i,n);if(o.length===0||s===r.children.length){if(n&&r.children[s]?.type==="child-panel")return r.children[s].child.unshift(t),r.children[s].selected=0,r;let c=[...r.children];c.splice(s,0,{type:"child-panel",child:[t]});let l=c.length,d=Array(l).fill(1/l);return{...r,children:c,sizes:d}}let a=r.children[s];if(a.type==="child-panel"&&o.length>0){let c=r.orientation==="horizontal"?"vertical":"horizontal",l=_(a,t,o,c,n),d=[...r.children];return d[s]=l,{...r,children:d}}let u=_(a,t,o,i,n),h=[...r.children];return h[s]=u,{...r,children:h}}function w(r,t,e){let i=structuredClone(r),n=i,s={horizontal:e,vertical:e};for(let o=0;o<t.length-1;o++)n.type==="split-panel"&&(s[n.orientation]/=n.sizes[t[o]],n=n.children[t[o]]);if(n.type==="split-panel"){let o=s[n.orientation],a=t[t.length-1];a<n.sizes.length-1&&(n.sizes=U(n.sizes,a,o))}return i}function U(r,t,e){let i=[...r],n=0;for(let o=0;o<=t;o++)n+=r[o];let s=0;for(let o=t+1;o<r.length;o++)s+=r[o];e=Math.sign(e)*Math.min(Math.abs(e),(1-.15)*(e>0?n:s));for(let o=0;o<=t;o++){let a=r[o]/n;i[o]=r[o]-e*a}for(let o=t+1;o<r.length;o++){let a=r[o]/s;i[o]=r[o]+e*a}return i}function $(r,{view_window:{row_start:t,row_end:e,col_start:i,col_end:n},box:s}){let a=t*s.height+0,u=i*s.width+0/2,h=(e-t)*s.height-0,c=(n-i)*s.width-0,l=`position:absolute!important;z-index:1;top:${a}px;left:${u}px;height:${h}px;width:${c}px;`;return`::slotted([slot="${r}"]){${l}}`}function z(r,t,e,i,n){let s=n.column_offset<.25||n.column_offset>1-.25,o=n.row_offset<.25||n.row_offset>1-.25;return s?N(r,t,e,i,n,n.column_offset,"horizontal"):o?N(r,t,e,i,n,n.row_offset,"vertical"):n}function N(r,t,e,i,n,s,o){let a=s<.25;if(n.orientation===o)if(n.path.length===0){let h=_(e,i,[a?0:1]);n=f(r,t,h,!1)}else{let u=n.path.slice(0,-1),h=n.path[n.path.length-1],c=a?h:h+1,l=_(e,i,[...u,c]);n=f(r,t,l,!1)}else{let u=[...n.path,a?0:1],h=_(e,i,u,o);n=f(r,t,h,!1)}return n.is_edge=!0,n}function O(r){if(r.type==="child-panel")return r.selected=r.selected||0,r;let t=[],e=[];for(let i=0;i<r.children.length;i++){let n=r.children[i],s=r.sizes[i],o=O(n);if(o.type==="split-panel"&&o.orientation===r.orientation)for(let a=0;a<o.children.length;a++)t.push(o.children[a]),e.push(o.sizes[a]*s);else t.push(o),e.push(s)}return t.length===1?t[0]:{type:"split-panel",orientation:r.orientation,children:t,sizes:e}}var v=class extends HTMLElement{_shadowRoot;_panel;_stylesheet;_dragPath;_slots;_unslotted_slot;constructor(){super(),this._panel=structuredClone(b),this._stylesheet=new CSSStyleSheet,this._unslotted_slot=document.createElement("slot"),this._shadowRoot=this.attachShadow({mode:"open"}),this._shadowRoot.adoptedStyleSheets=[this._stylesheet],this._shadowRoot.appendChild(this._unslotted_slot),this._slots=new Map}connectedCallback(){this.addEventListener("pointerdown",this.onPointerDown),this.addEventListener("pointerup",this.onPointerUp),this.addEventListener("pointermove",this.onPointerMove)}disconnectedCallback(){this.removeEventListener("pointerdown",this.onPointerDown),this.removeEventListener("pointerup",this.onPointerUp),this.removeEventListener("pointermove",this.onPointerMove)}setOverlayState=(t,e,{slot:i},n=m,s=x)=>{let o=this._panel;s==="absolute"&&(o=y(o,i),this.updateSlots(o,i),this._slots.get(i)?.assignedElements()[0]?.classList.add(n));let[a,u,h]=this.relativeCoordinates(t,e),c=f(a,u,o,!1);if(c){if(c=z(a,u,o,i,c),s==="grid"){let d=[i,c.slot],p=g(this._panel,!1,d);this._stylesheet.replaceSync(p)}else if(s==="absolute"){let d=g(o),p=$(i,{...c,box:h});this._stylesheet.replaceSync([d,p].join(`
4
+ `))}}else{let d=`${g(o)}}`;this._stylesheet.replaceSync(d)}let l=new CustomEvent("regular-layout-before-update",{detail:o});this.dispatchEvent(l)};clearOverlayState=(t,e,i,n=m,s=x)=>{let o=this._panel;s==="absolute"&&(o=y(o,i.slot),this._slots.get(i.slot)?.assignedElements()[0]?.classList.remove(n));let[a,u,h]=this.relativeCoordinates(t,e),c=f(a,u,o,!1);c&&(c=z(a,u,o,i.slot,c));let{path:l,orientation:d}=c||i;this.restore(_(o,i.slot,l,d,!c?.is_edge))};insertPanel=(t,e=[])=>{this.restore(_(this._panel,t,e))};removePanel=t=>{this.restore(y(this._panel,t))};getPanel=(t,e=this._panel)=>{if(e.type==="child-panel")return e.child.includes(t)?e:null;for(let i of e.children){let n=this.getPanel(t,i);if(n)return n}return null};calculateIntersect=(t,e,i=!1)=>{let[n,s,o]=this.relativeCoordinates(t,e),a=f(n,s,this._panel,i);return a?.type==="layout-path"?{...a,box:o}:null};clear=()=>{this.restore(b)};restore=(t,e=!1)=>{this._panel=e?t:O(t);let i=g(this._panel);this._stylesheet.replaceSync(i),this.updateSlots(this._panel);let n=new CustomEvent("regular-layout-update",{detail:this._panel});this.dispatchEvent(n)};save=()=>structuredClone(this._panel);relativeCoordinates=(t,e)=>{let i=this.getBoundingClientRect(),n=(t-i.left)/(i.right-i.left),s=(e-i.top)/(i.bottom-i.top);return[n,s,i]};updateSlots=(t,e)=>{let i=new Set(this._slots.keys());e&&i.delete(e);for(let n of C(t))if(i.delete(n),!this._slots.has(n)){let s=document.createElement("slot");s.setAttribute("name",n),this._shadowRoot.appendChild(s),this._slots.set(n,s)}for(let n of i){let s=this._slots.get(n);s&&(this._shadowRoot.removeChild(s),this._slots.delete(n))}};onPointerDown=t=>{if(t.target===this){let[e,i]=this.relativeCoordinates(t.clientX,t.clientY),n=f(e,i,this._panel);n&&n.type!=="layout-path"&&(this._dragPath=[n,e,i],this.setPointerCapture(t.pointerId),t.preventDefault())}};onPointerMove=t=>{if(this._dragPath){let[e,i]=this.relativeCoordinates(t.clientX,t.clientY),n=this._panel,[{path:s,type:o},a,u]=this._dragPath,h=o==="horizontal"?a-e:u-i,c=w(n,s,h);this._stylesheet.replaceSync(g(c))}};onPointerUp=t=>{if(this._dragPath){this.releasePointerCapture(t.pointerId);let[e,i]=this.relativeCoordinates(t.clientX,t.clientY),n=this._panel,[{path:s},o,a]=this._dragPath;if(this._dragPath[0].type==="horizontal"){let u=w(n,s,o-e);this.restore(u,!0)}else{let u=w(n,s,a-i);this.restore(u,!0)}this._dragPath=void 0}}};var G=r=>`
5
5
  :host{--titlebar--height:24px;box-sizing:border-box}
6
- :host([slot]){margin-top:calc(var(--titlebar--height) + 3px)!important;}
7
- :host([slot])::part(container){position:absolute;top:0;left:0;right:0;bottom:0;display:flex;flex-direction:column;background-color:inherit;border-radius:inherit}
8
- :host([slot])::part(titlebar){height:var(--titlebar--height);margin-top:calc(0px - var(--titlebar--height));user-select: none;}
9
- :host([slot])::part(body){flex:1 1 auto;}
10
- `,Y='<slot part="container"><slot part="titlebar"></slot><slot part="body"><slot></slot></slot></slot>',v=class extends HTMLElement{_shadowRoot;_container_sheet;_layout;_header;_drag_state=null;_drag_moved=!1;_tab_to_index_map=new WeakMap;constructor(){super(),this._container_sheet=new CSSStyleSheet,this._container_sheet.replaceSync(k),this._shadowRoot=this.attachShadow({mode:"open"}),this._shadowRoot.adoptedStyleSheets=[this._container_sheet],this.drawTabs=this.drawTabs.bind(this),this.onPointerDown=this.onPointerDown.bind(this),this.onPointerMove=this.onPointerMove.bind(this),this.onPointerUp=this.onPointerUp.bind(this),this.onPointerLost=this.onPointerLost.bind(this)}connectedCallback(){this._shadowRoot.innerHTML=Y,this._layout=this.parentElement,this._header=this._shadowRoot.children[0].children[0],this._header.addEventListener("pointerdown",this.onPointerDown),this._header.addEventListener("pointermove",this.onPointerMove),this._header.addEventListener("pointerup",this.onPointerUp),this._header.addEventListener("lostpointercapture",this.onPointerLost),this._layout.addEventListener("regular-layout-update",this.drawTabs)}disconnectedCallback(){this._header.removeEventListener("pointerdown",this.onPointerDown),this._header.removeEventListener("pointermove",this.onPointerMove),this._header.removeEventListener("pointerup",this.onPointerUp),this._header.removeEventListener("lostpointercapture",this.onPointerLost),this._layout.removeEventListener("regular-layout-update",this.drawTabs)}drawTabs(t){let o=this.getAttribute("slot");if(o){let r=this._layout.getPanel(o,t.detail);if(this._header.textContent="",!r)return;for(let e=0;e<(r?.child?.length||0);e++){let s=r?.child[e],n=document.createElement("div");this._tab_to_index_map.set(n,e),n.textContent=s||"",n.setAttribute("part",e===(r?.selected||0)?"tab active-tab":"tab");let l=e;e!==(r?.selected||0)&&n.addEventListener("pointerdown",c=>{r.selected=l,this._layout.restore(t.detail),c.preventDefault(),c.stopImmediatePropagation(),c.stopPropagation()}),this._header.appendChild(n)}}}onPointerDown=t=>{if(this._drag_state=this._layout.calculateIntersect(t.clientX,t.clientY),this._drag_state){let o=t.target;if(o.part.contains("tab")){let r=this._drag_state.path.length-1,e=this._tab_to_index_map.get(o);e&&(this._drag_state.path[r]=e)}this._header.setPointerCapture(t.pointerId)}};onPointerMove=t=>{this._drag_state&&(this._drag_moved=!0,this._layout.setOverlayState(t.clientX,t.clientY,this._drag_state))};onPointerUp=t=>{this._drag_state&&this._drag_moved&&this._layout.clearOverlayState(t.clientX,t.clientY,this._drag_state),this._header.releasePointerCapture(t.pointerId),this._drag_state=null,this._drag_moved=!1};onPointerLost=t=>{this._drag_state&&this._layout.clearOverlayState(-1,-1,this._drag_state),this._header.releasePointerCapture(t.pointerId),this._drag_state=null,this._drag_moved=!1}};customElements.define("regular-layout",L);customElements.define("regular-layout-frame",v);export{L as RegularLayout,v as RegularLayoutFrame};
6
+ :host(:not(.${r})){margin-top:calc(var(--titlebar--height) + 3px)!important;}
7
+ :host(:not(.${r}))::part(container){position:absolute;top:0;left:0;right:0;bottom:0;display:flex;flex-direction:column;background-color:inherit;border-radius:inherit}
8
+ :host(:not(.${r}))::part(titlebar){height:var(--titlebar--height);margin-top:calc(0px - var(--titlebar--height));user-select: none;}
9
+ :host(:not(.${r}))::part(body){flex:1 1 auto;}
10
+ `,W='<slot part="container"><slot part="titlebar"></slot><slot part="body"><slot></slot></slot></slot>',E=class extends HTMLElement{_shadowRoot;_container_sheet;_layout;_header;_drag_state=null;_drag_moved=!1;_tab_to_index_map=new WeakMap;_tab_panel_state=null;constructor(){super(),this._container_sheet=new CSSStyleSheet,this._container_sheet.replaceSync(G(m)),this._shadowRoot=this.attachShadow({mode:"open"}),this._shadowRoot.adoptedStyleSheets=[this._container_sheet]}connectedCallback(){this._shadowRoot.innerHTML=W,this._layout=this.parentElement,this._header=this._shadowRoot.children[0].children[0],this._header.addEventListener("pointerdown",this.onPointerDown),this._header.addEventListener("pointermove",this.onPointerMove),this._header.addEventListener("pointerup",this.onPointerUp),this._header.addEventListener("lostpointercapture",this.onPointerLost),this._layout.addEventListener("regular-layout-update",this.drawTabs),this._layout.addEventListener("regular-layout-before-update",this.drawTabs)}disconnectedCallback(){this._header.removeEventListener("pointerdown",this.onPointerDown),this._header.removeEventListener("pointermove",this.onPointerMove),this._header.removeEventListener("pointerup",this.onPointerUp),this._header.removeEventListener("lostpointercapture",this.onPointerLost),this._layout.removeEventListener("regular-layout-update",this.drawTabs),this._layout.removeEventListener("regular-layout-before-update",this.drawTabs)}onPointerDown=t=>{let e=t.target;if(e.part.contains("tab")&&(this._drag_state=this._layout.calculateIntersect(t.clientX,t.clientY),this._drag_state)){this._header.setPointerCapture(t.pointerId),t.preventDefault();let i=this._drag_state.path.length-1,n=this._tab_to_index_map.get(e);n&&(this._drag_state.path[i]=n)}};onPointerMove=t=>{if(this._drag_state){if(!this._drag_moved){let[e,i,n]=this._layout.relativeCoordinates(t.clientX,t.clientY),s=(e-this._drag_state.column)*n.width,o=(i-this._drag_state.row)*n.height;if(Math.sqrt(s*s+o*o)<=10)return}this._drag_moved=!0,this._layout.setOverlayState(t.clientX,t.clientY,this._drag_state,m)}};onPointerUp=t=>{this._drag_state&&this._drag_moved&&this._layout.clearOverlayState(t.clientX,t.clientY,this._drag_state,m),this._header.releasePointerCapture(t.pointerId),this._drag_state=null,this._drag_moved=!1};onPointerLost=t=>{this._drag_state&&this._layout.clearOverlayState(-1,-1,this._drag_state),this._header.releasePointerCapture(t.pointerId),this._drag_state=null,this._drag_moved=!1};drawTabs=t=>{let e=this.assignedSlot;if(!e)return;let i=t.detail,n=this._layout.getPanel(e.name,i);if(!n)return;for(let o=0;o<n.child.length;o++)if(o>=this._header.children.length){let a=this.createTab(n,o);this._header.appendChild(a)}else{let a=o===n.selected!=(o===this._tab_panel_state?.selected),u=this._header.children[o];if(a||this._tab_panel_state?.child[o]!==n.child[o]){let c=this.createTab(n,o);this._header.replaceChild(c,u)}}let s=n.child.length;for(let o=this._header.children.length-1;o>=s;o--)this._header.removeChild(this._header.children[o]);this._tab_panel_state=n};createTab=(t,e)=>{let i=t.selected||0,n=document.createElement("div");return this._tab_to_index_map.set(n,e),n.textContent=t.child[e]||"",e===i?n.setAttribute("part","tab active-tab"):(n.setAttribute("part","tab"),n.addEventListener("pointerdown",s=>this.onTabClick(t,e))),n};onTabClick=(t,e)=>{let i=this._layout.save(),n=this._layout.getPanel(t.child[e],i);n&&(n.selected=e,this._layout.restore(i))}};customElements.define("regular-layout",v);customElements.define("regular-layout-frame",E);export{v as RegularLayout,E as RegularLayoutFrame};
11
11
  //# sourceMappingURL=index.js.map