@coinbase/cds-mcp-server 8.17.1 → 8.17.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 +8 -0
- package/mcp-docs/mobile/components/Accordion.txt +189 -0
- package/mcp-docs/mobile/components/AccordionItem.txt +30 -0
- package/mcp-docs/mobile/components/Alert.txt +156 -0
- package/mcp-docs/mobile/components/AreaChart.txt +266 -0
- package/mcp-docs/mobile/components/Avatar.txt +196 -0
- package/mcp-docs/mobile/components/AvatarButton.txt +226 -0
- package/mcp-docs/mobile/components/Banner.txt +222 -0
- package/mcp-docs/mobile/components/BarChart.txt +816 -0
- package/mcp-docs/mobile/components/Box.txt +174 -0
- package/mcp-docs/mobile/components/BrowserBar.txt +147 -0
- package/mcp-docs/mobile/components/Button.txt +199 -0
- package/mcp-docs/mobile/components/ButtonGroup.txt +80 -0
- package/mcp-docs/mobile/components/Carousel.txt +1084 -0
- package/mcp-docs/mobile/components/CartesianChart.txt +826 -0
- package/mcp-docs/mobile/components/CellMedia.txt +71 -0
- package/mcp-docs/mobile/components/Checkbox.txt +246 -0
- package/mcp-docs/mobile/components/CheckboxCell.txt +202 -0
- package/mcp-docs/mobile/components/CheckboxGroup.txt +285 -0
- package/mcp-docs/mobile/components/Chip.txt +195 -0
- package/mcp-docs/mobile/components/Coachmark.txt +158 -0
- package/mcp-docs/mobile/components/Collapsible.txt +105 -0
- package/mcp-docs/mobile/components/ContainedAssetCard.txt +135 -0
- package/mcp-docs/mobile/components/ContentCard.txt +366 -0
- package/mcp-docs/mobile/components/ContentCardBody.txt +136 -0
- package/mcp-docs/mobile/components/ContentCardFooter.txt +128 -0
- package/mcp-docs/mobile/components/ContentCardHeader.txt +146 -0
- package/mcp-docs/mobile/components/ContentCell.txt +227 -0
- package/mcp-docs/mobile/components/ControlGroup.txt +444 -0
- package/mcp-docs/mobile/components/DatePicker.txt +497 -0
- package/mcp-docs/mobile/components/Divider.txt +139 -0
- package/mcp-docs/mobile/components/DotCount.txt +146 -0
- package/mcp-docs/mobile/components/DotStatusColor.txt +59 -0
- package/mcp-docs/mobile/components/DotSymbol.txt +135 -0
- package/mcp-docs/mobile/components/Fallback.txt +158 -0
- package/mcp-docs/mobile/components/FloatingAssetCard.txt +156 -0
- package/mcp-docs/mobile/components/HStack.txt +235 -0
- package/mcp-docs/mobile/components/HeroSquare.txt +48 -0
- package/mcp-docs/mobile/components/Icon.txt +52 -0
- package/mcp-docs/mobile/components/IconButton.txt +269 -0
- package/mcp-docs/mobile/components/InputChip.txt +188 -0
- package/mcp-docs/mobile/components/Interactable.txt +187 -0
- package/mcp-docs/mobile/components/LineChart.txt +1325 -0
- package/mcp-docs/mobile/components/Link.txt +292 -0
- package/mcp-docs/mobile/components/ListCell.txt +391 -0
- package/mcp-docs/mobile/components/LogoMark.txt +85 -0
- package/mcp-docs/mobile/components/LogoWordMark.txt +94 -0
- package/mcp-docs/mobile/components/Lottie.txt +139 -0
- package/mcp-docs/mobile/components/LottieStatusAnimation.txt +47 -0
- package/mcp-docs/mobile/components/Modal.txt +84 -0
- package/mcp-docs/mobile/components/ModalBody.txt +34 -0
- package/mcp-docs/mobile/components/ModalFooter.txt +25 -0
- package/mcp-docs/mobile/components/ModalHeader.txt +28 -0
- package/mcp-docs/mobile/components/MultiContentModule.txt +380 -0
- package/mcp-docs/mobile/components/NavigationTitle.txt +132 -0
- package/mcp-docs/mobile/components/NavigationTitleSelect.txt +142 -0
- package/mcp-docs/mobile/components/NudgeCard.txt +90 -0
- package/mcp-docs/mobile/components/Numpad.txt +341 -0
- package/mcp-docs/mobile/components/Overlay.txt +152 -0
- package/mcp-docs/mobile/components/PageFooter.txt +161 -0
- package/mcp-docs/mobile/components/PageHeader.txt +186 -0
- package/mcp-docs/mobile/components/PeriodSelector.txt +408 -0
- package/mcp-docs/mobile/components/Pictogram.txt +48 -0
- package/mcp-docs/mobile/components/Point.txt +205 -0
- package/mcp-docs/mobile/components/PortalProvider.txt +79 -0
- package/mcp-docs/mobile/components/Pressable.txt +211 -0
- package/mcp-docs/mobile/components/ProgressBar.txt +130 -0
- package/mcp-docs/mobile/components/ProgressBarWithFixedLabels.txt +161 -0
- package/mcp-docs/mobile/components/ProgressBarWithFloatLabel.txt +138 -0
- package/mcp-docs/mobile/components/ProgressCircle.txt +237 -0
- package/mcp-docs/mobile/components/Radio.txt +242 -0
- package/mcp-docs/mobile/components/RadioCell.txt +202 -0
- package/mcp-docs/mobile/components/RadioGroup.txt +282 -0
- package/mcp-docs/mobile/components/ReferenceLine.txt +153 -0
- package/mcp-docs/mobile/components/RemoteImage.txt +106 -0
- package/mcp-docs/mobile/components/RemoteImageGroup.txt +61 -0
- package/mcp-docs/mobile/components/RollingNumber.txt +789 -0
- package/mcp-docs/mobile/components/Scrubber.txt +204 -0
- package/mcp-docs/mobile/components/SearchInput.txt +192 -0
- package/mcp-docs/mobile/components/SectionHeader.txt +205 -0
- package/mcp-docs/mobile/components/SegmentedTabs.txt +316 -0
- package/mcp-docs/mobile/components/Select.txt +212 -0
- package/mcp-docs/mobile/components/SelectChip.txt +324 -0
- package/mcp-docs/mobile/components/SelectOption.txt +85 -0
- package/mcp-docs/mobile/components/SlideButton.txt +331 -0
- package/mcp-docs/mobile/components/Spacer.txt +84 -0
- package/mcp-docs/mobile/components/Sparkline.txt +123 -0
- package/mcp-docs/mobile/components/SparklineGradient.txt +107 -0
- package/mcp-docs/mobile/components/SparklineInteractive.txt +157 -0
- package/mcp-docs/mobile/components/SparklineInteractiveHeader.txt +73 -0
- package/mcp-docs/mobile/components/Spinner.txt +49 -0
- package/mcp-docs/mobile/components/SpotIcon.txt +48 -0
- package/mcp-docs/mobile/components/SpotRectangle.txt +48 -0
- package/mcp-docs/mobile/components/SpotSquare.txt +48 -0
- package/mcp-docs/mobile/components/Stepper.txt +528 -0
- package/mcp-docs/mobile/components/SubBrandLogoMark.txt +126 -0
- package/mcp-docs/mobile/components/SubBrandLogoWordMark.txt +126 -0
- package/mcp-docs/mobile/components/Switch.txt +98 -0
- package/mcp-docs/mobile/components/TabIndicator.txt +49 -0
- package/mcp-docs/mobile/components/TabLabel.txt +154 -0
- package/mcp-docs/mobile/components/TabNavigation.txt +147 -0
- package/mcp-docs/mobile/components/TabbedChips.txt +143 -0
- package/mcp-docs/mobile/components/Tabs.txt +191 -0
- package/mcp-docs/mobile/components/Tag.txt +301 -0
- package/mcp-docs/mobile/components/Text.txt +212 -0
- package/mcp-docs/mobile/components/TextInput.txt +718 -0
- package/mcp-docs/mobile/components/ThemeProvider.txt +133 -0
- package/mcp-docs/mobile/components/Toast.txt +197 -0
- package/mcp-docs/mobile/components/Tooltip.txt +60 -0
- package/mcp-docs/mobile/components/TopNavBar.txt +162 -0
- package/mcp-docs/mobile/components/Tour.txt +159 -0
- package/mcp-docs/mobile/components/Tray.txt +253 -0
- package/mcp-docs/mobile/components/UpsellCard.txt +322 -0
- package/mcp-docs/mobile/components/VStack.txt +223 -0
- package/mcp-docs/mobile/components/XAxis.txt +622 -0
- package/mcp-docs/mobile/components/YAxis.txt +568 -0
- package/mcp-docs/mobile/getting-started/introduction.txt +99 -0
- package/mcp-docs/mobile/getting-started/mcp-server.txt +94 -0
- package/mcp-docs/mobile/getting-started/playground.txt +25 -0
- package/mcp-docs/mobile/hooks/useDimensions.txt +47 -0
- package/mcp-docs/mobile/hooks/useOverlayContentContext.txt +215 -0
- package/mcp-docs/mobile/hooks/useTheme.txt +110 -0
- package/mcp-docs/mobile/routes.txt +132 -0
- package/mcp-docs/web/components/Accordion.txt +190 -0
- package/mcp-docs/web/components/AccordionItem.txt +32 -0
- package/mcp-docs/web/components/Alert.txt +165 -0
- package/mcp-docs/web/components/AreaChart.txt +511 -0
- package/mcp-docs/web/components/Avatar.txt +212 -0
- package/mcp-docs/web/components/AvatarButton.txt +241 -0
- package/mcp-docs/web/components/Banner.txt +227 -0
- package/mcp-docs/web/components/BarChart.txt +1268 -0
- package/mcp-docs/web/components/Box.txt +176 -0
- package/mcp-docs/web/components/Button.txt +213 -0
- package/mcp-docs/web/components/ButtonGroup.txt +80 -0
- package/mcp-docs/web/components/Calendar.txt +182 -0
- package/mcp-docs/web/components/Carousel.txt +1576 -0
- package/mcp-docs/web/components/CartesianChart.txt +1045 -0
- package/mcp-docs/web/components/CellMedia.txt +57 -0
- package/mcp-docs/web/components/Checkbox.txt +189 -0
- package/mcp-docs/web/components/CheckboxCell.txt +203 -0
- package/mcp-docs/web/components/CheckboxGroup.txt +220 -0
- package/mcp-docs/web/components/Chip.txt +197 -0
- package/mcp-docs/web/components/Coachmark.txt +189 -0
- package/mcp-docs/web/components/Collapsible.txt +120 -0
- package/mcp-docs/web/components/ContainedAssetCard.txt +233 -0
- package/mcp-docs/web/components/ContentCard.txt +368 -0
- package/mcp-docs/web/components/ContentCardBody.txt +138 -0
- package/mcp-docs/web/components/ContentCardFooter.txt +130 -0
- package/mcp-docs/web/components/ContentCardHeader.txt +148 -0
- package/mcp-docs/web/components/ContentCell.txt +220 -0
- package/mcp-docs/web/components/ControlGroup.txt +437 -0
- package/mcp-docs/web/components/DatePicker.txt +506 -0
- package/mcp-docs/web/components/Divider.txt +144 -0
- package/mcp-docs/web/components/DotCount.txt +150 -0
- package/mcp-docs/web/components/DotStatusColor.txt +59 -0
- package/mcp-docs/web/components/DotSymbol.txt +138 -0
- package/mcp-docs/web/components/Dropdown.txt +120 -0
- package/mcp-docs/web/components/Fallback.txt +164 -0
- package/mcp-docs/web/components/FloatingAssetCard.txt +251 -0
- package/mcp-docs/web/components/FullscreenAlert.txt +70 -0
- package/mcp-docs/web/components/FullscreenModal.txt +146 -0
- package/mcp-docs/web/components/FullscreenModalLayout.txt +188 -0
- package/mcp-docs/web/components/Grid.txt +237 -0
- package/mcp-docs/web/components/GridColumn.txt +210 -0
- package/mcp-docs/web/components/HStack.txt +237 -0
- package/mcp-docs/web/components/HeroSquare.txt +49 -0
- package/mcp-docs/web/components/Icon.txt +146 -0
- package/mcp-docs/web/components/IconButton.txt +391 -0
- package/mcp-docs/web/components/InputChip.txt +188 -0
- package/mcp-docs/web/components/Interactable.txt +194 -0
- package/mcp-docs/web/components/LineChart.txt +1577 -0
- package/mcp-docs/web/components/Link.txt +244 -0
- package/mcp-docs/web/components/ListCell.txt +397 -0
- package/mcp-docs/web/components/LogoMark.txt +85 -0
- package/mcp-docs/web/components/LogoWordMark.txt +94 -0
- package/mcp-docs/web/components/Lottie.txt +158 -0
- package/mcp-docs/web/components/LottieStatusAnimation.txt +58 -0
- package/mcp-docs/web/components/MediaQueryProvider.txt +109 -0
- package/mcp-docs/web/components/Modal.txt +193 -0
- package/mcp-docs/web/components/ModalBody.txt +118 -0
- package/mcp-docs/web/components/ModalFooter.txt +120 -0
- package/mcp-docs/web/components/ModalHeader.txt +124 -0
- package/mcp-docs/web/components/MultiContentModule.txt +382 -0
- package/mcp-docs/web/components/NavigationBar.txt +103 -0
- package/mcp-docs/web/components/NavigationTitle.txt +26 -0
- package/mcp-docs/web/components/NavigationTitleSelect.txt +46 -0
- package/mcp-docs/web/components/NudgeCard.txt +182 -0
- package/mcp-docs/web/components/Overlay.txt +172 -0
- package/mcp-docs/web/components/PageFooter.txt +185 -0
- package/mcp-docs/web/components/PageHeader.txt +244 -0
- package/mcp-docs/web/components/Pagination.txt +500 -0
- package/mcp-docs/web/components/PeriodSelector.txt +704 -0
- package/mcp-docs/web/components/Pictogram.txt +49 -0
- package/mcp-docs/web/components/Point.txt +461 -0
- package/mcp-docs/web/components/PortalProvider.txt +77 -0
- package/mcp-docs/web/components/Pressable.txt +194 -0
- package/mcp-docs/web/components/ProgressBar.txt +164 -0
- package/mcp-docs/web/components/ProgressBarWithFixedLabels.txt +213 -0
- package/mcp-docs/web/components/ProgressBarWithFloatLabel.txt +182 -0
- package/mcp-docs/web/components/ProgressCircle.txt +444 -0
- package/mcp-docs/web/components/Radio.txt +220 -0
- package/mcp-docs/web/components/RadioCell.txt +216 -0
- package/mcp-docs/web/components/RadioGroup.txt +289 -0
- package/mcp-docs/web/components/ReferenceLine.txt +452 -0
- package/mcp-docs/web/components/RemoteImage.txt +166 -0
- package/mcp-docs/web/components/RemoteImageGroup.txt +87 -0
- package/mcp-docs/web/components/RollingNumber.txt +1022 -0
- package/mcp-docs/web/components/Scrubber.txt +232 -0
- package/mcp-docs/web/components/SearchInput.txt +118 -0
- package/mcp-docs/web/components/SectionHeader.txt +218 -0
- package/mcp-docs/web/components/SegmentedTabs.txt +325 -0
- package/mcp-docs/web/components/Select.txt +225 -0
- package/mcp-docs/web/components/SelectChip.txt +315 -0
- package/mcp-docs/web/components/SelectOption.txt +166 -0
- package/mcp-docs/web/components/Sidebar.txt +350 -0
- package/mcp-docs/web/components/SidebarItem.txt +132 -0
- package/mcp-docs/web/components/SidebarMoreMenu.txt +31 -0
- package/mcp-docs/web/components/Spacer.txt +174 -0
- package/mcp-docs/web/components/Sparkline.txt +123 -0
- package/mcp-docs/web/components/SparklineGradient.txt +107 -0
- package/mcp-docs/web/components/SparklineInteractive.txt +154 -0
- package/mcp-docs/web/components/SparklineInteractiveHeader.txt +77 -0
- package/mcp-docs/web/components/Spinner.txt +129 -0
- package/mcp-docs/web/components/SpotIcon.txt +49 -0
- package/mcp-docs/web/components/SpotRectangle.txt +49 -0
- package/mcp-docs/web/components/SpotSquare.txt +49 -0
- package/mcp-docs/web/components/Stepper.txt +683 -0
- package/mcp-docs/web/components/SubBrandLogoMark.txt +126 -0
- package/mcp-docs/web/components/SubBrandLogoWordMark.txt +126 -0
- package/mcp-docs/web/components/Switch.txt +86 -0
- package/mcp-docs/web/components/TabIndicator.txt +49 -0
- package/mcp-docs/web/components/TabLabel.txt +159 -0
- package/mcp-docs/web/components/TabNavigation.txt +160 -0
- package/mcp-docs/web/components/TabbedChips.txt +156 -0
- package/mcp-docs/web/components/Table.txt +368 -0
- package/mcp-docs/web/components/TableBody.txt +84 -0
- package/mcp-docs/web/components/TableCaption.txt +103 -0
- package/mcp-docs/web/components/TableCell.txt +166 -0
- package/mcp-docs/web/components/TableCellFallback.txt +98 -0
- package/mcp-docs/web/components/TableFooter.txt +84 -0
- package/mcp-docs/web/components/TableHeader.txt +101 -0
- package/mcp-docs/web/components/TableRow.txt +141 -0
- package/mcp-docs/web/components/Tabs.txt +213 -0
- package/mcp-docs/web/components/Tag.txt +305 -0
- package/mcp-docs/web/components/Text.txt +233 -0
- package/mcp-docs/web/components/TextInput.txt +653 -0
- package/mcp-docs/web/components/ThemeProvider.txt +200 -0
- package/mcp-docs/web/components/TileButton.txt +159 -0
- package/mcp-docs/web/components/Toast.txt +204 -0
- package/mcp-docs/web/components/Tooltip.txt +90 -0
- package/mcp-docs/web/components/Tour.txt +180 -0
- package/mcp-docs/web/components/Tray.txt +289 -0
- package/mcp-docs/web/components/UpsellCard.txt +320 -0
- package/mcp-docs/web/components/VStack.txt +225 -0
- package/mcp-docs/web/components/XAxis.txt +620 -0
- package/mcp-docs/web/components/YAxis.txt +549 -0
- package/mcp-docs/web/getting-started/introduction.txt +99 -0
- package/mcp-docs/web/getting-started/mcp-server.txt +94 -0
- package/mcp-docs/web/getting-started/playground.txt +25 -0
- package/mcp-docs/web/hooks/useBreakpoints.txt +33 -0
- package/mcp-docs/web/hooks/useDimensions.txt +55 -0
- package/mcp-docs/web/hooks/useHasMounted.txt +55 -0
- package/mcp-docs/web/hooks/useIsoEffect.txt +42 -0
- package/mcp-docs/web/hooks/useMediaQuery.txt +94 -0
- package/mcp-docs/web/hooks/useOverlayContentContext.txt +217 -0
- package/mcp-docs/web/hooks/useScrollBlocker.txt +63 -0
- package/mcp-docs/web/hooks/useTheme.txt +105 -0
- package/mcp-docs/web/routes.txt +155 -0
- package/package.json +1 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: mcp-server
|
|
3
|
+
title: MCP Server
|
|
4
|
+
hide_title: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
import { MDXSection } from '@site/src/components/page/MDXSection';
|
|
8
|
+
import { MDXArticle } from '@site/src/components/page/MDXArticle';
|
|
9
|
+
import { ContentHeader } from '@site/src/components/page/ContentHeader';
|
|
10
|
+
|
|
11
|
+
<ContentHeader
|
|
12
|
+
title="MCP Server"
|
|
13
|
+
description="CDS includes an MCP Server that is automatically updated with each new version of our libraries."
|
|
14
|
+
/>
|
|
15
|
+
|
|
16
|
+
<MDXSection>
|
|
17
|
+
<MDXArticle>
|
|
18
|
+
## What is it?
|
|
19
|
+
|
|
20
|
+
The CDS MCP Server provides CDS context to LLMs, allowing AI models to understand and work with CDS APIs and components.
|
|
21
|
+
|
|
22
|
+
From [modelcontextprotocol.io](https://modelcontextprotocol.io/docs/getting-started/intro):
|
|
23
|
+
|
|
24
|
+
> _MCP is an open protocol that standardizes how applications provide context to large language models (LLMs). MCP provides a standardized way to connect AI models to different data sources and tools. MCP enables you build agents and complex workflows on top of LLMs and connects your models with the world._
|
|
25
|
+
|
|
26
|
+
</MDXArticle>
|
|
27
|
+
</MDXSection>
|
|
28
|
+
|
|
29
|
+
<MDXSection>
|
|
30
|
+
<MDXArticle>
|
|
31
|
+
## Basic installation
|
|
32
|
+
|
|
33
|
+
The CDS MCP server is published in the `@coinbase/cds-mcp-server` package.
|
|
34
|
+
|
|
35
|
+
This package is automatically included as a dependency of the CDS libraries, ensuring the CDS library and CDS MCP Server versions match. You do not need to install it separately if you are using the CDS libraries.
|
|
36
|
+
|
|
37
|
+
</MDXArticle>
|
|
38
|
+
<MDXArticle>
|
|
39
|
+
|
|
40
|
+
### First time setup
|
|
41
|
+
|
|
42
|
+
Run the setup command to install the CDS MCP Server for Cursor or Claude Code, then enable the MCP server in your agent.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npx --package=@coinbase/cds-mcp-server cds-mcp-setup
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
:::tip
|
|
49
|
+
Make sure to enable the MCP server after installation.<br />
|
|
50
|
+
See the [Cursor docs here](https://cursor.com/docs/context/mcp#using-mcp-in-chat) and the [Claude Code docs here](https://docs.claude.com/en/docs/claude-code/mcp#managing-your-servers) for more information.
|
|
51
|
+
:::
|
|
52
|
+
|
|
53
|
+
</MDXArticle>
|
|
54
|
+
<MDXArticle>
|
|
55
|
+
|
|
56
|
+
### Using the MCP server
|
|
57
|
+
|
|
58
|
+
Once the CDS MCP Server is enabled in your agent, the agent will automatically be able to use the CDS MCP tools to interact with the CDS APIs and components.
|
|
59
|
+
|
|
60
|
+
Try asking a question like "How can I add an icon to a CDS Button?" or "How can I customize the CDS Stepper component behavior?"
|
|
61
|
+
|
|
62
|
+
</MDXArticle>
|
|
63
|
+
</MDXSection>
|
|
64
|
+
|
|
65
|
+
<MDXSection>
|
|
66
|
+
<MDXArticle>
|
|
67
|
+
## Advanced installation
|
|
68
|
+
|
|
69
|
+
To install the MCP server separately as a standalone package and add it as a dependency to your project, run the following command:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npm install @coinbase/cds-mcp-server
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Alternatively, if you are using Yarn:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
yarn add @coinbase/cds-mcp-server
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
:::tip
|
|
82
|
+
Avoid installing mismatched versions of the CDS libraries and the CDS MCP Server.
|
|
83
|
+
:::
|
|
84
|
+
|
|
85
|
+
### Executing with npx directly
|
|
86
|
+
|
|
87
|
+
You can also execute the MCP server with npx directly, but it will not have the associated CDS agent rules installed.
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npx @coinbase/cds-mcp-server
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
</MDXArticle>
|
|
94
|
+
</MDXSection>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: playground
|
|
3
|
+
title: Playground
|
|
4
|
+
hide_title: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
import { MDXSection } from '@site/src/components/page/MDXSection';
|
|
8
|
+
import { MDXArticle } from '@site/src/components/page/MDXArticle';
|
|
9
|
+
import { ContentHeader } from '@site/src/components/page/ContentHeader';
|
|
10
|
+
import { PlaygroundBanner } from '@site/src/components/page/ComponentBanner/PlaygroundBanner';
|
|
11
|
+
import { ShareablePlayground } from '@site/src/components/page/ShareablePlayground';
|
|
12
|
+
|
|
13
|
+
<ContentHeader
|
|
14
|
+
title="Playground"
|
|
15
|
+
description="Live code playground for testing and sharing CDS components and code examples. All CDS components and hooks and all React exports are available to use in the playground without importing them. You must call render() to render your code."
|
|
16
|
+
banner={<PlaygroundBanner />}
|
|
17
|
+
/>
|
|
18
|
+
|
|
19
|
+
<MDXSection>
|
|
20
|
+
<MDXArticle>
|
|
21
|
+
|
|
22
|
+
<ShareablePlayground />
|
|
23
|
+
|
|
24
|
+
</MDXArticle>
|
|
25
|
+
</MDXSection>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
|
|
2
|
+
# useBreakpoints
|
|
3
|
+
Returns an object with a boolean for each breakpoint of the window. Useful for conditionally rendering components or component trees based on the current window breakpoint.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { useBreakpoints } from '@coinbase/cds-web/hooks/useBreakpoints'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
import { JSONCodeBlock } from '@site/src/components/page/JSONCodeBlock';
|
|
14
|
+
import { useBreakpoints } from '@coinbase/cds-web/hooks/useBreakpoints';
|
|
15
|
+
|
|
16
|
+
### Basic usage
|
|
17
|
+
|
|
18
|
+
Use the `useBreakpoints` hook to conditionally render components or component trees based on the current window breakpoint.
|
|
19
|
+
|
|
20
|
+
[See how breakpoints are defined in the `media` object →](https://github.com/coinbase/cds/blob/master/packages/web/src/styles/media.ts)
|
|
21
|
+
|
|
22
|
+
:::warning
|
|
23
|
+
Do not use `useBreakpoints` for responsive styles. Use CSS media queries or [the `StyleProps` API](/getting-started/styling#responsive-styles) for responsive styles.
|
|
24
|
+
:::
|
|
25
|
+
|
|
26
|
+
```tsx live
|
|
27
|
+
() => {
|
|
28
|
+
const breakpoints = useBreakpoints();
|
|
29
|
+
return <JSONCodeBlock json={breakpoints} />;
|
|
30
|
+
};
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
|
|
2
|
+
# useDimensions
|
|
3
|
+
Measures an element's dimensions using ResizeObserver.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { useDimensions } from '@coinbase/cds-web/hooks/useDimensions'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
### Basic usage
|
|
14
|
+
|
|
15
|
+
```tsx live
|
|
16
|
+
function Example() {
|
|
17
|
+
const ref = useRef(null);
|
|
18
|
+
const { width, height } = useDimensions({ ref });
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<Box ref={ref} padding={3} background="bgAlternate" borderRadius={300} width="100%">
|
|
22
|
+
<TextHeadline>
|
|
23
|
+
This box is {width}px wide and {height}px tall
|
|
24
|
+
</TextHeadline>
|
|
25
|
+
</Box>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### With Breakpoints
|
|
31
|
+
|
|
32
|
+
```tsx live
|
|
33
|
+
function Example() {
|
|
34
|
+
const ref = useRef(null);
|
|
35
|
+
const { width, currentBreakpoint } = useDimensions({
|
|
36
|
+
ref,
|
|
37
|
+
breakpoints: {
|
|
38
|
+
small: 300,
|
|
39
|
+
medium: 400,
|
|
40
|
+
large: 500,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<Box ref={ref} padding={3} background="bgAlternate" borderRadius={300} width="100%">
|
|
46
|
+
<VStack gap={2}>
|
|
47
|
+
<TextHeadline>Width: {width}px</TextHeadline>
|
|
48
|
+
<TextHeadline>Current breakpoint: {currentBreakpoint || 'none'}</TextHeadline>
|
|
49
|
+
</VStack>
|
|
50
|
+
</Box>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
|
|
2
|
+
# useHasMounted
|
|
3
|
+
Returns a boolean indicating if the component has mounted.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { useHasMounted } from '@coinbase/cds-web/hooks/useHasMounted'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
`useHasMounted` should be used when conditionally rendering components or styles in SSR or SSG environments.
|
|
14
|
+
|
|
15
|
+
We recommend using `useHasMounted` whenever you use [useBreakpoints](/hooks/useBreakpoints) or any other hooks that rely on the window object to conditionally render content. This combination can be used to prevent cumulative layout shifts (CLS). This is called two pass rendering and ensures that the component has been mounted and the window object is present before painting the DOM.
|
|
16
|
+
|
|
17
|
+
```jsx
|
|
18
|
+
const { isPhone } = useBreakpoints();
|
|
19
|
+
const hasMounted = useHasMounted();
|
|
20
|
+
|
|
21
|
+
// in component render
|
|
22
|
+
{
|
|
23
|
+
hasMounted && isPhone && <TextHeadline as="h3">Welcome {username}!</TextHeadline>;
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Basic usage
|
|
28
|
+
|
|
29
|
+
```tsx live
|
|
30
|
+
function Example() {
|
|
31
|
+
const hasMounted = useHasMounted();
|
|
32
|
+
|
|
33
|
+
return <TextHeadline>Component has {hasMounted ? 'mounted' : 'not mounted'}</TextHeadline>;
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Preventing Hydration Mismatch
|
|
38
|
+
|
|
39
|
+
```tsx live
|
|
40
|
+
function Example() {
|
|
41
|
+
const hasMounted = useHasMounted();
|
|
42
|
+
const [currentTime, setCurrentTime] = useState('');
|
|
43
|
+
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
// Only run client-side code after mounting
|
|
46
|
+
if (hasMounted) {
|
|
47
|
+
setCurrentTime(new Date().toLocaleTimeString());
|
|
48
|
+
}
|
|
49
|
+
}, [hasMounted]);
|
|
50
|
+
|
|
51
|
+
return <TextHeadline>{hasMounted ? `Current time: ${currentTime}` : 'Loading...'}</TextHeadline>;
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
|
|
2
|
+
# useIsoEffect
|
|
3
|
+
A safe way of calling useLayoutEffect only on the client. Does nothing on the server.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { useIsoEffect } from '@coinbase/cds-web/hooks/useIsoEffect'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
### Usage
|
|
14
|
+
|
|
15
|
+
```tsx live
|
|
16
|
+
function Example() {
|
|
17
|
+
const [position, setPosition] = useState({ x: 0, y: 0 });
|
|
18
|
+
|
|
19
|
+
useIsoEffect(() => {
|
|
20
|
+
const updatePosition = (e: MouseEvent) => {
|
|
21
|
+
setPosition({ x: e.clientX, y: e.clientY });
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
window.addEventListener('mousemove', updatePosition);
|
|
25
|
+
|
|
26
|
+
// Cleanup function to remove event listener
|
|
27
|
+
return () => {
|
|
28
|
+
window.removeEventListener('mousemove', updatePosition);
|
|
29
|
+
};
|
|
30
|
+
}, []); // Empty deps array means this effect runs once on mount
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<VStack gap={2}>
|
|
34
|
+
<TextHeadline>Mouse Position</TextHeadline>
|
|
35
|
+
<Text>X: {position.x}</Text>
|
|
36
|
+
<Text>Y: {position.y}</Text>
|
|
37
|
+
</VStack>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
|
|
2
|
+
# useMediaQuery
|
|
3
|
+
Subscribes to window.matchMedia changes with SSR support.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { useMediaQuery } from '@coinbase/cds-web/hooks/useMediaQuery'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
### Basic usage
|
|
14
|
+
|
|
15
|
+
Use the `useMediaQuery` hook to call `window.matchMedia` with SSR support. It must be used within a MediaQueryProvider component.
|
|
16
|
+
|
|
17
|
+
This hook is ideal for conditional rendering based on viewport size, user preferences, or other media features.
|
|
18
|
+
|
|
19
|
+
It subscribes to a single state shared by all media queries to ensure Suspense works correctly.
|
|
20
|
+
|
|
21
|
+
[See the MediaQueryProvider docs here →](/components/other/MediaQueryProvider)
|
|
22
|
+
|
|
23
|
+
:::warning
|
|
24
|
+
Do not use `useMediaQuery` for responsive styles. Use CSS media queries or [the `StyleProps` API](/getting-started/styling#responsive-styles) for responsive styles.
|
|
25
|
+
:::
|
|
26
|
+
|
|
27
|
+
```tsx live
|
|
28
|
+
() => {
|
|
29
|
+
const Page = () => {
|
|
30
|
+
const isMobile = useMediaQuery('(max-width: 767px)');
|
|
31
|
+
const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
|
|
32
|
+
return <JSONCodeBlock json={{ isMobile, prefersDarkMode }} />;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const App = () => (
|
|
36
|
+
<MediaQueryProvider>
|
|
37
|
+
<Page />
|
|
38
|
+
</MediaQueryProvider>
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
return <App />;
|
|
42
|
+
};
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### SSR support
|
|
46
|
+
|
|
47
|
+
The `useMediaQuery` hook integrates with the MediaQueryProvider `defaultValues` to provide consistent behavior between server and client rendering.
|
|
48
|
+
|
|
49
|
+
On the client the native `window.matchMedia` API is used. On the server the hook solves the `window.matchMedia` queries by comparing to the MediaQueryProvider `defaultValues`.
|
|
50
|
+
|
|
51
|
+
The comparison against `defaultValues` during SSR is limited: it cannot solve highly complex media queries. If a complex query cannot be solved during SSR the hook will simply return `false`, and the query can still be solved by `window.matchMedia` on the client.
|
|
52
|
+
|
|
53
|
+
:::tip
|
|
54
|
+
You can populate the MediaQueryProvider `defaultValues` with user preferences, cookies, etc. to ensure the correct styles are applied on the server.
|
|
55
|
+
:::
|
|
56
|
+
|
|
57
|
+
#### Simple queries that can be solved during SSR
|
|
58
|
+
|
|
59
|
+
- Simple media queries
|
|
60
|
+
- `width`, `min-width`, `max-width`, `height`, `min-height`, and `max-height` with pixel or em units
|
|
61
|
+
- `prefers-contrast` and `prefers-color-scheme`
|
|
62
|
+
- Logical `and` operator
|
|
63
|
+
|
|
64
|
+
#### Complex queries that cannot be solved during SSR
|
|
65
|
+
|
|
66
|
+
- Multiple comma-delimited values
|
|
67
|
+
- Logical `not` and `or` operators
|
|
68
|
+
- Mathematical `<=` and `>=` operators
|
|
69
|
+
- Complex or nested queries
|
|
70
|
+
- Other media types or features
|
|
71
|
+
|
|
72
|
+
[See the MediaQueryProvider SSR docs here →](/components/other/MediaQueryProvider#ssr-support)
|
|
73
|
+
|
|
74
|
+
### Complex queries on the client
|
|
75
|
+
|
|
76
|
+
Complex queries cannot be solved during SSR. They are solved on the client by calling `window.matchMedia`.
|
|
77
|
+
|
|
78
|
+
```tsx live
|
|
79
|
+
() => {
|
|
80
|
+
const isPortrait = useMediaQuery('(orientation: portrait)');
|
|
81
|
+
const isHighDPI = useMediaQuery('(min-resolution: 2dppx)');
|
|
82
|
+
const isTouch = useMediaQuery('(pointer: coarse)');
|
|
83
|
+
const isMediumHeight = useMediaQuery('(min-height: 600px) and (max-height: 900px)');
|
|
84
|
+
|
|
85
|
+
const complexQuery = useMediaQuery(
|
|
86
|
+
`((width >= 1200px) and (orientation: landscape)),
|
|
87
|
+
(width < 560px) or ((width > 768px) and (width < 900px))`,
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
return <JSONCodeBlock json={{ isPortrait, isHighDPI, isTouch, isMediumHeight, complexQuery }} />;
|
|
91
|
+
};
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
|
|
2
|
+
# useOverlayContentContext
|
|
3
|
+
A React context and hook for detecting if components are rendered inside overlay containers like modals, drawers, tours, and trays.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { OverlayContentContext, useOverlayContentContext } from '@coinbase/cds-common/overlays/OverlayContentContext'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
The `useOverlayContentContext` hook provides information about whether a component is rendered inside various types of overlay containers. This is useful for conditional rendering and styling based on the overlay context.
|
|
14
|
+
|
|
15
|
+
### Basic usage
|
|
16
|
+
|
|
17
|
+
```tsx live
|
|
18
|
+
function ExampleComponent() {
|
|
19
|
+
const { isOverlay, isModal, isDrawer, isTour } = useOverlayContentContext();
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<VStack gap={2}>
|
|
23
|
+
<TextHeadline>Overlay Context Information</TextHeadline>
|
|
24
|
+
<Text>Is inside any overlay: {isOverlay ? 'Yes' : 'No'}</Text>
|
|
25
|
+
<Text>Is inside modal: {isModal ? 'Yes' : 'No'}</Text>
|
|
26
|
+
<Text>Is inside drawer/tray: {isDrawer ? 'Yes' : 'No'}</Text>
|
|
27
|
+
<Text>Is inside tour: {isTour ? 'Yes' : 'No'}</Text>
|
|
28
|
+
</VStack>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Real Modal Example
|
|
34
|
+
|
|
35
|
+
Click the button below to open a modal and see how the hook behaves inside vs outside:
|
|
36
|
+
|
|
37
|
+
```tsx live
|
|
38
|
+
function ModalExample() {
|
|
39
|
+
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
40
|
+
|
|
41
|
+
const ExampleComponent = () => {
|
|
42
|
+
const { isOverlay, isModal, isDrawer, isTour } = useOverlayContentContext();
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<VStack gap={2}>
|
|
46
|
+
<TextHeadline>Overlay Context Information</TextHeadline>
|
|
47
|
+
<Text>Is inside any overlay: {isOverlay ? 'Yes' : 'No'}</Text>
|
|
48
|
+
<Text>Is inside modal: {isModal ? 'Yes' : 'No'}</Text>
|
|
49
|
+
<Text>Is inside drawer/tray: {isDrawer ? 'Yes' : 'No'}</Text>
|
|
50
|
+
<Text>Is inside tour: {isTour ? 'Yes' : 'No'}</Text>
|
|
51
|
+
</VStack>
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<VStack gap={3}>
|
|
57
|
+
<VStack gap={2} padding={3} background="bgSecondary" borderRadius={400}>
|
|
58
|
+
<TextHeadline>Outside Modal</TextHeadline>
|
|
59
|
+
<ExampleComponent />
|
|
60
|
+
</VStack>
|
|
61
|
+
|
|
62
|
+
<Button onClick={() => setIsModalOpen(true)}>Open Modal</Button>
|
|
63
|
+
|
|
64
|
+
<Modal visible={isModalOpen} onRequestClose={() => setIsModalOpen(false)}>
|
|
65
|
+
<ModalHeader closeAccessibilityLabel="Close" title="Modal with Context Hook" />
|
|
66
|
+
<ModalBody>
|
|
67
|
+
<VStack gap={3}>
|
|
68
|
+
<Text>
|
|
69
|
+
This content is rendered inside a modal. Notice how the context values change:
|
|
70
|
+
</Text>
|
|
71
|
+
<VStack gap={2} padding={3} background="bgAlternate" borderRadius={400}>
|
|
72
|
+
<ExampleComponent />
|
|
73
|
+
</VStack>
|
|
74
|
+
<Text color="fgMuted" font="caption">
|
|
75
|
+
The hook automatically detects it's inside a modal context!
|
|
76
|
+
</Text>
|
|
77
|
+
</VStack>
|
|
78
|
+
</ModalBody>
|
|
79
|
+
</Modal>
|
|
80
|
+
</VStack>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Using the Context Provider
|
|
86
|
+
|
|
87
|
+
You can also use the `OverlayContentContext` directly to provide context values:
|
|
88
|
+
|
|
89
|
+
```tsx live
|
|
90
|
+
function ContextProviderExample() {
|
|
91
|
+
const ExampleComponent = () => {
|
|
92
|
+
const { isOverlay, isModal, isDrawer, isTour } = useOverlayContentContext();
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<VStack gap={2}>
|
|
96
|
+
<TextHeadline>Overlay Context Information</TextHeadline>
|
|
97
|
+
<Text>Is inside any overlay: {isOverlay ? 'Yes' : 'No'}</Text>
|
|
98
|
+
<Text>Is inside modal: {isModal ? 'Yes' : 'No'}</Text>
|
|
99
|
+
<Text>Is inside drawer/tray: {isDrawer ? 'Yes' : 'No'}</Text>
|
|
100
|
+
<Text>Is inside tour: {isTour ? 'Yes' : 'No'}</Text>
|
|
101
|
+
</VStack>
|
|
102
|
+
);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const contextValue = {
|
|
106
|
+
isModal: true,
|
|
107
|
+
isDrawer: false,
|
|
108
|
+
isTour: false,
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<OverlayContentContext.Provider value={contextValue}>
|
|
113
|
+
<VStack gap={2} padding={3} background="bgSecondary" borderRadius={400}>
|
|
114
|
+
<TextHeadline>Inside Context Provider</TextHeadline>
|
|
115
|
+
<ExampleComponent />
|
|
116
|
+
</VStack>
|
|
117
|
+
</OverlayContentContext.Provider>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Conditional Rendering
|
|
123
|
+
|
|
124
|
+
Use the hook to conditionally render content based on overlay context:
|
|
125
|
+
|
|
126
|
+
```tsx live
|
|
127
|
+
function ConditionalRenderingExample() {
|
|
128
|
+
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
129
|
+
|
|
130
|
+
const ConditionalContent = () => {
|
|
131
|
+
const { isOverlay, isModal } = useOverlayContentContext();
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<VStack gap={2}>
|
|
135
|
+
<TextHeadline>Conditional Content</TextHeadline>
|
|
136
|
+
{isOverlay ? (
|
|
137
|
+
<VStack gap={1}>
|
|
138
|
+
<Text color="fgPositive">✓ This content shows when inside an overlay</Text>
|
|
139
|
+
{isModal && <Text color="fgPrimary">🎯 Specifically inside a modal!</Text>}
|
|
140
|
+
</VStack>
|
|
141
|
+
) : (
|
|
142
|
+
<Text color="fgMuted">This content shows when not in an overlay</Text>
|
|
143
|
+
)}
|
|
144
|
+
</VStack>
|
|
145
|
+
);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
return (
|
|
149
|
+
<VStack gap={3}>
|
|
150
|
+
<VStack gap={2} padding={3} background="bgSecondary" borderRadius={400}>
|
|
151
|
+
<TextHeadline>Outside Modal</TextHeadline>
|
|
152
|
+
<ConditionalContent />
|
|
153
|
+
</VStack>
|
|
154
|
+
|
|
155
|
+
<Button onClick={() => setIsModalOpen(true)}>Open Modal</Button>
|
|
156
|
+
|
|
157
|
+
<Modal visible={isModalOpen} onRequestClose={() => setIsModalOpen(false)}>
|
|
158
|
+
<ModalHeader closeAccessibilityLabel="Close" title="Conditional Content Demo" />
|
|
159
|
+
<ModalBody>
|
|
160
|
+
<ConditionalContent />
|
|
161
|
+
</ModalBody>
|
|
162
|
+
</Modal>
|
|
163
|
+
</VStack>
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Styling Based on Context
|
|
169
|
+
|
|
170
|
+
```tsx live
|
|
171
|
+
function StylingExample() {
|
|
172
|
+
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
173
|
+
|
|
174
|
+
const StyledContent = () => {
|
|
175
|
+
const { isModal, isDrawer } = useOverlayContentContext();
|
|
176
|
+
|
|
177
|
+
const getBackgroundColor = () => {
|
|
178
|
+
if (isModal) return 'bgPrimaryWash';
|
|
179
|
+
if (isDrawer) return 'bgSecondaryWash';
|
|
180
|
+
return 'bgAlternate';
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const getStatusText = () => {
|
|
184
|
+
if (isModal) return 'Modal styling applied! 🎉';
|
|
185
|
+
if (isDrawer) return 'Drawer styling applied!';
|
|
186
|
+
return 'Default styling';
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
return (
|
|
190
|
+
<VStack padding={3} background={getBackgroundColor()} borderRadius={400} gap={2}>
|
|
191
|
+
<TextHeadline>Dynamic Styling</TextHeadline>
|
|
192
|
+
<Text>{getStatusText()}</Text>
|
|
193
|
+
<Text color="fgMuted" font="caption">
|
|
194
|
+
Background color: {getBackgroundColor()}
|
|
195
|
+
</Text>
|
|
196
|
+
</VStack>
|
|
197
|
+
);
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
return (
|
|
201
|
+
<VStack gap={3}>
|
|
202
|
+
<StyledContent />
|
|
203
|
+
|
|
204
|
+
<Button onClick={() => setIsModalOpen(true)}>Open Modal</Button>
|
|
205
|
+
|
|
206
|
+
<Modal visible={isModalOpen} onRequestClose={() => setIsModalOpen(false)}>
|
|
207
|
+
<ModalHeader closeAccessibilityLabel="Close" title="Dynamic Styling Demo" />
|
|
208
|
+
<ModalBody>
|
|
209
|
+
<StyledContent />
|
|
210
|
+
</ModalBody>
|
|
211
|
+
</Modal>
|
|
212
|
+
</VStack>
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
|
|
2
|
+
# useScrollBlocker
|
|
3
|
+
Block and unblock page scrolling.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { useScrollBlocker } from '@coinbase/cds-web/hooks/useScrollBlocker'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Examples
|
|
12
|
+
|
|
13
|
+
### Basic usage
|
|
14
|
+
|
|
15
|
+
```tsx live
|
|
16
|
+
function Example() {
|
|
17
|
+
const blockScroll = useScrollBlocker();
|
|
18
|
+
const [isBlocked, setIsBlocked] = useState(false);
|
|
19
|
+
|
|
20
|
+
const toggleScroll = () => {
|
|
21
|
+
setIsBlocked(!isBlocked);
|
|
22
|
+
blockScroll(!isBlocked);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<VStack gap={3} alignItems="start">
|
|
27
|
+
<TextHeadline>Scroll is currently {isBlocked ? 'blocked' : 'enabled'}</TextHeadline>
|
|
28
|
+
<Button onClick={toggleScroll}>{isBlocked ? 'Enable Scroll' : 'Block Scroll'}</Button>
|
|
29
|
+
</VStack>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### With Overlay
|
|
35
|
+
|
|
36
|
+
```tsx live
|
|
37
|
+
function Example() {
|
|
38
|
+
const blockScroll = useScrollBlocker();
|
|
39
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
40
|
+
|
|
41
|
+
const openModal = () => {
|
|
42
|
+
setIsOpen(true);
|
|
43
|
+
blockScroll(true);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const closeModal = () => {
|
|
47
|
+
setIsOpen(false);
|
|
48
|
+
blockScroll(false);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<VStack gap={3} alignItems="start">
|
|
53
|
+
<Button onClick={openModal}>Open Overlay</Button>
|
|
54
|
+
<Modal visible={isOpen} onRequestClose={closeModal}>
|
|
55
|
+
<ModalHeader title="Modal Title" />
|
|
56
|
+
<ModalBody>Modal Content</ModalBody>
|
|
57
|
+
</Modal>
|
|
58
|
+
</VStack>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
|