@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.
- package/LICENSE +89 -0
- package/NOTICE +1 -0
- package/README.md +154 -0
- package/dist/components/ActionButton.d.ts +13 -0
- package/dist/components/ActionButton.d.ts.map +1 -0
- package/dist/components/ActionButton.js +14 -0
- package/dist/components/ActionPanel.d.ts +33 -0
- package/dist/components/ActionPanel.d.ts.map +1 -0
- package/dist/components/ActionPanel.js +148 -0
- package/dist/components/Card.d.ts +29 -0
- package/dist/components/Card.d.ts.map +1 -0
- package/dist/components/Card.js +220 -0
- package/dist/components/ChromeSuppressionContext.d.ts +7 -0
- package/dist/components/ChromeSuppressionContext.d.ts.map +1 -0
- package/dist/components/ChromeSuppressionContext.js +34 -0
- package/dist/components/CostDisplay.d.ts +22 -0
- package/dist/components/CostDisplay.d.ts.map +1 -0
- package/dist/components/CostDisplay.js +41 -0
- package/dist/components/DiceRoller.d.ts +30 -0
- package/dist/components/DiceRoller.d.ts.map +1 -0
- package/dist/components/DiceRoller.js +319 -0
- package/dist/components/Drawer.d.ts +19 -0
- package/dist/components/Drawer.d.ts.map +1 -0
- package/dist/components/Drawer.js +55 -0
- package/dist/components/ErrorBoundary.d.ts +24 -0
- package/dist/components/ErrorBoundary.d.ts.map +1 -0
- package/dist/components/ErrorBoundary.js +37 -0
- package/dist/components/GameEndDisplay.d.ts +27 -0
- package/dist/components/GameEndDisplay.d.ts.map +1 -0
- package/dist/components/GameEndDisplay.js +185 -0
- package/dist/components/GameSkeleton.d.ts +12 -0
- package/dist/components/GameSkeleton.d.ts.map +1 -0
- package/dist/components/GameSkeleton.js +54 -0
- package/dist/components/Hand.d.ts +99 -0
- package/dist/components/Hand.d.ts.map +1 -0
- package/dist/components/Hand.js +162 -0
- package/dist/components/HandDock.d.ts +35 -0
- package/dist/components/HandDock.d.ts.map +1 -0
- package/dist/components/HandDock.js +124 -0
- package/dist/components/InteractionForm.d.ts +50 -0
- package/dist/components/InteractionForm.d.ts.map +1 -0
- package/dist/components/InteractionForm.js +402 -0
- package/dist/components/MoreActions.d.ts +49 -0
- package/dist/components/MoreActions.d.ts.map +1 -0
- package/dist/components/MoreActions.js +64 -0
- package/dist/components/PhaseIndicator.d.ts +35 -0
- package/dist/components/PhaseIndicator.d.ts.map +1 -0
- package/dist/components/PhaseIndicator.js +212 -0
- package/dist/components/PlayArea.d.ts +28 -0
- package/dist/components/PlayArea.d.ts.map +1 -0
- package/dist/components/PlayArea.js +48 -0
- package/dist/components/PluginRuntime.d.ts +37 -0
- package/dist/components/PluginRuntime.d.ts.map +1 -0
- package/dist/components/PluginRuntime.js +47 -0
- package/dist/components/PrimaryActionButton.d.ts +98 -0
- package/dist/components/PrimaryActionButton.d.ts.map +1 -0
- package/dist/components/PrimaryActionButton.js +183 -0
- package/dist/components/PrimaryButton.d.ts +20 -0
- package/dist/components/PrimaryButton.d.ts.map +1 -0
- package/dist/components/PrimaryButton.js +5 -0
- package/dist/components/PromptDialogHost.d.ts +15 -0
- package/dist/components/PromptDialogHost.d.ts.map +1 -0
- package/dist/components/PromptDialogHost.js +22 -0
- package/dist/components/ResourceCounter.d.ts +38 -0
- package/dist/components/ResourceCounter.d.ts.map +1 -0
- package/dist/components/ResourceCounter.js +118 -0
- package/dist/components/ThemedButton.d.ts +12 -0
- package/dist/components/ThemedButton.d.ts.map +1 -0
- package/dist/components/ThemedButton.js +38 -0
- package/dist/components/Toast.d.ts +35 -0
- package/dist/components/Toast.d.ts.map +1 -0
- package/dist/components/Toast.js +116 -0
- package/dist/components/board/HexGrid.d.ts +344 -0
- package/dist/components/board/HexGrid.d.ts.map +1 -0
- package/dist/components/board/HexGrid.js +340 -0
- package/dist/components/board/NetworkGraph.d.ts +100 -0
- package/dist/components/board/NetworkGraph.d.ts.map +1 -0
- package/dist/components/board/NetworkGraph.js +123 -0
- package/dist/components/board/SlotSystem.d.ts +71 -0
- package/dist/components/board/SlotSystem.d.ts.map +1 -0
- package/dist/components/board/SlotSystem.js +87 -0
- package/dist/components/board/SquareGrid.d.ts +188 -0
- package/dist/components/board/SquareGrid.d.ts.map +1 -0
- package/dist/components/board/SquareGrid.js +328 -0
- package/dist/components/board/TrackBoard.d.ts +113 -0
- package/dist/components/board/TrackBoard.d.ts.map +1 -0
- package/dist/components/board/TrackBoard.js +135 -0
- package/dist/components/board/ZoneMap.d.ts +88 -0
- package/dist/components/board/ZoneMap.d.ts.map +1 -0
- package/dist/components/board/ZoneMap.js +133 -0
- package/dist/components/board/hex-board-view.d.ts +69 -0
- package/dist/components/board/hex-board-view.d.ts.map +1 -0
- package/dist/components/board/hex-board-view.js +60 -0
- package/dist/components/board/index.d.ts +23 -0
- package/dist/components/board/index.d.ts.map +1 -0
- package/dist/components/board/index.js +40 -0
- package/dist/components/board/interaction-accessibility.d.ts +5 -0
- package/dist/components/board/interaction-accessibility.d.ts.map +1 -0
- package/dist/components/board/interaction-accessibility.js +13 -0
- package/dist/components/board/target-layer.d.ts +13 -0
- package/dist/components/board/target-layer.d.ts.map +1 -0
- package/dist/components/board/target-layer.js +10 -0
- package/dist/components/card-render-content.type-test.d.ts +2 -0
- package/dist/components/card-render-content.type-test.d.ts.map +1 -0
- package/dist/components/card-render-content.type-test.js +1 -0
- package/dist/components/index.d.ts +34 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +35 -0
- package/dist/components/interaction-dialog-behavior.d.ts +15 -0
- package/dist/components/interaction-dialog-behavior.d.ts.map +1 -0
- package/dist/components/interaction-dialog-behavior.js +9 -0
- package/dist/components/surfaces/BlockerSurface.d.ts +27 -0
- package/dist/components/surfaces/BlockerSurface.d.ts.map +1 -0
- package/dist/components/surfaces/BlockerSurface.js +38 -0
- package/dist/components/surfaces/BoardSurface.d.ts +77 -0
- package/dist/components/surfaces/BoardSurface.d.ts.map +1 -0
- package/dist/components/surfaces/BoardSurface.js +180 -0
- package/dist/components/surfaces/ChromeSurface.d.ts +29 -0
- package/dist/components/surfaces/ChromeSurface.d.ts.map +1 -0
- package/dist/components/surfaces/ChromeSurface.js +34 -0
- package/dist/components/surfaces/ExhaustivenessAudit.d.ts +32 -0
- package/dist/components/surfaces/ExhaustivenessAudit.d.ts.map +1 -0
- package/dist/components/surfaces/ExhaustivenessAudit.js +65 -0
- package/dist/components/surfaces/InboxSurface.d.ts +40 -0
- package/dist/components/surfaces/InboxSurface.d.ts.map +1 -0
- package/dist/components/surfaces/InboxSurface.js +99 -0
- package/dist/components/surfaces/MarketSurface.d.ts +62 -0
- package/dist/components/surfaces/MarketSurface.d.ts.map +1 -0
- package/dist/components/surfaces/MarketSurface.js +242 -0
- package/dist/components/surfaces/PanelSurface.d.ts +111 -0
- package/dist/components/surfaces/PanelSurface.d.ts.map +1 -0
- package/dist/components/surfaces/PanelSurface.js +180 -0
- package/dist/components/surfaces/PlayerCardsSurface.d.ts +104 -0
- package/dist/components/surfaces/PlayerCardsSurface.d.ts.map +1 -0
- package/dist/components/surfaces/PlayerCardsSurface.js +178 -0
- package/dist/components/surfaces/internal/CardZoneFollowUpForm.d.ts +7 -0
- package/dist/components/surfaces/internal/CardZoneFollowUpForm.d.ts.map +1 -0
- package/dist/components/surfaces/internal/CardZoneFollowUpForm.js +9 -0
- package/dist/components/surfaces/internal/DefaultInteractionButton.d.ts +71 -0
- package/dist/components/surfaces/internal/DefaultInteractionButton.d.ts.map +1 -0
- package/dist/components/surfaces/internal/DefaultInteractionButton.js +82 -0
- package/dist/components/surfaces/internal/useCardZoneInteractions.d.ts +21 -0
- package/dist/components/surfaces/internal/useCardZoneInteractions.d.ts.map +1 -0
- package/dist/components/surfaces/internal/useCardZoneInteractions.js +202 -0
- package/dist/components/surfaces/types.d.ts +59 -0
- package/dist/components/surfaces/types.d.ts.map +1 -0
- package/dist/components/surfaces/types.js +1 -0
- package/dist/context/ClientParamSchemaContext.d.ts +21 -0
- package/dist/context/ClientParamSchemaContext.d.ts.map +1 -0
- package/dist/context/ClientParamSchemaContext.js +12 -0
- package/dist/context/InteractionDraftContext.d.ts +69 -0
- package/dist/context/InteractionDraftContext.d.ts.map +1 -0
- package/dist/context/InteractionDraftContext.js +145 -0
- package/dist/context/PluginSessionContext.d.ts +33 -0
- package/dist/context/PluginSessionContext.d.ts.map +1 -0
- package/dist/context/PluginSessionContext.js +38 -0
- package/dist/context/PluginStateContext.d.ts +116 -0
- package/dist/context/PluginStateContext.d.ts.map +1 -0
- package/dist/context/PluginStateContext.js +186 -0
- package/dist/context/RuntimeContext.d.ts +49 -0
- package/dist/context/RuntimeContext.d.ts.map +1 -0
- package/dist/context/RuntimeContext.js +67 -0
- package/dist/defaults/components.d.ts +52 -0
- package/dist/defaults/components.d.ts.map +1 -0
- package/dist/defaults/components.js +159 -0
- package/dist/defaults/index.d.ts +2 -0
- package/dist/defaults/index.d.ts.map +1 -0
- package/dist/defaults/index.js +1 -0
- package/dist/errors/ValidationError.d.ts +10 -0
- package/dist/errors/ValidationError.d.ts.map +1 -0
- package/dist/errors/ValidationError.js +23 -0
- package/dist/helpers/cards.d.ts +3 -0
- package/dist/helpers/cards.d.ts.map +1 -0
- package/dist/helpers/cards.js +11 -0
- package/dist/helpers/track-board.d.ts +79 -0
- package/dist/helpers/track-board.d.ts.map +1 -0
- package/dist/helpers/track-board.js +56 -0
- package/dist/hooks/useActivePlayers.d.ts +16 -0
- package/dist/hooks/useActivePlayers.d.ts.map +1 -0
- package/dist/hooks/useActivePlayers.js +17 -0
- package/dist/hooks/useBoardInteractions.d.ts +110 -0
- package/dist/hooks/useBoardInteractions.d.ts.map +1 -0
- package/dist/hooks/useBoardInteractions.js +248 -0
- package/dist/hooks/useBoardTopology.d.ts +23 -0
- package/dist/hooks/useBoardTopology.d.ts.map +1 -0
- package/dist/hooks/useBoardTopology.js +128 -0
- package/dist/hooks/useCards.d.ts +3 -0
- package/dist/hooks/useCards.d.ts.map +1 -0
- package/dist/hooks/useCards.js +5 -0
- package/dist/hooks/useGameSelector.d.ts +13 -0
- package/dist/hooks/useGameSelector.d.ts.map +1 -0
- package/dist/hooks/useGameSelector.js +67 -0
- package/dist/hooks/useGameView.d.ts +6 -0
- package/dist/hooks/useGameView.d.ts.map +1 -0
- package/dist/hooks/useGameView.js +7 -0
- package/dist/hooks/useHandLayout.d.ts +120 -0
- package/dist/hooks/useHandLayout.d.ts.map +1 -0
- package/dist/hooks/useHandLayout.js +235 -0
- package/dist/hooks/useHexBoard.d.ts +19 -0
- package/dist/hooks/useHexBoard.d.ts.map +1 -0
- package/dist/hooks/useHexBoard.js +28 -0
- package/dist/hooks/useHexGrid.d.ts +56 -0
- package/dist/hooks/useHexGrid.d.ts.map +1 -0
- package/dist/hooks/useHexGrid.js +112 -0
- package/dist/hooks/useInteractionByKey.d.ts +29 -0
- package/dist/hooks/useInteractionByKey.d.ts.map +1 -0
- package/dist/hooks/useInteractionByKey.js +263 -0
- package/dist/hooks/useInteractionHandle.d.ts +103 -0
- package/dist/hooks/useInteractionHandle.d.ts.map +1 -0
- package/dist/hooks/useInteractionHandle.js +254 -0
- package/dist/hooks/useIsMobile.d.ts +7 -0
- package/dist/hooks/useIsMobile.d.ts.map +1 -0
- package/dist/hooks/useIsMobile.js +29 -0
- package/dist/hooks/useIsMyTurn.d.ts +6 -0
- package/dist/hooks/useIsMyTurn.d.ts.map +1 -0
- package/dist/hooks/useIsMyTurn.js +11 -0
- package/dist/hooks/useLobby.d.ts +28 -0
- package/dist/hooks/useLobby.d.ts.map +1 -0
- package/dist/hooks/useLobby.js +60 -0
- package/dist/hooks/useMe.d.ts +11 -0
- package/dist/hooks/useMe.d.ts.map +1 -0
- package/dist/hooks/useMe.js +32 -0
- package/dist/hooks/usePanZoom.d.ts +113 -0
- package/dist/hooks/usePanZoom.d.ts.map +1 -0
- package/dist/hooks/usePanZoom.js +165 -0
- package/dist/hooks/usePlayerInfo.d.ts +4 -0
- package/dist/hooks/usePlayerInfo.d.ts.map +1 -0
- package/dist/hooks/usePlayerInfo.js +21 -0
- package/dist/hooks/usePlayerTurnOrder.d.ts +15 -0
- package/dist/hooks/usePlayerTurnOrder.d.ts.map +1 -0
- package/dist/hooks/usePlayerTurnOrder.js +22 -0
- package/dist/hooks/usePluginRuntime.d.ts +45 -0
- package/dist/hooks/usePluginRuntime.d.ts.map +1 -0
- package/dist/hooks/usePluginRuntime.js +92 -0
- package/dist/hooks/useSeatInbox.d.ts +22 -0
- package/dist/hooks/useSeatInbox.d.ts.map +1 -0
- package/dist/hooks/useSeatInbox.js +43 -0
- package/dist/hooks/useSimultaneousPhase.d.ts +7 -0
- package/dist/hooks/useSimultaneousPhase.d.ts.map +1 -0
- package/dist/hooks/useSimultaneousPhase.js +8 -0
- package/dist/hooks/useSquareBoard.d.ts +21 -0
- package/dist/hooks/useSquareBoard.d.ts.map +1 -0
- package/dist/hooks/useSquareBoard.js +67 -0
- package/dist/hooks/useSquareGrid.d.ts +96 -0
- package/dist/hooks/useSquareGrid.d.ts.map +1 -0
- package/dist/hooks/useSquareGrid.js +152 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/internal/ui/alert.d.ts +8 -0
- package/dist/internal/ui/alert.d.ts.map +1 -0
- package/dist/internal/ui/alert.js +11 -0
- package/dist/internal/ui/button.d.ts +10 -0
- package/dist/internal/ui/button.d.ts.map +1 -0
- package/dist/internal/ui/button.js +21 -0
- package/dist/internal/ui/dialog.d.ts +16 -0
- package/dist/internal/ui/dialog.d.ts.map +1 -0
- package/dist/internal/ui/dialog.js +35 -0
- package/dist/internal/ui/input.d.ts +3 -0
- package/dist/internal/ui/input.d.ts.map +1 -0
- package/dist/internal/ui/input.js +5 -0
- package/dist/internal/ui/label.d.ts +4 -0
- package/dist/internal/ui/label.d.ts.map +1 -0
- package/dist/internal/ui/label.js +7 -0
- package/dist/internal/ui/select.d.ts +9 -0
- package/dist/internal/ui/select.d.ts.map +1 -0
- package/dist/internal/ui/select.js +23 -0
- package/dist/internal/ui/tooltip.d.ts +7 -0
- package/dist/internal/ui/tooltip.d.ts.map +1 -0
- package/dist/internal/ui/tooltip.js +16 -0
- package/dist/internal/ui/utils.d.ts +3 -0
- package/dist/internal/ui/utils.d.ts.map +1 -0
- package/dist/internal/ui/utils.js +4 -0
- package/dist/internal.d.ts +7 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +4 -0
- package/dist/plugin-styles.css +246 -0
- package/dist/primitives/board.d.ts +29 -0
- package/dist/primitives/board.d.ts.map +1 -0
- package/dist/primitives/board.js +163 -0
- package/dist/primitives/game-ui-provider.d.ts +12 -0
- package/dist/primitives/game-ui-provider.d.ts.map +1 -0
- package/dist/primitives/game-ui-provider.js +7 -0
- package/dist/primitives/index.d.ts +8 -0
- package/dist/primitives/index.d.ts.map +1 -0
- package/dist/primitives/index.js +7 -0
- package/dist/primitives/interaction.d.ts +52 -0
- package/dist/primitives/interaction.d.ts.map +1 -0
- package/dist/primitives/interaction.js +250 -0
- package/dist/primitives/phase.d.ts +15 -0
- package/dist/primitives/phase.d.ts.map +1 -0
- package/dist/primitives/phase.js +18 -0
- package/dist/primitives/player-roster.d.ts +64 -0
- package/dist/primitives/player-roster.d.ts.map +1 -0
- package/dist/primitives/player-roster.js +149 -0
- package/dist/primitives/primitive-props.d.ts +15 -0
- package/dist/primitives/primitive-props.d.ts.map +1 -0
- package/dist/primitives/primitive-props.js +39 -0
- package/dist/primitives/prompt.d.ts +44 -0
- package/dist/primitives/prompt.d.ts.map +1 -0
- package/dist/primitives/prompt.js +101 -0
- package/dist/primitives/zone.d.ts +31 -0
- package/dist/primitives/zone.d.ts.map +1 -0
- package/dist/primitives/zone.js +58 -0
- package/dist/reducer.d.ts +21 -0
- package/dist/reducer.d.ts.map +1 -0
- package/dist/reducer.js +14 -0
- package/dist/runtime/createPluginRuntimeAPI.d.ts +67 -0
- package/dist/runtime/createPluginRuntimeAPI.d.ts.map +1 -0
- package/dist/runtime/createPluginRuntimeAPI.js +419 -0
- package/dist/theme/ThemeProvider.d.ts +98 -0
- package/dist/theme/ThemeProvider.d.ts.map +1 -0
- package/dist/theme/ThemeProvider.js +148 -0
- package/dist/theme/board.d.ts +42 -0
- package/dist/theme/board.d.ts.map +1 -0
- package/dist/theme/board.js +34 -0
- package/dist/theme/css-vars.d.ts +31 -0
- package/dist/theme/css-vars.d.ts.map +1 -0
- package/dist/theme/css-vars.js +88 -0
- package/dist/theme/derive.d.ts +66 -0
- package/dist/theme/derive.d.ts.map +1 -0
- package/dist/theme/derive.js +161 -0
- package/dist/theme/index.d.ts +22 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +20 -0
- package/dist/theme/presets/arcade.d.ts +10 -0
- package/dist/theme/presets/arcade.d.ts.map +1 -0
- package/dist/theme/presets/arcade.js +257 -0
- package/dist/theme/presets/studio.d.ts +10 -0
- package/dist/theme/presets/studio.d.ts.map +1 -0
- package/dist/theme/presets/studio.js +257 -0
- package/dist/theme/presets/tabletop.d.ts +15 -0
- package/dist/theme/presets/tabletop.d.ts.map +1 -0
- package/dist/theme/presets/tabletop.js +262 -0
- package/dist/theme/tokens.d.ts +345 -0
- package/dist/theme/tokens.d.ts.map +1 -0
- package/dist/theme/tokens.js +57 -0
- package/dist/types/player-state.d.ts +337 -0
- package/dist/types/player-state.d.ts.map +1 -0
- package/dist/types/player-state.js +1 -0
- package/dist/types/plugin-state.d.ts +324 -0
- package/dist/types/plugin-state.d.ts.map +1 -0
- package/dist/types/plugin-state.js +1 -0
- package/dist/types/reducer-state.d.ts +10 -0
- package/dist/types/reducer-state.d.ts.map +1 -0
- package/dist/types/reducer-state.js +1 -0
- package/dist/types/runtime-api.d.ts +99 -0
- package/dist/types/runtime-api.d.ts.map +1 -0
- package/dist/types/runtime-api.js +1 -0
- package/dist/types/tiled-board.d.ts +187 -0
- package/dist/types/tiled-board.d.ts.map +1 -0
- package/dist/types/tiled-board.js +226 -0
- package/dist/ui-contract.d.ts +78 -0
- package/dist/ui-contract.d.ts.map +1 -0
- package/dist/ui-contract.js +15 -0
- package/dist/ui-sdk.d.ts +3409 -0
- package/dist/utils/interaction-inputs.d.ts +22 -0
- package/dist/utils/interaction-inputs.d.ts.map +1 -0
- package/dist/utils/interaction-inputs.js +219 -0
- package/dist/utils/interaction-labels.d.ts +4 -0
- package/dist/utils/interaction-labels.d.ts.map +1 -0
- package/dist/utils/interaction-labels.js +18 -0
- package/dist/utils/interaction-status.d.ts +15 -0
- package/dist/utils/interaction-status.d.ts.map +1 -0
- package/dist/utils/interaction-status.js +31 -0
- package/package.json +101 -0
- package/src/components/ActionButton.tsx +48 -0
- package/src/components/ActionPanel.tsx +310 -0
- package/src/components/Card.tsx +385 -0
- package/src/components/ChromeSuppressionContext.tsx +70 -0
- package/src/components/CostDisplay.test.tsx +23 -0
- package/src/components/CostDisplay.tsx +145 -0
- package/src/components/DiceRoller.tsx +601 -0
- package/src/components/Drawer.tsx +179 -0
- package/src/components/ErrorBoundary.tsx +119 -0
- package/src/components/GameEndDisplay.test.tsx +19 -0
- package/src/components/GameEndDisplay.tsx +398 -0
- package/src/components/GameSkeleton.tsx +260 -0
- package/src/components/Hand.tsx +387 -0
- package/src/components/HandDock.tsx +257 -0
- package/src/components/InteractionForm.test.tsx +303 -0
- package/src/components/InteractionForm.tsx +1029 -0
- package/src/components/MoreActions.test.tsx +93 -0
- package/src/components/MoreActions.tsx +143 -0
- package/src/components/PhaseIndicator.tsx +341 -0
- package/src/components/PlayArea.tsx +125 -0
- package/src/components/PluginRuntime.tsx +92 -0
- package/src/components/PrimaryActionButton.test.tsx +138 -0
- package/src/components/PrimaryActionButton.tsx +351 -0
- package/src/components/PrimaryButton.tsx +44 -0
- package/src/components/PromptDialogHost.tsx +92 -0
- package/src/components/ResourceCounter.test.tsx +29 -0
- package/src/components/ResourceCounter.tsx +275 -0
- package/src/components/ThemedButton.tsx +78 -0
- package/src/components/Toast.tsx +251 -0
- package/src/components/__fixtures__/ActionButton.fixture.tsx +234 -0
- package/src/components/__fixtures__/ActionPanel.fixture.tsx +298 -0
- package/src/components/__fixtures__/Card.fixture.tsx +185 -0
- package/src/components/__fixtures__/CostDisplay.fixture.tsx +156 -0
- package/src/components/__fixtures__/DiceRoller.fixture.tsx +435 -0
- package/src/components/__fixtures__/Drawer.fixture.tsx +113 -0
- package/src/components/__fixtures__/ErrorBoundary.fixture.tsx +82 -0
- package/src/components/__fixtures__/GameEndDisplay.fixture.tsx +188 -0
- package/src/components/__fixtures__/GameSkeleton.fixture.tsx +46 -0
- package/src/components/__fixtures__/Hand.fixture.tsx +522 -0
- package/src/components/__fixtures__/HexGrid.fixture.tsx +1181 -0
- package/src/components/__fixtures__/NetworkGraph.fixture.tsx +599 -0
- package/src/components/__fixtures__/PhaseIndicator.fixture.tsx +181 -0
- package/src/components/__fixtures__/PlayArea.fixture.tsx +221 -0
- package/src/components/__fixtures__/ResourceCounter.fixture.tsx +227 -0
- package/src/components/__fixtures__/SlotSystem.fixture.tsx +824 -0
- package/src/components/__fixtures__/SquareGrid.fixture.tsx +764 -0
- package/src/components/__fixtures__/Toast.fixture.tsx +97 -0
- package/src/components/__fixtures__/TrackBoard.fixture.tsx +685 -0
- package/src/components/__fixtures__/ZoneMap.fixture.tsx +754 -0
- package/src/components/board/HexGrid.tsx +1294 -0
- package/src/components/board/NetworkGraph.tsx +476 -0
- package/src/components/board/SlotSystem.tsx +339 -0
- package/src/components/board/SquareGrid.tsx +1165 -0
- package/src/components/board/TrackBoard.tsx +496 -0
- package/src/components/board/ZoneMap.tsx +448 -0
- package/src/components/board/hex-board-view.test.tsx +114 -0
- package/src/components/board/hex-board-view.ts +123 -0
- package/src/components/board/index.ts +142 -0
- package/src/components/board/interaction-accessibility.ts +21 -0
- package/src/components/board/target-layer-grids.test.tsx +420 -0
- package/src/components/board/target-layer.ts +30 -0
- package/src/components/card-render-content.type-test.ts +27 -0
- package/src/components/index.ts +208 -0
- package/src/components/interaction-dialog-behavior.test.ts +23 -0
- package/src/components/interaction-dialog-behavior.ts +22 -0
- package/src/components/surfaces/BlockerSurface.test.tsx +158 -0
- package/src/components/surfaces/BlockerSurface.tsx +127 -0
- package/src/components/surfaces/BoardSurface.tsx +340 -0
- package/src/components/surfaces/ChromeSurface.tsx +123 -0
- package/src/components/surfaces/ExhaustivenessAudit.tsx +91 -0
- package/src/components/surfaces/InboxSurface.test.tsx +149 -0
- package/src/components/surfaces/InboxSurface.tsx +245 -0
- package/src/components/surfaces/MarketSurface.tsx +544 -0
- package/src/components/surfaces/PanelSurface.test.tsx +496 -0
- package/src/components/surfaces/PanelSurface.tsx +458 -0
- package/src/components/surfaces/PlayerCardsSurface.tsx +525 -0
- package/src/components/surfaces/internal/CardZoneFollowUpForm.tsx +35 -0
- package/src/components/surfaces/internal/DefaultInteractionButton.tsx +219 -0
- package/src/components/surfaces/internal/useCardZoneInteractions.ts +311 -0
- package/src/components/surfaces/types.ts +100 -0
- package/src/context/ClientParamSchemaContext.tsx +44 -0
- package/src/context/InteractionDraftContext.tsx +204 -0
- package/src/context/PluginSessionContext.tsx +47 -0
- package/src/context/PluginStateContext.tsx +254 -0
- package/src/context/RuntimeContext.tsx +96 -0
- package/src/defaults/components.tsx +442 -0
- package/src/defaults/defaults.test.tsx +230 -0
- package/src/defaults/index.ts +1 -0
- package/src/errors/ValidationError.ts +29 -0
- package/src/helpers/cards.ts +19 -0
- package/src/helpers/track-board.ts +211 -0
- package/src/hooks/useActivePlayers.ts +19 -0
- package/src/hooks/useBoardInteractions.test.tsx +622 -0
- package/src/hooks/useBoardInteractions.ts +434 -0
- package/src/hooks/useBoardTopology.ts +316 -0
- package/src/hooks/useCards.test.tsx +129 -0
- package/src/hooks/useCards.ts +10 -0
- package/src/hooks/useGameSelector.ts +105 -0
- package/src/hooks/useGameView.ts +9 -0
- package/src/hooks/useHandLayout.ts +349 -0
- package/src/hooks/useHexBoard.ts +74 -0
- package/src/hooks/useHexGrid.ts +185 -0
- package/src/hooks/useInteractionByKey.ts +349 -0
- package/src/hooks/useInteractionHandle.ts +437 -0
- package/src/hooks/useIsMobile.ts +35 -0
- package/src/hooks/useIsMyTurn.test.tsx +99 -0
- package/src/hooks/useIsMyTurn.ts +15 -0
- package/src/hooks/useLobby.ts +76 -0
- package/src/hooks/useMe.ts +48 -0
- package/src/hooks/usePanZoom.ts +278 -0
- package/src/hooks/usePlayerInfo.ts +28 -0
- package/src/hooks/usePlayerTurnOrder.ts +23 -0
- package/src/hooks/usePluginRuntime.test.tsx +102 -0
- package/src/hooks/usePluginRuntime.ts +130 -0
- package/src/hooks/useSeatInbox.ts +61 -0
- package/src/hooks/useSimultaneousPhase.ts +10 -0
- package/src/hooks/useSquareBoard.ts +124 -0
- package/src/hooks/useSquareGrid.ts +328 -0
- package/src/index.test.ts +474 -0
- package/src/index.ts +148 -0
- package/src/internal/ui/alert.tsx +51 -0
- package/src/internal/ui/button.tsx +58 -0
- package/src/internal/ui/dialog.tsx +134 -0
- package/src/internal/ui/input.tsx +21 -0
- package/src/internal/ui/label.tsx +21 -0
- package/src/internal/ui/select.tsx +129 -0
- package/src/internal/ui/tooltip.tsx +54 -0
- package/src/internal/ui/utils.ts +5 -0
- package/src/internal.ts +18 -0
- package/src/plugin-styles.css +246 -0
- package/src/primitives/board.test.tsx +139 -0
- package/src/primitives/board.tsx +267 -0
- package/src/primitives/game-ui-provider.tsx +35 -0
- package/src/primitives/index.ts +83 -0
- package/src/primitives/interaction.test.tsx +420 -0
- package/src/primitives/interaction.tsx +405 -0
- package/src/primitives/phase.test.tsx +82 -0
- package/src/primitives/phase.tsx +43 -0
- package/src/primitives/player-roster.test.tsx +168 -0
- package/src/primitives/player-roster.tsx +301 -0
- package/src/primitives/primitive-props.tsx +82 -0
- package/src/primitives/prompt.test.tsx +159 -0
- package/src/primitives/prompt.tsx +203 -0
- package/src/primitives/zone.tsx +113 -0
- package/src/reducer.ts +42 -0
- package/src/runtime/createPluginRuntimeAPI.ts +605 -0
- package/src/theme/ThemeProvider.test.tsx +36 -0
- package/src/theme/ThemeProvider.tsx +252 -0
- package/src/theme/board.ts +61 -0
- package/src/theme/css-vars.ts +105 -0
- package/src/theme/derive.ts +240 -0
- package/src/theme/index.ts +61 -0
- package/src/theme/presets/arcade.ts +261 -0
- package/src/theme/presets/studio.ts +261 -0
- package/src/theme/presets/tabletop.ts +266 -0
- package/src/theme/theme.test.ts +258 -0
- package/src/theme/tokens.ts +392 -0
- package/src/types/player-state.ts +445 -0
- package/src/types/plugin-state.ts +407 -0
- package/src/types/reducer-state.ts +24 -0
- package/src/types/runtime-api.ts +114 -0
- package/src/types/tiled-board.ts +785 -0
- package/src/ui-contract.ts +168 -0
- package/src/utils/interaction-inputs.test.ts +109 -0
- package/src/utils/interaction-inputs.ts +331 -0
- package/src/utils/interaction-labels.ts +23 -0
- package/src/utils/interaction-status.ts +59 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Theme-aware primary CTA button — the dominant call-to-action on
|
|
4
|
+
* the screen at any given moment ("Roll dice", "End turn", "Confirm
|
|
5
|
+
* trade", "Place settlement").
|
|
6
|
+
*
|
|
7
|
+
* The shell's `chrome.primaryAction` slot accepts either a
|
|
8
|
+
* pre-rendered React node *or* an {@link InteractionHandle}. When a
|
|
9
|
+
* handle is supplied, the shell wraps it in this component so the
|
|
10
|
+
* call site collapses from ~10 lines to one. Authors who need a
|
|
11
|
+
* fully bespoke CTA can still pass any node.
|
|
12
|
+
*
|
|
13
|
+
* Visual contract (Laws of UX cross-references):
|
|
14
|
+
*
|
|
15
|
+
* - **Fitts** — defaults to `lg` size (min 56px tall, generous
|
|
16
|
+
* horizontal padding) so the dock target is easy to land on.
|
|
17
|
+
* Authors can opt down to `md`.
|
|
18
|
+
* - **Von Restorff (isolation)** — uses `intent.primary.solid` with
|
|
19
|
+
* `elevation.lifted` and an animated halo when `attention="auto"`
|
|
20
|
+
* and the descriptor is available, so the button outranks every
|
|
21
|
+
* other element in its peripheral neighbourhood.
|
|
22
|
+
* - **Peak-end** — when the action becomes available (handle flips
|
|
23
|
+
* from disabled → enabled), the halo pulses for one breath cycle
|
|
24
|
+
* so the eye finds the change without re-scanning the screen.
|
|
25
|
+
* - **Doherty / responsiveness** — clicks set an internal `pending`
|
|
26
|
+
* flag the moment submit fires so the button visibly absorbs the
|
|
27
|
+
* tap, even on slow networks. Throwing submitters are swallowed
|
|
28
|
+
* here for the same reason `<DefaultInteractionButton>` does:
|
|
29
|
+
* descriptor availability is authoritative.
|
|
30
|
+
* - **Accessibility** — minimum 56×56 hit area satisfies WCAG 2.5.5.
|
|
31
|
+
* `prefers-reduced-motion` zeroes out the halo and press
|
|
32
|
+
* transitions through the theme's `motion.reducedMotion` token.
|
|
33
|
+
*/
|
|
34
|
+
import { useEffect, useRef, useState, } from "react";
|
|
35
|
+
import { motion } from "framer-motion";
|
|
36
|
+
import { useTheme } from "../theme/ThemeProvider.js";
|
|
37
|
+
import { intentForVariant, } from "../theme/derive.js";
|
|
38
|
+
import { interactionLabel } from "../utils/interaction-labels.js";
|
|
39
|
+
import { ThemedButton } from "./ThemedButton.js";
|
|
40
|
+
/**
|
|
41
|
+
* @see PrimaryActionButtonProps
|
|
42
|
+
*/
|
|
43
|
+
export function PrimaryActionButton({ handle, variant = "primary", size = "lg", label, ready = true, whenSubmitted, icon, params, attention = "auto", style, className, }) {
|
|
44
|
+
const theme = useTheme();
|
|
45
|
+
const reducedMotion = theme.motion.reducedMotion === "true";
|
|
46
|
+
const [pending, setPending] = useState(false);
|
|
47
|
+
const descriptor = handle.descriptor;
|
|
48
|
+
const submitted = handle.status === "submitted";
|
|
49
|
+
const submitting = handle.status === "submitting" || pending;
|
|
50
|
+
const available = descriptor.available && ready && !submitted && !submitting;
|
|
51
|
+
const resolvedVariant = submitted
|
|
52
|
+
? (whenSubmitted?.variant ?? "submitted")
|
|
53
|
+
: variant;
|
|
54
|
+
const disabled = !available;
|
|
55
|
+
const intent = intentForVariant(theme, resolvedVariant);
|
|
56
|
+
// Pulse the halo for one breath when availability flips on. After
|
|
57
|
+
// the breath we settle into the ambient cadence (or stop, when
|
|
58
|
+
// `attention` is `off`). Tracking the previous availability lets
|
|
59
|
+
// us catch the transition without re-mounting the component.
|
|
60
|
+
const previouslyAvailableRef = useRef(available);
|
|
61
|
+
const [pulseKey, setPulseKey] = useState(0);
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (!previouslyAvailableRef.current && available) {
|
|
64
|
+
setPulseKey((n) => n + 1);
|
|
65
|
+
}
|
|
66
|
+
previouslyAvailableRef.current = available;
|
|
67
|
+
}, [available]);
|
|
68
|
+
const haloEnabled = !reducedMotion && available && attention !== "off" && !submitted;
|
|
69
|
+
const fallbackLabel = interactionLabel(descriptor);
|
|
70
|
+
const tooltip = available
|
|
71
|
+
? undefined
|
|
72
|
+
: formatUnavailableReason(descriptor.unavailableReason);
|
|
73
|
+
const resolvedLabel = submitted
|
|
74
|
+
? (whenSubmitted?.label ?? label ?? fallbackLabel)
|
|
75
|
+
: (label ?? fallbackLabel);
|
|
76
|
+
const resolvedIcon = submitted && whenSubmitted?.icon ? (_jsx("span", { "aria-hidden": true, style: { fontSize: "1.15em" }, children: whenSubmitted.icon })) : ((icon ?? null));
|
|
77
|
+
return (_jsxs("span", { "data-dreamboard-primary-action": true, "data-available": available ? "true" : "false", "data-pending": submitting ? "true" : undefined, "data-action-state": submitted
|
|
78
|
+
? "submitted"
|
|
79
|
+
: submitting
|
|
80
|
+
? "submitting"
|
|
81
|
+
: available
|
|
82
|
+
? "available"
|
|
83
|
+
: "unavailable", style: {
|
|
84
|
+
position: "relative",
|
|
85
|
+
display: "inline-flex",
|
|
86
|
+
alignItems: "center",
|
|
87
|
+
justifyContent: "center",
|
|
88
|
+
// The halo overflows the button bounds; the wrapper reserves
|
|
89
|
+
// a transparent buffer so it doesn't get clipped by the
|
|
90
|
+
// dock's safe-area frame.
|
|
91
|
+
padding: theme.space[1],
|
|
92
|
+
}, children: [haloEnabled ? (_jsxs(_Fragment, { children: [_jsx(motion.span, { "aria-hidden": true, style: {
|
|
93
|
+
position: "absolute",
|
|
94
|
+
inset: 0,
|
|
95
|
+
borderRadius: theme.radius.md,
|
|
96
|
+
background: intent.soft,
|
|
97
|
+
opacity: 0.55,
|
|
98
|
+
pointerEvents: "none",
|
|
99
|
+
}, animate: {
|
|
100
|
+
scale: [1, 1.06, 1],
|
|
101
|
+
opacity: [0.45, 0.18, 0.45],
|
|
102
|
+
}, transition: {
|
|
103
|
+
repeat: Infinity,
|
|
104
|
+
duration: 2.4,
|
|
105
|
+
ease: "easeInOut",
|
|
106
|
+
} }), _jsx(motion.span, { "aria-hidden": true, style: {
|
|
107
|
+
position: "absolute",
|
|
108
|
+
inset: 0,
|
|
109
|
+
borderRadius: theme.radius.md,
|
|
110
|
+
boxShadow: `0 0 0 0 ${intent.solid}`,
|
|
111
|
+
pointerEvents: "none",
|
|
112
|
+
}, initial: { opacity: 0.7 }, animate: {
|
|
113
|
+
boxShadow: [
|
|
114
|
+
`0 0 0 0 ${withAlpha(intent.solid, 0.55)}`,
|
|
115
|
+
`0 0 0 14px ${withAlpha(intent.solid, 0)}`,
|
|
116
|
+
],
|
|
117
|
+
opacity: [0.7, 0],
|
|
118
|
+
}, transition: { duration: 0.9, ease: "easeOut" } }, pulseKey)] })) : null, _jsxs(ThemedButton, { type: "button", variant: resolvedVariant, size: size, pressed: submitting, className: className, "aria-label": typeof resolvedLabel === "string" ? resolvedLabel : fallbackLabel, "aria-disabled": disabled || undefined, "data-interaction-id": descriptor.interactionId, "data-emphasis": "primary", title: tooltip, disabled: disabled, style: {
|
|
119
|
+
// Sit above the halo so clicks land on the button.
|
|
120
|
+
position: "relative",
|
|
121
|
+
zIndex: 1,
|
|
122
|
+
boxShadow: disabled || submitted ? undefined : theme.elevation.lifted,
|
|
123
|
+
...style,
|
|
124
|
+
}, onClick: async (event) => {
|
|
125
|
+
event.preventDefault();
|
|
126
|
+
if (disabled)
|
|
127
|
+
return;
|
|
128
|
+
setPending(true);
|
|
129
|
+
try {
|
|
130
|
+
if (params !== undefined) {
|
|
131
|
+
await handle.submit(params);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
await handle.submitDraft();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
// Descriptor availability is authoritative; submit errors
|
|
139
|
+
// surface via the runtime's error channel.
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
setPending(false);
|
|
143
|
+
}
|
|
144
|
+
}, children: [resolvedIcon, _jsx("span", { children: resolvedLabel })] })] }));
|
|
145
|
+
}
|
|
146
|
+
function formatUnavailableReason(reason) {
|
|
147
|
+
if (reason === "INSUFFICIENT_RESOURCES") {
|
|
148
|
+
return "Insufficient resources";
|
|
149
|
+
}
|
|
150
|
+
return reason;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Add an alpha channel to a CSS colour string. Supports `#rgb`,
|
|
154
|
+
* `#rrggbb`, and any colour the browser can paint via a fallback to
|
|
155
|
+
* `color-mix` (modern Safari/Chrome/Firefox all support this; older
|
|
156
|
+
* runtimes get the original colour without alpha which is still
|
|
157
|
+
* visible — the halo is decorative).
|
|
158
|
+
*/
|
|
159
|
+
function withAlpha(color, alpha) {
|
|
160
|
+
const trimmed = color.trim();
|
|
161
|
+
if (trimmed.startsWith("#")) {
|
|
162
|
+
const hex = trimmed.slice(1);
|
|
163
|
+
if (hex.length === 3) {
|
|
164
|
+
// `String.prototype.slice` always returns a string (possibly
|
|
165
|
+
// empty) — never `undefined` — so duplicating each digit is
|
|
166
|
+
// safe to feed to `parseInt` without further narrowing.
|
|
167
|
+
const r = parseInt(hex.slice(0, 1).repeat(2), 16);
|
|
168
|
+
const g = parseInt(hex.slice(1, 2).repeat(2), 16);
|
|
169
|
+
const b = parseInt(hex.slice(2, 3).repeat(2), 16);
|
|
170
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
171
|
+
}
|
|
172
|
+
if (hex.length === 6) {
|
|
173
|
+
const r = parseInt(hex.slice(0, 2), 16);
|
|
174
|
+
const g = parseInt(hex.slice(2, 4), 16);
|
|
175
|
+
const b = parseInt(hex.slice(4, 6), 16);
|
|
176
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// Best-effort fallback for non-hex colours (rgb/hsl/named): use
|
|
180
|
+
// `color-mix` with transparent. Safe to land in inline style — the
|
|
181
|
+
// halo is purely decorative and will gracefully degrade.
|
|
182
|
+
return `color-mix(in srgb, ${trimmed} ${Math.round(alpha * 100)}%, transparent)`;
|
|
183
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimally-styled primary action button.
|
|
3
|
+
*
|
|
4
|
+
* Visual styling now flows through {@link buttonStyle}: the background,
|
|
5
|
+
* border, foreground, radius, typography and elevation all derive from
|
|
6
|
+
* the active {@link useTheme}'s `intent.primary` slot. Override the
|
|
7
|
+
* variant when a non-primary call site needs a different emphasis (the
|
|
8
|
+
* underlying `<DefaultInteractionButton>` is the canonical button for
|
|
9
|
+
* interaction-bound submission).
|
|
10
|
+
*/
|
|
11
|
+
import type { ButtonHTMLAttributes } from "react";
|
|
12
|
+
import type { ButtonSize, ButtonVariant } from "../theme/derive.js";
|
|
13
|
+
export interface PrimaryButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
14
|
+
/** Intent slot — defaults to `primary`. */
|
|
15
|
+
variant?: ButtonVariant;
|
|
16
|
+
/** Sizing token — defaults to `md`. */
|
|
17
|
+
size?: ButtonSize;
|
|
18
|
+
}
|
|
19
|
+
export declare function PrimaryButton({ children, disabled, style, variant, size, ...rest }: PrimaryButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=PrimaryButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrimaryButton.d.ts","sourceRoot":"","sources":["../../src/components/PrimaryButton.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGpE,MAAM,WAAW,kBACf,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;IAC/C,2CAA2C;IAC3C,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,uCAAuC;IACvC,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,OAAmB,EACnB,IAAW,EACX,GAAG,IAAI,EACR,EAAE,kBAAkB,2CAapB"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { ThemedButton } from "./ThemedButton.js";
|
|
3
|
+
export function PrimaryButton({ children, disabled, style, variant = "primary", size = "md", ...rest }) {
|
|
4
|
+
return (_jsx(ThemedButton, { type: "button", disabled: disabled, variant: variant, size: size, style: style, ...rest, children: children }));
|
|
5
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { InteractionContextOption, InteractionDescriptor } from "../types/plugin-state.js";
|
|
3
|
+
export interface PromptDialogHostProps {
|
|
4
|
+
contentClassName?: string;
|
|
5
|
+
messageClassName?: string;
|
|
6
|
+
optionClassName?: string;
|
|
7
|
+
optionsClassName?: string;
|
|
8
|
+
overlayClassName?: string;
|
|
9
|
+
titleClassName?: string;
|
|
10
|
+
renderBody?: (prompt: InteractionDescriptor) => ReactNode;
|
|
11
|
+
renderOptionLabel?: (option: InteractionContextOption, prompt: InteractionDescriptor) => ReactNode;
|
|
12
|
+
onSubmitError?: (error: unknown, prompt: InteractionDescriptor, option: InteractionContextOption) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare function PromptDialogHost(props: PromptDialogHostProps): import("react/jsx-runtime").JSX.Element | null;
|
|
15
|
+
//# sourceMappingURL=PromptDialogHost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PromptDialogHost.d.ts","sourceRoot":"","sources":["../../src/components/PromptDialogHost.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAK5D,OAAO,KAAK,EACV,wBAAwB,EACxB,qBAAqB,EACtB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,SAAS,CAAC;IAC1D,iBAAiB,CAAC,EAAE,CAClB,MAAM,EAAE,wBAAwB,EAChC,MAAM,EAAE,qBAAqB,KAC1B,SAAS,CAAC;IACf,aAAa,CAAC,EAAE,CACd,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,qBAAqB,EAC7B,MAAM,EAAE,wBAAwB,KAC7B,IAAI,CAAC;CACX;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,kDAO5D"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { clsx } from "clsx";
|
|
4
|
+
import { Dialog, DialogContent, DialogTitle } from "../internal/ui/dialog.js";
|
|
5
|
+
import { useSeatInbox } from "../hooks/useSeatInbox.js";
|
|
6
|
+
import { Prompt } from "../primitives/prompt.js";
|
|
7
|
+
export function PromptDialogHost(props) {
|
|
8
|
+
const { prompts } = useSeatInbox();
|
|
9
|
+
const prompt = prompts[0];
|
|
10
|
+
if (!prompt)
|
|
11
|
+
return null;
|
|
12
|
+
return (_jsx(PromptDialog, { prompt: prompt, ...props }, prompt.interactionKey));
|
|
13
|
+
}
|
|
14
|
+
function PromptDialog({ contentClassName, messageClassName, optionClassName, optionsClassName, overlayClassName, prompt, renderBody, renderOptionLabel, titleClassName, onSubmitError, }) {
|
|
15
|
+
const [open, setOpen] = useState(true);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
setOpen(true);
|
|
18
|
+
}, [prompt.interactionKey]);
|
|
19
|
+
return (_jsx(Dialog, { open: open, onOpenChange: setOpen, children: _jsx(DialogContent, { className: contentClassName, overlayClassName: overlayClassName, children: _jsxs(Prompt.Root, { interaction: prompt.interactionKey, children: [_jsx(DialogTitle, { className: titleClassName, children: _jsx(Prompt.Title, {}) }), _jsx(Prompt.Message, { className: messageClassName }), renderBody?.(prompt), _jsx("div", { className: clsx("flex flex-wrap gap-2", optionsClassName), children: (prompt.context?.options ?? []).map((option) => (_jsx(Prompt.Option, { className: optionClassName, value: option.id, onSubmitSuccess: () => setOpen(false), onSubmitError: (error) => onSubmitError?.(error, prompt, option), children: renderOptionLabel?.(option, prompt) ??
|
|
20
|
+
option.label ??
|
|
21
|
+
option.id }, option.id))) })] }) }) }));
|
|
22
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Displays resource counts with icons and animated updates.
|
|
3
|
+
*
|
|
4
|
+
* The chip frame (border, fill, shadow, padding, gap) is sourced from
|
|
5
|
+
* the active {@link useTheme}. Authors can still override per-chip
|
|
6
|
+
* colours via {@link ResourceDisplayConfig.bgColor} /
|
|
7
|
+
* {@link ResourceDisplayConfig.iconColor} / {@link ResourceDisplayConfig.textColor}
|
|
8
|
+
* (Tailwind class names) — those win over the theme defaults so existing
|
|
9
|
+
* callers that pass game-specific palettes (Catan: wheat/wood/brick…)
|
|
10
|
+
* keep their look.
|
|
11
|
+
*/
|
|
12
|
+
import { type ComponentType, type ReactNode } from "react";
|
|
13
|
+
import type { ResourceId } from "@dreamboard/manifest-contract";
|
|
14
|
+
export interface ResourceDisplayConfig {
|
|
15
|
+
type: ResourceId;
|
|
16
|
+
label: string;
|
|
17
|
+
icon: ReactNode | ComponentType<{
|
|
18
|
+
className?: string;
|
|
19
|
+
strokeWidth?: number;
|
|
20
|
+
"aria-hidden"?: string;
|
|
21
|
+
}>;
|
|
22
|
+
iconColor?: string;
|
|
23
|
+
bgColor?: string;
|
|
24
|
+
textColor?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface ResourceCounterProps {
|
|
27
|
+
resources: ResourceDisplayConfig[];
|
|
28
|
+
counts: Record<ResourceId, number>;
|
|
29
|
+
layout?: "row" | "grid" | "compact";
|
|
30
|
+
/** Number of columns for grid layout */
|
|
31
|
+
columns?: number;
|
|
32
|
+
showZero?: boolean;
|
|
33
|
+
size?: "sm" | "md" | "lg";
|
|
34
|
+
onResourceClick?: (resourceType: ResourceId) => void;
|
|
35
|
+
className?: string;
|
|
36
|
+
}
|
|
37
|
+
export declare function ResourceCounter({ resources, counts, layout, columns, showZero, size, onResourceClick, className, }: ResourceCounterProps): import("react/jsx-runtime").JSX.Element;
|
|
38
|
+
//# sourceMappingURL=ResourceCounter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResourceCounter.d.ts","sourceRoot":"","sources":["../../src/components/ResourceCounter.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAiB,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAahE,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EACA,SAAS,GACT,aAAa,CAAC;QACZ,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC,CAAC;IACP,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,qBAAqB,EAAE,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACnC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;IACpC,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,UAAU,KAAK,IAAI,CAAC;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,eAAe,CAAC,EAC9B,SAAS,EACT,MAAM,EACN,MAAc,EACd,OAAW,EACX,QAAe,EACf,IAAW,EACX,eAAe,EACf,SAAS,GACV,EAAE,oBAAoB,2CAkNtB"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Displays resource counts with icons and animated updates.
|
|
4
|
+
*
|
|
5
|
+
* The chip frame (border, fill, shadow, padding, gap) is sourced from
|
|
6
|
+
* the active {@link useTheme}. Authors can still override per-chip
|
|
7
|
+
* colours via {@link ResourceDisplayConfig.bgColor} /
|
|
8
|
+
* {@link ResourceDisplayConfig.iconColor} / {@link ResourceDisplayConfig.textColor}
|
|
9
|
+
* (Tailwind class names) — those win over the theme defaults so existing
|
|
10
|
+
* callers that pass game-specific palettes (Catan: wheat/wood/brick…)
|
|
11
|
+
* keep their look.
|
|
12
|
+
*/
|
|
13
|
+
import { motion, AnimatePresence } from "framer-motion";
|
|
14
|
+
import { clsx } from "clsx";
|
|
15
|
+
import { createElement } from "react";
|
|
16
|
+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "../internal/ui/tooltip.js";
|
|
17
|
+
import { useTheme } from "../theme/ThemeProvider.js";
|
|
18
|
+
export function ResourceCounter({ resources, counts, layout = "row", columns = 5, showZero = true, size = "md", onResourceClick, className, }) {
|
|
19
|
+
const theme = useTheme();
|
|
20
|
+
const reducedMotion = theme.motion.reducedMotion === "true";
|
|
21
|
+
const sizeConfig = {
|
|
22
|
+
sm: {
|
|
23
|
+
icon: "w-4 h-4",
|
|
24
|
+
fontSize: theme.typography.fontSize.sm,
|
|
25
|
+
paddingBlock: theme.space[1],
|
|
26
|
+
paddingInline: theme.space[2],
|
|
27
|
+
gap: theme.space[1],
|
|
28
|
+
},
|
|
29
|
+
md: {
|
|
30
|
+
icon: "w-5 h-5",
|
|
31
|
+
fontSize: theme.typography.fontSize.md,
|
|
32
|
+
paddingBlock: theme.space[1.5],
|
|
33
|
+
paddingInline: theme.space[3],
|
|
34
|
+
gap: theme.space[1.5],
|
|
35
|
+
},
|
|
36
|
+
lg: {
|
|
37
|
+
icon: "w-6 h-6",
|
|
38
|
+
fontSize: theme.typography.fontSize.lg,
|
|
39
|
+
paddingBlock: theme.space[2],
|
|
40
|
+
paddingInline: theme.space[4],
|
|
41
|
+
gap: theme.space[2],
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
const styles = sizeConfig[size];
|
|
45
|
+
const filteredResources = showZero
|
|
46
|
+
? resources
|
|
47
|
+
: resources.filter((r) => (counts[r.type] ?? 0) > 0);
|
|
48
|
+
// Base chip styling pulled from the theme. Caller-supplied
|
|
49
|
+
// `bgColor`/`textColor` (Tailwind classes) override these inline
|
|
50
|
+
// defaults via the `style` cascade — when a Tailwind class sets
|
|
51
|
+
// `background-color`, it wins because we don't pass `background`
|
|
52
|
+
// when the caller provided a `bgColor` class.
|
|
53
|
+
const baseChipStyle = (bgColorClass) => ({
|
|
54
|
+
display: "inline-flex",
|
|
55
|
+
alignItems: "center",
|
|
56
|
+
gap: styles.gap,
|
|
57
|
+
paddingBlock: styles.paddingBlock,
|
|
58
|
+
paddingInline: styles.paddingInline,
|
|
59
|
+
borderRadius: theme.radius.md,
|
|
60
|
+
border: `2px solid ${theme.semantic.border.default}`,
|
|
61
|
+
background: bgColorClass ? undefined : theme.semantic.surface.card,
|
|
62
|
+
boxShadow: theme.elevation.rest,
|
|
63
|
+
fontFamily: theme.typography.fontFamily.body,
|
|
64
|
+
transition: `transform ${theme.motion.duration.fast} ${theme.motion.easing.out}, box-shadow ${theme.motion.duration.normal} ${theme.motion.easing.out}`,
|
|
65
|
+
});
|
|
66
|
+
return (_jsx("div", { className: clsx(layout === "grid" && "grid", layout === "row" && "flex flex-wrap", layout === "compact" && "flex flex-wrap", layout === "row" && "gap-3 sm:gap-4", layout === "compact" && "gap-2", layout === "grid" && "gap-3 sm:gap-4", className), style: layout === "grid"
|
|
67
|
+
? {
|
|
68
|
+
gridTemplateColumns: `repeat(${columns}, 1fr)`,
|
|
69
|
+
fontFamily: theme.typography.fontFamily.body,
|
|
70
|
+
}
|
|
71
|
+
: { fontFamily: theme.typography.fontFamily.body }, role: "list", "aria-label": "Resource counts", children: _jsx(TooltipProvider, { delayDuration: 200, children: _jsx(AnimatePresence, { mode: "popLayout", children: filteredResources.map(({ type, label, icon, iconColor, bgColor, textColor }) => {
|
|
72
|
+
const count = counts[type] ?? 0;
|
|
73
|
+
const iconNode = typeof icon === "function" ? (createElement(icon, {
|
|
74
|
+
className: clsx(styles.icon, iconColor),
|
|
75
|
+
strokeWidth: 2.5,
|
|
76
|
+
"aria-hidden": "true",
|
|
77
|
+
})) : (_jsx("span", { className: clsx(styles.icon, iconColor), "aria-hidden": "true", style: {
|
|
78
|
+
display: "inline-flex",
|
|
79
|
+
alignItems: "center",
|
|
80
|
+
justifyContent: "center",
|
|
81
|
+
fontSize: "1.1em",
|
|
82
|
+
}, children: icon }));
|
|
83
|
+
const content = (_jsxs(_Fragment, { children: [iconNode, _jsx(motion.span, { initial: reducedMotion ? { scale: 1 } : { scale: 1.5 }, animate: { scale: 1 }, className: clsx("font-bold", textColor), style: {
|
|
84
|
+
fontSize: styles.fontSize,
|
|
85
|
+
fontFamily: theme.typography.fontFamily.tabular,
|
|
86
|
+
fontWeight: theme.typography.fontWeight.bold,
|
|
87
|
+
color: textColor
|
|
88
|
+
? undefined
|
|
89
|
+
: theme.semantic.text.primary,
|
|
90
|
+
}, children: count }, count)] }));
|
|
91
|
+
const sharedClassName = clsx("flex items-center focus-visible:outline-none", bgColor, onResourceClick
|
|
92
|
+
? "cursor-pointer focus-visible:ring-2 focus-visible:ring-offset-2"
|
|
93
|
+
: "cursor-help");
|
|
94
|
+
const sharedStyle = {
|
|
95
|
+
...baseChipStyle(bgColor),
|
|
96
|
+
color: textColor ? undefined : theme.semantic.text.primary,
|
|
97
|
+
};
|
|
98
|
+
const focusVisibleStyle = onResourceClick
|
|
99
|
+
? {
|
|
100
|
+
// Theming the focus ring requires a CSS variable hop
|
|
101
|
+
// because Tailwind's focus-visible:ring-offset uses
|
|
102
|
+
// `--tw-ring-offset-color`. We expose the theme
|
|
103
|
+
// border.focus token here so consumers without our
|
|
104
|
+
// Tailwind preset still get a visible ring.
|
|
105
|
+
"--tw-ring-color": theme.semantic.border.focus,
|
|
106
|
+
"--tw-ring-offset-color": theme.semantic.surface.app,
|
|
107
|
+
}
|
|
108
|
+
: {};
|
|
109
|
+
const chip = onResourceClick ? (_jsx("button", { type: "button", onClick: () => onResourceClick(type), className: sharedClassName, style: { ...sharedStyle, ...focusVisibleStyle }, "aria-label": `${label}: ${count}`, children: content })) : (_jsx("div", { className: sharedClassName, style: sharedStyle, "aria-label": `${label}: ${count}`, children: content }));
|
|
110
|
+
return (_jsx(motion.div, { layout: !reducedMotion, initial: reducedMotion
|
|
111
|
+
? { opacity: 0, scale: 1 }
|
|
112
|
+
: { opacity: 0, scale: 0.8 }, animate: { opacity: 1, scale: 1 }, exit: { opacity: 0, scale: 0.8 }, whileHover: onResourceClick && !reducedMotion
|
|
113
|
+
? { scale: 1.05 }
|
|
114
|
+
: undefined, whileTap: onResourceClick && !reducedMotion
|
|
115
|
+
? { scale: 0.95 }
|
|
116
|
+
: undefined, role: "listitem", children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: chip }), _jsxs(TooltipContent, { side: "top", sideOffset: 6, children: [_jsx("p", { className: "font-sans text-sm font-bold", children: label }), _jsxs("p", { className: "font-sans text-xs font-normal opacity-90", children: ["Quantity: ", count] })] })] }) }, type));
|
|
117
|
+
}) }) }) }));
|
|
118
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ComponentProps } from "react";
|
|
2
|
+
import { Button as ShadcnButton } from "../internal/ui/button.js";
|
|
3
|
+
import { type ButtonSize, type ButtonVariant } from "../theme/derive.js";
|
|
4
|
+
type ShadcnButtonProps = ComponentProps<typeof ShadcnButton>;
|
|
5
|
+
export interface ThemedButtonProps extends Omit<ShadcnButtonProps, "variant" | "size"> {
|
|
6
|
+
variant?: ButtonVariant;
|
|
7
|
+
size?: ButtonSize;
|
|
8
|
+
pressed?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function ThemedButton({ variant, size, pressed, disabled, className, style, ...props }: ThemedButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=ThemedButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThemedButton.d.ts","sourceRoot":"","sources":["../../src/components/ThemedButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAC;AAG5B,KAAK,iBAAiB,GAAG,cAAc,CAAC,OAAO,YAAY,CAAC,CAAC;AAE7D,MAAM,WAAW,iBACf,SAAQ,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,MAAM,CAAC;IACnD,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,YAAY,CAAC,EAC3B,OAAmB,EACnB,IAAW,EACX,OAAe,EACf,QAAQ,EACR,SAAS,EACT,KAAK,EACL,GAAG,KAAK,EACT,EAAE,iBAAiB,2CAkBnB"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
|
+
import { Button as ShadcnButton } from "../internal/ui/button.js";
|
|
4
|
+
import { buttonStyle, } from "../theme/derive.js";
|
|
5
|
+
import { useTheme } from "../theme/ThemeProvider.js";
|
|
6
|
+
export function ThemedButton({ variant = "primary", size = "md", pressed = false, disabled, className, style, ...props }) {
|
|
7
|
+
const theme = useTheme();
|
|
8
|
+
return (_jsx(ShadcnButton, { variant: toShadcnVariant(variant), size: toShadcnSize(size), disabled: disabled, "data-dreamboard-button": true, "data-dreamboard-button-variant": variant, "data-dreamboard-button-size": size, className: clsx("font-sans", className), style: {
|
|
9
|
+
...buttonStyle(theme, { variant, size, disabled, pressed }),
|
|
10
|
+
...style,
|
|
11
|
+
}, ...props }));
|
|
12
|
+
}
|
|
13
|
+
function toShadcnVariant(variant) {
|
|
14
|
+
switch (variant) {
|
|
15
|
+
case "danger":
|
|
16
|
+
return "destructive";
|
|
17
|
+
case "ghost":
|
|
18
|
+
return "ghost";
|
|
19
|
+
case "secondary":
|
|
20
|
+
return "secondary";
|
|
21
|
+
case "primary":
|
|
22
|
+
case "submitted":
|
|
23
|
+
case "success":
|
|
24
|
+
case "warning":
|
|
25
|
+
case "info":
|
|
26
|
+
return "default";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function toShadcnSize(size) {
|
|
30
|
+
switch (size) {
|
|
31
|
+
case "sm":
|
|
32
|
+
return "sm";
|
|
33
|
+
case "md":
|
|
34
|
+
return "default";
|
|
35
|
+
case "lg":
|
|
36
|
+
return "lg";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin-internal toast notification system.
|
|
3
|
+
*
|
|
4
|
+
* `<ToastProvider>` exposes a `useToast()` API that game authors call
|
|
5
|
+
* imperatively to surface their own game-specific feedback ("Resource
|
|
6
|
+
* gained", "Card discarded", "Tip: rotate the board with R", …). It
|
|
7
|
+
* is intentionally NOT wired to the host notification stream:
|
|
8
|
+
* `YOUR_TURN`, `PROMPT_OPENED` and `ACTION_REJECTED` events are owned
|
|
9
|
+
* by `@dreamboard/ui-host-runtime`'s `<HostFeedbackToaster>` and must
|
|
10
|
+
* not be mirrored from inside the plugin tree.
|
|
11
|
+
*/
|
|
12
|
+
import { type ReactNode } from "react";
|
|
13
|
+
export type ToastType = "success" | "error" | "info" | "warning";
|
|
14
|
+
export interface Toast {
|
|
15
|
+
id: string;
|
|
16
|
+
type: ToastType;
|
|
17
|
+
message: string;
|
|
18
|
+
duration?: number;
|
|
19
|
+
}
|
|
20
|
+
interface ToastContextValue {
|
|
21
|
+
toasts: Toast[];
|
|
22
|
+
show: (message: string, type?: ToastType, duration?: number) => void;
|
|
23
|
+
dismiss: (id: string) => void;
|
|
24
|
+
success: (message: string, duration?: number) => void;
|
|
25
|
+
error: (message: string, duration?: number) => void;
|
|
26
|
+
info: (message: string, duration?: number) => void;
|
|
27
|
+
warning: (message: string, duration?: number) => void;
|
|
28
|
+
}
|
|
29
|
+
export interface ToastProviderProps {
|
|
30
|
+
children: ReactNode;
|
|
31
|
+
}
|
|
32
|
+
export declare function ToastProvider({ children }: ToastProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
export declare function useToast(): ToastContextValue;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=Toast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toast.d.ts","sourceRoot":"","sources":["../../src/components/Toast.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAMf,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAEjE,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,iBAAiB;IACzB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACtD,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACvD;AAID,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE,kBAAkB,2CA4D7D;AAED,wBAAgB,QAAQ,sBAMvB"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Plugin-internal toast notification system.
|
|
4
|
+
*
|
|
5
|
+
* `<ToastProvider>` exposes a `useToast()` API that game authors call
|
|
6
|
+
* imperatively to surface their own game-specific feedback ("Resource
|
|
7
|
+
* gained", "Card discarded", "Tip: rotate the board with R", …). It
|
|
8
|
+
* is intentionally NOT wired to the host notification stream:
|
|
9
|
+
* `YOUR_TURN`, `PROMPT_OPENED` and `ACTION_REJECTED` events are owned
|
|
10
|
+
* by `@dreamboard/ui-host-runtime`'s `<HostFeedbackToaster>` and must
|
|
11
|
+
* not be mirrored from inside the plugin tree.
|
|
12
|
+
*/
|
|
13
|
+
import { motion, AnimatePresence } from "framer-motion";
|
|
14
|
+
import { X, CheckCircle, AlertCircle, Info, AlertTriangle } from "lucide-react";
|
|
15
|
+
import { Alert, AlertDescription } from "../internal/ui/alert.js";
|
|
16
|
+
import { createContext, useContext, useState, useCallback, } from "react";
|
|
17
|
+
import { useTheme } from "../theme/ThemeProvider.js";
|
|
18
|
+
import { intentForVariant } from "../theme/derive.js";
|
|
19
|
+
import { ThemedButton } from "./ThemedButton.js";
|
|
20
|
+
const ToastContext = createContext(null);
|
|
21
|
+
export function ToastProvider({ children }) {
|
|
22
|
+
const [toasts, setToasts] = useState([]);
|
|
23
|
+
const show = useCallback((message, type = "info", duration = 3000) => {
|
|
24
|
+
const id = `toast-${Date.now()}-${Math.random()}`;
|
|
25
|
+
const toast = { id, type, message, duration };
|
|
26
|
+
setToasts((prev) => {
|
|
27
|
+
// Dedup by `(type, message)` so a fast burst of identical
|
|
28
|
+
// toasts collapses to one visible toast instead of stacking
|
|
29
|
+
// and producing the flicker effect (toast-1 dismisses while
|
|
30
|
+
// toast-2 mounts → user sees a flash). Keep the existing
|
|
31
|
+
// entry untouched so its dismiss timer continues.
|
|
32
|
+
if (prev.some((item) => item.type === type && item.message === message)) {
|
|
33
|
+
return prev;
|
|
34
|
+
}
|
|
35
|
+
return [...prev, toast];
|
|
36
|
+
});
|
|
37
|
+
if (duration > 0) {
|
|
38
|
+
setTimeout(() => {
|
|
39
|
+
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
40
|
+
}, duration);
|
|
41
|
+
}
|
|
42
|
+
}, []);
|
|
43
|
+
const dismiss = useCallback((id) => {
|
|
44
|
+
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
45
|
+
}, []);
|
|
46
|
+
const success = useCallback((message, duration) => show(message, "success", duration), [show]);
|
|
47
|
+
const error = useCallback((message, duration) => show(message, "error", duration), [show]);
|
|
48
|
+
const info = useCallback((message, duration) => show(message, "info", duration), [show]);
|
|
49
|
+
const warning = useCallback((message, duration) => show(message, "warning", duration), [show]);
|
|
50
|
+
return (_jsxs(ToastContext.Provider, { value: { toasts, show, dismiss, success, error, info, warning }, children: [children, _jsx(ToastContainer, { toasts: toasts, onDismiss: dismiss })] }));
|
|
51
|
+
}
|
|
52
|
+
export function useToast() {
|
|
53
|
+
const context = useContext(ToastContext);
|
|
54
|
+
if (!context) {
|
|
55
|
+
throw new Error("useToast must be used within ToastProvider");
|
|
56
|
+
}
|
|
57
|
+
return context;
|
|
58
|
+
}
|
|
59
|
+
function ToastContainer({ toasts, onDismiss, }) {
|
|
60
|
+
return (_jsx("div", { className: "fixed bottom-4 right-4 z-50 flex flex-col gap-2 pointer-events-none", role: "region", "aria-live": "polite", "aria-label": "Notifications", children: _jsx(AnimatePresence, { children: toasts.map((toast) => (_jsx(ToastItem, { toast: toast, onDismiss: onDismiss }, toast.id))) }) }));
|
|
61
|
+
}
|
|
62
|
+
const TOAST_ICONS = {
|
|
63
|
+
success: CheckCircle,
|
|
64
|
+
error: AlertCircle,
|
|
65
|
+
info: Info,
|
|
66
|
+
warning: AlertTriangle,
|
|
67
|
+
};
|
|
68
|
+
const TOAST_VARIANT = {
|
|
69
|
+
success: "success",
|
|
70
|
+
error: "danger",
|
|
71
|
+
info: "info",
|
|
72
|
+
warning: "warning",
|
|
73
|
+
};
|
|
74
|
+
function toastSurfaceStyle(theme, type) {
|
|
75
|
+
const intent = intentForVariant(theme, TOAST_VARIANT[type]);
|
|
76
|
+
return {
|
|
77
|
+
minWidth: 280,
|
|
78
|
+
maxWidth: 400,
|
|
79
|
+
display: "flex",
|
|
80
|
+
alignItems: "flex-start",
|
|
81
|
+
gap: theme.space[3],
|
|
82
|
+
padding: theme.space[4],
|
|
83
|
+
background: intent.soft,
|
|
84
|
+
color: intent.onSoft,
|
|
85
|
+
border: `2px solid ${intent.border}`,
|
|
86
|
+
borderRadius: theme.radius.lg,
|
|
87
|
+
boxShadow: theme.elevation.lifted,
|
|
88
|
+
backdropFilter: "blur(4px)",
|
|
89
|
+
WebkitBackdropFilter: "blur(4px)",
|
|
90
|
+
fontFamily: theme.typography.fontFamily.body,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function ToastItem({ toast, onDismiss, }) {
|
|
94
|
+
const theme = useTheme();
|
|
95
|
+
const reducedMotion = theme.motion.reducedMotion === "true";
|
|
96
|
+
const Icon = TOAST_ICONS[toast.type];
|
|
97
|
+
const intent = intentForVariant(theme, TOAST_VARIANT[toast.type]);
|
|
98
|
+
const surfaceStyle = toastSurfaceStyle(theme, toast.type);
|
|
99
|
+
return (_jsx(motion.div, { style: { pointerEvents: "auto" }, initial: reducedMotion ? { opacity: 0 } : { opacity: 0, y: 20, scale: 0.9 }, animate: reducedMotion ? { opacity: 1 } : { opacity: 1, y: 0, scale: 1 }, exit: reducedMotion ? { opacity: 0 } : { opacity: 0, x: 100, scale: 0.9 }, transition: { type: "spring", stiffness: 300, damping: 25 }, children: _jsxs(Alert, { variant: toast.type === "error" ? "destructive" : "default", style: surfaceStyle, children: [_jsx(Icon, { size: 20, style: {
|
|
100
|
+
marginTop: 2,
|
|
101
|
+
flexShrink: 0,
|
|
102
|
+
color: intent.solid,
|
|
103
|
+
}, "aria-hidden": "true" }), _jsx(AlertDescription, { style: {
|
|
104
|
+
flex: 1,
|
|
105
|
+
fontSize: theme.typography.fontSize.sm,
|
|
106
|
+
fontWeight: theme.typography.fontWeight.medium,
|
|
107
|
+
lineHeight: theme.typography.lineHeight.relaxed,
|
|
108
|
+
color: intent.onSoft,
|
|
109
|
+
}, children: toast.message }), _jsx(ThemedButton, { type: "button", variant: "ghost", size: "sm", onClick: () => onDismiss(toast.id), style: {
|
|
110
|
+
height: 28,
|
|
111
|
+
width: 28,
|
|
112
|
+
flexShrink: 0,
|
|
113
|
+
borderRadius: theme.radius.pill,
|
|
114
|
+
color: intent.onSoft,
|
|
115
|
+
}, "aria-label": "Close notification", children: _jsx(X, { size: 16, "aria-hidden": "true" }) })] }) }));
|
|
116
|
+
}
|