11import type { UmbTiptapToolbarValue } from '../types.js' ;
2- import { css , customElement , html , map , nothing , property , state } from '@umbraco-cms/backoffice/external/lit' ;
2+ import { css , customElement , html , nothing , property , repeat } from '@umbraco-cms/backoffice/external/lit' ;
3+ import { debounce } from '@umbraco-cms/backoffice/utils' ;
34import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry' ;
45import { UmbExtensionsElementAndApiInitializer } from '@umbraco-cms/backoffice/extension-api' ;
56import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element' ;
@@ -9,18 +10,20 @@ import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/
910import '../cascading-menu-popover/cascading-menu-popover.element.js' ;
1011
1112/**
12- * Provides a sticky toolbar for the {@link UmbInputTiptapElement}
13- * @element umb-tiptap-toolbar
14- * @cssprop --umb-tiptap-edge-border-color - Defines the edge border color
15- * @cssprop --umb-tiptap-top - Defines the top value for the sticky toolbar
16- */
13+ * Provides a sticky toolbar for the {@link UmbInputTiptapElement}
14+ * @element umb-tiptap-toolbar
15+ * @cssprop --umb-tiptap-edge-border-color - Defines the edge border color
16+ * @cssprop --umb-tiptap-top - Defines the top value for the sticky toolbar
17+ */
1718@customElement ( 'umb-tiptap-toolbar' )
1819export class UmbTiptapToolbarElement extends UmbLitElement {
1920 #attached = false ;
21+
22+ #debouncer = debounce ( ( ) => this . requestUpdate ( ) , 100 ) ;
23+
2024 #extensionsController?: UmbExtensionsElementAndApiInitializer ;
2125
22- @state ( )
23- private _lookup ?: Map < string , unknown > ;
26+ #lookup: Map < string , unknown > = new Map ( ) ;
2427
2528 @property ( { type : Boolean , reflect : true } )
2629 readonly = false ;
@@ -58,12 +61,13 @@ export class UmbTiptapToolbarElement extends UmbLitElement {
5861 [ ] ,
5962 ( manifest ) => this . toolbar . flat ( 2 ) . includes ( manifest . alias ) ,
6063 ( extensionControllers ) => {
61- this . _lookup = new Map (
62- extensionControllers . map ( ( ext ) => {
64+ extensionControllers . forEach ( ( ext ) => {
65+ if ( ! this . #lookup . has ( ext . alias ) ) {
6366 ( ext . component as HTMLElement ) ?. setAttribute ( 'data-mark' , `action:tiptap-toolbar:${ ext . alias } ` ) ;
64- return [ ext . alias , ext . component ] ;
65- } ) ,
66- ) ;
67+ this . #lookup. set ( ext . alias , ext . component ) ;
68+ this . #debouncer( ) ;
69+ }
70+ } ) ;
6771 } ,
6872 undefined ,
6973 undefined ,
@@ -76,18 +80,23 @@ export class UmbTiptapToolbarElement extends UmbLitElement {
7680
7781 override render ( ) {
7882 if ( ! this . toolbar . flat ( 2 ) . length ) return nothing ;
83+ return this . #renderRows( this . toolbar ) ;
84+ }
7985
80- return map (
81- this . toolbar ,
82- ( row ) => html `
83- <div class= "row" >
84- ${ map (
85- row ,
86- ( group ) => html `<div class= "group" > ${ map ( group , ( alias ) => this . _lookup ?. get ( alias ) ?? nothing ) } </ div> ` ,
87- ) }
88- </ div>
89- ` ,
90- ) ;
86+ #renderRows( rows : UmbTiptapToolbarValue ) {
87+ return repeat ( rows , ( row ) => html `<div class= "row" > ${ this . #renderGroups( row ) } </ div> ` ) ;
88+ }
89+
90+ #renderGroups( groups : Array < Array < string > > ) {
91+ return repeat ( groups , ( group ) => html `<div class= "group" > ${ this . #renderActions( group ) } </ div> ` ) ;
92+ }
93+
94+ #renderActions( aliases : Array < string > ) {
95+ return repeat ( aliases , ( alias ) => this . #lookup?. get ( alias ) ?? this . #renderActionPlaceholder( ) ) ;
96+ }
97+
98+ #renderActionPlaceholder( ) {
99+ return html `<span class= "skeleton" role = "none"> </ span> ` ;
91100 }
92101
93102 static override readonly styles = css `
@@ -105,6 +114,7 @@ export class UmbTiptapToolbarElement extends UmbLitElement {
105114 bor der- to p- color : var(- - umb- tiptap- edge-bor der- color , var (- - uui- color - bor der));
106115 bor der- left- color : var(- - umb- tiptap- edge-bor der- color , var (- - uui- color - bor der));
107116 bor der- right- color : var(- - umb- tiptap- edge-bor der- color , var (- - uui- color - bor der));
117+ box- sizing: bor der- box;
108118
109119 background- color : var(- - uui- color - surface);
110120 color : var(- - color - text);
@@ -114,7 +124,7 @@ export class UmbTiptapToolbarElement extends UmbLitElement {
114124 flex- direction: column;
115125
116126 position: sticky;
117- to p: var(- - umb- tiptap- to p, -25px);
127+ to p: var(- - umb- tiptap- to p, -25px);
118128 left: 0;
119129 right: 0;
120130 padding: var(- - uui- size-3);
@@ -130,21 +140,32 @@ export class UmbTiptapToolbarElement extends UmbLitElement {
130140 flex-direction : row;
131141 flex-wrap : wrap;
132142
143+ min-height : var (--uui-size-12 , 36px );
144+
133145 .group {
134146 display : inline-flex;
135147 flex-wrap : wrap;
136148 align-items : stretch;
137149
150+ min-height : var (--uui-size-12 , 36px );
151+
138152 & : not (: last-child )::after {
139153 content : '' ;
140154 background-color : var (--uui-color-border );
141155 width : 1px ;
142156 place-self : center;
143- height : 22 px ;
157+ height : var ( --uui-size-7 , 21 px ) ;
144158 margin : 0 var (--uui-size-3 );
145159 }
146160 }
147161 }
162+
163+ .skeleton {
164+ background-color : var (--uui-color-background );
165+ height : var (--uui-size-12 , 36px );
166+ width : var (--uui-size-10 , 30px );
167+ margin-left : 1px ;
168+ }
148169 ` ;
149170}
150171
0 commit comments