From 82bcdf7bdc4bb1844f9225ab2b787c2ae354f328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Su=C5=A1ick=C3=BD?= Date: Sat, 5 Oct 2024 16:04:55 +0200 Subject: [PATCH] feat(optimization): hydrate toaster component on demand Closes #16 --- apps/cloudflare | 2 +- apps/web/astro.config.ts | 3 +++ apps/web/lib/event-directive.ts | 12 ++++++++++++ apps/web/lib/index.d.ts | 7 +++++++ apps/web/lib/register.ts | 13 +++++++++++++ apps/web/src/components/form/contact-form.tsx | 5 ++++- apps/web/src/config.ts | 2 ++ apps/web/src/pages/index.astro | 4 +++- apps/web/tsconfig.json | 2 +- 9 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 apps/web/lib/event-directive.ts create mode 100644 apps/web/lib/index.d.ts create mode 100644 apps/web/lib/register.ts diff --git a/apps/cloudflare b/apps/cloudflare index 58f2de4..30fd226 160000 --- a/apps/cloudflare +++ b/apps/cloudflare @@ -1 +1 @@ -Subproject commit 58f2de40f56e2fac7d388086fd37bcb51237b504 +Subproject commit 30fd2268cdac9819bf97e93d69145010f8ffcfb1 diff --git a/apps/web/astro.config.ts b/apps/web/astro.config.ts index d38ac2e..b472d29 100644 --- a/apps/web/astro.config.ts +++ b/apps/web/astro.config.ts @@ -21,6 +21,8 @@ import { browserslist } from "./package.json"; import sectionize from "@frontendista/rehype-sectionize"; import { rehypeHeadingIds } from "@astrojs/markdown-remark"; +import eventDirective from "./lib/register"; + import type { AstroIntegration } from "astro"; config(); @@ -51,6 +53,7 @@ if (process.env.VERCEL_ENV !== "production" || process.env.ENABLE_MOCKS === "1") } const integrations: AstroIntegration[] = [ + eventDirective(), mdx(), TailwindCSS({ applyBaseStyles: false diff --git a/apps/web/lib/event-directive.ts b/apps/web/lib/event-directive.ts new file mode 100644 index 0000000..418f432 --- /dev/null +++ b/apps/web/lib/event-directive.ts @@ -0,0 +1,12 @@ +import type { ClientDirective } from "astro"; + +export default (function (load, options) { + window.addEventListener( + options.value, + async () => { + const hydrate = await load(); + await hydrate(); + }, + { once: true }, + ); +} satisfies ClientDirective); diff --git a/apps/web/lib/index.d.ts b/apps/web/lib/index.d.ts new file mode 100644 index 0000000..1bf2f3c --- /dev/null +++ b/apps/web/lib/index.d.ts @@ -0,0 +1,7 @@ +import "astro"; + +declare module "astro" { + interface AstroClientDirectives { + "client:event"?: string; + } +} diff --git a/apps/web/lib/register.ts b/apps/web/lib/register.ts new file mode 100644 index 0000000..e683ab9 --- /dev/null +++ b/apps/web/lib/register.ts @@ -0,0 +1,13 @@ +import type { AstroIntegration } from "astro"; + +export default (): AstroIntegration => ({ + name: "client:event", + hooks: { + "astro:config:setup": ({ addClientDirective }) => { + addClientDirective({ + name: "event", + entrypoint: "./lib/event-directive.ts", + }); + }, + }, +}); diff --git a/apps/web/src/components/form/contact-form.tsx b/apps/web/src/components/form/contact-form.tsx index 52af0f2..c59eb64 100644 --- a/apps/web/src/components/form/contact-form.tsx +++ b/apps/web/src/components/form/contact-form.tsx @@ -9,6 +9,7 @@ import { TextTooltip } from "./radix/tooltip"; import { withClass } from "./hoc"; import { Textarea } from "./textarea"; import { Icon } from "../common/icon"; +import { CLIENT_EVENT_TOASTER } from "../../config"; import { delayPromise } from "~/utils/promise"; import { toast } from "~/stores/toast"; @@ -95,6 +96,8 @@ export const ContactForm: FunctionComponent = () => { }; const handleSubmit: JSX.SubmitEventHandler = async (event) => { + dispatchEvent(new Event(CLIENT_EVENT_TOASTER)); + event.preventDefault(); setLoading(true); @@ -301,7 +304,7 @@ export const ContactForm: FunctionComponent = () => { {image ? ( setHasDownloaded(true)}> - Generated image + Generated card ) : null} diff --git a/apps/web/src/config.ts b/apps/web/src/config.ts index a00f997..6bbec1d 100644 --- a/apps/web/src/config.ts +++ b/apps/web/src/config.ts @@ -1,3 +1,5 @@ +export const CLIENT_EVENT_TOASTER = "toaster-hydrate"; + interface Config { status: string | false; } diff --git a/apps/web/src/pages/index.astro b/apps/web/src/pages/index.astro index 89e170a..2b57957 100644 --- a/apps/web/src/pages/index.astro +++ b/apps/web/src/pages/index.astro @@ -10,6 +10,8 @@ import HeroSection from "./_index/hero-section.astro"; import ProjectSection from "./_index/project-section.astro"; import AboutSection from "./_index/about-section.astro"; import ContactSection from "./_index/contact-section.astro"; + +import { CLIENT_EVENT_TOASTER } from "../config"; --- @@ -21,5 +23,5 @@ import ContactSection from "./_index/contact-section.astro"; - + diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index 0116706..5c82ca9 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -18,5 +18,5 @@ "jsx": "react-jsx", "jsxImportSource": "preact", }, - "include": ["astro.config.ts", "tailwind.config.ts", "./src/**/*.ts", "./src/**/*.tsx", "./src/**/*.astro"] + "include": ["astro.config.ts", "tailwind.config.ts", "./src/**/*.ts", "./src/**/*.tsx", "./src/**/*.astro", "lib/**/*.d.ts"] }