@ankhorage/zora-tabletop 0.0.2 → 0.0.3
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/CHANGELOG.md +6 -0
- package/README.md +294 -72
- package/dist/colors.d.ts +13 -0
- package/dist/colors.d.ts.map +1 -1
- package/dist/colors.js +13 -0
- package/dist/colors.js.map +1 -1
- package/dist/components/card-back/CardBack.d.ts +12 -0
- package/dist/components/card-back/CardBack.d.ts.map +1 -1
- package/dist/components/card-back/CardBack.js +12 -0
- package/dist/components/card-back/CardBack.js.map +1 -1
- package/dist/components/card-hand/CardHand.d.ts +12 -0
- package/dist/components/card-hand/CardHand.d.ts.map +1 -1
- package/dist/components/card-hand/CardHand.js +12 -0
- package/dist/components/card-hand/CardHand.js.map +1 -1
- package/dist/components/playing-card/PlayingCard.d.ts +13 -0
- package/dist/components/playing-card/PlayingCard.d.ts.map +1 -1
- package/dist/components/playing-card/PlayingCard.js +13 -0
- package/dist/components/playing-card/PlayingCard.js.map +1 -1
- package/dist/components/tabletop-table/TabletopTable.d.ts +17 -0
- package/dist/components/tabletop-table/TabletopTable.d.ts.map +1 -1
- package/dist/components/tabletop-table/TabletopTable.js +17 -0
- package/dist/components/tabletop-table/TabletopTable.js.map +1 -1
- package/package.json +2 -2
- package/src/colors.ts +13 -0
- package/src/components/card-back/CardBack.tsx +12 -0
- package/src/components/card-hand/CardHand.tsx +12 -0
- package/src/components/playing-card/PlayingCard.tsx +13 -0
- package/src/components/tabletop-table/TabletopTable.tsx +17 -0
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -3,10 +3,92 @@
|
|
|
3
3
|
|
|
4
4
|
# @ankhorage/zora-tabletop
|
|
5
5
|
|
|
6
|
-
         
|
|
7
7
|
|
|
8
8
|
Reusable tabletop, playing-card, seat, token, and card-game presentation components for React Native and React Native Web.
|
|
9
9
|
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
### Minimal tabletop app root.
|
|
13
|
+
|
|
14
|
+
Use `TabletopTable` inside a ZORA app shell to render generic seats, visible
|
|
15
|
+
cards, face-down cards, and center-table labels without adding game rules.
|
|
16
|
+
|
|
17
|
+
Source: `examples/basic-tabletop/App.tsx`
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import {
|
|
21
|
+
AppBar,
|
|
22
|
+
AppShell,
|
|
23
|
+
Screen,
|
|
24
|
+
ScreenSection,
|
|
25
|
+
ZoraProvider,
|
|
26
|
+
type ZoraTheme,
|
|
27
|
+
} from '@ankhorage/zora';
|
|
28
|
+
import { type TabletopSeatState, TabletopTable } from '@ankhorage/zora-tabletop';
|
|
29
|
+
|
|
30
|
+
const tabletopTheme: ZoraTheme = {
|
|
31
|
+
id: 'basic-tabletop',
|
|
32
|
+
name: 'Basic tabletop',
|
|
33
|
+
appCategory: 'games',
|
|
34
|
+
primaryColor: '#0f766e',
|
|
35
|
+
harmony: 'analogous',
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const seats: readonly TabletopSeatState[] = [
|
|
39
|
+
{
|
|
40
|
+
id: 'seat-a',
|
|
41
|
+
label: 'Seat A',
|
|
42
|
+
sublabel: 'Ready',
|
|
43
|
+
cards: [
|
|
44
|
+
{ rank: 'A', suit: 'spades' },
|
|
45
|
+
{ rank: 'K', suit: 'hearts' },
|
|
46
|
+
],
|
|
47
|
+
selected: true,
|
|
48
|
+
tokenLabel: 'Active',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: 'seat-b',
|
|
52
|
+
label: 'Seat B',
|
|
53
|
+
sublabel: 'Hidden cards',
|
|
54
|
+
faceDownCards: 2,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 'seat-c',
|
|
58
|
+
label: 'Seat C',
|
|
59
|
+
sublabel: 'Paused',
|
|
60
|
+
faceDownCards: 2,
|
|
61
|
+
muted: true,
|
|
62
|
+
},
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
export default function BasicTabletopApp() {
|
|
66
|
+
return (
|
|
67
|
+
<ZoraProvider initialMode="light" theme={tabletopTheme}>
|
|
68
|
+
<AppShell header={<AppBar title="Tabletop" subtitle="Reusable card-game UI" />}>
|
|
69
|
+
<Screen>
|
|
70
|
+
<ScreenSection
|
|
71
|
+
title="Table state"
|
|
72
|
+
description="Map app data into generic seats and cards."
|
|
73
|
+
>
|
|
74
|
+
<TabletopTable
|
|
75
|
+
seats={seats}
|
|
76
|
+
centerCards={[
|
|
77
|
+
{ rank: 'Q', suit: 'diamonds' },
|
|
78
|
+
{ rank: 'J', suit: 'clubs' },
|
|
79
|
+
{ rank: '10', suit: 'spades' },
|
|
80
|
+
]}
|
|
81
|
+
centerLabel="Round 1"
|
|
82
|
+
centerSublabel="Shared cards"
|
|
83
|
+
/>
|
|
84
|
+
</ScreenSection>
|
|
85
|
+
</Screen>
|
|
86
|
+
</AppShell>
|
|
87
|
+
</ZoraProvider>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
10
92
|
## Generated documentation
|
|
11
93
|
|
|
12
94
|
- [Interactive documentation app](././paradox/index.html)
|
|
@@ -20,79 +102,219 @@ Reusable tabletop, playing-card, seat, token, and card-game presentation compone
|
|
|
20
102
|
- [PlayingCard sequence](././paradox/diagrams/sequences/playing-card.mmd)
|
|
21
103
|
- [TabletopTable sequence](././paradox/diagrams/sequences/tabletop-table.mmd)
|
|
22
104
|
|
|
23
|
-
##
|
|
105
|
+
## Public API
|
|
106
|
+
|
|
107
|
+
### Components
|
|
108
|
+
|
|
109
|
+
<details>
|
|
110
|
+
<summary>CardBack</summary>
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
CardBack({
|
|
114
|
+
size = 'medium',
|
|
115
|
+
muted = false,
|
|
116
|
+
accessibilityLabel,
|
|
117
|
+
colorScheme,
|
|
118
|
+
testID,
|
|
119
|
+
}: CardBackProps) => React.JSX.Element
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Face-down playing-card primitive for hidden cards and decks.
|
|
123
|
+
|
|
124
|
+
Use `CardBack` when a card should be represented visually without exposing its
|
|
125
|
+
rank or suit. The component keeps a generic accessible label for hidden cards.
|
|
126
|
+
|
|
127
|
+
#### Hidden cards
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
<CardBack size="small" />
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Related types: `CardBackProps`
|
|
134
|
+
|
|
135
|
+
<details>
|
|
136
|
+
<summary>Props</summary>
|
|
137
|
+
|
|
138
|
+
| Prop | Type | Required | Default | Description |
|
|
139
|
+
| ------------------ | ------------------------------------- | -------- | ---------- | ----------- |
|
|
140
|
+
| accessibilityLabel | `string \| undefined` | no | — | |
|
|
141
|
+
| colorScheme | `TabletopColorOverrides \| undefined` | no | — | |
|
|
142
|
+
| muted | `boolean \| undefined` | no | `false` | |
|
|
143
|
+
| size | `TabletopCardSize \| undefined` | no | `'medium'` | |
|
|
144
|
+
| testID | `string \| undefined` | no | — | |
|
|
145
|
+
|
|
146
|
+
</details>
|
|
147
|
+
|
|
148
|
+
</details>
|
|
149
|
+
|
|
150
|
+
<details>
|
|
151
|
+
<summary>CardHand</summary>
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
CardHand({
|
|
155
|
+
cards = [],
|
|
156
|
+
faceDownCards = 0,
|
|
157
|
+
size = 'medium',
|
|
158
|
+
muted = false,
|
|
159
|
+
colorScheme,
|
|
160
|
+
accessibilityLabel,
|
|
161
|
+
testID,
|
|
162
|
+
}: CardHandProps) => React.JSX.Element
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Compact row of visible and face-down playing cards.
|
|
166
|
+
|
|
167
|
+
Use `CardHand` when a seat, pile, or custom layout needs to show multiple cards
|
|
168
|
+
with consistent spacing, sizing, and muted state handling.
|
|
169
|
+
|
|
170
|
+
#### Mixed hand
|
|
171
|
+
|
|
172
|
+
```tsx
|
|
173
|
+
<CardHand cards={[{ rank: 'Q', suit: 'hearts' }]} faceDownCards={1} />
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Related types: `CardHandProps`
|
|
177
|
+
|
|
178
|
+
<details>
|
|
179
|
+
<summary>Props</summary>
|
|
180
|
+
|
|
181
|
+
| Prop | Type | Required | Default | Description |
|
|
182
|
+
| ------------------ | ------------------------------------------ | -------- | ---------- | ----------- |
|
|
183
|
+
| accessibilityLabel | `string \| undefined` | no | — | |
|
|
184
|
+
| cards | `readonly PlayingCardValue[] \| undefined` | no | `[]` | |
|
|
185
|
+
| colorScheme | `TabletopColorOverrides \| undefined` | no | — | |
|
|
186
|
+
| faceDownCards | `number \| undefined` | no | `0` | |
|
|
187
|
+
| muted | `boolean \| undefined` | no | `false` | |
|
|
188
|
+
| size | `TabletopCardSize \| undefined` | no | `'medium'` | |
|
|
189
|
+
| testID | `string \| undefined` | no | — | |
|
|
190
|
+
|
|
191
|
+
</details>
|
|
192
|
+
|
|
193
|
+
</details>
|
|
194
|
+
|
|
195
|
+
<details>
|
|
196
|
+
<summary>PlayingCard</summary>
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
PlayingCard({
|
|
200
|
+
card,
|
|
201
|
+
size = 'medium',
|
|
202
|
+
selected = false,
|
|
203
|
+
muted = false,
|
|
204
|
+
accessibilityLabel,
|
|
205
|
+
colorScheme,
|
|
206
|
+
testID,
|
|
207
|
+
}: PlayingCardProps) => React.JSX.Element
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Theme-aware face-up playing card primitive.
|
|
211
|
+
|
|
212
|
+
Use `PlayingCard` for visible card values in hands, shared table cards, piles,
|
|
213
|
+
or custom tabletop layouts. The component renders rank and suit text and exposes
|
|
214
|
+
an accessible card label by default.
|
|
215
|
+
|
|
216
|
+
#### Face-up card
|
|
217
|
+
|
|
218
|
+
```tsx
|
|
219
|
+
<PlayingCard card={{ rank: 'A', suit: 'spades' }} selected />
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Related types: `PlayingCardProps`
|
|
24
223
|
|
|
25
224
|
<details>
|
|
26
|
-
<summary>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
package__ankhorage_zora_tabletop -.-> module_src_components_card_hand_index_ts
|
|
60
|
-
module_src_components_card_hand_types_ts["src/components/card-hand/types.ts"]
|
|
61
|
-
package__ankhorage_zora_tabletop -.-> module_src_components_card_hand_types_ts
|
|
62
|
-
module_src_components_card_hand_types_ts --> module_src_colors_ts
|
|
63
|
-
module_src_components_card_hand_types_ts --> module_src_types_ts
|
|
64
|
-
module_src_components_playing_card_index_ts["src/components/playing-card/index.ts"]
|
|
65
|
-
package__ankhorage_zora_tabletop -.-> module_src_components_playing_card_index_ts
|
|
66
|
-
module_src_components_playing_card_PlayingCard_tsx["src/components/playing-card/PlayingCard.tsx"]
|
|
67
|
-
package__ankhorage_zora_tabletop -.-> module_src_components_playing_card_PlayingCard_tsx
|
|
68
|
-
module_src_components_playing_card_PlayingCard_tsx --> module_src_cardLabel_ts
|
|
69
|
-
module_src_components_playing_card_PlayingCard_tsx --> module_src_cardSizing_ts
|
|
70
|
-
module_src_components_playing_card_PlayingCard_tsx --> module_src_colors_ts
|
|
71
|
-
module_src_components_playing_card_PlayingCard_tsx --> module_src_components_playing_card_types_ts
|
|
72
|
-
module_src_components_playing_card_PlayingCard_tsx --> module_src_types_ts
|
|
73
|
-
module_src_components_playing_card_types_ts["src/components/playing-card/types.ts"]
|
|
74
|
-
package__ankhorage_zora_tabletop -.-> module_src_components_playing_card_types_ts
|
|
75
|
-
module_src_components_playing_card_types_ts --> module_src_colors_ts
|
|
76
|
-
module_src_components_playing_card_types_ts --> module_src_types_ts
|
|
77
|
-
module_src_components_tabletop_table_index_ts["src/components/tabletop-table/index.ts"]
|
|
78
|
-
package__ankhorage_zora_tabletop -.-> module_src_components_tabletop_table_index_ts
|
|
79
|
-
module_src_components_tabletop_table_TabletopTable_tsx["src/components/tabletop-table/TabletopTable.tsx"]
|
|
80
|
-
package__ankhorage_zora_tabletop -.-> module_src_components_tabletop_table_TabletopTable_tsx
|
|
81
|
-
module_src_components_tabletop_table_TabletopTable_tsx --> module_src_colors_ts
|
|
82
|
-
module_src_components_tabletop_table_TabletopTable_tsx --> module_src_components_card_hand_index_ts
|
|
83
|
-
module_src_components_tabletop_table_TabletopTable_tsx --> module_src_components_tabletop_table_types_ts
|
|
84
|
-
module_src_components_tabletop_table_TabletopTable_tsx --> module_src_tablePositions_ts
|
|
85
|
-
module_src_components_tabletop_table_TabletopTable_tsx --> module_src_types_ts
|
|
86
|
-
module_src_components_tabletop_table_types_ts["src/components/tabletop-table/types.ts"]
|
|
87
|
-
package__ankhorage_zora_tabletop -.-> module_src_components_tabletop_table_types_ts
|
|
88
|
-
module_src_components_tabletop_table_types_ts --> module_src_colors_ts
|
|
89
|
-
module_src_components_tabletop_table_types_ts --> module_src_types_ts
|
|
90
|
-
module_src_index_ts["src/index.ts"]
|
|
91
|
-
module_src_tablePositions_ts["src/tablePositions.ts"]
|
|
92
|
-
package__ankhorage_zora_tabletop -.-> module_src_tablePositions_ts
|
|
93
|
-
module_src_tablePositions_ts --> module_src_types_ts
|
|
94
|
-
module_src_types_ts["src/types.ts"]
|
|
95
|
-
package__ankhorage_zora_tabletop -.-> module_src_types_ts
|
|
225
|
+
<summary>Props</summary>
|
|
226
|
+
|
|
227
|
+
| Prop | Type | Required | Default | Description |
|
|
228
|
+
| ------------------ | ------------------------------------- | -------- | ---------- | ----------- |
|
|
229
|
+
| accessibilityLabel | `string \| undefined` | no | — | |
|
|
230
|
+
| card | `PlayingCardValue` | yes | — | |
|
|
231
|
+
| colorScheme | `TabletopColorOverrides \| undefined` | no | — | |
|
|
232
|
+
| muted | `boolean \| undefined` | no | `false` | |
|
|
233
|
+
| selected | `boolean \| undefined` | no | `false` | |
|
|
234
|
+
| size | `TabletopCardSize \| undefined` | no | `'medium'` | |
|
|
235
|
+
| testID | `string \| undefined` | no | — | |
|
|
236
|
+
|
|
237
|
+
</details>
|
|
238
|
+
|
|
239
|
+
</details>
|
|
240
|
+
|
|
241
|
+
<details>
|
|
242
|
+
<summary>TabletopTable</summary>
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
TabletopTable({
|
|
246
|
+
seats,
|
|
247
|
+
centerCards = [],
|
|
248
|
+
centerLabel,
|
|
249
|
+
centerSublabel,
|
|
250
|
+
shape = 'oval',
|
|
251
|
+
seatCount,
|
|
252
|
+
cardSize = 'small',
|
|
253
|
+
disabled = false,
|
|
254
|
+
colorScheme,
|
|
255
|
+
accessibilityLabel,
|
|
256
|
+
testID,
|
|
257
|
+
}: TabletopTableProps) => React.JSX.Element
|
|
96
258
|
```
|
|
97
259
|
|
|
260
|
+
Responsive tabletop surface for generic card-game and board-game scenes.
|
|
261
|
+
|
|
262
|
+
Use `TabletopTable` to arrange seats around a themed table surface, display
|
|
263
|
+
shared center cards, and show neutral seat labels/tokens without embedding game
|
|
264
|
+
rules into the component.
|
|
265
|
+
|
|
266
|
+
#### Basic table
|
|
267
|
+
|
|
268
|
+
```tsx
|
|
269
|
+
<TabletopTable seats={seats} centerCards={[{ rank: 'A', suit: 'spades' }]} centerLabel="Round 1" />
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Related types: `TabletopTableProps`
|
|
273
|
+
|
|
274
|
+
<details>
|
|
275
|
+
<summary>Props</summary>
|
|
276
|
+
|
|
277
|
+
| Prop | Type | Required | Default | Description |
|
|
278
|
+
| ------------------ | ------------------------------------------ | -------- | --------- | ----------- |
|
|
279
|
+
| accessibilityLabel | `string \| undefined` | no | — | |
|
|
280
|
+
| cardSize | `TabletopCardSize \| undefined` | no | `'small'` | |
|
|
281
|
+
| centerCards | `readonly PlayingCardValue[] \| undefined` | no | `[]` | |
|
|
282
|
+
| centerLabel | `React.ReactNode \| undefined` | no | — | |
|
|
283
|
+
| centerSublabel | `React.ReactNode \| undefined` | no | — | |
|
|
284
|
+
| colorScheme | `TabletopColorOverrides \| undefined` | no | — | |
|
|
285
|
+
| disabled | `boolean \| undefined` | no | `false` | |
|
|
286
|
+
| seatCount | `TabletopSeatCount \| undefined` | no | — | |
|
|
287
|
+
| seats | `readonly TabletopSeatState[]` | yes | — | |
|
|
288
|
+
| shape | `TabletopShape \| undefined` | no | `'oval'` | |
|
|
289
|
+
| testID | `string \| undefined` | no | — | |
|
|
290
|
+
|
|
291
|
+
</details>
|
|
292
|
+
|
|
293
|
+
</details>
|
|
294
|
+
|
|
295
|
+
### Utilities
|
|
296
|
+
|
|
297
|
+
<details>
|
|
298
|
+
<summary>createTabletopColorScheme</summary>
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
createTabletopColorScheme(theme: TabletopColorThemeShape, overrides?: Partial<TabletopColorScheme>) => TabletopColorScheme
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Creates the theme-derived color palette used by tabletop primitives.
|
|
305
|
+
|
|
306
|
+
Use `createTabletopColorScheme` when custom components need to align with the
|
|
307
|
+
same card, table, seat, token, and contrast-aware foreground colors as the
|
|
308
|
+
built-in tabletop components.
|
|
309
|
+
|
|
310
|
+
#### Custom color scheme
|
|
311
|
+
|
|
312
|
+
```ts
|
|
313
|
+
const colors = createTabletopColorScheme(theme, { tableFelt: '#065f46' });
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Module: `src/colors.ts`
|
|
317
|
+
Source: `src/colors.ts:73:1`
|
|
318
|
+
Related symbols: `TabletopColorScheme`
|
|
319
|
+
|
|
98
320
|
</details>
|
package/dist/colors.d.ts
CHANGED
|
@@ -44,5 +44,18 @@ export interface TabletopColorThemeShape {
|
|
|
44
44
|
};
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
|
+
/***
|
|
48
|
+
* Creates the theme-derived color palette used by tabletop primitives.
|
|
49
|
+
*
|
|
50
|
+
* Use `createTabletopColorScheme` when custom components need to align with the
|
|
51
|
+
* same card, table, seat, token, and contrast-aware foreground colors as the
|
|
52
|
+
* built-in tabletop components.
|
|
53
|
+
*
|
|
54
|
+
* @readme
|
|
55
|
+
* @example Custom color scheme
|
|
56
|
+
* ```ts
|
|
57
|
+
* const colors = createTabletopColorScheme(theme, { tableFelt: '#065f46' });
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
47
60
|
export declare function createTabletopColorScheme(theme: TabletopColorThemeShape, overrides?: TabletopColorOverrides): TabletopColorScheme;
|
|
48
61
|
//# sourceMappingURL=colors.d.ts.map
|
package/dist/colors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../src/colors.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAElE,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE;QACT,MAAM,EAAE;YACN,OAAO,EAAE;gBACP,IAAI,EAAE,MAAM,CAAC;gBACb,MAAM,EAAE,MAAM,CAAC;aAChB,CAAC;SACH,CAAC;QACF,OAAO,EAAE;YACP,OAAO,EAAE,MAAM,CAAC;YAChB,KAAK,EAAE,MAAM,CAAC;SACf,CAAC;QACF,OAAO,EAAE;YACP,MAAM,EAAE,MAAM,CAAC;YACf,OAAO,EAAE,MAAM,CAAC;YAChB,OAAO,EAAE,MAAM,CAAC;YAChB,YAAY,EAAE,MAAM,CAAC;SACtB,CAAC;QACF,OAAO,EAAE;YACP,IAAI,EAAE,MAAM,CAAC;YACb,MAAM,EAAE,MAAM,CAAC;SAChB,CAAC;KACH,CAAC;CACH;AAYD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,uBAAuB,EAC9B,SAAS,GAAE,sBAA2B,GACrC,mBAAmB,CAgDrB"}
|
|
1
|
+
{"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../src/colors.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAElE,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE;QACT,MAAM,EAAE;YACN,OAAO,EAAE;gBACP,IAAI,EAAE,MAAM,CAAC;gBACb,MAAM,EAAE,MAAM,CAAC;aAChB,CAAC;SACH,CAAC;QACF,OAAO,EAAE;YACP,OAAO,EAAE,MAAM,CAAC;YAChB,KAAK,EAAE,MAAM,CAAC;SACf,CAAC;QACF,OAAO,EAAE;YACP,MAAM,EAAE,MAAM,CAAC;YACf,OAAO,EAAE,MAAM,CAAC;YAChB,OAAO,EAAE,MAAM,CAAC;YAChB,YAAY,EAAE,MAAM,CAAC;SACtB,CAAC;QACF,OAAO,EAAE;YACP,IAAI,EAAE,MAAM,CAAC;YACb,MAAM,EAAE,MAAM,CAAC;SAChB,CAAC;KACH,CAAC;CACH;AAYD;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,uBAAuB,EAC9B,SAAS,GAAE,sBAA2B,GACrC,mBAAmB,CAgDrB"}
|
package/dist/colors.js
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
const DARK_TEXT_FALLBACK = '#111827';
|
|
2
2
|
const LIGHT_TEXT_FALLBACK = '#ffffff';
|
|
3
3
|
const MINIMUM_READABLE_CONTRAST = 4.5;
|
|
4
|
+
/***
|
|
5
|
+
* Creates the theme-derived color palette used by tabletop primitives.
|
|
6
|
+
*
|
|
7
|
+
* Use `createTabletopColorScheme` when custom components need to align with the
|
|
8
|
+
* same card, table, seat, token, and contrast-aware foreground colors as the
|
|
9
|
+
* built-in tabletop components.
|
|
10
|
+
*
|
|
11
|
+
* @readme
|
|
12
|
+
* @example Custom color scheme
|
|
13
|
+
* ```ts
|
|
14
|
+
* const colors = createTabletopColorScheme(theme, { tableFelt: '#065f46' });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
4
17
|
export function createTabletopColorScheme(theme, overrides = {}) {
|
|
5
18
|
const cardSurface = overrides.cardSurface ?? theme.semantics.neutral.surface;
|
|
6
19
|
const seatSurface = overrides.seatSurface ?? theme.semantics.neutral.surface;
|
package/dist/colors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"colors.js","sourceRoot":"","sources":["../src/colors.ts"],"names":[],"mappings":"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","sourcesContent":["export interface TabletopColorScheme {\n readonly cardBack: string;\n readonly cardBackBorder: string;\n readonly cardBorder: string;\n readonly cardSurface: string;\n readonly cardText: string;\n readonly mutedText: string;\n readonly redSuitText: string;\n readonly seatBorder: string;\n readonly seatMutedText: string;\n readonly seatSelectedBorder: string;\n readonly seatSurface: string;\n readonly seatText: string;\n readonly tableBorder: string;\n readonly tableFelt: string;\n readonly tableInnerBorder: string;\n readonly tableMutedText: string;\n readonly tableText: string;\n readonly tokenSurface: string;\n readonly tokenText: string;\n}\n\nexport type TabletopColorOverrides = Partial<TabletopColorScheme>;\n\nexport interface TabletopColorThemeShape {\n semantics: {\n action: {\n primary: {\n base: string;\n softBg: string;\n };\n };\n content: {\n default: string;\n muted: string;\n };\n neutral: {\n border: string;\n divider: string;\n surface: string;\n surfaceHover: string;\n };\n warning: {\n base: string;\n softBg: string;\n };\n };\n}\n\ninterface RgbColor {\n readonly red: number;\n readonly green: number;\n readonly blue: number;\n}\n\nconst DARK_TEXT_FALLBACK = '#111827';\nconst LIGHT_TEXT_FALLBACK = '#ffffff';\nconst MINIMUM_READABLE_CONTRAST = 4.5;\n\nexport function createTabletopColorScheme(\n theme: TabletopColorThemeShape,\n overrides: TabletopColorOverrides = {},\n): TabletopColorScheme {\n const cardSurface = overrides.cardSurface ?? theme.semantics.neutral.surface;\n const seatSurface = overrides.seatSurface ?? theme.semantics.neutral.surface;\n const tableFelt = overrides.tableFelt ?? theme.semantics.action.primary.softBg;\n const tokenSurface = overrides.tokenSurface ?? theme.semantics.warning.softBg;\n\n const cardText =\n overrides.cardText ??\n resolveReadableTextColor(cardSurface, theme.semantics.content.default, LIGHT_TEXT_FALLBACK);\n const seatText =\n overrides.seatText ??\n resolveReadableTextColor(seatSurface, theme.semantics.content.default, LIGHT_TEXT_FALLBACK);\n const tableText =\n overrides.tableText ??\n resolveReadableTextColor(tableFelt, theme.semantics.content.default, LIGHT_TEXT_FALLBACK);\n const tokenText =\n overrides.tokenText ??\n resolveReadableTextColor(tokenSurface, theme.semantics.content.default, LIGHT_TEXT_FALLBACK);\n\n return {\n cardBack: overrides.cardBack ?? theme.semantics.warning.base,\n cardBackBorder: overrides.cardBackBorder ?? theme.semantics.neutral.border,\n cardBorder: overrides.cardBorder ?? theme.semantics.neutral.border,\n cardSurface,\n cardText,\n mutedText:\n overrides.mutedText ??\n resolveReadableTextColor(cardSurface, theme.semantics.content.muted, cardText),\n redSuitText:\n overrides.redSuitText ??\n resolveReadableTextColor(cardSurface, theme.semantics.warning.base, cardText),\n seatBorder: overrides.seatBorder ?? theme.semantics.neutral.divider,\n seatMutedText:\n overrides.seatMutedText ??\n resolveReadableTextColor(seatSurface, theme.semantics.content.muted, seatText),\n seatSelectedBorder: overrides.seatSelectedBorder ?? theme.semantics.action.primary.base,\n seatSurface,\n seatText,\n tableBorder: overrides.tableBorder ?? theme.semantics.warning.base,\n tableFelt,\n tableInnerBorder: overrides.tableInnerBorder ?? theme.semantics.neutral.divider,\n tableMutedText:\n overrides.tableMutedText ??\n resolveReadableTextColor(tableFelt, theme.semantics.content.muted, tableText),\n tableText,\n tokenSurface,\n tokenText,\n };\n}\n\nfunction resolveReadableTextColor(background: string, preferred: string, fallback: string): string {\n const preferredContrast = getContrastRatio(background, preferred);\n if (preferredContrast !== null && preferredContrast >= MINIMUM_READABLE_CONTRAST) {\n return preferred;\n }\n\n const candidates = uniqueColors([preferred, fallback, LIGHT_TEXT_FALLBACK, DARK_TEXT_FALLBACK]);\n const [readableCandidate] = candidates\n .map((candidate) => ({ candidate, contrast: getContrastRatio(background, candidate) }))\n .filter(\n (entry): entry is { readonly candidate: string; readonly contrast: number } =>\n entry.contrast !== null,\n )\n .sort((left, right) => right.contrast - left.contrast);\n\n return readableCandidate?.candidate ?? preferred;\n}\n\nfunction uniqueColors(colors: readonly string[]): string[] {\n return [...new Set(colors)];\n}\n\nfunction getContrastRatio(background: string, foreground: string): number | null {\n const backgroundColor = parseHexColor(background);\n const foregroundColor = parseHexColor(foreground);\n\n if (backgroundColor === null || foregroundColor === null) return null;\n\n const backgroundLuminance = getRelativeLuminance(backgroundColor);\n const foregroundLuminance = getRelativeLuminance(foregroundColor);\n const lighter = Math.max(backgroundLuminance, foregroundLuminance);\n const darker = Math.min(backgroundLuminance, foregroundLuminance);\n\n return (lighter + 0.05) / (darker + 0.05);\n}\n\nfunction parseHexColor(color: string): RgbColor | null {\n const value = color.trim();\n const hex = value.startsWith('#') ? value.slice(1) : '';\n if (!isSupportedHexLength(hex) || !isHexColorValue(hex)) return null;\n\n if (hex.length === 3) {\n const red = hex.slice(0, 1);\n const green = hex.slice(1, 2);\n const blue = hex.slice(2, 3);\n\n return {\n red: parseInt(red + red, 16),\n green: parseInt(green + green, 16),\n blue: parseInt(blue + blue, 16),\n };\n }\n\n return {\n red: parseInt(hex.slice(0, 2), 16),\n green: parseInt(hex.slice(2, 4), 16),\n blue: parseInt(hex.slice(4, 6), 16),\n };\n}\n\nfunction isSupportedHexLength(hex: string): boolean {\n return hex.length === 3 || hex.length === 6 || hex.length === 8;\n}\n\nfunction isHexColorValue(hex: string): boolean {\n return [...hex].every((character) => isHexCharacter(character));\n}\n\nfunction isHexCharacter(character: string): boolean {\n const code = character.charCodeAt(0);\n const isDigit = code >= 48 && code <= 57;\n const isUpperHex = code >= 65 && code <= 70;\n const isLowerHex = code >= 97 && code <= 102;\n\n return isDigit || isUpperHex || isLowerHex;\n}\n\nfunction getRelativeLuminance(color: RgbColor): number {\n const red = normalizeColorChannel(color.red);\n const green = normalizeColorChannel(color.green);\n const blue = normalizeColorChannel(color.blue);\n\n return 0.2126 * red + 0.7152 * green + 0.0722 * blue;\n}\n\nfunction normalizeColorChannel(value: number): number {\n const normalized = value / 255;\n if (normalized <= 0.03928) return normalized / 12.92;\n return ((normalized + 0.055) / 1.055) ** 2.4;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"colors.js","sourceRoot":"","sources":["../src/colors.ts"],"names":[],"mappings":"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","sourcesContent":["export interface TabletopColorScheme {\n readonly cardBack: string;\n readonly cardBackBorder: string;\n readonly cardBorder: string;\n readonly cardSurface: string;\n readonly cardText: string;\n readonly mutedText: string;\n readonly redSuitText: string;\n readonly seatBorder: string;\n readonly seatMutedText: string;\n readonly seatSelectedBorder: string;\n readonly seatSurface: string;\n readonly seatText: string;\n readonly tableBorder: string;\n readonly tableFelt: string;\n readonly tableInnerBorder: string;\n readonly tableMutedText: string;\n readonly tableText: string;\n readonly tokenSurface: string;\n readonly tokenText: string;\n}\n\nexport type TabletopColorOverrides = Partial<TabletopColorScheme>;\n\nexport interface TabletopColorThemeShape {\n semantics: {\n action: {\n primary: {\n base: string;\n softBg: string;\n };\n };\n content: {\n default: string;\n muted: string;\n };\n neutral: {\n border: string;\n divider: string;\n surface: string;\n surfaceHover: string;\n };\n warning: {\n base: string;\n softBg: string;\n };\n };\n}\n\ninterface RgbColor {\n readonly red: number;\n readonly green: number;\n readonly blue: number;\n}\n\nconst DARK_TEXT_FALLBACK = '#111827';\nconst LIGHT_TEXT_FALLBACK = '#ffffff';\nconst MINIMUM_READABLE_CONTRAST = 4.5;\n\n/***\n * Creates the theme-derived color palette used by tabletop primitives.\n *\n * Use `createTabletopColorScheme` when custom components need to align with the\n * same card, table, seat, token, and contrast-aware foreground colors as the\n * built-in tabletop components.\n *\n * @readme\n * @example Custom color scheme\n * ```ts\n * const colors = createTabletopColorScheme(theme, { tableFelt: '#065f46' });\n * ```\n */\nexport function createTabletopColorScheme(\n theme: TabletopColorThemeShape,\n overrides: TabletopColorOverrides = {},\n): TabletopColorScheme {\n const cardSurface = overrides.cardSurface ?? theme.semantics.neutral.surface;\n const seatSurface = overrides.seatSurface ?? theme.semantics.neutral.surface;\n const tableFelt = overrides.tableFelt ?? theme.semantics.action.primary.softBg;\n const tokenSurface = overrides.tokenSurface ?? theme.semantics.warning.softBg;\n\n const cardText =\n overrides.cardText ??\n resolveReadableTextColor(cardSurface, theme.semantics.content.default, LIGHT_TEXT_FALLBACK);\n const seatText =\n overrides.seatText ??\n resolveReadableTextColor(seatSurface, theme.semantics.content.default, LIGHT_TEXT_FALLBACK);\n const tableText =\n overrides.tableText ??\n resolveReadableTextColor(tableFelt, theme.semantics.content.default, LIGHT_TEXT_FALLBACK);\n const tokenText =\n overrides.tokenText ??\n resolveReadableTextColor(tokenSurface, theme.semantics.content.default, LIGHT_TEXT_FALLBACK);\n\n return {\n cardBack: overrides.cardBack ?? theme.semantics.warning.base,\n cardBackBorder: overrides.cardBackBorder ?? theme.semantics.neutral.border,\n cardBorder: overrides.cardBorder ?? theme.semantics.neutral.border,\n cardSurface,\n cardText,\n mutedText:\n overrides.mutedText ??\n resolveReadableTextColor(cardSurface, theme.semantics.content.muted, cardText),\n redSuitText:\n overrides.redSuitText ??\n resolveReadableTextColor(cardSurface, theme.semantics.warning.base, cardText),\n seatBorder: overrides.seatBorder ?? theme.semantics.neutral.divider,\n seatMutedText:\n overrides.seatMutedText ??\n resolveReadableTextColor(seatSurface, theme.semantics.content.muted, seatText),\n seatSelectedBorder: overrides.seatSelectedBorder ?? theme.semantics.action.primary.base,\n seatSurface,\n seatText,\n tableBorder: overrides.tableBorder ?? theme.semantics.warning.base,\n tableFelt,\n tableInnerBorder: overrides.tableInnerBorder ?? theme.semantics.neutral.divider,\n tableMutedText:\n overrides.tableMutedText ??\n resolveReadableTextColor(tableFelt, theme.semantics.content.muted, tableText),\n tableText,\n tokenSurface,\n tokenText,\n };\n}\n\nfunction resolveReadableTextColor(background: string, preferred: string, fallback: string): string {\n const preferredContrast = getContrastRatio(background, preferred);\n if (preferredContrast !== null && preferredContrast >= MINIMUM_READABLE_CONTRAST) {\n return preferred;\n }\n\n const candidates = uniqueColors([preferred, fallback, LIGHT_TEXT_FALLBACK, DARK_TEXT_FALLBACK]);\n const [readableCandidate] = candidates\n .map((candidate) => ({ candidate, contrast: getContrastRatio(background, candidate) }))\n .filter(\n (entry): entry is { readonly candidate: string; readonly contrast: number } =>\n entry.contrast !== null,\n )\n .sort((left, right) => right.contrast - left.contrast);\n\n return readableCandidate?.candidate ?? preferred;\n}\n\nfunction uniqueColors(colors: readonly string[]): string[] {\n return [...new Set(colors)];\n}\n\nfunction getContrastRatio(background: string, foreground: string): number | null {\n const backgroundColor = parseHexColor(background);\n const foregroundColor = parseHexColor(foreground);\n\n if (backgroundColor === null || foregroundColor === null) return null;\n\n const backgroundLuminance = getRelativeLuminance(backgroundColor);\n const foregroundLuminance = getRelativeLuminance(foregroundColor);\n const lighter = Math.max(backgroundLuminance, foregroundLuminance);\n const darker = Math.min(backgroundLuminance, foregroundLuminance);\n\n return (lighter + 0.05) / (darker + 0.05);\n}\n\nfunction parseHexColor(color: string): RgbColor | null {\n const value = color.trim();\n const hex = value.startsWith('#') ? value.slice(1) : '';\n if (!isSupportedHexLength(hex) || !isHexColorValue(hex)) return null;\n\n if (hex.length === 3) {\n const red = hex.slice(0, 1);\n const green = hex.slice(1, 2);\n const blue = hex.slice(2, 3);\n\n return {\n red: parseInt(red + red, 16),\n green: parseInt(green + green, 16),\n blue: parseInt(blue + blue, 16),\n };\n }\n\n return {\n red: parseInt(hex.slice(0, 2), 16),\n green: parseInt(hex.slice(2, 4), 16),\n blue: parseInt(hex.slice(4, 6), 16),\n };\n}\n\nfunction isSupportedHexLength(hex: string): boolean {\n return hex.length === 3 || hex.length === 6 || hex.length === 8;\n}\n\nfunction isHexColorValue(hex: string): boolean {\n return [...hex].every((character) => isHexCharacter(character));\n}\n\nfunction isHexCharacter(character: string): boolean {\n const code = character.charCodeAt(0);\n const isDigit = code >= 48 && code <= 57;\n const isUpperHex = code >= 65 && code <= 70;\n const isLowerHex = code >= 97 && code <= 102;\n\n return isDigit || isUpperHex || isLowerHex;\n}\n\nfunction getRelativeLuminance(color: RgbColor): number {\n const red = normalizeColorChannel(color.red);\n const green = normalizeColorChannel(color.green);\n const blue = normalizeColorChannel(color.blue);\n\n return 0.2126 * red + 0.7152 * green + 0.0722 * blue;\n}\n\nfunction normalizeColorChannel(value: number): number {\n const normalized = value / 255;\n if (normalized <= 0.03928) return normalized / 12.92;\n return ((normalized + 0.055) / 1.055) ** 2.4;\n}\n"]}
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { CardBackProps } from './types';
|
|
3
|
+
/***
|
|
4
|
+
* Face-down playing-card primitive for hidden cards and decks.
|
|
5
|
+
*
|
|
6
|
+
* Use `CardBack` when a card should be represented visually without exposing its
|
|
7
|
+
* rank or suit. The component keeps a generic accessible label for hidden cards.
|
|
8
|
+
*
|
|
9
|
+
* @readme
|
|
10
|
+
* @example Hidden cards
|
|
11
|
+
* ```tsx
|
|
12
|
+
* <CardBack size="small" />
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
3
15
|
export declare function CardBack({ size, muted, accessibilityLabel, colorScheme, testID, }: CardBackProps): React.JSX.Element;
|
|
4
16
|
//# sourceMappingURL=CardBack.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CardBack.d.ts","sourceRoot":"","sources":["../../../src/components/card-back/CardBack.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,wBAAgB,QAAQ,CAAC,EACvB,IAAe,EACf,KAAa,EACb,kBAAkB,EAClB,WAAW,EACX,MAAM,GACP,EAAE,aAAa,qBAoCf"}
|
|
1
|
+
{"version":3,"file":"CardBack.d.ts","sourceRoot":"","sources":["../../../src/components/card-back/CardBack.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,EACvB,IAAe,EACf,KAAa,EACb,kBAAkB,EAClB,WAAW,EACX,MAAM,GACP,EAAE,aAAa,qBAoCf"}
|
|
@@ -4,6 +4,18 @@ import { StyleSheet, View } from 'react-native';
|
|
|
4
4
|
import { createHiddenCardLabel } from '../../cardLabel';
|
|
5
5
|
import { getTabletopCardDimensions } from '../../cardSizing';
|
|
6
6
|
import { createTabletopColorScheme } from '../../colors';
|
|
7
|
+
/***
|
|
8
|
+
* Face-down playing-card primitive for hidden cards and decks.
|
|
9
|
+
*
|
|
10
|
+
* Use `CardBack` when a card should be represented visually without exposing its
|
|
11
|
+
* rank or suit. The component keeps a generic accessible label for hidden cards.
|
|
12
|
+
*
|
|
13
|
+
* @readme
|
|
14
|
+
* @example Hidden cards
|
|
15
|
+
* ```tsx
|
|
16
|
+
* <CardBack size="small" />
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
7
19
|
export function CardBack({ size = 'medium', muted = false, accessibilityLabel, colorScheme, testID, }) {
|
|
8
20
|
const { theme } = useZoraTheme();
|
|
9
21
|
const colors = React.useMemo(() => createTabletopColorScheme(theme, colorScheme), [colorScheme, theme]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CardBack.js","sourceRoot":"","sources":["../../../src/components/card-back/CardBack.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAGzD,MAAM,UAAU,QAAQ,CAAC,EACvB,IAAI,GAAG,QAAQ,EACf,KAAK,GAAG,KAAK,EACb,kBAAkB,EAClB,WAAW,EACX,MAAM,GACQ;IACd,MAAM,EAAE,KAAK,EAAE,GAAG,YAAY,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAC1B,GAAG,EAAE,CAAC,yBAAyB,CAAC,KAAK,EAAE,WAAW,CAAC,EACnD,CAAC,WAAW,EAAE,KAAK,CAAC,CACrB,CAAC;IACF,MAAM,UAAU,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAEnD,OAAO,CACL,CAAC,IAAI,CACH,kBAAkB,CAAC,CAAC,kBAAkB,IAAI,qBAAqB,EAAE,CAAC,CAClE,iBAAiB,CAAC,OAAO,CACzB,KAAK,CAAC,CAAC;YACL,MAAM,CAAC,IAAI;YACX;gBACE,eAAe,EAAE,MAAM,CAAC,QAAQ;gBAChC,WAAW,EAAE,MAAM,CAAC,cAAc;gBAClC,YAAY,EAAE,UAAU,CAAC,MAAM;gBAC/B,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACzB,KAAK,EAAE,UAAU,CAAC,KAAK;aACxB;SACF,CAAC,CACF,MAAM,CAAC,CAAC,MAAM,CAAC,CAEf;MAAA,CAAC,IAAI,CACH,KAAK,CAAC,CAAC;YACL,MAAM,CAAC,KAAK;YACZ;gBACE,WAAW,EAAE,MAAM,CAAC,cAAc;gBAClC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;aACjD;SACF,CAAC,EAEN;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC;AAED,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAC/B,IAAI,EAAE;QACJ,UAAU,EAAE,QAAQ;QACpB,WAAW,EAAE,CAAC;QACd,cAAc,EAAE,QAAQ;KACzB;IACD,KAAK,EAAE;QACL,WAAW,EAAE,CAAC;QACd,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,KAAK;KACb;CACF,CAAC,CAAC","sourcesContent":["import { useZoraTheme } from '@ankhorage/zora';\nimport React from 'react';\nimport { StyleSheet, View } from 'react-native';\n\nimport { createHiddenCardLabel } from '../../cardLabel';\nimport { getTabletopCardDimensions } from '../../cardSizing';\nimport { createTabletopColorScheme } from '../../colors';\nimport type { CardBackProps } from './types';\n\nexport function CardBack({\n size = 'medium',\n muted = false,\n accessibilityLabel,\n colorScheme,\n testID,\n}: CardBackProps) {\n const { theme } = useZoraTheme();\n const colors = React.useMemo(\n () => createTabletopColorScheme(theme, colorScheme),\n [colorScheme, theme],\n );\n const dimensions = getTabletopCardDimensions(size);\n\n return (\n <View\n accessibilityLabel={accessibilityLabel ?? createHiddenCardLabel()}\n accessibilityRole=\"image\"\n style={[\n styles.card,\n {\n backgroundColor: colors.cardBack,\n borderColor: colors.cardBackBorder,\n borderRadius: dimensions.radius,\n height: dimensions.height,\n opacity: muted ? 0.48 : 1,\n width: dimensions.width,\n },\n ]}\n testID={testID}\n >\n <View\n style={[\n styles.inner,\n {\n borderColor: colors.cardBackBorder,\n borderRadius: Math.max(2, dimensions.radius - 3),\n },\n ]}\n />\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n card: {\n alignItems: 'center',\n borderWidth: 1,\n justifyContent: 'center',\n },\n inner: {\n borderWidth: 1,\n height: '68%',\n opacity: 0.48,\n width: '68%',\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"CardBack.js","sourceRoot":"","sources":["../../../src/components/card-back/CardBack.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAGzD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,QAAQ,CAAC,EACvB,IAAI,GAAG,QAAQ,EACf,KAAK,GAAG,KAAK,EACb,kBAAkB,EAClB,WAAW,EACX,MAAM,GACQ;IACd,MAAM,EAAE,KAAK,EAAE,GAAG,YAAY,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAC1B,GAAG,EAAE,CAAC,yBAAyB,CAAC,KAAK,EAAE,WAAW,CAAC,EACnD,CAAC,WAAW,EAAE,KAAK,CAAC,CACrB,CAAC;IACF,MAAM,UAAU,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;IAEnD,OAAO,CACL,CAAC,IAAI,CACH,kBAAkB,CAAC,CAAC,kBAAkB,IAAI,qBAAqB,EAAE,CAAC,CAClE,iBAAiB,CAAC,OAAO,CACzB,KAAK,CAAC,CAAC;YACL,MAAM,CAAC,IAAI;YACX;gBACE,eAAe,EAAE,MAAM,CAAC,QAAQ;gBAChC,WAAW,EAAE,MAAM,CAAC,cAAc;gBAClC,YAAY,EAAE,UAAU,CAAC,MAAM;gBAC/B,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACzB,KAAK,EAAE,UAAU,CAAC,KAAK;aACxB;SACF,CAAC,CACF,MAAM,CAAC,CAAC,MAAM,CAAC,CAEf;MAAA,CAAC,IAAI,CACH,KAAK,CAAC,CAAC;YACL,MAAM,CAAC,KAAK;YACZ;gBACE,WAAW,EAAE,MAAM,CAAC,cAAc;gBAClC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;aACjD;SACF,CAAC,EAEN;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC;AAED,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAC/B,IAAI,EAAE;QACJ,UAAU,EAAE,QAAQ;QACpB,WAAW,EAAE,CAAC;QACd,cAAc,EAAE,QAAQ;KACzB;IACD,KAAK,EAAE;QACL,WAAW,EAAE,CAAC;QACd,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,KAAK;KACb;CACF,CAAC,CAAC","sourcesContent":["import { useZoraTheme } from '@ankhorage/zora';\nimport React from 'react';\nimport { StyleSheet, View } from 'react-native';\n\nimport { createHiddenCardLabel } from '../../cardLabel';\nimport { getTabletopCardDimensions } from '../../cardSizing';\nimport { createTabletopColorScheme } from '../../colors';\nimport type { CardBackProps } from './types';\n\n/***\n * Face-down playing-card primitive for hidden cards and decks.\n *\n * Use `CardBack` when a card should be represented visually without exposing its\n * rank or suit. The component keeps a generic accessible label for hidden cards.\n *\n * @readme\n * @example Hidden cards\n * ```tsx\n * <CardBack size=\"small\" />\n * ```\n */\nexport function CardBack({\n size = 'medium',\n muted = false,\n accessibilityLabel,\n colorScheme,\n testID,\n}: CardBackProps) {\n const { theme } = useZoraTheme();\n const colors = React.useMemo(\n () => createTabletopColorScheme(theme, colorScheme),\n [colorScheme, theme],\n );\n const dimensions = getTabletopCardDimensions(size);\n\n return (\n <View\n accessibilityLabel={accessibilityLabel ?? createHiddenCardLabel()}\n accessibilityRole=\"image\"\n style={[\n styles.card,\n {\n backgroundColor: colors.cardBack,\n borderColor: colors.cardBackBorder,\n borderRadius: dimensions.radius,\n height: dimensions.height,\n opacity: muted ? 0.48 : 1,\n width: dimensions.width,\n },\n ]}\n testID={testID}\n >\n <View\n style={[\n styles.inner,\n {\n borderColor: colors.cardBackBorder,\n borderRadius: Math.max(2, dimensions.radius - 3),\n },\n ]}\n />\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n card: {\n alignItems: 'center',\n borderWidth: 1,\n justifyContent: 'center',\n },\n inner: {\n borderWidth: 1,\n height: '68%',\n opacity: 0.48,\n width: '68%',\n },\n});\n"]}
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { CardHandProps } from './types';
|
|
3
|
+
/***
|
|
4
|
+
* Compact row of visible and face-down playing cards.
|
|
5
|
+
*
|
|
6
|
+
* Use `CardHand` when a seat, pile, or custom layout needs to show multiple cards
|
|
7
|
+
* with consistent spacing, sizing, and muted state handling.
|
|
8
|
+
*
|
|
9
|
+
* @readme
|
|
10
|
+
* @example Mixed hand
|
|
11
|
+
* ```tsx
|
|
12
|
+
* <CardHand cards={[{ rank: 'Q', suit: 'hearts' }]} faceDownCards={1} />
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
3
15
|
export declare function CardHand({ cards, faceDownCards, size, muted, colorScheme, accessibilityLabel, testID, }: CardHandProps): React.JSX.Element;
|
|
4
16
|
//# sourceMappingURL=CardHand.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CardHand.d.ts","sourceRoot":"","sources":["../../../src/components/card-hand/CardHand.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAM7C,wBAAgB,QAAQ,CAAC,EACvB,KAAU,EACV,aAAiB,EACjB,IAAe,EACf,KAAa,EACb,WAAW,EACX,kBAAkB,EAClB,MAAM,GACP,EAAE,aAAa,qBA0Bf"}
|
|
1
|
+
{"version":3,"file":"CardHand.d.ts","sourceRoot":"","sources":["../../../src/components/card-hand/CardHand.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAM7C;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAU,EACV,aAAiB,EACjB,IAAe,EACf,KAAa,EACb,WAAW,EACX,kBAAkB,EAClB,MAAM,GACP,EAAE,aAAa,qBA0Bf"}
|
|
@@ -5,6 +5,18 @@ import { PlayingCard } from '../playing-card';
|
|
|
5
5
|
function createFaceDownCards(count) {
|
|
6
6
|
return Array.from({ length: Math.max(0, count) }, (_, index) => index);
|
|
7
7
|
}
|
|
8
|
+
/***
|
|
9
|
+
* Compact row of visible and face-down playing cards.
|
|
10
|
+
*
|
|
11
|
+
* Use `CardHand` when a seat, pile, or custom layout needs to show multiple cards
|
|
12
|
+
* with consistent spacing, sizing, and muted state handling.
|
|
13
|
+
*
|
|
14
|
+
* @readme
|
|
15
|
+
* @example Mixed hand
|
|
16
|
+
* ```tsx
|
|
17
|
+
* <CardHand cards={[{ rank: 'Q', suit: 'hearts' }]} faceDownCards={1} />
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
8
20
|
export function CardHand({ cards = [], faceDownCards = 0, size = 'medium', muted = false, colorScheme, accessibilityLabel, testID, }) {
|
|
9
21
|
const hiddenCards = createFaceDownCards(faceDownCards);
|
|
10
22
|
return (<View accessibilityLabel={accessibilityLabel} style={styles.hand} testID={testID}>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CardHand.js","sourceRoot":"","sources":["../../../src/components/card-hand/CardHand.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,EACvB,KAAK,GAAG,EAAE,EACV,aAAa,GAAG,CAAC,EACjB,IAAI,GAAG,QAAQ,EACf,KAAK,GAAG,KAAK,EACb,WAAW,EACX,kBAAkB,EAClB,MAAM,GACQ;IACd,MAAM,WAAW,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAEvD,OAAO,CACL,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,kBAAkB,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAC/E;MAAA,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAC1B,CAAC,WAAW,CACV,IAAI,CAAC,CAAC,IAAI,CAAC,CACX,WAAW,CAAC,CAAC,WAAW,CAAC,CACzB,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,KAAK,EAAE,CAAC,CAC1C,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,IAAI,CAAC,CAAC,IAAI,CAAC,CACX,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,SAAS,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EACvD,CACH,CAAC,CACF;MAAA,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAC1B,CAAC,QAAQ,CACP,WAAW,CAAC,CAAC,WAAW,CAAC,CACzB,GAAG,CAAC,CAAC,UAAU,KAAK,EAAE,CAAC,CACvB,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,IAAI,CAAC,CAAC,IAAI,CAAC,CACX,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,WAAW,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EACzD,CACH,CAAC,CACJ;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC;AAED,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAC/B,IAAI,EAAE;QACJ,UAAU,EAAE,QAAQ;QACpB,aAAa,EAAE,KAAK;QACpB,GAAG,EAAE,CAAC;QACN,cAAc,EAAE,QAAQ;KACzB;CACF,CAAC,CAAC","sourcesContent":["import React from 'react';\nimport { StyleSheet, View } from 'react-native';\n\nimport { CardBack } from '../card-back';\nimport { PlayingCard } from '../playing-card';\nimport type { CardHandProps } from './types';\n\nfunction createFaceDownCards(count: number): readonly number[] {\n return Array.from({ length: Math.max(0, count) }, (_, index) => index);\n}\n\nexport function CardHand({\n cards = [],\n faceDownCards = 0,\n size = 'medium',\n muted = false,\n colorScheme,\n accessibilityLabel,\n testID,\n}: CardHandProps) {\n const hiddenCards = createFaceDownCards(faceDownCards);\n\n return (\n <View accessibilityLabel={accessibilityLabel} style={styles.hand} testID={testID}>\n {cards.map((card, index) => (\n <PlayingCard\n card={card}\n colorScheme={colorScheme}\n key={`${card.rank}-${card.suit}-${index}`}\n muted={muted}\n size={size}\n testID={testID ? `${testID}-card-${index}` : undefined}\n />\n ))}\n {hiddenCards.map((index) => (\n <CardBack\n colorScheme={colorScheme}\n key={`hidden-${index}`}\n muted={muted}\n size={size}\n testID={testID ? `${testID}-hidden-${index}` : undefined}\n />\n ))}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n hand: {\n alignItems: 'center',\n flexDirection: 'row',\n gap: 4,\n justifyContent: 'center',\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"CardHand.js","sourceRoot":"","sources":["../../../src/components/card-hand/CardHand.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;AACzE,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,QAAQ,CAAC,EACvB,KAAK,GAAG,EAAE,EACV,aAAa,GAAG,CAAC,EACjB,IAAI,GAAG,QAAQ,EACf,KAAK,GAAG,KAAK,EACb,WAAW,EACX,kBAAkB,EAClB,MAAM,GACQ;IACd,MAAM,WAAW,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAEvD,OAAO,CACL,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,kBAAkB,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAC/E;MAAA,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAC1B,CAAC,WAAW,CACV,IAAI,CAAC,CAAC,IAAI,CAAC,CACX,WAAW,CAAC,CAAC,WAAW,CAAC,CACzB,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,KAAK,EAAE,CAAC,CAC1C,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,IAAI,CAAC,CAAC,IAAI,CAAC,CACX,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,SAAS,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EACvD,CACH,CAAC,CACF;MAAA,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAC1B,CAAC,QAAQ,CACP,WAAW,CAAC,CAAC,WAAW,CAAC,CACzB,GAAG,CAAC,CAAC,UAAU,KAAK,EAAE,CAAC,CACvB,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,IAAI,CAAC,CAAC,IAAI,CAAC,CACX,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,WAAW,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EACzD,CACH,CAAC,CACJ;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC;AAED,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAC/B,IAAI,EAAE;QACJ,UAAU,EAAE,QAAQ;QACpB,aAAa,EAAE,KAAK;QACpB,GAAG,EAAE,CAAC;QACN,cAAc,EAAE,QAAQ;KACzB;CACF,CAAC,CAAC","sourcesContent":["import React from 'react';\nimport { StyleSheet, View } from 'react-native';\n\nimport { CardBack } from '../card-back';\nimport { PlayingCard } from '../playing-card';\nimport type { CardHandProps } from './types';\n\nfunction createFaceDownCards(count: number): readonly number[] {\n return Array.from({ length: Math.max(0, count) }, (_, index) => index);\n}\n\n/***\n * Compact row of visible and face-down playing cards.\n *\n * Use `CardHand` when a seat, pile, or custom layout needs to show multiple cards\n * with consistent spacing, sizing, and muted state handling.\n *\n * @readme\n * @example Mixed hand\n * ```tsx\n * <CardHand cards={[{ rank: 'Q', suit: 'hearts' }]} faceDownCards={1} />\n * ```\n */\nexport function CardHand({\n cards = [],\n faceDownCards = 0,\n size = 'medium',\n muted = false,\n colorScheme,\n accessibilityLabel,\n testID,\n}: CardHandProps) {\n const hiddenCards = createFaceDownCards(faceDownCards);\n\n return (\n <View accessibilityLabel={accessibilityLabel} style={styles.hand} testID={testID}>\n {cards.map((card, index) => (\n <PlayingCard\n card={card}\n colorScheme={colorScheme}\n key={`${card.rank}-${card.suit}-${index}`}\n muted={muted}\n size={size}\n testID={testID ? `${testID}-card-${index}` : undefined}\n />\n ))}\n {hiddenCards.map((index) => (\n <CardBack\n colorScheme={colorScheme}\n key={`hidden-${index}`}\n muted={muted}\n size={size}\n testID={testID ? `${testID}-hidden-${index}` : undefined}\n />\n ))}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n hand: {\n alignItems: 'center',\n flexDirection: 'row',\n gap: 4,\n justifyContent: 'center',\n },\n});\n"]}
|
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { PlayingCardProps } from './types';
|
|
3
|
+
/***
|
|
4
|
+
* Theme-aware face-up playing card primitive.
|
|
5
|
+
*
|
|
6
|
+
* Use `PlayingCard` for visible card values in hands, shared table cards, piles,
|
|
7
|
+
* or custom tabletop layouts. The component renders rank and suit text and exposes
|
|
8
|
+
* an accessible card label by default.
|
|
9
|
+
*
|
|
10
|
+
* @readme
|
|
11
|
+
* @example Face-up card
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <PlayingCard card={{ rank: 'A', suit: 'spades' }} selected />
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
3
16
|
export declare function PlayingCard({ card, size, selected, muted, accessibilityLabel, colorScheme, testID, }: PlayingCardProps): React.JSX.Element;
|
|
4
17
|
//# sourceMappingURL=PlayingCard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlayingCard.d.ts","sourceRoot":"","sources":["../../../src/components/playing-card/PlayingCard.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAahD,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,IAAe,EACf,QAAgB,EAChB,KAAa,EACb,kBAAkB,EAClB,WAAW,EACX,MAAM,GACP,EAAE,gBAAgB,qBAsDlB"}
|
|
1
|
+
{"version":3,"file":"PlayingCard.d.ts","sourceRoot":"","sources":["../../../src/components/playing-card/PlayingCard.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAahD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,IAAe,EACf,QAAgB,EAChB,KAAa,EACb,kBAAkB,EAClB,WAAW,EACX,MAAM,GACP,EAAE,gBAAgB,qBAsDlB"}
|
|
@@ -13,6 +13,19 @@ const suitMarks = {
|
|
|
13
13
|
function isRedSuit(suit) {
|
|
14
14
|
return suit === 'diamonds' || suit === 'hearts';
|
|
15
15
|
}
|
|
16
|
+
/***
|
|
17
|
+
* Theme-aware face-up playing card primitive.
|
|
18
|
+
*
|
|
19
|
+
* Use `PlayingCard` for visible card values in hands, shared table cards, piles,
|
|
20
|
+
* or custom tabletop layouts. The component renders rank and suit text and exposes
|
|
21
|
+
* an accessible card label by default.
|
|
22
|
+
*
|
|
23
|
+
* @readme
|
|
24
|
+
* @example Face-up card
|
|
25
|
+
* ```tsx
|
|
26
|
+
* <PlayingCard card={{ rank: 'A', suit: 'spades' }} selected />
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
16
29
|
export function PlayingCard({ card, size = 'medium', selected = false, muted = false, accessibilityLabel, colorScheme, testID, }) {
|
|
17
30
|
const { theme } = useZoraTheme();
|
|
18
31
|
const colors = React.useMemo(() => createTabletopColorScheme(theme, colorScheme), [colorScheme, theme]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlayingCard.js","sourceRoot":"","sources":["../../../src/components/playing-card/PlayingCard.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useZoraTheme } from '@ankhorage/zora';\nimport React from 'react';\nimport { StyleSheet, Text, View } from 'react-native';\n\nimport { getPlayingCardLabel } from '../../cardLabel';\nimport { getTabletopCardDimensions } from '../../cardSizing';\nimport { createTabletopColorScheme } from '../../colors';\nimport type { PlayingCardSuit } from '../../types';\nimport type { PlayingCardProps } from './types';\n\nconst suitMarks: Readonly<Record<PlayingCardSuit, string>> = {\n clubs: 'C',\n diamonds: 'D',\n hearts: 'H',\n spades: 'S',\n};\n\nfunction isRedSuit(suit: PlayingCardSuit): boolean {\n return suit === 'diamonds' || suit === 'hearts';\n}\n\nexport function PlayingCard({\n card,\n size = 'medium',\n selected = false,\n muted = false,\n accessibilityLabel,\n colorScheme,\n testID,\n}: PlayingCardProps) {\n const { theme } = useZoraTheme();\n const colors = React.useMemo(\n () => createTabletopColorScheme(theme, colorScheme),\n [colorScheme, theme],\n );\n const dimensions = getTabletopCardDimensions(size);\n const suitColor = isRedSuit(card.suit) ? colors.redSuitText : colors.cardText;\n\n return (\n <View\n accessibilityLabel={accessibilityLabel ?? getPlayingCardLabel(card)}\n accessibilityRole=\"image\"\n style={[\n styles.card,\n {\n backgroundColor: colors.cardSurface,\n borderColor: selected ? colors.seatSelectedBorder : colors.cardBorder,\n borderRadius: dimensions.radius,\n height: dimensions.height,\n opacity: muted ? 0.48 : 1,\n width: dimensions.width,\n },\n ]}\n testID={testID}\n >\n <Text\n selectable={false}\n style={[\n styles.rank,\n {\n color: suitColor,\n fontSize: dimensions.rankFontSize,\n lineHeight: dimensions.rankFontSize + 4,\n },\n ]}\n >\n {card.rank}\n </Text>\n <Text\n selectable={false}\n style={[\n styles.suit,\n {\n color: suitColor,\n fontSize: dimensions.suitFontSize,\n lineHeight: dimensions.suitFontSize + 3,\n },\n ]}\n >\n {suitMarks[card.suit]}\n </Text>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n card: {\n alignItems: 'center',\n borderWidth: 1,\n justifyContent: 'center',\n },\n rank: {\n fontWeight: '800',\n },\n suit: {\n fontWeight: '700',\n marginTop: -2,\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"PlayingCard.js","sourceRoot":"","sources":["../../../src/components/playing-card/PlayingCard.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAIzD,MAAM,SAAS,GAA8C;IAC3D,KAAK,EAAE,GAAG;IACV,QAAQ,EAAE,GAAG;IACb,MAAM,EAAE,GAAG;IACX,MAAM,EAAE,GAAG;CACZ,CAAC;AAEF,SAAS,SAAS,CAAC,IAAqB;IACtC,OAAO,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,QAAQ,CAAC;AAClD,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,WAAW,CAAC,EAC1B,IAAI,EACJ,IAAI,GAAG,QAAQ,EACf,QAAQ,GAAG,KAAK,EAChB,KAAK,GAAG,KAAK,EACb,kBAAkB,EAClB,WAAW,EACX,MAAM,GACW;IACjB,MAAM,EAAE,KAAK,EAAE,GAAG,YAAY,EAAE,CAAC;IACjC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAC1B,GAAG,EAAE,CAAC,yBAAyB,CAAC,KAAK,EAAE,WAAW,CAAC,EACnD,CAAC,WAAW,EAAE,KAAK,CAAC,CACrB,CAAC;IACF,MAAM,UAAU,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAC;IACnD,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;IAE9E,OAAO,CACL,CAAC,IAAI,CACH,kBAAkB,CAAC,CAAC,kBAAkB,IAAI,mBAAmB,CAAC,IAAI,CAAC,CAAC,CACpE,iBAAiB,CAAC,OAAO,CACzB,KAAK,CAAC,CAAC;YACL,MAAM,CAAC,IAAI;YACX;gBACE,eAAe,EAAE,MAAM,CAAC,WAAW;gBACnC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU;gBACrE,YAAY,EAAE,UAAU,CAAC,MAAM;gBAC/B,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACzB,KAAK,EAAE,UAAU,CAAC,KAAK;aACxB;SACF,CAAC,CACF,MAAM,CAAC,CAAC,MAAM,CAAC,CAEf;MAAA,CAAC,IAAI,CACH,UAAU,CAAC,CAAC,KAAK,CAAC,CAClB,KAAK,CAAC,CAAC;YACL,MAAM,CAAC,IAAI;YACX;gBACE,KAAK,EAAE,SAAS;gBAChB,QAAQ,EAAE,UAAU,CAAC,YAAY;gBACjC,UAAU,EAAE,UAAU,CAAC,YAAY,GAAG,CAAC;aACxC;SACF,CAAC,CAEF;QAAA,CAAC,IAAI,CAAC,IAAI,CACZ;MAAA,EAAE,IAAI,CACN;MAAA,CAAC,IAAI,CACH,UAAU,CAAC,CAAC,KAAK,CAAC,CAClB,KAAK,CAAC,CAAC;YACL,MAAM,CAAC,IAAI;YACX;gBACE,KAAK,EAAE,SAAS;gBAChB,QAAQ,EAAE,UAAU,CAAC,YAAY;gBACjC,UAAU,EAAE,UAAU,CAAC,YAAY,GAAG,CAAC;aACxC;SACF,CAAC,CAEF;QAAA,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CACvB;MAAA,EAAE,IAAI,CACR;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC;AAED,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAC/B,IAAI,EAAE;QACJ,UAAU,EAAE,QAAQ;QACpB,WAAW,EAAE,CAAC;QACd,cAAc,EAAE,QAAQ;KACzB;IACD,IAAI,EAAE;QACJ,UAAU,EAAE,KAAK;KAClB;IACD,IAAI,EAAE;QACJ,UAAU,EAAE,KAAK;QACjB,SAAS,EAAE,CAAC,CAAC;KACd;CACF,CAAC,CAAC","sourcesContent":["import { useZoraTheme } from '@ankhorage/zora';\nimport React from 'react';\nimport { StyleSheet, Text, View } from 'react-native';\n\nimport { getPlayingCardLabel } from '../../cardLabel';\nimport { getTabletopCardDimensions } from '../../cardSizing';\nimport { createTabletopColorScheme } from '../../colors';\nimport type { PlayingCardSuit } from '../../types';\nimport type { PlayingCardProps } from './types';\n\nconst suitMarks: Readonly<Record<PlayingCardSuit, string>> = {\n clubs: 'C',\n diamonds: 'D',\n hearts: 'H',\n spades: 'S',\n};\n\nfunction isRedSuit(suit: PlayingCardSuit): boolean {\n return suit === 'diamonds' || suit === 'hearts';\n}\n\n/***\n * Theme-aware face-up playing card primitive.\n *\n * Use `PlayingCard` for visible card values in hands, shared table cards, piles,\n * or custom tabletop layouts. The component renders rank and suit text and exposes\n * an accessible card label by default.\n *\n * @readme\n * @example Face-up card\n * ```tsx\n * <PlayingCard card={{ rank: 'A', suit: 'spades' }} selected />\n * ```\n */\nexport function PlayingCard({\n card,\n size = 'medium',\n selected = false,\n muted = false,\n accessibilityLabel,\n colorScheme,\n testID,\n}: PlayingCardProps) {\n const { theme } = useZoraTheme();\n const colors = React.useMemo(\n () => createTabletopColorScheme(theme, colorScheme),\n [colorScheme, theme],\n );\n const dimensions = getTabletopCardDimensions(size);\n const suitColor = isRedSuit(card.suit) ? colors.redSuitText : colors.cardText;\n\n return (\n <View\n accessibilityLabel={accessibilityLabel ?? getPlayingCardLabel(card)}\n accessibilityRole=\"image\"\n style={[\n styles.card,\n {\n backgroundColor: colors.cardSurface,\n borderColor: selected ? colors.seatSelectedBorder : colors.cardBorder,\n borderRadius: dimensions.radius,\n height: dimensions.height,\n opacity: muted ? 0.48 : 1,\n width: dimensions.width,\n },\n ]}\n testID={testID}\n >\n <Text\n selectable={false}\n style={[\n styles.rank,\n {\n color: suitColor,\n fontSize: dimensions.rankFontSize,\n lineHeight: dimensions.rankFontSize + 4,\n },\n ]}\n >\n {card.rank}\n </Text>\n <Text\n selectable={false}\n style={[\n styles.suit,\n {\n color: suitColor,\n fontSize: dimensions.suitFontSize,\n lineHeight: dimensions.suitFontSize + 3,\n },\n ]}\n >\n {suitMarks[card.suit]}\n </Text>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n card: {\n alignItems: 'center',\n borderWidth: 1,\n justifyContent: 'center',\n },\n rank: {\n fontWeight: '800',\n },\n suit: {\n fontWeight: '700',\n marginTop: -2,\n },\n});\n"]}
|
|
@@ -1,4 +1,21 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { TabletopTableProps } from './types';
|
|
3
|
+
/***
|
|
4
|
+
* Responsive tabletop surface for generic card-game and board-game scenes.
|
|
5
|
+
*
|
|
6
|
+
* Use `TabletopTable` to arrange seats around a themed table surface, display
|
|
7
|
+
* shared center cards, and show neutral seat labels/tokens without embedding game
|
|
8
|
+
* rules into the component.
|
|
9
|
+
*
|
|
10
|
+
* @readme
|
|
11
|
+
* @example Basic table
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <TabletopTable
|
|
14
|
+
* seats={seats}
|
|
15
|
+
* centerCards={[{ rank: 'A', suit: 'spades' }]}
|
|
16
|
+
* centerLabel="Round 1"
|
|
17
|
+
* />
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
3
20
|
export declare function TabletopTable({ seats, centerCards, centerLabel, centerSublabel, shape, seatCount, cardSize, disabled, colorScheme, accessibilityLabel, testID, }: TabletopTableProps): React.JSX.Element;
|
|
4
21
|
//# sourceMappingURL=TabletopTable.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabletopTable.d.ts","sourceRoot":"","sources":["../../../src/components/tabletop-table/TabletopTable.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAelD,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,WAAgB,EAChB,WAAW,EACX,cAAc,EACd,KAAc,EACd,SAAS,EACT,QAAkB,EAClB,QAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,MAAM,GACP,EAAE,kBAAkB,qBAmGpB"}
|
|
1
|
+
{"version":3,"file":"TabletopTable.d.ts","sourceRoot":"","sources":["../../../src/components/tabletop-table/TabletopTable.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAelD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,WAAgB,EAChB,WAAW,EACX,cAAc,EACd,KAAc,EACd,SAAS,EACT,QAAkB,EAClB,QAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,MAAM,GACP,EAAE,kBAAkB,qBAmGpB"}
|
|
@@ -20,6 +20,23 @@ function createSeatAccessibilityLabel(seat) {
|
|
|
20
20
|
parts.push('muted');
|
|
21
21
|
return parts.join(', ');
|
|
22
22
|
}
|
|
23
|
+
/***
|
|
24
|
+
* Responsive tabletop surface for generic card-game and board-game scenes.
|
|
25
|
+
*
|
|
26
|
+
* Use `TabletopTable` to arrange seats around a themed table surface, display
|
|
27
|
+
* shared center cards, and show neutral seat labels/tokens without embedding game
|
|
28
|
+
* rules into the component.
|
|
29
|
+
*
|
|
30
|
+
* @readme
|
|
31
|
+
* @example Basic table
|
|
32
|
+
* ```tsx
|
|
33
|
+
* <TabletopTable
|
|
34
|
+
* seats={seats}
|
|
35
|
+
* centerCards={[{ rank: 'A', suit: 'spades' }]}
|
|
36
|
+
* centerLabel="Round 1"
|
|
37
|
+
* />
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
23
40
|
export function TabletopTable({ seats, centerCards = [], centerLabel, centerSublabel, shape = 'oval', seatCount, cardSize = 'small', disabled = false, colorScheme, accessibilityLabel, testID, }) {
|
|
24
41
|
const { theme } = useZoraTheme();
|
|
25
42
|
const colors = React.useMemo(() => createTabletopColorScheme(theme, colorScheme), [colorScheme, theme]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabletopTable.js","sourceRoot":"","sources":["../../../src/components/tabletop-table/TabletopTable.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useZoraTheme } from '@ankhorage/zora';\nimport React from 'react';\nimport { StyleSheet, Text, View } from 'react-native';\n\nimport { createTabletopColorScheme } from '../../colors';\nimport { getTabletopSeatPosition } from '../../tablePositions';\nimport type { TabletopSeatState } from '../../types';\nimport { CardHand } from '../card-hand';\nimport type { TabletopTableProps } from './types';\n\nfunction createSeatAccessibilityLabel(seat: TabletopSeatState): string | undefined {\n if (seat.accessibilityLabel !== undefined) return seat.accessibilityLabel;\n if (typeof seat.label !== 'string') return undefined;\n\n const parts = [seat.label];\n if (typeof seat.sublabel === 'string') parts.push(seat.sublabel);\n if (typeof seat.tokenLabel === 'string') parts.push(seat.tokenLabel);\n if (seat.selected) parts.push('selected');\n if (seat.muted) parts.push('muted');\n\n return parts.join(', ');\n}\n\nexport function TabletopTable({\n seats,\n centerCards = [],\n centerLabel,\n centerSublabel,\n shape = 'oval',\n seatCount,\n cardSize = 'small',\n disabled = false,\n colorScheme,\n accessibilityLabel,\n testID,\n}: TabletopTableProps) {\n const { theme } = useZoraTheme();\n const colors = React.useMemo(\n () => createTabletopColorScheme(theme, colorScheme),\n [colorScheme, theme],\n );\n const resolvedSeatCount = seatCount ?? seats.length;\n\n return (\n <View\n accessibilityLabel={accessibilityLabel}\n style={[styles.root, { opacity: disabled ? 0.56 : 1 }]}\n testID={testID}\n >\n <View\n style={[\n styles.surface,\n shape === 'circle' ? styles.circleSurface : styles.ovalSurface,\n shape === 'rounded' ? styles.roundedSurface : null,\n {\n backgroundColor: colors.tableFelt,\n borderColor: colors.tableBorder,\n },\n ]}\n >\n <View\n pointerEvents=\"none\"\n style={[\n styles.innerSurface,\n shape === 'circle' ? styles.circleSurface : styles.ovalSurface,\n shape === 'rounded' ? styles.roundedSurface : null,\n { borderColor: colors.tableInnerBorder },\n ]}\n />\n <View style={styles.centerContent}>\n {centerCards.length > 0 ? (\n <CardHand cards={centerCards} colorScheme={colorScheme} size={cardSize} />\n ) : null}\n {centerLabel !== undefined ? (\n <View style={[styles.centerLabel, { backgroundColor: colors.seatSurface }]}>\n <Text style={[styles.centerLabelText, { color: colors.seatText }]}>\n {centerLabel}\n </Text>\n </View>\n ) : null}\n {centerSublabel !== undefined ? (\n <Text style={[styles.centerSublabel, { color: colors.tableMutedText }]}>\n {centerSublabel}\n </Text>\n ) : null}\n </View>\n </View>\n\n {seats.map((seat, index) => {\n const position = getTabletopSeatPosition(index, resolvedSeatCount);\n return (\n <View\n accessibilityLabel={createSeatAccessibilityLabel(seat)}\n accessibilityRole=\"summary\"\n key={seat.id}\n style={[\n styles.seat,\n {\n borderColor: seat.selected ? colors.seatSelectedBorder : colors.seatBorder,\n backgroundColor: colors.seatSurface,\n left: position.left,\n opacity: seat.muted ? 0.48 : 1,\n top: position.top,\n },\n ]}\n testID={testID ? `${testID}-seat-${seat.id}` : undefined}\n >\n {seat.cards !== undefined || seat.faceDownCards !== undefined ? (\n <CardHand\n cards={seat.cards}\n colorScheme={colorScheme}\n faceDownCards={seat.faceDownCards}\n muted={seat.muted ?? seat.disabled}\n size={cardSize}\n />\n ) : null}\n <Text style={[styles.seatLabel, { color: colors.seatText }]}>{seat.label}</Text>\n {seat.sublabel !== undefined ? (\n <Text style={[styles.seatSublabel, { color: colors.seatMutedText }]}>\n {seat.sublabel}\n </Text>\n ) : null}\n {seat.tokenLabel !== undefined ? (\n <View style={[styles.token, { backgroundColor: colors.tokenSurface }]}>\n <Text style={[styles.tokenText, { color: colors.tokenText }]}>\n {seat.tokenLabel}\n </Text>\n </View>\n ) : null}\n </View>\n );\n })}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n centerContent: {\n alignItems: 'center',\n gap: 6,\n left: 0,\n position: 'absolute',\n right: 0,\n top: '35%',\n },\n centerLabel: {\n borderRadius: 999,\n paddingHorizontal: 10,\n paddingVertical: 4,\n },\n centerLabelText: {\n fontSize: 12,\n fontWeight: '800',\n },\n centerSublabel: {\n fontSize: 11,\n fontWeight: '700',\n },\n circleSurface: {\n borderRadius: 999,\n },\n innerSurface: {\n borderWidth: 1,\n bottom: 10,\n left: 10,\n opacity: 0.44,\n position: 'absolute',\n right: 10,\n top: 10,\n },\n ovalSurface: {\n borderRadius: 999,\n },\n root: {\n aspectRatio: 1.6,\n maxWidth: 760,\n position: 'relative',\n width: '100%',\n },\n roundedSurface: {\n borderRadius: 28,\n },\n seat: {\n alignItems: 'center',\n borderRadius: 10,\n borderWidth: 1,\n gap: 3,\n minWidth: 64,\n paddingHorizontal: 6,\n paddingVertical: 5,\n position: 'absolute',\n transform: [{ translateX: -32 }, { translateY: -28 }],\n },\n seatLabel: {\n fontSize: 11,\n fontWeight: '800',\n },\n seatSublabel: {\n fontSize: 10,\n fontWeight: '700',\n },\n surface: {\n borderWidth: 8,\n bottom: 28,\n left: 24,\n position: 'absolute',\n right: 24,\n top: 24,\n },\n token: {\n borderRadius: 999,\n paddingHorizontal: 6,\n paddingVertical: 2,\n },\n tokenText: {\n fontSize: 10,\n fontWeight: '800',\n },\n});\n"]}
|
|
1
|
+
{"version":3,"file":"TabletopTable.js","sourceRoot":"","sources":["../../../src/components/tabletop-table/TabletopTable.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useZoraTheme } from '@ankhorage/zora';\nimport React from 'react';\nimport { StyleSheet, Text, View } from 'react-native';\n\nimport { createTabletopColorScheme } from '../../colors';\nimport { getTabletopSeatPosition } from '../../tablePositions';\nimport type { TabletopSeatState } from '../../types';\nimport { CardHand } from '../card-hand';\nimport type { TabletopTableProps } from './types';\n\nfunction createSeatAccessibilityLabel(seat: TabletopSeatState): string | undefined {\n if (seat.accessibilityLabel !== undefined) return seat.accessibilityLabel;\n if (typeof seat.label !== 'string') return undefined;\n\n const parts = [seat.label];\n if (typeof seat.sublabel === 'string') parts.push(seat.sublabel);\n if (typeof seat.tokenLabel === 'string') parts.push(seat.tokenLabel);\n if (seat.selected) parts.push('selected');\n if (seat.muted) parts.push('muted');\n\n return parts.join(', ');\n}\n\n/***\n * Responsive tabletop surface for generic card-game and board-game scenes.\n *\n * Use `TabletopTable` to arrange seats around a themed table surface, display\n * shared center cards, and show neutral seat labels/tokens without embedding game\n * rules into the component.\n *\n * @readme\n * @example Basic table\n * ```tsx\n * <TabletopTable\n * seats={seats}\n * centerCards={[{ rank: 'A', suit: 'spades' }]}\n * centerLabel=\"Round 1\"\n * />\n * ```\n */\nexport function TabletopTable({\n seats,\n centerCards = [],\n centerLabel,\n centerSublabel,\n shape = 'oval',\n seatCount,\n cardSize = 'small',\n disabled = false,\n colorScheme,\n accessibilityLabel,\n testID,\n}: TabletopTableProps) {\n const { theme } = useZoraTheme();\n const colors = React.useMemo(\n () => createTabletopColorScheme(theme, colorScheme),\n [colorScheme, theme],\n );\n const resolvedSeatCount = seatCount ?? seats.length;\n\n return (\n <View\n accessibilityLabel={accessibilityLabel}\n style={[styles.root, { opacity: disabled ? 0.56 : 1 }]}\n testID={testID}\n >\n <View\n style={[\n styles.surface,\n shape === 'circle' ? styles.circleSurface : styles.ovalSurface,\n shape === 'rounded' ? styles.roundedSurface : null,\n {\n backgroundColor: colors.tableFelt,\n borderColor: colors.tableBorder,\n },\n ]}\n >\n <View\n pointerEvents=\"none\"\n style={[\n styles.innerSurface,\n shape === 'circle' ? styles.circleSurface : styles.ovalSurface,\n shape === 'rounded' ? styles.roundedSurface : null,\n { borderColor: colors.tableInnerBorder },\n ]}\n />\n <View style={styles.centerContent}>\n {centerCards.length > 0 ? (\n <CardHand cards={centerCards} colorScheme={colorScheme} size={cardSize} />\n ) : null}\n {centerLabel !== undefined ? (\n <View style={[styles.centerLabel, { backgroundColor: colors.seatSurface }]}>\n <Text style={[styles.centerLabelText, { color: colors.seatText }]}>\n {centerLabel}\n </Text>\n </View>\n ) : null}\n {centerSublabel !== undefined ? (\n <Text style={[styles.centerSublabel, { color: colors.tableMutedText }]}>\n {centerSublabel}\n </Text>\n ) : null}\n </View>\n </View>\n\n {seats.map((seat, index) => {\n const position = getTabletopSeatPosition(index, resolvedSeatCount);\n return (\n <View\n accessibilityLabel={createSeatAccessibilityLabel(seat)}\n accessibilityRole=\"summary\"\n key={seat.id}\n style={[\n styles.seat,\n {\n borderColor: seat.selected ? colors.seatSelectedBorder : colors.seatBorder,\n backgroundColor: colors.seatSurface,\n left: position.left,\n opacity: seat.muted ? 0.48 : 1,\n top: position.top,\n },\n ]}\n testID={testID ? `${testID}-seat-${seat.id}` : undefined}\n >\n {seat.cards !== undefined || seat.faceDownCards !== undefined ? (\n <CardHand\n cards={seat.cards}\n colorScheme={colorScheme}\n faceDownCards={seat.faceDownCards}\n muted={seat.muted ?? seat.disabled}\n size={cardSize}\n />\n ) : null}\n <Text style={[styles.seatLabel, { color: colors.seatText }]}>{seat.label}</Text>\n {seat.sublabel !== undefined ? (\n <Text style={[styles.seatSublabel, { color: colors.seatMutedText }]}>\n {seat.sublabel}\n </Text>\n ) : null}\n {seat.tokenLabel !== undefined ? (\n <View style={[styles.token, { backgroundColor: colors.tokenSurface }]}>\n <Text style={[styles.tokenText, { color: colors.tokenText }]}>\n {seat.tokenLabel}\n </Text>\n </View>\n ) : null}\n </View>\n );\n })}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n centerContent: {\n alignItems: 'center',\n gap: 6,\n left: 0,\n position: 'absolute',\n right: 0,\n top: '35%',\n },\n centerLabel: {\n borderRadius: 999,\n paddingHorizontal: 10,\n paddingVertical: 4,\n },\n centerLabelText: {\n fontSize: 12,\n fontWeight: '800',\n },\n centerSublabel: {\n fontSize: 11,\n fontWeight: '700',\n },\n circleSurface: {\n borderRadius: 999,\n },\n innerSurface: {\n borderWidth: 1,\n bottom: 10,\n left: 10,\n opacity: 0.44,\n position: 'absolute',\n right: 10,\n top: 10,\n },\n ovalSurface: {\n borderRadius: 999,\n },\n root: {\n aspectRatio: 1.6,\n maxWidth: 760,\n position: 'relative',\n width: '100%',\n },\n roundedSurface: {\n borderRadius: 28,\n },\n seat: {\n alignItems: 'center',\n borderRadius: 10,\n borderWidth: 1,\n gap: 3,\n minWidth: 64,\n paddingHorizontal: 6,\n paddingVertical: 5,\n position: 'absolute',\n transform: [{ translateX: -32 }, { translateY: -28 }],\n },\n seatLabel: {\n fontSize: 11,\n fontWeight: '800',\n },\n seatSublabel: {\n fontSize: 10,\n fontWeight: '700',\n },\n surface: {\n borderWidth: 8,\n bottom: 28,\n left: 24,\n position: 'absolute',\n right: 24,\n top: 24,\n },\n token: {\n borderRadius: 999,\n paddingHorizontal: 6,\n paddingVertical: 2,\n },\n tokenText: {\n fontSize: 10,\n fontWeight: '800',\n },\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/zora-tabletop",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.3",
|
|
5
5
|
"description": "Tabletop and card-game UI primitives for React Native and React Native Web, built on ZORA.",
|
|
6
6
|
"homepage": "https://github.com/ankhorage/zora-tabletop#readme",
|
|
7
7
|
"bugs": {
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@ankhorage/devtools": "^1.0.6",
|
|
71
|
-
"@ankhorage/paradox": "^0.1.
|
|
71
|
+
"@ankhorage/paradox": "^0.1.10",
|
|
72
72
|
"@ankhorage/zora": "^2.5.1",
|
|
73
73
|
"@changesets/cli": "^2.31.0",
|
|
74
74
|
"@types/bun": "^1.3.13",
|
package/src/colors.ts
CHANGED
|
@@ -57,6 +57,19 @@ const DARK_TEXT_FALLBACK = '#111827';
|
|
|
57
57
|
const LIGHT_TEXT_FALLBACK = '#ffffff';
|
|
58
58
|
const MINIMUM_READABLE_CONTRAST = 4.5;
|
|
59
59
|
|
|
60
|
+
/***
|
|
61
|
+
* Creates the theme-derived color palette used by tabletop primitives.
|
|
62
|
+
*
|
|
63
|
+
* Use `createTabletopColorScheme` when custom components need to align with the
|
|
64
|
+
* same card, table, seat, token, and contrast-aware foreground colors as the
|
|
65
|
+
* built-in tabletop components.
|
|
66
|
+
*
|
|
67
|
+
* @readme
|
|
68
|
+
* @example Custom color scheme
|
|
69
|
+
* ```ts
|
|
70
|
+
* const colors = createTabletopColorScheme(theme, { tableFelt: '#065f46' });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
60
73
|
export function createTabletopColorScheme(
|
|
61
74
|
theme: TabletopColorThemeShape,
|
|
62
75
|
overrides: TabletopColorOverrides = {},
|
|
@@ -7,6 +7,18 @@ import { getTabletopCardDimensions } from '../../cardSizing';
|
|
|
7
7
|
import { createTabletopColorScheme } from '../../colors';
|
|
8
8
|
import type { CardBackProps } from './types';
|
|
9
9
|
|
|
10
|
+
/***
|
|
11
|
+
* Face-down playing-card primitive for hidden cards and decks.
|
|
12
|
+
*
|
|
13
|
+
* Use `CardBack` when a card should be represented visually without exposing its
|
|
14
|
+
* rank or suit. The component keeps a generic accessible label for hidden cards.
|
|
15
|
+
*
|
|
16
|
+
* @readme
|
|
17
|
+
* @example Hidden cards
|
|
18
|
+
* ```tsx
|
|
19
|
+
* <CardBack size="small" />
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
10
22
|
export function CardBack({
|
|
11
23
|
size = 'medium',
|
|
12
24
|
muted = false,
|
|
@@ -9,6 +9,18 @@ function createFaceDownCards(count: number): readonly number[] {
|
|
|
9
9
|
return Array.from({ length: Math.max(0, count) }, (_, index) => index);
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
/***
|
|
13
|
+
* Compact row of visible and face-down playing cards.
|
|
14
|
+
*
|
|
15
|
+
* Use `CardHand` when a seat, pile, or custom layout needs to show multiple cards
|
|
16
|
+
* with consistent spacing, sizing, and muted state handling.
|
|
17
|
+
*
|
|
18
|
+
* @readme
|
|
19
|
+
* @example Mixed hand
|
|
20
|
+
* ```tsx
|
|
21
|
+
* <CardHand cards={[{ rank: 'Q', suit: 'hearts' }]} faceDownCards={1} />
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
12
24
|
export function CardHand({
|
|
13
25
|
cards = [],
|
|
14
26
|
faceDownCards = 0,
|
|
@@ -19,6 +19,19 @@ function isRedSuit(suit: PlayingCardSuit): boolean {
|
|
|
19
19
|
return suit === 'diamonds' || suit === 'hearts';
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
/***
|
|
23
|
+
* Theme-aware face-up playing card primitive.
|
|
24
|
+
*
|
|
25
|
+
* Use `PlayingCard` for visible card values in hands, shared table cards, piles,
|
|
26
|
+
* or custom tabletop layouts. The component renders rank and suit text and exposes
|
|
27
|
+
* an accessible card label by default.
|
|
28
|
+
*
|
|
29
|
+
* @readme
|
|
30
|
+
* @example Face-up card
|
|
31
|
+
* ```tsx
|
|
32
|
+
* <PlayingCard card={{ rank: 'A', suit: 'spades' }} selected />
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
22
35
|
export function PlayingCard({
|
|
23
36
|
card,
|
|
24
37
|
size = 'medium',
|
|
@@ -21,6 +21,23 @@ function createSeatAccessibilityLabel(seat: TabletopSeatState): string | undefin
|
|
|
21
21
|
return parts.join(', ');
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
/***
|
|
25
|
+
* Responsive tabletop surface for generic card-game and board-game scenes.
|
|
26
|
+
*
|
|
27
|
+
* Use `TabletopTable` to arrange seats around a themed table surface, display
|
|
28
|
+
* shared center cards, and show neutral seat labels/tokens without embedding game
|
|
29
|
+
* rules into the component.
|
|
30
|
+
*
|
|
31
|
+
* @readme
|
|
32
|
+
* @example Basic table
|
|
33
|
+
* ```tsx
|
|
34
|
+
* <TabletopTable
|
|
35
|
+
* seats={seats}
|
|
36
|
+
* centerCards={[{ rank: 'A', suit: 'spades' }]}
|
|
37
|
+
* centerLabel="Round 1"
|
|
38
|
+
* />
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
24
41
|
export function TabletopTable({
|
|
25
42
|
seats,
|
|
26
43
|
centerCards = [],
|