@exmg/exm-markdown-editor 1.1.12 → 1.1.13

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/dist/actions.js CHANGED
@@ -9,15 +9,15 @@ export const toolbarActions = [
9
9
  },
10
10
  {
11
11
  name: 'header_one',
12
- icon: 'headerone',
12
+ icon: 'format_h1',
13
13
  },
14
14
  {
15
15
  name: 'header_two',
16
- icon: 'headertwo',
16
+ icon: 'format_h2',
17
17
  },
18
18
  {
19
19
  name: 'header_three',
20
- icon: 'headerthree',
20
+ icon: 'format_h3',
21
21
  },
22
22
  {
23
23
  name: 'unordered_list',
@@ -57,7 +57,7 @@ export const toolbarActions = [
57
57
  },
58
58
  {
59
59
  name: 'hr',
60
- icon: 'hr',
60
+ icon: 'horizontal_rule',
61
61
  },
62
62
  {
63
63
  name: 'table',
@@ -48,9 +48,14 @@ export declare class MarkdownEditorElementBase extends MarkdownBaseClass {
48
48
  toolbarIcons?: ToolbarIcons;
49
49
  markedExtension?: TokenizerAndRendererExtension[];
50
50
  required: boolean;
51
+ disabled: boolean;
51
52
  supportingText: string;
53
+ splitView: boolean;
54
+ fullScreen: boolean;
52
55
  editorElement?: HTMLDivElement;
56
+ editorContainerElement?: HTMLDivElement;
53
57
  previewElement?: Element | null;
58
+ isFullScreen?: boolean;
54
59
  preview: boolean;
55
60
  editorConfiguration: EditorConfiguration;
56
61
  editorActions: MarkdownActions;
@@ -69,13 +74,16 @@ export declare class MarkdownEditorElementBase extends MarkdownBaseClass {
69
74
  protected firstUpdated(): void;
70
75
  protected disconectedCallback(): void;
71
76
  protected getPreviewElement(): Element | null;
77
+ private handleEditorScroll;
78
+ private toggleFullscreen;
79
+ private handleExitFullScreen;
72
80
  codeMirrorSetup(): void;
73
81
  handleFocus(): void;
74
82
  handleBlur(): void;
75
83
  handleAction(e: CustomEvent): void;
76
84
  handleInsertImage(url: string): void;
77
85
  updateValue(newValue?: string): void;
78
- disablePreview(): void;
86
+ private handleContainerClick;
79
87
  protected render(): import("lit-html").TemplateResult<1>;
80
88
  }
81
89
  export {};
@@ -53,7 +53,11 @@ export class MarkdownEditorElementBase extends MarkdownBaseClass {
53
53
  this.toolbarActions = toolbarActions;
54
54
  this.toolbarIcons = toolbarIcons;
55
55
  this.required = false;
56
+ this.disabled = false;
56
57
  this.supportingText = '';
58
+ this.splitView = false;
59
+ this.fullScreen = false;
60
+ this.isFullScreen = false;
57
61
  this.preview = true;
58
62
  this.editorConfiguration = defaultConfiguration;
59
63
  this.editorActions = markdownActions;
@@ -89,7 +93,9 @@ export class MarkdownEditorElementBase extends MarkdownBaseClass {
89
93
  }
90
94
  firstUpdated() {
91
95
  var _a;
92
- this.codeMirrorSetup();
96
+ if (!this.disabled) {
97
+ this.codeMirrorSetup();
98
+ }
93
99
  this.previewElement = this.getPreviewElement();
94
100
  /* Height */
95
101
  if (this.previewElement.hasAttribute('slot')) {
@@ -113,6 +119,49 @@ export class MarkdownEditorElementBase extends MarkdownBaseClass {
113
119
  getPreviewElement() {
114
120
  return this.shadowRoot.querySelector('#preview');
115
121
  }
122
+ // CodeMirror types is not handling the scroll event type correct
123
+ handleEditorScroll(event) {
124
+ const previewContainer = this.renderRoot.querySelector('.preview');
125
+ const previewArea = this.renderRoot.querySelector('.preview-content');
126
+ if (!previewArea || !previewContainer || (!this.splitView && !this.isFullScreen)) {
127
+ return;
128
+ }
129
+ // DOMRectList of CodeMirrors scroll area
130
+ const scroller = event.display.scroller.getClientRects()[0];
131
+ // DOMRectList of CodeMirrors editor/content area
132
+ const sizer = event.display.sizer.getClientRects()[0];
133
+ // DOMRectList of previewArea
134
+ const preview = previewArea.getClientRects()[0];
135
+ // Get the total distance scroller in the editor
136
+ const scrolledDistance = scroller.y - sizer.y;
137
+ // Get the maximal scroll distance for the editor
138
+ const maxEditorScrollDistance = sizer.height - scroller.height;
139
+ // Get the maximal scroll distance for the preview
140
+ const maxPreviewScrollDistance = preview.height - scroller.height;
141
+ // Calculate the scroll progress bases on the above values
142
+ const scrollProgress = Math.min(scrolledDistance / maxEditorScrollDistance, 1);
143
+ previewContainer.scrollTo({
144
+ top: maxPreviewScrollDistance * scrollProgress,
145
+ });
146
+ }
147
+ toggleFullscreen() {
148
+ if (!this.editorContainerElement) {
149
+ return;
150
+ }
151
+ this.isFullScreen = !this.isFullScreen;
152
+ if (!document.fullscreenElement) {
153
+ this.editorContainerElement.requestFullscreen();
154
+ document.addEventListener('fullscreenchange', this.handleExitFullScreen.bind(this));
155
+ }
156
+ else {
157
+ document.exitFullscreen();
158
+ }
159
+ }
160
+ handleExitFullScreen() {
161
+ if (!document.fullscreenElement) {
162
+ this.isFullScreen = false;
163
+ }
164
+ }
116
165
  codeMirrorSetup() {
117
166
  if (!this.editorElement) {
118
167
  console.log('Error');
@@ -126,12 +175,13 @@ export class MarkdownEditorElementBase extends MarkdownBaseClass {
126
175
  ...this.editorConfiguration,
127
176
  value: this.value || '',
128
177
  });
129
- this.codeMirrorEditor.on('focus', (_editor) => {
178
+ this.codeMirrorEditor.on('focus', (_) => {
130
179
  this.handleFocus();
131
180
  });
132
181
  this.codeMirrorEditor.on('change', (editor) => {
133
182
  this.updateValue(editor.getValue());
134
183
  });
184
+ this.codeMirrorEditor.on('scroll', this.handleEditorScroll.bind(this));
135
185
  this.internalTextarea = this.codeMirrorEditor.getInputField();
136
186
  }
137
187
  handleFocus() {
@@ -173,14 +223,25 @@ export class MarkdownEditorElementBase extends MarkdownBaseClass {
173
223
  this.value = newValue || '';
174
224
  this.fire('change', this.value);
175
225
  }
176
- disablePreview() {
177
- this.preview = false;
226
+ handleContainerClick() {
227
+ if (!this.disabled) {
228
+ this.preview = false;
229
+ }
178
230
  }
179
231
  render() {
180
- const containerClasses = { 'has-label': !!this.label, 'preview-mode': this.preview };
232
+ const containerClasses = {
233
+ 'has-label': !!this.label,
234
+ 'preview-mode': this.preview,
235
+ 'split-view': (this.splitView || !!this.isFullScreen) && !this.disabled,
236
+ 'full-screen': this.fullScreen,
237
+ };
181
238
  const labelClasses = { 'not-empty': !!this.value, 'preview-mode': this.preview };
182
239
  return html `
183
- <div id="markdownEditorContainer" class="container ${classMap(containerClasses)}" @click=${this.disablePreview}>
240
+ <div
241
+ id="markdownEditorContainer"
242
+ class="container ${classMap(containerClasses)}"
243
+ @click=${this.handleContainerClick}
244
+ >
184
245
  <div class="background"></div>
185
246
  <div class="state-layer"></div>
186
247
  ${this.label
@@ -192,8 +253,21 @@ export class MarkdownEditorElementBase extends MarkdownBaseClass {
192
253
  .actions=${this.toolbarActions || []}
193
254
  .icons=${this.toolbarIcons || []}
194
255
  ></exm-markdown-editor-toolbar>
195
- <div id="editor" class="editor"></div>
196
- <div id="preview"></div>
256
+ <section class="label-bar">
257
+ <span>Editor</span>
258
+ <span>Preview</span>
259
+ </section>
260
+ <div class="editor" id="editor" @scroll=${(evt) => console.log(evt)}></div>
261
+ <div id="preview" class="preview"></div>
262
+ ${this.fullScreen
263
+ ? html `
264
+ <section class="full-screen-button">
265
+ <md-icon-button @click=${this.toggleFullscreen} title="Toggle for a full screen editor mode"
266
+ ><md-icon>${this.isFullScreen ? 'fullscreen_exit' : 'fullscreen'}</md-icon></md-icon-button
267
+ >
268
+ </section>
269
+ `
270
+ : nothing}
197
271
  <slot name="preview"></slot>
198
272
  ${this.supportingText ? html `<div class="supporting-text">${this.supportingText}</div>` : nothing}
199
273
  </div>
@@ -224,15 +298,30 @@ __decorate([
224
298
  __decorate([
225
299
  property({ type: Boolean, reflect: true })
226
300
  ], MarkdownEditorElementBase.prototype, "required", void 0);
301
+ __decorate([
302
+ property({ type: Boolean, reflect: true })
303
+ ], MarkdownEditorElementBase.prototype, "disabled", void 0);
227
304
  __decorate([
228
305
  property({ type: String, attribute: 'supporting-text' })
229
306
  ], MarkdownEditorElementBase.prototype, "supportingText", void 0);
307
+ __decorate([
308
+ property({ type: Boolean, attribute: 'split-view' })
309
+ ], MarkdownEditorElementBase.prototype, "splitView", void 0);
310
+ __decorate([
311
+ property({ type: Boolean, attribute: 'full-screen' })
312
+ ], MarkdownEditorElementBase.prototype, "fullScreen", void 0);
230
313
  __decorate([
231
314
  query('#editor')
232
315
  ], MarkdownEditorElementBase.prototype, "editorElement", void 0);
316
+ __decorate([
317
+ query('#markdownEditorContainer')
318
+ ], MarkdownEditorElementBase.prototype, "editorContainerElement", void 0);
233
319
  __decorate([
234
320
  state()
235
321
  ], MarkdownEditorElementBase.prototype, "previewElement", void 0);
322
+ __decorate([
323
+ state()
324
+ ], MarkdownEditorElementBase.prototype, "isFullScreen", void 0);
236
325
  __decorate([
237
326
  state(),
238
327
  observer(function (preview) {
package/dist/icons.d.ts CHANGED
@@ -1,6 +1,3 @@
1
1
  export declare const toolbarIcons: {
2
- headerone: import("lit-html").TemplateResult<1>;
3
- headertwo: import("lit-html").TemplateResult<1>;
4
- headerthree: import("lit-html").TemplateResult<1>;
5
- hr: import("lit-html").TemplateResult<1>;
2
+ example_icon: import("lit-html").TemplateResult<1>;
6
3
  };
package/dist/icons.js CHANGED
@@ -1,28 +1,5 @@
1
1
  import { html } from 'lit';
2
2
  export const toolbarIcons = {
3
- headerone: html `<svg>
4
- <g id="header-one">
5
- <path
6
- d="M11.5 13H5v5a1.5 1.5 0 0 1-3 0V5a1.5 1.5 0 0 1 3 0v5h6.5V5a1.5 1.5 0 0 1 3 0v13a1.5 1.5 0 0 1-3 0v-5zm8.5 6h-1.2v-6.535l-1.8.627v-1.046L19.82 11H20v8z"
7
- />
8
- </g>
9
- </svg>`,
10
- headertwo: html `<svg>
11
- <g id="header-two">
12
- <path
13
- d="M11.5 13H5v5a1.5 1.5 0 0 1-3 0V5a1.5 1.5 0 0 1 3 0v5h6.5V5a1.5 1.5 0 0 1 3 0v13a1.5 1.5 0 0 1-3 0v-5zm7.142 4.948H22V19h-4.87v-.917l2.353-2.8c.203-.234.367-.45.497-.634a3.77 3.77 0 0 0 .316-.51c.079-.154.13-.296.163-.431a1.762 1.762 0 0 0-.028-.898 1.244 1.244 0 0 0-.209-.4.967.967 0 0 0-.333-.265 1.057 1.057 0 0 0-.457-.093c-.203 0-.39.037-.541.111a1.074 1.074 0 0 0-.384.302c-.096.129-.175.283-.226.461a2.298 2.298 0 0 0-.073.536H17c.006-.327.056-.634.158-.924.107-.307.265-.572.474-.8a2.14 2.14 0 0 1 .768-.541A2.66 2.66 0 0 1 19.444 11c.36 0 .682.05.97.148.277.104.52.246.711.437.192.184.339.412.44.683.102.27.153.572.153.898 0 .24-.034.486-.107.726-.074.24-.175.48-.305.72s-.282.48-.463.72c-.18.24-.372.486-.587.726l-1.614 1.89z"
14
- />
15
- </g>
16
- </svg>`,
17
- headerthree: html `<svg>
18
- <g id="header-three">
19
- <path
20
- d="M11.5 13H5v5a1.5 1.5 0 0 1-3 0V5a1.5 1.5 0 0 1 3 0v5h6.5V5a1.5 1.5 0 0 1 3 0v13a1.5 1.5 0 0 1-3 0v-5zm9.815 2.217c.165.125.292.269.393.427.102.164.171.335.222.499.045.184.07.374.07.565 0 .361-.063.69-.19.972a1.997 1.997 0 0 1-.533.722 2.185 2.185 0 0 1-.8.447c-.31.098-.64.151-1.002.151-.33 0-.641-.046-.94-.138a2.334 2.334 0 0 1-.786-.414 1.982 1.982 0 0 1-.546-.69 2.158 2.158 0 0 1-.203-.952h1.263c0 .171.031.329.089.473.057.145.14.263.247.368.108.105.235.184.387.236a1.4 1.4 0 0 0 .508.086c.387 0 .698-.105.92-.322.222-.217.336-.525.336-.933a1.55 1.55 0 0 0-.102-.571 1 1 0 0 0-.279-.4 1.174 1.174 0 0 0-.438-.23 2.212 2.212 0 0 0-.577-.073h-.749V14.41h.743c.215 0 .406-.026.564-.086.16-.059.292-.137.4-.243a.966.966 0 0 0 .241-.374c.051-.144.076-.309.076-.486 0-.374-.088-.663-.279-.867-.19-.204-.476-.309-.863-.309-.171 0-.323.027-.463.08-.14.052-.26.124-.368.216a.998.998 0 0 0-.241.341 1.127 1.127 0 0 0-.089.454H17.07c0-.302.057-.591.184-.848.114-.262.285-.486.495-.676.21-.19.463-.342.761-.453.292-.105.616-.158.965-.158.355 0 .685.046.97.131.299.092.552.237.762.42.216.191.38.421.495.697.12.276.177.598.177.959 0 .158-.019.322-.07.48-.044.164-.12.315-.215.466a2.005 2.005 0 0 1-.87.748c.235.086.432.191.59.316z"
21
- />
22
- </g>
23
- </svg>`,
24
- hr: html `<svg>
25
- <g id="trending-flat"><path d="M22 14h18v-2H3v2z"></path></g>
26
- </svg>`,
3
+ example_icon: html `Some svg here`,
27
4
  };
28
5
  //# sourceMappingURL=icons.js.map
@@ -23,10 +23,12 @@ export const style = css `
23
23
  }
24
24
 
25
25
  .container {
26
+ --label-height: 0px;
27
+
26
28
  display: grid;
27
29
  position: relative;
28
- grid-template-columns: 100%;
29
- grid-template-rows: 0px 56px 1fr auto;
30
+ grid-template-columns: repeat(2, 1fr);
31
+ grid-template-rows: var(--label-height) auto auto 1fr auto;
30
32
  transition: grid-template-rows 0.2s ease;
31
33
  border-top-right-radius: 4px;
32
34
  border-top-left-radius: 4px;
@@ -35,12 +37,95 @@ export const style = css `
35
37
  }
36
38
 
37
39
  .container.has-label {
38
- grid-template-rows: 2rem 56px 1fr;
40
+ --label-height: 2rem;
41
+ }
42
+
43
+ .container.preview-mode:hover .state-layer {
44
+ cursor: text;
45
+ }
46
+
47
+ .container.split-view .preview,
48
+ .container.preview-mode .preview {
49
+ display: block;
50
+ }
51
+
52
+ .container.preview-mode:not(.split-view) .editor {
53
+ display: none;
54
+ }
55
+
56
+ .container.preview-mode:not(.split-view) exm-markdown-editor-toolbar {
57
+ display: none;
58
+ }
59
+
60
+ .container.split-view .preview {
61
+ grid-area: 4/2/5/3;
62
+ border-left: 1px solid var(--md-sys-color-surface-variant);
63
+ background-color: var(--editor-code-background-color, var(--md-sys-color-surface-container-highest));
64
+ }
65
+
66
+ .container.split-view .editor {
67
+ grid-area: 4/1/5/2;
68
+ }
69
+
70
+ .container.split-view .label-bar {
71
+ display: grid;
72
+ }
73
+
74
+ .preview {
75
+ grid-area: 2/1/5/3;
76
+ display: none;
77
+ position: relative;
78
+ overflow: scroll;
79
+ }
80
+
81
+ .editor {
82
+ grid-area: 3/1/5/3;
83
+ position: relative;
84
+ overflow: hidden;
85
+ }
86
+
87
+ #editor {
88
+ overflow: hidden;
89
+ }
90
+
91
+ exm-markdown-editor-toolbar {
92
+ grid-area: 2/1/3/3;
93
+ }
94
+
95
+ .container.split-view exm-markdown-editor-toolbar {
96
+ padding-right: 4rem;
97
+ }
98
+
99
+ .full-screen-button {
100
+ position: absolute;
101
+ top: calc(var(--label-height) + 0.5rem);
102
+ right: 1rem;
103
+ }
104
+
105
+ .container.preview-mode:not(.split-view) .full-screen-button {
106
+ display: none;
107
+ }
108
+
109
+ .label-bar {
110
+ display: none;
111
+ grid-template-columns: repeat(2, 1fr);
112
+ grid-area: 3/1/4/3;
113
+ border-bottom: 1px solid var(--md-sys-color-surface-variant);
114
+ background-color: var(--md-sys-color-surface-container);
115
+ }
116
+
117
+ .label-bar span {
118
+ padding: 0.5rem 1rem;
39
119
  }
40
120
 
121
+ .label-bar span + span {
122
+ border-left: 1px solid var(--md-sys-color-surface-variant);
123
+ }
124
+
125
+ /* Background and state-layer stuff */
41
126
  .background,
42
127
  .state-layer {
43
- grid-area: 1/1/4/2;
128
+ grid-area: 1/1/5/3;
44
129
  }
45
130
 
46
131
  .background {
@@ -62,20 +147,9 @@ export const style = css `
62
147
  height: 3px;
63
148
  }
64
149
 
65
- .container.preview-mode {
66
- grid-template-rows: 0px 0.3rem 1fr auto;
67
- }
68
-
69
- .container.preview-mode.has-label {
70
- grid-template-rows: 2rem 0.3rem 1fr auto;
71
- }
72
-
73
- .container.preview-mode:hover .state-layer {
74
- cursor: text;
75
- }
76
-
150
+ /* The form label style */
77
151
  label {
78
- grid-area: 1/1/2/2;
152
+ grid-area: 1/1/2/3;
79
153
  }
80
154
 
81
155
  label[for='markdownEditorContainer'],
@@ -98,22 +172,9 @@ export const style = css `
98
172
  font-size: 1rem;
99
173
  }
100
174
 
101
- exm-markdown-editor-toolbar {
102
- grid-area: 2/1/3/2;
103
- visibility: visible;
104
- transition:
105
- visibility 0s,
106
- opacity 0.5s linear;
107
- opacity: 1;
108
- }
109
-
110
- .container.preview-mode exm-markdown-editor-toolbar {
111
- visibility: hidden;
112
- opacity: 0;
113
- }
114
-
175
+ /* Supporting text, also know as Description */
115
176
  .supporting-text {
116
- grid-area: 4/1/5/2;
177
+ grid-area: 5/1/6/3;
117
178
 
118
179
  color: var(--md-filled-field-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));
119
180
  display: flex;
@@ -137,52 +198,13 @@ export const style = css `
137
198
  padding-top: var(--md-filled-field-supporting-text-top-space, 4px);
138
199
  }
139
200
 
140
- #preview {
141
- grid-area: 3/1/4/2;
142
- display: none;
143
- position: relative;
144
- overflow: scroll;
145
- }
146
-
147
- .preview-content {
148
- height: 100%;
149
- overflow: scroll;
150
- }
151
-
152
- .container.preview-mode #preview {
153
- display: block;
154
- }
155
-
156
- .editor {
157
- grid-area: 3/1/4/2;
158
- position: relative;
159
- overflow: hidden;
160
- }
161
-
162
- .container.preview-mode .editor {
163
- display: none;
164
- }
165
-
166
201
  .CodeMirror {
167
202
  height: 100%;
168
203
  overflow: scroll;
169
204
  }
170
205
 
171
- slot[name='preview'] {
172
- display: none;
173
- grid-row-start: 3;
174
- }
175
-
176
- .container.preview-mode slot[name='preview'] {
177
- display: block;
178
- }
179
-
180
- ::slotted([slot='preview']) {
181
- overflow: scroll;
182
- }
183
-
184
206
  .preview-content {
185
- padding: 0 1rem;
207
+ padding: 1rem;
186
208
  }
187
209
  `;
188
210
  //# sourceMappingURL=exm-markdown-editor-css.js.map
@@ -2,11 +2,13 @@ import { css } from 'lit';
2
2
  export const style = css `
3
3
  :host {
4
4
  display: block;
5
+ border-bottom: 1px solid var(--md-sys-color-surface-variant);
5
6
  }
6
7
 
7
8
  .toolbar-container {
8
9
  padding: 0.5rem 1rem;
9
10
  display: flex;
11
+ flex-wrap: wrap;
10
12
  }
11
13
 
12
14
  md-icon-button:not(:first) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exmg/exm-markdown-editor",
3
- "version": "1.1.12",
3
+ "version": "1.1.13",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -52,5 +52,5 @@
52
52
  "publishConfig": {
53
53
  "access": "public"
54
54
  },
55
- "gitHead": "1478e41cdcc8b109995cf78f8ccfadd7699c22aa"
55
+ "gitHead": "f482775e785f3e1fe8dde56cf7614428ff9a7e80"
56
56
  }