@dreamboard-games/ui-sdk 0.0.41

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 (533) hide show
  1. package/LICENSE +89 -0
  2. package/NOTICE +1 -0
  3. package/README.md +154 -0
  4. package/dist/components/ActionButton.d.ts +13 -0
  5. package/dist/components/ActionButton.d.ts.map +1 -0
  6. package/dist/components/ActionButton.js +14 -0
  7. package/dist/components/ActionPanel.d.ts +33 -0
  8. package/dist/components/ActionPanel.d.ts.map +1 -0
  9. package/dist/components/ActionPanel.js +148 -0
  10. package/dist/components/Card.d.ts +29 -0
  11. package/dist/components/Card.d.ts.map +1 -0
  12. package/dist/components/Card.js +220 -0
  13. package/dist/components/ChromeSuppressionContext.d.ts +7 -0
  14. package/dist/components/ChromeSuppressionContext.d.ts.map +1 -0
  15. package/dist/components/ChromeSuppressionContext.js +34 -0
  16. package/dist/components/CostDisplay.d.ts +22 -0
  17. package/dist/components/CostDisplay.d.ts.map +1 -0
  18. package/dist/components/CostDisplay.js +41 -0
  19. package/dist/components/DiceRoller.d.ts +30 -0
  20. package/dist/components/DiceRoller.d.ts.map +1 -0
  21. package/dist/components/DiceRoller.js +319 -0
  22. package/dist/components/Drawer.d.ts +19 -0
  23. package/dist/components/Drawer.d.ts.map +1 -0
  24. package/dist/components/Drawer.js +55 -0
  25. package/dist/components/ErrorBoundary.d.ts +24 -0
  26. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  27. package/dist/components/ErrorBoundary.js +37 -0
  28. package/dist/components/GameEndDisplay.d.ts +27 -0
  29. package/dist/components/GameEndDisplay.d.ts.map +1 -0
  30. package/dist/components/GameEndDisplay.js +185 -0
  31. package/dist/components/GameSkeleton.d.ts +12 -0
  32. package/dist/components/GameSkeleton.d.ts.map +1 -0
  33. package/dist/components/GameSkeleton.js +54 -0
  34. package/dist/components/Hand.d.ts +99 -0
  35. package/dist/components/Hand.d.ts.map +1 -0
  36. package/dist/components/Hand.js +162 -0
  37. package/dist/components/HandDock.d.ts +35 -0
  38. package/dist/components/HandDock.d.ts.map +1 -0
  39. package/dist/components/HandDock.js +124 -0
  40. package/dist/components/InteractionForm.d.ts +50 -0
  41. package/dist/components/InteractionForm.d.ts.map +1 -0
  42. package/dist/components/InteractionForm.js +402 -0
  43. package/dist/components/MoreActions.d.ts +49 -0
  44. package/dist/components/MoreActions.d.ts.map +1 -0
  45. package/dist/components/MoreActions.js +64 -0
  46. package/dist/components/PhaseIndicator.d.ts +35 -0
  47. package/dist/components/PhaseIndicator.d.ts.map +1 -0
  48. package/dist/components/PhaseIndicator.js +212 -0
  49. package/dist/components/PlayArea.d.ts +28 -0
  50. package/dist/components/PlayArea.d.ts.map +1 -0
  51. package/dist/components/PlayArea.js +48 -0
  52. package/dist/components/PluginRuntime.d.ts +37 -0
  53. package/dist/components/PluginRuntime.d.ts.map +1 -0
  54. package/dist/components/PluginRuntime.js +47 -0
  55. package/dist/components/PrimaryActionButton.d.ts +98 -0
  56. package/dist/components/PrimaryActionButton.d.ts.map +1 -0
  57. package/dist/components/PrimaryActionButton.js +183 -0
  58. package/dist/components/PrimaryButton.d.ts +20 -0
  59. package/dist/components/PrimaryButton.d.ts.map +1 -0
  60. package/dist/components/PrimaryButton.js +5 -0
  61. package/dist/components/PromptDialogHost.d.ts +15 -0
  62. package/dist/components/PromptDialogHost.d.ts.map +1 -0
  63. package/dist/components/PromptDialogHost.js +22 -0
  64. package/dist/components/ResourceCounter.d.ts +38 -0
  65. package/dist/components/ResourceCounter.d.ts.map +1 -0
  66. package/dist/components/ResourceCounter.js +118 -0
  67. package/dist/components/ThemedButton.d.ts +12 -0
  68. package/dist/components/ThemedButton.d.ts.map +1 -0
  69. package/dist/components/ThemedButton.js +38 -0
  70. package/dist/components/Toast.d.ts +35 -0
  71. package/dist/components/Toast.d.ts.map +1 -0
  72. package/dist/components/Toast.js +116 -0
  73. package/dist/components/board/HexGrid.d.ts +344 -0
  74. package/dist/components/board/HexGrid.d.ts.map +1 -0
  75. package/dist/components/board/HexGrid.js +340 -0
  76. package/dist/components/board/NetworkGraph.d.ts +100 -0
  77. package/dist/components/board/NetworkGraph.d.ts.map +1 -0
  78. package/dist/components/board/NetworkGraph.js +123 -0
  79. package/dist/components/board/SlotSystem.d.ts +71 -0
  80. package/dist/components/board/SlotSystem.d.ts.map +1 -0
  81. package/dist/components/board/SlotSystem.js +87 -0
  82. package/dist/components/board/SquareGrid.d.ts +188 -0
  83. package/dist/components/board/SquareGrid.d.ts.map +1 -0
  84. package/dist/components/board/SquareGrid.js +328 -0
  85. package/dist/components/board/TrackBoard.d.ts +113 -0
  86. package/dist/components/board/TrackBoard.d.ts.map +1 -0
  87. package/dist/components/board/TrackBoard.js +135 -0
  88. package/dist/components/board/ZoneMap.d.ts +88 -0
  89. package/dist/components/board/ZoneMap.d.ts.map +1 -0
  90. package/dist/components/board/ZoneMap.js +133 -0
  91. package/dist/components/board/hex-board-view.d.ts +69 -0
  92. package/dist/components/board/hex-board-view.d.ts.map +1 -0
  93. package/dist/components/board/hex-board-view.js +60 -0
  94. package/dist/components/board/index.d.ts +23 -0
  95. package/dist/components/board/index.d.ts.map +1 -0
  96. package/dist/components/board/index.js +40 -0
  97. package/dist/components/board/interaction-accessibility.d.ts +5 -0
  98. package/dist/components/board/interaction-accessibility.d.ts.map +1 -0
  99. package/dist/components/board/interaction-accessibility.js +13 -0
  100. package/dist/components/board/target-layer.d.ts +13 -0
  101. package/dist/components/board/target-layer.d.ts.map +1 -0
  102. package/dist/components/board/target-layer.js +10 -0
  103. package/dist/components/card-render-content.type-test.d.ts +2 -0
  104. package/dist/components/card-render-content.type-test.d.ts.map +1 -0
  105. package/dist/components/card-render-content.type-test.js +1 -0
  106. package/dist/components/index.d.ts +34 -0
  107. package/dist/components/index.d.ts.map +1 -0
  108. package/dist/components/index.js +35 -0
  109. package/dist/components/interaction-dialog-behavior.d.ts +15 -0
  110. package/dist/components/interaction-dialog-behavior.d.ts.map +1 -0
  111. package/dist/components/interaction-dialog-behavior.js +9 -0
  112. package/dist/components/surfaces/BlockerSurface.d.ts +27 -0
  113. package/dist/components/surfaces/BlockerSurface.d.ts.map +1 -0
  114. package/dist/components/surfaces/BlockerSurface.js +38 -0
  115. package/dist/components/surfaces/BoardSurface.d.ts +77 -0
  116. package/dist/components/surfaces/BoardSurface.d.ts.map +1 -0
  117. package/dist/components/surfaces/BoardSurface.js +180 -0
  118. package/dist/components/surfaces/ChromeSurface.d.ts +29 -0
  119. package/dist/components/surfaces/ChromeSurface.d.ts.map +1 -0
  120. package/dist/components/surfaces/ChromeSurface.js +34 -0
  121. package/dist/components/surfaces/ExhaustivenessAudit.d.ts +32 -0
  122. package/dist/components/surfaces/ExhaustivenessAudit.d.ts.map +1 -0
  123. package/dist/components/surfaces/ExhaustivenessAudit.js +65 -0
  124. package/dist/components/surfaces/InboxSurface.d.ts +40 -0
  125. package/dist/components/surfaces/InboxSurface.d.ts.map +1 -0
  126. package/dist/components/surfaces/InboxSurface.js +99 -0
  127. package/dist/components/surfaces/MarketSurface.d.ts +62 -0
  128. package/dist/components/surfaces/MarketSurface.d.ts.map +1 -0
  129. package/dist/components/surfaces/MarketSurface.js +242 -0
  130. package/dist/components/surfaces/PanelSurface.d.ts +111 -0
  131. package/dist/components/surfaces/PanelSurface.d.ts.map +1 -0
  132. package/dist/components/surfaces/PanelSurface.js +180 -0
  133. package/dist/components/surfaces/PlayerCardsSurface.d.ts +104 -0
  134. package/dist/components/surfaces/PlayerCardsSurface.d.ts.map +1 -0
  135. package/dist/components/surfaces/PlayerCardsSurface.js +178 -0
  136. package/dist/components/surfaces/internal/CardZoneFollowUpForm.d.ts +7 -0
  137. package/dist/components/surfaces/internal/CardZoneFollowUpForm.d.ts.map +1 -0
  138. package/dist/components/surfaces/internal/CardZoneFollowUpForm.js +9 -0
  139. package/dist/components/surfaces/internal/DefaultInteractionButton.d.ts +71 -0
  140. package/dist/components/surfaces/internal/DefaultInteractionButton.d.ts.map +1 -0
  141. package/dist/components/surfaces/internal/DefaultInteractionButton.js +82 -0
  142. package/dist/components/surfaces/internal/useCardZoneInteractions.d.ts +21 -0
  143. package/dist/components/surfaces/internal/useCardZoneInteractions.d.ts.map +1 -0
  144. package/dist/components/surfaces/internal/useCardZoneInteractions.js +202 -0
  145. package/dist/components/surfaces/types.d.ts +59 -0
  146. package/dist/components/surfaces/types.d.ts.map +1 -0
  147. package/dist/components/surfaces/types.js +1 -0
  148. package/dist/context/ClientParamSchemaContext.d.ts +21 -0
  149. package/dist/context/ClientParamSchemaContext.d.ts.map +1 -0
  150. package/dist/context/ClientParamSchemaContext.js +12 -0
  151. package/dist/context/InteractionDraftContext.d.ts +69 -0
  152. package/dist/context/InteractionDraftContext.d.ts.map +1 -0
  153. package/dist/context/InteractionDraftContext.js +145 -0
  154. package/dist/context/PluginSessionContext.d.ts +33 -0
  155. package/dist/context/PluginSessionContext.d.ts.map +1 -0
  156. package/dist/context/PluginSessionContext.js +38 -0
  157. package/dist/context/PluginStateContext.d.ts +116 -0
  158. package/dist/context/PluginStateContext.d.ts.map +1 -0
  159. package/dist/context/PluginStateContext.js +186 -0
  160. package/dist/context/RuntimeContext.d.ts +49 -0
  161. package/dist/context/RuntimeContext.d.ts.map +1 -0
  162. package/dist/context/RuntimeContext.js +67 -0
  163. package/dist/defaults/components.d.ts +52 -0
  164. package/dist/defaults/components.d.ts.map +1 -0
  165. package/dist/defaults/components.js +159 -0
  166. package/dist/defaults/index.d.ts +2 -0
  167. package/dist/defaults/index.d.ts.map +1 -0
  168. package/dist/defaults/index.js +1 -0
  169. package/dist/errors/ValidationError.d.ts +10 -0
  170. package/dist/errors/ValidationError.d.ts.map +1 -0
  171. package/dist/errors/ValidationError.js +23 -0
  172. package/dist/helpers/cards.d.ts +3 -0
  173. package/dist/helpers/cards.d.ts.map +1 -0
  174. package/dist/helpers/cards.js +11 -0
  175. package/dist/helpers/track-board.d.ts +79 -0
  176. package/dist/helpers/track-board.d.ts.map +1 -0
  177. package/dist/helpers/track-board.js +56 -0
  178. package/dist/hooks/useActivePlayers.d.ts +16 -0
  179. package/dist/hooks/useActivePlayers.d.ts.map +1 -0
  180. package/dist/hooks/useActivePlayers.js +17 -0
  181. package/dist/hooks/useBoardInteractions.d.ts +110 -0
  182. package/dist/hooks/useBoardInteractions.d.ts.map +1 -0
  183. package/dist/hooks/useBoardInteractions.js +248 -0
  184. package/dist/hooks/useBoardTopology.d.ts +23 -0
  185. package/dist/hooks/useBoardTopology.d.ts.map +1 -0
  186. package/dist/hooks/useBoardTopology.js +128 -0
  187. package/dist/hooks/useCards.d.ts +3 -0
  188. package/dist/hooks/useCards.d.ts.map +1 -0
  189. package/dist/hooks/useCards.js +5 -0
  190. package/dist/hooks/useGameSelector.d.ts +13 -0
  191. package/dist/hooks/useGameSelector.d.ts.map +1 -0
  192. package/dist/hooks/useGameSelector.js +67 -0
  193. package/dist/hooks/useGameView.d.ts +6 -0
  194. package/dist/hooks/useGameView.d.ts.map +1 -0
  195. package/dist/hooks/useGameView.js +7 -0
  196. package/dist/hooks/useHandLayout.d.ts +120 -0
  197. package/dist/hooks/useHandLayout.d.ts.map +1 -0
  198. package/dist/hooks/useHandLayout.js +235 -0
  199. package/dist/hooks/useHexBoard.d.ts +19 -0
  200. package/dist/hooks/useHexBoard.d.ts.map +1 -0
  201. package/dist/hooks/useHexBoard.js +28 -0
  202. package/dist/hooks/useHexGrid.d.ts +56 -0
  203. package/dist/hooks/useHexGrid.d.ts.map +1 -0
  204. package/dist/hooks/useHexGrid.js +112 -0
  205. package/dist/hooks/useInteractionByKey.d.ts +29 -0
  206. package/dist/hooks/useInteractionByKey.d.ts.map +1 -0
  207. package/dist/hooks/useInteractionByKey.js +263 -0
  208. package/dist/hooks/useInteractionHandle.d.ts +103 -0
  209. package/dist/hooks/useInteractionHandle.d.ts.map +1 -0
  210. package/dist/hooks/useInteractionHandle.js +254 -0
  211. package/dist/hooks/useIsMobile.d.ts +7 -0
  212. package/dist/hooks/useIsMobile.d.ts.map +1 -0
  213. package/dist/hooks/useIsMobile.js +29 -0
  214. package/dist/hooks/useIsMyTurn.d.ts +6 -0
  215. package/dist/hooks/useIsMyTurn.d.ts.map +1 -0
  216. package/dist/hooks/useIsMyTurn.js +11 -0
  217. package/dist/hooks/useLobby.d.ts +28 -0
  218. package/dist/hooks/useLobby.d.ts.map +1 -0
  219. package/dist/hooks/useLobby.js +60 -0
  220. package/dist/hooks/useMe.d.ts +11 -0
  221. package/dist/hooks/useMe.d.ts.map +1 -0
  222. package/dist/hooks/useMe.js +32 -0
  223. package/dist/hooks/usePanZoom.d.ts +113 -0
  224. package/dist/hooks/usePanZoom.d.ts.map +1 -0
  225. package/dist/hooks/usePanZoom.js +165 -0
  226. package/dist/hooks/usePlayerInfo.d.ts +4 -0
  227. package/dist/hooks/usePlayerInfo.d.ts.map +1 -0
  228. package/dist/hooks/usePlayerInfo.js +21 -0
  229. package/dist/hooks/usePlayerTurnOrder.d.ts +15 -0
  230. package/dist/hooks/usePlayerTurnOrder.d.ts.map +1 -0
  231. package/dist/hooks/usePlayerTurnOrder.js +22 -0
  232. package/dist/hooks/usePluginRuntime.d.ts +45 -0
  233. package/dist/hooks/usePluginRuntime.d.ts.map +1 -0
  234. package/dist/hooks/usePluginRuntime.js +92 -0
  235. package/dist/hooks/useSeatInbox.d.ts +22 -0
  236. package/dist/hooks/useSeatInbox.d.ts.map +1 -0
  237. package/dist/hooks/useSeatInbox.js +43 -0
  238. package/dist/hooks/useSimultaneousPhase.d.ts +7 -0
  239. package/dist/hooks/useSimultaneousPhase.d.ts.map +1 -0
  240. package/dist/hooks/useSimultaneousPhase.js +8 -0
  241. package/dist/hooks/useSquareBoard.d.ts +21 -0
  242. package/dist/hooks/useSquareBoard.d.ts.map +1 -0
  243. package/dist/hooks/useSquareBoard.js +67 -0
  244. package/dist/hooks/useSquareGrid.d.ts +96 -0
  245. package/dist/hooks/useSquareGrid.d.ts.map +1 -0
  246. package/dist/hooks/useSquareGrid.js +152 -0
  247. package/dist/index.d.ts +30 -0
  248. package/dist/index.d.ts.map +1 -0
  249. package/dist/index.js +20 -0
  250. package/dist/internal/ui/alert.d.ts +8 -0
  251. package/dist/internal/ui/alert.d.ts.map +1 -0
  252. package/dist/internal/ui/alert.js +11 -0
  253. package/dist/internal/ui/button.d.ts +10 -0
  254. package/dist/internal/ui/button.d.ts.map +1 -0
  255. package/dist/internal/ui/button.js +21 -0
  256. package/dist/internal/ui/dialog.d.ts +16 -0
  257. package/dist/internal/ui/dialog.d.ts.map +1 -0
  258. package/dist/internal/ui/dialog.js +35 -0
  259. package/dist/internal/ui/input.d.ts +3 -0
  260. package/dist/internal/ui/input.d.ts.map +1 -0
  261. package/dist/internal/ui/input.js +5 -0
  262. package/dist/internal/ui/label.d.ts +4 -0
  263. package/dist/internal/ui/label.d.ts.map +1 -0
  264. package/dist/internal/ui/label.js +7 -0
  265. package/dist/internal/ui/select.d.ts +9 -0
  266. package/dist/internal/ui/select.d.ts.map +1 -0
  267. package/dist/internal/ui/select.js +23 -0
  268. package/dist/internal/ui/tooltip.d.ts +7 -0
  269. package/dist/internal/ui/tooltip.d.ts.map +1 -0
  270. package/dist/internal/ui/tooltip.js +16 -0
  271. package/dist/internal/ui/utils.d.ts +3 -0
  272. package/dist/internal/ui/utils.d.ts.map +1 -0
  273. package/dist/internal/ui/utils.js +4 -0
  274. package/dist/internal.d.ts +7 -0
  275. package/dist/internal.d.ts.map +1 -0
  276. package/dist/internal.js +4 -0
  277. package/dist/plugin-styles.css +246 -0
  278. package/dist/primitives/board.d.ts +29 -0
  279. package/dist/primitives/board.d.ts.map +1 -0
  280. package/dist/primitives/board.js +163 -0
  281. package/dist/primitives/game-ui-provider.d.ts +12 -0
  282. package/dist/primitives/game-ui-provider.d.ts.map +1 -0
  283. package/dist/primitives/game-ui-provider.js +7 -0
  284. package/dist/primitives/index.d.ts +8 -0
  285. package/dist/primitives/index.d.ts.map +1 -0
  286. package/dist/primitives/index.js +7 -0
  287. package/dist/primitives/interaction.d.ts +52 -0
  288. package/dist/primitives/interaction.d.ts.map +1 -0
  289. package/dist/primitives/interaction.js +250 -0
  290. package/dist/primitives/phase.d.ts +15 -0
  291. package/dist/primitives/phase.d.ts.map +1 -0
  292. package/dist/primitives/phase.js +18 -0
  293. package/dist/primitives/player-roster.d.ts +64 -0
  294. package/dist/primitives/player-roster.d.ts.map +1 -0
  295. package/dist/primitives/player-roster.js +149 -0
  296. package/dist/primitives/primitive-props.d.ts +15 -0
  297. package/dist/primitives/primitive-props.d.ts.map +1 -0
  298. package/dist/primitives/primitive-props.js +39 -0
  299. package/dist/primitives/prompt.d.ts +44 -0
  300. package/dist/primitives/prompt.d.ts.map +1 -0
  301. package/dist/primitives/prompt.js +101 -0
  302. package/dist/primitives/zone.d.ts +31 -0
  303. package/dist/primitives/zone.d.ts.map +1 -0
  304. package/dist/primitives/zone.js +58 -0
  305. package/dist/reducer.d.ts +21 -0
  306. package/dist/reducer.d.ts.map +1 -0
  307. package/dist/reducer.js +14 -0
  308. package/dist/runtime/createPluginRuntimeAPI.d.ts +67 -0
  309. package/dist/runtime/createPluginRuntimeAPI.d.ts.map +1 -0
  310. package/dist/runtime/createPluginRuntimeAPI.js +419 -0
  311. package/dist/theme/ThemeProvider.d.ts +98 -0
  312. package/dist/theme/ThemeProvider.d.ts.map +1 -0
  313. package/dist/theme/ThemeProvider.js +148 -0
  314. package/dist/theme/board.d.ts +42 -0
  315. package/dist/theme/board.d.ts.map +1 -0
  316. package/dist/theme/board.js +34 -0
  317. package/dist/theme/css-vars.d.ts +31 -0
  318. package/dist/theme/css-vars.d.ts.map +1 -0
  319. package/dist/theme/css-vars.js +88 -0
  320. package/dist/theme/derive.d.ts +66 -0
  321. package/dist/theme/derive.d.ts.map +1 -0
  322. package/dist/theme/derive.js +161 -0
  323. package/dist/theme/index.d.ts +22 -0
  324. package/dist/theme/index.d.ts.map +1 -0
  325. package/dist/theme/index.js +20 -0
  326. package/dist/theme/presets/arcade.d.ts +10 -0
  327. package/dist/theme/presets/arcade.d.ts.map +1 -0
  328. package/dist/theme/presets/arcade.js +257 -0
  329. package/dist/theme/presets/studio.d.ts +10 -0
  330. package/dist/theme/presets/studio.d.ts.map +1 -0
  331. package/dist/theme/presets/studio.js +257 -0
  332. package/dist/theme/presets/tabletop.d.ts +15 -0
  333. package/dist/theme/presets/tabletop.d.ts.map +1 -0
  334. package/dist/theme/presets/tabletop.js +262 -0
  335. package/dist/theme/tokens.d.ts +345 -0
  336. package/dist/theme/tokens.d.ts.map +1 -0
  337. package/dist/theme/tokens.js +57 -0
  338. package/dist/types/player-state.d.ts +337 -0
  339. package/dist/types/player-state.d.ts.map +1 -0
  340. package/dist/types/player-state.js +1 -0
  341. package/dist/types/plugin-state.d.ts +324 -0
  342. package/dist/types/plugin-state.d.ts.map +1 -0
  343. package/dist/types/plugin-state.js +1 -0
  344. package/dist/types/reducer-state.d.ts +10 -0
  345. package/dist/types/reducer-state.d.ts.map +1 -0
  346. package/dist/types/reducer-state.js +1 -0
  347. package/dist/types/runtime-api.d.ts +99 -0
  348. package/dist/types/runtime-api.d.ts.map +1 -0
  349. package/dist/types/runtime-api.js +1 -0
  350. package/dist/types/tiled-board.d.ts +187 -0
  351. package/dist/types/tiled-board.d.ts.map +1 -0
  352. package/dist/types/tiled-board.js +226 -0
  353. package/dist/ui-contract.d.ts +78 -0
  354. package/dist/ui-contract.d.ts.map +1 -0
  355. package/dist/ui-contract.js +15 -0
  356. package/dist/ui-sdk.d.ts +3409 -0
  357. package/dist/utils/interaction-inputs.d.ts +22 -0
  358. package/dist/utils/interaction-inputs.d.ts.map +1 -0
  359. package/dist/utils/interaction-inputs.js +219 -0
  360. package/dist/utils/interaction-labels.d.ts +4 -0
  361. package/dist/utils/interaction-labels.d.ts.map +1 -0
  362. package/dist/utils/interaction-labels.js +18 -0
  363. package/dist/utils/interaction-status.d.ts +15 -0
  364. package/dist/utils/interaction-status.d.ts.map +1 -0
  365. package/dist/utils/interaction-status.js +31 -0
  366. package/package.json +101 -0
  367. package/src/components/ActionButton.tsx +48 -0
  368. package/src/components/ActionPanel.tsx +310 -0
  369. package/src/components/Card.tsx +385 -0
  370. package/src/components/ChromeSuppressionContext.tsx +70 -0
  371. package/src/components/CostDisplay.test.tsx +23 -0
  372. package/src/components/CostDisplay.tsx +145 -0
  373. package/src/components/DiceRoller.tsx +601 -0
  374. package/src/components/Drawer.tsx +179 -0
  375. package/src/components/ErrorBoundary.tsx +119 -0
  376. package/src/components/GameEndDisplay.test.tsx +19 -0
  377. package/src/components/GameEndDisplay.tsx +398 -0
  378. package/src/components/GameSkeleton.tsx +260 -0
  379. package/src/components/Hand.tsx +387 -0
  380. package/src/components/HandDock.tsx +257 -0
  381. package/src/components/InteractionForm.test.tsx +303 -0
  382. package/src/components/InteractionForm.tsx +1029 -0
  383. package/src/components/MoreActions.test.tsx +93 -0
  384. package/src/components/MoreActions.tsx +143 -0
  385. package/src/components/PhaseIndicator.tsx +341 -0
  386. package/src/components/PlayArea.tsx +125 -0
  387. package/src/components/PluginRuntime.tsx +92 -0
  388. package/src/components/PrimaryActionButton.test.tsx +138 -0
  389. package/src/components/PrimaryActionButton.tsx +351 -0
  390. package/src/components/PrimaryButton.tsx +44 -0
  391. package/src/components/PromptDialogHost.tsx +92 -0
  392. package/src/components/ResourceCounter.test.tsx +29 -0
  393. package/src/components/ResourceCounter.tsx +275 -0
  394. package/src/components/ThemedButton.tsx +78 -0
  395. package/src/components/Toast.tsx +251 -0
  396. package/src/components/__fixtures__/ActionButton.fixture.tsx +234 -0
  397. package/src/components/__fixtures__/ActionPanel.fixture.tsx +298 -0
  398. package/src/components/__fixtures__/Card.fixture.tsx +185 -0
  399. package/src/components/__fixtures__/CostDisplay.fixture.tsx +156 -0
  400. package/src/components/__fixtures__/DiceRoller.fixture.tsx +435 -0
  401. package/src/components/__fixtures__/Drawer.fixture.tsx +113 -0
  402. package/src/components/__fixtures__/ErrorBoundary.fixture.tsx +82 -0
  403. package/src/components/__fixtures__/GameEndDisplay.fixture.tsx +188 -0
  404. package/src/components/__fixtures__/GameSkeleton.fixture.tsx +46 -0
  405. package/src/components/__fixtures__/Hand.fixture.tsx +522 -0
  406. package/src/components/__fixtures__/HexGrid.fixture.tsx +1181 -0
  407. package/src/components/__fixtures__/NetworkGraph.fixture.tsx +599 -0
  408. package/src/components/__fixtures__/PhaseIndicator.fixture.tsx +181 -0
  409. package/src/components/__fixtures__/PlayArea.fixture.tsx +221 -0
  410. package/src/components/__fixtures__/ResourceCounter.fixture.tsx +227 -0
  411. package/src/components/__fixtures__/SlotSystem.fixture.tsx +824 -0
  412. package/src/components/__fixtures__/SquareGrid.fixture.tsx +764 -0
  413. package/src/components/__fixtures__/Toast.fixture.tsx +97 -0
  414. package/src/components/__fixtures__/TrackBoard.fixture.tsx +685 -0
  415. package/src/components/__fixtures__/ZoneMap.fixture.tsx +754 -0
  416. package/src/components/board/HexGrid.tsx +1294 -0
  417. package/src/components/board/NetworkGraph.tsx +476 -0
  418. package/src/components/board/SlotSystem.tsx +339 -0
  419. package/src/components/board/SquareGrid.tsx +1165 -0
  420. package/src/components/board/TrackBoard.tsx +496 -0
  421. package/src/components/board/ZoneMap.tsx +448 -0
  422. package/src/components/board/hex-board-view.test.tsx +114 -0
  423. package/src/components/board/hex-board-view.ts +123 -0
  424. package/src/components/board/index.ts +142 -0
  425. package/src/components/board/interaction-accessibility.ts +21 -0
  426. package/src/components/board/target-layer-grids.test.tsx +420 -0
  427. package/src/components/board/target-layer.ts +30 -0
  428. package/src/components/card-render-content.type-test.ts +27 -0
  429. package/src/components/index.ts +208 -0
  430. package/src/components/interaction-dialog-behavior.test.ts +23 -0
  431. package/src/components/interaction-dialog-behavior.ts +22 -0
  432. package/src/components/surfaces/BlockerSurface.test.tsx +158 -0
  433. package/src/components/surfaces/BlockerSurface.tsx +127 -0
  434. package/src/components/surfaces/BoardSurface.tsx +340 -0
  435. package/src/components/surfaces/ChromeSurface.tsx +123 -0
  436. package/src/components/surfaces/ExhaustivenessAudit.tsx +91 -0
  437. package/src/components/surfaces/InboxSurface.test.tsx +149 -0
  438. package/src/components/surfaces/InboxSurface.tsx +245 -0
  439. package/src/components/surfaces/MarketSurface.tsx +544 -0
  440. package/src/components/surfaces/PanelSurface.test.tsx +496 -0
  441. package/src/components/surfaces/PanelSurface.tsx +458 -0
  442. package/src/components/surfaces/PlayerCardsSurface.tsx +525 -0
  443. package/src/components/surfaces/internal/CardZoneFollowUpForm.tsx +35 -0
  444. package/src/components/surfaces/internal/DefaultInteractionButton.tsx +219 -0
  445. package/src/components/surfaces/internal/useCardZoneInteractions.ts +311 -0
  446. package/src/components/surfaces/types.ts +100 -0
  447. package/src/context/ClientParamSchemaContext.tsx +44 -0
  448. package/src/context/InteractionDraftContext.tsx +204 -0
  449. package/src/context/PluginSessionContext.tsx +47 -0
  450. package/src/context/PluginStateContext.tsx +254 -0
  451. package/src/context/RuntimeContext.tsx +96 -0
  452. package/src/defaults/components.tsx +442 -0
  453. package/src/defaults/defaults.test.tsx +230 -0
  454. package/src/defaults/index.ts +1 -0
  455. package/src/errors/ValidationError.ts +29 -0
  456. package/src/helpers/cards.ts +19 -0
  457. package/src/helpers/track-board.ts +211 -0
  458. package/src/hooks/useActivePlayers.ts +19 -0
  459. package/src/hooks/useBoardInteractions.test.tsx +622 -0
  460. package/src/hooks/useBoardInteractions.ts +434 -0
  461. package/src/hooks/useBoardTopology.ts +316 -0
  462. package/src/hooks/useCards.test.tsx +129 -0
  463. package/src/hooks/useCards.ts +10 -0
  464. package/src/hooks/useGameSelector.ts +105 -0
  465. package/src/hooks/useGameView.ts +9 -0
  466. package/src/hooks/useHandLayout.ts +349 -0
  467. package/src/hooks/useHexBoard.ts +74 -0
  468. package/src/hooks/useHexGrid.ts +185 -0
  469. package/src/hooks/useInteractionByKey.ts +349 -0
  470. package/src/hooks/useInteractionHandle.ts +437 -0
  471. package/src/hooks/useIsMobile.ts +35 -0
  472. package/src/hooks/useIsMyTurn.test.tsx +99 -0
  473. package/src/hooks/useIsMyTurn.ts +15 -0
  474. package/src/hooks/useLobby.ts +76 -0
  475. package/src/hooks/useMe.ts +48 -0
  476. package/src/hooks/usePanZoom.ts +278 -0
  477. package/src/hooks/usePlayerInfo.ts +28 -0
  478. package/src/hooks/usePlayerTurnOrder.ts +23 -0
  479. package/src/hooks/usePluginRuntime.test.tsx +102 -0
  480. package/src/hooks/usePluginRuntime.ts +130 -0
  481. package/src/hooks/useSeatInbox.ts +61 -0
  482. package/src/hooks/useSimultaneousPhase.ts +10 -0
  483. package/src/hooks/useSquareBoard.ts +124 -0
  484. package/src/hooks/useSquareGrid.ts +328 -0
  485. package/src/index.test.ts +474 -0
  486. package/src/index.ts +148 -0
  487. package/src/internal/ui/alert.tsx +51 -0
  488. package/src/internal/ui/button.tsx +58 -0
  489. package/src/internal/ui/dialog.tsx +134 -0
  490. package/src/internal/ui/input.tsx +21 -0
  491. package/src/internal/ui/label.tsx +21 -0
  492. package/src/internal/ui/select.tsx +129 -0
  493. package/src/internal/ui/tooltip.tsx +54 -0
  494. package/src/internal/ui/utils.ts +5 -0
  495. package/src/internal.ts +18 -0
  496. package/src/plugin-styles.css +246 -0
  497. package/src/primitives/board.test.tsx +139 -0
  498. package/src/primitives/board.tsx +267 -0
  499. package/src/primitives/game-ui-provider.tsx +35 -0
  500. package/src/primitives/index.ts +83 -0
  501. package/src/primitives/interaction.test.tsx +420 -0
  502. package/src/primitives/interaction.tsx +405 -0
  503. package/src/primitives/phase.test.tsx +82 -0
  504. package/src/primitives/phase.tsx +43 -0
  505. package/src/primitives/player-roster.test.tsx +168 -0
  506. package/src/primitives/player-roster.tsx +301 -0
  507. package/src/primitives/primitive-props.tsx +82 -0
  508. package/src/primitives/prompt.test.tsx +159 -0
  509. package/src/primitives/prompt.tsx +203 -0
  510. package/src/primitives/zone.tsx +113 -0
  511. package/src/reducer.ts +42 -0
  512. package/src/runtime/createPluginRuntimeAPI.ts +605 -0
  513. package/src/theme/ThemeProvider.test.tsx +36 -0
  514. package/src/theme/ThemeProvider.tsx +252 -0
  515. package/src/theme/board.ts +61 -0
  516. package/src/theme/css-vars.ts +105 -0
  517. package/src/theme/derive.ts +240 -0
  518. package/src/theme/index.ts +61 -0
  519. package/src/theme/presets/arcade.ts +261 -0
  520. package/src/theme/presets/studio.ts +261 -0
  521. package/src/theme/presets/tabletop.ts +266 -0
  522. package/src/theme/theme.test.ts +258 -0
  523. package/src/theme/tokens.ts +392 -0
  524. package/src/types/player-state.ts +445 -0
  525. package/src/types/plugin-state.ts +407 -0
  526. package/src/types/reducer-state.ts +24 -0
  527. package/src/types/runtime-api.ts +114 -0
  528. package/src/types/tiled-board.ts +785 -0
  529. package/src/ui-contract.ts +168 -0
  530. package/src/utils/interaction-inputs.test.ts +109 -0
  531. package/src/utils/interaction-inputs.ts +331 -0
  532. package/src/utils/interaction-labels.ts +23 -0
  533. package/src/utils/interaction-status.ts +59 -0
@@ -0,0 +1,113 @@
1
+ /**
2
+ * SVG-based track visualization for racing and path games
3
+ * (Monopoly, Game of Life, Snakes & Ladders). Supports linear, circular, and branching tracks.
4
+ */
5
+ import { type ReactNode } from "react";
6
+ export interface TrackSpace<SpaceIdValue extends string = string, Data = unknown> {
7
+ id: SpaceIdValue;
8
+ index: number;
9
+ name?: string;
10
+ type?: string;
11
+ /** Override next spaces (for branching) */
12
+ nextSpaces?: readonly SpaceIdValue[];
13
+ /** Jump to another space (snakes/ladders) */
14
+ jumpTo?: SpaceIdValue;
15
+ position: {
16
+ x: number;
17
+ y: number;
18
+ };
19
+ data?: Data;
20
+ }
21
+ export interface TrackPiece<PieceIdValue extends string = string, SpaceIdValue extends string = string, OwnerIdValue extends string = string, Data = unknown> {
22
+ id: PieceIdValue;
23
+ spaceId: SpaceIdValue;
24
+ owner: OwnerIdValue;
25
+ type?: string;
26
+ data?: Data;
27
+ }
28
+ export interface TrackBoardProps {
29
+ spaces: TrackSpace[];
30
+ pieces: TrackPiece[];
31
+ type?: "linear" | "circular" | "branching";
32
+ renderSpace: (space: TrackSpace, pieces: TrackPiece[]) => ReactNode;
33
+ renderConnection?: (from: {
34
+ x: number;
35
+ y: number;
36
+ }, to: {
37
+ x: number;
38
+ y: number;
39
+ }, fromSpace: TrackSpace, toSpace: TrackSpace) => ReactNode;
40
+ renderJump?: (from: {
41
+ x: number;
42
+ y: number;
43
+ }, to: {
44
+ x: number;
45
+ y: number;
46
+ }, fromSpace: TrackSpace, toSpace: TrackSpace, isUp: boolean) => ReactNode;
47
+ width?: number | string;
48
+ height?: number | string;
49
+ enablePanZoom?: boolean;
50
+ initialZoom?: number;
51
+ minZoom?: number;
52
+ maxZoom?: number;
53
+ className?: string;
54
+ }
55
+ export interface DefaultTrackSpaceProps {
56
+ space: TrackSpace;
57
+ size?: number;
58
+ fill?: string;
59
+ stroke?: string;
60
+ strokeWidth?: number;
61
+ isHighlighted?: boolean;
62
+ isSelected?: boolean;
63
+ showJumpIndicator?: boolean;
64
+ onClick?: () => void;
65
+ onHover?: (hovering: boolean) => void;
66
+ className?: string;
67
+ children?: ReactNode;
68
+ }
69
+ export declare function DefaultTrackSpace({ space, size, fill, stroke, strokeWidth, isHighlighted, isSelected, showJumpIndicator, onClick, onHover, className, children, }: DefaultTrackSpaceProps): import("react/jsx-runtime").JSX.Element;
70
+ export interface DefaultTrackPieceProps {
71
+ piece: TrackPiece;
72
+ index?: number;
73
+ total?: number;
74
+ radius?: number;
75
+ color?: string;
76
+ onClick?: () => void;
77
+ className?: string;
78
+ }
79
+ export declare function DefaultTrackPiece({ piece, index, total, radius, color, onClick, className, }: DefaultTrackPieceProps): import("react/jsx-runtime").JSX.Element;
80
+ export interface DefaultTrackConnectionProps {
81
+ from: {
82
+ x: number;
83
+ y: number;
84
+ };
85
+ to: {
86
+ x: number;
87
+ y: number;
88
+ };
89
+ stroke?: string;
90
+ strokeWidth?: number;
91
+ className?: string;
92
+ }
93
+ export declare function DefaultTrackConnection({ from, to, stroke, strokeWidth, className, }: DefaultTrackConnectionProps): import("react/jsx-runtime").JSX.Element;
94
+ export interface DefaultTrackJumpProps {
95
+ from: {
96
+ x: number;
97
+ y: number;
98
+ };
99
+ to: {
100
+ x: number;
101
+ y: number;
102
+ };
103
+ /** Whether the jump goes forward or backward */
104
+ isUp: boolean;
105
+ spaceSize?: number;
106
+ upColor?: string;
107
+ downColor?: string;
108
+ strokeWidth?: number;
109
+ className?: string;
110
+ }
111
+ export declare function DefaultTrackJump({ from, to, isUp, spaceSize, upColor, downColor, strokeWidth, className, }: DefaultTrackJumpProps): import("react/jsx-runtime").JSX.Element;
112
+ export declare function TrackBoard({ spaces, pieces, type, renderSpace, renderConnection, renderJump, width, height, enablePanZoom, initialZoom, minZoom, maxZoom, className, }: TrackBoardProps): import("react/jsx-runtime").JSX.Element;
113
+ //# sourceMappingURL=TrackBoard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TrackBoard.d.ts","sourceRoot":"","sources":["../../../src/components/board/TrackBoard.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,135 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * SVG-based track visualization for racing and path games
4
+ * (Monopoly, Game of Life, Snakes & Ladders). Supports linear, circular, and branching tracks.
5
+ */
6
+ import { useMemo } from "react";
7
+ import { clsx } from "clsx";
8
+ import { usePanZoom } from "../../hooks/usePanZoom.js";
9
+ import { handleKeyboardActivation } from "./interaction-accessibility.js";
10
+ export function DefaultTrackSpace({ space, size = 50, fill = "#1e293b", stroke = "#475569", strokeWidth = 1, isHighlighted = false, isSelected = false, showJumpIndicator = true, onClick, onHover, className, children, }) {
11
+ const halfSize = size / 2;
12
+ const computedFill = isHighlighted ? "rgba(59, 130, 246, 0.3)" : fill;
13
+ const computedStroke = isSelected
14
+ ? "#3b82f6"
15
+ : isHighlighted
16
+ ? "#60a5fa"
17
+ : stroke;
18
+ const computedStrokeWidth = isHighlighted || isSelected ? 3 : strokeWidth;
19
+ return (_jsxs("g", { onClick: onClick, onMouseEnter: () => onHover?.(true), onMouseLeave: () => onHover?.(false), onKeyDown: (event) => handleKeyboardActivation(event, onClick), className: clsx(onClick && "cursor-pointer", className), role: onClick ? "button" : "listitem", "aria-label": space.name || `Space ${space.index}`, tabIndex: onClick ? 0 : undefined, children: [_jsx("rect", { x: -halfSize, y: -halfSize, width: size, height: size, rx: 8, fill: computedFill, stroke: computedStroke, strokeWidth: computedStrokeWidth }), space.name ? (_jsx("text", { textAnchor: "middle", dominantBaseline: "middle", fill: "white", fontSize: space.name.length > 4 ? 8 : 10, fontWeight: "bold", children: space.name.length > 8 ? space.name.slice(0, 7) + "…" : space.name })) : (_jsx("text", { textAnchor: "middle", dominantBaseline: "middle", fill: "#94a3b8", fontSize: 12, fontWeight: "bold", children: space.index })), showJumpIndicator && space.jumpTo && (_jsxs("g", { transform: `translate(${halfSize - 6}, ${-halfSize + 6})`, children: [_jsx("circle", { r: 6, fill: "#fbbf24" }), _jsx("text", { textAnchor: "middle", dominantBaseline: "central", fill: "black", fontSize: 8, fontWeight: "bold", children: "\u2197" })] })), children] }));
20
+ }
21
+ export function DefaultTrackPiece({ piece, index = 0, total = 1, radius = 8, color = "#f59e0b", onClick, className, }) {
22
+ // Arrange pieces in a circle around the space center
23
+ const spacing = radius * 2.2;
24
+ const angle = (index / total) * 2 * Math.PI - Math.PI / 2;
25
+ const offset = total > 1 ? spacing : 0;
26
+ const px = Math.cos(angle) * offset;
27
+ const py = Math.sin(angle) * offset;
28
+ return (_jsx("circle", { cx: px, cy: py, r: radius, fill: color, stroke: "white", strokeWidth: 2, onClick: (e) => {
29
+ e.stopPropagation();
30
+ onClick?.();
31
+ }, onKeyDown: (event) => handleKeyboardActivation(event, onClick, { stopPropagation: true }), className: clsx(onClick && "cursor-pointer", className), role: onClick ? "button" : undefined, tabIndex: onClick ? 0 : undefined, "aria-label": `Piece ${piece.id} owned by ${piece.owner}` }));
32
+ }
33
+ export function DefaultTrackConnection({ from, to, stroke = "#475569", strokeWidth = 2, className, }) {
34
+ return (_jsx("line", { x1: from.x, y1: from.y, x2: to.x, y2: to.y, stroke: stroke, strokeWidth: strokeWidth, strokeLinecap: "round", className: className }));
35
+ }
36
+ export function DefaultTrackJump({ from, to, isUp, spaceSize = 50, upColor = "#22c55e", downColor = "#ef4444", strokeWidth = 3, className, }) {
37
+ const color = isUp ? upColor : downColor;
38
+ // Calculate arrow direction
39
+ const dx = to.x - from.x;
40
+ const dy = to.y - from.y;
41
+ const len = Math.sqrt(dx * dx + dy * dy);
42
+ const unitX = dx / len;
43
+ const unitY = dy / len;
44
+ // Offset start and end points
45
+ const startX = from.x + unitX * (spaceSize / 2 + 5);
46
+ const startY = from.y + unitY * (spaceSize / 2 + 5);
47
+ const endX = to.x - unitX * (spaceSize / 2 + 5);
48
+ const endY = to.y - unitY * (spaceSize / 2 + 5);
49
+ // Generate unique marker IDs
50
+ const markerId = `arrow-${isUp ? "up" : "down"}-${from.x}-${from.y}`;
51
+ return (_jsxs("g", { className: className, children: [_jsx("defs", { children: _jsx("marker", { id: markerId, markerWidth: "10", markerHeight: "7", refX: "9", refY: "3.5", orient: "auto", children: _jsx("polygon", { points: "0 0, 10 3.5, 0 7", fill: color }) }) }), _jsx("line", { x1: startX, y1: startY, x2: endX, y2: endY, stroke: color, strokeWidth: strokeWidth, strokeDasharray: "6,4", markerEnd: `url(#${markerId})` })] }));
52
+ }
53
+ // ============================================================================
54
+ // Main Component
55
+ // ============================================================================
56
+ export function TrackBoard({ spaces, pieces, type = "linear", renderSpace, renderConnection, renderJump, width = 800, height = 600, enablePanZoom = false, initialZoom = 1, minZoom = 0.5, maxZoom = 3, className, }) {
57
+ // Use the unified pan/zoom hook
58
+ const { transform, bind, isDragging } = usePanZoom({
59
+ enabled: enablePanZoom,
60
+ initialZoom,
61
+ minZoom,
62
+ maxZoom,
63
+ mode: "viewbox",
64
+ });
65
+ // Group pieces by space
66
+ const piecesBySpace = useMemo(() => {
67
+ const map = {};
68
+ pieces.forEach((p) => {
69
+ const existing = map[p.spaceId];
70
+ if (existing) {
71
+ existing.push(p);
72
+ }
73
+ else {
74
+ map[p.spaceId] = [p];
75
+ }
76
+ });
77
+ return map;
78
+ }, [pieces]);
79
+ // Sort spaces by index for drawing connections
80
+ const sortedSpaces = useMemo(() => {
81
+ return [...spaces].sort((a, b) => a.index - b.index);
82
+ }, [spaces]);
83
+ // Create space lookup
84
+ const spaceMap = useMemo(() => {
85
+ return new Map(spaces.map((s) => [s.id, s]));
86
+ }, [spaces]);
87
+ // Render connections between spaces
88
+ const renderConnections = () => {
89
+ if (!renderConnection)
90
+ return null;
91
+ return sortedSpaces.map((space, i) => {
92
+ const nextSpace = sortedSpaces[i + 1];
93
+ const firstSpace = sortedSpaces[0];
94
+ const nextSpaceIds = space.nextSpaces ||
95
+ (i < sortedSpaces.length - 1 && nextSpace
96
+ ? [nextSpace.id]
97
+ : type === "circular" && firstSpace
98
+ ? [firstSpace.id]
99
+ : []);
100
+ return nextSpaceIds.map((nextId) => {
101
+ const targetSpace = spaceMap.get(nextId);
102
+ if (!targetSpace)
103
+ return null;
104
+ return (_jsx("g", { children: renderConnection(space.position, targetSpace.position, space, targetSpace) }, `${space.id}-${nextId}`));
105
+ });
106
+ });
107
+ };
108
+ // Render jump arrows (snakes/ladders)
109
+ const renderJumps = () => {
110
+ if (!renderJump)
111
+ return null;
112
+ return spaces.flatMap((space) => {
113
+ if (!space.jumpTo)
114
+ return [];
115
+ const targetSpace = spaceMap.get(space.jumpTo);
116
+ if (!targetSpace)
117
+ return [];
118
+ const isUp = targetSpace.index > space.index;
119
+ return [
120
+ _jsx("g", { children: renderJump(space.position, targetSpace.position, space, targetSpace, isUp) }, `jump-${space.id}`),
121
+ ];
122
+ });
123
+ };
124
+ // Calculate viewBox dimensions
125
+ const baseWidth = typeof width === "number" ? width : 800;
126
+ const baseHeight = typeof height === "number" ? height : 600;
127
+ const viewBoxWidth = baseWidth / transform.zoom;
128
+ const viewBoxHeight = baseHeight / transform.zoom;
129
+ const viewBoxX = (baseWidth - viewBoxWidth) / 2 - transform.pan.x;
130
+ const viewBoxY = (baseHeight - viewBoxHeight) / 2 - transform.pan.y;
131
+ return (_jsxs("svg", { width: width, height: height, viewBox: `${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}`, className: clsx("overflow-visible", enablePanZoom && "touch-none", isDragging && "cursor-grabbing", enablePanZoom && !isDragging && "cursor-grab", className), ...bind(), role: "img", "aria-label": "Track board", children: [_jsx("g", { className: "track-connections", children: renderConnections() }), _jsx("g", { className: "track-jumps", children: renderJumps() }), _jsx("g", { className: "track-spaces", role: "list", "aria-label": "Track spaces", children: spaces.map((space) => {
132
+ const spacePieces = piecesBySpace[space.id] || [];
133
+ return (_jsx("g", { transform: `translate(${space.position.x}, ${space.position.y})`, children: renderSpace(space, spacePieces) }, space.id));
134
+ }) }), enablePanZoom && transform.zoom !== 1 && (_jsxs("g", { transform: `translate(${viewBoxX + 10}, ${viewBoxY + viewBoxHeight - 30})`, children: [_jsx("rect", { x: 0, y: 0, width: 60, height: 20, rx: 4, fill: "rgba(0,0,0,0.6)" }), _jsxs("text", { x: 30, y: 14, textAnchor: "middle", fill: "white", fontSize: 12, children: [Math.round(transform.zoom * 100), "%"] })] }))] }));
135
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * SVG-based area control visualization for territory games (Risk, Small World, Diplomacy).
3
+ */
4
+ import { type ReactNode } from "react";
5
+ export interface ZoneShape {
6
+ type: "polygon" | "path" | "circle";
7
+ points?: Array<{
8
+ x: number;
9
+ y: number;
10
+ }>;
11
+ /** SVG path data */
12
+ path?: string;
13
+ center?: {
14
+ x: number;
15
+ y: number;
16
+ };
17
+ radius?: number;
18
+ }
19
+ export interface ZoneDefinition {
20
+ id: string;
21
+ name: string;
22
+ adjacentTo: string[];
23
+ shape?: ZoneShape;
24
+ value?: number;
25
+ type?: string;
26
+ data?: Record<string, unknown>;
27
+ }
28
+ export interface ZonePiece {
29
+ id: string;
30
+ zoneId: string;
31
+ type: string;
32
+ owner?: string;
33
+ /** Count for stackable pieces (armies) */
34
+ count?: number;
35
+ data?: Record<string, unknown>;
36
+ }
37
+ export interface ZoneMapProps {
38
+ zones: ZoneDefinition[];
39
+ pieces: ZonePiece[];
40
+ renderZone: (zone: ZoneDefinition, pieces: ZonePiece[]) => ReactNode;
41
+ backgroundImage?: string;
42
+ width?: number | string;
43
+ height?: number | string;
44
+ enablePanZoom?: boolean;
45
+ initialZoom?: number;
46
+ minZoom?: number;
47
+ maxZoom?: number;
48
+ className?: string;
49
+ }
50
+ export type ZoneHighlightType = "valid" | "selected" | "attack" | "defend" | "neutral";
51
+ export interface DefaultZoneProps {
52
+ zone: ZoneDefinition;
53
+ fill?: string;
54
+ stroke?: string;
55
+ strokeWidth?: number;
56
+ isHighlighted?: boolean;
57
+ highlightType?: ZoneHighlightType;
58
+ isSelected?: boolean;
59
+ showLabel?: boolean;
60
+ showValue?: boolean;
61
+ onClick?: () => void;
62
+ onHover?: (hovering: boolean) => void;
63
+ className?: string;
64
+ children?: ReactNode;
65
+ }
66
+ export declare function DefaultZone({ zone, fill, stroke, strokeWidth, isHighlighted, highlightType, isSelected, showLabel, showValue, onClick, onHover, className, children, }: DefaultZoneProps): import("react/jsx-runtime").JSX.Element;
67
+ export interface DefaultZonePiecesProps {
68
+ pieces: ZonePiece[];
69
+ zone: ZoneDefinition;
70
+ playerColors?: Record<string, string>;
71
+ radius?: number;
72
+ spacing?: number;
73
+ yOffset?: number;
74
+ className?: string;
75
+ }
76
+ export declare function DefaultZonePieces({ pieces, zone, playerColors, radius, spacing, yOffset, className, }: DefaultZonePiecesProps): import("react/jsx-runtime").JSX.Element | null;
77
+ export interface DefaultZonePieceProps {
78
+ piece: ZonePiece;
79
+ x?: number;
80
+ y?: number;
81
+ radius?: number;
82
+ color?: string;
83
+ onClick?: () => void;
84
+ className?: string;
85
+ }
86
+ export declare function DefaultZonePiece({ piece, x, y, radius, color, onClick, className, }: DefaultZonePieceProps): import("react/jsx-runtime").JSX.Element;
87
+ export declare function ZoneMap({ zones, pieces, renderZone, backgroundImage, width, height, enablePanZoom, initialZoom, minZoom, maxZoom, className, }: ZoneMapProps): import("react/jsx-runtime").JSX.Element;
88
+ //# sourceMappingURL=ZoneMap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ZoneMap.d.ts","sourceRoot":"","sources":["../../../src/components/board/ZoneMap.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,133 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * SVG-based area control visualization for territory games (Risk, Small World, Diplomacy).
4
+ */
5
+ import { useMemo } from "react";
6
+ import { clsx } from "clsx";
7
+ import { usePanZoom } from "../../hooks/usePanZoom.js";
8
+ import { handleKeyboardActivation } from "./interaction-accessibility.js";
9
+ // Highlight colors by type
10
+ const HIGHLIGHT_COLORS = {
11
+ valid: "rgba(34, 197, 94, 0.4)", // Green
12
+ selected: "rgba(59, 130, 246, 0.4)", // Blue
13
+ attack: "rgba(239, 68, 68, 0.4)", // Red
14
+ defend: "rgba(234, 179, 8, 0.4)", // Yellow
15
+ neutral: "rgba(148, 163, 184, 0.4)", // Slate
16
+ };
17
+ const HIGHLIGHT_STROKES = {
18
+ valid: "#22c55e",
19
+ selected: "#3b82f6",
20
+ attack: "#ef4444",
21
+ defend: "#eab308",
22
+ neutral: "#94a3b8",
23
+ };
24
+ const EMPTY_PLAYER_COLORS = {};
25
+ export function DefaultZone({ zone, fill = "rgba(100, 116, 139, 0.2)", stroke = "#475569", strokeWidth = 1, isHighlighted = false, highlightType, isSelected = false, showLabel = true, showValue = false, onClick, onHover, className, children, }) {
26
+ // Calculate colors based on state
27
+ let computedFill = fill;
28
+ let computedStroke = stroke;
29
+ let computedStrokeWidth = strokeWidth;
30
+ if (isHighlighted && highlightType && HIGHLIGHT_COLORS[highlightType]) {
31
+ computedFill = HIGHLIGHT_COLORS[highlightType];
32
+ computedStroke = HIGHLIGHT_STROKES[highlightType];
33
+ computedStrokeWidth = 3;
34
+ }
35
+ else if (isSelected) {
36
+ computedFill = HIGHLIGHT_COLORS.selected;
37
+ computedStroke = HIGHLIGHT_STROKES.selected;
38
+ computedStrokeWidth = 3;
39
+ }
40
+ // Render zone shape
41
+ const renderShape = () => {
42
+ if (!zone.shape)
43
+ return null;
44
+ switch (zone.shape.type) {
45
+ case "polygon":
46
+ if (!zone.shape.points)
47
+ return null;
48
+ return (_jsx("polygon", { points: zone.shape.points.map((p) => `${p.x},${p.y}`).join(" "), fill: computedFill, stroke: computedStroke, strokeWidth: computedStrokeWidth }));
49
+ case "path":
50
+ if (!zone.shape.path)
51
+ return null;
52
+ return (_jsx("path", { d: zone.shape.path, fill: computedFill, stroke: computedStroke, strokeWidth: computedStrokeWidth }));
53
+ case "circle":
54
+ if (!zone.shape.center)
55
+ return null;
56
+ return (_jsx("circle", { cx: zone.shape.center.x, cy: zone.shape.center.y, r: zone.shape.radius || 30, fill: computedFill, stroke: computedStroke, strokeWidth: computedStrokeWidth }));
57
+ default:
58
+ return null;
59
+ }
60
+ };
61
+ return (_jsxs("g", { onClick: onClick, onMouseEnter: () => onHover?.(true), onMouseLeave: () => onHover?.(false), onKeyDown: (event) => handleKeyboardActivation(event, onClick), className: clsx(onClick && "cursor-pointer", className), role: onClick ? "button" : "listitem", "aria-label": zone.name, tabIndex: onClick ? 0 : undefined, children: [renderShape(), showLabel && zone.shape?.center && (_jsx("text", { x: zone.shape.center.x, y: zone.shape.center.y - (showValue ? 8 : 0), textAnchor: "middle", dominantBaseline: "middle", fill: "white", fontSize: 12, fontWeight: "bold", style: { textShadow: "1px 1px 2px rgba(0,0,0,0.8)" }, children: zone.name })), showValue && zone.value !== undefined && zone.shape?.center && (_jsxs("text", { x: zone.shape.center.x, y: zone.shape.center.y + 8, textAnchor: "middle", dominantBaseline: "middle", fill: "#fbbf24", fontSize: 10, fontWeight: "bold", style: { textShadow: "1px 1px 2px rgba(0,0,0,0.8)" }, children: ["+", zone.value] })), children] }));
62
+ }
63
+ export function DefaultZonePieces({ pieces, zone, playerColors = EMPTY_PLAYER_COLORS, radius = 14, spacing = 25, yOffset = 20, className, }) {
64
+ if (pieces.length === 0 || !zone.shape?.center)
65
+ return null;
66
+ const centerX = zone.shape.center.x;
67
+ const centerY = zone.shape.center.y;
68
+ // Group pieces by owner
69
+ const piecesByOwner = {};
70
+ pieces.forEach((p) => {
71
+ const owner = p.owner || "neutral";
72
+ const existing = piecesByOwner[owner];
73
+ if (existing) {
74
+ existing.push(p);
75
+ }
76
+ else {
77
+ piecesByOwner[owner] = [p];
78
+ }
79
+ });
80
+ const owners = Object.keys(piecesByOwner);
81
+ const startOffset = -((owners.length - 1) * spacing) / 2;
82
+ return (_jsx("g", { className: clsx("zone-pieces", className), children: owners.map((owner, i) => {
83
+ const ownerPieces = piecesByOwner[owner] || [];
84
+ const totalCount = ownerPieces.reduce((sum, p) => sum + (p.count || 1), 0);
85
+ const offsetX = startOffset + i * spacing;
86
+ return (_jsxs("g", { transform: `translate(${centerX + offsetX}, ${centerY + yOffset})`, children: [_jsx("circle", { r: radius, fill: playerColors[owner] || "#64748b", stroke: "white", strokeWidth: 2 }), _jsx("text", { textAnchor: "middle", dominantBaseline: "central", fill: "white", fontSize: 10, fontWeight: "bold", children: totalCount })] }, owner));
87
+ }) }));
88
+ }
89
+ export function DefaultZonePiece({ piece, x = 0, y = 0, radius = 14, color = "#64748b", onClick, className, }) {
90
+ const count = piece.count || 1;
91
+ return (_jsxs("g", { transform: `translate(${x}, ${y})`, onClick: (e) => {
92
+ e.stopPropagation();
93
+ onClick?.();
94
+ }, onKeyDown: (event) => handleKeyboardActivation(event, onClick, { stopPropagation: true }), className: clsx(onClick && "cursor-pointer", className), role: onClick ? "button" : undefined, tabIndex: onClick ? 0 : undefined, "aria-label": `Piece ${piece.id}`, children: [_jsx("circle", { r: radius, fill: color, stroke: "white", strokeWidth: 2 }), _jsx("text", { textAnchor: "middle", dominantBaseline: "central", fill: "white", fontSize: 10, fontWeight: "bold", children: count })] }));
95
+ }
96
+ // ============================================================================
97
+ // Main Component
98
+ // ============================================================================
99
+ export function ZoneMap({ zones, pieces, renderZone, backgroundImage, width = 800, height = 600, enablePanZoom = false, initialZoom = 1, minZoom = 0.5, maxZoom = 3, className, }) {
100
+ // Use the unified pan/zoom hook
101
+ const { transform, bind, isDragging } = usePanZoom({
102
+ enabled: enablePanZoom,
103
+ initialZoom,
104
+ minZoom,
105
+ maxZoom,
106
+ mode: "viewbox",
107
+ });
108
+ // Group pieces by zone
109
+ const piecesByZone = useMemo(() => {
110
+ const map = {};
111
+ pieces.forEach((p) => {
112
+ const existing = map[p.zoneId];
113
+ if (existing) {
114
+ existing.push(p);
115
+ }
116
+ else {
117
+ map[p.zoneId] = [p];
118
+ }
119
+ });
120
+ return map;
121
+ }, [pieces]);
122
+ // Calculate viewBox dimensions
123
+ const baseWidth = typeof width === "number" ? width : 800;
124
+ const baseHeight = typeof height === "number" ? height : 600;
125
+ const viewBoxWidth = baseWidth / transform.zoom;
126
+ const viewBoxHeight = baseHeight / transform.zoom;
127
+ const viewBoxX = (baseWidth - viewBoxWidth) / 2 - transform.pan.x;
128
+ const viewBoxY = (baseHeight - viewBoxHeight) / 2 - transform.pan.y;
129
+ return (_jsxs("svg", { width: width, height: height, viewBox: `${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}`, className: clsx("overflow-visible", enablePanZoom && "touch-none", isDragging && "cursor-grabbing", enablePanZoom && !isDragging && "cursor-grab", className), ...bind(), role: "img", "aria-label": "Zone map", children: [backgroundImage && (_jsx("image", { href: backgroundImage, width: width, height: height })), _jsx("g", { className: "zones", role: "list", "aria-label": "Map zones", children: zones.map((zone) => {
130
+ const zonePieces = piecesByZone[zone.id] || [];
131
+ return _jsx("g", { children: renderZone(zone, zonePieces) }, zone.id);
132
+ }) }), enablePanZoom && transform.zoom !== 1 && (_jsxs("g", { transform: `translate(${viewBoxX + 10}, ${viewBoxY + viewBoxHeight - 30})`, children: [_jsx("rect", { x: 0, y: 0, width: 60, height: 20, rx: 4, fill: "rgba(0,0,0,0.6)" }), _jsxs("text", { x: 30, y: 14, textAnchor: "middle", fill: "white", fontSize: 12, children: [Math.round(transform.zoom * 100), "%"] })] }))] }));
133
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Typed adapter for joining static hex-board topology with a dynamic
3
+ * per-space view overlay. Use this to feed `HexGrid` a single board
4
+ * value whose tiles carry both static geometry (`q`, `r`, `id`) and
5
+ * the projected view fields the UI cares about (e.g. `terrain`,
6
+ * `numberToken`).
7
+ *
8
+ * The runtime is intentionally strict: every static space must have
9
+ * exactly one overlay, duplicates throw, and overlays for ids that
10
+ * are not on the board throw. There is no relaxed fallback in v1 —
11
+ * silent merge bugs are far more expensive than a loud throw at
12
+ * dev/CI time.
13
+ */
14
+ import type { AnyHexBoardInput, BoardIdOf, BoardSpaceIdOf, NormalizedHexTileOf } from "../../types/tiled-board.js";
15
+ /**
16
+ * Per-tile result produced by {@link createHexBoardView}. Each tile
17
+ * carries the static topology (`id`, `q`, `r`) plus the matched
18
+ * overlay row in `view`.
19
+ *
20
+ * Static board fields/properties are preserved from `TBoard`.
21
+ * Consumers should use `tile.properties` for authored static space
22
+ * fields and `tile.view` for dynamic per-space projection data.
23
+ */
24
+ export type HexBoardViewTile<TBoard extends AnyHexBoardInput, TSpaceView extends {
25
+ id: BoardSpaceIdOf<TBoard>;
26
+ }> = Omit<NormalizedHexTileOf<TBoard>, "view"> & {
27
+ view: TSpaceView;
28
+ };
29
+ /**
30
+ * Result of {@link createHexBoardView}. Shaped like an authored hex
31
+ * board so it can be passed straight to `<HexGrid board={...} />`
32
+ * without any further adapter work.
33
+ *
34
+ * The type-level board id and space id are preserved from `TBoard`,
35
+ * so `tile.id` stays narrow inside `renderTile`. `tile.view` is the
36
+ * authored overlay row, fully typed.
37
+ */
38
+ export interface HexBoardView<TBoard extends AnyHexBoardInput, TSpaceView extends {
39
+ id: BoardSpaceIdOf<TBoard>;
40
+ }> {
41
+ id: BoardIdOf<TBoard>;
42
+ layout?: "hex";
43
+ orientation?: "pointy-top" | "flat-top";
44
+ tiles: ReadonlyArray<HexBoardViewTile<TBoard, TSpaceView>>;
45
+ edges: TBoard["edges"];
46
+ vertices: TBoard["vertices"];
47
+ }
48
+ interface CreateHexBoardViewOptions<TSpaceView> {
49
+ spaces: readonly TSpaceView[];
50
+ }
51
+ /**
52
+ * Join a static hex board topology with a dynamic per-space overlay.
53
+ *
54
+ * The result is suitable for direct use as the `board` prop on
55
+ * `<HexGrid>`. Every overlay is enforced 1-to-1 against the board's
56
+ * spaces:
57
+ *
58
+ * - missing overlay for a board space → throws
59
+ * - duplicate overlay (same `id` twice) → throws
60
+ * - overlay `id` not present on the board → throws
61
+ *
62
+ * Each tile in the result carries a `view` field with the matched
63
+ * overlay row.
64
+ */
65
+ export declare function createHexBoardView<const TBoard extends AnyHexBoardInput, const TSpaceView extends {
66
+ id: BoardSpaceIdOf<TBoard>;
67
+ }>(board: TBoard, options: CreateHexBoardViewOptions<TSpaceView>): HexBoardView<TBoard, TSpaceView>;
68
+ export {};
69
+ //# sourceMappingURL=hex-board-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hex-board-view.d.ts","sourceRoot":"","sources":["../../../src/components/board/hex-board-view.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,SAAS,EACT,cAAc,EACd,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;AAGpC;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,CAC1B,MAAM,SAAS,gBAAgB,EAC/B,UAAU,SAAS;IAAE,EAAE,EAAE,cAAc,CAAC,MAAM,CAAC,CAAA;CAAE,IAC/C,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC;AAErE;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY,CAC3B,MAAM,SAAS,gBAAgB,EAC/B,UAAU,SAAS;IAAE,EAAE,EAAE,cAAc,CAAC,MAAM,CAAC,CAAA;CAAE;IAEjD,EAAE,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACtB,MAAM,CAAC,EAAE,KAAK,CAAC;IACf,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,KAAK,EAAE,aAAa,CAAC,gBAAgB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IAC3D,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;CAC9B;AAED,UAAU,yBAAyB,CAAC,UAAU;IAC5C,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;CAC/B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,CAAC,MAAM,SAAS,gBAAgB,EACrC,KAAK,CAAC,UAAU,SAAS;IAAE,EAAE,EAAE,cAAc,CAAC,MAAM,CAAC,CAAA;CAAE,EAEvD,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,yBAAyB,CAAC,UAAU,CAAC,GAC7C,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,CAyClC"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Typed adapter for joining static hex-board topology with a dynamic
3
+ * per-space view overlay. Use this to feed `HexGrid` a single board
4
+ * value whose tiles carry both static geometry (`q`, `r`, `id`) and
5
+ * the projected view fields the UI cares about (e.g. `terrain`,
6
+ * `numberToken`).
7
+ *
8
+ * The runtime is intentionally strict: every static space must have
9
+ * exactly one overlay, duplicates throw, and overlays for ids that
10
+ * are not on the board throw. There is no relaxed fallback in v1 —
11
+ * silent merge bugs are far more expensive than a loud throw at
12
+ * dev/CI time.
13
+ */
14
+ import { normalizeHexBoardInput } from "../../types/tiled-board.js";
15
+ /**
16
+ * Join a static hex board topology with a dynamic per-space overlay.
17
+ *
18
+ * The result is suitable for direct use as the `board` prop on
19
+ * `<HexGrid>`. Every overlay is enforced 1-to-1 against the board's
20
+ * spaces:
21
+ *
22
+ * - missing overlay for a board space → throws
23
+ * - duplicate overlay (same `id` twice) → throws
24
+ * - overlay `id` not present on the board → throws
25
+ *
26
+ * Each tile in the result carries a `view` field with the matched
27
+ * overlay row.
28
+ */
29
+ export function createHexBoardView(board, options) {
30
+ const overlayById = new Map();
31
+ for (const overlay of options.spaces) {
32
+ if (overlayById.has(overlay.id)) {
33
+ throw new Error(`createHexBoardView: duplicate overlay for space '${overlay.id}'.`);
34
+ }
35
+ overlayById.set(overlay.id, overlay);
36
+ }
37
+ const consumed = new Set();
38
+ const normalizedBoard = normalizeHexBoardInput(board);
39
+ const tiles = normalizedBoard.tiles.map((tile) => {
40
+ const overlay = overlayById.get(tile.id);
41
+ if (!overlay) {
42
+ throw new Error(`createHexBoardView: missing overlay for space '${tile.id}'.`);
43
+ }
44
+ consumed.add(tile.id);
45
+ return { ...tile, view: overlay };
46
+ });
47
+ for (const id of overlayById.keys()) {
48
+ if (!consumed.has(id)) {
49
+ throw new Error(`createHexBoardView: overlay '${id}' is not on the board.`);
50
+ }
51
+ }
52
+ return {
53
+ id: normalizedBoard.id,
54
+ layout: "hex",
55
+ orientation: board.orientation,
56
+ tiles,
57
+ edges: board.edges,
58
+ vertices: board.vertices,
59
+ };
60
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Board Primitives
3
+ *
4
+ * Reusable board visualization components for different game types.
5
+ *
6
+ * Components:
7
+ * - NetworkGraph: For route-building games (Ticket to Ride, Pandemic)
8
+ * - HexGrid: For hex-based games (Catan, wargames)
9
+ * - SquareGrid: For grid-based games (Chess, Go, Checkers)
10
+ * - ZoneMap: For area control games (Risk, Small World)
11
+ * - TrackBoard: For track/racing games (Monopoly, Game of Life)
12
+ * - SlotSystem: For worker placement games (Agricola, Viticulture)
13
+ */
14
+ export { NetworkGraph, DefaultNetworkNode, DefaultNetworkEdge, DefaultNetworkPiece, type NetworkGraphProps, type NetworkNode, type NetworkEdge, type NetworkPiece, type DefaultNetworkNodeProps, type DefaultNetworkEdgeProps, type DefaultNetworkPieceProps, } from "./NetworkGraph.js";
15
+ export { HexGrid, hexUtils, DefaultHexTile, DefaultHexEdge, DefaultHexVertex, type HexGridBoardProps, type HexGridProps, type HexOrientation, type HexTileGeometry, type InteractiveHexEdge, type InteractiveHexSpace, type InteractiveHexVertex, type EdgePosition, type DefaultHexTileProps, type DefaultHexEdgeProps, type DefaultHexVertexProps, } from "./HexGrid.js";
16
+ export type { InteractiveTargetLayer, InteractiveTargetRenderState, } from "./target-layer.js";
17
+ export { createHexBoardView, type HexBoardView, type HexBoardViewTile, } from "./hex-board-view.js";
18
+ export { SquareGrid, DefaultGridCell, DefaultGridPiece, DefaultChessPiece, toAlgebraic, toNumeric, type SquareGridBoardProps, type SquareGridProps, type InteractiveSquareEdge, type InteractiveSquareSpace, type InteractiveSquareVertex, type SquareEdgePosition, type SquareVertexPosition, type DefaultGridCellProps, type DefaultGridPieceProps, type DefaultChessPieceProps, } from "./SquareGrid.js";
19
+ export { ZoneMap, DefaultZone, DefaultZonePieces, DefaultZonePiece, type ZoneMapProps, type ZoneDefinition, type ZonePiece, type ZoneShape, type ZoneHighlightType, type DefaultZoneProps, type DefaultZonePiecesProps, type DefaultZonePieceProps, } from "./ZoneMap.js";
20
+ export { TrackBoard, DefaultTrackSpace, DefaultTrackPiece, DefaultTrackConnection, DefaultTrackJump, type TrackBoardProps, type TrackSpace, type TrackPiece, type DefaultTrackSpaceProps, type DefaultTrackPieceProps, type DefaultTrackConnectionProps, type DefaultTrackJumpProps, } from "./TrackBoard.js";
21
+ export { SlotSystem, DefaultSlotItem, DefaultSlotOccupant, DefaultEmptySlot, type SlotSystemProps, type SlotDefinition, type SlotOccupant, type DefaultSlotItemProps, type DefaultSlotOccupantProps, type DefaultEmptySlotProps, } from "./SlotSystem.js";
22
+ export type { HexTileState, HexEdgeState, HexVertexState, SquareCellState, SquareEdgeState, SquarePieceState, SquareVertexState, } from "../../types/player-state.js";
23
+ //# sourceMappingURL=index.d.ts.map