@iyulab/modern-app 0.2.5 → 0.3.0

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.
Files changed (33) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/App.d.ts +9 -6
  3. package/dist/App.js +28 -28
  4. package/dist/components/SidebarButton.d.ts +2 -3
  5. package/dist/components/SidebarButton.js +12 -14
  6. package/dist/components/SidebarButton.styles.js +14 -16
  7. package/dist/components/SidebarGroup.d.ts +5 -4
  8. package/dist/components/SidebarGroup.js +45 -46
  9. package/dist/components/SidebarGroup.styles.js +39 -44
  10. package/dist/components/SidebarLink.d.ts +2 -7
  11. package/dist/components/SidebarLink.js +29 -39
  12. package/dist/components/SidebarLink.styles.js +9 -9
  13. package/dist/components/SidebarSection.d.ts +4 -5
  14. package/dist/components/SidebarSection.js +18 -22
  15. package/dist/components/SidebarSection.styles.js +9 -14
  16. package/dist/index.d.ts +2 -3
  17. package/dist/internals/ScreenObserver.d.ts +43 -0
  18. package/dist/internals/ScreenObserver.js +37 -0
  19. package/dist/internals/{ExtendedBaseElement.d.ts → StyledElement.d.ts} +6 -4
  20. package/dist/internals/{ExtendedBaseElement.js → StyledElement.js} +13 -14
  21. package/dist/layouts/SidebarLayout.d.ts +27 -19
  22. package/dist/layouts/SidebarLayout.js +140 -108
  23. package/dist/layouts/SidebarLayout.styles.js +82 -42
  24. package/dist/layouts/SidebarLayout.types.d.ts +14 -12
  25. package/dist/types/AppConfigs.d.ts +11 -6
  26. package/package.json +7 -8
  27. package/dist/components/SidebarLogo.d.ts +0 -33
  28. package/dist/components/SidebarLogo.js +0 -60
  29. package/dist/components/SidebarLogo.styles.d.ts +0 -1
  30. package/dist/components/SidebarLogo.styles.js +0 -57
  31. package/dist/internals/observables.d.ts +0 -7
  32. package/dist/internals/observables.js +0 -5
  33. package/dist/types/AppTypes.d.ts +0 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0 (2026-01-21)
4
+
5
+ ### Breaking Changes
6
+ - **Configuration Updates**:
7
+ - Renamed `localization` to `i18n`
8
+ - Renamed `layout.menu` to `layout.main`
9
+ - Changed `logo` type to string (icon name)
10
+ - Added `title` property for app title
11
+ - Added `iconBasepath` option
12
+ - **Mobile layout support**: New mobile states (`mobile`, `mobile-open`) with dedicated mobile header
13
+
14
+ ### Removals
15
+ - Removed `SidebarLogo` component: Logo is now rendered using `u-icon` component
16
+ - Removed `observables.ts`: Replaced MobX observables with native `ScreenObserver` class
17
+ - Removed `AppTypes.ts`: Type definitions moved to their respective modules
18
+
19
+ ### Improvements
20
+ - Improved responsive behavior with screen size observer
21
+ - Added route context tracking and active link highlighting
22
+ - Improved color scheme and typography
23
+ - Enhanced transition animations
24
+ - Cleaner layout spacing and gaps
25
+ - Improved event handling for route changes and screen resizing
26
+ - Enhanced pattern matching for active link detection
27
+
3
28
  ## 0.2.5 (2026-01-06)
4
29
  - Updated `@iyulab/components` to v0.1.11
5
30
 
package/dist/App.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { Router } from '@iyulab/router';
2
- import { AppConfig } from './types/AppConfigs.js';
3
- import { NotificationOptions } from './types/AppOptions.js';
2
+ import { Theme } from '@iyulab/components/dist/utilities/Theme.js';
3
+ import { ScreenSize } from './internals/ScreenObserver';
4
+ import { AppConfig } from './types/AppConfigs';
5
+ import { NotificationOptions } from './types/AppOptions';
4
6
  /**
5
7
  * 애플리케이션 전역 상태 및 설정 관리 클래스
6
8
  */
@@ -9,6 +11,7 @@ declare class App {
9
11
  private _config?;
10
12
  private _layout?;
11
13
  private _router?;
14
+ private _screen?;
12
15
  private constructor();
13
16
  /** 싱글톤 인스턴스 반환 */
14
17
  static get instance(): App;
@@ -16,10 +19,12 @@ declare class App {
16
19
  get config(): AppConfig | undefined;
17
20
  /** 라우터 인스턴스 반환 */
18
21
  get router(): Router | undefined;
22
+ /** 화면 크기 반환 */
23
+ get screen(): ScreenSize | undefined;
19
24
  /** 스타일 테마 관리 유틸리티 객체 반환 */
20
- get theme(): import('@iyulab/components/dist/utilities/theme.js').Theme;
25
+ get theme(): typeof Theme;
21
26
  /** 다국어 로컬라이저(i18next) 반환 */
22
- get localizer(): import('i18next').i18n;
27
+ get i18n(): import('i18next').i18n;
23
28
  /** 앱 로드 및 초기화 */
24
29
  load(config: AppConfig): Promise<void>;
25
30
  /** 앱 언로드 */
@@ -40,8 +45,6 @@ declare class App {
40
45
  private notify;
41
46
  /** 레이아웃 생성 */
42
47
  private createLayout;
43
- /** 화면 크기 변경 핸들러 */
44
- private handleWindowResize;
45
48
  }
46
49
  /**
47
50
  * 전역 어플리케이션 설정 및 관리 인스턴스
package/dist/App.js CHANGED
@@ -1,18 +1,12 @@
1
- import { runInAction as l } from "mobx";
2
- import n from "i18next";
3
- import { Router as d } from "@iyulab/router";
4
- import { theme as u } from "@iyulab/components/dist/utilities/theme.js";
5
- import { notifier as h } from "@iyulab/components/dist/utilities/notifier.js";
6
- import { screen as s } from "./internals/observables.js";
1
+ import r from "i18next";
2
+ import { Router as u } from "@iyulab/router";
3
+ import { setDefaultBaseUrl as h } from "@iyulab/components/dist/utilities/IconRegistry.js";
4
+ import { Theme as s } from "@iyulab/components/dist/utilities/Theme.js";
5
+ import { Notifier as y } from "@iyulab/components/dist/utilities/Notifier.js";
6
+ import { ScreenObserver as c } from "./internals/ScreenObserver.js";
7
7
  class o {
8
8
  // private 생성자로 외부에서 인스턴스 생성 방지
9
9
  constructor() {
10
- this.handleWindowResize = (t) => {
11
- const e = window.innerWidth, [i, a] = this._config?.layout.breakpoints || [768, 1024];
12
- l(() => {
13
- e < i ? s.set("small") : e < a ? s.set("medium") : s.set("large");
14
- });
15
- };
16
10
  }
17
11
  /** 싱글톤 인스턴스 반환 */
18
12
  static get instance() {
@@ -26,24 +20,30 @@ class o {
26
20
  get router() {
27
21
  return this._router;
28
22
  }
23
+ /** 화면 크기 반환 */
24
+ get screen() {
25
+ return this._screen?.get();
26
+ }
29
27
  /** 스타일 테마 관리 유틸리티 객체 반환 */
30
28
  get theme() {
31
- return u;
29
+ return s;
32
30
  }
33
31
  /** 다국어 로컬라이저(i18next) 반환 */
34
- get localizer() {
35
- return n;
32
+ get i18n() {
33
+ return r;
36
34
  }
37
35
  /** 앱 로드 및 초기화 */
38
36
  async load(t) {
39
- if (this.unload(), this._config = t, await u.init(t.theme), t.localization) {
40
- for (const i of t.localization.plugins || [])
41
- n.use(i);
42
- await n.init(t.localization);
37
+ if (this.unload(), this._config = t, await s.init(t.theme), t.iconBasepath && h(t.iconBasepath), t.i18n) {
38
+ for (const i of t.i18n.plugins || [])
39
+ r.use(i);
40
+ await r.init(t.i18n);
43
41
  }
44
- window.addEventListener("resize", this.handleWindowResize), this.handleWindowResize(new Event("resize"));
45
42
  const e = t.root || document.body;
46
- this._layout = await this.createLayout(e, t.layout), this._router = new d({
43
+ this._layout = await this.createLayout(e, t.layout), this._screen = new c({
44
+ element: e,
45
+ breakpoints: t.layout.breakpoints || [768, 1024]
46
+ }), this._router = new u({
47
47
  root: this._layout,
48
48
  basepath: t.basepath,
49
49
  routes: t.routes,
@@ -52,7 +52,7 @@ class o {
52
52
  }
53
53
  /** 앱 언로드 */
54
54
  unload() {
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);
55
+ this._screen && (this._screen.destroy(), this._screen = void 0), this._layout && (this._layout.remove(), this._layout = void 0), this._router && (this._router.destroy(), this._router = void 0), this._config && (this._config = void 0);
56
56
  }
57
57
  /** 페이지 이동 */
58
58
  navigate(t) {
@@ -80,7 +80,7 @@ class o {
80
80
  }
81
81
  /** 알림 표시 */
82
82
  async notify(t, e, i) {
83
- await h.toast({
83
+ await y.toast({
84
84
  type: t,
85
85
  content: e,
86
86
  heading: i?.title,
@@ -91,13 +91,13 @@ class o {
91
91
  /** 레이아웃 생성 */
92
92
  async createLayout(t, e) {
93
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;
94
+ let i;
95
+ if (e.type === "sidebar") {
96
+ const { SidebarLayout: n } = await import("./layouts/SidebarLayout.js"), a = new n();
97
+ a.config = e, i = a;
98
98
  } else
99
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;
100
+ return t.appendChild(i), "updateComplete" in i && await i.updateComplete, i;
101
101
  }
102
102
  }
103
103
  const _ = o.instance;
@@ -1,7 +1,6 @@
1
1
  import { DirectiveResult } from 'lit/directive.js';
2
2
  import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
3
- import { ExtendedBaseElement } from '../internals/ExtendedBaseElement.js';
4
- import { StyleMap } from '../types/AppTypes.js';
3
+ import { StyledElement, StyleMap } from '../internals/StyledElement.js';
5
4
  /** 버튼 항목 부분 */
6
5
  type ElementParts = 'host' | 'base' | 'icon' | 'label';
7
6
  /** 버튼 항목 구성 */
@@ -15,7 +14,7 @@ export interface SidebarButtonConfig {
15
14
  /**
16
15
  * SidebarButton 컴포넌트는 사이드바 내의 버튼을 표시합니다.
17
16
  */
18
- export declare class SidebarButton extends ExtendedBaseElement<ElementParts> {
17
+ export declare class SidebarButton extends StyledElement<ElementParts> {
19
18
  static styles: import('lit').CSSResultGroup[];
20
19
  static dependencies: Record<string, typeof BaseElement>;
21
20
  /** 콤팩트 모드 여부 */
@@ -1,19 +1,19 @@
1
1
  import { html as c } from "lit";
2
2
  import { property as o } from "lit/decorators.js";
3
3
  import { UIcon as l } from "@iyulab/components/dist/components/icon/UIcon.component.js";
4
- import { ExtendedBaseElement as m } from "../internals/ExtendedBaseElement.js";
5
- import { styles as d } from "./SidebarButton.styles.js";
6
- var u = Object.defineProperty, n = (e, p, s, f) => {
4
+ import { StyledElement as m } from "../internals/StyledElement.js";
5
+ import { styles as u } from "./SidebarButton.styles.js";
6
+ var d = Object.defineProperty, p = (e, n, s, f) => {
7
7
  for (var t = void 0, r = e.length - 1, a; r >= 0; r--)
8
- (a = e[r]) && (t = a(p, s, t) || t);
9
- return t && u(p, s, t), t;
8
+ (a = e[r]) && (t = a(n, s, t) || t);
9
+ return t && d(n, 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, d];
16
+ this.styles = [super.styles, u];
17
17
  }
18
18
  static {
19
19
  this.dependencies = {
@@ -22,26 +22,24 @@ class i extends m {
22
22
  }
23
23
  render() {
24
24
  return c`
25
- <button part="base">
26
- <u-icon part="icon"
27
- ?hidden=${!this.icon}
25
+ <button part="base" ?compact=${this.compact}>
26
+ <u-icon part="icon" ?hidden=${!this.icon}
28
27
  .name=${this.icon}
29
28
  ></u-icon>
30
- <span part="label"
31
- ?hidden=${this.compact}>
29
+ <span part="label" ?hidden=${this.compact}>
32
30
  ${this.label}
33
31
  </span>
34
32
  </button>
35
33
  `;
36
34
  }
37
35
  }
38
- n([
36
+ p([
39
37
  o({ type: Boolean, reflect: !0 })
40
38
  ], i.prototype, "compact");
41
- n([
39
+ p([
42
40
  o({ type: String })
43
41
  ], i.prototype, "icon");
44
- n([
42
+ p([
45
43
  o({ type: String })
46
44
  ], i.prototype, "label");
47
45
  export {
@@ -3,23 +3,14 @@ const r = o`
3
3
  :host {
4
4
  display: block;
5
5
  width: 100%;
6
- padding: 8px 12px;
7
- font-size: 14px;
8
6
  color: var(--u-txt-color);
9
- background: transparent;
7
+ color: var(--u-neutral-800);
8
+ background-color: transparent;
10
9
  border: none;
11
10
  border-radius: 8px;
12
11
  transition: all 0.2s ease;
13
12
  cursor: pointer;
14
13
  }
15
- :host([comact]) {
16
- padding: 8px;
17
- }
18
- :host([compact]) button {
19
- width: 100%;
20
- justify-content: center;
21
- gap: 0;
22
- }
23
14
  :host(:hover) {
24
15
  color: var(--u-txt-color-hover);
25
16
  background-color: var(--u-bg-color-hover);
@@ -29,13 +20,19 @@ const r = o`
29
20
  }
30
21
 
31
22
  button {
32
- width: 100%;
33
23
  all: unset;
24
+ width: 100%;
34
25
  display: flex;
35
26
  flex-direction: row;
36
27
  align-items: center;
37
28
  justify-content: flex-start;
38
29
  gap: 12px;
30
+ padding: 8px 12px;
31
+ }
32
+ button[compact] {
33
+ justify-content: center;
34
+ gap: 0;
35
+ padding: 8px;
39
36
  }
40
37
  button:focus-visible {
41
38
  outline: 2px solid #6666ff;
@@ -43,17 +40,18 @@ const r = o`
43
40
  }
44
41
 
45
42
  u-icon {
46
- font-size: 20px;
47
- color: inherit;
48
43
  flex-shrink: 0;
44
+ color: inherit;
45
+ font-size: 20px;
49
46
  }
50
47
 
51
48
  span {
52
49
  flex: 1;
50
+ font-size: 14px;
53
51
  font-weight: 500;
54
- color: inherit;
55
- overflow: hidden;
52
+ line-height: 20px;
56
53
  white-space: nowrap;
54
+ overflow: hidden;
57
55
  text-overflow: ellipsis;
58
56
  }
59
57
  `;
@@ -1,9 +1,8 @@
1
1
  import { DirectiveResult } from 'lit/directive.js';
2
2
  import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
3
- import { StyleMap } from '../types/AppTypes.js';
4
- import { ExtendedBaseElement } from '../internals/ExtendedBaseElement.js';
3
+ import { StyledElement, StyleMap } from '../internals/StyledElement.js';
5
4
  import { SidebarLinkConfig } from './SidebarLink.js';
6
- type ElementParts = 'host' | 'container' | 'base' | 'icon' | 'label' | 'toggler' | 'items';
5
+ type ElementParts = 'host' | 'header' | 'icon' | 'label' | 'caret' | 'items';
7
6
  /** 그룹: 하위 링크들 묶음 */
8
7
  export interface SidebarGroupConfig {
9
8
  type: 'group';
@@ -17,11 +16,13 @@ export interface SidebarGroupConfig {
17
16
  /**
18
17
  * SidebarGroup 컴포넌트는 네비게이션 그룹 아이템을 표시합니다.
19
18
  */
20
- export declare class SidebarGroup extends ExtendedBaseElement<ElementParts> {
19
+ export declare class SidebarGroup extends StyledElement<ElementParts> {
21
20
  static styles: import('lit').CSSResultGroup[];
22
21
  static dependencies: Record<string, typeof BaseElement>;
23
22
  /** 콤팩트 모드 여부 */
24
23
  compact: boolean;
24
+ /** 선택된 상태 */
25
+ selected: boolean;
25
26
  /** collapsed 상태 */
26
27
  collapsed: boolean;
27
28
  /** 네비게이션 아이템 데이터 */
@@ -1,27 +1,22 @@
1
- import { html as c } from "lit";
2
- import { property as o } from "lit/decorators.js";
1
+ import { html as p } from "lit";
2
+ import { property as e } from "lit/decorators.js";
3
3
  import { UIcon as d } from "@iyulab/components/dist/components/icon/UIcon.component.js";
4
- import { app as m } from "../App.js";
5
- import { ExtendedBaseElement as u } from "../internals/ExtendedBaseElement.js";
6
- import { SidebarLink as h } from "./SidebarLink.js";
7
- import { styles as f } from "./SidebarGroup.styles.js";
8
- var y = Object.defineProperty, r = (i, n, e, l) => {
9
- for (var t = void 0, a = i.length - 1, p; a >= 0; a--)
10
- (p = i[a]) && (t = p(n, e, t) || t);
11
- return t && y(n, e, t), t;
4
+ import { StyledElement as h } from "../internals/StyledElement.js";
5
+ import { SidebarLink as m } from "./SidebarLink.js";
6
+ import { styles as u } from "./SidebarGroup.styles.js";
7
+ var f = Object.defineProperty, o = (i, l, c, a) => {
8
+ for (var t = void 0, r = i.length - 1, n; r >= 0; r--)
9
+ (n = i[r]) && (t = n(l, c, t) || t);
10
+ return t && f(l, c, t), t;
12
11
  };
13
- class s extends u {
12
+ class s extends h {
14
13
  constructor() {
15
- super(...arguments), this.compact = !1, this.collapsed = !0, this.handleButtonClick = (n) => {
16
- if (this.compact) {
17
- const e = this.shadowRoot?.querySelector("slot")?.assignedElements({ flatten: !0 }).find((l) => l instanceof h);
18
- m.navigate(e?.href || "/");
19
- } else
20
- this.collapsed = !this.collapsed;
14
+ super(...arguments), this.compact = !1, this.selected = !1, this.collapsed = !0, this.handleButtonClick = (l) => {
15
+ this.compact ? this.shadowRoot?.querySelector("slot")?.assignedElements({ flatten: !0 }).find((t) => t instanceof m)?.renderRoot.querySelector("u-link")?.click() : this.collapsed = !this.collapsed;
21
16
  };
22
17
  }
23
18
  static {
24
- this.styles = [super.styles, f];
19
+ this.styles = [super.styles, u];
25
20
  }
26
21
  static {
27
22
  this.dependencies = {
@@ -29,41 +24,45 @@ class s extends u {
29
24
  };
30
25
  }
31
26
  render() {
32
- return c`
33
- <div class="container" part="container">
34
- <button part="base"
35
- @click=${this.handleButtonClick}>
36
- <u-icon class="icon" part="icon"
37
- ?hidden=${!this.icon}
38
- .name=${this.icon}
39
- ></u-icon>
40
- <span class="label" part="label">
41
- ${this.label}
42
- </span>
43
- <u-icon class="toggler" part="toggler"
44
- lib="internal"
45
- name="chevron-down"
46
- ></u-icon>
47
- </button>
48
-
49
- <div class="items" part="items">
50
- <slot></slot>
51
- </div>
27
+ return p`
28
+ <button part="header"
29
+ ?compact=${this.compact}
30
+ ?selected=${this.selected}
31
+ @click=${this.handleButtonClick}>
32
+ <u-icon class="icon" part="icon" ?hidden=${!this.icon}
33
+ .name=${this.icon}
34
+ ></u-icon>
35
+ <span class="label" part="label" ?hidden=${this.compact}>
36
+ ${this.label}
37
+ </span>
38
+ <u-icon class="caret" part="caret" ?hidden=${this.compact}
39
+ ?collapsed=${this.collapsed}
40
+ lib="internal"
41
+ name="chevron-down"
42
+ ></u-icon>
43
+ </button>
44
+
45
+ <div class="items" part="items" ?hidden=${this.compact}
46
+ ?collapsed=${this.collapsed}>
47
+ <slot></slot>
52
48
  </div>
53
49
  `;
54
50
  }
55
51
  }
56
- r([
57
- o({ type: Boolean, reflect: !0 })
52
+ o([
53
+ e({ type: Boolean, reflect: !0 })
58
54
  ], s.prototype, "compact");
59
- r([
60
- o({ type: Boolean, reflect: !0 })
55
+ o([
56
+ e({ type: Boolean, reflect: !0 })
57
+ ], s.prototype, "selected");
58
+ o([
59
+ e({ type: Boolean, reflect: !0 })
61
60
  ], s.prototype, "collapsed");
62
- r([
63
- o({ type: String })
61
+ o([
62
+ e({ type: String })
64
63
  ], s.prototype, "icon");
65
- r([
66
- o({ type: String })
64
+ o([
65
+ e({ type: String })
67
66
  ], s.prototype, "label");
68
67
  export {
69
68
  s as SidebarGroup
@@ -1,93 +1,88 @@
1
1
  import { css as o } from "lit";
2
- const e = o`
2
+ const t = o`
3
3
  :host {
4
- display: block;
5
- }
6
- :host([compact]) button {
7
- justify-content: center;
8
- padding: 8px;
9
- }
10
- :host([compact]) .label {
11
- display: none;
12
- }
13
- :host([compact]) .toggler {
14
- display: none;
15
- }
16
- :host([compact]) .items {
17
- display: none;
18
- }
19
- :host(:not([compact])[collapsed]) .toggler {
20
- transform: rotate(-90deg);
21
- }
22
- :host(:not([compact])[collapsed]) .items {
23
- height: 0;
24
- margin-top: 0;
25
- opacity: 0;
26
- }
27
-
28
- .container {
29
4
  display: flex;
30
5
  flex-direction: column;
6
+ color: var(--u-neutral-800);
31
7
  }
32
8
 
33
9
  button {
34
10
  all: unset;
35
- position: relative;
11
+ width: 100%;
36
12
  display: flex;
37
13
  flex-direction: row;
38
- justify-content: space-between;
39
14
  align-items: center;
15
+ justify-content: space-between;
40
16
  gap: 12px;
41
- width: 100%;
42
17
  padding: 8px 12px;
43
- color: var(--u-txt-color);
44
- font-family: inherit;
45
- background: transparent;
18
+ background-color: transparent;
46
19
  border: none;
47
20
  border-radius: 8px;
48
21
  transition: all 0.2s ease;
49
22
  cursor: pointer;
50
23
  }
24
+ button[compact] {
25
+ justify-content: center;
26
+ gap: 0;
27
+ padding: 8px;
28
+ }
29
+ button[selected] {
30
+ color: var(--u-blue-700);
31
+ }
51
32
  button:hover {
52
- background-color: var(--u-bg-color-hover);
53
33
  color: var(--u-txt-color-hover);
34
+ background-color: var(--u-bg-color-hover);
35
+ }
36
+ button:active {
37
+ background-color: var(--u-bg-color-active);
38
+ }
39
+ button:focus-visible {
40
+ outline: 2px solid #6666ff;
41
+ outline-offset: 2px;
54
42
  }
55
43
 
56
44
  .icon {
57
- font-size: 20px;
58
- color: inherit;
59
45
  flex-shrink: 0;
46
+ color: inherit;
47
+ font-size: 20px;
60
48
  }
61
49
 
62
50
  .label {
63
51
  flex: 1;
64
- color: inherit;
65
52
  font-size: 14px;
66
- font-weight: 600;
67
53
  line-height: 20px;
68
- text-align: left;
54
+ font-weight: 600;
69
55
  overflow: hidden;
70
56
  white-space: nowrap;
71
57
  text-overflow: ellipsis;
72
58
  }
73
59
 
74
- .toggler {
60
+ .caret {
61
+ color: inherit;
75
62
  font-size: 16px !important;
76
63
  transition: transform 0.2s ease;
77
64
  }
65
+ .caret[collapsed] {
66
+ transform: rotate(-90deg);
67
+ }
78
68
 
79
69
  .items {
80
70
  display: flex;
81
71
  flex-direction: column;
82
- margin-left: 32px;
83
- margin-top: 4px;
84
72
  gap: 4px;
85
- overflow: hidden;
86
- transition: all 0.3s ease;
73
+ margin-top: 4px;
74
+ margin-left: 32px;
87
75
  border-left: 2px solid var(--u-border-color-weak);
88
76
  padding-left: 8px;
77
+ overflow: hidden;
78
+ transition: all 0.3s ease;
79
+ }
80
+ .items[collapsed] {
81
+ margin-top: 0;
82
+ height: 0;
83
+ opacity: 0;
89
84
  }
90
85
  `;
91
86
  export {
92
- e as styles
87
+ t as styles
93
88
  };
@@ -1,7 +1,6 @@
1
1
  import { DirectiveResult } from 'lit/directive.js';
2
2
  import { BaseElement } from '@iyulab/components/dist/components/BaseElement.js';
3
- import { ExtendedBaseElement } from '../internals/ExtendedBaseElement.js';
4
- import { StyleMap } from '../types/AppTypes.js';
3
+ import { StyledElement, StyleMap } from '../internals/StyledElement.js';
5
4
  type ElementParts = 'host' | 'base' | 'icon' | 'label';
6
5
  /** 링크 항목 디폴트 타입 */
7
6
  export interface SidebarLinkConfig {
@@ -16,7 +15,7 @@ export interface SidebarLinkConfig {
16
15
  * SidebarLink 컴포넌트는 계층형 네비게이션 아이템을 표시합니다.
17
16
  * 아이콘, 레이블, 하위 아이템을 지원합니다.
18
17
  */
19
- export declare class SidebarLink extends ExtendedBaseElement<ElementParts> {
18
+ export declare class SidebarLink extends StyledElement<ElementParts> {
20
19
  static styles: import('lit').CSSResultGroup[];
21
20
  static dependencies: Record<string, typeof BaseElement>;
22
21
  /** selected 상태 */
@@ -31,10 +30,6 @@ export declare class SidebarLink extends ExtendedBaseElement<ElementParts> {
31
30
  href?: string;
32
31
  /** 네비게이션 패턴 매칭 */
33
32
  pattern?: string | URLPattern;
34
- connectedCallback(): void;
35
- disconnectedCallback(): void;
36
33
  render(): import('lit-html').TemplateResult<1>;
37
- /** 라우트 변경 이벤트 핸들러 */
38
- private handleRouteBegin;
39
34
  }
40
35
  export {};