itube-specs 0.0.361 → 0.0.362
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/components/ui/s-dropdown.vue +51 -28
- package/components/ui/s-notification.vue +49 -42
- package/components/ui/s-popup.vue +117 -118
- package/package.json +1 -1
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
class="s-dropdown"
|
|
5
5
|
:style="`--max-height: ${getMaxHeight}`"
|
|
6
6
|
:class="[
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
{ '--top': top },
|
|
8
|
+
{ '--right': right },
|
|
9
|
+
{ '--center': center },
|
|
10
|
+
{ '--open': open },
|
|
11
|
+
{ '--separate': separateLastChild },
|
|
12
12
|
]"
|
|
13
13
|
@mouseleave="mouseHandler(false)"
|
|
14
14
|
@mouseover="mouseHandler(true)"
|
|
@@ -19,13 +19,14 @@
|
|
|
19
19
|
>
|
|
20
20
|
<slot name="trigger"></slot>
|
|
21
21
|
</div>
|
|
22
|
+
|
|
22
23
|
<transition name="s-dropdown" mode="out-in">
|
|
23
24
|
<dialog
|
|
24
25
|
v-if="useVIf ? open && $slots.items : true"
|
|
25
26
|
:style="!useVIf ? { display: (open && $slots.items) ? '' : 'none' } : {}"
|
|
26
27
|
ref="menuRef"
|
|
27
28
|
class="s-dropdown__menu"
|
|
28
|
-
:class="{'--open': open}"
|
|
29
|
+
:class="{ '--open': open }"
|
|
29
30
|
@click="close"
|
|
30
31
|
>
|
|
31
32
|
<button
|
|
@@ -38,11 +39,13 @@
|
|
|
38
39
|
type="button"
|
|
39
40
|
@click="close"
|
|
40
41
|
>
|
|
41
|
-
<SIcon name="close" size="16"/>
|
|
42
|
+
<SIcon name="close" size="16" />
|
|
42
43
|
</button>
|
|
44
|
+
|
|
43
45
|
<slot name="header"></slot>
|
|
46
|
+
|
|
44
47
|
<div class="s-dropdown__menu-items" v-if="$slots.items">
|
|
45
|
-
<slot name="items" v-bind="'s-dropdown__item'"></slot>
|
|
48
|
+
<slot name="items" v-bind="{ class: 's-dropdown__item' }"></slot>
|
|
46
49
|
</div>
|
|
47
50
|
</dialog>
|
|
48
51
|
</transition>
|
|
@@ -50,12 +53,12 @@
|
|
|
50
53
|
</template>
|
|
51
54
|
|
|
52
55
|
<script setup lang="ts">
|
|
53
|
-
|
|
56
|
+
import { ref, watch, computed, onMounted, onBeforeUnmount, nextTick } from 'vue';
|
|
54
57
|
import { onClickOutside, useScrollLock } from '@vueuse/core';
|
|
55
58
|
import { isMobile } from '../../runtime';
|
|
56
59
|
import type { CssBreakpoints } from '../../types';
|
|
57
60
|
|
|
58
|
-
const dropdownRef = ref<
|
|
61
|
+
const dropdownRef = ref<HTMLElement | null>(null);
|
|
59
62
|
const menuRef = ref<HTMLDialogElement | null>(null);
|
|
60
63
|
|
|
61
64
|
const props = withDefaults(defineProps<{
|
|
@@ -67,57 +70,77 @@ const props = withDefaults(defineProps<{
|
|
|
67
70
|
openByClick?: boolean;
|
|
68
71
|
useVIf?: boolean;
|
|
69
72
|
}>(), {
|
|
70
|
-
useVIf: false
|
|
73
|
+
useVIf: false,
|
|
71
74
|
});
|
|
72
75
|
|
|
73
76
|
const open = ref(false);
|
|
74
77
|
|
|
75
78
|
const breakpoints = useAppConfig().cssBreakpoints as Record<CssBreakpoints, number>;
|
|
76
79
|
|
|
77
|
-
//
|
|
78
|
-
const
|
|
80
|
+
// SSR-safe: тело страницы доступно только на клиенте
|
|
81
|
+
const bodyElement = ref<HTMLElement | null>(null);
|
|
82
|
+
const bodyScrollLocked = useScrollLock(bodyElement);
|
|
83
|
+
|
|
84
|
+
onMounted(() => {
|
|
85
|
+
bodyElement.value = document.body;
|
|
86
|
+
});
|
|
79
87
|
|
|
88
|
+
// Закрытие дропдауна
|
|
80
89
|
function close() {
|
|
81
90
|
open.value = false;
|
|
82
91
|
|
|
83
|
-
if (isMobile(breakpoints).value) {
|
|
92
|
+
if (isMobile(breakpoints).value && process.client) {
|
|
84
93
|
nextTick(() => {
|
|
85
|
-
menuRef.value?.close
|
|
86
|
-
bodyScrollLocked.value = false;
|
|
94
|
+
menuRef.value?.close();
|
|
95
|
+
bodyScrollLocked.value = false;
|
|
87
96
|
});
|
|
88
97
|
}
|
|
89
98
|
}
|
|
90
99
|
|
|
100
|
+
// Открытие по клику или ховеру
|
|
91
101
|
function openDropdown() {
|
|
92
102
|
if (props.openByClick) {
|
|
93
103
|
open.value = !open.value;
|
|
94
104
|
}
|
|
95
105
|
|
|
96
|
-
if (isMobile(breakpoints).value) {
|
|
106
|
+
if (isMobile(breakpoints).value && process.client) {
|
|
97
107
|
open.value = true;
|
|
98
108
|
|
|
99
109
|
nextTick(() => {
|
|
100
110
|
if (menuRef.value?.showModal) {
|
|
101
111
|
menuRef.value.showModal();
|
|
102
|
-
bodyScrollLocked.value = true;
|
|
112
|
+
bodyScrollLocked.value = true;
|
|
103
113
|
}
|
|
104
114
|
});
|
|
105
115
|
}
|
|
106
116
|
}
|
|
107
117
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
});
|
|
118
|
+
// Ховер-логика только на десктопе и без openByClick
|
|
119
|
+
function mouseHandler(isEnter: boolean) {
|
|
120
|
+
if (!isMobile(breakpoints).value && !props.openByClick && process.client) {
|
|
121
|
+
open.value = isEnter;
|
|
113
122
|
}
|
|
114
|
-
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Клик вне дропдауна
|
|
126
|
+
watch(
|
|
127
|
+
open,
|
|
128
|
+
(isOpen) => {
|
|
129
|
+
if (isOpen && process.client && dropdownRef.value) {
|
|
130
|
+
onClickOutside(dropdownRef.value, () => {
|
|
131
|
+
close();
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
{ immediate: true }
|
|
136
|
+
);
|
|
115
137
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
138
|
+
// Гарантированная разблокировка скролла при уходе со страницы
|
|
139
|
+
onBeforeUnmount(() => {
|
|
140
|
+
if (process.client) {
|
|
141
|
+
bodyScrollLocked.value = false;
|
|
119
142
|
}
|
|
120
|
-
}
|
|
143
|
+
});
|
|
121
144
|
|
|
122
145
|
const getMaxHeight = computed(() => {
|
|
123
146
|
return props.maxHeight ? `${props.maxHeight}px` : 'none';
|
|
@@ -2,16 +2,13 @@
|
|
|
2
2
|
<dialog
|
|
3
3
|
ref="notification"
|
|
4
4
|
class="s-notification"
|
|
5
|
-
:class="{'--popup': popup}"
|
|
5
|
+
:class="{ '--popup': popup }"
|
|
6
6
|
@click="closeByBackdropClick"
|
|
7
7
|
@cancel="close"
|
|
8
8
|
>
|
|
9
9
|
<div class="s-notification__wrapper">
|
|
10
10
|
<header class="s-notification__header">
|
|
11
|
-
<p
|
|
12
|
-
v-if="$slots.title"
|
|
13
|
-
class="s-notification__title"
|
|
14
|
-
>
|
|
11
|
+
<p v-if="$slots.title" class="s-notification__title">
|
|
15
12
|
<slot name="title"></slot>
|
|
16
13
|
</p>
|
|
17
14
|
<button
|
|
@@ -21,16 +18,13 @@
|
|
|
21
18
|
aria-label="close"
|
|
22
19
|
@click="close"
|
|
23
20
|
>
|
|
24
|
-
<SIcon class="s-notification__close-icon" name="close" size="16"/>
|
|
21
|
+
<SIcon class="s-notification__close-icon" name="close" size="16" />
|
|
25
22
|
</button>
|
|
26
23
|
</header>
|
|
27
24
|
<div class="s-notification__content">
|
|
28
25
|
<slot></slot>
|
|
29
26
|
</div>
|
|
30
|
-
<div
|
|
31
|
-
v-if="$slots.footer"
|
|
32
|
-
class="s-notification__footer"
|
|
33
|
-
>
|
|
27
|
+
<div v-if="$slots.footer" class="s-notification__footer">
|
|
34
28
|
<slot name="footer"></slot>
|
|
35
29
|
</div>
|
|
36
30
|
</div>
|
|
@@ -38,58 +32,71 @@
|
|
|
38
32
|
</template>
|
|
39
33
|
|
|
40
34
|
<script setup lang="ts">
|
|
41
|
-
import { ref, watch, onBeforeUnmount } from 'vue'
|
|
42
|
-
import { useScrollLock } from '@vueuse/core'
|
|
43
|
-
import { onBackdropClick } from '../../runtime'
|
|
35
|
+
import { ref, watch, onMounted, onBeforeUnmount } from 'vue'
|
|
36
|
+
import { useScrollLock } from '@vueuse/core'
|
|
37
|
+
import { onBackdropClick } from '../../runtime'
|
|
44
38
|
|
|
45
|
-
const notification = ref<HTMLDialogElement | null>(null)
|
|
39
|
+
const notification = ref<HTMLDialogElement | null>(null)
|
|
46
40
|
|
|
47
41
|
const emit = defineEmits<{
|
|
48
|
-
(
|
|
49
|
-
(
|
|
50
|
-
}>()
|
|
42
|
+
(e: 'update:modelValue', value: boolean): void
|
|
43
|
+
(e: 'close'): void
|
|
44
|
+
}>()
|
|
51
45
|
|
|
52
46
|
const props = defineProps<{
|
|
53
47
|
modelValue: boolean
|
|
54
48
|
popup?: boolean
|
|
55
|
-
}>()
|
|
49
|
+
}>()
|
|
50
|
+
|
|
51
|
+
// Создаём элемент ТОЛЬКО на клиенте
|
|
52
|
+
const bodyElement = ref<HTMLElement | null>(null)
|
|
53
|
+
const isBodyScrollLocked = useScrollLock(bodyElement)
|
|
56
54
|
|
|
57
|
-
//
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
// Инициализируем body только после монтирования на клиенте
|
|
56
|
+
onMounted(() => {
|
|
57
|
+
bodyElement.value = document.body
|
|
58
|
+
})
|
|
60
59
|
|
|
60
|
+
// Реактивно управляем открытием/закрытием и блокировкой скролла
|
|
61
61
|
watch(
|
|
62
62
|
() => props.modelValue,
|
|
63
|
-
(
|
|
64
|
-
if (
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
} else if (
|
|
73
|
-
notification.value
|
|
74
|
-
|
|
75
|
-
|
|
63
|
+
(isOpen) => {
|
|
64
|
+
if (!notification.value) return
|
|
65
|
+
|
|
66
|
+
if (isOpen && props.popup) {
|
|
67
|
+
notification.value.showModal()
|
|
68
|
+
// Блокировка только если мы уже на клиенте и body доступен
|
|
69
|
+
if (process.client && bodyElement.value) {
|
|
70
|
+
isBodyScrollLocked.value = true
|
|
71
|
+
}
|
|
72
|
+
} else if (!isOpen && props.popup) {
|
|
73
|
+
notification.value.close()
|
|
74
|
+
if (process.client) {
|
|
75
|
+
isBodyScrollLocked.value = false
|
|
76
|
+
}
|
|
77
|
+
} else if (isOpen && !props.popup) {
|
|
78
|
+
notification.value.show()
|
|
79
|
+
} else if (!isOpen && !props.popup) {
|
|
80
|
+
notification.value.close()
|
|
76
81
|
}
|
|
77
82
|
},
|
|
78
83
|
{ immediate: true }
|
|
79
|
-
)
|
|
84
|
+
)
|
|
80
85
|
|
|
81
|
-
//
|
|
86
|
+
// Гарантированная разблокировка при уходе со страницы
|
|
82
87
|
onBeforeUnmount(() => {
|
|
83
|
-
|
|
84
|
-
|
|
88
|
+
if (process.client) {
|
|
89
|
+
isBodyScrollLocked.value = false
|
|
90
|
+
}
|
|
91
|
+
})
|
|
85
92
|
|
|
86
93
|
function close() {
|
|
87
|
-
emit('close')
|
|
88
|
-
emit('update:modelValue', false)
|
|
94
|
+
emit('close')
|
|
95
|
+
emit('update:modelValue', false)
|
|
89
96
|
}
|
|
90
97
|
|
|
91
98
|
function closeByBackdropClick(event: Event) {
|
|
92
|
-
const target = event.target as HTMLDialogElement
|
|
93
|
-
onBackdropClick(target, close)
|
|
99
|
+
const target = event.target as HTMLDialogElement
|
|
100
|
+
onBackdropClick(target, close)
|
|
94
101
|
}
|
|
95
102
|
</script>
|
|
@@ -1,146 +1,144 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<dialog
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
{'--sheet': sheet},
|
|
7
|
-
{'--transparent-backdrop': transparentBackdrop},
|
|
8
|
-
{'--aside': $slots.aside}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
>
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
@click="close"
|
|
22
|
-
></button>
|
|
23
|
-
</div>
|
|
2
|
+
<dialog
|
|
3
|
+
ref="popupRef"
|
|
4
|
+
class="s-popup"
|
|
5
|
+
:class="[
|
|
6
|
+
{ '--sheet': sheet },
|
|
7
|
+
{ '--transparent-backdrop': transparentBackdrop },
|
|
8
|
+
{ '--aside': $slots.aside }
|
|
9
|
+
]"
|
|
10
|
+
@click="closeByBackdropClick"
|
|
11
|
+
@cancel="close"
|
|
12
|
+
>
|
|
13
|
+
<div class="s-popup__wrapper">
|
|
14
|
+
<div v-if="sheet" class="s-popup__sheet">
|
|
15
|
+
<button
|
|
16
|
+
class="s-popup__sheet-handler"
|
|
17
|
+
type="button"
|
|
18
|
+
@click="close"
|
|
19
|
+
></button>
|
|
20
|
+
</div>
|
|
24
21
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
>
|
|
29
|
-
<slot name="aside"></slot>
|
|
30
|
-
</aside>
|
|
31
|
-
|
|
32
|
-
<header
|
|
33
|
-
class="s-popup__header"
|
|
34
|
-
>
|
|
35
|
-
<button
|
|
36
|
-
v-if="back"
|
|
37
|
-
class="s-popup__back"
|
|
38
|
-
type="button"
|
|
39
|
-
@click="$emit('back')"
|
|
40
|
-
>
|
|
41
|
-
<SIcon name="angle-left" size="24" />
|
|
42
|
-
</button>
|
|
43
|
-
<div
|
|
44
|
-
v-if="$slots.title"
|
|
45
|
-
class="s-popup__title"
|
|
22
|
+
<aside
|
|
23
|
+
v-if="$slots.aside && !isMobile(breakpoints).value"
|
|
24
|
+
class="s-popup__aside"
|
|
46
25
|
>
|
|
47
|
-
<slot name="
|
|
26
|
+
<slot name="aside"></slot>
|
|
27
|
+
</aside>
|
|
28
|
+
|
|
29
|
+
<header class="s-popup__header">
|
|
30
|
+
<button
|
|
31
|
+
v-if="back"
|
|
32
|
+
class="s-popup__back"
|
|
33
|
+
type="button"
|
|
34
|
+
@click="$emit('back')"
|
|
35
|
+
>
|
|
36
|
+
<SIcon name="angle-left" size="24" />
|
|
37
|
+
</button>
|
|
38
|
+
|
|
39
|
+
<div v-if="$slots.title" class="s-popup__title">
|
|
40
|
+
<slot name="title"></slot>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<button
|
|
44
|
+
class="s-popup__close"
|
|
45
|
+
type="button"
|
|
46
|
+
@click="close"
|
|
47
|
+
>
|
|
48
|
+
<SIcon name="close" size="24" />
|
|
49
|
+
</button>
|
|
50
|
+
</header>
|
|
51
|
+
|
|
52
|
+
<div v-if="$slots.fixedContent" class="s-popup__subheader">
|
|
53
|
+
<slot name="fixedContent"></slot>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<div v-if="$slots.default" class="s-popup__content">
|
|
57
|
+
<slot></slot>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<div v-if="$slots.footer" class="s-popup__footer">
|
|
61
|
+
<slot name="footer"></slot>
|
|
48
62
|
</div>
|
|
49
|
-
<button
|
|
50
|
-
class="s-popup__close"
|
|
51
|
-
type="button"
|
|
52
|
-
@click="close"
|
|
53
|
-
>
|
|
54
|
-
<SIcon name="close" size="24" />
|
|
55
|
-
</button>
|
|
56
|
-
</header>
|
|
57
|
-
<div
|
|
58
|
-
v-if="$slots.fixedContent"
|
|
59
|
-
class="s-popup__subheader"
|
|
60
|
-
>
|
|
61
|
-
<slot name="fixedContent"></slot>
|
|
62
|
-
</div>
|
|
63
|
-
<div
|
|
64
|
-
v-if="$slots.default"
|
|
65
|
-
class="s-popup__content"
|
|
66
|
-
>
|
|
67
|
-
<slot></slot>
|
|
68
|
-
</div>
|
|
69
|
-
<div
|
|
70
|
-
v-if="$slots.footer"
|
|
71
|
-
class="s-popup__footer"
|
|
72
|
-
>
|
|
73
|
-
<slot name="footer"></slot>
|
|
74
63
|
</div>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
/>
|
|
81
|
-
</transition>
|
|
82
|
-
</dialog>
|
|
64
|
+
|
|
65
|
+
<transition mode="out-in">
|
|
66
|
+
<SSnackbar v-if="snackbarText && isSnackBarInPopup" />
|
|
67
|
+
</transition>
|
|
68
|
+
</dialog>
|
|
83
69
|
</template>
|
|
84
70
|
|
|
85
71
|
<script setup lang="ts">
|
|
72
|
+
import { ref, watch, nextTick, onMounted, onBeforeUnmount } from 'vue';
|
|
73
|
+
import { useScrollLock } from '@vueuse/core';
|
|
86
74
|
import { onBackdropClick, isMobile } from '../../runtime';
|
|
87
75
|
import type { CssBreakpoints } from '../../types';
|
|
88
|
-
import {
|
|
76
|
+
import { useSnackbar } from '~/composables/useSnackbar'; // предполагаю, что это composable
|
|
89
77
|
|
|
90
|
-
const
|
|
78
|
+
const popupRef = ref<HTMLDialogElement | null>(null);
|
|
91
79
|
|
|
92
|
-
const breakpoints = useAppConfig().cssBreakpoints as Record<CssBreakpoints, number>;
|
|
93
|
-
const popupRef = ref()
|
|
94
80
|
const emit = defineEmits<{
|
|
95
|
-
(
|
|
96
|
-
(
|
|
97
|
-
(
|
|
98
|
-
}>()
|
|
81
|
+
(e: 'update:modelValue', value: boolean): void;
|
|
82
|
+
(e: 'back'): void;
|
|
83
|
+
(e: 'close'): void;
|
|
84
|
+
}>();
|
|
99
85
|
|
|
100
86
|
const props = defineProps<{
|
|
101
|
-
modelValue: boolean
|
|
102
|
-
back?: boolean
|
|
103
|
-
transparentBackdrop?: boolean
|
|
104
|
-
sheet?: boolean
|
|
105
|
-
title?: string
|
|
106
|
-
notModal?: boolean
|
|
107
|
-
}>()
|
|
108
|
-
|
|
109
|
-
const isLocked = useScrollLock(
|
|
110
|
-
typeof document !== 'undefined' ? document.body : null
|
|
111
|
-
);
|
|
87
|
+
modelValue: boolean;
|
|
88
|
+
back?: boolean;
|
|
89
|
+
transparentBackdrop?: boolean;
|
|
90
|
+
sheet?: boolean;
|
|
91
|
+
title?: string;
|
|
92
|
+
notModal?: boolean;
|
|
93
|
+
}>();
|
|
112
94
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
isLocked.value = true;
|
|
119
|
-
|
|
120
|
-
if (props.notModal) {
|
|
121
|
-
popupRef.value?.show();
|
|
122
|
-
} else {
|
|
123
|
-
popupRef.value?.showModal();
|
|
124
|
-
}
|
|
125
|
-
popupRef.value?.focus({ preventScroll: true });
|
|
126
|
-
});
|
|
127
|
-
} else {
|
|
128
|
-
isLocked.value = false;
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
{ immediate: true }
|
|
132
|
-
);
|
|
95
|
+
const breakpoints = useAppConfig().cssBreakpoints as Record<CssBreakpoints, number>;
|
|
96
|
+
|
|
97
|
+
// SSR-safe scroll lock
|
|
98
|
+
const bodyElement = ref<HTMLElement | null>(null);
|
|
99
|
+
const isLocked = useScrollLock(bodyElement);
|
|
133
100
|
|
|
134
101
|
onMounted(() => {
|
|
102
|
+
bodyElement.value = document.body;
|
|
103
|
+
|
|
104
|
+
// Включаем режим отображения снакбара внутри попапа
|
|
135
105
|
isSnackBarInPopup.value = true;
|
|
136
106
|
resetSnackbar();
|
|
137
107
|
});
|
|
138
108
|
|
|
139
109
|
onBeforeUnmount(() => {
|
|
140
110
|
isSnackBarInPopup.value = false;
|
|
141
|
-
|
|
111
|
+
if (process.client) {
|
|
112
|
+
isLocked.value = false;
|
|
113
|
+
}
|
|
142
114
|
});
|
|
143
115
|
|
|
116
|
+
// Реактивное открытие/закрытие + блокировка скролла
|
|
117
|
+
watch(
|
|
118
|
+
() => props.modelValue,
|
|
119
|
+
async (isOpen) => {
|
|
120
|
+
if (!process.client || !popupRef.value) return;
|
|
121
|
+
|
|
122
|
+
if (isOpen) {
|
|
123
|
+
await nextTick(); // гарантируем, что dialog уже в DOM
|
|
124
|
+
|
|
125
|
+
if (props.notModal) {
|
|
126
|
+
popupRef.value.show();
|
|
127
|
+
} else {
|
|
128
|
+
popupRef.value.showModal();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
popupRef.value.focus({ preventScroll: true });
|
|
132
|
+
isLocked.value = true;
|
|
133
|
+
} else {
|
|
134
|
+
isLocked.value = false;
|
|
135
|
+
// dialog автоматически закрывается при удалении из DOM, но на всякий случай
|
|
136
|
+
popupRef.value.close();
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
{ immediate: true }
|
|
140
|
+
);
|
|
141
|
+
|
|
144
142
|
function close() {
|
|
145
143
|
emit('close');
|
|
146
144
|
emit('update:modelValue', false);
|
|
@@ -151,5 +149,6 @@ function closeByBackdropClick(event: Event) {
|
|
|
151
149
|
onBackdropClick(target, close);
|
|
152
150
|
}
|
|
153
151
|
|
|
154
|
-
|
|
152
|
+
// Доступ к состоянию снакбара
|
|
153
|
+
const { snackbarText, isSnackBarInPopup, resetSnackbar } = useSnackbar();
|
|
155
154
|
</script>
|