@typestyles/next 0.0.0-unstable.247bf362710f → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +11 -40
- package/dist/index.js +11 -35
- package/package.json +1 -12
- package/src/index.tsx +99 -20
- package/README.md +0 -303
- package/dist/client.cjs +0 -72
- package/dist/client.js +0 -45
- package/dist/server.cjs +0 -52
- package/dist/server.js +0 -15
- package/src/client.d.ts +0 -34
- package/src/client.tsx +0 -143
- package/src/server.ts +0 -54
package/dist/index.cjs
CHANGED
|
@@ -33,55 +33,29 @@ __export(index_exports, {
|
|
|
33
33
|
TypestylesStylesheet: () => TypestylesStylesheet,
|
|
34
34
|
collectStylesFromComponent: () => collectStylesFromComponent,
|
|
35
35
|
createTypestylesLayout: () => createTypestylesLayout,
|
|
36
|
-
getRegisteredCss: () => import_server.getRegisteredCss
|
|
37
|
-
getTypestylesMetadata: () => getTypestylesMetadata,
|
|
38
|
-
useServerInsertedHTML: () => import_react.useServerInsertedHTML,
|
|
39
|
-
useTypestyles: () => useTypestyles
|
|
36
|
+
getRegisteredCss: () => import_server.getRegisteredCss
|
|
40
37
|
});
|
|
41
38
|
module.exports = __toCommonJS(index_exports);
|
|
42
|
-
|
|
43
|
-
// src/server.ts
|
|
44
|
-
var import_server = require("typestyles/server");
|
|
45
|
-
async function collectStylesFromComponent(component) {
|
|
46
|
-
const { renderToString } = await import("react-dom/server");
|
|
47
|
-
const { css } = (0, import_server.collectStyles)(() => renderToString(component));
|
|
48
|
-
return css;
|
|
49
|
-
}
|
|
50
|
-
async function getTypestylesMetadata(component) {
|
|
51
|
-
return collectStylesFromComponent(component);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// src/client.tsx
|
|
55
39
|
var import_react = require("react");
|
|
56
|
-
var
|
|
40
|
+
var import_server = require("typestyles/server");
|
|
57
41
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
58
|
-
function useTypestyles() {
|
|
59
|
-
return (0, import_react.useSyncExternalStore)(
|
|
60
|
-
() => () => {
|
|
61
|
-
},
|
|
62
|
-
() => (0, import_server2.getRegisteredCss)(),
|
|
63
|
-
() => ""
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
42
|
function TypestylesStylesheet({ children }) {
|
|
67
43
|
const [css, setCss] = (0, import_react.useState)("");
|
|
68
|
-
(0, import_react.useServerInsertedHTML)(() => {
|
|
69
|
-
const registeredCss = (0, import_server2.getRegisteredCss)();
|
|
70
|
-
if (registeredCss) {
|
|
71
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { id: "typestyles", dangerouslySetInnerHTML: { __html: registeredCss } });
|
|
72
|
-
}
|
|
73
|
-
return null;
|
|
74
|
-
});
|
|
75
44
|
(0, import_react.useEffect)(() => {
|
|
76
|
-
setCss((0,
|
|
45
|
+
setCss((0, import_server.getRegisteredCss)());
|
|
77
46
|
}, []);
|
|
78
47
|
if (children) {
|
|
79
48
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
80
49
|
children,
|
|
81
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { id: "typestyles
|
|
50
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { id: "typestyles", dangerouslySetInnerHTML: { __html: css } })
|
|
82
51
|
] });
|
|
83
52
|
}
|
|
84
|
-
return
|
|
53
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { id: "typestyles", dangerouslySetInnerHTML: { __html: css } });
|
|
54
|
+
}
|
|
55
|
+
async function collectStylesFromComponent(component) {
|
|
56
|
+
const { renderToString } = await import("react-dom/server");
|
|
57
|
+
const { css } = (0, import_server.collectStyles)(() => renderToString(component));
|
|
58
|
+
return css;
|
|
85
59
|
}
|
|
86
60
|
function createTypestylesLayout(layout) {
|
|
87
61
|
return function TypestylesLayout(props) {
|
|
@@ -93,8 +67,5 @@ function createTypestylesLayout(layout) {
|
|
|
93
67
|
TypestylesStylesheet,
|
|
94
68
|
collectStylesFromComponent,
|
|
95
69
|
createTypestylesLayout,
|
|
96
|
-
getRegisteredCss
|
|
97
|
-
getTypestylesMetadata,
|
|
98
|
-
useServerInsertedHTML,
|
|
99
|
-
useTypestyles
|
|
70
|
+
getRegisteredCss
|
|
100
71
|
});
|
package/dist/index.js
CHANGED
|
@@ -1,45 +1,24 @@
|
|
|
1
|
-
// src/
|
|
1
|
+
// src/index.tsx
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
2
3
|
import { collectStyles, getRegisteredCss } from "typestyles/server";
|
|
3
|
-
async function collectStylesFromComponent(component) {
|
|
4
|
-
const { renderToString } = await import("react-dom/server");
|
|
5
|
-
const { css } = collectStyles(() => renderToString(component));
|
|
6
|
-
return css;
|
|
7
|
-
}
|
|
8
|
-
async function getTypestylesMetadata(component) {
|
|
9
|
-
return collectStylesFromComponent(component);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// src/client.tsx
|
|
13
|
-
import { useState, useEffect, useServerInsertedHTML, useSyncExternalStore } from "react";
|
|
14
|
-
import { getRegisteredCss as getRegisteredCss2 } from "typestyles/server";
|
|
15
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
16
|
-
function useTypestyles() {
|
|
17
|
-
return useSyncExternalStore(
|
|
18
|
-
() => () => {
|
|
19
|
-
},
|
|
20
|
-
() => getRegisteredCss2(),
|
|
21
|
-
() => ""
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
5
|
function TypestylesStylesheet({ children }) {
|
|
25
6
|
const [css, setCss] = useState("");
|
|
26
|
-
useServerInsertedHTML(() => {
|
|
27
|
-
const registeredCss = getRegisteredCss2();
|
|
28
|
-
if (registeredCss) {
|
|
29
|
-
return /* @__PURE__ */ jsx("style", { id: "typestyles", dangerouslySetInnerHTML: { __html: registeredCss } });
|
|
30
|
-
}
|
|
31
|
-
return null;
|
|
32
|
-
});
|
|
33
7
|
useEffect(() => {
|
|
34
|
-
setCss(
|
|
8
|
+
setCss(getRegisteredCss());
|
|
35
9
|
}, []);
|
|
36
10
|
if (children) {
|
|
37
11
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
38
12
|
children,
|
|
39
|
-
/* @__PURE__ */ jsx("style", { id: "typestyles
|
|
13
|
+
/* @__PURE__ */ jsx("style", { id: "typestyles", dangerouslySetInnerHTML: { __html: css } })
|
|
40
14
|
] });
|
|
41
15
|
}
|
|
42
|
-
return
|
|
16
|
+
return /* @__PURE__ */ jsx("style", { id: "typestyles", dangerouslySetInnerHTML: { __html: css } });
|
|
17
|
+
}
|
|
18
|
+
async function collectStylesFromComponent(component) {
|
|
19
|
+
const { renderToString } = await import("react-dom/server");
|
|
20
|
+
const { css } = collectStyles(() => renderToString(component));
|
|
21
|
+
return css;
|
|
43
22
|
}
|
|
44
23
|
function createTypestylesLayout(layout) {
|
|
45
24
|
return function TypestylesLayout(props) {
|
|
@@ -50,8 +29,5 @@ export {
|
|
|
50
29
|
TypestylesStylesheet,
|
|
51
30
|
collectStylesFromComponent,
|
|
52
31
|
createTypestylesLayout,
|
|
53
|
-
getRegisteredCss
|
|
54
|
-
getTypestylesMetadata,
|
|
55
|
-
useServerInsertedHTML,
|
|
56
|
-
useTypestyles
|
|
32
|
+
getRegisteredCss
|
|
57
33
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typestyles/next",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Next.js integration for typestyles SSR",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -11,17 +11,6 @@
|
|
|
11
11
|
"types": "./src/index.d.ts",
|
|
12
12
|
"import": "./dist/index.js",
|
|
13
13
|
"require": "./dist/index.cjs"
|
|
14
|
-
},
|
|
15
|
-
"./server": {
|
|
16
|
-
"types": "./src/server.d.ts",
|
|
17
|
-
"import": "./dist/server.js",
|
|
18
|
-
"require": "./dist/server.cjs"
|
|
19
|
-
},
|
|
20
|
-
"./client": {
|
|
21
|
-
"types": "./src/client.d.ts",
|
|
22
|
-
"import": "./dist/client.js",
|
|
23
|
-
"require": "./dist/client.cjs",
|
|
24
|
-
"default": "./dist/client.js"
|
|
25
14
|
}
|
|
26
15
|
},
|
|
27
16
|
"files": [
|
package/src/index.tsx
CHANGED
|
@@ -1,27 +1,106 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { collectStyles, getRegisteredCss } from 'typestyles/server';
|
|
3
|
+
|
|
4
|
+
export { getRegisteredCss };
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Props for the TypestylesStylesheet component.
|
|
8
|
+
*/
|
|
9
|
+
export interface TypestylesStylesheetProps {
|
|
10
|
+
/**
|
|
11
|
+
* The children to render (styles will be collected from these).
|
|
12
|
+
* If not provided, only the existing registered CSS will be included.
|
|
13
|
+
*/
|
|
14
|
+
children?: React.ReactNode;
|
|
15
|
+
}
|
|
16
|
+
|
|
1
17
|
/**
|
|
2
|
-
*
|
|
18
|
+
* A React component that renders typestyles CSS.
|
|
19
|
+
*
|
|
20
|
+
* For App Router: Use this in your root layout to collect and render styles.
|
|
3
21
|
*
|
|
4
|
-
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* // app/layout.tsx
|
|
25
|
+
* import { TypestylesStylesheet } from '@typestyles/next';
|
|
5
26
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
27
|
+
* export default function RootLayout({ children }) {
|
|
28
|
+
* return (
|
|
29
|
+
* <html>
|
|
30
|
+
* <head>
|
|
31
|
+
* <TypestylesStylesheet />
|
|
32
|
+
* </head>
|
|
33
|
+
* <body>{children}</body>
|
|
34
|
+
* </html>
|
|
35
|
+
* );
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export function TypestylesStylesheet({ children }: TypestylesStylesheetProps) {
|
|
40
|
+
const [css, setCss] = useState('');
|
|
41
|
+
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
// On client: get any CSS that was registered before hydration
|
|
44
|
+
setCss(getRegisteredCss());
|
|
45
|
+
}, []);
|
|
46
|
+
|
|
47
|
+
if (children) {
|
|
48
|
+
return (
|
|
49
|
+
<>
|
|
50
|
+
{children}
|
|
51
|
+
<style id="typestyles" dangerouslySetInnerHTML={{ __html: css }} />
|
|
52
|
+
</>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return <style id="typestyles" dangerouslySetInnerHTML={{ __html: css }} />;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Collect styles from a React component and return them as a string.
|
|
61
|
+
* Useful for server components or when you need more control.
|
|
9
62
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```tsx
|
|
65
|
+
* // app/styles.ts
|
|
66
|
+
* import { collectStylesFromComponent } from '@typestyles/next';
|
|
67
|
+
* import { YourApp } from './YourApp';
|
|
12
68
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
69
|
+
* export async function getStyles() {
|
|
70
|
+
* return collectStylesFromComponent(<YourApp />);
|
|
71
|
+
* }
|
|
72
|
+
* ```
|
|
15
73
|
*/
|
|
74
|
+
export async function collectStylesFromComponent(component: React.ReactElement): Promise<string> {
|
|
75
|
+
const { renderToString } = await import('react-dom/server');
|
|
76
|
+
const { css } = collectStyles(() => renderToString(component));
|
|
77
|
+
return css;
|
|
78
|
+
}
|
|
16
79
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Create a Next.js layout export that includes typestyles.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```tsx
|
|
85
|
+
* // app/layout.tsx
|
|
86
|
+
* import { createTypestylesLayout } from '@typestyles/next';
|
|
87
|
+
*
|
|
88
|
+
* export default createTypestylesLayout(function RootLayout({ children }) {
|
|
89
|
+
* return (
|
|
90
|
+
* <html>
|
|
91
|
+
* <head>
|
|
92
|
+
* <title>My App</title>
|
|
93
|
+
* </head>
|
|
94
|
+
* <body>{children}</body>
|
|
95
|
+
* </html>
|
|
96
|
+
* );
|
|
97
|
+
* });
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export function createTypestylesLayout<P extends { children?: React.ReactNode }>(
|
|
101
|
+
layout: (props: P) => React.ReactNode,
|
|
102
|
+
): (props: P) => React.ReactNode {
|
|
103
|
+
return function TypestylesLayout(props: P) {
|
|
104
|
+
return <TypestylesStylesheet>{layout(props)}</TypestylesStylesheet>;
|
|
105
|
+
};
|
|
106
|
+
}
|
package/README.md
DELETED
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
# @typestyles/next
|
|
2
|
-
|
|
3
|
-
Next.js integration for typestyles with full support for App Router, Pages Router, and React Server Components.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install @typestyles/next typestyles
|
|
9
|
-
# or
|
|
10
|
-
pnpm add @typestyles/next typestyles
|
|
11
|
-
# or
|
|
12
|
-
yarn add @typestyles/next typestyles
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## Requirements
|
|
16
|
-
|
|
17
|
-
- Next.js >= 13.0.0
|
|
18
|
-
- React >= 18.0.0
|
|
19
|
-
- typestyles >= 0.1.0
|
|
20
|
-
|
|
21
|
-
## Quick Start
|
|
22
|
-
|
|
23
|
-
### App Router (Recommended)
|
|
24
|
-
|
|
25
|
-
Import `getRegisteredCss` in your root layout to inject styles during SSR:
|
|
26
|
-
|
|
27
|
-
```tsx
|
|
28
|
-
// app/layout.tsx
|
|
29
|
-
import { getRegisteredCss } from '@typestyles/next';
|
|
30
|
-
|
|
31
|
-
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
32
|
-
const css = getRegisteredCss();
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<html lang="en">
|
|
36
|
-
<head>{css && <style dangerouslySetInnerHTML={{ __html: css }} />}</head>
|
|
37
|
-
<body>{children}</body>
|
|
38
|
-
</html>
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### Pages Router
|
|
44
|
-
|
|
45
|
-
Wrap your pages with the stylesheet component:
|
|
46
|
-
|
|
47
|
-
```tsx
|
|
48
|
-
// pages/_app.tsx
|
|
49
|
-
import { TypestylesStylesheet } from '@typestyles/next';
|
|
50
|
-
import type { AppProps } from 'next/app';
|
|
51
|
-
|
|
52
|
-
export default function App({ Component, pageProps }: AppProps) {
|
|
53
|
-
return (
|
|
54
|
-
<TypestylesStylesheet>
|
|
55
|
-
<Component {...pageProps} />
|
|
56
|
-
</TypestylesStylesheet>
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## React Server Components (RSC)
|
|
62
|
-
|
|
63
|
-
The package provides multiple approaches for RSC support:
|
|
64
|
-
|
|
65
|
-
### Option 1: Layout SSR (Simplest)
|
|
66
|
-
|
|
67
|
-
Import `getRegisteredCss` in your root layout - this works in both Server and Client Components:
|
|
68
|
-
|
|
69
|
-
```tsx
|
|
70
|
-
// app/layout.tsx
|
|
71
|
-
import { getRegisteredCss } from '@typestyles/next';
|
|
72
|
-
|
|
73
|
-
export default function RootLayout({ children }) {
|
|
74
|
-
const css = getRegisteredCss();
|
|
75
|
-
|
|
76
|
-
return (
|
|
77
|
-
<html>
|
|
78
|
-
<head>{css && <style dangerouslySetInnerHTML={{ __html: css }} />}</head>
|
|
79
|
-
<body>{children}</body>
|
|
80
|
-
</html>
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### Option 2: Client Component Provider
|
|
86
|
-
|
|
87
|
-
For complex cases with dynamic styles, create a client component wrapper:
|
|
88
|
-
|
|
89
|
-
```tsx
|
|
90
|
-
// components/TypestylesProvider.tsx
|
|
91
|
-
'use client';
|
|
92
|
-
|
|
93
|
-
import { getRegisteredCss } from 'typestyles/server';
|
|
94
|
-
import { useEffect, useState } from 'react';
|
|
95
|
-
|
|
96
|
-
export function TypestylesProvider({ children }) {
|
|
97
|
-
const [css, setCss] = useState('');
|
|
98
|
-
const [mounted, setMounted] = useState(false);
|
|
99
|
-
|
|
100
|
-
useEffect(() => {
|
|
101
|
-
setMounted(true);
|
|
102
|
-
setCss(getRegisteredCss());
|
|
103
|
-
}, []);
|
|
104
|
-
|
|
105
|
-
return (
|
|
106
|
-
<>
|
|
107
|
-
{children}
|
|
108
|
-
{mounted && css && <style id="typestyles" dangerouslySetInnerHTML={{ __html: css }} />}
|
|
109
|
-
</>
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Then use it in your layout:
|
|
115
|
-
|
|
116
|
-
```tsx
|
|
117
|
-
// app/layout.tsx
|
|
118
|
-
import { TypestylesProvider } from '@/components/TypestylesProvider';
|
|
119
|
-
|
|
120
|
-
export default function RootLayout({ children }) {
|
|
121
|
-
return (
|
|
122
|
-
<html>
|
|
123
|
-
<body>
|
|
124
|
-
<TypestylesProvider>{children}</TypestylesProvider>
|
|
125
|
-
</body>
|
|
126
|
-
</html>
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
### Option 3: Metadata API
|
|
132
|
-
|
|
133
|
-
For static generation, you can collect styles in `generateMetadata`:
|
|
134
|
-
|
|
135
|
-
```tsx
|
|
136
|
-
// app/layout.tsx
|
|
137
|
-
import { generateMetadata } from 'next';
|
|
138
|
-
import { getTypestylesMetadata } from '@typestyles/next/server';
|
|
139
|
-
import { Home } from './Home';
|
|
140
|
-
|
|
141
|
-
export async function generateMetadata() {
|
|
142
|
-
const css = await getTypestylesMetadata(<Home />);
|
|
143
|
-
return {
|
|
144
|
-
styles: [{ cssText: css, id: 'typestyles' }],
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
## API Reference
|
|
150
|
-
|
|
151
|
-
### getRegisteredCss
|
|
152
|
-
|
|
153
|
-
Returns all currently registered CSS as a string. This is the simplest way to get styles for SSR.
|
|
154
|
-
|
|
155
|
-
```tsx
|
|
156
|
-
import { getRegisteredCss } from '@typestyles/next';
|
|
157
|
-
|
|
158
|
-
const css = getRegisteredCss();
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
### collectStylesFromComponent
|
|
162
|
-
|
|
163
|
-
Collect styles from a React component tree. Useful when you need explicit control over style collection.
|
|
164
|
-
|
|
165
|
-
```tsx
|
|
166
|
-
import { collectStylesFromComponent } from '@typestyles/next/server';
|
|
167
|
-
import { YourComponent } from './YourComponent';
|
|
168
|
-
|
|
169
|
-
const css = await collectStylesFromComponent(<YourComponent />);
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### getTypestylesMetadata
|
|
173
|
-
|
|
174
|
-
Generate CSS for use in Next.js metadata API. Collects styles by rendering the component server-side.
|
|
175
|
-
|
|
176
|
-
```tsx
|
|
177
|
-
import { getTypestylesMetadata } from '@typestyles/next/server';
|
|
178
|
-
import { Home } from './Home';
|
|
179
|
-
|
|
180
|
-
const css = await getTypestylesMetadata(<Home />);
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### TypestylesStylesheet (Pages Router)
|
|
184
|
-
|
|
185
|
-
A React component that renders typestyles CSS. Works with Pages Router.
|
|
186
|
-
|
|
187
|
-
```tsx
|
|
188
|
-
import { TypestylesStylesheet } from '@typestyles/next';
|
|
189
|
-
|
|
190
|
-
<TypestylesStylesheet>
|
|
191
|
-
<YourApp />
|
|
192
|
-
</TypestylesStylesheet>;
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
## Examples
|
|
196
|
-
|
|
197
|
-
### Basic Usage with App Router
|
|
198
|
-
|
|
199
|
-
```tsx
|
|
200
|
-
// app/page.tsx
|
|
201
|
-
import { styles } from 'typestyles';
|
|
202
|
-
|
|
203
|
-
const button = styles.create('button', {
|
|
204
|
-
base: {
|
|
205
|
-
padding: '12px 24px',
|
|
206
|
-
backgroundColor: '#0066ff',
|
|
207
|
-
color: 'white',
|
|
208
|
-
border: 'none',
|
|
209
|
-
borderRadius: '6px',
|
|
210
|
-
cursor: 'pointer',
|
|
211
|
-
},
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
export default function Home() {
|
|
215
|
-
return (
|
|
216
|
-
<main>
|
|
217
|
-
<button className={button('base')}>Click me</button>
|
|
218
|
-
</main>
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
### With Design Tokens
|
|
224
|
-
|
|
225
|
-
```tsx
|
|
226
|
-
// app/tokens.ts
|
|
227
|
-
import { tokens } from 'typestyles';
|
|
228
|
-
|
|
229
|
-
export const colors = tokens.create('color', {
|
|
230
|
-
primary: '#0066ff',
|
|
231
|
-
secondary: '#64748b',
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
export const spacing = tokens.create('space', {
|
|
235
|
-
sm: '8px',
|
|
236
|
-
md: '16px',
|
|
237
|
-
lg: '24px',
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
// app/page.tsx
|
|
241
|
-
import { styles } from 'typestyles';
|
|
242
|
-
import { colors, spacing } from './tokens';
|
|
243
|
-
|
|
244
|
-
const card = styles.create('card', {
|
|
245
|
-
base: {
|
|
246
|
-
padding: spacing.md,
|
|
247
|
-
backgroundColor: colors.primary,
|
|
248
|
-
borderRadius: '8px',
|
|
249
|
-
},
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
export default function Page() {
|
|
253
|
-
return <div className={card('base')}>Hello World</div>;
|
|
254
|
-
}
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
### With Dark Mode
|
|
258
|
-
|
|
259
|
-
```tsx
|
|
260
|
-
// app/layout.tsx
|
|
261
|
-
import { tokens } from 'typestyles';
|
|
262
|
-
import { getRegisteredCss } from '@typestyles/next';
|
|
263
|
-
|
|
264
|
-
const darkTheme = tokens.createTheme('dark', {
|
|
265
|
-
color: {
|
|
266
|
-
background: '#1a1a1a',
|
|
267
|
-
text: '#ffffff',
|
|
268
|
-
},
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
export default function RootLayout({ children }) {
|
|
272
|
-
const css = getRegisteredCss();
|
|
273
|
-
|
|
274
|
-
return (
|
|
275
|
-
<html className={darkTheme}>
|
|
276
|
-
<head>{css && <style dangerouslySetInnerHTML={{ __html: css }} />}</head>
|
|
277
|
-
<body>{children}</body>
|
|
278
|
-
</html>
|
|
279
|
-
);
|
|
280
|
-
}
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
## Troubleshooting
|
|
284
|
-
|
|
285
|
-
### Flash of Unstyled Content (FOUC)
|
|
286
|
-
|
|
287
|
-
If you see a flash of unstyled content, ensure `getRegisteredCss()` is called in the layout and styles are injected before the body renders.
|
|
288
|
-
|
|
289
|
-
### Styles not appearing
|
|
290
|
-
|
|
291
|
-
Make sure `typestyles` is installed in your project:
|
|
292
|
-
|
|
293
|
-
```bash
|
|
294
|
-
npm install typestyles
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
### TypeScript errors
|
|
298
|
-
|
|
299
|
-
Ensure you have `"moduleResolution": "bundler"` or `"node"` in your `tsconfig.json`.
|
|
300
|
-
|
|
301
|
-
## License
|
|
302
|
-
|
|
303
|
-
MIT
|
package/dist/client.cjs
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
"use client";
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
-
|
|
21
|
-
// src/client.tsx
|
|
22
|
-
var client_exports = {};
|
|
23
|
-
__export(client_exports, {
|
|
24
|
-
TypestylesStylesheet: () => TypestylesStylesheet,
|
|
25
|
-
createTypestylesLayout: () => createTypestylesLayout,
|
|
26
|
-
useServerInsertedHTML: () => import_react.useServerInsertedHTML,
|
|
27
|
-
useTypestyles: () => useTypestyles
|
|
28
|
-
});
|
|
29
|
-
module.exports = __toCommonJS(client_exports);
|
|
30
|
-
var import_react = require("react");
|
|
31
|
-
var import_server = require("typestyles/server");
|
|
32
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
33
|
-
function useTypestyles() {
|
|
34
|
-
return (0, import_react.useSyncExternalStore)(
|
|
35
|
-
() => () => {
|
|
36
|
-
},
|
|
37
|
-
() => (0, import_server.getRegisteredCss)(),
|
|
38
|
-
() => ""
|
|
39
|
-
);
|
|
40
|
-
}
|
|
41
|
-
function TypestylesStylesheet({ children }) {
|
|
42
|
-
const [css, setCss] = (0, import_react.useState)("");
|
|
43
|
-
(0, import_react.useServerInsertedHTML)(() => {
|
|
44
|
-
const registeredCss = (0, import_server.getRegisteredCss)();
|
|
45
|
-
if (registeredCss) {
|
|
46
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { id: "typestyles", dangerouslySetInnerHTML: { __html: registeredCss } });
|
|
47
|
-
}
|
|
48
|
-
return null;
|
|
49
|
-
});
|
|
50
|
-
(0, import_react.useEffect)(() => {
|
|
51
|
-
setCss((0, import_server.getRegisteredCss)());
|
|
52
|
-
}, []);
|
|
53
|
-
if (children) {
|
|
54
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
55
|
-
children,
|
|
56
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { id: "typestyles-client", dangerouslySetInnerHTML: { __html: css } })
|
|
57
|
-
] });
|
|
58
|
-
}
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
function createTypestylesLayout(layout) {
|
|
62
|
-
return function TypestylesLayout(props) {
|
|
63
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TypestylesStylesheet, { children: layout(props) });
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
67
|
-
0 && (module.exports = {
|
|
68
|
-
TypestylesStylesheet,
|
|
69
|
-
createTypestylesLayout,
|
|
70
|
-
useServerInsertedHTML,
|
|
71
|
-
useTypestyles
|
|
72
|
-
});
|
package/dist/client.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
// src/client.tsx
|
|
4
|
-
import { useState, useEffect, useServerInsertedHTML, useSyncExternalStore } from "react";
|
|
5
|
-
import { getRegisteredCss } from "typestyles/server";
|
|
6
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
-
function useTypestyles() {
|
|
8
|
-
return useSyncExternalStore(
|
|
9
|
-
() => () => {
|
|
10
|
-
},
|
|
11
|
-
() => getRegisteredCss(),
|
|
12
|
-
() => ""
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
function TypestylesStylesheet({ children }) {
|
|
16
|
-
const [css, setCss] = useState("");
|
|
17
|
-
useServerInsertedHTML(() => {
|
|
18
|
-
const registeredCss = getRegisteredCss();
|
|
19
|
-
if (registeredCss) {
|
|
20
|
-
return /* @__PURE__ */ jsx("style", { id: "typestyles", dangerouslySetInnerHTML: { __html: registeredCss } });
|
|
21
|
-
}
|
|
22
|
-
return null;
|
|
23
|
-
});
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
setCss(getRegisteredCss());
|
|
26
|
-
}, []);
|
|
27
|
-
if (children) {
|
|
28
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
29
|
-
children,
|
|
30
|
-
/* @__PURE__ */ jsx("style", { id: "typestyles-client", dangerouslySetInnerHTML: { __html: css } })
|
|
31
|
-
] });
|
|
32
|
-
}
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
function createTypestylesLayout(layout) {
|
|
36
|
-
return function TypestylesLayout(props) {
|
|
37
|
-
return /* @__PURE__ */ jsx(TypestylesStylesheet, { children: layout(props) });
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
export {
|
|
41
|
-
TypestylesStylesheet,
|
|
42
|
-
createTypestylesLayout,
|
|
43
|
-
useServerInsertedHTML,
|
|
44
|
-
useTypestyles
|
|
45
|
-
};
|
package/dist/server.cjs
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name in all)
|
|
10
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
-
};
|
|
12
|
-
var __copyProps = (to, from, except, desc) => {
|
|
13
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
-
for (let key of __getOwnPropNames(from))
|
|
15
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
-
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
|
|
30
|
-
// src/server.ts
|
|
31
|
-
var server_exports = {};
|
|
32
|
-
__export(server_exports, {
|
|
33
|
-
collectStylesFromComponent: () => collectStylesFromComponent,
|
|
34
|
-
getRegisteredCss: () => import_server.getRegisteredCss,
|
|
35
|
-
getTypestylesMetadata: () => getTypestylesMetadata
|
|
36
|
-
});
|
|
37
|
-
module.exports = __toCommonJS(server_exports);
|
|
38
|
-
var import_server = require("typestyles/server");
|
|
39
|
-
async function collectStylesFromComponent(component) {
|
|
40
|
-
const { renderToString } = await import("react-dom/server");
|
|
41
|
-
const { css } = (0, import_server.collectStyles)(() => renderToString(component));
|
|
42
|
-
return css;
|
|
43
|
-
}
|
|
44
|
-
async function getTypestylesMetadata(component) {
|
|
45
|
-
return collectStylesFromComponent(component);
|
|
46
|
-
}
|
|
47
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
48
|
-
0 && (module.exports = {
|
|
49
|
-
collectStylesFromComponent,
|
|
50
|
-
getRegisteredCss,
|
|
51
|
-
getTypestylesMetadata
|
|
52
|
-
});
|
package/dist/server.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// src/server.ts
|
|
2
|
-
import { collectStyles, getRegisteredCss } from "typestyles/server";
|
|
3
|
-
async function collectStylesFromComponent(component) {
|
|
4
|
-
const { renderToString } = await import("react-dom/server");
|
|
5
|
-
const { css } = collectStyles(() => renderToString(component));
|
|
6
|
-
return css;
|
|
7
|
-
}
|
|
8
|
-
async function getTypestylesMetadata(component) {
|
|
9
|
-
return collectStylesFromComponent(component);
|
|
10
|
-
}
|
|
11
|
-
export {
|
|
12
|
-
collectStylesFromComponent,
|
|
13
|
-
getRegisteredCss,
|
|
14
|
-
getTypestylesMetadata
|
|
15
|
-
};
|
package/src/client.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type * as React from 'react';
|
|
2
|
-
import type { useSyncExternalStore, useServerInsertedHTML } from 'react';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Subscribe to typestyles CSS changes. Use this in client components
|
|
6
|
-
* that need to stay up-to-date with dynamically registered styles.
|
|
7
|
-
*/
|
|
8
|
-
export function useTypestyles(): ReturnType<typeof useSyncExternalStore<string>>;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Collect styles during server rendering for App Router.
|
|
12
|
-
*/
|
|
13
|
-
export { useServerInsertedHTML };
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Props for the TypestylesStylesheet component.
|
|
17
|
-
*/
|
|
18
|
-
export interface TypestylesStylesheetProps {
|
|
19
|
-
children?: React.ReactNode;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* A React component that renders typestyles CSS.
|
|
24
|
-
*/
|
|
25
|
-
export function TypestylesStylesheet(
|
|
26
|
-
props: TypestylesStylesheetProps,
|
|
27
|
-
): React.JSX.Element | null;
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Create a Next.js layout export that includes typestyles.
|
|
31
|
-
*/
|
|
32
|
-
export function createTypestylesLayout<P extends { children?: React.ReactNode }>(
|
|
33
|
-
layout: (props: P) => React.ReactNode,
|
|
34
|
-
): (props: P) => React.JSX.Element;
|
package/src/client.tsx
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import React, { useState, useEffect, useServerInsertedHTML, useSyncExternalStore } from 'react';
|
|
4
|
-
import { getRegisteredCss } from 'typestyles/server';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Subscribe to typestyles CSS changes. Use this in client components
|
|
8
|
-
* that need to stay up-to-date with dynamically registered styles.
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```tsx
|
|
12
|
-
* // components/Styles.tsx
|
|
13
|
-
* 'use client';
|
|
14
|
-
* import { useTypestyles } from '@typestyles/next/client';
|
|
15
|
-
*
|
|
16
|
-
* export function Styles() {
|
|
17
|
-
* useTypestyles();
|
|
18
|
-
* return null;
|
|
19
|
-
* }
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
export function useTypestyles() {
|
|
23
|
-
return useSyncExternalStore(
|
|
24
|
-
() => () => {},
|
|
25
|
-
() => getRegisteredCss(),
|
|
26
|
-
() => '',
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Collect styles during server rendering for App Router.
|
|
32
|
-
* Use this in a Client Component wrapper that collects styles from its children.
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* ```tsx
|
|
36
|
-
* // components/TypestylesProvider.tsx
|
|
37
|
-
* 'use client';
|
|
38
|
-
*
|
|
39
|
-
* import { useServerInsertedHTML, getRegisteredCss } from '@typestyles/next/client';
|
|
40
|
-
*
|
|
41
|
-
* export function TypestylesProvider({ children }: { children: React.ReactNode }) {
|
|
42
|
-
* useServerInsertedHTML(() => {
|
|
43
|
-
* return (
|
|
44
|
-
* <style
|
|
45
|
-
* id="typestyles"
|
|
46
|
-
* dangerouslySetInnerHTML={{ __html: getRegisteredCss() }}
|
|
47
|
-
* />
|
|
48
|
-
* );
|
|
49
|
-
* });
|
|
50
|
-
* return <>{children}</>;
|
|
51
|
-
* }
|
|
52
|
-
* ```
|
|
53
|
-
*/
|
|
54
|
-
export { useServerInsertedHTML };
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Props for the TypestylesStylesheet component.
|
|
58
|
-
*/
|
|
59
|
-
export interface TypestylesStylesheetProps {
|
|
60
|
-
/**
|
|
61
|
-
* The children to render (styles will be collected from these).
|
|
62
|
-
* If not provided, only the existing registered CSS will be included.
|
|
63
|
-
*/
|
|
64
|
-
children?: React.ReactNode;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* A React component that renders typestyles CSS.
|
|
69
|
-
*
|
|
70
|
-
* For App Router: Use this in your root layout to collect and render styles.
|
|
71
|
-
* Works with both Client Components and React Server Components.
|
|
72
|
-
*
|
|
73
|
-
* @example
|
|
74
|
-
* ```tsx
|
|
75
|
-
* // app/layout.tsx
|
|
76
|
-
* import { TypestylesStylesheet } from '@typestyles/next/client';
|
|
77
|
-
*
|
|
78
|
-
* export default function RootLayout({ children }) {
|
|
79
|
-
* return (
|
|
80
|
-
* <html>
|
|
81
|
-
* <head>
|
|
82
|
-
* <TypestylesStylesheet />
|
|
83
|
-
* </head>
|
|
84
|
-
* <body>{children}</body>
|
|
85
|
-
* </html>
|
|
86
|
-
* );
|
|
87
|
-
* }
|
|
88
|
-
* ```
|
|
89
|
-
*/
|
|
90
|
-
export function TypestylesStylesheet({ children }: TypestylesStylesheetProps) {
|
|
91
|
-
const [css, setCss] = useState('');
|
|
92
|
-
|
|
93
|
-
useServerInsertedHTML(() => {
|
|
94
|
-
const registeredCss = getRegisteredCss();
|
|
95
|
-
if (registeredCss) {
|
|
96
|
-
return <style id="typestyles" dangerouslySetInnerHTML={{ __html: registeredCss }} />;
|
|
97
|
-
}
|
|
98
|
-
return null;
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
useEffect(() => {
|
|
102
|
-
setCss(getRegisteredCss());
|
|
103
|
-
}, []);
|
|
104
|
-
|
|
105
|
-
if (children) {
|
|
106
|
-
return (
|
|
107
|
-
<>
|
|
108
|
-
{children}
|
|
109
|
-
<style id="typestyles-client" dangerouslySetInnerHTML={{ __html: css }} />
|
|
110
|
-
</>
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return null;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Create a Next.js layout export that includes typestyles.
|
|
119
|
-
*
|
|
120
|
-
* @example
|
|
121
|
-
* ```tsx
|
|
122
|
-
* // app/layout.tsx
|
|
123
|
-
* import { createTypestylesLayout } from '@typestyles/next/client';
|
|
124
|
-
*
|
|
125
|
-
* export default createTypestylesLayout(function RootLayout({ children }) {
|
|
126
|
-
* return (
|
|
127
|
-
* <html>
|
|
128
|
-
* <head>
|
|
129
|
-
* <title>My App</title>
|
|
130
|
-
* </head>
|
|
131
|
-
* <body>{children}</body>
|
|
132
|
-
* </html>
|
|
133
|
-
* );
|
|
134
|
-
* });
|
|
135
|
-
* ```
|
|
136
|
-
*/
|
|
137
|
-
export function createTypestylesLayout<P extends { children?: React.ReactNode }>(
|
|
138
|
-
layout: (props: P) => React.ReactNode,
|
|
139
|
-
): (props: P) => React.ReactNode {
|
|
140
|
-
return function TypestylesLayout(props: P) {
|
|
141
|
-
return <TypestylesStylesheet>{layout(props)}</TypestylesStylesheet>;
|
|
142
|
-
};
|
|
143
|
-
}
|
package/src/server.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Server-safe utilities for Next.js integration.
|
|
3
|
-
* These functions can be used in Server Components without adding "use client".
|
|
4
|
-
*/
|
|
5
|
-
import { collectStyles, getRegisteredCss } from 'typestyles/server';
|
|
6
|
-
|
|
7
|
-
export { getRegisteredCss };
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Collect styles from a React component and return them as a string.
|
|
11
|
-
* Useful for server components or when you need more control.
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```tsx
|
|
15
|
-
* // app/styles.ts
|
|
16
|
-
* import { collectStylesFromComponent } from '@typestyles/next/server';
|
|
17
|
-
* import { YourApp } from './YourApp';
|
|
18
|
-
*
|
|
19
|
-
* export async function getStyles() {
|
|
20
|
-
* return collectStylesFromComponent(<YourApp />);
|
|
21
|
-
* }
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
export async function collectStylesFromComponent(component: React.ReactElement): Promise<string> {
|
|
25
|
-
const { renderToString } = await import('react-dom/server');
|
|
26
|
-
const { css } = collectStyles(() => renderToString(component));
|
|
27
|
-
return css;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Generate CSS for use in Next.js metadata API.
|
|
32
|
-
* Call this in your layout or page to get CSS for the head.
|
|
33
|
-
*
|
|
34
|
-
* Note: This only captures CSS registered during the synchronous render.
|
|
35
|
-
* For dynamic styles that may be registered client-side, use TypestylesStylesheet.
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* ```tsx
|
|
39
|
-
* // app/layout.tsx
|
|
40
|
-
* import { generateMetadata } from 'next/metadata';
|
|
41
|
-
* import { getTypestylesMetadata } from '@typestyles/next/server';
|
|
42
|
-
* import { Home } from './Home';
|
|
43
|
-
*
|
|
44
|
-
* export async function generateMetadata() {
|
|
45
|
-
* const css = await getTypestylesMetadata(<Home />);
|
|
46
|
-
* return {
|
|
47
|
-
* styles: [{ cssText: css }],
|
|
48
|
-
* };
|
|
49
|
-
* }
|
|
50
|
-
* ```
|
|
51
|
-
*/
|
|
52
|
-
export async function getTypestylesMetadata(component: React.ReactElement): Promise<string> {
|
|
53
|
-
return collectStylesFromComponent(component);
|
|
54
|
-
}
|