@citizenplane/pimp 18.9.20 → 18.9.22
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/CpBottomSheet.vue.d.ts +6 -0
- package/dist/components/CpBottomSheet.vue.d.ts.map +1 -1
- package/dist/components/CpDynamicDialog.vue.d.ts +3 -0
- package/dist/components/CpDynamicDialog.vue.d.ts.map +1 -1
- package/dist/pimp.es.js +49 -22
- package/dist/pimp.umd.js +2 -2
- package/package.json +1 -1
- package/src/components/CpBottomSheet.vue +36 -4
- package/src/components/CpDynamicDialog.vue +14 -2
- package/src/stories/CpBottomSheet.stories.ts +24 -0
- package/src/stories/CpDynamicDialog.stories.ts +5 -0
package/package.json
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
:can-backdrop-close="canBackdropClose"
|
|
5
5
|
:can-swipe-close="canSwipeClose"
|
|
6
6
|
:duration="animationDuration"
|
|
7
|
-
expand-on-content-drag
|
|
7
|
+
:expand-on-content-drag="expandOnContentDrag"
|
|
8
8
|
:swipe-close-threshold="swipeCloseThreshold"
|
|
9
9
|
teleport-defer
|
|
10
|
+
:snap-points="resolvedSnapPoints"
|
|
10
11
|
@closed="onBottomSheetClosed"
|
|
11
12
|
@opened="onBottomSheetOpened"
|
|
12
13
|
>
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
|
|
25
26
|
<script setup lang="ts">
|
|
26
27
|
import VueBottomSheet from '@douxcode/vue-spring-bottom-sheet'
|
|
27
|
-
import { useTemplateRef, watch } from 'vue'
|
|
28
|
+
import { computed, useTemplateRef, watch } from 'vue'
|
|
28
29
|
|
|
29
30
|
interface Emits {
|
|
30
31
|
(e: 'close' | 'open'): void
|
|
@@ -34,13 +35,19 @@ interface Props {
|
|
|
34
35
|
animationDuration?: number
|
|
35
36
|
canBackdropClose?: boolean
|
|
36
37
|
canSwipeClose?: boolean
|
|
38
|
+
expandOnContentDrag?: boolean
|
|
39
|
+
halfAndExpand?: boolean
|
|
37
40
|
preventClose?: boolean
|
|
41
|
+
snapPoints?: Array<number | `${number}%`>
|
|
38
42
|
swipeCloseThreshold?: string
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
const props = withDefaults(defineProps<Props>(), {
|
|
42
46
|
animationDuration: 300,
|
|
43
|
-
|
|
47
|
+
expandOnContentDrag: true,
|
|
48
|
+
halfAndExpand: false,
|
|
49
|
+
snapPoints: () => [],
|
|
50
|
+
swipeCloseThreshold: '40%',
|
|
44
51
|
})
|
|
45
52
|
|
|
46
53
|
const emit = defineEmits<Emits>()
|
|
@@ -48,7 +55,21 @@ const emit = defineEmits<Emits>()
|
|
|
48
55
|
const bottomSheetRef = useTemplateRef('bottomSheetRef')
|
|
49
56
|
const isVisibleModel = defineModel<boolean>()
|
|
50
57
|
|
|
58
|
+
const resolvedSnapPoints = computed((): Array<number | `${number}%`> | undefined => {
|
|
59
|
+
if (props.snapPoints?.length) return props.snapPoints
|
|
60
|
+
return props.halfAndExpand ? ([`${50}%`, `${100}%`] as Array<number | `${number}%`>) : undefined
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
// Set right before syncing a self-close down to the model, so the resulting
|
|
64
|
+
// watch trigger doesn't re-issue a close() the underlying sheet already ran.
|
|
65
|
+
let skipNextToggle = false
|
|
66
|
+
|
|
51
67
|
const toggleBottomSheet = () => {
|
|
68
|
+
if (skipNextToggle) {
|
|
69
|
+
skipNextToggle = false
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
|
|
52
73
|
if (isVisibleModel.value) {
|
|
53
74
|
bottomSheetRef.value?.open()
|
|
54
75
|
return
|
|
@@ -62,7 +83,18 @@ watch(isVisibleModel, () => toggleBottomSheet())
|
|
|
62
83
|
const onBottomSheetOpened = () => emit('open')
|
|
63
84
|
|
|
64
85
|
const onBottomSheetClosed = () => {
|
|
65
|
-
if (props.preventClose)
|
|
86
|
+
if (props.preventClose) {
|
|
87
|
+
// The underlying sheet already closed itself (e.g. Escape key, which it
|
|
88
|
+
// never gates behind canBackdropClose/canSwipeClose) despite preventClose:
|
|
89
|
+
// reopen it so the visual state matches the model we never touched.
|
|
90
|
+
if (isVisibleModel.value) bottomSheetRef.value?.open()
|
|
91
|
+
return
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (isVisibleModel.value) {
|
|
95
|
+
skipNextToggle = true
|
|
96
|
+
isVisibleModel.value = false
|
|
97
|
+
}
|
|
66
98
|
|
|
67
99
|
emit('close')
|
|
68
100
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
v-if="dynamicRenderingCondition"
|
|
6
6
|
v-bind="dynamicComponentProps"
|
|
7
7
|
ref="dynamicComponentRef"
|
|
8
|
-
@close="
|
|
8
|
+
@close="onDynamicComponentClosed"
|
|
9
9
|
>
|
|
10
10
|
<!-- Header slot is only for bottom sheet -->
|
|
11
11
|
<template v-if="title" #header>
|
|
@@ -38,9 +38,14 @@ import CpBottomSheet from '@/components/CpBottomSheet.vue'
|
|
|
38
38
|
import CpDialog from '@/components/CpDialog.vue'
|
|
39
39
|
import CpTransitionDialog from '@/components/CpTransitionDialog.vue'
|
|
40
40
|
|
|
41
|
+
import { Breakpoints } from '@/constants/layout'
|
|
42
|
+
|
|
41
43
|
|
|
42
44
|
interface Props {
|
|
45
|
+
breakpoint?: number
|
|
43
46
|
class?: string
|
|
47
|
+
expandOnContentDrag?: boolean
|
|
48
|
+
halfAndExpand?: boolean
|
|
44
49
|
isClosableOnClickOutside?: boolean
|
|
45
50
|
maxWidth?: number | undefined
|
|
46
51
|
preventClose?: boolean
|
|
@@ -52,7 +57,7 @@ const props = defineProps<Props>()
|
|
|
52
57
|
|
|
53
58
|
const emit = defineEmits<{ (e: 'close'): void }>()
|
|
54
59
|
|
|
55
|
-
const isMobile = useIsBreakpoint()
|
|
60
|
+
const isMobile = useIsBreakpoint(props.breakpoint ?? Breakpoints.MOBILE)
|
|
56
61
|
|
|
57
62
|
const dynamicComponentRef = useTemplateRef('dynamicComponentRef')
|
|
58
63
|
|
|
@@ -80,7 +85,9 @@ const dynamicComponentProps = computed(() => {
|
|
|
80
85
|
contentClass: props.class,
|
|
81
86
|
canBackdropClose: !props.preventClose,
|
|
82
87
|
canSwipeClose: !props.preventClose,
|
|
88
|
+
expandOnContentDrag: props.expandOnContentDrag,
|
|
83
89
|
preventClose: props.preventClose,
|
|
90
|
+
halfAndExpand: props.halfAndExpand,
|
|
84
91
|
}
|
|
85
92
|
}
|
|
86
93
|
|
|
@@ -94,6 +101,11 @@ const dynamicComponentProps = computed(() => {
|
|
|
94
101
|
}
|
|
95
102
|
})
|
|
96
103
|
|
|
104
|
+
const onDynamicComponentClosed = () => {
|
|
105
|
+
isVisibleModel.value = false
|
|
106
|
+
emit('close')
|
|
107
|
+
}
|
|
108
|
+
|
|
97
109
|
const openBottomSheet = async () => {
|
|
98
110
|
await nextTick()
|
|
99
111
|
|
|
@@ -66,6 +66,30 @@ export const Default: Story = {
|
|
|
66
66
|
>
|
|
67
67
|
<template #header><strong>Header slot</strong></template>
|
|
68
68
|
<p>This is the default slot content. You can put any content here.</p>
|
|
69
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
70
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
71
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
72
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
73
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
74
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
75
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
76
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
77
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
78
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
79
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
80
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
81
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
82
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
83
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
84
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
85
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
86
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
87
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
88
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
89
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
90
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
91
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
92
|
+
<p>This is the default slot content. You can put any content here.</p>
|
|
69
93
|
<template #footer>
|
|
70
94
|
<CpButton @click="isVisible = false">Close</CpButton>
|
|
71
95
|
</template>
|
|
@@ -43,6 +43,11 @@ const meta = {
|
|
|
43
43
|
},
|
|
44
44
|
},
|
|
45
45
|
argTypes: {
|
|
46
|
+
breakpoint: {
|
|
47
|
+
control: 'number',
|
|
48
|
+
description:
|
|
49
|
+
'Viewport width (px) below which the dialog switches to a bottom sheet. Defaults to Breakpoints.MOBILE (552)',
|
|
50
|
+
},
|
|
46
51
|
maxWidth: {
|
|
47
52
|
control: 'number',
|
|
48
53
|
description: 'Maximum width of the desktop dialog (px)',
|