-
Notifications
You must be signed in to change notification settings - Fork 130
/
Copy pathutils.ts
84 lines (72 loc) · 2.26 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import { BASE, BASE_NOFS } from "~/constants.js";
export const doesPathnameMatchBase = (pathname: string) =>
pathname === BASE || pathname === BASE_NOFS;
// Credit https://stackoverflow.com/a/55652503/8234457
/**
* Must be invoked inside user events, such as onclick
*/
export const focusInputAndKeepVirtualKeyboardOpen = (
input: HTMLElement | (() => HTMLElement),
{ timeout }: { timeout?: number } = {},
) => {
// create invisible dummy input to receive the focus first
const fakeInput = document.createElement("input");
fakeInput.setAttribute("type", "text");
fakeInput.style.position = "absolute";
fakeInput.style.opacity = "0";
fakeInput.style.height = "0";
fakeInput.style.fontSize = "16px"; // disable auto zoom
// you may need to append to another element depending on the browser's auto
// zoom/scroll behavior
document.body.prepend(fakeInput);
// focus so that subsequent async focus will work
fakeInput.focus();
const switchFocus = () => {
/**
* do not query dom inside this block
*/
if (typeof input === "function") {
input()!.focus();
} else {
input.focus();
}
fakeInput.remove();
};
if (timeout) {
setTimeout(switchFocus, timeout);
return;
}
requestAnimationFrame(switchFocus);
};
export function getTextWidth(text: string, font: string): number {
// re-use canvas object for better performance
const canvas: HTMLCanvasElement =
// @ts-ignore
getTextWidth.canvas ||
// @ts-ignore
(getTextWidth.canvas = document.createElement("canvas"));
const context = canvas.getContext("2d")!;
context.font = font;
const metrics = context.measureText(text);
return metrics.width;
}
export function reflow() {
document.body.clientWidth;
}
export const scrollIntoView = (
input: string | Element,
{ offset, behavior }: { offset: number; behavior: "auto" | "smooth" },
) => {
const el = typeof input === "string" ? document.querySelector(input) : input;
if (!el) return;
window.scrollTo({
behavior,
top: el.getBoundingClientRect().top - document.body.getBoundingClientRect().top - offset,
});
};
export const kebabCaseToCapitalized = (str: string) => {
return str
.split("-")
.map(word => word[0]!.toUpperCase() + word.slice(1))
.join(" ");
};