Skip to content
This repository was archived by the owner on May 3, 2023. It is now read-only.

Commit 62e4a26

Browse files
authoredJan 21, 2020
Merge pull request #17 from mdevlamynck/shadow-dom
Add support for wrapping elm rendered dom in shadow dom
2 parents cea5ac0 + 0a3ea6c commit 62e4a26

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed
 

‎README.md

+11
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,17 @@ And now in your HTML you can use the component:
8181

8282
Any attributes are passed into your Elm app as Flags.
8383

84+
## Shadow Dom
85+
86+
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:
87+
88+
```js
89+
import elmWebComponents from '@teamthread/elm-web-components'
90+
import ElmApp from './Main.elm'
91+
92+
elmWebComponents.register('demo-elm-component', ElmApp.Main, {useShadowDom: true})
93+
```
94+
8495
## Ports
8596

8697
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:

‎src/index.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const elmWebComponents = {
4242
onDetached = () => {},
4343
mapFlags = flags => flags,
4444
onSetupError,
45+
useShadowDom = false,
4546
} = {}
4647
) {
4748
if (!this.__elmVersion) {
@@ -70,23 +71,25 @@ const elmWebComponents = {
7071
const flags = mapFlags(props)
7172
context.flags = flags
7273

74+
const parentDiv = useShadowDom ? this.attachShadow({mode: 'open'}) : this;
75+
7376
if (elmVersion === '0.19') {
7477
/* a change in Elm 0.19 means that ElmComponent.init now replaces the node you give it
7578
* whereas in 0.18 it rendered into it. To avoid Elm therefore destroying our custom element
7679
* we create a div that we let Elm render into, and manually clear any pre-rendered contents.
7780
*/
7881
const elmDiv = document.createElement('div')
7982

80-
this.innerHTML = ''
81-
this.appendChild(elmDiv)
83+
parentDiv.innerHTML = ''
84+
parentDiv.appendChild(elmDiv)
8285

8386
const elmElement = ElmComponent.init({
8487
flags,
8588
node: elmDiv,
8689
})
8790
setupPorts(elmElement.ports)
8891
} else if (elmVersion === '0.18') {
89-
const elmElement = ElmComponent.embed(this, flags)
92+
const elmElement = ElmComponent.embed(parentDiv, flags)
9093
setupPorts(elmElement.ports)
9194
}
9295
} catch (error) {

0 commit comments

Comments
 (0)
This repository has been archived.