Skip to content

Repository files navigation

browser-json-tree

Typed Halogen renderer + click behaviour for collapsible JSON trees.

📚 Full documentation + live demo: lambdasistemi.github.io/browser-json-tree

What is this

browser-json-tree turns a Data.Argonaut.Core.Json value into a foldable Halogen.HTML.HTML tree. Objects and array items render as native <details>/<summary> elements, so the open/closed state lives in the DOM rather than in a Halogen state machine. Array rows carry a CAD-style index bracket instead of a bullet, and string leaves are run through a configurable resolver that can upgrade them into truncated, hyperlinked <a> elements.

The default resolver (JsonTree.Cardano.resolve) recognises four Cardano string shapes — transaction id, transaction-output reference (<txid>#<ix>), bech32 address, and minting policy id — and links each to cardanoscan.io. Non-Cardano consumers pass their own String -> Maybe LinkSpec and keep the rest of the tree unchanged.

A small companion JS shim (JsonTree.Behaviour.install) adds the document-level gestures that native <details> does not: single-click toggles one level and cascade-closes descendants, double-click expands a subtree recursively, and any .v-copy element with a data-copy attribute writes its value to the clipboard. The renderer emits no per-leaf copy buttons; structure-level copy is a consumer affordance the library ships the CSS and handler for.

Two consumption paths exist: PureScript/Halogen apps call JsonTree.render directly, while vanilla JavaScript apps import the bundled ES module (JsonTree.JS → dist/browser-json-tree.js) and call mount. The self-contained stylesheet dist/json-tree.css is themable through --jt-* custom properties.

Architecture

flowchart TD
    PSApp["PureScript / Halogen app"]
    JSApp["Vanilla JS app"]

    subgraph lib["browser-json-tree (src/)"]
        Render["JsonTree<br/>render / renderWith / Config"]
        Cardano["JsonTree.Cardano<br/>default string-leaf resolver"]
        Behaviour["JsonTree.Behaviour<br/>install (click / dblclick / copy)"]
        JSAdaptor["JsonTree.JS<br/>mount / mountFromString / install"]
    end

    Bundle["dist/browser-json-tree.js<br/>spago bundle of JsonTree.JS"]
    CSS["dist/json-tree.css<br/>--jt-* themable styles"]

    PSApp --> Render
    PSApp --> Behaviour
    JSApp --> Bundle
    Bundle --> JSAdaptor
    JSAdaptor --> Render
    JSAdaptor --> Behaviour
    Render --> Cardano
    Render -.->|"emits .v-* classes"| CSS
    Behaviour -.->|"toggles open / .v-copy--ok"| CSS
Loading

Install

browser-json-tree ships in two flavours.

PureScript / Halogen — add the tagged Git source to spago.yaml:

package:
  dependencies:
    - browser-json-tree
workspace:
  extraPackages:
    browser-json-tree:
      git: https://github.com/lambdasistemi/browser-json-tree.git
      ref: v0.2.0
      dependencies: [argonaut-core, halogen]

Vanilla JavaScript — pull the standalone ES module bundle and the stylesheet from the latest GitHub Release. Every release ships browser-json-tree-<version>.js and json-tree-<version>.css as standalone assets.

See the installation guide for the full matrix (vendored CSS, npm github: dependency, CDN).

Quickstart

PureScript / Halogen:

import JsonTree as JsonTree
import JsonTree.Behaviour as Behaviour

main = HA.runHalogenAff do
  body <- HA.awaitBody
  _ <- runUI rootComponent unit body
  H.liftEffect Behaviour.install

view someJson =
  HH.div [ HP.class_ (HH.ClassName "json-tree-wrapper") ]
    [ JsonTree.render someJson ]

Vanilla JavaScript:

<link rel="stylesheet" href="./json-tree.css" />
<div id="tree" class="json-tree-wrapper"></div>
<script type="module">
  import { mount, install } from "./browser-json-tree.js";
  install();
  mount(document.getElementById("tree"), { hello: "world" });
</script>

Usage

  • JsonTree.render renders with defaultConfig: compound nodes collapsed, empty values (null, [], {}) hidden, Cardano string-leaf resolution on.
  • JsonTree.renderWith takes a Config — { initiallyOpen :: Boolean, hideEmpty :: Boolean, resolveString :: String -> Maybe LinkSpec }.
  • JsonTree.Behaviour.install wires the single-click / double-click / copy gestures. Call once from main.
  • The vanilla-JS surface (JsonTree.JS) exposes mount, mountFromString, and install, always using the default Config.

Full surface, the class taxonomy, and a worked custom-resolver example live in the usage and API pages.

Documentation

Development

nix develop          # purs / spago / purs-tidy / esbuild / nodejs / mkdocs / just
just build           # spago build the library (compile only)
just lint            # purs-tidy check
just js-bundle       # bundle JsonTree.JS -> dist/browser-json-tree.js
just example         # bundle the example app
just docs            # build the docs site into ./_site
just ci              # nix flake check (full local mirror of CI)

License

Apache-2.0, matching the upstream amaru-treasury-tx.

Credits

Extracted from lambdasistemi/amaru-treasury-tx's InspectReport renderer. The recursive collapse semantics, the CAD-style array bracket, and the cardanoscan resolution heuristics all originate there.

Releases

Packages

Contributors

Languages