@citizenplane/pimp 18.19.10 → 18.21.0
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/dist/components/CpAncillaryFlightSelection.vue.d.ts +27 -0
- package/dist/components/CpAncillaryFlightSelection.vue.d.ts.map +1 -0
- package/dist/components/CpStepper.vue.d.ts +17 -0
- package/dist/components/CpStepper.vue.d.ts.map +1 -0
- package/dist/components/CpStepperMobile.vue.d.ts +17 -0
- package/dist/components/CpStepperMobile.vue.d.ts.map +1 -0
- package/dist/components/index.d.ts +7 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/constants/CpAncillaryFlightSelectionTypes.d.ts +8 -0
- package/dist/constants/CpAncillaryFlightSelectionTypes.d.ts.map +1 -0
- package/dist/constants/CpStepperTypes.d.ts +9 -0
- package/dist/constants/CpStepperTypes.d.ts.map +1 -0
- package/dist/pimp.es.js +1702 -1571
- package/dist/pimp.umd.js +50 -50
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/CpAncillaryFlightSelection.vue +192 -0
- package/src/components/CpStepper.vue +136 -0
- package/src/components/CpStepperMobile.vue +164 -0
- package/src/components/index.ts +12 -0
- package/src/constants/CpAncillaryFlightSelectionTypes.ts +7 -0
- package/src/constants/CpStepperTypes.ts +9 -0
- package/src/stories/CpAncillaryFlightSelection.stories.ts +135 -0
- package/src/stories/CpStepper.stories.ts +90 -0
- package/src/stories/CpStepperMobile.stories.ts +92 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
|
|
4
|
+
import type { CpAncillaryFlightSelectionFlight } from '@/constants/CpAncillaryFlightSelectionTypes'
|
|
5
|
+
|
|
6
|
+
import CpAncillaryFlightSelection from '@/components/CpAncillaryFlightSelection.vue'
|
|
7
|
+
|
|
8
|
+
import { docLabelStyle } from '@/stories/documentationStyles'
|
|
9
|
+
|
|
10
|
+
const sampleFlights: CpAncillaryFlightSelectionFlight[] = [
|
|
11
|
+
{
|
|
12
|
+
id: 'outbound',
|
|
13
|
+
originCity: 'Paris',
|
|
14
|
+
originIata: 'CDG',
|
|
15
|
+
destinationCity: 'New York',
|
|
16
|
+
destinationIata: 'JFK',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: 'inbound',
|
|
20
|
+
originCity: 'New York',
|
|
21
|
+
originIata: 'JFK',
|
|
22
|
+
destinationCity: 'Paris',
|
|
23
|
+
destinationIata: 'CDG',
|
|
24
|
+
},
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
const meta = {
|
|
28
|
+
title: 'Business/CpAncillaryFlightSelection',
|
|
29
|
+
component: CpAncillaryFlightSelection,
|
|
30
|
+
argTypes: {
|
|
31
|
+
label: {
|
|
32
|
+
control: 'text',
|
|
33
|
+
description: 'Label of the "apply to all flights" switch',
|
|
34
|
+
},
|
|
35
|
+
outboundLabel: {
|
|
36
|
+
control: 'text',
|
|
37
|
+
description: 'Label of the first flight tab',
|
|
38
|
+
},
|
|
39
|
+
returnLabel: {
|
|
40
|
+
control: 'text',
|
|
41
|
+
description: 'Label of the second flight tab',
|
|
42
|
+
},
|
|
43
|
+
flights: {
|
|
44
|
+
control: 'object',
|
|
45
|
+
description: 'Flights shown as tabs when the switch is off',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
} satisfies Meta<typeof CpAncillaryFlightSelection>
|
|
49
|
+
|
|
50
|
+
export default meta
|
|
51
|
+
type Story = StoryObj<typeof meta>
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Switch off, tab strip visible, first flight selected. The models are wired
|
|
55
|
+
* with refs to demonstrate the round trip.
|
|
56
|
+
*/
|
|
57
|
+
export const Default: Story = {
|
|
58
|
+
args: {
|
|
59
|
+
flights: sampleFlights,
|
|
60
|
+
label: 'Apply to all flights',
|
|
61
|
+
outboundLabel: 'Outbound',
|
|
62
|
+
returnLabel: 'Return',
|
|
63
|
+
},
|
|
64
|
+
render: (args) => ({
|
|
65
|
+
components: { CpAncillaryFlightSelection },
|
|
66
|
+
setup() {
|
|
67
|
+
const applyToAllFlights = ref(false)
|
|
68
|
+
const activeFlightId = ref(sampleFlights[0].id)
|
|
69
|
+
return { args, applyToAllFlights, activeFlightId }
|
|
70
|
+
},
|
|
71
|
+
template: `
|
|
72
|
+
<div style="padding: 20px; width: 40rem;">
|
|
73
|
+
<CpAncillaryFlightSelection
|
|
74
|
+
v-bind="args"
|
|
75
|
+
v-model:apply-to-all-flights="applyToAllFlights"
|
|
76
|
+
v-model:active-flight-id="activeFlightId"
|
|
77
|
+
/>
|
|
78
|
+
</div>
|
|
79
|
+
`,
|
|
80
|
+
}),
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Switch on: the tab strip collapses away.
|
|
85
|
+
*/
|
|
86
|
+
export const ApplyToAllFlights: Story = {
|
|
87
|
+
args: {
|
|
88
|
+
...Default.args,
|
|
89
|
+
},
|
|
90
|
+
render: (args) => ({
|
|
91
|
+
components: { CpAncillaryFlightSelection },
|
|
92
|
+
setup() {
|
|
93
|
+
const applyToAllFlights = ref(true)
|
|
94
|
+
const activeFlightId = ref(sampleFlights[0].id)
|
|
95
|
+
return { args, applyToAllFlights, activeFlightId }
|
|
96
|
+
},
|
|
97
|
+
template: `
|
|
98
|
+
<div style="padding: 20px; width: 40rem;">
|
|
99
|
+
<CpAncillaryFlightSelection
|
|
100
|
+
v-bind="args"
|
|
101
|
+
v-model:apply-to-all-flights="applyToAllFlights"
|
|
102
|
+
v-model:active-flight-id="activeFlightId"
|
|
103
|
+
/>
|
|
104
|
+
</div>
|
|
105
|
+
`,
|
|
106
|
+
}),
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* At a 358px container width the tabs swap city names for IATA codes.
|
|
111
|
+
*/
|
|
112
|
+
export const Mobile: Story = {
|
|
113
|
+
args: {
|
|
114
|
+
...Default.args,
|
|
115
|
+
},
|
|
116
|
+
parameters: { controls: { disable: true } },
|
|
117
|
+
render: () => ({
|
|
118
|
+
components: { CpAncillaryFlightSelection },
|
|
119
|
+
setup() {
|
|
120
|
+
const applyToAllFlights = ref(false)
|
|
121
|
+
const activeFlightId = ref(sampleFlights[0].id)
|
|
122
|
+
return { sampleFlights, applyToAllFlights, activeFlightId, docLabelStyle }
|
|
123
|
+
},
|
|
124
|
+
template: `
|
|
125
|
+
<div style="display: flex; flex-direction: column; gap: 10px; width: 358px;">
|
|
126
|
+
<span :style="docLabelStyle">358px</span>
|
|
127
|
+
<CpAncillaryFlightSelection
|
|
128
|
+
:flights="sampleFlights"
|
|
129
|
+
v-model:apply-to-all-flights="applyToAllFlights"
|
|
130
|
+
v-model:active-flight-id="activeFlightId"
|
|
131
|
+
/>
|
|
132
|
+
</div>
|
|
133
|
+
`,
|
|
134
|
+
}),
|
|
135
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
|
|
4
|
+
import type { CpStepperStep } from '@/constants/CpStepperTypes'
|
|
5
|
+
|
|
6
|
+
import CpStepper from '@/components/CpStepper.vue'
|
|
7
|
+
|
|
8
|
+
import { docLabelStyle } from '@/stories/documentationStyles'
|
|
9
|
+
|
|
10
|
+
const galleryRowStyle = 'display: flex; flex-direction: column; gap: 10px; width: 100%;'
|
|
11
|
+
|
|
12
|
+
const steps: CpStepperStep[] = [
|
|
13
|
+
{ id: 'passengers', label: 'Passengers' },
|
|
14
|
+
{ id: 'safetyChecks', label: 'Safety checks' },
|
|
15
|
+
{ id: 'seats', label: 'Seats' },
|
|
16
|
+
{ id: 'extras', label: 'Extras' },
|
|
17
|
+
{ id: 'confirmation', label: 'Confirmation' },
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
const meta = {
|
|
21
|
+
title: 'Business/CpStepper',
|
|
22
|
+
component: CpStepper,
|
|
23
|
+
argTypes: {
|
|
24
|
+
activeStepId: {
|
|
25
|
+
control: 'select',
|
|
26
|
+
options: steps.map((step) => step.id),
|
|
27
|
+
description: 'id of the step to render as active',
|
|
28
|
+
},
|
|
29
|
+
reachedStepIndex: {
|
|
30
|
+
control: 'number',
|
|
31
|
+
description: 'Highest reached step index; steps beyond it render disabled',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
} satisfies Meta<typeof CpStepper>
|
|
35
|
+
|
|
36
|
+
export default meta
|
|
37
|
+
type Story = StoryObj<typeof meta>
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Clicking an enabled step updates the active step locally, the way a
|
|
41
|
+
* consumer would react to `select` by navigating.
|
|
42
|
+
*/
|
|
43
|
+
export const Default: Story = {
|
|
44
|
+
args: {
|
|
45
|
+
steps,
|
|
46
|
+
activeStepId: 'seats',
|
|
47
|
+
reachedStepIndex: 2,
|
|
48
|
+
},
|
|
49
|
+
render: (args) => ({
|
|
50
|
+
components: { CpStepper },
|
|
51
|
+
setup() {
|
|
52
|
+
const activeStepId = ref(args.activeStepId)
|
|
53
|
+
|
|
54
|
+
const handleSelect = (id: string) => {
|
|
55
|
+
activeStepId.value = id
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return { args, activeStepId, handleSelect }
|
|
59
|
+
},
|
|
60
|
+
template: `
|
|
61
|
+
<div style="width: 70rem;">
|
|
62
|
+
<CpStepper v-bind="args" :active-step-id="activeStepId" @select="handleSelect" />
|
|
63
|
+
</div>
|
|
64
|
+
`,
|
|
65
|
+
}),
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Below the container width threshold (60.5rem, matching online-checkin's
|
|
70
|
+
* former `$breakpoint-large-tablet`), step titles collapse and only the
|
|
71
|
+
* numbered pills remain.
|
|
72
|
+
*/
|
|
73
|
+
export const Narrow: Story = {
|
|
74
|
+
args: { ...Default.args },
|
|
75
|
+
parameters: { controls: { disable: true } },
|
|
76
|
+
render: () => ({
|
|
77
|
+
components: { CpStepper },
|
|
78
|
+
setup() {
|
|
79
|
+
return { steps, galleryRowStyle, docLabelStyle }
|
|
80
|
+
},
|
|
81
|
+
template: `
|
|
82
|
+
<div :style="galleryRowStyle">
|
|
83
|
+
<span :style="docLabelStyle">Container width: 28rem</span>
|
|
84
|
+
<div style="width: 28rem;">
|
|
85
|
+
<CpStepper :steps="steps" active-step-id="seats" :reached-step-index="2" />
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
`,
|
|
89
|
+
}),
|
|
90
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
|
2
|
+
import { computed, ref } from 'vue'
|
|
3
|
+
|
|
4
|
+
import type { CpStepperStep } from '@/constants/CpStepperTypes'
|
|
5
|
+
|
|
6
|
+
import CpButton from '@/components/CpButton.vue'
|
|
7
|
+
import CpStepperMobile from '@/components/CpStepperMobile.vue'
|
|
8
|
+
|
|
9
|
+
const steps: CpStepperStep[] = [
|
|
10
|
+
{ id: 'passengers', label: 'Passengers' },
|
|
11
|
+
{ id: 'safetyChecks', label: 'Safety checks' },
|
|
12
|
+
{ id: 'seats', label: 'Seats' },
|
|
13
|
+
{ id: 'extras', label: 'Extras' },
|
|
14
|
+
{ id: 'confirmation', label: 'Confirmation' },
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
const meta = {
|
|
18
|
+
title: 'Business/CpStepperMobile',
|
|
19
|
+
component: CpStepperMobile,
|
|
20
|
+
argTypes: {
|
|
21
|
+
activeStepId: {
|
|
22
|
+
control: 'select',
|
|
23
|
+
options: steps.map((step) => step.id),
|
|
24
|
+
description: 'id of the step to render as active',
|
|
25
|
+
},
|
|
26
|
+
hasPreviousButton: {
|
|
27
|
+
control: 'boolean',
|
|
28
|
+
description: 'Whether the back chevron button is rendered',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
} satisfies Meta<typeof CpStepperMobile>
|
|
32
|
+
|
|
33
|
+
export default meta
|
|
34
|
+
type Story = StoryObj<typeof meta>
|
|
35
|
+
|
|
36
|
+
export const Default: Story = {
|
|
37
|
+
args: {
|
|
38
|
+
steps,
|
|
39
|
+
activeStepId: 'seats',
|
|
40
|
+
hasPreviousButton: true,
|
|
41
|
+
},
|
|
42
|
+
render: (args) => ({
|
|
43
|
+
components: { CpStepperMobile },
|
|
44
|
+
setup() {
|
|
45
|
+
return { args }
|
|
46
|
+
},
|
|
47
|
+
template: `
|
|
48
|
+
<div style="width: 24rem;">
|
|
49
|
+
<CpStepperMobile v-bind="args" />
|
|
50
|
+
</div>
|
|
51
|
+
`,
|
|
52
|
+
}),
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Previous/Next move the active step index so the title's
|
|
57
|
+
* slide-forward / slide-backward transition plays in each direction.
|
|
58
|
+
*/
|
|
59
|
+
export const Interactive: Story = {
|
|
60
|
+
args: { ...Default.args },
|
|
61
|
+
parameters: { controls: { disable: true } },
|
|
62
|
+
render: () => ({
|
|
63
|
+
components: { CpStepperMobile, CpButton },
|
|
64
|
+
setup() {
|
|
65
|
+
const activeIndex = ref(2)
|
|
66
|
+
const activeStepId = computed(() => steps[activeIndex.value].id)
|
|
67
|
+
const hasPreviousButton = computed(() => activeIndex.value > 0)
|
|
68
|
+
const isLastStep = computed(() => activeIndex.value === steps.length - 1)
|
|
69
|
+
|
|
70
|
+
const handlePrevious = () => {
|
|
71
|
+
activeIndex.value -= 1
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const handleNext = () => {
|
|
75
|
+
activeIndex.value += 1
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return { steps, activeStepId, hasPreviousButton, isLastStep, handlePrevious, handleNext }
|
|
79
|
+
},
|
|
80
|
+
template: `
|
|
81
|
+
<div style="display: flex; flex-direction: column; gap: 16px; width: 24rem;">
|
|
82
|
+
<CpStepperMobile
|
|
83
|
+
:steps="steps"
|
|
84
|
+
:active-step-id="activeStepId"
|
|
85
|
+
:has-previous-button="hasPreviousButton"
|
|
86
|
+
@previous="handlePrevious"
|
|
87
|
+
/>
|
|
88
|
+
<CpButton :disabled="isLastStep" @click="handleNext">Next</CpButton>
|
|
89
|
+
</div>
|
|
90
|
+
`,
|
|
91
|
+
}),
|
|
92
|
+
}
|