@components-1812/json-visualizer

0.0.2 • Public • Published

JSON Visualizer custom element

Examples


Installation

NPM

npm install @components-1812/json-visualizer

CDN

<script type="module">
    import JSONVisualizer from 'https://cdn.jsdelivr.net/npm/@components-1812/json-visualizer@0.0.2/src/JSONVisualizer.min.js';

    //Load the stylesheet
    JSONVisualizer.stylesSheets.links.push('https://cdn.jsdelivr.net/npm/@components-1812/json-visualizer@0.0.2/src/JSONVisualizer.min.css');

    console.log(JSONVisualizer);

    customElements.define('custom-json-visualizer', JSONVisualizer);
</script>

Usage

If you use Vite or a framework based on Vite such as Astro, you can import the component in a client-side script file:

import '@components-1812/json-visualizer';

and use it in your HTML:

<custom-svg-isolate>
    {
        "name": "John Doe",
        "age": null,
        "isStudent": false,
        "courses": ["Math", "Science"],
        "address": {
            "street": "123 Main St",
            "city": "Anytown"
        },
        "grades": [ 85, 92, 78 ],
        "contact": {
            "email": "john.doe@example.com",
            "phone": "123-456-7890"
        }
    }
</custom-svg-isolate>

<custom-json-visualizer json='{"name": "John Doe", "age": null}'></custom-json-visualizer>

<custom-json-visualizer src="https://jsonplaceholder.typicode.com/todos/1"></custom-json-visualizer>

Note:

If you are using a builder or framework that doesn't support import ?raw, you need to load the component and its stylesheets manually.

see Adding CSS stylesheets manually


Adding CSS stylesheets manually

If you want to add custom stylesheets to the component or need to load stylesheets from a different path, you can do it like this:

  • AdoptedStyleSheets (recommended)

    Using your builder’s import raw method, CSSStyleSheet, and the component’s AdoptedStyleSheets property:

    import JSONVisualizer from "@components-1812/json-visualizer/JSONVisualizer.js";
    import JSONVisualizerRawCSS from "@components-1812/json-visualizer/JSONVisualizer.css?raw";
    
    //Add the stylesheets to the component
    const JSONVisualizerCSS = new CSSStyleSheet();
    
    JSONVisualizerCSS.replaceSync(JSONVisualizerRawCSS);
    
    JSONVisualizer.stylesSheets.adopted.push(JSONVisualizerCSS);
    
    //Define the component
    import('@components-1812/json-visualizer/define');
  • Raw CSS in a <style> tag

    Using a <style> tag inside the shadow root of the component:

    import JSONVisualizer from "@components-1812/json-visualizer/JSONVisualizer.js";
    import JSONVisualizerRawCSS from "@components-1812/json-visualizer/JSONVisualizer.css?raw";
    
    //Add the stylesheets to the component
    JSONVisualizer.stylesSheets.raw.push(JSONVisualizerCSS);
    
    //Define the component
    import('@components-1812/json-visualizer/define');
  • External CSS files in a <link> tag

    Using a <link> tag inside the shadow root of the component:

    import JSONVisualizer from "@components-1812/json-visualizer/JSONVisualizer.js";
    import JSONVisualizerCSS from "@components-1812/json-visualizer/JSONVisualizer.css?url";
    
    //Add the stylesheets to the component
    JSONVisualizer.stylesSheets.links.push(JSONVisualizerCSS);
    
    //Define the component
    import('@components-1812/json-visualizer/define');

Note:

import('@components-1812/json-visualizer/define') calls customElements.define('custom-json-visualizer', JSONVisualizer); in define.js


Customization

CSS variables

--line-height: 1.25;
--line-elements-gap: 5px;
--line-white-space: normal;
--font: Consolas, "Courier New", monospace, sans-serif;

--line-number-padding: 5px;
--line-number-color: #777;
--line-number-background: transparent;
--line-number-text-align: right;
--line-number-width: fit-content;
--line-number-min-width: 2ch;/* Set by JS according to JSON line count */

--toggle-button-width: 15px;
--toggle-button-color: #777;
--toggle-button-hover-color: #fff;
--toggle-button-padding: 0;

--copy-button-width: 40px;
--copy-button-height: 40px;
--copy-button-color: #777;
--copy-button-hover-color: #fff;
--copy-button-padding: 10px;

--indentation-guides-lines-color: #444;
--indentation-guides-lines-width: 1px;
    
--json-tab-size: 4ch;

/* Theme Colors */
--json-background: #222;
--json-foreground: #eee;

--json-key: #9cdcfe;           
--json-string: #ce9178;        
--json-number: #b5cea8;        
--json-boolean: #569cd6;       
--json-null: #dcdcaa;  

--json-brace: #ffd700;         
--json-bracket: #ffd700;       
--json-comma: #d4d4d4;         
--json-colon: #d4d4d4; 

Themes

You can use one of the existing themes located in the assets/themes folder.

Example with Vite (or other bundlers):

import "@components-1812/json-visualizer/assets/themes/nord.css"

Example with CDN:

<link rel="stylesheet" href="https://unpkg.com/@components-1812/json-visualizer@0.0.2/assets/themes/dracula.css">

Then apply the theme by using the corresponding class name:

<custom-json-visualizer class="dracula"></custom-json-visualizer>
<custom-json-visualizer class="nord"></custom-json-visualizer>

Note:

All themes are based on the default <custom-json-visualizer> tag name.

If you register the custom element under a different name, you’ll need to adjust the theme’s CSS selectors accordingly.

Show all available themes in this example: Changing themes

Custom icons

If you want to add your own icons to the component, you can do it like this:

Use a <template> tag with the slot="icons" attribute, and assign a data-name to each icon using one of the following values: toggle, copy, or copy-done.

<custom-json-visualizer>
    {
        "name": "John Doe",
        "age": null,
        "isStudent": false,
        "courses": ["Math", "Science"],
    }
    <template slot="icons">
        <span data-name="toggle">🔽</span>
        <span data-name="copy">📋</span>
        <span data-name="copy-done"></span>
    </template>
</custom-json-visualizer>

Note:

You can retrieve icons using the getIcon(name) method.

To get a cloned copy of the icon instead of a reference, use getIcon(name, { clone: true }).

Custom tokenizer

The default tokenizer in JSONTokenizer.js has been tested a lot (see tests) and works well with any valid JSON input.

However, if you prefer to use your own tokenizer, you can override the default behavior via JSONVisualizer.getTokens:

import JSONVisualizer from "@components-1812/json-visualizer";

JSONVisualizer.getTokens = async (rawJson) => {

    return [];//[{type, value, tags}, ...]
}

Each token should follow this structure:

type Token = {
    type:'brace-open' | 'brace-close' | 'bracket-open' | 'bracket-close' | 'colon' | 'comma' | 'string' | 'number' | 'boolean' | 'null',
    value:string | boolean | number | null,
    tags:Array<'brace' | 'bracket' | 'colon' | 'comma' | 'string' | 'number' | 'boolean' | 'null' | 'open' | 'close' | 'key' | 'value' | 'array-value'>,
}

Note:

The type property is required for the JSON to render correctly.

The tags array is used for syntax highlighting.

Aqui puedes ver un ejemplo usando babel-standalone: custom tokenizer



Attributes

Reactive attributes

  • src: URL used to fetch a JSON file.

    If the src attribute is not set, the component will use either the json attribute or its textContent during initialization.

  • json: A raw JSON string to render directly.

Non reactive atributes

  • line-numbers: Controls whether line numbers are rendered. Set to "none" to hide them.

  • toggle-lines: Controls whether toggle buttons for collapsible sections are shown. Set to "none" to hide them.

  • indentation-guides-lines: Shows indentation guide lines. Set to "none" to hide them.

  • copy-button: Controls whether the copy button are rendered. Set to "none" to hide it.

  • render-deep default: Infinity: Limits the initial rendering depth for deeply nested JSON. Any non-numeric value is treated as Infinity.

    Deeper levels will only be rendered when expanded by the user.

Ready attributes

  • ready: Set when the component is fully initialized (at the end of connectedCallback()).

  • ready-links: Set when external stylesheets from JSONVisualizer.stylesSheets.links have finished loading.

  • ready-json: Set when the JSON has been successfully loaded and rendered.


Properties

Mirrors of Attributes

These properties reflect the corresponding HTML attributes:

  • json (reactive): A raw JSON string to render. Updating this will trigger a re-render.

  • src (reactive): A URL to fetch a JSON file. Updating this will also trigger a re-render.

  • lineNumbers: Controls whether line numbers are shown. Use "none" to hide them.

  • toggleLines: Controls whether toggle buttons are shown.

  • indentationGuidesLines: Controls the visibility of indentation guide lines.

  • copyButton: Controls the visibility of the copy button.

Other

  • data (readonly): Returns the parsed result of the current json value (JSON.parse(json)). If parsing fails, returns null.

Methods

  • async renderJSON(raw, options?)

    Clears the currently rendered JSON and renders the new one using the given options.

    raw can be a string or parsed object.

  • clearJSON()

    Clears the currently rendered JSON content.

  • async loadJSON(url, options?)

    Fetches a JSON file from the specified URL and renders it using the given options.

  • getIcon(name, { clone = false })

    Retrieves one of the internal icons used for the toggle or copy buttons.

    Valid name values: "toggle", "copy", "copy-done".

    Pass { clone: true } to get a cloned copy of the icon instead of a reference.

  • clearListeners()

    Removes all internal event listeners used by the component.

Events

  • ready: Fired when the component has finished initializing (at the end of connectedCallback()).

  • ready-links: Fired when the stylesheets defined in JSONVisualizer.stylesSheets.links are loaded.

    document.querySelector('custom-json-visualizer').addEventListener('ready-links', (e) => {
    
        const {results} = e.detail;
    
        console.log(results);//[{link:HTMLLinkElement, href:string, status:'loaded' | 'error'}, ...]
    });
  • ready-json: Fired when the JSON has been successfully loaded and rendered.

  • copy-done: Fired when the copy button is clicked and the JSON data has been copied to the clipboard.

    document.querySelector('custom-json-visualizer').addEventListener('copy-done', (e) => {
    
        const {data} = e.detail;
    });

JSONTokenizer

import JSONTokenizer from '@components-1812/json-visualizer/JSONTokenizer.js';

const tokenizer = new JSONTokenizer(); 

tokenizer.tokenize(rawJson);

console.log(tokenizer.tokens);//[{type, value, tags}, ...]

License

This package is distributed under the MIT license.

Credits

Default icons used in this package are sourced from the Bootstrap Icons project, licensed under the MIT license.
© 2019–2024 The Bootstrap Authors

Package Sidebar

Install

npm i @components-1812/json-visualizer

Weekly Downloads

162

Version

0.0.2

License

MIT

Unpacked Size

144 kB

Total Files

25

Last publish

Collaborators

  • _1812_