@skyservice-developers/vue-dev-kit 1.5.12 → 2.0.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.
Files changed (57) hide show
  1. package/README.md +96 -15
  2. package/dist/api-BOvdjB3h.js +266 -0
  3. package/dist/api-D5C6FvTr.cjs +1 -0
  4. package/dist/components/BaseTeleport.vue.d.ts +14 -0
  5. package/dist/components/Dialog.vue.d.ts +28 -0
  6. package/dist/components/DialogModal.vue.d.ts +28 -0
  7. package/dist/components/DialogNext.vue.d.ts +28 -0
  8. package/dist/components/Header.vue.d.ts +37 -0
  9. package/dist/components/Modal.vue.d.ts +30 -0
  10. package/dist/components/SkyButton.vue.d.ts +22 -0
  11. package/dist/components/SkySelect.vue.d.ts +16 -0
  12. package/dist/components/index.d.ts +8 -0
  13. package/dist/index.d.ts +3 -0
  14. package/dist/sdk/api.d.ts +54 -0
  15. package/dist/sdk/bridge.d.ts +43 -0
  16. package/dist/sdk/index.d.ts +6 -0
  17. package/dist/sdk/types.d.ts +73 -0
  18. package/dist/sdk/webview.d.ts +16 -0
  19. package/dist/sdk.cjs +1 -0
  20. package/dist/sdk.js +33 -0
  21. package/dist/style.css +1 -0
  22. package/dist/vue-dev-kit.cjs +1 -0
  23. package/dist/vue-dev-kit.js +903 -0
  24. package/package.json +32 -43
  25. package/dist/vue2/style.css +0 -1
  26. package/dist/vue2/vue-dev-kit.cjs +0 -1
  27. package/dist/vue2/vue-dev-kit.js +0 -2622
  28. package/dist/vue3/style.css +0 -1
  29. package/dist/vue3/vue-dev-kit.cjs +0 -1
  30. package/dist/vue3/vue-dev-kit.js +0 -2277
  31. package/src/index.js +0 -9
  32. package/src/shared/index.js +0 -1
  33. package/src/shared/types/index.d.ts +0 -72
  34. package/src/shared/utils/index.js +0 -2
  35. package/src/shared/utils/parentBridge.js +0 -84
  36. package/src/shared/utils/webviewCheck.js +0 -54
  37. package/src/styles/scrollbar.css +0 -17
  38. package/src/vue2/components/BaseTeleport.vue +0 -16
  39. package/src/vue2/components/Dialog.vue +0 -106
  40. package/src/vue2/components/DialogModal.vue +0 -439
  41. package/src/vue2/components/DialogNext.vue +0 -379
  42. package/src/vue2/components/Header.vue +0 -466
  43. package/src/vue2/components/Modal.vue +0 -252
  44. package/src/vue2/components/SkyButton.vue +0 -144
  45. package/src/vue2/components/SkySelect.vue +0 -327
  46. package/src/vue2/components/index.js +0 -6
  47. package/src/vue2/index.js +0 -2
  48. package/src/vue3/components/BaseTeleport.vue +0 -16
  49. package/src/vue3/components/Dialog.vue +0 -97
  50. package/src/vue3/components/DialogModal.vue +0 -458
  51. package/src/vue3/components/DialogNext.vue +0 -427
  52. package/src/vue3/components/Header.vue +0 -505
  53. package/src/vue3/components/Modal.vue +0 -253
  54. package/src/vue3/components/SkyButton.vue +0 -140
  55. package/src/vue3/components/SkySelect.vue +0 -266
  56. package/src/vue3/components/index.js +0 -8
  57. package/src/vue3/index.js +0 -2
@@ -1,505 +0,0 @@
1
- <template>
2
- <header class="sky-header-container">
3
- <div class="topmenubox">
4
- <div class="header-left">
5
- <button
6
- v-if="shouldShowBackButton"
7
- class="btn-back"
8
- @click="handleBack"
9
- :title="backButtonTitle"
10
- >
11
- <svg
12
- width="15"
13
- height="15"
14
- viewBox="0 0 451.847 451.847"
15
- style="transform: rotate(90deg)"
16
- >
17
- <path
18
- fill="currentColor"
19
- 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"
20
- />
21
- </svg>
22
- </button>
23
- <div ref="dropdownRef" class="titleAndDesc">
24
- <button
25
- class="title-dropdown-toggle"
26
- :class="{ 'title-dropdown-toggle-active': sortedItems.length }"
27
- @click="toggleDropdown"
28
- >
29
- <slot name="title">
30
- <h4 class="notPadding">
31
- <span class="topmenu-title">{{ title }}</span>
32
- <svg
33
- v-if="sortedItems.length"
34
- class="arrow"
35
- :class="{ open: isDropdownOpen }"
36
- width="12"
37
- height="12"
38
- viewBox="0 0 451.847 451.847"
39
- style="flex-shrink: 0"
40
- >
41
- <path
42
- fill="currentColor"
43
- 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"
44
- />
45
- </svg>
46
- </h4>
47
- </slot>
48
- </button>
49
- <div v-if="isDropdownOpen && sortedItems.length" class="title-dropdown">
50
- <div class="title-dropdown-header">{{ dropdownTitle }}</div>
51
- <div class="title-dropdown-divider"></div>
52
- <div
53
- v-for="(item, index) in sortedItems"
54
- :key="index"
55
- class="title-dropdown-item"
56
- @click="selectItem(item)"
57
- >
58
- <p class="pageName">{{ translateName(item.name) }}</p>
59
- <small class="pageVisit">
60
- ({{ visitLabel }} {{ getTimeAgo(item.lastVisit) }})
61
- </small>
62
- </div>
63
- </div>
64
- <slot name="subtitle">
65
- <p v-if="subtitle" class="topmenu-description">{{ subtitle }}</p>
66
- </slot>
67
- </div>
68
- </div>
69
-
70
- <div class="topmenubox-button">
71
- <!-- Порожні блоки ремонтують відображення на windows в додатку, не видаляти! -->
72
- <div></div>
73
- <slot></slot>
74
- <div></div>
75
- </div>
76
- </div>
77
- </header>
78
- </template>
79
-
80
- <script setup>
81
- import { ref, computed, onMounted, onUnmounted } from 'vue'
82
- import { isInIframe } from '../../shared/utils/webviewCheck'
83
- import { getParentLocalStorage, getParentWindowValue, setParentLocalStorage, sendToParent, setSenderId, getSenderId } from '../../shared/utils/parentBridge'
84
-
85
- const props = defineProps({
86
- title: {
87
- type: String,
88
- default: "",
89
- },
90
- subtitle: {
91
- type: String,
92
- default: "",
93
- },
94
- showBackButton: {
95
- type: Boolean,
96
- default: true,
97
- },
98
- backButtonTitle: {
99
- type: String,
100
- default: "Назад",
101
- },
102
- backEvent: {
103
- type: Function,
104
- default: null,
105
- },
106
- dropdownItems: {
107
- type: Array,
108
- default: () => [],
109
- },
110
- dropdownTitle: {
111
- type: String,
112
- default: "Останні відвідані розділи",
113
- },
114
- visitLabel: {
115
- type: String,
116
- default: "Останнє відвідування",
117
- },
118
- trackPageName: {
119
- type: String,
120
- default: "",
121
- },
122
- trackPagePath: {
123
- type: String,
124
- default: "",
125
- },
126
- appId: {
127
- type: String,
128
- default: "",
129
- },
130
- });
131
-
132
- // Initialize sender ID from prop or generate
133
- setSenderId(props.appId || getSenderId())
134
-
135
- const emit = defineEmits(['back', 'navigate'])
136
-
137
- const dropdownRef = ref(null)
138
- const isDropdownOpen = ref(false)
139
-
140
- const localStorageItems = ref([])
141
- const parentLang = ref({})
142
-
143
- // Track page visit in parent's componentStats
144
- if (isInIframe() && props.trackPageName) {
145
- sendToParent({
146
- type: 'trackVisit',
147
- name: props.trackPageName,
148
- path: props.trackPagePath || `/${props.trackPageName}`,
149
- })
150
- }
151
-
152
- // Set rocketMode in parent, remember previous value to restore on unmount
153
- const previousRocketMode = ref(null)
154
-
155
- if (isInIframe()) {
156
- getParentLocalStorage('rocketMode').then(async (value) => {
157
- previousRocketMode.value = value
158
- const existingFallback = await getParentLocalStorage('fallbackRocketMode')
159
- if (existingFallback === null) {
160
- setParentLocalStorage('fallbackRocketMode', value === true || value === 'true' ? 'true' : 'false')
161
- }
162
- sendToParent({ type: 'setRocketMode', value: true })
163
- })
164
- }
165
-
166
- onUnmounted(() => {
167
- restoreRocketMode()
168
- })
169
-
170
- // Load translations from parent
171
- if (isInIframe()) {
172
- getParentWindowValue('lang').then((data) => {
173
- if (data != null) {
174
- parentLang.value = data
175
- }
176
- })
177
- }
178
-
179
- function loadComponentStats(raw) {
180
- try {
181
- if (!raw) return
182
- const data = typeof raw === 'string' ? JSON.parse(raw) : raw
183
- if (data?.pages) {
184
- localStorageItems.value = Object.values(data.pages)
185
- }
186
- } catch {}
187
- }
188
-
189
- // Load from local localStorage first
190
- loadComponentStats(localStorage['componentStats'])
191
-
192
- // If in iframe, request from parent and update
193
- if (isInIframe()) {
194
- getParentLocalStorage('componentStats').then((data) => {
195
- if (data != null) {
196
- localStorage.setItem('componentStats', JSON.stringify(data))
197
- loadComponentStats(data)
198
- }
199
- })
200
- }
201
-
202
- const sortedItems = computed(() => {
203
- const items = props.dropdownItems.length ? props.dropdownItems : localStorageItems.value
204
- return [...items].sort((a, b) => b.lastVisit - a.lastVisit)
205
- })
206
-
207
- const toggleDropdown = () => {
208
- if (sortedItems.value.length) {
209
- isDropdownOpen.value = !isDropdownOpen.value
210
- }
211
- }
212
-
213
- const closeDropdown = () => {
214
- isDropdownOpen.value = false
215
- }
216
-
217
- const selectItem = (item) => {
218
- emit('navigate', item.path)
219
- if (isInIframe()) {
220
- sendToParent({ type: 'navigate', path: item.path })
221
- }
222
- closeDropdown()
223
- }
224
-
225
- const translateName = (name) => {
226
- if (!name) return ''
227
- const translated = parentLang.value[name] || name
228
- return translated.charAt(0).toUpperCase() + translated.slice(1)
229
- }
230
-
231
- const getTimeAgo = (lastVisit) => {
232
- const now = Date.now()
233
- const diff = now - lastVisit
234
-
235
- const seconds = Math.floor(diff / 1000)
236
- const minutes = Math.floor(seconds / 60)
237
- const hours = Math.floor(minutes / 60)
238
- const days = Math.floor(hours / 24)
239
-
240
- if (days > 0) return `${days}д тому`
241
- if (hours > 0) return `${hours}год тому`
242
- if (minutes > 0) return `${minutes}хв тому`
243
- return `${seconds}с тому`
244
- }
245
-
246
- const handleClickOutside = (e) => {
247
- if (dropdownRef.value && !dropdownRef.value.contains(e.target)) {
248
- closeDropdown()
249
- }
250
- }
251
-
252
- onMounted(() => {
253
- document.addEventListener('click', handleClickOutside, true)
254
- })
255
-
256
- onUnmounted(() => {
257
- document.removeEventListener('click', handleClickOutside, true)
258
- })
259
-
260
- // Показуємо кнопку якщо є backEvent АБО (showBackButton=true І сторінка в iframe)
261
- const shouldShowBackButton = computed(() => {
262
- return props.backEvent || (props.showBackButton && isInIframe());
263
- });
264
-
265
- const restoreRocketMode = () => {
266
- if (previousRocketMode.value !== null) {
267
- const restore = previousRocketMode.value === true || previousRocketMode.value === 'true'
268
- sendToParent({ type: 'setRocketMode', value: restore })
269
- }
270
- }
271
-
272
- const findPreviousPage = () => {
273
- return sortedItems.value.find(item => item.name !== props.trackPageName && item.path)
274
- }
275
-
276
- const handleBack = async () => {
277
- if (props.backEvent) {
278
- restoreRocketMode()
279
- return props.backEvent()
280
- }
281
-
282
- let previousPage = findPreviousPage()
283
-
284
- if (!previousPage && isInIframe()) {
285
- const data = await getParentLocalStorage('componentStats')
286
- if (data) {
287
- loadComponentStats(data)
288
- previousPage = findPreviousPage()
289
- }
290
- }
291
-
292
- restoreRocketMode()
293
-
294
- if (previousPage) {
295
- sendToParent({ type: 'navigate', path: previousPage.path })
296
- } else {
297
- sendToParent({ type: 'exit' })
298
- }
299
- }
300
- </script>
301
-
302
- <style scoped>
303
- .sky-header-container {
304
- width: 100%;
305
- min-height: var(--sky-header-min-height, 82px);
306
- background-color: var(--sky-header-bg, transparent);
307
- display: flex;
308
- flex-direction: row;
309
- padding: var(--sky-header-padding, 10px);
310
- border-bottom: 1px solid var(--sky-header-border-color, #dee2e6);
311
- z-index: var(--sky-header-z-index, 4);
312
- position: relative;
313
- }
314
-
315
- .topmenubox {
316
- width: 100%;
317
- display: flex;
318
- padding: 4px;
319
- justify-content: space-between;
320
- align-items: center;
321
- background-color: transparent;
322
- }
323
-
324
- .header-left {
325
- display: flex;
326
- align-items: center;
327
- }
328
-
329
- .header-left > * + * {
330
- margin-left: 12px;
331
- }
332
-
333
- .titleAndDesc {
334
- display: flex;
335
- flex-direction: column;
336
- position: relative;
337
- }
338
-
339
- .notPadding {
340
- margin: 0;
341
- padding: 0;
342
- font-size: var(--sky-header-title-size, 18px);
343
- font-weight: var(--sky-header-title-weight, 500);
344
- color: var(--sky-header-title-color, #252525);
345
- line-height: 1.5;
346
- user-select: none;
347
- display: flex;
348
- align-items: center;
349
- flex-wrap: nowrap;
350
- }
351
-
352
- .topmenu-title {
353
- white-space: pre-line;
354
- }
355
-
356
- .title-dropdown-toggle {
357
- display: flex;
358
- flex-direction: row;
359
- padding: 0;
360
- margin: 0;
361
- background: transparent;
362
- border: none;
363
- text-align: left;
364
- font: inherit;
365
- color: inherit;
366
- }
367
-
368
- .title-dropdown-toggle-active {
369
- cursor: pointer;
370
- }
371
-
372
- .arrow {
373
- width: 12px;
374
- position: relative;
375
- margin-left: 5px;
376
- flex-shrink: 0;
377
- transition: transform 0.25s ease;
378
- color: var(--sky-header-title-color, #252525);
379
- }
380
-
381
- .arrow.open {
382
- transform: rotate(180deg);
383
- }
384
-
385
- .title-dropdown {
386
- position: absolute;
387
- top: 100%;
388
- left: 0;
389
- min-width: 240px;
390
- background: white;
391
- border-radius: 5px;
392
- box-shadow: 0 1px 12px rgba(0, 0, 0, 0.1);
393
- border: none;
394
- z-index: 10;
395
- padding: 4px 0;
396
- margin-top: 4px;
397
- }
398
-
399
- .title-dropdown-header {
400
- padding: 4px 24px;
401
- font-size: 13px;
402
- color: #6c757d;
403
- }
404
-
405
- .title-dropdown-divider {
406
- height: 0;
407
- margin: 4px 0;
408
- border-top: 1px solid #e9ecef;
409
- }
410
-
411
- .title-dropdown-item {
412
- padding: 4px 24px;
413
- cursor: pointer;
414
- transition: background-color 0.1s;
415
- }
416
-
417
- .title-dropdown-item:hover {
418
- background-color: #f8f9fa;
419
- }
420
-
421
- .title-dropdown-item:active {
422
- background-color: #e9ecef;
423
- }
424
-
425
- .pageName {
426
- padding-bottom: 0;
427
- margin: 0;
428
- font-weight: 500;
429
- font-size: 14px;
430
- }
431
-
432
- .pageVisit {
433
- color: gray;
434
- font-weight: 400;
435
- font-size: 11px;
436
- }
437
-
438
- .topmenu-description {
439
- margin: 0;
440
- margin-bottom: 5px;
441
- color: var(--sky-header-subtitle-color, #5d5d5d);
442
- font-size: 13px;
443
- font-weight: 400;
444
- line-height: 1.5;
445
- }
446
-
447
- .topmenubox-button {
448
- display: flex;
449
- flex-direction: row;
450
- align-items: center;
451
- justify-content: space-between;
452
- }
453
-
454
- .btn-back {
455
- display: flex;
456
- align-items: center;
457
- justify-content: center;
458
- width: 32px;
459
- height: 32px;
460
- padding: 0;
461
- background: transparent;
462
- border: none;
463
- cursor: pointer;
464
- border-radius: 6px;
465
- transition: background-color 0.2s;
466
- color: var(--sky-header-back-btn-color, #374151);
467
- }
468
-
469
- .btn-back img,
470
- .btn-back svg {
471
- display: block;
472
- }
473
-
474
- .btn-back:hover {
475
- background-color: var(--sky-header-back-btn-hover-bg, #f8f9fa);
476
- }
477
-
478
- .btn-back:active {
479
- background-color: var(--sky-header-back-btn-active-bg, #e9ecef);
480
- }
481
-
482
- /* Responsive: <500px — hide description, smaller title */
483
- @media (max-width: 499px) {
484
- .topmenu-description {
485
- display: none;
486
- }
487
- .notPadding {
488
- font-size: 13px;
489
- }
490
- }
491
-
492
- /* Responsive: 500-1099px — smaller description */
493
- @media (min-width: 500px) and (max-width: 1099px) {
494
- .topmenu-description {
495
- font-size: 11px;
496
- }
497
- }
498
-
499
- /* iOS safe area */
500
- @supports (padding-top: env(safe-area-inset-top)) {
501
- .sky-header-container {
502
- padding-top: calc(10px + env(safe-area-inset-top));
503
- }
504
- }
505
- </style>