diff --git a/README.md b/README.md index 731349b..5bcbb39 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,17 @@ And now in your HTML you can use the component: Any attributes are passed into your Elm app as Flags. +## Shadow Dom + +By default Elm will render inside your custom element directly, if you want to isolate the Elm renderer dom using shadow dom you can register the custom element like this: + +```js +import elmWebComponents from '@teamthread/elm-web-components' +import ElmApp from './Main.elm' + +elmWebComponents.register('demo-elm-component', ElmApp.Main, {useShadowDom: true}) +``` + ## Ports You can also hook up a component that uses ports. The third argument to `elmWebComponents.register` is an object that can take a function that will be called with the ports object that Elm provides, so you can then hook into it and `subscribe` and `send` to them as you would normally: diff --git a/src/index.js b/src/index.js index b97a6bd..28015ae 100644 --- a/src/index.js +++ b/src/index.js @@ -42,6 +42,7 @@ const elmWebComponents = { onDetached = () => {}, mapFlags = flags => flags, onSetupError, + useShadowDom = false, } = {} ) { if (!this.__elmVersion) { @@ -70,6 +71,8 @@ const elmWebComponents = { const flags = mapFlags(props) context.flags = flags + const parentDiv = useShadowDom ? this.attachShadow({mode: 'open'}) : this; + if (elmVersion === '0.19') { /* a change in Elm 0.19 means that ElmComponent.init now replaces the node you give it * whereas in 0.18 it rendered into it. To avoid Elm therefore destroying our custom element @@ -77,8 +80,8 @@ const elmWebComponents = { */ const elmDiv = document.createElement('div') - this.innerHTML = '' - this.appendChild(elmDiv) + parentDiv.innerHTML = '' + parentDiv.appendChild(elmDiv) const elmElement = ElmComponent.init({ flags, @@ -86,7 +89,7 @@ const elmWebComponents = { }) setupPorts(elmElement.ports) } else if (elmVersion === '0.18') { - const elmElement = ElmComponent.embed(this, flags) + const elmElement = ElmComponent.embed(parentDiv, flags) setupPorts(elmElement.ports) } } catch (error) {