@cubit-ui/core 1.0.0 → 1.1.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.
package/dist/index.js CHANGED
@@ -1,56 +1,73 @@
1
- var k = Object.defineProperty;
2
- var w = (a, t, e) => t in a ? k(a, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : a[t] = e;
3
- var c = (a, t, e) => w(a, typeof t != "symbol" ? t + "" : t, e);
4
- class n extends HTMLElement {
1
+ var S = Object.defineProperty;
2
+ var L = (a, e, t) => e in a ? S(a, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[e] = t;
3
+ var c = (a, e, t) => L(a, typeof e != "symbol" ? e + "" : e, t);
4
+ class l extends HTMLElement {
5
5
  constructor() {
6
6
  super();
7
7
  c(this, "root");
8
+ c(this, "internals", null);
9
+ /** 상위 <fieldset disabled> 등 폼이 부여한 비활성 상태 (속성 disabled 와 별개) */
10
+ c(this, "formDisabled", !1);
8
11
  c(this, "lifecycleAbort", null);
9
- this.root = this.attachShadow({ mode: "open" });
12
+ if (this.root = this.attachShadow({ mode: "open" }), this.constructor.formAssociated && typeof this.attachInternals == "function")
13
+ try {
14
+ this.internals = this.attachInternals();
15
+ } catch {
16
+ this.internals = null;
17
+ }
18
+ }
19
+ /** 폼 제출 값 설정. null 이면 제출에서 제외된다. */
20
+ setFormValue(t) {
21
+ var r;
22
+ (r = this.internals) == null || r.setFormValue(t);
23
+ }
24
+ /** <fieldset disabled> 등으로 폼이 비활성/활성 상태를 바꿀 때 브라우저가 호출한다. */
25
+ formDisabledCallback(t) {
26
+ this.formDisabled = t, this.render();
10
27
  }
11
28
  connectedCallback() {
12
- var e;
13
- (e = this.lifecycleAbort) == null || e.abort(), this.lifecycleAbort = new AbortController(), this.render();
29
+ var t;
30
+ (t = this.lifecycleAbort) == null || t.abort(), this.lifecycleAbort = new AbortController(), this.render();
14
31
  }
15
32
  disconnectedCallback() {
16
- var e;
17
- (e = this.lifecycleAbort) == null || e.abort(), this.lifecycleAbort = null;
33
+ var t;
34
+ (t = this.lifecycleAbort) == null || t.abort(), this.lifecycleAbort = null;
18
35
  }
19
- listen(e, r) {
36
+ listen(t, r) {
20
37
  var i;
21
- this.addEventListener(e, r, { signal: (i = this.lifecycleAbort) == null ? void 0 : i.signal });
38
+ this.addEventListener(t, r, { signal: (i = this.lifecycleAbort) == null ? void 0 : i.signal });
22
39
  }
23
40
  /**
24
41
  * HTML 템플릿에 삽입되는 속성/텍스트 값 이스케이프 (속성 주입·XSS 방지)
25
42
  */
26
- escapeHtml(e) {
27
- return String(e ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
43
+ escapeHtml(t) {
44
+ return String(t ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
28
45
  }
29
46
  /**
30
47
  * href/src 용: javascript:, data:, vbscript: 스킴은 차단하고 이스케이프한다.
31
48
  */
32
- safeUrl(e) {
33
- const r = e.trim(), i = r.replace(/[\u0000-\u0020]/g, "").match(/^([a-z][a-z0-9+.-]*):/i);
49
+ safeUrl(t) {
50
+ const r = t.trim(), i = r.replace(/[\u0000-\u0020]/g, "").match(/^([a-z][a-z0-9+.-]*):/i);
34
51
  return i && !["http", "https", "mailto", "tel"].includes((i[1] ?? "").toLowerCase()) ? "" : this.escapeHtml(r);
35
52
  }
36
- attributeChangedCallback(e, r, i) {
53
+ attributeChangedCallback(t, r, i) {
37
54
  r !== i && this.render();
38
55
  }
39
56
  /**
40
57
  * shadow 경계를 넘어 bubbling된 클릭 등의 이벤트에서 실제 클릭 지점 원소를 얻는다.
41
58
  * (e.target은 shadow를 지나며 호스트로 retarget되므로 내부 클릭 판별에 쓸 수 없다)
42
59
  */
43
- composedTarget(e) {
44
- const r = e.composedPath();
60
+ composedTarget(t) {
61
+ const r = t.composedPath();
45
62
  for (const i of r)
46
63
  if (i instanceof HTMLElement) return i;
47
- return e.target;
64
+ return t.target;
48
65
  }
49
66
  /**
50
67
  * 커스텀 이벤트 발화 (bubbles: true, composed: true)
51
68
  */
52
- emit(e, r) {
53
- const i = new CustomEvent(e, {
69
+ emit(t, r) {
70
+ const i = new CustomEvent(t, {
54
71
  bubbles: !0,
55
72
  cancelable: !0,
56
73
  composed: !0,
@@ -61,21 +78,23 @@ class n extends HTMLElement {
61
78
  /**
62
79
  * 불리언 속성 헬퍼
63
80
  */
64
- getBooleanAttr(e) {
65
- return this.hasAttribute(e);
81
+ getBooleanAttr(t) {
82
+ return this.hasAttribute(t);
66
83
  }
67
- setBooleanAttr(e, r) {
68
- r ? this.setAttribute(e, "") : this.removeAttribute(e);
84
+ setBooleanAttr(t, r) {
85
+ r ? this.setAttribute(t, "") : this.removeAttribute(t);
69
86
  }
70
87
  }
88
+ /** 폼 참여(name/value 제출, reset, fieldset disabled)가 필요한 컴포넌트는 true 로 오버라이드 */
89
+ c(l, "formAssociated", !1);
71
90
  const g = class g {
72
- constructor(t) {
91
+ constructor(e) {
73
92
  c(this, "element");
74
93
  c(this, "firstFocusableEl", null);
75
94
  c(this, "lastFocusableEl", null);
76
95
  c(this, "handleKeyDownBound");
77
96
  c(this, "active", !1);
78
- this.element = t, this.handleKeyDownBound = this.handleKeyDown.bind(this);
97
+ this.element = e, this.handleKeyDownBound = this.handleKeyDown.bind(this);
79
98
  }
80
99
  activate() {
81
100
  this.updateFocusableElements(), this.firstFocusableEl && this.firstFocusableEl.focus(), document.addEventListener("keydown", this.handleKeyDownBound), this.active = !0;
@@ -84,18 +103,18 @@ const g = class g {
84
103
  this.active && (document.removeEventListener("keydown", this.handleKeyDownBound), this.active = !1);
85
104
  }
86
105
  updateFocusableElements() {
87
- const t = Array.from(
106
+ const e = Array.from(
88
107
  this.element.querySelectorAll(g.FOCUSABLE_SELECTORS)
89
- ).filter((e) => e.offsetParent !== null || e.offsetWidth > 0 || e.offsetHeight > 0);
90
- this.firstFocusableEl = t[0] || null, this.lastFocusableEl = t[t.length - 1] || null;
108
+ ).filter((t) => t.offsetParent !== null || t.offsetWidth > 0 || t.offsetHeight > 0);
109
+ this.firstFocusableEl = e[0] || null, this.lastFocusableEl = e[e.length - 1] || null;
91
110
  }
92
- handleKeyDown(t) {
93
- if (t.key === "Tab") {
111
+ handleKeyDown(e) {
112
+ if (e.key === "Tab") {
94
113
  if (this.updateFocusableElements(), !this.firstFocusableEl || !this.lastFocusableEl) {
95
- t.preventDefault();
114
+ e.preventDefault();
96
115
  return;
97
116
  }
98
- t.shiftKey ? (document.activeElement === this.firstFocusableEl || this.element === document.activeElement) && (this.lastFocusableEl.focus(), t.preventDefault()) : document.activeElement === this.lastFocusableEl && (this.firstFocusableEl.focus(), t.preventDefault());
117
+ e.shiftKey ? (document.activeElement === this.firstFocusableEl || this.element === document.activeElement) && (this.lastFocusableEl.focus(), e.preventDefault()) : document.activeElement === this.lastFocusableEl && (this.firstFocusableEl.focus(), e.preventDefault());
99
118
  }
100
119
  }
101
120
  };
@@ -109,8 +128,8 @@ c(g, "FOCUSABLE_SELECTORS", [
109
128
  "ui-button:not([disabled])",
110
129
  "ui-input:not([disabled])"
111
130
  ].join(","));
112
- let v = g;
113
- class A extends n {
131
+ let y = g;
132
+ class B extends l {
114
133
  static get observedAttributes() {
115
134
  return ["variant", "size", "disabled", "type", "aria-label"];
116
135
  }
@@ -123,14 +142,14 @@ class A extends n {
123
142
  get disabled() {
124
143
  return this.getBooleanAttr("disabled");
125
144
  }
126
- set disabled(t) {
127
- this.setBooleanAttr("disabled", t);
145
+ set disabled(e) {
146
+ this.setBooleanAttr("disabled", e);
128
147
  }
129
148
  get type() {
130
149
  return this.getAttribute("type") || "button";
131
150
  }
132
151
  render() {
133
- const t = this.variant, e = this.size, r = this.disabled, i = this.getAttribute("aria-label") || "";
152
+ const e = this.variant, t = this.size, r = this.disabled, i = this.getAttribute("aria-label") || "";
134
153
  this.root.innerHTML = `
135
154
  <style>
136
155
  :host {
@@ -233,7 +252,7 @@ class A extends n {
233
252
  }
234
253
  </style>
235
254
  <button
236
- class="${t} ${e}"
255
+ class="${e} ${t}"
237
256
  type="${this.type}"
238
257
  ${r ? "disabled" : ""}
239
258
  ${r ? 'aria-disabled="true"' : ""}
@@ -242,24 +261,28 @@ class A extends n {
242
261
  <slot></slot>
243
262
  </button>
244
263
  `;
245
- const s = this.root.querySelector("button");
246
- s && (s.onclick = (o) => {
264
+ const o = this.root.querySelector("button");
265
+ o && (o.onclick = (s) => {
247
266
  if (this.disabled) {
248
- o.preventDefault(), o.stopImmediatePropagation();
267
+ s.preventDefault(), s.stopImmediatePropagation();
249
268
  return;
250
269
  }
251
270
  if (this.type === "submit") {
252
- const l = this.closest("form");
253
- l && l.requestSubmit();
271
+ const n = this.closest("form");
272
+ n && n.requestSubmit();
254
273
  } else if (this.type === "reset") {
255
- const l = this.closest("form");
256
- l && l.reset();
274
+ const n = this.closest("form");
275
+ n && n.reset();
257
276
  }
258
277
  });
259
278
  }
260
279
  }
261
- customElements.get("ui-button") || customElements.define("ui-button", A);
262
- class z extends n {
280
+ customElements.get("ui-button") || customElements.define("ui-button", B);
281
+ class A extends l {
282
+ constructor() {
283
+ super(...arguments);
284
+ c(this, "defaultValue", "");
285
+ }
263
286
  static get observedAttributes() {
264
287
  return ["value", "placeholder", "type", "disabled", "readonly", "size", "invalid", "aria-label"];
265
288
  }
@@ -269,11 +292,11 @@ class z extends n {
269
292
  }
270
293
  set value(t) {
271
294
  this.setAttribute("value", t);
272
- const e = this.root.querySelector("input");
273
- e && (e.value = t);
295
+ const r = this.root.querySelector("input");
296
+ r && (r.value = t);
274
297
  }
275
298
  get disabled() {
276
- return this.getBooleanAttr("disabled");
299
+ return this.getBooleanAttr("disabled") || this.formDisabled;
277
300
  }
278
301
  set disabled(t) {
279
302
  this.setBooleanAttr("disabled", t);
@@ -288,26 +311,34 @@ class z extends n {
288
311
  * value 속성 변경은 내부 input 값을 제자리 갱신한다.
289
312
  * 전체 재렌더를 하면 input 요소가 교체되어 포커스·캐릿이 사라진다.
290
313
  */
291
- attributeChangedCallback(t, e, r) {
292
- if (t === "value" && e !== r) {
293
- const i = this.root.querySelector("input");
294
- if (i) {
295
- if (i.value !== r) {
296
- const s = i.selectionStart ?? null, o = i.selectionEnd ?? null;
297
- if (i.value = r ?? "", s !== null && o !== null && r !== null && s <= r.length)
314
+ attributeChangedCallback(t, r, i) {
315
+ if (t === "value" && r !== i) {
316
+ this.setFormValue(i ?? "");
317
+ const o = this.root.querySelector("input");
318
+ if (o) {
319
+ if (o.value !== i) {
320
+ const s = o.selectionStart ?? null, n = o.selectionEnd ?? null;
321
+ if (o.value = i ?? "", s !== null && n !== null && i !== null && s <= i.length)
298
322
  try {
299
- i.setSelectionRange(s, o);
323
+ o.setSelectionRange(s, n);
300
324
  } catch {
301
325
  }
302
326
  }
303
327
  return;
304
328
  }
305
329
  }
306
- super.attributeChangedCallback(t, e, r);
330
+ super.attributeChangedCallback(t, r, i);
331
+ }
332
+ connectedCallback() {
333
+ this.defaultValue = this.getAttribute("value") || "", super.connectedCallback();
334
+ }
335
+ /** <form>.reset() 시 초기값으로 복원 */
336
+ formResetCallback() {
337
+ this.value = this.defaultValue;
307
338
  }
308
339
  render() {
309
- const t = this.getAttribute("type") || "text", e = this.getAttribute("placeholder") || "", r = this.getAttribute("size") || "md", i = this.disabled, s = this.hasAttribute("readonly"), o = this.invalid, l = this.getAttribute("aria-label") || "", d = this.getAttribute("value") || "";
310
- this.root.innerHTML = `
340
+ const t = this.getAttribute("type") || "text", r = this.getAttribute("placeholder") || "", i = this.getAttribute("size") || "md", o = this.disabled, s = this.hasAttribute("readonly"), n = this.invalid, d = this.getAttribute("aria-label") || "", b = this.getAttribute("value") || "";
341
+ this.setFormValue(b), this.root.innerHTML = `
311
342
  <style>
312
343
  :host {
313
344
  display: block;
@@ -375,31 +406,36 @@ class z extends n {
375
406
  cursor: not-allowed;
376
407
  }
377
408
  </style>
378
- <div class="wrapper ${this.escapeHtml(r)} ${i ? "disabled" : ""} ${o ? "invalid" : ""}">
409
+ <div class="wrapper ${this.escapeHtml(i)} ${o ? "disabled" : ""} ${n ? "invalid" : ""}">
379
410
  <input
380
411
  type="${this.escapeHtml(t)}"
381
- placeholder="${this.escapeHtml(e)}"
382
- value="${this.escapeHtml(d)}"
383
- ${i ? "disabled" : ""}
412
+ placeholder="${this.escapeHtml(r)}"
413
+ value="${this.escapeHtml(b)}"
414
+ ${o ? "disabled" : ""}
384
415
  ${s ? "readonly" : ""}
385
- ${i ? 'aria-disabled="true"' : ""}
386
- ${o ? 'aria-invalid="true"' : 'aria-invalid="false"'}
387
- ${l ? `aria-label="${this.escapeHtml(l)}"` : ""}
416
+ ${o ? 'aria-disabled="true"' : ""}
417
+ ${n ? 'aria-invalid="true"' : 'aria-invalid="false"'}
418
+ ${d ? `aria-label="${this.escapeHtml(d)}"` : ""}
388
419
  />
389
420
  </div>
390
421
  `;
391
- const u = this.root.querySelector("input"), h = this.root.querySelector(".wrapper");
392
- u && h && (u.onfocus = () => h.classList.add("focused"), u.onblur = () => h.classList.remove("focused"), u.oninput = (b) => {
393
- const p = b.target.value;
394
- this.setAttribute("value", p), this.emit("input", { value: p });
395
- }, u.onchange = (b) => {
396
- const p = b.target.value;
397
- this.setAttribute("value", p), this.emit("change", { value: p });
422
+ const h = this.root.querySelector("input"), p = this.root.querySelector(".wrapper");
423
+ h && p && (h.onfocus = () => p.classList.add("focused"), h.onblur = () => p.classList.remove("focused"), h.oninput = (f) => {
424
+ const u = f.target.value;
425
+ this.setAttribute("value", u), this.emit("input", { value: u });
426
+ }, h.onchange = (f) => {
427
+ const u = f.target.value;
428
+ this.setAttribute("value", u), this.emit("change", { value: u });
398
429
  });
399
430
  }
400
431
  }
401
- customElements.get("ui-input") || customElements.define("ui-input", z);
402
- class E extends n {
432
+ c(A, "formAssociated", !0);
433
+ customElements.get("ui-input") || customElements.define("ui-input", A);
434
+ class z extends l {
435
+ constructor() {
436
+ super(...arguments);
437
+ c(this, "defaultChecked", !1);
438
+ }
403
439
  static get observedAttributes() {
404
440
  return ["checked", "disabled", "indeterminate", "name", "value", "aria-label"];
405
441
  }
@@ -416,13 +452,13 @@ class E extends n {
416
452
  this.setBooleanAttr("indeterminate", t);
417
453
  }
418
454
  get disabled() {
419
- return this.getBooleanAttr("disabled");
455
+ return this.getBooleanAttr("disabled") || this.formDisabled;
420
456
  }
421
457
  set disabled(t) {
422
458
  this.setBooleanAttr("disabled", t);
423
459
  }
424
460
  connectedCallback() {
425
- super.connectedCallback(), this.setAttribute("tabindex", this.disabled ? "-1" : "0"), this.setAttribute("role", "checkbox"), this.listen("keydown", this.handleKeyDown.bind(this)), this.listen("click", this.handleClick.bind(this));
461
+ this.defaultChecked = this.checked, super.connectedCallback(), this.setAttribute("tabindex", this.disabled ? "-1" : "0"), this.setAttribute("role", "checkbox"), this.listen("keydown", this.handleKeyDown.bind(this)), this.listen("click", this.handleClick.bind(this));
426
462
  }
427
463
  handleKeyDown(t) {
428
464
  this.disabled || (t.key === " " || t.key === "Enter") && (t.preventDefault(), this.toggle());
@@ -434,12 +470,16 @@ class E extends n {
434
470
  }
435
471
  this.toggle();
436
472
  }
473
+ /** <form>.reset() 시 초기 상태로 복원 */
474
+ formResetCallback() {
475
+ this.checked = this.defaultChecked;
476
+ }
437
477
  toggle() {
438
478
  this.disabled || (this.checked = !this.checked, this.indeterminate && (this.indeterminate = !1), this.setAttribute("aria-checked", String(this.checked)), this.emit("change", { checked: this.checked }));
439
479
  }
440
480
  render() {
441
- const t = this.checked, e = this.indeterminate, r = this.disabled;
442
- this.setAttribute("aria-checked", e ? "mixed" : String(t)), this.setAttribute("aria-disabled", String(r)), this.setAttribute("tabindex", r ? "-1" : "0"), this.root.innerHTML = `
481
+ const t = this.checked, r = this.indeterminate, i = this.disabled;
482
+ this.setFormValue(t ? this.getAttribute("value") ?? "on" : null), this.setAttribute("aria-checked", r ? "mixed" : String(t)), this.setAttribute("aria-disabled", String(i)), this.setAttribute("tabindex", i ? "-1" : "0"), this.root.innerHTML = `
443
483
  <style>
444
484
  :host {
445
485
  display: inline-flex;
@@ -492,7 +532,7 @@ class E extends n {
492
532
  line-height: var(--ui-line-height-normal, 1.5);
493
533
  }
494
534
  </style>
495
- <div class="box ${t ? "checked" : ""} ${e ? "indeterminate" : ""}">
535
+ <div class="box ${t ? "checked" : ""} ${r ? "indeterminate" : ""}">
496
536
  <svg class="icon icon-check" viewBox="0 0 16 16">
497
537
  <path d="M13.5 3.5L6.5 11.5L2.5 7.5" stroke="white" stroke-width="2" stroke-linecap="square" fill="none" />
498
538
  </svg>
@@ -504,8 +544,13 @@ class E extends n {
504
544
  `;
505
545
  }
506
546
  }
507
- customElements.get("ui-checkbox") || customElements.define("ui-checkbox", E);
508
- class x extends n {
547
+ c(z, "formAssociated", !0);
548
+ customElements.get("ui-checkbox") || customElements.define("ui-checkbox", z);
549
+ const m = class m extends l {
550
+ constructor() {
551
+ super(...arguments);
552
+ c(this, "defaultChecked", !1);
553
+ }
509
554
  static get observedAttributes() {
510
555
  return ["checked", "disabled", "name", "value"];
511
556
  }
@@ -516,7 +561,7 @@ class x extends n {
516
561
  this.setBooleanAttr("checked", t);
517
562
  }
518
563
  get disabled() {
519
- return this.getBooleanAttr("disabled");
564
+ return this.getBooleanAttr("disabled") || this.formDisabled;
520
565
  }
521
566
  set disabled(t) {
522
567
  this.setBooleanAttr("disabled", t);
@@ -528,7 +573,7 @@ class x extends n {
528
573
  return this.getAttribute("value") || "";
529
574
  }
530
575
  connectedCallback() {
531
- super.connectedCallback(), this.setAttribute("role", "radio"), this.setAttribute("tabindex", this.checked ? "0" : "-1"), this.listen("click", this.handleClick.bind(this)), this.listen("keydown", this.handleKeyDown.bind(this));
576
+ this.defaultChecked = this.checked, super.connectedCallback(), this.setAttribute("role", "radio"), this.setAttribute("tabindex", this.checked ? "0" : "-1"), this.listen("click", this.handleClick.bind(this)), this.listen("keydown", this.handleKeyDown.bind(this));
532
577
  }
533
578
  handleClick(t) {
534
579
  if (this.disabled) {
@@ -540,16 +585,20 @@ class x extends n {
540
585
  handleKeyDown(t) {
541
586
  this.disabled || (t.key === " " || t.key === "Enter") && (t.preventDefault(), this.select());
542
587
  }
588
+ /** <form>.reset() 시 초기 상태로 복원 */
589
+ formResetCallback() {
590
+ this.checked = this.defaultChecked;
591
+ }
543
592
  select() {
544
593
  if (this.disabled || this.checked) return;
545
594
  const t = this.name;
546
- t && this.getRootNode().querySelectorAll(`ui-radio[name="${CSS.escape(t)}"]`).forEach((i) => {
547
- i !== this && i instanceof x && (i.checked = !1, i.setAttribute("tabindex", "-1"));
595
+ t && this.getRootNode().querySelectorAll(`ui-radio[name="${CSS.escape(t)}"]`).forEach((o) => {
596
+ o !== this && o instanceof m && (o.checked = !1, o.setAttribute("tabindex", "-1"));
548
597
  }), this.checked = !0, this.setAttribute("tabindex", "0"), this.setAttribute("aria-checked", "true"), this.emit("change", { value: this.value, checked: !0 });
549
598
  }
550
599
  render() {
551
- const t = this.checked, e = this.disabled;
552
- this.setAttribute("aria-checked", String(t)), this.setAttribute("aria-disabled", String(e)), this.root.innerHTML = `
600
+ const t = this.checked, r = this.disabled;
601
+ this.setFormValue(t ? this.getAttribute("value") ?? "on" : null), this.setAttribute("aria-checked", String(t)), this.setAttribute("aria-disabled", String(r)), this.root.innerHTML = `
553
602
  <style>
554
603
  :host {
555
604
  display: inline-flex;
@@ -605,11 +654,17 @@ class x extends n {
605
654
  <span class="label"><slot></slot></span>
606
655
  `;
607
656
  }
608
- }
609
- customElements.get("ui-radio") || customElements.define("ui-radio", x);
610
- class C extends n {
657
+ };
658
+ c(m, "formAssociated", !0);
659
+ let k = m;
660
+ customElements.get("ui-radio") || customElements.define("ui-radio", k);
661
+ class C extends l {
662
+ constructor() {
663
+ super(...arguments);
664
+ c(this, "defaultChecked", !1);
665
+ }
611
666
  static get observedAttributes() {
612
- return ["checked", "disabled", "aria-label"];
667
+ return ["checked", "disabled", "aria-label", "value"];
613
668
  }
614
669
  get checked() {
615
670
  return this.getBooleanAttr("checked");
@@ -618,13 +673,13 @@ class C extends n {
618
673
  this.setBooleanAttr("checked", t);
619
674
  }
620
675
  get disabled() {
621
- return this.getBooleanAttr("disabled");
676
+ return this.getBooleanAttr("disabled") || this.formDisabled;
622
677
  }
623
678
  set disabled(t) {
624
679
  this.setBooleanAttr("disabled", t);
625
680
  }
626
681
  connectedCallback() {
627
- super.connectedCallback(), this.setAttribute("role", "switch"), this.setAttribute("tabindex", this.disabled ? "-1" : "0"), this.listen("click", this.handleClick.bind(this)), this.listen("keydown", this.handleKeyDown.bind(this));
682
+ this.defaultChecked = this.checked, super.connectedCallback(), this.setAttribute("role", "switch"), this.setAttribute("tabindex", this.disabled ? "-1" : "0"), this.listen("click", this.handleClick.bind(this)), this.listen("keydown", this.handleKeyDown.bind(this));
628
683
  }
629
684
  handleClick(t) {
630
685
  if (this.disabled) {
@@ -636,12 +691,16 @@ class C extends n {
636
691
  handleKeyDown(t) {
637
692
  this.disabled || (t.key === " " || t.key === "Enter") && (t.preventDefault(), this.toggle());
638
693
  }
694
+ /** <form>.reset() 시 초기 상태로 복원 */
695
+ formResetCallback() {
696
+ this.checked = this.defaultChecked;
697
+ }
639
698
  toggle() {
640
699
  this.disabled || (this.checked = !this.checked, this.setAttribute("aria-checked", String(this.checked)), this.emit("change", { checked: this.checked }));
641
700
  }
642
701
  render() {
643
- const t = this.checked, e = this.disabled;
644
- this.setAttribute("aria-checked", String(t)), this.setAttribute("aria-disabled", String(e)), this.setAttribute("tabindex", e ? "-1" : "0"), this.root.innerHTML = `
702
+ const t = this.checked, r = this.disabled;
703
+ this.setFormValue(t ? this.getAttribute("value") ?? "on" : null), this.setAttribute("aria-checked", String(t)), this.setAttribute("aria-disabled", String(r)), this.setAttribute("tabindex", r ? "-1" : "0"), this.root.innerHTML = `
645
704
  <style>
646
705
  :host {
647
706
  display: inline-flex;
@@ -702,8 +761,9 @@ class C extends n {
702
761
  `;
703
762
  }
704
763
  }
764
+ c(C, "formAssociated", !0);
705
765
  customElements.get("ui-switch") || customElements.define("ui-switch", C);
706
- class $ extends n {
766
+ class T extends l {
707
767
  constructor() {
708
768
  super();
709
769
  c(this, "_isOpen", !1);
@@ -718,14 +778,14 @@ class $ extends n {
718
778
  get value() {
719
779
  return this._selectedValue || this.getAttribute("value") || "";
720
780
  }
721
- set value(e) {
722
- this._selectedValue = e, this.setAttribute("value", e), this.updateSelectedLabel(), this.render();
781
+ set value(t) {
782
+ this._selectedValue = t, this.setAttribute("value", t), this.updateSelectedLabel(), this.render();
723
783
  }
724
784
  get disabled() {
725
785
  return this.getBooleanAttr("disabled");
726
786
  }
727
- set disabled(e) {
728
- this.setBooleanAttr("disabled", e);
787
+ set disabled(t) {
788
+ this.setBooleanAttr("disabled", t);
729
789
  }
730
790
  connectedCallback() {
731
791
  super.connectedCallback(), this._selectedValue = this.getAttribute("value") || "", this.updateSelectedLabel(), document.addEventListener("click", this.handleDocumentClickBound), this.listen("keydown", this.handleKeyDown.bind(this));
@@ -733,11 +793,11 @@ class $ extends n {
733
793
  disconnectedCallback() {
734
794
  super.disconnectedCallback(), document.removeEventListener("click", this.handleDocumentClickBound);
735
795
  }
736
- handleDocumentClick(e) {
737
- !this.contains(e.target) && !this.root.contains(e.target) && this.close();
796
+ handleDocumentClick(t) {
797
+ !this.contains(t.target) && !this.root.contains(t.target) && this.close();
738
798
  }
739
- handleKeyDown(e) {
740
- this.disabled || (e.key === " " || e.key === "Enter" ? (e.preventDefault(), this.toggle()) : e.key === "Escape" && this._isOpen && (e.preventDefault(), this.close()));
799
+ handleKeyDown(t) {
800
+ this.disabled || (t.key === " " || t.key === "Enter" ? (t.preventDefault(), this.toggle()) : t.key === "Escape" && this._isOpen && (t.preventDefault(), this.close()));
741
801
  }
742
802
  toggle() {
743
803
  this.disabled || (this._isOpen ? this.close() : this.open());
@@ -753,7 +813,7 @@ class $ extends n {
753
813
  r ? this._selectedLabel = r.textContent || "" : this._selectedLabel = "";
754
814
  }
755
815
  render() {
756
- const e = this.disabled, r = this.getAttribute("placeholder") || "선택하세요", i = this._selectedLabel || r, s = this._isOpen, o = this.getAttribute("size") || "md";
816
+ const t = this.disabled, r = this.getAttribute("placeholder") || "선택하세요", i = this._selectedLabel || r, o = this._isOpen, s = this.getAttribute("size") || "md";
757
817
  this.root.innerHTML = `
758
818
  <style>
759
819
  :host {
@@ -812,7 +872,7 @@ class $ extends n {
812
872
  border-radius: var(--ui-radius-sm, 1px);
813
873
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
814
874
  z-index: 1000;
815
- display: ${s ? "block" : "none"};
875
+ display: ${o ? "block" : "none"};
816
876
  max-height: 200px;
817
877
  overflow-y: auto;
818
878
  }
@@ -827,10 +887,10 @@ class $ extends n {
827
887
  }
828
888
  </style>
829
889
  <div
830
- class="trigger ${o} ${s ? "open" : ""} ${e ? "disabled" : ""}"
831
- tabindex="${e ? "-1" : "0"}"
890
+ class="trigger ${s} ${o ? "open" : ""} ${t ? "disabled" : ""}"
891
+ tabindex="${t ? "-1" : "0"}"
832
892
  role="combobox"
833
- aria-expanded="${s}"
893
+ aria-expanded="${o}"
834
894
  aria-haspopup="listbox"
835
895
  >
836
896
  <span>${this.escapeHtml(i)}</span>
@@ -842,26 +902,26 @@ class $ extends n {
842
902
  <slot></slot>
843
903
  </div>
844
904
  `;
845
- const l = this.root.querySelector(".trigger");
846
- l && l.addEventListener("click", () => this.toggle());
905
+ const n = this.root.querySelector(".trigger");
906
+ n && n.addEventListener("click", () => this.toggle());
847
907
  const d = this.root.querySelector("slot");
848
- d && d.addEventListener("click", (u) => {
849
- const h = this.composedTarget(u).closest("ui-option");
908
+ d && d.addEventListener("click", (b) => {
909
+ const h = this.composedTarget(b).closest("ui-option");
850
910
  if (h) {
851
- const b = h.getAttribute("value") || "";
852
- this.value = b, this.close(), this.emit("change", { value: b });
911
+ const p = h.getAttribute("value") || "";
912
+ this.value = p, this.close(), this.emit("change", { value: p });
853
913
  }
854
914
  });
855
915
  }
856
916
  }
857
- class L extends HTMLElement {
917
+ class H extends HTMLElement {
858
918
  connectedCallback() {
859
919
  this.setAttribute("role", "option");
860
920
  }
861
921
  }
862
- customElements.get("ui-select") || customElements.define("ui-select", $);
863
- customElements.get("ui-option") || customElements.define("ui-option", L);
864
- class S extends n {
922
+ customElements.get("ui-select") || customElements.define("ui-select", T);
923
+ customElements.get("ui-option") || customElements.define("ui-option", H);
924
+ class D extends l {
865
925
  constructor() {
866
926
  super();
867
927
  c(this, "focusTrap", null);
@@ -874,14 +934,14 @@ class S extends n {
874
934
  get open() {
875
935
  return this.getBooleanAttr("open");
876
936
  }
877
- set open(e) {
878
- this.setBooleanAttr("open", e);
937
+ set open(t) {
938
+ this.setBooleanAttr("open", t);
879
939
  }
880
940
  get title() {
881
941
  return this.getAttribute("title") || "";
882
942
  }
883
- set title(e) {
884
- this.setAttribute("title", e);
943
+ set title(t) {
944
+ this.setAttribute("title", t);
885
945
  }
886
946
  connectedCallback() {
887
947
  super.connectedCallback(), document.addEventListener("keydown", this.handleKeyDownBound), this.open && this.setupFocusTrap();
@@ -889,26 +949,26 @@ class S extends n {
889
949
  disconnectedCallback() {
890
950
  super.disconnectedCallback(), document.removeEventListener("keydown", this.handleKeyDownBound), this.focusTrap && this.focusTrap.deactivate();
891
951
  }
892
- attributeChangedCallback(e, r, i) {
893
- super.attributeChangedCallback(e, r, i), e === "open" && (this.open ? this.setupFocusTrap() : this.focusTrap && this.focusTrap.deactivate());
952
+ attributeChangedCallback(t, r, i) {
953
+ super.attributeChangedCallback(t, r, i), t === "open" && (this.open ? this.setupFocusTrap() : this.focusTrap && this.focusTrap.deactivate());
894
954
  }
895
955
  setupFocusTrap() {
896
956
  setTimeout(() => {
897
- this.focusTrap || (this.focusTrap = new v(this.root)), this.focusTrap.activate();
957
+ this.focusTrap || (this.focusTrap = new y(this.root)), this.focusTrap.activate();
898
958
  }, 0);
899
959
  }
900
- handleKeyDown(e) {
901
- this.open && e.key === "Escape" && (e.preventDefault(), this.close());
960
+ handleKeyDown(t) {
961
+ this.open && t.key === "Escape" && (t.preventDefault(), this.close());
902
962
  }
903
963
  close() {
904
964
  this.open = !1, this.emit("close");
905
965
  }
906
966
  render() {
907
- const e = this.open, r = this.title, i = this.getAttribute("aria-label") || r || "Dialog";
967
+ const t = this.open, r = this.title, i = this.getAttribute("aria-label") || r || "Dialog";
908
968
  this.root.innerHTML = `
909
969
  <style>
910
970
  :host {
911
- display: ${e ? "block" : "none"};
971
+ display: ${t ? "block" : "none"};
912
972
  font-family: var(--ui-font-family-base, sans-serif);
913
973
  }
914
974
  .backdrop {
@@ -1014,16 +1074,16 @@ class S extends n {
1014
1074
  </div>
1015
1075
  </div>
1016
1076
  `;
1017
- const s = this.root.querySelector("#backdrop"), o = this.root.querySelector("#closeBtn");
1018
- s && s.addEventListener("click", (l) => {
1019
- l.target === s && this.close();
1020
- }), o && o.addEventListener("click", () => {
1077
+ const o = this.root.querySelector("#backdrop"), s = this.root.querySelector("#closeBtn");
1078
+ o && o.addEventListener("click", (n) => {
1079
+ n.target === o && this.close();
1080
+ }), s && s.addEventListener("click", () => {
1021
1081
  this.close();
1022
1082
  });
1023
1083
  }
1024
1084
  }
1025
- customElements.get("ui-modal") || customElements.define("ui-modal", S);
1026
- class T extends n {
1085
+ customElements.get("ui-modal") || customElements.define("ui-modal", D);
1086
+ class M extends l {
1027
1087
  constructor() {
1028
1088
  super(...arguments);
1029
1089
  c(this, "timer", null);
@@ -1037,8 +1097,8 @@ class T extends n {
1037
1097
  get open() {
1038
1098
  return this.getBooleanAttr("open");
1039
1099
  }
1040
- set open(e) {
1041
- this.setBooleanAttr("open", e);
1100
+ set open(t) {
1101
+ this.setBooleanAttr("open", t);
1042
1102
  }
1043
1103
  get duration() {
1044
1104
  return parseInt(this.getAttribute("duration") || "4000", 10);
@@ -1049,8 +1109,8 @@ class T extends n {
1049
1109
  disconnectedCallback() {
1050
1110
  super.disconnectedCallback(), this.clearTimer();
1051
1111
  }
1052
- attributeChangedCallback(e, r, i) {
1053
- super.attributeChangedCallback(e, r, i), e === "open" && (this.open ? this.startTimer() : this.clearTimer());
1112
+ attributeChangedCallback(t, r, i) {
1113
+ super.attributeChangedCallback(t, r, i), t === "open" && (this.open ? this.startTimer() : this.clearTimer());
1054
1114
  }
1055
1115
  startTimer() {
1056
1116
  this.clearTimer(), this.duration > 0 && (this.timer = window.setTimeout(() => {
@@ -1064,7 +1124,7 @@ class T extends n {
1064
1124
  this.open = !1, this.clearTimer(), this.emit("close");
1065
1125
  }
1066
1126
  render() {
1067
- const e = this.variant, r = this.open;
1127
+ const t = this.variant, r = this.open;
1068
1128
  this.root.innerHTML = `
1069
1129
  <style>
1070
1130
  :host {
@@ -1128,7 +1188,7 @@ class T extends n {
1128
1188
  stroke-width: 2;
1129
1189
  }
1130
1190
  </style>
1131
- <div class="toast ${e}">
1191
+ <div class="toast ${t}">
1132
1192
  <div class="content"><slot></slot></div>
1133
1193
  <button class="close-btn" aria-label="Close toast" id="closeBtn">
1134
1194
  <svg class="close-icon" viewBox="0 0 16 16">
@@ -1141,38 +1201,38 @@ class T extends n {
1141
1201
  i && i.addEventListener("click", () => this.close());
1142
1202
  }
1143
1203
  }
1144
- customElements.get("ui-toast") || customElements.define("ui-toast", T);
1145
- class B extends n {
1204
+ customElements.get("ui-toast") || customElements.define("ui-toast", M);
1205
+ class q extends l {
1146
1206
  static get observedAttributes() {
1147
1207
  return ["content", "position"];
1148
1208
  }
1149
1209
  get content() {
1150
1210
  return this.getAttribute("content") || "";
1151
1211
  }
1152
- set content(t) {
1153
- this.setAttribute("content", t);
1212
+ set content(e) {
1213
+ this.setAttribute("content", e);
1154
1214
  }
1155
1215
  get position() {
1156
1216
  return this.getAttribute("position") || "top";
1157
1217
  }
1158
- set position(t) {
1159
- this.setAttribute("position", t);
1218
+ set position(e) {
1219
+ this.setAttribute("position", e);
1160
1220
  }
1161
1221
  connectedCallback() {
1162
- super.connectedCallback(), this.listen("mouseenter", this.show.bind(this)), this.listen("mouseleave", this.hide.bind(this)), this.listen("focusin", this.show.bind(this)), this.listen("focusout", this.hide.bind(this)), this.listen("keydown", (t) => {
1163
- t.key === "Escape" && this.hide();
1222
+ super.connectedCallback(), this.listen("mouseenter", this.show.bind(this)), this.listen("mouseleave", this.hide.bind(this)), this.listen("focusin", this.show.bind(this)), this.listen("focusout", this.hide.bind(this)), this.listen("keydown", (e) => {
1223
+ e.key === "Escape" && this.hide();
1164
1224
  });
1165
1225
  }
1166
1226
  show() {
1167
- const t = this.root.querySelector(".tooltip");
1168
- t && t.classList.add("visible");
1227
+ const e = this.root.querySelector(".tooltip");
1228
+ e && e.classList.add("visible");
1169
1229
  }
1170
1230
  hide() {
1171
- const t = this.root.querySelector(".tooltip");
1172
- t && t.classList.remove("visible");
1231
+ const e = this.root.querySelector(".tooltip");
1232
+ e && e.classList.remove("visible");
1173
1233
  }
1174
1234
  render() {
1175
- const t = this.content, e = this.position;
1235
+ const e = this.content, t = this.position;
1176
1236
  this.root.innerHTML = `
1177
1237
  <style>
1178
1238
  :host {
@@ -1223,50 +1283,50 @@ class B extends n {
1223
1283
  }
1224
1284
  </style>
1225
1285
  <slot></slot>
1226
- <div class="tooltip ${e}" role="tooltip" aria-hidden="true">
1227
- ${t}
1286
+ <div class="tooltip ${t}" role="tooltip" aria-hidden="true">
1287
+ ${e}
1228
1288
  </div>
1229
1289
  `;
1230
1290
  }
1231
1291
  }
1232
- customElements.get("ui-tooltip") || customElements.define("ui-tooltip", B);
1233
- class D extends n {
1292
+ customElements.get("ui-tooltip") || customElements.define("ui-tooltip", q);
1293
+ class I extends l {
1234
1294
  static get observedAttributes() {
1235
1295
  return ["value"];
1236
1296
  }
1237
1297
  get value() {
1238
1298
  return this.getAttribute("value") || "";
1239
1299
  }
1240
- set value(t) {
1241
- this.setAttribute("value", t), this.syncTabsAndPanels();
1300
+ set value(e) {
1301
+ this.setAttribute("value", e), this.syncTabsAndPanels();
1242
1302
  }
1243
1303
  connectedCallback() {
1244
1304
  super.connectedCallback(), this.listen("click", this.handleClick.bind(this)), this.listen("keydown", this.handleKeyDown.bind(this)), setTimeout(() => this.syncTabsAndPanels(), 0);
1245
1305
  }
1246
- handleClick(t) {
1247
- const e = t.target.closest("ui-tab");
1248
- if (e && !e.hasAttribute("disabled")) {
1249
- const r = e.getAttribute("value") || "";
1306
+ handleClick(e) {
1307
+ const t = e.target.closest("ui-tab");
1308
+ if (t && !t.hasAttribute("disabled")) {
1309
+ const r = t.getAttribute("value") || "";
1250
1310
  this.value = r, this.emit("change", { value: r });
1251
1311
  }
1252
1312
  }
1253
- handleKeyDown(t) {
1254
- const e = Array.from(this.querySelectorAll("ui-tab:not([disabled])"));
1255
- if (!e.length) return;
1256
- const r = e.findIndex((s) => s.getAttribute("value") === this.value);
1313
+ handleKeyDown(e) {
1314
+ const t = Array.from(this.querySelectorAll("ui-tab:not([disabled])"));
1315
+ if (!t.length) return;
1316
+ const r = t.findIndex((o) => o.getAttribute("value") === this.value);
1257
1317
  let i = r;
1258
- if (t.key === "ArrowRight" || t.key === "ArrowDown" ? (t.preventDefault(), i = (r + 1) % e.length) : t.key === "ArrowLeft" || t.key === "ArrowUp" ? (t.preventDefault(), i = (r - 1 + e.length) % e.length) : t.key === "Home" ? (t.preventDefault(), i = 0) : t.key === "End" && (t.preventDefault(), i = e.length - 1), i !== r && e[i]) {
1259
- const s = e[i], o = s.getAttribute("value") || "";
1260
- this.value = o, s.focus(), this.emit("change", { value: o });
1318
+ if (e.key === "ArrowRight" || e.key === "ArrowDown" ? (e.preventDefault(), i = (r + 1) % t.length) : e.key === "ArrowLeft" || e.key === "ArrowUp" ? (e.preventDefault(), i = (r - 1 + t.length) % t.length) : e.key === "Home" ? (e.preventDefault(), i = 0) : e.key === "End" && (e.preventDefault(), i = t.length - 1), i !== r && t[i]) {
1319
+ const o = t[i], s = o.getAttribute("value") || "";
1320
+ this.value = s, o.focus(), this.emit("change", { value: s });
1261
1321
  }
1262
1322
  }
1263
1323
  syncTabsAndPanels() {
1264
- const t = this.value, e = Array.from(this.querySelectorAll("ui-tab")), r = Array.from(this.querySelectorAll("ui-tab-panel"));
1265
- e.forEach((i) => {
1266
- const s = i.getAttribute("value") === t;
1267
- i.setAttribute("aria-selected", String(s)), i.setAttribute("tabindex", s ? "0" : "-1");
1324
+ const e = this.value, t = Array.from(this.querySelectorAll("ui-tab")), r = Array.from(this.querySelectorAll("ui-tab-panel"));
1325
+ t.forEach((i) => {
1326
+ const o = i.getAttribute("value") === e;
1327
+ i.setAttribute("aria-selected", String(o)), i.setAttribute("tabindex", o ? "0" : "-1");
1268
1328
  }), r.forEach((i) => {
1269
- i.getAttribute("value") === t ? (i.removeAttribute("hidden"), i.setAttribute("tabindex", "0")) : i.setAttribute("hidden", "");
1329
+ i.getAttribute("value") === e ? (i.removeAttribute("hidden"), i.setAttribute("tabindex", "0")) : i.setAttribute("hidden", "");
1270
1330
  });
1271
1331
  }
1272
1332
  render() {
@@ -1294,7 +1354,7 @@ class D extends n {
1294
1354
  `;
1295
1355
  }
1296
1356
  }
1297
- class H extends HTMLElement {
1357
+ class U extends HTMLElement {
1298
1358
  connectedCallback() {
1299
1359
  this.setAttribute("role", "tab"), this.hasAttribute("tabindex") || this.setAttribute("tabindex", "-1"), this.style.all = "unset", this.style.display = "inline-flex", this.style.alignItems = "center", this.style.padding = "8px 16px", this.style.cursor = "pointer", this.style.fontSize = "var(--ui-font-size-sm, 14px)", this.style.fontWeight = "var(--ui-font-weight-medium, 500)", this.style.borderBottom = "2px solid transparent", this.style.marginBottom = "-1px", this.style.userSelect = "none", this.render();
1300
1360
  }
@@ -1305,19 +1365,19 @@ class H extends HTMLElement {
1305
1365
  this.render();
1306
1366
  }
1307
1367
  render() {
1308
- const t = this.getAttribute("aria-selected") === "true", e = this.hasAttribute("disabled");
1309
- this.style.color = t ? "var(--ui-color-primary, #ff5500)" : "var(--ui-color-text-secondary, #616161)", this.style.borderBottomColor = t ? "var(--ui-color-primary, #ff5500)" : "transparent", this.style.opacity = e ? "0.5" : "1", this.style.pointerEvents = e ? "none" : "auto";
1368
+ const e = this.getAttribute("aria-selected") === "true", t = this.hasAttribute("disabled");
1369
+ this.style.color = e ? "var(--ui-color-primary, #ff5500)" : "var(--ui-color-text-secondary, #616161)", this.style.borderBottomColor = e ? "var(--ui-color-primary, #ff5500)" : "transparent", this.style.opacity = t ? "0.5" : "1", this.style.pointerEvents = t ? "none" : "auto";
1310
1370
  }
1311
1371
  }
1312
- class I extends HTMLElement {
1372
+ class F extends HTMLElement {
1313
1373
  connectedCallback() {
1314
1374
  this.setAttribute("role", "tabpanel");
1315
1375
  }
1316
1376
  }
1317
- customElements.get("ui-tabs") || customElements.define("ui-tabs", D);
1318
- customElements.get("ui-tab") || customElements.define("ui-tab", H);
1319
- customElements.get("ui-tab-panel") || customElements.define("ui-tab-panel", I);
1320
- class M extends n {
1377
+ customElements.get("ui-tabs") || customElements.define("ui-tabs", I);
1378
+ customElements.get("ui-tab") || customElements.define("ui-tab", U);
1379
+ customElements.get("ui-tab-panel") || customElements.define("ui-tab-panel", F);
1380
+ class j extends l {
1321
1381
  static get observedAttributes() {
1322
1382
  return ["variant", "size"];
1323
1383
  }
@@ -1328,7 +1388,7 @@ class M extends n {
1328
1388
  return this.getAttribute("size") || "md";
1329
1389
  }
1330
1390
  render() {
1331
- const t = this.variant, e = this.size;
1391
+ const e = this.variant, t = this.size;
1332
1392
  this.root.innerHTML = `
1333
1393
  <style>
1334
1394
  :host {
@@ -1393,14 +1453,14 @@ class M extends n {
1393
1453
  border: var(--ui-border-width-thin, 1px) solid var(--ui-color-error, #d32f2f);
1394
1454
  }
1395
1455
  </style>
1396
- <span class="badge ${t} ${e}">
1456
+ <span class="badge ${e} ${t}">
1397
1457
  <slot></slot>
1398
1458
  </span>
1399
1459
  `;
1400
1460
  }
1401
1461
  }
1402
- customElements.get("ui-badge") || customElements.define("ui-badge", M);
1403
- class q extends n {
1462
+ customElements.get("ui-badge") || customElements.define("ui-badge", j);
1463
+ class K extends l {
1404
1464
  static get observedAttributes() {
1405
1465
  return ["size", "aria-label"];
1406
1466
  }
@@ -1411,7 +1471,7 @@ class q extends n {
1411
1471
  super.connectedCallback(), this.setAttribute("role", "status"), this.hasAttribute("aria-label") || this.setAttribute("aria-label", "Loading");
1412
1472
  }
1413
1473
  render() {
1414
- const t = this.size;
1474
+ const e = this.size;
1415
1475
  this.root.innerHTML = `
1416
1476
  <style>
1417
1477
  :host {
@@ -1447,12 +1507,12 @@ class q extends n {
1447
1507
  100% { transform: rotate(360deg); }
1448
1508
  }
1449
1509
  </style>
1450
- <div class="spinner ${t}"></div>
1510
+ <div class="spinner ${e}"></div>
1451
1511
  `;
1452
1512
  }
1453
1513
  }
1454
- customElements.get("ui-spinner") || customElements.define("ui-spinner", q);
1455
- class U extends n {
1514
+ customElements.get("ui-spinner") || customElements.define("ui-spinner", K);
1515
+ class O extends l {
1456
1516
  static get observedAttributes() {
1457
1517
  return ["variant", "title", "closable", "aria-label"];
1458
1518
  }
@@ -1462,8 +1522,8 @@ class U extends n {
1462
1522
  get title() {
1463
1523
  return this.getAttribute("title") || "";
1464
1524
  }
1465
- set title(t) {
1466
- this.setAttribute("title", t);
1525
+ set title(e) {
1526
+ this.setAttribute("title", e);
1467
1527
  }
1468
1528
  get closable() {
1469
1529
  return this.getBooleanAttr("closable");
@@ -1475,7 +1535,7 @@ class U extends n {
1475
1535
  this.style.display = "none", this.emit("close");
1476
1536
  }
1477
1537
  render() {
1478
- const t = this.variant, e = this.title, r = this.closable;
1538
+ const e = this.variant, t = this.title, r = this.closable;
1479
1539
  this.root.innerHTML = `
1480
1540
  <style>
1481
1541
  :host {
@@ -1546,9 +1606,9 @@ class U extends n {
1546
1606
  stroke-width: 2;
1547
1607
  }
1548
1608
  </style>
1549
- <div class="alert ${t}">
1609
+ <div class="alert ${e}">
1550
1610
  <div class="content">
1551
- ${e ? `<div class="title">${this.escapeHtml(e)}</div>` : ""}
1611
+ ${t ? `<div class="title">${this.escapeHtml(t)}</div>` : ""}
1552
1612
  <slot></slot>
1553
1613
  </div>
1554
1614
  ${r ? `
@@ -1564,8 +1624,8 @@ class U extends n {
1564
1624
  i && i.addEventListener("click", () => this.close());
1565
1625
  }
1566
1626
  }
1567
- customElements.get("ui-alert") || customElements.define("ui-alert", U);
1568
- class O extends n {
1627
+ customElements.get("ui-alert") || customElements.define("ui-alert", O);
1628
+ class P extends l {
1569
1629
  static get observedAttributes() {
1570
1630
  return ["variant", "bordered"];
1571
1631
  }
@@ -1576,7 +1636,7 @@ class O extends n {
1576
1636
  return this.hasAttribute("bordered") || this.variant === "bordered";
1577
1637
  }
1578
1638
  render() {
1579
- const t = this.variant, e = this.bordered;
1639
+ const e = this.variant, t = this.bordered;
1580
1640
  this.root.innerHTML = `
1581
1641
  <style>
1582
1642
  :host {
@@ -1587,7 +1647,7 @@ class O extends n {
1587
1647
  .card {
1588
1648
  background-color: var(--ui-color-bg-surface, #ffffff);
1589
1649
  color: var(--ui-color-text-primary, #000000);
1590
- border: ${e ? "var(--ui-border-width-thin, 1px) solid var(--ui-color-border-strong, #000000)" : "var(--ui-border-width-thin, 1px) solid var(--ui-color-border, #e0e0e0)"};
1650
+ border: ${t ? "var(--ui-border-width-thin, 1px) solid var(--ui-color-border-strong, #000000)" : "var(--ui-border-width-thin, 1px) solid var(--ui-color-border, #e0e0e0)"};
1591
1651
  border-radius: var(--ui-radius-sm, 1px);
1592
1652
  box-sizing: border-box;
1593
1653
  overflow: hidden;
@@ -1616,7 +1676,7 @@ class O extends n {
1616
1676
  background-color: var(--ui-color-bg-subtle, #fafafa);
1617
1677
  }
1618
1678
  </style>
1619
- <div class="card ${t}">
1679
+ <div class="card ${e}">
1620
1680
  <slot name="header"></slot>
1621
1681
  <div class="content">
1622
1682
  <slot></slot>
@@ -1626,8 +1686,8 @@ class O extends n {
1626
1686
  `;
1627
1687
  }
1628
1688
  }
1629
- customElements.get("ui-card") || customElements.define("ui-card", O);
1630
- class _ extends n {
1689
+ customElements.get("ui-card") || customElements.define("ui-card", P);
1690
+ class _ extends l {
1631
1691
  static get observedAttributes() {
1632
1692
  return ["multiple"];
1633
1693
  }
@@ -1637,9 +1697,9 @@ class _ extends n {
1637
1697
  connectedCallback() {
1638
1698
  super.connectedCallback(), this.listen("toggle-item", this.handleItemToggle.bind(this));
1639
1699
  }
1640
- handleItemToggle(t) {
1641
- this.multiple || t.detail.open && Array.from(this.querySelectorAll("ui-accordion-item")).forEach((r) => {
1642
- r !== t.detail.item && r instanceof y && (r.open = !1);
1700
+ handleItemToggle(e) {
1701
+ this.multiple || e.detail.open && Array.from(this.querySelectorAll("ui-accordion-item")).forEach((r) => {
1702
+ r !== e.detail.item && r instanceof E && (r.open = !1);
1643
1703
  });
1644
1704
  }
1645
1705
  render() {
@@ -1657,21 +1717,21 @@ class _ extends n {
1657
1717
  `;
1658
1718
  }
1659
1719
  }
1660
- class y extends n {
1720
+ class E extends l {
1661
1721
  static get observedAttributes() {
1662
1722
  return ["open", "title", "disabled"];
1663
1723
  }
1664
1724
  get open() {
1665
1725
  return this.getBooleanAttr("open");
1666
1726
  }
1667
- set open(t) {
1668
- this.setBooleanAttr("open", t);
1727
+ set open(e) {
1728
+ this.setBooleanAttr("open", e);
1669
1729
  }
1670
1730
  get title() {
1671
1731
  return this.getAttribute("title") || "";
1672
1732
  }
1673
- set title(t) {
1674
- this.setAttribute("title", t);
1733
+ set title(e) {
1734
+ this.setAttribute("title", e);
1675
1735
  }
1676
1736
  get disabled() {
1677
1737
  return this.getBooleanAttr("disabled");
@@ -1680,7 +1740,7 @@ class y extends n {
1680
1740
  this.disabled || (this.open = !this.open, this.emit("toggle-item", { item: this, open: this.open }), this.emit("change", { open: this.open }));
1681
1741
  }
1682
1742
  render() {
1683
- const t = this.open, e = this.disabled, r = this.title;
1743
+ const e = this.open, t = this.disabled, r = this.title;
1684
1744
  this.root.innerHTML = `
1685
1745
  <style>
1686
1746
  :host {
@@ -1725,7 +1785,7 @@ class y extends n {
1725
1785
  transform: rotate(180deg);
1726
1786
  }
1727
1787
  .content {
1728
- display: ${t ? "block" : "none"};
1788
+ display: ${e ? "block" : "none"};
1729
1789
  padding: var(--ui-space-4, 16px);
1730
1790
  background-color: var(--ui-color-bg-subtle, #fafafa);
1731
1791
  font-size: var(--ui-font-size-sm, 14px);
@@ -1734,10 +1794,10 @@ class y extends n {
1734
1794
  }
1735
1795
  </style>
1736
1796
  <div
1737
- class="header ${t ? "open" : ""} ${e ? "disabled" : ""}"
1797
+ class="header ${e ? "open" : ""} ${t ? "disabled" : ""}"
1738
1798
  role="button"
1739
- tabindex="${e ? "-1" : "0"}"
1740
- aria-expanded="${t}"
1799
+ tabindex="${t ? "-1" : "0"}"
1800
+ aria-expanded="${e}"
1741
1801
  >
1742
1802
  <span>${this.escapeHtml(r)}</span>
1743
1803
  <svg class="icon" viewBox="0 0 16 16">
@@ -1749,15 +1809,15 @@ class y extends n {
1749
1809
  </div>
1750
1810
  `;
1751
1811
  const i = this.root.querySelector(".header");
1752
- i && (i.addEventListener("click", () => this.toggle()), i.addEventListener("keydown", (s) => {
1753
- const o = s;
1754
- (o.key === " " || o.key === "Enter") && (o.preventDefault(), this.toggle());
1812
+ i && (i.addEventListener("click", () => this.toggle()), i.addEventListener("keydown", (o) => {
1813
+ const s = o;
1814
+ (s.key === " " || s.key === "Enter") && (s.preventDefault(), this.toggle());
1755
1815
  }));
1756
1816
  }
1757
1817
  }
1758
1818
  customElements.get("ui-accordion") || customElements.define("ui-accordion", _);
1759
- customElements.get("ui-accordion-item") || customElements.define("ui-accordion-item", y);
1760
- class j extends n {
1819
+ customElements.get("ui-accordion-item") || customElements.define("ui-accordion-item", E);
1820
+ class R extends l {
1761
1821
  constructor() {
1762
1822
  super();
1763
1823
  c(this, "_isOpen", !1);
@@ -1770,8 +1830,8 @@ class j extends n {
1770
1830
  get open() {
1771
1831
  return this._isOpen;
1772
1832
  }
1773
- set open(e) {
1774
- this._isOpen = e, this.setBooleanAttr("open", e), this.render();
1833
+ set open(t) {
1834
+ this._isOpen = t, this.setBooleanAttr("open", t), this.render();
1775
1835
  }
1776
1836
  get placement() {
1777
1837
  return this.getAttribute("placement") || "bottom-start";
@@ -1785,11 +1845,11 @@ class j extends n {
1785
1845
  disconnectedCallback() {
1786
1846
  super.disconnectedCallback(), document.removeEventListener("click", this.handleDocClickBound);
1787
1847
  }
1788
- handleDocClick(e) {
1789
- !this.contains(e.target) && !this.root.contains(e.target) && this._isOpen && this.close();
1848
+ handleDocClick(t) {
1849
+ !this.contains(t.target) && !this.root.contains(t.target) && this._isOpen && this.close();
1790
1850
  }
1791
- handleKeyDown(e) {
1792
- e.key === "Escape" && this._isOpen && (e.preventDefault(), this.close());
1851
+ handleKeyDown(t) {
1852
+ t.key === "Escape" && this._isOpen && (t.preventDefault(), this.close());
1793
1853
  }
1794
1854
  toggle() {
1795
1855
  this.disabled || (this._isOpen ? this.close() : this.openDropdown());
@@ -1801,7 +1861,7 @@ class j extends n {
1801
1861
  this._isOpen && (this.open = !1, this.emit("close"));
1802
1862
  }
1803
1863
  render() {
1804
- const e = this._isOpen, r = this.placement;
1864
+ const t = this._isOpen, r = this.placement;
1805
1865
  this.root.innerHTML = `
1806
1866
  <style>
1807
1867
  :host {
@@ -1817,7 +1877,7 @@ class j extends n {
1817
1877
  border: var(--ui-border-width-thin, 1px) solid var(--ui-color-border-strong, #000000);
1818
1878
  border-radius: var(--ui-radius-sm, 1px);
1819
1879
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
1820
- display: ${e ? "block" : "none"};
1880
+ display: ${t ? "block" : "none"};
1821
1881
  min-width: 160px;
1822
1882
  box-sizing: border-box;
1823
1883
  padding: var(--ui-space-1, 4px) 0;
@@ -1845,38 +1905,38 @@ class j extends n {
1845
1905
  <div id="trigger-wrapper">
1846
1906
  <slot name="trigger"></slot>
1847
1907
  </div>
1848
- <div class="popover ${r}" role="menu" aria-hidden="${!e}">
1908
+ <div class="popover ${r}" role="menu" aria-hidden="${!t}">
1849
1909
  <slot></slot>
1850
1910
  </div>
1851
1911
  `;
1852
1912
  const i = this.root.querySelector("#trigger-wrapper");
1853
- i && i.addEventListener("click", (o) => {
1854
- o.stopPropagation(), this.toggle();
1913
+ i && i.addEventListener("click", (s) => {
1914
+ s.stopPropagation(), this.toggle();
1855
1915
  });
1856
1916
  }
1857
1917
  }
1858
- class K extends HTMLElement {
1918
+ class V extends HTMLElement {
1859
1919
  connectedCallback() {
1860
1920
  this.setAttribute("role", "menuitem"), this.setAttribute("tabindex", "0");
1861
1921
  }
1862
1922
  }
1863
- customElements.get("ui-dropdown") || customElements.define("ui-dropdown", j);
1864
- customElements.get("ui-dropdown-item") || customElements.define("ui-dropdown-item", K);
1865
- class F extends n {
1923
+ customElements.get("ui-dropdown") || customElements.define("ui-dropdown", R);
1924
+ customElements.get("ui-dropdown-item") || customElements.define("ui-dropdown-item", V);
1925
+ class N extends l {
1866
1926
  static get observedAttributes() {
1867
1927
  return ["value", "max", "size", "variant", "aria-label"];
1868
1928
  }
1869
1929
  get value() {
1870
1930
  return parseFloat(this.getAttribute("value") || "0");
1871
1931
  }
1872
- set value(t) {
1873
- this.setAttribute("value", String(t));
1932
+ set value(e) {
1933
+ this.setAttribute("value", String(e));
1874
1934
  }
1875
1935
  get max() {
1876
1936
  return parseFloat(this.getAttribute("max") || "100");
1877
1937
  }
1878
- set max(t) {
1879
- this.setAttribute("max", String(t));
1938
+ set max(e) {
1939
+ this.setAttribute("max", String(e));
1880
1940
  }
1881
1941
  get size() {
1882
1942
  return this.getAttribute("size") || "md";
@@ -1888,8 +1948,8 @@ class F extends n {
1888
1948
  super.connectedCallback(), this.setAttribute("role", "progressbar");
1889
1949
  }
1890
1950
  render() {
1891
- const t = Math.min(Math.max(this.value, 0), this.max), e = this.max > 0 ? t / this.max * 100 : 0, r = this.size, i = this.variant, s = this.getAttribute("aria-label") || "Progress";
1892
- this.setAttribute("aria-valuenow", String(t)), this.setAttribute("aria-valuemin", "0"), this.setAttribute("aria-valuemax", String(this.max)), this.setAttribute("aria-label", s), this.root.innerHTML = `
1951
+ const e = Math.min(Math.max(this.value, 0), this.max), t = this.max > 0 ? e / this.max * 100 : 0, r = this.size, i = this.variant, o = this.getAttribute("aria-label") || "Progress";
1952
+ this.setAttribute("aria-valuenow", String(e)), this.setAttribute("aria-valuemin", "0"), this.setAttribute("aria-valuemax", String(this.max)), this.setAttribute("aria-label", o), this.root.innerHTML = `
1893
1953
  <style>
1894
1954
  :host {
1895
1955
  display: block;
@@ -1913,7 +1973,7 @@ class F extends n {
1913
1973
 
1914
1974
  .bar {
1915
1975
  height: 100%;
1916
- width: ${e}%;
1976
+ width: ${t}%;
1917
1977
  transition: width var(--ui-transition-normal);
1918
1978
  }
1919
1979
 
@@ -1937,43 +1997,43 @@ class F extends n {
1937
1997
  `;
1938
1998
  }
1939
1999
  }
1940
- customElements.get("ui-progress") || customElements.define("ui-progress", F);
1941
- class P extends n {
2000
+ customElements.get("ui-progress") || customElements.define("ui-progress", N);
2001
+ class W extends l {
1942
2002
  static get observedAttributes() {
1943
2003
  return ["current", "total", "page-size"];
1944
2004
  }
1945
2005
  get current() {
1946
2006
  return parseInt(this.getAttribute("current") || "1", 10);
1947
2007
  }
1948
- set current(t) {
1949
- this.setAttribute("current", String(t)), this.render();
2008
+ set current(e) {
2009
+ this.setAttribute("current", String(e)), this.render();
1950
2010
  }
1951
2011
  get total() {
1952
2012
  return parseInt(this.getAttribute("total") || "1", 10);
1953
2013
  }
1954
- set total(t) {
1955
- this.setAttribute("total", String(t)), this.render();
2014
+ set total(e) {
2015
+ this.setAttribute("total", String(e)), this.render();
1956
2016
  }
1957
2017
  get totalPages() {
1958
- const t = parseInt(this.getAttribute("page-size") || "10", 10);
1959
- return Math.max(1, Math.ceil(this.total / t));
2018
+ const e = parseInt(this.getAttribute("page-size") || "10", 10);
2019
+ return Math.max(1, Math.ceil(this.total / e));
1960
2020
  }
1961
2021
  connectedCallback() {
1962
2022
  super.connectedCallback(), this.setAttribute("role", "navigation"), this.setAttribute("aria-label", "Pagination"), this.listen("click", this.handleClick.bind(this));
1963
2023
  }
1964
- handleClick(t) {
1965
- const e = this.composedTarget(t).closest("button");
1966
- if (!e || e.hasAttribute("disabled")) return;
1967
- const r = e.dataset.action, i = e.dataset.page;
2024
+ handleClick(e) {
2025
+ const t = this.composedTarget(e).closest("button");
2026
+ if (!t || t.hasAttribute("disabled")) return;
2027
+ const r = t.dataset.action, i = t.dataset.page;
1968
2028
  r === "prev" ? this.current > 1 && this.goToPage(this.current - 1) : r === "next" ? this.current < this.totalPages && this.goToPage(this.current + 1) : i && this.goToPage(parseInt(i, 10));
1969
2029
  }
1970
- goToPage(t) {
1971
- t !== this.current && (this.current = t, this.emit("change", { page: t }));
2030
+ goToPage(e) {
2031
+ e !== this.current && (this.current = e, this.emit("change", { page: e }));
1972
2032
  }
1973
2033
  render() {
1974
- const t = this.current, e = this.totalPages, r = [], i = Math.max(1, t - 2), s = Math.min(e, i + 4);
1975
- for (let o = i; o <= s; o++)
1976
- r.push(o);
2034
+ const e = this.current, t = this.totalPages, r = [], i = Math.max(1, e - 2), o = Math.min(t, i + 4);
2035
+ for (let s = i; s <= o; s++)
2036
+ r.push(s);
1977
2037
  this.root.innerHTML = `
1978
2038
  <style>
1979
2039
  :host {
@@ -2019,29 +2079,29 @@ class P extends n {
2019
2079
  cursor: not-allowed;
2020
2080
  }
2021
2081
  </style>
2022
- <button data-action="prev" ${t <= 1 ? "disabled" : ""} aria-label="Previous page">
2082
+ <button data-action="prev" ${e <= 1 ? "disabled" : ""} aria-label="Previous page">
2023
2083
  &lsaquo;
2024
2084
  </button>
2025
2085
  ${r.map(
2026
- (o) => `
2086
+ (s) => `
2027
2087
  <button
2028
- data-page="${o}"
2029
- class="${o === t ? "active" : ""}"
2030
- aria-current="${o === t ? "page" : "false"}"
2031
- aria-label="Page ${o}"
2088
+ data-page="${s}"
2089
+ class="${s === e ? "active" : ""}"
2090
+ aria-current="${s === e ? "page" : "false"}"
2091
+ aria-label="Page ${s}"
2032
2092
  >
2033
- ${o}
2093
+ ${s}
2034
2094
  </button>
2035
2095
  `
2036
2096
  ).join("")}
2037
- <button data-action="next" ${t >= e ? "disabled" : ""} aria-label="Next page">
2097
+ <button data-action="next" ${e >= t ? "disabled" : ""} aria-label="Next page">
2038
2098
  &rsaquo;
2039
2099
  </button>
2040
2100
  `;
2041
2101
  }
2042
2102
  }
2043
- customElements.get("ui-pagination") || customElements.define("ui-pagination", P);
2044
- const f = class f extends n {
2103
+ customElements.get("ui-pagination") || customElements.define("ui-pagination", W);
2104
+ const v = class v extends l {
2045
2105
  static get observedAttributes() {
2046
2106
  return ["striped", "bordered", "hoverable"];
2047
2107
  }
@@ -2051,10 +2111,10 @@ const f = class f extends n {
2051
2111
  * ui-table 태그로 스코프가 한정되므로 외부 영향은 없다.
2052
2112
  */
2053
2113
  ensureLightCss() {
2054
- if (f.lightCssInjected) return;
2055
- f.lightCssInjected = !0;
2056
- const t = document.createElement("style");
2057
- t.setAttribute("data-cubit-ui-table", ""), t.textContent = `
2114
+ if (v.lightCssInjected) return;
2115
+ v.lightCssInjected = !0;
2116
+ const e = document.createElement("style");
2117
+ e.setAttribute("data-cubit-ui-table", ""), e.textContent = `
2058
2118
  ui-table thead th,
2059
2119
  ui-table tbody td {
2060
2120
  padding: var(--ui-space-3, 12px) var(--ui-space-4, 16px);
@@ -2081,7 +2141,7 @@ const f = class f extends n {
2081
2141
  ui-table[hoverable] tbody tr:hover td {
2082
2142
  background-color: var(--ui-color-bg-secondary-subtle, #ffe4c9);
2083
2143
  }
2084
- `, document.head.appendChild(t);
2144
+ `, document.head.appendChild(e);
2085
2145
  }
2086
2146
  get striped() {
2087
2147
  return this.hasAttribute("striped");
@@ -2093,7 +2153,7 @@ const f = class f extends n {
2093
2153
  return this.hasAttribute("hoverable");
2094
2154
  }
2095
2155
  render() {
2096
- const t = this.striped, e = this.bordered, r = this.hoverable;
2156
+ const e = this.striped, t = this.bordered, r = this.hoverable;
2097
2157
  this.ensureLightCss(), this.root.innerHTML = `
2098
2158
  <style>
2099
2159
  :host {
@@ -2108,7 +2168,7 @@ const f = class f extends n {
2108
2168
  text-align: left;
2109
2169
  font-size: var(--ui-font-size-sm, 14px);
2110
2170
  color: var(--ui-color-text-primary, #000000);
2111
- border: ${e ? "var(--ui-border-width-thin, 1px) solid var(--ui-color-border-strong, #000000)" : "var(--ui-border-width-thin, 1px) solid var(--ui-color-border, #e0e0e0)"};
2171
+ border: ${t ? "var(--ui-border-width-thin, 1px) solid var(--ui-color-border-strong, #000000)" : "var(--ui-border-width-thin, 1px) solid var(--ui-color-border, #e0e0e0)"};
2112
2172
  }
2113
2173
  ::slotted(thead) {
2114
2174
  background-color: var(--ui-color-bg-subtle, #fafafa);
@@ -2119,12 +2179,12 @@ const f = class f extends n {
2119
2179
  padding: var(--ui-space-3, 12px) var(--ui-space-4, 16px);
2120
2180
  border-bottom: var(--ui-border-width-thin, 1px) solid var(--ui-color-border, #e0e0e0);
2121
2181
  }
2122
- ${e ? `
2182
+ ${t ? `
2123
2183
  ::slotted(th), ::slotted(td) {
2124
2184
  border: var(--ui-border-width-thin, 1px) solid var(--ui-color-border, #e0e0e0);
2125
2185
  }
2126
2186
  ` : ""}
2127
- ${t ? `
2187
+ ${e ? `
2128
2188
  ::slotted(tbody tr:nth-child(even)) {
2129
2189
  background-color: var(--ui-color-bg-subtle, #fafafa);
2130
2190
  }
@@ -2141,18 +2201,18 @@ const f = class f extends n {
2141
2201
  `;
2142
2202
  }
2143
2203
  };
2144
- c(f, "lightCssInjected", !1);
2145
- let m = f;
2146
- customElements.get("ui-table") || customElements.define("ui-table", m);
2147
- class N extends n {
2204
+ c(v, "lightCssInjected", !1);
2205
+ let w = v;
2206
+ customElements.get("ui-table") || customElements.define("ui-table", w);
2207
+ class X extends l {
2148
2208
  static get observedAttributes() {
2149
2209
  return ["src", "alt", "name", "size", "shape"];
2150
2210
  }
2151
2211
  get src() {
2152
2212
  return this.getAttribute("src") || "";
2153
2213
  }
2154
- set src(t) {
2155
- this.setAttribute("src", t);
2214
+ set src(e) {
2215
+ this.setAttribute("src", e);
2156
2216
  }
2157
2217
  get alt() {
2158
2218
  return this.getAttribute("alt") || "";
@@ -2166,13 +2226,13 @@ class N extends n {
2166
2226
  get shape() {
2167
2227
  return this.getAttribute("shape") || "circle";
2168
2228
  }
2169
- getInitials(t) {
2170
- if (!t) return "";
2171
- const e = t.trim().split(/\s+/);
2172
- return e.length >= 2 ? (e[0][0] || "") + (e[1][0] || "") : t.slice(0, 2).toUpperCase();
2229
+ getInitials(e) {
2230
+ if (!e) return "";
2231
+ const t = e.trim().split(/\s+/);
2232
+ return t.length >= 2 ? (t[0][0] || "") + (t[1][0] || "") : e.slice(0, 2).toUpperCase();
2173
2233
  }
2174
2234
  render() {
2175
- const t = this.src, e = this.alt || this.name, r = this.size, i = this.shape !== "square", s = this.getInitials(this.name);
2235
+ const e = this.src, t = this.alt || this.name, r = this.size, i = this.shape !== "square", o = this.getInitials(this.name);
2176
2236
  this.root.innerHTML = `
2177
2237
  <style>
2178
2238
  :host {
@@ -2216,14 +2276,14 @@ class N extends n {
2216
2276
  object-fit: cover;
2217
2277
  }
2218
2278
  </style>
2219
- <div class="avatar ${this.escapeHtml(r)}" role="img" aria-label="${this.escapeHtml(e)}">
2220
- ${t ? `<img src="${this.safeUrl(t)}" alt="${this.escapeHtml(e)}" onerror="this.style.display='none'; this.nextElementSibling.style.display='inline-flex';" /><span style="display:none;">${this.escapeHtml(s)}</span>` : `<span>${this.escapeHtml(s)}</span>`}
2279
+ <div class="avatar ${this.escapeHtml(r)}" role="img" aria-label="${this.escapeHtml(t)}">
2280
+ ${e ? `<img src="${this.safeUrl(e)}" alt="${this.escapeHtml(t)}" onerror="this.style.display='none'; this.nextElementSibling.style.display='inline-flex';" /><span style="display:none;">${this.escapeHtml(o)}</span>` : `<span>${this.escapeHtml(o)}</span>`}
2221
2281
  </div>
2222
2282
  `;
2223
2283
  }
2224
2284
  }
2225
- customElements.get("ui-avatar") || customElements.define("ui-avatar", N);
2226
- class R extends n {
2285
+ customElements.get("ui-avatar") || customElements.define("ui-avatar", X);
2286
+ class Y extends l {
2227
2287
  static get observedAttributes() {
2228
2288
  return ["separator", "aria-label"];
2229
2289
  }
@@ -2232,16 +2292,16 @@ class R extends n {
2232
2292
  }
2233
2293
  connectedCallback() {
2234
2294
  super.connectedCallback(), this.setAttribute("role", "navigation");
2235
- const t = this.getAttribute("aria-label") || "Breadcrumbs";
2236
- this.setAttribute("aria-label", t), this.syncSeparators();
2295
+ const e = this.getAttribute("aria-label") || "Breadcrumbs";
2296
+ this.setAttribute("aria-label", e), this.syncSeparators();
2237
2297
  }
2238
- attributeChangedCallback(t, e, r) {
2239
- super.attributeChangedCallback(t, e, r), t === "separator" && this.syncSeparators();
2298
+ attributeChangedCallback(e, t, r) {
2299
+ super.attributeChangedCallback(e, t, r), e === "separator" && this.syncSeparators();
2240
2300
  }
2241
2301
  syncSeparators() {
2242
- const t = Array.from(this.querySelectorAll("ui-breadcrumb-item"));
2243
- t.forEach((e, r) => {
2244
- r === t.length - 1 ? (e.setAttribute("current", "true"), e.removeAttribute("separator")) : (e.removeAttribute("current"), e.setAttribute("separator", this.separator));
2302
+ const e = Array.from(this.querySelectorAll("ui-breadcrumb-item"));
2303
+ e.forEach((t, r) => {
2304
+ r === e.length - 1 ? (t.setAttribute("current", "true"), t.removeAttribute("separator")) : (t.removeAttribute("current"), t.setAttribute("separator", this.separator));
2245
2305
  });
2246
2306
  }
2247
2307
  render() {
@@ -2265,11 +2325,11 @@ class R extends n {
2265
2325
  <slot></slot>
2266
2326
  </ol>
2267
2327
  `;
2268
- const t = this.root.querySelector("slot");
2269
- t && t.addEventListener("slotchange", () => this.syncSeparators());
2328
+ const e = this.root.querySelector("slot");
2329
+ e && e.addEventListener("slotchange", () => this.syncSeparators());
2270
2330
  }
2271
2331
  }
2272
- class V extends n {
2332
+ class G extends l {
2273
2333
  static get observedAttributes() {
2274
2334
  return ["href", "separator", "current"];
2275
2335
  }
@@ -2283,7 +2343,7 @@ class V extends n {
2283
2343
  return this.hasAttribute("current") || this.getAttribute("current") === "true";
2284
2344
  }
2285
2345
  render() {
2286
- const t = this.href, e = this.current, r = this.separator;
2346
+ const e = this.href, t = this.current, r = this.separator;
2287
2347
  this.root.innerHTML = `
2288
2348
  <style>
2289
2349
  :host {
@@ -2322,15 +2382,15 @@ class V extends n {
2322
2382
  }
2323
2383
  </style>
2324
2384
  <li role="listitem">
2325
- ${e ? '<span class="current" aria-current="page"><slot></slot></span>' : t ? `<a href="${this.safeUrl(t)}"><slot></slot></a>` : "<span><slot></slot></span>"}
2385
+ ${t ? '<span class="current" aria-current="page"><slot></slot></span>' : e ? `<a href="${this.safeUrl(e)}"><slot></slot></a>` : "<span><slot></slot></span>"}
2326
2386
  ${r ? `<span class="separator" aria-hidden="true">${this.escapeHtml(r)}</span>` : ""}
2327
2387
  </li>
2328
2388
  `;
2329
2389
  }
2330
2390
  }
2331
- customElements.get("ui-breadcrumbs") || customElements.define("ui-breadcrumbs", R);
2332
- customElements.get("ui-breadcrumb-item") || customElements.define("ui-breadcrumb-item", V);
2333
- class X extends n {
2391
+ customElements.get("ui-breadcrumbs") || customElements.define("ui-breadcrumbs", Y);
2392
+ customElements.get("ui-breadcrumb-item") || customElements.define("ui-breadcrumb-item", G);
2393
+ class J extends l {
2334
2394
  static get observedAttributes() {
2335
2395
  return ["open", "side", "title"];
2336
2396
  }
@@ -2340,8 +2400,8 @@ class X extends n {
2340
2400
  get open() {
2341
2401
  return this.getBooleanAttr("open");
2342
2402
  }
2343
- set open(t) {
2344
- this.setBooleanAttr("open", t);
2403
+ set open(e) {
2404
+ this.setBooleanAttr("open", e);
2345
2405
  }
2346
2406
  get side() {
2347
2407
  return this.getAttribute("side") || "right";
@@ -2349,21 +2409,21 @@ class X extends n {
2349
2409
  get title() {
2350
2410
  return this.getAttribute("title") || "";
2351
2411
  }
2352
- set title(t) {
2353
- this.setAttribute("title", t);
2412
+ set title(e) {
2413
+ this.setAttribute("title", e);
2354
2414
  }
2355
2415
  connectedCallback() {
2356
- super.connectedCallback(), this.hasAttribute("role") || this.setAttribute("role", "dialog"), this.setAttribute("aria-modal", "true"), this.listen("keydown", (t) => {
2357
- t.key === "Escape" && this.open && this.close();
2416
+ super.connectedCallback(), this.hasAttribute("role") || this.setAttribute("role", "dialog"), this.setAttribute("aria-modal", "true"), this.listen("keydown", (e) => {
2417
+ e.key === "Escape" && this.open && this.close();
2358
2418
  });
2359
2419
  }
2360
2420
  close() {
2361
2421
  this.open = !1, this.emit("close", {});
2362
2422
  }
2363
2423
  render() {
2364
- var o;
2365
- const t = this.open, e = this.side === "left" ? "left" : "right", r = this.title;
2366
- if (!t) {
2424
+ var s;
2425
+ const e = this.open, t = this.side === "left" ? "left" : "right", r = this.title;
2426
+ if (!e) {
2367
2427
  this.root.innerHTML = "";
2368
2428
  return;
2369
2429
  }
@@ -2406,7 +2466,7 @@ class X extends n {
2406
2466
  border-bottom-right-radius: var(--ui-radius-md, 12px);
2407
2467
  }
2408
2468
  @keyframes slide-in {
2409
- from { transform: translateX(${e === "left" ? "-24px" : "24px"}); opacity: 0.4; }
2469
+ from { transform: translateX(${t === "left" ? "-24px" : "24px"}); opacity: 0.4; }
2410
2470
  to { transform: translateX(0); opacity: 1; }
2411
2471
  }
2412
2472
  header.head {
@@ -2454,7 +2514,7 @@ class X extends n {
2454
2514
  }
2455
2515
  </style>
2456
2516
  <div class="backdrop" data-backdrop></div>
2457
- <div class="panel ${e}" part="panel">
2517
+ <div class="panel ${t}" part="panel">
2458
2518
  <header class="head">
2459
2519
  <h2>${this.escapeHtml(r)}</h2>
2460
2520
  <button class="close-btn" data-close aria-label="닫기">✕</button>
@@ -2464,14 +2524,14 @@ class X extends n {
2464
2524
  </div>
2465
2525
  `;
2466
2526
  const i = this.root.querySelector("footer.foot");
2467
- this.querySelector('[slot="footer"]') && (i.style.display = "block"), this.root.querySelector("[data-backdrop]").addEventListener("click", () => this.close()), (o = this.root.querySelector("[data-close]")) == null || o.addEventListener("click", () => this.close()), requestAnimationFrame(() => {
2468
- var l;
2469
- (l = this.root.querySelector(".close-btn")) == null || l.focus();
2527
+ this.querySelector('[slot="footer"]') && (i.style.display = "block"), this.root.querySelector("[data-backdrop]").addEventListener("click", () => this.close()), (s = this.root.querySelector("[data-close]")) == null || s.addEventListener("click", () => this.close()), requestAnimationFrame(() => {
2528
+ var n;
2529
+ (n = this.root.querySelector(".close-btn")) == null || n.focus();
2470
2530
  });
2471
2531
  }
2472
2532
  }
2473
- customElements.get("ui-drawer") || customElements.define("ui-drawer", X);
2474
- class W extends n {
2533
+ customElements.get("ui-drawer") || customElements.define("ui-drawer", J);
2534
+ class Q extends l {
2475
2535
  static get observedAttributes() {
2476
2536
  return ["variant", "width", "height", "lines"];
2477
2537
  }
@@ -2485,11 +2545,11 @@ class W extends n {
2485
2545
  return this.getAttribute("height") || "";
2486
2546
  }
2487
2547
  get lines() {
2488
- const t = parseInt(this.getAttribute("lines") || "1", 10);
2489
- return Number.isFinite(t) && t > 0 ? Math.min(t, 6) : 1;
2548
+ const e = parseInt(this.getAttribute("lines") || "1", 10);
2549
+ return Number.isFinite(e) && e > 0 ? Math.min(e, 6) : 1;
2490
2550
  }
2491
2551
  render() {
2492
- const t = this.variant, e = this.width ? `width: ${this.escape(this.width)};` : "", r = this.height ? `height: ${this.escape(this.height)};` : "", i = t === "text" && this.lines > 1 ? Array.from({ length: this.lines }, (s, o) => `<span class="shimmer bar" style="${o === this.lines - 1 ? "width: 70%;" : "width: 100%;"}"></span>`).join("") : `<span class="shimmer ${t === "circle" ? "circle" : t === "rect" ? "rect" : "bar"}" style="${e}${r}"></span>`;
2552
+ const e = this.variant, t = this.width ? `width: ${this.escape(this.width)};` : "", r = this.height ? `height: ${this.escape(this.height)};` : "", i = e === "text" && this.lines > 1 ? Array.from({ length: this.lines }, (o, s) => `<span class="shimmer bar" style="${s === this.lines - 1 ? "width: 70%;" : "width: 100%;"}"></span>`).join("") : `<span class="shimmer ${e === "circle" ? "circle" : e === "rect" ? "rect" : "bar"}" style="${t}${r}"></span>`;
2493
2553
  this.root.innerHTML = `
2494
2554
  <style>
2495
2555
  :host {
@@ -2526,12 +2586,12 @@ class W extends n {
2526
2586
  <div class="wrap" aria-hidden="true">${i}</div>
2527
2587
  `;
2528
2588
  }
2529
- escape(t) {
2530
- return t.replace(/["<>]/g, "");
2589
+ escape(e) {
2590
+ return e.replace(/["<>]/g, "");
2531
2591
  }
2532
2592
  }
2533
- customElements.get("ui-skeleton") || customElements.define("ui-skeleton", W);
2534
- class Y extends n {
2593
+ customElements.get("ui-skeleton") || customElements.define("ui-skeleton", Q);
2594
+ class Z extends l {
2535
2595
  static get observedAttributes() {
2536
2596
  return ["brand", "sticky"];
2537
2597
  }
@@ -2542,14 +2602,14 @@ class Y extends n {
2542
2602
  return this.getBooleanAttr("sticky");
2543
2603
  }
2544
2604
  render() {
2545
- const t = this.brand, e = this.sticky;
2605
+ const e = this.brand, t = this.sticky;
2546
2606
  this.root.innerHTML = `
2547
2607
  <style>
2548
2608
  :host {
2549
2609
  display: block;
2550
2610
  font-family: var(--ui-font-family-base, sans-serif);
2551
2611
  }
2552
- ${e ? ":host { position: sticky; top: 0; z-index: 500; }" : ""}
2612
+ ${t ? ":host { position: sticky; top: 0; z-index: 500; }" : ""}
2553
2613
  nav.bar {
2554
2614
  display: flex;
2555
2615
  align-items: center;
@@ -2610,27 +2670,545 @@ class Y extends n {
2610
2670
  }
2611
2671
  </style>
2612
2672
  <nav class="bar" aria-label="주요 탐색">
2613
- ${t ? `<span class="brand">${this.escapeHtml(t)}</span>` : ""}
2673
+ ${e ? `<span class="brand">${this.escapeHtml(e)}</span>` : ""}
2614
2674
  <div class="links"><slot></slot></div>
2615
2675
  <div class="actions"><slot name="actions"></slot></div>
2616
2676
  </nav>
2617
2677
  `;
2618
2678
  }
2619
2679
  }
2620
- customElements.get("ui-navbar") || customElements.define("ui-navbar", Y);
2621
- class G extends n {
2680
+ customElements.get("ui-navbar") || customElements.define("ui-navbar", Z);
2681
+ class $ extends l {
2682
+ constructor() {
2683
+ super(...arguments);
2684
+ c(this, "defaultValue", "");
2685
+ }
2686
+ static get observedAttributes() {
2687
+ return [
2688
+ "value",
2689
+ "placeholder",
2690
+ "rows",
2691
+ "maxlength",
2692
+ "resize",
2693
+ "size",
2694
+ "disabled",
2695
+ "readonly",
2696
+ "invalid",
2697
+ "aria-label"
2698
+ ];
2699
+ }
2700
+ get value() {
2701
+ const t = this.root.querySelector("textarea");
2702
+ return t ? t.value : this.getAttribute("value") || "";
2703
+ }
2704
+ set value(t) {
2705
+ this.setAttribute("value", t);
2706
+ const r = this.root.querySelector("textarea");
2707
+ r && (r.value = t);
2708
+ }
2709
+ get disabled() {
2710
+ return this.getBooleanAttr("disabled") || this.formDisabled;
2711
+ }
2712
+ set disabled(t) {
2713
+ this.setBooleanAttr("disabled", t);
2714
+ }
2715
+ get invalid() {
2716
+ return this.getBooleanAttr("invalid");
2717
+ }
2718
+ set invalid(t) {
2719
+ this.setBooleanAttr("invalid", t);
2720
+ }
2721
+ connectedCallback() {
2722
+ this.defaultValue = this.getAttribute("value") || "", super.connectedCallback();
2723
+ }
2724
+ /** <form>.reset() 시 초기값으로 복원 */
2725
+ formResetCallback() {
2726
+ this.value = this.defaultValue;
2727
+ }
2728
+ /** value 속성 변경은 내부 textarea 를 제자리 갱신해 포커스·캐럿을 보존한다. */
2729
+ attributeChangedCallback(t, r, i) {
2730
+ if (t === "value" && r !== i) {
2731
+ this.setFormValue(i ?? "");
2732
+ const o = this.root.querySelector("textarea");
2733
+ if (o) {
2734
+ if (o.value !== i) {
2735
+ const s = o.selectionStart, n = o.selectionEnd;
2736
+ if (o.value = i ?? "", i !== null && s <= i.length)
2737
+ try {
2738
+ o.setSelectionRange(s, Math.min(n, i.length));
2739
+ } catch {
2740
+ }
2741
+ }
2742
+ this.updateCounter();
2743
+ return;
2744
+ }
2745
+ }
2746
+ super.attributeChangedCallback(t, r, i);
2747
+ }
2748
+ updateCounter() {
2749
+ const t = this.root.querySelector(".counter"), r = this.root.querySelector("textarea"), i = this.getAttribute("maxlength");
2750
+ t && r && i && (t.textContent = `${r.value.length} / ${i}`);
2751
+ }
2752
+ render() {
2753
+ const t = ["sm", "md", "lg"].includes(this.getAttribute("size") || "") ? this.getAttribute("size") : "md", r = ["none", "vertical", "both"].includes(this.getAttribute("resize") || "") ? this.getAttribute("resize") : "vertical", i = Math.max(1, parseInt(this.getAttribute("rows") || "3", 10) || 3), o = parseInt(this.getAttribute("maxlength") || "", 10), s = Number.isFinite(o) && o > 0, n = this.disabled, d = this.hasAttribute("readonly"), b = this.invalid, h = this.getAttribute("aria-label") || "", p = this.getAttribute("placeholder") || "", f = this.getAttribute("value") || "";
2754
+ this.setFormValue(f), this.root.innerHTML = `
2755
+ <style>
2756
+ :host { display: block; font-family: var(--ui-font-family-base, sans-serif); }
2757
+ .wrapper {
2758
+ position: relative;
2759
+ box-sizing: border-box;
2760
+ background-color: var(--ui-color-bg-surface, #ffffff);
2761
+ border: var(--ui-border-width-thin, 1px) solid var(--ui-color-border, #e0e0e0);
2762
+ border-radius: var(--ui-radius-sm, 8px);
2763
+ transition: border-color var(--ui-transition-fast), box-shadow var(--ui-transition-fast);
2764
+ }
2765
+ .wrapper:hover:not(.disabled) { border-color: var(--ui-color-border-strong, #000000); }
2766
+ .wrapper.focused {
2767
+ border-color: var(--ui-color-primary, #ff5500);
2768
+ box-shadow: 0 0 0 1px var(--ui-color-primary, #ff5500);
2769
+ }
2770
+ .wrapper.invalid { border-color: var(--ui-color-error, #d32f2f); }
2771
+ .wrapper.invalid.focused { box-shadow: 0 0 0 1px var(--ui-color-error, #d32f2f); }
2772
+ .wrapper.disabled {
2773
+ background-color: var(--ui-color-bg-muted, #f5f5f5);
2774
+ opacity: 0.6;
2775
+ cursor: not-allowed;
2776
+ }
2777
+ textarea {
2778
+ all: unset;
2779
+ display: block;
2780
+ width: 100%;
2781
+ box-sizing: border-box;
2782
+ white-space: pre-wrap;
2783
+ overflow: auto;
2784
+ color: var(--ui-color-text-primary, #000000);
2785
+ font-family: inherit;
2786
+ line-height: var(--ui-line-height-normal, 1.5);
2787
+ resize: ${r};
2788
+ }
2789
+ textarea::placeholder { color: var(--ui-color-text-muted, #9e9e9e); }
2790
+ textarea:disabled { cursor: not-allowed; }
2791
+ .sm textarea { padding: var(--ui-space-1, 4px) var(--ui-space-2, 8px); font-size: var(--ui-font-size-xs, 12px); }
2792
+ .md textarea { padding: var(--ui-space-2, 8px) var(--ui-space-3, 12px); font-size: var(--ui-font-size-sm, 14px); }
2793
+ .lg textarea { padding: var(--ui-space-3, 12px) var(--ui-space-4, 16px); font-size: var(--ui-font-size-md, 16px); }
2794
+ .counter {
2795
+ text-align: right;
2796
+ padding: 0 var(--ui-space-3, 12px) var(--ui-space-1, 4px);
2797
+ font-size: var(--ui-font-size-xs, 12px);
2798
+ color: var(--ui-color-text-muted, #9e9e9e);
2799
+ }
2800
+ </style>
2801
+ <div class="wrapper ${t} ${n ? "disabled" : ""} ${b ? "invalid" : ""}">
2802
+ <textarea
2803
+ rows="${i}"
2804
+ placeholder="${this.escapeHtml(p)}"
2805
+ ${s ? `maxlength="${o}"` : ""}
2806
+ ${n ? "disabled" : ""}
2807
+ ${d ? "readonly" : ""}
2808
+ aria-invalid="${b ? "true" : "false"}"
2809
+ ${h ? `aria-label="${this.escapeHtml(h)}"` : ""}
2810
+ >
2811
+ ${this.escapeHtml(f)}</textarea>
2812
+ ${s ? `<div class="counter" aria-hidden="true">${f.length} / ${o}</div>` : ""}
2813
+ </div>
2814
+ `;
2815
+ const u = this.root.querySelector("textarea"), x = this.root.querySelector(".wrapper");
2816
+ u && x && (u.onfocus = () => x.classList.add("focused"), u.onblur = () => x.classList.remove("focused"), u.oninput = () => {
2817
+ this.setAttribute("value", u.value), this.emit("input", { value: u.value });
2818
+ }, u.onchange = () => {
2819
+ this.setAttribute("value", u.value), this.emit("change", { value: u.value });
2820
+ });
2821
+ }
2822
+ }
2823
+ c($, "formAssociated", !0);
2824
+ customElements.get("ui-textarea") || customElements.define("ui-textarea", $);
2825
+ class tt extends l {
2826
+ static get observedAttributes() {
2827
+ return ["heading", "description", "size", "variant"];
2828
+ }
2829
+ render() {
2830
+ const e = this.getAttribute("heading") || "", t = this.getAttribute("description") || "", r = this.getAttribute("size") === "sm" ? "sm" : "md", i = ["default", "error"].includes(this.getAttribute("variant") || "") ? this.getAttribute("variant") : "default";
2831
+ this.root.innerHTML = `
2832
+ <style>
2833
+ :host { display: block; font-family: var(--ui-font-family-base, sans-serif); }
2834
+ .box {
2835
+ display: flex;
2836
+ flex-direction: column;
2837
+ align-items: center;
2838
+ text-align: center;
2839
+ gap: var(--ui-space-2, 8px);
2840
+ box-sizing: border-box;
2841
+ padding: var(--ui-space-8, 32px) var(--ui-space-4, 16px);
2842
+ border: var(--ui-border-width-thin, 1px) dashed var(--ui-color-border, #e0e0e0);
2843
+ border-radius: var(--ui-radius-md, 12px);
2844
+ background-color: var(--ui-color-bg-subtle, #fafafa);
2845
+ color: var(--ui-color-text-secondary, #616161);
2846
+ }
2847
+ .box.sm { padding: var(--ui-space-4, 16px); gap: var(--ui-space-1, 4px); }
2848
+ .box.error { border-color: var(--ui-color-error, #d32f2f); background-color: var(--ui-color-error-bg, #fde8e8); }
2849
+ .icon { display: none; color: var(--ui-color-text-muted, #9e9e9e); font-size: 32px; line-height: 1; }
2850
+ .icon.has { display: block; }
2851
+ .heading {
2852
+ margin: 0;
2853
+ font-size: var(--ui-font-size-md, 16px);
2854
+ font-weight: var(--ui-font-weight-semibold, 600);
2855
+ color: var(--ui-color-text-primary, #000000);
2856
+ }
2857
+ .sm .heading { font-size: var(--ui-font-size-sm, 14px); }
2858
+ .desc { margin: 0; max-width: 42ch; font-size: var(--ui-font-size-sm, 14px); line-height: var(--ui-line-height-normal, 1.5); }
2859
+ .sm .desc { font-size: var(--ui-font-size-xs, 12px); }
2860
+ .actions { display: none; margin-top: var(--ui-space-2, 8px); gap: var(--ui-space-2, 8px); flex-wrap: wrap; justify-content: center; }
2861
+ .actions.has { display: flex; }
2862
+ </style>
2863
+ <div class="box ${r} ${i}">
2864
+ <div class="icon" aria-hidden="true"><slot name="icon"></slot></div>
2865
+ ${e ? `<h3 class="heading">${this.escapeHtml(e)}</h3>` : ""}
2866
+ ${t ? `<p class="desc">${this.escapeHtml(t)}</p>` : ""}
2867
+ <div class="actions"><slot></slot></div>
2868
+ </div>
2869
+ `;
2870
+ const o = (s, n) => {
2871
+ const d = this.root.querySelector(s ? `slot[name="${s}"]` : "slot:not([name])");
2872
+ if (!d || !n) return;
2873
+ const b = () => {
2874
+ n.classList.toggle("has", d.assignedNodes({ flatten: !0 }).some((h) => h.nodeType === 1 || (h.textContent || "").trim() !== ""));
2875
+ };
2876
+ d.addEventListener("slotchange", b), b();
2877
+ };
2878
+ o("icon", this.root.querySelector(".icon")), o(null, this.root.querySelector(".actions"));
2879
+ }
2880
+ }
2881
+ customElements.get("ui-empty-state") || customElements.define("ui-empty-state", tt);
2882
+ class et extends l {
2883
+ static get observedAttributes() {
2884
+ return ["value", "size", "disabled", "aria-label"];
2885
+ }
2886
+ get value() {
2887
+ return this.getAttribute("value") || "";
2888
+ }
2889
+ set value(e) {
2890
+ this.setAttribute("value", e);
2891
+ }
2892
+ get disabled() {
2893
+ return this.getBooleanAttr("disabled");
2894
+ }
2895
+ set disabled(e) {
2896
+ this.setBooleanAttr("disabled", e);
2897
+ }
2898
+ connectedCallback() {
2899
+ super.connectedCallback(), this.setAttribute("role", "radiogroup"), this.listen("click", this.handleClick.bind(this)), this.listen("keydown", this.handleKeyDown.bind(this)), this.refresh();
2900
+ }
2901
+ attributeChangedCallback(e, t, r) {
2902
+ super.attributeChangedCallback(e, t, r), this.refresh();
2903
+ }
2904
+ segments() {
2905
+ return Array.from(this.querySelectorAll("ui-segment"));
2906
+ }
2907
+ enabledSegments() {
2908
+ return this.segments().filter((e) => !e.hasAttribute("disabled") && !this.disabled);
2909
+ }
2910
+ select(e) {
2911
+ const t = e.getAttribute("value") || "";
2912
+ t !== this.value && (this.value = t, this.emit("change", { value: t }));
2913
+ }
2914
+ handleClick(e) {
2915
+ const t = e.target.closest("ui-segment");
2916
+ !t || t.hasAttribute("disabled") || this.disabled || this.select(t);
2917
+ }
2918
+ handleKeyDown(e) {
2919
+ const t = this.enabledSegments();
2920
+ if (!t.length) return;
2921
+ const r = t.findIndex((s) => s.getAttribute("value") === this.value);
2922
+ let i = r;
2923
+ if (e.key === "ArrowRight" || e.key === "ArrowDown") i = r < 0 ? 0 : (r + 1) % t.length;
2924
+ else if (e.key === "ArrowLeft" || e.key === "ArrowUp") i = r < 0 ? t.length - 1 : (r - 1 + t.length) % t.length;
2925
+ else if (e.key === "Home") i = 0;
2926
+ else if (e.key === "End") i = t.length - 1;
2927
+ else if ((e.key === " " || e.key === "Enter") && e.target.closest("ui-segment")) {
2928
+ e.preventDefault(), this.select(e.target.closest("ui-segment"));
2929
+ return;
2930
+ } else return;
2931
+ e.preventDefault();
2932
+ const o = t[i];
2933
+ o && (this.select(o), o.focus());
2934
+ }
2935
+ /** aria-checked / tabindex(roving) 를 자식 ui-segment 에 반영 (자식이 속성 변경 시에도 호출) */
2936
+ refresh() {
2937
+ const e = this.segments(), t = e.some((i) => i.getAttribute("value") === this.value && !i.hasAttribute("disabled"));
2938
+ let r = !1;
2939
+ e.forEach((i) => {
2940
+ const o = i.hasAttribute("disabled") || this.disabled, s = i.getAttribute("value") === this.value;
2941
+ i.setAttribute("aria-checked", String(s)), i.setAttribute("aria-disabled", String(o));
2942
+ let n = -1;
2943
+ !o && (s && t || !t && !r) && (n = 0, r = !0), i.setAttribute("tabindex", String(n));
2944
+ });
2945
+ }
2946
+ render() {
2947
+ var t;
2948
+ const e = ["sm", "md", "lg"].includes(this.getAttribute("size") || "") ? this.getAttribute("size") : "md";
2949
+ this.root.innerHTML = `
2950
+ <style>
2951
+ :host {
2952
+ display: inline-flex;
2953
+ box-sizing: border-box;
2954
+ padding: 2px;
2955
+ gap: 2px;
2956
+ background-color: var(--ui-color-bg-muted, #f5f5f5);
2957
+ border: var(--ui-border-width-thin, 1px) solid var(--ui-color-border, #e0e0e0);
2958
+ border-radius: var(--ui-radius-md, 12px);
2959
+ font-family: var(--ui-font-family-base, sans-serif);
2960
+ }
2961
+ :host([disabled]) { opacity: 0.5; }
2962
+ ::slotted(ui-segment) {
2963
+ display: inline-flex;
2964
+ align-items: center;
2965
+ justify-content: center;
2966
+ box-sizing: border-box;
2967
+ cursor: pointer;
2968
+ user-select: none;
2969
+ white-space: nowrap;
2970
+ font-weight: var(--ui-font-weight-medium, 500);
2971
+ color: var(--ui-color-text-secondary, #616161);
2972
+ border-radius: var(--ui-radius-sm, 8px);
2973
+ outline: none;
2974
+ transition: background-color var(--ui-transition-fast), color var(--ui-transition-fast);
2975
+ ${e === "sm" ? "padding: 2px 10px; font-size: var(--ui-font-size-xs, 12px);" : e === "lg" ? "padding: 8px 20px; font-size: var(--ui-font-size-md, 16px);" : "padding: 5px 14px; font-size: var(--ui-font-size-sm, 14px);"}
2976
+ }
2977
+ ::slotted(ui-segment:hover:not([aria-disabled="true"])) { color: var(--ui-color-text-primary, #000000); }
2978
+ ::slotted(ui-segment[aria-checked="true"]) {
2979
+ background-color: var(--ui-color-bg-surface, #ffffff);
2980
+ color: var(--ui-color-primary, #ff5500);
2981
+ box-shadow: 0 0 0 var(--ui-border-width-thin, 1px) var(--ui-color-primary, #ff5500);
2982
+ }
2983
+ ::slotted(ui-segment[aria-disabled="true"]) { opacity: 0.5; cursor: not-allowed; }
2984
+ ::slotted(ui-segment:focus-visible) {
2985
+ box-shadow: 0 0 0 2px var(--ui-color-bg-canvas, #ffffff), 0 0 0 4px var(--ui-color-focus-ring, #ff5500);
2986
+ }
2987
+ </style>
2988
+ <slot></slot>
2989
+ `, (t = this.root.querySelector("slot")) == null || t.addEventListener("slotchange", () => this.refresh());
2990
+ }
2991
+ }
2992
+ class it extends HTMLElement {
2993
+ connectedCallback() {
2994
+ var e;
2995
+ this.setAttribute("role", "radio"), this.hasAttribute("aria-checked") || this.setAttribute("aria-checked", "false"), this.hasAttribute("tabindex") || this.setAttribute("tabindex", "-1"), (e = this.closest("ui-segmented")) == null || e.refresh();
2996
+ }
2997
+ static get observedAttributes() {
2998
+ return ["value", "disabled"];
2999
+ }
3000
+ attributeChangedCallback() {
3001
+ var e;
3002
+ (e = this.closest("ui-segmented")) == null || e.refresh();
3003
+ }
3004
+ }
3005
+ customElements.get("ui-segmented") || customElements.define("ui-segmented", et);
3006
+ customElements.get("ui-segment") || customElements.define("ui-segment", it);
3007
+ class rt extends l {
3008
+ static get observedAttributes() {
3009
+ return ["current", "orientation", "aria-label"];
3010
+ }
3011
+ get current() {
3012
+ const e = parseInt(this.getAttribute("current") || "0", 10);
3013
+ return Number.isFinite(e) ? e : 0;
3014
+ }
3015
+ set current(e) {
3016
+ this.setAttribute("current", String(e));
3017
+ }
3018
+ connectedCallback() {
3019
+ super.connectedCallback(), this.setAttribute("role", "list"), this.refresh();
3020
+ }
3021
+ attributeChangedCallback(e, t, r) {
3022
+ super.attributeChangedCallback(e, t, r), this.refresh();
3023
+ }
3024
+ /** 자식 ui-step 의 상태·번호·마지막 여부를 갱신 (자식이 속성 변경 시에도 호출) */
3025
+ refresh() {
3026
+ const e = Array.from(this.querySelectorAll("ui-step")), t = this.current;
3027
+ e.forEach((r, i) => {
3028
+ const s = r.getAttribute("status") === "error" ? "error" : i < t ? "done" : i === t ? "active" : "pending";
3029
+ r.setAttribute("data-state", s), r.setAttribute("data-index", String(i + 1)), r.toggleAttribute("data-last", i === e.length - 1), r.toggleAttribute("data-vertical", this.getAttribute("orientation") === "vertical"), s === "active" ? r.setAttribute("aria-current", "step") : r.removeAttribute("aria-current");
3030
+ });
3031
+ }
3032
+ render() {
3033
+ var t;
3034
+ const e = this.getAttribute("orientation") === "vertical";
3035
+ this.root.innerHTML = `
3036
+ <style>
3037
+ :host {
3038
+ display: flex;
3039
+ flex-direction: ${e ? "column" : "row"};
3040
+ align-items: ${e ? "stretch" : "flex-start"};
3041
+ gap: 0;
3042
+ font-family: var(--ui-font-family-base, sans-serif);
3043
+ }
3044
+ </style>
3045
+ <slot></slot>
3046
+ `, (t = this.root.querySelector("slot")) == null || t.addEventListener("slotchange", () => this.refresh());
3047
+ }
3048
+ }
3049
+ class ot extends l {
3050
+ static get observedAttributes() {
3051
+ return ["label", "description", "status", "data-state", "data-index", "data-last", "data-vertical"];
3052
+ }
3053
+ connectedCallback() {
3054
+ var e;
3055
+ super.connectedCallback(), this.setAttribute("role", "listitem"), (e = this.closest("ui-stepper")) == null || e.refresh();
3056
+ }
3057
+ attributeChangedCallback(e, t, r) {
3058
+ var i;
3059
+ super.attributeChangedCallback(e, t, r), e.startsWith("data-") || (i = this.closest("ui-stepper")) == null || i.refresh();
3060
+ }
3061
+ render() {
3062
+ const e = this.getAttribute("data-state") || "pending", t = this.getAttribute("data-index") || "", r = this.hasAttribute("data-last"), i = this.hasAttribute("data-vertical"), o = this.getAttribute("label") || "", s = this.getAttribute("description") || "", n = e === "done" ? '<svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"><path d="M3 8.5l3.2 3.2L13 5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>' : e === "error" ? "!" : this.escapeHtml(t), d = { done: "completed", active: "current step", pending: "upcoming", error: "error" }[e] || "";
3063
+ this.root.innerHTML = `
3064
+ <style>
3065
+ :host {
3066
+ display: flex;
3067
+ flex: ${r || i ? "0 0 auto" : "1 1 0"};
3068
+ flex-direction: ${i ? "row" : "column"};
3069
+ min-width: 0;
3070
+ font-family: var(--ui-font-family-base, sans-serif);
3071
+ }
3072
+ .row { display: flex; align-items: center; gap: var(--ui-space-2, 8px); ${i ? "flex-direction: column; align-items: center;" : ""} }
3073
+ .marker {
3074
+ flex: none;
3075
+ width: 28px; height: 28px;
3076
+ box-sizing: border-box;
3077
+ display: inline-flex; align-items: center; justify-content: center;
3078
+ border-radius: var(--ui-radius-full, 9999px);
3079
+ border: var(--ui-border-width-thin, 1px) solid var(--ui-color-border-strong, #000000);
3080
+ background-color: var(--ui-color-bg-surface, #ffffff);
3081
+ color: var(--ui-color-text-secondary, #616161);
3082
+ font-size: var(--ui-font-size-xs, 12px);
3083
+ font-weight: var(--ui-font-weight-semibold, 600);
3084
+ }
3085
+ .done .marker { background-color: var(--ui-color-primary, #ff5500); border-color: var(--ui-color-primary, #ff5500); color: var(--ui-color-primary-contrast, #ffffff); }
3086
+ .active .marker { border-color: var(--ui-color-primary, #ff5500); color: var(--ui-color-primary, #ff5500); box-shadow: 0 0 0 3px var(--ui-color-primary-subtle, #fff3e6); }
3087
+ .error .marker { background-color: var(--ui-color-error, #d32f2f); border-color: var(--ui-color-error, #d32f2f); color: var(--ui-color-error-contrast, #ffffff); }
3088
+ .line {
3089
+ flex: 1 1 auto;
3090
+ ${i ? "width: 2px; min-height: 20px; margin: 0 auto;" : "height: 2px; min-width: 16px;"}
3091
+ background-color: var(--ui-color-border, #e0e0e0);
3092
+ ${r ? "display: none;" : ""}
3093
+ }
3094
+ .done .line { background-color: var(--ui-color-primary, #ff5500); }
3095
+ .text { ${i ? "margin-left: var(--ui-space-3, 12px); padding-bottom: var(--ui-space-4, 16px);" : "margin-top: var(--ui-space-2, 8px); padding-right: var(--ui-space-2, 8px);"} min-width: 0; }
3096
+ .label { font-size: var(--ui-font-size-sm, 14px); font-weight: var(--ui-font-weight-medium, 500); color: var(--ui-color-text-primary, #000000); }
3097
+ .pending .label { color: var(--ui-color-text-secondary, #616161); }
3098
+ .error .label { color: var(--ui-color-error, #d32f2f); }
3099
+ .desc { font-size: var(--ui-font-size-xs, 12px); color: var(--ui-color-text-secondary, #616161); }
3100
+ .vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
3101
+ .wrap { display: flex; ${i ? "flex-direction: row;" : "flex-direction: column; flex: 1;"} }
3102
+ .vrail { display: flex; flex-direction: column; align-items: center; }
3103
+ </style>
3104
+ ${i ? `<div class="wrap ${e}">
3105
+ <div class="vrail"><span class="marker" aria-hidden="true">${n}</span><span class="line"></span></div>
3106
+ <div class="text"><div class="label">${this.escapeHtml(o)}<span class="vh"> (${d})</span></div>${s ? `<div class="desc">${this.escapeHtml(s)}</div>` : ""}<slot></slot></div>
3107
+ </div>` : `<div class="wrap ${e}">
3108
+ <div class="row"><span class="marker" aria-hidden="true">${n}</span><span class="line"></span></div>
3109
+ <div class="text"><div class="label">${this.escapeHtml(o)}<span class="vh"> (${d})</span></div>${s ? `<div class="desc">${this.escapeHtml(s)}</div>` : ""}<slot></slot></div>
3110
+ </div>`}
3111
+ `;
3112
+ }
3113
+ }
3114
+ customElements.get("ui-stepper") || customElements.define("ui-stepper", rt);
3115
+ customElements.get("ui-step") || customElements.define("ui-step", ot);
3116
+ class st extends l {
3117
+ static get observedAttributes() {
3118
+ return ["variant", "size", "removable", "disabled", "remove-label"];
3119
+ }
3120
+ get removable() {
3121
+ return this.getBooleanAttr("removable");
3122
+ }
3123
+ set removable(e) {
3124
+ this.setBooleanAttr("removable", e);
3125
+ }
3126
+ get disabled() {
3127
+ return this.getBooleanAttr("disabled");
3128
+ }
3129
+ set disabled(e) {
3130
+ this.setBooleanAttr("disabled", e);
3131
+ }
3132
+ connectedCallback() {
3133
+ super.connectedCallback(), this.listen("keydown", this.handleKeyDown.bind(this));
3134
+ }
3135
+ requestRemove() {
3136
+ this.disabled || !this.removable || this.emit("remove");
3137
+ }
3138
+ handleKeyDown(e) {
3139
+ if (e.key === "Delete" || e.key === "Backspace") {
3140
+ if (this.disabled || !this.removable) return;
3141
+ e.preventDefault(), this.requestRemove();
3142
+ }
3143
+ }
3144
+ render() {
3145
+ var s;
3146
+ const e = ["neutral", "primary", "success", "warning", "error"].includes(this.getAttribute("variant") || "") ? this.getAttribute("variant") : "neutral", t = this.getAttribute("size") === "sm" ? "sm" : "md", r = this.removable, i = this.disabled, o = this.getAttribute("remove-label") || "Remove";
3147
+ r && !i ? this.setAttribute("tabindex", "0") : this.removeAttribute("tabindex"), this.setAttribute("aria-disabled", String(i)), this.root.innerHTML = `
3148
+ <style>
3149
+ :host { display: inline-flex; font-family: var(--ui-font-family-base, sans-serif); outline: none; }
3150
+ :host(:focus-visible) .chip { box-shadow: 0 0 0 2px var(--ui-color-bg-canvas, #ffffff), 0 0 0 4px var(--ui-color-focus-ring, #ff5500); }
3151
+ .chip {
3152
+ display: inline-flex;
3153
+ align-items: center;
3154
+ gap: var(--ui-space-1, 4px);
3155
+ box-sizing: border-box;
3156
+ max-width: 100%;
3157
+ border-radius: var(--ui-radius-full, 9999px);
3158
+ border: var(--ui-border-width-thin, 1px) solid var(--ui-color-border, #e0e0e0);
3159
+ background-color: var(--ui-color-bg-muted, #f5f5f5);
3160
+ color: var(--ui-color-text-primary, #000000);
3161
+ font-weight: var(--ui-font-weight-medium, 500);
3162
+ line-height: var(--ui-line-height-none, 1);
3163
+ user-select: none;
3164
+ }
3165
+ .chip.md { padding: 5px 10px; font-size: var(--ui-font-size-sm, 14px); }
3166
+ .chip.sm { padding: 3px 8px; font-size: var(--ui-font-size-xs, 12px); }
3167
+ .chip.primary { background-color: var(--ui-color-primary-subtle, #fff3e6); border-color: var(--ui-color-primary, #ff5500); color: var(--ui-color-primary-active, #cc4400); }
3168
+ .chip.success { background-color: var(--ui-color-success-bg, #e8f5e9); border-color: var(--ui-color-success, #1b873f); color: var(--ui-color-success, #1b873f); }
3169
+ .chip.warning { background-color: var(--ui-color-warning-bg, #fffbeb); border-color: var(--ui-color-warning, #d97706); color: var(--ui-color-warning, #d97706); }
3170
+ .chip.error { background-color: var(--ui-color-error-bg, #fde8e8); border-color: var(--ui-color-error, #d32f2f); color: var(--ui-color-error, #d32f2f); }
3171
+ .chip.disabled { opacity: 0.5; cursor: not-allowed; }
3172
+ .label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
3173
+ button {
3174
+ all: unset;
3175
+ display: inline-flex; align-items: center; justify-content: center;
3176
+ width: 16px; height: 16px;
3177
+ margin-right: -4px;
3178
+ border-radius: var(--ui-radius-full, 9999px);
3179
+ cursor: pointer;
3180
+ color: inherit;
3181
+ }
3182
+ button:hover { background-color: rgba(0, 0, 0, 0.12); }
3183
+ button:focus-visible { box-shadow: 0 0 0 2px var(--ui-color-focus-ring, #ff5500); }
3184
+ button[disabled] { cursor: not-allowed; }
3185
+ svg { width: 10px; height: 10px; pointer-events: none; }
3186
+ </style>
3187
+ <span class="chip ${e} ${t} ${i ? "disabled" : ""}">
3188
+ <span class="label"><slot></slot></span>
3189
+ ${r ? `<button type="button" tabindex="-1" aria-label="${this.escapeHtml(o)}" ${i ? "disabled" : ""}>
3190
+ <svg viewBox="0 0 10 10" aria-hidden="true"><path d="M2 2l6 6M8 2L2 8" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" fill="none"/></svg>
3191
+ </button>` : ""}
3192
+ </span>
3193
+ `, (s = this.root.querySelector("button")) == null || s.addEventListener("click", (n) => {
3194
+ n.stopPropagation(), this.requestRemove();
3195
+ });
3196
+ }
3197
+ }
3198
+ customElements.get("ui-chip") || customElements.define("ui-chip", st);
3199
+ class at extends l {
2622
3200
  static get observedAttributes() {
2623
3201
  return ["level", "time"];
2624
3202
  }
2625
3203
  get level() {
2626
- const t = this.getAttribute("level") || "info";
2627
- return ["info", "success", "warning", "error", "debug"].includes(t) ? t : "info";
3204
+ const e = this.getAttribute("level") || "info";
3205
+ return ["info", "success", "warning", "error", "debug"].includes(e) ? e : "info";
2628
3206
  }
2629
3207
  get time() {
2630
3208
  return this.getAttribute("time") || "";
2631
3209
  }
2632
3210
  render() {
2633
- const t = this.time;
3211
+ const e = this.time;
2634
3212
  this.root.innerHTML = `
2635
3213
  <style>
2636
3214
  :host {
@@ -2671,13 +3249,13 @@ class G extends n {
2671
3249
  :host([level="debug"]) .msg { color: var(--ui-color-text-muted, #9e9e9e); }
2672
3250
  </style>
2673
3251
  <span class="marker" aria-hidden="true"></span>
2674
- ${t ? `<span class="time">${this.escapeHtml(t)}</span>` : ""}
3252
+ ${e ? `<span class="time">${this.escapeHtml(e)}</span>` : ""}
2675
3253
  <span class="msg"><slot></slot></span>
2676
3254
  `;
2677
3255
  }
2678
3256
  }
2679
- customElements.get("ui-log-item") || customElements.define("ui-log-item", G);
2680
- class J extends n {
3257
+ customElements.get("ui-log-item") || customElements.define("ui-log-item", at);
3258
+ class nt extends l {
2681
3259
  static get observedAttributes() {
2682
3260
  return ["label", "height", "wrap", "auto-scroll", "max", "empty"];
2683
3261
  }
@@ -2694,55 +3272,55 @@ class J extends n {
2694
3272
  return this.getAttribute("auto-scroll") !== "false";
2695
3273
  }
2696
3274
  get max() {
2697
- const t = parseInt(this.getAttribute("max") || "500", 10);
2698
- return Number.isFinite(t) && t > 0 ? t : 500;
3275
+ const e = parseInt(this.getAttribute("max") || "500", 10);
3276
+ return Number.isFinite(e) && e > 0 ? e : 500;
2699
3277
  }
2700
3278
  get emptyText() {
2701
3279
  return this.getAttribute("empty") || "표시할 항목이 없습니다.";
2702
3280
  }
2703
3281
  connectedCallback() {
2704
3282
  super.connectedCallback();
2705
- const t = this.root.querySelector("slot");
2706
- t == null || t.addEventListener("slotchange", () => this.handleSlotChange());
3283
+ const e = this.root.querySelector("slot");
3284
+ e == null || e.addEventListener("slotchange", () => this.handleSlotChange());
2707
3285
  }
2708
3286
  /**
2709
3287
  * item 수집 (ui-log-item만)
2710
3288
  */
2711
3289
  items() {
2712
3290
  return Array.from(this.children).filter(
2713
- (t) => t.tagName.toLowerCase() === "ui-log-item"
3291
+ (e) => e.tagName.toLowerCase() === "ui-log-item"
2714
3292
  );
2715
3293
  }
2716
3294
  /**
2717
3295
  * 최대 개수 초과 시 오래된 항목 제거 + 스티키 바텀
2718
3296
  */
2719
3297
  handleSlotChange() {
2720
- var s;
2721
- const t = this.root.querySelector(".viewport"), e = t ? t.scrollHeight - t.scrollTop - t.clientHeight < 40 : !0, r = this.items(), i = r.length - this.max;
2722
- for (let o = 0; o < i; o++) (s = r[o]) == null || s.remove();
2723
- t && (e || this.autoScroll) && (t.scrollTop = t.scrollHeight), this.updateEmpty(), this.updateCount();
3298
+ var o;
3299
+ const e = this.root.querySelector(".viewport"), t = e ? e.scrollHeight - e.scrollTop - e.clientHeight < 40 : !0, r = this.items(), i = r.length - this.max;
3300
+ for (let s = 0; s < i; s++) (o = r[s]) == null || o.remove();
3301
+ e && (t || this.autoScroll) && (e.scrollTop = e.scrollHeight), this.updateEmpty(), this.updateCount();
2724
3302
  }
2725
3303
  updateEmpty() {
2726
- const t = this.root.querySelector(".empty");
2727
- t && t.setAttribute("aria-hidden", this.items().length > 0 ? "true" : "false");
3304
+ const e = this.root.querySelector(".empty");
3305
+ e && e.setAttribute("aria-hidden", this.items().length > 0 ? "true" : "false");
2728
3306
  }
2729
3307
  /** 맨 아래로 강제 스크롤 */
2730
3308
  scrollDown() {
2731
- const t = this.root.querySelector(".viewport");
2732
- t && (t.scrollTop = t.scrollHeight);
3309
+ const e = this.root.querySelector(".viewport");
3310
+ e && (e.scrollTop = e.scrollHeight);
2733
3311
  }
2734
3312
  /** 프로그래매틱 로그 추가 */
2735
- push(t, e, r) {
3313
+ push(e, t, r) {
2736
3314
  const i = document.createElement("ui-log-item");
2737
- i.setAttribute("level", t), r && i.setAttribute("time", r), i.textContent = e, this.appendChild(i);
3315
+ i.setAttribute("level", e), r && i.setAttribute("time", r), i.textContent = t, this.appendChild(i);
2738
3316
  }
2739
3317
  /** 전체 비우기 */
2740
3318
  clear() {
2741
- this.items().forEach((t) => t.remove()), this.updateEmpty();
3319
+ this.items().forEach((e) => e.remove()), this.updateEmpty();
2742
3320
  }
2743
3321
  render() {
2744
3322
  var i;
2745
- const t = this.label, e = `height: ${this.height.replace(/["<>]/g, "")};`, r = this.escapeHtml(this.emptyText);
3323
+ const e = this.label, t = `height: ${this.height.replace(/["<>]/g, "")};`, r = this.escapeHtml(this.emptyText);
2746
3324
  this.root.innerHTML = `
2747
3325
  <style>
2748
3326
  :host {
@@ -2792,7 +3370,7 @@ class J extends n {
2792
3370
  .copy-btn:focus-visible { box-shadow: 0 0 0 2px var(--ui-color-focus-ring, #ff5500); }
2793
3371
  .viewport {
2794
3372
  overflow: auto;
2795
- ${e}
3373
+ ${t}
2796
3374
  padding: var(--ui-space-3, 12px) var(--ui-space-4, 16px);
2797
3375
  }
2798
3376
  .empty {
@@ -2804,10 +3382,10 @@ class J extends n {
2804
3382
  }
2805
3383
  .empty[aria-hidden="true"] { display: none; }
2806
3384
  </style>
2807
- <div class="log" role="log" aria-label="${this.escapeHtml(t || "로그")}" aria-live="polite">
3385
+ <div class="log" role="log" aria-label="${this.escapeHtml(e || "로그")}" aria-live="polite">
2808
3386
  <div class="head">
2809
3387
  <span class="bar" aria-hidden="true"></span>
2810
- <span class="label">${this.escapeHtml(t || "로그")}</span>
3388
+ <span class="label">${this.escapeHtml(e || "로그")}</span>
2811
3389
  <span class="count"></span>
2812
3390
  <span class="spacer"></span>
2813
3391
  <button class="copy-btn" title="전체 복사">복사</button>
@@ -2818,56 +3396,63 @@ class J extends n {
2818
3396
  </div>
2819
3397
  </div>
2820
3398
  `, (i = this.root.querySelector(".copy-btn")) == null || i.addEventListener("click", () => {
2821
- var l;
2822
- const s = this.items().map((d) => d.textContent ?? "").join(`
3399
+ var n;
3400
+ const o = this.items().map((d) => d.textContent ?? "").join(`
2823
3401
  `);
2824
- (l = navigator.clipboard) != null && l.writeText && navigator.clipboard.writeText(s).catch(() => {
3402
+ (n = navigator.clipboard) != null && n.writeText && navigator.clipboard.writeText(o).catch(() => {
2825
3403
  });
2826
- const o = this.root.querySelector(".copy-btn");
2827
- o && (o.textContent = "복사됨", window.setTimeout(() => {
2828
- o.textContent = "복사";
2829
- }, 1400)), this.emit("copy", { text: s });
3404
+ const s = this.root.querySelector(".copy-btn");
3405
+ s && (s.textContent = "복사됨", window.setTimeout(() => {
3406
+ s.textContent = "복사";
3407
+ }, 1400)), this.emit("copy", { text: o });
2830
3408
  }), this.updateCount(), this.updateEmpty();
2831
3409
  }
2832
3410
  updateCount() {
2833
- const t = this.root.querySelector(".count");
2834
- t && (t.textContent = this.items().length > 0 ? `${this.items().length}건` : "");
3411
+ const e = this.root.querySelector(".count");
3412
+ e && (e.textContent = this.items().length > 0 ? `${this.items().length}건` : "");
2835
3413
  }
2836
3414
  }
2837
- customElements.get("ui-log") || customElements.define("ui-log", J);
3415
+ customElements.get("ui-log") || customElements.define("ui-log", nt);
2838
3416
  export {
2839
- v as FocusTrap,
3417
+ y as FocusTrap,
2840
3418
  _ as UIAccordion,
2841
- y as UIAccordionItem,
2842
- U as UIAlert,
2843
- N as UIAvatar,
2844
- M as UIBadge,
2845
- V as UIBreadcrumbItem,
2846
- R as UIBreadcrumbs,
2847
- A as UIButton,
2848
- O as UICard,
2849
- E as UICheckbox,
2850
- X as UIDrawer,
2851
- j as UIDropdown,
2852
- K as UIDropdownItem,
2853
- n as UIElement,
2854
- z as UIInput,
2855
- J as UILog,
2856
- G as UILogItem,
2857
- S as UIModal,
2858
- Y as UINavbar,
2859
- L as UIOption,
2860
- P as UIPagination,
2861
- F as UIProgress,
2862
- x as UIRadio,
2863
- $ as UISelect,
2864
- W as UISkeleton,
2865
- q as UISpinner,
3419
+ E as UIAccordionItem,
3420
+ O as UIAlert,
3421
+ X as UIAvatar,
3422
+ j as UIBadge,
3423
+ G as UIBreadcrumbItem,
3424
+ Y as UIBreadcrumbs,
3425
+ B as UIButton,
3426
+ P as UICard,
3427
+ z as UICheckbox,
3428
+ st as UIChip,
3429
+ J as UIDrawer,
3430
+ R as UIDropdown,
3431
+ V as UIDropdownItem,
3432
+ l as UIElement,
3433
+ tt as UIEmptyState,
3434
+ A as UIInput,
3435
+ nt as UILog,
3436
+ at as UILogItem,
3437
+ D as UIModal,
3438
+ Z as UINavbar,
3439
+ H as UIOption,
3440
+ W as UIPagination,
3441
+ N as UIProgress,
3442
+ k as UIRadio,
3443
+ it as UISegment,
3444
+ et as UISegmented,
3445
+ T as UISelect,
3446
+ Q as UISkeleton,
3447
+ K as UISpinner,
3448
+ ot as UIStep,
3449
+ rt as UIStepper,
2866
3450
  C as UISwitch,
2867
- H as UITab,
2868
- I as UITabPanel,
2869
- m as UITable,
2870
- D as UITabs,
2871
- T as UIToast,
2872
- B as UITooltip
3451
+ U as UITab,
3452
+ F as UITabPanel,
3453
+ w as UITable,
3454
+ I as UITabs,
3455
+ $ as UITextarea,
3456
+ M as UIToast,
3457
+ q as UITooltip
2873
3458
  };