Skip to content

Commit 351a25a

Browse files
committed
rm sidebar
1 parent 6f00216 commit 351a25a

15 files changed

+730
-1
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"docs/@capsule/components/capsule-icon/vscode.data.json",
2828
"docs/@capsule/components/capsule-input/vscode.data.json",
2929
"docs/@capsule/components/capsule-hover-card/vscode.data.json",
30-
"docs/@capsule/components/capsule-radio-group/vscode.data.json"
30+
"docs/@capsule/components/capsule-radio-group/vscode.data.json",
31+
"docs/@capsule/components/capsule-sidebar/vscode.data.json"
3132
]
3233
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import { LitElement, html } from '../../lit';
2+
3+
class CapsuleSidebarContainer extends LitElement {
4+
static properties = {
5+
open: { type: Boolean, reflect: true },
6+
defaultOpen: { type: Boolean, reflect: true },
7+
};
8+
9+
constructor() {
10+
super();
11+
this.open = true;
12+
this.defaultOpen = true;
13+
this._isMobile = false;
14+
}
15+
16+
createRenderRoot() {
17+
return this;
18+
}
19+
20+
connectedCallback() {
21+
super.connectedCallback();
22+
this._checkMobile();
23+
this._loadState();
24+
this._attachListeners();
25+
this._updateState();
26+
}
27+
28+
disconnectedCallback() {
29+
super.disconnectedCallback();
30+
this._detachListeners();
31+
}
32+
33+
updated(changedProperties) {
34+
if (changedProperties.has('open')) {
35+
this._updateState();
36+
this._saveState();
37+
this._dispatchChange();
38+
}
39+
}
40+
41+
_checkMobile() {
42+
const mediaQuery = window.matchMedia('(max-width: 768px)');
43+
this._isMobile = mediaQuery.matches;
44+
this._handleMediaChange(mediaQuery);
45+
mediaQuery.addEventListener('change', this._handleMediaChange.bind(this));
46+
}
47+
48+
_handleMediaChange(mediaQuery) {
49+
this._isMobile = mediaQuery.matches;
50+
this._updateState();
51+
}
52+
53+
_loadState() {
54+
if (this.defaultOpen !== undefined) {
55+
this.open = this.defaultOpen;
56+
} else {
57+
const saved = localStorage.getItem('capsule-sidebar-state');
58+
if (saved !== null) {
59+
this.open = saved === 'true';
60+
}
61+
}
62+
}
63+
64+
_saveState() {
65+
localStorage.setItem('capsule-sidebar-state', String(this.open));
66+
}
67+
68+
_attachListeners() {
69+
document.addEventListener('keydown', this._handleKeyDown);
70+
}
71+
72+
_detachListeners() {
73+
document.removeEventListener('keydown', this._handleKeyDown);
74+
}
75+
76+
_handleKeyDown = (event) => {
77+
if ((event.metaKey || event.ctrlKey) && event.key === 'b') {
78+
event.preventDefault();
79+
this.toggle();
80+
}
81+
};
82+
83+
_updateState() {
84+
const state = this.open ? 'expanded' : 'collapsed';
85+
this.setAttribute('data-state', state);
86+
this.style.setProperty('--sidebar-open', this.open ? '1' : '0');
87+
88+
// Update all sidebar children
89+
const tagName = this.tagName.toLowerCase();
90+
if (tagName.includes('container')) {
91+
const sidebarTagName = tagName.replace('-container', '');
92+
const sidebars = this.querySelectorAll(sidebarTagName);
93+
sidebars.forEach((sidebar) => {
94+
if (sidebar && sidebar.setAttribute) {
95+
sidebar.setAttribute('data-state', state);
96+
const collapsible = sidebar.collapsible || sidebar.getAttribute('collapsible') || '';
97+
sidebar.setAttribute('data-collapsible', state === 'collapsed' ? collapsible : '');
98+
}
99+
});
100+
}
101+
}
102+
103+
_dispatchChange() {
104+
this.dispatchEvent(
105+
new CustomEvent('sidebar-change', {
106+
bubbles: true,
107+
detail: {
108+
open: this.open,
109+
state: this.open ? 'expanded' : 'collapsed',
110+
},
111+
})
112+
);
113+
}
114+
115+
toggle() {
116+
this.open = !this.open;
117+
}
118+
119+
setOpen(value) {
120+
this.open = value;
121+
}
122+
123+
getState() {
124+
return this.open ? 'expanded' : 'collapsed';
125+
}
126+
127+
getIsMobile() {
128+
return this._isMobile;
129+
}
130+
131+
render() {
132+
return html`<slot></slot>`;
133+
}
134+
}
135+
136+
customElements.define('capsule-sidebar-container', CapsuleSidebarContainer);
137+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { LitElement, html } from '../../lit';
2+
3+
class CapsuleSidebarContent extends LitElement {
4+
constructor() {
5+
super();
6+
}
7+
8+
createRenderRoot() {
9+
return this;
10+
}
11+
12+
render() {
13+
return html`<slot></slot>`;
14+
}
15+
}
16+
17+
customElements.define('capsule-sidebar-content', CapsuleSidebarContent);
18+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { LitElement, html } from '../../lit';
2+
3+
class CapsuleSidebarFooter extends LitElement {
4+
constructor() {
5+
super();
6+
}
7+
8+
createRenderRoot() {
9+
return this;
10+
}
11+
12+
render() {
13+
return html`<slot></slot>`;
14+
}
15+
}
16+
17+
customElements.define('capsule-sidebar-footer', CapsuleSidebarFooter);
18+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { LitElement, html } from '../../lit';
2+
3+
class CapsuleSidebarHeader extends LitElement {
4+
constructor() {
5+
super();
6+
}
7+
8+
createRenderRoot() {
9+
return this;
10+
}
11+
12+
render() {
13+
return html`<slot></slot>`;
14+
}
15+
}
16+
17+
customElements.define('capsule-sidebar-header', CapsuleSidebarHeader);
18+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { LitElement, html } from '../../lit';
2+
3+
class CapsuleSidebarMain extends LitElement {
4+
constructor() {
5+
super();
6+
}
7+
8+
createRenderRoot() {
9+
return this;
10+
}
11+
12+
render() {
13+
return html`<slot></slot>`;
14+
}
15+
}
16+
17+
customElements.define('capsule-sidebar-main', CapsuleSidebarMain);
18+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { LitElement, html } from '../../lit';
2+
3+
class CapsuleSidebarMain extends LitElement {
4+
constructor() {
5+
super();
6+
}
7+
8+
createRenderRoot() {
9+
return this;
10+
}
11+
12+
render() {
13+
return html`<slot></slot>`;
14+
}
15+
}
16+
17+
customElements.define('capsule-sidebar-main', CapsuleSidebarMain);
18+
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import { LitElement, html } from '../../lit';
2+
3+
class CapsuleSidebarProvider extends LitElement {
4+
static properties = {
5+
open: { type: Boolean, reflect: true },
6+
defaultOpen: { type: Boolean, reflect: true },
7+
};
8+
9+
constructor() {
10+
super();
11+
this.open = true;
12+
this.defaultOpen = true;
13+
this._isMobile = false;
14+
}
15+
16+
createRenderRoot() {
17+
return this;
18+
}
19+
20+
connectedCallback() {
21+
super.connectedCallback();
22+
this._checkMobile();
23+
this._loadState();
24+
this._attachListeners();
25+
this._updateState();
26+
}
27+
28+
disconnectedCallback() {
29+
super.disconnectedCallback();
30+
this._detachListeners();
31+
}
32+
33+
updated(changedProperties) {
34+
if (changedProperties.has('open')) {
35+
this._updateState();
36+
this._saveState();
37+
this._dispatchChange();
38+
}
39+
}
40+
41+
_checkMobile() {
42+
const mediaQuery = window.matchMedia('(max-width: 768px)');
43+
this._isMobile = mediaQuery.matches;
44+
this._handleMediaChange(mediaQuery);
45+
mediaQuery.addEventListener('change', this._handleMediaChange.bind(this));
46+
}
47+
48+
_handleMediaChange(mediaQuery) {
49+
this._isMobile = mediaQuery.matches;
50+
this._updateState();
51+
}
52+
53+
_loadState() {
54+
if (this.defaultOpen !== undefined) {
55+
this.open = this.defaultOpen;
56+
} else {
57+
const saved = localStorage.getItem('capsule-sidebar-state');
58+
if (saved !== null) {
59+
this.open = saved === 'true';
60+
}
61+
}
62+
}
63+
64+
_saveState() {
65+
localStorage.setItem('capsule-sidebar-state', String(this.open));
66+
}
67+
68+
_attachListeners() {
69+
document.addEventListener('keydown', this._handleKeyDown);
70+
}
71+
72+
_detachListeners() {
73+
document.removeEventListener('keydown', this._handleKeyDown);
74+
}
75+
76+
_handleKeyDown = (event) => {
77+
if ((event.metaKey || event.ctrlKey) && event.key === 'b') {
78+
event.preventDefault();
79+
this.toggle();
80+
}
81+
};
82+
83+
_updateState() {
84+
const state = this.open ? 'expanded' : 'collapsed';
85+
this.setAttribute('data-state', state);
86+
this.style.setProperty('--sidebar-open', this.open ? '1' : '0');
87+
88+
// Update all sidebar children
89+
const tagName = this.tagName.toLowerCase();
90+
if (tagName.includes('provider')) {
91+
const sidebarTagName = tagName.replace('-provider', '');
92+
const sidebars = this.querySelectorAll(sidebarTagName);
93+
sidebars.forEach((sidebar) => {
94+
if (sidebar && sidebar.setAttribute) {
95+
sidebar.setAttribute('data-state', state);
96+
const collapsible = sidebar.collapsible || sidebar.getAttribute('collapsible') || '';
97+
sidebar.setAttribute('data-collapsible', state === 'collapsed' ? collapsible : '');
98+
}
99+
});
100+
}
101+
}
102+
103+
_dispatchChange() {
104+
this.dispatchEvent(
105+
new CustomEvent('sidebar-change', {
106+
bubbles: true,
107+
detail: {
108+
open: this.open,
109+
state: this.open ? 'expanded' : 'collapsed',
110+
},
111+
})
112+
);
113+
}
114+
115+
toggle() {
116+
this.open = !this.open;
117+
}
118+
119+
setOpen(value) {
120+
this.open = value;
121+
}
122+
123+
getState() {
124+
return this.open ? 'expanded' : 'collapsed';
125+
}
126+
127+
getIsMobile() {
128+
return this._isMobile;
129+
}
130+
131+
render() {
132+
return html`<slot></slot>`;
133+
}
134+
}
135+
136+
customElements.define('capsule-sidebar-provider', CapsuleSidebarProvider);
137+

0 commit comments

Comments
 (0)