Bridge Training
UI Bridge

Hooks

Shared hooks for bridge game logic — auctions, hands, contracts, play, and deal validation.

Hooks live next to the module they serve (hand/hooks/*, contract/hooks/*, play/hooks/*, primitives/editor/*); only cross-cutting hooks stay under @workspace/ui-bridge/hooks/*.

All hooks use useBridgeEngine() internally to get variant-specific configuration.

Pedagogy Mode Hooks

usePedagogyModeGroups

Provides pedagogy mode groups for the PedagogyModeSelect component. Labels are handled by <TeachingModeGroup> and <TeachingMode> label components.

Import from @workspace/ui-bridge/primitives/editor/use-pedagogy-mode-groups.

import { usePedagogyModeGroups } from '@workspace/ui-bridge/primitives/editor/use-pedagogy-mode-groups';

const groups = usePedagogyModeGroups();
// [{ id: "with-auction", items: ["auction", "sequence"] }, ...]

Returns: PedagogyModeGroup[] — Each group has an id ("with-auction" | "without-auction") and items (TeachingMode[]).

usePedagogyModeWithRules

Wraps a pedagogy mode onChange handler to derive variant from the engine.

Import from @workspace/ui-bridge/primitives/editor/use-pedagogy-mode-with-rules.

import { usePedagogyModeWithRules } from '@workspace/ui-bridge/primitives/editor/use-pedagogy-mode-with-rules';

const handleModeChange = usePedagogyModeWithRules(setPedagogyMode);
ParameterTypeDescription
onChange(mode: string) => voidThe original onChange handler

Returns: (mode: string) => void

Hand Hooks

useAreHandsComplete

Checks if all hands are complete (have the expected number of cards).

Import from @workspace/ui-bridge/hand/hooks/use-are-hands-complete.

import { useAreHandsComplete } from '@workspace/ui-bridge/hand/hooks/use-are-hands-complete';

const { areComplete, incompletePlayers } = useAreHandsComplete(hands);

useHandsStatus

Gets the complete status of all hands including duplicated cards detection.

Import from @workspace/ui-bridge/hand/hooks/use-hands-status.

import { useHandsStatus } from '@workspace/ui-bridge/hand/hooks/use-hands-status';

const { areComplete, areEmpty, hasTooManyCards, incompletePlayers, duplicatedCards } = useHandsStatus(hands);

useHandInputState

Manages hand input state with debouncing and formatting. Provides internal state during typing, 300ms debounce, immediate validation on blur, and localized rank formatting via the engine notation context.

Import from @workspace/ui-bridge/hand/use-hand-input-state.

import { useHandInputState } from '@workspace/ui-bridge/hand/use-hand-input-state';

const { inputValue, handleChange, handleFocus, handleBlur } = useHandInputState({
  value: ['A', 'K', 'Q'],
  onChange: (ranks) => setRanks(ranks),
});

useHandInputValidation

Handles validated hand input with debouncing, formatting, duplicate removal, and rank sorting. Similar to useHandInputState but also filters invalid ranks and sorts by rank order.

Import from @workspace/ui-bridge/hand/use-hand-input-validation.

import { useHandInputValidation } from '@workspace/ui-bridge/hand/use-hand-input-validation';

const { inputValue, onChange, onFocus, onBlur } = useHandInputValidation({
  value: ['A', 'K', 'Q'],
  onValueChange: (ranks) => setRanks(ranks),
});

Contract Hooks

useContractResult

Gets the contract result (confirmed or candidate) from an Auction.

Import from @workspace/ui-bridge/contract/hooks/use-contract-result.

import { useContractResult } from '@workspace/ui-bridge/contract/hooks/use-contract-result';

const { result, declarer, isCandidate } = useContractResult(auction);

useTrump

Gets the trump suit from an Auction. Uses the candidate contract if not yet confirmed.

Import from @workspace/ui-bridge/contract/hooks/use-trump.

import { useTrump } from '@workspace/ui-bridge/contract/hooks/use-trump';

const trump = useTrump(auction);
// trump = "S" | "H" | "D" | "C" | null
ParameterTypeDescription
auctionAuctionThe auction, { first, moves }

Returns: Suit | null

Play Hooks

useHasPlayedSuit

Returns a function that checks if a player has played a card of a specific suit across all tricks.

Import from @workspace/ui-bridge/play/hooks/use-has-played-suit.

import { useHasPlayedSuit } from '@workspace/ui-bridge/play/hooks/use-has-played-suit';

const hasPlayedSuit = useHasPlayedSuit(tricks);
const played = hasPlayedSuit('N', 'S'); // Has North played a spade?
ParameterTypeDescription
tricksTrick[]Tricks as buildTricks returns them, or as trickSchema parses form data

Returns: (player: Player, suit: Suit) => boolean

useLead

Gets the opening lead (first card of the first trick).

Import from @workspace/ui-bridge/play/hooks/use-lead.

import { useLead } from '@workspace/ui-bridge/play/hooks/use-lead';

const lead = useLead(tricks);
// lead = { suit: "S", rank: "A" } | null
ParameterTypeDescription
tricksTrick[]Array of tricks from the play state

Returns: Card | null

useTricksWithWinners

Enriches tricks with computed winners using the bridge engine. Takes display tricks (with nullable cards) and a parsed contract, returns tricks with winner fields populated.

Import from @workspace/ui-bridge/play/hooks/useTricksWithWinners.

import { useTricksWithWinners } from '@workspace/ui-bridge/play/hooks/useTricksWithWinners';

const tricksWithWinners = useTricksWithWinners(tricks, contract);
ParameterTypeDescription
tricksTrick[]Array of display tricks from TricksDisplay
contractDisplayContract | nullParsed contract (needed for trump suit)

Returns: Trick[] — Same tricks with winner computed for each complete trick.

Deal Validation

useValidateDeal

Validates a deal (hands + contract). Takes all data as props with no form dependency.

Import from @workspace/ui-bridge/hooks/useValidateDeal.

import { useValidateDeal } from '@workspace/ui-bridge/hooks/useValidateDeal';

const { isValid, errors, result } = useValidateDeal({
  hands,
  auction,
  denomination,
});