# Components

## Table of contents

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->


- [StyleFrameProvider](#styleframeprovider)
  - [Usage](#usage)
  - [Problem](#problem)
  - [Solution](#solution)
- [ThemeProvider](#themeprovider)
  - [Usage](#usage-1)
  - [Modes](#modes)
  - [Scoping (Local vs. Global)](#scoping-local-vs-global)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## StyleFrameProvider

This component ensures styles generated by the Style System work when components are rendered within an iFrame.

### Usage

Wrap any components using the Style System with the `StyleFrameProvider` when rendering within an iFrame.

```jsx
import { StyleFrameProvider } from '@wp-g2/styles';
import { View } from '@wp-g2/components';
import Frame from 'react-frame-component'; // Works with any iFrame component.

function Example() {
	return (
		<Frame>
			<StyleFrameProvider>
				<View>...</View>
			</StyleFrameProvider>
		</Frame>
	);
}
```

### Problem

By default, [CSS-in-JS](https://emotion.sh/docs/introduction) system injects styles to the `document` `<head>` of the main `window`. Under regular use-cases, this works perfectly fine, as there would ever be a single window. However, with iFrames, the styles need to inject to the iFrame's `window`.

### Solution

The `StyleFrameProvider` coordinates with the Style System's renderer to ensure that the styles are injected to the **correct** `window`.

## ThemeProvider

This component provides the theme values (aka. "Design Tokens") for UI rendered with the Style System. This component can also render UI in different modes, including **dark**, **high-contrast**, and **color-blind**.

### Usage

The example below showcases how a custom theme can be created using the `createTheme` utility. The custom theme can then be passed into `ThemeProvider` via the `theme` prop.

```jsx
import { createTheme, ThemeProvider } from '@wp-g2/styles';
import { Button } from '@wp-g2/components';

const customTheme = createTheme(({ theme }) => {
	return { ...theme, colorAdmin: '#0055ff' };
});

function Example() {
	return (
		<ThemeProvider theme={customTheme}>
			<Button variant="primary">...</Button>
		</ThemeProvider>
	);
}
```

### Modes

The Style System has built-in support for several modes: **dark**, **high-contrast**, and **color-blind**. These modes can be used individually or combined as needed.

In the example below, we've enabled **dark** (`isDark`), **high-contrast** (`isHighContrast`), and **color-blind** (`isColorBlind`).

```jsx
import { ThemeProvider } from '@wp-g2/styles';
import { Button, Surface } from '@wp-g2/components';

function Example() {
	return (
		<ThemeProvider isDark isHighContrast isColorBlind>
			<Surface css={{ padding: 20 }}>
				<Button variant="primary">...</Button>
			</Surface>
		</ThemeProvider>
	);
}
```

### Scoping (Local vs. Global)

The examples above have demonstrated `ThemeProvider` can be used scoped to affect components rendered within. `ThemeProvider` can also be used to apply it's theme and mode settings globally.

#### Local

In the following example, the `ThemeProvider` settings only affect the `Surface` and `Text` components rendered within it.

```jsx
import { ThemeProvider } from '@wp-g2/styles';
import { Surface, Text } from '@wp-g2/components';

function Example() {
	return (
		<Surface>
			<div>
				<ThemeProvider isDark>
					<Surface>
						<Text>...</Text>
					</Surface>
				</ThemeProvider>
			</div>
			<div>
				<Text>...</Text>
			</div>
		</Surface>
	);
}
```

#### Global

In the following example, the `ThemeProvider` settings affect all UI using the Style System. This is enabled by the `isGlobal` property.

Note: For applying theme settings globally, it isn't necessary to wrap all UI within the `ThemeProvider`. Notice how the contents in the example is empty.

```jsx
import { ThemeProvider } from '@wp-g2/styles';
import { Surface, Text } from '@wp-g2/components';

function Example() {
	return (
		<>
			<ThemeProvider isDark isGlobal />
			<Surface>
				<div>
					<Surface>
						<Text>...</Text>
					</Surface>
				</div>
				<div>
					<Text>...</Text>
				</div>
			</Surface>
		</>
	);
}
```
