Automatically adjust dialog position when the virtual keyboard is displayed, and allow input from the virtual keyboard to update value bindings in Svelte textfields.
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
import TextField from "@smui/textfield";
|
||||
import MessageDialog from "$dialogs/MessageDialog.svelte";
|
||||
import * as api from "$lib/api";
|
||||
import { virtualKeyboardChangeHelper } from "$lib/customActions";
|
||||
|
||||
// https://man7.org/linux/man-pages/man7/hostname.7.html
|
||||
//
|
||||
@@ -72,15 +73,12 @@
|
||||
<Content id="change-hostname-dialog-content">
|
||||
<TextField
|
||||
bind:value={hostname}
|
||||
use={[[virtualKeyboardChangeHelper, (newValue) => (hostname = newValue)]]}
|
||||
label="New Hostname"
|
||||
spellcheck="false"
|
||||
variant="filled"
|
||||
style="width: 100%;"
|
||||
/>
|
||||
|
||||
<p>
|
||||
<em>Clicking Confirm will reboot the controller to apply the change.</em>
|
||||
</p>
|
||||
</Content>
|
||||
|
||||
<Actions>
|
||||
|
||||
@@ -135,6 +135,67 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { onMount, onDestroy } from "svelte";
|
||||
|
||||
let bodyObserver: MutationObserver;
|
||||
let keyboardObserver: MutationObserver;
|
||||
|
||||
onMount(() => {
|
||||
bodyObserver = new MutationObserver(() => {
|
||||
const virtualKeyboard = document.getElementById(
|
||||
"virtualKeyboardChromeExtension"
|
||||
);
|
||||
|
||||
if (virtualKeyboard) {
|
||||
bodyObserver.disconnect();
|
||||
bodyObserver = undefined;
|
||||
|
||||
const virtualKeyboardOverlay = document.getElementById(
|
||||
"virtualKeyboardChromeExtensionOverlayScrollExtend"
|
||||
);
|
||||
|
||||
keyboardObserver = new MutationObserver(() => {
|
||||
const open = virtualKeyboard.getAttribute("_state") === "open";
|
||||
const keyboardHeight = Number.parseFloat(
|
||||
virtualKeyboardOverlay.style.height
|
||||
);
|
||||
|
||||
const dialogContainers = document.querySelectorAll<HTMLDivElement>(
|
||||
".mdc-dialog .mdc-dialog__container"
|
||||
);
|
||||
|
||||
for (let dialogContainer of dialogContainers) {
|
||||
dialogContainer.style["marginBottom"] = open
|
||||
? `${keyboardHeight}px`
|
||||
: "";
|
||||
}
|
||||
});
|
||||
|
||||
keyboardObserver.observe(virtualKeyboard, { attributes: true });
|
||||
}
|
||||
});
|
||||
|
||||
bodyObserver.observe(document.querySelector("body"), {
|
||||
subtree: false,
|
||||
childList: true,
|
||||
});
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
if (bodyObserver) {
|
||||
bodyObserver.disconnect();
|
||||
bodyObserver = undefined;
|
||||
}
|
||||
|
||||
if (keyboardObserver) {
|
||||
keyboardObserver.disconnect();
|
||||
keyboardObserver = undefined;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<HomeMachineDialog {...$HomeMachineDialogProps} />
|
||||
<ProbeDialog {...$ProbeDialogProps} />
|
||||
<ScreenRotationDialog {...$ScreenRotationDialogProps} />
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import TextField from "@smui/textfield";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import { ControllerMethods } from "$lib/RegisterControllerMethods";
|
||||
import { virtualKeyboardChangeHelper } from "$lib/customActions";
|
||||
|
||||
export let open: boolean;
|
||||
export let axis = "";
|
||||
@@ -30,6 +31,7 @@
|
||||
label="Absolute"
|
||||
type="number"
|
||||
bind:value
|
||||
use={[[virtualKeyboardChangeHelper, (newValue) => (value = newValue)]]}
|
||||
variant="filled"
|
||||
style="width: 100%;"
|
||||
/>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import TextField from "@smui/textfield";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import { ControllerMethods } from "$lib/RegisterControllerMethods";
|
||||
import { virtualKeyboardChangeHelper } from "$lib/customActions";
|
||||
|
||||
export let open: boolean;
|
||||
export let axis = "";
|
||||
@@ -42,6 +43,7 @@
|
||||
label="Position"
|
||||
type="number"
|
||||
bind:value
|
||||
use={[[virtualKeyboardChangeHelper, (newValue) => (value = newValue)]]}
|
||||
spellcheck="false"
|
||||
variant="filled"
|
||||
style="width: 100%;"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import CircularProgress from "@smui/circular-progress";
|
||||
import VirtualList from "svelte-tiny-virtual-list";
|
||||
import * as api from "$lib/api";
|
||||
import { virtualKeyboardChangeHelper } from "$lib/customActions";
|
||||
|
||||
const itemHeight = 35;
|
||||
|
||||
@@ -153,6 +154,9 @@
|
||||
<Label>Date & Time</Label>
|
||||
<TextField
|
||||
bind:value
|
||||
use={[
|
||||
[virtualKeyboardChangeHelper, (newValue) => (value = newValue)],
|
||||
]}
|
||||
label="Time"
|
||||
type="datetime-local"
|
||||
variant="filled"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import MessageDialog from "$dialogs/MessageDialog.svelte";
|
||||
import type { WifiNetwork } from "$lib/NetworkInfo";
|
||||
import * as api from "$lib/api";
|
||||
import { virtualKeyboardChangeHelper } from "$lib/customActions";
|
||||
|
||||
export let open = false;
|
||||
export let network: WifiNetwork;
|
||||
@@ -56,6 +57,7 @@
|
||||
{#if needPassword}
|
||||
<TextField
|
||||
bind:value={password}
|
||||
use={[[virtualKeyboardChangeHelper, (newValue) => (password = newValue)]]}
|
||||
label="Password"
|
||||
spellcheck="false"
|
||||
variant="filled"
|
||||
|
||||
4
src/svelte-components/src/lib/customActions.ts
Normal file
4
src/svelte-components/src/lib/customActions.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export function virtualKeyboardChangeHelper(node: HTMLElement, cb: (value: any) => void) {
|
||||
const input = node.querySelector("input");
|
||||
input.addEventListener("keyup", () => cb(input.value));
|
||||
}
|
||||
@@ -20,6 +20,10 @@
|
||||
:root {
|
||||
--mdc-theme-text-primary-on-background: #777;
|
||||
|
||||
.mdc-dialog .mdc-dialog__container {
|
||||
transition: margin-bottom 0.5s;
|
||||
}
|
||||
|
||||
.mdc-dialog .mdc-dialog__content {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user