@kodaris/krubble-components 1.0.25 → 1.0.26
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.
- package/custom-elements.json +43 -43
- package/dist/krubble.bundled.js +3 -0
- package/dist/krubble.bundled.js.map +1 -1
- package/dist/krubble.bundled.min.js +3 -0
- package/dist/krubble.bundled.min.js.map +1 -1
- package/dist/krubble.umd.js +3 -0
- package/dist/krubble.umd.js.map +1 -1
- package/dist/krubble.umd.min.js +3 -0
- package/dist/krubble.umd.min.js.map +1 -1
- package/dist/tabs/tab.d.ts.map +1 -1
- package/dist/tabs/tab.js +2 -0
- package/dist/tabs/tab.js.map +1 -1
- package/dist/tabs/tabs.d.ts.map +1 -1
- package/dist/tabs/tabs.js +1 -0
- package/dist/tabs/tabs.js.map +1 -1
- package/package.json +1 -1
package/custom-elements.json
CHANGED
|
@@ -1053,66 +1053,66 @@
|
|
|
1053
1053
|
},
|
|
1054
1054
|
{
|
|
1055
1055
|
"kind": "javascript-module",
|
|
1056
|
-
"path": "dist/
|
|
1056
|
+
"path": "dist/button/button.js",
|
|
1057
1057
|
"declarations": [
|
|
1058
1058
|
{
|
|
1059
1059
|
"kind": "variable",
|
|
1060
|
-
"name": "
|
|
1061
|
-
"default": "class
|
|
1062
|
-
"description": "
|
|
1060
|
+
"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; } }",
|
|
1062
|
+
"description": "A customizable button component."
|
|
1063
1063
|
}
|
|
1064
1064
|
],
|
|
1065
1065
|
"exports": [
|
|
1066
1066
|
{
|
|
1067
1067
|
"kind": "js",
|
|
1068
|
-
"name": "
|
|
1068
|
+
"name": "KRButton",
|
|
1069
1069
|
"declaration": {
|
|
1070
|
-
"name": "
|
|
1071
|
-
"module": "dist/
|
|
1070
|
+
"name": "KRButton",
|
|
1071
|
+
"module": "dist/button/button.js"
|
|
1072
1072
|
}
|
|
1073
1073
|
}
|
|
1074
1074
|
]
|
|
1075
1075
|
},
|
|
1076
1076
|
{
|
|
1077
1077
|
"kind": "javascript-module",
|
|
1078
|
-
"path": "dist/
|
|
1078
|
+
"path": "dist/context-menu/context-menu.js",
|
|
1079
1079
|
"declarations": [
|
|
1080
1080
|
{
|
|
1081
1081
|
"kind": "variable",
|
|
1082
|
-
"name": "
|
|
1083
|
-
"default": "class
|
|
1084
|
-
"description": "
|
|
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```"
|
|
1085
1085
|
}
|
|
1086
1086
|
],
|
|
1087
1087
|
"exports": [
|
|
1088
1088
|
{
|
|
1089
1089
|
"kind": "js",
|
|
1090
|
-
"name": "
|
|
1090
|
+
"name": "KRContextMenu",
|
|
1091
1091
|
"declaration": {
|
|
1092
|
-
"name": "
|
|
1093
|
-
"module": "dist/
|
|
1092
|
+
"name": "KRContextMenu",
|
|
1093
|
+
"module": "dist/context-menu/context-menu.js"
|
|
1094
1094
|
}
|
|
1095
1095
|
}
|
|
1096
1096
|
]
|
|
1097
1097
|
},
|
|
1098
1098
|
{
|
|
1099
1099
|
"kind": "javascript-module",
|
|
1100
|
-
"path": "dist/
|
|
1100
|
+
"path": "dist/code-demo/code-demo.js",
|
|
1101
1101
|
"declarations": [
|
|
1102
1102
|
{
|
|
1103
1103
|
"kind": "variable",
|
|
1104
|
-
"name": "
|
|
1105
|
-
"default": "class
|
|
1106
|
-
"description": "
|
|
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."
|
|
1107
1107
|
}
|
|
1108
1108
|
],
|
|
1109
1109
|
"exports": [
|
|
1110
1110
|
{
|
|
1111
1111
|
"kind": "js",
|
|
1112
|
-
"name": "
|
|
1112
|
+
"name": "KRCodeDemo",
|
|
1113
1113
|
"declaration": {
|
|
1114
|
-
"name": "
|
|
1115
|
-
"module": "dist/
|
|
1114
|
+
"name": "KRCodeDemo",
|
|
1115
|
+
"module": "dist/code-demo/code-demo.js"
|
|
1116
1116
|
}
|
|
1117
1117
|
}
|
|
1118
1118
|
]
|
|
@@ -3519,6 +3519,28 @@
|
|
|
3519
3519
|
}
|
|
3520
3520
|
]
|
|
3521
3521
|
},
|
|
3522
|
+
{
|
|
3523
|
+
"kind": "javascript-module",
|
|
3524
|
+
"path": "dist/form/detail-field/detail-field.js",
|
|
3525
|
+
"declarations": [
|
|
3526
|
+
{
|
|
3527
|
+
"kind": "variable",
|
|
3528
|
+
"name": "KRDetailField",
|
|
3529
|
+
"default": "class KRDetailField extends LitElement { constructor() { super(...arguments); /** * The field label text */ this.label = ''; /** * The value to display */ this.value = ''; } render() { return html ` <div class=\"wrapper\"> ${this.label ? html `<label>${this.label}</label>` : nothing} <div class=\"value\">${this.value}</div> </div> `; } }",
|
|
3530
|
+
"description": "A read-only field component that displays a label and value."
|
|
3531
|
+
}
|
|
3532
|
+
],
|
|
3533
|
+
"exports": [
|
|
3534
|
+
{
|
|
3535
|
+
"kind": "js",
|
|
3536
|
+
"name": "KRDetailField",
|
|
3537
|
+
"declaration": {
|
|
3538
|
+
"name": "KRDetailField",
|
|
3539
|
+
"module": "dist/form/detail-field/detail-field.js"
|
|
3540
|
+
}
|
|
3541
|
+
}
|
|
3542
|
+
]
|
|
3543
|
+
},
|
|
3522
3544
|
{
|
|
3523
3545
|
"kind": "javascript-module",
|
|
3524
3546
|
"path": "dist/form/select-field/select-field.js",
|
|
@@ -3607,28 +3629,6 @@
|
|
|
3607
3629
|
}
|
|
3608
3630
|
]
|
|
3609
3631
|
},
|
|
3610
|
-
{
|
|
3611
|
-
"kind": "javascript-module",
|
|
3612
|
-
"path": "dist/form/detail-field/detail-field.js",
|
|
3613
|
-
"declarations": [
|
|
3614
|
-
{
|
|
3615
|
-
"kind": "variable",
|
|
3616
|
-
"name": "KRDetailField",
|
|
3617
|
-
"default": "class KRDetailField extends LitElement { constructor() { super(...arguments); /** * The field label text */ this.label = ''; /** * The value to display */ this.value = ''; } render() { return html ` <div class=\"wrapper\"> ${this.label ? html `<label>${this.label}</label>` : nothing} <div class=\"value\">${this.value}</div> </div> `; } }",
|
|
3618
|
-
"description": "A read-only field component that displays a label and value."
|
|
3619
|
-
}
|
|
3620
|
-
],
|
|
3621
|
-
"exports": [
|
|
3622
|
-
{
|
|
3623
|
-
"kind": "js",
|
|
3624
|
-
"name": "KRDetailField",
|
|
3625
|
-
"declaration": {
|
|
3626
|
-
"name": "KRDetailField",
|
|
3627
|
-
"module": "dist/form/detail-field/detail-field.js"
|
|
3628
|
-
}
|
|
3629
|
-
}
|
|
3630
|
-
]
|
|
3631
|
-
},
|
|
3632
3632
|
{
|
|
3633
3633
|
"kind": "javascript-module",
|
|
3634
3634
|
"path": "src/form/detail-field/detail-field.ts",
|
package/dist/krubble.bundled.js
CHANGED
|
@@ -1960,6 +1960,7 @@ KRTabGroup.styles = [
|
|
|
1960
1960
|
:host {
|
|
1961
1961
|
display: flex;
|
|
1962
1962
|
flex-direction: column;
|
|
1963
|
+
overflow: hidden;
|
|
1963
1964
|
}
|
|
1964
1965
|
|
|
1965
1966
|
.header {
|
|
@@ -2171,6 +2172,8 @@ KRTab.styles = [
|
|
|
2171
2172
|
|
|
2172
2173
|
:host([active]) {
|
|
2173
2174
|
display: block;
|
|
2175
|
+
width: 100%;
|
|
2176
|
+
height: 100%;
|
|
2174
2177
|
}
|
|
2175
2178
|
`,
|
|
2176
2179
|
];
|