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

Commit 2da25b7

Browse files
author
Matthias Devlamynck
committed
Add support for wrapping elm rendered dom in shadow dom
1 parent 728b887 commit 2da25b7

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

README.md

Lines changed: 11 additions & 0 deletions
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

Lines changed: 12 additions & 4 deletions
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,30 @@ const elmWebComponents = {
7071
const flags = mapFlags(props)
7172
context.flags = flags
7273

74+
var elmDiv = this;
75+
var parentDiv = this;
76+
77+
if (useShadowDom) {
78+
parentDiv = this.attachShadow({mode: 'open'});
79+
}
80+
7381
if (elmVersion === '0.19') {
7482
/* a change in Elm 0.19 means that ElmComponent.init now replaces the node you give it
7583
* whereas in 0.18 it rendered into it. To avoid Elm therefore destroying our custom element
7684
* we create a div that we let Elm render into, and manually clear any pre-rendered contents.
7785
*/
78-
const elmDiv = document.createElement('div')
86+
elmDiv = document.createElement('div')
7987

80-
this.innerHTML = ''
81-
this.appendChild(elmDiv)
88+
parentDiv.innerHTML = ''
89+
parentDiv.appendChild(elmDiv)
8290

8391
const elmElement = ElmComponent.init({
8492
flags,
8593
node: elmDiv,
8694
})
8795
setupPorts(elmElement.ports)
8896
} else if (elmVersion === '0.18') {
89-
const elmElement = ElmComponent.embed(this, flags)
97+
const elmElement = ElmComponent.embed(elmDiv, flags)
9098
setupPorts(elmElement.ports)
9199
}
92100
} catch (error) {

0 commit comments

Comments
 (0)