kempo-ui 0.3.10 → 0.3.12

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.
@@ -1,4 +1,4 @@
1
- import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"../lit-all.min.js";import{boolTrueFalse as i}from"../utils/propConverters.js";import"./FocusCapture.js";import"./Icon.js";export default class o extends e{static properties={state:{type:String,reflect:!0},side:{type:String,reflect:!0},main:{type:String,reflect:!0},overlayClose:{type:Boolean,reflect:!0,attribute:"overlay-close",converter:i},escClose:{type:Boolean,reflect:!0,attribute:"esc-close",converter:i},persistentId:{type:String,reflect:!0,attribute:"persistent-id"}};constructor(){super(),this.state="offscreen",this.side="left",this.main="overlay",this.overlayClose=!0,this.escClose=!0,this.persistentId=null}overlayClick=()=>{this.overlayClose&&this.hide()};handleKeyDown=e=>{this.escClose&&"Escape"===e.key&&this.hide()};updated(e){if(super.updated(e),e.has("persistentId")&&this.persistentId&&window?.localStorage){const e=window.localStorage.getItem(`aside-persistent-id-${this.persistentId}`);e&&(this.state=e)}if(e.has("state")){const t=e.get("state");"offscreen"===this.state||"offscreen"!==t&&void 0!==t?"offscreen"===this.state&&void 0!==t&&"offscreen"!==t&&document.removeEventListener("keydown",this.handleKeyDown):document.addEventListener("keydown",this.handleKeyDown),"overlay"===this.main&&("expanded"===this.state?document.body.classList.add("no-scroll"):document.body.classList.remove("no-scroll"));const s="offscreen"===this.state?0:this.getTargetWidth(this.state),a={aside:this,state:this.state,main:this.main,width:s};this.dispatchEvent(new CustomEvent("aside_state_change",{detail:a})),window.dispatchEvent(new CustomEvent("aside_state_change",{detail:a})),this.inert="offscreen"===this.state,this.persistentId&&window?.localStorage&&window.localStorage.setItem(`aside-persistent-id-${this.persistentId}`,this.state)}}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("keydown",this.handleKeyDown),document.body.classList.remove("no-scroll");const e={aside:this,state:"offscreen",main:this.main,width:0};this.dispatchEvent(new CustomEvent("aside_state_change",{detail:e})),window.dispatchEvent(new CustomEvent("aside_state_change",{detail:e}))}expand=()=>this.state="expanded";collapse=()=>this.state="collapsed";hide=()=>this.state="offscreen";toggle=()=>{this.state="expanded"===this.state?"offscreen":"expanded"};getTargetWidth(e){const t=parseFloat(getComputedStyle(document.documentElement).fontSize),s="collapsed"===e?"--collapsed-width":"--width",a=getComputedStyle(this).getPropertyValue(s).trim();return(a?parseFloat(a):"collapsed"===e?3.5:20)*t}render(){const e=t`<aside><slot></slot></aside>`;return"overlay"===this.main?t`
1
+ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"../lit-all.min.js";import{boolTrueFalse as i}from"../utils/propConverters.js";import"./Dropdown.js";import"./FocusCapture.js";import"./Icon.js";export default class n extends e{static properties={state:{type:String,reflect:!0},side:{type:String,reflect:!0},main:{type:String,reflect:!0},overlayClose:{type:Boolean,reflect:!0,attribute:"overlay-close",converter:i},escClose:{type:Boolean,reflect:!0,attribute:"esc-close",converter:i},persistentId:{type:String,reflect:!0,attribute:"persistent-id"}};constructor(){super(),this.state="offscreen",this.side="left",this.main="overlay",this.overlayClose=!0,this.escClose=!0,this.persistentId=null}overlayClick=()=>{this.overlayClose&&this.hide()};handleKeyDown=e=>{this.escClose&&"Escape"===e.key&&this.hide()};updated(e){if(super.updated(e),e.has("persistentId")&&this.persistentId&&window?.localStorage){const e=window.localStorage.getItem(`aside-persistent-id-${this.persistentId}`);e&&(this.state=e)}if(e.has("state")){const t=e.get("state");"offscreen"===this.state||"offscreen"!==t&&void 0!==t?"offscreen"===this.state&&void 0!==t&&"offscreen"!==t&&document.removeEventListener("keydown",this.handleKeyDown):document.addEventListener("keydown",this.handleKeyDown),"overlay"===this.main&&("expanded"===this.state?document.body.classList.add("no-scroll"):document.body.classList.remove("no-scroll"));const s="offscreen"===this.state?0:this.getTargetWidth(this.state),a={aside:this,state:this.state,main:this.main,width:s};this.dispatchEvent(new CustomEvent("aside_state_change",{detail:a})),window.dispatchEvent(new CustomEvent("aside_state_change",{detail:a})),this.inert="offscreen"===this.state,this.persistentId&&window?.localStorage&&window.localStorage.setItem(`aside-persistent-id-${this.persistentId}`,this.state)}}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("keydown",this.handleKeyDown),document.body.classList.remove("no-scroll");const e={aside:this,state:"offscreen",main:this.main,width:0};this.dispatchEvent(new CustomEvent("aside_state_change",{detail:e})),window.dispatchEvent(new CustomEvent("aside_state_change",{detail:e}))}expand=()=>this.state="expanded";collapse=()=>this.state="collapsed";hide=()=>this.state="offscreen";toggle=()=>{this.state="expanded"===this.state?"offscreen":"expanded"};getTargetWidth(e){const t=parseFloat(getComputedStyle(document.documentElement).fontSize),s="collapsed"===e?"--collapsed-width":"--width",a=getComputedStyle(this).getPropertyValue(s).trim();return(a?parseFloat(a):"collapsed"===e?3.5:20)*t}render(){const e=t`<aside><slot></slot></aside>`;return"overlay"===this.main?t`
2
2
  <k-focus-capture>
3
3
  <div id="container">
4
4
  <button id="overlay-btn" @click=${this.overlayClick}>
@@ -121,10 +121,10 @@ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"
121
121
  }
122
122
  :host([main="push"][state="collapsed"]) aside {
123
123
  width: var(--collapsed-width);
124
- transform: translateX(0);
124
+ transform: none;
125
125
  }
126
126
  :host([main="push"][state="expanded"]) aside {
127
- transform: translateX(0);
127
+ transform: none;
128
128
  }
129
129
  :host([main="overlay"]) aside {
130
130
  width: var(--width);
@@ -133,15 +133,15 @@ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"
133
133
  transform: translateX(-100%);
134
134
  }
135
135
  :host([main="overlay"][state="expanded"]) aside {
136
- transform: translateX(0);
136
+ transform: none;
137
137
  }
138
138
  :host([main="overlay"][side="right"]) aside {
139
139
  transform: translateX(100%);
140
140
  }
141
141
  :host([main="overlay"][side="right"][state="expanded"]) aside {
142
- transform: translateX(0);
142
+ transform: none;
143
143
  }
144
- `}customElements.define("k-aside",o);class n extends e{static properties={icon:{type:String},href:{type:String},active:{type:Boolean,reflect:!0},collapsed:{type:Boolean,reflect:!0},"no-expand":{type:Boolean,attribute:"no-expand"},"hide-when-collapsed":{type:Boolean,attribute:"hide-when-collapsed"}};constructor(){super(),this.icon="",this.href="#",this.active=!1,this.collapsed=!1,this["no-expand"]=!1,this["hide-when-collapsed"]=!1}connectedCallback(){super.connectedCallback(),this.aside=this.closest("k-aside"),this.aside&&(this.collapsed="collapsed"===this.aside.state,this.aside.addEventListener("aside_state_change",this.handleStateChange))}disconnectedCallback(){super.disconnectedCallback(),this.aside&&this.aside.removeEventListener("aside_state_change",this.handleStateChange)}handleStateChange=e=>{const{state:t}=e.detail;"collapsed"===t?this.collapsed=!0:"expanded"===t&&(this.collapsed=!1)};handleClick=e=>{this.collapsed&&!this["no-expand"]&&this.aside&&(e.preventDefault(),this.aside.expand())};render(){return t`
144
+ `}customElements.define("k-aside",n);class o extends e{static properties={icon:{type:String},href:{type:String},active:{type:Boolean,reflect:!0},collapsed:{type:Boolean,reflect:!0},"no-expand":{type:Boolean,attribute:"no-expand"},"hide-when-collapsed":{type:Boolean,attribute:"hide-when-collapsed"}};constructor(){super(),this.icon="",this.href="#",this.active=!1,this.collapsed=!1,this["no-expand"]=!1,this["hide-when-collapsed"]=!1}connectedCallback(){super.connectedCallback(),this.aside=this.closest("k-aside"),this.inMenu=!!this.closest("k-aside-menu"),this.aside&&!this.inMenu&&(this.collapsed="collapsed"===this.aside.state,this.aside.addEventListener("aside_state_change",this.handleStateChange))}disconnectedCallback(){super.disconnectedCallback(),this.aside&&this.aside.removeEventListener("aside_state_change",this.handleStateChange)}handleStateChange=e=>{const{state:t}=e.detail;"collapsed"===t?this.collapsed=!0:"expanded"===t&&(this.collapsed=!1)};handleClick=e=>{this.collapsed&&!this["no-expand"]&&this.aside&&(e.preventDefault(),this.aside.expand())};render(){return t`
145
145
  <a href="${this.href}" class="item ${this.active?"active bg-primary":""}" @click=${this.handleClick}>
146
146
  ${this.icon?t`<k-icon name="${this.icon}"></k-icon>`:this.collapsed?t`<k-icon name="dot"></k-icon>`:a}
147
147
  ${this.collapsed?a:t`<span class="label"><slot></slot></span>`}
@@ -183,7 +183,7 @@ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"
183
183
  overflow: hidden;
184
184
  text-overflow: ellipsis;
185
185
  }
186
- `}class d extends e{static properties={collapsed:{type:Boolean,reflect:!0}};constructor(){super(),this.collapsed=!1}connectedCallback(){super.connectedCallback(),this.aside=this.closest("k-aside"),this.aside&&(this.collapsed="collapsed"===this.aside.state,this.aside.addEventListener("aside_state_change",this.handleStateChange))}disconnectedCallback(){super.disconnectedCallback(),this.aside&&this.aside.removeEventListener("aside_state_change",this.handleStateChange)}handleStateChange=e=>{const{state:t}=e.detail;"collapsed"===t?this.collapsed=!0:"expanded"===t&&(this.collapsed=!1)};render(){return this.collapsed?t`<hr>`:t`<div class="label"><slot></slot></div>`}static styles=s`
186
+ `}class r extends e{static properties={collapsed:{type:Boolean,reflect:!0}};constructor(){super(),this.collapsed=!1}connectedCallback(){super.connectedCallback(),this.aside=this.closest("k-aside"),this.aside&&(this.collapsed="collapsed"===this.aside.state,this.aside.addEventListener("aside_state_change",this.handleStateChange))}disconnectedCallback(){super.disconnectedCallback(),this.aside&&this.aside.removeEventListener("aside_state_change",this.handleStateChange)}handleStateChange=e=>{const{state:t}=e.detail;"collapsed"===t?this.collapsed=!0:"expanded"===t&&(this.collapsed=!1)};render(){return this.collapsed?t`<hr>`:t`<div class="label"><slot></slot></div>`}static styles=s`
187
187
  :host {
188
188
  display: block;
189
189
  margin: var(--spacer_h) 0;
@@ -208,14 +208,21 @@ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"
208
208
  :host([collapsed]) hr {
209
209
  margin: var(--spacer_h) 0;
210
210
  }
211
- `}class r extends e{static properties={icon:{type:String},label:{type:String},open:{type:Boolean,reflect:!0},collapsed:{type:Boolean,reflect:!0},"no-expand":{type:Boolean,attribute:"no-expand"},"hide-when-collapsed":{type:Boolean,attribute:"hide-when-collapsed"}};constructor(){super(),this.icon="",this.label="",this.open=!1,this.collapsed=!1,this["no-expand"]=!1,this["hide-when-collapsed"]=!1}connectedCallback(){super.connectedCallback(),this.aside=this.closest("k-aside"),this.aside&&(this.collapsed="collapsed"===this.aside.state,this.aside.addEventListener("aside_state_change",this.handleStateChange))}disconnectedCallback(){super.disconnectedCallback(),this.aside&&this.aside.removeEventListener("aside_state_change",this.handleStateChange)}handleStateChange=e=>{const{state:t}=e.detail;"collapsed"===t?(this.collapsed=!0,this.open=!1):"expanded"===t&&(this.collapsed=!1)};toggleMenu=()=>{this.collapsed&&!this["no-expand"]&&this.aside?this.aside.expand():this.collapsed||(this.open=!this.open)};render(){return t`
211
+ `}class d extends e{static properties={icon:{type:String},label:{type:String},open:{type:Boolean,reflect:!0},collapsed:{type:Boolean,reflect:!0},side:{type:String},"no-expand":{type:Boolean,attribute:"no-expand"},"hide-when-collapsed":{type:Boolean,attribute:"hide-when-collapsed"}};constructor(){super(),this.icon="",this.label="",this.open=!1,this.collapsed=!1,this.side="left",this["no-expand"]=!1,this["hide-when-collapsed"]=!1}connectedCallback(){super.connectedCallback(),this.aside=this.closest("k-aside"),this.aside&&(this.collapsed="collapsed"===this.aside.state,this.side=this.aside.side||"left",this.aside.addEventListener("aside_state_change",this.handleStateChange))}disconnectedCallback(){super.disconnectedCallback(),this.aside&&this.aside.removeEventListener("aside_state_change",this.handleStateChange)}handleStateChange=e=>{const{state:t}=e.detail;"collapsed"===t?(this.collapsed=!0,this.open=!1):"expanded"===t&&(this.collapsed=!1),this.side=this.aside?.side||"left"};toggleMenu=()=>{this.collapsed||(this.open=!this.open)};handleCollapsedClick=()=>{this.open=!0,this.aside?.expand()};render(){if(this.collapsed){const e="right"===this.side?"left down":"right down";return t`
212
+ <k-dropdown open-direction=${e} hover>
213
+ <button slot="trigger" class="no-btn collapsed-trigger" @click=${this.handleCollapsedClick}>
214
+ ${this.icon?t`<k-icon name="${this.icon}"></k-icon>`:t`<k-icon name="dot"></k-icon>`}
215
+ </button>
216
+ <slot></slot>
217
+ </k-dropdown>
218
+ `}return t`
212
219
  <div class="menu-container">
213
220
  <button class="no-btn menu-header ${this.open?"open":""}" @click=${this.toggleMenu}>
214
- ${this.icon?t`<k-icon name="${this.icon}"></k-icon>`:this.collapsed?t`<k-icon name="dot"></k-icon>`:a}
215
- ${this.collapsed?a:t`<span class="label">${this.label}</span>`}
216
- ${this.collapsed?a:t`<k-icon class="chevron" name="chevron" direction="${this.open?"down":"right"}"></k-icon>`}
221
+ ${this.icon?t`<k-icon name="${this.icon}"></k-icon>`:a}
222
+ <span class="label">${this.label}</span>
223
+ <k-icon class="chevron" name="chevron" direction="${this.open?"down":"right"}"></k-icon>
217
224
  </button>
218
- <div class="menu-content ${this.open&&!this.collapsed?"open":""}">
225
+ <div class="menu-content ${this.open?"open":""}">
219
226
  <slot></slot>
220
227
  </div>
221
228
  </div>
@@ -242,12 +249,29 @@ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"
242
249
  white-space: nowrap;
243
250
  transition: background var(--animation_ms);
244
251
  }
245
- :host([collapsed]) .menu-header {
246
- width: auto;
247
- }
248
252
  .menu-header:hover {
249
253
  background: var(--c_bg_hover);
250
254
  }
255
+ .collapsed-trigger {
256
+ display: flex;
257
+ align-items: center;
258
+ justify-content: center;
259
+ padding: var(--spacer_h);
260
+ color: var(--tc);
261
+ background: transparent;
262
+ border: none;
263
+ appearance: none;
264
+ border-radius: var(--radius);
265
+ margin: 0 var(--spacer_h);
266
+ cursor: pointer;
267
+ transition: background var(--animation_ms);
268
+ }
269
+ .collapsed-trigger:hover {
270
+ background: var(--c_bg_hover);
271
+ }
272
+ k-dropdown {
273
+ display: block;
274
+ }
251
275
  k-icon {
252
276
  flex-shrink: 0;
253
277
  }
@@ -266,9 +290,6 @@ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"
266
290
  transition: max-height var(--animation_ms);
267
291
  padding-left: calc(var(--spacer_h) * 2);
268
292
  }
269
- :host([collapsed]) .menu-content {
270
- padding-left: 0;
271
- }
272
293
  .menu-content.open {
273
294
  max-height: 500px;
274
295
  }
@@ -313,6 +334,7 @@ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"
313
334
  width: 2rem;
314
335
  height: 2rem;
315
336
  border: none;
337
+ appearance: none;
316
338
  background: transparent;
317
339
  color: var(--c_text);
318
340
  cursor: pointer;
@@ -325,4 +347,4 @@ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"
325
347
  #toggle:hover {
326
348
  background: var(--c_bg_hover);
327
349
  }
328
- `}customElements.define("k-aside-item",n),customElements.define("k-aside-label",d),customElements.define("k-aside-menu",r),customElements.define("k-aside-spacer",l),customElements.define("k-aside-toggle",c);
350
+ `}customElements.define("k-aside-item",o),customElements.define("k-aside-label",r),customElements.define("k-aside-menu",d),customElements.define("k-aside-spacer",l),customElements.define("k-aside-toggle",c);
@@ -1,4 +1,4 @@
1
- import{html as e,css as t}from"../lit-all.min.js";import o from"./ShadowComponent.js";import{boolTrueFalse as n}from"../utils/propConverters.js";const i=new Set;export default class s extends o{static properties={opened:{type:Boolean,reflect:!0},openDirection:{type:String,reflect:!0,attribute:"open-direction"},closeOnSelect:{type:Boolean,reflect:!0,attribute:"close-on-select",converter:n},closeOnClickOutside:{type:Boolean,reflect:!0,attribute:"close-on-click-outside",converter:n},submenu:{type:Boolean,reflect:!0}};constructor(){super(),this.opened=!1,this.openDirection="down left",this.closeOnSelect=!0,this.closeOnClickOutside=!0,this.submenu=!1}connectedCallback(){super.connectedCallback(),"K-DROPDOWN"!==this.parentElement?.tagName||this.hasAttribute("slot")||(this.submenu=!0,this.hasAttribute("open-direction")||(this.openDirection="right down")),this.submenu?(this.addEventListener("mouseenter",this.handleSubmenuEnter),this.addEventListener("mouseleave",this.handleSubmenuLeave)):document.addEventListener("click",this.handleDocumentClick),document.addEventListener("keydown",this.handleKeydown)}disconnectedCallback(){super.disconnectedCallback(),this.submenu?(this.removeEventListener("mouseenter",this.handleSubmenuEnter),this.removeEventListener("mouseleave",this.handleSubmenuLeave)):document.removeEventListener("click",this.handleDocumentClick),document.removeEventListener("keydown",this.handleKeydown),i.delete(this)}updated(e){super.updated(e),e.has("opened")&&(this.submenu||(this.opened?i.add(this):i.delete(this)),this.dispatchEvent(new CustomEvent(this.opened?"opened":"closed",{bubbles:!0})))}handleDocumentClick=e=>{const t=e.composedPath(),o=t.find(e=>e.matches?.('[slot="trigger"]'));if(o){const e=o.closest("k-dropdown");if(e===this)return;if(this.contains(e))return;return void(this.opened&&this.close())}if(!this.opened)return;if(!t.includes(this))return void(this.closeOnClickOutside&&this.close());const n=t.find(e=>e.matches?.("a, button"));n&&!n.closest('[slot="trigger"]')&&this.closeOnSelect&&this.close()};handleTriggerClick=e=>{e.stopPropagation(),this.opened||i.forEach(e=>{e!==this&&e.close()}),this.toggle()};handleMenuClick=e=>{const t=e.target.closest("a, button");if(!t||t.hasAttribute("disabled"))return;if(t.closest("k-dropdown")!==this)return;const o=t.dataset?.value||t.textContent.trim();this.dispatchEvent(new CustomEvent("select",{detail:{value:o,item:t},bubbles:!0}))};handleKeydown=e=>{if(!this.opened)return;const t=document.activeElement;if(!this.contains(t))return;const o=this.querySelector(":scope > k-dropdown[opened]");if(!o?.contains(t))if("Escape"===e.key||this.submenu&&"ArrowLeft"===e.key)e.preventDefault(),this.close(),this.focusTrigger();else if("ArrowDown"===e.key)e.preventDefault(),this.focusNextItem();else if("ArrowUp"===e.key)e.preventDefault(),this.focusPreviousItem();else if("ArrowRight"===e.key){const o=t?.closest("k-dropdown[submenu]");o?.parentElement===this&&(e.preventDefault(),o.open(),o.focusFirstItem())}else if("Enter"===e.key||" "===e.key){const o=t?.closest("k-dropdown[submenu]");o?.parentElement===this?(e.preventDefault(),o.open(),o.focusFirstItem()):t&&!t.closest('[slot="trigger"]')&&(e.preventDefault(),t.click())}};open(){return this.submenu?[...this.parentElement.querySelectorAll(":scope > k-dropdown[opened]")].forEach(e=>{e!==this&&e.close()}):i.forEach(e=>{e!==this&&e.close()}),this.opened=!0,this.submenu||requestAnimationFrame(()=>this.focusFirstItem()),this}close(){return this.querySelectorAll(":scope > k-dropdown[opened]").forEach(e=>e.close()),this.opened=!1,this}toggle(){return this.opened?this.close():this.open()}focusTrigger(){const e=this.querySelector('[slot="trigger"]');e&&e.focus()}getMenuItems(){return[...this.children].reduce((e,t)=>{if(t.matches('[slot="trigger"]')||t.hasAttribute("disabled"))return e;if("K-DROPDOWN"===t.tagName){const o=t.querySelector('[slot="trigger"]');o&&e.push(o)}else t.matches("a, button")&&e.push(t);return e},[])}focusFirstItem(){const e=this.getMenuItems();e.length>0&&e[0].focus()}focusNextItem(){const e=this.getMenuItems(),t=document.activeElement,o=e.indexOf(t),n=e[o+1]||e[0];n&&n.focus()}focusPreviousItem(){const e=this.getMenuItems(),t=document.activeElement,o=e.indexOf(t),n=e[o-1]||e[e.length-1];n&&n.focus()}static styles=t`
1
+ import{html as e,css as t}from"../lit-all.min.js";import o from"./ShadowComponent.js";import{boolTrueFalse as n}from"../utils/propConverters.js";const i=new Set;export default class s extends o{static properties={opened:{type:Boolean,reflect:!0},openDirection:{type:String,reflect:!0,attribute:"open-direction"},closeOnSelect:{type:Boolean,reflect:!0,attribute:"close-on-select",converter:n},closeOnClickOutside:{type:Boolean,reflect:!0,attribute:"close-on-click-outside",converter:n},submenu:{type:Boolean,reflect:!0},hover:{type:Boolean,reflect:!0}};constructor(){super(),this.opened=!1,this.openDirection="down left",this.closeOnSelect=!0,this.closeOnClickOutside=!0,this.submenu=!1,this.hover=!1}connectedCallback(){super.connectedCallback(),"K-DROPDOWN"!==this.parentElement?.tagName||this.hasAttribute("slot")||(this.submenu=!0,this.hasAttribute("open-direction")||(this.openDirection="right down")),this.submenu?(this.addEventListener("mouseenter",this.handleSubmenuEnter),this.addEventListener("mouseleave",this.handleSubmenuLeave)):(document.addEventListener("click",this.handleDocumentClick),this.hover&&(this.addEventListener("mouseenter",this.handleHoverEnter),this.addEventListener("mouseleave",this.handleHoverLeave))),document.addEventListener("keydown",this.handleKeydown)}disconnectedCallback(){super.disconnectedCallback(),this.submenu?(this.removeEventListener("mouseenter",this.handleSubmenuEnter),this.removeEventListener("mouseleave",this.handleSubmenuLeave)):(document.removeEventListener("click",this.handleDocumentClick),this.removeEventListener("mouseenter",this.handleHoverEnter),this.removeEventListener("mouseleave",this.handleHoverLeave)),document.removeEventListener("keydown",this.handleKeydown),i.delete(this)}updated(e){super.updated(e),e.has("opened")&&(this.submenu||(this.opened?i.add(this):i.delete(this)),this.dispatchEvent(new CustomEvent(this.opened?"opened":"closed",{bubbles:!0})))}handleDocumentClick=e=>{const t=e.composedPath(),o=t.find(e=>e.matches?.('[slot="trigger"]'));if(o){const e=o.closest("k-dropdown");if(e===this)return;if(this.contains(e))return;return void(this.opened&&this.close())}if(!this.opened)return;if(!t.includes(this))return void(this.closeOnClickOutside&&this.close());const n=t.find(e=>e.matches?.("a, button"));n&&!n.closest('[slot="trigger"]')&&this.closeOnSelect&&this.close()};handleTriggerClick=e=>{this.hover||(e.stopPropagation(),this.opened||i.forEach(e=>{e!==this&&e.close()}),this.toggle())};handleMenuClick=e=>{const t=e.target.closest("a, button");if(!t||t.hasAttribute("disabled"))return;if(t.closest("k-dropdown")!==this)return;const o=t.dataset?.value||t.textContent.trim();this.dispatchEvent(new CustomEvent("select",{detail:{value:o,item:t},bubbles:!0}))};handleKeydown=e=>{if(!this.opened)return;const t=document.activeElement;if(!this.contains(t))return;const o=this.querySelector(":scope > k-dropdown[opened]");if(!o?.contains(t))if("Escape"===e.key||this.submenu&&"ArrowLeft"===e.key)e.preventDefault(),this.close(),this.focusTrigger();else if("ArrowDown"===e.key)e.preventDefault(),this.focusNextItem();else if("ArrowUp"===e.key)e.preventDefault(),this.focusPreviousItem();else if("ArrowRight"===e.key){const o=t?.closest("k-dropdown[submenu]");o?.parentElement===this&&(e.preventDefault(),o.open(),o.focusFirstItem())}else if("Enter"===e.key||" "===e.key){const o=t?.closest("k-dropdown[submenu]");o?.parentElement===this?(e.preventDefault(),o.open(),o.focusFirstItem()):t&&!t.closest('[slot="trigger"]')&&(e.preventDefault(),t.click())}};open(){return this.submenu?[...this.parentElement.querySelectorAll(":scope > k-dropdown[opened]")].forEach(e=>{e!==this&&e.close()}):i.forEach(e=>{e!==this&&e.close()}),this.opened=!0,this.submenu||requestAnimationFrame(()=>this.focusFirstItem()),this}close(){return this.querySelectorAll(":scope > k-dropdown[opened]").forEach(e=>e.close()),this.opened=!1,this}toggle(){return this.opened?this.close():this.open()}focusTrigger(){const e=this.querySelector('[slot="trigger"]');e&&e.focus()}getMenuItems(){return[...this.children].reduce((e,t)=>{if(t.matches('[slot="trigger"]')||t.hasAttribute("disabled"))return e;if("K-DROPDOWN"===t.tagName){const o=t.querySelector('[slot="trigger"]');o&&e.push(o)}else t.matches("a, button")&&e.push(t);return e},[])}focusFirstItem(){const e=this.getMenuItems();e.length>0&&e[0].focus()}focusNextItem(){const e=this.getMenuItems(),t=document.activeElement,o=e.indexOf(t),n=e[o+1]||e[0];n&&n.focus()}focusPreviousItem(){const e=this.getMenuItems(),t=document.activeElement,o=e.indexOf(t),n=e[o-1]||e[e.length-1];n&&n.focus()}static styles=t`
2
2
  :host {
3
3
  display: inline-block;
4
4
  position: relative;
@@ -160,7 +160,7 @@ import{html as e,css as t}from"../lit-all.min.js";import o from"./ShadowComponen
160
160
  font-size: 0.75em;
161
161
  opacity: 0.6;
162
162
  }
163
- `;handleSubmenuEnter=()=>{clearTimeout(this.closeTimer),this.opened||this.open()};handleSubmenuLeave=()=>{this.closeTimer=setTimeout(()=>this.close(),150)};handleSlotChange=e=>{e.target.assignedElements().filter(e=>e.matches("a, button, k-dropdown")).forEach((e,t)=>e.classList.toggle("k-dropdown-first",0===t))};render(){return e`
163
+ `;handleHoverEnter=()=>{clearTimeout(this.closeTimer),this.opened||this.open()};handleHoverLeave=()=>{this.closeTimer=setTimeout(()=>this.close(),150)};handleSubmenuEnter=()=>{clearTimeout(this.closeTimer),this.opened||this.open()};handleSubmenuLeave=()=>{this.closeTimer=setTimeout(()=>this.close(),150)};handleSlotChange=e=>{e.target.assignedElements().filter(e=>e.matches("a, button, k-dropdown")).forEach((e,t)=>e.classList.toggle("k-dropdown-first",0===t))};render(){return e`
164
164
  <div id="trigger" @click=${this.handleTriggerClick}>
165
165
  <slot name="trigger"></slot>
166
166
  ${this.submenu?e`<k-icon name="chevron"></k-icon>`:""}
@@ -1,4 +1,4 @@
1
- import{html as e,css as t}from"../lit-all.min.js";import i from"./ShadowComponent.js";import o from"../utils/formatCode.js";import l from"../utils/debounce.js";import{getCalculatedTheme as r,subscribeToTheme as s}from"../utils/theme.js";import a from"./Dialog.js";export default class c extends i{static formAssociated=!0;static properties={name:{type:String,reflect:!0},value:{type:String,reflect:!0},selection:{type:Object,state:!0},mode:{type:String,reflect:!0},controls:{type:String,reflect:!0},lexicalSrc:{type:String,attribute:"lexical-src"},monacoSrc:{type:String,attribute:"monaco-src"},nodes:{type:String},hasTopToolbar:{type:Boolean,state:!0},hasBottomToolbar:{type:Boolean,state:!0},fullscreen:{type:Boolean,reflect:!0}};constructor(){super(),this.internals=this.attachInternals(),this.name="",this.value="",this.selection=null,this.cursor=null,this.mode="visual",this.controls="",this.controlsLoaded=!1,this.lexicalSrc="",this.monacoSrc="",this.nodes="",this.hasTopToolbar=!1,this.hasBottomToolbar=!1,this.skipValueSync=!1,this.lexicalValueSync=!1,this.savedSelection=null,this.lexicalEditor=null,this.monacoEditor=null,this.editorTheme="auto",this.wordWrap=!0,this.minimapEnabled=!1,this.fontSize=14,this.fullscreen=!1,this.lx={},this.debouncedSyncValue=l(()=>this.syncValueFromLexical(),300)}connectedCallback(){super.connectedCallback(),this.hasAttribute("value")&&(this.value=this.getAttribute("value")),this.slotObserver=new MutationObserver(()=>this.updateToolbarVisibility()),this.slotObserver.observe(this,{childList:!0,subtree:!0}),this.updateToolbarVisibility()}disconnectedCallback(){super.disconnectedCallback(),this.slotObserver?.disconnect(),this.cleanupFns?.forEach(e=>e?.()),this.monacoEditor?.dispose(),this.unsubscribeTheme?.(),this.syncShadowSelection&&document.removeEventListener("selectionchange",this.syncShadowSelection),this.fullscreen&&this.exitFullscreen()}updateToolbarVisibility(){const e=new Set(Array.from(this.children).map(e=>e.getAttribute("slot"))),t=this.constructor.controlSets[this.controls]??null;this.hasTopToolbar=!(!t?.topLeft&&!t?.topRight)||["toolbar-top","toolbar-top-left","toolbar-top-right"].some(t=>e.has(t)),this.hasBottomToolbar=!(!t?.bottomLeft&&!t?.bottomRight)||["toolbar-bottom","toolbar-bottom-left","toolbar-bottom-right"].some(t=>e.has(t))}updated(e){if(super.updated(e),e.has("controls")&&(this.updateToolbarVisibility(),this.controls&&"none"!==this.controls&&this.loadControls()),e.has("value")&&!this.skipValueSync&&(this.lexicalValueSync?this.lexicalValueSync=!1:this.lexicalEditor&&"visual"===this.mode&&!this.isVisualCompatible(this.value)?(this.skipLexicalExport=!0,this.mode="code"):this.syncContentToEditors(),this.updateFormValue(),this.dispatchEvent(new CustomEvent("change",{detail:{value:this.value},bubbles:!0}))),e.has("mode")){const t=window.scrollY;this.handleModeSwitch(e.get("mode")),this.dispatchEvent(new CustomEvent("mode-changed",{detail:{mode:this.mode},bubbles:!0})),requestAnimationFrame(()=>window.scrollTo(0,t))}e.has("fullscreen")&&requestAnimationFrame(()=>this.monacoEditor?.layout())}async firstUpdated(){this.lexicalContainer=this.shadowRoot.querySelector(".lexical-editor"),this.monacoContainer=this.shadowRoot.querySelector(".monaco-editor-container"),await this.initLexical(),this.dispatchEvent(new CustomEvent("ready",{detail:{value:this.value},bubbles:!0}))}async loadControls(){if(this.controlsLoaded)return;this.controlsLoaded=!0;const e=new URL("./htmlEditorControls/",import.meta.url).href;await Promise.all([import(`${e}Bold.js`),import(`${e}Italic.js`),import(`${e}Underline.js`),import(`${e}Strikethrough.js`),import(`${e}InlineCode.js`),import(`${e}DropdownControl.js`),import(`${e}FormatBlock.js`),import(`${e}CodeBlock.js`),import(`${e}BulletList.js`),import(`${e}NumberList.js`),import(`${e}AlignLeft.js`),import(`${e}AlignCenter.js`),import(`${e}AlignRight.js`),import(`${e}AlignJustify.js`),import(`${e}TextColor.js`),import(`${e}TextBackgroundColor.js`),import(`${e}ClearFormatting.js`),import(`${e}CreateLink.js`),import(`${e}InsertTable.js`),import(`${e}ControlGroup.js`),import(`${e}ControlSpacer.js`),import(`${e}Mode.js`),import(`${e}WordCount.js`),import(`${e}CharacterCount.js`)]);const t=new URL("./codeEditorControls/",import.meta.url).href;await Promise.all([import(`${t}FormatCode.js`),import(`${t}CopyCode.js`),import(`${t}Undo.js`),import(`${t}Redo.js`),import(`${t}WordWrap.js`),import(`${t}Minimap.js`),import(`${t}FindReplace.js`),import(`${t}FontSize.js`),import(`${t}FoldAll.js`),import(`${t}EditorTheme.js`),import(`${t}Fullscreen.js`),import(`${t}ControlGroup.js`)]),this.requestUpdate()}async loadNodeModules(){if(!this.nodes?.trim())return[];const e=new URL("./htmlEditorNodes/",import.meta.url).href;return(await Promise.all(this.nodes.split(",").map(e=>e.trim()).filter(Boolean).map(t=>import(`${e}${t}.js`)))).map(e=>e.default?.lexicalNode).filter(Boolean)}async loadLexicalModules(){const e=this.lexicalSrc||window.kempo?.lexicalUrl||"https://esm.sh",t=t=>((e,t)=>`${e}/${t}@0.43.0`)(e,t),[i,o,l,r,s,a,c,n,h]=await Promise.all([import(t("lexical")),import(t("@lexical/rich-text")),import(t("@lexical/html")),import(t("@lexical/history")),import(t("@lexical/list")),import(t("@lexical/link")),import(t("@lexical/selection")),import(t("@lexical/table")),import(t("@lexical/code"))]);this.lx={lexical:i,richText:o,lexicalHtml:l,history:r,list:s,link:a,selection:c,table:n,code:h},this.StyledTextNode=class extends i.TextNode{static getType(){return"styled-text"}static clone(e){return new this(e.__text,e.__key)}static importDOM(){return{span:()=>({conversion:e=>{const t=e.getAttribute("style");if(!t)return null;const o=i.$createTextNode(e.textContent);return o.setStyle(t),{node:o}},priority:1})}}static importJSON(e){return i.$createTextNode(e.text)}exportJSON(){return{...super.exportJSON(),type:"styled-text"}}}}async initLexical(){await this.loadLexicalModules(),this.customNodes=await this.loadNodeModules(),this.nodeCompatCheckers=this.customNodes.filter(e=>"function"==typeof e.isVisualCompatible).map(e=>e.isVisualCompatible),this.nodePreprocessors=this.customNodes.filter(e=>"function"==typeof e.preprocessHtml).map(e=>e.preprocessHtml);const{lexical:e,richText:t,history:i,list:o,link:l,table:r,code:s}=this.lx,a={namespace:"KempoHtmlEditor",theme:{paragraph:"k-editor-p",heading:{h1:"k-editor-h1",h2:"k-editor-h2",h3:"k-editor-h3",h4:"k-editor-h4",h5:"k-editor-h5",h6:"k-editor-h6"},text:{underline:"td-u",strikethrough:"td-lt"},list:{ul:"k-editor-ul",ol:"k-editor-ol",listitem:"k-editor-li"},link:"k-editor-link",quote:"k-editor-quote",code:"k-editor-code-block",codeHighlight:{},table:"k-editor-table",tableCell:"k-editor-table-cell",tableCellHeader:"k-editor-table-cell-header"},nodes:[t.HeadingNode,t.QuoteNode,o.ListNode,o.ListItemNode,l.LinkNode,r.TableNode,r.TableCellNode,r.TableRowNode,s.CodeNode,s.CodeHighlightNode,this.StyledTextNode,...this.customNodes],onError:console.error,editorState:null};this.lexicalEditor=e.createEditor(a),this.lexicalEditor.setRootElement(this.lexicalContainer),this.cleanupFns=[t.registerRichText(this.lexicalEditor),i.registerHistory(this.lexicalEditor,i.createEmptyHistoryState(),300)],o.registerList&&this.cleanupFns.push(o.registerList(this.lexicalEditor)),r.registerTable&&this.cleanupFns.push(r.registerTable(this.lexicalEditor)),s.registerCodeHighlighting&&this.cleanupFns.push(s.registerCodeHighlighting(this.lexicalEditor)),l.registerLink&&this.cleanupFns.push(l.registerLink(this.lexicalEditor,{validateUrl:e=>{try{return new URL(e),!0}catch{return!1}}})),this.value&&(this.isVisualCompatible(this.value)?this.importHtmlToLexical(this.value):(this.skipLexicalExport=!0,this.mode="code")),this.lexicalEditor.registerUpdateListener(({dirtyElements:e,dirtyLeaves:t})=>{0===e.size&&0===t.size||(this.debouncedSyncValue(),this.dispatchEvent(new CustomEvent("input",{detail:{value:this.exportHtmlFromLexical()},bubbles:!0})))}),this.lexicalEditor.registerCommand(e.SELECTION_CHANGE_COMMAND,()=>(this.updateSelection(),!1),e.COMMAND_PRIORITY_LOW),this.syncShadowSelection=()=>{if("visual"!==this.mode||!this.lexicalEditor)return;const t=this.shadowRoot.getSelection?.();if(!t||0===t.rangeCount)return;const i=t.getRangeAt(0);this.lexicalContainer.contains(i.startContainer)&&(this.lexicalEditor.update(()=>{const i=e.$createRangeSelectionFromDom(t,this.lexicalEditor);i&&e.$setSelection(i)},{discrete:!0}),this.updateSelection())},document.addEventListener("selectionchange",this.syncShadowSelection)}async initMonaco(){if(!this.monacoEditor){if(this.monacoInitPromise)return this.monacoInitPromise;this.monacoInitPromise=this._initMonaco(),await this.monacoInitPromise,this.monacoInitPromise=null}}async _initMonaco(){const e=this.monacoSrc||window.kempo?.monacoUrl||"https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min";await new Promise((t,i)=>{if(window.monaco)return void t();if(window.require?.defined?.("vs/editor/editor.main"))return void t();const o=document.querySelector(`script[src="${e}/vs/loader.js"]`);if(o)return void o.addEventListener("load",()=>{window.require.config({paths:{vs:`${e}/vs`}}),window.require(["vs/editor/editor.main"],()=>t(),i)});const l=document.createElement("script");l.src=`${e}/vs/loader.js`,l.onload=()=>{window.require.config({paths:{vs:`${e}/vs`}}),window.require(["vs/editor/editor.main"],()=>t(),i)},l.onerror=i,document.head.appendChild(l)}),this.monacoEditor=window.monaco.editor.create(this.monacoContainer,{value:o(this.value),language:"html",theme:this.resolveMonacoTheme(),minimap:{enabled:this.minimapEnabled},wordWrap:this.wordWrap?"on":"off",fontSize:this.fontSize,scrollBeyondLastLine:!1,automaticLayout:!0,tabSize:2,padding:{top:8}});const t=document.querySelector('link[href*="monaco"][href*="editor.main.css"]');if(t){const e=document.createElement("link");e.rel="stylesheet",e.href=t.href,this.shadowRoot.appendChild(e)}this.unsubscribeTheme=s(()=>{this.monacoEditor&&"auto"===this.editorTheme&&window.monaco.editor.setTheme(this.resolveMonacoTheme())}),this.monacoEditor.onDidChangeModelContent(()=>{this.skipValueSync=!0,this.value=this.monacoEditor.getValue(),this.skipValueSync=!1,this.updateFormValue(),this.dispatchEvent(new CustomEvent("change",{detail:{value:this.value},bubbles:!0})),this.dispatchEvent(new CustomEvent("input",{detail:{value:this.value},bubbles:!0}))})}importHtmlToLexical(e){if(!this.lexicalEditor||!this.lx.lexicalHtml)return;const{lexical:t,lexicalHtml:i}=this.lx,o=(this.nodePreprocessors||[]).reduce((e,t)=>t(e),e);this.lexicalEditor.update(()=>{if(t.$getRoot().clear(),!o?.trim())return;const e=(new DOMParser).parseFromString(o,"text/html"),l=i.$generateNodesFromDOM(this.lexicalEditor,e);l.length>0&&t.$insertNodes(l)},{discrete:!0})}exportHtmlFromLexical(){if(!this.lexicalEditor||!this.lx.lexicalHtml)return this.value;let e="";return this.lexicalEditor.getEditorState().read(()=>{e=this.lx.lexicalHtml.$generateHtmlFromNodes(this.lexicalEditor,null)}),this.cleanExportedHtml(e)}isVisualCompatible(e){if(!e?.trim())return!0;const t=new Set(["script","style","meta","link","head","iframe","object","embed","canvas","video","audio","form","input","button","select","textarea","fieldset","label","noscript","template","slot","svg","math"]),i=this.nodeCompatCheckers||[],o=(new DOMParser).parseFromString(e,"text/html"),l=document.createTreeWalker(o.body,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_COMMENT);let r;for(;r=l.nextNode();)if(!i.some(e=>e(r))){if(r.nodeType===Node.COMMENT_NODE)return!1;if(t.has(r.tagName?.toLowerCase()))return!1}return!0}cleanExportedHtml(e){const t=(new DOMParser).parseFromString(e,"text/html");return t.body.querySelectorAll("[class]").forEach(e=>{const t=Array.from(e.classList).filter(e=>!e.startsWith("k-editor-")&&"td-u"!==e&&"td-lt"!==e);0===t.length?e.removeAttribute("class"):e.className=t.join(" ")}),t.body.querySelectorAll("[style]").forEach(e=>{const t=e.style.cssText.replace(/white-space:\s*pre-wrap;?\s*/g,"").trim();t?e.style.cssText=t:e.removeAttribute("style")}),t.body.querySelectorAll("span:not([class]):not([style]):not([id])").forEach(e=>{e.attributes.length||e.replaceWith(...e.childNodes)}),t.body.querySelectorAll("b > strong, i > em, b > b, strong > strong, i > i, em > em").forEach(e=>{e.replaceWith(...e.childNodes)}),t.body.querySelectorAll("pre[data-highlight-language], code[data-highlight-language]").forEach(e=>{e.removeAttribute("data-highlight-language"),e.removeAttribute("data-language")}),t.body.innerHTML}syncValueFromLexical(){this.lexicalEditor&&(this.lexicalValueSync=!0,this.value=this.exportHtmlFromLexical(),this.updateFormValue())}syncContentToEditors(){"visual"===this.mode&&this.lexicalEditor&&this.importHtmlToLexical(this.value)}async handleModeSwitch(e){"code"===this.mode?(this.lexicalEditor&&!this.skipLexicalExport&&(this.value=this.exportHtmlFromLexical()),this.skipLexicalExport=!1,await this.initMonaco(),this.monacoEditor&&(this.monacoEditor.setValue(o(this.value)),this.monacoEditor.layout())):"visual"===this.mode&&(this.monacoEditor&&(this.value=this.monacoEditor.getValue()),this.lexicalEditor&&this.importHtmlToLexical(this.value)),this.requestUpdate()}updateFormValue(){this.internals.setFormValue(this.getValue())}formResetCallback(){this.value=""}formStateRestoreCallback(e){this.value=e}updateSelection=()=>{if("visual"!==this.mode||!this.lexicalEditor)return void(this.selection=null);const{lexical:e}=this.lx;this.lexicalEditor.getEditorState().read(()=>{const t=e.$getSelection();e.$isRangeSelection(t)&&!t.isCollapsed()?this.selection={text:t.getTextContent(),collapsed:!1}:(this.selection=null,this.cursor=t?{anchor:t.anchor,focus:t.focus}:null)})};setMode(e){return["visual","code"].includes(e)?"visual"!==e||this.isVisualCompatible(this.getValue())?(this.mode=e,this):(a.confirm("This html contains code that is not compatible with the visual editor, the incompatible code will be lost",t=>{t&&(this.mode=e)},{title:"Warning",confirmText:"Change Anyways"}),this):this}toggleMode(){return this.setMode("visual"===this.mode?"code":"visual")}getValue(){if("visual"===this.mode&&this.lexicalEditor)this.skipValueSync=!0,this.value=this.exportHtmlFromLexical(),this.skipValueSync=!1;else if("code"===this.mode&&this.monacoEditor)return this.monacoEditor.getValue();return this.value}setValue(e){return this.lexicalEditor&&"visual"===this.mode&&!this.isVisualCompatible(e)?(this.value=e,this.skipLexicalExport=!0,this.mode="code",this.updateFormValue(),this):(this.skipValueSync=!0,this.value=e,"visual"===this.mode?this.syncContentToEditors():"code"===this.mode&&this.monacoEditor&&this.monacoEditor.setValue(o(e)),this.updateFormValue(),this.skipValueSync=!1,this)}clear(){return this.setValue("")}bold(){return this.lexicalFormat("bold"),this}italic(){return this.lexicalFormat("italic"),this}underline(){return this.lexicalFormat("underline"),this}strikethrough(){return this.lexicalFormat("strikethrough"),this}inlineCode(){return this.lexicalFormat("code"),this}orderedList(){return"visual"===this.mode&&this.lexicalEditor?(this.lexicalEditor.update(()=>{this.lx.list.$insertList("number")},{discrete:!0}),this):this}unorderedList(){return"visual"===this.mode&&this.lexicalEditor?(this.lexicalEditor.update(()=>{this.lx.list.$insertList("bullet")},{discrete:!0}),this):this}alignLeft(){return this.lexicalFormatElement("left"),this}alignCenter(){return this.lexicalFormatElement("center"),this}alignRight(){return this.lexicalFormatElement("right"),this}alignJustify(){return this.lexicalFormatElement("justify"),this}setTextColor(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,selection:i}=this.lx;return this.lexicalEditor.update(()=>{const o=t.$getSelection();t.$isRangeSelection(o)&&i.$patchStyleText(o,{color:e})},{discrete:!0}),this}removeTextColor(){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:e,selection:t}=this.lx;return this.lexicalEditor.update(()=>{const i=e.$getSelection();e.$isRangeSelection(i)&&t.$patchStyleText(i,{color:null})},{discrete:!0}),this}setTextBackgroundColor(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,selection:i}=this.lx;return this.lexicalEditor.update(()=>{const o=t.$getSelection();t.$isRangeSelection(o)&&i.$patchStyleText(o,{"background-color":e})},{discrete:!0}),this}removeTextBackgroundColor(){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:e,selection:t}=this.lx;return this.lexicalEditor.update(()=>{const i=e.$getSelection();e.$isRangeSelection(i)&&t.$patchStyleText(i,{"background-color":null})},{discrete:!0}),this}removeFormat(){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:e,selection:t}=this.lx;return this.lexicalEditor.update(()=>{const i=e.$getSelection();e.$isRangeSelection(i)&&(i.getNodes().forEach(t=>{e.$isTextNode(t)&&t.setFormat(0)}),t.$patchStyleText(i,{color:null,"background-color":null}))},{discrete:!0}),this}formatBlock(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,richText:i,code:o}=this.lx;return this.lexicalEditor.update(()=>{const l=t.$getSelection();if(!t.$isRangeSelection(l))return;const r=l.anchor.getNode().getTopLevelElementOrThrow(),s=o.$isCodeNode(r);let a;if("p"===e)a=t.$createParagraphNode();else if(e.match(/^h[1-6]$/))a=i.$createHeadingNode(e);else if("blockquote"===e)a=i.$createQuoteNode();else{if("pre"!==e)return;a=o.$createCodeNode()}if(s&&"pre"!==e){const e=r.getTextContent();r.replace(a),a.append(t.$createTextNode(e))}else{const e=r.getChildren();r.replace(a),e.forEach(e=>a.append(e))}a.selectEnd()},{discrete:!0}),this}isSelectionInCodeBlock(){if("visual"!==this.mode||!this.lexicalEditor)return!1;let e=!1;const{lexical:t,code:i}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const o=t.$getSelection();t.$isRangeSelection(o)&&(e=i.$isCodeNode(o.anchor.getNode().getTopLevelElementOrThrow()))}),e}getTableAtSelection(){if("visual"!==this.mode||!this.lexicalEditor)return null;let e=null;const{lexical:t,table:i}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const o=t.$getSelection();if(!t.$isRangeSelection(o))return;let l=o.anchor.getNode();for(;l;){if(i.$isTableNode(l)){const t=l.getChildren(),o=[];let r=!1,s=0;t.forEach((e,t)=>{const l=[];e.getChildren().forEach(e=>{0===t&&i.$isTableCellNode(e)&&e.getHeaderStyles()===i.TableCellHeaderStates.ROW&&(r=!0),l.push(e.getTextContent())}),l.length>s&&(s=l.length),o.push(l)}),e={key:l.getKey(),rows:r?t.length-1:t.length,cols:s,hasHeaders:r,cellData:o};break}l=l.getParent()}}),e}removeTableByKey(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t}=this.lx;return this.lexicalEditor.update(()=>{const i=t.$getNodeByKey(e);i&&i.remove()},{discrete:!0}),this}insertHTML(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,lexicalHtml:i}=this.lx;return this.lexicalEditor.update(()=>{const o=(new DOMParser).parseFromString(e,"text/html"),l=i.$generateNodesFromDOM(this.lexicalEditor,o);t.$insertNodes(l)},{discrete:!0}),this}insertAtCursor(e){return this.insertHTML(e)}insertTable(e,t,i=!1,o=null){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:l,table:r}=this.lx;return this.lexicalEditor.update(()=>{const s=e+(i?1:0),a=[];for(let e=0;e<s;e++){const s=[];for(let a=0;a<t;a++){const t=i&&0===e,c=t?r.TableCellHeaderStates.ROW:r.TableCellHeaderStates.NO_STATUS,n=r.$createTableCellNode(c),h=o?.[e]?.[a]??(t?`Header ${a+1}`:""),d=l.$createParagraphNode();d.append(l.$createTextNode(h||" ")),n.append(d),s.push(n)}a.push(r.$createTableRowNode().append(...s))}const c=r.$createTableNode().append(...a),n=l.$getSelection();if(l.$isRangeSelection(n)){n.anchor.getNode().getTopLevelElementOrThrow().insertAfter(c);const e=l.$createParagraphNode();c.insertAfter(e),e.selectEnd()}else{const e=l.$getRoot();e.append(c),e.append(l.$createParagraphNode())}},{discrete:!0}),this}insertElementAtCursor(e){return this.insertHTML(e.outerHTML)}replaceSelectionWithElement(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,lexicalHtml:i}=this.lx;return this.lexicalEditor.update(()=>{const o=t.$getSelection();if(!t.$isRangeSelection(o))return;o.removeText();const l=(new DOMParser).parseFromString(e.outerHTML,"text/html"),r=i.$generateNodesFromDOM(this.lexicalEditor,l);t.$insertNodes(r)},{discrete:!0}),this}wrapSelection(e,t,i=null){if("visual"!==this.mode||!this.lexicalEditor)return this;const o=i||this.getSelectedText();return o?this.insertHTML(e+o+t):this}getSelection(){if("visual"!==this.mode||!this.lexicalEditor)return null;let e=null;const{lexical:t}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const i=t.$getSelection();t.$isRangeSelection(i)&&!i.isCollapsed()&&(e={text:i.getTextContent(),html:i.getTextContent(),selection:i})}),e}getSelectedText(){let e="";if("visual"!==this.mode||!this.lexicalEditor)return e;const{lexical:t}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const i=t.$getSelection();t.$isRangeSelection(i)&&(e=i.getTextContent())}),e}getSelectedHTML(){return this.getSelectedText()}selectAll(){if("visual"===this.mode&&this.lexicalEditor){const{lexical:e}=this.lx;this.lexicalEditor.update(()=>{e.$selectAll()},{discrete:!0})}else if(this.monacoEditor){const e=this.monacoEditor.getModel();e&&this.monacoEditor.setSelection(e.getFullModelRange())}return this}replaceSelection(e){return this.insertHTML(e)}deleteSelection(){return"visual"===this.mode?this.lexicalCmd("DELETE_CHARACTER_COMMAND",!1):this.monacoEditor&&this.monacoEditor.trigger("keyboard","deleteAllLeft",null),this}getValueWithSelectionMarkers(){if("visual"!==this.mode||!this.lexicalEditor)return{html:this.value,hasCursor:!1,hasSelection:!1,selectedText:""};let e={html:this.exportHtmlFromLexical(),hasCursor:!1,hasSelection:!1,selectedText:""};const{lexical:t}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const i=t.$getSelection();t.$isRangeSelection(i)&&(i.isCollapsed()?e.hasCursor=!0:(e.hasSelection=!0,e.selectedText=i.getTextContent()))}),e}setValueFromSelectionMarkers(e){return this.setValue(e)}captureSelection(){return this.selection}restoreSavedSelection(){return!1}clearSavedSelection(){this.savedSelection=null}createLink(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{link:t}=this.lx;return this.lexicalEditor.update(()=>{t.$toggleLink(e)},{discrete:!0}),this}createLinkWithText(e,t){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:i,link:o}=this.lx;return this.lexicalEditor.update(()=>{const l=i.$getSelection();i.$isRangeSelection(l)&&!l.isCollapsed()&&l.removeText();const r=o.$createLinkNode(e);r.append(i.$createTextNode(t)),i.$insertNodes([r])},{discrete:!0}),this}unlink(){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:e,link:t}=this.lx;return this.lexicalEditor.update(()=>{const i=e.$getSelection();e.$isRangeSelection(i)&&i.getNodes().forEach(e=>{const i=e.getParent();i&&t.$isLinkNode?.(i)&&(i.getChildren().forEach(e=>i.insertBefore(e)),i.remove())})},{discrete:!0}),this}insertImage(e){return this.insertHTML(`<img src="${encodeURI(e)}" />`)}undo(){return"code"===this.mode?this.monacoEditor?.trigger("toolbar","undo"):this.lexicalCmd("UNDO_COMMAND",void 0),this}redo(){return"code"===this.mode?this.monacoEditor?.trigger("toolbar","redo"):this.lexicalCmd("REDO_COMMAND",void 0),this}copyToClipboard(){return navigator.clipboard.writeText(this.getValue()),this}setEditorTheme(e){return["auto","light","dark"].includes(e)&&(this.editorTheme=e),this.monacoEditor&&window.monaco.editor.setTheme(this.resolveMonacoTheme()),this}openFind(){return this.monacoEditor?.getAction("actions.find")?.run(),this}foldAll(){return this.monacoEditor?.getAction("editor.foldAll")?.run(),this}unfoldAll(){return this.monacoEditor?.getAction("editor.unfoldAll")?.run(),this}enterFullscreen(){return this.fullscreen=!0,document.body.classList.add("no-scroll"),this.dispatchEvent(new CustomEvent("fullscreen-changed",{detail:{fullscreen:!0},bubbles:!0})),this}exitFullscreen(){return this.fullscreen=!1,document.body.classList.remove("no-scroll"),this.dispatchEvent(new CustomEvent("fullscreen-changed",{detail:{fullscreen:!1},bubbles:!0})),this}toggleFullscreen(){return this.fullscreen?this.exitFullscreen():this.enterFullscreen()}increaseFontSize(){return this.fontSize=Math.min(this.fontSize+2,40),this.monacoEditor?.updateOptions({fontSize:this.fontSize}),this}decreaseFontSize(){return this.fontSize=Math.max(this.fontSize-2,8),this.monacoEditor?.updateOptions({fontSize:this.fontSize}),this}setWordWrap(e){return this.wordWrap=e,this.monacoEditor?.updateOptions({wordWrap:e?"on":"off"}),this}setMinimap(e){return this.minimapEnabled=e,this.monacoEditor?.updateOptions({minimap:{enabled:e}}),this}resolveMonacoTheme(){return"dark"===this.editorTheme?"vs-dark":"light"===this.editorTheme?"vs":"dark"===r()?"vs-dark":"vs"}lexicalCmd(e,t){if("visual"!==this.mode||!this.lexicalEditor)return;const i=this.lx.lexical?.[e];i&&this.lexicalEditor.dispatchCommand(i,t)}lexicalFormat(e){if("visual"!==this.mode||!this.lexicalEditor)return;const{lexical:t}=this.lx;this.lexicalEditor.update(()=>{const i=t.$getSelection();t.$isRangeSelection(i)&&i.formatText(e)},{discrete:!0})}lexicalFormatElement(e){"visual"===this.mode&&this.lexicalEditor&&this.lexicalEditor.dispatchCommand(this.lx.lexical.FORMAT_ELEMENT_COMMAND,e)}render(){const t=this.constructor.controlSets[this.controls]??{};return e`
1
+ import{html as e,css as t}from"../lit-all.min.js";import i from"./ShadowComponent.js";import o from"../utils/formatCode.js";import l from"../utils/debounce.js";import{getCalculatedTheme as r,subscribeToTheme as s}from"../utils/theme.js";import a from"./Dialog.js";export default class c extends i{static formAssociated=!0;static properties={name:{type:String,reflect:!0},value:{type:String,reflect:!0},selection:{type:Object,state:!0},mode:{type:String,reflect:!0},controls:{type:String,reflect:!0},lexicalSrc:{type:String,attribute:"lexical-src"},monacoSrc:{type:String,attribute:"monaco-src"},nodes:{type:String},hasTopToolbar:{type:Boolean,state:!0},hasBottomToolbar:{type:Boolean,state:!0},fullscreen:{type:Boolean,reflect:!0}};constructor(){super(),this.internals=this.attachInternals(),this.name="",this.value="",this.selection=null,this.cursor=null,this.mode="visual",this.controls="",this.controlsLoaded=!1,this.lexicalSrc="",this.monacoSrc="",this.nodes="",this.hasTopToolbar=!1,this.hasBottomToolbar=!1,this.skipValueSync=!1,this.lexicalValueSync=!1,this.savedSelection=null,this.lexicalEditor=null,this.monacoEditor=null,this.editorTheme="auto",this.wordWrap=!0,this.minimapEnabled=!1,this.fontSize=14,this.fullscreen=!1,this.lx={},this.debouncedSyncValue=l(()=>this.syncValueFromLexical(),300)}connectedCallback(){super.connectedCallback(),this.hasAttribute("value")&&(this.value=this.getAttribute("value")),this.slotObserver=new MutationObserver(()=>this.updateToolbarVisibility()),this.slotObserver.observe(this,{childList:!0,subtree:!0}),this.updateToolbarVisibility()}disconnectedCallback(){super.disconnectedCallback(),this.slotObserver?.disconnect(),this.cleanupFns?.forEach(e=>e?.()),this.monacoEditor?.dispose(),this.unsubscribeTheme?.(),this.fullscreen&&this.exitFullscreen()}updateToolbarVisibility(){const e=new Set(Array.from(this.children).map(e=>e.getAttribute("slot"))),t=this.constructor.controlSets[this.controls]??null;this.hasTopToolbar=!(!t?.topLeft&&!t?.topRight)||["toolbar-top","toolbar-top-left","toolbar-top-right"].some(t=>e.has(t)),this.hasBottomToolbar=!(!t?.bottomLeft&&!t?.bottomRight)||["toolbar-bottom","toolbar-bottom-left","toolbar-bottom-right"].some(t=>e.has(t))}updated(e){if(super.updated(e),e.has("controls")&&(this.updateToolbarVisibility(),this.controls&&"none"!==this.controls&&this.loadControls()),e.has("value")&&!this.skipValueSync&&(this.lexicalValueSync?this.lexicalValueSync=!1:this.lexicalEditor&&"visual"===this.mode&&!this.isVisualCompatible(this.value)?(this.skipLexicalExport=!0,this.mode="code"):this.syncContentToEditors(),this.updateFormValue(),this.dispatchEvent(new CustomEvent("change",{detail:{value:this.value},bubbles:!0}))),e.has("mode")){const t=window.scrollY;this.handleModeSwitch(e.get("mode")),this.dispatchEvent(new CustomEvent("mode-changed",{detail:{mode:this.mode},bubbles:!0})),requestAnimationFrame(()=>window.scrollTo(0,t))}e.has("fullscreen")&&requestAnimationFrame(()=>this.monacoEditor?.layout())}async firstUpdated(){this.lexicalContainer=this.shadowRoot.querySelector(".lexical-editor"),this.monacoContainer=this.shadowRoot.querySelector(".monaco-editor-container"),await this.initLexical(),this.dispatchEvent(new CustomEvent("ready",{detail:{value:this.value},bubbles:!0}))}async loadControls(){if(this.controlsLoaded)return;this.controlsLoaded=!0;const e=new URL("./htmlEditorControls/",import.meta.url).href;await Promise.all([import(`${e}Bold.js`),import(`${e}Italic.js`),import(`${e}Underline.js`),import(`${e}Strikethrough.js`),import(`${e}InlineCode.js`),import(`${e}DropdownControl.js`),import(`${e}FormatBlock.js`),import(`${e}CodeBlock.js`),import(`${e}BulletList.js`),import(`${e}NumberList.js`),import(`${e}AlignLeft.js`),import(`${e}AlignCenter.js`),import(`${e}AlignRight.js`),import(`${e}AlignJustify.js`),import(`${e}TextColor.js`),import(`${e}TextBackgroundColor.js`),import(`${e}ClearFormatting.js`),import(`${e}CreateLink.js`),import(`${e}InsertTable.js`),import(`${e}ControlGroup.js`),import(`${e}ControlSpacer.js`),import(`${e}Mode.js`),import(`${e}WordCount.js`),import(`${e}CharacterCount.js`)]);const t=new URL("./codeEditorControls/",import.meta.url).href;await Promise.all([import(`${t}FormatCode.js`),import(`${t}CopyCode.js`),import(`${t}Undo.js`),import(`${t}Redo.js`),import(`${t}WordWrap.js`),import(`${t}Minimap.js`),import(`${t}FindReplace.js`),import(`${t}FontSize.js`),import(`${t}FoldAll.js`),import(`${t}EditorTheme.js`),import(`${t}Fullscreen.js`),import(`${t}ControlGroup.js`)]),this.requestUpdate()}async loadNodeModules(){if(!this.nodes?.trim())return[];const e=new URL("./htmlEditorNodes/",import.meta.url).href;return(await Promise.all(this.nodes.split(",").map(e=>e.trim()).filter(Boolean).map(t=>import(`${e}${t}.js`)))).map(e=>e.default?.lexicalNode).filter(Boolean)}async loadLexicalModules(){const e=this.lexicalSrc||window.kempo?.lexicalUrl||"https://esm.sh",t=t=>((e,t)=>`${e}/${t}@0.43.0`)(e,t),[i,o,l,r,s,a,c,n,h]=await Promise.all([import(t("lexical")),import(t("@lexical/rich-text")),import(t("@lexical/html")),import(t("@lexical/history")),import(t("@lexical/list")),import(t("@lexical/link")),import(t("@lexical/selection")),import(t("@lexical/table")),import(t("@lexical/code"))]);this.lx={lexical:i,richText:o,lexicalHtml:l,history:r,list:s,link:a,selection:c,table:n,code:h},this.StyledTextNode=class extends i.TextNode{static getType(){return"styled-text"}static clone(e){return new this(e.__text,e.__key)}static importDOM(){return{span:()=>({conversion:e=>{const t=e.getAttribute("style");if(!t)return null;const o=i.$createTextNode(e.textContent);return o.setStyle(t),{node:o}},priority:1})}}static importJSON(e){return i.$createTextNode(e.text)}exportJSON(){return{...super.exportJSON(),type:"styled-text"}}}}async initLexical(){await this.loadLexicalModules(),this.customNodes=await this.loadNodeModules(),this.nodeCompatCheckers=this.customNodes.filter(e=>"function"==typeof e.isVisualCompatible).map(e=>e.isVisualCompatible),this.nodePreprocessors=this.customNodes.filter(e=>"function"==typeof e.preprocessHtml).map(e=>e.preprocessHtml);const{lexical:e,richText:t,history:i,list:o,link:l,table:r,code:s}=this.lx,a={namespace:"KempoHtmlEditor",theme:{paragraph:"k-editor-p",heading:{h1:"k-editor-h1",h2:"k-editor-h2",h3:"k-editor-h3",h4:"k-editor-h4",h5:"k-editor-h5",h6:"k-editor-h6"},text:{underline:"td-u",strikethrough:"td-lt"},list:{ul:"k-editor-ul",ol:"k-editor-ol",listitem:"k-editor-li"},link:"k-editor-link",quote:"k-editor-quote",code:"k-editor-code-block",codeHighlight:{},table:"k-editor-table",tableCell:"k-editor-table-cell",tableCellHeader:"k-editor-table-cell-header"},nodes:[t.HeadingNode,t.QuoteNode,o.ListNode,o.ListItemNode,l.LinkNode,r.TableNode,r.TableCellNode,r.TableRowNode,s.CodeNode,s.CodeHighlightNode,this.StyledTextNode,...this.customNodes],onError:console.error,editorState:null};this.lexicalEditor=e.createEditor(a),this.lexicalEditor.setRootElement(this.lexicalContainer),this.lexicalEditor._window=new Proxy(window,{get:(e,t)=>{if("getSelection"===t)return()=>this.shadowRoot.getSelection();const i=Reflect.get(e,t);return"function"==typeof i?i.bind(e):i}}),this.cleanupFns=[t.registerRichText(this.lexicalEditor),i.registerHistory(this.lexicalEditor,i.createEmptyHistoryState(),300)],o.registerList&&this.cleanupFns.push(o.registerList(this.lexicalEditor)),r.registerTable&&this.cleanupFns.push(r.registerTable(this.lexicalEditor)),s.registerCodeHighlighting&&this.cleanupFns.push(s.registerCodeHighlighting(this.lexicalEditor)),l.registerLink&&this.cleanupFns.push(l.registerLink(this.lexicalEditor,{validateUrl:e=>{try{return new URL(e),!0}catch{return!1}}})),this.value&&(this.isVisualCompatible(this.value)?this.importHtmlToLexical(this.value):(this.skipLexicalExport=!0,this.mode="code")),this.lexicalEditor.registerUpdateListener(({dirtyElements:e,dirtyLeaves:t})=>{0===e.size&&0===t.size||(this.debouncedSyncValue(),this.dispatchEvent(new CustomEvent("input",{detail:{value:this.exportHtmlFromLexical()},bubbles:!0})))}),this.lexicalEditor.registerCommand(e.SELECTION_CHANGE_COMMAND,()=>(this.updateSelection(),!1),e.COMMAND_PRIORITY_LOW)}async initMonaco(){if(!this.monacoEditor){if(this.monacoInitPromise)return this.monacoInitPromise;this.monacoInitPromise=this._initMonaco(),await this.monacoInitPromise,this.monacoInitPromise=null}}async _initMonaco(){const e=this.monacoSrc||window.kempo?.monacoUrl||"https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min";await new Promise((t,i)=>{if(window.monaco)return void t();if(window.require?.defined?.("vs/editor/editor.main"))return void t();const o=document.querySelector(`script[src="${e}/vs/loader.js"]`);if(o)return void o.addEventListener("load",()=>{window.require.config({paths:{vs:`${e}/vs`}}),window.require(["vs/editor/editor.main"],()=>t(),i)});const l=document.createElement("script");l.src=`${e}/vs/loader.js`,l.onload=()=>{window.require.config({paths:{vs:`${e}/vs`}}),window.require(["vs/editor/editor.main"],()=>t(),i)},l.onerror=i,document.head.appendChild(l)}),this.monacoEditor=window.monaco.editor.create(this.monacoContainer,{value:o(this.value),language:"html",theme:this.resolveMonacoTheme(),minimap:{enabled:this.minimapEnabled},wordWrap:this.wordWrap?"on":"off",fontSize:this.fontSize,scrollBeyondLastLine:!1,automaticLayout:!0,tabSize:2,padding:{top:8}});const t=document.querySelector('link[href*="monaco"][href*="editor.main.css"]');if(t){const e=document.createElement("link");e.rel="stylesheet",e.href=t.href,this.shadowRoot.appendChild(e)}this.unsubscribeTheme=s(()=>{this.monacoEditor&&"auto"===this.editorTheme&&window.monaco.editor.setTheme(this.resolveMonacoTheme())}),this.monacoEditor.onDidChangeModelContent(()=>{this.skipValueSync=!0,this.value=this.monacoEditor.getValue(),this.skipValueSync=!1,this.updateFormValue(),this.dispatchEvent(new CustomEvent("change",{detail:{value:this.value},bubbles:!0})),this.dispatchEvent(new CustomEvent("input",{detail:{value:this.value},bubbles:!0}))})}importHtmlToLexical(e){if(!this.lexicalEditor||!this.lx.lexicalHtml)return;const{lexical:t,lexicalHtml:i}=this.lx,o=(this.nodePreprocessors||[]).reduce((e,t)=>t(e),e);this.lexicalEditor.update(()=>{if(t.$getRoot().clear(),!o?.trim())return;const e=(new DOMParser).parseFromString(o,"text/html"),l=i.$generateNodesFromDOM(this.lexicalEditor,e);l.length>0&&t.$insertNodes(l)},{discrete:!0})}exportHtmlFromLexical(){if(!this.lexicalEditor||!this.lx.lexicalHtml)return this.value;let e="";return this.lexicalEditor.getEditorState().read(()=>{e=this.lx.lexicalHtml.$generateHtmlFromNodes(this.lexicalEditor,null)}),this.cleanExportedHtml(e)}isVisualCompatible(e){if(!e?.trim())return!0;const t=new Set(["script","style","meta","link","head","iframe","object","embed","canvas","video","audio","form","input","button","select","textarea","fieldset","label","noscript","template","slot","svg","math"]),i=this.nodeCompatCheckers||[],o=(new DOMParser).parseFromString(e,"text/html"),l=document.createTreeWalker(o.body,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_COMMENT);let r;for(;r=l.nextNode();)if(!i.some(e=>e(r))){if(r.nodeType===Node.COMMENT_NODE)return!1;if(t.has(r.tagName?.toLowerCase()))return!1}return!0}cleanExportedHtml(e){const t=(new DOMParser).parseFromString(e,"text/html");return t.body.querySelectorAll("[class]").forEach(e=>{const t=Array.from(e.classList).filter(e=>!e.startsWith("k-editor-")&&"td-u"!==e&&"td-lt"!==e);0===t.length?e.removeAttribute("class"):e.className=t.join(" ")}),t.body.querySelectorAll("[style]").forEach(e=>{const t=e.style.cssText.replace(/white-space:\s*pre-wrap;?\s*/g,"").trim();t?e.style.cssText=t:e.removeAttribute("style")}),t.body.querySelectorAll("span:not([class]):not([style]):not([id])").forEach(e=>{e.attributes.length||e.replaceWith(...e.childNodes)}),t.body.querySelectorAll("b > strong, i > em, b > b, strong > strong, i > i, em > em").forEach(e=>{e.replaceWith(...e.childNodes)}),t.body.querySelectorAll("pre[data-highlight-language], code[data-highlight-language]").forEach(e=>{e.removeAttribute("data-highlight-language"),e.removeAttribute("data-language")}),t.body.innerHTML}syncValueFromLexical(){this.lexicalEditor&&(this.lexicalValueSync=!0,this.value=this.exportHtmlFromLexical(),this.updateFormValue())}syncContentToEditors(){"visual"===this.mode&&this.lexicalEditor&&this.importHtmlToLexical(this.value)}async handleModeSwitch(e){"code"===this.mode?(this.lexicalEditor&&!this.skipLexicalExport&&(this.value=this.exportHtmlFromLexical()),this.skipLexicalExport=!1,await this.initMonaco(),this.monacoEditor&&(this.monacoEditor.setValue(o(this.value)),this.monacoEditor.layout())):"visual"===this.mode&&(this.monacoEditor&&(this.value=this.monacoEditor.getValue()),this.lexicalEditor&&this.importHtmlToLexical(this.value)),this.requestUpdate()}updateFormValue(){this.internals.setFormValue(this.getValue())}formResetCallback(){this.value=""}formStateRestoreCallback(e){this.value=e}updateSelection=()=>{if("visual"!==this.mode||!this.lexicalEditor)return void(this.selection=null);const{lexical:e}=this.lx;this.lexicalEditor.getEditorState().read(()=>{const t=e.$getSelection();e.$isRangeSelection(t)&&!t.isCollapsed()?this.selection={text:t.getTextContent(),collapsed:!1}:(this.selection=null,this.cursor=t?{anchor:t.anchor,focus:t.focus}:null)})};setMode(e){return["visual","code"].includes(e)?"visual"!==e||this.isVisualCompatible(this.getValue())?(this.mode=e,this):(a.confirm("This html contains code that is not compatible with the visual editor, the incompatible code will be lost",t=>{t&&(this.mode=e)},{title:"Warning",confirmText:"Change Anyways"}),this):this}toggleMode(){return this.setMode("visual"===this.mode?"code":"visual")}getValue(){if("visual"===this.mode&&this.lexicalEditor)this.skipValueSync=!0,this.value=this.exportHtmlFromLexical(),this.skipValueSync=!1;else if("code"===this.mode&&this.monacoEditor)return this.monacoEditor.getValue();return this.value}setValue(e){return this.lexicalEditor&&"visual"===this.mode&&!this.isVisualCompatible(e)?(this.value=e,this.skipLexicalExport=!0,this.mode="code",this.updateFormValue(),this):(this.skipValueSync=!0,this.value=e,"visual"===this.mode?this.syncContentToEditors():"code"===this.mode&&this.monacoEditor&&this.monacoEditor.setValue(o(e)),this.updateFormValue(),this.skipValueSync=!1,this)}clear(){return this.setValue("")}bold(){return this.lexicalFormat("bold"),this}italic(){return this.lexicalFormat("italic"),this}underline(){return this.lexicalFormat("underline"),this}strikethrough(){return this.lexicalFormat("strikethrough"),this}inlineCode(){return this.lexicalFormat("code"),this}orderedList(){return"visual"===this.mode&&this.lexicalEditor?(this.lexicalEditor.update(()=>{this.lx.list.$insertList("number")},{discrete:!0}),this):this}unorderedList(){return"visual"===this.mode&&this.lexicalEditor?(this.lexicalEditor.update(()=>{this.lx.list.$insertList("bullet")},{discrete:!0}),this):this}alignLeft(){return this.lexicalFormatElement("left"),this}alignCenter(){return this.lexicalFormatElement("center"),this}alignRight(){return this.lexicalFormatElement("right"),this}alignJustify(){return this.lexicalFormatElement("justify"),this}setTextColor(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,selection:i}=this.lx;return this.lexicalEditor.update(()=>{const o=t.$getSelection();t.$isRangeSelection(o)&&i.$patchStyleText(o,{color:e})},{discrete:!0}),this}removeTextColor(){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:e,selection:t}=this.lx;return this.lexicalEditor.update(()=>{const i=e.$getSelection();e.$isRangeSelection(i)&&t.$patchStyleText(i,{color:null})},{discrete:!0}),this}setTextBackgroundColor(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,selection:i}=this.lx;return this.lexicalEditor.update(()=>{const o=t.$getSelection();t.$isRangeSelection(o)&&i.$patchStyleText(o,{"background-color":e})},{discrete:!0}),this}removeTextBackgroundColor(){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:e,selection:t}=this.lx;return this.lexicalEditor.update(()=>{const i=e.$getSelection();e.$isRangeSelection(i)&&t.$patchStyleText(i,{"background-color":null})},{discrete:!0}),this}removeFormat(){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:e,selection:t}=this.lx;return this.lexicalEditor.update(()=>{const i=e.$getSelection();e.$isRangeSelection(i)&&(i.getNodes().forEach(t=>{e.$isTextNode(t)&&t.setFormat(0)}),t.$patchStyleText(i,{color:null,"background-color":null}))},{discrete:!0}),this}formatBlock(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,richText:i,code:o}=this.lx;return this.lexicalEditor.update(()=>{const l=t.$getSelection();if(!t.$isRangeSelection(l))return;const r=l.anchor.getNode().getTopLevelElementOrThrow(),s=o.$isCodeNode(r);let a;if("p"===e)a=t.$createParagraphNode();else if(e.match(/^h[1-6]$/))a=i.$createHeadingNode(e);else if("blockquote"===e)a=i.$createQuoteNode();else{if("pre"!==e)return;a=o.$createCodeNode()}if(s&&"pre"!==e){const e=r.getTextContent();r.replace(a),a.append(t.$createTextNode(e))}else{const e=r.getChildren();r.replace(a),e.forEach(e=>a.append(e))}a.selectEnd()},{discrete:!0}),this}isSelectionInCodeBlock(){if("visual"!==this.mode||!this.lexicalEditor)return!1;let e=!1;const{lexical:t,code:i}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const o=t.$getSelection();t.$isRangeSelection(o)&&(e=i.$isCodeNode(o.anchor.getNode().getTopLevelElementOrThrow()))}),e}getTableAtSelection(){if("visual"!==this.mode||!this.lexicalEditor)return null;let e=null;const{lexical:t,table:i}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const o=t.$getSelection();if(!t.$isRangeSelection(o))return;let l=o.anchor.getNode();for(;l;){if(i.$isTableNode(l)){const t=l.getChildren(),o=[];let r=!1,s=0;t.forEach((e,t)=>{const l=[];e.getChildren().forEach(e=>{0===t&&i.$isTableCellNode(e)&&e.getHeaderStyles()===i.TableCellHeaderStates.ROW&&(r=!0),l.push(e.getTextContent())}),l.length>s&&(s=l.length),o.push(l)}),e={key:l.getKey(),rows:r?t.length-1:t.length,cols:s,hasHeaders:r,cellData:o};break}l=l.getParent()}}),e}removeTableByKey(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t}=this.lx;return this.lexicalEditor.update(()=>{const i=t.$getNodeByKey(e);i&&i.remove()},{discrete:!0}),this}insertHTML(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,lexicalHtml:i}=this.lx;return this.lexicalEditor.update(()=>{const o=(new DOMParser).parseFromString(e,"text/html"),l=i.$generateNodesFromDOM(this.lexicalEditor,o);t.$insertNodes(l)},{discrete:!0}),this}insertAtCursor(e){return this.insertHTML(e)}insertTable(e,t,i=!1,o=null){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:l,table:r}=this.lx;return this.lexicalEditor.update(()=>{const s=e+(i?1:0),a=[];for(let e=0;e<s;e++){const s=[];for(let a=0;a<t;a++){const t=i&&0===e,c=t?r.TableCellHeaderStates.ROW:r.TableCellHeaderStates.NO_STATUS,n=r.$createTableCellNode(c),h=o?.[e]?.[a]??(t?`Header ${a+1}`:""),d=l.$createParagraphNode();d.append(l.$createTextNode(h||" ")),n.append(d),s.push(n)}a.push(r.$createTableRowNode().append(...s))}const c=r.$createTableNode().append(...a),n=l.$getSelection();if(l.$isRangeSelection(n)){n.anchor.getNode().getTopLevelElementOrThrow().insertAfter(c);const e=l.$createParagraphNode();c.insertAfter(e),e.selectEnd()}else{const e=l.$getRoot();e.append(c),e.append(l.$createParagraphNode())}},{discrete:!0}),this}insertElementAtCursor(e){return this.insertHTML(e.outerHTML)}replaceSelectionWithElement(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:t,lexicalHtml:i}=this.lx;return this.lexicalEditor.update(()=>{const o=t.$getSelection();if(!t.$isRangeSelection(o))return;o.removeText();const l=(new DOMParser).parseFromString(e.outerHTML,"text/html"),r=i.$generateNodesFromDOM(this.lexicalEditor,l);t.$insertNodes(r)},{discrete:!0}),this}wrapSelection(e,t,i=null){if("visual"!==this.mode||!this.lexicalEditor)return this;const o=i||this.getSelectedText();return o?this.insertHTML(e+o+t):this}getSelection(){if("visual"!==this.mode||!this.lexicalEditor)return null;let e=null;const{lexical:t}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const i=t.$getSelection();t.$isRangeSelection(i)&&!i.isCollapsed()&&(e={text:i.getTextContent(),html:i.getTextContent(),selection:i})}),e}getSelectedText(){let e="";if("visual"!==this.mode||!this.lexicalEditor)return e;const{lexical:t}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const i=t.$getSelection();t.$isRangeSelection(i)&&(e=i.getTextContent())}),e}getSelectedHTML(){return this.getSelectedText()}selectAll(){if("visual"===this.mode&&this.lexicalEditor){const{lexical:e}=this.lx;this.lexicalEditor.update(()=>{e.$selectAll()},{discrete:!0})}else if(this.monacoEditor){const e=this.monacoEditor.getModel();e&&this.monacoEditor.setSelection(e.getFullModelRange())}return this}replaceSelection(e){return this.insertHTML(e)}deleteSelection(){return"visual"===this.mode?this.lexicalCmd("DELETE_CHARACTER_COMMAND",!1):this.monacoEditor&&this.monacoEditor.trigger("keyboard","deleteAllLeft",null),this}getValueWithSelectionMarkers(){if("visual"!==this.mode||!this.lexicalEditor)return{html:this.value,hasCursor:!1,hasSelection:!1,selectedText:""};let e={html:this.exportHtmlFromLexical(),hasCursor:!1,hasSelection:!1,selectedText:""};const{lexical:t}=this.lx;return this.lexicalEditor.getEditorState().read(()=>{const i=t.$getSelection();t.$isRangeSelection(i)&&(i.isCollapsed()?e.hasCursor=!0:(e.hasSelection=!0,e.selectedText=i.getTextContent()))}),e}setValueFromSelectionMarkers(e){return this.setValue(e)}captureSelection(){return this.selection}restoreSavedSelection(){return!1}clearSavedSelection(){this.savedSelection=null}createLink(e){if("visual"!==this.mode||!this.lexicalEditor)return this;const{link:t}=this.lx;return this.lexicalEditor.update(()=>{t.$toggleLink(e)},{discrete:!0}),this}createLinkWithText(e,t){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:i,link:o}=this.lx;return this.lexicalEditor.update(()=>{const l=i.$getSelection();i.$isRangeSelection(l)&&!l.isCollapsed()&&l.removeText();const r=o.$createLinkNode(e);r.append(i.$createTextNode(t)),i.$insertNodes([r])},{discrete:!0}),this}unlink(){if("visual"!==this.mode||!this.lexicalEditor)return this;const{lexical:e,link:t}=this.lx;return this.lexicalEditor.update(()=>{const i=e.$getSelection();e.$isRangeSelection(i)&&i.getNodes().forEach(e=>{const i=e.getParent();i&&t.$isLinkNode?.(i)&&(i.getChildren().forEach(e=>i.insertBefore(e)),i.remove())})},{discrete:!0}),this}insertImage(e){return this.insertHTML(`<img src="${encodeURI(e)}" />`)}undo(){return"code"===this.mode?this.monacoEditor?.trigger("toolbar","undo"):this.lexicalCmd("UNDO_COMMAND",void 0),this}redo(){return"code"===this.mode?this.monacoEditor?.trigger("toolbar","redo"):this.lexicalCmd("REDO_COMMAND",void 0),this}copyToClipboard(){return navigator.clipboard.writeText(this.getValue()),this}setEditorTheme(e){return["auto","light","dark"].includes(e)&&(this.editorTheme=e),this.monacoEditor&&window.monaco.editor.setTheme(this.resolveMonacoTheme()),this}openFind(){return this.monacoEditor?.getAction("actions.find")?.run(),this}foldAll(){return this.monacoEditor?.getAction("editor.foldAll")?.run(),this}unfoldAll(){return this.monacoEditor?.getAction("editor.unfoldAll")?.run(),this}enterFullscreen(){return this.fullscreen=!0,document.body.classList.add("no-scroll"),this.dispatchEvent(new CustomEvent("fullscreen-changed",{detail:{fullscreen:!0},bubbles:!0})),this}exitFullscreen(){return this.fullscreen=!1,document.body.classList.remove("no-scroll"),this.dispatchEvent(new CustomEvent("fullscreen-changed",{detail:{fullscreen:!1},bubbles:!0})),this}toggleFullscreen(){return this.fullscreen?this.exitFullscreen():this.enterFullscreen()}increaseFontSize(){return this.fontSize=Math.min(this.fontSize+2,40),this.monacoEditor?.updateOptions({fontSize:this.fontSize}),this}decreaseFontSize(){return this.fontSize=Math.max(this.fontSize-2,8),this.monacoEditor?.updateOptions({fontSize:this.fontSize}),this}setWordWrap(e){return this.wordWrap=e,this.monacoEditor?.updateOptions({wordWrap:e?"on":"off"}),this}setMinimap(e){return this.minimapEnabled=e,this.monacoEditor?.updateOptions({minimap:{enabled:e}}),this}resolveMonacoTheme(){return"dark"===this.editorTheme?"vs-dark":"light"===this.editorTheme?"vs":"dark"===r()?"vs-dark":"vs"}lexicalCmd(e,t){if("visual"!==this.mode||!this.lexicalEditor)return;const i=this.lx.lexical?.[e];i&&this.lexicalEditor.dispatchCommand(i,t)}lexicalFormat(e){if("visual"!==this.mode||!this.lexicalEditor)return;const{lexical:t}=this.lx;this.lexicalEditor.update(()=>{const i=t.$getSelection();t.$isRangeSelection(i)&&i.formatText(e)},{discrete:!0})}lexicalFormatElement(e){"visual"===this.mode&&this.lexicalEditor&&this.lexicalEditor.dispatchCommand(this.lx.lexical.FORMAT_ELEMENT_COMMAND,e)}render(){const t=this.constructor.controlSets[this.controls]??{};return e`
2
2
  ${this.hasTopToolbar?e`
3
3
  <div class="toolbar-top bb">
4
4
  <div class="toolbar-start">
@@ -201,20 +201,6 @@ import{html as e,css as t}from"../lit-all.min.js";import i from"./ShadowComponen
201
201
  <k-hec-bullet-list></k-hec-bullet-list>
202
202
  <k-hec-number-list></k-hec-number-list>
203
203
  </k-hec-group>
204
- `,topRight:e`
205
- <k-hec-group>
206
- <k-hec-align-left></k-hec-align-left>
207
- <k-hec-align-center></k-hec-align-center>
208
- <k-hec-align-right></k-hec-align-right>
209
- <k-hec-align-justify></k-hec-align-justify>
210
- </k-hec-group>
211
- <k-hec-create-link></k-hec-create-link>
212
- <k-hec-group>
213
- <k-hec-text-color></k-hec-text-color>
214
- <k-hec-text-background-color></k-hec-text-background-color>
215
- </k-hec-group>
216
- <k-hec-clear-formatting></k-hec-clear-formatting>
217
- <k-hec-insert-table></k-hec-insert-table>
218
204
  <k-cec-group>
219
205
  <k-cec-undo></k-cec-undo>
220
206
  <k-cec-redo></k-cec-redo>
@@ -230,6 +216,20 @@ import{html as e,css as t}from"../lit-all.min.js";import i from"./ShadowComponen
230
216
  <k-cec-fold-all></k-cec-fold-all>
231
217
  </k-cec-group>
232
218
  <k-cec-font-size></k-cec-font-size>
219
+ `,topRight:e`
220
+ <k-hec-group>
221
+ <k-hec-align-left></k-hec-align-left>
222
+ <k-hec-align-center></k-hec-align-center>
223
+ <k-hec-align-right></k-hec-align-right>
224
+ <k-hec-align-justify></k-hec-align-justify>
225
+ </k-hec-group>
226
+ <k-hec-create-link></k-hec-create-link>
227
+ <k-hec-group>
228
+ <k-hec-text-color></k-hec-text-color>
229
+ <k-hec-text-background-color></k-hec-text-background-color>
230
+ </k-hec-group>
231
+ <k-hec-clear-formatting></k-hec-clear-formatting>
232
+ <k-hec-insert-table></k-hec-insert-table>
233
233
  <k-cec-editor-theme></k-cec-editor-theme>
234
234
  <k-hec-mode></k-hec-mode>
235
235
  <k-cec-fullscreen></k-cec-fullscreen>
@@ -263,6 +263,7 @@
263
263
  <a href="#disabledItems">Disabled Items</a><br />
264
264
  <a href="#links">Using Links</a><br />
265
265
  <a href="#events">Events</a><br />
266
+ <a href="#hover">Hover</a><br />
266
267
 
267
268
  <h6 class="mt"><a href="#jsRef" class="no-link">JavaScript Reference</a></h6>
268
269
  <a href="#constructor">Constructor</a><br />
@@ -473,6 +474,26 @@
473
474
  </div>
474
475
  </div>
475
476
 
477
+ <h3 id="hover"><a href="#hover" class="no-link">Hover</a></h3>
478
+ <p>Add the <code>hover</code> attribute to open the menu when the trigger is hovered instead of clicked. The menu closes automatically 150ms after the cursor leaves the component.</p>
479
+ <div class="row -mx">
480
+ <div class="col m-span-12 px">
481
+ <k-card label="HTML">
482
+ <pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">k-dropdown</span> <span class="hljs-attr">hover</span>&gt;</span><br> <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">slot</span>=<span class="hljs-string">&#x27;trigger&#x27;</span>&gt;</span>Hover Me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br> <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">data-value</span>=<span class="hljs-string">&#x27;edit&#x27;</span>&gt;</span>Edit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br> <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">data-value</span>=<span class="hljs-string">&#x27;copy&#x27;</span>&gt;</span>Copy<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br> <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">data-value</span>=<span class="hljs-string">&#x27;delete&#x27;</span>&gt;</span>Delete<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">k-dropdown</span>&gt;</span></code></pre>
483
+ </k-card>
484
+ </div>
485
+ <div class="col m-span-12 px">
486
+ <k-card label="Output">
487
+ <k-dropdown hover>
488
+ <button slot="trigger">Hover Me</button>
489
+ <button data-value="edit">Edit</button>
490
+ <button data-value="copy">Copy</button>
491
+ <button data-value="delete">Delete</button>
492
+ </k-dropdown>
493
+ </k-card>
494
+ </div>
495
+ </div>
496
+
476
497
  <h2 id="jsRef"><a href="#jsRef" class="no-link">JavaScript Reference</a></h2>
477
498
 
478
499
  <h3 id="constructor"><a href="#constructor" class="no-link">Constructor</a></h3>
@@ -501,6 +522,9 @@
501
522
  <h5><code>submenu<i>: boolean</i></code></h5>
502
523
  <p>Automatically set to <code>true</code> when a <code>k-dropdown</code> is nested inside another <code>k-dropdown</code>. Sub menus open on hover/focus, display a chevron icon, and default to <code>open-direction="right down"</code>. Supports <code>ArrowRight</code> to open and <code>ArrowLeft</code> to close via keyboard.</p>
503
524
 
525
+ <h5><code>hover<i>: boolean</i></code></h5>
526
+ <p>When present, the menu opens on <code>mouseenter</code> instead of trigger click. The menu closes 150ms after the cursor leaves the component. Default is <code>false</code>.</p>
527
+
504
528
  <h3 id="methods"><a href="#methods" class="no-link">Methods</a></h3>
505
529
  <h5><code>open()<i>: this</i></code></h5>
506
530
  <p>Opens the dropdown menu and focuses the first item.</p>
@@ -1,4 +1,4 @@
1
- import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"../lit-all.min.js";import{boolTrueFalse as i}from"../utils/propConverters.js";import"./FocusCapture.js";import"./Icon.js";export default class o extends e{static properties={state:{type:String,reflect:!0},side:{type:String,reflect:!0},main:{type:String,reflect:!0},overlayClose:{type:Boolean,reflect:!0,attribute:"overlay-close",converter:i},escClose:{type:Boolean,reflect:!0,attribute:"esc-close",converter:i},persistentId:{type:String,reflect:!0,attribute:"persistent-id"}};constructor(){super(),this.state="offscreen",this.side="left",this.main="overlay",this.overlayClose=!0,this.escClose=!0,this.persistentId=null}overlayClick=()=>{this.overlayClose&&this.hide()};handleKeyDown=e=>{this.escClose&&"Escape"===e.key&&this.hide()};updated(e){if(super.updated(e),e.has("persistentId")&&this.persistentId&&window?.localStorage){const e=window.localStorage.getItem(`aside-persistent-id-${this.persistentId}`);e&&(this.state=e)}if(e.has("state")){const t=e.get("state");"offscreen"===this.state||"offscreen"!==t&&void 0!==t?"offscreen"===this.state&&void 0!==t&&"offscreen"!==t&&document.removeEventListener("keydown",this.handleKeyDown):document.addEventListener("keydown",this.handleKeyDown),"overlay"===this.main&&("expanded"===this.state?document.body.classList.add("no-scroll"):document.body.classList.remove("no-scroll"));const s="offscreen"===this.state?0:this.getTargetWidth(this.state),a={aside:this,state:this.state,main:this.main,width:s};this.dispatchEvent(new CustomEvent("aside_state_change",{detail:a})),window.dispatchEvent(new CustomEvent("aside_state_change",{detail:a})),this.inert="offscreen"===this.state,this.persistentId&&window?.localStorage&&window.localStorage.setItem(`aside-persistent-id-${this.persistentId}`,this.state)}}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("keydown",this.handleKeyDown),document.body.classList.remove("no-scroll");const e={aside:this,state:"offscreen",main:this.main,width:0};this.dispatchEvent(new CustomEvent("aside_state_change",{detail:e})),window.dispatchEvent(new CustomEvent("aside_state_change",{detail:e}))}expand=()=>this.state="expanded";collapse=()=>this.state="collapsed";hide=()=>this.state="offscreen";toggle=()=>{this.state="expanded"===this.state?"offscreen":"expanded"};getTargetWidth(e){const t=parseFloat(getComputedStyle(document.documentElement).fontSize),s="collapsed"===e?"--collapsed-width":"--width",a=getComputedStyle(this).getPropertyValue(s).trim();return(a?parseFloat(a):"collapsed"===e?3.5:20)*t}render(){const e=t`<aside><slot></slot></aside>`;return"overlay"===this.main?t`
1
+ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"../lit-all.min.js";import{boolTrueFalse as i}from"../utils/propConverters.js";import"./Dropdown.js";import"./FocusCapture.js";import"./Icon.js";export default class n extends e{static properties={state:{type:String,reflect:!0},side:{type:String,reflect:!0},main:{type:String,reflect:!0},overlayClose:{type:Boolean,reflect:!0,attribute:"overlay-close",converter:i},escClose:{type:Boolean,reflect:!0,attribute:"esc-close",converter:i},persistentId:{type:String,reflect:!0,attribute:"persistent-id"}};constructor(){super(),this.state="offscreen",this.side="left",this.main="overlay",this.overlayClose=!0,this.escClose=!0,this.persistentId=null}overlayClick=()=>{this.overlayClose&&this.hide()};handleKeyDown=e=>{this.escClose&&"Escape"===e.key&&this.hide()};updated(e){if(super.updated(e),e.has("persistentId")&&this.persistentId&&window?.localStorage){const e=window.localStorage.getItem(`aside-persistent-id-${this.persistentId}`);e&&(this.state=e)}if(e.has("state")){const t=e.get("state");"offscreen"===this.state||"offscreen"!==t&&void 0!==t?"offscreen"===this.state&&void 0!==t&&"offscreen"!==t&&document.removeEventListener("keydown",this.handleKeyDown):document.addEventListener("keydown",this.handleKeyDown),"overlay"===this.main&&("expanded"===this.state?document.body.classList.add("no-scroll"):document.body.classList.remove("no-scroll"));const s="offscreen"===this.state?0:this.getTargetWidth(this.state),a={aside:this,state:this.state,main:this.main,width:s};this.dispatchEvent(new CustomEvent("aside_state_change",{detail:a})),window.dispatchEvent(new CustomEvent("aside_state_change",{detail:a})),this.inert="offscreen"===this.state,this.persistentId&&window?.localStorage&&window.localStorage.setItem(`aside-persistent-id-${this.persistentId}`,this.state)}}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("keydown",this.handleKeyDown),document.body.classList.remove("no-scroll");const e={aside:this,state:"offscreen",main:this.main,width:0};this.dispatchEvent(new CustomEvent("aside_state_change",{detail:e})),window.dispatchEvent(new CustomEvent("aside_state_change",{detail:e}))}expand=()=>this.state="expanded";collapse=()=>this.state="collapsed";hide=()=>this.state="offscreen";toggle=()=>{this.state="expanded"===this.state?"offscreen":"expanded"};getTargetWidth(e){const t=parseFloat(getComputedStyle(document.documentElement).fontSize),s="collapsed"===e?"--collapsed-width":"--width",a=getComputedStyle(this).getPropertyValue(s).trim();return(a?parseFloat(a):"collapsed"===e?3.5:20)*t}render(){const e=t`<aside><slot></slot></aside>`;return"overlay"===this.main?t`
2
2
  <k-focus-capture>
3
3
  <div id="container">
4
4
  <button id="overlay-btn" @click=${this.overlayClick}>
@@ -121,10 +121,10 @@ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"
121
121
  }
122
122
  :host([main="push"][state="collapsed"]) aside {
123
123
  width: var(--collapsed-width);
124
- transform: translateX(0);
124
+ transform: none;
125
125
  }
126
126
  :host([main="push"][state="expanded"]) aside {
127
- transform: translateX(0);
127
+ transform: none;
128
128
  }
129
129
  :host([main="overlay"]) aside {
130
130
  width: var(--width);
@@ -133,15 +133,15 @@ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"
133
133
  transform: translateX(-100%);
134
134
  }
135
135
  :host([main="overlay"][state="expanded"]) aside {
136
- transform: translateX(0);
136
+ transform: none;
137
137
  }
138
138
  :host([main="overlay"][side="right"]) aside {
139
139
  transform: translateX(100%);
140
140
  }
141
141
  :host([main="overlay"][side="right"][state="expanded"]) aside {
142
- transform: translateX(0);
142
+ transform: none;
143
143
  }
144
- `}customElements.define("k-aside",o);class n extends e{static properties={icon:{type:String},href:{type:String},active:{type:Boolean,reflect:!0},collapsed:{type:Boolean,reflect:!0},"no-expand":{type:Boolean,attribute:"no-expand"},"hide-when-collapsed":{type:Boolean,attribute:"hide-when-collapsed"}};constructor(){super(),this.icon="",this.href="#",this.active=!1,this.collapsed=!1,this["no-expand"]=!1,this["hide-when-collapsed"]=!1}connectedCallback(){super.connectedCallback(),this.aside=this.closest("k-aside"),this.aside&&(this.collapsed="collapsed"===this.aside.state,this.aside.addEventListener("aside_state_change",this.handleStateChange))}disconnectedCallback(){super.disconnectedCallback(),this.aside&&this.aside.removeEventListener("aside_state_change",this.handleStateChange)}handleStateChange=e=>{const{state:t}=e.detail;"collapsed"===t?this.collapsed=!0:"expanded"===t&&(this.collapsed=!1)};handleClick=e=>{this.collapsed&&!this["no-expand"]&&this.aside&&(e.preventDefault(),this.aside.expand())};render(){return t`
144
+ `}customElements.define("k-aside",n);class o extends e{static properties={icon:{type:String},href:{type:String},active:{type:Boolean,reflect:!0},collapsed:{type:Boolean,reflect:!0},"no-expand":{type:Boolean,attribute:"no-expand"},"hide-when-collapsed":{type:Boolean,attribute:"hide-when-collapsed"}};constructor(){super(),this.icon="",this.href="#",this.active=!1,this.collapsed=!1,this["no-expand"]=!1,this["hide-when-collapsed"]=!1}connectedCallback(){super.connectedCallback(),this.aside=this.closest("k-aside"),this.inMenu=!!this.closest("k-aside-menu"),this.aside&&!this.inMenu&&(this.collapsed="collapsed"===this.aside.state,this.aside.addEventListener("aside_state_change",this.handleStateChange))}disconnectedCallback(){super.disconnectedCallback(),this.aside&&this.aside.removeEventListener("aside_state_change",this.handleStateChange)}handleStateChange=e=>{const{state:t}=e.detail;"collapsed"===t?this.collapsed=!0:"expanded"===t&&(this.collapsed=!1)};handleClick=e=>{this.collapsed&&!this["no-expand"]&&this.aside&&(e.preventDefault(),this.aside.expand())};render(){return t`
145
145
  <a href="${this.href}" class="item ${this.active?"active bg-primary":""}" @click=${this.handleClick}>
146
146
  ${this.icon?t`<k-icon name="${this.icon}"></k-icon>`:this.collapsed?t`<k-icon name="dot"></k-icon>`:a}
147
147
  ${this.collapsed?a:t`<span class="label"><slot></slot></span>`}
@@ -183,7 +183,7 @@ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"
183
183
  overflow: hidden;
184
184
  text-overflow: ellipsis;
185
185
  }
186
- `}class d extends e{static properties={collapsed:{type:Boolean,reflect:!0}};constructor(){super(),this.collapsed=!1}connectedCallback(){super.connectedCallback(),this.aside=this.closest("k-aside"),this.aside&&(this.collapsed="collapsed"===this.aside.state,this.aside.addEventListener("aside_state_change",this.handleStateChange))}disconnectedCallback(){super.disconnectedCallback(),this.aside&&this.aside.removeEventListener("aside_state_change",this.handleStateChange)}handleStateChange=e=>{const{state:t}=e.detail;"collapsed"===t?this.collapsed=!0:"expanded"===t&&(this.collapsed=!1)};render(){return this.collapsed?t`<hr>`:t`<div class="label"><slot></slot></div>`}static styles=s`
186
+ `}class r extends e{static properties={collapsed:{type:Boolean,reflect:!0}};constructor(){super(),this.collapsed=!1}connectedCallback(){super.connectedCallback(),this.aside=this.closest("k-aside"),this.aside&&(this.collapsed="collapsed"===this.aside.state,this.aside.addEventListener("aside_state_change",this.handleStateChange))}disconnectedCallback(){super.disconnectedCallback(),this.aside&&this.aside.removeEventListener("aside_state_change",this.handleStateChange)}handleStateChange=e=>{const{state:t}=e.detail;"collapsed"===t?this.collapsed=!0:"expanded"===t&&(this.collapsed=!1)};render(){return this.collapsed?t`<hr>`:t`<div class="label"><slot></slot></div>`}static styles=s`
187
187
  :host {
188
188
  display: block;
189
189
  margin: var(--spacer_h) 0;
@@ -208,14 +208,21 @@ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"
208
208
  :host([collapsed]) hr {
209
209
  margin: var(--spacer_h) 0;
210
210
  }
211
- `}class r extends e{static properties={icon:{type:String},label:{type:String},open:{type:Boolean,reflect:!0},collapsed:{type:Boolean,reflect:!0},"no-expand":{type:Boolean,attribute:"no-expand"},"hide-when-collapsed":{type:Boolean,attribute:"hide-when-collapsed"}};constructor(){super(),this.icon="",this.label="",this.open=!1,this.collapsed=!1,this["no-expand"]=!1,this["hide-when-collapsed"]=!1}connectedCallback(){super.connectedCallback(),this.aside=this.closest("k-aside"),this.aside&&(this.collapsed="collapsed"===this.aside.state,this.aside.addEventListener("aside_state_change",this.handleStateChange))}disconnectedCallback(){super.disconnectedCallback(),this.aside&&this.aside.removeEventListener("aside_state_change",this.handleStateChange)}handleStateChange=e=>{const{state:t}=e.detail;"collapsed"===t?(this.collapsed=!0,this.open=!1):"expanded"===t&&(this.collapsed=!1)};toggleMenu=()=>{this.collapsed&&!this["no-expand"]&&this.aside?this.aside.expand():this.collapsed||(this.open=!this.open)};render(){return t`
211
+ `}class d extends e{static properties={icon:{type:String},label:{type:String},open:{type:Boolean,reflect:!0},collapsed:{type:Boolean,reflect:!0},side:{type:String},"no-expand":{type:Boolean,attribute:"no-expand"},"hide-when-collapsed":{type:Boolean,attribute:"hide-when-collapsed"}};constructor(){super(),this.icon="",this.label="",this.open=!1,this.collapsed=!1,this.side="left",this["no-expand"]=!1,this["hide-when-collapsed"]=!1}connectedCallback(){super.connectedCallback(),this.aside=this.closest("k-aside"),this.aside&&(this.collapsed="collapsed"===this.aside.state,this.side=this.aside.side||"left",this.aside.addEventListener("aside_state_change",this.handleStateChange))}disconnectedCallback(){super.disconnectedCallback(),this.aside&&this.aside.removeEventListener("aside_state_change",this.handleStateChange)}handleStateChange=e=>{const{state:t}=e.detail;"collapsed"===t?(this.collapsed=!0,this.open=!1):"expanded"===t&&(this.collapsed=!1),this.side=this.aside?.side||"left"};toggleMenu=()=>{this.collapsed||(this.open=!this.open)};handleCollapsedClick=()=>{this.open=!0,this.aside?.expand()};render(){if(this.collapsed){const e="right"===this.side?"left down":"right down";return t`
212
+ <k-dropdown open-direction=${e} hover>
213
+ <button slot="trigger" class="no-btn collapsed-trigger" @click=${this.handleCollapsedClick}>
214
+ ${this.icon?t`<k-icon name="${this.icon}"></k-icon>`:t`<k-icon name="dot"></k-icon>`}
215
+ </button>
216
+ <slot></slot>
217
+ </k-dropdown>
218
+ `}return t`
212
219
  <div class="menu-container">
213
220
  <button class="no-btn menu-header ${this.open?"open":""}" @click=${this.toggleMenu}>
214
- ${this.icon?t`<k-icon name="${this.icon}"></k-icon>`:this.collapsed?t`<k-icon name="dot"></k-icon>`:a}
215
- ${this.collapsed?a:t`<span class="label">${this.label}</span>`}
216
- ${this.collapsed?a:t`<k-icon class="chevron" name="chevron" direction="${this.open?"down":"right"}"></k-icon>`}
221
+ ${this.icon?t`<k-icon name="${this.icon}"></k-icon>`:a}
222
+ <span class="label">${this.label}</span>
223
+ <k-icon class="chevron" name="chevron" direction="${this.open?"down":"right"}"></k-icon>
217
224
  </button>
218
- <div class="menu-content ${this.open&&!this.collapsed?"open":""}">
225
+ <div class="menu-content ${this.open?"open":""}">
219
226
  <slot></slot>
220
227
  </div>
221
228
  </div>
@@ -242,12 +249,29 @@ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"
242
249
  white-space: nowrap;
243
250
  transition: background var(--animation_ms);
244
251
  }
245
- :host([collapsed]) .menu-header {
246
- width: auto;
247
- }
248
252
  .menu-header:hover {
249
253
  background: var(--c_bg_hover);
250
254
  }
255
+ .collapsed-trigger {
256
+ display: flex;
257
+ align-items: center;
258
+ justify-content: center;
259
+ padding: var(--spacer_h);
260
+ color: var(--tc);
261
+ background: transparent;
262
+ border: none;
263
+ appearance: none;
264
+ border-radius: var(--radius);
265
+ margin: 0 var(--spacer_h);
266
+ cursor: pointer;
267
+ transition: background var(--animation_ms);
268
+ }
269
+ .collapsed-trigger:hover {
270
+ background: var(--c_bg_hover);
271
+ }
272
+ k-dropdown {
273
+ display: block;
274
+ }
251
275
  k-icon {
252
276
  flex-shrink: 0;
253
277
  }
@@ -266,9 +290,6 @@ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"
266
290
  transition: max-height var(--animation_ms);
267
291
  padding-left: calc(var(--spacer_h) * 2);
268
292
  }
269
- :host([collapsed]) .menu-content {
270
- padding-left: 0;
271
- }
272
293
  .menu-content.open {
273
294
  max-height: 500px;
274
295
  }
@@ -313,6 +334,7 @@ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"
313
334
  width: 2rem;
314
335
  height: 2rem;
315
336
  border: none;
337
+ appearance: none;
316
338
  background: transparent;
317
339
  color: var(--c_text);
318
340
  cursor: pointer;
@@ -325,4 +347,4 @@ import e from"./ShadowComponent.js";import{html as t,css as s,nothing as a}from"
325
347
  #toggle:hover {
326
348
  background: var(--c_bg_hover);
327
349
  }
328
- `}customElements.define("k-aside-item",n),customElements.define("k-aside-label",d),customElements.define("k-aside-menu",r),customElements.define("k-aside-spacer",l),customElements.define("k-aside-toggle",c);
350
+ `}customElements.define("k-aside-item",o),customElements.define("k-aside-label",r),customElements.define("k-aside-menu",d),customElements.define("k-aside-spacer",l),customElements.define("k-aside-toggle",c);
@@ -1,4 +1,4 @@
1
- import{html as e,css as t}from"../lit-all.min.js";import o from"./ShadowComponent.js";import{boolTrueFalse as n}from"../utils/propConverters.js";const i=new Set;export default class s extends o{static properties={opened:{type:Boolean,reflect:!0},openDirection:{type:String,reflect:!0,attribute:"open-direction"},closeOnSelect:{type:Boolean,reflect:!0,attribute:"close-on-select",converter:n},closeOnClickOutside:{type:Boolean,reflect:!0,attribute:"close-on-click-outside",converter:n},submenu:{type:Boolean,reflect:!0}};constructor(){super(),this.opened=!1,this.openDirection="down left",this.closeOnSelect=!0,this.closeOnClickOutside=!0,this.submenu=!1}connectedCallback(){super.connectedCallback(),"K-DROPDOWN"!==this.parentElement?.tagName||this.hasAttribute("slot")||(this.submenu=!0,this.hasAttribute("open-direction")||(this.openDirection="right down")),this.submenu?(this.addEventListener("mouseenter",this.handleSubmenuEnter),this.addEventListener("mouseleave",this.handleSubmenuLeave)):document.addEventListener("click",this.handleDocumentClick),document.addEventListener("keydown",this.handleKeydown)}disconnectedCallback(){super.disconnectedCallback(),this.submenu?(this.removeEventListener("mouseenter",this.handleSubmenuEnter),this.removeEventListener("mouseleave",this.handleSubmenuLeave)):document.removeEventListener("click",this.handleDocumentClick),document.removeEventListener("keydown",this.handleKeydown),i.delete(this)}updated(e){super.updated(e),e.has("opened")&&(this.submenu||(this.opened?i.add(this):i.delete(this)),this.dispatchEvent(new CustomEvent(this.opened?"opened":"closed",{bubbles:!0})))}handleDocumentClick=e=>{const t=e.composedPath(),o=t.find(e=>e.matches?.('[slot="trigger"]'));if(o){const e=o.closest("k-dropdown");if(e===this)return;if(this.contains(e))return;return void(this.opened&&this.close())}if(!this.opened)return;if(!t.includes(this))return void(this.closeOnClickOutside&&this.close());const n=t.find(e=>e.matches?.("a, button"));n&&!n.closest('[slot="trigger"]')&&this.closeOnSelect&&this.close()};handleTriggerClick=e=>{e.stopPropagation(),this.opened||i.forEach(e=>{e!==this&&e.close()}),this.toggle()};handleMenuClick=e=>{const t=e.target.closest("a, button");if(!t||t.hasAttribute("disabled"))return;if(t.closest("k-dropdown")!==this)return;const o=t.dataset?.value||t.textContent.trim();this.dispatchEvent(new CustomEvent("select",{detail:{value:o,item:t},bubbles:!0}))};handleKeydown=e=>{if(!this.opened)return;const t=document.activeElement;if(!this.contains(t))return;const o=this.querySelector(":scope > k-dropdown[opened]");if(!o?.contains(t))if("Escape"===e.key||this.submenu&&"ArrowLeft"===e.key)e.preventDefault(),this.close(),this.focusTrigger();else if("ArrowDown"===e.key)e.preventDefault(),this.focusNextItem();else if("ArrowUp"===e.key)e.preventDefault(),this.focusPreviousItem();else if("ArrowRight"===e.key){const o=t?.closest("k-dropdown[submenu]");o?.parentElement===this&&(e.preventDefault(),o.open(),o.focusFirstItem())}else if("Enter"===e.key||" "===e.key){const o=t?.closest("k-dropdown[submenu]");o?.parentElement===this?(e.preventDefault(),o.open(),o.focusFirstItem()):t&&!t.closest('[slot="trigger"]')&&(e.preventDefault(),t.click())}};open(){return this.submenu?[...this.parentElement.querySelectorAll(":scope > k-dropdown[opened]")].forEach(e=>{e!==this&&e.close()}):i.forEach(e=>{e!==this&&e.close()}),this.opened=!0,this.submenu||requestAnimationFrame(()=>this.focusFirstItem()),this}close(){return this.querySelectorAll(":scope > k-dropdown[opened]").forEach(e=>e.close()),this.opened=!1,this}toggle(){return this.opened?this.close():this.open()}focusTrigger(){const e=this.querySelector('[slot="trigger"]');e&&e.focus()}getMenuItems(){return[...this.children].reduce((e,t)=>{if(t.matches('[slot="trigger"]')||t.hasAttribute("disabled"))return e;if("K-DROPDOWN"===t.tagName){const o=t.querySelector('[slot="trigger"]');o&&e.push(o)}else t.matches("a, button")&&e.push(t);return e},[])}focusFirstItem(){const e=this.getMenuItems();e.length>0&&e[0].focus()}focusNextItem(){const e=this.getMenuItems(),t=document.activeElement,o=e.indexOf(t),n=e[o+1]||e[0];n&&n.focus()}focusPreviousItem(){const e=this.getMenuItems(),t=document.activeElement,o=e.indexOf(t),n=e[o-1]||e[e.length-1];n&&n.focus()}static styles=t`
1
+ import{html as e,css as t}from"../lit-all.min.js";import o from"./ShadowComponent.js";import{boolTrueFalse as n}from"../utils/propConverters.js";const i=new Set;export default class s extends o{static properties={opened:{type:Boolean,reflect:!0},openDirection:{type:String,reflect:!0,attribute:"open-direction"},closeOnSelect:{type:Boolean,reflect:!0,attribute:"close-on-select",converter:n},closeOnClickOutside:{type:Boolean,reflect:!0,attribute:"close-on-click-outside",converter:n},submenu:{type:Boolean,reflect:!0},hover:{type:Boolean,reflect:!0}};constructor(){super(),this.opened=!1,this.openDirection="down left",this.closeOnSelect=!0,this.closeOnClickOutside=!0,this.submenu=!1,this.hover=!1}connectedCallback(){super.connectedCallback(),"K-DROPDOWN"!==this.parentElement?.tagName||this.hasAttribute("slot")||(this.submenu=!0,this.hasAttribute("open-direction")||(this.openDirection="right down")),this.submenu?(this.addEventListener("mouseenter",this.handleSubmenuEnter),this.addEventListener("mouseleave",this.handleSubmenuLeave)):(document.addEventListener("click",this.handleDocumentClick),this.hover&&(this.addEventListener("mouseenter",this.handleHoverEnter),this.addEventListener("mouseleave",this.handleHoverLeave))),document.addEventListener("keydown",this.handleKeydown)}disconnectedCallback(){super.disconnectedCallback(),this.submenu?(this.removeEventListener("mouseenter",this.handleSubmenuEnter),this.removeEventListener("mouseleave",this.handleSubmenuLeave)):(document.removeEventListener("click",this.handleDocumentClick),this.removeEventListener("mouseenter",this.handleHoverEnter),this.removeEventListener("mouseleave",this.handleHoverLeave)),document.removeEventListener("keydown",this.handleKeydown),i.delete(this)}updated(e){super.updated(e),e.has("opened")&&(this.submenu||(this.opened?i.add(this):i.delete(this)),this.dispatchEvent(new CustomEvent(this.opened?"opened":"closed",{bubbles:!0})))}handleDocumentClick=e=>{const t=e.composedPath(),o=t.find(e=>e.matches?.('[slot="trigger"]'));if(o){const e=o.closest("k-dropdown");if(e===this)return;if(this.contains(e))return;return void(this.opened&&this.close())}if(!this.opened)return;if(!t.includes(this))return void(this.closeOnClickOutside&&this.close());const n=t.find(e=>e.matches?.("a, button"));n&&!n.closest('[slot="trigger"]')&&this.closeOnSelect&&this.close()};handleTriggerClick=e=>{this.hover||(e.stopPropagation(),this.opened||i.forEach(e=>{e!==this&&e.close()}),this.toggle())};handleMenuClick=e=>{const t=e.target.closest("a, button");if(!t||t.hasAttribute("disabled"))return;if(t.closest("k-dropdown")!==this)return;const o=t.dataset?.value||t.textContent.trim();this.dispatchEvent(new CustomEvent("select",{detail:{value:o,item:t},bubbles:!0}))};handleKeydown=e=>{if(!this.opened)return;const t=document.activeElement;if(!this.contains(t))return;const o=this.querySelector(":scope > k-dropdown[opened]");if(!o?.contains(t))if("Escape"===e.key||this.submenu&&"ArrowLeft"===e.key)e.preventDefault(),this.close(),this.focusTrigger();else if("ArrowDown"===e.key)e.preventDefault(),this.focusNextItem();else if("ArrowUp"===e.key)e.preventDefault(),this.focusPreviousItem();else if("ArrowRight"===e.key){const o=t?.closest("k-dropdown[submenu]");o?.parentElement===this&&(e.preventDefault(),o.open(),o.focusFirstItem())}else if("Enter"===e.key||" "===e.key){const o=t?.closest("k-dropdown[submenu]");o?.parentElement===this?(e.preventDefault(),o.open(),o.focusFirstItem()):t&&!t.closest('[slot="trigger"]')&&(e.preventDefault(),t.click())}};open(){return this.submenu?[...this.parentElement.querySelectorAll(":scope > k-dropdown[opened]")].forEach(e=>{e!==this&&e.close()}):i.forEach(e=>{e!==this&&e.close()}),this.opened=!0,this.submenu||requestAnimationFrame(()=>this.focusFirstItem()),this}close(){return this.querySelectorAll(":scope > k-dropdown[opened]").forEach(e=>e.close()),this.opened=!1,this}toggle(){return this.opened?this.close():this.open()}focusTrigger(){const e=this.querySelector('[slot="trigger"]');e&&e.focus()}getMenuItems(){return[...this.children].reduce((e,t)=>{if(t.matches('[slot="trigger"]')||t.hasAttribute("disabled"))return e;if("K-DROPDOWN"===t.tagName){const o=t.querySelector('[slot="trigger"]');o&&e.push(o)}else t.matches("a, button")&&e.push(t);return e},[])}focusFirstItem(){const e=this.getMenuItems();e.length>0&&e[0].focus()}focusNextItem(){const e=this.getMenuItems(),t=document.activeElement,o=e.indexOf(t),n=e[o+1]||e[0];n&&n.focus()}focusPreviousItem(){const e=this.getMenuItems(),t=document.activeElement,o=e.indexOf(t),n=e[o-1]||e[e.length-1];n&&n.focus()}static styles=t`
2
2
  :host {
3
3
  display: inline-block;
4
4
  position: relative;
@@ -160,7 +160,7 @@ import{html as e,css as t}from"../lit-all.min.js";import o from"./ShadowComponen
160
160
  font-size: 0.75em;
161
161
  opacity: 0.6;
162
162
  }
163
- `;handleSubmenuEnter=()=>{clearTimeout(this.closeTimer),this.opened||this.open()};handleSubmenuLeave=()=>{this.closeTimer=setTimeout(()=>this.close(),150)};handleSlotChange=e=>{e.target.assignedElements().filter(e=>e.matches("a, button, k-dropdown")).forEach((e,t)=>e.classList.toggle("k-dropdown-first",0===t))};render(){return e`
163
+ `;handleHoverEnter=()=>{clearTimeout(this.closeTimer),this.opened||this.open()};handleHoverLeave=()=>{this.closeTimer=setTimeout(()=>this.close(),150)};handleSubmenuEnter=()=>{clearTimeout(this.closeTimer),this.opened||this.open()};handleSubmenuLeave=()=>{this.closeTimer=setTimeout(()=>this.close(),150)};handleSlotChange=e=>{e.target.assignedElements().filter(e=>e.matches("a, button, k-dropdown")).forEach((e,t)=>e.classList.toggle("k-dropdown-first",0===t))};render(){return e`
164
164
  <div id="trigger" @click=${this.handleTriggerClick}>
165
165
  <slot name="trigger"></slot>
166
166
  ${this.submenu?e`<k-icon name="chevron"></k-icon>`:""}