UNPKG

nxt-json-view

Version:
229 lines (221 loc) 16.5 kB
import * as i0 from '@angular/core'; import { Injectable, input, model, signal, effect, computed, inject, ViewEncapsulation, Component, linkedSignal, NgModule } from '@angular/core'; class ExpanderService { constructor() { this.items = new Set(); } addItem(item) { this.items.add(item); } removeItem(item) { this.items.delete(item); } expandTo(level) { this.items.forEach(i => { if (i.level() <= level && !i.isOpen()) { i.levelOpen.set(level); i.toggle(); } }); } collapseTo(level) { this.items.forEach(i => { if (i.level() > level && i.isOpen()) i.toggle(); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ExpanderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ExpanderService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ExpanderService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }] }); /** @internal */ function isObject(value) { return value !== null && typeof value === 'object'; } /** @internal */ function isArray(value) { return Array.isArray(value); } /** @internal */ function isUndefined(value) { return typeof value === 'undefined'; } /** @internal */ function isString(value) { return typeof value === 'string'; } /** @internal */ function isNumber(value) { return typeof value === 'number'; } /** @internal */ function isBoolean(value) { return typeof value === 'boolean'; } /** @internal */ class JsonViewItemComponent { constructor() { this.data = input(...(ngDevMode ? [undefined, { debugName: "data" }] : [])); this.key = input(...(ngDevMode ? [undefined, { debugName: "key" }] : [])); this.level = input(0, ...(ngDevMode ? [{ debugName: "level" }] : [])); this.levelOpen = model(...(ngDevMode ? [undefined, { debugName: "levelOpen" }] : [])); this.levelLabels = input(...(ngDevMode ? [undefined, { debugName: "levelLabels" }] : [])); this.isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : [])); this.effectRef = effect(() => { const levelOpen = this.levelOpen(); this.isOpen.set(!isUndefined(levelOpen) && (this.level() <= levelOpen)); this.effectRef.destroy(); }, { ...(ngDevMode ? { debugName: "effectRef" } : {}), manualCleanup: true }); this.childrenKeys = computed(() => { const data = this.data(); if (isObject(data)) { return Object.keys(data); } return []; }, ...(ngDevMode ? [{ debugName: "childrenKeys" }] : [])); this.hasChildren = computed(() => !!(this.childrenKeys().length), ...(ngDevMode ? [{ debugName: "hasChildren" }] : [])); this._levelLabels = computed(() => { const levelLabels = this.levelLabels(); return levelLabels?.[this.level()] || {}; }, ...(ngDevMode ? [{ debugName: "_levelLabels" }] : [])); this.dataType = computed(() => { let dataType; const data = this.data(); if (isObject(data)) { dataType = 'Object'; if (isArray(data)) { dataType = 'Array'; } const key = this.key(); if (key && this._levelLabels()[key]) { dataType = this._levelLabels()[key]; } } return dataType; }, ...(ngDevMode ? [{ debugName: "dataType" }] : [])); this.value = computed(() => { let value; const data = this.data(); if (!isObject(data)) { value = data; if (null === data) { value = 'null'; } } return value; }, ...(ngDevMode ? [{ debugName: "value" }] : [])); this.valueType = computed(() => { const data = this.data(); if (!isObject(data)) { if (isString(data)) { return 'string'; } else if (isNumber(data)) { return 'number'; } else if (isBoolean(data)) { return 'boolean'; } else if (null === data) { return 'null'; } } return; }, ...(ngDevMode ? [{ debugName: "valueType" }] : [])); this.isObject = computed(() => isObject(this.data()), ...(ngDevMode ? [{ debugName: "isObject" }] : [])); this.isArray = computed(() => isObject(this.data()) && isArray(this.data()), ...(ngDevMode ? [{ debugName: "isArray" }] : [])); this.expanderService = inject(ExpanderService); } ngOnInit() { this.expanderService.addItem(this); } ngOnDestroy() { this.expanderService.removeItem(this); } toggle() { if (!(this.childrenKeys().length)) { return; } this.isOpen.set(!this.isOpen()); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: JsonViewItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: JsonViewItemComponent, isStandalone: true, selector: "nxt-json-view-item", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, key: { classPropertyName: "key", publicName: "key", isSignal: true, isRequired: false, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, levelOpen: { classPropertyName: "levelOpen", publicName: "levelOpen", isSignal: true, isRequired: false, transformFunction: null }, levelLabels: { classPropertyName: "levelLabels", publicName: "levelLabels", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { levelOpen: "levelOpenChange" }, ngImport: i0, template: "<div class=\"json-view\">\r\n <a (click)=\"toggle()\"\r\n tabindex=\"0\"\r\n (keydown.space)=\"toggle()\">\r\n <span class=\"toggler\"\r\n [class]=\"{'collapse': isOpen(), 'expand': !isOpen()}\"\r\n [style.visibility]=\"hasChildren()?'visible':'hidden'\"></span>\r\n @if (key()) {\r\n <span class=\"key\">\r\n <span>{{key()}}</span>\r\n <span>: </span>\r\n </span>\r\n }\r\n <span class=\"value\">\r\n @if (isObject()) {\r\n <span>\r\n {{ dataType() }}\r\n @if (isArray()) {\r\n <span>[ {{ $any(data())?.length }} ]</span>\r\n }\r\n </span>\r\n }\r\n @if (!isObject() && valueType()) {\r\n <span [class]=\"valueType()\">{{ value() }}</span>\r\n }\r\n </span>\r\n </a>\r\n @if (hasChildren() && isOpen()) {\r\n <div class=\"children\">\r\n @for (_key of childrenKeys(); track _key) {\r\n <nxt-json-view-item [data]=\"data()[_key]\"\r\n [key]=\"_key\"\r\n [level]=\"level()+1\"\r\n [levelOpen]=\"levelOpen()\"\r\n [levelLabels]=\"levelLabels()\" />\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [".json-view a{cursor:pointer;text-decoration:none}.json-view .toggler{width:1em;padding:0;display:block;text-align:center;float:left}.json-view .collapse:before{content:\"-\"}.json-view .expand:before{content:\"+\"}.json-view .key{color:var(--nxt-json-view-color-key, #92278f)}.json-view .value{color:var(--nxt-json-view-color-value, #000000)}.json-view .value .string{color:var(--nxt-json-view-color-string, #3ab54a)}.json-view .value .number{color:var(--nxt-json-view-color-number, #25aae2)}.json-view .value .boolean{color:var(--nxt-json-view-color-boolean, #aa0d91)}.json-view .value .null{color:var(--nxt-json-view-color-null, #f1592a)}.json-view .children{margin-left:1em}\n"], dependencies: [{ kind: "component", type: JsonViewItemComponent, selector: "nxt-json-view-item", inputs: ["data", "key", "level", "levelOpen", "levelLabels"], outputs: ["levelOpenChange"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: JsonViewItemComponent, decorators: [{ type: Component, args: [{ selector: 'nxt-json-view-item', encapsulation: ViewEncapsulation.Emulated, template: "<div class=\"json-view\">\r\n <a (click)=\"toggle()\"\r\n tabindex=\"0\"\r\n (keydown.space)=\"toggle()\">\r\n <span class=\"toggler\"\r\n [class]=\"{'collapse': isOpen(), 'expand': !isOpen()}\"\r\n [style.visibility]=\"hasChildren()?'visible':'hidden'\"></span>\r\n @if (key()) {\r\n <span class=\"key\">\r\n <span>{{key()}}</span>\r\n <span>: </span>\r\n </span>\r\n }\r\n <span class=\"value\">\r\n @if (isObject()) {\r\n <span>\r\n {{ dataType() }}\r\n @if (isArray()) {\r\n <span>[ {{ $any(data())?.length }} ]</span>\r\n }\r\n </span>\r\n }\r\n @if (!isObject() && valueType()) {\r\n <span [class]=\"valueType()\">{{ value() }}</span>\r\n }\r\n </span>\r\n </a>\r\n @if (hasChildren() && isOpen()) {\r\n <div class=\"children\">\r\n @for (_key of childrenKeys(); track _key) {\r\n <nxt-json-view-item [data]=\"data()[_key]\"\r\n [key]=\"_key\"\r\n [level]=\"level()+1\"\r\n [levelOpen]=\"levelOpen()\"\r\n [levelLabels]=\"levelLabels()\" />\r\n }\r\n </div>\r\n }\r\n</div>\r\n", styles: [".json-view a{cursor:pointer;text-decoration:none}.json-view .toggler{width:1em;padding:0;display:block;text-align:center;float:left}.json-view .collapse:before{content:\"-\"}.json-view .expand:before{content:\"+\"}.json-view .key{color:var(--nxt-json-view-color-key, #92278f)}.json-view .value{color:var(--nxt-json-view-color-value, #000000)}.json-view .value .string{color:var(--nxt-json-view-color-string, #3ab54a)}.json-view .value .number{color:var(--nxt-json-view-color-number, #25aae2)}.json-view .value .boolean{color:var(--nxt-json-view-color-boolean, #aa0d91)}.json-view .value .null{color:var(--nxt-json-view-color-null, #f1592a)}.json-view .children{margin-left:1em}\n"] }] }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], key: [{ type: i0.Input, args: [{ isSignal: true, alias: "key", required: false }] }], level: [{ type: i0.Input, args: [{ isSignal: true, alias: "level", required: false }] }], levelOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "levelOpen", required: false }] }, { type: i0.Output, args: ["levelOpenChange"] }], levelLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "levelLabels", required: false }] }] } }); class JsonViewComponent { constructor() { /** JSON data, any valid JSON object */ this.data = input(...(ngDevMode ? [undefined, { debugName: "data" }] : [])); /** Initial number of levels to be expanded; to expand / collapse the view after initial render, use `expandTo` / `collapseTo` */ this.levelOpen = input(...(ngDevMode ? [undefined, { debugName: "levelOpen" }] : [])); /** Custom labels for elements within the hierarcy */ this.levelLabels = input(...(ngDevMode ? [undefined, { debugName: "levelLabels" }] : [])); /** @internal */ this._levelOpen = linkedSignal({ ...(ngDevMode ? { debugName: "_levelOpen" } : {}), source: () => this.levelOpen(), computation: level => level }); this.expanderService = inject(ExpanderService); } ngAfterViewChecked() { if (this._levelOpen() != undefined) { // Reset levelOpen to keep nested items collapsed when toggling this._levelOpen.set(undefined); } } /** Expand all items up to the given level */ expandTo(level) { this._levelOpen.set(level); this.expanderService.expandTo(level); } /** Collapse any open items above the given level */ collapseTo(level) { this.expanderService.collapseTo(level); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: JsonViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.0", type: JsonViewComponent, isStandalone: true, selector: "nxt-json-view", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, levelOpen: { classPropertyName: "levelOpen", publicName: "levelOpen", isSignal: true, isRequired: false, transformFunction: null }, levelLabels: { classPropertyName: "levelLabels", publicName: "levelLabels", isSignal: true, isRequired: false, transformFunction: null } }, providers: [ { provide: ExpanderService, useClass: ExpanderService } ], ngImport: i0, template: "<div class=\"nxt-json-view\">\r\n <nxt-json-view-item [data]=\"data()\"\r\n [level]=\"0\"\r\n [levelOpen]=\"_levelOpen()\"\r\n [levelLabels]=\"levelLabels()\"\r\n class=\"json-view\" />\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "component", type: JsonViewItemComponent, selector: "nxt-json-view-item", inputs: ["data", "key", "level", "levelOpen", "levelLabels"], outputs: ["levelOpenChange"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: JsonViewComponent, decorators: [{ type: Component, args: [{ selector: 'nxt-json-view', encapsulation: ViewEncapsulation.Emulated, providers: [ { provide: ExpanderService, useClass: ExpanderService } ], imports: [ JsonViewItemComponent ], template: "<div class=\"nxt-json-view\">\r\n <nxt-json-view-item [data]=\"data()\"\r\n [level]=\"0\"\r\n [levelOpen]=\"_levelOpen()\"\r\n [levelLabels]=\"levelLabels()\"\r\n class=\"json-view\" />\r\n</div>\r\n" }] }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], levelOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "levelOpen", required: false }] }], levelLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "levelLabels", required: false }] }] } }); /** @deprecated use standalone imports */ class JsonViewModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: JsonViewModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.0", ngImport: i0, type: JsonViewModule, imports: [JsonViewComponent], exports: [JsonViewComponent] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: JsonViewModule }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: JsonViewModule, decorators: [{ type: NgModule, args: [{ imports: [ JsonViewComponent ], exports: [ JsonViewComponent ] }] }] }); /** * Generated bundle index. Do not edit. */ export { JsonViewComponent, JsonViewModule }; //# sourceMappingURL=nxt-json-view.mjs.map