@hjmds/design-contracts 1.7.0 → 1.9.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 (250) hide show
  1. package/THIRD_PARTY_NOTICES.md +58 -0
  2. package/dist/affix.d.ts +8 -0
  3. package/dist/affix.d.ts.map +1 -0
  4. package/dist/affix.js +7 -0
  5. package/dist/affix.js.map +1 -0
  6. package/dist/agreement.d.ts +3 -3
  7. package/dist/agreement.js +1 -1
  8. package/dist/agreement.js.map +1 -1
  9. package/dist/asset.d.ts +1 -1
  10. package/dist/asset.js +1 -1
  11. package/dist/asset.js.map +1 -1
  12. package/dist/base-recipes.d.ts +12 -12
  13. package/dist/base-recipes.d.ts.map +1 -1
  14. package/dist/base-recipes.js +15 -14
  15. package/dist/base-recipes.js.map +1 -1
  16. package/dist/behaviors.d.ts +1 -1
  17. package/dist/catalog.d.ts +445 -651
  18. package/dist/catalog.d.ts.map +1 -1
  19. package/dist/catalog.js +149 -101
  20. package/dist/catalog.js.map +1 -1
  21. package/dist/color-picker.d.ts +11 -0
  22. package/dist/color-picker.d.ts.map +1 -0
  23. package/dist/color-picker.js +20 -0
  24. package/dist/color-picker.js.map +1 -0
  25. package/dist/command-palette.d.ts +3 -3
  26. package/dist/component-contracts.d.ts +4 -4
  27. package/dist/component-contracts.d.ts.map +1 -1
  28. package/dist/component-contracts.js +5 -4
  29. package/dist/component-contracts.js.map +1 -1
  30. package/dist/component-definitions.d.ts +1 -9
  31. package/dist/component-definitions.d.ts.map +1 -1
  32. package/dist/component-definitions.js +1 -9
  33. package/dist/component-definitions.js.map +1 -1
  34. package/dist/component-recipes.d.ts +76 -83
  35. package/dist/component-recipes.d.ts.map +1 -1
  36. package/dist/component-recipes.js +29 -49
  37. package/dist/component-recipes.js.map +1 -1
  38. package/dist/component-references.d.ts +10 -25
  39. package/dist/component-references.d.ts.map +1 -1
  40. package/dist/component-references.js +5 -8
  41. package/dist/component-references.js.map +1 -1
  42. package/dist/data-table.d.ts +3 -3
  43. package/dist/data-table.js +1 -1
  44. package/dist/data-table.js.map +1 -1
  45. package/dist/date-picker.d.ts +2 -2
  46. package/dist/icon-button-recipe.d.ts +2 -2
  47. package/dist/icon-button-recipe.js +1 -1
  48. package/dist/icon-button-recipe.js.map +1 -1
  49. package/dist/image.d.ts +2 -2
  50. package/dist/image.js +2 -2
  51. package/dist/image.js.map +1 -1
  52. package/dist/index.d.ts +1 -1
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +1 -1
  55. package/dist/index.js.map +1 -1
  56. package/dist/interaction-adapters.d.ts +53 -0
  57. package/dist/interaction-adapters.d.ts.map +1 -0
  58. package/dist/interaction-adapters.js +45 -0
  59. package/dist/interaction-adapters.js.map +1 -0
  60. package/dist/internal/thinking-orb/braid.d.ts +3 -0
  61. package/dist/internal/thinking-orb/braid.d.ts.map +1 -0
  62. package/dist/internal/thinking-orb/braid.js +47 -0
  63. package/dist/internal/thinking-orb/braid.js.map +1 -0
  64. package/dist/internal/thinking-orb/core.d.ts +60 -0
  65. package/dist/internal/thinking-orb/core.d.ts.map +1 -0
  66. package/dist/internal/thinking-orb/core.js +86 -0
  67. package/dist/internal/thinking-orb/core.js.map +1 -0
  68. package/dist/internal/thinking-orb/lattice.d.ts +5 -0
  69. package/dist/internal/thinking-orb/lattice.d.ts.map +1 -0
  70. package/dist/internal/thinking-orb/lattice.js +187 -0
  71. package/dist/internal/thinking-orb/lattice.js.map +1 -0
  72. package/dist/internal/thinking-orb/morph.d.ts +3 -0
  73. package/dist/internal/thinking-orb/morph.d.ts.map +1 -0
  74. package/dist/internal/thinking-orb/morph.js +127 -0
  75. package/dist/internal/thinking-orb/morph.js.map +1 -0
  76. package/dist/internal/thinking-orb/orbits.d.ts +3 -0
  77. package/dist/internal/thinking-orb/orbits.d.ts.map +1 -0
  78. package/dist/internal/thinking-orb/orbits.js +68 -0
  79. package/dist/internal/thinking-orb/orbits.js.map +1 -0
  80. package/dist/internal/thinking-orb/presets.d.ts +21 -0
  81. package/dist/internal/thinking-orb/presets.d.ts.map +1 -0
  82. package/dist/internal/thinking-orb/presets.js +77 -0
  83. package/dist/internal/thinking-orb/presets.js.map +1 -0
  84. package/dist/internal/thinking-orb/profiles.d.ts +8 -0
  85. package/dist/internal/thinking-orb/profiles.d.ts.map +1 -0
  86. package/dist/internal/thinking-orb/profiles.js +158 -0
  87. package/dist/internal/thinking-orb/profiles.js.map +1 -0
  88. package/dist/internal/thinking-orb/registry.d.ts +9 -0
  89. package/dist/internal/thinking-orb/registry.d.ts.map +1 -0
  90. package/dist/internal/thinking-orb/registry.js +27 -0
  91. package/dist/internal/thinking-orb/registry.js.map +1 -0
  92. package/dist/internal/thinking-orb/ribbon.d.ts +3 -0
  93. package/dist/internal/thinking-orb/ribbon.d.ts.map +1 -0
  94. package/dist/internal/thinking-orb/ribbon.js +87 -0
  95. package/dist/internal/thinking-orb/ribbon.js.map +1 -0
  96. package/dist/internal/thinking-orb/types.d.ts +15 -0
  97. package/dist/internal/thinking-orb/types.d.ts.map +1 -0
  98. package/dist/internal/thinking-orb/types.js +4 -0
  99. package/dist/internal/thinking-orb/types.js.map +1 -0
  100. package/dist/internal/thinking-orb/web.d.ts +3 -0
  101. package/dist/internal/thinking-orb/web.d.ts.map +1 -0
  102. package/dist/internal/thinking-orb/web.js +92 -0
  103. package/dist/internal/thinking-orb/web.js.map +1 -0
  104. package/dist/masonry.d.ts +17 -0
  105. package/dist/masonry.d.ts.map +1 -0
  106. package/dist/masonry.js +18 -0
  107. package/dist/masonry.js.map +1 -0
  108. package/dist/menubar.d.ts +3 -3
  109. package/dist/menubar.js +1 -1
  110. package/dist/menubar.js.map +1 -1
  111. package/dist/number-field.d.ts +2 -2
  112. package/dist/otp-field.d.ts +1 -1
  113. package/dist/password-field.d.ts +2 -2
  114. package/dist/popover.d.ts +7 -8
  115. package/dist/popover.d.ts.map +1 -1
  116. package/dist/popover.js +2 -0
  117. package/dist/popover.js.map +1 -1
  118. package/dist/qr-code-recipe.d.ts +7 -0
  119. package/dist/qr-code-recipe.d.ts.map +1 -0
  120. package/dist/qr-code-recipe.js +2 -0
  121. package/dist/qr-code-recipe.js.map +1 -0
  122. package/dist/qr-code.d.ts +16 -0
  123. package/dist/qr-code.d.ts.map +1 -0
  124. package/dist/qr-code.js +37 -0
  125. package/dist/qr-code.js.map +1 -0
  126. package/dist/semantic-colors.d.ts +1 -1
  127. package/dist/semantic-colors.js +1 -1
  128. package/dist/semantic-colors.js.map +1 -1
  129. package/dist/showcase.d.ts +5 -1
  130. package/dist/showcase.d.ts.map +1 -1
  131. package/dist/showcase.js +53 -12
  132. package/dist/showcase.js.map +1 -1
  133. package/dist/sidebar.d.ts +3 -3
  134. package/dist/sidebar.js +1 -1
  135. package/dist/sidebar.js.map +1 -1
  136. package/dist/tag.d.ts +4 -4
  137. package/dist/tag.js +3 -3
  138. package/dist/tag.js.map +1 -1
  139. package/dist/tags-input.d.ts +3 -3
  140. package/dist/tags-input.js +1 -1
  141. package/dist/tags-input.js.map +1 -1
  142. package/dist/text-formats.d.ts +2 -2
  143. package/dist/text-formats.js +2 -2
  144. package/dist/text-formats.js.map +1 -1
  145. package/dist/thinking-orb-recipe.d.ts +15 -0
  146. package/dist/thinking-orb-recipe.d.ts.map +1 -0
  147. package/dist/thinking-orb-recipe.js +9 -0
  148. package/dist/thinking-orb-recipe.js.map +1 -0
  149. package/dist/thinking-orb.d.ts +25 -0
  150. package/dist/thinking-orb.d.ts.map +1 -0
  151. package/dist/thinking-orb.js +40 -0
  152. package/dist/thinking-orb.js.map +1 -0
  153. package/dist/toast-liquid.d.ts +116 -0
  154. package/dist/toast-liquid.d.ts.map +1 -0
  155. package/dist/toast-liquid.js +103 -0
  156. package/dist/toast-liquid.js.map +1 -0
  157. package/dist/toast.d.ts +7 -1
  158. package/dist/toast.d.ts.map +1 -1
  159. package/dist/toast.js +5 -0
  160. package/dist/toast.js.map +1 -1
  161. package/dist/toggle-group.d.ts +2 -2
  162. package/dist/toggle-group.js +3 -3
  163. package/dist/toggle-group.js.map +1 -1
  164. package/dist/transfer-list.d.ts +3 -3
  165. package/dist/transfer-list.js +1 -1
  166. package/dist/transfer-list.js.map +1 -1
  167. package/dist/tree.d.ts +2 -2
  168. package/dist/version.d.ts +1 -1
  169. package/dist/version.js +1 -1
  170. package/dist/version.js.map +1 -1
  171. package/dist/virtual-list.d.ts +13 -0
  172. package/dist/virtual-list.d.ts.map +1 -0
  173. package/dist/virtual-list.js +13 -0
  174. package/dist/virtual-list.js.map +1 -0
  175. package/dist/watermark.d.ts +15 -0
  176. package/dist/watermark.d.ts.map +1 -0
  177. package/dist/watermark.js +11 -0
  178. package/dist/watermark.js.map +1 -0
  179. package/docs/affix.md +27 -63
  180. package/docs/anchor.md +5 -4
  181. package/docs/ant-design-coverage.md +8 -12
  182. package/docs/architecture.md +6 -2
  183. package/docs/authoring-brief.md +3 -2
  184. package/docs/bottom-navigation.md +7 -6
  185. package/docs/breadcrumb.md +5 -2
  186. package/docs/calendar.md +6 -3
  187. package/docs/carousel.md +2 -2
  188. package/docs/cascader.md +11 -0
  189. package/docs/catalog-cleanup.md +7 -0
  190. package/docs/catalog-decision-status.md +8 -3
  191. package/docs/catalog-freeze.json +9 -7
  192. package/docs/collapsible.md +12 -0
  193. package/docs/color-picker.md +30 -72
  194. package/docs/command-palette.md +5 -3
  195. package/docs/confirm-popover.md +5 -0
  196. package/docs/consumer-policy.md +29 -12
  197. package/docs/context-menu.md +12 -2
  198. package/docs/data-table.md +11 -6
  199. package/docs/date-picker.md +6 -4
  200. package/docs/date-range.md +4 -2
  201. package/docs/description-list.md +8 -9
  202. package/docs/dialog.md +39 -0
  203. package/docs/expansion-roadmap.md +11 -7
  204. package/docs/file-picker.md +5 -3
  205. package/docs/form.md +16 -4
  206. package/docs/generated/component-maturity.md +91 -99
  207. package/docs/generated/renderer-evidence.json +2043 -1059
  208. package/docs/generated/renderer-evidence.md +156 -145
  209. package/docs/generated/showcase-manifest.json +476 -625
  210. package/docs/layout.md +8 -9
  211. package/docs/library-gap-analysis.md +1 -1
  212. package/docs/masonry.md +11 -0
  213. package/docs/mentions.md +14 -7
  214. package/docs/optional-adapters.md +126 -0
  215. package/docs/otp-field.md +2 -1
  216. package/docs/pagination.md +4 -1
  217. package/docs/password-field.md +2 -1
  218. package/docs/popover.md +9 -6
  219. package/docs/promotion-candidates.md +2 -1
  220. package/docs/qr-code.md +11 -65
  221. package/docs/rating.md +5 -0
  222. package/docs/react-native-completion.md +1 -1
  223. package/docs/result.md +8 -5
  224. package/docs/screen-chrome.md +2 -1
  225. package/docs/sheet.md +8 -2
  226. package/docs/showcase.md +10 -2
  227. package/docs/side-panel.md +12 -6
  228. package/docs/sidebar.md +3 -0
  229. package/docs/splitter.md +6 -6
  230. package/docs/stable-core.md +92 -0
  231. package/docs/stable-promotion.md +47 -43
  232. package/docs/tags-input.md +5 -2
  233. package/docs/theme-palette.md +27 -0
  234. package/docs/thinking-orb.md +124 -0
  235. package/docs/time-picker.md +5 -0
  236. package/docs/timeline.md +2 -3
  237. package/docs/toast.md +6 -0
  238. package/docs/tooltip.md +2 -1
  239. package/docs/tour.md +14 -8
  240. package/docs/transfer-list.md +24 -21
  241. package/docs/tree-select.md +7 -1
  242. package/docs/tree.md +12 -7
  243. package/docs/upload-item.md +7 -3
  244. package/docs/virtual-list.md +10 -67
  245. package/docs/watermark.md +26 -58
  246. package/package.json +54 -3
  247. package/docs/app-provider.md +0 -50
  248. package/docs/border-beam.md +0 -66
  249. package/docs/chart.md +0 -33
  250. package/docs/utility.md +0 -53
@@ -81,12 +81,12 @@ export declare const numberFieldRecipe: {
81
81
  readonly frame: {
82
82
  readonly background: Readonly<{
83
83
  source: "theme";
84
- key: "surface";
84
+ key: "bg";
85
85
  alpha?: number;
86
86
  }>;
87
87
  readonly border: Readonly<{
88
88
  source: "theme";
89
- key: "textMuted";
89
+ key: "borderControl";
90
90
  alpha?: number;
91
91
  }>;
92
92
  readonly focusBorder: Readonly<{
@@ -91,7 +91,7 @@ export declare const otpFieldRecipe: {
91
91
  readonly slot: {
92
92
  readonly border: Readonly<{
93
93
  source: "theme";
94
- key: "textMuted";
94
+ key: "borderControl";
95
95
  alpha?: number;
96
96
  }>;
97
97
  readonly focusBorder: Readonly<{
@@ -58,12 +58,12 @@ export declare const passwordFieldRecipe: {
58
58
  readonly frame: {
59
59
  readonly background: Readonly<{
60
60
  source: "theme";
61
- key: "surface";
61
+ key: "bg";
62
62
  alpha?: number;
63
63
  }>;
64
64
  readonly border: Readonly<{
65
65
  source: "theme";
66
- key: "textMuted";
66
+ key: "borderControl";
67
67
  alpha?: number;
68
68
  }>;
69
69
  readonly focusBorder: Readonly<{
package/dist/popover.d.ts CHANGED
@@ -63,14 +63,13 @@ export type PopoverDismissPolicy = Readonly<{
63
63
  focusOutDismiss: boolean;
64
64
  }>;
65
65
  /**
66
- * 무엇이 popover를 여는가. `press`가 기본이고 `hover`는 **읽기 전용 미리보기**
67
- * (다른 시스템의 HoverCard)를 위한 축이다.
66
+ * 무엇이 popover를 여는가. `press`가 기본이고 `hover`는 포인터의 추가 진입
67
+ * 방식이다. hover를 켜도 press 경로를 유지해야 키보드·터치 사용자가 같은
68
+ * 콘텐츠에 도달할 수 있다.
68
69
  *
69
- * 별도 컴포넌트를 만들지 않은 이유: 표면·초점·dismiss·충돌 회피가 전부 같고 다른 것은
70
- * 여는 방법 하나뿐이다. 두 컴포넌트로 나누면 그 네 가지가 두 벌이 된다.
71
- *
72
- * 대신 `hover`에는 제약이 붙는다 — hover로만 열리는 내용에 **행동을 두면 안 된다**.
73
- * 포인터가 없는 사용자는 그 행동에 닿을 수 없기 때문이다. 미리보기는 읽기 전용이다.
70
+ * 별도 HoverCard는 검토했지만 표면·초점·dismiss·충돌 회피 계약은 같고 여는
71
+ * 방식만 하나 더하는 것이므로 컴포넌트를 나누지 않는다. hover는 지나가는 포인터에
72
+ * 바로 반응하지 않도록 지연되며, click/키보드/터치 경로를 대체하지 않는다.
74
73
  */
75
74
  export type PopoverOpenOn = "press" | "hover";
76
75
  export declare const popoverBehaviorDefaults: {
@@ -163,5 +162,5 @@ export declare const popoverRecipe: {
163
162
  * src/behaviors.ts). Kept here, not there, so this module stays self-contained
164
163
  * per the authoring brief.
165
164
  */
166
- export declare const popoverBehaviorScenarios: readonly ["focus-enters-surface-on-open", "escape-closes-and-restores-trigger-focus", "outside-pointer-close-does-not-cancel-the-original-interaction", "tabbing-past-last-focusable-child-closes-without-trapping", "controlled-owner-programmatic-close-always-wins", "close-action-inside-content-closes-exactly-once", "trigger-while-open-does-not-reopen", "one-visible-popover-per-trigger"];
165
+ export declare const popoverBehaviorScenarios: readonly ["focus-enters-surface-on-open", "escape-closes-and-restores-trigger-focus", "outside-pointer-close-does-not-cancel-the-original-interaction", "tabbing-past-last-focusable-child-closes-without-trapping", "optional-hover-opens-after-delay-and-survives-pointer-crossing", "hover-mode-retains-press-activation-for-touch-and-keyboard", "controlled-owner-programmatic-close-always-wins", "close-action-inside-content-closes-exactly-once", "trigger-while-open-does-not-reopen", "one-visible-popover-per-trigger"];
167
166
  //# sourceMappingURL=popover.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../src/popover.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;AAClE,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEtD;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAC5B,cAAc,GACd,iBAAiB,GACjB,eAAe,GACf,QAAQ,GACR,cAAc,CAAC;AAEnB;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,oBAAoB,CAAC;AAEvE,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,MAAM,EAAE,uBAAuB,CAAC;CACjC,CAAC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC,CAAC;AAEH,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAC/C,SAAS,EAAE,gBAAgB,CAAC;IAC5B,KAAK,EAAE,YAAY,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;CAG6C,CAAC;AAEpF;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC,CAAC;AAEH;;;;;;;;;GASG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,OAAO,CAAC;AAE9C,eAAO,MAAM,uBAAuB;qBACf,aAAa;;;;;CAK6C,CAAC;AAEhF,+CAA+C;AAC/C,eAAO,MAAM,iBAAiB;;;CAAqC,CAAC;AAEpE,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAChD,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,KAAK,CAAC;IACpB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,wBAAwB,GAAG,IAAI,CAAC;CACtE,CAAC,CAAC;AAEH,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,CACb,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,wBAAwB,KAC9B,IAAI,CAAC;CACX,CAAC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GACxB,0BAA0B,GAC1B,4BAA4B,CAAC;AAEjC,6FAA6F;AAC7F,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;AAuBpE,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,iBAAiB,GAAG,IAAI,CA6B7E;AAED,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,iBAAiB,GAC5B,yBAAyB,CAS3B;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAgCtE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,oBAAoB,EAC5B,MAAM,GAAE,oBAA8C,GACrD,OAAO,CAOT;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkBzB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,qYAS3B,CAAC"}
1
+ {"version":3,"file":"popover.d.ts","sourceRoot":"","sources":["../src/popover.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC;AAClE,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEtD;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAC5B,cAAc,GACd,iBAAiB,GACjB,eAAe,GACf,QAAQ,GACR,cAAc,CAAC;AAEnB;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,oBAAoB,CAAC;AAEvE,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,MAAM,EAAE,uBAAuB,CAAC;CACjC,CAAC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC,CAAC;AAEH,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC;IAC/C,SAAS,EAAE,gBAAgB,CAAC;IAC5B,KAAK,EAAE,YAAY,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;CAG6C,CAAC;AAEpF;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,OAAO,CAAC;AAE9C,eAAO,MAAM,uBAAuB;qBACf,aAAa;;;;;CAK6C,CAAC;AAEhF,+CAA+C;AAC/C,eAAO,MAAM,iBAAiB;;;CAAqC,CAAC;AAEpE,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAChD,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,KAAK,CAAC;IACpB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,wBAAwB,GAAG,IAAI,CAAC;CACtE,CAAC,CAAC;AAEH,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,CACb,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,wBAAwB,KAC9B,IAAI,CAAC;CACX,CAAC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GACxB,0BAA0B,GAC1B,4BAA4B,CAAC;AAEjC,6FAA6F;AAC7F,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;AAuBpE,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,iBAAiB,GAAG,IAAI,CA6B7E;AAED,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,iBAAiB,GAC5B,yBAAyB,CAS3B;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAgCtE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,oBAAoB,EAC5B,MAAM,GAAE,oBAA8C,GACrD,OAAO,CAOT;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkBzB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,qgBAW3B,CAAC"}
package/dist/popover.js CHANGED
@@ -132,6 +132,8 @@ export const popoverBehaviorScenarios = [
132
132
  "escape-closes-and-restores-trigger-focus",
133
133
  "outside-pointer-close-does-not-cancel-the-original-interaction",
134
134
  "tabbing-past-last-focusable-child-closes-without-trapping",
135
+ "optional-hover-opens-after-delay-and-survives-pointer-crossing",
136
+ "hover-mode-retains-press-activation-for-touch-and-keyboard",
135
137
  "controlled-owner-programmatic-close-always-wins",
136
138
  "close-action-inside-content-closes-exactly-once",
137
139
  "trigger-while-open-does-not-reopen",
@@ -1 +1 @@
1
- {"version":3,"file":"popover.js","sourceRoot":"","sources":["../src/popover.ts"],"names":[],"mappings":"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","sourcesContent":["import { floatingSurfaceContract } from \"./component-contracts.js\";\nimport { motionPreset, spacing } from \"./foundations.js\";\n\n/**\n * Popover is the third corner of a triangle with Tooltip and Menu — all three\n * are \"a floating surface anchored to a trigger.\" Tooltip is explicitly\n * plain-text and never receives focus (docs/tooltip.md: \"interactive\n * Popover로 확장하지 않는다\"). Menu is a collection of actionable items with\n * its own role/keyboard table (behaviorRegistry.menu). Popover is what is left:\n * arbitrary *interactive* content (a small form, rich text with a link, a\n * mixed layout) that is neither a single plain sentence nor an item list.\n * Focus entering the surface is the decisive, testable difference from\n * Tooltip — everything else here (dismiss reasons, non-modal posture) follows\n * from that one fact.\n */\nexport type PopoverPlacement = \"top\" | \"bottom\" | \"start\" | \"end\";\nexport type PopoverAlign = \"start\" | \"center\" | \"end\";\n\n/**\n * Popover is non-modal: it does not trap focus like Dialog/Sheet and does not\n * block the rest of the page. So its dismiss vocabulary is deliberately\n * narrower than SheetDismissReason — no \"back\" or \"swipe\" (this is a web-only\n * surface), but it adds \"outside-focus\" because, unlike a modal, Tab can\n * legitimately carry focus out of a non-modal surface and that departure is\n * itself a dismiss signal distinct from a pointer click outside.\n */\nexport type PopoverDismissReason =\n | \"close-action\"\n | \"outside-pointer\"\n | \"outside-focus\"\n | \"escape\"\n | \"programmatic\";\n\n/**\n * 여는 사유는 `\"trigger\"`다. Sheet·SidePanel·CommandPalette가 모두 이 이름을 쓰고,\n * `\"trigger-activation\"`은 `src/tooltip.ts`에서 **닫는** 사유(열려 있는 툴팁의\n * 트리거를 눌러 닫는다)로 이미 쓰이고 있다. 한 문자열이 여는 뜻과 닫는 뜻을 겸하면\n * 렌더러가 조용히 반대로 처리한다 — 컴파일러는 둘 다 유효한 문자열로만 본다.\n */\nexport type PopoverOpenChangeReason = \"trigger\" | PopoverDismissReason;\n\nexport type PopoverOpenChangeDetails = Readonly<{\n reason: PopoverOpenChangeReason;\n}>;\n\nexport type PopoverDescriptor = Readonly<{\n placement?: PopoverPlacement;\n align?: PopoverAlign;\n /**\n * Optional explicit accessible name. A renderer must connect its visible\n * heading with aria-labelledby; a heading alone does not name a dialog.\n */\n accessibilityLabel?: string;\n}>;\n\nexport type ResolvedPopoverDescriptor = Readonly<{\n placement: PopoverPlacement;\n align: PopoverAlign;\n accessibilityLabel?: string;\n}>;\n\nexport const popoverDescriptorDefaults = {\n placement: \"bottom\",\n align: \"start\",\n} as const satisfies Readonly<{ placement: PopoverPlacement; align: PopoverAlign }>;\n\n/**\n * A controlled owner's programmatic close always wins, exactly like\n * SheetDismissPolicy/canDismissSheet. Popover has no `busy` axis: unlike\n * Sheet/AlertDialog it is not modal, so there is no global \"block every\n * dismiss\" state to defend — a form inside the content that wants to ignore\n * Escape while submitting makes that call itself, at the content level.\n */\nexport type PopoverDismissPolicy = Readonly<{\n dismissible: boolean;\n outsideDismiss: boolean;\n escapeDismiss: boolean;\n focusOutDismiss: boolean;\n}>;\n\n/**\n * 무엇이 popover를 여는가. `press`가 기본이고 `hover`는 **읽기 전용 미리보기**\n * (다른 시스템의 HoverCard)를 위한 축이다.\n *\n * 별도 컴포넌트를 만들지 않은 이유: 표면·초점·dismiss·충돌 회피가 전부 같고 다른 것은\n * 여는 방법 하나뿐이다. 두 컴포넌트로 나누면 그 네 가지가 두 벌이 된다.\n *\n * 대신 `hover`에는 제약이 붙는다 — hover로만 열리는 내용에 **행동을 두면 안 된다**.\n * 포인터가 없는 사용자는 그 행동에 닿을 수 없기 때문이다. 미리보기는 읽기 전용이다.\n */\nexport type PopoverOpenOn = \"press\" | \"hover\";\n\nexport const popoverBehaviorDefaults = {\n openOn: \"press\" as PopoverOpenOn,\n dismissible: true,\n outsideDismiss: true,\n escapeDismiss: true,\n focusOutDismiss: true,\n} as const satisfies PopoverDismissPolicy & Readonly<{ openOn: PopoverOpenOn }>;\n\n/** hover로 열 때의 지연. 지나가는 포인터마다 열리면 화면이 깜빡인다. */\nexport const popoverHoverDelay = { open: 300, close: 150 } as const;\n\nexport type ControlledPopoverOpenState = Readonly<{\n open: boolean;\n defaultOpen?: never;\n onOpenChange(open: boolean, details: PopoverOpenChangeDetails): void;\n}>;\n\nexport type UncontrolledPopoverOpenState = Readonly<{\n open?: never;\n defaultOpen?: boolean;\n onOpenChange?: (\n open: boolean,\n details: PopoverOpenChangeDetails,\n ) => void;\n}>;\n\nexport type PopoverOpenState =\n | ControlledPopoverOpenState\n | UncontrolledPopoverOpenState;\n\n/** Products own what page-change caused this; Popover only needs \"did it happen and how.\" */\nexport type PopoverChangeHandler = PopoverOpenState[\"onOpenChange\"];\n\nconst placements = new Set<PopoverPlacement>([\"top\", \"bottom\", \"start\", \"end\"]);\nconst alignments = new Set<PopoverAlign>([\"start\", \"center\", \"end\"]);\nconst descriptorKeys = new Set([\"placement\", \"align\", \"accessibilityLabel\"]);\nconst openStateKeys = new Set([\"open\", \"defaultOpen\", \"onOpenChange\"]);\n\nfunction isObject(value: unknown): value is Readonly<Record<string, unknown>> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction rejectUnknownKeys(\n value: Readonly<Record<string, unknown>>,\n allowed: ReadonlySet<string>,\n field: string,\n): void {\n for (const key of Object.keys(value)) {\n if (!allowed.has(key)) {\n throw new TypeError(`Unsupported Popover ${field} field: ${key}`);\n }\n }\n}\n\nexport function validatePopoverDescriptor(descriptor: PopoverDescriptor): void {\n if (!isObject(descriptor)) {\n throw new TypeError(\"Popover descriptor must be an object\");\n }\n rejectUnknownKeys(descriptor, descriptorKeys, \"descriptor\");\n if (\n descriptor.placement !== undefined &&\n !placements.has(descriptor.placement)\n ) {\n throw new TypeError(\n `Unsupported Popover placement: ${String(descriptor.placement)}`,\n );\n }\n if (descriptor.align !== undefined && !alignments.has(descriptor.align)) {\n throw new TypeError(`Unsupported Popover align: ${String(descriptor.align)}`);\n }\n if (descriptor.accessibilityLabel !== undefined) {\n if (\n typeof descriptor.accessibilityLabel !== \"string\" ||\n descriptor.accessibilityLabel.trim().length === 0\n ) {\n throw new TypeError(\"Popover accessibilityLabel must not be empty\");\n }\n if (descriptor.accessibilityLabel !== descriptor.accessibilityLabel.trim()) {\n throw new TypeError(\n \"Popover accessibilityLabel must not start or end with whitespace\",\n );\n }\n }\n}\n\nexport function resolvePopoverDescriptor(\n descriptor: PopoverDescriptor,\n): ResolvedPopoverDescriptor {\n validatePopoverDescriptor(descriptor);\n return {\n placement: descriptor.placement ?? popoverDescriptorDefaults.placement,\n align: descriptor.align ?? popoverDescriptorDefaults.align,\n ...(descriptor.accessibilityLabel !== undefined\n ? { accessibilityLabel: descriptor.accessibilityLabel }\n : {}),\n };\n}\n\nexport function validatePopoverOpenState(state: PopoverOpenState): void {\n if (!isObject(state)) {\n throw new TypeError(\"Popover open state must be an object\");\n }\n rejectUnknownKeys(state, openStateKeys, \"open state\");\n const runtime = state as Readonly<Record<string, unknown>>;\n const hasOpen = Object.prototype.hasOwnProperty.call(runtime, \"open\");\n const hasDefaultOpen = Object.prototype.hasOwnProperty.call(\n runtime,\n \"defaultOpen\",\n );\n if (hasOpen) {\n if (typeof runtime.open !== \"boolean\") {\n throw new TypeError(\"Popover open must be a boolean\");\n }\n if (hasDefaultOpen) {\n throw new TypeError(\"Controlled Popover must not provide defaultOpen\");\n }\n if (typeof runtime.onOpenChange !== \"function\") {\n throw new TypeError(\"Controlled Popover must provide onOpenChange\");\n }\n return;\n }\n if (hasDefaultOpen && typeof runtime.defaultOpen !== \"boolean\") {\n throw new TypeError(\"Popover defaultOpen must be a boolean\");\n }\n if (\n runtime.onOpenChange !== undefined &&\n typeof runtime.onOpenChange !== \"function\"\n ) {\n throw new TypeError(\"Popover onOpenChange must be a function\");\n }\n}\n\n/**\n * Resolves an attempted close without platform knowledge, mirroring\n * canDismissSheet. Programmatic close is always an owner override.\n */\nexport function canDismissPopover(\n reason: PopoverDismissReason,\n policy: PopoverDismissPolicy = popoverBehaviorDefaults,\n): boolean {\n if (reason === \"programmatic\") return true;\n if (!policy.dismissible) return false;\n if (reason === \"outside-pointer\") return policy.outsideDismiss;\n if (reason === \"outside-focus\") return policy.focusOutDismiss;\n if (reason === \"escape\") return policy.escapeDismiss;\n return true;\n}\n\n/**\n * Positioning boundary is identical to Tooltip's: HJM owns preferred\n * placement, spacing, and motion; DOM measurement, portal, flip/shift, and\n * RTL logical-to-physical translation stay in the product Web renderer's\n * private AnchoredOverlay (see docs/tooltip.md \"Positioning boundary\"). This\n * module never exposes that internal tool, so Popover cannot regress Tooltip's\n * \"no public collision/portal API\" boundary.\n */\nexport const popoverRecipe = {\n slots: [\"trigger\", \"content\", \"arrow\", \"closeAction\"] as const,\n surface: floatingSurfaceContract,\n arrow: { size: spacing.xxs, offset: spacing.xxs },\n sideOffset: spacing.xs,\n collisionPadding: spacing.xs,\n minWidth: 240,\n maxWidth: 360,\n transition: { enter: motionPreset.enter, exit: motionPreset.exit },\n} as const satisfies {\n slots: readonly string[];\n surface: typeof floatingSurfaceContract;\n arrow: { size: number; offset: number };\n sideOffset: number;\n collisionPadding: number;\n minWidth: number;\n maxWidth: number;\n transition: { enter: typeof motionPreset.enter; exit: typeof motionPreset.exit };\n};\n\n/**\n * Literal scenario names for behaviorRegistry.popover (lead wires into\n * src/behaviors.ts). Kept here, not there, so this module stays self-contained\n * per the authoring brief.\n */\nexport const popoverBehaviorScenarios = [\n \"focus-enters-surface-on-open\",\n \"escape-closes-and-restores-trigger-focus\",\n \"outside-pointer-close-does-not-cancel-the-original-interaction\",\n \"tabbing-past-last-focusable-child-closes-without-trapping\",\n \"controlled-owner-programmatic-close-always-wins\",\n \"close-action-inside-content-closes-exactly-once\",\n \"trigger-while-open-does-not-reopen\",\n \"one-visible-popover-per-trigger\",\n] as const;\n"]}
1
+ {"version":3,"file":"popover.js","sourceRoot":"","sources":["../src/popover.ts"],"names":[],"mappings":"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","sourcesContent":["import { floatingSurfaceContract } from \"./component-contracts.js\";\nimport { motionPreset, spacing } from \"./foundations.js\";\n\n/**\n * Popover is the third corner of a triangle with Tooltip and Menu — all three\n * are \"a floating surface anchored to a trigger.\" Tooltip is explicitly\n * plain-text and never receives focus (docs/tooltip.md: \"interactive\n * Popover로 확장하지 않는다\"). Menu is a collection of actionable items with\n * its own role/keyboard table (behaviorRegistry.menu). Popover is what is left:\n * arbitrary *interactive* content (a small form, rich text with a link, a\n * mixed layout) that is neither a single plain sentence nor an item list.\n * Focus entering the surface is the decisive, testable difference from\n * Tooltip — everything else here (dismiss reasons, non-modal posture) follows\n * from that one fact.\n */\nexport type PopoverPlacement = \"top\" | \"bottom\" | \"start\" | \"end\";\nexport type PopoverAlign = \"start\" | \"center\" | \"end\";\n\n/**\n * Popover is non-modal: it does not trap focus like Dialog/Sheet and does not\n * block the rest of the page. So its dismiss vocabulary is deliberately\n * narrower than SheetDismissReason — no \"back\" or \"swipe\" (this is a web-only\n * surface), but it adds \"outside-focus\" because, unlike a modal, Tab can\n * legitimately carry focus out of a non-modal surface and that departure is\n * itself a dismiss signal distinct from a pointer click outside.\n */\nexport type PopoverDismissReason =\n | \"close-action\"\n | \"outside-pointer\"\n | \"outside-focus\"\n | \"escape\"\n | \"programmatic\";\n\n/**\n * 여는 사유는 `\"trigger\"`다. Sheet·SidePanel·CommandPalette가 모두 이 이름을 쓰고,\n * `\"trigger-activation\"`은 `src/tooltip.ts`에서 **닫는** 사유(열려 있는 툴팁의\n * 트리거를 눌러 닫는다)로 이미 쓰이고 있다. 한 문자열이 여는 뜻과 닫는 뜻을 겸하면\n * 렌더러가 조용히 반대로 처리한다 — 컴파일러는 둘 다 유효한 문자열로만 본다.\n */\nexport type PopoverOpenChangeReason = \"trigger\" | PopoverDismissReason;\n\nexport type PopoverOpenChangeDetails = Readonly<{\n reason: PopoverOpenChangeReason;\n}>;\n\nexport type PopoverDescriptor = Readonly<{\n placement?: PopoverPlacement;\n align?: PopoverAlign;\n /**\n * Optional explicit accessible name. A renderer must connect its visible\n * heading with aria-labelledby; a heading alone does not name a dialog.\n */\n accessibilityLabel?: string;\n}>;\n\nexport type ResolvedPopoverDescriptor = Readonly<{\n placement: PopoverPlacement;\n align: PopoverAlign;\n accessibilityLabel?: string;\n}>;\n\nexport const popoverDescriptorDefaults = {\n placement: \"bottom\",\n align: \"start\",\n} as const satisfies Readonly<{ placement: PopoverPlacement; align: PopoverAlign }>;\n\n/**\n * A controlled owner's programmatic close always wins, exactly like\n * SheetDismissPolicy/canDismissSheet. Popover has no `busy` axis: unlike\n * Sheet/AlertDialog it is not modal, so there is no global \"block every\n * dismiss\" state to defend — a form inside the content that wants to ignore\n * Escape while submitting makes that call itself, at the content level.\n */\nexport type PopoverDismissPolicy = Readonly<{\n dismissible: boolean;\n outsideDismiss: boolean;\n escapeDismiss: boolean;\n focusOutDismiss: boolean;\n}>;\n\n/**\n * 무엇이 popover를 여는가. `press`가 기본이고 `hover`는 포인터의 추가 진입\n * 방식이다. hover를 켜도 press 경로를 유지해야 키보드·터치 사용자가 같은\n * 콘텐츠에 도달할 수 있다.\n *\n * 별도 HoverCard는 검토했지만 표면·초점·dismiss·충돌 회피 계약은 같고 여는\n * 방식만 하나 더하는 것이므로 컴포넌트를 나누지 않는다. hover는 지나가는 포인터에\n * 바로 반응하지 않도록 지연되며, click/키보드/터치 경로를 대체하지 않는다.\n */\nexport type PopoverOpenOn = \"press\" | \"hover\";\n\nexport const popoverBehaviorDefaults = {\n openOn: \"press\" as PopoverOpenOn,\n dismissible: true,\n outsideDismiss: true,\n escapeDismiss: true,\n focusOutDismiss: true,\n} as const satisfies PopoverDismissPolicy & Readonly<{ openOn: PopoverOpenOn }>;\n\n/** hover로 열 때의 지연. 지나가는 포인터마다 열리면 화면이 깜빡인다. */\nexport const popoverHoverDelay = { open: 300, close: 150 } as const;\n\nexport type ControlledPopoverOpenState = Readonly<{\n open: boolean;\n defaultOpen?: never;\n onOpenChange(open: boolean, details: PopoverOpenChangeDetails): void;\n}>;\n\nexport type UncontrolledPopoverOpenState = Readonly<{\n open?: never;\n defaultOpen?: boolean;\n onOpenChange?: (\n open: boolean,\n details: PopoverOpenChangeDetails,\n ) => void;\n}>;\n\nexport type PopoverOpenState =\n | ControlledPopoverOpenState\n | UncontrolledPopoverOpenState;\n\n/** Products own what page-change caused this; Popover only needs \"did it happen and how.\" */\nexport type PopoverChangeHandler = PopoverOpenState[\"onOpenChange\"];\n\nconst placements = new Set<PopoverPlacement>([\"top\", \"bottom\", \"start\", \"end\"]);\nconst alignments = new Set<PopoverAlign>([\"start\", \"center\", \"end\"]);\nconst descriptorKeys = new Set([\"placement\", \"align\", \"accessibilityLabel\"]);\nconst openStateKeys = new Set([\"open\", \"defaultOpen\", \"onOpenChange\"]);\n\nfunction isObject(value: unknown): value is Readonly<Record<string, unknown>> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction rejectUnknownKeys(\n value: Readonly<Record<string, unknown>>,\n allowed: ReadonlySet<string>,\n field: string,\n): void {\n for (const key of Object.keys(value)) {\n if (!allowed.has(key)) {\n throw new TypeError(`Unsupported Popover ${field} field: ${key}`);\n }\n }\n}\n\nexport function validatePopoverDescriptor(descriptor: PopoverDescriptor): void {\n if (!isObject(descriptor)) {\n throw new TypeError(\"Popover descriptor must be an object\");\n }\n rejectUnknownKeys(descriptor, descriptorKeys, \"descriptor\");\n if (\n descriptor.placement !== undefined &&\n !placements.has(descriptor.placement)\n ) {\n throw new TypeError(\n `Unsupported Popover placement: ${String(descriptor.placement)}`,\n );\n }\n if (descriptor.align !== undefined && !alignments.has(descriptor.align)) {\n throw new TypeError(`Unsupported Popover align: ${String(descriptor.align)}`);\n }\n if (descriptor.accessibilityLabel !== undefined) {\n if (\n typeof descriptor.accessibilityLabel !== \"string\" ||\n descriptor.accessibilityLabel.trim().length === 0\n ) {\n throw new TypeError(\"Popover accessibilityLabel must not be empty\");\n }\n if (descriptor.accessibilityLabel !== descriptor.accessibilityLabel.trim()) {\n throw new TypeError(\n \"Popover accessibilityLabel must not start or end with whitespace\",\n );\n }\n }\n}\n\nexport function resolvePopoverDescriptor(\n descriptor: PopoverDescriptor,\n): ResolvedPopoverDescriptor {\n validatePopoverDescriptor(descriptor);\n return {\n placement: descriptor.placement ?? popoverDescriptorDefaults.placement,\n align: descriptor.align ?? popoverDescriptorDefaults.align,\n ...(descriptor.accessibilityLabel !== undefined\n ? { accessibilityLabel: descriptor.accessibilityLabel }\n : {}),\n };\n}\n\nexport function validatePopoverOpenState(state: PopoverOpenState): void {\n if (!isObject(state)) {\n throw new TypeError(\"Popover open state must be an object\");\n }\n rejectUnknownKeys(state, openStateKeys, \"open state\");\n const runtime = state as Readonly<Record<string, unknown>>;\n const hasOpen = Object.prototype.hasOwnProperty.call(runtime, \"open\");\n const hasDefaultOpen = Object.prototype.hasOwnProperty.call(\n runtime,\n \"defaultOpen\",\n );\n if (hasOpen) {\n if (typeof runtime.open !== \"boolean\") {\n throw new TypeError(\"Popover open must be a boolean\");\n }\n if (hasDefaultOpen) {\n throw new TypeError(\"Controlled Popover must not provide defaultOpen\");\n }\n if (typeof runtime.onOpenChange !== \"function\") {\n throw new TypeError(\"Controlled Popover must provide onOpenChange\");\n }\n return;\n }\n if (hasDefaultOpen && typeof runtime.defaultOpen !== \"boolean\") {\n throw new TypeError(\"Popover defaultOpen must be a boolean\");\n }\n if (\n runtime.onOpenChange !== undefined &&\n typeof runtime.onOpenChange !== \"function\"\n ) {\n throw new TypeError(\"Popover onOpenChange must be a function\");\n }\n}\n\n/**\n * Resolves an attempted close without platform knowledge, mirroring\n * canDismissSheet. Programmatic close is always an owner override.\n */\nexport function canDismissPopover(\n reason: PopoverDismissReason,\n policy: PopoverDismissPolicy = popoverBehaviorDefaults,\n): boolean {\n if (reason === \"programmatic\") return true;\n if (!policy.dismissible) return false;\n if (reason === \"outside-pointer\") return policy.outsideDismiss;\n if (reason === \"outside-focus\") return policy.focusOutDismiss;\n if (reason === \"escape\") return policy.escapeDismiss;\n return true;\n}\n\n/**\n * Positioning boundary is identical to Tooltip's: HJM owns preferred\n * placement, spacing, and motion; DOM measurement, portal, flip/shift, and\n * RTL logical-to-physical translation stay in the product Web renderer's\n * private AnchoredOverlay (see docs/tooltip.md \"Positioning boundary\"). This\n * module never exposes that internal tool, so Popover cannot regress Tooltip's\n * \"no public collision/portal API\" boundary.\n */\nexport const popoverRecipe = {\n slots: [\"trigger\", \"content\", \"arrow\", \"closeAction\"] as const,\n surface: floatingSurfaceContract,\n arrow: { size: spacing.xxs, offset: spacing.xxs },\n sideOffset: spacing.xs,\n collisionPadding: spacing.xs,\n minWidth: 240,\n maxWidth: 360,\n transition: { enter: motionPreset.enter, exit: motionPreset.exit },\n} as const satisfies {\n slots: readonly string[];\n surface: typeof floatingSurfaceContract;\n arrow: { size: number; offset: number };\n sideOffset: number;\n collisionPadding: number;\n minWidth: number;\n maxWidth: number;\n transition: { enter: typeof motionPreset.enter; exit: typeof motionPreset.exit };\n};\n\n/**\n * Literal scenario names for behaviorRegistry.popover (lead wires into\n * src/behaviors.ts). Kept here, not there, so this module stays self-contained\n * per the authoring brief.\n */\nexport const popoverBehaviorScenarios = [\n \"focus-enters-surface-on-open\",\n \"escape-closes-and-restores-trigger-focus\",\n \"outside-pointer-close-does-not-cancel-the-original-interaction\",\n \"tabbing-past-last-focusable-child-closes-without-trapping\",\n \"optional-hover-opens-after-delay-and-survives-pointer-crossing\",\n \"hover-mode-retains-press-activation-for-touch-and-keyboard\",\n \"controlled-owner-programmatic-close-always-wins\",\n \"close-action-inside-content-closes-exactly-once\",\n \"trigger-while-open-does-not-reopen\",\n \"one-visible-popover-per-trigger\",\n] as const;\n"]}
@@ -0,0 +1,7 @@
1
+ export declare const qrCodeRecipe: {
2
+ readonly quietZone: 4;
3
+ readonly minModuleSize: 2;
4
+ readonly foreground: "#000000";
5
+ readonly background: "#ffffff";
6
+ };
7
+ //# sourceMappingURL=qr-code-recipe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qr-code-recipe.d.ts","sourceRoot":"","sources":["../src/qr-code-recipe.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY;;;;;CAA4F,CAAC"}
@@ -0,0 +1,2 @@
1
+ export const qrCodeRecipe = { quietZone: 4, minModuleSize: 2, foreground: "#000000", background: "#ffffff" };
2
+ //# sourceMappingURL=qr-code-recipe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qr-code-recipe.js","sourceRoot":"","sources":["../src/qr-code-recipe.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,SAAS,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAW,CAAC","sourcesContent":["export const qrCodeRecipe = { quietZone: 4, minModuleSize: 2, foreground: \"#000000\", background: \"#ffffff\" } as const;\n"]}
@@ -0,0 +1,16 @@
1
+ export type QRErrorCorrection = "L" | "M" | "Q" | "H";
2
+ /** Pure encoding: hosts render the same matrix without image/network dependencies. */
3
+ export type QREncoder = (type: 0, level: QRErrorCorrection) => {
4
+ addData(value: string, mode: "Byte"): void;
5
+ make(): void;
6
+ getModuleCount(): number;
7
+ isDark(row: number, column: number): boolean;
8
+ };
9
+ export declare function createQRMatrix(value: string, encode: QREncoder, level?: QRErrorCorrection): {
10
+ count: number;
11
+ cells: boolean[][];
12
+ quietZone: 4;
13
+ };
14
+ export declare function qrPath(matrix: ReturnType<typeof createQRMatrix>): string;
15
+ export { qrCodeRecipe } from "./qr-code-recipe.js";
16
+ //# sourceMappingURL=qr-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qr-code.d.ts","sourceRoot":"","sources":["../src/qr-code.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AACtD,sFAAsF;AACtF,MAAM,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,iBAAiB,KAAK;IAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,IAAI,IAAI,IAAI,CAAC;IAAC,cAAc,IAAI,MAAM,CAAC;IAAC,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAEpM,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,GAAE,iBAAuB;;;;EAoB9F;AACD,wBAAgB,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,UAE/D;AACD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,37 @@
1
+ // Encoding is injected by renderers so the neutral contracts package stays dependency-free.
2
+ export function createQRMatrix(value, encode, level = "M") {
3
+ if (!value.trim() || !["L", "M", "Q", "H"].includes(level))
4
+ throw new TypeError("QRCode needs a value and valid error correction level");
5
+ const code = encode(0, level);
6
+ // Encode UTF-8 explicitly: the upstream default truncates non-Latin strings to bytes.
7
+ // Hermes hosts need not provide TextEncoder; preserve UTF-8 without a global polyfill.
8
+ const bytes = [];
9
+ for (const character of value) {
10
+ const raw = character.codePointAt(0);
11
+ const code = raw >= 0xd800 && raw <= 0xdfff ? 0xfffd : raw;
12
+ if (code < 0x80)
13
+ bytes.push(code);
14
+ else if (code < 0x800)
15
+ bytes.push(0xc0 | (code >> 6), 0x80 | (code & 63));
16
+ else if (code < 0x10000)
17
+ bytes.push(0xe0 | (code >> 12), 0x80 | ((code >> 6) & 63), 0x80 | (code & 63));
18
+ else
19
+ bytes.push(0xf0 | (code >> 18), 0x80 | ((code >> 12) & 63), 0x80 | ((code >> 6) & 63), 0x80 | (code & 63));
20
+ }
21
+ const binary = bytes.map(byte => String.fromCharCode(byte)).join("");
22
+ code.addData(binary, "Byte");
23
+ try {
24
+ code.make();
25
+ }
26
+ catch {
27
+ throw new RangeError("QRCode value exceeds the selected encoding capacity");
28
+ }
29
+ const count = code.getModuleCount();
30
+ const cells = Array.from({ length: count }, (_, row) => Array.from({ length: count }, (_, column) => code.isDark(row, column)));
31
+ return { count, cells, quietZone: 4 };
32
+ }
33
+ export function qrPath(matrix) {
34
+ return matrix.cells.flatMap((row, y) => row.flatMap((dark, x) => dark ? [`M${x + 4},${y + 4}h1v1h-1z`] : [])).join("");
35
+ }
36
+ export { qrCodeRecipe } from "./qr-code-recipe.js";
37
+ //# sourceMappingURL=qr-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qr-code.js","sourceRoot":"","sources":["../src/qr-code.ts"],"names":[],"mappings":"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","sourcesContent":["export type QRErrorCorrection = \"L\" | \"M\" | \"Q\" | \"H\";\n/** Pure encoding: hosts render the same matrix without image/network dependencies. */\nexport type QREncoder = (type: 0, level: QRErrorCorrection) => { addData(value: string, mode: \"Byte\"): void; make(): void; getModuleCount(): number; isDark(row: number, column: number): boolean };\n// Encoding is injected by renderers so the neutral contracts package stays dependency-free.\nexport function createQRMatrix(value: string, encode: QREncoder, level: QRErrorCorrection = \"M\") {\n if (!value.trim() || ![\"L\", \"M\", \"Q\", \"H\"].includes(level)) throw new TypeError(\"QRCode needs a value and valid error correction level\");\n const code = encode(0, level);\n // Encode UTF-8 explicitly: the upstream default truncates non-Latin strings to bytes.\n // Hermes hosts need not provide TextEncoder; preserve UTF-8 without a global polyfill.\n const bytes: number[] = [];\n for (const character of value) {\n const raw = character.codePointAt(0)!;\n const code = raw >= 0xd800 && raw <= 0xdfff ? 0xfffd : raw;\n if (code < 0x80) bytes.push(code);\n else if (code < 0x800) bytes.push(0xc0 | (code >> 6), 0x80 | (code & 63));\n else if (code < 0x10000) bytes.push(0xe0 | (code >> 12), 0x80 | ((code >> 6) & 63), 0x80 | (code & 63));\n else bytes.push(0xf0 | (code >> 18), 0x80 | ((code >> 12) & 63), 0x80 | ((code >> 6) & 63), 0x80 | (code & 63));\n }\n const binary = bytes.map(byte => String.fromCharCode(byte)).join(\"\");\n code.addData(binary, \"Byte\");\n try { code.make(); } catch { throw new RangeError(\"QRCode value exceeds the selected encoding capacity\"); }\n const count = code.getModuleCount();\n const cells = Array.from({ length: count }, (_, row) => Array.from({ length: count }, (_, column) => code.isDark(row, column)));\n return { count, cells, quietZone: 4 as const };\n}\nexport function qrPath(matrix: ReturnType<typeof createQRMatrix>) {\n return matrix.cells.flatMap((row, y) => row.flatMap((dark, x) => dark ? [`M${x + 4},${y + 4}h1v1h-1z`] : [])).join(\"\");\n}\nexport { qrCodeRecipe } from \"./qr-code-recipe.js\";\n"]}
@@ -121,7 +121,7 @@ export declare const semanticColors: {
121
121
  readonly neutral: {
122
122
  readonly background: Readonly<{
123
123
  source: "theme";
124
- key: "surfaceAlt";
124
+ key: "bg";
125
125
  alpha?: number;
126
126
  }>;
127
127
  readonly content: Readonly<{
@@ -36,7 +36,7 @@ export const semanticColors = {
36
36
  content: themeColor("onPrimary"),
37
37
  },
38
38
  neutral: {
39
- background: themeColor("surfaceAlt"),
39
+ background: themeColor("bg"),
40
40
  content: themeColor("text"),
41
41
  // A control outline is a border role. `textSub` made a resting neutral
42
42
  // action read heavier than the selected control beside it.
@@ -1 +1 @@
1
- {"version":3,"file":"semantic-colors.js","sourceRoot":"","sources":["../src/semantic-colors.ts"],"names":[],"mappings":"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","sourcesContent":["import { accentColor, themeColor } from \"./color-references.js\";\n\n/**\n * Stable role aliases above the legacy ThemeColors key set. New recipes should\n * prefer these roles so the underlying theme shape can evolve independently.\n */\nexport const semanticColors = {\n canvas: themeColor(\"bg\"),\n surface: {\n default: themeColor(\"surface\"),\n sunken: themeColor(\"surfaceAlt\"),\n raised: themeColor(\"bg\"),\n brand: themeColor(\"surfaceAccent\"),\n },\n content: {\n primary: themeColor(\"text\"),\n body: themeColor(\"textBody\"),\n secondary: themeColor(\"textMuted\"),\n tertiary: themeColor(\"textSub\"),\n decorative: themeColor(\"textWeak\"),\n brand: themeColor(\"contentBrand\"),\n danger: themeColor(\"danger\"),\n inverse: themeColor(\"onPrimary\"),\n },\n border: {\n subtle: themeColor(\"border\", 0.7),\n default: themeColor(\"border\"),\n /** Resting outline of an interactive control. */\n control: themeColor(\"borderControl\"),\n strong: themeColor(\"textWeak\"),\n focus: themeColor(\"contentBrand\"),\n danger: themeColor(\"danger\"),\n },\n action: {\n brand: {\n background: themeColor(\"primary\"),\n content: themeColor(\"onPrimary\"),\n },\n neutral: {\n background: themeColor(\"surfaceAlt\"),\n content: themeColor(\"text\"),\n // A control outline is a border role. `textSub` made a resting neutral\n // action read heavier than the selected control beside it.\n border: themeColor(\"borderControl\"),\n },\n danger: {\n background: themeColor(\"dangerFill\"),\n content: themeColor(\"onDanger\"),\n },\n },\n feedback: {\n info: {\n foreground: accentColor(\"info\"),\n background: accentColor(\"info\", 0.1),\n badgeBackground: accentColor(\"info\", 0.1),\n border: accentColor(\"info\", 0.3),\n },\n success: {\n foreground: accentColor(\"success\"),\n background: accentColor(\"success\", 0.1),\n badgeBackground: accentColor(\"success\", 0.1),\n border: accentColor(\"success\", 0.3),\n },\n warning: {\n foreground: accentColor(\"warning\"),\n background: accentColor(\"warning\", 0.1),\n badgeBackground: accentColor(\"warning\", 0.1),\n border: accentColor(\"warning\", 0.3),\n },\n attention: {\n foreground: accentColor(\"attention\"),\n background: accentColor(\"attention\", 0.1),\n badgeBackground: accentColor(\"attention\", 0.1),\n border: accentColor(\"attention\", 0.3),\n },\n danger: {\n foreground: themeColor(\"danger\"),\n background: themeColor(\"danger\", 0.1),\n badgeBackground: themeColor(\"danger\", 0.1),\n border: themeColor(\"danger\", 0.3),\n },\n },\n interaction: {\n hover: themeColor(\"text\", 0.06),\n focus: themeColor(\"contentBrand\", 0.08),\n pressed: themeColor(\"text\", 0.1),\n selected: themeColor(\"primary\", 0.1),\n },\n} as const;\n"]}
1
+ {"version":3,"file":"semantic-colors.js","sourceRoot":"","sources":["../src/semantic-colors.ts"],"names":[],"mappings":"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","sourcesContent":["import { accentColor, themeColor } from \"./color-references.js\";\n\n/**\n * Stable role aliases above the legacy ThemeColors key set. New recipes should\n * prefer these roles so the underlying theme shape can evolve independently.\n */\nexport const semanticColors = {\n canvas: themeColor(\"bg\"),\n surface: {\n default: themeColor(\"surface\"),\n sunken: themeColor(\"surfaceAlt\"),\n raised: themeColor(\"bg\"),\n brand: themeColor(\"surfaceAccent\"),\n },\n content: {\n primary: themeColor(\"text\"),\n body: themeColor(\"textBody\"),\n secondary: themeColor(\"textMuted\"),\n tertiary: themeColor(\"textSub\"),\n decorative: themeColor(\"textWeak\"),\n brand: themeColor(\"contentBrand\"),\n danger: themeColor(\"danger\"),\n inverse: themeColor(\"onPrimary\"),\n },\n border: {\n subtle: themeColor(\"border\", 0.7),\n default: themeColor(\"border\"),\n /** Resting outline of an interactive control. */\n control: themeColor(\"borderControl\"),\n strong: themeColor(\"textWeak\"),\n focus: themeColor(\"contentBrand\"),\n danger: themeColor(\"danger\"),\n },\n action: {\n brand: {\n background: themeColor(\"primary\"),\n content: themeColor(\"onPrimary\"),\n },\n neutral: {\n background: themeColor(\"bg\"),\n content: themeColor(\"text\"),\n // A control outline is a border role. `textSub` made a resting neutral\n // action read heavier than the selected control beside it.\n border: themeColor(\"borderControl\"),\n },\n danger: {\n background: themeColor(\"dangerFill\"),\n content: themeColor(\"onDanger\"),\n },\n },\n feedback: {\n info: {\n foreground: accentColor(\"info\"),\n background: accentColor(\"info\", 0.1),\n badgeBackground: accentColor(\"info\", 0.1),\n border: accentColor(\"info\", 0.3),\n },\n success: {\n foreground: accentColor(\"success\"),\n background: accentColor(\"success\", 0.1),\n badgeBackground: accentColor(\"success\", 0.1),\n border: accentColor(\"success\", 0.3),\n },\n warning: {\n foreground: accentColor(\"warning\"),\n background: accentColor(\"warning\", 0.1),\n badgeBackground: accentColor(\"warning\", 0.1),\n border: accentColor(\"warning\", 0.3),\n },\n attention: {\n foreground: accentColor(\"attention\"),\n background: accentColor(\"attention\", 0.1),\n badgeBackground: accentColor(\"attention\", 0.1),\n border: accentColor(\"attention\", 0.3),\n },\n danger: {\n foreground: themeColor(\"danger\"),\n background: themeColor(\"danger\", 0.1),\n badgeBackground: themeColor(\"danger\", 0.1),\n border: themeColor(\"danger\", 0.3),\n },\n },\n interaction: {\n hover: themeColor(\"text\", 0.06),\n focus: themeColor(\"contentBrand\", 0.08),\n pressed: themeColor(\"text\", 0.1),\n selected: themeColor(\"primary\", 0.1),\n },\n} as const;\n"]}
@@ -56,7 +56,7 @@ export declare const showcaseEnvironmentMatrix: readonly [{
56
56
  }];
57
57
  /** Bridges documentation fixtures to the same environment contract products consume. */
58
58
  export declare function getShowcaseEnvironmentInput(environment: ShowcaseEnvironment): DesignSystemEnvironmentInput;
59
- export type ShowcaseScenarioId = "contract" | "default" | "dark" | "long-copy" | "large-text" | "rtl" | "reduced-motion" | "accessibility" | "keyboard" | "platform-parity";
59
+ export type ShowcaseScenarioId = "contract" | "default" | "dark" | "long-copy" | "large-text" | "rtl" | "reduced-motion" | "accessibility" | "keyboard" | "native-actions" | "platform-parity";
60
60
  export type ShowcaseSurface = "contract" | "web" | "native";
61
61
  export type ShowcaseScenario = Readonly<{
62
62
  id: ShowcaseScenarioId;
@@ -99,6 +99,10 @@ export declare const showcaseScenarios: readonly [{
99
99
  readonly id: "keyboard";
100
100
  readonly label: "Keyboard";
101
101
  readonly description: "Focus order and documented keyboard behavior run as interaction tests.";
102
+ }, {
103
+ readonly id: "native-actions";
104
+ readonly label: "Native actions";
105
+ readonly description: "Accessible host actions and their state transitions run against the Native renderer.";
102
106
  }, {
103
107
  readonly id: "platform-parity";
104
108
  readonly label: "Web / Native parity";
@@ -1 +1 @@
1
- {"version":3,"file":"showcase.d.ts","sourceRoot":"","sources":["../src/showcase.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"showcase.d.ts","sourceRoot":"","sources":["../src/showcase.ts"],"names":[],"mappings":"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"}
package/dist/showcase.js CHANGED
@@ -101,6 +101,11 @@ export const showcaseScenarios = [
101
101
  label: "Keyboard",
102
102
  description: "Focus order and documented keyboard behavior run as interaction tests.",
103
103
  },
104
+ {
105
+ id: "native-actions",
106
+ label: "Native actions",
107
+ description: "Accessible host actions and their state transitions run against the Native renderer.",
108
+ },
104
109
  {
105
110
  id: "platform-parity",
106
111
  label: "Web / Native parity",
@@ -129,22 +134,59 @@ export function getRequiredShowcaseScenarios(entry) {
129
134
  const activeSurfaces = ["web", "native"].filter((surface) => isRendererMaturity(getComponentSurfaceStatus(entry, surface)));
130
135
  if (activeSurfaces.length === 0)
131
136
  return plannedRequirements;
132
- return ["contract", ...getRendererShowcaseScenarios(entry, activeSurfaces)];
137
+ const rendererScenarios = [...new Set(activeSurfaces.flatMap((surface) => getRendererShowcaseScenarios(entry, surface)))];
138
+ return [
139
+ "contract",
140
+ ...rendererScenarios,
141
+ ];
133
142
  }
134
143
  function isRendererMaturity(status) {
135
144
  return status === "stable" || status === "beta";
136
145
  }
137
- // 글자 슬롯이 없어 long-copy를 증명할 수 없는 컴포넌트. 근거: docs/stable-core.md 1.5.0.
138
- const textlessComponentNames = new Set(["Icon", "IconButton", "Skeleton", "Spinner", "Divider"]);
139
- function getRendererShowcaseScenarios(entry, activeSurfaces) {
146
+ // These outputs expose no consumer-authored visible prose; default and accessibility proofs remain required.
147
+ const textlessComponentNames = new Set([
148
+ "Icon", "IconButton", "Skeleton", "Spinner", "ThinkingOrb", "Divider",
149
+ "Avatar", "Asset", "CounterBadge", "Image", "VisuallyHidden", "Pagination",
150
+ // These own form/range behavior but no long-form text slot; their child fields
151
+ // and calendar cells own their copy, so duplicating that proof here misattributes it.
152
+ "Form", "DateRangePicker",
153
+ ]);
154
+ // These behaviors expose no interaction on either rendered surface.
155
+ const semanticOnlyBehaviors = new Set([
156
+ "top", "authScreen", "heading", "bottomInfo", "nativePlatform", "textFormat", "asset",
157
+ ]);
158
+ // Keep surface capability lookup local: importing behaviorRegistry here would pull every
159
+ // behavior contract into the lightweight showcase/evidence entry points. The alternative was
160
+ // importing that registry; showcase.test.ts cross-checks these names against it to prevent drift.
161
+ const webKeyboardBehaviors = new Set([
162
+ "agreement", "alertDialog", "anchor", "authProviderButton", "bottomNavigation", "breadcrumb",
163
+ "calendar", "carousel", "checkbox", "checkboxGroup", "chip", "collapsible", "combobox",
164
+ "commandPalette", "contextMenu", "dataTable", "datePicker", "dateRange", "dialog",
165
+ "disclosureGroup", "field", "filePicker", "floatingActionButton", "form", "layout", "link",
166
+ "loadMore", "menu", "menubar", "numberField", "otpField", "pagination", "passwordField",
167
+ "popover", "radioGroup", "searchField", "segmentedControl", "select", "sheet", "sidePanel",
168
+ "sidebar", "skipNav", "slider", "splitter", "switch", "tabs", "tagsInput", "toast",
169
+ "toggleGroup", "tooltip", "tour", "transferList", "tree", "uploadItem",
170
+ ]);
171
+ const nativeActionBehaviors = new Set([
172
+ "agreement", "alertDialog", "authProviderButton", "bottomNavigation", "calendar", "carousel",
173
+ "checkbox", "checkboxGroup", "chip", "collapsible", "combobox", "datePicker", "dateRange",
174
+ "dialog", "disclosureGroup", "field", "filePicker", "floatingActionButton", "form", "link",
175
+ "loadMore", "menu", "numberField", "otpField", "passwordField", "radioGroup", "searchField",
176
+ "segmentedControl", "select", "sheet", "slider", "switch", "tabs", "tagsInput", "toast",
177
+ "toggleGroup", "transferList", "uploadItem",
178
+ ]);
179
+ function getRendererShowcaseScenarios(entry, surface) {
140
180
  const requirements = rendererRequirements.filter((scenario) => scenario !== "long-copy" || !textlessComponentNames.has(entry.name));
141
- if (entry.behavior) {
181
+ // ColorPicker composes native form controls; its text commit/escape behavior still needs real keyboard proof.
182
+ if (entry.name === "ColorPicker" && surface === "web")
142
183
  requirements.push("keyboard");
143
- }
144
- if (entry.platform === "adaptive" &&
145
- activeSurfaces.includes("web") &&
146
- activeSurfaces.includes("native")) {
147
- requirements.push("platform-parity");
184
+ if (entry.behavior && !semanticOnlyBehaviors.has(entry.behavior)) {
185
+ // Web owns DOM key bindings; Native declares host accessibility actions instead, so Pressable tests must not claim physical keyboard proof.
186
+ if (surface === "web" && webKeyboardBehaviors.has(entry.behavior))
187
+ requirements.push("keyboard");
188
+ if (surface === "native" && nativeActionBehaviors.has(entry.behavior))
189
+ requirements.push("native-actions");
148
190
  }
149
191
  return requirements;
150
192
  }
@@ -156,9 +198,8 @@ export function getRequiredShowcaseEvidence(entry) {
156
198
  { surface: "contract", scenarios: ["contract"] },
157
199
  ];
158
200
  const activeSurfaces = ["web", "native"].filter((surface) => isRendererMaturity(getComponentSurfaceStatus(entry, surface)));
159
- const rendererScenarios = getRendererShowcaseScenarios(entry, activeSurfaces);
160
201
  for (const surface of activeSurfaces) {
161
- requirements.push({ surface, scenarios: rendererScenarios });
202
+ requirements.push({ surface, scenarios: getRendererShowcaseScenarios(entry, surface) });
162
203
  }
163
204
  return requirements;
164
205
  }
@@ -1 +1 @@
1
- {"version":3,"file":"showcase.js","sourceRoot":"","sources":["../src/showcase.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n componentCatalog,\n getComponentSurfaceStatus,\n type ComponentCatalogEntry,\n type ComponentStatus,\n type ComponentSurface,\n type ComponentSurfaceMaturity,\n type ComponentSurfaceStatus,\n} from \"./catalog.js\";\nimport type { ResolvedTheme } from \"./colors.js\";\nimport type {\n DesignSystemDirection,\n DesignSystemEnvironmentInput,\n DesignSystemTextScale,\n} from \"./design-system-provider.js\";\n\nexport type ShowcaseTheme = ResolvedTheme;\nexport type ShowcaseDirection = DesignSystemDirection;\n/** Closed fixture subset of the Provider's continuous text-scale signal. */\nexport type ShowcaseTextScale = 1 | 1.5 | 2;\nexport type ShowcaseMotionPreference = \"full\" | \"reduced\";\n\nexport type ShowcaseEnvironment = Readonly<{\n id: \"default\" | \"dark\" | \"large-text\" | \"rtl\" | \"reduced-motion\";\n label: string;\n theme: ShowcaseTheme;\n direction: ShowcaseDirection;\n textScale: ShowcaseTextScale;\n motion: ShowcaseMotionPreference;\n}>;\n\n/**\n * A small, deliberate environment matrix catches the high-risk differences\n * without multiplying every story into an unreadable Cartesian product.\n */\nexport const showcaseEnvironmentMatrix = [\n {\n id: \"default\",\n label: \"Light · LTR · 100%\",\n theme: \"light\",\n direction: \"ltr\",\n textScale: 1,\n motion: \"full\",\n },\n {\n id: \"dark\",\n label: \"Dark · LTR · 100%\",\n theme: \"dark\",\n direction: \"ltr\",\n textScale: 1,\n motion: \"full\",\n },\n {\n id: \"large-text\",\n label: \"Light · LTR · 200%\",\n theme: \"light\",\n direction: \"ltr\",\n textScale: 2,\n motion: \"full\",\n },\n {\n id: \"rtl\",\n label: \"Light · RTL · 100%\",\n theme: \"light\",\n direction: \"rtl\",\n textScale: 1,\n motion: \"full\",\n },\n {\n id: \"reduced-motion\",\n label: \"Light · LTR · Reduced motion\",\n theme: \"light\",\n direction: \"ltr\",\n textScale: 1,\n motion: \"reduced\",\n },\n] as const satisfies readonly ShowcaseEnvironment[];\n\n/** Bridges documentation fixtures to the same environment contract products consume. */\nexport function getShowcaseEnvironmentInput(\n environment: ShowcaseEnvironment,\n): DesignSystemEnvironmentInput {\n const textScale: DesignSystemTextScale = environment.textScale;\n return {\n theme: environment.theme,\n direction: environment.direction,\n textScale,\n reducedMotion: environment.motion === \"reduced\",\n };\n}\n\nexport type ShowcaseScenarioId =\n | \"contract\"\n | \"default\"\n | \"dark\"\n | \"long-copy\"\n | \"large-text\"\n | \"rtl\"\n | \"reduced-motion\"\n | \"accessibility\"\n | \"keyboard\"\n | \"platform-parity\";\n\nexport type ShowcaseSurface = \"contract\" | \"web\" | \"native\";\n\nexport type ShowcaseScenario = Readonly<{\n id: ShowcaseScenarioId;\n label: string;\n description: string;\n}>;\n\nexport const showcaseScenarios = [\n {\n id: \"contract\",\n label: \"Contract\",\n description: \"Anatomy, defaults, supported axes, platform and maturity are visible.\",\n },\n {\n id: \"default\",\n label: \"Default\",\n description: \"The normal state renders using recipe defaults without product overrides.\",\n },\n {\n id: \"dark\",\n label: \"Dark\",\n description: \"Semantic colors remain legible on the dark theme.\",\n },\n {\n id: \"long-copy\",\n label: \"Long copy\",\n description: \"Long Korean and English copy wraps without clipping or hiding meaning.\",\n },\n {\n id: \"large-text\",\n label: \"200% text\",\n description: \"Text can grow to 200% without truncating required information.\",\n },\n {\n id: \"rtl\",\n label: \"RTL\",\n description: \"Logical start/end layout and directional icons mirror correctly.\",\n },\n {\n id: \"reduced-motion\",\n label: \"Reduced motion\",\n description: \"Motion follows the recipe reduced-motion fallback.\",\n },\n {\n id: \"accessibility\",\n label: \"Accessibility\",\n description: \"Names, states, relationships, contrast and touch targets are inspectable.\",\n },\n {\n id: \"keyboard\",\n label: \"Keyboard\",\n description: \"Focus order and documented keyboard behavior run as interaction tests.\",\n },\n {\n id: \"platform-parity\",\n label: \"Web / Native parity\",\n description: \"Adaptive renderers preserve intent while using platform-native behavior.\",\n },\n] as const satisfies readonly ShowcaseScenario[];\n\nconst plannedRequirements = [\"contract\"] as const satisfies readonly ShowcaseScenarioId[];\nconst rendererRequirements = [\n \"default\",\n \"dark\",\n \"long-copy\",\n \"large-text\",\n \"rtl\",\n \"reduced-motion\",\n \"accessibility\",\n] as const satisfies readonly Exclude<ShowcaseScenarioId, \"contract\">[];\n\nexport type ShowcaseComponentEntry = Readonly<{\n storyId: string;\n component: ComponentCatalogEntry;\n /** Resolved Web/Native renderer maturity, including legacy catalog inputs. */\n surfaceMaturity: ComponentSurfaceMaturity;\n requirements: readonly ShowcaseEvidenceRequirement[];\n requiredScenarios: readonly ShowcaseScenarioId[];\n requiredSurfaces: readonly ShowcaseSurface[];\n}>;\n\nexport type ShowcaseEvidenceRequirement = Readonly<{\n surface: ShowcaseSurface;\n scenarios: readonly ShowcaseScenarioId[];\n}>;\n\nexport type ShowcaseEvidenceEntry = Readonly<{\n storyId: string;\n surface: ShowcaseSurface;\n scenarios: readonly ShowcaseScenarioId[];\n}>;\n\nexport type ShowcaseCoverageEntry = Readonly<{\n storyId: string;\n component: ComponentCatalogEntry;\n missingEvidence: readonly Readonly<{\n surface: ShowcaseSurface;\n scenario: ShowcaseScenarioId;\n }>[];\n missingSurfaces: readonly ShowcaseSurface[];\n missingScenarios: readonly ShowcaseScenarioId[];\n complete: boolean;\n}>;\n\nexport function getShowcaseStoryId(entry: ComponentCatalogEntry): string {\n const slug = entry.name\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .replace(/[^a-zA-Z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .toLowerCase();\n return `${entry.category}/${slug}`;\n}\n\nexport function getRequiredShowcaseScenarios(\n entry: ComponentCatalogEntry,\n): readonly ShowcaseScenarioId[] {\n const activeSurfaces = ([\"web\", \"native\"] as const).filter((surface) =>\n isRendererMaturity(getComponentSurfaceStatus(entry, surface)),\n );\n if (activeSurfaces.length === 0) return plannedRequirements;\n\n return [\"contract\", ...getRendererShowcaseScenarios(entry, activeSurfaces)];\n}\n\nfunction isRendererMaturity(\n status: ComponentSurfaceStatus,\n): status is Extract<ComponentStatus, \"stable\" | \"beta\"> {\n return status === \"stable\" || status === \"beta\";\n}\n\n// 글자 슬롯이 없어 long-copy를 증명할 수 없는 컴포넌트. 근거: docs/stable-core.md 1.5.0.\nconst textlessComponentNames: ReadonlySet<string> = new Set([\"Icon\", \"IconButton\", \"Skeleton\", \"Spinner\", \"Divider\"]);\n\nfunction getRendererShowcaseScenarios(\n entry: ComponentCatalogEntry,\n activeSurfaces: readonly ComponentSurface[],\n): readonly Exclude<ShowcaseScenarioId, \"contract\">[] {\n const requirements: Exclude<ShowcaseScenarioId, \"contract\">[] = rendererRequirements.filter(\n (scenario) => scenario !== \"long-copy\" || !textlessComponentNames.has(entry.name),\n );\n if (entry.behavior) {\n requirements.push(\"keyboard\");\n }\n if (\n entry.platform === \"adaptive\" &&\n activeSurfaces.includes(\"web\") &&\n activeSurfaces.includes(\"native\")\n ) {\n requirements.push(\"platform-parity\");\n }\n return requirements;\n}\n\nexport function getRequiredShowcaseSurfaces(\n entry: ComponentCatalogEntry,\n): readonly ShowcaseSurface[] {\n return getRequiredShowcaseEvidence(entry).map(({ surface }) => surface);\n}\n\nexport function getRequiredShowcaseEvidence(\n entry: ComponentCatalogEntry,\n): readonly ShowcaseEvidenceRequirement[] {\n const requirements: ShowcaseEvidenceRequirement[] = [\n { surface: \"contract\", scenarios: [\"contract\"] },\n ];\n const activeSurfaces = ([\"web\", \"native\"] as const).filter((surface) =>\n isRendererMaturity(getComponentSurfaceStatus(entry, surface)),\n );\n const rendererScenarios = getRendererShowcaseScenarios(entry, activeSurfaces);\n for (const surface of activeSurfaces) {\n requirements.push({ surface, scenarios: rendererScenarios });\n }\n return requirements;\n}\n\nexport function createShowcaseManifest(\n entries: readonly ComponentCatalogEntry[] = componentCatalog,\n): readonly ShowcaseComponentEntry[] {\n return entries.map((component) => ({\n storyId: getShowcaseStoryId(component),\n component,\n surfaceMaturity: {\n web: getComponentSurfaceStatus(component, \"web\"),\n native: getComponentSurfaceStatus(component, \"native\"),\n },\n requirements: getRequiredShowcaseEvidence(component),\n requiredScenarios: getRequiredShowcaseScenarios(component),\n requiredSurfaces: getRequiredShowcaseSurfaces(component),\n }));\n}\n\nexport const showcaseManifest = createShowcaseManifest();\n\nexport function createShowcaseCoverage(\n evidence: readonly ShowcaseEvidenceEntry[],\n manifest: readonly ShowcaseComponentEntry[] = showcaseManifest,\n): readonly ShowcaseCoverageEntry[] {\n return manifest.map(({ storyId, component, requirements }) => {\n const componentEvidence = evidence.filter((entry) => entry.storyId === storyId);\n const missingEvidence = requirements.flatMap(({ surface, scenarios }) =>\n scenarios\n .filter(\n (scenario) =>\n !componentEvidence.some(\n (entry) => entry.surface === surface && entry.scenarios.includes(scenario),\n ),\n )\n .map((scenario) => ({ surface, scenario })),\n );\n const missingSurfaces = [...new Set(missingEvidence.map(({ surface }) => surface))];\n const missingScenarios = [...new Set(missingEvidence.map(({ scenario }) => scenario))];\n return {\n storyId,\n component,\n missingEvidence,\n missingSurfaces,\n missingScenarios,\n complete: missingSurfaces.length === 0 && missingScenarios.length === 0,\n };\n });\n}\n\nexport function assertShowcaseCoverage(\n evidence: readonly ShowcaseEvidenceEntry[],\n manifest: readonly ShowcaseComponentEntry[] = showcaseManifest,\n): void {\n const missing = createShowcaseCoverage(evidence, manifest).filter(({ complete }) => !complete);\n if (missing.length === 0) return;\n const details = missing\n .map(({ storyId, missingEvidence }) =>\n `${storyId} (${missingEvidence.map(({ surface, scenario }) => `${surface}/${scenario}`).join(\", \") || \"none\"})`,\n )\n .join(\"\\n\");\n throw new Error(`Showcase evidence is incomplete:\\n${details}`);\n}\n\nexport function summarizeShowcaseMaturity(\n entries: readonly ComponentCatalogEntry[] = componentCatalog,\n): Readonly<Record<ComponentStatus, number>> {\n return entries.reduce<Record<ComponentStatus, number>>(\n (summary, entry) => {\n summary[entry.status] += 1;\n return summary;\n },\n { stable: 0, beta: 0, planned: 0, deprecated: 0 },\n );\n}\n"]}
1
+ {"version":3,"file":"showcase.js","sourceRoot":"","sources":["../src/showcase.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n componentCatalog,\n getComponentSurfaceStatus,\n type ComponentCatalogEntry,\n type ComponentStatus,\n type ComponentSurfaceMaturity,\n type ComponentSurfaceStatus,\n} from \"./catalog.js\";\nimport type { BehaviorName } from \"./behaviors.js\";\nimport type { ResolvedTheme } from \"./colors.js\";\nimport type {\n DesignSystemDirection,\n DesignSystemEnvironmentInput,\n DesignSystemTextScale,\n} from \"./design-system-provider.js\";\n\nexport type ShowcaseTheme = ResolvedTheme;\nexport type ShowcaseDirection = DesignSystemDirection;\n/** Closed fixture subset of the Provider's continuous text-scale signal. */\nexport type ShowcaseTextScale = 1 | 1.5 | 2;\nexport type ShowcaseMotionPreference = \"full\" | \"reduced\";\n\nexport type ShowcaseEnvironment = Readonly<{\n id: \"default\" | \"dark\" | \"large-text\" | \"rtl\" | \"reduced-motion\";\n label: string;\n theme: ShowcaseTheme;\n direction: ShowcaseDirection;\n textScale: ShowcaseTextScale;\n motion: ShowcaseMotionPreference;\n}>;\n\n/**\n * A small, deliberate environment matrix catches the high-risk differences\n * without multiplying every story into an unreadable Cartesian product.\n */\nexport const showcaseEnvironmentMatrix = [\n {\n id: \"default\",\n label: \"Light · LTR · 100%\",\n theme: \"light\",\n direction: \"ltr\",\n textScale: 1,\n motion: \"full\",\n },\n {\n id: \"dark\",\n label: \"Dark · LTR · 100%\",\n theme: \"dark\",\n direction: \"ltr\",\n textScale: 1,\n motion: \"full\",\n },\n {\n id: \"large-text\",\n label: \"Light · LTR · 200%\",\n theme: \"light\",\n direction: \"ltr\",\n textScale: 2,\n motion: \"full\",\n },\n {\n id: \"rtl\",\n label: \"Light · RTL · 100%\",\n theme: \"light\",\n direction: \"rtl\",\n textScale: 1,\n motion: \"full\",\n },\n {\n id: \"reduced-motion\",\n label: \"Light · LTR · Reduced motion\",\n theme: \"light\",\n direction: \"ltr\",\n textScale: 1,\n motion: \"reduced\",\n },\n] as const satisfies readonly ShowcaseEnvironment[];\n\n/** Bridges documentation fixtures to the same environment contract products consume. */\nexport function getShowcaseEnvironmentInput(\n environment: ShowcaseEnvironment,\n): DesignSystemEnvironmentInput {\n const textScale: DesignSystemTextScale = environment.textScale;\n return {\n theme: environment.theme,\n direction: environment.direction,\n textScale,\n reducedMotion: environment.motion === \"reduced\",\n };\n}\n\nexport type ShowcaseScenarioId =\n | \"contract\"\n | \"default\"\n | \"dark\"\n | \"long-copy\"\n | \"large-text\"\n | \"rtl\"\n | \"reduced-motion\"\n | \"accessibility\"\n | \"keyboard\"\n | \"native-actions\"\n | \"platform-parity\";\n\nexport type ShowcaseSurface = \"contract\" | \"web\" | \"native\";\n\nexport type ShowcaseScenario = Readonly<{\n id: ShowcaseScenarioId;\n label: string;\n description: string;\n}>;\n\nexport const showcaseScenarios = [\n {\n id: \"contract\",\n label: \"Contract\",\n description: \"Anatomy, defaults, supported axes, platform and maturity are visible.\",\n },\n {\n id: \"default\",\n label: \"Default\",\n description: \"The normal state renders using recipe defaults without product overrides.\",\n },\n {\n id: \"dark\",\n label: \"Dark\",\n description: \"Semantic colors remain legible on the dark theme.\",\n },\n {\n id: \"long-copy\",\n label: \"Long copy\",\n description: \"Long Korean and English copy wraps without clipping or hiding meaning.\",\n },\n {\n id: \"large-text\",\n label: \"200% text\",\n description: \"Text can grow to 200% without truncating required information.\",\n },\n {\n id: \"rtl\",\n label: \"RTL\",\n description: \"Logical start/end layout and directional icons mirror correctly.\",\n },\n {\n id: \"reduced-motion\",\n label: \"Reduced motion\",\n description: \"Motion follows the recipe reduced-motion fallback.\",\n },\n {\n id: \"accessibility\",\n label: \"Accessibility\",\n description: \"Names, states, relationships, contrast and touch targets are inspectable.\",\n },\n {\n id: \"keyboard\",\n label: \"Keyboard\",\n description: \"Focus order and documented keyboard behavior run as interaction tests.\",\n },\n {\n id: \"native-actions\",\n label: \"Native actions\",\n description: \"Accessible host actions and their state transitions run against the Native renderer.\",\n },\n {\n id: \"platform-parity\",\n label: \"Web / Native parity\",\n description: \"Adaptive renderers preserve intent while using platform-native behavior.\",\n },\n] as const satisfies readonly ShowcaseScenario[];\n\nconst plannedRequirements = [\"contract\"] as const satisfies readonly ShowcaseScenarioId[];\nconst rendererRequirements = [\n \"default\",\n \"dark\",\n \"long-copy\",\n \"large-text\",\n \"rtl\",\n \"reduced-motion\",\n \"accessibility\",\n] as const satisfies readonly Exclude<ShowcaseScenarioId, \"contract\">[];\n\nexport type ShowcaseComponentEntry = Readonly<{\n storyId: string;\n component: ComponentCatalogEntry;\n /** Resolved Web/Native renderer maturity, including legacy catalog inputs. */\n surfaceMaturity: ComponentSurfaceMaturity;\n requirements: readonly ShowcaseEvidenceRequirement[];\n requiredScenarios: readonly ShowcaseScenarioId[];\n requiredSurfaces: readonly ShowcaseSurface[];\n}>;\n\nexport type ShowcaseEvidenceRequirement = Readonly<{\n surface: ShowcaseSurface;\n scenarios: readonly ShowcaseScenarioId[];\n}>;\n\nexport type ShowcaseEvidenceEntry = Readonly<{\n storyId: string;\n surface: ShowcaseSurface;\n scenarios: readonly ShowcaseScenarioId[];\n}>;\n\nexport type ShowcaseCoverageEntry = Readonly<{\n storyId: string;\n component: ComponentCatalogEntry;\n missingEvidence: readonly Readonly<{\n surface: ShowcaseSurface;\n scenario: ShowcaseScenarioId;\n }>[];\n missingSurfaces: readonly ShowcaseSurface[];\n missingScenarios: readonly ShowcaseScenarioId[];\n complete: boolean;\n}>;\n\nexport function getShowcaseStoryId(entry: ComponentCatalogEntry): string {\n const slug = entry.name\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .replace(/[^a-zA-Z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .toLowerCase();\n return `${entry.category}/${slug}`;\n}\n\nexport function getRequiredShowcaseScenarios(\n entry: ComponentCatalogEntry,\n): readonly ShowcaseScenarioId[] {\n const activeSurfaces = ([\"web\", \"native\"] as const).filter((surface) =>\n isRendererMaturity(getComponentSurfaceStatus(entry, surface)),\n );\n if (activeSurfaces.length === 0) return plannedRequirements;\n\n const rendererScenarios = [...new Set(activeSurfaces.flatMap((surface) =>\n getRendererShowcaseScenarios(entry, surface),\n ))];\n return [\n \"contract\",\n ...rendererScenarios,\n ];\n}\n\nfunction isRendererMaturity(\n status: ComponentSurfaceStatus,\n): status is Extract<ComponentStatus, \"stable\" | \"beta\"> {\n return status === \"stable\" || status === \"beta\";\n}\n\n// These outputs expose no consumer-authored visible prose; default and accessibility proofs remain required.\nconst textlessComponentNames: ReadonlySet<string> = new Set([\n \"Icon\", \"IconButton\", \"Skeleton\", \"Spinner\", \"ThinkingOrb\", \"Divider\",\n \"Avatar\", \"Asset\", \"CounterBadge\", \"Image\", \"VisuallyHidden\", \"Pagination\",\n // These own form/range behavior but no long-form text slot; their child fields\n // and calendar cells own their copy, so duplicating that proof here misattributes it.\n \"Form\", \"DateRangePicker\",\n]);\n\n// These behaviors expose no interaction on either rendered surface.\nconst semanticOnlyBehaviors: ReadonlySet<NonNullable<ComponentCatalogEntry[\"behavior\"]>> = new Set([\n \"top\", \"authScreen\", \"heading\", \"bottomInfo\", \"nativePlatform\", \"textFormat\", \"asset\",\n]);\n\n// Keep surface capability lookup local: importing behaviorRegistry here would pull every\n// behavior contract into the lightweight showcase/evidence entry points. The alternative was\n// importing that registry; showcase.test.ts cross-checks these names against it to prevent drift.\nconst webKeyboardBehaviors: ReadonlySet<BehaviorName> = new Set([\n \"agreement\", \"alertDialog\", \"anchor\", \"authProviderButton\", \"bottomNavigation\", \"breadcrumb\",\n \"calendar\", \"carousel\", \"checkbox\", \"checkboxGroup\", \"chip\", \"collapsible\", \"combobox\",\n \"commandPalette\", \"contextMenu\", \"dataTable\", \"datePicker\", \"dateRange\", \"dialog\",\n \"disclosureGroup\", \"field\", \"filePicker\", \"floatingActionButton\", \"form\", \"layout\", \"link\",\n \"loadMore\", \"menu\", \"menubar\", \"numberField\", \"otpField\", \"pagination\", \"passwordField\",\n \"popover\", \"radioGroup\", \"searchField\", \"segmentedControl\", \"select\", \"sheet\", \"sidePanel\",\n \"sidebar\", \"skipNav\", \"slider\", \"splitter\", \"switch\", \"tabs\", \"tagsInput\", \"toast\",\n \"toggleGroup\", \"tooltip\", \"tour\", \"transferList\", \"tree\", \"uploadItem\",\n]);\nconst nativeActionBehaviors: ReadonlySet<BehaviorName> = new Set([\n \"agreement\", \"alertDialog\", \"authProviderButton\", \"bottomNavigation\", \"calendar\", \"carousel\",\n \"checkbox\", \"checkboxGroup\", \"chip\", \"collapsible\", \"combobox\", \"datePicker\", \"dateRange\",\n \"dialog\", \"disclosureGroup\", \"field\", \"filePicker\", \"floatingActionButton\", \"form\", \"link\",\n \"loadMore\", \"menu\", \"numberField\", \"otpField\", \"passwordField\", \"radioGroup\", \"searchField\",\n \"segmentedControl\", \"select\", \"sheet\", \"slider\", \"switch\", \"tabs\", \"tagsInput\", \"toast\",\n \"toggleGroup\", \"transferList\", \"uploadItem\",\n]);\n\nfunction getRendererShowcaseScenarios(\n entry: ComponentCatalogEntry,\n surface?: \"web\" | \"native\",\n): readonly Exclude<ShowcaseScenarioId, \"contract\">[] {\n const requirements: Exclude<ShowcaseScenarioId, \"contract\">[] = rendererRequirements.filter(\n (scenario) => scenario !== \"long-copy\" || !textlessComponentNames.has(entry.name),\n );\n // ColorPicker composes native form controls; its text commit/escape behavior still needs real keyboard proof.\n if (entry.name === \"ColorPicker\" && surface === \"web\") requirements.push(\"keyboard\");\n if (entry.behavior && !semanticOnlyBehaviors.has(entry.behavior)) {\n // Web owns DOM key bindings; Native declares host accessibility actions instead, so Pressable tests must not claim physical keyboard proof.\n if (surface === \"web\" && webKeyboardBehaviors.has(entry.behavior)) requirements.push(\"keyboard\");\n if (surface === \"native\" && nativeActionBehaviors.has(entry.behavior)) requirements.push(\"native-actions\");\n }\n return requirements;\n}\n\nexport function getRequiredShowcaseSurfaces(\n entry: ComponentCatalogEntry,\n): readonly ShowcaseSurface[] {\n return getRequiredShowcaseEvidence(entry).map(({ surface }) => surface);\n}\n\nexport function getRequiredShowcaseEvidence(\n entry: ComponentCatalogEntry,\n): readonly ShowcaseEvidenceRequirement[] {\n const requirements: ShowcaseEvidenceRequirement[] = [\n { surface: \"contract\", scenarios: [\"contract\"] },\n ];\n const activeSurfaces = ([\"web\", \"native\"] as const).filter((surface) =>\n isRendererMaturity(getComponentSurfaceStatus(entry, surface)),\n );\n for (const surface of activeSurfaces) {\n requirements.push({ surface, scenarios: getRendererShowcaseScenarios(entry, surface) });\n }\n return requirements;\n}\n\nexport function createShowcaseManifest(\n entries: readonly ComponentCatalogEntry[] = componentCatalog,\n): readonly ShowcaseComponentEntry[] {\n return entries.map((component) => ({\n storyId: getShowcaseStoryId(component),\n component,\n surfaceMaturity: {\n web: getComponentSurfaceStatus(component, \"web\"),\n native: getComponentSurfaceStatus(component, \"native\"),\n },\n requirements: getRequiredShowcaseEvidence(component),\n requiredScenarios: getRequiredShowcaseScenarios(component),\n requiredSurfaces: getRequiredShowcaseSurfaces(component),\n }));\n}\n\nexport const showcaseManifest = createShowcaseManifest();\n\nexport function createShowcaseCoverage(\n evidence: readonly ShowcaseEvidenceEntry[],\n manifest: readonly ShowcaseComponentEntry[] = showcaseManifest,\n): readonly ShowcaseCoverageEntry[] {\n return manifest.map(({ storyId, component, requirements }) => {\n const componentEvidence = evidence.filter((entry) => entry.storyId === storyId);\n const missingEvidence = requirements.flatMap(({ surface, scenarios }) =>\n scenarios\n .filter(\n (scenario) =>\n !componentEvidence.some(\n (entry) => entry.surface === surface && entry.scenarios.includes(scenario),\n ),\n )\n .map((scenario) => ({ surface, scenario })),\n );\n const missingSurfaces = [...new Set(missingEvidence.map(({ surface }) => surface))];\n const missingScenarios = [...new Set(missingEvidence.map(({ scenario }) => scenario))];\n return {\n storyId,\n component,\n missingEvidence,\n missingSurfaces,\n missingScenarios,\n complete: missingSurfaces.length === 0 && missingScenarios.length === 0,\n };\n });\n}\n\nexport function assertShowcaseCoverage(\n evidence: readonly ShowcaseEvidenceEntry[],\n manifest: readonly ShowcaseComponentEntry[] = showcaseManifest,\n): void {\n const missing = createShowcaseCoverage(evidence, manifest).filter(({ complete }) => !complete);\n if (missing.length === 0) return;\n const details = missing\n .map(({ storyId, missingEvidence }) =>\n `${storyId} (${missingEvidence.map(({ surface, scenario }) => `${surface}/${scenario}`).join(\", \") || \"none\"})`,\n )\n .join(\"\\n\");\n throw new Error(`Showcase evidence is incomplete:\\n${details}`);\n}\n\nexport function summarizeShowcaseMaturity(\n entries: readonly ComponentCatalogEntry[] = componentCatalog,\n): Readonly<Record<ComponentStatus, number>> {\n return entries.reduce<Record<ComponentStatus, number>>(\n (summary, entry) => {\n summary[entry.status] += 1;\n return summary;\n },\n { stable: 0, beta: 0, planned: 0, deprecated: 0 },\n );\n}\n"]}
package/dist/sidebar.d.ts CHANGED
@@ -51,7 +51,7 @@ export declare const sidebarRecipe: {
51
51
  };
52
52
  readonly background: Readonly<{
53
53
  source: "theme";
54
- key: "surfaceAlt";
54
+ key: "bg";
55
55
  alpha?: number;
56
56
  }>;
57
57
  readonly border: Readonly<{
@@ -97,7 +97,7 @@ export declare const sidebarRecipe: {
97
97
  };
98
98
  readonly highlightedBackground: Readonly<{
99
99
  source: "theme";
100
- key: "text";
100
+ key: "bg";
101
101
  alpha?: number;
102
102
  }>;
103
103
  readonly focus: {
@@ -111,7 +111,7 @@ export declare const sidebarRecipe: {
111
111
  };
112
112
  readonly selectedBackground: Readonly<{
113
113
  source: "theme";
114
- key: "primary";
114
+ key: "bg";
115
115
  alpha?: number;
116
116
  }>;
117
117
  readonly selectedIndicator: Readonly<{
package/dist/sidebar.js CHANGED
@@ -50,7 +50,7 @@ export const sidebarRecipe = {
50
50
  slots: ["root", "group", "groupLabel", "item", "label", "badge", "toggle"],
51
51
  defaults: sidebarDefaults,
52
52
  widths: { expanded: 260, collapsed: 72 },
53
- background: semanticColors.surface.sunken,
53
+ background: semanticColors.canvas,
54
54
  border: semanticColors.border.default,
55
55
  borderWidth: stroke.default,
56
56
  paddingVertical: spacing.sm,