@@ -137,7 +137,13 @@ export class CdkStep implements OnChanges {
137137 @Input ( ) stepControl : AbstractControl ;
138138
139139 /** Whether user has attempted to move away from the step. */
140- interacted = false ;
140+ get interacted ( ) : boolean {
141+ return this . _interacted ( ) ;
142+ }
143+ set interacted ( value : boolean ) {
144+ this . _interacted . set ( value ) ;
145+ }
146+ private _interacted = signal ( false ) ;
141147
142148 /** Emits when the user has attempted to move away from the step. */
143149 @Output ( 'interacted' )
@@ -159,46 +165,82 @@ export class CdkStep implements OnChanges {
159165 @Input ( 'aria-labelledby' ) ariaLabelledby : string ;
160166
161167 /** State of the step. */
162- @Input ( ) state : StepState ;
168+ @Input ( )
169+ get state ( ) : StepState {
170+ return this . _state ( ) ! ;
171+ }
172+ set state ( value : StepState ) {
173+ this . _state . set ( value ) ;
174+ }
175+ private _state = signal < StepState | undefined > ( undefined ) ;
163176
164177 /** Whether the user can return to this step once it has been marked as completed. */
165- @Input ( { transform : booleanAttribute } ) editable : boolean = true ;
178+ @Input ( { transform : booleanAttribute } )
179+ get editable ( ) : boolean {
180+ return this . _editable ( ) ! ;
181+ }
182+ set editable ( value : boolean ) {
183+ this . _editable . set ( value ) ;
184+ }
185+ private _editable = signal ( true ) ;
166186
167187 /** Whether the completion of step is optional. */
168188 @Input ( { transform : booleanAttribute } ) optional : boolean = false ;
169189
170190 /** Whether step is marked as completed. */
171191 @Input ( { transform : booleanAttribute } )
172192 get completed ( ) : boolean {
173- if ( this . _completedOverride != null ) {
174- return this . _completedOverride ;
193+ const override = this . _completedOverride ( ) ;
194+ const interacted = this . _interacted ( ) ;
195+
196+ if ( override != null ) {
197+ return override ;
175198 }
176199
177- return this . stepControl ? this . stepControl . valid && this . interacted : this . interacted ;
200+ return interacted && ( ! this . stepControl || this . stepControl . valid ) ;
178201 }
179202 set completed ( value : boolean ) {
180- this . _completedOverride = value ;
203+ this . _completedOverride . set ( value ) ;
181204 }
182- _completedOverride : boolean | null = null ;
205+ _completedOverride = signal < boolean | null > ( null ) ;
183206
184207 /** Current index of the step within the stepper. */
185208 readonly index = signal ( - 1 ) ;
186209
187210 /** Whether the step is selected. */
188- readonly isSelected = computed ( ( ) => this . _stepper . selectedIndex === this . index ( ) ) ;
211+ readonly isSelected = computed < boolean > ( ( ) => this . _stepper . selectedIndex === this . index ( ) ) ;
189212
190213 /** Type of indicator that should be shown for the step. */
191- readonly indicatorType = computed ( ( ) => {
192- const isCurrentStep = this . isSelected ( ) ;
193- return this . _displayDefaultIndicatorType
194- ? this . _getDefaultIndicatorLogic ( isCurrentStep )
195- : this . _getGuidelineLogic ( isCurrentStep ) ;
214+ readonly indicatorType = computed < StepState > ( ( ) => {
215+ const selected = this . isSelected ( ) ;
216+ const completed = this . completed ;
217+ const defaultState = this . _state ( ) ?? STEP_STATE . NUMBER ;
218+ const editable = this . _editable ( ) ;
219+
220+ if ( this . _showError ( ) && this . hasError && ! selected ) {
221+ return STEP_STATE . ERROR ;
222+ }
223+
224+ if ( this . _displayDefaultIndicatorType ) {
225+ if ( ! completed || selected ) {
226+ return STEP_STATE . NUMBER ;
227+ }
228+ return editable ? STEP_STATE . EDIT : STEP_STATE . DONE ;
229+ } else {
230+ if ( completed && ! selected ) {
231+ return STEP_STATE . DONE ;
232+ } else if ( completed && selected ) {
233+ return defaultState ;
234+ }
235+ return editable && selected ? STEP_STATE . EDIT : defaultState ;
236+ }
196237 } ) ;
197238
198239 /** Whether the user can navigate to the step. */
199- readonly isNavigable = computed ( ( ) => {
240+ readonly isNavigable = computed < boolean > ( ( ) => {
200241 const isSelected = this . isSelected ( ) ;
201- return this . completed || isSelected || ! this . _stepper . linear ;
242+ const isCompleted = this . completed ;
243+ return isCompleted || isSelected || ! this . _stepper . linear ;
202244 } ) ;
203245
204246 /** Whether step has an error. */
@@ -213,7 +255,7 @@ export class CdkStep implements OnChanges {
213255 private _customError = signal < boolean | null > ( null ) ;
214256
215257 private _getDefaultError ( ) {
216- return this . stepControl && this . stepControl . invalid && this . interacted ;
258+ return this . interacted && ! ! this . stepControl ? .invalid ;
217259 }
218260
219261 constructor ( ...args : unknown [ ] ) ;
@@ -231,10 +273,10 @@ export class CdkStep implements OnChanges {
231273
232274 /** Resets the step to its initial state. Note that this includes resetting form data. */
233275 reset ( ) : void {
234- this . interacted = false ;
276+ this . _interacted . set ( false ) ;
235277
236- if ( this . _completedOverride != null ) {
237- this . _completedOverride = false ;
278+ if ( this . _completedOverride ( ) != null ) {
279+ this . _completedOverride . set ( false ) ;
238280 }
239281
240282 if ( this . _customError ( ) != null ) {
@@ -257,8 +299,8 @@ export class CdkStep implements OnChanges {
257299 }
258300
259301 _markAsInteracted ( ) {
260- if ( ! this . interacted ) {
261- this . interacted = true ;
302+ if ( ! this . _interacted ( ) ) {
303+ this . _interacted . set ( true ) ;
262304 this . interactedStream . emit ( this ) ;
263305 }
264306 }
@@ -269,30 +311,6 @@ export class CdkStep implements OnChanges {
269311 // global options, or if they've explicitly set it through the `hasError` input.
270312 return this . _stepperOptions . showError ?? this . _customError ( ) != null ;
271313 }
272-
273- private _getDefaultIndicatorLogic ( isCurrentStep : boolean ) : StepState {
274- if ( this . _showError ( ) && this . hasError && ! isCurrentStep ) {
275- return STEP_STATE . ERROR ;
276- } else if ( ! this . completed || isCurrentStep ) {
277- return STEP_STATE . NUMBER ;
278- }
279- return this . editable ? STEP_STATE . EDIT : STEP_STATE . DONE ;
280- }
281-
282- private _getGuidelineLogic ( isCurrentStep : boolean ) : StepState {
283- const defaultState = this . state || STEP_STATE . NUMBER ;
284-
285- if ( this . _showError ( ) && this . hasError && ! isCurrentStep ) {
286- return STEP_STATE . ERROR ;
287- } else if ( this . completed && ! isCurrentStep ) {
288- return STEP_STATE . DONE ;
289- } else if ( this . completed && isCurrentStep ) {
290- return defaultState ;
291- } else if ( this . editable && isCurrentStep ) {
292- return STEP_STATE . EDIT ;
293- }
294- return defaultState ;
295- }
296314}
297315
298316@Directive ( {
@@ -577,7 +595,7 @@ export class CdkStepper implements AfterContentInit, AfterViewInit, OnDestroy {
577595 const isIncomplete = control
578596 ? control . invalid || control . pending || ! step . interacted
579597 : ! step . completed ;
580- return isIncomplete && ! step . optional && ! step . _completedOverride ;
598+ return isIncomplete && ! step . optional && ! step . _completedOverride ( ) ;
581599 } ) ;
582600 }
583601
0 commit comments