@rossigee/clarity-angular 18.2.1-fixed.1 → 18.2.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.
- package/fesm2022/clr-angular-accordion.mjs +355 -0
- package/fesm2022/clr-angular-accordion.mjs.map +1 -0
- package/fesm2022/clr-angular-button.mjs +713 -0
- package/fesm2022/clr-angular-button.mjs.map +1 -0
- package/fesm2022/clr-angular-collapsible-panel.mjs +201 -0
- package/fesm2022/clr-angular-collapsible-panel.mjs.map +1 -0
- package/fesm2022/clr-angular-data-datagrid.mjs +7635 -0
- package/fesm2022/clr-angular-data-datagrid.mjs.map +1 -0
- package/fesm2022/clr-angular-data-stack-view.mjs +442 -0
- package/fesm2022/clr-angular-data-stack-view.mjs.map +1 -0
- package/fesm2022/clr-angular-data-tree-view.mjs +1106 -0
- package/fesm2022/clr-angular-data-tree-view.mjs.map +1 -0
- package/fesm2022/clr-angular-data.mjs +40 -0
- package/fesm2022/clr-angular-data.mjs.map +1 -0
- package/fesm2022/clr-angular-emphasis-alert.mjs +624 -0
- package/fesm2022/clr-angular-emphasis-alert.mjs.map +1 -0
- package/fesm2022/clr-angular-emphasis-badge.mjs +69 -0
- package/fesm2022/clr-angular-emphasis-badge.mjs.map +1 -0
- package/fesm2022/clr-angular-emphasis-common.mjs +25 -0
- package/fesm2022/clr-angular-emphasis-common.mjs.map +1 -0
- package/fesm2022/clr-angular-emphasis-label.mjs +105 -0
- package/fesm2022/clr-angular-emphasis-label.mjs.map +1 -0
- package/fesm2022/clr-angular-emphasis.mjs +41 -0
- package/fesm2022/clr-angular-emphasis.mjs.map +1 -0
- package/fesm2022/clr-angular-forms-checkbox.mjs +270 -0
- package/fesm2022/clr-angular-forms-checkbox.mjs.map +1 -0
- package/fesm2022/clr-angular-forms-combobox.mjs +1775 -0
- package/fesm2022/clr-angular-forms-combobox.mjs.map +1 -0
- package/fesm2022/clr-angular-forms-common.mjs +1251 -0
- package/fesm2022/clr-angular-forms-common.mjs.map +1 -0
- package/fesm2022/clr-angular-forms-datalist.mjs +263 -0
- package/fesm2022/clr-angular-forms-datalist.mjs.map +1 -0
- package/fesm2022/clr-angular-forms-datepicker.mjs +3274 -0
- package/fesm2022/clr-angular-forms-datepicker.mjs.map +1 -0
- package/fesm2022/clr-angular-forms-file-input.mjs +826 -0
- package/fesm2022/clr-angular-forms-file-input.mjs.map +1 -0
- package/fesm2022/clr-angular-forms-input.mjs +153 -0
- package/fesm2022/clr-angular-forms-input.mjs.map +1 -0
- package/fesm2022/clr-angular-forms-number-input.mjs +236 -0
- package/fesm2022/clr-angular-forms-number-input.mjs.map +1 -0
- package/fesm2022/clr-angular-forms-password.mjs +233 -0
- package/fesm2022/clr-angular-forms-password.mjs.map +1 -0
- package/fesm2022/clr-angular-forms-radio.mjs +231 -0
- package/fesm2022/clr-angular-forms-radio.mjs.map +1 -0
- package/fesm2022/clr-angular-forms-range.mjs +186 -0
- package/fesm2022/clr-angular-forms-range.mjs.map +1 -0
- package/fesm2022/clr-angular-forms-select.mjs +153 -0
- package/fesm2022/clr-angular-forms-select.mjs.map +1 -0
- package/fesm2022/clr-angular-forms-textarea.mjs +136 -0
- package/fesm2022/clr-angular-forms-textarea.mjs.map +1 -0
- package/fesm2022/clr-angular-forms.mjs +100 -0
- package/fesm2022/clr-angular-forms.mjs.map +1 -0
- package/fesm2022/clr-angular-icon.mjs +7397 -0
- package/fesm2022/clr-angular-icon.mjs.map +1 -0
- package/fesm2022/clr-angular-layout-breadcrumbs.mjs +120 -0
- package/fesm2022/clr-angular-layout-breadcrumbs.mjs.map +1 -0
- package/fesm2022/clr-angular-layout-main-container.mjs +100 -0
- package/fesm2022/clr-angular-layout-main-container.mjs.map +1 -0
- package/fesm2022/clr-angular-layout-nav.mjs +582 -0
- package/fesm2022/clr-angular-layout-nav.mjs.map +1 -0
- package/fesm2022/clr-angular-layout-tabs.mjs +807 -0
- package/fesm2022/clr-angular-layout-tabs.mjs.map +1 -0
- package/fesm2022/clr-angular-layout-vertical-nav.mjs +507 -0
- package/fesm2022/clr-angular-layout-vertical-nav.mjs.map +1 -0
- package/fesm2022/clr-angular-layout.mjs +44 -0
- package/fesm2022/clr-angular-layout.mjs.map +1 -0
- package/fesm2022/clr-angular-modal.mjs +617 -0
- package/fesm2022/clr-angular-modal.mjs.map +1 -0
- package/fesm2022/clr-angular-popover-common.mjs +1082 -0
- package/fesm2022/clr-angular-popover-common.mjs.map +1 -0
- package/fesm2022/clr-angular-popover-dropdown.mjs +492 -0
- package/fesm2022/clr-angular-popover-dropdown.mjs.map +1 -0
- package/fesm2022/clr-angular-popover-signpost.mjs +494 -0
- package/fesm2022/clr-angular-popover-signpost.mjs.map +1 -0
- package/fesm2022/clr-angular-popover-tooltip.mjs +293 -0
- package/fesm2022/clr-angular-popover-tooltip.mjs.map +1 -0
- package/fesm2022/clr-angular-popover.mjs +41 -0
- package/fesm2022/clr-angular-popover.mjs.map +1 -0
- package/fesm2022/clr-angular-progress-progress-bars.mjs +217 -0
- package/fesm2022/clr-angular-progress-progress-bars.mjs.map +1 -0
- package/fesm2022/clr-angular-progress-spinner.mjs +132 -0
- package/fesm2022/clr-angular-progress-spinner.mjs.map +1 -0
- package/fesm2022/clr-angular-stepper.mjs +694 -0
- package/fesm2022/clr-angular-stepper.mjs.map +1 -0
- package/fesm2022/clr-angular-timeline.mjs +316 -0
- package/fesm2022/clr-angular-timeline.mjs.map +1 -0
- package/fesm2022/clr-angular-utils-conditional.mjs +351 -0
- package/fesm2022/clr-angular-utils-conditional.mjs.map +1 -0
- package/fesm2022/clr-angular-utils-loading.mjs +107 -0
- package/fesm2022/clr-angular-utils-loading.mjs.map +1 -0
- package/fesm2022/clr-angular-utils.mjs +2079 -0
- package/fesm2022/clr-angular-utils.mjs.map +1 -0
- package/fesm2022/clr-angular-wizard.mjs +3074 -0
- package/fesm2022/clr-angular-wizard.mjs.map +1 -0
- package/fesm2022/clr-angular.mjs +2 -2
- package/fesm2022/clr-angular.mjs.map +1 -1
- package/package.json +7 -5
- package/schematics/ng-update/index.d.ts +2 -0
- package/schematics/ng-update/index.js +69 -0
- package/schematics/ng-update/index.js.map +1 -0
- package/schematics/ng-update/migrations/css-migration.d.ts +6 -0
- package/schematics/ng-update/migrations/css-migration.js +177 -0
- package/schematics/ng-update/migrations/css-migration.js.map +1 -0
- package/schematics/ng-update/migrations/import-migration.d.ts +4 -0
- package/schematics/ng-update/migrations/import-migration.js +187 -0
- package/schematics/ng-update/migrations/import-migration.js.map +1 -0
- package/schematics/ng-update/migrations/template-migration.d.ts +6 -0
- package/schematics/ng-update/migrations/template-migration.js +261 -0
- package/schematics/ng-update/migrations/template-migration.js.map +1 -0
- package/schematics/ng-update/replacements/css-replacements.d.ts +17 -0
- package/schematics/ng-update/replacements/css-replacements.js +74 -0
- package/schematics/ng-update/replacements/css-replacements.js.map +1 -0
- package/schematics/ng-update/replacements/import-replacements.d.ts +13 -0
- package/schematics/ng-update/replacements/import-replacements.js +108 -0
- package/schematics/ng-update/replacements/import-replacements.js.map +1 -0
- package/schematics/ng-update/replacements/symbol-replacements.d.ts +12 -0
- package/schematics/ng-update/replacements/symbol-replacements.js +67 -0
- package/schematics/ng-update/replacements/symbol-replacements.js.map +1 -0
- package/schematics/ng-update/replacements/template-replacements.d.ts +19 -0
- package/schematics/ng-update/replacements/template-replacements.js +57 -0
- package/schematics/ng-update/replacements/template-replacements.js.map +1 -0
- package/schematics/ng-update/tests/test-helpers.d.ts +6 -0
- package/schematics/ng-update/tests/test-helpers.js +34 -0
- package/schematics/ng-update/tests/test-helpers.js.map +1 -0
- package/schematics/ng-update/utils/file-visitor.d.ts +8 -0
- package/schematics/ng-update/utils/file-visitor.js +44 -0
- package/schematics/ng-update/utils/file-visitor.js.map +1 -0
- package/schematics/ng-update/utils/regexp-utils.d.ts +16 -0
- package/schematics/ng-update/utils/regexp-utils.js +34 -0
- package/schematics/ng-update/utils/regexp-utils.js.map +1 -0
- package/schematics/vitest.config.d.ts +2 -0
- package/schematics/vitest.config.js +17 -0
- package/schematics/vitest.config.js.map +1 -0
- package/types/clr-angular-accordion.d.ts +100 -0
- package/types/clr-angular-button.d.ts +169 -0
- package/types/clr-angular-collapsible-panel.d.ts +73 -0
- package/types/clr-angular-data-datagrid.d.ts +1843 -0
- package/types/clr-angular-data-stack-view.d.ts +87 -0
- package/types/clr-angular-data-tree-view.d.ts +229 -0
- package/types/clr-angular-data.d.ts +15 -0
- package/types/clr-angular-emphasis-alert.d.ts +175 -0
- package/types/clr-angular-emphasis-badge.d.ts +25 -0
- package/types/clr-angular-emphasis-common.d.ts +6 -0
- package/types/clr-angular-emphasis-label.d.ts +29 -0
- package/types/clr-angular-emphasis.d.ts +15 -0
- package/types/clr-angular-forms-checkbox.d.ts +69 -0
- package/types/clr-angular-forms-combobox.d.ts +353 -0
- package/types/clr-angular-forms-common.d.ts +339 -0
- package/types/clr-angular-forms-datalist.d.ts +59 -0
- package/types/clr-angular-forms-datepicker.d.ts +986 -0
- package/types/clr-angular-forms-file-input.d.ts +193 -0
- package/types/clr-angular-forms-input.d.ts +29 -0
- package/types/clr-angular-forms-number-input.d.ts +43 -0
- package/types/clr-angular-forms-password.d.ts +52 -0
- package/types/clr-angular-forms-radio.d.ts +50 -0
- package/types/clr-angular-forms-range.d.ts +37 -0
- package/types/clr-angular-forms-select.d.ts +36 -0
- package/types/clr-angular-forms-textarea.d.ts +29 -0
- package/types/clr-angular-forms.d.ts +36 -0
- package/types/clr-angular-icon.d.ts +1498 -0
- package/types/clr-angular-layout-breadcrumbs.d.ts +45 -0
- package/types/clr-angular-layout-main-container.d.ts +28 -0
- package/types/clr-angular-layout-nav.d.ts +142 -0
- package/types/clr-angular-layout-tabs.d.ts +158 -0
- package/types/clr-angular-layout-vertical-nav.d.ts +128 -0
- package/types/clr-angular-layout.d.ts +19 -0
- package/types/clr-angular-modal.d.ts +160 -0
- package/types/clr-angular-popover-common.d.ts +254 -0
- package/types/clr-angular-popover-dropdown.d.ts +123 -0
- package/types/clr-angular-popover-signpost.d.ts +157 -0
- package/types/clr-angular-popover-tooltip.d.ts +83 -0
- package/types/clr-angular-popover.d.ts +16 -0
- package/types/clr-angular-progress-progress-bars.d.ts +57 -0
- package/types/clr-angular-progress-spinner.d.ts +44 -0
- package/types/clr-angular-stepper.d.ts +179 -0
- package/types/clr-angular-timeline.d.ts +86 -0
- package/types/clr-angular-utils-conditional.d.ts +132 -0
- package/types/clr-angular-utils-loading.d.ts +38 -0
- package/types/clr-angular-utils.d.ts +913 -0
- package/types/clr-angular-wizard.d.ts +1508 -0
|
@@ -0,0 +1,3074 @@
|
|
|
1
|
+
import * as i6 from '@angular/common';
|
|
2
|
+
import { isPlatformBrowser, CommonModule } from '@angular/common';
|
|
3
|
+
import * as i0 from '@angular/core';
|
|
4
|
+
import { Injectable, EventEmitter, Output, Input, Component, Directive, ContentChild, ViewChildren, PLATFORM_ID, ViewChild, ContentChildren, Inject, NgModule } from '@angular/core';
|
|
5
|
+
import * as i3 from '@clr/angular/utils';
|
|
6
|
+
import { uniqueIdFactory } from '@clr/angular/utils';
|
|
7
|
+
import { filter } from 'rxjs/operators';
|
|
8
|
+
import { Subject, startWith, debounceTime, tap } from 'rxjs';
|
|
9
|
+
import * as i5 from '@clr/angular/icon';
|
|
10
|
+
import { ClarityIcons, errorStandardIcon, successStandardIcon, ClrIcon } from '@clr/angular/icon';
|
|
11
|
+
import * as i8 from '@clr/angular/modal';
|
|
12
|
+
import { ClrModalModule } from '@clr/angular/modal';
|
|
13
|
+
import { ClrAlertModule } from '@clr/angular/emphasis/alert';
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
17
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
18
|
+
* This software is released under MIT license.
|
|
19
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
20
|
+
*/
|
|
21
|
+
var ClrWizardFooterAlign;
|
|
22
|
+
(function (ClrWizardFooterAlign) {
|
|
23
|
+
ClrWizardFooterAlign["START"] = "start";
|
|
24
|
+
ClrWizardFooterAlign["END"] = "end";
|
|
25
|
+
})(ClrWizardFooterAlign || (ClrWizardFooterAlign = {}));
|
|
26
|
+
const CLR_WIZARD_FOOTER_ALIGN_VALUES = new Set(Object.values(ClrWizardFooterAlign));
|
|
27
|
+
function footerAlignAttribute(value) {
|
|
28
|
+
if (CLR_WIZARD_FOOTER_ALIGN_VALUES.has(value)) {
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
throw new Error(`Invalid ClrWizardFooterAlign: "${value}". Expected one of: ${[...CLR_WIZARD_FOOTER_ALIGN_VALUES].join(', ')}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/*
|
|
35
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
36
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
37
|
+
* This software is released under MIT license.
|
|
38
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
39
|
+
*/
|
|
40
|
+
var ClrWizardStepnavLayout;
|
|
41
|
+
(function (ClrWizardStepnavLayout) {
|
|
42
|
+
ClrWizardStepnavLayout["VERTICAL"] = "vertical";
|
|
43
|
+
ClrWizardStepnavLayout["HORIZONTAL"] = "horizontal";
|
|
44
|
+
})(ClrWizardStepnavLayout || (ClrWizardStepnavLayout = {}));
|
|
45
|
+
const CLR_WIZARD_STEPNAV_LAYOUT_VALUES = new Set(Object.values(ClrWizardStepnavLayout));
|
|
46
|
+
function stepnavLayoutAttribute(value) {
|
|
47
|
+
if (CLR_WIZARD_STEPNAV_LAYOUT_VALUES.has(value)) {
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
50
|
+
throw new Error(`Invalid ClrWizardStepnavLayout: "${value}". Expected one of: ${[...CLR_WIZARD_STEPNAV_LAYOUT_VALUES].join(', ')}`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/*
|
|
54
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
55
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
56
|
+
* This software is released under MIT license.
|
|
57
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
58
|
+
*/
|
|
59
|
+
class ButtonHubService {
|
|
60
|
+
constructor() {
|
|
61
|
+
this.buttonsReady = false;
|
|
62
|
+
this._previousBtnClicked = new Subject();
|
|
63
|
+
this._nextBtnClicked = new Subject();
|
|
64
|
+
this._dangerBtnClicked = new Subject();
|
|
65
|
+
this._cancelBtnClicked = new Subject();
|
|
66
|
+
this._finishBtnClicked = new Subject();
|
|
67
|
+
this._customBtnClicked = new Subject();
|
|
68
|
+
}
|
|
69
|
+
get previousBtnClicked() {
|
|
70
|
+
return this._previousBtnClicked.asObservable();
|
|
71
|
+
}
|
|
72
|
+
get nextBtnClicked() {
|
|
73
|
+
return this._nextBtnClicked.asObservable();
|
|
74
|
+
}
|
|
75
|
+
get dangerBtnClicked() {
|
|
76
|
+
return this._dangerBtnClicked.asObservable();
|
|
77
|
+
}
|
|
78
|
+
get cancelBtnClicked() {
|
|
79
|
+
return this._cancelBtnClicked.asObservable();
|
|
80
|
+
}
|
|
81
|
+
get finishBtnClicked() {
|
|
82
|
+
return this._finishBtnClicked.asObservable();
|
|
83
|
+
}
|
|
84
|
+
get customBtnClicked() {
|
|
85
|
+
return this._customBtnClicked.asObservable();
|
|
86
|
+
}
|
|
87
|
+
buttonClicked(buttonType) {
|
|
88
|
+
if ('previous' === buttonType) {
|
|
89
|
+
this._previousBtnClicked.next();
|
|
90
|
+
}
|
|
91
|
+
else if ('next' === buttonType) {
|
|
92
|
+
this._nextBtnClicked.next();
|
|
93
|
+
}
|
|
94
|
+
else if ('finish' === buttonType) {
|
|
95
|
+
this._finishBtnClicked.next();
|
|
96
|
+
}
|
|
97
|
+
else if ('danger' === buttonType) {
|
|
98
|
+
this._dangerBtnClicked.next();
|
|
99
|
+
}
|
|
100
|
+
else if ('cancel' === buttonType) {
|
|
101
|
+
this._cancelBtnClicked.next();
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
this._customBtnClicked.next(buttonType);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ButtonHubService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
108
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ButtonHubService }); }
|
|
109
|
+
}
|
|
110
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ButtonHubService, decorators: [{
|
|
111
|
+
type: Injectable
|
|
112
|
+
}] });
|
|
113
|
+
|
|
114
|
+
/*
|
|
115
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
116
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
117
|
+
* This software is released under MIT license.
|
|
118
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
119
|
+
*/
|
|
120
|
+
/**
|
|
121
|
+
* PageCollectionService manages the collection of pages assigned to the wizard and offers
|
|
122
|
+
* a number of functions useful across the wizards providers and subcomponents -- all related
|
|
123
|
+
* to essentially lookups on the collection of pages.
|
|
124
|
+
*
|
|
125
|
+
* The easiest way to access PageCollectionService is via the wizard. The
|
|
126
|
+
* following example would allow you to access your instance of the wizard from your host
|
|
127
|
+
* component and thereby access the page collection via YourHostComponent.wizard.pageCollection.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* <clr-wizard #wizard ...>
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* export class YourHostComponent {
|
|
134
|
+
* @ViewChild("wizard") wizard: Wizard;
|
|
135
|
+
* ...
|
|
136
|
+
* }
|
|
137
|
+
*
|
|
138
|
+
* The heart of the page collection is the query list of pages, which it is assigned as a
|
|
139
|
+
* reference to the Wizard.pages QueryList when the wizard is created.
|
|
140
|
+
*
|
|
141
|
+
*/
|
|
142
|
+
class PageCollectionService {
|
|
143
|
+
constructor() {
|
|
144
|
+
/**
|
|
145
|
+
*
|
|
146
|
+
* @memberof PageCollectionService
|
|
147
|
+
*/
|
|
148
|
+
this._pagesReset = new Subject();
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Converts the PageCollectionService.pages QueryList to an array and returns it.
|
|
152
|
+
*
|
|
153
|
+
* Useful for many instances when you would prefer a QueryList to act like an array.
|
|
154
|
+
*
|
|
155
|
+
* @memberof PageCollectionService
|
|
156
|
+
*/
|
|
157
|
+
get pagesAsArray() {
|
|
158
|
+
return this.pages ? this.pages.toArray() : [];
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Returns the length of the pages query list.
|
|
162
|
+
*
|
|
163
|
+
* @memberof PageCollectionService
|
|
164
|
+
*/
|
|
165
|
+
get pagesCount() {
|
|
166
|
+
return this.pages ? this.pages.length : 0;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Returns the next-to-last page in the query list of pages. Operates as a getter
|
|
170
|
+
* so that it isn't working with stale data.
|
|
171
|
+
*
|
|
172
|
+
* @memberof PageCollectionService
|
|
173
|
+
*/
|
|
174
|
+
get penultimatePage() {
|
|
175
|
+
const pageCount = this.pagesCount;
|
|
176
|
+
if (pageCount < 2) {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
return this.pagesAsArray[pageCount - 2];
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Returns the last page in the query list of pages. Operates as a getter
|
|
183
|
+
* so that it isn't working with stale data.
|
|
184
|
+
*
|
|
185
|
+
* @memberof PageCollectionService
|
|
186
|
+
*/
|
|
187
|
+
get lastPage() {
|
|
188
|
+
const pageCount = this.pagesCount;
|
|
189
|
+
if (pageCount < 1) {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
return this.pagesAsArray[pageCount - 1];
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Returns the first page in the query list of pages. Operates as a getter
|
|
196
|
+
* so that it isn't working with stale data.
|
|
197
|
+
*
|
|
198
|
+
* @memberof PageCollectionService
|
|
199
|
+
*/
|
|
200
|
+
get firstPage() {
|
|
201
|
+
if (!this.pagesCount) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
return this.pagesAsArray[0];
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* An observable that the navigation service listens to in order to know when
|
|
208
|
+
* the page collection completed states have been reset to false so that way it
|
|
209
|
+
* can also reset the navigation to make the first page in the page collection
|
|
210
|
+
* current/active.
|
|
211
|
+
*
|
|
212
|
+
* @memberof PageCollectionService
|
|
213
|
+
*/
|
|
214
|
+
get pagesReset() {
|
|
215
|
+
return this._pagesReset.asObservable();
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Used mostly internally, but accepts a string ID and returns a ClrWizardPage
|
|
219
|
+
* object that matches the ID passed. Note that IDs here should include the prefix
|
|
220
|
+
* "clr-wizard-page-".
|
|
221
|
+
*
|
|
222
|
+
* Returns the next-to-last page in the query list of pages. Operates as a getter
|
|
223
|
+
* so that it isn't working with stale data.
|
|
224
|
+
*
|
|
225
|
+
* @memberof PageCollectionService
|
|
226
|
+
*/
|
|
227
|
+
getPageById(id) {
|
|
228
|
+
const foundPages = this.pages.filter((page) => id === page.id);
|
|
229
|
+
return this.checkResults(foundPages, id);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Accepts s number as a parameter and treats that number as the index of the page
|
|
233
|
+
* you're looking for in the collection of pages. Returns a wizard page object.
|
|
234
|
+
*
|
|
235
|
+
* @memberof PageCollectionService
|
|
236
|
+
*/
|
|
237
|
+
getPageByIndex(index) {
|
|
238
|
+
const pageCount = this.pagesCount;
|
|
239
|
+
const pagesLastIndex = pageCount > 1 ? pageCount - 1 : 0;
|
|
240
|
+
if (index < 0) {
|
|
241
|
+
throw new Error('Cannot retrieve page with index of ' + index);
|
|
242
|
+
}
|
|
243
|
+
if (index > pagesLastIndex) {
|
|
244
|
+
throw new Error('Page index is greater than length of pages array.');
|
|
245
|
+
}
|
|
246
|
+
return this.pagesAsArray[index];
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Takes a wizard page object as a parameter and returns its index in the
|
|
250
|
+
* collection of pages.
|
|
251
|
+
*
|
|
252
|
+
* @memberof PageCollectionService
|
|
253
|
+
*/
|
|
254
|
+
getPageIndex(page) {
|
|
255
|
+
const index = this.pagesAsArray.indexOf(page);
|
|
256
|
+
if (index < 0) {
|
|
257
|
+
throw new Error('Requested page cannot be found in collection of pages.');
|
|
258
|
+
}
|
|
259
|
+
return index;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Accepts two numeric indexes and returns an array of wizard page objects that include
|
|
263
|
+
* all wizard pages in the page collection from the first index to the second.
|
|
264
|
+
*
|
|
265
|
+
* @memberof PageCollectionService
|
|
266
|
+
*/
|
|
267
|
+
pageRange(start, end) {
|
|
268
|
+
let pages = [];
|
|
269
|
+
if (start < 0 || end < 0) {
|
|
270
|
+
return [];
|
|
271
|
+
}
|
|
272
|
+
if (start === null || typeof start === 'undefined' || isNaN(start)) {
|
|
273
|
+
return [];
|
|
274
|
+
}
|
|
275
|
+
if (end === null || typeof end === 'undefined' || isNaN(end)) {
|
|
276
|
+
return [];
|
|
277
|
+
}
|
|
278
|
+
if (end > this.pagesCount) {
|
|
279
|
+
end = this.pagesCount;
|
|
280
|
+
}
|
|
281
|
+
pages = this.pagesAsArray;
|
|
282
|
+
if (end - start === 0) {
|
|
283
|
+
// just return the one page they want
|
|
284
|
+
return [this.getPageByIndex(start)];
|
|
285
|
+
}
|
|
286
|
+
// slice end does not include item referenced by end index, which is weird for users
|
|
287
|
+
// incrementing end index here to correct that so users and other methods
|
|
288
|
+
// don't have to think about it
|
|
289
|
+
end = end + 1;
|
|
290
|
+
// slice does not return the last one in the range but it does include the first one
|
|
291
|
+
// does not modify original array
|
|
292
|
+
return pages.slice(start, end);
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Accepts two wizard page objects and returns those page objects with all other page
|
|
296
|
+
* objects between them in the page collection. It doesn't care which page is ahead of the
|
|
297
|
+
* other in the parameters. It will be smart enough to figure that out on its own.
|
|
298
|
+
*
|
|
299
|
+
* @memberof PageCollectionService
|
|
300
|
+
*/
|
|
301
|
+
getPageRangeFromPages(page, otherPage) {
|
|
302
|
+
const pageIndex = this.getPageIndex(page);
|
|
303
|
+
const otherPageIndex = this.getPageIndex(otherPage);
|
|
304
|
+
let startIndex;
|
|
305
|
+
let endIndex;
|
|
306
|
+
if (pageIndex <= otherPageIndex) {
|
|
307
|
+
startIndex = pageIndex;
|
|
308
|
+
endIndex = otherPageIndex;
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
startIndex = otherPageIndex;
|
|
312
|
+
endIndex = pageIndex;
|
|
313
|
+
}
|
|
314
|
+
return this.pageRange(startIndex, endIndex);
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Takes a wizard page object as a parameter and returns the wizard page object of
|
|
318
|
+
* the page immediately before it in the page collection. Returns null if there is
|
|
319
|
+
* no page before the page it is passed.
|
|
320
|
+
*
|
|
321
|
+
* @memberof PageCollectionService
|
|
322
|
+
*/
|
|
323
|
+
getPreviousPage(page) {
|
|
324
|
+
const myPageIndex = this.getPageIndex(page);
|
|
325
|
+
const previousPageIndex = myPageIndex - 1;
|
|
326
|
+
if (previousPageIndex < 0) {
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
return this.getPageByIndex(previousPageIndex);
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Accepts a wizard page object as a parameter and returns a Boolean that says if
|
|
333
|
+
* the page you sent it is complete.
|
|
334
|
+
*
|
|
335
|
+
* @memberof PageCollectionService
|
|
336
|
+
*/
|
|
337
|
+
previousPageIsCompleted(page) {
|
|
338
|
+
if (!page) {
|
|
339
|
+
return false;
|
|
340
|
+
}
|
|
341
|
+
const previousPage = this.getPreviousPage(page);
|
|
342
|
+
if (null === previousPage) {
|
|
343
|
+
// page is the first page. no previous page.
|
|
344
|
+
return true;
|
|
345
|
+
}
|
|
346
|
+
return previousPage.completed;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Takes a wizard page object as a parameter and returns the wizard page object of
|
|
350
|
+
* the page immediately after it in the page collection. Returns null if there is
|
|
351
|
+
* no page after the page it is passed.
|
|
352
|
+
*
|
|
353
|
+
* @memberof PageCollectionService
|
|
354
|
+
*/
|
|
355
|
+
getNextPage(page) {
|
|
356
|
+
const myPageIndex = this.getPageIndex(page);
|
|
357
|
+
const nextPageIndex = myPageIndex + 1;
|
|
358
|
+
if (nextPageIndex >= this.pagesAsArray.length) {
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
return this.getPageByIndex(nextPageIndex);
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Takes a wizard page object as a parameter and generates a step item id from the
|
|
365
|
+
* page ID. Returns the generated step item ID as a string.
|
|
366
|
+
*
|
|
367
|
+
* @memberof PageCollectionService
|
|
368
|
+
*/
|
|
369
|
+
getStepItemIdForPage(page) {
|
|
370
|
+
const pageId = page.id;
|
|
371
|
+
const pageIdParts = pageId.split('-').reverse();
|
|
372
|
+
pageIdParts[1] = 'step';
|
|
373
|
+
return pageIdParts.reverse().join('-');
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Generally only used internally to mark that a specific page has been "committed".
|
|
377
|
+
* This involves marking the page complete and firing the ClrWizardPage.onCommit
|
|
378
|
+
* (clrWizardPageOnCommit) output. Takes the wizard page object that you intend to
|
|
379
|
+
* mark completed as a parameter.
|
|
380
|
+
*
|
|
381
|
+
* @memberof PageCollectionService
|
|
382
|
+
*/
|
|
383
|
+
commitPage(page) {
|
|
384
|
+
const pageHasOverrides = page.stopNext || page.preventDefault;
|
|
385
|
+
page.completed = true;
|
|
386
|
+
if (!pageHasOverrides) {
|
|
387
|
+
// prevent loop of event emission; alternate flows work off
|
|
388
|
+
// of event emitters this is how they break that cycle.
|
|
389
|
+
page.onCommit.emit(page.id);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Sets all completed states of the pages in the page collection to false and
|
|
394
|
+
* notifies the navigation service to likewise reset the navigation.
|
|
395
|
+
*
|
|
396
|
+
* @memberof PageCollectionService
|
|
397
|
+
*/
|
|
398
|
+
reset() {
|
|
399
|
+
this.pagesAsArray.forEach((page) => {
|
|
400
|
+
page.completed = false;
|
|
401
|
+
});
|
|
402
|
+
this._pagesReset.next(true);
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Rolls through all the pages in the page collection to make sure there are no
|
|
406
|
+
* incomplete pages sandwiched between completed pages in the workflow. Identifies
|
|
407
|
+
* the first incomplete page index and sets all pages behind it to a completed
|
|
408
|
+
* state of false.
|
|
409
|
+
*
|
|
410
|
+
* @memberof PageCollectionService
|
|
411
|
+
*/
|
|
412
|
+
updateCompletedStates() {
|
|
413
|
+
const firstIncompleteIndex = this.findFirstIncompletePageIndex();
|
|
414
|
+
if (firstIncompleteIndex === this.pagesAsArray.length - 1) {
|
|
415
|
+
// all complete no need to do anything
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
this.pagesAsArray.forEach((page, index) => {
|
|
419
|
+
if (index > firstIncompleteIndex) {
|
|
420
|
+
page.completed = false;
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Retrieves the index of the first incomplete page in the page collection.
|
|
426
|
+
*
|
|
427
|
+
* @memberof PageCollectionService
|
|
428
|
+
*/
|
|
429
|
+
findFirstIncompletePageIndex() {
|
|
430
|
+
let returnIndex = null;
|
|
431
|
+
this.pagesAsArray.forEach((page, index) => {
|
|
432
|
+
if (null === returnIndex && false === page.completed) {
|
|
433
|
+
returnIndex = index;
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
// fallthrough, all completed, return last page
|
|
437
|
+
if (null === returnIndex) {
|
|
438
|
+
returnIndex = this.pagesCount - 1;
|
|
439
|
+
}
|
|
440
|
+
return returnIndex;
|
|
441
|
+
}
|
|
442
|
+
findFirstIncompletePage() {
|
|
443
|
+
const myIncompleteIndex = this.findFirstIncompletePageIndex();
|
|
444
|
+
return this.pagesAsArray[myIncompleteIndex];
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Consolidates guard logic that prevents a couple of unfortunate edge cases with
|
|
448
|
+
* look ups on the collection of pages.
|
|
449
|
+
*
|
|
450
|
+
* @memberof PageCollectionService
|
|
451
|
+
*/
|
|
452
|
+
checkResults(results, requestedPageId) {
|
|
453
|
+
const foundPagesCount = results.length || 0;
|
|
454
|
+
if (foundPagesCount > 1) {
|
|
455
|
+
throw new Error('More than one page has the requested id ' + requestedPageId + '.');
|
|
456
|
+
}
|
|
457
|
+
else if (foundPagesCount < 1) {
|
|
458
|
+
throw new Error('No page can be found with the id ' + requestedPageId + '.');
|
|
459
|
+
}
|
|
460
|
+
else {
|
|
461
|
+
return results[0];
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: PageCollectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
465
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: PageCollectionService }); }
|
|
466
|
+
}
|
|
467
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: PageCollectionService, decorators: [{
|
|
468
|
+
type: Injectable
|
|
469
|
+
}] });
|
|
470
|
+
|
|
471
|
+
/*
|
|
472
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
473
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
474
|
+
* This software is released under MIT license.
|
|
475
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
476
|
+
*/
|
|
477
|
+
/**
|
|
478
|
+
* Performs navigation functions for a wizard and manages the current page. Presented as a
|
|
479
|
+
* separate service to encapsulate the behavior of navigating and completing the wizard so
|
|
480
|
+
* that it can be shared across the wizard and its sub-components.
|
|
481
|
+
*
|
|
482
|
+
* The easiest way to access the navigation service is there a reference on your wizard. The
|
|
483
|
+
* Following example would allow you to access your instance of the wizard from your host
|
|
484
|
+
* component and thereby access the navigation service via YourHostComponent.wizard.navService.
|
|
485
|
+
*
|
|
486
|
+
* @example
|
|
487
|
+
* <clr-wizard #wizard ...>
|
|
488
|
+
*
|
|
489
|
+
* @example
|
|
490
|
+
* export class YourHostComponent {
|
|
491
|
+
* @ViewChild("wizard") wizard: Wizard;
|
|
492
|
+
* ...
|
|
493
|
+
* }
|
|
494
|
+
*
|
|
495
|
+
*/
|
|
496
|
+
class WizardNavigationService {
|
|
497
|
+
/**
|
|
498
|
+
* Creates an instance of WizardNavigationService. Also sets up subscriptions
|
|
499
|
+
* that listen to the button service to determine when a button has been clicked
|
|
500
|
+
* in the wizard. Is also responsible for taking action when the page collection
|
|
501
|
+
* requests that navigation be reset to its pristine state.
|
|
502
|
+
*
|
|
503
|
+
* @memberof WizardNavigationService
|
|
504
|
+
*/
|
|
505
|
+
constructor(pageCollection, buttonService) {
|
|
506
|
+
this.pageCollection = pageCollection;
|
|
507
|
+
this.buttonService = buttonService;
|
|
508
|
+
/**
|
|
509
|
+
* A Boolean flag used by the ClrWizardPage to avoid a race condition when pages are
|
|
510
|
+
* loading and there is no current page defined.
|
|
511
|
+
*
|
|
512
|
+
* @memberof WizardNavigationService
|
|
513
|
+
*/
|
|
514
|
+
this.navServiceLoaded = false;
|
|
515
|
+
/**
|
|
516
|
+
* A boolean flag shared across the Wizard subcomponents that follows the value
|
|
517
|
+
* of the Wizard.forceForward (clrWizardForceForwardNavigation) input. When true,
|
|
518
|
+
* navigating backwards in the stepnav menu will reset any skipped pages' completed
|
|
519
|
+
* state to false.
|
|
520
|
+
*
|
|
521
|
+
* This is useful when a wizard executes validation on a page-by-page basis when
|
|
522
|
+
* the next button is clicked.
|
|
523
|
+
*
|
|
524
|
+
* @memberof WizardNavigationService
|
|
525
|
+
*/
|
|
526
|
+
this.forceForwardNavigation = false;
|
|
527
|
+
/**
|
|
528
|
+
* A boolean flag shared across the Wizard subcomponents that follows the value
|
|
529
|
+
* of the Wizard.stopCancel (clrWizardPreventDefaultCancel) input. When true, the cancel
|
|
530
|
+
* routine is subverted and must be reinstated in the host component calling Wizard.close()
|
|
531
|
+
* at some point.
|
|
532
|
+
*
|
|
533
|
+
* @memberof WizardNavigationService
|
|
534
|
+
*/
|
|
535
|
+
this.wizardHasAltCancel = false;
|
|
536
|
+
/**
|
|
537
|
+
* A boolean flag shared across the Wizard subcomponents that follows the value
|
|
538
|
+
* of the Wizard.stopNext (clrWizardPreventDefaultNext) input. When true, the next and finish
|
|
539
|
+
* routines are subverted and must be reinstated in the host component calling Wizard.next(),
|
|
540
|
+
* Wizard.forceNext(), Wizard.finish(), or Wizard.forceFinish().
|
|
541
|
+
*
|
|
542
|
+
* @memberof WizardNavigationService
|
|
543
|
+
*/
|
|
544
|
+
this.wizardHasAltNext = false;
|
|
545
|
+
/**
|
|
546
|
+
* A boolean flag shared across the Wizard subcomponents that follows the value
|
|
547
|
+
* of the Wizard.stopNavigation (clrWizardPreventNavigation) input. When true, all
|
|
548
|
+
* navigational elements in the wizard are disabled.
|
|
549
|
+
*
|
|
550
|
+
* This is intended to freeze the wizard in place. Events are not fired so this is
|
|
551
|
+
* not a way to implement alternate functionality for navigation.
|
|
552
|
+
*
|
|
553
|
+
* @memberof WizardNavigationService
|
|
554
|
+
*/
|
|
555
|
+
this.wizardStopNavigation = false;
|
|
556
|
+
/**
|
|
557
|
+
* A boolean flag shared with the stepnav items that prevents user clicks on
|
|
558
|
+
* stepnav items from navigating the wizard.
|
|
559
|
+
*
|
|
560
|
+
* @memberof WizardNavigationService
|
|
561
|
+
*/
|
|
562
|
+
this.wizardDisableStepnav = false;
|
|
563
|
+
/**
|
|
564
|
+
* The layout of the wizard stepnav, either 'vertical' or 'horizontal'.
|
|
565
|
+
*/
|
|
566
|
+
this.stepnavLayout = ClrWizardStepnavLayout.VERTICAL;
|
|
567
|
+
/**
|
|
568
|
+
*
|
|
569
|
+
* @memberof WizardNavigationService
|
|
570
|
+
*/
|
|
571
|
+
this._currentChanged = new Subject();
|
|
572
|
+
/**
|
|
573
|
+
* @memberof WizardNavigationService
|
|
574
|
+
*/
|
|
575
|
+
this._movedToNextPage = new Subject();
|
|
576
|
+
/**
|
|
577
|
+
* @memberof WizardNavigationService
|
|
578
|
+
*/
|
|
579
|
+
this._wizardFinished = new Subject();
|
|
580
|
+
/**
|
|
581
|
+
* @memberof WizardNavigationService
|
|
582
|
+
*/
|
|
583
|
+
this._movedToPreviousPage = new Subject();
|
|
584
|
+
/**
|
|
585
|
+
* @memberof WizardNavigationService
|
|
586
|
+
*/
|
|
587
|
+
this._cancelWizard = new Subject();
|
|
588
|
+
this.previousButtonSubscription = buttonService.previousBtnClicked.subscribe(() => {
|
|
589
|
+
const currentPage = this.currentPage;
|
|
590
|
+
if (this.currentPageIsFirst || currentPage.previousStepDisabled) {
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
currentPage.previousButtonClicked.emit(currentPage);
|
|
594
|
+
if (!currentPage.preventDefault) {
|
|
595
|
+
this.previous();
|
|
596
|
+
}
|
|
597
|
+
});
|
|
598
|
+
this.nextButtonSubscription = buttonService.nextBtnClicked.subscribe(() => {
|
|
599
|
+
this.checkAndCommitCurrentPage('next');
|
|
600
|
+
});
|
|
601
|
+
this.dangerButtonSubscription = buttonService.dangerBtnClicked.subscribe(() => {
|
|
602
|
+
this.checkAndCommitCurrentPage('danger');
|
|
603
|
+
});
|
|
604
|
+
this.finishButtonSubscription = buttonService.finishBtnClicked.subscribe(() => {
|
|
605
|
+
this.checkAndCommitCurrentPage('finish');
|
|
606
|
+
});
|
|
607
|
+
this.customButtonSubscription = buttonService.customBtnClicked.subscribe((type) => {
|
|
608
|
+
if (!this.wizardStopNavigation) {
|
|
609
|
+
this.currentPage.customButtonClicked.emit(type);
|
|
610
|
+
}
|
|
611
|
+
});
|
|
612
|
+
this.cancelButtonSubscription = buttonService.cancelBtnClicked.subscribe(() => {
|
|
613
|
+
if (this.wizardStopNavigation) {
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
if (this.currentPage.preventDefault) {
|
|
617
|
+
this.currentPage.pageOnCancel.emit(this.currentPage);
|
|
618
|
+
}
|
|
619
|
+
else {
|
|
620
|
+
this.cancel();
|
|
621
|
+
}
|
|
622
|
+
});
|
|
623
|
+
this.pagesResetSubscription = pageCollection.pagesReset.subscribe(() => {
|
|
624
|
+
this.setFirstPageCurrent();
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* An Observable that is predominantly used amongst the subcomponents and services
|
|
629
|
+
* of the wizard. It is recommended that users listen to the ClrWizardPage.onLoad
|
|
630
|
+
* (clrWizardPageOnLoad) output instead of this Observable.
|
|
631
|
+
*
|
|
632
|
+
* @memberof WizardNavigationService
|
|
633
|
+
*/
|
|
634
|
+
get currentPageChange() {
|
|
635
|
+
return this._currentChanged.asObservable();
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* @memberof WizardNavigationService
|
|
639
|
+
*/
|
|
640
|
+
get currentPageTitle() {
|
|
641
|
+
// when the querylist of pages is empty. this is the first place it fails...
|
|
642
|
+
if (!this.currentPage) {
|
|
643
|
+
return null;
|
|
644
|
+
}
|
|
645
|
+
return this.currentPage.title;
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Returns a Boolean that tells you whether or not the current page is the first
|
|
649
|
+
* page in the Wizard.
|
|
650
|
+
*
|
|
651
|
+
* This is helpful for determining whether a page is navigable.
|
|
652
|
+
*
|
|
653
|
+
* @memberof WizardNavigationService
|
|
654
|
+
*/
|
|
655
|
+
get currentPageIsFirst() {
|
|
656
|
+
return this.pageCollection.firstPage === this.currentPage;
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Returns a Boolean that tells you whether or not the current page is the
|
|
660
|
+
* last page in the Wizard.
|
|
661
|
+
*
|
|
662
|
+
* This is used to determine which buttons should display in the wizard footer.
|
|
663
|
+
*
|
|
664
|
+
* @memberof WizardNavigationService
|
|
665
|
+
*/
|
|
666
|
+
get currentPageIsLast() {
|
|
667
|
+
return this.pageCollection.lastPage === this.currentPage;
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* Returns the ClrWizardPage object of the current page or null.
|
|
671
|
+
*
|
|
672
|
+
* @memberof WizardNavigationService
|
|
673
|
+
*/
|
|
674
|
+
get currentPage() {
|
|
675
|
+
if (!this._currentPage) {
|
|
676
|
+
return null;
|
|
677
|
+
}
|
|
678
|
+
return this._currentPage;
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Accepts a ClrWizardPage object, since that object to be the current/active
|
|
682
|
+
* page in the wizard, and emits the ClrWizardPage.onLoad (clrWizardPageOnLoad)
|
|
683
|
+
* event for that page.
|
|
684
|
+
*
|
|
685
|
+
* Note that all of this work is bypassed if the ClrWizardPage object is already
|
|
686
|
+
* the current page.
|
|
687
|
+
*
|
|
688
|
+
* @memberof WizardNavigationService
|
|
689
|
+
*/
|
|
690
|
+
set currentPage(page) {
|
|
691
|
+
if (this._currentPage !== page && !this.wizardStopNavigation) {
|
|
692
|
+
this._currentPage = page;
|
|
693
|
+
page.onLoad.emit(page.id);
|
|
694
|
+
this._currentChanged.next(page);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
/**
|
|
698
|
+
* An observable used internally to alert the wizard that forward navigation
|
|
699
|
+
* has occurred. It is recommended that you use the Wizard.onMoveNext
|
|
700
|
+
* (clrWizardOnNext) output instead of this one.
|
|
701
|
+
*
|
|
702
|
+
* @memberof WizardNavigationService
|
|
703
|
+
*/
|
|
704
|
+
get movedToNextPage() {
|
|
705
|
+
return this._movedToNextPage.asObservable();
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* An observable used internally to alert the wizard that the nav service
|
|
709
|
+
* has approved completion of the wizard.
|
|
710
|
+
*
|
|
711
|
+
* It is recommended that you use the Wizard.wizardFinished (clrWizardOnFinish)
|
|
712
|
+
* output instead of this one.
|
|
713
|
+
*
|
|
714
|
+
* @memberof WizardNavigationService
|
|
715
|
+
*/
|
|
716
|
+
get wizardFinished() {
|
|
717
|
+
return this._wizardFinished.asObservable();
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Notifies the wizard when backwards navigation has occurred via the
|
|
721
|
+
* previous button.
|
|
722
|
+
*
|
|
723
|
+
* @memberof WizardNavigationService
|
|
724
|
+
*/
|
|
725
|
+
get movedToPreviousPage() {
|
|
726
|
+
return this._movedToPreviousPage.asObservable();
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* Notifies the wizard that a user is trying to cancel it.
|
|
730
|
+
*
|
|
731
|
+
* @memberof WizardNavigationService
|
|
732
|
+
*/
|
|
733
|
+
get notifyWizardCancel() {
|
|
734
|
+
return this._cancelWizard.asObservable();
|
|
735
|
+
}
|
|
736
|
+
/**
|
|
737
|
+
*
|
|
738
|
+
* @memberof WizardNavigationService
|
|
739
|
+
*/
|
|
740
|
+
ngOnDestroy() {
|
|
741
|
+
this.previousButtonSubscription.unsubscribe();
|
|
742
|
+
this.nextButtonSubscription.unsubscribe();
|
|
743
|
+
this.dangerButtonSubscription.unsubscribe();
|
|
744
|
+
this.finishButtonSubscription.unsubscribe();
|
|
745
|
+
this.customButtonSubscription.unsubscribe();
|
|
746
|
+
this.cancelButtonSubscription.unsubscribe();
|
|
747
|
+
this.pagesResetSubscription.unsubscribe();
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* This is a public function that can be used to programmatically advance
|
|
751
|
+
* the user to the next page.
|
|
752
|
+
*
|
|
753
|
+
* When invoked, this method will move the wizard to the next page after
|
|
754
|
+
* successful validation. Note that this method goes through all checks
|
|
755
|
+
* and event emissions as if Wizard.next(false) had been called.
|
|
756
|
+
*
|
|
757
|
+
* In most cases, it makes more sense to use Wizard.next(false).
|
|
758
|
+
*
|
|
759
|
+
* @memberof WizardNavigationService
|
|
760
|
+
*/
|
|
761
|
+
next() {
|
|
762
|
+
if (this.currentPageIsLast) {
|
|
763
|
+
this.checkAndCommitCurrentPage('finish');
|
|
764
|
+
}
|
|
765
|
+
else {
|
|
766
|
+
this.checkAndCommitCurrentPage('next');
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* Bypasses checks and most event emissions to force a page to navigate forward.
|
|
771
|
+
*
|
|
772
|
+
* Comparable to calling Wizard.next() or Wizard.forceNext().
|
|
773
|
+
*
|
|
774
|
+
* @memberof WizardNavigationService
|
|
775
|
+
*/
|
|
776
|
+
forceNext() {
|
|
777
|
+
const currentPage = this.currentPage;
|
|
778
|
+
const nextPage = this.pageCollection.getNextPage(currentPage);
|
|
779
|
+
// catch errant null or undefineds that creep in
|
|
780
|
+
if (!nextPage) {
|
|
781
|
+
throw new Error('The wizard has no next page to go to.');
|
|
782
|
+
}
|
|
783
|
+
if (this.wizardStopNavigation) {
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
if (!currentPage.completed) {
|
|
787
|
+
// this is a state that alt next flows can get themselves in...
|
|
788
|
+
this.pageCollection.commitPage(currentPage);
|
|
789
|
+
}
|
|
790
|
+
this.currentPage = nextPage;
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* Accepts a button/action type as a parameter. Encapsulates all logic for
|
|
794
|
+
* event emissions, state of the current page, and wizard and page level overrides.
|
|
795
|
+
*
|
|
796
|
+
* Avoid calling this function directly unless you really know what you're doing.
|
|
797
|
+
*
|
|
798
|
+
* @memberof WizardNavigationService
|
|
799
|
+
*/
|
|
800
|
+
checkAndCommitCurrentPage(buttonType) {
|
|
801
|
+
const currentPage = this.currentPage;
|
|
802
|
+
if (!currentPage.readyToComplete || this.wizardStopNavigation) {
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
805
|
+
const iAmTheLastPage = this.currentPageIsLast;
|
|
806
|
+
const isNext = buttonType === 'next';
|
|
807
|
+
const isDanger = buttonType === 'danger';
|
|
808
|
+
const isDangerNext = isDanger && !iAmTheLastPage;
|
|
809
|
+
const isDangerFinish = isDanger && iAmTheLastPage;
|
|
810
|
+
const isFinish = buttonType === 'finish' || isDangerFinish;
|
|
811
|
+
if (isFinish && !iAmTheLastPage) {
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
currentPage.primaryButtonClicked.emit(buttonType);
|
|
815
|
+
if (isFinish) {
|
|
816
|
+
currentPage.finishButtonClicked.emit(currentPage);
|
|
817
|
+
}
|
|
818
|
+
else if (isDanger) {
|
|
819
|
+
currentPage.dangerButtonClicked.emit();
|
|
820
|
+
}
|
|
821
|
+
else if (isNext) {
|
|
822
|
+
currentPage.nextButtonClicked.emit();
|
|
823
|
+
}
|
|
824
|
+
if (currentPage.stopNext || currentPage.preventDefault) {
|
|
825
|
+
currentPage.onCommit.emit(currentPage.id);
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
// order is very important with these emitters!
|
|
829
|
+
if (isFinish) {
|
|
830
|
+
// mark page as complete
|
|
831
|
+
if (!this.wizardHasAltNext) {
|
|
832
|
+
this.pageCollection.commitPage(currentPage);
|
|
833
|
+
}
|
|
834
|
+
this._wizardFinished.next();
|
|
835
|
+
}
|
|
836
|
+
if (this.wizardHasAltNext) {
|
|
837
|
+
this.pageCollection.commitPage(currentPage);
|
|
838
|
+
if (isNext || isDangerNext) {
|
|
839
|
+
this._movedToNextPage.next(true);
|
|
840
|
+
}
|
|
841
|
+
// jump out here, no matter what type we're looking at
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
if (isNext || isDangerNext) {
|
|
845
|
+
this.forceNext();
|
|
846
|
+
}
|
|
847
|
+
if (!this.wizardHasAltNext && !this.wizardStopNavigation) {
|
|
848
|
+
this._movedToNextPage.next(true);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
/**
|
|
852
|
+
* This is a public function that can be used to programmatically conclude
|
|
853
|
+
* the wizard.
|
|
854
|
+
*
|
|
855
|
+
* When invoked, this method will initiate the work involved with finalizing
|
|
856
|
+
* and finishing the wizard workflow. Note that this method goes through all
|
|
857
|
+
* checks and event emissions as if Wizard.finish(false) had been called.
|
|
858
|
+
*
|
|
859
|
+
* In most cases, it makes more sense to use Wizard.finish(false).
|
|
860
|
+
*
|
|
861
|
+
* @memberof WizardNavigationService
|
|
862
|
+
*/
|
|
863
|
+
finish() {
|
|
864
|
+
this.checkAndCommitCurrentPage('finish');
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Programmatically moves the wizard to the page before the current page.
|
|
868
|
+
*
|
|
869
|
+
* In most instances, it makes more sense to call Wizard.previous()
|
|
870
|
+
* which does the same thing.
|
|
871
|
+
*
|
|
872
|
+
* @memberof WizardNavigationService
|
|
873
|
+
*/
|
|
874
|
+
previous() {
|
|
875
|
+
if (this.currentPageIsFirst || this.wizardStopNavigation) {
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
const previousPage = this.pageCollection.getPreviousPage(this.currentPage);
|
|
879
|
+
if (!previousPage) {
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
this._movedToPreviousPage.next(true);
|
|
883
|
+
if (this.forceForwardNavigation) {
|
|
884
|
+
this.currentPage.completed = false;
|
|
885
|
+
}
|
|
886
|
+
this.currentPage = previousPage;
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* Allows a hook into the cancel workflow of the wizard from the nav service. Note that
|
|
890
|
+
* this route goes through all checks and event emissions as if a cancel button had
|
|
891
|
+
* been clicked.
|
|
892
|
+
*
|
|
893
|
+
* In most cases, users looking for a hook into the cancel routine are actually looking
|
|
894
|
+
* for a way to close the wizard from their host component because they have prevented
|
|
895
|
+
* the default cancel action.
|
|
896
|
+
*
|
|
897
|
+
* In this instance, it is recommended that you use Wizard.close() to avoid any event
|
|
898
|
+
* emission loop resulting from an event handler calling back into routine that will
|
|
899
|
+
* again evoke the events it handles.
|
|
900
|
+
*
|
|
901
|
+
* @memberof WizardNavigationService
|
|
902
|
+
*/
|
|
903
|
+
cancel() {
|
|
904
|
+
this._cancelWizard.next();
|
|
905
|
+
}
|
|
906
|
+
/**
|
|
907
|
+
* Performs all required checks to determine if a user can navigate to a page. Checking at each
|
|
908
|
+
* point if a page is navigable -- completed where the page immediately after the last completed
|
|
909
|
+
* page.
|
|
910
|
+
*
|
|
911
|
+
* Takes two parameters. The first one must be either the ClrWizardPage object or the ID of the
|
|
912
|
+
* ClrWizardPage object that you want to make the current page.
|
|
913
|
+
*
|
|
914
|
+
* The second parameter is optional and is a Boolean flag for "lazy completion". What this means
|
|
915
|
+
* is the Wizard will mark all pages between the current page and the page you want to navigate
|
|
916
|
+
* to as completed. This is useful for informational wizards that do not require user action,
|
|
917
|
+
* allowing an easy means for users to jump ahead.
|
|
918
|
+
*
|
|
919
|
+
* To avoid checks on navigation, use ClrWizardPage.makeCurrent() instead.
|
|
920
|
+
*
|
|
921
|
+
* @memberof WizardNavigationService
|
|
922
|
+
*/
|
|
923
|
+
goTo(pageToGoToOrId, lazyComplete = false) {
|
|
924
|
+
const myPages = this.pageCollection;
|
|
925
|
+
const pageToGoTo = typeof pageToGoToOrId === 'string' ? myPages.getPageById(pageToGoToOrId) : pageToGoToOrId;
|
|
926
|
+
const currentPage = this.currentPage;
|
|
927
|
+
// no point in going to the current page. you're there already!
|
|
928
|
+
// also hard block on any navigation when stopNavigation is true
|
|
929
|
+
if (pageToGoTo === currentPage || this.wizardStopNavigation) {
|
|
930
|
+
return;
|
|
931
|
+
}
|
|
932
|
+
const currentPageIndex = myPages.getPageIndex(currentPage);
|
|
933
|
+
const goToPageIndex = myPages.getPageIndex(pageToGoTo);
|
|
934
|
+
const goingForward = goToPageIndex > currentPageIndex;
|
|
935
|
+
const pagesToCheck = myPages.getPageRangeFromPages(this.currentPage, pageToGoTo);
|
|
936
|
+
const okayToMove = lazyComplete || this.canGoTo(pagesToCheck);
|
|
937
|
+
if (!okayToMove) {
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
if (goingForward && lazyComplete) {
|
|
941
|
+
pagesToCheck.forEach((page) => {
|
|
942
|
+
if (page !== pageToGoTo) {
|
|
943
|
+
page.completed = true;
|
|
944
|
+
}
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
else if (!goingForward && this.forceForwardNavigation) {
|
|
948
|
+
pagesToCheck.forEach((page) => {
|
|
949
|
+
page.completed = false;
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
this.currentPage = pageToGoTo;
|
|
953
|
+
}
|
|
954
|
+
/**
|
|
955
|
+
* Accepts a range of ClrWizardPage objects as a parameter. Performs the work of checking
|
|
956
|
+
* those objects to determine if navigation can be accomplished.
|
|
957
|
+
*
|
|
958
|
+
* @memberof WizardNavigationService
|
|
959
|
+
*/
|
|
960
|
+
canGoTo(pagesToCheck) {
|
|
961
|
+
let okayToMove = true;
|
|
962
|
+
const myPages = this.pageCollection;
|
|
963
|
+
// previous page can be important when moving because if it's completed it
|
|
964
|
+
// allows us to move to the page even if it's incomplete...
|
|
965
|
+
let previousPagePasses;
|
|
966
|
+
if (!pagesToCheck || pagesToCheck.length < 1) {
|
|
967
|
+
return false;
|
|
968
|
+
}
|
|
969
|
+
pagesToCheck.forEach((page) => {
|
|
970
|
+
if (!okayToMove) {
|
|
971
|
+
return;
|
|
972
|
+
}
|
|
973
|
+
if (page.completed) {
|
|
974
|
+
// default is true. just jump out instead of complicating it.
|
|
975
|
+
return;
|
|
976
|
+
}
|
|
977
|
+
// so we know our page is not completed...
|
|
978
|
+
const previousPage = myPages.getPageIndex(page) > 0 ? myPages.getPreviousPage(page) : null;
|
|
979
|
+
previousPagePasses = previousPage === null || previousPage.completed === true;
|
|
980
|
+
// we are false if not the current page AND previous page is not completed
|
|
981
|
+
// (but must have a previous page)
|
|
982
|
+
if (!page.current && !previousPagePasses) {
|
|
983
|
+
okayToMove = false;
|
|
984
|
+
}
|
|
985
|
+
// falls through to true as default
|
|
986
|
+
});
|
|
987
|
+
return okayToMove;
|
|
988
|
+
}
|
|
989
|
+
/**
|
|
990
|
+
* Looks through the collection of pages to find the first one that is incomplete
|
|
991
|
+
* and makes that page the current/active page.
|
|
992
|
+
*
|
|
993
|
+
* @memberof WizardNavigationService
|
|
994
|
+
*/
|
|
995
|
+
setLastEnabledPageCurrent() {
|
|
996
|
+
const allPages = this.pageCollection.pagesAsArray;
|
|
997
|
+
let lastCompletedPageIndex = null;
|
|
998
|
+
allPages.forEach((page, index) => {
|
|
999
|
+
if (page.completed) {
|
|
1000
|
+
lastCompletedPageIndex = index;
|
|
1001
|
+
}
|
|
1002
|
+
});
|
|
1003
|
+
if (lastCompletedPageIndex === null) {
|
|
1004
|
+
// always is at least the first item...
|
|
1005
|
+
lastCompletedPageIndex = 0;
|
|
1006
|
+
}
|
|
1007
|
+
else if (lastCompletedPageIndex + 1 < allPages.length) {
|
|
1008
|
+
lastCompletedPageIndex = lastCompletedPageIndex + 1;
|
|
1009
|
+
}
|
|
1010
|
+
this.currentPage = allPages[lastCompletedPageIndex];
|
|
1011
|
+
}
|
|
1012
|
+
/**
|
|
1013
|
+
* Finds the first page in the collection of pages and makes that page the
|
|
1014
|
+
* current/active page.
|
|
1015
|
+
*
|
|
1016
|
+
* @memberof WizardNavigationService
|
|
1017
|
+
*/
|
|
1018
|
+
setFirstPageCurrent() {
|
|
1019
|
+
this.currentPage = this.pageCollection.pagesAsArray[0];
|
|
1020
|
+
}
|
|
1021
|
+
/**
|
|
1022
|
+
* Updates the stepnav on the left side of the wizard when pages are dynamically
|
|
1023
|
+
* added or removed from the collection of pages.
|
|
1024
|
+
*
|
|
1025
|
+
* @memberof WizardNavigationService
|
|
1026
|
+
*/
|
|
1027
|
+
updateNavigation() {
|
|
1028
|
+
let toSetCurrent;
|
|
1029
|
+
this.pageCollection.updateCompletedStates();
|
|
1030
|
+
const currentPageRemoved = this.pageCollection.pagesAsArray.indexOf(this.currentPage) < 0;
|
|
1031
|
+
if (currentPageRemoved) {
|
|
1032
|
+
toSetCurrent = this.pageCollection.findFirstIncompletePage();
|
|
1033
|
+
this.currentPage = toSetCurrent;
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: WizardNavigationService, deps: [{ token: PageCollectionService }, { token: ButtonHubService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1037
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: WizardNavigationService }); }
|
|
1038
|
+
}
|
|
1039
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: WizardNavigationService, decorators: [{
|
|
1040
|
+
type: Injectable
|
|
1041
|
+
}], ctorParameters: () => [{ type: PageCollectionService }, { type: ButtonHubService }] });
|
|
1042
|
+
|
|
1043
|
+
/*
|
|
1044
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
1045
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
1046
|
+
* This software is released under MIT license.
|
|
1047
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
1048
|
+
*/
|
|
1049
|
+
class HeaderActionService {
|
|
1050
|
+
constructor(navService) {
|
|
1051
|
+
this.navService = navService;
|
|
1052
|
+
}
|
|
1053
|
+
get wizardHasHeaderActions() {
|
|
1054
|
+
const wizardHdrActions = this.wizardHeaderActions;
|
|
1055
|
+
if (!wizardHdrActions) {
|
|
1056
|
+
return false;
|
|
1057
|
+
}
|
|
1058
|
+
return wizardHdrActions.toArray().length > 0;
|
|
1059
|
+
}
|
|
1060
|
+
get currentPageHasHeaderActions() {
|
|
1061
|
+
return this.navService.currentPage ? this.navService.currentPage.hasHeaderActions : false;
|
|
1062
|
+
}
|
|
1063
|
+
get showWizardHeaderActions() {
|
|
1064
|
+
return !this.currentPageHasHeaderActions && this.wizardHasHeaderActions;
|
|
1065
|
+
}
|
|
1066
|
+
get displayHeaderActionsWrapper() {
|
|
1067
|
+
return this.currentPageHasHeaderActions || this.wizardHasHeaderActions;
|
|
1068
|
+
}
|
|
1069
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: HeaderActionService, deps: [{ token: WizardNavigationService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1070
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: HeaderActionService }); }
|
|
1071
|
+
}
|
|
1072
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: HeaderActionService, decorators: [{
|
|
1073
|
+
type: Injectable
|
|
1074
|
+
}], ctorParameters: () => [{ type: WizardNavigationService }] });
|
|
1075
|
+
|
|
1076
|
+
/*
|
|
1077
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
1078
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
1079
|
+
* This software is released under MIT license.
|
|
1080
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
1081
|
+
*/
|
|
1082
|
+
const DEFAULT_BUTTON_TYPES = {
|
|
1083
|
+
cancel: 'cancel',
|
|
1084
|
+
previous: 'previous',
|
|
1085
|
+
next: 'next',
|
|
1086
|
+
finish: 'finish',
|
|
1087
|
+
danger: 'danger',
|
|
1088
|
+
};
|
|
1089
|
+
const CUSTOM_BUTTON_TYPES = {
|
|
1090
|
+
cancel: 'custom-cancel',
|
|
1091
|
+
previous: 'custom-previous',
|
|
1092
|
+
next: 'custom-next',
|
|
1093
|
+
finish: 'custom-finish',
|
|
1094
|
+
danger: 'custom-danger',
|
|
1095
|
+
};
|
|
1096
|
+
class ClrWizardButton {
|
|
1097
|
+
constructor(navService, buttonService) {
|
|
1098
|
+
this.navService = navService;
|
|
1099
|
+
this.buttonService = buttonService;
|
|
1100
|
+
this.type = '';
|
|
1101
|
+
this.disabled = false;
|
|
1102
|
+
this.hidden = false;
|
|
1103
|
+
// EventEmitter which is emitted when a button is clicked.
|
|
1104
|
+
this.wasClicked = new EventEmitter(false);
|
|
1105
|
+
}
|
|
1106
|
+
get isCancel() {
|
|
1107
|
+
return this.checkDefaultAndCustomType(this.type, 'cancel');
|
|
1108
|
+
}
|
|
1109
|
+
get isNext() {
|
|
1110
|
+
return this.checkDefaultAndCustomType(this.type, 'next');
|
|
1111
|
+
}
|
|
1112
|
+
get isPrevious() {
|
|
1113
|
+
return this.checkDefaultAndCustomType(this.type, 'previous');
|
|
1114
|
+
}
|
|
1115
|
+
get isFinish() {
|
|
1116
|
+
return this.checkDefaultAndCustomType(this.type, 'finish');
|
|
1117
|
+
}
|
|
1118
|
+
get isDanger() {
|
|
1119
|
+
return this.checkDefaultAndCustomType(this.type, 'danger');
|
|
1120
|
+
}
|
|
1121
|
+
get isPrimaryAction() {
|
|
1122
|
+
return this.isNext || this.isDanger || this.isFinish;
|
|
1123
|
+
}
|
|
1124
|
+
get _disabledAttribute() {
|
|
1125
|
+
if (this.isDisabled) {
|
|
1126
|
+
return '';
|
|
1127
|
+
}
|
|
1128
|
+
return null;
|
|
1129
|
+
}
|
|
1130
|
+
get isDisabled() {
|
|
1131
|
+
// dealing with negatives here. cognitively easier to think of it like this...
|
|
1132
|
+
const disabled = true;
|
|
1133
|
+
const nav = this.navService;
|
|
1134
|
+
const page = this.navService.currentPage;
|
|
1135
|
+
// Ensure we don't change the response until buttons are ready to avoid chocolate
|
|
1136
|
+
if (!this.buttonService.buttonsReady) {
|
|
1137
|
+
return !disabled;
|
|
1138
|
+
}
|
|
1139
|
+
if (this.disabled || nav.wizardStopNavigation || !page) {
|
|
1140
|
+
return true;
|
|
1141
|
+
}
|
|
1142
|
+
if (this.isCancel) {
|
|
1143
|
+
return !disabled;
|
|
1144
|
+
}
|
|
1145
|
+
if (this.isPrevious && (nav.currentPageIsFirst || page.previousStepDisabled)) {
|
|
1146
|
+
return disabled;
|
|
1147
|
+
}
|
|
1148
|
+
if (this.isDanger && !page.readyToComplete) {
|
|
1149
|
+
return disabled;
|
|
1150
|
+
}
|
|
1151
|
+
if (this.isNext && (nav.currentPageIsLast || !page.readyToComplete)) {
|
|
1152
|
+
return disabled;
|
|
1153
|
+
}
|
|
1154
|
+
if (this.isFinish && (!nav.currentPageIsLast || !page.readyToComplete)) {
|
|
1155
|
+
return disabled;
|
|
1156
|
+
}
|
|
1157
|
+
return !disabled;
|
|
1158
|
+
}
|
|
1159
|
+
get isHidden() {
|
|
1160
|
+
// dealing with negatives here. cognitively easier to think of it like this...
|
|
1161
|
+
const hidden = true;
|
|
1162
|
+
const nav = this.navService;
|
|
1163
|
+
// Ensure we don't change the response until buttons are ready to avoid chocolate
|
|
1164
|
+
if (!this.buttonService.buttonsReady) {
|
|
1165
|
+
return !hidden;
|
|
1166
|
+
}
|
|
1167
|
+
if (this.hidden) {
|
|
1168
|
+
return true;
|
|
1169
|
+
}
|
|
1170
|
+
if (this.isCancel) {
|
|
1171
|
+
return !hidden;
|
|
1172
|
+
}
|
|
1173
|
+
if (this.isPrevious && nav.currentPageIsFirst) {
|
|
1174
|
+
return hidden;
|
|
1175
|
+
}
|
|
1176
|
+
if (this.isNext && nav.currentPageIsLast) {
|
|
1177
|
+
return hidden;
|
|
1178
|
+
}
|
|
1179
|
+
if (this.isFinish && !nav.currentPageIsLast) {
|
|
1180
|
+
return hidden;
|
|
1181
|
+
}
|
|
1182
|
+
return !hidden;
|
|
1183
|
+
}
|
|
1184
|
+
click() {
|
|
1185
|
+
if (this.isDisabled) {
|
|
1186
|
+
return;
|
|
1187
|
+
}
|
|
1188
|
+
this.wasClicked.emit(this.type);
|
|
1189
|
+
this.buttonService.buttonClicked(this.type);
|
|
1190
|
+
}
|
|
1191
|
+
checkDefaultAndCustomType(valueToCheck = '', typeToLookUp) {
|
|
1192
|
+
if (DEFAULT_BUTTON_TYPES[typeToLookUp] === valueToCheck) {
|
|
1193
|
+
return true;
|
|
1194
|
+
}
|
|
1195
|
+
if (CUSTOM_BUTTON_TYPES[typeToLookUp] === valueToCheck) {
|
|
1196
|
+
return true;
|
|
1197
|
+
}
|
|
1198
|
+
return false;
|
|
1199
|
+
}
|
|
1200
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardButton, deps: [{ token: WizardNavigationService }, { token: ButtonHubService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1201
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.3", type: ClrWizardButton, isStandalone: false, selector: "clr-wizard-button", inputs: { type: "type", disabled: ["clrWizardButtonDisabled", "disabled"], hidden: ["clrWizardButtonHidden", "hidden"] }, outputs: { wasClicked: "clrWizardButtonClicked" }, host: { properties: { "attr.aria-hidden": "isHidden" }, classAttribute: "clr-wizard-btn-wrapper" }, ngImport: i0, template: `
|
|
1202
|
+
<button
|
|
1203
|
+
type="button"
|
|
1204
|
+
class="btn clr-wizard-btn"
|
|
1205
|
+
[class.btn-link]="isCancel"
|
|
1206
|
+
[class.clr-wizard-btn--tertiary]="isCancel"
|
|
1207
|
+
[class.btn-outline]="isPrevious"
|
|
1208
|
+
[class.clr-wizard-btn--secondary]="isPrevious"
|
|
1209
|
+
[class.btn-primary]="isPrimaryAction"
|
|
1210
|
+
[class.clr-wizard-btn--primary]="isPrimaryAction"
|
|
1211
|
+
[class.btn-success]="isFinish"
|
|
1212
|
+
[class.btn-danger]="isDanger"
|
|
1213
|
+
[class.disabled]="isDisabled"
|
|
1214
|
+
[attr.disabled]="_disabledAttribute"
|
|
1215
|
+
(click)="click()"
|
|
1216
|
+
>
|
|
1217
|
+
<ng-content></ng-content>
|
|
1218
|
+
</button>
|
|
1219
|
+
`, isInline: true }); }
|
|
1220
|
+
}
|
|
1221
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardButton, decorators: [{
|
|
1222
|
+
type: Component,
|
|
1223
|
+
args: [{
|
|
1224
|
+
selector: 'clr-wizard-button',
|
|
1225
|
+
template: `
|
|
1226
|
+
<button
|
|
1227
|
+
type="button"
|
|
1228
|
+
class="btn clr-wizard-btn"
|
|
1229
|
+
[class.btn-link]="isCancel"
|
|
1230
|
+
[class.clr-wizard-btn--tertiary]="isCancel"
|
|
1231
|
+
[class.btn-outline]="isPrevious"
|
|
1232
|
+
[class.clr-wizard-btn--secondary]="isPrevious"
|
|
1233
|
+
[class.btn-primary]="isPrimaryAction"
|
|
1234
|
+
[class.clr-wizard-btn--primary]="isPrimaryAction"
|
|
1235
|
+
[class.btn-success]="isFinish"
|
|
1236
|
+
[class.btn-danger]="isDanger"
|
|
1237
|
+
[class.disabled]="isDisabled"
|
|
1238
|
+
[attr.disabled]="_disabledAttribute"
|
|
1239
|
+
(click)="click()"
|
|
1240
|
+
>
|
|
1241
|
+
<ng-content></ng-content>
|
|
1242
|
+
</button>
|
|
1243
|
+
`,
|
|
1244
|
+
host: { class: 'clr-wizard-btn-wrapper', '[attr.aria-hidden]': 'isHidden' },
|
|
1245
|
+
standalone: false,
|
|
1246
|
+
}]
|
|
1247
|
+
}], ctorParameters: () => [{ type: WizardNavigationService }, { type: ButtonHubService }], propDecorators: { type: [{
|
|
1248
|
+
type: Input,
|
|
1249
|
+
args: ['type']
|
|
1250
|
+
}], disabled: [{
|
|
1251
|
+
type: Input,
|
|
1252
|
+
args: ['clrWizardButtonDisabled']
|
|
1253
|
+
}], hidden: [{
|
|
1254
|
+
type: Input,
|
|
1255
|
+
args: ['clrWizardButtonHidden']
|
|
1256
|
+
}], wasClicked: [{
|
|
1257
|
+
type: Output,
|
|
1258
|
+
args: ['clrWizardButtonClicked']
|
|
1259
|
+
}] } });
|
|
1260
|
+
|
|
1261
|
+
/*
|
|
1262
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
1263
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
1264
|
+
* This software is released under MIT license.
|
|
1265
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
1266
|
+
*/
|
|
1267
|
+
let wizardHeaderActionIndex = 0;
|
|
1268
|
+
class ClrWizardHeaderAction {
|
|
1269
|
+
constructor() {
|
|
1270
|
+
// title is explanatory text added to the header action
|
|
1271
|
+
this.title = '';
|
|
1272
|
+
// If our host has an ID attribute, we use this instead of our index.
|
|
1273
|
+
this._id = (wizardHeaderActionIndex++).toString();
|
|
1274
|
+
this.disabled = false;
|
|
1275
|
+
this.headerActionClicked = new EventEmitter(false);
|
|
1276
|
+
}
|
|
1277
|
+
get id() {
|
|
1278
|
+
return `clr-wizard-header-action-${this._id}`;
|
|
1279
|
+
}
|
|
1280
|
+
click() {
|
|
1281
|
+
if (this.disabled) {
|
|
1282
|
+
return;
|
|
1283
|
+
}
|
|
1284
|
+
// passing the header action id allows users to have one method that
|
|
1285
|
+
// routes to many different actions based on the type of header action
|
|
1286
|
+
// clicked. this is further aided by users being able to specify ids
|
|
1287
|
+
// for their header actions.
|
|
1288
|
+
this.headerActionClicked.emit(this._id);
|
|
1289
|
+
}
|
|
1290
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardHeaderAction, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1291
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.3", type: ClrWizardHeaderAction, isStandalone: false, selector: "clr-wizard-header-action", inputs: { title: "title", _id: ["id", "_id"], disabled: ["clrWizardHeaderActionDisabled", "disabled"] }, outputs: { headerActionClicked: "actionClicked" }, host: { classAttribute: "clr-wizard-header-action-wrapper" }, ngImport: i0, template: `
|
|
1292
|
+
<button
|
|
1293
|
+
type="button"
|
|
1294
|
+
class="btn clr-wizard-header-action btn-link"
|
|
1295
|
+
[id]="id"
|
|
1296
|
+
[class.disabled]="disabled"
|
|
1297
|
+
(click)="click()"
|
|
1298
|
+
[title]="title"
|
|
1299
|
+
>
|
|
1300
|
+
<ng-content></ng-content>
|
|
1301
|
+
</button>
|
|
1302
|
+
`, isInline: true }); }
|
|
1303
|
+
}
|
|
1304
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardHeaderAction, decorators: [{
|
|
1305
|
+
type: Component,
|
|
1306
|
+
args: [{
|
|
1307
|
+
selector: 'clr-wizard-header-action',
|
|
1308
|
+
template: `
|
|
1309
|
+
<button
|
|
1310
|
+
type="button"
|
|
1311
|
+
class="btn clr-wizard-header-action btn-link"
|
|
1312
|
+
[id]="id"
|
|
1313
|
+
[class.disabled]="disabled"
|
|
1314
|
+
(click)="click()"
|
|
1315
|
+
[title]="title"
|
|
1316
|
+
>
|
|
1317
|
+
<ng-content></ng-content>
|
|
1318
|
+
</button>
|
|
1319
|
+
`,
|
|
1320
|
+
host: { class: 'clr-wizard-header-action-wrapper' },
|
|
1321
|
+
standalone: false,
|
|
1322
|
+
}]
|
|
1323
|
+
}], propDecorators: { title: [{
|
|
1324
|
+
type: Input,
|
|
1325
|
+
args: ['title']
|
|
1326
|
+
}], _id: [{
|
|
1327
|
+
type: Input,
|
|
1328
|
+
args: ['id']
|
|
1329
|
+
}], disabled: [{
|
|
1330
|
+
type: Input,
|
|
1331
|
+
args: ['clrWizardHeaderActionDisabled']
|
|
1332
|
+
}], headerActionClicked: [{
|
|
1333
|
+
type: Output,
|
|
1334
|
+
args: ['actionClicked']
|
|
1335
|
+
}] } });
|
|
1336
|
+
|
|
1337
|
+
/*
|
|
1338
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
1339
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
1340
|
+
* This software is released under MIT license.
|
|
1341
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
1342
|
+
*/
|
|
1343
|
+
class ClrWizardPageButtons {
|
|
1344
|
+
constructor(pageButtonsTemplateRef) {
|
|
1345
|
+
this.pageButtonsTemplateRef = pageButtonsTemplateRef;
|
|
1346
|
+
}
|
|
1347
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardPageButtons, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1348
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrWizardPageButtons, isStandalone: false, selector: "[clrPageButtons]", ngImport: i0 }); }
|
|
1349
|
+
}
|
|
1350
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardPageButtons, decorators: [{
|
|
1351
|
+
type: Directive,
|
|
1352
|
+
args: [{
|
|
1353
|
+
selector: '[clrPageButtons]',
|
|
1354
|
+
standalone: false,
|
|
1355
|
+
}]
|
|
1356
|
+
}], ctorParameters: () => [{ type: i0.TemplateRef }] });
|
|
1357
|
+
|
|
1358
|
+
/*
|
|
1359
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
1360
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
1361
|
+
* This software is released under MIT license.
|
|
1362
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
1363
|
+
*/
|
|
1364
|
+
class ClrWizardPageHeaderActions {
|
|
1365
|
+
constructor(pageHeaderActionsTemplateRef) {
|
|
1366
|
+
this.pageHeaderActionsTemplateRef = pageHeaderActionsTemplateRef;
|
|
1367
|
+
}
|
|
1368
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardPageHeaderActions, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1369
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrWizardPageHeaderActions, isStandalone: false, selector: "[clrPageHeaderActions]", ngImport: i0 }); }
|
|
1370
|
+
}
|
|
1371
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardPageHeaderActions, decorators: [{
|
|
1372
|
+
type: Directive,
|
|
1373
|
+
args: [{
|
|
1374
|
+
selector: '[clrPageHeaderActions]',
|
|
1375
|
+
standalone: false,
|
|
1376
|
+
}]
|
|
1377
|
+
}], ctorParameters: () => [{ type: i0.TemplateRef }] });
|
|
1378
|
+
|
|
1379
|
+
/*
|
|
1380
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
1381
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
1382
|
+
* This software is released under MIT license.
|
|
1383
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
1384
|
+
*/
|
|
1385
|
+
class ClrWizardPageNavTitle {
|
|
1386
|
+
constructor(pageNavTitleTemplateRef) {
|
|
1387
|
+
this.pageNavTitleTemplateRef = pageNavTitleTemplateRef;
|
|
1388
|
+
}
|
|
1389
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardPageNavTitle, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1390
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrWizardPageNavTitle, isStandalone: false, selector: "[clrPageNavTitle]", ngImport: i0 }); }
|
|
1391
|
+
}
|
|
1392
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardPageNavTitle, decorators: [{
|
|
1393
|
+
type: Directive,
|
|
1394
|
+
args: [{
|
|
1395
|
+
selector: '[clrPageNavTitle]',
|
|
1396
|
+
standalone: false,
|
|
1397
|
+
}]
|
|
1398
|
+
}], ctorParameters: () => [{ type: i0.TemplateRef }] });
|
|
1399
|
+
|
|
1400
|
+
/*
|
|
1401
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
1402
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
1403
|
+
* This software is released under MIT license.
|
|
1404
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
1405
|
+
*/
|
|
1406
|
+
class ClrWizardPageTitle {
|
|
1407
|
+
constructor(pageTitleTemplateRef) {
|
|
1408
|
+
this.pageTitleTemplateRef = pageTitleTemplateRef;
|
|
1409
|
+
}
|
|
1410
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardPageTitle, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1411
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrWizardPageTitle, isStandalone: false, selector: "[clrPageTitle]", inputs: { headingLevel: ["clrHeadingLevel", "headingLevel"] }, ngImport: i0 }); }
|
|
1412
|
+
}
|
|
1413
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardPageTitle, decorators: [{
|
|
1414
|
+
type: Directive,
|
|
1415
|
+
args: [{
|
|
1416
|
+
selector: '[clrPageTitle]',
|
|
1417
|
+
standalone: false,
|
|
1418
|
+
}]
|
|
1419
|
+
}], ctorParameters: () => [{ type: i0.TemplateRef }], propDecorators: { headingLevel: [{
|
|
1420
|
+
type: Input,
|
|
1421
|
+
args: ['clrHeadingLevel']
|
|
1422
|
+
}] } });
|
|
1423
|
+
|
|
1424
|
+
/*
|
|
1425
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
1426
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
1427
|
+
* This software is released under MIT license.
|
|
1428
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
1429
|
+
*/
|
|
1430
|
+
let wizardPageIndex = 0;
|
|
1431
|
+
/**
|
|
1432
|
+
* The ClrWizardPage component is responsible for displaying the content of each step
|
|
1433
|
+
* in the wizard workflow.
|
|
1434
|
+
*
|
|
1435
|
+
* ClrWizardPage component has hooks into the navigation service (ClrWizardPage.navService),
|
|
1436
|
+
* page collection (ClrWizardPage.pageCollection), and button service
|
|
1437
|
+
* (ClrWizardPage.buttonService). These three providers are shared across the components
|
|
1438
|
+
* within each instance of a Wizard.
|
|
1439
|
+
*
|
|
1440
|
+
*/
|
|
1441
|
+
class ClrWizardPage {
|
|
1442
|
+
/**
|
|
1443
|
+
* Creates an instance of ClrWizardPage.
|
|
1444
|
+
*
|
|
1445
|
+
* @memberof WizardPage
|
|
1446
|
+
*/
|
|
1447
|
+
constructor(navService, pageCollection, buttonService) {
|
|
1448
|
+
this.navService = navService;
|
|
1449
|
+
this.pageCollection = pageCollection;
|
|
1450
|
+
this.buttonService = buttonService;
|
|
1451
|
+
/**
|
|
1452
|
+
* An input value that is used internally to generate the ClrWizardPage ID as
|
|
1453
|
+
* well as the step nav item ID.
|
|
1454
|
+
*
|
|
1455
|
+
* Typed as any because it should be able to accept numbers as well as
|
|
1456
|
+
* strings. Passing an index for wizard whose pages are created with an
|
|
1457
|
+
* ngFor loop is a common use case.
|
|
1458
|
+
*
|
|
1459
|
+
* @memberof WizardPage
|
|
1460
|
+
*
|
|
1461
|
+
*/
|
|
1462
|
+
this._id = (wizardPageIndex++).toString();
|
|
1463
|
+
/**
|
|
1464
|
+
* Overrides all actions from the page level, so you can use an alternate function for
|
|
1465
|
+
* validation or data-munging with a ClrWizardPage.onCommit (clrWizardPageOnCommit output),
|
|
1466
|
+
* ClrWizardPage.onCancel (clrWizardPageOnCancel output), or one
|
|
1467
|
+
* of the granular page-level button click event emitters.
|
|
1468
|
+
*
|
|
1469
|
+
* @memberof WizardPage
|
|
1470
|
+
*
|
|
1471
|
+
*/
|
|
1472
|
+
this.preventDefault = false;
|
|
1473
|
+
/**
|
|
1474
|
+
* Emits when the value of ClrWizardPage.nextStepDisabled changes.
|
|
1475
|
+
* Should emit the new value of nextStepDisabled.
|
|
1476
|
+
*
|
|
1477
|
+
* @memberof WizardPage
|
|
1478
|
+
*
|
|
1479
|
+
*/
|
|
1480
|
+
this.nextStepDisabledChange = new EventEmitter();
|
|
1481
|
+
/**
|
|
1482
|
+
* Emits when the value of ClrWizardPage.previousStepDisabled changes.
|
|
1483
|
+
* Should emit the new value of previousStepDisabled.
|
|
1484
|
+
*
|
|
1485
|
+
* @memberof WizardPage
|
|
1486
|
+
*
|
|
1487
|
+
*/
|
|
1488
|
+
this.previousStepDisabledChange = new EventEmitter();
|
|
1489
|
+
/**
|
|
1490
|
+
*
|
|
1491
|
+
* @memberof WizardPage
|
|
1492
|
+
*
|
|
1493
|
+
*/
|
|
1494
|
+
this.stopCancelChange = new EventEmitter();
|
|
1495
|
+
/**
|
|
1496
|
+
* An event emitter carried over from a legacy version of ClrWizardPage.
|
|
1497
|
+
* Fires an event on ClrWizardPage whenever the next or finish buttons
|
|
1498
|
+
* are clicked and the page is the current page of the Wizard.
|
|
1499
|
+
*
|
|
1500
|
+
* Note that this does not automatically emit an event when a custom
|
|
1501
|
+
* button is used in place of a next or finish button.
|
|
1502
|
+
*
|
|
1503
|
+
* @memberof WizardPage
|
|
1504
|
+
*
|
|
1505
|
+
*/
|
|
1506
|
+
this.onCommit = new EventEmitter(false);
|
|
1507
|
+
/**
|
|
1508
|
+
* Emits an event when ClrWizardPage becomes the current page of the
|
|
1509
|
+
* Wizard.
|
|
1510
|
+
*
|
|
1511
|
+
* @memberof WizardPage
|
|
1512
|
+
*
|
|
1513
|
+
*/
|
|
1514
|
+
this.onLoad = new EventEmitter();
|
|
1515
|
+
/**
|
|
1516
|
+
* Emits an event when the ClrWizardPage invokes the cancel routine for the wizard.
|
|
1517
|
+
*
|
|
1518
|
+
* Can be used in conjunction with the ClrWizardPage.stopCancel
|
|
1519
|
+
* (clrWizardPagePreventDefaultCancel) or ClrWizardPage.preventDefault
|
|
1520
|
+
* (clrWizardPagePagePreventDefault) inputs to implement custom cancel
|
|
1521
|
+
* functionality at the page level. This is useful if you would like to do
|
|
1522
|
+
* validation, save data, or warn users before cancelling the wizard.
|
|
1523
|
+
*
|
|
1524
|
+
* Note that this requires you to call Wizard.close() from the host component.
|
|
1525
|
+
* This constitues a full replacement of the cancel functionality.
|
|
1526
|
+
*
|
|
1527
|
+
* @memberof WizardPage
|
|
1528
|
+
*
|
|
1529
|
+
*/
|
|
1530
|
+
this.pageOnCancel = new EventEmitter();
|
|
1531
|
+
/**
|
|
1532
|
+
* Emits an event when the finish button is clicked and the ClrWizardPage is
|
|
1533
|
+
* the wizard's current page.
|
|
1534
|
+
*
|
|
1535
|
+
* Can be used in conjunction with the ClrWizardPage.preventDefault
|
|
1536
|
+
* (clrWizardPagePagePreventDefault) input to implement custom finish
|
|
1537
|
+
* functionality at the page level. This is useful if you would like to do
|
|
1538
|
+
* validation, save data, or warn users before allowing them to complete
|
|
1539
|
+
* the wizard.
|
|
1540
|
+
*
|
|
1541
|
+
* Note that this requires you to call Wizard.finish() or Wizard.forceFinish()
|
|
1542
|
+
* from the host component. This combination creates a full replacement of
|
|
1543
|
+
* the finish functionality.
|
|
1544
|
+
*
|
|
1545
|
+
* @memberof WizardPage
|
|
1546
|
+
*
|
|
1547
|
+
*/
|
|
1548
|
+
this.finishButtonClicked = new EventEmitter();
|
|
1549
|
+
/**
|
|
1550
|
+
* Emits an event when the previous button is clicked and the ClrWizardPage is
|
|
1551
|
+
* the wizard's current page.
|
|
1552
|
+
*
|
|
1553
|
+
* Can be used in conjunction with the ClrWizardPage.preventDefault
|
|
1554
|
+
* (clrWizardPagePagePreventDefault) input to implement custom backwards
|
|
1555
|
+
* navigation at the page level. This is useful if you would like to do
|
|
1556
|
+
* validation, save data, or warn users before allowing them to go
|
|
1557
|
+
* backwards in the wizard.
|
|
1558
|
+
*
|
|
1559
|
+
* Note that this requires you to call Wizard.previous()
|
|
1560
|
+
* from the host component. This combination creates a full replacement of
|
|
1561
|
+
* the backwards navigation functionality.
|
|
1562
|
+
*
|
|
1563
|
+
* @memberof WizardPage
|
|
1564
|
+
*
|
|
1565
|
+
*/
|
|
1566
|
+
this.previousButtonClicked = new EventEmitter();
|
|
1567
|
+
/**
|
|
1568
|
+
* Emits an event when the next button is clicked and the ClrWizardPage is
|
|
1569
|
+
* the wizard's current page.
|
|
1570
|
+
*
|
|
1571
|
+
* Can be used in conjunction with the ClrWizardPage.preventDefault
|
|
1572
|
+
* (clrWizardPagePagePreventDefault) input to implement custom forwards
|
|
1573
|
+
* navigation at the page level. This is useful if you would like to do
|
|
1574
|
+
* validation, save data, or warn users before allowing them to go
|
|
1575
|
+
* to the next page in the wizard.
|
|
1576
|
+
*
|
|
1577
|
+
* Note that this requires you to call Wizard.forceNext() or Wizard.next()
|
|
1578
|
+
* from the host component. This combination creates a full replacement of
|
|
1579
|
+
* the forward navigation functionality.
|
|
1580
|
+
*
|
|
1581
|
+
* @memberof WizardPage
|
|
1582
|
+
*
|
|
1583
|
+
*/
|
|
1584
|
+
this.nextButtonClicked = new EventEmitter();
|
|
1585
|
+
/**
|
|
1586
|
+
* Emits an event when a danger button is clicked and the ClrWizardPage is
|
|
1587
|
+
* the wizard's current page. By default, a danger button will act as
|
|
1588
|
+
* either a "next" or "finish" button depending on if the ClrWizardPage is the
|
|
1589
|
+
* last page or not.
|
|
1590
|
+
*
|
|
1591
|
+
* Can be used in conjunction with the ClrWizardPage.preventDefault
|
|
1592
|
+
* (clrWizardPagePagePreventDefault) input to implement custom forwards
|
|
1593
|
+
* or finish navigation at the page level when the danger button is clicked.
|
|
1594
|
+
* This is useful if you would like to do validation, save data, or warn
|
|
1595
|
+
* users before allowing them to go to the next page in the wizard or
|
|
1596
|
+
* finish the wizard.
|
|
1597
|
+
*
|
|
1598
|
+
* Note that this requires you to call Wizard.finish(), Wizard.forceFinish(),
|
|
1599
|
+
* Wizard.forceNext() or Wizard.next() from the host component. This
|
|
1600
|
+
* combination creates a full replacement of the forward navigation and
|
|
1601
|
+
* finish functionality.
|
|
1602
|
+
*
|
|
1603
|
+
* @memberof WizardPage
|
|
1604
|
+
*
|
|
1605
|
+
*/
|
|
1606
|
+
this.dangerButtonClicked = new EventEmitter();
|
|
1607
|
+
/**
|
|
1608
|
+
* Emits an event when a next, finish, or danger button is clicked and the
|
|
1609
|
+
* ClrWizardPage is the wizard's current page.
|
|
1610
|
+
*
|
|
1611
|
+
* Can be used in conjunction with the ClrWizardPage.preventDefault
|
|
1612
|
+
* (clrWizardPagePagePreventDefault) input to implement custom forwards
|
|
1613
|
+
* or finish navigation at the page level, regardless of the type of
|
|
1614
|
+
* primary button.
|
|
1615
|
+
*
|
|
1616
|
+
* This is useful if you would like to do validation, save data, or warn
|
|
1617
|
+
* users before allowing them to go to the next page in the wizard or
|
|
1618
|
+
* finish the wizard.
|
|
1619
|
+
*
|
|
1620
|
+
* Note that this requires you to call Wizard.finish(), Wizard.forceFinish(),
|
|
1621
|
+
* Wizard.forceNext() or Wizard.next() from the host component. This
|
|
1622
|
+
* combination creates a full replacement of the forward navigation and
|
|
1623
|
+
* finish functionality.
|
|
1624
|
+
*
|
|
1625
|
+
* @memberof WizardPage
|
|
1626
|
+
*
|
|
1627
|
+
*/
|
|
1628
|
+
this.primaryButtonClicked = new EventEmitter();
|
|
1629
|
+
this.customButtonClicked = new EventEmitter();
|
|
1630
|
+
/**
|
|
1631
|
+
*
|
|
1632
|
+
* @memberof WizardPage
|
|
1633
|
+
*
|
|
1634
|
+
*/
|
|
1635
|
+
this._nextStepDisabled = false;
|
|
1636
|
+
/**
|
|
1637
|
+
*
|
|
1638
|
+
* @memberof WizardPage
|
|
1639
|
+
*
|
|
1640
|
+
*/
|
|
1641
|
+
this._previousStepDisabled = false;
|
|
1642
|
+
/**
|
|
1643
|
+
*
|
|
1644
|
+
* @memberof WizardPage
|
|
1645
|
+
*
|
|
1646
|
+
*/
|
|
1647
|
+
this._hasError = false;
|
|
1648
|
+
/**
|
|
1649
|
+
*
|
|
1650
|
+
* @memberof WizardPage
|
|
1651
|
+
*
|
|
1652
|
+
*/
|
|
1653
|
+
this._stopCancel = false;
|
|
1654
|
+
/**
|
|
1655
|
+
*
|
|
1656
|
+
* @memberof WizardPage
|
|
1657
|
+
*
|
|
1658
|
+
*/
|
|
1659
|
+
this._stopNext = false;
|
|
1660
|
+
/**
|
|
1661
|
+
*
|
|
1662
|
+
* @memberof WizardPage
|
|
1663
|
+
*
|
|
1664
|
+
*/
|
|
1665
|
+
this._complete = false;
|
|
1666
|
+
}
|
|
1667
|
+
/**
|
|
1668
|
+
* A property that tells whether or not the wizard should be allowed
|
|
1669
|
+
* to move to the next page.
|
|
1670
|
+
*
|
|
1671
|
+
* Useful for in-page validation because it prevents forward navigation
|
|
1672
|
+
* and visibly disables the next button.
|
|
1673
|
+
*
|
|
1674
|
+
* Does not require that you re-implement navigation routines like you
|
|
1675
|
+
* would if you were using ClrWizardPage.preventDefault or
|
|
1676
|
+
* Wizard.preventDefault.
|
|
1677
|
+
*
|
|
1678
|
+
* @memberof WizardPage
|
|
1679
|
+
*
|
|
1680
|
+
*/
|
|
1681
|
+
get nextStepDisabled() {
|
|
1682
|
+
return this._nextStepDisabled;
|
|
1683
|
+
}
|
|
1684
|
+
set nextStepDisabled(val) {
|
|
1685
|
+
const valBool = !!val;
|
|
1686
|
+
if (valBool !== this._nextStepDisabled) {
|
|
1687
|
+
this._nextStepDisabled = valBool;
|
|
1688
|
+
this.nextStepDisabledChange.emit(valBool);
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
/**
|
|
1692
|
+
* A property that tells whether or not the wizard should be allowed
|
|
1693
|
+
* to move to the previous page.
|
|
1694
|
+
*
|
|
1695
|
+
* Useful for in-page validation because it prevents backward navigation
|
|
1696
|
+
* and visibly disables the previous button.
|
|
1697
|
+
*
|
|
1698
|
+
* Does not require that you re-implement navigation routines like you
|
|
1699
|
+
* would if you were using ClrWizardPage.preventDefault or
|
|
1700
|
+
* Wizard.preventDefault.
|
|
1701
|
+
*
|
|
1702
|
+
* @memberof WizardPage
|
|
1703
|
+
*
|
|
1704
|
+
*/
|
|
1705
|
+
get previousStepDisabled() {
|
|
1706
|
+
return this._previousStepDisabled;
|
|
1707
|
+
}
|
|
1708
|
+
set previousStepDisabled(val) {
|
|
1709
|
+
const valBool = !!val;
|
|
1710
|
+
if (valBool !== this._previousStepDisabled) {
|
|
1711
|
+
this._previousStepDisabled = valBool;
|
|
1712
|
+
this.previousStepDisabledChange.emit(valBool);
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
/**
|
|
1716
|
+
* Whether the page has an error and also resolve the "falsy" value. The
|
|
1717
|
+
* current logic treat a "0" or an empty string as false and likewise will treat any
|
|
1718
|
+
* "truthy" value as true.
|
|
1719
|
+
*
|
|
1720
|
+
* @memberof WizardPage
|
|
1721
|
+
*
|
|
1722
|
+
*/
|
|
1723
|
+
get hasError() {
|
|
1724
|
+
return this._hasError;
|
|
1725
|
+
}
|
|
1726
|
+
set hasError(val) {
|
|
1727
|
+
const valBool = !!val;
|
|
1728
|
+
if (valBool !== this._hasError) {
|
|
1729
|
+
this._hasError = valBool;
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
/**
|
|
1733
|
+
* Overrides the cancel action from the page level. Allows you to use an
|
|
1734
|
+
* alternate function for validation or data-munging before cancelling the
|
|
1735
|
+
* wizard when combined with the ClrWizardPage.onCancel
|
|
1736
|
+
* (the clrWizardPageOnCancel output).
|
|
1737
|
+
*
|
|
1738
|
+
* Requires that you manually close the wizard from your host component,
|
|
1739
|
+
* usually with a call to Wizard.forceNext() or wizard.next();
|
|
1740
|
+
*
|
|
1741
|
+
* @memberof ClrWizardPage
|
|
1742
|
+
*/
|
|
1743
|
+
get stopCancel() {
|
|
1744
|
+
return this._stopCancel;
|
|
1745
|
+
}
|
|
1746
|
+
set stopCancel(val) {
|
|
1747
|
+
const valBool = !!val;
|
|
1748
|
+
if (valBool !== this._stopCancel) {
|
|
1749
|
+
this._stopCancel = valBool;
|
|
1750
|
+
this.stopCancelChange.emit(valBool);
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
/**
|
|
1754
|
+
* Overrides forward navigation from the page level. Allows you to use an
|
|
1755
|
+
* alternate function for validation or data-munging before moving the
|
|
1756
|
+
* wizard to the next pagewhen combined with the ClrWizardPage.onCommit
|
|
1757
|
+
* (clrWizardPageOnCommit) or ClrWizardPage.nextButtonClicked
|
|
1758
|
+
* (clrWizardPageNext) outputs.
|
|
1759
|
+
*
|
|
1760
|
+
* Requires that you manually tell the wizard to navigate forward from
|
|
1761
|
+
* the hostComponent, usually with a call to Wizard.forceNext() or
|
|
1762
|
+
* wizard.next();
|
|
1763
|
+
*
|
|
1764
|
+
* @memberof ClrWizardPage
|
|
1765
|
+
*/
|
|
1766
|
+
get stopNext() {
|
|
1767
|
+
return this._stopNext;
|
|
1768
|
+
}
|
|
1769
|
+
set stopNext(val) {
|
|
1770
|
+
const valBool = !!val;
|
|
1771
|
+
if (valBool !== this._stopNext) {
|
|
1772
|
+
this._stopNext = valBool;
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
/**
|
|
1776
|
+
* A read-only getter that generates an ID string for the wizard page from
|
|
1777
|
+
* either the value passed to the ClrWizardPage "id" input or a wizard page
|
|
1778
|
+
* counter shared across all wizard pages in the application.
|
|
1779
|
+
*
|
|
1780
|
+
* Note that the value passed into the ID input Will be prefixed with
|
|
1781
|
+
* "clr-wizard-page-".
|
|
1782
|
+
*
|
|
1783
|
+
* @readonly
|
|
1784
|
+
*
|
|
1785
|
+
* @memberof ClrWizardPage
|
|
1786
|
+
*/
|
|
1787
|
+
get id() {
|
|
1788
|
+
// covers things like null, undefined, false, and empty string
|
|
1789
|
+
// while allowing zero to pass
|
|
1790
|
+
const idIsNonZeroFalsy = !this._id && this._id !== 0;
|
|
1791
|
+
// in addition to non-zero falsy we also want to make sure _id is not a negative
|
|
1792
|
+
// number.
|
|
1793
|
+
if (idIsNonZeroFalsy || this._id < 0) {
|
|
1794
|
+
// guard here in the event that input becomes undefined or null by accident
|
|
1795
|
+
this._id = (wizardPageIndex++).toString();
|
|
1796
|
+
}
|
|
1797
|
+
return `clr-wizard-page-${this._id}`;
|
|
1798
|
+
}
|
|
1799
|
+
/**
|
|
1800
|
+
* A read-only getter that serves as a convenience for those who would rather
|
|
1801
|
+
* not think in the terms of !ClrWizardPage.nextStepDisabled. For some use cases,
|
|
1802
|
+
* ClrWizardPage.readyToComplete is more logical and declarative.
|
|
1803
|
+
*
|
|
1804
|
+
* @memberof WizardPage
|
|
1805
|
+
*
|
|
1806
|
+
*/
|
|
1807
|
+
get readyToComplete() {
|
|
1808
|
+
return !this.nextStepDisabled;
|
|
1809
|
+
}
|
|
1810
|
+
/**
|
|
1811
|
+
* A page is marked as completed if it is both readyToComplete and completed,
|
|
1812
|
+
* as in the next or finish action has been executed while this page was current.
|
|
1813
|
+
*
|
|
1814
|
+
* Note there is and open question about how to handle pages that are marked
|
|
1815
|
+
* complete but who are no longer readyToComplete. This might indicate an error
|
|
1816
|
+
* state for the ClrWizardPage. Currently, the wizard does not acknowledge this state
|
|
1817
|
+
* and only returns that the page is incomplete.
|
|
1818
|
+
*
|
|
1819
|
+
* @memberof WizardPage
|
|
1820
|
+
*
|
|
1821
|
+
*/
|
|
1822
|
+
get completed() {
|
|
1823
|
+
return this._complete && this.readyToComplete;
|
|
1824
|
+
// FOR V2: UNWIND COMPLETED, READYTOCOMPLETE, AND ERRORS
|
|
1825
|
+
// SUCH THAT ERRORS IS ITS OWN INPUT. IF A STEP IS
|
|
1826
|
+
// INCOMPLETE AND ERRORED, ERRORED WILL NOT SHOW.
|
|
1827
|
+
// FIRST QUESTION: AM I GREY OR COLORED?
|
|
1828
|
+
// SECOND QUESTION: AM I GREEN OR RED?
|
|
1829
|
+
}
|
|
1830
|
+
/**
|
|
1831
|
+
* A ClrWizardPage can be manually set to completed using this boolean setter.
|
|
1832
|
+
* It is recommended that users rely on the convenience functions in the wizard
|
|
1833
|
+
* and navigation service instead of manually setting pages’ completion state.
|
|
1834
|
+
*
|
|
1835
|
+
* @memberof ClrWizardPage
|
|
1836
|
+
*/
|
|
1837
|
+
set completed(value) {
|
|
1838
|
+
this._complete = value;
|
|
1839
|
+
}
|
|
1840
|
+
/**
|
|
1841
|
+
* Checks with the navigation service to see if it is the current page.
|
|
1842
|
+
*
|
|
1843
|
+
* @memberof WizardPage
|
|
1844
|
+
*
|
|
1845
|
+
*/
|
|
1846
|
+
get current() {
|
|
1847
|
+
return this.navService.currentPage === this;
|
|
1848
|
+
}
|
|
1849
|
+
get disabled() {
|
|
1850
|
+
return !this.enabled;
|
|
1851
|
+
}
|
|
1852
|
+
/**
|
|
1853
|
+
* A read-only getter that returns whether or not the page is navigable
|
|
1854
|
+
* in the wizard. A wizard page can be navigated to if it is completed
|
|
1855
|
+
* or the page before it is completed.
|
|
1856
|
+
*
|
|
1857
|
+
* This getter handles the logic for enabling or disabling the links in
|
|
1858
|
+
* the step nav on the left Side of the wizard.
|
|
1859
|
+
*
|
|
1860
|
+
* @memberof WizardPage
|
|
1861
|
+
*
|
|
1862
|
+
*/
|
|
1863
|
+
get enabled() {
|
|
1864
|
+
return this.current || this.completed || this.previousCompleted;
|
|
1865
|
+
}
|
|
1866
|
+
/**
|
|
1867
|
+
* A read-only getter that returns whether or not the page before this
|
|
1868
|
+
* ClrWizardPage is completed. This is useful for determining whether or not
|
|
1869
|
+
* a page is navigable if it is not current or already completed.
|
|
1870
|
+
*
|
|
1871
|
+
* @memberof WizardPage
|
|
1872
|
+
*
|
|
1873
|
+
*/
|
|
1874
|
+
get previousCompleted() {
|
|
1875
|
+
const previousPage = this.pageCollection.getPreviousPage(this);
|
|
1876
|
+
if (!previousPage) {
|
|
1877
|
+
return true;
|
|
1878
|
+
}
|
|
1879
|
+
return previousPage.completed;
|
|
1880
|
+
}
|
|
1881
|
+
/**
|
|
1882
|
+
*
|
|
1883
|
+
* @memberof WizardPage
|
|
1884
|
+
*
|
|
1885
|
+
*/
|
|
1886
|
+
get title() {
|
|
1887
|
+
return this.pageTitle?.pageTitleTemplateRef;
|
|
1888
|
+
}
|
|
1889
|
+
/**
|
|
1890
|
+
*
|
|
1891
|
+
* @memberof WizardPage
|
|
1892
|
+
*
|
|
1893
|
+
*/
|
|
1894
|
+
get navTitle() {
|
|
1895
|
+
if (this.pageNavTitle) {
|
|
1896
|
+
return this.pageNavTitle.pageNavTitleTemplateRef;
|
|
1897
|
+
}
|
|
1898
|
+
return this.pageTitle?.pageTitleTemplateRef;
|
|
1899
|
+
}
|
|
1900
|
+
/**
|
|
1901
|
+
*
|
|
1902
|
+
* @memberof WizardPage
|
|
1903
|
+
*
|
|
1904
|
+
*/
|
|
1905
|
+
get headerActions() {
|
|
1906
|
+
if (!this._headerActions) {
|
|
1907
|
+
return undefined;
|
|
1908
|
+
}
|
|
1909
|
+
return this._headerActions.pageHeaderActionsTemplateRef;
|
|
1910
|
+
}
|
|
1911
|
+
/**
|
|
1912
|
+
*
|
|
1913
|
+
* @memberof WizardPage
|
|
1914
|
+
*
|
|
1915
|
+
*/
|
|
1916
|
+
get hasHeaderActions() {
|
|
1917
|
+
return !!this._headerActions;
|
|
1918
|
+
}
|
|
1919
|
+
/**
|
|
1920
|
+
*
|
|
1921
|
+
* @memberof WizardPage
|
|
1922
|
+
*
|
|
1923
|
+
*/
|
|
1924
|
+
get buttons() {
|
|
1925
|
+
if (!this._buttons) {
|
|
1926
|
+
return undefined;
|
|
1927
|
+
}
|
|
1928
|
+
return this._buttons.pageButtonsTemplateRef;
|
|
1929
|
+
}
|
|
1930
|
+
/**
|
|
1931
|
+
* A read-only getter that returns a boolean that says whether or
|
|
1932
|
+
* not the ClrWizardPage includes buttons. Used to determine if the
|
|
1933
|
+
* Wizard should override the default button set defined as
|
|
1934
|
+
* its direct children.
|
|
1935
|
+
*
|
|
1936
|
+
* @memberof WizardPage
|
|
1937
|
+
*
|
|
1938
|
+
*/
|
|
1939
|
+
get hasButtons() {
|
|
1940
|
+
return !!this._buttons;
|
|
1941
|
+
}
|
|
1942
|
+
/**
|
|
1943
|
+
* A read-only getter that returns the id used by the step nav item associated with the page.
|
|
1944
|
+
*
|
|
1945
|
+
* ClrWizardPage needs this ID string for aria information.
|
|
1946
|
+
*
|
|
1947
|
+
* @memberof WizardPage
|
|
1948
|
+
*
|
|
1949
|
+
*/
|
|
1950
|
+
get stepItemId() {
|
|
1951
|
+
return this.pageCollection.getStepItemIdForPage(this);
|
|
1952
|
+
}
|
|
1953
|
+
/**
|
|
1954
|
+
* Links the nav service and establishes the current page if one is not defined.
|
|
1955
|
+
*
|
|
1956
|
+
* @memberof WizardPage
|
|
1957
|
+
*
|
|
1958
|
+
*/
|
|
1959
|
+
ngOnInit() {
|
|
1960
|
+
const navService = this.navService;
|
|
1961
|
+
if (!navService.currentPage && !navService.navServiceLoaded) {
|
|
1962
|
+
this.makeCurrent();
|
|
1963
|
+
this.navService.navServiceLoaded = true;
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
/**
|
|
1967
|
+
* Uses the nav service to make the ClrWizardPage the current page in the
|
|
1968
|
+
* wizard. Bypasses all checks but still emits the ClrWizardPage.onLoad
|
|
1969
|
+
* (clrWizardPageOnLoad) output.
|
|
1970
|
+
*
|
|
1971
|
+
* In most cases, it is better to use the default navigation functions
|
|
1972
|
+
* in Wizard.
|
|
1973
|
+
*
|
|
1974
|
+
* @memberof WizardPage
|
|
1975
|
+
*
|
|
1976
|
+
*/
|
|
1977
|
+
makeCurrent() {
|
|
1978
|
+
this.navService.currentPage = this;
|
|
1979
|
+
}
|
|
1980
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardPage, deps: [{ token: WizardNavigationService }, { token: PageCollectionService }, { token: ButtonHubService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1981
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.3", type: ClrWizardPage, isStandalone: false, selector: "clr-wizard-page", inputs: { _id: ["id", "_id"], preventDefault: ["clrWizardPagePreventDefault", "preventDefault"], nextStepDisabled: ["clrWizardPageNextDisabled", "nextStepDisabled"], previousStepDisabled: ["clrWizardPagePreviousDisabled", "previousStepDisabled"], hasError: ["clrWizardPageHasError", "hasError"], stopCancel: ["clrWizardPagePreventDefaultCancel", "stopCancel"], stopNext: ["clrWizardPagePreventDefaultNext", "stopNext"] }, outputs: { nextStepDisabledChange: "clrWizardPageNextDisabledChange", previousStepDisabledChange: "clrWizardPagePreviousDisabledChange", stopCancelChange: "clrWizardPagePreventDefaultCancelChange", onCommit: "clrWizardPageOnCommit", onLoad: "clrWizardPageOnLoad", pageOnCancel: "clrWizardPageOnCancel", finishButtonClicked: "clrWizardPageFinish", previousButtonClicked: "clrWizardPagePrevious", nextButtonClicked: "clrWizardPageNext", dangerButtonClicked: "clrWizardPageDanger", primaryButtonClicked: "clrWizardPagePrimary", customButtonClicked: "clrWizardPageCustomButton" }, host: { properties: { "id": "id", "attr.aria-hidden": "!current", "attr.aria-labelledby": "stepItemId", "class.active": "current", "class.clr-wizard-page": "true" } }, queries: [{ propertyName: "pageTitle", first: true, predicate: ClrWizardPageTitle, static: true }, { propertyName: "pageNavTitle", first: true, predicate: ClrWizardPageNavTitle, static: true }, { propertyName: "_buttons", first: true, predicate: ClrWizardPageButtons, static: true }, { propertyName: "_headerActions", first: true, predicate: ClrWizardPageHeaderActions, descendants: true, static: true }], ngImport: i0, template: '<ng-content></ng-content>', isInline: true }); }
|
|
1982
|
+
}
|
|
1983
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardPage, decorators: [{
|
|
1984
|
+
type: Component,
|
|
1985
|
+
args: [{
|
|
1986
|
+
selector: 'clr-wizard-page',
|
|
1987
|
+
template: '<ng-content></ng-content>',
|
|
1988
|
+
host: {
|
|
1989
|
+
'[id]': 'id',
|
|
1990
|
+
'[attr.aria-hidden]': '!current',
|
|
1991
|
+
'[attr.aria-labelledby]': 'stepItemId',
|
|
1992
|
+
'[class.active]': 'current',
|
|
1993
|
+
'[class.clr-wizard-page]': 'true',
|
|
1994
|
+
},
|
|
1995
|
+
standalone: false,
|
|
1996
|
+
}]
|
|
1997
|
+
}], ctorParameters: () => [{ type: WizardNavigationService }, { type: PageCollectionService }, { type: ButtonHubService }], propDecorators: { _id: [{
|
|
1998
|
+
type: Input,
|
|
1999
|
+
args: ['id']
|
|
2000
|
+
}], preventDefault: [{
|
|
2001
|
+
type: Input,
|
|
2002
|
+
args: ['clrWizardPagePreventDefault']
|
|
2003
|
+
}], nextStepDisabledChange: [{
|
|
2004
|
+
type: Output,
|
|
2005
|
+
args: ['clrWizardPageNextDisabledChange']
|
|
2006
|
+
}], previousStepDisabledChange: [{
|
|
2007
|
+
type: Output,
|
|
2008
|
+
args: ['clrWizardPagePreviousDisabledChange']
|
|
2009
|
+
}], stopCancelChange: [{
|
|
2010
|
+
type: Output,
|
|
2011
|
+
args: ['clrWizardPagePreventDefaultCancelChange']
|
|
2012
|
+
}], onCommit: [{
|
|
2013
|
+
type: Output,
|
|
2014
|
+
args: ['clrWizardPageOnCommit']
|
|
2015
|
+
}], onLoad: [{
|
|
2016
|
+
type: Output,
|
|
2017
|
+
args: ['clrWizardPageOnLoad']
|
|
2018
|
+
}], pageOnCancel: [{
|
|
2019
|
+
type: Output,
|
|
2020
|
+
args: ['clrWizardPageOnCancel']
|
|
2021
|
+
}], finishButtonClicked: [{
|
|
2022
|
+
type: Output,
|
|
2023
|
+
args: ['clrWizardPageFinish']
|
|
2024
|
+
}], previousButtonClicked: [{
|
|
2025
|
+
type: Output,
|
|
2026
|
+
args: ['clrWizardPagePrevious']
|
|
2027
|
+
}], nextButtonClicked: [{
|
|
2028
|
+
type: Output,
|
|
2029
|
+
args: ['clrWizardPageNext']
|
|
2030
|
+
}], dangerButtonClicked: [{
|
|
2031
|
+
type: Output,
|
|
2032
|
+
args: ['clrWizardPageDanger']
|
|
2033
|
+
}], primaryButtonClicked: [{
|
|
2034
|
+
type: Output,
|
|
2035
|
+
args: ['clrWizardPagePrimary']
|
|
2036
|
+
}], customButtonClicked: [{
|
|
2037
|
+
type: Output,
|
|
2038
|
+
args: ['clrWizardPageCustomButton']
|
|
2039
|
+
}], pageTitle: [{
|
|
2040
|
+
type: ContentChild,
|
|
2041
|
+
args: [ClrWizardPageTitle, { static: true, descendants: false }]
|
|
2042
|
+
}], pageNavTitle: [{
|
|
2043
|
+
type: ContentChild,
|
|
2044
|
+
args: [ClrWizardPageNavTitle, { static: true, descendants: false }]
|
|
2045
|
+
}], _buttons: [{
|
|
2046
|
+
type: ContentChild,
|
|
2047
|
+
args: [ClrWizardPageButtons, { static: true, descendants: false }]
|
|
2048
|
+
}], _headerActions: [{
|
|
2049
|
+
type: ContentChild,
|
|
2050
|
+
args: [ClrWizardPageHeaderActions, { static: true }]
|
|
2051
|
+
}], nextStepDisabled: [{
|
|
2052
|
+
type: Input,
|
|
2053
|
+
args: ['clrWizardPageNextDisabled']
|
|
2054
|
+
}], previousStepDisabled: [{
|
|
2055
|
+
type: Input,
|
|
2056
|
+
args: ['clrWizardPagePreviousDisabled']
|
|
2057
|
+
}], hasError: [{
|
|
2058
|
+
type: Input,
|
|
2059
|
+
args: ['clrWizardPageHasError']
|
|
2060
|
+
}], stopCancel: [{
|
|
2061
|
+
type: Input,
|
|
2062
|
+
args: ['clrWizardPagePreventDefaultCancel']
|
|
2063
|
+
}], stopNext: [{
|
|
2064
|
+
type: Input,
|
|
2065
|
+
args: ['clrWizardPagePreventDefaultNext']
|
|
2066
|
+
}] } });
|
|
2067
|
+
|
|
2068
|
+
/*
|
|
2069
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
2070
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
2071
|
+
* This software is released under MIT license.
|
|
2072
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
2073
|
+
*/
|
|
2074
|
+
class ClrWizardTitle {
|
|
2075
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardTitle, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2076
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrWizardTitle, isStandalone: false, selector: "clr-wizard-title", inputs: { headingLevel: ["clrHeadingLevel", "headingLevel"] }, ngImport: i0 }); }
|
|
2077
|
+
}
|
|
2078
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardTitle, decorators: [{
|
|
2079
|
+
type: Directive,
|
|
2080
|
+
args: [{
|
|
2081
|
+
selector: 'clr-wizard-title',
|
|
2082
|
+
standalone: false,
|
|
2083
|
+
}]
|
|
2084
|
+
}], propDecorators: { headingLevel: [{
|
|
2085
|
+
type: Input,
|
|
2086
|
+
args: ['clrHeadingLevel']
|
|
2087
|
+
}] } });
|
|
2088
|
+
|
|
2089
|
+
/*
|
|
2090
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
2091
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
2092
|
+
* This software is released under MIT license.
|
|
2093
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
2094
|
+
*/
|
|
2095
|
+
class ClrWizardStepnavItem {
|
|
2096
|
+
constructor(navService, pageCollection, commonStrings, elementRef) {
|
|
2097
|
+
this.navService = navService;
|
|
2098
|
+
this.pageCollection = pageCollection;
|
|
2099
|
+
this.commonStrings = commonStrings;
|
|
2100
|
+
this.elementRef = elementRef;
|
|
2101
|
+
/**
|
|
2102
|
+
* This is used to prevent the steps from scrolling as the user clicks on the steps.
|
|
2103
|
+
*/
|
|
2104
|
+
this.skipNextScroll = false;
|
|
2105
|
+
}
|
|
2106
|
+
get id() {
|
|
2107
|
+
this.pageGuard();
|
|
2108
|
+
return this.pageCollection.getStepItemIdForPage(this.page);
|
|
2109
|
+
}
|
|
2110
|
+
get stepAriaCurrent() {
|
|
2111
|
+
return this.isCurrent && 'step';
|
|
2112
|
+
}
|
|
2113
|
+
get isDisabled() {
|
|
2114
|
+
this.pageGuard();
|
|
2115
|
+
return this.page.disabled || this.navService.wizardStopNavigation || this.navService.wizardDisableStepnav;
|
|
2116
|
+
}
|
|
2117
|
+
get isCurrent() {
|
|
2118
|
+
this.pageGuard();
|
|
2119
|
+
return this.page.current;
|
|
2120
|
+
}
|
|
2121
|
+
get isComplete() {
|
|
2122
|
+
this.pageGuard();
|
|
2123
|
+
return this.page.completed;
|
|
2124
|
+
}
|
|
2125
|
+
get hasError() {
|
|
2126
|
+
this.pageGuard();
|
|
2127
|
+
return this.page.hasError && this.isComplete;
|
|
2128
|
+
}
|
|
2129
|
+
get canNavigate() {
|
|
2130
|
+
this.pageGuard();
|
|
2131
|
+
return this.pageCollection.previousPageIsCompleted(this.page);
|
|
2132
|
+
}
|
|
2133
|
+
get stepIconId() {
|
|
2134
|
+
return `${this.id}-step-icon`;
|
|
2135
|
+
}
|
|
2136
|
+
get stepTextId() {
|
|
2137
|
+
return `${this.id}-step-text`;
|
|
2138
|
+
}
|
|
2139
|
+
get stepNumberId() {
|
|
2140
|
+
return `${this.id}-step-number`;
|
|
2141
|
+
}
|
|
2142
|
+
get stepTitleId() {
|
|
2143
|
+
return `${this.id}-step-title`;
|
|
2144
|
+
}
|
|
2145
|
+
get labelledby() {
|
|
2146
|
+
const textIds = [this.stepTextId, this.stepNumberId, this.stepTitleId];
|
|
2147
|
+
const allIds = this.isComplete ? [this.stepIconId, ...textIds] : textIds;
|
|
2148
|
+
return allIds.join(' ');
|
|
2149
|
+
}
|
|
2150
|
+
get icon() {
|
|
2151
|
+
if (this.isCurrent && this.navService.stepnavLayout !== ClrWizardStepnavLayout.HORIZONTAL) {
|
|
2152
|
+
return {
|
|
2153
|
+
shape: 'dot-circle',
|
|
2154
|
+
label: this.commonStrings.keys.wizardStepCurrent || this.commonStrings.keys.timelineStepCurrent,
|
|
2155
|
+
};
|
|
2156
|
+
}
|
|
2157
|
+
else if (this.hasError) {
|
|
2158
|
+
return {
|
|
2159
|
+
shape: 'error-standard',
|
|
2160
|
+
label: this.commonStrings.keys.wizardStepError || this.commonStrings.keys.timelineStepError,
|
|
2161
|
+
};
|
|
2162
|
+
}
|
|
2163
|
+
else if (this.isComplete) {
|
|
2164
|
+
return {
|
|
2165
|
+
shape: 'success-standard',
|
|
2166
|
+
label: this.commonStrings.keys.wizardStepSuccess || this.commonStrings.keys.timelineStepSuccess,
|
|
2167
|
+
};
|
|
2168
|
+
}
|
|
2169
|
+
else {
|
|
2170
|
+
return null;
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
ngOnInit() {
|
|
2174
|
+
this.subscription = this.ensureCurrentStepIsScrolledIntoView().subscribe();
|
|
2175
|
+
}
|
|
2176
|
+
ngOnDestroy() {
|
|
2177
|
+
this.subscription?.unsubscribe();
|
|
2178
|
+
}
|
|
2179
|
+
click() {
|
|
2180
|
+
this.pageGuard();
|
|
2181
|
+
// if we click on our own stepnav or a disabled stepnav, we don't want to do anything
|
|
2182
|
+
if (this.isDisabled || this.isCurrent) {
|
|
2183
|
+
return;
|
|
2184
|
+
}
|
|
2185
|
+
this.skipNextScroll = true;
|
|
2186
|
+
this.navService.goTo(this.page);
|
|
2187
|
+
}
|
|
2188
|
+
scrollIntoView() {
|
|
2189
|
+
this.elementRef.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });
|
|
2190
|
+
}
|
|
2191
|
+
pageGuard() {
|
|
2192
|
+
if (!this.page) {
|
|
2193
|
+
throw new Error('Wizard stepnav item is not associated with a wizard page.');
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
ensureCurrentStepIsScrolledIntoView() {
|
|
2197
|
+
// Don't use "smooth" scrolling when the wizard is first opened to avoid a delay in scrolling the current step into view.
|
|
2198
|
+
// The current step when the wizard is opened might not be the first step. For example, the wizard can be closed and re-opened.
|
|
2199
|
+
let scrollBehavior = 'auto';
|
|
2200
|
+
return this.navService.currentPageChange.pipe(startWith(this.navService.currentPage), debounceTime(1), tap(currentPage => {
|
|
2201
|
+
if (!this.skipNextScroll && currentPage === this.page) {
|
|
2202
|
+
this.elementRef.nativeElement.scrollIntoView({ behavior: scrollBehavior, block: 'center', inline: 'center' });
|
|
2203
|
+
}
|
|
2204
|
+
scrollBehavior = 'smooth';
|
|
2205
|
+
this.skipNextScroll = false;
|
|
2206
|
+
}));
|
|
2207
|
+
}
|
|
2208
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardStepnavItem, deps: [{ token: WizardNavigationService }, { token: PageCollectionService }, { token: i3.ClrCommonStringsService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2209
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ClrWizardStepnavItem, isStandalone: false, selector: "[clr-wizard-stepnav-item]", inputs: { page: "page" }, host: { listeners: { "focusin": "scrollIntoView()" }, properties: { "id": "id", "attr.aria-current": "stepAriaCurrent", "attr.aria-controls": "page.id", "class.clr-nav-link": "true", "class.nav-item": "true", "class.active": "isCurrent", "class.disabled": "isDisabled", "class.no-click": "!canNavigate", "class.complete": "isComplete", "class.error": "hasError" } }, ngImport: i0, template: `
|
|
2210
|
+
<button
|
|
2211
|
+
type="button"
|
|
2212
|
+
class="btn btn-link clr-wizard-stepnav-link"
|
|
2213
|
+
(click)="click()"
|
|
2214
|
+
[attr.disabled]="isDisabled ? '' : null"
|
|
2215
|
+
[attr.aria-labelledby]="labelledby"
|
|
2216
|
+
>
|
|
2217
|
+
<div class="clr-wizard-stepnav-link-icon">
|
|
2218
|
+
@if (icon; as icon) {
|
|
2219
|
+
<cds-icon
|
|
2220
|
+
[id]="stepIconId"
|
|
2221
|
+
role="img"
|
|
2222
|
+
class="clr-wizard-stepnav-link-icon"
|
|
2223
|
+
[shape]="icon.shape"
|
|
2224
|
+
[attr.aria-label]="icon.label"
|
|
2225
|
+
></cds-icon>
|
|
2226
|
+
}
|
|
2227
|
+
</div>
|
|
2228
|
+
|
|
2229
|
+
<span [id]="stepTextId" class="clr-sr-only">{{ commonStrings.keys.wizardStep }}</span>
|
|
2230
|
+
<div [id]="stepNumberId" class="clr-wizard-stepnav-link-page-number">
|
|
2231
|
+
<ng-content></ng-content>
|
|
2232
|
+
</div>
|
|
2233
|
+
<span [id]="stepTitleId" class="clr-wizard-stepnav-link-title">
|
|
2234
|
+
<ng-template [ngTemplateOutlet]="page.navTitle"></ng-template>
|
|
2235
|
+
</span>
|
|
2236
|
+
</button>
|
|
2237
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i5.ClrIcon, selector: "clr-icon, cds-icon", inputs: ["shape", "size", "direction", "flip", "solid", "status", "inverse", "badge"] }] }); }
|
|
2238
|
+
}
|
|
2239
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardStepnavItem, decorators: [{
|
|
2240
|
+
type: Component,
|
|
2241
|
+
args: [{
|
|
2242
|
+
selector: '[clr-wizard-stepnav-item]',
|
|
2243
|
+
template: `
|
|
2244
|
+
<button
|
|
2245
|
+
type="button"
|
|
2246
|
+
class="btn btn-link clr-wizard-stepnav-link"
|
|
2247
|
+
(click)="click()"
|
|
2248
|
+
[attr.disabled]="isDisabled ? '' : null"
|
|
2249
|
+
[attr.aria-labelledby]="labelledby"
|
|
2250
|
+
>
|
|
2251
|
+
<div class="clr-wizard-stepnav-link-icon">
|
|
2252
|
+
@if (icon; as icon) {
|
|
2253
|
+
<cds-icon
|
|
2254
|
+
[id]="stepIconId"
|
|
2255
|
+
role="img"
|
|
2256
|
+
class="clr-wizard-stepnav-link-icon"
|
|
2257
|
+
[shape]="icon.shape"
|
|
2258
|
+
[attr.aria-label]="icon.label"
|
|
2259
|
+
></cds-icon>
|
|
2260
|
+
}
|
|
2261
|
+
</div>
|
|
2262
|
+
|
|
2263
|
+
<span [id]="stepTextId" class="clr-sr-only">{{ commonStrings.keys.wizardStep }}</span>
|
|
2264
|
+
<div [id]="stepNumberId" class="clr-wizard-stepnav-link-page-number">
|
|
2265
|
+
<ng-content></ng-content>
|
|
2266
|
+
</div>
|
|
2267
|
+
<span [id]="stepTitleId" class="clr-wizard-stepnav-link-title">
|
|
2268
|
+
<ng-template [ngTemplateOutlet]="page.navTitle"></ng-template>
|
|
2269
|
+
</span>
|
|
2270
|
+
</button>
|
|
2271
|
+
`,
|
|
2272
|
+
host: {
|
|
2273
|
+
'[id]': 'id',
|
|
2274
|
+
'[attr.aria-current]': 'stepAriaCurrent',
|
|
2275
|
+
'[attr.aria-controls]': 'page.id',
|
|
2276
|
+
'[class.clr-nav-link]': 'true',
|
|
2277
|
+
'[class.nav-item]': 'true',
|
|
2278
|
+
'[class.active]': 'isCurrent',
|
|
2279
|
+
'[class.disabled]': 'isDisabled',
|
|
2280
|
+
'[class.no-click]': '!canNavigate',
|
|
2281
|
+
'[class.complete]': 'isComplete',
|
|
2282
|
+
'[class.error]': 'hasError',
|
|
2283
|
+
'(focusin)': 'scrollIntoView()',
|
|
2284
|
+
},
|
|
2285
|
+
standalone: false,
|
|
2286
|
+
}]
|
|
2287
|
+
}], ctorParameters: () => [{ type: WizardNavigationService }, { type: PageCollectionService }, { type: i3.ClrCommonStringsService }, { type: i0.ElementRef }], propDecorators: { page: [{
|
|
2288
|
+
type: Input,
|
|
2289
|
+
args: ['page']
|
|
2290
|
+
}] } });
|
|
2291
|
+
|
|
2292
|
+
/*
|
|
2293
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
2294
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
2295
|
+
* This software is released under MIT license.
|
|
2296
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
2297
|
+
*/
|
|
2298
|
+
class ClrWizardStepnav {
|
|
2299
|
+
constructor(pageService, navService, elementRef) {
|
|
2300
|
+
this.pageService = pageService;
|
|
2301
|
+
this.navService = navService;
|
|
2302
|
+
this.elementRef = elementRef;
|
|
2303
|
+
this.showScrollLeftButton = false;
|
|
2304
|
+
this.showScrollRightButton = false;
|
|
2305
|
+
this.firstItemVisible = true;
|
|
2306
|
+
this.lastItemVisible = true;
|
|
2307
|
+
}
|
|
2308
|
+
get stepnavLayout() {
|
|
2309
|
+
return this.navService.stepnavLayout;
|
|
2310
|
+
}
|
|
2311
|
+
ngAfterViewInit() {
|
|
2312
|
+
if (this.stepnavLayout === ClrWizardStepnavLayout.HORIZONTAL) {
|
|
2313
|
+
this.setupIntersectionObserver();
|
|
2314
|
+
this.stepnavItems.notifyOnChanges();
|
|
2315
|
+
this.subscription = this.stepnavItems.changes.pipe(startWith(undefined)).subscribe(() => {
|
|
2316
|
+
this.observeEdgeItems();
|
|
2317
|
+
});
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
ngOnDestroy() {
|
|
2321
|
+
this.subscription?.unsubscribe();
|
|
2322
|
+
this.intersectionObserver?.disconnect();
|
|
2323
|
+
}
|
|
2324
|
+
scrollLeft() {
|
|
2325
|
+
this.scroll('left');
|
|
2326
|
+
}
|
|
2327
|
+
scrollRight() {
|
|
2328
|
+
this.scroll('right');
|
|
2329
|
+
}
|
|
2330
|
+
setupIntersectionObserver() {
|
|
2331
|
+
const scrollContainer = this.elementRef.nativeElement.querySelector('.clr-wizard-stepnav-list');
|
|
2332
|
+
this.intersectionObserver = new IntersectionObserver(entries => {
|
|
2333
|
+
for (const entry of entries) {
|
|
2334
|
+
const target = entry.target;
|
|
2335
|
+
const isFirst = target === this.stepnavItems.first?.elementRef.nativeElement;
|
|
2336
|
+
const isLast = target === this.stepnavItems.last?.elementRef.nativeElement;
|
|
2337
|
+
if (isFirst) {
|
|
2338
|
+
this.firstItemVisible = entry.isIntersecting;
|
|
2339
|
+
}
|
|
2340
|
+
if (isLast) {
|
|
2341
|
+
this.lastItemVisible = entry.isIntersecting;
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
this.showScrollLeftButton = !this.firstItemVisible;
|
|
2345
|
+
this.showScrollRightButton = !this.lastItemVisible;
|
|
2346
|
+
}, { root: scrollContainer, threshold: 0.99 });
|
|
2347
|
+
}
|
|
2348
|
+
observeEdgeItems() {
|
|
2349
|
+
this.intersectionObserver.disconnect();
|
|
2350
|
+
this.firstItemVisible = true;
|
|
2351
|
+
this.lastItemVisible = true;
|
|
2352
|
+
const first = this.stepnavItems.first;
|
|
2353
|
+
const last = this.stepnavItems.last;
|
|
2354
|
+
if (first) {
|
|
2355
|
+
this.intersectionObserver.observe(first.elementRef.nativeElement);
|
|
2356
|
+
}
|
|
2357
|
+
if (last && last !== first) {
|
|
2358
|
+
this.intersectionObserver.observe(last.elementRef.nativeElement);
|
|
2359
|
+
}
|
|
2360
|
+
}
|
|
2361
|
+
scroll(direction) {
|
|
2362
|
+
const scrollContainer = this.elementRef.nativeElement.querySelector('.clr-wizard-stepnav-list');
|
|
2363
|
+
const scrollAmount = scrollContainer.clientWidth * 0.5;
|
|
2364
|
+
scrollContainer.scrollBy({ left: direction === 'left' ? -scrollAmount : scrollAmount, behavior: 'smooth' });
|
|
2365
|
+
}
|
|
2366
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardStepnav, deps: [{ token: PageCollectionService }, { token: WizardNavigationService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2367
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ClrWizardStepnav, isStandalone: false, selector: "clr-wizard-stepnav", inputs: { label: "label" }, host: { classAttribute: "clr-wizard-stepnav" }, viewQueries: [{ propertyName: "stepnavItems", predicate: ClrWizardStepnavItem, descendants: true }], ngImport: i0, template: `
|
|
2368
|
+
@if (showScrollLeftButton && stepnavLayout === 'horizontal') {
|
|
2369
|
+
<button
|
|
2370
|
+
type="button"
|
|
2371
|
+
class="btn btn-sm btn-icon clr-wizard-stepnav-scroll-button-left"
|
|
2372
|
+
(click)="scrollLeft()"
|
|
2373
|
+
tabindex="-1"
|
|
2374
|
+
>
|
|
2375
|
+
<cds-icon shape="angle" direction="left"></cds-icon>
|
|
2376
|
+
</button>
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
<nav
|
|
2380
|
+
class="clr-wizard-stepnav-nav"
|
|
2381
|
+
[ngClass]="{
|
|
2382
|
+
'clr-wizard-stepnav-nav--with-one-scroll-button': showScrollLeftButton || showScrollRightButton,
|
|
2383
|
+
'clr-wizard-stepnav-nav--with-two-scroll-buttons': showScrollLeftButton && showScrollRightButton,
|
|
2384
|
+
}"
|
|
2385
|
+
[attr.aria-label]="label"
|
|
2386
|
+
>
|
|
2387
|
+
<ol class="clr-wizard-stepnav-list">
|
|
2388
|
+
@for (page of pageService.pages; track page; let i = $index) {
|
|
2389
|
+
<li clr-wizard-stepnav-item [page]="page" class="clr-wizard-stepnav-item">
|
|
2390
|
+
{{ i + 1 }}
|
|
2391
|
+
</li>
|
|
2392
|
+
}
|
|
2393
|
+
</ol>
|
|
2394
|
+
</nav>
|
|
2395
|
+
|
|
2396
|
+
@if (showScrollRightButton && stepnavLayout === 'horizontal') {
|
|
2397
|
+
<button
|
|
2398
|
+
type="button"
|
|
2399
|
+
class="btn btn-sm btn-icon clr-wizard-stepnav-scroll-button-right"
|
|
2400
|
+
(click)="scrollRight()"
|
|
2401
|
+
tabindex="-1"
|
|
2402
|
+
>
|
|
2403
|
+
<cds-icon shape="angle" direction="right"></cds-icon>
|
|
2404
|
+
</button>
|
|
2405
|
+
}
|
|
2406
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: i5.ClrIcon, selector: "clr-icon, cds-icon", inputs: ["shape", "size", "direction", "flip", "solid", "status", "inverse", "badge"] }, { kind: "component", type: ClrWizardStepnavItem, selector: "[clr-wizard-stepnav-item]", inputs: ["page"] }] }); }
|
|
2407
|
+
}
|
|
2408
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardStepnav, decorators: [{
|
|
2409
|
+
type: Component,
|
|
2410
|
+
args: [{
|
|
2411
|
+
selector: 'clr-wizard-stepnav',
|
|
2412
|
+
template: `
|
|
2413
|
+
@if (showScrollLeftButton && stepnavLayout === 'horizontal') {
|
|
2414
|
+
<button
|
|
2415
|
+
type="button"
|
|
2416
|
+
class="btn btn-sm btn-icon clr-wizard-stepnav-scroll-button-left"
|
|
2417
|
+
(click)="scrollLeft()"
|
|
2418
|
+
tabindex="-1"
|
|
2419
|
+
>
|
|
2420
|
+
<cds-icon shape="angle" direction="left"></cds-icon>
|
|
2421
|
+
</button>
|
|
2422
|
+
}
|
|
2423
|
+
|
|
2424
|
+
<nav
|
|
2425
|
+
class="clr-wizard-stepnav-nav"
|
|
2426
|
+
[ngClass]="{
|
|
2427
|
+
'clr-wizard-stepnav-nav--with-one-scroll-button': showScrollLeftButton || showScrollRightButton,
|
|
2428
|
+
'clr-wizard-stepnav-nav--with-two-scroll-buttons': showScrollLeftButton && showScrollRightButton,
|
|
2429
|
+
}"
|
|
2430
|
+
[attr.aria-label]="label"
|
|
2431
|
+
>
|
|
2432
|
+
<ol class="clr-wizard-stepnav-list">
|
|
2433
|
+
@for (page of pageService.pages; track page; let i = $index) {
|
|
2434
|
+
<li clr-wizard-stepnav-item [page]="page" class="clr-wizard-stepnav-item">
|
|
2435
|
+
{{ i + 1 }}
|
|
2436
|
+
</li>
|
|
2437
|
+
}
|
|
2438
|
+
</ol>
|
|
2439
|
+
</nav>
|
|
2440
|
+
|
|
2441
|
+
@if (showScrollRightButton && stepnavLayout === 'horizontal') {
|
|
2442
|
+
<button
|
|
2443
|
+
type="button"
|
|
2444
|
+
class="btn btn-sm btn-icon clr-wizard-stepnav-scroll-button-right"
|
|
2445
|
+
(click)="scrollRight()"
|
|
2446
|
+
tabindex="-1"
|
|
2447
|
+
>
|
|
2448
|
+
<cds-icon shape="angle" direction="right"></cds-icon>
|
|
2449
|
+
</button>
|
|
2450
|
+
}
|
|
2451
|
+
`,
|
|
2452
|
+
host: { class: 'clr-wizard-stepnav' },
|
|
2453
|
+
standalone: false,
|
|
2454
|
+
}]
|
|
2455
|
+
}], ctorParameters: () => [{ type: PageCollectionService }, { type: WizardNavigationService }, { type: i0.ElementRef }], propDecorators: { label: [{
|
|
2456
|
+
type: Input
|
|
2457
|
+
}], stepnavItems: [{
|
|
2458
|
+
type: ViewChildren,
|
|
2459
|
+
args: [ClrWizardStepnavItem]
|
|
2460
|
+
}] } });
|
|
2461
|
+
|
|
2462
|
+
/*
|
|
2463
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
2464
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
2465
|
+
* This software is released under MIT license.
|
|
2466
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
2467
|
+
*/
|
|
2468
|
+
class ClrWizard {
|
|
2469
|
+
constructor(platformId, commonStrings, navService, pageCollection, buttonService, headerActionService, elementRef, differs) {
|
|
2470
|
+
this.platformId = platformId;
|
|
2471
|
+
this.commonStrings = commonStrings;
|
|
2472
|
+
this.navService = navService;
|
|
2473
|
+
this.pageCollection = pageCollection;
|
|
2474
|
+
this.buttonService = buttonService;
|
|
2475
|
+
this.headerActionService = headerActionService;
|
|
2476
|
+
this.elementRef = elementRef;
|
|
2477
|
+
/**
|
|
2478
|
+
* Set the aria-label for the stepnav section of the wizard. Set using `[clrWizardStepnavAriaLabel]` input.
|
|
2479
|
+
*/
|
|
2480
|
+
this.stepnavAriaLabel = this.commonStrings.keys.wizardStepnavAriaLabel;
|
|
2481
|
+
/**
|
|
2482
|
+
* Set the wizard stepnav layout to 'vertical' (default) or 'horizontal'. Set using `[clrWizardStepnavLayout]` input.
|
|
2483
|
+
*/
|
|
2484
|
+
this.stepnavLayout = ClrWizardStepnavLayout.VERTICAL;
|
|
2485
|
+
/**
|
|
2486
|
+
* Set the modal size of the wizard. Set using `[clrWizardSize]` input.
|
|
2487
|
+
*/
|
|
2488
|
+
this.size = 'xl';
|
|
2489
|
+
/**
|
|
2490
|
+
* Enable "in page" wizard. Set using `[clrWizardInPage]` input.
|
|
2491
|
+
*/
|
|
2492
|
+
this.inPage = false;
|
|
2493
|
+
/**
|
|
2494
|
+
* Make an "in page" wizard fill the `.content-area`. Set using `[clrWizardInPageFillContentArea]` input.
|
|
2495
|
+
* If you can't use this option, you will likely need to provide custom CSS to set the wizard's height and margins.
|
|
2496
|
+
*/
|
|
2497
|
+
this.inPageFillContentArea = false;
|
|
2498
|
+
/**
|
|
2499
|
+
* Hide the wizard footer entirely. Set using `[clrWizardHideFooter]` input.
|
|
2500
|
+
* Useful when a nested wizard or stepper handles its own navigation.
|
|
2501
|
+
*/
|
|
2502
|
+
this.hideFooter = false;
|
|
2503
|
+
/**
|
|
2504
|
+
* Align the footer buttons to 'start' (left) or 'end' (right).
|
|
2505
|
+
* By default, modal wizards align to 'end' and in-page wizards align to 'start'.
|
|
2506
|
+
* Nested wizards inherit the default unless this input is explicitly set.
|
|
2507
|
+
* Set using `[clrWizardFooterAlign]` input.
|
|
2508
|
+
*/
|
|
2509
|
+
this._footerAlign = null;
|
|
2510
|
+
/**
|
|
2511
|
+
* Tells the modal part of the wizard whether it should have a close "X"
|
|
2512
|
+
* in the top right corner. Set using `[clrWizardClosable]` input.
|
|
2513
|
+
*/
|
|
2514
|
+
this.closable = true;
|
|
2515
|
+
/**
|
|
2516
|
+
* Used to communicate to the underlying modal that animations are not
|
|
2517
|
+
* wanted. Primary use is for the display of static/inline wizards.
|
|
2518
|
+
* Set using `[clrWizardPreventModalAnimation]` input.
|
|
2519
|
+
*/
|
|
2520
|
+
this._stopModalAnimations = false;
|
|
2521
|
+
/**
|
|
2522
|
+
* Emits when the wizard is opened or closed.
|
|
2523
|
+
* Listen via `(clrWizardOpenChange)` event.
|
|
2524
|
+
*/
|
|
2525
|
+
this._openChanged = new EventEmitter(false);
|
|
2526
|
+
/**
|
|
2527
|
+
* Emits when the wizard is canceled. Listen via `(clrWizardOnCancel)` event.
|
|
2528
|
+
* Can be combined with the `[clrWizardPreventDefaultCancel]` input to create
|
|
2529
|
+
* wizard-level custom cancel routines.
|
|
2530
|
+
*/
|
|
2531
|
+
this.onCancel = new EventEmitter(false);
|
|
2532
|
+
/**
|
|
2533
|
+
* Emits when the wizard is completed. Listen via `(clrWizardOnFinish)` event.
|
|
2534
|
+
* Can be combined with the `[clrWizardPreventDefaultNext]` input to create
|
|
2535
|
+
* wizard-level custom completion routines.
|
|
2536
|
+
*/
|
|
2537
|
+
this.wizardFinished = new EventEmitter(false);
|
|
2538
|
+
/**
|
|
2539
|
+
* Emits when the wizard is reset. Listen via `(clrWizardOnReset)` event.
|
|
2540
|
+
*/
|
|
2541
|
+
this.onReset = new EventEmitter(false);
|
|
2542
|
+
/**
|
|
2543
|
+
* Emits when the current page has changed. Listen via `(clrWizardCurrentPageChange)` event.
|
|
2544
|
+
* output. Useful for non-blocking validation.
|
|
2545
|
+
*/
|
|
2546
|
+
this.currentPageChange = new EventEmitter(false);
|
|
2547
|
+
/**
|
|
2548
|
+
* Emits when the wizard moves to the next page. Listen via `(clrWizardOnNext)` event.
|
|
2549
|
+
* Can be combined with the `[clrWizardPreventDefaultNext]` input to create
|
|
2550
|
+
* wizard-level custom navigation routines, which are useful for validation.
|
|
2551
|
+
*/
|
|
2552
|
+
this.onMoveNext = new EventEmitter(false);
|
|
2553
|
+
/**
|
|
2554
|
+
* Emits when the wizard moves to the previous page. Can be useful for validation.
|
|
2555
|
+
* Listen via `(clrWizardOnPrevious)` event.
|
|
2556
|
+
*/
|
|
2557
|
+
this.onMovePrevious = new EventEmitter(false);
|
|
2558
|
+
this._open = false;
|
|
2559
|
+
this.wizardId = uniqueIdFactory();
|
|
2560
|
+
this.ClrWizardFooterAlign = ClrWizardFooterAlign;
|
|
2561
|
+
this.ClrWizardStepnavLayout = ClrWizardStepnavLayout;
|
|
2562
|
+
this._forceForward = false;
|
|
2563
|
+
this._stopNext = false;
|
|
2564
|
+
this._stopCancel = false;
|
|
2565
|
+
this._stopNavigation = false;
|
|
2566
|
+
this._disableStepnav = false;
|
|
2567
|
+
this.subscriptions = [];
|
|
2568
|
+
this.subscriptions.push(this.listenForNextPageChanges(), this.listenForPreviousPageChanges(), this.listenForCancelChanges(), this.listenForFinishedChanges(), this.listenForPageChanges());
|
|
2569
|
+
this.differ = differs.find([]).create(null);
|
|
2570
|
+
}
|
|
2571
|
+
/**
|
|
2572
|
+
* Resets page completed states when navigating backwards.
|
|
2573
|
+
* Set using `[clrWizardForceForwardNavigation]` input.
|
|
2574
|
+
*/
|
|
2575
|
+
get forceForward() {
|
|
2576
|
+
return this._forceForward;
|
|
2577
|
+
}
|
|
2578
|
+
set forceForward(value) {
|
|
2579
|
+
this._forceForward = !!value;
|
|
2580
|
+
this.navService.forceForwardNavigation = value;
|
|
2581
|
+
}
|
|
2582
|
+
/**
|
|
2583
|
+
* Toggles open/close of the wizard component.
|
|
2584
|
+
* Set using the `[clrWizardOpen]` input.
|
|
2585
|
+
*/
|
|
2586
|
+
set clrWizardOpen(open) {
|
|
2587
|
+
if (open) {
|
|
2588
|
+
this.buttonService.buttonsReady = true;
|
|
2589
|
+
}
|
|
2590
|
+
this._open = open;
|
|
2591
|
+
}
|
|
2592
|
+
/**
|
|
2593
|
+
* Prevents ClrWizard from moving to the next page or closing itself on finishing.
|
|
2594
|
+
* Set using the `[clrWizardPreventDefaultNext]` input. Note that using stopNext
|
|
2595
|
+
* will require you to create your own calls to .next() and .finish() in your
|
|
2596
|
+
* host component to make the ClrWizard work as expected.
|
|
2597
|
+
*/
|
|
2598
|
+
get stopNext() {
|
|
2599
|
+
return this._stopNext;
|
|
2600
|
+
}
|
|
2601
|
+
set stopNext(value) {
|
|
2602
|
+
this._stopNext = !!value;
|
|
2603
|
+
this.navService.wizardHasAltNext = value;
|
|
2604
|
+
}
|
|
2605
|
+
/**
|
|
2606
|
+
* Prevents ClrWizard from closing when the cancel button or close "X" is clicked.
|
|
2607
|
+
* Set using the `[clrWizardPreventDefaultCancel]` input.
|
|
2608
|
+
*
|
|
2609
|
+
* Note that using stopCancel will require you to create your own calls to `close()` in your host compone`nt
|
|
2610
|
+
* to make the ClrWizard work as expected. Useful for doing checks or prompts
|
|
2611
|
+
* before closing a ClrWizard.
|
|
2612
|
+
*/
|
|
2613
|
+
get stopCancel() {
|
|
2614
|
+
return this._stopCancel;
|
|
2615
|
+
}
|
|
2616
|
+
set stopCancel(value) {
|
|
2617
|
+
this._stopCancel = !!value;
|
|
2618
|
+
this.navService.wizardHasAltCancel = value;
|
|
2619
|
+
}
|
|
2620
|
+
/**
|
|
2621
|
+
* Prevents ClrWizard from performing any form of navigation away from the current
|
|
2622
|
+
* page. Set using the `[clrWizardPreventNavigation]` input.
|
|
2623
|
+
* Note that stopNavigation is meant to freeze the wizard in place, typically
|
|
2624
|
+
* during a long validation or background action where you want the wizard to
|
|
2625
|
+
* display loading content but not allow the user to execute navigation in
|
|
2626
|
+
* the stepnav, close X, or the back, finish, or next buttons.
|
|
2627
|
+
*/
|
|
2628
|
+
get stopNavigation() {
|
|
2629
|
+
return this._stopNavigation;
|
|
2630
|
+
}
|
|
2631
|
+
set stopNavigation(value) {
|
|
2632
|
+
this._stopNavigation = !!value;
|
|
2633
|
+
this.navService.wizardStopNavigation = value;
|
|
2634
|
+
}
|
|
2635
|
+
/**
|
|
2636
|
+
* Prevents clicks on the links in the stepnav from working.
|
|
2637
|
+
* Set using `[clrWizardDisableStepnav]` input.
|
|
2638
|
+
* A more granular bypassing of navigation which can be useful when your
|
|
2639
|
+
* ClrWizard is in a state of completion and you don't want users to be
|
|
2640
|
+
* able to jump backwards and change things.
|
|
2641
|
+
*/
|
|
2642
|
+
get disableStepnav() {
|
|
2643
|
+
return this._disableStepnav;
|
|
2644
|
+
}
|
|
2645
|
+
set disableStepnav(value) {
|
|
2646
|
+
this._disableStepnav = !!value;
|
|
2647
|
+
this.navService.wizardDisableStepnav = value;
|
|
2648
|
+
}
|
|
2649
|
+
get currentPage() {
|
|
2650
|
+
return this.navService.currentPage;
|
|
2651
|
+
}
|
|
2652
|
+
set currentPage(page) {
|
|
2653
|
+
this.navService.goTo(page, true);
|
|
2654
|
+
}
|
|
2655
|
+
get isLast() {
|
|
2656
|
+
return this.navService.currentPageIsLast;
|
|
2657
|
+
}
|
|
2658
|
+
get isFirst() {
|
|
2659
|
+
return this.navService.currentPageIsFirst;
|
|
2660
|
+
}
|
|
2661
|
+
get isInline() {
|
|
2662
|
+
return this.elementRef.nativeElement.classList.contains('clr-wizard--inline');
|
|
2663
|
+
}
|
|
2664
|
+
get showHeader() {
|
|
2665
|
+
return (!!this.navService.currentPage?.pageTitle ||
|
|
2666
|
+
(this.stepnavLayout === ClrWizardStepnavLayout.VERTICAL && this.headerActionService.displayHeaderActionsWrapper));
|
|
2667
|
+
}
|
|
2668
|
+
get showFooter() {
|
|
2669
|
+
return !this.hideFooter && (this.navService.currentPage?.hasButtons || this.wizardButtons?.length > 0);
|
|
2670
|
+
}
|
|
2671
|
+
get footerAlign() {
|
|
2672
|
+
if (this._footerAlign !== null) {
|
|
2673
|
+
return this._footerAlign;
|
|
2674
|
+
}
|
|
2675
|
+
return this.inPage ? ClrWizardFooterAlign.START : ClrWizardFooterAlign.END;
|
|
2676
|
+
}
|
|
2677
|
+
get stopModalAnimations() {
|
|
2678
|
+
return this._stopModalAnimations;
|
|
2679
|
+
}
|
|
2680
|
+
ngAfterContentInit() {
|
|
2681
|
+
this.navService.stepnavLayout = this.stepnavLayout;
|
|
2682
|
+
this.pageCollection.pages = this.pages;
|
|
2683
|
+
this.headerActionService.wizardHeaderActions = this.headerActions;
|
|
2684
|
+
if (this.inPage) {
|
|
2685
|
+
this.open();
|
|
2686
|
+
}
|
|
2687
|
+
this.initializeButtons();
|
|
2688
|
+
}
|
|
2689
|
+
ngDoCheck() {
|
|
2690
|
+
this.updateNavOnPageChanges();
|
|
2691
|
+
}
|
|
2692
|
+
ngOnDestroy() {
|
|
2693
|
+
this.subscriptions.forEach(s => s.unsubscribe());
|
|
2694
|
+
}
|
|
2695
|
+
/**
|
|
2696
|
+
* Marks Wizard as finished. By default it does not execute event
|
|
2697
|
+
* emissions or checks before completing and closing. This method is commonly
|
|
2698
|
+
* used as part of an alternative navigation with `[clrWizardPreventDefaultNext]`.
|
|
2699
|
+
*
|
|
2700
|
+
* If `skipChecksAndEmits` is true, the wizard will complete and close
|
|
2701
|
+
* regardless of the state of its current page. This is useful for alternative
|
|
2702
|
+
* navigation where event emissions have already been done and firing them again
|
|
2703
|
+
* may cause an event loop.
|
|
2704
|
+
*/
|
|
2705
|
+
finish(skipChecksAndEmits = true) {
|
|
2706
|
+
if (skipChecksAndEmits) {
|
|
2707
|
+
this.forceFinish();
|
|
2708
|
+
}
|
|
2709
|
+
else {
|
|
2710
|
+
this.navService.finish();
|
|
2711
|
+
}
|
|
2712
|
+
}
|
|
2713
|
+
/**
|
|
2714
|
+
* Marks the wizard as finished but does run checks and emissions.
|
|
2715
|
+
* Good for a last step in an alternate workflow. Does the same thing as
|
|
2716
|
+
* calling `ClrWizard.finish(true)` or `ClrWizard.finish()` without a parameter.
|
|
2717
|
+
*/
|
|
2718
|
+
forceFinish() {
|
|
2719
|
+
if (this.stopNavigation) {
|
|
2720
|
+
return;
|
|
2721
|
+
}
|
|
2722
|
+
this.close();
|
|
2723
|
+
}
|
|
2724
|
+
/**
|
|
2725
|
+
* Opens the wizard. If there is no current page defined, sets the first page in the wizard to be current.
|
|
2726
|
+
*/
|
|
2727
|
+
open() {
|
|
2728
|
+
this._open = true;
|
|
2729
|
+
if (!this.currentPage) {
|
|
2730
|
+
this.navService.setFirstPageCurrent();
|
|
2731
|
+
}
|
|
2732
|
+
// Only render buttons when wizard is opened, to avoid chocolate errors
|
|
2733
|
+
this.buttonService.buttonsReady = true;
|
|
2734
|
+
this._openChanged.emit(true);
|
|
2735
|
+
}
|
|
2736
|
+
/**
|
|
2737
|
+
* Closes the wizard. Call this directly instead of `cancel()` to implement alternative cancel functionality.
|
|
2738
|
+
*/
|
|
2739
|
+
close() {
|
|
2740
|
+
if (this.stopNavigation) {
|
|
2741
|
+
return;
|
|
2742
|
+
}
|
|
2743
|
+
this._open = false;
|
|
2744
|
+
this._openChanged.emit(false);
|
|
2745
|
+
}
|
|
2746
|
+
/**
|
|
2747
|
+
* Used to open and close the wizard. By default the wizard will
|
|
2748
|
+
* close if invoked with no parameter. If parameter is true wizard will open
|
|
2749
|
+
* else if false will close.
|
|
2750
|
+
*/
|
|
2751
|
+
toggle(open) {
|
|
2752
|
+
if (open) {
|
|
2753
|
+
this.open();
|
|
2754
|
+
}
|
|
2755
|
+
else {
|
|
2756
|
+
this.close();
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
2759
|
+
/**
|
|
2760
|
+
* Moves the wizard to the previous page.
|
|
2761
|
+
*/
|
|
2762
|
+
previous() {
|
|
2763
|
+
this.navService.previous();
|
|
2764
|
+
}
|
|
2765
|
+
/**
|
|
2766
|
+
* By default, `next()` does not execute event emissions.
|
|
2767
|
+
* This method is commonly called as part of an alternative navigation
|
|
2768
|
+
* with `[clrWizardPreventDefaultNext]`. The wizard will move to the next page
|
|
2769
|
+
* regardless of the state of its current page. This is useful for alternative
|
|
2770
|
+
* navigation where event emissions have already been done and firing them again
|
|
2771
|
+
* may cause an event loop.
|
|
2772
|
+
*
|
|
2773
|
+
* If `skipChecksAndEmits` is false, the wizard will execute default checks
|
|
2774
|
+
* and emit events as normal. This is useful for custom buttons or programmatic
|
|
2775
|
+
* workflows that are not executing the wizards default checks and emissions.
|
|
2776
|
+
* It is another way to navigate without having to rewrite the wizard’s default
|
|
2777
|
+
* functionality from scratch.
|
|
2778
|
+
*/
|
|
2779
|
+
next(skipChecksAndEmits = true) {
|
|
2780
|
+
if (skipChecksAndEmits) {
|
|
2781
|
+
this.forceNext();
|
|
2782
|
+
}
|
|
2783
|
+
else {
|
|
2784
|
+
this.navService.next();
|
|
2785
|
+
}
|
|
2786
|
+
}
|
|
2787
|
+
/**
|
|
2788
|
+
* Moves the wizard to the next page without the checks and emissions.
|
|
2789
|
+
* Good for a last step in an alternate workflow.
|
|
2790
|
+
* Alias for `ClrWizard.next(true)` or `ClrWizard.next()`
|
|
2791
|
+
*/
|
|
2792
|
+
forceNext() {
|
|
2793
|
+
this.navService.forceNext();
|
|
2794
|
+
}
|
|
2795
|
+
/**
|
|
2796
|
+
* Cancels and closes the wizard. Do not use this for an override of the cancel
|
|
2797
|
+
* the functionality with `[clrWizardPreventDefaultCancel]`, `[clrWizardPreventPageDefaultCancel]`,
|
|
2798
|
+
* or `[clrWizardPagePreventDefault]` because it will initiate the same checks
|
|
2799
|
+
* and event emissions that invoked your event handler. Use `ClrWizard.close()` instead.
|
|
2800
|
+
*/
|
|
2801
|
+
cancel() {
|
|
2802
|
+
this.navService.cancel();
|
|
2803
|
+
}
|
|
2804
|
+
/**
|
|
2805
|
+
* Overrides behavior of the underlying modal to avoid collisions with
|
|
2806
|
+
* alternative cancel functionality. In most cases, use `ClrWizard.cancel()` instead.
|
|
2807
|
+
*/
|
|
2808
|
+
modalCancel() {
|
|
2809
|
+
if (this.closable) {
|
|
2810
|
+
this.checkAndCancel();
|
|
2811
|
+
}
|
|
2812
|
+
}
|
|
2813
|
+
/**
|
|
2814
|
+
* Checks for alternative cancel flows defined at the current page or
|
|
2815
|
+
* wizard level. Performs a canceled if not. Emits events that initiate
|
|
2816
|
+
* the alternative cancel outputs `(clrWizardPageOnCancel)` and `(clrWizardOnCancel)`.
|
|
2817
|
+
*/
|
|
2818
|
+
checkAndCancel() {
|
|
2819
|
+
const currentPage = this.currentPage;
|
|
2820
|
+
const currentPageHasOverrides = currentPage.stopCancel || currentPage.preventDefault;
|
|
2821
|
+
if (this.stopNavigation) {
|
|
2822
|
+
return;
|
|
2823
|
+
}
|
|
2824
|
+
currentPage.pageOnCancel.emit();
|
|
2825
|
+
if (!currentPageHasOverrides) {
|
|
2826
|
+
this.onCancel.emit();
|
|
2827
|
+
}
|
|
2828
|
+
if (!this.stopCancel && !currentPageHasOverrides) {
|
|
2829
|
+
this.close();
|
|
2830
|
+
}
|
|
2831
|
+
}
|
|
2832
|
+
/**
|
|
2833
|
+
* Navigates to a given page in the Wizard. Navigation will invoke the wizard’s default
|
|
2834
|
+
* checks and event emissions.
|
|
2835
|
+
*
|
|
2836
|
+
* The format of the expected ID parameter can be found in the return of the
|
|
2837
|
+
* ClrWizardPage.id getter, usually prefixed with `clr-wizard-page-` and then either a
|
|
2838
|
+
* numeric ID or the ID specified for the `ClrWizardPage` component’s `id` input.
|
|
2839
|
+
*/
|
|
2840
|
+
goTo(pageId) {
|
|
2841
|
+
if (!pageId) {
|
|
2842
|
+
return;
|
|
2843
|
+
}
|
|
2844
|
+
this.navService.goTo(pageId);
|
|
2845
|
+
}
|
|
2846
|
+
/**
|
|
2847
|
+
* Reset sets all WizardPages to incomplete and sets the first page in the `ClrWizard` to
|
|
2848
|
+
* be the current page, resetting the wizard navigation.
|
|
2849
|
+
* Use `(clrWizardOnReset)` event to reset the data or model of your wizard.
|
|
2850
|
+
*/
|
|
2851
|
+
reset() {
|
|
2852
|
+
this.pageCollection.reset();
|
|
2853
|
+
this.onReset.emit();
|
|
2854
|
+
}
|
|
2855
|
+
listenForNextPageChanges() {
|
|
2856
|
+
return this.navService.movedToNextPage.pipe(filter(() => isPlatformBrowser(this.platformId))).subscribe(() => {
|
|
2857
|
+
this.onMoveNext.emit();
|
|
2858
|
+
this.pageTitle?.nativeElement.focus();
|
|
2859
|
+
});
|
|
2860
|
+
}
|
|
2861
|
+
listenForPreviousPageChanges() {
|
|
2862
|
+
return this.navService.movedToPreviousPage.pipe(filter(() => isPlatformBrowser(this.platformId))).subscribe(() => {
|
|
2863
|
+
this.onMovePrevious.emit();
|
|
2864
|
+
this.pageTitle?.nativeElement.focus();
|
|
2865
|
+
});
|
|
2866
|
+
}
|
|
2867
|
+
listenForCancelChanges() {
|
|
2868
|
+
return this.navService.notifyWizardCancel.subscribe(() => this.checkAndCancel());
|
|
2869
|
+
}
|
|
2870
|
+
listenForFinishedChanges() {
|
|
2871
|
+
return this.navService.wizardFinished.subscribe(() => this.emitWizardFinished());
|
|
2872
|
+
}
|
|
2873
|
+
listenForPageChanges() {
|
|
2874
|
+
return this.navService.currentPageChange.subscribe(() => {
|
|
2875
|
+
// Added to address VPAT-749:
|
|
2876
|
+
// When clicking on a wizard tab, focus should move to that
|
|
2877
|
+
// tabs content to make the wizard more accessible.
|
|
2878
|
+
this.pageTitle?.nativeElement.focus();
|
|
2879
|
+
this.currentPageChange.emit();
|
|
2880
|
+
// scroll to top of page in case there is long page content
|
|
2881
|
+
this.bodyElementRef?.nativeElement.scrollTo(0, 0);
|
|
2882
|
+
});
|
|
2883
|
+
}
|
|
2884
|
+
updateNavOnPageChanges() {
|
|
2885
|
+
const changes = this.differ.diff(this.pages);
|
|
2886
|
+
if (changes) {
|
|
2887
|
+
changes.forEachAddedItem(() => this.navService.updateNavigation());
|
|
2888
|
+
changes.forEachRemovedItem(() => this.navService.updateNavigation());
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
initializeButtons() {
|
|
2892
|
+
// Only trigger buttons ready if default is open (inlined)
|
|
2893
|
+
if (this._open) {
|
|
2894
|
+
this.buttonService.buttonsReady = true;
|
|
2895
|
+
}
|
|
2896
|
+
}
|
|
2897
|
+
emitWizardFinished() {
|
|
2898
|
+
if (!this.stopNext) {
|
|
2899
|
+
this.forceFinish();
|
|
2900
|
+
}
|
|
2901
|
+
this.wizardFinished.emit();
|
|
2902
|
+
}
|
|
2903
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizard, deps: [{ token: PLATFORM_ID }, { token: i3.ClrCommonStringsService }, { token: WizardNavigationService }, { token: PageCollectionService }, { token: ButtonHubService }, { token: HeaderActionService }, { token: i0.ElementRef }, { token: i0.IterableDiffers }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2904
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ClrWizard, isStandalone: false, selector: "clr-wizard", inputs: { stepnavAriaLabel: ["clrWizardStepnavAriaLabel", "stepnavAriaLabel"], stepnavLayout: ["clrWizardStepnavLayout", "stepnavLayout", stepnavLayoutAttribute], size: ["clrWizardSize", "size"], inPage: ["clrWizardInPage", "inPage"], inPageFillContentArea: ["clrWizardInPageFillContentArea", "inPageFillContentArea"], hideFooter: ["clrWizardHideFooter", "hideFooter"], _footerAlign: ["clrWizardFooterAlign", "_footerAlign", footerAlignAttribute], closable: ["clrWizardClosable", "closable"], _stopModalAnimations: ["clrWizardPreventModalAnimation", "_stopModalAnimations"], forceForward: ["clrWizardForceForwardNavigation", "forceForward"], clrWizardOpen: "clrWizardOpen", stopNext: ["clrWizardPreventDefaultNext", "stopNext"], stopCancel: ["clrWizardPreventDefaultCancel", "stopCancel"], stopNavigation: ["clrWizardPreventNavigation", "stopNavigation"], disableStepnav: ["clrWizardDisableStepnav", "disableStepnav"] }, outputs: { _openChanged: "clrWizardOpenChange", onCancel: "clrWizardOnCancel", wizardFinished: "clrWizardOnFinish", onReset: "clrWizardOnReset", currentPageChange: "clrWizardCurrentPageChange", onMoveNext: "clrWizardOnNext", onMovePrevious: "clrWizardOnPrevious" }, host: { properties: { "class.clr-wizard": "true", "class.wizard-md": "size == 'md'", "class.wizard-lg": "size == 'lg'", "class.wizard-xl": "size == 'xl'", "class.wizard-in-page": "inPage", "class.wizard-in-page--fill-content-area": "inPage && inPageFillContentArea", "class.wizard-horizontal": "stepnavLayout === ClrWizardStepnavLayout.HORIZONTAL" } }, providers: [WizardNavigationService, PageCollectionService, ButtonHubService, HeaderActionService], queries: [{ propertyName: "wizardTitle", first: true, predicate: ClrWizardTitle, descendants: true }, { propertyName: "pages", predicate: ClrWizardPage }, { propertyName: "wizardButtons", predicate: ClrWizardButton }, { propertyName: "headerActions", predicate: ClrWizardHeaderAction }], viewQueries: [{ propertyName: "pageTitle", first: true, predicate: ["pageTitle"], descendants: true }, { propertyName: "bodyElementRef", first: true, predicate: ["body"], descendants: true }], ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n<ng-template #coreWizardContent>\n <div class=\"clr-wizard-content-wrapper\">\n @if (stepnavLayout === ClrWizardStepnavLayout.HORIZONTAL) {\n <div class=\"clr-wizard-title-wrapper\">\n <ng-container [ngTemplateOutlet]=\"wizardTitleTemplate\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"wizardActionsTemplate\"></ng-container>\n </div>\n }\n\n <div class=\"clr-wizard-stepnav-wrapper\" role=\"region\">\n @if (stepnavLayout === ClrWizardStepnavLayout.VERTICAL) {\n <ng-container [ngTemplateOutlet]=\"wizardTitleTemplate\"></ng-container>\n }\n <clr-wizard-stepnav [label]=\"stepnavAriaLabel\"></clr-wizard-stepnav>\n </div>\n\n <div class=\"clr-wizard-main-content\">\n @if (showHeader) {\n <div class=\"clr-wizard-header\">\n @if (navService.currentPage?.pageTitle) {\n <div class=\"clr-wizard-page-title-wrapper\" cdkFocusInitial tabindex=\"-1\">\n <div\n class=\"clr-wizard-page-title\"\n role=\"heading\"\n [attr.aria-level]=\"navService.currentPage?.pageTitle?.headingLevel || 2\"\n >\n <span tabindex=\"-1\" #pageTitle class=\"clr-wizard-page-title-text\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPageTitle\"></ng-template>\n </span>\n </div>\n </div>\n } @if (stepnavLayout === ClrWizardStepnavLayout.VERTICAL) {\n <ng-container [ngTemplateOutlet]=\"wizardActionsTemplate\"></ng-container>\n }\n </div>\n }\n\n <div #body class=\"clr-wizard-body-wrapper\">\n <div class=\"clr-wizard-body\">\n <main clr-wizard-pages-wrapper class=\"clr-wizard-content\">\n <ng-content></ng-content>\n </main>\n </div>\n </div>\n\n @if (showFooter) {\n <div class=\"clr-wizard-footer\">\n <div class=\"clr-wizard-footer-buttons\">\n <div\n class=\"clr-wizard-footer-buttons-wrapper\"\n [ngClass]=\"{'align-start': footerAlign === ClrWizardFooterAlign.START, 'align-end': footerAlign === ClrWizardFooterAlign.END}\"\n >\n @if (navService.currentPage?.hasButtons) {\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.buttons\"></ng-template>\n } @else {\n <ng-content select=\"clr-wizard-button\"></ng-content>\n }\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n</ng-template>\n\n<ng-template #wizardTitleTemplate>\n <div class=\"clr-wizard-title\" [id]=\"wizardId\" role=\"heading\" [attr.aria-level]=\"wizardTitle?.headingLevel || 1\">\n <ng-content select=\"clr-wizard-title\"></ng-content>\n </div>\n</ng-template>\n\n<ng-template #wizardActionsTemplate>\n @if (headerActionService.displayHeaderActionsWrapper) {\n <div class=\"clr-wizard-header-actions-wrapper\">\n @if (headerActionService.showWizardHeaderActions) {\n <ng-content select=\"clr-wizard-header-action\"></ng-content>\n } @if (headerActionService.currentPageHasHeaderActions) {\n <ng-template [ngTemplateOutlet]=\"navService.currentPage?.headerActions\"></ng-template>\n }\n </div>\n } @if (closable && !inPage) {\n <button type=\"button\" class=\"close\" [attr.aria-label]=\"commonStrings.keys.close\" (click)=\"modalCancel()\">\n <cds-icon shape=\"window-close\"></cds-icon>\n </button>\n }\n</ng-template>\n\n@if (inPage) {\n<ng-container [ngTemplateOutlet]=\"coreWizardContent\"></ng-container>\n} @else {\n<clr-modal\n [clrModalOpen]=\"_open\"\n [clrModalSize]=\"size\"\n [clrModalClosable]=\"closable\"\n [clrModalStaticBackdrop]=\"true\"\n [clrModalSkipAnimation]=\"stopModalAnimations\"\n [clrModalOverrideScrollService]=\"isInline\"\n [clrModalPreventClose]=\"true\"\n (clrModalAlternateClose)=\"modalCancel()\"\n [clrModalLabelledById]=\"wizardId\"\n>\n <ng-template #clrInternalModalContentTemplate>\n <ng-container [ngTemplateOutlet]=\"coreWizardContent\"></ng-container>\n </ng-template>\n</clr-modal>\n}\n", dependencies: [{ kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i5.ClrIcon, selector: "clr-icon, cds-icon", inputs: ["shape", "size", "direction", "flip", "solid", "status", "inverse", "badge"] }, { kind: "component", type: i8.ClrModal, selector: "clr-modal", inputs: ["clrModalOpen", "clrModalClosable", "clrModalCloseButtonAriaLabel", "clrModalSize", "clrModalStaticBackdrop", "clrModalSkipAnimation", "clrModalPreventClose", "clrModalLabelledById", "clrModalOverrideScrollService"], outputs: ["clrModalOpenChange", "clrModalAlternateClose"] }, { kind: "component", type: ClrWizardStepnav, selector: "clr-wizard-stepnav", inputs: ["label"] }] }); }
|
|
2905
|
+
}
|
|
2906
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizard, decorators: [{
|
|
2907
|
+
type: Component,
|
|
2908
|
+
args: [{ selector: 'clr-wizard', providers: [WizardNavigationService, PageCollectionService, ButtonHubService, HeaderActionService], host: {
|
|
2909
|
+
'[class.clr-wizard]': 'true',
|
|
2910
|
+
'[class.wizard-md]': "size == 'md'",
|
|
2911
|
+
'[class.wizard-lg]': "size == 'lg'",
|
|
2912
|
+
'[class.wizard-xl]': "size == 'xl'",
|
|
2913
|
+
'[class.wizard-in-page]': 'inPage',
|
|
2914
|
+
'[class.wizard-in-page--fill-content-area]': 'inPage && inPageFillContentArea',
|
|
2915
|
+
'[class.wizard-horizontal]': 'stepnavLayout === ClrWizardStepnavLayout.HORIZONTAL',
|
|
2916
|
+
}, standalone: false, template: "<!--\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n<ng-template #coreWizardContent>\n <div class=\"clr-wizard-content-wrapper\">\n @if (stepnavLayout === ClrWizardStepnavLayout.HORIZONTAL) {\n <div class=\"clr-wizard-title-wrapper\">\n <ng-container [ngTemplateOutlet]=\"wizardTitleTemplate\"></ng-container>\n <ng-container [ngTemplateOutlet]=\"wizardActionsTemplate\"></ng-container>\n </div>\n }\n\n <div class=\"clr-wizard-stepnav-wrapper\" role=\"region\">\n @if (stepnavLayout === ClrWizardStepnavLayout.VERTICAL) {\n <ng-container [ngTemplateOutlet]=\"wizardTitleTemplate\"></ng-container>\n }\n <clr-wizard-stepnav [label]=\"stepnavAriaLabel\"></clr-wizard-stepnav>\n </div>\n\n <div class=\"clr-wizard-main-content\">\n @if (showHeader) {\n <div class=\"clr-wizard-header\">\n @if (navService.currentPage?.pageTitle) {\n <div class=\"clr-wizard-page-title-wrapper\" cdkFocusInitial tabindex=\"-1\">\n <div\n class=\"clr-wizard-page-title\"\n role=\"heading\"\n [attr.aria-level]=\"navService.currentPage?.pageTitle?.headingLevel || 2\"\n >\n <span tabindex=\"-1\" #pageTitle class=\"clr-wizard-page-title-text\">\n <ng-template [ngTemplateOutlet]=\"navService.currentPageTitle\"></ng-template>\n </span>\n </div>\n </div>\n } @if (stepnavLayout === ClrWizardStepnavLayout.VERTICAL) {\n <ng-container [ngTemplateOutlet]=\"wizardActionsTemplate\"></ng-container>\n }\n </div>\n }\n\n <div #body class=\"clr-wizard-body-wrapper\">\n <div class=\"clr-wizard-body\">\n <main clr-wizard-pages-wrapper class=\"clr-wizard-content\">\n <ng-content></ng-content>\n </main>\n </div>\n </div>\n\n @if (showFooter) {\n <div class=\"clr-wizard-footer\">\n <div class=\"clr-wizard-footer-buttons\">\n <div\n class=\"clr-wizard-footer-buttons-wrapper\"\n [ngClass]=\"{'align-start': footerAlign === ClrWizardFooterAlign.START, 'align-end': footerAlign === ClrWizardFooterAlign.END}\"\n >\n @if (navService.currentPage?.hasButtons) {\n <ng-template [ngTemplateOutlet]=\"navService.currentPage.buttons\"></ng-template>\n } @else {\n <ng-content select=\"clr-wizard-button\"></ng-content>\n }\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n</ng-template>\n\n<ng-template #wizardTitleTemplate>\n <div class=\"clr-wizard-title\" [id]=\"wizardId\" role=\"heading\" [attr.aria-level]=\"wizardTitle?.headingLevel || 1\">\n <ng-content select=\"clr-wizard-title\"></ng-content>\n </div>\n</ng-template>\n\n<ng-template #wizardActionsTemplate>\n @if (headerActionService.displayHeaderActionsWrapper) {\n <div class=\"clr-wizard-header-actions-wrapper\">\n @if (headerActionService.showWizardHeaderActions) {\n <ng-content select=\"clr-wizard-header-action\"></ng-content>\n } @if (headerActionService.currentPageHasHeaderActions) {\n <ng-template [ngTemplateOutlet]=\"navService.currentPage?.headerActions\"></ng-template>\n }\n </div>\n } @if (closable && !inPage) {\n <button type=\"button\" class=\"close\" [attr.aria-label]=\"commonStrings.keys.close\" (click)=\"modalCancel()\">\n <cds-icon shape=\"window-close\"></cds-icon>\n </button>\n }\n</ng-template>\n\n@if (inPage) {\n<ng-container [ngTemplateOutlet]=\"coreWizardContent\"></ng-container>\n} @else {\n<clr-modal\n [clrModalOpen]=\"_open\"\n [clrModalSize]=\"size\"\n [clrModalClosable]=\"closable\"\n [clrModalStaticBackdrop]=\"true\"\n [clrModalSkipAnimation]=\"stopModalAnimations\"\n [clrModalOverrideScrollService]=\"isInline\"\n [clrModalPreventClose]=\"true\"\n (clrModalAlternateClose)=\"modalCancel()\"\n [clrModalLabelledById]=\"wizardId\"\n>\n <ng-template #clrInternalModalContentTemplate>\n <ng-container [ngTemplateOutlet]=\"coreWizardContent\"></ng-container>\n </ng-template>\n</clr-modal>\n}\n" }]
|
|
2917
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
2918
|
+
type: Inject,
|
|
2919
|
+
args: [PLATFORM_ID]
|
|
2920
|
+
}] }, { type: i3.ClrCommonStringsService }, { type: WizardNavigationService }, { type: PageCollectionService }, { type: ButtonHubService }, { type: HeaderActionService }, { type: i0.ElementRef }, { type: i0.IterableDiffers }], propDecorators: { stepnavAriaLabel: [{
|
|
2921
|
+
type: Input,
|
|
2922
|
+
args: ['clrWizardStepnavAriaLabel']
|
|
2923
|
+
}], stepnavLayout: [{
|
|
2924
|
+
type: Input,
|
|
2925
|
+
args: [{ alias: 'clrWizardStepnavLayout', transform: stepnavLayoutAttribute }]
|
|
2926
|
+
}], size: [{
|
|
2927
|
+
type: Input,
|
|
2928
|
+
args: ['clrWizardSize']
|
|
2929
|
+
}], inPage: [{
|
|
2930
|
+
type: Input,
|
|
2931
|
+
args: ['clrWizardInPage']
|
|
2932
|
+
}], inPageFillContentArea: [{
|
|
2933
|
+
type: Input,
|
|
2934
|
+
args: ['clrWizardInPageFillContentArea']
|
|
2935
|
+
}], hideFooter: [{
|
|
2936
|
+
type: Input,
|
|
2937
|
+
args: ['clrWizardHideFooter']
|
|
2938
|
+
}], _footerAlign: [{
|
|
2939
|
+
type: Input,
|
|
2940
|
+
args: [{ alias: 'clrWizardFooterAlign', transform: footerAlignAttribute }]
|
|
2941
|
+
}], closable: [{
|
|
2942
|
+
type: Input,
|
|
2943
|
+
args: ['clrWizardClosable']
|
|
2944
|
+
}], _stopModalAnimations: [{
|
|
2945
|
+
type: Input,
|
|
2946
|
+
args: ['clrWizardPreventModalAnimation']
|
|
2947
|
+
}], _openChanged: [{
|
|
2948
|
+
type: Output,
|
|
2949
|
+
args: ['clrWizardOpenChange']
|
|
2950
|
+
}], onCancel: [{
|
|
2951
|
+
type: Output,
|
|
2952
|
+
args: ['clrWizardOnCancel']
|
|
2953
|
+
}], wizardFinished: [{
|
|
2954
|
+
type: Output,
|
|
2955
|
+
args: ['clrWizardOnFinish']
|
|
2956
|
+
}], onReset: [{
|
|
2957
|
+
type: Output,
|
|
2958
|
+
args: ['clrWizardOnReset']
|
|
2959
|
+
}], currentPageChange: [{
|
|
2960
|
+
type: Output,
|
|
2961
|
+
args: ['clrWizardCurrentPageChange']
|
|
2962
|
+
}], onMoveNext: [{
|
|
2963
|
+
type: Output,
|
|
2964
|
+
args: ['clrWizardOnNext']
|
|
2965
|
+
}], onMovePrevious: [{
|
|
2966
|
+
type: Output,
|
|
2967
|
+
args: ['clrWizardOnPrevious']
|
|
2968
|
+
}], pageTitle: [{
|
|
2969
|
+
type: ViewChild,
|
|
2970
|
+
args: ['pageTitle']
|
|
2971
|
+
}], pages: [{
|
|
2972
|
+
type: ContentChildren,
|
|
2973
|
+
args: [ClrWizardPage]
|
|
2974
|
+
}], wizardButtons: [{
|
|
2975
|
+
type: ContentChildren,
|
|
2976
|
+
args: [ClrWizardButton, { descendants: false }]
|
|
2977
|
+
}], headerActions: [{
|
|
2978
|
+
type: ContentChildren,
|
|
2979
|
+
args: [ClrWizardHeaderAction]
|
|
2980
|
+
}], wizardTitle: [{
|
|
2981
|
+
type: ContentChild,
|
|
2982
|
+
args: [ClrWizardTitle]
|
|
2983
|
+
}], bodyElementRef: [{
|
|
2984
|
+
type: ViewChild,
|
|
2985
|
+
args: ['body']
|
|
2986
|
+
}], forceForward: [{
|
|
2987
|
+
type: Input,
|
|
2988
|
+
args: ['clrWizardForceForwardNavigation']
|
|
2989
|
+
}], clrWizardOpen: [{
|
|
2990
|
+
type: Input,
|
|
2991
|
+
args: ['clrWizardOpen']
|
|
2992
|
+
}], stopNext: [{
|
|
2993
|
+
type: Input,
|
|
2994
|
+
args: ['clrWizardPreventDefaultNext']
|
|
2995
|
+
}], stopCancel: [{
|
|
2996
|
+
type: Input,
|
|
2997
|
+
args: ['clrWizardPreventDefaultCancel']
|
|
2998
|
+
}], stopNavigation: [{
|
|
2999
|
+
type: Input,
|
|
3000
|
+
args: ['clrWizardPreventNavigation']
|
|
3001
|
+
}], disableStepnav: [{
|
|
3002
|
+
type: Input,
|
|
3003
|
+
args: ['clrWizardDisableStepnav']
|
|
3004
|
+
}] } });
|
|
3005
|
+
|
|
3006
|
+
/*
|
|
3007
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
3008
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
3009
|
+
* This software is released under MIT license.
|
|
3010
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
3011
|
+
*/
|
|
3012
|
+
const CLR_WIZARD_DIRECTIVES = [
|
|
3013
|
+
ClrWizard,
|
|
3014
|
+
ClrWizardPage,
|
|
3015
|
+
ClrWizardStepnav,
|
|
3016
|
+
ClrWizardStepnavItem,
|
|
3017
|
+
ClrWizardButton,
|
|
3018
|
+
ClrWizardHeaderAction,
|
|
3019
|
+
ClrWizardTitle,
|
|
3020
|
+
ClrWizardPageTitle,
|
|
3021
|
+
ClrWizardPageNavTitle,
|
|
3022
|
+
ClrWizardPageButtons,
|
|
3023
|
+
ClrWizardPageHeaderActions,
|
|
3024
|
+
];
|
|
3025
|
+
class ClrWizardModule {
|
|
3026
|
+
constructor() {
|
|
3027
|
+
ClarityIcons.addIcons(errorStandardIcon, successStandardIcon);
|
|
3028
|
+
}
|
|
3029
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
3030
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardModule, declarations: [ClrWizard,
|
|
3031
|
+
ClrWizardPage,
|
|
3032
|
+
ClrWizardStepnav,
|
|
3033
|
+
ClrWizardStepnavItem,
|
|
3034
|
+
ClrWizardButton,
|
|
3035
|
+
ClrWizardHeaderAction,
|
|
3036
|
+
ClrWizardTitle,
|
|
3037
|
+
ClrWizardPageTitle,
|
|
3038
|
+
ClrWizardPageNavTitle,
|
|
3039
|
+
ClrWizardPageButtons,
|
|
3040
|
+
ClrWizardPageHeaderActions], imports: [CommonModule, ClrIcon, ClrModalModule, ClrAlertModule], exports: [ClrWizard,
|
|
3041
|
+
ClrWizardPage,
|
|
3042
|
+
ClrWizardStepnav,
|
|
3043
|
+
ClrWizardStepnavItem,
|
|
3044
|
+
ClrWizardButton,
|
|
3045
|
+
ClrWizardHeaderAction,
|
|
3046
|
+
ClrWizardTitle,
|
|
3047
|
+
ClrWizardPageTitle,
|
|
3048
|
+
ClrWizardPageNavTitle,
|
|
3049
|
+
ClrWizardPageButtons,
|
|
3050
|
+
ClrWizardPageHeaderActions] }); }
|
|
3051
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardModule, imports: [CommonModule, ClrIcon, ClrModalModule, ClrAlertModule] }); }
|
|
3052
|
+
}
|
|
3053
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrWizardModule, decorators: [{
|
|
3054
|
+
type: NgModule,
|
|
3055
|
+
args: [{
|
|
3056
|
+
imports: [CommonModule, ClrIcon, ClrModalModule, ClrAlertModule],
|
|
3057
|
+
declarations: [CLR_WIZARD_DIRECTIVES],
|
|
3058
|
+
exports: [CLR_WIZARD_DIRECTIVES],
|
|
3059
|
+
}]
|
|
3060
|
+
}], ctorParameters: () => [] });
|
|
3061
|
+
|
|
3062
|
+
/*
|
|
3063
|
+
* Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
|
|
3064
|
+
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
|
|
3065
|
+
* This software is released under MIT license.
|
|
3066
|
+
* The full license information can be found in LICENSE in the root directory of this project.
|
|
3067
|
+
*/
|
|
3068
|
+
|
|
3069
|
+
/**
|
|
3070
|
+
* Generated bundle index. Do not edit.
|
|
3071
|
+
*/
|
|
3072
|
+
|
|
3073
|
+
export { CLR_WIZARD_DIRECTIVES, CUSTOM_BUTTON_TYPES, ClrWizard, ClrWizardButton, ClrWizardFooterAlign, ClrWizardHeaderAction, ClrWizardModule, ClrWizardPage, ClrWizardPageButtons, ClrWizardPageHeaderActions, ClrWizardPageNavTitle, ClrWizardPageTitle, ClrWizardStepnav, ClrWizardStepnavItem, ClrWizardStepnavLayout, ClrWizardTitle, DEFAULT_BUTTON_TYPES, footerAlignAttribute, stepnavLayoutAttribute };
|
|
3074
|
+
//# sourceMappingURL=clr-angular-wizard.mjs.map
|