@hjmds/design-contracts 1.10.0 → 1.11.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 (189) hide show
  1. package/dist/action-session.d.ts +47 -0
  2. package/dist/action-session.d.ts.map +1 -0
  3. package/dist/action-session.js +60 -0
  4. package/dist/action-session.js.map +1 -0
  5. package/dist/activity-heatmap.d.ts +22 -0
  6. package/dist/activity-heatmap.d.ts.map +1 -0
  7. package/dist/activity-heatmap.js +29 -0
  8. package/dist/activity-heatmap.js.map +1 -0
  9. package/dist/auth-screen.d.ts +4 -0
  10. package/dist/auth-screen.d.ts.map +1 -1
  11. package/dist/auth-screen.js +2 -0
  12. package/dist/auth-screen.js.map +1 -1
  13. package/dist/avatar-fallback.d.ts +25 -0
  14. package/dist/avatar-fallback.d.ts.map +1 -0
  15. package/dist/avatar-fallback.js +17 -0
  16. package/dist/avatar-fallback.js.map +1 -0
  17. package/dist/behaviors.d.ts +2 -2
  18. package/dist/bottom-navigation-defaults.d.ts +1 -1
  19. package/dist/bottom-navigation-defaults.d.ts.map +1 -1
  20. package/dist/bottom-navigation-defaults.js.map +1 -1
  21. package/dist/bottom-navigation.d.ts.map +1 -1
  22. package/dist/bottom-navigation.js +5 -1
  23. package/dist/bottom-navigation.js.map +1 -1
  24. package/dist/catalog.d.ts +29 -1
  25. package/dist/catalog.d.ts.map +1 -1
  26. package/dist/code-block.d.ts +23 -0
  27. package/dist/code-block.d.ts.map +1 -0
  28. package/dist/code-block.js +13 -0
  29. package/dist/code-block.js.map +1 -0
  30. package/dist/component-definitions.d.ts +2 -3
  31. package/dist/component-definitions.d.ts.map +1 -1
  32. package/dist/component-definitions.js +1 -2
  33. package/dist/component-definitions.js.map +1 -1
  34. package/dist/component-recipes.d.ts +25 -1
  35. package/dist/component-recipes.d.ts.map +1 -1
  36. package/dist/component-recipes.js +12 -1
  37. package/dist/component-recipes.js.map +1 -1
  38. package/dist/component-references.d.ts +0 -6
  39. package/dist/component-references.d.ts.map +1 -1
  40. package/dist/component-references.js +0 -5
  41. package/dist/component-references.js.map +1 -1
  42. package/dist/content-transition.d.ts +17 -0
  43. package/dist/content-transition.d.ts.map +1 -0
  44. package/dist/content-transition.js +15 -0
  45. package/dist/content-transition.js.map +1 -0
  46. package/dist/duration-field.d.ts +22 -0
  47. package/dist/duration-field.d.ts.map +1 -0
  48. package/dist/duration-field.js +20 -0
  49. package/dist/duration-field.js.map +1 -0
  50. package/dist/effect-surface.d.ts +29 -0
  51. package/dist/effect-surface.d.ts.map +1 -0
  52. package/dist/effect-surface.js +26 -0
  53. package/dist/effect-surface.js.map +1 -0
  54. package/dist/gooey-navigation.d.ts +13 -0
  55. package/dist/gooey-navigation.d.ts.map +1 -0
  56. package/dist/gooey-navigation.js +11 -0
  57. package/dist/gooey-navigation.js.map +1 -0
  58. package/dist/gravity-letters.d.ts +12 -0
  59. package/dist/gravity-letters.d.ts.map +1 -0
  60. package/dist/gravity-letters.js +11 -0
  61. package/dist/gravity-letters.js.map +1 -0
  62. package/dist/grid-reveal.d.ts +8 -0
  63. package/dist/grid-reveal.d.ts.map +1 -0
  64. package/dist/grid-reveal.js +5 -0
  65. package/dist/grid-reveal.js.map +1 -0
  66. package/dist/internal/object-validation.d.ts +3 -0
  67. package/dist/internal/object-validation.d.ts.map +1 -0
  68. package/dist/internal/object-validation.js +12 -0
  69. package/dist/internal/object-validation.js.map +1 -0
  70. package/dist/internal/thinking-orb/braid.d.ts.map +1 -1
  71. package/dist/internal/thinking-orb/braid.js +2 -9
  72. package/dist/internal/thinking-orb/braid.js.map +1 -1
  73. package/dist/internal/thinking-orb/core.d.ts +1 -0
  74. package/dist/internal/thinking-orb/core.d.ts.map +1 -1
  75. package/dist/internal/thinking-orb/core.js +12 -0
  76. package/dist/internal/thinking-orb/core.js.map +1 -1
  77. package/dist/internal/thinking-orb/presentation.d.ts +4 -0
  78. package/dist/internal/thinking-orb/presentation.d.ts.map +1 -0
  79. package/dist/internal/thinking-orb/presentation.js +28 -0
  80. package/dist/internal/thinking-orb/presentation.js.map +1 -0
  81. package/dist/internal/thinking-orb/ribbon.d.ts.map +1 -1
  82. package/dist/internal/thinking-orb/ribbon.js +2 -9
  83. package/dist/internal/thinking-orb/ribbon.js.map +1 -1
  84. package/dist/layout.d.ts +0 -5
  85. package/dist/layout.d.ts.map +1 -1
  86. package/dist/layout.js +0 -7
  87. package/dist/layout.js.map +1 -1
  88. package/dist/otp-field.d.ts +2 -0
  89. package/dist/otp-field.d.ts.map +1 -1
  90. package/dist/otp-field.js.map +1 -1
  91. package/dist/popover.d.ts.map +1 -1
  92. package/dist/popover.js +3 -12
  93. package/dist/popover.js.map +1 -1
  94. package/dist/reactions.d.ts +10 -0
  95. package/dist/reactions.d.ts.map +1 -0
  96. package/dist/reactions.js +20 -0
  97. package/dist/reactions.js.map +1 -0
  98. package/dist/scroll-progress.d.ts +8 -0
  99. package/dist/scroll-progress.d.ts.map +1 -0
  100. package/dist/scroll-progress.js +10 -0
  101. package/dist/scroll-progress.js.map +1 -0
  102. package/dist/task-list.d.ts +7 -0
  103. package/dist/task-list.d.ts.map +1 -0
  104. package/dist/task-list.js +4 -0
  105. package/dist/task-list.js.map +1 -0
  106. package/dist/theme-studio.d.ts +14 -0
  107. package/dist/theme-studio.d.ts.map +1 -0
  108. package/dist/theme-studio.js +16 -0
  109. package/dist/theme-studio.js.map +1 -0
  110. package/dist/thinking-orb.d.ts +4 -2
  111. package/dist/thinking-orb.d.ts.map +1 -1
  112. package/dist/thinking-orb.js +8 -3
  113. package/dist/thinking-orb.js.map +1 -1
  114. package/dist/toast-liquid.d.ts +4 -4
  115. package/dist/toast-liquid.d.ts.map +1 -1
  116. package/dist/toast-liquid.js +11 -10
  117. package/dist/toast-liquid.js.map +1 -1
  118. package/dist/toast.d.ts +4 -4
  119. package/dist/toast.d.ts.map +1 -1
  120. package/dist/toast.js +4 -3
  121. package/dist/toast.js.map +1 -1
  122. package/dist/tooltip.d.ts.map +1 -1
  123. package/dist/tooltip.js +3 -12
  124. package/dist/tooltip.js.map +1 -1
  125. package/dist/version.d.ts +1 -1
  126. package/dist/version.js +1 -1
  127. package/dist/version.js.map +1 -1
  128. package/dist/voice-note.d.ts +20 -0
  129. package/dist/voice-note.d.ts.map +1 -0
  130. package/dist/voice-note.js +16 -0
  131. package/dist/voice-note.js.map +1 -0
  132. package/docs/action-session.md +73 -0
  133. package/docs/activity-heatmap.md +32 -0
  134. package/docs/anchor.md +1 -1
  135. package/docs/auth-screen.md +44 -4
  136. package/docs/authoring-brief.md +5 -0
  137. package/docs/avatar-fallback.md +74 -0
  138. package/docs/bottom-navigation.md +16 -1
  139. package/docs/breadcrumb.md +1 -1
  140. package/docs/calendar.md +1 -1
  141. package/docs/cascader.md +1 -1
  142. package/docs/code-block.md +32 -0
  143. package/docs/command-palette.md +1 -1
  144. package/docs/compound-controls.md +83 -0
  145. package/docs/confirm-popover.md +1 -1
  146. package/docs/consumer-policy.md +30 -23
  147. package/docs/cross-platform-core-normalization.md +19 -21
  148. package/docs/data-table.md +8 -5
  149. package/docs/dialog.md +2 -0
  150. package/docs/effect-surface.md +50 -0
  151. package/docs/floating-action-button.md +1 -1
  152. package/docs/folder-preview.md +26 -0
  153. package/docs/generated/component-maturity.md +1 -1
  154. package/docs/generated/renderer-evidence.json +3 -3
  155. package/docs/generated/renderer-evidence.md +1 -1
  156. package/docs/generated/showcase-manifest.json +1 -1
  157. package/docs/gooey-navigation.md +36 -0
  158. package/docs/gravity-letters.md +26 -0
  159. package/docs/grid-reveal.md +11 -0
  160. package/docs/icon.md +26 -0
  161. package/docs/image.md +2 -2
  162. package/docs/layout.md +1 -2
  163. package/docs/migration-0.5.md +4 -1
  164. package/docs/migration-native-legacy-removal.md +59 -0
  165. package/docs/navigation-bar.md +28 -0
  166. package/docs/optional-adapters.md +24 -1
  167. package/docs/otp-field.md +15 -0
  168. package/docs/pagination.md +1 -1
  169. package/docs/popover.md +2 -2
  170. package/docs/product-adoption-1.4.md +7 -0
  171. package/docs/product-audit-2026-09-15.md +1 -1
  172. package/docs/provider-button.md +6 -3
  173. package/docs/rating.md +1 -1
  174. package/docs/react-native-completion.md +4 -4
  175. package/docs/screen-chrome.md +1 -1
  176. package/docs/scroll-progress.md +29 -0
  177. package/docs/sheet.md +2 -0
  178. package/docs/sidebar.md +6 -0
  179. package/docs/splitter.md +1 -1
  180. package/docs/step-player.md +16 -0
  181. package/docs/task-list.md +32 -0
  182. package/docs/theme-studio.md +13 -0
  183. package/docs/thinking-orb.md +9 -2
  184. package/docs/time-picker.md +1 -1
  185. package/docs/toast.md +8 -7
  186. package/docs/tour.md +1 -1
  187. package/docs/tree-select.md +2 -2
  188. package/docs/voice-note.md +19 -0
  189. package/package.json +91 -1
package/docs/rating.md CHANGED
@@ -65,7 +65,7 @@
65
65
 
66
66
  ## 2026-09-16: React/RN 작동 조합
67
67
 
68
- 명시 요청에 따라 `Patterns/Rating`에 정수/0.5점 입력과 읽기 전용 평균 표시를 추가했다.
68
+ 명시 요청에 따라 `컴포넌트/입력/Rating`에 정수/0.5점 입력과 읽기 전용 평균 표시를 추가했다.
69
69
  입력은 기존 Slider, 현재값과 평균 표시는 Statistic이며 별 모양 variant를 새로 만든 것은 아니다.
70
70
 
71
71
  - [Web 예제](../../../showcase/web/src/patterns/Rating.stories.tsx): `@hjmds/react/slider`,
@@ -113,9 +113,9 @@ Context 배선/정적 토큰 사용은 예제로 설명하며 BorderBeam은 모
113
113
  경로를 유지했다. Anchor는 문서·별도 스크롤 영역, section focus, reduced motion, fragment
114
114
  history와 동적 본문 관찰을 구현했다. Web 전용이며 Native wrapper를 추가하지 않았다.
115
115
  [Breadcrumb](./breadcrumb.md), [Pagination](./pagination.md), [Anchor](./anchor.md).
116
- - Patterns/WebNavigation은 125개 기록의 페이지별 목록 교체와 보관함 왕복을 제공한다.
116
+ - 갤러리/웹 탐색은 125개 기록의 페이지별 목록 교체와 보관함 왕복을 제공한다.
117
117
  경로 변경 후 사라진 링크 대신 새 본문으로 focus를 옮기며 초기 mount에서는 focus를 뺏지 않는다.
118
- Patterns/Anchor는 세 부분의 실제 읽기 가이드에서 목차·스크롤·focus를 연결한다.
118
+ 컴포넌트/탐색/Anchor는 세 부분의 실제 읽기 가이드에서 목차·스크롤·focus를 연결한다.
119
119
  - 탐색 묶음 `pnpm ci:check` exit 0: contracts 733, Web SSR 139 + browser 140,
120
120
  Native 268 = 패키지 테스트 1,280개. Showcase Web 19 / Native 1과 타입·문서·evidence·
121
121
  번들·정적 Storybook(Web 71 / contract-only 23 / unsupported 0)이 통과했다.
@@ -131,7 +131,7 @@ Context 배선/정적 토큰 사용은 예제로 설명하며 BorderBeam은 모
131
131
  바깥 pointer/Tab이 향한 곳을 그대로 두고, 자식 popover가 감싸는 Dialog보다 Escape를 먼저 받는다.
132
132
  [API와 근거](./popover.md). ConfirmPopover는 새 renderer가 아니라 Popover의 확인/취소 조합으로
133
133
  제공하고 파괴적 동작은 AlertDialog에 남긴다. [조합 근거](./confirm-popover.md).
134
- - Patterns/Popover는 필터 적용과 되돌릴 수 있는 보관 두 화면을 제공한다. 보관하면 트리거가
134
+ - 컴포넌트/오버레이/Popover는 필터 적용과 되돌릴 수 있는 보관 두 화면을 제공한다. 보관하면 트리거가
135
135
  사라지므로 제품이 초점을 보관 취소 버튼으로 옮기고, 초기 mount에서는 초점을 뺏지 않는다.
136
136
  - 묶음 종료 시 두 예산이 실측에서 걸려 근거와 함께 올렸다. contracts 루트 barrel은
137
137
  111.8 -> 112.3 kB gzip인데 모듈별로 재면 catalog.js +522 B(Popover·ConfirmPopover maturity
@@ -160,7 +160,7 @@ Context 배선/정적 토큰 사용은 예제로 설명하며 BorderBeam은 모
160
160
  - 브라우저(chromium) 검증 6개: 도킹·초점 가둠·스크롤 락과 flush 모서리, RTL `start` 미러링과
161
161
  wide 560px, 비모달의 살아 있는 페이지·내부 Escape만 dismiss, 사유별 단일 보고와 busy 중
162
162
  outside 차단, controlled owner의 busy 종료와 1회 완료, 320px·2배 글자에서 가로 넘침 없음.
163
- `Patterns/SidePanel`은 기록 편집(모달)과 도움말(비모달) 두 화면을 제공한다.
163
+ `컴포넌트/오버레이/Side Panel`은 기록 편집(모달)과 도움말(비모달) 두 화면을 제공한다.
164
164
  - 예산은 실측으로 넷을 조정했다. `./side-panel` 45.9 kB raw / 11.0 kB gzip(6 modules),
165
165
  `./overlays`는 modal.js 분리로 6→7 modules(81.2/16.7 kB, 의존성 추가 아님),
166
166
  루트는 36→38 modules(322.3/66.3 kB, 바이트 한도 그대로), `./styles.css`는 도킹·크기·footer
@@ -43,7 +43,7 @@ LTR/RTL, light/dark에서 hit target, 글자 범위, overflow, 제목 분리와
43
43
  검증한다. ref/heading/link, busy 중 중복 실행 방지와 폭/focus 보존, sticky footer 위
44
44
  마지막 본문 행동의 도달 가능성도 검사한다. 기본 SSR renderer fixture를 추가한다.
45
45
 
46
- `Patterns/Notification settings`는 Web/RN에서 동일 문구·선택·저장 상태를 합성한다.
46
+ `패턴/알림 설정`는 Web/RN에서 동일 문구·선택·저장 상태를 합성한다.
47
47
  행 제목과 스위치 문구가 중복되면 `labelVisibility="hidden"`을 사용한다. `label`은
48
48
  계속 필수이며 Web의 visually-hidden 텍스트와 Native의 accessibilityLabel로 남는다.
49
49
  Web List의 indented 구분선은 행 margin이 아닌 별도 선으로 그린다. 320px 조합에서
@@ -0,0 +1,29 @@
1
+ # Scroll progress
2
+
3
+ Reviewed: 2026-10-01. Both renderers expose `ScrollProgress` through `/scroll-progress`.
4
+ This extension composes canonical Progress; it does not introduce another range,
5
+ accessibility or drawing implementation. Use plain Progress for task completion.
6
+
7
+ Pass `label`, `metrics: {offset, contentSize, viewportSize}` and normal Progress
8
+ presentation options. Metrics are logical forward distances in one consistent unit.
9
+ The shared resolver clamps bounce/overscroll into 0–1. An unmeasured viewport returns
10
+ 0; content fitting a measured viewport returns 1. Negative sizes and nonfinite
11
+ numbers throw. Horizontal RTL hosts must normalize platform-specific offsets.
12
+
13
+ On Web use `const metrics = useScrollMetrics(host)` with the actual vertical
14
+ scrolling HTMLElement stored by a callback ref. No implicit window listener is
15
+ installed. Scroll events are batched per animation frame; ResizeObserver and DOM
16
+ changes update the content extent. The hook disconnects when the host changes.
17
+
18
+ On Native feed `onScroll` contentOffset.y, `onContentSizeChange` height, and
19
+ `onLayout` viewport height from the product's ScrollView. Keep the product's
20
+ existing callbacks and gesture handling. The renderer adds no scroll responder.
21
+ Both showcases contain `컴포넌트/피드백/Scroll Progress` with working scroll
22
+ content. Updates are continuous range values, not repeated live announcements.
23
+
24
+ Regression checks cover overscroll, unknown/fitting dimensions, actual browser
25
+ scroll/content resize and Native canonical Progress values. The [Native integration audit](../../../docs/evidence/native-visual-integration-2026-10-01/README.md)
26
+ records Default/Dark/LargeText initial-view captures on the existing iPhone 17 / iOS 27
27
+ simulator. The subsequent [component flow audit](../../../docs/evidence/component-flows-2026-10-01/README.md)
28
+ verifies real LargeText swipes from 0% to 100% and back to 87%, with captures and
29
+ accessibility snapshots. VoiceOver speech and physical-device performance remain unverified.
package/docs/sheet.md CHANGED
@@ -61,3 +61,5 @@ focus/dismiss와 텍스트 배치 회귀를 직접 확인하도록 위 테스트
61
61
 
62
62
  참조: [React Native Keyboard](https://reactnative.dev/docs/keyboard),
63
63
  [ScrollView](https://reactnative.dev/docs/scrollview).
64
+
65
+ Native accessibility follow-up (2026-10-01): at 200% text scale, the close glyph was clipped inside the fixed IconButton frame. Dialog and Sheet now render that decorative glyph at a fixed icon size, matching Toast; title/body text still scales and the named close action and touch target are preserved. `sheet-viewport.test.tsx` checks both renderers and close callbacks.
package/docs/sidebar.md CHANGED
@@ -31,3 +31,9 @@
31
31
 
32
32
  **Web 전용.** 폰은 BottomNavigation을 쓰고, 네이티브 태블릿의 split view는 navigator의
33
33
  문제다.
34
+
35
+ ## 선택형 Web 표현 — 2026-10-01
36
+
37
+ `appearance`는 standard(기본), bounce, hook, proximity를 지원한다. bounce는 새로 선택한 항목의 아이콘에 한 번만 적용하고, hook은 선택 항목의 시작 쪽 곡선 경계를 강조한다. proximity는 마우스/펜의 세로 거리에 따라 아이콘만 최대 18% 확대한다. 링크 경계와 키보드 순서는 변하지 않는다. 터치는 근접 효과를 만들지 않는다. HJM provider의 모션 줄이기에서 동적 표현을 끄며, provider 없이도 기본 정적 탐색은 가능하다.
38
+
39
+ 독립적으로 구현한 제한된 표현이다. 원본 사이트의 모션 엔진을 복제하지 않았다. Web 전용이라는 기존 지원 범위를 유지하며 Native에서 새 사이드바를 만들지 않는다. Storybook `컴포넌트/탐색/Sidebar Motion`의 Default/Dark/LargeText에서 네 가지 표현과 접기를 비교한다. 기존 앱 셸 예제는 컴포넌트/탐색/Sidebar에 남는다.
package/docs/splitter.md CHANGED
@@ -69,7 +69,7 @@ Native `unsupported`다. 제품 채택과 실제 보조기기 실측은 승격
69
69
  인자 평가까지 통째로 건너뛰어 키보드 조절이 조용히 죽는다. commit을 먼저 하고 알린다.
70
70
  - 로컬 검증: `test/splitter.browser.test.tsx` 6개(separator 의미·수직 방향과 44px hit
71
71
  target, 방향키 step과 Home/End 경계, 드래그 스냅과 드래그당 1회 end, RTL 드래그·키보드,
72
- disabled, 실제 Tab focus와 focused keyboard resize)와 `Patterns/Splitter`.
72
+ disabled, 실제 Tab focus와 focused keyboard resize)와 `컴포넌트/레이아웃/Splitter`.
73
73
 
74
74
  **검증 범위.** Web Chromium renderer matrix가 긴 pane 콘텐츠·환경·접근성 증거를 제공한다.
75
75
  제품 vertical slice, screen reader 실측, 모든 OS 조합은 보증하지 않으며 소비 앱 릴리스 QA에서 확인한다.
@@ -0,0 +1,16 @@
1
+ # StepPlayer
2
+
3
+ 검토일: 2026-10-01.
4
+
5
+ `@hjmds/react/step-player`, `@hjmds/react-native/step-player`는 기존 Steps, Progress, Button을 합성한다. 별도 단계 상태 머신이나 재생 엔진을 두지 않는다. 사용자가 요청한 단계형 소개와 미디어는 서로 다른 시계를 사용하므로 호스트가 현재 위치와 재생 상태를 소유한다.
6
+
7
+ - `descriptor`, `statusLabels`, `composeAccessibleName`: 기존 Steps 계약 그대로.
8
+ - `progress`: 전체 재생 진행률 0~1. `playing`: 실제 호스트 재생 여부.
9
+ - `onPlayingChange`: 재생/일시정지 요청. 콜백 호출 자체로 내부 상태를 바꾸지 않는다.
10
+ - `onReplay`: 호스트가 현재 단계와 진행률을 초기화하고 재생 정책을 결정한다.
11
+ - `labels`: 번역된 play/pause/replay/progress 문구. `disabled`는 두 동작을 비활성화한다.
12
+ - `children`: 현재 단계의 실제 콘텐츠. 모션은 기존 ContentTransition 등으로 합성한다.
13
+
14
+ 완료 시 마지막 단계와 progress=1을 전달하고 재생 여부를 false로 바꾼다. 실제 비동기 작업의 완료를 타이머로 추정하는 용도가 아니다. 재생 종료/탐색 이탈/백그라운드 정지는 호스트 책임이다. 모션 줄이기는 콘텐츠 전환을 줄이며 사용자가 요청한 재생 자체를 막지 않는다.
15
+
16
+ 양쪽 Storybook `컴포넌트/피드백/Step Player`에 Default/Dark/LargeText를 제공한다. 예제만 사용자가 시작하는 6초 소개 시계를 가지며, 브라우저 숨김 또는 Native AppState 비활성에서 정지한다. 실제 서비스의 작업 진행이나 저장 완료를 주장하지 않는다.
@@ -0,0 +1,32 @@
1
+ # Task list
2
+
3
+ Reviewed: 2026-10-01. Web and Native expose TaskList through `/task-list`.
4
+ TaskList composes existing List and Checkbox rather than creating another selection
5
+ or gesture engine. Each controlled item has unique `id`, localized `label`, boolean
6
+ `completed`, optional `description` and `disabled`. Invalid identity/completion data
7
+ throws. Pass a localized list `label` and `onCompletedChange(id, completed)`; the
8
+ product accepts the requested change and owns saving, errors and rollback.
9
+
10
+ `emptyContent` is product-localized content when there are no tasks. `disabled`
11
+ disables every checkbox. Checking a task never reorders or removes it automatically.
12
+
13
+ For reordering, supply `renderCollection({items, renderItem})` and compose the
14
+ existing optional SortableCollection. Pass its localized labels and accept its
15
+ `orderedIds` in product state. Map its SortableItem back to the TaskItem by ID before
16
+ calling `renderItem`. The host propagates any global disabled/active state to that
17
+ collection; TaskList continues to control checkbox disabled state. This slot keeps
18
+ DND peers out of the plain TaskList import graph, while the existing adapter owns
19
+ keyboard/drag/cancellation/accessibility behavior.
20
+
21
+ Both showcases register 컴포넌트/입력/Task List with Default, Dark and LargeText
22
+ and working controlled completion/reordering. Web tests exercise actual checkbox
23
+ interaction; Native tests check controlled intent and disabled props. Device drag,
24
+ focus and screen-reader verification remain pending.
25
+
26
+ ## Native enlarged selection marks
27
+
28
+ The 2026-10-01 [device flow audit](../../../docs/evidence/component-flows-2026-10-01/README.md)
29
+ found that 200% text scaling enlarged Checkbox's decorative mark beyond its fixed box.
30
+ Native Checkbox now keeps the checked/mixed artwork at the recipe typography size
31
+ while its label and description continue scaling. TaskList inherits this correction
32
+ through Checkbox; it does not provide a second selection indicator.
@@ -0,0 +1,13 @@
1
+ # Theme studio
2
+
3
+ 검토일: 2026-10-01.
4
+
5
+ `@hjmds/design-contracts/theme-studio`는 기존 provider의 brandPalette와 색 대비 계산을 재사용하는 작업 도구다. 새로운 테마 엔진이나 자동 색상 생성기는 아니다.
6
+
7
+ - `applyStudioColor`는 light/dark별 primary, onPrimary, contentBrand 역할에 여섯 자리 HEX를 적용하며 기존 입력 객체를 변경하지 않는다.
8
+ - `studioReport`는 HJM 기본 팔레트에 override를 합친 뒤 기존 paletteContrastRules의 각 색상 쌍에 정확한 ratio·minimum·pass를 반환한다. 표시할 때만 소수점을 줄이고 통과 판정은 원래 값으로 한다.
9
+ - `exportStudioPalette`는 실제 설정을 `{brandPalette: ...}` JSON으로 직렬화한다. 소비 제품 기본값이나 중앙 토큰을 수정하지 않는다.
10
+
11
+ Web/Native Storybook `디자인 기초/테마 편집`에서 Default/Dark/LargeText 예제를 제공한다. 양쪽 테마를 동시에 비교하고 버튼·입력·disabled·오류, Lucide 의미 아이콘, 안내·성공·주의 알림을 확인할 수 있다. 기록 데이터는 Web DataTable, Native List로 비교한다. Native에 없는 DataTable을 새로 흉내 내지 않고 기존 읽기 순서와 의미를 유지한다. Web은 JSON 파일 다운로드, Native는 OS 공유와 선택 가능한 코드 표시를 제공한다. 공개 API에는 번역 문구를 넣지 않으며 라벨과 오류 안내는 showcase가 소유한다.
12
+
13
+ 색상 쌍 통과는 전체 접근성 인증이 아니다. 웹 버튼의 hover/focus는 실제 상호작용으로 확인하며, 실제 제품 배경과 보조기기 사용성은 별도 확인해야 한다. 서체 비교·라이선스 입력은 별도 후속 구현이다.
@@ -1,6 +1,6 @@
1
1
  # ThinkingOrb — AI 작업 상태
2
2
 
3
- 검토일: 2026-09-29. 원본: [Thinking Orbs](https://github.com/Jakubantalik/thinking-orbs/tree/de85557ca220332586d070d8788c0e1d6e877a0d), MIT.
3
+ 검토일: 2026-10-01. 원본: [Thinking Orbs](https://github.com/Jakubantalik/thinking-orbs/tree/de85557ca220332586d070d8788c0e1d6e877a0d), MIT.
4
4
 
5
5
  ## 결정과 범위
6
6
 
@@ -22,6 +22,7 @@
22
22
 
23
23
  - `state`: working, searching, solving, listening, connecting, weaving, composing, breathing, shaping.
24
24
  실제 상태를 앱에서 전달한다. listening은 음성 크기에 반응하는 오디오 시각화가 아니다.
25
+ - `appearance`: 기본 `state`는 상태별 원본 기하를 유지한다. `fluid`는 물결치는 점 고리, `matrix`는 원형 점 격자로 독립 구현한 표현이다. 실제 진행률이나 음성 신호를 나타내지 않으며 기존 정지·가시성·모션 줄이기 규칙을 공유한다.
25
26
  - `size`: 20 또는 64. 원본의 점 수·반지름 튜닝을 유지하며 임의 CSS 확대는 지원하지 않는다.
26
27
  - `label`: 필수. 앱에서 번역한 현재 작업 설명. 완료·오류 때는 별도 결과 UI로 교체한다.
27
28
  - `speed`: 기본 1, 유한수 0 초과 4 이하. 무제한 속도는 읽기 어려운 모션을 만들므로 제한한다.
@@ -30,7 +31,7 @@
30
31
  AppState만으로는 여전히 mounted인 숨긴 화면을 알아낼 수 없기 때문이다.
31
32
 
32
33
  HJM provider의 `text` 색을 깊이에 따른 opacity와 조합한다. 원본의 고정 grayscale 팔레트는
33
- 브랜드 테마와 배경에서 어긋날 수 있어 사용하지 않는다. 기하 좌표는 원본과 동일하다.
34
+ 브랜드 테마와 배경에서 어긋날 수 있어 사용하지 않는다. `appearance="state"`의 기하 좌표는 원본과 동일하다.
34
35
  모션 줄이기에서는 elapsed 0.6초 프레임만 그린다. 긴 JS 정체 후 이동은 최대 64ms로 제한해
35
36
  순간적인 모션 점프를 줄인다. 상태 전환은 새 모양으로 즉시 바뀌며 morph 전환은 제공하지 않는다.
36
37
  웹은 role=status와 숨긴 텍스트, Native는 접근 가능한 progressbar host를 사용한다.
@@ -122,3 +123,9 @@ Storybook registry 누락을 수정해 해당 검사를 다시 통과했다. Evi
122
123
  workspace/evidence/docs/governance, 양쪽 showcase 검사, Web Storybook build 및
123
124
  112 canonical story inventory, 중앙 library-policy 정적 검사, `git diff --check` 통과.
124
125
  게시·소비 앱 갱신은 실행하지 않았다.
126
+
127
+ ## Storybook 탐색
128
+
129
+ Web/Native 모두 `컴포넌트/피드백/ThinkingOrb`에서 Default, Dark, LargeText를 제공한다.
130
+ Fluid와 Matrix는 같은 컴포넌트의 표현 예제이며 새 상태 엔진이나 진행률 계약을 추가하지 않는다.
131
+ 2026-10-01 추가 표현의 Native 실제 화면 확인은 아직 미완료다.
@@ -95,7 +95,7 @@ catalog의 `{ name: "TimePicker", category: "input", platform: "adaptive", statu
95
95
 
96
96
  ## 2026-09-16: React/RN 작동 조합
97
97
 
98
- 명시 요청에 따라 위 합성 경로를 양쪽 Showcase의 `Patterns/Time selection`에 구현했다.
98
+ 명시 요청에 따라 위 합성 경로를 양쪽 Showcase의 `패턴/시간 선택`에 구현했다.
99
99
  시 00–23와 분 00–59의 독립 Select, 두 값이 있어야 가능한 확정, 초기화, 변경 시 확정 결과 해제를
100
100
  포함한다. 새 TimePicker renderer를 선언하지 않고 기존 공개 `Select`를 그대로 조합한다.
101
101
 
package/docs/toast.md CHANGED
@@ -10,8 +10,7 @@ Toast는 사용자가 응답해야만 진행되는 modal UI가 아니라, 무시
10
10
  필수 선택·삭제 확인·시간 안에 응답해야 하는 작업은 `AlertDialog`를 사용합니다.
11
11
 
12
12
  HJM은 Radix Primitives에서 provider/viewport anatomy, visible timer pause, focus·Escape·swipe
13
- 수명주기를 참고하고 React Aria/Spectrum에서 bounded queue, stable id close handle, 5초 최소
14
- timeout과 actionable persistent 기본값을 참고했습니다. 외부 component나 prop 이름은 공개하지
13
+ 수명주기를 참고하고 React Aria/Spectrum에서 bounded queue, stable id close handle과 actionable persistent 기본값을 참고했습니다. 외부 component나 prop 이름은 공개하지
15
14
  않고 다음 세 계층으로 번역했습니다.
16
15
 
17
16
  ```text
@@ -44,7 +43,9 @@ const result = store.publish({
44
43
  `announcement`를 제공합니다.
45
44
  - action은 무시해도 안전해야 합니다. label 자체로 동작이 명확하지 않으면
46
45
  `accessibilityLabel`에 완전한 이름을 제공합니다.
47
- - action이 있는 Toast는 기본 persistent입니다. 제품이 명시한 `durationMs`도 5000ms보다
46
+ - 기본 알림과 리퀴드 알림은 모두 표시 후 3초에 자동 닫힘을 시작합니다. 리퀴드는 진입 연출 동안 타이머를 멈춥니다.
47
+ 2026-10-02 사용자 요청으로 기존 5초 기본값·최솟값을 3초로 변경했습니다.
48
+ - action이 있는 Toast는 기본 persistent입니다. 제품이 명시한 `durationMs`도 3000ms보다
48
49
  짧아질 수 없으며, `null`은 명시적 persistent입니다.
49
50
 
50
51
  `publish` 결과에는 stable id와 `visible | queued` 위치가 포함됩니다. 호출자는 반환된 함수
@@ -74,9 +75,9 @@ duration을 갖습니다. `closing` id는 exit가 끝날 때까지 새 publish
74
75
  자기 monotonic clock으로 `advanceTime(elapsedMs)`를 호출합니다.
75
76
 
76
77
  ```text
77
- queued(waiting, 5000) ─ show ─→ visible(running, 5000)
78
+ queued(waiting, 3000) ─ show ─→ visible(running, 3000)
78
79
  ├─ pointer/focus/window/gesture → paused
79
- └─ elapsed=5000 → closing(timeout)
80
+ └─ elapsed=3000 → closing(timeout)
80
81
  └─ exit complete → closed
81
82
  ```
82
83
 
@@ -113,7 +114,7 @@ so a window-width breakpoint left doubled text and action labels compressed
113
114
  even in a wide window. A 1280px window/420px card regression covers that case.
114
115
 
115
116
  Proof: `packages/react/test/toast-layout.browser.test.tsx`; review fixture:
116
- Storybook `Patterns/Toast layout`. The fixture covers long Korean/English copy,
117
+ Storybook `패턴/토스트 배치`. The fixture covers long Korean/English copy,
117
118
  doubled text, dark theme and RTL. Automated browser checks are separate from
118
119
  real assistive-technology and consumer-release evidence; Toast remains beta.
119
120
 
@@ -132,7 +133,7 @@ Toast의 `●` 글리프가 뜻 없는 회색 점으로 보였고, 글자 글리
132
133
  - 여러 줄·큰 글자에서도 badge는 제목 옆 위쪽에 붙고, 한국어는 `word-break: keep-all`로 단어 중간에서
133
134
  끊지 않습니다(Web).
134
135
 
135
- Review fixture: Storybook `Patterns/Toast layout` → `Tone gallery`(light/dark).
136
+ Review fixture: Storybook `패턴/토스트 배치` → `Tone gallery`(light/dark).
136
137
 
137
138
  Web renderer:
138
139
 
package/docs/tour.md CHANGED
@@ -154,7 +154,7 @@ renderer이며 Native는 계속 `unsupported`다. Web renderer 증거는 stable
154
154
  다음 단계에 맞춘 anchor 하이라이트, 배경 inert와 바깥 pointer 무시, 첫 단계 이전은
155
155
  no-op·마지막 다음은 complete, Escape·건너뛰기 탈출, unmount의 1회 interrupted,
156
156
  controlled owner 종료와 320px 배치, 긴 번역 copy 내부 스크롤·키보드 건너뛰기·호출자
157
- focus 복귀)와 `Patterns/Tour`.
157
+ focus 복귀)와 `컴포넌트/오버레이/Tour`.
158
158
 
159
159
  ## 검증 화면
160
160
 
@@ -114,12 +114,12 @@ antd `TreeSelect`의 `checkStrictly`(부모/자식을 독립적으로 체크할
114
114
  - 표면: `@hjmds/react/popover`의 `Popover`(트리거 + 팝업 + 확정 버튼)
115
115
  - collection: `@hjmds/react/tree`의 `Tree`(깊이 발표·화살표·확장)
116
116
  - 집계: 이 모듈의 `resolveTreeCheckedStates`/`toggleTreeCheckedSelection`
117
- - 예제: Showcase `Patterns/Tree`의 TreeSelect 화면
117
+ - 예제: Showcase `컴포넌트/데이터 표시/Tree`의 TreeSelect 화면
118
118
 
119
119
  **Cascader도 같은 자리에서 끝난다.** catalog는 Cascader를 "TreeSelect에 path value와
120
120
  중간 단계 commit 축이 필요하다"는 prerequisite로 묶어 뒀는데, Tree renderer의 resolve
121
121
  결과가 이미 `parentId` 사슬을 들고 있어 경로는 파생이고, 중간 단계 확정은 그 노드를 그대로
122
122
  고르는 것이다. 새 축을 계약에 추가할 이유가 없어 prerequisite를 풀고 `composed`로 옮겼다
123
- (`Patterns/Tree`의 Cascader 화면). antd의 열(column) 방식 화면은 베끼지 않는다 — HJM의
123
+ (`컴포넌트/데이터 표시/Tree`의 Cascader 화면). antd의 열(column) 방식 화면은 베끼지 않는다 — HJM의
124
124
  계층 탐색 어휘를 그대로 쓰는 쪽이 같은 문제를 이미 푼다.
125
125
 
@@ -0,0 +1,19 @@
1
+ # VoiceNote
2
+
3
+ 검토일: 2026-10-01.
4
+
5
+ Web `@hjmds/react/voice-note`, Native `@hjmds/react-native/voice-note`.
6
+ 공통 `@hjmds/design-contracts/voice-note`의 descriptor는 제목, 실제 재생 상태, 초 단위 위치·길이를 받는다.
7
+
8
+ 기존 Asset의 장식 이미지 슬롯, Slider의 키보드/접근성 조정, Button의 비활성/로딩 상태를 합성한다. 독립 오디오 엔진을 추가하지 않는다. 녹음 권한, 파일 다운로드, 오디오 세션, 재생 종료와 백그라운드 처리는 제품 플레이어의 책임이다.
9
+
10
+ - 상태는 paused/playing/loading/error. duration=null은 메타데이터 미확인, 0은 확인된 빈 녹음이다. 두 경우 탐색·재생을 막는다.
11
+ - position은 실제 플레이어 위치이며 duration을 넘어가면 끝으로 제한한다. 음수·무한수는 거절한다.
12
+ - onPlayingChange는 재생/정지 요청, onSeek는 Slider 변경 요청이다. 제품은 요청을 실제 엔진에 적용하고 새 descriptor를 전달한다. 내부 타이머로 재생을 꾸미지 않는다.
13
+ - 오류 시 labels.error와 선택형 onRetry를 제공한다. 로딩·오류·disabled에서 재생과 탐색을 막는다.
14
+ - labels와 formatTime은 제품 번역을 받는다. Native의 이전/다음 접근성 동작 문구도 labels에 포함된다.
15
+ - artwork는 제목 옆 장식용 슬롯이다. 실제 파일 정보나 필수 텍스트를 이 슬롯에만 두지 않는다.
16
+
17
+ 양쪽 Storybook 컴포넌트/데이터 표시/Voice Note에 Default/Dark/LargeText와 로딩·오류 전환 버튼이 있다. 스토리는 상태 조작 예제라고 명시하며 실제 소리를 재생하지 않는다. 패키지 검사는 플레이어 연결 계약을 검증하며 실제 오디오·권한·OS 백그라운드 지원의 증거가 아니다.
18
+
19
+ [Native 후속 검증](../../../docs/evidence/component-flows-2026-10-01/README.md)에서 iPhone 17 / iOS 27 시뮬레이터의 큰 글씨 재생·정지 상태 전환, 로딩 중 비활성, 오류 후 재시도를 실제 조작했다. 캡처는 UI 상태 연결을 증명하며 실제 음성 재생 검증은 아니다.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hjmds/design-contracts",
3
- "version": "1.10.0",
3
+ "version": "1.11.0",
4
4
  "description": "Renderer-neutral design contracts, tokens, recipes, and behaviors shared by HJM products.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -570,6 +570,96 @@
570
570
  "react-native": "./dist/interaction-adapters.js",
571
571
  "import": "./dist/interaction-adapters.js",
572
572
  "default": "./dist/interaction-adapters.js"
573
+ },
574
+ "./avatar-fallback": {
575
+ "types": "./dist/avatar-fallback.d.ts",
576
+ "react-native": "./dist/avatar-fallback.js",
577
+ "import": "./dist/avatar-fallback.js",
578
+ "default": "./dist/avatar-fallback.js"
579
+ },
580
+ "./effect-surface": {
581
+ "types": "./dist/effect-surface.d.ts",
582
+ "react-native": "./dist/effect-surface.js",
583
+ "import": "./dist/effect-surface.js",
584
+ "default": "./dist/effect-surface.js"
585
+ },
586
+ "./content-transition": {
587
+ "types": "./dist/content-transition.d.ts",
588
+ "react-native": "./dist/content-transition.js",
589
+ "import": "./dist/content-transition.js",
590
+ "default": "./dist/content-transition.js"
591
+ },
592
+ "./duration-field": {
593
+ "types": "./dist/duration-field.d.ts",
594
+ "react-native": "./dist/duration-field.js",
595
+ "import": "./dist/duration-field.js",
596
+ "default": "./dist/duration-field.js"
597
+ },
598
+ "./reactions": {
599
+ "types": "./dist/reactions.d.ts",
600
+ "react-native": "./dist/reactions.js",
601
+ "import": "./dist/reactions.js",
602
+ "default": "./dist/reactions.js"
603
+ },
604
+ "./scroll-progress": {
605
+ "types": "./dist/scroll-progress.d.ts",
606
+ "react-native": "./dist/scroll-progress.js",
607
+ "import": "./dist/scroll-progress.js",
608
+ "default": "./dist/scroll-progress.js"
609
+ },
610
+ "./code-block": {
611
+ "types": "./dist/code-block.d.ts",
612
+ "react-native": "./dist/code-block.js",
613
+ "import": "./dist/code-block.js",
614
+ "default": "./dist/code-block.js"
615
+ },
616
+ "./activity-heatmap": {
617
+ "types": "./dist/activity-heatmap.d.ts",
618
+ "react-native": "./dist/activity-heatmap.js",
619
+ "import": "./dist/activity-heatmap.js",
620
+ "default": "./dist/activity-heatmap.js"
621
+ },
622
+ "./task-list": {
623
+ "types": "./dist/task-list.d.ts",
624
+ "react-native": "./dist/task-list.js",
625
+ "import": "./dist/task-list.js",
626
+ "default": "./dist/task-list.js"
627
+ },
628
+ "./voice-note": {
629
+ "types": "./dist/voice-note.d.ts",
630
+ "react-native": "./dist/voice-note.js",
631
+ "import": "./dist/voice-note.js",
632
+ "default": "./dist/voice-note.js"
633
+ },
634
+ "./theme-studio": {
635
+ "types": "./dist/theme-studio.d.ts",
636
+ "react-native": "./dist/theme-studio.js",
637
+ "import": "./dist/theme-studio.js",
638
+ "default": "./dist/theme-studio.js"
639
+ },
640
+ "./grid-reveal": {
641
+ "types": "./dist/grid-reveal.d.ts",
642
+ "react-native": "./dist/grid-reveal.js",
643
+ "import": "./dist/grid-reveal.js",
644
+ "default": "./dist/grid-reveal.js"
645
+ },
646
+ "./gravity-letters": {
647
+ "types": "./dist/gravity-letters.d.ts",
648
+ "react-native": "./dist/gravity-letters.js",
649
+ "import": "./dist/gravity-letters.js",
650
+ "default": "./dist/gravity-letters.js"
651
+ },
652
+ "./gooey-navigation": {
653
+ "types": "./dist/gooey-navigation.d.ts",
654
+ "react-native": "./dist/gooey-navigation.js",
655
+ "import": "./dist/gooey-navigation.js",
656
+ "default": "./dist/gooey-navigation.js"
657
+ },
658
+ "./action-session": {
659
+ "types": "./dist/action-session.d.ts",
660
+ "react-native": "./dist/action-session.js",
661
+ "import": "./dist/action-session.js",
662
+ "default": "./dist/action-session.js"
573
663
  }
574
664
  },
575
665
  "files": [