Skip to content

TeemuKoivisto/svelte-tree-view

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Library to show Javascript objects in a nice tree layout. It's written in Svelte but since it compiles to pure JS it can be used anywhere (although to customize the rendered nodes you must Svelte).

npm i svelte-tree-view

How to use

The package should work without extra setup with both SvelteKit and Vite, see examples in packages/site and packages/vite-site. Previously, at least with Rollup, you had to add a mainFields property with values like ['svelte', 'module', 'browser', 'main'] to ensure it was imported as a Svelte component.

To use it:

import TreeView from 'svelte-tree-view' ... <TreeView data={selectedEntry.contentDiff} showLogButton showCopyButton valueComponent={DiffValue} recursionOpts={{ maxDepth: 16, mapChildren: mapDocDeltaChildren, shouldExpandNode: () => true }} />

Or if you are not using Svelte (NOTE: if you're using TS you must install svelte as a devDependency for the types):

import { TreeView } from 'svelte-tree-view' const treeView = new TreeView({ target: document.querySelector('#mount-point') as HTMLElement, props: { data: { a: [1, 2, 3], b: new Map([ ['c', { d: null }], ['e', { f: [9, 8, 7] }] ]) }, recursionOpts: { maxDepth: 4 } } })

To override default styles I suggest using child or element selector to get enough specificity:

<div class="wrapper"> <TreeView /> </div> <style lang="postcss">  .wrapper > :global(.svelte-tree-view) {  /* ... */  }  /* OR */  :global(ul.svelte-tree-view) {  /* ... */  } </style>

API

The full typings as copied from the source are:

export type ValueType = | 'array' | 'map' | 'set' | 'date' | 'object' | 'function' | 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'null' | 'undefined' export interface TreeNode<T = any> { id: string // ID generated from the path to this node eg "[0,1,2]" index: number // Index of this node in the parent object as its values are iterated key: string // Key of this node eg "1" for an array key or "foo" for an object value: T // The value mapped to this key depth: number collapsed: boolean type: ValueType path: number[] parentId: string | null // Circularity is checked by object identity to prevent recursing the same values again circularOfId: string | null children: TreeNode[] } export interface Base16Theme { scheme?: string author?: string base00: string // Default Background base01: string // Lighter Background (Used for status bars, line number and folding marks) base02: string // Selection Background base03: string // Comments, Invisibles, Line Highlighting base04: string // Dark Foreground (Used for status bars) base05: string // Default Foreground, Caret, Delimiters, Operators base06: string // Light Foreground (Not often used) base07: string // Light Background (Not often used) base08: string // Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted base09: string // Integers, Boolean, Constants, XML Attributes, Markup Link Url base0A: string // Classes, Markup Bold, Search Text Background base0B: string // Strings, Inherited Class, Markup Code, Diff Inserted base0C: string // Support, Regular Expressions, Escape Characters, Markup Quotes base0D: string // Functions, Methods, Attribute IDs, Headings base0E: string // Keywords, Storage, Selector, Markup Italic, Diff Changed base0F: string // Deprecated, Opening/Closing Embedded Language Tags, e.g. <?php ?> } // As described in https://stackoverflow.com/questions/67697298/svelte-components-as-object-properties/67737182#67737182 export type ValueComponent = new (...args: any) => SvelteComponentTyped<{ node: TreeNode defaultFormatter?: (val: any) => string | undefined }> export interface TreeViewProps { data: unknown // Data can be basically any non-primitive value class?: string // Top node has 'svelte-tree-view' class by default theme?: Base16Theme showLogButton?: boolean showCopyButton?: bool ean valueComponent?: ValueComponent // The Svelte component to replace the default value-as-string presentation recursionOpts?: TreeRecursionOpts // For custom formatting of the value string. Returning undefined will pass the value to the default formatter valueFormatter?: (val: any, n: TreeNode) => string | undefined } export interface TreeRecursionOpts { maxDepth?: number // The default maxDepth is 16 // Quick and dirty way to prevent recursing certain object keys instead of overriding shouldExpandNode omitKeys?: string[] stopCircularRecursion?: boolean // Stops recursing objects already recursed isCircularNode?: (n: TreeNode, iteratedValues: Map<any, TreeNode>) => boolean // For custom circularity detection magic shouldExpandNode?: (n: TreeNode) => boolean // Will auto-expand or collapse values as data is provided mapChildren?: (val: any, type: ValueType, parent: TreeNode) => [string, any][] | undefined // For customizing the created key-value pairs } export class TreeView extends SvelteComponentTyped<TreeViewProps> {} export default TreeView

Theming

This library uses base16 theming, similar to react-json-tree. So basically instead of theming each type (string, number, undefined etc) separately, you use the same color for all similar values. Here's a repo that might explain it better https://github.com/chriskempson/base16

The example theme is the monokai theme from react-json-tree with changed background color. You can define your own theme or use one from for example here https://github.com/reduxjs/redux-devtools/tree/75322b15ee7ba03fddf10ac3399881e302848874/src/react/themes

To use a theme, you can either provide an object or set CSS variables (recommended).

So either

const theme = { scheme: 'google', author: 'seth wright (http://sethawright.com)', base00: '#1d1f21', base01: '#282a2e', base02: '#373b41', base03: '#969896', base04: '#b4b7b4', base05: '#c5c8c6', base06: '#e0e0e0', base07: '#ffffff', base08: '#CC342B', base09: '#F96A38', base0A: '#FBA922', base0B: '#198844', base0C: '#3971ED', base0D: '#3971ED', base0E: '#A36AC7', base0F: '#3971ED' } <div class="wrapper"> <TreeView theme={theme} /> </div>

or

/* This is the example monokai theme */ .wrapper { --tree-view-base00: #363755; --tree-view-base01: #604d49; --tree-view-base02: #6d5a55; --tree-view-base03: #d1929b; --tree-view-base04: #b79f8d; --tree-view-base05: #f9f8f2; --tree-view-base06: #f7f4f1; --tree-view-base07: #faf8f5; --tree-view-base08: #fa3e7e; --tree-view-base09: #fd993c; --tree-view-base0A: #f6bf81; --tree-view-base0B: #b8e248; --tree-view-base0C: #b4efe4; --tree-view-base0D: #85d9ef; --tree-view-base0E: #be87ff; --tree-view-base0F: #d6724c; }

works.

Other

A little explanation on the internal logic.

Caveats

Rendering very large trees is not fast. The same happens with say react-json-tree but I assume that by using some clever hacks you could make it faster. Like VSCode fast. In general, it seems the use of recursive components is non-optimal regardless of the framework.

How to develop locally

You must have pnpm installed globally.

  1. pnpm
  2. pnpm start

This should start the SvelteKit app at http://localhost:5185 that hot-reloads changes to the library.

Similar libraries

While this library was basically written from scratch, its UI and API borrows from some existing libraries.

Contributing

PRs & issues are welcome!

About

Svelte component to view and explore JavaScript objects in a tree layout.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •