@kodaris/krubble-components 1.0.26 → 1.0.28

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.
Files changed (46) hide show
  1. package/custom-elements.json +620 -239
  2. package/dist/alert/alert.d.ts +2 -2
  3. package/dist/alert/alert.d.ts.map +1 -1
  4. package/dist/alert/alert.js +25 -11
  5. package/dist/alert/alert.js.map +1 -1
  6. package/dist/button/button.d.ts +0 -1
  7. package/dist/button/button.d.ts.map +1 -1
  8. package/dist/button/button.js +20 -20
  9. package/dist/button/button.js.map +1 -1
  10. package/dist/code-demo/code-demo.d.ts +14 -15
  11. package/dist/code-demo/code-demo.d.ts.map +1 -1
  12. package/dist/code-demo/code-demo.js +109 -128
  13. package/dist/code-demo/code-demo.js.map +1 -1
  14. package/dist/dialog/dialog.d.ts +43 -34
  15. package/dist/dialog/dialog.d.ts.map +1 -1
  16. package/dist/dialog/dialog.js +108 -58
  17. package/dist/dialog/dialog.js.map +1 -1
  18. package/dist/form/select-field/select-field.d.ts +1 -1
  19. package/dist/form/select-field/select-field.d.ts.map +1 -1
  20. package/dist/form/select-field/select-field.js +39 -31
  21. package/dist/form/select-field/select-field.js.map +1 -1
  22. package/dist/index.d.ts +4 -2
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +3 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/{krubble.bundled.js → krubble-components.bundled.js} +599 -320
  27. package/dist/krubble-components.bundled.js.map +1 -0
  28. package/dist/{krubble.bundled.min.js → krubble-components.bundled.min.js} +322 -234
  29. package/dist/krubble-components.bundled.min.js.map +1 -0
  30. package/dist/{krubble.umd.js → krubble-components.umd.js} +599 -320
  31. package/dist/krubble-components.umd.js.map +1 -0
  32. package/dist/{krubble.umd.min.js → krubble-components.umd.min.js} +295 -207
  33. package/dist/krubble-components.umd.min.js.map +1 -0
  34. package/dist/progress-bar/progress-bar.d.ts +30 -0
  35. package/dist/progress-bar/progress-bar.d.ts.map +1 -0
  36. package/dist/progress-bar/progress-bar.js +104 -0
  37. package/dist/progress-bar/progress-bar.js.map +1 -0
  38. package/dist/spinner/spinner.d.ts +30 -0
  39. package/dist/spinner/spinner.d.ts.map +1 -0
  40. package/dist/spinner/spinner.js +133 -0
  41. package/dist/spinner/spinner.js.map +1 -0
  42. package/package.json +9 -1
  43. package/dist/krubble.bundled.js.map +0 -1
  44. package/dist/krubble.bundled.min.js.map +0 -1
  45. package/dist/krubble.umd.js.map +0 -1
  46. package/dist/krubble.umd.min.js.map +0 -1
@@ -65,9 +65,9 @@
65
65
  },
66
66
  {
67
67
  "kind": "js",
68
- "name": "DialogRef",
68
+ "name": "KRDialogRef",
69
69
  "declaration": {
70
- "name": "DialogRef",
70
+ "name": "KRDialogRef",
71
71
  "module": "./dialog/dialog.js"
72
72
  }
73
73
  },
@@ -103,6 +103,22 @@
103
103
  "module": "./table/table.js"
104
104
  }
105
105
  },
106
+ {
107
+ "kind": "js",
108
+ "name": "KRSpinner",
109
+ "declaration": {
110
+ "name": "KRSpinner",
111
+ "module": "./spinner/spinner.js"
112
+ }
113
+ },
114
+ {
115
+ "kind": "js",
116
+ "name": "KRProgressBar",
117
+ "declaration": {
118
+ "name": "KRProgressBar",
119
+ "module": "./progress-bar/progress-bar.js"
120
+ }
121
+ },
106
122
  {
107
123
  "kind": "js",
108
124
  "name": "KRTextField",
@@ -139,7 +155,7 @@
139
155
  },
140
156
  {
141
157
  "kind": "javascript-module",
142
- "path": "dist/krubble.bundled.js",
158
+ "path": "dist/krubble-components.bundled.js",
143
159
  "declarations": [
144
160
  {
145
161
  "kind": "variable",
@@ -164,13 +180,13 @@
164
180
  {
165
181
  "kind": "variable",
166
182
  "name": "KRAlert",
167
- "default": "class KRAlert extends i$2 { constructor() { super(...arguments); /** * The alert type/severity */ this.type = 'info'; /** * Whether the alert can be dismissed */ this.dismissible = false; /** * Whether the alert is visible */ this.visible = true; } /** Handles dismiss button click */ _handleDismiss() { this.visible = false; this.dispatchEvent(new CustomEvent('dismiss', { bubbles: true, composed: true })); } render() { const icons = { info: b `<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z\" clip-rule=\"evenodd\"/></svg>`, success: b `<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\" clip-rule=\"evenodd\"/></svg>`, warning: b `<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\" clip-rule=\"evenodd\"/></svg>`, error: b `<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\" clip-rule=\"evenodd\"/></svg>`, }; return b ` <div class=${e$1({ 'alert': true, ['alert--' + this.type]: true, 'alert--hidden': !this.visible })} role=\"alert\" > ${icons[this.type]} <div class=\"content\"> ${this.header ? b `<h4 class=\"header\">${this.header}</h4>` : A} <div class=\"message\"> <slot></slot> </div> </div> ${this.dismissible ? b ` <button class=\"dismiss\" type=\"button\" aria-label=\"Dismiss alert\" @click=${this._handleDismiss} > <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"16\" height=\"16\"> <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} </div> `; } }",
183
+ "default": "class KRAlert extends i$2 { constructor() { super(...arguments); /** * The alert type/severity */ this.type = 'info'; /** * Optional title text */ this.title = ''; /** * Whether the alert can be dismissed */ this.dismissible = false; /** * Whether the alert is visible */ this.visible = true; } /** Handles dismiss button click */ _handleDismiss() { this.visible = false; this.dispatchEvent(new CustomEvent('dismiss', { bubbles: true, composed: true })); } render() { const icons = { info: b `<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z\" clip-rule=\"evenodd\"/></svg>`, success: b `<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\" clip-rule=\"evenodd\"/></svg>`, warning: b `<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\" clip-rule=\"evenodd\"/></svg>`, error: b `<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\" clip-rule=\"evenodd\"/></svg>`, }; return b ` <div class=${e$1({ 'alert': true, ['alert--' + this.type]: true, 'alert--has-header': !!this.title, 'alert--hidden': !this.visible })} role=\"alert\" > ${icons[this.type]} <div class=\"content\"> ${this.title ? b `<h4 class=\"header\">${this.title}</h4>` : A} <div class=\"message\"> <slot></slot> </div> </div> ${this.dismissible ? b ` <button class=\"dismiss\" type=\"button\" aria-label=\"Dismiss alert\" @click=${this._handleDismiss} > <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"16\" height=\"16\"> <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} </div> `; } }",
168
184
  "description": "A customizable alert component for displaying important information to users."
169
185
  },
170
186
  {
171
187
  "kind": "variable",
172
188
  "name": "KRButton",
173
- "default": "class KRButton extends i$2 { constructor() { super(...arguments); /** * The button variant (shape) */ this.variant = 'flat'; /** * The button color */ this.color = 'primary'; /** * The button size */ this.size = 'medium'; /** * Whether the button is disabled */ this.disabled = false; /** * Dropdown options - when provided, button becomes a dropdown */ this.options = []; this._state = 'idle'; this._stateText = ''; this._dropdownOpened = false; this._dropdownAlignRight = false; this._handleHostClick = (e) => { if (this.options.length) { e.stopPropagation(); this._toggleDropdown(); } }; this._handleKeydown = (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); if (this.options.length) { this._toggleDropdown(); } else { this.click(); } } if (e.key === 'Escape' && this._dropdownOpened) { this._dropdownOpened = false; } }; this._handleClickOutside = (e) => { if (this._dropdownOpened && !this.contains(e.target)) { this._dropdownOpened = false; } }; } connectedCallback() { super.connectedCallback(); this.setAttribute('role', this.href ? 'link' : 'button'); this.setAttribute('tabindex', '0'); this.addEventListener('keydown', this._handleKeydown); this.addEventListener('click', this._handleHostClick); document.addEventListener('click', this._handleClickOutside); } disconnectedCallback() { super.disconnectedCallback(); this.removeEventListener('keydown', this._handleKeydown); this.removeEventListener('click', this._handleHostClick); document.removeEventListener('click', this._handleClickOutside); } _toggleDropdown() { this._dropdownOpened = !this._dropdownOpened; if (this._dropdownOpened) { // Check if dropdown would overflow viewport after render requestAnimationFrame(() => { const dropdown = this.shadowRoot?.querySelector('.dropdown'); if (dropdown) { const rect = dropdown.getBoundingClientRect(); this._dropdownAlignRight = rect.right > window.innerWidth; } }); } } _handleOptionClick(option, e) { e.stopPropagation(); this._dropdownOpened = false; this.dispatchEvent(new CustomEvent('option-select', { detail: { id: option.id, label: option.label }, bubbles: true, composed: true })); } /** * Shows a loading spinner and disables the button. */ showLoading() { this._clearStateTimeout(); this._state = 'loading'; this._stateText = ''; } /** * Shows a success state with optional custom text. * @param text - Text to display (default: \"Saved\") * @param duration - Duration in ms before auto-reset (default: 2000) */ showSuccess(text = 'Success', duration = 2000) { this._clearStateTimeout(); this._state = 'success'; this._stateText = text; this._stateTimeout = window.setTimeout(() => this.reset(), duration); } /** * Shows an error state with optional custom text. * @param text - Text to display (default: \"Error\") * @param duration - Duration in ms before auto-reset (default: 2000) */ showError(text = 'Error', duration = 2000) { this._clearStateTimeout(); this._state = 'error'; this._stateText = text; this._stateTimeout = window.setTimeout(() => this.reset(), duration); } /** * Resets the button to its idle state. */ reset() { this._clearStateTimeout(); this._state = 'idle'; this._stateText = ''; } _clearStateTimeout() { if (this._stateTimeout) { clearTimeout(this._stateTimeout); this._stateTimeout = undefined; } } updated(changedProperties) { // Reflect state classes to host this.classList.toggle('kr-button--loading', this._state === 'loading'); this.classList.toggle('kr-button--success', this._state === 'success'); this.classList.toggle('kr-button--error', this._state === 'error'); this.classList.toggle(`kr-button--${this.variant}`, true); this.classList.toggle(`kr-button--${this.color}`, true); this.classList.toggle('kr-button--small', this.size === 'small'); this.classList.toggle('kr-button--large', this.size === 'large'); } render() { const content = b ` <slot></slot> ${this.options.length ? b `<svg class=\"caret\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20\" width=\"20\" 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>` : A} ${this._state !== 'idle' ? b `<span class=\"state-overlay\"> ${this._state === 'loading' ? b `<span class=\"spinner\"></span>` : this._stateText} </span>` : A} ${this.options.length ? b ` <div class=\"dropdown ${this._dropdownOpened ? 'dropdown--opened' : ''} ${this._dropdownAlignRight ? 'dropdown--align-right' : ''}\"> ${this.options.map(option => b ` <button class=\"dropdown-item\" @click=${(e) => this._handleOptionClick(option, e)} >${option.label}</button> `)} </div> ` : A} `; return this.href ? b `<a class=\"link\" href=${this.href} target=${this.target || A}>${content}</a>` : content; } }",
189
+ "default": "class KRButton extends i$2 { constructor() { super(...arguments); /** * The button variant (shape) */ this.variant = 'flat'; /** * The button color */ this.color = 'primary'; /** * The button size */ this.size = 'medium'; /** * Whether the button is disabled */ this.disabled = false; /** * Dropdown options - when provided, button becomes a dropdown */ this.options = []; this._state = 'idle'; this._stateText = ''; this._dropdownOpened = false; this._handleHostClick = (e) => { if (this.options.length) { e.stopPropagation(); this._toggleDropdown(); } }; this._handleKeydown = (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); if (this.options.length) { this._toggleDropdown(); } else { this.click(); } } if (e.key === 'Escape' && this._dropdownOpened) { this._dropdownOpened = false; } }; this._handleClickOutside = (e) => { if (this._dropdownOpened && !this.contains(e.target)) { this._dropdownOpened = false; } }; } connectedCallback() { super.connectedCallback(); this.setAttribute('role', this.href ? 'link' : 'button'); this.setAttribute('tabindex', '0'); this.addEventListener('keydown', this._handleKeydown); this.addEventListener('click', this._handleHostClick); document.addEventListener('click', this._handleClickOutside); } disconnectedCallback() { super.disconnectedCallback(); this.removeEventListener('keydown', this._handleKeydown); this.removeEventListener('click', this._handleHostClick); document.removeEventListener('click', this._handleClickOutside); } _toggleDropdown() { this._dropdownOpened = !this._dropdownOpened; if (this._dropdownOpened) { // Position the fixed dropdown relative to the host element requestAnimationFrame(() => { const dropdown = this.shadowRoot?.querySelector('.dropdown'); if (dropdown) { const hostRect = this.getBoundingClientRect(); dropdown.style.top = hostRect.bottom + 4 + 'px'; dropdown.style.left = hostRect.left + 'px'; dropdown.style.minWidth = hostRect.width + 'px'; // Align right if dropdown overflows viewport const dropdownRect = dropdown.getBoundingClientRect(); if (dropdownRect.right > window.innerWidth) { dropdown.style.left = ''; dropdown.style.right = window.innerWidth - hostRect.right + 'px'; } } }); } } _handleOptionClick(option, e) { e.stopPropagation(); this._dropdownOpened = false; this.dispatchEvent(new CustomEvent('option-select', { detail: { id: option.id, label: option.label }, bubbles: true, composed: true })); } /** * Shows a loading spinner and disables the button. */ showLoading() { this._clearStateTimeout(); this._state = 'loading'; this._stateText = ''; } /** * Shows a success state with optional custom text. * @param text - Text to display (default: \"Saved\") * @param duration - Duration in ms before auto-reset (default: 2000) */ showSuccess(text = 'Success', duration = 2000) { this._clearStateTimeout(); this._state = 'success'; this._stateText = text; if (duration > 0) { this._stateTimeout = window.setTimeout(() => this.reset(), duration); } } /** * Shows an error state with optional custom text. * @param text - Text to display (default: \"Error\") * @param duration - Duration in ms before auto-reset (default: 2000) */ showError(text = 'Error', duration = 2000) { this._clearStateTimeout(); this._state = 'error'; this._stateText = text; if (duration > 0) { this._stateTimeout = window.setTimeout(() => this.reset(), duration); } } /** * Resets the button to its idle state. */ reset() { this._clearStateTimeout(); this._state = 'idle'; this._stateText = ''; } _clearStateTimeout() { if (this._stateTimeout) { clearTimeout(this._stateTimeout); this._stateTimeout = undefined; } } updated(changedProperties) { // Reflect state classes to host this.classList.toggle('kr-button--loading', this._state === 'loading'); this.classList.toggle('kr-button--success', this._state === 'success'); this.classList.toggle('kr-button--error', this._state === 'error'); this.classList.toggle(`kr-button--${this.variant}`, true); this.classList.toggle(`kr-button--${this.color}`, true); this.classList.toggle('kr-button--small', this.size === 'small'); this.classList.toggle('kr-button--large', this.size === 'large'); } render() { const content = b ` <slot></slot> ${this.options.length ? b `<svg class=\"caret\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20\" width=\"20\" 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>` : A} ${this._state !== 'idle' ? b `<span class=\"state-overlay\"> ${this._state === 'loading' ? b `<span class=\"spinner\"></span>` : this._stateText} </span>` : A} ${this.options.length ? b ` <div class=\"dropdown ${this._dropdownOpened ? 'dropdown--opened' : ''}\"> ${this.options.map(option => b ` <button class=\"dropdown-item\" @click=${(e) => this._handleOptionClick(option, e)} >${option.label}</button> `)} </div> ` : A} `; return this.href ? b `<a class=\"link\" href=${this.href} target=${this.target || A}>${content}</a>` : content; } }",
174
190
  "description": "A customizable button component."
175
191
  },
176
192
  {
@@ -180,7 +196,7 @@
180
196
  "members": [],
181
197
  "superclass": {
182
198
  "name": "i$1",
183
- "module": "dist/krubble.bundled.js"
199
+ "module": "dist/krubble-components.bundled.js"
184
200
  },
185
201
  "tagName": "t",
186
202
  "customElement": true
@@ -188,8 +204,8 @@
188
204
  {
189
205
  "kind": "variable",
190
206
  "name": "KRCodeDemo",
191
- "default": "class KRCodeDemo extends i$2 { constructor() { super(...arguments); this.language = 'html'; this.code = ''; this.activeTab = 'preview'; this.copied = false; } setTab(tab) { this.activeTab = tab; } getHighlightedCode() { if (!this.code) return ''; if (window.Prism && window.Prism.languages[this.language]) { return window.Prism.highlight(this.code, window.Prism.languages[this.language], this.language); } // Fallback: escape HTML and return plain text return this.escapeHtml(this.code); } escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } async copyCode() { if (!this.code) return; try { await navigator.clipboard.writeText(this.code); this.copied = true; setTimeout(() => { this.copied = false; }, 2000); } catch (err) { console.error('Failed to copy code:', err); } } render() { return b ` <div class=\"tabs\"> <button class=${e$1({ tab: true, 'tab--active': this.activeTab === 'preview' })} @click=${() => this.setTab('preview')} > Preview </button> <button class=${e$1({ tab: true, 'tab--active': this.activeTab === 'code' })} @click=${() => this.setTab('code')} > Code </button> </div> <div class=${e$1({ panel: true, 'panel--active': this.activeTab === 'preview', preview: true })}> <slot name=\"preview\"></slot> </div> <div class=${e$1({ panel: true, 'panel--active': this.activeTab === 'code', 'code-container': true })}> <button class=${e$1({ 'copy-btn': true, 'copy-btn--copied': this.copied })} @click=${this.copyCode} > ${this.copied ? 'Copied!' : 'Copy'} </button> <pre class=\"code\"><code>${o$2(this.getHighlightedCode())}</code></pre> </div> `; } }",
192
- "description": "Code demo component with Preview/Code tabs and syntax highlighting.\n\nUsage:\n```html\n<kr-code-demo language=\"html\">\n <div slot=\"preview\">\n <kr-button>Click me</kr-button>\n </div>\n <script slot=\"code\" type=\"text/plain\">\n <kr-button>Click me</kr-button>\n </script>\n</kr-code-demo>\n```\n\nRequires Prism.js to be loaded globally for syntax highlighting."
207
+ "default": "class KRCodeDemo extends i$2 { constructor() { super(...arguments); this.language = 'html'; this.code = ''; this.activeTab = 'preview'; this.copied = false; this.highlightedCode = ''; } connectedCallback() { super.connectedCallback(); // Defer to next frame so the parser finishes with children before we read innerHTML requestAnimationFrame(() => { if (!this.code) { // innerHTML normalizes boolean attributes (e.g. dismissible -> dismissible=\"\"), strip the =\"\" for cleaner display this.code = this.innerHTML.trim().replace(/=\"\"(?=[\\s>])/g, ''); } this.querySelectorAll('script').forEach(oldScript => { const newScript = document.createElement('script'); newScript.textContent = oldScript.textContent; oldScript.replaceWith(newScript); }); if (this.code && window.hljs && window.hljs.getLanguage(this.language)) { this.highlightedCode = window.hljs.highlight(this.code, { language: this.language }).value; } else { this.highlightedCode = this.code.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); } }); } activateTab(tab) { this.activeTab = tab; } copyCode() { if (!this.code) return; navigator.clipboard.writeText(this.code).then(() => { this.copied = true; setTimeout(() => { this.copied = false; }, 2000); }); } render() { return b ` <div class=\"tabs\"> <button class=${e$1({ tab: true, 'tab--active': this.activeTab === 'preview' })} @click=${() => this.activateTab('preview')} > Preview </button> <button class=${e$1({ tab: true, 'tab--active': this.activeTab === 'code' })} @click=${() => this.activateTab('code')} > Code </button> <button class=${e$1({ 'copy': true, 'copy--success': this.copied })} @click=${this.copyCode} title=${this.copied ? 'Copied!' : 'Copy code'} > ${this.copied ? b `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>` : b `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path></svg>`} </button> </div> <div class=${e$1({ panel: true, 'panel--active': this.activeTab === 'preview', 'panel--preview': true })}> <slot></slot> </div> <div class=${e$1({ panel: true, 'panel--active': this.activeTab === 'code', 'panel--code': true })}> <pre class=\"code\"><code>${o$2(this.highlightedCode)}</code></pre> </div> `; } }",
208
+ "description": "Code demo component with Preview/Code tabs and syntax highlighting.\n\nUsage:\n```html\n<kr-code-demo language=\"html\">\n <kr-button>Click me</kr-button>\n</kr-code-demo>\n```\n\nRequires highlight.js to be loaded globally for syntax highlighting."
193
209
  },
194
210
  {
195
211
  "kind": "variable",
@@ -199,25 +215,33 @@
199
215
  },
200
216
  {
201
217
  "kind": "class",
202
- "description": "",
203
- "name": "DialogRef",
218
+ "description": "A reference to an open dialog instance.\n\nUsed to close the dialog and retrieve its result.",
219
+ "name": "KRDialogRef",
204
220
  "members": [
205
221
  {
206
222
  "kind": "method",
207
223
  "name": "close",
208
224
  "parameters": [
209
225
  {
210
- "name": "result"
226
+ "name": "result",
227
+ "description": "The result to return to the caller"
211
228
  }
212
- ]
229
+ ],
230
+ "description": "Closes the dialog and resolves with the given result."
213
231
  },
214
232
  {
215
233
  "kind": "method",
216
- "name": "afterClosed"
234
+ "name": "afterClosed",
235
+ "description": "Returns a promise that resolves when the dialog is closed.",
236
+ "return": {
237
+ "type": {
238
+ "text": ""
239
+ }
240
+ }
217
241
  },
218
242
  {
219
243
  "kind": "field",
220
- "name": "resolvePromise",
244
+ "name": "_resolvePromise",
221
245
  "type": {
222
246
  "text": "null"
223
247
  },
@@ -225,7 +249,7 @@
225
249
  },
226
250
  {
227
251
  "kind": "field",
228
- "name": "dialogElement",
252
+ "name": "_dialogElement",
229
253
  "type": {
230
254
  "text": "null"
231
255
  },
@@ -233,16 +257,16 @@
233
257
  },
234
258
  {
235
259
  "kind": "field",
236
- "name": "promise",
237
- "default": "new Promise((resolve) => { this.resolvePromise = resolve; })"
260
+ "name": "_promise",
261
+ "default": "new Promise((resolve) => { this._resolvePromise = resolve; })"
238
262
  }
239
263
  ]
240
264
  },
241
265
  {
242
266
  "kind": "variable",
243
267
  "name": "KRDialog",
244
- "default": "class KRDialog extends i$2 { constructor() { super(...arguments); this.contentElement = null; this.dialogRef = null; this.boundHandleKeyDown = this.handleKeyDown.bind(this); } static open(component, config) { const existing = document.querySelector('kr-dialog'); if (existing) { existing.remove(); } const dialogRef = new DialogRef(); 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.boundHandleKeyDown); return dialogRef; } handleKeyDown(e) { if (e.key === 'Escape') { this.dialogRef?.close(undefined); } } handleBackdropClick(e) { if (e.target.classList.contains('backdrop')) { this.dialogRef?.close(undefined); } } disconnectedCallback() { super.disconnectedCallback(); document.removeEventListener('keydown', this.boundHandleKeyDown); } render() { return b ` <div class=\"backdrop\" @click=${this.handleBackdropClick}></div> <div class=\"dialog\"> ${this.contentElement} </div> `; } }",
245
- "description": "Generic dialog component that renders a Lit component inside a dialog shell.\n\nUsage:\n```ts\n// Define your dialog content component\nclass EditItemDialog extends LitElement {\n // Injected by KRDialog\n dialogRef: DialogRef<{ label: string }>;\n data: { label: string };\n\n save() {\n this.dialogRef.close({ label: this.label });\n }\n}\n\n// Open the dialog\nconst dialogRef = KRDialog.open(EditItemDialog, {\n data: { label: 'Dashboard' }\n});\n\nconst result = await dialogRef.afterClosed();\nif (result) {\n console.log('Saved:', result.label);\n}\n```"
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."
246
270
  },
247
271
  {
248
272
  "kind": "variable",
@@ -266,6 +290,18 @@
266
290
  "name": "KRTable",
267
291
  "default": "class KRTable extends i$2 { constructor() { super(...arguments); /** * Internal flag to switch between scroll edge modes: * - 'overlay': Fixed padding with overlay elements that hide content at edges (scrollbar at viewport edge) * - 'edge': Padding scrolls with content, allowing table to reach edges when scrolling */ this._scrollStyle = 'overlay'; this._data = []; this._dataState = 'idle'; this._page = 1; this._pageSize = 50; this._totalItems = 0; this._totalPages = 0; this._searchQuery = ''; this._canScrollLeft = false; this._canScrollRight = false; this._canScrollHorizontal = false; this._columnPickerOpen = false; this._displayedColumns = []; this._resizing = null; this._resizeObserver = null; this._searchPositionLocked = false; this._def = { columns: [] }; this.def = { columns: [] }; this._handleClickOutsideColumnPicker = (e) => { if (!this._columnPickerOpen) return; const path = e.composedPath(); const picker = this.shadowRoot?.querySelector('.column-picker-wrapper'); if (picker && !path.includes(picker)) { this._columnPickerOpen = false; } }; this._handleResizeMove = (e) => { if (!this._resizing) return; const col = this._def.columns.find(c => c.id === this._resizing.columnId); if (col) { const newWidth = this._resizing.startWidth + (e.clientX - this._resizing.startX); col.width = `${Math.min(900, Math.max(50, newWidth))}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', this._scrollStyle === 'overlay'); this.classList.toggle('kr-table--scroll-edge', this._scrollStyle === 'edge'); this._fetch(); this._initRefresh(); document.addEventListener('click', this._handleClickOutsideColumnPicker); this._resizeObserver = new ResizeObserver(() => { // Unlock and recalculate on resize since layout changes this._searchPositionLocked = false; this._updateSearchPosition(); }); this._resizeObserver.observe(this); } disconnectedCallback() { super.disconnectedCallback(); clearInterval(this._refreshTimer); document.removeEventListener('click', this._handleClickOutsideColumnPicker); this._resizeObserver?.disconnect(); } willUpdate(changedProperties) { if (changedProperties.has('def')) { // Copy user's def and normalize action columns this._def = { ...this.def, columns: this.def.columns.map(col => { if (col.type === 'actions') { return { ...col, label: col.label ?? '', sticky: 'right', resizable: false }; } return { ...col }; }) }; this._displayedColumns = this._def.displayedColumns || this._def.columns.map(c => c.id); this._fetch(); this._initRefresh(); } } updated(changedProperties) { this._updateScrollFlags(); this._syncSlottedContent(); } /** Syncs light DOM content for cells with custom render functions */ _syncSlottedContent() { const columns = this.getDisplayedColumns().filter(col => col.render); if (!columns.length) return; // Clear old slotted content this.querySelectorAll('[slot^=\"cell-\"]').forEach(el => el.remove()); // Create new slotted content this._data.forEach((row, rowIndex) => { columns.forEach(col => { const result = col.render(row); const content = typeof result === 'string' ? result : ''; if (content) { const el = document.createElement('span'); el.slot = `cell-${rowIndex}-${col.id}`; if (col.type === 'actions') { el.style.display = 'flex'; el.style.gap = '8px'; } el.innerHTML = content; this.appendChild(el); } }); }); } // ---------------------------------------------------------------------------- // Public Interface // ---------------------------------------------------------------------------- refresh() { this._fetch(); } goToPrevPage() { if (this._page > 1) { this._page--; this._fetch(); } } goToNextPage() { if (this._page < this._totalPages) { this._page++; this._fetch(); } } goToPage(page) { if (page >= 1 && page <= this._totalPages) { this._page = page; this._fetch(); } } // ---------------------------------------------------------------------------- // Data Fetching // ---------------------------------------------------------------------------- /** * Fetches data from the API and updates the table. * Shows a loading spinner while fetching, then displays rows on success * or an error snackbar on failure. * Request/response format depends on dataSource.mode (solr, opensearch, db). */ _fetch() { if (!this._def.dataSource) return; this._dataState = 'loading'; // Build request based on mode let request; switch (this._def.dataSource.mode) { case 'opensearch': throw Error('Opensearch not supported yet'); case 'db': request = { page: this._page - 1, size: this._pageSize, sorts: [], filterFields: [], queryFields: [], facetFields: [] }; if (this._searchQuery?.trim().length) { this._def.columns.filter(col => col.searchable).forEach(col => { request.queryFields.push({ name: col.id, operation: 'CONTAINS', value: this._searchQuery, and: false }); }); } break; default: // solr request = { page: this._page - 1, size: this._pageSize, sorts: [], filterFields: [], queryFields: [], facetFields: [] }; if (this._searchQuery?.trim().length) { request.queryFields.push({ name: '_text_', operation: 'IS', value: escapeSolrQuery(this._searchQuery) }); } } this._def.dataSource.fetch(request) .then(response => { // Parse response based on mode switch (this._def.dataSource?.mode) { case 'opensearch': { throw Error('Opensearch not supported yet'); } case 'db': { const res = response; this._data = res.data.content; this._totalItems = res.data.totalElements; this._totalPages = res.data.totalPages; this._pageSize = res.data.size; break; } default: { // solr const res = response; this._data = res.data.content; this._totalItems = res.data.totalElements; this._totalPages = res.data.totalPages; this._pageSize = res.data.size; } } this._dataState = 'success'; this._updateSearchPosition(); }) .catch(err => { this._dataState = 'error'; KRSnackbar.show({ message: err instanceof Error ? err.message : 'Failed to load data', type: 'error' }); }); } /** * Sets up auto-refresh so the table automatically fetches fresh data * at a regular interval (useful for dashboards, monitoring views). * Configured via def.refreshInterval in milliseconds. */ _initRefresh() { clearInterval(this._refreshTimer); if (this._def.refreshInterval && this._def.refreshInterval > 0) { this._refreshTimer = window.setInterval(() => { this._fetch(); }, this._def.refreshInterval); } } _handleSearch(e) { const input = e.target; this._searchQuery = input.value; this._page = 1; this._fetch(); } _getGridTemplateColumns() { const cols = this.getDisplayedColumns(); return cols.map((col) => { // If column has explicit width, use it if (col.width) { return col.width; } // Actions columns: fit content without minimum if (col.type === 'actions') { return 'max-content'; } // No width specified - use content-based sizing with minimum return 'minmax(80px, auto)'; }).join(' '); } /** * Updates search position to be centered with equal gaps from title and tools. * On first call: resets to flex centering, measures position, then locks with fixed margin. * Subsequent calls are ignored unless _searchPositionLocked is reset (e.g., on resize). */ _updateSearchPosition() { // Skip if already locked (prevents shifts on pagination changes) if (this._searchPositionLocked) return; const search = this.shadowRoot?.querySelector('.search'); const searchField = search?.querySelector('.search-field'); if (!search || !searchField) return; // Reset to flex centering search.style.justifyContent = 'center'; searchField.style.marginLeft = ''; requestAnimationFrame(() => { const searchRect = search.getBoundingClientRect(); const fieldRect = searchField.getBoundingClientRect(); // Calculate how far from the left of search container the field currently is const currentOffset = fieldRect.left - searchRect.left; // Lock position: switch to flex-start and use fixed margin search.style.justifyContent = 'flex-start'; searchField.style.marginLeft = `${currentOffset}px`; // Mark as locked so pagination changes don't shift the search this._searchPositionLocked = true; }); } // ---------------------------------------------------------------------------- // Columns // ---------------------------------------------------------------------------- _toggleColumnPicker() { this._columnPickerOpen = !this._columnPickerOpen; } _toggleColumn(columnId) { if (this._displayedColumns.includes(columnId)) { this._displayedColumns = this._displayedColumns.filter(id => id !== columnId); } else { this._displayedColumns = [...this._displayedColumns, columnId]; } } // When a user toggles a column on via the column picker, it gets appended // to _displayedColumns. By mapping over _displayedColumns (not def.columns), // the new column appears at the right edge of the table instead of jumping // back to its original position in the column definition. // Actions columns are always moved to the end. getDisplayedColumns() { return this._displayedColumns .map(id => this._def.columns.find(col => col.id === id)) .sort((a, b) => { if (a.type === 'actions' && b.type !== 'actions') return 1; if (a.type !== 'actions' && b.type === 'actions') return -1; return 0; }); } // ---------------------------------------------------------------------------- // Scrolling // ---------------------------------------------------------------------------- /** * Scroll event handler that updates scroll flags in real-time as user scrolls. * Updates shadow indicators to show if more content exists left/right. */ _handleScroll(e) { const container = e.target; this._canScrollLeft = container.scrollLeft > 0; this._canScrollRight = container.scrollLeft < container.scrollWidth - container.clientWidth - 1; } /** * Updates scroll state flags for the table content container. * - _canScrollLeft: true if scrolled right (can scroll back left) * - _canScrollRight: true if more content exists to the right * - _canScrollHorizontal: true if content is wider than container * These flags control scroll shadow indicators and CSS classes. */ _updateScrollFlags() { const container = this.shadowRoot?.querySelector('.content'); if (container) { this._canScrollLeft = container.scrollLeft > 0; this._canScrollRight = container.scrollWidth > container.clientWidth && container.scrollLeft < container.scrollWidth - container.clientWidth - 1; this._canScrollHorizontal = container.scrollWidth > container.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(c => c.sticky === 'left')); this.classList.toggle('kr-table--sticky-right', this.getDisplayedColumns().some(c => c.sticky === 'right')); } // ---------------------------------------------------------------------------- // Column Resizing // ---------------------------------------------------------------------------- _handleResizeStart(e, columnId) { e.preventDefault(); const headerCell = this.shadowRoot?.querySelector(`.header-cell[data-column-id=\"${columnId}\"]`); this._resizing = { columnId, startX: e.clientX, startWidth: headerCell?.offsetWidth || 200 }; document.addEventListener('mousemove', this._handleResizeMove); document.addEventListener('mouseup', this._handleResizeEnd); } // ---------------------------------------------------------------------------- // Header // ---------------------------------------------------------------------------- _handleAction(action) { if (action.href) { return; } this.dispatchEvent(new CustomEvent('action', { detail: { action: action.id }, bubbles: true, composed: true })); } // ---------------------------------------------------------------------------- // Rendering // ---------------------------------------------------------------------------- _renderCellContent(column, row, rowIndex) { const value = row[column.id]; if (column.render) { // Use slot to project content from light DOM so external styles apply return b `<slot name=\"cell-${rowIndex}-${column.id}\"></slot>`; } if (value === null || value === undefined) { return ''; } switch (column.type) { case 'number': return typeof value === 'number' ? value.toLocaleString() : String(value); case 'currency': return typeof value === 'number' ? value.toLocaleString('en-US', { style: 'currency', currency: 'USD' }) : String(value); case 'date': { let date; if (value instanceof Date) { date = value; } else if (typeof value === 'string' && /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}/.test(value)) { // MySQL datetime format (UTC): \"2026-01-28 01:33:44:517\" // Replace last colon before ms with dot, append Z for UTC const isoString = value.replace(/(\\d{2}:\\d{2}:\\d{2}):(\\d+)$/, '$1.$2').replace(' ', 'T') + 'Z'; date = new Date(isoString); } else { date = new Date(value); } // Show date and time for datetime values return date.toLocaleString(undefined, { year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' }); } case 'boolean': if (value === true) return 'Yes'; if (value === false) return 'No'; return ''; default: return String(value); } } /** * Returns CSS classes for a header cell based on column config. */ _getHeaderCellClasses(column, index) { return { 'header-cell': true, 'header-cell--align-center': column.align === 'center', 'header-cell--align-right': column.align === 'right', 'header-cell--sticky-left': column.sticky === 'left', 'header-cell--sticky-left-last': column.sticky === 'left' && !this.getDisplayedColumns().slice(index + 1).some(c => c.sticky === 'left'), 'header-cell--sticky-right': column.sticky === 'right', 'header-cell--sticky-right-first': column.sticky === 'right' && !this.getDisplayedColumns().slice(0, index).some(c => c.sticky === 'right') }; } /** * Returns CSS classes for a table cell based on column config: * - Alignment (center, right) * - Sticky positioning (left, right) * - Border classes for the last left-sticky or first right-sticky column */ _getCellClasses(column, index) { return { 'cell': true, 'cell--actions': column.type === 'actions', 'cell--align-center': column.align === 'center', 'cell--align-right': column.align === 'right', 'cell--sticky-left': column.sticky === 'left', 'cell--sticky-left-last': column.sticky === 'left' && !this.getDisplayedColumns().slice(index + 1).some(c => c.sticky === 'left'), 'cell--sticky-right': column.sticky === 'right', 'cell--sticky-right-first': column.sticky === 'right' && !this.getDisplayedColumns().slice(0, index).some(c => c.sticky === 'right') }; } /** * Returns inline styles for a table cell: * - Width (from column config or default 150px) * - Min-width (if specified) * - Left/right offset for sticky columns (calculated from widths of preceding sticky columns) */ _getCellStyle(column, index) { const styles = {}; if (column.sticky === 'left') { let leftOffset = 0; for (let i = 0; i < index; i++) { const col = this.getDisplayedColumns()[i]; if (col.sticky === 'left') { leftOffset += parseInt(col.width || '0', 10); } } styles.left = `${leftOffset}px`; } if (column.sticky === 'right') { let rightOffset = 0; for (let i = index + 1; i < this.getDisplayedColumns().length; i++) { const col = this.getDisplayedColumns()[i]; if (col.sticky === 'right') { rightOffset += parseInt(col.width || '0', 10); } } styles.right = `${rightOffset}px`; } return styles; } /** * Renders the pagination controls: * - Previous page arrow (disabled on first page) * - Range text showing \"1-50 of 150\" format * - Next page arrow (disabled on last page) * * Hidden when there's no data or all data fits on one page. */ _renderPagination() { const start = (this._page - 1) * this._pageSize + 1; const end = Math.min(this._page * this._pageSize, this._totalItems); return b ` <div class=\"pagination\"> <span class=\"pagination-icon ${this._page === 1 ? '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\">${start}-${end} 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> `; } /** * Renders the header toolbar containing: * - Title (left) * - Search bar with view selector dropdown (center) * - Tools (right): page navigation, refresh button, column visibility picker, actions dropdown * * Hidden when there's no title, no actions, and data fits on one page. */ _renderHeader() { if (!this._def.title && !this._def.actions?.length && this._totalPages <= 1) { return A; } return b ` <div class=\"header\"> <div class=\"title\">${this._def.title ?? ''}</div> ${this._def.dataSource?.mode === 'db' && !this._def.columns.some(col => col.searchable) ? b `<div class=\"search\"></div>` : b ` <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> `} <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(col => col.type !== 'actions').sort((a, b) => (a.label ?? a.id).localeCompare(b.label ?? b.id)).map(col => b ` <div class=\"column-picker-item\" @click=${() => this._toggleColumn(col.id)}> <div class=\"column-picker-checkbox ${this._displayedColumns.includes(col.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\">${col.label ?? col.id}</span> </div> `)} </div> </div> ${this._def.actions?.length === 1 ? b ` <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 ? b ` <kr-button class=\"actions\" .options=${this._def.actions.map(a => ({ id: a.id, label: a.label }))} @option-select=${(e) => this._handleAction({ id: e.detail.id, label: e.detail.label })} > Actions </kr-button> ` : A} </div> </div> `; } /** Renders status message (loading, error, empty) */ _renderStatus() { if (this._dataState === 'loading' && this._data.length === 0) { return b `<div class=\"status\">Loading...</div>`; } if (this._dataState === 'error' && this._data.length === 0) { return b `<div class=\"status status--error\">Error loading data</div>`; } if (this._data.length === 0) { return b `<div class=\"status\">No data available</div>`; } return A; } /** Renders the scrollable data grid with column headers and rows. */ _renderTable() { return b ` <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((col, i) => b ` <div class=${e$1(this._getHeaderCellClasses(col, i))} style=${o$1(this._getCellStyle(col, i))} data-column-id=${col.id} >${col.label ?? col.id}${col.resizable !== false ? b `<div class=\"header-cell__resize\" @mousedown=${(e) => this._handleResizeStart(e, col.id)} ></div>` : A}</div> `)} </div> ${this._data.map((row, rowIndex) => b ` <div class=\"row\"> ${this.getDisplayedColumns().map((col, i) => b ` <div class=${e$1(this._getCellClasses(col, i))} style=${o$1(this._getCellStyle(col, i))} data-column-id=${col.id} > ${this._renderCellContent(col, row, rowIndex)} </div> `)} </div> `)} </div> </div> </div> `; } /** * Renders a data table with: * - Header bar with title, search input with view selector, and tools (pagination, refresh, column visibility, actions dropdown) * - Scrollable grid with sticky header row and optional sticky left/right columns * - Loading, error message, or empty state when no data */ render() { if (!this._def.columns.length) { return b `<slot></slot>`; } return b ` ${this._renderHeader()} ${this._renderTable()} `; } }"
268
292
  },
293
+ {
294
+ "kind": "variable",
295
+ "name": "KRSpinner",
296
+ "default": "class KRSpinner extends i$2 { constructor() { super(...arguments); /** * The size of the spinner. Can be 'sm', 'md', 'lg', 'xl', or any valid CSS size value (e.g., '100px', '2rem'). */ this.size = 'md'; /** * The color of the spinner. Can be 'dark', 'light', or any valid CSS color value. */ this.color = 'dark'; } render() { var normalizedSize = ''; var normalizedColor = ''; if (this.size == 'sm') { normalizedSize = '16px'; } else if (this.size == 'md') { normalizedSize = '24px'; } else if (this.size == 'lg') { normalizedSize = '32px'; } else if (this.size == 'xl') { normalizedSize = '48px'; } else { normalizedSize = this.size; } if (this.color == 'dark') { normalizedColor = '#163052'; } else if (this.color == 'light') { normalizedColor = '#ffffff'; } else { normalizedColor = this.color; } return b ` <svg class=\"spinner\" style=${`width: ${normalizedSize}; height: ${normalizedSize}; color: ${normalizedColor}`} viewBox=\"0 0 44 44\" role=\"status\" aria-label=\"Loading\" > <circle class=\"circle\" cx=\"22\" cy=\"22\" r=\"20\" fill=\"none\" stroke-width=\"4\" /> </svg> `; } }",
297
+ "description": "A circular loading indicator component that shows activity or ongoing processes."
298
+ },
299
+ {
300
+ "kind": "variable",
301
+ "name": "KRProgressBar",
302
+ "default": "class KRProgressBar extends i$2 { constructor() { super(...arguments); /** * The color of the progress bar. Can be 'dark', 'light', or any valid CSS color value. */ this.color = 'dark'; } render() { let normalizedColor = ''; let normalizedTrackColor = ''; if (this.color === 'dark') { normalizedColor = '#163052'; } else if (this.color === 'light') { normalizedColor = '#ffffff'; } else { normalizedColor = this.color; } if (this.trackColor) { normalizedTrackColor = this.trackColor; } else if (this.color === 'light') { normalizedTrackColor = '#ffffff4d'; } else { normalizedTrackColor = '#0000001a'; } return b ` <div class=\"progress-bar\" style=${`background: ${normalizedTrackColor}`} role=\"status\" aria-label=\"Loading\" > <div class=\"fill\" style=${`background: ${normalizedColor}`}></div> </div> `; } }",
303
+ "description": "A linear loading indicator that shows activity or ongoing processes."
304
+ },
269
305
  {
270
306
  "kind": "variable",
271
307
  "name": "KRTextField",
@@ -275,7 +311,7 @@
275
311
  {
276
312
  "kind": "variable",
277
313
  "name": "KRSelectField",
278
- "default": "class KRSelectField extends i$2 { constructor() { super(); /** * The select label text */ this.label = ''; /** * The input name for form submission */ this.name = ''; /** * The currently selected value */ this.value = ''; /** * Placeholder text when no option is selected */ this.placeholder = 'Select an option'; /** * Whether the select is disabled */ this.disabled = false; /** * Whether the field is required */ this.required = false; /** * Whether the field is readonly */ this.readonly = false; /** * Helper text shown below the select */ this.hint = ''; this._isOpen = false; this._highlightedIndex = -1; this._touched = false; this._handleInvalid = (e) => { e.preventDefault(); this._touched = true; }; this._handleOutsideClick = (e) => { if (!e.composedPath().includes(this)) { this._close(); } }; this._handleKeyDown = (e) => { if (!this._isOpen) return; const options = Array.from(this.querySelectorAll('kr-select-option')); switch (e.key) { case 'Escape': this._close(); this._triggerElement?.focus(); break; case 'ArrowDown': e.preventDefault(); if (options.some(o => !o.disabled)) { let newIndex = this._highlightedIndex + 1; while (newIndex < options.length && options[newIndex]?.disabled) newIndex++; if (newIndex < options.length) this._highlightedIndex = newIndex; } break; case 'ArrowUp': e.preventDefault(); { let newIndex = this._highlightedIndex - 1; while (newIndex >= 0 && options[newIndex]?.disabled) newIndex--; if (newIndex >= 0) this._highlightedIndex = newIndex; } break; case 'Enter': e.preventDefault(); if (this._highlightedIndex >= 0 && this._highlightedIndex < options.length) { this._selectOption(options[this._highlightedIndex]); } break; } }; this._internals = this.attachInternals(); } // Form-associated custom element callbacks get form() { return this._internals.form; } get validity() { return this._internals.validity; } get validationMessage() { return this._internals.validationMessage; } get willValidate() { return this._internals.willValidate; } checkValidity() { return this._internals.checkValidity(); } reportValidity() { return this._internals.reportValidity(); } formResetCallback() { this.value = ''; this._touched = false; this._internals.setFormValue(''); this._internals.setValidity({}); } formStateRestoreCallback(state) { this.value = state; } connectedCallback() { super.connectedCallback(); document.addEventListener('click', this._handleOutsideClick); document.addEventListener('keydown', this._handleKeyDown); this.addEventListener('invalid', this._handleInvalid); } firstUpdated() { this._updateValidity(); } updated(changedProperties) { if (changedProperties.has('required') || changedProperties.has('value')) { this._updateValidity(); } } disconnectedCallback() { super.disconnectedCallback(); document.removeEventListener('click', this._handleOutsideClick); document.removeEventListener('keydown', this._handleKeyDown); this.removeEventListener('invalid', this._handleInvalid); } _toggle() { if (this.disabled || this.readonly) return; if (this._isOpen) { this._close(); } else { this._isOpen = true; const options = Array.from(this.querySelectorAll('kr-select-option')); this._highlightedIndex = options.findIndex(o => o.value === this.value); } } _close() { this._isOpen = false; this._highlightedIndex = -1; } _selectOption(option) { if (option.disabled) return; this.value = option.value; this._internals.setFormValue(this.value); this._updateValidity(); this.dispatchEvent(new Event('change', { bubbles: true, composed: true })); this._close(); this._triggerElement?.focus(); } _handleBlur() { this._touched = true; this._updateValidity(); } _updateValidity() { if (this.required && !this.value) { this._internals.setValidity({ valueMissing: true }, 'Please select an option', this._triggerElement); } else { this._internals.setValidity({}); } } render() { const options = Array.from(this.querySelectorAll('kr-select-option')); const selectedLabel = options.find(o => o.value === this.value)?.label; return b ` <div class=\"wrapper\"> ${this.label ? b ` <label> ${this.label} ${this.required ? b `<span class=\"required\" aria-hidden=\"true\">*</span>` : ''} </label> ` : A} <div class=\"select-wrapper\"> <button class=${e$1({ 'select-trigger': true, 'select-trigger--open': this._isOpen, 'select-trigger--invalid': this._touched && this.required && !this.value, })} type=\"button\" ?disabled=${this.disabled} aria-haspopup=\"listbox\" aria-expanded=${this._isOpen} @click=${this._toggle} @blur=${this._handleBlur} > <span class=${e$1({ 'select-value': true, 'select-placeholder': !selectedLabel })}> ${selectedLabel || this.placeholder} </span> <svg class=${e$1({ 'chevron-icon': true, 'select-icon': true, 'select-icon--open': this._isOpen })} viewBox=\"0 0 20 20\" fill=\"currentColor\" > <path fill-rule=\"evenodd\" d=\"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z\" clip-rule=\"evenodd\" /> </svg> </button> <div class=${e$1({ 'select-dropdown': true, 'hidden': !this._isOpen })} role=\"listbox\"> <div class=\"select-options\"> ${options.length === 0 ? b `<div class=\"select-empty\">No options available</div>` : options.map((option, idx) => { const isSelected = option.value === this.value; return b ` <div class=${e$1({ 'select-option': true, 'select-option--selected': isSelected, 'select-option--disabled': option.disabled, 'select-option--highlighted': idx === this._highlightedIndex, })} role=\"option\" aria-selected=${isSelected} @click=${() => this._selectOption(option)} @mouseenter=${() => (this._highlightedIndex = idx)} > ${option.label} ${isSelected ? b `<svg class=\"chevron-icon select-check\" viewBox=\"0 0 20 20\" fill=\"currentColor\"> <path fill-rule=\"evenodd\" d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\" clip-rule=\"evenodd\" /> </svg>` : A} </div> `; })} </div> </div> </div> ${this._touched && this.required && !this.value ? b `<div class=\"validation-message\">Please select an option</div>` : this.hint ? b `<div class=\"hint\">${this.hint}</div>` : ''} </div> <div class=\"options-slot\"> <slot @slotchange=${() => this.requestUpdate()}></slot> </div> `; } // Public methods for programmatic control focus() { this._triggerElement?.focus(); } blur() { this._triggerElement?.blur(); } }",
314
+ "default": "class KRSelectField extends i$2 { constructor() { super(); /** * The select label text */ this.label = ''; /** * The input name for form submission */ this.name = ''; /** * The currently selected value */ this.value = ''; /** * Placeholder text when no option is selected */ this.placeholder = 'Select an option'; /** * Whether the select is disabled */ this.disabled = false; /** * Whether the field is required */ this.required = false; /** * Whether the field is readonly */ this.readonly = false; /** * Helper text shown below the select */ this.hint = ''; this._isOpen = false; this._highlightedIndex = -1; this._touched = false; this._handleInvalid = (e) => { e.preventDefault(); this._touched = true; }; this._handleOutsideClick = (e) => { if (!e.composedPath().includes(this)) { this._close(); } }; this._handleKeyDown = (e) => { if (!this._isOpen) return; const options = Array.from(this.querySelectorAll('kr-select-option')); switch (e.key) { case 'Escape': this._close(); this._triggerElement?.focus(); break; case 'ArrowDown': e.preventDefault(); if (options.some(o => !o.disabled)) { let newIndex = this._highlightedIndex + 1; while (newIndex < options.length && options[newIndex]?.disabled) newIndex++; if (newIndex < options.length) this._highlightedIndex = newIndex; } break; case 'ArrowUp': e.preventDefault(); { let newIndex = this._highlightedIndex - 1; while (newIndex >= 0 && options[newIndex]?.disabled) newIndex--; if (newIndex >= 0) this._highlightedIndex = newIndex; } break; case 'Enter': e.preventDefault(); if (this._highlightedIndex >= 0 && this._highlightedIndex < options.length) { this._selectOption(options[this._highlightedIndex]); } break; } }; this._internals = this.attachInternals(); } // Form-associated custom element callbacks get form() { return this._internals.form; } get validity() { return this._internals.validity; } get validationMessage() { return this._internals.validationMessage; } get willValidate() { return this._internals.willValidate; } checkValidity() { return this._internals.checkValidity(); } reportValidity() { return this._internals.reportValidity(); } formResetCallback() { this.value = ''; this._touched = false; this._internals.setFormValue(''); this._internals.setValidity({}); } formStateRestoreCallback(state) { this.value = state; } connectedCallback() { super.connectedCallback(); document.addEventListener('click', this._handleOutsideClick); document.addEventListener('keydown', this._handleKeyDown); this.addEventListener('invalid', this._handleInvalid); } firstUpdated() { this._updateValidity(); } updated(changedProperties) { if (changedProperties.has('required') || changedProperties.has('value')) { this._updateValidity(); } } disconnectedCallback() { super.disconnectedCallback(); document.removeEventListener('click', this._handleOutsideClick); document.removeEventListener('keydown', this._handleKeyDown); this.removeEventListener('invalid', this._handleInvalid); } _toggle() { if (this.disabled || this.readonly) return; if (this._isOpen) { this._close(); } else { this._isOpen = true; const options = Array.from(this.querySelectorAll('kr-select-option')); this._highlightedIndex = options.findIndex(o => o.value === this.value); // Position the fixed dropdown relative to the trigger requestAnimationFrame(() => { const dropdown = this.shadowRoot?.querySelector('.select-dropdown'); if (dropdown) { const triggerRect = this._triggerElement.getBoundingClientRect(); dropdown.style.top = triggerRect.bottom + 4 + 'px'; dropdown.style.left = triggerRect.left + 'px'; dropdown.style.width = triggerRect.width + 'px'; } }); } } _close() { this._isOpen = false; this._highlightedIndex = -1; } _selectOption(option) { if (option.disabled) return; this.value = option.value; this._internals.setFormValue(this.value); this._updateValidity(); this.dispatchEvent(new Event('change', { bubbles: true, composed: true })); this._close(); this._triggerElement?.focus(); } _handleBlur() { this._touched = true; this._updateValidity(); } _updateValidity() { if (this.required && !this.value) { this._internals.setValidity({ valueMissing: true }, 'Please select an option', this._triggerElement); } else { this._internals.setValidity({}); } } render() { const options = Array.from(this.querySelectorAll('kr-select-option')); const selectedLabel = options.find(o => o.value === this.value)?.label; return b ` <div class=\"wrapper\"> ${this.label ? b ` <label> ${this.label} ${this.required ? b `<span class=\"required\" aria-hidden=\"true\">*</span>` : ''} </label> ` : A} <div class=\"select-wrapper\"> <button class=${e$1({ 'select-trigger': true, 'select-trigger--open': this._isOpen, 'select-trigger--invalid': this._touched && this.required && !this.value, })} type=\"button\" ?disabled=${this.disabled} aria-haspopup=\"listbox\" aria-expanded=${this._isOpen} @click=${this._toggle} @blur=${this._handleBlur} > <span class=${e$1({ 'select-value': true, 'select-placeholder': !selectedLabel })}> ${selectedLabel || this.placeholder} </span> <svg class=${e$1({ 'chevron-icon': true, 'select-icon': true, 'select-icon--open': this._isOpen })} viewBox=\"0 0 24 24\" fill=\"currentColor\" > <path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6z\"/> </svg> </button> <div class=${e$1({ 'select-dropdown': true, 'hidden': !this._isOpen })} role=\"listbox\"> <div class=\"select-options\"> ${options.length === 0 ? b `<div class=\"select-empty\">No options available</div>` : options.map((option, idx) => { const isSelected = option.value === this.value; return b ` <div class=${e$1({ 'select-option': true, 'select-option--selected': isSelected, 'select-option--disabled': option.disabled, 'select-option--highlighted': idx === this._highlightedIndex, })} role=\"option\" aria-selected=${isSelected} @click=${() => this._selectOption(option)} @mouseenter=${() => (this._highlightedIndex = idx)} > ${option.label} ${isSelected ? b `<svg class=\"chevron-icon select-check\" viewBox=\"0 0 20 20\" fill=\"currentColor\"> <path fill-rule=\"evenodd\" d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\" clip-rule=\"evenodd\" /> </svg>` : A} </div> `; })} </div> </div> </div> ${this._touched && this.required && !this.value ? b `<div class=\"validation-message\">Please select an option</div>` : this.hint ? b `<div class=\"hint\">${this.hint}</div>` : ''} </div> <div class=\"options-slot\"> <slot @slotchange=${() => this.requestUpdate()}></slot> </div> `; } // Public methods for programmatic control focus() { this._triggerElement?.focus(); } blur() { this._triggerElement?.blur(); } }",
279
315
  "description": "A select dropdown component that works with native browser forms.\n\nUses ElementInternals for form association, allowing the component\nto participate in form submission, validation, and reset."
280
316
  },
281
317
  {
@@ -297,7 +333,7 @@
297
333
  "name": "t",
298
334
  "declaration": {
299
335
  "name": "e",
300
- "module": "dist/krubble.bundled.js"
336
+ "module": "dist/krubble-components.bundled.js"
301
337
  }
302
338
  },
303
339
  {
@@ -305,15 +341,7 @@
305
341
  "name": "t",
306
342
  "declaration": {
307
343
  "name": "e",
308
- "module": "dist/krubble.bundled.js"
309
- }
310
- },
311
- {
312
- "kind": "js",
313
- "name": "DialogRef",
314
- "declaration": {
315
- "name": "DialogRef",
316
- "module": "dist/krubble.bundled.js"
344
+ "module": "dist/krubble-components.bundled.js"
317
345
  }
318
346
  },
319
347
  {
@@ -321,7 +349,7 @@
321
349
  "name": "KRAccordion",
322
350
  "declaration": {
323
351
  "name": "KRAccordion",
324
- "module": "dist/krubble.bundled.js"
352
+ "module": "dist/krubble-components.bundled.js"
325
353
  }
326
354
  },
327
355
  {
@@ -329,7 +357,7 @@
329
357
  "name": "KRAlert",
330
358
  "declaration": {
331
359
  "name": "KRAlert",
332
- "module": "dist/krubble.bundled.js"
360
+ "module": "dist/krubble-components.bundled.js"
333
361
  }
334
362
  },
335
363
  {
@@ -337,7 +365,7 @@
337
365
  "name": "KRButton",
338
366
  "declaration": {
339
367
  "name": "KRButton",
340
- "module": "dist/krubble.bundled.js"
368
+ "module": "dist/krubble-components.bundled.js"
341
369
  }
342
370
  },
343
371
  {
@@ -345,7 +373,7 @@
345
373
  "name": "KRCodeDemo",
346
374
  "declaration": {
347
375
  "name": "KRCodeDemo",
348
- "module": "dist/krubble.bundled.js"
376
+ "module": "dist/krubble-components.bundled.js"
349
377
  }
350
378
  },
351
379
  {
@@ -353,7 +381,7 @@
353
381
  "name": "KRContextMenu",
354
382
  "declaration": {
355
383
  "name": "KRContextMenu",
356
- "module": "dist/krubble.bundled.js"
384
+ "module": "dist/krubble-components.bundled.js"
357
385
  }
358
386
  },
359
387
  {
@@ -361,7 +389,23 @@
361
389
  "name": "KRDialog",
362
390
  "declaration": {
363
391
  "name": "KRDialog",
364
- "module": "dist/krubble.bundled.js"
392
+ "module": "dist/krubble-components.bundled.js"
393
+ }
394
+ },
395
+ {
396
+ "kind": "js",
397
+ "name": "KRDialogRef",
398
+ "declaration": {
399
+ "name": "KRDialogRef",
400
+ "module": "dist/krubble-components.bundled.js"
401
+ }
402
+ },
403
+ {
404
+ "kind": "js",
405
+ "name": "KRProgressBar",
406
+ "declaration": {
407
+ "name": "KRProgressBar",
408
+ "module": "dist/krubble-components.bundled.js"
365
409
  }
366
410
  },
367
411
  {
@@ -369,7 +413,7 @@
369
413
  "name": "KRSelectField",
370
414
  "declaration": {
371
415
  "name": "KRSelectField",
372
- "module": "dist/krubble.bundled.js"
416
+ "module": "dist/krubble-components.bundled.js"
373
417
  }
374
418
  },
375
419
  {
@@ -377,7 +421,7 @@
377
421
  "name": "KRSelectOption",
378
422
  "declaration": {
379
423
  "name": "KRSelectOption",
380
- "module": "dist/krubble.bundled.js"
424
+ "module": "dist/krubble-components.bundled.js"
381
425
  }
382
426
  },
383
427
  {
@@ -385,7 +429,15 @@
385
429
  "name": "KRSnackbar",
386
430
  "declaration": {
387
431
  "name": "KRSnackbar",
388
- "module": "dist/krubble.bundled.js"
432
+ "module": "dist/krubble-components.bundled.js"
433
+ }
434
+ },
435
+ {
436
+ "kind": "js",
437
+ "name": "KRSpinner",
438
+ "declaration": {
439
+ "name": "KRSpinner",
440
+ "module": "dist/krubble-components.bundled.js"
389
441
  }
390
442
  },
391
443
  {
@@ -393,7 +445,7 @@
393
445
  "name": "KRTab",
394
446
  "declaration": {
395
447
  "name": "KRTab",
396
- "module": "dist/krubble.bundled.js"
448
+ "module": "dist/krubble-components.bundled.js"
397
449
  }
398
450
  },
399
451
  {
@@ -401,7 +453,7 @@
401
453
  "name": "KRTabGroup",
402
454
  "declaration": {
403
455
  "name": "KRTabGroup",
404
- "module": "dist/krubble.bundled.js"
456
+ "module": "dist/krubble-components.bundled.js"
405
457
  }
406
458
  },
407
459
  {
@@ -409,7 +461,7 @@
409
461
  "name": "KRTable",
410
462
  "declaration": {
411
463
  "name": "KRTable",
412
- "module": "dist/krubble.bundled.js"
464
+ "module": "dist/krubble-components.bundled.js"
413
465
  }
414
466
  },
415
467
  {
@@ -417,7 +469,7 @@
417
469
  "name": "KRTextField",
418
470
  "declaration": {
419
471
  "name": "KRTextField",
420
- "module": "dist/krubble.bundled.js"
472
+ "module": "dist/krubble-components.bundled.js"
421
473
  }
422
474
  },
423
475
  {
@@ -425,7 +477,7 @@
425
477
  "name": "KRTextareaField",
426
478
  "declaration": {
427
479
  "name": "KRTextareaField",
428
- "module": "dist/krubble.bundled.js"
480
+ "module": "dist/krubble-components.bundled.js"
429
481
  }
430
482
  },
431
483
  {
@@ -433,14 +485,14 @@
433
485
  "name": "krBaseCSS",
434
486
  "declaration": {
435
487
  "name": "krBaseCSS",
436
- "module": "dist/krubble.bundled.js"
488
+ "module": "dist/krubble-components.bundled.js"
437
489
  }
438
490
  }
439
491
  ]
440
492
  },
441
493
  {
442
494
  "kind": "javascript-module",
443
- "path": "dist/krubble.bundled.min.js",
495
+ "path": "dist/krubble-components.bundled.min.js",
444
496
  "declarations": [
445
497
  {
446
498
  "kind": "variable",
@@ -453,38 +505,38 @@
453
505
  },
454
506
  {
455
507
  "kind": "variable",
456
- "name": "le",
508
+ "name": "ae",
457
509
  "default": "r` :host, *, *::before, *::after { box-sizing: border-box; } :host { /* Primary */ --kr-primary: rgb(22, 48, 82); --kr-primary-hover: rgb(16, 36, 62); --kr-primary-text: #ffffff; /* Accent */ --kr-accent: #BEEA4E; --kr-accent-hover: #a8d43a; --kr-accent-text: #000000; /* Text */ --kr-text: #000000; --kr-text-muted: #4b5563; --kr-text-disabled: #9ca3af; /* Borders */ --kr-border: #e5e7eb; } `"
458
510
  },
459
511
  {
460
512
  "kind": "variable",
461
513
  "name": "be",
462
- "default": "class extends ne{constructor(){super(...arguments),this.header=\"\",this.expanded=!1}toggle(){this.expanded=!this.expanded}render(){return U` <div class=\"header\" @click=${this.toggle}> <span class=\"header__title\">${this.header}</span> <svg class=\"header__icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"> <path d=\"M6 9l6 6 6-6\"/> </svg> </div> <div class=\"content\"> <div class=\"content__inner\"> <div class=\"content__body\"> <slot></slot> </div> </div> </div> `}}"
514
+ "default": "class extends ne{constructor(){super(...arguments),this.header=\"\",this.expanded=!1}toggle(){this.expanded=!this.expanded}render(){return V` <div class=\"header\" @click=${this.toggle}> <span class=\"header__title\">${this.header}</span> <svg class=\"header__icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"> <path d=\"M6 9l6 6 6-6\"/> </svg> </div> <div class=\"content\"> <div class=\"content__inner\"> <div class=\"content__body\"> <slot></slot> </div> </div> </div> `}}"
463
515
  },
464
516
  {
465
517
  "kind": "variable",
466
518
  "name": "Ce",
467
- "default": "class extends ne{constructor(){super(...arguments),this.type=\"info\",this.dismissible=!1,this.visible=!0}_handleDismiss(){this.visible=!1,this.dispatchEvent(new CustomEvent(\"dismiss\",{bubbles:!0,composed:!0}))}render(){const e={info:U`<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z\" clip-rule=\"evenodd\"/></svg>`,success:U`<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\" clip-rule=\"evenodd\"/></svg>`,warning:U`<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\" clip-rule=\"evenodd\"/></svg>`,error:U`<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\" clip-rule=\"evenodd\"/></svg>`};return U` <div class=${we({alert:!0,[\"alert--\"+this.type]:!0,\"alert--hidden\":!this.visible})} role=\"alert\" > ${e[this.type]} <div class=\"content\"> ${this.header?U`<h4 class=\"header\">${this.header}</h4>`:N} <div class=\"message\"> <slot></slot> </div> </div> ${this.dismissible?U` <button class=\"dismiss\" type=\"button\" aria-label=\"Dismiss alert\" @click=${this._handleDismiss} > <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"16\" height=\"16\"> <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> `:N} </div> `}}"
519
+ "default": "class extends ne{constructor(){super(...arguments),this.type=\"info\",this.title=\"\",this.dismissible=!1,this.visible=!0}_handleDismiss(){this.visible=!1,this.dispatchEvent(new CustomEvent(\"dismiss\",{bubbles:!0,composed:!0}))}render(){const e={info:V`<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z\" clip-rule=\"evenodd\"/></svg>`,success:V`<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\" clip-rule=\"evenodd\"/></svg>`,warning:V`<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\" clip-rule=\"evenodd\"/></svg>`,error:V`<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\" clip-rule=\"evenodd\"/></svg>`};return V` <div class=${we({alert:!0,[\"alert--\"+this.type]:!0,\"alert--has-header\":!!this.title,\"alert--hidden\":!this.visible})} role=\"alert\" > ${e[this.type]} <div class=\"content\"> ${this.title?V`<h4 class=\"header\">${this.title}</h4>`:N} <div class=\"message\"> <slot></slot> </div> </div> ${this.dismissible?V` <button class=\"dismiss\" type=\"button\" aria-label=\"Dismiss alert\" @click=${this._handleDismiss} > <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"16\" height=\"16\"> <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> `:N} </div> `}}"
468
520
  },
469
521
  {
470
522
  "kind": "variable",
471
523
  "name": "Ee",
472
- "default": "class extends ne{constructor(){super(...arguments),this.variant=\"flat\",this.color=\"primary\",this.size=\"medium\",this.disabled=!1,this.options=[],this._state=\"idle\",this._stateText=\"\",this._dropdownOpened=!1,this._dropdownAlignRight=!1,this._handleHostClick=e=>{this.options.length&&(e.stopPropagation(),this._toggleDropdown())},this._handleKeydown=e=>{\"Enter\"!==e.key&&\" \"!==e.key||(e.preventDefault(),this.options.length?this._toggleDropdown():this.click()),\"Escape\"===e.key&&this._dropdownOpened&&(this._dropdownOpened=!1)},this._handleClickOutside=e=>{this._dropdownOpened&&!this.contains(e.target)&&(this._dropdownOpened=!1)}}connectedCallback(){super.connectedCallback(),this.setAttribute(\"role\",this.href?\"link\":\"button\"),this.setAttribute(\"tabindex\",\"0\"),this.addEventListener(\"keydown\",this._handleKeydown),this.addEventListener(\"click\",this._handleHostClick),document.addEventListener(\"click\",this._handleClickOutside)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(\"keydown\",this._handleKeydown),this.removeEventListener(\"click\",this._handleHostClick),document.removeEventListener(\"click\",this._handleClickOutside)}_toggleDropdown(){this._dropdownOpened=!this._dropdownOpened,this._dropdownOpened&&requestAnimationFrame(()=>{const e=this.shadowRoot?.querySelector(\".dropdown\");if(e){const t=e.getBoundingClientRect();this._dropdownAlignRight=t.right>window.innerWidth}})}_handleOptionClick(e,t){t.stopPropagation(),this._dropdownOpened=!1,this.dispatchEvent(new CustomEvent(\"option-select\",{detail:{id:e.id,label:e.label},bubbles:!0,composed:!0}))}showLoading(){this._clearStateTimeout(),this._state=\"loading\",this._stateText=\"\"}showSuccess(e=\"Success\",t=2e3){this._clearStateTimeout(),this._state=\"success\",this._stateText=e,this._stateTimeout=window.setTimeout(()=>this.reset(),t)}showError(e=\"Error\",t=2e3){this._clearStateTimeout(),this._state=\"error\",this._stateText=e,this._stateTimeout=window.setTimeout(()=>this.reset(),t)}reset(){this._clearStateTimeout(),this._state=\"idle\",this._stateText=\"\"}_clearStateTimeout(){this._stateTimeout&&(clearTimeout(this._stateTimeout),this._stateTimeout=void 0)}updated(e){this.classList.toggle(\"kr-button--loading\",\"loading\"===this._state),this.classList.toggle(\"kr-button--success\",\"success\"===this._state),this.classList.toggle(\"kr-button--error\",\"error\"===this._state),this.classList.toggle(`kr-button--${this.variant}`,!0),this.classList.toggle(`kr-button--${this.color}`,!0),this.classList.toggle(\"kr-button--small\",\"small\"===this.size),this.classList.toggle(\"kr-button--large\",\"large\"===this.size)}render(){const e=U` <slot></slot> ${this.options.length?U`<svg class=\"caret\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20\" width=\"20\" 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>`:N} ${\"idle\"!==this._state?U`<span class=\"state-overlay\"> ${\"loading\"===this._state?U`<span class=\"spinner\"></span>`:this._stateText} </span>`:N} ${this.options.length?U` <div class=\"dropdown ${this._dropdownOpened?\"dropdown--opened\":\"\"} ${this._dropdownAlignRight?\"dropdown--align-right\":\"\"}\"> ${this.options.map(e=>U` <button class=\"dropdown-item\" @click=${t=>this._handleOptionClick(e,t)} >${e.label}</button> `)} </div> `:N} `;return this.href?U`<a class=\"link\" href=${this.href} target=${this.target||N}>${e}</a>`:e}}"
524
+ "default": "class extends ne{constructor(){super(...arguments),this.variant=\"flat\",this.color=\"primary\",this.size=\"medium\",this.disabled=!1,this.options=[],this._state=\"idle\",this._stateText=\"\",this._dropdownOpened=!1,this._handleHostClick=e=>{this.options.length&&(e.stopPropagation(),this._toggleDropdown())},this._handleKeydown=e=>{\"Enter\"!==e.key&&\" \"!==e.key||(e.preventDefault(),this.options.length?this._toggleDropdown():this.click()),\"Escape\"===e.key&&this._dropdownOpened&&(this._dropdownOpened=!1)},this._handleClickOutside=e=>{this._dropdownOpened&&!this.contains(e.target)&&(this._dropdownOpened=!1)}}connectedCallback(){super.connectedCallback(),this.setAttribute(\"role\",this.href?\"link\":\"button\"),this.setAttribute(\"tabindex\",\"0\"),this.addEventListener(\"keydown\",this._handleKeydown),this.addEventListener(\"click\",this._handleHostClick),document.addEventListener(\"click\",this._handleClickOutside)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(\"keydown\",this._handleKeydown),this.removeEventListener(\"click\",this._handleHostClick),document.removeEventListener(\"click\",this._handleClickOutside)}_toggleDropdown(){this._dropdownOpened=!this._dropdownOpened,this._dropdownOpened&&requestAnimationFrame(()=>{const e=this.shadowRoot?.querySelector(\".dropdown\");if(e){const t=this.getBoundingClientRect();e.style.top=t.bottom+4+\"px\",e.style.left=t.left+\"px\",e.style.minWidth=t.width+\"px\";e.getBoundingClientRect().right>window.innerWidth&&(e.style.left=\"\",e.style.right=window.innerWidth-t.right+\"px\")}})}_handleOptionClick(e,t){t.stopPropagation(),this._dropdownOpened=!1,this.dispatchEvent(new CustomEvent(\"option-select\",{detail:{id:e.id,label:e.label},bubbles:!0,composed:!0}))}showLoading(){this._clearStateTimeout(),this._state=\"loading\",this._stateText=\"\"}showSuccess(e=\"Success\",t=2e3){this._clearStateTimeout(),this._state=\"success\",this._stateText=e,t>0&&(this._stateTimeout=window.setTimeout(()=>this.reset(),t))}showError(e=\"Error\",t=2e3){this._clearStateTimeout(),this._state=\"error\",this._stateText=e,t>0&&(this._stateTimeout=window.setTimeout(()=>this.reset(),t))}reset(){this._clearStateTimeout(),this._state=\"idle\",this._stateText=\"\"}_clearStateTimeout(){this._stateTimeout&&(clearTimeout(this._stateTimeout),this._stateTimeout=void 0)}updated(e){this.classList.toggle(\"kr-button--loading\",\"loading\"===this._state),this.classList.toggle(\"kr-button--success\",\"success\"===this._state),this.classList.toggle(\"kr-button--error\",\"error\"===this._state),this.classList.toggle(`kr-button--${this.variant}`,!0),this.classList.toggle(`kr-button--${this.color}`,!0),this.classList.toggle(\"kr-button--small\",\"small\"===this.size),this.classList.toggle(\"kr-button--large\",\"large\"===this.size)}render(){const e=V` <slot></slot> ${this.options.length?V`<svg class=\"caret\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20\" width=\"20\" 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>`:N} ${\"idle\"!==this._state?V`<span class=\"state-overlay\"> ${\"loading\"===this._state?V`<span class=\"spinner\"></span>`:this._stateText} </span>`:N} ${this.options.length?V` <div class=\"dropdown ${this._dropdownOpened?\"dropdown--opened\":\"\"}\"> ${this.options.map(e=>V` <button class=\"dropdown-item\" @click=${t=>this._handleOptionClick(e,t)} >${e.label}</button> `)} </div> `:N} `;return this.href?V`<a class=\"link\" href=${this.href} target=${this.target||N}>${e}</a>`:e}}"
473
525
  },
474
526
  {
475
527
  "kind": "variable",
476
528
  "name": "Pe",
477
- "default": "class extends ne{constructor(){super(...arguments),this.language=\"html\",this.code=\"\",this.activeTab=\"preview\",this.copied=!1}setTab(e){this.activeTab=e}getHighlightedCode(){return this.code?window.Prism&&window.Prism.languages[this.language]?window.Prism.highlight(this.code,window.Prism.languages[this.language],this.language):this.escapeHtml(this.code):\"\"}escapeHtml(e){const t=document.createElement(\"div\");return t.textContent=e,t.innerHTML}async copyCode(){if(this.code)try{await navigator.clipboard.writeText(this.code),this.copied=!0,setTimeout(()=>{this.copied=!1},2e3)}catch(e){console.error(\"Failed to copy code:\",e)}}render(){return U` <div class=\"tabs\"> <button class=${we({tab:!0,\"tab--active\":\"preview\"===this.activeTab})} @click=${()=>this.setTab(\"preview\")} > Preview </button> <button class=${we({tab:!0,\"tab--active\":\"code\"===this.activeTab})} @click=${()=>this.setTab(\"code\")} > Code </button> </div> <div class=${we({panel:!0,\"panel--active\":\"preview\"===this.activeTab,preview:!0})}> <slot name=\"preview\"></slot> </div> <div class=${we({panel:!0,\"panel--active\":\"code\"===this.activeTab,\"code-container\":!0})}> <button class=${we({\"copy-btn\":!0,\"copy-btn--copied\":this.copied})} @click=${this.copyCode} > ${this.copied?\"Copied!\":\"Copy\"} </button> <pre class=\"code\"><code>${Oe(this.getHighlightedCode())}</code></pre> </div> `}}"
529
+ "default": "class extends ne{constructor(){super(...arguments),this.language=\"html\",this.code=\"\",this.activeTab=\"preview\",this.copied=!1,this.highlightedCode=\"\"}connectedCallback(){super.connectedCallback(),requestAnimationFrame(()=>{this.code||(this.code=this.innerHTML.trim().replace(/=\"\"(?=[\\s>])/g,\"\")),this.querySelectorAll(\"script\").forEach(e=>{const t=document.createElement(\"script\");t.textContent=e.textContent,e.replaceWith(t)}),this.code&&window.hljs&&window.hljs.getLanguage(this.language)?this.highlightedCode=window.hljs.highlight(this.code,{language:this.language}).value:this.highlightedCode=this.code.replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\")})}activateTab(e){this.activeTab=e}copyCode(){this.code&&navigator.clipboard.writeText(this.code).then(()=>{this.copied=!0,setTimeout(()=>{this.copied=!1},2e3)})}render(){return V` <div class=\"tabs\"> <button class=${we({tab:!0,\"tab--active\":\"preview\"===this.activeTab})} @click=${()=>this.activateTab(\"preview\")} > Preview </button> <button class=${we({tab:!0,\"tab--active\":\"code\"===this.activeTab})} @click=${()=>this.activateTab(\"code\")} > Code </button> <button class=${we({copy:!0,\"copy--success\":this.copied})} @click=${this.copyCode} title=${this.copied?\"Copied!\":\"Copy code\"} > ${this.copied?V`<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>`:V`<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path></svg>`} </button> </div> <div class=${we({panel:!0,\"panel--active\":\"preview\"===this.activeTab,\"panel--preview\":!0})}> <slot></slot> </div> <div class=${we({panel:!0,\"panel--active\":\"code\"===this.activeTab,\"panel--code\":!0})}> <pre class=\"code\"><code>${ze(this.highlightedCode)}</code></pre> </div> `}}"
478
530
  },
479
531
  {
480
532
  "kind": "variable",
481
533
  "name": "Le",
482
- "default": "class extends ne{constructor(){super(...arguments),this.items=[],this.resolvePromise=null,this.boundHandleOutsideClick=this.handleOutsideClick.bind(this),this.boundHandleKeyDown=this.handleKeyDown.bind(this)}static async open(e){const t=document.querySelector(\"kr-context-menu\");t&&t.remove();const i=document.createElement(\"kr-context-menu\");return document.body.appendChild(i),i.show(e)}async show(e){this.items=e.items,this.style.left=`${e.x}px`,this.style.top=`${e.y}px`,await this.updateComplete;const t=this.getBoundingClientRect();return t.right>window.innerWidth&&(this.style.left=e.x-t.width+\"px\"),t.bottom>window.innerHeight&&(this.style.top=e.y-t.height+\"px\"),requestAnimationFrame(()=>{document.addEventListener(\"click\",this.boundHandleOutsideClick),document.addEventListener(\"contextmenu\",this.boundHandleOutsideClick),document.addEventListener(\"keydown\",this.boundHandleKeyDown)}),new Promise(e=>{this.resolvePromise=e})}handleOutsideClick(e){this.contains(e.target)||this.close(null)}handleKeyDown(e){\"Escape\"===e.key&&this.close(null)}handleItemClick(e){e.disabled||e.divider||this.close(e)}close(e){document.removeEventListener(\"click\",this.boundHandleOutsideClick),document.removeEventListener(\"contextmenu\",this.boundHandleOutsideClick),document.removeEventListener(\"keydown\",this.boundHandleKeyDown),this.resolvePromise&&(this.resolvePromise(e),this.resolvePromise=null),this.remove()}render(){return U` <div class=\"menu\"> ${this.items.map(e=>e.divider?U`<div class=\"menu__divider\"></div>`:U` <button class=\"menu__item\" ?disabled=${e.disabled} @click=${()=>this.handleItemClick(e)} > ${e.icon?U`<span class=\"menu__item-icon\">${e.icon}</span>`:null} ${e.label} </button> `)} </div> `}}"
534
+ "default": "class extends ne{constructor(){super(...arguments),this.items=[],this.resolvePromise=null,this.boundHandleOutsideClick=this.handleOutsideClick.bind(this),this.boundHandleKeyDown=this.handleKeyDown.bind(this)}static async open(e){const t=document.querySelector(\"kr-context-menu\");t&&t.remove();const i=document.createElement(\"kr-context-menu\");return document.body.appendChild(i),i.show(e)}async show(e){this.items=e.items,this.style.left=`${e.x}px`,this.style.top=`${e.y}px`,await this.updateComplete;const t=this.getBoundingClientRect();return t.right>window.innerWidth&&(this.style.left=e.x-t.width+\"px\"),t.bottom>window.innerHeight&&(this.style.top=e.y-t.height+\"px\"),requestAnimationFrame(()=>{document.addEventListener(\"click\",this.boundHandleOutsideClick),document.addEventListener(\"contextmenu\",this.boundHandleOutsideClick),document.addEventListener(\"keydown\",this.boundHandleKeyDown)}),new Promise(e=>{this.resolvePromise=e})}handleOutsideClick(e){this.contains(e.target)||this.close(null)}handleKeyDown(e){\"Escape\"===e.key&&this.close(null)}handleItemClick(e){e.disabled||e.divider||this.close(e)}close(e){document.removeEventListener(\"click\",this.boundHandleOutsideClick),document.removeEventListener(\"contextmenu\",this.boundHandleOutsideClick),document.removeEventListener(\"keydown\",this.boundHandleKeyDown),this.resolvePromise&&(this.resolvePromise(e),this.resolvePromise=null),this.remove()}render(){return V` <div class=\"menu\"> ${this.items.map(e=>e.divider?V`<div class=\"menu__divider\"></div>`:V` <button class=\"menu__item\" ?disabled=${e.disabled} @click=${()=>this.handleItemClick(e)} > ${e.icon?V`<span class=\"menu__item-icon\">${e.icon}</span>`:null} ${e.label} </button> `)} </div> `}}"
483
535
  },
484
536
  {
485
537
  "kind": "class",
486
538
  "description": "",
487
- "name": "Me",
539
+ "name": "qe",
488
540
  "members": [
489
541
  {
490
542
  "kind": "method",
@@ -510,7 +562,7 @@
510
562
  },
511
563
  {
512
564
  "kind": "field",
513
- "name": "resolvePromise",
565
+ "name": "_resolvePromise",
514
566
  "type": {
515
567
  "text": "null"
516
568
  },
@@ -518,7 +570,7 @@
518
570
  },
519
571
  {
520
572
  "kind": "field",
521
- "name": "dialogElement",
573
+ "name": "_dialogElement",
522
574
  "type": {
523
575
  "text": "null"
524
576
  },
@@ -526,54 +578,64 @@
526
578
  },
527
579
  {
528
580
  "kind": "field",
529
- "name": "promise",
530
- "default": "new Promise(e=>{this.resolvePromise=e})"
581
+ "name": "_promise",
582
+ "default": "new Promise(e=>{this._resolvePromise=e})"
531
583
  }
532
584
  ]
533
585
  },
534
586
  {
535
587
  "kind": "variable",
536
- "name": "je",
537
- "default": "class extends ne{constructor(){super(...arguments),this.contentElement=null,this.dialogRef=null,this.boundHandleKeyDown=this.handleKeyDown.bind(this)}static open(e,t){const i=document.querySelector(\"kr-dialog\");i&&i.remove();const o=new Me,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.boundHandleKeyDown),o}handleKeyDown(e){\"Escape\"===e.key&&this.dialogRef?.close(void 0)}handleBackdropClick(e){e.target.classList.contains(\"backdrop\")&&this.dialogRef?.close(void 0)}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(\"keydown\",this.boundHandleKeyDown)}render(){return U` <div class=\"backdrop\" @click=${this.handleBackdropClick}></div> <div class=\"dialog\"> ${this.contentElement} </div> `}}"
588
+ "name": "Ie",
589
+ "default": "class extends ne{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 qe,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 V` <div class=\"backdrop\" @click=${this._handleBackdropClick}></div> <div class=\"dialog\"> ${this._contentElement} </div> `}}"
538
590
  },
539
591
  {
540
592
  "kind": "variable",
541
- "name": "qe"
593
+ "name": "Ve"
542
594
  },
543
595
  {
544
596
  "kind": "variable",
545
- "name": "Ne",
546
- "default": "class extends ne{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 N;const i=t.cloneNode(!0);return i.removeAttribute(\"slot\"),U`<span class=\"label-icon\">${i}</span>`}render(){return U` <div class=\"header\" role=\"tablist\" @keydown=${this._handleKeyDown}> ${this._getTabs().map(e=>U` <button class=${we({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?U`<span class=\"label-badge\" style=${Ue({backgroundColor:e.badgeBackground,color:e.badgeColor})}>${e.badge}</span>`:N} ${e.dismissible?U` <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> `:N} </button> `)} </div> <div class=\"content\" role=\"tabpanel\" aria-labelledby=${this.activeTabId||\"\"}> <slot @slotchange=${this._updateActiveTab}></slot> </div> `}}"
597
+ "name": "Ke",
598
+ "default": "class extends ne{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 N;const i=t.cloneNode(!0);return i.removeAttribute(\"slot\"),V`<span class=\"label-icon\">${i}</span>`}render(){return V` <div class=\"header\" role=\"tablist\" @keydown=${this._handleKeyDown}> ${this._getTabs().map(e=>V` <button class=${we({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?V`<span class=\"label-badge\" style=${Fe({backgroundColor:e.badgeBackground,color:e.badgeColor})}>${e.badge}</span>`:N} ${e.dismissible?V` <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> `:N} </button> `)} </div> <div class=\"content\" role=\"tabpanel\" aria-labelledby=${this.activeTabId||\"\"}> <slot @slotchange=${this._updateActiveTab}></slot> </div> `}}"
547
599
  },
548
600
  {
549
601
  "kind": "variable",
550
- "name": "We",
551
- "default": "class extends ne{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 U`<slot></slot>`}}"
602
+ "name": "Qe",
603
+ "default": "class extends ne{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 V`<slot></slot>`}}"
552
604
  },
553
605
  {
554
606
  "kind": "variable",
555
- "name": "Ye",
556
- "default": "class extends ne{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:Xe(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\",qe.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 U`<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 U` <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?N:U` <div class=\"header\"> <div class=\"title\">${this._def.title??\"\"}</div> ${\"db\"!==this._def.dataSource?.mode||this._def.columns.some(e=>e.searchable)?U` <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> `:U`<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=>U` <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?U` <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?U` <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> `:N} </div> </div> `}_renderStatus(){return\"loading\"===this._dataState&&0===this._data.length?U`<div class=\"status\">Loading...</div>`:\"error\"===this._dataState&&0===this._data.length?U`<div class=\"status status--error\">Error loading data</div>`:0===this._data.length?U`<div class=\"status\">No data available</div>`:N}_renderTable(){return U` <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)=>U` <div class=${we(this._getHeaderCellClasses(e,t))} style=${Ue(this._getCellStyle(e,t))} data-column-id=${e.id} >${e.label??e.id}${!1!==e.resizable?U`<div class=\"header-cell__resize\" @mousedown=${t=>this._handleResizeStart(t,e.id)} ></div>`:N}</div> `)} </div> ${this._data.map((e,t)=>U` <div class=\"row\"> ${this.getDisplayedColumns().map((i,o)=>U` <div class=${we(this._getCellClasses(i,o))} style=${Ue(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?U` ${this._renderHeader()} ${this._renderTable()} `:U`<slot></slot>`}}"
607
+ "name": "et",
608
+ "default": "class extends ne{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:Je(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\",Ve.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 V`<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 V` <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?N:V` <div class=\"header\"> <div class=\"title\">${this._def.title??\"\"}</div> ${\"db\"!==this._def.dataSource?.mode||this._def.columns.some(e=>e.searchable)?V` <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> `:V`<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=>V` <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?V` <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?V` <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> `:N} </div> </div> `}_renderStatus(){return\"loading\"===this._dataState&&0===this._data.length?V`<div class=\"status\">Loading...</div>`:\"error\"===this._dataState&&0===this._data.length?V`<div class=\"status status--error\">Error loading data</div>`:0===this._data.length?V`<div class=\"status\">No data available</div>`:N}_renderTable(){return V` <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)=>V` <div class=${we(this._getHeaderCellClasses(e,t))} style=${Fe(this._getCellStyle(e,t))} data-column-id=${e.id} >${e.label??e.id}${!1!==e.resizable?V`<div class=\"header-cell__resize\" @mousedown=${t=>this._handleResizeStart(t,e.id)} ></div>`:N}</div> `)} </div> ${this._data.map((e,t)=>V` <div class=\"row\"> ${this.getDisplayedColumns().map((i,o)=>V` <div class=${we(this._getCellClasses(i,o))} style=${Fe(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?V` ${this._renderHeader()} ${this._renderTable()} `:V`<slot></slot>`}}"
557
609
  },
558
610
  {
559
611
  "kind": "variable",
560
612
  "name": "it",
561
- "default": "class extends ne{constructor(){super(),this.label=\"\",this.name=\"\",this.value=\"\",this.placeholder=\"\",this.type=\"text\",this.required=!1,this.disabled=!1,this.readonly=!1,this.autocomplete=\"\",this.hint=\"\",this._touched=!1,this._dirty=!1,this._handleInvalid=e=>{e.preventDefault(),this._touched=!0},this._internals=this.attachInternals()}get form(){return this._internals.form}get validity(){return this._internals.validity}get validationMessage(){return this._internals.validationMessage}get willValidate(){return this._internals.willValidate}checkValidity(){return this._internals.checkValidity()}reportValidity(){return this._internals.reportValidity()}formResetCallback(){this.value=\"\",this._touched=!1,this._dirty=!1,this._internals.setFormValue(\"\"),this._internals.setValidity({})}formStateRestoreCallback(e){this.value=e}connectedCallback(){super.connectedCallback(),this.addEventListener(\"invalid\",this._handleInvalid)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(\"invalid\",this._handleInvalid)}firstUpdated(){this._updateValidity()}updated(e){(e.has(\"required\")||e.has(\"value\"))&&this._updateValidity()}_updateValidity(){this._input&&this._internals.setValidity(this._input.validity,this._input.validationMessage)}_handleInput(e){this.value=e.target.value,this._dirty=!0,this._internals.setFormValue(this.value),this._internals.setValidity(this._input.validity,this._input.validationMessage)}_handleChange(e){this.value=e.target.value,this._internals.setFormValue(this.value)}_handleBlur(){this._touched=!0,this._internals.setValidity(this._input.validity,this._input.validationMessage)}render(){let e=\"\";return this._touched&&this._input&&!this._input.validity.valid&&(e=this._input.validationMessage),U` <div class=\"wrapper\"> ${this.label?U` <label for=\"input\"> ${this.label} ${this.required?U`<span class=\"required\" aria-hidden=\"true\">*</span>`:\"\"} </label> `:\"\"} <input id=\"input\" class=${we({\"input--invalid\":this._touched&&this._input&&!this._input.validity.valid})} type=${this.type} name=${this.name} .value=${et(this.value)} placeholder=${this.placeholder} ?required=${this.required} ?disabled=${this.disabled} ?readonly=${this.readonly} minlength=${Ge(this.minlength)} maxlength=${Ge(this.maxlength)} pattern=${Ge(this.pattern)} autocomplete=${Ge(this.autocomplete||void 0)} @input=${this._handleInput} @change=${this._handleChange} @blur=${this._handleBlur} /> ${e?U`<div class=\"validation-message\">${e}</div>`:this.hint?U`<div class=\"hint\">${this.hint}</div>`:\"\"} </div> `}focus(){this._input?.focus()}blur(){this._input?.blur()}select(){this._input?.select()}}"
613
+ "default": "class extends ne{constructor(){super(...arguments),this.size=\"md\",this.color=\"dark\"}render(){var e=\"\",t=\"\";return e=\"sm\"==this.size?\"16px\":\"md\"==this.size?\"24px\":\"lg\"==this.size?\"32px\":\"xl\"==this.size?\"48px\":this.size,t=\"dark\"==this.color?\"#163052\":\"light\"==this.color?\"#ffffff\":this.color,V` <svg class=\"spinner\" style=${`width: ${e}; height: ${e}; color: ${t}`} viewBox=\"0 0 44 44\" role=\"status\" aria-label=\"Loading\" > <circle class=\"circle\" cx=\"22\" cy=\"22\" r=\"20\" fill=\"none\" stroke-width=\"4\" /> </svg> `}}"
562
614
  },
563
615
  {
564
616
  "kind": "variable",
565
617
  "name": "st",
566
- "default": "class extends ne{constructor(){super(),this.label=\"\",this.name=\"\",this.value=\"\",this.placeholder=\"Select an option\",this.disabled=!1,this.required=!1,this.readonly=!1,this.hint=\"\",this._isOpen=!1,this._highlightedIndex=-1,this._touched=!1,this._handleInvalid=e=>{e.preventDefault(),this._touched=!0},this._handleOutsideClick=e=>{e.composedPath().includes(this)||this._close()},this._handleKeyDown=e=>{if(!this._isOpen)return;const t=Array.from(this.querySelectorAll(\"kr-select-option\"));switch(e.key){case\"Escape\":this._close(),this._triggerElement?.focus();break;case\"ArrowDown\":if(e.preventDefault(),t.some(e=>!e.disabled)){let e=this._highlightedIndex+1;for(;e<t.length&&t[e]?.disabled;)e++;e<t.length&&(this._highlightedIndex=e)}break;case\"ArrowUp\":e.preventDefault();{let e=this._highlightedIndex-1;for(;e>=0&&t[e]?.disabled;)e--;e>=0&&(this._highlightedIndex=e)}break;case\"Enter\":e.preventDefault(),this._highlightedIndex>=0&&this._highlightedIndex<t.length&&this._selectOption(t[this._highlightedIndex])}},this._internals=this.attachInternals()}get form(){return this._internals.form}get validity(){return this._internals.validity}get validationMessage(){return this._internals.validationMessage}get willValidate(){return this._internals.willValidate}checkValidity(){return this._internals.checkValidity()}reportValidity(){return this._internals.reportValidity()}formResetCallback(){this.value=\"\",this._touched=!1,this._internals.setFormValue(\"\"),this._internals.setValidity({})}formStateRestoreCallback(e){this.value=e}connectedCallback(){super.connectedCallback(),document.addEventListener(\"click\",this._handleOutsideClick),document.addEventListener(\"keydown\",this._handleKeyDown),this.addEventListener(\"invalid\",this._handleInvalid)}firstUpdated(){this._updateValidity()}updated(e){(e.has(\"required\")||e.has(\"value\"))&&this._updateValidity()}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(\"click\",this._handleOutsideClick),document.removeEventListener(\"keydown\",this._handleKeyDown),this.removeEventListener(\"invalid\",this._handleInvalid)}_toggle(){if(!this.disabled&&!this.readonly)if(this._isOpen)this._close();else{this._isOpen=!0;const e=Array.from(this.querySelectorAll(\"kr-select-option\"));this._highlightedIndex=e.findIndex(e=>e.value===this.value)}}_close(){this._isOpen=!1,this._highlightedIndex=-1}_selectOption(e){e.disabled||(this.value=e.value,this._internals.setFormValue(this.value),this._updateValidity(),this.dispatchEvent(new Event(\"change\",{bubbles:!0,composed:!0})),this._close(),this._triggerElement?.focus())}_handleBlur(){this._touched=!0,this._updateValidity()}_updateValidity(){this.required&&!this.value?this._internals.setValidity({valueMissing:!0},\"Please select an option\",this._triggerElement):this._internals.setValidity({})}render(){const e=Array.from(this.querySelectorAll(\"kr-select-option\")),t=e.find(e=>e.value===this.value)?.label;return U` <div class=\"wrapper\"> ${this.label?U` <label> ${this.label} ${this.required?U`<span class=\"required\" aria-hidden=\"true\">*</span>`:\"\"} </label> `:N} <div class=\"select-wrapper\"> <button class=${we({\"select-trigger\":!0,\"select-trigger--open\":this._isOpen,\"select-trigger--invalid\":this._touched&&this.required&&!this.value})} type=\"button\" ?disabled=${this.disabled} aria-haspopup=\"listbox\" aria-expanded=${this._isOpen} @click=${this._toggle} @blur=${this._handleBlur} > <span class=${we({\"select-value\":!0,\"select-placeholder\":!t})}> ${t||this.placeholder} </span> <svg class=${we({\"chevron-icon\":!0,\"select-icon\":!0,\"select-icon--open\":this._isOpen})} viewBox=\"0 0 20 20\" fill=\"currentColor\" > <path fill-rule=\"evenodd\" d=\"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z\" clip-rule=\"evenodd\" /> </svg> </button> <div class=${we({\"select-dropdown\":!0,hidden:!this._isOpen})} role=\"listbox\"> <div class=\"select-options\"> ${0===e.length?U`<div class=\"select-empty\">No options available</div>`:e.map((e,t)=>{const i=e.value===this.value;return U` <div class=${we({\"select-option\":!0,\"select-option--selected\":i,\"select-option--disabled\":e.disabled,\"select-option--highlighted\":t===this._highlightedIndex})} role=\"option\" aria-selected=${i} @click=${()=>this._selectOption(e)} @mouseenter=${()=>this._highlightedIndex=t} > ${e.label} ${i?U`<svg class=\"chevron-icon select-check\" viewBox=\"0 0 20 20\" fill=\"currentColor\"> <path fill-rule=\"evenodd\" d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\" clip-rule=\"evenodd\" /> </svg>`:N} </div> `})} </div> </div> </div> ${this._touched&&this.required&&!this.value?U`<div class=\"validation-message\">Please select an option</div>`:this.hint?U`<div class=\"hint\">${this.hint}</div>`:\"\"} </div> <div class=\"options-slot\"> <slot @slotchange=${()=>this.requestUpdate()}></slot> </div> `}focus(){this._triggerElement?.focus()}blur(){this._triggerElement?.blur()}}"
618
+ "default": "class extends ne{constructor(){super(...arguments),this.color=\"dark\"}render(){let e=\"\",t=\"\";return e=\"dark\"===this.color?\"#163052\":\"light\"===this.color?\"#ffffff\":this.color,t=this.trackColor?this.trackColor:\"light\"===this.color?\"#ffffff4d\":\"#0000001a\",V` <div class=\"progress-bar\" style=${`background: ${t}`} role=\"status\" aria-label=\"Loading\" > <div class=\"fill\" style=${`background: ${e}`}></div> </div> `}}"
619
+ },
620
+ {
621
+ "kind": "variable",
622
+ "name": "dt",
623
+ "default": "class extends ne{constructor(){super(),this.label=\"\",this.name=\"\",this.value=\"\",this.placeholder=\"\",this.type=\"text\",this.required=!1,this.disabled=!1,this.readonly=!1,this.autocomplete=\"\",this.hint=\"\",this._touched=!1,this._dirty=!1,this._handleInvalid=e=>{e.preventDefault(),this._touched=!0},this._internals=this.attachInternals()}get form(){return this._internals.form}get validity(){return this._internals.validity}get validationMessage(){return this._internals.validationMessage}get willValidate(){return this._internals.willValidate}checkValidity(){return this._internals.checkValidity()}reportValidity(){return this._internals.reportValidity()}formResetCallback(){this.value=\"\",this._touched=!1,this._dirty=!1,this._internals.setFormValue(\"\"),this._internals.setValidity({})}formStateRestoreCallback(e){this.value=e}connectedCallback(){super.connectedCallback(),this.addEventListener(\"invalid\",this._handleInvalid)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(\"invalid\",this._handleInvalid)}firstUpdated(){this._updateValidity()}updated(e){(e.has(\"required\")||e.has(\"value\"))&&this._updateValidity()}_updateValidity(){this._input&&this._internals.setValidity(this._input.validity,this._input.validationMessage)}_handleInput(e){this.value=e.target.value,this._dirty=!0,this._internals.setFormValue(this.value),this._internals.setValidity(this._input.validity,this._input.validationMessage)}_handleChange(e){this.value=e.target.value,this._internals.setFormValue(this.value)}_handleBlur(){this._touched=!0,this._internals.setValidity(this._input.validity,this._input.validationMessage)}render(){let e=\"\";return this._touched&&this._input&&!this._input.validity.valid&&(e=this._input.validationMessage),V` <div class=\"wrapper\"> ${this.label?V` <label for=\"input\"> ${this.label} ${this.required?V`<span class=\"required\" aria-hidden=\"true\">*</span>`:\"\"} </label> `:\"\"} <input id=\"input\" class=${we({\"input--invalid\":this._touched&&this._input&&!this._input.validity.valid})} type=${this.type} name=${this.name} .value=${lt(this.value)} placeholder=${this.placeholder} ?required=${this.required} ?disabled=${this.disabled} ?readonly=${this.readonly} minlength=${rt(this.minlength)} maxlength=${rt(this.maxlength)} pattern=${rt(this.pattern)} autocomplete=${rt(this.autocomplete||void 0)} @input=${this._handleInput} @change=${this._handleChange} @blur=${this._handleBlur} /> ${e?V`<div class=\"validation-message\">${e}</div>`:this.hint?V`<div class=\"hint\">${this.hint}</div>`:\"\"} </div> `}focus(){this._input?.focus()}blur(){this._input?.blur()}select(){this._input?.select()}}"
567
624
  },
568
625
  {
569
626
  "kind": "variable",
570
- "name": "nt",
571
- "default": "class extends ne{constructor(){super(...arguments),this.value=\"\",this.disabled=!1}get label(){return this.textContent?.trim()||\"\"}render(){return U`<slot></slot>`}}"
627
+ "name": "ht",
628
+ "default": "class extends ne{constructor(){super(),this.label=\"\",this.name=\"\",this.value=\"\",this.placeholder=\"Select an option\",this.disabled=!1,this.required=!1,this.readonly=!1,this.hint=\"\",this._isOpen=!1,this._highlightedIndex=-1,this._touched=!1,this._handleInvalid=e=>{e.preventDefault(),this._touched=!0},this._handleOutsideClick=e=>{e.composedPath().includes(this)||this._close()},this._handleKeyDown=e=>{if(!this._isOpen)return;const t=Array.from(this.querySelectorAll(\"kr-select-option\"));switch(e.key){case\"Escape\":this._close(),this._triggerElement?.focus();break;case\"ArrowDown\":if(e.preventDefault(),t.some(e=>!e.disabled)){let e=this._highlightedIndex+1;for(;e<t.length&&t[e]?.disabled;)e++;e<t.length&&(this._highlightedIndex=e)}break;case\"ArrowUp\":e.preventDefault();{let e=this._highlightedIndex-1;for(;e>=0&&t[e]?.disabled;)e--;e>=0&&(this._highlightedIndex=e)}break;case\"Enter\":e.preventDefault(),this._highlightedIndex>=0&&this._highlightedIndex<t.length&&this._selectOption(t[this._highlightedIndex])}},this._internals=this.attachInternals()}get form(){return this._internals.form}get validity(){return this._internals.validity}get validationMessage(){return this._internals.validationMessage}get willValidate(){return this._internals.willValidate}checkValidity(){return this._internals.checkValidity()}reportValidity(){return this._internals.reportValidity()}formResetCallback(){this.value=\"\",this._touched=!1,this._internals.setFormValue(\"\"),this._internals.setValidity({})}formStateRestoreCallback(e){this.value=e}connectedCallback(){super.connectedCallback(),document.addEventListener(\"click\",this._handleOutsideClick),document.addEventListener(\"keydown\",this._handleKeyDown),this.addEventListener(\"invalid\",this._handleInvalid)}firstUpdated(){this._updateValidity()}updated(e){(e.has(\"required\")||e.has(\"value\"))&&this._updateValidity()}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener(\"click\",this._handleOutsideClick),document.removeEventListener(\"keydown\",this._handleKeyDown),this.removeEventListener(\"invalid\",this._handleInvalid)}_toggle(){if(!this.disabled&&!this.readonly)if(this._isOpen)this._close();else{this._isOpen=!0;const e=Array.from(this.querySelectorAll(\"kr-select-option\"));this._highlightedIndex=e.findIndex(e=>e.value===this.value),requestAnimationFrame(()=>{const e=this.shadowRoot?.querySelector(\".select-dropdown\");if(e){const t=this._triggerElement.getBoundingClientRect();e.style.top=t.bottom+4+\"px\",e.style.left=t.left+\"px\",e.style.width=t.width+\"px\"}})}}_close(){this._isOpen=!1,this._highlightedIndex=-1}_selectOption(e){e.disabled||(this.value=e.value,this._internals.setFormValue(this.value),this._updateValidity(),this.dispatchEvent(new Event(\"change\",{bubbles:!0,composed:!0})),this._close(),this._triggerElement?.focus())}_handleBlur(){this._touched=!0,this._updateValidity()}_updateValidity(){this.required&&!this.value?this._internals.setValidity({valueMissing:!0},\"Please select an option\",this._triggerElement):this._internals.setValidity({})}render(){const e=Array.from(this.querySelectorAll(\"kr-select-option\")),t=e.find(e=>e.value===this.value)?.label;return V` <div class=\"wrapper\"> ${this.label?V` <label> ${this.label} ${this.required?V`<span class=\"required\" aria-hidden=\"true\">*</span>`:\"\"} </label> `:N} <div class=\"select-wrapper\"> <button class=${we({\"select-trigger\":!0,\"select-trigger--open\":this._isOpen,\"select-trigger--invalid\":this._touched&&this.required&&!this.value})} type=\"button\" ?disabled=${this.disabled} aria-haspopup=\"listbox\" aria-expanded=${this._isOpen} @click=${this._toggle} @blur=${this._handleBlur} > <span class=${we({\"select-value\":!0,\"select-placeholder\":!t})}> ${t||this.placeholder} </span> <svg class=${we({\"chevron-icon\":!0,\"select-icon\":!0,\"select-icon--open\":this._isOpen})} viewBox=\"0 0 24 24\" fill=\"currentColor\" > <path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6z\"/> </svg> </button> <div class=${we({\"select-dropdown\":!0,hidden:!this._isOpen})} role=\"listbox\"> <div class=\"select-options\"> ${0===e.length?V`<div class=\"select-empty\">No options available</div>`:e.map((e,t)=>{const i=e.value===this.value;return V` <div class=${we({\"select-option\":!0,\"select-option--selected\":i,\"select-option--disabled\":e.disabled,\"select-option--highlighted\":t===this._highlightedIndex})} role=\"option\" aria-selected=${i} @click=${()=>this._selectOption(e)} @mouseenter=${()=>this._highlightedIndex=t} > ${e.label} ${i?V`<svg class=\"chevron-icon select-check\" viewBox=\"0 0 20 20\" fill=\"currentColor\"> <path fill-rule=\"evenodd\" d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\" clip-rule=\"evenodd\" /> </svg>`:N} </div> `})} </div> </div> </div> ${this._touched&&this.required&&!this.value?V`<div class=\"validation-message\">Please select an option</div>`:this.hint?V`<div class=\"hint\">${this.hint}</div>`:\"\"} </div> <div class=\"options-slot\"> <slot @slotchange=${()=>this.requestUpdate()}></slot> </div> `}focus(){this._triggerElement?.focus()}blur(){this._triggerElement?.blur()}}"
572
629
  },
573
630
  {
574
631
  "kind": "variable",
575
- "name": "lt",
576
- "default": "class extends ne{constructor(){super(),this.label=\"\",this.name=\"\",this.value=\"\",this.placeholder=\"\",this.required=!1,this.disabled=!1,this.readonly=!1,this.rows=3,this.autocomplete=\"\",this.hint=\"\",this._touched=!1,this._dirty=!1,this._handleInvalid=e=>{e.preventDefault(),this._touched=!0},this._internals=this.attachInternals()}get form(){return this._internals.form}get validity(){return this._internals.validity}get validationMessage(){return this._internals.validationMessage}get willValidate(){return this._internals.willValidate}checkValidity(){return this._internals.checkValidity()}reportValidity(){return this._internals.reportValidity()}formResetCallback(){this.value=\"\",this._touched=!1,this._dirty=!1,this._internals.setFormValue(\"\"),this._internals.setValidity({})}formStateRestoreCallback(e){this.value=e}connectedCallback(){super.connectedCallback(),this.addEventListener(\"invalid\",this._handleInvalid)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(\"invalid\",this._handleInvalid)}firstUpdated(){this._updateValidity()}updated(e){(e.has(\"required\")||e.has(\"value\"))&&this._updateValidity()}_updateValidity(){this._textarea&&this._internals.setValidity(this._textarea.validity,this._textarea.validationMessage)}_handleInput(e){this.value=e.target.value,this._dirty=!0,this._internals.setFormValue(this.value),this._internals.setValidity(this._textarea.validity,this._textarea.validationMessage)}_handleChange(e){this.value=e.target.value,this._internals.setFormValue(this.value)}_handleBlur(){this._touched=!0,this._internals.setValidity(this._textarea.validity,this._textarea.validationMessage)}render(){let e=\"\";return this._touched&&this._textarea&&!this._textarea.validity.valid&&(e=this._textarea.validationMessage),U` <div class=\"wrapper\"> ${this.label?U` <label for=\"textarea\"> ${this.label} ${this.required?U`<span class=\"required\" aria-hidden=\"true\">*</span>`:N} </label> `:N} <textarea id=\"textarea\" class=${we({\"textarea--invalid\":this._touched&&this._textarea&&!this._textarea.validity.valid})} name=${this.name} .value=${et(this.value)} placeholder=${this.placeholder} ?required=${this.required} ?disabled=${this.disabled} ?readonly=${this.readonly} rows=${this.rows} cols=${Ge(this.cols)} minlength=${Ge(this.minlength)} maxlength=${Ge(this.maxlength)} autocomplete=${Ge(this.autocomplete||void 0)} @input=${this._handleInput} @change=${this._handleChange} @blur=${this._handleBlur} ></textarea> ${e?U`<div class=\"validation-message\">${e}</div>`:this.hint?U`<div class=\"hint\">${this.hint}</div>`:N} </div> `}focus(){this._textarea?.focus()}blur(){this._textarea?.blur()}select(){this._textarea?.select()}}"
632
+ "name": "ut",
633
+ "default": "class extends ne{constructor(){super(...arguments),this.value=\"\",this.disabled=!1}get label(){return this.textContent?.trim()||\"\"}render(){return V`<slot></slot>`}}"
634
+ },
635
+ {
636
+ "kind": "variable",
637
+ "name": "gt",
638
+ "default": "class extends ne{constructor(){super(),this.label=\"\",this.name=\"\",this.value=\"\",this.placeholder=\"\",this.required=!1,this.disabled=!1,this.readonly=!1,this.rows=3,this.autocomplete=\"\",this.hint=\"\",this._touched=!1,this._dirty=!1,this._handleInvalid=e=>{e.preventDefault(),this._touched=!0},this._internals=this.attachInternals()}get form(){return this._internals.form}get validity(){return this._internals.validity}get validationMessage(){return this._internals.validationMessage}get willValidate(){return this._internals.willValidate}checkValidity(){return this._internals.checkValidity()}reportValidity(){return this._internals.reportValidity()}formResetCallback(){this.value=\"\",this._touched=!1,this._dirty=!1,this._internals.setFormValue(\"\"),this._internals.setValidity({})}formStateRestoreCallback(e){this.value=e}connectedCallback(){super.connectedCallback(),this.addEventListener(\"invalid\",this._handleInvalid)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener(\"invalid\",this._handleInvalid)}firstUpdated(){this._updateValidity()}updated(e){(e.has(\"required\")||e.has(\"value\"))&&this._updateValidity()}_updateValidity(){this._textarea&&this._internals.setValidity(this._textarea.validity,this._textarea.validationMessage)}_handleInput(e){this.value=e.target.value,this._dirty=!0,this._internals.setFormValue(this.value),this._internals.setValidity(this._textarea.validity,this._textarea.validationMessage)}_handleChange(e){this.value=e.target.value,this._internals.setFormValue(this.value)}_handleBlur(){this._touched=!0,this._internals.setValidity(this._textarea.validity,this._textarea.validationMessage)}render(){let e=\"\";return this._touched&&this._textarea&&!this._textarea.validity.valid&&(e=this._textarea.validationMessage),V` <div class=\"wrapper\"> ${this.label?V` <label for=\"textarea\"> ${this.label} ${this.required?V`<span class=\"required\" aria-hidden=\"true\">*</span>`:N} </label> `:N} <textarea id=\"textarea\" class=${we({\"textarea--invalid\":this._touched&&this._textarea&&!this._textarea.validity.valid})} name=${this.name} .value=${lt(this.value)} placeholder=${this.placeholder} ?required=${this.required} ?disabled=${this.disabled} ?readonly=${this.readonly} rows=${this.rows} cols=${rt(this.cols)} minlength=${rt(this.minlength)} maxlength=${rt(this.maxlength)} autocomplete=${rt(this.autocomplete||void 0)} @input=${this._handleInput} @change=${this._handleChange} @blur=${this._handleBlur} ></textarea> ${e?V`<div class=\"validation-message\">${e}</div>`:this.hint?V`<div class=\"hint\">${this.hint}</div>`:N} </div> `}focus(){this._textarea?.focus()}blur(){this._textarea?.blur()}select(){this._textarea?.select()}}"
577
639
  }
578
640
  ],
579
641
  "exports": [
@@ -582,7 +644,7 @@
582
644
  "name": "e",
583
645
  "declaration": {
584
646
  "name": "t",
585
- "module": "dist/krubble.bundled.min.js"
647
+ "module": "dist/krubble-components.bundled.min.js"
586
648
  }
587
649
  },
588
650
  {
@@ -590,15 +652,7 @@
590
652
  "name": "e",
591
653
  "declaration": {
592
654
  "name": "t",
593
- "module": "dist/krubble.bundled.min.js"
594
- }
595
- },
596
- {
597
- "kind": "js",
598
- "name": "DialogRef",
599
- "declaration": {
600
- "name": "Me",
601
- "module": "dist/krubble.bundled.min.js"
655
+ "module": "dist/krubble-components.bundled.min.js"
602
656
  }
603
657
  },
604
658
  {
@@ -606,7 +660,7 @@
606
660
  "name": "KRAccordion",
607
661
  "declaration": {
608
662
  "name": "be",
609
- "module": "dist/krubble.bundled.min.js"
663
+ "module": "dist/krubble-components.bundled.min.js"
610
664
  }
611
665
  },
612
666
  {
@@ -614,7 +668,7 @@
614
668
  "name": "KRAlert",
615
669
  "declaration": {
616
670
  "name": "Ce",
617
- "module": "dist/krubble.bundled.min.js"
671
+ "module": "dist/krubble-components.bundled.min.js"
618
672
  }
619
673
  },
620
674
  {
@@ -622,7 +676,7 @@
622
676
  "name": "KRButton",
623
677
  "declaration": {
624
678
  "name": "Ee",
625
- "module": "dist/krubble.bundled.min.js"
679
+ "module": "dist/krubble-components.bundled.min.js"
626
680
  }
627
681
  },
628
682
  {
@@ -630,7 +684,7 @@
630
684
  "name": "KRCodeDemo",
631
685
  "declaration": {
632
686
  "name": "Pe",
633
- "module": "dist/krubble.bundled.min.js"
687
+ "module": "dist/krubble-components.bundled.min.js"
634
688
  }
635
689
  },
636
690
  {
@@ -638,94 +692,118 @@
638
692
  "name": "KRContextMenu",
639
693
  "declaration": {
640
694
  "name": "Le",
641
- "module": "dist/krubble.bundled.min.js"
695
+ "module": "dist/krubble-components.bundled.min.js"
642
696
  }
643
697
  },
644
698
  {
645
699
  "kind": "js",
646
700
  "name": "KRDialog",
647
701
  "declaration": {
648
- "name": "je",
649
- "module": "dist/krubble.bundled.min.js"
702
+ "name": "Ie",
703
+ "module": "dist/krubble-components.bundled.min.js"
650
704
  }
651
705
  },
652
706
  {
653
707
  "kind": "js",
654
- "name": "KRSelectField",
708
+ "name": "KRDialogRef",
709
+ "declaration": {
710
+ "name": "qe",
711
+ "module": "dist/krubble-components.bundled.min.js"
712
+ }
713
+ },
714
+ {
715
+ "kind": "js",
716
+ "name": "KRProgressBar",
655
717
  "declaration": {
656
718
  "name": "st",
657
- "module": "dist/krubble.bundled.min.js"
719
+ "module": "dist/krubble-components.bundled.min.js"
720
+ }
721
+ },
722
+ {
723
+ "kind": "js",
724
+ "name": "KRSelectField",
725
+ "declaration": {
726
+ "name": "ht",
727
+ "module": "dist/krubble-components.bundled.min.js"
658
728
  }
659
729
  },
660
730
  {
661
731
  "kind": "js",
662
732
  "name": "KRSelectOption",
663
733
  "declaration": {
664
- "name": "nt",
665
- "module": "dist/krubble.bundled.min.js"
734
+ "name": "ut",
735
+ "module": "dist/krubble-components.bundled.min.js"
666
736
  }
667
737
  },
668
738
  {
669
739
  "kind": "js",
670
740
  "name": "KRSnackbar",
671
741
  "declaration": {
672
- "name": "qe",
673
- "module": "dist/krubble.bundled.min.js"
742
+ "name": "Ve",
743
+ "module": "dist/krubble-components.bundled.min.js"
744
+ }
745
+ },
746
+ {
747
+ "kind": "js",
748
+ "name": "KRSpinner",
749
+ "declaration": {
750
+ "name": "it",
751
+ "module": "dist/krubble-components.bundled.min.js"
674
752
  }
675
753
  },
676
754
  {
677
755
  "kind": "js",
678
756
  "name": "KRTab",
679
757
  "declaration": {
680
- "name": "We",
681
- "module": "dist/krubble.bundled.min.js"
758
+ "name": "Qe",
759
+ "module": "dist/krubble-components.bundled.min.js"
682
760
  }
683
761
  },
684
762
  {
685
763
  "kind": "js",
686
764
  "name": "KRTabGroup",
687
765
  "declaration": {
688
- "name": "Ne",
689
- "module": "dist/krubble.bundled.min.js"
766
+ "name": "Ke",
767
+ "module": "dist/krubble-components.bundled.min.js"
690
768
  }
691
769
  },
692
770
  {
693
771
  "kind": "js",
694
772
  "name": "KRTable",
695
773
  "declaration": {
696
- "name": "Ye",
697
- "module": "dist/krubble.bundled.min.js"
774
+ "name": "et",
775
+ "module": "dist/krubble-components.bundled.min.js"
698
776
  }
699
777
  },
700
778
  {
701
779
  "kind": "js",
702
780
  "name": "KRTextField",
703
781
  "declaration": {
704
- "name": "it",
705
- "module": "dist/krubble.bundled.min.js"
782
+ "name": "dt",
783
+ "module": "dist/krubble-components.bundled.min.js"
706
784
  }
707
785
  },
708
786
  {
709
787
  "kind": "js",
710
788
  "name": "KRTextareaField",
711
789
  "declaration": {
712
- "name": "lt",
713
- "module": "dist/krubble.bundled.min.js"
790
+ "name": "gt",
791
+ "module": "dist/krubble-components.bundled.min.js"
714
792
  }
715
793
  },
716
794
  {
717
795
  "kind": "js",
718
796
  "name": "krBaseCSS",
719
797
  "declaration": {
720
- "name": "le",
721
- "module": "dist/krubble.bundled.min.js"
798
+ "name": "ae",
799
+ "module": "dist/krubble-components.bundled.min.js"
722
800
  }
723
801
  }
724
802
  ]
725
803
  },
726
804
  {
727
805
  "kind": "javascript-module",
728
- "path": "dist/krubble.umd.js",
806
+ "path": "dist/krubble-components.umd.js",
729
807
  "declarations": [
730
808
  {
731
809
  "kind": "variable",
@@ -742,7 +820,7 @@
742
820
  "members": [],
743
821
  "superclass": {
744
822
  "name": "i$1",
745
- "module": "dist/krubble.umd.js"
823
+ "module": "dist/krubble-components.umd.js"
746
824
  },
747
825
  "tagName": "t",
748
826
  "customElement": true
@@ -754,7 +832,7 @@
754
832
  "name": "t",
755
833
  "declaration": {
756
834
  "name": "e",
757
- "module": "dist/krubble.umd.js"
835
+ "module": "dist/krubble-components.umd.js"
758
836
  }
759
837
  },
760
838
  {
@@ -762,14 +840,14 @@
762
840
  "name": "t",
763
841
  "declaration": {
764
842
  "name": "e",
765
- "module": "dist/krubble.umd.js"
843
+ "module": "dist/krubble-components.umd.js"
766
844
  }
767
845
  }
768
846
  ]
769
847
  },
770
848
  {
771
849
  "kind": "javascript-module",
772
- "path": "dist/krubble.umd.min.js",
850
+ "path": "dist/krubble-components.umd.min.js",
773
851
  "declarations": [
774
852
  {
775
853
  "kind": "variable",
@@ -787,7 +865,7 @@
787
865
  "name": "e",
788
866
  "declaration": {
789
867
  "name": "t",
790
- "module": "dist/krubble.umd.min.js"
868
+ "module": "dist/krubble-components.umd.min.js"
791
869
  }
792
870
  },
793
871
  {
@@ -795,7 +873,7 @@
795
873
  "name": "e",
796
874
  "declaration": {
797
875
  "name": "t",
798
- "module": "dist/krubble.umd.min.js"
876
+ "module": "dist/krubble-components.umd.min.js"
799
877
  }
800
878
  }
801
879
  ]
@@ -871,9 +949,9 @@
871
949
  },
872
950
  {
873
951
  "kind": "js",
874
- "name": "DialogRef",
952
+ "name": "KRDialogRef",
875
953
  "declaration": {
876
- "name": "DialogRef",
954
+ "name": "KRDialogRef",
877
955
  "module": "./dialog/dialog.js"
878
956
  }
879
957
  },
@@ -941,6 +1019,22 @@
941
1019
  "module": "./table/table.js"
942
1020
  }
943
1021
  },
1022
+ {
1023
+ "kind": "js",
1024
+ "name": "KRSpinner",
1025
+ "declaration": {
1026
+ "name": "KRSpinner",
1027
+ "module": "./spinner/spinner.js"
1028
+ }
1029
+ },
1030
+ {
1031
+ "kind": "js",
1032
+ "name": "KRProgressBar",
1033
+ "declaration": {
1034
+ "name": "KRProgressBar",
1035
+ "module": "./progress-bar/progress-bar.js"
1036
+ }
1037
+ },
944
1038
  {
945
1039
  "kind": "js",
946
1040
  "name": "KRTextField",
@@ -991,9 +1085,9 @@
991
1085
  },
992
1086
  {
993
1087
  "kind": "js",
994
- "name": "DialogConfig",
1088
+ "name": "KRDialogConfig",
995
1089
  "declaration": {
996
- "name": "DialogConfig",
1090
+ "name": "KRDialogConfig",
997
1091
  "module": "./dialog/dialog.js"
998
1092
  }
999
1093
  },
@@ -1036,7 +1130,7 @@
1036
1130
  {
1037
1131
  "kind": "variable",
1038
1132
  "name": "KRAlert",
1039
- "default": "class KRAlert extends LitElement { constructor() { super(...arguments); /** * The alert type/severity */ this.type = 'info'; /** * Whether the alert can be dismissed */ this.dismissible = false; /** * Whether the alert is visible */ this.visible = true; } /** Handles dismiss button click */ _handleDismiss() { this.visible = false; this.dispatchEvent(new CustomEvent('dismiss', { bubbles: true, composed: true })); } render() { const icons = { info: html `<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z\" clip-rule=\"evenodd\"/></svg>`, success: html `<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\" clip-rule=\"evenodd\"/></svg>`, warning: html `<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\" clip-rule=\"evenodd\"/></svg>`, error: html `<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\" clip-rule=\"evenodd\"/></svg>`, }; return html ` <div class=${classMap({ 'alert': true, ['alert--' + this.type]: true, 'alert--hidden': !this.visible })} role=\"alert\" > ${icons[this.type]} <div class=\"content\"> ${this.header ? html `<h4 class=\"header\">${this.header}</h4>` : nothing} <div class=\"message\"> <slot></slot> </div> </div> ${this.dismissible ? html ` <button class=\"dismiss\" type=\"button\" aria-label=\"Dismiss alert\" @click=${this._handleDismiss} > <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"16\" height=\"16\"> <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} </div> `; } }",
1133
+ "default": "class KRAlert extends LitElement { constructor() { super(...arguments); /** * The alert type/severity */ this.type = 'info'; /** * Optional title text */ this.title = ''; /** * Whether the alert can be dismissed */ this.dismissible = false; /** * Whether the alert is visible */ this.visible = true; } /** Handles dismiss button click */ _handleDismiss() { this.visible = false; this.dispatchEvent(new CustomEvent('dismiss', { bubbles: true, composed: true })); } render() { const icons = { info: html `<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z\" clip-rule=\"evenodd\"/></svg>`, success: html `<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\" clip-rule=\"evenodd\"/></svg>`, warning: html `<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\" clip-rule=\"evenodd\"/></svg>`, error: html `<svg class=\"icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z\" clip-rule=\"evenodd\"/></svg>`, }; return html ` <div class=${classMap({ 'alert': true, ['alert--' + this.type]: true, 'alert--has-header': !!this.title, 'alert--hidden': !this.visible })} role=\"alert\" > ${icons[this.type]} <div class=\"content\"> ${this.title ? html `<h4 class=\"header\">${this.title}</h4>` : nothing} <div class=\"message\"> <slot></slot> </div> </div> ${this.dismissible ? html ` <button class=\"dismiss\" type=\"button\" aria-label=\"Dismiss alert\" @click=${this._handleDismiss} > <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"16\" height=\"16\"> <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} </div> `; } }",
1040
1134
  "description": "A customizable alert component for displaying important information to users."
1041
1135
  }
1042
1136
  ],
@@ -1058,7 +1152,7 @@
1058
1152
  {
1059
1153
  "kind": "variable",
1060
1154
  "name": "KRButton",
1061
- "default": "class KRButton extends LitElement { constructor() { super(...arguments); /** * The button variant (shape) */ this.variant = 'flat'; /** * The button color */ this.color = 'primary'; /** * The button size */ this.size = 'medium'; /** * Whether the button is disabled */ this.disabled = false; /** * Dropdown options - when provided, button becomes a dropdown */ this.options = []; this._state = 'idle'; this._stateText = ''; this._dropdownOpened = false; this._dropdownAlignRight = false; this._handleHostClick = (e) => { if (this.options.length) { e.stopPropagation(); this._toggleDropdown(); } }; this._handleKeydown = (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); if (this.options.length) { this._toggleDropdown(); } else { this.click(); } } if (e.key === 'Escape' && this._dropdownOpened) { this._dropdownOpened = false; } }; this._handleClickOutside = (e) => { if (this._dropdownOpened && !this.contains(e.target)) { this._dropdownOpened = false; } }; } connectedCallback() { super.connectedCallback(); this.setAttribute('role', this.href ? 'link' : 'button'); this.setAttribute('tabindex', '0'); this.addEventListener('keydown', this._handleKeydown); this.addEventListener('click', this._handleHostClick); document.addEventListener('click', this._handleClickOutside); } disconnectedCallback() { super.disconnectedCallback(); this.removeEventListener('keydown', this._handleKeydown); this.removeEventListener('click', this._handleHostClick); document.removeEventListener('click', this._handleClickOutside); } _toggleDropdown() { this._dropdownOpened = !this._dropdownOpened; if (this._dropdownOpened) { // Check if dropdown would overflow viewport after render requestAnimationFrame(() => { const dropdown = this.shadowRoot?.querySelector('.dropdown'); if (dropdown) { const rect = dropdown.getBoundingClientRect(); this._dropdownAlignRight = rect.right > window.innerWidth; } }); } } _handleOptionClick(option, e) { e.stopPropagation(); this._dropdownOpened = false; this.dispatchEvent(new CustomEvent('option-select', { detail: { id: option.id, label: option.label }, bubbles: true, composed: true })); } /** * Shows a loading spinner and disables the button. */ showLoading() { this._clearStateTimeout(); this._state = 'loading'; this._stateText = ''; } /** * Shows a success state with optional custom text. * @param text - Text to display (default: \"Saved\") * @param duration - Duration in ms before auto-reset (default: 2000) */ showSuccess(text = 'Success', duration = 2000) { this._clearStateTimeout(); this._state = 'success'; this._stateText = text; this._stateTimeout = window.setTimeout(() => this.reset(), duration); } /** * Shows an error state with optional custom text. * @param text - Text to display (default: \"Error\") * @param duration - Duration in ms before auto-reset (default: 2000) */ showError(text = 'Error', duration = 2000) { this._clearStateTimeout(); this._state = 'error'; this._stateText = text; this._stateTimeout = window.setTimeout(() => this.reset(), duration); } /** * Resets the button to its idle state. */ reset() { this._clearStateTimeout(); this._state = 'idle'; this._stateText = ''; } _clearStateTimeout() { if (this._stateTimeout) { clearTimeout(this._stateTimeout); this._stateTimeout = undefined; } } updated(changedProperties) { // Reflect state classes to host this.classList.toggle('kr-button--loading', this._state === 'loading'); this.classList.toggle('kr-button--success', this._state === 'success'); this.classList.toggle('kr-button--error', this._state === 'error'); this.classList.toggle(`kr-button--${this.variant}`, true); this.classList.toggle(`kr-button--${this.color}`, true); this.classList.toggle('kr-button--small', this.size === 'small'); this.classList.toggle('kr-button--large', this.size === 'large'); } render() { const content = html ` <slot></slot> ${this.options.length ? html `<svg class=\"caret\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20\" width=\"20\" 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>` : nothing} ${this._state !== 'idle' ? html `<span class=\"state-overlay\"> ${this._state === 'loading' ? html `<span class=\"spinner\"></span>` : this._stateText} </span>` : nothing} ${this.options.length ? html ` <div class=\"dropdown ${this._dropdownOpened ? 'dropdown--opened' : ''} ${this._dropdownAlignRight ? 'dropdown--align-right' : ''}\"> ${this.options.map(option => html ` <button class=\"dropdown-item\" @click=${(e) => this._handleOptionClick(option, e)} >${option.label}</button> `)} </div> ` : nothing} `; return this.href ? html `<a class=\"link\" href=${this.href} target=${this.target || nothing}>${content}</a>` : content; } }",
1155
+ "default": "class KRButton extends LitElement { constructor() { super(...arguments); /** * The button variant (shape) */ this.variant = 'flat'; /** * The button color */ this.color = 'primary'; /** * The button size */ this.size = 'medium'; /** * Whether the button is disabled */ this.disabled = false; /** * Dropdown options - when provided, button becomes a dropdown */ this.options = []; this._state = 'idle'; this._stateText = ''; this._dropdownOpened = false; this._handleHostClick = (e) => { if (this.options.length) { e.stopPropagation(); this._toggleDropdown(); } }; this._handleKeydown = (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); if (this.options.length) { this._toggleDropdown(); } else { this.click(); } } if (e.key === 'Escape' && this._dropdownOpened) { this._dropdownOpened = false; } }; this._handleClickOutside = (e) => { if (this._dropdownOpened && !this.contains(e.target)) { this._dropdownOpened = false; } }; } connectedCallback() { super.connectedCallback(); this.setAttribute('role', this.href ? 'link' : 'button'); this.setAttribute('tabindex', '0'); this.addEventListener('keydown', this._handleKeydown); this.addEventListener('click', this._handleHostClick); document.addEventListener('click', this._handleClickOutside); } disconnectedCallback() { super.disconnectedCallback(); this.removeEventListener('keydown', this._handleKeydown); this.removeEventListener('click', this._handleHostClick); document.removeEventListener('click', this._handleClickOutside); } _toggleDropdown() { this._dropdownOpened = !this._dropdownOpened; if (this._dropdownOpened) { // Position the fixed dropdown relative to the host element requestAnimationFrame(() => { const dropdown = this.shadowRoot?.querySelector('.dropdown'); if (dropdown) { const hostRect = this.getBoundingClientRect(); dropdown.style.top = hostRect.bottom + 4 + 'px'; dropdown.style.left = hostRect.left + 'px'; dropdown.style.minWidth = hostRect.width + 'px'; // Align right if dropdown overflows viewport const dropdownRect = dropdown.getBoundingClientRect(); if (dropdownRect.right > window.innerWidth) { dropdown.style.left = ''; dropdown.style.right = window.innerWidth - hostRect.right + 'px'; } } }); } } _handleOptionClick(option, e) { e.stopPropagation(); this._dropdownOpened = false; this.dispatchEvent(new CustomEvent('option-select', { detail: { id: option.id, label: option.label }, bubbles: true, composed: true })); } /** * Shows a loading spinner and disables the button. */ showLoading() { this._clearStateTimeout(); this._state = 'loading'; this._stateText = ''; } /** * Shows a success state with optional custom text. * @param text - Text to display (default: \"Saved\") * @param duration - Duration in ms before auto-reset (default: 2000) */ showSuccess(text = 'Success', duration = 2000) { this._clearStateTimeout(); this._state = 'success'; this._stateText = text; if (duration > 0) { this._stateTimeout = window.setTimeout(() => this.reset(), duration); } } /** * Shows an error state with optional custom text. * @param text - Text to display (default: \"Error\") * @param duration - Duration in ms before auto-reset (default: 2000) */ showError(text = 'Error', duration = 2000) { this._clearStateTimeout(); this._state = 'error'; this._stateText = text; if (duration > 0) { this._stateTimeout = window.setTimeout(() => this.reset(), duration); } } /** * Resets the button to its idle state. */ reset() { this._clearStateTimeout(); this._state = 'idle'; this._stateText = ''; } _clearStateTimeout() { if (this._stateTimeout) { clearTimeout(this._stateTimeout); this._stateTimeout = undefined; } } updated(changedProperties) { // Reflect state classes to host this.classList.toggle('kr-button--loading', this._state === 'loading'); this.classList.toggle('kr-button--success', this._state === 'success'); this.classList.toggle('kr-button--error', this._state === 'error'); this.classList.toggle(`kr-button--${this.variant}`, true); this.classList.toggle(`kr-button--${this.color}`, true); this.classList.toggle('kr-button--small', this.size === 'small'); this.classList.toggle('kr-button--large', this.size === 'large'); } render() { const content = html ` <slot></slot> ${this.options.length ? html `<svg class=\"caret\" xmlns=\"http://www.w3.org/2000/svg\" height=\"20\" width=\"20\" 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>` : nothing} ${this._state !== 'idle' ? html `<span class=\"state-overlay\"> ${this._state === 'loading' ? html `<span class=\"spinner\"></span>` : this._stateText} </span>` : nothing} ${this.options.length ? html ` <div class=\"dropdown ${this._dropdownOpened ? 'dropdown--opened' : ''}\"> ${this.options.map(option => html ` <button class=\"dropdown-item\" @click=${(e) => this._handleOptionClick(option, e)} >${option.label}</button> `)} </div> ` : nothing} `; return this.href ? html `<a class=\"link\" href=${this.href} target=${this.target || nothing}>${content}</a>` : content; } }",
1062
1156
  "description": "A customizable button component."
1063
1157
  }
1064
1158
  ],
@@ -1075,44 +1169,44 @@
1075
1169
  },
1076
1170
  {
1077
1171
  "kind": "javascript-module",
1078
- "path": "dist/context-menu/context-menu.js",
1172
+ "path": "dist/code-demo/code-demo.js",
1079
1173
  "declarations": [
1080
1174
  {
1081
1175
  "kind": "variable",
1082
- "name": "KRContextMenu",
1083
- "default": "class KRContextMenu extends LitElement { constructor() { super(...arguments); this.items = []; this.resolvePromise = null; this.boundHandleOutsideClick = this.handleOutsideClick.bind(this); this.boundHandleKeyDown = this.handleKeyDown.bind(this); } static async open(options) { // Remove any existing context menu const existing = document.querySelector('kr-context-menu'); if (existing) { existing.remove(); } // Create and position the menu const menu = document.createElement('kr-context-menu'); document.body.appendChild(menu); return menu.show(options); } async show(options) { this.items = options.items; this.style.left = `${options.x}px`; this.style.top = `${options.y}px`; // Adjust position if menu would go off screen await this.updateComplete; const rect = this.getBoundingClientRect(); if (rect.right > window.innerWidth) { this.style.left = `${options.x - rect.width}px`; } if (rect.bottom > window.innerHeight) { this.style.top = `${options.y - rect.height}px`; } // Add event listeners after a microtask to avoid the current event triggering close requestAnimationFrame(() => { document.addEventListener('click', this.boundHandleOutsideClick); document.addEventListener('contextmenu', this.boundHandleOutsideClick); document.addEventListener('keydown', this.boundHandleKeyDown); }); return new Promise((resolve) => { this.resolvePromise = resolve; }); } handleOutsideClick(e) { if (!this.contains(e.target)) { this.close(null); } } handleKeyDown(e) { if (e.key === 'Escape') { this.close(null); } } handleItemClick(item) { if (!item.disabled && !item.divider) { this.close(item); } } close(result) { document.removeEventListener('click', this.boundHandleOutsideClick); document.removeEventListener('contextmenu', this.boundHandleOutsideClick); document.removeEventListener('keydown', this.boundHandleKeyDown); if (this.resolvePromise) { this.resolvePromise(result); this.resolvePromise = null; } this.remove(); } render() { return html ` <div class=\"menu\"> ${this.items.map(item => item.divider ? html `<div class=\"menu__divider\"></div>` : html ` <button class=\"menu__item\" ?disabled=${item.disabled} @click=${() => this.handleItemClick(item)} > ${item.icon ? html `<span class=\"menu__item-icon\">${item.icon}</span>` : null} ${item.label} </button> `)} </div> `; } }",
1084
- "description": "Context menu component that can be opened programmatically.\n\nUsage:\n```ts\nconst result = await ContextMenu.open({\n x: event.clientX,\n y: event.clientY,\n items: [\n { id: 'edit', label: 'Edit Item' },\n { id: 'divider', label: '', divider: true },\n { id: 'add-above', label: 'Add Item Above' },\n { id: 'add-below', label: 'Add Item Below' },\n ]\n});\n\nif (result) {\n console.log('Selected:', result.id);\n}\n```"
1176
+ "name": "KRCodeDemo",
1177
+ "default": "class KRCodeDemo extends LitElement { constructor() { super(...arguments); this.language = 'html'; this.code = ''; this.activeTab = 'preview'; this.copied = false; this.highlightedCode = ''; } connectedCallback() { super.connectedCallback(); // Defer to next frame so the parser finishes with children before we read innerHTML requestAnimationFrame(() => { if (!this.code) { // innerHTML normalizes boolean attributes (e.g. dismissible -> dismissible=\"\"), strip the =\"\" for cleaner display this.code = this.innerHTML.trim().replace(/=\"\"(?=[\\s>])/g, ''); } this.querySelectorAll('script').forEach(oldScript => { const newScript = document.createElement('script'); newScript.textContent = oldScript.textContent; oldScript.replaceWith(newScript); }); if (this.code && window.hljs && window.hljs.getLanguage(this.language)) { this.highlightedCode = window.hljs.highlight(this.code, { language: this.language }).value; } else { this.highlightedCode = this.code.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); } }); } activateTab(tab) { this.activeTab = tab; } copyCode() { if (!this.code) return; navigator.clipboard.writeText(this.code).then(() => { this.copied = true; setTimeout(() => { this.copied = false; }, 2000); }); } render() { return html ` <div class=\"tabs\"> <button class=${classMap({ tab: true, 'tab--active': this.activeTab === 'preview' })} @click=${() => this.activateTab('preview')} > Preview </button> <button class=${classMap({ tab: true, 'tab--active': this.activeTab === 'code' })} @click=${() => this.activateTab('code')} > Code </button> <button class=${classMap({ 'copy': true, 'copy--success': this.copied })} @click=${this.copyCode} title=${this.copied ? 'Copied!' : 'Copy code'} > ${this.copied ? html `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"></polyline></svg>` : html `<svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path></svg>`} </button> </div> <div class=${classMap({ panel: true, 'panel--active': this.activeTab === 'preview', 'panel--preview': true })}> <slot></slot> </div> <div class=${classMap({ panel: true, 'panel--active': this.activeTab === 'code', 'panel--code': true })}> <pre class=\"code\"><code>${unsafeHTML(this.highlightedCode)}</code></pre> </div> `; } }",
1178
+ "description": "Code demo component with Preview/Code tabs and syntax highlighting.\n\nUsage:\n```html\n<kr-code-demo language=\"html\">\n <kr-button>Click me</kr-button>\n</kr-code-demo>\n```\n\nRequires highlight.js to be loaded globally for syntax highlighting."
1085
1179
  }
1086
1180
  ],
1087
1181
  "exports": [
1088
1182
  {
1089
1183
  "kind": "js",
1090
- "name": "KRContextMenu",
1184
+ "name": "KRCodeDemo",
1091
1185
  "declaration": {
1092
- "name": "KRContextMenu",
1093
- "module": "dist/context-menu/context-menu.js"
1186
+ "name": "KRCodeDemo",
1187
+ "module": "dist/code-demo/code-demo.js"
1094
1188
  }
1095
1189
  }
1096
1190
  ]
1097
1191
  },
1098
1192
  {
1099
1193
  "kind": "javascript-module",
1100
- "path": "dist/code-demo/code-demo.js",
1194
+ "path": "dist/context-menu/context-menu.js",
1101
1195
  "declarations": [
1102
1196
  {
1103
1197
  "kind": "variable",
1104
- "name": "KRCodeDemo",
1105
- "default": "class KRCodeDemo extends LitElement { constructor() { super(...arguments); this.language = 'html'; this.code = ''; this.activeTab = 'preview'; this.copied = false; } setTab(tab) { this.activeTab = tab; } getHighlightedCode() { if (!this.code) return ''; if (window.Prism && window.Prism.languages[this.language]) { return window.Prism.highlight(this.code, window.Prism.languages[this.language], this.language); } // Fallback: escape HTML and return plain text return this.escapeHtml(this.code); } escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } async copyCode() { if (!this.code) return; try { await navigator.clipboard.writeText(this.code); this.copied = true; setTimeout(() => { this.copied = false; }, 2000); } catch (err) { console.error('Failed to copy code:', err); } } render() { return html ` <div class=\"tabs\"> <button class=${classMap({ tab: true, 'tab--active': this.activeTab === 'preview' })} @click=${() => this.setTab('preview')} > Preview </button> <button class=${classMap({ tab: true, 'tab--active': this.activeTab === 'code' })} @click=${() => this.setTab('code')} > Code </button> </div> <div class=${classMap({ panel: true, 'panel--active': this.activeTab === 'preview', preview: true })}> <slot name=\"preview\"></slot> </div> <div class=${classMap({ panel: true, 'panel--active': this.activeTab === 'code', 'code-container': true })}> <button class=${classMap({ 'copy-btn': true, 'copy-btn--copied': this.copied })} @click=${this.copyCode} > ${this.copied ? 'Copied!' : 'Copy'} </button> <pre class=\"code\"><code>${unsafeHTML(this.getHighlightedCode())}</code></pre> </div> `; } }",
1106
- "description": "Code demo component with Preview/Code tabs and syntax highlighting.\n\nUsage:\n```html\n<kr-code-demo language=\"html\">\n <div slot=\"preview\">\n <kr-button>Click me</kr-button>\n </div>\n <script slot=\"code\" type=\"text/plain\">\n <kr-button>Click me</kr-button>\n </script>\n</kr-code-demo>\n```\n\nRequires Prism.js to be loaded globally for syntax highlighting."
1198
+ "name": "KRContextMenu",
1199
+ "default": "class KRContextMenu extends LitElement { constructor() { super(...arguments); this.items = []; this.resolvePromise = null; this.boundHandleOutsideClick = this.handleOutsideClick.bind(this); this.boundHandleKeyDown = this.handleKeyDown.bind(this); } static async open(options) { // Remove any existing context menu const existing = document.querySelector('kr-context-menu'); if (existing) { existing.remove(); } // Create and position the menu const menu = document.createElement('kr-context-menu'); document.body.appendChild(menu); return menu.show(options); } async show(options) { this.items = options.items; this.style.left = `${options.x}px`; this.style.top = `${options.y}px`; // Adjust position if menu would go off screen await this.updateComplete; const rect = this.getBoundingClientRect(); if (rect.right > window.innerWidth) { this.style.left = `${options.x - rect.width}px`; } if (rect.bottom > window.innerHeight) { this.style.top = `${options.y - rect.height}px`; } // Add event listeners after a microtask to avoid the current event triggering close requestAnimationFrame(() => { document.addEventListener('click', this.boundHandleOutsideClick); document.addEventListener('contextmenu', this.boundHandleOutsideClick); document.addEventListener('keydown', this.boundHandleKeyDown); }); return new Promise((resolve) => { this.resolvePromise = resolve; }); } handleOutsideClick(e) { if (!this.contains(e.target)) { this.close(null); } } handleKeyDown(e) { if (e.key === 'Escape') { this.close(null); } } handleItemClick(item) { if (!item.disabled && !item.divider) { this.close(item); } } close(result) { document.removeEventListener('click', this.boundHandleOutsideClick); document.removeEventListener('contextmenu', this.boundHandleOutsideClick); document.removeEventListener('keydown', this.boundHandleKeyDown); if (this.resolvePromise) { this.resolvePromise(result); this.resolvePromise = null; } this.remove(); } render() { return html ` <div class=\"menu\"> ${this.items.map(item => item.divider ? html `<div class=\"menu__divider\"></div>` : html ` <button class=\"menu__item\" ?disabled=${item.disabled} @click=${() => this.handleItemClick(item)} > ${item.icon ? html `<span class=\"menu__item-icon\">${item.icon}</span>` : null} ${item.label} </button> `)} </div> `; } }",
1200
+ "description": "Context menu component that can be opened programmatically.\n\nUsage:\n```ts\nconst result = await ContextMenu.open({\n x: event.clientX,\n y: event.clientY,\n items: [\n { id: 'edit', label: 'Edit Item' },\n { id: 'divider', label: '', divider: true },\n { id: 'add-above', label: 'Add Item Above' },\n { id: 'add-below', label: 'Add Item Below' },\n ]\n});\n\nif (result) {\n console.log('Selected:', result.id);\n}\n```"
1107
1201
  }
1108
1202
  ],
1109
1203
  "exports": [
1110
1204
  {
1111
1205
  "kind": "js",
1112
- "name": "KRCodeDemo",
1206
+ "name": "KRContextMenu",
1113
1207
  "declaration": {
1114
- "name": "KRCodeDemo",
1115
- "module": "dist/code-demo/code-demo.js"
1208
+ "name": "KRContextMenu",
1209
+ "module": "dist/context-menu/context-menu.js"
1116
1210
  }
1117
1211
  }
1118
1212
  ]
@@ -1121,27 +1215,50 @@
1121
1215
  "kind": "javascript-module",
1122
1216
  "path": "dist/dialog/dialog.js",
1123
1217
  "declarations": [
1218
+ {
1219
+ "kind": "variable",
1220
+ "name": "KRDialogHeader",
1221
+ "default": "class KRDialogHeader extends LitElement { render() { return html `<slot></slot>`; } }"
1222
+ },
1223
+ {
1224
+ "kind": "variable",
1225
+ "name": "KRDialogContent",
1226
+ "default": "class KRDialogContent extends LitElement { render() { return html `<slot></slot>`; } }"
1227
+ },
1228
+ {
1229
+ "kind": "variable",
1230
+ "name": "KRDialogFooter",
1231
+ "default": "class KRDialogFooter extends LitElement { render() { return html `<slot></slot>`; } }"
1232
+ },
1124
1233
  {
1125
1234
  "kind": "class",
1126
- "description": "",
1127
- "name": "DialogRef",
1235
+ "description": "A reference to an open dialog instance.\n\nUsed to close the dialog and retrieve its result.",
1236
+ "name": "KRDialogRef",
1128
1237
  "members": [
1129
1238
  {
1130
1239
  "kind": "method",
1131
1240
  "name": "close",
1132
1241
  "parameters": [
1133
1242
  {
1134
- "name": "result"
1243
+ "name": "result",
1244
+ "description": "The result to return to the caller"
1135
1245
  }
1136
- ]
1246
+ ],
1247
+ "description": "Closes the dialog and resolves with the given result."
1137
1248
  },
1138
1249
  {
1139
1250
  "kind": "method",
1140
- "name": "afterClosed"
1251
+ "name": "afterClosed",
1252
+ "description": "Returns a promise that resolves when the dialog is closed.",
1253
+ "return": {
1254
+ "type": {
1255
+ "text": ""
1256
+ }
1257
+ }
1141
1258
  },
1142
1259
  {
1143
1260
  "kind": "field",
1144
- "name": "resolvePromise",
1261
+ "name": "_resolvePromise",
1145
1262
  "type": {
1146
1263
  "text": "null"
1147
1264
  },
@@ -1149,7 +1266,7 @@
1149
1266
  },
1150
1267
  {
1151
1268
  "kind": "field",
1152
- "name": "dialogElement",
1269
+ "name": "_dialogElement",
1153
1270
  "type": {
1154
1271
  "text": "null"
1155
1272
  },
@@ -1157,24 +1274,48 @@
1157
1274
  },
1158
1275
  {
1159
1276
  "kind": "field",
1160
- "name": "promise",
1161
- "default": "new Promise((resolve) => { this.resolvePromise = resolve; })"
1277
+ "name": "_promise",
1278
+ "default": "new Promise((resolve) => { this._resolvePromise = resolve; })"
1162
1279
  }
1163
1280
  ]
1164
1281
  },
1165
1282
  {
1166
1283
  "kind": "variable",
1167
1284
  "name": "KRDialog",
1168
- "default": "class KRDialog extends LitElement { constructor() { super(...arguments); this.contentElement = null; this.dialogRef = null; this.boundHandleKeyDown = this.handleKeyDown.bind(this); } static open(component, config) { const existing = document.querySelector('kr-dialog'); if (existing) { existing.remove(); } const dialogRef = new DialogRef(); 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.boundHandleKeyDown); return dialogRef; } handleKeyDown(e) { if (e.key === 'Escape') { this.dialogRef?.close(undefined); } } handleBackdropClick(e) { if (e.target.classList.contains('backdrop')) { this.dialogRef?.close(undefined); } } disconnectedCallback() { super.disconnectedCallback(); document.removeEventListener('keydown', this.boundHandleKeyDown); } render() { return html ` <div class=\"backdrop\" @click=${this.handleBackdropClick}></div> <div class=\"dialog\"> ${this.contentElement} </div> `; } }",
1169
- "description": "Generic dialog component that renders a Lit component inside a dialog shell.\n\nUsage:\n```ts\n// Define your dialog content component\nclass EditItemDialog extends LitElement {\n // Injected by KRDialog\n dialogRef: DialogRef<{ label: string }>;\n data: { label: string };\n\n save() {\n this.dialogRef.close({ label: this.label });\n }\n}\n\n// Open the dialog\nconst dialogRef = KRDialog.open(EditItemDialog, {\n data: { label: 'Dashboard' }\n});\n\nconst result = await dialogRef.afterClosed();\nif (result) {\n console.log('Saved:', result.label);\n}\n```"
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."
1170
1287
  }
1171
1288
  ],
1172
1289
  "exports": [
1173
1290
  {
1174
1291
  "kind": "js",
1175
- "name": "DialogRef",
1292
+ "name": "KRDialogHeader",
1176
1293
  "declaration": {
1177
- "name": "DialogRef",
1294
+ "name": "KRDialogHeader",
1295
+ "module": "dist/dialog/dialog.js"
1296
+ }
1297
+ },
1298
+ {
1299
+ "kind": "js",
1300
+ "name": "KRDialogContent",
1301
+ "declaration": {
1302
+ "name": "KRDialogContent",
1303
+ "module": "dist/dialog/dialog.js"
1304
+ }
1305
+ },
1306
+ {
1307
+ "kind": "js",
1308
+ "name": "KRDialogFooter",
1309
+ "declaration": {
1310
+ "name": "KRDialogFooter",
1311
+ "module": "dist/dialog/dialog.js"
1312
+ }
1313
+ },
1314
+ {
1315
+ "kind": "js",
1316
+ "name": "KRDialogRef",
1317
+ "declaration": {
1318
+ "name": "KRDialogRef",
1178
1319
  "module": "dist/dialog/dialog.js"
1179
1320
  }
1180
1321
  },
@@ -1235,6 +1376,28 @@
1235
1376
  }
1236
1377
  ]
1237
1378
  },
1379
+ {
1380
+ "kind": "javascript-module",
1381
+ "path": "dist/progress-bar/progress-bar.js",
1382
+ "declarations": [
1383
+ {
1384
+ "kind": "variable",
1385
+ "name": "KRProgressBar",
1386
+ "default": "class KRProgressBar extends LitElement { constructor() { super(...arguments); /** * The color of the progress bar. Can be 'dark', 'light', or any valid CSS color value. */ this.color = 'dark'; } render() { let normalizedColor = ''; let normalizedTrackColor = ''; if (this.color === 'dark') { normalizedColor = '#163052'; } else if (this.color === 'light') { normalizedColor = '#ffffff'; } else { normalizedColor = this.color; } if (this.trackColor) { normalizedTrackColor = this.trackColor; } else if (this.color === 'light') { normalizedTrackColor = '#ffffff4d'; } else { normalizedTrackColor = '#0000001a'; } return html ` <div class=\"progress-bar\" style=${`background: ${normalizedTrackColor}`} role=\"status\" aria-label=\"Loading\" > <div class=\"fill\" style=${`background: ${normalizedColor}`}></div> </div> `; } }",
1387
+ "description": "A linear loading indicator that shows activity or ongoing processes."
1388
+ }
1389
+ ],
1390
+ "exports": [
1391
+ {
1392
+ "kind": "js",
1393
+ "name": "KRProgressBar",
1394
+ "declaration": {
1395
+ "name": "KRProgressBar",
1396
+ "module": "dist/progress-bar/progress-bar.js"
1397
+ }
1398
+ }
1399
+ ]
1400
+ },
1238
1401
  {
1239
1402
  "kind": "javascript-module",
1240
1403
  "path": "dist/snackbar/snackbar.js",
@@ -1256,6 +1419,28 @@
1256
1419
  }
1257
1420
  ]
1258
1421
  },
1422
+ {
1423
+ "kind": "javascript-module",
1424
+ "path": "dist/spinner/spinner.js",
1425
+ "declarations": [
1426
+ {
1427
+ "kind": "variable",
1428
+ "name": "KRSpinner",
1429
+ "default": "class KRSpinner extends LitElement { constructor() { super(...arguments); /** * The size of the spinner. Can be 'sm', 'md', 'lg', 'xl', or any valid CSS size value (e.g., '100px', '2rem'). */ this.size = 'md'; /** * The color of the spinner. Can be 'dark', 'light', or any valid CSS color value. */ this.color = 'dark'; } render() { var normalizedSize = ''; var normalizedColor = ''; if (this.size == 'sm') { normalizedSize = '16px'; } else if (this.size == 'md') { normalizedSize = '24px'; } else if (this.size == 'lg') { normalizedSize = '32px'; } else if (this.size == 'xl') { normalizedSize = '48px'; } else { normalizedSize = this.size; } if (this.color == 'dark') { normalizedColor = '#163052'; } else if (this.color == 'light') { normalizedColor = '#ffffff'; } else { normalizedColor = this.color; } return html ` <svg class=\"spinner\" style=${`width: ${normalizedSize}; height: ${normalizedSize}; color: ${normalizedColor}`} viewBox=\"0 0 44 44\" role=\"status\" aria-label=\"Loading\" > <circle class=\"circle\" cx=\"22\" cy=\"22\" r=\"20\" fill=\"none\" stroke-width=\"4\" /> </svg> `; } }",
1430
+ "description": "A circular loading indicator component that shows activity or ongoing processes."
1431
+ }
1432
+ ],
1433
+ "exports": [
1434
+ {
1435
+ "kind": "js",
1436
+ "name": "KRSpinner",
1437
+ "declaration": {
1438
+ "name": "KRSpinner",
1439
+ "module": "dist/spinner/spinner.js"
1440
+ }
1441
+ }
1442
+ ]
1443
+ },
1259
1444
  {
1260
1445
  "kind": "javascript-module",
1261
1446
  "path": "dist/style/base.js",
@@ -1459,12 +1644,13 @@
1459
1644
  },
1460
1645
  {
1461
1646
  "kind": "field",
1462
- "name": "header",
1647
+ "name": "title",
1463
1648
  "type": {
1464
- "text": "string | undefined"
1649
+ "text": "string"
1465
1650
  },
1466
- "description": "Optional header text",
1467
- "attribute": "header"
1651
+ "default": "''",
1652
+ "description": "Optional title text",
1653
+ "attribute": "title"
1468
1654
  },
1469
1655
  {
1470
1656
  "kind": "field",
@@ -1513,12 +1699,13 @@
1513
1699
  "fieldName": "type"
1514
1700
  },
1515
1701
  {
1516
- "name": "header",
1702
+ "name": "title",
1517
1703
  "type": {
1518
- "text": "string | undefined"
1704
+ "text": "string"
1519
1705
  },
1520
- "description": "Optional header text",
1521
- "fieldName": "header"
1706
+ "default": "''",
1707
+ "description": "Optional title text",
1708
+ "fieldName": "title"
1522
1709
  },
1523
1710
  {
1524
1711
  "name": "dismissible",
@@ -1680,15 +1867,6 @@
1680
1867
  "privacy": "private",
1681
1868
  "default": "false"
1682
1869
  },
1683
- {
1684
- "kind": "field",
1685
- "name": "_dropdownAlignRight",
1686
- "type": {
1687
- "text": "boolean"
1688
- },
1689
- "privacy": "private",
1690
- "default": "false"
1691
- },
1692
1870
  {
1693
1871
  "kind": "field",
1694
1872
  "name": "_stateTimeout",
@@ -1895,7 +2073,7 @@
1895
2073
  "declarations": [
1896
2074
  {
1897
2075
  "kind": "class",
1898
- "description": "Code demo component with Preview/Code tabs and syntax highlighting.\n\nUsage:\n```html\n<kr-code-demo language=\"html\">\n <div slot=\"preview\">\n <kr-button>Click me</kr-button>\n </div>\n <script slot=\"code\" type=\"text/plain\">\n <kr-button>Click me</kr-button>\n </script>\n</kr-code-demo>\n```\n\nRequires Prism.js to be loaded globally for syntax highlighting.",
2076
+ "description": "Code demo component with Preview/Code tabs and syntax highlighting.\n\nUsage:\n```html\n<kr-code-demo language=\"html\">\n <kr-button>Click me</kr-button>\n</kr-code-demo>\n```\n\nRequires highlight.js to be loaded globally for syntax highlighting.",
1899
2077
  "name": "KRCodeDemo",
1900
2078
  "members": [
1901
2079
  {
@@ -1913,8 +2091,8 @@
1913
2091
  "type": {
1914
2092
  "text": "string"
1915
2093
  },
1916
- "default": "''",
1917
- "attribute": "code"
2094
+ "privacy": "private",
2095
+ "default": "''"
1918
2096
  },
1919
2097
  {
1920
2098
  "kind": "field",
@@ -1935,42 +2113,23 @@
1935
2113
  "default": "false"
1936
2114
  },
1937
2115
  {
1938
- "kind": "method",
1939
- "name": "setTab",
1940
- "privacy": "private",
1941
- "parameters": [
1942
- {
1943
- "name": "tab",
1944
- "type": {
1945
- "text": "'preview' | 'code'"
1946
- }
1947
- }
1948
- ]
1949
- },
1950
- {
1951
- "kind": "method",
1952
- "name": "getHighlightedCode",
2116
+ "kind": "field",
2117
+ "name": "highlightedCode",
2118
+ "type": {
2119
+ "text": "string"
2120
+ },
1953
2121
  "privacy": "private",
1954
- "return": {
1955
- "type": {
1956
- "text": "string"
1957
- }
1958
- }
2122
+ "default": "''"
1959
2123
  },
1960
2124
  {
1961
2125
  "kind": "method",
1962
- "name": "escapeHtml",
2126
+ "name": "activateTab",
1963
2127
  "privacy": "private",
1964
- "return": {
1965
- "type": {
1966
- "text": "string"
1967
- }
1968
- },
1969
2128
  "parameters": [
1970
2129
  {
1971
- "name": "text",
2130
+ "name": "tab",
1972
2131
  "type": {
1973
- "text": "string"
2132
+ "text": "'preview' | 'code'"
1974
2133
  }
1975
2134
  }
1976
2135
  ]
@@ -1989,14 +2148,6 @@
1989
2148
  },
1990
2149
  "default": "'html'",
1991
2150
  "fieldName": "language"
1992
- },
1993
- {
1994
- "name": "code",
1995
- "type": {
1996
- "text": "string"
1997
- },
1998
- "default": "''",
1999
- "fieldName": "code"
2000
2151
  }
2001
2152
  ],
2002
2153
  "superclass": {
@@ -2185,11 +2336,47 @@
2185
2336
  {
2186
2337
  "kind": "class",
2187
2338
  "description": "",
2188
- "name": "DialogRef",
2339
+ "name": "KRDialogHeader",
2340
+ "members": [],
2341
+ "superclass": {
2342
+ "name": "LitElement",
2343
+ "package": "lit"
2344
+ },
2345
+ "tagName": "kr-dialog-header",
2346
+ "customElement": true
2347
+ },
2348
+ {
2349
+ "kind": "class",
2350
+ "description": "",
2351
+ "name": "KRDialogContent",
2352
+ "members": [],
2353
+ "superclass": {
2354
+ "name": "LitElement",
2355
+ "package": "lit"
2356
+ },
2357
+ "tagName": "kr-dialog-content",
2358
+ "customElement": true
2359
+ },
2360
+ {
2361
+ "kind": "class",
2362
+ "description": "",
2363
+ "name": "KRDialogFooter",
2364
+ "members": [],
2365
+ "superclass": {
2366
+ "name": "LitElement",
2367
+ "package": "lit"
2368
+ },
2369
+ "tagName": "kr-dialog-footer",
2370
+ "customElement": true
2371
+ },
2372
+ {
2373
+ "kind": "class",
2374
+ "description": "A reference to an open dialog instance.\n\nUsed to close the dialog and retrieve its result.",
2375
+ "name": "KRDialogRef",
2189
2376
  "members": [
2190
2377
  {
2191
2378
  "kind": "field",
2192
- "name": "resolvePromise",
2379
+ "name": "_resolvePromise",
2193
2380
  "type": {
2194
2381
  "text": "((value: R | undefined) => void) | null"
2195
2382
  },
@@ -2198,16 +2385,16 @@
2198
2385
  },
2199
2386
  {
2200
2387
  "kind": "field",
2201
- "name": "promise",
2388
+ "name": "_promise",
2202
2389
  "type": {
2203
2390
  "text": "Promise<R | undefined>"
2204
2391
  },
2205
2392
  "privacy": "private",
2206
- "default": "new Promise((resolve) => { this.resolvePromise = resolve; })"
2393
+ "default": "new Promise((resolve) => { this._resolvePromise = resolve; })"
2207
2394
  },
2208
2395
  {
2209
2396
  "kind": "field",
2210
- "name": "dialogElement",
2397
+ "name": "_dialogElement",
2211
2398
  "type": {
2212
2399
  "text": "KRDialog | null"
2213
2400
  },
@@ -2223,56 +2410,54 @@
2223
2410
  "optional": true,
2224
2411
  "type": {
2225
2412
  "text": "R"
2226
- }
2413
+ },
2414
+ "description": "The result to return to the caller"
2227
2415
  }
2228
- ]
2416
+ ],
2417
+ "description": "Closes the dialog and resolves with the given result."
2229
2418
  },
2230
2419
  {
2231
2420
  "kind": "method",
2232
2421
  "name": "afterClosed",
2233
2422
  "return": {
2234
2423
  "type": {
2235
- "text": "Promise<R | undefined>"
2424
+ "text": ""
2236
2425
  }
2237
- }
2426
+ },
2427
+ "description": "Returns a promise that resolves when the dialog is closed."
2238
2428
  }
2239
2429
  ]
2240
2430
  },
2241
2431
  {
2242
2432
  "kind": "class",
2243
- "description": "Generic dialog component that renders a Lit component inside a dialog shell.\n\nUsage:\n```ts\n// Define your dialog content component\nclass EditItemDialog extends LitElement {\n // Injected by KRDialog\n dialogRef: DialogRef<{ label: string }>;\n data: { label: string };\n\n save() {\n this.dialogRef.close({ label: this.label });\n }\n}\n\n// Open the dialog\nconst dialogRef = KRDialog.open(EditItemDialog, {\n data: { label: 'Dashboard' }\n});\n\nconst result = await dialogRef.afterClosed();\nif (result) {\n console.log('Saved:', result.label);\n}\n```",
2433
+ "description": "Generic dialog component that renders a Lit component inside a dialog shell.",
2244
2434
  "name": "KRDialog",
2245
2435
  "members": [
2246
2436
  {
2247
2437
  "kind": "field",
2248
- "name": "contentElement",
2438
+ "name": "_dialogRef",
2249
2439
  "type": {
2250
- "text": "LitElement | null"
2440
+ "text": "KRDialogRef | null"
2251
2441
  },
2252
2442
  "privacy": "private",
2253
2443
  "default": "null"
2254
2444
  },
2255
2445
  {
2256
2446
  "kind": "field",
2257
- "name": "dialogRef",
2447
+ "name": "_contentElement",
2258
2448
  "type": {
2259
- "text": "DialogRef | null"
2449
+ "text": "LitElement | null"
2260
2450
  },
2261
2451
  "privacy": "private",
2262
2452
  "default": "null"
2263
2453
  },
2264
- {
2265
- "kind": "field",
2266
- "name": "boundHandleKeyDown",
2267
- "privacy": "private"
2268
- },
2269
2454
  {
2270
2455
  "kind": "method",
2271
2456
  "name": "open",
2272
2457
  "static": true,
2273
2458
  "return": {
2274
2459
  "type": {
2275
- "text": "DialogRef"
2460
+ "text": "KRDialogRef"
2276
2461
  }
2277
2462
  },
2278
2463
  "parameters": [
@@ -2286,27 +2471,19 @@
2286
2471
  "name": "config",
2287
2472
  "optional": true,
2288
2473
  "type": {
2289
- "text": "DialogConfig"
2474
+ "text": "KRDialogConfig"
2290
2475
  }
2291
2476
  }
2292
2477
  ]
2293
2478
  },
2294
2479
  {
2295
- "kind": "method",
2296
- "name": "handleKeyDown",
2297
- "privacy": "private",
2298
- "parameters": [
2299
- {
2300
- "name": "e",
2301
- "type": {
2302
- "text": "KeyboardEvent"
2303
- }
2304
- }
2305
- ]
2480
+ "kind": "field",
2481
+ "name": "_handleDocumentKeyDown",
2482
+ "privacy": "private"
2306
2483
  },
2307
2484
  {
2308
2485
  "kind": "method",
2309
- "name": "handleBackdropClick",
2486
+ "name": "_handleBackdropClick",
2310
2487
  "privacy": "private",
2311
2488
  "parameters": [
2312
2489
  {
@@ -2329,9 +2506,57 @@
2329
2506
  "exports": [
2330
2507
  {
2331
2508
  "kind": "js",
2332
- "name": "DialogRef",
2509
+ "name": "KRDialogHeader",
2510
+ "declaration": {
2511
+ "name": "KRDialogHeader",
2512
+ "module": "src/dialog/dialog.ts"
2513
+ }
2514
+ },
2515
+ {
2516
+ "kind": "custom-element-definition",
2517
+ "name": "kr-dialog-header",
2518
+ "declaration": {
2519
+ "name": "KRDialogHeader",
2520
+ "module": "src/dialog/dialog.ts"
2521
+ }
2522
+ },
2523
+ {
2524
+ "kind": "js",
2525
+ "name": "KRDialogContent",
2526
+ "declaration": {
2527
+ "name": "KRDialogContent",
2528
+ "module": "src/dialog/dialog.ts"
2529
+ }
2530
+ },
2531
+ {
2532
+ "kind": "custom-element-definition",
2533
+ "name": "kr-dialog-content",
2534
+ "declaration": {
2535
+ "name": "KRDialogContent",
2536
+ "module": "src/dialog/dialog.ts"
2537
+ }
2538
+ },
2539
+ {
2540
+ "kind": "js",
2541
+ "name": "KRDialogFooter",
2542
+ "declaration": {
2543
+ "name": "KRDialogFooter",
2544
+ "module": "src/dialog/dialog.ts"
2545
+ }
2546
+ },
2547
+ {
2548
+ "kind": "custom-element-definition",
2549
+ "name": "kr-dialog-footer",
2550
+ "declaration": {
2551
+ "name": "KRDialogFooter",
2552
+ "module": "src/dialog/dialog.ts"
2553
+ }
2554
+ },
2555
+ {
2556
+ "kind": "js",
2557
+ "name": "KRDialogRef",
2333
2558
  "declaration": {
2334
- "name": "DialogRef",
2559
+ "name": "KRDialogRef",
2335
2560
  "module": "src/dialog/dialog.ts"
2336
2561
  }
2337
2562
  },
@@ -2400,6 +2625,83 @@
2400
2625
  }
2401
2626
  ]
2402
2627
  },
2628
+ {
2629
+ "kind": "javascript-module",
2630
+ "path": "src/progress-bar/progress-bar.ts",
2631
+ "declarations": [
2632
+ {
2633
+ "kind": "class",
2634
+ "description": "A linear loading indicator that shows activity or ongoing processes.",
2635
+ "name": "KRProgressBar",
2636
+ "members": [
2637
+ {
2638
+ "kind": "field",
2639
+ "name": "color",
2640
+ "type": {
2641
+ "text": "'dark' | 'light' | string"
2642
+ },
2643
+ "default": "'dark'",
2644
+ "description": "The color of the progress bar. Can be 'dark', 'light', or any valid CSS color value.",
2645
+ "attribute": "color",
2646
+ "reflects": true
2647
+ },
2648
+ {
2649
+ "kind": "field",
2650
+ "name": "trackColor",
2651
+ "type": {
2652
+ "text": "string | undefined"
2653
+ },
2654
+ "description": "The background track color. Can be any valid CSS color value.",
2655
+ "attribute": "trackColor",
2656
+ "reflects": true
2657
+ }
2658
+ ],
2659
+ "attributes": [
2660
+ {
2661
+ "name": "color",
2662
+ "type": {
2663
+ "text": "'dark' | 'light' | string"
2664
+ },
2665
+ "default": "'dark'",
2666
+ "description": "The color of the progress bar. Can be 'dark', 'light', or any valid CSS color value.",
2667
+ "fieldName": "color"
2668
+ },
2669
+ {
2670
+ "name": "trackColor",
2671
+ "type": {
2672
+ "text": "string | undefined"
2673
+ },
2674
+ "description": "The background track color. Can be any valid CSS color value.",
2675
+ "fieldName": "trackColor"
2676
+ }
2677
+ ],
2678
+ "superclass": {
2679
+ "name": "LitElement",
2680
+ "package": "lit"
2681
+ },
2682
+ "tagName": "kr-progress-bar",
2683
+ "customElement": true
2684
+ }
2685
+ ],
2686
+ "exports": [
2687
+ {
2688
+ "kind": "js",
2689
+ "name": "KRProgressBar",
2690
+ "declaration": {
2691
+ "name": "KRProgressBar",
2692
+ "module": "src/progress-bar/progress-bar.ts"
2693
+ }
2694
+ },
2695
+ {
2696
+ "kind": "custom-element-definition",
2697
+ "name": "kr-progress-bar",
2698
+ "declaration": {
2699
+ "name": "KRProgressBar",
2700
+ "module": "src/progress-bar/progress-bar.ts"
2701
+ }
2702
+ }
2703
+ ]
2704
+ },
2403
2705
  {
2404
2706
  "kind": "javascript-module",
2405
2707
  "path": "src/snackbar/snackbar.ts",
@@ -2574,6 +2876,85 @@
2574
2876
  }
2575
2877
  ]
2576
2878
  },
2879
+ {
2880
+ "kind": "javascript-module",
2881
+ "path": "src/spinner/spinner.ts",
2882
+ "declarations": [
2883
+ {
2884
+ "kind": "class",
2885
+ "description": "A circular loading indicator component that shows activity or ongoing processes.",
2886
+ "name": "KRSpinner",
2887
+ "members": [
2888
+ {
2889
+ "kind": "field",
2890
+ "name": "size",
2891
+ "type": {
2892
+ "text": "'sm' | 'md' | 'lg' | 'xl' | string"
2893
+ },
2894
+ "default": "'md'",
2895
+ "description": "The size of the spinner. Can be 'sm', 'md', 'lg', 'xl', or any valid CSS size value (e.g., '100px', '2rem').",
2896
+ "attribute": "size",
2897
+ "reflects": true
2898
+ },
2899
+ {
2900
+ "kind": "field",
2901
+ "name": "color",
2902
+ "type": {
2903
+ "text": "'dark' | 'light' | string"
2904
+ },
2905
+ "default": "'dark'",
2906
+ "description": "The color of the spinner. Can be 'dark', 'light', or any valid CSS color value.",
2907
+ "attribute": "color",
2908
+ "reflects": true
2909
+ }
2910
+ ],
2911
+ "attributes": [
2912
+ {
2913
+ "name": "size",
2914
+ "type": {
2915
+ "text": "'sm' | 'md' | 'lg' | 'xl' | string"
2916
+ },
2917
+ "default": "'md'",
2918
+ "description": "The size of the spinner. Can be 'sm', 'md', 'lg', 'xl', or any valid CSS size value (e.g., '100px', '2rem').",
2919
+ "fieldName": "size"
2920
+ },
2921
+ {
2922
+ "name": "color",
2923
+ "type": {
2924
+ "text": "'dark' | 'light' | string"
2925
+ },
2926
+ "default": "'dark'",
2927
+ "description": "The color of the spinner. Can be 'dark', 'light', or any valid CSS color value.",
2928
+ "fieldName": "color"
2929
+ }
2930
+ ],
2931
+ "superclass": {
2932
+ "name": "LitElement",
2933
+ "package": "lit"
2934
+ },
2935
+ "tagName": "kr-spinner",
2936
+ "customElement": true
2937
+ }
2938
+ ],
2939
+ "exports": [
2940
+ {
2941
+ "kind": "js",
2942
+ "name": "KRSpinner",
2943
+ "declaration": {
2944
+ "name": "KRSpinner",
2945
+ "module": "src/spinner/spinner.ts"
2946
+ }
2947
+ },
2948
+ {
2949
+ "kind": "custom-element-definition",
2950
+ "name": "kr-spinner",
2951
+ "declaration": {
2952
+ "name": "KRSpinner",
2953
+ "module": "src/spinner/spinner.ts"
2954
+ }
2955
+ }
2956
+ ]
2957
+ },
2577
2958
  {
2578
2959
  "kind": "javascript-module",
2579
2960
  "path": "src/style/base.ts",
@@ -3548,7 +3929,7 @@
3548
3929
  {
3549
3930
  "kind": "variable",
3550
3931
  "name": "KRSelectField",
3551
- "default": "class KRSelectField extends LitElement { constructor() { super(); /** * The select label text */ this.label = ''; /** * The input name for form submission */ this.name = ''; /** * The currently selected value */ this.value = ''; /** * Placeholder text when no option is selected */ this.placeholder = 'Select an option'; /** * Whether the select is disabled */ this.disabled = false; /** * Whether the field is required */ this.required = false; /** * Whether the field is readonly */ this.readonly = false; /** * Helper text shown below the select */ this.hint = ''; this._isOpen = false; this._highlightedIndex = -1; this._touched = false; this._handleInvalid = (e) => { e.preventDefault(); this._touched = true; }; this._handleOutsideClick = (e) => { if (!e.composedPath().includes(this)) { this._close(); } }; this._handleKeyDown = (e) => { if (!this._isOpen) return; const options = Array.from(this.querySelectorAll('kr-select-option')); switch (e.key) { case 'Escape': this._close(); this._triggerElement?.focus(); break; case 'ArrowDown': e.preventDefault(); if (options.some(o => !o.disabled)) { let newIndex = this._highlightedIndex + 1; while (newIndex < options.length && options[newIndex]?.disabled) newIndex++; if (newIndex < options.length) this._highlightedIndex = newIndex; } break; case 'ArrowUp': e.preventDefault(); { let newIndex = this._highlightedIndex - 1; while (newIndex >= 0 && options[newIndex]?.disabled) newIndex--; if (newIndex >= 0) this._highlightedIndex = newIndex; } break; case 'Enter': e.preventDefault(); if (this._highlightedIndex >= 0 && this._highlightedIndex < options.length) { this._selectOption(options[this._highlightedIndex]); } break; } }; this._internals = this.attachInternals(); } // Form-associated custom element callbacks get form() { return this._internals.form; } get validity() { return this._internals.validity; } get validationMessage() { return this._internals.validationMessage; } get willValidate() { return this._internals.willValidate; } checkValidity() { return this._internals.checkValidity(); } reportValidity() { return this._internals.reportValidity(); } formResetCallback() { this.value = ''; this._touched = false; this._internals.setFormValue(''); this._internals.setValidity({}); } formStateRestoreCallback(state) { this.value = state; } connectedCallback() { super.connectedCallback(); document.addEventListener('click', this._handleOutsideClick); document.addEventListener('keydown', this._handleKeyDown); this.addEventListener('invalid', this._handleInvalid); } firstUpdated() { this._updateValidity(); } updated(changedProperties) { if (changedProperties.has('required') || changedProperties.has('value')) { this._updateValidity(); } } disconnectedCallback() { super.disconnectedCallback(); document.removeEventListener('click', this._handleOutsideClick); document.removeEventListener('keydown', this._handleKeyDown); this.removeEventListener('invalid', this._handleInvalid); } _toggle() { if (this.disabled || this.readonly) return; if (this._isOpen) { this._close(); } else { this._isOpen = true; const options = Array.from(this.querySelectorAll('kr-select-option')); this._highlightedIndex = options.findIndex(o => o.value === this.value); } } _close() { this._isOpen = false; this._highlightedIndex = -1; } _selectOption(option) { if (option.disabled) return; this.value = option.value; this._internals.setFormValue(this.value); this._updateValidity(); this.dispatchEvent(new Event('change', { bubbles: true, composed: true })); this._close(); this._triggerElement?.focus(); } _handleBlur() { this._touched = true; this._updateValidity(); } _updateValidity() { if (this.required && !this.value) { this._internals.setValidity({ valueMissing: true }, 'Please select an option', this._triggerElement); } else { this._internals.setValidity({}); } } render() { const options = Array.from(this.querySelectorAll('kr-select-option')); const selectedLabel = options.find(o => o.value === this.value)?.label; return html ` <div class=\"wrapper\"> ${this.label ? html ` <label> ${this.label} ${this.required ? html `<span class=\"required\" aria-hidden=\"true\">*</span>` : ''} </label> ` : nothing} <div class=\"select-wrapper\"> <button class=${classMap({ 'select-trigger': true, 'select-trigger--open': this._isOpen, 'select-trigger--invalid': this._touched && this.required && !this.value, })} type=\"button\" ?disabled=${this.disabled} aria-haspopup=\"listbox\" aria-expanded=${this._isOpen} @click=${this._toggle} @blur=${this._handleBlur} > <span class=${classMap({ 'select-value': true, 'select-placeholder': !selectedLabel })}> ${selectedLabel || this.placeholder} </span> <svg class=${classMap({ 'chevron-icon': true, 'select-icon': true, 'select-icon--open': this._isOpen })} viewBox=\"0 0 20 20\" fill=\"currentColor\" > <path fill-rule=\"evenodd\" d=\"M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z\" clip-rule=\"evenodd\" /> </svg> </button> <div class=${classMap({ 'select-dropdown': true, 'hidden': !this._isOpen })} role=\"listbox\"> <div class=\"select-options\"> ${options.length === 0 ? html `<div class=\"select-empty\">No options available</div>` : options.map((option, idx) => { const isSelected = option.value === this.value; return html ` <div class=${classMap({ 'select-option': true, 'select-option--selected': isSelected, 'select-option--disabled': option.disabled, 'select-option--highlighted': idx === this._highlightedIndex, })} role=\"option\" aria-selected=${isSelected} @click=${() => this._selectOption(option)} @mouseenter=${() => (this._highlightedIndex = idx)} > ${option.label} ${isSelected ? html `<svg class=\"chevron-icon select-check\" viewBox=\"0 0 20 20\" fill=\"currentColor\"> <path fill-rule=\"evenodd\" d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\" clip-rule=\"evenodd\" /> </svg>` : nothing} </div> `; })} </div> </div> </div> ${this._touched && this.required && !this.value ? html `<div class=\"validation-message\">Please select an option</div>` : this.hint ? html `<div class=\"hint\">${this.hint}</div>` : ''} </div> <div class=\"options-slot\"> <slot @slotchange=${() => this.requestUpdate()}></slot> </div> `; } // Public methods for programmatic control focus() { this._triggerElement?.focus(); } blur() { this._triggerElement?.blur(); } }",
3932
+ "default": "class KRSelectField extends LitElement { constructor() { super(); /** * The select label text */ this.label = ''; /** * The input name for form submission */ this.name = ''; /** * The currently selected value */ this.value = ''; /** * Placeholder text when no option is selected */ this.placeholder = 'Select an option'; /** * Whether the select is disabled */ this.disabled = false; /** * Whether the field is required */ this.required = false; /** * Whether the field is readonly */ this.readonly = false; /** * Helper text shown below the select */ this.hint = ''; this._isOpen = false; this._highlightedIndex = -1; this._touched = false; this._handleInvalid = (e) => { e.preventDefault(); this._touched = true; }; this._handleOutsideClick = (e) => { if (!e.composedPath().includes(this)) { this._close(); } }; this._handleKeyDown = (e) => { if (!this._isOpen) return; const options = Array.from(this.querySelectorAll('kr-select-option')); switch (e.key) { case 'Escape': this._close(); this._triggerElement?.focus(); break; case 'ArrowDown': e.preventDefault(); if (options.some(o => !o.disabled)) { let newIndex = this._highlightedIndex + 1; while (newIndex < options.length && options[newIndex]?.disabled) newIndex++; if (newIndex < options.length) this._highlightedIndex = newIndex; } break; case 'ArrowUp': e.preventDefault(); { let newIndex = this._highlightedIndex - 1; while (newIndex >= 0 && options[newIndex]?.disabled) newIndex--; if (newIndex >= 0) this._highlightedIndex = newIndex; } break; case 'Enter': e.preventDefault(); if (this._highlightedIndex >= 0 && this._highlightedIndex < options.length) { this._selectOption(options[this._highlightedIndex]); } break; } }; this._internals = this.attachInternals(); } // Form-associated custom element callbacks get form() { return this._internals.form; } get validity() { return this._internals.validity; } get validationMessage() { return this._internals.validationMessage; } get willValidate() { return this._internals.willValidate; } checkValidity() { return this._internals.checkValidity(); } reportValidity() { return this._internals.reportValidity(); } formResetCallback() { this.value = ''; this._touched = false; this._internals.setFormValue(''); this._internals.setValidity({}); } formStateRestoreCallback(state) { this.value = state; } connectedCallback() { super.connectedCallback(); document.addEventListener('click', this._handleOutsideClick); document.addEventListener('keydown', this._handleKeyDown); this.addEventListener('invalid', this._handleInvalid); } firstUpdated() { this._updateValidity(); } updated(changedProperties) { if (changedProperties.has('required') || changedProperties.has('value')) { this._updateValidity(); } } disconnectedCallback() { super.disconnectedCallback(); document.removeEventListener('click', this._handleOutsideClick); document.removeEventListener('keydown', this._handleKeyDown); this.removeEventListener('invalid', this._handleInvalid); } _toggle() { if (this.disabled || this.readonly) return; if (this._isOpen) { this._close(); } else { this._isOpen = true; const options = Array.from(this.querySelectorAll('kr-select-option')); this._highlightedIndex = options.findIndex(o => o.value === this.value); // Position the fixed dropdown relative to the trigger requestAnimationFrame(() => { const dropdown = this.shadowRoot?.querySelector('.select-dropdown'); if (dropdown) { const triggerRect = this._triggerElement.getBoundingClientRect(); dropdown.style.top = triggerRect.bottom + 4 + 'px'; dropdown.style.left = triggerRect.left + 'px'; dropdown.style.width = triggerRect.width + 'px'; } }); } } _close() { this._isOpen = false; this._highlightedIndex = -1; } _selectOption(option) { if (option.disabled) return; this.value = option.value; this._internals.setFormValue(this.value); this._updateValidity(); this.dispatchEvent(new Event('change', { bubbles: true, composed: true })); this._close(); this._triggerElement?.focus(); } _handleBlur() { this._touched = true; this._updateValidity(); } _updateValidity() { if (this.required && !this.value) { this._internals.setValidity({ valueMissing: true }, 'Please select an option', this._triggerElement); } else { this._internals.setValidity({}); } } render() { const options = Array.from(this.querySelectorAll('kr-select-option')); const selectedLabel = options.find(o => o.value === this.value)?.label; return html ` <div class=\"wrapper\"> ${this.label ? html ` <label> ${this.label} ${this.required ? html `<span class=\"required\" aria-hidden=\"true\">*</span>` : ''} </label> ` : nothing} <div class=\"select-wrapper\"> <button class=${classMap({ 'select-trigger': true, 'select-trigger--open': this._isOpen, 'select-trigger--invalid': this._touched && this.required && !this.value, })} type=\"button\" ?disabled=${this.disabled} aria-haspopup=\"listbox\" aria-expanded=${this._isOpen} @click=${this._toggle} @blur=${this._handleBlur} > <span class=${classMap({ 'select-value': true, 'select-placeholder': !selectedLabel })}> ${selectedLabel || this.placeholder} </span> <svg class=${classMap({ 'chevron-icon': true, 'select-icon': true, 'select-icon--open': this._isOpen })} viewBox=\"0 0 24 24\" fill=\"currentColor\" > <path d=\"M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6z\"/> </svg> </button> <div class=${classMap({ 'select-dropdown': true, 'hidden': !this._isOpen })} role=\"listbox\"> <div class=\"select-options\"> ${options.length === 0 ? html `<div class=\"select-empty\">No options available</div>` : options.map((option, idx) => { const isSelected = option.value === this.value; return html ` <div class=${classMap({ 'select-option': true, 'select-option--selected': isSelected, 'select-option--disabled': option.disabled, 'select-option--highlighted': idx === this._highlightedIndex, })} role=\"option\" aria-selected=${isSelected} @click=${() => this._selectOption(option)} @mouseenter=${() => (this._highlightedIndex = idx)} > ${option.label} ${isSelected ? html `<svg class=\"chevron-icon select-check\" viewBox=\"0 0 20 20\" fill=\"currentColor\"> <path fill-rule=\"evenodd\" d=\"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z\" clip-rule=\"evenodd\" /> </svg>` : nothing} </div> `; })} </div> </div> </div> ${this._touched && this.required && !this.value ? html `<div class=\"validation-message\">Please select an option</div>` : this.hint ? html `<div class=\"hint\">${this.hint}</div>` : ''} </div> <div class=\"options-slot\"> <slot @slotchange=${() => this.requestUpdate()}></slot> </div> `; } // Public methods for programmatic control focus() { this._triggerElement?.focus(); } blur() { this._triggerElement?.blur(); } }",
3552
3933
  "description": "A select dropdown component that works with native browser forms.\n\nUses ElementInternals for form association, allowing the component\nto participate in form submission, validation, and reset."
3553
3934
  }
3554
3935
  ],