@citizenplane/pimp 18.8.1 → 18.8.3
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/CpMenu.vue.d.ts +2 -2
- package/dist/components/CpMenu.vue.d.ts.map +1 -1
- package/dist/components/CpTrip.vue.d.ts.map +1 -1
- package/dist/composables/useIsBreakpoint.d.ts +3 -0
- package/dist/composables/useIsBreakpoint.d.ts.map +1 -0
- package/dist/pimp.es.js +3137 -3130
- package/dist/pimp.umd.js +51 -51
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/assets/css/easings.css +1 -0
- package/src/assets/css/transitions.css +34 -0
- package/src/assets/main.css +1 -0
- package/src/components/CpMenu.vue +28 -46
- package/src/components/CpTrip.vue +3 -0
- package/src/composables/useIsBreakpoint.ts +16 -0
- package/src/stories/CpMenu.stories.ts +6 -3
package/package.json
CHANGED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/* Transitions classes that are globally used */
|
|
2
|
+
|
|
3
|
+
.scale-elastic-enter-active,
|
|
4
|
+
.scale-elastic-leave-active {
|
|
5
|
+
transition:
|
|
6
|
+
scale 200ms var(--cp-easing-elastic),
|
|
7
|
+
opacity 200ms ease;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.scale-elastic-enter-from,
|
|
11
|
+
.scale-elastic-leave-to {
|
|
12
|
+
opacity: 0;
|
|
13
|
+
scale: 0.9;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.drawer-enter-active,
|
|
17
|
+
.drawer-leave-active {
|
|
18
|
+
transition: transform 500ms var(--cp-easing-ease-out-quart);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.drawer-enter-from,
|
|
22
|
+
.drawer-leave-to {
|
|
23
|
+
transform: translate3d(0, 100%, 0);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.fade-enter-active,
|
|
27
|
+
.fade-leave-active {
|
|
28
|
+
transition: opacity 300ms ease;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.fade-enter-from,
|
|
32
|
+
.fade-leave-to {
|
|
33
|
+
opacity: 0;
|
|
34
|
+
}
|
package/src/assets/main.css
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="cpMenu">
|
|
3
|
+
<div v-if="isDrawer" class="cpMenu__drawerOverlay" :class="drawerOverlayDynamicClass" />
|
|
3
4
|
<div
|
|
4
5
|
ref="trigger"
|
|
5
6
|
:aria-controls="menuId"
|
|
@@ -62,25 +63,28 @@
|
|
|
62
63
|
import PrimevueDrawer from 'primevue/drawer'
|
|
63
64
|
import type { MenuItem } from 'primevue/menuitem'
|
|
64
65
|
import PrimevuePopover from 'primevue/popover'
|
|
65
|
-
import { computed, nextTick,
|
|
66
|
+
import { computed, nextTick, ref, useId } from 'vue'
|
|
67
|
+
|
|
68
|
+
import { useIsBreakpoint } from '@/composables/useIsBreakpoint'
|
|
66
69
|
|
|
67
70
|
import CpButton from '@/components/CpButton.vue'
|
|
68
71
|
import CpIcon from '@/components/CpIcon.vue'
|
|
69
72
|
import CpMenuList from '@/components/CpMenuList.vue'
|
|
70
73
|
|
|
74
|
+
import { Breakpoints } from '@/constants/layout'
|
|
71
75
|
import { getKeyboardFocusableElements } from '@/helpers/dom'
|
|
72
76
|
|
|
73
77
|
export interface Props {
|
|
74
78
|
class?: string
|
|
75
79
|
forcePopover?: boolean
|
|
76
|
-
|
|
80
|
+
isFullHeightDrawer?: boolean
|
|
77
81
|
items?: MenuItem[]
|
|
78
82
|
keepOpenOnClick?: boolean
|
|
79
83
|
}
|
|
80
84
|
|
|
81
85
|
const props = withDefaults(defineProps<Props>(), {
|
|
82
86
|
class: undefined,
|
|
83
|
-
|
|
87
|
+
isFullHeightDrawer: false,
|
|
84
88
|
items: undefined,
|
|
85
89
|
keepOpenOnClick: false,
|
|
86
90
|
})
|
|
@@ -90,37 +94,33 @@ const emits = defineEmits<{
|
|
|
90
94
|
show: []
|
|
91
95
|
}>()
|
|
92
96
|
|
|
93
|
-
const MOBILE_BREAKPOINT_PX = 640
|
|
94
|
-
|
|
95
97
|
const trigger = ref<HTMLElement | null>(null)
|
|
96
98
|
const popover = ref<InstanceType<typeof PrimevuePopover>>()
|
|
97
99
|
const closeButton = ref<InstanceType<typeof CpButton> | null>(null)
|
|
98
100
|
const isOpen = ref(false)
|
|
99
101
|
const menuId = useId()
|
|
100
102
|
|
|
101
|
-
const
|
|
102
|
-
const isMobileViewport = ref(mediaQuery.matches)
|
|
103
|
-
const onMediaChange = (event: MediaQueryListEvent) => {
|
|
104
|
-
isMobileViewport.value = event.matches
|
|
105
|
-
}
|
|
106
|
-
mediaQuery.addEventListener('change', onMediaChange)
|
|
107
|
-
onUnmounted(() => mediaQuery.removeEventListener('change', onMediaChange))
|
|
103
|
+
const isMobileViewport = useIsBreakpoint(Breakpoints.TABLET)
|
|
108
104
|
|
|
109
105
|
const isDrawer = computed(() => isMobileViewport.value && !props.forcePopover)
|
|
110
106
|
const hasItems = computed(() => props.items?.length)
|
|
111
107
|
const popupType = computed(() => (hasItems.value ? 'menu' : 'dialog'))
|
|
112
108
|
|
|
113
109
|
const popoverPt = {
|
|
114
|
-
root: { class: ['
|
|
115
|
-
content: { class: '
|
|
110
|
+
root: { class: ['cpMenu__menu', props.class] },
|
|
111
|
+
content: { class: 'cpMenu__menuContent' },
|
|
116
112
|
transition: { name: 'scale-elastic', duration: 100 },
|
|
117
113
|
}
|
|
118
114
|
|
|
115
|
+
const drawerOverlayDynamicClass = computed(() => ({
|
|
116
|
+
'cpMenu__drawerOverlay--isOpen': isOpen.value,
|
|
117
|
+
}))
|
|
118
|
+
|
|
119
119
|
const drawerPt = {
|
|
120
|
-
root: { class: ['cpMenu__drawer', { 'cpMenu__drawer--
|
|
120
|
+
root: { class: ['cpMenu__drawer', { 'cpMenu__drawer--isFullHeight': props.isFullHeightDrawer }] },
|
|
121
121
|
content: { class: 'cpMenu__drawerContent' },
|
|
122
|
-
mask: { class: 'cpMenu__drawerMask' },
|
|
123
122
|
header: { class: 'cpMenu__drawerHeader' },
|
|
123
|
+
transition: { name: 'drawer', duration: 300 },
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
const show = (event: Event) => {
|
|
@@ -171,7 +171,7 @@ defineExpose({ show, hide, toggle })
|
|
|
171
171
|
cursor: pointer;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
&
|
|
174
|
+
&__menu {
|
|
175
175
|
position: absolute;
|
|
176
176
|
min-width: calc(var(--cp-dimensions-1) * 62.5);
|
|
177
177
|
border-radius: var(--cp-radius-md);
|
|
@@ -182,18 +182,25 @@ defineExpose({ show, hide, toggle })
|
|
|
182
182
|
will-change: opacity, transform;
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
&
|
|
185
|
+
&__menuContent {
|
|
186
186
|
padding: var(--cp-spacing-sm) 0;
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
&
|
|
189
|
+
&__drawerOverlay {
|
|
190
190
|
position: fixed;
|
|
191
|
-
z-index:
|
|
191
|
+
z-index: 0;
|
|
192
192
|
display: flex;
|
|
193
193
|
align-items: flex-end;
|
|
194
194
|
justify-content: center;
|
|
195
195
|
background-color: var(--cp-background-overlay);
|
|
196
196
|
inset: 0;
|
|
197
|
+
opacity: 0;
|
|
198
|
+
pointer-events: none;
|
|
199
|
+
transition: opacity 250ms ease;
|
|
200
|
+
|
|
201
|
+
&--isOpen {
|
|
202
|
+
opacity: 1;
|
|
203
|
+
}
|
|
197
204
|
}
|
|
198
205
|
|
|
199
206
|
&__drawer {
|
|
@@ -208,7 +215,7 @@ defineExpose({ show, hide, toggle })
|
|
|
208
215
|
box-shadow: var(--cp-shadows-overlay);
|
|
209
216
|
}
|
|
210
217
|
|
|
211
|
-
&__drawer--
|
|
218
|
+
&__drawer--isFullHeight {
|
|
212
219
|
height: 100%;
|
|
213
220
|
max-height: 100%;
|
|
214
221
|
border-radius: 0;
|
|
@@ -230,29 +237,4 @@ defineExpose({ show, hide, toggle })
|
|
|
230
237
|
padding: var(--cp-spacing-md) var(--cp-spacing-xl);
|
|
231
238
|
}
|
|
232
239
|
}
|
|
233
|
-
|
|
234
|
-
.scale-elastic-enter-active,
|
|
235
|
-
.scale-elastic-leave-active {
|
|
236
|
-
transition:
|
|
237
|
-
scale 200ms var(--cp-easing-elastic),
|
|
238
|
-
opacity 200ms ease;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
.scale-elastic-enter-from,
|
|
242
|
-
.scale-elastic-leave-to {
|
|
243
|
-
opacity: 0;
|
|
244
|
-
scale: 0.9;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
.p-drawer-enter-active,
|
|
248
|
-
.p-drawer-leave-active {
|
|
249
|
-
transition:
|
|
250
|
-
transform 300ms ease,
|
|
251
|
-
opacity 250ms ease;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
.p-drawer-enter-from,
|
|
255
|
-
.p-drawer-leave-to {
|
|
256
|
-
transform: translateY(100%);
|
|
257
|
-
}
|
|
258
240
|
</style>
|
|
@@ -96,6 +96,8 @@ const uniqueAirlines = computed(() => {
|
|
|
96
96
|
|
|
97
97
|
<style lang="scss">
|
|
98
98
|
.cpTrip {
|
|
99
|
+
width: 100%;
|
|
100
|
+
|
|
99
101
|
&__header {
|
|
100
102
|
display: flex;
|
|
101
103
|
align-items: center;
|
|
@@ -126,6 +128,7 @@ const uniqueAirlines = computed(() => {
|
|
|
126
128
|
position: relative;
|
|
127
129
|
display: flex;
|
|
128
130
|
flex-direction: column;
|
|
131
|
+
align-items: flex-start;
|
|
129
132
|
justify-content: center;
|
|
130
133
|
|
|
131
134
|
&:last-child {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useWindowSize } from '@vueuse/core'
|
|
2
|
+
import { computed, onMounted, ref } from 'vue'
|
|
3
|
+
|
|
4
|
+
import { Breakpoints } from '@/constants/layout'
|
|
5
|
+
|
|
6
|
+
export const useIsBreakpoint = (breakpoint: Breakpoints = Breakpoints.MOBILE) => {
|
|
7
|
+
const isMounted = ref(false)
|
|
8
|
+
onMounted(() => (isMounted.value = true))
|
|
9
|
+
|
|
10
|
+
const { width } = useWindowSize()
|
|
11
|
+
|
|
12
|
+
return computed(() => {
|
|
13
|
+
if (!isMounted.value) return false
|
|
14
|
+
return width.value < breakpoint
|
|
15
|
+
})
|
|
16
|
+
}
|
|
@@ -29,7 +29,7 @@ const meta = {
|
|
|
29
29
|
description: 'Disable the bottom-drawer behavior on mobile and keep the popover anchored to the trigger.',
|
|
30
30
|
table: { defaultValue: { summary: 'false' } },
|
|
31
31
|
},
|
|
32
|
-
|
|
32
|
+
isFullHeightDrawer: {
|
|
33
33
|
control: 'boolean',
|
|
34
34
|
description: 'When enabled, the mobile drawer takes the full available height.',
|
|
35
35
|
table: { defaultValue: { summary: 'false' } },
|
|
@@ -132,7 +132,10 @@ export const ForcePopoverOnMobile: Story = {
|
|
|
132
132
|
*/
|
|
133
133
|
export const FullHeightDrawer: Story = {
|
|
134
134
|
args: {
|
|
135
|
-
|
|
135
|
+
isFullHeightDrawer: true,
|
|
136
|
+
},
|
|
137
|
+
globals: {
|
|
138
|
+
viewport: { value: 'mobile1', isRotated: false },
|
|
136
139
|
},
|
|
137
140
|
render: (args) => ({
|
|
138
141
|
components: { CpButton, CpMenu },
|
|
@@ -150,7 +153,7 @@ export const FullHeightDrawer: Story = {
|
|
|
150
153
|
template: `
|
|
151
154
|
<CpMenu v-bind="args" :items="items">
|
|
152
155
|
<template #trigger>
|
|
153
|
-
<CpButton>Open
|
|
156
|
+
<CpButton size="xs" appearance="secondary">Open drawer</CpButton>
|
|
154
157
|
</template>
|
|
155
158
|
</CpMenu>
|
|
156
159
|
`,
|