@aquera/ngx-smart-table 0.0.13-alpha → 0.0.14-alpha
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/esm2020/lib/editors/nile-select-editor.mjs +110 -39
- package/esm2020/lib/renderer/components/st-cell/st-cell.component.mjs +2 -2
- package/esm2020/lib/renderer/components/st-table/st-table.component.mjs +44 -1
- package/esm2020/lib/renderer/components/st-workbook/st-workbook.component.mjs +30 -4
- package/fesm2015/aquera-ngx-smart-table.mjs +183 -42
- package/fesm2015/aquera-ngx-smart-table.mjs.map +1 -1
- package/fesm2020/aquera-ngx-smart-table.mjs +181 -42
- package/fesm2020/aquera-ngx-smart-table.mjs.map +1 -1
- package/lib/editors/nile-select-editor.d.ts +6 -0
- package/lib/renderer/components/st-table/st-table.component.d.ts +11 -0
- package/lib/renderer/components/st-workbook/st-workbook.component.d.ts +16 -0
- package/package.json +1 -1
|
@@ -3552,6 +3552,77 @@ class NileSelectEditor {
|
|
|
3552
3552
|
}
|
|
3553
3553
|
}
|
|
3554
3554
|
}
|
|
3555
|
+
/**
|
|
3556
|
+
* Inject global styles to remove border from nile-select combobox
|
|
3557
|
+
* Uses ::part selector which works across shadow DOM boundaries
|
|
3558
|
+
*/
|
|
3559
|
+
injectBorderlessStyles() {
|
|
3560
|
+
if (NileSelectEditor.stylesInjected)
|
|
3561
|
+
return;
|
|
3562
|
+
const styleId = 'nile-select-borderless-styles';
|
|
3563
|
+
if (document.getElementById(styleId)) {
|
|
3564
|
+
NileSelectEditor.stylesInjected = true;
|
|
3565
|
+
return;
|
|
3566
|
+
}
|
|
3567
|
+
const style = document.createElement('style');
|
|
3568
|
+
style.id = styleId;
|
|
3569
|
+
style.textContent = `
|
|
3570
|
+
.st-cell-editor::part(combobox) {
|
|
3571
|
+
border: none !important;
|
|
3572
|
+
outline: none !important;
|
|
3573
|
+
box-shadow: none !important;
|
|
3574
|
+
min-height: unset !important;
|
|
3575
|
+
height: 100% !important;
|
|
3576
|
+
padding: 0 !important;
|
|
3577
|
+
}
|
|
3578
|
+
.st-cell-editor::part(combobox):hover {
|
|
3579
|
+
border: none !important;
|
|
3580
|
+
outline: none !important;
|
|
3581
|
+
box-shadow: none !important;
|
|
3582
|
+
}
|
|
3583
|
+
.st-cell-editor::part(combobox):focus {
|
|
3584
|
+
border: none !important;
|
|
3585
|
+
outline: none !important;
|
|
3586
|
+
box-shadow: none !important;
|
|
3587
|
+
}
|
|
3588
|
+
// .st-cell-editor::part(tag) {
|
|
3589
|
+
// margin: 1px 2px !important;
|
|
3590
|
+
// border-radius: 3px !important;
|
|
3591
|
+
// background-color: #e2e8f0 !important;
|
|
3592
|
+
// font-size: 12px !important;
|
|
3593
|
+
// height: auto !important;
|
|
3594
|
+
// }
|
|
3595
|
+
// .st-cell-editor::part(tag__base) {
|
|
3596
|
+
// border: none !important;
|
|
3597
|
+
// outline: none !important;
|
|
3598
|
+
// padding: 0 2px !important;
|
|
3599
|
+
// height: auto !important;
|
|
3600
|
+
// }
|
|
3601
|
+
// .st-cell-editor::part(tag__content) {
|
|
3602
|
+
// padding: 0 !important;
|
|
3603
|
+
// }
|
|
3604
|
+
.st-cell-editor::part(tags) {
|
|
3605
|
+
gap: 2px !important;
|
|
3606
|
+
align-items: center !important;
|
|
3607
|
+
}
|
|
3608
|
+
.st-cell-editor::part(tags-count) {
|
|
3609
|
+
margin: 0 !important;
|
|
3610
|
+
}
|
|
3611
|
+
.st-cell-editor::part(footer) {
|
|
3612
|
+
height: 35px !important;
|
|
3613
|
+
min-height: 35px !important;
|
|
3614
|
+
padding: 8px !important;
|
|
3615
|
+
padding-bottom: 30px !important;
|
|
3616
|
+
box-sizing: border-box !important;
|
|
3617
|
+
}
|
|
3618
|
+
.st-cell-editor::part(listbox) {
|
|
3619
|
+
margin-bottom: 0 !important;
|
|
3620
|
+
padding-bottom: 0 !important;
|
|
3621
|
+
}
|
|
3622
|
+
`;
|
|
3623
|
+
document.head.appendChild(style);
|
|
3624
|
+
NileSelectEditor.stylesInjected = true;
|
|
3625
|
+
}
|
|
3555
3626
|
edit(context) {
|
|
3556
3627
|
if (!context.container) {
|
|
3557
3628
|
console.warn('NileSelectEditor requires a container element');
|
|
@@ -3562,10 +3633,18 @@ class NileSelectEditor {
|
|
|
3562
3633
|
// Create NileSelect custom element using document.createElement
|
|
3563
3634
|
this.select = document.createElement('nile-select');
|
|
3564
3635
|
this.select.className = 'st-cell-editor';
|
|
3565
|
-
// Apply inline styles for proper cell fitting
|
|
3566
|
-
this.select.style.width = '100%';
|
|
3567
|
-
this.select.style.height = '
|
|
3636
|
+
// Apply inline styles for proper cell fitting - prevent height changes
|
|
3637
|
+
this.select.style.width = 'calc(100% - 4px)';
|
|
3638
|
+
this.select.style.height = '100%';
|
|
3639
|
+
this.select.style.maxHeight = '100%';
|
|
3568
3640
|
this.select.style.boxSizing = 'border-box';
|
|
3641
|
+
this.select.style.margin = '0 2px';
|
|
3642
|
+
this.select.style.overflow = 'hidden';
|
|
3643
|
+
// Inject styles to remove border using ::part selector
|
|
3644
|
+
this.injectBorderlessStyles();
|
|
3645
|
+
// Also try removing outline on host element
|
|
3646
|
+
this.select.style.outline = 'none';
|
|
3647
|
+
this.select.style.border = 'none';
|
|
3569
3648
|
// Set initial value
|
|
3570
3649
|
this.setInitialValue(context.value);
|
|
3571
3650
|
// Apply all configuration options
|
|
@@ -3577,27 +3656,22 @@ class NileSelectEditor {
|
|
|
3577
3656
|
// Clear container and append select
|
|
3578
3657
|
context.container.innerHTML = '';
|
|
3579
3658
|
context.container.appendChild(this.select);
|
|
3580
|
-
// Focus after render
|
|
3659
|
+
// Focus and auto-open after render
|
|
3581
3660
|
setTimeout(() => {
|
|
3582
3661
|
var _a;
|
|
3583
3662
|
(_a = this.select) === null || _a === void 0 ? void 0 : _a.focus();
|
|
3584
|
-
//
|
|
3663
|
+
// Auto-open the dropdown
|
|
3585
3664
|
if (this.select) {
|
|
3586
3665
|
this.select.open = true;
|
|
3587
3666
|
}
|
|
3588
|
-
//
|
|
3589
|
-
|
|
3590
|
-
|
|
3667
|
+
// Clear initializing flag after dropdown has opened
|
|
3668
|
+
setTimeout(() => {
|
|
3669
|
+
this.isInitializing = false;
|
|
3670
|
+
// For multi-select, find the portal div for click detection
|
|
3671
|
+
if (this.options.multiple) {
|
|
3591
3672
|
this.portalDiv = document.querySelector('.nile-select-portal-append');
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
}
|
|
3595
|
-
else {
|
|
3596
|
-
// Clear initializing flag after dropdown has time to open
|
|
3597
|
-
setTimeout(() => {
|
|
3598
|
-
this.isInitializing = false;
|
|
3599
|
-
}, 100);
|
|
3600
|
-
}
|
|
3673
|
+
}
|
|
3674
|
+
}, 100);
|
|
3601
3675
|
}, 0);
|
|
3602
3676
|
}
|
|
3603
3677
|
/**
|
|
@@ -3762,6 +3836,13 @@ class NileSelectEditor {
|
|
|
3762
3836
|
if (!this.select)
|
|
3763
3837
|
return;
|
|
3764
3838
|
const validateOnSave = this.options.validateOnSave !== false;
|
|
3839
|
+
// Prevent click events from bubbling up to the cell container
|
|
3840
|
+
// This prevents parent handlers from interfering with nile-select's toggle
|
|
3841
|
+
const clickHandler = (e) => {
|
|
3842
|
+
e.stopPropagation();
|
|
3843
|
+
};
|
|
3844
|
+
this.select.addEventListener('click', clickHandler);
|
|
3845
|
+
this.eventListeners.push({ event: 'click', handler: clickHandler });
|
|
3765
3846
|
// Handle keyboard events (keydown is not replaced by custom events)
|
|
3766
3847
|
const keydownHandler = (e) => {
|
|
3767
3848
|
const keyEvent = e;
|
|
@@ -3793,7 +3874,8 @@ class NileSelectEditor {
|
|
|
3793
3874
|
};
|
|
3794
3875
|
this.select.addEventListener('nile-change', changeHandler);
|
|
3795
3876
|
this.eventListeners.push({ event: 'nile-change', handler: changeHandler });
|
|
3796
|
-
// Handle blur as secondary save trigger
|
|
3877
|
+
// Handle blur as secondary save trigger - only for single-select
|
|
3878
|
+
// Multi-select uses hide event instead
|
|
3797
3879
|
const blurHandler = (e) => {
|
|
3798
3880
|
var _a, _b;
|
|
3799
3881
|
// Ignore blur during initialization
|
|
@@ -3804,26 +3886,13 @@ class NileSelectEditor {
|
|
|
3804
3886
|
(_b = this.select) === null || _b === void 0 ? void 0 : _b.reportValidity();
|
|
3805
3887
|
return;
|
|
3806
3888
|
}
|
|
3807
|
-
//
|
|
3889
|
+
// For single-select, save on blur (when clicking outside)
|
|
3890
|
+
if (!this.options.multiple) {
|
|
3891
|
+
context.onSave(this.getCurrentValue());
|
|
3892
|
+
}
|
|
3808
3893
|
};
|
|
3809
3894
|
this.select.addEventListener('nile-blur', blurHandler);
|
|
3810
3895
|
this.eventListeners.push({ event: 'nile-blur', handler: blurHandler });
|
|
3811
|
-
// Handle nile-hide event to prevent unwanted closing during initialization
|
|
3812
|
-
const hideHandler = (e) => {
|
|
3813
|
-
// If dropdown closes during initialization, re-open it (for both single and multi-select)
|
|
3814
|
-
if (this.isInitializing) {
|
|
3815
|
-
e.preventDefault();
|
|
3816
|
-
e.stopPropagation();
|
|
3817
|
-
// Re-open the dropdown after a brief delay using the open property
|
|
3818
|
-
setTimeout(() => {
|
|
3819
|
-
if (this.select && this.isInitializing) {
|
|
3820
|
-
this.select.open = true;
|
|
3821
|
-
}
|
|
3822
|
-
}, 10);
|
|
3823
|
-
}
|
|
3824
|
-
};
|
|
3825
|
-
this.select.addEventListener('nile-hide', hideHandler);
|
|
3826
|
-
this.eventListeners.push({ event: 'nile-hide', handler: hideHandler });
|
|
3827
3896
|
// Handle clear button if enabled
|
|
3828
3897
|
if (this.options.clearable) {
|
|
3829
3898
|
const clearHandler = (e) => {
|
|
@@ -3871,7 +3940,8 @@ class NileSelectEditor {
|
|
|
3871
3940
|
setTimeout(() => {
|
|
3872
3941
|
// Only add if select still exists (editor not destroyed)
|
|
3873
3942
|
if (this.select) {
|
|
3874
|
-
|
|
3943
|
+
// Use bubbling phase (false) instead of capture to not interfere with nile-select's toggle
|
|
3944
|
+
document.addEventListener('click', documentClickHandler, false);
|
|
3875
3945
|
this.eventListeners.push({
|
|
3876
3946
|
event: 'document-click',
|
|
3877
3947
|
handler: documentClickHandler
|
|
@@ -3910,8 +3980,8 @@ class NileSelectEditor {
|
|
|
3910
3980
|
this.eventListeners.forEach(({ event, handler }) => {
|
|
3911
3981
|
var _a;
|
|
3912
3982
|
if (event === 'document-click') {
|
|
3913
|
-
// Remove from document for multi-select click handler
|
|
3914
|
-
document.removeEventListener('click', handler,
|
|
3983
|
+
// Remove from document for multi-select click handler (bubbling phase)
|
|
3984
|
+
document.removeEventListener('click', handler, false);
|
|
3915
3985
|
}
|
|
3916
3986
|
else {
|
|
3917
3987
|
// Remove from select element
|
|
@@ -3941,6 +4011,7 @@ class NileSelectEditor {
|
|
|
3941
4011
|
return (Array.isArray(value) ? (value.length > 0 ? value[0] : '') : value);
|
|
3942
4012
|
}
|
|
3943
4013
|
}
|
|
4014
|
+
NileSelectEditor.stylesInjected = false;
|
|
3944
4015
|
|
|
3945
4016
|
/**
|
|
3946
4017
|
* Custom editor using NileAutoComplete from @aquera/nile-elements
|
|
@@ -5156,10 +5227,10 @@ class StCellComponent {
|
|
|
5156
5227
|
}
|
|
5157
5228
|
}
|
|
5158
5229
|
StCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5159
|
-
StCellComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StCellComponent, selector: "st-cell", inputs: { cell: "cell", editMode: "editMode", tableState: "tableState", tableConfig: "tableConfig", columnIndex: "columnIndex" }, outputs: { cellChange: "cellChange", cellEdit: "cellEdit", cellSave: "cellSave", cellCancel: "cellCancel", cellSaveAndNavigate: "cellSaveAndNavigate" }, host: { listeners: { "keydown": "onCellKeyDown($event)" } }, viewQueries: [{ propertyName: "editorContainer", first: true, predicate: ["editorContainer"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div class=\"st-cell\" \n [ngClass]=\"{\n 'editing': cell.isEditing(),\n 'dirty': cell.isDirty(),\n 'invalid': !cell.isValid(),\n 'readonly': !isEditable\n }\"\n (click)=\"onCellClick()\" \n (dblclick)=\"onCellDoubleClick()\">\n\n <!-- Display Mode with Template Support -->\n <ng-container *ngIf=\"!cell.isEditing()\">\n <!-- Custom Template -->\n <ng-container *ngIf=\"hasCellTemplate\">\n <ng-container *ngTemplateOutlet=\"cellTemplate; context: templateContext\"></ng-container>\n </ng-container>\n\n <!-- Default Text Rendering -->\n <span *ngIf=\"!hasCellTemplate\" class=\"cell-display\">\n {{ cell.render() }}\n </span>\n </ng-container>\n\n <!-- Edit Mode -->\n <div *ngIf=\"cell.isEditing()\" class=\"cell-editor\" #editorContainer>\n </div>\n</div>", styles: [".st-cell{position:relative;cursor:pointer;transition:background-color .2s;min-height:28px;display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;box-sizing:border-box}.st-cell.invalid{border-left:2px solid #e53e3e}.st-cell.readonly{cursor:default}.cell-display{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;align-content:center;width:100%;height:100%;padding-left:8px;padding-right:8px;font-size:12px;font-weight:300;letter-spacing:.2px;line-height:14px}.cell-editor{display:flex;height:100%;width:100%}.cell-editor input,.cell-editor select,.cell-editor textarea{width:100%;border:none;outline:none;font:inherit;padding:0;background:transparent;color:inherit}.cell-editor input[type=number]{text-align:inherit}.cell-error{position:absolute;right:4px;top:50%;transform:translateY(-50%);color:#e53e3e;font-weight:700;cursor:help;font-size:14px}\n"], directives: [{ type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
|
|
5230
|
+
StCellComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StCellComponent, selector: "st-cell", inputs: { cell: "cell", editMode: "editMode", tableState: "tableState", tableConfig: "tableConfig", columnIndex: "columnIndex" }, outputs: { cellChange: "cellChange", cellEdit: "cellEdit", cellSave: "cellSave", cellCancel: "cellCancel", cellSaveAndNavigate: "cellSaveAndNavigate" }, host: { listeners: { "keydown": "onCellKeyDown($event)" } }, viewQueries: [{ propertyName: "editorContainer", first: true, predicate: ["editorContainer"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div class=\"st-cell\" \n [ngClass]=\"{\n 'editing': cell.isEditing(),\n 'dirty': cell.isDirty(),\n 'invalid': !cell.isValid(),\n 'readonly': !isEditable\n }\"\n (click)=\"onCellClick()\" \n (dblclick)=\"onCellDoubleClick()\">\n\n <!-- Display Mode with Template Support -->\n <ng-container *ngIf=\"!cell.isEditing()\">\n <!-- Custom Template -->\n <ng-container *ngIf=\"hasCellTemplate\">\n <ng-container *ngTemplateOutlet=\"cellTemplate; context: templateContext\"></ng-container>\n </ng-container>\n\n <!-- Default Text Rendering -->\n <span *ngIf=\"!hasCellTemplate\" class=\"cell-display\">\n {{ cell.render() }}\n </span>\n </ng-container>\n\n <!-- Edit Mode -->\n <div *ngIf=\"cell.isEditing()\" class=\"cell-editor\" #editorContainer>\n </div>\n</div>", styles: [".st-cell{position:relative;cursor:pointer;transition:background-color .2s;min-height:28px;display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;box-sizing:border-box}.st-cell.invalid{border-left:2px solid #e53e3e}.st-cell.readonly{cursor:default}.cell-display{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;align-content:center;width:100%;height:100%;padding-left:8px;padding-right:8px;font-size:12px;font-weight:300;letter-spacing:.2px;line-height:14px}.cell-editor{display:flex;height:100%;width:100%}.cell-editor input,.cell-editor select,.cell-editor textarea{width:100%;border:none;outline:none;font:inherit;padding:0;background:transparent;color:inherit}.cell-editor input[type=number]{text-align:inherit}.cell-editor nile-select::part(combobox){border:none!important;outline:none!important;box-shadow:none!important}.cell-editor nile-select::part(tag){border:none!important;outline:none!important}.cell-editor nile-select::part(listbox){border:none!important}.cell-error{position:absolute;right:4px;top:50%;transform:translateY(-50%);color:#e53e3e;font-weight:700;cursor:help;font-size:14px}\n"], directives: [{ type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
|
|
5160
5231
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StCellComponent, decorators: [{
|
|
5161
5232
|
type: Component,
|
|
5162
|
-
args: [{ selector: 'st-cell', template: "<div class=\"st-cell\" \n [ngClass]=\"{\n 'editing': cell.isEditing(),\n 'dirty': cell.isDirty(),\n 'invalid': !cell.isValid(),\n 'readonly': !isEditable\n }\"\n (click)=\"onCellClick()\" \n (dblclick)=\"onCellDoubleClick()\">\n\n <!-- Display Mode with Template Support -->\n <ng-container *ngIf=\"!cell.isEditing()\">\n <!-- Custom Template -->\n <ng-container *ngIf=\"hasCellTemplate\">\n <ng-container *ngTemplateOutlet=\"cellTemplate; context: templateContext\"></ng-container>\n </ng-container>\n\n <!-- Default Text Rendering -->\n <span *ngIf=\"!hasCellTemplate\" class=\"cell-display\">\n {{ cell.render() }}\n </span>\n </ng-container>\n\n <!-- Edit Mode -->\n <div *ngIf=\"cell.isEditing()\" class=\"cell-editor\" #editorContainer>\n </div>\n</div>", styles: [".st-cell{position:relative;cursor:pointer;transition:background-color .2s;min-height:28px;display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;box-sizing:border-box}.st-cell.invalid{border-left:2px solid #e53e3e}.st-cell.readonly{cursor:default}.cell-display{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;align-content:center;width:100%;height:100%;padding-left:8px;padding-right:8px;font-size:12px;font-weight:300;letter-spacing:.2px;line-height:14px}.cell-editor{display:flex;height:100%;width:100%}.cell-editor input,.cell-editor select,.cell-editor textarea{width:100%;border:none;outline:none;font:inherit;padding:0;background:transparent;color:inherit}.cell-editor input[type=number]{text-align:inherit}.cell-error{position:absolute;right:4px;top:50%;transform:translateY(-50%);color:#e53e3e;font-weight:700;cursor:help;font-size:14px}\n"] }]
|
|
5233
|
+
args: [{ selector: 'st-cell', template: "<div class=\"st-cell\" \n [ngClass]=\"{\n 'editing': cell.isEditing(),\n 'dirty': cell.isDirty(),\n 'invalid': !cell.isValid(),\n 'readonly': !isEditable\n }\"\n (click)=\"onCellClick()\" \n (dblclick)=\"onCellDoubleClick()\">\n\n <!-- Display Mode with Template Support -->\n <ng-container *ngIf=\"!cell.isEditing()\">\n <!-- Custom Template -->\n <ng-container *ngIf=\"hasCellTemplate\">\n <ng-container *ngTemplateOutlet=\"cellTemplate; context: templateContext\"></ng-container>\n </ng-container>\n\n <!-- Default Text Rendering -->\n <span *ngIf=\"!hasCellTemplate\" class=\"cell-display\">\n {{ cell.render() }}\n </span>\n </ng-container>\n\n <!-- Edit Mode -->\n <div *ngIf=\"cell.isEditing()\" class=\"cell-editor\" #editorContainer>\n </div>\n</div>", styles: [".st-cell{position:relative;cursor:pointer;transition:background-color .2s;min-height:28px;display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;box-sizing:border-box}.st-cell.invalid{border-left:2px solid #e53e3e}.st-cell.readonly{cursor:default}.cell-display{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;align-content:center;width:100%;height:100%;padding-left:8px;padding-right:8px;font-size:12px;font-weight:300;letter-spacing:.2px;line-height:14px}.cell-editor{display:flex;height:100%;width:100%}.cell-editor input,.cell-editor select,.cell-editor textarea{width:100%;border:none;outline:none;font:inherit;padding:0;background:transparent;color:inherit}.cell-editor input[type=number]{text-align:inherit}.cell-editor nile-select::part(combobox){border:none!important;outline:none!important;box-shadow:none!important}.cell-editor nile-select::part(tag){border:none!important;outline:none!important}.cell-editor nile-select::part(listbox){border:none!important}.cell-error{position:absolute;right:4px;top:50%;transform:translateY(-50%);color:#e53e3e;font-weight:700;cursor:help;font-size:14px}\n"] }]
|
|
5163
5234
|
}], ctorParameters: function () { return []; }, propDecorators: { cell: [{
|
|
5164
5235
|
type: Input
|
|
5165
5236
|
}], editMode: [{
|
|
@@ -8757,6 +8828,51 @@ class StTableComponent {
|
|
|
8757
8828
|
scrollContainer.scrollTop += (cellRect.bottom - visibleBottom);
|
|
8758
8829
|
}
|
|
8759
8830
|
}
|
|
8831
|
+
/**
|
|
8832
|
+
* Scroll to a specific row by index and optionally focus it
|
|
8833
|
+
* @param rowIndex - The index of the row to scroll to
|
|
8834
|
+
* @param focusFirstCell - Whether to focus the first editable cell (default: false)
|
|
8835
|
+
*/
|
|
8836
|
+
scrollToRowAndFocus(rowIndex, focusFirstCell = false) {
|
|
8837
|
+
setTimeout(() => {
|
|
8838
|
+
var _a;
|
|
8839
|
+
const hostElement = (_a = this.elementRef) === null || _a === void 0 ? void 0 : _a.nativeElement;
|
|
8840
|
+
if (!hostElement)
|
|
8841
|
+
return;
|
|
8842
|
+
// Find the target row
|
|
8843
|
+
const rows = hostElement.querySelectorAll('tbody tr');
|
|
8844
|
+
const targetRow = rows[rowIndex];
|
|
8845
|
+
if (targetRow) {
|
|
8846
|
+
// Scroll the row into view
|
|
8847
|
+
targetRow.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
8848
|
+
// Optionally focus the first editable cell
|
|
8849
|
+
if (focusFirstCell) {
|
|
8850
|
+
const cells = targetRow.querySelectorAll('td:not(.settings-column):not(.row-number-cell)');
|
|
8851
|
+
const firstCell = cells[0];
|
|
8852
|
+
if (firstCell && typeof firstCell.focus === 'function') {
|
|
8853
|
+
setTimeout(() => {
|
|
8854
|
+
firstCell.focus();
|
|
8855
|
+
// Update table state focus position
|
|
8856
|
+
if (this.tableState) {
|
|
8857
|
+
this.tableState.focusCell(rowIndex, 0);
|
|
8858
|
+
}
|
|
8859
|
+
}, 100);
|
|
8860
|
+
}
|
|
8861
|
+
}
|
|
8862
|
+
}
|
|
8863
|
+
}, 0);
|
|
8864
|
+
}
|
|
8865
|
+
/**
|
|
8866
|
+
* Scroll to the last row in the table
|
|
8867
|
+
* @param focusFirstCell - Whether to focus the first editable cell (default: true)
|
|
8868
|
+
*/
|
|
8869
|
+
scrollToLastRow(focusFirstCell = true) {
|
|
8870
|
+
var _a;
|
|
8871
|
+
const rowCount = ((_a = this.data) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
8872
|
+
if (rowCount > 0) {
|
|
8873
|
+
this.scrollToRowAndFocus(rowCount - 1, focusFirstCell);
|
|
8874
|
+
}
|
|
8875
|
+
}
|
|
8760
8876
|
/**
|
|
8761
8877
|
* Get the scroll container element
|
|
8762
8878
|
*/
|
|
@@ -10294,12 +10410,34 @@ class StWorkbookComponent {
|
|
|
10294
10410
|
};
|
|
10295
10411
|
window.addEventListener('beforeunload', this.beforeUnloadHandler);
|
|
10296
10412
|
}
|
|
10413
|
+
// ===================================================
|
|
10414
|
+
// Public API Methods
|
|
10415
|
+
// ===================================================
|
|
10416
|
+
/**
|
|
10417
|
+
* Scroll to a specific row in the current table
|
|
10418
|
+
* @param rowIndex - The index of the row to scroll to
|
|
10419
|
+
* @param focusFirstCell - Whether to focus the first editable cell (default: false)
|
|
10420
|
+
*/
|
|
10421
|
+
scrollToRow(rowIndex, focusFirstCell = false) {
|
|
10422
|
+
if (this.tableComponent) {
|
|
10423
|
+
this.tableComponent.scrollToRowAndFocus(rowIndex, focusFirstCell);
|
|
10424
|
+
}
|
|
10425
|
+
}
|
|
10426
|
+
/**
|
|
10427
|
+
* Scroll to the last row in the current table
|
|
10428
|
+
* @param focusFirstCell - Whether to focus the first editable cell (default: true)
|
|
10429
|
+
*/
|
|
10430
|
+
scrollToLastRow(focusFirstCell = true) {
|
|
10431
|
+
if (this.tableComponent) {
|
|
10432
|
+
this.tableComponent.scrollToLastRow(focusFirstCell);
|
|
10433
|
+
}
|
|
10434
|
+
}
|
|
10297
10435
|
}
|
|
10298
10436
|
StWorkbookComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StWorkbookComponent, deps: [{ token: AutosaveService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
10299
|
-
StWorkbookComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StWorkbookComponent, selector: "st-workbook", inputs: { config: "config", sheetsData: "sheetsData", state: "state" }, outputs: { sheetChanged: "sheetChanged", addSheet: "addSheet", sheetTabAction: "sheetTabAction", workbookAction: "workbookAction", cellChange: "cellChange", cellSave: "cellSave", tableStateChange: "tableStateChange", fullscreenToggle: "fullscreenToggle", requestAddRow: "requestAddRow" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"workbook-container\" [class.fullscreen]=\"isFullscreen$ | async\">\n <nile-tab-group [activeIndex]=\"activeSheetIndex\">\n \n <!-- Sheet Tabs (one per sheet) -->\n <nile-tab *ngFor=\"let sheet of sheets; let i = index\"\n slot=\"nav\" \n panel=\"shared-panel\"\n [class.active]=\"i === activeSheetIndex\"\n (click)=\"onTabChange(i)\">\n <div class=\"sheet-tab-content\">\n <span class=\"sheet-name\">{{ sheet.name }}</span>\n \n <!-- Tab actions dropdown button -->\n <button class=\"tab-actions-button\"\n (click)=\"openTabActions($event, sheet, i)\"\n *ngIf=\"hasTabActions(sheet)\">\n <nile-icon name=\"arrowdown\" size=\"14\"></nile-icon>\n </button>\n </div>\n </nile-tab>\n \n <!-- Toolbar Tab (for workbook controls) -->\n <nile-tab slot=\"nav\" \n panel=\"shared-panel\"\n class=\"workbook-toolbar-tab\"\n [disabled]=\"true\">\n <div class=\"workbook-toolbar-content\">\n <!-- Autosave Indicator -->\n <div class=\"autosave-indicator\" *ngIf=\"autosaveEnabled\">\n <nile-icon \n *ngIf=\"!isSaving && lastSaveTime\" \n name=\"save\" \n size=\"14\"\n [title]=\"'Saved at ' + (lastSaveTime | date:'HH:mm:ss')\">\n </nile-icon>\n <nile-icon \n *ngIf=\"isSaving\" \n name=\"loader\" \n size=\"14\"\n title=\"Saving...\">\n </nile-icon>\n </div>\n\n <!-- Workbook Actions Dropdown -->\n <button class=\"workbook-actions-button\"\n *ngIf=\"config.workbookActions && config.workbookActions.length > 0\"\n (click)=\"toggleWorkbookActions($event)\"\n title=\"Workbook Actions\">\n <nile-icon name=\"settings\"></nile-icon>\n </button>\n \n <!-- Add Sheet Button -->\n <button class=\"add-sheet-button\"\n *ngIf=\"canAddSheet\"\n (click)=\"onAddSheet()\"\n title=\"Add Sheet\">\n <nile-icon name=\"plus\"></nile-icon>\n </button>\n \n <!-- Fullscreen Button -->\n <button class=\"fullscreen-button\"\n *ngIf=\"config.display?.allowFullscreen !== false\"\n (click)=\"toggleFullscreen()\"\n [title]=\"(isFullscreen$ | async) ? 'Exit Fullscreen' : 'Fullscreen'\">\n <nile-icon [name]=\"(isFullscreen$ | async) ? 'collapse' : 'expand-06'\"></nile-icon>\n </button>\n </div>\n </nile-tab>\n \n <!-- Single Shared Tab Panel -->\n <nile-tab-panel name=\"shared-panel\">\n <!-- Lazy loading strategy: table is destroyed and recreated with new config/state when sheet changes -->\n <!-- Using ngFor with trackBy to force complete reinitialization when tableComponentKey changes -->\n <ng-container *ngFor=\"let key of [tableComponentKey]; trackBy: trackByKey\">\n <st-table *ngIf=\"currentTableConfig && currentTableState\"\n [attr.data-sheet-key]=\"key\"\n [tableConfig]=\"currentTableConfig\"\n [data$]=\"currentTableData$\"\n [tableState]=\"currentTableState\"\n (cellChange)=\"onCellChange($event)\"\n (cellSave)=\"onCellSave($event)\"\n (stateChange)=\"onTableStateChange($event)\"\n (requestAddRow)=\"onRequestAddRow($event)\">\n </st-table>\n </ng-container>\n </nile-tab-panel>\n \n </nile-tab-group>\n</div>\n\n<!-- Tab Actions Dropdown -->\n<div class=\"tab-actions-dropdown\" \n *ngIf=\"tabActionsOpen\"\n [ngStyle]=\"tabActionsPosition\">\n <div class=\"dropdown-backdrop\" (click)=\"closeTabActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n <nile-menu-item *ngFor=\"let action of selectedSheet?.tabActions\" \n (click)=\"onTabActionClick(action, $event)\">\n <nile-icon *ngIf=\"action.icon\" slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n {{ action.label }}\n </nile-menu-item>\n </nile-menu>\n </div>\n</div>\n\n<!-- Workbook Actions Dropdown -->\n<div class=\"workbook-actions-dropdown\"\n *ngIf=\"workbookActionsOpen\"\n [ngStyle]=\"workbookActionsPosition\">\n <div class=\"dropdown-backdrop\" (click)=\"closeWorkbookActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n <nile-menu-item *ngFor=\"let action of visibleWorkbookActions\"\n [class.disabled]=\"isActionDisabled(action)\"\n (click)=\"onWorkbookActionClick(action, $event)\">\n <nile-icon *ngIf=\"action.icon\" slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n {{ action.label }}\n </nile-menu-item>\n </nile-menu>\n </div>\n</div>\n\n<!-- Fullscreen Backdrop -->\n<div class=\"fullscreen-backdrop\" \n *ngIf=\"isFullscreen$ | async\"\n (click)=\"toggleFullscreen()\">\n</div>\n\n", styles: ["@import\"@aquera/nile/lib/styles/variables.css\";:host{display:block;width:100%;height:100%}.workbook-container{display:flex;flex-direction:column;height:100%;background:white;border:1px solid var(--nile-color-neutral-200);border-radius:4px;overflow:hidden}.workbook-container.fullscreen{position:fixed;inset:0;z-index:2000;border:none;border-radius:0}.workbook-container nile-tab-group{height:100%;display:flex;flex-direction:column}.sheet-tab-content{display:flex;align-items:center;gap:8px;padding:0 4px}.sheet-tab-content .sheet-name{font-size:12px;font-weight:500;font-family:var(--nile-font-family-sans-serif);color:#000}.sheet-tab-content .tab-actions-button{width:20px;height:20px;padding:0;background:transparent;border:none;cursor:pointer}.workbook-toolbar-tab{margin-left:auto!important;pointer-events:auto!important;border-left:1px solid var(--nile-color-neutral-200)}.workbook-toolbar-tab .workbook-toolbar-content{display:flex;gap:4px;align-items:center;padding:0 8px}.workbook-toolbar-tab .workbook-toolbar-content .autosave-indicator{display:flex;align-items:center;margin-right:8px;color:var(--nile-color-success-500)}.workbook-toolbar-tab button{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:transparent;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s;color:var(--nile-color-neutral-600)}.workbook-toolbar-tab button:hover{background-color:var(--nile-color-neutral-100);color:var(--nile-color-neutral-900)}.workbook-toolbar-tab button:active{background-color:var(--nile-color-neutral-200)}.workbook-toolbar-tab button nile-icon{font-size:16px}.tab-actions-dropdown{position:fixed;z-index:1001}.tab-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.tab-actions-dropdown .dropdown-menu{position:relative;min-width:180px;background:white;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.tab-actions-dropdown .dropdown-menu nile-menu{display:block}.workbook-actions-dropdown{position:fixed;z-index:1001}.workbook-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.workbook-actions-dropdown .dropdown-menu{position:relative;min-width:200px;background:white;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.workbook-actions-dropdown .dropdown-menu nile-menu{display:block}.fullscreen-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:1999;cursor:pointer}nile-tab-group::part(nav){background-color:#fafafa}nile-tab-group::part(active-tab-indicator-path){background:none}nile-tab-group::part(active-tab-indicator){border-bottom:none}nile-tab-group::part(tabs){gap:0}nile-tab-group nile-tab{border:1px solid #e0e0e0;border-top-left-radius:6px;border-top-right-radius:6px}nile-tab-group nile-tab::part(base){padding-left:.5rem;padding-top:.5rem;padding-bottom:.5rem;border-bottom-left-radius:0;border-bottom-right-radius:0}nile-tab-group nile-tab.active{background-color:#fff;color:#000}nile-tab-group nile-tab-panel::part(base){padding:0;max-height:30rem}\n"], components: [{ type: StTableComponent, selector: "st-table", inputs: ["tableConfig", "data", "data$", "tableState", "enableSorting", "enableFiltering", "validateConfig"], outputs: ["stateChange", "dataChange", "cellEdit", "cellSave", "cellCancel", "cellChange", "columnResized", "columnMoved", "configValidationErrors", "columnAdded", "rowAction", "validationStateChange", "requestAddRow"] }], directives: [{ type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], pipes: { "async": i1.AsyncPipe, "date": i1.DatePipe } });
|
|
10437
|
+
StWorkbookComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: StWorkbookComponent, selector: "st-workbook", inputs: { config: "config", sheetsData: "sheetsData", state: "state" }, outputs: { sheetChanged: "sheetChanged", addSheet: "addSheet", sheetTabAction: "sheetTabAction", workbookAction: "workbookAction", cellChange: "cellChange", cellSave: "cellSave", tableStateChange: "tableStateChange", fullscreenToggle: "fullscreenToggle", requestAddRow: "requestAddRow" }, viewQueries: [{ propertyName: "tableComponent", first: true, predicate: StTableComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"workbook-container\" [class.fullscreen]=\"isFullscreen$ | async\">\n <nile-tab-group [activeIndex]=\"activeSheetIndex\">\n \n <!-- Sheet Tabs (one per sheet) -->\n <nile-tab *ngFor=\"let sheet of sheets; let i = index\"\n slot=\"nav\" \n panel=\"shared-panel\"\n [class.active]=\"i === activeSheetIndex\"\n (click)=\"onTabChange(i)\">\n <div class=\"sheet-tab-content\">\n <span class=\"sheet-name\">{{ sheet.name }}</span>\n \n <!-- Tab actions dropdown button -->\n <button class=\"tab-actions-button\"\n (click)=\"openTabActions($event, sheet, i)\"\n *ngIf=\"hasTabActions(sheet)\">\n <nile-icon name=\"arrowdown\" size=\"14\"></nile-icon>\n </button>\n </div>\n </nile-tab>\n \n <!-- Toolbar Tab (for workbook controls) -->\n <nile-tab slot=\"nav\" \n panel=\"shared-panel\"\n class=\"workbook-toolbar-tab\"\n [disabled]=\"true\">\n <div class=\"workbook-toolbar-content\">\n <!-- Autosave Indicator -->\n <div class=\"autosave-indicator\" *ngIf=\"autosaveEnabled\">\n <nile-icon \n *ngIf=\"!isSaving && lastSaveTime\" \n name=\"save\" \n size=\"14\"\n [title]=\"'Saved at ' + (lastSaveTime | date:'HH:mm:ss')\">\n </nile-icon>\n <nile-icon \n *ngIf=\"isSaving\" \n name=\"loader\" \n size=\"14\"\n title=\"Saving...\">\n </nile-icon>\n </div>\n\n <!-- Workbook Actions Dropdown -->\n <button class=\"workbook-actions-button\"\n *ngIf=\"config.workbookActions && config.workbookActions.length > 0\"\n (click)=\"toggleWorkbookActions($event)\"\n title=\"Workbook Actions\">\n <nile-icon name=\"settings\"></nile-icon>\n </button>\n \n <!-- Add Sheet Button -->\n <button class=\"add-sheet-button\"\n *ngIf=\"canAddSheet\"\n (click)=\"onAddSheet()\"\n title=\"Add Sheet\">\n <nile-icon name=\"plus\"></nile-icon>\n </button>\n \n <!-- Fullscreen Button -->\n <button class=\"fullscreen-button\"\n *ngIf=\"config.display?.allowFullscreen !== false\"\n (click)=\"toggleFullscreen()\"\n [title]=\"(isFullscreen$ | async) ? 'Exit Fullscreen' : 'Fullscreen'\">\n <nile-icon [name]=\"(isFullscreen$ | async) ? 'collapse' : 'expand-06'\"></nile-icon>\n </button>\n </div>\n </nile-tab>\n \n <!-- Single Shared Tab Panel -->\n <nile-tab-panel name=\"shared-panel\">\n <!-- Lazy loading strategy: table is destroyed and recreated with new config/state when sheet changes -->\n <!-- Using ngFor with trackBy to force complete reinitialization when tableComponentKey changes -->\n <ng-container *ngFor=\"let key of [tableComponentKey]; trackBy: trackByKey\">\n <st-table *ngIf=\"currentTableConfig && currentTableState\"\n [attr.data-sheet-key]=\"key\"\n [tableConfig]=\"currentTableConfig\"\n [data$]=\"currentTableData$\"\n [tableState]=\"currentTableState\"\n (cellChange)=\"onCellChange($event)\"\n (cellSave)=\"onCellSave($event)\"\n (stateChange)=\"onTableStateChange($event)\"\n (requestAddRow)=\"onRequestAddRow($event)\">\n </st-table>\n </ng-container>\n </nile-tab-panel>\n \n </nile-tab-group>\n</div>\n\n<!-- Tab Actions Dropdown -->\n<div class=\"tab-actions-dropdown\" \n *ngIf=\"tabActionsOpen\"\n [ngStyle]=\"tabActionsPosition\">\n <div class=\"dropdown-backdrop\" (click)=\"closeTabActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n <nile-menu-item *ngFor=\"let action of selectedSheet?.tabActions\" \n (click)=\"onTabActionClick(action, $event)\">\n <nile-icon *ngIf=\"action.icon\" slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n {{ action.label }}\n </nile-menu-item>\n </nile-menu>\n </div>\n</div>\n\n<!-- Workbook Actions Dropdown -->\n<div class=\"workbook-actions-dropdown\"\n *ngIf=\"workbookActionsOpen\"\n [ngStyle]=\"workbookActionsPosition\">\n <div class=\"dropdown-backdrop\" (click)=\"closeWorkbookActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n <nile-menu-item *ngFor=\"let action of visibleWorkbookActions\"\n [class.disabled]=\"isActionDisabled(action)\"\n (click)=\"onWorkbookActionClick(action, $event)\">\n <nile-icon *ngIf=\"action.icon\" slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n {{ action.label }}\n </nile-menu-item>\n </nile-menu>\n </div>\n</div>\n\n<!-- Fullscreen Backdrop -->\n<div class=\"fullscreen-backdrop\" \n *ngIf=\"isFullscreen$ | async\"\n (click)=\"toggleFullscreen()\">\n</div>\n\n", styles: ["@import\"@aquera/nile/lib/styles/variables.css\";:host{display:block;width:100%;height:100%}.workbook-container{display:flex;flex-direction:column;height:100%;background:white;border:1px solid var(--nile-color-neutral-200);border-radius:4px;overflow:hidden}.workbook-container.fullscreen{position:fixed;inset:0;z-index:2000;border:none;border-radius:0}.workbook-container nile-tab-group{height:100%;display:flex;flex-direction:column}.sheet-tab-content{display:flex;align-items:center;gap:8px;padding:0 4px}.sheet-tab-content .sheet-name{font-size:12px;font-weight:500;font-family:var(--nile-font-family-sans-serif);color:#000}.sheet-tab-content .tab-actions-button{width:20px;height:20px;padding:0;background:transparent;border:none;cursor:pointer}.workbook-toolbar-tab{margin-left:auto!important;pointer-events:auto!important;border-left:1px solid var(--nile-color-neutral-200)}.workbook-toolbar-tab .workbook-toolbar-content{display:flex;gap:4px;align-items:center;padding:0 8px}.workbook-toolbar-tab .workbook-toolbar-content .autosave-indicator{display:flex;align-items:center;margin-right:8px;color:var(--nile-color-success-500)}.workbook-toolbar-tab button{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:transparent;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s;color:var(--nile-color-neutral-600)}.workbook-toolbar-tab button:hover{background-color:var(--nile-color-neutral-100);color:var(--nile-color-neutral-900)}.workbook-toolbar-tab button:active{background-color:var(--nile-color-neutral-200)}.workbook-toolbar-tab button nile-icon{font-size:16px}.tab-actions-dropdown{position:fixed;z-index:1001}.tab-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.tab-actions-dropdown .dropdown-menu{position:relative;min-width:180px;background:white;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.tab-actions-dropdown .dropdown-menu nile-menu{display:block}.workbook-actions-dropdown{position:fixed;z-index:1001}.workbook-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.workbook-actions-dropdown .dropdown-menu{position:relative;min-width:200px;background:white;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.workbook-actions-dropdown .dropdown-menu nile-menu{display:block}.fullscreen-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:1999;cursor:pointer}nile-tab-group::part(nav){background-color:#fafafa}nile-tab-group::part(active-tab-indicator-path){background:none}nile-tab-group::part(active-tab-indicator){border-bottom:none}nile-tab-group::part(tabs){gap:0}nile-tab-group nile-tab{border:1px solid #e0e0e0;border-top-left-radius:6px;border-top-right-radius:6px}nile-tab-group nile-tab::part(base){padding-left:.5rem;padding-top:.5rem;padding-bottom:.5rem;border-bottom-left-radius:0;border-bottom-right-radius:0}nile-tab-group nile-tab.active{background-color:#fff;color:#000}nile-tab-group nile-tab.active .sheet-name{font-weight:600}nile-tab-group nile-tab-panel::part(base){padding:0;max-height:30rem}\n"], components: [{ type: StTableComponent, selector: "st-table", inputs: ["tableConfig", "data", "data$", "tableState", "enableSorting", "enableFiltering", "validateConfig"], outputs: ["stateChange", "dataChange", "cellEdit", "cellSave", "cellCancel", "cellChange", "columnResized", "columnMoved", "configValidationErrors", "columnAdded", "rowAction", "validationStateChange", "requestAddRow"] }], directives: [{ type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], pipes: { "async": i1.AsyncPipe, "date": i1.DatePipe } });
|
|
10300
10438
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: StWorkbookComponent, decorators: [{
|
|
10301
10439
|
type: Component,
|
|
10302
|
-
args: [{ selector: 'st-workbook', template: "<div class=\"workbook-container\" [class.fullscreen]=\"isFullscreen$ | async\">\n <nile-tab-group [activeIndex]=\"activeSheetIndex\">\n \n <!-- Sheet Tabs (one per sheet) -->\n <nile-tab *ngFor=\"let sheet of sheets; let i = index\"\n slot=\"nav\" \n panel=\"shared-panel\"\n [class.active]=\"i === activeSheetIndex\"\n (click)=\"onTabChange(i)\">\n <div class=\"sheet-tab-content\">\n <span class=\"sheet-name\">{{ sheet.name }}</span>\n \n <!-- Tab actions dropdown button -->\n <button class=\"tab-actions-button\"\n (click)=\"openTabActions($event, sheet, i)\"\n *ngIf=\"hasTabActions(sheet)\">\n <nile-icon name=\"arrowdown\" size=\"14\"></nile-icon>\n </button>\n </div>\n </nile-tab>\n \n <!-- Toolbar Tab (for workbook controls) -->\n <nile-tab slot=\"nav\" \n panel=\"shared-panel\"\n class=\"workbook-toolbar-tab\"\n [disabled]=\"true\">\n <div class=\"workbook-toolbar-content\">\n <!-- Autosave Indicator -->\n <div class=\"autosave-indicator\" *ngIf=\"autosaveEnabled\">\n <nile-icon \n *ngIf=\"!isSaving && lastSaveTime\" \n name=\"save\" \n size=\"14\"\n [title]=\"'Saved at ' + (lastSaveTime | date:'HH:mm:ss')\">\n </nile-icon>\n <nile-icon \n *ngIf=\"isSaving\" \n name=\"loader\" \n size=\"14\"\n title=\"Saving...\">\n </nile-icon>\n </div>\n\n <!-- Workbook Actions Dropdown -->\n <button class=\"workbook-actions-button\"\n *ngIf=\"config.workbookActions && config.workbookActions.length > 0\"\n (click)=\"toggleWorkbookActions($event)\"\n title=\"Workbook Actions\">\n <nile-icon name=\"settings\"></nile-icon>\n </button>\n \n <!-- Add Sheet Button -->\n <button class=\"add-sheet-button\"\n *ngIf=\"canAddSheet\"\n (click)=\"onAddSheet()\"\n title=\"Add Sheet\">\n <nile-icon name=\"plus\"></nile-icon>\n </button>\n \n <!-- Fullscreen Button -->\n <button class=\"fullscreen-button\"\n *ngIf=\"config.display?.allowFullscreen !== false\"\n (click)=\"toggleFullscreen()\"\n [title]=\"(isFullscreen$ | async) ? 'Exit Fullscreen' : 'Fullscreen'\">\n <nile-icon [name]=\"(isFullscreen$ | async) ? 'collapse' : 'expand-06'\"></nile-icon>\n </button>\n </div>\n </nile-tab>\n \n <!-- Single Shared Tab Panel -->\n <nile-tab-panel name=\"shared-panel\">\n <!-- Lazy loading strategy: table is destroyed and recreated with new config/state when sheet changes -->\n <!-- Using ngFor with trackBy to force complete reinitialization when tableComponentKey changes -->\n <ng-container *ngFor=\"let key of [tableComponentKey]; trackBy: trackByKey\">\n <st-table *ngIf=\"currentTableConfig && currentTableState\"\n [attr.data-sheet-key]=\"key\"\n [tableConfig]=\"currentTableConfig\"\n [data$]=\"currentTableData$\"\n [tableState]=\"currentTableState\"\n (cellChange)=\"onCellChange($event)\"\n (cellSave)=\"onCellSave($event)\"\n (stateChange)=\"onTableStateChange($event)\"\n (requestAddRow)=\"onRequestAddRow($event)\">\n </st-table>\n </ng-container>\n </nile-tab-panel>\n \n </nile-tab-group>\n</div>\n\n<!-- Tab Actions Dropdown -->\n<div class=\"tab-actions-dropdown\" \n *ngIf=\"tabActionsOpen\"\n [ngStyle]=\"tabActionsPosition\">\n <div class=\"dropdown-backdrop\" (click)=\"closeTabActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n <nile-menu-item *ngFor=\"let action of selectedSheet?.tabActions\" \n (click)=\"onTabActionClick(action, $event)\">\n <nile-icon *ngIf=\"action.icon\" slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n {{ action.label }}\n </nile-menu-item>\n </nile-menu>\n </div>\n</div>\n\n<!-- Workbook Actions Dropdown -->\n<div class=\"workbook-actions-dropdown\"\n *ngIf=\"workbookActionsOpen\"\n [ngStyle]=\"workbookActionsPosition\">\n <div class=\"dropdown-backdrop\" (click)=\"closeWorkbookActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n <nile-menu-item *ngFor=\"let action of visibleWorkbookActions\"\n [class.disabled]=\"isActionDisabled(action)\"\n (click)=\"onWorkbookActionClick(action, $event)\">\n <nile-icon *ngIf=\"action.icon\" slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n {{ action.label }}\n </nile-menu-item>\n </nile-menu>\n </div>\n</div>\n\n<!-- Fullscreen Backdrop -->\n<div class=\"fullscreen-backdrop\" \n *ngIf=\"isFullscreen$ | async\"\n (click)=\"toggleFullscreen()\">\n</div>\n\n", styles: ["@import\"@aquera/nile/lib/styles/variables.css\";:host{display:block;width:100%;height:100%}.workbook-container{display:flex;flex-direction:column;height:100%;background:white;border:1px solid var(--nile-color-neutral-200);border-radius:4px;overflow:hidden}.workbook-container.fullscreen{position:fixed;inset:0;z-index:2000;border:none;border-radius:0}.workbook-container nile-tab-group{height:100%;display:flex;flex-direction:column}.sheet-tab-content{display:flex;align-items:center;gap:8px;padding:0 4px}.sheet-tab-content .sheet-name{font-size:12px;font-weight:500;font-family:var(--nile-font-family-sans-serif);color:#000}.sheet-tab-content .tab-actions-button{width:20px;height:20px;padding:0;background:transparent;border:none;cursor:pointer}.workbook-toolbar-tab{margin-left:auto!important;pointer-events:auto!important;border-left:1px solid var(--nile-color-neutral-200)}.workbook-toolbar-tab .workbook-toolbar-content{display:flex;gap:4px;align-items:center;padding:0 8px}.workbook-toolbar-tab .workbook-toolbar-content .autosave-indicator{display:flex;align-items:center;margin-right:8px;color:var(--nile-color-success-500)}.workbook-toolbar-tab button{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:transparent;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s;color:var(--nile-color-neutral-600)}.workbook-toolbar-tab button:hover{background-color:var(--nile-color-neutral-100);color:var(--nile-color-neutral-900)}.workbook-toolbar-tab button:active{background-color:var(--nile-color-neutral-200)}.workbook-toolbar-tab button nile-icon{font-size:16px}.tab-actions-dropdown{position:fixed;z-index:1001}.tab-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.tab-actions-dropdown .dropdown-menu{position:relative;min-width:180px;background:white;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.tab-actions-dropdown .dropdown-menu nile-menu{display:block}.workbook-actions-dropdown{position:fixed;z-index:1001}.workbook-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.workbook-actions-dropdown .dropdown-menu{position:relative;min-width:200px;background:white;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.workbook-actions-dropdown .dropdown-menu nile-menu{display:block}.fullscreen-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:1999;cursor:pointer}nile-tab-group::part(nav){background-color:#fafafa}nile-tab-group::part(active-tab-indicator-path){background:none}nile-tab-group::part(active-tab-indicator){border-bottom:none}nile-tab-group::part(tabs){gap:0}nile-tab-group nile-tab{border:1px solid #e0e0e0;border-top-left-radius:6px;border-top-right-radius:6px}nile-tab-group nile-tab::part(base){padding-left:.5rem;padding-top:.5rem;padding-bottom:.5rem;border-bottom-left-radius:0;border-bottom-right-radius:0}nile-tab-group nile-tab.active{background-color:#fff;color:#000}nile-tab-group nile-tab-panel::part(base){padding:0;max-height:30rem}\n"] }]
|
|
10440
|
+
args: [{ selector: 'st-workbook', template: "<div class=\"workbook-container\" [class.fullscreen]=\"isFullscreen$ | async\">\n <nile-tab-group [activeIndex]=\"activeSheetIndex\">\n \n <!-- Sheet Tabs (one per sheet) -->\n <nile-tab *ngFor=\"let sheet of sheets; let i = index\"\n slot=\"nav\" \n panel=\"shared-panel\"\n [class.active]=\"i === activeSheetIndex\"\n (click)=\"onTabChange(i)\">\n <div class=\"sheet-tab-content\">\n <span class=\"sheet-name\">{{ sheet.name }}</span>\n \n <!-- Tab actions dropdown button -->\n <button class=\"tab-actions-button\"\n (click)=\"openTabActions($event, sheet, i)\"\n *ngIf=\"hasTabActions(sheet)\">\n <nile-icon name=\"arrowdown\" size=\"14\"></nile-icon>\n </button>\n </div>\n </nile-tab>\n \n <!-- Toolbar Tab (for workbook controls) -->\n <nile-tab slot=\"nav\" \n panel=\"shared-panel\"\n class=\"workbook-toolbar-tab\"\n [disabled]=\"true\">\n <div class=\"workbook-toolbar-content\">\n <!-- Autosave Indicator -->\n <div class=\"autosave-indicator\" *ngIf=\"autosaveEnabled\">\n <nile-icon \n *ngIf=\"!isSaving && lastSaveTime\" \n name=\"save\" \n size=\"14\"\n [title]=\"'Saved at ' + (lastSaveTime | date:'HH:mm:ss')\">\n </nile-icon>\n <nile-icon \n *ngIf=\"isSaving\" \n name=\"loader\" \n size=\"14\"\n title=\"Saving...\">\n </nile-icon>\n </div>\n\n <!-- Workbook Actions Dropdown -->\n <button class=\"workbook-actions-button\"\n *ngIf=\"config.workbookActions && config.workbookActions.length > 0\"\n (click)=\"toggleWorkbookActions($event)\"\n title=\"Workbook Actions\">\n <nile-icon name=\"settings\"></nile-icon>\n </button>\n \n <!-- Add Sheet Button -->\n <button class=\"add-sheet-button\"\n *ngIf=\"canAddSheet\"\n (click)=\"onAddSheet()\"\n title=\"Add Sheet\">\n <nile-icon name=\"plus\"></nile-icon>\n </button>\n \n <!-- Fullscreen Button -->\n <button class=\"fullscreen-button\"\n *ngIf=\"config.display?.allowFullscreen !== false\"\n (click)=\"toggleFullscreen()\"\n [title]=\"(isFullscreen$ | async) ? 'Exit Fullscreen' : 'Fullscreen'\">\n <nile-icon [name]=\"(isFullscreen$ | async) ? 'collapse' : 'expand-06'\"></nile-icon>\n </button>\n </div>\n </nile-tab>\n \n <!-- Single Shared Tab Panel -->\n <nile-tab-panel name=\"shared-panel\">\n <!-- Lazy loading strategy: table is destroyed and recreated with new config/state when sheet changes -->\n <!-- Using ngFor with trackBy to force complete reinitialization when tableComponentKey changes -->\n <ng-container *ngFor=\"let key of [tableComponentKey]; trackBy: trackByKey\">\n <st-table *ngIf=\"currentTableConfig && currentTableState\"\n [attr.data-sheet-key]=\"key\"\n [tableConfig]=\"currentTableConfig\"\n [data$]=\"currentTableData$\"\n [tableState]=\"currentTableState\"\n (cellChange)=\"onCellChange($event)\"\n (cellSave)=\"onCellSave($event)\"\n (stateChange)=\"onTableStateChange($event)\"\n (requestAddRow)=\"onRequestAddRow($event)\">\n </st-table>\n </ng-container>\n </nile-tab-panel>\n \n </nile-tab-group>\n</div>\n\n<!-- Tab Actions Dropdown -->\n<div class=\"tab-actions-dropdown\" \n *ngIf=\"tabActionsOpen\"\n [ngStyle]=\"tabActionsPosition\">\n <div class=\"dropdown-backdrop\" (click)=\"closeTabActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n <nile-menu-item *ngFor=\"let action of selectedSheet?.tabActions\" \n (click)=\"onTabActionClick(action, $event)\">\n <nile-icon *ngIf=\"action.icon\" slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n {{ action.label }}\n </nile-menu-item>\n </nile-menu>\n </div>\n</div>\n\n<!-- Workbook Actions Dropdown -->\n<div class=\"workbook-actions-dropdown\"\n *ngIf=\"workbookActionsOpen\"\n [ngStyle]=\"workbookActionsPosition\">\n <div class=\"dropdown-backdrop\" (click)=\"closeWorkbookActions()\"></div>\n <div class=\"dropdown-menu\">\n <nile-menu>\n <nile-menu-item *ngFor=\"let action of visibleWorkbookActions\"\n [class.disabled]=\"isActionDisabled(action)\"\n (click)=\"onWorkbookActionClick(action, $event)\">\n <nile-icon *ngIf=\"action.icon\" slot=\"prefix\" size=\"14\" [name]=\"action.icon\"></nile-icon>\n {{ action.label }}\n </nile-menu-item>\n </nile-menu>\n </div>\n</div>\n\n<!-- Fullscreen Backdrop -->\n<div class=\"fullscreen-backdrop\" \n *ngIf=\"isFullscreen$ | async\"\n (click)=\"toggleFullscreen()\">\n</div>\n\n", styles: ["@import\"@aquera/nile/lib/styles/variables.css\";:host{display:block;width:100%;height:100%}.workbook-container{display:flex;flex-direction:column;height:100%;background:white;border:1px solid var(--nile-color-neutral-200);border-radius:4px;overflow:hidden}.workbook-container.fullscreen{position:fixed;inset:0;z-index:2000;border:none;border-radius:0}.workbook-container nile-tab-group{height:100%;display:flex;flex-direction:column}.sheet-tab-content{display:flex;align-items:center;gap:8px;padding:0 4px}.sheet-tab-content .sheet-name{font-size:12px;font-weight:500;font-family:var(--nile-font-family-sans-serif);color:#000}.sheet-tab-content .tab-actions-button{width:20px;height:20px;padding:0;background:transparent;border:none;cursor:pointer}.workbook-toolbar-tab{margin-left:auto!important;pointer-events:auto!important;border-left:1px solid var(--nile-color-neutral-200)}.workbook-toolbar-tab .workbook-toolbar-content{display:flex;gap:4px;align-items:center;padding:0 8px}.workbook-toolbar-tab .workbook-toolbar-content .autosave-indicator{display:flex;align-items:center;margin-right:8px;color:var(--nile-color-success-500)}.workbook-toolbar-tab button{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:transparent;border:none;border-radius:4px;cursor:pointer;transition:background-color .2s;color:var(--nile-color-neutral-600)}.workbook-toolbar-tab button:hover{background-color:var(--nile-color-neutral-100);color:var(--nile-color-neutral-900)}.workbook-toolbar-tab button:active{background-color:var(--nile-color-neutral-200)}.workbook-toolbar-tab button nile-icon{font-size:16px}.tab-actions-dropdown{position:fixed;z-index:1001}.tab-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.tab-actions-dropdown .dropdown-menu{position:relative;min-width:180px;background:white;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.tab-actions-dropdown .dropdown-menu nile-menu{display:block}.workbook-actions-dropdown{position:fixed;z-index:1001}.workbook-actions-dropdown .dropdown-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1000}.workbook-actions-dropdown .dropdown-menu{position:relative;min-width:200px;background:white;border-radius:8px;box-shadow:0 4px 12px #00000026;z-index:1001;overflow:hidden}.workbook-actions-dropdown .dropdown-menu nile-menu{display:block}.fullscreen-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:1999;cursor:pointer}nile-tab-group::part(nav){background-color:#fafafa}nile-tab-group::part(active-tab-indicator-path){background:none}nile-tab-group::part(active-tab-indicator){border-bottom:none}nile-tab-group::part(tabs){gap:0}nile-tab-group nile-tab{border:1px solid #e0e0e0;border-top-left-radius:6px;border-top-right-radius:6px}nile-tab-group nile-tab::part(base){padding-left:.5rem;padding-top:.5rem;padding-bottom:.5rem;border-bottom-left-radius:0;border-bottom-right-radius:0}nile-tab-group nile-tab.active{background-color:#fff;color:#000}nile-tab-group nile-tab.active .sheet-name{font-weight:600}nile-tab-group nile-tab-panel::part(base){padding:0;max-height:30rem}\n"] }]
|
|
10303
10441
|
}], ctorParameters: function () { return [{ type: AutosaveService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { config: [{
|
|
10304
10442
|
type: Input
|
|
10305
10443
|
}], sheetsData: [{
|
|
@@ -10324,6 +10462,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
10324
10462
|
type: Output
|
|
10325
10463
|
}], requestAddRow: [{
|
|
10326
10464
|
type: Output
|
|
10465
|
+
}], tableComponent: [{
|
|
10466
|
+
type: ViewChild,
|
|
10467
|
+
args: [StTableComponent]
|
|
10327
10468
|
}] } });
|
|
10328
10469
|
|
|
10329
10470
|
/**
|