Skip to content

Commit

Permalink
feat: new extension vike-react-styled-components
Browse files Browse the repository at this point in the history
  • Loading branch information
phonzammi committed Dec 3, 2024
1 parent 8f7bc0f commit cb04e92
Show file tree
Hide file tree
Showing 10 changed files with 405 additions and 9 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"vike-react-query": "link:./packages/vike-react-query/",
"vike-react-apollo": "link:./packages/vike-react-apollo/",
"vike-react-chakra": "link:./packages/vike-react-chakra/",
"vike-react-antd": "link:./packages/vike-react-antd/"
"vike-react-antd": "link:./packages/vike-react-antd/",
"vike-react-styled-components": "link:./packages/vike-react-styled-components/"
}
},
"devDependencies": {
Expand Down
2 changes: 2 additions & 0 deletions packages/vike-react-styled-components/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/node_modules/
/dist/
112 changes: 112 additions & 0 deletions packages/vike-react-styled-components/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# `vike-react-styled-components`

[Installation](#installation)
[Settings](#settings)
[Version history](https://github.com/vikejs/vike-react/blob/main/packages/vike-react-styled-components/CHANGELOG.md)
[See Also](#see-also)

<br/>

Integrates [styled-components](https://styled-components.com) to your [`vike-react`](https://vike.dev/vike-react) app.

## Installation

1. `npm install vike-react-styled-components styled-components`

2. Extend `+config.js`:
```js
// pages/+config.js

import vikeReact from "vike-react/config"
import vikeReactStyledComponents from "vike-react-styled-components/config"

export default {
// ...
extends: [vikeReact, vikeReactStyledComponents]
}
```
3. You can now use styled-components at any of your components.
```jsx
import { styled } from "styled-components";
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: #BF4F74;
`;

const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;

function SomeComponent() {
return (
<Wrapper>
<Title>Hello World!</Title>
</Wrapper>
)
}
```

> [!NOTE]
> The `vike-react-styled-components` extension requires [`vike-react`](https://vike.dev/vike-react).

In order to reliably perform server side rendering and avoids checksum mismatches due to different class generation on the client and on the server, you'll need to use [babel-plugin-styled-components](https://styled-components.com/docs/tooling#babel-plugin):

1. `npm install --save-dev babel-plugin-styled-components`
2. Add the `babel-plugin-styled-components` to the `babel` options in the `@vitejs/plugin-react` configuration.
```js
// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import vike from 'vike/plugin'

export default defineConfig({
plugins: [
vike(),
react({
babel: {
plugins: [['babel-plugin-styled-components']],
},
}),
],
})
```

<br/>

## Settings

`vike-react-styled-components` provides a configuration `+styleSheetManager` for customizing the [StyleSheetManager](https://styled-components.com/docs/api#stylesheetmanager).

```ts
// pages/+styleSheetManager.ts
export { styleSheetManager }

import type { IStyleSheetManager } from 'styled-components'
import rtlPlugin from 'stylis-plugin-rtl';

const styleSheetManager: Omit<IStyleSheetManager, "sheet" | "children"> = {
stylisPlugins: [rtlPlugin],
}
```

You can remove the styled-components SSR integration from [some of your pages](https://vike.dev/config#inheritance):

```js
// pages/about/+styleSheetManager.js

export const styleSheetManager = null
```

For full customization consider [ejecting](https://vike.dev/eject).

> [!NOTE]
> Consider making a [Pull Request before ejecting](https://vike.dev/eject#when-to-eject).
<br/>

## See also

- [Vike Docs > styled-components](https://vike.dev/styled-components)
17 changes: 17 additions & 0 deletions packages/vike-react-styled-components/Wrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export { Wrapper }

import React, { type ReactNode } from 'react'
import { StyleSheetManager } from 'styled-components'
import { usePageContext } from 'vike-react/usePageContext'

function Wrapper({ children }: { children: ReactNode }) {
const pageContext = usePageContext()
const { styleSheetManager } = pageContext.config

if (typeof window !== 'undefined' || styleSheetManager === null) return <>{children}</>
return (
<StyleSheetManager sheet={pageContext.styleSheet?.instance} {...styleSheetManager}>
{children}
</StyleSheetManager>
)
}
34 changes: 34 additions & 0 deletions packages/vike-react-styled-components/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export { config as default }

import type { IStyleSheetManager, ServerStyleSheet } from 'styled-components'
import type { Config } from 'vike/types'

const config = {
name: 'vike-react-styled-components',
require: {
vike: '>=0.4.203',
'vike-react': '>=0.4.13',
},
onAfterRenderHtml: 'import:vike-react-styled-components/__internal/onAfterRenderHtml:onAfterRenderHtml',
onBeforeRenderHtml: 'import:vike-react-styled-components/__internal/onBeforeRenderHtml:onBeforeRenderHtml',
Wrapper: 'import:vike-react-styled-components/__internal/Wrapper:Wrapper',
meta: {
styleSheetManager: {
env: {
server: true,
client: false,
},
},
},
} satisfies Config

declare global {
namespace Vike {
interface PageContext {
styleSheet?: ServerStyleSheet
}
interface Config {
styleSheetManager?: null | Omit<IStyleSheetManager, 'sheet' | 'children'>
}
}
}
23 changes: 23 additions & 0 deletions packages/vike-react-styled-components/onAfterRenderHtml.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export { onAfterRenderHtml }

import React from 'react'
import { useConfig } from 'vike-react/useConfig'
import type { PageContext } from 'vike/types'

function onAfterRenderHtml(pageContext: PageContext) {
const config = useConfig()

if (pageContext.styleSheet) {
const { styleSheet } = pageContext
try {
const styles = styleSheet.getStyleElement()
config({
Head: styles,
})
} catch (error) {
throw error
} finally {
styleSheet.seal()
}
}
}
11 changes: 11 additions & 0 deletions packages/vike-react-styled-components/onBeforeRenderHtml.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export { onBeforeRenderHtml }

import { ServerStyleSheet } from 'styled-components'
import type { PageContext } from 'vike/types'

function onBeforeRenderHtml(pageContext: PageContext) {
if (pageContext.config.styleSheetManager !== null) {
pageContext.config.styleSheetManager ??= {}
pageContext.styleSheet = new ServerStyleSheet()
}
}
56 changes: 56 additions & 0 deletions packages/vike-react-styled-components/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"name": "vike-react-styled-components",
"version": "0.0.0",
"type": "module",
"exports": {
"./config": "./dist/config.js",
"./__internal/onAfterRenderHtml": "./dist/onAfterRenderHtml.js",
"./__internal/onBeforeRenderHtml": "./dist/onBeforeRenderHtml.js",
"./__internal/Wrapper": "./dist/Wrapper.js"
},
"scripts": {
"dev": "tsc --watch",
"build": "rimraf dist/ && tsc",
"release": "release-me patch",
"release:minor": "release-me minor",
"release:major": "release-me major",
"release:commit": "release-me commit"
},
"peerDependencies": {
"styled-components": ">=6",
"react": ">=18",
"vike-react": ">=0.4.13"
},
"devDependencies": {
"@brillout/release-me": "^0.4.2",
"@types/react": "^18.2.55",
"react": "^18.3.1",
"rimraf": "^5.0.5",
"styled-components": "^6.1.13",
"typescript": "^5.5.3",
"vike": "^0.4.203",
"vike-react": "^0.5.9",
"vite": "^5.4.0"
},
"typesVersions": {
"*": {
"config": [
"dist/config.d.ts"
],
"__internal/onAfterRenderHtml": [
"dist/onAfterRenderHtml.d.ts"
],
"__internal/onBeforeRenderHtml": [
"dist/onBeforeRenderHtml.d.ts"
],
"__internal/Wrapper": [
"dist/Wrapper.d.ts"
]
}
},
"files": [
"dist"
],
"repository": "https://github.com/vikejs/vike-react/tree/main/packages/vike-react-styled-components",
"license": "MIT"
}
16 changes: 16 additions & 0 deletions packages/vike-react-styled-components/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"declaration": true,
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"jsx": "react",
"outDir": "./dist/",
"skipLibCheck": true,
"types": ["vike-react"],
// Strictness
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitAny": true
}
}
Loading

0 comments on commit cb04e92

Please sign in to comment.