@kodaris/krubble-components 1.0.9 → 1.0.10
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 +727 -57
- package/dist/button/button.d.ts +14 -0
- package/dist/button/button.d.ts.map +1 -1
- package/dist/button/button.js +120 -3
- package/dist/button/button.js.map +1 -1
- package/dist/form/text-field/text-field.js +2 -2
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/krubble.bundled.js +1311 -56
- package/dist/krubble.bundled.js.map +1 -1
- package/dist/krubble.bundled.min.js +762 -76
- package/dist/krubble.bundled.min.js.map +1 -1
- package/dist/krubble.umd.js +1310 -55
- package/dist/krubble.umd.js.map +1 -1
- package/dist/krubble.umd.min.js +754 -68
- package/dist/krubble.umd.min.js.map +1 -1
- package/dist/table/table.d.ts +253 -0
- package/dist/table/table.d.ts.map +1 -0
- package/dist/table/table.js +1146 -0
- package/dist/table/table.js.map +1 -0
- package/dist/tabs/tabs.d.ts.map +1 -1
- package/dist/tabs/tabs.js +2 -0
- package/dist/tabs/tabs.js.map +1 -1
- package/package.json +5 -1
package/dist/krubble.umd.js
CHANGED
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
96
96
|
*/function e$3(e,r){return (n,s,i)=>{const o=t=>t.renderRoot?.querySelector(e)??null;return e$4(n,s,{get(){return o(this)}})}}
|
|
97
97
|
|
|
98
|
-
var __decorate$
|
|
98
|
+
var __decorate$c = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
99
99
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
100
100
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
101
101
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -202,13 +202,13 @@
|
|
|
202
202
|
padding: 16px 16px 8px 16px;
|
|
203
203
|
}
|
|
204
204
|
`;
|
|
205
|
-
__decorate$
|
|
205
|
+
__decorate$c([
|
|
206
206
|
n$1({ type: String })
|
|
207
207
|
], exports.KRAccordion.prototype, "header", void 0);
|
|
208
|
-
__decorate$
|
|
208
|
+
__decorate$c([
|
|
209
209
|
n$1({ type: Boolean, reflect: true })
|
|
210
210
|
], exports.KRAccordion.prototype, "expanded", void 0);
|
|
211
|
-
exports.KRAccordion = __decorate$
|
|
211
|
+
exports.KRAccordion = __decorate$c([
|
|
212
212
|
t$1('kr-accordion')
|
|
213
213
|
], exports.KRAccordion);
|
|
214
214
|
|
|
@@ -225,7 +225,7 @@
|
|
|
225
225
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
226
226
|
*/const e$1=e$2(class extends i$1{constructor(t$1){if(super(t$1),t$1.type!==t.ATTRIBUTE||"class"!==t$1.name||t$1.strings?.length>2)throw Error("`classMap()` can only be used in the `class` attribute and must be the only part in the attribute.")}render(t){return " "+Object.keys(t).filter(s=>t[s]).join(" ")+" "}update(s,[i]){if(void 0===this.st){this.st=new Set,void 0!==s.strings&&(this.nt=new Set(s.strings.join(" ").split(/\s/).filter(t=>""!==t)));for(const t in i)i[t]&&!this.nt?.has(t)&&this.st.add(t);return this.render(i)}const r=s.element.classList;for(const t of this.st)t in i||(r.remove(t),this.st.delete(t));for(const t in i){const s=!!i[t];s===this.st.has(t)||this.nt?.has(t)||(s?(r.add(t),this.st.add(t)):(r.remove(t),this.st.delete(t)));}return E}});
|
|
227
227
|
|
|
228
|
-
var __decorate$
|
|
228
|
+
var __decorate$b = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
229
229
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
230
230
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
231
231
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -409,23 +409,23 @@
|
|
|
409
409
|
outline-offset: 2px;
|
|
410
410
|
}
|
|
411
411
|
`;
|
|
412
|
-
__decorate$
|
|
412
|
+
__decorate$b([
|
|
413
413
|
n$1({ type: String })
|
|
414
414
|
], exports.KRAlert.prototype, "type", void 0);
|
|
415
|
-
__decorate$
|
|
415
|
+
__decorate$b([
|
|
416
416
|
n$1({ type: String })
|
|
417
417
|
], exports.KRAlert.prototype, "header", void 0);
|
|
418
|
-
__decorate$
|
|
418
|
+
__decorate$b([
|
|
419
419
|
n$1({ type: Boolean })
|
|
420
420
|
], exports.KRAlert.prototype, "dismissible", void 0);
|
|
421
|
-
__decorate$
|
|
421
|
+
__decorate$b([
|
|
422
422
|
n$1({ type: Boolean })
|
|
423
423
|
], exports.KRAlert.prototype, "visible", void 0);
|
|
424
|
-
exports.KRAlert = __decorate$
|
|
424
|
+
exports.KRAlert = __decorate$b([
|
|
425
425
|
t$1('kr-alert')
|
|
426
426
|
], exports.KRAlert);
|
|
427
427
|
|
|
428
|
-
var __decorate$
|
|
428
|
+
var __decorate$a = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
429
429
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
430
430
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
431
431
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -436,6 +436,7 @@
|
|
|
436
436
|
*
|
|
437
437
|
* @slot - The button content
|
|
438
438
|
* @fires click - Fired when the button is clicked
|
|
439
|
+
* @fires option-select - Fired when a dropdown option is selected
|
|
439
440
|
*/
|
|
440
441
|
exports.KRButton = class KRButton extends i$2 {
|
|
441
442
|
constructor() {
|
|
@@ -456,12 +457,36 @@
|
|
|
456
457
|
* Whether the button is disabled
|
|
457
458
|
*/
|
|
458
459
|
this.disabled = false;
|
|
460
|
+
/**
|
|
461
|
+
* Dropdown options - when provided, button becomes a dropdown
|
|
462
|
+
*/
|
|
463
|
+
this.options = [];
|
|
459
464
|
this._state = 'idle';
|
|
460
465
|
this._stateText = '';
|
|
466
|
+
this._dropdownOpen = false;
|
|
467
|
+
this._handleHostClick = (e) => {
|
|
468
|
+
if (this.options.length) {
|
|
469
|
+
e.stopPropagation();
|
|
470
|
+
this._toggleDropdown();
|
|
471
|
+
}
|
|
472
|
+
};
|
|
461
473
|
this._handleKeydown = (e) => {
|
|
462
474
|
if (e.key === 'Enter' || e.key === ' ') {
|
|
463
475
|
e.preventDefault();
|
|
464
|
-
this.
|
|
476
|
+
if (this.options.length) {
|
|
477
|
+
this._toggleDropdown();
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
this.click();
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
if (e.key === 'Escape' && this._dropdownOpen) {
|
|
484
|
+
this._dropdownOpen = false;
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
this._handleClickOutside = (e) => {
|
|
488
|
+
if (this._dropdownOpen && !this.contains(e.target)) {
|
|
489
|
+
this._dropdownOpen = false;
|
|
465
490
|
}
|
|
466
491
|
};
|
|
467
492
|
}
|
|
@@ -470,10 +495,26 @@
|
|
|
470
495
|
this.setAttribute('role', 'button');
|
|
471
496
|
this.setAttribute('tabindex', '0');
|
|
472
497
|
this.addEventListener('keydown', this._handleKeydown);
|
|
498
|
+
this.addEventListener('click', this._handleHostClick);
|
|
499
|
+
document.addEventListener('click', this._handleClickOutside);
|
|
473
500
|
}
|
|
474
501
|
disconnectedCallback() {
|
|
475
502
|
super.disconnectedCallback();
|
|
476
503
|
this.removeEventListener('keydown', this._handleKeydown);
|
|
504
|
+
this.removeEventListener('click', this._handleHostClick);
|
|
505
|
+
document.removeEventListener('click', this._handleClickOutside);
|
|
506
|
+
}
|
|
507
|
+
_toggleDropdown() {
|
|
508
|
+
this._dropdownOpen = !this._dropdownOpen;
|
|
509
|
+
}
|
|
510
|
+
_handleOptionClick(option, e) {
|
|
511
|
+
e.stopPropagation();
|
|
512
|
+
this._dropdownOpen = false;
|
|
513
|
+
this.dispatchEvent(new CustomEvent('option-select', {
|
|
514
|
+
detail: { id: option.id, label: option.label },
|
|
515
|
+
bubbles: true,
|
|
516
|
+
composed: true
|
|
517
|
+
}));
|
|
477
518
|
}
|
|
478
519
|
/**
|
|
479
520
|
* Shows a loading spinner and disables the button.
|
|
@@ -530,15 +571,27 @@
|
|
|
530
571
|
this.classList.toggle('kr-button--large', this.size === 'large');
|
|
531
572
|
}
|
|
532
573
|
render() {
|
|
574
|
+
const hasOptions = this.options.length > 0;
|
|
533
575
|
return b `
|
|
534
576
|
<slot></slot>
|
|
577
|
+
${hasOptions ? 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}
|
|
535
578
|
${this._state !== 'idle'
|
|
536
579
|
? b `<span class="state-overlay">
|
|
537
580
|
${this._state === 'loading'
|
|
538
581
|
? b `<span class="spinner"></span>`
|
|
539
582
|
: this._stateText}
|
|
540
583
|
</span>`
|
|
541
|
-
:
|
|
584
|
+
: A}
|
|
585
|
+
${hasOptions ? b `
|
|
586
|
+
<div class="dropdown ${this._dropdownOpen ? 'open' : ''}">
|
|
587
|
+
${this.options.map(option => b `
|
|
588
|
+
<button
|
|
589
|
+
class="dropdown-item"
|
|
590
|
+
@click=${(e) => this._handleOptionClick(option, e)}
|
|
591
|
+
>${option.label}</button>
|
|
592
|
+
`)}
|
|
593
|
+
</div>
|
|
594
|
+
` : A}
|
|
542
595
|
`;
|
|
543
596
|
}
|
|
544
597
|
};
|
|
@@ -687,26 +740,90 @@
|
|
|
687
740
|
height: 16px;
|
|
688
741
|
border-width: 3px;
|
|
689
742
|
}
|
|
743
|
+
|
|
744
|
+
/* Dropdown */
|
|
745
|
+
.dropdown {
|
|
746
|
+
position: absolute;
|
|
747
|
+
top: 100%;
|
|
748
|
+
left: 0;
|
|
749
|
+
margin-top: 4px;
|
|
750
|
+
min-width: 100%;
|
|
751
|
+
background: white;
|
|
752
|
+
border: 1px solid #9ba7b6;
|
|
753
|
+
border-radius: 8px;
|
|
754
|
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
|
755
|
+
padding: 8px 0;
|
|
756
|
+
z-index: 100;
|
|
757
|
+
display: none;
|
|
758
|
+
transform-origin: top;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
.dropdown.open {
|
|
762
|
+
display: block;
|
|
763
|
+
animation: dropdown-fade-in 150ms ease-out;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
@keyframes dropdown-fade-in {
|
|
767
|
+
from {
|
|
768
|
+
opacity: 0;
|
|
769
|
+
transform: translateY(-4px);
|
|
770
|
+
}
|
|
771
|
+
to {
|
|
772
|
+
opacity: 1;
|
|
773
|
+
transform: translateY(0);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
.dropdown-item {
|
|
778
|
+
display: block;
|
|
779
|
+
width: 100%;
|
|
780
|
+
padding: 8px 16px;
|
|
781
|
+
text-align: left;
|
|
782
|
+
background: none;
|
|
783
|
+
border: none;
|
|
784
|
+
font-size: 14px;
|
|
785
|
+
color: #374151;
|
|
786
|
+
cursor: pointer;
|
|
787
|
+
font-family: inherit;
|
|
788
|
+
white-space: nowrap;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
.dropdown-item:hover {
|
|
792
|
+
background: #f3f4f6;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
/* Caret for dropdown button */
|
|
796
|
+
.caret {
|
|
797
|
+
margin-left: 4px;
|
|
798
|
+
margin-right: -6px;
|
|
799
|
+
display: flex;
|
|
800
|
+
}
|
|
690
801
|
`;
|
|
691
|
-
__decorate$
|
|
802
|
+
__decorate$a([
|
|
692
803
|
n$1({ type: String, reflect: true })
|
|
693
804
|
], exports.KRButton.prototype, "variant", void 0);
|
|
694
|
-
__decorate$
|
|
805
|
+
__decorate$a([
|
|
695
806
|
n$1({ type: String, reflect: true })
|
|
696
807
|
], exports.KRButton.prototype, "color", void 0);
|
|
697
|
-
__decorate$
|
|
808
|
+
__decorate$a([
|
|
698
809
|
n$1({ type: String, reflect: true })
|
|
699
810
|
], exports.KRButton.prototype, "size", void 0);
|
|
700
|
-
__decorate$
|
|
811
|
+
__decorate$a([
|
|
701
812
|
n$1({ type: Boolean, reflect: true })
|
|
702
813
|
], exports.KRButton.prototype, "disabled", void 0);
|
|
703
|
-
__decorate$
|
|
814
|
+
__decorate$a([
|
|
815
|
+
n$1({ type: Array })
|
|
816
|
+
], exports.KRButton.prototype, "options", void 0);
|
|
817
|
+
__decorate$a([
|
|
704
818
|
r$1()
|
|
705
819
|
], exports.KRButton.prototype, "_state", void 0);
|
|
706
|
-
__decorate$
|
|
820
|
+
__decorate$a([
|
|
707
821
|
r$1()
|
|
708
822
|
], exports.KRButton.prototype, "_stateText", void 0);
|
|
709
|
-
|
|
823
|
+
__decorate$a([
|
|
824
|
+
r$1()
|
|
825
|
+
], exports.KRButton.prototype, "_dropdownOpen", void 0);
|
|
826
|
+
exports.KRButton = __decorate$a([
|
|
710
827
|
t$1('kr-button')
|
|
711
828
|
], exports.KRButton);
|
|
712
829
|
|
|
@@ -716,7 +833,7 @@
|
|
|
716
833
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
717
834
|
*/class e extends i$1{constructor(i){if(super(i),this.it=A,i.type!==t.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(r){if(r===A||null==r)return this._t=void 0,this.it=r;if(r===E)return r;if("string"!=typeof r)throw Error(this.constructor.directiveName+"() called with a non-string value");if(r===this.it)return this._t;this.it=r;const s=[r];return s.raw=s,this._t={_$litType$:this.constructor.resultType,strings:s,values:[]}}}e.directiveName="unsafeHTML",e.resultType=1;const o$2=e$2(e);
|
|
718
835
|
|
|
719
|
-
var __decorate$
|
|
836
|
+
var __decorate$9 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
720
837
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
721
838
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
722
839
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -973,23 +1090,23 @@
|
|
|
973
1090
|
color: #fab387;
|
|
974
1091
|
}
|
|
975
1092
|
`;
|
|
976
|
-
__decorate$
|
|
1093
|
+
__decorate$9([
|
|
977
1094
|
n$1({ type: String })
|
|
978
1095
|
], exports.KRCodeDemo.prototype, "language", void 0);
|
|
979
|
-
__decorate$
|
|
1096
|
+
__decorate$9([
|
|
980
1097
|
n$1({ type: String })
|
|
981
1098
|
], exports.KRCodeDemo.prototype, "code", void 0);
|
|
982
|
-
__decorate$
|
|
1099
|
+
__decorate$9([
|
|
983
1100
|
r$1()
|
|
984
1101
|
], exports.KRCodeDemo.prototype, "activeTab", void 0);
|
|
985
|
-
__decorate$
|
|
1102
|
+
__decorate$9([
|
|
986
1103
|
r$1()
|
|
987
1104
|
], exports.KRCodeDemo.prototype, "copied", void 0);
|
|
988
|
-
exports.KRCodeDemo = __decorate$
|
|
1105
|
+
exports.KRCodeDemo = __decorate$9([
|
|
989
1106
|
t$1('kr-code-demo')
|
|
990
1107
|
], exports.KRCodeDemo);
|
|
991
1108
|
|
|
992
|
-
var __decorate$
|
|
1109
|
+
var __decorate$8 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
993
1110
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
994
1111
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
995
1112
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -1158,14 +1275,14 @@
|
|
|
1158
1275
|
margin: 4px 0;
|
|
1159
1276
|
}
|
|
1160
1277
|
`;
|
|
1161
|
-
__decorate$
|
|
1278
|
+
__decorate$8([
|
|
1162
1279
|
r$1()
|
|
1163
1280
|
], exports.KRContextMenu.prototype, "items", void 0);
|
|
1164
|
-
exports.KRContextMenu = __decorate$
|
|
1281
|
+
exports.KRContextMenu = __decorate$8([
|
|
1165
1282
|
t$1('kr-context-menu')
|
|
1166
1283
|
], exports.KRContextMenu);
|
|
1167
1284
|
|
|
1168
|
-
var __decorate$
|
|
1285
|
+
var __decorate$7 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
1169
1286
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1170
1287
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1171
1288
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -1297,14 +1414,14 @@
|
|
|
1297
1414
|
overflow: auto;
|
|
1298
1415
|
}
|
|
1299
1416
|
`;
|
|
1300
|
-
__decorate$
|
|
1417
|
+
__decorate$7([
|
|
1301
1418
|
r$1()
|
|
1302
1419
|
], exports.KRDialog.prototype, "contentElement", void 0);
|
|
1303
|
-
exports.KRDialog = __decorate$
|
|
1420
|
+
exports.KRDialog = __decorate$7([
|
|
1304
1421
|
t$1('kr-dialog')
|
|
1305
1422
|
], exports.KRDialog);
|
|
1306
1423
|
|
|
1307
|
-
var __decorate$
|
|
1424
|
+
var __decorate$6 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
1308
1425
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1309
1426
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1310
1427
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -1601,19 +1718,19 @@
|
|
|
1601
1718
|
`;
|
|
1602
1719
|
/** Track active snackbars for stacking */
|
|
1603
1720
|
exports.KRSnackbar.activeSnackbars = [];
|
|
1604
|
-
__decorate$
|
|
1721
|
+
__decorate$6([
|
|
1605
1722
|
n$1({ type: String })
|
|
1606
1723
|
], exports.KRSnackbar.prototype, "type", void 0);
|
|
1607
|
-
__decorate$
|
|
1724
|
+
__decorate$6([
|
|
1608
1725
|
n$1({ type: String })
|
|
1609
1726
|
], exports.KRSnackbar.prototype, "title", void 0);
|
|
1610
|
-
__decorate$
|
|
1727
|
+
__decorate$6([
|
|
1611
1728
|
n$1({ type: String })
|
|
1612
1729
|
], exports.KRSnackbar.prototype, "message", void 0);
|
|
1613
|
-
__decorate$
|
|
1730
|
+
__decorate$6([
|
|
1614
1731
|
n$1({ type: Number })
|
|
1615
1732
|
], exports.KRSnackbar.prototype, "duration", void 0);
|
|
1616
|
-
exports.KRSnackbar = KRSnackbar_1 = __decorate$
|
|
1733
|
+
exports.KRSnackbar = KRSnackbar_1 = __decorate$6([
|
|
1617
1734
|
t$1('kr-snackbar')
|
|
1618
1735
|
], exports.KRSnackbar);
|
|
1619
1736
|
|
|
@@ -1623,7 +1740,7 @@
|
|
|
1623
1740
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
1624
1741
|
*/const n="important",i=" !"+n,o$1=e$2(class extends i$1{constructor(t$1){if(super(t$1),t$1.type!==t.ATTRIBUTE||"style"!==t$1.name||t$1.strings?.length>2)throw Error("The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.")}render(t){return Object.keys(t).reduce((e,r)=>{const s=t[r];return null==s?e:e+`${r=r.includes("-")?r:r.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g,"-$&").toLowerCase()}:${s};`},"")}update(e,[r]){const{style:s}=e.element;if(void 0===this.ft)return this.ft=new Set(Object.keys(r)),this.render(r);for(const t of this.ft)null==r[t]&&(this.ft.delete(t),t.includes("-")?s.removeProperty(t):s[t]=null);for(const t in r){const e=r[t];if(null!=e){this.ft.add(t);const r="string"==typeof e&&e.endsWith(i);t.includes("-")||r?s.setProperty(t,r?e.slice(0,-11):e,r?n:""):s[t]=e;}}return E}});
|
|
1625
1742
|
|
|
1626
|
-
var __decorate$
|
|
1743
|
+
var __decorate$5 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
1627
1744
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1628
1745
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1629
1746
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -1798,7 +1915,9 @@
|
|
|
1798
1915
|
}
|
|
1799
1916
|
|
|
1800
1917
|
.header {
|
|
1918
|
+
height: 44px;
|
|
1801
1919
|
display: flex;
|
|
1920
|
+
flex-shrink: 0;
|
|
1802
1921
|
align-items: stretch;
|
|
1803
1922
|
border-bottom: 1px solid #e5e7eb;
|
|
1804
1923
|
overflow-x: auto;
|
|
@@ -1923,20 +2042,20 @@
|
|
|
1923
2042
|
}
|
|
1924
2043
|
`,
|
|
1925
2044
|
];
|
|
1926
|
-
__decorate$
|
|
2045
|
+
__decorate$5([
|
|
1927
2046
|
n$1({ type: String, attribute: 'active-tab-id' })
|
|
1928
2047
|
], exports.KRTabGroup.prototype, "activeTabId", void 0);
|
|
1929
|
-
__decorate$
|
|
2048
|
+
__decorate$5([
|
|
1930
2049
|
n$1({ type: Boolean })
|
|
1931
2050
|
], exports.KRTabGroup.prototype, "justified", void 0);
|
|
1932
|
-
__decorate$
|
|
2051
|
+
__decorate$5([
|
|
1933
2052
|
n$1({ type: String, reflect: true })
|
|
1934
2053
|
], exports.KRTabGroup.prototype, "size", void 0);
|
|
1935
|
-
exports.KRTabGroup = __decorate$
|
|
2054
|
+
exports.KRTabGroup = __decorate$5([
|
|
1936
2055
|
t$1('kr-tab-group')
|
|
1937
2056
|
], exports.KRTabGroup);
|
|
1938
2057
|
|
|
1939
|
-
var __decorate$
|
|
2058
|
+
var __decorate$4 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
1940
2059
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
1941
2060
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
1942
2061
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
@@ -2007,34 +2126,1170 @@
|
|
|
2007
2126
|
}
|
|
2008
2127
|
`,
|
|
2009
2128
|
];
|
|
2010
|
-
__decorate$
|
|
2129
|
+
__decorate$4([
|
|
2011
2130
|
n$1({ type: String, reflect: true })
|
|
2012
2131
|
], exports.KRTab.prototype, "id", void 0);
|
|
2013
|
-
__decorate$
|
|
2132
|
+
__decorate$4([
|
|
2014
2133
|
n$1({ type: String })
|
|
2015
2134
|
], exports.KRTab.prototype, "title", void 0);
|
|
2016
|
-
__decorate$
|
|
2135
|
+
__decorate$4([
|
|
2017
2136
|
n$1({ type: String })
|
|
2018
2137
|
], exports.KRTab.prototype, "badge", void 0);
|
|
2019
|
-
__decorate$
|
|
2138
|
+
__decorate$4([
|
|
2020
2139
|
n$1({ type: String, attribute: 'badge-background' })
|
|
2021
2140
|
], exports.KRTab.prototype, "badgeBackground", void 0);
|
|
2022
|
-
__decorate$
|
|
2141
|
+
__decorate$4([
|
|
2023
2142
|
n$1({ type: String, attribute: 'badge-color' })
|
|
2024
2143
|
], exports.KRTab.prototype, "badgeColor", void 0);
|
|
2025
|
-
__decorate$
|
|
2144
|
+
__decorate$4([
|
|
2026
2145
|
n$1({ type: Boolean })
|
|
2027
2146
|
], exports.KRTab.prototype, "disabled", void 0);
|
|
2028
|
-
__decorate$
|
|
2147
|
+
__decorate$4([
|
|
2029
2148
|
n$1({ type: Boolean })
|
|
2030
2149
|
], exports.KRTab.prototype, "dismissible", void 0);
|
|
2031
|
-
__decorate$
|
|
2150
|
+
__decorate$4([
|
|
2032
2151
|
n$1({ type: Boolean, reflect: true })
|
|
2033
2152
|
], exports.KRTab.prototype, "active", void 0);
|
|
2034
|
-
exports.KRTab = __decorate$
|
|
2153
|
+
exports.KRTab = __decorate$4([
|
|
2035
2154
|
t$1('kr-tab')
|
|
2036
2155
|
], exports.KRTab);
|
|
2037
2156
|
|
|
2157
|
+
var __decorate$3 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
2158
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2159
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2160
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2161
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2162
|
+
};
|
|
2163
|
+
// === Solr Utilities ===
|
|
2164
|
+
const SOLR_RESERVED_CHARS = [
|
|
2165
|
+
'"', '+', '-', '&&', '||', '!', '(', ')', '{',
|
|
2166
|
+
'}', '[', ']', '^', '~', '*', '?', ':'
|
|
2167
|
+
];
|
|
2168
|
+
const SOLR_RESERVED_CHARS_REPLACEMENT = [
|
|
2169
|
+
'\\"', '\\+', '\\-', '\\&\\&', '\\|\\|', '\\!', '\\(', '\\)', '\\{',
|
|
2170
|
+
'\\}', '\\[', '\\]', '\\^', '\\~', '\\*', '\\?', '\\:'
|
|
2171
|
+
];
|
|
2172
|
+
function escapeSolrQuery(query) {
|
|
2173
|
+
let escaped = query;
|
|
2174
|
+
for (let i = 0; i < SOLR_RESERVED_CHARS.length; i++) {
|
|
2175
|
+
escaped = escaped.split(SOLR_RESERVED_CHARS[i]).join(SOLR_RESERVED_CHARS_REPLACEMENT[i]);
|
|
2176
|
+
}
|
|
2177
|
+
return escaped;
|
|
2178
|
+
}
|
|
2179
|
+
exports.KRTable = class KRTable extends i$2 {
|
|
2180
|
+
constructor() {
|
|
2181
|
+
super(...arguments);
|
|
2182
|
+
/**
|
|
2183
|
+
* Internal flag to switch between scroll edge modes:
|
|
2184
|
+
* - 'overlay': Fixed padding with overlay elements that hide content at edges (scrollbar at viewport edge)
|
|
2185
|
+
* - 'edge': Padding scrolls with content, allowing table to reach edges when scrolling
|
|
2186
|
+
*/
|
|
2187
|
+
this._scrollStyle = 'edge';
|
|
2188
|
+
this._data = [];
|
|
2189
|
+
this._dataState = 'idle';
|
|
2190
|
+
this._page = 1;
|
|
2191
|
+
this._pageSize = 50;
|
|
2192
|
+
this._totalItems = 0;
|
|
2193
|
+
this._totalPages = 0;
|
|
2194
|
+
this._searchQuery = '';
|
|
2195
|
+
this._canScrollLeft = false;
|
|
2196
|
+
this._canScrollRight = false;
|
|
2197
|
+
this._canScrollHorizontal = false;
|
|
2198
|
+
this._columnPickerOpen = false;
|
|
2199
|
+
this._displayedColumns = [];
|
|
2200
|
+
this._columnWidths = new Map();
|
|
2201
|
+
this._resizing = null;
|
|
2202
|
+
this._resizeObserver = null;
|
|
2203
|
+
this._searchPositionLocked = false;
|
|
2204
|
+
this.def = { columns: [] };
|
|
2205
|
+
this._handleClickOutsideColumnPicker = (e) => {
|
|
2206
|
+
if (!this._columnPickerOpen)
|
|
2207
|
+
return;
|
|
2208
|
+
const path = e.composedPath();
|
|
2209
|
+
const picker = this.shadowRoot?.querySelector('.column-picker-wrapper');
|
|
2210
|
+
if (picker && !path.includes(picker)) {
|
|
2211
|
+
this._columnPickerOpen = false;
|
|
2212
|
+
}
|
|
2213
|
+
};
|
|
2214
|
+
this._handleResizeMove = (e) => {
|
|
2215
|
+
if (!this._resizing)
|
|
2216
|
+
return;
|
|
2217
|
+
this._columnWidths.set(this._resizing.columnId, Math.max(50, this._resizing.startWidth + (e.clientX - this._resizing.startX)));
|
|
2218
|
+
this.requestUpdate();
|
|
2219
|
+
};
|
|
2220
|
+
this._handleResizeEnd = () => {
|
|
2221
|
+
this._resizing = null;
|
|
2222
|
+
document.removeEventListener('mousemove', this._handleResizeMove);
|
|
2223
|
+
document.removeEventListener('mouseup', this._handleResizeEnd);
|
|
2224
|
+
};
|
|
2225
|
+
}
|
|
2226
|
+
connectedCallback() {
|
|
2227
|
+
super.connectedCallback();
|
|
2228
|
+
this.classList.toggle('kr-table--scroll-overlay', this._scrollStyle === 'overlay');
|
|
2229
|
+
this.classList.toggle('kr-table--scroll-edge', this._scrollStyle === 'edge');
|
|
2230
|
+
this._fetch();
|
|
2231
|
+
this._initRefresh();
|
|
2232
|
+
document.addEventListener('click', this._handleClickOutsideColumnPicker);
|
|
2233
|
+
this._resizeObserver = new ResizeObserver(() => {
|
|
2234
|
+
// Unlock and recalculate on resize since layout changes
|
|
2235
|
+
this._searchPositionLocked = false;
|
|
2236
|
+
this._updateSearchPosition();
|
|
2237
|
+
});
|
|
2238
|
+
this._resizeObserver.observe(this);
|
|
2239
|
+
}
|
|
2240
|
+
disconnectedCallback() {
|
|
2241
|
+
super.disconnectedCallback();
|
|
2242
|
+
clearInterval(this._refreshTimer);
|
|
2243
|
+
document.removeEventListener('click', this._handleClickOutsideColumnPicker);
|
|
2244
|
+
this._resizeObserver?.disconnect();
|
|
2245
|
+
}
|
|
2246
|
+
updated(changedProperties) {
|
|
2247
|
+
if (changedProperties.has('def')) {
|
|
2248
|
+
this._displayedColumns = this.def.displayedColumns || this.def.columns.map(c => c.id);
|
|
2249
|
+
this._fetch();
|
|
2250
|
+
this._initRefresh();
|
|
2251
|
+
}
|
|
2252
|
+
this._updateScrollFlags();
|
|
2253
|
+
}
|
|
2254
|
+
// ----------------------------------------------------------------------------
|
|
2255
|
+
// Public Interface
|
|
2256
|
+
// ----------------------------------------------------------------------------
|
|
2257
|
+
refresh() {
|
|
2258
|
+
this._fetch();
|
|
2259
|
+
}
|
|
2260
|
+
goToPrevPage() {
|
|
2261
|
+
if (this._page > 1) {
|
|
2262
|
+
this._page--;
|
|
2263
|
+
this._fetch();
|
|
2264
|
+
}
|
|
2265
|
+
}
|
|
2266
|
+
goToNextPage() {
|
|
2267
|
+
if (this._page < this._totalPages) {
|
|
2268
|
+
this._page++;
|
|
2269
|
+
this._fetch();
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
goToPage(page) {
|
|
2273
|
+
if (page >= 1 && page <= this._totalPages) {
|
|
2274
|
+
this._page = page;
|
|
2275
|
+
this._fetch();
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
// ----------------------------------------------------------------------------
|
|
2279
|
+
// Data Fetching
|
|
2280
|
+
// ----------------------------------------------------------------------------
|
|
2281
|
+
/**
|
|
2282
|
+
* Fetches data from the API and updates the table.
|
|
2283
|
+
* Shows a loading spinner while fetching, then displays rows on success
|
|
2284
|
+
* or an error snackbar on failure.
|
|
2285
|
+
* Request/response format depends on dataSource.mode (solr, opensearch, db).
|
|
2286
|
+
*/
|
|
2287
|
+
_fetch() {
|
|
2288
|
+
if (!this.def.dataSource)
|
|
2289
|
+
return;
|
|
2290
|
+
this._dataState = 'loading';
|
|
2291
|
+
// Build request based on mode
|
|
2292
|
+
let request;
|
|
2293
|
+
switch (this.def.dataSource.mode) {
|
|
2294
|
+
case 'opensearch':
|
|
2295
|
+
throw Error('Opensearch not supported yet');
|
|
2296
|
+
case 'db':
|
|
2297
|
+
throw Error('DB not supported yet');
|
|
2298
|
+
default: // solr
|
|
2299
|
+
request = {
|
|
2300
|
+
page: this._page - 1,
|
|
2301
|
+
size: this._pageSize,
|
|
2302
|
+
sorts: [],
|
|
2303
|
+
filterFields: [],
|
|
2304
|
+
queryFields: [],
|
|
2305
|
+
facetFields: []
|
|
2306
|
+
};
|
|
2307
|
+
if (this._searchQuery?.trim().length) {
|
|
2308
|
+
request.queryFields.push({
|
|
2309
|
+
name: '_text_',
|
|
2310
|
+
operation: 'IS',
|
|
2311
|
+
value: escapeSolrQuery(this._searchQuery)
|
|
2312
|
+
});
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
this.def.dataSource.fetch(request)
|
|
2316
|
+
.then(response => {
|
|
2317
|
+
// Parse response based on mode
|
|
2318
|
+
switch (this.def.dataSource?.mode) {
|
|
2319
|
+
case 'opensearch': {
|
|
2320
|
+
throw Error('Opensearch not supported yet');
|
|
2321
|
+
}
|
|
2322
|
+
case 'db': {
|
|
2323
|
+
throw Error('DB not supported yet');
|
|
2324
|
+
}
|
|
2325
|
+
default: { // solr
|
|
2326
|
+
const res = response;
|
|
2327
|
+
this._data = res.data.content;
|
|
2328
|
+
this._totalItems = res.data.totalElements;
|
|
2329
|
+
this._totalPages = res.data.totalPages;
|
|
2330
|
+
this._pageSize = res.data.size;
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
this._dataState = 'success';
|
|
2334
|
+
this._updateSearchPosition();
|
|
2335
|
+
})
|
|
2336
|
+
.catch(err => {
|
|
2337
|
+
this._dataState = 'error';
|
|
2338
|
+
exports.KRSnackbar.show({
|
|
2339
|
+
message: err instanceof Error ? err.message : 'Failed to load data',
|
|
2340
|
+
type: 'error'
|
|
2341
|
+
});
|
|
2342
|
+
});
|
|
2343
|
+
}
|
|
2344
|
+
/**
|
|
2345
|
+
* Sets up auto-refresh so the table automatically fetches fresh data
|
|
2346
|
+
* at a regular interval (useful for dashboards, monitoring views).
|
|
2347
|
+
* Configured via def.refreshInterval in milliseconds.
|
|
2348
|
+
*/
|
|
2349
|
+
_initRefresh() {
|
|
2350
|
+
clearInterval(this._refreshTimer);
|
|
2351
|
+
if (this.def.refreshInterval && this.def.refreshInterval > 0) {
|
|
2352
|
+
this._refreshTimer = window.setInterval(() => {
|
|
2353
|
+
this._fetch();
|
|
2354
|
+
}, this.def.refreshInterval);
|
|
2355
|
+
}
|
|
2356
|
+
}
|
|
2357
|
+
_handleSearch(e) {
|
|
2358
|
+
const input = e.target;
|
|
2359
|
+
this._searchQuery = input.value;
|
|
2360
|
+
this._page = 1;
|
|
2361
|
+
this._fetch();
|
|
2362
|
+
}
|
|
2363
|
+
/**
|
|
2364
|
+
* Updates search position to be centered with equal gaps from title and tools.
|
|
2365
|
+
* On first call: resets to flex centering, measures position, then locks with fixed margin.
|
|
2366
|
+
* Subsequent calls are ignored unless _searchPositionLocked is reset (e.g., on resize).
|
|
2367
|
+
*/
|
|
2368
|
+
_updateSearchPosition() {
|
|
2369
|
+
// Skip if already locked (prevents shifts on pagination changes)
|
|
2370
|
+
if (this._searchPositionLocked)
|
|
2371
|
+
return;
|
|
2372
|
+
const search = this.shadowRoot?.querySelector('.search');
|
|
2373
|
+
const searchField = search?.querySelector('.search-field');
|
|
2374
|
+
if (!search || !searchField)
|
|
2375
|
+
return;
|
|
2376
|
+
// Reset to flex centering
|
|
2377
|
+
search.style.justifyContent = 'center';
|
|
2378
|
+
searchField.style.marginLeft = '';
|
|
2379
|
+
requestAnimationFrame(() => {
|
|
2380
|
+
const searchRect = search.getBoundingClientRect();
|
|
2381
|
+
const fieldRect = searchField.getBoundingClientRect();
|
|
2382
|
+
// Calculate how far from the left of search container the field currently is
|
|
2383
|
+
const currentOffset = fieldRect.left - searchRect.left;
|
|
2384
|
+
// Lock position: switch to flex-start and use fixed margin
|
|
2385
|
+
search.style.justifyContent = 'flex-start';
|
|
2386
|
+
searchField.style.marginLeft = `${currentOffset}px`;
|
|
2387
|
+
// Mark as locked so pagination changes don't shift the search
|
|
2388
|
+
this._searchPositionLocked = true;
|
|
2389
|
+
});
|
|
2390
|
+
}
|
|
2391
|
+
// ----------------------------------------------------------------------------
|
|
2392
|
+
// Columns
|
|
2393
|
+
// ----------------------------------------------------------------------------
|
|
2394
|
+
_toggleColumnPicker() {
|
|
2395
|
+
this._columnPickerOpen = !this._columnPickerOpen;
|
|
2396
|
+
}
|
|
2397
|
+
_toggleColumn(columnId) {
|
|
2398
|
+
if (this._displayedColumns.includes(columnId)) {
|
|
2399
|
+
this._displayedColumns = this._displayedColumns.filter(id => id !== columnId);
|
|
2400
|
+
}
|
|
2401
|
+
else {
|
|
2402
|
+
this._displayedColumns = [...this._displayedColumns, columnId];
|
|
2403
|
+
}
|
|
2404
|
+
}
|
|
2405
|
+
// When a user toggles a column on via the column picker, it gets appended
|
|
2406
|
+
// to _displayedColumns. By mapping over _displayedColumns (not def.columns),
|
|
2407
|
+
// the new column appears at the right edge of the table instead of jumping
|
|
2408
|
+
// back to its original position in the column definition.
|
|
2409
|
+
getDisplayedColumns() {
|
|
2410
|
+
return this._displayedColumns.map(id => this.def.columns.find(col => col.id === id));
|
|
2411
|
+
}
|
|
2412
|
+
// ----------------------------------------------------------------------------
|
|
2413
|
+
// Scrolling
|
|
2414
|
+
// ----------------------------------------------------------------------------
|
|
2415
|
+
/**
|
|
2416
|
+
* Scroll event handler that updates scroll flags in real-time as user scrolls.
|
|
2417
|
+
* Updates shadow indicators to show if more content exists left/right.
|
|
2418
|
+
*/
|
|
2419
|
+
_handleScroll(e) {
|
|
2420
|
+
const container = e.target;
|
|
2421
|
+
this._canScrollLeft = container.scrollLeft > 0;
|
|
2422
|
+
this._canScrollRight = container.scrollLeft < container.scrollWidth - container.clientWidth - 1;
|
|
2423
|
+
}
|
|
2424
|
+
/**
|
|
2425
|
+
* Updates scroll state flags for the table content container.
|
|
2426
|
+
* - _canScrollLeft: true if scrolled right (can scroll back left)
|
|
2427
|
+
* - _canScrollRight: true if more content exists to the right
|
|
2428
|
+
* - _canScrollHorizontal: true if content is wider than container
|
|
2429
|
+
* These flags control scroll shadow indicators and CSS classes.
|
|
2430
|
+
*/
|
|
2431
|
+
_updateScrollFlags() {
|
|
2432
|
+
const container = this.shadowRoot?.querySelector('.content');
|
|
2433
|
+
if (container) {
|
|
2434
|
+
this._canScrollLeft = container.scrollLeft > 0;
|
|
2435
|
+
this._canScrollRight = container.scrollWidth > container.clientWidth && container.scrollLeft < container.scrollWidth - container.clientWidth - 1;
|
|
2436
|
+
this._canScrollHorizontal = container.scrollWidth > container.clientWidth;
|
|
2437
|
+
}
|
|
2438
|
+
this.classList.toggle('kr-table--scroll-left-available', this._canScrollLeft);
|
|
2439
|
+
this.classList.toggle('kr-table--scroll-right-available', this._canScrollRight);
|
|
2440
|
+
this.classList.toggle('kr-table--scroll-horizontal-available', this._canScrollHorizontal);
|
|
2441
|
+
}
|
|
2442
|
+
// ----------------------------------------------------------------------------
|
|
2443
|
+
// Column Resizing
|
|
2444
|
+
// ----------------------------------------------------------------------------
|
|
2445
|
+
_handleResizeStart(e, columnId) {
|
|
2446
|
+
e.preventDefault();
|
|
2447
|
+
const column = this.def.columns.find(c => c.id === columnId);
|
|
2448
|
+
this._resizing = {
|
|
2449
|
+
columnId,
|
|
2450
|
+
startX: e.clientX,
|
|
2451
|
+
startWidth: this._columnWidths.get(columnId) || parseInt(column?.width || '150', 10)
|
|
2452
|
+
};
|
|
2453
|
+
document.addEventListener('mousemove', this._handleResizeMove);
|
|
2454
|
+
document.addEventListener('mouseup', this._handleResizeEnd);
|
|
2455
|
+
}
|
|
2456
|
+
// ----------------------------------------------------------------------------
|
|
2457
|
+
// Header
|
|
2458
|
+
// ----------------------------------------------------------------------------
|
|
2459
|
+
_handleAction(action) {
|
|
2460
|
+
this.dispatchEvent(new CustomEvent('action', {
|
|
2461
|
+
detail: { action: action.id },
|
|
2462
|
+
bubbles: true,
|
|
2463
|
+
composed: true
|
|
2464
|
+
}));
|
|
2465
|
+
}
|
|
2466
|
+
// ----------------------------------------------------------------------------
|
|
2467
|
+
// Rendering
|
|
2468
|
+
// ----------------------------------------------------------------------------
|
|
2469
|
+
_renderCellContent(column, row) {
|
|
2470
|
+
const value = row[column.id];
|
|
2471
|
+
if (column.render) {
|
|
2472
|
+
return column.render(row);
|
|
2473
|
+
}
|
|
2474
|
+
if (value === null || value === undefined) {
|
|
2475
|
+
return '';
|
|
2476
|
+
}
|
|
2477
|
+
switch (column.type) {
|
|
2478
|
+
case 'number':
|
|
2479
|
+
return typeof value === 'number' ? value.toLocaleString() : String(value);
|
|
2480
|
+
case 'currency':
|
|
2481
|
+
return typeof value === 'number'
|
|
2482
|
+
? value.toLocaleString('en-US', { style: 'currency', currency: 'USD' })
|
|
2483
|
+
: String(value);
|
|
2484
|
+
case 'date':
|
|
2485
|
+
return value instanceof Date
|
|
2486
|
+
? value.toLocaleDateString()
|
|
2487
|
+
: new Date(value).toLocaleDateString();
|
|
2488
|
+
case 'boolean':
|
|
2489
|
+
if (value === true)
|
|
2490
|
+
return 'Yes';
|
|
2491
|
+
if (value === false)
|
|
2492
|
+
return 'No';
|
|
2493
|
+
return '';
|
|
2494
|
+
default:
|
|
2495
|
+
return String(value);
|
|
2496
|
+
}
|
|
2497
|
+
}
|
|
2498
|
+
/**
|
|
2499
|
+
* Returns CSS classes for a header cell based on column config.
|
|
2500
|
+
*/
|
|
2501
|
+
_getHeaderCellClasses(column, index) {
|
|
2502
|
+
return {
|
|
2503
|
+
'header-cell': true,
|
|
2504
|
+
'header-cell--align-center': column.align === 'center',
|
|
2505
|
+
'header-cell--align-right': column.align === 'right',
|
|
2506
|
+
'header-cell--sticky-left': column.sticky === 'left',
|
|
2507
|
+
'header-cell--sticky-left-last': column.sticky === 'left' &&
|
|
2508
|
+
!this.getDisplayedColumns().slice(index + 1).some(c => c.sticky === 'left'),
|
|
2509
|
+
'header-cell--sticky-right': column.sticky === 'right',
|
|
2510
|
+
'header-cell--sticky-right-first': column.sticky === 'right' &&
|
|
2511
|
+
!this.getDisplayedColumns().slice(0, index).some(c => c.sticky === 'right')
|
|
2512
|
+
};
|
|
2513
|
+
}
|
|
2514
|
+
/**
|
|
2515
|
+
* Returns CSS classes for a table cell based on column config:
|
|
2516
|
+
* - Alignment (center, right)
|
|
2517
|
+
* - Sticky positioning (left, right)
|
|
2518
|
+
* - Border classes for the last left-sticky or first right-sticky column
|
|
2519
|
+
*/
|
|
2520
|
+
_getCellClasses(column, index) {
|
|
2521
|
+
return {
|
|
2522
|
+
'cell': true,
|
|
2523
|
+
'cell--align-center': column.align === 'center',
|
|
2524
|
+
'cell--align-right': column.align === 'right',
|
|
2525
|
+
'cell--sticky-left': column.sticky === 'left',
|
|
2526
|
+
'cell--sticky-left-last': column.sticky === 'left' &&
|
|
2527
|
+
!this.getDisplayedColumns().slice(index + 1).some(c => c.sticky === 'left'),
|
|
2528
|
+
'cell--sticky-right': column.sticky === 'right',
|
|
2529
|
+
'cell--sticky-right-first': column.sticky === 'right' &&
|
|
2530
|
+
!this.getDisplayedColumns().slice(0, index).some(c => c.sticky === 'right')
|
|
2531
|
+
};
|
|
2532
|
+
}
|
|
2533
|
+
/**
|
|
2534
|
+
* Returns inline styles for a table cell:
|
|
2535
|
+
* - Width (from column config or default 150px)
|
|
2536
|
+
* - Min-width (if specified)
|
|
2537
|
+
* - Left/right offset for sticky columns (calculated from widths of preceding sticky columns)
|
|
2538
|
+
*/
|
|
2539
|
+
_getCellStyle(column, index) {
|
|
2540
|
+
const styles = {};
|
|
2541
|
+
const isLastColumn = index === this.getDisplayedColumns().length - 1;
|
|
2542
|
+
const customWidth = this._columnWidths.get(column.id);
|
|
2543
|
+
const width = customWidth ? `${customWidth}px` : (column.width || '150px');
|
|
2544
|
+
if (isLastColumn && !customWidth) {
|
|
2545
|
+
styles.flex = '1';
|
|
2546
|
+
styles.minWidth = column.width || '150px';
|
|
2547
|
+
styles.marginRight = '24px';
|
|
2548
|
+
}
|
|
2549
|
+
else {
|
|
2550
|
+
styles.width = width;
|
|
2551
|
+
}
|
|
2552
|
+
if (column.minWidth)
|
|
2553
|
+
styles.minWidth = column.minWidth;
|
|
2554
|
+
if (column.sticky === 'left') {
|
|
2555
|
+
let leftOffset = 0;
|
|
2556
|
+
for (let i = 0; i < index; i++) {
|
|
2557
|
+
if (this.getDisplayedColumns()[i].sticky === 'left') {
|
|
2558
|
+
leftOffset += parseInt(this.getDisplayedColumns()[i].width || '150', 10);
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
styles.left = `${leftOffset}px`;
|
|
2562
|
+
}
|
|
2563
|
+
if (column.sticky === 'right') {
|
|
2564
|
+
let rightOffset = 0;
|
|
2565
|
+
for (let i = index + 1; i < this.getDisplayedColumns().length; i++) {
|
|
2566
|
+
if (this.getDisplayedColumns()[i].sticky === 'right') {
|
|
2567
|
+
rightOffset += parseInt(this.getDisplayedColumns()[i].width || '150', 10);
|
|
2568
|
+
}
|
|
2569
|
+
}
|
|
2570
|
+
styles.right = `${rightOffset}px`;
|
|
2571
|
+
}
|
|
2572
|
+
return styles;
|
|
2573
|
+
}
|
|
2574
|
+
/**
|
|
2575
|
+
* Renders the pagination controls:
|
|
2576
|
+
* - Previous page arrow (disabled on first page)
|
|
2577
|
+
* - Range text showing "1-50 of 150" format
|
|
2578
|
+
* - Next page arrow (disabled on last page)
|
|
2579
|
+
*
|
|
2580
|
+
* Hidden when there's no data or all data fits on one page.
|
|
2581
|
+
*/
|
|
2582
|
+
_renderPagination() {
|
|
2583
|
+
const start = (this._page - 1) * this._pageSize + 1;
|
|
2584
|
+
const end = Math.min(this._page * this._pageSize, this._totalItems);
|
|
2585
|
+
return b `
|
|
2586
|
+
<div class="pagination">
|
|
2587
|
+
<span
|
|
2588
|
+
class="pagination-icon ${this._page === 1 ? 'pagination-icon--disabled' : ''}"
|
|
2589
|
+
@click=${this.goToPrevPage}
|
|
2590
|
+
>
|
|
2591
|
+
<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>
|
|
2592
|
+
</span>
|
|
2593
|
+
<span class="pagination-info">${start}-${end} of ${this._totalItems}</span>
|
|
2594
|
+
<span
|
|
2595
|
+
class="pagination-icon ${this._page === this._totalPages ? 'pagination-icon--disabled' : ''}"
|
|
2596
|
+
@click=${this.goToNextPage}
|
|
2597
|
+
>
|
|
2598
|
+
<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>
|
|
2599
|
+
</span>
|
|
2600
|
+
</div>
|
|
2601
|
+
`;
|
|
2602
|
+
}
|
|
2603
|
+
/**
|
|
2604
|
+
* Renders the header toolbar containing:
|
|
2605
|
+
* - Title (left)
|
|
2606
|
+
* - Search bar with view selector dropdown (center)
|
|
2607
|
+
* - Tools (right): page navigation, refresh button, column visibility picker, actions dropdown
|
|
2608
|
+
*
|
|
2609
|
+
* Hidden when there's no title, no actions, and data fits on one page.
|
|
2610
|
+
*/
|
|
2611
|
+
_renderHeader() {
|
|
2612
|
+
if (!this.def.title && !this.def.actions?.length && this._totalPages <= 1) {
|
|
2613
|
+
return A;
|
|
2614
|
+
}
|
|
2615
|
+
return b `
|
|
2616
|
+
<div class="header">
|
|
2617
|
+
<div class="title">${this.def.title ?? ''}</div>
|
|
2618
|
+
<div class="search">
|
|
2619
|
+
<!-- TODO: Saved views dropdown
|
|
2620
|
+
<div class="views">
|
|
2621
|
+
<span>Default View</span>
|
|
2622
|
+
<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>
|
|
2623
|
+
</div>
|
|
2624
|
+
-->
|
|
2625
|
+
<div class="search-field">
|
|
2626
|
+
<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>
|
|
2627
|
+
<input
|
|
2628
|
+
type="text"
|
|
2629
|
+
class="search-input"
|
|
2630
|
+
placeholder="Search..."
|
|
2631
|
+
.value=${this._searchQuery}
|
|
2632
|
+
@input=${this._handleSearch}
|
|
2633
|
+
/>
|
|
2634
|
+
</div>
|
|
2635
|
+
</div>
|
|
2636
|
+
<div class="tools">
|
|
2637
|
+
${this._renderPagination()}
|
|
2638
|
+
<span class="refresh" title="Refresh" @click=${() => this.refresh()}>
|
|
2639
|
+
<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>
|
|
2640
|
+
</span>
|
|
2641
|
+
<div class="column-picker-wrapper">
|
|
2642
|
+
<span class="header-icon" title="Columns" @click=${this._toggleColumnPicker}>
|
|
2643
|
+
<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>
|
|
2644
|
+
</span>
|
|
2645
|
+
<div class="column-picker ${this._columnPickerOpen ? 'open' : ''}">
|
|
2646
|
+
${[...this.def.columns].sort((a, b) => (a.label ?? a.id).localeCompare(b.label ?? b.id)).map(col => b `
|
|
2647
|
+
<div class="column-picker-item" @click=${() => this._toggleColumn(col.id)}>
|
|
2648
|
+
<div class="column-picker-checkbox ${this._displayedColumns.includes(col.id) ? 'checked' : ''}">
|
|
2649
|
+
<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>
|
|
2650
|
+
</div>
|
|
2651
|
+
<span class="column-picker-label">${col.label ?? col.id}</span>
|
|
2652
|
+
</div>
|
|
2653
|
+
`)}
|
|
2654
|
+
</div>
|
|
2655
|
+
</div>
|
|
2656
|
+
${this.def.actions?.length ? b `
|
|
2657
|
+
<kr-button
|
|
2658
|
+
class="actions"
|
|
2659
|
+
.options=${this.def.actions.map(a => ({ id: a.id, label: a.label }))}
|
|
2660
|
+
@option-select=${(e) => this._handleAction({ id: e.detail.id, label: e.detail.label })}
|
|
2661
|
+
>
|
|
2662
|
+
Actions
|
|
2663
|
+
</kr-button>
|
|
2664
|
+
` : A}
|
|
2665
|
+
</div>
|
|
2666
|
+
</div>
|
|
2667
|
+
`;
|
|
2668
|
+
}
|
|
2669
|
+
/** Renders status message (loading, error, empty) */
|
|
2670
|
+
_renderStatus() {
|
|
2671
|
+
if (this._dataState === 'loading' && this._data.length === 0) {
|
|
2672
|
+
return b `<div class="status">Loading...</div>`;
|
|
2673
|
+
}
|
|
2674
|
+
if (this._dataState === 'error' && this._data.length === 0) {
|
|
2675
|
+
return b `<div class="status status--error">Error loading data</div>`;
|
|
2676
|
+
}
|
|
2677
|
+
if (this._data.length === 0) {
|
|
2678
|
+
return b `<div class="status">No data available</div>`;
|
|
2679
|
+
}
|
|
2680
|
+
return A;
|
|
2681
|
+
}
|
|
2682
|
+
/** Renders the scrollable data grid with column headers and rows. */
|
|
2683
|
+
_renderTable() {
|
|
2684
|
+
return b `
|
|
2685
|
+
<div class="wrapper">
|
|
2686
|
+
<div class="overlay-left"></div>
|
|
2687
|
+
<div class="overlay-right"></div>
|
|
2688
|
+
${this._renderStatus()}
|
|
2689
|
+
<div class="content" @scroll=${this._handleScroll}>
|
|
2690
|
+
<div class="table">
|
|
2691
|
+
<div class="header-row">
|
|
2692
|
+
${this.getDisplayedColumns().map((col, i) => b `
|
|
2693
|
+
<div
|
|
2694
|
+
class=${e$1(this._getHeaderCellClasses(col, i))}
|
|
2695
|
+
style=${o$1(this._getCellStyle(col, i))}
|
|
2696
|
+
>
|
|
2697
|
+
<span class="header-cell__label">${col.label ?? col.id}</span>
|
|
2698
|
+
<div
|
|
2699
|
+
class="header-cell__resize"
|
|
2700
|
+
@mousedown=${(e) => this._handleResizeStart(e, col.id)}
|
|
2701
|
+
></div>
|
|
2702
|
+
</div>
|
|
2703
|
+
`)}
|
|
2704
|
+
</div>
|
|
2705
|
+
${this._data.map(row => b `
|
|
2706
|
+
<div class="row">
|
|
2707
|
+
${this.getDisplayedColumns().map((col, i) => b `
|
|
2708
|
+
<div
|
|
2709
|
+
class=${e$1(this._getCellClasses(col, i))}
|
|
2710
|
+
style=${o$1(this._getCellStyle(col, i))}
|
|
2711
|
+
>
|
|
2712
|
+
${this._renderCellContent(col, row)}
|
|
2713
|
+
</div>
|
|
2714
|
+
`)}
|
|
2715
|
+
</div>
|
|
2716
|
+
`)}
|
|
2717
|
+
</div>
|
|
2718
|
+
</div>
|
|
2719
|
+
</div>
|
|
2720
|
+
`;
|
|
2721
|
+
}
|
|
2722
|
+
/**
|
|
2723
|
+
* Renders a data table with:
|
|
2724
|
+
* - Header bar with title, search input with view selector, and tools (pagination, refresh, column visibility, actions dropdown)
|
|
2725
|
+
* - Scrollable grid with sticky header row and optional sticky left/right columns
|
|
2726
|
+
* - Loading, error message, or empty state when no data
|
|
2727
|
+
*/
|
|
2728
|
+
render() {
|
|
2729
|
+
if (!this.def.columns.length) {
|
|
2730
|
+
return b `<slot></slot>`;
|
|
2731
|
+
}
|
|
2732
|
+
return b `
|
|
2733
|
+
${this._renderHeader()}
|
|
2734
|
+
${this._renderTable()}
|
|
2735
|
+
`;
|
|
2736
|
+
}
|
|
2737
|
+
};
|
|
2738
|
+
exports.KRTable.styles = [krBaseCSS, i$5 `
|
|
2739
|
+
/* -------------------------------------------------------------------------
|
|
2740
|
+
* Host
|
|
2741
|
+
* ----------------------------------------------------------------------- */
|
|
2742
|
+
:host {
|
|
2743
|
+
display: flex;
|
|
2744
|
+
flex-direction: column;
|
|
2745
|
+
width: 100%;
|
|
2746
|
+
height: 100%;
|
|
2747
|
+
overflow: hidden;
|
|
2748
|
+
container-type: inline-size;
|
|
2749
|
+
}
|
|
2750
|
+
|
|
2751
|
+
/* -------------------------------------------------------------------------
|
|
2752
|
+
* Header
|
|
2753
|
+
* ----------------------------------------------------------------------- */
|
|
2754
|
+
.header {
|
|
2755
|
+
flex-shrink: 0;
|
|
2756
|
+
display: flex;
|
|
2757
|
+
align-items: center;
|
|
2758
|
+
gap: 16px;
|
|
2759
|
+
margin: 0 24px;
|
|
2760
|
+
padding: 0 4px;
|
|
2761
|
+
height: 64px;
|
|
2762
|
+
border-bottom: 1px solid #e5e7eb;
|
|
2763
|
+
background: #fff;
|
|
2764
|
+
}
|
|
2765
|
+
|
|
2766
|
+
:host(.kr-table--scroll-edge) .header {
|
|
2767
|
+
border-bottom: none;
|
|
2768
|
+
}
|
|
2769
|
+
|
|
2770
|
+
.title {
|
|
2771
|
+
font-size: 20px;
|
|
2772
|
+
font-weight: 400;
|
|
2773
|
+
color: #000;
|
|
2774
|
+
}
|
|
2775
|
+
|
|
2776
|
+
/* -------------------------------------------------------------------------
|
|
2777
|
+
* Content
|
|
2778
|
+
* ----------------------------------------------------------------------- */
|
|
2779
|
+
.wrapper {
|
|
2780
|
+
flex: 1;
|
|
2781
|
+
position: relative;
|
|
2782
|
+
overflow: hidden;
|
|
2783
|
+
}
|
|
2784
|
+
|
|
2785
|
+
.content {
|
|
2786
|
+
height: 100%;
|
|
2787
|
+
overflow: auto;
|
|
2788
|
+
padding-bottom: 24px;
|
|
2789
|
+
}
|
|
2790
|
+
|
|
2791
|
+
/* -------------------------------------------------------------------------
|
|
2792
|
+
* Search
|
|
2793
|
+
* ----------------------------------------------------------------------- */
|
|
2794
|
+
.search {
|
|
2795
|
+
flex: 1;
|
|
2796
|
+
display: flex;
|
|
2797
|
+
align-items: center;
|
|
2798
|
+
justify-content: center;
|
|
2799
|
+
min-width: 0;
|
|
2800
|
+
}
|
|
2801
|
+
|
|
2802
|
+
.search-field {
|
|
2803
|
+
width: 100%;
|
|
2804
|
+
max-width: 400px;
|
|
2805
|
+
position: relative;
|
|
2806
|
+
display: flex;
|
|
2807
|
+
align-items: center;
|
|
2808
|
+
border: 1px solid #00000038;
|
|
2809
|
+
border-radius: 18px;
|
|
2810
|
+
transition: border-color 0.2s, box-shadow 0.2s;
|
|
2811
|
+
}
|
|
2812
|
+
|
|
2813
|
+
.search-field:focus-within {
|
|
2814
|
+
border-color: #163052;
|
|
2815
|
+
box-shadow: 0 0 0 3px rgba(22, 48, 82, 0.1);
|
|
2816
|
+
}
|
|
2817
|
+
|
|
2818
|
+
/* TODO: Uncomment when views dropdown is added
|
|
2819
|
+
.search-field:focus-within .views {
|
|
2820
|
+
border-color: #163052;
|
|
2821
|
+
}
|
|
2822
|
+
*/
|
|
2823
|
+
|
|
2824
|
+
.search-icon {
|
|
2825
|
+
position: absolute;
|
|
2826
|
+
left: 16px;
|
|
2827
|
+
width: 20px;
|
|
2828
|
+
height: 20px;
|
|
2829
|
+
color: #656871;
|
|
2830
|
+
pointer-events: none;
|
|
2831
|
+
}
|
|
2832
|
+
|
|
2833
|
+
.search-input {
|
|
2834
|
+
height: 36px;
|
|
2835
|
+
padding: 0 16px 0 42px;
|
|
2836
|
+
border: none;
|
|
2837
|
+
border-radius: 16px;
|
|
2838
|
+
font-size: 14px;
|
|
2839
|
+
font-weight: 400;
|
|
2840
|
+
font-family: inherit;
|
|
2841
|
+
color: #163052;
|
|
2842
|
+
background: transparent;
|
|
2843
|
+
outline: none;
|
|
2844
|
+
flex: 1;
|
|
2845
|
+
min-width: 0;
|
|
2846
|
+
width: 100%;
|
|
2847
|
+
}
|
|
2848
|
+
|
|
2849
|
+
.search-input::placeholder {
|
|
2850
|
+
color: #656871;
|
|
2851
|
+
font-weight: 400;
|
|
2852
|
+
}
|
|
2853
|
+
|
|
2854
|
+
.search-input:focus {
|
|
2855
|
+
outline: none;
|
|
2856
|
+
}
|
|
2857
|
+
|
|
2858
|
+
@container (max-width: 800px) {
|
|
2859
|
+
.search-field {
|
|
2860
|
+
max-width: 250px;
|
|
2861
|
+
}
|
|
2862
|
+
}
|
|
2863
|
+
|
|
2864
|
+
.views {
|
|
2865
|
+
display: flex;
|
|
2866
|
+
align-items: center;
|
|
2867
|
+
gap: 4px;
|
|
2868
|
+
height: 36px;
|
|
2869
|
+
padding: 0 16px;
|
|
2870
|
+
border: 1px solid #00000038;
|
|
2871
|
+
border-right: none;
|
|
2872
|
+
border-radius: 16px 0 0 16px;
|
|
2873
|
+
font-size: 14px;
|
|
2874
|
+
font-family: inherit;
|
|
2875
|
+
color: #163052;
|
|
2876
|
+
background: transparent;
|
|
2877
|
+
cursor: pointer;
|
|
2878
|
+
white-space: nowrap;
|
|
2879
|
+
transition: border-color 0.2s;
|
|
2880
|
+
}
|
|
2881
|
+
|
|
2882
|
+
.views:hover {
|
|
2883
|
+
background: #e8f0f8;
|
|
2884
|
+
}
|
|
2885
|
+
|
|
2886
|
+
.views svg {
|
|
2887
|
+
width: 16px;
|
|
2888
|
+
height: 16px;
|
|
2889
|
+
color: #163052;
|
|
2890
|
+
}
|
|
2891
|
+
|
|
2892
|
+
/* -------------------------------------------------------------------------
|
|
2893
|
+
* Pagination
|
|
2894
|
+
* ----------------------------------------------------------------------- */
|
|
2895
|
+
.tools {
|
|
2896
|
+
display: flex;
|
|
2897
|
+
align-items: center;
|
|
2898
|
+
gap: 8px;
|
|
2899
|
+
}
|
|
2900
|
+
|
|
2901
|
+
.pagination {
|
|
2902
|
+
display: flex;
|
|
2903
|
+
align-items: center;
|
|
2904
|
+
gap: 2px;
|
|
2905
|
+
}
|
|
2906
|
+
|
|
2907
|
+
.pagination-info {
|
|
2908
|
+
font-size: 13px;
|
|
2909
|
+
color: var(--kr-primary);
|
|
2910
|
+
white-space: nowrap;
|
|
2911
|
+
}
|
|
2912
|
+
|
|
2913
|
+
.pagination-icon {
|
|
2914
|
+
display: flex;
|
|
2915
|
+
color: var(--kr-primary);
|
|
2916
|
+
cursor: pointer;
|
|
2917
|
+
}
|
|
2918
|
+
|
|
2919
|
+
.pagination-icon--disabled {
|
|
2920
|
+
opacity: 0.3;
|
|
2921
|
+
pointer-events: none;
|
|
2922
|
+
}
|
|
2923
|
+
|
|
2924
|
+
.pagination-icon svg {
|
|
2925
|
+
width: 24px;
|
|
2926
|
+
height: 24px;
|
|
2927
|
+
}
|
|
2928
|
+
|
|
2929
|
+
/* -------------------------------------------------------------------------
|
|
2930
|
+
* Header Icons
|
|
2931
|
+
* ----------------------------------------------------------------------- */
|
|
2932
|
+
.refresh,
|
|
2933
|
+
.header-icon {
|
|
2934
|
+
display: flex;
|
|
2935
|
+
align-items: center;
|
|
2936
|
+
justify-content: center;
|
|
2937
|
+
color: var(--kr-primary);
|
|
2938
|
+
background: #EBF1FA;
|
|
2939
|
+
cursor: pointer;
|
|
2940
|
+
padding: 6px;
|
|
2941
|
+
border-radius: 50%;
|
|
2942
|
+
transition: background 0.15s;
|
|
2943
|
+
}
|
|
2944
|
+
|
|
2945
|
+
.refresh:hover,
|
|
2946
|
+
.header-icon:hover {
|
|
2947
|
+
background: #e8f0f8;
|
|
2948
|
+
}
|
|
2949
|
+
|
|
2950
|
+
.refresh svg,
|
|
2951
|
+
.header-icon svg {
|
|
2952
|
+
width: 24px;
|
|
2953
|
+
height: 24px;
|
|
2954
|
+
}
|
|
2955
|
+
|
|
2956
|
+
/* -------------------------------------------------------------------------
|
|
2957
|
+
* Column Picker
|
|
2958
|
+
* ----------------------------------------------------------------------- */
|
|
2959
|
+
.column-picker-wrapper {
|
|
2960
|
+
position: relative;
|
|
2961
|
+
}
|
|
2962
|
+
|
|
2963
|
+
.column-picker {
|
|
2964
|
+
position: absolute;
|
|
2965
|
+
top: 100%;
|
|
2966
|
+
right: 0;
|
|
2967
|
+
margin-top: 4px;
|
|
2968
|
+
min-width: 200px;
|
|
2969
|
+
max-height: calc(100vh - 120px);
|
|
2970
|
+
overflow-y: auto;
|
|
2971
|
+
background: white;
|
|
2972
|
+
border: 1px solid #9ba7b6;
|
|
2973
|
+
border-radius: 8px;
|
|
2974
|
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
|
2975
|
+
padding: 8px 0;
|
|
2976
|
+
z-index: 100;
|
|
2977
|
+
display: none;
|
|
2978
|
+
transform-origin: top;
|
|
2979
|
+
}
|
|
2980
|
+
|
|
2981
|
+
.column-picker.open {
|
|
2982
|
+
display: block;
|
|
2983
|
+
animation: column-picker-fade-in 150ms ease-out;
|
|
2984
|
+
}
|
|
2985
|
+
|
|
2986
|
+
@keyframes column-picker-fade-in {
|
|
2987
|
+
from {
|
|
2988
|
+
opacity: 0;
|
|
2989
|
+
transform: translateY(-4px);
|
|
2990
|
+
}
|
|
2991
|
+
to {
|
|
2992
|
+
opacity: 1;
|
|
2993
|
+
transform: translateY(0);
|
|
2994
|
+
}
|
|
2995
|
+
}
|
|
2996
|
+
|
|
2997
|
+
.column-picker-item {
|
|
2998
|
+
display: flex;
|
|
2999
|
+
align-items: center;
|
|
3000
|
+
gap: 10px;
|
|
3001
|
+
padding: 8px 16px;
|
|
3002
|
+
cursor: pointer;
|
|
3003
|
+
white-space: nowrap;
|
|
3004
|
+
}
|
|
3005
|
+
|
|
3006
|
+
.column-picker-item:hover {
|
|
3007
|
+
background: #f3f4f6;
|
|
3008
|
+
}
|
|
3009
|
+
|
|
3010
|
+
.column-picker-checkbox {
|
|
3011
|
+
width: 16px;
|
|
3012
|
+
height: 16px;
|
|
3013
|
+
border: 1.5px solid #9ca3af;
|
|
3014
|
+
border-radius: 3px;
|
|
3015
|
+
display: flex;
|
|
3016
|
+
align-items: center;
|
|
3017
|
+
justify-content: center;
|
|
3018
|
+
flex-shrink: 0;
|
|
3019
|
+
transition: all 0.15s;
|
|
3020
|
+
}
|
|
3021
|
+
|
|
3022
|
+
.column-picker-checkbox.checked {
|
|
3023
|
+
background: var(--kr-primary);
|
|
3024
|
+
border-color: var(--kr-primary);
|
|
3025
|
+
}
|
|
3026
|
+
|
|
3027
|
+
.column-picker-checkbox svg {
|
|
3028
|
+
width: 12px;
|
|
3029
|
+
height: 12px;
|
|
3030
|
+
color: white;
|
|
3031
|
+
opacity: 0;
|
|
3032
|
+
}
|
|
3033
|
+
|
|
3034
|
+
.column-picker-checkbox.checked svg {
|
|
3035
|
+
opacity: 1;
|
|
3036
|
+
}
|
|
3037
|
+
|
|
3038
|
+
.column-picker-label {
|
|
3039
|
+
font-size: 14px;
|
|
3040
|
+
color: #374151;
|
|
3041
|
+
}
|
|
3042
|
+
|
|
3043
|
+
/* -------------------------------------------------------------------------
|
|
3044
|
+
* Table Structure
|
|
3045
|
+
* ----------------------------------------------------------------------- */
|
|
3046
|
+
.table {
|
|
3047
|
+
display: flex;
|
|
3048
|
+
flex-direction: column;
|
|
3049
|
+
width: 100%;
|
|
3050
|
+
min-width: max-content;
|
|
3051
|
+
font-size: 14px;
|
|
3052
|
+
}
|
|
3053
|
+
|
|
3054
|
+
.row {
|
|
3055
|
+
display: flex;
|
|
3056
|
+
}
|
|
3057
|
+
|
|
3058
|
+
.header-row {
|
|
3059
|
+
display: flex;
|
|
3060
|
+
position: sticky;
|
|
3061
|
+
top: 0;
|
|
3062
|
+
z-index: 2;
|
|
3063
|
+
}
|
|
3064
|
+
|
|
3065
|
+
.row:hover .cell {
|
|
3066
|
+
background: #f9fafb;
|
|
3067
|
+
}
|
|
3068
|
+
|
|
3069
|
+
.cell {
|
|
3070
|
+
padding: 12px 16px;
|
|
3071
|
+
white-space: nowrap;
|
|
3072
|
+
overflow: hidden;
|
|
3073
|
+
text-overflow: ellipsis;
|
|
3074
|
+
flex-shrink: 0;
|
|
3075
|
+
box-sizing: border-box;
|
|
3076
|
+
}
|
|
3077
|
+
|
|
3078
|
+
.header-cell {
|
|
3079
|
+
display: flex;
|
|
3080
|
+
align-items: center;
|
|
3081
|
+
padding: 12px 16px;
|
|
3082
|
+
white-space: nowrap;
|
|
3083
|
+
flex-shrink: 0;
|
|
3084
|
+
box-sizing: border-box;
|
|
3085
|
+
background: #f9fafb;
|
|
3086
|
+
border-bottom: 2px solid #e5e7eb;
|
|
3087
|
+
font-weight: 600;
|
|
3088
|
+
color: #374151;
|
|
3089
|
+
overflow: visible;
|
|
3090
|
+
}
|
|
3091
|
+
|
|
3092
|
+
.header-cell__label {
|
|
3093
|
+
flex: 1;
|
|
3094
|
+
overflow: hidden;
|
|
3095
|
+
text-overflow: ellipsis;
|
|
3096
|
+
}
|
|
3097
|
+
|
|
3098
|
+
.header-cell__resize {
|
|
3099
|
+
width: 14px;
|
|
3100
|
+
margin-right: -22px;
|
|
3101
|
+
align-self: stretch;
|
|
3102
|
+
cursor: col-resize;
|
|
3103
|
+
display: flex;
|
|
3104
|
+
align-items: center;
|
|
3105
|
+
justify-content: center;
|
|
3106
|
+
z-index: 1;
|
|
3107
|
+
}
|
|
3108
|
+
|
|
3109
|
+
.header-cell__resize::after {
|
|
3110
|
+
content: '';
|
|
3111
|
+
width: 2px;
|
|
3112
|
+
height: 20px;
|
|
3113
|
+
background: #c6c6cd;
|
|
3114
|
+
}
|
|
3115
|
+
|
|
3116
|
+
.header-cell:last-child .header-cell__resize::after {
|
|
3117
|
+
display: none;
|
|
3118
|
+
}
|
|
3119
|
+
|
|
3120
|
+
.cell {
|
|
3121
|
+
background: #fff;
|
|
3122
|
+
border-bottom: 1px solid #e5e7eb;
|
|
3123
|
+
color: #1f2937;
|
|
3124
|
+
}
|
|
3125
|
+
|
|
3126
|
+
.cell--align-center {
|
|
3127
|
+
text-align: center;
|
|
3128
|
+
}
|
|
3129
|
+
|
|
3130
|
+
.cell--align-right {
|
|
3131
|
+
text-align: right;
|
|
3132
|
+
}
|
|
3133
|
+
|
|
3134
|
+
.cell--sticky-left,
|
|
3135
|
+
.cell--sticky-right {
|
|
3136
|
+
position: sticky;
|
|
3137
|
+
z-index: 1;
|
|
3138
|
+
}
|
|
3139
|
+
|
|
3140
|
+
.header-cell--sticky-left,
|
|
3141
|
+
.header-cell--sticky-right {
|
|
3142
|
+
position: sticky;
|
|
3143
|
+
z-index: 3;
|
|
3144
|
+
}
|
|
3145
|
+
|
|
3146
|
+
.header-cell--align-center {
|
|
3147
|
+
text-align: center;
|
|
3148
|
+
}
|
|
3149
|
+
|
|
3150
|
+
.header-cell--align-right {
|
|
3151
|
+
text-align: right;
|
|
3152
|
+
}
|
|
3153
|
+
|
|
3154
|
+
.header-cell--sticky-left-last,
|
|
3155
|
+
.cell--sticky-left-last {
|
|
3156
|
+
border-right: 1px solid #d1d5db;
|
|
3157
|
+
}
|
|
3158
|
+
|
|
3159
|
+
.header-cell--sticky-right-first,
|
|
3160
|
+
.cell--sticky-right-first {
|
|
3161
|
+
border-left: 1px solid #d1d5db;
|
|
3162
|
+
}
|
|
3163
|
+
|
|
3164
|
+
/* -------------------------------------------------------------------------
|
|
3165
|
+
* Scroll Mode: Edge
|
|
3166
|
+
* Padding scrolls with content, table can reach edges when scrolling
|
|
3167
|
+
* ----------------------------------------------------------------------- */
|
|
3168
|
+
:host(.kr-table--scroll-edge) .table {
|
|
3169
|
+
padding-left: 24px;
|
|
3170
|
+
}
|
|
3171
|
+
|
|
3172
|
+
/* Only add right padding when no horizontal scroll is needed */
|
|
3173
|
+
:host(.kr-table--scroll-edge):not(.kr-table--scroll-horizontal-available) .table {
|
|
3174
|
+
padding-right: 24px;
|
|
3175
|
+
}
|
|
3176
|
+
|
|
3177
|
+
:host(.kr-table--scroll-edge) .header-row .header-cell {
|
|
3178
|
+
border-top: 1px solid #e5e7eb;
|
|
3179
|
+
}
|
|
3180
|
+
|
|
3181
|
+
/* -------------------------------------------------------------------------
|
|
3182
|
+
* Scroll Mode: Overlay
|
|
3183
|
+
* Fixed padding with overlay elements that hide content at edges
|
|
3184
|
+
* ----------------------------------------------------------------------- */
|
|
3185
|
+
:host(.kr-table--scroll-overlay) .content {
|
|
3186
|
+
padding-left: 24px;
|
|
3187
|
+
padding-right: 24px;
|
|
3188
|
+
}
|
|
3189
|
+
|
|
3190
|
+
.overlay-left,
|
|
3191
|
+
.overlay-right {
|
|
3192
|
+
display: none;
|
|
3193
|
+
position: absolute;
|
|
3194
|
+
top: 0;
|
|
3195
|
+
bottom: 0;
|
|
3196
|
+
width: 24px;
|
|
3197
|
+
z-index: 5;
|
|
3198
|
+
pointer-events: none;
|
|
3199
|
+
transition: box-shadow 0.15s ease;
|
|
3200
|
+
}
|
|
3201
|
+
|
|
3202
|
+
:host(.kr-table--scroll-overlay) .overlay-left,
|
|
3203
|
+
:host(.kr-table--scroll-overlay) .overlay-right {
|
|
3204
|
+
display: block;
|
|
3205
|
+
}
|
|
3206
|
+
|
|
3207
|
+
.overlay-left {
|
|
3208
|
+
left: 0;
|
|
3209
|
+
background: linear-gradient(to right, #fff 50%, transparent);
|
|
3210
|
+
}
|
|
3211
|
+
|
|
3212
|
+
.overlay-right {
|
|
3213
|
+
right: 0;
|
|
3214
|
+
background: linear-gradient(to left, #fff 50%, transparent);
|
|
3215
|
+
}
|
|
3216
|
+
|
|
3217
|
+
:host(.kr-table--scroll-left-available) .overlay-left {
|
|
3218
|
+
box-shadow: inset -6px 0 6px -6px rgba(0, 0, 0, 0.08);
|
|
3219
|
+
}
|
|
3220
|
+
|
|
3221
|
+
:host(.kr-table--scroll-right-available) .overlay-right {
|
|
3222
|
+
box-shadow: inset 6px 0 6px -6px rgba(0, 0, 0, 0.08);
|
|
3223
|
+
}
|
|
3224
|
+
|
|
3225
|
+
/* -------------------------------------------------------------------------
|
|
3226
|
+
* Status (Loading, Error, Empty)
|
|
3227
|
+
* ----------------------------------------------------------------------- */
|
|
3228
|
+
.status {
|
|
3229
|
+
position: absolute;
|
|
3230
|
+
top: 0;
|
|
3231
|
+
left: 0;
|
|
3232
|
+
right: 0;
|
|
3233
|
+
bottom: 0;
|
|
3234
|
+
display: flex;
|
|
3235
|
+
align-items: center;
|
|
3236
|
+
justify-content: center;
|
|
3237
|
+
font-size: 14px;
|
|
3238
|
+
font-weight: 400;
|
|
3239
|
+
color: #5f6368;
|
|
3240
|
+
pointer-events: none;
|
|
3241
|
+
}
|
|
3242
|
+
|
|
3243
|
+
.status--error {
|
|
3244
|
+
color: #dc2626;
|
|
3245
|
+
}
|
|
3246
|
+
`];
|
|
3247
|
+
__decorate$3([
|
|
3248
|
+
r$1()
|
|
3249
|
+
], exports.KRTable.prototype, "_data", void 0);
|
|
3250
|
+
__decorate$3([
|
|
3251
|
+
r$1()
|
|
3252
|
+
], exports.KRTable.prototype, "_dataState", void 0);
|
|
3253
|
+
__decorate$3([
|
|
3254
|
+
r$1()
|
|
3255
|
+
], exports.KRTable.prototype, "_page", void 0);
|
|
3256
|
+
__decorate$3([
|
|
3257
|
+
r$1()
|
|
3258
|
+
], exports.KRTable.prototype, "_pageSize", void 0);
|
|
3259
|
+
__decorate$3([
|
|
3260
|
+
r$1()
|
|
3261
|
+
], exports.KRTable.prototype, "_totalItems", void 0);
|
|
3262
|
+
__decorate$3([
|
|
3263
|
+
r$1()
|
|
3264
|
+
], exports.KRTable.prototype, "_totalPages", void 0);
|
|
3265
|
+
__decorate$3([
|
|
3266
|
+
r$1()
|
|
3267
|
+
], exports.KRTable.prototype, "_searchQuery", void 0);
|
|
3268
|
+
__decorate$3([
|
|
3269
|
+
r$1()
|
|
3270
|
+
], exports.KRTable.prototype, "_canScrollLeft", void 0);
|
|
3271
|
+
__decorate$3([
|
|
3272
|
+
r$1()
|
|
3273
|
+
], exports.KRTable.prototype, "_canScrollRight", void 0);
|
|
3274
|
+
__decorate$3([
|
|
3275
|
+
r$1()
|
|
3276
|
+
], exports.KRTable.prototype, "_canScrollHorizontal", void 0);
|
|
3277
|
+
__decorate$3([
|
|
3278
|
+
r$1()
|
|
3279
|
+
], exports.KRTable.prototype, "_columnPickerOpen", void 0);
|
|
3280
|
+
__decorate$3([
|
|
3281
|
+
r$1()
|
|
3282
|
+
], exports.KRTable.prototype, "_displayedColumns", void 0);
|
|
3283
|
+
__decorate$3([
|
|
3284
|
+
r$1()
|
|
3285
|
+
], exports.KRTable.prototype, "_columnWidths", void 0);
|
|
3286
|
+
__decorate$3([
|
|
3287
|
+
n$1({ type: Object })
|
|
3288
|
+
], exports.KRTable.prototype, "def", void 0);
|
|
3289
|
+
exports.KRTable = __decorate$3([
|
|
3290
|
+
t$1('kr-table')
|
|
3291
|
+
], exports.KRTable);
|
|
3292
|
+
|
|
2038
3293
|
/**
|
|
2039
3294
|
* @license
|
|
2040
3295
|
* Copyright 2018 Google LLC
|
|
@@ -2272,8 +3527,8 @@
|
|
|
2272
3527
|
|
|
2273
3528
|
input:focus {
|
|
2274
3529
|
outline: none;
|
|
2275
|
-
border-color: var(--kr-text-field-focus-border-color, #
|
|
2276
|
-
box-shadow: 0 0 0 3px var(--kr-text-field-focus-ring-color, rgba(
|
|
3530
|
+
border-color: var(--kr-text-field-focus-border-color, #163052);
|
|
3531
|
+
box-shadow: 0 0 0 3px var(--kr-text-field-focus-ring-color, rgba(22, 48, 82, 0.1));
|
|
2277
3532
|
}
|
|
2278
3533
|
|
|
2279
3534
|
input:disabled {
|