@iyulab/components 1.2.1 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.3.3] - 2026-07-03
4
+
5
+ ### Fixed
6
+ - `UCheckbox`: 클래스 JSDoc에 `@event change` 태그 누락으로 공식 React 래퍼(`@iyulab/components/react`)의 `UCheckbox` props가 빈 `{}`로 생성되어 `onChange`가 노출되지 않던 결함 수정. 런타임은 `this.relay(e)`로 `change`를 정상 발생시키지만, 래퍼 생성기가 `@event` 태그(또는 `this.fire<T>('name')` 리터럴)로만 이벤트 맵을 도출하므로 태그가 없으면 이벤트가 누락된다. (`USwitch`/`UInput`/`UTextarea`는 태그 보유 — `relay()`를 쓰는 폼 컨트롤 중 `UCheckbox`만 누락되어 있었음.) yesung-oms dogfooding에서 발견.
7
+
8
+ ### Changed
9
+ - `plugins/vite-plugin-react-wrapper.ts`: `@customElement` 컴포넌트가 `this.relay(...)`/`this.dispatchEvent(...)`로 이벤트를 발생시키지만 수집된 이벤트가 0건이면 빌드 시 경고를 출력하도록 개선 — 위 `UCheckbox`류의 "태그 누락으로 이벤트가 조용히 사라지는" 결함 재발 방지. (`this.fire<T>('name')`은 이름이 정적으로 잡히므로 경고 대상이 아님.)
10
+
11
+ ## [1.3.2] - 2026-07-02
12
+
13
+ ### Documentation
14
+ - `docs/form-controls.md`: `UCheckbox`의 `label` attribute가 다른 폼 컨트롤과 달리 default slot의 fallback content로 쓰인다는 점(slot이 있으면 attribute보다 우선)을 "Common Properties" 표 아래에 명시.
15
+
16
+ ## [1.3.1] - 2026-07-02
17
+
18
+ ### Added
19
+ - `UInput`: `--u-input-display` CSS 커스텀 프로퍼티 추가(기본값 `inline-block`, 기존과 동일). 폼/그리드 셀에서 전체 폭을 채우려는 소비자는 `u-input { --u-input-display: block; }`로 오버라이드 가능 — 이전에는 전역 `u-input{ display:block; width:100% }` 같은 하드코딩 우회가 필요했다.
20
+
21
+ ## [1.3.0] - 2026-07-02
22
+
23
+ ### Fixed
24
+ - `UFloatingElement.strategy`에 `reflect: true` 누락 수정 — JS로 `.strategy = 'fixed'`를 설정해도 host 속성이 갱신되지 않아 `:host([strategy="fixed"])` CSS 셀렉터가 매치되지 않던 버그.
25
+
26
+ ### Changed
27
+ - `USelect` 내부 `<u-popover>`의 기본 위치 전략을 `strategy="fixed"`로 변경. 기존 `absolute` 기본값은 `UDrawer` body(`overflow:auto`)처럼 스크롤 컨테이너 안에 `u-select`가 놓이면 팝오버가 잘리는 문제가 있었다(흔한 "폼 드로어 + 셀렉트" 조합에서 재현). `fixed`는 뷰포트 기준으로 그려져 조상의 `overflow`에 클리핑되지 않으며, `@floating-ui/dom`의 `autoUpdate`가 스크롤/리사이즈 시 위치를 계속 재계산하므로 기존 동작과 시각적으로 동일하게 보인다.
28
+
3
29
  ## [1.2.1] - 2026-07-02
4
30
 
5
31
  ### Fixed
package/README.md CHANGED
@@ -100,6 +100,7 @@ Theme.set('system');
100
100
  | [docs/theming.md](./docs/theming.md) | 테마 및 CSS 변수 |
101
101
  | [docs/form-controls.md](./docs/form-controls.md) | 폼 연동 및 검증 API |
102
102
  | [docs/icons.md](./docs/icons.md) | 아이콘 등록 및 사용 |
103
+ | [docs/native-event.md](./docs/native-event.md) | 컴포넌트가 다루는 네이티브 DOM 이벤트 목록 |
103
104
 
104
105
  ## License
105
106
 
@@ -220,7 +220,10 @@ __decorate([property({
220
220
  type: String,
221
221
  reflect: true
222
222
  }), __decorateMetadata("design:type", String)], UFloatingElement.prototype, "for", void 0);
223
- __decorate([property({ type: String }), __decorateMetadata("design:type", Object)], UFloatingElement.prototype, "strategy", void 0);
223
+ __decorate([property({
224
+ type: String,
225
+ reflect: true
226
+ }), __decorateMetadata("design:type", Object)], UFloatingElement.prototype, "strategy", void 0);
224
227
  __decorate([property({ type: String }), __decorateMetadata("design:type", Object)], UFloatingElement.prototype, "placement", void 0);
225
228
  __decorate([property({ type: Number }), __decorateMetadata("design:type", Object)], UFloatingElement.prototype, "offset", void 0);
226
229
  __decorate([property({ type: Boolean }), __decorateMetadata("design:type", Boolean)], UFloatingElement.prototype, "shift", void 0);
@@ -16,6 +16,8 @@ export type CheckboxColor = "blue" | "green" | "red" | "orange" | "teal" | "cyan
16
16
  * @cssprop --checkbox-color - 체크 표시 색상 (outline variant)
17
17
  * @cssprop --checkbox-border-color - 체크박스 테두리 색상
18
18
  * @cssprop --checkbox-background-color - 체크박스 배경색 (filled variant)
19
+ *
20
+ * @event change - 체크 상태 변경 시 발생
19
21
  */
20
22
  export declare class UCheckbox extends UFormControlElement<string> {
21
23
  static styles: import('lit').CSSResultGroup[];
@@ -10,7 +10,7 @@ var styles = css`
10
10
 
11
11
  :host {
12
12
  position: relative;
13
- display: inline-block;
13
+ display: var(--u-input-display, inline-block);
14
14
  color: var(--u-txt-color);
15
15
  font-size: inherit;
16
16
  font-family: var(--u-font-base);
@@ -180,6 +180,7 @@ var USelect = class USelect extends UFormControlElement {
180
180
  trigger="click"
181
181
  placement="bottom-start"
182
182
  offset="1"
183
+ strategy="fixed"
183
184
  @show=${this.handlePopoverEvent}
184
185
  @hide=${this.handlePopoverEvent}
185
186
  >
@@ -3,6 +3,7 @@ import { UCheckbox as UCheckboxElement } from '../components/checkbox/UCheckbox'
3
3
 
4
4
  export declare const UCheckbox: React.ForwardRefExoticComponent<
5
5
  Partial<UCheckboxElement> & React.HTMLAttributes<UCheckboxElement> & {
6
+ onChange?: (event: CustomEvent) => void;
6
7
  }
7
8
  >;
8
9
 
@@ -6,5 +6,7 @@ export const UCheckbox = createComponent({
6
6
  react: React,
7
7
  tagName: 'u-checkbox',
8
8
  elementClass: UCheckboxElement,
9
- events: {},
9
+ events: {
10
+ onChange: 'change',
11
+ },
10
12
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@iyulab/components",
3
3
  "description": "web-components library based on lit-element made by iyulab",
4
- "version": "1.2.1",
4
+ "version": "1.3.3",
5
5
  "keywords": [
6
6
  "iyulab",
7
7
  "components",
@@ -42,6 +42,7 @@
42
42
  "dev": "vite --force",
43
43
  "test": "vitest run",
44
44
  "test:watch": "vitest",
45
+ "test:browser": "vitest run --project=browser",
45
46
  "build:plugins": "tsc -p plugins/tsconfig.json",
46
47
  "build": "eslint && vite build && npm run build:plugins"
47
48
  },
@@ -65,6 +66,7 @@
65
66
  "devDependencies": {
66
67
  "@eslint/js": "^9.39.4",
67
68
  "@types/node": "^25.8.0",
69
+ "@vitest/browser-playwright": "^4.1.8",
68
70
  "eslint": "^9.39.4",
69
71
  "eslint-plugin-lit": "^2.3.1",
70
72
  "glob": "^13.0.6",
@@ -63,6 +63,14 @@ function parseComponent(filePath) {
63
63
  if (!classMatch)
64
64
  return [];
65
65
  const events = collectEvents(content);
66
+ // 이벤트를 발생시키지만(relay/dispatchEvent) 정적으로 이름을 도출할 수 없는 컴포넌트가
67
+ // @event 태그도 없으면 events 맵이 빈 채로 생성되어 React 소비자가 이벤트를 구독할 수 없다.
68
+ // (this.fire<T>('name')은 이름이 문자열 리터럴로 잡히므로 이 경고 대상이 아님)
69
+ if (events.length === 0 && /this\.(relay|dispatchEvent)\s*\(/.test(content)) {
70
+ console.warn(`\x1b[33m[react-wrapper]\x1b[0m ${classMatch[1]} (${tagMatch[1]}): ` +
71
+ `이벤트를 발생시키지만(relay/dispatchEvent) @event 태그가 없어 React 래퍼에 이벤트 prop이 노출되지 않습니다. ` +
72
+ `클래스 JSDoc에 '@event <name>'을 추가하세요.`);
73
+ }
66
74
  return [{
67
75
  className: classMatch[1],
68
76
  tagName: tagMatch[1],