kempo-ui 0.0.63 → 0.0.65
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,4 +1,4 @@
|
|
|
1
|
-
import ShadowComponent from"./ShadowComponent.js";import{html,css,nothing}from"../lit-all.min.js";import"./Icon.js";class SidePanel extends ShadowComponent{static properties={collapsed:{type:Boolean,reflect:!0},side:{type:String,reflect:!0}};constructor(){super(),this.collapsed=!1,this.side="left"}toggleClick=()=>this.toggle();updated(e){if(super.updated(e),e.has("collapsed")){const e=this.collapsed?"collapse":"expand";this.dispatchEvent(new CustomEvent(e)),this.dispatchEvent(new CustomEvent("change",{detail:e})),window.dispatchEvent(new CustomEvent("side-panel-change",{detail:{collapsed:this.collapsed,width:this.collapsed?"3.5rem":"16rem",side:this.side}}))}}expand=()=>this.collapsed=!1;collapse=()=>this.collapsed=!0;toggle(){this.collapsed=!this.collapsed,this.dispatchEvent(new CustomEvent("toggle"))}render(){return html`
|
|
1
|
+
import ShadowComponent from"./ShadowComponent.js";import{html,css,nothing}from"../lit-all.min.js";import"./Icon.js";class SidePanel extends ShadowComponent{static properties={collapsed:{type:Boolean,reflect:!0},side:{type:String,reflect:!0},persistentId:{type:String,reflect:!0,attribute:"persistent-id"}};constructor(){super(),this.collapsed=!1,this.side="left",this.persistentId=null,this.isInitialLoad=!0}toggleClick=()=>this.toggle();updated(e){if(super.updated(e),e.has("persistentId")&&this.persistentId&&window?.localStorage){const e=`side-panel-persistent-id-${this.persistentId}`,t=window.localStorage.getItem(e);null!==t&&(this.collapsed="true"===t,this.isInitialLoad=!1)}if(e.has("collapsed")){if(this.persistentId&&window?.localStorage&&!this.isInitialLoad){const e=`side-panel-persistent-id-${this.persistentId}`;window.localStorage.setItem(e,this.collapsed.toString())}this.isInitialLoad=!1;const e=this.collapsed?"collapse":"expand";this.dispatchEvent(new CustomEvent(e)),this.dispatchEvent(new CustomEvent("change",{detail:e})),window.dispatchEvent(new CustomEvent("side-panel-change",{detail:{collapsed:this.collapsed,width:this.collapsed?"3.5rem":"16rem",side:this.side}}))}}expand=()=>this.collapsed=!1;collapse=()=>this.collapsed=!0;toggle(){this.collapsed=!this.collapsed,this.dispatchEvent(new CustomEvent("toggle"))}render(){return html`
|
|
2
2
|
<div id="header">
|
|
3
3
|
<slot name="logo"></slot>
|
|
4
4
|
<button id="toggle" @click=${this.toggleClick} aria-label="${this.collapsed?"Expand panel":"Collapse panel"}">
|
|
@@ -23,7 +23,7 @@ import ShadowComponent from"./ShadowComponent.js";import{html,css,nothing}from".
|
|
|
23
23
|
transition: width var(--transition-duration);
|
|
24
24
|
background: var(--bg);
|
|
25
25
|
border-right: 1px solid var(--c_border);
|
|
26
|
-
z-index:
|
|
26
|
+
z-index: 99;
|
|
27
27
|
}
|
|
28
28
|
:host([collapsed]) {
|
|
29
29
|
width: auto;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>SidePanel Persistent State Example</title>
|
|
7
|
+
<link rel="stylesheet" href="../kempo-vars.css" />
|
|
8
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/kempo-css@1.3.2/dist/kempo.min.css" />
|
|
9
|
+
<script>window.litDisableBundleWarning = true;</script>
|
|
10
|
+
<script type="module">
|
|
11
|
+
import theme from '../src/utils/theme.js';
|
|
12
|
+
theme.init();
|
|
13
|
+
</script>
|
|
14
|
+
<script type="module" src="../src/components/SidePanel.js"></script>
|
|
15
|
+
<script type="module" src="../src/components/Main.js"></script>
|
|
16
|
+
<style>
|
|
17
|
+
body {
|
|
18
|
+
margin: 0;
|
|
19
|
+
padding: 0;
|
|
20
|
+
}
|
|
21
|
+
</style>
|
|
22
|
+
</head>
|
|
23
|
+
<body>
|
|
24
|
+
<k-side-panel persistent-id="demo-panel">
|
|
25
|
+
<h3 slot="logo" class="m0">My App</h3>
|
|
26
|
+
<k-side-panel-item icon="cards" href="#" active>Dashboard</k-side-panel-item>
|
|
27
|
+
<k-side-panel-item icon="check" href="#">Tasks</k-side-panel-item>
|
|
28
|
+
<k-side-panel-item icon="label" href="#">Email</k-side-panel-item>
|
|
29
|
+
<k-side-panel-label>Projects</k-side-panel-label>
|
|
30
|
+
<k-side-panel-item icon="folder" href="#">Website Redesign</k-side-panel-item>
|
|
31
|
+
<k-side-panel-item icon="folder" href="#">Mobile App</k-side-panel-item>
|
|
32
|
+
<k-side-panel-spacer></k-side-panel-spacer>
|
|
33
|
+
<k-side-panel-item icon="settings" href="#">Settings</k-side-panel-item>
|
|
34
|
+
<k-side-panel-item icon="account-circle" href="#">Profile</k-side-panel-item>
|
|
35
|
+
</k-side-panel>
|
|
36
|
+
|
|
37
|
+
<k-main>
|
|
38
|
+
<h1>Persistent State Demo</h1>
|
|
39
|
+
<p>This side panel has <code>persistent-id="demo-panel"</code> set, which means it saves its collapsed/expanded state to localStorage.</p>
|
|
40
|
+
|
|
41
|
+
<h2>Try It Out</h2>
|
|
42
|
+
<ol>
|
|
43
|
+
<li>Click the toggle arrow to collapse or expand the side panel</li>
|
|
44
|
+
<li>Refresh the page (or this iframe)</li>
|
|
45
|
+
<li>Notice the panel returns to the same state you left it in</li>
|
|
46
|
+
</ol>
|
|
47
|
+
|
|
48
|
+
<h2>How It Works</h2>
|
|
49
|
+
<p>When you set the <code>persistent-id</code> attribute, the component:</p>
|
|
50
|
+
<ul>
|
|
51
|
+
<li>Saves the collapsed state to <code>localStorage</code> whenever it changes</li>
|
|
52
|
+
<li>Restores the saved state when the component mounts</li>
|
|
53
|
+
<li>Uses the key format: <code>side-panel-persistent-id-{persistentId}</code></li>
|
|
54
|
+
</ul>
|
|
55
|
+
|
|
56
|
+
<p>This is useful for preserving user preferences across sessions, making your application feel more responsive and personalized.</p>
|
|
57
|
+
|
|
58
|
+
<div style="margin-top: 2rem; padding: 1rem; background: var(--c_bg__alt); border-radius: var(--radius);">
|
|
59
|
+
<h3>Technical Details</h3>
|
|
60
|
+
<p><strong>LocalStorage Key:</strong> <code>side-panel-persistent-id-demo-panel</code></p>
|
|
61
|
+
<p><strong>Stored Value:</strong> <code id="stored-value">Loading...</code></p>
|
|
62
|
+
<button onclick="clearStorage()" class="btn">Clear Stored State</button>
|
|
63
|
+
</div>
|
|
64
|
+
</k-main>
|
|
65
|
+
|
|
66
|
+
<script>
|
|
67
|
+
function updateStoredValue() {
|
|
68
|
+
const value = localStorage.getItem('side-panel-persistent-id-demo-panel');
|
|
69
|
+
document.getElementById('stored-value').textContent = value || 'null (not set)';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function clearStorage() {
|
|
73
|
+
localStorage.removeItem('side-panel-persistent-id-demo-panel');
|
|
74
|
+
updateStoredValue();
|
|
75
|
+
window.location.reload();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Update on load
|
|
79
|
+
updateStoredValue();
|
|
80
|
+
|
|
81
|
+
// Update when storage changes
|
|
82
|
+
window.addEventListener('storage', updateStoredValue);
|
|
83
|
+
|
|
84
|
+
// Update when panel changes
|
|
85
|
+
window.addEventListener('side-panel-change', () => {
|
|
86
|
+
setTimeout(updateStoredValue, 100);
|
|
87
|
+
});
|
|
88
|
+
</script>
|
|
89
|
+
</body>
|
|
90
|
+
</html>
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
<a href="#withMenu">With Menu</a><br />
|
|
26
26
|
<a href="#independentScrolling">Independent Scrolling</a><br />
|
|
27
27
|
<a href="#collapsedDefault">Collapsed by Default</a><br />
|
|
28
|
+
<a href="#persistent">Persistent State</a><br />
|
|
28
29
|
<a href="#rightSidePanel">Right Side Panel</a><br />
|
|
29
30
|
<a href="#dualPanels">Dual Side Panels</a><br />
|
|
30
31
|
<a href="#customStyling">Custom Styling</a><br />
|
|
@@ -82,6 +83,22 @@
|
|
|
82
83
|
</div>
|
|
83
84
|
</div>
|
|
84
85
|
|
|
86
|
+
<h3 id="persistent"><a href="#persistent" class="no-link">Persistent State</a></h3>
|
|
87
|
+
<p>Use the <code>persistent-id</code> attribute to save the panel's collapsed/expanded state to localStorage. When the page is refreshed, the panel will remember its previous state.</p>
|
|
88
|
+
<div class="row -mx">
|
|
89
|
+
<div class="col m-span-12 px">
|
|
90
|
+
<k-card label="HTML">
|
|
91
|
+
<pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">k-side-panel</span> <span class="hljs-attr">persistent-id</span>=<span class="hljs-string">"main-nav"</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">h3</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">"logo"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"m0"</span>></span>My App<span class="hljs-tag"></<span class="hljs-name">h3</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">k-side-panel-item</span> <span class="hljs-attr">icon</span>=<span class="hljs-string">"cards"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">active</span>></span>Dashboard<span class="hljs-tag"></<span class="hljs-name">k-side-panel-item</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">k-side-panel-item</span> <span class="hljs-attr">icon</span>=<span class="hljs-string">"check"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>></span>Tasks<span class="hljs-tag"></<span class="hljs-name">k-side-panel-item</span>></span><br /> <span class="hljs-tag"><<span class="hljs-name">k-side-panel-item</span> <span class="hljs-attr">icon</span>=<span class="hljs-string">"settings"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>></span>Settings<span class="hljs-tag"></<span class="hljs-name">k-side-panel-item</span>></span><br /><span class="hljs-tag"></<span class="hljs-name">k-side-panel</span>></span></code></pre>
|
|
92
|
+
</k-card>
|
|
93
|
+
</div>
|
|
94
|
+
<div class="col m-span-12 px">
|
|
95
|
+
<k-card label="Output">
|
|
96
|
+
<p class="info-box">Try collapsing/expanding the panel, then refresh this page. The panel will remember its state!</p>
|
|
97
|
+
<iframe src="./side-panel-persistent.html" style="width: 100%; height: 400px; border: 1px solid var(--c_border); border-radius: var(--radius);"></iframe>
|
|
98
|
+
</k-card>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
|
|
85
102
|
<h3 id="rightSidePanel"><a href="#rightSidePanel" class="no-link">Right Side Panel</a></h3>
|
|
86
103
|
<p>Set the <code>side</code> attribute to <code>"right"</code> to position the panel on the right side of the page.</p>
|
|
87
104
|
<div class="row -mx">
|
|
@@ -146,6 +163,8 @@
|
|
|
146
163
|
<p>Whether the side panel is collapsed to icon-only view. Defaults to <code>false</code>. Syncs to <code>collapsed</code> attribute.</p>
|
|
147
164
|
<h5><code>side<i>: string</i></code></h5>
|
|
148
165
|
<p>The side where the panel is positioned. Can be <code>"left"</code> or <code>"right"</code>. Defaults to <code>"left"</code>. Syncs to <code>side</code> attribute.</p>
|
|
166
|
+
<h5><code>persistentId<i>: string</i></code></h5>
|
|
167
|
+
<p>A unique identifier for saving the panel's collapsed/expanded state to localStorage. When set, the panel will remember its state across page refreshes. Syncs to <code>persistent-id</code> attribute.</p>
|
|
149
168
|
|
|
150
169
|
<h3 id="events"><a href="#events" class="no-link">Events</a></h3>
|
|
151
170
|
<h5><code>expand</code></h5>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import ShadowComponent from"./ShadowComponent.js";import{html,css,nothing}from"../lit-all.min.js";import"./Icon.js";class SidePanel extends ShadowComponent{static properties={collapsed:{type:Boolean,reflect:!0},side:{type:String,reflect:!0}};constructor(){super(),this.collapsed=!1,this.side="left"}toggleClick=()=>this.toggle();updated(e){if(super.updated(e),e.has("collapsed")){const e=this.collapsed?"collapse":"expand";this.dispatchEvent(new CustomEvent(e)),this.dispatchEvent(new CustomEvent("change",{detail:e})),window.dispatchEvent(new CustomEvent("side-panel-change",{detail:{collapsed:this.collapsed,width:this.collapsed?"3.5rem":"16rem",side:this.side}}))}}expand=()=>this.collapsed=!1;collapse=()=>this.collapsed=!0;toggle(){this.collapsed=!this.collapsed,this.dispatchEvent(new CustomEvent("toggle"))}render(){return html`
|
|
1
|
+
import ShadowComponent from"./ShadowComponent.js";import{html,css,nothing}from"../lit-all.min.js";import"./Icon.js";class SidePanel extends ShadowComponent{static properties={collapsed:{type:Boolean,reflect:!0},side:{type:String,reflect:!0},persistentId:{type:String,reflect:!0,attribute:"persistent-id"}};constructor(){super(),this.collapsed=!1,this.side="left",this.persistentId=null,this.isInitialLoad=!0}toggleClick=()=>this.toggle();updated(e){if(super.updated(e),e.has("persistentId")&&this.persistentId&&window?.localStorage){const e=`side-panel-persistent-id-${this.persistentId}`,t=window.localStorage.getItem(e);null!==t&&(this.collapsed="true"===t,this.isInitialLoad=!1)}if(e.has("collapsed")){if(this.persistentId&&window?.localStorage&&!this.isInitialLoad){const e=`side-panel-persistent-id-${this.persistentId}`;window.localStorage.setItem(e,this.collapsed.toString())}this.isInitialLoad=!1;const e=this.collapsed?"collapse":"expand";this.dispatchEvent(new CustomEvent(e)),this.dispatchEvent(new CustomEvent("change",{detail:e})),window.dispatchEvent(new CustomEvent("side-panel-change",{detail:{collapsed:this.collapsed,width:this.collapsed?"3.5rem":"16rem",side:this.side}}))}}expand=()=>this.collapsed=!1;collapse=()=>this.collapsed=!0;toggle(){this.collapsed=!this.collapsed,this.dispatchEvent(new CustomEvent("toggle"))}render(){return html`
|
|
2
2
|
<div id="header">
|
|
3
3
|
<slot name="logo"></slot>
|
|
4
4
|
<button id="toggle" @click=${this.toggleClick} aria-label="${this.collapsed?"Expand panel":"Collapse panel"}">
|
|
@@ -23,7 +23,7 @@ import ShadowComponent from"./ShadowComponent.js";import{html,css,nothing}from".
|
|
|
23
23
|
transition: width var(--transition-duration);
|
|
24
24
|
background: var(--bg);
|
|
25
25
|
border-right: 1px solid var(--c_border);
|
|
26
|
-
z-index:
|
|
26
|
+
z-index: 99;
|
|
27
27
|
}
|
|
28
28
|
:host([collapsed]) {
|
|
29
29
|
width: auto;
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kempo-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.65",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A Lit based web-component library",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "node scripts/build.js",
|
|
9
9
|
"prod": "node scripts/docs.js",
|
|
10
|
-
"dev": "node scripts/docs.js --src",
|
|
10
|
+
"dev": "node scripts/docs.js --src --logging silent",
|
|
11
11
|
"geticon": "node scripts/getIcon.js",
|
|
12
12
|
"test": "npx kempo-test",
|
|
13
13
|
"test:gui": "npx kempo-test --gui",
|
|
@@ -8,13 +8,16 @@ import './Icon.js';
|
|
|
8
8
|
class SidePanel extends ShadowComponent {
|
|
9
9
|
static properties = {
|
|
10
10
|
collapsed: { type: Boolean, reflect: true },
|
|
11
|
-
side: { type: String, reflect: true }
|
|
11
|
+
side: { type: String, reflect: true },
|
|
12
|
+
persistentId: { type: String, reflect: true, attribute: 'persistent-id' }
|
|
12
13
|
};
|
|
13
14
|
|
|
14
15
|
constructor() {
|
|
15
16
|
super();
|
|
16
17
|
this.collapsed = false;
|
|
17
18
|
this.side = 'left';
|
|
19
|
+
this.persistentId = null;
|
|
20
|
+
this.isInitialLoad = true;
|
|
18
21
|
}
|
|
19
22
|
|
|
20
23
|
toggleClick = () => this.toggle();
|
|
@@ -22,7 +25,22 @@ class SidePanel extends ShadowComponent {
|
|
|
22
25
|
updated(changedProperties) {
|
|
23
26
|
super.updated(changedProperties);
|
|
24
27
|
|
|
28
|
+
if(changedProperties.has('persistentId') && this.persistentId && window?.localStorage) {
|
|
29
|
+
const key = `side-panel-persistent-id-${this.persistentId}`;
|
|
30
|
+
const value = window.localStorage.getItem(key);
|
|
31
|
+
if(value !== null) {
|
|
32
|
+
this.collapsed = value === 'true';
|
|
33
|
+
this.isInitialLoad = false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
25
37
|
if(changedProperties.has('collapsed')) {
|
|
38
|
+
if(this.persistentId && window?.localStorage && !this.isInitialLoad) {
|
|
39
|
+
const key = `side-panel-persistent-id-${this.persistentId}`;
|
|
40
|
+
window.localStorage.setItem(key, this.collapsed.toString());
|
|
41
|
+
}
|
|
42
|
+
this.isInitialLoad = false;
|
|
43
|
+
|
|
26
44
|
const eventName = this.collapsed ? 'collapse' : 'expand';
|
|
27
45
|
this.dispatchEvent(new CustomEvent(eventName));
|
|
28
46
|
this.dispatchEvent(new CustomEvent('change', { detail: eventName }));
|
|
@@ -80,7 +98,7 @@ class SidePanel extends ShadowComponent {
|
|
|
80
98
|
transition: width var(--transition-duration);
|
|
81
99
|
background: var(--bg);
|
|
82
100
|
border-right: 1px solid var(--c_border);
|
|
83
|
-
z-index:
|
|
101
|
+
z-index: 99;
|
|
84
102
|
}
|
|
85
103
|
:host([collapsed]) {
|
|
86
104
|
width: auto;
|