Skip to content
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

feat: add emotion #222

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,5 @@
"workspaces": [
"packages/*"
],
"packageManager": "pnpm@9.6.0+sha512.38dc6fba8dba35b39340b9700112c2fe1e12f10b17134715a4aa98ccf7bb035e76fd981cf0bb384dfa98f8d6af5481c2bef2f4266a24bfa20c34eb7147ce0b5e"
"packageManager": "pnpm@9.12.1+sha512.e5a7e52a4183a02d5931057f7a0dbff9d5e9ce3161e33fa68ae392125b79282a8a8a470a51dfc8a0ed86221442eb2fb57019b0990ed24fab519bf0e1bc5ccfc4"
}
5 changes: 3 additions & 2 deletions packages/tod-blog/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
"rules": {
"import/no-extraneous-dependencies": "error",
"import/no-relative-packages": "error",
"import/no-useless-path-segments": "error"
"import/no-useless-path-segments": "error",
"react/no-unknown-property": ["error", { "ignore": ["css"] }]
}
}
]
}
}
116 changes: 116 additions & 0 deletions packages/tod-blog/app/emotion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
'use client';
import createCache, {
EmotionCache,
Options as OptionsOfCreateCache,
} from '@emotion/cache';
import { CacheProvider as DefaultCacheProvider } from '@emotion/react';
import { useServerInsertedHTML } from 'next/navigation';
import { Fragment, useState } from 'react';

export type AppRouterCacheProviderProps = {
/**
* These are the options passed to createCache() from 'import createCache from "@emotion/cache"'.
*/
options?: Partial<OptionsOfCreateCache> & {
/**
* If `true`, the generated styles are wrapped within `@layer mui`.
* This is useful if you want to override the Material UI's generated styles with different styling solution, like Tailwind CSS, plain CSS etc.
*/
enableCssLayer?: boolean;
};
/**
* By default <CacheProvider /> from 'import { CacheProvider } from "@emotion/react"'.
*/
CacheProvider?: React.ElementType<{ value: EmotionCache }>;
children: React.ReactNode;
};

/**
* Emotion works OK without this provider but it's recommended to use this provider to improve performance.
* Without it, Emotion will generate a new <style> tag during SSR for every component.
* See /~https://github.com/mui/material-ui/issues/26561#issuecomment-855286153 for why it's a problem.
*/
export default function AppRouterCacheProvider(
props: AppRouterCacheProviderProps
) {
const { options, CacheProvider = DefaultCacheProvider, children } = props;

const [registry] = useState(() => {
const cache = createCache({ ...options, key: options?.key ?? 'mui' });
cache.compat = true;

const prevInsert = cache.insert;
let inserted: { name: string; isGlobal: boolean }[] = [];
// Override the insert method to support streaming SSR with flush().
cache.insert = (...args) => {
if (options?.enableCssLayer) {
args[1].styles = `@layer mui {${args[1].styles}}`;
}
const [selector, serialized] = args;
if (cache.inserted[serialized.name] === undefined) {
inserted.push({
name: serialized.name,
isGlobal: !selector,
});
}
return prevInsert(...args);
};
const flush = () => {
const prevInserted = inserted;
inserted = [];
return prevInserted;
};
return { cache, flush };
});

useServerInsertedHTML(() => {
const inserted = registry.flush();
if (inserted.length === 0) {
return null;
}
let styles = '';
let dataEmotionAttribute = registry.cache.key;

const globals: {
name: string;
style: string;
}[] = [];

inserted.forEach(({ name, isGlobal }) => {
const style = registry.cache.inserted[name];

if (typeof style === 'string') {
if (isGlobal) {
globals.push({ name, style });
} else {
styles += style;
dataEmotionAttribute += ` ${name}`;
}
}
});

return (
<Fragment>
{globals.map(({ name, style }) => (
<style
nonce={options?.nonce}
key={name}
data-emotion={`${registry.cache.key}-global ${name}`}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: style }}
/>
))}
{styles && (
<style
nonce={options?.nonce}
data-emotion={dataEmotionAttribute}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: styles }}
/>
)}
</Fragment>
);
});

return <CacheProvider value={registry.cache}>{children}</CacheProvider>;
}
2 changes: 2 additions & 0 deletions packages/tod-blog/app/landingPage/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client';

import type { NextPage } from 'next';

import EntryContent from './EntryContent';
Expand Down
56 changes: 31 additions & 25 deletions packages/tod-blog/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
'use client';

import '@/styles/globals.css';

import { Caveat } from 'next/font/google';
import { ReactNode } from 'react';

import Navbar from '@/app/components/Navbar';

export const generateMetadata = async () => {
return {
title: "Tod's personal blog",
description: 'This is a personal blog created by tod sung from Taiwan',
openGraph: {
title: "Tod's personal blog",
description: 'This is a personal blog created by tod sung from Taiwan',
type: 'website',
emails: 'wlunareve@gmail.com',
locale: 'zh-tw',
},
verification: {
google: '9JFlPPjMcTWCa_ePEuHyFvlCv8LS2xZkeK3alcNc_oE',
},
};
};
import AppRouterCacheProvider from './emotion';

// export const generateMetadata = async () => {
// return {
// title: "Tod's personal blog",
// description: 'This is a personal blog created by tod sung from Taiwan',
// openGraph: {
// title: "Tod's personal blog",
// description: 'This is a personal blog created by tod sung from Taiwan',
// type: 'website',
// emails: 'wlunareve@gmail.com',
// locale: 'zh-tw',
// },
// verification: {
// google: '9JFlPPjMcTWCa_ePEuHyFvlCv8LS2xZkeK3alcNc_oE',
// },
// };
// };

const caveat = Caveat({
subsets: ['latin'],
Expand All @@ -34,15 +38,17 @@ const RootLayout = ({ children }: RootLayoutProps) => {
return (
<html lang='en' className={caveat.className}>
<body>
<main
id='app'
className='bg-default-canvas text-default-text flex min-h-screen justify-center px-2 text-justify'
>
<Navbar />
<div className='relative mt-[3.2rem] flex w-full justify-center sm:w-[80vw]'>
{children}
</div>
</main>
<AppRouterCacheProvider>
<main
id='app'
className='bg-default-canvas text-default-text flex min-h-screen justify-center px-2 text-justify'
>
<Navbar />
<div className='relative mt-[3.2rem] flex w-full justify-center sm:w-[80vw]'>
{children}
</div>
</main>
</AppRouterCacheProvider>
</body>
</html>
);
Expand Down
9 changes: 9 additions & 0 deletions packages/tod-blog/app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
'use client';

const NotFound = () => (
<div>
<h2>Not Found</h2>
</div>
);

export default NotFound;
2 changes: 2 additions & 0 deletions packages/tod-blog/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client';

import '@/styles/globals.css';

import type { NextPage } from 'next';
Expand Down
27 changes: 27 additions & 0 deletions packages/tod-blog/app/survey/emotion/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use client';

import { css } from '@emotion/react';
import type { NextPage } from 'next';

const red = css`
color: red;
font-size: 36px;
`;

const blue = css`
color: blue;
font-size: 36px;
`;

const LandingPage: NextPage = () => {
console.log(red);
return (
<main className='flex max-w-5xl flex-col gap-3'>
<div>Emotion Survey Page</div>
<div css={red}>red</div>
<div css={blue}>blue</div>
</main>
);
};

export default LandingPage;
3 changes: 3 additions & 0 deletions packages/tod-blog/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
*/
const nextConfig = {
output: 'export',
compiler: {
emotion: true,
},
};

module.exports = nextConfig;
8 changes: 6 additions & 2 deletions packages/tod-blog/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,20 @@
},
"private": true,
"dependencies": {
"@emotion/cache": "^11.13.1",
"@emotion/css": "^11.13.4",
"@emotion/react": "^11.13.3",
"lodash": "4.17.21",
"rxjs": "^7.8.1",
"typed.js": "2.1.0"
},
"devDependencies": {
"@emotion/eslint-plugin": "^11.12.0",
"@types/lodash": "^4.17.6"
},
"peerDependencies": {
"next": "14.2.4",
"react": "18.3.1",
"react-icons": "4.12.0",
"next": "14.2.4"
"react-icons": "4.12.0"
}
}
3 changes: 2 additions & 1 deletion packages/tod-blog/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"jsxImportSource": "@emotion/react",
"incremental": true,
"plugins": [
{
Expand All @@ -28,7 +29,7 @@
"@/*": [
"./*"
]
},
}
},
"include": [
"next-env.d.ts",
Expand Down
Loading
Loading