Bridge Training
Bridge React

HandsEditor

Compound component for editing all 4 hands with built-in keyboard navigation.

Import from @workspace/bridge-react/primitives/hands-editor.

Overview

HandsEditor is a 3-level compound component that provides a fully self-contained board editor with built-in keyboard navigation across all 4 players and 4 suits.

All navigation (S→H→D→C→next player) is handled internally — consumers only provide data and an onCardsChange callback.

Architecture

ComponentRole
HandsEditor.RootBoard-level context: hands data, callbacks, cross-player ref map
HandsEditor.HandPer-player wrapper: suit refs, within-hand + exit navigation, styling
HandsEditor.SuitPer-suit input row: auto-registers ref, delegates keyboard events

Basic Usage

import { PLAYERS } from '@workspace/bridge-core/constants';
import { SUITS } from '@workspace/bridge-core/constants';
import { Board } from '@workspace/bridge-react/board/board';
import { HandsEditor } from '@workspace/bridge-react/primitives/hands-editor';

<HandsEditor.Root hands={hands} onCardsChange={handleCardsChange}>
  <Board.Layout>
    {PLAYERS.map((player) => (
      <Board.Position key={player} position={player}>
        <HandsEditor.Hand player={player}>
          {SUITS.map((suit) => (
            <HandsEditor.Suit key={suit} suit={suit} />
          ))}
        </HandsEditor.Hand>
      </Board.Position>
    ))}
    <Board.Center>
      <PlayerSelector onChange={setPlayer} value={player} variant="buttons" />
    </Board.Center>
  </Board.Layout>
</HandsEditor.Root>

Keyboard Navigation

Navigation is handled automatically inside HandsEditor.Suit:

KeyAction
Enter / ArrowDownFocus next suit (S→H→D→C), then wraps to next player's Spades
ArrowUpFocus previous suit, wraps to previous player's Clubs
Shift+TabNative browser backward navigation

Props

HandsEditor.Root

HandsEditor.Hand

HandsEditor.Suit

Notes

  • HandsEditor.Root is wrapped with withBridgeContext — can be used outside a BridgeProvider
  • Compose with Board.Layout / Board.Position / Board.Center for the compass grid layout
  • PlayerSelector and SelectedPlayerAlert are separate components — compose them alongside the compound as needed
  • Confirmation logic (e.g. warning when editing played suits) is the responsibility of the consuming wrapper

On this page