ngx-json-treeview
Version:
A simple Angular component to display object data in an expandable JSON tree view.
1 lines • 25.3 kB
Source Map (JSON)
{"version":3,"file":"ngx-json-treeview.mjs","sources":["../../../projects/ngx-json-treeview/src/lib/util.ts","../../../projects/ngx-json-treeview/src/lib/ngx-json-treeview.component.ts","../../../projects/ngx-json-treeview/src/lib/ngx-json-treeview.component.html","../../../projects/ngx-json-treeview/src/public-api.ts","../../../projects/ngx-json-treeview/src/ngx-json-treeview.ts"],"sourcesContent":["/**\n * Generates a preview string representation of an object.\n *\n * @param obj The object to preview.\n * @param limit The maximum length of the preview string. Defaults to 200.\n * @param stringsLimit The maximum length of a string to display before\n * truncating. Defaults to 10.\n * @returns A preview string representation of the object.\n */\nexport function previewString(obj: any, limit = 200, stringsLimit = 10) {\n let result = '';\n\n if (obj === null) {\n result += 'null';\n } else if (obj === undefined) {\n result += 'undefined';\n } else if (typeof obj === 'string') {\n if (obj.length > stringsLimit) {\n result += `\"${obj.substring(0, stringsLimit)}…\"`;\n } else {\n result += `\"${obj}\"`;\n }\n } else if (typeof obj === 'boolean') {\n result += `${obj ? 'true' : 'false'}`;\n } else if (typeof obj === 'number') {\n result += `${obj}`;\n } else if (typeof obj === 'object') {\n if (obj instanceof Date) {\n result += `\"${obj.toISOString()}\"`;\n } else if (Array.isArray(obj)) {\n result += `Array[${obj.length}] [`;\n for (const key in obj) {\n if (result.length >= limit) {\n break;\n }\n result += previewString(obj[key], limit - result.length);\n result += ',';\n }\n if (result.endsWith(',')) {\n result = result.slice(0, -1);\n }\n result += ']';\n } else {\n result += 'Object {';\n for (const key in obj) {\n if (result.length >= limit) {\n break;\n }\n if (obj[key] !== undefined) {\n result += `\"${key}\":`;\n result += previewString(obj[key], limit - result.length);\n result += ',';\n }\n }\n if (result.endsWith(',')) {\n result = result.slice(0, -1);\n }\n result += '}';\n }\n } else if (typeof obj === 'function') {\n result += 'Function';\n }\n\n if (result.length >= limit) {\n return result.substring(0, limit) + '…';\n }\n\n return result;\n}\n\n/**\n * Decycles a JavaScript object by replacing circular references with `$ref`\n * properties. This is useful for serializing objects that contain circular\n * references, preventing infinite loops.\n *\n * Original: https://github.com/douglascrockford/JSON-js/blob/master/cycle.js\n *\n * @param object The object to decycle.\n * @returns A decycled version of the object.\n */\nexport function decycle(object: any): any {\n const objects = new WeakMap();\n return (function derez(value, path) {\n let old_path;\n let nu: any;\n\n if (\n typeof value === 'object' &&\n value !== null &&\n !(value instanceof Boolean) &&\n !(value instanceof Date) &&\n !(value instanceof Number) &&\n !(value instanceof RegExp) &&\n !(value instanceof String)\n ) {\n old_path = objects.get(value);\n if (old_path !== undefined) {\n return { $ref: old_path };\n }\n objects.set(value, path);\n\n if (Array.isArray(value)) {\n nu = [];\n value.forEach(function (element, i) {\n nu[i] = derez(element, path + '[' + i + ']');\n });\n } else {\n nu = {};\n Object.keys(value).forEach(function (name) {\n nu[name] = derez(\n value[name],\n path + '[' + JSON.stringify(name) + ']'\n );\n });\n }\n return nu;\n }\n return value;\n })(object, '$');\n}\n","import { Component, computed, input, output } from '@angular/core';\nimport { decycle, previewString } from './util';\n\n/**\n * Represents a segment (node) within the JSON tree structure.\n * Each segment corresponds to a key-value pair in an object, an item in an\n * array, or the root value itself, providing context and state for rendering.\n */\nexport interface Segment {\n /** The key (for objects) or index (for arrays). */\n key: string;\n /** The actual JavaScript value represented by this segment. */\n value: any;\n /** The JavaScript data type of the value. */\n type?: string;\n /** A string representation of the value, used for display purposes. */\n description: string;\n /** Indicates whether the segment is expanded in the UI. */\n expanded: boolean;\n /** A reference to the parent segment in the JSON tree. Undefined for root. */\n parent?: Segment;\n /**\n * A dot/bracket notation path string to this specific segment\n * (e.g., 'settings.notifications.email', 'items[1].value').\n */\n path: string;\n}\n\nexport type IsClickableValueFn = (segment: Segment) => boolean;\n\n/**\n * Renders JSON data in an expandable and collapsible tree structure.\n * Allows users to navigate complex data hierarchies visually.\n */\n@Component({\n selector: 'ngx-json-treeview',\n imports: [],\n templateUrl: './ngx-json-treeview.component.html',\n styleUrls: ['./ngx-json-treeview.component.scss'],\n})\nexport class NgxJsonTreeviewComponent {\n /**\n * The JSON object or array to display in the tree view.\n * @required\n */\n json = input.required<any>();\n\n /**\n * Controls the default expansion state for all expandable segments\n * i.e. objects and arrays.\n * - If `true`, nodes are expanded down to the specified `depth`.\n * - If `false`, all nodes start collapsed.\n * @default true\n */\n expanded = input<boolean>(true);\n\n /**\n * Determines the maximum nesting level automatically expanded when `expanded`\n * is `true`.\n * - `-1`: Infinite depth (all levels expanded).\n * - `0`: Only the root node is expanded (if applicable).\n * - `n`: Root and nodes down to `n` levels are expanded.\n * @default -1\n */\n depth = input<number>(-1);\n\n /**\n * If `true`, value nodes will emit an `onValueClick` event when clicked. This\n * allows for some interesting use cases, such as:\n * - Rendering preformatted text, html, markdown, etc in another component.\n * - Copying a value to the clipboard.\n * - Following hyperlinks, etc\n * @default false\n */\n enableClickableValues = input<boolean>(false);\n\n /**\n * A function that determines if a specific value node should be considered\n * clickable. This provides more granular control than the global\n * `enableClickableValues` flag.\n *\n * The function receives the `Segment` object and should return `true` if the\n * value is clickable, `false` otherwise. This check is only performed if\n * `enableClickableValues` is also `true`.\n *\n * @param segment - The segment being evaluated.\n * @returns `true` if the segment's value should be clickable, `false`\n * otherwise.\n * @default () => true - By default, all values are considered clickable if\n * `enableClickableValues` is true.\n */\n isClickableValue = input<IsClickableValueFn>(() => true);\n\n /**\n * If `enableClickableValues` is set to `true`, emits a `Segment` object when\n * a value node is clicked. The emitted `Segment` contains details about the\n * clicked node (key, value, type, path, etc.).\n */\n onValueClick = output<Segment>();\n\n /**\n * *Internal* input representing the parent segment in the tree hierarchy.\n * Primrily used for calculating paths.\n * @internal\n */\n _parent = input<Segment>();\n\n /**\n * *Internal* input representing the current nesting depth. Used in\n * conjunction with the `depth` input to control expansion.\n * @internal\n */\n _currentDepth = input<number>(0);\n\n rootType = computed<string>(() => {\n if (this.json() === null) {\n return 'null';\n } else if (Array.isArray(this.json())) {\n return 'array';\n } else return typeof this.json();\n });\n segments = computed<Segment[]>(() => {\n const json = decycle(this.json());\n if (typeof json === 'object' && json != null) {\n return Object.keys(json).map((key) => this.parseKeyValue(key, json[key]));\n }\n return [];\n });\n isExpanded = computed<boolean>(\n () =>\n this.expanded() &&\n !(this.depth() > -1 && this._currentDepth() >= this.depth())\n );\n openingBrace = computed<string>(() => {\n if (this.rootType() === 'array') {\n return '[';\n } else return '{';\n });\n closingBrace = computed<string>(() => {\n if (this.rootType() === 'array') {\n return ']';\n } else return '}';\n });\n asString = computed<string>(() =>\n JSON.stringify(this.json(), null, 2).trim()\n );\n primativeSegmentClass = computed<string>(() => {\n const type = this.rootType();\n if (['object', 'array'].includes(type)) {\n return 'punctuation';\n }\n return 'segment-type-' + type;\n });\n isArrayElement = computed<boolean>(() => this.rootType() === 'array');\n\n isExpandable(segment: Segment) {\n return (\n (segment.type === 'object' && Object.keys(segment.value).length > 0) ||\n (segment.type === 'array' && segment.value.length > 0)\n );\n }\n\n isEmpty(segment: Segment) {\n return (\n (segment.type === 'object' && Object.keys(segment.value).length === 0) ||\n (segment.type === 'array' && segment.value.length === 0)\n );\n }\n\n isClickable(segment: Segment) {\n return this.enableClickableValues() && this.isClickableValue()(segment);\n }\n\n toggle(segment: Segment) {\n if (this.isExpandable(segment)) {\n segment.expanded = !segment.expanded;\n }\n }\n\n onValueClickHandler(segment: Segment) {\n if (this.isClickable(segment)) {\n this.onValueClick.emit(segment);\n console.debug(`onValueClick: ${segment.path}`);\n }\n }\n\n openingBraceForSegment(segment: Segment) {\n if (segment.type === 'array') {\n return '[';\n } else if (segment.type === 'object') {\n return '{';\n }\n\n return undefined;\n }\n\n closingBraceForSegment(segment: Segment) {\n if (segment.type === 'array') {\n return ']';\n } else if (segment.type === 'object') {\n return '}';\n }\n\n return undefined;\n }\n\n private getPath(key: string): string {\n const parent = this._parent();\n let path: string;\n\n if (parent) {\n if (parent.type === 'array') {\n path = `${parent.path}[${key}]`;\n } else {\n path = `${parent.path}.${key}`;\n }\n } else {\n path = key;\n }\n\n return path;\n }\n\n private parseKeyValue(key: any, value: any): Segment {\n const segment: Segment = {\n parent: this._parent(),\n path: this.getPath(key),\n key: key,\n value: value,\n type: undefined,\n description: '' + value,\n expanded: this.isExpanded(),\n };\n\n switch (typeof segment.value) {\n case 'number':\n segment.type = 'number';\n break;\n case 'boolean':\n segment.type = 'boolean';\n break;\n case 'function':\n segment.type = 'function';\n break;\n case 'string':\n segment.type = 'string';\n segment.description = JSON.stringify(segment.value);\n break;\n case 'undefined':\n segment.type = 'undefined';\n segment.description = 'undefined';\n break;\n case 'object':\n if (segment.value === null) {\n segment.type = 'null';\n segment.description = 'null';\n } else if (Array.isArray(segment.value)) {\n segment.type = 'array';\n segment.description = previewString(segment.value);\n } else if (segment.value instanceof Date) {\n segment.type = 'date';\n segment.description = `\"${segment.value.toISOString()}\"`;\n } else {\n segment.type = 'object';\n segment.description = previewString(segment.value);\n }\n break;\n default:\n console.error('Unknown type parsing json key/value.');\n }\n\n return segment;\n }\n}\n","<section class=\"ngx-json-treeview\">\n @if (segments().length === 0) {\n <div [class]=\"primativeSegmentClass()\">\n <span class=\"segment-primitive\">\n {{ asString() }}\n </span>\n </div>\n } @else {\n @if (_currentDepth() === 0) {\n <span class=\"punctuation\">{{ openingBrace() }}</span>\n }\n @for (\n segment of segments();\n track segment;\n let i = $index;\n let len = $count\n ) {\n @let needsComma = i < len - 1;\n @let expandable = isExpandable(segment);\n @let empty = isEmpty(segment);\n @let openingBrace = openingBraceForSegment(segment);\n @let closingBrace = closingBraceForSegment(segment);\n @let clickableValue = isClickable(segment);\n <div [class]=\"'segment segment-type-' + segment.type\">\n <div class=\"segment-main\">\n <span\n [tabindex]=\"expandable ? 0 : -1\"\n [class.expandable]=\"expandable\"\n [class.expanded]=\"segment.expanded\"\n (click)=\"toggle(segment)\"\n (keydown.enter)=\"toggle(segment)\">\n @if (expandable) {\n <div class=\"toggler\"></div>\n }\n @if (isArrayElement()) {\n <span class=\"segment-label\">{{ segment.key }}</span>\n } @else {\n <span class=\"segment-key\">{{ `\"${segment.key}\"` }}</span>\n }\n </span>\n <span\n [class.segment-label]=\"isArrayElement()\"\n [class.punctuation]=\"!isArrayElement()\"\n >:\n </span>\n @if (empty) {\n <span class=\"punctuation\"\n >{{ openingBrace }}{{ closingBrace\n }}{{ needsComma ? ',' : '' }}</span\n >\n } @else if (!expandable || !segment.expanded) {\n <span\n [tabindex]=\"clickableValue ? 0 : -1\"\n [class.segment-label]=\"expandable\"\n [class.segment-value]=\"!expandable\"\n [class.clickable]=\"clickableValue\"\n (click)=\"onValueClickHandler(segment)\"\n (keydown.enter)=\"onValueClickHandler(segment)\"\n >{{ segment.description }}</span\n >\n <span class=\"punctuation\">{{ needsComma ? ',' : '' }}</span>\n } @else {\n <span class=\"punctuation\">\n {{ openingBrace }}\n </span>\n }\n </div>\n @if (expandable && segment.expanded) {\n <div class=\"children\">\n <ngx-json-treeview\n [json]=\"segment.value\"\n [expanded]=\"expanded()\"\n [depth]=\"depth()\"\n [isClickableValue]=\"isClickableValue()\"\n [enableClickableValues]=\"enableClickableValues()\"\n [_parent]=\"segment\"\n [_currentDepth]=\"_currentDepth() + 1\"\n (onValueClick)=\"onValueClickHandler($event)\" />\n <span class=\"punctuation\">\n {{ closingBrace }}{{ needsComma ? ',' : '' }}\n </span>\n </div>\n }\n </div>\n }\n @if (_currentDepth() === 0) {\n <span class=\"punctuation\">{{ closingBrace() }}</span>\n }\n }\n</section>\n","/*\n * Public API Surface of ngx-json-treeview\n */\n\nexport * from './lib/ngx-json-treeview.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}