@kodaris/krubble-components 1.0.30 → 1.0.32

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 +1,10 @@
1
- []
1
+ [
2
+ {
3
+ "version": "1.0.30",
4
+ "description": "<kr-tab> \"title\" attribute renamed to \"label\" to avoid native HTML title tooltip"
5
+ },
6
+ {
7
+ "version": "1.0.30",
8
+ "description": "<kr-dialog> is now hidden by default (display: none). It requires the \"opened\" attribute or calling .open() to become visible. Programmatic usage via KRDialog.open() is unchanged."
9
+ }
10
+ ]
@@ -265,8 +265,8 @@
265
265
  {
266
266
  "kind": "variable",
267
267
  "name": "KRDialog",
268
- "default": "class KRDialog extends i$2 { constructor() { super(...arguments); this._dialogRef = null; this._contentElement = null; this._handleDocumentKeyDown = (e) => { if (e.key === 'Escape') { this._dialogRef?.close(undefined); } }; } disconnectedCallback() { super.disconnectedCallback(); document.removeEventListener('keydown', this._handleDocumentKeyDown); } static open(component, config) { const existing = document.querySelector('kr-dialog'); if (existing) { existing.remove(); } const dialogRef = new KRDialogRef(); const dialog = document.createElement('kr-dialog'); dialogRef.setDialogElement(dialog); dialog._dialogRef = dialogRef; // Create the content component const content = new component(); content.dialogRef = dialogRef; if (config?.data) { content.data = config.data; } dialog._contentElement = content; document.body.appendChild(dialog); document.addEventListener('keydown', dialog._handleDocumentKeyDown); return dialogRef; } _handleBackdropClick(e) { if (e.target.classList.contains('backdrop')) { this._dialogRef?.close(undefined); } } render() { return b ` <div class=\"backdrop\" @click=${this._handleBackdropClick}></div> <div class=\"dialog\"> ${this._contentElement} </div> `; } }",
269
- "description": "Generic dialog component that renders a Lit component inside a dialog shell."
268
+ "default": "class KRDialog extends i$2 { constructor() { super(...arguments); this._dialogRef = null; this._contentElement = null; this.opened = false; this.width = '560px'; this._handleDocumentKeyDown = (e) => { if (e.key === 'Escape') { this.close(); } }; } disconnectedCallback() { super.disconnectedCallback(); document.removeEventListener('keydown', this._handleDocumentKeyDown); } updated(changedProperties) { super.updated(changedProperties); if (changedProperties.has('opened')) { if (this.opened) { document.addEventListener('keydown', this._handleDocumentKeyDown); } else { document.removeEventListener('keydown', this._handleDocumentKeyDown); } } } /** * Opens the dialog (declarative mode). */ open() { this.opened = true; } /** * Closes the dialog. * In programmatic mode (has _dialogRef), delegates to the dialog ref. * In declarative mode, sets opened=false and dispatches close event. */ close() { if (this._dialogRef) { this._dialogRef.close(undefined); return; } this.opened = false; this.dispatchEvent(new CustomEvent('close', { bubbles: true, composed: true })); } /** * Opens a dialog programmatically by creating a component and injecting it. */ static open(component, config) { // Only remove other programmatic dialogs (those with a _dialogRef) document.querySelectorAll('kr-dialog').forEach((el) => { if (el._dialogRef) { el.remove(); } }); const dialogRef = new KRDialogRef(); const dialog = document.createElement('kr-dialog'); dialogRef.setDialogElement(dialog); dialog._dialogRef = dialogRef; // Create the content component const content = new component(); content.dialogRef = dialogRef; if (config?.data) { content.data = config.data; } dialog._contentElement = content; dialog.opened = true; document.body.appendChild(dialog); return dialogRef; } _handleBackdropClick(e) { if (e.target.classList.contains('backdrop')) { this.close(); } } render() { return b ` <div class=\"backdrop\" @click=${this._handleBackdropClick}></div> <div class=\"dialog\" style=${o$1({ width: this.width })}> ${this._contentElement ? this._contentElement : b `<slot></slot>`} </div> `; } }",
269
+ "description": "Generic dialog component that supports both declarative and programmatic usage.\n\nDeclarative: place `<kr-dialog>` in HTML with slotted content and call `.open()` / `.close()`.\nProgrammatic: use `KRDialog.open(Component, config)` to create and show a dialog."
270
270
  },
271
271
  {
272
272
  "kind": "variable",
@@ -276,13 +276,13 @@
276
276
  {
277
277
  "kind": "variable",
278
278
  "name": "KRTabGroup",
279
- "default": "class KRTabGroup extends i$2 { constructor() { super(...arguments); /** * Whether tabs should stretch to fill the full width evenly */ this.justified = false; /** * Size of the tabs: 'small' | 'medium' | 'large' */ this.size = 'medium'; } updated(changes) { if (changes.has('activeTabId')) { this._updateActiveTab(); } } firstUpdated() { this._updateActiveTab(); } _getTabs() { return Array.from(this.querySelectorAll('kr-tab')); } _updateActiveTab() { const tabs = this._getTabs(); if (tabs.length === 0) return; if (!this.activeTabId) { this.activeTabId = tabs[0]?.id; } tabs.forEach((tab) => { tab.active = tab.id === this.activeTabId; }); this.requestUpdate(); } _handleTabClick(tab) { if (tab.disabled) return; this.activeTabId = tab.id; this.dispatchEvent(new CustomEvent('tab-change', { detail: { activeTabId: tab.id }, bubbles: true, composed: true, })); } _handleTabDismiss(tab, e) { e.stopPropagation(); this.dispatchEvent(new CustomEvent('tab-dismiss', { detail: { tabId: tab.id }, bubbles: true, composed: true, })); } _handleKeyDown(e) { const enabledTabs = this._getTabs().filter((t) => !t.disabled); const currentIndex = enabledTabs.findIndex((t) => t.id === this.activeTabId); let newIndex = -1; switch (e.key) { case 'ArrowLeft': newIndex = currentIndex > 0 ? currentIndex - 1 : enabledTabs.length - 1; break; case 'ArrowRight': newIndex = currentIndex < enabledTabs.length - 1 ? currentIndex + 1 : 0; break; case 'Home': newIndex = 0; break; case 'End': newIndex = enabledTabs.length - 1; break; } if (newIndex >= 0) { e.preventDefault(); const newTab = enabledTabs[newIndex]; this.activeTabId = newTab.id; this.dispatchEvent(new CustomEvent('tab-change', { detail: { activeTabId: newTab.id }, bubbles: true, composed: true, })); const tabButtons = this.shadowRoot?.querySelectorAll('.label'); const targetButton = Array.from(tabButtons || []).find((btn) => btn.getAttribute('data-tab-id') === newTab.id); targetButton?.focus(); } } _renderTabIcon(tab) { const iconElement = tab.getIconElement(); if (!iconElement) return A; // Clone the icon element to render in the header const clonedIcon = iconElement.cloneNode(true); clonedIcon.removeAttribute('slot'); return b `<span class=\"label-icon\">${clonedIcon}</span>`; } render() { return b ` <div class=\"header\" role=\"tablist\" @keydown=${this._handleKeyDown}> ${this._getTabs().map((tab) => b ` <button class=${e$1({ label: true, 'label--active': tab.id === this.activeTabId, 'label--justified': this.justified, })} role=\"tab\" data-tab-id=${tab.id} aria-selected=${tab.id === this.activeTabId} aria-controls=${`panel-${tab.id}`} tabindex=${tab.id === this.activeTabId ? 0 : -1} ?disabled=${tab.disabled} @click=${() => this._handleTabClick(tab)} > ${this._renderTabIcon(tab)} <span>${tab.title}</span> ${tab.badge ? b `<span class=\"label-badge\" style=${o$1({ backgroundColor: tab.badgeBackground, color: tab.badgeColor })}>${tab.badge}</span>` : A} ${tab.dismissible ? b ` <button class=\"label-dismiss\" type=\"button\" aria-label=\"Close tab\" @click=${(e) => this._handleTabDismiss(tab, e)} > <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"12\" height=\"12\"><path fill-rule=\"evenodd\" d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\" clip-rule=\"evenodd\"/></svg> </button> ` : A} </button> `)} </div> <div class=\"content\" role=\"tabpanel\" aria-labelledby=${this.activeTabId || ''}> <slot @slotchange=${this._updateActiveTab}></slot> </div> `; } }",
279
+ "default": "class KRTabGroup extends i$2 { constructor() { super(...arguments); /** * Whether tabs should stretch to fill the full width evenly */ this.justified = false; /** * Size of the tabs: 'small' | 'medium' | 'large' */ this.size = 'medium'; } updated(changes) { if (changes.has('activeTabId')) { this._updateActiveTab(); } } firstUpdated() { this._updateActiveTab(); } _getTabs() { return Array.from(this.querySelectorAll('kr-tab')); } _updateActiveTab() { const tabs = this._getTabs(); if (tabs.length === 0) return; if (!this.activeTabId) { this.activeTabId = tabs[0]?.id; } tabs.forEach((tab) => { tab.active = tab.id === this.activeTabId; }); this.requestUpdate(); } _handleTabClick(tab) { if (tab.disabled) return; this.activeTabId = tab.id; this.dispatchEvent(new CustomEvent('tab-change', { detail: { activeTabId: tab.id }, bubbles: true, composed: true, })); } _handleTabDismiss(tab, e) { e.stopPropagation(); this.dispatchEvent(new CustomEvent('tab-dismiss', { detail: { tabId: tab.id }, bubbles: true, composed: true, })); } _handleKeyDown(e) { const enabledTabs = this._getTabs().filter((t) => !t.disabled); const currentIndex = enabledTabs.findIndex((t) => t.id === this.activeTabId); let newIndex = -1; switch (e.key) { case 'ArrowLeft': newIndex = currentIndex > 0 ? currentIndex - 1 : enabledTabs.length - 1; break; case 'ArrowRight': newIndex = currentIndex < enabledTabs.length - 1 ? currentIndex + 1 : 0; break; case 'Home': newIndex = 0; break; case 'End': newIndex = enabledTabs.length - 1; break; } if (newIndex >= 0) { e.preventDefault(); const newTab = enabledTabs[newIndex]; this.activeTabId = newTab.id; this.dispatchEvent(new CustomEvent('tab-change', { detail: { activeTabId: newTab.id }, bubbles: true, composed: true, })); const tabButtons = this.shadowRoot?.querySelectorAll('.label'); const targetButton = Array.from(tabButtons || []).find((btn) => btn.getAttribute('data-tab-id') === newTab.id); targetButton?.focus(); } } _renderTabIcon(tab) { const iconElement = tab.getIconElement(); if (!iconElement) return A; // Clone the icon element to render in the header const clonedIcon = iconElement.cloneNode(true); clonedIcon.removeAttribute('slot'); return b `<span class=\"label-icon\">${clonedIcon}</span>`; } render() { return b ` <div class=\"header\" role=\"tablist\" @keydown=${this._handleKeyDown}> ${this._getTabs().map((tab) => b ` <button class=${e$1({ label: true, 'label--active': tab.id === this.activeTabId, 'label--justified': this.justified, })} role=\"tab\" data-tab-id=${tab.id} aria-selected=${tab.id === this.activeTabId} aria-controls=${`panel-${tab.id}`} tabindex=${tab.id === this.activeTabId ? 0 : -1} ?disabled=${tab.disabled} @click=${() => this._handleTabClick(tab)} > ${this._renderTabIcon(tab)} <span>${tab.label}</span> ${tab.badge ? b `<span class=\"label-badge\" style=${o$1({ backgroundColor: tab.badgeBackground, color: tab.badgeColor })}>${tab.badge}</span>` : A} ${tab.dismissible ? b ` <button class=\"label-dismiss\" type=\"button\" aria-label=\"Close tab\" @click=${(e) => this._handleTabDismiss(tab, e)} > <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"12\" height=\"12\"><path fill-rule=\"evenodd\" d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\" clip-rule=\"evenodd\"/></svg> </button> ` : A} </button> `)} </div> <div class=\"content\" role=\"tabpanel\" aria-labelledby=${this.activeTabId || ''}> <slot @slotchange=${this._updateActiveTab}></slot> </div> `; } }",
280
280
  "description": "A tabbed navigation component for switching between content sections."
281
281
  },
282
282
  {
283
283
  "kind": "variable",
284
284
  "name": "KRTab",
285
- "default": "class KRTab extends i$2 { constructor() { super(...arguments); /** * Unique identifier for the tab */ this.id = ''; /** * Display title for the tab */ this.title = ''; /** * Badge text displayed next to title (e.g. notification count) */ this.badge = ''; /** * Badge background color */ this.badgeBackground = ''; /** * Badge text color */ this.badgeColor = ''; /** * Whether the tab is disabled */ this.disabled = false; /** * Whether the tab can be dismissed/closed */ this.dismissible = false; /** * Whether this tab is currently active (set by parent) */ this.active = false; } /** * Gets the icon element from the icon slot (if any) */ getIconElement() { return this.querySelector('[slot=\"icon\"]'); } render() { return b `<slot></slot>`; } }",
285
+ "default": "class KRTab extends i$2 { constructor() { super(...arguments); /** * Unique identifier for the tab */ this.id = ''; /** * Display label for the tab */ this.label = ''; /** * Badge text displayed next to label (e.g. notification count) */ this.badge = ''; /** * Badge background color */ this.badgeBackground = ''; /** * Badge text color */ this.badgeColor = ''; /** * Whether the tab is disabled */ this.disabled = false; /** * Whether the tab can be dismissed/closed */ this.dismissible = false; /** * Whether this tab is currently active (set by parent) */ this.active = false; } /** * Gets the icon element from the icon slot (if any) */ getIconElement() { return this.querySelector('[slot=\"icon\"]'); } render() { console.log('tab render'); return b `<slot></slot>`; } }",
286
286
  "description": "A tab for the kr-tab-group component."
287
287
  },
288
288
  {
@@ -536,7 +536,7 @@
536
536
  {
537
537
  "kind": "class",
538
538
  "description": "",
539
- "name": "De",
539
+ "name": "Be",
540
540
  "members": [
541
541
  {
542
542
  "kind": "method",
@@ -585,27 +585,27 @@
585
585
  },
586
586
  {
587
587
  "kind": "variable",
588
- "name": "Ie",
589
- "default": "class extends re{constructor(){super(...arguments),this._dialogRef=null,this._contentElement=null,this._handleDocumentKeyDown=e=>{\"Escape\"===e.key&&this._dialogRef?.close(void 0)}}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(\"keydown\",this._handleDocumentKeyDown)}static open(e,t){const i=document.querySelector(\"kr-dialog\");i&&i.remove();const o=new De,s=document.createElement(\"kr-dialog\");o.setDialogElement(s),s._dialogRef=o;const r=new e;return r.dialogRef=o,t?.data&&(r.data=t.data),s._contentElement=r,document.body.appendChild(s),document.addEventListener(\"keydown\",s._handleDocumentKeyDown),o}_handleBackdropClick(e){e.target.classList.contains(\"backdrop\")&&this._dialogRef?.close(void 0)}render(){return H` <div class=\"backdrop\" @click=${this._handleBackdropClick}></div> <div class=\"dialog\"> ${this._contentElement} </div> `}}"
588
+ "name": "He",
589
+ "default": "class extends re{constructor(){super(...arguments),this._dialogRef=null,this._contentElement=null,this.opened=!1,this.width=\"560px\",this._handleDocumentKeyDown=e=>{\"Escape\"===e.key&&this.close()}}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(\"keydown\",this._handleDocumentKeyDown)}updated(e){super.updated(e),e.has(\"opened\")&&(this.opened?document.addEventListener(\"keydown\",this._handleDocumentKeyDown):document.removeEventListener(\"keydown\",this._handleDocumentKeyDown))}open(){this.opened=!0}close(){this._dialogRef?this._dialogRef.close(void 0):(this.opened=!1,this.dispatchEvent(new CustomEvent(\"close\",{bubbles:!0,composed:!0})))}static open(e,t){document.querySelectorAll(\"kr-dialog\").forEach((e=>{e._dialogRef&&e.remove()}));const i=new Be,o=document.createElement(\"kr-dialog\");i.setDialogElement(o),o._dialogRef=i;const s=new e;return s.dialogRef=i,t?.data&&(s.data=t.data),o._contentElement=s,o.opened=!0,document.body.appendChild(o),i}_handleBackdropClick(e){e.target.classList.contains(\"backdrop\")&&this.close()}render(){return H` <div class=\"backdrop\" @click=${this._handleBackdropClick}></div> <div class=\"dialog\" style=${je({width:this.width})}> ${this._contentElement?this._contentElement:H`<slot></slot>`} </div> `}}"
590
590
  },
591
591
  {
592
592
  "kind": "variable",
593
- "name": "He"
593
+ "name": "Ne"
594
594
  },
595
595
  {
596
596
  "kind": "variable",
597
597
  "name": "We",
598
- "default": "class extends re{constructor(){super(...arguments),this.justified=!1,this.size=\"medium\"}updated(e){e.has(\"activeTabId\")&&this._updateActiveTab()}firstUpdated(){this._updateActiveTab()}_getTabs(){return Array.from(this.querySelectorAll(\"kr-tab\"))}_updateActiveTab(){const e=this._getTabs();0!==e.length&&(this.activeTabId||(this.activeTabId=e[0]?.id),e.forEach((e=>{e.active=e.id===this.activeTabId})),this.requestUpdate())}_handleTabClick(e){e.disabled||(this.activeTabId=e.id,this.dispatchEvent(new CustomEvent(\"tab-change\",{detail:{activeTabId:e.id},bubbles:!0,composed:!0})))}_handleTabDismiss(e,t){t.stopPropagation(),this.dispatchEvent(new CustomEvent(\"tab-dismiss\",{detail:{tabId:e.id},bubbles:!0,composed:!0}))}_handleKeyDown(e){const t=this._getTabs().filter((e=>!e.disabled)),i=t.findIndex((e=>e.id===this.activeTabId));let o=-1;switch(e.key){case\"ArrowLeft\":o=i>0?i-1:t.length-1;break;case\"ArrowRight\":o=i<t.length-1?i+1:0;break;case\"Home\":o=0;break;case\"End\":o=t.length-1}if(o>=0){e.preventDefault();const i=t[o];this.activeTabId=i.id,this.dispatchEvent(new CustomEvent(\"tab-change\",{detail:{activeTabId:i.id},bubbles:!0,composed:!0}));const s=this.shadowRoot?.querySelectorAll(\".label\"),r=Array.from(s||[]).find((e=>e.getAttribute(\"data-tab-id\")===i.id));r?.focus()}}_renderTabIcon(e){const t=e.getIconElement();if(!t)return U;const i=t.cloneNode(!0);return i.removeAttribute(\"slot\"),H`<span class=\"label-icon\">${i}</span>`}render(){return H` <div class=\"header\" role=\"tablist\" @keydown=${this._handleKeyDown}> ${this._getTabs().map((e=>H` <button class=${ke({label:!0,\"label--active\":e.id===this.activeTabId,\"label--justified\":this.justified})} role=\"tab\" data-tab-id=${e.id} aria-selected=${e.id===this.activeTabId} aria-controls=${`panel-${e.id}`} tabindex=${e.id===this.activeTabId?0:-1} ?disabled=${e.disabled} @click=${()=>this._handleTabClick(e)} > ${this._renderTabIcon(e)} <span>${e.title}</span> ${e.badge?H`<span class=\"label-badge\" style=${Ne({backgroundColor:e.badgeBackground,color:e.badgeColor})}>${e.badge}</span>`:U} ${e.dismissible?H` <button class=\"label-dismiss\" type=\"button\" aria-label=\"Close tab\" @click=${t=>this._handleTabDismiss(e,t)} > <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"12\" height=\"12\"><path fill-rule=\"evenodd\" d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\" clip-rule=\"evenodd\"/></svg> </button> `:U} </button> `))} </div> <div class=\"content\" role=\"tabpanel\" aria-labelledby=${this.activeTabId||\"\"}> <slot @slotchange=${this._updateActiveTab}></slot> </div> `}}"
598
+ "default": "class extends re{constructor(){super(...arguments),this.justified=!1,this.size=\"medium\"}updated(e){e.has(\"activeTabId\")&&this._updateActiveTab()}firstUpdated(){this._updateActiveTab()}_getTabs(){return Array.from(this.querySelectorAll(\"kr-tab\"))}_updateActiveTab(){const e=this._getTabs();0!==e.length&&(this.activeTabId||(this.activeTabId=e[0]?.id),e.forEach((e=>{e.active=e.id===this.activeTabId})),this.requestUpdate())}_handleTabClick(e){e.disabled||(this.activeTabId=e.id,this.dispatchEvent(new CustomEvent(\"tab-change\",{detail:{activeTabId:e.id},bubbles:!0,composed:!0})))}_handleTabDismiss(e,t){t.stopPropagation(),this.dispatchEvent(new CustomEvent(\"tab-dismiss\",{detail:{tabId:e.id},bubbles:!0,composed:!0}))}_handleKeyDown(e){const t=this._getTabs().filter((e=>!e.disabled)),i=t.findIndex((e=>e.id===this.activeTabId));let o=-1;switch(e.key){case\"ArrowLeft\":o=i>0?i-1:t.length-1;break;case\"ArrowRight\":o=i<t.length-1?i+1:0;break;case\"Home\":o=0;break;case\"End\":o=t.length-1}if(o>=0){e.preventDefault();const i=t[o];this.activeTabId=i.id,this.dispatchEvent(new CustomEvent(\"tab-change\",{detail:{activeTabId:i.id},bubbles:!0,composed:!0}));const s=this.shadowRoot?.querySelectorAll(\".label\"),r=Array.from(s||[]).find((e=>e.getAttribute(\"data-tab-id\")===i.id));r?.focus()}}_renderTabIcon(e){const t=e.getIconElement();if(!t)return U;const i=t.cloneNode(!0);return i.removeAttribute(\"slot\"),H`<span class=\"label-icon\">${i}</span>`}render(){return H` <div class=\"header\" role=\"tablist\" @keydown=${this._handleKeyDown}> ${this._getTabs().map((e=>H` <button class=${ke({label:!0,\"label--active\":e.id===this.activeTabId,\"label--justified\":this.justified})} role=\"tab\" data-tab-id=${e.id} aria-selected=${e.id===this.activeTabId} aria-controls=${`panel-${e.id}`} tabindex=${e.id===this.activeTabId?0:-1} ?disabled=${e.disabled} @click=${()=>this._handleTabClick(e)} > ${this._renderTabIcon(e)} <span>${e.label}</span> ${e.badge?H`<span class=\"label-badge\" style=${je({backgroundColor:e.badgeBackground,color:e.badgeColor})}>${e.badge}</span>`:U} ${e.dismissible?H` <button class=\"label-dismiss\" type=\"button\" aria-label=\"Close tab\" @click=${t=>this._handleTabDismiss(e,t)} > <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"12\" height=\"12\"><path fill-rule=\"evenodd\" d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\" clip-rule=\"evenodd\"/></svg> </button> `:U} </button> `))} </div> <div class=\"content\" role=\"tabpanel\" aria-labelledby=${this.activeTabId||\"\"}> <slot @slotchange=${this._updateActiveTab}></slot> </div> `}}"
599
599
  },
600
600
  {
601
601
  "kind": "variable",
602
602
  "name": "Ze",
603
- "default": "class extends re{constructor(){super(...arguments),this.id=\"\",this.title=\"\",this.badge=\"\",this.badgeBackground=\"\",this.badgeColor=\"\",this.disabled=!1,this.dismissible=!1,this.active=!1}getIconElement(){return this.querySelector('[slot=\"icon\"]')}render(){return H`<slot></slot>`}}"
603
+ "default": "class extends re{constructor(){super(...arguments),this.id=\"\",this.label=\"\",this.badge=\"\",this.badgeBackground=\"\",this.badgeColor=\"\",this.disabled=!1,this.dismissible=!1,this.active=!1}getIconElement(){return this.querySelector('[slot=\"icon\"]')}render(){return console.log(\"tab render\"),H`<slot></slot>`}}"
604
604
  },
605
605
  {
606
606
  "kind": "variable",
607
607
  "name": "Je",
608
- "default": "class extends re{constructor(){super(...arguments),this._scrollStyle=\"overlay\",this._data=[],this._dataState=\"idle\",this._page=1,this._pageSize=50,this._totalItems=0,this._totalPages=0,this._searchQuery=\"\",this._canScrollLeft=!1,this._canScrollRight=!1,this._canScrollHorizontal=!1,this._columnPickerOpen=!1,this._displayedColumns=[],this._resizing=null,this._resizeObserver=null,this._searchPositionLocked=!1,this._def={columns:[]},this.def={columns:[]},this._handleClickOutsideColumnPicker=e=>{if(!this._columnPickerOpen)return;const t=e.composedPath(),i=this.shadowRoot?.querySelector(\".column-picker-wrapper\");i&&!t.includes(i)&&(this._columnPickerOpen=!1)},this._handleResizeMove=e=>{if(!this._resizing)return;const t=this._def.columns.find((e=>e.id===this._resizing.columnId));if(t){const i=this._resizing.startWidth+(e.clientX-this._resizing.startX);t.width=`${Math.min(900,Math.max(50,i))}px`,this.requestUpdate()}},this._handleResizeEnd=()=>{this._resizing=null,document.removeEventListener(\"mousemove\",this._handleResizeMove),document.removeEventListener(\"mouseup\",this._handleResizeEnd)}}connectedCallback(){super.connectedCallback(),this.classList.toggle(\"kr-table--scroll-overlay\",\"overlay\"===this._scrollStyle),this.classList.toggle(\"kr-table--scroll-edge\",\"edge\"===this._scrollStyle),this._fetch(),this._initRefresh(),document.addEventListener(\"click\",this._handleClickOutsideColumnPicker),this._resizeObserver=new ResizeObserver((()=>{this._searchPositionLocked=!1,this._updateSearchPosition()})),this._resizeObserver.observe(this)}disconnectedCallback(){super.disconnectedCallback(),clearInterval(this._refreshTimer),document.removeEventListener(\"click\",this._handleClickOutsideColumnPicker),this._resizeObserver?.disconnect()}willUpdate(e){e.has(\"def\")&&(this._def={...this.def,columns:this.def.columns.map((e=>\"actions\"===e.type?{...e,label:e.label??\"\",sticky:\"right\",resizable:!1}:{...e}))},this._displayedColumns=this._def.displayedColumns||this._def.columns.map((e=>e.id)),this._fetch(),this._initRefresh())}updated(e){this._updateScrollFlags(),this._syncSlottedContent()}_syncSlottedContent(){const e=this.getDisplayedColumns().filter((e=>e.render));e.length&&(this.querySelectorAll('[slot^=\"cell-\"]').forEach((e=>e.remove())),this._data.forEach(((t,i)=>{e.forEach((e=>{const o=e.render(t),s=\"string\"==typeof o?o:\"\";if(s){const t=document.createElement(\"span\");t.slot=`cell-${i}-${e.id}`,\"actions\"===e.type&&(t.style.display=\"flex\",t.style.gap=\"8px\"),t.innerHTML=s,this.appendChild(t)}}))})))}refresh(){this._fetch()}goToPrevPage(){this._page>1&&(this._page--,this._fetch())}goToNextPage(){this._page<this._totalPages&&(this._page++,this._fetch())}goToPage(e){e>=1&&e<=this._totalPages&&(this._page=e,this._fetch())}_fetch(){if(!this._def.dataSource)return;let e;switch(this._dataState=\"loading\",this._def.dataSource.mode){case\"opensearch\":throw Error(\"Opensearch not supported yet\");case\"db\":e={page:this._page-1,size:this._pageSize,sorts:[],filterFields:[],queryFields:[],facetFields:[]},this._searchQuery?.trim().length&&this._def.columns.filter((e=>e.searchable)).forEach((t=>{e.queryFields.push({name:t.id,operation:\"CONTAINS\",value:this._searchQuery,and:!1})}));break;default:e={page:this._page-1,size:this._pageSize,sorts:[],filterFields:[],queryFields:[],facetFields:[]},this._searchQuery?.trim().length&&e.queryFields.push({name:\"_text_\",operation:\"IS\",value:Ge(this._searchQuery)})}this._def.dataSource.fetch(e).then((e=>{switch(this._def.dataSource?.mode){case\"opensearch\":throw Error(\"Opensearch not supported yet\");case\"db\":{const t=e;this._data=t.data.content,this._totalItems=t.data.totalElements,this._totalPages=t.data.totalPages,this._pageSize=t.data.size;break}default:{const t=e;this._data=t.data.content,this._totalItems=t.data.totalElements,this._totalPages=t.data.totalPages,this._pageSize=t.data.size}}this._dataState=\"success\",this._updateSearchPosition()})).catch((e=>{this._dataState=\"error\",He.show({message:e instanceof Error?e.message:\"Failed to load data\",type:\"error\"})}))}_initRefresh(){clearInterval(this._refreshTimer),this._def.refreshInterval&&this._def.refreshInterval>0&&(this._refreshTimer=window.setInterval((()=>{this._fetch()}),this._def.refreshInterval))}_handleSearch(e){const t=e.target;this._searchQuery=t.value,this._page=1,this._fetch()}_getGridTemplateColumns(){return this.getDisplayedColumns().map((e=>e.width?e.width:\"actions\"===e.type?\"max-content\":\"minmax(80px, auto)\")).join(\" \")}_updateSearchPosition(){if(this._searchPositionLocked)return;const e=this.shadowRoot?.querySelector(\".search\"),t=e?.querySelector(\".search-field\");e&&t&&(e.style.justifyContent=\"center\",t.style.marginLeft=\"\",requestAnimationFrame((()=>{const i=e.getBoundingClientRect(),o=t.getBoundingClientRect().left-i.left;e.style.justifyContent=\"flex-start\",t.style.marginLeft=`${o}px`,this._searchPositionLocked=!0})))}_toggleColumnPicker(){this._columnPickerOpen=!this._columnPickerOpen}_toggleColumn(e){this._displayedColumns.includes(e)?this._displayedColumns=this._displayedColumns.filter((t=>t!==e)):this._displayedColumns=[...this._displayedColumns,e]}getDisplayedColumns(){return this._displayedColumns.map((e=>this._def.columns.find((t=>t.id===e)))).sort(((e,t)=>\"actions\"===e.type&&\"actions\"!==t.type?1:\"actions\"!==e.type&&\"actions\"===t.type?-1:0))}_handleScroll(e){const t=e.target;this._canScrollLeft=t.scrollLeft>0,this._canScrollRight=t.scrollLeft<t.scrollWidth-t.clientWidth-1}_updateScrollFlags(){const e=this.shadowRoot?.querySelector(\".content\");e&&(this._canScrollLeft=e.scrollLeft>0,this._canScrollRight=e.scrollWidth>e.clientWidth&&e.scrollLeft<e.scrollWidth-e.clientWidth-1,this._canScrollHorizontal=e.scrollWidth>e.clientWidth),this.classList.toggle(\"kr-table--scroll-left-available\",this._canScrollLeft),this.classList.toggle(\"kr-table--scroll-right-available\",this._canScrollRight),this.classList.toggle(\"kr-table--scroll-horizontal-available\",this._canScrollHorizontal),this.classList.toggle(\"kr-table--sticky-left\",this.getDisplayedColumns().some((e=>\"left\"===e.sticky))),this.classList.toggle(\"kr-table--sticky-right\",this.getDisplayedColumns().some((e=>\"right\"===e.sticky)))}_handleResizeStart(e,t){e.preventDefault();const i=this.shadowRoot?.querySelector(`.header-cell[data-column-id=\"${t}\"]`);this._resizing={columnId:t,startX:e.clientX,startWidth:i?.offsetWidth||200},document.addEventListener(\"mousemove\",this._handleResizeMove),document.addEventListener(\"mouseup\",this._handleResizeEnd)}_handleAction(e){e.href||this.dispatchEvent(new CustomEvent(\"action\",{detail:{action:e.id},bubbles:!0,composed:!0}))}_renderCellContent(e,t,i){const o=t[e.id];if(e.render)return H`<slot name=\"cell-${i}-${e.id}\"></slot>`;if(null==o)return\"\";switch(e.type){case\"number\":return\"number\"==typeof o?o.toLocaleString():String(o);case\"currency\":return\"number\"==typeof o?o.toLocaleString(\"en-US\",{style:\"currency\",currency:\"USD\"}):String(o);case\"date\":{let e;if(o instanceof Date)e=o;else if(\"string\"==typeof o&&/^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}/.test(o)){const t=o.replace(/(\\d{2}:\\d{2}:\\d{2}):(\\d+)$/,\"$1.$2\").replace(\" \",\"T\")+\"Z\";e=new Date(t)}else e=new Date(o);return e.toLocaleString(void 0,{year:\"numeric\",month:\"short\",day:\"numeric\",hour:\"numeric\",minute:\"2-digit\"})}case\"boolean\":return!0===o?\"Yes\":!1===o?\"No\":\"\";default:return String(o)}}_getHeaderCellClasses(e,t){return{\"header-cell\":!0,\"header-cell--align-center\":\"center\"===e.align,\"header-cell--align-right\":\"right\"===e.align,\"header-cell--sticky-left\":\"left\"===e.sticky,\"header-cell--sticky-left-last\":\"left\"===e.sticky&&!this.getDisplayedColumns().slice(t+1).some((e=>\"left\"===e.sticky)),\"header-cell--sticky-right\":\"right\"===e.sticky,\"header-cell--sticky-right-first\":\"right\"===e.sticky&&!this.getDisplayedColumns().slice(0,t).some((e=>\"right\"===e.sticky))}}_getCellClasses(e,t){return{cell:!0,\"cell--actions\":\"actions\"===e.type,\"cell--align-center\":\"center\"===e.align,\"cell--align-right\":\"right\"===e.align,\"cell--sticky-left\":\"left\"===e.sticky,\"cell--sticky-left-last\":\"left\"===e.sticky&&!this.getDisplayedColumns().slice(t+1).some((e=>\"left\"===e.sticky)),\"cell--sticky-right\":\"right\"===e.sticky,\"cell--sticky-right-first\":\"right\"===e.sticky&&!this.getDisplayedColumns().slice(0,t).some((e=>\"right\"===e.sticky))}}_getCellStyle(e,t){const i={};if(\"left\"===e.sticky){let e=0;for(let i=0;i<t;i++){const t=this.getDisplayedColumns()[i];\"left\"===t.sticky&&(e+=parseInt(t.width||\"0\",10))}i.left=`${e}px`}if(\"right\"===e.sticky){let e=0;for(let i=t+1;i<this.getDisplayedColumns().length;i++){const t=this.getDisplayedColumns()[i];\"right\"===t.sticky&&(e+=parseInt(t.width||\"0\",10))}i.right=`${e}px`}return i}_renderPagination(){const e=(this._page-1)*this._pageSize+1,t=Math.min(this._page*this._pageSize,this._totalItems);return H` <div class=\"pagination\"> <span class=\"pagination-icon ${1===this._page?\"pagination-icon--disabled\":\"\"}\" @click=${this.goToPrevPage} > <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"/></svg> </span> <span class=\"pagination-info\">${e}-${t} of ${this._totalItems}</span> <span class=\"pagination-icon ${this._page===this._totalPages?\"pagination-icon--disabled\":\"\"}\" @click=${this.goToNextPage} > <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"/></svg> </span> </div> `}_renderHeader(){return!this._def.title&&!this._def.actions?.length&&this._totalPages<=1?U:H` <div class=\"header\"> <div class=\"title\">${this._def.title??\"\"}</div> ${\"db\"!==this._def.dataSource?.mode||this._def.columns.some((e=>e.searchable))?H` <div class=\"search\"> <!-- TODO: Saved views dropdown <div class=\"views\"> <span>Default View</span> <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z\"/></svg> </div> --> <div class=\"search-field\"> <svg class=\"search-icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z\"/></svg> <input type=\"text\" class=\"search-input\" placeholder=\"Search...\" .value=${this._searchQuery} @input=${this._handleSearch} /> </div> </div> `:H`<div class=\"search\"></div>`} <div class=\"tools\"> ${this._renderPagination()} <span class=\"refresh\" title=\"Refresh\" @click=${()=>this.refresh()}> <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M480-160q-134 0-227-93t-93-227q0-134 93-227t227-93q69 0 132 28.5T720-690v-110h80v280H520v-80h168q-32-56-87.5-88T480-720q-100 0-170 70t-70 170q0 100 70 170t170 70q77 0 139-44t87-116h84q-28 106-114 173t-196 67Z\"/></svg> </span> <div class=\"column-picker-wrapper\"> <span class=\"header-icon\" title=\"Columns\" @click=${this._toggleColumnPicker}> <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M121-280v-400q0-33 23.5-56.5T201-760h559q33 0 56.5 23.5T840-680v400q0 33-23.5 56.5T760-200H201q-33 0-56.5-23.5T121-280Zm79 0h133v-400H200v400Zm213 0h133v-400H413v400Zm213 0h133v-400H626v400Z\"/></svg> </span> <div class=\"column-picker ${this._columnPickerOpen?\"open\":\"\"}\"> ${[...this._def.columns].filter((e=>\"actions\"!==e.type)).sort(((e,t)=>(e.label??e.id).localeCompare(t.label??t.id))).map((e=>H` <div class=\"column-picker-item\" @click=${()=>this._toggleColumn(e.id)}> <div class=\"column-picker-checkbox ${this._displayedColumns.includes(e.id)?\"checked\":\"\"}\"> <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"/></svg> </div> <span class=\"column-picker-label\">${e.label??e.id}</span> </div> `))} </div> </div> ${1===this._def.actions?.length?H` <kr-button class=\"actions\" .href=${this._def.actions[0].href} .target=${this._def.actions[0].target} @click=${()=>this._handleAction(this._def.actions[0])} > ${this._def.actions[0].label} </kr-button> `:this._def.actions?.length?H` <kr-button class=\"actions\" .options=${this._def.actions.map((e=>({id:e.id,label:e.label})))} @option-select=${e=>this._handleAction({id:e.detail.id,label:e.detail.label})} > Actions </kr-button> `:U} </div> </div> `}_renderStatus(){return\"loading\"===this._dataState&&0===this._data.length?H`<div class=\"status\">Loading...</div>`:\"error\"===this._dataState&&0===this._data.length?H`<div class=\"status status--error\">Error loading data</div>`:0===this._data.length?H`<div class=\"status\">No data available</div>`:U}_renderTable(){return H` <div class=\"wrapper\"> <div class=\"overlay-left\"></div> <div class=\"overlay-right\"></div> ${this._renderStatus()} <div class=\"content\" @scroll=${this._handleScroll}> <div class=\"table\" style=\"grid-template-columns: ${this._getGridTemplateColumns()}\"> <div class=\"header-row\"> ${this.getDisplayedColumns().map(((e,t)=>H` <div class=${ke(this._getHeaderCellClasses(e,t))} style=${Ne(this._getCellStyle(e,t))} data-column-id=${e.id} >${e.label??e.id}${!1!==e.resizable?H`<div class=\"header-cell__resize\" @mousedown=${t=>this._handleResizeStart(t,e.id)} ></div>`:U}</div> `))} </div> ${this._data.map(((e,t)=>H` <div class=\"row\"> ${this.getDisplayedColumns().map(((i,o)=>H` <div class=${ke(this._getCellClasses(i,o))} style=${Ne(this._getCellStyle(i,o))} data-column-id=${i.id} > ${this._renderCellContent(i,e,t)} </div> `))} </div> `))} </div> </div> </div> `}render(){return this._def.columns.length?H` ${this._renderHeader()} ${this._renderTable()} `:H`<slot></slot>`}}"
608
+ "default": "class extends re{constructor(){super(...arguments),this._scrollStyle=\"overlay\",this._data=[],this._dataState=\"idle\",this._page=1,this._pageSize=50,this._totalItems=0,this._totalPages=0,this._searchQuery=\"\",this._canScrollLeft=!1,this._canScrollRight=!1,this._canScrollHorizontal=!1,this._columnPickerOpen=!1,this._displayedColumns=[],this._resizing=null,this._resizeObserver=null,this._searchPositionLocked=!1,this._def={columns:[]},this.def={columns:[]},this._handleClickOutsideColumnPicker=e=>{if(!this._columnPickerOpen)return;const t=e.composedPath(),i=this.shadowRoot?.querySelector(\".column-picker-wrapper\");i&&!t.includes(i)&&(this._columnPickerOpen=!1)},this._handleResizeMove=e=>{if(!this._resizing)return;const t=this._def.columns.find((e=>e.id===this._resizing.columnId));if(t){const i=this._resizing.startWidth+(e.clientX-this._resizing.startX);t.width=`${Math.min(900,Math.max(50,i))}px`,this.requestUpdate()}},this._handleResizeEnd=()=>{this._resizing=null,document.removeEventListener(\"mousemove\",this._handleResizeMove),document.removeEventListener(\"mouseup\",this._handleResizeEnd)}}connectedCallback(){super.connectedCallback(),this.classList.toggle(\"kr-table--scroll-overlay\",\"overlay\"===this._scrollStyle),this.classList.toggle(\"kr-table--scroll-edge\",\"edge\"===this._scrollStyle),this._fetch(),this._initRefresh(),document.addEventListener(\"click\",this._handleClickOutsideColumnPicker),this._resizeObserver=new ResizeObserver((()=>{this._searchPositionLocked=!1,this._updateSearchPosition()})),this._resizeObserver.observe(this)}disconnectedCallback(){super.disconnectedCallback(),clearInterval(this._refreshTimer),document.removeEventListener(\"click\",this._handleClickOutsideColumnPicker),this._resizeObserver?.disconnect()}willUpdate(e){e.has(\"def\")&&(this._def={...this.def,columns:this.def.columns.map((e=>\"actions\"===e.type?{...e,label:e.label??\"\",sticky:\"right\",resizable:!1}:{...e}))},this._displayedColumns=this._def.displayedColumns||this._def.columns.map((e=>e.id)),this._fetch(),this._initRefresh())}updated(e){this._updateScrollFlags(),this._syncSlottedContent()}_syncSlottedContent(){const e=this.getDisplayedColumns().filter((e=>e.render));e.length&&(this.querySelectorAll('[slot^=\"cell-\"]').forEach((e=>e.remove())),this._data.forEach(((t,i)=>{e.forEach((e=>{const o=e.render(t),s=\"string\"==typeof o?o:\"\";if(s){const t=document.createElement(\"span\");t.slot=`cell-${i}-${e.id}`,\"actions\"===e.type&&(t.style.display=\"flex\",t.style.gap=\"8px\"),t.innerHTML=s,this.appendChild(t)}}))})))}refresh(){this._fetch()}goToPrevPage(){this._page>1&&(this._page--,this._fetch())}goToNextPage(){this._page<this._totalPages&&(this._page++,this._fetch())}goToPage(e){e>=1&&e<=this._totalPages&&(this._page=e,this._fetch())}_fetch(){if(!this._def.dataSource)return;let e;switch(this._dataState=\"loading\",this._def.dataSource.mode){case\"opensearch\":throw Error(\"Opensearch not supported yet\");case\"db\":e={page:this._page-1,size:this._pageSize,sorts:[],filterFields:[],queryFields:[],facetFields:[]},this._searchQuery?.trim().length&&this._def.columns.filter((e=>e.searchable)).forEach((t=>{e.queryFields.push({name:t.id,operation:\"CONTAINS\",value:this._searchQuery,and:!1})}));break;default:e={page:this._page-1,size:this._pageSize,sorts:[],filterFields:[],queryFields:[],facetFields:[]},this._searchQuery?.trim().length&&e.queryFields.push({name:\"_text_\",operation:\"IS\",value:Ge(this._searchQuery)})}this._def.dataSource.fetch(e).then((e=>{switch(this._def.dataSource?.mode){case\"opensearch\":throw Error(\"Opensearch not supported yet\");case\"db\":{const t=e;this._data=t.data.content,this._totalItems=t.data.totalElements,this._totalPages=t.data.totalPages,this._pageSize=t.data.size;break}default:{const t=e;this._data=t.data.content,this._totalItems=t.data.totalElements,this._totalPages=t.data.totalPages,this._pageSize=t.data.size}}this._dataState=\"success\",this._updateSearchPosition()})).catch((e=>{this._dataState=\"error\",Ne.show({message:e instanceof Error?e.message:\"Failed to load data\",type:\"error\"})}))}_initRefresh(){clearInterval(this._refreshTimer),this._def.refreshInterval&&this._def.refreshInterval>0&&(this._refreshTimer=window.setInterval((()=>{this._fetch()}),this._def.refreshInterval))}_handleSearch(e){const t=e.target;this._searchQuery=t.value,this._page=1,this._fetch()}_getGridTemplateColumns(){return this.getDisplayedColumns().map((e=>e.width?e.width:\"actions\"===e.type?\"max-content\":\"minmax(80px, auto)\")).join(\" \")}_updateSearchPosition(){if(this._searchPositionLocked)return;const e=this.shadowRoot?.querySelector(\".search\"),t=e?.querySelector(\".search-field\");e&&t&&(e.style.justifyContent=\"center\",t.style.marginLeft=\"\",requestAnimationFrame((()=>{const i=e.getBoundingClientRect(),o=t.getBoundingClientRect().left-i.left;e.style.justifyContent=\"flex-start\",t.style.marginLeft=`${o}px`,this._searchPositionLocked=!0})))}_toggleColumnPicker(){this._columnPickerOpen=!this._columnPickerOpen}_toggleColumn(e){this._displayedColumns.includes(e)?this._displayedColumns=this._displayedColumns.filter((t=>t!==e)):this._displayedColumns=[...this._displayedColumns,e]}getDisplayedColumns(){return this._displayedColumns.map((e=>this._def.columns.find((t=>t.id===e)))).sort(((e,t)=>\"actions\"===e.type&&\"actions\"!==t.type?1:\"actions\"!==e.type&&\"actions\"===t.type?-1:0))}_handleScroll(e){const t=e.target;this._canScrollLeft=t.scrollLeft>0,this._canScrollRight=t.scrollLeft<t.scrollWidth-t.clientWidth-1}_updateScrollFlags(){const e=this.shadowRoot?.querySelector(\".content\");e&&(this._canScrollLeft=e.scrollLeft>0,this._canScrollRight=e.scrollWidth>e.clientWidth&&e.scrollLeft<e.scrollWidth-e.clientWidth-1,this._canScrollHorizontal=e.scrollWidth>e.clientWidth),this.classList.toggle(\"kr-table--scroll-left-available\",this._canScrollLeft),this.classList.toggle(\"kr-table--scroll-right-available\",this._canScrollRight),this.classList.toggle(\"kr-table--scroll-horizontal-available\",this._canScrollHorizontal),this.classList.toggle(\"kr-table--sticky-left\",this.getDisplayedColumns().some((e=>\"left\"===e.sticky))),this.classList.toggle(\"kr-table--sticky-right\",this.getDisplayedColumns().some((e=>\"right\"===e.sticky)))}_handleResizeStart(e,t){e.preventDefault();const i=this.shadowRoot?.querySelector(`.header-cell[data-column-id=\"${t}\"]`);this._resizing={columnId:t,startX:e.clientX,startWidth:i?.offsetWidth||200},document.addEventListener(\"mousemove\",this._handleResizeMove),document.addEventListener(\"mouseup\",this._handleResizeEnd)}_handleAction(e){e.href||this.dispatchEvent(new CustomEvent(\"action\",{detail:{action:e.id},bubbles:!0,composed:!0}))}_renderCellContent(e,t,i){const o=t[e.id];if(e.render)return H`<slot name=\"cell-${i}-${e.id}\"></slot>`;if(null==o)return\"\";switch(e.type){case\"number\":return\"number\"==typeof o?o.toLocaleString():String(o);case\"currency\":return\"number\"==typeof o?o.toLocaleString(\"en-US\",{style:\"currency\",currency:\"USD\"}):String(o);case\"date\":{let e;if(o instanceof Date)e=o;else if(\"string\"==typeof o&&/^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}/.test(o)){const t=o.replace(/(\\d{2}:\\d{2}:\\d{2}):(\\d+)$/,\"$1.$2\").replace(\" \",\"T\")+\"Z\";e=new Date(t)}else e=new Date(o);return e.toLocaleString(void 0,{year:\"numeric\",month:\"short\",day:\"numeric\",hour:\"numeric\",minute:\"2-digit\"})}case\"boolean\":return!0===o?\"Yes\":!1===o?\"No\":\"\";default:return String(o)}}_getHeaderCellClasses(e,t){return{\"header-cell\":!0,\"header-cell--align-center\":\"center\"===e.align,\"header-cell--align-right\":\"right\"===e.align,\"header-cell--sticky-left\":\"left\"===e.sticky,\"header-cell--sticky-left-last\":\"left\"===e.sticky&&!this.getDisplayedColumns().slice(t+1).some((e=>\"left\"===e.sticky)),\"header-cell--sticky-right\":\"right\"===e.sticky,\"header-cell--sticky-right-first\":\"right\"===e.sticky&&!this.getDisplayedColumns().slice(0,t).some((e=>\"right\"===e.sticky))}}_getCellClasses(e,t){return{cell:!0,\"cell--actions\":\"actions\"===e.type,\"cell--align-center\":\"center\"===e.align,\"cell--align-right\":\"right\"===e.align,\"cell--sticky-left\":\"left\"===e.sticky,\"cell--sticky-left-last\":\"left\"===e.sticky&&!this.getDisplayedColumns().slice(t+1).some((e=>\"left\"===e.sticky)),\"cell--sticky-right\":\"right\"===e.sticky,\"cell--sticky-right-first\":\"right\"===e.sticky&&!this.getDisplayedColumns().slice(0,t).some((e=>\"right\"===e.sticky))}}_getCellStyle(e,t){const i={};if(\"left\"===e.sticky){let e=0;for(let i=0;i<t;i++){const t=this.getDisplayedColumns()[i];\"left\"===t.sticky&&(e+=parseInt(t.width||\"0\",10))}i.left=`${e}px`}if(\"right\"===e.sticky){let e=0;for(let i=t+1;i<this.getDisplayedColumns().length;i++){const t=this.getDisplayedColumns()[i];\"right\"===t.sticky&&(e+=parseInt(t.width||\"0\",10))}i.right=`${e}px`}return i}_renderPagination(){const e=(this._page-1)*this._pageSize+1,t=Math.min(this._page*this._pageSize,this._totalItems);return H` <div class=\"pagination\"> <span class=\"pagination-icon ${1===this._page?\"pagination-icon--disabled\":\"\"}\" @click=${this.goToPrevPage} > <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"/></svg> </span> <span class=\"pagination-info\">${e}-${t} of ${this._totalItems}</span> <span class=\"pagination-icon ${this._page===this._totalPages?\"pagination-icon--disabled\":\"\"}\" @click=${this.goToNextPage} > <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"/></svg> </span> </div> `}_renderHeader(){return!this._def.title&&!this._def.actions?.length&&this._totalPages<=1?U:H` <div class=\"header\"> <div class=\"title\">${this._def.title??\"\"}</div> ${\"db\"!==this._def.dataSource?.mode||this._def.columns.some((e=>e.searchable))?H` <div class=\"search\"> <!-- TODO: Saved views dropdown <div class=\"views\"> <span>Default View</span> <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z\"/></svg> </div> --> <div class=\"search-field\"> <svg class=\"search-icon\" viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z\"/></svg> <input type=\"text\" class=\"search-input\" placeholder=\"Search...\" .value=${this._searchQuery} @input=${this._handleSearch} /> </div> </div> `:H`<div class=\"search\"></div>`} <div class=\"tools\"> ${this._renderPagination()} <span class=\"refresh\" title=\"Refresh\" @click=${()=>this.refresh()}> <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M480-160q-134 0-227-93t-93-227q0-134 93-227t227-93q69 0 132 28.5T720-690v-110h80v280H520v-80h168q-32-56-87.5-88T480-720q-100 0-170 70t-70 170q0 100 70 170t170 70q77 0 139-44t87-116h84q-28 106-114 173t-196 67Z\"/></svg> </span> <div class=\"column-picker-wrapper\"> <span class=\"header-icon\" title=\"Columns\" @click=${this._toggleColumnPicker}> <svg viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M121-280v-400q0-33 23.5-56.5T201-760h559q33 0 56.5 23.5T840-680v400q0 33-23.5 56.5T760-200H201q-33 0-56.5-23.5T121-280Zm79 0h133v-400H200v400Zm213 0h133v-400H413v400Zm213 0h133v-400H626v400Z\"/></svg> </span> <div class=\"column-picker ${this._columnPickerOpen?\"open\":\"\"}\"> ${[...this._def.columns].filter((e=>\"actions\"!==e.type)).sort(((e,t)=>(e.label??e.id).localeCompare(t.label??t.id))).map((e=>H` <div class=\"column-picker-item\" @click=${()=>this._toggleColumn(e.id)}> <div class=\"column-picker-checkbox ${this._displayedColumns.includes(e.id)?\"checked\":\"\"}\"> <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z\"/></svg> </div> <span class=\"column-picker-label\">${e.label??e.id}</span> </div> `))} </div> </div> ${1===this._def.actions?.length?H` <kr-button class=\"actions\" .href=${this._def.actions[0].href} .target=${this._def.actions[0].target} @click=${()=>this._handleAction(this._def.actions[0])} > ${this._def.actions[0].label} </kr-button> `:this._def.actions?.length?H` <kr-button class=\"actions\" .options=${this._def.actions.map((e=>({id:e.id,label:e.label})))} @option-select=${e=>this._handleAction({id:e.detail.id,label:e.detail.label})} > Actions </kr-button> `:U} </div> </div> `}_renderStatus(){return\"loading\"===this._dataState&&0===this._data.length?H`<div class=\"status\">Loading...</div>`:\"error\"===this._dataState&&0===this._data.length?H`<div class=\"status status--error\">Error loading data</div>`:0===this._data.length?H`<div class=\"status\">No data available</div>`:U}_renderTable(){return H` <div class=\"wrapper\"> <div class=\"overlay-left\"></div> <div class=\"overlay-right\"></div> ${this._renderStatus()} <div class=\"content\" @scroll=${this._handleScroll}> <div class=\"table\" style=\"grid-template-columns: ${this._getGridTemplateColumns()}\"> <div class=\"header-row\"> ${this.getDisplayedColumns().map(((e,t)=>H` <div class=${ke(this._getHeaderCellClasses(e,t))} style=${je(this._getCellStyle(e,t))} data-column-id=${e.id} >${e.label??e.id}${!1!==e.resizable?H`<div class=\"header-cell__resize\" @mousedown=${t=>this._handleResizeStart(t,e.id)} ></div>`:U}</div> `))} </div> ${this._data.map(((e,t)=>H` <div class=\"row\"> ${this.getDisplayedColumns().map(((i,o)=>H` <div class=${ke(this._getCellClasses(i,o))} style=${je(this._getCellStyle(i,o))} data-column-id=${i.id} > ${this._renderCellContent(i,e,t)} </div> `))} </div> `))} </div> </div> </div> `}render(){return this._def.columns.length?H` ${this._renderHeader()} ${this._renderTable()} `:H`<slot></slot>`}}"
609
609
  },
610
610
  {
611
611
  "kind": "variable",
@@ -699,7 +699,7 @@
699
699
  "kind": "js",
700
700
  "name": "KRDialog",
701
701
  "declaration": {
702
- "name": "Ie",
702
+ "name": "He",
703
703
  "module": "dist/krubble-components.bundled.min.js"
704
704
  }
705
705
  },
@@ -707,7 +707,7 @@
707
707
  "kind": "js",
708
708
  "name": "KRDialogRef",
709
709
  "declaration": {
710
- "name": "De",
710
+ "name": "Be",
711
711
  "module": "dist/krubble-components.bundled.min.js"
712
712
  }
713
713
  },
@@ -739,7 +739,7 @@
739
739
  "kind": "js",
740
740
  "name": "KRSnackbar",
741
741
  "declaration": {
742
- "name": "He",
742
+ "name": "Ne",
743
743
  "module": "dist/krubble-components.bundled.min.js"
744
744
  }
745
745
  },
@@ -1282,8 +1282,8 @@
1282
1282
  {
1283
1283
  "kind": "variable",
1284
1284
  "name": "KRDialog",
1285
- "default": "class KRDialog extends LitElement { constructor() { super(...arguments); this._dialogRef = null; this._contentElement = null; this._handleDocumentKeyDown = (e) => { if (e.key === 'Escape') { this._dialogRef?.close(undefined); } }; } disconnectedCallback() { super.disconnectedCallback(); document.removeEventListener('keydown', this._handleDocumentKeyDown); } static open(component, config) { const existing = document.querySelector('kr-dialog'); if (existing) { existing.remove(); } const dialogRef = new KRDialogRef(); const dialog = document.createElement('kr-dialog'); dialogRef.setDialogElement(dialog); dialog._dialogRef = dialogRef; // Create the content component const content = new component(); content.dialogRef = dialogRef; if (config?.data) { content.data = config.data; } dialog._contentElement = content; document.body.appendChild(dialog); document.addEventListener('keydown', dialog._handleDocumentKeyDown); return dialogRef; } _handleBackdropClick(e) { if (e.target.classList.contains('backdrop')) { this._dialogRef?.close(undefined); } } render() { return html ` <div class=\"backdrop\" @click=${this._handleBackdropClick}></div> <div class=\"dialog\"> ${this._contentElement} </div> `; } }",
1286
- "description": "Generic dialog component that renders a Lit component inside a dialog shell."
1285
+ "default": "class KRDialog extends LitElement { constructor() { super(...arguments); this._dialogRef = null; this._contentElement = null; this.opened = false; this.width = '560px'; this._handleDocumentKeyDown = (e) => { if (e.key === 'Escape') { this.close(); } }; } disconnectedCallback() { super.disconnectedCallback(); document.removeEventListener('keydown', this._handleDocumentKeyDown); } updated(changedProperties) { super.updated(changedProperties); if (changedProperties.has('opened')) { if (this.opened) { document.addEventListener('keydown', this._handleDocumentKeyDown); } else { document.removeEventListener('keydown', this._handleDocumentKeyDown); } } } /** * Opens the dialog (declarative mode). */ open() { this.opened = true; } /** * Closes the dialog. * In programmatic mode (has _dialogRef), delegates to the dialog ref. * In declarative mode, sets opened=false and dispatches close event. */ close() { if (this._dialogRef) { this._dialogRef.close(undefined); return; } this.opened = false; this.dispatchEvent(new CustomEvent('close', { bubbles: true, composed: true })); } /** * Opens a dialog programmatically by creating a component and injecting it. */ static open(component, config) { // Only remove other programmatic dialogs (those with a _dialogRef) document.querySelectorAll('kr-dialog').forEach((el) => { if (el._dialogRef) { el.remove(); } }); const dialogRef = new KRDialogRef(); const dialog = document.createElement('kr-dialog'); dialogRef.setDialogElement(dialog); dialog._dialogRef = dialogRef; // Create the content component const content = new component(); content.dialogRef = dialogRef; if (config?.data) { content.data = config.data; } dialog._contentElement = content; dialog.opened = true; document.body.appendChild(dialog); return dialogRef; } _handleBackdropClick(e) { if (e.target.classList.contains('backdrop')) { this.close(); } } render() { return html ` <div class=\"backdrop\" @click=${this._handleBackdropClick}></div> <div class=\"dialog\" style=${styleMap({ width: this.width })}> ${this._contentElement ? this._contentElement : html `<slot></slot>`} </div> `; } }",
1286
+ "description": "Generic dialog component that supports both declarative and programmatic usage.\n\nDeclarative: place `<kr-dialog>` in HTML with slotted content and call `.open()` / `.close()`.\nProgrammatic: use `KRDialog.open(Component, config)` to create and show a dialog."
1287
1287
  }
1288
1288
  ],
1289
1289
  "exports": [
@@ -1376,6 +1376,36 @@
1376
1376
  }
1377
1377
  ]
1378
1378
  },
1379
+ {
1380
+ "kind": "javascript-module",
1381
+ "path": "dist/monaco/monaco.js",
1382
+ "declarations": [
1383
+ {
1384
+ "kind": "variable",
1385
+ "name": "KRMonaco",
1386
+ "default": "class KRMonaco extends LitElement { constructor() { super(...arguments); this._headObserver = null; this.options = {}; this.editor = null; } firstUpdated() { requestAnimationFrame(() => { this._copyMonacoStyles(); this._initEditor(); }); } disconnectedCallback() { super.disconnectedCallback(); if (this._headObserver) { this._headObserver.disconnect(); this._headObserver = null; } if (this.editor) { this.editor.dispose(); this.editor = null; } } _isMonacoStyle(text) { return text.includes('.monaco-') || text.includes('.codicon'); } _copyMonacoStyles() { if (!this.shadowRoot) { return; } document.head.querySelectorAll('style').forEach((style) => { if (style.textContent && this._isMonacoStyle(style.textContent)) { this.shadowRoot.appendChild(style.cloneNode(true)); } }); this._headObserver = new MutationObserver((mutations) => { mutations.forEach((mutation) => { mutation.addedNodes.forEach((node) => { if (node instanceof HTMLStyleElement && node.textContent && this._isMonacoStyle(node.textContent)) { this.shadowRoot.appendChild(node.cloneNode(true)); } }); }); }); this._headObserver.observe(document.head, { childList: true }); } _initEditor() { const container = this.shadowRoot?.querySelector('#container'); if (!container) { return; } this.editor = monaco.editor.create(container, this.options); this.dispatchEvent(new CustomEvent('ready', { detail: { editor: this.editor }, bubbles: true, composed: true, })); } render() { return html `<div id=\"container\"></div>`; } }",
1387
+ "description": "A Monaco Editor wrapper that handles shadow DOM boilerplate.\n\nCopies Monaco's injected styles from document.head into the shadow root\nand watches for new styles added later via MutationObserver. Applies CSS\nfixes for the find widget inside shadow DOM. Disposes the editor and\nobserver on disconnect.\n\nConsumers get full access to the Monaco API via the `editor` property.\nPass editor configuration through the `options` property before the\nelement connects, or call `editor.updateOptions()` after."
1388
+ }
1389
+ ],
1390
+ "exports": [
1391
+ {
1392
+ "kind": "js",
1393
+ "name": "KRMonaco",
1394
+ "declaration": {
1395
+ "name": "KRMonaco",
1396
+ "module": "dist/monaco/monaco.js"
1397
+ }
1398
+ },
1399
+ {
1400
+ "kind": "js",
1401
+ "name": "monaco",
1402
+ "declaration": {
1403
+ "name": "monaco",
1404
+ "module": "dist/monaco/monaco.js"
1405
+ }
1406
+ }
1407
+ ]
1408
+ },
1379
1409
  {
1380
1410
  "kind": "javascript-module",
1381
1411
  "path": "dist/progress-bar/progress-bar.js",
@@ -1491,7 +1521,7 @@
1491
1521
  {
1492
1522
  "kind": "variable",
1493
1523
  "name": "KRTab",
1494
- "default": "class KRTab extends LitElement { constructor() { super(...arguments); /** * Unique identifier for the tab */ this.id = ''; /** * Display title for the tab */ this.title = ''; /** * Badge text displayed next to title (e.g. notification count) */ this.badge = ''; /** * Badge background color */ this.badgeBackground = ''; /** * Badge text color */ this.badgeColor = ''; /** * Whether the tab is disabled */ this.disabled = false; /** * Whether the tab can be dismissed/closed */ this.dismissible = false; /** * Whether this tab is currently active (set by parent) */ this.active = false; } /** * Gets the icon element from the icon slot (if any) */ getIconElement() { return this.querySelector('[slot=\"icon\"]'); } render() { return html `<slot></slot>`; } }",
1524
+ "default": "class KRTab extends LitElement { constructor() { super(...arguments); /** * Unique identifier for the tab */ this.id = ''; /** * Display label for the tab */ this.label = ''; /** * Badge text displayed next to label (e.g. notification count) */ this.badge = ''; /** * Badge background color */ this.badgeBackground = ''; /** * Badge text color */ this.badgeColor = ''; /** * Whether the tab is disabled */ this.disabled = false; /** * Whether the tab can be dismissed/closed */ this.dismissible = false; /** * Whether this tab is currently active (set by parent) */ this.active = false; } /** * Gets the icon element from the icon slot (if any) */ getIconElement() { return this.querySelector('[slot=\"icon\"]'); } render() { console.log('tab render'); return html `<slot></slot>`; } }",
1495
1525
  "description": "A tab for the kr-tab-group component."
1496
1526
  }
1497
1527
  ],
@@ -1513,7 +1543,7 @@
1513
1543
  {
1514
1544
  "kind": "variable",
1515
1545
  "name": "KRTabGroup",
1516
- "default": "class KRTabGroup extends LitElement { constructor() { super(...arguments); /** * Whether tabs should stretch to fill the full width evenly */ this.justified = false; /** * Size of the tabs: 'small' | 'medium' | 'large' */ this.size = 'medium'; } updated(changes) { if (changes.has('activeTabId')) { this._updateActiveTab(); } } firstUpdated() { this._updateActiveTab(); } _getTabs() { return Array.from(this.querySelectorAll('kr-tab')); } _updateActiveTab() { const tabs = this._getTabs(); if (tabs.length === 0) return; if (!this.activeTabId) { this.activeTabId = tabs[0]?.id; } tabs.forEach((tab) => { tab.active = tab.id === this.activeTabId; }); this.requestUpdate(); } _handleTabClick(tab) { if (tab.disabled) return; this.activeTabId = tab.id; this.dispatchEvent(new CustomEvent('tab-change', { detail: { activeTabId: tab.id }, bubbles: true, composed: true, })); } _handleTabDismiss(tab, e) { e.stopPropagation(); this.dispatchEvent(new CustomEvent('tab-dismiss', { detail: { tabId: tab.id }, bubbles: true, composed: true, })); } _handleKeyDown(e) { const enabledTabs = this._getTabs().filter((t) => !t.disabled); const currentIndex = enabledTabs.findIndex((t) => t.id === this.activeTabId); let newIndex = -1; switch (e.key) { case 'ArrowLeft': newIndex = currentIndex > 0 ? currentIndex - 1 : enabledTabs.length - 1; break; case 'ArrowRight': newIndex = currentIndex < enabledTabs.length - 1 ? currentIndex + 1 : 0; break; case 'Home': newIndex = 0; break; case 'End': newIndex = enabledTabs.length - 1; break; } if (newIndex >= 0) { e.preventDefault(); const newTab = enabledTabs[newIndex]; this.activeTabId = newTab.id; this.dispatchEvent(new CustomEvent('tab-change', { detail: { activeTabId: newTab.id }, bubbles: true, composed: true, })); const tabButtons = this.shadowRoot?.querySelectorAll('.label'); const targetButton = Array.from(tabButtons || []).find((btn) => btn.getAttribute('data-tab-id') === newTab.id); targetButton?.focus(); } } _renderTabIcon(tab) { const iconElement = tab.getIconElement(); if (!iconElement) return nothing; // Clone the icon element to render in the header const clonedIcon = iconElement.cloneNode(true); clonedIcon.removeAttribute('slot'); return html `<span class=\"label-icon\">${clonedIcon}</span>`; } render() { return html ` <div class=\"header\" role=\"tablist\" @keydown=${this._handleKeyDown}> ${this._getTabs().map((tab) => html ` <button class=${classMap({ label: true, 'label--active': tab.id === this.activeTabId, 'label--justified': this.justified, })} role=\"tab\" data-tab-id=${tab.id} aria-selected=${tab.id === this.activeTabId} aria-controls=${`panel-${tab.id}`} tabindex=${tab.id === this.activeTabId ? 0 : -1} ?disabled=${tab.disabled} @click=${() => this._handleTabClick(tab)} > ${this._renderTabIcon(tab)} <span>${tab.title}</span> ${tab.badge ? html `<span class=\"label-badge\" style=${styleMap({ backgroundColor: tab.badgeBackground, color: tab.badgeColor })}>${tab.badge}</span>` : nothing} ${tab.dismissible ? html ` <button class=\"label-dismiss\" type=\"button\" aria-label=\"Close tab\" @click=${(e) => this._handleTabDismiss(tab, e)} > <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"12\" height=\"12\"><path fill-rule=\"evenodd\" d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\" clip-rule=\"evenodd\"/></svg> </button> ` : nothing} </button> `)} </div> <div class=\"content\" role=\"tabpanel\" aria-labelledby=${this.activeTabId || ''}> <slot @slotchange=${this._updateActiveTab}></slot> </div> `; } }",
1546
+ "default": "class KRTabGroup extends LitElement { constructor() { super(...arguments); /** * Whether tabs should stretch to fill the full width evenly */ this.justified = false; /** * Size of the tabs: 'small' | 'medium' | 'large' */ this.size = 'medium'; } updated(changes) { if (changes.has('activeTabId')) { this._updateActiveTab(); } } firstUpdated() { this._updateActiveTab(); } _getTabs() { return Array.from(this.querySelectorAll('kr-tab')); } _updateActiveTab() { const tabs = this._getTabs(); if (tabs.length === 0) return; if (!this.activeTabId) { this.activeTabId = tabs[0]?.id; } tabs.forEach((tab) => { tab.active = tab.id === this.activeTabId; }); this.requestUpdate(); } _handleTabClick(tab) { if (tab.disabled) return; this.activeTabId = tab.id; this.dispatchEvent(new CustomEvent('tab-change', { detail: { activeTabId: tab.id }, bubbles: true, composed: true, })); } _handleTabDismiss(tab, e) { e.stopPropagation(); this.dispatchEvent(new CustomEvent('tab-dismiss', { detail: { tabId: tab.id }, bubbles: true, composed: true, })); } _handleKeyDown(e) { const enabledTabs = this._getTabs().filter((t) => !t.disabled); const currentIndex = enabledTabs.findIndex((t) => t.id === this.activeTabId); let newIndex = -1; switch (e.key) { case 'ArrowLeft': newIndex = currentIndex > 0 ? currentIndex - 1 : enabledTabs.length - 1; break; case 'ArrowRight': newIndex = currentIndex < enabledTabs.length - 1 ? currentIndex + 1 : 0; break; case 'Home': newIndex = 0; break; case 'End': newIndex = enabledTabs.length - 1; break; } if (newIndex >= 0) { e.preventDefault(); const newTab = enabledTabs[newIndex]; this.activeTabId = newTab.id; this.dispatchEvent(new CustomEvent('tab-change', { detail: { activeTabId: newTab.id }, bubbles: true, composed: true, })); const tabButtons = this.shadowRoot?.querySelectorAll('.label'); const targetButton = Array.from(tabButtons || []).find((btn) => btn.getAttribute('data-tab-id') === newTab.id); targetButton?.focus(); } } _renderTabIcon(tab) { const iconElement = tab.getIconElement(); if (!iconElement) return nothing; // Clone the icon element to render in the header const clonedIcon = iconElement.cloneNode(true); clonedIcon.removeAttribute('slot'); return html `<span class=\"label-icon\">${clonedIcon}</span>`; } render() { return html ` <div class=\"header\" role=\"tablist\" @keydown=${this._handleKeyDown}> ${this._getTabs().map((tab) => html ` <button class=${classMap({ label: true, 'label--active': tab.id === this.activeTabId, 'label--justified': this.justified, })} role=\"tab\" data-tab-id=${tab.id} aria-selected=${tab.id === this.activeTabId} aria-controls=${`panel-${tab.id}`} tabindex=${tab.id === this.activeTabId ? 0 : -1} ?disabled=${tab.disabled} @click=${() => this._handleTabClick(tab)} > ${this._renderTabIcon(tab)} <span>${tab.label}</span> ${tab.badge ? html `<span class=\"label-badge\" style=${styleMap({ backgroundColor: tab.badgeBackground, color: tab.badgeColor })}>${tab.badge}</span>` : nothing} ${tab.dismissible ? html ` <button class=\"label-dismiss\" type=\"button\" aria-label=\"Close tab\" @click=${(e) => this._handleTabDismiss(tab, e)} > <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"12\" height=\"12\"><path fill-rule=\"evenodd\" d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\" clip-rule=\"evenodd\"/></svg> </button> ` : nothing} </button> `)} </div> <div class=\"content\" role=\"tabpanel\" aria-labelledby=${this.activeTabId || ''}> <slot @slotchange=${this._updateActiveTab}></slot> </div> `; } }",
1517
1547
  "description": "A tabbed navigation component for switching between content sections."
1518
1548
  }
1519
1549
  ],
@@ -2455,8 +2485,14 @@
2455
2485
  },
2456
2486
  {
2457
2487
  "kind": "class",
2458
- "description": "Generic dialog component that renders a Lit component inside a dialog shell.",
2488
+ "description": "Generic dialog component that supports both declarative and programmatic usage.\n\nDeclarative: place `<kr-dialog>` in HTML with slotted content and call `.open()` / `.close()`.\nProgrammatic: use `KRDialog.open(Component, config)` to create and show a dialog.",
2459
2489
  "name": "KRDialog",
2490
+ "slots": [
2491
+ {
2492
+ "description": "Default slot for declarative dialog content (kr-dialog-header, kr-dialog-content, kr-dialog-footer)",
2493
+ "name": ""
2494
+ }
2495
+ ],
2460
2496
  "members": [
2461
2497
  {
2462
2498
  "kind": "field",
@@ -2476,6 +2512,35 @@
2476
2512
  "privacy": "private",
2477
2513
  "default": "null"
2478
2514
  },
2515
+ {
2516
+ "kind": "field",
2517
+ "name": "opened",
2518
+ "type": {
2519
+ "text": "boolean"
2520
+ },
2521
+ "default": "false",
2522
+ "attribute": "opened",
2523
+ "reflects": true
2524
+ },
2525
+ {
2526
+ "kind": "field",
2527
+ "name": "width",
2528
+ "type": {
2529
+ "text": "string"
2530
+ },
2531
+ "default": "'560px'",
2532
+ "attribute": "width"
2533
+ },
2534
+ {
2535
+ "kind": "method",
2536
+ "name": "open",
2537
+ "description": "Opens the dialog (declarative mode)."
2538
+ },
2539
+ {
2540
+ "kind": "method",
2541
+ "name": "close",
2542
+ "description": "Closes the dialog.\nIn programmatic mode (has _dialogRef), delegates to the dialog ref.\nIn declarative mode, sets opened=false and dispatches close event."
2543
+ },
2479
2544
  {
2480
2545
  "kind": "method",
2481
2546
  "name": "open",
@@ -2499,7 +2564,8 @@
2499
2564
  "text": "KRDialogConfig"
2500
2565
  }
2501
2566
  }
2502
- ]
2567
+ ],
2568
+ "description": "Opens a dialog programmatically by creating a component and injecting it."
2503
2569
  },
2504
2570
  {
2505
2571
  "kind": "field",
@@ -2520,6 +2586,33 @@
2520
2586
  ]
2521
2587
  }
2522
2588
  ],
2589
+ "events": [
2590
+ {
2591
+ "name": "close",
2592
+ "type": {
2593
+ "text": "CustomEvent"
2594
+ },
2595
+ "description": "Fired when a declarative dialog is closed"
2596
+ }
2597
+ ],
2598
+ "attributes": [
2599
+ {
2600
+ "name": "opened",
2601
+ "type": {
2602
+ "text": "boolean"
2603
+ },
2604
+ "default": "false",
2605
+ "fieldName": "opened"
2606
+ },
2607
+ {
2608
+ "name": "width",
2609
+ "type": {
2610
+ "text": "string"
2611
+ },
2612
+ "default": "'560px'",
2613
+ "fieldName": "width"
2614
+ }
2615
+ ],
2523
2616
  "superclass": {
2524
2617
  "name": "LitElement",
2525
2618
  "package": "lit"
@@ -2650,6 +2743,119 @@
2650
2743
  }
2651
2744
  ]
2652
2745
  },
2746
+ {
2747
+ "kind": "javascript-module",
2748
+ "path": "src/monaco/monaco.ts",
2749
+ "declarations": [
2750
+ {
2751
+ "kind": "class",
2752
+ "description": "A Monaco Editor wrapper that handles shadow DOM boilerplate.\n\nCopies Monaco's injected styles from document.head into the shadow root\nand watches for new styles added later via MutationObserver. Applies CSS\nfixes for the find widget inside shadow DOM. Disposes the editor and\nobserver on disconnect.\n\nConsumers get full access to the Monaco API via the `editor` property.\nPass editor configuration through the `options` property before the\nelement connects, or call `editor.updateOptions()` after.",
2753
+ "name": "KRMonaco",
2754
+ "members": [
2755
+ {
2756
+ "kind": "field",
2757
+ "name": "_headObserver",
2758
+ "type": {
2759
+ "text": "MutationObserver | null"
2760
+ },
2761
+ "privacy": "private",
2762
+ "default": "null"
2763
+ },
2764
+ {
2765
+ "kind": "field",
2766
+ "name": "options",
2767
+ "type": {
2768
+ "text": "monaco.editor.IStandaloneEditorConstructionOptions"
2769
+ },
2770
+ "default": "{}",
2771
+ "attribute": "options"
2772
+ },
2773
+ {
2774
+ "kind": "field",
2775
+ "name": "editor",
2776
+ "type": {
2777
+ "text": "monaco.editor.IStandaloneCodeEditor | null"
2778
+ },
2779
+ "default": "null"
2780
+ },
2781
+ {
2782
+ "kind": "method",
2783
+ "name": "_isMonacoStyle",
2784
+ "privacy": "private",
2785
+ "parameters": [
2786
+ {
2787
+ "name": "text",
2788
+ "type": {
2789
+ "text": "string"
2790
+ }
2791
+ }
2792
+ ]
2793
+ },
2794
+ {
2795
+ "kind": "method",
2796
+ "name": "_copyMonacoStyles",
2797
+ "privacy": "private"
2798
+ },
2799
+ {
2800
+ "kind": "method",
2801
+ "name": "_initEditor",
2802
+ "privacy": "private"
2803
+ }
2804
+ ],
2805
+ "events": [
2806
+ {
2807
+ "name": "ready",
2808
+ "type": {
2809
+ "text": "CustomEvent"
2810
+ },
2811
+ "description": "Fired when the editor instance is created. Detail: `{ editor }`"
2812
+ }
2813
+ ],
2814
+ "attributes": [
2815
+ {
2816
+ "name": "options",
2817
+ "type": {
2818
+ "text": "monaco.editor.IStandaloneEditorConstructionOptions"
2819
+ },
2820
+ "default": "{}",
2821
+ "fieldName": "options"
2822
+ }
2823
+ ],
2824
+ "superclass": {
2825
+ "name": "LitElement",
2826
+ "package": "lit"
2827
+ },
2828
+ "tagName": "kr-monaco",
2829
+ "customElement": true
2830
+ }
2831
+ ],
2832
+ "exports": [
2833
+ {
2834
+ "kind": "js",
2835
+ "name": "KRMonaco",
2836
+ "declaration": {
2837
+ "name": "KRMonaco",
2838
+ "module": "src/monaco/monaco.ts"
2839
+ }
2840
+ },
2841
+ {
2842
+ "kind": "custom-element-definition",
2843
+ "name": "kr-monaco",
2844
+ "declaration": {
2845
+ "name": "KRMonaco",
2846
+ "module": "src/monaco/monaco.ts"
2847
+ }
2848
+ },
2849
+ {
2850
+ "kind": "js",
2851
+ "name": "monaco",
2852
+ "declaration": {
2853
+ "name": "monaco",
2854
+ "module": "src/monaco/monaco.ts"
2855
+ }
2856
+ }
2857
+ ]
2858
+ },
2653
2859
  {
2654
2860
  "kind": "javascript-module",
2655
2861
  "path": "src/progress-bar/progress-bar.ts",
@@ -3549,13 +3755,13 @@
3549
3755
  },
3550
3756
  {
3551
3757
  "kind": "field",
3552
- "name": "title",
3758
+ "name": "label",
3553
3759
  "type": {
3554
3760
  "text": "string"
3555
3761
  },
3556
3762
  "default": "''",
3557
- "description": "Display title for the tab",
3558
- "attribute": "title"
3763
+ "description": "Display label for the tab",
3764
+ "attribute": "label"
3559
3765
  },
3560
3766
  {
3561
3767
  "kind": "field",
@@ -3564,7 +3770,7 @@
3564
3770
  "text": "string"
3565
3771
  },
3566
3772
  "default": "''",
3567
- "description": "Badge text displayed next to title (e.g. notification count)",
3773
+ "description": "Badge text displayed next to label (e.g. notification count)",
3568
3774
  "attribute": "badge"
3569
3775
  },
3570
3776
  {
@@ -3640,13 +3846,13 @@
3640
3846
  "fieldName": "id"
3641
3847
  },
3642
3848
  {
3643
- "name": "title",
3849
+ "name": "label",
3644
3850
  "type": {
3645
3851
  "text": "string"
3646
3852
  },
3647
3853
  "default": "''",
3648
- "description": "Display title for the tab",
3649
- "fieldName": "title"
3854
+ "description": "Display label for the tab",
3855
+ "fieldName": "label"
3650
3856
  },
3651
3857
  {
3652
3858
  "name": "badge",
@@ -3654,7 +3860,7 @@
3654
3860
  "text": "string"
3655
3861
  },
3656
3862
  "default": "''",
3657
- "description": "Badge text displayed next to title (e.g. notification count)",
3863
+ "description": "Badge text displayed next to label (e.g. notification count)",
3658
3864
  "fieldName": "badge"
3659
3865
  },
3660
3866
  {
@@ -450,8 +450,8 @@ KRButton.styles = css `
450
450
  }
451
451
 
452
452
  :host(.kr-button--small) ::slotted([slot="icon"]) {
453
- width: 14px;
454
- height: 14px;
453
+ width: 16px;
454
+ height: 16px;
455
455
  }
456
456
 
457
457
  :host(.kr-button--large) ::slotted([slot="icon"]) {
@@ -42,15 +42,38 @@ export declare class KRDialogRef<R = unknown> {
42
42
  afterClosed(): Promise<R | undefined>;
43
43
  }
44
44
  /**
45
- * Generic dialog component that renders a Lit component inside a dialog shell.
45
+ * Generic dialog component that supports both declarative and programmatic usage.
46
+ *
47
+ * Declarative: place `<kr-dialog>` in HTML with slotted content and call `.open()` / `.close()`.
48
+ * Programmatic: use `KRDialog.open(Component, config)` to create and show a dialog.
46
49
  *
47
50
  * @element kr-dialog
51
+ *
52
+ * @slot - Default slot for declarative dialog content (kr-dialog-header, kr-dialog-content, kr-dialog-footer)
53
+ *
54
+ * @fires close - Fired when a declarative dialog is closed
48
55
  */
49
56
  export declare class KRDialog extends LitElement {
50
57
  static styles: import("lit").CSSResult;
51
58
  private _dialogRef;
52
59
  private _contentElement;
60
+ opened: boolean;
61
+ width: string;
53
62
  disconnectedCallback(): void;
63
+ updated(changedProperties: Map<string, unknown>): void;
64
+ /**
65
+ * Opens the dialog (declarative mode).
66
+ */
67
+ open(): void;
68
+ /**
69
+ * Closes the dialog.
70
+ * In programmatic mode (has _dialogRef), delegates to the dialog ref.
71
+ * In declarative mode, sets opened=false and dispatches close event.
72
+ */
73
+ close(): void;
74
+ /**
75
+ * Opens a dialog programmatically by creating a component and injecting it.
76
+ */
54
77
  static open(component: new () => LitElement, config?: KRDialogConfig): KRDialogRef;
55
78
  private _handleDocumentKeyDown;
56
79
  private _handleBackdropClick;