{"id":31103827,"url":"https://github.com/peterszerzo/elm-arborist","last_synced_at":"2025-09-17T02:58:51.714Z","repository":{"id":62418982,"uuid":"102002444","full_name":"peterszerzo/elm-arborist","owner":"peterszerzo","description":"Parameterized 🌲tree🌲-editor for Elm","archived":false,"fork":false,"pushed_at":"2020-05-16T07:14:24.000Z","size":1866,"stargazers_count":60,"open_issues_count":2,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-04-14T23:57:17.736Z","etag":null,"topics":["elm","tree-structure","visualization"],"latest_commit_sha":null,"homepage":"http://package.elm-lang.org/packages/peterszerzo/elm-arborist/latest","language":"Elm","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/peterszerzo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-08-31T13:15:47.000Z","updated_at":"2024-01-10T10:34:37.000Z","dependencies_parsed_at":"2022-11-01T16:47:31.005Z","dependency_job_id":null,"html_url":"https://github.com/peterszerzo/elm-arborist","commit_stats":null,"previous_names":[],"tags_count":43,"template":false,"template_full_name":null,"purl":"pkg:github/peterszerzo/elm-arborist","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterszerzo%2Felm-arborist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterszerzo%2Felm-arborist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterszerzo%2Felm-arborist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterszerzo%2Felm-arborist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peterszerzo","download_url":"https://codeload.github.com/peterszerzo/elm-arborist/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peterszerzo%2Felm-arborist/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275526439,"owners_count":25480460,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-17T02:00:09.119Z","response_time":84,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elm","tree-structure","visualization"],"created_at":"2025-09-17T02:58:49.088Z","updated_at":"2025-09-17T02:58:51.699Z","avatar_url":"https://github.com/peterszerzo.png","language":"Elm","funding_links":[],"categories":[],"sub_categories":[],"readme":"```\n  🌲           🌲                             🌲          \n 🌲🌲   🌲🌲 🌲      🌲   🌲  🌲   🌲     🌲  🌲      🌲🌲             🌲    \n🌲🌲🌲  🌲🌲🌲 🌲  🌲🌲🌲 🌲🌲  🌲  🌲🌲🌲 🌲🌲🌲   🌲 🌲🌲        🌲🌲      🌲   \n```\n\n# elm-arborist\n\nDrag-and-drop interface to edit, dissect and-rearrange tree structures, with nodes holding any data type you wish. Here is a [demo](https://peterszerzo.github.io/elm-arborist/), and here some [docs](http://package.elm-lang.org/packages/peterszerzo/elm-arborist/latest).\n\n## Getting started\n\n**TLDR:** [simple app example](https://github.com/peterszerzo/elm-arborist/blob/master/examples/Simple.elm) (run with `cd examples \u0026\u0026 elm reactor`, then open http://localhost:8000/Simple.elm)\n\nFirst things first, we need to specify what kind of data structure our tree's nodes will hold. For this demo, it will be a record with a question and an answer.\n\n```elm\ntype alias MyNode =\n    { question : String\n    , answer : String\n    }\n\nexampleNode = MyNode \"How are you?\" \"Fine thanks\"\n```\n\nWe can then use the `Arborist.Tree` module to recursively construct a tree structure:\n\n```elm\nimport Arborist.Tree as Tree\n\ntree : Tree.Tree MyNode\ntree =\n  Tree.Node (MyNode \"Q1\" \"A1\")\n    [ Tree.Node (MyNode \"Q2\" \"A2\") []\n    , Tree.Node (MyNode \"Q3\" \"A3\")\n        [ Tree.Node ( \"Q4\", \"A4\" )\n        ]\n    ]\n```\n\nNow, we can now define a model for your app:\n\n```elm\nimport Arborist\nimport Arborist.Tree as Tree\n\ntype alias Model =\n  { tree : Tree.Tree MyNode\n  , arborist : Arborist.State\n  }\n```\n\nNext, we configure the editor:\n\n```elm\narboristSettings : List (Arborist.Setting MyNode)\narboristSettings =\n    [ Settings.keyboardNavigation True\n    , Settings.defaultNode (MyNode \"A\" \"Q\")\n    , Settings.nodeWidth 100\n    , Settings.level 80\n    , Settings.gutter 20\n    ]\n```\n\nRendering the editor will look like this:\n\n```elm\nview : Model -\u003e Html Msg\nview model =\n    Arborist.view\n        []\n        { state = model.arborist\n        , tree = model.tree\n        , settings = arboristSettings\n        -- We get to these two in a second\n        , nodeView = nodeView\n        , toMsg = Arborist\n        }\n```\n\nNow let's look at the two bits we left out: `nodeView` and `toMsg`.\n\n### `nodeView`\n\nThis function specifies how a node should be displayed within its bounding box, and looks like this:\n\n```elm\n-- Don't worry about `context` for now\nnodeView : Arborist.NodeView MyNode Msg\nnodeView context maybeNode =\n    case maybeNode of\n        Just node -\u003e\n            text node.question\n\n        Nothing -\u003e\n            text \"+ add node\"\n```\n\n### `toMsg`\n\nArborist uses the teach-me-how-to-message pattern, passing an `Arborist.Updater` to your app's `update` function. The updater is a function that works out the new tree and new state based on the previous tree and previous state.\n\n```elm\ntype Msg\n    -- This is the message constructor that goes into the `toMsg` field above\n    = Arborist (Arborist.Updater MyNode)\n\nupdate : Msg -\u003e Model -\u003e ( Model, Cmd Msg )\nupdate msg model =\n    case msg of\n        Arborist updater -\u003e\n            let\n                ( newState, newTree ) =\n                    updater model.arborist model.tree\n            in\n            ( { model\n                | arborist = newState\n                , tree = newTree\n              }\n            , Cmd.none\n            )\n```\n\n\u003e Arborist cannot give new values straight away because mouse events are fired so quickly that they can undo each others' changes in the runtime, hence the complexity in the update logic above.\n\nAnd that's it - your very own tree editor is ready.\n\n## Going further\n\n### Context\n\nThe [context object](https://package.elm-lang.org/packages/peterszerzo/elm-arborist/latest/Arborist#Context) exposed in the `nodeView` function above provides, as its name suggests, contextual information to the node when it is rendered, including their parent node and list of siblings. 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.\n\nThis should work for a large number of tree editing cases. If you need a broader context, you will need to traverse the tree yourself.\n\n### UX goodies\n\nIn the [settings module](https://package.elm-lang.org/packages/peterszerzo/elm-arborist/latest/Arborist-Settings), you will find setup instructions for advanced features like node clustering and keyboard navigation. For a real-world example, have a look at the [elm-arborist landing page](https://github.com/peterszerzo/elm-arborist/blob/master/landing/src/Landing.elm).\n\n## Contributing\n\nContributions welcome - please feel free to go ahead with issues and PR's, or reach out to me on Elm Slack at `@peterszerzo`.\n\n## License\n\nMIT.\n\n\n```\n🌲🌲🌲  🌲🌲🌲 🌲  🌲🌲🌲 🌲🌲  🌲  🌲🌲🌲 🌲🌲🌲   🌲 🌲🌲        🌲🌲      🌲   \n 🌲🌲   🌲🌲 🌲      🌲   🌲  🌲   🌲     🌲  🌲      🌲🌲             🌲    \n  🌲           🌲                             🌲          \n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeterszerzo%2Felm-arborist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeterszerzo%2Felm-arborist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeterszerzo%2Felm-arborist/lists"}