# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).

## [0.16.2] - 2026-08-25

### Added

- Agent-skill reference docs (`skills/iyulab-u-widgets/`) — the `<u-widget spec="...">` usage
  pattern, the full widget catalog (`widget` value → element → description), events, and the
  complete `--u-widget-*` CSS Custom Properties token sheet.

## [0.16.1] - 2026-08-12

### Fixed

- **Published `.d.ts` declarations were broken for 16 of the 17 registered custom elements,
  across all 6 build entries.** The dts bundler strips `declare global` blocks (which hold each
  element's `HTMLElementTagNameMap` entry) and a build-time patch step was meant to restore
  them, but its guard only recognized the one element it had originally been written for and
  silently skipped the rest, leaving orphaned/broken global declarations behind. The patch now
  detects and restores every stripped block (brace-depth aware, not a single string match),
  covers all 17 elements, and runs against every build entry. `uw-chart` and `uw-math` are now
  typed with their real exported classes instead of a generic `HTMLElement`.

## [0.16.0] - 2026-08-11

### Added

- **A rem-based typography scale**: `--u-widget-font-size-label` (0.8125rem), `-caption`
  (0.75rem), `-overline` (0.6875rem), alongside the existing `--u-widget-font-size` (body,
  0.875rem). Every element previously hardcoded one of these four values directly in dozens of
  places; they now reference the shared tokens, so a host page can retune the whole scale (or
  a single tier) by setting one custom property instead of overriding each element's internal
  selectors. Values are unchanged — this is purely additive, no visual difference at defaults.
  The scale stays local to this package (not a reference to any other package's tokens), so
  `u-widgets` remains installable and themeable without any other design-system package
  present.

### Fixed

- **`@iyulab/components` is no longer a required peer dependency.** It was declared in 0.15.0
  but nothing in this package's source actually imports it or references its tokens — this
  package has always styled itself through its own local `--u-widget-*` custom properties.
  Installing `u-widgets` no longer requires installing (or satisfying a version range for) a
  package it does not use.

## [0.15.0] - 2026-08-05

### Changed

- ⚠**`@iyulab/components` is now a required peer dependency (`>=1.24.0`).** The token
  sheet is a runtime premise rather than a nicety — the styles reference it in 58 places,
  and installing without it lets the fallback literals quietly stand in for the theme.

  Consumers pinned to `@iyulab/components@1.23.x` will see an `ERESOLVE` on install.

### Fixed

- **`sideEffects` no longer misses part of the emitted entry points.** The declaration
  named four output files, but with multiple entries the bundler splits shared code —
  custom-element registrations included — into hash-named chunks that were not listed. A
  consumer's bundler could drop them and the widgets would never register, with no build
  error. It now covers `./dist/*.js`.

- **The `./themes/shadcn.css` subpath points back at the built output.** It had been
  rewritten to a source path, which does not exist in the published package.

## [0.14.1] - 2026-08-03

### Fixed

- **포커스 링·강조 배경이 브랜드 색을 따라가지 않던 문제** — 세 곳이 인디고 값을
  `rgba(79, 70, 229, …)` 리터럴로 굽고 있었다. `--u-widget-primary` 는 **테마마다 다른
  값**(라이트 `#4f46e5` / 다크 `#818cf8`)인데 리터럴은 그것을 모르므로, 다크에서
  테두리와 포커스 링이 서로 다른 인디고가 됐다. 소비자가 브랜드를 덮어도 따라오지 않았다.
  `color-mix()` 로 토큰에서 파생하도록 고쳤다(무효 오류 배경도 `--u-widget-negative` 기준).

## [0.14.0] - 2026-08-02

### Fixed

- ★**채움 버튼의 글자가 다크 테마에서 읽히지 않던 문제.** `[data-style="primary"]` ·
  `[data-style="danger"]` · 완료된 단계(`uw-steps`)가 `color: white` 를 유채색 면 위에
  칠하는데, 다크 팔레트는 그 색들을 **밝게** 만든다(다크 페이지에서 *글자*로 읽히게 하려고):

  ```
  흰 글자 대비 —  primary #818cf8  2.98 ✗   ·  negative #f87171  2.77 ✗
                 positive #4ade80  1.74 ✗            (AA 기준 4.5)
  ```

  한 토큰이 **면**과 **글자**를 겸할 수 없어서 생긴 결함이다. 전경을 토큰으로 분리하고
  테마에 따라 뒤집는다 — 아래 Added 참조. 라이트는 종전대로 흰색이다(6.29 / 4.83 / 5.02).

- **`--u-widget-positive` 가 라이트에서 AA 미달.** `#16a34a` 는 흰 바탕 대비 **3.30** 인데
  이 토큰은 틴트만이 아니라 **글자**로도 쓰인다(`uw-metric` 값, `uw-code` diff 표시).
  `#15803d`(**5.02**)로 한 단 내렸다.

- **`--u-widget-text-secondary` 가 표면 위에서 AA 미달.** `#64748b` 는 `--u-widget-bg`
  위에서는 4.76 으로 통과하지만 `--u-widget-surface`(`#f1f5f9`) 위에서는 **4.34** 였고,
  보조 텍스트는 표면 위에 놓이는 경우가 그만큼 많다. `#5b6777`(**5.25** / 바탕 5.75).

### Added

- **`--u-widget-on-primary` · `--u-widget-on-negative` · `--u-widget-on-positive`** —
  채움 면 위의 전경색. 라이트 `#ffffff` / 다크 `#1e1e2e`.
  브랜드를 바꿀 때 `--u-widget-primary` 와 **함께** 조정하면 된다. 종전에는 전경이
  리터럴이라 조정할 방법이 없었다.

### Known issues

- `--u-widget-border` 가 바탕 대비 **1.23**(라이트) · **1.59**(다크)로 WCAG 1.4.11(3.0)에
  미달한다. 무엇이 "UI 컴포넌트 경계"인지의 판단이 선행돼야 한다.

## [0.13.0] - 2026-07-16

### Added
- `chart.waterfall`: **행 단위 총계(total) 막대** 지원 — `mapping.total`(필드명)로 지정한 행은 절대 총계 막대로 `base=0`에서 그려지고 누적(running total)을 자기 값으로 리셋한다(선행 총계=개시 잔액, 후행 총계=마감 잔액). 지금까지 모든 행이 예외 없이 델타(증감)로 누적되어, 표준 waterfall 관례(첫·마지막 행은 절대 총계)를 따라 데이터를 넘기면 **마지막 총계 행이 `2×total` 높이로 그려지던** 결함(프로덕션 실재현 — 같은 지표가 게이지에서는 81.2%, waterfall 에서는 ~162 로 어긋남)을 해소. 총계 행 미지정 시 3-시리즈 출력이 byte-identical하게 유지되어 파괴적 변경이 없다. 총계 막대는 중립색(slate)으로 증감 막대와 시각 구분. schema mapping 검증 allowlist에도 `total` 반영. 실사용에서 관측.

### Fixed
- `echarts-adapter`: 축 config를 `options` 최상위(`options.xAxis`/`yAxis`)에 두면 조용히 무시되던 문제에 **dev 경고**를 추가 — `options.echarts.xAxis`(생성된 축 위에 재귀 deep-merge)로 유도한다. 축 라벨 제어(`axisLabel.interval`/`rotate` 등 긴 라벨 자동 소실 방지)는 `options.echarts` passthrough로 **이미 지원**되고 있었으나(문서·회귀 테스트로 명시), 최상위 경로로 넘기던 기존 소비자(`energy/transformer-loss` 등)의 값이 버려지고 있었다. `docs/widgets.md`에 waterfall total 매핑 + 축 라벨 제어 레시피 문서화, adapter의 "one level" 주석을 실제 재귀 deep-merge로 정정.

### Build
- `@microsoft/api-extractor`를 명시적 devDependency로 추가 — `vite-plugin-dts` v5에서 `bundleTypes`(선언 파일 번들)는 `@microsoft/api-extractor`를 optional peerDependency로 요구한다. 표준 `npm ci`(단독 저장소)에서 자동 설치되지 않아 번들이 조용히 per-file로 폴백(그리고 `afterBuild` 훅이 stale toolchain 조합에서 `dist/u-widgets.d.ts` 미생성으로 실패)하던 릴리스 정합 문제를 해소. 이제 v4 시절과 동일한 번들된 엔트리별 단일 `.d.ts`(`u-widgets.d.ts` 등)를 출력한다.

## [0.12.1] - 2026-07-13

### Fixed
- `chart.treemap`: **계층 데이터에서 부모 노드에 `value`를 생략하면 트리맵 전체가 빈 화면으로 렌더**되던 무음 결함 수정. `toTreeNode`가 `value: Number(item.value ?? 0)`으로 부모에 명시적 0을 주입해 ECharts가 children 합산 대신 면적 0으로 그렸다. value가 있을 때만 전달하고 합산은 ECharts에 맡긴다(leaf는 기존대로 0 기본값). e2e 렌더 커버리지 확장 중 데모 스크린샷 육안 검증에서 발견 — 캔버스 존재 검사로는 못 잡는 결함이라 픽셀 비율 e2e 가드 추가. 회귀 가드: 유닛(RED→GREEN) + e2e 픽셀 검사.
- `uw-metric`(stat-group): **항목 수가 많고 값이 긴 경우(예: 7항목 × 12자리 천단위 값) 값 텍스트가 이웃 셀 위로 겹쳐 판독 불가**하던 표시 결함 수정. 원인은 `flex: 1; min-width: 100px`(콘텐츠 무관 균등분할·shrink 허용) × `white-space: nowrap`(0.11.10) × overflow 미처리 조합. 셀에 `min-width: min(100%, max-content)`를 적용해 값보다 좁아질 수 없게 하고, 넘치는 항목은 다음 행으로 wrap한다. wrap 도입에 따라 `+` 셀렉터 구분선(한 줄 전제)이 둘째 행 선두에도 붙는 동반 결함을 클립 래퍼(음수 마진) 기법으로 함께 해결 — 구분선은 같은 행 인접 셀 사이에만 나타난다. 좁은 폭(≤30rem) 컬럼 모드는 기존 동작 유지. 알려진 한계: 단일 값이 위젯 전체 폭을 넘는 극단(60자+)은 위젯 경계에서 클립. 회귀 가드: e2e 바운딩 검사(7항목 × 12자리, RED→GREEN 검증) + 유닛 CSS 가드 + 데모 스트레스 카드. 실사용에서 관측.
- `README.md` React 예제: `widget: 'stat-group'`에 metric 형태의 객체 `data`를 넘겨 아무것도 렌더되지 않는 예제였던 것을 배열 data로 교정 (stat-group `data`는 배열 필수).
- `e2e/widgets.spec.ts` `deepShadowText` 헬퍼: `title`이 있는 스펙에서 첫 요소(`.widget-title`)만 보고 중첩 shadow 텍스트를 놓쳐 `confirm` 테스트가 오탐 실패하던 것을 호스트+전 shadow 자식 텍스트 합산으로 수정.
- `playwright.config.ts`: webServer 부팅 타임아웃 30s→120s — `vite --force` 콜드 부팅(의존성 사전번들 재생성)이 30s를 초과해 e2e가 서버 기동 단계에서 실패하던 문제.
- `src/types/jsx.ts`: `@typescript-eslint/no-namespace` 린트 에러 해소 — JSX 전역 증강은 namespace 선언만 가능하므로 사유 명시 인라인 disable.

## [0.12.0] - 2026-07-07

### Added
- `chart.*`: ECharts **CustomChart(custom series)** 등록 — `options.series[i].type: "custom"` 또는 `options.echarts` passthrough로 custom `renderItem`(Gantt/타임라인 등)을 주입하면 이제 바로 렌더된다. 기존에는 임의 series `type` 오버라이드를 허용하면서 CustomChart만 미등록이어서 `[ECharts] Series custom is used but not imported` 경고 후 무음 미렌더되던 비대칭을 해소. 실사용에서 관측 — 소비자 앱측 `use([CustomChart])` 워크어라운드 제거 가능.
- `uw-chart`/echarts-adapter: **미등록 series-type 어포던스 가드** 신설 — `options.series[i].type` 오버라이드와 `options.echarts.series[].type` passthrough가 미등록 series(`graph`/`sankey`/`gauge`/`sunburst` 등)를 요청하면, raw ECharts 경고 대신 u-widgets dev 경고 + `@iyulab/flex-chart` 리디렉트를 출력한다. 등록 series는 `bar`/`line`/`pie`/`scatter`/`radar`/`heatmap`/`boxplot`/`funnel`/`treemap`/`custom`. 컴포넌트 키 가드(`dataZoom`/`toolbox` 등)와 대칭 완성 — tree-shakeable 빌드의 false-affordance를 series 클래스까지 확장.
- `uw-table`: **컬럼 강조(`variant`)** — `UWidgetColumnDefinition`에 `variant?: 'success'|'warning'|'danger'|'info'|'neutral'` 추가. 지정 시 해당 컬럼 셀에 `font-weight:600` + `uw-metric`과 동일한 `--u-widget-*` 색 토큰을 적용해 핵심 열을 강조한다. 그동안 stat-group(`uw-metric`)만 `variant` 강조가 가능하고 `table`은 강조 렌더 경로가 없던 카탈로그 내 표현력 비대칭을 해소. 미등록 variant는 warn-once 후 default fallback. schema `columnDefinition`에도 반영. 실사용에서 관측.

### Fixed
- `tests/core/format.test.ts`: `formatValue(null)`이 빈 문자열을 기대하던 stale 테스트를 수정 — 0.11.x의 em-dash(`—`) null 렌더링(의도된 동작, JSDoc 문서화됨)과 불일치했다.

## [0.11.11] - 2026-07-03

### Documentation
- `README.md`에 `## React` 섹션 신설 — `@iyulab/u-widgets/react` 서브패스가 제공하는 공식 래퍼 `UWidget`(객체 `spec` prop·`onWidgetEvent` 타입드 이벤트·`UWidgetSpec/UWidgetEvent/UWidgetAction` 타입 re-export·peerDependency 안내)을 문서화. 그동안 `/react` 서브패스가 존재함에도 README에 전혀 노출되지 않아 소비자가 공식 래퍼를 발견하지 못했다.
- `## Framework Integration`의 Next.js 예제를 공식 래퍼 사용으로 교정 — 기존 예제는 `<u-widget spec={JSON.stringify(spec)} />` 손수 래퍼를 만들도록 안내해, 같은 패키지에 객체 spec·타입드 이벤트를 처리하는 공식 `UWidget` 래퍼가 있는데도 소비자를 수동 직렬화 우회로 유도하고 있었다.

## [0.11.10] - 2026-07-03

### Fixed
- `uw-metric`: 좁은 카드(모바일 2열 stat-group)에서 큰 통화 값(예: `₩5,122,661,618`)이 천단위 그룹 중간에서 줄바꿈되던 문제 수정. `.metric-value`에 `white-space: nowrap`을 지정해 한 줄을 유지하고, 이미 존재하던 `container: uw-metric / inline-size` 기준으로 카드 폭 티어(16rem → 1.25rem, 12rem → 1.05rem) container 쿼리를 추가해 좁은 카드에서 폰트를 줄여 맞춘다. `part="value"`가 노출되지만 `u-widget` 래퍼의 중첩 shadow DOM(exportparts 없음)에 막혀 소비자 `::part(value)` CSS로 도달 불가하므로 업스트림 수정. 실사용에서 관측.

## [0.11.9] - 2026-07-02

### Fixed
- `UWidgetColumnDefinition.format` 타입이 `currency:${string}` 형태를 허용하지 않아 JSDoc·런타임(`formatValue`)이 이미 지원하는 `"currency:KRW"` 같은 값을 지정할 때마다 `as unknown as` 캐스트가 필요했던 문제 수정 — 템플릿 리터럴 타입 추가(하위 호환)
- `uw-metric`의 `variant`가 유효하지 않은 값(예: `'default'`)을 받으면 타입 캐스트만 거쳐 조용히 no-op 렌더링되던 문제 — 알 수 없는 variant 값에 대해 콘솔 경고(값당 1회)를 추가하고 기본 스타일로 폴백

### Documentation
- `docs/widgets.md`에 `installGlobalThemeSync()` auto-run 동작(import 시점 자동 실행, `data-theme` 감시·전파 메커니즘) 문서화 — 기존에 문서화되지 않아 소비자가 동일 기능을 중복 구현하는 사례 발생

## [0.11.8] - 2026-06-11

### Fixed
- `theme-sync`: import 시점 자동 초기화가 SSR DOM shim 환경(@lit-labs/ssr 등)에서 throw하여 소비자 모듈 로드 자체가 실패하던 문제 수정 — `documentElement`/`querySelectorAll`/`MutationObserver` 부재 시 no-op으로 통과

### Added
- `options.echarts` passthrough에 미등록 ECharts 컴포넌트 키(`dataZoom`, `toolbox`, `title` 등)가 전달되면 키당 1회 콘솔 경고 출력 — 옵션은 병합되지만 런타임에 동작하지 않는 false affordance 방지. 헤비 인터랙션(zoom/pan/toolbox)은 `@iyulab/flex-chart`가 담당 예정

## [0.11.4] - 2026-05-07

### Fixed
- `uw-table`: `pageSize` 미설정 시 1,000행 초과 데이터를 자동으로 100건씩 페이지네이션. 기존에는 전체 행을 한 번에 DOM 마운트하여 대용량 데이터에서 성능 저하 발생. `spec.options.pageSize: 0`으로 명시한 기존 소비자는 영향 없음

## [0.4.0] - 2026-02-18

### Added

- **Widget: `code`** — Syntax-highlighted code display with built-in mini highlighter (12 languages), line numbers, line highlighting, copy button, scroll containment
- **Widget: `citation`** — Source/reference cards with title, URL, snippet, source; compact and numbered modes
- **Widget: `status`** — Inline status badges with 7 semantic variants (success, warning, error, info, pending, neutral, custom)
- **Widget: `steps`** — Multi-step progress indicator with vertical/horizontal layouts, 4 statuses (done, active, pending, error), compact mode
- **Widget: `rating`** — Star/heart/thumb rating with display-only and interactive modes, fractional values, hover preview
- **Widget: `video`** — HTML5 video player wrapper with controls, poster, autoplay (muted), loop, playsinline
- **Widget: `gallery`** — CSS Grid image gallery with lazy loading, figure/figcaption semantics, auto-fill responsive grid
- **Widget: `kv`** — Key-value pair display for structured data
- **Widget: `divider`** — Visual separator for compose layouts
- **Widget: `header`** — Section header for compose layouts
- **Compose:** `options.widths` for proportional grid column widths (fr/auto/stretch values)
- **Compose:** `collapsed` property on child specs for progressive disclosure via native `<details>/<summary>`
- **Metric:** Global `actions` support for display widgets
- **MCP Tools:** Full catalog, templates, and examples for all new widgets

### Fixed

- **Security:** `u-citation` now uses sanitized URL in `window.open` and event data
- **Code:** Fixed `highlightJSON` double-advance bug for `true`/`false`/`null` tokens
- **Rating:** Fixed thumb icon half-star rendering (rounds to nearest full/empty)
- **Steps:** Fixed horizontal layout ignoring `compact` option

### Changed

- Tools bundle budget raised from 10 KB to 12 KB (MCP-only, not in core budget)

## [0.3.3] - 2026-02-18

### Added

- **Accessibility:** `aria-invalid` for select, radio, checkbox, multiselect in forms
- **Accessibility:** `scope="col"` on markdown-generated table `<th>` elements
- **Accessibility:** `aria-live="polite"` on callout widgets
- **Accessibility:** `role="radiogroup"` / `role="group"` on form radio/checkbox/multiselect groups
- **Accessibility:** `role="region"` with `aria-label` on compose widget (when title present)
- **Accessibility:** Sortable table headers now keyboard-operable (`tabindex`, Enter/Space)
- **Theme:** CSS theme tokens (`--u-widget-*`) propagated to all 8 elements via shared `themeStyles`
- **i18n:** Intl API locale-aware formatting for percent, date, datetime values
- **Responsive:** Container query for `u-form` (compact layout at narrow widths)
- **DRY:** Common `isDateLikeString` utility extracted to `core/utils.ts`
- **Tests:** Bundle size budget regression tests (6 tests)
- **Tests:** Theme token verification tests (20 tests)

### Changed

- Bundle budget tests enforce: core < 5 KB, charts < 5 KB, tools < 5 KB, forms < 2 KB, shared < 4 KB (all gzip)

## [0.3.2] - 2026-02-18

### Added

- **Tests:** u-chart direct tests, pipeline integration tests, entry point tests
- **Form:** Textarea `minLength`/`maxLength` validation
- **Inference:** Date string detection (`isDateLikeString`) for auto x-axis mapping
- **Suggest:** Non-chart widget suggestions (progress, chart.area recommendations)
- **Image:** Lazy loading optimization (`loading="lazy"`)
- **Schema:** JSON schema `minLength`/`pattern` support
- **Catalog:** Enhanced `help()` with field type details
- **Inference:** Smart `inferPrimaryKey` for table/list
- **Suggest:** Mapping suggestions for all chart types

## [0.3.1] - 2026-02-18

### Fixed

- **Security:** XSS vulnerability in markdown parser — `javascript:`, `data:`, `vbscript:` URLs now blocked in links and image `src`
- **Security:** `sanitizeUrl` hardened against zero-width Unicode character bypass (`\u200B`, `\uFEFF`, etc.)
- **Form:** `number`/`range` input values now coerced to `Number` — fixes silent `min`/`max` validation skip
- **Form:** `<input type="datetime">` mapped to `datetime-local` — fixes browser fallback to plain text input
- **Form:** Enter key now triggers submit even when no explicit `submit` action is defined
- **Form:** `<label>` elements linked to inputs via `for`/`id` attributes for Shadow DOM accessibility
- **Form:** Removed redundant `?selected` binding on `<select>` options
- **Chart:** Added `ResizeObserver` to `u-chart` — charts now auto-resize when container dimensions change
- **Chart:** Fixed `radar` infer/adapter contract — `infer()` now returns `{ axis, y }` matching adapter expectations
- **Chart:** Waterfall chart uses `null` instead of `'-'` for empty bar slots (correct ECharts stacked bar behavior)
- **Table:** Numeric string values now sorted numerically (`"2" < "10"`) instead of alphabetically
- **Markdown:** Code block newlines preserved — `<br>` conversion no longer corrupts `<pre>` content
- **Validation:** `ARRAY_DATA`/`OBJECT_DATA` converted from string to `Set` — fixes substring false-positive matching

### Added

- **Markdown:** Ordered list support (`1. item` → `<ol><li>`)

## [0.3.0] - 2026-02-18

### Added

- **Developer tools entry point:** `u-widgets/tools` — separate bundle for programmatic APIs
  - `help(widget?)` — widget catalog with descriptions, mapping keys, and data shapes
  - `template(widget)` — minimal template spec generation for all widget types
  - `suggestMapping(data, widget?)` — data-driven widget and mapping recommendations
  - `autoSpec(data)` — one-call convenience to generate a complete spec from data
- **Widget name typo detection:** "Did you mean?" suggestions for unknown widget names using Levenshtein distance
  - `suggestWidget(name)` — exported utility function
  - Integrated into `<u-widget>` fallback card UI
- **Mapping validation warnings:** `validate()` now produces warnings when mapping fields reference data keys that don't exist
- **CDN bundle:** `unpkg` and `jsdelivr` fields in `package.json` for automatic CDN resolution

### Changed

- Tools APIs (`help`, `template`, `suggestMapping`, `autoSpec`) moved to `u-widgets/tools` entry point to keep core bundle within 4 KB budget
- Core bundle: 4.11 KB gzip (was 3.84 KB in v0.2.0)

## [0.2.0] - 2026-02-18

### Added

- **Chart types:** scatter (with bubble/size mapping), radar, heatmap, box plot, funnel, waterfall, treemap
- **Chart options:** `legend`, `grid`, `animate`, `colors`, `stacked`, `horizontal`, `smooth`, `donut`, `showLabel`, `referenceLines`, `echarts` passthrough
- **Content widgets:** `markdown`, `image`, `callout` (via `u-content` element)
- **Formdown integration:** `u-widgets/forms` entry point for `@formdown/core` parser
- **CSS theme system:** dark/light mode via CSS custom properties (`--u-widget-*`)
- **ECharts CSS theme integration:** axis, text, legend colors from CSS variables
- **Accessibility:**
  - ARIA attributes on form and table widgets
  - Keyboard navigation for table (roving tabindex, Arrow/Home/End, Enter/Space)
  - Keyboard navigation for list (roving tabindex)
  - Form keyboard support (Enter submit, Escape cancel, `aria-describedby`)
- **i18n:** locale registry, `locale` attribute on `<u-widget>`, template-based validation messages, per-field message override
- **Responsive:** CSS Container Query layouts on all components
- **Table:** sortable columns, pagination, search, compact mode
- **Form validation:** `required`, `maxLength`, `min`/`max`, `email` pattern
- **Composition:** `compose` widget with `stack`, `row`, `grid` layouts and `span`/`columns`
- **Error handling:** styled error card for invalid specs, data type validation messages
- **JSON Schema:** `schema/u-widget.schema.json` aligned with TypeScript types
- **CDN bundle:** IIFE build (`dist/u-widgets.global.js`) for `<script>` tag usage
- **JSDoc:** comprehensive documentation on all public API exports
- **E2E tests:** 27 Playwright tests across all widget types

### Changed

- Removed hardcoded `en-US` locale from `formatValue()` — respects browser/system locale
- Pagination tabindex reset via reactive `_focusedIdx` state
- Bundle split: `u-widgets` (core), `u-widgets/charts` (ECharts), `u-widgets/forms` (formdown)

### Fixed

- `package.json` exports `types` paths aligned with actual `.d.ts` filenames
- Heatmap performance: `Map` lookup instead of `findIndex`
- ECharts options deep merge for `echarts` passthrough

## [0.1.0] - 2026-02-15

### Added

- **Core widgets:** `metric`, `stat-group`, `gauge`, `progress`
- **Chart widgets:** `chart.bar`, `chart.line`, `chart.area`, `chart.pie`
- **Data widgets:** `table`, `list`
- **Input widgets:** `form`, `confirm`
- **Composition:** `compose` widget
- **Auto-inference:** mapping inferred from data shape when omitted
- **Format hints:** `number`, `currency`, `percent`, `date`, `datetime`, `bytes`
- **Events:** `u-widget-event` custom event with `submit`, `action`, `change`, `select` types
- **Formdown:** built-in lightweight parser for markdown-like form definitions
- **Spec validation:** `validate()` and `isWidgetSpec()` functions
- **Web Component:** single `<u-widget>` element with `spec` property and attribute binding
