Skip to content

Commit 544eab7

Browse files
committed
chore: docs updates
1 parent ca492c5 commit 544eab7

22 files changed

Lines changed: 498 additions & 85 deletions

app/docs.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"pages": [
33
{
4-
"title": "v7 (NEW)",
4+
"title": "v7 (alpha)",
55
"pathname": "v7",
66
"sections": [
77
{ "title": "What's new in v7" },
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { NextResponse } from 'next/server';
2+
3+
import { buildCompatJson } from '@/utils/cssCompatFormats';
4+
import { loadCompatMatrix } from '@/utils/cssCompat.server';
5+
6+
export const dynamic = 'force-static';
7+
8+
export function GET() {
9+
return NextResponse.json(buildCompatJson(loadCompatMatrix()));
10+
}

app/docs/compatibility.md/route.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { buildCompatMarkdown } from '@/utils/cssCompatFormats';
2+
import { loadCompatMatrix } from '@/utils/cssCompat.server';
3+
4+
export const dynamic = 'force-static';
5+
6+
export function GET() {
7+
return new Response(buildCompatMarkdown(loadCompatMatrix()), {
8+
headers: {
9+
'content-type': 'text/markdown; charset=utf-8',
10+
},
11+
});
12+
}

app/docs/compatibility/page.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Metadata } from 'next';
33
import DocsLayout from '@/components/DocsLayout';
44
import DocsPageNav from '@/components/DocsPageNav';
55
import CompatibilityMatrix from '@/components/CompatibilityMatrix';
6+
import Link from '@/components/Link';
67
import { loadCompatMatrix } from '@/utils/cssCompat.server';
78

89
export const metadata: Metadata = {
@@ -20,7 +21,15 @@ export default function CompatibilityPage() {
2021
A per-feature reference for which CSS works on React Native. The v6 and v7 columns show styled-components'
2122
native runtime support; the iOS and Android columns show what stock React Native handles without any
2223
styled-components polyfill. Click any row for caveats, the underlying RN style key, and links to upstream PRs in
23-
flight.
24+
flight. Machine-readable versions are available as{' '}
25+
<Link href="/docs/compatibility.json" variant="inline">
26+
JSON
27+
</Link>{' '}
28+
and{' '}
29+
<Link href="/docs/compatibility.md" variant="inline">
30+
Markdown
31+
</Link>
32+
.
2433
</p>
2534

2635
<CompatibilityMatrix entries={entries} />

app/docs/page.tsx

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ const { pages } = json;
2020
const faqCategories = [
2121
{
2222
label: 'Migration',
23-
items: ['What do I need to do to migrate to v6?', 'What do I need to do to migrate to v5?'],
23+
items: [
24+
{ title: 'What do I need to do to migrate to v7?', href: '/docs/v7#migrating-from-v6' },
25+
'What do I need to do to migrate to v6?',
26+
'What do I need to do to migrate to v5?',
27+
],
2428
},
2529
{
2630
label: 'Styling Patterns',
@@ -58,7 +62,7 @@ export default function Documentation() {
5862
return (
5963
<DocsLayout title="Documentation">
6064
<p>
61-
Utilising tagged template literals (a recent addition to JavaScript) and the power of CSS, styled-components
65+
Utilizing tagged template literals (a recent addition to JavaScript) and the power of CSS, styled-components
6266
allows you to write actual CSS code to style your components. It also removes the mapping between components and
6367
styles – using components as a low-level styling construct could not be easier!
6468
</p>
@@ -77,13 +81,18 @@ export default function Documentation() {
7781
{faqCategories.map(cat => (
7882
<FaqGroup key={cat.label}>
7983
<CategoryLabel>{cat.label}</CategoryLabel>
80-
{cat.items.map(item => (
81-
<SubHeader key={item}>
82-
<Link variant="heading" href={`/docs/${pathname}#${titleToDash(item)}`}>
83-
{item}
84-
</Link>
85-
</SubHeader>
86-
))}
84+
{cat.items.map(item => {
85+
const title = typeof item === 'string' ? item : item.title;
86+
const href = typeof item === 'string' ? `/docs/${pathname}#${titleToDash(item)}` : item.href;
87+
88+
return (
89+
<SubHeader key={title}>
90+
<Link variant="heading" href={href}>
91+
{title}
92+
</Link>
93+
</SubHeader>
94+
);
95+
})}
8796
</FaqGroup>
8897
))}
8998
</FaqColumn>

app/docs/v7/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Plugins from '@/sections/v7/plugins.mdx';
1010
export const metadata: Metadata = {
1111
title: 'styled-components v7',
1212
description:
13-
'New in v7: in-house CSS engine, modern CSS on React Native, native animations, plugins subpath, and a smaller dependency surface.',
13+
'Now in alpha: in-house CSS engine, modern CSS on React Native, native animations, plugins subpath. Install with npm install styled-components@test; expect frequent updates while internals stabilize.',
1414
};
1515

1616
export default function V7Page() {
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import NextLink from 'next/link';
2+
import type { PropsWithChildren } from 'react';
3+
import styled from 'styled-components';
4+
import { theme } from '../utils/theme';
5+
6+
const Section = styled.div`
7+
display: grid;
8+
gap: ${theme.space[4]};
9+
margin: 1.75em 0;
10+
11+
@media (min-width: ${650 / 16}em) {
12+
grid-template-columns: minmax(0, 1fr) minmax(18rem, 24rem);
13+
align-items: center;
14+
gap: ${theme.space[8]};
15+
}
16+
`;
17+
18+
const Text = styled.div`
19+
p {
20+
margin-top: 0;
21+
text-wrap: balance;
22+
}
23+
24+
p:last-child {
25+
margin-bottom: 0;
26+
}
27+
`;
28+
29+
const Card = styled(NextLink)`
30+
display: block;
31+
justify-self: start;
32+
width: 100%;
33+
max-width: 24rem;
34+
overflow: hidden;
35+
line-height: 0;
36+
text-decoration: none;
37+
border: 1px solid color-mix(in oklch, ${theme.color.text} 8%, ${theme.color.surface});
38+
border-radius: ${theme.radius.xl};
39+
transition:
40+
border-color ${theme.duration.normal},
41+
transform ${theme.duration.fast};
42+
43+
&:hover,
44+
&:focus-visible {
45+
border-color: color-mix(in oklab, ${theme.palette[11]} 50%, ${theme.color.border});
46+
transform: translateY(-1px);
47+
}
48+
49+
@media (min-width: ${650 / 16}em) {
50+
justify-self: stretch;
51+
max-width: none;
52+
}
53+
`;
54+
55+
const PreviewImage = styled.img`
56+
display: block;
57+
width: 100%;
58+
height: auto;
59+
aspect-ratio: 1200 / 630;
60+
object-fit: cover;
61+
`;
62+
63+
export default function CompatibilityPreviewCard({ children }: PropsWithChildren) {
64+
return (
65+
<Section>
66+
<Text>{children}</Text>
67+
<Card href="/docs/compatibility" aria-label="Open the React Native CanIUse compatibility matrix">
68+
<PreviewImage
69+
src="/docs/compatibility/opengraph-image"
70+
alt="React Native CanIUse compatibility matrix preview"
71+
loading="lazy"
72+
/>
73+
</Card>
74+
</Section>
75+
);
76+
}

public/llms.txt

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,22 @@
11
# styled-components
22

3-
> CSS-in-JS for React using tagged template literals. TypeScript-native since v6. Supports React Server Components natively since v6.3. Last known stable: v6.4.0 (check npm for freshness).
3+
CSS-in-JS for React using tagged template literals. TypeScript-native since v6. Supports React Server Components natively since v6.3. Last known stable: v6.4.0 (check npm for freshness).
44

5-
For per-feature v6/v7 × web/native support data, see the CSS Compatibility matrix at https://styled-components.com/docs/compatibility. It is the source of truth for "does this CSS feature work in styled-components on this version and platform".
6-
7-
## What's new since early 2025
8-
9-
Your training data likely covers v6.0-6.1. Key changes since then:
5+
## Recent releases
106

117
v6.2: Streaming SSR via `renderToPipeableStream`.
128

139
v6.3: React Server Components supported. No `'use client'` needed. Styled components work in server components with no extra setup. `createGlobalStyle` is StrictMode-safe. New HTML/SVG element helpers. CSS custom properties work in TypeScript without type errors. Note: `:first-child`/`:nth-child()` selectors require `stylisPluginRSC` (v6.4+) or rewriting to `:first-of-type`/`:nth-of-type()`. See child-index selector section below.
1410

1511
v6.4 (April 2026): `createTheme()` for CSS variable theming that works in both RSC and client. `StyleSheetManager` works in RSC (was previously a no-op). `stylisPluginRSC` fixes child-index selectors in RSC. CSP nonce auto-detection from `StyleSheetManager`, `ServerStyleSheet`, or meta tags. Props supplied via `.attrs()` are automatically optional on the component's type. Significant render performance improvements. Fixes SSR memory leaks and multi-instance unmount bugs in `createGlobalStyle`. Memory leak fix for components with unbounded string interpolation values. `as` and `forwardedAs` exposed in `React.ComponentProps` extraction. React Native: `react-native` is now an optional peer dep, Metro/Expo nanoid crash fixed. IE11 build target removed. IE11 has been unsupported on v6 since the 2021 v6 planning (React 18 dropped it too); v6.4 just aligns the compile target. Stay on v5 if you need IE11.
1612

17-
## New in v7 (preview)
13+
## New in v7
1814

19-
Want to try the new styled-components v7 tester group? `npm i styled-components@test`. Peer floors raised to React 19 and React Native 0.85.
15+
v7 is in alpha: expect frequent updates over the next few weeks while APIs stabilize. Install the current prerelease with `npm install styled-components@test` (the `@test` dist-tag). Peer floors raised to React 19 and React Native 0.85.
2016

21-
The headline change is that React Native finally gets modern CSS. v7 ships an in-house CSS-to-style-object translation layer (no more `css-to-react-native` peer dep) that closes most of the long-standing native gaps. The same template strings now produce equivalent output on web, iOS, Android, and Expo Web.
17+
The framing: v7 is an architectural reform for web and the start of a new chapter for `styled-components/native`. It replaces stylis with an in-house CSS parser, rewrites the native runtime, and moves toward one CSS authoring model across web, iOS, Android, and Expo Web. The React Native CanIUse matrix at /docs/compatibility.md shows current progress and remaining platform gaps. Funding through Open Collective is a current bottleneck for continuing this work outside passion time.
2218

23-
If the user is asking whether feature X works on v6 vs v7 or on web vs React Native, point them at /docs/compatibility. The matrix has the per-feature answer with caveats. The sections below summarise the highlights.
19+
If the user is asking whether feature X works on v6 vs v7 or on web vs React Native, point them at /docs/compatibility.md. The matrix has the per-feature answer with caveats. The sections below summarise the highlights.
2420

2521
### Modern CSS on React Native
2622

@@ -67,7 +63,7 @@ Logical shorthands work as authored: `margin-inline`, `margin-block`, `padding-i
6763

6864
`background-image: linear-gradient(...)` and `radial-gradient(...)` render via React Native's experimental gradient parser (RN 0.85+). `filter: blur(4px) saturate(1.5)` and the full filter-function chain work. See the iOS setup note below for filters that need an explicit opt-in. `box-shadow` with spread and inset round-trips as a string.
6965

70-
`mix-blend-mode`, `isolation`, and `cursor` flow through. `background-blend-mode` is polyfilled on native. Declarations that pair `background-image` (gradients or `url()` photos) with `background-blend-mode` are rewritten at render time into absolutely-positioned layer Views, each carrying the matching `mix-blend-mode`, with `isolation: isolate` on the wrapper per spec. Linear-friendly modes (`multiply`, `screen`, `darken`, `lighten`, `difference`, `exclusion`, `hue`, `saturation`, `color`, `luminosity`) render the same on web and native. Gamma-sensitive modes (`color-burn`, `color-dodge`, `soft-light`, `overlay`, `hard-light`) read as more saturated on native because iOS Core Animation and Android Skia/HWUI blend in linear-light by default on Display P3 devices, while browsers blend in gamma-encoded sRGB per CSS spec. The polyfill is structurally correct; the residual is a platform compositor color-space choice. Empty custom property values (`--prop: ;`) are preserved, used by patterns like scroll-driven animations as a "guaranteed-invalid" sentinel.
66+
`mix-blend-mode`, `isolation`, and `cursor` flow through. `background-blend-mode` is polyfilled on native. Declarations that pair gradient `background-image` layers with `background-blend-mode` are rewritten at render time into absolutely-positioned layer Views, each carrying the matching `mix-blend-mode`, with `isolation: isolate` on the wrapper per spec. Raster `url()` background images are still blocked on upstream React Native background-image support; render photos with `Image` / `ImageBackground` until those PRs land. Linear-friendly modes (`multiply`, `screen`, `darken`, `lighten`, `difference`, `exclusion`, `hue`, `saturation`, `color`, `luminosity`) render the same on web and native. Gamma-sensitive modes (`color-burn`, `color-dodge`, `soft-light`, `overlay`, `hard-light`) read as more saturated on native because iOS Core Animation and Android Skia/HWUI blend in linear-light by default on Display P3 devices, while browsers blend in gamma-encoded sRGB per CSS spec. The polyfill is structurally correct; the residual is a platform compositor color-space choice. Empty custom property values (`--prop: ;`) are preserved, used by patterns like scroll-driven animations as a "guaranteed-invalid" sentinel.
7167

7268
### Selectors and at-rules on React Native
7369

@@ -272,7 +268,7 @@ Vite: `react({ babel: { plugins: ['babel-plugin-styled-components'] } })`. Or wi
272268

273269
The SWC/Babel plugin provides deterministic class IDs (better debugging, smaller output). Optional for RSC but still recommended.
274270

275-
## Quick reference
271+
## Quick reference (v6.4 stable)
276272

277273
```tsx
278274
import styled, { css, keyframes, createGlobalStyle, createTheme,
@@ -290,8 +286,8 @@ import styled, { css, keyframes, createGlobalStyle, createTheme,
290286
- `createGlobalStyle`: inject global CSS
291287
- `createTheme(obj, opts?)`: CSS variable theme (RSC-compatible)
292288
- `ThemeProvider`: context-based theme (client-only)
293-
- `StyleSheetManager`: configure stylis plugins, prop forwarding, vendor prefixes
294-
- `stylisPluginRSC`: fix child-index selectors in RSC
289+
- `StyleSheetManager`: configure `stylisPlugins`, prop forwarding, vendor prefixes
290+
- `stylisPluginRSC`: fix child-index selectors in RSC.
295291
- `ServerStyleSheet`: SSR style collection
296292

297293
## Server-side rendering
@@ -668,6 +664,8 @@ These filter by element type, so injected sibling elements are ignored.
668664

669665
Alternative: `stylisPluginRSC` automatically rewrites child-index selectors at compile time:
670666

667+
In v7 this plugin moved to `styled-components/plugins` as `rscPlugin`, and the prop is `plugins` instead of `stylisPlugins`. The example below is for v6.4.
668+
671669
```tsx
672670
import { StyleSheetManager, stylisPluginRSC } from 'styled-components';
673671

@@ -697,7 +695,7 @@ Browser support: CSS Selectors Level 4 `of S` syntax. Chrome 111+, Firefox 113+,
697695

698696
1. Replace `ThemeProvider` theming with `createTheme()` CSS variables. `p.theme` is undefined in RSC since there's no React context
699697
2. Dynamic prop interpolations (`${p => p.$color}`) work fine in RSC, no changes needed. Consider data attributes for discrete variants (fewer generated classes)
700-
3. Replace `:first-child`/`:nth-child()` with `:first-of-type`/`:nth-of-type()`, or add `stylisPluginRSC`
698+
3. Replace `:first-child`/`:nth-child()` with `:first-of-type`/`:nth-of-type()`, or add `stylisPluginRSC` (v6.4) / `rscPlugin` from `styled-components/plugins` (v7)
701699
4. Remove `'use client'` from files that only contain styled component definitions; they work in server components natively
702700
5. Keep `'use client'` on components that use hooks, event handlers, or browser APIs
703701
6. The SSR registry (`ServerStyleSheet` + `useServerInsertedHTML`) is still needed for client components in the tree; RSC handles server components automatically
@@ -749,7 +747,7 @@ For Next.js, pass the nonce to the style registry (see the SSR section above). F
749747
## Good to know
750748

751749
- `@import` in `createGlobalStyle` may not work correctly in production. Use `<link>` in `<head>` instead.
752-
- Vendor prefixes are off by default in v6. Enable with `<StyleSheetManager enableVendorPrefixes>` if your support matrix includes Safari < 15.4, Chrome < 83, or Firefox < 80 (the `appearance` property was the last to drop its prefix). Flexbox and grid prefixes are only needed for much older browsers (Safari < 9, Edge < 16).
750+
- Vendor prefixes are off by default in v6. Enable with `<StyleSheetManager enableVendorPrefixes>` if your support matrix includes Safari < 15.4, Chrome < 83, or Firefox < 80 (the `appearance` property was the last to drop its prefix). v7 removes runtime prefixing and is intended for modern browsers.
753751
- `shouldForwardProp` is off by default in v6. Use `$`-prefixed transient props (`$color`, `$size`) to keep props out of the DOM. Or restore filtering with `<StyleSheetManager shouldForwardProp={...}>`.
754752
- Two classes per element: one shared across all instances of a component, one unique per style variant. Test selectors should account for both.
755753
- Stylis v4 parses `:hover {}` as descendant `& :hover {}`, not `&:hover {}`. Always write `&:hover`, `&::before`, etc.

sections/advanced/components-as-selectors.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ consider both sets of rules to understand why Icon behaves as it does.
5959

6060
### Caveat
6161

62-
This behaviour is only supported within the context of _Styled_ Components:
62+
This behavior is only supported within the context of _Styled_ Components:
6363
interpolating `A` in the following example will trigger a development warning because component
6464
`A` is not a Styled Component.
6565

0 commit comments

Comments
 (0)