@citizenplane/pimp 18.9.20 → 18.9.21

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@citizenplane/pimp",
3
- "version": "18.9.20",
3
+ "version": "18.9.21",
4
4
  "scripts": {
5
5
  "dev": "storybook dev -p 8081",
6
6
  "build-storybook": "storybook build --output-dir ./docs",
@@ -48,7 +48,16 @@ const emit = defineEmits<Emits>()
48
48
  const bottomSheetRef = useTemplateRef('bottomSheetRef')
49
49
  const isVisibleModel = defineModel<boolean>()
50
50
 
51
+ // Set right before syncing a self-close down to the model, so the resulting
52
+ // watch trigger doesn't re-issue a close() the underlying sheet already ran.
53
+ let skipNextToggle = false
54
+
51
55
  const toggleBottomSheet = () => {
56
+ if (skipNextToggle) {
57
+ skipNextToggle = false
58
+ return
59
+ }
60
+
52
61
  if (isVisibleModel.value) {
53
62
  bottomSheetRef.value?.open()
54
63
  return
@@ -62,7 +71,18 @@ watch(isVisibleModel, () => toggleBottomSheet())
62
71
  const onBottomSheetOpened = () => emit('open')
63
72
 
64
73
  const onBottomSheetClosed = () => {
65
- if (props.preventClose) return
74
+ if (props.preventClose) {
75
+ // The underlying sheet already closed itself (e.g. Escape key, which it
76
+ // never gates behind canBackdropClose/canSwipeClose) despite preventClose:
77
+ // reopen it so the visual state matches the model we never touched.
78
+ if (isVisibleModel.value) bottomSheetRef.value?.open()
79
+ return
80
+ }
81
+
82
+ if (isVisibleModel.value) {
83
+ skipNextToggle = true
84
+ isVisibleModel.value = false
85
+ }
66
86
 
67
87
  emit('close')
68
88
  }
@@ -5,7 +5,7 @@
5
5
  v-if="dynamicRenderingCondition"
6
6
  v-bind="dynamicComponentProps"
7
7
  ref="dynamicComponentRef"
8
- @close="emit('close')"
8
+ @close="onDynamicComponentClosed"
9
9
  >
10
10
  <!-- Header slot is only for bottom sheet -->
11
11
  <template v-if="title" #header>
@@ -38,8 +38,11 @@ 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
44
47
  isClosableOnClickOutside?: boolean
45
48
  maxWidth?: number | undefined
@@ -52,7 +55,7 @@ const props = defineProps<Props>()
52
55
 
53
56
  const emit = defineEmits<{ (e: 'close'): void }>()
54
57
 
55
- const isMobile = useIsBreakpoint()
58
+ const isMobile = useIsBreakpoint(props.breakpoint ?? Breakpoints.MOBILE)
56
59
 
57
60
  const dynamicComponentRef = useTemplateRef('dynamicComponentRef')
58
61
 
@@ -94,6 +97,11 @@ const dynamicComponentProps = computed(() => {
94
97
  }
95
98
  })
96
99
 
100
+ const onDynamicComponentClosed = () => {
101
+ isVisibleModel.value = false
102
+ emit('close')
103
+ }
104
+
97
105
  const openBottomSheet = async () => {
98
106
  await nextTick()
99
107
 
@@ -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)',