s4y-ui 5.0.0 → 5.0.1

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { ContentChild, Component, signal, computed, Injectable, inject, input, HostBinding, Input, ChangeDetectionStrategy, NgModule, booleanAttribute, forwardRef, HostListener, Directive, EventEmitter, Output, model, output, ViewEncapsulation, effect, Inject, TemplateRef, ViewChild, ContentChildren, ElementRef, ViewContainerRef } from '@angular/core';
2
+ import { ContentChild, Component, signal, computed, Injectable, inject, input, HostBinding, Input, ChangeDetectionStrategy, NgModule, booleanAttribute, forwardRef, HostListener, Directive, EventEmitter, Output, model, output, ViewEncapsulation, effect, Inject, TemplateRef, ViewChild, ContentChildren, ElementRef, ViewContainerRef, InjectionToken, Injector } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { CommonModule, AsyncPipe, JsonPipe, NgClass, NgTemplateOutlet, DOCUMENT, NgIf, NgStyle } from '@angular/common';
5
5
  import * as i1$1 from '@angular/platform-browser';
@@ -7,15 +7,14 @@ import { DomSanitizer } from '@angular/platform-browser';
7
7
  import * as i1$2 from '@angular/router';
8
8
  import { Router, RouterModule, GuardsCheckEnd } from '@angular/router';
9
9
  import { catchError, map, filter } from 'rxjs/operators';
10
- import { defer, from, throwError, BehaviorSubject, map as map$1, Subject, takeUntil, Subscription, filter as filter$1, fromEvent } from 'rxjs';
10
+ import { defer, from, throwError, BehaviorSubject, map as map$1, Subject, takeUntil, Subscription, filter as filter$1, fromEvent, isObservable, firstValueFrom, ReplaySubject, take } from 'rxjs';
11
11
  import * as i1$3 from '@angular/cdk/scrolling';
12
12
  import { CdkScrollableModule, CdkScrollable } from '@angular/cdk/scrolling';
13
13
  import * as i2 from '@angular/forms';
14
14
  import { NG_VALUE_ACCESSOR, NgControl, FormsModule } from '@angular/forms';
15
15
  import { trigger, transition, animate, style, group, query, state } from '@angular/animations';
16
16
  import { Overlay } from '@angular/cdk/overlay';
17
- import { TemplatePortal } from '@angular/cdk/portal';
18
- import { Dialog } from '@angular/cdk/dialog';
17
+ import { TemplatePortal, CdkPortalOutlet, ComponentPortal } from '@angular/cdk/portal';
19
18
 
20
19
  class DashboardLayoutComponent {
21
20
  asideTemplate;
@@ -3333,30 +3332,292 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
3333
3332
  args: ['document:mousedown', ['$event']]
3334
3333
  }] } });
3335
3334
 
3335
+ const DYNAMIC_DIALOG_DATA = new InjectionToken('DYNAMIC_DIALOG_DATA');
3336
+ const DYNAMIC_DIALOG_OPTIONS = new InjectionToken('DYNAMIC_DIALOG_OPTIONS');
3337
+
3338
+ // dynamic-dialog.util.ts
3339
+ function isPromise(v) {
3340
+ return v && typeof v.then === 'function';
3341
+ }
3342
+ function isEmitter(v) {
3343
+ return v instanceof EventEmitter;
3344
+ }
3345
+ async function toMaybeBooleanPromise(value) {
3346
+ if (isPromise(value))
3347
+ return await value;
3348
+ if (isObservable(value))
3349
+ return await firstValueFrom(value);
3350
+ if (isEmitter(value))
3351
+ return await firstValueFrom(value);
3352
+ return value;
3353
+ }
3354
+
3355
+ class DynamicDialogRef {
3356
+ overlayRef;
3357
+ afterOpened$;
3358
+ afterClosed$;
3359
+ // Declare sem inicializar aqui
3360
+ backdropClick$;
3361
+ keydownEvents$;
3362
+ _afterOpened = new ReplaySubject();
3363
+ _afterClosed = new Subject();
3364
+ panelEl;
3365
+ isClosing = false;
3366
+ constructor(overlayRef) {
3367
+ this.overlayRef = overlayRef;
3368
+ this.afterOpened$ = this._afterOpened.asObservable();
3369
+ this.afterClosed$ = this._afterClosed.asObservable();
3370
+ // Agora é seguro inicializar, pois overlayRef já foi recebido
3371
+ this.backdropClick$ = this.overlayRef.backdropClick();
3372
+ this.keydownEvents$ = this.overlayRef.keydownEvents();
3373
+ this.panelEl = this.overlayRef.overlayElement;
3374
+ // Fallbacks para detach/dispose externos
3375
+ this.overlayRef.detachments().subscribe(() => {
3376
+ if (!this._afterClosed.closed) {
3377
+ this._afterClosed.next({ reason: 'detach' });
3378
+ this._afterClosed.complete();
3379
+ }
3380
+ });
3381
+ const originalDispose = this.overlayRef.dispose.bind(this.overlayRef);
3382
+ this.overlayRef.dispose = () => {
3383
+ if (!this._afterClosed.closed) {
3384
+ this._afterClosed.next({ reason: 'dispose' });
3385
+ this._afterClosed.complete();
3386
+ }
3387
+ originalDispose();
3388
+ };
3389
+ }
3390
+ get backdropEl() {
3391
+ // disponível após criar o backdrop
3392
+ return this.overlayRef.backdropElement ?? null;
3393
+ }
3394
+ /** Chamado pelo service logo após anexar o container. */
3395
+ _notifyOpened() {
3396
+ if (!this._afterOpened.closed) {
3397
+ this._afterOpened.next();
3398
+ this._afterOpened.complete();
3399
+ }
3400
+ }
3401
+ /** Fecha programaticamente com razão e (opcional) resultado. */
3402
+ close(result, reason = 'close') {
3403
+ if (!this._afterClosed.closed) {
3404
+ this._afterClosed.next({ reason, result });
3405
+ this._afterClosed.complete();
3406
+ }
3407
+ this.overlayRef.dispose();
3408
+ }
3409
+ async closeAnimated(result, reason = 'close', opts = {}) {
3410
+ if (this.isClosing)
3411
+ return;
3412
+ this.isClosing = true;
3413
+ const panelCls = opts.panelClass ?? 'fade-out';
3414
+ const hideBackdropCls = opts.backdropHideClass ?? 'cdk-overlay-backdrop-showing';
3415
+ const timeoutMs = opts.timeoutMs ?? 600;
3416
+ // aciona animação do painel
3417
+ this.panelEl.classList.add(panelCls);
3418
+ // aciona transição do backdrop (remove a classe “showing”)
3419
+ const bd = this.backdropEl;
3420
+ if (bd && bd.classList.contains(hideBackdropCls)) {
3421
+ bd.classList.remove(hideBackdropCls);
3422
+ }
3423
+ // espera animationend do painel ou timeout
3424
+ await new Promise((resolve) => {
3425
+ let done = false;
3426
+ const finish = () => {
3427
+ if (done)
3428
+ return;
3429
+ done = true;
3430
+ this.panelEl.removeEventListener('animationend', onAnimEnd);
3431
+ clearTimeout(to);
3432
+ resolve();
3433
+ };
3434
+ const onAnimEnd = (e) => {
3435
+ if (e.target === this.panelEl)
3436
+ finish();
3437
+ };
3438
+ this.panelEl.addEventListener('animationend', onAnimEnd, { once: true });
3439
+ const to = setTimeout(finish, timeoutMs);
3440
+ });
3441
+ // emite afterClosed e destrói
3442
+ if (!this._afterClosed.closed) {
3443
+ this._afterClosed.next({ reason, result });
3444
+ this._afterClosed.complete();
3445
+ }
3446
+ this.overlayRef.dispose();
3447
+ }
3448
+ }
3449
+
3336
3450
  class DynamicDialogComponent {
3337
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: DynamicDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3338
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: DynamicDialogComponent, isStandalone: true, selector: "s4y-dynamic-dialog", ngImport: i0, template: "<div class=\"s4y-dialog\">\r\n <header class=\"s4y-dialog-header\">\r\n <h2 class=\"s4y-dialog-header__title\">titulo</h2>\r\n <button role=\"button\">\r\n <p>&times;</p>\r\n </button>\r\n </header>\r\n <section class=\"s4y-dialog__body\">\r\n <p>Conteudo principal aqui</p>\r\n\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <!-- \u2026conte\u00FAdo longo\u2026 -->\r\n <h1>ds</h1>\r\n </section>\r\n\r\n <footer>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n </footer>\r\n</div>\r\n", styles: [".s4y-dialog-header{padding-bottom:1rem;flex-shrink:0;display:flex;align-items:center;justify-content:space-between}.s4y-dialog-header button{padding:.6rem 1.2rem;font-size:1.8rem;cursor:pointer}.s4y-dialog-header .s4y-dialog-header__title{font-size:2.2rem;color:var(--primary-color)}\n"] });
3451
+ ref;
3452
+ dialogOptions;
3453
+ injectedData = inject(DYNAMIC_DIALOG_DATA, {
3454
+ optional: true,
3455
+ });
3456
+ okLoading = false;
3457
+ cancelLoading = false;
3458
+ contentPortal;
3459
+ headerTemplate;
3460
+ footerTemplate;
3461
+ contentTemplate;
3462
+ templateContext;
3463
+ constructor(ref, dialogOptions) {
3464
+ this.ref = ref;
3465
+ this.dialogOptions = dialogOptions;
3466
+ }
3467
+ get data() {
3468
+ return this.injectedData;
3469
+ }
3470
+ async onOk() {
3471
+ if (this.okLoading)
3472
+ return;
3473
+ this.okLoading = true;
3474
+ try {
3475
+ const res = await toMaybeBooleanPromise(this.dialogOptions?.onOk?.({ data: this.injectedData, ref: this.ref }));
3476
+ if (res === false)
3477
+ return;
3478
+ await this.ref.closeAnimated(undefined, 'ok');
3479
+ }
3480
+ finally {
3481
+ this.okLoading = false;
3482
+ }
3483
+ }
3484
+ // ---- Cancel ----
3485
+ async onCancel() {
3486
+ if (this.cancelLoading)
3487
+ return;
3488
+ this.cancelLoading = true;
3489
+ try {
3490
+ const res = await toMaybeBooleanPromise(this.dialogOptions?.onCancel?.({
3491
+ data: this.injectedData,
3492
+ ref: this.ref,
3493
+ }));
3494
+ if (res === false)
3495
+ return;
3496
+ await this.ref.closeAnimated(undefined, 'cancel');
3497
+ }
3498
+ finally {
3499
+ this.cancelLoading = false;
3500
+ }
3501
+ }
3502
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: DynamicDialogComponent, deps: [{ token: DynamicDialogRef }, { token: DYNAMIC_DIALOG_OPTIONS }], target: i0.ɵɵFactoryTarget.Component });
3503
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: DynamicDialogComponent, isStandalone: true, selector: "s4y-dynamic-dialog", inputs: { contentPortal: "contentPortal", headerTemplate: "headerTemplate", footerTemplate: "footerTemplate", contentTemplate: "contentTemplate", templateContext: "templateContext" }, host: { attributes: { "role": "dialog", "aria-modal": "true", "tabindex": "-1" }, properties: { "attr.aria-labelledby": "'s4y-dialog-title'" }, classAttribute: "s4y-dialog" }, ngImport: i0, template: "<article class=\"s4y-dialog\" role=\"dialog\" aria-modal=\"true\">\r\n @if (headerTemplate) {\r\n <header\r\n class=\"s4y-dialog-header\"\r\n [class.s4y-centered-header]=\"dialogOptions?.centeredHeader\"\r\n [ngStyle]=\"dialogOptions?.headerStyle\"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"headerTemplate\"\r\n [ngTemplateOutletContext]=\"templateContext\"\r\n >\r\n </ng-container>\r\n </header>\r\n } @else if (dialogOptions?.title || dialogOptions?.description) {\r\n <header\r\n class=\"s4y-dialog-header\"\r\n [class.s4y-centered-header]=\"dialogOptions?.centeredHeader\"\r\n [ngStyle]=\"dialogOptions?.headerStyle\"\r\n >\r\n <h2 class=\"s4y-dialog-header__title\">{{ dialogOptions?.title }}</h2>\r\n <p class=\"s4y-dialog-header__description\">\r\n {{ dialogOptions?.description }}\r\n </p>\r\n </header>\r\n }\r\n\r\n @if (dialogOptions?.closable || dialogOptions?.closable == undefined) {\r\n <button class=\"s4y-dialog-close-btn\" (click)=\"ref.closeAnimated(undefined, 'close')\" aria-label=\"Fechar\">\r\n &times;\r\n </button>\r\n }\r\n\r\n <section class=\"s4y-dialog__body\" [ngStyle]=\"dialogOptions?.bodyStyle\">\r\n @if (contentTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"contentTemplate\"\r\n [ngTemplateOutletContext]=\"templateContext\"\r\n >\r\n </ng-container>\r\n } @else {\r\n <ng-template\r\n cdkPortalOutlet\r\n [cdkPortalOutlet]=\"contentPortal\"\r\n ></ng-template>\r\n }\r\n </section>\r\n\r\n @let cancelBtnOptions = this.dialogOptions?.cancelBtnOptions;\r\n @let okBtnOptions = this.dialogOptions?.okBtnOptions;\r\n\r\n @if (!(dialogOptions?.hideFooter ?? false)) {\r\n <footer\r\n class=\"flex gap-1 s4y-dialog__footer\"\r\n [ngStyle]=\"dialogOptions?.footerStyle\"\r\n >\r\n @if (footerTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"footerTemplate\"\r\n [ngTemplateOutletContext]=\"templateContext\"\r\n >\r\n </ng-container>\r\n } @else {\r\n @if (cancelBtnOptions?.text) {\r\n <button\r\n (click)=\"onCancel()\"\r\n [loading]=\"cancelLoading || (cancelBtnOptions?.loading ?? false)\"\r\n [fullWidth]=\"cancelBtnOptions?.fullWidth ?? false\"\r\n s4yButton\r\n [variant]=\"cancelBtnOptions?.variant ?? 'gray'\"\r\n [outlined]=\"cancelBtnOptions?.outlined ?? true\"\r\n [disabled]=\"cancelBtnOptions?.disabled ?? false\"\r\n [size]=\"cancelBtnOptions?.size ?? 'small'\"\r\n >\r\n {{ cancelBtnOptions?.text ?? \"Cancelar\" }}\r\n </button>\r\n }\r\n @if (okBtnOptions?.text) {\r\n <button\r\n (click)=\"onOk()\"\r\n [loading]=\"okLoading || (okBtnOptions?.loading ?? false)\"\r\n [fullWidth]=\"okBtnOptions?.fullWidth ?? false\"\r\n s4yButton\r\n [variant]=\"okBtnOptions?.variant ?? 'primary'\"\r\n [outlined]=\"okBtnOptions?.outlined ?? false\"\r\n [disabled]=\"okBtnOptions?.disabled ?? false\"\r\n [size]=\"okBtnOptions?.size ?? 'small'\"\r\n >\r\n {{ okBtnOptions?.text ?? \"Ok\" }}\r\n </button>\r\n }\r\n }\r\n </footer>\r\n }\r\n</article>\r\n", styles: [".s4y-dialog{display:flex;flex-direction:column;max-height:90dvh;overflow:hidden;position:relative}.s4y-dialog-header{display:flex;flex-direction:column;align-items:flex-start;flex-shrink:0;padding-bottom:1.4rem;gap:.4rem}.s4y-centered-header{align-items:center}.s4y-dialog-action{display:flex;align-items:center;justify-content:space-between;width:100%}.s4y-dialog__footer{display:flex;align-items:center;justify-content:flex-end;gap:1rem;padding-top:1.4rem;flex-shrink:0}@media screen and (min-width: 320px) and (max-width: 480px){.s4y-dialog__footer{flex-direction:column-reverse}.s4y-dialog__footer button{width:100%}}.s4y-dialog-header__title{font-size:1.8rem;color:var(--primary-color)}.s4y-dialog-header__description{font-size:2rem;font-size:1.4rem;font-weight:400;color:var(--gray-700)}.s4y-dialog__body{flex:1 1 auto;min-height:0;overflow-y:auto}.s4y-dialog-close-btn{padding:0rem 1.4rem;cursor:pointer;font-size:2rem;position:absolute;right:0;top:0;transition:.5 ease}.s4y-dialog-close-btn:hover{background-color:var(--gray-200);border-radius:var(--radius)}\n"], dependencies: [{ kind: "directive", type: CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }, { kind: "component", type: ButtonComponent, selector: "button[s4yButton], a[s4yButton]", inputs: ["disabled", "outlined", "loading", "size", "variant", "fullWidth", "iconAligned"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], animations: [] });
3339
3504
  }
3340
3505
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: DynamicDialogComponent, decorators: [{
3341
3506
  type: Component,
3342
- args: [{ selector: 's4y-dynamic-dialog', imports: [], template: "<div class=\"s4y-dialog\">\r\n <header class=\"s4y-dialog-header\">\r\n <h2 class=\"s4y-dialog-header__title\">titulo</h2>\r\n <button role=\"button\">\r\n <p>&times;</p>\r\n </button>\r\n </header>\r\n <section class=\"s4y-dialog__body\">\r\n <p>Conteudo principal aqui</p>\r\n\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <!-- \u2026conte\u00FAdo longo\u2026 -->\r\n <h1>ds</h1>\r\n </section>\r\n\r\n <footer>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n <h1>ds</h1>\r\n </footer>\r\n</div>\r\n", styles: [".s4y-dialog-header{padding-bottom:1rem;flex-shrink:0;display:flex;align-items:center;justify-content:space-between}.s4y-dialog-header button{padding:.6rem 1.2rem;font-size:1.8rem;cursor:pointer}.s4y-dialog-header .s4y-dialog-header__title{font-size:2.2rem;color:var(--primary-color)}\n"] }]
3343
- }] });
3507
+ args: [{ selector: 's4y-dynamic-dialog', imports: [CdkPortalOutlet, ButtonComponent, NgStyle, NgIf, NgTemplateOutlet], host: {
3508
+ role: 'dialog',
3509
+ 'aria-modal': 'true',
3510
+ tabindex: '-1',
3511
+ class: 's4y-dialog',
3512
+ '[attr.aria-labelledby]': "'s4y-dialog-title'",
3513
+ }, animations: [], template: "<article class=\"s4y-dialog\" role=\"dialog\" aria-modal=\"true\">\r\n @if (headerTemplate) {\r\n <header\r\n class=\"s4y-dialog-header\"\r\n [class.s4y-centered-header]=\"dialogOptions?.centeredHeader\"\r\n [ngStyle]=\"dialogOptions?.headerStyle\"\r\n >\r\n <ng-container\r\n [ngTemplateOutlet]=\"headerTemplate\"\r\n [ngTemplateOutletContext]=\"templateContext\"\r\n >\r\n </ng-container>\r\n </header>\r\n } @else if (dialogOptions?.title || dialogOptions?.description) {\r\n <header\r\n class=\"s4y-dialog-header\"\r\n [class.s4y-centered-header]=\"dialogOptions?.centeredHeader\"\r\n [ngStyle]=\"dialogOptions?.headerStyle\"\r\n >\r\n <h2 class=\"s4y-dialog-header__title\">{{ dialogOptions?.title }}</h2>\r\n <p class=\"s4y-dialog-header__description\">\r\n {{ dialogOptions?.description }}\r\n </p>\r\n </header>\r\n }\r\n\r\n @if (dialogOptions?.closable || dialogOptions?.closable == undefined) {\r\n <button class=\"s4y-dialog-close-btn\" (click)=\"ref.closeAnimated(undefined, 'close')\" aria-label=\"Fechar\">\r\n &times;\r\n </button>\r\n }\r\n\r\n <section class=\"s4y-dialog__body\" [ngStyle]=\"dialogOptions?.bodyStyle\">\r\n @if (contentTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"contentTemplate\"\r\n [ngTemplateOutletContext]=\"templateContext\"\r\n >\r\n </ng-container>\r\n } @else {\r\n <ng-template\r\n cdkPortalOutlet\r\n [cdkPortalOutlet]=\"contentPortal\"\r\n ></ng-template>\r\n }\r\n </section>\r\n\r\n @let cancelBtnOptions = this.dialogOptions?.cancelBtnOptions;\r\n @let okBtnOptions = this.dialogOptions?.okBtnOptions;\r\n\r\n @if (!(dialogOptions?.hideFooter ?? false)) {\r\n <footer\r\n class=\"flex gap-1 s4y-dialog__footer\"\r\n [ngStyle]=\"dialogOptions?.footerStyle\"\r\n >\r\n @if (footerTemplate) {\r\n <ng-container\r\n [ngTemplateOutlet]=\"footerTemplate\"\r\n [ngTemplateOutletContext]=\"templateContext\"\r\n >\r\n </ng-container>\r\n } @else {\r\n @if (cancelBtnOptions?.text) {\r\n <button\r\n (click)=\"onCancel()\"\r\n [loading]=\"cancelLoading || (cancelBtnOptions?.loading ?? false)\"\r\n [fullWidth]=\"cancelBtnOptions?.fullWidth ?? false\"\r\n s4yButton\r\n [variant]=\"cancelBtnOptions?.variant ?? 'gray'\"\r\n [outlined]=\"cancelBtnOptions?.outlined ?? true\"\r\n [disabled]=\"cancelBtnOptions?.disabled ?? false\"\r\n [size]=\"cancelBtnOptions?.size ?? 'small'\"\r\n >\r\n {{ cancelBtnOptions?.text ?? \"Cancelar\" }}\r\n </button>\r\n }\r\n @if (okBtnOptions?.text) {\r\n <button\r\n (click)=\"onOk()\"\r\n [loading]=\"okLoading || (okBtnOptions?.loading ?? false)\"\r\n [fullWidth]=\"okBtnOptions?.fullWidth ?? false\"\r\n s4yButton\r\n [variant]=\"okBtnOptions?.variant ?? 'primary'\"\r\n [outlined]=\"okBtnOptions?.outlined ?? false\"\r\n [disabled]=\"okBtnOptions?.disabled ?? false\"\r\n [size]=\"okBtnOptions?.size ?? 'small'\"\r\n >\r\n {{ okBtnOptions?.text ?? \"Ok\" }}\r\n </button>\r\n }\r\n }\r\n </footer>\r\n }\r\n</article>\r\n", styles: [".s4y-dialog{display:flex;flex-direction:column;max-height:90dvh;overflow:hidden;position:relative}.s4y-dialog-header{display:flex;flex-direction:column;align-items:flex-start;flex-shrink:0;padding-bottom:1.4rem;gap:.4rem}.s4y-centered-header{align-items:center}.s4y-dialog-action{display:flex;align-items:center;justify-content:space-between;width:100%}.s4y-dialog__footer{display:flex;align-items:center;justify-content:flex-end;gap:1rem;padding-top:1.4rem;flex-shrink:0}@media screen and (min-width: 320px) and (max-width: 480px){.s4y-dialog__footer{flex-direction:column-reverse}.s4y-dialog__footer button{width:100%}}.s4y-dialog-header__title{font-size:1.8rem;color:var(--primary-color)}.s4y-dialog-header__description{font-size:2rem;font-size:1.4rem;font-weight:400;color:var(--gray-700)}.s4y-dialog__body{flex:1 1 auto;min-height:0;overflow-y:auto}.s4y-dialog-close-btn{padding:0rem 1.4rem;cursor:pointer;font-size:2rem;position:absolute;right:0;top:0;transition:.5 ease}.s4y-dialog-close-btn:hover{background-color:var(--gray-200);border-radius:var(--radius)}\n"] }]
3514
+ }], ctorParameters: () => [{ type: DynamicDialogRef }, { type: undefined, decorators: [{
3515
+ type: Inject,
3516
+ args: [DYNAMIC_DIALOG_OPTIONS]
3517
+ }] }], propDecorators: { contentPortal: [{
3518
+ type: Input
3519
+ }], headerTemplate: [{
3520
+ type: Input
3521
+ }], footerTemplate: [{
3522
+ type: Input
3523
+ }], contentTemplate: [{
3524
+ type: Input
3525
+ }], templateContext: [{
3526
+ type: Input
3527
+ }] } });
3344
3528
 
3345
3529
  class DynamicDialogService {
3346
- dialog = inject(Dialog);
3347
3530
  overlay = inject(Overlay);
3348
- open(component) {
3349
- return this.dialog.open(DynamicDialogComponent, {
3350
- panelClass: ['s4y-panel-dialog'],
3351
- backdropClass: ['s4y-backdrop-dialog'],
3352
- scrollStrategy: this.overlay.scrollStrategies.reposition(),
3531
+ rootInjector = inject(Injector);
3532
+ open(component, opts = {}) {
3533
+ const overlayRef = this.overlay.create(this.buildOverlayConfig(opts));
3534
+ overlayRef.updateSize({
3535
+ width: opts.width ?? 'auto',
3536
+ height: opts.height ?? 'auto',
3537
+ minWidth: opts.minWidth ?? '32rem',
3538
+ minHeight: opts.minHeight ?? 'auto',
3539
+ maxWidth: opts.maxWidth ?? '90dvw',
3540
+ maxHeight: opts.maxHeight ?? '90dvh',
3541
+ });
3542
+ if (opts.panelClass) {
3543
+ const classes = Array.isArray(opts.panelClass)
3544
+ ? opts.panelClass
3545
+ : [opts.panelClass];
3546
+ classes.forEach((c) => overlayRef.addPanelClass(c));
3547
+ }
3548
+ const dialogRef = new DynamicDialogRef(overlayRef);
3549
+ if (opts.closeOnBackdrop) {
3550
+ overlayRef
3551
+ .backdropClick()
3552
+ .pipe(take(1))
3553
+ .subscribe(() => {
3554
+ dialogRef.closeAnimated(undefined, 'backdrop');
3555
+ });
3556
+ }
3557
+ if (opts.closeOnEsc !== false) {
3558
+ overlayRef
3559
+ .keydownEvents()
3560
+ .pipe(filter$1((e) => e.key === 'Escape' || e.key === 'Esc'), take(1))
3561
+ .subscribe(() => dialogRef.closeAnimated(undefined, 'esc'));
3562
+ }
3563
+ // injeta o ref + dados no componente container
3564
+ const injector = Injector.create({
3565
+ parent: this.rootInjector,
3566
+ providers: [
3567
+ { provide: DynamicDialogRef, useValue: dialogRef },
3568
+ { provide: DYNAMIC_DIALOG_DATA, useValue: opts.data },
3569
+ { provide: DYNAMIC_DIALOG_OPTIONS, useValue: opts },
3570
+ ],
3353
3571
  });
3572
+ // anexa o container
3573
+ const containerPortal = new ComponentPortal(DynamicDialogComponent, null, injector);
3574
+ const containerRef = overlayRef.attach(containerPortal);
3575
+ const templateCtx = {
3576
+ $implicit: opts.data,
3577
+ data: opts.data,
3578
+ ref: dialogRef,
3579
+ modalRef: dialogRef,
3580
+ };
3581
+ containerRef.instance.headerTemplate = opts.headerTemplate;
3582
+ containerRef.instance.footerTemplate = opts.footerTemplate;
3583
+ containerRef.instance.contentTemplate = opts.contentTemplate;
3584
+ containerRef.instance.templateContext = templateCtx;
3585
+ // notifica afterOpened (container anexado)
3586
+ dialogRef._notifyOpened();
3587
+ // anexa o conteúdo
3588
+ if (!opts.contentTemplate) {
3589
+ const contentPortal = new ComponentPortal(component, null, injector);
3590
+ containerRef.instance.contentPortal = contentPortal;
3591
+ }
3592
+ return dialogRef;
3593
+ }
3594
+ buildOverlayConfig(opts) {
3595
+ const position = opts.positionStrategy ??
3596
+ this.overlay.position().global().centerHorizontally().centerVertically();
3597
+ return {
3598
+ positionStrategy: position,
3599
+ hasBackdrop: opts.hasBackdrop ?? true,
3600
+ backdropClass: opts.backdropClass ?? ['s4y-backdrop-dialog'],
3601
+ scrollStrategy: opts.scrollStrategy ?? this.overlay.scrollStrategies.block(),
3602
+ disposeOnNavigation: opts.disposeOnNavigation ?? true,
3603
+ panelClass: [
3604
+ 's4y-dialog-panel',
3605
+ ...(Array.isArray(opts.panelClass)
3606
+ ? opts.panelClass
3607
+ : opts.panelClass
3608
+ ? [opts.panelClass]
3609
+ : []),
3610
+ ],
3611
+ };
3354
3612
  }
3355
3613
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: DynamicDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3356
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: DynamicDialogService });
3614
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: DynamicDialogService, providedIn: 'root' });
3357
3615
  }
3358
3616
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: DynamicDialogService, decorators: [{
3359
- type: Injectable
3617
+ type: Injectable,
3618
+ args: [{
3619
+ providedIn: 'root',
3620
+ }]
3360
3621
  }] });
3361
3622
 
3362
3623
  /*
@@ -3368,5 +3629,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
3368
3629
  * Generated bundle index. Do not edit.
3369
3630
  */
3370
3631
 
3371
- export { AsideComponent, AsideService, AvatarComponent, BreadcrumbComponent, BreadcrumbItemDirective, BreadcrumbService, ButtonComponent, CheckboxComponent, ClickOutsideDirective, DashboardContainerComponent, DashboardLayoutComponent, DashboardModule, DashboardRoutesComponent, DrawerComponent, DynamicDialogComponent, DynamicDialogService, ErrorMessageComponent, FormFieldComponent, FormFieldPasswordComponent, FormsKitModule, HintComponent, InputComponent, InputPrefixComponent, InputSufixComponent, LabelComponent, LoadingModalComponent, LoadingModalService, MaskDirective, MenuComponent, MenuItemComponent, ModalComponent, ModalConfirmationComponent, ModalConfirmationService, NavbarComponent, PaginationComponent, PopoverPanelComponent, PopoverTriggerDirective, RadioComponent, SearchBarComponent, SelectComponent, SelectMultiComponent, SidebarRightComponent, SidebarRightService, SliderComponent, SpinnerComponent, StepComponent, StepPanelComponent, StepperComponent, SvgComponent, SvgService, TableComponent, TableSortDirective, ToastComponent, ToastService, ToggleComponent, TooltipComponent, TooltipDirective, TooltipModule, TooltipPosition, modalFadeCombined, sidebarRightAnimation };
3632
+ export { AsideComponent, AsideService, AvatarComponent, BreadcrumbComponent, BreadcrumbItemDirective, BreadcrumbService, ButtonComponent, CheckboxComponent, ClickOutsideDirective, DYNAMIC_DIALOG_DATA, DYNAMIC_DIALOG_OPTIONS, DashboardContainerComponent, DashboardLayoutComponent, DashboardModule, DashboardRoutesComponent, DrawerComponent, DynamicDialogComponent, DynamicDialogRef, DynamicDialogService, ErrorMessageComponent, FormFieldComponent, FormFieldPasswordComponent, FormsKitModule, HintComponent, InputComponent, InputPrefixComponent, InputSufixComponent, LabelComponent, LoadingModalComponent, LoadingModalService, MaskDirective, MenuComponent, MenuItemComponent, ModalComponent, ModalConfirmationComponent, ModalConfirmationService, NavbarComponent, PaginationComponent, PopoverPanelComponent, PopoverTriggerDirective, RadioComponent, SearchBarComponent, SelectComponent, SelectMultiComponent, SidebarRightComponent, SidebarRightService, SliderComponent, SpinnerComponent, StepComponent, StepPanelComponent, StepperComponent, SvgComponent, SvgService, TableComponent, TableSortDirective, ToastComponent, ToastService, ToggleComponent, TooltipComponent, TooltipDirective, TooltipModule, TooltipPosition, modalFadeCombined, sidebarRightAnimation };
3372
3633
  //# sourceMappingURL=s4y-ui.mjs.map