diff --git a/package-lock.json b/package-lock.json index dc5039d..0cc86a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,10 +14,12 @@ "@react-three/postprocessing": "^3.0.4", "framer-motion": "^12.40.0", "gsap": "^3.15.0", + "leaflet": "^1.9.4", "lenis": "^1.3.23", "next": "16.2.6", "react": "19.2.4", "react-dom": "19.2.4", + "react-leaflet": "^5.0.0", "three": "^0.171.0" }, "devDependencies": { @@ -25,6 +27,7 @@ "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", "@types/jest": "^30.0.0", + "@types/leaflet": "^1.9.21", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", @@ -2277,6 +2280,17 @@ "url": "https://opencollective.com/pkgr" } }, + "node_modules/@react-leaflet/core": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-3.0.0.tgz", + "integrity": "sha512-3EWmekh4Nz+pGcr+xjf0KNyYfC3U2JjnkWsh0zcqaexYqmmB5ZhH37kz41JXGmKzpaMZCnPofBBm64i+YrEvGQ==", + "license": "Hippocratic-2.1", + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + } + }, "node_modules/@react-three/drei": { "version": "10.7.7", "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-10.7.7.tgz", @@ -2903,6 +2917,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -2996,6 +3017,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/leaflet": { + "version": "1.9.21", + "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.21.tgz", + "integrity": "sha512-TbAd9DaPGSnzp6QvtYngntMZgcRk+igFELwR2N99XZn7RXUdKgsXMR+28bUO0rPsWp8MIu/f47luLIQuSLYv/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@types/node": { "version": "20.19.41", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.41.tgz", @@ -8225,6 +8256,12 @@ "node": ">=0.10" } }, + "node_modules/leaflet": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", + "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", + "license": "BSD-2-Clause" + }, "node_modules/lenis": { "version": "1.3.23", "resolved": "https://registry.npmjs.org/lenis/-/lenis-1.3.23.tgz", @@ -9662,6 +9699,20 @@ "dev": true, "license": "MIT" }, + "node_modules/react-leaflet": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-5.0.0.tgz", + "integrity": "sha512-CWbTpr5vcHw5bt9i4zSlPEVQdTVcML390TjeDG0cK59z1ylexpqC6M1PJFjV8jD7CF+ACBFsLIDs6DRMoLEofw==", + "license": "Hippocratic-2.1", + "dependencies": { + "@react-leaflet/core": "^3.0.0" + }, + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + } + }, "node_modules/react-use-measure": { "version": "2.1.7", "resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz", diff --git a/package.json b/package.json index 722c841..4dde4b8 100644 --- a/package.json +++ b/package.json @@ -19,10 +19,12 @@ "@react-three/postprocessing": "^3.0.4", "framer-motion": "^12.40.0", "gsap": "^3.15.0", + "leaflet": "^1.9.4", "lenis": "^1.3.23", "next": "16.2.6", "react": "19.2.4", "react-dom": "19.2.4", + "react-leaflet": "^5.0.0", "three": "^0.171.0" }, "devDependencies": { @@ -30,6 +32,7 @@ "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", "@types/jest": "^30.0.0", + "@types/leaflet": "^1.9.21", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", diff --git a/src/components/map/ContactMapEmbed.tsx b/src/components/map/ContactMapEmbed.tsx new file mode 100644 index 0000000..44a57f8 --- /dev/null +++ b/src/components/map/ContactMapEmbed.tsx @@ -0,0 +1,22 @@ +"use client"; + +/** + * ContactMapEmbed + * --------------------------------------------------------------------------- + * Client boundary that lazy-loads the Leaflet map. `ssr: false` keeps Leaflet + * out of the server bundle and off the critical render path; the skeleton fills + * the host container's fixed height so there is zero layout shift (CLS) while + * the map chunk loads. + */ + +import dynamic from "next/dynamic"; +import styles from "./OfficeMap.module.css"; + +const OfficeMap = dynamic(() => import("./OfficeMap"), { + ssr: false, + loading: () =>