@@ -12,7 +12,7 @@ import {
12
12
watch ,
13
13
withDefaults ,
14
14
} from ' vue'
15
- import type { OptionParams , StepperEmitValue , StepperProps , StepperValue } from ' ../types'
15
+ import type { StepperProps , OptionParams } from ' ../types'
16
16
import Step from ' ./Step.vue'
17
17
18
18
defineOptions ({
@@ -21,10 +21,7 @@ defineOptions({
21
21
})
22
22
23
23
const props = withDefaults (defineProps <StepperProps >(), {
24
- value: {
25
- value: 2 ,
26
- id: undefined ,
27
- },
24
+ stepperId: undefined ,
28
25
steps: 0 ,
29
26
linear: true ,
30
27
persist: false ,
@@ -33,70 +30,34 @@ const props = withDefaults(defineProps<StepperProps>(), {
33
30
debug: false ,
34
31
})
35
32
36
- const emit = defineEmits ([' input' , ' reset' ])
33
+ const modelValue = defineModel ()
34
+
35
+ const emit = defineEmits ([' reset' ])
37
36
38
37
const namespace = { kebab: ' stepper' , capitalize: ' Stepper' }
39
38
const stepsArr = ref (getStepsArr ())
40
- const index = ref (toIndex (props .value .value ))
39
+ const currentIndex = ref (toIndex (modelValue .value ))
40
+
41
41
const slots = useSlots ()
42
- const id = computed (() => ` ${namespace .kebab }-${Math .random ().toString (36 ).substr (2 , 9 )} ` )
43
- const lastIndex = computed (() => stepsArr .value .length - 1 )
44
- const random = computed (() => props .linear === false )
45
-
46
- const queries = computed (() => {
47
- const { steps } = props
48
-
49
- return Array .from (Array (steps )).reduce (
50
- (queries , step , $index ) => {
51
- const query = ` isStep${$index + 1 } `
52
- queries [query ] = index .value === $index
53
- return queries
54
- },
55
- {} as Record <string , boolean >,
56
- )
57
- })
42
+ const id = computed (() => ` ${namespace .kebab }-${Math .random ().toString (36 ).substring (2 , 9 )} ` )
58
43
59
- watch (
60
- () => props .value ,
61
- (newValue ) => {
62
- index .value = toIndex (newValue .value )
63
- if (props .persist ) {
64
- setStorage ()
65
- }
66
- },
67
- )
68
-
69
- watch (
70
- index ,
71
- (newValue ) => {
72
- emitValue (toValue (newValue ))
73
- },
74
- { immediate: true },
75
- )
76
-
77
- const scope = computed (() => ({
78
- index: index .value ,
79
- displayIndex: index .value + 1 ,
80
- defaultSlot: slots .default ? slots .default () : undefined ,
81
- flags: {
82
- isActive: true ,
83
- isVisited: false ,
84
- isDisabled: false ,
85
- },
86
- }))
87
-
88
- const classes = computed (() => ({
89
- ' is-active' : true ,
90
- ' is-visited' : false ,
91
- ' is-disabled' : false ,
92
- }))
44
+ watch (() => modelValue .value , (step ) => {
45
+ currentIndex .value = toIndex (step )
46
+ if (props .persist ) {
47
+ setStorage ();
48
+ }
49
+ });
50
+
51
+ watch (currentIndex , (stepIndex ) => {
52
+ emitValue (toValue (stepIndex ));
53
+ }, { immediate: true });
93
54
94
55
onMounted (() => {
95
56
if (props .persist ) {
96
57
const storage = getStorage ()
97
58
if (storage ) {
98
59
stepsArr .value = storage .stepsArr
99
- index .value = storage .index
60
+ currentIndex .value = storage .index
100
61
} else {
101
62
setStorage ()
102
63
}
@@ -153,9 +114,9 @@ function doesStepExist(index: number) {
153
114
}
154
115
155
116
function handleChange(stepIndex : number ) {
156
- const isNext = stepIndex === index .value + 1
157
- const isPrevious = stepIndex === index .value - 1
158
- const oldIndex = toIndex (props . value .value )
117
+ const isNext = stepIndex === currentIndex .value + 1
118
+ const isPrevious = stepIndex === currentIndex .value - 1
119
+ const oldIndex = toIndex (modelValue .value )
159
120
160
121
if (props .linear ) {
161
122
if (isNext || isPrevious ) {
@@ -195,7 +156,7 @@ function getStepsArr() {
195
156
}
196
157
197
158
function offset(offset : number ) {
198
- const stepIndex = index .value + offset
159
+ const stepIndex = currentIndex .value + offset
199
160
if (doesStepExist (stepIndex )) {
200
161
handleChange (stepIndex )
201
162
}
@@ -211,7 +172,7 @@ function previous() {
211
172
212
173
function reset() {
213
174
stepsArr .value = getStepsArr ()
214
- index .value = 0
175
+ currentIndex .value = 0
215
176
emit (' reset' )
216
177
}
217
178
@@ -220,15 +181,15 @@ function setStep(stepIndex: number, prop: string, value: any) {
220
181
}
221
182
222
183
function setStorage() {
223
- window [props .storekeeper ].setItem (id .value , JSON .stringify ({ index: index .value , stepsArr: stepsArr .value }))
184
+ window [props .storekeeper ].setItem (id .value , JSON .stringify ({ index: currentIndex .value , stepsArr: stepsArr .value }))
224
185
}
225
186
226
187
function getStorage() {
227
188
return JSON .parse (window [props .storekeeper ].getItem (id .value ) || ' null' )
228
189
}
229
190
230
191
function emitValue(value : number ) {
231
- emit ( ' input ' , { id: id .value , value , queries: queries . value })
192
+ modelValue .value = value
232
193
}
233
194
234
195
defineExpose ({
@@ -238,40 +199,39 @@ defineExpose({
238
199
})
239
200
</script >
240
201
<template >
241
- <div class =" v-stepper" >
242
- <stepper-root >
243
- <step
244
- v-for =" (step, $index) in stepsArr"
245
- :name =" id"
246
- :key =" $index"
247
- :debug =" debug"
248
- :index =" $index"
249
- @change =" handleChange"
250
- :visited =" step.visited"
251
- :disabled =" step.disabled"
252
- :with-divider =" withDivider"
253
- :active =" step.index === toIndex(value.value)"
254
- >
255
- <template
256
- v-slot :index-root =" scope "
257
- v-if =" withSlot (getSlotName (' index-root' , $index + 1 ))"
258
- >
259
- <slot :name =" getSlotName('index-root', scope.displayIndex)" v-bind =" scope" ></slot >
260
- </template >
261
-
202
+ <div class =" flex w-full select-none box-border justify-between " >
203
+ <step
204
+ v-for =" (step, $index) in stepsArr"
205
+ :name =" id"
206
+ :key =" $index"
207
+ :debug =" debug"
208
+ :index =" $index"
209
+ @change =" handleChange"
210
+ :visited =" step.visited"
211
+ :disabled =" step.disabled"
212
+ :with-divider =" withDivider"
213
+ :active =" step.index === toIndex(modelValue)"
214
+ :isLastStep =" steps === ($index + 1)"
215
+ >
262
216
<template
263
- v-if =" withoutSlot (getSlotName (' index-root' , $index + 1 ))"
264
- v-slot :index =" scope " >
265
- <slot :name =" getSlotName('index', scope.displayIndex)" v-bind =" scope" >
266
- {{ scope.displayIndex }}
267
- </slot >
268
- </template >
269
-
270
- <template v-slot :defaultSlot =" scope " >
271
- <slot :name =" getSlotName('', scope.displayIndex)" v-bind =" scope" >2</slot >
272
- </template >
273
-
274
- </step >
275
- </stepper-root >
217
+ v-slot :index-root =" scope "
218
+ v-if =" withSlot (getSlotName (' index-root' , $index + 1 ))"
219
+ >
220
+ <slot :name =" getSlotName('index-root', scope.displayIndex)" v-bind =" scope" ></slot >
221
+ </template >
222
+
223
+ <template
224
+ v-if =" withoutSlot (getSlotName (' index-root' , $index + 1 ))"
225
+ v-slot :index =" scope " >
226
+ <slot :name =" getSlotName('index', scope.displayIndex)" v-bind =" scope" >
227
+ {{ scope.displayIndex }}
228
+ </slot >
229
+ </template >
230
+
231
+ <template v-slot :defaultSlot =" scope " >
232
+ <slot :name =" getSlotName('', scope.displayIndex)" v-bind =" scope" >2</slot >
233
+ </template >
234
+
235
+ </step >
276
236
</div >
277
237
</template >
0 commit comments