🌲 🌲 🌲 🌲🌲 🌲🌲 🌲 🌲 🌲 🌲 🌲 🌲 🌲 🌲🌲 🌲 🌲🌲🌲 🌲🌲🌲 🌲 🌲🌲🌲 🌲🌲 🌲 🌲🌲🌲 🌲🌲🌲 🌲 🌲🌲 🌲🌲 🌲
First things first, we need to specify what kind of data structure our tree's nodes will hold. For this demo, it'll be a tuple of names and ages.
type alias Node = ( String, Int ) exampleNode = ( "Frank", 54 )
We can then use the
Arborist.Tree module to construct a tree structure:
import Arborist.Tree as Tree tree = Arborist.node ( "Frank", 54 ) [ Arborist.node ( "Mark", 36 )  , Arborist.node ( "Sally", 31 ) [ Arborist.node ( "Robert", 14 ) ] ]
The tree is defined recursively, with each node holding an arbitrary number of children. This is similar to the binary tree example on the Elm website.
Anyway, we can now define a model Arborist can work with:
import Arborist type alias Model = Arborist.Model Node init : Model init = Arborist.init tree
Notice how the model needs to know what data structure it holds, hence the type variable reference to the
Node structure defined above.
The rest is pretty much standard Elm architecture:
type Msg = ArboristMsg Arborist.Msg update msg model = case msg of ArboristMsg arboristMsg -> Arborist.update arboristMsg model view model = Arborist.view nodeView  model
The final missing piece is
nodeView. It specifies how a node should be displayed, and has the following form:
-- Ignore `Context` for now view : Context -> Maybe Node -> Html msg view _ maybeNode = -- The node is not always available, because we also need to -- specify how placeholders are rendered. case maybeNode of Just ( name, age ) -> div  [ span  [ text name ], span  [ text (toString age) ] ] Nothing -> div  [ text "Insert node" ]
That's it - your very own tree editor is ready.
The context object provides, as its name suggests, contextual information to the node when it is rendered, including their parent node and list of siblings (see
Arborist.Context docs for details). You may for instance want to signal to the user that a child can't be older than their parent in the family tree as they edit it, but traversing the tree to find that information is tedious and inefficient - so Arborist gives you access to it directly.
This should work for a large number of tree editing cases. If you need a broader context, you will need to traverse the tree for it yourself.
initWith [ Arborist.Settings.canvasWidth 800, Arborist.Settings.nodeHeight 40, Arborist.Settings.gutter 20 ] to add all kinds of customizations to the editor. See
Arborist.subscriptions, you can smoothly animate to center a node when it is activated. See example for details.
You can use
styledView instead of
StyledNodeView instead of
NodeView if you wish to use elm-css to style your view.
elm-css under the hood, as it was necessary for most realistic use-cases that came up with the library.
Please open an issue if first-class style-elements support is essential to your project.
🌲🌲🌲 🌲🌲🌲 🌲 🌲🌲🌲 🌲🌲 🌲 🌲🌲🌲 🌲🌲🌲 🌲 🌲🌲 🌲🌲 🌲 🌲🌲 🌲🌲 🌲 🌲 🌲 🌲 🌲 🌲 🌲 🌲🌲 🌲 🌲 🌲 🌲