From f69ac4180a0d4da4085ce2d36c3233d8c0d2bc94 Mon Sep 17 00:00:00 2001 From: Amina Date: Mon, 2 Dec 2024 12:42:46 -0600 Subject: [PATCH 1/9] Implemented recipe page with examples of common styling patterns --- .../docs/learn/04-styling-ui/03-recipes.mdx | 121 ++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 apps/docs/docs/learn/04-styling-ui/03-recipes.mdx diff --git a/apps/docs/docs/learn/04-styling-ui/03-recipes.mdx b/apps/docs/docs/learn/04-styling-ui/03-recipes.mdx new file mode 100644 index 00000000..b14e4aa8 --- /dev/null +++ b/apps/docs/docs/learn/04-styling-ui/03-recipes.mdx @@ -0,0 +1,121 @@ +--- +# 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'; + +# Recipes + +This section provides practical examples and patterns that demonstrate how to use StyleX for common styling scenarios. + +## Contextual Styles + +Contextual styles are an effective way to dynamically adapt styles based on a component's state or its environment. Here are some approaches to achieve this: + +### Using Context + +Context can help reduce prop-drilling by sharing state across components. For example, you can manage the open or closed state of a sidebar using React Context and conditionally apply styles: + +```tsx +import { createContext, useContext } from 'react'; +import * as stylex from '@stylexjs/stylex'; + +const SidebarContext = createContext(false); + +const styles = stylex.create({ + sidebarOpen: { + width: '250px', + }, + sidebarClosed: { + width: '50px', + }, +}); + +function Sidebar({ children }) { + const isOpen = useContext(SidebarContext); + return ( +
+ {children} +
+ ); +} +``` + +## 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({ + primary: { + backgroundColor: 'blue', + color: 'white', + ':hover': { + backgroundColor: 'darkblue', + }, + }, + secondary: { + backgroundColor: 'gray', + color: 'white', + ':hover': { + backgroundColor: 'darkgray', + }, + }, +}); + +function Button({ variant = 'primary', ...props }) { + return + +``` + +## Fluid, Responsive Design + +The best approach to building responsive layouts is often to use fluid designs that adapt naturally to available space. This minimizes the total CSS and avoids brittle breakpoints. + +### Example: Fluid Grid Layout + +```tsx +import * as stylex from '@stylexjs/stylex'; + +const styles = stylex.create({ + row: { + display: 'flex', + flexWrap: 'wrap', + }, + column: { + flexShrink: 0, + flexBasis: 'auto', + maxWidth: '100%', + }, + fluid: { + flexBasis: 0, + flexGrow: 1, + }, +}); + +export const Col = ({ children, fluid = false }: { children: React.ReactNode; fluid?: boolean }) => ( +
{children}
+); + +export const Row = ({ children }: { children: React.ReactNode }) => ( +
{children}
+); +``` +## Sharing Your Recipes + +We’d love to see the unique patterns and use cases you come up with! Share your recipes with the StyleX community to inspire others. From 85bed015ce90da62ad9b324b7aeda9f8d03823b8 Mon Sep 17 00:00:00 2001 From: Amina Date: Mon, 2 Dec 2024 12:48:43 -0600 Subject: [PATCH 2/9] added hover styles section --- .../docs/learn/04-styling-ui/03-recipes.mdx | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/apps/docs/docs/learn/04-styling-ui/03-recipes.mdx b/apps/docs/docs/learn/04-styling-ui/03-recipes.mdx index b14e4aa8..4467ef38 100644 --- a/apps/docs/docs/learn/04-styling-ui/03-recipes.mdx +++ b/apps/docs/docs/learn/04-styling-ui/03-recipes.mdx @@ -83,6 +83,37 @@ function Button({ variant = 'primary', ...props }) { ``` +## Hover-Dependent Descendant Styles + +Using CSS variables, you can style descendants based on a parent's state, such as `:hover`. + +### Example: Nested Hover Styles + +In this example, we'll apply a hover effect to a child element when the parent is hovered: + +```tsx +import * as stylex from '@stylexjs/stylex'; + +const styles = stylex.create({ + parent: { + '--child-color': 'black', + ':hover': { + '--child-color': 'blue', + }, + }, + child: { + color: 'var(--child-color)', + }, +}); + +function ParentWithHover() { + return ( +
+ Hover over me! +
+ ); +} +``` ## Fluid, Responsive Design The best approach to building responsive layouts is often to use fluid designs that adapt naturally to available space. This minimizes the total CSS and avoids brittle breakpoints. From 81c6d5757819dc5630dd321fa98dc279411a7ae9 Mon Sep 17 00:00:00 2001 From: Amina Date: Wed, 4 Dec 2024 17:28:07 -0600 Subject: [PATCH 3/9] refactor: restructured recipes, imp. suggestions --- .../docs/learn/04-styling-ui/03-recipes.mdx | 152 ------------------ .../learn/06-recipes/01-contexual-styles.mdx | 45 ++++++ .../docs/learn/06-recipes/02-variants.mdx | 47 ++++++ .../learn/06-recipes/03-descendant styles.mdx | 46 ++++++ .../docs/learn/06-recipes/_category_.json | 4 + 5 files changed, 142 insertions(+), 152 deletions(-) delete mode 100644 apps/docs/docs/learn/04-styling-ui/03-recipes.mdx create mode 100644 apps/docs/docs/learn/06-recipes/01-contexual-styles.mdx create mode 100644 apps/docs/docs/learn/06-recipes/02-variants.mdx create mode 100644 apps/docs/docs/learn/06-recipes/03-descendant styles.mdx create mode 100644 apps/docs/docs/learn/06-recipes/_category_.json diff --git a/apps/docs/docs/learn/04-styling-ui/03-recipes.mdx b/apps/docs/docs/learn/04-styling-ui/03-recipes.mdx deleted file mode 100644 index 4467ef38..00000000 --- a/apps/docs/docs/learn/04-styling-ui/03-recipes.mdx +++ /dev/null @@ -1,152 +0,0 @@ ---- -# 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'; - -# Recipes - -This section provides practical examples and patterns that demonstrate how to use StyleX for common styling scenarios. - -## Contextual Styles - -Contextual styles are an effective way to dynamically adapt styles based on a component's state or its environment. Here are some approaches to achieve this: - -### Using Context - -Context can help reduce prop-drilling by sharing state across components. For example, you can manage the open or closed state of a sidebar using React Context and conditionally apply styles: - -```tsx -import { createContext, useContext } from 'react'; -import * as stylex from '@stylexjs/stylex'; - -const SidebarContext = createContext(false); - -const styles = stylex.create({ - sidebarOpen: { - width: '250px', - }, - sidebarClosed: { - width: '50px', - }, -}); - -function Sidebar({ children }) { - const isOpen = useContext(SidebarContext); - return ( -
- {children} -
- ); -} -``` - -## 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({ - primary: { - backgroundColor: 'blue', - color: 'white', - ':hover': { - backgroundColor: 'darkblue', - }, - }, - secondary: { - backgroundColor: 'gray', - color: 'white', - ':hover': { - backgroundColor: 'darkgray', - }, - }, -}); - -function Button({ variant = 'primary', ...props }) { - return - -``` - -## Hover-Dependent Descendant Styles - -Using CSS variables, you can style descendants based on a parent's state, such as `:hover`. - -### Example: Nested Hover Styles - -In this example, we'll apply a hover effect to a child element when the parent is hovered: - -```tsx -import * as stylex from '@stylexjs/stylex'; - -const styles = stylex.create({ - parent: { - '--child-color': 'black', - ':hover': { - '--child-color': 'blue', - }, - }, - child: { - color: 'var(--child-color)', - }, -}); - -function ParentWithHover() { - return ( -
- Hover over me! -
- ); -} -``` -## Fluid, Responsive Design - -The best approach to building responsive layouts is often to use fluid designs that adapt naturally to available space. This minimizes the total CSS and avoids brittle breakpoints. - -### Example: Fluid Grid Layout - -```tsx -import * as stylex from '@stylexjs/stylex'; - -const styles = stylex.create({ - row: { - display: 'flex', - flexWrap: 'wrap', - }, - column: { - flexShrink: 0, - flexBasis: 'auto', - maxWidth: '100%', - }, - fluid: { - flexBasis: 0, - flexGrow: 1, - }, -}); - -export const Col = ({ children, fluid = false }: { children: React.ReactNode; fluid?: boolean }) => ( -
{children}
-); - -export const Row = ({ children }: { children: React.ReactNode }) => ( -
{children}
-); -``` -## Sharing Your Recipes - -We’d love to see the unique patterns and use cases you come up with! Share your recipes with the StyleX community to inspire others. diff --git a/apps/docs/docs/learn/06-recipes/01-contexual-styles.mdx b/apps/docs/docs/learn/06-recipes/01-contexual-styles.mdx new file mode 100644 index 00000000..f3597f8a --- /dev/null +++ b/apps/docs/docs/learn/06-recipes/01-contexual-styles.mdx @@ -0,0 +1,45 @@ +--- +# 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'; + + +# Contextual styles + +Contextual styles are an effective way to dynamically adapt styles based on a component's state or its environment. Here are some approaches to achieve this: + +### Using Context + +Context can help reduce prop-drilling by sharing state across components. For example, you can manage the open or closed state of a sidebar using React Context and conditionally apply styles: + +```tsx +import { createContext, useContext } from 'react'; +import * as stylex from '@stylexjs/stylex'; + +const SidebarContext = createContext(false); + +const styles = stylex.create({ + sidebarOpen: { + width: '250px', + }, + sidebarClosed: { + width: '50px', + }, +}); + +function Sidebar({ children }) { + const isOpen = useContext(SidebarContext); + return ( +
+ {children} +
+ ); +} +``` + diff --git a/apps/docs/docs/learn/06-recipes/02-variants.mdx b/apps/docs/docs/learn/06-recipes/02-variants.mdx new file mode 100644 index 00000000..e84f6edf --- /dev/null +++ b/apps/docs/docs/learn/06-recipes/02-variants.mdx @@ -0,0 +1,47 @@ +--- +# 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({ + primary: { + backgroundColor: { + default: 'blue', + ':hover': 'darkblue', + }, + color: 'white', + }, + secondary: { + backgroundColor: { + default: 'gray', + ':hover': 'darkgray', + }, + color: 'white', + }, +}); + +function Button({ variant = 'primary', ...props }) { + return + +``` \ No newline at end of file diff --git a/apps/docs/docs/learn/06-recipes/03-descendant styles.mdx b/apps/docs/docs/learn/06-recipes/03-descendant styles.mdx new file mode 100644 index 00000000..01a2a452 --- /dev/null +++ b/apps/docs/docs/learn/06-recipes/03-descendant styles.mdx @@ -0,0 +1,46 @@ +# Descendant styles + +## Hover-Dependent Descendant Styles + +Using CSS variables, you can style descendants based on a parent's state, such as `:hover`. + +### Example: Nested Hover Styles + +In this example, we'll apply a hover effect to a child element when the parent is hovered: + +`variables.stylex.ts` defines a variable using `stylex.defineVars`: + +```tsx +import * as stylex from '@stylexjs/stylex'; + +export const vars = stylex.defineVars({ + childColor: 'black', +}); +``` +In the `styles.parent` object, the variable `vars.childColor` is referenced and updated on hover. + +```tsx +import * as stylex from '@stylexjs/stylex'; +import { vars } from './variables.stylex'; + +const styles = stylex.create({ + parent: { + [vars.childColor]: vars.childColor, + ':hover': { + [vars.childColor]: 'blue', + }, + }, + child: { + color: `var(${vars.childColor})`, + }, +}); + +function ParentWithHover() { + return ( +
+ Hover over me! +
+ ); +} + +``` \ No newline at end of file diff --git a/apps/docs/docs/learn/06-recipes/_category_.json b/apps/docs/docs/learn/06-recipes/_category_.json new file mode 100644 index 00000000..3a9a5262 --- /dev/null +++ b/apps/docs/docs/learn/06-recipes/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Recipes", + "position": 4 +} From 965f1e466f69f2b0c1a395100654db56a7a9212f Mon Sep 17 00:00:00 2001 From: Amina Date: Wed, 4 Dec 2024 19:08:48 -0600 Subject: [PATCH 4/9] refactor: reorder files, split up tsx snippets --- .../learn/06-recipes/01-contexual-styles.mdx | 63 ++++++++++++++++--- .../learn/06-recipes/03-descendant styles.mdx | 11 ++++ 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/apps/docs/docs/learn/06-recipes/01-contexual-styles.mdx b/apps/docs/docs/learn/06-recipes/01-contexual-styles.mdx index f3597f8a..c94ec56f 100644 --- a/apps/docs/docs/learn/06-recipes/01-contexual-styles.mdx +++ b/apps/docs/docs/learn/06-recipes/01-contexual-styles.mdx @@ -3,7 +3,7 @@ # # 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 +sidebar_position: 6 --- import Tabs from '@theme/Tabs'; @@ -12,34 +12,83 @@ import TabItem from '@theme/TabItem'; # Contextual styles -Contextual styles are an effective way to dynamically adapt styles based on a component's state or its environment. Here are some approaches to achieve this: +Contextual styles are an effective way to dynamically adapt styles based on a component's state +or its environment. Here are some approaches to achieve this: ### Using Context -Context can help reduce prop-drilling by sharing state across components. For example, you can manage the open or closed state of a sidebar using React Context and conditionally apply styles: +Context can help reduce prop-drilling by sharing state across components. +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, useContext } from 'react'; +import { createContext } from 'react'; import * as stylex from '@stylexjs/stylex'; const SidebarContext = createContext(false); const styles = stylex.create({ sidebarOpen: { - width: '250px', + width: '250', }, sidebarClosed: { - width: '50px', + width: '50', }, }); -function Sidebar({ children }) { +export { SidebarContext, styles }; +``` +## 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, styles } from './SidebarContext'; + + +function Sidebar({ children }: { children: React.ReactNode }) { const isOpen = useContext(SidebarContext); + return (
{children}
); } + +export default Sidebar; +``` +## 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'; + +function App() { + const [isSidebarOpen, setIsSidebarOpen] = useState(false); + + return ( + + + +

Sidebar Content

+
+
+ ); +} + +export default App; ``` diff --git a/apps/docs/docs/learn/06-recipes/03-descendant styles.mdx b/apps/docs/docs/learn/06-recipes/03-descendant styles.mdx index 01a2a452..294b4823 100644 --- a/apps/docs/docs/learn/06-recipes/03-descendant styles.mdx +++ b/apps/docs/docs/learn/06-recipes/03-descendant styles.mdx @@ -1,3 +1,14 @@ +--- +# 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 ## Hover-Dependent Descendant Styles From 8bfd0da90290f21c9806ca737b634bc9e15a20e6 Mon Sep 17 00:00:00 2001 From: Amina Date: Wed, 4 Dec 2024 19:24:49 -0600 Subject: [PATCH 5/9] refactor: implementing suggested changes --- apps/docs/docs/learn/06-recipes/02-variants.mdx | 9 +++++++-- apps/docs/docs/learn/06-recipes/03-descendant styles.mdx | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/docs/docs/learn/06-recipes/02-variants.mdx b/apps/docs/docs/learn/06-recipes/02-variants.mdx index e84f6edf..677cb92b 100644 --- a/apps/docs/docs/learn/06-recipes/02-variants.mdx +++ b/apps/docs/docs/learn/06-recipes/02-variants.mdx @@ -21,6 +21,12 @@ Here’s how you can create a button component with different visual styles base import * as stylex from '@stylexjs/stylex'; const styles = stylex.create({ + base: { + appearance: 'none', + borderWidth: 0, + }, +}); +const variants = stylex.create({ primary: { backgroundColor: { default: 'blue', @@ -36,9 +42,8 @@ const styles = stylex.create({ color: 'white', }, }); - function Button({ variant = 'primary', ...props }) { - return