Open caocanx opened 1 year ago
This is a tricky one. ref: #773
If you console.log the styleText
, what does it contain?
This is a tricky one. ref: #773
If you console.log the
styleText
, what does it contain?
Look like it contains all the content of @mantine/core/styles.css
, 6898 lines css.
have you ever tried this method https://mantine.dev/styles/vanilla-extract/
have you ever tried this method https://mantine.dev/styles/vanilla-extract/
This is not highly relevant to the problems I am currently facing. What I want now is to ensure that all default styles work as expected. Then I will use Vanilla extract or CSS Modules to make some custom styles.
Yes, I also encountered it
It seems there are 2 separate issues here:
:root
by default (aka the <html>
element, since shadow DOMs are DocumentFragments
, not Documents
) (ref: https://mantine.dev/theming/mantine-provider/#cssvariablesselector)<body>
, which doesn't allow some Mantine global styles to be applied (ref: https://mantine.dev/styles/global-styles/#body-and-root-elements-styles).For #1, MantineProvider has a prop that allows you to change where CSS variables are added. In our case, we want it to be :host
to apply to the shadow host (ref: https://mantine.dev/theming/mantine-provider/#cssvariablesselector):
<MantineProvider cssVariablesSelector=":host"></MantineProvider>
For #2, manually override styles that apply to :root
, html
, and body
:
Create an override CSS file (changing all :root
, html
, and body
tags to :host
, ref: https://mantine.dev/styles/global-styles/#css-reset and https://mantine.dev/styles/global-styles/#body-and-root-elements-styles):
:host {
height: 100%;
margin: 0;
color-scheme: var(--mantine-color-scheme);
font-family: var(--mantine-font-family);
font-size: var(--mantine-font-size-md);
line-height: var(--mantine-line-height);
background-color: var(--mantine-color-body);
color: var(--mantine-color-text);
-webkit-font-smoothing: var(--mantine-webkit-font-smoothing);
-moz-osx-font-smoothing: var(--mantine-moz-font-smoothing);
}
Import the CSS file to your CSUI, along with the Mantine global styles:
import "@mantine/core/styles.css";
import globalCss from "data-text:@mantine/core/styles.css";
import shadowCss from "data-text:~shadow.css";
Export the getStyle
function with both CSS applied:
export const getStyle: PlasmoGetStyle = () => {
const style = document.createElement("style");
style.textContent = globalCss + shadowCss;
return style;
};
Could you let us know if this works for you?
Hi @0xjoo: thank you for your solution. I've applied it and it works for buttons
but not for inputs (the below is using <TextInput variant="filled" />
:
Information, this is working with "@mantine/core": "^7.2.2",
and "plasmo": "0.84.0",
.
It seems there are 2 separate issues here:
- Mantine adds CSS variables to
:root
by default (aka the<html>
element, since shadow DOMs areDocumentFragments
, notDocuments
) (ref: https://mantine.dev/theming/mantine-provider/#cssvariablesselector)- CSUI injects the shadow DOM outside of
<body>
, which doesn't allow some Mantine global styles to be applied (ref: https://mantine.dev/styles/global-styles/#body-and-root-elements-styles).For #1, MantineProvider has a prop that allows you to change where CSS variables are added. In our case, we want it to be
:host
to apply to the shadow host (ref: https://mantine.dev/theming/mantine-provider/#cssvariablesselector):<MantineProvider cssVariablesSelector=":host"></MantineProvider>
For #2, manually override styles that apply to
:root
,html
, andbody
:
- Create an override CSS file (changing all
:root
,html
, andbody
tags to:host
, ref: https://mantine.dev/styles/global-styles/#css-reset and https://mantine.dev/styles/global-styles/#body-and-root-elements-styles)::host { height: 100%; margin: 0; color-scheme: var(--mantine-color-scheme); font-family: var(--mantine-font-family); font-size: var(--mantine-font-size-md); line-height: var(--mantine-line-height); background-color: var(--mantine-color-body); color: var(--mantine-color-text); -webkit-font-smoothing: var(--mantine-webkit-font-smoothing); -moz-osx-font-smoothing: var(--mantine-moz-font-smoothing); }
- Import the CSS file to your CSUI, along with the Mantine global styles:
import "@mantine/core/styles.css"; import globalCss from "data-text:@mantine/core/styles.css"; import shadowCss from "data-text:~shadow.css";
- Export the
getStyle
function with both CSS applied:export const getStyle: PlasmoGetStyle = () => { const style = document.createElement("style"); style.textContent = globalCss + shadowCss; return style; };
Could you let us know if this works for you?
I've just encountered this issue too. And, I can say this solution works. I used the solution above in my extension.
But, then a new problem came. The style from Mantine leaks to the main web page. It overrides some styles from the web page with Mantine's style.
Currently, I'm still trying to solve this issue. I'll post here again once I can solve this issue.
EDIT: Additional information, my extension is opening a popup on top of the main page.
I've successfully solve my issue above. The problem was in this import:
import "@mantine/core/styles.css";
When we use it inside popup or the side panel page, it will work fine because it's isolated from the main webpage. However, when we create an extension with overlay/inline with the webpage, the import above will override the CSS of the main webpage because it was imported globally.
If we removed that line, some Mantine's components won't work. For my case, Mantine's modal didn't work because it was portal-ed from shadow DOM to the main webpage. So, the modal can't access the CSS inside the shadow DOM.
My solution is I implemented my own custom modal that can work inside shadow DOM.
I've successfully solve my issue above. The problem was in this import:
import "@mantine/core/styles.css";
When we use it inside popup or the side panel page, it will work fine because it's isolated from the main webpage. However, when we create an extension with overlay/inline with the webpage, the import above will override the CSS of the main webpage because it was imported globally.
If we removed that line, some Mantine's components won't work. For my case, Mantine's modal didn't work because it was portal-ed from shadow DOM to the main webpage. So, the modal can't access the CSS inside the shadow DOM.
My solution is I implemented my own custom modal that can work inside shadow DOM.
Can you share it? I'm also having issues when using modal and darkmode.
@murnifine sure. My project is open-source. Take a look at this file https://github.com/chloe-matt/sonastik/blob/main/browser-extension/contents/plasmo-overlay.tsx
mantine v7.9.0 was recently released and seems to support the use of emotion again https://mantine.dev/styles/emotion/
I've successfully solve my issue above. The problem was in this import:
import "@mantine/core/styles.css";
When we use it inside popup or the side panel page, it will work fine because it's isolated from the main webpage. However, when we create an extension with overlay/inline with the webpage, the import above will override the CSS of the main webpage because it was imported globally.
If we removed that line, some Mantine's components won't work. For my case, Mantine's modal didn't work because it was portal-ed from shadow DOM to the main webpage. So, the modal can't access the CSS inside the shadow DOM.
My solution is I implemented my own custom modal that can work inside shadow DOM.
Ran into the same issue and found a workaround. Not fully tested, so please let us know if you run into any issues if you try this out.
As mentioned above, the main issue is due to the following import, which applies Mantine styles globally:
import "@mantine/core/styles.css";
However, if we remove this import, some styles are not applied, even when exporting Plasmo's getStyle
function.
It appears that Plasmo's getStyle
function adds the CSS style directly under #shadow-root
, which does not correctly apply to Mantine components within.
It seems that when the cssVariablesSelector
is set to :host
, Mantine doesn't correctly find CSS variables from the <style>
tag that Plasmo inserted underneath the shadow DOM.
To force Mantine to correctly use the inline styles, we can make the following changes:
Import the default Mantine styles (as text):
import mantineCss from "data-text:@mantine/core/styles.css";
Import custom CSS styles to apply global styles within the shadow DOM (as text):
import overrideCss from "data-text:~styles/override.css";
where override.css
has the following content:
div.plasmo-csui-container {
margin: 0;
color-scheme: var(--mantine-color-scheme);
font-family: var(--mantine-font-family);
font-size: var(--mantine-font-size-md);
line-height: var(--mantine-line-height);
background-color: var(--mantine-color-body);
color: var(--mantine-color-text);
-webkit-font-smoothing: var(--mantine-webkit-font-smoothing);
-moz-osx-font-smoothing: var(--mantine-moz-font-smoothing);
}
Define MantineProvider
to use the following props:
<MantineProvider
theme={...}
cssVariablesSelector="div.plasmo-csui-container"
getRootElement={() =>
document.querySelector("plasmo-csui").shadowRoot.querySelector("div.plasmo-csui-container")
}
>
<style>{mantineCss + overrideCss}</style>
{...}
</MantineProvider>
The main difference you'll notice is that we changed the cssVariablesSelector
prop from :host
to div.plasmo-csui-container
. This allows Mantine to correctly source CSS variables from within the div.plasmo-csui-container
container.
You'll also notice that we updated the override.css
CSS to use the same container as its selector.
We also define the getRootElement
prop to correctly set the data-mantine-color-scheme
attribute (Ref: https://mantine.dev/theming/mantine-provider/#getrootelement).
Lastly, we drop the use of Plasmo's getStyle
function, and apply it inline via <style>
tags within MantineProvider
, so that the styles are inserted inline within the div.plasmo-csui-container
container.
Full implementation via a dedicated theme.tsx
file:
import { createTheme, MantineProvider, mergeThemeOverrides, Modal } from "@mantine/core";
import mantineCss from "data-text:@mantine/core/styles.css";
import overrideCss from "data-text:~styles/override.css";
export const defaultTheme = createTheme({});
const contentTheme = createTheme({
components: {
Modal: Modal.extend({ defaultProps: { withinPortal: false } })
}
});
const mergedTheme = mergeThemeOverrides(defaultTheme, contentTheme);
export function ContentProvider({ children }) {
return (
<MantineProvider
theme={mergedTheme}
defaultColorScheme="auto"
cssVariablesSelector="div.plasmo-csui-container"
getRootElement={() =>
document.querySelector("plasmo-csui").shadowRoot.querySelector("div.plasmo-csui-container")
}
>
<style>{mantineCss + overrideCss}</style>
{children}
</MantineProvider>
);
}
where defaultTheme
can be imported to be used in your app's MantineProvider
, while still applying to CSUI components. contentTheme
includes theme overrides that should only be applied to CSUI components. mergedTheme
merges the two and uses it within a dedicated ContentProvider
, which wraps MantineProvider
with the necessary overrides to apply Mantine styles to CSUI components. This should make it easier to develop CSUI components, since all the overrides are done locally in this file.
Lastly, make sure to set modals (among other components) to render within the shadow DOM, not via a portal:
const theme = createTheme({
components: {
Modal: Modal.extend({ defaultProps: { withinPortal: false } })
}
});
This allows styles to be correctly applied to the modal, since it will render with the shadow DOM's styles that we set inline above.
Please let us know if this works for you!
I've successfully solve my issue above. The problem was in this import:
import "@mantine/core/styles.css";
When we use it inside popup or the side panel page, it will work fine because it's isolated from the main webpage. However, when we create an extension with overlay/inline with the webpage, the import above will override the CSS of the main webpage because it was imported globally. If we removed that line, some Mantine's components won't work. For my case, Mantine's modal didn't work because it was portal-ed from shadow DOM to the main webpage. So, the modal can't access the CSS inside the shadow DOM. My solution is I implemented my own custom modal that can work inside shadow DOM.
Ran into the same issue and found a workaround. Not fully tested, so please let us know if you run into any issues if you try this out.
As mentioned above, the main issue is due to the following import, which applies Mantine styles globally:
import "@mantine/core/styles.css";
However, if we remove this import, some styles are not applied, even when exporting Plasmo's
getStyle
function.It appears that Plasmo's
getStyle
function adds the CSS style directly under#shadow-root
, which does not correctly apply to Mantine components within.It seems that when the
cssVariablesSelector
is set to:host
, Mantine doesn't correctly find CSS variables from the<style>
tag that Plasmo inserted underneath the shadow DOM.To force Mantine to correctly use the inline styles, we can make the following changes:
- Import the default Mantine styles (as text):
import mantineCss from "data-text:@mantine/core/styles.css";
- Import custom CSS styles to apply global styles within the shadow DOM (as text):
import overrideCss from "data-text:~styles/override.css";
where
override.css
has the following content:div.plasmo-csui-container { margin: 0; color-scheme: var(--mantine-color-scheme); font-family: var(--mantine-font-family); font-size: var(--mantine-font-size-md); line-height: var(--mantine-line-height); background-color: var(--mantine-color-body); color: var(--mantine-color-text); -webkit-font-smoothing: var(--mantine-webkit-font-smoothing); -moz-osx-font-smoothing: var(--mantine-moz-font-smoothing); }
- Define
MantineProvider
to use the following props:<MantineProvider theme={...} cssVariablesSelector="div.plasmo-csui-container" getRootElement={() => document.querySelector("plasmo-csui").shadowRoot.querySelector("div.plasmo-csui-container") } > <style>{mantineCss + overrideCss}</style> {...} </MantineProvider>
The main difference you'll notice is that we changed the
cssVariablesSelector
prop from:host
todiv.plasmo-csui-container
. This allows Mantine to correctly source CSS variables from within thediv.plasmo-csui-container
container.You'll also notice that we updated the
override.css
CSS to use the same container as its selector.We also define the
getRootElement
prop to correctly set thedata-mantine-color-scheme
attribute (Ref: https://mantine.dev/theming/mantine-provider/#getrootelement).Lastly, we drop the use of Plasmo's
getStyle
function, and apply it inline via<style>
tags withinMantineProvider
, so that the styles are inserted inline within thediv.plasmo-csui-container
container.Full implementation via a dedicated
theme.tsx
file:import { createTheme, MantineProvider, mergeThemeOverrides, Modal } from "@mantine/core"; import mantineCss from "data-text:@mantine/core/styles.css"; import overrideCss from "data-text:~styles/override.css"; export const defaultTheme = createTheme({}); const contentTheme = createTheme({ components: { Modal: Modal.extend({ defaultProps: { withinPortal: false } }) } }); const mergedTheme = mergeThemeOverrides(defaultTheme, contentTheme); export function ContentProvider({ children }) { return ( <MantineProvider theme={mergedTheme} defaultColorScheme="auto" cssVariablesSelector="div.plasmo-csui-container" getRootElement={() => document.querySelector("plasmo-csui").shadowRoot.querySelector("div.plasmo-csui-container") } > <style>{mantineCss + overrideCss}</style> {children} </MantineProvider> ); }
where
defaultTheme
can be imported to be used in your app'sMantineProvider
, while still applying to CSUI components.contentTheme
includes theme overrides that should only be applied to CSUI components.mergedTheme
merges the two and uses it within a dedicatedContentProvider
, which wrapsMantineProvider
with the necessary overrides to apply Mantine styles to CSUI components. This should make it easier to develop CSUI components, since all the overrides are done locally in this file.Lastly, make sure to set modals (among other components) to render within the shadow DOM, not via a portal:
const theme = createTheme({ components: { Modal: Modal.extend({ defaultProps: { withinPortal: false } }) } });
This allows styles to be correctly applied to the modal, since it will render with the shadow DOM's styles that we set inline above.
Please let us know if this works for you!
I have tried it, this approach seems to be better, but there are still a few problems that I encountered when trying some components.
Modal
and Drawer
display is not suitable, the Modal
is not in the center of the page with other components on its left side, and the same goes for the Drawer
.Notifications
is also the same, I tried to position it at the bottom right, but it doesn't seem to work.https://github.com/PlasmoHQ/plasmo/assets/123402607/ea522800-1eda-46dc-a014-9e19b31a3502
// theme.tsx
. . .
const contentTheme = createTheme({
components: {
Modal: Modal.extend({ defaultProps: { withinPortal: false } }),
Drawer: Drawer.extend({ defaultProps: { withinPortal: false } }),
Dialog: Dialog.extend({ defaultProps: { withinPortal: false } }),
Affix: Affix.extend({ defaultProps: { withinPortal: false } }),
Menu: Menu.extend({ defaultProps: { withinPortal: false } }),
HoverCard: HoverCard.extend({ defaultProps: { withinPortal: false } }),
Popover: Popover.extend({ defaultProps: { withinPortal: false } }),
Notifications: Notifications.extend({ defaultProps: { withinPortal: false, position: "bottom-right" } })
}
})
. . .
I've successfully solve my issue above. The problem was in this import:
import "@mantine/core/styles.css";
When we use it inside popup or the side panel page, it will work fine because it's isolated from the main webpage. However, when we create an extension with overlay/inline with the webpage, the import above will override the CSS of the main webpage because it was imported globally. If we removed that line, some Mantine's components won't work. For my case, Mantine's modal didn't work because it was portal-ed from shadow DOM to the main webpage. So, the modal can't access the CSS inside the shadow DOM. My solution is I implemented my own custom modal that can work inside shadow DOM.
Ran into the same issue and found a workaround. Not fully tested, so please let us know if you run into any issues if you try this out.
As mentioned above, the main issue is due to the following import, which applies Mantine styles globally:
import "@mantine/core/styles.css";
However, if we remove this import, some styles are not applied, even when exporting Plasmo's
getStyle
function.It appears that Plasmo's
getStyle
function adds the CSS style directly under#shadow-root
, which does not correctly apply to Mantine components within.It seems that when the
cssVariablesSelector
is set to:host
, Mantine doesn't correctly find CSS variables from the<style>
tag that Plasmo inserted underneath the shadow DOM.To force Mantine to correctly use the inline styles, we can make the following changes:
1. Import the default Mantine styles (as text):
import mantineCss from "data-text:@mantine/core/styles.css";
2. Import custom CSS styles to apply global styles within the shadow DOM (as text):
import overrideCss from "data-text:~styles/override.css";
where
override.css
has the following content:div.plasmo-csui-container { margin: 0; color-scheme: var(--mantine-color-scheme); font-family: var(--mantine-font-family); font-size: var(--mantine-font-size-md); line-height: var(--mantine-line-height); background-color: var(--mantine-color-body); color: var(--mantine-color-text); -webkit-font-smoothing: var(--mantine-webkit-font-smoothing); -moz-osx-font-smoothing: var(--mantine-moz-font-smoothing); }
3. Define `MantineProvider` to use the following props:
<MantineProvider theme={...} cssVariablesSelector="div.plasmo-csui-container" getRootElement={() => document.querySelector("plasmo-csui").shadowRoot.querySelector("div.plasmo-csui-container") } > <style>{mantineCss + overrideCss}</style> {...} </MantineProvider>
The main difference you'll notice is that we changed the
cssVariablesSelector
prop from:host
todiv.plasmo-csui-container
. This allows Mantine to correctly source CSS variables from within thediv.plasmo-csui-container
container.You'll also notice that we updated the
override.css
CSS to use the same container as its selector.We also define the
getRootElement
prop to correctly set thedata-mantine-color-scheme
attribute (Ref: https://mantine.dev/theming/mantine-provider/#getrootelement).Lastly, we drop the use of Plasmo's
getStyle
function, and apply it inline via<style>
tags withinMantineProvider
, so that the styles are inserted inline within thediv.plasmo-csui-container
container.Full implementation via a dedicated
theme.tsx
file:import { createTheme, MantineProvider, mergeThemeOverrides, Modal } from "@mantine/core"; import mantineCss from "data-text:@mantine/core/styles.css"; import overrideCss from "data-text:~styles/override.css"; export const defaultTheme = createTheme({}); const contentTheme = createTheme({ components: { Modal: Modal.extend({ defaultProps: { withinPortal: false } }) } }); const mergedTheme = mergeThemeOverrides(defaultTheme, contentTheme); export function ContentProvider({ children }) { return ( <MantineProvider theme={mergedTheme} defaultColorScheme="auto" cssVariablesSelector="div.plasmo-csui-container" getRootElement={() => document.querySelector("plasmo-csui").shadowRoot.querySelector("div.plasmo-csui-container") } > <style>{mantineCss + overrideCss}</style> {children} </MantineProvider> ); }
where
defaultTheme
can be imported to be used in your app'sMantineProvider
, while still applying to CSUI components.contentTheme
includes theme overrides that should only be applied to CSUI components.mergedTheme
merges the two and uses it within a dedicatedContentProvider
, which wrapsMantineProvider
with the necessary overrides to apply Mantine styles to CSUI components. This should make it easier to develop CSUI components, since all the overrides are done locally in this file.Lastly, make sure to set modals (among other components) to render within the shadow DOM, not via a portal:
const theme = createTheme({ components: { Modal: Modal.extend({ defaultProps: { withinPortal: false } }) } });
This allows styles to be correctly applied to the modal, since it will render with the shadow DOM's styles that we set inline above.
Please let us know if this works for you!
Thx to your explaination that make me got why those problems happens. I have tried ur solution but still exist a problem. So far I need Notication System
and Modal
. Under ur solution, the Modal
works. But Notificatio
lose styles. And I tryied to move Notification
to plasmo-csui as below
const contentTheme = createTheme({
components: {
Modal: Modal.extend({ defaultProps: { withinPortal: false } }),
Notifications: Notifications.extend({ defaultProps: { withinPortal: false, position: "bottom-right" } })
}
})
But the position of notification is error. It's always placed in left-top. And I don't know how the location system works. So I decide make notification within portal. And try to figure out the problem that styles losted. After my effort, it works. Maybe my solution can help u.
import '@mantine/core/styles.css';
import '@mantine/notifications/styles.css';
import mantineCss from 'data-text:@mantine/core/styles.css';
export const getStyle = () => {
const style = document.createElement('style');
// tailwindCss refer to https://docs.plasmo.com/quickstarts/with-tailwindcss
style.textContent = mantineCss + tailwindCss().textContent;
return style;
};
const theme = createTheme({
components: {
Modal: Modal.extend({ defaultProps: { withinPortal: false } }),
},
});
const getRootElement = () => {
return document.querySelector('plasmo-csui').shadowRoot.querySelector('div.plasmo-csui-container') as HTMLElement;
};
function ContentApp() {
useEffect(() => {
const html = document.querySelector('html');
html.setAttribute('data-mantine-color-scheme', 'light');
}, []);
return (
<>
<MantineProvider theme={theme} getRootElement={getRootElement}>
<Notifications />
<ModalsProvider />
</MantineProvider>
</>
);
}
export default ContentApp;
What happened?
I am using mantine to create a CSUI. I need to import
@mantine/core/styles.css
. Following the Import Stylesheet guide, it doesn't work well. The code:The result: (the button should have a blue background and the input should have a light gray background)
If I add a normal import line, some styles will work, some not. The code:
The result:
Inspect the input component, it shows that some css variables are not define.
Same components works well in popup
Version
Latest
What OS are you seeing the problem on?
No response
What browsers are you seeing the problem on?
No response
Relevant log output
No response
(OPTIONAL) Contribution
Code of Conduct