Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Implemented "recipe" page #791

Merged
merged 9 commits into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions apps/docs/docs/learn/06-recipes/01-contextual-styles.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
sidebar_position: 6
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Conditional styles based on context

StyleX lets you apply styles conditionally. Any condition can be used to do so, `Props`, `State` or `Context`.

The React Context API (and other similar APIs) can be used to avoid prop-drilling
and provide conditions that child component can read and apply styles conditionally.

Context can help reduce prop-drilling by sharing state across components. This can often
an alternative to using descendent selectors where the same results can be achieved
*without* "styling at a distance".

For example, you can manage the open or closed state of a sidebar using React Context
and conditionally apply styles:

## Defining context and styles

This file sets up the `SidebarContext` and defines the styles for the sidebar in one place.
The context provides a way to share the open/closed state, and the styles determine
the appearance of the sidebar based on that state.

```tsx
import { createContext } from 'react';
import * as stylex from '@stylexjs/stylex';

export default createContext(false);
```
## Building the sidebar component
The `Sidebar` component uses the `SidebarContext` to determine its open or closed state
and conditionally applies the appropriate styles.

```tsx
import React, { useContext } from 'react';
import * as stylex from '@stylexjs/stylex';
import { SidebarContext } from './SidebarContext';

export default function Sidebar({ children }) {
const isOpen = useContext(SidebarContext);

return (
<div {...stylex.props(styles.base, isOpen ? styles.open : styles.closed)}>
{children}
</div>
);
}

const styles = stylex.create({
base: {...},
open: {
width: 250,
},
closed: {
width: 50,
},
});
```

## Using the sidebar in a parent component

The `App` component manages the sidebar's open/closed state and provides it to
child components through `SidebarContext.Provider`. A button toggles the sidebar state dynamically.

```tsx
import React, { useState } from 'react';
import SidebarContext from './SidebarContext';
import Sidebar from './Sidebar';

export default function App() {
const [isSidebarOpen, setIsSidebarOpen] = useState(false);

return (
<SidebarContext.Provider value={isSidebarOpen}>
<button onClick={() => setIsSidebarOpen(!isSidebarOpen)}>
Toggle Sidebar
</button>
<Sidebar>
<p>Sidebar Content</p>
</Sidebar>
</SidebarContext.Provider>
);
}
```

52 changes: 52 additions & 0 deletions apps/docs/docs/learn/06-recipes/02-variants.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
sidebar_position: 5
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Variants

The "variants" pattern allows you to conditionally apply one of several predefined styles based on a value. This is especially useful for theming or dynamic component behavior.

### Example: Button Variants

Here’s how you can create a button component with different visual styles based on a `variant` prop:

```tsx
import * as stylex from '@stylexjs/stylex';

const styles = stylex.create({
base: {
appearance: 'none',
borderWidth: 0,
},
});
const variants = stylex.create({
primary: {
backgroundColor: {
default: 'blue',
':hover': 'darkblue',
},
color: 'white',
},
secondary: {
backgroundColor: {
default: 'gray',
':hover': 'darkgray',
},
color: 'white',
},
});
function Button({ variant = 'primary', ...props }) {
return <button {...props} {...stylex.props(styles.base, variants[variant], props.style)} />;
}

// Usage
<Button variant="primary">Primary</Button>
<Button variant="secondary">Secondary</Button>
```
76 changes: 76 additions & 0 deletions apps/docs/docs/learn/06-recipes/03-descendant styles.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
sidebar_position: 7
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Descendant styles dependent on ancestor state

## Example: Sidebar

Consider the case where the content within a sidebar needs to have conditional styles applied
when the sidebar as whole is hovered.

Using CSS variables, you can style descendants based on a parent's state, such as `:hover`.

### Step 1
Define one or more variables using `stylex.defineVars`:

```tsx variables.stylex.ts
// variables.stylex.ts
import * as stylex from '@stylexjs/stylex';

export const vars = stylex.defineVars({
childColor: 'black',
});
```

### Step 2
Define conditional styles setting the value for the variable in the ancestor component.

```tsx
import * as stylex from '@stylexjs/stylex';
import { vars } from './variables.stylex';

const styles = stylex.create({
parent: {
[vars.childColor]: {
default: 'black',
':hover': 'blue',
},
},
});

function ParentWithHover({children}) {
return (
<div {...stylex.props(styles.parent)}>
{children}
</div>
);
}
```

### Step 3
Use the variable to style the child component

```tsx
import * as stylex from '@stylexjs/stylex';
import { vars } from './variables.stylex';

const styles = stylex.create({
row: {
color: vars.childColor,
}
});

function ParentWithHover() {
return (
<span {...stylex.props(styles.child)}><Icon />A Row</span>
);
}
```
4 changes: 4 additions & 0 deletions apps/docs/docs/learn/06-recipes/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"label": "Recipes",
"position": 4
}
Loading