@citizenplane/pimp 18.7.0 → 18.8.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/biome.json +178 -0
- package/dist/components/BaseInputLabel.vue.d.ts.map +1 -1
- package/dist/components/BaseSelectClearButton.vue.d.ts.map +1 -1
- package/dist/components/CpAccordion.vue.d.ts.map +1 -1
- package/dist/components/CpAlert.vue.d.ts.map +1 -1
- package/dist/components/CpBadge.vue.d.ts.map +1 -1
- package/dist/components/CpButton.vue.d.ts.map +1 -1
- package/dist/components/CpButtonToggle.vue.d.ts +1 -1
- package/dist/components/CpButtonToggle.vue.d.ts.map +1 -1
- package/dist/components/CpCalendar.vue.d.ts.map +1 -1
- package/dist/components/CpCheckbox.vue.d.ts.map +1 -1
- package/dist/components/CpContextualMenu.vue.d.ts.map +1 -1
- package/dist/components/CpDate.vue.d.ts.map +1 -1
- package/dist/components/CpDatepicker.vue.d.ts.map +1 -1
- package/dist/components/CpInput.vue.d.ts.map +1 -1
- package/dist/components/CpItemActions.vue.d.ts.map +1 -1
- package/dist/components/CpMenu.vue.d.ts.map +1 -1
- package/dist/components/CpMenuItem.vue.d.ts.map +1 -1
- package/dist/components/CpMultiselect.vue.d.ts.map +1 -1
- package/dist/components/CpRadio.vue.d.ts.map +1 -1
- package/dist/components/CpRadioGroup.vue.d.ts.map +1 -1
- package/dist/components/CpRadioNew.vue.d.ts.map +1 -1
- package/dist/components/CpSelect.vue.d.ts.map +1 -1
- package/dist/components/CpSelectMenu.vue.d.ts.map +1 -1
- package/dist/components/CpSelectableButton.vue.d.ts +1 -1
- package/dist/components/CpSelectableButton.vue.d.ts.map +1 -1
- package/dist/components/CpSwitch.vue.d.ts.map +1 -1
- package/dist/components/CpTable.vue.d.ts.map +1 -1
- package/dist/components/CpTelInput.vue.d.ts.map +1 -1
- package/dist/components/CpTooltip.vue.d.ts +2 -0
- package/dist/components/CpTooltip.vue.d.ts.map +1 -1
- package/dist/components/CpTrip.vue.d.ts +48 -0
- package/dist/components/CpTrip.vue.d.ts.map +1 -0
- package/dist/components/CpTripTimeline.vue.d.ts +24 -0
- package/dist/components/CpTripTimeline.vue.d.ts.map +1 -0
- package/dist/components/icons/IconDestination.vue.d.ts +3 -0
- package/dist/components/icons/IconDestination.vue.d.ts.map +1 -0
- package/dist/components/icons/IconOrigin.vue.d.ts +3 -0
- package/dist/components/icons/IconOrigin.vue.d.ts.map +1 -0
- package/dist/components/index.d.ts +2 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/composables/useDynamicSize.d.ts +9 -0
- package/dist/composables/useDynamicSize.d.ts.map +1 -0
- package/dist/constants/CpCustomIcons.d.ts +2 -0
- package/dist/constants/CpCustomIcons.d.ts.map +1 -1
- package/dist/constants/index.d.ts +2 -2
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/layout/Breakpoints.d.ts +9 -0
- package/dist/constants/layout/Breakpoints.d.ts.map +1 -0
- package/dist/constants/layout/Sizes.d.ts +2 -0
- package/dist/constants/layout/Sizes.d.ts.map +1 -0
- package/dist/constants/layout/index.d.ts +3 -0
- package/dist/constants/layout/index.d.ts.map +1 -0
- package/dist/helpers/functions.d.ts +1 -0
- package/dist/helpers/functions.d.ts.map +1 -1
- package/dist/libs/CoreDatepicker.vue.d.ts.map +1 -1
- package/dist/pimp.es.js +6474 -6113
- package/dist/pimp.umd.js +54 -54
- package/dist/style.css +1 -1
- package/package.json +14 -24
- package/src/assets/css/base.css +17 -11
- package/src/assets/css/colors.css +12 -22
- package/src/assets/css/dimensions.css +4 -0
- package/src/assets/css/shadows.css +0 -3
- package/src/assets/css/tokens.css +21 -65
- package/src/assets/css/typography.css +0 -17
- package/src/assets/main.css +7 -7
- package/src/assets/styles/helpers/_functions.scss +2 -2
- package/src/assets/styles/utilities/_index.scss +2 -3
- package/src/components/BaseInputLabel.vue +7 -11
- package/src/components/BaseSelectClearButton.vue +6 -7
- package/src/components/CpAccordion.vue +27 -28
- package/src/components/CpAccordionGroup.vue +2 -2
- package/src/components/CpAlert.vue +12 -11
- package/src/components/CpBadge.vue +4 -19
- package/src/components/CpButton.vue +23 -25
- package/src/components/CpButtonGroup.vue +2 -2
- package/src/components/CpButtonToggle.vue +22 -22
- package/src/components/CpCalendar.vue +30 -26
- package/src/components/CpCheckbox.vue +29 -33
- package/src/components/CpContextualMenu.vue +1 -2
- package/src/components/CpDate.vue +72 -76
- package/src/components/CpDatepicker.vue +2 -3
- package/src/components/CpDialog.vue +8 -8
- package/src/components/CpHeading.vue +6 -6
- package/src/components/CpIcon.vue +2 -2
- package/src/components/CpInput.vue +46 -48
- package/src/components/CpItemActions.vue +10 -10
- package/src/components/CpMenu.vue +8 -9
- package/src/components/CpMenuItem.vue +7 -7
- package/src/components/CpMenuList.vue +3 -3
- package/src/components/CpMultiselect.vue +29 -30
- package/src/components/CpRadio.vue +53 -59
- package/src/components/CpRadioGroup.vue +11 -12
- package/src/components/CpRadioNew.vue +56 -58
- package/src/components/CpSelect.vue +42 -42
- package/src/components/CpSelectMenu.vue +32 -32
- package/src/components/CpSelectableButton.vue +50 -51
- package/src/components/CpSwitch.vue +43 -44
- package/src/components/CpTable.vue +69 -81
- package/src/components/CpTableColumnEditor.vue +16 -16
- package/src/components/CpTableEmptyState.vue +4 -4
- package/src/components/CpTableFooter.vue +2 -2
- package/src/components/CpTableFooterDesktop.vue +2 -2
- package/src/components/CpTableFooterDetails.vue +2 -2
- package/src/components/CpTableFooterMobile.vue +4 -4
- package/src/components/CpTabs.vue +1 -1
- package/src/components/CpTelInput.vue +31 -32
- package/src/components/CpTextarea.vue +13 -13
- package/src/components/CpToast.vue +25 -24
- package/src/components/CpTooltip.vue +15 -13
- package/src/components/CpTransitionCounter.vue +1 -1
- package/src/components/CpTransitionExpand.vue +5 -5
- package/src/components/CpTransitionSize.vue +1 -1
- package/src/components/CpTrip.vue +190 -0
- package/src/components/CpTripTimeline.vue +272 -0
- package/src/components/icons/IconDestination.vue +5 -0
- package/src/components/icons/IconOrigin.vue +5 -0
- package/src/components/index.ts +36 -34
- package/src/composables/useDynamicSize.ts +60 -0
- package/src/constants/CpCustomIcons.ts +4 -0
- package/src/constants/index.ts +2 -2
- package/src/constants/layout/Breakpoints.ts +8 -0
- package/src/constants/layout/Sizes.ts +1 -0
- package/src/constants/layout/index.ts +3 -0
- package/src/directives/ClickOutside.ts +1 -1
- package/src/directives/ResizeSelect.ts +1 -1
- package/src/helpers/functions.ts +1 -1
- package/src/helpers/index.ts +1 -1
- package/src/libs/CoreDatepicker.vue +115 -134
- package/src/stories/Colors.stories.ts +2 -1
- package/src/stories/CpAccordion.stories.ts +2 -2
- package/src/stories/CpAccordionGroup.stories.ts +1 -2
- package/src/stories/CpButtonToggle.stories.ts +1 -2
- package/src/stories/CpCheckbox.stories.ts +1 -2
- package/src/stories/CpContextualMenu.stories.ts +1 -2
- package/src/stories/CpDate.stories.ts +1 -2
- package/src/stories/CpDatepicker.stories.ts +1 -2
- package/src/stories/CpDialog.stories.ts +1 -2
- package/src/stories/CpInput.stories.ts +1 -2
- package/src/stories/CpItemActions.stories.ts +1 -2
- package/src/stories/CpMenu.stories.ts +1 -2
- package/src/stories/CpMenuItem.stories.ts +1 -2
- package/src/stories/CpMultiselect.stories.ts +1 -2
- package/src/stories/CpRadio.stories.ts +1 -2
- package/src/stories/CpRadioGroup.stories.ts +1 -2
- package/src/stories/CpSelect.stories.ts +1 -2
- package/src/stories/CpSelectMenu.stories.ts +1 -2
- package/src/stories/CpSwitch.stories.ts +1 -2
- package/src/stories/CpTable.stories.ts +2 -3
- package/src/stories/CpTabs.stories.ts +1 -2
- package/src/stories/CpText.stories.ts +2 -1
- package/src/stories/CpTextarea.stories.ts +1 -2
- package/src/stories/CpToast.stories.ts +2 -3
- package/src/stories/CpTransitionCounter.stories.ts +1 -2
- package/src/stories/CpTransitionExpand.stories.ts +1 -2
- package/src/stories/CpTransitionListItems.stories.ts +1 -2
- package/src/stories/CpTransitionSize.stories.ts +1 -2
- package/src/stories/CpTransitionSlide.stories.ts +1 -2
- package/src/stories/CpTransitionTabContent.stories.ts +1 -2
- package/src/stories/CpTrip.stories.ts +323 -0
- package/src/stories/Dimensions.stories.ts +1 -0
- package/src/stories/Shadows.stories.ts +1 -0
- package/src/stories/Typography.stories.ts +1 -0
- package/src/vendors/ff-polyfill.ts +1 -1
- package/vitest.workspace.js +1 -1
- package/src/components/Pimp.vue +0 -10
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="cpTrip">
|
|
3
|
+
<div class="cpTrip__content">
|
|
4
|
+
<div class="cpTrip__routePoint">
|
|
5
|
+
<time class="cpTrip__time" :datetime="trip.departureDate.raw">{{ trip.departureTime }}</time>
|
|
6
|
+
<span class="cpTrip__iata">{{ trip.origin.iataCode }}</span>
|
|
7
|
+
</div>
|
|
8
|
+
<cp-trip-timeline
|
|
9
|
+
:airlines="uniqueAirlines"
|
|
10
|
+
:hide-airlines="hideAirlines"
|
|
11
|
+
class="cpTrip__timeline"
|
|
12
|
+
:flight-duration="trip.flightDuration.formatted"
|
|
13
|
+
:has-self-transfer="trip.hasSelfTransfer"
|
|
14
|
+
:labels="trip.labels"
|
|
15
|
+
:stops="trip.stops"
|
|
16
|
+
/>
|
|
17
|
+
<div class="cpTrip__routePoint">
|
|
18
|
+
<time class="cpTrip__time" :datetime="trip.arrivalDate.raw">{{ trip.arrivalTime }}</time>
|
|
19
|
+
<span class="cpTrip__iata">
|
|
20
|
+
{{ trip.destination.iataCode }}
|
|
21
|
+
<span v-if="trip.dayCountAfterDeparture" class="cpTrip__plus">+{{ trip.dayCountAfterDeparture }}</span>
|
|
22
|
+
</span>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</template>
|
|
27
|
+
|
|
28
|
+
<script setup lang="ts">
|
|
29
|
+
import { computed } from 'vue'
|
|
30
|
+
|
|
31
|
+
import CpTripTimeline from '@/components/CpTripTimeline.vue'
|
|
32
|
+
|
|
33
|
+
type Trip = {
|
|
34
|
+
airlines: {
|
|
35
|
+
iataCode: string
|
|
36
|
+
name: string
|
|
37
|
+
}[];
|
|
38
|
+
arrivalDate: {
|
|
39
|
+
formatted: string
|
|
40
|
+
raw: string
|
|
41
|
+
}
|
|
42
|
+
arrivalTime: string
|
|
43
|
+
dayCountAfterDeparture?: number
|
|
44
|
+
departureDate: {
|
|
45
|
+
formatted: string
|
|
46
|
+
raw: string
|
|
47
|
+
}
|
|
48
|
+
departureTime: string
|
|
49
|
+
destination: {
|
|
50
|
+
iataCode: string
|
|
51
|
+
name: string
|
|
52
|
+
}
|
|
53
|
+
flightDuration: {
|
|
54
|
+
formatted: string
|
|
55
|
+
raw: string
|
|
56
|
+
}
|
|
57
|
+
hasSelfTransfer?: boolean
|
|
58
|
+
labels?: {
|
|
59
|
+
layover?: string
|
|
60
|
+
nonStop?: string
|
|
61
|
+
stopCount?: string
|
|
62
|
+
transfer?: string
|
|
63
|
+
}
|
|
64
|
+
origin: {
|
|
65
|
+
iataCode: string
|
|
66
|
+
name: string
|
|
67
|
+
}
|
|
68
|
+
stops?: {
|
|
69
|
+
duration: string
|
|
70
|
+
iata: string
|
|
71
|
+
name: string
|
|
72
|
+
}[]
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
interface Props {
|
|
76
|
+
hideAirlines?: boolean
|
|
77
|
+
trip: Trip
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const props = defineProps<Props>()
|
|
81
|
+
|
|
82
|
+
const uniqueAirlines = computed(() => {
|
|
83
|
+
const allAirlinesIataCodes = props.trip.airlines.map((airline) => airline.iataCode)
|
|
84
|
+
const uniqueAirlineIatas: string[] = Array.from(new Set(allAirlinesIataCodes))
|
|
85
|
+
|
|
86
|
+
const allUniqueAirlines = uniqueAirlineIatas.map((uniqueIataCode: string) => {
|
|
87
|
+
return props.trip.airlines.find((airline) => airline.iataCode === uniqueIataCode)
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
return allUniqueAirlines as {
|
|
91
|
+
iataCode: string
|
|
92
|
+
name: string
|
|
93
|
+
}[]
|
|
94
|
+
})
|
|
95
|
+
</script>
|
|
96
|
+
|
|
97
|
+
<style lang="scss">
|
|
98
|
+
.cpTrip {
|
|
99
|
+
&__header {
|
|
100
|
+
display: flex;
|
|
101
|
+
align-items: center;
|
|
102
|
+
justify-content: space-between;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
&__title {
|
|
106
|
+
color: var(--cp-text-secondary);
|
|
107
|
+
font-size: var(--cp-text-size-xs);
|
|
108
|
+
font-weight: 600;
|
|
109
|
+
line-height: var(--cp-line-height-xs);
|
|
110
|
+
padding-block: var(--cp-spacing-sm);
|
|
111
|
+
text-transform: uppercase;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
&__content {
|
|
115
|
+
display: flex;
|
|
116
|
+
align-items: center;
|
|
117
|
+
gap: var(--cp-spacing-2xl);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
&__timeline {
|
|
121
|
+
min-width: 0;
|
|
122
|
+
flex: 1;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
&__routePoint {
|
|
126
|
+
position: relative;
|
|
127
|
+
display: flex;
|
|
128
|
+
flex-direction: column;
|
|
129
|
+
justify-content: center;
|
|
130
|
+
|
|
131
|
+
&:last-child {
|
|
132
|
+
align-items: flex-end;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
&__plus {
|
|
137
|
+
position: absolute;
|
|
138
|
+
top: fn.px-to-rem(-2);
|
|
139
|
+
right: fn.px-to-rem(-12);
|
|
140
|
+
color: var(--cp-text-error-primary);
|
|
141
|
+
font-size: fn.px-to-rem(10);
|
|
142
|
+
line-height: fn.px-to-rem(14);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
&__time {
|
|
146
|
+
font-size: var(--cp-text-size-xl);
|
|
147
|
+
font-weight: 600;
|
|
148
|
+
line-height: var(--cp-line-height-xl);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
&__iata {
|
|
152
|
+
color: var(--cp-text-secondary);
|
|
153
|
+
font-size: var(--cp-text-size-md);
|
|
154
|
+
font-weight: 500;
|
|
155
|
+
line-height: var(--cp-line-height-md);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@include mx.media-query-max(370px) {
|
|
160
|
+
.cpTrip {
|
|
161
|
+
&__content {
|
|
162
|
+
gap: var(--cp-spacing-md);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@include mx.media-query-max(300px) {
|
|
168
|
+
.cpTrip {
|
|
169
|
+
&__content {
|
|
170
|
+
justify-content: center;
|
|
171
|
+
gap: var(--cp-spacing-sm);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
&__time {
|
|
175
|
+
font-size: var(--cp-text-size-lg);
|
|
176
|
+
line-height: var(--cp-line-height-sm);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
&__iata {
|
|
180
|
+
font-size: var(--cp-text-size-sm);
|
|
181
|
+
line-height: var(--cp-line-height-sm);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
&__plus {
|
|
185
|
+
font-size: fn.px-to-rem(8);
|
|
186
|
+
line-height: fn.px-to-rem(10);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
</style>
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="cpTripTimeline">
|
|
3
|
+
<div class="cpTripTimeline__information">
|
|
4
|
+
<div class="cpTripTimeline__dotWrapper">
|
|
5
|
+
<span class="cpTripTimeline__dot" />
|
|
6
|
+
</div>
|
|
7
|
+
<cp-badge :size="badgeDynamicSize">
|
|
8
|
+
{{ flightDuration }}
|
|
9
|
+
</cp-badge>
|
|
10
|
+
<cp-tooltip v-if="!hideAirlines" allow-outside-container>
|
|
11
|
+
<div class="cpTripTimeline__airlines">
|
|
12
|
+
<div
|
|
13
|
+
v-for="(airline, index) in firstAirlines"
|
|
14
|
+
:key="airline.iataCode"
|
|
15
|
+
class="cpTripTimeline__airlineLogo"
|
|
16
|
+
>
|
|
17
|
+
<span v-if="displayRemainingAirlinesCount(index)" class="cpTripTimeline__remaining">+{{ remainingAirlinesCount }}</span>
|
|
18
|
+
<cp-airline-logo v-else :iata-code="airline.iataCode" :size="logoDynamicSize" />
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
<template #content>
|
|
22
|
+
<ul class="cpTripTimeline__airlinesList">
|
|
23
|
+
<li v-for="airline in airlines" :key="airline.iataCode">{{ airline.name }}</li>
|
|
24
|
+
</ul>
|
|
25
|
+
</template>
|
|
26
|
+
</cp-tooltip>
|
|
27
|
+
<div class="cpTripTimeline__dotWrapper">
|
|
28
|
+
<span class="cpTripTimeline__dot" />
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
<cp-tooltip class="cpTripTimeline__tooltip" :disabled="!hasStops" allow-outside-container>
|
|
32
|
+
<p class="cpTripTimeline__summary">
|
|
33
|
+
<template v-if="hasStops">
|
|
34
|
+
<span class="cpTripTimeline__stop">{{ stopLabel }}</span>
|
|
35
|
+
<span v-if="hasSelfTransfer" class="cpTripTimeline__transfer">
|
|
36
|
+
{{ transferLabel }}
|
|
37
|
+
</span>
|
|
38
|
+
<span>{{ formattedStops }}</span>
|
|
39
|
+
</template>
|
|
40
|
+
<span v-else>{{ nonStopLabel }}</span>
|
|
41
|
+
</p>
|
|
42
|
+
<template #content>
|
|
43
|
+
<ul class="cpTripTimeline__stops">
|
|
44
|
+
<li v-for="stop in stops" :key="stop.iata">
|
|
45
|
+
{{ stop.duration }} {{ layoverLabel }} •
|
|
46
|
+
<template v-if="stop.selfTransferLabel">
|
|
47
|
+
{{ stop.selfTransferLabel }}
|
|
48
|
+
</template>
|
|
49
|
+
<template v-else> {{ stop.name }} ({{ stop.iata }})</template>
|
|
50
|
+
|
|
51
|
+
<hr />
|
|
52
|
+
</li>
|
|
53
|
+
</ul>
|
|
54
|
+
</template>
|
|
55
|
+
</cp-tooltip>
|
|
56
|
+
</div>
|
|
57
|
+
</template>
|
|
58
|
+
|
|
59
|
+
<script setup lang="ts">
|
|
60
|
+
import { computed } from 'vue'
|
|
61
|
+
|
|
62
|
+
import { useDynamicSize } from '@/composables/useDynamicSize'
|
|
63
|
+
|
|
64
|
+
interface Props {
|
|
65
|
+
airlines: {
|
|
66
|
+
iataCode: string;
|
|
67
|
+
name: string;
|
|
68
|
+
}[];
|
|
69
|
+
flightDuration: string;
|
|
70
|
+
hasSelfTransfer?: boolean;
|
|
71
|
+
hideAirlines?: boolean;
|
|
72
|
+
labels?: {
|
|
73
|
+
layover?: string;
|
|
74
|
+
nonStop?: string;
|
|
75
|
+
stopCount?: string;
|
|
76
|
+
transfer?: string;
|
|
77
|
+
};
|
|
78
|
+
stops?: {
|
|
79
|
+
duration: string;
|
|
80
|
+
iata: string;
|
|
81
|
+
name: string;
|
|
82
|
+
selfTransferLabel?: string;
|
|
83
|
+
}[];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const props = defineProps<Props>()
|
|
87
|
+
|
|
88
|
+
const stopLabel = computed(() => props.labels?.stopCount)
|
|
89
|
+
const layoverLabel = computed(() => props.labels?.layover)
|
|
90
|
+
const nonStopLabel = computed(() => props.labels?.nonStop)
|
|
91
|
+
const transferLabel = computed(() => props.labels?.transfer)
|
|
92
|
+
|
|
93
|
+
const badgeDynamicSize = useDynamicSize({ default: 'sm', 300: 'xs' })
|
|
94
|
+
const logoDynamicSize = useDynamicSize({ default: 24, 300: 20 })
|
|
95
|
+
|
|
96
|
+
const hasStops = computed(() => !!props.stops?.length)
|
|
97
|
+
|
|
98
|
+
const AIRLINES_LIMIT = 3
|
|
99
|
+
const firstAirlines = computed(() => props.airlines.slice(0, AIRLINES_LIMIT))
|
|
100
|
+
const hasMoreAirlinesThanLimit = computed(() => props.airlines.length > (AIRLINES_LIMIT + 1))
|
|
101
|
+
|
|
102
|
+
const formattedStops = computed(() => {
|
|
103
|
+
if (!hasStops.value) return ''
|
|
104
|
+
return props.stops!.map(({ name }) => name).join(', ')
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
const remainingAirlinesCount = computed(() => props.airlines.length - firstAirlines.value.length)
|
|
108
|
+
|
|
109
|
+
const displayRemainingAirlinesCount = (index: number) => {
|
|
110
|
+
const isLastItem = index === firstAirlines.value.length - 1
|
|
111
|
+
return hasMoreAirlinesThanLimit.value && isLastItem
|
|
112
|
+
}
|
|
113
|
+
</script>
|
|
114
|
+
|
|
115
|
+
<style lang="scss">
|
|
116
|
+
.cpTripTimeline {
|
|
117
|
+
position: relative;
|
|
118
|
+
display: flex;
|
|
119
|
+
flex-direction: column;
|
|
120
|
+
align-items: center;
|
|
121
|
+
|
|
122
|
+
&__information {
|
|
123
|
+
display: flex;
|
|
124
|
+
overflow: hidden;
|
|
125
|
+
width: 100%;
|
|
126
|
+
align-items: center;
|
|
127
|
+
justify-content: center;
|
|
128
|
+
gap: var(--cp-spacing-md);
|
|
129
|
+
padding-block: fn.px-to-rem(3);
|
|
130
|
+
|
|
131
|
+
&::before,
|
|
132
|
+
&::after {
|
|
133
|
+
display: block;
|
|
134
|
+
width: 100%;
|
|
135
|
+
min-width: 0;
|
|
136
|
+
height: fn.px-to-rem(2);
|
|
137
|
+
flex: 1 1 fn.px-to-rem(32);
|
|
138
|
+
border-radius: var(--cp-radius-xs);
|
|
139
|
+
background-color: var(--cp-border-soft);
|
|
140
|
+
content: "";
|
|
141
|
+
transform-origin: right;
|
|
142
|
+
transition: transform 300ms var(--cp-easing-elastic);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
&__dotWrapper {
|
|
147
|
+
display: flex;
|
|
148
|
+
width: fn.px-to-rem(16);
|
|
149
|
+
height: fn.px-to-rem(16);
|
|
150
|
+
align-items: center;
|
|
151
|
+
justify-content: center;
|
|
152
|
+
|
|
153
|
+
&:first-child {
|
|
154
|
+
order: -1;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
&:last-child {
|
|
158
|
+
order: 1;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
&__dot {
|
|
163
|
+
width: fn.px-to-rem(6);
|
|
164
|
+
height: fn.px-to-rem(6);
|
|
165
|
+
border-radius: var(--cp-radius-full);
|
|
166
|
+
background-color: var(--cp-foreground-quaternary);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
&__airlines {
|
|
170
|
+
position: relative;
|
|
171
|
+
display: flex;
|
|
172
|
+
flex-direction: row;
|
|
173
|
+
align-items: center;
|
|
174
|
+
gap: var(--cp-spacing-xs);
|
|
175
|
+
|
|
176
|
+
> *:not(:first-child) {
|
|
177
|
+
margin-left: calc(var(--cp-spacing-md) * -1);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
&__remaining {
|
|
182
|
+
display: flex;
|
|
183
|
+
width: fn.px-to-rem(24);
|
|
184
|
+
height: fn.px-to-rem(24);
|
|
185
|
+
align-items: center;
|
|
186
|
+
justify-content: center;
|
|
187
|
+
border-radius: var(--cp-radius-sm);
|
|
188
|
+
background: var(--cp-background-tertiary);
|
|
189
|
+
font-size: var(--cp-text-size-xs);
|
|
190
|
+
font-weight: 600;
|
|
191
|
+
line-height: var(--cp-line-height-xs);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
&__tooltip {
|
|
195
|
+
display: inline-flex;
|
|
196
|
+
width: 100%;
|
|
197
|
+
justify-content: center;
|
|
198
|
+
padding-block: var(--cp-spacing-sm);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
&__summary {
|
|
202
|
+
@extend %u-text-ellipsis;
|
|
203
|
+
|
|
204
|
+
color: var(--cp-text-secondary);
|
|
205
|
+
font-size: var(--cp-text-size-xs);
|
|
206
|
+
line-height: var(--cp-line-height-xs);
|
|
207
|
+
|
|
208
|
+
&:has(.cpTripTimeline__stop) {
|
|
209
|
+
border-bottom: 1px dashed var(--cp-border-strong);
|
|
210
|
+
cursor: help;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
span:not(:first-child)::before {
|
|
214
|
+
color: var(--cp-text-secondary);
|
|
215
|
+
content: "•";
|
|
216
|
+
font-size: var(--cp-text-size-xs);
|
|
217
|
+
letter-spacing: var(--cp-letter-spacing-xs);
|
|
218
|
+
line-height: var(--cp-line-height-xs);
|
|
219
|
+
margin-inline: var(--cp-spacing-xs);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
&__transfer {
|
|
224
|
+
color: var(--cp-text-error-primary);
|
|
225
|
+
text-transform: capitalize;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
&__stops {
|
|
229
|
+
max-width: fn.px-to-rem(300);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
&__stops li hr {
|
|
233
|
+
border-radius: var(--cp-radius-md);
|
|
234
|
+
margin-block: var(--cp-spacing-md);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
&__stops li:last-child hr {
|
|
238
|
+
display: none;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
@include mx.media-query-max(370px) {
|
|
243
|
+
.cpTripTimeline {
|
|
244
|
+
&__dotWrapper {
|
|
245
|
+
display: none;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
@include mx.media-query-max(300px) {
|
|
251
|
+
.cpTripTimeline {
|
|
252
|
+
&__information {
|
|
253
|
+
padding-block: 0;
|
|
254
|
+
|
|
255
|
+
&::before,
|
|
256
|
+
&::after {
|
|
257
|
+
display: none;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
&__remaining {
|
|
262
|
+
width: fn.px-to-rem(20);
|
|
263
|
+
height: fn.px-to-rem(20);
|
|
264
|
+
font-size: fn.px-to-rem(10);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
&__tooltip {
|
|
268
|
+
padding-block: var(--cp-spacing-xs);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
</style>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
|
3
|
+
<path d="M16 11.9999C16 9.02546 18.1644 6.55652 21.0042 6.08217C21.5489 5.99118 22 6.44763 22 6.99992C22 7.5522 21.5453 7.98709 21.0101 8.12334C19.2798 8.56386 18 10.1324 18 11.9999C18 13.8674 19.2798 15.436 21.0101 15.8765C21.5453 16.0127 22 16.4476 22 16.9999C22 17.5522 21.5489 18.0087 21.0042 17.9177C18.1644 17.4433 16 14.9744 16 11.9999ZM11.5859 12.9999L9.29297 15.2929C8.90244 15.6834 8.90244 16.3164 9.29297 16.7069C9.68349 17.0975 10.3165 17.0975 10.707 16.7069L14.6967 12.7173C14.8838 12.5356 15 12.2813 15 11.9999C15 11.7185 14.8838 11.4642 14.6967 11.2825L10.707 7.29288C10.3165 6.90236 9.68349 6.90236 9.29297 7.29288C8.90244 7.68341 8.90244 8.31642 9.29297 8.70695L11.5859 10.9999H2C1.44772 10.9999 1 11.4476 1 11.9999C1 12.5522 1.44772 12.9999 2 12.9999H11.5859Z"/>
|
|
4
|
+
</svg>
|
|
5
|
+
</template>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
|
3
|
+
<path d="M2 6.99992C2 6.44763 2.45108 5.99118 2.99581 6.08217C5.83559 6.55653 8 9.02546 8 11.9999C8 14.9744 5.83559 17.4433 2.99581 17.9177C2.45107 18.0087 2 17.5522 2 16.9999C2 16.4476 2.45467 16.0127 2.98988 15.8765C4.72024 15.436 6 13.8674 6 11.9999C6 10.1324 4.72024 8.56386 2.98988 8.12334C2.45467 7.98709 2 7.5522 2 6.99992ZM19.5859 13H10C9.44771 13 9 12.5523 9 12C9 11.4478 9.44771 11 10 11H19.5859L17.293 8.70707C16.9024 8.31655 16.9024 7.68353 17.293 7.29301C17.6835 6.90248 18.3165 6.90248 18.707 7.29301L22.707 11.293C23.0976 11.6835 23.0976 12.3165 22.707 12.7071L18.707 16.7071C18.3165 17.0976 17.6835 17.0976 17.293 16.7071C16.9024 16.3165 16.9024 15.6835 17.293 15.293L19.5859 13Z"/>
|
|
4
|
+
</svg>
|
|
5
|
+
</template>
|
package/src/components/index.ts
CHANGED
|
@@ -8,11 +8,10 @@ import { vTooltip } from 'floating-vue'
|
|
|
8
8
|
import { vMaska } from 'maska/vue'
|
|
9
9
|
import PrimeVue from 'primevue/config'
|
|
10
10
|
import ToastService from 'primevue/toastservice'
|
|
11
|
+
import type { App, Plugin } from 'vue'
|
|
11
12
|
import { BindOnceDirective } from 'vue-bind-once'
|
|
12
13
|
import VueTelInput from 'vue-tel-input'
|
|
13
14
|
|
|
14
|
-
import type { App, Plugin } from 'vue'
|
|
15
|
-
|
|
16
15
|
import ClickOutside from '../directives/ClickOutside'
|
|
17
16
|
import CpCoreDatepicker from '../libs/CoreDatepicker.vue'
|
|
18
17
|
import CpAccordion from './CpAccordion.vue'
|
|
@@ -60,6 +59,7 @@ import CpTransitionListItems from './CpTransitionListItems.vue'
|
|
|
60
59
|
import CpTransitionSize from './CpTransitionSize.vue'
|
|
61
60
|
import CpTransitionSlide from './CpTransitionSlide.vue'
|
|
62
61
|
import CpTransitionTabContent from './CpTransitionTabContent.vue'
|
|
62
|
+
import CpTrip from './CpTrip.vue'
|
|
63
63
|
import IconAirline from './icons/IconAirline.vue'
|
|
64
64
|
import IconCheckList from './icons/IconCheckList.vue'
|
|
65
65
|
import IconCollapse from './icons/IconCollapse.vue'
|
|
@@ -126,6 +126,7 @@ const Components = {
|
|
|
126
126
|
CpTransitionListItems,
|
|
127
127
|
CpTransitionSlide,
|
|
128
128
|
CpTransitionTabContent,
|
|
129
|
+
CpTrip,
|
|
129
130
|
}
|
|
130
131
|
|
|
131
132
|
const Pimp: Plugin = {
|
|
@@ -149,59 +150,60 @@ const Pimp: Plugin = {
|
|
|
149
150
|
export {
|
|
150
151
|
CpAccordion,
|
|
151
152
|
CpAccordionGroup,
|
|
152
|
-
|
|
153
|
-
|
|
153
|
+
CpAirlineLogo,
|
|
154
|
+
CpAlert,
|
|
154
155
|
CpBadge,
|
|
155
|
-
CpTabs,
|
|
156
|
-
CpHeading,
|
|
157
156
|
CpButton,
|
|
158
157
|
CpButtonGroup,
|
|
159
|
-
|
|
160
|
-
|
|
158
|
+
CpButtonToggle,
|
|
159
|
+
CpCalendar,
|
|
160
|
+
CpCheckbox,
|
|
161
161
|
CpContextualMenu,
|
|
162
|
-
CpMenu,
|
|
163
|
-
CpMenuItem,
|
|
164
|
-
CpMenuList,
|
|
165
|
-
CpItemActions,
|
|
166
162
|
CpCoreDatepicker,
|
|
163
|
+
CpDate,
|
|
167
164
|
CpDatepicker,
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
CpLoader,
|
|
165
|
+
CpDialog,
|
|
166
|
+
CpHeading,
|
|
167
|
+
CpIcon,
|
|
172
168
|
CpInput,
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
169
|
+
CpItemActions,
|
|
170
|
+
CpLoader,
|
|
171
|
+
CpMenu,
|
|
172
|
+
CpMenuItem,
|
|
173
|
+
CpMenuList,
|
|
177
174
|
CpMultiselect,
|
|
178
|
-
CpCheckbox,
|
|
179
175
|
CpRadio,
|
|
180
176
|
CpRadioGroup,
|
|
177
|
+
CpRadioNew,
|
|
178
|
+
CpSelect,
|
|
181
179
|
CpSelectableButton,
|
|
180
|
+
CpSelectMenu,
|
|
182
181
|
CpSwitch,
|
|
183
182
|
CpTable,
|
|
184
183
|
CpTableColumnEditor,
|
|
185
|
-
|
|
184
|
+
CpTabs,
|
|
186
185
|
CpTelInput,
|
|
186
|
+
CpText,
|
|
187
|
+
CpTextarea,
|
|
188
|
+
CpToast,
|
|
187
189
|
CpTooltip,
|
|
188
|
-
|
|
189
|
-
IconAirline,
|
|
190
|
-
IconOta,
|
|
191
|
-
IconSupplier,
|
|
192
|
-
IconThirdParty,
|
|
193
|
-
IconTooltip,
|
|
194
|
-
IconGroupBy,
|
|
195
|
-
IconCollapse,
|
|
196
|
-
IconExpand,
|
|
197
|
-
IconCheckList,
|
|
190
|
+
CpTransitionCounter,
|
|
198
191
|
CpTransitionDialog,
|
|
199
192
|
CpTransitionExpand,
|
|
200
|
-
CpTransitionSize,
|
|
201
|
-
CpTransitionCounter,
|
|
202
193
|
CpTransitionListItems,
|
|
194
|
+
CpTransitionSize,
|
|
203
195
|
CpTransitionSlide,
|
|
204
196
|
CpTransitionTabContent,
|
|
197
|
+
CpTrip,
|
|
198
|
+
IconAirline,
|
|
199
|
+
IconCheckList,
|
|
200
|
+
IconCollapse,
|
|
201
|
+
IconExpand,
|
|
202
|
+
IconGroupBy,
|
|
203
|
+
IconOta,
|
|
204
|
+
IconSupplier,
|
|
205
|
+
IconThirdParty,
|
|
206
|
+
IconTooltip,
|
|
205
207
|
}
|
|
206
208
|
|
|
207
209
|
export default Pimp
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { useWindowSize } from '@vueuse/core'
|
|
2
|
+
import { computed, onMounted, ref } from 'vue'
|
|
3
|
+
|
|
4
|
+
import type { Sizes } from '@/constants/layout'
|
|
5
|
+
|
|
6
|
+
import { Breakpoints } from '@/constants/layout'
|
|
7
|
+
|
|
8
|
+
type SizeValue = Sizes | number
|
|
9
|
+
|
|
10
|
+
type BreakpointName = 'mobile' | 'tablet' | 'largeTablet' | 'desktop' | 'large'
|
|
11
|
+
|
|
12
|
+
const NAMED_BREAKPOINTS: Record<BreakpointName, number> = {
|
|
13
|
+
mobile: Breakpoints.MOBILE,
|
|
14
|
+
tablet: Breakpoints.TABLET,
|
|
15
|
+
largeTablet: Breakpoints.LARGE_TABLET,
|
|
16
|
+
desktop: Breakpoints.DESKTOP,
|
|
17
|
+
large: Breakpoints.LARGE,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type DynamicSizeConfig = {
|
|
21
|
+
default: SizeValue
|
|
22
|
+
} & Partial<Record<number | BreakpointName, SizeValue>>
|
|
23
|
+
|
|
24
|
+
const resolveThreshold = (key: string): number => {
|
|
25
|
+
if (key in NAMED_BREAKPOINTS) {
|
|
26
|
+
return NAMED_BREAKPOINTS[key as BreakpointName]
|
|
27
|
+
}
|
|
28
|
+
return Number(key)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const resolveSize = (width: number, config: DynamicSizeConfig): SizeValue => {
|
|
32
|
+
const { default: defaultValue, ...breakpoints } = config
|
|
33
|
+
|
|
34
|
+
let match: SizeValue | undefined
|
|
35
|
+
let matchThreshold = -1
|
|
36
|
+
|
|
37
|
+
for (const [key, value] of Object.entries(breakpoints)) {
|
|
38
|
+
const threshold = resolveThreshold(key)
|
|
39
|
+
if (width <= threshold && threshold > matchThreshold) {
|
|
40
|
+
match = value
|
|
41
|
+
matchThreshold = threshold
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return match ?? defaultValue
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const useDynamicSize = (config: DynamicSizeConfig) => {
|
|
49
|
+
if (import.meta.env.SSR) return config.default
|
|
50
|
+
|
|
51
|
+
const isMounted = ref(false)
|
|
52
|
+
onMounted(() => (isMounted.value = true))
|
|
53
|
+
|
|
54
|
+
const { width: windowWidth } = useWindowSize()
|
|
55
|
+
|
|
56
|
+
return computed(() => {
|
|
57
|
+
if (!isMounted.value) return config.default
|
|
58
|
+
return resolveSize(windowWidth.value, config)
|
|
59
|
+
})
|
|
60
|
+
}
|
|
@@ -38,6 +38,7 @@ import IconCorrosive from '@/components/icons/IconCorrosive.vue'
|
|
|
38
38
|
import IconDashedCircle from '@/components/icons/IconDashedCircle.vue'
|
|
39
39
|
import IconDedicated from '@/components/icons/IconDedicated.vue'
|
|
40
40
|
import IconDeparture from '@/components/icons/IconDeparture.vue'
|
|
41
|
+
import IconDestination from '@/components/icons/IconDestination.vue'
|
|
41
42
|
import IconDeviceForbidden from '@/components/icons/IconDeviceForbidden.vue'
|
|
42
43
|
import IconDirectFlightAlt from '@/components/icons/IconDirectFlightAlt.vue'
|
|
43
44
|
import IconDistribution from '@/components/icons/IconDistribution.vue'
|
|
@@ -92,6 +93,7 @@ import IconNoSeat from '@/components/icons/IconNoSeat.vue'
|
|
|
92
93
|
import IconNotion from '@/components/icons/IconNotion.vue'
|
|
93
94
|
import IconOffline from '@/components/icons/IconOffline.vue'
|
|
94
95
|
import IconOneWay from '@/components/icons/IconOneWay.vue'
|
|
96
|
+
import IconOrigin from '@/components/icons/IconOrigin.vue'
|
|
95
97
|
import IconOta from '@/components/icons/IconOta.vue'
|
|
96
98
|
import IconOtaFilled from '@/components/icons/IconOtaFilled.vue'
|
|
97
99
|
import IconPaid from '@/components/icons/IconPaid.vue'
|
|
@@ -173,6 +175,7 @@ export const CustomCpIcons = {
|
|
|
173
175
|
dedicated: IconDedicated,
|
|
174
176
|
departure: IconDeparture,
|
|
175
177
|
'direct-flight-alt': IconDirectFlightAlt,
|
|
178
|
+
destination: IconDestination,
|
|
176
179
|
'device-forbidden': IconDeviceForbidden,
|
|
177
180
|
distribution: IconDistribution,
|
|
178
181
|
'distribution-closed': IconDistributionClosed,
|
|
@@ -226,6 +229,7 @@ export const CustomCpIcons = {
|
|
|
226
229
|
notion: IconNotion,
|
|
227
230
|
offline: IconOffline,
|
|
228
231
|
'one-way': IconOneWay,
|
|
232
|
+
origin: IconOrigin,
|
|
229
233
|
ota: IconOta,
|
|
230
234
|
'ota-filled': IconOtaFilled,
|
|
231
235
|
paid: IconPaid,
|
package/src/constants/index.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
export type { Colors } from './colors/Colors'
|
|
2
|
-
export { Position } from './Position'
|
|
3
2
|
export type { ToggleColors } from './colors/ToggleColors'
|
|
4
|
-
export { RESERVED_KEYS, VISIBLE_ROWS_MAX } from './CpTableConfig'
|
|
5
3
|
export type { Sizes } from './Sizes'
|
|
6
4
|
|
|
7
5
|
export { CustomCpIcons } from './CpCustomIcons'
|
|
6
|
+
export { RESERVED_KEYS, VISIBLE_ROWS_MAX } from './CpTableConfig'
|
|
8
7
|
export { Intent } from './Intent'
|
|
8
|
+
export { Position } from './Position'
|
|
9
9
|
|
|
10
10
|
export const HUMAN_MAX_AGE = 120
|