@skyservice-developers/vue-dev-kit 1.1.1 → 1.1.2
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/vue2/style.css +1 -1
- package/dist/vue2/vue-dev-kit.cjs +1 -1
- package/dist/vue2/vue-dev-kit.js +3 -3
- package/dist/vue3/style.css +1 -1
- package/dist/vue3/vue-dev-kit.cjs +1 -1
- package/dist/vue3/vue-dev-kit.js +246 -228
- package/package.json +1 -1
- package/src/vue2/components/DialogModal.vue +87 -55
- package/src/vue2/components/Header.vue +28 -18
- package/src/vue3/components/DialogModal.vue +117 -71
- package/src/vue3/components/DialogNext.vue +117 -72
- package/src/vue3/components/Header.vue +29 -18
- package/src/vue3/components/Modal.vue +62 -40
|
@@ -6,18 +6,34 @@
|
|
|
6
6
|
class="sky-dialogbox sky-dialogbox-next"
|
|
7
7
|
:style="[zIndex ? { 'z-index': zIndex } : null]"
|
|
8
8
|
>
|
|
9
|
-
<div
|
|
9
|
+
<div
|
|
10
|
+
class="sky-dialog-overlay"
|
|
11
|
+
:class="{ 'sky-dialog-animate': enableAnimation }"
|
|
12
|
+
>
|
|
10
13
|
<div ref="dialogContent" class="sky-dialog-content">
|
|
11
14
|
<!-- Header -->
|
|
12
15
|
<button class="sky-dialog-back" :title="closeText" @click="close">
|
|
13
|
-
<svg
|
|
14
|
-
|
|
16
|
+
<svg
|
|
17
|
+
width="15"
|
|
18
|
+
height="15"
|
|
19
|
+
viewBox="0 0 451.847 451.847"
|
|
20
|
+
style="transform: rotate(90deg)"
|
|
21
|
+
>
|
|
22
|
+
<path
|
|
23
|
+
fill="currentColor"
|
|
24
|
+
d="M225.923,354.706c-8.098,0-16.195-3.092-22.369-9.263L9.27,151.157c-12.359-12.359-12.359-32.397,0-44.751c12.354-12.354,32.388-12.354,44.748,0l171.905,171.915l171.906-171.909c12.359-12.354,32.391-12.354,44.744,0c12.365,12.354,12.365,32.392,0,44.751L248.292,345.449C242.115,351.621,234.018,354.706,225.923,354.706z"
|
|
25
|
+
/>
|
|
15
26
|
</svg>
|
|
16
27
|
</button>
|
|
17
28
|
|
|
18
|
-
<div
|
|
29
|
+
<div
|
|
30
|
+
class="sky-dialog-title"
|
|
31
|
+
:class="{ 'sky-dialog-title-with-subtitle': subtitle }"
|
|
32
|
+
>
|
|
19
33
|
{{ title }}
|
|
20
|
-
<span v-if="subtitle" class="sky-dialog-subtitle">{{
|
|
34
|
+
<span v-if="subtitle" class="sky-dialog-subtitle">{{
|
|
35
|
+
subtitle
|
|
36
|
+
}}</span>
|
|
21
37
|
</div>
|
|
22
38
|
|
|
23
39
|
<div class="sky-dialog-clearfix" />
|
|
@@ -34,10 +50,17 @@
|
|
|
34
50
|
<div v-if="isIos" class="sky-dialog-swipe-area" />
|
|
35
51
|
<slot></slot>
|
|
36
52
|
</div>
|
|
37
|
-
|
|
38
53
|
<!-- Footer -->
|
|
39
|
-
<div
|
|
54
|
+
<div></div>
|
|
55
|
+
<div
|
|
56
|
+
v-if="showFooter"
|
|
57
|
+
class="sky-dialog-footer"
|
|
58
|
+
:class="{ 'sky-dialog-footer-animate': enableAnimation }"
|
|
59
|
+
>
|
|
60
|
+
<!-- Порожні блоки ремонтують відображення на windows в додатку, не видаляти! -->
|
|
61
|
+
<div></div>
|
|
40
62
|
<slot name="buttons"></slot>
|
|
63
|
+
<div></div>
|
|
41
64
|
</div>
|
|
42
65
|
</div>
|
|
43
66
|
</div>
|
|
@@ -47,148 +70,162 @@
|
|
|
47
70
|
</template>
|
|
48
71
|
|
|
49
72
|
<script setup>
|
|
50
|
-
import {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
73
|
+
import {
|
|
74
|
+
ref,
|
|
75
|
+
computed,
|
|
76
|
+
watch,
|
|
77
|
+
onMounted,
|
|
78
|
+
onUnmounted,
|
|
79
|
+
nextTick,
|
|
80
|
+
useSlots,
|
|
81
|
+
} from "vue";
|
|
82
|
+
import {
|
|
83
|
+
isIosWebview,
|
|
84
|
+
isAndroidWebview,
|
|
85
|
+
} from "../../shared/utils/webviewCheck";
|
|
86
|
+
|
|
87
|
+
const slots = useSlots();
|
|
54
88
|
|
|
55
89
|
const props = defineProps({
|
|
56
90
|
modelValue: {
|
|
57
91
|
type: Boolean,
|
|
58
|
-
default: false
|
|
92
|
+
default: false,
|
|
59
93
|
},
|
|
60
94
|
title: {
|
|
61
95
|
type: String,
|
|
62
|
-
default:
|
|
96
|
+
default: "",
|
|
63
97
|
},
|
|
64
98
|
subtitle: {
|
|
65
99
|
type: String,
|
|
66
|
-
default:
|
|
100
|
+
default: "",
|
|
67
101
|
},
|
|
68
102
|
zIndex: {
|
|
69
103
|
type: [Number, String],
|
|
70
|
-
default: null
|
|
104
|
+
default: null,
|
|
71
105
|
},
|
|
72
106
|
closeText: {
|
|
73
107
|
type: String,
|
|
74
|
-
default:
|
|
108
|
+
default: "Назад",
|
|
75
109
|
},
|
|
76
110
|
enableAnimation: {
|
|
77
111
|
type: Boolean,
|
|
78
|
-
default: true
|
|
112
|
+
default: true,
|
|
79
113
|
},
|
|
80
114
|
closeOnEsc: {
|
|
81
115
|
type: Boolean,
|
|
82
|
-
default: true
|
|
116
|
+
default: true,
|
|
83
117
|
},
|
|
84
118
|
hasButtons: {
|
|
85
119
|
type: Boolean,
|
|
86
|
-
default: null
|
|
87
|
-
}
|
|
88
|
-
})
|
|
120
|
+
default: null,
|
|
121
|
+
},
|
|
122
|
+
});
|
|
89
123
|
|
|
90
|
-
const emit = defineEmits([
|
|
124
|
+
const emit = defineEmits(["update:modelValue", "close", "save"]);
|
|
91
125
|
|
|
92
|
-
const dialogContent = ref(null)
|
|
93
|
-
const dialogPaper = ref(null)
|
|
94
|
-
const touchStartX = ref(0)
|
|
126
|
+
const dialogContent = ref(null);
|
|
127
|
+
const dialogPaper = ref(null);
|
|
128
|
+
const touchStartX = ref(0);
|
|
95
129
|
|
|
96
130
|
const isIos = computed(() => {
|
|
97
131
|
try {
|
|
98
|
-
return isIosWebview()
|
|
132
|
+
return isIosWebview();
|
|
99
133
|
} catch {
|
|
100
|
-
return false
|
|
134
|
+
return false;
|
|
101
135
|
}
|
|
102
|
-
})
|
|
136
|
+
});
|
|
103
137
|
|
|
104
138
|
const isAndroid = computed(() => {
|
|
105
139
|
try {
|
|
106
|
-
return isAndroidWebview()
|
|
140
|
+
return isAndroidWebview();
|
|
107
141
|
} catch {
|
|
108
|
-
return false
|
|
142
|
+
return false;
|
|
109
143
|
}
|
|
110
|
-
})
|
|
144
|
+
});
|
|
111
145
|
|
|
112
146
|
// Determine if footer should be shown
|
|
113
147
|
const showFooter = computed(() => {
|
|
114
148
|
// If hasButtons prop is explicitly set, use it
|
|
115
149
|
if (props.hasButtons !== null) {
|
|
116
|
-
return props.hasButtons
|
|
150
|
+
return props.hasButtons;
|
|
117
151
|
}
|
|
118
152
|
// Fallback to slot check (for direct usage without Dialog wrapper)
|
|
119
|
-
return !!slots.buttons
|
|
120
|
-
})
|
|
153
|
+
return !!slots.buttons;
|
|
154
|
+
});
|
|
121
155
|
|
|
122
156
|
const close = () => {
|
|
123
|
-
emit(
|
|
124
|
-
emit(
|
|
125
|
-
}
|
|
157
|
+
emit("update:modelValue", false);
|
|
158
|
+
emit("close");
|
|
159
|
+
};
|
|
126
160
|
|
|
127
161
|
const handleKeydown = (e) => {
|
|
128
|
-
if (e.key ===
|
|
129
|
-
close()
|
|
162
|
+
if (e.key === "Escape" && props.closeOnEsc && props.modelValue) {
|
|
163
|
+
close();
|
|
130
164
|
}
|
|
131
|
-
if (e.key ===
|
|
132
|
-
emit(
|
|
165
|
+
if (e.key === "Enter" && props.modelValue) {
|
|
166
|
+
emit("save");
|
|
133
167
|
}
|
|
134
|
-
}
|
|
168
|
+
};
|
|
135
169
|
|
|
136
170
|
// Touch handling for iOS swipe back
|
|
137
171
|
const handleTouchStart = (e) => {
|
|
138
172
|
if (e.touches[0].clientX < 35) {
|
|
139
|
-
touchStartX.value = e.touches[0].clientX
|
|
173
|
+
touchStartX.value = e.touches[0].clientX;
|
|
140
174
|
}
|
|
141
|
-
}
|
|
175
|
+
};
|
|
142
176
|
|
|
143
177
|
const handleTouchEnd = (e) => {
|
|
144
178
|
if (touchStartX.value > 0 && touchStartX.value < 35) {
|
|
145
|
-
const touchEndX = e.changedTouches[0].clientX
|
|
179
|
+
const touchEndX = e.changedTouches[0].clientX;
|
|
146
180
|
if (touchEndX - touchStartX.value > 50) {
|
|
147
|
-
close()
|
|
181
|
+
close();
|
|
148
182
|
}
|
|
149
183
|
}
|
|
150
|
-
touchStartX.value = 0
|
|
151
|
-
}
|
|
184
|
+
touchStartX.value = 0;
|
|
185
|
+
};
|
|
152
186
|
|
|
153
187
|
// Android notch fix
|
|
154
188
|
const androidFix = () => {
|
|
155
|
-
if (!isAndroid.value || !dialogContent.value) return
|
|
189
|
+
if (!isAndroid.value || !dialogContent.value) return;
|
|
156
190
|
|
|
157
191
|
try {
|
|
158
|
-
if (typeof Android !==
|
|
159
|
-
const cutoutTop = Android.getDisplayCutoutTop()
|
|
192
|
+
if (typeof Android !== "undefined" && Android.getDisplayCutoutTop) {
|
|
193
|
+
const cutoutTop = Android.getDisplayCutoutTop();
|
|
160
194
|
if (cutoutTop && window.devicePixelRatio > 1.0) {
|
|
161
|
-
const paddingTop = cutoutTop / window.devicePixelRatio
|
|
162
|
-
dialogContent.value.style.paddingTop = paddingTop +
|
|
195
|
+
const paddingTop = cutoutTop / window.devicePixelRatio;
|
|
196
|
+
dialogContent.value.style.paddingTop = paddingTop + "px";
|
|
163
197
|
}
|
|
164
198
|
}
|
|
165
199
|
} catch (err) {
|
|
166
200
|
// Android interface not available
|
|
167
201
|
}
|
|
168
|
-
}
|
|
202
|
+
};
|
|
169
203
|
|
|
170
204
|
// Body scroll lock
|
|
171
|
-
watch(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
205
|
+
watch(
|
|
206
|
+
() => props.modelValue,
|
|
207
|
+
(value) => {
|
|
208
|
+
if (value) {
|
|
209
|
+
document.body.style.overflow = "hidden";
|
|
210
|
+
nextTick(() => {
|
|
211
|
+
androidFix();
|
|
212
|
+
});
|
|
213
|
+
} else {
|
|
214
|
+
document.body.style.overflow = "";
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
);
|
|
181
218
|
|
|
182
219
|
onMounted(() => {
|
|
183
|
-
document.addEventListener(
|
|
184
|
-
window.addEventListener(
|
|
185
|
-
})
|
|
220
|
+
document.addEventListener("keydown", handleKeydown);
|
|
221
|
+
window.addEventListener("resize", androidFix);
|
|
222
|
+
});
|
|
186
223
|
|
|
187
224
|
onUnmounted(() => {
|
|
188
|
-
document.removeEventListener(
|
|
189
|
-
window.removeEventListener(
|
|
190
|
-
document.body.style.overflow =
|
|
191
|
-
})
|
|
225
|
+
document.removeEventListener("keydown", handleKeydown);
|
|
226
|
+
window.removeEventListener("resize", androidFix);
|
|
227
|
+
document.body.style.overflow = "";
|
|
228
|
+
});
|
|
192
229
|
</script>
|
|
193
230
|
|
|
194
231
|
<style>
|
|
@@ -309,7 +346,10 @@ onUnmounted(() => {
|
|
|
309
346
|
max-width: 100%;
|
|
310
347
|
}
|
|
311
348
|
|
|
312
|
-
.sky-dialog-footer:has(
|
|
349
|
+
.sky-dialog-footer:has(
|
|
350
|
+
> :deep(*:nth-child(2)):not(:has(> :deep(*:nth-child(3))))
|
|
351
|
+
)
|
|
352
|
+
> :deep(*) {
|
|
313
353
|
flex: 1 1 50%;
|
|
314
354
|
}
|
|
315
355
|
|
|
@@ -336,6 +376,11 @@ onUnmounted(() => {
|
|
|
336
376
|
max-height: calc(100% - 70px);
|
|
337
377
|
margin-bottom: 10px;
|
|
338
378
|
}
|
|
379
|
+
|
|
380
|
+
/* .sky-dialogbox,
|
|
381
|
+
.sky-dialog-overlay {
|
|
382
|
+
padding: 10px;
|
|
383
|
+
} */
|
|
339
384
|
}
|
|
340
385
|
|
|
341
386
|
/* Mobile */
|
|
@@ -9,8 +9,16 @@
|
|
|
9
9
|
@click="handleBack"
|
|
10
10
|
:title="backButtonTitle"
|
|
11
11
|
>
|
|
12
|
-
<svg
|
|
13
|
-
|
|
12
|
+
<svg
|
|
13
|
+
width="15"
|
|
14
|
+
height="15"
|
|
15
|
+
viewBox="0 0 451.847 451.847"
|
|
16
|
+
style="transform: rotate(90deg)"
|
|
17
|
+
>
|
|
18
|
+
<path
|
|
19
|
+
fill="currentColor"
|
|
20
|
+
d="M225.923,354.706c-8.098,0-16.195-3.092-22.369-9.263L9.27,151.157c-12.359-12.359-12.359-32.397,0-44.751c12.354-12.354,32.388-12.354,44.748,0l171.905,171.915l171.906-171.909c12.359-12.354,32.391-12.354,44.744,0c12.365,12.354,12.365,32.392,0,44.751L248.292,345.449C242.115,351.621,234.018,354.706,225.923,354.706z"
|
|
21
|
+
/>
|
|
14
22
|
</svg>
|
|
15
23
|
</button>
|
|
16
24
|
<div class="header-title-content">
|
|
@@ -24,7 +32,10 @@
|
|
|
24
32
|
</div>
|
|
25
33
|
|
|
26
34
|
<div class="header-actions">
|
|
35
|
+
<!-- Порожні блоки ремонтують відображення на windows в додатку, не видаляти! -->
|
|
36
|
+
<div></div>
|
|
27
37
|
<slot></slot>
|
|
38
|
+
<div></div>
|
|
28
39
|
</div>
|
|
29
40
|
</div>
|
|
30
41
|
</div>
|
|
@@ -32,53 +43,53 @@
|
|
|
32
43
|
</template>
|
|
33
44
|
|
|
34
45
|
<script setup>
|
|
35
|
-
import { computed } from
|
|
46
|
+
import { computed } from "vue";
|
|
36
47
|
|
|
37
48
|
const props = defineProps({
|
|
38
49
|
title: {
|
|
39
50
|
type: String,
|
|
40
|
-
default:
|
|
51
|
+
default: "",
|
|
41
52
|
},
|
|
42
53
|
subtitle: {
|
|
43
54
|
type: String,
|
|
44
|
-
default:
|
|
55
|
+
default: "",
|
|
45
56
|
},
|
|
46
57
|
showBackButton: {
|
|
47
58
|
type: Boolean,
|
|
48
|
-
default: true
|
|
59
|
+
default: true,
|
|
49
60
|
},
|
|
50
61
|
backButtonTitle: {
|
|
51
62
|
type: String,
|
|
52
|
-
default:
|
|
63
|
+
default: "Назад",
|
|
53
64
|
},
|
|
54
65
|
backEvent: {
|
|
55
66
|
type: Function,
|
|
56
|
-
default: null
|
|
57
|
-
}
|
|
58
|
-
})
|
|
67
|
+
default: null,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
59
70
|
|
|
60
71
|
// Перевіряємо чи сторінка в iframe
|
|
61
72
|
const isInIframe = computed(() => {
|
|
62
73
|
try {
|
|
63
|
-
return window.self !== window.top
|
|
74
|
+
return window.self !== window.top;
|
|
64
75
|
} catch (e) {
|
|
65
|
-
return true
|
|
76
|
+
return true;
|
|
66
77
|
}
|
|
67
|
-
})
|
|
78
|
+
});
|
|
68
79
|
|
|
69
80
|
// Показуємо кнопку якщо є backEvent АБО (showBackButton=true І сторінка в iframe)
|
|
70
81
|
const shouldShowBackButton = computed(() => {
|
|
71
|
-
return props.backEvent || (props.showBackButton && isInIframe.value)
|
|
72
|
-
})
|
|
82
|
+
return props.backEvent || (props.showBackButton && isInIframe.value);
|
|
83
|
+
});
|
|
73
84
|
|
|
74
85
|
// Обробник кнопки "Назад" - викликає backEvent або відправляє повідомлення батьківському вікну
|
|
75
86
|
const handleBack = () => {
|
|
76
87
|
if (props.backEvent) {
|
|
77
|
-
props.backEvent()
|
|
88
|
+
props.backEvent();
|
|
78
89
|
} else {
|
|
79
|
-
window.parent.postMessage({ type:
|
|
90
|
+
window.parent.postMessage({ type: "exit" }, "*");
|
|
80
91
|
}
|
|
81
|
-
}
|
|
92
|
+
};
|
|
82
93
|
</script>
|
|
83
94
|
|
|
84
95
|
<style scoped>
|
|
@@ -1,17 +1,34 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<BaseTeleport to="body">
|
|
3
3
|
<transition name="modal-fade">
|
|
4
|
-
<div
|
|
4
|
+
<div
|
|
5
|
+
v-if="modelValue"
|
|
6
|
+
class="sky-modal-overlay"
|
|
7
|
+
@click.self="handleOverlayClick"
|
|
8
|
+
>
|
|
5
9
|
<div class="sky-modal" :style="modalStyle">
|
|
6
10
|
<div class="sky-modal-header">
|
|
7
11
|
<button class="sky-modal-back" @click="close" :title="closeTitle">
|
|
8
|
-
<svg
|
|
9
|
-
|
|
12
|
+
<svg
|
|
13
|
+
width="15"
|
|
14
|
+
height="15"
|
|
15
|
+
viewBox="0 0 24 24"
|
|
16
|
+
fill="none"
|
|
17
|
+
stroke="currentColor"
|
|
18
|
+
stroke-width="2"
|
|
19
|
+
>
|
|
20
|
+
<path
|
|
21
|
+
d="M19 12H5M12 19l-7-7 7-7"
|
|
22
|
+
stroke-linecap="round"
|
|
23
|
+
stroke-linejoin="round"
|
|
24
|
+
/>
|
|
10
25
|
</svg>
|
|
11
26
|
</button>
|
|
12
27
|
<div class="sky-modal-title-wrapper">
|
|
13
28
|
<h4 class="sky-modal-title">{{ title }}</h4>
|
|
14
|
-
<div v-if="subtitle" class="sky-modal-subtitle">
|
|
29
|
+
<div v-if="subtitle" class="sky-modal-subtitle">
|
|
30
|
+
{{ subtitle }}
|
|
31
|
+
</div>
|
|
15
32
|
</div>
|
|
16
33
|
</div>
|
|
17
34
|
|
|
@@ -20,7 +37,10 @@
|
|
|
20
37
|
</div>
|
|
21
38
|
|
|
22
39
|
<div v-if="$slots.footer" class="sky-modal-footer">
|
|
40
|
+
<!-- Порожні блоки ремонтують відображення на windows в додатку, не видаляти! -->
|
|
41
|
+
<div></div>
|
|
23
42
|
<slot name="footer"></slot>
|
|
43
|
+
<div></div>
|
|
24
44
|
</div>
|
|
25
45
|
</div>
|
|
26
46
|
</div>
|
|
@@ -29,85 +49,87 @@
|
|
|
29
49
|
</template>
|
|
30
50
|
|
|
31
51
|
<script setup>
|
|
32
|
-
import { computed, watch, onMounted, onUnmounted } from
|
|
33
|
-
import BaseTeleport from
|
|
34
|
-
|
|
52
|
+
import { computed, watch, onMounted, onUnmounted } from "vue";
|
|
53
|
+
import BaseTeleport from "./BaseTeleport.vue";
|
|
35
54
|
|
|
36
55
|
const props = defineProps({
|
|
37
56
|
modelValue: {
|
|
38
57
|
type: Boolean,
|
|
39
|
-
default: false
|
|
58
|
+
default: false,
|
|
40
59
|
},
|
|
41
60
|
title: {
|
|
42
61
|
type: String,
|
|
43
|
-
default:
|
|
62
|
+
default: "",
|
|
44
63
|
},
|
|
45
64
|
subtitle: {
|
|
46
65
|
type: String,
|
|
47
|
-
default:
|
|
66
|
+
default: "",
|
|
48
67
|
},
|
|
49
68
|
closeTitle: {
|
|
50
69
|
type: String,
|
|
51
|
-
default:
|
|
70
|
+
default: "Закрити",
|
|
52
71
|
},
|
|
53
72
|
closeOnOverlay: {
|
|
54
73
|
type: Boolean,
|
|
55
|
-
default: true
|
|
74
|
+
default: true,
|
|
56
75
|
},
|
|
57
76
|
closeOnEsc: {
|
|
58
77
|
type: Boolean,
|
|
59
|
-
default: true
|
|
78
|
+
default: true,
|
|
60
79
|
},
|
|
61
80
|
width: {
|
|
62
81
|
type: String,
|
|
63
|
-
default:
|
|
82
|
+
default: "100%",
|
|
64
83
|
},
|
|
65
84
|
height: {
|
|
66
85
|
type: String,
|
|
67
|
-
default:
|
|
68
|
-
}
|
|
69
|
-
})
|
|
86
|
+
default: "100%",
|
|
87
|
+
},
|
|
88
|
+
});
|
|
70
89
|
|
|
71
|
-
const emit = defineEmits([
|
|
90
|
+
const emit = defineEmits(["update:modelValue", "close"]);
|
|
72
91
|
|
|
73
92
|
const modalStyle = computed(() => ({
|
|
74
93
|
width: props.width,
|
|
75
|
-
height: props.height
|
|
76
|
-
}))
|
|
94
|
+
height: props.height,
|
|
95
|
+
}));
|
|
77
96
|
|
|
78
97
|
const close = () => {
|
|
79
|
-
emit(
|
|
80
|
-
emit(
|
|
81
|
-
}
|
|
98
|
+
emit("update:modelValue", false);
|
|
99
|
+
emit("close");
|
|
100
|
+
};
|
|
82
101
|
|
|
83
102
|
const handleOverlayClick = () => {
|
|
84
103
|
if (props.closeOnOverlay) {
|
|
85
|
-
close()
|
|
104
|
+
close();
|
|
86
105
|
}
|
|
87
|
-
}
|
|
106
|
+
};
|
|
88
107
|
|
|
89
108
|
const handleKeydown = (e) => {
|
|
90
|
-
if (e.key ===
|
|
91
|
-
close()
|
|
109
|
+
if (e.key === "Escape" && props.closeOnEsc && props.modelValue) {
|
|
110
|
+
close();
|
|
92
111
|
}
|
|
93
|
-
}
|
|
112
|
+
};
|
|
94
113
|
|
|
95
|
-
watch(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
114
|
+
watch(
|
|
115
|
+
() => props.modelValue,
|
|
116
|
+
(value) => {
|
|
117
|
+
if (value) {
|
|
118
|
+
document.body.style.overflow = "hidden";
|
|
119
|
+
} else {
|
|
120
|
+
document.body.style.overflow = "";
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
);
|
|
102
124
|
|
|
103
125
|
onMounted(() => {
|
|
104
|
-
document.addEventListener(
|
|
105
|
-
})
|
|
126
|
+
document.addEventListener("keydown", handleKeydown);
|
|
127
|
+
});
|
|
106
128
|
|
|
107
129
|
onUnmounted(() => {
|
|
108
|
-
document.removeEventListener(
|
|
109
|
-
document.body.style.overflow =
|
|
110
|
-
})
|
|
130
|
+
document.removeEventListener("keydown", handleKeydown);
|
|
131
|
+
document.body.style.overflow = "";
|
|
132
|
+
});
|
|
111
133
|
</script>
|
|
112
134
|
|
|
113
135
|
<style scoped>
|