@tmdjr/ngx-editor-js2 20.0.6 → 20.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmdjr/ngx-editor-js2",
3
- "version": "20.0.6",
3
+ "version": "20.0.7",
4
4
  "schematics": "./schematics/collection.json",
5
5
  "peerDependencies": {
6
6
  "@angular/animations": "^20.0.4",
@@ -0,0 +1,66 @@
1
+ import { Component, inject } from '@angular/core';
2
+ import { AsyncPipe } from '@angular/common';
3
+ import { MatCard, MatCardContent } from '@angular/material/card';
4
+ import { NgxEditorJs2Component } from '@tmdjr/ngx-editor-js2';
5
+
6
+ import { NgxEditorJs2 } from '../services/ngx-editor-js2';
7
+
8
+ @Component({
9
+ selector: 'app-root',
10
+ imports: [
11
+ AsyncPipe,
12
+ MatCard,
13
+ MatCardContent,
14
+ NgxEditorJs2Component,
15
+ Hero,
16
+ ],
17
+ template: `
18
+ <main>
19
+ <app-hero></app-hero>
20
+ <mat-card appearance="outlined">
21
+ <mat-card-content>
22
+ <ngx-editor-js2
23
+ [blocks]="(ngxEditorJs2.ngxEditorJsBlocks$ | async)!"
24
+ [requestBlocks]="ngxEditorJs2.requestBlocks$ | async"
25
+ (blocksRequested)="ngxEditorJs2.handleBlocks($event)"
26
+ ></ngx-editor-js2>
27
+ </mat-card-content>
28
+ </mat-card>
29
+ </main>
30
+ `,
31
+ styles: [
32
+ `
33
+ @use '@angular/material' as mat;
34
+ :host {
35
+ @include mat.card-overrides(
36
+ (
37
+ outlined-outline-width: 0.5px,
38
+ outlined-container-color: var(--mat-sys-surface-container-low),
39
+ outlined-outline-color: var(--mat-sys-on-surface),
40
+ )
41
+ );
42
+
43
+ display: flex;
44
+ flex-direction: column;
45
+ min-height: 100vh;
46
+
47
+ main {
48
+ flex: 1;
49
+ display: flex;
50
+ flex-direction: column;
51
+ align-items: center;
52
+ gap: 3em;
53
+ margin-top: 56px;
54
+ mat-card {
55
+ width: 100%;
56
+ max-width: 800px;
57
+ margin-bottom: 3em;
58
+ }
59
+ }
60
+ }
61
+ `,
62
+ ],
63
+ })
64
+ export class AppComponent {
65
+ ngxEditorJs2 = inject(NgxEditorJs2);
66
+ }
@@ -0,0 +1,126 @@
1
+ import { Component, inject } from '@angular/core';
2
+ import { MatButton } from '@angular/material/button';
3
+ import { NgxEditorJs2, TEST_DATA, TEST_DATA_TWO } from '../services/ngx-editor-js2';
4
+ import { MatTooltip } from '@angular/material/tooltip';
5
+ import { of } from 'rxjs';
6
+
7
+ @Component({
8
+ selector: 'app-hero',
9
+ imports: [MatButton, MatTooltip],
10
+ template: `
11
+ <header class="header-background">
12
+ <div class="header-section">
13
+ <div class="header-headline">
14
+ <h1>Ngx EditorJs2</h1>
15
+ <h2>A Custom Themeable Angular Material 3 Component</h2>
16
+ </div>
17
+ <div class="header-start">
18
+ <button
19
+ mat-stroked-button
20
+ matTooltip="Simulate loading blocks"
21
+ (click)="loadValue()"
22
+ >
23
+ Load
24
+ </button>
25
+ <button
26
+ mat-stroked-button
27
+ matTooltip="Simulate clearing blocks"
28
+ (click)="clearValue()"
29
+ >
30
+ Clear
31
+ </button>
32
+ <button
33
+ mat-stroked-button
34
+ matTooltip="Open the console for blocks"
35
+ (click)="saveValue()"
36
+ >
37
+ Save
38
+ </button>
39
+ </div>
40
+ </div>
41
+ </header>
42
+ `,
43
+ styles: [
44
+ `
45
+ @use '@angular/material' as mat;
46
+
47
+ :host {
48
+ width: 100%;
49
+ @include mat.button-overrides(
50
+ (
51
+ outlined-label-text-color: var(--mat-sys-on-secondary),
52
+ )
53
+ );
54
+ .header-background {
55
+ overflow: hidden;
56
+ position: relative;
57
+ height: 360px;
58
+ color: var(--mat-sys-on-secondary);
59
+ background: var(--mat-sys-secondary);
60
+ &::before {
61
+ content: '';
62
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48" fill="%23FFFFFF"><path d="M14.5 40V13H4V8h26v5H19.5v27Zm18 0V23H26v-5h18v5h-6.5v17Z"/></svg>');
63
+ background-repeat: no-repeat;
64
+ background-size: 400px;
65
+ background-position: 80% -25px;
66
+ opacity: 0.2;
67
+ position: absolute;
68
+ top: 0;
69
+ bottom: 0;
70
+ left: 0;
71
+ right: 0;
72
+ }
73
+ }
74
+ .header-section {
75
+ display: flex;
76
+ justify-content: center;
77
+ flex-direction: column;
78
+ align-items: center;
79
+ height: 100%;
80
+ text-align: center;
81
+ .header-headline {
82
+ h1 {
83
+ font-size: 56px;
84
+ font-weight: bold;
85
+ line-height: 56px;
86
+ margin: 15px 5px;
87
+ }
88
+ h2 {
89
+ font-size: 20px;
90
+ font-weight: 300;
91
+ line-height: 28px;
92
+ margin: 15px 0 25px 0;
93
+ }
94
+ }
95
+ .header-start {
96
+ display: flex;
97
+ flex-direction: row;
98
+ gap: 10px;
99
+ button {
100
+ margin: 0 5px;
101
+ }
102
+ }
103
+ }
104
+ }
105
+ `,
106
+ ],
107
+ })
108
+ export class HeroComponent {
109
+ ngxEditorJs2 = inject(NgxEditorJs2);
110
+
111
+ saveValue() {
112
+ this.ngxEditorJs2.requestBlocks.next({});
113
+ }
114
+
115
+ switch = false;
116
+ loadValue() {
117
+ this.switch = !this.switch;
118
+ this.ngxEditorJs2.ngxEditorJsBlocks.next(
119
+ this.switch ? TEST_DATA : TEST_DATA_TWO
120
+ );
121
+ }
122
+
123
+ clearValue() {
124
+ this.ngxEditorJs2.ngxEditorJsBlocks.next([]);
125
+ }
126
+ }
@@ -0,0 +1,140 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { NgxEditorJsBlock } from '@tmdjr/ngx-editor-js2';
3
+ import { BehaviorSubject, lastValueFrom, Observable, tap } from 'rxjs';
4
+
5
+ export const TEST_DATA: NgxEditorJsBlock[] = [
6
+ {
7
+ blockId: 'n177d7',
8
+ sortIndex: 0,
9
+ componentInstanceName: 'NgxEditorJs2BlockquotesComponent',
10
+ savedAction: 'display-large',
11
+ dataClean:
12
+ '`Design is not just what it looks like and feels like. Design is how it works.',
13
+ },
14
+ {
15
+ blockId: 'n177dsd',
16
+ sortIndex: 1,
17
+ componentInstanceName: 'NgxEditorJs2ImageComponent',
18
+ savedAction: 'stretch',
19
+ dataClean:
20
+ '{"url":"https://res.cloudinary.com/dowdpiikk/image/upload/w_650,q_auto:best,f_auto/v1709445782/lnyst5aqppuin8wt73ci.webp","title":"test"}',
21
+ },
22
+ {
23
+ blockId: 'iovlbzgosf',
24
+ sortIndex: 2,
25
+ componentInstanceName: 'HeaderBlockComponent',
26
+ savedAction: 'h1',
27
+ dataClean: 'Prerequisites',
28
+ },
29
+ {
30
+ blockId: '8u3uiij5vyj',
31
+ sortIndex: 3,
32
+ componentInstanceName: 'ParagraphBlockComponent',
33
+ savedAction: 'large',
34
+ dataClean:
35
+ '<ul><li><a href="https://www.typescriptlang.org/">TypeScript</a> and HTML5 programming</li><li>Angular app-design fundamentals, as described in <a href="https://angular.io/guide/architecture">Angular Concepts</a><br></li><li>The basics of <a href="https://angular.io/guide/architecture-components#template-syntax">Angular template syntax</a><br></li></ul>',
36
+ },
37
+ {
38
+ blockId: 'bu23hwyltss',
39
+ sortIndex: 4,
40
+ componentInstanceName: 'ParagraphBlockComponent',
41
+ savedAction: 'large',
42
+ dataClean:
43
+ 'Evaluation of a template expression should have no visible side effects. Use the syntax for template expressions to help avoid side effects. In general, the correct syntax prevents you from assigning a value to anything in a property binding expression. The syntax also prevents you from using increment and decrement operators.',
44
+ },
45
+ {
46
+ blockId: 'uapf2',
47
+ sortIndex: 5,
48
+ componentInstanceName: 'NgxEditorJs2MermaidjsComponent',
49
+ savedAction: 'center',
50
+ dataClean:
51
+ 'flowchart TD\n A[Christmas] -->|Get money| B(Go shopping)\n B --> C{Let me think}\n C -->|One| D[Laptop]\n C -->|Two| E[Hello World iPhone]\n C -->|Three| F[fa:fa-car Car]',
52
+ },
53
+ {
54
+ blockId: 'bu23hwyltsww',
55
+ sortIndex: 6,
56
+ componentInstanceName: 'ParagraphBlockComponent',
57
+ savedAction: 'small',
58
+ dataClean:
59
+ 'Material Design uses color to create accessible, personal color schemes that communicate your products hierarchy, state, and brand. See Material Designs Color System page to learn more about its use and purpose.',
60
+ },
61
+ {
62
+ blockId: 'asdfasdf',
63
+ sortIndex: 7,
64
+ componentInstanceName: 'NgxEditorJs2CodemirrorComponent',
65
+ savedAction: 'text/typescript',
66
+ dataClean:
67
+ "export class SimpleFormGroup {\n form = new FormGroup({\n first: new FormControl('Nancy', Validators.minLength(2)),\n last: new FormControl('Drew'),\n });\n\n get first(): any {\n return this.form.get('first');\n }\n\n onSubmit(): void {\n console.log(this.form.value); // {first: 'Nancy', last: 'Drew'}\n }\n\n setValue() {\n this.form.setValue({first: 'Carson', last: 'Drew'});\n }\n}",
68
+ },
69
+ {
70
+ blockId: 'l13u3k',
71
+ sortIndex: 8,
72
+ componentInstanceName: 'HeaderBlockComponent',
73
+ savedAction: 'h1',
74
+ dataClean: 'New way of learning...',
75
+ },
76
+ {
77
+ blockId: '9bqhk',
78
+ sortIndex: 9,
79
+ componentInstanceName: 'NgxEditorJs2PopQuizComponent',
80
+ savedAction: 'display-large',
81
+ dataClean:
82
+ '{"question":"Which of the following statements is true about Angular\'s default RouteReuseStrategy?","answer":"It reuses components when the route configuration remains the same.","correctResponse":"That\'s correct! Angular\'s default RouteReuseStrategy reuses components when the route configuration remains the same. This prevents components from being destroyed and recreated when only the fragment or query parameters change.","incorrectResponse":"That\'s incorrect. The correct answer is C. Angular\'s default RouteReuseStrategy reuses components when the route configuration remains the same. This prevents components from being destroyed and recreated when only the fragment or query parameters change.","choices":[{"value":"It only reuses components when the route configuration changes."},{"value":"It only reuses components when the route parameters change."},{"value":"It reuses components when the route configuration remains the same."},{"value":"It never reuses components."}]}',
83
+ },
84
+ ];
85
+
86
+ export const TEST_DATA_TWO: NgxEditorJsBlock[] = [
87
+ {
88
+ blockId: 'iovlbzgosf',
89
+ sortIndex: 0,
90
+ componentInstanceName: 'HeaderBlockComponent',
91
+ dataClean: 'Different Prerequisites',
92
+ savedAction: 'h1',
93
+ },
94
+ {
95
+ blockId: 'bu23hwyltwl',
96
+ sortIndex: 1,
97
+ componentInstanceName: 'ParagraphBlockComponent',
98
+ dataClean:
99
+ 'Skips the very first call to startViewTransition. This can be useful for disabling the animation during the applications initial loading phase.',
100
+ savedAction: 'meduim',
101
+ },
102
+ {
103
+ blockId: 'bu23hwyltss',
104
+ sortIndex: 2,
105
+ componentInstanceName: 'ParagraphBlockComponent',
106
+ dataClean: 'SOmeehting Different then the last one',
107
+ savedAction: 'meduim',
108
+ },
109
+ {
110
+ blockId: 'iovlbzgosuu',
111
+ sortIndex: 3,
112
+ componentInstanceName: 'HeaderBlockComponent',
113
+ dataClean: 'Woah! This is cool..',
114
+ savedAction: 'h3',
115
+ },
116
+ {
117
+ blockId: 'bu23hwyltsww',
118
+ sortIndex: 2,
119
+ componentInstanceName: 'ParagraphBlockComponent',
120
+ dataClean:
121
+ 'Material Design uses color to create accessible, personal color schemes that communicate your products hierarchy, state, and brand. See Material Designs Color System page to learn more about its use and purpose.',
122
+ savedAction: 'small',
123
+ },
124
+ ];
125
+
126
+
127
+ @Injectable({
128
+ providedIn: 'root',
129
+ })
130
+ export class NgxEditorJs2 {
131
+ ngxEditorJsBlocks = new BehaviorSubject<NgxEditorJsBlock[]>(TEST_DATA);
132
+ ngxEditorJsBlocks$ = this.ngxEditorJsBlocks.asObservable();
133
+
134
+ requestBlocks = new BehaviorSubject<{}>({});
135
+ requestBlocks$ = this.requestBlocks.asObservable();
136
+
137
+ handleBlocks(blocks$: Observable<NgxEditorJsBlock[]>) {
138
+ void lastValueFrom(blocks$.pipe(tap(console.table)));
139
+ }
140
+ }
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.ngAdd = ngAdd;
13
+ const schematics_1 = require("@angular-devkit/schematics");
13
14
  const tasks_1 = require("@angular-devkit/schematics/tasks");
14
15
  const dependencies_1 = require("@schematics/angular/utility/dependencies");
15
16
  const optionalBlocks = {
@@ -88,6 +89,14 @@ function ngAdd(options) {
88
89
  updateStylesScss(tree, blocks, context, sourceRoot);
89
90
  updateAppConfig(tree, blocks, context, sourceRoot);
90
91
  addCodeMirrorSetup(tree, blocks, context, sourceRoot);
92
+ if (options.demo) {
93
+ // Add demo files
94
+ context.logger.info('✨ Adding demo AppComponent...');
95
+ (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)('./files/demo'), [
96
+ (0, schematics_1.applyTemplates)({}), // you can pass vars here if you want
97
+ (0, schematics_1.move)('src/app'), // adjust this path if needed
98
+ ]))(tree, context);
99
+ }
91
100
  context.logger.info('✅ Installation setup complete.');
92
101
  return tree;
93
102
  });
@@ -184,7 +193,7 @@ import 'codemirror/mode/xml/xml';
184
193
  @use "codemirror/theme/material-palenight";
185
194
  `;
186
195
  if (!stylesContent.includes('CODEMIRROR Dependencies')) {
187
- tree.overwrite(stylesPath, codeMirrorStyles + stylesContent); // pachinko
196
+ tree.overwrite(stylesPath, codeMirrorStyles + stylesContent);
188
197
  context.logger.info('CodeMirror styles added to styles.scss');
189
198
  }
190
199
  }
@@ -1,4 +1,4 @@
1
- import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
1
+ import { apply, applyTemplates, mergeWith, move, Rule, SchematicContext, Tree, url } from '@angular-devkit/schematics';
2
2
  import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
3
3
  import {
4
4
  addPackageJsonDependency,
@@ -94,8 +94,18 @@ export function ngAdd(options: any): Rule {
94
94
  updateAppConfig(tree, blocks, context, sourceRoot);
95
95
  addCodeMirrorSetup(tree, blocks, context, sourceRoot);
96
96
 
97
- context.logger.info('✅ Installation setup complete.');
97
+ if (options.demo) {
98
+ // Add demo files
99
+ context.logger.info('✨ Adding demo AppComponent...');
100
+ mergeWith(
101
+ apply(url('./files/demo'), [
102
+ applyTemplates({}), // you can pass vars here if you want
103
+ move('src/app'), // adjust this path if needed
104
+ ])
105
+ )(tree, context);
106
+ }
98
107
 
108
+ context.logger.info('✅ Installation setup complete.');
99
109
  return tree;
100
110
  };
101
111
  }
@@ -249,7 +259,7 @@ import 'codemirror/mode/xml/xml';
249
259
  `;
250
260
 
251
261
  if (!stylesContent.includes('CODEMIRROR Dependencies')) {
252
- tree.overwrite(stylesPath, codeMirrorStyles + stylesContent); // pachinko
262
+ tree.overwrite(stylesPath, codeMirrorStyles + stylesContent);
253
263
  context.logger.info('CodeMirror styles added to styles.scss');
254
264
  }
255
265
  } else {
@@ -25,6 +25,15 @@
25
25
  "type": "string",
26
26
  "description": "The Angular project to update",
27
27
  "x-prompt": "Which Angular project would you like to update?"
28
+ },
29
+ "demo": {
30
+ "type": "boolean",
31
+ "default": false,
32
+ "description": "Add component and service",
33
+ "x-prompt": {
34
+ "message": "Would you like to create demo of ng-editor-js2?",
35
+ "type": "confirm"
36
+ }
28
37
  }
29
38
  }
30
39
  }