@iyulab/modern-app 0.2.5 → 0.3.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/CHANGELOG.md +45 -0
- package/README.md +18 -0
- package/dist/App.d.ts +9 -6
- package/dist/App.js +30 -28
- package/dist/components/SidebarButton.d.ts +4 -5
- package/dist/components/SidebarButton.js +12 -14
- package/dist/components/SidebarButton.styles.js +15 -18
- package/dist/components/SidebarGroup.d.ts +7 -6
- package/dist/components/SidebarGroup.js +45 -46
- package/dist/components/SidebarGroup.styles.js +39 -44
- package/dist/components/SidebarLink.d.ts +5 -10
- package/dist/components/SidebarLink.js +29 -39
- package/dist/components/SidebarLink.styles.js +9 -9
- package/dist/components/SidebarSection.d.ts +6 -7
- package/dist/components/SidebarSection.js +18 -22
- package/dist/components/SidebarSection.styles.js +9 -14
- package/dist/index.d.ts +2 -3
- package/dist/internals/ScreenObserver.d.ts +43 -0
- package/dist/internals/ScreenObserver.js +37 -0
- package/dist/internals/StyledElement.d.ts +24 -0
- package/dist/internals/{ExtendedBaseElement.js → StyledElement.js} +13 -14
- package/dist/layouts/SidebarLayout.d.ts +29 -21
- package/dist/layouts/SidebarLayout.js +143 -111
- package/dist/layouts/SidebarLayout.styles.js +82 -42
- package/dist/layouts/SidebarLayout.types.d.ts +14 -12
- package/dist/types/AppConfigs.d.ts +12 -7
- package/dist/types/AppOptions.d.ts +1 -1
- package/package.json +9 -11
- package/dist/components/SidebarLogo.d.ts +0 -33
- package/dist/components/SidebarLogo.js +0 -60
- package/dist/components/SidebarLogo.styles.d.ts +0 -1
- package/dist/components/SidebarLogo.styles.js +0 -57
- package/dist/internals/ExtendedBaseElement.d.ts +0 -22
- package/dist/internals/observables.d.ts +0 -7
- package/dist/internals/observables.js +0 -5
- package/dist/types/AppTypes.d.ts +0 -4
|
@@ -1,114 +1,134 @@
|
|
|
1
|
-
import { nothing as
|
|
2
|
-
import { query as
|
|
1
|
+
import { nothing as h, html as a } from "lit";
|
|
2
|
+
import { query as b, state as g, property as p, customElement as f } from "lit/decorators.js";
|
|
3
3
|
import { unsafeHTML as m } from "lit/directives/unsafe-html.js";
|
|
4
|
-
import { repeat as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { repeat as l } from "lit/directives/repeat.js";
|
|
5
|
+
import { UIcon as v } from "@iyulab/components/dist/components/icon/UIcon.component.js";
|
|
6
|
+
import { UButton as $ } from "@iyulab/components/dist/components/button/UButton.component.js";
|
|
7
7
|
import { UProgressBar as y } from "@iyulab/components/dist/components/progress-bar/UProgressBar.component.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
var
|
|
17
|
-
for (var r =
|
|
18
|
-
(c = e[d]) && (r = (
|
|
19
|
-
return
|
|
20
|
-
},
|
|
21
|
-
|
|
8
|
+
import { app as u } from "../App.js";
|
|
9
|
+
import { StyledElement as w } from "../internals/StyledElement.js";
|
|
10
|
+
import { SidebarSection as k } from "../components/SidebarSection.js";
|
|
11
|
+
import { SidebarGroup as B } from "../components/SidebarGroup.js";
|
|
12
|
+
import { SidebarLink as L } from "../components/SidebarLink.js";
|
|
13
|
+
import { SidebarButton as _ } from "../components/SidebarButton.js";
|
|
14
|
+
import { styles as C } from "./SidebarLayout.styles.js";
|
|
15
|
+
import { IconRegistry as R } from "@iyulab/components/dist/utilities/IconRegistry.js";
|
|
16
|
+
var S = Object.defineProperty, z = Object.getOwnPropertyDescriptor, E = Object.getPrototypeOf, x = Reflect.get, n = (e, t, s, o) => {
|
|
17
|
+
for (var r = o > 1 ? void 0 : o ? z(t, s) : t, d = e.length - 1, c; d >= 0; d--)
|
|
18
|
+
(c = e[d]) && (r = (o ? c(t, s, r) : c(r)) || r);
|
|
19
|
+
return o && r && S(t, s, r), r;
|
|
20
|
+
}, M = (e, t, s) => x(E(e), s, t);
|
|
21
|
+
R.register("sidebar-app", (e) => e === "layout-sidebar" ? '<svg viewBox="0 0 16 16"><path d="M0 3a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm5-1v12h9a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1zM4 2H2a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h2z"/></svg>' : e === "list" ? '<svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M1 3a1 1 0 0 1 1-1h12a1 1 0 0 1 0 2H2a1 1 0 0 1-1-1 m0 5a1 1 0 0 1 1-1h12a1 1 0 0 1 0 2H2a1 1 0 0 1-1-1 m0 5a1 1 0 0 1 1-1h12a1 1 0 0 1 0 2H2a1 1 0 0 1-1-1"/></svg>' : e === "x-lg" ? '<svg viewBox="0 0 16 16"><path d="M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z"/></svg>' : "");
|
|
22
|
+
let i = class extends w {
|
|
22
23
|
constructor() {
|
|
23
|
-
super(...arguments), this.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
super(...arguments), this.context = null, this.state = "default", this.isMatchedLink = (e) => !this.context || !e ? !1 : (e = typeof e == "string" ? new URLPattern(e, window.location.origin) : e, e.test(this.context.path, window.location.origin)), this.handleBrandLogoClick = () => {
|
|
25
|
+
u.navigate("");
|
|
26
|
+
}, this.handleToggleButtonClick = () => {
|
|
27
|
+
const e = u.screen ?? "large";
|
|
28
|
+
e === "large" ? this.state = this.state === "default" ? "slim" : "default" : e === "medium" ? this.state = this.state === "slim" ? "modal" : "slim" : e === "small" ? this.state = this.state === "mobile" ? "mobile-open" : "mobile" : console.warn("Unknown screen size:", e);
|
|
29
|
+
}, this.handleBackdropClick = () => {
|
|
30
|
+
this.state = "slim";
|
|
29
31
|
}, this.handleRouteBegin = (e) => {
|
|
30
|
-
this.progressBarEl.value = 0, this.
|
|
32
|
+
this.progressBarEl.value = 0, this.state === "modal" && (this.state = "slim"), this.state === "mobile-open" && (this.state = "mobile"), this.context = e.context;
|
|
31
33
|
}, this.handleRouteProgress = (e) => {
|
|
32
34
|
this.progressBarEl.value = e.progress;
|
|
33
35
|
}, this.handleRouteDone = (e) => {
|
|
34
36
|
this.progressBarEl.value = 100;
|
|
37
|
+
}, this.handleScreenResize = (e) => {
|
|
38
|
+
const t = e.detail.size;
|
|
39
|
+
t === "large" ? this.state = "default" : t === "medium" ? this.state = "slim" : t === "small" ? this.state = "mobile" : console.warn("Unknown screen size:", t);
|
|
35
40
|
};
|
|
36
41
|
}
|
|
37
42
|
connectedCallback() {
|
|
38
|
-
super.connectedCallback(), this.
|
|
39
|
-
const e = u.get();
|
|
40
|
-
this.updateState(e);
|
|
41
|
-
})), window.addEventListener("route-begin", this.handleRouteBegin), window.addEventListener("route-done", this.handleRouteDone), window.addEventListener("route-progress", this.handleRouteProgress);
|
|
43
|
+
super.connectedCallback(), window.addEventListener("route-begin", this.handleRouteBegin), window.addEventListener("route-done", this.handleRouteDone), window.addEventListener("route-progress", this.handleRouteProgress), window.addEventListener("screen-resize", this.handleScreenResize);
|
|
42
44
|
}
|
|
43
45
|
disconnectedCallback() {
|
|
44
|
-
|
|
46
|
+
window.removeEventListener("route-begin", this.handleRouteBegin), window.removeEventListener("route-done", this.handleRouteDone), window.removeEventListener("route-progress", this.handleRouteProgress), window.removeEventListener("screen-resize", this.handleScreenResize), super.disconnectedCallback();
|
|
45
47
|
}
|
|
46
48
|
updated(e) {
|
|
47
49
|
super.updated(e), e.has("config") && (this.styles = this.config?.styles);
|
|
48
50
|
}
|
|
49
51
|
render() {
|
|
50
|
-
return this.config ?
|
|
52
|
+
return this.config ? a`
|
|
53
|
+
<!-- Mobile Header -->
|
|
54
|
+
<div class="mobile-header" part="mobile-header" ?hidden="${!this.state.startsWith("mobile")}">
|
|
55
|
+
<u-icon class="logo"
|
|
56
|
+
.name="${this.config.logo}"
|
|
57
|
+
@click=${this.handleBrandLogoClick}
|
|
58
|
+
></u-icon>
|
|
59
|
+
<span class="title">
|
|
60
|
+
${this.config.title}
|
|
61
|
+
</span>
|
|
62
|
+
<u-button class="toggler"
|
|
63
|
+
@click=${this.handleToggleButtonClick}>
|
|
64
|
+
<u-icon
|
|
65
|
+
lib="sidebar-app"
|
|
66
|
+
name=${this.state === "mobile-open" ? "x-lg" : "list"}
|
|
67
|
+
></u-icon>
|
|
68
|
+
</u-button>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
51
71
|
<!-- Sidebar -->
|
|
52
|
-
<aside class="sidebar" part="sidebar" state
|
|
72
|
+
<aside class="sidebar" part="sidebar" state="${this.state}">
|
|
53
73
|
<!-- Sidebar Header -->
|
|
54
74
|
<div class="sidebar-header" part="sidebar-header">
|
|
55
|
-
<u-
|
|
56
|
-
.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
75
|
+
<u-icon class="logo"
|
|
76
|
+
.name="${this.config.logo}"
|
|
77
|
+
@click=${this.handleBrandLogoClick}
|
|
78
|
+
></u-icon>
|
|
79
|
+
<span class="title" ?hidden=${this.state === "slim"}>
|
|
80
|
+
${this.config.title}
|
|
81
|
+
</span>
|
|
82
|
+
<u-button class="toggler"
|
|
83
|
+
@click=${this.handleToggleButtonClick}>
|
|
84
|
+
<u-icon
|
|
85
|
+
lib="sidebar-app"
|
|
86
|
+
name="layout-sidebar"
|
|
87
|
+
></u-icon>
|
|
88
|
+
</u-button>
|
|
69
89
|
</div>
|
|
70
90
|
|
|
71
91
|
<!-- Sidebar Navigation Menu -->
|
|
72
|
-
<nav class="sidebar-
|
|
73
|
-
${
|
|
74
|
-
this.config.
|
|
92
|
+
<nav class="sidebar-main" part="sidebar-main" scrollable>
|
|
93
|
+
${l(
|
|
94
|
+
this.config.main ?? [],
|
|
75
95
|
(e, t) => t,
|
|
76
|
-
(e
|
|
96
|
+
(e) => this.renderItem(e)
|
|
77
97
|
)}
|
|
78
98
|
</nav>
|
|
79
99
|
|
|
80
100
|
<!-- Sidebar Footer -->
|
|
81
|
-
<div class="sidebar-footer" part="sidebar-footer"
|
|
82
|
-
|
|
83
|
-
${n(
|
|
101
|
+
<div class="sidebar-footer" part="sidebar-footer">
|
|
102
|
+
${l(
|
|
84
103
|
this.config.footer ?? [],
|
|
85
104
|
(e, t) => t,
|
|
86
|
-
(e
|
|
105
|
+
(e) => this.renderItem(e)
|
|
87
106
|
)}
|
|
88
107
|
</div>
|
|
89
108
|
</aside>
|
|
90
109
|
|
|
91
110
|
<!-- Main Content -->
|
|
92
|
-
<div class="main" part="main">
|
|
111
|
+
<div class="main" part="main" scrollable>
|
|
93
112
|
<u-progress-bar part="progress"></u-progress-bar>
|
|
94
113
|
|
|
95
|
-
<
|
|
114
|
+
<slot></slot>
|
|
96
115
|
</div>
|
|
97
116
|
|
|
98
117
|
<!-- Backdrop for modal state -->
|
|
99
|
-
<div class="backdrop"
|
|
100
|
-
|
|
101
|
-
@click="${this.toggleStateIfModalState}"
|
|
118
|
+
<div class="backdrop" ?hidden="${this.state !== "modal"}"
|
|
119
|
+
@click="${this.handleBackdropClick}"
|
|
102
120
|
></div>
|
|
103
|
-
` :
|
|
121
|
+
` : h;
|
|
104
122
|
}
|
|
105
123
|
/** 사이드바 아이템 렌더링 */
|
|
106
124
|
renderItem(e) {
|
|
107
|
-
if (!e) return
|
|
108
|
-
if (e.type === "
|
|
125
|
+
if (!e) return h;
|
|
126
|
+
if (e.type === "html") {
|
|
109
127
|
const t = e.render(this.state);
|
|
110
|
-
return typeof t == "string" ? m(t) :
|
|
111
|
-
} else
|
|
128
|
+
return typeof t == "string" ? m(t) : a`${t}`;
|
|
129
|
+
} else {
|
|
130
|
+
if (e.type === "button")
|
|
131
|
+
return a`
|
|
112
132
|
<u-sidebar-button
|
|
113
133
|
?compact=${this.state === "slim"}
|
|
114
134
|
.icon="${e.icon}"
|
|
@@ -116,71 +136,83 @@ let o = class extends S {
|
|
|
116
136
|
.styles="${e.styles}"
|
|
117
137
|
@click="${e.onClick}"
|
|
118
138
|
></u-sidebar-button>
|
|
119
|
-
|
|
139
|
+
`;
|
|
140
|
+
if (e.type === "link") {
|
|
141
|
+
const t = this.isMatchedLink(e.pattern || e.href);
|
|
142
|
+
return a`
|
|
143
|
+
<u-sidebar-link
|
|
144
|
+
?compact=${this.state === "slim"}
|
|
145
|
+
?selected=${t}
|
|
146
|
+
.icon="${e.icon}"
|
|
147
|
+
.label="${e.label}"
|
|
148
|
+
.href="${e.href}"
|
|
149
|
+
.pattern="${e.pattern}"
|
|
150
|
+
.styles="${e.styles}"
|
|
151
|
+
></u-sidebar-link>
|
|
152
|
+
`;
|
|
153
|
+
} else {
|
|
154
|
+
if (e.type === "section")
|
|
155
|
+
return a`
|
|
120
156
|
<u-sidebar-section
|
|
121
157
|
?compact=${this.state === "slim"}
|
|
122
158
|
.mainTitle="${e.title}"
|
|
123
159
|
.subTitle="${e.subTitle}"
|
|
124
|
-
.items="${e.items}"
|
|
125
160
|
.styles="${e.styles}">
|
|
126
|
-
${
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
161
|
+
${l(
|
|
162
|
+
e.items,
|
|
163
|
+
(t, s) => s,
|
|
164
|
+
(t) => this.renderItem(t)
|
|
165
|
+
)}
|
|
131
166
|
</u-sidebar-section>
|
|
132
|
-
|
|
167
|
+
`;
|
|
168
|
+
if (e.type === "group") {
|
|
169
|
+
const t = e.items.some((s) => this.isMatchedLink(s.pattern || s.href));
|
|
170
|
+
return a`
|
|
133
171
|
<u-sidebar-group
|
|
134
172
|
?compact=${this.state === "slim"}
|
|
173
|
+
?selected=${t}
|
|
135
174
|
?collapsed="${e.collapsed ?? !1}"
|
|
136
175
|
.icon="${e.icon}"
|
|
137
176
|
.label="${e.label}"
|
|
138
|
-
.items="${e.items}"
|
|
139
177
|
.styles="${e.styles}">
|
|
140
|
-
${
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
178
|
+
${l(
|
|
179
|
+
e.items,
|
|
180
|
+
(s, o) => o,
|
|
181
|
+
(s) => this.renderItem(s)
|
|
182
|
+
)}
|
|
145
183
|
</u-sidebar-group>
|
|
146
|
-
` : i`
|
|
147
|
-
<u-sidebar-link
|
|
148
|
-
?compact=${this.state === "slim"}
|
|
149
|
-
.icon="${e.icon}"
|
|
150
|
-
.label="${e.label}"
|
|
151
|
-
.href="${e.href}"
|
|
152
|
-
.pattern="${e.pattern}"
|
|
153
|
-
.styles="${e.styles}"
|
|
154
|
-
></u-sidebar-link>
|
|
155
184
|
`;
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
185
|
+
} else
|
|
186
|
+
return h;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
160
189
|
}
|
|
161
190
|
};
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
"u-icon
|
|
191
|
+
i.styles = [M(i, i, "styles"), C];
|
|
192
|
+
i.dependencies = {
|
|
193
|
+
"u-icon": v,
|
|
194
|
+
"u-button": $,
|
|
165
195
|
"u-progress-bar": y,
|
|
166
|
-
"u-sidebar-
|
|
167
|
-
"u-sidebar-
|
|
168
|
-
"u-sidebar-
|
|
169
|
-
"u-sidebar-
|
|
170
|
-
"u-sidebar-button": B
|
|
196
|
+
"u-sidebar-section": k,
|
|
197
|
+
"u-sidebar-group": B,
|
|
198
|
+
"u-sidebar-link": L,
|
|
199
|
+
"u-sidebar-button": _
|
|
171
200
|
};
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
],
|
|
175
|
-
|
|
201
|
+
n([
|
|
202
|
+
b("u-progress-bar")
|
|
203
|
+
], i.prototype, "progressBarEl", 2);
|
|
204
|
+
n([
|
|
176
205
|
g()
|
|
177
|
-
],
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
],
|
|
181
|
-
|
|
206
|
+
], i.prototype, "context", 2);
|
|
207
|
+
n([
|
|
208
|
+
p({ type: String, reflect: !0 })
|
|
209
|
+
], i.prototype, "state", 2);
|
|
210
|
+
n([
|
|
211
|
+
p({ type: Object })
|
|
212
|
+
], i.prototype, "config", 2);
|
|
213
|
+
i = n([
|
|
182
214
|
f("u-sidebar-layout")
|
|
183
|
-
],
|
|
215
|
+
], i);
|
|
184
216
|
export {
|
|
185
|
-
|
|
217
|
+
i as SidebarLayout
|
|
186
218
|
};
|
|
@@ -1,13 +1,49 @@
|
|
|
1
|
-
import { css as
|
|
2
|
-
const r =
|
|
1
|
+
import { css as e } from "lit";
|
|
2
|
+
const r = e`
|
|
3
3
|
:host {
|
|
4
4
|
position: relative;
|
|
5
5
|
display: flex;
|
|
6
6
|
flex-direction: row;
|
|
7
7
|
width: 100%;
|
|
8
8
|
height: 100%;
|
|
9
|
+
font-family: var(--u-font-base);
|
|
9
10
|
overflow: hidden;
|
|
10
11
|
}
|
|
12
|
+
:host([state="mobile"]),
|
|
13
|
+
:host([state="mobile-open"]) {
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.logo {
|
|
18
|
+
color: var(--u-txt-color);
|
|
19
|
+
font-size: 24px;
|
|
20
|
+
cursor: pointer;
|
|
21
|
+
}
|
|
22
|
+
.logo:hover {
|
|
23
|
+
color: var(--u-txt-color-hover);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.title {
|
|
27
|
+
flex: 1;
|
|
28
|
+
color: var(--u-txt-color);
|
|
29
|
+
font-size: 18px;
|
|
30
|
+
line-height: 24px;
|
|
31
|
+
font-weight: 700;
|
|
32
|
+
white-space: nowrap;
|
|
33
|
+
overflow: hidden;
|
|
34
|
+
text-overflow: ellipsis;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.toggler {
|
|
38
|
+
color: inherit;
|
|
39
|
+
font-size: 20px;
|
|
40
|
+
padding: 0px;
|
|
41
|
+
border: none;
|
|
42
|
+
background: transparent;
|
|
43
|
+
}
|
|
44
|
+
.toggler:hover {
|
|
45
|
+
color: var(--u-txt-color-hover);
|
|
46
|
+
}
|
|
11
47
|
|
|
12
48
|
/* Sidebar Container */
|
|
13
49
|
.sidebar {
|
|
@@ -17,53 +53,57 @@ const r = o`
|
|
|
17
53
|
flex-direction: column;
|
|
18
54
|
justify-content: space-between;
|
|
19
55
|
gap: 8px;
|
|
20
|
-
|
|
21
|
-
height: 100vh;
|
|
56
|
+
height: 100%;
|
|
22
57
|
background: var(--u-panel-bg-color);
|
|
23
58
|
border-right: 1px solid var(--u-border-color);
|
|
24
|
-
|
|
25
|
-
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
59
|
+
transition: all 0.3s ease;
|
|
26
60
|
}
|
|
27
61
|
/* Sidebar states */
|
|
62
|
+
.sidebar[state="default"] {
|
|
63
|
+
width: 260px;
|
|
64
|
+
}
|
|
28
65
|
.sidebar[state="slim"] {
|
|
29
66
|
width: 64px;
|
|
30
67
|
}
|
|
31
68
|
.sidebar[state="slim"] .sidebar-header {
|
|
32
69
|
flex-direction: column;
|
|
70
|
+
gap: 16px;
|
|
71
|
+
padding: 16px;
|
|
33
72
|
}
|
|
34
|
-
.sidebar[state="
|
|
35
|
-
position: fixed;
|
|
36
|
-
top: 0;
|
|
37
|
-
left: -260px;
|
|
38
|
-
bottom: 0;
|
|
73
|
+
.sidebar[state="modal"] {
|
|
39
74
|
width: 260px;
|
|
40
|
-
}
|
|
41
|
-
.sidebar[state="closed"] .sidebar-toggler {
|
|
42
75
|
position: absolute;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
left: calc(100% - 16px);
|
|
46
|
-
background-color: var(--u-panel-bg-color);
|
|
47
|
-
border: 1px solid var(--u-border-color-strong);
|
|
48
|
-
border-radius: 4px 8px 8px 4px;
|
|
76
|
+
top: 0;
|
|
77
|
+
left: 0;
|
|
49
78
|
}
|
|
50
|
-
.sidebar[state="
|
|
51
|
-
|
|
79
|
+
.sidebar[state="mobile"] {
|
|
80
|
+
position: absolute;
|
|
81
|
+
top: 0;
|
|
82
|
+
left: 0;
|
|
83
|
+
right: 0;
|
|
84
|
+
transform: translateY(-100%);
|
|
52
85
|
}
|
|
53
|
-
.sidebar[state="
|
|
54
|
-
position:
|
|
86
|
+
.sidebar[state="mobile-open"] {
|
|
87
|
+
position: absolute;
|
|
55
88
|
top: 0;
|
|
56
89
|
left: 0;
|
|
57
|
-
|
|
58
|
-
|
|
90
|
+
right: 0;
|
|
91
|
+
transform: translateY(0);
|
|
59
92
|
}
|
|
60
93
|
|
|
61
|
-
/*
|
|
62
|
-
.
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
94
|
+
/* Mobile Header */
|
|
95
|
+
.mobile-header {
|
|
96
|
+
position: relative;
|
|
97
|
+
z-index: 1001;
|
|
98
|
+
display: flex;
|
|
99
|
+
flex-direction: row;
|
|
100
|
+
align-items: center;
|
|
101
|
+
justify-content: space-between;
|
|
102
|
+
gap: 12px;
|
|
103
|
+
padding: 16px;
|
|
104
|
+
background: var(--u-panel-bg-color);
|
|
105
|
+
border-bottom: 1px solid var(--u-border-color-weak);
|
|
106
|
+
user-select: none;
|
|
67
107
|
}
|
|
68
108
|
|
|
69
109
|
/* Sidebar Header */
|
|
@@ -72,23 +112,21 @@ const r = o`
|
|
|
72
112
|
flex-direction: row;
|
|
73
113
|
align-items: center;
|
|
74
114
|
justify-content: space-between;
|
|
75
|
-
gap:
|
|
76
|
-
padding: 16px
|
|
115
|
+
gap: 12px;
|
|
116
|
+
padding: 16px;
|
|
77
117
|
border-bottom: 1px solid var(--u-border-color-weak);
|
|
118
|
+
user-select: none;
|
|
78
119
|
}
|
|
79
120
|
|
|
80
|
-
/* Sidebar Menu */
|
|
81
|
-
.sidebar-
|
|
121
|
+
/* Sidebar Main Menu */
|
|
122
|
+
.sidebar-main {
|
|
82
123
|
flex: 1;
|
|
83
124
|
display: flex;
|
|
84
125
|
flex-direction: column;
|
|
85
126
|
gap: 4px;
|
|
86
127
|
padding: 8px;
|
|
87
|
-
overflow-y: auto;
|
|
88
128
|
overflow-x: hidden;
|
|
89
|
-
|
|
90
|
-
scrollbar-width: thin;
|
|
91
|
-
scrollbar-color: var(--u-scrollbar-color) var(--u-scrollbar-track-color);
|
|
129
|
+
overflow-y: auto;
|
|
92
130
|
}
|
|
93
131
|
|
|
94
132
|
/* Sidebar Footer */
|
|
@@ -99,14 +137,16 @@ const r = o`
|
|
|
99
137
|
padding: 8px;
|
|
100
138
|
border-top: 1px solid var(--u-border-color-weak);
|
|
101
139
|
}
|
|
140
|
+
.sidebar-footer:empty {
|
|
141
|
+
display: none;
|
|
142
|
+
}
|
|
102
143
|
|
|
103
144
|
/* Main Content */
|
|
104
145
|
.main {
|
|
105
146
|
position: relative;
|
|
106
147
|
flex: 1;
|
|
107
|
-
display: block;
|
|
108
|
-
overflow: hidden;
|
|
109
148
|
background: var(--u-bg-color);
|
|
149
|
+
overflow: auto;
|
|
110
150
|
}
|
|
111
151
|
|
|
112
152
|
.main u-progress-bar {
|
|
@@ -114,6 +154,7 @@ const r = o`
|
|
|
114
154
|
z-index: 100;
|
|
115
155
|
top: 0;
|
|
116
156
|
left: 0;
|
|
157
|
+
right: 0;
|
|
117
158
|
height: 4px;
|
|
118
159
|
border-radius: 0;
|
|
119
160
|
background-color: transparent;
|
|
@@ -121,7 +162,6 @@ const r = o`
|
|
|
121
162
|
|
|
122
163
|
/* Backdrop for modal mode */
|
|
123
164
|
.backdrop {
|
|
124
|
-
content: '';
|
|
125
165
|
position: absolute;
|
|
126
166
|
z-index: 100;
|
|
127
167
|
top: 0;
|
|
@@ -1,27 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { TemplateResult } from 'lit';
|
|
2
|
+
import { StyleMap } from '../internals/StyledElement';
|
|
3
3
|
import { SidebarLinkConfig } from '../components/SidebarLink';
|
|
4
4
|
import { SidebarSectionConfig } from '../components/SidebarSection';
|
|
5
5
|
import { SidebarGroupConfig } from '../components/SidebarGroup';
|
|
6
6
|
import { SidebarButtonConfig } from '../components/SidebarButton';
|
|
7
7
|
/** 사이드바 레이아웃 컴포넌트의 요소(part) 타입 */
|
|
8
|
-
export type SidebarParts = 'host' | '
|
|
8
|
+
export type SidebarParts = 'host' | 'mobile-header' | 'sidebar' | 'sidebar-header' | 'sidebar-main' | 'sidebar-footer' | 'main' | 'progress';
|
|
9
9
|
/** 사이드바 상태 타입 */
|
|
10
|
-
export type SidebarState = '
|
|
10
|
+
export type SidebarState = 'default' | 'slim' | 'modal' | 'mobile' | 'mobile-open';
|
|
11
11
|
/** 사이드바 안에 HTML 또는 엘리먼트를 직접 렌더링하는 설정 */
|
|
12
|
-
export interface
|
|
13
|
-
type: '
|
|
14
|
-
render: (state: SidebarState) => HTMLElement | string;
|
|
12
|
+
export interface SidebarHtmlConfig {
|
|
13
|
+
type: 'html';
|
|
14
|
+
render: (state: SidebarState) => TemplateResult<1> | HTMLElement | string;
|
|
15
15
|
}
|
|
16
16
|
/** union: section | group | link | button */
|
|
17
|
-
export type SidebarItem = (SidebarLinkConfig | SidebarSectionConfig | SidebarGroupConfig | SidebarButtonConfig |
|
|
18
|
-
/** 사이드바 전체 설정
|
|
17
|
+
export type SidebarItem = (SidebarLinkConfig | SidebarSectionConfig | SidebarGroupConfig | SidebarButtonConfig | SidebarHtmlConfig);
|
|
18
|
+
/** 사이드바 레이아웃 전체 설정 */
|
|
19
19
|
export interface SidebarLayoutConfig {
|
|
20
20
|
type: 'sidebar';
|
|
21
21
|
/** 최상단 앱 로고 */
|
|
22
|
-
logo?:
|
|
23
|
-
/**
|
|
24
|
-
|
|
22
|
+
logo?: string;
|
|
23
|
+
/** 앱 제목 */
|
|
24
|
+
title?: string;
|
|
25
|
+
/** 상단/메인 메뉴 아이템 항목들 */
|
|
26
|
+
main?: SidebarItem[];
|
|
25
27
|
/** 하단(footer)에 고정해서 렌더할 항목들 */
|
|
26
28
|
footer?: SidebarItem[];
|
|
27
29
|
/** 사이드바 스타일 맵 */
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { InitOptions, Module, Newable, NewableModule } from 'i18next';
|
|
2
2
|
import { RouteConfig, FallbackRouteConfig } from '@iyulab/router';
|
|
3
|
-
import { ThemeInitOptions } from '@iyulab/components/dist/utilities/
|
|
3
|
+
import { ThemeInitOptions } from '@iyulab/components/dist/utilities/Theme.js';
|
|
4
4
|
import { SidebarLayoutConfig } from '../layouts/SidebarLayout.types';
|
|
5
5
|
/**
|
|
6
6
|
* i18next의 초기화 옵션과 플러그인 배열을 포함한 다국어 설정
|
|
7
7
|
*/
|
|
8
|
-
export type
|
|
8
|
+
export type I18nInitOptions = InitOptions & {
|
|
9
9
|
/**
|
|
10
10
|
* i18next 플러그인 배열
|
|
11
11
|
* @description i18next.use() 메서드에 전달되는 플러그인들의 배열입니다.
|
|
@@ -28,10 +28,15 @@ export type LayoutConfig = (SidebarLayoutConfig) & {
|
|
|
28
28
|
*/
|
|
29
29
|
export interface AppConfig {
|
|
30
30
|
/**
|
|
31
|
-
* 현재 애플리케이션의 기본 경로 설정
|
|
31
|
+
* 현재 애플리케이션의 기본 라우팅 경로 설정
|
|
32
32
|
* @default '/'
|
|
33
33
|
*/
|
|
34
34
|
basepath?: string;
|
|
35
|
+
/**
|
|
36
|
+
* 현재 애플리케이션의 기본 아이콘 경로 설정
|
|
37
|
+
* @default '/assets/icons/'
|
|
38
|
+
*/
|
|
39
|
+
iconBasepath?: string;
|
|
35
40
|
/**
|
|
36
41
|
* 클라이언트 사이드 라우팅을 위한 설정 배열
|
|
37
42
|
*/
|
|
@@ -42,11 +47,12 @@ export interface AppConfig {
|
|
|
42
47
|
fallback?: FallbackRouteConfig;
|
|
43
48
|
/**
|
|
44
49
|
* 애플리케이션이 렌더링될 루트 HTML 요소
|
|
45
|
-
* @
|
|
50
|
+
* @default document.body
|
|
46
51
|
*/
|
|
47
52
|
root?: Element;
|
|
48
53
|
/**
|
|
49
54
|
* 애플리케이션을 구성하기 위한 레이아웃 설정
|
|
55
|
+
*
|
|
50
56
|
* @description 현재는 사이드바 레이아웃만 지원합니다.
|
|
51
57
|
*/
|
|
52
58
|
layout: LayoutConfig;
|
|
@@ -55,9 +61,8 @@ export interface AppConfig {
|
|
|
55
61
|
*/
|
|
56
62
|
theme?: ThemeInitOptions;
|
|
57
63
|
/**
|
|
58
|
-
* i18next를
|
|
59
|
-
* @description i18next의 InitOptions와 플러그인 배열을 포함합니다. i18next를 사용하지 않는 경우 이 설정은 생략할 수 있습니다.
|
|
64
|
+
* i18next의 InitOptions와 플러그인 배열을 포함합니다. i18next를 사용하지 않는 경우 이 설정은 생략할 수 있습니다.
|
|
60
65
|
* @see 설정에 대한 자세한 내용은 {@link https://www.i18next.com/overview/configuration-options} 참조하십시오.
|
|
61
66
|
*/
|
|
62
|
-
|
|
67
|
+
i18n?: I18nInitOptions;
|
|
63
68
|
}
|