@flywheel-io/vision 21.2.0 → 21.2.1-beta.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.
@@ -1294,11 +1294,11 @@ class FwAvatarListComponent {
1294
1294
  this.subscriptions.push(sub);
1295
1295
  }
1296
1296
  calcOverflow() {
1297
- const hostRect = this.hostElement.nativeElement.getBoundingClientRect();
1298
1297
  const avatarElements = this.avatarElementRefs().map(ref => ref.nativeElement);
1299
1298
  const moreTextElement = this.moreText().nativeElement;
1300
1299
  avatarElements.forEach(avatar => avatar.classList.remove('hidden'));
1301
1300
  moreTextElement.classList.remove('hidden');
1301
+ const hostRect = this.hostElement.nativeElement.getBoundingClientRect();
1302
1302
  const visibleAvatars = avatarElements.filter(avatar => {
1303
1303
  const avatarRect = avatar.getBoundingClientRect();
1304
1304
  return !(avatarRect.right > hostRect.right || avatarRect.bottom > hostRect.bottom);
@@ -3215,11 +3215,11 @@ class FwDialogComponent {
3215
3215
  }, 300);
3216
3216
  }
3217
3217
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FwDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3218
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: FwDialogComponent, isStandalone: true, selector: "fw-dialog", inputs: { width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconColor: { classPropertyName: "iconColor", publicName: "iconColor", isSignal: true, isRequired: false, transformFunction: null }, showClose: { classPropertyName: "showClose", publicName: "showClose", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null }, externalClasses: { classPropertyName: "externalClasses", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close" }, host: { properties: { "attr.title": "this.hostTitle", "class": "this.classes" } }, ngImport: i0, template: "<div class=\"fw-dialog\">\n @if (showClose()) {\n <fw-icon-button tabindex=\"-1\" icon=\"close\" color=\"slate\" [ariaLabel]=\"closeLabel()\" (click)=\"handleCloseButton()\"> </fw-icon-button>\n }\n <div class=\"dialog-header\" [id]=\"headerId\">\n <ng-content select=\"fw-dialog-header\"></ng-content>\n @if (title()) {\n <div class=\"dialog-title\">\n <h3 class=\"vision-h3\">{{ title() }}</h3>\n </div>\n }\n </div>\n <div class=\"dialog-body\">\n <ng-content select=\"fw-dialog-content\"></ng-content>\n </div>\n <div class=\"dialog-actions\">\n <ng-content select=\"fw-dialog-actions\"></ng-content>\n </div>\n</div>\n", styles: ["@keyframes slide-in-from-bottom{0%{opacity:0;transform:translateY(100vh)}to{opacity:1;transform:translateY(0)}}@keyframes slide-out-to-bottom{0%{opacity:1;transform:translateY(0)}99%{opacity:0;transform:translateY(100vh)}to{opacity:0;transform:translateY(100vh)}}:host{box-sizing:border-box;background-color:var(--card-background);border:1px solid var(--separations-border);border-radius:8px;display:flex;flex-direction:column;overflow:hidden;animation:slide-in-from-bottom .15s ease-out}:host.dialog-closing{animation:slide-out-to-bottom .15s ease-in forwards}:host.dialog-width-extra-small{width:444px}:host.dialog-width-small{width:600px}:host.dialog-width-medium{width:900px}:host.dialog-width-large{width:1200px}:host.dialog-width-extra-large{width:1536px}:host.dialog-width-responsive{max-width:100vw;margin:0 12px}@media only screen and (width<=575px){:host.dialog-width-responsive{max-height:92vh;margin-top:4vh;margin-bottom:4vh}:host.dialog-width-responsive .fw-dialog{border-radius:12px}:host.dialog-width-responsive .fw-dialog .dialog-body{max-height:65vh;overflow-y:auto;-webkit-overflow-scrolling:touch}:host.dialog-width-responsive .fw-dialog .dialog-body::-webkit-scrollbar{width:4px}:host.dialog-width-responsive .fw-dialog .dialog-body::-webkit-scrollbar-track{background:var(--separations-base)}:host.dialog-width-responsive .fw-dialog .dialog-body::-webkit-scrollbar-thumb{background:var(--slate-base);border-radius:2px}}@media only screen and (width>=576px){:host.dialog-width-responsive{width:90vw;max-width:600px;margin:0}}@media only screen and (width>=768px){:host.dialog-width-responsive{width:80vw;max-width:900px}:host.dialog-width-responsive .fw-dialog .dialog-body{max-height:70vh;overflow-y:auto}}@media only screen and (width>=992px){:host.dialog-width-responsive{width:60vw;max-width:1200px}}@media only screen and (width>=1200px){:host.dialog-width-responsive{width:50vw;max-width:1536px}}:host .fw-dialog{position:relative}:host .fw-dialog fw-icon-button{position:absolute;top:4px;right:4px}:host .fw-dialog .dialog-header{background-color:var(--card-header)}:host .fw-dialog .dialog-header .dialog-title{display:flex;box-sizing:border-box;border-bottom:1px solid var(--separations-base);padding:12px 16px;height:44px;overflow:hidden;align-items:center}:host .fw-dialog .dialog-header .dialog-title h3{overflow:clip visible;min-width:0;white-space:nowrap;text-overflow:ellipsis;margin-right:30px;flex:1}:host .fw-dialog .dialog-header h3{margin:0}:host .fw-dialog .dialog-header:empty{display:none}:host .fw-dialog .dialog-body{background-color:var(--card-background);border-bottom:1px solid var(--separations-base)}:host .fw-dialog .dialog-body:empty{display:none}:host .fw-dialog .dialog-actions{padding:16px}:host .fw-dialog .dialog-actions:empty{display:none}\n"], dependencies: [{ kind: "component", type: FwIconButtonComponent, selector: "fw-icon-button", inputs: ["color", "icon", "size", "disabled", "selected", "border", "focusInitial", "ariaLabel"] }] }); }
3218
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: FwDialogComponent, isStandalone: true, selector: "fw-dialog", inputs: { width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconColor: { classPropertyName: "iconColor", publicName: "iconColor", isSignal: true, isRequired: false, transformFunction: null }, showClose: { classPropertyName: "showClose", publicName: "showClose", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null }, externalClasses: { classPropertyName: "externalClasses", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { close: "close" }, host: { properties: { "attr.title": "this.hostTitle", "class": "this.classes" } }, ngImport: i0, template: "<div class=\"dialog-header\" [id]=\"headerId\">\n <ng-content select=\"fw-dialog-header\"></ng-content>\n @if (title()) {\n <div class=\"dialog-title\">\n @if (icon()) {\n <fw-icon [color]=\"iconColor()\">{{ icon() }}</fw-icon>\n }\n <h3 class=\"vision-h3\">{{ title() }}</h3>\n </div>\n }\n</div>\n<ng-content select=\"fw-dialog-content\"/>\n<div class=\"dialog-actions\">\n <ng-content select=\"fw-dialog-actions\"></ng-content>\n</div>\n@if (showClose()) {\n <fw-icon-button\n tabindex=\"-1\" icon=\"close\" color=\"slate\"\n (click)=\"handleCloseButton()\"\n />\n}\n", styles: ["@keyframes slide-in-from-bottom{0%{opacity:0;transform:translateY(100vh)}to{opacity:1;transform:translateY(0)}}@keyframes slide-out-to-bottom{0%{opacity:1;transform:translateY(0)}99%{opacity:0;transform:translateY(100vh)}to{opacity:0;transform:translateY(100vh)}}:host{box-sizing:border-box;background-color:var(--card-background);border:1px solid var(--separations-border);border-radius:8px;display:flex;flex-direction:column;overflow:hidden;animation:slide-in-from-bottom .15s ease-out;position:relative;max-height:80vh}:host fw-icon-button{position:absolute;top:4px;right:4px}:host .dialog-header{background-color:var(--card-header)}:host .dialog-header .dialog-title{display:flex;gap:8px;box-sizing:border-box;border-bottom:1px solid var(--separations-base);padding:12px 16px;height:44px;overflow:hidden;align-items:center}:host .dialog-header .dialog-title fw-icon{font-size:22px}:host .dialog-header .dialog-title h3{overflow:clip visible;min-width:0;white-space:nowrap;text-overflow:ellipsis;margin-right:30px;flex:1}:host .dialog-header h3{margin:0}:host .dialog-header:empty{display:none}:host ::ng-deep fw-dialog-content{flex-shrink:1;overflow-y:auto;background-color:var(--card-background)}:host ::ng-deep fw-dialog-content:empty{display:none}:host .dialog-actions{border-top:1px solid var(--separations-base);padding:16px}:host .dialog-actions:empty{display:none}:host.dialog-closing{animation:slide-out-to-bottom .15s ease-in forwards}:host.dialog-width-extra-small{width:444px}:host.dialog-width-small{width:600px}:host.dialog-width-medium{width:900px}:host.dialog-width-large{width:1200px}:host.dialog-width-extra-large{width:1536px}:host.dialog-width-responsive{max-width:100vw;margin:0 12px}@media only screen and (width<=575px){:host.dialog-width-responsive{max-height:92vh;margin-top:4vh;margin-bottom:4vh}:host.dialog-width-responsive .fw-dialog{border-radius:12px}:host.dialog-width-responsive .fw-dialog .dialog-body{max-height:65vh;overflow-y:auto;-webkit-overflow-scrolling:touch}:host.dialog-width-responsive .fw-dialog .dialog-body::-webkit-scrollbar{width:4px}:host.dialog-width-responsive .fw-dialog .dialog-body::-webkit-scrollbar-track{background:var(--separations-base)}:host.dialog-width-responsive .fw-dialog .dialog-body::-webkit-scrollbar-thumb{background:var(--slate-base);border-radius:2px}}@media only screen and (width>=576px){:host.dialog-width-responsive{width:90vw;max-width:600px;margin:0}}@media only screen and (width>=768px){:host.dialog-width-responsive{width:80vw;max-width:900px}:host.dialog-width-responsive .fw-dialog .dialog-body{max-height:70vh;overflow-y:auto}}@media only screen and (width>=992px){:host.dialog-width-responsive{width:60vw;max-width:1200px}}@media only screen and (width>=1200px){:host.dialog-width-responsive{width:50vw;max-width:1536px}}\n"], dependencies: [{ kind: "component", type: FwIconButtonComponent, selector: "fw-icon-button", inputs: ["color", "icon", "size", "disabled", "selected", "border", "focusInitial", "ariaLabel"] }, { kind: "component", type: FwIconComponent, selector: "fw-icon", inputs: ["ariaLabel", "size", "color"] }] }); }
3219
3219
  }
3220
3220
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FwDialogComponent, decorators: [{
3221
3221
  type: Component,
3222
- args: [{ selector: 'fw-dialog', imports: [FwIconButtonComponent, FwIconComponent], template: "<div class=\"fw-dialog\">\n @if (showClose()) {\n <fw-icon-button tabindex=\"-1\" icon=\"close\" color=\"slate\" [ariaLabel]=\"closeLabel()\" (click)=\"handleCloseButton()\"> </fw-icon-button>\n }\n <div class=\"dialog-header\" [id]=\"headerId\">\n <ng-content select=\"fw-dialog-header\"></ng-content>\n @if (title()) {\n <div class=\"dialog-title\">\n <h3 class=\"vision-h3\">{{ title() }}</h3>\n </div>\n }\n </div>\n <div class=\"dialog-body\">\n <ng-content select=\"fw-dialog-content\"></ng-content>\n </div>\n <div class=\"dialog-actions\">\n <ng-content select=\"fw-dialog-actions\"></ng-content>\n </div>\n</div>\n", styles: ["@keyframes slide-in-from-bottom{0%{opacity:0;transform:translateY(100vh)}to{opacity:1;transform:translateY(0)}}@keyframes slide-out-to-bottom{0%{opacity:1;transform:translateY(0)}99%{opacity:0;transform:translateY(100vh)}to{opacity:0;transform:translateY(100vh)}}:host{box-sizing:border-box;background-color:var(--card-background);border:1px solid var(--separations-border);border-radius:8px;display:flex;flex-direction:column;overflow:hidden;animation:slide-in-from-bottom .15s ease-out}:host.dialog-closing{animation:slide-out-to-bottom .15s ease-in forwards}:host.dialog-width-extra-small{width:444px}:host.dialog-width-small{width:600px}:host.dialog-width-medium{width:900px}:host.dialog-width-large{width:1200px}:host.dialog-width-extra-large{width:1536px}:host.dialog-width-responsive{max-width:100vw;margin:0 12px}@media only screen and (width<=575px){:host.dialog-width-responsive{max-height:92vh;margin-top:4vh;margin-bottom:4vh}:host.dialog-width-responsive .fw-dialog{border-radius:12px}:host.dialog-width-responsive .fw-dialog .dialog-body{max-height:65vh;overflow-y:auto;-webkit-overflow-scrolling:touch}:host.dialog-width-responsive .fw-dialog .dialog-body::-webkit-scrollbar{width:4px}:host.dialog-width-responsive .fw-dialog .dialog-body::-webkit-scrollbar-track{background:var(--separations-base)}:host.dialog-width-responsive .fw-dialog .dialog-body::-webkit-scrollbar-thumb{background:var(--slate-base);border-radius:2px}}@media only screen and (width>=576px){:host.dialog-width-responsive{width:90vw;max-width:600px;margin:0}}@media only screen and (width>=768px){:host.dialog-width-responsive{width:80vw;max-width:900px}:host.dialog-width-responsive .fw-dialog .dialog-body{max-height:70vh;overflow-y:auto}}@media only screen and (width>=992px){:host.dialog-width-responsive{width:60vw;max-width:1200px}}@media only screen and (width>=1200px){:host.dialog-width-responsive{width:50vw;max-width:1536px}}:host .fw-dialog{position:relative}:host .fw-dialog fw-icon-button{position:absolute;top:4px;right:4px}:host .fw-dialog .dialog-header{background-color:var(--card-header)}:host .fw-dialog .dialog-header .dialog-title{display:flex;box-sizing:border-box;border-bottom:1px solid var(--separations-base);padding:12px 16px;height:44px;overflow:hidden;align-items:center}:host .fw-dialog .dialog-header .dialog-title h3{overflow:clip visible;min-width:0;white-space:nowrap;text-overflow:ellipsis;margin-right:30px;flex:1}:host .fw-dialog .dialog-header h3{margin:0}:host .fw-dialog .dialog-header:empty{display:none}:host .fw-dialog .dialog-body{background-color:var(--card-background);border-bottom:1px solid var(--separations-base)}:host .fw-dialog .dialog-body:empty{display:none}:host .fw-dialog .dialog-actions{padding:16px}:host .fw-dialog .dialog-actions:empty{display:none}\n"] }]
3222
+ args: [{ selector: 'fw-dialog', imports: [FwIconButtonComponent, FwIconComponent], template: "<div class=\"dialog-header\" [id]=\"headerId\">\n <ng-content select=\"fw-dialog-header\"></ng-content>\n @if (title()) {\n <div class=\"dialog-title\">\n @if (icon()) {\n <fw-icon [color]=\"iconColor()\">{{ icon() }}</fw-icon>\n }\n <h3 class=\"vision-h3\">{{ title() }}</h3>\n </div>\n }\n</div>\n<ng-content select=\"fw-dialog-content\"/>\n<div class=\"dialog-actions\">\n <ng-content select=\"fw-dialog-actions\"></ng-content>\n</div>\n@if (showClose()) {\n <fw-icon-button\n tabindex=\"-1\" icon=\"close\" color=\"slate\"\n (click)=\"handleCloseButton()\"\n />\n}\n", styles: ["@keyframes slide-in-from-bottom{0%{opacity:0;transform:translateY(100vh)}to{opacity:1;transform:translateY(0)}}@keyframes slide-out-to-bottom{0%{opacity:1;transform:translateY(0)}99%{opacity:0;transform:translateY(100vh)}to{opacity:0;transform:translateY(100vh)}}:host{box-sizing:border-box;background-color:var(--card-background);border:1px solid var(--separations-border);border-radius:8px;display:flex;flex-direction:column;overflow:hidden;animation:slide-in-from-bottom .15s ease-out;position:relative;max-height:80vh}:host fw-icon-button{position:absolute;top:4px;right:4px}:host .dialog-header{background-color:var(--card-header)}:host .dialog-header .dialog-title{display:flex;gap:8px;box-sizing:border-box;border-bottom:1px solid var(--separations-base);padding:12px 16px;height:44px;overflow:hidden;align-items:center}:host .dialog-header .dialog-title fw-icon{font-size:22px}:host .dialog-header .dialog-title h3{overflow:clip visible;min-width:0;white-space:nowrap;text-overflow:ellipsis;margin-right:30px;flex:1}:host .dialog-header h3{margin:0}:host .dialog-header:empty{display:none}:host ::ng-deep fw-dialog-content{flex-shrink:1;overflow-y:auto;background-color:var(--card-background)}:host ::ng-deep fw-dialog-content:empty{display:none}:host .dialog-actions{border-top:1px solid var(--separations-base);padding:16px}:host .dialog-actions:empty{display:none}:host.dialog-closing{animation:slide-out-to-bottom .15s ease-in forwards}:host.dialog-width-extra-small{width:444px}:host.dialog-width-small{width:600px}:host.dialog-width-medium{width:900px}:host.dialog-width-large{width:1200px}:host.dialog-width-extra-large{width:1536px}:host.dialog-width-responsive{max-width:100vw;margin:0 12px}@media only screen and (width<=575px){:host.dialog-width-responsive{max-height:92vh;margin-top:4vh;margin-bottom:4vh}:host.dialog-width-responsive .fw-dialog{border-radius:12px}:host.dialog-width-responsive .fw-dialog .dialog-body{max-height:65vh;overflow-y:auto;-webkit-overflow-scrolling:touch}:host.dialog-width-responsive .fw-dialog .dialog-body::-webkit-scrollbar{width:4px}:host.dialog-width-responsive .fw-dialog .dialog-body::-webkit-scrollbar-track{background:var(--separations-base)}:host.dialog-width-responsive .fw-dialog .dialog-body::-webkit-scrollbar-thumb{background:var(--slate-base);border-radius:2px}}@media only screen and (width>=576px){:host.dialog-width-responsive{width:90vw;max-width:600px;margin:0}}@media only screen and (width>=768px){:host.dialog-width-responsive{width:80vw;max-width:900px}:host.dialog-width-responsive .fw-dialog .dialog-body{max-height:70vh;overflow-y:auto}}@media only screen and (width>=992px){:host.dialog-width-responsive{width:60vw;max-width:1200px}}@media only screen and (width>=1200px){:host.dialog-width-responsive{width:50vw;max-width:1536px}}\n"] }]
3223
3223
  }], propDecorators: { width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], iconColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconColor", required: false }] }], showClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClose", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], externalClasses: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], close: [{
3224
3224
  type: Output
3225
3225
  }], hostTitle: [{
@@ -3230,90 +3230,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
3230
3230
  args: ['class']
3231
3231
  }] } });
3232
3232
 
3233
- /* eslint-disable @typescript-eslint/no-explicit-any */
3234
- class FwDialogService extends Dialog {
3235
- constructor() {
3236
- super();
3237
- this.overlay = inject(Overlay);
3238
- this._overlayContainerRef = inject(OverlayContainer);
3239
- }
3240
- /**
3241
- * Open a custom component in an overlay and positioned near the top
3242
- */
3243
- openDialog(component, config, topOffset) {
3244
- const defaultSettings = {
3245
- backdropClass: 'vision-overlay',
3246
- positionStrategy: config?.responsive
3247
- ? this.overlay.position().global()
3248
- .top('5vh') // Reduced top margin for mobile optimization
3249
- .centerHorizontally()
3250
- : this.overlay.position().global()
3251
- .top(topOffset ? topOffset : '10vh')
3252
- .centerHorizontally(),
3253
- disableClose: true, // Disable default backdrop close to handle it manually
3254
- ariaModal: true, // CDK defaults this to false; the dialog panel is genuinely modal
3255
- };
3256
- config = { ...config, ...defaultSettings };
3257
- const dialogRef = super.open(component, config);
3258
- // Handle backdrop clicks with animation
3259
- if (dialogRef.overlayRef.backdropElement) {
3260
- dialogRef.overlayRef.backdropElement.addEventListener('click', evt => {
3261
- const isBackdropCloseEnabled = !config.canCloseCheck || config.canCloseCheck();
3262
- if (isBackdropCloseEnabled) {
3263
- evt.stopPropagation();
3264
- this.closeWithAnimation(dialogRef);
3265
- }
3266
- });
3267
- }
3268
- // Handle ESC key with animation
3269
- dialogRef.overlayRef.keydownEvents().subscribe(event => {
3270
- if (event.key === 'Escape') {
3271
- const isBackdropCloseEnabled = !config.canCloseCheck || config.canCloseCheck();
3272
- if (isBackdropCloseEnabled) {
3273
- this.closeWithAnimation(dialogRef);
3274
- }
3275
- }
3276
- });
3277
- return dialogRef;
3278
- }
3279
- openModalDialog(component, config, topOffset) {
3280
- const defaultSettings = {
3281
- backdropClass: 'vision-overlay',
3282
- positionStrategy: this.overlay.position().global().top(topOffset ? topOffset : '10vh').centerHorizontally(),
3283
- disableClose: true, // Disable default backdrop close to handle it manually
3284
- ariaModal: true, // CDK defaults this to false; the dialog panel is genuinely modal
3285
- };
3286
- config = { ...config, ...defaultSettings };
3287
- return super.open(component, config);
3288
- }
3289
- closeWithAnimation(dialogRef) {
3290
- const dialogElement = dialogRef.overlayRef.overlayElement?.querySelector('fw-dialog, fw-dialog-confirm, fw-dialog-simple');
3291
- if (dialogElement && !dialogElement.classList.contains('dialog-closing')) {
3292
- if (dialogElement.tagName.toLowerCase() !== 'fw-dialog') {
3293
- // For fw-dialog-confirm and fw-dialog-simple, apply the class to the inner fw-dialog element
3294
- const innerDialog = dialogElement.querySelector('fw-dialog');
3295
- if (innerDialog) {
3296
- innerDialog.classList.add('dialog-closing');
3297
- }
3298
- }
3299
- else {
3300
- dialogElement.classList.add('dialog-closing');
3301
- }
3302
- setTimeout(() => {
3303
- dialogRef.close();
3304
- }, 300);
3305
- }
3306
- }
3307
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FwDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3308
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FwDialogService, providedIn: 'root' }); }
3309
- }
3310
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FwDialogService, decorators: [{
3311
- type: Injectable,
3312
- args: [{
3313
- providedIn: 'root',
3314
- }]
3315
- }], ctorParameters: () => [] });
3316
-
3317
3233
  /**
3318
3234
  * Sub-component for rendering the action button row of a dialog, laid out with flex and end-alignment
3319
3235
  * @see [Vision storybook](https://cdn.flywheel.io/docs/vision/master/?path=/docs/components-dialog--docs)
@@ -3354,7 +3270,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
3354
3270
  class FwDialogContentComponent {
3355
3271
  constructor() {
3356
3272
  this.sanitizer = inject(DomSanitizer);
3357
- this.padded = input(undefined, ...(ngDevMode ? [{ debugName: "padded" }] : /* istanbul ignore next */ []));
3273
+ this.padded = input(false, ...(ngDevMode ? [{ debugName: "padded" }] : /* istanbul ignore next */ []));
3358
3274
  }
3359
3275
  get style() {
3360
3276
  if (this.padded()) {
@@ -3479,6 +3395,113 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
3479
3395
  args: ['class']
3480
3396
  }] } });
3481
3397
 
3398
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3399
+ ;
3400
+ /**
3401
+ * Wrapper class for the Angular CDK Dialog Service. Manages the opening and closing of dialogs.
3402
+ * @see [Vision Storybook](https://cdn.flywheel.io/docs/vision/master/?path=/docs/components-dialogs--docs)
3403
+ * @see [Angular CDK Dialog Docs](https://material.angular.dev/cdk/dialog/api#services)
3404
+ */
3405
+ class FwDialogService extends Dialog {
3406
+ constructor() {
3407
+ super();
3408
+ this.overlay = inject(Overlay);
3409
+ this._overlayContainerRef = inject(OverlayContainer);
3410
+ }
3411
+ /**
3412
+ * Open a custom component in an overlay and positioned near the top
3413
+ */
3414
+ openDialog(component, config, topOffset) {
3415
+ const parsedConfig = this.parseFwDialogConfig({
3416
+ ...config,
3417
+ topOffset,
3418
+ });
3419
+ const dialogRef = super.open(component, parsedConfig);
3420
+ this.registerCloseListeners(dialogRef, config);
3421
+ return dialogRef;
3422
+ }
3423
+ openModalDialog(component, config, topOffset) {
3424
+ const defaultSettings = {
3425
+ backdropClass: 'vision-overlay',
3426
+ positionStrategy: this.overlay.position().global().top(topOffset ? topOffset : '10vh').centerHorizontally(),
3427
+ disableClose: true, // Disable default backdrop close to handle it manually
3428
+ ariaModal: true, // CDK defaults this to false; the dialog panel is genuinely modal
3429
+ };
3430
+ const parsedConfig = this.parseFwDialogConfig({ ...config, ...defaultSettings });
3431
+ const dialogRef = super.open(component, parsedConfig);
3432
+ this.registerCloseListeners(dialogRef, config);
3433
+ return dialogRef;
3434
+ }
3435
+ closeWithAnimation(dialogRef) {
3436
+ const dialogElement = dialogRef.overlayRef.overlayElement?.querySelector('fw-dialog, fw-dialog-confirm, fw-dialog-simple');
3437
+ if (dialogElement && !dialogElement.classList.contains('dialog-closing')) {
3438
+ if (dialogElement.tagName.toLowerCase() !== 'fw-dialog') {
3439
+ // For fw-dialog-confirm and fw-dialog-simple, apply the class to the inner fw-dialog element
3440
+ const innerDialog = dialogElement.querySelector('fw-dialog');
3441
+ if (innerDialog) {
3442
+ innerDialog.classList.add('dialog-closing');
3443
+ }
3444
+ }
3445
+ else {
3446
+ dialogElement.classList.add('dialog-closing');
3447
+ }
3448
+ setTimeout(() => {
3449
+ dialogRef.close();
3450
+ }, 300);
3451
+ }
3452
+ }
3453
+ registerCloseListeners(dialogRef, config) {
3454
+ // Handle backdrop clicks with animation
3455
+ if (dialogRef.overlayRef.backdropElement) {
3456
+ dialogRef.overlayRef.backdropElement.addEventListener('click', evt => {
3457
+ const isBackdropCloseEnabled = !config?.canCloseCheck || config.canCloseCheck();
3458
+ if (isBackdropCloseEnabled) {
3459
+ evt.stopPropagation();
3460
+ this.closeWithAnimation(dialogRef);
3461
+ }
3462
+ });
3463
+ }
3464
+ // Handle ESC key with animation
3465
+ dialogRef.overlayRef.keydownEvents().subscribe(event => {
3466
+ if (event.key === 'Escape') {
3467
+ const isBackdropCloseEnabled = !config?.canCloseCheck || config.canCloseCheck();
3468
+ if (isBackdropCloseEnabled) {
3469
+ this.closeWithAnimation(dialogRef);
3470
+ }
3471
+ }
3472
+ });
3473
+ }
3474
+ parseFwDialogConfig(config) {
3475
+ const responsivePosition = this.overlay.position()
3476
+ .global()
3477
+ .top('5vh') // Reduced top margin for mobile optimization
3478
+ .centerHorizontally();
3479
+ const standardPosition = this.overlay.position()
3480
+ .global()
3481
+ .top(config?.topOffset ? config.topOffset : '10vh')
3482
+ .centerHorizontally();
3483
+ const parsedConfig = {
3484
+ backdropClass: 'vision-overlay',
3485
+ maxHeight: '80vh',
3486
+ positionStrategy: config?.responsive
3487
+ ? responsivePosition
3488
+ : standardPosition,
3489
+ disableClose: true, // Disable default backdrop close to handle it manually
3490
+ ariaModal: true, // CDK defaults this to false; the dialog panel is genuinely modal
3491
+ ...config,
3492
+ };
3493
+ return parsedConfig;
3494
+ }
3495
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FwDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3496
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FwDialogService, providedIn: 'root' }); }
3497
+ }
3498
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FwDialogService, decorators: [{
3499
+ type: Injectable,
3500
+ args: [{
3501
+ providedIn: 'root',
3502
+ }]
3503
+ }], ctorParameters: () => [] });
3504
+
3482
3505
  /**
3483
3506
  * Sub-component for rendering the header row of a dialog, with consistent padding and border styling
3484
3507
  * @see [Vision storybook](https://cdn.flywheel.io/docs/vision/master/?path=/docs/components-dialog--docs)
@@ -3600,15 +3623,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
3600
3623
  }] } });
3601
3624
 
3602
3625
  /**
3603
- * @deprecated import component directly, intent to remove in v20
3626
+ * Module for easily importing all the dialog components
3627
+ * @see [Vision Storybook](https://cdn.flywheel.io/docs/vision/master/?path=/docs/components-dialogs--docs)
3604
3628
  */
3605
3629
  class FwDialogsModule {
3606
3630
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FwDialogsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
3607
3631
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.18", ngImport: i0, type: FwDialogsModule, imports: [CommonModule,
3608
3632
  DialogModule,
3609
- FwButtonModule,
3610
- FwIconButtonModule,
3611
- FwIconModule,
3633
+ FwButtonComponent,
3634
+ FwIconButtonComponent,
3635
+ FwIconComponent,
3612
3636
  FwDialogActionsComponent,
3613
3637
  FwDialogComponent,
3614
3638
  FwDialogConfirmComponent,
@@ -3623,10 +3647,7 @@ class FwDialogsModule {
3623
3647
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FwDialogsModule, providers: [
3624
3648
  FwDialogService,
3625
3649
  ], imports: [CommonModule,
3626
- DialogModule,
3627
- FwButtonModule,
3628
- FwIconButtonModule,
3629
- FwIconModule] }); }
3650
+ DialogModule] }); }
3630
3651
  }
3631
3652
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: FwDialogsModule, decorators: [{
3632
3653
  type: NgModule,
@@ -3634,9 +3655,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImpo
3634
3655
  imports: [
3635
3656
  CommonModule,
3636
3657
  DialogModule,
3637
- FwButtonModule,
3638
- FwIconButtonModule,
3639
- FwIconModule,
3658
+ FwButtonComponent,
3659
+ FwIconButtonComponent,
3660
+ FwIconComponent,
3640
3661
  FwDialogActionsComponent,
3641
3662
  FwDialogComponent,
3642
3663
  FwDialogConfirmComponent,