@coinbase/cds-mcp-server 8.40.2 → 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.
Files changed (43) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/mcp-docs/mobile/components/Alert.txt +1 -1
  3. package/mcp-docs/mobile/components/Combobox.txt +45 -0
  4. package/mcp-docs/mobile/components/ContainedAssetCard.txt +1 -1
  5. package/mcp-docs/mobile/components/ContentCard.txt +220 -174
  6. package/mcp-docs/mobile/components/ContentCardBody.txt +127 -19
  7. package/mcp-docs/mobile/components/ContentCardFooter.txt +63 -1
  8. package/mcp-docs/mobile/components/ContentCardHeader.txt +71 -16
  9. package/mcp-docs/mobile/components/DataCard.txt +723 -0
  10. package/mcp-docs/mobile/components/DateInput.txt +4 -3
  11. package/mcp-docs/mobile/components/DatePicker.txt +4 -3
  12. package/mcp-docs/mobile/components/FloatingAssetCard.txt +1 -1
  13. package/mcp-docs/mobile/components/MediaCard.txt +526 -0
  14. package/mcp-docs/mobile/components/MessagingCard.txt +1025 -0
  15. package/mcp-docs/mobile/components/NudgeCard.txt +1 -1
  16. package/mcp-docs/mobile/components/Pictogram.txt +1 -1
  17. package/mcp-docs/mobile/components/Scrubber.txt +140 -0
  18. package/mcp-docs/mobile/components/SelectAlpha.txt +72 -4
  19. package/mcp-docs/mobile/components/SelectChipAlpha.txt +1 -0
  20. package/mcp-docs/mobile/components/TextInput.txt +4 -3
  21. package/mcp-docs/mobile/routes.txt +6 -3
  22. package/mcp-docs/web/components/Alert.txt +1 -1
  23. package/mcp-docs/web/components/Combobox.txt +47 -0
  24. package/mcp-docs/web/components/ContentCard.txt +419 -327
  25. package/mcp-docs/web/components/ContentCardBody.txt +91 -16
  26. package/mcp-docs/web/components/ContentCardFooter.txt +231 -165
  27. package/mcp-docs/web/components/ContentCardHeader.txt +237 -177
  28. package/mcp-docs/web/components/DataCard.txt +800 -0
  29. package/mcp-docs/web/components/DateInput.txt +8 -9
  30. package/mcp-docs/web/components/DatePicker.txt +8 -9
  31. package/mcp-docs/web/components/MediaCard.txt +559 -0
  32. package/mcp-docs/web/components/MessagingCard.txt +1054 -0
  33. package/mcp-docs/web/components/NudgeCard.txt +1 -1
  34. package/mcp-docs/web/components/Pictogram.txt +1 -1
  35. package/mcp-docs/web/components/ReferenceLine.txt +1 -0
  36. package/mcp-docs/web/components/Scrubber.txt +106 -0
  37. package/mcp-docs/web/components/SelectAlpha.txt +66 -4
  38. package/mcp-docs/web/components/SelectChipAlpha.txt +1 -0
  39. package/mcp-docs/web/components/TextInput.txt +8 -9
  40. package/mcp-docs/web/components/TileButton.txt +1 -1
  41. package/mcp-docs/web/components/Tooltip.txt +7 -8
  42. package/mcp-docs/web/routes.txt +3 -0
  43. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -8,6 +8,14 @@ All notable changes to this project will be documented in this file.
8
8
 
9
9
  <!-- template-start -->
10
10
 
11
+ ## 8.42.0 ((2/4/2026, 01:51 PM PST))
12
+
13
+ This is an artificial version bump with no new change.
14
+
15
+ ## 8.41.0 ((2/4/2026, 09:22 AM PST))
16
+
17
+ This is an artificial version bump with no new change.
18
+
11
19
  ## 8.40.2 ((2/2/2026, 11:25 AM PST))
12
20
 
13
21
  This is an artificial version bump with no new change.
@@ -149,7 +149,7 @@ function AlertOnModalExample() {
149
149
  | `onDidClose` | `(() => void)` | No | `-` | Callback fired after the component is closed. |
150
150
  | `onDismissActionPress` | `(() => void)` | No | `-` | Callback function fired when the dismiss action is pressed |
151
151
  | `onPreferredActionPress` | `(() => void)` | No | `-` | Callback function fired when the preferred action is pressed |
152
- | `pictogram` | `key \| done \| loop \| cardSuccess \| warning \| error \| add \| browser \| calculator \| calendar \| checkmark \| clock \| coinbaseOneLogo \| crystalBallInsight \| derivativesProduct \| email \| gasFees \| identityCard \| instantUnstakingClock \| laptop \| learningRewardsProduct \| lock \| passport \| paypal \| phone \| pieChartData \| planet \| robot \| safe \| securityKey \| settings \| shield \| support \| taxes \| tokenSales \| trading \| verifiedPools \| wallet \| 2fa \| accountsNavigation \| accreditedInvestor \| addCard \| addPayment \| addPhone \| addressBook \| addToWatchlist \| addWallet \| advancedTradingDesktop \| advancedTradingNavigation \| advancedTradingRebates \| agent \| alerts \| alertsCoinbaseOne \| analyticsNavigation \| apartOfDropsNft \| applyForHigherLimits \| apyInterest \| assetEncryption \| assetHubNavigation \| assetManagement \| assetManagementNavigation \| assetMeasurements \| assetMovement \| authenticationApp \| authenticator \| authenticatorAlt \| authenticatorProgress \| avatarAa \| avatarAb \| avatarAc \| avatarAd \| avatarAe \| avatarAf \| avatarAg \| avatarAh \| avatarAi \| avatarAj \| avatarBa \| avatarBb \| avatarBc \| avatarBd \| avatarBe \| avatarBf \| avatarBg \| avatarBh \| avatarBi \| avatarBj \| avatarCa \| avatarCb \| avatarCc \| avatarCd \| avatarCe \| avatarCf \| avatarCg \| avatarCh \| avatarCi \| avatarCj \| avatarDa \| avatarDb \| avatarDc \| avatarDd \| avatarDe \| avatarDf \| avatarDg \| avatarDh \| avatarDi \| avatarDj \| avatarEa \| avatarEb \| avatarEc \| avatarEd \| avatarEe \| avatarEf \| avatarEg \| avatarEh \| avatarEi \| avatarEj \| avatarFa \| avatarFb \| avatarFc \| avatarFd \| avatarFe \| avatarFf \| avatarFg \| avatarFh \| avatarFi \| avatarFj \| avatarGa \| avatarGb \| avatarGc \| avatarGd \| avatarGe \| avatarGf \| avatarGg \| avatarGh \| avatarGi \| avatarGj \| avatarHa \| avatarHb \| avatarHc \| avatarHd \| avatarHe \| avatarHf \| avatarHg \| avatarHh \| avatarHi \| avatarHj \| avatarIa \| avatarIb \| avatarIc \| avatarId \| avatarIe \| avatarIf \| avatarIg \| avatarIh \| avatarIi \| avatarIj \| avatarJa \| avatarJb \| avatarJc \| avatarJd \| avatarJe \| avatarJf \| avatarJg \| avatarJh \| avatarJi \| avatarJj \| barChart \| baseAscend \| baseCertificateStar \| baseChartSmall \| baseChatBubbleHeart \| baseCheckSmall \| baseCoinCryptoSmall \| baseCoinNetworkSmall \| baseCoinStack \| baseCoinStar \| baseComet \| baseComputer \| baseConfetti \| baseConnectApps \| baseConnectSmall \| baseCreatorCoin \| baseDecentralizationSmall \| baseDiamondSmall \| baseDiamondTrophy \| baseDoor \| baseEarnedBadge \| baseEmptySmall \| baseErrorButterflySmall \| baseErrorSmall \| baseExchange \| baseFire \| baseGem \| baseGlobe \| baseHandStar \| baseLayout \| baseLightningbolt \| baseLoadingSmall \| baseLocationSmall \| baseLogo \| baseLogoNavigation \| baseMedal \| baseMessaging \| baseMintNftSmall \| baseNetworkSmall \| baseNftSmall \| basePaycoinSmall \| basePeopleSmall \| basePiechartSmall \| basePlant \| basePower \| baseRibbon \| baseRocket \| baseRockon \| baseSaved \| baseSecuritySmall \| baseSendSmall \| baseSignin \| baseSmile \| baseStack \| baseStar \| baseTargetSmall \| baseTile \| bigBtcSend \| bitcoin \| bitcoinPizza \| bitcoinRewards \| bitcoinWhitePaper \| blockchainConnection \| bonusFivePercent \| bonusTwoPercent \| borrowCoins \| borrowingLending \| borrowNavigation \| browserMultiPlatform \| browserTransaction \| btcOneHundred \| bundle \| businessProduct \| calendarCaution \| calendarHighlight \| candleSticksGraph \| cardBlocked \| cardDeclined \| cardNavigation \| cb1BankTransfers \| chart \| chat \| cloudNavigation \| coinbaseLogoAdvancedBrand \| coinbaseLogoNavigation \| coinbaseOneAuthenticator \| coinbaseOneChat \| coinbaseOneEarn \| coinbaseOneEarnCoins \| coinbaseOneEarnCoinsLogo \| coinbaseOneFiat \| coinbaseOneProductIcon \| coinbaseOneProductInvestWeekly \| coinbaseOneRefreshed \| coinbaseOneShield \| coinbaseOneTrade \| coinbaseOneTrusted \| coinbaseOneUnlimitedRewards \| coinbaseUnlockOffers \| coinbaseWalletApp \| coinFocus \| coinShare \| coldStorageCheck \| collectionOfAssets \| commerceCheckout \| commerceInvoice \| commerceNavigation \| commodities \| completeQuiz \| complianceNavigation \| congratulations \| connectNavigation \| contactInfo \| controlWalletStorage \| creative \| creditCard \| crypto101 \| cryptoCard \| cryptoCoins \| cryptoFolder \| custodialJourney \| custodyNavigation \| dataMarketplaceNavigation \| decentralizationEverything \| decentralizedExchange \| decentralizedIdentity \| decentralizedWeb3 \| defiEarnMoment \| delegate \| delegateNavigation \| derivativesNavigation \| developerPlatformNavigation \| developerSDKNavigation \| directDepositNavigation \| dollarShowcase \| driversLicense \| driversLicenseWheel \| earnCoins \| earnGraph \| earnNavigation \| easyToUse \| economyGlobal \| emailAndMessages \| enableVoting \| envelope \| ethereumFocus \| ethRewards \| ethStaking \| ethStakingChart \| ethStakingRewards \| ethToken \| exchangeNavigation \| explore \| fast \| faucetNavigation \| feesRestriction \| fiat \| finance \| findYourSelection \| formDownload \| futures \| futuresCoinbaseOne \| gem \| genericCountryIDCard \| getStarted \| giftbox \| globalConnections \| globalPayments \| globalTransactions \| googleAuthenticator \| governance \| hardwareWallet \| helpCenterNavigation \| higherLimits \| holdingCoin \| idBlock \| idError \| idVerification \| increaseLimits \| institutionalNavigation \| institutions \| internationalExchangeNavigation \| internet \| investGraph \| laptopCharts \| laptopVideo \| layerNetworks \| leadGraph \| learn \| learningRewardsNavigation \| lightbulbLearn \| lightningNetworkSend \| linkYourAccount \| listingFees \| locationUsa \| lowFees \| manageWeb3SignersAcct \| miningCoins \| mintedNft \| mobileCharts \| mobileError \| mobileNotifcation \| mobileSuccess \| mobileWarning \| moneyCrypto \| moneyEarn \| moneySwift \| monitoringPerformance \| moreThanBitcoin \| multiAccountsAndCards \| multiPlatform \| multipleAssets \| musicAndSounds \| myNumberCard \| newUserChecklistBuyCrypto \| newUserChecklistCompleteAccount \| newUserChecklistVerifyId \| nftAvatar \| nftLibrary \| nftNavigation \| noAnnualFee \| noNftFound \| notificationHubAnalysis \| notificationHubNews \| notificationHubPortfolio \| notificationHubSocial \| notifications \| noVisibility \| noWiFi \| orders \| outage \| partialCoins \| participateNavigation \| passwordWalletLocked \| payNavigation \| peerToPeer \| pieChart \| pizza \| pluginBrowser \| podium \| positiveReviews \| predictionMarkets \| premiumInvestor \| priceTracking \| primeMobileApp \| primeNavigation \| privateClientNavigation \| proNavigation \| protectionPlan \| queryTransactNavigation \| receipt \| recurringPurchases \| restaking \| reviewAndAdd \| rewardsNavigation \| riskStaking \| rosettaNavigation \| securedAssets \| security \| securityCoinShield \| seedPhrase \| selectAddNft \| selfCustodyWallet \| selfServe \| sellSendAnytime \| sendPaymentToOthers \| settled \| sideChainSide \| signInNavigation \| smsAuthenticate \| sparkleCoinbaseOne \| ssnCard \| stableCoinMetaphor \| stacking \| stakingGraph \| standWithCryptoLogoNavigation \| startToday \| strongInfo \| strongWarning \| successPhone \| supportChat \| takeQuiz \| target \| taxBeta \| taxCenterNavigation \| taxesArrangement \| taxSeason \| timingCheck \| tokenBaskets \| transferSend \| transistor \| trendingAssets \| trusted \| tryAgainLater \| twoBonus \| typeScript \| ubiKey \| usaProduct \| usdcEarn \| usdcInterest \| usdcLoan \| usdcLogo \| usdcRewards \| usdcRewardsRibbon \| usdcToken \| venturesNavigation \| videoCalendar \| videoContent \| waiting \| waitingForConsensus \| walletAsServiceNavigation \| walletDeposit \| walletError \| walletExchange \| walletLinkNavigation \| walletLogoNavigation \| walletNavigation \| walletPassword \| walletSuccess \| walletWarning \| winBTC \| worldwide \| wrapEth` | No | `-` | Illustration pictogram name for alert |
152
+ | `pictogram` | `key \| done \| loop \| cardSuccess \| warning \| error \| add \| arrowsUpDown \| browser \| calculator \| calendar \| checkmark \| clock \| coinbaseOneLogo \| crystalBallInsight \| derivativesProduct \| email \| gasFees \| identityCard \| instantUnstakingClock \| laptop \| learningRewardsProduct \| lock \| passport \| paypal \| phone \| pieChartData \| planet \| robot \| safe \| securityKey \| settings \| shield \| support \| taxes \| tokenSales \| trading \| verifiedPools \| wallet \| 2fa \| accountsNavigation \| accreditedInvestor \| addCard \| addPayment \| addPhone \| addressBook \| addToWatchlist \| addWallet \| advancedTradingDesktop \| advancedTradingNavigation \| advancedTradingRebates \| agent \| alerts \| alertsCoinbaseOne \| analyticsNavigation \| apartOfDropsNft \| applyForHigherLimits \| apyInterest \| assetEncryption \| assetHubNavigation \| assetManagement \| assetManagementNavigation \| assetMeasurements \| assetMovement \| authenticationApp \| authenticator \| authenticatorAlt \| authenticatorProgress \| avatarAa \| avatarAb \| avatarAc \| avatarAd \| avatarAe \| avatarAf \| avatarAg \| avatarAh \| avatarAi \| avatarAj \| avatarBa \| avatarBb \| avatarBc \| avatarBd \| avatarBe \| avatarBf \| avatarBg \| avatarBh \| avatarBi \| avatarBj \| avatarCa \| avatarCb \| avatarCc \| avatarCd \| avatarCe \| avatarCf \| avatarCg \| avatarCh \| avatarCi \| avatarCj \| avatarDa \| avatarDb \| avatarDc \| avatarDd \| avatarDe \| avatarDf \| avatarDg \| avatarDh \| avatarDi \| avatarDj \| avatarEa \| avatarEb \| avatarEc \| avatarEd \| avatarEe \| avatarEf \| avatarEg \| avatarEh \| avatarEi \| avatarEj \| avatarFa \| avatarFb \| avatarFc \| avatarFd \| avatarFe \| avatarFf \| avatarFg \| avatarFh \| avatarFi \| avatarFj \| avatarGa \| avatarGb \| avatarGc \| avatarGd \| avatarGe \| avatarGf \| avatarGg \| avatarGh \| avatarGi \| avatarGj \| avatarHa \| avatarHb \| avatarHc \| avatarHd \| avatarHe \| avatarHf \| avatarHg \| avatarHh \| avatarHi \| avatarHj \| avatarIa \| avatarIb \| avatarIc \| avatarId \| avatarIe \| avatarIf \| avatarIg \| avatarIh \| avatarIi \| avatarIj \| avatarJa \| avatarJb \| avatarJc \| avatarJd \| avatarJe \| avatarJf \| avatarJg \| avatarJh \| avatarJi \| avatarJj \| barChart \| baseAscend \| baseCertificateStar \| baseChartSmall \| baseChatBubbleHeart \| baseCheckSmall \| baseCoinCryptoSmall \| baseCoinNetworkSmall \| baseCoinStack \| baseCoinStar \| baseComet \| baseComputer \| baseConfetti \| baseConnectApps \| baseConnectSmall \| baseCreatorCoin \| baseDecentralizationSmall \| baseDiamondSmall \| baseDiamondTrophy \| baseDoor \| baseEarnedBadge \| baseEmptySmall \| baseErrorButterflySmall \| baseErrorSmall \| baseExchange \| baseFire \| baseGem \| baseGlobe \| baseHandStar \| baseLayout \| baseLightningbolt \| baseLoadingSmall \| baseLocationSmall \| baseLogo \| baseLogoNavigation \| baseMedal \| baseMessaging \| baseMintNftSmall \| baseNetworkSmall \| baseNftSmall \| basePaycoinSmall \| basePeopleSmall \| basePiechartSmall \| basePlant \| basePower \| baseRibbon \| baseRocket \| baseRockon \| baseSaved \| baseSecuritySmall \| baseSendSmall \| baseSignin \| baseSmile \| baseStack \| baseStar \| baseTargetSmall \| baseTile \| bigBtcSend \| bitcoin \| bitcoinPizza \| bitcoinRewards \| bitcoinWhitePaper \| blockchainConnection \| bonusFivePercent \| bonusTwoPercent \| borrowCoins \| borrowingLending \| borrowNavigation \| browserMultiPlatform \| browserTransaction \| btcOneHundred \| bundle \| businessProduct \| calendarCaution \| calendarHighlight \| candleSticksGraph \| cardBlocked \| cardDeclined \| cardNavigation \| cb1BankTransfers \| chart \| chat \| cloudNavigation \| coinbaseLogoAdvancedBrand \| coinbaseLogoNavigation \| coinbaseOneAuthenticator \| coinbaseOneChat \| coinbaseOneEarn \| coinbaseOneEarnCoins \| coinbaseOneEarnCoinsLogo \| coinbaseOneFiat \| coinbaseOneProductIcon \| coinbaseOneProductInvestWeekly \| coinbaseOneRefreshed \| coinbaseOneShield \| coinbaseOneTrade \| coinbaseOneTrusted \| coinbaseOneUnlimitedRewards \| coinbaseUnlockOffers \| coinbaseWalletApp \| coinFocus \| coinShare \| coldStorageCheck \| collectionOfAssets \| commerceCheckout \| commerceInvoice \| commerceNavigation \| commodities \| completeQuiz \| complianceNavigation \| congratulations \| connectNavigation \| contactInfo \| controlWalletStorage \| creative \| creditCard \| crypto101 \| cryptoCard \| cryptoCoins \| cryptoFolder \| custodialJourney \| custodyNavigation \| dataMarketplaceNavigation \| decentralizationEverything \| decentralizedExchange \| decentralizedIdentity \| decentralizedWeb3 \| defiEarnMoment \| delegate \| delegateNavigation \| derivativesNavigation \| developerPlatformNavigation \| developerSDKNavigation \| directDepositNavigation \| dollarShowcase \| driversLicense \| driversLicenseWheel \| earnCoins \| earnGraph \| earnNavigation \| easyToUse \| economyGlobal \| emailAndMessages \| enableVoting \| envelope \| ethereumFocus \| ethRewards \| ethStaking \| ethStakingChart \| ethStakingRewards \| ethToken \| exchangeNavigation \| explore \| fast \| faucetNavigation \| feesRestriction \| fiat \| finance \| findYourSelection \| formDownload \| futures \| futuresCoinbaseOne \| gem \| genericCountryIDCard \| getStarted \| giftbox \| globalConnections \| globalPayments \| globalTransactions \| googleAuthenticator \| governance \| hardwareWallet \| helpCenterNavigation \| higherLimits \| holdingCoin \| idBlock \| idError \| idVerification \| increaseLimits \| institutionalNavigation \| institutions \| internationalExchangeNavigation \| internet \| investGraph \| laptopCharts \| laptopVideo \| layerNetworks \| leadGraph \| learn \| learningRewardsNavigation \| lightbulbLearn \| lightningNetworkSend \| linkYourAccount \| listingFees \| locationUsa \| lowFees \| manageWeb3SignersAcct \| miningCoins \| mintedNft \| mobileCharts \| mobileError \| mobileNotifcation \| mobileSuccess \| mobileWarning \| moneyCrypto \| moneyEarn \| moneySwift \| monitoringPerformance \| moreThanBitcoin \| multiAccountsAndCards \| multiPlatform \| multipleAssets \| musicAndSounds \| myNumberCard \| newUserChecklistBuyCrypto \| newUserChecklistCompleteAccount \| newUserChecklistVerifyId \| nftAvatar \| nftLibrary \| nftNavigation \| noAnnualFee \| noNftFound \| notificationHubAnalysis \| notificationHubNews \| notificationHubPortfolio \| notificationHubSocial \| notifications \| noVisibility \| noWiFi \| orders \| outage \| partialCoins \| participateNavigation \| passwordWalletLocked \| payNavigation \| peerToPeer \| pieChart \| pizza \| pluginBrowser \| podium \| positiveReviews \| predictionMarkets \| premiumInvestor \| priceTracking \| primeMobileApp \| primeNavigation \| privateClientNavigation \| proNavigation \| protectionPlan \| queryTransactNavigation \| receipt \| recurringPurchases \| restaking \| reviewAndAdd \| rewardsNavigation \| riskStaking \| rosettaNavigation \| securedAssets \| security \| securityCoinShield \| seedPhrase \| selectAddNft \| selfCustodyWallet \| selfServe \| sellSendAnytime \| sendPaymentToOthers \| settled \| sideChainSide \| signInNavigation \| smsAuthenticate \| sparkleCoinbaseOne \| ssnCard \| stableCoinMetaphor \| stacking \| stakingGraph \| standWithCryptoLogoNavigation \| startToday \| strongInfo \| strongWarning \| successPhone \| supportChat \| takeQuiz \| target \| taxBeta \| taxCenterNavigation \| taxesArrangement \| taxSeason \| timingCheck \| tokenBaskets \| transferSend \| transistor \| trendingAssets \| trusted \| tryAgainLater \| twoBonus \| typeScript \| ubiKey \| usaProduct \| usdcEarn \| usdcInterest \| usdcLoan \| usdcLogo \| usdcRewards \| usdcRewardsRibbon \| usdcToken \| venturesNavigation \| videoCalendar \| videoContent \| waiting \| waitingForConsensus \| walletAsServiceNavigation \| walletDeposit \| walletError \| walletExchange \| walletLinkNavigation \| walletLogoNavigation \| walletNavigation \| walletPassword \| walletSuccess \| walletWarning \| winBTC \| worldwide \| wrapEth` | No | `-` | Illustration pictogram name for alert |
153
153
  | `preferredActionVariant` | `primary \| negative` | No | `primary` | Button variant of the preferred action |
154
154
  | `ref` | `((instance: ModalRefBaseProps \| null) => void) \| RefObject<ModalRefBaseProps> \| null` | No | `-` | - |
155
155
  | `testID` | `string` | No | `-` | Used to locate this element in unit and end-to-end tests. Under the hood, testID translates to data-testid on Web. On Mobile, testID stays the same - testID |
@@ -133,6 +133,50 @@ function HelperTextExample() {
133
133
  }
134
134
  ```
135
135
 
136
+ ### Alignment
137
+
138
+ The alignment of the selected value(s) can be adjusted using the `align` prop.
139
+
140
+ ::::note
141
+ Left / right alignment is preferred for styling.
142
+ ::::
143
+
144
+ ```jsx
145
+ function AlignmentExample() {
146
+ const fruitOptions = [
147
+ { value: 'apple', label: 'Apple' },
148
+ { value: 'banana', label: 'Banana' },
149
+ { value: 'cherry', label: 'Cherry' },
150
+ { value: 'date', label: 'Date' },
151
+ { value: 'elderberry', label: 'Elderberry' },
152
+ ];
153
+
154
+ const { value, onChange } = useMultiSelect({ initialValue: ['apple', 'banana', 'cherry'] });
155
+
156
+ return (
157
+ <VStack gap={2}>
158
+ <Combobox
159
+ label="Default align - start"
160
+ onChange={onChange}
161
+ options={fruitOptions}
162
+ placeholder="Search fruits..."
163
+ type="multi"
164
+ value={value}
165
+ />
166
+ <Combobox
167
+ align="end"
168
+ label="End align"
169
+ onChange={onChange}
170
+ options={fruitOptions}
171
+ placeholder="Search fruits..."
172
+ type="multi"
173
+ value={value}
174
+ />
175
+ </VStack>
176
+ );
177
+ }
178
+ ```
179
+
136
180
  ### Borderless
137
181
 
138
182
  You can remove the border from the combobox control by setting `bordered` to `false`.
@@ -201,6 +245,7 @@ function BorderlessExample() {
201
245
  | `SelectOptionGroupComponent` | `SelectOptionGroupComponent<Type, SelectOptionValue>` | No | `-` | Custom component to render group headers |
202
246
  | `accessibilityRoles` | `{ option?: AccessibilityRole; } \| undefined` | No | `-` | Accessibility roles for dropdown elements |
203
247
  | `accessory` | `ReactElement<CellAccessoryProps, string \| JSXElementConstructor<any>>` | No | `-` | - |
248
+ | `align` | `end \| start \| center` | No | `'start'` | Alignment of the value node. |
204
249
  | `bordered` | `boolean` | No | `true` | Add a border around all sides of the box. Determines if the control should have a default border. |
205
250
  | `clearAllLabel` | `string` | No | `-` | Label for the Clear All option in multi-select mode |
206
251
  | `closeButtonLabel` | `string` | No | `-` | Label for close button when combobox is open (mobile only) |
@@ -1,6 +1,6 @@
1
1
  # ContainedAssetCard
2
2
 
3
- Asset Cards display current and potential future assets, offering a straightforward method to view and manage a customer's holdings. They provide a clear visual and informative overview, simplifying asset management and investment considerations.
3
+ Asset Cards display current and potential future assets, offering a straightforward method to view and manage a customer's holdings.
4
4
 
5
5
  ## Import
6
6
 
@@ -1,6 +1,6 @@
1
1
  # ContentCard
2
2
 
3
- A flexible card component for displaying content with header, body, and footer sections.
3
+ A flexible, composable card component for displaying rich content with customizable header, body, and footer sections. Use with ContentCardHeader, ContentCardBody, and ContentCardFooter sub-components.
4
4
 
5
5
  ## Import
6
6
 
@@ -10,84 +10,125 @@ import { ContentCard } from '@coinbase/cds-mobile/cards/ContentCard'
10
10
 
11
11
  ## Examples
12
12
 
13
- ### Text only
13
+ ContentCard is a flexible, composable card component built with `ContentCardHeader`, `ContentCardBody`, and `ContentCardFooter` sub-components. It can display various content layouts including text, media, and interactive elements.
14
14
 
15
- These are our most basic Content Cards.
15
+ ### Basic Examples
16
+
17
+ ContentCard uses sub-components for flexible layout. Combine `ContentCardHeader`, `ContentCardBody`, and `ContentCardFooter` to create your card structure.
16
18
 
17
19
  ```jsx
18
20
  function Example() {
19
21
  return (
20
- <VStack bordered borderRadius="400" maxWidth={375}>
22
+ <VStack gap={2}>
21
23
  <ContentCard>
22
24
  <ContentCardHeader
23
- end={
24
- <IconButton
25
- transparent
26
- accessibilityLabel="More information about coinDesk card news"
27
- name="more"
28
- variant="secondary"
29
- />
30
- }
31
- meta={
32
- <Box marginLeft={-1}>
33
- <Text as="span" font="label2" color="fgMuted" marginLeft={-1} numberOfLines={1}>
34
- ・News・5 hrs
35
- </Text>
36
- </Box>
25
+ thumbnail={assets.eth.imageUrl}
26
+ title="CoinDesk"
27
+ subtitle="News"
28
+ actions={
29
+ <HStack gap={0}>
30
+ <IconButton
31
+ transparent
32
+ accessibilityLabel="favorite"
33
+ name="star"
34
+ variant="secondary"
35
+ />
36
+ <IconButton
37
+ transparent
38
+ accessibilityLabel="More options"
39
+ name="more"
40
+ variant="secondary"
41
+ />
42
+ </HStack>
37
43
  }
38
- title="Description"
39
44
  />
40
45
  <ContentCardBody
41
- body="Bitcoin Network Shatters Records With Hashrate Climbing to 464 EH/s"
46
+ title="Ethereum Network Shatters Records With Hashrate Climbing to 464 EH/s"
47
+ description="This is a description of the record-breaking hashrate milestone."
42
48
  label={
43
49
  <HStack alignItems="flex-end" flexWrap="wrap" gap={0.5}>
44
- <Text as="p" font="label2" color="fgMuted" numberOfLines={1}>
45
- BTC
50
+ <Text color="fgMuted" font="label2" numberOfLines={1}>
51
+ $3,081.01
46
52
  </Text>
47
- <Text font="label2" accessibilityLabel="Up 5.12%" as="p" color="fgPositive">
48
- 5.12%
53
+ <Text color="fgPositive" font="label2">
54
+ 6.37%
49
55
  </Text>
50
56
  </HStack>
51
57
  }
52
58
  />
59
+ <ContentCardFooter>
60
+ <RemoteImageGroup shape="circle" size={32}>
61
+ <RemoteImage source={{ uri: assets.eth.imageUrl }} />
62
+ <RemoteImage source={{ uri: assets.polygon.imageUrl }} />
63
+ </RemoteImageGroup>
64
+ <Button compact variant="secondary">
65
+ Share
66
+ </Button>
67
+ </ContentCardFooter>
53
68
  </ContentCard>
69
+ </VStack>
70
+ );
71
+ }
72
+ ```
73
+
74
+ ### Media Placement
75
+
76
+ Use the `mediaPlacement` prop on `ContentCardBody` to control where media is positioned relative to the content.
77
+
78
+ ```jsx
79
+ function Example() {
80
+ const exampleMedia = (
81
+ <RemoteImage
82
+ accessibilityLabel="Ethereum background"
83
+ source={{ uri: ethBackground }}
84
+ style={{ borderRadius: 24 }}
85
+ width="100%"
86
+ />
87
+ );
88
+
89
+ return (
90
+ <VStack gap={2}>
91
+ <Text font="headline">mediaPlacement: top (default)</Text>
54
92
  <ContentCard>
55
- <ContentCardHeader
56
- meta={
57
- <Box marginLeft={-1}>
58
- <Text as="span" font="label2" color="fgMuted" numberOfLines={1}>
59
- ・News・5 hrs
60
- </Text>
61
- </Box>
62
- }
63
- title="Brian Armstrong"
93
+ <ContentCardHeader thumbnail={assets.eth.imageUrl} title="CoinDesk" subtitle="News" />
94
+ <ContentCardBody
95
+ title="Media at top"
96
+ description="The media appears above the text content."
97
+ media={exampleMedia}
98
+ mediaPlacement="top"
99
+ />
100
+ </ContentCard>
101
+
102
+ <Text font="headline">mediaPlacement: bottom</Text>
103
+ <ContentCard>
104
+ <ContentCardHeader thumbnail={assets.eth.imageUrl} title="CoinDesk" subtitle="News" />
105
+ <ContentCardBody
106
+ title="Media at bottom"
107
+ description="The media appears below the text content."
108
+ media={exampleMedia}
109
+ mediaPlacement="bottom"
64
110
  />
111
+ </ContentCard>
112
+
113
+ <Text font="headline">mediaPlacement: end</Text>
114
+ <ContentCard>
115
+ <ContentCardHeader thumbnail={assets.eth.imageUrl} title="CoinDesk" subtitle="News" />
65
116
  <ContentCardBody
66
- body="Bitcoin Network Shatters Records With Hashrate Climbing to 464 EH/s"
67
- label={
68
- <HStack alignItems="flex-end" flexWrap="wrap" gap={0.5}>
69
- <Text as="p" font="label2" color="fgMuted" numberOfLines={1}>
70
- BTC
71
- </Text>
72
- <Text font="label2" accessibilityLabel="Up 5.12%" as="p" color="fgPositive">
73
- 5.12%
74
- </Text>
75
- </HStack>
76
- }
77
- media={
78
- <img
79
- alt=""
80
- aria-hidden="true"
81
- src="/img/card/content_card_basic.png"
82
- style={{
83
- objectFit: 'cover',
84
- cursor: 'pointer',
85
- borderRadius: '24px',
86
- }}
87
- width="100%"
88
- />
89
- }
90
- mediaPosition="right"
117
+ title="Media at end"
118
+ description="The media appears to the right of the text content."
119
+ media={exampleMedia}
120
+ mediaPlacement="end"
121
+ />
122
+ </ContentCard>
123
+
124
+ <Text font="headline">mediaPlacement: start</Text>
125
+ <ContentCard>
126
+ <ContentCardHeader thumbnail={assets.eth.imageUrl} title="CoinDesk" subtitle="News" />
127
+ <ContentCardBody
128
+ title="Media at start"
129
+ description="The media appears to the left of the text content."
130
+ media={exampleMedia}
131
+ mediaPlacement="start"
91
132
  />
92
133
  </ContentCard>
93
134
  </VStack>
@@ -95,79 +136,110 @@ function Example() {
95
136
  }
96
137
  ```
97
138
 
98
- ### Rewards Content Card
139
+ ### With Background
99
140
 
100
- This is an example of Content Cards being used for rewards.
141
+ Apply a background color to the card using the `background` prop. When using a background, consider using `variant="tertiary"` on buttons.
101
142
 
102
143
  ```jsx
103
144
  function Example() {
104
- const opIcon = (
105
- <svg fill="none" height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg">
106
- <g clipPath="url(#clip0_3440_332)">
107
- <circle cx="16" cy="16" fill="#FF0420" r="16" />
108
- <path
109
- clipRule="evenodd"
110
- d="M7.05376 20.238C7.76564 20.7575 8.6789 21.0172 9.79355 21.0172C11.1424 21.0172 12.2195 20.7064 13.0251 20.085C13.8306 19.4543 14.3973 18.5036 14.7252 17.2329C14.9219 16.4538 15.0904 15.6515 15.231 14.826C15.2778 14.5292 15.3012 14.2834 15.3012 14.0886C15.3012 13.4394 15.1373 12.8829 14.8095 12.4191C14.4816 11.9461 14.032 11.5936 13.4606 11.3617C12.8893 11.1206 12.243 11 11.5217 11C8.87092 11 7.22705 12.2753 6.59011 14.826C6.3653 15.7628 6.19202 16.5651 6.07025 17.2329C6.02342 17.5297 6 17.7801 6 17.9842C6 18.9581 6.35125 19.7094 7.05376 20.238ZM11.325 18.5546C10.9597 18.8607 10.5148 19.0137 9.99025 19.0137C9.09104 19.0137 8.64143 18.5871 8.64143 17.7337C8.64143 17.5297 8.66016 17.3349 8.69763 17.1494C8.86624 16.2498 9.03483 15.4892 9.20344 14.8677C9.36267 14.237 9.62494 13.7686 9.99025 13.4626C10.3649 13.1565 10.8145 13.0034 11.3391 13.0034C12.2289 13.0034 12.6738 13.4255 12.6738 14.2695C12.6738 14.4735 12.6551 14.673 12.6176 14.8677C12.5052 15.517 12.3413 16.2776 12.1259 17.1494C11.9666 17.7801 11.6997 18.2485 11.325 18.5546Z"
111
- fill="white"
112
- fillRule="evenodd"
145
+ const exampleMedia = (
146
+ <RemoteImage
147
+ accessibilityLabel="Ethereum background"
148
+ source={{ uri: ethBackground }}
149
+ style={{ borderRadius: 24 }}
150
+ width="100%"
151
+ />
152
+ );
153
+
154
+ return (
155
+ <VStack gap={2}>
156
+ <ContentCard background="bgAlternate">
157
+ <ContentCardHeader thumbnail={assets.eth.imageUrl} title="CoinDesk" subtitle="News" />
158
+ <ContentCardBody
159
+ title="Card with Background"
160
+ description="This card has an alternate background color."
161
+ media={exampleMedia}
113
162
  />
114
- <path
115
- clipRule="evenodd"
116
- d="M16.488 20.7807C16.5442 20.8456 16.6238 20.878 16.7269 20.878H18.6377C18.7314 20.878 18.8203 20.8456 18.9046 20.7807C18.9889 20.7157 19.0405 20.6323 19.0592 20.5302L19.7055 17.4833H21.6023C22.8293 17.4833 23.7941 17.2283 24.4966 16.7182C25.2085 16.208 25.6815 15.4196 25.9157 14.353C25.9719 14.1025 26 13.8614 26 13.6295C26 12.8226 25.6815 12.2058 25.0446 11.7791C24.417 11.3525 23.5834 11.1391 22.5436 11.1391H18.8063C18.7127 11.1391 18.6236 11.1716 18.5394 11.2365C18.4551 11.3014 18.4035 11.3849 18.3848 11.4869L16.4459 20.5302C16.4271 20.623 16.4412 20.7064 16.488 20.7807ZM22.7263 15.2434C22.4359 15.4567 22.0941 15.5634 21.7006 15.5634H20.0849L20.6188 13.073H22.3048C22.6888 13.073 22.9605 13.1472 23.1197 13.2956C23.2789 13.4347 23.3586 13.6388 23.3586 13.9078C23.3586 14.0283 23.3445 14.1675 23.3164 14.3251C23.2227 14.724 23.026 15.0301 22.7263 15.2434Z"
117
- fill="white"
118
- fillRule="evenodd"
163
+ <ContentCardFooter>
164
+ <RemoteImageGroup shape="circle" size={32}>
165
+ <RemoteImage source={{ uri: assets.eth.imageUrl }} />
166
+ <RemoteImage source={{ uri: assets.polygon.imageUrl }} />
167
+ </RemoteImageGroup>
168
+ <Button compact variant="tertiary">
169
+ Share
170
+ </Button>
171
+ </ContentCardFooter>
172
+ </ContentCard>
173
+
174
+ <ContentCard background="bgAlternate">
175
+ <ContentCardHeader thumbnail={assets.eth.imageUrl} title="CoinDesk" subtitle="News" />
176
+ <ContentCardBody
177
+ title="No Media with Background"
178
+ description="This card has no media element."
119
179
  />
120
- </g>
121
- <defs>
122
- <clipPath id="clip0_3440_332">
123
- <rect fill="white" height="32" width="32" />
124
- </clipPath>
125
- </defs>
126
- </svg>
180
+ <ContentCardFooter>
181
+ <HStack gap={4} justifyContent="space-between" paddingTop={0.5}>
182
+ <IconCounterButton accessibilityLabel="like, 99 likes" count={99} icon="heart" />
183
+ <IconCounterButton
184
+ accessibilityLabel="comment, 4200 comments"
185
+ count={4200}
186
+ icon="comment"
187
+ />
188
+ <IconCounterButton
189
+ accessibilityLabel="share, 32 shares"
190
+ count={32}
191
+ icon="arrowsHorizontal"
192
+ />
193
+ </HStack>
194
+ </ContentCardFooter>
195
+ </ContentCard>
196
+ </VStack>
127
197
  );
198
+ }
199
+ ```
200
+
201
+ ### Rewards Card Example
202
+
203
+ Example showing a rewards-style content card with claim button.
204
+
205
+ ```jsx
206
+ function Example() {
128
207
  return (
129
- <VStack bordered borderRadius="400" maxWidth={375}>
208
+ <VStack gap={2}>
130
209
  <ContentCard gap={3}>
131
210
  <ContentCardBody
132
- body={
133
- <Text as="p" font="body" paddingTop={0.5}>
211
+ title={
212
+ <Text font="body" style={{ paddingTop: 4 }}>
134
213
  Bitcoin Network Shatters Records With Hashrate Climbing to 464 EH/s
135
214
  </Text>
136
215
  }
137
216
  label={
138
217
  <HStack alignItems="flex-end" flexWrap="wrap" gap={0.5}>
139
- <Text as="p" font="label2" color="fgMuted" numberOfLines={1}>
218
+ <Text color="fgMuted" font="label2" numberOfLines={1}>
140
219
  BTC
141
220
  </Text>
142
- <Text font="label2" accessibilityLabel="Up 5.12%" as="p" color="fgPositive">
221
+ <Text color="fgPositive" font="label2">
143
222
  ↗ 5.12%
144
223
  </Text>
145
224
  </HStack>
146
225
  }
147
226
  media={
148
- <img
149
- alt=""
150
- aria-hidden="true"
151
- src="/img/components/card/content_card_rewards.png"
152
- style={{
153
- objectFit: 'cover',
154
- cursor: 'pointer',
155
- borderRadius: '24px',
156
- }}
227
+ <RemoteImage
228
+ accessibilityLabel="Rewards banner"
229
+ source={{ uri: ethBackground }}
230
+ style={{ borderRadius: 24 }}
157
231
  width="100%"
158
232
  />
159
233
  }
160
234
  />
161
235
  <ContentCardFooter>
162
236
  <HStack alignItems="center" gap={1}>
163
- <Box>{opIcon}</Box>
237
+ <Avatar src={assets.op.imageUrl} size="xl" />
164
238
  <VStack>
165
- <TextLegal as="span" color="fgMuted">
239
+ <Text color="fgMuted" font="legal">
166
240
  Reward
167
- </TextLegal>
168
- <Text as="span" font="headline">
169
- +$15 ACS
170
241
  </Text>
242
+ <Text font="headline">+$15 ACS</Text>
171
243
  </VStack>
172
244
  </HStack>
173
245
  <Button compact accessibilityLabel="Claim now" variant="secondary">
@@ -180,92 +252,66 @@ function Example() {
180
252
  }
181
253
  ```
182
254
 
183
- ### Custom
255
+ ### Accessibility
184
256
 
185
- Example of a content card with a tweet.
257
+ #### Interactive Cards
258
+
259
+ When making ContentCard interactive, wrap it in a `Pressable` component and handle accessibility carefully to avoid nested interactive elements.
260
+
261
+ **The Problem**: If you wrap ContentCard in a `Pressable` and also have interactive elements inside (like buttons), the card becomes a pressable container with nested interactive elements. This creates accessibility issues for VoiceOver users.
262
+
263
+ **The Solution**: Use `accessible={false}` on the Pressable wrapper and add a separate action button inside the card. This allows:
264
+
265
+ - Regular users to tap anywhere on the card
266
+ - VoiceOver users to navigate through card content and focus on individual interactive elements
267
+ - Switch Control users to activate the action button
186
268
 
187
269
  ```jsx
188
- function Example() {
189
- const anotherContentCard = (
190
- <ContentCard
270
+ function AccessibleCard() {
271
+ return (
272
+ <Pressable
273
+ accessible={false}
191
274
  background="bgAlternate"
192
- borderRadius="400"
193
- paddingHorizontal={1.5}
194
- paddingVertical={1.5}
275
+ borderRadius={500}
276
+ onPress={() => console.log('Card pressed - navigating...')}
195
277
  >
196
- <ContentCardHeader
197
- avatar={
198
- <Avatar
199
- alt="Mat Dryhurst"
200
- name="Mat Dryhurst"
201
- shape="circle"
202
- size="s"
203
- src="/img/card/content_card_custom_avatar_2.png"
204
- />
205
- }
206
- meta={
207
- <Box marginLeft={-1}>
208
- <Text as="span" font="label2" color="fgMuted" numberOfLines={1}>
209
- @matdryhurst・7 mo
210
- </Text>
211
- </Box>
212
- }
213
- title="Mat Dryhurst"
214
- />
215
- <ContentCardBody body="A bunch of massive youtubers are quitting, citing exhuastion and an algorithm that punishes a variety of output." />
216
- </ContentCard>
217
- );
218
- return (
219
- <VStack alignItems="center" maxWidth={375} bordered borderRadius={400}>
220
- <ContentCard>
221
- <ContentCardHeader
222
- avatar="/img/card/content_card_custom_avatar_1.png"
223
- meta={
224
- <Box marginLeft={-1}>
225
- <Text as="span" font="label2" color="fgMuted" numberOfLines={1}>
226
- ・News・5 hrs
227
- </Text>
228
- </Box>
229
- }
230
- title="Description"
231
- end={
232
- <IconButton
233
- transparent
234
- accessibilityLabel="More information about coinDesk card news"
235
- name="more"
236
- variant="secondary"
237
- />
238
- }
239
- />
278
+ <ContentCard maxWidth={375}>
279
+ <ContentCardHeader subtitle="News" thumbnail={ethBackground} title="CoinDesk" />
240
280
  <ContentCardBody
241
- body="Bitcoin Network Shatters Records With Hashrate Climbing to 464 EH/s"
242
- gap={1.5}
243
- label={
244
- <HStack alignItems="flex-end" flexWrap="wrap" gap={0.5}>
245
- <Text as="p" font="label2" color="fgMuted" numberOfLines={1}>
246
- BTC
247
- </Text>
248
- <Text font="label2" accessibilityLabel="Up 5.12%" as="p" color="fgPositive">
249
- ↗ 5.12%
250
- </Text>
251
- </HStack>
252
- }
253
- paddingBottom={3}
254
- paddingStart={5}
255
- >
256
- {anotherContentCard}
257
- </ContentCardBody>
258
- <ContentCardFooter>
259
- <IconCounterButton count={20} icon="heart" />
260
- <IconCounterButton count={40} icon="comment" />
261
- <IconCounterButton count={32} icon="wireTransfer" />
281
+ title="Accessible Interactive Card"
282
+ description="Card with both card-level press and internal action button"
283
+ />
284
+ <ContentCardFooter alignItems="center">
285
+ <Text color="fgMuted" font="legal">
286
+ 2 hours ago
287
+ </Text>
288
+ <Button
289
+ compact
290
+ variant="tertiary"
291
+ onPress={() => console.log('Button pressed - navigating...')}
292
+ >
293
+ View Details
294
+ </Button>
262
295
  </ContentCardFooter>
263
296
  </ContentCard>
264
- </VStack>
297
+ </Pressable>
265
298
  );
266
299
  }
267
300
  ```
268
301
 
302
+ **Key points:**
303
+
304
+ - Use `accessible={false}` on the Pressable to remove it from the accessibility tree, allowing VoiceOver to focus on child elements individually
305
+ - Add a `Button` in the footer that performs the same action as the card press for VoiceOver users
306
+
307
+ :::warning Avoid Nested Interactive Elements
308
+ When ContentCard is wrapped in an interactive Pressable, avoid placing too many interactive elements inside the card. Each interactive element should have a clear, distinct purpose. If the card has many actions, consider using a non-interactive card layout instead.
309
+ :::
310
+
311
+ #### Color Contrast
312
+
313
+ When customizing card backgrounds, ensure sufficient color contrast between text and background colors. WCAG AA requires a minimum contrast ratio of 4.5:1 for normal text.
314
+
269
315
  ## Props
270
316
 
271
317
  | Prop | Type | Required | Default | Description |