@hjmds/design-contracts 1.6.0 → 1.8.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 (228) hide show
  1. package/THIRD_PARTY_NOTICES.md +58 -0
  2. package/dist/agreement.d.ts +3 -3
  3. package/dist/agreement.js +1 -1
  4. package/dist/agreement.js.map +1 -1
  5. package/dist/asset.d.ts +1 -1
  6. package/dist/asset.js +1 -1
  7. package/dist/asset.js.map +1 -1
  8. package/dist/base-recipes.d.ts +12 -12
  9. package/dist/base-recipes.d.ts.map +1 -1
  10. package/dist/base-recipes.js +15 -14
  11. package/dist/base-recipes.js.map +1 -1
  12. package/dist/behaviors.d.ts +1 -1
  13. package/dist/catalog.d.ts +417 -561
  14. package/dist/catalog.d.ts.map +1 -1
  15. package/dist/catalog.js +138 -90
  16. package/dist/catalog.js.map +1 -1
  17. package/dist/command-palette.d.ts +3 -3
  18. package/dist/component-contracts.d.ts +4 -4
  19. package/dist/component-contracts.d.ts.map +1 -1
  20. package/dist/component-contracts.js +5 -4
  21. package/dist/component-contracts.js.map +1 -1
  22. package/dist/component-definitions.d.ts +1 -4
  23. package/dist/component-definitions.d.ts.map +1 -1
  24. package/dist/component-definitions.js +1 -4
  25. package/dist/component-definitions.js.map +1 -1
  26. package/dist/component-recipes.d.ts +76 -83
  27. package/dist/component-recipes.d.ts.map +1 -1
  28. package/dist/component-recipes.js +29 -49
  29. package/dist/component-recipes.js.map +1 -1
  30. package/dist/component-references.d.ts +0 -15
  31. package/dist/component-references.d.ts.map +1 -1
  32. package/dist/component-references.js +0 -3
  33. package/dist/component-references.js.map +1 -1
  34. package/dist/data-table.d.ts +3 -3
  35. package/dist/data-table.js +1 -1
  36. package/dist/data-table.js.map +1 -1
  37. package/dist/date-picker.d.ts +2 -2
  38. package/dist/icon-button-recipe.d.ts +2 -2
  39. package/dist/icon-button-recipe.js +1 -1
  40. package/dist/icon-button-recipe.js.map +1 -1
  41. package/dist/image.d.ts +2 -2
  42. package/dist/image.js +2 -2
  43. package/dist/image.js.map +1 -1
  44. package/dist/index.d.ts +1 -1
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +1 -1
  47. package/dist/index.js.map +1 -1
  48. package/dist/internal/thinking-orb/braid.d.ts +3 -0
  49. package/dist/internal/thinking-orb/braid.d.ts.map +1 -0
  50. package/dist/internal/thinking-orb/braid.js +47 -0
  51. package/dist/internal/thinking-orb/braid.js.map +1 -0
  52. package/dist/internal/thinking-orb/core.d.ts +60 -0
  53. package/dist/internal/thinking-orb/core.d.ts.map +1 -0
  54. package/dist/internal/thinking-orb/core.js +86 -0
  55. package/dist/internal/thinking-orb/core.js.map +1 -0
  56. package/dist/internal/thinking-orb/lattice.d.ts +5 -0
  57. package/dist/internal/thinking-orb/lattice.d.ts.map +1 -0
  58. package/dist/internal/thinking-orb/lattice.js +187 -0
  59. package/dist/internal/thinking-orb/lattice.js.map +1 -0
  60. package/dist/internal/thinking-orb/morph.d.ts +3 -0
  61. package/dist/internal/thinking-orb/morph.d.ts.map +1 -0
  62. package/dist/internal/thinking-orb/morph.js +127 -0
  63. package/dist/internal/thinking-orb/morph.js.map +1 -0
  64. package/dist/internal/thinking-orb/orbits.d.ts +3 -0
  65. package/dist/internal/thinking-orb/orbits.d.ts.map +1 -0
  66. package/dist/internal/thinking-orb/orbits.js +68 -0
  67. package/dist/internal/thinking-orb/orbits.js.map +1 -0
  68. package/dist/internal/thinking-orb/presets.d.ts +21 -0
  69. package/dist/internal/thinking-orb/presets.d.ts.map +1 -0
  70. package/dist/internal/thinking-orb/presets.js +77 -0
  71. package/dist/internal/thinking-orb/presets.js.map +1 -0
  72. package/dist/internal/thinking-orb/profiles.d.ts +8 -0
  73. package/dist/internal/thinking-orb/profiles.d.ts.map +1 -0
  74. package/dist/internal/thinking-orb/profiles.js +158 -0
  75. package/dist/internal/thinking-orb/profiles.js.map +1 -0
  76. package/dist/internal/thinking-orb/registry.d.ts +9 -0
  77. package/dist/internal/thinking-orb/registry.d.ts.map +1 -0
  78. package/dist/internal/thinking-orb/registry.js +27 -0
  79. package/dist/internal/thinking-orb/registry.js.map +1 -0
  80. package/dist/internal/thinking-orb/ribbon.d.ts +3 -0
  81. package/dist/internal/thinking-orb/ribbon.d.ts.map +1 -0
  82. package/dist/internal/thinking-orb/ribbon.js +87 -0
  83. package/dist/internal/thinking-orb/ribbon.js.map +1 -0
  84. package/dist/internal/thinking-orb/types.d.ts +15 -0
  85. package/dist/internal/thinking-orb/types.d.ts.map +1 -0
  86. package/dist/internal/thinking-orb/types.js +4 -0
  87. package/dist/internal/thinking-orb/types.js.map +1 -0
  88. package/dist/internal/thinking-orb/web.d.ts +3 -0
  89. package/dist/internal/thinking-orb/web.d.ts.map +1 -0
  90. package/dist/internal/thinking-orb/web.js +92 -0
  91. package/dist/internal/thinking-orb/web.js.map +1 -0
  92. package/dist/masonry.d.ts +17 -0
  93. package/dist/masonry.d.ts.map +1 -0
  94. package/dist/masonry.js +18 -0
  95. package/dist/masonry.js.map +1 -0
  96. package/dist/menubar.d.ts +3 -3
  97. package/dist/menubar.js +1 -1
  98. package/dist/menubar.js.map +1 -1
  99. package/dist/number-field.d.ts +2 -2
  100. package/dist/otp-field.d.ts +1 -1
  101. package/dist/password-field.d.ts +2 -2
  102. package/dist/popover.d.ts +7 -8
  103. package/dist/popover.d.ts.map +1 -1
  104. package/dist/popover.js +2 -0
  105. package/dist/popover.js.map +1 -1
  106. package/dist/qr-code-recipe.d.ts +7 -0
  107. package/dist/qr-code-recipe.d.ts.map +1 -0
  108. package/dist/qr-code-recipe.js +2 -0
  109. package/dist/qr-code-recipe.js.map +1 -0
  110. package/dist/qr-code.d.ts +16 -0
  111. package/dist/qr-code.d.ts.map +1 -0
  112. package/dist/qr-code.js +37 -0
  113. package/dist/qr-code.js.map +1 -0
  114. package/dist/semantic-colors.d.ts +1 -1
  115. package/dist/semantic-colors.js +1 -1
  116. package/dist/semantic-colors.js.map +1 -1
  117. package/dist/showcase.d.ts +5 -1
  118. package/dist/showcase.d.ts.map +1 -1
  119. package/dist/showcase.js +51 -13
  120. package/dist/showcase.js.map +1 -1
  121. package/dist/sidebar.d.ts +3 -3
  122. package/dist/sidebar.js +1 -1
  123. package/dist/sidebar.js.map +1 -1
  124. package/dist/tag.d.ts +4 -4
  125. package/dist/tag.js +3 -3
  126. package/dist/tag.js.map +1 -1
  127. package/dist/tags-input.d.ts +3 -3
  128. package/dist/tags-input.js +1 -1
  129. package/dist/tags-input.js.map +1 -1
  130. package/dist/text-formats.d.ts +2 -2
  131. package/dist/text-formats.js +2 -2
  132. package/dist/text-formats.js.map +1 -1
  133. package/dist/thinking-orb-recipe.d.ts +15 -0
  134. package/dist/thinking-orb-recipe.d.ts.map +1 -0
  135. package/dist/thinking-orb-recipe.js +9 -0
  136. package/dist/thinking-orb-recipe.js.map +1 -0
  137. package/dist/thinking-orb.d.ts +25 -0
  138. package/dist/thinking-orb.d.ts.map +1 -0
  139. package/dist/thinking-orb.js +40 -0
  140. package/dist/thinking-orb.js.map +1 -0
  141. package/dist/toast-liquid.d.ts +116 -0
  142. package/dist/toast-liquid.d.ts.map +1 -0
  143. package/dist/toast-liquid.js +100 -0
  144. package/dist/toast-liquid.js.map +1 -0
  145. package/dist/toast.d.ts +7 -1
  146. package/dist/toast.d.ts.map +1 -1
  147. package/dist/toast.js +5 -0
  148. package/dist/toast.js.map +1 -1
  149. package/dist/toggle-group.d.ts +2 -2
  150. package/dist/toggle-group.js +3 -3
  151. package/dist/toggle-group.js.map +1 -1
  152. package/dist/transfer-list.d.ts +3 -3
  153. package/dist/transfer-list.js +1 -1
  154. package/dist/transfer-list.js.map +1 -1
  155. package/dist/tree.d.ts +2 -2
  156. package/dist/version.d.ts +1 -1
  157. package/dist/version.js +1 -1
  158. package/dist/version.js.map +1 -1
  159. package/dist/virtual-list.d.ts +13 -0
  160. package/dist/virtual-list.d.ts.map +1 -0
  161. package/dist/virtual-list.js +13 -0
  162. package/dist/virtual-list.js.map +1 -0
  163. package/docs/anchor.md +5 -4
  164. package/docs/ant-design-coverage.md +2 -2
  165. package/docs/architecture.md +6 -2
  166. package/docs/authoring-brief.md +3 -2
  167. package/docs/bottom-navigation.md +7 -6
  168. package/docs/breadcrumb.md +5 -2
  169. package/docs/calendar.md +6 -3
  170. package/docs/carousel.md +2 -2
  171. package/docs/cascader.md +6 -0
  172. package/docs/catalog-cleanup.md +7 -0
  173. package/docs/catalog-decision-status.md +3 -3
  174. package/docs/catalog-freeze.json +9 -7
  175. package/docs/collapsible.md +12 -0
  176. package/docs/command-palette.md +5 -3
  177. package/docs/consumer-policy.md +29 -12
  178. package/docs/context-menu.md +12 -2
  179. package/docs/data-table.md +11 -6
  180. package/docs/date-picker.md +6 -4
  181. package/docs/date-range.md +4 -2
  182. package/docs/description-list.md +8 -9
  183. package/docs/dialog.md +39 -0
  184. package/docs/expansion-roadmap.md +11 -7
  185. package/docs/file-picker.md +5 -3
  186. package/docs/form.md +16 -4
  187. package/docs/generated/component-maturity.md +88 -91
  188. package/docs/generated/renderer-evidence.json +1848 -1023
  189. package/docs/generated/renderer-evidence.md +153 -145
  190. package/docs/generated/showcase-manifest.json +431 -497
  191. package/docs/layout.md +8 -9
  192. package/docs/library-gap-analysis.md +1 -1
  193. package/docs/masonry.md +11 -0
  194. package/docs/mentions.md +14 -7
  195. package/docs/optional-adapters.md +106 -0
  196. package/docs/otp-field.md +2 -1
  197. package/docs/pagination.md +4 -1
  198. package/docs/password-field.md +2 -1
  199. package/docs/popover.md +9 -6
  200. package/docs/promotion-candidates.md +2 -1
  201. package/docs/qr-code.md +11 -65
  202. package/docs/react-native-completion.md +1 -1
  203. package/docs/result.md +8 -5
  204. package/docs/screen-chrome.md +2 -1
  205. package/docs/sheet.md +16 -3
  206. package/docs/showcase.md +10 -2
  207. package/docs/side-panel.md +12 -6
  208. package/docs/sidebar.md +3 -0
  209. package/docs/splitter.md +6 -6
  210. package/docs/stable-core.md +72 -0
  211. package/docs/stable-promotion.md +47 -43
  212. package/docs/tags-input.md +5 -2
  213. package/docs/theme-palette.md +27 -0
  214. package/docs/thinking-orb.md +124 -0
  215. package/docs/timeline.md +2 -3
  216. package/docs/toast.md +6 -0
  217. package/docs/tooltip.md +2 -1
  218. package/docs/tour.md +14 -8
  219. package/docs/transfer-list.md +24 -21
  220. package/docs/tree-select.md +2 -1
  221. package/docs/tree.md +12 -7
  222. package/docs/upload-item.md +7 -3
  223. package/docs/virtual-list.md +10 -67
  224. package/package.json +30 -3
  225. package/docs/app-provider.md +0 -50
  226. package/docs/border-beam.md +0 -66
  227. package/docs/chart.md +0 -33
  228. package/docs/utility.md +0 -53
@@ -0,0 +1,92 @@
1
+ // Indexed reads are bounded by the populated array length or modulo; assertions preserve upstream geometry.
2
+ // Adapted from Thinking Orbs de85557 (MIT); see THIRD_PARTY_NOTICES.md.
3
+ // Web: a constellation wires itself — the "connecting" state. Nodes drift
4
+ // on the sphere under slow value noise; any pair closer than `thr` grows an
5
+ // edge, and bright packets run along randomly re-picked node pairs.
6
+ import { fibDir, finalizeFrame, frac, hashD, lerp, makeProj, radiusScale, vnoise } from './core.js';
7
+ export const frameWeb = (size, t, o) => {
8
+ const cx = size / 2;
9
+ const cy = size / 2;
10
+ const R = (size / 2) * 0.8 * (o.spread ?? 1);
11
+ // note the projector carries the radius as its scale, so node vectors stay
12
+ // unit-length and distances below are in unit-sphere space
13
+ const pt = makeProj(t * 0.12, 0.32, cx, cy, R);
14
+ const rs = radiusScale(size, o.rsPow ?? 0.6);
15
+ const nodeN = o.nodeN ?? 30;
16
+ const thr = o.thr ?? 0.72;
17
+ const nodeR = o.nodeR ?? 1.4;
18
+ const nodeRDepth = o.nodeRDepth ?? 1.8;
19
+ // nodes: fib lattice + slow noise wander, renormalised to the surface
20
+ const nodes = [];
21
+ for (let i = 0; i < nodeN; i++) {
22
+ const d = fibDir(i, nodeN);
23
+ const x = d[0] + 0.3 * (vnoise(i * 0.31 + 9, t * 0.24) - 0.5) * 2;
24
+ const y = d[1] + 0.3 * (vnoise(i * 0.53 + 27, t * 0.21) - 0.5) * 2;
25
+ const z = d[2] + 0.3 * (vnoise(i * 0.77 + 55, t * 0.27) - 0.5) * 2;
26
+ const l = Math.sqrt(x * x + y * y + z * z);
27
+ nodes.push([x / l, y / l, z / l]);
28
+ }
29
+ const lines = [];
30
+ const dots = [];
31
+ // edges between close neighbours, alpha by proximity + depth
32
+ for (let i = 0; i < nodeN; i++) {
33
+ for (let j = i + 1; j < nodeN; j++) {
34
+ const dx = nodes[i][0] - nodes[j][0];
35
+ const dy = nodes[i][1] - nodes[j][1];
36
+ const dz = nodes[i][2] - nodes[j][2];
37
+ const dist = Math.sqrt(dx * dx + dy * dy + dz * dz);
38
+ if (dist >= thr)
39
+ continue;
40
+ const [x1, y1, z1] = pt(nodes[i][0], nodes[i][1], nodes[i][2]);
41
+ const [x2, y2, z2] = pt(nodes[j][0], nodes[j][1], nodes[j][2]);
42
+ const depth = ((z1 + z2) / 2 + 1) / 2;
43
+ lines.push({
44
+ x1,
45
+ y1,
46
+ x2,
47
+ y2,
48
+ white: 0.42,
49
+ a: (1 - dist / thr) * (0.3 + 0.55 * depth),
50
+ w: Math.max(0.6, (o.lineW ?? 0.8) * rs)
51
+ });
52
+ }
53
+ }
54
+ for (let i = 0; i < nodeN; i++) {
55
+ const [px, py, z] = pt(nodes[i][0], nodes[i][1], nodes[i][2]);
56
+ const depth = (z + 1) / 2;
57
+ const pulse = 1 + 0.25 * Math.sin(t * 1.4 + i * 2.7);
58
+ dots.push({
59
+ x: px,
60
+ y: py,
61
+ z,
62
+ r: (nodeR + nodeRDepth * depth) * pulse * rs,
63
+ white: 0.55 - 0.45 * depth
64
+ });
65
+ }
66
+ // signals: bright packets running between paired nodes
67
+ const signals = o.signals ?? 5;
68
+ for (let s = 0; s < signals; s++) {
69
+ const seg = Math.floor(t * 0.55 + s * 7.31);
70
+ const a = Math.floor(hashD(seg, s * 3.1 + 1.7) * nodeN);
71
+ const b = Math.floor(hashD(seg, s * 5.7 + 4.2) * nodeN);
72
+ if (a === b)
73
+ continue;
74
+ const f = frac(t * 0.55 + s * 7.31);
75
+ const x = lerp(nodes[a][0], nodes[b][0], f);
76
+ const y = lerp(nodes[a][1], nodes[b][1], f);
77
+ const z = lerp(nodes[a][2], nodes[b][2], f);
78
+ const l = Math.max(1e-6, Math.sqrt(x * x + y * y + z * z));
79
+ const [px, py, zr] = pt(x / l, y / l, z / l);
80
+ const depth = (zr + 1) / 2;
81
+ dots.push({
82
+ x: px,
83
+ y: py,
84
+ z: zr,
85
+ r: (nodeR * 1.5 + nodeRDepth * depth) * rs,
86
+ white: 0.05,
87
+ a: 0.5 + 0.5 * depth
88
+ });
89
+ }
90
+ return finalizeFrame(dots, lines, o.rMin);
91
+ };
92
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../../src/internal/thinking-orb/web.ts"],"names":[],"mappings":"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","sourcesContent":["// Indexed reads are bounded by the populated array length or modulo; assertions preserve upstream geometry.\n// Adapted from Thinking Orbs de85557 (MIT); see THIRD_PARTY_NOTICES.md.\n// Web: a constellation wires itself — the \"connecting\" state. Nodes drift\n// on the sphere under slow value noise; any pair closer than `thr` grows an\n// edge, and bright packets run along randomly re-picked node pairs.\n\nimport type { Dot, Line, ModeFrame } from './types.js';\nimport { fibDir, finalizeFrame, frac, hashD, lerp, makeProj, radiusScale, vnoise } from './core.js';\n\nexport const frameWeb: ModeFrame = (size, t, o) => {\n const cx = size / 2;\n const cy = size / 2;\n const R = (size / 2) * 0.8 * (o.spread ?? 1);\n // note the projector carries the radius as its scale, so node vectors stay\n // unit-length and distances below are in unit-sphere space\n const pt = makeProj(t * 0.12, 0.32, cx, cy, R);\n const rs = radiusScale(size, o.rsPow ?? 0.6);\n\n const nodeN = o.nodeN ?? 30;\n const thr = o.thr ?? 0.72;\n const nodeR = o.nodeR ?? 1.4;\n const nodeRDepth = o.nodeRDepth ?? 1.8;\n\n // nodes: fib lattice + slow noise wander, renormalised to the surface\n const nodes: Array<[number, number, number]> = [];\n for (let i = 0; i < nodeN; i++) {\n const d = fibDir(i, nodeN);\n const x = d[0] + 0.3 * (vnoise(i * 0.31 + 9, t * 0.24) - 0.5) * 2;\n const y = d[1] + 0.3 * (vnoise(i * 0.53 + 27, t * 0.21) - 0.5) * 2;\n const z = d[2] + 0.3 * (vnoise(i * 0.77 + 55, t * 0.27) - 0.5) * 2;\n const l = Math.sqrt(x * x + y * y + z * z);\n nodes.push([x / l, y / l, z / l]);\n }\n\n const lines: Line[] = [];\n const dots: Dot[] = [];\n\n // edges between close neighbours, alpha by proximity + depth\n for (let i = 0; i < nodeN; i++) {\n for (let j = i + 1; j < nodeN; j++) {\n const dx = nodes[i]![0] - nodes[j]![0];\n const dy = nodes[i]![1] - nodes[j]![1];\n const dz = nodes[i]![2] - nodes[j]![2];\n const dist = Math.sqrt(dx * dx + dy * dy + dz * dz);\n if (dist >= thr) continue;\n const [x1, y1, z1] = pt(nodes[i]![0], nodes[i]![1], nodes[i]![2]);\n const [x2, y2, z2] = pt(nodes[j]![0], nodes[j]![1], nodes[j]![2]);\n const depth = ((z1 + z2) / 2 + 1) / 2;\n lines.push({\n x1,\n y1,\n x2,\n y2,\n white: 0.42,\n a: (1 - dist / thr) * (0.3 + 0.55 * depth),\n w: Math.max(0.6, (o.lineW ?? 0.8) * rs)\n });\n }\n }\n\n for (let i = 0; i < nodeN; i++) {\n const [px, py, z] = pt(nodes[i]![0], nodes[i]![1], nodes[i]![2]);\n const depth = (z + 1) / 2;\n const pulse = 1 + 0.25 * Math.sin(t * 1.4 + i * 2.7);\n dots.push({\n x: px,\n y: py,\n z,\n r: (nodeR + nodeRDepth * depth) * pulse * rs,\n white: 0.55 - 0.45 * depth\n });\n }\n\n // signals: bright packets running between paired nodes\n const signals = o.signals ?? 5;\n for (let s = 0; s < signals; s++) {\n const seg = Math.floor(t * 0.55 + s * 7.31);\n const a = Math.floor(hashD(seg, s * 3.1 + 1.7) * nodeN);\n const b = Math.floor(hashD(seg, s * 5.7 + 4.2) * nodeN);\n if (a === b) continue;\n const f = frac(t * 0.55 + s * 7.31);\n const x = lerp(nodes[a]![0], nodes[b]![0], f);\n const y = lerp(nodes[a]![1], nodes[b]![1], f);\n const z = lerp(nodes[a]![2], nodes[b]![2], f);\n const l = Math.max(1e-6, Math.sqrt(x * x + y * y + z * z));\n const [px, py, zr] = pt(x / l, y / l, z / l);\n const depth = (zr + 1) / 2;\n dots.push({\n x: px,\n y: py,\n z: zr,\n r: (nodeR * 1.5 + nodeRDepth * depth) * rs,\n white: 0.05,\n a: 0.5 + 0.5 * depth\n });\n }\n\n return finalizeFrame(dots, lines, o.rMin);\n};\n"]}
@@ -0,0 +1,17 @@
1
+ /** Height-driven packing preserves source order; DOM/native reading order never follows columns. */
2
+ export declare function resolveMasonryLayout(heights: readonly number[], width: number, columns?: number, gap?: number): {
3
+ items: {
4
+ top: number;
5
+ left: number;
6
+ width: number;
7
+ height: number;
8
+ }[];
9
+ height: number;
10
+ itemWidth: number;
11
+ };
12
+ export declare const masonryRecipe: {
13
+ readonly layout: "shortest-column";
14
+ readonly readingOrder: "source";
15
+ readonly maxColumns: 12;
16
+ };
17
+ //# sourceMappingURL=masonry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"masonry.d.ts","sourceRoot":"","sources":["../src/masonry.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,SAAI,EAAE,GAAG,SAAK;;;;;;;;;EAYpG;AACD,eAAO,MAAM,aAAa;;;;CAAiF,CAAC"}
@@ -0,0 +1,18 @@
1
+ /** Height-driven packing preserves source order; DOM/native reading order never follows columns. */
2
+ export function resolveMasonryLayout(heights, width, columns = 2, gap = 12) {
3
+ if (!Number.isFinite(width) || width <= 0 || !Number.isInteger(columns) || columns < 1 || columns > 12 || !Number.isFinite(gap) || gap < 0)
4
+ throw new TypeError("Invalid Masonry geometry");
5
+ const itemWidth = (width - gap * (columns - 1)) / columns;
6
+ if (itemWidth <= 0 || heights.some(height => !Number.isFinite(height) || height <= 0))
7
+ throw new TypeError("Masonry items need positive dimensions");
8
+ const ends = Array(columns).fill(0);
9
+ const items = heights.map(height => {
10
+ const column = ends.indexOf(Math.min(...ends));
11
+ const top = ends[column];
12
+ ends[column] = top + height + gap;
13
+ return { top, left: column * (itemWidth + gap), width: itemWidth, height };
14
+ });
15
+ return { items, height: heights.length ? Math.max(...ends) - gap : 0, itemWidth };
16
+ }
17
+ export const masonryRecipe = { layout: "shortest-column", readingOrder: "source", maxColumns: 12 };
18
+ //# sourceMappingURL=masonry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"masonry.js","sourceRoot":"","sources":["../src/masonry.ts"],"names":[],"mappings":"AAAA,oGAAoG;AACpG,MAAM,UAAU,oBAAoB,CAAC,OAA0B,EAAE,KAAa,EAAE,OAAO,GAAG,CAAC,EAAE,GAAG,GAAG,EAAE;IACnG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,0BAA0B,CAAC,CAAC;IAC5L,MAAM,SAAS,GAAG,CAAC,KAAK,GAAG,GAAG,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;IAC1D,IAAI,SAAS,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,wCAAwC,CAAC,CAAC;IACrJ,MAAM,IAAI,GAAG,KAAK,CAAS,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;QAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAE,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,MAAM,GAAG,GAAG,CAAC;QAClC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAC7E,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;AACpF,CAAC;AACD,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,MAAM,EAAE,iBAAiB,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAW,CAAC","sourcesContent":["/** Height-driven packing preserves source order; DOM/native reading order never follows columns. */\nexport function resolveMasonryLayout(heights: readonly number[], width: number, columns = 2, gap = 12) {\n if (!Number.isFinite(width) || width <= 0 || !Number.isInteger(columns) || columns < 1 || columns > 12 || !Number.isFinite(gap) || gap < 0) throw new TypeError(\"Invalid Masonry geometry\");\n const itemWidth = (width - gap * (columns - 1)) / columns;\n if (itemWidth <= 0 || heights.some(height => !Number.isFinite(height) || height <= 0)) throw new TypeError(\"Masonry items need positive dimensions\");\n const ends = Array<number>(columns).fill(0);\n const items = heights.map(height => {\n const column = ends.indexOf(Math.min(...ends));\n const top = ends[column]!;\n ends[column] = top + height + gap;\n return { top, left: column * (itemWidth + gap), width: itemWidth, height };\n });\n return { items, height: heights.length ? Math.max(...ends) - gap : 0, itemWidth };\n}\nexport const masonryRecipe = { layout: \"shortest-column\", readingOrder: \"source\", maxColumns: 12 } as const;\n"]}
package/dist/menubar.d.ts CHANGED
@@ -40,7 +40,7 @@ export declare const menubarRecipe: {
40
40
  }>;
41
41
  readonly openBackground: Readonly<{
42
42
  source: "theme";
43
- key: "primary";
43
+ key: "bg";
44
44
  alpha?: number;
45
45
  }>;
46
46
  };
@@ -67,7 +67,7 @@ export declare const menubarRecipe: {
67
67
  };
68
68
  readonly highlightedBackground: Readonly<{
69
69
  source: "theme";
70
- key: "text";
70
+ key: "bg";
71
71
  alpha?: number;
72
72
  }>;
73
73
  readonly focus: {
@@ -81,7 +81,7 @@ export declare const menubarRecipe: {
81
81
  };
82
82
  readonly selectedBackground: Readonly<{
83
83
  source: "theme";
84
- key: "primary";
84
+ key: "bg";
85
85
  alpha?: number;
86
86
  }>;
87
87
  readonly selectedIndicator: Readonly<{
package/dist/menubar.js CHANGED
@@ -47,7 +47,7 @@ export const menubarRecipe = {
47
47
  paddingHorizontal: spacing.sm,
48
48
  radius: radius.sm,
49
49
  color: semanticColors.content.body,
50
- openBackground: semanticColors.interaction.selected,
50
+ openBackground: semanticColors.canvas,
51
51
  },
52
52
  item: collectionItemContract,
53
53
  states: { focus: focusIndicatorContract },
@@ -1 +1 @@
1
- {"version":3,"file":"menubar.js","sourceRoot":"","sources":["../src/menubar.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BehaviorContract, MenuItemDescriptor } from \"./behaviors.js\";\nimport type { ColorReference } from \"./color-references.js\";\nimport { collectionItemContract, focusIndicatorContract } from \"./component-contracts.js\";\nimport { control, radius, spacing } from \"./foundations.js\";\nimport { semanticColors } from \"./semantic-colors.js\";\n\n/**\n * 데스크톱 앱의 가로 메뉴 막대 — 파일·편집·보기처럼 항상 같은 자리에 있는 메뉴들.\n *\n * `Menu` 여러 개를 나란히 놓는 것과 다르다. 막대는 **하나의 키보드 단위**다: 메뉴가\n * 열린 상태에서 좌우 방향키를 누르면 옆 메뉴로 **넘어가고**(닫았다 여는 것이 아니라),\n * 한 번에 하나만 열린다. 독립된 Menu 세 개로는 그 이동이 성립하지 않는다.\n *\n * `Tabs`와도 다르다. Tabs는 화면을 바꾸고 선택 상태가 남는다. Menubar는 행동을 실행하고\n * 아무것도 선택되지 않은 상태로 돌아간다.\n */\nexport type MenubarMenuDescriptor<\n Key extends string = string,\n MenuKey extends string = string,\n> = Readonly<{\n id: MenuKey;\n label: string;\n items: readonly MenuItemDescriptor<Key>[];\n disabled?: boolean;\n}>;\n\nexport type MenubarDescriptor<\n Key extends string = string,\n MenuKey extends string = string,\n> = Readonly<{\n accessibilityLabel: string;\n menus: readonly MenubarMenuDescriptor<Key, MenuKey>[];\n}>;\n\nfunction assertNonEmpty(value: string, field: string): void {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new TypeError(`Menubar ${field} must not be empty`);\n }\n}\n\nexport function validateMenubarDescriptor<Key extends string, MenuKey extends string>(\n descriptor: MenubarDescriptor<Key, MenuKey>,\n): void {\n assertNonEmpty(descriptor.accessibilityLabel, \"accessibilityLabel\");\n if (!Array.isArray(descriptor.menus) || descriptor.menus.length === 0) {\n throw new RangeError(\"Menubar must contain at least one menu\");\n }\n const menuIds = new Set<MenuKey>();\n for (const menu of descriptor.menus) {\n assertNonEmpty(menu.id, \"menu id\");\n assertNonEmpty(menu.label, `menu ${menu.id} label`);\n if (menuIds.has(menu.id)) throw new TypeError(`Duplicate Menubar menu id: ${menu.id}`);\n menuIds.add(menu.id);\n if (!Array.isArray(menu.items) || menu.items.length === 0) {\n throw new RangeError(`Menubar menu ${menu.id} must contain at least one item`);\n }\n }\n}\n\n/**\n * 좌우 이동은 **비활성 메뉴를 건너뛰고 순환**한다. 막대 끝에서 멈추면 사용자가 방향을\n * 바꿔 되돌아와야 하는데, 항목이 대여섯 개뿐인 가로 막대에서는 순환이 더 짧다.\n */\nexport function resolveMenubarNavigation<Key extends string, MenuKey extends string>(\n descriptor: MenubarDescriptor<Key, MenuKey>,\n currentId: MenuKey,\n direction: \"next\" | \"previous\",\n): MenuKey {\n validateMenubarDescriptor(descriptor);\n const enabled = descriptor.menus.filter((menu) => menu.disabled !== true);\n if (enabled.length === 0) return currentId;\n const index = enabled.findIndex((menu) => menu.id === currentId);\n if (index === -1) return enabled[0]!.id;\n const next = direction === \"next\" ? index + 1 : index - 1;\n return enabled[(next + enabled.length) % enabled.length]!.id;\n}\n\nexport const menubarRecipe = {\n slots: [\"root\", \"menu\", \"label\", \"panel\", \"item\"] as const,\n minHeight: control.minTouchTarget,\n gap: spacing.xxs,\n paddingHorizontal: spacing.xs,\n label: {\n paddingHorizontal: spacing.sm,\n radius: radius.sm,\n color: semanticColors.content.body,\n openBackground: semanticColors.interaction.selected,\n },\n item: collectionItemContract,\n states: { focus: focusIndicatorContract },\n} as const satisfies {\n slots: readonly [\"root\", \"menu\", \"label\", \"panel\", \"item\"];\n minHeight: number;\n gap: number;\n paddingHorizontal: number;\n label: { paddingHorizontal: number; radius: number; color: ColorReference; openBackground: ColorReference };\n item: typeof collectionItemContract;\n states: { focus: typeof focusIndicatorContract };\n};\n\nexport const menubarBehavior = {\n controlled: [\"openMenuId\", \"defaultOpenMenuId\", \"onOpenMenuIdChange\"],\n inputs: [\"menus\", \"accessibilityLabel\"],\n events: [\"onAction\"],\n stateAxes: {\n availability: [\"enabled\", \"disabled\"],\n value: [\"open\", \"closed\"],\n interaction: [\"idle\", \"hover\", \"focusVisible\"],\n },\n web: {\n roles: [\"menubar\", \"menuitem\", \"menu\"],\n keyboard: [\"ArrowLeft\", \"ArrowRight\", \"ArrowDown\", \"ArrowUp\", \"Home\", \"End\", \"Enter\", \"Space\", \"Escape\"],\n focus: \"roving\",\n dismiss: [\"escape\", \"outside\"],\n },\n /** Web-only: a phone has no always-present menu bar, and a native app bar is the OS's. */\n native: { roles: [], states: [], actions: [] },\n scenarios: [\n \"left-and-right-move-between-menus-while-one-is-open-instead-of-closing-and-reopening\",\n \"exactly-one-menu-is-open-at-a-time-which-three-independent-menus-cannot-guarantee\",\n \"disabled-menus-are-skipped-by-navigation-and-cycling-is-shorter-than-stopping-at-the-end\",\n \"the-bar-is-a-single-tab-stop-with-roving-focus-not-one-stop-per-menu\",\n \"activating-an-item-runs-an-action-and-leaves-nothing-selected-unlike-tabs\",\n ],\n} as const satisfies BehaviorContract;\n"]}
1
+ {"version":3,"file":"menubar.js","sourceRoot":"","sources":["../src/menubar.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BehaviorContract, MenuItemDescriptor } from \"./behaviors.js\";\nimport type { ColorReference } from \"./color-references.js\";\nimport { collectionItemContract, focusIndicatorContract } from \"./component-contracts.js\";\nimport { control, radius, spacing } from \"./foundations.js\";\nimport { semanticColors } from \"./semantic-colors.js\";\n\n/**\n * 데스크톱 앱의 가로 메뉴 막대 — 파일·편집·보기처럼 항상 같은 자리에 있는 메뉴들.\n *\n * `Menu` 여러 개를 나란히 놓는 것과 다르다. 막대는 **하나의 키보드 단위**다: 메뉴가\n * 열린 상태에서 좌우 방향키를 누르면 옆 메뉴로 **넘어가고**(닫았다 여는 것이 아니라),\n * 한 번에 하나만 열린다. 독립된 Menu 세 개로는 그 이동이 성립하지 않는다.\n *\n * `Tabs`와도 다르다. Tabs는 화면을 바꾸고 선택 상태가 남는다. Menubar는 행동을 실행하고\n * 아무것도 선택되지 않은 상태로 돌아간다.\n */\nexport type MenubarMenuDescriptor<\n Key extends string = string,\n MenuKey extends string = string,\n> = Readonly<{\n id: MenuKey;\n label: string;\n items: readonly MenuItemDescriptor<Key>[];\n disabled?: boolean;\n}>;\n\nexport type MenubarDescriptor<\n Key extends string = string,\n MenuKey extends string = string,\n> = Readonly<{\n accessibilityLabel: string;\n menus: readonly MenubarMenuDescriptor<Key, MenuKey>[];\n}>;\n\nfunction assertNonEmpty(value: string, field: string): void {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new TypeError(`Menubar ${field} must not be empty`);\n }\n}\n\nexport function validateMenubarDescriptor<Key extends string, MenuKey extends string>(\n descriptor: MenubarDescriptor<Key, MenuKey>,\n): void {\n assertNonEmpty(descriptor.accessibilityLabel, \"accessibilityLabel\");\n if (!Array.isArray(descriptor.menus) || descriptor.menus.length === 0) {\n throw new RangeError(\"Menubar must contain at least one menu\");\n }\n const menuIds = new Set<MenuKey>();\n for (const menu of descriptor.menus) {\n assertNonEmpty(menu.id, \"menu id\");\n assertNonEmpty(menu.label, `menu ${menu.id} label`);\n if (menuIds.has(menu.id)) throw new TypeError(`Duplicate Menubar menu id: ${menu.id}`);\n menuIds.add(menu.id);\n if (!Array.isArray(menu.items) || menu.items.length === 0) {\n throw new RangeError(`Menubar menu ${menu.id} must contain at least one item`);\n }\n }\n}\n\n/**\n * 좌우 이동은 **비활성 메뉴를 건너뛰고 순환**한다. 막대 끝에서 멈추면 사용자가 방향을\n * 바꿔 되돌아와야 하는데, 항목이 대여섯 개뿐인 가로 막대에서는 순환이 더 짧다.\n */\nexport function resolveMenubarNavigation<Key extends string, MenuKey extends string>(\n descriptor: MenubarDescriptor<Key, MenuKey>,\n currentId: MenuKey,\n direction: \"next\" | \"previous\",\n): MenuKey {\n validateMenubarDescriptor(descriptor);\n const enabled = descriptor.menus.filter((menu) => menu.disabled !== true);\n if (enabled.length === 0) return currentId;\n const index = enabled.findIndex((menu) => menu.id === currentId);\n if (index === -1) return enabled[0]!.id;\n const next = direction === \"next\" ? index + 1 : index - 1;\n return enabled[(next + enabled.length) % enabled.length]!.id;\n}\n\nexport const menubarRecipe = {\n slots: [\"root\", \"menu\", \"label\", \"panel\", \"item\"] as const,\n minHeight: control.minTouchTarget,\n gap: spacing.xxs,\n paddingHorizontal: spacing.xs,\n label: {\n paddingHorizontal: spacing.sm,\n radius: radius.sm,\n color: semanticColors.content.body,\n openBackground: semanticColors.canvas,\n },\n item: collectionItemContract,\n states: { focus: focusIndicatorContract },\n} as const satisfies {\n slots: readonly [\"root\", \"menu\", \"label\", \"panel\", \"item\"];\n minHeight: number;\n gap: number;\n paddingHorizontal: number;\n label: { paddingHorizontal: number; radius: number; color: ColorReference; openBackground: ColorReference };\n item: typeof collectionItemContract;\n states: { focus: typeof focusIndicatorContract };\n};\n\nexport const menubarBehavior = {\n controlled: [\"openMenuId\", \"defaultOpenMenuId\", \"onOpenMenuIdChange\"],\n inputs: [\"menus\", \"accessibilityLabel\"],\n events: [\"onAction\"],\n stateAxes: {\n availability: [\"enabled\", \"disabled\"],\n value: [\"open\", \"closed\"],\n interaction: [\"idle\", \"hover\", \"focusVisible\"],\n },\n web: {\n roles: [\"menubar\", \"menuitem\", \"menu\"],\n keyboard: [\"ArrowLeft\", \"ArrowRight\", \"ArrowDown\", \"ArrowUp\", \"Home\", \"End\", \"Enter\", \"Space\", \"Escape\"],\n focus: \"roving\",\n dismiss: [\"escape\", \"outside\"],\n },\n /** Web-only: a phone has no always-present menu bar, and a native app bar is the OS's. */\n native: { roles: [], states: [], actions: [] },\n scenarios: [\n \"left-and-right-move-between-menus-while-one-is-open-instead-of-closing-and-reopening\",\n \"exactly-one-menu-is-open-at-a-time-which-three-independent-menus-cannot-guarantee\",\n \"disabled-menus-are-skipped-by-navigation-and-cycling-is-shorter-than-stopping-at-the-end\",\n \"the-bar-is-a-single-tab-stop-with-roving-focus-not-one-stop-per-menu\",\n \"activating-an-item-runs-an-action-and-leaves-nothing-selected-unlike-tabs\",\n ],\n} as const satisfies BehaviorContract;\n"]}
@@ -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":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AA4DzD,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,SAAS,EAAE,QAAQ;IACnB,KAAK,EAAE,OAAO;CACmE,CAAC;AA2BpF,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,MAAM,EAAE,OAAwB;IAChC,WAAW,EAAE,IAAI;IACjB,cAAc,EAAE,IAAI;IACpB,aAAa,EAAE,IAAI;IACnB,eAAe,EAAE,IAAI;CACwD,CAAC;AAEhF,+CAA+C;AAC/C,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAW,CAAC;AAwBpE,MAAM,UAAU,GAAG,IAAI,GAAG,CAAmB,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;AAChF,MAAM,UAAU,GAAG,IAAI,GAAG,CAAe,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;AACrE,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC;AAC7E,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,aAAa,EAAE,cAAc,CAAC,CAAC,CAAC;AAEvE,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,iBAAiB,CACxB,KAAwC,EACxC,OAA4B,EAC5B,KAAa;IAEb,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,SAAS,CAAC,uBAAuB,KAAK,WAAW,GAAG,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,UAA6B;IACrE,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,SAAS,CAAC,sCAAsC,CAAC,CAAC;IAC9D,CAAC;IACD,iBAAiB,CAAC,UAAU,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;IAC5D,IACE,UAAU,CAAC,SAAS,KAAK,SAAS;QAClC,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,EACrC,CAAC;QACD,MAAM,IAAI,SAAS,CACjB,kCAAkC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CACjE,CAAC;IACJ,CAAC;IACD,IAAI,UAAU,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACxE,MAAM,IAAI,SAAS,CAAC,8BAA8B,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,UAAU,CAAC,kBAAkB,KAAK,SAAS,EAAE,CAAC;QAChD,IACE,OAAO,UAAU,CAAC,kBAAkB,KAAK,QAAQ;YACjD,UAAU,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EACjD,CAAC;YACD,MAAM,IAAI,SAAS,CAAC,8CAA8C,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,UAAU,CAAC,kBAAkB,KAAK,UAAU,CAAC,kBAAkB,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3E,MAAM,IAAI,SAAS,CACjB,kEAAkE,CACnE,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,UAA6B;IAE7B,yBAAyB,CAAC,UAAU,CAAC,CAAC;IACtC,OAAO;QACL,SAAS,EAAE,UAAU,CAAC,SAAS,IAAI,yBAAyB,CAAC,SAAS;QACtE,KAAK,EAAE,UAAU,CAAC,KAAK,IAAI,yBAAyB,CAAC,KAAK;QAC1D,GAAG,CAAC,UAAU,CAAC,kBAAkB,KAAK,SAAS;YAC7C,CAAC,CAAC,EAAE,kBAAkB,EAAE,UAAU,CAAC,kBAAkB,EAAE;YACvD,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAuB;IAC9D,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,SAAS,CAAC,sCAAsC,CAAC,CAAC;IAC9D,CAAC;IACD,iBAAiB,CAAC,KAAK,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC;IACtD,MAAM,OAAO,GAAG,KAA0C,CAAC;IAC3D,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACtE,MAAM,cAAc,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CACzD,OAAO,EACP,aAAa,CACd,CAAC;IACF,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACtC,MAAM,IAAI,SAAS,CAAC,gCAAgC,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,cAAc,EAAE,CAAC;YACnB,MAAM,IAAI,SAAS,CAAC,iDAAiD,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,OAAO,OAAO,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;YAC/C,MAAM,IAAI,SAAS,CAAC,8CAA8C,CAAC,CAAC;QACtE,CAAC;QACD,OAAO;IACT,CAAC;IACD,IAAI,cAAc,IAAI,OAAO,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QAC/D,MAAM,IAAI,SAAS,CAAC,uCAAuC,CAAC,CAAC;IAC/D,CAAC;IACD,IACE,OAAO,CAAC,YAAY,KAAK,SAAS;QAClC,OAAO,OAAO,CAAC,YAAY,KAAK,UAAU,EAC1C,CAAC;QACD,MAAM,IAAI,SAAS,CAAC,yCAAyC,CAAC,CAAC;IACjE,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAA4B,EAC5B,SAA+B,uBAAuB;IAEtD,IAAI,MAAM,KAAK,cAAc;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,CAAC,MAAM,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC;IACtC,IAAI,MAAM,KAAK,iBAAiB;QAAE,OAAO,MAAM,CAAC,cAAc,CAAC;IAC/D,IAAI,MAAM,KAAK,eAAe;QAAE,OAAO,MAAM,CAAC,eAAe,CAAC;IAC9D,IAAI,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,aAAa,CAAC;IACrD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,KAAK,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,CAAU;IAC9D,OAAO,EAAE,uBAAuB;IAChC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE;IACjD,UAAU,EAAE,OAAO,CAAC,EAAE;IACtB,gBAAgB,EAAE,OAAO,CAAC,EAAE;IAC5B,QAAQ,EAAE,GAAG;IACb,QAAQ,EAAE,GAAG;IACb,UAAU,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE;CAUnE,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,8BAA8B;IAC9B,0CAA0C;IAC1C,gEAAgE;IAChE,2DAA2D;IAC3D,gEAAgE;IAChE,4DAA4D;IAC5D,iDAAiD;IACjD,iDAAiD;IACjD,oCAAoC;IACpC,iCAAiC;CACzB,CAAC","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":"AAGA,4FAA4F;AAC5F,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,MAAiB,EAAE,QAA2B,GAAG;IAC7F,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,uDAAuD,CAAC,CAAC;IACzI,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC9B,sFAAsF;IACtF,uFAAuF;IACvF,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,SAAS,IAAI,KAAK,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC;QACtC,MAAM,IAAI,GAAG,GAAG,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;QAC3D,IAAI,IAAI,GAAG,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aAC7B,IAAI,IAAI,GAAG,KAAK;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;aACrE,IAAI,IAAI,GAAG,OAAO;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;;YACnG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;IAClH,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,IAAI,CAAC;QAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,MAAM,IAAI,UAAU,CAAC,qDAAqD,CAAC,CAAC;IAAC,CAAC;IAC3G,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;IACpC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAChI,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAU,EAAE,CAAC;AACjD,CAAC;AACD,MAAM,UAAU,MAAM,CAAC,MAAyC;IAC9D,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACzH,CAAC;AACD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC","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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"}