allo-media / canopy

A generic Tree API in Elm
http://package.elm-lang.org/packages/allo-media/canopy/latest
MIT License
11 stars 0 forks source link

insertBefore, swap, move, isEmpty #4

Open janwirth opened 6 years ago

janwirth commented 6 years ago

I have implemented and tested the functions insertBefore, swap and isEmpty Are you interested in a PR once I also have move done?

n1k0 commented 6 years ago

Most definitely, these sound super useful :+1:

janwirth commented 6 years ago

I also have a DataTree implementation that wraps tree and a dict to work with the tree with unique ids without having unique content. I have not written any tests for that one though.

n1k0 commented 6 years ago

As mentioned early in the docs, I really tend to delegate dealing with uniqueness to developers using this lib, as I never found a generic enough way to expose a reasonable API to deal with it; though I'm curious about your Dict-based solution. Do you have a sample snippet leveraging this API?

janwirth commented 6 years ago

-- User UI library
import Bulma
-- sub-model
import Component exposing (Component)

import DataTree exposing (DataTree, dataTree, TreeLocation(..))

initialUiSpec : DataTree Component
initialUiSpec = dataTree Component.root
  |> DataTree.insert (AsLastChildOf 0) Bulma.columns
  |> DataTree.insert (AsLastChildOf 1) Bulma.column
  |> DataTree.insert (AsLastChildOf 1) Bulma.column
  |> DataTree.insert (AsLastChildOf 0) Bulma.nav
  |> DataTree.insert (Before 2) Bulma.button
  |> DataTree.insert (AsLastChildOf 2) Bulma.button

render globalModel =
  renderRecursive globalModel (DataTree.withIds globalModel.uiSpec)

renderRecursive : Model.Model -> Node (Id, Component) -> Html Msg
-- ...
n1k0 commented 6 years ago

I see. Do you expose any way for defining node own ids or are these always autogenerated?

janwirth commented 6 years ago

Right now I don't because I do not need it yet. However I'm thinking of an id generator function that takes the current DataTree as input and returns a new ID.

n1k0 commented 6 years ago

So I did that initially in the early stages of the project, though quickly discarded the idea because:

  1. The API surface was larger & much harder to learn/grasp, especially when you indeed want to allow people to provide their own unique id generators
  2. It's harder than one may think (eg. constant validation of manipulations, violation error reporting, etc)

I realized that it wasn't too hard to deal with uniqueness outside of the lib, and decided to come with the simplest yet open implementation as possible. But I'm still open to the idea provided the implementation isn't too complex.

janwirth commented 6 years ago

I think it makes sense to put it into a separate Canopy.DataTree package or sth - The Canopy package is pretty good as is.

janwirth commented 6 years ago

Right now in my dataTree implemenation I am missing an insertNode as well - so that I can place subtrees anywhere in my tree.

n1k0 commented 6 years ago

I'm definitely interested in having insert, move and swap :+1:

n1k0 commented 6 years ago

Now I think about it, what would provide insert compared to existing append and prepend? :thinking:

janwirth commented 6 years ago

Insert allows you to put the new node anywhere not just at the start or end of the child list.

n1k0 commented 6 years ago

Right, that was obvious, sorry.

janwirth commented 5 years ago

Note: I prefer insertBefore and insertAfter over insert and a union type.

Same goes for moveToBefore moveToAfter. @n1k0 any intuitions?

I have picked up working with canopy again. It is awesome! Thank you for that.