@coinbase/cds-mcp-server 8.41.0 → 8.42.0
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 +4 -0
- package/mcp-docs/mobile/components/ContainedAssetCard.txt +1 -1
- package/mcp-docs/mobile/components/ContentCard.txt +220 -174
- package/mcp-docs/mobile/components/ContentCardBody.txt +127 -19
- package/mcp-docs/mobile/components/ContentCardFooter.txt +63 -1
- package/mcp-docs/mobile/components/ContentCardHeader.txt +71 -16
- package/mcp-docs/mobile/components/DataCard.txt +723 -0
- package/mcp-docs/mobile/components/FloatingAssetCard.txt +1 -1
- package/mcp-docs/mobile/components/MediaCard.txt +526 -0
- package/mcp-docs/mobile/components/MessagingCard.txt +1025 -0
- package/mcp-docs/mobile/components/Scrubber.txt +140 -0
- package/mcp-docs/mobile/routes.txt +6 -3
- package/mcp-docs/web/components/ContentCard.txt +419 -327
- package/mcp-docs/web/components/ContentCardBody.txt +91 -16
- package/mcp-docs/web/components/ContentCardFooter.txt +231 -165
- package/mcp-docs/web/components/ContentCardHeader.txt +237 -177
- package/mcp-docs/web/components/DataCard.txt +800 -0
- package/mcp-docs/web/components/MediaCard.txt +559 -0
- package/mcp-docs/web/components/MessagingCard.txt +1054 -0
- package/mcp-docs/web/components/ReferenceLine.txt +1 -0
- package/mcp-docs/web/components/Scrubber.txt +106 -0
- package/mcp-docs/web/routes.txt +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,723 @@
|
|
|
1
|
+
# DataCard
|
|
2
|
+
|
|
3
|
+
A flexible card component for displaying data with visualizations like progress bars and circles. It supports horizontal and vertical layouts with customizable thumbnails and title accessories.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { DataCard } from '@coinbase/cds-mobile/alpha/data-card'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
DataCard is a flexible card component for displaying data with visualizations. It provides a structured layout for thumbnails, titles, subtitles, and visualization content. Pass any visualization component as children, such as `ProgressBar`, `ProgressCircle`, or custom content.
|
|
14
|
+
|
|
15
|
+
:::info Migrating from Legacy DataCard?
|
|
16
|
+
See the [Migration Guide](#migration-from-legacy-datacard) at the end of this page.
|
|
17
|
+
:::
|
|
18
|
+
|
|
19
|
+
### Basic Examples
|
|
20
|
+
|
|
21
|
+
DataCard supports two layouts: `vertical` (stacked) and `horizontal` (side-by-side). Pass visualization components as children.
|
|
22
|
+
|
|
23
|
+
```jsx
|
|
24
|
+
function Example() {
|
|
25
|
+
const { spectrum } = useTheme();
|
|
26
|
+
const exampleThumbnail = (
|
|
27
|
+
<RemoteImage
|
|
28
|
+
accessibilityLabel="Ethereum"
|
|
29
|
+
shape="circle"
|
|
30
|
+
size="l"
|
|
31
|
+
source={{ uri: ethBackground }}
|
|
32
|
+
/>
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<VStack gap={2}>
|
|
37
|
+
<DataCard
|
|
38
|
+
layout="vertical"
|
|
39
|
+
subtitle="Progress indicator"
|
|
40
|
+
thumbnail={exampleThumbnail}
|
|
41
|
+
title="Progress Bar Card"
|
|
42
|
+
titleAccessory={
|
|
43
|
+
<Text dangerouslySetColor={`rgb(${spectrum.green70})`} font="label1">
|
|
44
|
+
↗ 25.25%
|
|
45
|
+
</Text>
|
|
46
|
+
}
|
|
47
|
+
>
|
|
48
|
+
<Box paddingTop={6}>
|
|
49
|
+
<ProgressBarWithFixedLabels
|
|
50
|
+
labelPlacement="below"
|
|
51
|
+
startLabel={{
|
|
52
|
+
value: 45,
|
|
53
|
+
render: (num) => (
|
|
54
|
+
<Text color="fgMuted" font="legal">
|
|
55
|
+
{num}%
|
|
56
|
+
</Text>
|
|
57
|
+
),
|
|
58
|
+
}}
|
|
59
|
+
>
|
|
60
|
+
<ProgressBar accessibilityLabel="45% complete" progress={0.45} weight="semiheavy" />
|
|
61
|
+
</ProgressBarWithFixedLabels>
|
|
62
|
+
</Box>
|
|
63
|
+
</DataCard>
|
|
64
|
+
<DataCard
|
|
65
|
+
layout="horizontal"
|
|
66
|
+
subtitle="Circular progress"
|
|
67
|
+
thumbnail={exampleThumbnail}
|
|
68
|
+
title="Progress Circle Card"
|
|
69
|
+
titleAccessory={
|
|
70
|
+
<Text color="fgNegative" font="label1">
|
|
71
|
+
↘ 3.12%
|
|
72
|
+
</Text>
|
|
73
|
+
}
|
|
74
|
+
>
|
|
75
|
+
<HStack alignItems="center" height="100%">
|
|
76
|
+
<ProgressCircle
|
|
77
|
+
accessibilityLabel="60% complete"
|
|
78
|
+
progress={0.6}
|
|
79
|
+
size={100}
|
|
80
|
+
weight="heavy"
|
|
81
|
+
/>
|
|
82
|
+
</HStack>
|
|
83
|
+
</DataCard>
|
|
84
|
+
</VStack>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Layout Variations
|
|
90
|
+
|
|
91
|
+
Use `layout="vertical"` for stacked layouts (thumbnail on left, visualization below) or `layout="horizontal"` for side-by-side layouts (header on left, visualization on right).
|
|
92
|
+
|
|
93
|
+
```jsx
|
|
94
|
+
function Example() {
|
|
95
|
+
const exampleThumbnail = (
|
|
96
|
+
<RemoteImage
|
|
97
|
+
accessibilityLabel="Ethereum"
|
|
98
|
+
shape="circle"
|
|
99
|
+
size="l"
|
|
100
|
+
source={{ uri: ethBackground }}
|
|
101
|
+
/>
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<VStack gap={2}>
|
|
106
|
+
<DataCard
|
|
107
|
+
layout="vertical"
|
|
108
|
+
subtitle="Vertical layout stacks content"
|
|
109
|
+
thumbnail={exampleThumbnail}
|
|
110
|
+
title="Vertical Layout"
|
|
111
|
+
>
|
|
112
|
+
<Box paddingTop={6}>
|
|
113
|
+
<ProgressBarWithFixedLabels
|
|
114
|
+
labelPlacement="below"
|
|
115
|
+
startLabel={{
|
|
116
|
+
value: 75,
|
|
117
|
+
render: (num) => (
|
|
118
|
+
<Text color="fgMuted" font="legal">
|
|
119
|
+
{num}%
|
|
120
|
+
</Text>
|
|
121
|
+
),
|
|
122
|
+
}}
|
|
123
|
+
>
|
|
124
|
+
<ProgressBar accessibilityLabel="75% complete" progress={0.75} weight="semiheavy" />
|
|
125
|
+
</ProgressBarWithFixedLabels>
|
|
126
|
+
</Box>
|
|
127
|
+
</DataCard>
|
|
128
|
+
<DataCard
|
|
129
|
+
layout="horizontal"
|
|
130
|
+
subtitle="Horizontal layout places content side by side"
|
|
131
|
+
thumbnail={exampleThumbnail}
|
|
132
|
+
title="Horizontal Layout"
|
|
133
|
+
>
|
|
134
|
+
<HStack alignItems="center" height="100%">
|
|
135
|
+
<ProgressCircle
|
|
136
|
+
accessibilityLabel="75% complete"
|
|
137
|
+
progress={0.75}
|
|
138
|
+
size={100}
|
|
139
|
+
weight="heavy"
|
|
140
|
+
/>
|
|
141
|
+
</HStack>
|
|
142
|
+
</DataCard>
|
|
143
|
+
</VStack>
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Title Accessory
|
|
149
|
+
|
|
150
|
+
Use `titleAccessory` to display supplementary information inline with the title, such as trends, percentages, or status indicators.
|
|
151
|
+
|
|
152
|
+
```jsx
|
|
153
|
+
function Example() {
|
|
154
|
+
const { spectrum } = useTheme();
|
|
155
|
+
const exampleThumbnail = (
|
|
156
|
+
<RemoteImage
|
|
157
|
+
accessibilityLabel="Ethereum"
|
|
158
|
+
shape="circle"
|
|
159
|
+
size="l"
|
|
160
|
+
source={{ uri: ethBackground }}
|
|
161
|
+
/>
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
return (
|
|
165
|
+
<VStack gap={2}>
|
|
166
|
+
<DataCard
|
|
167
|
+
layout="vertical"
|
|
168
|
+
subtitle="With positive trend"
|
|
169
|
+
thumbnail={exampleThumbnail}
|
|
170
|
+
title="Positive Trend"
|
|
171
|
+
titleAccessory={
|
|
172
|
+
<Text dangerouslySetColor={`rgb(${spectrum.green70})`} font="label1">
|
|
173
|
+
↗ 8.5%
|
|
174
|
+
</Text>
|
|
175
|
+
}
|
|
176
|
+
>
|
|
177
|
+
<Box paddingTop={6}>
|
|
178
|
+
<ProgressBarWithFixedLabels
|
|
179
|
+
labelPlacement="below"
|
|
180
|
+
startLabel={{
|
|
181
|
+
value: 90,
|
|
182
|
+
render: (num) => (
|
|
183
|
+
<Text color="fgMuted" font="legal">
|
|
184
|
+
{num}%
|
|
185
|
+
</Text>
|
|
186
|
+
),
|
|
187
|
+
}}
|
|
188
|
+
>
|
|
189
|
+
<ProgressBar accessibilityLabel="90% complete" progress={0.9} weight="semiheavy" />
|
|
190
|
+
</ProgressBarWithFixedLabels>
|
|
191
|
+
</Box>
|
|
192
|
+
</DataCard>
|
|
193
|
+
<DataCard
|
|
194
|
+
layout="horizontal"
|
|
195
|
+
subtitle="With negative trend"
|
|
196
|
+
thumbnail={exampleThumbnail}
|
|
197
|
+
title="Negative Trend"
|
|
198
|
+
titleAccessory={
|
|
199
|
+
<Text color="fgNegative" font="label1">
|
|
200
|
+
↘ 4.2%
|
|
201
|
+
</Text>
|
|
202
|
+
}
|
|
203
|
+
>
|
|
204
|
+
<HStack alignItems="center" height="100%">
|
|
205
|
+
<ProgressCircle
|
|
206
|
+
accessibilityLabel="70% complete"
|
|
207
|
+
progress={0.7}
|
|
208
|
+
size={100}
|
|
209
|
+
weight="heavy"
|
|
210
|
+
/>
|
|
211
|
+
</HStack>
|
|
212
|
+
</DataCard>
|
|
213
|
+
</VStack>
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Interactive Cards
|
|
219
|
+
|
|
220
|
+
Use `renderAsPressable` to make the card interactive with `onPress` handler.
|
|
221
|
+
|
|
222
|
+
```jsx
|
|
223
|
+
function Example() {
|
|
224
|
+
const { spectrum } = useTheme();
|
|
225
|
+
const exampleThumbnail = (
|
|
226
|
+
<RemoteImage
|
|
227
|
+
accessibilityLabel="Ethereum"
|
|
228
|
+
shape="circle"
|
|
229
|
+
size="l"
|
|
230
|
+
source={{ uri: ethBackground }}
|
|
231
|
+
/>
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
return (
|
|
235
|
+
<VStack gap={2}>
|
|
236
|
+
<DataCard
|
|
237
|
+
renderAsPressable
|
|
238
|
+
accessibilityLabel="View progress details"
|
|
239
|
+
layout="vertical"
|
|
240
|
+
onPress={() => Alert.alert('Progress bar card pressed!')}
|
|
241
|
+
subtitle="Clickable progress card"
|
|
242
|
+
thumbnail={exampleThumbnail}
|
|
243
|
+
title="Tap to View Details"
|
|
244
|
+
titleAccessory={
|
|
245
|
+
<Text dangerouslySetColor={`rgb(${spectrum.green70})`} font="label1">
|
|
246
|
+
↗ 8.5%
|
|
247
|
+
</Text>
|
|
248
|
+
}
|
|
249
|
+
>
|
|
250
|
+
<Box paddingTop={6}>
|
|
251
|
+
<ProgressBarWithFixedLabels
|
|
252
|
+
labelPlacement="below"
|
|
253
|
+
startLabel={{
|
|
254
|
+
value: 75,
|
|
255
|
+
render: (num) => (
|
|
256
|
+
<Text color="fgMuted" font="legal">
|
|
257
|
+
{num}%
|
|
258
|
+
</Text>
|
|
259
|
+
),
|
|
260
|
+
}}
|
|
261
|
+
>
|
|
262
|
+
<ProgressBar accessibilityLabel="75% complete" progress={0.75} weight="semiheavy" />
|
|
263
|
+
</ProgressBarWithFixedLabels>
|
|
264
|
+
</Box>
|
|
265
|
+
</DataCard>
|
|
266
|
+
<DataCard
|
|
267
|
+
renderAsPressable
|
|
268
|
+
accessibilityLabel="View circle progress details"
|
|
269
|
+
layout="horizontal"
|
|
270
|
+
onPress={() => Alert.alert('Circle card pressed!')}
|
|
271
|
+
subtitle="Tap for more info"
|
|
272
|
+
thumbnail={exampleThumbnail}
|
|
273
|
+
title="Interactive Circle"
|
|
274
|
+
titleAccessory={
|
|
275
|
+
<Text color="fgMuted" font="label1">
|
|
276
|
+
Details
|
|
277
|
+
</Text>
|
|
278
|
+
}
|
|
279
|
+
>
|
|
280
|
+
<HStack alignItems="center" height="100%">
|
|
281
|
+
<ProgressCircle
|
|
282
|
+
accessibilityLabel="85% complete"
|
|
283
|
+
progress={0.85}
|
|
284
|
+
size={100}
|
|
285
|
+
weight="heavy"
|
|
286
|
+
/>
|
|
287
|
+
</HStack>
|
|
288
|
+
</DataCard>
|
|
289
|
+
</VStack>
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Style Customization
|
|
295
|
+
|
|
296
|
+
Use `styles` prop to customize specific parts of the card layout.
|
|
297
|
+
|
|
298
|
+
```jsx
|
|
299
|
+
function Example() {
|
|
300
|
+
const exampleThumbnail = (
|
|
301
|
+
<RemoteImage
|
|
302
|
+
accessibilityLabel="Ethereum"
|
|
303
|
+
shape="circle"
|
|
304
|
+
size="l"
|
|
305
|
+
source={{ uri: ethBackground }}
|
|
306
|
+
/>
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
return (
|
|
310
|
+
<VStack gap={2}>
|
|
311
|
+
<DataCard
|
|
312
|
+
layout="vertical"
|
|
313
|
+
styles={{
|
|
314
|
+
root: { borderWidth: 2, borderColor: '#0066FF' },
|
|
315
|
+
}}
|
|
316
|
+
subtitle="Custom border"
|
|
317
|
+
thumbnail={exampleThumbnail}
|
|
318
|
+
title="Custom Root Styles"
|
|
319
|
+
>
|
|
320
|
+
<Box paddingTop={6}>
|
|
321
|
+
<ProgressBarWithFixedLabels
|
|
322
|
+
labelPlacement="below"
|
|
323
|
+
startLabel={{
|
|
324
|
+
value: 50,
|
|
325
|
+
render: (num) => (
|
|
326
|
+
<Text color="fgMuted" font="legal">
|
|
327
|
+
{num}%
|
|
328
|
+
</Text>
|
|
329
|
+
),
|
|
330
|
+
}}
|
|
331
|
+
>
|
|
332
|
+
<ProgressBar accessibilityLabel="50% complete" progress={0.5} weight="semiheavy" />
|
|
333
|
+
</ProgressBarWithFixedLabels>
|
|
334
|
+
</Box>
|
|
335
|
+
</DataCard>
|
|
336
|
+
<DataCard
|
|
337
|
+
layout="horizontal"
|
|
338
|
+
styles={{
|
|
339
|
+
root: { backgroundColor: '#F5F5F5' },
|
|
340
|
+
headerContainer: { paddingLeft: 16 },
|
|
341
|
+
}}
|
|
342
|
+
subtitle="Custom background and padding"
|
|
343
|
+
thumbnail={exampleThumbnail}
|
|
344
|
+
title="Custom Layout Styles"
|
|
345
|
+
>
|
|
346
|
+
<HStack alignItems="center" height="100%">
|
|
347
|
+
<ProgressCircle
|
|
348
|
+
accessibilityLabel="70% complete"
|
|
349
|
+
progress={0.7}
|
|
350
|
+
size={100}
|
|
351
|
+
weight="heavy"
|
|
352
|
+
/>
|
|
353
|
+
</HStack>
|
|
354
|
+
</DataCard>
|
|
355
|
+
</VStack>
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Multiple Cards
|
|
361
|
+
|
|
362
|
+
DataCards work well in lists or dashboards to display multiple data points.
|
|
363
|
+
|
|
364
|
+
```jsx
|
|
365
|
+
function Example() {
|
|
366
|
+
const { spectrum } = useTheme();
|
|
367
|
+
const exampleThumbnail = (
|
|
368
|
+
<RemoteImage
|
|
369
|
+
accessibilityLabel="Ethereum"
|
|
370
|
+
shape="circle"
|
|
371
|
+
size="l"
|
|
372
|
+
source={{ uri: ethBackground }}
|
|
373
|
+
/>
|
|
374
|
+
);
|
|
375
|
+
|
|
376
|
+
return (
|
|
377
|
+
<VStack gap={2}>
|
|
378
|
+
<DataCard
|
|
379
|
+
layout="vertical"
|
|
380
|
+
subtitle="Daily goal progress"
|
|
381
|
+
thumbnail={exampleThumbnail}
|
|
382
|
+
title="Steps Today"
|
|
383
|
+
titleAccessory={
|
|
384
|
+
<Text dangerouslySetColor={`rgb(${spectrum.green70})`} font="label1">
|
|
385
|
+
6,500 / 10,000
|
|
386
|
+
</Text>
|
|
387
|
+
}
|
|
388
|
+
>
|
|
389
|
+
<Box paddingTop={6}>
|
|
390
|
+
<ProgressBarWithFixedLabels
|
|
391
|
+
labelPlacement="below"
|
|
392
|
+
startLabel={{
|
|
393
|
+
value: 65,
|
|
394
|
+
render: (num) => (
|
|
395
|
+
<Text color="fgMuted" font="legal">
|
|
396
|
+
{num}%
|
|
397
|
+
</Text>
|
|
398
|
+
),
|
|
399
|
+
}}
|
|
400
|
+
>
|
|
401
|
+
<ProgressBar accessibilityLabel="65% complete" progress={0.65} weight="semiheavy" />
|
|
402
|
+
</ProgressBarWithFixedLabels>
|
|
403
|
+
</Box>
|
|
404
|
+
</DataCard>
|
|
405
|
+
<DataCard
|
|
406
|
+
layout="horizontal"
|
|
407
|
+
subtitle="Below target this week"
|
|
408
|
+
thumbnail={exampleThumbnail}
|
|
409
|
+
title="Workout Goal"
|
|
410
|
+
titleAccessory={
|
|
411
|
+
<Text color="fgNegative" font="label1">
|
|
412
|
+
2 / 7 days
|
|
413
|
+
</Text>
|
|
414
|
+
}
|
|
415
|
+
>
|
|
416
|
+
<HStack alignItems="center" height="100%">
|
|
417
|
+
<ProgressCircle
|
|
418
|
+
accessibilityLabel="29% complete"
|
|
419
|
+
progress={0.29}
|
|
420
|
+
size={100}
|
|
421
|
+
weight="heavy"
|
|
422
|
+
/>
|
|
423
|
+
</HStack>
|
|
424
|
+
</DataCard>
|
|
425
|
+
</VStack>
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Accessibility
|
|
431
|
+
|
|
432
|
+
Ensure all visualization components have appropriate `accessibilityLabel` props to convey the progress information to screen readers.
|
|
433
|
+
|
|
434
|
+
#### Interactive Cards
|
|
435
|
+
|
|
436
|
+
When making DataCard interactive with `renderAsPressable`:
|
|
437
|
+
|
|
438
|
+
- Add an `accessibilityLabel` to summarize the card's content for VoiceOver users, ensuring all visual text of the card is included in the label (e.g., `accessibilityLabel="ETH Holdings, 45% progress, View details"`)
|
|
439
|
+
|
|
440
|
+
```jsx
|
|
441
|
+
<DataCard
|
|
442
|
+
renderAsPressable
|
|
443
|
+
accessibilityLabel="ETH Holdings, 45% progress, View details"
|
|
444
|
+
onPress={() => handlePress()}
|
|
445
|
+
title="ETH Holdings"
|
|
446
|
+
subtitle="45% progress"
|
|
447
|
+
>
|
|
448
|
+
<Box paddingTop={6}>
|
|
449
|
+
<ProgressBarWithFixedLabels
|
|
450
|
+
labelPlacement="below"
|
|
451
|
+
startLabel={{
|
|
452
|
+
value: 45,
|
|
453
|
+
render: (num) => (
|
|
454
|
+
<Text color="fgMuted" font="legal">
|
|
455
|
+
{num}%
|
|
456
|
+
</Text>
|
|
457
|
+
),
|
|
458
|
+
}}
|
|
459
|
+
>
|
|
460
|
+
<ProgressBar accessibilityLabel="45% complete" progress={0.45} weight="semiheavy" />
|
|
461
|
+
</ProgressBarWithFixedLabels>
|
|
462
|
+
</Box>
|
|
463
|
+
</DataCard>
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
:::warning Avoid Nested Interactive Elements
|
|
467
|
+
Don't place buttons or pressables inside an interactive card, as this creates accessibility issues for VoiceOver users and can cause unexpected behavior when tapping.
|
|
468
|
+
:::
|
|
469
|
+
|
|
470
|
+
#### Color Contrast for Gain/Loss Text
|
|
471
|
+
|
|
472
|
+
When displaying gain or loss percentages in DataCard, be aware of color contrast differences between light and dark modes.
|
|
473
|
+
|
|
474
|
+
**Why this matters:** DataCard uses `bgAlternate` as its background color. In **light mode**, the semantic `fgPositive` token does not meet WCAG AA contrast requirements:
|
|
475
|
+
|
|
476
|
+
| Mode | Color | Background | Contrast Ratio | WCAG AA (4.5:1) |
|
|
477
|
+
| ----- | ------------------------ | ------------------------ | -------------- | --------------- |
|
|
478
|
+
| Light | `fgPositive` (`green60`) | `bgAlternate` (`gray10`) | ~3.6:1 | ❌ Fails |
|
|
479
|
+
| Light | `green70` | `bgAlternate` (`gray10`) | ~4.8:1 | ✅ Passes |
|
|
480
|
+
| Dark | `fgPositive` (`green60`) | `bgAlternate` (`gray5`) | ~6.2:1 | ✅ Passes |
|
|
481
|
+
|
|
482
|
+
**Recommendation:**
|
|
483
|
+
|
|
484
|
+
- **Light mode**: Use `green70` for positive values instead of `fgPositive`
|
|
485
|
+
- **Dark mode**: `fgPositive` meets WCAG AA requirements and can be used as-is
|
|
486
|
+
- **Both modes**: `fgNegative` meets WCAG AA requirements
|
|
487
|
+
|
|
488
|
+
**On mobile**, access the theme spectrum via `useTheme()` hook for light mode compatibility:
|
|
489
|
+
|
|
490
|
+
```jsx
|
|
491
|
+
const { spectrum } = useTheme();
|
|
492
|
+
|
|
493
|
+
{
|
|
494
|
+
/* Gain text */
|
|
495
|
+
}
|
|
496
|
+
<Text dangerouslySetColor={`rgb(${spectrum.green70})`} font="label1">
|
|
497
|
+
↗ 12.5%
|
|
498
|
+
</Text>;
|
|
499
|
+
|
|
500
|
+
{
|
|
501
|
+
/* Loss text */
|
|
502
|
+
}
|
|
503
|
+
<Text color="fgNegative" font="label1">
|
|
504
|
+
↘ 3.2%
|
|
505
|
+
</Text>;
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
```jsx
|
|
509
|
+
function Example() {
|
|
510
|
+
const { spectrum } = useTheme();
|
|
511
|
+
const exampleThumbnail = (
|
|
512
|
+
<RemoteImage
|
|
513
|
+
accessibilityLabel="Ethereum logo"
|
|
514
|
+
shape="circle"
|
|
515
|
+
size="l"
|
|
516
|
+
source={{ uri: ethBackground }}
|
|
517
|
+
/>
|
|
518
|
+
);
|
|
519
|
+
|
|
520
|
+
return (
|
|
521
|
+
<VStack gap={2}>
|
|
522
|
+
<DataCard
|
|
523
|
+
layout="vertical"
|
|
524
|
+
subtitle="Portfolio allocation"
|
|
525
|
+
thumbnail={exampleThumbnail}
|
|
526
|
+
title="ETH Holdings"
|
|
527
|
+
titleAccessory={
|
|
528
|
+
<Text dangerouslySetColor={`rgb(${spectrum.green70})`} font="label1">
|
|
529
|
+
↗ 12.5%
|
|
530
|
+
</Text>
|
|
531
|
+
}
|
|
532
|
+
>
|
|
533
|
+
<Box paddingTop={6}>
|
|
534
|
+
<ProgressBarWithFixedLabels
|
|
535
|
+
labelPlacement="below"
|
|
536
|
+
startLabel={{
|
|
537
|
+
value: 80,
|
|
538
|
+
render: (num) => (
|
|
539
|
+
<Text color="fgMuted" font="legal">
|
|
540
|
+
{num}%
|
|
541
|
+
</Text>
|
|
542
|
+
),
|
|
543
|
+
}}
|
|
544
|
+
>
|
|
545
|
+
<ProgressBar
|
|
546
|
+
accessibilityLabel="ETH holdings at 80% of target, currently $4,000 of $5,000 goal"
|
|
547
|
+
progress={0.8}
|
|
548
|
+
weight="semiheavy"
|
|
549
|
+
/>
|
|
550
|
+
</ProgressBarWithFixedLabels>
|
|
551
|
+
</Box>
|
|
552
|
+
</DataCard>
|
|
553
|
+
</VStack>
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
### Migration from Legacy DataCard
|
|
559
|
+
|
|
560
|
+
The new `DataCard` from `@coinbase/cds-mobile/alpha/data-card` replaces the legacy `DataCard`. The new version provides more flexibility with custom layouts and visualization components.
|
|
561
|
+
|
|
562
|
+
**Before:**
|
|
563
|
+
|
|
564
|
+
```jsx
|
|
565
|
+
import { DataCard } from '@coinbase/cds-mobile/cards/DataCard';
|
|
566
|
+
|
|
567
|
+
<DataCard
|
|
568
|
+
title="Progress"
|
|
569
|
+
description="45% complete"
|
|
570
|
+
progress={0.45}
|
|
571
|
+
progressVariant="bar"
|
|
572
|
+
startLabel={45}
|
|
573
|
+
/>;
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
**After:**
|
|
577
|
+
|
|
578
|
+
```jsx
|
|
579
|
+
import { DataCard } from '@coinbase/cds-mobile/alpha/data-card';
|
|
580
|
+
|
|
581
|
+
<DataCard
|
|
582
|
+
title="Progress"
|
|
583
|
+
subtitle="45% complete"
|
|
584
|
+
layout="vertical"
|
|
585
|
+
thumbnail={<RemoteImage source={{ uri: assetUrl }} shape="circle" size="l" />}
|
|
586
|
+
>
|
|
587
|
+
<ProgressBarWithFixedLabels
|
|
588
|
+
startLabel={{
|
|
589
|
+
value: 45,
|
|
590
|
+
render: (num) => (
|
|
591
|
+
<Text color="fgMuted" font="legal">
|
|
592
|
+
{num}%
|
|
593
|
+
</Text>
|
|
594
|
+
),
|
|
595
|
+
}}
|
|
596
|
+
labelPlacement="below"
|
|
597
|
+
>
|
|
598
|
+
<ProgressBar accessibilityLabel="45% complete" progress={0.45} weight="semiheavy" />
|
|
599
|
+
</ProgressBarWithFixedLabels>
|
|
600
|
+
</DataCard>;
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
## Props
|
|
604
|
+
|
|
605
|
+
| Prop | Type | Required | Default | Description |
|
|
606
|
+
| --- | --- | --- | --- | --- |
|
|
607
|
+
| `layout` | `horizontal \| vertical` | Yes | `'vertical'` | Layout orientation of the card. Horizontal places header and visualization side by side, vertical stacks them. |
|
|
608
|
+
| `title` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | Yes | `-` | Text or React node to display as the card title. Use a Text component to override default color and font. |
|
|
609
|
+
| `alignContent` | `flex-start \| flex-end \| center \| stretch \| space-between \| space-around \| space-evenly` | No | `-` | - |
|
|
610
|
+
| `alignItems` | `flex-start \| flex-end \| center \| stretch \| baseline` | No | `-` | - |
|
|
611
|
+
| `alignSelf` | `auto \| FlexAlignType` | No | `-` | - |
|
|
612
|
+
| `aspectRatio` | `string \| number` | No | `-` | - |
|
|
613
|
+
| `background` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent` | No | `-` | Background color of the overlay (element being interacted with). |
|
|
614
|
+
| `blendStyles` | `InteractableBlendStyles` | No | `-` | - |
|
|
615
|
+
| `block` | `boolean` | No | `-` | Set element to block and expand to 100% width. |
|
|
616
|
+
| `borderBottomLeftRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - |
|
|
617
|
+
| `borderBottomRightRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - |
|
|
618
|
+
| `borderBottomWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - |
|
|
619
|
+
| `borderColor` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent` | No | `-` | - |
|
|
620
|
+
| `borderEndWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - |
|
|
621
|
+
| `borderRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - |
|
|
622
|
+
| `borderStartWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - |
|
|
623
|
+
| `borderTopLeftRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - |
|
|
624
|
+
| `borderTopRightRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - |
|
|
625
|
+
| `borderTopWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - |
|
|
626
|
+
| `borderWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - |
|
|
627
|
+
| `bordered` | `boolean` | No | `-` | Add a border around all sides of the box. |
|
|
628
|
+
| `borderedBottom` | `boolean` | No | `-` | Add a border to the bottom side of the box. |
|
|
629
|
+
| `borderedEnd` | `boolean` | No | `-` | Add a border to the trailing side of the box. |
|
|
630
|
+
| `borderedHorizontal` | `boolean` | No | `-` | Add a border to the leading and trailing sides of the box. |
|
|
631
|
+
| `borderedStart` | `boolean` | No | `-` | Add a border to the leading side of the box. |
|
|
632
|
+
| `borderedTop` | `boolean` | No | `-` | Add a border to the top side of the box. |
|
|
633
|
+
| `borderedVertical` | `boolean` | No | `-` | Add a border to the top and bottom sides of the box. |
|
|
634
|
+
| `bottom` | `string \| number` | No | `-` | - |
|
|
635
|
+
| `children` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Child node to display as the visualization (e.g., ProgressBar or ProgressCircle). |
|
|
636
|
+
| `color` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent` | No | `-` | - |
|
|
637
|
+
| `columnGap` | `0 \| 1 \| 2 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10` | No | `-` | - |
|
|
638
|
+
| `contentStyle` | `null \| false \| ViewStyle \| RegisteredStyle<ViewStyle> \| RecursiveArray<ViewStyle \| Falsy \| RegisteredStyle<ViewStyle>>` | No | `-` | Apply animated styles to the inner container. |
|
|
639
|
+
| `dangerouslySetBackground` | `string` | No | `-` | - |
|
|
640
|
+
| `debounceTime` | `number` | No | `500` | The amount of time to wait (in milliseconds) before invoking the debounced function. This prop is used in conjunction with the disableDebounce prop. The debounce function is configured to be invoked as soon as its called, but subsequent calls within the debounceTime period will be ignored. |
|
|
641
|
+
| `disableDebounce` | `boolean` | No | `-` | React Native is historically trash at debouncing touch events. This can cause a lot of unwanted behavior such as double navigations where we push a screen onto the stack 2 times. Debouncing the event 500 miliseconds, but taking the leading event prevents this effect and the accidental double-tap. |
|
|
642
|
+
| `disabled` | `boolean` | No | `-` | Is the element currently disabled. Whether the press behavior is disabled. |
|
|
643
|
+
| `display` | `flex \| none` | No | `-` | - |
|
|
644
|
+
| `elevation` | `0 \| 1 \| 2` | No | `-` | Determines box shadow styles. Parent should have overflow set to visible to ensure styles are not clipped. Is the element elevated. |
|
|
645
|
+
| `feedback` | `none \| light \| normal \| heavy` | No | `none` | Haptic feedback to trigger when being pressed. |
|
|
646
|
+
| `flexBasis` | `string \| number` | No | `-` | - |
|
|
647
|
+
| `flexDirection` | `row \| column \| row-reverse \| column-reverse` | No | `-` | - |
|
|
648
|
+
| `flexGrow` | `number` | No | `-` | - |
|
|
649
|
+
| `flexShrink` | `number` | No | `-` | - |
|
|
650
|
+
| `flexWrap` | `wrap \| nowrap \| wrap-reverse` | No | `-` | - |
|
|
651
|
+
| `font` | `inherit \| FontFamily` | No | `-` | - |
|
|
652
|
+
| `fontFamily` | `inherit \| FontFamily` | No | `-` | - |
|
|
653
|
+
| `fontSize` | `inherit \| FontSize` | No | `-` | - |
|
|
654
|
+
| `fontWeight` | `inherit \| FontWeight` | No | `-` | - |
|
|
655
|
+
| `gap` | `0 \| 1 \| 2 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10` | No | `-` | - |
|
|
656
|
+
| `height` | `string \| number` | No | `-` | - |
|
|
657
|
+
| `justifyContent` | `flex-start \| flex-end \| center \| space-between \| space-around \| space-evenly` | No | `-` | - |
|
|
658
|
+
| `key` | `Key \| null` | No | `-` | - |
|
|
659
|
+
| `left` | `string \| number` | No | `-` | - |
|
|
660
|
+
| `lineHeight` | `inherit \| LineHeight` | No | `-` | - |
|
|
661
|
+
| `loading` | `boolean` | No | `-` | Is the element currenty loading. When set to true, will disable element from press and keyboard events Is the element currenty loading. |
|
|
662
|
+
| `margin` | `0 \| -1 \| -2 \| -0.25 \| -0.5 \| -0.75 \| -1.5 \| -3 \| -4 \| -5 \| -6 \| -7 \| -8 \| -9 \| -10` | No | `-` | - |
|
|
663
|
+
| `marginBottom` | `0 \| -1 \| -2 \| -0.25 \| -0.5 \| -0.75 \| -1.5 \| -3 \| -4 \| -5 \| -6 \| -7 \| -8 \| -9 \| -10` | No | `-` | - |
|
|
664
|
+
| `marginEnd` | `0 \| -1 \| -2 \| -0.25 \| -0.5 \| -0.75 \| -1.5 \| -3 \| -4 \| -5 \| -6 \| -7 \| -8 \| -9 \| -10` | No | `-` | - |
|
|
665
|
+
| `marginStart` | `0 \| -1 \| -2 \| -0.25 \| -0.5 \| -0.75 \| -1.5 \| -3 \| -4 \| -5 \| -6 \| -7 \| -8 \| -9 \| -10` | No | `-` | - |
|
|
666
|
+
| `marginTop` | `0 \| -1 \| -2 \| -0.25 \| -0.5 \| -0.75 \| -1.5 \| -3 \| -4 \| -5 \| -6 \| -7 \| -8 \| -9 \| -10` | No | `-` | - |
|
|
667
|
+
| `marginX` | `0 \| -1 \| -2 \| -0.25 \| -0.5 \| -0.75 \| -1.5 \| -3 \| -4 \| -5 \| -6 \| -7 \| -8 \| -9 \| -10` | No | `-` | - |
|
|
668
|
+
| `marginY` | `0 \| -1 \| -2 \| -0.25 \| -0.5 \| -0.75 \| -1.5 \| -3 \| -4 \| -5 \| -6 \| -7 \| -8 \| -9 \| -10` | No | `-` | - |
|
|
669
|
+
| `maxHeight` | `string \| number` | No | `-` | - |
|
|
670
|
+
| `maxWidth` | `string \| number` | No | `-` | - |
|
|
671
|
+
| `minHeight` | `string \| number` | No | `-` | - |
|
|
672
|
+
| `minWidth` | `string \| number` | No | `-` | - |
|
|
673
|
+
| `noScaleOnPress` | `boolean` | No | `-` | Dont scale element on press. |
|
|
674
|
+
| `onPointerCancel` | `((event: PointerEvent) => void)` | No | `-` | - |
|
|
675
|
+
| `onPointerCancelCapture` | `((event: PointerEvent) => void)` | No | `-` | - |
|
|
676
|
+
| `onPointerDown` | `((event: PointerEvent) => void)` | No | `-` | - |
|
|
677
|
+
| `onPointerDownCapture` | `((event: PointerEvent) => void)` | No | `-` | - |
|
|
678
|
+
| `onPointerEnter` | `((event: PointerEvent) => void)` | No | `-` | - |
|
|
679
|
+
| `onPointerEnterCapture` | `((event: PointerEvent) => void)` | No | `-` | - |
|
|
680
|
+
| `onPointerLeave` | `((event: PointerEvent) => void)` | No | `-` | - |
|
|
681
|
+
| `onPointerLeaveCapture` | `((event: PointerEvent) => void)` | No | `-` | - |
|
|
682
|
+
| `onPointerMove` | `((event: PointerEvent) => void)` | No | `-` | - |
|
|
683
|
+
| `onPointerMoveCapture` | `((event: PointerEvent) => void)` | No | `-` | - |
|
|
684
|
+
| `onPointerUp` | `((event: PointerEvent) => void)` | No | `-` | - |
|
|
685
|
+
| `onPointerUpCapture` | `((event: PointerEvent) => void)` | No | `-` | - |
|
|
686
|
+
| `onPress` | `((event: GestureResponderEvent) => void) \| null` | No | `-` | Called when a single tap gesture is detected. |
|
|
687
|
+
| `onPressIn` | `(((event: GestureResponderEvent) => void) & ((event: GestureResponderEvent) => void))` | No | `-` | Callback fired before onPress when button is pressed. Called when a touch is engaged before onPress. |
|
|
688
|
+
| `onPressOut` | `(((event: GestureResponderEvent) => void) & ((event: GestureResponderEvent) => void))` | No | `-` | Callback fired before onPress when button is released. Called when a touch is released before onPress. |
|
|
689
|
+
| `opacity` | `number \| AnimatedNode` | No | `-` | - |
|
|
690
|
+
| `overflow` | `visible \| hidden \| scroll` | No | `-` | - |
|
|
691
|
+
| `padding` | `0 \| 1 \| 2 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10` | No | `-` | - |
|
|
692
|
+
| `paddingBottom` | `0 \| 1 \| 2 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10` | No | `-` | - |
|
|
693
|
+
| `paddingEnd` | `0 \| 1 \| 2 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10` | No | `-` | - |
|
|
694
|
+
| `paddingStart` | `0 \| 1 \| 2 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10` | No | `-` | - |
|
|
695
|
+
| `paddingTop` | `0 \| 1 \| 2 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10` | No | `-` | - |
|
|
696
|
+
| `paddingX` | `0 \| 1 \| 2 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10` | No | `-` | - |
|
|
697
|
+
| `paddingY` | `0 \| 1 \| 2 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10` | No | `-` | - |
|
|
698
|
+
| `pin` | `top \| bottom \| left \| right \| all` | No | `-` | Direction in which to absolutely pin the box. |
|
|
699
|
+
| `position` | `static \| relative \| fixed \| absolute \| sticky` | No | `-` | - |
|
|
700
|
+
| `ref` | `((instance: View \| null) => void) \| RefObject<View> \| null` | No | `-` | - |
|
|
701
|
+
| `renderAsPressable` | `boolean` | No | `false` | If true, the CardRoot will be rendered as a Pressable component. When false, renders as an HStack for layout purposes. |
|
|
702
|
+
| `right` | `string \| number` | No | `-` | - |
|
|
703
|
+
| `rowGap` | `0 \| 1 \| 2 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10` | No | `-` | - |
|
|
704
|
+
| `style` | `null \| false \| ViewStyle \| RegisteredStyle<ViewStyle> \| RecursiveArray<ViewStyle \| Falsy \| RegisteredStyle<ViewStyle>>` | No | `-` | - |
|
|
705
|
+
| `styles` | `({ layoutContainer?: StyleProp<ViewStyle>; headerContainer?: StyleProp<ViewStyle>; textContainer?: StyleProp<ViewStyle>; titleContainer?: StyleProp<ViewStyle>; } & { root?: StyleProp<ViewStyle>; })` | No | `-` | - |
|
|
706
|
+
| `subtitle` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | Text or React node to display as the card subtitle. Use a Text component to override default color and font. |
|
|
707
|
+
| `testID` | `string` | No | `-` | Used to locate this element in unit and end-to-end tests. Used to locate this view in end-to-end tests. |
|
|
708
|
+
| `textAlign` | `left \| right \| auto \| center \| justify` | No | `-` | - |
|
|
709
|
+
| `textDecorationLine` | `none \| underline \| line-through \| underline line-through` | No | `-` | - |
|
|
710
|
+
| `textDecorationStyle` | `solid \| dotted \| dashed \| double` | No | `-` | - |
|
|
711
|
+
| `textTransform` | `none \| capitalize \| uppercase \| lowercase` | No | `-` | - |
|
|
712
|
+
| `thumbnail` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | React node to display as a thumbnail in the header area. |
|
|
713
|
+
| `titleAccessory` | `null \| string \| number \| false \| true \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal` | No | `-` | React node to display as a title accessory. |
|
|
714
|
+
| `top` | `string \| number` | No | `-` | - |
|
|
715
|
+
| `transform` | `string \| (({ scaleX: AnimatableNumericValue; } & { scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ scaleY: AnimatableNumericValue; } & { scaleX?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ translateX: AnimatableNumericValue \| ${number}%; } & { scaleX?: undefined; scaleY?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ translateY: AnimatableNumericValue \| ${number}%; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ perspective: AnimatableNumericValue; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ rotate: AnimatableStringValue; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ rotateX: AnimatableStringValue; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ rotateY: AnimatableStringValue; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ rotateZ: AnimatableStringValue; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ scale: AnimatableNumericValue; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; skewX?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ skewX: AnimatableStringValue; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewY?: undefined; matrix?: undefined; }) \| ({ skewY: AnimatableStringValue; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; matrix?: undefined; }) \| ({ matrix: AnimatableNumericValue[]; } & { scaleX?: undefined; scaleY?: undefined; translateX?: undefined; translateY?: undefined; perspective?: undefined; rotate?: undefined; rotateX?: undefined; rotateY?: undefined; rotateZ?: undefined; scale?: undefined; skewX?: undefined; skewY?: undefined; }))[]` | No | `-` | - |
|
|
716
|
+
| `transparentWhileInactive` | `boolean` | No | `-` | Mark the background and border as transparent until the element is interacted with (hovered, pressed, etc). Must be used in conjunction with the pressed prop |
|
|
717
|
+
| `transparentWhilePressed` | `boolean` | No | `-` | Mark the background and border as transparent even while element is interacted with (elevation underlay issue). Must be used in conjunction with the pressed prop |
|
|
718
|
+
| `userSelect` | `none \| auto \| contain \| text \| all` | No | `-` | - |
|
|
719
|
+
| `width` | `string \| number` | No | `-` | - |
|
|
720
|
+
| `wrapperStyles` | `{ base?: StyleProp<ViewStyle>; pressed?: StyleProp<ViewStyle>; disabled?: StyleProp<ViewStyle>; }` | No | `-` | Apply styles to the outer container. |
|
|
721
|
+
| `zIndex` | `number` | No | `-` | - |
|
|
722
|
+
|
|
723
|
+
|