integra-ng 21.0.10 → 21.0.12

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.
@@ -453,7 +453,7 @@ class TooltipComponent {
453
453
  {{ text }}
454
454
  <div class="i-tooltip__arrow"></div>
455
455
  </div>
456
- `, isInline: true, styles: [".i-tooltip{background-color:var(--color-component-background-solid);color:var(--color-text-contrast)}.i-tooltip--above .i-tooltip__arrow{border-top-color:var(--color-component-background-solid)}.i-tooltip--below .i-tooltip__arrow{border-bottom-color:var(--color-component-background-solid)}.i-tooltip--left .i-tooltip__arrow{border-left-color:var(--color-component-background-solid)}.i-tooltip--right .i-tooltip__arrow{border-right-color:var(--color-component-background-solid)}.i-tooltip{position:relative;padding:8px 12px;border-radius:4px;font-size:.9em;line-height:1.4;white-space:nowrap;max-width:200px;word-wrap:break-word;white-space:normal;z-index:9999;opacity:0;animation:fadeIn .2s ease-in-out forwards}.i-tooltip__arrow{position:absolute;width:0;height:0;border:6px solid transparent}.i-tooltip--above .i-tooltip__arrow{bottom:-6px;left:50%;transform:translate(-50%);border-bottom:none}.i-tooltip--below .i-tooltip__arrow{top:-6px;left:50%;transform:translate(-50%);border-top:none}.i-tooltip--left .i-tooltip__arrow{right:-6px;top:50%;transform:translateY(-50%);border-right:none}.i-tooltip--right .i-tooltip__arrow{left:-6px;top:50%;transform:translateY(-50%);border-left:none}@keyframes fadeIn{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}\n"] });
456
+ `, isInline: true, styles: [".i-tooltip{background-color:var(--color-component-background-solid);color:var(--color-text-contrast)}.i-tooltip--above .i-tooltip__arrow{border-top-color:var(--color-component-background-solid)}.i-tooltip--below .i-tooltip__arrow{border-bottom-color:var(--color-component-background-solid)}.i-tooltip--left .i-tooltip__arrow{border-left-color:var(--color-component-background-solid)}.i-tooltip--right .i-tooltip__arrow{border-right-color:var(--color-component-background-solid)}.i-tooltip{position:relative;padding:8px 12px;border-radius:4px;font-size:.9em;line-height:1.4;white-space:nowrap;max-width:200px;word-wrap:break-word;white-space:normal;z-index:10000;opacity:0;animation:fadeIn .2s ease-in-out forwards}.i-tooltip__arrow{position:absolute;width:0;height:0;border:6px solid transparent}.i-tooltip--above .i-tooltip__arrow{bottom:-6px;left:50%;transform:translate(-50%);border-bottom:none}.i-tooltip--below .i-tooltip__arrow{top:-6px;left:50%;transform:translate(-50%);border-top:none}.i-tooltip--left .i-tooltip__arrow{right:-6px;top:50%;transform:translateY(-50%);border-right:none}.i-tooltip--right .i-tooltip__arrow{left:-6px;top:50%;transform:translateY(-50%);border-left:none}@keyframes fadeIn{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}\n"] });
457
457
  }
458
458
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: TooltipComponent, decorators: [{
459
459
  type: Component,
@@ -468,13 +468,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
468
468
  {{ text }}
469
469
  <div class="i-tooltip__arrow"></div>
470
470
  </div>
471
- `, styles: [".i-tooltip{background-color:var(--color-component-background-solid);color:var(--color-text-contrast)}.i-tooltip--above .i-tooltip__arrow{border-top-color:var(--color-component-background-solid)}.i-tooltip--below .i-tooltip__arrow{border-bottom-color:var(--color-component-background-solid)}.i-tooltip--left .i-tooltip__arrow{border-left-color:var(--color-component-background-solid)}.i-tooltip--right .i-tooltip__arrow{border-right-color:var(--color-component-background-solid)}.i-tooltip{position:relative;padding:8px 12px;border-radius:4px;font-size:.9em;line-height:1.4;white-space:nowrap;max-width:200px;word-wrap:break-word;white-space:normal;z-index:9999;opacity:0;animation:fadeIn .2s ease-in-out forwards}.i-tooltip__arrow{position:absolute;width:0;height:0;border:6px solid transparent}.i-tooltip--above .i-tooltip__arrow{bottom:-6px;left:50%;transform:translate(-50%);border-bottom:none}.i-tooltip--below .i-tooltip__arrow{top:-6px;left:50%;transform:translate(-50%);border-top:none}.i-tooltip--left .i-tooltip__arrow{right:-6px;top:50%;transform:translateY(-50%);border-right:none}.i-tooltip--right .i-tooltip__arrow{left:-6px;top:50%;transform:translateY(-50%);border-left:none}@keyframes fadeIn{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}\n"] }]
471
+ `, styles: [".i-tooltip{background-color:var(--color-component-background-solid);color:var(--color-text-contrast)}.i-tooltip--above .i-tooltip__arrow{border-top-color:var(--color-component-background-solid)}.i-tooltip--below .i-tooltip__arrow{border-bottom-color:var(--color-component-background-solid)}.i-tooltip--left .i-tooltip__arrow{border-left-color:var(--color-component-background-solid)}.i-tooltip--right .i-tooltip__arrow{border-right-color:var(--color-component-background-solid)}.i-tooltip{position:relative;padding:8px 12px;border-radius:4px;font-size:.9em;line-height:1.4;white-space:nowrap;max-width:200px;word-wrap:break-word;white-space:normal;z-index:10000;opacity:0;animation:fadeIn .2s ease-in-out forwards}.i-tooltip__arrow{position:absolute;width:0;height:0;border:6px solid transparent}.i-tooltip--above .i-tooltip__arrow{bottom:-6px;left:50%;transform:translate(-50%);border-bottom:none}.i-tooltip--below .i-tooltip__arrow{top:-6px;left:50%;transform:translate(-50%);border-top:none}.i-tooltip--left .i-tooltip__arrow{right:-6px;top:50%;transform:translateY(-50%);border-right:none}.i-tooltip--right .i-tooltip__arrow{left:-6px;top:50%;transform:translateY(-50%);border-left:none}@keyframes fadeIn{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}\n"] }]
472
472
  }], propDecorators: { text: [{
473
473
  type: Input
474
474
  }], position: [{
475
475
  type: Input
476
476
  }] } });
477
477
 
478
+ /**
479
+ * Tooltip Directive
480
+ *
481
+ * Displays contextual tooltips on hover or focus.
482
+ * Tooltips are appended to document.body with z-index: 10000 to ensure
483
+ * they appear above all other elements including dialogs (z-index: 1000).
484
+ *
485
+ * @example
486
+ * <button iTooltip="Click to save" tooltipPosition="above">Save</button>
487
+ */
478
488
  class TooltipDirective {
479
489
  elementRef;
480
490
  renderer;
@@ -628,9 +638,11 @@ class TooltipDirective {
628
638
  top = viewportHeight - tooltipRect.height - gap + scrollY;
629
639
  }
630
640
  // Apply final position and make visible
641
+ // Use z-index 10000 to ensure tooltips appear above dialogs (z-index: 1000)
631
642
  this.renderer.setStyle(tooltipElement, 'position', 'absolute');
632
643
  this.renderer.setStyle(tooltipElement, 'top', `${top}px`);
633
644
  this.renderer.setStyle(tooltipElement, 'left', `${left}px`);
645
+ this.renderer.setStyle(tooltipElement, 'z-index', '10000');
634
646
  this.renderer.setStyle(tooltipElement, 'visibility', 'visible');
635
647
  }
636
648
  destroyTooltip() {
@@ -3125,7 +3137,24 @@ class LayoutComponent {
3125
3137
  router;
3126
3138
  config;
3127
3139
  menuModel = [];
3140
+ mainContainer;
3141
+ Math = Math;
3128
3142
  routerSubscription;
3143
+ touchStartY = 0;
3144
+ touchCurrentY = 0;
3145
+ isPulling = false;
3146
+ pullDistance = signal(0, ...(ngDevMode ? [{ debugName: "pullDistance" }] : []));
3147
+ isRefreshing = signal(false, ...(ngDevMode ? [{ debugName: "isRefreshing" }] : []));
3148
+ PULL_THRESHOLD = 80;
3149
+ MAX_PULL_DISTANCE = 150;
3150
+ INDICATOR_OFFSET = 60;
3151
+ REFRESH_DELAY = 300;
3152
+ // Store bound event handlers for cleanup
3153
+ boundHandleTouchStart;
3154
+ boundHandleTouchMove;
3155
+ boundHandleTouchEnd;
3156
+ refreshTimeoutId;
3157
+ isPullToRefreshInitialized = false;
3129
3158
  constructor(layoutService, router) {
3130
3159
  this.layoutService = layoutService;
3131
3160
  this.router = router;
@@ -3149,6 +3178,83 @@ class LayoutComponent {
3149
3178
  ngOnInit() {
3150
3179
  this.syncViewportToCurrentWindow();
3151
3180
  }
3181
+ ngAfterViewInit() {
3182
+ this.setupPullToRefresh();
3183
+ }
3184
+ setupPullToRefresh() {
3185
+ if (!this.config.enablePullToRefresh || typeof window === 'undefined') {
3186
+ return;
3187
+ }
3188
+ const container = this.mainContainer?.nativeElement;
3189
+ if (!container) {
3190
+ return;
3191
+ }
3192
+ // Bind event handlers and store references for cleanup
3193
+ this.boundHandleTouchStart = this.handleTouchStart.bind(this);
3194
+ this.boundHandleTouchMove = this.handleTouchMove.bind(this);
3195
+ this.boundHandleTouchEnd = this.handleTouchEnd.bind(this);
3196
+ // Use passive: true for touchstart for better scroll performance
3197
+ container.addEventListener('touchstart', this.boundHandleTouchStart, {
3198
+ passive: true,
3199
+ });
3200
+ // Use passive: false for touchmove where preventDefault() is needed
3201
+ container.addEventListener('touchmove', this.boundHandleTouchMove, {
3202
+ passive: false,
3203
+ });
3204
+ container.addEventListener('touchend', this.boundHandleTouchEnd);
3205
+ this.isPullToRefreshInitialized = true;
3206
+ }
3207
+ handleTouchStart(event) {
3208
+ const state = this.layoutService.state();
3209
+ if (!state.isMobileViewport || event.touches.length === 0) {
3210
+ return;
3211
+ }
3212
+ const container = this.mainContainer?.nativeElement;
3213
+ if (!container || container.scrollTop > 0) {
3214
+ return;
3215
+ }
3216
+ this.touchStartY = event.touches[0].clientY;
3217
+ this.isPulling = true;
3218
+ }
3219
+ handleTouchMove(event) {
3220
+ if (!this.isPulling || event.touches.length === 0) {
3221
+ return;
3222
+ }
3223
+ const container = this.mainContainer?.nativeElement;
3224
+ if (!container || container.scrollTop > 0) {
3225
+ this.isPulling = false;
3226
+ this.pullDistance.set(0);
3227
+ return;
3228
+ }
3229
+ this.touchCurrentY = event.touches[0].clientY;
3230
+ const pullDistance = Math.max(0, Math.min(this.touchCurrentY - this.touchStartY, this.MAX_PULL_DISTANCE));
3231
+ if (pullDistance > 0) {
3232
+ event.preventDefault();
3233
+ this.pullDistance.set(pullDistance);
3234
+ }
3235
+ }
3236
+ handleTouchEnd() {
3237
+ if (!this.isPulling) {
3238
+ return;
3239
+ }
3240
+ this.isPulling = false;
3241
+ if (this.pullDistance() >= this.PULL_THRESHOLD) {
3242
+ this.refresh();
3243
+ }
3244
+ else {
3245
+ this.pullDistance.set(0);
3246
+ }
3247
+ }
3248
+ refresh() {
3249
+ this.isRefreshing.set(true);
3250
+ this.pullDistance.set(0);
3251
+ // Delay reload slightly to show the refreshing state
3252
+ this.refreshTimeoutId = window.setTimeout(() => {
3253
+ if (typeof window !== 'undefined') {
3254
+ window.location.reload();
3255
+ }
3256
+ }, this.REFRESH_DELAY);
3257
+ }
3152
3258
  onWindowResize() {
3153
3259
  this.syncViewportToCurrentWindow();
3154
3260
  }
@@ -3176,17 +3282,33 @@ class LayoutComponent {
3176
3282
  if (this.routerSubscription) {
3177
3283
  this.routerSubscription.unsubscribe();
3178
3284
  }
3285
+ // Clear any pending refresh timeout
3286
+ if (this.refreshTimeoutId !== undefined) {
3287
+ window.clearTimeout(this.refreshTimeoutId);
3288
+ }
3289
+ // Clean up event listeners
3290
+ if (this.isPullToRefreshInitialized) {
3291
+ const container = this.mainContainer?.nativeElement;
3292
+ if (container && this.boundHandleTouchStart && this.boundHandleTouchMove && this.boundHandleTouchEnd) {
3293
+ container.removeEventListener('touchstart', this.boundHandleTouchStart);
3294
+ container.removeEventListener('touchmove', this.boundHandleTouchMove);
3295
+ container.removeEventListener('touchend', this.boundHandleTouchEnd);
3296
+ }
3297
+ }
3179
3298
  }
3180
3299
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LayoutComponent, deps: [{ token: LayoutService }, { token: i2.Router }], target: i0.ɵɵFactoryTarget.Component });
3181
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: LayoutComponent, isStandalone: true, selector: "i-layout", inputs: { config: "config", menuModel: "menuModel" }, host: { listeners: { "window:resize": "onWindowResize()" } }, ngImport: i0, template: "<div class=\"layout\">\n <div class=\"layout-wrapper\" [ngClass]=\"containerClass()\">\n <i-topbar [config]=\"config\">\n <ng-content select=\"[topbarActions]\" />\n </i-topbar>\n <div class=\"layout-body\">\n <div\n class=\"layout-sidebar-container\"\n [ngClass]=\"{\n 'sidebar-open': layoutService.state().isSidebarOpen,\n 'sidebar-closed': !layoutService.state().isSidebarOpen\n }\"\n >\n <i-sidebar [menuModel]=\"menuModel\" />\n </div>\n <div class=\"layout-main-container\">\n <div class=\"layout-main\">\n <router-outlet />\n </div>\n </div>\n </div>\n <div class=\"layout-mask\" (click)=\"hideMenu()\"></div>\n </div>\n</div>\n", styles: [".layout .layout-wrapper{display:flex;flex-direction:column;height:100vh;overflow:hidden}.layout .layout-wrapper .layout-body{display:flex;flex:1 1 auto;min-height:0}.layout .layout-wrapper .layout-body .layout-sidebar-container{flex-shrink:0;width:300px;height:100%;overflow-y:auto;transition:transform .3s ease,opacity .3s ease;opacity:1}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar{width:6px;height:6px}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb:hover{background:#00000059}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb:active{background:#00000080}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-corner{background:transparent}.layout .layout-wrapper .layout-body .layout-sidebar-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.layout .layout-wrapper .layout-body .layout-sidebar-container{scrollbar-color:var(--color-text-secondary) transparent}.layout .layout-wrapper .layout-body .layout-sidebar-container.sidebar-open{transform:translate(0);opacity:1;pointer-events:auto}.layout .layout-wrapper .layout-body .layout-sidebar-container.sidebar-closed{transform:translate(-100%);opacity:0;pointer-events:none}.layout .layout-wrapper .layout-body .layout-main-container{flex:1 1 auto;min-width:0;overflow-y:auto;padding:2rem;transition:margin-left .3s ease}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:hover{background:#00000059}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:active{background:#00000080}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-corner{background:transparent}.layout .layout-wrapper .layout-body .layout-main-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.layout .layout-wrapper .layout-body .layout-main-container{scrollbar-color:var(--color-text-secondary) transparent}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar{width:6px;height:6px}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.layout .layout-wrapper .layout-body .layout-main-container{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.layout .layout-wrapper .layout-body .layout-main-container .layout-main{width:100%;max-width:100%}.layout .layout-wrapper.layout-static-inactive .layout-main-container{margin-left:-300px}.layout .layout-wrapper.layout-overlay-active .layout-sidebar-container{position:fixed;left:0;top:5rem;height:calc(100vh - 5rem);z-index:999;background:var(--surface-overlay)}.layout .layout-wrapper .layout-mask{position:fixed;top:0;left:0;width:100%;height:100%;background:#0006;z-index:998;display:none}.layout .layout-wrapper.layout-mobile-active .layout-mask{display:block}@media(max-width:991px){.layout .layout-wrapper .layout-body .layout-sidebar-container{position:fixed;left:0;top:0;height:100vh;z-index:999;transition:transform .2s ease;background:var(--surface-overlay);overflow-y:auto}.layout .layout-wrapper .layout-body .layout-main-container{margin-left:0;width:100%;padding:24px 10px}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: TopbarComponent, selector: "i-topbar", inputs: ["config"] }, { kind: "component", type: SidebarComponent, selector: "i-sidebar", inputs: ["menuModel"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
3300
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: LayoutComponent, isStandalone: true, selector: "i-layout", inputs: { config: "config", menuModel: "menuModel" }, host: { listeners: { "window:resize": "onWindowResize()" } }, viewQueries: [{ propertyName: "mainContainer", first: true, predicate: ["mainContainer"], descendants: true }], ngImport: i0, template: "<div class=\"layout\">\n <div class=\"layout-wrapper\" [ngClass]=\"containerClass()\">\n <i-topbar [config]=\"config\">\n <ng-content select=\"[topbarActions]\" />\n </i-topbar>\n <div class=\"layout-body\">\n <div\n class=\"layout-sidebar-container\"\n [ngClass]=\"{\n 'sidebar-open': layoutService.state().isSidebarOpen,\n 'sidebar-closed': !layoutService.state().isSidebarOpen\n }\"\n >\n <i-sidebar [menuModel]=\"menuModel\" />\n </div>\n <div class=\"layout-main-container\" #mainContainer>\n @if (config.enablePullToRefresh && layoutService.state().isMobileViewport) {\n <div \n class=\"pull-to-refresh-indicator\"\n [style.transform]=\"'translateY(' + Math.max(-INDICATOR_OFFSET, pullDistance() - INDICATOR_OFFSET) + 'px)'\"\n [style.opacity]=\"Math.min(1, pullDistance() / PULL_THRESHOLD)\"\n >\n <div class=\"refresh-icon\" [class.refreshing]=\"isRefreshing()\">\n <i class=\"pi pi-refresh\"></i>\n </div>\n <div class=\"refresh-text\">\n {{ isRefreshing() ? 'Refreshing...' : (pullDistance() >= PULL_THRESHOLD ? 'Release to refresh' : 'Pull to refresh') }}\n </div>\n </div>\n }\n <div class=\"layout-main\">\n <router-outlet />\n </div>\n </div>\n </div>\n <div class=\"layout-mask\" (click)=\"hideMenu()\"></div>\n </div>\n</div>\n", styles: [".layout .layout-wrapper{display:flex;flex-direction:column;height:100vh;overflow:hidden}.layout .layout-wrapper .layout-body{display:flex;flex:1 1 auto;min-height:0}.layout .layout-wrapper .layout-body .layout-sidebar-container{flex-shrink:0;width:300px;height:100%;overflow-y:auto;transition:transform .3s ease,opacity .3s ease;opacity:1}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar{width:6px;height:6px}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb:hover{background:#00000059}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb:active{background:#00000080}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-corner{background:transparent}.layout .layout-wrapper .layout-body .layout-sidebar-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.layout .layout-wrapper .layout-body .layout-sidebar-container{scrollbar-color:var(--color-text-secondary) transparent}.layout .layout-wrapper .layout-body .layout-sidebar-container.sidebar-open{transform:translate(0);opacity:1;pointer-events:auto}.layout .layout-wrapper .layout-body .layout-sidebar-container.sidebar-closed{transform:translate(-100%);opacity:0;pointer-events:none}.layout .layout-wrapper .layout-body .layout-main-container{flex:1 1 auto;min-width:0;overflow-y:auto;padding:2rem;transition:margin-left .3s ease;position:relative}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:hover{background:#00000059}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:active{background:#00000080}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-corner{background:transparent}.layout .layout-wrapper .layout-body .layout-main-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.layout .layout-wrapper .layout-body .layout-main-container{scrollbar-color:var(--color-text-secondary) transparent}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar{width:6px;height:6px}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.layout .layout-wrapper .layout-body .layout-main-container{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.layout .layout-wrapper .layout-body .layout-main-container .pull-to-refresh-indicator{position:absolute;top:0;left:0;right:0;height:60px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.5rem;pointer-events:none;z-index:10;transition:opacity .2s ease}.layout .layout-wrapper .layout-body .layout-main-container .pull-to-refresh-indicator .refresh-icon{font-size:1.5rem;color:var(--primary-color);transition:transform .3s ease}.layout .layout-wrapper .layout-body .layout-main-container .pull-to-refresh-indicator .refresh-icon.refreshing{animation:spin 1s linear infinite}.layout .layout-wrapper .layout-body .layout-main-container .pull-to-refresh-indicator .refresh-text{font-size:.875rem;color:var(--text-color-secondary);font-weight:500}.layout .layout-wrapper .layout-body .layout-main-container .layout-main{width:100%;max-width:100%}.layout .layout-wrapper.layout-static-inactive .layout-main-container{margin-left:-300px}.layout .layout-wrapper.layout-overlay-active .layout-sidebar-container{position:fixed;left:0;top:5rem;height:calc(100vh - 5rem);z-index:999;background:var(--surface-overlay)}.layout .layout-wrapper .layout-mask{position:fixed;top:0;left:0;width:100%;height:100%;background:#0006;z-index:998;display:none}.layout .layout-wrapper.layout-mobile-active .layout-mask{display:block}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media(max-width:991px){.layout .layout-wrapper .layout-body .layout-sidebar-container{position:fixed;left:0;top:0;height:100vh;z-index:999;transition:transform .2s ease;background:var(--surface-overlay);overflow-y:auto}.layout .layout-wrapper .layout-body .layout-main-container{margin-left:0;width:100%;padding:24px 10px}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: TopbarComponent, selector: "i-topbar", inputs: ["config"] }, { kind: "component", type: SidebarComponent, selector: "i-sidebar", inputs: ["menuModel"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
3182
3301
  }
3183
3302
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LayoutComponent, decorators: [{
3184
3303
  type: Component,
3185
- args: [{ selector: 'i-layout', imports: [NgClass, TopbarComponent, SidebarComponent, RouterOutlet], template: "<div class=\"layout\">\n <div class=\"layout-wrapper\" [ngClass]=\"containerClass()\">\n <i-topbar [config]=\"config\">\n <ng-content select=\"[topbarActions]\" />\n </i-topbar>\n <div class=\"layout-body\">\n <div\n class=\"layout-sidebar-container\"\n [ngClass]=\"{\n 'sidebar-open': layoutService.state().isSidebarOpen,\n 'sidebar-closed': !layoutService.state().isSidebarOpen\n }\"\n >\n <i-sidebar [menuModel]=\"menuModel\" />\n </div>\n <div class=\"layout-main-container\">\n <div class=\"layout-main\">\n <router-outlet />\n </div>\n </div>\n </div>\n <div class=\"layout-mask\" (click)=\"hideMenu()\"></div>\n </div>\n</div>\n", styles: [".layout .layout-wrapper{display:flex;flex-direction:column;height:100vh;overflow:hidden}.layout .layout-wrapper .layout-body{display:flex;flex:1 1 auto;min-height:0}.layout .layout-wrapper .layout-body .layout-sidebar-container{flex-shrink:0;width:300px;height:100%;overflow-y:auto;transition:transform .3s ease,opacity .3s ease;opacity:1}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar{width:6px;height:6px}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb:hover{background:#00000059}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb:active{background:#00000080}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-corner{background:transparent}.layout .layout-wrapper .layout-body .layout-sidebar-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.layout .layout-wrapper .layout-body .layout-sidebar-container{scrollbar-color:var(--color-text-secondary) transparent}.layout .layout-wrapper .layout-body .layout-sidebar-container.sidebar-open{transform:translate(0);opacity:1;pointer-events:auto}.layout .layout-wrapper .layout-body .layout-sidebar-container.sidebar-closed{transform:translate(-100%);opacity:0;pointer-events:none}.layout .layout-wrapper .layout-body .layout-main-container{flex:1 1 auto;min-width:0;overflow-y:auto;padding:2rem;transition:margin-left .3s ease}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:hover{background:#00000059}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:active{background:#00000080}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-corner{background:transparent}.layout .layout-wrapper .layout-body .layout-main-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.layout .layout-wrapper .layout-body .layout-main-container{scrollbar-color:var(--color-text-secondary) transparent}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar{width:6px;height:6px}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.layout .layout-wrapper .layout-body .layout-main-container{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.layout .layout-wrapper .layout-body .layout-main-container .layout-main{width:100%;max-width:100%}.layout .layout-wrapper.layout-static-inactive .layout-main-container{margin-left:-300px}.layout .layout-wrapper.layout-overlay-active .layout-sidebar-container{position:fixed;left:0;top:5rem;height:calc(100vh - 5rem);z-index:999;background:var(--surface-overlay)}.layout .layout-wrapper .layout-mask{position:fixed;top:0;left:0;width:100%;height:100%;background:#0006;z-index:998;display:none}.layout .layout-wrapper.layout-mobile-active .layout-mask{display:block}@media(max-width:991px){.layout .layout-wrapper .layout-body .layout-sidebar-container{position:fixed;left:0;top:0;height:100vh;z-index:999;transition:transform .2s ease;background:var(--surface-overlay);overflow-y:auto}.layout .layout-wrapper .layout-body .layout-main-container{margin-left:0;width:100%;padding:24px 10px}}\n"] }]
3304
+ args: [{ selector: 'i-layout', imports: [NgClass, TopbarComponent, SidebarComponent, RouterOutlet], template: "<div class=\"layout\">\n <div class=\"layout-wrapper\" [ngClass]=\"containerClass()\">\n <i-topbar [config]=\"config\">\n <ng-content select=\"[topbarActions]\" />\n </i-topbar>\n <div class=\"layout-body\">\n <div\n class=\"layout-sidebar-container\"\n [ngClass]=\"{\n 'sidebar-open': layoutService.state().isSidebarOpen,\n 'sidebar-closed': !layoutService.state().isSidebarOpen\n }\"\n >\n <i-sidebar [menuModel]=\"menuModel\" />\n </div>\n <div class=\"layout-main-container\" #mainContainer>\n @if (config.enablePullToRefresh && layoutService.state().isMobileViewport) {\n <div \n class=\"pull-to-refresh-indicator\"\n [style.transform]=\"'translateY(' + Math.max(-INDICATOR_OFFSET, pullDistance() - INDICATOR_OFFSET) + 'px)'\"\n [style.opacity]=\"Math.min(1, pullDistance() / PULL_THRESHOLD)\"\n >\n <div class=\"refresh-icon\" [class.refreshing]=\"isRefreshing()\">\n <i class=\"pi pi-refresh\"></i>\n </div>\n <div class=\"refresh-text\">\n {{ isRefreshing() ? 'Refreshing...' : (pullDistance() >= PULL_THRESHOLD ? 'Release to refresh' : 'Pull to refresh') }}\n </div>\n </div>\n }\n <div class=\"layout-main\">\n <router-outlet />\n </div>\n </div>\n </div>\n <div class=\"layout-mask\" (click)=\"hideMenu()\"></div>\n </div>\n</div>\n", styles: [".layout .layout-wrapper{display:flex;flex-direction:column;height:100vh;overflow:hidden}.layout .layout-wrapper .layout-body{display:flex;flex:1 1 auto;min-height:0}.layout .layout-wrapper .layout-body .layout-sidebar-container{flex-shrink:0;width:300px;height:100%;overflow-y:auto;transition:transform .3s ease,opacity .3s ease;opacity:1}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar{width:6px;height:6px}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb:hover{background:#00000059}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb:active{background:#00000080}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-corner{background:transparent}.layout .layout-wrapper .layout-body .layout-sidebar-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.layout .layout-wrapper .layout-body .layout-sidebar-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.layout .layout-wrapper .layout-body .layout-sidebar-container{scrollbar-color:var(--color-text-secondary) transparent}.layout .layout-wrapper .layout-body .layout-sidebar-container.sidebar-open{transform:translate(0);opacity:1;pointer-events:auto}.layout .layout-wrapper .layout-body .layout-sidebar-container.sidebar-closed{transform:translate(-100%);opacity:0;pointer-events:none}.layout .layout-wrapper .layout-body .layout-main-container{flex:1 1 auto;min-width:0;overflow-y:auto;padding:2rem;transition:margin-left .3s ease;position:relative}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-track{background:transparent;border-radius:3px}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb{background:#0003;border-radius:3px;transition:background .2s ease}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:hover{background:#00000059}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:active{background:#00000080}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-corner{background:transparent}.layout .layout-wrapper .layout-body .layout-main-container{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent;scroll-behavior:smooth}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb{background:var(--color-text-secondary);opacity:.4}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.6}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.7}.layout .layout-wrapper .layout-body .layout-main-container{scrollbar-color:var(--color-text-secondary) transparent}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar{width:6px;height:6px}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-track{background:#0000000d;border-radius:3px;margin:2px 0}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb{border-radius:3px;min-height:20px;background:var(--color-text-secondary);opacity:.6}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:hover{background:var(--color-text-primary);opacity:.8}.layout .layout-wrapper .layout-body .layout-main-container::-webkit-scrollbar-thumb:active{background:var(--color-primary);opacity:.9}.layout .layout-wrapper .layout-body .layout-main-container{scrollbar-width:thin;scrollbar-color:var(--color-text-secondary) rgba(0,0,0,.05)}.layout .layout-wrapper .layout-body .layout-main-container .pull-to-refresh-indicator{position:absolute;top:0;left:0;right:0;height:60px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.5rem;pointer-events:none;z-index:10;transition:opacity .2s ease}.layout .layout-wrapper .layout-body .layout-main-container .pull-to-refresh-indicator .refresh-icon{font-size:1.5rem;color:var(--primary-color);transition:transform .3s ease}.layout .layout-wrapper .layout-body .layout-main-container .pull-to-refresh-indicator .refresh-icon.refreshing{animation:spin 1s linear infinite}.layout .layout-wrapper .layout-body .layout-main-container .pull-to-refresh-indicator .refresh-text{font-size:.875rem;color:var(--text-color-secondary);font-weight:500}.layout .layout-wrapper .layout-body .layout-main-container .layout-main{width:100%;max-width:100%}.layout .layout-wrapper.layout-static-inactive .layout-main-container{margin-left:-300px}.layout .layout-wrapper.layout-overlay-active .layout-sidebar-container{position:fixed;left:0;top:5rem;height:calc(100vh - 5rem);z-index:999;background:var(--surface-overlay)}.layout .layout-wrapper .layout-mask{position:fixed;top:0;left:0;width:100%;height:100%;background:#0006;z-index:998;display:none}.layout .layout-wrapper.layout-mobile-active .layout-mask{display:block}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media(max-width:991px){.layout .layout-wrapper .layout-body .layout-sidebar-container{position:fixed;left:0;top:0;height:100vh;z-index:999;transition:transform .2s ease;background:var(--surface-overlay);overflow-y:auto}.layout .layout-wrapper .layout-body .layout-main-container{margin-left:0;width:100%;padding:24px 10px}}\n"] }]
3186
3305
  }], ctorParameters: () => [{ type: LayoutService }, { type: i2.Router }], propDecorators: { config: [{
3187
3306
  type: Input
3188
3307
  }], menuModel: [{
3189
3308
  type: Input
3309
+ }], mainContainer: [{
3310
+ type: ViewChild,
3311
+ args: ['mainContainer']
3190
3312
  }], onWindowResize: [{
3191
3313
  type: HostListener,
3192
3314
  args: ['window:resize']