1- import type { Orientation } from '@js/common' ;
1+ import type { Orientation , SingleOrNone } from '@js/common' ;
22import registerComponent from '@js/core/component_registrator' ;
33import type { DxElement } from '@js/core/element' ;
44import $ , { type dxElementWrapper } from '@js/core/renderer' ;
55import { Deferred } from '@js/core/utils/deferred' ;
66import { isDefined } from '@js/core/utils/type' ;
77import type { DxEvent } from '@js/events' ;
8- import type { Item } from '@js/ui/stepper' ;
8+ import type { Item , Properties } from '@js/ui/stepper' ;
99import { BindableTemplate } from '@ts/core/templates/m_bindable_template' ;
1010import type { Template } from '@ts/core/templates/m_template' ;
1111import { getImageContainer } from '@ts/core/utils/m_icon' ;
@@ -17,10 +17,11 @@ import type {
1717} from '@ts/ui/collection/collection_widget.base' ;
1818import CollectionWidgetAsync from '@ts/ui/collection/m_collection_widget.async' ;
1919import Connector from '@ts/ui/stepper/connector' ;
20- import type { StepperItemProperties } from '@ts/ui/stepper/stepper_item' ;
21- import StepperItem , { STEP_COMPLETED_CLASS } from '@ts/ui/stepper/stepper_item' ;
22-
23- import type { CollectionWidgetEditProperties } from '../collection/m_collection_widget.edit' ;
20+ import StepperItem , {
21+ STEP_COMPLETED_CLASS ,
22+ STEP_INVALID_ICON ,
23+ STEP_VALID_ICON ,
24+ } from '@ts/ui/stepper/stepper_item' ;
2425
2526export const STEPPER_CLASS = 'dx-stepper' ;
2627export const STEP_LIST_CLASS = 'dx-step-list' ;
@@ -41,10 +42,12 @@ export const ORIENTATION: Record<string, Orientation> = {
4142 vertical : 'vertical' ,
4243} ;
4344
44- export interface StepperProperties extends CollectionWidgetEditProperties < Stepper > {
45- orientation ?: Orientation ;
46- linear ?: boolean ;
47- isValidExpr ?: ( data : Item ) => boolean | undefined ;
45+ export interface StepperProperties extends Properties {
46+ selectionMode ?: SingleOrNone ;
47+
48+ loopItemFocus ?: boolean ;
49+
50+ selectionRequired ?: boolean ;
4851}
4952
5053class Stepper extends CollectionWidgetAsync < StepperProperties > {
@@ -66,9 +69,6 @@ class Stepper extends CollectionWidgetAsync<StepperProperties> {
6669 focusStateEnabled : true ,
6770 loopItemFocus : false ,
6871 selectionRequired : true ,
69- isValidExpr ( data ) : boolean | undefined {
70- return data ? data . isValid : undefined ;
71- } ,
7272 } ;
7373 }
7474
@@ -83,17 +83,36 @@ class Stepper extends CollectionWidgetAsync<StepperProperties> {
8383 } ;
8484 }
8585
86- _prepareDefaultItemTemplate ( data : StepperItemProperties , $container : dxElementWrapper ) : void {
86+ _getStepIcon ( data : Item ) : string | undefined {
87+ const { isValid, icon } = data ;
88+
89+ if ( isValid === false ) {
90+ return STEP_INVALID_ICON ;
91+ }
92+
93+ if ( isValid === true ) {
94+ return STEP_VALID_ICON ;
95+ }
96+
97+ return icon ;
98+ }
99+
100+ _prepareDefaultItemTemplate ( data : Item , $container : dxElementWrapper ) : void {
101+ const { text, title } = data ;
102+
87103 const $indicatorElement = $ ( '<div>' ) . addClass ( STEP_INDICATOR_CLASS ) ;
88- const $iconElement = getImageContainer ( data . icon ) ?? $ ( '<div>' ) . addClass ( STEP_TEXT_CLASS ) . text ( data . text ?? '' ) ;
104+
105+ const iconName = this . _getStepIcon ( data ) ;
106+ const $iconElement = getImageContainer ( iconName ) ?? $ ( '<div>' ) . addClass ( STEP_TEXT_CLASS ) . text ( text ?? '' ) ;
89107
90108 $iconElement . appendTo ( $indicatorElement ) ;
109+
91110 $indicatorElement . prependTo ( $container ) ;
92111
93- if ( isDefined ( data . title ) ) {
112+ if ( isDefined ( title ) ) {
94113 const $stepTitleDiv = $ ( '<div>' ) . addClass ( STEP_TITLE_CLASS ) ;
95114
96- $stepTitleDiv . text ( data . title ) ;
115+ $stepTitleDiv . text ( title ) ;
97116
98117 $stepTitleDiv . appendTo ( $container ) ;
99118 }
@@ -103,15 +122,18 @@ class Stepper extends CollectionWidgetAsync<StepperProperties> {
103122 super . _initTemplates ( ) ;
104123
105124 this . _templateManager . addDefaultTemplates ( {
106- item : new BindableTemplate ( ( $container : dxElementWrapper , data : StepperItemProperties ) => {
125+ item : new BindableTemplate ( (
126+ $container : dxElementWrapper ,
127+ data : Item ,
128+ ) => {
107129 this . _prepareDefaultItemTemplate ( data , $container ) ;
108130 } , [ 'text' , 'icon' , 'title' , 'isValid' ] , this . option ( 'integrationOptions.watchMethod' ) ) ,
109131 } ) ;
110132 }
111133
112134 _createItemByTemplate (
113135 itemTemplate : Template ,
114- renderArgs : ItemRenderInfo < StepperItemProperties > ,
136+ renderArgs : ItemRenderInfo < Item > ,
115137 ) : DxElement {
116138 const { itemData, index } = renderArgs ;
117139
@@ -128,13 +150,26 @@ class Stepper extends CollectionWidgetAsync<StepperProperties> {
128150 return StepperItem . getInstance < StepperItem > ( $item ) ;
129151 }
130152
153+ _renderItem (
154+ index : number ,
155+ itemData : Item ,
156+ $container : dxElementWrapper ,
157+ $itemToReplace : dxElementWrapper ,
158+ ) : dxElementWrapper {
159+ const $itemFrame = super . _renderItem ( index , itemData , $container , $itemToReplace ) ;
160+
161+ this . _getItemInstance ( $itemFrame ) . updateInvalidClass ( itemData . isValid ) ;
162+
163+ return $itemFrame ;
164+ }
165+
131166 _postprocessRenderItem ( args : PostprocessRenderItemInfo < StepperItem > ) : void {
132167 super . _postprocessRenderItem ( args ) ;
133168
134169 const { selectedIndex = 0 } = this . option ( ) ;
135- const $ itemInstance = this . _getItemInstance ( args . itemElement ) ;
170+ const itemInstance = this . _getItemInstance ( args . itemElement ) ;
136171
137- $ itemInstance. changeCompleted ( args . itemIndex < selectedIndex ) ;
172+ itemInstance . changeCompleted ( args . itemIndex < selectedIndex ) ;
138173 }
139174
140175 _itemClass ( ) : string {
@@ -276,9 +311,9 @@ class Stepper extends CollectionWidgetAsync<StepperProperties> {
276311 const isCompleted = lastCompletedIndex < selectedIndex ;
277312
278313 for ( let i = startIndex ; i < endIndex ; i += 1 ) {
279- const $ itemInstance = this . _getItemInstance ( $ ( itemElements [ i ] ) ) ;
314+ const itemInstance = this . _getItemInstance ( $ ( itemElements [ i ] ) ) ;
280315
281- $ itemInstance. changeCompleted ( isCompleted ) ;
316+ itemInstance . changeCompleted ( isCompleted ) ;
282317 }
283318 }
284319
@@ -296,12 +331,25 @@ class Stepper extends CollectionWidgetAsync<StepperProperties> {
296331 }
297332
298333 _itemOptionChanged (
299- item : StepperItemProperties ,
300- property : keyof StepperItemProperties ,
334+ item : Item ,
335+ property : keyof Item ,
301336 value : unknown ,
302337 prevValue : unknown ,
303338 ) : void {
304339 switch ( property ) {
340+ case 'isValid' : {
341+ type PropertyType = Item [ typeof property ] ;
342+
343+ const itemIndex = this . _getIndexByItem ( item ) ;
344+ const $item = $ ( this . _itemElements ( ) [ itemIndex ] ) ;
345+
346+ const itemInstance = this . _getItemInstance ( $item ) ;
347+
348+ itemInstance . updateInvalidClass ( value as PropertyType ) ;
349+
350+ super . _itemOptionChanged ( item , property , value , prevValue ) ;
351+ break ;
352+ }
305353 default :
306354 super . _itemOptionChanged ( item , property , value , prevValue ) ;
307355 }
@@ -318,9 +366,6 @@ class Stepper extends CollectionWidgetAsync<StepperProperties> {
318366 break ;
319367 case 'linear' :
320368 break ;
321- case 'isValidExpr' :
322- this . _invalidate ( ) ;
323- break ;
324369 default :
325370 super . _optionChanged ( args ) ;
326371 }
0 commit comments