Skip to content

HyDtcgTree

A hy-tree specialized for DTCG (W3C Design Tokens Community Group) documents. Pass a parsed DTCG JSON object via tokens, and the wrapper walks it, renders each group as a non-leaf tree item and each token as a leaf item with an inline value preview.

The wrapper owns expansion state (not the underlying hy-tree-items) so filter changes can transparently expand ancestors of matches without fighting the user's manual expansion.

Filter semantics: an item is visible when (1) its own path contains the filter text, (2) any descendant's path does, or (3) an ancestor's path does — in the last case, the ancestor's whole subtree "opens up" (every descendant renders, matching or not). Set strict-filter to disable the third case so only own/descendant matches remain.

Examples

Browser for a DTCG file — value previews follow $type (color swatch, dimension mono, shadow thumb, typography summary, alias chip). Previews show by default; set the valuePreview property to false to hide them.

javascript
<hy-dtcg-tree id="browser"></hy-dtcg-tree>

<script>
const browser = document.getElementById('browser');
browser.tokens = await (await fetch('/tokens.json')).json();
browser.addEventListener('select', (event) => {
console.log(event.detail.path, event.detail.token);
});
</script>

Filterable token picker — non-matching items hide; ancestors of matches stay visible and auto-expand. A matching group "opens up" every descendant regardless of self-match.

javascript
<hy-text-input id="filter" placeholder="Filter tokens" clearable></hy-text-input>
<hy-dtcg-tree id="picker"></hy-dtcg-tree>

<script>
const filter = document.getElementById('filter');
const picker = document.getElementById('picker');
picker.tokens = await (await fetch('/tokens.json')).json();
filter.addEventListener('input', (event) => {
picker.filterText = event.detail.value;
});
</script>

Selection mirrored in the URL — selectedPath is a reflected attribute, so setAttribute and property assignment stay in sync.

html
<hy-dtcg-tree id="router"></hy-dtcg-tree>

<script>
  const tree = document.getElementById('router');
  tree.tokens = await (await fetch('/tokens.json')).json();

  const fromHash = () => tree.setAttribute('selected-path', location.hash.slice(1));
  fromHash();
  window.addEventListener('hashchange', fromHash);

  tree.addEventListener('select', (event) => {
  if (location.hash.slice(1) !== event.detail.path) {
  location.hash = event.detail.path;
  }
  });
</script>

Overriding the clipboard default — the copy event is cancelable and fires before the internal clipboard write

javascript
tree.addEventListener('copy', (event) => {
  event.preventDefault();
  navigator.clipboard.writeText(`{${event.detail.path}}`);
});

Domain-specific key ordering — pass sortKeys to reorder children per parent path (type-scale shorthands, font-weight words, numeric z-index)

javascript
tree.sortKeys = (parentPath, keys) => {
  if (parentPath === 'spacing') {
    const order = ['xs', 'sm', 'md', 'lg', 'xl'];
    return [...keys].sort((a, b) => order.indexOf(a) - order.indexOf(b));
  }
  return keys;
};

Events

  • select - { path, token } — fires when the user clicks a tree item.
  • copy - { path } — cancelable; fires before the internal clipboard write. Call preventDefault() to suppress the default write and own it.
  • action - { path, action, isToken, token } — fires when the user picks an item from the per-row context menu (when rowActions is set).

Slots

  • header - Forwarded to the inner hy-tree's header slot.
  • empty - Shown when the filter excludes every item.

Methods

expandAll()

Expose the internal tree's imperative methods for advanced use.

resetExpansion()

Clear all expansion state. Useful when the consumer knows the document content changed meaningfully without a reference-swap.

Built with Lit. Documented with VitePress.