Skip to content

Commit

Permalink
feat: support for render styles to html on the server side (geist-org…
Browse files Browse the repository at this point in the history
…#738)

* feat: support for render styles to html on the server side

* chore: release v2.3.2

* docs(examples): add example for remix
  • Loading branch information
unix authored Feb 12, 2022
1 parent b83edbb commit ccb839c
Show file tree
Hide file tree
Showing 16 changed files with 171 additions and 3 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ examples/**/yarn.lock
examples/**/out
examples/**/.next
examples/**/node_modules
examples/**/_build
examples/**/.cache

# Local Netlify folder
.netlify
5 changes: 4 additions & 1 deletion components/css-baseline/css-baseline.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React, { ReactElement } from 'react'
import useTheme from '../use-theme'
import flush from 'styled-jsx/server'
import flush, { flushToHTML } from 'styled-jsx/server'

export type FlushToReact = <T>(opts?: { nonce?: string }) => Array<ReactElement<T>>
export type FlushToHTML = (opts?: { nonce?: string }) => string

const CssBaseline: React.FC<React.PropsWithChildren<unknown>> = ({ children }) => {
const theme = useTheme()
Expand Down Expand Up @@ -304,11 +305,13 @@ const CssBaseline: React.FC<React.PropsWithChildren<unknown>> = ({ children }) =

type MemoCssBaselineComponent<P = {}> = React.NamedExoticComponent<P> & {
flush: FlushToReact
flushToHTML: FlushToHTML
}

const MemoCssBaseline = React.memo(CssBaseline) as MemoCssBaselineComponent<
React.PropsWithChildren<unknown>
>
MemoCssBaseline.flush = flush
MemoCssBaseline.flushToHTML = flushToHTML

export default MemoCssBaseline
21 changes: 21 additions & 0 deletions examples/remix/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Remix demo for Geist UI

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/routes/index.tsx`. The page auto-updates as you edit the file.

## Learn More

To learn more about Remix, take a look at the following resources:

- [Remix v1](https://remix.run/docs/en/v1) - learn about Next.js features and API.
5 changes: 5 additions & 0 deletions examples/remix/api/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const { createRequestHandler } = require('@remix-run/vercel')

module.exports = createRequestHandler({
build: require('./_build'),
})
4 changes: 4 additions & 0 deletions examples/remix/app/entry.client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { hydrate } from 'react-dom'
import { RemixBrowser } from 'remix'

hydrate(<RemixBrowser />, document)
21 changes: 21 additions & 0 deletions examples/remix/app/entry.server.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { renderToString } from 'react-dom/server'
import { RemixServer } from 'remix'
import type { EntryContext } from 'remix'
import { CssBaseline } from '@geist-ui/core'

export default function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext,
) {
let markup = renderToString(<RemixServer context={remixContext} url={request.url} />)
markup = markup.replace('__STYLES__', CssBaseline.flushToHTML())

responseHeaders.set('Content-Type', 'text/html')

return new Response('<!DOCTYPE html>' + markup, {
status: responseStatusCode,
headers: responseHeaders,
})
}
30 changes: 30 additions & 0 deletions examples/remix/app/root.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Links, LiveReload, Meta, Outlet, Scripts, ScrollRestoration } from 'remix'
import type { MetaFunction } from 'remix'
import { CssBaseline, GeistProvider } from '@geist-ui/core'

export const meta: MetaFunction = () => {
return { title: 'Geist with Remix' }
}

export default function App() {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<Meta />
<Links />
{typeof document === 'undefined' ? '__STYLES__' : null}
</head>
<body>
<GeistProvider>
<CssBaseline />
<Outlet />
</GeistProvider>
<ScrollRestoration />
<Scripts />
{process.env.NODE_ENV === 'development' && <LiveReload />}
</body>
</html>
)
}
11 changes: 11 additions & 0 deletions examples/remix/app/routes/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Card, Page, Text } from '@geist-ui/core'

export default function Index() {
return (
<Page>
<Card>
<Text>Hello, Geist with Remix</Text>
</Card>
</Page>
)
}
31 changes: 31 additions & 0 deletions examples/remix/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "geist-remix",
"license": "MIT",
"scripts": {
"build": "remix build",
"dev": "remix dev",
"postinstall": "remix setup node"
},
"prettier": "@geist-ui/prettier-config",
"dependencies": {
"@geist-ui/core": "latest",
"@remix-run/react": "^1.1.3",
"@remix-run/serve": "^1.1.3",
"@remix-run/vercel": "^1.1.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"remix": "^1.1.3"
},
"devDependencies": {
"@geist-ui/prettier-config": "^1.0.1",
"@remix-run/dev": "^1.1.3",
"@types/react": "^17.0.24",
"@types/react-dom": "^17.0.9",
"prettier": "^2.5.1",
"typescript": "^4.1.2"
},
"engines": {
"node": ">=14"
},
"sideEffects": false
}
Binary file added examples/remix/public/favicon.ico
Binary file not shown.
10 changes: 10 additions & 0 deletions examples/remix/remix.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* @type {import('@remix-run/dev/config').AppConfig}
*/
module.exports = {
appDirectory: 'app',
assetsBuildDirectory: 'public/build',
publicPath: '/build/',
serverBuildDirectory: 'api/_build',
ignoredRouteFiles: ['.*'],
}
2 changes: 2 additions & 0 deletions examples/remix/remix.env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// <reference types="@remix-run/dev" />
/// <reference types="@remix-run/node/globals" />
20 changes: 20 additions & 0 deletions examples/remix/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ES2019"],
"isolatedModules": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"moduleResolution": "node",
"resolveJsonModule": true,
"target": "ES2019",
"strict": true,
"baseUrl": ".",
"paths": {
"~/*": ["./app/*"]
},

// Remix takes care of building everything in `remix build`.
"noEmit": true
}
}
7 changes: 7 additions & 0 deletions examples/remix/vercel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"build": {
"env": {
"ENABLE_FILE_SYSTEM_API": "1"
}
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@geist-ui/core",
"version": "2.3.1",
"version": "2.3.2",
"main": "dist/index.js",
"module": "esm/index.js",
"types": "esm/index.d.ts",
Expand Down
3 changes: 2 additions & 1 deletion scripts/built-in/styled-jsx-server.es.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { server } from './styled-jsx.es'
const { flushToHTML } = server

export { server }
export { server, flushToHTML }
export default server

0 comments on commit ccb839c

Please sign in to comment.