@citizenplane/pimp 18.23.0 → 18.23.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/package.json
CHANGED
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="cpStepper">
|
|
3
3
|
<div class="cpStepper__wrapper">
|
|
4
|
-
<div v-for="
|
|
4
|
+
<div v-for="stepItem in stepItems" :key="stepItem.id" class="cpStepper__stepWrapper">
|
|
5
5
|
<button
|
|
6
|
+
:aria-label="stepItem.label"
|
|
6
7
|
class="cpStepper__step"
|
|
7
|
-
:class="
|
|
8
|
-
:disabled="
|
|
8
|
+
:class="stepItem.className"
|
|
9
|
+
:disabled="stepItem.isDisabled"
|
|
9
10
|
type="button"
|
|
10
|
-
@click="handleStepClick(
|
|
11
|
+
@click="handleStepClick(stepItem.id)"
|
|
11
12
|
>
|
|
12
|
-
<span class="cpStepper__stepNumber">
|
|
13
|
-
|
|
13
|
+
<span class="cpStepper__stepNumber">
|
|
14
|
+
<cp-icon v-if="stepItem.isCompleted" size="12" type="check" />
|
|
15
|
+
<template v-else>{{ stepItem.number }}</template>
|
|
16
|
+
</span>
|
|
17
|
+
<span class="cpStepper__stepTitle">{{ stepItem.label }}</span>
|
|
14
18
|
</button>
|
|
15
|
-
<cp-icon v-if="
|
|
19
|
+
<cp-icon v-if="stepItem.isNotLast" class="cpStepper__chevron" size="16" type="chevron-right" />
|
|
16
20
|
</div>
|
|
17
21
|
</div>
|
|
18
22
|
</div>
|
|
19
23
|
</template>
|
|
20
24
|
|
|
21
25
|
<script setup lang="ts">
|
|
26
|
+
import { computed } from 'vue'
|
|
27
|
+
|
|
22
28
|
import type { CpStepperStep } from '@/constants/CpStepperTypes'
|
|
23
29
|
|
|
24
30
|
import CpIcon from '@/components/CpIcon.vue'
|
|
@@ -36,13 +42,32 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
36
42
|
|
|
37
43
|
const emit = defineEmits<{ select: [id: string] }>()
|
|
38
44
|
|
|
39
|
-
const
|
|
45
|
+
const activeStepIndex = computed(() => props.steps.findIndex((step) => step.id === props.activeStepId))
|
|
46
|
+
|
|
47
|
+
const isStepCompleted = (stepIndex: number) => activeStepIndex.value > -1 && stepIndex < activeStepIndex.value
|
|
40
48
|
|
|
41
|
-
const
|
|
49
|
+
const stepClassName = (step: CpStepperStep, stepIndex: number) => {
|
|
50
|
+
return {
|
|
51
|
+
'cpStepper__step--isActive': step.id === props.activeStepId,
|
|
52
|
+
'cpStepper__step--isCompleted': isStepCompleted(stepIndex),
|
|
53
|
+
}
|
|
54
|
+
}
|
|
42
55
|
|
|
43
|
-
const
|
|
56
|
+
const stepItems = computed(() => {
|
|
57
|
+
return props.steps.map((step, stepIndex) => {
|
|
58
|
+
return {
|
|
59
|
+
className: stepClassName(step, stepIndex),
|
|
60
|
+
id: step.id,
|
|
61
|
+
isCompleted: isStepCompleted(stepIndex),
|
|
62
|
+
isDisabled: stepIndex > props.reachedStepIndex,
|
|
63
|
+
isNotLast: stepIndex < props.steps.length - 1,
|
|
64
|
+
label: step.label,
|
|
65
|
+
number: stepIndex + 1,
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
})
|
|
44
69
|
|
|
45
|
-
const handleStepClick = (
|
|
70
|
+
const handleStepClick = (stepId: string) => emit('select', stepId)
|
|
46
71
|
</script>
|
|
47
72
|
|
|
48
73
|
<style lang="scss">
|
|
@@ -85,6 +110,12 @@ const handleStepClick = (step: CpStepperStep) => emit('select', step.id)
|
|
|
85
110
|
color: var(--cp-text-accent-primary);
|
|
86
111
|
}
|
|
87
112
|
|
|
113
|
+
&--isCompleted {
|
|
114
|
+
border-color: transparent;
|
|
115
|
+
background-color: var(--cp-background-primary);
|
|
116
|
+
color: var(--cp-text-primary);
|
|
117
|
+
}
|
|
118
|
+
|
|
88
119
|
&:not(:disabled) {
|
|
89
120
|
@extend %u-focus-outline;
|
|
90
121
|
|
|
@@ -115,6 +146,11 @@ const handleStepClick = (step: CpStepperStep) => emit('select', step.id)
|
|
|
115
146
|
color: var(--cp-text-white);
|
|
116
147
|
}
|
|
117
148
|
|
|
149
|
+
&__step--isCompleted &__stepNumber {
|
|
150
|
+
background-color: var(--cp-background-success-primary);
|
|
151
|
+
color: var(--cp-foreground-success-primary);
|
|
152
|
+
}
|
|
153
|
+
|
|
118
154
|
&__stepTitle {
|
|
119
155
|
@extend %u-text-ellipsis;
|
|
120
156
|
|
|
@@ -37,6 +37,10 @@ export default meta
|
|
|
37
37
|
type Story = StoryObj<typeof meta>
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
+
* Three visual states coexist: steps before the active one render as
|
|
41
|
+
* completed (white pill, green check badge, dark label), the active one keeps
|
|
42
|
+
* its accent pill, and the following ones stay upcoming (bordered, grey).
|
|
43
|
+
*
|
|
40
44
|
* Clicking an enabled step updates the active step locally, the way a
|
|
41
45
|
* consumer would react to `select` by navigating.
|
|
42
46
|
*/
|
|
@@ -65,10 +69,55 @@ export const Default: Story = {
|
|
|
65
69
|
}),
|
|
66
70
|
}
|
|
67
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Three steps already behind the active one: each renders completed, with the
|
|
74
|
+
* check badge replacing its number. Completed steps stay clickable.
|
|
75
|
+
*/
|
|
76
|
+
export const Completed: Story = {
|
|
77
|
+
args: {
|
|
78
|
+
steps,
|
|
79
|
+
activeStepId: 'extras',
|
|
80
|
+
reachedStepIndex: 3,
|
|
81
|
+
},
|
|
82
|
+
render: (args) => ({
|
|
83
|
+
components: { CpStepper },
|
|
84
|
+
setup() {
|
|
85
|
+
return { args }
|
|
86
|
+
},
|
|
87
|
+
template: `
|
|
88
|
+
<div style="width: 70rem;">
|
|
89
|
+
<CpStepper v-bind="args" />
|
|
90
|
+
</div>
|
|
91
|
+
`,
|
|
92
|
+
}),
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* The funnel's last step is active, so every preceding step is completed.
|
|
97
|
+
*/
|
|
98
|
+
export const LastStep: Story = {
|
|
99
|
+
args: {
|
|
100
|
+
steps,
|
|
101
|
+
activeStepId: 'confirmation',
|
|
102
|
+
reachedStepIndex: 4,
|
|
103
|
+
},
|
|
104
|
+
render: (args) => ({
|
|
105
|
+
components: { CpStepper },
|
|
106
|
+
setup() {
|
|
107
|
+
return { args }
|
|
108
|
+
},
|
|
109
|
+
template: `
|
|
110
|
+
<div style="width: 70rem;">
|
|
111
|
+
<CpStepper v-bind="args" />
|
|
112
|
+
</div>
|
|
113
|
+
`,
|
|
114
|
+
}),
|
|
115
|
+
}
|
|
116
|
+
|
|
68
117
|
/**
|
|
69
118
|
* Below the container width threshold (60.5rem, matching online-checkin's
|
|
70
119
|
* former `$breakpoint-large-tablet`), step titles collapse and only the
|
|
71
|
-
* numbered pills remain.
|
|
120
|
+
* numbered pills remain, the completed ones showing their check badge.
|
|
72
121
|
*/
|
|
73
122
|
export const Narrow: Story = {
|
|
74
123
|
args: { ...Default.args },
|