pzavolinsky / elmx

A tiny precompiler that takes an Elm program with embedded HTML and desugars the HTML into elm-html syntax. Elmx is to Elm what React's JSX is to Javascript
MIT License
351 stars 11 forks source link

Keyed nodes #10

Closed daig closed 7 years ago

daig commented 7 years ago

In JSX there's special syntax for keyed nodes in a list:

<ul>{notes |> map (\ note -> <li key={note.id}>{note.task}</li>)}</ul>

There is functionality for keyed nodes in Elm but so far as I can tell they use a different datastructure from normal nodes. So, it will be tricky to implement this transform as it A possible first step is, rather than nesting like above (#9), simply translate <li key={k}>{stuff}</li> to (k,li [] [stuff]) and require the keyed parent node explicitly.

pzavolinsky commented 7 years ago

Hi @daig , I haven't used keyed elements in Elm, but this seems like something worth implementing.

I like the idea of translating a node with a key={k} attribute into (k,node), but I'll have to look into promoting the parent node into Html.Keyed.node.

Can you send me a working example in plain Elm?

daig commented 7 years ago

The example I'm working with is:

import List
import Uuid exposing (Uuid)
import Html exposing (li)
import Note
import Html.Keyed as Keyed
type alias Notes = List (Uuid,Note.Model)
view : Notes -> Html Msg
view notes = Keyed.ul [] (notes |> List.map (\(id,note) -> (toString id, li [] [Note.view note])))
pzavolinsky commented 7 years ago

Hi @daig , I've just pushed elmx@1.0.8 and Atom's language-elmx@1.2.9 with keyed node support.

I added some examples in the README and here.

I've also added some examples at the end of the live demo.

Thanks for suggesting this feature!

Cheers!

pzavolinsky commented 7 years ago

Here's your example in elmx:

import Html
import Html.Attributes
import Html.Keyed
import List
import Uuid exposing (Uuid)
import Note
type alias Notes = List (Uuid,Note.Model)

view : Notes -> Html Msg
view notes =
  let
    items = notes |> List.map (\(id,note) -> <li key={toString id}>{Note.view note}</li>)
  in
    <ul keyed>{:items}</ul>