diff --git a/rollup.config.js b/rollup.config.js index 93c4434b..958d1e03 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -19,5 +19,13 @@ export default createConfig({ }, plugins: { // Modify plugins options here. + replace: { + // Replace X CSS injector by our custom one. + 'addStyle(id, style);': 'window.xCSSInjector.addStyle(style);', + delimiters: ['', ''] + }, + styles: { + mode: ['inject', varname => `window.xCSSInjector.addStyle({ source: ${varname} });`] + } } }); diff --git a/src/main.ts b/src/main.ts index a986278b..b41dc4a7 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,3 +1,4 @@ +import './xCSSInjector'; import { XInstaller } from '@empathyco/x-components'; import Vue from 'vue'; import { installXOptions } from './x-components/plugin.options'; diff --git a/src/shims-tsx.d.ts b/src/shims-tsx.d.ts index 56efc194..34239b15 100644 --- a/src/shims-tsx.d.ts +++ b/src/shims-tsx.d.ts @@ -1,5 +1,10 @@ import Vue, { VNode } from 'vue'; +export interface XCSSInjector { + addStyle: (styles: { source: string }) => void; + setHost: (el: Element | ShadowRoot) => void; +} + declare global { namespace JSX { interface Element extends VNode {} @@ -8,4 +13,7 @@ declare global { [elem: string]: any; } } + interface Window { + xCSSInjector: XCSSInjector; + } } diff --git a/src/x-components/plugin.options.ts b/src/x-components/plugin.options.ts index 80a77d7a..f8744b82 100644 --- a/src/x-components/plugin.options.ts +++ b/src/x-components/plugin.options.ts @@ -6,11 +6,31 @@ import store from '../store'; import { adapter } from '../adapter/adapter'; import { useDevice } from '../composables/use-device.composable'; +console.log(process.env.NODE_ENV); + const device = useDevice(); + +function getDomElement(): Element { + const domElement = document.createElement('div'); + if (process.env.NODE_ENV === 'production' || true) { + const container = document.createElement('div'); + const shadowRoot = container.attachShadow({ mode: 'open' }); + shadowRoot.appendChild(domElement); + document.body.appendChild(container); + window.xCSSInjector.setHost(shadowRoot); + } else { + document.body.appendChild(domElement); + window.xCSSInjector.setHost(document.head); + } + + return domElement; +} + export const installXOptions: InstallXOptions = { adapter, store, app: App, + domElement: getDomElement, xModules: { facets: { config: { diff --git a/src/xCSSInjector.ts b/src/xCSSInjector.ts new file mode 100644 index 00000000..d64660c4 --- /dev/null +++ b/src/xCSSInjector.ts @@ -0,0 +1,25 @@ +import { XCSSInjector } from './shims-tsx'; + +class CssInjector implements XCSSInjector { + protected host!: Element | ShadowRoot; + protected stylesQueue: string[] = []; + + addStyle(styles: { source: string }): void { + console.log(styles); + this.stylesQueue.push(styles.source); + if (this.host) { + this.stylesQueue.forEach(styles => { + const styleTag = document.createElement('style'); + styleTag.textContent = styles; + this.host.appendChild(styleTag); + }); + this.stylesQueue = []; + } + } + + setHost(host: Element | ShadowRoot): void { + this.host = host; + } +} + +window.xCSSInjector = new CssInjector();