-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docs(example): add an example of using emotion css prop #1607
Changes from 5 commits
1538735
51489c3
e36dd31
8ab7b8c
bd5902b
c462154
5b66ce7
e0028f3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,6 +58,7 @@ | |
- GregBrimble | ||
- hardingmatt | ||
- HenryVogt | ||
- himorishige | ||
- hkan | ||
- Holben888 | ||
- hollandThomas | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
node_modules | ||
|
||
/.cache | ||
/build | ||
/public/build |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Example app with [Emotion](https://emotion.sh/docs/introduction) - css Prop | ||
|
||
This example features how to use [Emotion](https://emotion.sh/docs/introduction) - css Prop with Remix. | ||
|
||
## Preview | ||
|
||
Open this example on [CodeSandbox](https://codesandbox.com): | ||
|
||
[![Open in CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/remix-run/remix/tree/main/examples/emotion-css-prop) | ||
|
||
## Example | ||
|
||
This example shows how to use Emotion - css Prop with Remix. | ||
|
||
Relevant files: | ||
|
||
- [app/root.tsx](./app/root.tsx) - This is where we render the app and if we're rendering on the server we have placeholder text of __STYLES__. | ||
- [app/entry.server.tsx](./app/entry.server.tsx) - This is where we render the app on the server and replace __STYLES__ with the styles that emotion collect. | ||
- [app/routes/index.tsx](./app/routes/index.tsx) - Here's where we use the css Prop to styling component. | ||
- [tsconfig.json](./tsconfig.json) - Add `jsxImportSource` to use the css Prop in tsx file. | ||
|
||
## Related Links | ||
|
||
- [Emotion](https://emotion.sh/docs/introduction) | ||
- [The css Prop](https://emotion.sh/docs/css-prop) | ||
- [emotion-reset](https://github.com/sayegh7/emotion-reset) |
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); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { renderToString } from "react-dom/server"; | ||
import { RemixServer } from "remix"; | ||
import createEmotionServer from "@emotion/server/create-instance"; | ||
import createCache from "@emotion/cache"; | ||
import { css, CacheProvider, Global } from "@emotion/react"; | ||
import emotionReset from "emotion-reset"; | ||
import type { EntryContext } from "remix"; | ||
|
||
const key = "emotion"; | ||
const cache = createCache({ key }); | ||
const { extractCriticalToChunks, constructStyleTagsFromChunks } = | ||
createEmotionServer(cache); | ||
|
||
export default function handleRequest( | ||
request: Request, | ||
responseStatusCode: number, | ||
responseHeaders: Headers, | ||
remixContext: EntryContext | ||
) { | ||
let markup = renderToString( | ||
<CacheProvider value={cache}> | ||
{/* Set the global style. */} | ||
<Global | ||
styles={css` | ||
${emotionReset} | ||
*, *::after, *::before { | ||
box-sizing: border-box; | ||
-moz-osx-font-smoothing: grayscale; | ||
-webkit-font-smoothing: antialiased; | ||
font-smoothing: antialiased; | ||
} | ||
`} | ||
/> | ||
<RemixServer context={remixContext} url={request.url} /> | ||
</CacheProvider> | ||
); | ||
|
||
const chunks = extractCriticalToChunks(markup); | ||
|
||
const styles = constructStyleTagsFromChunks(chunks); | ||
markup = markup.replace("__STYLES__", styles); | ||
|
||
responseHeaders.set("Content-Type", "text/html"); | ||
|
||
return new Response("<!DOCTYPE html>" + markup, { | ||
status: responseStatusCode, | ||
headers: responseHeaders | ||
}); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { | ||
Links, | ||
LiveReload, | ||
Meta, | ||
Outlet, | ||
Scripts, | ||
ScrollRestoration | ||
} from "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> | ||
<Outlet /> | ||
<ScrollRestoration /> | ||
<Scripts /> | ||
<LiveReload /> | ||
</body> | ||
</html> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/** @jsx jsx */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does esbuild respect this pragma? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. esbuild supports jsx annotations. ref: Support /** @jsx pragma Add support for jsxImportSource There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Although it is limited, it seems to be possible to remove the pragma by adopting the patch in this issue. |
||
import { jsx, css } from "@emotion/react"; | ||
|
||
// Object Styles | ||
const wrapperStyle = { | ||
height: "100vh", | ||
display: "flex", | ||
alignItems: "center", | ||
justifyContent: "center" | ||
}; | ||
|
||
// String Styles | ||
const headingStyle = css` | ||
font-size: 2rem; | ||
font-weight: 700; | ||
color: hotpink; | ||
`; | ||
|
||
export default function Index() { | ||
return ( | ||
<div css={wrapperStyle}> | ||
<h1 css={headingStyle}>Welcome to Remix (With Emotion css Prop)</h1> | ||
</div> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are you confident this doesn't result in hydration mismatches? What about client side navigations, does emotion replace the contents here? Is it stable on rerenders in
App
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review.
There were some implementation mistakes...
I've committed the adjusted version again.