Skip to content

Commit abb682c

Browse files
joebuonoJoe Buonodbanksdesign
authored
chore(docs): ThemeProvider API documentation (#2711)
* add new docs page for ThemeProvider API * rename ThemeProvider API to ThemeProvider * document nonce prop for ThemeProvider * include basic ThemeProvider example * update theming example * update custom theme example * Update docs/src/pages/[platform]/theming/theme-provider/react.mdx Co-authored-by: Danny Banks <[email protected]> * remove useTheme hook from custom theme example Co-authored-by: Joe Buono <[email protected]> Co-authored-by: Danny Banks <[email protected]>
1 parent 0377bcc commit abb682c

File tree

7 files changed

+179
-25
lines changed

7 files changed

+179
-25
lines changed

docs/src/data/links.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,11 @@ export const theming: ComponentNavItem[] = [
540540
platforms: ['react', 'vue', 'angular'],
541541
tertiary: true,
542542
},
543+
{
544+
href: '/theming/theme-provider',
545+
label: 'ThemeProvider',
546+
platforms: ['react'],
547+
},
543548
{
544549
href: '/theming/dark-mode',
545550
label: 'Dark mode',

docs/src/pages/[platform]/theming/default-theme/colors/examples/ColorsExample.tsx

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,26 @@
1-
import {
2-
ThemeProvider,
3-
Card,
4-
Heading,
5-
Text,
6-
useTheme,
7-
} from '@aws-amplify/ui-react';
1+
import { Card, Heading, Text, ThemeProvider } from '@aws-amplify/ui-react';
82

9-
export const ColorsExample = () => {
10-
const { tokens } = useTheme();
11-
const theme = {
12-
name: 'custom-theme',
13-
tokens: {
14-
components: {
15-
card: {
16-
backgroundColor: tokens.colors.background.secondary,
17-
outlined: {
18-
borderColor: tokens.colors.black,
19-
},
20-
},
21-
text: {
22-
color: tokens.colors.neutral[80],
23-
},
24-
heading: {
25-
color: tokens.colors.brand.secondary[80],
3+
const theme = {
4+
name: 'custom-theme',
5+
tokens: {
6+
components: {
7+
card: {
8+
backgroundColor: { value: '{colors.background.secondary}' },
9+
outlined: {
10+
borderColor: { value: '{colors.black}' },
2611
},
2712
},
13+
heading: {
14+
color: { value: '{colors.brand.secondary[80]}' },
15+
},
16+
text: {
17+
color: { value: '{colors.brand.primary[80]}' },
18+
},
2819
},
29-
};
20+
},
21+
};
22+
23+
export const ColorsExample = () => {
3024
return (
3125
<ThemeProvider theme={theme}>
3226
<Card variation="outlined">
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Button, useTheme } from '@aws-amplify/ui-react';
2+
3+
export const BasicExample = () => {
4+
const { tokens } = useTheme();
5+
6+
return (
7+
<Button border={`2px solid ${tokens.colors.blue[80]}`} color="purple.80">
8+
Themed Button
9+
</Button>
10+
);
11+
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Card, Heading, Text, ThemeProvider } from '@aws-amplify/ui-react';
2+
3+
const theme = {
4+
name: 'custom-theme',
5+
tokens: {
6+
components: {
7+
card: {
8+
backgroundColor: { value: '{colors.background.secondary}' },
9+
outlined: {
10+
borderColor: { value: '{colors.black}' },
11+
},
12+
},
13+
heading: {
14+
color: { value: '{colors.brand.secondary[80]}' },
15+
},
16+
text: {
17+
color: { value: '{colors.brand.primary[80]}' },
18+
},
19+
},
20+
},
21+
};
22+
23+
export const CustomThemeExample = () => {
24+
return (
25+
<ThemeProvider theme={theme}>
26+
<Card variation="outlined">
27+
<Heading level={6}>Heading text</Heading>
28+
<Text>Some sample text for this card.</Text>
29+
</Card>
30+
</ThemeProvider>
31+
);
32+
};
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { BasicExample } from './BasicExample';
2+
export { CustomThemeExample } from './CustomThemeExample';
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
title: ThemeProvider
3+
description: The ThemeProvider allows you to apply a Theme to your application.
4+
supportedFrameworks: react
5+
---
6+
7+
import { Fragment } from '@/components/Fragment';
8+
import { FRAMEWORKS } from '@/data/frameworks';
9+
import { getCustomStaticPath } from "@/utils/getCustomStaticPath";
10+
11+
export async function getStaticPaths() {
12+
return getCustomStaticPath(frontmatter.supportedFrameworks);
13+
}
14+
15+
{/* `getStaticProps` is required to prevent "Error: getStaticPaths was added without a getStaticProps. Without getStaticProps, getStaticPaths does nothing" */}
16+
17+
export async function getStaticProps() {
18+
return { props: {} }
19+
}
20+
21+
<Fragment>{({ platform }) => import(`./${platform}.mdx`)}</Fragment>
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { Flex } from '@aws-amplify/ui-react';
2+
import { Example, ExampleCode } from '@/components/Example';
3+
4+
import { BasicExample, CustomThemeExample } from './examples';
5+
6+
## Usage
7+
8+
Import the `ThemeProvider` and wrap your application with it:
9+
10+
```jsx
11+
import { ThemeProvider } from '@aws-amplify/ui-react';
12+
13+
export const App = () => (
14+
<ThemeProvider>
15+
<YourApplication />
16+
</ThemeProvider>
17+
);
18+
```
19+
20+
After wrapping your application in the `ThemeProvider`, you have access to all theme values in your components. To style the components in your app, you can either:
21+
1. Get the theme `tokens` through the `useTheme` hook (e.g., `tokens.colors.blue[80]`)
22+
2. Reference the theme `tokens` directly in style props (e.g., `"purple.80"`)
23+
24+
<Example>
25+
<Flex>
26+
<BasicExample />
27+
</Flex>
28+
29+
<ExampleCode>
30+
```tsx file=./examples/BasicExample.tsx
31+
```
32+
33+
</ExampleCode>
34+
</Example>
35+
36+
### theme
37+
38+
To create and use your own custom theme, you may pass a [theme object](https://ui.docs.amplify.aws/react/theming#theme-object) to the `theme` prop on the `ThemeProvider`.
39+
40+
- [Theming overview](./theming)
41+
42+
<Example>
43+
<CustomThemeExample />
44+
45+
<ExampleCode>
46+
```tsx file=./examples/CustomThemeExample.tsx
47+
```
48+
49+
</ExampleCode>
50+
</Example>
51+
52+
### colorMode
53+
54+
The `ThemeProvider` accepts a `colorMode` prop which can be `light`, `dark`, or `system`.
55+
56+
See the [Dark mode documentation](./dark-mode) for a detailed explanation of how to use the `colorMode` prop.
57+
58+
### nonce
59+
60+
When you have a `Content-Security-Policy` ([CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)) header defined, the browser will automatically block inline styles.
61+
62+
To safely allow inline styles when using strict CSP rules, you may pass a [nonce](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce) to the `nonce` prop on the `ThemeProvider`. This will add a nonce to the `<style>` tag rendered by the `ThemeProvider`. For example:
63+
64+
**CSP rules**
65+
```
66+
style-src css-cdn.example.com 'nonce-rAnd0m';
67+
```
68+
69+
**ThemeProvider**
70+
```jsx
71+
<ThemeProvider nonce="rAnd0m">
72+
{/* your app */}
73+
</ThemeProvider>
74+
```
75+
76+
**HTML output**
77+
```html
78+
<style nonce="rAnd0m">
79+
:root, [data-amplify-theme] {
80+
--amplify-colors-white: hsl(0, 0%, 100%);
81+
/* etc */
82+
}
83+
/*
84+
* Any of your custom theme styles
85+
*/
86+
</style>
87+
```
88+
89+
For more information, see the following documention on [allowing inline styles using a nonce](https://content-security-policy.com/examples/allow-inline-style).

0 commit comments

Comments
 (0)