From c5d3f09d50af56c27f50476c88c0a0816b96d1e6 Mon Sep 17 00:00:00 2001 From: Kevin Buhmann Date: Thu, 16 Nov 2023 18:53:49 -0600 Subject: [PATCH] feat(wizard): add back inline wizards in 15.x (#1067) This reverts commit 7470769480b843dc332adbd25f67624ce4979e56 (#419), removes the deprecated comments, and adds a comment explaining when inline wizards are used. Inline wizards are used by vSphere plugins to display a wizard inside an iframe that is inside a modal. CDE-154 --- .storybook/stories/modal/modal.stories.ts | 1 + projects/angular/clarity.api.md | 13 ++- projects/angular/src/modal/modal.ts | 5 +- .../angular/src/wizard/_wizard.clarity.scss | 83 +++++++++++++++++++ projects/angular/src/wizard/wizard.html | 2 + projects/angular/src/wizard/wizard.ts | 24 ++++++ .../src/app/wizard/wizard-inline.demo.html | 63 ++++++++++++++ .../demo/src/app/wizard/wizard-inline.demo.ts | 18 ++++ .../demo/src/app/wizard/wizard.demo.module.ts | 3 + .../src/app/wizard/wizard.demo.routing.ts | 2 + projects/demo/src/app/wizard/wizard.demo.ts | 1 + 11 files changed, 211 insertions(+), 4 deletions(-) create mode 100644 projects/demo/src/app/wizard/wizard-inline.demo.html create mode 100644 projects/demo/src/app/wizard/wizard-inline.demo.ts diff --git a/.storybook/stories/modal/modal.stories.ts b/.storybook/stories/modal/modal.stories.ts index 86be0903e6..dae7d29340 100644 --- a/.storybook/stories/modal/modal.stories.ts +++ b/.storybook/stories/modal/modal.stories.ts @@ -25,6 +25,7 @@ const defaultStory: Story = args => ({ [clrModalCloseButtonAriaLabel]="clrModalCloseButtonAriaLabel" [clrModalLabelledById]="clrModalLabelledById" [clrModalOpen]="clrModalOpen" + [clrModalOverrideScrollService]="clrModalOverrideScrollService" [clrModalPreventClose]="clrModalPreventClose" [clrModalSize]="clrModalSize" [clrModalSkipAnimation]="clrModalSkipAnimation" diff --git a/projects/angular/clarity.api.md b/projects/angular/clarity.api.md index 5c18f5669c..41636e9fc7 100644 --- a/projects/angular/clarity.api.md +++ b/projects/angular/clarity.api.md @@ -2650,6 +2650,8 @@ export class ClrModal implements OnChanges, OnDestroy { // (undocumented) altClose: EventEmitter; // (undocumented) + bypassScrollService: boolean; + // (undocumented) closable: boolean; // (undocumented) close(): void; @@ -2684,7 +2686,7 @@ export class ClrModal implements OnChanges, OnDestroy { // (undocumented) stopClose: boolean; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } @@ -4283,7 +4285,7 @@ export class ClrVerticalNavModule { // @public (undocumented) export class ClrWizard implements OnDestroy, AfterContentInit, DoCheck { - constructor(platformId: any, commonStrings: ClrCommonStringsService, navService: WizardNavigationService, pageCollection: PageCollectionService, buttonService: ButtonHubService, headerActionService: HeaderActionService, differs: IterableDiffers); + constructor(platformId: any, commonStrings: ClrCommonStringsService, navService: WizardNavigationService, pageCollection: PageCollectionService, buttonService: ButtonHubService, headerActionService: HeaderActionService, elementRef: ElementRef, differs: IterableDiffers); // Warning: (ae-forgotten-export) The symbol "ButtonHubService" needs to be exported by the entry point index.d.ts // // (undocumented) @@ -4314,6 +4316,8 @@ export class ClrWizard implements OnDestroy, AfterContentInit, DoCheck { // (undocumented) get isFirst(): boolean; // (undocumented) + get isInline(): boolean; + // (undocumented) get isLast(): boolean; modalCancel(): void; // Warning: (ae-forgotten-export) The symbol "WizardNavigationService" needs to be exported by the entry point index.d.ts @@ -4349,6 +4353,9 @@ export class ClrWizard implements OnDestroy, AfterContentInit, DoCheck { stepnavAriaLabel: string; get stopCancel(): boolean; set stopCancel(value: boolean); + // (undocumented) + get stopModalAnimations(): string; + _stopModalAnimations: boolean; get stopNavigation(): boolean; set stopNavigation(value: boolean); get stopNext(): boolean; @@ -4360,7 +4367,7 @@ export class ClrWizard implements OnDestroy, AfterContentInit, DoCheck { // (undocumented) protected wizardTitle: ClrWizardTitle; // (undocumented) - static ɵcmp: i0.ɵɵComponentDeclaration; + static ɵcmp: i0.ɵɵComponentDeclaration; // (undocumented) static ɵfac: i0.ɵɵFactoryDeclaration; } diff --git a/projects/angular/src/modal/modal.ts b/projects/angular/src/modal/modal.ts index fb13ae7bc9..1bce345042 100644 --- a/projects/angular/src/modal/modal.ts +++ b/projects/angular/src/modal/modal.ts @@ -54,6 +54,9 @@ export class ClrModal implements OnChanges, OnDestroy { @Input('clrModalLabelledById') labelledBy = this.modalId; + // presently this is only used by inline wizards + @Input('clrModalOverrideScrollService') bypassScrollService = false; + constructor( private _scrollingService: ScrollingService, public commonStrings: ClrCommonStringsService, @@ -62,7 +65,7 @@ export class ClrModal implements OnChanges, OnDestroy { // Detect when _open is set to true and set no-scrolling to true ngOnChanges(changes: { [propName: string]: SimpleChange }): void { - if (changes && Object.prototype.hasOwnProperty.call(changes, '_open')) { + if (!this.bypassScrollService && changes && Object.prototype.hasOwnProperty.call(changes, '_open')) { if (changes._open.currentValue) { this._scrollingService.stopScrolling(); this.modalStackService.trackModalOpen(this); diff --git a/projects/angular/src/wizard/_wizard.clarity.scss b/projects/angular/src/wizard/_wizard.clarity.scss index f60cb9a5e6..1bc34394c5 100644 --- a/projects/angular/src/wizard/_wizard.clarity.scss +++ b/projects/angular/src/wizard/_wizard.clarity.scss @@ -661,6 +661,89 @@ } } + // Inline wizards are used by vSphere plugins to display a wizard inside an iframe that is inside a modal. + .clr-wizard--inline { + display: block; + width: 100%; + // you will want to set a fixed width and height for these static wizards + // otherwise, you'll get some minor jumping along the right edge when it is + // closed... + + & > clr-modal > .modal:focus { + // need to remove the outline style or trap-focus directive will make + // outline appear in Safari and Microsoft browsers + outline-style: none; + outline-color: transparent; + } + + clr-modal { + @include mixins.equilateral(100%); + display: block; + } + + .modal { + padding: 0; + position: static; + height: 100%; + max-height: 100%; + + .content-container { + height: 100%; + + .nav-panel { + @include mixins.equilateral(99%); + } + } + + .modal-content { + box-shadow: none; + } + + .modal-dialog { + min-height: 100%; + @include mixins.equilateral(100%); + z-index: auto; + } + } + + .modal-body-wrapper { + height: 100%; + } + + .modal-header .close { + display: none; + } + + .nav.navList { + padding-top: 0; + } + + .modal-dialog .modal-content .modal-body .content-area { + overflow-y: auto; + } + + .modal-backdrop { + @include mixins.equilateral(0); + display: none; + } + + .modal-content-wrapper { + align-items: stretch; + height: 100%; + } + + .clr-wizard-stepnav-wrapper, + &.clr-wizard .modal-content { + min-height: 100%; + height: auto; + max-height: 100%; + + .clr-wizard-stepnav { + height: 100%; + } + } + } + .clr-wizard--no-shadow { .modal-content-wrapper, .modal-dialog { diff --git a/projects/angular/src/wizard/wizard.html b/projects/angular/src/wizard/wizard.html index ec7a888206..112e60d77d 100644 --- a/projects/angular/src/wizard/wizard.html +++ b/projects/angular/src/wizard/wizard.html @@ -9,6 +9,8 @@ [clrModalSize]="size" [clrModalClosable]="closable" [clrModalStaticBackdrop]="true" + [clrModalSkipAnimation]="stopModalAnimations" + [clrModalOverrideScrollService]="isInline" [clrModalPreventClose]="true" (clrModalAlternateClose)="modalCancel()" [clrModalLabelledById]="wizardId" diff --git a/projects/angular/src/wizard/wizard.ts b/projects/angular/src/wizard/wizard.ts index 9bf8530074..a645e6a27b 100644 --- a/projects/angular/src/wizard/wizard.ts +++ b/projects/angular/src/wizard/wizard.ts @@ -64,6 +64,13 @@ export class ClrWizard implements OnDestroy, AfterContentInit, DoCheck { */ @Input('clrWizardClosable') closable = true; + /** + * Used to communicate to the underlying modal that animations are not + * wanted. Primary use is for the display of static/inline wizards. + * Set using `[clrWizardPreventModalAnimation]` input. + */ + @Input('clrWizardPreventModalAnimation') _stopModalAnimations = false; + /** * Emits when the wizard is opened or closed. * Listen via `(clrWizardOpenChange)` event. @@ -132,6 +139,7 @@ export class ClrWizard implements OnDestroy, AfterContentInit, DoCheck { public pageCollection: PageCollectionService, public buttonService: ButtonHubService, public headerActionService: HeaderActionService, + private elementRef: ElementRef, differs: IterableDiffers ) { this.subscriptions.push( @@ -250,9 +258,18 @@ export class ClrWizard implements OnDestroy, AfterContentInit, DoCheck { return this.navService.currentPageIsFirst; } + get isInline(): boolean { + return this.elementRef.nativeElement.classList.contains('clr-wizard--inline'); + } + + get stopModalAnimations(): string { + return this._stopModalAnimations ? 'true' : 'false'; + } + ngAfterContentInit(): void { this.pageCollection.pages = this.pages; this.headerActionService.wizardHeaderActions = this.headerActions; + this.initializeButtons(); } ngDoCheck(): void { @@ -481,6 +498,13 @@ export class ClrWizard implements OnDestroy, AfterContentInit, DoCheck { } } + private initializeButtons(): void { + // Only trigger buttons ready if default is open (inlined) + if (this._open) { + this.buttonService.buttonsReady = true; + } + } + private emitWizardFinished(): void { if (!this.stopNext) { this.forceFinish(); diff --git a/projects/demo/src/app/wizard/wizard-inline.demo.html b/projects/demo/src/app/wizard/wizard-inline.demo.html new file mode 100644 index 0000000000..9a2b72c823 --- /dev/null +++ b/projects/demo/src/app/wizard/wizard-inline.demo.html @@ -0,0 +1,63 @@ + + + + + Inline Wizard + + Cancel + Back + Next + Submit + + + Page 1 + + +

Content for page 1

+

+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae minima inventore quia, officiis rem id explicabo + incidunt, illum deleniti qui doloremque voluptatem, saepe tenetur quas! Quaerat explicabo expedita placeat vero. +

+

+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae minima inventore quia, officiis rem id explicabo + incidunt, illum deleniti qui doloremque voluptatem, saepe tenetur quas! Quaerat explicabo expedita placeat vero. +

+

+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae minima inventore quia, officiis rem id explicabo + incidunt, illum deleniti qui doloremque voluptatem, saepe tenetur quas! Quaerat explicabo expedita placeat vero. +

+

+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae minima inventore quia, officiis rem id explicabo + incidunt, illum deleniti qui doloremque voluptatem, saepe tenetur quas! Quaerat explicabo expedita placeat vero. +

+
+ + + Page 2 + + +

Content for page 2

+

+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quae minima inventore quia, officiis rem id explicabo + incidunt, illum deleniti qui doloremque voluptatem, saepe tenetur quas! Quaerat explicabo expedita placeat vero. +

+
+ + + Page 3 + + +

Content for page 3

+
+
diff --git a/projects/demo/src/app/wizard/wizard-inline.demo.ts b/projects/demo/src/app/wizard/wizard-inline.demo.ts new file mode 100644 index 0000000000..717c4fee00 --- /dev/null +++ b/projects/demo/src/app/wizard/wizard-inline.demo.ts @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved. + * This software is released under MIT license. + * The full license information can be found in LICENSE in the root directory of this project. + */ + +import { Component, ViewChild } from '@angular/core'; +import { ClrWizard } from '@clr/angular'; + +@Component({ + selector: 'clr-wizard-inline', + templateUrl: './wizard-inline.demo.html', +}) +export class WizardInlineDemo { + @ViewChild('wizard') wizard: ClrWizard; + + open = true; +} diff --git a/projects/demo/src/app/wizard/wizard.demo.module.ts b/projects/demo/src/app/wizard/wizard.demo.module.ts index b45dfd4e9a..dd6a9c2536 100644 --- a/projects/demo/src/app/wizard/wizard.demo.module.ts +++ b/projects/demo/src/app/wizard/wizard.demo.module.ts @@ -17,6 +17,7 @@ import { WizardCustomButtonsDemo } from './wizard-custom-buttons.demo'; import { WizardForceForwardDemo } from './wizard-force-forward.demo'; import { WizardFormValidation } from './wizard-form-validation.demo'; import { WizardHeaderActionsDemo } from './wizard-header-actions.demo'; +import { WizardInlineDemo } from './wizard-inline.demo'; import { WizardJumpToDemo } from './wizard-jump-to.demo'; import { WizardNotClosableDemo } from './wizard-not-closable.demo'; import { WizardResetDemo } from './wizard-reset.demo'; @@ -39,6 +40,7 @@ import { ROUTING } from './wizard.demo.routing'; WizardResetDemo, WizardHeaderActionsDemo, WizardAltCancelDemo, + WizardInlineDemo, WizardJumpToDemo, WizardAltNextDemo, WizardForceForwardDemo, @@ -55,6 +57,7 @@ import { ROUTING } from './wizard.demo.routing'; WizardCustomButtonsDemo, WizardHeaderActionsDemo, WizardAltCancelDemo, + WizardInlineDemo, WizardResetDemo, WizardJumpToDemo, WizardAltNextDemo, diff --git a/projects/demo/src/app/wizard/wizard.demo.routing.ts b/projects/demo/src/app/wizard/wizard.demo.routing.ts index e1f5090f5e..fb57f8d9bb 100644 --- a/projects/demo/src/app/wizard/wizard.demo.routing.ts +++ b/projects/demo/src/app/wizard/wizard.demo.routing.ts @@ -15,6 +15,7 @@ import { WizardCustomButtonsDemo } from './wizard-custom-buttons.demo'; import { WizardForceForwardDemo } from './wizard-force-forward.demo'; import { WizardFormValidation } from './wizard-form-validation.demo'; import { WizardHeaderActionsDemo } from './wizard-header-actions.demo'; +import { WizardInlineDemo } from './wizard-inline.demo'; import { WizardJumpToDemo } from './wizard-jump-to.demo'; import { WizardNotClosableDemo } from './wizard-not-closable.demo'; import { WizardResetDemo } from './wizard-reset.demo'; @@ -37,6 +38,7 @@ const ROUTES: Routes = [ { path: 'custom-buttons', component: WizardCustomButtonsDemo }, { path: 'header-actions', component: WizardHeaderActionsDemo }, { path: 'alt-cancel', component: WizardAltCancelDemo }, + { path: 'inline', component: WizardInlineDemo }, { path: 'jump-to', component: WizardJumpToDemo }, { path: 'reset', component: WizardResetDemo }, { path: 'alt-next', component: WizardAltNextDemo }, diff --git a/projects/demo/src/app/wizard/wizard.demo.ts b/projects/demo/src/app/wizard/wizard.demo.ts index 4ffd50ed12..4035bf6c7d 100644 --- a/projects/demo/src/app/wizard/wizard.demo.ts +++ b/projects/demo/src/app/wizard/wizard.demo.ts @@ -29,6 +29,7 @@ import { Component, ViewEncapsulation } from '@angular/core';
  • Header actions
  • Alt cancel
  • Alt next
  • +
  • Inline/static wizard
  • Force forward
  • Stop navigation