npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@teamthread/elm-web-components

v1.1.1

Published

Run your Elm apps through web components.

Downloads

5,287

Readme

elm-web-components

A small JavaScript package to let you wrap your Elm applications up in a web component.

Only supports the V1 web component spec.

Install

yarn add @teamthread/elm-web-components

Configuration (new in 0.6.0)

We support both Elm 0.18 and 0.19. You must configure the module so it knows which one to support:

elmWebComponents.configure('0.18')
// OR:
elmWebComponents.configure('0.19')

You will get an error and the library will not work without this configuration step.

Example

Given the following Elm app:

module Main exposing (..)

import Html exposing (text, Html)
import Browser

type Msg
    = NoOp


type alias Model =
    { name : String
    }


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    ( model, Cmd.none )

view : Model -> Html Msg
view model =
  text ("Hello world, my name is: " ++ model.name)


type alias Flags =
    { name : String }

init : Flags -> ( Model, Cmd Msg )
init flags =
    ( Model flags.name, Cmd.none )


main : Program Flags Model Msg
main =
    Browser.element
        { init = init, update = update, subscriptions = \_ -> Sub.none, view = view }

You can create a custom web element that will render it like so:

import elmWebComponents from '@teamthread/elm-web-components'
import ElmApp from './Main.elm'

elmWebComponents.register('demo-elm-component', ElmApp.Main)

And now in your HTML you can use the component:

<demo-elm-component name="Jack"></demo-elm-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:

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:

elmWebComponents.register('component-with-ports', ComponentWithPorts, {
  setupPorts: ports => {
    ports.somePort.send(1)
    ports.someOtherPort.subscribe(data => {
      // deal with port here
    })
  },
})

Static Flags

Sometimes you will want to pass in flags not only via HTML attributes, but from JavaScript. The third argument to elmWebComponents.register takes a staticFlags object which will be passed in:

elmWebComponents.register('component-with-ports', ComponentWithPorts, {
  setupPorts: ports => {},
  staticFlags: {
    someCustomProp: 'foo',
  },
})

Now, rendering the component like so:

<component-with-ports name="Jack"></component-with-ports>

Will pass through two flags: someCustomProp and name. Note that currently if a static flag and a passed attribute have the same name, the static flag takes priority.

Transforming flags

Sometimes you might want to pre-process the flags a bit in Javascript before giving them to Elm. For example, all the attributes from the DOM are strings, but you might want to make one of them an integer:

elmWebComponents.register('component-with-ports', ComponentWithPorts, {
  mapFlags: flags => {
    const someId = parseInt(flags.someId)
    return Object.assign({}, flags, { someId })
  },
})

Rendering the component with:

<component-with-ports some-id="1"></component-with-ports>

Will pass the flags as { someId : Int }, rather than { someId : String }.

onDetached

If you need to do some work when the Elm component is removed from the DOM, you can now pass onDetached: () => ... as another option:

elmWebComponents.register('component-with-ports', ComponentWithPorts, {
  setupPorts: ports => {},
  staticFlags: {
    someCustomProp: 'foo',
  },
  onDetached: () => {
    console.log('Called when the component is removed from the DOM')
  },
})

This is useful for tidying up any event listeners you might have.

Handling errors

If you want to catch any errors registering the component, you can pass onSetupError:

elmWebComponents.register('component-with-ports', ComponentWithPorts, {
  onSetupError: error => {
    console.log('Something went wrong', error)
  },
})

Examples

You can find full examples in the example directory. If you have cloned the repository, you can run yarn run example-018 or yarn run example-019 to run them locally.

Polyfilling for older browsers

elm-web-components does not ship with any polyfills. You should ensure the following functions are available in all browsers you support:

  • Object.assign
  • Object.keys

And additionally ensure that you've included a polyfill for custom elements. We recommend document-register-element.