@iyulab/components 1.3.4 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/_virtual/_glob-assets_raw/dark.css.e8ac080d.js +1 -1
  3. package/dist/assets/locales/ar.json.js +23 -0
  4. package/dist/assets/locales/de.json.js +23 -0
  5. package/dist/assets/locales/en.json.js +23 -0
  6. package/dist/assets/locales/es.json.js +23 -0
  7. package/dist/assets/locales/fr.json.js +23 -0
  8. package/dist/assets/locales/id.json.js +23 -0
  9. package/dist/assets/locales/ja.json.js +23 -0
  10. package/dist/assets/locales/ko.json.js +23 -0
  11. package/dist/assets/locales/pt-BR.json.js +23 -0
  12. package/dist/assets/locales/ru.json.js +23 -0
  13. package/dist/assets/locales/th.json.js +23 -0
  14. package/dist/assets/locales/vi.json.js +23 -0
  15. package/dist/assets/locales/zh-CN.json.js +23 -0
  16. package/dist/assets/locales/zh-TW.json.js +23 -0
  17. package/dist/components/UFloatingElement.js +13 -4
  18. package/dist/components/UFormControlElement.d.ts +38 -8
  19. package/dist/components/UFormControlElement.js +61 -6
  20. package/dist/components/UOverlayElement.d.ts +4 -0
  21. package/dist/components/UOverlayElement.js +14 -4
  22. package/dist/components/alert/UAlert.js +10 -4
  23. package/dist/components/alert/UAlert.styles.js +0 -6
  24. package/dist/components/avatar/UAvatar.js +1 -1
  25. package/dist/components/badge/UBadge.d.ts +1 -1
  26. package/dist/components/badge/UBadge.js +2 -2
  27. package/dist/components/badge/UBadge.styles.js +1 -1
  28. package/dist/components/breadcrumb/UBreadcrumb.js +1 -1
  29. package/dist/components/breadcrumb-item/UBreadcrumbItem.js +1 -1
  30. package/dist/components/button/UButton.d.ts +6 -11
  31. package/dist/components/button/UButton.js +1 -1
  32. package/dist/components/button/UButton.styles.js +50 -51
  33. package/dist/components/button-group/UButtonGroup.js +1 -1
  34. package/dist/components/card/UCard.js +1 -1
  35. package/dist/components/carousel/UCarousel.js +2 -2
  36. package/dist/components/checkbox/UCheckbox.d.ts +4 -1
  37. package/dist/components/checkbox/UCheckbox.js +11 -8
  38. package/dist/components/checkbox/UCheckbox.styles.js +12 -7
  39. package/dist/components/chip/UChip.js +6 -3
  40. package/dist/components/dialog/UDialog.js +2 -2
  41. package/dist/components/divider/UDivider.js +1 -1
  42. package/dist/components/drawer/UDrawer.js +2 -2
  43. package/dist/components/drawer/UDrawer.styles.js +0 -6
  44. package/dist/components/field/UField.js +1 -1
  45. package/dist/components/form/UForm.js +1 -1
  46. package/dist/components/icon/UIcon.js +1 -1
  47. package/dist/components/icon-button/UIconButton.d.ts +0 -1
  48. package/dist/components/icon-button/UIconButton.js +2 -7
  49. package/dist/components/input/UInput.d.ts +2 -3
  50. package/dist/components/input/UInput.js +37 -9
  51. package/dist/components/input/UInput.styles.js +1 -4
  52. package/dist/components/menu/UMenu.js +1 -1
  53. package/dist/components/menu-item/UMenuItem.js +1 -1
  54. package/dist/components/menu-item/UMenuItem.styles.js +4 -3
  55. package/dist/components/option/UOption.d.ts +4 -1
  56. package/dist/components/option/UOption.js +10 -4
  57. package/dist/components/option/UOption.styles.js +5 -4
  58. package/dist/components/panel/UPanel.js +1 -1
  59. package/dist/components/popover/UPopover.js +1 -1
  60. package/dist/components/progress-bar/UProgressBar.js +1 -1
  61. package/dist/components/progress-bar/UProgressBar.styles.js +2 -2
  62. package/dist/components/progress-ring/UProgressRing.js +1 -1
  63. package/dist/components/progress-ring/UProgressRing.styles.js +2 -2
  64. package/dist/components/radio/URadio.d.ts +1 -1
  65. package/dist/components/radio/URadio.js +5 -6
  66. package/dist/components/radio/URadio.styles.js +21 -16
  67. package/dist/components/rating/URating.d.ts +3 -2
  68. package/dist/components/rating/URating.js +30 -37
  69. package/dist/components/select/USelect.d.ts +8 -5
  70. package/dist/components/select/USelect.js +29 -41
  71. package/dist/components/select/USelect.styles.js +5 -5
  72. package/dist/components/skeleton/USkeleton.js +1 -1
  73. package/dist/components/slider/USlider.d.ts +3 -2
  74. package/dist/components/slider/USlider.js +20 -30
  75. package/dist/components/slider/USlider.styles.js +2 -2
  76. package/dist/components/spinner/USpinner.js +1 -1
  77. package/dist/components/spinner/USpinner.styles.js +1 -1
  78. package/dist/components/split-panel/USplitPanel.js +25 -13
  79. package/dist/components/switch/USwitch.d.ts +4 -1
  80. package/dist/components/switch/USwitch.js +11 -8
  81. package/dist/components/switch/USwitch.styles.js +5 -1
  82. package/dist/components/tab/UTab.js +6 -3
  83. package/dist/components/tab-panel/UTabPanel.d.ts +5 -0
  84. package/dist/components/tab-panel/UTabPanel.js +12 -4
  85. package/dist/components/tab-panel/UTabPanel.styles.js +7 -3
  86. package/dist/components/tag/UTag.js +1 -1
  87. package/dist/components/tag/UTag.styles.js +14 -13
  88. package/dist/components/textarea/UTextarea.d.ts +1 -1
  89. package/dist/components/textarea/UTextarea.js +17 -6
  90. package/dist/components/tooltip/UTooltip.js +1 -1
  91. package/dist/components/tree/UTree.js +1 -1
  92. package/dist/components/tree-item/UTreeItem.js +10 -4
  93. package/dist/components/tree-item/UTreeItem.styles.js +5 -4
  94. package/dist/index.d.ts +2 -4
  95. package/dist/index.js +6 -8
  96. package/dist/react/UTabPanel.d.ts +1 -0
  97. package/dist/react/UTabPanel.js +3 -1
  98. package/dist/styles/dark.css +99 -99
  99. package/dist/utilities/Locale.d.ts +38 -0
  100. package/dist/utilities/Locale.js +93 -0
  101. package/dist/utilities/Toast.d.ts +9 -0
  102. package/dist/utilities/Toast.js +15 -7
  103. package/dist/utilities/elements.d.ts +0 -23
  104. package/dist/utilities/elements.js +1 -34
  105. package/package.json +2 -3
  106. package/skills/iyulab-components/SKILL.md +2 -3
  107. package/skills/iyulab-components/references/components/input.md +1 -2
  108. package/skills/iyulab-components/references/components/option.md +1 -0
  109. package/skills/iyulab-components/references/components/select.md +1 -2
  110. package/skills/iyulab-components/references/components/tab-panel.md +6 -0
  111. package/skills/iyulab-components/references/extensions/form-control.md +22 -6
  112. package/skills/iyulab-components/references/usage.md +11 -0
  113. package/skills/iyulab-components/references/utilities/elements.md +1 -17
  114. package/skills/iyulab-components/references/utilities/locale.md +36 -0
  115. package/skills/iyulab-components/references/utilities/theme.md +12 -0
  116. package/skills/iyulab-components/references/utilities/toast.md +6 -0
  117. package/dist/components/UDataElement.d.ts +0 -44
  118. package/dist/components/UDataElement.js +0 -101
  119. package/dist/components/UDataElement.styles.d.ts +0 -1
  120. package/dist/components/UDataElement.styles.js +0 -95
  121. package/dist/core/locale.d.ts +0 -69
  122. package/dist/core/locale.js +0 -85
  123. package/dist/utilities/sanitizers.d.ts +0 -35
  124. package/dist/utilities/sanitizers.js +0 -75
  125. package/skills/iyulab-components/references/extensions/data.md +0 -60
  126. package/skills/iyulab-components/references/utilities/sanitizers.md +0 -32
@@ -7,14 +7,18 @@ export type SelectVariant = 'outlined' | 'filled' | 'underlined' | 'borderless';
7
7
  * 단일 선택 및 다중 선택, 검색 기능을 지원합니다.
8
8
  *
9
9
  * @slot - u-option 아이템
10
+ * @slot display - 트리거에 표시할 콘텐츠를 직접 지정. 비워두면 선택값 텍스트를 자동 생성해 보여준다.
11
+ * (u-option을 그대로 옮겨 꽂을 수는 없다 — 하나의 노드는 slot에 동시에 두 곳 렌더링될 수 없어서
12
+ * 팝오버 목록에서 사라지기 때문. 리치 콘텐츠가 필요하면 이 slot에 별도 마크업을 할당하고
13
+ * `change` 이벤트에서 직접 갱신한다.)
10
14
  *
11
15
  * @csspart field - u-field 요소
12
16
  * @csspart container - 트리거 영역을 감싸는 요소
13
17
  * @csspart popover - 옵션 목록이 표시되는 팝오버 요소
14
18
  * @csspart search-input - 검색 입력 영역
15
19
  *
16
- * @cssprop --select-popover-min-width - 팝오버의 최소 너비 (기본값: 100%)
17
- * @cssprop --select-popover-max-width - 팝오버의 최대 너비 (기본값: 80vw)
20
+ * @cssprop --select-popover-width - 팝오버의 너비 (기본값: 앵커(트리거) 너비, strategy와 무관하게 동일).
21
+ * 옵션 텍스트가 길어도 값을 넘겨 넓어지지 않으며, 넘치는 텍스트는 UOption에서 ellipsis 처리된다.
18
22
  * @cssprop --select-popover-min-height - 팝오버의 최소 높이 (기본값: 0px)
19
23
  * @cssprop --select-popover-max-height - 팝오버의 최대 높이 (기본값: 50vh)
20
24
  *
@@ -41,6 +45,7 @@ export declare class USelect extends UFormControlElement<string | string[]> {
41
45
  containerEl?: HTMLElement;
42
46
  popoverEl?: UPopover;
43
47
  private options;
48
+ protected shouldValidate(changed: PropertyValues): boolean;
44
49
  private get valueAsString();
45
50
  private get valueAsArray();
46
51
  private get hasValue();
@@ -48,12 +53,11 @@ export declare class USelect extends UFormControlElement<string | string[]> {
48
53
  protected updated(changedProperties: PropertyValues): void;
49
54
  render(): import('lit-html').TemplateResult<1>;
50
55
  private renderContent;
51
- validate(): boolean;
56
+ protected setValidity(): void;
52
57
  reset(): void;
53
58
  private setup;
54
59
  private cleanup;
55
60
  private onChangeValue;
56
- private getValidity;
57
61
  private handleSlotChange;
58
62
  private handleOptionClick;
59
63
  private handleOptionKeydown;
@@ -61,7 +65,6 @@ export declare class USelect extends UFormControlElement<string | string[]> {
61
65
  private handleSearchKeydown;
62
66
  private handleClearClick;
63
67
  private handleChipRemove;
64
- private handlePopoverEvent;
65
68
  }
66
69
  declare global {
67
70
  interface HTMLElementTagNameMap {
@@ -1,15 +1,15 @@
1
- import { formatTemplate, getLocaleStrings, resolveLocale } from "../../core/locale.js";
2
1
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/decorateMetadata.js";
3
2
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/decorate.js";
4
3
  import { UFormControlElement } from "../UFormControlElement.js";
5
- import "../icon/UIcon.js";
6
4
  import "../spinner/USpinner.js";
5
+ import "../icon/UIcon.js";
6
+ import { Locale } from "../../utilities/Locale.js";
7
7
  import "../field/UField.js";
8
8
  import { UOption } from "../option/UOption.js";
9
9
  import { UPopover } from "../popover/UPopover.js";
10
10
  import { styles } from "./USelect.styles.js";
11
- import { customElement, property, query, state } from "lit/decorators.js";
12
11
  import { html } from "lit";
12
+ import { customElement, property, query, state } from "lit/decorators.js";
13
13
  //#region src/components/select/USelect.ts
14
14
  var USelect = class USelect extends UFormControlElement {
15
15
  constructor(..._args) {
@@ -107,18 +107,21 @@ var USelect = class USelect extends UFormControlElement {
107
107
  this.containerEl?.click();
108
108
  };
109
109
  this.handleChipRemove = (e) => {
110
- e.stopImmediatePropagation();
111
110
  const value = e.currentTarget.dataset.value;
112
111
  if (!value) return;
113
112
  this.value = this.valueAsArray.filter((v) => v !== value);
114
113
  };
115
- this.handlePopoverEvent = (e) => {
116
- e.stopPropagation();
117
- };
118
114
  }
119
115
  static {
120
116
  this.styles = [super.styles, styles];
121
117
  }
118
+ shouldValidate(changed) {
119
+ return super.shouldValidate(changed) || [
120
+ "minCount",
121
+ "maxCount",
122
+ "multiple"
123
+ ].some((k) => changed.has(k));
124
+ }
122
125
  get valueAsString() {
123
126
  return Array.isArray(this.value) ? this.value.join(",") : this.value ?? "";
124
127
  }
@@ -152,7 +155,7 @@ var USelect = class USelect extends UFormControlElement {
152
155
 
153
156
  <div class="container" part="container" tabindex=${this.disabled ? "-1" : "0"}>
154
157
  <slot name="prefix"></slot>
155
- ${this.renderContent()}
158
+ <slot name="display">${this.renderContent()}</slot>
156
159
  <slot name="suffix"></slot>
157
160
 
158
161
  <u-icon class="suffix-item"
@@ -178,11 +181,9 @@ var USelect = class USelect extends UFormControlElement {
178
181
  autofocus
179
182
  for=".container"
180
183
  trigger="click"
184
+ strategy="fixed"
181
185
  placement="bottom-start"
182
186
  offset="1"
183
- strategy="fixed"
184
- @show=${this.handlePopoverEvent}
185
- @hide=${this.handlePopoverEvent}
186
187
  >
187
188
  <div class="search-input" part="search-input"
188
189
  ?hidden=${!this.searchable}>
@@ -214,19 +215,27 @@ var USelect = class USelect extends UFormControlElement {
214
215
  </div>
215
216
  `;
216
217
  } else {
217
- const text = this.options.find((o) => o.value === this.value)?.getText();
218
- if (!text) return html`
218
+ const option = this.options.find((o) => o.value === this.value);
219
+ if (!option) return html`
219
220
  <span class="text-content placeholder">${this.placeholder ?? ""}</span>`;
220
- return html`<span class="text-content">${text}</span>`;
221
+ return html`<span class="text-content">${option.getContent()}</span>`;
221
222
  }
222
223
  }
223
- validate() {
224
- if (this.internals) this.invalid = !this.internals.checkValidity();
225
- else {
226
- const { flags } = this.getValidity(this.valueAsArray);
227
- this.invalid = Object.keys(flags).length > 0;
224
+ setValidity() {
225
+ const values = this.valueAsArray;
226
+ let flags = {};
227
+ let message = "";
228
+ if (this.required && !values.length) {
229
+ flags = { valueMissing: true };
230
+ message = Locale.getValue("valueMissing");
231
+ } else if (this.multiple && this.minCount != null && values.length > 0 && values.length < this.minCount) {
232
+ flags = { tooShort: true };
233
+ message = Locale.getValue("tooShort", { min: this.minCount });
234
+ } else if (this.multiple && this.maxCount != null && values.length > this.maxCount) {
235
+ flags = { tooLong: true };
236
+ message = Locale.getValue("tooLong", { max: this.maxCount });
228
237
  }
229
- return !this.invalid;
238
+ this.commit(flags, message, this.containerEl ?? void 0);
230
239
  }
231
240
  reset() {
232
241
  this.value = this.multiple ? [] : "";
@@ -254,33 +263,12 @@ var USelect = class USelect extends UFormControlElement {
254
263
  for (const option of this.options) if (this.multiple) option.selected = values.includes(option.value);
255
264
  else option.selected = option.value === this.value;
256
265
  this.internals?.setFormValue(this.valueAsString);
257
- const { flags, message } = this.getValidity(values);
258
- this.internals?.setValidity(flags, this.validationMessage || message, this.containerEl || void 0);
259
266
  if (!this.novalidate) this.validate();
260
267
  this.dispatchEvent(new Event("change", {
261
268
  bubbles: true,
262
269
  composed: true
263
270
  }));
264
271
  }
265
- getValidity(values) {
266
- const s = getLocaleStrings(resolveLocale(this.locale));
267
- if (this.required && !values.length) return {
268
- flags: { valueMissing: true },
269
- message: s.required
270
- };
271
- if (this.multiple && this.minCount != null && values.length > 0 && values.length < this.minCount) return {
272
- flags: { rangeUnderflow: true },
273
- message: formatTemplate(s.minCount, { min: this.minCount })
274
- };
275
- if (this.multiple && this.maxCount != null && values.length > this.maxCount) return {
276
- flags: { rangeOverflow: true },
277
- message: formatTemplate(s.maxCount, { max: this.maxCount })
278
- };
279
- return {
280
- flags: {},
281
- message: ""
282
- };
283
- }
284
272
  };
285
273
  __decorate([property({
286
274
  type: String,
@@ -2,8 +2,8 @@ import { css } from "lit";
2
2
  //#region src/components/select/USelect.styles.ts
3
3
  var styles = css`
4
4
  :host {
5
- --select-popover-min-width: 100%;
6
- --select-popover-max-width: 80vw;
5
+ /* --anchor-width u-popover(자식) 자신에게 JS로 설정되므로 여기서는 참조할 수 없다
6
+ (커스텀 프로퍼티는 조상→자손으로만 상속). 실제 폴백은 아래 u-popover 규칙에서 처리. */
7
7
  --select-popover-min-height: 0px;
8
8
  --select-popover-max-height: 50vh;
9
9
  }
@@ -163,10 +163,10 @@ var styles = css`
163
163
  color: var(--u-icon-color-active);
164
164
  }
165
165
 
166
- /* 드롭다운 패널 */
166
+ /* 드롭다운 패널 — 옵션 텍스트가 길어도 팝오버가 앵커보다 넓어지지 않도록 고정 너비로
167
+ 맞춘다(긴 텍스트는 UOption 자체의 ellipsis로 처리). */
167
168
  u-popover {
168
- min-width: var(--select-popover-min-width);
169
- max-width: var(--select-popover-max-width);
169
+ width: var(--select-popover-width, var(--anchor-width, 100%));
170
170
  min-height: var(--select-popover-min-height);
171
171
  max-height: var(--select-popover-max-height);
172
172
  padding: 4px;
@@ -2,8 +2,8 @@ import { UElement } from "../UElement.js";
2
2
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/decorateMetadata.js";
3
3
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/decorate.js";
4
4
  import { styles } from "./USkeleton.styles.js";
5
- import { customElement, property } from "lit/decorators.js";
6
5
  import { html } from "lit";
6
+ import { customElement, property } from "lit/decorators.js";
7
7
  //#region src/components/skeleton/USkeleton.ts
8
8
  var USkeleton = class USkeleton extends UElement {
9
9
  constructor(..._args) {
@@ -56,6 +56,8 @@ export declare class USlider extends UFormControlElement<number | number[]> {
56
56
  step: number;
57
57
  private dragging;
58
58
  private trackEl;
59
+ private containerEl?;
60
+ protected shouldValidate(changed: PropertyValues): boolean;
59
61
  get valueAsNumber(): number;
60
62
  get valueAsArray(): number[];
61
63
  private get minVal();
@@ -67,10 +69,9 @@ export declare class USlider extends UFormControlElement<number | number[]> {
67
69
  private get hasMarks();
68
70
  protected willUpdate(changedProperties: PropertyValues): void;
69
71
  render(): TemplateResult<1>;
70
- validate(): boolean;
72
+ protected setValidity(): void;
71
73
  reset(): void;
72
74
  private onChangeValue;
73
- private getValidity;
74
75
  private renderThumb;
75
76
  private formatDisplay;
76
77
  private formatValue;
@@ -1,12 +1,12 @@
1
- import { formatTemplate, getLocaleStrings, resolveLocale } from "../../core/locale.js";
2
1
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/decorateMetadata.js";
3
2
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/decorate.js";
4
3
  import { UFormControlElement } from "../UFormControlElement.js";
5
4
  import "../tooltip/UTooltip.js";
5
+ import { Locale } from "../../utilities/Locale.js";
6
6
  import "../field/UField.js";
7
7
  import { styles } from "./USlider.styles.js";
8
- import { customElement, property, query, state } from "lit/decorators.js";
9
8
  import { html } from "lit";
9
+ import { customElement, property, query, state } from "lit/decorators.js";
10
10
  //#region src/components/slider/USlider.ts
11
11
  var USlider = class USlider extends UFormControlElement {
12
12
  constructor(..._args) {
@@ -90,6 +90,9 @@ var USlider = class USlider extends UFormControlElement {
90
90
  static {
91
91
  this.styles = [super.styles, styles];
92
92
  }
93
+ shouldValidate(changed) {
94
+ return super.shouldValidate(changed) || changed.has("min") || changed.has("max");
95
+ }
93
96
  get valueAsNumber() {
94
97
  return Array.isArray(this.value) ? this.value[0] : this.value || 0;
95
98
  }
@@ -169,13 +172,21 @@ var USlider = class USlider extends UFormControlElement {
169
172
  </u-field>
170
173
  `;
171
174
  }
172
- validate() {
173
- if (this.internals) this.invalid = !this.internals.checkValidity();
174
- else {
175
- const { flags } = this.getValidity();
176
- this.invalid = Object.values(flags).some(Boolean);
175
+ setValidity() {
176
+ const v = this.valueAsNumber;
177
+ let flags = {};
178
+ let message = "";
179
+ if (this.required && !v) {
180
+ flags = { valueMissing: true };
181
+ message = Locale.getValue("valueMissing");
182
+ } else if (v < this.min) {
183
+ flags = { rangeUnderflow: true };
184
+ message = Locale.getValue("rangeUnderflow", { min: this.min });
185
+ } else if (v > this.max) {
186
+ flags = { rangeOverflow: true };
187
+ message = Locale.getValue("rangeOverflow", { max: this.max });
177
188
  }
178
- return !this.invalid;
189
+ this.commit(flags, message, this.containerEl ?? void 0);
179
190
  }
180
191
  reset() {
181
192
  if (this.range) this.value = [this.min, this.max];
@@ -186,33 +197,11 @@ var USlider = class USlider extends UFormControlElement {
186
197
  if (Array.isArray(this.value)) this.value = [this.snap(this.value[0]), this.snap(this.value[1])];
187
198
  else if (typeof this.value === "number") this.value = this.snap(this.value);
188
199
  this.internals?.setFormValue(this.valueAsNumber.toString());
189
- const { flags, message } = this.getValidity();
190
- this.internals?.setValidity(flags, this.validationMessage || message, this.renderRoot.querySelector(".container") || void 0);
191
200
  this.dispatchEvent(new Event("change", {
192
201
  bubbles: true,
193
202
  composed: true
194
203
  }));
195
204
  }
196
- getValidity() {
197
- const v = this.valueAsNumber;
198
- const s = getLocaleStrings(resolveLocale(this.locale));
199
- if (this.required && !v) return {
200
- flags: { valueMissing: true },
201
- message: s.required
202
- };
203
- if (v < this.min) return {
204
- flags: { rangeUnderflow: true },
205
- message: formatTemplate(s.minValue, { min: this.min })
206
- };
207
- if (v > this.max) return {
208
- flags: { rangeOverflow: true },
209
- message: formatTemplate(s.maxValue, { max: this.max })
210
- };
211
- return {
212
- flags: {},
213
- message: ""
214
- };
215
- }
216
205
  renderThumb(thumb) {
217
206
  const isEnd = thumb === "max";
218
207
  const val = this.getThumbValue(thumb);
@@ -282,6 +271,7 @@ __decorate([property({ type: Number }), __decorateMetadata("design:type", Number
282
271
  __decorate([property({ type: Number }), __decorateMetadata("design:type", Number)], USlider.prototype, "step", void 0);
283
272
  __decorate([state(), __decorateMetadata("design:type", Object)], USlider.prototype, "dragging", void 0);
284
273
  __decorate([query(".track"), __decorateMetadata("design:type", typeof HTMLElement === "undefined" ? Object : HTMLElement)], USlider.prototype, "trackEl", void 0);
274
+ __decorate([query(".container"), __decorateMetadata("design:type", typeof HTMLElement === "undefined" ? Object : HTMLElement)], USlider.prototype, "containerEl", void 0);
285
275
  USlider = __decorate([customElement("u-slider")], USlider);
286
276
  //#endregion
287
277
  export { USlider };
@@ -2,11 +2,11 @@ import { css } from "lit";
2
2
  //#region src/components/slider/USlider.styles.ts
3
3
  var styles = css`
4
4
  :host {
5
- --slider-fill-color: var(--u-blue-600);
5
+ --slider-fill-color: var(--u-primary-color, var(--u-blue-600));
6
6
  --slider-track-color: var(--u-neutral-300);
7
7
  --slider-track-height: 6px;
8
8
  --slider-thumb-size: 18px;
9
- --slider-thumb-color: var(--u-blue-600);
9
+ --slider-thumb-color: var(--slider-fill-color);
10
10
  --slider-thumb-border-color: var(--u-neutral-0);
11
11
  --slider-mark-size: 12px;
12
12
  --slider-mark-color: var(--u-neutral-0);
@@ -2,8 +2,8 @@ import { UElement } from "../UElement.js";
2
2
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/decorateMetadata.js";
3
3
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/decorate.js";
4
4
  import { styles } from "./USpinner.styles.js";
5
- import { customElement, property, state } from "lit/decorators.js";
6
5
  import { html } from "lit";
6
+ import { customElement, property, state } from "lit/decorators.js";
7
7
  //#region src/components/spinner/USpinner.ts
8
8
  var USpinner = class USpinner extends UElement {
9
9
  constructor(..._args) {
@@ -4,7 +4,7 @@ var styles = css`
4
4
  :host {
5
5
  --spinner-track-width: 0.125em;
6
6
  --spinner-track-color: var(--u-neutral-200);
7
- --spinner-indicator-color: var(--u-neutral-800);
7
+ --spinner-indicator-color: var(--u-primary-color, var(--u-blue-600));
8
8
  --spinner-indicator-speed: 2s;
9
9
  }
10
10
 
@@ -3,8 +3,8 @@ import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.138.0/hel
3
3
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/decorate.js";
4
4
  import { arrayAttrConverter } from "../../utilities/converters.js";
5
5
  import { styles } from "./USplitPanel.styles.js";
6
- import { customElement, property, query } from "lit/decorators.js";
7
6
  import { html } from "lit";
7
+ import { customElement, property, query } from "lit/decorators.js";
8
8
  //#region src/components/split-panel/USplitPanel.ts
9
9
  var USplitPanel = class USplitPanel extends UElement {
10
10
  constructor(..._args) {
@@ -67,10 +67,14 @@ var USplitPanel = class USplitPanel extends UElement {
67
67
  }
68
68
  document.body.style.userSelect = "none";
69
69
  document.body.style.cursor = this.orientation === "horizontal" ? "col-resize" : "row-resize";
70
- this.fire("shift-start", { detail: {
71
- index: this.dragState.index,
72
- ratio: [...this.percentages]
73
- } });
70
+ this.fire("shift-start", {
71
+ bubbles: false,
72
+ composed: false,
73
+ detail: {
74
+ index: this.dragState.index,
75
+ ratio: [...this.percentages]
76
+ }
77
+ });
74
78
  };
75
79
  this.handlePointerMove = (e) => {
76
80
  e.preventDefault();
@@ -95,10 +99,14 @@ var USplitPanel = class USplitPanel extends UElement {
95
99
  newRatio[bIdx] = bPercent;
96
100
  this.ratio = newRatio;
97
101
  }
98
- this.fire("shift", { detail: {
99
- index: this.dragState.index,
100
- ratio: this.lazy ? this.percentages : [...this.ratio]
101
- } });
102
+ this.fire("shift", {
103
+ bubbles: false,
104
+ composed: false,
105
+ detail: {
106
+ index: this.dragState.index,
107
+ ratio: this.lazy ? this.percentages : [...this.ratio]
108
+ }
109
+ });
102
110
  };
103
111
  this.handlePointerUp = (e) => {
104
112
  const target = e.currentTarget;
@@ -121,10 +129,14 @@ var USplitPanel = class USplitPanel extends UElement {
121
129
  }
122
130
  document.body.style.userSelect = "";
123
131
  document.body.style.cursor = "";
124
- this.fire("shift-end", { detail: {
125
- index: this.dragState.index,
126
- ratio: [...this.percentages]
127
- } });
132
+ this.fire("shift-end", {
133
+ bubbles: false,
134
+ composed: false,
135
+ detail: {
136
+ index: this.dragState.index,
137
+ ratio: [...this.percentages]
138
+ }
139
+ });
128
140
  };
129
141
  }
130
142
  static {
@@ -1,3 +1,4 @@
1
+ import { PropertyValues } from 'lit';
1
2
  import { UFormControlElement } from '../UFormControlElement.js';
2
3
  /**
3
4
  * 온/오프 상태를 전환하는 스위치 컴포넌트입니다.
@@ -31,8 +32,10 @@ export declare class USwitch extends UFormControlElement<string> {
31
32
  static styles: import('lit').CSSResultGroup[];
32
33
  /** 체크 여부 */
33
34
  checked: boolean;
35
+ inputEl?: HTMLInputElement;
36
+ protected shouldValidate(changed: PropertyValues): boolean;
34
37
  render(): import('lit-html').TemplateResult<1>;
35
- validate(): boolean;
38
+ protected setValidity(): void;
36
39
  reset(): void;
37
40
  private handleInputChange;
38
41
  }
@@ -1,9 +1,10 @@
1
1
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/decorateMetadata.js";
2
2
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/decorate.js";
3
3
  import { UFormControlElement } from "../UFormControlElement.js";
4
+ import { Locale } from "../../utilities/Locale.js";
4
5
  import { styles } from "./USwitch.styles.js";
5
- import { customElement, property } from "lit/decorators.js";
6
6
  import { html } from "lit";
7
+ import { customElement, property, query } from "lit/decorators.js";
7
8
  import { live } from "lit/directives/live.js";
8
9
  //#region src/components/switch/USwitch.ts
9
10
  var USwitch = class USwitch extends UFormControlElement {
@@ -16,7 +17,6 @@ var USwitch = class USwitch extends UFormControlElement {
16
17
  const input = e.target;
17
18
  this.checked = input.checked;
18
19
  this.internals?.setFormValue(this.checked ? this.value || String(this.checked) : String(this.checked));
19
- this.internals?.setValidity(input.validity, this.validationMessage || input.validationMessage, this.shadowRoot?.querySelector(".track") || void 0);
20
20
  if (!this.novalidate) this.validate();
21
21
  this.relay(e);
22
22
  };
@@ -24,6 +24,9 @@ var USwitch = class USwitch extends UFormControlElement {
24
24
  static {
25
25
  this.styles = [super.styles, styles];
26
26
  }
27
+ shouldValidate(changed) {
28
+ return super.shouldValidate(changed) || changed.has("checked");
29
+ }
27
30
  render() {
28
31
  return html`
29
32
  <label class="wrapper" part="wrapper">
@@ -56,15 +59,14 @@ var USwitch = class USwitch extends UFormControlElement {
56
59
  </span>
57
60
  </label>
58
61
 
59
- <div class="description" ?hidden=${!this.description}>
60
- ${this.description}
62
+ <div class="description" ?hidden=${!(this.invalid && this.validationMessage) && !this.description}>
63
+ ${this.invalid && this.validationMessage ? this.validationMessage : this.description}
61
64
  </div>
62
65
  `;
63
66
  }
64
- validate() {
65
- if (this.internals) this.invalid = !this.internals.reportValidity();
66
- else this.invalid = this.required && !this.checked;
67
- return !this.invalid;
67
+ setValidity() {
68
+ const missing = !!this.inputEl?.validity.valueMissing;
69
+ this.commit(missing ? { valueMissing: true } : {}, missing ? Locale.getValue("valueMissing") : "", this.shadowRoot?.querySelector(".track") ?? void 0);
68
70
  }
69
71
  reset() {
70
72
  this.checked = false;
@@ -75,6 +77,7 @@ __decorate([property({
75
77
  type: Boolean,
76
78
  reflect: true
77
79
  }), __decorateMetadata("design:type", Boolean)], USwitch.prototype, "checked", void 0);
80
+ __decorate([query("input", true), __decorateMetadata("design:type", typeof HTMLInputElement === "undefined" ? Object : HTMLInputElement)], USwitch.prototype, "inputEl", void 0);
78
81
  USwitch = __decorate([customElement("u-switch")], USwitch);
79
82
  //#endregion
80
83
  export { USwitch };
@@ -5,7 +5,7 @@ var styles = css`
5
5
  --switch-track-width: 2.4em;
6
6
  --switch-track-height: 1.4em;
7
7
  --switch-track-color: var(--u-neutral-300);
8
- --switch-track-color-checked: var(--u-blue-600);
8
+ --switch-track-color-checked: var(--u-primary-color, var(--u-blue-600));
9
9
  --switch-thumb-size: 1.1em;
10
10
  --switch-thumb-offset: 0.15em;
11
11
  --switch-thumb-color: #fff;
@@ -186,6 +186,10 @@ var styles = css`
186
186
  font-size: 0.75em;
187
187
  line-height: 1.3;
188
188
  }
189
+
190
+ :host([invalid]) .description {
191
+ color: var(--u-red-600);
192
+ }
189
193
  `;
190
194
  //#endregion
191
195
  export { styles };
@@ -1,11 +1,11 @@
1
1
  import { UElement } from "../UElement.js";
2
2
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/decorateMetadata.js";
3
3
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/decorate.js";
4
- import "../icon/UIcon.js";
5
4
  import "../button/UButton.js";
5
+ import "../icon/UIcon.js";
6
6
  import { styles } from "./UTab.styles.js";
7
- import { customElement, property } from "lit/decorators.js";
8
7
  import { html } from "lit";
8
+ import { customElement, property } from "lit/decorators.js";
9
9
  //#region src/components/tab/UTab.ts
10
10
  var UTab = class UTab extends UElement {
11
11
  constructor(..._args) {
@@ -17,7 +17,10 @@ var UTab = class UTab extends UElement {
17
17
  this.handleRemoveClick = (e) => {
18
18
  e.stopPropagation();
19
19
  if (this.disabled) return;
20
- if (this.fire("remove")) this.remove();
20
+ if (this.fire("remove", {
21
+ bubbles: false,
22
+ composed: false
23
+ })) this.remove();
21
24
  };
22
25
  }
23
26
  static {
@@ -12,6 +12,10 @@ export type TabPanelPlacement = 'top' | 'bottom' | 'left' | 'right';
12
12
  * @csspart nav - 탭 버튼들이 실제로 배치되는 네비게이션 영역
13
13
  * @csspart toolbar - 탭 헤더 내 툴바 영역
14
14
  * @csspart content - 탭 패널이 있는 콘텐츠 영역
15
+ *
16
+ * @event change - 탭을 클릭하거나 키보드로 선택했을 때만 발생한다. 최초 마운트 시 첫 탭이
17
+ * 자동 선택되는 경우나 `value` 프로퍼티를 직접 대입하는 경우는 사용자 조작이 아니므로
18
+ * 발생시키지 않는다(네이티브 select가 프로그래밍적 대입에는 change를 내지 않는 것과 동일한 관례).
15
19
  */
16
20
  export declare class UTabPanel extends UElement {
17
21
  static styles: import('lit').CSSResultGroup[];
@@ -31,6 +35,7 @@ export declare class UTabPanel extends UElement {
31
35
  private get isVertical();
32
36
  protected willUpdate(changedProperties: PropertyValues): void;
33
37
  render(): import('lit-html').TemplateResult<1>;
38
+ private change;
34
39
  private updateTabPanel;
35
40
  private handleSlotChange;
36
41
  private handleTabSlotChange;
@@ -4,8 +4,8 @@ import __decorate from "../../_virtual/_@oxc-project_runtime@0.138.0/helpers/esm
4
4
  import { UPanel } from "../panel/UPanel.js";
5
5
  import { UTab } from "../tab/UTab.js";
6
6
  import { styles } from "./UTabPanel.styles.js";
7
- import { customElement, property, state } from "lit/decorators.js";
8
7
  import { html } from "lit";
8
+ import { customElement, property, state } from "lit/decorators.js";
9
9
  //#region src/components/tab-panel/UTabPanel.ts
10
10
  var UTabPanel = class UTabPanel extends UElement {
11
11
  constructor(..._args) {
@@ -40,7 +40,7 @@ var UTabPanel = class UTabPanel extends UElement {
40
40
  this.handleTabClick = (e) => {
41
41
  const tab = e.currentTarget || e.target;
42
42
  if (tab.disabled || this.disabled) return;
43
- this.value = tab.value;
43
+ this.change(tab.value);
44
44
  };
45
45
  this.handleTabKeydown = (e) => {
46
46
  const enabledTabs = this.tabs.filter((t) => !t.disabled);
@@ -62,14 +62,14 @@ var UTabPanel = class UTabPanel extends UElement {
62
62
  break;
63
63
  case "Enter":
64
64
  case " ":
65
- this.value = enabledTabs[currentIndex].value;
65
+ this.change(enabledTabs[currentIndex].value);
66
66
  return;
67
67
  default: return;
68
68
  }
69
69
  if (targetIndex >= 0) {
70
70
  e.preventDefault();
71
71
  enabledTabs[targetIndex].focus();
72
- this.value = enabledTabs[targetIndex].value;
72
+ this.change(enabledTabs[targetIndex].value);
73
73
  }
74
74
  };
75
75
  this.handleNavWheel = (e) => {
@@ -111,6 +111,14 @@ var UTabPanel = class UTabPanel extends UElement {
111
111
  </div>
112
112
  `;
113
113
  }
114
+ change(value) {
115
+ if (this.value === value) return;
116
+ this.value = value;
117
+ this.fire("change", {
118
+ bubbles: false,
119
+ composed: false
120
+ });
121
+ }
114
122
  updateTabPanel() {
115
123
  this.tabs.forEach((tab) => {
116
124
  tab.toggleAttribute("active", tab.value === this.value);