@dreamboard-games/sdk 0.2.1-alpha.0 → 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 (363) 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-fy0_QzgO.d.ts → ThemeProvider-DvMl17Ny.d.ts} +1 -1
  4. package/dist/attributes-BeRyboMS.d.ts +279 -0
  5. package/dist/browser-interaction.d.ts +708 -0
  6. package/dist/browser-interaction.js +106 -0
  7. package/dist/{chunk-KAELH4KC.js → chunk-3RQEICD3.js} +2 -2
  8. package/dist/{chunk-TDSWKVZ4.js → chunk-ADYH6PVT.js} +2457 -1265
  9. package/dist/chunk-ADYH6PVT.js.map +1 -0
  10. package/dist/{chunk-YFY3RL52.js → chunk-P7VMTJ5D.js} +2 -2
  11. package/dist/{chunk-YFY3RL52.js.map → chunk-P7VMTJ5D.js.map} +1 -1
  12. package/dist/chunk-QLG6VEMW.js +1691 -0
  13. package/dist/chunk-QLG6VEMW.js.map +1 -0
  14. package/dist/{chunk-WYPQ3GG5.js → chunk-QZ6X4B5P.js} +1177 -1106
  15. package/dist/chunk-QZ6X4B5P.js.map +1 -0
  16. package/dist/{chunk-GKKBPPSW.js → chunk-TXXLS3OI.js} +405 -309
  17. package/dist/chunk-TXXLS3OI.js.map +1 -0
  18. package/dist/{chunk-FDNZTDD6.js → chunk-W6SGFWXH.js} +48 -44
  19. package/dist/chunk-W6SGFWXH.js.map +1 -0
  20. package/dist/{chunk-MKXPVOUT.js → chunk-Y2AFYBMB.js} +48 -4
  21. package/dist/chunk-Y2AFYBMB.js.map +1 -0
  22. package/dist/{index-BwqPQtBu.d.ts → codegen.d.ts} +57 -565
  23. package/dist/{infrastructure/workspace-codegen.js → codegen.js} +3 -3
  24. package/dist/{components-D5ZRE2Hl.d.ts → components-DaIqi9QM.d.ts} +48 -37
  25. package/dist/{hex-board-view-D_07hO6O.d.ts → hex-board-view-UCUjMALd.d.ts} +3 -2
  26. package/dist/{infrastructure/reducer-bundle-abi.d.ts → index.d-BGqVifr_.d.ts} +289 -10
  27. package/dist/index.js +1 -1
  28. package/dist/package-set.d.ts +2 -2
  29. package/dist/package-set.js +1 -1
  30. package/dist/primitive-props-BNHDkgd7.d.ts +16 -0
  31. package/dist/reducer-contract.d.ts +3 -0
  32. package/dist/{infrastructure/reducer-bundle-abi.js → reducer-contract.js} +4 -4
  33. package/dist/reducer.d.ts +185 -179
  34. package/dist/reducer.js +1637 -1353
  35. package/dist/reducer.js.map +1 -1
  36. package/dist/runtime/primitives.d.ts +10 -9
  37. package/dist/runtime/primitives.js +8 -7
  38. package/dist/runtime/runtime-api.d.ts +2 -0
  39. package/dist/runtime/runtime-api.js +1 -0
  40. package/dist/runtime/workspace-contract.d.ts +63 -17
  41. package/dist/runtime/workspace-contract.js +5 -5
  42. package/dist/{runtime-api-DWxvTr-O.d.ts → runtime-api-tGL3ArsB.d.ts} +109 -4
  43. package/dist/runtime.d.ts +12 -57
  44. package/dist/runtime.js +487 -7
  45. package/dist/runtime.js.map +1 -1
  46. package/dist/testing.d.ts +4 -4
  47. package/dist/testing.js.map +1 -1
  48. package/dist/types.d.ts +1531 -85
  49. package/dist/types.js +1 -3
  50. package/dist/types.js.map +1 -1
  51. package/dist/ui/components.d.ts +7 -8
  52. package/dist/ui/components.js +1 -1
  53. package/dist/ui/defaults.d.ts +1 -1
  54. package/dist/ui/{types/player-state.d.ts → player-state.d.ts} +2 -2
  55. package/dist/{ui-contract-iQfTtUSL.d.ts → ui-contract-SctM4ibF.d.ts} +157 -150
  56. package/dist/ui.d.ts +10 -11
  57. package/dist/ui.js +2 -2
  58. package/package.json +35 -74
  59. package/dist/bundle-CDd5FKeD.d.ts +0 -283
  60. package/dist/cards-Sl3b40Mv.d.ts +0 -13
  61. package/dist/chunk-7YAHLYBR.js +0 -481
  62. package/dist/chunk-7YAHLYBR.js.map +0 -1
  63. package/dist/chunk-FDNZTDD6.js.map +0 -1
  64. package/dist/chunk-GKKBPPSW.js.map +0 -1
  65. package/dist/chunk-I46YJSOD.js +0 -1
  66. package/dist/chunk-MKXPVOUT.js.map +0 -1
  67. package/dist/chunk-T52J5RMF.js +0 -1
  68. package/dist/chunk-TDSWKVZ4.js.map +0 -1
  69. package/dist/chunk-U5C6BONG.js +0 -34
  70. package/dist/chunk-U5C6BONG.js.map +0 -1
  71. package/dist/chunk-WYPQ3GG5.js.map +0 -1
  72. package/dist/generated/runtime/primitives.d.ts +0 -12
  73. package/dist/generated/runtime/primitives.js +0 -180
  74. package/dist/generated/runtime/primitives.js.map +0 -1
  75. package/dist/generated/runtime-api.d.ts +0 -3
  76. package/dist/generated/runtime-api.js +0 -2
  77. package/dist/generated/runtime.d.ts +0 -14
  78. package/dist/generated/runtime.js +0 -18
  79. package/dist/generated/runtime.js.map +0 -1
  80. package/dist/generated/workspace-contract.d.ts +0 -14
  81. package/dist/generated/workspace-contract.js +0 -14
  82. package/dist/generated/workspace-contract.js.map +0 -1
  83. package/dist/infrastructure/reducer-bundle-abi.js.map +0 -1
  84. package/dist/infrastructure/workspace-codegen.d.ts +0 -53
  85. package/dist/infrastructure/workspace-codegen.js.map +0 -1
  86. package/dist/manifest-contract-BNHVGFtU.d.ts +0 -9
  87. package/dist/primitive-props-DpKs-GCr.d.ts +0 -11
  88. package/dist/runtime/types/runtime-api.d.ts +0 -1
  89. package/dist/runtime/types/runtime-api.js +0 -2
  90. package/dist/runtime-api-3dshj6kK.d.ts +0 -101
  91. package/dist/slots-1GPGihk8.d.ts +0 -8
  92. package/src/generated/reducer-contract/builders.ts +0 -90
  93. package/src/generated/reducer-contract/version.ts +0 -9
  94. package/src/generated/reducer-contract/wire.ts +0 -100
  95. package/src/generated/reducer-contract/zod.ts +0 -103
  96. package/src/generated/runtime/primitives.ts +0 -2
  97. package/src/generated/runtime-api.ts +0 -5
  98. package/src/generated/runtime.ts +0 -35
  99. package/src/generated/workspace-contract.ts +0 -2
  100. package/src/index.ts +0 -7
  101. package/src/infrastructure/reducer-bundle-abi.ts +0 -8
  102. package/src/infrastructure/reducer-contract/bundle.ts +0 -37
  103. package/src/infrastructure/workspace-codegen/hex-geometry.ts +0 -69
  104. package/src/infrastructure/workspace-codegen/index.ts +0 -64
  105. package/src/infrastructure/workspace-codegen/manifest-contract.ts +0 -6632
  106. package/src/infrastructure/workspace-codegen/manifest-validation.ts +0 -795
  107. package/src/infrastructure/workspace-codegen/ownership.ts +0 -131
  108. package/src/infrastructure/workspace-codegen/preset-card-sets.ts +0 -169
  109. package/src/infrastructure/workspace-codegen/seeds.ts +0 -1705
  110. package/src/infrastructure/workspace-codegen.ts +0 -1
  111. package/src/package-set.ts +0 -19
  112. package/src/reducer/authoring/contract.ts +0 -157
  113. package/src/reducer/authoring/effect.ts +0 -224
  114. package/src/reducer/authoring/game.ts +0 -23
  115. package/src/reducer/authoring/interaction.ts +0 -98
  116. package/src/reducer/authoring/phase.ts +0 -300
  117. package/src/reducer/authoring/types.ts +0 -70
  118. package/src/reducer/authoring/validation.ts +0 -382
  119. package/src/reducer/authoring/view-stage.ts +0 -68
  120. package/src/reducer/authoring.ts +0 -29
  121. package/src/reducer/bundle/ingress-bundle.ts +0 -491
  122. package/src/reducer/bundle/trusted/engine-instruction-resolver.ts +0 -254
  123. package/src/reducer/bundle/trusted/flow-instruction-resolver.ts +0 -73
  124. package/src/reducer/bundle/trusted/instruction-runner.ts +0 -414
  125. package/src/reducer/bundle/trusted/interaction-authorization.ts +0 -137
  126. package/src/reducer/bundle/trusted/interaction-collectors.ts +0 -859
  127. package/src/reducer/bundle/trusted/interaction-decision.ts +0 -747
  128. package/src/reducer/bundle/trusted/interaction-resolver.ts +0 -95
  129. package/src/reducer/bundle/trusted/interaction-types.ts +0 -171
  130. package/src/reducer/bundle/trusted/lifecycle-runner.ts +0 -427
  131. package/src/reducer/bundle/trusted/projection-builder.ts +0 -356
  132. package/src/reducer/bundle/trusted/projection-context.ts +0 -39
  133. package/src/reducer/bundle/trusted/rng-sampler.ts +0 -150
  134. package/src/reducer/bundle/trusted/runtime-registry.ts +0 -120
  135. package/src/reducer/bundle/trusted/runtime-scope.ts +0 -336
  136. package/src/reducer/bundle/trusted/simultaneous-player.ts +0 -97
  137. package/src/reducer/bundle/trusted/stage-resolver.ts +0 -87
  138. package/src/reducer/bundle/trusted/static-projection.ts +0 -116
  139. package/src/reducer/bundle/trusted/trusted-runtime-args.ts +0 -97
  140. package/src/reducer/bundle/trusted/trusted-runtime-result.ts +0 -39
  141. package/src/reducer/bundle/trusted/trusted-setup-profiles.ts +0 -43
  142. package/src/reducer/bundle/trusted/trusted-state-codec.ts +0 -48
  143. package/src/reducer/bundle/trusted-bundle.ts +0 -97
  144. package/src/reducer/bundle/types.ts +0 -171
  145. package/src/reducer/bundle.ts +0 -2
  146. package/src/reducer/client-param-schemas.ts +0 -57
  147. package/src/reducer/compose.ts +0 -34
  148. package/src/reducer/core/runtime-input.ts +0 -30
  149. package/src/reducer/core/runtime-instruction.ts +0 -59
  150. package/src/reducer/core/types.ts +0 -62
  151. package/src/reducer/definition-index.ts +0 -277
  152. package/src/reducer/derived.ts +0 -106
  153. package/src/reducer/effects.ts +0 -92
  154. package/src/reducer/engine/runtime-instruction-engine.ts +0 -155
  155. package/src/reducer/ingress/decode-runtime-input.ts +0 -7
  156. package/src/reducer/ingress/decode-session-state.ts +0 -9
  157. package/src/reducer/ingress/encode-session-state.ts +0 -6
  158. package/src/reducer/ingress/input-codec.ts +0 -18
  159. package/src/reducer/ingress/phase-schemas.ts +0 -62
  160. package/src/reducer/ingress/raw-types.ts +0 -107
  161. package/src/reducer/ingress/runtime-codec.ts +0 -14
  162. package/src/reducer/ingress/runtime-payload.ts +0 -13
  163. package/src/reducer/ingress/session-codec.ts +0 -392
  164. package/src/reducer/ingress/types.ts +0 -6
  165. package/src/reducer/inputs/boardInput.ts +0 -217
  166. package/src/reducer/inputs/boardTarget.ts +0 -190
  167. package/src/reducer/inputs/cardInput.ts +0 -86
  168. package/src/reducer/inputs/cardTarget.ts +0 -101
  169. package/src/reducer/inputs/choiceTarget.ts +0 -104
  170. package/src/reducer/inputs/defineInputs.ts +0 -71
  171. package/src/reducer/inputs/formInput.ts +0 -809
  172. package/src/reducer/inputs/many.ts +0 -120
  173. package/src/reducer/inputs/promptInput.ts +0 -87
  174. package/src/reducer/inputs/rngInput.ts +0 -58
  175. package/src/reducer/inputs/targetRule.ts +0 -123
  176. package/src/reducer/inputs.ts +0 -41
  177. package/src/reducer/model/definition.ts +0 -1072
  178. package/src/reducer/model/extract.ts +0 -745
  179. package/src/reducer/model/manifest.ts +0 -570
  180. package/src/reducer/model/queries.ts +0 -641
  181. package/src/reducer/model/runtime.ts +0 -264
  182. package/src/reducer/model/spec.ts +0 -1386
  183. package/src/reducer/model/table.ts +0 -260
  184. package/src/reducer/model.ts +0 -7
  185. package/src/reducer/ops.ts +0 -1034
  186. package/src/reducer/parse-utils.ts +0 -28
  187. package/src/reducer/per-player.ts +0 -422
  188. package/src/reducer/rng.ts +0 -69
  189. package/src/reducer/schema-helpers.ts +0 -185
  190. package/src/reducer/setup-bootstrap-helpers.ts +0 -171
  191. package/src/reducer/setup-bootstrap.ts +0 -481
  192. package/src/reducer/table-ops.ts +0 -2671
  193. package/src/reducer/table-queries.ts +0 -372
  194. package/src/reducer/transaction.ts +0 -120
  195. package/src/reducer.ts +0 -314
  196. package/src/runtime/primitives.ts +0 -1
  197. package/src/runtime/types/runtime-api.ts +0 -1
  198. package/src/runtime/workspace-contract.ts +0 -32
  199. package/src/runtime-internal/components/InteractionForm.tsx +0 -1309
  200. package/src/runtime-internal/components/PluginRuntime.tsx +0 -103
  201. package/src/runtime-internal/components/board/target-layer.ts +0 -70
  202. package/src/runtime-internal/context/ClientParamSchemaContext.tsx +0 -44
  203. package/src/runtime-internal/context/InteractionDraftContext.tsx +0 -279
  204. package/src/runtime-internal/context/PluginSessionContext.tsx +0 -47
  205. package/src/runtime-internal/context/PluginStateContext.tsx +0 -262
  206. package/src/runtime-internal/context/RuntimeContext.tsx +0 -96
  207. package/src/runtime-internal/defaults/components.tsx +0 -409
  208. package/src/runtime-internal/defaults/index.ts +0 -11
  209. package/src/runtime-internal/errors/ValidationError.ts +0 -29
  210. package/src/runtime-internal/hooks/useActivePlayers.ts +0 -33
  211. package/src/runtime-internal/hooks/useBoardInteractions.ts +0 -665
  212. package/src/runtime-internal/hooks/useGameSelector.ts +0 -105
  213. package/src/runtime-internal/hooks/useGameView.ts +0 -9
  214. package/src/runtime-internal/hooks/useInteractionByKey.ts +0 -354
  215. package/src/runtime-internal/hooks/useInteractionHandle.ts +0 -438
  216. package/src/runtime-internal/hooks/useIsMyTurn.ts +0 -20
  217. package/src/runtime-internal/hooks/useLobby.ts +0 -76
  218. package/src/runtime-internal/hooks/useMe.ts +0 -48
  219. package/src/runtime-internal/hooks/usePlayerInfo.ts +0 -28
  220. package/src/runtime-internal/hooks/usePlayerTurnOrder.ts +0 -23
  221. package/src/runtime-internal/hooks/usePluginRuntime.ts +0 -147
  222. package/src/runtime-internal/hooks/useSeatInbox.ts +0 -61
  223. package/src/runtime-internal/hooks/useSimultaneousPhase.ts +0 -10
  224. package/src/runtime-internal/index.ts +0 -42
  225. package/src/runtime-internal/internal.ts +0 -43
  226. package/src/runtime-internal/plugin-styles.css +0 -250
  227. package/src/runtime-internal/primitives/board.tsx +0 -459
  228. package/src/runtime-internal/primitives/dialog-lifecycle.ts +0 -58
  229. package/src/runtime-internal/primitives/dice.tsx +0 -79
  230. package/src/runtime-internal/primitives/game-ui-provider.tsx +0 -35
  231. package/src/runtime-internal/primitives/game.tsx +0 -387
  232. package/src/runtime-internal/primitives/hand-intent-adapter.ts +0 -147
  233. package/src/runtime-internal/primitives/hand-surface.tsx +0 -594
  234. package/src/runtime-internal/primitives/index.ts +0 -196
  235. package/src/runtime-internal/primitives/interaction-form-binding.tsx +0 -56
  236. package/src/runtime-internal/primitives/interaction-submit.ts +0 -90
  237. package/src/runtime-internal/primitives/interaction.tsx +0 -987
  238. package/src/runtime-internal/primitives/phase.tsx +0 -43
  239. package/src/runtime-internal/primitives/player-roster.tsx +0 -302
  240. package/src/runtime-internal/primitives/primitive-props.tsx +0 -101
  241. package/src/runtime-internal/primitives/prompt.tsx +0 -255
  242. package/src/runtime-internal/primitives/ui.tsx +0 -60
  243. package/src/runtime-internal/primitives/zone.tsx +0 -791
  244. package/src/runtime-internal/reducer.ts +0 -30
  245. package/src/runtime-internal/runtime/createPluginRuntimeAPI.ts +0 -605
  246. package/src/runtime-internal/types/plugin-state.ts +0 -508
  247. package/src/runtime-internal/types/reducer-state.ts +0 -24
  248. package/src/runtime-internal/types/runtime-api.ts +0 -114
  249. package/src/runtime-internal/ui-contract.ts +0 -519
  250. package/src/runtime-internal/utils/card-intent-adapter.ts +0 -546
  251. package/src/runtime-internal/utils/interaction-inputs.ts +0 -492
  252. package/src/runtime-internal/utils/interaction-labels.ts +0 -23
  253. package/src/runtime-internal/utils/interaction-router.ts +0 -273
  254. package/src/runtime-internal/utils/interaction-status.ts +0 -74
  255. package/src/runtime-internal/workspace-contract.ts +0 -1170
  256. package/src/runtime.ts +0 -34
  257. package/src/testing/create-expect-api.ts +0 -352
  258. package/src/testing/create-test-runtime.ts +0 -381
  259. package/src/testing/definitions.ts +0 -127
  260. package/src/testing/index.ts +0 -3
  261. package/src/testing.ts +0 -1
  262. package/src/type-stubs/manifest-contract.d.ts +0 -42
  263. package/src/type-stubs/manifest-contract.js +0 -72
  264. package/src/type-stubs/ui-contract.d.ts +0 -5
  265. package/src/type-stubs/ui-contract.js +0 -1
  266. package/src/types/authoring-card-properties.type-test.ts +0 -266
  267. package/src/types/authoring.ts +0 -1282
  268. package/src/types/cards.ts +0 -19
  269. package/src/types/contracts.ts +0 -1550
  270. package/src/types/generated-helpers.ts +0 -35
  271. package/src/types/index.ts +0 -147
  272. package/src/types/slots.ts +0 -11
  273. package/src/types.ts +0 -1
  274. package/src/ui/components/ActionButton.tsx +0 -97
  275. package/src/ui/components/ActionPanel.tsx +0 -315
  276. package/src/ui/components/Card.tsx +0 -378
  277. package/src/ui/components/CardDragSurface.tsx +0 -1076
  278. package/src/ui/components/ChromeSuppressionContext.tsx +0 -70
  279. package/src/ui/components/CostDisplay.tsx +0 -145
  280. package/src/ui/components/DiceRoller.tsx +0 -581
  281. package/src/ui/components/Drawer.tsx +0 -180
  282. package/src/ui/components/ErrorBoundary.tsx +0 -275
  283. package/src/ui/components/GameEndDisplay.tsx +0 -398
  284. package/src/ui/components/GameSkeleton.tsx +0 -260
  285. package/src/ui/components/Hand.tsx +0 -468
  286. package/src/ui/components/HandDock.tsx +0 -299
  287. package/src/ui/components/HandView.tsx +0 -441
  288. package/src/ui/components/MobileHandTray.tsx +0 -381
  289. package/src/ui/components/MoreActions.tsx +0 -143
  290. package/src/ui/components/PhaseIndicator.tsx +0 -341
  291. package/src/ui/components/PlayArea.tsx +0 -146
  292. package/src/ui/components/PrimaryActionButton.tsx +0 -336
  293. package/src/ui/components/PrimaryButton.tsx +0 -45
  294. package/src/ui/components/ResourceCounter.tsx +0 -270
  295. package/src/ui/components/StagingZone.tsx +0 -134
  296. package/src/ui/components/ThemedButton.tsx +0 -113
  297. package/src/ui/components/Toast.tsx +0 -264
  298. package/src/ui/components/board/HexGrid.tsx +0 -1294
  299. package/src/ui/components/board/NetworkGraph.tsx +0 -476
  300. package/src/ui/components/board/SlotSystem.tsx +0 -388
  301. package/src/ui/components/board/SquareGrid.tsx +0 -1165
  302. package/src/ui/components/board/TrackBoard.tsx +0 -496
  303. package/src/ui/components/board/ZoneMap.tsx +0 -448
  304. package/src/ui/components/board/hex-board-view.ts +0 -123
  305. package/src/ui/components/board/index.ts +0 -142
  306. package/src/ui/components/board/interaction-accessibility.ts +0 -21
  307. package/src/ui/components/board/target-layer.ts +0 -66
  308. package/src/ui/components/card-render-content.type-test.ts +0 -27
  309. package/src/ui/components/hand-layout-math.ts +0 -163
  310. package/src/ui/components/hand-pointer-engine.ts +0 -413
  311. package/src/ui/components/index.ts +0 -245
  312. package/src/ui/components.ts +0 -1
  313. package/src/ui/defaults/components.tsx +0 -106
  314. package/src/ui/defaults/index.ts +0 -8
  315. package/src/ui/defaults.ts +0 -1
  316. package/src/ui/errors/ValidationError.ts +0 -29
  317. package/src/ui/helpers/cards.ts +0 -19
  318. package/src/ui/helpers/track-board.ts +0 -211
  319. package/src/ui/hooks/useBoardTopology.ts +0 -316
  320. package/src/ui/hooks/useCards.ts +0 -10
  321. package/src/ui/hooks/useHandCardPointer.ts +0 -381
  322. package/src/ui/hooks/useHandLayout.ts +0 -378
  323. package/src/ui/hooks/useHandPresentation.ts +0 -121
  324. package/src/ui/hooks/useHexBoard.ts +0 -74
  325. package/src/ui/hooks/useHexGrid.ts +0 -185
  326. package/src/ui/hooks/useIsMobile.ts +0 -35
  327. package/src/ui/hooks/usePanZoom.ts +0 -278
  328. package/src/ui/hooks/useSquareBoard.ts +0 -124
  329. package/src/ui/hooks/useSquareGrid.ts +0 -328
  330. package/src/ui/index.ts +0 -98
  331. package/src/ui/internal/ui/alert.tsx +0 -51
  332. package/src/ui/internal/ui/button.tsx +0 -58
  333. package/src/ui/internal/ui/dialog.tsx +0 -134
  334. package/src/ui/internal/ui/input.tsx +0 -21
  335. package/src/ui/internal/ui/label.tsx +0 -21
  336. package/src/ui/internal/ui/select.tsx +0 -129
  337. package/src/ui/internal/ui/tooltip.tsx +0 -54
  338. package/src/ui/internal/ui/utils.ts +0 -5
  339. package/src/ui/plugin-styles.css +0 -250
  340. package/src/ui/primitives/dialog-lifecycle.ts +0 -58
  341. package/src/ui/primitives/dice.tsx +0 -79
  342. package/src/ui/primitives/primitive-props.tsx +0 -101
  343. package/src/ui/theme/ThemeProvider.tsx +0 -252
  344. package/src/ui/theme/board.ts +0 -61
  345. package/src/ui/theme/css-vars.ts +0 -105
  346. package/src/ui/theme/derive.ts +0 -240
  347. package/src/ui/theme/index.ts +0 -61
  348. package/src/ui/theme/presets/arcade.ts +0 -261
  349. package/src/ui/theme/presets/studio.ts +0 -261
  350. package/src/ui/theme/presets/tabletop.ts +0 -266
  351. package/src/ui/theme/tokens.ts +0 -392
  352. package/src/ui/types/hex-color.ts +0 -20
  353. package/src/ui/types/player-state.ts +0 -463
  354. package/src/ui/types/tiled-board.ts +0 -785
  355. package/src/ui/types/visual-state.ts +0 -137
  356. package/src/ui.ts +0 -1
  357. /package/dist/{chunk-I46YJSOD.js.map → browser-interaction.js.map} +0 -0
  358. /package/dist/{chunk-KAELH4KC.js.map → chunk-3RQEICD3.js.map} +0 -0
  359. /package/dist/{chunk-T52J5RMF.js.map → codegen.js.map} +0 -0
  360. /package/dist/{generated/runtime-api.js.map → reducer-contract.js.map} +0 -0
  361. /package/dist/runtime/{types/runtime-api.js.map → runtime-api.js.map} +0 -0
  362. /package/dist/ui/{types/player-state.js → player-state.js} +0 -0
  363. /package/dist/ui/{types/player-state.js.map → player-state.js.map} +0 -0
@@ -1,987 +0,0 @@
1
- import {
2
- createContext,
3
- useCallback,
4
- useContext,
5
- useEffect,
6
- useMemo,
7
- useRef,
8
- type ButtonHTMLAttributes,
9
- type HTMLAttributes,
10
- type InputHTMLAttributes,
11
- type ReactNode,
12
- } from "react";
13
- import {
14
- useInteractionHandle,
15
- type InteractionHandle,
16
- type InteractionParamsShape,
17
- } from "../hooks/useInteractionHandle.js";
18
- import {
19
- useInteractionUiStore,
20
- usePendingInteractionKey,
21
- usePendingInteractionRevision,
22
- } from "../context/InteractionDraftContext.js";
23
- import { usePluginState } from "../context/PluginStateContext.js";
24
- import type { InteractionInputKey, InteractionKey } from "../ui-contract.js";
25
- import type {
26
- InteractionDescriptor,
27
- InteractionInputDescriptor,
28
- ZoneHandlesSnapshot,
29
- } from "../types/plugin-state.js";
30
- import {
31
- hasInteractionFieldErrors,
32
- inputByKey,
33
- isBoardTargetDomain,
34
- isResolvedTargetDomain,
35
- isTargetDomain,
36
- isManyTargetSelectable,
37
- } from "../utils/interaction-inputs.js";
38
- import {
39
- getInteractionDraftReadiness,
40
- markInteractionPending,
41
- routeCardInputIntent,
42
- shouldRouteInteractionPending,
43
- } from "../utils/interaction-router.js";
44
- import {
45
- interactionUnavailableReason,
46
- isInteractionAvailable,
47
- } from "../utils/interaction-status.js";
48
- import { interactionLabel } from "../utils/interaction-labels.js";
49
- import {
50
- composeEventHandlers,
51
- renderPrimitive,
52
- type PrimitiveCommonProps,
53
- } from "./primitive-props.js";
54
- import {
55
- BoundInteractionForm,
56
- castInteractionDraft,
57
- castInteractionHandle,
58
- type BoundInteractionFormProps,
59
- } from "./interaction-form-binding.js";
60
- import {
61
- InteractionField as BaseInteractionField,
62
- type InteractionFieldProps as BaseInteractionFieldProps,
63
- } from "../components/InteractionForm.js";
64
- import {
65
- submitInteractionDraft,
66
- submitInteractionParams,
67
- type InteractionSubmitCallbacks,
68
- } from "./interaction-submit.js";
69
- import {
70
- useDialogLifecycle,
71
- type DialogLifecycleState,
72
- } from "./dialog-lifecycle.js";
73
- import { useGameActionError } from "./game.js";
74
- import { useOptionalZonePrimitiveContext, useZoneCardContext } from "./zone.js";
75
-
76
- interface InteractionContextValue {
77
- interaction: string;
78
- descriptor: InteractionDescriptor | null;
79
- handle: ReturnType<typeof useInteractionHandle> | null;
80
- }
81
-
82
- const InteractionContext = createContext<InteractionContextValue | null>(null);
83
-
84
- function humanizeInteraction(value: string): string {
85
- const parts = value.split(".");
86
- const leaf = parts[parts.length - 1] ?? value;
87
- return leaf
88
- .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
89
- .replace(/[-_]+/g, " ")
90
- .replace(/\s+/g, " ")
91
- .trim()
92
- .replace(/^./, (first: string) => first.toUpperCase());
93
- }
94
-
95
- export function useInteractionPrimitiveContext(): InteractionContextValue {
96
- const value = useContext(InteractionContext);
97
- if (!value) {
98
- throw new Error(
99
- "Interaction primitives must be rendered inside <Interaction.Root>.",
100
- );
101
- }
102
- return value;
103
- }
104
-
105
- /**
106
- * Live draft value for the active interaction's card-target input, resolved
107
- * from the surrounding `<Interaction.Root>`. Returns the selected card-id array
108
- * for `selection: "many"` inputs and the single id for `selection: "one"`.
109
- * Returns `undefined` when there is no interaction context or no card-target
110
- * input (so it is safe to render outside a root). Reactive: `handle.values`
111
- * updates as the draft changes. Backs the card surface `slot.card.Value`.
112
- */
113
- export function useResolvedCardTargetValue(): unknown {
114
- const context = useContext(InteractionContext);
115
- const descriptor = context?.descriptor;
116
- const handle = context?.handle;
117
- if (!descriptor || !handle) return undefined;
118
- const cardInput = descriptor.inputs.find(
119
- (input) =>
120
- isTargetDomain(input.domain) && input.domain.type === "cardTarget",
121
- );
122
- if (!cardInput) return undefined;
123
- return (handle.values as Record<string, unknown>)[cardInput.key];
124
- }
125
-
126
- function useInteractionDescriptor(interaction: string) {
127
- return usePluginState((state) =>
128
- state.gameplay.availableInteractions.find(
129
- (descriptor) =>
130
- descriptor.interactionKey === interaction ||
131
- descriptor.interactionId === interaction,
132
- ),
133
- );
134
- }
135
-
136
- export interface InteractionRootProps<
137
- Interaction extends string = InteractionKey,
138
- > {
139
- interaction: Interaction;
140
- children: ReactNode;
141
- unavailable?: "render" | "hide";
142
- }
143
-
144
- function ResolvedInteractionRoot({
145
- interaction,
146
- descriptor,
147
- children,
148
- }: {
149
- interaction: string;
150
- descriptor: InteractionDescriptor;
151
- children: ReactNode;
152
- }) {
153
- const handle = useInteractionHandle(descriptor);
154
- const value = useMemo<InteractionContextValue>(
155
- () => ({ interaction, descriptor, handle }),
156
- [descriptor, handle, interaction],
157
- );
158
- return (
159
- <InteractionContext.Provider value={value}>
160
- {children}
161
- </InteractionContext.Provider>
162
- );
163
- }
164
-
165
- export function InteractionRoot<Interaction extends string = InteractionKey>({
166
- interaction,
167
- children,
168
- unavailable = "render",
169
- }: InteractionRootProps<Interaction>) {
170
- const descriptor = useInteractionDescriptor(interaction);
171
- if (!descriptor) {
172
- if (unavailable === "hide") return null;
173
- return (
174
- <InteractionContext.Provider
175
- value={{
176
- interaction,
177
- descriptor: null,
178
- handle: null,
179
- }}
180
- >
181
- {children}
182
- </InteractionContext.Provider>
183
- );
184
- }
185
- if (!isInteractionAvailable(descriptor) && unavailable === "hide") {
186
- return null;
187
- }
188
- return (
189
- <ResolvedInteractionRoot interaction={interaction} descriptor={descriptor}>
190
- {children}
191
- </ResolvedInteractionRoot>
192
- );
193
- }
194
-
195
- export type InteractionDialogState = DialogLifecycleState;
196
-
197
- export interface InteractionDialogRenderState<
198
- Interaction extends string = InteractionKey,
199
- > {
200
- interaction: Interaction;
201
- state: InteractionDialogState;
202
- open: boolean;
203
- minimized: boolean;
204
- dismissed: boolean;
205
- setOpen: (open: boolean) => void;
206
- restore: () => void;
207
- minimize: () => void;
208
- dismiss: () => void;
209
- }
210
-
211
- export interface InteractionDialogProps<
212
- Interaction extends string = InteractionKey,
213
- > {
214
- defaultOpen?: boolean;
215
- onStateChange?: (state: InteractionDialogState) => void;
216
- children: (state: InteractionDialogRenderState<Interaction>) => ReactNode;
217
- }
218
-
219
- export function InteractionDialog<Interaction extends string = InteractionKey>({
220
- defaultOpen = false,
221
- onStateChange,
222
- children,
223
- }: InteractionDialogProps<Interaction>) {
224
- const { interaction } = useInteractionPrimitiveContext();
225
- const pendingInteractionKey = usePendingInteractionKey();
226
- const pendingInteractionRevision = usePendingInteractionRevision();
227
- const lifecycle = useDialogLifecycle({ defaultOpen, onStateChange });
228
- const restoredRevisionRef = useRef<number | null>(null);
229
- useEffect(() => {
230
- if (
231
- pendingInteractionKey === interaction &&
232
- restoredRevisionRef.current !== pendingInteractionRevision
233
- ) {
234
- restoredRevisionRef.current = pendingInteractionRevision;
235
- lifecycle.restore();
236
- }
237
- }, [
238
- interaction,
239
- lifecycle,
240
- pendingInteractionKey,
241
- pendingInteractionRevision,
242
- ]);
243
- const renderState = useMemo<InteractionDialogRenderState<Interaction>>(
244
- () => ({
245
- interaction: interaction as Interaction,
246
- ...lifecycle,
247
- }),
248
- [interaction, lifecycle],
249
- );
250
- return <>{children(renderState)}</>;
251
- }
252
-
253
- export interface InteractionSwitchRenderState<
254
- Interaction extends string = InteractionKey,
255
- > {
256
- interaction: Interaction;
257
- descriptor: InteractionDescriptor<Interaction>;
258
- }
259
-
260
- export type InteractionSwitchRouteMap<
261
- Interaction extends string = InteractionKey,
262
- > = {
263
- [Key in Interaction]?: (
264
- state: InteractionSwitchRenderState<Key>,
265
- ) => ReactNode;
266
- };
267
-
268
- export interface InteractionRoute {
269
- readonly collect: Record<string, unknown>;
270
- }
271
-
272
- export type InteractionRoutesMap<Interaction extends string = InteractionKey> =
273
- {
274
- [Key in Interaction]: InteractionRoute;
275
- };
276
-
277
- export interface InteractionSwitchProps<
278
- Interaction extends string = InteractionKey,
279
- > {
280
- interaction?: Interaction;
281
- routes: InteractionSwitchRouteMap<Interaction>;
282
- fallback?: ReactNode;
283
- }
284
-
285
- export function InteractionSwitch<Interaction extends string = InteractionKey>({
286
- interaction,
287
- routes,
288
- fallback = null,
289
- }: InteractionSwitchProps<Interaction>) {
290
- const pendingInteractionKey = usePendingInteractionKey();
291
- const descriptors = usePluginState(
292
- (state) => state.gameplay.availableInteractions,
293
- );
294
- const routedInteraction = interaction ?? pendingInteractionKey;
295
- const descriptor = routedInteraction
296
- ? descriptors.find(
297
- (candidate) => candidate.interactionKey === routedInteraction,
298
- )
299
- : undefined;
300
- if (!descriptor) return <>{fallback}</>;
301
- const route =
302
- routes[descriptor.interactionKey as keyof typeof routes] ?? null;
303
- if (!route) return <>{fallback}</>;
304
- const typedInteraction = descriptor.interactionKey as Interaction;
305
- return (
306
- <InteractionRoot interaction={typedInteraction}>
307
- {route({
308
- interaction: typedInteraction,
309
- descriptor: descriptor as InteractionDescriptor<Interaction>,
310
- })}
311
- </InteractionRoot>
312
- );
313
- }
314
-
315
- export interface InteractionRoutesProps<
316
- Interaction extends string = InteractionKey,
317
- > {
318
- routes: InteractionRoutesMap<Interaction>;
319
- fallback?: ReactNode;
320
- includeUnavailable?: boolean | null;
321
- }
322
-
323
- const warnedInteractionRouteIssues = new Set<string>();
324
-
325
- function warnInteractionRouteIssue(message: string) {
326
- if (warnedInteractionRouteIssues.has(message)) return;
327
- warnedInteractionRouteIssues.add(message);
328
- console.warn(message);
329
- }
330
-
331
- export function InteractionRoutes<Interaction extends string = InteractionKey>({
332
- routes,
333
- fallback = null,
334
- includeUnavailable = false,
335
- }: InteractionRoutesProps<Interaction>) {
336
- const descriptors = usePluginState(
337
- (state) => state.gameplay.availableInteractions,
338
- );
339
- if (descriptors.length === 0) return <>{fallback}</>;
340
- const routedDescriptors = descriptors
341
- .filter(
342
- (descriptor) => includeUnavailable || isInteractionAvailable(descriptor),
343
- )
344
- .map((descriptor) => {
345
- const interaction = descriptor.interactionKey as Interaction;
346
- const route = routes[interaction as keyof typeof routes];
347
- if (!route) {
348
- warnInteractionRouteIssue(
349
- `[dreamboard] Interaction.Routes is missing a collector route for "${descriptor.interactionKey}". Declare the interaction in routes so input collection stays explicit.`,
350
- );
351
- return null;
352
- }
353
- const missingInputs = descriptor.inputs
354
- .map((input) => input.key)
355
- .filter((input) => !(input in route.collect));
356
- if (missingInputs.length > 0) {
357
- warnInteractionRouteIssue(
358
- `[dreamboard] Interaction.Routes route "${descriptor.interactionKey}" is missing collectors for: ${missingInputs.join(
359
- ", ",
360
- )}.`,
361
- );
362
- }
363
- return descriptor;
364
- });
365
- if (routedDescriptors.length === 0) return <>{fallback}</>;
366
- return null;
367
- }
368
-
369
- export type InteractionPartProps = PrimitiveCommonProps &
370
- HTMLAttributes<HTMLElement>;
371
-
372
- export function InteractionLabel({ children, ...props }: InteractionPartProps) {
373
- const { descriptor, interaction } = useInteractionPrimitiveContext();
374
- return renderPrimitive("span", {
375
- ...props,
376
- "data-dreamboard-interaction-label": "",
377
- children:
378
- children ??
379
- (descriptor
380
- ? interactionLabel(descriptor)
381
- : humanizeInteraction(interaction)),
382
- });
383
- }
384
-
385
- export function InteractionDescription({
386
- children,
387
- ...props
388
- }: InteractionPartProps) {
389
- const content = children;
390
- if (!content) return null;
391
- return renderPrimitive("span", {
392
- ...props,
393
- "data-dreamboard-interaction-description": "",
394
- children: content,
395
- });
396
- }
397
-
398
- export function InteractionUnavailableMessage({
399
- children,
400
- ...props
401
- }: InteractionPartProps) {
402
- const { descriptor, handle } = useInteractionPrimitiveContext();
403
- const reason =
404
- children ??
405
- handle?.unavailableReason ??
406
- interactionUnavailableReason(descriptor);
407
- if (!reason) return null;
408
- return renderPrimitive("span", {
409
- ...props,
410
- "data-dreamboard-interaction-unavailable": "",
411
- children: reason,
412
- });
413
- }
414
-
415
- export function InteractionValidationMessage({
416
- children,
417
- ...props
418
- }: InteractionPartProps) {
419
- const { handle } = useInteractionPrimitiveContext();
420
- const validation = handle?.validateDraft();
421
- const message =
422
- children ??
423
- validation?.formErrors[0] ??
424
- Object.values(validation?.fieldErrors ?? {})[0]?.[0] ??
425
- (validation?.missing[0]
426
- ? `${String(validation.missing[0])} is required.`
427
- : null);
428
- if (!message) return null;
429
- return renderPrimitive("span", {
430
- ...props,
431
- "data-dreamboard-interaction-validation": "",
432
- children: message,
433
- });
434
- }
435
-
436
- export type InteractionTriggerProps = PrimitiveCommonProps &
437
- ButtonHTMLAttributes<HTMLButtonElement>;
438
-
439
- export function InteractionTrigger({
440
- disabled,
441
- onClick,
442
- ...props
443
- }: InteractionTriggerProps) {
444
- const { descriptor, handle } = useInteractionPrimitiveContext();
445
- const available = isInteractionAvailable(descriptor);
446
- const isDisabled = disabled === true || !available;
447
- return renderPrimitive("button", {
448
- type: "button",
449
- ...props,
450
- disabled: isDisabled,
451
- "aria-disabled": isDisabled,
452
- "data-dreamboard-interaction-trigger": "",
453
- "data-interaction-id": descriptor?.interactionId,
454
- "data-interaction-key": descriptor?.interactionKey,
455
- "data-available": available,
456
- "data-disabled": isDisabled || undefined,
457
- "data-state": handle?.isArmed ? "armed" : "idle",
458
- onClick: composeEventHandlers(onClick, () => {
459
- handle?.arm();
460
- }),
461
- });
462
- }
463
-
464
- export interface InteractionStateSnapshot<
465
- Params extends InteractionParamsShape = InteractionParamsShape,
466
- DefaultedKeys extends keyof Params & string = never,
467
- > {
468
- interaction: string;
469
- descriptor: InteractionDescriptor;
470
- handle: InteractionHandle<Params, DefaultedKeys>;
471
- draft: InteractionHandle<Params, DefaultedKeys>["draft"];
472
- values: InteractionHandle<Params, DefaultedKeys>["values"];
473
- status: InteractionHandle<Params, DefaultedKeys>["status"];
474
- available: boolean;
475
- isReady: boolean;
476
- isArmed: boolean;
477
- inputKeys: readonly string[];
478
- missingInputs: readonly string[];
479
- readyFrontier: readonly string[];
480
- blockedInputs: readonly string[];
481
- hasInputs: boolean;
482
- }
483
-
484
- export interface InteractionStateProps<
485
- Params extends InteractionParamsShape = InteractionParamsShape,
486
- DefaultedKeys extends keyof Params & string = never,
487
- > {
488
- unavailable: ReactNode;
489
- children: (
490
- state: InteractionStateSnapshot<Params, DefaultedKeys>,
491
- ) => ReactNode;
492
- }
493
-
494
- export function InteractionState<
495
- Params extends InteractionParamsShape = InteractionParamsShape,
496
- DefaultedKeys extends keyof Params & string = never,
497
- >({ children, unavailable }: InteractionStateProps<Params, DefaultedKeys>) {
498
- const { interaction, descriptor, handle } = useInteractionPrimitiveContext();
499
- const store = useInteractionUiStore();
500
- if (!descriptor || !handle) {
501
- return <>{unavailable}</>;
502
- }
503
- const typedHandle = castInteractionHandle<Params, DefaultedKeys>(handle);
504
- const liveDraft = castInteractionDraft<Params, DefaultedKeys>(
505
- store.getDraft(descriptor.interactionKey),
506
- );
507
- const inputKeys = descriptor.inputs.map((input) => input.key);
508
- const readiness = getInteractionDraftReadiness(descriptor, liveDraft);
509
- return (
510
- <>
511
- {children({
512
- interaction,
513
- descriptor,
514
- handle: typedHandle,
515
- draft: liveDraft,
516
- values: typedHandle.values,
517
- status: typedHandle.status,
518
- available: typedHandle.available,
519
- isReady: readiness.ready,
520
- isArmed: typedHandle.isArmed,
521
- inputKeys,
522
- missingInputs: readiness.missingInputs,
523
- readyFrontier: readiness.readyFrontier,
524
- blockedInputs: readiness.blockedInputs,
525
- hasInputs: inputKeys.length > 0,
526
- })}
527
- </>
528
- );
529
- }
530
-
531
- export type InteractionFormPrimitiveProps<
532
- Params extends InteractionParamsShape = InteractionParamsShape,
533
- DefaultedKeys extends keyof Params & string = never,
534
- > = BoundInteractionFormProps<Params, DefaultedKeys>;
535
-
536
- export function InteractionFormPrimitive<
537
- Params extends InteractionParamsShape = InteractionParamsShape,
538
- DefaultedKeys extends keyof Params & string = never,
539
- >(props: InteractionFormPrimitiveProps<Params, DefaultedKeys>) {
540
- const { descriptor, handle } = useInteractionPrimitiveContext();
541
- if (!descriptor || !handle) return null;
542
- return (
543
- <BoundInteractionForm<Params, DefaultedKeys>
544
- descriptor={descriptor}
545
- handle={handle}
546
- {...props}
547
- />
548
- );
549
- }
550
-
551
- export type InteractionFieldPrimitiveProps<
552
- Params extends InteractionParamsShape = InteractionParamsShape,
553
- Input extends keyof Params & string = keyof Params & string,
554
- > = Omit<
555
- BaseInteractionFieldProps<Params, Input>,
556
- "descriptor" | "handle" | "inputKey"
557
- > & {
558
- input: Input;
559
- };
560
-
561
- export function InteractionFieldPrimitive<
562
- Params extends InteractionParamsShape = InteractionParamsShape,
563
- Input extends keyof Params & string = keyof Params & string,
564
- >({ input, ...props }: InteractionFieldPrimitiveProps<Params, Input>) {
565
- const { descriptor, handle } = useInteractionPrimitiveContext();
566
- if (!descriptor || !handle) return null;
567
- return (
568
- <BaseInteractionField<Params, Input>
569
- descriptor={descriptor}
570
- handle={castInteractionHandle<Params>(handle)}
571
- inputKey={input}
572
- {...props}
573
- />
574
- );
575
- }
576
-
577
- export type InteractionSubmitProps = PrimitiveCommonProps &
578
- ButtonHTMLAttributes<HTMLButtonElement> & {
579
- params?:
580
- | InteractionParamsShape
581
- | (() => InteractionParamsShape | null | undefined);
582
- onSubmitSuccess?: InteractionSubmitCallbacks["onSubmitSuccess"];
583
- onSubmitError?: InteractionSubmitCallbacks["onSubmitError"];
584
- };
585
-
586
- export function InteractionSubmit({
587
- disabled,
588
- onClick,
589
- params,
590
- onSubmitSuccess,
591
- onSubmitError,
592
- ...props
593
- }: InteractionSubmitProps) {
594
- const { descriptor, handle } = useInteractionPrimitiveContext();
595
- const gameActionError = useGameActionError();
596
- const isSubmitting = handle?.status === "submitting";
597
- const hasExplicitParams = params !== undefined;
598
- const available = isInteractionAvailable(descriptor);
599
- const isDisabled =
600
- disabled === true ||
601
- !available ||
602
- (!hasExplicitParams && !handle?.isReady) ||
603
- isSubmitting;
604
- return renderPrimitive("button", {
605
- type: "button",
606
- ...props,
607
- disabled: isDisabled,
608
- "aria-disabled": isDisabled,
609
- "data-dreamboard-interaction-submit": "",
610
- "data-interaction-id": descriptor?.interactionId,
611
- "data-interaction-key": descriptor?.interactionKey,
612
- "data-available": available,
613
- "data-disabled": isDisabled || undefined,
614
- "data-ready": handle?.isReady ?? false,
615
- "data-has-inputs": descriptor ? descriptor.inputs.length > 0 : undefined,
616
- "data-input-count": descriptor?.inputs.length,
617
- "data-submitting": isSubmitting || undefined,
618
- "data-state": handle?.status ?? "unavailable",
619
- onClick: composeEventHandlers(onClick, () => {
620
- if (isDisabled || !handle) return;
621
- const resolvedParams = typeof params === "function" ? params() : params;
622
- if (resolvedParams === null || resolvedParams === undefined) {
623
- void submitInteractionDraft(handle, {
624
- onSubmitSuccess,
625
- onSubmitError: onSubmitError ?? gameActionError ?? undefined,
626
- });
627
- return;
628
- }
629
- void submitInteractionParams(handle, resolvedParams, {
630
- onSubmitSuccess,
631
- onSubmitError: onSubmitError ?? gameActionError ?? undefined,
632
- });
633
- }),
634
- });
635
- }
636
-
637
- export type InteractionInputProps = PrimitiveCommonProps &
638
- Omit<InputHTMLAttributes<HTMLInputElement>, "name"> & {
639
- name: string;
640
- parse?: (value: string) => unknown;
641
- };
642
-
643
- export function InteractionInput({
644
- name,
645
- parse,
646
- onChange,
647
- disabled,
648
- ...props
649
- }: InteractionInputProps) {
650
- const { descriptor, handle } = useInteractionPrimitiveContext();
651
- const value = handle?.draft[name];
652
- const isDisabled = disabled === true || !isInteractionAvailable(descriptor);
653
- return renderPrimitive("input", {
654
- ...props,
655
- name,
656
- disabled: isDisabled,
657
- "aria-disabled": isDisabled,
658
- "data-dreamboard-interaction-input": "",
659
- "data-input-name": name,
660
- "data-disabled": isDisabled || undefined,
661
- "data-selected": value !== undefined || undefined,
662
- onChange: composeEventHandlers(onChange, (event) => {
663
- const target = event.currentTarget;
664
- handle?.setInput(name, parse ? parse(target.value) : target.value);
665
- }),
666
- });
667
- }
668
-
669
- export type InteractionCardInputProps<
670
- Input extends string = InteractionInputKey,
671
- > = PrimitiveCommonProps &
672
- Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children"> & {
673
- input: Input;
674
- unsafeCardId?: string;
675
- selected?: boolean;
676
- onSelectedChange?: (selected: boolean) => void;
677
- children?:
678
- | ReactNode
679
- | ((state: InteractionCardInputRenderState) => ReactNode);
680
- };
681
-
682
- export interface InteractionCardInputRenderState {
683
- cardId: string | undefined;
684
- zone: string | undefined;
685
- selected: boolean;
686
- disabled: boolean;
687
- eligible: boolean;
688
- targetValid: boolean;
689
- selectable: boolean;
690
- cardAvailable: boolean;
691
- invalid: boolean;
692
- }
693
-
694
- export function InteractionCardInput<
695
- Input extends string = InteractionInputKey,
696
- >({
697
- input,
698
- unsafeCardId,
699
- selected,
700
- onSelectedChange,
701
- onClick,
702
- disabled,
703
- children,
704
- ...props
705
- }: InteractionCardInputProps<Input>) {
706
- const { descriptor, handle } = useInteractionPrimitiveContext();
707
- const store = useInteractionUiStore();
708
- const zoneCard = useZoneCardContext();
709
- const zoneContext = useOptionalZonePrimitiveContext();
710
- const cardId = zoneCard?.cardId ?? unsafeCardId;
711
- const validationZone = zoneCard?.zone ?? zoneContext?.zone;
712
- const zoneSnapshot = usePluginState((state) =>
713
- validationZone ? state.gameplay.zones[validationZone] : undefined,
714
- );
715
- const cardDescriptor = usePluginState((state) => {
716
- if (!cardId || !validationZone) return undefined;
717
- return state.gameplay.zones[validationZone]?.playableByCardId[cardId]?.find(
718
- (candidate) =>
719
- candidate.interactionKey === descriptor?.interactionKey &&
720
- candidate.inputs.some((candidateInput) => candidateInput.key === input),
721
- );
722
- });
723
- const inputDescriptor = descriptor
724
- ? inputByKey(descriptor, input)
725
- : undefined;
726
- const targetInvalidReason = cardTargetInvalidReason({
727
- cardDescriptor,
728
- cardId,
729
- inputDescriptor,
730
- unsafeCardId,
731
- validationZone,
732
- zoneCard,
733
- zoneSnapshot,
734
- });
735
- const isTargetValid = targetInvalidReason === undefined;
736
- throwCardInputDevMismatch({
737
- cardId,
738
- targetInvalidReason,
739
- unsafeCardId,
740
- validationZone,
741
- zoneCard,
742
- });
743
- const liveDraft = descriptor ? store.getDraft(descriptor.interactionKey) : {};
744
- const currentValue =
745
- liveDraft[input] ?? handle?.draft[input] ?? handle?.values[input];
746
- const selection = isTargetDomain(inputDescriptor?.domain)
747
- ? inputDescriptor.domain.selection
748
- : undefined;
749
- const selectedByDraft =
750
- selection?.mode === "many"
751
- ? Array.isArray(currentValue) &&
752
- currentValue.map((item) => String(item)).includes(String(cardId))
753
- : currentValue !== undefined &&
754
- cardId !== undefined &&
755
- String(currentValue) === String(cardId);
756
- const isSelected = selected ?? selectedByDraft;
757
- const descriptorAvailable = isInteractionAvailable(descriptor);
758
- const cardDescriptorAvailable =
759
- cardDescriptor === undefined
760
- ? undefined
761
- : isInteractionAvailable(cardDescriptor);
762
- const isCardAvailable =
763
- cardDescriptorAvailable ?? (isTargetValid && descriptorAvailable);
764
- const cardUnavailableReason =
765
- interactionUnavailableReason(cardDescriptor) ??
766
- (!descriptorAvailable
767
- ? (interactionUnavailableReason(descriptor) ?? "interaction-unavailable")
768
- : undefined);
769
- const isSelectable =
770
- cardId !== undefined &&
771
- inputDescriptor !== undefined &&
772
- isManyTargetSelectable(inputDescriptor, currentValue, cardId);
773
- const validation = handle?.validateDraft();
774
- const fieldErrors = validation?.fieldErrors[input] ?? [];
775
- const isInvalid = fieldErrors.length > 0;
776
- const isDisabled =
777
- disabled === true ||
778
- !descriptorAvailable ||
779
- !cardId ||
780
- !isTargetValid ||
781
- !isCardAvailable ||
782
- !isSelectable ||
783
- !handle;
784
-
785
- const activateCardInput = useCallback(() => {
786
- if (isDisabled || !descriptor || !cardId || !handle || !inputDescriptor) {
787
- return;
788
- }
789
- const { params, readiness } = routeCardInputIntent(store, descriptor, {
790
- cardInputKey: input,
791
- cardId,
792
- });
793
- const hasMissingSurfaceTarget = readiness.readyFrontier.some((key) => {
794
- const candidate = inputByKey(descriptor, key);
795
- return (
796
- candidate !== undefined &&
797
- isBoardTargetDomain(candidate.domain) &&
798
- candidate.domain.selection?.mode !== "many"
799
- );
800
- });
801
- const hasMissingFormInput = readiness.readyFrontier.some((key) => {
802
- const candidate = inputByKey(descriptor, key);
803
- return (
804
- candidate !== undefined &&
805
- (!isTargetDomain(candidate.domain) ||
806
- candidate.domain.selection?.mode === "many")
807
- );
808
- });
809
- const hasFieldErrors = hasInteractionFieldErrors(readiness.fieldErrors);
810
- if (shouldRouteInteractionPending(descriptor, readiness)) {
811
- markInteractionPending(store, descriptor);
812
- store.setPendingInteraction(
813
- !hasMissingSurfaceTarget && (hasMissingFormInput || hasFieldErrors)
814
- ? descriptor.interactionKey
815
- : null,
816
- );
817
- }
818
- onSelectedChange?.(
819
- selection?.mode === "many"
820
- ? Array.isArray(params[input]) && params[input].includes(cardId)
821
- : true,
822
- );
823
- }, [
824
- cardId,
825
- descriptor,
826
- handle,
827
- input,
828
- inputDescriptor,
829
- isDisabled,
830
- onSelectedChange,
831
- selection,
832
- store,
833
- ]);
834
-
835
- const renderState: InteractionCardInputRenderState = {
836
- cardId,
837
- zone: validationZone,
838
- selected: isSelected,
839
- disabled: isDisabled,
840
- eligible: isTargetValid && isCardAvailable,
841
- targetValid: isTargetValid,
842
- selectable: isSelectable,
843
- cardAvailable: isCardAvailable,
844
- invalid: isInvalid,
845
- };
846
- const renderedChildren =
847
- typeof children === "function" ? children(renderState) : children;
848
-
849
- return renderPrimitive("button", {
850
- type: "button",
851
- ...props,
852
- children: renderedChildren,
853
- disabled: isDisabled,
854
- "aria-disabled": isDisabled,
855
- "aria-pressed": isSelected,
856
- "data-dreamboard-interaction-card-input": "",
857
- "data-input-name": input,
858
- "data-card-id": cardId,
859
- "data-zone": validationZone,
860
- "data-selected": isSelected || undefined,
861
- "data-eligible": isTargetValid && isCardAvailable,
862
- "data-target-valid": isTargetValid,
863
- "data-target-invalid-reason": targetInvalidReason,
864
- "data-selectable": isSelectable,
865
- "data-card-available": isCardAvailable,
866
- "data-card-unavailable-reason": cardUnavailableReason,
867
- "data-invalid": isInvalid || undefined,
868
- "data-disabled": isDisabled || undefined,
869
- "data-missing-resource": cardId ? undefined : true,
870
- onClick: composeEventHandlers(onClick, () => {
871
- activateCardInput();
872
- }),
873
- });
874
- }
875
-
876
- type CardTargetInvalidReason =
877
- | "missing-card"
878
- | "wrong-zone"
879
- | "not-in-zone"
880
- | "not-top-card"
881
- | "not-in-domain";
882
-
883
- function cardTargetInvalidReason({
884
- cardDescriptor,
885
- cardId,
886
- inputDescriptor,
887
- unsafeCardId,
888
- validationZone,
889
- zoneCard,
890
- zoneSnapshot,
891
- }: {
892
- cardDescriptor: InteractionDescriptor | undefined;
893
- cardId: string | undefined;
894
- inputDescriptor: InteractionInputDescriptor | undefined;
895
- unsafeCardId: string | undefined;
896
- validationZone: string | undefined;
897
- zoneCard: ReturnType<typeof useZoneCardContext>;
898
- zoneSnapshot: ZoneHandlesSnapshot | undefined;
899
- }): CardTargetInvalidReason | undefined {
900
- if (!cardId) return "missing-card";
901
- if (inputDescriptor?.domain.type !== "cardTarget") {
902
- return "not-in-domain";
903
- }
904
- if (zoneCard && unsafeCardId && unsafeCardId !== zoneCard.cardId) {
905
- return "wrong-zone";
906
- }
907
- if (
908
- validationZone &&
909
- zoneSnapshot &&
910
- !zoneSnapshot.cardIds.includes(cardId)
911
- ) {
912
- return "not-in-zone";
913
- }
914
- if (
915
- validationZone &&
916
- inputDescriptor.domain.zoneIds &&
917
- !inputDescriptor.domain.zoneIds.includes(validationZone)
918
- ) {
919
- return "wrong-zone";
920
- }
921
- if (validationZone && !cardDescriptor) {
922
- return zoneSnapshot?.cardIds[0] !== cardId
923
- ? "not-top-card"
924
- : "not-in-domain";
925
- }
926
- if (
927
- !zoneCard &&
928
- isResolvedTargetDomain(inputDescriptor.domain) &&
929
- !inputDescriptor.domain.eligibleTargets.includes(cardId)
930
- ) {
931
- return "not-in-domain";
932
- }
933
- return undefined;
934
- }
935
-
936
- function throwCardInputDevMismatch({
937
- cardId,
938
- targetInvalidReason,
939
- unsafeCardId,
940
- validationZone,
941
- zoneCard,
942
- }: {
943
- cardId: string | undefined;
944
- targetInvalidReason: CardTargetInvalidReason | undefined;
945
- unsafeCardId: string | undefined;
946
- validationZone: string | undefined;
947
- zoneCard: ReturnType<typeof useZoneCardContext>;
948
- }) {
949
- if (!isDevelopmentRuntime() || !validationZone) return;
950
- if (zoneCard && unsafeCardId && unsafeCardId !== zoneCard.cardId) {
951
- throw new Error(
952
- `Interaction.CardInput unsafeCardId '${unsafeCardId}' does not match surrounding Zone.Item card '${zoneCard.cardId}'.`,
953
- );
954
- }
955
- if (targetInvalidReason === "not-in-zone" && cardId) {
956
- throw new Error(
957
- `Interaction.CardInput card '${cardId}' is not present in surrounding zone '${validationZone}'.`,
958
- );
959
- }
960
- }
961
-
962
- function isDevelopmentRuntime(): boolean {
963
- const processLike = (
964
- globalThis as {
965
- process?: { env?: { NODE_ENV?: string } };
966
- }
967
- ).process;
968
- return processLike?.env?.NODE_ENV !== "production";
969
- }
970
-
971
- export const Interaction = {
972
- Root: InteractionRoot,
973
- State: InteractionState,
974
- Switch: InteractionSwitch,
975
- Routes: InteractionRoutes,
976
- Dialog: InteractionDialog,
977
- Trigger: InteractionTrigger,
978
- Label: InteractionLabel,
979
- Description: InteractionDescription,
980
- UnavailableMessage: InteractionUnavailableMessage,
981
- ValidationMessage: InteractionValidationMessage,
982
- Input: InteractionInput,
983
- Field: InteractionFieldPrimitive,
984
- CardInput: InteractionCardInput,
985
- Form: InteractionFormPrimitive,
986
- Submit: InteractionSubmit,
987
- };