-
Notifications
You must be signed in to change notification settings - Fork 98
/
wizard.component.ts
220 lines (203 loc) · 6.98 KB
/
wizard.component.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
import {
AfterContentInit,
Component,
ContentChildren,
HostBinding,
Input,
OnChanges,
QueryList,
SimpleChanges,
ViewEncapsulation,
Inject,
Optional
} from '@angular/core';
import {NavigationMode} from '../navigation/navigation-mode.interface';
import {NavigationModeInput} from '../navigation/navigation-mode-input.interface';
import {NavigationModeFactory, NAVIGATION_MODE_FACTORY} from '../navigation/navigation-mode-factory.interface';
import {BaseNavigationModeFactory} from '../navigation/base-navigation-mode-factory.provider';
import {WizardState} from '../navigation/wizard-state.model';
import {WizardStep} from '../util/wizard-step.interface';
/**
* The `aw-wizard` component defines the root component of a wizard.
* Through the setting of input parameters for the `aw-wizard` component it's possible to change the location and size
* of its navigation bar.
*
* ### Syntax
* ```html
* <aw-wizard [navBarLocation]="location of navigation bar" [navBarLayout]="layout of navigation bar">
* ...
* </aw-wizard>
* ```
*
* ### Example
*
* Without completion step:
*
* ```html
* <aw-wizard navBarLocation="top" navBarLayout="small">
* <aw-wizard-step>...</aw-wizard-step>
* <aw-wizard-step>...</aw-wizard-step>
* </aw-wizard>
* ```
*
* With completion step:
*
* ```html
* <aw-wizard navBarLocation="top" navBarLayout="small">
* <aw-wizard-step>...</aw-wizard-step>
* <aw-wizard-step>...</aw-wizard-step>
* <aw-wizard-completion-step>...</aw-wizard-completion-step>
* </aw-wizard>
* ```
*
* @author Marc Arndt
*/
@Component({
selector: 'aw-wizard',
templateUrl: 'wizard.component.html',
styleUrls: ['wizard.component.less'],
encapsulation: ViewEncapsulation.None,
providers: [WizardState]
})
export class WizardComponent implements OnChanges, AfterContentInit {
/**
* A QueryList containing all [[WizardStep]]s inside this wizard
*/
@ContentChildren(WizardStep)
public wizardSteps: QueryList<WizardStep>;
/**
* The location of the navigation bar inside the wizard.
* This location can be either top, bottom, left or right
*/
@Input()
public navBarLocation = 'top';
/**
* The layout of the navigation bar inside the wizard.
* The layout can be either small, large-filled, large-empty or large-symbols
*/
@Input()
public navBarLayout = 'small';
/**
* The direction in which the steps inside the navigation bar should be shown.
* The direction can be either `left-to-right` or `right-to-left`
*/
@Input()
public navBarDirection = 'left-to-right';
/**
* The navigation mode used for transitioning between different steps.
*
* The input value can be either a navigation mode name or a function.
*
* A set of supported mode names is determined by the configured navigation mode factory.
* The default navigation mode factory recognizes `strict`, `semi-strict` and `free`.
*
* If the value is a function, the function will be called during the initialization of the wizard
* component and must return an instance of [[NavigationMode]] to be used in the component.
*
* If the input is not configured or set to a falsy value, a default mode will be chosen by the navigation mode factory.
* For the default navigation mode factory, the default mode is `strict`.
*/
@Input()
public navigationMode: NavigationModeInput;
/**
* The initially selected step, represented by its index
*/
@Input()
public defaultStepIndex = 0;
/**
* True, if the navigation bar shouldn't be used for navigating
*/
@Input()
public disableNavigationBar = false;
/**
* Constructor
*
* @param model The model for this wizard component
* @param navigationModeFactory Navigation mode factory for this wizard component
*/
constructor(
public model: WizardState,
// Using @Optional() in order not to break applications which import ArchwizardModule without calling forRoot().
@Optional() @Inject(NAVIGATION_MODE_FACTORY) private navigationModeFactory: NavigationModeFactory) {
if (!this.navigationModeFactory) {
this.navigationModeFactory = new BaseNavigationModeFactory();
}
}
/**
* Returns true if this wizard uses a horizontal orientation.
* The wizard uses a horizontal orientation, iff the navigation bar is shown at the top or bottom of this wizard
*
* @returns True if this wizard uses a horizontal orientation
*/
@HostBinding('class.horizontal')
public get horizontalOrientation(): boolean {
return this.navBarLocation === 'top' || this.navBarLocation === 'bottom';
}
/**
* Returns true if this wizard uses a vertical orientation.
* The wizard uses a vertical orientation, iff the navigation bar is shown at the left or right of this wizard
*
* @returns True if this wizard uses a vertical orientation
*/
@HostBinding('class.vertical')
public get verticalOrientation(): boolean {
return this.navBarLocation === 'left' || this.navBarLocation === 'right';
}
/**
* The navigation mode for this wizard
*/
public get navigation(): NavigationMode {
return this.model.navigationMode;
}
/**
* Updates the model after certain input values have changed
*
* @param changes The detected changes
*/
public ngOnChanges(changes: SimpleChanges) {
for (const propName of Object.keys(changes)) {
const change = changes[propName];
if (!change.firstChange) {
switch (propName) {
case 'defaultStepIndex':
this.model.defaultStepIndex = parseInt(change.currentValue, 10);
break;
case 'disableNavigationBar':
this.model.disableNavigationBar = change.currentValue;
break;
case 'navigationMode':
this.updateNavigationMode(change.currentValue);
break;
/* istanbul ignore next */
default:
}
}
}
}
/**
* Initialization work
*/
public ngAfterContentInit(): void {
// add a subscriber to the wizard steps QueryList to listen to changes in the DOM
this.wizardSteps.changes.subscribe(changedWizardSteps => {
this.model.updateWizardSteps(changedWizardSteps.toArray());
});
// initialize the model
this.model.disableNavigationBar = this.disableNavigationBar;
this.model.defaultStepIndex = this.defaultStepIndex;
this.model.updateWizardSteps(this.wizardSteps.toArray());
this.updateNavigationMode(this.navigationMode);
// finally reset the whole wizard state
this.navigation.reset();
}
/**
* Updates the navigation mode for this wizard component.
*
* Initially the wizard component uses the navigation mode specified in the [[navigationMode]] input
* or the default navigation mode if the [[navigationMode]] input is not defined.
* Use this method to select a different navigation mode after the wizard component is initialized.
*/
public updateNavigationMode(navigationModeInput: NavigationModeInput) {
this.model.updateNavigationMode(this.navigationModeFactory.create(this, navigationModeInput));
}
}