60 lines
1.7 KiB
JavaScript
60 lines
1.7 KiB
JavaScript
// app/ThemeRegistry.tsx
|
|
'use client';
|
|
import createCache from '@emotion/cache';
|
|
import { useServerInsertedHTML } from 'next/navigation';
|
|
import { CacheProvider, ThemeProvider } from '@emotion/react';
|
|
import React from 'react';
|
|
import theme from '../theme/theme';
|
|
|
|
// This implementation is from emotion-js
|
|
// https://github.com/emotion-js/emotion/issues/2928#issuecomment-1319747902
|
|
export default function ThemeRegistry({
|
|
children
|
|
}) {
|
|
const options = { key: 'mui' }
|
|
const [{ cache, flush }] = React.useState(() => {
|
|
const cache = createCache(options);
|
|
cache.compat = true;
|
|
const prevInsert = cache.insert;
|
|
let inserted = [];
|
|
cache.insert = (...args) => {
|
|
const serialized = args[1];
|
|
if (cache.inserted[serialized.name] === undefined) {
|
|
inserted.push(serialized.name);
|
|
}
|
|
return prevInsert(...args);
|
|
};
|
|
const flush = () => {
|
|
const prevInserted = inserted;
|
|
inserted = [];
|
|
return prevInserted;
|
|
};
|
|
return { cache, flush };
|
|
});
|
|
|
|
useServerInsertedHTML(() => {
|
|
const names = flush();
|
|
if (names.length === 0) {
|
|
return null;
|
|
}
|
|
let styles = '';
|
|
for (const name of names) {
|
|
styles += cache.inserted[name];
|
|
}
|
|
return (
|
|
<style
|
|
key={cache.key}
|
|
data-emotion={`${cache.key} ${names.join(' ')}`}
|
|
dangerouslySetInnerHTML={{
|
|
__html: styles,
|
|
}}
|
|
/>
|
|
);
|
|
});
|
|
|
|
return (
|
|
<CacheProvider value={cache}>
|
|
<ThemeProvider theme={theme}>{children}</ThemeProvider>
|
|
</CacheProvider>
|
|
);
|
|
} |