@citizenplane/pimp 18.14.4 → 18.16.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/dist/components/CpMultiselect.vue.d.ts.map +1 -1
- package/dist/components/CpTextMorph.vue.d.ts +11 -0
- package/dist/components/CpTextMorph.vue.d.ts.map +1 -0
- package/dist/components/CpTripDetails.vue.d.ts +14 -0
- package/dist/components/CpTripDetails.vue.d.ts.map +1 -0
- package/dist/components/CpTripLegRouteInformation.vue.d.ts +11 -0
- package/dist/components/CpTripLegRouteInformation.vue.d.ts.map +1 -0
- package/dist/components/CpTripLegRouteLayover.vue.d.ts +13 -0
- package/dist/components/CpTripLegRouteLayover.vue.d.ts.map +1 -0
- package/dist/components/CpTripLegRoutePlace.vue.d.ts +22 -0
- package/dist/components/CpTripLegRoutePlace.vue.d.ts.map +1 -0
- package/dist/components/CpTripLegRouteSegment.vue.d.ts +18 -0
- package/dist/components/CpTripLegRouteSegment.vue.d.ts.map +1 -0
- package/dist/components/index.d.ts +8 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/constants/tripDetails/Airline.d.ts +5 -0
- package/dist/constants/tripDetails/Airline.d.ts.map +1 -0
- package/dist/constants/tripDetails/Airport.d.ts +7 -0
- package/dist/constants/tripDetails/Airport.d.ts.map +1 -0
- package/dist/constants/tripDetails/CpTripDetailsConfig.d.ts +16 -0
- package/dist/constants/tripDetails/CpTripDetailsConfig.d.ts.map +1 -0
- package/dist/constants/tripDetails/Flight.d.ts +5 -0
- package/dist/constants/tripDetails/Flight.d.ts.map +1 -0
- package/dist/constants/tripDetails/FlightSegment.d.ts +15 -0
- package/dist/constants/tripDetails/FlightSegment.d.ts.map +1 -0
- package/dist/constants/tripDetails/FlightStopTypes.d.ts +7 -0
- package/dist/constants/tripDetails/FlightStopTypes.d.ts.map +1 -0
- package/dist/constants/tripDetails/Terminal.d.ts +5 -0
- package/dist/constants/tripDetails/Terminal.d.ts.map +1 -0
- package/dist/constants/tripDetails/index.d.ts +9 -0
- package/dist/constants/tripDetails/index.d.ts.map +1 -0
- package/dist/helpers/tripDetails.d.ts +23 -0
- package/dist/helpers/tripDetails.d.ts.map +1 -0
- package/dist/pimp.es.js +5496 -4508
- package/dist/pimp.umd.js +67 -34
- package/dist/style.css +1 -1
- package/package.json +2 -1
- package/src/assets/images/dot.svg +3 -0
- package/src/components/CpMultiselect.vue +23 -1
- package/src/components/CpTextMorph.vue +17 -0
- package/src/components/CpTripDetails.vue +64 -0
- package/src/components/CpTripLegRouteInformation.vue +224 -0
- package/src/components/CpTripLegRouteLayover.vue +63 -0
- package/src/components/CpTripLegRoutePlace.vue +196 -0
- package/src/components/CpTripLegRouteSegment.vue +99 -0
- package/src/components/index.ts +26 -0
- package/src/constants/tripDetails/Airline.ts +4 -0
- package/src/constants/tripDetails/Airport.ts +6 -0
- package/src/constants/tripDetails/CpTripDetailsConfig.ts +29 -0
- package/src/constants/tripDetails/Flight.ts +5 -0
- package/src/constants/tripDetails/FlightSegment.ts +15 -0
- package/src/constants/tripDetails/FlightStopTypes.ts +6 -0
- package/src/constants/tripDetails/Terminal.ts +4 -0
- package/src/constants/tripDetails/index.ts +9 -0
- package/src/helpers/tripDetails.ts +61 -0
- package/src/stories/CpMultiselect.stories.ts +30 -0
- package/src/stories/CpTextMorph.stories.ts +236 -0
- package/src/stories/CpTrip.stories.ts +147 -0
- package/src/stories/CpTripDetails.stories.ts +134 -0
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { Args, Meta, StoryObj } from '@storybook/vue3-vite'
|
|
2
2
|
|
|
3
|
+
import type { Flight } from '@/constants/tripDetails/Flight'
|
|
4
|
+
|
|
5
|
+
import CpAccordion from '@/components/CpAccordion.vue'
|
|
3
6
|
import CpTrip from '@/components/CpTrip.vue'
|
|
7
|
+
import CpTripDetails from '@/components/CpTripDetails.vue'
|
|
4
8
|
|
|
5
9
|
const directTrip = {
|
|
6
10
|
arrivalDate: {
|
|
@@ -221,6 +225,104 @@ const fourStopTrip = {
|
|
|
221
225
|
],
|
|
222
226
|
}
|
|
223
227
|
|
|
228
|
+
/**
|
|
229
|
+
* Summary and segments below describe the same one-stop CDG → MUC → JFK
|
|
230
|
+
* itinerary: 09:00 Paris → 10:40 Munich, 2h 10m layover, 12:50 Munich →
|
|
231
|
+
* 16:15 New York, for 13h 15m of total travel time on 10 Jun 2026.
|
|
232
|
+
*/
|
|
233
|
+
const fullTrip = {
|
|
234
|
+
arrivalDate: {
|
|
235
|
+
formatted: 'Wed, 10 Jun 2026',
|
|
236
|
+
raw: '2026-06-10',
|
|
237
|
+
},
|
|
238
|
+
arrivalTime: '16:15',
|
|
239
|
+
dayCountAfterDeparture: 0,
|
|
240
|
+
departureDate: {
|
|
241
|
+
formatted: 'Wed, 10 Jun 2026',
|
|
242
|
+
raw: '2026-06-10',
|
|
243
|
+
},
|
|
244
|
+
departureTime: '09:00',
|
|
245
|
+
destination: {
|
|
246
|
+
iataCode: 'JFK',
|
|
247
|
+
name: 'John F. Kennedy International Airport',
|
|
248
|
+
},
|
|
249
|
+
flightDuration: {
|
|
250
|
+
formatted: '13h 15m',
|
|
251
|
+
raw: 'PT13H15M',
|
|
252
|
+
},
|
|
253
|
+
labels: {
|
|
254
|
+
layover: 'layover',
|
|
255
|
+
stopCount: '1 stop',
|
|
256
|
+
},
|
|
257
|
+
airlines: [
|
|
258
|
+
{
|
|
259
|
+
iataCode: 'AF',
|
|
260
|
+
name: 'Air France',
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
iataCode: 'LH',
|
|
264
|
+
name: 'Lufthansa',
|
|
265
|
+
},
|
|
266
|
+
],
|
|
267
|
+
origin: {
|
|
268
|
+
iataCode: 'CDG',
|
|
269
|
+
name: 'Paris Charles de Gaulle Airport',
|
|
270
|
+
},
|
|
271
|
+
stops: [
|
|
272
|
+
{
|
|
273
|
+
duration: '2h 10m',
|
|
274
|
+
iata: 'MUC',
|
|
275
|
+
name: 'Munich',
|
|
276
|
+
},
|
|
277
|
+
],
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/** Segment dates are GMT — `CpTripDetails` converts them to each airport's timezone. */
|
|
281
|
+
const fullTripFlight: Flight = {
|
|
282
|
+
segments: [
|
|
283
|
+
{
|
|
284
|
+
airline: { iata_code: 'AF', name: 'Air France' },
|
|
285
|
+
arrival_date: '2026-06-10T08:40:00',
|
|
286
|
+
departure_date: '2026-06-10T07:00:00',
|
|
287
|
+
destination: {
|
|
288
|
+
city_name: 'Munich',
|
|
289
|
+
iata_code: 'MUC',
|
|
290
|
+
name: 'Franz Josef Strauss Airport',
|
|
291
|
+
timezone: 'Europe/Berlin',
|
|
292
|
+
},
|
|
293
|
+
destination_terminal: { label: 'Terminal 2', terminal_code: '2' },
|
|
294
|
+
flight_number: 'AF1122',
|
|
295
|
+
origin: {
|
|
296
|
+
city_name: 'Paris',
|
|
297
|
+
iata_code: 'CDG',
|
|
298
|
+
name: 'Paris Charles de Gaulle Airport',
|
|
299
|
+
timezone: 'Europe/Paris',
|
|
300
|
+
},
|
|
301
|
+
origin_terminal: { label: 'Terminal 2E', terminal_code: '2E' },
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
airline: { iata_code: 'LH', name: 'Lufthansa' },
|
|
305
|
+
arrival_date: '2026-06-10T20:15:00',
|
|
306
|
+
departure_date: '2026-06-10T10:50:00',
|
|
307
|
+
destination: {
|
|
308
|
+
city_name: 'New York',
|
|
309
|
+
iata_code: 'JFK',
|
|
310
|
+
name: 'John F. Kennedy International Airport',
|
|
311
|
+
timezone: 'America/New_York',
|
|
312
|
+
},
|
|
313
|
+
destination_terminal: { label: 'Terminal 1', terminal_code: '1' },
|
|
314
|
+
flight_number: 'LH410',
|
|
315
|
+
origin: {
|
|
316
|
+
city_name: 'Munich',
|
|
317
|
+
iata_code: 'MUC',
|
|
318
|
+
name: 'Franz Josef Strauss Airport',
|
|
319
|
+
timezone: 'Europe/Berlin',
|
|
320
|
+
},
|
|
321
|
+
origin_terminal: { label: 'Terminal 2', terminal_code: '2' },
|
|
322
|
+
},
|
|
323
|
+
],
|
|
324
|
+
}
|
|
325
|
+
|
|
224
326
|
const meta = {
|
|
225
327
|
title: 'Business/CpTrip',
|
|
226
328
|
component: CpTrip,
|
|
@@ -321,3 +423,48 @@ export const HideAirlines: Story = {
|
|
|
321
423
|
},
|
|
322
424
|
render: defaultRender,
|
|
323
425
|
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* A complete itinerary: `CpTrip` acts as the always-visible summary in the
|
|
429
|
+
* accordion header, and `CpTripDetails` renders the leg-by-leg breakdown in
|
|
430
|
+
* the expandable content. The rounded corners come from the wrapper, since
|
|
431
|
+
* `CpAccordion` is square by design so it can be stacked in a group.
|
|
432
|
+
*/
|
|
433
|
+
export const FullTrip: Story = {
|
|
434
|
+
args: {
|
|
435
|
+
trip: fullTrip,
|
|
436
|
+
},
|
|
437
|
+
render: (args: Args) => ({
|
|
438
|
+
components: { CpAccordion, CpTrip, CpTripDetails },
|
|
439
|
+
setup() {
|
|
440
|
+
const wrapperStyle = [
|
|
441
|
+
'box-sizing: border-box',
|
|
442
|
+
'width: 640px',
|
|
443
|
+
'max-width: 100%',
|
|
444
|
+
'overflow: hidden',
|
|
445
|
+
'border: 1px solid var(--cp-border-soft)',
|
|
446
|
+
'border-radius: var(--cp-radius-xl)',
|
|
447
|
+
'box-shadow: var(--cp-shadows-xs)',
|
|
448
|
+
].join('; ')
|
|
449
|
+
|
|
450
|
+
const summaryStyle = 'padding-top: var(--cp-spacing-md);'
|
|
451
|
+
const detailsStyle = 'border-top: 1px solid var(--cp-border-soft);'
|
|
452
|
+
|
|
453
|
+
return { args, detailsStyle, fullTripFlight, summaryStyle, wrapperStyle }
|
|
454
|
+
},
|
|
455
|
+
template: `
|
|
456
|
+
<div :style="wrapperStyle">
|
|
457
|
+
<CpAccordion :default-open-state="true" icon-position="trailing" title="Outbound · Wed, 10 Jun 2026">
|
|
458
|
+
<template #leading-slot>
|
|
459
|
+
<div :style="summaryStyle">
|
|
460
|
+
<CpTrip v-bind="args" />
|
|
461
|
+
</div>
|
|
462
|
+
</template>
|
|
463
|
+
<div :style="detailsStyle">
|
|
464
|
+
<CpTripDetails :flight="fullTripFlight" />
|
|
465
|
+
</div>
|
|
466
|
+
</CpAccordion>
|
|
467
|
+
</div>
|
|
468
|
+
`,
|
|
469
|
+
}),
|
|
470
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { Args, Meta, StoryObj } from '@storybook/vue3-vite'
|
|
2
|
+
|
|
3
|
+
import type { Flight } from '@/constants/tripDetails/Flight'
|
|
4
|
+
|
|
5
|
+
import CpTripDetails from '@/components/CpTripDetails.vue'
|
|
6
|
+
|
|
7
|
+
const parisAirport = {
|
|
8
|
+
city_name: 'Paris',
|
|
9
|
+
iata_code: 'CDG',
|
|
10
|
+
name: 'Paris Charles de Gaulle Airport',
|
|
11
|
+
timezone: 'Europe/Paris',
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const munichAirport = {
|
|
15
|
+
city_name: 'Munich',
|
|
16
|
+
iata_code: 'MUC',
|
|
17
|
+
name: 'Franz Josef Strauss Airport',
|
|
18
|
+
timezone: 'Europe/Berlin',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const newYorkAirport = {
|
|
22
|
+
city_name: 'New York',
|
|
23
|
+
iata_code: 'JFK',
|
|
24
|
+
name: 'John F. Kennedy International Airport',
|
|
25
|
+
timezone: 'America/New_York',
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const directFlight: Flight = {
|
|
29
|
+
segments: [
|
|
30
|
+
{
|
|
31
|
+
airline: { iata_code: 'AF', name: 'Air France' },
|
|
32
|
+
arrival_date: '2026-06-10T17:40:00',
|
|
33
|
+
departure_date: '2026-06-10T09:00:00',
|
|
34
|
+
destination: newYorkAirport,
|
|
35
|
+
destination_terminal: { label: 'Terminal 1', terminal_code: '1' },
|
|
36
|
+
flight_number: 'AF008',
|
|
37
|
+
origin: parisAirport,
|
|
38
|
+
origin_terminal: { label: 'Terminal 2E', terminal_code: '2E' },
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const oneStopFlight: Flight = {
|
|
44
|
+
segments: [
|
|
45
|
+
{
|
|
46
|
+
airline: { iata_code: 'AF', name: 'Air France' },
|
|
47
|
+
arrival_date: '2026-06-10T11:10:00',
|
|
48
|
+
departure_date: '2026-06-10T09:00:00',
|
|
49
|
+
destination: munichAirport,
|
|
50
|
+
flight_number: 'AF1234',
|
|
51
|
+
origin: parisAirport,
|
|
52
|
+
origin_terminal: { label: 'Terminal 2E', terminal_code: '2E' },
|
|
53
|
+
via_airport: { city_name: 'Munich', iata_code: 'MUC' },
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
airline: { iata_code: 'KL', name: 'KLM' },
|
|
57
|
+
arrival_date: '2026-06-10T20:25:00',
|
|
58
|
+
departure_date: '2026-06-10T13:20:00',
|
|
59
|
+
destination: newYorkAirport,
|
|
60
|
+
destination_terminal: { label: 'Terminal 4', terminal_code: '4' },
|
|
61
|
+
flight_number: 'KL5678',
|
|
62
|
+
origin: munichAirport,
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Luxon formats times and durations through `Intl`, so any BCP 47 tag works. */
|
|
68
|
+
const localeOptions = ['en', 'fr', 'de', 'es', 'it', 'nl', 'pt']
|
|
69
|
+
|
|
70
|
+
const localeLabels: Record<string, string> = {
|
|
71
|
+
de: 'Deutsch (de)',
|
|
72
|
+
en: 'English (en)',
|
|
73
|
+
es: 'Español (es)',
|
|
74
|
+
fr: 'Français (fr)',
|
|
75
|
+
it: 'Italiano (it)',
|
|
76
|
+
nl: 'Nederlands (nl)',
|
|
77
|
+
pt: 'Português (pt)',
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const meta = {
|
|
81
|
+
title: 'Business/CpTripDetails',
|
|
82
|
+
component: CpTripDetails,
|
|
83
|
+
argTypes: {
|
|
84
|
+
flight: {
|
|
85
|
+
control: 'object',
|
|
86
|
+
description: 'Raw flight data (segments) the leg-by-leg route detail is built from',
|
|
87
|
+
},
|
|
88
|
+
config: {
|
|
89
|
+
control: 'object',
|
|
90
|
+
description: 'Static label overrides — Pimp has no i18n, so the consumer supplies its own translations',
|
|
91
|
+
},
|
|
92
|
+
locale: {
|
|
93
|
+
control: { type: 'select', labels: localeLabels },
|
|
94
|
+
options: localeOptions,
|
|
95
|
+
description: 'Locale used to format durations and the date tooltips. Does not translate the `config` labels.',
|
|
96
|
+
table: { defaultValue: { summary: 'en' } },
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
} satisfies Meta<typeof CpTripDetails>
|
|
100
|
+
|
|
101
|
+
export default meta
|
|
102
|
+
|
|
103
|
+
type Story = StoryObj<typeof meta>
|
|
104
|
+
|
|
105
|
+
const defaultRender = (args: Args) => ({
|
|
106
|
+
components: { CpTripDetails },
|
|
107
|
+
setup() {
|
|
108
|
+
return { args }
|
|
109
|
+
},
|
|
110
|
+
template: `<CpTripDetails v-bind="args" />`,
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Direct flight: a single segment, no layover section.
|
|
115
|
+
*/
|
|
116
|
+
export const DirectFlight: Story = {
|
|
117
|
+
args: {
|
|
118
|
+
flight: directFlight,
|
|
119
|
+
locale: 'en',
|
|
120
|
+
},
|
|
121
|
+
render: defaultRender,
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* One-stop itinerary: the layover section appears between the two segments,
|
|
126
|
+
* and the technical-stop row is visible in the connection details.
|
|
127
|
+
*/
|
|
128
|
+
export const OneStop: Story = {
|
|
129
|
+
args: {
|
|
130
|
+
flight: oneStopFlight,
|
|
131
|
+
locale: 'en',
|
|
132
|
+
},
|
|
133
|
+
render: defaultRender,
|
|
134
|
+
}
|