@skyservice-developers/vue-dev-kit 1.1.1 → 1.2.0

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.
@@ -6,18 +6,40 @@
6
6
  class="sky-dialogbox sky-dialogbox-classic"
7
7
  :style="[zIndex ? { 'z-index': zIndex } : null]"
8
8
  >
9
- <div class="sky-dialog-overlay" :class="{ 'sky-dialog-animate': enableAnimation }">
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
- <div class="sky-dialog-title" :class="{ 'sky-dialog-title-with-subtitle': subtitle }">
15
+ <div
16
+ class="sky-dialog-title"
17
+ :class="{ 'sky-dialog-title-with-subtitle': subtitle }"
18
+ >
13
19
  {{ title }}
14
- <span v-if="subtitle" class="sky-dialog-subtitle">{{ subtitle }}</span>
20
+ <span v-if="subtitle" class="sky-dialog-subtitle">{{
21
+ subtitle
22
+ }}</span>
15
23
  </div>
16
24
 
17
25
  <button class="sky-dialog-close" :title="closeText" @click="close">
18
26
  <svg viewBox="0 0 16 16" width="16" height="16">
19
- <line x1="1" y1="15" x2="15" y2="1" stroke="currentColor" stroke-width="2" />
20
- <line x1="1" y1="1" x2="15" y2="15" stroke="currentColor" stroke-width="2" />
27
+ <line
28
+ x1="1"
29
+ y1="15"
30
+ x2="15"
31
+ y2="1"
32
+ stroke="currentColor"
33
+ stroke-width="2"
34
+ />
35
+ <line
36
+ x1="1"
37
+ y1="1"
38
+ x2="15"
39
+ y2="15"
40
+ stroke="currentColor"
41
+ stroke-width="2"
42
+ />
21
43
  </svg>
22
44
  </button>
23
45
 
@@ -37,8 +59,15 @@
37
59
  </div>
38
60
 
39
61
  <!-- Footer -->
40
- <div v-if="showFooter" class="sky-dialog-footer" :class="{ 'sky-dialog-footer-animate': enableAnimation }">
62
+ <div
63
+ v-if="showFooter"
64
+ class="sky-dialog-footer"
65
+ :class="{ 'sky-dialog-footer-animate': enableAnimation }"
66
+ >
67
+ <!-- Порожні блоки ремонтують відображення на windows в додатку, не видаляти! -->
68
+ <div></div>
41
69
  <slot name="buttons"></slot>
70
+ <div></div>
42
71
  </div>
43
72
  </div>
44
73
  </div>
@@ -48,148 +77,162 @@
48
77
  </template>
49
78
 
50
79
  <script setup>
51
- import { ref, computed, watch, onMounted, onUnmounted, nextTick, useSlots } from 'vue'
52
- import { isIosWebview, isAndroidWebview } from '../../shared/utils/webviewCheck'
53
-
54
- const slots = useSlots()
80
+ import {
81
+ ref,
82
+ computed,
83
+ watch,
84
+ onMounted,
85
+ onUnmounted,
86
+ nextTick,
87
+ useSlots,
88
+ } from "vue";
89
+ import {
90
+ isIosWebview,
91
+ isAndroidWebview,
92
+ } from "../../shared/utils/webviewCheck";
93
+
94
+ const slots = useSlots();
55
95
 
56
96
  const props = defineProps({
57
97
  modelValue: {
58
98
  type: Boolean,
59
- default: false
99
+ default: false,
60
100
  },
61
101
  title: {
62
102
  type: String,
63
- default: ''
103
+ default: "",
64
104
  },
65
105
  subtitle: {
66
106
  type: String,
67
- default: ''
107
+ default: "",
68
108
  },
69
109
  zIndex: {
70
110
  type: [Number, String],
71
- default: null
111
+ default: null,
72
112
  },
73
113
  closeText: {
74
114
  type: String,
75
- default: 'Закрити'
115
+ default: "Закрити",
76
116
  },
77
117
  enableAnimation: {
78
118
  type: Boolean,
79
- default: true
119
+ default: true,
80
120
  },
81
121
  closeOnEsc: {
82
122
  type: Boolean,
83
- default: true
123
+ default: true,
84
124
  },
85
125
  hasButtons: {
86
126
  type: Boolean,
87
- default: null
88
- }
89
- })
127
+ default: null,
128
+ },
129
+ });
90
130
 
91
- const emit = defineEmits(['update:modelValue', 'close', 'save'])
131
+ const emit = defineEmits(["update:modelValue", "close", "save"]);
92
132
 
93
- const dialogContent = ref(null)
94
- const dialogPaper = ref(null)
95
- const touchStartX = ref(0)
133
+ const dialogContent = ref(null);
134
+ const dialogPaper = ref(null);
135
+ const touchStartX = ref(0);
96
136
 
97
137
  const isIos = computed(() => {
98
138
  try {
99
- return isIosWebview()
139
+ return isIosWebview();
100
140
  } catch {
101
- return false
141
+ return false;
102
142
  }
103
- })
143
+ });
104
144
 
105
145
  const isAndroid = computed(() => {
106
146
  try {
107
- return isAndroidWebview()
147
+ return isAndroidWebview();
108
148
  } catch {
109
- return false
149
+ return false;
110
150
  }
111
- })
151
+ });
112
152
 
113
153
  // Determine if footer should be shown
114
154
  const showFooter = computed(() => {
115
155
  // If hasButtons prop is explicitly set, use it
116
156
  if (props.hasButtons !== null) {
117
- return props.hasButtons
157
+ return props.hasButtons;
118
158
  }
119
159
  // Fallback to slot check (for direct usage without Dialog wrapper)
120
- return !!slots.buttons
121
- })
160
+ return !!slots.buttons;
161
+ });
122
162
 
123
163
  const close = () => {
124
- emit('update:modelValue', false)
125
- emit('close')
126
- }
164
+ emit("update:modelValue", false);
165
+ emit("close");
166
+ };
127
167
 
128
168
  const handleKeydown = (e) => {
129
- if (e.key === 'Escape' && props.closeOnEsc && props.modelValue) {
130
- close()
169
+ if (e.key === "Escape" && props.closeOnEsc && props.modelValue) {
170
+ close();
131
171
  }
132
- if (e.key === 'Enter' && props.modelValue) {
133
- emit('save')
172
+ if (e.key === "Enter" && props.modelValue) {
173
+ emit("save");
134
174
  }
135
- }
175
+ };
136
176
 
137
177
  // Touch handling for iOS swipe back
138
178
  const handleTouchStart = (e) => {
139
179
  if (e.touches[0].clientX < 35) {
140
- touchStartX.value = e.touches[0].clientX
180
+ touchStartX.value = e.touches[0].clientX;
141
181
  }
142
- }
182
+ };
143
183
 
144
184
  const handleTouchEnd = (e) => {
145
185
  if (touchStartX.value > 0 && touchStartX.value < 35) {
146
- const touchEndX = e.changedTouches[0].clientX
186
+ const touchEndX = e.changedTouches[0].clientX;
147
187
  if (touchEndX - touchStartX.value > 50) {
148
- close()
188
+ close();
149
189
  }
150
190
  }
151
- touchStartX.value = 0
152
- }
191
+ touchStartX.value = 0;
192
+ };
153
193
 
154
194
  // Android notch fix
155
195
  const androidFix = () => {
156
- if (!isAndroid.value || !dialogContent.value) return
196
+ if (!isAndroid.value || !dialogContent.value) return;
157
197
 
158
198
  try {
159
- if (typeof Android !== 'undefined' && Android.getDisplayCutoutTop) {
160
- const cutoutTop = Android.getDisplayCutoutTop()
199
+ if (typeof Android !== "undefined" && Android.getDisplayCutoutTop) {
200
+ const cutoutTop = Android.getDisplayCutoutTop();
161
201
  if (cutoutTop && window.devicePixelRatio > 1.0) {
162
- const paddingTop = cutoutTop / window.devicePixelRatio
163
- dialogContent.value.style.paddingTop = paddingTop + 'px'
202
+ const paddingTop = cutoutTop / window.devicePixelRatio;
203
+ dialogContent.value.style.paddingTop = paddingTop + "px";
164
204
  }
165
205
  }
166
206
  } catch (err) {
167
207
  // Android interface not available
168
208
  }
169
- }
209
+ };
170
210
 
171
211
  // Body scroll lock
172
- watch(() => props.modelValue, (value) => {
173
- if (value) {
174
- document.body.style.overflow = 'hidden'
175
- nextTick(() => {
176
- androidFix()
177
- })
178
- } else {
179
- document.body.style.overflow = ''
180
- }
181
- })
212
+ watch(
213
+ () => props.modelValue,
214
+ (value) => {
215
+ if (value) {
216
+ document.body.style.overflow = "hidden";
217
+ nextTick(() => {
218
+ androidFix();
219
+ });
220
+ } else {
221
+ document.body.style.overflow = "";
222
+ }
223
+ },
224
+ );
182
225
 
183
226
  onMounted(() => {
184
- document.addEventListener('keydown', handleKeydown)
185
- window.addEventListener('resize', androidFix)
186
- })
227
+ document.addEventListener("keydown", handleKeydown);
228
+ window.addEventListener("resize", androidFix);
229
+ });
187
230
 
188
231
  onUnmounted(() => {
189
- document.removeEventListener('keydown', handleKeydown)
190
- window.removeEventListener('resize', androidFix)
191
- document.body.style.overflow = ''
192
- })
232
+ document.removeEventListener("keydown", handleKeydown);
233
+ window.removeEventListener("resize", androidFix);
234
+ document.body.style.overflow = "";
235
+ });
193
236
  </script>
194
237
 
195
238
  <style>
@@ -312,7 +355,10 @@ onUnmounted(() => {
312
355
  max-width: 100%;
313
356
  }
314
357
 
315
- .sky-dialog-footer:has(> :deep(*:nth-child(2)):not(:has(> :deep(*:nth-child(3))))) > :deep(*) {
358
+ .sky-dialog-footer:has(
359
+ > :deep(*:nth-child(2)):not(:has(> :deep(*:nth-child(3))))
360
+ )
361
+ > :deep(*) {
316
362
  flex: 1 1 50%;
317
363
  }
318
364
 
@@ -6,18 +6,34 @@
6
6
  class="sky-dialogbox sky-dialogbox-next"
7
7
  :style="[zIndex ? { 'z-index': zIndex } : null]"
8
8
  >
9
- <div class="sky-dialog-overlay" :class="{ 'sky-dialog-animate': enableAnimation }">
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 width="15" height="15" viewBox="0 0 451.847 451.847" style="transform: rotate(90deg)">
14
- <path fill="currentColor" 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"/>
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 class="sky-dialog-title" :class="{ 'sky-dialog-title-with-subtitle': subtitle }">
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">{{ subtitle }}</span>
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" />
@@ -36,8 +52,15 @@
36
52
  </div>
37
53
 
38
54
  <!-- Footer -->
39
- <div v-if="showFooter" class="sky-dialog-footer" :class="{ 'sky-dialog-footer-animate': enableAnimation }">
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 { ref, computed, watch, onMounted, onUnmounted, nextTick, useSlots } from 'vue'
51
- import { isIosWebview, isAndroidWebview } from '../../shared/utils/webviewCheck'
52
-
53
- const slots = useSlots()
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(['update:modelValue', 'close', 'save'])
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('update:modelValue', false)
124
- emit('close')
125
- }
157
+ emit("update:modelValue", false);
158
+ emit("close");
159
+ };
126
160
 
127
161
  const handleKeydown = (e) => {
128
- if (e.key === 'Escape' && props.closeOnEsc && props.modelValue) {
129
- close()
162
+ if (e.key === "Escape" && props.closeOnEsc && props.modelValue) {
163
+ close();
130
164
  }
131
- if (e.key === 'Enter' && props.modelValue) {
132
- emit('save')
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 !== 'undefined' && Android.getDisplayCutoutTop) {
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 + 'px'
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(() => props.modelValue, (value) => {
172
- if (value) {
173
- document.body.style.overflow = 'hidden'
174
- nextTick(() => {
175
- androidFix()
176
- })
177
- } else {
178
- document.body.style.overflow = ''
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('keydown', handleKeydown)
184
- window.addEventListener('resize', androidFix)
185
- })
220
+ document.addEventListener("keydown", handleKeydown);
221
+ window.addEventListener("resize", androidFix);
222
+ });
186
223
 
187
224
  onUnmounted(() => {
188
- document.removeEventListener('keydown', handleKeydown)
189
- window.removeEventListener('resize', androidFix)
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(> :deep(*:nth-child(2)):not(:has(> :deep(*:nth-child(3))))) > :deep(*) {
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 */