Skip to content
This repository was archived by the owner on May 3, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
9 changes: 6 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const elmWebComponents = {
onDetached = () => {},
mapFlags = flags => flags,
onSetupError,
useShadowDom = false,
} = {}
) {
if (!this.__elmVersion) {
Expand Down Expand Up @@ -70,23 +71,25 @@ 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
* we create a div that we let Elm render into, and manually clear any pre-rendered contents.
*/
const elmDiv = document.createElement('div')

this.innerHTML = ''
this.appendChild(elmDiv)
parentDiv.innerHTML = ''
parentDiv.appendChild(elmDiv)

const elmElement = ElmComponent.init({
flags,
node: elmDiv,
})
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) {
Expand Down