ngx-lexical-editor 1.1.2 → 1.1.4

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.
@@ -15,6 +15,8 @@ class EditorService {
15
15
  editor;
16
16
  platformId = inject(PLATFORM_ID);
17
17
  editorState = signal(null, ...(ngDevMode ? [{ debugName: "editorState" }] : /* istanbul ignore next */ []));
18
+ json;
19
+ html;
18
20
  constructor() {
19
21
  const editorConfig = {
20
22
  namespace: 'NgxLexicalEditor',
@@ -60,15 +62,7 @@ class EditorService {
60
62
  },
61
63
  editable: true,
62
64
  };
63
- if (isPlatformBrowser(this.platformId)) {
64
- this.initEditor(editorConfig);
65
- }
66
- }
67
- /**
68
- * JSON Signal of the editor's content
69
- */
70
- get getJSON() {
71
- return computed(() => {
65
+ this.json = computed(() => {
72
66
  const state = this.editorState();
73
67
  return state
74
68
  ? state.toJSON()
@@ -82,13 +76,8 @@ class EditorService {
82
76
  version: 1,
83
77
  },
84
78
  };
85
- });
86
- }
87
- /**
88
- * Returns the editor's content as an HTML string. As a signal
89
- */
90
- get getHTML() {
91
- return computed(() => {
79
+ }, ...(ngDevMode ? [{ debugName: "json" }] : /* istanbul ignore next */ []));
80
+ this.html = computed(() => {
92
81
  const state = this.editorState();
93
82
  if (!state || !this.editor) {
94
83
  return '';
@@ -98,7 +87,10 @@ class EditorService {
98
87
  html = $generateHtmlFromNodes(this.editor);
99
88
  });
100
89
  return html;
101
- });
90
+ }, ...(ngDevMode ? [{ debugName: "html" }] : /* istanbul ignore next */ []));
91
+ if (isPlatformBrowser(this.platformId)) {
92
+ this.initEditor(editorConfig);
93
+ }
102
94
  }
103
95
  getEditorState() {
104
96
  return this.editorState.asReadonly();
@@ -106,7 +98,7 @@ class EditorService {
106
98
  getEditor() {
107
99
  return this.editor;
108
100
  }
109
- async initEditor(editorConfig) {
101
+ initEditor(editorConfig) {
110
102
  this.editor = createEditor(editorConfig);
111
103
  this.editor.registerUpdateListener(({ editorState }) => {
112
104
  this.editorState.set(editorState);
@@ -126,16 +118,8 @@ class LexicalEditorComponent {
126
118
  registerRichText(this.editor);
127
119
  }
128
120
  effect(() => {
129
- const json = this.editorService.getJSON();
130
- if (json) {
131
- this.jsonDataChanged.emit(json);
132
- }
133
- });
134
- effect(() => {
135
- const html = this.editorService.getHTML();
136
- if (html) {
137
- this.htmlContentChanged.emit(html);
138
- }
121
+ this.jsonDataChanged.emit(this.editorService.json());
122
+ this.htmlContentChanged.emit(this.editorService.html());
139
123
  });
140
124
  }
141
125
  ngAfterViewInit() {
@@ -183,11 +167,11 @@ class LexicalEditorComponent {
183
167
  });
184
168
  }
185
169
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: LexicalEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
186
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.13", type: LexicalEditorComponent, isStandalone: true, selector: "lexical-editor", outputs: { jsonDataChanged: "jsonDataChanged", htmlContentChanged: "htmlContentChanged" }, providers: [EditorService], viewQueries: [{ propertyName: "editorContent", first: true, predicate: ["editorContent"], descendants: true }], ngImport: i0, template: "<div class=\"container\">\n <div aria-label=\"Text Formatting Tools\" class=\"toolbar\" ngToolbar>\n\n <!-- Inline formats -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatText('bold')\" ngToolbarWidget type=\"button\" value=\"bold\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M266-192v-576h227.95q67.05 0 123.55 41.32Q674-685.35 674-612q0 51-22.5 79.5T609-490.96Q635-479 665-448t30 91q0 91-67.03 128t-125.81 37H266Zm127-118h104.68Q546-310 556-334.5t10-35.5q0-11-10.5-35.5T494-430H393v120Zm0-232h93q33 0 48.5-17.5T550-597q0-24-17.11-39t-44.28-15H393v109Z\" />\n </svg>\n </button>\n <button (click)=\"formatText('italic')\" ngToolbarWidget type=\"button\" value=\"italic\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M216-192v-96h160l124-384H336v-96h408v96H596L472-288h152v96H216Z\" />\n </svg>\n </button>\n <button (click)=\"formatText('underline')\" ngToolbarWidget type=\"button\" value=\"underline\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M240-144v-72h480v72H240Zm91.5-203.4Q279-406.8 279-504.86V-816h97.21v317.09q0 52.85 26.43 85.88Q429.07-380 480.03-380q50.97 0 77.39-33.03 26.41-33.03 26.41-85.88V-816H681v311.14q0 98.06-52.5 157.46Q576-288 480-288t-148.5-59.4Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Block formats -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatHeading('h1')\" ngToolbarWidget type=\"button\" value=\"h1\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M192-288v-384h72v156h168v-156h72v384h-72v-156H264v156h-72Zm504 0v-312h-96v-72h168v384h-72Z\" />\n </svg>\n </button>\n <button (click)=\"formatHeading('h2')\" ngToolbarWidget type=\"button\" value=\"h2\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M144-288v-384h72v156h168v-156h72v384h-72v-156H216v156h-72Zm384 0v-156q0-29.7 21.15-50.85Q570.3-516 600-516h144v-84H528v-72h216.26Q774-672 795-650.85q21 21.15 21 50.85v84q0 29.7-21.15 50.85Q773.7-444 744-444H600v84h216v72H528Z\" />\n </svg>\n </button>\n <button (click)=\"formatParagraph()\" ngToolbarWidget type=\"button\" value=\"p\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M384-192v-192q-79.68 0-135.84-56.23-56.16-56.22-56.16-136Q192-656 248.16-712q56.16-56 135.84-56h336v72h-96v504h-72v-504h-96v504h-72Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Lists -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatList('bullet')\" ngToolbarWidget type=\"button\" value=\"bullet\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M360-240v-72h456v72H360Zm0-204v-72h456v72H360Zm0-204v-72h456v72H360ZM215.79-204Q186-204 165-225.21t-21-51Q144-306 165.21-327t51-21Q246-348 267-326.79t21 51Q288-246 266.79-225t-51 21Zm0-204Q186-408 165-429.21t-21-51Q144-510 165.21-531t51-21Q246-552 267-530.79t21 51Q288-450 266.79-429t-51 21ZM165-633.21q-21-21.21-21-51T165.21-735q21.21-21 51-21T267-734.79q21 21.21 21 51T266.79-633q-21.21 21-51 21T165-633.21Z\" />\n </svg>\n </button>\n <button (click)=\"formatList('number')\" ngToolbarWidget type=\"button\" value=\"number\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M144-144v-48h96v-24h-48v-48h48v-24h-96v-48h120q10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v48q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9 10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v48q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9H144Zm0-240v-96q0-10.2 6.9-17.1 6.9-6.9 17.1-6.9h72v-24h-96v-48h120q10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v72q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9h-72v24h96v48H144Zm48-240v-144h-48v-48h96v192h-48Zm168 384v-72h456v72H360Zm0-204v-72h456v72H360Zm0-204v-72h456v72H360Z\" />\n </svg>\n </button>\n <button (click)=\"formatList('check')\" ngToolbarWidget type=\"button\" value=\"check\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M232-216 96-352l51-51 84 85 170-170 52 51-221 221Zm0-312L96-664l51-51 85 85 169-170 52 51-221 221Zm296 240v-72h336v72H528Zm0-312v-72h336v72H528Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Code Block -->\n <button (click)=\"formatCodeBlock()\" ngToolbarWidget type=\"button\" value=\"code\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M336-240 96-480l240-240 51 51-189 189 189 189-51 51Zm288 0-51-51 189-189-189-189 51-51 240 240-240 240Z\" />\n </svg>\n </button>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Table (Basic insertion) -->\n <button (click)=\"insertTable()\" ngToolbarWidget type=\"button\" value=\"table\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M216-144q-33 0-52.5-19.5T144-216v-528q0-33 19.5-52.5T216-816h528q33 0 52.5 19.5T816-744v528q0 33-19.5 52.5T744-144H216Zm228-228H216v156h228v-156Zm72 0v156h228v-156H516Zm-72-72v-156H216v156h228Zm72 0h228v-156H516v156ZM216-672h528v-72H216v72Z\" />\n </svg>\n </button>\n </div>\n <div class=\"lexical-editor-container\">\n <div #editorContent class=\"lexical-content-editable\" contenteditable=\"true\"></div>\n </div>\n</div>\n", styles: [":host{--primary-contrast: #333333;--quinary-contrast: #e0e0e0;--septenary-contrast: #f8f9fa;--hot-pink: #ff69b4}.container{height:100%;width:100%}.toolbar{overflow-x:auto}[ngToolbar]{margin:.5rem 1rem;gap:1.5rem;display:flex;padding:.5rem 1rem;border-radius:.5rem;background-color:var(--septenary-contrast)}.group{gap:.5rem;display:flex}.separator{width:1px;align-self:center;height:calc(100% - 1rem);background-color:var(--quinary-contrast)}[ngToolbarWidget]{border:none;cursor:pointer;padding:.5rem;border-radius:4px;display:flex;align-items:center;justify-content:center;background-color:transparent;color:var(--primary-contrast)}[ngToolbarWidget] svg{fill:currentColor}[ngToolbarWidget]:hover{background-color:color-mix(in srgb,var(--primary-contrast) 10%,transparent)}[ngToolbarWidget]:active{background-color:color-mix(in srgb,var(--primary-contrast) 15%,transparent)}[ngToolbarWidget]:focus{outline-offset:-1px;outline:1px solid color-mix(in srgb,var(--hot-pink) 60%,transparent)}[ngToolbarWidget][aria-pressed=true],[ngToolbarWidget][aria-checked=true]{color:color-mix(in srgb,var(--hot-pink) 80%,var(--primary-contrast));background-color:color-mix(in srgb,var(--hot-pink) 10%,transparent)}.divider{color:var(--quinary-contrast);align-self:center}.lexical-editor-container{position:relative;background-color:#fff}.lexical-content-editable{min-height:300px;padding:16px;outline:none}.lexical-paragraph{margin:0 0 10px}.lexical-bold{font-weight:700}.lexical-italic{font-style:italic}.lexical-underline{text-decoration:underline}.lexical-strikethrough{text-decoration:line-through}.lexical-inline-code{font-family:monospace;background-color:#f0f0f0;padding:2px 4px;border-radius:2px}.lexical-h1{font-size:2em;margin-top:20px;margin-bottom:10px}.lexical-h2{font-size:1.5em;margin-top:15px;margin-bottom:10px}.lexical-h3{font-size:1.17em;margin-top:10px;margin-bottom:10px}.lexical-ul{padding-left:30px;list-style-type:disc}.lexical-ol{padding-left:30px;list-style-type:decimal}.lexical-listitem{margin-bottom:4px}.lexical-code-block{background-color:#282c34;color:#abb2bf;font-family:Fira Code,monospace;display:block;padding:16px;line-height:1.5;font-size:14px;margin:10px 0;overflow-x:auto;border-radius:6px;tab-size:2}.lexical-table{border-collapse:collapse;border-spacing:0;max-width:100%;overflow-y:scroll;table-layout:fixed;width:100%;margin:10px 0}.lexical-table-row{border-bottom:1px solid #ddd}.lexical-table-cell{border:1px solid #ddd;padding:8px;vertical-align:top;text-align:left}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: Toolbar, selector: "[ngToolbar]", inputs: ["orientation", "softDisabled", "disabled", "wrap", "values"], outputs: ["valuesChange"], exportAs: ["ngToolbar"] }, { kind: "directive", type: ToolbarWidgetGroup, selector: "[ngToolbarWidgetGroup]", inputs: ["disabled", "multi"], exportAs: ["ngToolbarWidgetGroup"] }, { kind: "directive", type: ToolbarWidget, selector: "[ngToolbarWidget]", inputs: ["id", "disabled", "value"], exportAs: ["ngToolbarWidget"] }] });
170
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.13", type: LexicalEditorComponent, isStandalone: true, selector: "lexical-editor", outputs: { jsonDataChanged: "jsonDataChanged", htmlContentChanged: "htmlContentChanged" }, providers: [EditorService], viewQueries: [{ propertyName: "editorContent", first: true, predicate: ["editorContent"], descendants: true }], ngImport: i0, template: "<div class=\"container\">\n <div>\n <div aria-label=\"Text Formatting Tools\" class=\"toolbar\" ngToolbar>\n\n <!-- Inline formats -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatText('bold')\" ngToolbarWidget type=\"button\" value=\"bold\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M266-192v-576h227.95q67.05 0 123.55 41.32Q674-685.35 674-612q0 51-22.5 79.5T609-490.96Q635-479 665-448t30 91q0 91-67.03 128t-125.81 37H266Zm127-118h104.68Q546-310 556-334.5t10-35.5q0-11-10.5-35.5T494-430H393v120Zm0-232h93q33 0 48.5-17.5T550-597q0-24-17.11-39t-44.28-15H393v109Z\" />\n </svg>\n </button>\n <button (click)=\"formatText('italic')\" ngToolbarWidget type=\"button\" value=\"italic\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M216-192v-96h160l124-384H336v-96h408v96H596L472-288h152v96H216Z\" />\n </svg>\n </button>\n <button (click)=\"formatText('underline')\" ngToolbarWidget type=\"button\" value=\"underline\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M240-144v-72h480v72H240Zm91.5-203.4Q279-406.8 279-504.86V-816h97.21v317.09q0 52.85 26.43 85.88Q429.07-380 480.03-380q50.97 0 77.39-33.03 26.41-33.03 26.41-85.88V-816H681v311.14q0 98.06-52.5 157.46Q576-288 480-288t-148.5-59.4Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Block formats -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatHeading('h1')\" ngToolbarWidget type=\"button\" value=\"h1\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M192-288v-384h72v156h168v-156h72v384h-72v-156H264v156h-72Zm504 0v-312h-96v-72h168v384h-72Z\" />\n </svg>\n </button>\n <button (click)=\"formatHeading('h2')\" ngToolbarWidget type=\"button\" value=\"h2\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M144-288v-384h72v156h168v-156h72v384h-72v-156H216v156h-72Zm384 0v-156q0-29.7 21.15-50.85Q570.3-516 600-516h144v-84H528v-72h216.26Q774-672 795-650.85q21 21.15 21 50.85v84q0 29.7-21.15 50.85Q773.7-444 744-444H600v84h216v72H528Z\" />\n </svg>\n </button>\n <button (click)=\"formatParagraph()\" ngToolbarWidget type=\"button\" value=\"p\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M384-192v-192q-79.68 0-135.84-56.23-56.16-56.22-56.16-136Q192-656 248.16-712q56.16-56 135.84-56h336v72h-96v504h-72v-504h-96v504h-72Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Lists -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatList('bullet')\" ngToolbarWidget type=\"button\" value=\"bullet\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M360-240v-72h456v72H360Zm0-204v-72h456v72H360Zm0-204v-72h456v72H360ZM215.79-204Q186-204 165-225.21t-21-51Q144-306 165.21-327t51-21Q246-348 267-326.79t21 51Q288-246 266.79-225t-51 21Zm0-204Q186-408 165-429.21t-21-51Q144-510 165.21-531t51-21Q246-552 267-530.79t21 51Q288-450 266.79-429t-51 21ZM165-633.21q-21-21.21-21-51T165.21-735q21.21-21 51-21T267-734.79q21 21.21 21 51T266.79-633q-21.21 21-51 21T165-633.21Z\" />\n </svg>\n </button>\n <button (click)=\"formatList('number')\" ngToolbarWidget type=\"button\" value=\"number\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M144-144v-48h96v-24h-48v-48h48v-24h-96v-48h120q10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v48q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9 10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v48q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9H144Zm0-240v-96q0-10.2 6.9-17.1 6.9-6.9 17.1-6.9h72v-24h-96v-48h120q10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v72q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9h-72v24h96v48H144Zm48-240v-144h-48v-48h96v192h-48Zm168 384v-72h456v72H360Zm0-204v-72h456v72H360Zm0-204v-72h456v72H360Z\" />\n </svg>\n </button>\n <button (click)=\"formatList('check')\" ngToolbarWidget type=\"button\" value=\"check\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M232-216 96-352l51-51 84 85 170-170 52 51-221 221Zm0-312L96-664l51-51 85 85 169-170 52 51-221 221Zm296 240v-72h336v72H528Zm0-312v-72h336v72H528Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Code Block -->\n <button (click)=\"formatCodeBlock()\" ngToolbarWidget type=\"button\" value=\"code\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M336-240 96-480l240-240 51 51-189 189 189 189-51 51Zm288 0-51-51 189-189-189-189 51-51 240 240-240 240Z\" />\n </svg>\n </button>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Table (Basic insertion) -->\n <button (click)=\"insertTable()\" ngToolbarWidget type=\"button\" value=\"table\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M216-144q-33 0-52.5-19.5T144-216v-528q0-33 19.5-52.5T216-816h528q33 0 52.5 19.5T816-744v528q0 33-19.5 52.5T744-144H216Zm228-228H216v156h228v-156Zm72 0v156h228v-156H516Zm-72-72v-156H216v156h228Zm72 0h228v-156H516v156ZM216-672h528v-72H216v72Z\" />\n </svg>\n </button>\n </div>\n </div>\n <div class=\"lexical-editor-container\">\n <div #editorContent class=\"lexical-content-editable\" contenteditable=\"true\"></div>\n </div>\n</div>\n", styles: [":host{--primary-contrast: #333333;--grey-neutral: #aeaeae;--quinary-contrast: #e0e0e0;--septenary-contrast: #f8f9fa;--hot-pink: #ff69b4}.container{height:100%;width:100%;overflow:hidden}[ngToolbar]{scrollbar-color:transparent transparent;scrollbar-width:thin;--scrollbar-background: var(--quinary-contrast, var(--septenary-contrast));overflow-x:auto;margin:.5rem 1rem;gap:1.5rem;display:flex;padding:.5rem 1rem;border-radius:.5rem;background-color:var(--septenary-contrast)}[ngToolbar]:hover{scrollbar-color:var(--grey-neutral) transparent}.group{gap:.5rem;display:flex}.separator{width:1px;align-self:center;height:calc(100% - 1rem);background-color:var(--quinary-contrast)}[ngToolbarWidget]{border:none;cursor:pointer;padding:.5rem;border-radius:4px;display:flex;align-items:center;justify-content:center;background-color:transparent;color:var(--primary-contrast)}[ngToolbarWidget] svg{fill:currentColor}[ngToolbarWidget]:hover{background-color:color-mix(in srgb,var(--primary-contrast) 10%,transparent)}[ngToolbarWidget]:active{background-color:color-mix(in srgb,var(--primary-contrast) 15%,transparent)}[ngToolbarWidget]:focus{outline-offset:-1px;outline:1px solid color-mix(in srgb,var(--hot-pink) 60%,transparent)}[ngToolbarWidget][aria-pressed=true],[ngToolbarWidget][aria-checked=true]{color:color-mix(in srgb,var(--hot-pink) 80%,var(--primary-contrast));background-color:color-mix(in srgb,var(--hot-pink) 10%,transparent)}.divider{color:var(--quinary-contrast);align-self:center}.lexical-editor-container{position:relative;background-color:#fff;overflow-y:auto}.lexical-content-editable{min-height:450px;min-width:100%;padding:16px;outline:none;word-break:break-word;overflow-wrap:break-word}.lexical-paragraph{margin:0 0 10px}.lexical-bold{font-weight:700}.lexical-italic{font-style:italic}.lexical-underline{text-decoration:underline}.lexical-strikethrough{text-decoration:line-through}.lexical-inline-code{font-family:monospace;background-color:#f0f0f0;padding:2px 4px;border-radius:2px}.lexical-h1{font-size:2em;margin-top:20px;margin-bottom:10px}.lexical-h2{font-size:1.5em;margin-top:15px;margin-bottom:10px}.lexical-h3{font-size:1.17em;margin-top:10px;margin-bottom:10px}.lexical-ul{padding-left:30px;list-style-type:disc}.lexical-ol{padding-left:30px;list-style-type:decimal}.lexical-listitem{margin-bottom:4px}.lexical-code-block{background-color:#282c34;color:#abb2bf;font-family:Fira Code,monospace;display:block;padding:16px;line-height:1.5;font-size:14px;margin:10px 0;overflow-x:auto;border-radius:6px;tab-size:2}.lexical-table{border-collapse:collapse;border-spacing:0;max-width:100%;overflow-y:scroll;table-layout:fixed;width:100%;margin:10px 0}.lexical-table-row{border-bottom:1px solid #ddd}.lexical-table-cell{border:1px solid #ddd;padding:8px;vertical-align:top;text-align:left}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: Toolbar, selector: "[ngToolbar]", inputs: ["orientation", "softDisabled", "disabled", "wrap", "values"], outputs: ["valuesChange"], exportAs: ["ngToolbar"] }, { kind: "directive", type: ToolbarWidgetGroup, selector: "[ngToolbarWidgetGroup]", inputs: ["disabled", "multi"], exportAs: ["ngToolbarWidgetGroup"] }, { kind: "directive", type: ToolbarWidget, selector: "[ngToolbarWidget]", inputs: ["id", "disabled", "value"], exportAs: ["ngToolbarWidget"] }] });
187
171
  }
188
172
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: LexicalEditorComponent, decorators: [{
189
173
  type: Component,
190
- args: [{ selector: 'lexical-editor', standalone: true, imports: [CommonModule, Toolbar, ToolbarWidgetGroup, ToolbarWidget], providers: [EditorService], template: "<div class=\"container\">\n <div aria-label=\"Text Formatting Tools\" class=\"toolbar\" ngToolbar>\n\n <!-- Inline formats -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatText('bold')\" ngToolbarWidget type=\"button\" value=\"bold\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M266-192v-576h227.95q67.05 0 123.55 41.32Q674-685.35 674-612q0 51-22.5 79.5T609-490.96Q635-479 665-448t30 91q0 91-67.03 128t-125.81 37H266Zm127-118h104.68Q546-310 556-334.5t10-35.5q0-11-10.5-35.5T494-430H393v120Zm0-232h93q33 0 48.5-17.5T550-597q0-24-17.11-39t-44.28-15H393v109Z\" />\n </svg>\n </button>\n <button (click)=\"formatText('italic')\" ngToolbarWidget type=\"button\" value=\"italic\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M216-192v-96h160l124-384H336v-96h408v96H596L472-288h152v96H216Z\" />\n </svg>\n </button>\n <button (click)=\"formatText('underline')\" ngToolbarWidget type=\"button\" value=\"underline\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M240-144v-72h480v72H240Zm91.5-203.4Q279-406.8 279-504.86V-816h97.21v317.09q0 52.85 26.43 85.88Q429.07-380 480.03-380q50.97 0 77.39-33.03 26.41-33.03 26.41-85.88V-816H681v311.14q0 98.06-52.5 157.46Q576-288 480-288t-148.5-59.4Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Block formats -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatHeading('h1')\" ngToolbarWidget type=\"button\" value=\"h1\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M192-288v-384h72v156h168v-156h72v384h-72v-156H264v156h-72Zm504 0v-312h-96v-72h168v384h-72Z\" />\n </svg>\n </button>\n <button (click)=\"formatHeading('h2')\" ngToolbarWidget type=\"button\" value=\"h2\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M144-288v-384h72v156h168v-156h72v384h-72v-156H216v156h-72Zm384 0v-156q0-29.7 21.15-50.85Q570.3-516 600-516h144v-84H528v-72h216.26Q774-672 795-650.85q21 21.15 21 50.85v84q0 29.7-21.15 50.85Q773.7-444 744-444H600v84h216v72H528Z\" />\n </svg>\n </button>\n <button (click)=\"formatParagraph()\" ngToolbarWidget type=\"button\" value=\"p\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M384-192v-192q-79.68 0-135.84-56.23-56.16-56.22-56.16-136Q192-656 248.16-712q56.16-56 135.84-56h336v72h-96v504h-72v-504h-96v504h-72Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Lists -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatList('bullet')\" ngToolbarWidget type=\"button\" value=\"bullet\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M360-240v-72h456v72H360Zm0-204v-72h456v72H360Zm0-204v-72h456v72H360ZM215.79-204Q186-204 165-225.21t-21-51Q144-306 165.21-327t51-21Q246-348 267-326.79t21 51Q288-246 266.79-225t-51 21Zm0-204Q186-408 165-429.21t-21-51Q144-510 165.21-531t51-21Q246-552 267-530.79t21 51Q288-450 266.79-429t-51 21ZM165-633.21q-21-21.21-21-51T165.21-735q21.21-21 51-21T267-734.79q21 21.21 21 51T266.79-633q-21.21 21-51 21T165-633.21Z\" />\n </svg>\n </button>\n <button (click)=\"formatList('number')\" ngToolbarWidget type=\"button\" value=\"number\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M144-144v-48h96v-24h-48v-48h48v-24h-96v-48h120q10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v48q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9 10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v48q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9H144Zm0-240v-96q0-10.2 6.9-17.1 6.9-6.9 17.1-6.9h72v-24h-96v-48h120q10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v72q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9h-72v24h96v48H144Zm48-240v-144h-48v-48h96v192h-48Zm168 384v-72h456v72H360Zm0-204v-72h456v72H360Zm0-204v-72h456v72H360Z\" />\n </svg>\n </button>\n <button (click)=\"formatList('check')\" ngToolbarWidget type=\"button\" value=\"check\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M232-216 96-352l51-51 84 85 170-170 52 51-221 221Zm0-312L96-664l51-51 85 85 169-170 52 51-221 221Zm296 240v-72h336v72H528Zm0-312v-72h336v72H528Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Code Block -->\n <button (click)=\"formatCodeBlock()\" ngToolbarWidget type=\"button\" value=\"code\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M336-240 96-480l240-240 51 51-189 189 189 189-51 51Zm288 0-51-51 189-189-189-189 51-51 240 240-240 240Z\" />\n </svg>\n </button>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Table (Basic insertion) -->\n <button (click)=\"insertTable()\" ngToolbarWidget type=\"button\" value=\"table\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M216-144q-33 0-52.5-19.5T144-216v-528q0-33 19.5-52.5T216-816h528q33 0 52.5 19.5T816-744v528q0 33-19.5 52.5T744-144H216Zm228-228H216v156h228v-156Zm72 0v156h228v-156H516Zm-72-72v-156H216v156h228Zm72 0h228v-156H516v156ZM216-672h528v-72H216v72Z\" />\n </svg>\n </button>\n </div>\n <div class=\"lexical-editor-container\">\n <div #editorContent class=\"lexical-content-editable\" contenteditable=\"true\"></div>\n </div>\n</div>\n", styles: [":host{--primary-contrast: #333333;--quinary-contrast: #e0e0e0;--septenary-contrast: #f8f9fa;--hot-pink: #ff69b4}.container{height:100%;width:100%}.toolbar{overflow-x:auto}[ngToolbar]{margin:.5rem 1rem;gap:1.5rem;display:flex;padding:.5rem 1rem;border-radius:.5rem;background-color:var(--septenary-contrast)}.group{gap:.5rem;display:flex}.separator{width:1px;align-self:center;height:calc(100% - 1rem);background-color:var(--quinary-contrast)}[ngToolbarWidget]{border:none;cursor:pointer;padding:.5rem;border-radius:4px;display:flex;align-items:center;justify-content:center;background-color:transparent;color:var(--primary-contrast)}[ngToolbarWidget] svg{fill:currentColor}[ngToolbarWidget]:hover{background-color:color-mix(in srgb,var(--primary-contrast) 10%,transparent)}[ngToolbarWidget]:active{background-color:color-mix(in srgb,var(--primary-contrast) 15%,transparent)}[ngToolbarWidget]:focus{outline-offset:-1px;outline:1px solid color-mix(in srgb,var(--hot-pink) 60%,transparent)}[ngToolbarWidget][aria-pressed=true],[ngToolbarWidget][aria-checked=true]{color:color-mix(in srgb,var(--hot-pink) 80%,var(--primary-contrast));background-color:color-mix(in srgb,var(--hot-pink) 10%,transparent)}.divider{color:var(--quinary-contrast);align-self:center}.lexical-editor-container{position:relative;background-color:#fff}.lexical-content-editable{min-height:300px;padding:16px;outline:none}.lexical-paragraph{margin:0 0 10px}.lexical-bold{font-weight:700}.lexical-italic{font-style:italic}.lexical-underline{text-decoration:underline}.lexical-strikethrough{text-decoration:line-through}.lexical-inline-code{font-family:monospace;background-color:#f0f0f0;padding:2px 4px;border-radius:2px}.lexical-h1{font-size:2em;margin-top:20px;margin-bottom:10px}.lexical-h2{font-size:1.5em;margin-top:15px;margin-bottom:10px}.lexical-h3{font-size:1.17em;margin-top:10px;margin-bottom:10px}.lexical-ul{padding-left:30px;list-style-type:disc}.lexical-ol{padding-left:30px;list-style-type:decimal}.lexical-listitem{margin-bottom:4px}.lexical-code-block{background-color:#282c34;color:#abb2bf;font-family:Fira Code,monospace;display:block;padding:16px;line-height:1.5;font-size:14px;margin:10px 0;overflow-x:auto;border-radius:6px;tab-size:2}.lexical-table{border-collapse:collapse;border-spacing:0;max-width:100%;overflow-y:scroll;table-layout:fixed;width:100%;margin:10px 0}.lexical-table-row{border-bottom:1px solid #ddd}.lexical-table-cell{border:1px solid #ddd;padding:8px;vertical-align:top;text-align:left}\n"] }]
174
+ args: [{ selector: 'lexical-editor', standalone: true, imports: [CommonModule, Toolbar, ToolbarWidgetGroup, ToolbarWidget], providers: [EditorService], template: "<div class=\"container\">\n <div>\n <div aria-label=\"Text Formatting Tools\" class=\"toolbar\" ngToolbar>\n\n <!-- Inline formats -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatText('bold')\" ngToolbarWidget type=\"button\" value=\"bold\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M266-192v-576h227.95q67.05 0 123.55 41.32Q674-685.35 674-612q0 51-22.5 79.5T609-490.96Q635-479 665-448t30 91q0 91-67.03 128t-125.81 37H266Zm127-118h104.68Q546-310 556-334.5t10-35.5q0-11-10.5-35.5T494-430H393v120Zm0-232h93q33 0 48.5-17.5T550-597q0-24-17.11-39t-44.28-15H393v109Z\" />\n </svg>\n </button>\n <button (click)=\"formatText('italic')\" ngToolbarWidget type=\"button\" value=\"italic\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M216-192v-96h160l124-384H336v-96h408v96H596L472-288h152v96H216Z\" />\n </svg>\n </button>\n <button (click)=\"formatText('underline')\" ngToolbarWidget type=\"button\" value=\"underline\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M240-144v-72h480v72H240Zm91.5-203.4Q279-406.8 279-504.86V-816h97.21v317.09q0 52.85 26.43 85.88Q429.07-380 480.03-380q50.97 0 77.39-33.03 26.41-33.03 26.41-85.88V-816H681v311.14q0 98.06-52.5 157.46Q576-288 480-288t-148.5-59.4Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Block formats -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatHeading('h1')\" ngToolbarWidget type=\"button\" value=\"h1\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M192-288v-384h72v156h168v-156h72v384h-72v-156H264v156h-72Zm504 0v-312h-96v-72h168v384h-72Z\" />\n </svg>\n </button>\n <button (click)=\"formatHeading('h2')\" ngToolbarWidget type=\"button\" value=\"h2\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M144-288v-384h72v156h168v-156h72v384h-72v-156H216v156h-72Zm384 0v-156q0-29.7 21.15-50.85Q570.3-516 600-516h144v-84H528v-72h216.26Q774-672 795-650.85q21 21.15 21 50.85v84q0 29.7-21.15 50.85Q773.7-444 744-444H600v84h216v72H528Z\" />\n </svg>\n </button>\n <button (click)=\"formatParagraph()\" ngToolbarWidget type=\"button\" value=\"p\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M384-192v-192q-79.68 0-135.84-56.23-56.16-56.22-56.16-136Q192-656 248.16-712q56.16-56 135.84-56h336v72h-96v504h-72v-504h-96v504h-72Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Lists -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatList('bullet')\" ngToolbarWidget type=\"button\" value=\"bullet\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M360-240v-72h456v72H360Zm0-204v-72h456v72H360Zm0-204v-72h456v72H360ZM215.79-204Q186-204 165-225.21t-21-51Q144-306 165.21-327t51-21Q246-348 267-326.79t21 51Q288-246 266.79-225t-51 21Zm0-204Q186-408 165-429.21t-21-51Q144-510 165.21-531t51-21Q246-552 267-530.79t21 51Q288-450 266.79-429t-51 21ZM165-633.21q-21-21.21-21-51T165.21-735q21.21-21 51-21T267-734.79q21 21.21 21 51T266.79-633q-21.21 21-51 21T165-633.21Z\" />\n </svg>\n </button>\n <button (click)=\"formatList('number')\" ngToolbarWidget type=\"button\" value=\"number\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M144-144v-48h96v-24h-48v-48h48v-24h-96v-48h120q10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v48q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9 10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v48q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9H144Zm0-240v-96q0-10.2 6.9-17.1 6.9-6.9 17.1-6.9h72v-24h-96v-48h120q10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v72q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9h-72v24h96v48H144Zm48-240v-144h-48v-48h96v192h-48Zm168 384v-72h456v72H360Zm0-204v-72h456v72H360Zm0-204v-72h456v72H360Z\" />\n </svg>\n </button>\n <button (click)=\"formatList('check')\" ngToolbarWidget type=\"button\" value=\"check\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M232-216 96-352l51-51 84 85 170-170 52 51-221 221Zm0-312L96-664l51-51 85 85 169-170 52 51-221 221Zm296 240v-72h336v72H528Zm0-312v-72h336v72H528Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Code Block -->\n <button (click)=\"formatCodeBlock()\" ngToolbarWidget type=\"button\" value=\"code\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M336-240 96-480l240-240 51 51-189 189 189 189-51 51Zm288 0-51-51 189-189-189-189 51-51 240 240-240 240Z\" />\n </svg>\n </button>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Table (Basic insertion) -->\n <button (click)=\"insertTable()\" ngToolbarWidget type=\"button\" value=\"table\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M216-144q-33 0-52.5-19.5T144-216v-528q0-33 19.5-52.5T216-816h528q33 0 52.5 19.5T816-744v528q0 33-19.5 52.5T744-144H216Zm228-228H216v156h228v-156Zm72 0v156h228v-156H516Zm-72-72v-156H216v156h228Zm72 0h228v-156H516v156ZM216-672h528v-72H216v72Z\" />\n </svg>\n </button>\n </div>\n </div>\n <div class=\"lexical-editor-container\">\n <div #editorContent class=\"lexical-content-editable\" contenteditable=\"true\"></div>\n </div>\n</div>\n", styles: [":host{--primary-contrast: #333333;--grey-neutral: #aeaeae;--quinary-contrast: #e0e0e0;--septenary-contrast: #f8f9fa;--hot-pink: #ff69b4}.container{height:100%;width:100%;overflow:hidden}[ngToolbar]{scrollbar-color:transparent transparent;scrollbar-width:thin;--scrollbar-background: var(--quinary-contrast, var(--septenary-contrast));overflow-x:auto;margin:.5rem 1rem;gap:1.5rem;display:flex;padding:.5rem 1rem;border-radius:.5rem;background-color:var(--septenary-contrast)}[ngToolbar]:hover{scrollbar-color:var(--grey-neutral) transparent}.group{gap:.5rem;display:flex}.separator{width:1px;align-self:center;height:calc(100% - 1rem);background-color:var(--quinary-contrast)}[ngToolbarWidget]{border:none;cursor:pointer;padding:.5rem;border-radius:4px;display:flex;align-items:center;justify-content:center;background-color:transparent;color:var(--primary-contrast)}[ngToolbarWidget] svg{fill:currentColor}[ngToolbarWidget]:hover{background-color:color-mix(in srgb,var(--primary-contrast) 10%,transparent)}[ngToolbarWidget]:active{background-color:color-mix(in srgb,var(--primary-contrast) 15%,transparent)}[ngToolbarWidget]:focus{outline-offset:-1px;outline:1px solid color-mix(in srgb,var(--hot-pink) 60%,transparent)}[ngToolbarWidget][aria-pressed=true],[ngToolbarWidget][aria-checked=true]{color:color-mix(in srgb,var(--hot-pink) 80%,var(--primary-contrast));background-color:color-mix(in srgb,var(--hot-pink) 10%,transparent)}.divider{color:var(--quinary-contrast);align-self:center}.lexical-editor-container{position:relative;background-color:#fff;overflow-y:auto}.lexical-content-editable{min-height:450px;min-width:100%;padding:16px;outline:none;word-break:break-word;overflow-wrap:break-word}.lexical-paragraph{margin:0 0 10px}.lexical-bold{font-weight:700}.lexical-italic{font-style:italic}.lexical-underline{text-decoration:underline}.lexical-strikethrough{text-decoration:line-through}.lexical-inline-code{font-family:monospace;background-color:#f0f0f0;padding:2px 4px;border-radius:2px}.lexical-h1{font-size:2em;margin-top:20px;margin-bottom:10px}.lexical-h2{font-size:1.5em;margin-top:15px;margin-bottom:10px}.lexical-h3{font-size:1.17em;margin-top:10px;margin-bottom:10px}.lexical-ul{padding-left:30px;list-style-type:disc}.lexical-ol{padding-left:30px;list-style-type:decimal}.lexical-listitem{margin-bottom:4px}.lexical-code-block{background-color:#282c34;color:#abb2bf;font-family:Fira Code,monospace;display:block;padding:16px;line-height:1.5;font-size:14px;margin:10px 0;overflow-x:auto;border-radius:6px;tab-size:2}.lexical-table{border-collapse:collapse;border-spacing:0;max-width:100%;overflow-y:scroll;table-layout:fixed;width:100%;margin:10px 0}.lexical-table-row{border-bottom:1px solid #ddd}.lexical-table-cell{border:1px solid #ddd;padding:8px;vertical-align:top;text-align:left}\n"] }]
191
175
  }], ctorParameters: () => [], propDecorators: { jsonDataChanged: [{ type: i0.Output, args: ["jsonDataChanged"] }], htmlContentChanged: [{ type: i0.Output, args: ["htmlContentChanged"] }], editorContent: [{
192
176
  type: ViewChild,
193
177
  args: ['editorContent']
@@ -218,6 +202,15 @@ class LexicalPreviewComponent {
218
202
  });
219
203
  try {
220
204
  const editorStateObj = typeof inputData === 'string' ? JSON.parse(inputData) : inputData;
205
+ // Lexical throws an error if you try to set an empty state.
206
+ // An empty state might be null, an empty object, or a state with no nodes.
207
+ // We'll do a basic check here to avoid the error.
208
+ if (!editorStateObj ||
209
+ !editorStateObj.root ||
210
+ !editorStateObj.root.children ||
211
+ editorStateObj.root.children.length === 0) {
212
+ return this.sanitizer.bypassSecurityTrustHtml('');
213
+ }
221
214
  const state = tempEditor.parseEditorState(editorStateObj);
222
215
  tempEditor.setEditorState(state);
223
216
  let html = '';
@@ -228,7 +221,7 @@ class LexicalPreviewComponent {
228
221
  }
229
222
  catch (e) {
230
223
  console.error('Failed to parse Lexical state in preview:', e);
231
- return this.sanitizer.bypassSecurityTrustHtml('<div>Sorry an error occurred</div>');
224
+ return this.sanitizer.bypassSecurityTrustHtml('<div>No content to display</div>');
232
225
  }
233
226
  }
234
227
  // 2. Fallback to live editor state if no input data provided
@@ -251,17 +244,19 @@ class LexicalPreviewComponent {
251
244
  }
252
245
  const inputData = this.data();
253
246
  if (inputData) {
254
- return typeof inputData === 'string' ? inputData : JSON.stringify(inputData, null, 2);
247
+ return typeof inputData === 'string'
248
+ ? inputData
249
+ : JSON.stringify(inputData, null, 2);
255
250
  }
256
251
  const state = this.liveEditorState();
257
252
  return state ? JSON.stringify(state.toJSON(), null, 2) : 'No state available';
258
253
  }, ...(ngDevMode ? [{ debugName: "debugJson" }] : /* istanbul ignore next */ []));
259
254
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: LexicalPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
260
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: LexicalPreviewComponent, isStandalone: true, selector: "lexical-preview", inputs: { debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, providers: [EditorService], ngImport: i0, template: "<div class=\"lexical-preview-container\">\n <!-- Render the visual HTML representation -->\n <div class=\"rendered-content\" [innerHTML]=\"renderedContent()\"></div>\n\n <!-- Render the debug JSON conditionally -->\n @if (debug()) {\n <div class=\"debug-container\">\n <h4>Editor State JSON (Preview)</h4>\n <pre>{{ debugJson() }}</pre>\n </div>\n }\n</div>\n", styles: [".lexical-preview-container{padding:10px}b,strong{font-weight:700}i,em{font-style:italic}u{text-decoration:underline}s{text-decoration:line-through}code{font-family:monospace;background-color:#f0f0f0;padding:2px 4px;border-radius:2px}.debug-container{margin-top:20px;padding:10px;background-color:#f9f9f9;border:1px solid #ddd;border-radius:4px}pre{white-space:pre-wrap;word-wrap:break-word;font-size:12px;margin:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
255
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: LexicalPreviewComponent, isStandalone: true, selector: "lexical-preview", inputs: { debug: { classPropertyName: "debug", publicName: "debug", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, providers: [EditorService], ngImport: i0, template: "<div class=\"lexical-preview-container\">\n <!-- Render the visual HTML representation -->\n <div class=\"rendered-content\" [innerHTML]=\"renderedContent()\"></div>\n\n <!-- Render the debug JSON conditionally -->\n @if (debug()) {\n <div class=\"debug-container\">\n <h4>Editor State JSON (Preview)</h4>\n <pre>{{ debugJson() }}</pre>\n </div>\n }\n</div>\n", styles: [".lexical-preview-container{padding:10px;word-break:break-word;overflow-wrap:break-word}b,strong{font-weight:700}i,em{font-style:italic}u{text-decoration:underline}s{text-decoration:line-through}code{font-family:monospace;background-color:#f0f0f0;padding:2px 4px;border-radius:2px}.debug-container{margin-top:20px;padding:10px;background-color:#f9f9f9;border:1px solid #ddd;border-radius:4px}pre{white-space:pre-wrap;word-wrap:break-word;font-size:12px;margin:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
261
256
  }
262
257
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: LexicalPreviewComponent, decorators: [{
263
258
  type: Component,
264
- args: [{ selector: 'lexical-preview', standalone: true, imports: [CommonModule], providers: [EditorService], template: "<div class=\"lexical-preview-container\">\n <!-- Render the visual HTML representation -->\n <div class=\"rendered-content\" [innerHTML]=\"renderedContent()\"></div>\n\n <!-- Render the debug JSON conditionally -->\n @if (debug()) {\n <div class=\"debug-container\">\n <h4>Editor State JSON (Preview)</h4>\n <pre>{{ debugJson() }}</pre>\n </div>\n }\n</div>\n", styles: [".lexical-preview-container{padding:10px}b,strong{font-weight:700}i,em{font-style:italic}u{text-decoration:underline}s{text-decoration:line-through}code{font-family:monospace;background-color:#f0f0f0;padding:2px 4px;border-radius:2px}.debug-container{margin-top:20px;padding:10px;background-color:#f9f9f9;border:1px solid #ddd;border-radius:4px}pre{white-space:pre-wrap;word-wrap:break-word;font-size:12px;margin:0}\n"] }]
259
+ args: [{ selector: 'lexical-preview', standalone: true, imports: [CommonModule], providers: [EditorService], template: "<div class=\"lexical-preview-container\">\n <!-- Render the visual HTML representation -->\n <div class=\"rendered-content\" [innerHTML]=\"renderedContent()\"></div>\n\n <!-- Render the debug JSON conditionally -->\n @if (debug()) {\n <div class=\"debug-container\">\n <h4>Editor State JSON (Preview)</h4>\n <pre>{{ debugJson() }}</pre>\n </div>\n }\n</div>\n", styles: [".lexical-preview-container{padding:10px;word-break:break-word;overflow-wrap:break-word}b,strong{font-weight:700}i,em{font-style:italic}u{text-decoration:underline}s{text-decoration:line-through}code{font-family:monospace;background-color:#f0f0f0;padding:2px 4px;border-radius:2px}.debug-container{margin-top:20px;padding:10px;background-color:#f9f9f9;border:1px solid #ddd;border-radius:4px}pre{white-space:pre-wrap;word-wrap:break-word;font-size:12px;margin:0}\n"] }]
265
260
  }], propDecorators: { debug: [{ type: i0.Input, args: [{ isSignal: true, alias: "debug", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }] } });
266
261
 
267
262
  /*
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-lexical-editor.mjs","sources":["../../../projects/ngx-lexical-editor/src/lib/services/editor.service.ts","../../../projects/ngx-lexical-editor/src/lib/components/editor/editor.component.ts","../../../projects/ngx-lexical-editor/src/lib/components/editor/editor.component.html","../../../projects/ngx-lexical-editor/src/lib/components/preview/preview.component.ts","../../../projects/ngx-lexical-editor/src/lib/components/preview/preview.component.html","../../../projects/ngx-lexical-editor/src/public-api.ts","../../../projects/ngx-lexical-editor/src/ngx-lexical-editor.ts"],"sourcesContent":["import { computed, inject, PLATFORM_ID, signal, Signal } from '@angular/core';\nimport {\n createEditor,\n CreateEditorArgs,\n EditorState,\n LexicalEditor,\n ParagraphNode,\n SerializedEditorState,\n TextNode\n} from 'lexical';\nimport { HeadingNode, QuoteNode } from '@lexical/rich-text';\nimport { ListItemNode, ListNode } from '@lexical/list';\nimport { CodeHighlightNode, CodeNode } from '@lexical/code';\nimport { TableCellNode, TableNode, TableRowNode } from '@lexical/table';\nimport { isPlatformBrowser } from '@angular/common';\nimport { $generateHtmlFromNodes } from '@lexical/html';\n\nexport class EditorService {\n private editor?: LexicalEditor;\n private platformId = inject(PLATFORM_ID);\n private readonly editorState = signal<EditorState | null>(null);\n\n constructor() {\n const editorConfig: CreateEditorArgs = {\n namespace: 'NgxLexicalEditor',\n theme: {\n paragraph: 'lexical-paragraph',\n heading: {\n h1: 'lexical-h1',\n h2: 'lexical-h2',\n h3: 'lexical-h3',\n },\n list: {\n ul: 'lexical-ul',\n ol: 'lexical-ol',\n listitem: 'lexical-listitem',\n },\n code: 'lexical-code-block',\n table: 'lexical-table',\n tableCell: 'lexical-table-cell',\n tableRow: 'lexical-table-row',\n text: {\n bold: 'lexical-bold',\n italic: 'lexical-italic',\n underline: 'lexical-underline',\n strikethrough: 'lexical-strikethrough',\n code: 'lexical-inline-code',\n },\n },\n nodes: [\n HeadingNode,\n QuoteNode,\n ListNode,\n ListItemNode,\n CodeNode,\n CodeHighlightNode,\n TableNode,\n TableRowNode,\n TableCellNode,\n ParagraphNode,\n TextNode,\n ],\n onError: (error: Error) => {\n console.error('Lexical Error:', error);\n },\n editable: true,\n };\n\n if (isPlatformBrowser(this.platformId)) {\n this.initEditor(editorConfig);\n }\n }\n\n /**\n * JSON Signal of the editor's content\n */\n public get getJSON(): Signal<SerializedEditorState> {\n return computed(() => {\n const state = this.editorState();\n return state\n ? state.toJSON()\n : ({\n root: {\n children: [],\n direction: null,\n format: '',\n indent: 0,\n type: 'root',\n version: 1,\n },\n } as SerializedEditorState);\n });\n }\n\n /**\n * Returns the editor's content as an HTML string. As a signal\n */\n public get getHTML(): Signal<string> {\n return computed(() => {\n const state = this.editorState();\n if (!state || !this.editor) {\n return '';\n }\n\n let html = '';\n this.editor.getEditorState().read(() => {\n html = $generateHtmlFromNodes(this.editor!);\n });\n return html;\n });\n }\n\n getEditorState(): Signal<EditorState | null> {\n return this.editorState.asReadonly();\n }\n\n getEditor(): LexicalEditor | undefined {\n return this.editor;\n }\n\n private async initEditor(editorConfig: CreateEditorArgs) {\n this.editor = createEditor(editorConfig);\n this.editor.registerUpdateListener(({ editorState }) => {\n this.editorState.set(editorState);\n });\n }\n}\n","import {\n AfterViewInit,\n Component,\n effect,\n ElementRef,\n inject,\n OnDestroy,\n output,\n OutputEmitterRef,\n ViewChild\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { EditorService } from '../../services/editor.service';\nimport {\n $createParagraphNode,\n $getSelection,\n $isRangeSelection,\n FORMAT_TEXT_COMMAND,\n LexicalEditor,\n SerializedEditorState\n} from 'lexical';\nimport { $setBlocksType } from '@lexical/selection';\nimport { $createHeadingNode, HeadingTagType, registerRichText } from '@lexical/rich-text';\nimport { $insertList } from '@lexical/list';\nimport { $createCodeNode } from '@lexical/code';\nimport { INSERT_TABLE_COMMAND } from '@lexical/table';\nimport { Toolbar, ToolbarWidget, ToolbarWidgetGroup } from '@angular/aria/toolbar';\n\n@Component({\n selector: 'lexical-editor',\n standalone: true,\n imports: [CommonModule, Toolbar, ToolbarWidgetGroup, ToolbarWidget],\n templateUrl: './editor.component.html',\n styleUrl: './editor.component.css',\n providers: [EditorService],\n})\nexport class LexicalEditorComponent implements AfterViewInit, OnDestroy {\n public readonly jsonDataChanged: OutputEmitterRef<SerializedEditorState> = output();\n public readonly htmlContentChanged: OutputEmitterRef<string> = output();\n @ViewChild('editorContent') protected editorContent!: ElementRef<HTMLDivElement>;\n private readonly editorService = inject(EditorService);\n private readonly editor?: LexicalEditor;\n\n constructor() {\n this.editor = this.editorService.getEditor();\n if (this.editor) {\n registerRichText(this.editor);\n }\n\n effect(() => {\n const json = this.editorService.getJSON();\n if (json) {\n this.jsonDataChanged.emit(json);\n }\n });\n\n effect(() => {\n const html = this.editorService.getHTML();\n if (html) {\n this.htmlContentChanged.emit(html);\n }\n });\n }\n\n ngAfterViewInit(): void {\n this.editor?.setRootElement(this.editorContent.nativeElement);\n }\n\n ngOnDestroy(): void {\n this.editor?.setRootElement(null);\n }\n\n protected formatText(type: 'bold' | 'italic' | 'underline'): void {\n this.editor?.dispatchCommand(FORMAT_TEXT_COMMAND, type);\n }\n\n protected formatHeading(headingSize: HeadingTagType): void {\n this.editor?.update(() => {\n const selection = $getSelection();\n if ($isRangeSelection(selection)) {\n $setBlocksType(selection, () => $createHeadingNode(headingSize));\n }\n });\n }\n\n protected formatParagraph(): void {\n this.editor?.update(() => {\n const selection = $getSelection();\n if ($isRangeSelection(selection)) {\n $setBlocksType(selection, () => $createParagraphNode());\n }\n });\n }\n\n protected formatList(listType: 'bullet' | 'number' | 'check'): void {\n this.editor?.update(() => {\n $insertList(listType);\n });\n }\n\n protected formatCodeBlock(): void {\n this.editor?.update(() => {\n const selection = $getSelection();\n if ($isRangeSelection(selection)) {\n $setBlocksType(selection, () => $createCodeNode());\n }\n });\n }\n\n protected insertTable(): void {\n this.editor?.dispatchCommand(INSERT_TABLE_COMMAND, {\n rows: '3',\n columns: '3',\n });\n }\n}\n","<div class=\"container\">\n <div aria-label=\"Text Formatting Tools\" class=\"toolbar\" ngToolbar>\n\n <!-- Inline formats -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatText('bold')\" ngToolbarWidget type=\"button\" value=\"bold\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M266-192v-576h227.95q67.05 0 123.55 41.32Q674-685.35 674-612q0 51-22.5 79.5T609-490.96Q635-479 665-448t30 91q0 91-67.03 128t-125.81 37H266Zm127-118h104.68Q546-310 556-334.5t10-35.5q0-11-10.5-35.5T494-430H393v120Zm0-232h93q33 0 48.5-17.5T550-597q0-24-17.11-39t-44.28-15H393v109Z\" />\n </svg>\n </button>\n <button (click)=\"formatText('italic')\" ngToolbarWidget type=\"button\" value=\"italic\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M216-192v-96h160l124-384H336v-96h408v96H596L472-288h152v96H216Z\" />\n </svg>\n </button>\n <button (click)=\"formatText('underline')\" ngToolbarWidget type=\"button\" value=\"underline\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M240-144v-72h480v72H240Zm91.5-203.4Q279-406.8 279-504.86V-816h97.21v317.09q0 52.85 26.43 85.88Q429.07-380 480.03-380q50.97 0 77.39-33.03 26.41-33.03 26.41-85.88V-816H681v311.14q0 98.06-52.5 157.46Q576-288 480-288t-148.5-59.4Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Block formats -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatHeading('h1')\" ngToolbarWidget type=\"button\" value=\"h1\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M192-288v-384h72v156h168v-156h72v384h-72v-156H264v156h-72Zm504 0v-312h-96v-72h168v384h-72Z\" />\n </svg>\n </button>\n <button (click)=\"formatHeading('h2')\" ngToolbarWidget type=\"button\" value=\"h2\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M144-288v-384h72v156h168v-156h72v384h-72v-156H216v156h-72Zm384 0v-156q0-29.7 21.15-50.85Q570.3-516 600-516h144v-84H528v-72h216.26Q774-672 795-650.85q21 21.15 21 50.85v84q0 29.7-21.15 50.85Q773.7-444 744-444H600v84h216v72H528Z\" />\n </svg>\n </button>\n <button (click)=\"formatParagraph()\" ngToolbarWidget type=\"button\" value=\"p\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M384-192v-192q-79.68 0-135.84-56.23-56.16-56.22-56.16-136Q192-656 248.16-712q56.16-56 135.84-56h336v72h-96v504h-72v-504h-96v504h-72Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Lists -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatList('bullet')\" ngToolbarWidget type=\"button\" value=\"bullet\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M360-240v-72h456v72H360Zm0-204v-72h456v72H360Zm0-204v-72h456v72H360ZM215.79-204Q186-204 165-225.21t-21-51Q144-306 165.21-327t51-21Q246-348 267-326.79t21 51Q288-246 266.79-225t-51 21Zm0-204Q186-408 165-429.21t-21-51Q144-510 165.21-531t51-21Q246-552 267-530.79t21 51Q288-450 266.79-429t-51 21ZM165-633.21q-21-21.21-21-51T165.21-735q21.21-21 51-21T267-734.79q21 21.21 21 51T266.79-633q-21.21 21-51 21T165-633.21Z\" />\n </svg>\n </button>\n <button (click)=\"formatList('number')\" ngToolbarWidget type=\"button\" value=\"number\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M144-144v-48h96v-24h-48v-48h48v-24h-96v-48h120q10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v48q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9 10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v48q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9H144Zm0-240v-96q0-10.2 6.9-17.1 6.9-6.9 17.1-6.9h72v-24h-96v-48h120q10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v72q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9h-72v24h96v48H144Zm48-240v-144h-48v-48h96v192h-48Zm168 384v-72h456v72H360Zm0-204v-72h456v72H360Zm0-204v-72h456v72H360Z\" />\n </svg>\n </button>\n <button (click)=\"formatList('check')\" ngToolbarWidget type=\"button\" value=\"check\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M232-216 96-352l51-51 84 85 170-170 52 51-221 221Zm0-312L96-664l51-51 85 85 169-170 52 51-221 221Zm296 240v-72h336v72H528Zm0-312v-72h336v72H528Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Code Block -->\n <button (click)=\"formatCodeBlock()\" ngToolbarWidget type=\"button\" value=\"code\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M336-240 96-480l240-240 51 51-189 189 189 189-51 51Zm288 0-51-51 189-189-189-189 51-51 240 240-240 240Z\" />\n </svg>\n </button>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Table (Basic insertion) -->\n <button (click)=\"insertTable()\" ngToolbarWidget type=\"button\" value=\"table\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M216-144q-33 0-52.5-19.5T144-216v-528q0-33 19.5-52.5T216-816h528q33 0 52.5 19.5T816-744v528q0 33-19.5 52.5T744-144H216Zm228-228H216v156h228v-156Zm72 0v156h228v-156H516Zm-72-72v-156H216v156h228Zm72 0h228v-156H516v156ZM216-672h528v-72H216v72Z\" />\n </svg>\n </button>\n </div>\n <div class=\"lexical-editor-container\">\n <div #editorContent class=\"lexical-content-editable\" contenteditable=\"true\"></div>\n </div>\n</div>\n","import { Component, computed, inject, input } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { EditorService } from '../../services/editor.service';\nimport { $generateHtmlFromNodes } from '@lexical/html';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { createEditor, SerializedEditorState } from 'lexical';\n\n@Component({\n selector: 'lexical-preview',\n standalone: true,\n imports: [CommonModule],\n templateUrl: './preview.component.html',\n styleUrl: './preview.component.css',\n providers: [EditorService],\n})\nexport class LexicalPreviewComponent {\n debug = input<boolean>(false);\n\n /**\n * Accepts JSON string or SerializedEditorState object directly.\n */\n data = input<string | SerializedEditorState | null>(null);\n\n private readonly editorService = inject(EditorService);\n private readonly sanitizer = inject(DomSanitizer);\n\n // If we don't have input data, fallback to the live editor state.\n private readonly liveEditorState = this.editorService.getEditorState();\n\n protected readonly renderedContent = computed<SafeHtml>(() => {\n const inputData = this.data();\n\n // 1. If we have explicit input data, parse it and render\n if (inputData) {\n // We need a temporary headless editor to parse the state and convert to HTML.\n // This is necessary because Lexical's HTML generation requires an editor instance.\n // Using the service's editor config is a good idea to ensure custom nodes match.\n const tempEditor = createEditor({\n // We reuse the nodes registered in the main editor to ensure it knows how to parse them\n nodes: this.editorService.getEditor()?._nodes\n ? Array.from(this.editorService.getEditor()!._nodes.values()).map((n) => n.klass)\n : [],\n });\n\n try {\n const editorStateObj = typeof inputData === 'string' ? JSON.parse(inputData) : inputData;\n const state = tempEditor.parseEditorState(editorStateObj);\n tempEditor.setEditorState(state);\n\n let html = '';\n tempEditor.getEditorState().read(() => {\n html = $generateHtmlFromNodes(tempEditor, null);\n });\n return this.sanitizer.bypassSecurityTrustHtml(html);\n } catch (e) {\n console.error('Failed to parse Lexical state in preview:', e);\n return this.sanitizer.bypassSecurityTrustHtml('<div>Sorry an error occurred</div>');\n }\n }\n\n // 2. Fallback to live editor state if no input data provided\n const state = this.liveEditorState();\n if (!state) {\n return this.sanitizer.bypassSecurityTrustHtml('');\n }\n\n let html = '';\n const editor = this.editorService.getEditor();\n\n if (editor) {\n editor.getEditorState().read(() => {\n html = $generateHtmlFromNodes(editor, null);\n });\n }\n\n return this.sanitizer.bypassSecurityTrustHtml(html);\n });\n\n protected readonly debugJson = computed(() => {\n if (!this.debug()) {\n return null;\n }\n\n const inputData = this.data();\n if (inputData) {\n return typeof inputData === 'string' ? inputData : JSON.stringify(inputData, null, 2);\n }\n\n const state = this.liveEditorState();\n return state ? JSON.stringify(state.toJSON(), null, 2) : 'No state available';\n });\n}\n","<div class=\"lexical-preview-container\">\n <!-- Render the visual HTML representation -->\n <div class=\"rendered-content\" [innerHTML]=\"renderedContent()\"></div>\n\n <!-- Render the debug JSON conditionally -->\n @if (debug()) {\n <div class=\"debug-container\">\n <h4>Editor State JSON (Preview)</h4>\n <pre>{{ debugJson() }}</pre>\n </div>\n }\n</div>\n","/*\n * Public API Surface of ngx-lexical-editor\n */\n\nexport * from './lib/index';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngx-lexical-editor.mjs","sources":["../../../projects/ngx-lexical-editor/src/lib/services/editor.service.ts","../../../projects/ngx-lexical-editor/src/lib/components/editor/editor.component.ts","../../../projects/ngx-lexical-editor/src/lib/components/editor/editor.component.html","../../../projects/ngx-lexical-editor/src/lib/components/preview/preview.component.ts","../../../projects/ngx-lexical-editor/src/lib/components/preview/preview.component.html","../../../projects/ngx-lexical-editor/src/public-api.ts","../../../projects/ngx-lexical-editor/src/ngx-lexical-editor.ts"],"sourcesContent":["import { computed, inject, PLATFORM_ID, signal, Signal } from '@angular/core';\nimport {\n createEditor,\n CreateEditorArgs,\n EditorState,\n LexicalEditor,\n ParagraphNode,\n SerializedEditorState,\n TextNode\n} from 'lexical';\nimport { HeadingNode, QuoteNode } from '@lexical/rich-text';\nimport { ListItemNode, ListNode } from '@lexical/list';\nimport { CodeHighlightNode, CodeNode } from '@lexical/code';\nimport { TableCellNode, TableNode, TableRowNode } from '@lexical/table';\nimport { isPlatformBrowser } from '@angular/common';\nimport { $generateHtmlFromNodes } from '@lexical/html';\n\nexport class EditorService {\n private editor?: LexicalEditor;\n private platformId = inject(PLATFORM_ID);\n private readonly editorState = signal<EditorState | null>(null);\n\n public readonly json: Signal<SerializedEditorState>;\n public readonly html: Signal<string>;\n\n constructor() {\n const editorConfig: CreateEditorArgs = {\n namespace: 'NgxLexicalEditor',\n theme: {\n paragraph: 'lexical-paragraph',\n heading: {\n h1: 'lexical-h1',\n h2: 'lexical-h2',\n h3: 'lexical-h3',\n },\n list: {\n ul: 'lexical-ul',\n ol: 'lexical-ol',\n listitem: 'lexical-listitem',\n },\n code: 'lexical-code-block',\n table: 'lexical-table',\n tableCell: 'lexical-table-cell',\n tableRow: 'lexical-table-row',\n text: {\n bold: 'lexical-bold',\n italic: 'lexical-italic',\n underline: 'lexical-underline',\n strikethrough: 'lexical-strikethrough',\n code: 'lexical-inline-code',\n },\n },\n nodes: [\n HeadingNode,\n QuoteNode,\n ListNode,\n ListItemNode,\n CodeNode,\n CodeHighlightNode,\n TableNode,\n TableRowNode,\n TableCellNode,\n ParagraphNode,\n TextNode,\n ],\n onError: (error: Error) => {\n console.error('Lexical Error:', error);\n },\n editable: true,\n };\n\n this.json = computed(() => {\n const state = this.editorState();\n return state\n ? state.toJSON()\n : ({\n root: {\n children: [],\n direction: null,\n format: '',\n indent: 0,\n type: 'root',\n version: 1,\n },\n } as SerializedEditorState);\n });\n\n this.html = computed(() => {\n const state = this.editorState();\n if (!state || !this.editor) {\n return '';\n }\n\n let html = '';\n this.editor.getEditorState().read(() => {\n html = $generateHtmlFromNodes(this.editor!);\n });\n return html;\n });\n\n if (isPlatformBrowser(this.platformId)) {\n this.initEditor(editorConfig);\n }\n }\n\n getEditorState(): Signal<EditorState | null> {\n return this.editorState.asReadonly();\n }\n\n getEditor(): LexicalEditor | undefined {\n return this.editor;\n }\n\n private initEditor(editorConfig: CreateEditorArgs) {\n this.editor = createEditor(editorConfig);\n this.editor.registerUpdateListener(({ editorState }) => {\n this.editorState.set(editorState);\n });\n }\n}\n","import {\n AfterViewInit,\n Component,\n effect,\n ElementRef,\n inject,\n OnDestroy,\n output,\n OutputEmitterRef,\n ViewChild\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { EditorService } from '../../services/editor.service';\nimport {\n $createParagraphNode,\n $getSelection,\n $isRangeSelection,\n FORMAT_TEXT_COMMAND,\n LexicalEditor,\n SerializedEditorState\n} from 'lexical';\nimport { $setBlocksType } from '@lexical/selection';\nimport { $createHeadingNode, HeadingTagType, registerRichText } from '@lexical/rich-text';\nimport { $insertList } from '@lexical/list';\nimport { $createCodeNode } from '@lexical/code';\nimport { INSERT_TABLE_COMMAND } from '@lexical/table';\nimport { Toolbar, ToolbarWidget, ToolbarWidgetGroup } from '@angular/aria/toolbar';\n\n@Component({\n selector: 'lexical-editor',\n standalone: true,\n imports: [CommonModule, Toolbar, ToolbarWidgetGroup, ToolbarWidget],\n templateUrl: './editor.component.html',\n styleUrl: './editor.component.css',\n providers: [EditorService],\n})\nexport class LexicalEditorComponent implements AfterViewInit, OnDestroy {\n public readonly jsonDataChanged: OutputEmitterRef<SerializedEditorState> = output();\n public readonly htmlContentChanged: OutputEmitterRef<string> = output();\n @ViewChild('editorContent') protected editorContent!: ElementRef<HTMLDivElement>;\n private readonly editorService = inject(EditorService);\n private readonly editor?: LexicalEditor;\n\n constructor() {\n this.editor = this.editorService.getEditor();\n if (this.editor) {\n registerRichText(this.editor);\n }\n\n effect(() => {\n this.jsonDataChanged.emit(this.editorService.json());\n this.htmlContentChanged.emit(this.editorService.html());\n });\n }\n\n ngAfterViewInit(): void {\n this.editor?.setRootElement(this.editorContent.nativeElement);\n }\n\n ngOnDestroy(): void {\n this.editor?.setRootElement(null);\n }\n\n protected formatText(type: 'bold' | 'italic' | 'underline'): void {\n this.editor?.dispatchCommand(FORMAT_TEXT_COMMAND, type);\n }\n\n protected formatHeading(headingSize: HeadingTagType): void {\n this.editor?.update(() => {\n const selection = $getSelection();\n if ($isRangeSelection(selection)) {\n $setBlocksType(selection, () => $createHeadingNode(headingSize));\n }\n });\n }\n\n protected formatParagraph(): void {\n this.editor?.update(() => {\n const selection = $getSelection();\n if ($isRangeSelection(selection)) {\n $setBlocksType(selection, () => $createParagraphNode());\n }\n });\n }\n\n protected formatList(listType: 'bullet' | 'number' | 'check'): void {\n this.editor?.update(() => {\n $insertList(listType);\n });\n }\n\n protected formatCodeBlock(): void {\n this.editor?.update(() => {\n const selection = $getSelection();\n if ($isRangeSelection(selection)) {\n $setBlocksType(selection, () => $createCodeNode());\n }\n });\n }\n\n protected insertTable(): void {\n this.editor?.dispatchCommand(INSERT_TABLE_COMMAND, {\n rows: '3',\n columns: '3',\n });\n }\n}\n","<div class=\"container\">\n <div>\n <div aria-label=\"Text Formatting Tools\" class=\"toolbar\" ngToolbar>\n\n <!-- Inline formats -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatText('bold')\" ngToolbarWidget type=\"button\" value=\"bold\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M266-192v-576h227.95q67.05 0 123.55 41.32Q674-685.35 674-612q0 51-22.5 79.5T609-490.96Q635-479 665-448t30 91q0 91-67.03 128t-125.81 37H266Zm127-118h104.68Q546-310 556-334.5t10-35.5q0-11-10.5-35.5T494-430H393v120Zm0-232h93q33 0 48.5-17.5T550-597q0-24-17.11-39t-44.28-15H393v109Z\" />\n </svg>\n </button>\n <button (click)=\"formatText('italic')\" ngToolbarWidget type=\"button\" value=\"italic\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M216-192v-96h160l124-384H336v-96h408v96H596L472-288h152v96H216Z\" />\n </svg>\n </button>\n <button (click)=\"formatText('underline')\" ngToolbarWidget type=\"button\" value=\"underline\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M240-144v-72h480v72H240Zm91.5-203.4Q279-406.8 279-504.86V-816h97.21v317.09q0 52.85 26.43 85.88Q429.07-380 480.03-380q50.97 0 77.39-33.03 26.41-33.03 26.41-85.88V-816H681v311.14q0 98.06-52.5 157.46Q576-288 480-288t-148.5-59.4Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Block formats -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatHeading('h1')\" ngToolbarWidget type=\"button\" value=\"h1\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M192-288v-384h72v156h168v-156h72v384h-72v-156H264v156h-72Zm504 0v-312h-96v-72h168v384h-72Z\" />\n </svg>\n </button>\n <button (click)=\"formatHeading('h2')\" ngToolbarWidget type=\"button\" value=\"h2\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M144-288v-384h72v156h168v-156h72v384h-72v-156H216v156h-72Zm384 0v-156q0-29.7 21.15-50.85Q570.3-516 600-516h144v-84H528v-72h216.26Q774-672 795-650.85q21 21.15 21 50.85v84q0 29.7-21.15 50.85Q773.7-444 744-444H600v84h216v72H528Z\" />\n </svg>\n </button>\n <button (click)=\"formatParagraph()\" ngToolbarWidget type=\"button\" value=\"p\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M384-192v-192q-79.68 0-135.84-56.23-56.16-56.22-56.16-136Q192-656 248.16-712q56.16-56 135.84-56h336v72h-96v504h-72v-504h-96v504h-72Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Lists -->\n <div class=\"group\" ngToolbarWidgetGroup>\n <button (click)=\"formatList('bullet')\" ngToolbarWidget type=\"button\" value=\"bullet\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M360-240v-72h456v72H360Zm0-204v-72h456v72H360Zm0-204v-72h456v72H360ZM215.79-204Q186-204 165-225.21t-21-51Q144-306 165.21-327t51-21Q246-348 267-326.79t21 51Q288-246 266.79-225t-51 21Zm0-204Q186-408 165-429.21t-21-51Q144-510 165.21-531t51-21Q246-552 267-530.79t21 51Q288-450 266.79-429t-51 21ZM165-633.21q-21-21.21-21-51T165.21-735q21.21-21 51-21T267-734.79q21 21.21 21 51T266.79-633q-21.21 21-51 21T165-633.21Z\" />\n </svg>\n </button>\n <button (click)=\"formatList('number')\" ngToolbarWidget type=\"button\" value=\"number\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M144-144v-48h96v-24h-48v-48h48v-24h-96v-48h120q10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v48q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9 10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v48q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9H144Zm0-240v-96q0-10.2 6.9-17.1 6.9-6.9 17.1-6.9h72v-24h-96v-48h120q10.2 0 17.1 6.9 6.9 6.9 6.9 17.1v72q0 10.2-6.9 17.1-6.9 6.9-17.1 6.9h-72v24h96v48H144Zm48-240v-144h-48v-48h96v192h-48Zm168 384v-72h456v72H360Zm0-204v-72h456v72H360Zm0-204v-72h456v72H360Z\" />\n </svg>\n </button>\n <button (click)=\"formatList('check')\" ngToolbarWidget type=\"button\" value=\"check\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M232-216 96-352l51-51 84 85 170-170 52 51-221 221Zm0-312L96-664l51-51 85 85 169-170 52 51-221 221Zm296 240v-72h336v72H528Zm0-312v-72h336v72H528Z\" />\n </svg>\n </button>\n </div>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Code Block -->\n <button (click)=\"formatCodeBlock()\" ngToolbarWidget type=\"button\" value=\"code\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M336-240 96-480l240-240 51 51-189 189 189 189-51 51Zm288 0-51-51 189-189-189-189 51-51 240 240-240 240Z\" />\n </svg>\n </button>\n\n <span aria-hidden=\"true\" class=\"divider\">|</span>\n\n <!-- Table (Basic insertion) -->\n <button (click)=\"insertTable()\" ngToolbarWidget type=\"button\" value=\"table\">\n <svg fill=\"#808080\" height=\"20px\" viewBox=\"0 -960 960 960\" width=\"20px\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M216-144q-33 0-52.5-19.5T144-216v-528q0-33 19.5-52.5T216-816h528q33 0 52.5 19.5T816-744v528q0 33-19.5 52.5T744-144H216Zm228-228H216v156h228v-156Zm72 0v156h228v-156H516Zm-72-72v-156H216v156h228Zm72 0h228v-156H516v156ZM216-672h528v-72H216v72Z\" />\n </svg>\n </button>\n </div>\n </div>\n <div class=\"lexical-editor-container\">\n <div #editorContent class=\"lexical-content-editable\" contenteditable=\"true\"></div>\n </div>\n</div>\n","import { Component, computed, inject, input } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { EditorService } from '../../services/editor.service';\nimport { $generateHtmlFromNodes } from '@lexical/html';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { createEditor, SerializedEditorState } from 'lexical';\n\n@Component({\n selector: 'lexical-preview',\n standalone: true,\n imports: [CommonModule],\n templateUrl: './preview.component.html',\n styleUrl: './preview.component.css',\n providers: [EditorService],\n})\nexport class LexicalPreviewComponent {\n debug = input<boolean>(false);\n\n /**\n * Accepts JSON string or SerializedEditorState object directly.\n */\n data = input<string | SerializedEditorState | null>(null);\n\n private readonly editorService = inject(EditorService);\n private readonly sanitizer = inject(DomSanitizer);\n\n // If we don't have input data, fallback to the live editor state.\n private readonly liveEditorState = this.editorService.getEditorState();\n\n protected readonly renderedContent = computed<SafeHtml>(() => {\n const inputData = this.data();\n\n // 1. If we have explicit input data, parse it and render\n if (inputData) {\n // We need a temporary headless editor to parse the state and convert to HTML.\n // This is necessary because Lexical's HTML generation requires an editor instance.\n // Using the service's editor config is a good idea to ensure custom nodes match.\n const tempEditor = createEditor({\n // We reuse the nodes registered in the main editor to ensure it knows how to parse them\n nodes: this.editorService.getEditor()?._nodes\n ? Array.from(this.editorService.getEditor()!._nodes.values()).map(\n (n) => n.klass\n )\n : [],\n });\n\n try {\n const editorStateObj =\n typeof inputData === 'string' ? JSON.parse(inputData) : inputData;\n\n // Lexical throws an error if you try to set an empty state.\n // An empty state might be null, an empty object, or a state with no nodes.\n // We'll do a basic check here to avoid the error.\n if (\n !editorStateObj ||\n !editorStateObj.root ||\n !editorStateObj.root.children ||\n editorStateObj.root.children.length === 0\n ) {\n return this.sanitizer.bypassSecurityTrustHtml('');\n }\n\n const state = tempEditor.parseEditorState(editorStateObj);\n tempEditor.setEditorState(state);\n\n let html = '';\n tempEditor.getEditorState().read(() => {\n html = $generateHtmlFromNodes(tempEditor, null);\n });\n return this.sanitizer.bypassSecurityTrustHtml(html);\n } catch (e) {\n console.error('Failed to parse Lexical state in preview:', e);\n return this.sanitizer.bypassSecurityTrustHtml(\n '<div>No content to display</div>'\n );\n }\n }\n\n // 2. Fallback to live editor state if no input data provided\n const state = this.liveEditorState();\n if (!state) {\n return this.sanitizer.bypassSecurityTrustHtml('');\n }\n\n let html = '';\n const editor = this.editorService.getEditor();\n\n if (editor) {\n editor.getEditorState().read(() => {\n html = $generateHtmlFromNodes(editor, null);\n });\n }\n\n return this.sanitizer.bypassSecurityTrustHtml(html);\n });\n\n protected readonly debugJson = computed(() => {\n if (!this.debug()) {\n return null;\n }\n\n const inputData = this.data();\n if (inputData) {\n return typeof inputData === 'string'\n ? inputData\n : JSON.stringify(inputData, null, 2);\n }\n\n const state = this.liveEditorState();\n return state ? JSON.stringify(state.toJSON(), null, 2) : 'No state available';\n });\n}\n","<div class=\"lexical-preview-container\">\n <!-- Render the visual HTML representation -->\n <div class=\"rendered-content\" [innerHTML]=\"renderedContent()\"></div>\n\n <!-- Render the debug JSON conditionally -->\n @if (debug()) {\n <div class=\"debug-container\">\n <h4>Editor State JSON (Preview)</h4>\n <pre>{{ debugJson() }}</pre>\n </div>\n }\n</div>\n","/*\n * Public API Surface of ngx-lexical-editor\n */\n\nexport * from './lib/index';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;;;;;;;MAiBa,aAAa,CAAA;AAChB,IAAA,MAAM;AACN,IAAA,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC;AACvB,IAAA,WAAW,GAAG,MAAM,CAAqB,IAAI,kFAAC;AAE/C,IAAA,IAAI;AACJ,IAAA,IAAI;AAEpB,IAAA,WAAA,GAAA;AACE,QAAA,MAAM,YAAY,GAAqB;AACrC,YAAA,SAAS,EAAE,kBAAkB;AAC7B,YAAA,KAAK,EAAE;AACL,gBAAA,SAAS,EAAE,mBAAmB;AAC9B,gBAAA,OAAO,EAAE;AACP,oBAAA,EAAE,EAAE,YAAY;AAChB,oBAAA,EAAE,EAAE,YAAY;AAChB,oBAAA,EAAE,EAAE,YAAY;AACjB,iBAAA;AACD,gBAAA,IAAI,EAAE;AACJ,oBAAA,EAAE,EAAE,YAAY;AAChB,oBAAA,EAAE,EAAE,YAAY;AAChB,oBAAA,QAAQ,EAAE,kBAAkB;AAC7B,iBAAA;AACD,gBAAA,IAAI,EAAE,oBAAoB;AAC1B,gBAAA,KAAK,EAAE,eAAe;AACtB,gBAAA,SAAS,EAAE,oBAAoB;AAC/B,gBAAA,QAAQ,EAAE,mBAAmB;AAC7B,gBAAA,IAAI,EAAE;AACJ,oBAAA,IAAI,EAAE,cAAc;AACpB,oBAAA,MAAM,EAAE,gBAAgB;AACxB,oBAAA,SAAS,EAAE,mBAAmB;AAC9B,oBAAA,aAAa,EAAE,uBAAuB;AACtC,oBAAA,IAAI,EAAE,qBAAqB;AAC5B,iBAAA;AACF,aAAA;AACD,YAAA,KAAK,EAAE;gBACL,WAAW;gBACX,SAAS;gBACT,QAAQ;gBACR,YAAY;gBACZ,QAAQ;gBACR,iBAAiB;gBACjB,SAAS;gBACT,YAAY;gBACZ,aAAa;gBACb,aAAa;gBACb,QAAQ;AACT,aAAA;AACD,YAAA,OAAO,EAAE,CAAC,KAAY,KAAI;AACxB,gBAAA,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC;YACxC,CAAC;AACD,YAAA,QAAQ,EAAE,IAAI;SACf;AAED,QAAA,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,MAAK;AACxB,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE;AAChC,YAAA,OAAO;AACL,kBAAE,KAAK,CAAC,MAAM;AACd,kBAAG;AACD,oBAAA,IAAI,EAAE;AACJ,wBAAA,QAAQ,EAAE,EAAE;AACZ,wBAAA,SAAS,EAAE,IAAI;AACf,wBAAA,MAAM,EAAE,EAAE;AACV,wBAAA,MAAM,EAAE,CAAC;AACT,wBAAA,IAAI,EAAE,MAAM;AACZ,wBAAA,OAAO,EAAE,CAAC;AACX,qBAAA;iBACwB;AAC/B,QAAA,CAAC,2EAAC;AAEF,QAAA,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,MAAK;AACxB,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE;YAChC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;AAC1B,gBAAA,OAAO,EAAE;YACX;YAEA,IAAI,IAAI,GAAG,EAAE;YACb,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,MAAK;AACrC,gBAAA,IAAI,GAAG,sBAAsB,CAAC,IAAI,CAAC,MAAO,CAAC;AAC7C,YAAA,CAAC,CAAC;AACF,YAAA,OAAO,IAAI;AACb,QAAA,CAAC,2EAAC;AAEF,QAAA,IAAI,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;AACtC,YAAA,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;QAC/B;IACF;IAEA,cAAc,GAAA;AACZ,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE;IACtC;IAEA,SAAS,GAAA;QACP,OAAO,IAAI,CAAC,MAAM;IACpB;AAEQ,IAAA,UAAU,CAAC,YAA8B,EAAA;AAC/C,QAAA,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,EAAE,WAAW,EAAE,KAAI;AACrD,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC;AACnC,QAAA,CAAC,CAAC;IACJ;AACD;;MCnFY,sBAAsB,CAAA;IACjB,eAAe,GAA4C,MAAM,EAAE;IACnE,kBAAkB,GAA6B,MAAM,EAAE;AACjC,IAAA,aAAa;AAClC,IAAA,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC;AACrC,IAAA,MAAM;AAEvB,IAAA,WAAA,GAAA;QACE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE;AAC5C,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;AACf,YAAA,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC;QAC/B;QAEA,MAAM,CAAC,MAAK;AACV,YAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;AACpD,YAAA,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;AACzD,QAAA,CAAC,CAAC;IACJ;IAEA,eAAe,GAAA;QACb,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC;IAC/D;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,IAAI,CAAC;IACnC;AAEU,IAAA,UAAU,CAAC,IAAqC,EAAA;QACxD,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,mBAAmB,EAAE,IAAI,CAAC;IACzD;AAEU,IAAA,aAAa,CAAC,WAA2B,EAAA;AACjD,QAAA,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAK;AACvB,YAAA,MAAM,SAAS,GAAG,aAAa,EAAE;AACjC,YAAA,IAAI,iBAAiB,CAAC,SAAS,CAAC,EAAE;gBAChC,cAAc,CAAC,SAAS,EAAE,MAAM,kBAAkB,CAAC,WAAW,CAAC,CAAC;YAClE;AACF,QAAA,CAAC,CAAC;IACJ;IAEU,eAAe,GAAA;AACvB,QAAA,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAK;AACvB,YAAA,MAAM,SAAS,GAAG,aAAa,EAAE;AACjC,YAAA,IAAI,iBAAiB,CAAC,SAAS,CAAC,EAAE;gBAChC,cAAc,CAAC,SAAS,EAAE,MAAM,oBAAoB,EAAE,CAAC;YACzD;AACF,QAAA,CAAC,CAAC;IACJ;AAEU,IAAA,UAAU,CAAC,QAAuC,EAAA;AAC1D,QAAA,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAK;YACvB,WAAW,CAAC,QAAQ,CAAC;AACvB,QAAA,CAAC,CAAC;IACJ;IAEU,eAAe,GAAA;AACvB,QAAA,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,MAAK;AACvB,YAAA,MAAM,SAAS,GAAG,aAAa,EAAE;AACjC,YAAA,IAAI,iBAAiB,CAAC,SAAS,CAAC,EAAE;gBAChC,cAAc,CAAC,SAAS,EAAE,MAAM,eAAe,EAAE,CAAC;YACpD;AACF,QAAA,CAAC,CAAC;IACJ;IAEU,WAAW,GAAA;AACnB,QAAA,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,oBAAoB,EAAE;AACjD,YAAA,IAAI,EAAE,GAAG;AACT,YAAA,OAAO,EAAE,GAAG;AACb,SAAA,CAAC;IACJ;wGArEW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,OAAA,EAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,EAAA,SAAA,EAFtB,CAAC,aAAa,CAAC,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,eAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,eAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EClC5B,q6MAiGA,EAAA,MAAA,EAAA,CAAA,2vFAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDlEY,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,OAAO,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,cAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,CAAA,EAAA,OAAA,EAAA,CAAA,cAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,kBAAkB,sIAAE,aAAa,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,IAAA,EAAA,UAAA,EAAA,OAAA,CAAA,EAAA,QAAA,EAAA,CAAA,iBAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;4FAKvD,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBARlC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gBAAgB,EAAA,UAAA,EACd,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,EAAE,OAAO,EAAE,kBAAkB,EAAE,aAAa,CAAC,EAAA,SAAA,EAGxD,CAAC,aAAa,CAAC,EAAA,QAAA,EAAA,q6MAAA,EAAA,MAAA,EAAA,CAAA,2vFAAA,CAAA,EAAA;;sBAKzB,SAAS;uBAAC,eAAe;;;MExBf,uBAAuB,CAAA;AAClC,IAAA,KAAK,GAAG,KAAK,CAAU,KAAK,4EAAC;AAE7B;;AAEG;AACH,IAAA,IAAI,GAAG,KAAK,CAAwC,IAAI,2EAAC;AAExC,IAAA,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC;AACrC,IAAA,SAAS,GAAG,MAAM,CAAC,YAAY,CAAC;;AAGhC,IAAA,eAAe,GAAG,IAAI,CAAC,aAAa,CAAC,cAAc,EAAE;AAEnD,IAAA,eAAe,GAAG,QAAQ,CAAW,MAAK;AAC3D,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE;;QAG7B,IAAI,SAAS,EAAE;;;;YAIb,MAAM,UAAU,GAAG,YAAY,CAAC;;gBAE9B,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,EAAE;AACrC,sBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,SAAS,EAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAC7D,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK;AAElB,sBAAE,EAAE;AACP,aAAA,CAAC;AAEF,YAAA,IAAI;AACF,gBAAA,MAAM,cAAc,GAClB,OAAO,SAAS,KAAK,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,SAAS;;;;AAKnE,gBAAA,IACE,CAAC,cAAc;oBACf,CAAC,cAAc,CAAC,IAAI;AACpB,oBAAA,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ;oBAC7B,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EACzC;oBACA,OAAO,IAAI,CAAC,SAAS,CAAC,uBAAuB,CAAC,EAAE,CAAC;gBACnD;gBAEA,MAAM,KAAK,GAAG,UAAU,CAAC,gBAAgB,CAAC,cAAc,CAAC;AACzD,gBAAA,UAAU,CAAC,cAAc,CAAC,KAAK,CAAC;gBAEhC,IAAI,IAAI,GAAG,EAAE;AACb,gBAAA,UAAU,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,MAAK;AACpC,oBAAA,IAAI,GAAG,sBAAsB,CAAC,UAAU,EAAE,IAAI,CAAC;AACjD,gBAAA,CAAC,CAAC;gBACF,OAAO,IAAI,CAAC,SAAS,CAAC,uBAAuB,CAAC,IAAI,CAAC;YACrD;YAAE,OAAO,CAAC,EAAE;AACV,gBAAA,OAAO,CAAC,KAAK,CAAC,2CAA2C,EAAE,CAAC,CAAC;gBAC7D,OAAO,IAAI,CAAC,SAAS,CAAC,uBAAuB,CAC3C,kCAAkC,CACnC;YACH;QACF;;AAGA,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE;QACpC,IAAI,CAAC,KAAK,EAAE;YACV,OAAO,IAAI,CAAC,SAAS,CAAC,uBAAuB,CAAC,EAAE,CAAC;QACnD;QAEA,IAAI,IAAI,GAAG,EAAE;QACb,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE;QAE7C,IAAI,MAAM,EAAE;AACV,YAAA,MAAM,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,MAAK;AAChC,gBAAA,IAAI,GAAG,sBAAsB,CAAC,MAAM,EAAE,IAAI,CAAC;AAC7C,YAAA,CAAC,CAAC;QACJ;QAEA,OAAO,IAAI,CAAC,SAAS,CAAC,uBAAuB,CAAC,IAAI,CAAC;AACrD,IAAA,CAAC,sFAAC;AAEiB,IAAA,SAAS,GAAG,QAAQ,CAAC,MAAK;AAC3C,QAAA,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE;AACjB,YAAA,OAAO,IAAI;QACb;AAEA,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE;QAC7B,IAAI,SAAS,EAAE;YACb,OAAO,OAAO,SAAS,KAAK;AAC1B,kBAAE;kBACA,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACxC;AAEA,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE;QACpC,OAAO,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,oBAAoB;AAC/E,IAAA,CAAC,gFAAC;wGA/FS,uBAAuB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAvB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,uBAAuB,uTAFvB,CAAC,aAAa,CAAC,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECb5B,8XAYA,wgBDFY,YAAY,EAAA,CAAA,EAAA,CAAA;;4FAKX,uBAAuB,EAAA,UAAA,EAAA,CAAA;kBARnC,SAAS;+BACE,iBAAiB,EAAA,UAAA,EACf,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,CAAC,EAAA,SAAA,EAGZ,CAAC,aAAa,CAAC,EAAA,QAAA,EAAA,8XAAA,EAAA,MAAA,EAAA,CAAA,idAAA,CAAA,EAAA;;;AEb5B;;AAEG;;ACFH;;AAEG;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-lexical-editor",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^21.2.0",
6
6
  "@angular/core": "^21.2.0",