Skip to content

Commit edeaa2f

Browse files
committed
add FAQ and other sections
1 parent f40b575 commit edeaa2f

File tree

2 files changed

+101
-11
lines changed

2 files changed

+101
-11
lines changed

packages/dev/s2-docs/pages/s2/styling.mdx

Lines changed: 81 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export const description = 'Styling in React Spectrum';
1111

1212
# Styling
1313

14-
React Spectrum includes a build-time style macro that generates atomic CSS and lets you apply Spectrum tokens directly in your components with type-safe autocompletion.
14+
React Spectrum includes a build-time `style` macro that generates atomic CSS and lets you apply Spectrum tokens directly in your components with type-safe autocompletion.
1515

1616
## Style macro
1717

@@ -37,6 +37,14 @@ Colocating styles with your component code means:
3737
- Develop more efficiently – no switching files or writing selectors.
3838
- Refactor with confidence – changes are isolated; deleting a component removes its styles.
3939

40+
<InlineAlert variant="informative">
41+
<Heading>Important Note</Heading>
42+
<Content>
43+
Due to the atomic nature of the generated CSS rules, it is strongly recommended that you follow the best practices listed [below](#css-optimization).
44+
Failure to do so can result in large number of duplicate rules and obtuse styling bugs.
45+
</Content>
46+
</InlineAlert>
47+
4048
## Spectrum components
4149

4250
The `styles` prop accepts a limited set of CSS properties, including layout, spacing, sizing, and positioning. Other styles such as colors and internal padding cannot be customized within Spectrum components.
@@ -88,7 +96,7 @@ import {Button} from '@react-spectrum/s2';
8896

8997
### UNSAFE Style Overrides
9098

91-
We highly discourage overriding the styles of React Spectrum components because it may break at any time when we change our implementation, making it difficult for you to update in the future. Consider using [React Aria Components](https://react-spectrum.adobe.com/react-aria/) with our style macro to build a custom component with Spectrum styles instead.
99+
We highly discourage overriding the styles of React Spectrum components because it may break at any time when we change our implementation, making it difficult for you to update in the future. Consider using [React Aria Components](https://react-spectrum.adobe.com/react-aria/) with our `style` macro to build a custom component with Spectrum styles instead.
92100

93101
With that being said, the `UNSAFE_className` and `UNSAFE_style` props are supported on Spectrum 2 components as last-resort escape hatches.
94102

@@ -153,7 +161,7 @@ Type scales include: UI, Body, Heading, Title, Detail, and Code. Each scale has
153161
<InlineAlert variant="notice">
154162
<Heading>Important Note</Heading>
155163
<Content>
156-
Only use `<Heading>` and `<Text>` inside Spectrum components with predefined styles (e.g., `<Dialog>`, `<MenuItem>`). They are unstyled by default and should not be used standalone. Use HTML elements with the style macro instead.
164+
Only use `<Heading>` and `<Text>` inside Spectrum components with predefined styles (e.g., `<Dialog>`, `<MenuItem>`). They are unstyled by default and should not be used standalone. Use HTML elements with the `style` macro instead.
157165
</Content>
158166
</InlineAlert>
159167

@@ -195,13 +203,14 @@ function MyComponent({variant}: {variant: 'primary' | 'secondary'}) {
195203
}
196204
```
197205

198-
Boolean conditions starting with `is` can be used directly without nesting:
206+
Boolean conditions starting with `is` or `allows` can be used directly without nesting:
199207

200208
```tsx
201209
const styles = style({
202210
backgroundColor: {
203211
default: 'gray-100',
204-
isSelected: 'gray-900'
212+
isSelected: 'gray-900',
213+
allowsRemoving: 'gray-400'
205214
}
206215
});
207216

@@ -222,7 +231,7 @@ import {style} from '@react-spectrum/s2/style' with {type: 'macro'};
222231
isSelected: 'gray-900'
223232
}
224233
})}
225-
/>
234+
/>
226235
```
227236

228237
### Nesting conditions
@@ -308,9 +317,31 @@ const buttonStyle = style({
308317
<Button styles={buttonStyle}>Press me</Button>
309318
```
310319

320+
## Setting CSS variables
321+
322+
CSS variables can be directly defined in a `style` macro, allowing child elements to then access them in their own styles.
323+
A `type` should be provided to specify the CSS property type the `value` represents.
324+
325+
```tsx
326+
const parentStyle = style({
327+
'--rowBackgroundColor': {
328+
type: 'backgroundColor',
329+
value: 'gray-400'
330+
}
331+
});
332+
333+
const childStyle = style({
334+
backgroundColor: '--rowBackgroundColor'
335+
});
336+
```
337+
338+
## Creating custom components with style macros
339+
340+
TODO: I want to add the usuage of mergeStyles here from that one thread. Maybe an example with RAC + style macros as well
341+
311342
## CSS optimization
312343

313-
The style macro relies on CSS bundling and minification for optimal output. Follow these best practices:
344+
The `style` macro relies on CSS bundling and minification for optimal output. Follow these best practices:
314345

315346
- Ensure styles are extracted into a CSS bundle; do not inject at runtime with `<style>` tags.
316347
- Use a CSS minifier like `lightningcss` to deduplicate common rules (consider in dev for easier debugging).
@@ -362,4 +393,46 @@ CSS resets are strongly discouraged. Global CSS selectors can unintentionally af
362393
/* App.css */
363394
@layer reset, _;
364395
@import "reset.css" layer(reset);
365-
```
396+
```
397+
398+
### Developing with style macros
399+
400+
Since `style` macros are quite different from using `className`/`style` directly, many may find it initially challenging to debug and develop against.
401+
Below are some useful tools that may benefit your developer experience:
402+
403+
- The [atomic-css-devtools](https://github.com/astahmer/atomic-css-devtools) extension presents an inspected element's atomic CSS rules
404+
in a non-atomic format, making it easier to scan.
405+
406+
- This [sandbox](https://codesandbox.io/p/devbox/react-spectrum-s2-style-macro-template-h6fpsq) is preconfigured to support React Spectrum S2, React Aria Components, and
407+
the `style` macros for quick prototyping.
408+
409+
- If you are using Cursor, we offer a set of [Cursor rules](https://github.com/adobe/react-spectrum/blob/main/rules/style-macro.mdc) to use when developing with style macros. Additionally,
410+
we have MCP servers for [React Aria](#TODO) and [React Spectrum](https://www.npmjs.com/package/@react-spectrum/mcp) respectively that interface with the docs.
411+
412+
413+
- TODO: link to the dev tool Rob is making, perhaps replacing the atomic css dev tool. Any others we wanna call out
414+
415+
416+
## FAQ
417+
418+
> I'm getting a "Could not statically evaluate macro argument" error.
419+
420+
This happens if your `style` macro has a condition that isn't evaluable at build time. This can happen for a variety of reasons such
421+
as if you've referenced non-constant variables within your `style` macro or if you've called non-macro functions within your `style` macro.
422+
If you are using Typescript, it can be as simple as forgetting to add `as const` to your own defined reusable macro.
423+
TODO: create an example here, should I link to the sections above like "reusing styles"?
424+
425+
> I'm seeing a ton of duplicate rules being generated and/or my dev tools are very slow.
426+
427+
Please make sure you've followed the [best practices listed above](#css-optimization).
428+
429+
> I tried to pass my `style` macro to `UNSAFE_className` but it doesn't work.
430+
431+
The `style` macro is not meant to be used with `UNSAFE_className`. Overrides to the Spectrum styles is highly discouraged,
432+
consider styling an equivalent React Aria Component instead.
433+
TODO: we already touch on this via the UNSAFE Style Overrides section
434+
TODO: example of RAC + style macros? maybe later
435+
436+
> I'm coming from S1, but where are Flex/Grid/etc?
437+
438+
These no longer exist. Please style `<div>`, `<span>`, and other standard HTML elements with the `style` macro instead.

packages/dev/s2-docs/src/Layout.tsx

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,23 @@ const components = {
3131
p: ({children, ...props}) => <p {...props} className={style({font: {default: 'body', lg: 'body-lg'}, marginY: 24})}>{children}</p>,
3232
ul: (props) => <ul {...props} />,
3333
li: ({children, ...props}) => <li {...props} className={style({font: {default: 'body', lg: 'body-lg'}, marginY: 0})}>{children}</li>,
34+
blockquote: ({children, ...props}) => (
35+
<blockquote
36+
{...props}
37+
className={style({
38+
borderStartWidth: 4,
39+
borderEndWidth: 0,
40+
borderTopWidth: 0,
41+
borderBottomWidth: 0,
42+
borderStyle: 'solid',
43+
borderColor: 'gray-400',
44+
paddingStart: 12,
45+
font: {default: 'body', lg: 'body-lg'},
46+
margin: 'unset'
47+
})}>
48+
{children}
49+
</blockquote>
50+
),
3451
Figure: (props) => <figure {...props} className={style({display: 'flex', flexDirection: 'column', alignItems: 'center', marginY: 32, marginX: 0})} />,
3552
Caption: (props) => <figcaption {...props} className={style({font: 'body-sm'})} />,
3653
CodeBlock: CodeBlock,
@@ -56,14 +73,14 @@ const getTitle = (currentPage: Page): string => {
5673
if (explicitTitle && explicitTitle !== currentPage.tableOfContents?.[0]?.title && explicitTitle !== currentPage.name) {
5774
return explicitTitle as string;
5875
}
59-
76+
6077
let library = getLibraryLabel(getLibraryFromPage(currentPage));
6178
const pageTitle = currentPage.tableOfContents?.[0]?.title ?? currentPage.name;
62-
79+
6380
if (currentPage.name === 'index.html' || currentPage.name.endsWith('/index.html')) {
6481
return library || 'React Spectrum';
6582
}
66-
83+
6784
return library ? `${pageTitle} | ${library}` : pageTitle;
6885
};
6986

0 commit comments

Comments
 (0)