@dreamboard-games/sdk 0.2.1-alpha.1 → 0.3.0-alpha.1

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 (372) hide show
  1. package/dist/{HandView-ncJIVLhN.d.ts → HandView-PYDmehVD.d.ts} +1 -1
  2. package/dist/{ResourceCounter-CTREyF73.d.ts → ResourceCounter-BTXklCEZ.d.ts} +1 -1
  3. package/dist/{ThemeProvider-BBMVT3KG.d.ts → ThemeProvider-DvMl17Ny.d.ts} +1 -1
  4. package/dist/{chunk-NKCRKGR2.js → chunk-3RQEICD3.js} +2 -2
  5. package/dist/{chunk-ZABVH7AO.js → chunk-ADYH6PVT.js} +1336 -1363
  6. package/dist/chunk-ADYH6PVT.js.map +1 -0
  7. package/dist/{chunk-PEI3FIL2.js → chunk-P7VMTJ5D.js} +2 -2
  8. package/dist/{chunk-PEI3FIL2.js.map → chunk-P7VMTJ5D.js.map} +1 -1
  9. package/dist/{chunk-WG4JQL3S.js → chunk-QZ6X4B5P.js} +1177 -1109
  10. package/dist/chunk-QZ6X4B5P.js.map +1 -0
  11. package/dist/{chunk-MZNVHMJ5.js → chunk-TXXLS3OI.js} +405 -309
  12. package/dist/chunk-TXXLS3OI.js.map +1 -0
  13. package/dist/{chunk-FDNZTDD6.js → chunk-W6SGFWXH.js} +48 -44
  14. package/dist/chunk-W6SGFWXH.js.map +1 -0
  15. package/dist/{chunk-MKXPVOUT.js → chunk-Y2AFYBMB.js} +48 -4
  16. package/dist/chunk-Y2AFYBMB.js.map +1 -0
  17. package/dist/{index-BwqPQtBu.d.ts → codegen.d.ts} +57 -565
  18. package/dist/{infrastructure/workspace-codegen.js → codegen.js} +3 -3
  19. package/dist/{components-BoiVSYqx.d.ts → components-DaIqi9QM.d.ts} +48 -37
  20. package/dist/{hex-board-view-1iAyJRFn.d.ts → hex-board-view-UCUjMALd.d.ts} +2 -2
  21. package/dist/{infrastructure/reducer-bundle-abi.d.ts → index.d-BGqVifr_.d.ts} +289 -10
  22. package/dist/index.js +1 -1
  23. package/dist/package-set.d.ts +2 -2
  24. package/dist/package-set.js +1 -1
  25. package/dist/primitive-props-BNHDkgd7.d.ts +16 -0
  26. package/dist/reducer-contract.d.ts +3 -0
  27. package/dist/{infrastructure/reducer-bundle-abi.js → reducer-contract.js} +4 -4
  28. package/dist/reducer.d.ts +185 -179
  29. package/dist/reducer.js +1363 -1372
  30. package/dist/reducer.js.map +1 -1
  31. package/dist/runtime/primitives.d.ts +9 -9
  32. package/dist/runtime/primitives.js +7 -7
  33. package/dist/runtime/runtime-api.d.ts +2 -0
  34. package/dist/runtime/runtime-api.js +1 -0
  35. package/dist/runtime/workspace-contract.d.ts +62 -17
  36. package/dist/runtime/workspace-contract.js +5 -6
  37. package/dist/{runtime-api-CPLm_XDG.d.ts → runtime-api-tGL3ArsB.d.ts} +103 -4
  38. package/dist/runtime.d.ts +11 -57
  39. package/dist/runtime.js +487 -8
  40. package/dist/runtime.js.map +1 -1
  41. package/dist/testing.d.ts +4 -4
  42. package/dist/testing.js.map +1 -1
  43. package/dist/types.d.ts +1531 -85
  44. package/dist/types.js +1 -3
  45. package/dist/types.js.map +1 -1
  46. package/dist/ui/components.d.ts +7 -8
  47. package/dist/ui/components.js +1 -1
  48. package/dist/ui/defaults.d.ts +1 -1
  49. package/dist/ui/{types/player-state.d.ts → player-state.d.ts} +2 -2
  50. package/dist/{ui-contract-rzKBwOLC.d.ts → ui-contract-SctM4ibF.d.ts} +155 -150
  51. package/dist/ui.d.ts +10 -11
  52. package/dist/ui.js +2 -2
  53. package/package.json +30 -75
  54. package/dist/bundle-CDd5FKeD.d.ts +0 -283
  55. package/dist/cards-Sl3b40Mv.d.ts +0 -13
  56. package/dist/chunk-326PGVAA.js +0 -34
  57. package/dist/chunk-326PGVAA.js.map +0 -1
  58. package/dist/chunk-FDNZTDD6.js.map +0 -1
  59. package/dist/chunk-I46YJSOD.js +0 -1
  60. package/dist/chunk-MKXPVOUT.js.map +0 -1
  61. package/dist/chunk-MZNVHMJ5.js.map +0 -1
  62. package/dist/chunk-T52J5RMF.js +0 -1
  63. package/dist/chunk-WG4JQL3S.js.map +0 -1
  64. package/dist/chunk-XV6D3ET4.js +0 -485
  65. package/dist/chunk-XV6D3ET4.js.map +0 -1
  66. package/dist/chunk-ZABVH7AO.js.map +0 -1
  67. package/dist/generated/runtime/primitives.d.ts +0 -13
  68. package/dist/generated/runtime/primitives.js +0 -181
  69. package/dist/generated/runtime/primitives.js.map +0 -1
  70. package/dist/generated/runtime-api.d.ts +0 -3
  71. package/dist/generated/runtime-api.js +0 -2
  72. package/dist/generated/runtime.d.ts +0 -15
  73. package/dist/generated/runtime.js +0 -19
  74. package/dist/generated/runtime.js.map +0 -1
  75. package/dist/generated/workspace-contract.d.ts +0 -15
  76. package/dist/generated/workspace-contract.js +0 -15
  77. package/dist/generated/workspace-contract.js.map +0 -1
  78. package/dist/infrastructure/reducer-bundle-abi.js.map +0 -1
  79. package/dist/infrastructure/workspace-codegen.d.ts +0 -53
  80. package/dist/infrastructure/workspace-codegen.js.map +0 -1
  81. package/dist/manifest-contract-BNHVGFtU.d.ts +0 -9
  82. package/dist/primitive-props-DpKs-GCr.d.ts +0 -11
  83. package/dist/runtime/types/runtime-api.d.ts +0 -1
  84. package/dist/runtime/types/runtime-api.js +0 -2
  85. package/dist/runtime/types/runtime-api.js.map +0 -1
  86. package/dist/runtime-api-3dshj6kK.d.ts +0 -101
  87. package/dist/slots-1GPGihk8.d.ts +0 -8
  88. package/src/browser-interaction/attributes.ts +0 -211
  89. package/src/browser-interaction/canonical.ts +0 -77
  90. package/src/browser-interaction/constants.ts +0 -77
  91. package/src/browser-interaction/effects.ts +0 -176
  92. package/src/browser-interaction/index.ts +0 -111
  93. package/src/browser-interaction/normalize.ts +0 -997
  94. package/src/browser-interaction/registry.ts +0 -70
  95. package/src/browser-interaction/resolve.ts +0 -596
  96. package/src/browser-interaction/schemas.ts +0 -152
  97. package/src/browser-interaction/types.ts +0 -304
  98. package/src/browser-interaction.ts +0 -1
  99. package/src/generated/reducer-contract/builders.ts +0 -90
  100. package/src/generated/reducer-contract/version.ts +0 -9
  101. package/src/generated/reducer-contract/wire.ts +0 -100
  102. package/src/generated/reducer-contract/zod.ts +0 -103
  103. package/src/generated/runtime/primitives.ts +0 -2
  104. package/src/generated/runtime-api.ts +0 -5
  105. package/src/generated/runtime.ts +0 -35
  106. package/src/generated/workspace-contract.ts +0 -2
  107. package/src/index.ts +0 -7
  108. package/src/infrastructure/reducer-bundle-abi.ts +0 -8
  109. package/src/infrastructure/reducer-contract/bundle.ts +0 -37
  110. package/src/infrastructure/workspace-codegen/hex-geometry.ts +0 -69
  111. package/src/infrastructure/workspace-codegen/index.ts +0 -64
  112. package/src/infrastructure/workspace-codegen/manifest-contract.ts +0 -6632
  113. package/src/infrastructure/workspace-codegen/manifest-validation.ts +0 -795
  114. package/src/infrastructure/workspace-codegen/ownership.ts +0 -131
  115. package/src/infrastructure/workspace-codegen/preset-card-sets.ts +0 -169
  116. package/src/infrastructure/workspace-codegen/seeds.ts +0 -1705
  117. package/src/infrastructure/workspace-codegen.ts +0 -1
  118. package/src/package-set.ts +0 -19
  119. package/src/reducer/authoring/contract.ts +0 -157
  120. package/src/reducer/authoring/effect.ts +0 -224
  121. package/src/reducer/authoring/game.ts +0 -23
  122. package/src/reducer/authoring/interaction.ts +0 -98
  123. package/src/reducer/authoring/phase.ts +0 -300
  124. package/src/reducer/authoring/types.ts +0 -70
  125. package/src/reducer/authoring/validation.ts +0 -382
  126. package/src/reducer/authoring/view-stage.ts +0 -68
  127. package/src/reducer/authoring.ts +0 -29
  128. package/src/reducer/bundle/ingress-bundle.ts +0 -491
  129. package/src/reducer/bundle/trusted/engine-instruction-resolver.ts +0 -254
  130. package/src/reducer/bundle/trusted/flow-instruction-resolver.ts +0 -73
  131. package/src/reducer/bundle/trusted/instruction-runner.ts +0 -414
  132. package/src/reducer/bundle/trusted/interaction-authorization.ts +0 -137
  133. package/src/reducer/bundle/trusted/interaction-collectors.ts +0 -859
  134. package/src/reducer/bundle/trusted/interaction-decision.ts +0 -747
  135. package/src/reducer/bundle/trusted/interaction-resolver.ts +0 -95
  136. package/src/reducer/bundle/trusted/interaction-types.ts +0 -174
  137. package/src/reducer/bundle/trusted/lifecycle-runner.ts +0 -427
  138. package/src/reducer/bundle/trusted/projection-builder.ts +0 -680
  139. package/src/reducer/bundle/trusted/projection-context.ts +0 -39
  140. package/src/reducer/bundle/trusted/rng-sampler.ts +0 -150
  141. package/src/reducer/bundle/trusted/runtime-registry.ts +0 -120
  142. package/src/reducer/bundle/trusted/runtime-scope.ts +0 -336
  143. package/src/reducer/bundle/trusted/simultaneous-player.ts +0 -97
  144. package/src/reducer/bundle/trusted/stage-resolver.ts +0 -87
  145. package/src/reducer/bundle/trusted/static-projection.ts +0 -116
  146. package/src/reducer/bundle/trusted/trusted-runtime-args.ts +0 -97
  147. package/src/reducer/bundle/trusted/trusted-runtime-result.ts +0 -39
  148. package/src/reducer/bundle/trusted/trusted-setup-profiles.ts +0 -43
  149. package/src/reducer/bundle/trusted/trusted-state-codec.ts +0 -48
  150. package/src/reducer/bundle/trusted-bundle.ts +0 -97
  151. package/src/reducer/bundle/types.ts +0 -171
  152. package/src/reducer/bundle.ts +0 -2
  153. package/src/reducer/client-param-schemas.ts +0 -57
  154. package/src/reducer/compose.ts +0 -34
  155. package/src/reducer/core/runtime-input.ts +0 -30
  156. package/src/reducer/core/runtime-instruction.ts +0 -59
  157. package/src/reducer/core/types.ts +0 -62
  158. package/src/reducer/definition-index.ts +0 -277
  159. package/src/reducer/derived.ts +0 -106
  160. package/src/reducer/effects.ts +0 -92
  161. package/src/reducer/engine/runtime-instruction-engine.ts +0 -155
  162. package/src/reducer/ingress/decode-runtime-input.ts +0 -7
  163. package/src/reducer/ingress/decode-session-state.ts +0 -9
  164. package/src/reducer/ingress/encode-session-state.ts +0 -6
  165. package/src/reducer/ingress/input-codec.ts +0 -18
  166. package/src/reducer/ingress/phase-schemas.ts +0 -62
  167. package/src/reducer/ingress/raw-types.ts +0 -107
  168. package/src/reducer/ingress/runtime-codec.ts +0 -14
  169. package/src/reducer/ingress/runtime-payload.ts +0 -13
  170. package/src/reducer/ingress/session-codec.ts +0 -392
  171. package/src/reducer/ingress/types.ts +0 -6
  172. package/src/reducer/inputs/boardInput.ts +0 -217
  173. package/src/reducer/inputs/boardTarget.ts +0 -190
  174. package/src/reducer/inputs/cardInput.ts +0 -86
  175. package/src/reducer/inputs/cardTarget.ts +0 -101
  176. package/src/reducer/inputs/choiceTarget.ts +0 -104
  177. package/src/reducer/inputs/defineInputs.ts +0 -71
  178. package/src/reducer/inputs/formInput.ts +0 -809
  179. package/src/reducer/inputs/many.ts +0 -120
  180. package/src/reducer/inputs/promptInput.ts +0 -87
  181. package/src/reducer/inputs/rngInput.ts +0 -58
  182. package/src/reducer/inputs/targetRule.ts +0 -123
  183. package/src/reducer/inputs.ts +0 -41
  184. package/src/reducer/model/definition.ts +0 -1072
  185. package/src/reducer/model/extract.ts +0 -745
  186. package/src/reducer/model/manifest.ts +0 -570
  187. package/src/reducer/model/queries.ts +0 -641
  188. package/src/reducer/model/runtime.ts +0 -264
  189. package/src/reducer/model/spec.ts +0 -1386
  190. package/src/reducer/model/table.ts +0 -260
  191. package/src/reducer/model.ts +0 -7
  192. package/src/reducer/ops.ts +0 -1034
  193. package/src/reducer/parse-utils.ts +0 -28
  194. package/src/reducer/per-player.ts +0 -422
  195. package/src/reducer/rng.ts +0 -69
  196. package/src/reducer/schema-helpers.ts +0 -185
  197. package/src/reducer/setup-bootstrap-helpers.ts +0 -171
  198. package/src/reducer/setup-bootstrap.ts +0 -481
  199. package/src/reducer/table-ops.ts +0 -2671
  200. package/src/reducer/table-queries.ts +0 -372
  201. package/src/reducer/transaction.ts +0 -120
  202. package/src/reducer.ts +0 -314
  203. package/src/runtime/primitives.ts +0 -1
  204. package/src/runtime/types/runtime-api.ts +0 -1
  205. package/src/runtime/workspace-contract.ts +0 -32
  206. package/src/runtime-internal/components/InteractionForm.tsx +0 -1647
  207. package/src/runtime-internal/components/PluginRuntime.tsx +0 -105
  208. package/src/runtime-internal/components/board/target-layer.ts +0 -72
  209. package/src/runtime-internal/context/ClientParamSchemaContext.tsx +0 -44
  210. package/src/runtime-internal/context/InteractionDraftContext.tsx +0 -279
  211. package/src/runtime-internal/context/PluginSessionContext.tsx +0 -47
  212. package/src/runtime-internal/context/PluginStateContext.tsx +0 -303
  213. package/src/runtime-internal/context/RuntimeContext.tsx +0 -96
  214. package/src/runtime-internal/defaults/components.tsx +0 -409
  215. package/src/runtime-internal/defaults/index.ts +0 -11
  216. package/src/runtime-internal/errors/ValidationError.ts +0 -29
  217. package/src/runtime-internal/hooks/useActivePlayers.ts +0 -33
  218. package/src/runtime-internal/hooks/useBoardInteractions.ts +0 -727
  219. package/src/runtime-internal/hooks/useGameSelector.ts +0 -105
  220. package/src/runtime-internal/hooks/useGameView.ts +0 -9
  221. package/src/runtime-internal/hooks/useInteractionByKey.ts +0 -354
  222. package/src/runtime-internal/hooks/useInteractionHandle.ts +0 -438
  223. package/src/runtime-internal/hooks/useIsMyTurn.ts +0 -20
  224. package/src/runtime-internal/hooks/useLobby.ts +0 -76
  225. package/src/runtime-internal/hooks/useMe.ts +0 -48
  226. package/src/runtime-internal/hooks/usePlayerInfo.ts +0 -28
  227. package/src/runtime-internal/hooks/usePlayerTurnOrder.ts +0 -23
  228. package/src/runtime-internal/hooks/usePluginRuntime.ts +0 -147
  229. package/src/runtime-internal/hooks/useSeatInbox.ts +0 -61
  230. package/src/runtime-internal/hooks/useSimultaneousPhase.ts +0 -10
  231. package/src/runtime-internal/index.ts +0 -42
  232. package/src/runtime-internal/internal.ts +0 -43
  233. package/src/runtime-internal/plugin-styles.css +0 -250
  234. package/src/runtime-internal/primitives/board.tsx +0 -530
  235. package/src/runtime-internal/primitives/dialog-lifecycle.ts +0 -58
  236. package/src/runtime-internal/primitives/dice.tsx +0 -79
  237. package/src/runtime-internal/primitives/game-ui-provider.tsx +0 -35
  238. package/src/runtime-internal/primitives/game.tsx +0 -387
  239. package/src/runtime-internal/primitives/hand-intent-adapter.ts +0 -147
  240. package/src/runtime-internal/primitives/hand-surface.tsx +0 -594
  241. package/src/runtime-internal/primitives/index.ts +0 -196
  242. package/src/runtime-internal/primitives/interaction-form-binding.tsx +0 -56
  243. package/src/runtime-internal/primitives/interaction-submit.ts +0 -90
  244. package/src/runtime-internal/primitives/interaction.tsx +0 -1146
  245. package/src/runtime-internal/primitives/phase.tsx +0 -43
  246. package/src/runtime-internal/primitives/player-roster.tsx +0 -302
  247. package/src/runtime-internal/primitives/primitive-props.tsx +0 -101
  248. package/src/runtime-internal/primitives/prompt.tsx +0 -255
  249. package/src/runtime-internal/primitives/ui.tsx +0 -60
  250. package/src/runtime-internal/primitives/zone.tsx +0 -791
  251. package/src/runtime-internal/reducer.ts +0 -30
  252. package/src/runtime-internal/runtime/createPluginRuntimeAPI.ts +0 -605
  253. package/src/runtime-internal/types/plugin-state.ts +0 -514
  254. package/src/runtime-internal/types/reducer-state.ts +0 -24
  255. package/src/runtime-internal/types/runtime-api.ts +0 -114
  256. package/src/runtime-internal/ui-contract.ts +0 -519
  257. package/src/runtime-internal/utils/browser-interaction-effects.ts +0 -240
  258. package/src/runtime-internal/utils/card-intent-adapter.ts +0 -546
  259. package/src/runtime-internal/utils/interaction-draft-digest.ts +0 -252
  260. package/src/runtime-internal/utils/interaction-inputs.ts +0 -492
  261. package/src/runtime-internal/utils/interaction-labels.ts +0 -23
  262. package/src/runtime-internal/utils/interaction-router.ts +0 -273
  263. package/src/runtime-internal/utils/interaction-status.ts +0 -74
  264. package/src/runtime-internal/utils/semantic-projection-digest.ts +0 -407
  265. package/src/runtime-internal/workspace-contract.ts +0 -1170
  266. package/src/runtime.ts +0 -34
  267. package/src/testing/create-expect-api.ts +0 -352
  268. package/src/testing/create-test-runtime.ts +0 -381
  269. package/src/testing/definitions.ts +0 -127
  270. package/src/testing/index.ts +0 -3
  271. package/src/testing.ts +0 -1
  272. package/src/type-stubs/manifest-contract.d.ts +0 -42
  273. package/src/type-stubs/manifest-contract.js +0 -72
  274. package/src/type-stubs/ui-contract.d.ts +0 -5
  275. package/src/type-stubs/ui-contract.js +0 -1
  276. package/src/types/authoring-card-properties.type-test.ts +0 -266
  277. package/src/types/authoring.ts +0 -1282
  278. package/src/types/cards.ts +0 -19
  279. package/src/types/contracts.ts +0 -1550
  280. package/src/types/generated-helpers.ts +0 -35
  281. package/src/types/index.ts +0 -147
  282. package/src/types/slots.ts +0 -11
  283. package/src/types.ts +0 -1
  284. package/src/ui/components/ActionButton.tsx +0 -97
  285. package/src/ui/components/ActionPanel.tsx +0 -315
  286. package/src/ui/components/Card.tsx +0 -378
  287. package/src/ui/components/CardDragSurface.tsx +0 -1076
  288. package/src/ui/components/ChromeSuppressionContext.tsx +0 -70
  289. package/src/ui/components/CostDisplay.tsx +0 -145
  290. package/src/ui/components/DiceRoller.tsx +0 -581
  291. package/src/ui/components/Drawer.tsx +0 -180
  292. package/src/ui/components/ErrorBoundary.tsx +0 -275
  293. package/src/ui/components/GameEndDisplay.tsx +0 -398
  294. package/src/ui/components/GameSkeleton.tsx +0 -260
  295. package/src/ui/components/Hand.tsx +0 -468
  296. package/src/ui/components/HandDock.tsx +0 -299
  297. package/src/ui/components/HandView.tsx +0 -441
  298. package/src/ui/components/MobileHandTray.tsx +0 -381
  299. package/src/ui/components/MoreActions.tsx +0 -143
  300. package/src/ui/components/PhaseIndicator.tsx +0 -341
  301. package/src/ui/components/PlayArea.tsx +0 -146
  302. package/src/ui/components/PrimaryActionButton.tsx +0 -336
  303. package/src/ui/components/PrimaryButton.tsx +0 -45
  304. package/src/ui/components/ResourceCounter.tsx +0 -270
  305. package/src/ui/components/StagingZone.tsx +0 -134
  306. package/src/ui/components/ThemedButton.tsx +0 -113
  307. package/src/ui/components/Toast.tsx +0 -264
  308. package/src/ui/components/board/HexGrid.tsx +0 -1297
  309. package/src/ui/components/board/NetworkGraph.tsx +0 -476
  310. package/src/ui/components/board/SlotSystem.tsx +0 -388
  311. package/src/ui/components/board/SquareGrid.tsx +0 -1165
  312. package/src/ui/components/board/TrackBoard.tsx +0 -496
  313. package/src/ui/components/board/ZoneMap.tsx +0 -448
  314. package/src/ui/components/board/hex-board-view.ts +0 -123
  315. package/src/ui/components/board/index.ts +0 -142
  316. package/src/ui/components/board/interaction-accessibility.ts +0 -21
  317. package/src/ui/components/board/target-layer.ts +0 -67
  318. package/src/ui/components/card-render-content.type-test.ts +0 -27
  319. package/src/ui/components/hand-layout-math.ts +0 -163
  320. package/src/ui/components/hand-pointer-engine.ts +0 -413
  321. package/src/ui/components/index.ts +0 -245
  322. package/src/ui/components.ts +0 -1
  323. package/src/ui/defaults/components.tsx +0 -106
  324. package/src/ui/defaults/index.ts +0 -8
  325. package/src/ui/defaults.ts +0 -1
  326. package/src/ui/errors/ValidationError.ts +0 -29
  327. package/src/ui/helpers/cards.ts +0 -19
  328. package/src/ui/helpers/track-board.ts +0 -211
  329. package/src/ui/hooks/useBoardTopology.ts +0 -316
  330. package/src/ui/hooks/useCards.ts +0 -10
  331. package/src/ui/hooks/useHandCardPointer.ts +0 -381
  332. package/src/ui/hooks/useHandLayout.ts +0 -378
  333. package/src/ui/hooks/useHandPresentation.ts +0 -121
  334. package/src/ui/hooks/useHexBoard.ts +0 -74
  335. package/src/ui/hooks/useHexGrid.ts +0 -185
  336. package/src/ui/hooks/useIsMobile.ts +0 -35
  337. package/src/ui/hooks/usePanZoom.ts +0 -278
  338. package/src/ui/hooks/useSquareBoard.ts +0 -124
  339. package/src/ui/hooks/useSquareGrid.ts +0 -328
  340. package/src/ui/index.ts +0 -98
  341. package/src/ui/internal/ui/alert.tsx +0 -51
  342. package/src/ui/internal/ui/button.tsx +0 -58
  343. package/src/ui/internal/ui/dialog.tsx +0 -134
  344. package/src/ui/internal/ui/input.tsx +0 -21
  345. package/src/ui/internal/ui/label.tsx +0 -21
  346. package/src/ui/internal/ui/select.tsx +0 -129
  347. package/src/ui/internal/ui/tooltip.tsx +0 -54
  348. package/src/ui/internal/ui/utils.ts +0 -5
  349. package/src/ui/plugin-styles.css +0 -250
  350. package/src/ui/primitives/dialog-lifecycle.ts +0 -58
  351. package/src/ui/primitives/dice.tsx +0 -79
  352. package/src/ui/primitives/primitive-props.tsx +0 -101
  353. package/src/ui/theme/ThemeProvider.tsx +0 -252
  354. package/src/ui/theme/board.ts +0 -61
  355. package/src/ui/theme/css-vars.ts +0 -105
  356. package/src/ui/theme/derive.ts +0 -240
  357. package/src/ui/theme/index.ts +0 -61
  358. package/src/ui/theme/presets/arcade.ts +0 -261
  359. package/src/ui/theme/presets/studio.ts +0 -261
  360. package/src/ui/theme/presets/tabletop.ts +0 -266
  361. package/src/ui/theme/tokens.ts +0 -392
  362. package/src/ui/types/hex-color.ts +0 -20
  363. package/src/ui/types/player-state.ts +0 -463
  364. package/src/ui/types/tiled-board.ts +0 -785
  365. package/src/ui/types/visual-state.ts +0 -137
  366. package/src/ui.ts +0 -1
  367. /package/dist/{chunk-NKCRKGR2.js.map → chunk-3RQEICD3.js.map} +0 -0
  368. /package/dist/{chunk-I46YJSOD.js.map → codegen.js.map} +0 -0
  369. /package/dist/{chunk-T52J5RMF.js.map → reducer-contract.js.map} +0 -0
  370. /package/dist/{generated → runtime}/runtime-api.js.map +0 -0
  371. /package/dist/ui/{types/player-state.js → player-state.js} +0 -0
  372. /package/dist/ui/{types/player-state.js.map → player-state.js.map} +0 -0
@@ -1,15 +1,3 @@
1
- import {
2
- BROWSER_INTERACTION_ATTRIBUTES,
3
- DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,
4
- GAMEPLAY_BROWSER_INTERACTION_SURFACE,
5
- createGameplayActuatorAttributes,
6
- createGameplayInteractionRootAttributes,
7
- gameplayAdjustResourceEffect,
8
- gameplayCommitEffect,
9
- gameplayInvokeEffect,
10
- gameplaySetCandidateEffect,
11
- gameplaySetScalarEffect
12
- } from "./chunk-QLG6VEMW.js";
13
1
  import {
14
2
  CardDragSurface,
15
3
  CardDropTargetView,
@@ -29,9 +17,25 @@ import {
29
17
  useChromeSuppression,
30
18
  useTheme,
31
19
  useThemeCssVars
32
- } from "./chunk-WG4JQL3S.js";
20
+ } from "./chunk-QZ6X4B5P.js";
21
+ import {
22
+ composeEventHandlers,
23
+ renderPrimitive
24
+ } from "./chunk-VDXOF4FW.js";
25
+ import {
26
+ BROWSER_INTERACTION_ATTRIBUTES,
27
+ DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,
28
+ GAMEPLAY_BROWSER_INTERACTION_SURFACE,
29
+ createGameplayActuatorAttributes,
30
+ createGameplayInteractionRootAttributes,
31
+ gameplayAdjustResourceEffect,
32
+ gameplayCommitEffect,
33
+ gameplayInvokeEffect,
34
+ gameplaySetCandidateEffect,
35
+ gameplaySetScalarEffect
36
+ } from "./chunk-QLG6VEMW.js";
33
37
 
34
- // src/runtime-internal/primitives/ui.tsx
38
+ // src/runtime/primitives/ui.tsx
35
39
  import { Fragment, jsx } from "react/jsx-runtime";
36
40
  function UIRoot({
37
41
  theme,
@@ -60,10 +64,10 @@ var UI = {
60
64
  Root: UIRoot
61
65
  };
62
66
 
63
- // src/runtime-internal/primitives/hand-intent-adapter.ts
67
+ // src/runtime/primitives/hand-intent-adapter.ts
64
68
  import { useCallback } from "react";
65
69
 
66
- // src/runtime-internal/context/InteractionDraftContext.tsx
70
+ // src/runtime/context/InteractionDraftContext.tsx
67
71
  import { createContext, useContext, useMemo } from "react";
68
72
  import { useStore } from "zustand";
69
73
  import { createStore } from "zustand/vanilla";
@@ -247,7 +251,7 @@ function useInteractionSubmitting(interactionId) {
247
251
  );
248
252
  }
249
253
 
250
- // src/runtime-internal/context/PluginSessionContext.tsx
254
+ // src/runtime/context/PluginSessionContext.tsx
251
255
  import { createContext as createContext2, useContext as useContext2 } from "react";
252
256
  var PluginSessionContext = createContext2(
253
257
  null
@@ -262,7 +266,7 @@ function usePluginSession() {
262
266
  return context;
263
267
  }
264
268
 
265
- // src/runtime-internal/context/PluginStateContext.tsx
269
+ // src/runtime/context/PluginStateContext.tsx
266
270
  import {
267
271
  createContext as createContext4,
268
272
  useContext as useContext4,
@@ -272,7 +276,7 @@ import {
272
276
  useSyncExternalStore
273
277
  } from "react";
274
278
 
275
- // src/runtime-internal/context/RuntimeContext.tsx
279
+ // src/runtime/context/RuntimeContext.tsx
276
280
  import { createContext as createContext3, useContext as useContext3, useState, useEffect } from "react";
277
281
  import { jsx as jsx3 } from "react/jsx-runtime";
278
282
  var RuntimeContext = createContext3(null);
@@ -305,7 +309,7 @@ function RuntimeProvider({
305
309
  return /* @__PURE__ */ jsx3(RuntimeContext.Provider, { value: runtime, children: /* @__PURE__ */ jsx3(PluginSessionContext.Provider, { value: sessionState, children }) });
306
310
  }
307
311
 
308
- // src/runtime-internal/utils/semantic-projection-digest.ts
312
+ // src/runtime/utils/semantic-projection-digest.ts
309
313
  var AUTHORIZED_SEAT_PROJECTION_DIGEST_VERSION = "authorized-seat-projection@2";
310
314
  function semanticProjectionDigestForState(state) {
311
315
  const actorPlayerId = state.session.controllingPlayerId;
@@ -644,7 +648,7 @@ function utf8Bytes(input) {
644
648
  return Array.from(new TextEncoder().encode(input));
645
649
  }
646
650
 
647
- // src/runtime-internal/context/PluginStateContext.tsx
651
+ // src/runtime/context/PluginStateContext.tsx
648
652
  import { Fragment as Fragment2, jsx as jsx4, jsxs } from "react/jsx-runtime";
649
653
  var PluginStateContext = createContext4(null);
650
654
  var GAMEPLAY_BROWSER_SCOPE_ID = "runtime";
@@ -724,7 +728,7 @@ function usePluginActions() {
724
728
  };
725
729
  }
726
730
 
727
- // src/runtime-internal/utils/interaction-inputs.ts
731
+ // src/runtime/utils/interaction-inputs.ts
728
732
  function interactionInputKeys(descriptor) {
729
733
  return descriptor.inputs.map((input) => input.key);
730
734
  }
@@ -1029,7 +1033,7 @@ function pluralize(word, count) {
1029
1033
  return count === 1 ? word : `${word}s`;
1030
1034
  }
1031
1035
 
1032
- // src/runtime-internal/utils/interaction-router.ts
1036
+ // src/runtime/utils/interaction-router.ts
1033
1037
  function applyInteractionDraftMutation(store, descriptor, mutations) {
1034
1038
  const originalDraft = {
1035
1039
  ...store.getDraft(descriptor.interactionKey)
@@ -1176,7 +1180,7 @@ function claimInteractionSubmit(store, descriptor) {
1176
1180
  return store.claimSubmitting(descriptor.interactionKey);
1177
1181
  }
1178
1182
 
1179
- // src/runtime-internal/utils/interaction-status.ts
1183
+ // src/runtime/utils/interaction-status.ts
1180
1184
  function isInteractionAvailable(descriptor) {
1181
1185
  return descriptor?.availability.status === "available";
1182
1186
  }
@@ -1185,7 +1189,7 @@ function interactionUnavailableReason(descriptor) {
1185
1189
  return availability && availability.status !== "available" ? availability.reason : void 0;
1186
1190
  }
1187
1191
 
1188
- // src/runtime-internal/utils/card-intent-adapter.ts
1192
+ // src/runtime/utils/card-intent-adapter.ts
1189
1193
  var DROP_TARGET_PREFIX = "dreamboard:drop";
1190
1194
  function encodeRuntimeDropTargetKind(kind, value) {
1191
1195
  return `${DROP_TARGET_PREFIX}:kind:${kind}:${value}`;
@@ -1440,7 +1444,7 @@ function selectedCardIdsForZone(store, zone, state) {
1440
1444
  return [...result];
1441
1445
  }
1442
1446
 
1443
- // src/runtime-internal/primitives/hand-intent-adapter.ts
1447
+ // src/runtime/primitives/hand-intent-adapter.ts
1444
1448
  function decodeAuthoredCardIntent(intent) {
1445
1449
  if (intent.type !== "drop") {
1446
1450
  return intent;
@@ -1518,11 +1522,11 @@ function useCardIntentAdapter({
1518
1522
  );
1519
1523
  }
1520
1524
 
1521
- // src/runtime-internal/primitives/game.tsx
1525
+ // src/runtime/primitives/game.tsx
1522
1526
  import { createContext as createContext5, useContext as useContext5, useMemo as useMemo5 } from "react";
1523
1527
  import { useStore as useStore2 } from "zustand";
1524
1528
 
1525
- // src/runtime-internal/hooks/useActivePlayers.ts
1529
+ // src/runtime/hooks/useActivePlayers.ts
1526
1530
  function useActivePlayers() {
1527
1531
  return usePluginState((state) => {
1528
1532
  const simultaneous = state.gameplay.simultaneousPhase;
@@ -1533,7 +1537,7 @@ function useActivePlayers() {
1533
1537
  });
1534
1538
  }
1535
1539
 
1536
- // src/runtime-internal/hooks/useGameSelector.ts
1540
+ // src/runtime/hooks/useGameSelector.ts
1537
1541
  import { useRef, useSyncExternalStore as useSyncExternalStore2 } from "react";
1538
1542
  function defaultEquality(left, right) {
1539
1543
  return Object.is(left, right);
@@ -1597,15 +1601,15 @@ function useGameSelector(selector, equalityFn = defaultEquality) {
1597
1601
  return useSyncExternalStore2(subscribe, getSnapshot, getSnapshot);
1598
1602
  }
1599
1603
 
1600
- // src/runtime-internal/hooks/useGameView.ts
1604
+ // src/runtime/hooks/useGameView.ts
1601
1605
  function useGameView() {
1602
1606
  return useGameSelector((view) => view);
1603
1607
  }
1604
1608
 
1605
- // src/runtime-internal/hooks/usePlayerInfo.ts
1609
+ // src/runtime/hooks/usePlayerInfo.ts
1606
1610
  import { useMemo as useMemo3 } from "react";
1607
1611
 
1608
- // src/runtime-internal/hooks/useLobby.ts
1612
+ // src/runtime/hooks/useLobby.ts
1609
1613
  import { useState as useState3, useEffect as useEffect3 } from "react";
1610
1614
  function useLobbyState() {
1611
1615
  const runtime = useRuntimeContext();
@@ -1644,7 +1648,7 @@ function useLobby() {
1644
1648
  return lobbyState;
1645
1649
  }
1646
1650
 
1647
- // src/runtime-internal/hooks/usePlayerInfo.ts
1651
+ // src/runtime/hooks/usePlayerInfo.ts
1648
1652
  function usePlayerInfo() {
1649
1653
  const lobby = useLobbyState();
1650
1654
  return useMemo3(() => {
@@ -1665,7 +1669,7 @@ function usePlayerInfo() {
1665
1669
  }, [lobby]);
1666
1670
  }
1667
1671
 
1668
- // src/runtime-internal/hooks/usePlayerTurnOrder.ts
1672
+ // src/runtime/hooks/usePlayerTurnOrder.ts
1669
1673
  import { useMemo as useMemo4 } from "react";
1670
1674
  function usePlayerTurnOrder() {
1671
1675
  const lobby = useLobby();
@@ -1675,7 +1679,7 @@ function usePlayerTurnOrder() {
1675
1679
  }, [lobby]);
1676
1680
  }
1677
1681
 
1678
- // src/runtime-internal/utils/interaction-labels.ts
1682
+ // src/runtime/utils/interaction-labels.ts
1679
1683
  function humanizeInteractionId(id) {
1680
1684
  if (!id) return id;
1681
1685
  const withSpaces = id.replace(/[-_]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").trim();
@@ -1688,7 +1692,7 @@ function interactionLabel(descriptor) {
1688
1692
  );
1689
1693
  }
1690
1694
 
1691
- // src/runtime-internal/primitives/game.tsx
1695
+ // src/runtime/primitives/game.tsx
1692
1696
  import { Fragment as Fragment3, jsx as jsx5 } from "react/jsx-runtime";
1693
1697
  var GameActionErrorContext = createContext5(
1694
1698
  null
@@ -1866,78 +1870,14 @@ var Game = {
1866
1870
  Chrome: GameChrome
1867
1871
  };
1868
1872
 
1869
- // src/runtime-internal/primitives/primitive-props.tsx
1870
- import {
1871
- cloneElement,
1872
- isValidElement
1873
- } from "react";
1874
- import { jsx as jsx6 } from "react/jsx-runtime";
1875
- function composeEventHandlers(authorHandler, primitiveHandler) {
1876
- if (!authorHandler) return primitiveHandler;
1877
- if (!primitiveHandler) return authorHandler;
1878
- return (event) => {
1879
- authorHandler(event);
1880
- if (!event.defaultPrevented) {
1881
- primitiveHandler(event);
1882
- }
1883
- };
1884
- }
1885
- function renderPrimitive(tagName, props) {
1886
- const { asChild, children, ...primitiveProps } = props;
1887
- if (asChild) {
1888
- if (!isValidElement(children)) {
1889
- throw new Error(
1890
- "asChild requires exactly one valid React element child."
1891
- );
1892
- }
1893
- const element = children;
1894
- const childProps = element.props;
1895
- return cloneElement(element, {
1896
- ...primitiveProps,
1897
- ...childProps,
1898
- className: [primitiveProps.className, childProps.className].filter(Boolean).join(" "),
1899
- style: {
1900
- ...primitiveProps.style ?? {},
1901
- ...childProps.style ?? {}
1902
- },
1903
- onClick: composeEventHandlers(
1904
- childProps.onClick,
1905
- primitiveProps.onClick
1906
- ),
1907
- onPointerDown: composeEventHandlers(
1908
- childProps.onPointerDown,
1909
- primitiveProps.onPointerDown
1910
- ),
1911
- onPointerMove: composeEventHandlers(
1912
- childProps.onPointerMove,
1913
- primitiveProps.onPointerMove
1914
- ),
1915
- onPointerUp: composeEventHandlers(
1916
- childProps.onPointerUp,
1917
- primitiveProps.onPointerUp
1918
- ),
1919
- onPointerCancel: composeEventHandlers(
1920
- childProps.onPointerCancel,
1921
- primitiveProps.onPointerCancel
1922
- ),
1923
- onChange: composeEventHandlers(
1924
- childProps.onChange,
1925
- primitiveProps.onChange
1926
- )
1927
- });
1928
- }
1929
- const Tag = tagName;
1930
- return /* @__PURE__ */ jsx6(Tag, { ...primitiveProps, children });
1931
- }
1932
-
1933
- // src/runtime-internal/primitives/zone.tsx
1873
+ // src/runtime/primitives/zone.tsx
1934
1874
  import {
1935
1875
  createContext as createContext6,
1936
1876
  useContext as useContext6,
1937
1877
  useMemo as useMemo6
1938
1878
  } from "react";
1939
1879
 
1940
- // src/runtime-internal/primitives/interaction-submit.ts
1880
+ // src/runtime/primitives/interaction-submit.ts
1941
1881
  async function runInteractionAction(action, {
1942
1882
  onSuccess,
1943
1883
  onError,
@@ -1976,8 +1916,8 @@ function submitInteractionParams(handle, params, callbacks = {}, options = {}) {
1976
1916
  });
1977
1917
  }
1978
1918
 
1979
- // src/runtime-internal/primitives/zone.tsx
1980
- import { Fragment as Fragment4, jsx as jsx7 } from "react/jsx-runtime";
1919
+ // src/runtime/primitives/zone.tsx
1920
+ import { Fragment as Fragment4, jsx as jsx6 } from "react/jsx-runtime";
1981
1921
  var ZoneContext = createContext6(null);
1982
1922
  var ZoneCardContext = createContext6(null);
1983
1923
  var ZonePileContext = createContext6(null);
@@ -2013,7 +1953,7 @@ function ZoneRoot({
2013
1953
  () => ({ zone, snapshot }),
2014
1954
  [snapshot, zone]
2015
1955
  );
2016
- return /* @__PURE__ */ jsx7(ZoneContext.Provider, { value, children: renderPrimitive("div", {
1956
+ return /* @__PURE__ */ jsx6(ZoneContext.Provider, { value, children: renderPrimitive("div", {
2017
1957
  ...props,
2018
1958
  "data-dreamboard-zone-root": "",
2019
1959
  "data-zone": zone,
@@ -2023,7 +1963,7 @@ function ZoneRoot({
2023
1963
  }
2024
1964
  function ZoneList({ children, empty, sort, ...props }) {
2025
1965
  const { zone, items, isEmpty } = useZoneCards({ sort });
2026
- const renderedChildren = typeof children === "function" ? isEmpty ? empty : items.map((item) => /* @__PURE__ */ jsx7(ZoneItem, { card: item, children: children(item) }, item.id)) : isEmpty && empty !== void 0 ? empty : children;
1966
+ const renderedChildren = typeof children === "function" ? isEmpty ? empty : items.map((item) => /* @__PURE__ */ jsx6(ZoneItem, { card: item, children: children(item) }, item.id)) : isEmpty && empty !== void 0 ? empty : children;
2027
1967
  return renderPrimitive("div", {
2028
1968
  ...props,
2029
1969
  role: props.role ?? "list",
@@ -2063,7 +2003,7 @@ function ZoneItem({ card, children, ...props }) {
2063
2003
  () => ({ zone, cardId: item.id }),
2064
2004
  [item.id, zone]
2065
2005
  );
2066
- return /* @__PURE__ */ jsx7(ZoneCardContext.Provider, { value: cardContext, children: renderPrimitive("div", {
2006
+ return /* @__PURE__ */ jsx6(ZoneCardContext.Provider, { value: cardContext, children: renderPrimitive("div", {
2067
2007
  ...props,
2068
2008
  role: props.role ?? "listitem",
2069
2009
  "data-dreamboard-zone-item": "",
@@ -2084,23 +2024,23 @@ function ZoneCardAtContent({
2084
2024
  }) {
2085
2025
  const { zone, snapshot } = useZonePrimitiveContext();
2086
2026
  const cardIndex = resolveZoneCardIndex(snapshot, index);
2087
- if (cardIndex === null) return /* @__PURE__ */ jsx7(Fragment4, { children: empty });
2027
+ if (cardIndex === null) return /* @__PURE__ */ jsx6(Fragment4, { children: empty });
2088
2028
  const cardId = snapshot?.cardIds[cardIndex];
2089
- if (!cardId) return /* @__PURE__ */ jsx7(Fragment4, { children: empty });
2029
+ if (!cardId) return /* @__PURE__ */ jsx6(Fragment4, { children: empty });
2090
2030
  const card = createZoneCardRenderItem(zone, snapshot, cardId, cardIndex);
2091
- return /* @__PURE__ */ jsx7(ZoneItem, { card, ...props, children: typeof children === "function" ? children(card) : children });
2031
+ return /* @__PURE__ */ jsx6(ZoneItem, { card, ...props, children: typeof children === "function" ? children(card) : children });
2092
2032
  }
2093
2033
  function ZoneCardAt({
2094
2034
  zone,
2095
2035
  ...props
2096
2036
  }) {
2097
2037
  if (zone) {
2098
- return /* @__PURE__ */ jsx7(ZoneRoot, { zone, children: /* @__PURE__ */ jsx7(ZoneCardAtContent, { ...props }) });
2038
+ return /* @__PURE__ */ jsx6(ZoneRoot, { zone, children: /* @__PURE__ */ jsx6(ZoneCardAtContent, { ...props }) });
2099
2039
  }
2100
- return /* @__PURE__ */ jsx7(ZoneCardAtContent, { ...props });
2040
+ return /* @__PURE__ */ jsx6(ZoneCardAtContent, { ...props });
2101
2041
  }
2102
2042
  function ZoneTopCard(props) {
2103
- return /* @__PURE__ */ jsx7(ZoneCardAt, { ...props, index: 0 });
2043
+ return /* @__PURE__ */ jsx6(ZoneCardAt, { ...props, index: 0 });
2104
2044
  }
2105
2045
  function ZoneCardAction({
2106
2046
  card,
@@ -2203,7 +2143,7 @@ function ZonePileRoot({
2203
2143
  children,
2204
2144
  ...props
2205
2145
  }) {
2206
- return /* @__PURE__ */ jsx7(ZoneRoot, { zone, ...props, children: /* @__PURE__ */ jsx7(
2146
+ return /* @__PURE__ */ jsx6(ZoneRoot, { zone, ...props, children: /* @__PURE__ */ jsx6(
2207
2147
  ZonePileProvider,
2208
2148
  {
2209
2149
  emptyDescription,
@@ -2243,7 +2183,7 @@ function ZonePileProvider({
2243
2183
  }),
2244
2184
  [cards, count, description, hasVisibleCards, isHidden, items, label, zone]
2245
2185
  );
2246
- return /* @__PURE__ */ jsx7(ZonePileContext.Provider, { value, children });
2186
+ return /* @__PURE__ */ jsx6(ZonePileContext.Provider, { value, children });
2247
2187
  }
2248
2188
  function ZonePileTrigger({ children, ...props }) {
2249
2189
  const pile = useZonePileContext();
@@ -2294,7 +2234,7 @@ function ZonePileDescription({
2294
2234
  function ZonePileCards({ renderCard, ...props }) {
2295
2235
  const pile = useZonePileContext();
2296
2236
  if (!pile.hasVisibleCards) return null;
2297
- return /* @__PURE__ */ jsx7(ZoneList, { ...props, children: pile.items.map((card) => /* @__PURE__ */ jsx7(ZoneItem, { card, children: renderCard(card) }, card.id)) });
2237
+ return /* @__PURE__ */ jsx6(ZoneList, { ...props, children: pile.items.map((card) => /* @__PURE__ */ jsx6(ZoneItem, { card, children: renderCard(card) }, card.id)) });
2298
2238
  }
2299
2239
  function indexOfCard(snapshot, cardId) {
2300
2240
  return snapshot?.cardIds.indexOf(cardId) ?? -1;
@@ -2409,7 +2349,7 @@ var Zone = {
2409
2349
  useZoneCards
2410
2350
  };
2411
2351
 
2412
- // src/runtime-internal/primitives/hand-surface.tsx
2352
+ // src/runtime/primitives/hand-surface.tsx
2413
2353
  import {
2414
2354
  Fragment as Fragment5,
2415
2355
  useCallback as useCallback2,
@@ -2419,7 +2359,7 @@ import {
2419
2359
  } from "react";
2420
2360
  import { useStore as useStore3 } from "zustand";
2421
2361
  import { useShallow as useShallow2 } from "zustand/shallow";
2422
- import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
2362
+ import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
2423
2363
  function HandSurfaceView({
2424
2364
  zone,
2425
2365
  cards,
@@ -2546,7 +2486,7 @@ function HandSurfaceView({
2546
2486
  }, [selectionSummary]);
2547
2487
  const summaryContent = renderSummary ? renderSummary(selectionSummary) : null;
2548
2488
  const actionsNode = renderActions ? renderActions(selectionSummary) : null;
2549
- const actionsContent = actionsNode !== null && actionsNode !== void 0 ? /* @__PURE__ */ jsx8(
2489
+ const actionsContent = actionsNode !== null && actionsNode !== void 0 ? /* @__PURE__ */ jsx7(
2550
2490
  "div",
2551
2491
  {
2552
2492
  "data-dreamboard-hand-actions": "",
@@ -2565,7 +2505,7 @@ function HandSurfaceView({
2565
2505
  },
2566
2506
  [route]
2567
2507
  );
2568
- const handView = /* @__PURE__ */ jsx8(
2508
+ const handView = /* @__PURE__ */ jsx7(
2569
2509
  HandView,
2570
2510
  {
2571
2511
  cards: viewCards,
@@ -2589,7 +2529,7 @@ function HandSurfaceView({
2589
2529
  return handView;
2590
2530
  }
2591
2531
  return /* @__PURE__ */ jsxs2(Fragment5, { children: [
2592
- summaryContent !== null ? /* @__PURE__ */ jsx8(
2532
+ summaryContent !== null ? /* @__PURE__ */ jsx7(
2593
2533
  "div",
2594
2534
  {
2595
2535
  "data-dreamboard-runtime-hand-summary": "",
@@ -2603,7 +2543,7 @@ function HandSurfaceView({
2603
2543
  actionsContent
2604
2544
  ] });
2605
2545
  }
2606
- const targets = dropTargets.map((target) => /* @__PURE__ */ jsx8(
2546
+ const targets = dropTargets.map((target) => /* @__PURE__ */ jsx7(
2607
2547
  CardDropTargetView,
2608
2548
  {
2609
2549
  targetId: target.targetId,
@@ -2617,7 +2557,7 @@ function HandSurfaceView({
2617
2557
  target.targetId
2618
2558
  ));
2619
2559
  return /* @__PURE__ */ jsxs2(CardDragSurface, { onCardIntent: handleIntent, children: [
2620
- summaryContent !== null ? /* @__PURE__ */ jsx8(
2560
+ summaryContent !== null ? /* @__PURE__ */ jsx7(
2621
2561
  "div",
2622
2562
  {
2623
2563
  "data-dreamboard-runtime-hand-summary": "",
@@ -2627,7 +2567,7 @@ function HandSurfaceView({
2627
2567
  children: summaryContent
2628
2568
  }
2629
2569
  ) : null,
2630
- renderDropTargets ? renderDropTargets(/* @__PURE__ */ jsx8(Fragment5, { children: targets })) : /* @__PURE__ */ jsx8("div", { "data-dreamboard-runtime-drop-row": "", className: "flex gap-2 mb-2", children: targets }),
2570
+ renderDropTargets ? renderDropTargets(/* @__PURE__ */ jsx7(Fragment5, { children: targets })) : /* @__PURE__ */ jsx7("div", { "data-dreamboard-runtime-drop-row": "", className: "flex gap-2 mb-2", children: targets }),
2631
2571
  handView,
2632
2572
  actionsContent
2633
2573
  ] });
@@ -2693,7 +2633,7 @@ function HandStagingView({
2693
2633
  [route]
2694
2634
  );
2695
2635
  if (slotCount <= 0 && cards.length === 0) return null;
2696
- return /* @__PURE__ */ jsx8(
2636
+ return /* @__PURE__ */ jsx7(
2697
2637
  StagingZone,
2698
2638
  {
2699
2639
  cards,
@@ -2724,7 +2664,7 @@ function descriptorsHaveDestinationInput(state) {
2724
2664
  return false;
2725
2665
  }
2726
2666
 
2727
- // src/runtime-internal/primitives/board.tsx
2667
+ // src/runtime/primitives/board.tsx
2728
2668
  import {
2729
2669
  createContext as createContext7,
2730
2670
  useContext as useContext7,
@@ -2732,11 +2672,11 @@ import {
2732
2672
  } from "react";
2733
2673
  import { useStore as useStore5 } from "zustand";
2734
2674
 
2735
- // src/runtime-internal/hooks/useBoardInteractions.ts
2675
+ // src/runtime/hooks/useBoardInteractions.ts
2736
2676
  import { useCallback as useCallback3, useMemo as useMemo8 } from "react";
2737
2677
  import { useStore as useStore4 } from "zustand";
2738
2678
 
2739
- // src/runtime-internal/errors/ValidationError.ts
2679
+ // src/ui/errors/ValidationError.ts
2740
2680
  var ValidationError = class extends Error {
2741
2681
  constructor(errorCode, message) {
2742
2682
  super(message || errorCode || "Validation failed");
@@ -2752,7 +2692,7 @@ function validationErrorFromUnknown(error, fallbackMessage = "Interaction submis
2752
2692
  return new ValidationError(errorCode, message);
2753
2693
  }
2754
2694
 
2755
- // src/runtime-internal/utils/interaction-draft-digest.ts
2695
+ // src/runtime/utils/interaction-draft-digest.ts
2756
2696
  function interactionDraftDigestForValues(descriptor, values) {
2757
2697
  if (descriptor.descriptorDigest === void 0 || descriptor.actorSeat === void 0 || descriptor.draftDigest === void 0) {
2758
2698
  return void 0;
@@ -2981,7 +2921,7 @@ var K = [
2981
2921
  3329325298
2982
2922
  ];
2983
2923
 
2984
- // src/runtime-internal/utils/browser-interaction-effects.ts
2924
+ // src/runtime/utils/browser-interaction-effects.ts
2985
2925
  function gameplayCandidateMetadata(input) {
2986
2926
  const inputDescriptor = resolvedInputByKey(
2987
2927
  input.descriptor,
@@ -3119,7 +3059,7 @@ function dedupePatterns(patterns) {
3119
3059
  return result;
3120
3060
  }
3121
3061
 
3122
- // src/runtime-internal/hooks/useBoardInteractions.ts
3062
+ // src/runtime/hooks/useBoardInteractions.ts
3123
3063
  var BoardInteractionConflictError = class extends Error {
3124
3064
  name = "BoardInteractionConflictError";
3125
3065
  targetKind;
@@ -3530,8 +3470,8 @@ function candidateUnavailableReason(match, conflict) {
3530
3470
  return void 0;
3531
3471
  }
3532
3472
 
3533
- // src/runtime-internal/primitives/board.tsx
3534
- import { Fragment as Fragment6, jsx as jsx9 } from "react/jsx-runtime";
3473
+ // src/runtime/primitives/board.tsx
3474
+ import { Fragment as Fragment6, jsx as jsx8 } from "react/jsx-runtime";
3535
3475
  var BoardContext = createContext7(null);
3536
3476
  var warnedAmbiguousBoardTargets = /* @__PURE__ */ new Set();
3537
3477
  function warnAmbiguousBoardTarget({
@@ -3557,21 +3497,21 @@ function useBoardPrimitiveContext() {
3557
3497
  }
3558
3498
  function BoardRoot({ children, targetKinds, ...props }) {
3559
3499
  const board = useBoardInteractions({ targetKinds });
3560
- return /* @__PURE__ */ jsx9(BoardContext.Provider, { value: board, children: renderPrimitive("div", {
3500
+ return /* @__PURE__ */ jsx8(BoardContext.Provider, { value: board, children: renderPrimitive("div", {
3561
3501
  ...props,
3562
3502
  "data-dreamboard-board-root": "",
3563
3503
  children
3564
3504
  }) });
3565
3505
  }
3566
3506
  function BoardState({ children }) {
3567
- return /* @__PURE__ */ jsx9(Fragment6, { children: children(useBoardPrimitiveContext()) });
3507
+ return /* @__PURE__ */ jsx8(Fragment6, { children: children(useBoardPrimitiveContext()) });
3568
3508
  }
3569
3509
  function BoardHexView({ board, spaces, children }) {
3570
3510
  const view = useMemo9(
3571
3511
  () => createHexBoardView(board, { spaces }),
3572
3512
  [board, spaces]
3573
3513
  );
3574
- return /* @__PURE__ */ jsx9(Fragment6, { children: children(view) });
3514
+ return /* @__PURE__ */ jsx8(Fragment6, { children: children(view) });
3575
3515
  }
3576
3516
  function BoardHexGrid({
3577
3517
  board,
@@ -3596,7 +3536,7 @@ function BoardHexGrid({
3596
3536
  interactionKeys: interactions === "auto" ? void 0 : interactions.space,
3597
3537
  onError: gameActionError ?? void 0
3598
3538
  });
3599
- return /* @__PURE__ */ jsx9(BoardHexView, { board, spaces, children: (view) => /* @__PURE__ */ jsx9(
3539
+ return /* @__PURE__ */ jsx8(BoardHexView, { board, spaces, children: (view) => /* @__PURE__ */ jsx8(
3600
3540
  HexGrid,
3601
3541
  {
3602
3542
  ...props,
@@ -3618,7 +3558,7 @@ function BoardTarget({
3618
3558
  ) : void 0
3619
3559
  );
3620
3560
  if (interaction) {
3621
- return descriptor ? /* @__PURE__ */ jsx9(ExplicitBoardTarget, { descriptor, input, ...props }) : /* @__PURE__ */ jsx9(
3561
+ return descriptor ? /* @__PURE__ */ jsx8(ExplicitBoardTarget, { descriptor, input, ...props }) : /* @__PURE__ */ jsx8(
3622
3562
  UnavailableBoardTarget,
3623
3563
  {
3624
3564
  interaction,
@@ -3627,16 +3567,16 @@ function BoardTarget({
3627
3567
  }
3628
3568
  );
3629
3569
  }
3630
- return /* @__PURE__ */ jsx9(UnambiguousBoardTarget, { input, ...props });
3570
+ return /* @__PURE__ */ jsx8(UnambiguousBoardTarget, { input, ...props });
3631
3571
  }
3632
3572
  function BoardSpaceTarget(props) {
3633
- return /* @__PURE__ */ jsx9(BoardTarget, { kind: "space", ...props });
3573
+ return /* @__PURE__ */ jsx8(BoardTarget, { kind: "space", ...props });
3634
3574
  }
3635
3575
  function BoardEdgeTarget(props) {
3636
- return /* @__PURE__ */ jsx9(BoardTarget, { kind: "edge", ...props });
3576
+ return /* @__PURE__ */ jsx8(BoardTarget, { kind: "edge", ...props });
3637
3577
  }
3638
3578
  function BoardVertexTarget(props) {
3639
- return /* @__PURE__ */ jsx9(BoardTarget, { kind: "vertex", ...props });
3579
+ return /* @__PURE__ */ jsx8(BoardTarget, { kind: "vertex", ...props });
3640
3580
  }
3641
3581
  function UnambiguousBoardTarget({
3642
3582
  kind,
@@ -3835,28 +3775,25 @@ var Board = {
3835
3775
  VertexTarget: BoardVertexTarget
3836
3776
  };
3837
3777
 
3838
- // src/runtime-internal/primitives/interaction.tsx
3778
+ // src/runtime/primitives/interaction/context.tsx
3839
3779
  import {
3840
3780
  createContext as createContext9,
3841
- useCallback as useCallback6,
3842
3781
  useContext as useContext9,
3843
- useEffect as useEffect7,
3844
- useMemo as useMemo13,
3845
- useRef as useRef4
3782
+ useMemo as useMemo11
3846
3783
  } from "react";
3847
3784
 
3848
- // src/runtime-internal/hooks/useInteractionHandle.ts
3785
+ // src/runtime/hooks/useInteractionHandle.ts
3849
3786
  import { useCallback as useCallback4, useEffect as useEffect5, useMemo as useMemo10, useRef as useRef3 } from "react";
3850
3787
 
3851
- // src/runtime-internal/context/ClientParamSchemaContext.tsx
3788
+ // src/runtime/context/ClientParamSchemaContext.tsx
3852
3789
  import { createContext as createContext8, useContext as useContext8 } from "react";
3853
- import { jsx as jsx10 } from "react/jsx-runtime";
3790
+ import { jsx as jsx9 } from "react/jsx-runtime";
3854
3791
  var ClientParamSchemaContext = createContext8({});
3855
3792
  function ClientParamSchemaProvider({
3856
3793
  schemas,
3857
3794
  children
3858
3795
  }) {
3859
- return /* @__PURE__ */ jsx10(ClientParamSchemaContext.Provider, { value: schemas ?? {}, children });
3796
+ return /* @__PURE__ */ jsx9(ClientParamSchemaContext.Provider, { value: schemas ?? {}, children });
3860
3797
  }
3861
3798
  function useClientParamSchema(phaseName, interactionId) {
3862
3799
  const schemas = useContext8(ClientParamSchemaContext);
@@ -3864,7 +3801,7 @@ function useClientParamSchema(phaseName, interactionId) {
3864
3801
  return schemas[phaseName]?.[interactionId];
3865
3802
  }
3866
3803
 
3867
- // src/runtime-internal/hooks/useInteractionHandle.ts
3804
+ // src/runtime/hooks/useInteractionHandle.ts
3868
3805
  function useInteractionHandle(descriptor) {
3869
3806
  const runtime = useRuntimeContext();
3870
3807
  const { controllingPlayerId } = usePluginSession();
@@ -4109,20 +4046,11 @@ function useInteractionHandle(descriptor) {
4109
4046
  };
4110
4047
  }
4111
4048
 
4112
- // src/runtime-internal/components/InteractionForm.tsx
4113
- import {
4114
- useEffect as useEffect6,
4115
- useId,
4116
- useMemo as useMemo11,
4117
- useState as useState4
4118
- } from "react";
4119
- import * as AccordionPrimitive from "@radix-ui/react-accordion";
4120
- import { Fragment as Fragment7, jsx as jsx11, jsxs as jsxs3 } from "react/jsx-runtime";
4121
- var EMPTY_FIELD_ERRORS = [];
4049
+ // src/runtime/interactions/gameplay-attributes.ts
4122
4050
  var GAMEPLAY_BROWSER_SCOPE_ID4 = "runtime";
4123
4051
  function gameplayInteractionRootAttributes({
4124
4052
  descriptor,
4125
- draftValues,
4053
+ draftDigest: draftDigest2,
4126
4054
  ready,
4127
4055
  available
4128
4056
  }) {
@@ -4131,17 +4059,13 @@ function gameplayInteractionRootAttributes({
4131
4059
  interactionKey: descriptor.interactionKey,
4132
4060
  interactionId: descriptor.interactionId,
4133
4061
  ...descriptor.descriptorDigest !== void 0 ? { descriptorDigest: descriptor.descriptorDigest } : {},
4134
- ...descriptor.draftDigest !== void 0 ? {
4135
- draftDigest: interactionDraftDigestForValues(
4136
- descriptor,
4137
- draftValues ?? {}
4138
- )
4139
- } : {},
4062
+ ...draftDigest2 !== void 0 ? { draftDigest: draftDigest2 } : {},
4140
4063
  readiness: available ? ready ? "ready" : "blocked" : "unavailable"
4141
4064
  });
4142
4065
  }
4143
4066
  function gameplayActuatorAttributes({
4144
4067
  descriptor,
4068
+ draftDigest: draftDigest2,
4145
4069
  inputKey,
4146
4070
  intent,
4147
4071
  candidateValue,
@@ -4149,7 +4073,6 @@ function gameplayActuatorAttributes({
4149
4073
  semanticEffects,
4150
4074
  acceptedEffectPatterns,
4151
4075
  preparationPatterns,
4152
- draftValues,
4153
4076
  enabled,
4154
4077
  actuatorKind,
4155
4078
  actuatorId
@@ -4163,12 +4086,7 @@ function gameplayActuatorAttributes({
4163
4086
  actuatorKind,
4164
4087
  actuatorId,
4165
4088
  ...descriptor.descriptorDigest !== void 0 ? { descriptorDigest: descriptor.descriptorDigest } : {},
4166
- ...descriptor.draftDigest !== void 0 ? {
4167
- draftDigest: interactionDraftDigestForValues(
4168
- descriptor,
4169
- draftValues ?? {}
4170
- )
4171
- } : {},
4089
+ ...draftDigest2 !== void 0 ? { draftDigest: draftDigest2 } : {},
4172
4090
  ...inputKey !== void 0 ? { inputKey } : {},
4173
4091
  ...candidateValue !== void 0 ? { candidateValue } : {},
4174
4092
  ...candidateState !== void 0 ? { candidateState } : {},
@@ -4177,849 +4095,472 @@ function gameplayActuatorAttributes({
4177
4095
  ...preparationPatterns !== void 0 ? { preparationPatterns } : {}
4178
4096
  });
4179
4097
  }
4180
- function InteractionForm({
4098
+
4099
+ // src/runtime/primitives/interaction/context.tsx
4100
+ import { jsx as jsx10 } from "react/jsx-runtime";
4101
+ var InteractionContext = createContext9(null);
4102
+ function humanizeInteraction(value) {
4103
+ const parts = value.split(".");
4104
+ const leaf = parts[parts.length - 1] ?? value;
4105
+ return leaf.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[-_]+/g, " ").replace(/\s+/g, " ").trim().replace(/^./, (first) => first.toUpperCase());
4106
+ }
4107
+ function useInteractionPrimitiveContext() {
4108
+ const value = useContext9(InteractionContext);
4109
+ if (!value) {
4110
+ throw new Error(
4111
+ "Interaction primitives must be rendered inside <Interaction.Root>."
4112
+ );
4113
+ }
4114
+ return value;
4115
+ }
4116
+ function useResolvedCardTargetValue() {
4117
+ const context = useContext9(InteractionContext);
4118
+ const descriptor = context?.descriptor;
4119
+ const handle = context?.handle;
4120
+ if (!descriptor || !handle) return void 0;
4121
+ const cardInput = descriptor.inputs.find(
4122
+ (input) => isTargetDomain(input.domain) && input.domain.type === "cardTarget"
4123
+ );
4124
+ if (!cardInput) return void 0;
4125
+ return handle.values[cardInput.key];
4126
+ }
4127
+ function useInteractionDescriptor(interaction) {
4128
+ return usePluginState(
4129
+ (state) => state.gameplay.availableInteractions.find(
4130
+ (descriptor) => descriptor.interactionKey === interaction || descriptor.interactionId === interaction
4131
+ )
4132
+ );
4133
+ }
4134
+ function ResolvedInteractionRoot({
4135
+ interaction,
4181
4136
  descriptor,
4182
- handle,
4183
- fields,
4184
- hiddenFields,
4185
- renderFields,
4186
- inputs,
4187
- submit: renderSubmit,
4188
- title,
4189
- description,
4190
- submitLabel,
4191
- cancelLabel = "Cancel",
4192
- onCancel,
4193
- onSubmitSuccess,
4194
- disabled = false,
4195
- accordion = true,
4196
- defaultOpen = false,
4197
- style
4137
+ children
4198
4138
  }) {
4199
- const theme = useTheme();
4200
- const fallbackLabel = interactionLabel(descriptor);
4201
- const formId = useId();
4202
- useChromeSuppression(formId, true);
4203
- const [pending, setPending] = useState4(false);
4204
- const [validation, setValidation] = useState4(
4205
- null
4139
+ const handle = useInteractionHandle(descriptor);
4140
+ const value = useMemo11(
4141
+ () => ({ interaction, descriptor, handle }),
4142
+ [descriptor, handle, interaction]
4206
4143
  );
4207
- const [formError, setFormError] = useState4(null);
4208
- const [accordionOpen, setAccordionOpen] = useState4(defaultOpen);
4209
- const hidden = useMemo11(() => new Set(hiddenFields ?? []), [hiddenFields]);
4210
- const visibleInputs = useMemo11(() => {
4211
- if (inputs) {
4212
- const rendered = new Set(Object.keys(inputs));
4213
- return resolveInteractionInputs(
4214
- descriptor,
4215
- handle.values
4216
- ).filter((input) => rendered.has(input.key));
4217
- }
4218
- const allowed = fields ? new Set(fields) : null;
4219
- return defaultFormInputs(
4220
- descriptor,
4221
- handle.values
4222
- ).filter((input) => {
4223
- const key = input.key;
4224
- if (allowed && !allowed.has(key)) return false;
4225
- return !hidden.has(key);
4226
- });
4227
- }, [descriptor, fields, hidden, handle.values, inputs]);
4228
- const currentValidation = validation;
4229
- const fieldErrors = currentValidation?.fieldErrors ?? {};
4230
- const missing = new Set(currentValidation?.missing ?? []);
4231
- const formErrors = [
4232
- ...currentValidation?.formErrors ?? [],
4233
- ...formError ? [formError] : []
4234
- ];
4235
- const isDisabled = disabled || pending || !isInteractionAvailable(descriptor);
4236
- const useAccordion = accordion && visibleInputs.length > 0;
4237
- const rootBrowserAttributes = gameplayInteractionRootAttributes({
4238
- descriptor,
4239
- draftValues: handle.values,
4240
- ready: handle.isReady,
4241
- available: !isDisabled
4242
- });
4243
- const armBrowserAttributes = gameplayActuatorAttributes({
4244
- descriptor,
4245
- draftValues: handle.values,
4246
- intent: "arm",
4247
- enabled: !isDisabled,
4248
- actuatorKind: "click",
4249
- actuatorId: "arm",
4250
- preparationPatterns: gameplayPreparationPatternsForDescriptor(
4251
- descriptor,
4252
- handle.values
4253
- )
4254
- });
4255
- const submitMetadata = gameplaySubmitMetadata({ descriptor });
4256
- const submitBrowserAttributes = gameplayActuatorAttributes({
4257
- descriptor,
4258
- draftValues: handle.values,
4259
- intent: submitMetadata.intent,
4260
- enabled: !isDisabled && handle.isReady,
4261
- actuatorKind: "click",
4262
- actuatorId: "submit",
4263
- semanticEffects: submitMetadata.semanticEffects
4144
+ const available = isInteractionAvailable(descriptor);
4145
+ const rootAttributes = createGameplayInteractionRootAttributes({
4146
+ scopeId: GAMEPLAY_BROWSER_SCOPE_ID4,
4147
+ interactionKey: descriptor.interactionKey,
4148
+ interactionId: descriptor.interactionId,
4149
+ ...descriptor.descriptorDigest !== void 0 ? { descriptorDigest: descriptor.descriptorDigest } : {},
4150
+ ...descriptor.draftDigest !== void 0 ? { draftDigest: descriptor.draftDigest } : {},
4151
+ readiness: available ? handle.isReady ? "ready" : "blocked" : "unavailable"
4264
4152
  });
4265
- useEffect6(() => {
4266
- setAccordionOpen(defaultOpen);
4267
- }, [defaultOpen, descriptor.interactionId]);
4268
- const containerStyle = {
4269
- ...surfaceStyle(theme, { tone: "card" }),
4270
- display: "flex",
4271
- flexDirection: "column",
4272
- gap: theme.space[2],
4273
- padding: theme.space[3],
4274
- minWidth: "min(100%, 280px)",
4275
- boxSizing: "border-box",
4276
- fontFamily: theme.typography.fontFamily.body,
4277
- ...style
4278
- };
4279
- const submit = async (event) => {
4280
- event.preventDefault();
4281
- if (isDisabled) return;
4282
- const nextValidation = handle.validateDraft();
4283
- setValidation(nextValidation);
4284
- setFormError(null);
4285
- if (!nextValidation.ok) {
4286
- setAccordionOpen(true);
4287
- return;
4288
- }
4289
- setPending(true);
4290
- try {
4291
- await handle.submitDraft();
4292
- onSubmitSuccess?.();
4293
- setAccordionOpen(defaultOpen);
4294
- } catch (error) {
4295
- setAccordionOpen(true);
4296
- setFormError(
4297
- error instanceof Error ? error.message : "Interaction submission failed"
4298
- );
4299
- } finally {
4300
- setPending(false);
4301
- }
4302
- };
4303
- const header = /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: 2 }, children: [
4304
- /* @__PURE__ */ jsx11(
4305
- "strong",
4306
- {
4307
- style: {
4308
- fontFamily: theme.typography.fontFamily.display,
4309
- fontSize: theme.typography.fontSize.md,
4310
- color: theme.semantic.text.primary
4311
- },
4312
- children: title ?? fallbackLabel
4313
- }
4314
- ),
4315
- description ? /* @__PURE__ */ jsx11(
4316
- "span",
4153
+ return /* @__PURE__ */ jsx10(InteractionContext.Provider, { value, children: renderPrimitive("span", {
4154
+ ...rootAttributes,
4155
+ style: { display: "contents" },
4156
+ children
4157
+ }) });
4158
+ }
4159
+ function InteractionRoot({
4160
+ interaction,
4161
+ children,
4162
+ unavailable = "render"
4163
+ }) {
4164
+ const descriptor = useInteractionDescriptor(interaction);
4165
+ if (!descriptor) {
4166
+ if (unavailable === "hide") return null;
4167
+ return /* @__PURE__ */ jsx10(
4168
+ InteractionContext.Provider,
4317
4169
  {
4318
- style: {
4319
- fontSize: theme.typography.fontSize.sm,
4320
- color: theme.semantic.text.muted
4170
+ value: {
4171
+ interaction,
4172
+ descriptor: null,
4173
+ handle: null
4321
4174
  },
4322
- children: description
4175
+ children
4323
4176
  }
4324
- ) : null
4325
- ] });
4326
- const fieldsContent = visibleInputs.length > 0 ? /* @__PURE__ */ jsx11(
4327
- "div",
4328
- {
4329
- style: {
4330
- display: "flex",
4331
- flexDirection: "column",
4332
- gap: theme.space[3]
4333
- },
4334
- children: visibleInputs.map((input) => {
4335
- const key = input.key;
4336
- const inputRenderer = inputs?.[key];
4177
+ );
4178
+ }
4179
+ if (!isInteractionAvailable(descriptor) && unavailable === "hide") {
4180
+ return null;
4181
+ }
4182
+ return /* @__PURE__ */ jsx10(ResolvedInteractionRoot, { interaction, descriptor, children });
4183
+ }
4184
+
4185
+ // src/runtime/components/interaction-form/fields.tsx
4186
+ import { useId } from "react";
4187
+ import { Fragment as Fragment7, jsx as jsx11, jsxs as jsxs3 } from "react/jsx-runtime";
4188
+ var EMPTY_FIELD_ERRORS = [];
4189
+ function InteractionField({
4190
+ descriptor,
4191
+ inputKey,
4192
+ handle,
4193
+ errors = EMPTY_FIELD_ERRORS,
4194
+ missing = false,
4195
+ disabled = false,
4196
+ render
4197
+ }) {
4198
+ const input = descriptor.inputs.find(
4199
+ (candidate) => candidate.key === inputKey
4200
+ );
4201
+ if (!input) return null;
4202
+ const typedInput = resolveInputDomain(
4203
+ input,
4204
+ handle.values
4205
+ );
4206
+ const value = handle.values[inputKey];
4207
+ const props = {
4208
+ descriptor,
4209
+ input: typedInput,
4210
+ handle,
4211
+ value,
4212
+ setValue: (next) => handle.setInput(inputKey, next),
4213
+ clearValue: () => handle.clearInput(inputKey),
4214
+ errors,
4215
+ missing,
4216
+ disabled
4217
+ };
4218
+ if (render) return /* @__PURE__ */ jsx11(Fragment7, { children: render(props) });
4219
+ return /* @__PURE__ */ jsx11(DefaultInteractionField, { ...props });
4220
+ }
4221
+ function defaultFormInputs(descriptor, values = {}) {
4222
+ return resolveInteractionInputs(descriptor, values).filter((input) => {
4223
+ switch (input.domain.type) {
4224
+ case "choice":
4225
+ case "choiceList":
4226
+ case "resourceMap":
4227
+ case "boundedNumber":
4228
+ return true;
4229
+ case "cardTarget":
4230
+ case "boardTarget":
4231
+ return input.domain.selection?.mode === "many";
4232
+ }
4233
+ });
4234
+ }
4235
+ function DefaultInteractionField(props) {
4236
+ const { input } = props;
4237
+ switch (input.domain.type) {
4238
+ case "choice":
4239
+ if (input.domain.selection?.mode === "many") {
4337
4240
  return /* @__PURE__ */ jsx11(
4338
- InteractionField,
4241
+ ChoiceListField,
4339
4242
  {
4340
- descriptor,
4341
- inputKey: key,
4342
- handle,
4343
- errors: fieldErrors[key] ?? [],
4344
- missing: missing.has(key),
4345
- disabled: isDisabled,
4346
- render: inputRenderer ? ({ input: input2, errors, missing: missing2, disabled: disabled2 }) => inputRenderer(
4347
- createInteractionInputSlot({
4348
- descriptor,
4349
- input: input2,
4350
- handle,
4351
- errors,
4352
- missing: missing2,
4353
- disabled: disabled2
4354
- })
4355
- ) : renderFields?.[key]
4356
- },
4357
- input.key
4243
+ ...props,
4244
+ domain: {
4245
+ type: "choiceList",
4246
+ choices: input.domain.choices,
4247
+ min: input.domain.selection.min ?? 0,
4248
+ max: input.domain.selection.max,
4249
+ selection: input.domain.selection
4250
+ }
4251
+ }
4358
4252
  );
4359
- })
4360
- }
4361
- ) : null;
4362
- if (visibleInputs.length === 0 && !handle.isReady) {
4363
- throw new Error(
4364
- `InteractionForm '${descriptor.interactionKey}' has required inputs that cannot be rendered by the default form. Provide renderFields, select on a surface, or use a default-renderable input domain.`
4365
- );
4253
+ }
4254
+ return /* @__PURE__ */ jsx11(ChoiceField, { ...props, domain: input.domain });
4255
+ case "choiceList":
4256
+ return /* @__PURE__ */ jsx11(ChoiceListField, { ...props, domain: input.domain });
4257
+ case "resourceMap":
4258
+ return /* @__PURE__ */ jsx11(ResourceMapField, { ...props, domain: input.domain });
4259
+ case "boundedNumber":
4260
+ return /* @__PURE__ */ jsx11(BoundedNumberField, { ...props, domain: input.domain });
4261
+ case "cardTarget":
4262
+ case "boardTarget":
4263
+ return /* @__PURE__ */ jsx11(TargetSummaryField, { ...props, domain: input.domain });
4366
4264
  }
4367
- const formErrorContent = formErrors.length > 0 ? /* @__PURE__ */ jsx11(
4265
+ }
4266
+ function FieldFrame({
4267
+ label,
4268
+ controlId,
4269
+ errors,
4270
+ missing,
4271
+ children
4272
+ }) {
4273
+ const theme = useTheme();
4274
+ const messages = errors.length > 0 ? errors : missing ? ["Required"] : [];
4275
+ return /* @__PURE__ */ jsxs3(
4368
4276
  "div",
4369
4277
  {
4370
- role: "alert",
4371
4278
  style: {
4372
4279
  display: "flex",
4373
4280
  flexDirection: "column",
4374
4281
  gap: theme.space[1],
4375
- color: theme.semantic.intent.danger.solid,
4376
- fontSize: theme.typography.fontSize.sm
4282
+ fontSize: theme.typography.fontSize.sm,
4283
+ color: theme.semantic.text.primary
4377
4284
  },
4378
- children: formErrors.map((error) => /* @__PURE__ */ jsx11("span", { children: error }, error))
4285
+ children: [
4286
+ /* @__PURE__ */ jsx11(
4287
+ Label,
4288
+ {
4289
+ htmlFor: controlId,
4290
+ style: {
4291
+ color: theme.semantic.text.primary,
4292
+ fontWeight: theme.typography.fontWeight.bold
4293
+ },
4294
+ children: label
4295
+ }
4296
+ ),
4297
+ children,
4298
+ messages.length > 0 ? /* @__PURE__ */ jsx11(
4299
+ "span",
4300
+ {
4301
+ role: "alert",
4302
+ style: {
4303
+ display: "flex",
4304
+ flexDirection: "column",
4305
+ gap: 2,
4306
+ color: theme.semantic.intent.danger.solid,
4307
+ fontSize: theme.typography.fontSize.xs
4308
+ },
4309
+ children: messages.map((message) => /* @__PURE__ */ jsx11("span", { children: message }, message))
4310
+ }
4311
+ ) : null
4312
+ ]
4379
4313
  }
4380
- ) : null;
4381
- const actions = /* @__PURE__ */ jsxs3(
4382
- "div",
4314
+ );
4315
+ }
4316
+ function ChoiceOptionLabel({ choice }) {
4317
+ const theme = useTheme();
4318
+ return /* @__PURE__ */ jsxs3(
4319
+ "span",
4383
4320
  {
4384
4321
  style: {
4385
- display: "flex",
4386
- gap: theme.space[2],
4387
- justifyContent: "flex-end"
4322
+ display: "inline-flex",
4323
+ alignItems: "center",
4324
+ gap: 6,
4325
+ minWidth: 0
4388
4326
  },
4389
4327
  children: [
4390
- onCancel ? /* @__PURE__ */ jsx11(
4391
- ThemedButton,
4328
+ /* @__PURE__ */ jsxs3(
4329
+ "span",
4392
4330
  {
4393
- type: "button",
4394
- variant: "secondary",
4395
- size: "sm",
4396
- disabled: pending,
4397
- onClick: onCancel,
4398
- className: "h-9 px-3 text-sm",
4399
- children: cancelLabel
4331
+ style: {
4332
+ display: "inline-flex",
4333
+ alignItems: "center",
4334
+ gap: 6,
4335
+ minWidth: 0
4336
+ },
4337
+ children: [
4338
+ choice.icon ? /* @__PURE__ */ jsx11("span", { "aria-hidden": true, style: { fontSize: "1.1em", lineHeight: 1 }, children: choice.icon }) : null,
4339
+ /* @__PURE__ */ jsx11("span", { style: { overflow: "hidden", textOverflow: "ellipsis" }, children: choice.label })
4340
+ ]
4400
4341
  }
4401
- ) : null,
4402
- renderSubmit ? renderSubmit(
4403
- {
4404
- Button: ({ children, ...buttonProps }) => /* @__PURE__ */ jsx11(
4405
- ThemedButton,
4406
- {
4407
- type: "submit",
4408
- variant: "primary",
4409
- size: "sm",
4410
- disabled: isDisabled,
4411
- className: "h-9 px-3 text-sm",
4412
- ...submitBrowserAttributes,
4413
- ...buttonProps,
4414
- children: pending ? "Submitting..." : children ?? submitLabel ?? fallbackLabel
4415
- }
4416
- )
4417
- },
4418
- descriptor
4419
- ) : /* @__PURE__ */ jsx11(
4420
- ThemedButton,
4342
+ ),
4343
+ choice.badge ? /* @__PURE__ */ jsx11(
4344
+ "span",
4421
4345
  {
4422
- type: "submit",
4423
- variant: "primary",
4424
- size: "sm",
4425
- disabled: isDisabled,
4426
- className: "h-9 px-3 text-sm",
4427
- ...submitBrowserAttributes,
4428
- children: pending ? "Submitting..." : submitLabel ?? fallbackLabel
4346
+ style: {
4347
+ borderRadius: 999,
4348
+ background: theme.semantic.surface.inset,
4349
+ color: theme.semantic.text.muted,
4350
+ fontSize: theme.typography.fontSize.xs,
4351
+ fontWeight: theme.typography.fontWeight.bold,
4352
+ lineHeight: 1,
4353
+ padding: "3px 6px",
4354
+ whiteSpace: "nowrap"
4355
+ },
4356
+ children: choice.badge
4429
4357
  }
4430
- )
4358
+ ) : null
4431
4359
  ]
4432
4360
  }
4433
4361
  );
4434
- const body = /* @__PURE__ */ jsxs3(Fragment7, { children: [
4435
- fieldsContent,
4436
- formErrorContent,
4437
- actions
4438
- ] });
4362
+ }
4363
+ function ChoiceDescription({ choice }) {
4364
+ const theme = useTheme();
4365
+ const message = choice?.disabledReason ?? choice?.description;
4366
+ if (!message) return null;
4439
4367
  return /* @__PURE__ */ jsx11(
4440
- "form",
4368
+ "span",
4441
4369
  {
4442
- "data-interaction-form": true,
4443
- "data-interaction-id": descriptor.interactionId,
4444
- onSubmit: (event) => void submit(event),
4445
- style: containerStyle,
4446
- ...rootBrowserAttributes,
4447
- children: useAccordion ? /* @__PURE__ */ jsx11(
4448
- AccordionPrimitive.Root,
4449
- {
4450
- type: "single",
4451
- collapsible: true,
4452
- value: accordionOpen ? "fields" : void 0,
4453
- onValueChange: (value) => setAccordionOpen(value === "fields"),
4454
- children: /* @__PURE__ */ jsxs3(AccordionPrimitive.Item, { value: "fields", children: [
4455
- /* @__PURE__ */ jsx11(AccordionPrimitive.Header, { style: { margin: 0 }, children: /* @__PURE__ */ jsxs3(
4456
- AccordionPrimitive.Trigger,
4457
- {
4458
- ...armBrowserAttributes,
4459
- style: {
4460
- alignItems: "center",
4461
- appearance: "none",
4462
- background: "transparent",
4463
- border: 0,
4464
- color: theme.semantic.text.primary,
4465
- cursor: "pointer",
4466
- display: "flex",
4467
- fontFamily: theme.typography.fontFamily.display,
4468
- fontSize: theme.typography.fontSize.md,
4469
- fontWeight: theme.typography.fontWeight.bold,
4470
- justifyContent: "space-between",
4471
- padding: 0,
4472
- textAlign: "left",
4473
- width: "100%"
4474
- },
4475
- children: [
4476
- /* @__PURE__ */ jsx11("span", { children: title ?? fallbackLabel }),
4477
- /* @__PURE__ */ jsx11("span", { "aria-hidden": true, children: accordionOpen ? "\u2212" : "+" })
4478
- ]
4479
- }
4480
- ) }),
4481
- /* @__PURE__ */ jsx11(AccordionPrimitive.Content, { children: /* @__PURE__ */ jsxs3(
4482
- "div",
4483
- {
4484
- style: {
4485
- display: "flex",
4486
- flexDirection: "column",
4487
- gap: theme.space[2],
4488
- marginTop: theme.space[2]
4489
- },
4490
- children: [
4491
- description ? /* @__PURE__ */ jsx11(
4492
- "span",
4493
- {
4494
- style: {
4495
- fontSize: theme.typography.fontSize.sm,
4496
- color: theme.semantic.text.muted
4497
- },
4498
- children: description
4499
- }
4500
- ) : null,
4501
- body
4502
- ]
4503
- }
4504
- ) })
4505
- ] })
4506
- }
4507
- ) : /* @__PURE__ */ jsxs3(Fragment7, { children: [
4508
- header,
4509
- body
4510
- ] })
4370
+ style: {
4371
+ color: choice?.disabledReason ? theme.semantic.intent.danger.solid : theme.semantic.text.muted,
4372
+ fontSize: theme.typography.fontSize.xs
4373
+ },
4374
+ children: message
4511
4375
  }
4512
4376
  );
4513
4377
  }
4514
- function createInteractionInputSlot({
4378
+ var NULL_CHOICE_SELECT_VALUE = "__dreamboard_null_choice__";
4379
+ function choiceRenderKey(choice) {
4380
+ return choice.value === null ? NULL_CHOICE_SELECT_VALUE : choice.value;
4381
+ }
4382
+ function encodeChoiceSelectValue(value) {
4383
+ if (value === null) return NULL_CHOICE_SELECT_VALUE;
4384
+ return typeof value === "string" ? value : void 0;
4385
+ }
4386
+ function decodeChoiceSelectValue(value) {
4387
+ return value === NULL_CHOICE_SELECT_VALUE ? null : value;
4388
+ }
4389
+ function ChoiceField({
4515
4390
  descriptor,
4516
- input,
4517
4391
  handle,
4392
+ input,
4393
+ value,
4394
+ setValue,
4518
4395
  errors,
4519
4396
  missing,
4520
- disabled
4397
+ disabled,
4398
+ domain
4521
4399
  }) {
4522
- const value = handle.values[input.key];
4523
- const resolvedInput = resolveInputDomain(
4524
- input,
4525
- handle.values
4526
- );
4527
- const targetButton = ({
4528
- value: targetValue,
4529
- children,
4530
- kind,
4531
- ...buttonProps
4532
- }) => {
4533
- const domain = resolvedInput.domain;
4534
- const eligible = isResolvedTargetDomain(domain) && domain.eligibleTargets.includes(targetValue);
4535
- const selection = isTargetDomain(domain) ? domain.selection : void 0;
4536
- const currentValue = handle.values[input.key];
4537
- const selected = selection?.mode === "many" ? Array.isArray(currentValue) && currentValue.map(String).includes(targetValue) : currentValue !== void 0 && String(currentValue) === targetValue;
4538
- const isDisabled = disabled || !eligible;
4539
- const dataAttribute = kind === "card" ? { "data-dreamboard-interaction-card-slot": "" } : { "data-dreamboard-interaction-target-slot": "" };
4540
- const browserAttributes = gameplayActuatorAttributes({
4541
- descriptor,
4542
- draftValues: handle.values,
4543
- inputKey: input.key,
4544
- intent: selection?.mode === "many" ? "toggle" : "select",
4545
- candidateValue: targetValue,
4546
- candidateState: selected ? "selected" : "unselected",
4547
- enabled: !isDisabled,
4548
- actuatorKind: "click",
4549
- actuatorId: `${kind}:${input.key}:${targetValue}`,
4550
- semanticEffects: gameplayCandidateMetadata({
4551
- descriptor,
4552
- draftValues: handle.values,
4553
- inputKey: input.key,
4554
- candidateValue: targetValue,
4555
- intent: selection?.mode === "many" ? "toggle" : "select"
4556
- }).semanticEffects
4557
- });
4400
+ const theme = useTheme();
4401
+ const themeCssVars = useThemeCssVars();
4402
+ const choices = domain.choices ?? [];
4403
+ const controlId = useId();
4404
+ const selectedChoice = typeof value === "string" || value === null ? choices.find((choice) => choice.value === value) : void 0;
4405
+ if (choices.length > 0 && choices.length <= 3) {
4558
4406
  return /* @__PURE__ */ jsx11(
4559
- "button",
4560
- {
4561
- type: "button",
4562
- disabled: isDisabled,
4563
- "aria-disabled": isDisabled,
4564
- "aria-pressed": selected,
4565
- "data-input-name": input.key,
4566
- "data-target-kind": inputTargetKind(domain),
4567
- "data-target-value": targetValue,
4568
- "data-eligible": eligible,
4569
- "data-selected": selected || void 0,
4570
- "data-disabled": isDisabled || void 0,
4571
- ...dataAttribute,
4572
- ...browserAttributes,
4573
- ...buttonProps,
4574
- onClick: () => {
4575
- if (isDisabled) return;
4576
- const nextValue = selection?.mode === "many" ? toggleManyValue(currentValue, targetValue, selection) : targetValue;
4577
- handle.setInput(input.key, nextValue);
4578
- },
4579
- children: children ?? targetValue
4580
- }
4581
- );
4582
- };
4583
- return {
4584
- Field: () => /* @__PURE__ */ jsx11(
4585
- DefaultInteractionField,
4407
+ FieldFrame,
4586
4408
  {
4587
- descriptor,
4588
- input: resolvedInput,
4589
- handle,
4590
- value,
4591
- setValue: (next) => handle.setInput(input.key, next),
4592
- clearValue: () => handle.clearInput(input.key),
4409
+ label: labelForInput(input),
4593
4410
  errors,
4594
4411
  missing,
4595
- disabled
4412
+ children: /* @__PURE__ */ jsx11(
4413
+ "span",
4414
+ {
4415
+ style: {
4416
+ display: "inline-flex",
4417
+ flexWrap: "wrap",
4418
+ gap: theme.space[1]
4419
+ },
4420
+ children: choices.map((choice) => {
4421
+ const selected = value === choice.value;
4422
+ const isDisabled = disabled || choice.disabled;
4423
+ return /* @__PURE__ */ jsx11(
4424
+ ThemedButton,
4425
+ {
4426
+ type: "button",
4427
+ variant: selected ? "primary" : "secondary",
4428
+ size: "sm",
4429
+ disabled: isDisabled,
4430
+ "aria-pressed": selected,
4431
+ title: choice.disabledReason ?? choice.description,
4432
+ ...gameplayActuatorAttributes({
4433
+ descriptor,
4434
+ draftDigest: interactionDraftDigestForValues(
4435
+ descriptor,
4436
+ handle.values
4437
+ ),
4438
+ inputKey: input.key,
4439
+ intent: "select",
4440
+ candidateValue: choice.value,
4441
+ candidateState: selected ? "selected" : "unselected",
4442
+ enabled: !isDisabled,
4443
+ actuatorKind: "click",
4444
+ actuatorId: `choice:${input.key}:${choiceRenderKey(choice)}`,
4445
+ semanticEffects: gameplayCandidateMetadata({
4446
+ descriptor,
4447
+ draftValues: handle.values,
4448
+ inputKey: input.key,
4449
+ candidateValue: choice.value,
4450
+ intent: "select"
4451
+ }).semanticEffects
4452
+ }),
4453
+ onClick: () => setValue(choice.value),
4454
+ className: "h-8 px-3 text-sm",
4455
+ children: /* @__PURE__ */ jsx11(ChoiceOptionLabel, { choice })
4456
+ },
4457
+ choiceRenderKey(choice)
4458
+ );
4459
+ })
4460
+ }
4461
+ )
4596
4462
  }
4597
- ),
4598
- Default: ({ children }) => {
4599
- const hasDefault = "defaultValue" in input;
4600
- const isDisabled = disabled || !hasDefault;
4601
- const browserAttributes = gameplayActuatorAttributes({
4602
- descriptor,
4603
- draftValues: handle.values,
4604
- inputKey: input.key,
4605
- intent: "select",
4606
- candidateValue: input.defaultValue,
4607
- candidateState: "unselected",
4608
- enabled: !isDisabled,
4609
- actuatorKind: "click",
4610
- actuatorId: `default:${input.key}`,
4611
- semanticEffects: hasDefault ? gameplayCandidateMetadata({
4612
- descriptor,
4613
- draftValues: handle.values,
4614
- inputKey: input.key,
4615
- candidateValue: input.defaultValue,
4616
- intent: "select"
4617
- }).semanticEffects : void 0
4618
- });
4619
- return /* @__PURE__ */ jsx11(
4620
- "button",
4621
- {
4622
- type: "button",
4623
- disabled: isDisabled,
4624
- "aria-disabled": isDisabled,
4625
- "data-dreamboard-interaction-default-slot": "",
4626
- "data-input-name": input.key,
4627
- "data-disabled": isDisabled || void 0,
4628
- ...browserAttributes,
4629
- onClick: () => {
4630
- if (isDisabled) return;
4631
- handle.setInput(input.key, input.defaultValue);
4632
- },
4633
- children: children ?? "Use default"
4634
- }
4635
- );
4636
- },
4637
- Target: (props) => targetButton({ ...props, kind: "target" }),
4638
- Card: (props) => targetButton({ ...props, kind: "card" }),
4639
- Cards: ({ children }) => {
4640
- const domain = resolvedInput.domain;
4641
- const targets = isResolvedTargetDomain(domain) ? domain.eligibleTargets : [];
4642
- return /* @__PURE__ */ jsx11(Fragment7, { children: targets.map((id) => children({ id })) });
4643
- },
4644
- Options: ({ children }) => {
4645
- const domain = resolvedInput.domain;
4646
- const choices = domain.type === "choice" || domain.type === "choiceList" ? domain.choices ?? [] : [];
4647
- return /* @__PURE__ */ jsx11(Fragment7, { children: choices.map((choice) => children(choice)) });
4648
- },
4649
- Value: ({ children }) => /* @__PURE__ */ jsx11(Fragment7, { children: children(value) }),
4650
- Label: ({ children }) => /* @__PURE__ */ jsx11(Fragment7, { children: children ?? labelForInput(resolvedInput) }),
4651
- Message: ({ children }) => {
4652
- const message = children ?? errors[0] ?? (missing ? "Required" : null);
4653
- return message ? /* @__PURE__ */ jsx11("span", { role: "alert", "data-dreamboard-interaction-message-slot": "", children: message }) : null;
4654
- }
4655
- };
4656
- }
4657
- function InteractionField({
4658
- descriptor,
4659
- inputKey,
4660
- handle,
4661
- errors = EMPTY_FIELD_ERRORS,
4662
- missing = false,
4663
- disabled = false,
4664
- render
4665
- }) {
4666
- const input = descriptor.inputs.find(
4667
- (candidate) => candidate.key === inputKey
4668
- );
4669
- if (!input) return null;
4670
- const typedInput = resolveInputDomain(
4671
- input,
4672
- handle.values
4673
- );
4674
- const value = handle.values[inputKey];
4675
- const props = {
4676
- descriptor,
4677
- input: typedInput,
4678
- handle,
4679
- value,
4680
- setValue: (next) => handle.setInput(inputKey, next),
4681
- clearValue: () => handle.clearInput(inputKey),
4682
- errors,
4683
- missing,
4684
- disabled
4685
- };
4686
- if (render) return /* @__PURE__ */ jsx11(Fragment7, { children: render(props) });
4687
- return /* @__PURE__ */ jsx11(DefaultInteractionField, { ...props });
4688
- }
4689
- function defaultFormInputs(descriptor, values = {}) {
4690
- return resolveInteractionInputs(descriptor, values).filter((input) => {
4691
- switch (input.domain.type) {
4692
- case "choice":
4693
- case "choiceList":
4694
- case "resourceMap":
4695
- case "boundedNumber":
4696
- return true;
4697
- case "cardTarget":
4698
- case "boardTarget":
4699
- return input.domain.selection?.mode === "many";
4700
- }
4701
- });
4702
- }
4703
- function DefaultInteractionField(props) {
4704
- const { input } = props;
4705
- switch (input.domain.type) {
4706
- case "choice":
4707
- if (input.domain.selection?.mode === "many") {
4708
- return /* @__PURE__ */ jsx11(
4709
- ChoiceListField,
4710
- {
4711
- ...props,
4712
- domain: {
4713
- type: "choiceList",
4714
- choices: input.domain.choices,
4715
- min: input.domain.selection.min ?? 0,
4716
- max: input.domain.selection.max,
4717
- selection: input.domain.selection
4718
- }
4719
- }
4720
- );
4721
- }
4722
- return /* @__PURE__ */ jsx11(ChoiceField, { ...props, domain: input.domain });
4723
- case "choiceList":
4724
- return /* @__PURE__ */ jsx11(ChoiceListField, { ...props, domain: input.domain });
4725
- case "resourceMap":
4726
- return /* @__PURE__ */ jsx11(ResourceMapField, { ...props, domain: input.domain });
4727
- case "boundedNumber":
4728
- return /* @__PURE__ */ jsx11(BoundedNumberField, { ...props, domain: input.domain });
4729
- case "cardTarget":
4730
- case "boardTarget":
4731
- return /* @__PURE__ */ jsx11(TargetSummaryField, { ...props, domain: input.domain });
4463
+ );
4732
4464
  }
4733
- }
4734
- function FieldFrame({
4735
- label,
4736
- controlId,
4737
- errors,
4738
- missing,
4739
- children
4740
- }) {
4741
- const theme = useTheme();
4742
- const messages = errors.length > 0 ? errors : missing ? ["Required"] : [];
4743
- return /* @__PURE__ */ jsxs3(
4744
- "div",
4745
- {
4746
- style: {
4747
- display: "flex",
4748
- flexDirection: "column",
4749
- gap: theme.space[1],
4750
- fontSize: theme.typography.fontSize.sm,
4751
- color: theme.semantic.text.primary
4752
- },
4753
- children: [
4754
- /* @__PURE__ */ jsx11(
4755
- Label,
4756
- {
4757
- htmlFor: controlId,
4758
- style: {
4759
- color: theme.semantic.text.primary,
4760
- fontWeight: theme.typography.fontWeight.bold
4761
- },
4762
- children: label
4763
- }
4764
- ),
4765
- children,
4766
- messages.length > 0 ? /* @__PURE__ */ jsx11(
4767
- "span",
4768
- {
4769
- role: "alert",
4770
- style: {
4771
- display: "flex",
4772
- flexDirection: "column",
4773
- gap: 2,
4774
- color: theme.semantic.intent.danger.solid,
4775
- fontSize: theme.typography.fontSize.xs
4776
- },
4777
- children: messages.map((message) => /* @__PURE__ */ jsx11("span", { children: message }, message))
4778
- }
4779
- ) : null
4780
- ]
4781
- }
4782
- );
4783
- }
4784
- function ChoiceOptionLabel({ choice }) {
4785
- const theme = useTheme();
4786
4465
  return /* @__PURE__ */ jsxs3(
4787
- "span",
4466
+ FieldFrame,
4788
4467
  {
4789
- style: {
4790
- display: "inline-flex",
4791
- alignItems: "center",
4792
- gap: 6,
4793
- minWidth: 0
4794
- },
4468
+ label: labelForInput(input),
4469
+ controlId,
4470
+ errors,
4471
+ missing,
4795
4472
  children: [
4796
4473
  /* @__PURE__ */ jsxs3(
4797
- "span",
4474
+ Select,
4798
4475
  {
4799
- style: {
4800
- display: "inline-flex",
4801
- alignItems: "center",
4802
- gap: 6,
4803
- minWidth: 0
4804
- },
4476
+ disabled,
4477
+ value: encodeChoiceSelectValue(value),
4478
+ onValueChange: (next) => setValue(decodeChoiceSelectValue(next)),
4805
4479
  children: [
4806
- choice.icon ? /* @__PURE__ */ jsx11("span", { "aria-hidden": true, style: { fontSize: "1.1em", lineHeight: 1 }, children: choice.icon }) : null,
4807
- /* @__PURE__ */ jsx11("span", { style: { overflow: "hidden", textOverflow: "ellipsis" }, children: choice.label })
4480
+ /* @__PURE__ */ jsx11(
4481
+ SelectTrigger,
4482
+ {
4483
+ id: controlId,
4484
+ size: "sm",
4485
+ className: "w-full bg-white",
4486
+ ...gameplayActuatorAttributes({
4487
+ descriptor,
4488
+ draftDigest: interactionDraftDigestForValues(
4489
+ descriptor,
4490
+ handle.values
4491
+ ),
4492
+ inputKey: input.key,
4493
+ intent: "reveal",
4494
+ enabled: !disabled,
4495
+ actuatorKind: "click",
4496
+ actuatorId: `choice-reveal:${input.key}`,
4497
+ preparationPatterns: gameplayPreparationPatternsForDescriptor(
4498
+ { inputs: [input] },
4499
+ handle.values
4500
+ )
4501
+ }),
4502
+ children: /* @__PURE__ */ jsx11("span", { "data-slot": "select-value", children: selectedChoice ? /* @__PURE__ */ jsx11(ChoiceOptionLabel, { choice: selectedChoice }) : /* @__PURE__ */ jsx11("span", { style: { color: theme.semantic.text.muted }, children: "Choose..." }) })
4503
+ }
4504
+ ),
4505
+ /* @__PURE__ */ jsx11(
4506
+ SelectContent,
4507
+ {
4508
+ style: {
4509
+ ...themeCssVars,
4510
+ fontFamily: theme.typography.fontFamily.body
4511
+ },
4512
+ children: choices.map((choice) => /* @__PURE__ */ jsx11(
4513
+ SelectItem,
4514
+ {
4515
+ value: choiceRenderKey(choice),
4516
+ textValue: choice.label,
4517
+ disabled: choice.disabled,
4518
+ ...gameplayActuatorAttributes({
4519
+ descriptor,
4520
+ draftDigest: interactionDraftDigestForValues(
4521
+ descriptor,
4522
+ handle.values
4523
+ ),
4524
+ inputKey: input.key,
4525
+ intent: "select",
4526
+ candidateValue: choice.value,
4527
+ candidateState: value === choice.value ? "selected" : "unselected",
4528
+ enabled: !disabled && !choice.disabled,
4529
+ actuatorKind: "click",
4530
+ actuatorId: `choice:${input.key}:${choiceRenderKey(choice)}`,
4531
+ semanticEffects: gameplayCandidateMetadata({
4532
+ descriptor,
4533
+ draftValues: handle.values,
4534
+ inputKey: input.key,
4535
+ candidateValue: choice.value,
4536
+ intent: "select"
4537
+ }).semanticEffects
4538
+ }),
4539
+ children: /* @__PURE__ */ jsx11(ChoiceOptionLabel, { choice })
4540
+ },
4541
+ choiceRenderKey(choice)
4542
+ ))
4543
+ }
4544
+ )
4808
4545
  ]
4809
4546
  }
4810
4547
  ),
4811
- choice.badge ? /* @__PURE__ */ jsx11(
4812
- "span",
4813
- {
4814
- style: {
4815
- borderRadius: 999,
4816
- background: theme.semantic.surface.inset,
4817
- color: theme.semantic.text.muted,
4818
- fontSize: theme.typography.fontSize.xs,
4819
- fontWeight: theme.typography.fontWeight.bold,
4820
- lineHeight: 1,
4821
- padding: "3px 6px",
4822
- whiteSpace: "nowrap"
4823
- },
4824
- children: choice.badge
4825
- }
4826
- ) : null
4548
+ /* @__PURE__ */ jsx11(ChoiceDescription, { choice: selectedChoice })
4827
4549
  ]
4828
4550
  }
4829
4551
  );
4830
4552
  }
4831
- function ChoiceDescription({ choice }) {
4832
- const theme = useTheme();
4833
- const message = choice?.disabledReason ?? choice?.description;
4834
- if (!message) return null;
4835
- return /* @__PURE__ */ jsx11(
4836
- "span",
4837
- {
4838
- style: {
4839
- color: choice?.disabledReason ? theme.semantic.intent.danger.solid : theme.semantic.text.muted,
4840
- fontSize: theme.typography.fontSize.xs
4841
- },
4842
- children: message
4843
- }
4844
- );
4845
- }
4846
- var NULL_CHOICE_SELECT_VALUE = "__dreamboard_null_choice__";
4847
- function choiceRenderKey(choice) {
4848
- return choice.value === null ? NULL_CHOICE_SELECT_VALUE : choice.value;
4849
- }
4850
- function encodeChoiceSelectValue(value) {
4851
- if (value === null) return NULL_CHOICE_SELECT_VALUE;
4852
- return typeof value === "string" ? value : void 0;
4853
- }
4854
- function decodeChoiceSelectValue(value) {
4855
- return value === NULL_CHOICE_SELECT_VALUE ? null : value;
4856
- }
4857
- function ChoiceField({
4858
- descriptor,
4859
- handle,
4860
- input,
4861
- value,
4862
- setValue,
4863
- errors,
4864
- missing,
4865
- disabled,
4866
- domain
4867
- }) {
4868
- const theme = useTheme();
4869
- const themeCssVars = useThemeCssVars();
4870
- const choices = domain.choices ?? [];
4871
- const controlId = useId();
4872
- const selectedChoice = typeof value === "string" || value === null ? choices.find((choice) => choice.value === value) : void 0;
4873
- if (choices.length > 0 && choices.length <= 3) {
4874
- return /* @__PURE__ */ jsx11(
4875
- FieldFrame,
4876
- {
4877
- label: labelForInput(input),
4878
- errors,
4879
- missing,
4880
- children: /* @__PURE__ */ jsx11(
4881
- "span",
4882
- {
4883
- style: {
4884
- display: "inline-flex",
4885
- flexWrap: "wrap",
4886
- gap: theme.space[1]
4887
- },
4888
- children: choices.map((choice) => {
4889
- const selected = value === choice.value;
4890
- const isDisabled = disabled || choice.disabled;
4891
- return /* @__PURE__ */ jsx11(
4892
- ThemedButton,
4893
- {
4894
- type: "button",
4895
- variant: selected ? "primary" : "secondary",
4896
- size: "sm",
4897
- disabled: isDisabled,
4898
- "aria-pressed": selected,
4899
- title: choice.disabledReason ?? choice.description,
4900
- ...gameplayActuatorAttributes({
4901
- descriptor,
4902
- draftValues: handle.values,
4903
- inputKey: input.key,
4904
- intent: "select",
4905
- candidateValue: choice.value,
4906
- candidateState: selected ? "selected" : "unselected",
4907
- enabled: !isDisabled,
4908
- actuatorKind: "click",
4909
- actuatorId: `choice:${input.key}:${choiceRenderKey(choice)}`,
4910
- semanticEffects: gameplayCandidateMetadata({
4911
- descriptor,
4912
- draftValues: handle.values,
4913
- inputKey: input.key,
4914
- candidateValue: choice.value,
4915
- intent: "select"
4916
- }).semanticEffects
4917
- }),
4918
- onClick: () => setValue(choice.value),
4919
- className: "h-8 px-3 text-sm",
4920
- children: /* @__PURE__ */ jsx11(ChoiceOptionLabel, { choice })
4921
- },
4922
- choiceRenderKey(choice)
4923
- );
4924
- })
4925
- }
4926
- )
4927
- }
4928
- );
4929
- }
4930
- return /* @__PURE__ */ jsxs3(
4931
- FieldFrame,
4932
- {
4933
- label: labelForInput(input),
4934
- controlId,
4935
- errors,
4936
- missing,
4937
- children: [
4938
- /* @__PURE__ */ jsxs3(
4939
- Select,
4940
- {
4941
- disabled,
4942
- value: encodeChoiceSelectValue(value),
4943
- onValueChange: (next) => setValue(decodeChoiceSelectValue(next)),
4944
- children: [
4945
- /* @__PURE__ */ jsx11(
4946
- SelectTrigger,
4947
- {
4948
- id: controlId,
4949
- size: "sm",
4950
- className: "w-full bg-white",
4951
- ...gameplayActuatorAttributes({
4952
- descriptor,
4953
- draftValues: handle.values,
4954
- inputKey: input.key,
4955
- intent: "reveal",
4956
- enabled: !disabled,
4957
- actuatorKind: "click",
4958
- actuatorId: `choice-reveal:${input.key}`,
4959
- preparationPatterns: gameplayPreparationPatternsForDescriptor(
4960
- { inputs: [input] },
4961
- handle.values
4962
- )
4963
- }),
4964
- children: /* @__PURE__ */ jsx11("span", { "data-slot": "select-value", children: selectedChoice ? /* @__PURE__ */ jsx11(ChoiceOptionLabel, { choice: selectedChoice }) : /* @__PURE__ */ jsx11("span", { style: { color: theme.semantic.text.muted }, children: "Choose..." }) })
4965
- }
4966
- ),
4967
- /* @__PURE__ */ jsx11(
4968
- SelectContent,
4969
- {
4970
- style: {
4971
- ...themeCssVars,
4972
- fontFamily: theme.typography.fontFamily.body
4973
- },
4974
- children: choices.map((choice) => /* @__PURE__ */ jsx11(
4975
- SelectItem,
4976
- {
4977
- value: choiceRenderKey(choice),
4978
- textValue: choice.label,
4979
- disabled: choice.disabled,
4980
- ...gameplayActuatorAttributes({
4981
- descriptor,
4982
- draftValues: handle.values,
4983
- inputKey: input.key,
4984
- intent: "select",
4985
- candidateValue: choice.value,
4986
- candidateState: value === choice.value ? "selected" : "unselected",
4987
- enabled: !disabled && !choice.disabled,
4988
- actuatorKind: "click",
4989
- actuatorId: `choice:${input.key}:${choiceRenderKey(choice)}`,
4990
- semanticEffects: gameplayCandidateMetadata({
4991
- descriptor,
4992
- draftValues: handle.values,
4993
- inputKey: input.key,
4994
- candidateValue: choice.value,
4995
- intent: "select"
4996
- }).semanticEffects
4997
- }),
4998
- children: /* @__PURE__ */ jsx11(ChoiceOptionLabel, { choice })
4999
- },
5000
- choiceRenderKey(choice)
5001
- ))
5002
- }
5003
- )
5004
- ]
5005
- }
5006
- ),
5007
- /* @__PURE__ */ jsx11(ChoiceDescription, { choice: selectedChoice })
5008
- ]
5009
- }
5010
- );
5011
- }
5012
- function ChoiceListField({
5013
- descriptor,
5014
- handle,
5015
- input,
5016
- value,
5017
- setValue,
5018
- errors,
5019
- missing,
5020
- disabled,
5021
- domain
5022
- }) {
4553
+ function ChoiceListField({
4554
+ descriptor,
4555
+ handle,
4556
+ input,
4557
+ value,
4558
+ setValue,
4559
+ errors,
4560
+ missing,
4561
+ disabled,
4562
+ domain
4563
+ }) {
5023
4564
  const theme = useTheme();
5024
4565
  const selected = new Set(Array.isArray(value) ? value : []);
5025
4566
  const min = domain.selection?.mode === "many" ? domain.selection.min ?? 0 : domain.min;
@@ -5065,7 +4606,10 @@ function ChoiceListField({
5065
4606
  title: choice.disabledReason ?? choice.description,
5066
4607
  ...gameplayActuatorAttributes({
5067
4608
  descriptor,
5068
- draftValues: handle.values,
4609
+ draftDigest: interactionDraftDigestForValues(
4610
+ descriptor,
4611
+ handle.values
4612
+ ),
5069
4613
  inputKey: input.key,
5070
4614
  intent: "toggle",
5071
4615
  candidateValue: value2,
@@ -5156,7 +4700,10 @@ function ResourceMapField({
5156
4700
  disabled: disabled || amount <= min,
5157
4701
  browserAttributes: gameplayActuatorAttributes({
5158
4702
  descriptor,
5159
- draftValues: handle.values,
4703
+ draftDigest: interactionDraftDigestForValues(
4704
+ descriptor,
4705
+ handle.values
4706
+ ),
5160
4707
  inputKey: input.key,
5161
4708
  intent: "decrement",
5162
4709
  candidateValue: resource.resourceId,
@@ -5191,7 +4738,10 @@ function ResourceMapField({
5191
4738
  disabled: disabled || amount >= max,
5192
4739
  browserAttributes: gameplayActuatorAttributes({
5193
4740
  descriptor,
5194
- draftValues: handle.values,
4741
+ draftDigest: interactionDraftDigestForValues(
4742
+ descriptor,
4743
+ handle.values
4744
+ ),
5195
4745
  inputKey: input.key,
5196
4746
  intent: "increment",
5197
4747
  candidateValue: resource.resourceId,
@@ -5257,7 +4807,10 @@ function BoundedNumberField({
5257
4807
  disabled: disabled || current <= min,
5258
4808
  browserAttributes: gameplayActuatorAttributes({
5259
4809
  descriptor,
5260
- draftValues: handle.values,
4810
+ draftDigest: interactionDraftDigestForValues(
4811
+ descriptor,
4812
+ handle.values
4813
+ ),
5261
4814
  inputKey: input.key,
5262
4815
  intent: "decrement",
5263
4816
  enabled: !(disabled || current <= min),
@@ -5284,7 +4837,10 @@ function BoundedNumberField({
5284
4837
  disabled,
5285
4838
  ...gameplayActuatorAttributes({
5286
4839
  descriptor,
5287
- draftValues: handle.values,
4840
+ draftDigest: interactionDraftDigestForValues(
4841
+ descriptor,
4842
+ handle.values
4843
+ ),
5288
4844
  inputKey: input.key,
5289
4845
  intent: "fill",
5290
4846
  enabled: !disabled,
@@ -5306,7 +4862,10 @@ function BoundedNumberField({
5306
4862
  disabled: disabled || current >= max,
5307
4863
  browserAttributes: gameplayActuatorAttributes({
5308
4864
  descriptor,
5309
- draftValues: handle.values,
4865
+ draftDigest: interactionDraftDigestForValues(
4866
+ descriptor,
4867
+ handle.values
4868
+ ),
5310
4869
  inputKey: input.key,
5311
4870
  intent: "increment",
5312
4871
  enabled: !(disabled || current >= max),
@@ -5320,76 +4879,583 @@ function BoundedNumberField({
5320
4879
  onClick: () => update(current + step),
5321
4880
  children: "+"
5322
4881
  }
5323
- )
5324
- ]
4882
+ )
4883
+ ]
4884
+ }
4885
+ )
4886
+ }
4887
+ );
4888
+ }
4889
+ function TargetSummaryField({
4890
+ input,
4891
+ value,
4892
+ errors,
4893
+ missing,
4894
+ domain
4895
+ }) {
4896
+ const target = inputTargetKind(domain) ?? "target";
4897
+ return /* @__PURE__ */ jsx11(FieldFrame, { label: labelForInput(input), errors, missing, children: /* @__PURE__ */ jsx11("span", { children: Array.isArray(value) ? value.length > 0 ? `${value.length} selected: ${value.join(", ")}` : `Select ${targetSelectionLabel(domain)}.` : typeof value === "string" ? value : `Select a ${target} on the board.` }) });
4898
+ }
4899
+ function targetSelectionLabel(domain) {
4900
+ const target = inputTargetKind(domain) ?? "target";
4901
+ const selection = isTargetDomain(domain) ? domain.selection : void 0;
4902
+ if (selection?.mode !== "many") return `a ${target}`;
4903
+ const min = selection.min ?? 0;
4904
+ if (selection.max !== void 0 && min === selection.max) {
4905
+ return `${min} ${target}${min === 1 ? "" : "s"}`;
4906
+ }
4907
+ return `${min}${selection.max ? `-${selection.max}` : "+"} ${target}s`;
4908
+ }
4909
+ function StepperButton({
4910
+ label,
4911
+ disabled,
4912
+ browserAttributes,
4913
+ onClick,
4914
+ children
4915
+ }) {
4916
+ return /* @__PURE__ */ jsx11(
4917
+ ThemedButton,
4918
+ {
4919
+ type: "button",
4920
+ variant: "secondary",
4921
+ size: "sm",
4922
+ "aria-label": label,
4923
+ disabled,
4924
+ ...browserAttributes,
4925
+ onClick,
4926
+ className: "h-8 w-8 text-sm",
4927
+ children
4928
+ }
4929
+ );
4930
+ }
4931
+ function labelForInput(input) {
4932
+ if (input.domain.type === "choice") {
4933
+ const exact = input.domain.choices?.find(
4934
+ (choice) => choice.value === input.defaultValue
4935
+ );
4936
+ if (exact?.label && input.key === exact.value) return exact.label;
4937
+ }
4938
+ return humanize(input.key);
4939
+ }
4940
+ function humanize(key) {
4941
+ return key.replace(/Id$/, "").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[-_]+/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
4942
+ }
4943
+ function isRecord2(value) {
4944
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4945
+ }
4946
+ function numberOrZero(value) {
4947
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
4948
+ }
4949
+
4950
+ // src/runtime/components/interaction-form/InteractionForm.tsx
4951
+ import {
4952
+ useEffect as useEffect6,
4953
+ useId as useId2,
4954
+ useMemo as useMemo12,
4955
+ useState as useState4
4956
+ } from "react";
4957
+ import * as AccordionPrimitive from "@radix-ui/react-accordion";
4958
+
4959
+ // src/runtime/components/interaction-form/input-slot.tsx
4960
+ import { Fragment as Fragment8, jsx as jsx12 } from "react/jsx-runtime";
4961
+ function createInteractionInputSlot({
4962
+ descriptor,
4963
+ input,
4964
+ handle,
4965
+ errors,
4966
+ missing,
4967
+ disabled
4968
+ }) {
4969
+ const value = handle.values[input.key];
4970
+ const resolvedInput = resolveInputDomain(
4971
+ input,
4972
+ handle.values
4973
+ );
4974
+ const targetButton = ({
4975
+ value: targetValue,
4976
+ children,
4977
+ kind,
4978
+ ...buttonProps
4979
+ }) => {
4980
+ const domain = resolvedInput.domain;
4981
+ const eligible = isResolvedTargetDomain(domain) && domain.eligibleTargets.includes(targetValue);
4982
+ const selection = isTargetDomain(domain) ? domain.selection : void 0;
4983
+ const currentValue = handle.values[input.key];
4984
+ const selected = selection?.mode === "many" ? Array.isArray(currentValue) && currentValue.map(String).includes(targetValue) : currentValue !== void 0 && String(currentValue) === targetValue;
4985
+ const isDisabled = disabled || !eligible;
4986
+ const dataAttribute = kind === "card" ? { "data-dreamboard-interaction-card-slot": "" } : { "data-dreamboard-interaction-target-slot": "" };
4987
+ const browserAttributes = gameplayActuatorAttributes({
4988
+ descriptor,
4989
+ draftDigest: interactionDraftDigestForValues(
4990
+ descriptor,
4991
+ handle.values
4992
+ ),
4993
+ inputKey: input.key,
4994
+ intent: selection?.mode === "many" ? "toggle" : "select",
4995
+ candidateValue: targetValue,
4996
+ candidateState: selected ? "selected" : "unselected",
4997
+ enabled: !isDisabled,
4998
+ actuatorKind: "click",
4999
+ actuatorId: `${kind}:${input.key}:${targetValue}`,
5000
+ semanticEffects: gameplayCandidateMetadata({
5001
+ descriptor,
5002
+ draftValues: handle.values,
5003
+ inputKey: input.key,
5004
+ candidateValue: targetValue,
5005
+ intent: selection?.mode === "many" ? "toggle" : "select"
5006
+ }).semanticEffects
5007
+ });
5008
+ return /* @__PURE__ */ jsx12(
5009
+ "button",
5010
+ {
5011
+ type: "button",
5012
+ disabled: isDisabled,
5013
+ "aria-disabled": isDisabled,
5014
+ "aria-pressed": selected,
5015
+ "data-input-name": input.key,
5016
+ "data-target-kind": inputTargetKind(domain),
5017
+ "data-target-value": targetValue,
5018
+ "data-eligible": eligible,
5019
+ "data-selected": selected || void 0,
5020
+ "data-disabled": isDisabled || void 0,
5021
+ ...dataAttribute,
5022
+ ...browserAttributes,
5023
+ ...buttonProps,
5024
+ onClick: () => {
5025
+ if (isDisabled) return;
5026
+ const nextValue = selection?.mode === "many" ? toggleManyValue(currentValue, targetValue, selection) : targetValue;
5027
+ handle.setInput(input.key, nextValue);
5028
+ },
5029
+ children: children ?? targetValue
5030
+ }
5031
+ );
5032
+ };
5033
+ return {
5034
+ Field: () => /* @__PURE__ */ jsx12(
5035
+ DefaultInteractionField,
5036
+ {
5037
+ descriptor,
5038
+ input: resolvedInput,
5039
+ handle,
5040
+ value,
5041
+ setValue: (next) => handle.setInput(input.key, next),
5042
+ clearValue: () => handle.clearInput(input.key),
5043
+ errors,
5044
+ missing,
5045
+ disabled
5046
+ }
5047
+ ),
5048
+ Default: ({ children }) => {
5049
+ const hasDefault = "defaultValue" in input;
5050
+ const isDisabled = disabled || !hasDefault;
5051
+ const browserAttributes = gameplayActuatorAttributes({
5052
+ descriptor,
5053
+ draftDigest: interactionDraftDigestForValues(
5054
+ descriptor,
5055
+ handle.values
5056
+ ),
5057
+ inputKey: input.key,
5058
+ intent: "select",
5059
+ candidateValue: input.defaultValue,
5060
+ candidateState: "unselected",
5061
+ enabled: !isDisabled,
5062
+ actuatorKind: "click",
5063
+ actuatorId: `default:${input.key}`,
5064
+ semanticEffects: hasDefault ? gameplayCandidateMetadata({
5065
+ descriptor,
5066
+ draftValues: handle.values,
5067
+ inputKey: input.key,
5068
+ candidateValue: input.defaultValue,
5069
+ intent: "select"
5070
+ }).semanticEffects : void 0
5071
+ });
5072
+ return /* @__PURE__ */ jsx12(
5073
+ "button",
5074
+ {
5075
+ type: "button",
5076
+ disabled: isDisabled,
5077
+ "aria-disabled": isDisabled,
5078
+ "data-dreamboard-interaction-default-slot": "",
5079
+ "data-input-name": input.key,
5080
+ "data-disabled": isDisabled || void 0,
5081
+ ...browserAttributes,
5082
+ onClick: () => {
5083
+ if (isDisabled) return;
5084
+ handle.setInput(input.key, input.defaultValue);
5085
+ },
5086
+ children: children ?? "Use default"
5087
+ }
5088
+ );
5089
+ },
5090
+ Target: (props) => targetButton({ ...props, kind: "target" }),
5091
+ Card: (props) => targetButton({ ...props, kind: "card" }),
5092
+ Cards: ({ children }) => {
5093
+ const domain = resolvedInput.domain;
5094
+ const targets = isResolvedTargetDomain(domain) ? domain.eligibleTargets : [];
5095
+ return /* @__PURE__ */ jsx12(Fragment8, { children: targets.map((id) => children({ id })) });
5096
+ },
5097
+ Options: ({ children }) => {
5098
+ const domain = resolvedInput.domain;
5099
+ const choices = domain.type === "choice" || domain.type === "choiceList" ? domain.choices ?? [] : [];
5100
+ return /* @__PURE__ */ jsx12(Fragment8, { children: choices.map((choice) => children(choice)) });
5101
+ },
5102
+ Value: ({ children }) => /* @__PURE__ */ jsx12(Fragment8, { children: children(value) }),
5103
+ Label: ({ children }) => /* @__PURE__ */ jsx12(Fragment8, { children: children ?? labelForInput(resolvedInput) }),
5104
+ Message: ({ children }) => {
5105
+ const message = children ?? errors[0] ?? (missing ? "Required" : null);
5106
+ return message ? /* @__PURE__ */ jsx12("span", { role: "alert", "data-dreamboard-interaction-message-slot": "", children: message }) : null;
5107
+ }
5108
+ };
5109
+ }
5110
+
5111
+ // src/runtime/components/interaction-form/InteractionForm.tsx
5112
+ import { Fragment as Fragment9, jsx as jsx13, jsxs as jsxs4 } from "react/jsx-runtime";
5113
+ function InteractionForm({
5114
+ descriptor,
5115
+ handle,
5116
+ fields,
5117
+ hiddenFields,
5118
+ renderFields,
5119
+ inputs,
5120
+ submit: renderSubmit,
5121
+ title,
5122
+ description,
5123
+ submitLabel,
5124
+ cancelLabel = "Cancel",
5125
+ onCancel,
5126
+ onSubmitSuccess,
5127
+ disabled = false,
5128
+ accordion = true,
5129
+ defaultOpen = false,
5130
+ style
5131
+ }) {
5132
+ const theme = useTheme();
5133
+ const fallbackLabel = interactionLabel(descriptor);
5134
+ const formId = useId2();
5135
+ useChromeSuppression(formId, true);
5136
+ const [pending, setPending] = useState4(false);
5137
+ const [validation, setValidation] = useState4(
5138
+ null
5139
+ );
5140
+ const [formError, setFormError] = useState4(null);
5141
+ const [accordionOpen, setAccordionOpen] = useState4(defaultOpen);
5142
+ const hidden = useMemo12(() => new Set(hiddenFields ?? []), [hiddenFields]);
5143
+ const visibleInputs = useMemo12(() => {
5144
+ if (inputs) {
5145
+ const rendered = new Set(Object.keys(inputs));
5146
+ return resolveInteractionInputs(
5147
+ descriptor,
5148
+ handle.values
5149
+ ).filter((input) => rendered.has(input.key));
5150
+ }
5151
+ const allowed = fields ? new Set(fields) : null;
5152
+ return defaultFormInputs(
5153
+ descriptor,
5154
+ handle.values
5155
+ ).filter((input) => {
5156
+ const key = input.key;
5157
+ if (allowed && !allowed.has(key)) return false;
5158
+ return !hidden.has(key);
5159
+ });
5160
+ }, [descriptor, fields, hidden, handle.values, inputs]);
5161
+ const currentValidation = validation;
5162
+ const fieldErrors = currentValidation?.fieldErrors ?? {};
5163
+ const missing = new Set(currentValidation?.missing ?? []);
5164
+ const formErrors = [
5165
+ ...currentValidation?.formErrors ?? [],
5166
+ ...formError ? [formError] : []
5167
+ ];
5168
+ const isDisabled = disabled || pending || !isInteractionAvailable(descriptor);
5169
+ const useAccordion = accordion && visibleInputs.length > 0;
5170
+ const rootBrowserAttributes = gameplayInteractionRootAttributes({
5171
+ descriptor,
5172
+ draftDigest: interactionDraftDigestForValues(
5173
+ descriptor,
5174
+ handle.values
5175
+ ),
5176
+ ready: handle.isReady,
5177
+ available: !isDisabled
5178
+ });
5179
+ const armBrowserAttributes = gameplayActuatorAttributes({
5180
+ descriptor,
5181
+ draftDigest: interactionDraftDigestForValues(
5182
+ descriptor,
5183
+ handle.values
5184
+ ),
5185
+ intent: "arm",
5186
+ enabled: !isDisabled,
5187
+ actuatorKind: "click",
5188
+ actuatorId: "arm",
5189
+ preparationPatterns: gameplayPreparationPatternsForDescriptor(
5190
+ descriptor,
5191
+ handle.values
5192
+ )
5193
+ });
5194
+ const submitMetadata = gameplaySubmitMetadata({ descriptor });
5195
+ const submitBrowserAttributes = gameplayActuatorAttributes({
5196
+ descriptor,
5197
+ draftDigest: interactionDraftDigestForValues(
5198
+ descriptor,
5199
+ handle.values
5200
+ ),
5201
+ intent: submitMetadata.intent,
5202
+ enabled: !isDisabled && handle.isReady,
5203
+ actuatorKind: "click",
5204
+ actuatorId: "submit",
5205
+ semanticEffects: submitMetadata.semanticEffects
5206
+ });
5207
+ useEffect6(() => {
5208
+ setAccordionOpen(defaultOpen);
5209
+ }, [defaultOpen, descriptor.interactionId]);
5210
+ const containerStyle = {
5211
+ ...surfaceStyle(theme, { tone: "card" }),
5212
+ display: "flex",
5213
+ flexDirection: "column",
5214
+ gap: theme.space[2],
5215
+ padding: theme.space[3],
5216
+ minWidth: "min(100%, 280px)",
5217
+ boxSizing: "border-box",
5218
+ fontFamily: theme.typography.fontFamily.body,
5219
+ ...style
5220
+ };
5221
+ const submit = async (event) => {
5222
+ event.preventDefault();
5223
+ if (isDisabled) return;
5224
+ const nextValidation = handle.validateDraft();
5225
+ setValidation(nextValidation);
5226
+ setFormError(null);
5227
+ if (!nextValidation.ok) {
5228
+ setAccordionOpen(true);
5229
+ return;
5230
+ }
5231
+ setPending(true);
5232
+ try {
5233
+ await handle.submitDraft();
5234
+ onSubmitSuccess?.();
5235
+ setAccordionOpen(defaultOpen);
5236
+ } catch (error) {
5237
+ setAccordionOpen(true);
5238
+ setFormError(
5239
+ error instanceof Error ? error.message : "Interaction submission failed"
5240
+ );
5241
+ } finally {
5242
+ setPending(false);
5243
+ }
5244
+ };
5245
+ const header = /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: 2 }, children: [
5246
+ /* @__PURE__ */ jsx13(
5247
+ "strong",
5248
+ {
5249
+ style: {
5250
+ fontFamily: theme.typography.fontFamily.display,
5251
+ fontSize: theme.typography.fontSize.md,
5252
+ color: theme.semantic.text.primary
5253
+ },
5254
+ children: title ?? fallbackLabel
5255
+ }
5256
+ ),
5257
+ description ? /* @__PURE__ */ jsx13(
5258
+ "span",
5259
+ {
5260
+ style: {
5261
+ fontSize: theme.typography.fontSize.sm,
5262
+ color: theme.semantic.text.muted
5263
+ },
5264
+ children: description
5265
+ }
5266
+ ) : null
5267
+ ] });
5268
+ const fieldsContent = visibleInputs.length > 0 ? /* @__PURE__ */ jsx13(
5269
+ "div",
5270
+ {
5271
+ style: {
5272
+ display: "flex",
5273
+ flexDirection: "column",
5274
+ gap: theme.space[3]
5275
+ },
5276
+ children: visibleInputs.map((input) => {
5277
+ const key = input.key;
5278
+ const inputRenderer = inputs?.[key];
5279
+ return /* @__PURE__ */ jsx13(
5280
+ InteractionField,
5281
+ {
5282
+ descriptor,
5283
+ inputKey: key,
5284
+ handle,
5285
+ errors: fieldErrors[key] ?? [],
5286
+ missing: missing.has(key),
5287
+ disabled: isDisabled,
5288
+ render: inputRenderer ? ({ input: input2, errors, missing: missing2, disabled: disabled2 }) => inputRenderer(
5289
+ createInteractionInputSlot({
5290
+ descriptor,
5291
+ input: input2,
5292
+ handle,
5293
+ errors,
5294
+ missing: missing2,
5295
+ disabled: disabled2
5296
+ })
5297
+ ) : renderFields?.[key]
5298
+ },
5299
+ input.key
5300
+ );
5301
+ })
5302
+ }
5303
+ ) : null;
5304
+ if (visibleInputs.length === 0 && !handle.isReady) {
5305
+ throw new Error(
5306
+ `InteractionForm '${descriptor.interactionKey}' has required inputs that cannot be rendered by the default form. Provide renderFields, select on a surface, or use a default-renderable input domain.`
5307
+ );
5308
+ }
5309
+ const formErrorContent = formErrors.length > 0 ? /* @__PURE__ */ jsx13(
5310
+ "div",
5311
+ {
5312
+ role: "alert",
5313
+ style: {
5314
+ display: "flex",
5315
+ flexDirection: "column",
5316
+ gap: theme.space[1],
5317
+ color: theme.semantic.intent.danger.solid,
5318
+ fontSize: theme.typography.fontSize.sm
5319
+ },
5320
+ children: formErrors.map((error) => /* @__PURE__ */ jsx13("span", { children: error }, error))
5321
+ }
5322
+ ) : null;
5323
+ const actions = /* @__PURE__ */ jsxs4(
5324
+ "div",
5325
+ {
5326
+ style: {
5327
+ display: "flex",
5328
+ gap: theme.space[2],
5329
+ justifyContent: "flex-end"
5330
+ },
5331
+ children: [
5332
+ onCancel ? /* @__PURE__ */ jsx13(
5333
+ ThemedButton,
5334
+ {
5335
+ type: "button",
5336
+ variant: "secondary",
5337
+ size: "sm",
5338
+ disabled: pending,
5339
+ onClick: onCancel,
5340
+ className: "h-9 px-3 text-sm",
5341
+ children: cancelLabel
5342
+ }
5343
+ ) : null,
5344
+ renderSubmit ? renderSubmit(
5345
+ {
5346
+ Button: ({ children, ...buttonProps }) => /* @__PURE__ */ jsx13(
5347
+ ThemedButton,
5348
+ {
5349
+ type: "submit",
5350
+ variant: "primary",
5351
+ size: "sm",
5352
+ disabled: isDisabled,
5353
+ className: "h-9 px-3 text-sm",
5354
+ ...submitBrowserAttributes,
5355
+ ...buttonProps,
5356
+ children: pending ? "Submitting..." : children ?? submitLabel ?? fallbackLabel
5357
+ }
5358
+ )
5359
+ },
5360
+ descriptor
5361
+ ) : /* @__PURE__ */ jsx13(
5362
+ ThemedButton,
5363
+ {
5364
+ type: "submit",
5365
+ variant: "primary",
5366
+ size: "sm",
5367
+ disabled: isDisabled,
5368
+ className: "h-9 px-3 text-sm",
5369
+ ...submitBrowserAttributes,
5370
+ children: pending ? "Submitting..." : submitLabel ?? fallbackLabel
5371
+ }
5372
+ )
5373
+ ]
5374
+ }
5375
+ );
5376
+ const body = /* @__PURE__ */ jsxs4(Fragment9, { children: [
5377
+ fieldsContent,
5378
+ formErrorContent,
5379
+ actions
5380
+ ] });
5381
+ return /* @__PURE__ */ jsx13(
5382
+ "form",
5383
+ {
5384
+ "data-interaction-form": true,
5385
+ "data-interaction-id": descriptor.interactionId,
5386
+ onSubmit: (event) => void submit(event),
5387
+ style: containerStyle,
5388
+ ...rootBrowserAttributes,
5389
+ children: useAccordion ? /* @__PURE__ */ jsx13(
5390
+ AccordionPrimitive.Root,
5391
+ {
5392
+ type: "single",
5393
+ collapsible: true,
5394
+ value: accordionOpen ? "fields" : void 0,
5395
+ onValueChange: (value) => setAccordionOpen(value === "fields"),
5396
+ children: /* @__PURE__ */ jsxs4(AccordionPrimitive.Item, { value: "fields", children: [
5397
+ /* @__PURE__ */ jsx13(AccordionPrimitive.Header, { style: { margin: 0 }, children: /* @__PURE__ */ jsxs4(
5398
+ AccordionPrimitive.Trigger,
5399
+ {
5400
+ ...armBrowserAttributes,
5401
+ style: {
5402
+ alignItems: "center",
5403
+ appearance: "none",
5404
+ background: "transparent",
5405
+ border: 0,
5406
+ color: theme.semantic.text.primary,
5407
+ cursor: "pointer",
5408
+ display: "flex",
5409
+ fontFamily: theme.typography.fontFamily.display,
5410
+ fontSize: theme.typography.fontSize.md,
5411
+ fontWeight: theme.typography.fontWeight.bold,
5412
+ justifyContent: "space-between",
5413
+ padding: 0,
5414
+ textAlign: "left",
5415
+ width: "100%"
5416
+ },
5417
+ children: [
5418
+ /* @__PURE__ */ jsx13("span", { children: title ?? fallbackLabel }),
5419
+ /* @__PURE__ */ jsx13("span", { "aria-hidden": true, children: accordionOpen ? "\u2212" : "+" })
5420
+ ]
5421
+ }
5422
+ ) }),
5423
+ /* @__PURE__ */ jsx13(AccordionPrimitive.Content, { children: /* @__PURE__ */ jsxs4(
5424
+ "div",
5425
+ {
5426
+ style: {
5427
+ display: "flex",
5428
+ flexDirection: "column",
5429
+ gap: theme.space[2],
5430
+ marginTop: theme.space[2]
5431
+ },
5432
+ children: [
5433
+ description ? /* @__PURE__ */ jsx13(
5434
+ "span",
5435
+ {
5436
+ style: {
5437
+ fontSize: theme.typography.fontSize.sm,
5438
+ color: theme.semantic.text.muted
5439
+ },
5440
+ children: description
5441
+ }
5442
+ ) : null,
5443
+ body
5444
+ ]
5445
+ }
5446
+ ) })
5447
+ ] })
5325
5448
  }
5326
- )
5327
- }
5328
- );
5329
- }
5330
- function TargetSummaryField({
5331
- input,
5332
- value,
5333
- errors,
5334
- missing,
5335
- domain
5336
- }) {
5337
- const target = inputTargetKind(domain) ?? "target";
5338
- return /* @__PURE__ */ jsx11(FieldFrame, { label: labelForInput(input), errors, missing, children: /* @__PURE__ */ jsx11("span", { children: Array.isArray(value) ? value.length > 0 ? `${value.length} selected: ${value.join(", ")}` : `Select ${targetSelectionLabel(domain)}.` : typeof value === "string" ? value : `Select a ${target} on the board.` }) });
5339
- }
5340
- function targetSelectionLabel(domain) {
5341
- const target = inputTargetKind(domain) ?? "target";
5342
- const selection = isTargetDomain(domain) ? domain.selection : void 0;
5343
- if (selection?.mode !== "many") return `a ${target}`;
5344
- const min = selection.min ?? 0;
5345
- if (selection.max !== void 0 && min === selection.max) {
5346
- return `${min} ${target}${min === 1 ? "" : "s"}`;
5347
- }
5348
- return `${min}${selection.max ? `-${selection.max}` : "+"} ${target}s`;
5349
- }
5350
- function StepperButton({
5351
- label,
5352
- disabled,
5353
- browserAttributes,
5354
- onClick,
5355
- children
5356
- }) {
5357
- return /* @__PURE__ */ jsx11(
5358
- ThemedButton,
5359
- {
5360
- type: "button",
5361
- variant: "secondary",
5362
- size: "sm",
5363
- "aria-label": label,
5364
- disabled,
5365
- ...browserAttributes,
5366
- onClick,
5367
- className: "h-8 w-8 text-sm",
5368
- children
5449
+ ) : /* @__PURE__ */ jsxs4(Fragment9, { children: [
5450
+ header,
5451
+ body
5452
+ ] })
5369
5453
  }
5370
5454
  );
5371
5455
  }
5372
- function labelForInput(input) {
5373
- if (input.domain.type === "choice") {
5374
- const exact = input.domain.choices?.find(
5375
- (choice) => choice.value === input.defaultValue
5376
- );
5377
- if (exact?.label && input.key === exact.value) return exact.label;
5378
- }
5379
- return humanize(input.key);
5380
- }
5381
- function humanize(key) {
5382
- return key.replace(/Id$/, "").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[-_]+/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
5383
- }
5384
- function isRecord2(value) {
5385
- return typeof value === "object" && value !== null && !Array.isArray(value);
5386
- }
5387
- function numberOrZero(value) {
5388
- return typeof value === "number" && Number.isFinite(value) ? value : 0;
5389
- }
5390
5456
 
5391
- // src/runtime-internal/primitives/interaction-form-binding.tsx
5392
- import { jsx as jsx12 } from "react/jsx-runtime";
5457
+ // src/runtime/primitives/interaction/form.tsx
5458
+ import { jsx as jsx14 } from "react/jsx-runtime";
5393
5459
  function castInteractionHandle(handle) {
5394
5460
  return handle;
5395
5461
  }
@@ -5401,7 +5467,7 @@ function BoundInteractionForm({
5401
5467
  handle,
5402
5468
  ...props
5403
5469
  }) {
5404
- return /* @__PURE__ */ jsx12(
5470
+ return /* @__PURE__ */ jsx14(
5405
5471
  InteractionForm,
5406
5472
  {
5407
5473
  descriptor,
@@ -5410,194 +5476,66 @@ function BoundInteractionForm({
5410
5476
  }
5411
5477
  );
5412
5478
  }
5413
-
5414
- // src/runtime-internal/primitives/dialog-lifecycle.ts
5415
- import { useCallback as useCallback5, useMemo as useMemo12, useState as useState5 } from "react";
5416
- function useDialogLifecycle({
5417
- defaultOpen = true,
5418
- onStateChange
5419
- }) {
5420
- const [state, setState] = useState5(
5421
- defaultOpen ? "open" : "minimized"
5422
- );
5423
- const updateState = useCallback5(
5424
- (nextState) => {
5425
- setState(nextState);
5426
- onStateChange?.(nextState);
5427
- },
5428
- [onStateChange]
5429
- );
5430
- const restore = useCallback5(() => updateState("open"), [updateState]);
5431
- const minimize = useCallback5(() => updateState("minimized"), [updateState]);
5432
- const dismiss = useCallback5(() => updateState("dismissed"), [updateState]);
5433
- const setOpen = useCallback5(
5434
- (open) => {
5435
- updateState(open ? "open" : "minimized");
5436
- },
5437
- [updateState]
5438
- );
5439
- return useMemo12(
5440
- () => ({
5441
- state,
5442
- open: state === "open",
5443
- minimized: state === "minimized",
5444
- dismissed: state === "dismissed",
5445
- setOpen,
5446
- restore,
5447
- minimize,
5448
- dismiss
5449
- }),
5450
- [dismiss, minimize, restore, setOpen, state]
5451
- );
5452
- }
5453
-
5454
- // src/runtime-internal/primitives/interaction.tsx
5455
- import { Fragment as Fragment8, jsx as jsx13 } from "react/jsx-runtime";
5456
- var InteractionContext = createContext9(null);
5457
- function humanizeInteraction(value) {
5458
- const parts = value.split(".");
5459
- const leaf = parts[parts.length - 1] ?? value;
5460
- return leaf.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[-_]+/g, " ").replace(/\s+/g, " ").trim().replace(/^./, (first) => first.toUpperCase());
5461
- }
5462
- var GAMEPLAY_BROWSER_SCOPE_ID5 = "runtime";
5463
- function gameplayActuatorAttributes2({
5464
- descriptor,
5465
- inputKey,
5466
- intent,
5467
- candidateValue,
5468
- candidateState,
5469
- semanticEffects,
5470
- acceptedEffectPatterns,
5471
- preparationPatterns,
5472
- enabled,
5473
- actuatorKind,
5474
- actuatorId
5475
- }) {
5476
- return createGameplayActuatorAttributes({
5477
- scopeId: GAMEPLAY_BROWSER_SCOPE_ID5,
5478
- interactionKey: descriptor.interactionKey,
5479
- interactionId: descriptor.interactionId,
5480
- intent,
5481
- enabled,
5482
- actuatorKind,
5483
- actuatorId,
5484
- ...descriptor.descriptorDigest !== void 0 ? { descriptorDigest: descriptor.descriptorDigest } : {},
5485
- ...descriptor.draftDigest !== void 0 ? { draftDigest: descriptor.draftDigest } : {},
5486
- ...inputKey !== void 0 ? { inputKey } : {},
5487
- ...candidateValue !== void 0 ? { candidateValue } : {},
5488
- ...candidateState !== void 0 ? { candidateState } : {},
5489
- ...semanticEffects !== void 0 ? { semanticEffects } : {},
5490
- ...acceptedEffectPatterns !== void 0 ? { acceptedEffectPatterns } : {},
5491
- ...preparationPatterns !== void 0 ? { preparationPatterns } : {}
5492
- });
5493
- }
5494
- function useInteractionPrimitiveContext() {
5495
- const value = useContext9(InteractionContext);
5496
- if (!value) {
5497
- throw new Error(
5498
- "Interaction primitives must be rendered inside <Interaction.Root>."
5499
- );
5500
- }
5501
- return value;
5502
- }
5503
- function useResolvedCardTargetValue() {
5504
- const context = useContext9(InteractionContext);
5505
- const descriptor = context?.descriptor;
5506
- const handle = context?.handle;
5507
- if (!descriptor || !handle) return void 0;
5508
- const cardInput = descriptor.inputs.find(
5509
- (input) => isTargetDomain(input.domain) && input.domain.type === "cardTarget"
5510
- );
5511
- if (!cardInput) return void 0;
5512
- return handle.values[cardInput.key];
5513
- }
5514
- function useInteractionDescriptor(interaction) {
5515
- return usePluginState(
5516
- (state) => state.gameplay.availableInteractions.find(
5517
- (descriptor) => descriptor.interactionKey === interaction || descriptor.interactionId === interaction
5518
- )
5519
- );
5520
- }
5521
- function ResolvedInteractionRoot({
5522
- interaction,
5523
- descriptor,
5524
- children
5525
- }) {
5526
- const handle = useInteractionHandle(descriptor);
5527
- const value = useMemo13(
5528
- () => ({ interaction, descriptor, handle }),
5529
- [descriptor, handle, interaction]
5479
+ function InteractionFormPrimitive(props) {
5480
+ const { descriptor, handle } = useInteractionPrimitiveContext();
5481
+ if (!descriptor || !handle) return null;
5482
+ return /* @__PURE__ */ jsx14(
5483
+ BoundInteractionForm,
5484
+ {
5485
+ descriptor,
5486
+ handle,
5487
+ ...props
5488
+ }
5530
5489
  );
5531
- const available = isInteractionAvailable(descriptor);
5532
- const rootAttributes = createGameplayInteractionRootAttributes({
5533
- scopeId: GAMEPLAY_BROWSER_SCOPE_ID5,
5534
- interactionKey: descriptor.interactionKey,
5535
- interactionId: descriptor.interactionId,
5536
- ...descriptor.descriptorDigest !== void 0 ? { descriptorDigest: descriptor.descriptorDigest } : {},
5537
- ...descriptor.draftDigest !== void 0 ? { draftDigest: descriptor.draftDigest } : {},
5538
- readiness: available ? handle.isReady ? "ready" : "blocked" : "unavailable"
5539
- });
5540
- return /* @__PURE__ */ jsx13(InteractionContext.Provider, { value, children: renderPrimitive("span", {
5541
- ...rootAttributes,
5542
- style: { display: "contents" },
5543
- children
5544
- }) });
5545
- }
5546
- function InteractionRoot({
5547
- interaction,
5548
- children,
5549
- unavailable = "render"
5550
- }) {
5551
- const descriptor = useInteractionDescriptor(interaction);
5552
- if (!descriptor) {
5553
- if (unavailable === "hide") return null;
5554
- return /* @__PURE__ */ jsx13(
5555
- InteractionContext.Provider,
5556
- {
5557
- value: {
5558
- interaction,
5559
- descriptor: null,
5560
- handle: null
5561
- },
5562
- children
5563
- }
5564
- );
5565
- }
5566
- if (!isInteractionAvailable(descriptor) && unavailable === "hide") {
5567
- return null;
5568
- }
5569
- return /* @__PURE__ */ jsx13(ResolvedInteractionRoot, { interaction, descriptor, children });
5570
5490
  }
5571
- function InteractionDialog({
5572
- defaultOpen = false,
5573
- onStateChange,
5574
- children
5575
- }) {
5576
- const { interaction } = useInteractionPrimitiveContext();
5577
- const pendingInteractionKey = usePendingInteractionKey();
5578
- const pendingInteractionRevision = usePendingInteractionRevision();
5579
- const lifecycle = useDialogLifecycle({ defaultOpen, onStateChange });
5580
- const restoredRevisionRef = useRef4(null);
5581
- useEffect7(() => {
5582
- if (pendingInteractionKey === interaction && restoredRevisionRef.current !== pendingInteractionRevision) {
5583
- restoredRevisionRef.current = pendingInteractionRevision;
5584
- lifecycle.restore();
5585
- }
5586
- }, [
5587
- interaction,
5588
- lifecycle,
5589
- pendingInteractionKey,
5590
- pendingInteractionRevision
5591
- ]);
5592
- const renderState = useMemo13(
5593
- () => ({
5594
- interaction,
5595
- ...lifecycle
5596
- }),
5597
- [interaction, lifecycle]
5491
+ function InteractionFieldPrimitive({ input, ...props }) {
5492
+ const { descriptor, handle } = useInteractionPrimitiveContext();
5493
+ if (!descriptor || !handle) return null;
5494
+ return /* @__PURE__ */ jsx14(
5495
+ InteractionField,
5496
+ {
5497
+ descriptor,
5498
+ handle: castInteractionHandle(handle),
5499
+ inputKey: input,
5500
+ ...props
5501
+ }
5502
+ );
5503
+ }
5504
+
5505
+ // src/runtime/primitives/interaction/state.tsx
5506
+ import { Fragment as Fragment10, jsx as jsx15 } from "react/jsx-runtime";
5507
+ function InteractionState({ children, unavailable }) {
5508
+ const { interaction, descriptor, handle } = useInteractionPrimitiveContext();
5509
+ const store = useInteractionUiStore();
5510
+ if (!descriptor || !handle) {
5511
+ return /* @__PURE__ */ jsx15(Fragment10, { children: unavailable });
5512
+ }
5513
+ const typedHandle = castInteractionHandle(handle);
5514
+ const liveDraft = castInteractionDraft(
5515
+ store.getDraft(descriptor.interactionKey)
5598
5516
  );
5599
- return /* @__PURE__ */ jsx13(Fragment8, { children: children(renderState) });
5517
+ const inputKeys = descriptor.inputs.map((input) => input.key);
5518
+ const readiness = getInteractionDraftReadiness(descriptor, liveDraft);
5519
+ return /* @__PURE__ */ jsx15(Fragment10, { children: children({
5520
+ interaction,
5521
+ descriptor,
5522
+ handle: typedHandle,
5523
+ draft: liveDraft,
5524
+ values: typedHandle.values,
5525
+ status: typedHandle.status,
5526
+ available: typedHandle.available,
5527
+ isReady: readiness.ready,
5528
+ isArmed: typedHandle.isArmed,
5529
+ inputKeys,
5530
+ missingInputs: readiness.missingInputs,
5531
+ readyFrontier: readiness.readyFrontier,
5532
+ blockedInputs: readiness.blockedInputs,
5533
+ hasInputs: inputKeys.length > 0
5534
+ }) });
5600
5535
  }
5536
+
5537
+ // src/runtime/primitives/interaction/routes.tsx
5538
+ import { Fragment as Fragment11, jsx as jsx16 } from "react/jsx-runtime";
5601
5539
  function InteractionSwitch({
5602
5540
  interaction,
5603
5541
  routes,
@@ -5611,11 +5549,11 @@ function InteractionSwitch({
5611
5549
  const descriptor = routedInteraction ? descriptors.find(
5612
5550
  (candidate) => candidate.interactionKey === routedInteraction
5613
5551
  ) : void 0;
5614
- if (!descriptor) return /* @__PURE__ */ jsx13(Fragment8, { children: fallback });
5552
+ if (!descriptor) return /* @__PURE__ */ jsx16(Fragment11, { children: fallback });
5615
5553
  const route = routes[descriptor.interactionKey] ?? null;
5616
- if (!route) return /* @__PURE__ */ jsx13(Fragment8, { children: fallback });
5554
+ if (!route) return /* @__PURE__ */ jsx16(Fragment11, { children: fallback });
5617
5555
  const typedInteraction = descriptor.interactionKey;
5618
- return /* @__PURE__ */ jsx13(InteractionRoot, { interaction: typedInteraction, children: route({
5556
+ return /* @__PURE__ */ jsx16(InteractionRoot, { interaction: typedInteraction, children: route({
5619
5557
  interaction: typedInteraction,
5620
5558
  descriptor
5621
5559
  }) });
@@ -5634,7 +5572,7 @@ function InteractionRoutes({
5634
5572
  const descriptors = usePluginState(
5635
5573
  (state) => state.gameplay.availableInteractions
5636
5574
  );
5637
- if (descriptors.length === 0) return /* @__PURE__ */ jsx13(Fragment8, { children: fallback });
5575
+ if (descriptors.length === 0) return /* @__PURE__ */ jsx16(Fragment11, { children: fallback });
5638
5576
  const routedDescriptors = descriptors.filter(
5639
5577
  (descriptor) => includeUnavailable || isInteractionAvailable(descriptor)
5640
5578
  ).map((descriptor) => {
@@ -5656,56 +5594,87 @@ function InteractionRoutes({
5656
5594
  }
5657
5595
  return descriptor;
5658
5596
  });
5659
- if (routedDescriptors.length === 0) return /* @__PURE__ */ jsx13(Fragment8, { children: fallback });
5597
+ if (routedDescriptors.length === 0) return /* @__PURE__ */ jsx16(Fragment11, { children: fallback });
5660
5598
  return null;
5661
5599
  }
5662
- function InteractionLabel({ children, ...props }) {
5663
- const { descriptor, interaction } = useInteractionPrimitiveContext();
5664
- return renderPrimitive("span", {
5665
- ...props,
5666
- "data-dreamboard-interaction-label": "",
5667
- children: children ?? (descriptor ? interactionLabel(descriptor) : humanizeInteraction(interaction))
5668
- });
5669
- }
5670
- function InteractionDescription({
5671
- children,
5672
- ...props
5673
- }) {
5674
- const content = children;
5675
- if (!content) return null;
5676
- return renderPrimitive("span", {
5677
- ...props,
5678
- "data-dreamboard-interaction-description": "",
5679
- children: content
5680
- });
5681
- }
5682
- function InteractionUnavailableMessage({
5683
- children,
5684
- ...props
5600
+
5601
+ // src/runtime/primitives/interaction/dialog.tsx
5602
+ import { useEffect as useEffect7, useMemo as useMemo14, useRef as useRef4 } from "react";
5603
+
5604
+ // src/ui/primitives/dialog-lifecycle.ts
5605
+ import { useCallback as useCallback5, useMemo as useMemo13, useState as useState5 } from "react";
5606
+ function useDialogLifecycle({
5607
+ defaultOpen = true,
5608
+ onStateChange
5685
5609
  }) {
5686
- const { descriptor, handle } = useInteractionPrimitiveContext();
5687
- const reason = children ?? handle?.unavailableReason ?? interactionUnavailableReason(descriptor);
5688
- if (!reason) return null;
5689
- return renderPrimitive("span", {
5690
- ...props,
5691
- "data-dreamboard-interaction-unavailable": "",
5692
- children: reason
5693
- });
5610
+ const [state, setState] = useState5(
5611
+ defaultOpen ? "open" : "minimized"
5612
+ );
5613
+ const updateState = useCallback5(
5614
+ (nextState) => {
5615
+ setState(nextState);
5616
+ onStateChange?.(nextState);
5617
+ },
5618
+ [onStateChange]
5619
+ );
5620
+ const restore = useCallback5(() => updateState("open"), [updateState]);
5621
+ const minimize = useCallback5(() => updateState("minimized"), [updateState]);
5622
+ const dismiss = useCallback5(() => updateState("dismissed"), [updateState]);
5623
+ const setOpen = useCallback5(
5624
+ (open) => {
5625
+ updateState(open ? "open" : "minimized");
5626
+ },
5627
+ [updateState]
5628
+ );
5629
+ return useMemo13(
5630
+ () => ({
5631
+ state,
5632
+ open: state === "open",
5633
+ minimized: state === "minimized",
5634
+ dismissed: state === "dismissed",
5635
+ setOpen,
5636
+ restore,
5637
+ minimize,
5638
+ dismiss
5639
+ }),
5640
+ [dismiss, minimize, restore, setOpen, state]
5641
+ );
5694
5642
  }
5695
- function InteractionValidationMessage({
5696
- children,
5697
- ...props
5643
+
5644
+ // src/runtime/primitives/interaction/dialog.tsx
5645
+ import { Fragment as Fragment12, jsx as jsx17 } from "react/jsx-runtime";
5646
+ function InteractionDialog({
5647
+ defaultOpen = false,
5648
+ onStateChange,
5649
+ children
5698
5650
  }) {
5699
- const { handle } = useInteractionPrimitiveContext();
5700
- const validation = handle?.validateDraft();
5701
- const message = children ?? validation?.formErrors[0] ?? Object.values(validation?.fieldErrors ?? {})[0]?.[0] ?? (validation?.missing[0] ? `${String(validation.missing[0])} is required.` : null);
5702
- if (!message) return null;
5703
- return renderPrimitive("span", {
5704
- ...props,
5705
- "data-dreamboard-interaction-validation": "",
5706
- children: message
5707
- });
5651
+ const { interaction } = useInteractionPrimitiveContext();
5652
+ const pendingInteractionKey = usePendingInteractionKey();
5653
+ const pendingInteractionRevision = usePendingInteractionRevision();
5654
+ const lifecycle = useDialogLifecycle({ defaultOpen, onStateChange });
5655
+ const restoredRevisionRef = useRef4(null);
5656
+ useEffect7(() => {
5657
+ if (pendingInteractionKey === interaction && restoredRevisionRef.current !== pendingInteractionRevision) {
5658
+ restoredRevisionRef.current = pendingInteractionRevision;
5659
+ lifecycle.restore();
5660
+ }
5661
+ }, [
5662
+ interaction,
5663
+ lifecycle,
5664
+ pendingInteractionKey,
5665
+ pendingInteractionRevision
5666
+ ]);
5667
+ const renderState = useMemo14(
5668
+ () => ({
5669
+ interaction,
5670
+ ...lifecycle
5671
+ }),
5672
+ [interaction, lifecycle]
5673
+ );
5674
+ return /* @__PURE__ */ jsx17(Fragment12, { children: children(renderState) });
5708
5675
  }
5676
+
5677
+ // src/runtime/primitives/interaction/controls.tsx
5709
5678
  function InteractionTrigger({
5710
5679
  disabled,
5711
5680
  onClick,
@@ -5717,8 +5686,9 @@ function InteractionTrigger({
5717
5686
  return renderPrimitive("button", {
5718
5687
  type: "button",
5719
5688
  ...props,
5720
- ...descriptor ? gameplayActuatorAttributes2({
5689
+ ...descriptor ? gameplayActuatorAttributes({
5721
5690
  descriptor,
5691
+ draftDigest: descriptor.draftDigest,
5722
5692
  intent: "arm",
5723
5693
  enabled: !isDisabled,
5724
5694
  actuatorKind: "click",
@@ -5741,60 +5711,6 @@ function InteractionTrigger({
5741
5711
  })
5742
5712
  });
5743
5713
  }
5744
- function InteractionState({ children, unavailable }) {
5745
- const { interaction, descriptor, handle } = useInteractionPrimitiveContext();
5746
- const store = useInteractionUiStore();
5747
- if (!descriptor || !handle) {
5748
- return /* @__PURE__ */ jsx13(Fragment8, { children: unavailable });
5749
- }
5750
- const typedHandle = castInteractionHandle(handle);
5751
- const liveDraft = castInteractionDraft(
5752
- store.getDraft(descriptor.interactionKey)
5753
- );
5754
- const inputKeys = descriptor.inputs.map((input) => input.key);
5755
- const readiness = getInteractionDraftReadiness(descriptor, liveDraft);
5756
- return /* @__PURE__ */ jsx13(Fragment8, { children: children({
5757
- interaction,
5758
- descriptor,
5759
- handle: typedHandle,
5760
- draft: liveDraft,
5761
- values: typedHandle.values,
5762
- status: typedHandle.status,
5763
- available: typedHandle.available,
5764
- isReady: readiness.ready,
5765
- isArmed: typedHandle.isArmed,
5766
- inputKeys,
5767
- missingInputs: readiness.missingInputs,
5768
- readyFrontier: readiness.readyFrontier,
5769
- blockedInputs: readiness.blockedInputs,
5770
- hasInputs: inputKeys.length > 0
5771
- }) });
5772
- }
5773
- function InteractionFormPrimitive(props) {
5774
- const { descriptor, handle } = useInteractionPrimitiveContext();
5775
- if (!descriptor || !handle) return null;
5776
- return /* @__PURE__ */ jsx13(
5777
- BoundInteractionForm,
5778
- {
5779
- descriptor,
5780
- handle,
5781
- ...props
5782
- }
5783
- );
5784
- }
5785
- function InteractionFieldPrimitive({ input, ...props }) {
5786
- const { descriptor, handle } = useInteractionPrimitiveContext();
5787
- if (!descriptor || !handle) return null;
5788
- return /* @__PURE__ */ jsx13(
5789
- InteractionField,
5790
- {
5791
- descriptor,
5792
- handle: castInteractionHandle(handle),
5793
- inputKey: input,
5794
- ...props
5795
- }
5796
- );
5797
- }
5798
5714
  function InteractionSubmit({
5799
5715
  disabled,
5800
5716
  onClick,
@@ -5813,8 +5729,9 @@ function InteractionSubmit({
5813
5729
  return renderPrimitive("button", {
5814
5730
  type: "button",
5815
5731
  ...props,
5816
- ...descriptor ? gameplayActuatorAttributes2({
5732
+ ...descriptor ? gameplayActuatorAttributes({
5817
5733
  descriptor,
5734
+ draftDigest: descriptor.draftDigest,
5818
5735
  intent: submitMetadata?.intent ?? "submit",
5819
5736
  enabled: !isDisabled,
5820
5737
  actuatorKind: "click",
@@ -5872,8 +5789,9 @@ function InteractionInput({
5872
5789
  return renderPrimitive("input", {
5873
5790
  ...props,
5874
5791
  name,
5875
- ...descriptor ? gameplayActuatorAttributes2({
5792
+ ...descriptor ? gameplayActuatorAttributes({
5876
5793
  descriptor,
5794
+ draftDigest: descriptor.draftDigest,
5877
5795
  inputKey: name,
5878
5796
  intent: "fill",
5879
5797
  enabled: !isDisabled,
@@ -5893,6 +5811,60 @@ function InteractionInput({
5893
5811
  })
5894
5812
  });
5895
5813
  }
5814
+
5815
+ // src/runtime/primitives/interaction/parts.tsx
5816
+ function InteractionLabel({ children, ...props }) {
5817
+ const { descriptor, interaction } = useInteractionPrimitiveContext();
5818
+ return renderPrimitive("span", {
5819
+ ...props,
5820
+ "data-dreamboard-interaction-label": "",
5821
+ children: children ?? (descriptor ? interactionLabel(descriptor) : humanizeInteraction(interaction))
5822
+ });
5823
+ }
5824
+ function InteractionDescription({
5825
+ children,
5826
+ ...props
5827
+ }) {
5828
+ const content = children;
5829
+ if (!content) return null;
5830
+ return renderPrimitive("span", {
5831
+ ...props,
5832
+ "data-dreamboard-interaction-description": "",
5833
+ children: content
5834
+ });
5835
+ }
5836
+ function InteractionUnavailableMessage({
5837
+ children,
5838
+ ...props
5839
+ }) {
5840
+ const { descriptor, handle } = useInteractionPrimitiveContext();
5841
+ const reason = children ?? handle?.unavailableReason ?? interactionUnavailableReason(descriptor);
5842
+ if (!reason) return null;
5843
+ return renderPrimitive("span", {
5844
+ ...props,
5845
+ "data-dreamboard-interaction-unavailable": "",
5846
+ children: reason
5847
+ });
5848
+ }
5849
+ function InteractionValidationMessage({
5850
+ children,
5851
+ ...props
5852
+ }) {
5853
+ const { handle } = useInteractionPrimitiveContext();
5854
+ const validation = handle?.validateDraft();
5855
+ const message = children ?? validation?.formErrors[0] ?? Object.values(validation?.fieldErrors ?? {})[0]?.[0] ?? (validation?.missing[0] ? `${String(validation.missing[0])} is required.` : null);
5856
+ if (!message) return null;
5857
+ return renderPrimitive("span", {
5858
+ ...props,
5859
+ "data-dreamboard-interaction-validation": "",
5860
+ children: message
5861
+ });
5862
+ }
5863
+
5864
+ // src/runtime/primitives/interaction/card-input.tsx
5865
+ import {
5866
+ useCallback as useCallback6
5867
+ } from "react";
5896
5868
  function InteractionCardInput({
5897
5869
  input,
5898
5870
  unsafeCardId,
@@ -6003,8 +5975,9 @@ function InteractionCardInput({
6003
5975
  type: "button",
6004
5976
  ...props,
6005
5977
  children: renderedChildren,
6006
- ...descriptor ? gameplayActuatorAttributes2({
5978
+ ...descriptor ? gameplayActuatorAttributes({
6007
5979
  descriptor,
5980
+ draftDigest: descriptor.draftDigest,
6008
5981
  inputKey: input,
6009
5982
  intent: selection?.mode === "many" ? "toggle" : "select",
6010
5983
  candidateValue: cardId,
@@ -6095,6 +6068,8 @@ function isDevelopmentRuntime() {
6095
6068
  const processLike = globalThis.process;
6096
6069
  return processLike?.env?.NODE_ENV !== "production";
6097
6070
  }
6071
+
6072
+ // src/runtime/primitives/interaction/index.ts
6098
6073
  var Interaction = {
6099
6074
  Root: InteractionRoot,
6100
6075
  State: InteractionState,
@@ -6113,8 +6088,8 @@ var Interaction = {
6113
6088
  Submit: InteractionSubmit
6114
6089
  };
6115
6090
 
6116
- // src/runtime-internal/primitives/phase.tsx
6117
- import { Fragment as Fragment9, jsx as jsx14 } from "react/jsx-runtime";
6091
+ // src/runtime/primitives/phase.tsx
6092
+ import { Fragment as Fragment13, jsx as jsx18 } from "react/jsx-runtime";
6118
6093
  function hasRoute(routes, phase) {
6119
6094
  return Object.prototype.hasOwnProperty.call(routes, phase);
6120
6095
  }
@@ -6127,22 +6102,22 @@ function PhaseSwitch({
6127
6102
  }) {
6128
6103
  const phase = usePluginState((state) => state.gameplay.currentPhase);
6129
6104
  if (phase && hasRoute(routes, phase)) {
6130
- return /* @__PURE__ */ jsx14(Fragment9, { children: routes[phase]() });
6105
+ return /* @__PURE__ */ jsx18(Fragment13, { children: routes[phase]() });
6131
6106
  }
6132
- return /* @__PURE__ */ jsx14(Fragment9, { children: renderFallback(fallback, phase) });
6107
+ return /* @__PURE__ */ jsx18(Fragment13, { children: renderFallback(fallback, phase) });
6133
6108
  }
6134
6109
  var Phase = {
6135
6110
  Switch: PhaseSwitch
6136
6111
  };
6137
6112
 
6138
- // src/runtime-internal/primitives/player-roster.tsx
6113
+ // src/runtime/primitives/player-roster.tsx
6139
6114
  import {
6140
6115
  createContext as createContext10,
6141
- Fragment as Fragment10,
6116
+ Fragment as Fragment14,
6142
6117
  useContext as useContext10,
6143
- useMemo as useMemo14
6118
+ useMemo as useMemo15
6144
6119
  } from "react";
6145
- import { Fragment as Fragment11, jsx as jsx15, jsxs as jsxs4 } from "react/jsx-runtime";
6120
+ import { Fragment as Fragment15, jsx as jsx19, jsxs as jsxs5 } from "react/jsx-runtime";
6146
6121
  var PlayerRosterContext = createContext10(
6147
6122
  null
6148
6123
  );
@@ -6173,7 +6148,7 @@ function PlayerRosterRoot({
6173
6148
  const activePlayers = useActivePlayers();
6174
6149
  const turnOrder = usePlayerTurnOrder();
6175
6150
  const { controllingPlayerId, controllablePlayerIds } = usePluginSession();
6176
- const players = useMemo14(() => {
6151
+ const players = useMemo15(() => {
6177
6152
  const orderedPlayerIds = order === "self-first" && controllingPlayerId ? [
6178
6153
  ...turnOrder.filter((pid) => pid === controllingPlayerId),
6179
6154
  ...turnOrder.filter((pid) => pid !== controllingPlayerId)
@@ -6215,11 +6190,11 @@ function PlayerRosterRoot({
6215
6190
  scoreLabel,
6216
6191
  turnOrder
6217
6192
  ]);
6218
- const value = useMemo14(
6193
+ const value = useMemo15(
6219
6194
  () => ({ players }),
6220
6195
  [players]
6221
6196
  );
6222
- return /* @__PURE__ */ jsx15(PlayerRosterContext.Provider, { value, children });
6197
+ return /* @__PURE__ */ jsx19(PlayerRosterContext.Provider, { value, children });
6223
6198
  }
6224
6199
  function PlayerRosterList({
6225
6200
  children,
@@ -6229,13 +6204,13 @@ function PlayerRosterList({
6229
6204
  return renderPrimitive("div", {
6230
6205
  ...props,
6231
6206
  "data-dreamboard-player-roster-list": "",
6232
- children: players.map((player) => /* @__PURE__ */ jsx15(Fragment10, { children: children ? children(player) : /* @__PURE__ */ jsx15(PlayerRosterName, { player }) }, player.playerId))
6207
+ children: players.map((player) => /* @__PURE__ */ jsx19(Fragment14, { children: children ? children(player) : /* @__PURE__ */ jsx19(PlayerRosterName, { player }) }, player.playerId))
6233
6208
  });
6234
6209
  }
6235
6210
  function PlayerRosterEmpty({ children }) {
6236
6211
  const { players } = usePlayerRosterContext();
6237
6212
  if (players.length > 0) return null;
6238
- return /* @__PURE__ */ jsx15(Fragment11, { children });
6213
+ return /* @__PURE__ */ jsx19(Fragment15, { children });
6239
6214
  }
6240
6215
  function PlayerRosterSwitchButton({
6241
6216
  player,
@@ -6296,7 +6271,7 @@ function PlayerRosterBadges({
6296
6271
  return renderPrimitive("span", {
6297
6272
  ...props,
6298
6273
  "data-dreamboard-player-roster-badges": "",
6299
- children: children ?? player.badges.map((badge) => /* @__PURE__ */ jsxs4(
6274
+ children: children ?? player.badges.map((badge) => /* @__PURE__ */ jsxs5(
6300
6275
  "span",
6301
6276
  {
6302
6277
  "data-dreamboard-player-roster-badge": "",
@@ -6321,15 +6296,15 @@ var PlayerRoster = {
6321
6296
  Badges: PlayerRosterBadges
6322
6297
  };
6323
6298
 
6324
- // src/runtime-internal/primitives/prompt.tsx
6299
+ // src/runtime/primitives/prompt.tsx
6325
6300
  import {
6326
- Fragment as Fragment12,
6301
+ Fragment as Fragment16,
6327
6302
  createContext as createContext11,
6328
6303
  useContext as useContext11,
6329
- useMemo as useMemo15
6304
+ useMemo as useMemo16
6330
6305
  } from "react";
6331
6306
 
6332
- // src/runtime-internal/hooks/useSeatInbox.ts
6307
+ // src/runtime/hooks/useSeatInbox.ts
6333
6308
  function useSeatInbox() {
6334
6309
  const interactions = usePluginState(
6335
6310
  (s) => s.gameplay.availableInteractions ?? []
@@ -6362,22 +6337,22 @@ function bucketForDescriptor(descriptor) {
6362
6337
  return "panel";
6363
6338
  }
6364
6339
 
6365
- // src/runtime-internal/primitives/prompt.tsx
6366
- import { Fragment as Fragment13, jsx as jsx16 } from "react/jsx-runtime";
6340
+ // src/runtime/primitives/prompt.tsx
6341
+ import { Fragment as Fragment17, jsx as jsx20 } from "react/jsx-runtime";
6367
6342
  function PromptRoot(props) {
6368
- return /* @__PURE__ */ jsx16(InteractionRoot, { ...props });
6343
+ return /* @__PURE__ */ jsx20(InteractionRoot, { ...props });
6369
6344
  }
6370
6345
  function PromptTitle(props) {
6371
6346
  const { descriptor } = useInteractionPrimitiveContext();
6372
6347
  const context = descriptor?.kind === "prompt" ? descriptor.context : void 0;
6373
- return /* @__PURE__ */ jsx16(InteractionLabel, { ...props, children: props.children ?? context?.title ?? (descriptor ? interactionLabel(descriptor) : void 0) });
6348
+ return /* @__PURE__ */ jsx20(InteractionLabel, { ...props, children: props.children ?? context?.title ?? (descriptor ? interactionLabel(descriptor) : void 0) });
6374
6349
  }
6375
6350
  function PromptMessage(props) {
6376
6351
  const { descriptor } = useInteractionPrimitiveContext();
6377
6352
  const context = descriptor?.kind === "prompt" ? descriptor.context : void 0;
6378
6353
  const message = props.children ?? (typeof context?.payload?.message === "string" ? context.payload.message : void 0);
6379
6354
  if (!message) return null;
6380
- return /* @__PURE__ */ jsx16(InteractionDescription, { ...props, children: message });
6355
+ return /* @__PURE__ */ jsx20(InteractionDescription, { ...props, children: message });
6381
6356
  }
6382
6357
  function PromptOption({
6383
6358
  value,
@@ -6428,7 +6403,7 @@ function PromptOption({
6428
6403
  function PromptOptions({ children }) {
6429
6404
  const { descriptor } = useInteractionPrimitiveContext();
6430
6405
  const options = descriptor?.kind === "prompt" ? descriptor.context.options ?? [] : [];
6431
- return /* @__PURE__ */ jsx16(Fragment13, { children: options.map((option) => /* @__PURE__ */ jsx16(Fragment12, { children: children(option) }, option.id)) });
6406
+ return /* @__PURE__ */ jsx20(Fragment17, { children: options.map((option) => /* @__PURE__ */ jsx20(Fragment16, { children: children(option) }, option.id)) });
6432
6407
  }
6433
6408
  function PromptDialog({
6434
6409
  prompt,
@@ -6437,14 +6412,14 @@ function PromptDialog({
6437
6412
  children
6438
6413
  }) {
6439
6414
  const lifecycle = useDialogLifecycle({ defaultOpen, onStateChange });
6440
- const renderState = useMemo15(
6415
+ const renderState = useMemo16(
6441
6416
  () => ({
6442
6417
  prompt,
6443
6418
  ...lifecycle
6444
6419
  }),
6445
6420
  [lifecycle, prompt]
6446
6421
  );
6447
- return /* @__PURE__ */ jsx16(Fragment13, { children: children(renderState) });
6422
+ return /* @__PURE__ */ jsx20(Fragment17, { children: children(renderState) });
6448
6423
  }
6449
6424
  var PromptInboxContext = createContext11(null);
6450
6425
  function usePromptInboxContext() {
@@ -6458,16 +6433,16 @@ function usePromptInboxContext() {
6458
6433
  }
6459
6434
  function PromptInboxRoot({ children }) {
6460
6435
  const inbox = useSeatInbox();
6461
- return /* @__PURE__ */ jsx16(PromptInboxContext.Provider, { value: { prompts: inbox.prompts }, children });
6436
+ return /* @__PURE__ */ jsx20(PromptInboxContext.Provider, { value: { prompts: inbox.prompts }, children });
6462
6437
  }
6463
6438
  function PromptInboxEmpty({ children }) {
6464
6439
  const { prompts } = usePromptInboxContext();
6465
6440
  if (prompts.length > 0) return null;
6466
- return /* @__PURE__ */ jsx16(Fragment13, { children });
6441
+ return /* @__PURE__ */ jsx20(Fragment17, { children });
6467
6442
  }
6468
6443
  function PromptInboxItems({ children }) {
6469
6444
  const { prompts } = usePromptInboxContext();
6470
- return /* @__PURE__ */ jsx16(Fragment13, { children: prompts.map((prompt) => children(prompt)) });
6445
+ return /* @__PURE__ */ jsx20(Fragment17, { children: prompts.map((prompt) => children(prompt)) });
6471
6446
  }
6472
6447
  var Prompt = {
6473
6448
  Root: PromptRoot,
@@ -6483,9 +6458,9 @@ var PromptInbox = {
6483
6458
  Items: PromptInboxItems
6484
6459
  };
6485
6460
 
6486
- // src/runtime-internal/primitives/dice.tsx
6461
+ // src/runtime/primitives/dice.tsx
6487
6462
  import { createContext as createContext12, useContext as useContext12 } from "react";
6488
- import { jsx as jsx17 } from "react/jsx-runtime";
6463
+ import { jsx as jsx21 } from "react/jsx-runtime";
6489
6464
  var DiceContext = createContext12(null);
6490
6465
  function normalizeDiceState({
6491
6466
  values,
@@ -6505,7 +6480,7 @@ function normalizeDiceState({
6505
6480
  };
6506
6481
  }
6507
6482
  function DiceRoot({ values, count, children }) {
6508
- return /* @__PURE__ */ jsx17(DiceContext.Provider, { value: normalizeDiceState({ values, count }), children });
6483
+ return /* @__PURE__ */ jsx21(DiceContext.Provider, { value: normalizeDiceState({ values, count }), children });
6509
6484
  }
6510
6485
  function useDicePrimitiveContext() {
6511
6486
  const value = useContext12(DiceContext);
@@ -6537,8 +6512,6 @@ export {
6537
6512
  GameRoot,
6538
6513
  GameChrome,
6539
6514
  Game,
6540
- composeEventHandlers,
6541
- renderPrimitive,
6542
6515
  useZonePrimitiveContext,
6543
6516
  useOptionalZonePrimitiveContext,
6544
6517
  useZoneCardContext,
@@ -6576,18 +6549,18 @@ export {
6576
6549
  useInteractionPrimitiveContext,
6577
6550
  useResolvedCardTargetValue,
6578
6551
  InteractionRoot,
6579
- InteractionDialog,
6552
+ InteractionFormPrimitive,
6553
+ InteractionState,
6580
6554
  InteractionSwitch,
6581
6555
  InteractionRoutes,
6556
+ InteractionDialog,
6557
+ InteractionTrigger,
6558
+ InteractionSubmit,
6559
+ InteractionInput,
6582
6560
  InteractionLabel,
6583
6561
  InteractionDescription,
6584
6562
  InteractionUnavailableMessage,
6585
6563
  InteractionValidationMessage,
6586
- InteractionTrigger,
6587
- InteractionState,
6588
- InteractionFormPrimitive,
6589
- InteractionSubmit,
6590
- InteractionInput,
6591
6564
  InteractionCardInput,
6592
6565
  Interaction,
6593
6566
  PhaseSwitch,
@@ -6617,4 +6590,4 @@ export {
6617
6590
  DiceValues,
6618
6591
  Dice
6619
6592
  };
6620
- //# sourceMappingURL=chunk-ZABVH7AO.js.map
6593
+ //# sourceMappingURL=chunk-ADYH6PVT.js.map