1
1
import type { UmbTiptapExtensionApi } from '../../extensions/types.js' ;
2
2
import type { UmbTiptapToolbarValue } from '../types.js' ;
3
- import { css , customElement , html , property , state , when } from '@umbraco-cms/backoffice/external/lit' ;
3
+ import { css , customElement , html , property , state , unsafeCSS , when } from '@umbraco-cms/backoffice/external/lit' ;
4
4
import { loadManifestApi } from '@umbraco-cms/backoffice/extension-api' ;
5
5
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry' ;
6
6
import { Editor } from '@umbraco-cms/backoffice/external/tiptap' ;
7
7
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event' ;
8
8
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element' ;
9
9
import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation' ;
10
+ import type { CSSResultGroup } from '@umbraco-cms/backoffice/external/lit' ;
11
+ import type { Extensions } from '@umbraco-cms/backoffice/external/tiptap' ;
10
12
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor' ;
11
13
12
14
import './tiptap-hover-menu.element.js' ;
@@ -45,6 +47,9 @@ export class UmbInputTiptapElement extends UmbFormControlMixin<string, typeof Um
45
47
@state ( )
46
48
private readonly _extensions : Array < UmbTiptapExtensionApi > = [ ] ;
47
49
50
+ @state ( )
51
+ private _styles : Array < CSSResultGroup > = [ ] ;
52
+
48
53
@state ( )
49
54
_toolbar : UmbTiptapToolbarValue = [ [ [ ] ] ] ;
50
55
@@ -100,14 +105,24 @@ export class UmbInputTiptapElement extends UmbFormControlMixin<string, typeof Um
100
105
101
106
this . _toolbar = this . configuration ?. getValueByAlias < UmbTiptapToolbarValue > ( 'toolbar' ) ?? [ [ [ ] ] ] ;
102
107
103
- const extensions = this . _extensions
104
- . map ( ( ext ) => ext . getTiptapExtensions ( { configuration : this . configuration } ) )
105
- . flat ( ) ;
108
+ const tiptapExtensions : Extensions = [ ] ;
109
+
110
+ this . _extensions . forEach ( ( ext ) => {
111
+ const tiptapExt = ext . getTiptapExtensions ( { configuration : this . configuration } ) ;
112
+ if ( tiptapExt ?. length ) {
113
+ tiptapExtensions . push ( ...tiptapExt ) ;
114
+ }
115
+
116
+ const styles = ext . getStyles ( ) ;
117
+ if ( styles ) {
118
+ this . _styles . push ( styles ) ;
119
+ }
120
+ } ) ;
106
121
107
122
this . _editor = new Editor ( {
108
123
element : element ,
109
124
editable : ! this . readonly ,
110
- extensions : extensions ,
125
+ extensions : tiptapExtensions ,
111
126
content : this . #value,
112
127
onBeforeCreate : ( { editor } ) => {
113
128
this . _extensions . forEach ( ( ext ) => ext . setEditor ( editor ) ) ;
@@ -125,6 +140,7 @@ export class UmbInputTiptapElement extends UmbFormControlMixin<string, typeof Um
125
140
! this . _editor && ! this . _extensions ?. length ,
126
141
( ) => html `<div id= "loader" > <uui- loader> </ uui- loader> </ div> ` ,
127
142
( ) => html `
143
+ ${ this . #renderStyles( ) }
128
144
<umb- tiptap- to olbar
129
145
.toolbar = ${ this . _toolbar }
130
146
.editor = ${ this . _editor }
@@ -136,6 +152,15 @@ export class UmbInputTiptapElement extends UmbFormControlMixin<string, typeof Um
136
152
` ;
137
153
}
138
154
155
+ #renderStyles( ) {
156
+ if ( ! this . _styles ?. length ) return ;
157
+ return html `
158
+ <style>
159
+ ${ this . _styles . map ( ( style ) => unsafeCSS ( style ) ) }
160
+ </ style>
161
+ ` ;
162
+ }
163
+
139
164
static override readonly styles = [
140
165
css `
141
166
: host {
@@ -158,23 +183,6 @@ export class UmbInputTiptapElement extends UmbFormControlMixin<string, typeof Um
158
183
justify-content : center;
159
184
}
160
185
161
- .tiptap {
162
- height : 100% ;
163
- width : 100% ;
164
- outline : none;
165
- white-space : pre-wrap;
166
- min-width : 0 ;
167
- }
168
-
169
- .tiptap .is-editor-empty : first-child ::before {
170
- color : var (--uui-color-text );
171
- opacity : 0.55 ;
172
- content : attr (data-placeholder);
173
- float : left;
174
- height : 0 ;
175
- pointer-events : none;
176
- }
177
-
178
186
# editor {
179
187
/* Required as overflow is set to auto, so that the scrollbars don't appear. */
180
188
display : flex;
@@ -189,6 +197,24 @@ export class UmbInputTiptapElement extends UmbFormControlMixin<string, typeof Um
189
197
height : 100% ;
190
198
width : 100% ;
191
199
200
+ .tiptap {
201
+ height : 100% ;
202
+ width : 100% ;
203
+ outline : none;
204
+ white-space : pre-wrap;
205
+ min-width : 0 ;
206
+
207
+ .is-editor-empty : first-child ::before {
208
+ color : var (--uui-color-text );
209
+ opacity : 0.55 ;
210
+ content : attr (data-placeholder);
211
+ float : left;
212
+ height : 0 ;
213
+ pointer-events : none;
214
+ }
215
+ }
216
+
217
+ /* The following styles are required for the "StarterKit" extension. */
192
218
pre {
193
219
background-color : var (--uui-color-surface-alt );
194
220
padding : var (--uui-size-space-2 ) var (--uui-size-space-4 );
@@ -220,118 +246,12 @@ export class UmbInputTiptapElement extends UmbFormControlMixin<string, typeof Um
220
246
margin-bottom : 0.5em ;
221
247
}
222
248
223
- figure {
224
- > p ,
225
- img {
226
- pointer-events : none;
227
- margin : 0 ;
228
- padding : 0 ;
229
- }
230
-
231
- & .ProseMirror-selectednode {
232
- outline : 3px solid var (--uui-color-focus );
233
- }
234
- }
235
-
236
- img {
237
- & .ProseMirror-selectednode {
238
- outline : 3px solid var (--uui-color-focus );
239
- }
240
- }
241
-
242
249
li {
243
250
> p {
244
251
margin : 0 ;
245
252
padding : 0 ;
246
253
}
247
254
}
248
-
249
- .umb-embed-holder {
250
- display : inline-block;
251
- position : relative;
252
- }
253
-
254
- .umb-embed-holder > * {
255
- user-select : none;
256
- pointer-events : none;
257
- }
258
-
259
- .umb-embed-holder .ProseMirror-selectednode {
260
- outline : 2px solid var (--uui-palette-spanish-pink-light );
261
- }
262
-
263
- .umb-embed-holder ::before {
264
- z-index : 1000 ;
265
- width : 100% ;
266
- height : 100% ;
267
- position : absolute;
268
- content : ' ' ;
269
- }
270
-
271
- .umb-embed-holder .ProseMirror-selectednode ::before {
272
- background : rgba (0 , 0 , 0 , 0.025 );
273
- }
274
-
275
- /* Table-specific styling */
276
- .tableWrapper {
277
- margin : 1.5rem 0 ;
278
- overflow-x : auto;
279
-
280
- table {
281
- border-collapse : collapse;
282
- margin : 0 ;
283
- overflow : hidden;
284
- table-layout : fixed;
285
- width : 100% ;
286
-
287
- td ,
288
- th {
289
- border : 1px solid var (--uui-color-border );
290
- box-sizing : border-box;
291
- min-width : 1em ;
292
- padding : 6px 8px ;
293
- position : relative;
294
- vertical-align : top;
295
-
296
- > * {
297
- margin-bottom : 0 ;
298
- }
299
- }
300
-
301
- th {
302
- background-color : var (--uui-color-background );
303
- font-weight : bold;
304
- text-align : left;
305
- }
306
-
307
- .selectedCell : after {
308
- background : var (--uui-color-surface-emphasis );
309
- content : '' ;
310
- left : 0 ;
311
- right : 0 ;
312
- top : 0 ;
313
- bottom : 0 ;
314
- pointer-events : none;
315
- position : absolute;
316
- z-index : 2 ;
317
- }
318
-
319
- .column-resize-handle {
320
- background-color : var (--uui-color-default );
321
- bottom : -2px ;
322
- pointer-events : none;
323
- position : absolute;
324
- right : -2px ;
325
- top : 0 ;
326
- width : 3px ;
327
- }
328
- }
329
-
330
- .resize-cursor {
331
- cursor : ew-resize;
332
- cursor : col-resize;
333
- }
334
- }
335
255
}
336
256
` ,
337
257
] ;
0 commit comments