https://github.com/ankhorage/zora-tabletop
Reusable tabletop, playing-card, seat, token, and card-game presentation components for React Native and React Native Web.
https://github.com/ankhorage/zora-tabletop
card-game cards expo react-native react-native-web tabletop ui-kit zora
Last synced: 21 days ago
JSON representation
Reusable tabletop, playing-card, seat, token, and card-game presentation components for React Native and React Native Web.
- Host: GitHub
- URL: https://github.com/ankhorage/zora-tabletop
- Owner: ankhorage
- License: mit
- Created: 2026-05-22T11:49:42.000Z (26 days ago)
- Default Branch: main
- Last Pushed: 2026-05-22T12:33:22.000Z (26 days ago)
- Last Synced: 2026-05-22T17:44:03.089Z (26 days ago)
- Topics: card-game, cards, expo, react-native, react-native-web, tabletop, ui-kit, zora
- Language: HTML
- Size: 174 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Agents: AGENTS.md
Awesome Lists containing this project
README
# @ankhorage/zora-tabletop
        
Reusable tabletop, playing-card, seat, token, and card-game presentation components for React Native and React Native Web.
## Usage
### Minimal tabletop app root.
Use `TabletopTable` inside a ZORA app shell to render generic seats, visible
cards, face-down cards, and center-table labels without adding game rules.
Source: `examples/basic-tabletop/App.tsx`
```tsx
import {
AppBar,
AppShell,
Screen,
ScreenSection,
ZoraProvider,
type ZoraTheme,
} from '@ankhorage/zora';
import { type TabletopSeatState, TabletopTable } from '@ankhorage/zora-tabletop';
const tabletopTheme: ZoraTheme = {
id: 'basic-tabletop',
name: 'Basic tabletop',
appCategory: 'games',
primaryColor: '#0f766e',
harmony: 'analogous',
};
const seats: readonly TabletopSeatState[] = [
{
id: 'seat-a',
label: 'Seat A',
sublabel: 'Ready',
cards: [
{ rank: 'A', suit: 'spades' },
{ rank: 'K', suit: 'hearts' },
],
selected: true,
tokenLabel: 'Active',
},
{
id: 'seat-b',
label: 'Seat B',
sublabel: 'Hidden cards',
faceDownCards: 2,
},
{
id: 'seat-c',
label: 'Seat C',
sublabel: 'Paused',
faceDownCards: 2,
muted: true,
},
];
export default function BasicTabletopApp() {
return (
}>
);
}
```
## Generated documentation
- [Interactive documentation app](././paradox/index.html)
- [Public API reference](././paradox/exports.md)
- [Component registry](././paradox/components.md)
- [Architecture overview](././paradox/diagrams/architecture-overview.mmd)
- [Module relationships](././paradox/diagrams/module-relationships.mmd)
- [Export graph](././paradox/diagrams/export-graph.mmd)
- [CardBack sequence](././paradox/diagrams/sequences/card-back.mmd)
- [CardHand sequence](././paradox/diagrams/sequences/card-hand.mmd)
- [PlayingCard sequence](././paradox/diagrams/sequences/playing-card.mmd)
- [TabletopTable sequence](././paradox/diagrams/sequences/tabletop-table.mmd)
## Public API
### Components
CardBack
```ts
CardBack({
size = 'medium',
muted = false,
accessibilityLabel,
colorScheme,
testID,
}: CardBackProps) => React.JSX.Element
```
Face-down playing-card primitive for hidden cards and decks.
Use `CardBack` when a card should be represented visually without exposing its
rank or suit. The component keeps a generic accessible label for hidden cards.
#### Hidden cards
```tsx
```
Related types: `CardBackProps`
Props
| Prop | Type | Required | Default | Description |
| ------------------ | ------------------------------------- | -------- | ---------- | ----------- |
| accessibilityLabel | `string \| undefined` | no | — | |
| colorScheme | `TabletopColorOverrides \| undefined` | no | — | |
| muted | `boolean \| undefined` | no | `false` | |
| size | `TabletopCardSize \| undefined` | no | `'medium'` | |
| testID | `string \| undefined` | no | — | |
CardHand
```ts
CardHand({
cards = [],
faceDownCards = 0,
size = 'medium',
muted = false,
colorScheme,
accessibilityLabel,
testID,
}: CardHandProps) => React.JSX.Element
```
Compact row of visible and face-down playing cards.
Use `CardHand` when a seat, pile, or custom layout needs to show multiple cards
with consistent spacing, sizing, and muted state handling.
#### Mixed hand
```tsx
```
Related types: `CardHandProps`
Props
| Prop | Type | Required | Default | Description |
| ------------------ | ------------------------------------------ | -------- | ---------- | ----------- |
| accessibilityLabel | `string \| undefined` | no | — | |
| cards | `readonly PlayingCardValue[] \| undefined` | no | `[]` | |
| colorScheme | `TabletopColorOverrides \| undefined` | no | — | |
| faceDownCards | `number \| undefined` | no | `0` | |
| muted | `boolean \| undefined` | no | `false` | |
| size | `TabletopCardSize \| undefined` | no | `'medium'` | |
| testID | `string \| undefined` | no | — | |
PlayingCard
```ts
PlayingCard({
card,
size = 'medium',
selected = false,
muted = false,
accessibilityLabel,
colorScheme,
testID,
}: PlayingCardProps) => React.JSX.Element
```
Theme-aware face-up playing card primitive.
Use `PlayingCard` for visible card values in hands, shared table cards, piles,
or custom tabletop layouts. The component renders rank and suit glyphs and
exposes an accessible card label by default.
#### Face-up card
```tsx
```
Related types: `PlayingCardProps`
Props
| Prop | Type | Required | Default | Description |
| ------------------ | ------------------------------------- | -------- | ---------- | ----------- |
| accessibilityLabel | `string \| undefined` | no | — | |
| card | `PlayingCardValue` | yes | — | |
| colorScheme | `TabletopColorOverrides \| undefined` | no | — | |
| muted | `boolean \| undefined` | no | `false` | |
| selected | `boolean \| undefined` | no | `false` | |
| size | `TabletopCardSize \| undefined` | no | `'medium'` | |
| testID | `string \| undefined` | no | — | |
TabletopTable
```ts
TabletopTable({
seats,
centerCards = [],
centerLabel,
centerSublabel,
shape = 'oval',
seatCount,
cardSize = 'small',
disabled = false,
colorScheme,
accessibilityLabel,
testID,
}: TabletopTableProps) => React.JSX.Element
```
Responsive tabletop surface for generic card-game and board-game scenes.
Use `TabletopTable` to arrange seats around a themed table surface, display
shared center cards, and show neutral seat labels/tokens without embedding game
rules into the component.
#### Basic table
```tsx
```
Related types: `TabletopTableProps`
Props
| Prop | Type | Required | Default | Description |
| ------------------ | ------------------------------------------ | -------- | --------- | ----------- |
| accessibilityLabel | `string \| undefined` | no | — | |
| cardSize | `TabletopCardSize \| undefined` | no | `'small'` | |
| centerCards | `readonly PlayingCardValue[] \| undefined` | no | `[]` | |
| centerLabel | `React.ReactNode \| undefined` | no | — | |
| centerSublabel | `React.ReactNode \| undefined` | no | — | |
| colorScheme | `TabletopColorOverrides \| undefined` | no | — | |
| disabled | `boolean \| undefined` | no | `false` | |
| seatCount | `TabletopSeatCount \| undefined` | no | — | |
| seats | `readonly TabletopSeatState[]` | yes | — | |
| shape | `TabletopShape \| undefined` | no | `'oval'` | |
| testID | `string \| undefined` | no | — | |
### Utilities
createTabletopColorScheme
```ts
createTabletopColorScheme(theme: TabletopColorThemeShape, overrides?: Partial) => TabletopColorScheme
```
Creates the theme-derived color palette used by tabletop primitives.
Use `createTabletopColorScheme` when custom components need to align with the
same card, table, seat, token, and contrast-aware foreground colors as the
built-in tabletop components.
#### Custom color scheme
```ts
const colors = createTabletopColorScheme(theme, { tableFelt: '#065f46' });
```
Module: `src/colors.ts`
Source: `src/colors.ts:73:1`
Related symbols: `TabletopColorScheme`