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
|
import { useState, useMemo, useCallback, useEffect } from "react";
import {
getCachedFontAtlas,
loadFontAtlas,
clearFontAtlasCache,
} from "@/lib/fonts/google-fonts";
import type { FontAtlas } from "@/lib/fonts/types";
import { SYSTEM_FONTS } from "@/lib/fonts/system-fonts";
type Status = "idle" | "loading" | "error";
export function useFontAtlas({ open }: { open: boolean }) {
const [atlas, setAtlas] = useState<FontAtlas | null>(() =>
getCachedFontAtlas(),
);
const [status, setStatus] = useState<Status>(() =>
getCachedFontAtlas() ? "idle" : "loading",
);
useEffect(() => {
if (!open || atlas) return;
setStatus("loading");
loadFontAtlas().then((data) => {
if (data) {
setAtlas(data);
setStatus("idle");
} else {
setStatus("error");
}
});
}, [open, atlas]);
const retry = useCallback(() => {
clearFontAtlasCache();
setStatus("loading");
loadFontAtlas().then((data) => {
if (data) {
setAtlas(data);
setStatus("idle");
} else {
setStatus("error");
}
});
}, []);
const fontNames = useMemo(() => {
if (!atlas) return [];
return [...Object.keys(atlas.fonts), ...SYSTEM_FONTS].sort();
}, [atlas]);
return { atlas, status, fontNames, retry };
}
|