@saasmakers/ui 2.0.79 → 2.0.81
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.
|
@@ -46,10 +46,12 @@ const id = useId()
|
|
|
46
46
|
const modelValue = defineModel<FieldInput['modelValue']>({ default: '' })
|
|
47
47
|
const input = ref<HTMLInputElement>()
|
|
48
48
|
const showPassword = ref(false)
|
|
49
|
-
const { isDesktopBrowser } = useDevice()
|
|
50
49
|
|
|
50
|
+
// On mobile, a prior focusWarmupInput() already opened the keyboard in the
|
|
51
|
+
// user gesture; focusing here moves focus input→input so the keyboard stays
|
|
52
|
+
// open and typing lands in the visible field.
|
|
51
53
|
onMounted(() => {
|
|
52
|
-
if (props.autofocus && input.value
|
|
54
|
+
if (props.autofocus && input.value) {
|
|
53
55
|
input.value.focus()
|
|
54
56
|
}
|
|
55
57
|
})
|
|
@@ -30,10 +30,11 @@ const emit = defineEmits<{
|
|
|
30
30
|
const id = useId()
|
|
31
31
|
const modelValue = defineModel<FieldTextarea['modelValue']>({ default: '' })
|
|
32
32
|
const textarea = ref<HTMLTextAreaElement>()
|
|
33
|
-
const { isDesktopBrowser } = useDevice()
|
|
34
33
|
|
|
34
|
+
// Same as FieldInput: on mobile, transfer focus from the keyboard warmup
|
|
35
|
+
// input so typing lands in the visible field while the keyboard stays open.
|
|
35
36
|
onMounted(() => {
|
|
36
|
-
if (props.autofocus && textarea.value
|
|
37
|
+
if (props.autofocus && textarea.value) {
|
|
37
38
|
textarea.value.focus()
|
|
38
39
|
}
|
|
39
40
|
})
|
|
@@ -19,6 +19,7 @@ const contentRef = ref<HTMLElement>()
|
|
|
19
19
|
const panelRef = ref<HTMLElement>()
|
|
20
20
|
const { release: onAfterLeave } = useDialog(visible, panelRef)
|
|
21
21
|
const { isKeyboardOpen, keyboardInset } = useKeyboardInset()
|
|
22
|
+
const skipLeaveSlide = ref(false)
|
|
22
23
|
|
|
23
24
|
const drag = reactive({
|
|
24
25
|
closing: false,
|
|
@@ -44,6 +45,19 @@ const panelStyle = computed(() => {
|
|
|
44
45
|
}
|
|
45
46
|
})
|
|
46
47
|
|
|
48
|
+
function dismissKeyboard() {
|
|
49
|
+
if (!import.meta.client) {
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const activeElement = document.activeElement
|
|
54
|
+
|
|
55
|
+
// Blur instead of Keyboard.hide() so focus is cleared too (incl. the warmup input).
|
|
56
|
+
if (activeElement instanceof HTMLElement && activeElement !== document.body) {
|
|
57
|
+
activeElement.blur()
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
47
61
|
function onBackdropClick() {
|
|
48
62
|
if (props.closeOnBackdrop) {
|
|
49
63
|
onClose()
|
|
@@ -84,6 +98,12 @@ function onHeaderPointerDown(event: PointerEvent) {
|
|
|
84
98
|
handle.setPointerCapture(event.pointerId)
|
|
85
99
|
}
|
|
86
100
|
|
|
101
|
+
function onLeaveComplete() {
|
|
102
|
+
skipLeaveSlide.value = false
|
|
103
|
+
|
|
104
|
+
onAfterLeave()
|
|
105
|
+
}
|
|
106
|
+
|
|
87
107
|
function onPanelTransitionEnd(event: TransitionEvent) {
|
|
88
108
|
if (event.propertyName !== 'transform' || !drag.closing) {
|
|
89
109
|
return
|
|
@@ -168,6 +188,13 @@ function onPointerUp(event: PointerEvent) {
|
|
|
168
188
|
handle.releasePointerCapture(event.pointerId)
|
|
169
189
|
|
|
170
190
|
if (drag.offset >= closeThreshold.value) {
|
|
191
|
+
if (isKeyboardOpen.value) {
|
|
192
|
+
onClose()
|
|
193
|
+
resetDragState()
|
|
194
|
+
|
|
195
|
+
return
|
|
196
|
+
}
|
|
197
|
+
|
|
171
198
|
drag.closing = true
|
|
172
199
|
|
|
173
200
|
return
|
|
@@ -192,6 +219,10 @@ function resetPendingDrag() {
|
|
|
192
219
|
|
|
193
220
|
watch(visible, (isVisible) => {
|
|
194
221
|
if (!isVisible) {
|
|
222
|
+
// iOS hides the keyboard before a leave slide would finish.
|
|
223
|
+
skipLeaveSlide.value = isKeyboardOpen.value
|
|
224
|
+
|
|
225
|
+
dismissKeyboard()
|
|
195
226
|
resetDragState()
|
|
196
227
|
}
|
|
197
228
|
})
|
|
@@ -209,13 +240,14 @@ watch(visible, (isVisible) => {
|
|
|
209
240
|
<ClientOnly>
|
|
210
241
|
<Teleport to="body">
|
|
211
242
|
<Transition
|
|
243
|
+
:css="!skipLeaveSlide"
|
|
212
244
|
enter-active-class="transition-transform duration-300 ease motion-reduce:transition-none motion-reduce:duration-0"
|
|
213
245
|
enter-from-class="translate-y-full motion-reduce:translate-y-0"
|
|
214
246
|
enter-to-class="translate-y-0"
|
|
215
247
|
leave-active-class="transition-transform duration-300 ease motion-reduce:transition-none motion-reduce:duration-0"
|
|
216
248
|
leave-from-class="translate-y-0"
|
|
217
249
|
leave-to-class="translate-y-full motion-reduce:translate-y-0"
|
|
218
|
-
@after-leave="
|
|
250
|
+
@after-leave="onLeaveComplete"
|
|
219
251
|
>
|
|
220
252
|
<div
|
|
221
253
|
v-if="visible"
|