kempo-ui 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/get_icon.js +0 -0
- package/bin/highlight_code.js +0 -0
- package/bin/icon.js +0 -0
- package/bin/list_icons.js +0 -0
- package/dist/components/Split.js +31 -13
- package/docs/components/split.html +28 -3
- package/docs/src/components/Split.js +31 -13
- package/docs-src/components/split.page.html +28 -3
- package/package.json +1 -1
- package/src/components/Split.js +163 -132
package/bin/get_icon.js
CHANGED
|
File without changes
|
package/bin/highlight_code.js
CHANGED
|
File without changes
|
package/bin/icon.js
CHANGED
|
File without changes
|
package/bin/list_icons.js
CHANGED
|
File without changes
|
package/dist/components/Split.js
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
|
-
import{html as e,css as t}from"../lit-all.min.js";import i from"./ShadowComponent.js";import s from"../utils/drag.js";export default class
|
|
1
|
+
import{html as e,css as t}from"../lit-all.min.js";import i from"./ShadowComponent.js";import s from"../utils/drag.js";import{boolExists as r}from"../utils/propConverters.js";export default class d extends i{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"},grip:{type:Boolean,reflect:!0,converter:r}};constructor(){super(),this.resizing=!1,this.stacked=!1,this.stackWidth=0,this.direction="horizontal",this.persistentId=null,this.grip=!1,this.dragStartSize=0,this.dragCleanup=()=>{},this.resizeObserver=null}firstUpdated(){if(super.firstUpdated(),this.grip){const e=document.createElement("div");e.style.cssText="position:absolute;visibility:hidden;width:var(--handle_width)",this.shadowRoot.appendChild(e);const t=e.offsetWidth;this.shadowRoot.removeChild(e);const i=t%2==0?t-1:t;this.style.setProperty("--handle_grip_width",`${i}px`)}if(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=s({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)}render(){return e`
|
|
2
|
+
<div id="pane-1" class="pane">
|
|
3
|
+
<slot></slot>
|
|
4
|
+
</div>
|
|
5
|
+
<div id="divider-handle">
|
|
6
|
+
<div id="divider-border">
|
|
7
|
+
${this.grip?e`<div id="divider-grip"></div>`:""}
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
10
|
+
<div id="pane-2" class="pane">
|
|
11
|
+
<slot name="right"></slot>
|
|
12
|
+
</div>
|
|
13
|
+
`}static styles=t`
|
|
2
14
|
:host {
|
|
3
15
|
--pane_1_size: calc((100% - var(--handle_width)) / 2);
|
|
4
|
-
--handle_width:
|
|
16
|
+
--handle_width: 7px;
|
|
5
17
|
--min_pane_size: 6rem;
|
|
6
18
|
|
|
7
19
|
height: 100%;
|
|
@@ -27,6 +39,7 @@ import{html as e,css as t}from"../lit-all.min.js";import i from"./ShadowComponen
|
|
|
27
39
|
}
|
|
28
40
|
|
|
29
41
|
#divider-handle {
|
|
42
|
+
position: relative;
|
|
30
43
|
display: flex;
|
|
31
44
|
flex-shrink: 0;
|
|
32
45
|
justify-content: center;
|
|
@@ -47,10 +60,21 @@ import{html as e,css as t}from"../lit-all.min.js";import i from"./ShadowComponen
|
|
|
47
60
|
}
|
|
48
61
|
|
|
49
62
|
#divider-border {
|
|
63
|
+
position: relative;
|
|
50
64
|
width: 1px;
|
|
51
65
|
height: 100%;
|
|
52
66
|
border-left: 1px solid var(--c_border);
|
|
53
67
|
}
|
|
68
|
+
#divider-grip {
|
|
69
|
+
position: absolute;
|
|
70
|
+
top: 50%;
|
|
71
|
+
left: 50%;
|
|
72
|
+
transform: translate(-50%, -50%);
|
|
73
|
+
width: var(--handle_grip_width, var(--handle_width));
|
|
74
|
+
height: 2rem;
|
|
75
|
+
border-radius: 0.25rem;
|
|
76
|
+
background-color: var(--c_border);
|
|
77
|
+
}
|
|
54
78
|
|
|
55
79
|
#pane-2 {
|
|
56
80
|
flex: 1 1;
|
|
@@ -105,14 +129,8 @@ import{html as e,css as t}from"../lit-all.min.js";import i from"./ShadowComponen
|
|
|
105
129
|
border-left: none;
|
|
106
130
|
border-top: 1px solid var(--c_border);
|
|
107
131
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
<div id="divider-border"></div>
|
|
114
|
-
</div>
|
|
115
|
-
<div id="pane-2" class="pane">
|
|
116
|
-
<slot name="right"></slot>
|
|
117
|
-
</div>
|
|
118
|
-
`}}customElements.define("k-split",r);
|
|
132
|
+
:host([direction="vertical"]) #divider-grip {
|
|
133
|
+
width: 2rem;
|
|
134
|
+
height: 0.5rem;
|
|
135
|
+
}
|
|
136
|
+
`}customElements.define("k-split",d);
|
|
@@ -451,6 +451,7 @@
|
|
|
451
451
|
<a href="#resizing">Resizing</a><br />
|
|
452
452
|
<a href="#verticalSplit">Vertical Split</a><br />
|
|
453
453
|
<a href="#persistentState">Persistent State</a><br />
|
|
454
|
+
<a href="#grip">Grip</a><br />
|
|
454
455
|
<h6 class="mt"><a href="#jsRef" class="no-link">JavaScript Reference</a></h6>
|
|
455
456
|
<a href="#constructor">Constructor</a><br />
|
|
456
457
|
<a href="#requirements">Requirements</a><br />
|
|
@@ -501,11 +502,11 @@
|
|
|
501
502
|
<h3>Sizes</h3>
|
|
502
503
|
<p>Set the CSS Custom Property <code>--pane_1_size</code> to set the initial size of the first pane.</p>
|
|
503
504
|
<p>Set the CSS Custom Property <code>--min_pane_size</code> to set the minimum size each pane can be.</p>
|
|
504
|
-
<p>Set the CSS Custom Property <code>--handle_width</code> to set the size of the handle (the draggable region between the panes).</p>
|
|
505
|
+
<p>Set the CSS Custom Property <code>--handle_width</code> to set the size of the handle (the draggable region between the panes), odd sizes are recommended so it can be centered on the border.</p>
|
|
505
506
|
<div class="row -mx">
|
|
506
507
|
<div class="col m-span-12 px">
|
|
507
508
|
<k-card label="HTML">
|
|
508
|
-
<pre><code class="hljs xml"><span class="hljs-tag"><<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:
|
|
509
|
+
<pre><code class="hljs xml"><span class="hljs-tag"><<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: 19px;<br /> height: 10rem<br /> "</span><br /> <span class="hljs-attr">class</span>=<span class="hljs-string">"b"</span><br />></span><br /> <span class="hljs-tag"><<span class="hljs-name">p</span>></span>left<span class="hljs-tag"></<span class="hljs-name">p</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">p</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"right"</span>></span>right<span class="hljs-tag"></<span class="hljs-name">p</span>></span><br /><span class="hljs-tag"></<span class="hljs-name">k-split</span>></span></code></pre>
|
|
509
510
|
</k-card>
|
|
510
511
|
</div>
|
|
511
512
|
<div class="col m-span-12 px">
|
|
@@ -514,7 +515,7 @@
|
|
|
514
515
|
style="
|
|
515
516
|
--pane_1_size: 100px;
|
|
516
517
|
--min_pane_size: 100px;
|
|
517
|
-
--handle_width:
|
|
518
|
+
--handle_width: 19px;
|
|
518
519
|
height: 10rem
|
|
519
520
|
"
|
|
520
521
|
class="b"
|
|
@@ -583,6 +584,28 @@
|
|
|
583
584
|
</div>
|
|
584
585
|
</div>
|
|
585
586
|
|
|
587
|
+
<h3 id="grip"><a href="#grip" class="no-link">Grip</a></h3>
|
|
588
|
+
<p>Add the <code>grip</code> attribute to render a visual grip indicator centered on the divider handle, making it easier to identify the draggable area.</p>
|
|
589
|
+
<div class="row -mx mb">
|
|
590
|
+
<div class="col d-span-6 m-span-12 px">
|
|
591
|
+
<k-card label="HTML">
|
|
592
|
+
<pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">k-split</span> <span class="hljs-attr">grip</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 mb"</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">div</span>></span>Left Pane Content<span class="hljs-tag"></<span class="hljs-name">div</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"right"</span>></span>Right Pane Content<span class="hljs-tag"></<span class="hljs-name">div</span>></span><br /><span class="hljs-tag"></<span class="hljs-name">k-split</span>></span><br /><span class="hljs-tag"><<span class="hljs-name">k-split</span> <span class="hljs-attr">grip</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>></span><br /> <span class="hljs-tag"><<span class="hljs-name">div</span>></span>Top Pane Content<span class="hljs-tag"></<span class="hljs-name">div</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"right"</span>></span>Bottom Pane Content<span class="hljs-tag"></<span class="hljs-name">div</span>></span><br /><span class="hljs-tag"></<span class="hljs-name">k-split</span>></span></code></pre>
|
|
593
|
+
</k-card>
|
|
594
|
+
</div>
|
|
595
|
+
<div class="col d-span-6 m-span-12 px">
|
|
596
|
+
<k-card label="Results">
|
|
597
|
+
<k-split grip style="height: 10rem" class="b mb">
|
|
598
|
+
<div>Left Pane Content</div>
|
|
599
|
+
<div slot="right">Right Pane Content</div>
|
|
600
|
+
</k-split>
|
|
601
|
+
<k-split grip direction="vertical" style="height: 16rem" class="b">
|
|
602
|
+
<div>Top Pane Content</div>
|
|
603
|
+
<div slot="right">Bottom Pane Content</div>
|
|
604
|
+
</k-split>
|
|
605
|
+
</k-card>
|
|
606
|
+
</div>
|
|
607
|
+
</div>
|
|
608
|
+
|
|
586
609
|
<h2 id="jsRef">JavaScript Reference</h2>
|
|
587
610
|
|
|
588
611
|
<h3 id="constructor"><a href="#constructor" class="no-link">Constructor</a></h3>
|
|
@@ -607,6 +630,8 @@
|
|
|
607
630
|
<p>The direction of the split. Can be <code>"horizontal"</code> (default) or <code>"vertical"</code>. Syncs to <code>direction</code> attribute.</p>
|
|
608
631
|
<h5><code>persistentId<i>: string</i></code></h5>
|
|
609
632
|
<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>
|
|
633
|
+
<h5><code>grip<i>: boolean</i></code></h5>
|
|
634
|
+
<p>When set, renders a visual grip indicator centered on the divider handle. Syncs to <code>grip</code> attribute.</p>
|
|
610
635
|
|
|
611
636
|
<h3 id="cssCustomProperties"><a href="#cssCustomProperties" class="no-link">CSS Custom Properties</a></h3>
|
|
612
637
|
<h5><code>--pane_1_size</code></h5>
|
|
@@ -1,7 +1,19 @@
|
|
|
1
|
-
import{html as e,css as t}from"../lit-all.min.js";import i from"./ShadowComponent.js";import s from"../utils/drag.js";export default class
|
|
1
|
+
import{html as e,css as t}from"../lit-all.min.js";import i from"./ShadowComponent.js";import s from"../utils/drag.js";import{boolExists as r}from"../utils/propConverters.js";export default class d extends i{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"},grip:{type:Boolean,reflect:!0,converter:r}};constructor(){super(),this.resizing=!1,this.stacked=!1,this.stackWidth=0,this.direction="horizontal",this.persistentId=null,this.grip=!1,this.dragStartSize=0,this.dragCleanup=()=>{},this.resizeObserver=null}firstUpdated(){if(super.firstUpdated(),this.grip){const e=document.createElement("div");e.style.cssText="position:absolute;visibility:hidden;width:var(--handle_width)",this.shadowRoot.appendChild(e);const t=e.offsetWidth;this.shadowRoot.removeChild(e);const i=t%2==0?t-1:t;this.style.setProperty("--handle_grip_width",`${i}px`)}if(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=s({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)}render(){return e`
|
|
2
|
+
<div id="pane-1" class="pane">
|
|
3
|
+
<slot></slot>
|
|
4
|
+
</div>
|
|
5
|
+
<div id="divider-handle">
|
|
6
|
+
<div id="divider-border">
|
|
7
|
+
${this.grip?e`<div id="divider-grip"></div>`:""}
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
10
|
+
<div id="pane-2" class="pane">
|
|
11
|
+
<slot name="right"></slot>
|
|
12
|
+
</div>
|
|
13
|
+
`}static styles=t`
|
|
2
14
|
:host {
|
|
3
15
|
--pane_1_size: calc((100% - var(--handle_width)) / 2);
|
|
4
|
-
--handle_width:
|
|
16
|
+
--handle_width: 7px;
|
|
5
17
|
--min_pane_size: 6rem;
|
|
6
18
|
|
|
7
19
|
height: 100%;
|
|
@@ -27,6 +39,7 @@ import{html as e,css as t}from"../lit-all.min.js";import i from"./ShadowComponen
|
|
|
27
39
|
}
|
|
28
40
|
|
|
29
41
|
#divider-handle {
|
|
42
|
+
position: relative;
|
|
30
43
|
display: flex;
|
|
31
44
|
flex-shrink: 0;
|
|
32
45
|
justify-content: center;
|
|
@@ -47,10 +60,21 @@ import{html as e,css as t}from"../lit-all.min.js";import i from"./ShadowComponen
|
|
|
47
60
|
}
|
|
48
61
|
|
|
49
62
|
#divider-border {
|
|
63
|
+
position: relative;
|
|
50
64
|
width: 1px;
|
|
51
65
|
height: 100%;
|
|
52
66
|
border-left: 1px solid var(--c_border);
|
|
53
67
|
}
|
|
68
|
+
#divider-grip {
|
|
69
|
+
position: absolute;
|
|
70
|
+
top: 50%;
|
|
71
|
+
left: 50%;
|
|
72
|
+
transform: translate(-50%, -50%);
|
|
73
|
+
width: var(--handle_grip_width, var(--handle_width));
|
|
74
|
+
height: 2rem;
|
|
75
|
+
border-radius: 0.25rem;
|
|
76
|
+
background-color: var(--c_border);
|
|
77
|
+
}
|
|
54
78
|
|
|
55
79
|
#pane-2 {
|
|
56
80
|
flex: 1 1;
|
|
@@ -105,14 +129,8 @@ import{html as e,css as t}from"../lit-all.min.js";import i from"./ShadowComponen
|
|
|
105
129
|
border-left: none;
|
|
106
130
|
border-top: 1px solid var(--c_border);
|
|
107
131
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
<div id="divider-border"></div>
|
|
114
|
-
</div>
|
|
115
|
-
<div id="pane-2" class="pane">
|
|
116
|
-
<slot name="right"></slot>
|
|
117
|
-
</div>
|
|
118
|
-
`}}customElements.define("k-split",r);
|
|
132
|
+
:host([direction="vertical"]) #divider-grip {
|
|
133
|
+
width: 2rem;
|
|
134
|
+
height: 0.5rem;
|
|
135
|
+
}
|
|
136
|
+
`}customElements.define("k-split",d);
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
<a href="#resizing">Resizing</a><br />
|
|
10
10
|
<a href="#verticalSplit">Vertical Split</a><br />
|
|
11
11
|
<a href="#persistentState">Persistent State</a><br />
|
|
12
|
+
<a href="#grip">Grip</a><br />
|
|
12
13
|
<h6 class="mt"><a href="#jsRef" class="no-link">JavaScript Reference</a></h6>
|
|
13
14
|
<a href="#constructor">Constructor</a><br />
|
|
14
15
|
<a href="#requirements">Requirements</a><br />
|
|
@@ -59,11 +60,11 @@
|
|
|
59
60
|
<h3>Sizes</h3>
|
|
60
61
|
<p>Set the CSS Custom Property <code>--pane_1_size</code> to set the initial size of the first pane.</p>
|
|
61
62
|
<p>Set the CSS Custom Property <code>--min_pane_size</code> to set the minimum size each pane can be.</p>
|
|
62
|
-
<p>Set the CSS Custom Property <code>--handle_width</code> to set the size of the handle (the draggable region between the panes).</p>
|
|
63
|
+
<p>Set the CSS Custom Property <code>--handle_width</code> to set the size of the handle (the draggable region between the panes), odd sizes are recommended so it can be centered on the border.</p>
|
|
63
64
|
<div class="row -mx">
|
|
64
65
|
<div class="col m-span-12 px">
|
|
65
66
|
<k-card label="HTML">
|
|
66
|
-
<pre><code class="hljs xml"><span class="hljs-tag"><<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:
|
|
67
|
+
<pre><code class="hljs xml"><span class="hljs-tag"><<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: 19px;<br /> height: 10rem<br /> "</span><br /> <span class="hljs-attr">class</span>=<span class="hljs-string">"b"</span><br />></span><br /> <span class="hljs-tag"><<span class="hljs-name">p</span>></span>left<span class="hljs-tag"></<span class="hljs-name">p</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">p</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"right"</span>></span>right<span class="hljs-tag"></<span class="hljs-name">p</span>></span><br /><span class="hljs-tag"></<span class="hljs-name">k-split</span>></span></code></pre>
|
|
67
68
|
</k-card>
|
|
68
69
|
</div>
|
|
69
70
|
<div class="col m-span-12 px">
|
|
@@ -72,7 +73,7 @@
|
|
|
72
73
|
style="
|
|
73
74
|
--pane_1_size: 100px;
|
|
74
75
|
--min_pane_size: 100px;
|
|
75
|
-
--handle_width:
|
|
76
|
+
--handle_width: 19px;
|
|
76
77
|
height: 10rem
|
|
77
78
|
"
|
|
78
79
|
class="b"
|
|
@@ -141,6 +142,28 @@
|
|
|
141
142
|
</div>
|
|
142
143
|
</div>
|
|
143
144
|
|
|
145
|
+
<h3 id="grip"><a href="#grip" class="no-link">Grip</a></h3>
|
|
146
|
+
<p>Add the <code>grip</code> attribute to render a visual grip indicator centered on the divider handle, making it easier to identify the draggable area.</p>
|
|
147
|
+
<div class="row -mx mb">
|
|
148
|
+
<div class="col d-span-6 m-span-12 px">
|
|
149
|
+
<k-card label="HTML">
|
|
150
|
+
<pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">k-split</span> <span class="hljs-attr">grip</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 mb"</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">div</span>></span>Left Pane Content<span class="hljs-tag"></<span class="hljs-name">div</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"right"</span>></span>Right Pane Content<span class="hljs-tag"></<span class="hljs-name">div</span>></span><br /><span class="hljs-tag"></<span class="hljs-name">k-split</span>></span><br /><span class="hljs-tag"><<span class="hljs-name">k-split</span> <span class="hljs-attr">grip</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>></span><br /> <span class="hljs-tag"><<span class="hljs-name">div</span>></span>Top Pane Content<span class="hljs-tag"></<span class="hljs-name">div</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"right"</span>></span>Bottom Pane Content<span class="hljs-tag"></<span class="hljs-name">div</span>></span><br /><span class="hljs-tag"></<span class="hljs-name">k-split</span>></span></code></pre>
|
|
151
|
+
</k-card>
|
|
152
|
+
</div>
|
|
153
|
+
<div class="col d-span-6 m-span-12 px">
|
|
154
|
+
<k-card label="Results">
|
|
155
|
+
<k-split grip style="height: 10rem" class="b mb">
|
|
156
|
+
<div>Left Pane Content</div>
|
|
157
|
+
<div slot="right">Right Pane Content</div>
|
|
158
|
+
</k-split>
|
|
159
|
+
<k-split grip direction="vertical" style="height: 16rem" class="b">
|
|
160
|
+
<div>Top Pane Content</div>
|
|
161
|
+
<div slot="right">Bottom Pane Content</div>
|
|
162
|
+
</k-split>
|
|
163
|
+
</k-card>
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
|
|
144
167
|
<h2 id="jsRef">JavaScript Reference</h2>
|
|
145
168
|
|
|
146
169
|
<h3 id="constructor"><a href="#constructor" class="no-link">Constructor</a></h3>
|
|
@@ -165,6 +188,8 @@
|
|
|
165
188
|
<p>The direction of the split. Can be <code>"horizontal"</code> (default) or <code>"vertical"</code>. Syncs to <code>direction</code> attribute.</p>
|
|
166
189
|
<h5><code>persistentId<i>: string</i></code></h5>
|
|
167
190
|
<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>
|
|
191
|
+
<h5><code>grip<i>: boolean</i></code></h5>
|
|
192
|
+
<p>When set, renders a visual grip indicator centered on the divider handle. Syncs to <code>grip</code> attribute.</p>
|
|
168
193
|
|
|
169
194
|
<h3 id="cssCustomProperties"><a href="#cssCustomProperties" class="no-link">CSS Custom Properties</a></h3>
|
|
170
195
|
<h5><code>--pane_1_size</code></h5>
|
package/package.json
CHANGED
package/src/components/Split.js
CHANGED
|
@@ -1,125 +1,157 @@
|
|
|
1
1
|
import { html, css } from '../lit-all.min.js';
|
|
2
2
|
import ShadowComponent from './ShadowComponent.js';
|
|
3
3
|
import drag from '../utils/drag.js';
|
|
4
|
+
import { boolExists } from '../utils/propConverters.js';
|
|
4
5
|
|
|
5
6
|
export default class Split extends ShadowComponent {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
7
|
+
static properties = {
|
|
8
|
+
resizing: { type: Boolean, reflect: true },
|
|
9
|
+
stacked: { type: Boolean, reflect: true },
|
|
10
|
+
stackWidth: { type: Number, attribute: 'stack-width' },
|
|
11
|
+
direction: { type: String, reflect: true },
|
|
12
|
+
persistentId: { type: String, reflect: true, attribute: 'persistent-id' },
|
|
13
|
+
grip: { type: Boolean, reflect: true, converter: boolExists }
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
constructor() {
|
|
17
|
+
super();
|
|
18
|
+
|
|
19
|
+
this.resizing = false;
|
|
20
|
+
this.stacked = false;
|
|
21
|
+
this.stackWidth = 0;
|
|
22
|
+
this.direction = 'horizontal';
|
|
23
|
+
this.persistentId = null;
|
|
24
|
+
this.grip = false;
|
|
25
|
+
|
|
26
|
+
// Private state
|
|
27
|
+
this.dragStartSize = 0;
|
|
28
|
+
this.dragCleanup = () => { };
|
|
29
|
+
this.resizeObserver = null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/*
|
|
33
|
+
Lifecycle Callbacks
|
|
34
|
+
*/
|
|
35
|
+
firstUpdated() {
|
|
36
|
+
super.firstUpdated();
|
|
37
|
+
if(this.grip){
|
|
38
|
+
const el = document.createElement('div');
|
|
39
|
+
el.style.cssText = 'position:absolute;visibility:hidden;width:var(--handle_width)';
|
|
40
|
+
this.shadowRoot.appendChild(el);
|
|
41
|
+
const handleWidth = el.offsetWidth;
|
|
42
|
+
this.shadowRoot.removeChild(el);
|
|
43
|
+
const gripWidth = handleWidth % 2 === 0 ? handleWidth - 1 : handleWidth;
|
|
44
|
+
this.style.setProperty('--handle_grip_width', `${gripWidth}px`);
|
|
45
|
+
}
|
|
46
|
+
this.setupDragHandler();
|
|
47
|
+
this.setupResizeObserver();
|
|
48
|
+
if (this.persistentId && window?.localStorage) {
|
|
49
|
+
const size = window.localStorage.getItem(`split-persistent-id-${this.persistentId}`);
|
|
50
|
+
if (size) this.setSize(size);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
disconnectedCallback() {
|
|
55
|
+
super.disconnectedCallback();
|
|
56
|
+
this.dragCleanup();
|
|
57
|
+
if (this.resizeObserver) {
|
|
58
|
+
this.resizeObserver.disconnect();
|
|
59
|
+
this.resizeObserver = null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/*
|
|
64
|
+
Event Handlers
|
|
65
|
+
*/
|
|
66
|
+
handleDragStart = () => {
|
|
67
|
+
this.resizing = true;
|
|
68
|
+
this.dragStartSize = Math.round(this.shadowRoot.getElementById('pane-1').getBoundingClientRect()[this.direction === 'vertical' ? 'height' : 'width']);
|
|
69
|
+
this.dispatchEvent(new CustomEvent('resizestart', {
|
|
70
|
+
detail: { startSize: this.dragStartSize },
|
|
71
|
+
bubbles: true
|
|
72
|
+
}));
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
handleDrag = ({ x, y }) => {
|
|
76
|
+
const delta = this.direction === 'vertical' ? y : x;
|
|
77
|
+
const size = `${this.dragStartSize + delta}px`;
|
|
78
|
+
this.setSize(size);
|
|
79
|
+
this.dispatchEvent(new CustomEvent('resize', {
|
|
80
|
+
detail: { size },
|
|
81
|
+
bubbles: true
|
|
82
|
+
}));
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
handleDragEnd = ({ x, y }) => {
|
|
86
|
+
this.resizing = false;
|
|
87
|
+
const delta = this.direction === 'vertical' ? y : x;
|
|
88
|
+
const size = `${this.dragStartSize + delta}px`;
|
|
89
|
+
this.setSize(size);
|
|
90
|
+
if (this.persistentId && window?.localStorage) {
|
|
91
|
+
window.localStorage.setItem(`split-persistent-id-${this.persistentId}`, size);
|
|
92
|
+
}
|
|
93
|
+
this.dispatchEvent(new CustomEvent('resizeend', {
|
|
94
|
+
detail: { size },
|
|
95
|
+
bubbles: true
|
|
96
|
+
}));
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
/*
|
|
100
|
+
Public Methods
|
|
101
|
+
*/
|
|
102
|
+
setSize(size) {
|
|
103
|
+
this.style.setProperty('--pane_1_size', size);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
setupDragHandler() {
|
|
107
|
+
const handle = this.shadowRoot.getElementById('divider-handle');
|
|
108
|
+
if (handle) {
|
|
109
|
+
this.dragCleanup = drag({
|
|
110
|
+
element: handle,
|
|
111
|
+
callback: this.handleDrag,
|
|
112
|
+
startCallback: this.handleDragStart,
|
|
113
|
+
endCallback: this.handleDragEnd
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
setupResizeObserver() {
|
|
119
|
+
this.resizeObserver = new ResizeObserver(entries => {
|
|
120
|
+
for (const entry of entries) {
|
|
121
|
+
const width = entry.contentRect.width;
|
|
122
|
+
this.stacked = width <= this.stackWidth;
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
this.resizeObserver.observe(this);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/*
|
|
129
|
+
Styles
|
|
130
|
+
*/
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
/*
|
|
134
|
+
Rendering
|
|
135
|
+
*/
|
|
136
|
+
render() {
|
|
137
|
+
return html`
|
|
138
|
+
<div id="pane-1" class="pane">
|
|
139
|
+
<slot></slot>
|
|
140
|
+
</div>
|
|
141
|
+
<div id="divider-handle">
|
|
142
|
+
<div id="divider-border">
|
|
143
|
+
${this.grip ? html`<div id="divider-grip"></div>` : ''}
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
<div id="pane-2" class="pane">
|
|
147
|
+
<slot name="right"></slot>
|
|
148
|
+
</div>
|
|
149
|
+
`;
|
|
150
|
+
}
|
|
151
|
+
static styles = css`
|
|
120
152
|
:host {
|
|
121
153
|
--pane_1_size: calc((100% - var(--handle_width)) / 2);
|
|
122
|
-
--handle_width:
|
|
154
|
+
--handle_width: 7px;
|
|
123
155
|
--min_pane_size: 6rem;
|
|
124
156
|
|
|
125
157
|
height: 100%;
|
|
@@ -145,6 +177,7 @@ export default class Split extends ShadowComponent {
|
|
|
145
177
|
}
|
|
146
178
|
|
|
147
179
|
#divider-handle {
|
|
180
|
+
position: relative;
|
|
148
181
|
display: flex;
|
|
149
182
|
flex-shrink: 0;
|
|
150
183
|
justify-content: center;
|
|
@@ -165,10 +198,21 @@ export default class Split extends ShadowComponent {
|
|
|
165
198
|
}
|
|
166
199
|
|
|
167
200
|
#divider-border {
|
|
201
|
+
position: relative;
|
|
168
202
|
width: 1px;
|
|
169
203
|
height: 100%;
|
|
170
204
|
border-left: 1px solid var(--c_border);
|
|
171
205
|
}
|
|
206
|
+
#divider-grip {
|
|
207
|
+
position: absolute;
|
|
208
|
+
top: 50%;
|
|
209
|
+
left: 50%;
|
|
210
|
+
transform: translate(-50%, -50%);
|
|
211
|
+
width: var(--handle_grip_width, var(--handle_width));
|
|
212
|
+
height: 2rem;
|
|
213
|
+
border-radius: 0.25rem;
|
|
214
|
+
background-color: var(--c_border);
|
|
215
|
+
}
|
|
172
216
|
|
|
173
217
|
#pane-2 {
|
|
174
218
|
flex: 1 1;
|
|
@@ -223,24 +267,11 @@ export default class Split extends ShadowComponent {
|
|
|
223
267
|
border-left: none;
|
|
224
268
|
border-top: 1px solid var(--c_border);
|
|
225
269
|
}
|
|
270
|
+
:host([direction="vertical"]) #divider-grip {
|
|
271
|
+
width: 2rem;
|
|
272
|
+
height: 0.5rem;
|
|
273
|
+
}
|
|
226
274
|
`;
|
|
227
|
-
|
|
228
|
-
/*
|
|
229
|
-
Rendering
|
|
230
|
-
*/
|
|
231
|
-
render() {
|
|
232
|
-
return html`
|
|
233
|
-
<div id="pane-1" class="pane">
|
|
234
|
-
<slot></slot>
|
|
235
|
-
</div>
|
|
236
|
-
<div id="divider-handle">
|
|
237
|
-
<div id="divider-border"></div>
|
|
238
|
-
</div>
|
|
239
|
-
<div id="pane-2" class="pane">
|
|
240
|
-
<slot name="right"></slot>
|
|
241
|
-
</div>
|
|
242
|
-
`;
|
|
243
|
-
}
|
|
244
275
|
}
|
|
245
276
|
|
|
246
277
|
customElements.define('k-split', Split);
|