Usage
How to integrate and use @workspace/bridge-react in your application.
Installation
Add the dependency to your app's package.json:
{
"dependencies": {
"@workspace/bridge-react": "workspace:*"
}
}Peer Dependencies
The package requires React and react-i18next as peer dependencies:
{
"peerDependencies": {
"react": "^19",
"react-dom": "^19",
"react-i18next": "^15"
}
}Import Styles
Import the package stylesheet in your app's root CSS:
@import "@workspace/bridge-react/styles.css";Provider Setup
Global Provider
Wrap your application with BridgeProvider to configure the engine for all child components:
import { BridgeProvider } from '@workspace/bridge-react/bridge-context/bridge-provider';
function App() {
return (
<BridgeProvider context={{ teachingMode: 'auction', locale: 'fr' }}>
{/* All bridge components use this engine */}
</BridgeProvider>
);
}The context prop accepts a BridgeContext object (see Bridge Core Usage for details).
Without a Provider
All components work without a provider. When no BridgeProvider is in the tree, useBridgeEngine() falls back to a default engine with the classic variant:
import { SuitDisplay } from '@workspace/bridge-react/suit/suit-display';
// Works without any provider — uses classic variant defaults
function Standalone() {
return <SuitDisplay suit="S" />;
}Per-Component Override
Every exported component that uses the engine internally is wrapped with withBridgeContext. This adds an optional context prop that creates a local provider, overriding any parent provider:
import { BridgeProvider } from '@workspace/bridge-react/bridge-context/bridge-provider';
import { SuitDisplay } from '@workspace/bridge-react/suit/suit-display';
function App() {
return (
<BridgeProvider context={{ teachingMode: 'auction', locale: 'fr' }}>
{/* Uses the global provider (classic variant, French notation) */}
<SuitDisplay suit="S" />
{/* Overrides with petit-bridge variant for this component */}
<SuitDisplay suit="S" context={{ teachingMode: 'petit-bridge' }} />
</BridgeProvider>
);
}This is useful for preview elements that need a different variant or locale than the rest of the app.
Components
Display Components
Simple components for rendering bridge entities:
import { SuitDisplay } from '@workspace/bridge-react/suit/suit-display';
import { CardDisplay } from '@workspace/bridge-react/card/card-display';
import { BidDisplay } from '@workspace/bridge-react/bid/bid-display';
<SuitDisplay suit="S" />
<SuitDisplay suit="H" colorVariant="bid" />
<CardDisplay card="SA" />
<BidDisplay bid="2H" />Hand Component
The standalone Hand component renders a full bridge hand with inputs:
import { Hand } from '@workspace/bridge-react/components/hand/hand';
<Hand
player="N"
cards={{ S: ['A', 'K'], H: ['Q', 'J'], D: ['10', '9'], C: ['8'] }}
readOnly
/>Hand Compound Component
For more control, use the compound component API:
import { Hand } from '@workspace/bridge-react/hand/hand';
const SUITS = ['S', 'H', 'D', 'C'] as const;
<Hand.Root player="N" cards={cards} onCardsChange={handleChange}>
{SUITS.map(suit => (
<Hand.InputRow key={suit} suit={suit} value={cards[suit]} />
))}
</Hand.Root>BiddingTable Compound Component
import { BiddingTable } from '@workspace/bridge-react/bidding/table/bidding-table';
<BiddingTable.Root dealer="N" vulnerability="ALL">
<BiddingTable.Table>
<BiddingTable.Header />
<BiddingTable.Content>
{rows.map((row, i) => (
<BiddingTable.Row key={i}>
{row.map((cell, j) =>
cell ? (
<BiddingTable.BidCell key={cell.index} bid={cell.bid} />
) : (
<BiddingTable.EmptyCell key={j} />
)
)}
</BiddingTable.Row>
))}
</BiddingTable.Content>
</BiddingTable.Table>
</BiddingTable.Root>Form Components
Pre-built form fields for bridge settings:
import { VulnerabilitySelect } from '@workspace/bridge-react/form/vulnerability-select';
import { ScoringSelect } from '@workspace/bridge-react/form/scoring-select';
<VulnerabilitySelect value={vulnerability} onChange={setVulnerability} />
<ScoringSelect value={scoring} onChange={setScoring} />BridgePrimitivesProvider
For apps that use the rich text editor, BridgePrimitivesProvider combines the engine context with the final comment editor context, and exposes an imperative ref:
import {
BridgePrimitivesProvider,
type BridgePrimitivesRef,
} from '@workspace/bridge-react/provider';
import { useRef } from 'react';
function Editor() {
const ref = useRef<BridgePrimitivesRef>(null);
const handleSave = () => {
const html = ref.current?.getFinalCommentHTML();
const pbn = ref.current?.getFinalCommentPBN();
};
return (
<BridgePrimitivesProvider
ref={ref}
context={{ teachingMode: 'auction', locale: 'fr' }}
>
{/* Editor components */}
</BridgePrimitivesProvider>
);
}Internationalization (i18n)
Components that display text (form labels, player names, etc.) use translations from the primitives namespace via react-i18next.
The package exports its translation resources for integration into your app's i18next setup:
import { primitivesResources, PRIMITIVES_NAMESPACES } from '@workspace/bridge-react/i18n';For detailed loading strategies (HTTP backend vs direct bundle), see the i18n Usage documentation.
Quick Setup
import { primitivesResources } from '@workspace/bridge-react/i18n';
i18n.init({
ns: ['translation', 'primitives', 'rich-editor'],
resources: {
en: { translation: appEn, ...primitivesResources.en },
fr: { translation: appFr, ...primitivesResources.fr },
},
});