Skip to content

Commit

Permalink
[system] set before directly without using prepend for global styles (
Browse files Browse the repository at this point in the history
  • Loading branch information
siriwatknp authored Dec 23, 2024
1 parent 0ea1ef5 commit e16f0f5
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,11 @@ import { StyleSheet } from '@emotion/sheet';

// We might be able to remove this when this issue is fixed:
// https://github.com/emotion-js/emotion/issues/2790
const createEmotionCache = (options) => {
const createEmotionCache = (options, CustomSheet) => {
const cache = createCache(options);

/**
* This is for client-side apps only.
* A custom sheet is required to make the GlobalStyles API work with `prepend: true`.
* This is because the [sheet](https://github.com/emotion-js/emotion/blob/main/packages/react/src/global.js#L94-L99) does not consume the options.
*/
class MyStyleSheet extends StyleSheet {
constructor(args) {
super(args);
this.prepend = cache.sheet.prepend;
}
}

// Do the same as https://github.com/emotion-js/emotion/blob/main/packages/cache/src/index.js#L238-L245
cache.sheet = new MyStyleSheet({
cache.sheet = new CustomSheet({
key: cache.key,
nonce: cache.sheet.nonce,
container: cache.sheet.container,
Expand All @@ -35,11 +23,34 @@ const createEmotionCache = (options) => {
return cache;
};

// prepend: true moves MUI styles to the top of the <head> so they're loaded first.
// It allows developers to easily override MUI styles with other styling solutions, like CSS modules.
let cache;
if (typeof document === 'object') {
cache = createEmotionCache({ key: 'css', prepend: true });
// Use `insertionPoint` over `prepend`(deprecated) because it can be controlled for GlobalStyles injection order
// For more information, see https://github.com/mui/material-ui/issues/44597
let insertionPoint = document.querySelector('[name="emotion-insertion-point"]');
if (!insertionPoint) {
insertionPoint = document.createElement('meta');
insertionPoint.setAttribute('name', 'emotion-insertion-point');
insertionPoint.setAttribute('content', '');
const head = document.querySelector('head');
if (head) {
head.prepend(insertionPoint);
}
}
/**
* This is for client-side apps only.
* A custom sheet is required to make the GlobalStyles API injected above the insertion point.
* This is because the [sheet](https://github.com/emotion-js/emotion/blob/main/packages/react/src/global.js#L94-L99) does not consume the options.
*/
class MyStyleSheet extends StyleSheet {
insert(rule, options) {
if (this.key && this.key.endsWith('global')) {
this.before = insertionPoint;
}
return super.insert(rule, options);
}
}
cache = createEmotionCache({ key: 'css', insertionPoint }, MyStyleSheet);
}

export default function StyledEngineProvider(props) {
Expand Down
16 changes: 16 additions & 0 deletions test/regressions/fixtures/GlobalStyles/InjectFirst.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as React from 'react';
import { StyledEngineProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import GlobalStyles from '@mui/material/GlobalStyles';
import Typography from '@mui/material/Typography';

export default function InjectFirst() {
return (
<StyledEngineProvider injectFirst>
<CssBaseline />
<Typography variant="h1">Hello MUI v6</Typography>
<Typography>The color should be red</Typography>
<GlobalStyles styles={() => ({ body: { color: 'red' } })} />
</StyledEngineProvider>
);
}

0 comments on commit e16f0f5

Please sign in to comment.