@iyulab/modern-app 0.2.1 → 0.2.3

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 CHANGED
@@ -1,10 +1,18 @@
1
- # Changelog
2
-
3
- ## 0.2.1 (2025-11-13)
4
- - Fixed few component and sidebar styles
5
- - removed `theme` setter property in `app` instance
6
- - changed `progress` property to function in `app` instance
7
- - changed name `locales` option to `localization` option in `AppConfig` type
8
-
9
- ## 0.2.0 (2025-11-12)
1
+ # Changelog
2
+
3
+ ## 0.2.3 (2025-12-19)
4
+ - added `root` option in `AppConfig` type to set application root element
5
+ - update `@iyulab/components` to v0.1.10
6
+
7
+ ## 0.2.2 (2025-11-17)
8
+ - added `fallback` config in `AppConfig` type
9
+ - improved route-progress handling in layout component
10
+
11
+ ## 0.2.1 (2025-11-13)
12
+ - Fixed few component and sidebar styles
13
+ - removed `theme` setter property in `app` instance
14
+ - changed `progress` property to function in `app` instance
15
+ - changed name `locales` option to `localization` option in `AppConfig` type
16
+
17
+ ## 0.2.0 (2025-11-12)
10
18
  - Initial library version release
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Iyulab, Inc.
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Iyulab, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
package/README.md CHANGED
@@ -1,35 +1,158 @@
1
- # Modern App
2
-
3
- A modern web application framework by iyulab, built on React and Lit Element.
4
-
5
- For complete examples and documentation, visit our demo site: [https://modern-app.iyulab.com](https://modern-app.iyulab.com)
6
-
7
- ## Installation
8
-
9
- ```bash
10
- npm install @iyulab/modern-app
11
- ```
12
-
13
- ## Quick Start
14
-
15
- ```javascript
16
- import { app } from '@iyulab/modern-app';
17
-
18
- // Load your app configuration
19
- await app.load({
20
- layout: {
21
- type: 'sidebar',
22
- // layout configuration
23
- },
24
- routes: [
25
- // your routes
26
- ],
27
- locales: {
28
- // locale configuration
29
- }
30
- });
31
- ```
32
-
33
- ## License
34
-
35
- MIT
1
+ # Modern App
2
+
3
+ A modern web application framework by iyulab, built on React and Lit Element.
4
+
5
+ For complete examples and documentation, visit our demo site: [https://modern-app.iyulab.com](https://modern-app.iyulab.com)
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @iyulab/modern-app
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import { app } from '@iyulab/modern-app';
17
+
18
+ await app.load({
19
+ basepath: '/',
20
+ layout: {
21
+ type: 'sidebar',
22
+ // ...layout configuration
23
+ },
24
+ routes: [
25
+ { index: true, render: () => html`<home-page></home-page>` },
26
+ { path: 'about', render: () => html`<about-page></about-page>` },
27
+ ],
28
+ });
29
+ ```
30
+
31
+ ## API Reference
32
+
33
+ ### Navigation
34
+
35
+ ```typescript
36
+ // Navigate to a path
37
+ app.navigate('/path');
38
+
39
+ // Access router instance
40
+ app.router?.go('/path');
41
+ app.router?.basepath; // Get base path
42
+ app.router?.routes; // Get registered routes
43
+ app.router?.context; // Get current route context
44
+ ```
45
+
46
+ ### Theme Management
47
+
48
+ ```typescript
49
+ // Get current theme
50
+ app.theme.get(); // Returns: 'system' | 'light' | 'dark' | undefined
51
+
52
+ // Set theme
53
+ app.theme.set('dark'); // 'system' | 'light' | 'dark'
54
+
55
+ // Check initialization status
56
+ app.theme.isInitialized;
57
+ ```
58
+
59
+ ### Notifications
60
+
61
+ ```typescript
62
+ // Display notifications (returns Promise<void>)
63
+ await app.notice('Notice message');
64
+ await app.info('Info message');
65
+ await app.success('Success message');
66
+ await app.warning('Warning message');
67
+ await app.error('Error message');
68
+
69
+ // With options
70
+ await app.success('Saved!', {
71
+ title: 'Success',
72
+ duration: 5000, // milliseconds (default: 3000)
73
+ position: 'top-right' // 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'
74
+ });
75
+ ```
76
+
77
+ ### Localization
78
+
79
+ ```typescript
80
+ // Access i18next instance
81
+ app.localizer; // i18next instance
82
+
83
+ // Usage with lit-i18n
84
+ import { translate } from 'lit-i18n';
85
+ html`<p>${translate('namespace::key')}</p>`;
86
+ ```
87
+
88
+ ## Configuration
89
+
90
+ ### AppConfig
91
+
92
+ ```typescript
93
+ interface AppConfig {
94
+ root?: Element; // Root element (default: document.body)
95
+ basepath?: string; // Base path for routing (default: '/')
96
+ routes: RouteConfig[]; // Route definitions
97
+ fallback?: FallbackConfig; // Error fallback route
98
+ theme?: ThemeInitOptions; // Theme configuration
99
+ localization?: i18next.InitOptions; // i18next options
100
+ layout: LayoutConfig; // Layout configuration
101
+ }
102
+ ```
103
+
104
+ ### Theme Options
105
+
106
+ ```typescript
107
+ interface ThemeInitOptions {
108
+ default?: 'system' | 'light' | 'dark'; // Default theme
109
+ debug?: boolean; // Enable debug logging
110
+ store?: false | { // Persist theme preference
111
+ type: 'cookie' | 'localStorage' | 'sessionStorage';
112
+ prefix?: string;
113
+ };
114
+ useBuiltIn?: boolean; // Use built-in styles (default: true)
115
+ }
116
+ ```
117
+
118
+ ### Layout Configuration (Sidebar)
119
+
120
+ ```typescript
121
+ interface SidebarLayoutConfig {
122
+ type: 'sidebar';
123
+ breakpoints?: [number, number]; // [small, medium] (default: [768, 1024])
124
+ logo?: {
125
+ type: 'icon' | 'image';
126
+ icon?: string;
127
+ src?: string;
128
+ label?: string;
129
+ onClick?: () => void;
130
+ };
131
+ menu?: MenuItem[]; // Navigation menu items
132
+ footer?: FooterItem[]; // Footer buttons/items
133
+ }
134
+ ```
135
+
136
+ ### Route Configuration
137
+
138
+ ```typescript
139
+ interface RouteConfig {
140
+ index?: boolean; // Index route
141
+ path?: string; // Route path (supports :param patterns)
142
+ title?: string; // Document title
143
+ force?: boolean; // Force re-render
144
+ render: (context: RouteContext) => RenderResult | Promise<RenderResult>;
145
+ }
146
+
147
+ interface RouteContext {
148
+ href: string; // Full URL
149
+ pathname: string; // Path portion
150
+ basepath: string; // Base path
151
+ params: Record<string, string>; // URL parameters
152
+ progress: (value: number) => void; // Progress callback (0-100)
153
+ }
154
+ ```
155
+
156
+ ## License
157
+
158
+ MIT
@@ -1,15 +1,15 @@
1
- import { runInAction as r } from "mobx";
1
+ import { runInAction as l } from "mobx";
2
2
  import n from "i18next";
3
- import { Router as l } from "@iyulab/router";
4
- import { notifier as c } from "@iyulab/components/dist/utilities/notifier.js";
3
+ import { Router as d } from "@iyulab/router";
5
4
  import { theme as u } from "@iyulab/components/dist/utilities/theme.js";
6
- import { screen as s, progress as d } from "./internals/observables.js";
5
+ import { notifier as h } from "@iyulab/components/dist/utilities/notifier.js";
6
+ import { screen as s } from "./internals/observables.js";
7
7
  class o {
8
8
  // private 생성자로 외부에서 인스턴스 생성 방지
9
9
  constructor() {
10
10
  this.handleWindowResize = (t) => {
11
11
  const e = window.innerWidth, [i, a] = this._config?.layout.breakpoints || [768, 1024];
12
- r(() => {
12
+ l(() => {
13
13
  e < i ? s.set("small") : e < a ? s.set("medium") : s.set("large");
14
14
  });
15
15
  };
@@ -30,41 +30,34 @@ class o {
30
30
  get theme() {
31
31
  return u;
32
32
  }
33
- /** 현재 언어 코드 반환 (i18next.language) */
34
- get language() {
35
- return n.language;
33
+ /** 다국어 로컬라이저(i18next) 반환 */
34
+ get localizer() {
35
+ return n;
36
36
  }
37
37
  /** 앱 로드 및 초기화 */
38
38
  async load(t) {
39
39
  if (this.unload(), this._config = t, await u.init(t.theme), t.localization) {
40
- for (const e of t.localization.plugins || [])
41
- n.use(e);
40
+ for (const i of t.localization.plugins || [])
41
+ n.use(i);
42
42
  await n.init(t.localization);
43
43
  }
44
- window.addEventListener("resize", this.handleWindowResize), this.handleWindowResize(new Event("resize")), this._root = await this.createLayout(t.layout), this._router = new l({
45
- root: this._root,
44
+ window.addEventListener("resize", this.handleWindowResize), this.handleWindowResize(new Event("resize"));
45
+ const e = t.root || document.body;
46
+ this._layout = await this.createLayout(e, t.layout), this._router = new d({
47
+ root: this._layout,
46
48
  basepath: t.basepath,
47
- routes: t.routes
48
- }), console.log("✅ App loaded successfully");
49
+ routes: t.routes,
50
+ fallback: t.fallback
51
+ });
49
52
  }
50
53
  /** 앱 언로드 */
51
54
  unload() {
52
- window.removeEventListener("resize", this.handleWindowResize), this._root && (this._root.remove(), this._root = void 0), this._router && (this._router.destroy(), this._router = void 0), this._config && (this._config = void 0);
55
+ window.removeEventListener("resize", this.handleWindowResize), this._layout && (this._layout.remove(), this._layout = void 0), this._router && (this._router.destroy(), this._router = void 0), this._config && (this._config = void 0);
53
56
  }
54
57
  /** 페이지 이동 */
55
58
  navigate(t) {
56
59
  this._router?.go(t);
57
60
  }
58
- /** 언어 설정 변경(i18next.changeLanguage 호출) */
59
- async setLanguage(t) {
60
- await n.changeLanguage(t);
61
- }
62
- /** 레이아웃 진행바 설정 */
63
- progress(t) {
64
- r(() => {
65
- d.set(t);
66
- });
67
- }
68
61
  /** 공지 메시지 */
69
62
  async notice(t, e) {
70
63
  await this.notify("notice", t, e);
@@ -85,28 +78,29 @@ class o {
85
78
  async error(t, e) {
86
79
  await this.notify("error", t, e);
87
80
  }
88
- /** 레이아웃 생성 */
89
- async createLayout(t) {
90
- let e = document.body.querySelector("[data-layout]");
91
- if (e && document.body.removeChild(e), t.type === "sidebar") {
92
- const { SidebarLayout: i } = await import("./layouts/SidebarLayout.js"), a = new i();
93
- a.config = t, e = a;
94
- } else
95
- throw new Error(`Unsupported layout type: ${t.type}`);
96
- return e.setAttribute("data-layout", "true"), document.body.appendChild(e), "updateComplete" in e && await e.updateComplete, e;
97
- }
98
81
  /** 알림 표시 */
99
82
  async notify(t, e, i) {
100
- await c.toast({
83
+ await h.toast({
101
84
  type: t,
102
85
  content: e,
103
- label: i?.title,
86
+ heading: i?.title,
104
87
  duration: i?.duration || 3e3,
105
88
  position: i?.position || "top-right"
106
89
  });
107
90
  }
91
+ /** 레이아웃 생성 */
92
+ async createLayout(t, e) {
93
+ t === document.body && (document.body.style.margin = "0", document.body.style.width = "100vw", document.body.style.height = "100vh");
94
+ let i = t.querySelector("[data-layout]");
95
+ if (i && t.removeChild(i), e.type === "sidebar") {
96
+ const { SidebarLayout: a } = await import("./layouts/SidebarLayout.js"), r = new a();
97
+ r.config = e, i = r;
98
+ } else
99
+ throw new Error(`Unsupported layout type: ${e.type}`);
100
+ return i.setAttribute("data-layout", "true"), t.appendChild(i), "updateComplete" in i && await i.updateComplete, i;
101
+ }
108
102
  }
109
- const g = o.instance;
103
+ const _ = o.instance;
110
104
  export {
111
- g as app
105
+ _ as app
112
106
  };
@@ -1,19 +1,19 @@
1
1
  import { html as c } from "lit";
2
2
  import { property as o } from "lit/decorators.js";
3
- import { Icon as l } from "@iyulab/components/dist/components/Icon/Icon.js";
3
+ import { UIcon as l } from "@iyulab/components/dist/components/Icon/UIcon.component.js";
4
4
  import { ExtendedBaseElement as m } from "../internals/ExtendedBaseElement.js";
5
- import { styles as u } from "./SidebarButton.styles.js";
6
- var d = Object.defineProperty, n = (e, p, s, f) => {
5
+ import { styles as d } from "./SidebarButton.styles.js";
6
+ var u = Object.defineProperty, n = (e, p, s, f) => {
7
7
  for (var t = void 0, r = e.length - 1, a; r >= 0; r--)
8
8
  (a = e[r]) && (t = a(p, s, t) || t);
9
- return t && d(p, s, t), t;
9
+ return t && u(p, s, t), t;
10
10
  };
11
11
  class i extends m {
12
12
  constructor() {
13
13
  super(...arguments), this.compact = !1;
14
14
  }
15
15
  static {
16
- this.styles = [super.styles, u];
16
+ this.styles = [super.styles, d];
17
17
  }
18
18
  static {
19
19
  this.dependencies = {
@@ -25,7 +25,6 @@ class i extends m {
25
25
  <button part="base">
26
26
  <u-icon part="icon"
27
27
  ?hidden=${!this.icon}
28
- ?remote=${!0}
29
28
  .name=${this.icon}
30
29
  ></u-icon>
31
30
  <span part="label"
@@ -5,7 +5,7 @@ const r = o`
5
5
  width: 100%;
6
6
  padding: 8px 12px;
7
7
  font-size: 14px;
8
- color: var(--u-text-color);
8
+ color: var(--u-txt-color);
9
9
  background: transparent;
10
10
  border: none;
11
11
  border-radius: 8px;
@@ -21,7 +21,7 @@ const r = o`
21
21
  gap: 0;
22
22
  }
23
23
  :host(:hover) {
24
- color: var(--u-text-color-hover);
24
+ color: var(--u-txt-color-hover);
25
25
  background-color: var(--u-bg-color-hover);
26
26
  }
27
27
  :host(:active) {
@@ -38,7 +38,7 @@ const r = o`
38
38
  gap: 12px;
39
39
  }
40
40
  button:focus-visible {
41
- outline: 2px solid var(--u-input-border-focus);
41
+ outline: 2px solid #6666ff;
42
42
  outline-offset: 2px;
43
43
  }
44
44
 
@@ -1,7 +1,7 @@
1
1
  import { html as c } from "lit";
2
2
  import { property as o } from "lit/decorators.js";
3
- import { Icon as d } from "@iyulab/components/dist/components/Icon/Icon.js";
4
- import { app as m } from "../app.js";
3
+ import { UIcon as d } from "@iyulab/components/dist/components/Icon/UIcon.component.js";
4
+ import { app as m } from "../App.js";
5
5
  import { ExtendedBaseElement as u } from "../internals/ExtendedBaseElement.js";
6
6
  import { SidebarLink as h } from "./SidebarLink.js";
7
7
  import { styles as f } from "./SidebarGroup.styles.js";
@@ -35,13 +35,13 @@ class s extends u {
35
35
  @click=${this.handleButtonClick}>
36
36
  <u-icon class="icon" part="icon"
37
37
  ?hidden=${!this.icon}
38
- ?remote=${!0}
39
38
  .name=${this.icon}
40
39
  ></u-icon>
41
40
  <span class="label" part="label">
42
41
  ${this.label}
43
42
  </span>
44
43
  <u-icon class="toggler" part="toggler"
44
+ lib="internal"
45
45
  name="chevron-down"
46
46
  ></u-icon>
47
47
  </button>
@@ -40,7 +40,7 @@ const e = o`
40
40
  gap: 12px;
41
41
  width: 100%;
42
42
  padding: 8px 12px;
43
- color: var(--u-text-color);
43
+ color: var(--u-txt-color);
44
44
  font-family: inherit;
45
45
  background: transparent;
46
46
  border: none;
@@ -50,7 +50,7 @@ const e = o`
50
50
  }
51
51
  button:hover {
52
52
  background-color: var(--u-bg-color-hover);
53
- color: var(--u-text-color-hover);
53
+ color: var(--u-txt-color-hover);
54
54
  }
55
55
 
56
56
  .icon {
@@ -1,17 +1,17 @@
1
1
  import { html as c } from "lit";
2
2
  import { property as e } from "lit/decorators.js";
3
- import { Icon as l } from "@iyulab/components/dist/components/Icon/Icon.js";
3
+ import { UIcon as l } from "@iyulab/components/dist/components/Icon/UIcon.component.js";
4
4
  import { ExtendedBaseElement as h } from "../internals/ExtendedBaseElement.js";
5
5
  import { styles as d } from "./SidebarLink.styles.js";
6
- var u = Object.defineProperty, n = (o, r, a, f) => {
6
+ var f = Object.defineProperty, n = (o, r, a, m) => {
7
7
  for (var t = void 0, s = o.length - 1, p; s >= 0; s--)
8
8
  (p = o[s]) && (t = p(r, a, t) || t);
9
- return t && u(r, a, t), t;
9
+ return t && f(r, a, t), t;
10
10
  };
11
11
  class i extends h {
12
12
  constructor() {
13
13
  super(...arguments), this.selected = !1, this.compact = !1, this.handleRouteBegin = (r) => {
14
- this.pattern ||= this.href, this.pattern ? (this.pattern = typeof this.pattern == "string" ? new URLPattern(this.pattern, window.location.origin) : this.pattern, this.selected = this.pattern.test(r.routeInfo.path, window.location.origin)) : this.selected = !1;
14
+ this.pattern ||= this.href, this.pattern ? (this.pattern = typeof this.pattern == "string" ? new URLPattern(this.pattern, window.location.origin) : this.pattern, this.selected = this.pattern.test(r.context.path, window.location.origin)) : this.selected = !1;
15
15
  };
16
16
  }
17
17
  static {
@@ -35,7 +35,6 @@ class i extends h {
35
35
  ?compact=${this.compact}>
36
36
  <u-icon part="icon"
37
37
  ?hidden=${!this.icon}
38
- ?remote=${!0}
39
38
  .name=${this.icon}
40
39
  ></u-icon>
41
40
  <span part="label"
@@ -1,26 +1,26 @@
1
1
  import { css as o } from "lit";
2
- const r = o`
2
+ const e = o`
3
3
  :host {
4
4
  display: block;
5
5
  border-radius: 8px;
6
- color: var(--u-text-color);
6
+ color: var(--u-txt-color);
7
7
  text-decoration: none;
8
8
  transition: all 0.2s ease;
9
9
  cursor: pointer;
10
10
  }
11
11
  :host(:hover) {
12
- color: var(--u-text-color-hover);
12
+ color: var(--u-txt-color-hover);
13
13
  background-color: var(--u-bg-color-hover);
14
14
  }
15
15
  :host([selected]) {
16
- color: var(--u-text-color-inverse);
16
+ color: var(--u-txt-color-inverse);
17
17
  background-color: var(--u-blue-600);
18
- box-shadow: 0 1px 3px var(--u-shadow-weak);
18
+ box-shadow: 0 1px 3px var(--u-shadow-color-weak);
19
19
  }
20
20
  :host([selected]:hover) {
21
- color: var(--u-text-color-inverse);
21
+ color: var(--u-txt-color-inverse);
22
22
  background-color: var(--u-blue-700);
23
- box-shadow: 0 2px 6px var(--u-shadow-normal);
23
+ box-shadow: 0 2px 6px var(--u-shadow-color-normal);
24
24
  }
25
25
 
26
26
  u-link {
@@ -54,5 +54,5 @@ const r = o`
54
54
  }
55
55
  `;
56
56
  export {
57
- r as styles
57
+ e as styles
58
58
  };
@@ -1,6 +1,6 @@
1
1
  import { nothing as m, html as s } from "lit";
2
2
  import { property as e } from "lit/decorators.js";
3
- import { Icon as l } from "@iyulab/components/dist/components/icon/Icon.js";
3
+ import { UIcon as l } from "@iyulab/components/dist/components/icon/UIcon.component.js";
4
4
  import { ExtendedBaseElement as h } from "../internals/ExtendedBaseElement.js";
5
5
  import { styles as y } from "./SidebarLogo.styles.js";
6
6
  var d = Object.defineProperty, i = (r, n, a, g) => {
@@ -29,8 +29,7 @@ class o extends h {
29
29
  src=${this.image}
30
30
  alt="App Logo"
31
31
  />` : this.type === "icon" && this.icon ? s`
32
- <u-icon part="icon"
33
- .remote=${!0}
32
+ <u-icon part="icon"
34
33
  .name=${this.icon}
35
34
  ></u-icon>` : m}
36
35
  <span part="label"
@@ -1,19 +1,19 @@
1
- import { css as e } from "lit";
2
- const t = e`
1
+ import { css as o } from "lit";
2
+ const e = o`
3
3
  :host {
4
4
  display: block;
5
5
  min-width: 0;
6
6
  font-size: 32px;
7
- color: var(--u-text-color);
7
+ color: var(--u-txt-color);
8
8
  user-select: none;
9
9
  cursor: pointer;
10
10
  transition: all 0.2s ease;
11
11
  }
12
12
  :host(:hover) {
13
- color: var(--u-text-color-hover);
13
+ color: var(--u-txt-color-hover);
14
14
  }
15
15
  :host(:active) {
16
- color: var(--u-text-color-active);
16
+ color: var(--u-txt-color-active);
17
17
  }
18
18
 
19
19
  .container {
@@ -53,5 +53,5 @@ const t = e`
53
53
  }
54
54
  `;
55
55
  export {
56
- t as styles
56
+ e as styles
57
57
  };
@@ -21,7 +21,7 @@ const o = e`
21
21
  .title {
22
22
  font-size: 12px;
23
23
  font-weight: 700;
24
- color: var(--u-soft-text-color);
24
+ color: var(--u-txt-color-weak);
25
25
  text-transform: uppercase;
26
26
  letter-spacing: 0.5px;
27
27
  margin: 0;
@@ -29,7 +29,7 @@ const o = e`
29
29
 
30
30
  .subtitle {
31
31
  font-size: 11px;
32
- color: var(--u-text-color-disabled);
32
+ color: var(--u-txt-color-disabled);
33
33
  margin: 0;
34
34
  }
35
35
 
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { app } from './app';
1
+ import { app } from './App.js';
2
2
  export type * from './types/AppConfigs.js';
3
3
  export type * from './types/AppOptions.js';
4
4
  export type * from './types/AppTypes.js';
5
- export { app } from './app';
5
+ export { app };
6
6
  export default app;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { app as a } from "./app.js";
1
+ import { app as a } from "./App.js";
2
2
  export {
3
3
  a as app,
4
4
  a as default
@@ -5,7 +5,3 @@ export type ScreenSize = 'small' | 'medium' | 'large';
5
5
  * 현재 화면 크기 상태
6
6
  */
7
7
  export declare const screen: IObservableValue<ScreenSize>;
8
- /**
9
- * 로딩 진행 상태 (0 - 100)
10
- */
11
- export declare const progress: IObservableValue<number>;
@@ -1,6 +1,5 @@
1
- import { observable as o } from "mobx";
2
- const e = o.box("large"), s = o.box(0);
1
+ import { observable as e } from "mobx";
2
+ const r = e.box("large");
3
3
  export {
4
- s as progress,
5
- e as screen
4
+ r as screen
6
5
  };
@@ -1,17 +1,19 @@
1
1
  import { nothing, PropertyValues } from 'lit';
2
2
  import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
3
+ import { UIconButton } from '@iyulab/components/dist/components/icon-button/UIconButton.component.js';
4
+ import { UProgressBar } from '@iyulab/components/dist/components/progress-bar/UProgressBar.component.js';
3
5
  import { ExtendedBaseElement } from '../internals/ExtendedBaseElement';
4
- import { ProgressBar } from '../components/ProgressBar';
5
6
  import { SidebarLogo } from '../components/SidebarLogo';
6
7
  import { SidebarSection } from '../components/SidebarSection';
7
8
  import { SidebarGroup } from '../components/SidebarGroup';
8
9
  import { SidebarLink } from '../components/SidebarLink';
9
10
  import { SidebarButton } from '../components/SidebarButton';
10
11
  import { SidebarLayoutConfig, SidebarState, SidebarParts } from './SidebarLayout.types';
11
- /** 엘리먼트 타입 매핑 */
12
+ /** 엘리먼트 타입 매핑 (for deveveloper experience) */
12
13
  declare global {
13
14
  interface HTMLElementTagNameMap {
14
- 'u-progress-bar': ProgressBar;
15
+ 'u-icon-button': UIconButton;
16
+ 'u-progress-bar': UProgressBar;
15
17
  'u-sidebar-logo': SidebarLogo;
16
18
  'u-sidebar-section': SidebarSection;
17
19
  'u-sidebar-group': SidebarGroup;
@@ -35,7 +37,7 @@ export declare class SidebarLayout extends ExtendedBaseElement<SidebarParts> {
35
37
  static dependencies: Record<string, typeof BaseElement>;
36
38
  /** 반응형 상태 관리를 위한 MobX 반응 해제 함수들 */
37
39
  private disposers;
38
- progressEl?: ProgressBar;
40
+ progressBarEl: UProgressBar;
39
41
  /** 사이드바 상태 */
40
42
  state: SidebarState;
41
43
  /** 사이드바 레이아웃 설정 */
@@ -55,4 +57,10 @@ export declare class SidebarLayout extends ExtendedBaseElement<SidebarParts> {
55
57
  * 백드롭 클릭 or 라우트 변경 시
56
58
  */
57
59
  private toggleStateIfModalState;
60
+ /** 라우트 변경 시작 핸들러 */
61
+ private handleRouteBegin;
62
+ /** 라우트 변경 진행 핸들러 */
63
+ private handleRouteProgress;
64
+ /** 라우트 변경 완료 핸들러 */
65
+ private handleRouteDone;
58
66
  }
@@ -1,24 +1,24 @@
1
1
  import { nothing as p, html as i } from "lit";
2
- import { query as f, state as b, property as h, customElement as m } from "lit/decorators.js";
3
- import { repeat as l } from "lit/directives/repeat.js";
4
- import { autorun as g } from "mobx";
5
- import { IconButton as $ } from "@iyulab/components/dist/components/icon-button/IconButton.js";
6
- import { screen as u, progress as y } from "../internals/observables.js";
7
- import { ExtendedBaseElement as v } from "../internals/ExtendedBaseElement.js";
8
- import { ProgressBar as S } from "../components/ProgressBar.js";
2
+ import { query as h, state as g, property as b, customElement as f } from "lit/decorators.js";
3
+ import { unsafeHTML as m } from "lit/directives/unsafe-html.js";
4
+ import { repeat as n } from "lit/directives/repeat.js";
5
+ import { autorun as $ } from "mobx";
6
+ import { UIconButton as v } from "@iyulab/components/dist/components/icon-button/UIconButton.component.js";
7
+ import { UProgressBar as y } from "@iyulab/components/dist/components/progress-bar/UProgressBar.component.js";
8
+ import { screen as u } from "../internals/observables.js";
9
+ import { ExtendedBaseElement as S } from "../internals/ExtendedBaseElement.js";
9
10
  import { SidebarLogo as _ } from "../components/SidebarLogo.js";
10
- import { SidebarSection as k } from "../components/SidebarSection.js";
11
- import { SidebarGroup as w } from "../components/SidebarGroup.js";
12
- import { SidebarLink as I } from "../components/SidebarLink.js";
13
- import { SidebarButton as E } from "../components/SidebarButton.js";
14
- import { styles as C } from "./SidebarLayout.styles.js";
15
- import { unsafeHTML as O } from "lit/directives/unsafe-html.js";
16
- var M = Object.defineProperty, L = Object.getOwnPropertyDescriptor, P = Object.getPrototypeOf, B = Reflect.get, n = (e, t, s, a) => {
17
- for (var r = a > 1 ? void 0 : a ? L(t, s) : t, d = e.length - 1, c; d >= 0; d--)
11
+ import { SidebarSection as w } from "../components/SidebarSection.js";
12
+ import { SidebarGroup as k } from "../components/SidebarGroup.js";
13
+ import { SidebarLink as E } from "../components/SidebarLink.js";
14
+ import { SidebarButton as B } from "../components/SidebarButton.js";
15
+ import { styles as L } from "./SidebarLayout.styles.js";
16
+ var R = Object.defineProperty, I = Object.getOwnPropertyDescriptor, P = Object.getPrototypeOf, C = Reflect.get, l = (e, t, s, a) => {
17
+ for (var r = a > 1 ? void 0 : a ? I(t, s) : t, d = e.length - 1, c; d >= 0; d--)
18
18
  (c = e[d]) && (r = (a ? c(t, s, r) : c(r)) || r);
19
- return a && r && M(t, s, r), r;
20
- }, j = (e, t, s) => B(P(e), s, t);
21
- let o = class extends v {
19
+ return a && r && R(t, s, r), r;
20
+ }, O = (e, t, s) => C(P(e), s, t);
21
+ let o = class extends S {
22
22
  constructor() {
23
23
  super(...arguments), this.disposers = [], this.state = "docked", this.toggleState = () => {
24
24
  const e = u.get();
@@ -26,19 +26,22 @@ let o = class extends v {
26
26
  }, this.toggleStateIfModalState = () => {
27
27
  const e = u.get();
28
28
  this.state === "modal" && (e === "medium" ? this.state = "slim" : e === "small" && (this.state = "closed"));
29
+ }, this.handleRouteBegin = (e) => {
30
+ this.progressBarEl.value = 0, this.toggleStateIfModalState();
31
+ }, this.handleRouteProgress = (e) => {
32
+ this.progressBarEl.value = e.progress;
33
+ }, this.handleRouteDone = (e) => {
34
+ this.progressBarEl.value = 100;
29
35
  };
30
36
  }
31
37
  connectedCallback() {
32
- super.connectedCallback(), this.disposers.push(g(() => {
38
+ super.connectedCallback(), this.disposers.push($(() => {
33
39
  const e = u.get();
34
40
  this.updateState(e);
35
- })), this.disposers.push(g(() => {
36
- const e = y.get();
37
- this.progressEl && (this.progressEl.value = e);
38
- })), window.addEventListener("route-begin", this.toggleStateIfModalState);
41
+ })), window.addEventListener("route-begin", this.handleRouteBegin), window.addEventListener("route-done", this.handleRouteDone), window.addEventListener("route-progress", this.handleRouteProgress);
39
42
  }
40
43
  disconnectedCallback() {
41
- this.disposers.forEach((e) => e()), window.removeEventListener("route-begin", this.toggleStateIfModalState), super.disconnectedCallback();
44
+ this.disposers.forEach((e) => e()), window.removeEventListener("route-begin", this.handleRouteBegin), window.removeEventListener("route-done", this.handleRouteDone), window.removeEventListener("route-progress", this.handleRouteProgress), super.disconnectedCallback();
42
45
  }
43
46
  updated(e) {
44
47
  super.updated(e), e.has("config") && (this.styles = this.config?.styles);
@@ -51,14 +54,15 @@ let o = class extends v {
51
54
  <div class="sidebar-header" part="sidebar-header">
52
55
  <u-sidebar-logo
53
56
  .compact="${this.state === "slim"}"
54
- .type=${this.config.logo.type}
55
- .image="${this.config.logo.image}"
56
- .icon="${this.config.logo.icon}"
57
- .label="${this.config.logo.label}"
58
- .styles="${this.config.logo.styles}"
59
- @click="${this.config.logo.onClick}"
57
+ .type=${this.config.logo?.type || "icon"}
58
+ .image="${this.config.logo?.image}"
59
+ .icon="${this.config.logo?.icon}"
60
+ .label="${this.config.logo?.label}"
61
+ .styles="${this.config.logo?.styles}"
62
+ @click="${this.config.logo?.onClick}"
60
63
  ></u-sidebar-logo>
61
64
  <u-icon-button class="sidebar-toggler" part="sidebar-toggler"
65
+ lib="internal"
62
66
  name=${this.state === "closed" ? "chevron-right" : "layout-sidebar"}
63
67
  @click="${this.toggleState}"
64
68
  ></u-icon-button>
@@ -66,7 +70,7 @@ let o = class extends v {
66
70
 
67
71
  <!-- Sidebar Navigation Menu -->
68
72
  <nav class="sidebar-menu" part="sidebar-menu">
69
- ${l(
73
+ ${n(
70
74
  this.config.menu ?? [],
71
75
  (e, t) => t,
72
76
  (e, t) => this.renderItem(e)
@@ -76,7 +80,7 @@ let o = class extends v {
76
80
  <!-- Sidebar Footer -->
77
81
  <div class="sidebar-footer" part="sidebar-footer"
78
82
  ?hidden="${!this.config.footer || this.config.footer.length === 0}">
79
- ${l(
83
+ ${n(
80
84
  this.config.footer ?? [],
81
85
  (e, t) => t,
82
86
  (e, t) => this.renderItem(e)
@@ -100,7 +104,11 @@ let o = class extends v {
100
104
  }
101
105
  /** 사이드바 아이템 렌더링 */
102
106
  renderItem(e) {
103
- return e ? e.type === "content" ? this.state === "slim" ? p : O(e.content) : e.type === "button" ? i`
107
+ if (!e) return p;
108
+ if (e.type === "innerHtml") {
109
+ const t = e.render(this.state);
110
+ return typeof t == "string" ? m(t) : i`${t}`;
111
+ } else return e.type === "button" ? i`
104
112
  <u-sidebar-button
105
113
  ?compact=${this.state === "slim"}
106
114
  .icon="${e.icon}"
@@ -115,7 +123,7 @@ let o = class extends v {
115
123
  .subTitle="${e.subTitle}"
116
124
  .items="${e.items}"
117
125
  .styles="${e.styles}">
118
- ${l(
126
+ ${n(
119
127
  e.items,
120
128
  (t, s) => s,
121
129
  (t, s) => this.renderItem(t)
@@ -129,7 +137,7 @@ let o = class extends v {
129
137
  .label="${e.label}"
130
138
  .items="${e.items}"
131
139
  .styles="${e.styles}">
132
- ${l(
140
+ ${n(
133
141
  e.items,
134
142
  (t, s) => s,
135
143
  (t, s) => this.renderItem(t)
@@ -144,34 +152,34 @@ let o = class extends v {
144
152
  .pattern="${e.pattern}"
145
153
  .styles="${e.styles}"
146
154
  ></u-sidebar-link>
147
- ` : p;
155
+ `;
148
156
  }
149
157
  /** 화면 크기 변경에 따른 사이드바 상태 업데이트 */
150
158
  updateState(e) {
151
159
  e === "large" ? this.state = "docked" : e === "medium" ? this.state = "slim" : e === "small" ? this.state = "closed" : console.warn("Unknown screen size:", e);
152
160
  }
153
161
  };
154
- o.styles = [j(o, o, "styles"), C];
162
+ o.styles = [O(o, o, "styles"), L];
155
163
  o.dependencies = {
156
- "u-icon-button": $,
157
- "u-progress-bar": S,
164
+ "u-icon-button": v,
165
+ "u-progress-bar": y,
158
166
  "u-sidebar-logo": _,
159
- "u-sidebar-section": k,
160
- "u-sidebar-group": w,
161
- "u-sidebar-link": I,
162
- "u-sidebar-button": E
167
+ "u-sidebar-section": w,
168
+ "u-sidebar-group": k,
169
+ "u-sidebar-link": E,
170
+ "u-sidebar-button": B
163
171
  };
164
- n([
165
- f("u-progress-bar")
166
- ], o.prototype, "progressEl", 2);
167
- n([
168
- b()
172
+ l([
173
+ h("u-progress-bar")
174
+ ], o.prototype, "progressBarEl", 2);
175
+ l([
176
+ g()
169
177
  ], o.prototype, "state", 2);
170
- n([
171
- h({ type: Object })
178
+ l([
179
+ b({ type: Object })
172
180
  ], o.prototype, "config", 2);
173
- o = n([
174
- m("app-sidebar-layout")
181
+ o = l([
182
+ f("u-sidebar-layout")
175
183
  ], o);
176
184
  export {
177
185
  o as SidebarLayout
@@ -4,8 +4,8 @@ const r = o`
4
4
  position: relative;
5
5
  display: flex;
6
6
  flex-direction: row;
7
- width: 100vw;
8
- height: 100vh;
7
+ width: 100%;
8
+ height: 100%;
9
9
  overflow: hidden;
10
10
  }
11
11
 
@@ -21,7 +21,7 @@ const r = o`
21
21
  height: 100vh;
22
22
  background: var(--u-panel-bg-color);
23
23
  border-right: 1px solid var(--u-border-color);
24
- box-shadow: 0 2px 8px var(--u-shadow-weak);
24
+ box-shadow: 0 2px 8px var(--u-shadow-color-weak);
25
25
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
26
26
  }
27
27
  /* Sidebar states */
@@ -100,6 +100,25 @@ const r = o`
100
100
  border-top: 1px solid var(--u-border-color-weak);
101
101
  }
102
102
 
103
+ /* Main Content */
104
+ .main {
105
+ position: relative;
106
+ flex: 1;
107
+ display: block;
108
+ overflow: hidden;
109
+ background: var(--u-bg-color);
110
+ }
111
+
112
+ .main u-progress-bar {
113
+ position: absolute;
114
+ z-index: 100;
115
+ top: 0;
116
+ left: 0;
117
+ height: 4px;
118
+ border-radius: 0;
119
+ background-color: transparent;
120
+ }
121
+
103
122
  /* Backdrop for modal mode */
104
123
  .backdrop {
105
124
  content: '';
@@ -111,15 +130,6 @@ const r = o`
111
130
  bottom: 0;
112
131
  background: var(--u-overlay-bg-color);
113
132
  }
114
-
115
- /* Main Content */
116
- .main {
117
- position: relative;
118
- flex: 1;
119
- display: block;
120
- overflow: hidden;
121
- background: var(--u-bg-color);
122
- }
123
133
  `;
124
134
  export {
125
135
  r as styles
@@ -8,18 +8,18 @@ import { SidebarButtonConfig } from '../components/SidebarButton';
8
8
  export type SidebarParts = 'host' | 'sidebar' | 'sidebar-toggler' | 'sidebar-header' | 'sidebar-menu' | 'sidebar-footer' | 'main' | 'progress';
9
9
  /** 사이드바 상태 타입 */
10
10
  export type SidebarState = 'docked' | 'modal' | 'slim' | 'closed';
11
- /** 사이드바 컨텐츠 커스텀 HTML 타입 */
12
- export interface SidebarContentConfig {
13
- type: 'content';
14
- content: string;
11
+ /** 사이드바 안에 HTML 또는 엘리먼트를 직접 렌더링하는 설정 */
12
+ export interface SidebarInnerHtmlConfig {
13
+ type: 'innerHtml';
14
+ render: (state: SidebarState) => HTMLElement | string;
15
15
  }
16
16
  /** union: section | group | link | button */
17
- export type SidebarItem = (SidebarLinkConfig | SidebarSectionConfig | SidebarGroupConfig | SidebarButtonConfig | SidebarContentConfig);
17
+ export type SidebarItem = (SidebarLinkConfig | SidebarSectionConfig | SidebarGroupConfig | SidebarButtonConfig | SidebarInnerHtmlConfig);
18
18
  /** 사이드바 전체 설정 (루트) */
19
19
  export interface SidebarLayoutConfig {
20
20
  type: 'sidebar';
21
21
  /** 최상단 앱 로고 */
22
- logo: SidebarLogoConfig;
22
+ logo?: SidebarLogoConfig;
23
23
  /** 상단/메인 메뉴 항목들 */
24
24
  menu?: SidebarItem[];
25
25
  /** 하단(footer)에 고정해서 렌더할 항목들 */
@@ -1,5 +1,5 @@
1
1
  import { InitOptions, Module, Newable, NewableModule } from 'i18next';
2
- import { RouteConfig } from '@iyulab/router';
2
+ import { RouteConfig, FallbackRouteConfig } from '@iyulab/router';
3
3
  import { ThemeInitOptions } from '@iyulab/components/dist/utilities/theme.js';
4
4
  import { SidebarLayoutConfig } from '../layouts/SidebarLayout.types';
5
5
  /**
@@ -8,7 +8,7 @@ import { SidebarLayoutConfig } from '../layouts/SidebarLayout.types';
8
8
  export type LocalizationInitOptions = InitOptions & {
9
9
  /**
10
10
  * i18next 플러그인 배열
11
- * @description i18next.use() 메서드에 전달될 플러그인들의 배열입니다.
11
+ * @description i18next.use() 메서드에 전달되는 플러그인들의 배열입니다.
12
12
  */
13
13
  plugins?: (Module | NewableModule<Module> | Newable<Module>)[];
14
14
  };
@@ -35,7 +35,21 @@ export interface AppConfig {
35
35
  /**
36
36
  * 클라이언트 사이드 라우팅을 위한 설정 배열
37
37
  */
38
- routes: RouteConfig[];
38
+ routes?: RouteConfig[];
39
+ /**
40
+ * 라우팅 실패 시 대체 컨텐츠 설정
41
+ */
42
+ fallback?: FallbackRouteConfig;
43
+ /**
44
+ * 애플리케이션이 렌더링될 루트 HTML 요소
45
+ * @description 지정하지 않을 경우 document.body가 사용됩니다.
46
+ */
47
+ root?: Element;
48
+ /**
49
+ * 애플리케이션을 구성하기 위한 레이아웃 설정
50
+ * @description 현재는 사이드바 레이아웃만 지원합니다.
51
+ */
52
+ layout: LayoutConfig;
39
53
  /**
40
54
  * 애플리케이션의 스타일 테마 설정
41
55
  */
@@ -46,9 +60,4 @@ export interface AppConfig {
46
60
  * @see 설정에 대한 자세한 내용은 {@link https://www.i18next.com/overview/configuration-options} 참조하십시오.
47
61
  */
48
62
  localization?: LocalizationInitOptions;
49
- /**
50
- * 애플리케이션을 구성하기 위한 레이아웃 설정
51
- * @description 현재는 사이드바 레이아웃만 지원합니다.
52
- */
53
- layout: LayoutConfig;
54
63
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@iyulab/modern-app",
3
3
  "description": "web-framework by iyulab based on react, lit-element",
4
- "version": "0.2.1",
4
+ "version": "0.2.3",
5
5
  "keywords": [
6
6
  "iyulab",
7
7
  "web-framework",
@@ -38,16 +38,16 @@
38
38
  "build": "vite build"
39
39
  },
40
40
  "dependencies": {
41
- "@iyulab/components": "^0.1.2",
42
- "@iyulab/router": "^0.5.1",
41
+ "@iyulab/components": "^0.1.10",
42
+ "@iyulab/router": "^0.5.3",
43
43
  "lit": "^3.3.1",
44
44
  "mobx": "^6.15.0",
45
- "i18next": "^25.6.2"
45
+ "i18next": "^25.7.3"
46
46
  },
47
47
  "devDependencies": {
48
- "@types/node": "^24.10.1",
48
+ "@types/node": "^25.0.3",
49
49
  "typescript": "^5.9.3",
50
- "vite": "^7.2.2",
50
+ "vite": "^7.3.0",
51
51
  "vite-plugin-dts": "^4.5.4"
52
52
  }
53
- }
53
+ }
package/dist/app.d.ts DELETED
@@ -1,54 +0,0 @@
1
- import { Router } from '@iyulab/router';
2
- import { AppConfig } from './types/AppConfigs.js';
3
- import { NotificationOptions } from './types/AppOptions.js';
4
- /**
5
- * 애플리케이션 전역 상태 및 설정 관리 클래스
6
- */
7
- declare class App {
8
- private static _instance;
9
- private _config?;
10
- private _router?;
11
- private _root?;
12
- private constructor();
13
- /** 싱글톤 인스턴스 반환 */
14
- static get instance(): App;
15
- /** 현재 앱 설정 반환 */
16
- get config(): AppConfig | undefined;
17
- /** 라우터 인스턴스 반환 */
18
- get router(): Router | undefined;
19
- /** 스타일 테마 관리 유틸리티 객체 반환 */
20
- get theme(): import('@iyulab/components/dist/utilities/theme.js').Theme;
21
- /** 현재 언어 코드 반환 (i18next.language) */
22
- get language(): string;
23
- /** 앱 로드 및 초기화 */
24
- load(config: AppConfig): Promise<void>;
25
- /** 앱 언로드 */
26
- unload(): void;
27
- /** 페이지 이동 */
28
- navigate(path: string): void;
29
- /** 언어 설정 변경(i18next.changeLanguage 호출) */
30
- setLanguage(lang: string): Promise<void>;
31
- /** 레이아웃 진행바 설정 */
32
- progress(value: number): void;
33
- /** 공지 메시지 */
34
- notice(message: string, options?: NotificationOptions): Promise<void>;
35
- /** 정보 메시지 */
36
- info(message: string, options?: NotificationOptions): Promise<void>;
37
- /** 경고 메시지 */
38
- warning(message: string, options?: NotificationOptions): Promise<void>;
39
- /** 성공 메시지 */
40
- success(message: string, options?: NotificationOptions): Promise<void>;
41
- /** 에러 메시지 */
42
- error(message: string, options?: NotificationOptions): Promise<void>;
43
- /** 레이아웃 생성 */
44
- private createLayout;
45
- /** 알림 표시 */
46
- private notify;
47
- /** 화면 크기 변경 핸들러 */
48
- private handleWindowResize;
49
- }
50
- /**
51
- * 전역 어플리케이션 설정 및 관리 인스턴스
52
- */
53
- export declare const app: App;
54
- export {};
@@ -1,22 +0,0 @@
1
- import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
2
- /**
3
- * ProgressBar 컴포넌트는 진행 상태를 시각적으로 표시합니다.
4
- * 로딩 상태나 작업 진행률을 표시하는데 사용됩니다.
5
- */
6
- export declare class ProgressBar extends BaseElement {
7
- static styles: import('lit').CSSResultGroup[];
8
- static dependencies: Record<string, typeof BaseElement>;
9
- /** 불확정 상태 (로딩 애니메이션 표시) */
10
- indeterminate: boolean;
11
- /** 최소값 (기본값: 0) */
12
- minValue: number;
13
- /** 최대값 (기본값: 100) */
14
- maxValue: number;
15
- /** 현재값 */
16
- value: number;
17
- connectedCallback(): void;
18
- protected updated(changedProperties: Map<string, unknown>): void;
19
- render(): import('lit-html').TemplateResult<1>;
20
- /** 진행 상태 업데이트 */
21
- private updateProgress;
22
- }
@@ -1,54 +0,0 @@
1
- import { html as h } from "lit";
2
- import { property as i } from "lit/decorators.js";
3
- import { BaseElement as n } from "@iyulab/components/dist/components/BaseElement.js";
4
- import { styles as p } from "./ProgressBar.styles.js";
5
- var v = Object.defineProperty, a = (u, t, s, o) => {
6
- for (var e = void 0, l = u.length - 1, m; l >= 0; l--)
7
- (m = u[l]) && (e = m(t, s, e) || e);
8
- return e && v(t, s, e), e;
9
- };
10
- class r extends n {
11
- constructor() {
12
- super(...arguments), this.indeterminate = !1, this.minValue = 0, this.maxValue = 100, this.value = 0;
13
- }
14
- static {
15
- this.styles = [super.styles, p];
16
- }
17
- static {
18
- this.dependencies = {};
19
- }
20
- connectedCallback() {
21
- super.connectedCallback(), this.setAttribute("role", "progressbar");
22
- }
23
- updated(t) {
24
- super.updated(t), t.has("value") && (this.updateProgress(t.get("value"), this.value), this.setAttribute("aria-valuenow", this.value.toString())), t.has("minValue") && (this.updateProgress(this.value, this.value), this.setAttribute("aria-valuemax", this.maxValue.toString())), t.has("maxValue") && (this.updateProgress(this.value, this.value), this.setAttribute("aria-valuemin", this.minValue.toString())), t.has("indeterminate") && (this.updateProgress(this.value, this.value), this.indeterminate ? (this.removeAttribute("aria-valuenow"), this.setAttribute("aria-busy", "true")) : this.removeAttribute("aria-busy"));
25
- }
26
- render() {
27
- return h`<slot></slot>`;
28
- }
29
- /** 진행 상태 업데이트 */
30
- updateProgress(t, s) {
31
- if (this.indeterminate) return;
32
- const e = (Math.min(Math.max(s, this.minValue), this.maxValue) - this.minValue) / (this.maxValue - this.minValue);
33
- t < s ? (this.style.transform = `scaleX(${e})`, s >= this.maxValue && setTimeout(() => {
34
- this.style.opacity = "0";
35
- }, 300)) : (this.style.opacity = "0", this.style.transform = "scaleX(0)", setTimeout(() => {
36
- this.style.opacity = "1", this.style.transform = `scaleX(${e})`;
37
- }, 300));
38
- }
39
- }
40
- a([
41
- i({ type: Boolean, reflect: !0 })
42
- ], r.prototype, "indeterminate");
43
- a([
44
- i({ type: Number })
45
- ], r.prototype, "minValue");
46
- a([
47
- i({ type: Number })
48
- ], r.prototype, "maxValue");
49
- a([
50
- i({ type: Number })
51
- ], r.prototype, "value");
52
- export {
53
- r as ProgressBar
54
- };
@@ -1 +0,0 @@
1
- export declare const styles: import('lit').CSSResult;
@@ -1,31 +0,0 @@
1
- import { css as t } from "lit";
2
- const a = t`
3
- :host {
4
- display: block;
5
- position: absolute;
6
- z-index: 9999;
7
- top: 0;
8
- left: 0;
9
- right: 0;
10
- height: 4px;
11
- background-color: var(--u-blue-600);
12
- transform-origin: left;
13
- transition: all 0.3s ease-out;
14
- box-shadow: 0 2px 4px var(--u-shadow-weak);
15
- }
16
- :host([indeterminate]) {
17
- animation: indeterminate 1.5s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite;
18
- }
19
-
20
- @keyframes indeterminate {
21
- 0% {
22
- transform: translateX(-100%);
23
- }
24
- 100% {
25
- transform: translateX(100%);
26
- }
27
- }
28
- `;
29
- export {
30
- a as styles
31
- };