iOS: fix modal+validation scrolling (#29023)
This commit is contained in:
parent
94c2606797
commit
21efd23fcf
4 changed files with 29 additions and 2 deletions
|
|
@ -444,6 +444,11 @@ a:hover {
|
|||
}
|
||||
}
|
||||
|
||||
.modal {
|
||||
/* prevent touch-scroll chaining from the modal to <html> on iOS Safari */
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 1rem 0 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@ import YamlEntry from "./YamlEntry.vue";
|
|||
import AuthCodeDisplay from "../AuthCodeDisplay.vue";
|
||||
import AuthConnectButton from "../AuthConnectButton.vue";
|
||||
import { initialTestState, performTest } from "../utils/test";
|
||||
import { reportValidityInModal } from "../utils/reportValidityInModal";
|
||||
import { initialAuthState, prepareAuthLogin } from "../utils/authProvider";
|
||||
import sleep from "@/utils/sleep";
|
||||
import { ConfigType } from "@/types/evcc";
|
||||
|
|
@ -618,7 +619,7 @@ export default defineComponent({
|
|||
|
||||
// trigger browser validation
|
||||
if (this.$refs["form"]) {
|
||||
if (!(this.$refs["form"] as HTMLFormElement).reportValidity()) {
|
||||
if (!reportValidityInModal(this.$refs["form"] as HTMLFormElement)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
20
assets/js/components/Config/utils/reportValidityInModal.ts
Normal file
20
assets/js/components/Config/utils/reportValidityInModal.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* `form.reportValidity()` with the document scroll restored afterwards.
|
||||
*
|
||||
* The native call scroll-into-views the first invalid field and leaks scroll
|
||||
* up to `<html>` (overflow:hidden only blocks user scroll). On iOS Safari
|
||||
* that wedges the modal's touch scrolling onto the page underneath.
|
||||
*/
|
||||
export function reportValidityInModal(form: HTMLFormElement): boolean {
|
||||
const { scrollX, scrollY } = window;
|
||||
const valid = form.reportValidity();
|
||||
if (window.scrollX !== scrollX || window.scrollY !== scrollY) {
|
||||
// Chromium ignores scrollTop writes while overflow-y:hidden; relax briefly.
|
||||
const html = document.documentElement;
|
||||
const prev = html.style.overflowY;
|
||||
html.style.overflowY = "auto";
|
||||
window.scrollTo(scrollX, scrollY);
|
||||
html.style.overflowY = prev;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import type { AxiosResponse } from "axios";
|
||||
import sleep from "@/utils/sleep";
|
||||
import { reportValidityInModal } from "./reportValidityInModal";
|
||||
|
||||
export type TestState = {
|
||||
isUnknown: boolean;
|
||||
|
|
@ -28,7 +29,7 @@ export const performTest = async (
|
|||
api: () => Promise<AxiosResponse<any, any>>,
|
||||
form: HTMLElement | undefined
|
||||
) => {
|
||||
if (form && !(form as HTMLFormElement).reportValidity()) return false;
|
||||
if (form && !reportValidityInModal(form as HTMLFormElement)) return false;
|
||||
state.isUnknown = false;
|
||||
state.isSuccess = false;
|
||||
state.isRunning = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue