Skip to content

Commit c93096e

Browse files
morealclaude
andcommitted
perf: lazy-load About modal to reduce initial bundle size
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 402ca9d commit c93096e

File tree

2 files changed

+107
-97
lines changed

2 files changed

+107
-97
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { Dialog } from "@base-ui/react/dialog";
2+
import { useLanguage } from "../hooks/useLanguage";
3+
4+
interface AboutModalProps {
5+
isOpen: boolean;
6+
onClose: () => void;
7+
}
8+
9+
function AboutModal({ isOpen, onClose }: AboutModalProps) {
10+
const { t } = useLanguage();
11+
const aboutContent = t("footer.aboutContent") as unknown as string[];
12+
13+
return (
14+
<Dialog.Root open={isOpen} onOpenChange={(open) => !open && onClose()}>
15+
<Dialog.Portal keepMounted>
16+
<Dialog.Backdrop
17+
className="modal-backdrop"
18+
style={{
19+
position: "fixed",
20+
top: 0,
21+
left: 0,
22+
right: 0,
23+
bottom: 0,
24+
backgroundColor: "rgba(0, 0, 0, 0.7)",
25+
zIndex: "var(--z-index-backdrop)",
26+
}}
27+
/>
28+
<Dialog.Popup
29+
className="modal-popup"
30+
style={{
31+
position: "fixed",
32+
top: "50%",
33+
left: "50%",
34+
transform: "translate(-50%, -50%)",
35+
backgroundColor: "var(--bg-primary)",
36+
color: "var(--text-primary)",
37+
padding: "1.5rem",
38+
borderRadius: "8px",
39+
maxWidth: "90vw",
40+
width: "600px",
41+
maxHeight: "90vh",
42+
overflow: "auto",
43+
zIndex: "var(--z-index-modal)",
44+
margin: "10px",
45+
}}
46+
>
47+
<Dialog.Close
48+
aria-label={t("common.close")}
49+
className="modal-close-button"
50+
style={{
51+
position: "absolute",
52+
top: "14px",
53+
right: "14px",
54+
background: "none",
55+
border: "none",
56+
color: "var(--text-primary)",
57+
fontSize: "24px",
58+
cursor: "pointer",
59+
width: "36px",
60+
height: "36px",
61+
display: "flex",
62+
alignItems: "center",
63+
justifyContent: "center",
64+
touchAction: "manipulation",
65+
}}
66+
>
67+
×
68+
</Dialog.Close>
69+
<Dialog.Title
70+
style={{
71+
marginTop: 0,
72+
color: "var(--text-primary)",
73+
fontSize: "clamp(20px, 5vw, 24px)",
74+
}}
75+
>
76+
{t("footer.aboutTitle")}
77+
</Dialog.Title>
78+
<Dialog.Description>
79+
{aboutContent.map((paragraph, index) => (
80+
<p
81+
key={index}
82+
style={{
83+
lineHeight: 1.6,
84+
color: "var(--text-primary)",
85+
wordBreak: "keep-all",
86+
fontSize: "clamp(14px, 4vw, 16px)",
87+
}}
88+
>
89+
{paragraph}
90+
</p>
91+
))}
92+
</Dialog.Description>
93+
</Dialog.Popup>
94+
</Dialog.Portal>
95+
</Dialog.Root>
96+
);
97+
}
98+
99+
export default AboutModal;
Lines changed: 8 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,9 @@
1-
import { useState } from "react";
2-
import { Dialog } from "@base-ui/react/dialog";
1+
import { useState, lazy, Suspense } from "react";
32
import { ThemeToggle } from "./ThemeToggle";
43
import { LanguageSelect } from "./LanguageSelect";
54
import { useLanguage } from "../hooks/useLanguage";
65

7-
interface AboutModalProps {
8-
isOpen: boolean;
9-
onClose: () => void;
10-
}
11-
12-
function AboutModal({ isOpen, onClose }: AboutModalProps) {
13-
const { t } = useLanguage();
14-
const aboutContent = t("footer.aboutContent") as unknown as string[];
15-
16-
return (
17-
<Dialog.Root open={isOpen} onOpenChange={(open) => !open && onClose()}>
18-
<Dialog.Portal keepMounted>
19-
<Dialog.Backdrop
20-
className="modal-backdrop"
21-
style={{
22-
position: "fixed",
23-
top: 0,
24-
left: 0,
25-
right: 0,
26-
bottom: 0,
27-
backgroundColor: "rgba(0, 0, 0, 0.7)",
28-
zIndex: "var(--z-index-backdrop)",
29-
}}
30-
/>
31-
<Dialog.Popup
32-
className="modal-popup"
33-
style={{
34-
position: "fixed",
35-
top: "50%",
36-
left: "50%",
37-
transform: "translate(-50%, -50%)",
38-
backgroundColor: "var(--bg-primary)",
39-
color: "var(--text-primary)",
40-
padding: "1.5rem",
41-
borderRadius: "8px",
42-
maxWidth: "90vw",
43-
width: "600px",
44-
maxHeight: "90vh",
45-
overflow: "auto",
46-
zIndex: "var(--z-index-modal)",
47-
margin: "10px",
48-
}}
49-
>
50-
<Dialog.Close
51-
aria-label={t("common.close")}
52-
className="modal-close-button"
53-
style={{
54-
position: "absolute",
55-
top: "14px",
56-
right: "14px",
57-
background: "none",
58-
border: "none",
59-
color: "var(--text-primary)",
60-
fontSize: "24px",
61-
cursor: "pointer",
62-
width: "36px",
63-
height: "36px",
64-
display: "flex",
65-
alignItems: "center",
66-
justifyContent: "center",
67-
touchAction: "manipulation",
68-
}}
69-
>
70-
×
71-
</Dialog.Close>
72-
<Dialog.Title
73-
style={{
74-
marginTop: 0,
75-
color: "var(--text-primary)",
76-
fontSize: "clamp(20px, 5vw, 24px)",
77-
}}
78-
>
79-
{t("footer.aboutTitle")}
80-
</Dialog.Title>
81-
<Dialog.Description>
82-
{aboutContent.map((paragraph, index) => (
83-
<p
84-
key={index}
85-
style={{
86-
lineHeight: 1.6,
87-
color: "var(--text-primary)",
88-
wordBreak: "keep-all",
89-
fontSize: "clamp(14px, 4vw, 16px)",
90-
}}
91-
>
92-
{paragraph}
93-
</p>
94-
))}
95-
</Dialog.Description>
96-
</Dialog.Popup>
97-
</Dialog.Portal>
98-
</Dialog.Root>
99-
);
100-
}
6+
const AboutModal = lazy(() => import("./AboutModal"));
1017

1028
export function Footer() {
1039
const [isAboutOpen, setIsAboutOpen] = useState(false);
@@ -157,7 +63,12 @@ export function Footer() {
15763
</a>
15864
<ThemeToggle />
15965
<LanguageSelect />
160-
<AboutModal isOpen={isAboutOpen} onClose={() => setIsAboutOpen(false)} />
66+
<Suspense fallback={null}>
67+
<AboutModal
68+
isOpen={isAboutOpen}
69+
onClose={() => setIsAboutOpen(false)}
70+
/>
71+
</Suspense>
16172
</footer>
16273
);
16374
}

0 commit comments

Comments
 (0)