kempo-ui 0.0.73 → 0.0.75

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.
@@ -1,8 +1,8 @@
1
- import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComponent.js";import drag from"../utils/drag.js";export default class Split extends ShadowComponent{static properties={resizing:{type:Boolean,reflect:!0},stacked:{type:Boolean,reflect:!0},stackWidth:{type:Number,attribute:"stack-width"}};constructor(){super(),this.resizing=!1,this.stacked=!1,this.stackWidth=0,this.dragStartWidth=0,this.dragCleanup=()=>{},this.resizeObserver=null}firstUpdated(){super.firstUpdated(),this.setupDragHandler(),this.setupResizeObserver()}disconnectedCallback(){super.disconnectedCallback(),this.dragCleanup(),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null)}handleDragStart=()=>{this.resizing=!0,this.dragStartWidth=Math.round(this.shadowRoot.getElementById("left").getBoundingClientRect().width),this.dispatchEvent(new CustomEvent("resizestart",{detail:{startSize:this.dragStartWidth},bubbles:!0}))};handleDrag=({x:e})=>{const t=`${this.dragStartWidth+e}px`;this.setSize(t),this.dispatchEvent(new CustomEvent("resize",{detail:{size:t},bubbles:!0}))};handleDragEnd=({x:e})=>{this.resizing=!1;const t=`${this.dragStartWidth+e}px`;this.setSize(t),this.dispatchEvent(new CustomEvent("resizeend",{detail:{size:t},bubbles:!0}))};setSize(e){this.style.setProperty("--left_width",e)}setupDragHandler(){const e=this.shadowRoot.getElementById("divider-handle");e&&(this.dragCleanup=drag({element:e,callback:this.handleDrag,startCallback:this.handleDragStart,endCallback:this.handleDragEnd}))}setupResizeObserver(){this.resizeObserver=new ResizeObserver(e=>{for(const t of e){const e=t.contentRect.width;this.stacked=e<=this.stackWidth}}),this.resizeObserver.observe(this)}static styles=css`
1
+ import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComponent.js";import drag from"../utils/drag.js";export default class Split extends ShadowComponent{static properties={resizing:{type:Boolean,reflect:!0},stacked:{type:Boolean,reflect:!0},stackWidth:{type:Number,attribute:"stack-width"},direction:{type:String,reflect:!0},persistentId:{type:String,reflect:!0,attribute:"persistent-id"}};constructor(){super(),this.resizing=!1,this.stacked=!1,this.stackWidth=0,this.direction="horizontal",this.persistentId=null,this.dragStartSize=0,this.dragCleanup=()=>{},this.resizeObserver=null}firstUpdated(){if(super.firstUpdated(),this.setupDragHandler(),this.setupResizeObserver(),this.persistentId&&window?.localStorage){const e=window.localStorage.getItem(`split-persistent-id-${this.persistentId}`);e&&this.setSize(e)}}disconnectedCallback(){super.disconnectedCallback(),this.dragCleanup(),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null)}handleDragStart=()=>{this.resizing=!0,this.dragStartSize=Math.round(this.shadowRoot.getElementById("pane-1").getBoundingClientRect()["vertical"===this.direction?"height":"width"]),this.dispatchEvent(new CustomEvent("resizestart",{detail:{startSize:this.dragStartSize},bubbles:!0}))};handleDrag=({x:e,y:t})=>{const i="vertical"===this.direction?t:e,s=`${this.dragStartSize+i}px`;this.setSize(s),this.dispatchEvent(new CustomEvent("resize",{detail:{size:s},bubbles:!0}))};handleDragEnd=({x:e,y:t})=>{this.resizing=!1;const i="vertical"===this.direction?t:e,s=`${this.dragStartSize+i}px`;this.setSize(s),this.persistentId&&window?.localStorage&&window.localStorage.setItem(`split-persistent-id-${this.persistentId}`,s),this.dispatchEvent(new CustomEvent("resizeend",{detail:{size:s},bubbles:!0}))};setSize(e){this.style.setProperty("--pane_1_size",e)}setupDragHandler(){const e=this.shadowRoot.getElementById("divider-handle");e&&(this.dragCleanup=drag({element:e,callback:this.handleDrag,startCallback:this.handleDragStart,endCallback:this.handleDragEnd}))}setupResizeObserver(){this.resizeObserver=new ResizeObserver(e=>{for(const t of e){const e=t.contentRect.width;this.stacked=e<=this.stackWidth}}),this.resizeObserver.observe(this)}static styles=css`
2
2
  :host {
3
- --left_width: calc((100% - var(--handle_width)) / 2);
3
+ --pane_1_size: calc((100% - var(--handle_width)) / 2);
4
4
  --handle_width: 0.5rem;
5
- --min_pane_width: 6rem;
5
+ --min_pane_size: 6rem;
6
6
 
7
7
  height: 100%;
8
8
  display: flex;
@@ -16,14 +16,14 @@ import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComp
16
16
  }
17
17
 
18
18
  .pane {
19
- min-width: var(--min_pane_width);
20
- max-width: calc(100% - var(--min_pane_width));
19
+ min-width: var(--min_pane_size);
20
+ max-width: calc(100% - var(--min_pane_size));
21
21
  max-height: 100%;
22
22
  overflow: hidden;
23
23
  }
24
24
 
25
- #left {
26
- flex: 0 0 var(--left_width);
25
+ #pane-1 {
26
+ flex: 0 0 var(--pane_1_size);
27
27
  }
28
28
 
29
29
  #divider-handle {
@@ -48,12 +48,12 @@ import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComp
48
48
  border-left: 1px solid var(--c_border);
49
49
  }
50
50
 
51
- #right {
51
+ #pane-2 {
52
52
  flex: 1 1;
53
53
  }
54
54
 
55
- :host([stacked]) #left,
56
- :host([stacked]) #right {
55
+ :host([stacked]) #pane-1,
56
+ :host([stacked]) #pane-2 {
57
57
  display: block;
58
58
  }
59
59
 
@@ -71,14 +71,44 @@ import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComp
71
71
  :host([stacked]) {
72
72
  display: block;
73
73
  }
74
+
75
+ :host([direction="vertical"]) {
76
+ flex-direction: column;
77
+ }
78
+
79
+ :host([direction="vertical"]) .pane {
80
+ min-width: 0;
81
+ max-width: 100%;
82
+ min-height: var(--min_pane_size);
83
+ max-height: calc(100% - var(--min_pane_size));
84
+ }
85
+
86
+ :host([direction="vertical"]) #pane-1 {
87
+ flex: 0 0 var(--pane_1_size);
88
+ }
89
+
90
+ :host([direction="vertical"]) #divider-handle {
91
+ width: 100%;
92
+ height: var(--handle_width);
93
+ cursor: ns-resize;
94
+ align-items: center;
95
+ justify-content: initial;
96
+ }
97
+
98
+ :host([direction="vertical"]) #divider-border {
99
+ width: 100%;
100
+ height: 1px;
101
+ border-left: none;
102
+ border-top: 1px solid var(--c_border);
103
+ }
74
104
  `;render(){return html`
75
- <div id="left" class="pane">
105
+ <div id="pane-1" class="pane">
76
106
  <slot></slot>
77
107
  </div>
78
108
  <div id="divider-handle">
79
109
  <div id="divider-border"></div>
80
110
  </div>
81
- <div id="right" class="pane">
111
+ <div id="pane-2" class="pane">
82
112
  <slot name="right"></slot>
83
113
  </div>
84
114
  `}}customElements.define("k-split",Split);
@@ -23,7 +23,8 @@
23
23
  <h6>Examples</h6>
24
24
  <a href="#basicUsage">Basic Usage</a><br />
25
25
  <a href="#resizing">Resizing</a><br />
26
-
26
+ <a href="#verticalSplit">Vertical Split</a><br />
27
+ <a href="#persistentState">Persistent State</a><br />
27
28
  <h6 class="mt"><a href="#jsRef" class="no-link">JavaScript Reference</a></h6>
28
29
  <a href="#constructor">Constructor</a><br />
29
30
  <a href="#requirements">Requirements</a><br />
@@ -36,7 +37,7 @@
36
37
  </k-accordion>
37
38
 
38
39
  <h3 id="basicUsage"><a href="#basicUsage" class="no-link">Basic Usage</a></h3>
39
- <p>Create a split view using the <code>k-split</code> component. Add content to the left pane by placing it inside the component, and add content to the right pane by using the <code>slot="right"</code> attribute.</p>
40
+ <p>Create a split view using the <code>k-split</code> component. Add content to the first pane by placing it inside the component, and add content to the second pane by using the <code>slot="right"</code> attribute.</p>
40
41
  <div class="row -mx mb">
41
42
  <div class="col d-span-6 m-span-12 px">
42
43
  <k-card label="HTML">
@@ -54,16 +55,16 @@
54
55
  </div>
55
56
 
56
57
  <h3 id="resizing"><a href="#resizing" class="no-link">Resizing</a></h3>
57
- <p>The split view can be resized by dragging the divider handle. The initial width of the left pane can be set using the <code>--left_width</code> CSS custom property.</p>
58
+ <p>The split view can be resized by dragging the divider handle. The initial size of the first pane can be set using the <code>--pane_1_size</code> CSS custom property.</p>
58
59
  <div class="row -mx mb">
59
60
  <div class="col d-span-6 m-span-12 px">
60
61
  <k-card label="HTML">
61
- <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-split</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"--left_width: 30%; height: 10rem"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"b"</span>&gt;</span><br /> <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Left Pane Content<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br /> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"right"</span>&gt;</span>Right Pane Content<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br /><span class="hljs-tag">&lt;/<span class="hljs-name">k-split</span>&gt;</span></code></pre>
62
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-split</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"--pane_1_size: 30%; height: 10rem"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"b"</span>&gt;</span><br /> <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Left Pane Content<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br /> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"right"</span>&gt;</span>Right Pane Content<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br /><span class="hljs-tag">&lt;/<span class="hljs-name">k-split</span>&gt;</span></code></pre>
62
63
  </k-card>
63
64
  </div>
64
65
  <div class="col d-span-6 m-span-12 px">
65
66
  <k-card label="Results">
66
- <k-split style="--left_width: 30%; height: 10rem" class="b">
67
+ <k-split style="--pane_1_size: 30%; height: 10rem" class="b">
67
68
  <div>Left Pane Content</div>
68
69
  <div slot="right">Right Pane Content</div>
69
70
  </k-split>
@@ -72,21 +73,21 @@
72
73
  </div>
73
74
 
74
75
  <h3>Sizes</h3>
75
- <p>Set the CSS Custom Property <code>--left_width</code> to set the initial size.</p>
76
- <p>Set the CSS Custom Property <code>--min_pane_width</code> to set the minimum size each side can be.</p>
77
- <p>Set the CSS Custom Property <code>--handle_width</code> to set the size of the handle (the draggable region between the sides).</p>
76
+ <p>Set the CSS Custom Property <code>--pane_1_size</code> to set the initial size of the first pane.</p>
77
+ <p>Set the CSS Custom Property <code>--min_pane_size</code> to set the minimum size each pane can be.</p>
78
+ <p>Set the CSS Custom Property <code>--handle_width</code> to set the size of the handle (the draggable region between the panes).</p>
78
79
  <div class="row -mx">
79
80
  <div class="col m-span-12 px">
80
81
  <k-card label="HTML">
81
- <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-split</span><br /> <span class="hljs-attr">style</span>=<span class="hljs-string">"<br /> --left_width: 100px;<br /> --min_pane_width: 100px;<br /> --handle_width: 20px;<br /> height: 10rem<br /> "</span><br /> <span class="hljs-attr">class</span>=<span class="hljs-string">"b"</span><br />&gt;</span><br /> <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>left<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br /> <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"right"</span>&gt;</span>right<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br /><span class="hljs-tag">&lt;/<span class="hljs-name">k-split</span>&gt;</span></code></pre>
82
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-split</span><br /> <span class="hljs-attr">style</span>=<span class="hljs-string">"<br /> --pane_1_size: 100px;<br /> --min_pane_size: 100px;<br /> --handle_width: 20px;<br /> height: 10rem<br /> "</span><br /> <span class="hljs-attr">class</span>=<span class="hljs-string">"b"</span><br />&gt;</span><br /> <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>left<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br /> <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"right"</span>&gt;</span>right<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span><br /><span class="hljs-tag">&lt;/<span class="hljs-name">k-split</span>&gt;</span></code></pre>
82
83
  </k-card>
83
84
  </div>
84
85
  <div class="col m-span-12 px">
85
86
  <k-card label="Output">
86
87
  <k-split
87
88
  style="
88
- --left_width: 100px;
89
- --min_pane_width: 100px;
89
+ --pane_1_size: 100px;
90
+ --min_pane_size: 100px;
90
91
  --handle_width: 20px;
91
92
  height: 10rem
92
93
  "
@@ -99,6 +100,24 @@
99
100
  </div>
100
101
  </div>
101
102
 
103
+ <h3 id="verticalSplit"><a href="#verticalSplit" class="no-link">Vertical Split</a></h3>
104
+ <p>Use the <code>direction="vertical"</code> attribute to create a vertical split where the top and bottom panes are divided by a horizontal handle. Set an explicit height on the component for predictable sizing. The default slot provides the top pane content; use <code>slot="right"</code> for the bottom pane content.</p>
105
+ <div class="row -mx mb">
106
+ <div class="col d-span-6 m-span-12 px">
107
+ <k-card label="HTML">
108
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-split</span> <span class="hljs-attr">direction</span>=<span class="hljs-string">"vertical"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"height: 16rem"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"b"</span>&gt;</span><br /> <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Top Pane Content<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br /> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"right"</span>&gt;</span>Bottom Pane Content<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br /><span class="hljs-tag">&lt;/<span class="hljs-name">k-split</span>&gt;</span></code></pre>
109
+ </k-card>
110
+ </div>
111
+ <div class="col d-span-6 m-span-12 px">
112
+ <k-card label="Results">
113
+ <k-split direction="vertical" style="height: 16rem" class="b">
114
+ <div>Top Pane Content</div>
115
+ <div slot="right">Bottom Pane Content</div>
116
+ </k-split>
117
+ </k-card>
118
+ </div>
119
+ </div>
120
+
102
121
  <h3 id="stacking"><a href="#stacking" class="no-link">Stacking</a></h3>
103
122
  <p>When the screen size is small (mobile) a split panel may not make sense, rather than changing the markup set the <code>stack-width</code> attribute to stack the contents (disable split view) when the component's size is less than the provided size.</p>
104
123
  <div class="row -mx">
@@ -120,6 +139,24 @@
120
139
  </div>
121
140
 
122
141
 
142
+ <h3 id="persistentState"><a href="#persistentState" class="no-link">Persistent State</a></h3>
143
+ <p>Add the <code>persistent-id</code> attribute to save and restore the pane size across page refreshes using <code>localStorage</code>. Each split that uses persistence must have a unique <code>persistent-id</code> value.</p>
144
+ <div class="row -mx mb">
145
+ <div class="col d-span-6 m-span-12 px">
146
+ <k-card label="HTML">
147
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-split</span> <span class="hljs-attr">persistent-id</span>=<span class="hljs-string">"my-split"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"height: 10rem"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"b"</span>&gt;</span><br /> <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Left Pane Content<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br /> <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"right"</span>&gt;</span>Right Pane Content<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br /><span class="hljs-tag">&lt;/<span class="hljs-name">k-split</span>&gt;</span></code></pre>
148
+ </k-card>
149
+ </div>
150
+ <div class="col d-span-6 m-span-12 px">
151
+ <k-card label="Results">
152
+ <k-split persistent-id="docs-split-example" style="height: 10rem" class="b">
153
+ <div>Left Pane Content</div>
154
+ <div slot="right">Right Pane Content</div>
155
+ </k-split>
156
+ </k-card>
157
+ </div>
158
+ </div>
159
+
123
160
  <h2 id="jsRef">JavaScript Reference</h2>
124
161
 
125
162
  <h3 id="constructor"><a href="#constructor" class="no-link">Constructor</a></h3>
@@ -140,18 +177,22 @@
140
177
  <p>Whether the split view is in stacked mode. Syncs to <code>stacked</code> attribute.</p>
141
178
  <h5><code>stackWidth<i>: number</i></code></h5>
142
179
  <p>The window width threshold for stacking behavior. Syncs to <code>stack-width</code> attribute.</p>
180
+ <h5><code>direction<i>: string</i></code></h5>
181
+ <p>The direction of the split. Can be <code>"horizontal"</code> (default) or <code>"vertical"</code>. Syncs to <code>direction</code> attribute.</p>
182
+ <h5><code>persistentId<i>: string</i></code></h5>
183
+ <p>When set, the pane size is saved to <code>localStorage</code> on resize and restored on initialization. Must be unique per split instance. Syncs to <code>persistent-id</code> attribute.</p>
143
184
 
144
185
  <h3 id="cssCustomProperties"><a href="#cssCustomProperties" class="no-link">CSS Custom Properties</a></h3>
145
- <h5><code>--left_width</code></h5>
146
- <p>The width of the left pane. Default is <code>calc((100% - var(--handle_width)) / 2)</code>.</p>
186
+ <h5><code>--pane_1_size</code></h5>
187
+ <p>The size of pane 1 (width in horizontal mode, height in vertical mode). Default is <code>calc((100% - var(--handle_width)) / 2)</code>.</p>
147
188
  <h5><code>--handle_width</code></h5>
148
- <p>The width of the draggable divider handle. Default is <code>0.5rem</code>.</p>
149
- <h5><code>--min_pane_width</code></h5>
150
- <p>The minimum width each pane can be resized to. Default is <code>6rem</code>.</p>
189
+ <p>The width/height of the draggable divider handle. Default is <code>0.5rem</code>.</p>
190
+ <h5><code>--min_pane_size</code></h5>
191
+ <p>The minimum size each pane can be resized to. Default is <code>6rem</code>.</p>
151
192
 
152
193
  <h3 id="methods"><a href="#methods" class="no-link">Methods</a></h3>
153
194
  <h5><code>setSize(size)<i>: void</i></code></h5>
154
- <p>Sets the width of the left pane.</p>
195
+ <p>Sets the size of pane 1 via <code>--pane_1_size</code>. Controls width in horizontal mode and height in vertical mode.</p>
155
196
 
156
197
  <h3 id="events"><a href="#events" class="no-link">Events</a></h3>
157
198
  <h5><code>resizestart</code></h5>
@@ -1,8 +1,8 @@
1
- import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComponent.js";import drag from"../utils/drag.js";export default class Split extends ShadowComponent{static properties={resizing:{type:Boolean,reflect:!0},stacked:{type:Boolean,reflect:!0},stackWidth:{type:Number,attribute:"stack-width"}};constructor(){super(),this.resizing=!1,this.stacked=!1,this.stackWidth=0,this.dragStartWidth=0,this.dragCleanup=()=>{},this.resizeObserver=null}firstUpdated(){super.firstUpdated(),this.setupDragHandler(),this.setupResizeObserver()}disconnectedCallback(){super.disconnectedCallback(),this.dragCleanup(),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null)}handleDragStart=()=>{this.resizing=!0,this.dragStartWidth=Math.round(this.shadowRoot.getElementById("left").getBoundingClientRect().width),this.dispatchEvent(new CustomEvent("resizestart",{detail:{startSize:this.dragStartWidth},bubbles:!0}))};handleDrag=({x:e})=>{const t=`${this.dragStartWidth+e}px`;this.setSize(t),this.dispatchEvent(new CustomEvent("resize",{detail:{size:t},bubbles:!0}))};handleDragEnd=({x:e})=>{this.resizing=!1;const t=`${this.dragStartWidth+e}px`;this.setSize(t),this.dispatchEvent(new CustomEvent("resizeend",{detail:{size:t},bubbles:!0}))};setSize(e){this.style.setProperty("--left_width",e)}setupDragHandler(){const e=this.shadowRoot.getElementById("divider-handle");e&&(this.dragCleanup=drag({element:e,callback:this.handleDrag,startCallback:this.handleDragStart,endCallback:this.handleDragEnd}))}setupResizeObserver(){this.resizeObserver=new ResizeObserver(e=>{for(const t of e){const e=t.contentRect.width;this.stacked=e<=this.stackWidth}}),this.resizeObserver.observe(this)}static styles=css`
1
+ import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComponent.js";import drag from"../utils/drag.js";export default class Split extends ShadowComponent{static properties={resizing:{type:Boolean,reflect:!0},stacked:{type:Boolean,reflect:!0},stackWidth:{type:Number,attribute:"stack-width"},direction:{type:String,reflect:!0},persistentId:{type:String,reflect:!0,attribute:"persistent-id"}};constructor(){super(),this.resizing=!1,this.stacked=!1,this.stackWidth=0,this.direction="horizontal",this.persistentId=null,this.dragStartSize=0,this.dragCleanup=()=>{},this.resizeObserver=null}firstUpdated(){if(super.firstUpdated(),this.setupDragHandler(),this.setupResizeObserver(),this.persistentId&&window?.localStorage){const e=window.localStorage.getItem(`split-persistent-id-${this.persistentId}`);e&&this.setSize(e)}}disconnectedCallback(){super.disconnectedCallback(),this.dragCleanup(),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null)}handleDragStart=()=>{this.resizing=!0,this.dragStartSize=Math.round(this.shadowRoot.getElementById("pane-1").getBoundingClientRect()["vertical"===this.direction?"height":"width"]),this.dispatchEvent(new CustomEvent("resizestart",{detail:{startSize:this.dragStartSize},bubbles:!0}))};handleDrag=({x:e,y:t})=>{const i="vertical"===this.direction?t:e,s=`${this.dragStartSize+i}px`;this.setSize(s),this.dispatchEvent(new CustomEvent("resize",{detail:{size:s},bubbles:!0}))};handleDragEnd=({x:e,y:t})=>{this.resizing=!1;const i="vertical"===this.direction?t:e,s=`${this.dragStartSize+i}px`;this.setSize(s),this.persistentId&&window?.localStorage&&window.localStorage.setItem(`split-persistent-id-${this.persistentId}`,s),this.dispatchEvent(new CustomEvent("resizeend",{detail:{size:s},bubbles:!0}))};setSize(e){this.style.setProperty("--pane_1_size",e)}setupDragHandler(){const e=this.shadowRoot.getElementById("divider-handle");e&&(this.dragCleanup=drag({element:e,callback:this.handleDrag,startCallback:this.handleDragStart,endCallback:this.handleDragEnd}))}setupResizeObserver(){this.resizeObserver=new ResizeObserver(e=>{for(const t of e){const e=t.contentRect.width;this.stacked=e<=this.stackWidth}}),this.resizeObserver.observe(this)}static styles=css`
2
2
  :host {
3
- --left_width: calc((100% - var(--handle_width)) / 2);
3
+ --pane_1_size: calc((100% - var(--handle_width)) / 2);
4
4
  --handle_width: 0.5rem;
5
- --min_pane_width: 6rem;
5
+ --min_pane_size: 6rem;
6
6
 
7
7
  height: 100%;
8
8
  display: flex;
@@ -16,14 +16,14 @@ import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComp
16
16
  }
17
17
 
18
18
  .pane {
19
- min-width: var(--min_pane_width);
20
- max-width: calc(100% - var(--min_pane_width));
19
+ min-width: var(--min_pane_size);
20
+ max-width: calc(100% - var(--min_pane_size));
21
21
  max-height: 100%;
22
22
  overflow: hidden;
23
23
  }
24
24
 
25
- #left {
26
- flex: 0 0 var(--left_width);
25
+ #pane-1 {
26
+ flex: 0 0 var(--pane_1_size);
27
27
  }
28
28
 
29
29
  #divider-handle {
@@ -48,12 +48,12 @@ import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComp
48
48
  border-left: 1px solid var(--c_border);
49
49
  }
50
50
 
51
- #right {
51
+ #pane-2 {
52
52
  flex: 1 1;
53
53
  }
54
54
 
55
- :host([stacked]) #left,
56
- :host([stacked]) #right {
55
+ :host([stacked]) #pane-1,
56
+ :host([stacked]) #pane-2 {
57
57
  display: block;
58
58
  }
59
59
 
@@ -71,14 +71,44 @@ import{html,css}from"../lit-all.min.js";import ShadowComponent from"./ShadowComp
71
71
  :host([stacked]) {
72
72
  display: block;
73
73
  }
74
+
75
+ :host([direction="vertical"]) {
76
+ flex-direction: column;
77
+ }
78
+
79
+ :host([direction="vertical"]) .pane {
80
+ min-width: 0;
81
+ max-width: 100%;
82
+ min-height: var(--min_pane_size);
83
+ max-height: calc(100% - var(--min_pane_size));
84
+ }
85
+
86
+ :host([direction="vertical"]) #pane-1 {
87
+ flex: 0 0 var(--pane_1_size);
88
+ }
89
+
90
+ :host([direction="vertical"]) #divider-handle {
91
+ width: 100%;
92
+ height: var(--handle_width);
93
+ cursor: ns-resize;
94
+ align-items: center;
95
+ justify-content: initial;
96
+ }
97
+
98
+ :host([direction="vertical"]) #divider-border {
99
+ width: 100%;
100
+ height: 1px;
101
+ border-left: none;
102
+ border-top: 1px solid var(--c_border);
103
+ }
74
104
  `;render(){return html`
75
- <div id="left" class="pane">
105
+ <div id="pane-1" class="pane">
76
106
  <slot></slot>
77
107
  </div>
78
108
  <div id="divider-handle">
79
109
  <div id="divider-border"></div>
80
110
  </div>
81
- <div id="right" class="pane">
111
+ <div id="pane-2" class="pane">
82
112
  <slot name="right"></slot>
83
113
  </div>
84
114
  `}}customElements.define("k-split",Split);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kempo-ui",
3
- "version": "0.0.73",
3
+ "version": "0.0.75",
4
4
  "type": "module",
5
5
  "description": "A Lit based web-component library",
6
6
  "main": "index.js",
@@ -6,7 +6,9 @@ export default class Split extends ShadowComponent {
6
6
  static properties = {
7
7
  resizing: { type: Boolean, reflect: true },
8
8
  stacked: { type: Boolean, reflect: true },
9
- stackWidth: { type: Number, attribute: 'stack-width' }
9
+ stackWidth: { type: Number, attribute: 'stack-width' },
10
+ direction: { type: String, reflect: true },
11
+ persistentId: { type: String, reflect: true, attribute: 'persistent-id' }
10
12
  };
11
13
 
12
14
  constructor() {
@@ -15,9 +17,11 @@ export default class Split extends ShadowComponent {
15
17
  this.resizing = false;
16
18
  this.stacked = false;
17
19
  this.stackWidth = 0;
20
+ this.direction = 'horizontal';
21
+ this.persistentId = null;
18
22
 
19
23
  // Private state
20
- this.dragStartWidth = 0;
24
+ this.dragStartSize = 0;
21
25
  this.dragCleanup = () => {};
22
26
  this.resizeObserver = null;
23
27
  }
@@ -29,6 +33,10 @@ export default class Split extends ShadowComponent {
29
33
  super.firstUpdated();
30
34
  this.setupDragHandler();
31
35
  this.setupResizeObserver();
36
+ if(this.persistentId && window?.localStorage) {
37
+ const size = window.localStorage.getItem(`split-persistent-id-${this.persistentId}`);
38
+ if(size) this.setSize(size);
39
+ }
32
40
  }
33
41
 
34
42
  disconnectedCallback() {
@@ -45,15 +53,16 @@ export default class Split extends ShadowComponent {
45
53
  */
46
54
  handleDragStart = () => {
47
55
  this.resizing = true;
48
- this.dragStartWidth = Math.round(this.shadowRoot.getElementById('left').getBoundingClientRect().width);
56
+ this.dragStartSize = Math.round(this.shadowRoot.getElementById('pane-1').getBoundingClientRect()[this.direction === 'vertical' ? 'height' : 'width']);
49
57
  this.dispatchEvent(new CustomEvent('resizestart', {
50
- detail: { startSize: this.dragStartWidth },
58
+ detail: { startSize: this.dragStartSize },
51
59
  bubbles: true
52
60
  }));
53
61
  };
54
62
 
55
- handleDrag = ({ x }) => {
56
- const size = `${this.dragStartWidth + x}px`;
63
+ handleDrag = ({ x, y }) => {
64
+ const delta = this.direction === 'vertical' ? y : x;
65
+ const size = `${this.dragStartSize + delta}px`;
57
66
  this.setSize(size);
58
67
  this.dispatchEvent(new CustomEvent('resize', {
59
68
  detail: { size },
@@ -61,11 +70,14 @@ export default class Split extends ShadowComponent {
61
70
  }));
62
71
  };
63
72
 
64
- handleDragEnd = ({ x }) => {
73
+ handleDragEnd = ({ x, y }) => {
65
74
  this.resizing = false;
66
- const width = this.dragStartWidth + x;
67
- const size = `${width}px`;
75
+ const delta = this.direction === 'vertical' ? y : x;
76
+ const size = `${this.dragStartSize + delta}px`;
68
77
  this.setSize(size);
78
+ if(this.persistentId && window?.localStorage) {
79
+ window.localStorage.setItem(`split-persistent-id-${this.persistentId}`, size);
80
+ }
69
81
  this.dispatchEvent(new CustomEvent('resizeend', {
70
82
  detail: { size },
71
83
  bubbles: true
@@ -76,7 +88,7 @@ export default class Split extends ShadowComponent {
76
88
  Public Methods
77
89
  */
78
90
  setSize(size) {
79
- this.style.setProperty('--left_width', size);
91
+ this.style.setProperty('--pane_1_size', size);
80
92
  }
81
93
 
82
94
  setupDragHandler() {
@@ -106,9 +118,9 @@ export default class Split extends ShadowComponent {
106
118
  */
107
119
  static styles = css`
108
120
  :host {
109
- --left_width: calc((100% - var(--handle_width)) / 2);
121
+ --pane_1_size: calc((100% - var(--handle_width)) / 2);
110
122
  --handle_width: 0.5rem;
111
- --min_pane_width: 6rem;
123
+ --min_pane_size: 6rem;
112
124
 
113
125
  height: 100%;
114
126
  display: flex;
@@ -122,14 +134,14 @@ export default class Split extends ShadowComponent {
122
134
  }
123
135
 
124
136
  .pane {
125
- min-width: var(--min_pane_width);
126
- max-width: calc(100% - var(--min_pane_width));
137
+ min-width: var(--min_pane_size);
138
+ max-width: calc(100% - var(--min_pane_size));
127
139
  max-height: 100%;
128
140
  overflow: hidden;
129
141
  }
130
142
 
131
- #left {
132
- flex: 0 0 var(--left_width);
143
+ #pane-1 {
144
+ flex: 0 0 var(--pane_1_size);
133
145
  }
134
146
 
135
147
  #divider-handle {
@@ -154,12 +166,12 @@ export default class Split extends ShadowComponent {
154
166
  border-left: 1px solid var(--c_border);
155
167
  }
156
168
 
157
- #right {
169
+ #pane-2 {
158
170
  flex: 1 1;
159
171
  }
160
172
 
161
- :host([stacked]) #left,
162
- :host([stacked]) #right {
173
+ :host([stacked]) #pane-1,
174
+ :host([stacked]) #pane-2 {
163
175
  display: block;
164
176
  }
165
177
 
@@ -177,6 +189,36 @@ export default class Split extends ShadowComponent {
177
189
  :host([stacked]) {
178
190
  display: block;
179
191
  }
192
+
193
+ :host([direction="vertical"]) {
194
+ flex-direction: column;
195
+ }
196
+
197
+ :host([direction="vertical"]) .pane {
198
+ min-width: 0;
199
+ max-width: 100%;
200
+ min-height: var(--min_pane_size);
201
+ max-height: calc(100% - var(--min_pane_size));
202
+ }
203
+
204
+ :host([direction="vertical"]) #pane-1 {
205
+ flex: 0 0 var(--pane_1_size);
206
+ }
207
+
208
+ :host([direction="vertical"]) #divider-handle {
209
+ width: 100%;
210
+ height: var(--handle_width);
211
+ cursor: ns-resize;
212
+ align-items: center;
213
+ justify-content: initial;
214
+ }
215
+
216
+ :host([direction="vertical"]) #divider-border {
217
+ width: 100%;
218
+ height: 1px;
219
+ border-left: none;
220
+ border-top: 1px solid var(--c_border);
221
+ }
180
222
  `;
181
223
 
182
224
  /*
@@ -184,13 +226,13 @@ export default class Split extends ShadowComponent {
184
226
  */
185
227
  render() {
186
228
  return html`
187
- <div id="left" class="pane">
229
+ <div id="pane-1" class="pane">
188
230
  <slot></slot>
189
231
  </div>
190
232
  <div id="divider-handle">
191
233
  <div id="divider-border"></div>
192
234
  </div>
193
- <div id="right" class="pane">
235
+ <div id="pane-2" class="pane">
194
236
  <slot name="right"></slot>
195
237
  </div>
196
238
  `;
@@ -5,7 +5,7 @@ const createSplit = async (options = {}) => {
5
5
  container.style.width = '800px';
6
6
  container.style.height = '400px';
7
7
  container.innerHTML = `
8
- <k-split ${options.stacked ? 'stacked' : ''} ${options.stackWidth ? `stack-width="${options.stackWidth}"` : ''}>
8
+ <k-split ${options.stacked ? 'stacked' : ''} ${options.stackWidth ? `stack-width="${options.stackWidth}"` : ''} ${options.direction ? `direction="${options.direction}"` : ''} ${options.persistentId ? `persistent-id="${options.persistentId}"` : ''}>
9
9
  <div id="left-content">Left Pane Content</div>
10
10
  <div slot="right" id="right-content">Right Pane Content</div>
11
11
  </k-split>
@@ -102,41 +102,41 @@ export default {
102
102
  'should render left pane': async ({pass, fail}) => {
103
103
  const { container, split } = await createSplit();
104
104
 
105
- const leftPane = split.shadowRoot.getElementById('left');
106
- if(!leftPane){
105
+ const pane1 = split.shadowRoot.getElementById('pane-1');
106
+ if(!pane1){
107
107
  cleanup(container);
108
- fail('Split should render left pane');
108
+ fail('Split should render pane-1');
109
109
  return;
110
110
  }
111
111
 
112
- if(!leftPane.classList.contains('pane')){
112
+ if(!pane1.classList.contains('pane')){
113
113
  cleanup(container);
114
- fail('Left pane should have pane class');
114
+ fail('pane-1 should have pane class');
115
115
  return;
116
116
  }
117
117
 
118
118
  cleanup(container);
119
- pass('Split renders left pane');
119
+ pass('Split renders pane-1');
120
120
  },
121
121
 
122
122
  'should render right pane': async ({pass, fail}) => {
123
123
  const { container, split } = await createSplit();
124
124
 
125
- const rightPane = split.shadowRoot.getElementById('right');
126
- if(!rightPane){
125
+ const pane2 = split.shadowRoot.getElementById('pane-2');
126
+ if(!pane2){
127
127
  cleanup(container);
128
- fail('Split should render right pane');
128
+ fail('Split should render pane-2');
129
129
  return;
130
130
  }
131
131
 
132
- if(!rightPane.classList.contains('pane')){
132
+ if(!pane2.classList.contains('pane')){
133
133
  cleanup(container);
134
- fail('Right pane should have pane class');
134
+ fail('pane-2 should have pane class');
135
135
  return;
136
136
  }
137
137
 
138
138
  cleanup(container);
139
- pass('Split renders right pane');
139
+ pass('Split renders pane-2');
140
140
  },
141
141
 
142
142
  'should render divider handle': async ({pass, fail}) => {
@@ -170,31 +170,31 @@ export default {
170
170
  'should render default slot for left content': async ({pass, fail}) => {
171
171
  const { container, split } = await createSplit();
172
172
 
173
- const leftPane = split.shadowRoot.getElementById('left');
174
- const slot = leftPane.querySelector('slot:not([name])');
173
+ const pane1 = split.shadowRoot.getElementById('pane-1');
174
+ const slot = pane1.querySelector('slot:not([name])');
175
175
  if(!slot){
176
176
  cleanup(container);
177
- fail('Left pane should have default slot');
177
+ fail('pane-1 should have default slot');
178
178
  return;
179
179
  }
180
180
 
181
181
  cleanup(container);
182
- pass('Split renders default slot for left content');
182
+ pass('Split renders default slot for pane-1 content');
183
183
  },
184
184
 
185
185
  'should render named slot for right content': async ({pass, fail}) => {
186
186
  const { container, split } = await createSplit();
187
187
 
188
- const rightPane = split.shadowRoot.getElementById('right');
189
- const slot = rightPane.querySelector('slot[name="right"]');
188
+ const pane2 = split.shadowRoot.getElementById('pane-2');
189
+ const slot = pane2.querySelector('slot[name="right"]');
190
190
  if(!slot){
191
191
  cleanup(container);
192
- fail('Right pane should have named right slot');
192
+ fail('pane-2 should have named right slot');
193
193
  return;
194
194
  }
195
195
 
196
196
  cleanup(container);
197
- pass('Split renders named slot for right content');
197
+ pass('Split renders named slot for pane-2 content');
198
198
  },
199
199
 
200
200
  'should slot left content correctly': async ({pass, fail}) => {
@@ -250,20 +250,20 @@ export default {
250
250
  pass('Split has setSize method');
251
251
  },
252
252
 
253
- 'setSize should set --left_width CSS property': async ({pass, fail}) => {
253
+ 'setSize should set --pane_1_size CSS property': async ({pass, fail}) => {
254
254
  const { container, split } = await createSplit();
255
255
 
256
256
  split.setSize('300px');
257
- const leftWidth = split.style.getPropertyValue('--left_width');
257
+ const pane1Size = split.style.getPropertyValue('--pane_1_size');
258
258
 
259
- if(leftWidth !== '300px'){
259
+ if(pane1Size !== '300px'){
260
260
  cleanup(container);
261
- fail(`Expected --left_width to be 300px, got ${leftWidth}`);
261
+ fail(`Expected --pane_1_size to be 300px, got ${pane1Size}`);
262
262
  return;
263
263
  }
264
264
 
265
265
  cleanup(container);
266
- pass('setSize sets --left_width property');
266
+ pass('setSize sets --pane_1_size property');
267
267
  },
268
268
 
269
269
  'should have ew-resize cursor on divider handle': async ({pass, fail}) => {
@@ -521,8 +521,8 @@ export default {
521
521
  split.resizing = true;
522
522
  await split.updateComplete;
523
523
 
524
- const leftPane = split.shadowRoot.getElementById('left');
525
- const pointerEvents = getComputedStyle(leftPane).pointerEvents;
524
+ const pane1 = split.shadowRoot.getElementById('pane-1');
525
+ const pointerEvents = getComputedStyle(pane1).pointerEvents;
526
526
 
527
527
  if(pointerEvents !== 'none'){
528
528
  cleanup(container);
@@ -540,8 +540,8 @@ export default {
540
540
  split.resizing = true;
541
541
  await split.updateComplete;
542
542
 
543
- const leftPane = split.shadowRoot.getElementById('left');
544
- const userSelect = getComputedStyle(leftPane).userSelect;
543
+ const pane1 = split.shadowRoot.getElementById('pane-1');
544
+ const userSelect = getComputedStyle(pane1).userSelect;
545
545
 
546
546
  if(userSelect !== 'none'){
547
547
  cleanup(container);
@@ -611,19 +611,190 @@ export default {
611
611
  const { container, split } = await createSplit();
612
612
 
613
613
  split.handleDragStart();
614
- const startWidth = split.dragStartWidth;
614
+ const startSize = split.dragStartSize;
615
615
  split.handleDrag({ x: 100, y: 0 });
616
616
 
617
- const leftWidth = split.style.getPropertyValue('--left_width');
618
- const expectedWidth = `${startWidth + 100}px`;
617
+ const pane1Size = split.style.getPropertyValue('--pane_1_size');
618
+ const expectedSize = `${startSize + 100}px`;
619
619
 
620
- if(leftWidth !== expectedWidth){
620
+ if(pane1Size !== expectedSize){
621
621
  cleanup(container);
622
- fail(`Expected --left_width ${expectedWidth}, got ${leftWidth}`);
622
+ fail(`Expected --pane_1_size ${expectedSize}, got ${pane1Size}`);
623
623
  return;
624
624
  }
625
625
 
626
626
  cleanup(container);
627
627
  pass('Size updates during drag');
628
+ },
629
+
630
+ 'should have default direction as horizontal': async ({pass, fail}) => {
631
+ const { container, split } = await createSplit();
632
+
633
+ if(split.direction !== 'horizontal'){
634
+ cleanup(container);
635
+ fail(`Expected direction to be horizontal, got ${split.direction}`);
636
+ return;
637
+ }
638
+
639
+ cleanup(container);
640
+ pass('Default direction is horizontal');
641
+ },
642
+
643
+ 'should accept direction="vertical" attribute': async ({pass, fail}) => {
644
+ const { container, split } = await createSplit({ direction: 'vertical' });
645
+
646
+ if(split.direction !== 'vertical'){
647
+ cleanup(container);
648
+ fail(`Expected direction to be vertical, got ${split.direction}`);
649
+ return;
650
+ }
651
+
652
+ if(!split.hasAttribute('direction') || split.getAttribute('direction') !== 'vertical'){
653
+ cleanup(container);
654
+ fail('direction attribute should be reflected as vertical');
655
+ return;
656
+ }
657
+
658
+ cleanup(container);
659
+ pass('direction="vertical" attribute accepted and reflected');
660
+ },
661
+
662
+ 'should have ns-resize cursor on divider handle when vertical': async ({pass, fail}) => {
663
+ const { container, split } = await createSplit({ direction: 'vertical' });
664
+
665
+ const handle = split.shadowRoot.getElementById('divider-handle');
666
+ const cursor = getComputedStyle(handle).cursor;
667
+
668
+ if(cursor !== 'ns-resize'){
669
+ cleanup(container);
670
+ fail(`Expected cursor ns-resize for vertical split, got ${cursor}`);
671
+ return;
672
+ }
673
+
674
+ cleanup(container);
675
+ pass('Divider handle has ns-resize cursor in vertical mode');
676
+ },
677
+
678
+ 'setSize should set --pane_1_size CSS property in vertical mode': async ({pass, fail}) => {
679
+ const { container, split } = await createSplit({ direction: 'vertical' });
680
+
681
+ split.setSize('200px');
682
+ const pane1Size = split.style.getPropertyValue('--pane_1_size');
683
+
684
+ if(pane1Size !== '200px'){
685
+ cleanup(container);
686
+ fail(`Expected --pane_1_size to be 200px, got ${pane1Size}`);
687
+ return;
688
+ }
689
+
690
+ cleanup(container);
691
+ pass('setSize sets --pane_1_size property in vertical mode');
692
+ },
693
+
694
+ 'should update size during vertical drag': async ({pass, fail}) => {
695
+ const { container, split } = await createSplit({ direction: 'vertical' });
696
+
697
+ split.handleDragStart();
698
+ const startSize = split.dragStartSize;
699
+ split.handleDrag({ x: 0, y: 80 });
700
+
701
+ const pane1Size = split.style.getPropertyValue('--pane_1_size');
702
+ const expectedSize = `${startSize + 80}px`;
703
+
704
+ if(pane1Size !== expectedSize){
705
+ cleanup(container);
706
+ fail(`Expected --pane_1_size ${expectedSize}, got ${pane1Size}`);
707
+ return;
708
+ }
709
+
710
+ cleanup(container);
711
+ pass('Size updates during vertical drag');
712
+ },
713
+
714
+ 'should have default persistentId as null': async ({pass, fail}) => {
715
+ const { container, split } = await createSplit();
716
+
717
+ if(split.persistentId !== null){
718
+ cleanup(container);
719
+ fail(`Expected persistentId to be null, got ${split.persistentId}`);
720
+ return;
721
+ }
722
+
723
+ cleanup(container);
724
+ pass('Default persistentId is null');
725
+ },
726
+
727
+ 'should accept persistent-id attribute': async ({pass, fail}) => {
728
+ const { container, split } = await createSplit({ persistentId: 'my-split' });
729
+
730
+ if(split.persistentId !== 'my-split'){
731
+ cleanup(container);
732
+ fail(`Expected persistentId to be "my-split", got ${split.persistentId}`);
733
+ return;
734
+ }
735
+
736
+ cleanup(container);
737
+ pass('persistent-id attribute accepted');
738
+ },
739
+
740
+ 'should save size to localStorage on drag end when persistentId is set': async ({pass, fail}) => {
741
+ const key = 'split-persistent-id-save-test';
742
+ window.localStorage.removeItem(key);
743
+
744
+ const { container, split } = await createSplit({ persistentId: 'save-test' });
745
+
746
+ split.handleDragStart();
747
+ split.handleDragEnd({ x: 100, y: 0 });
748
+
749
+ const saved = window.localStorage.getItem(key);
750
+
751
+ if(!saved){
752
+ cleanup(container);
753
+ window.localStorage.removeItem(key);
754
+ fail('Size should be saved to localStorage on drag end');
755
+ return;
756
+ }
757
+
758
+ cleanup(container);
759
+ window.localStorage.removeItem(key);
760
+ pass('Size saved to localStorage on drag end');
761
+ },
762
+
763
+ 'should not save to localStorage on drag end when persistentId is not set': async ({pass, fail}) => {
764
+ const { container, split } = await createSplit();
765
+
766
+ const keysBefore = Object.keys(window.localStorage).filter(k => k.startsWith('split-persistent-id-'));
767
+ split.handleDragStart();
768
+ split.handleDragEnd({ x: 100, y: 0 });
769
+ const keysAfter = Object.keys(window.localStorage).filter(k => k.startsWith('split-persistent-id-'));
770
+
771
+ if(keysAfter.length !== keysBefore.length){
772
+ cleanup(container);
773
+ fail('Should not save to localStorage when persistentId is not set');
774
+ return;
775
+ }
776
+
777
+ cleanup(container);
778
+ pass('Does not save to localStorage when persistentId is not set');
779
+ },
780
+
781
+ 'should restore size from localStorage when persistentId is set': async ({pass, fail}) => {
782
+ const key = 'split-persistent-id-restore-test';
783
+ window.localStorage.setItem(key, '350px');
784
+
785
+ const { container, split } = await createSplit({ persistentId: 'restore-test' });
786
+
787
+ const pane1Size = split.style.getPropertyValue('--pane_1_size');
788
+
789
+ window.localStorage.removeItem(key);
790
+
791
+ if(pane1Size !== '350px'){
792
+ cleanup(container);
793
+ fail(`Expected --pane_1_size to be 350px (restored from localStorage), got ${pane1Size}`);
794
+ return;
795
+ }
796
+
797
+ cleanup(container);
798
+ pass('Size restored from localStorage when persistentId is set');
628
799
  }
629
800
  };