Skip to content

Commit

Permalink
Merge pull request #37 from plezanje-net/crags-fix-map-markers
Browse files Browse the repository at this point in the history
Crags fix map markers
  • Loading branch information
salamca authored Mar 10, 2024
2 parents 0dac8a9 + 68c65e2 commit b1d6ebc
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 27 deletions.
2 changes: 1 addition & 1 deletion src/app/[lang]/crag/[cragSlug]/info/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ import Map from "@/components/map/map";
import Button from "@/components/ui/button";
import IconMissing from "@/components/ui/icons/missing";
import Link from "@/components/ui/link";
import { TMarker } from "@/components/map/lazy-map";
import { IconSize } from "@/components/ui/icons/icon-size";
import IconMore from "@/components/ui/icons/more";
import { TMarker } from "@/components/map/map-marker";

type TCragInfoPageParams = {
cragSlug: string;
Expand Down
29 changes: 4 additions & 25 deletions src/components/map/lazy-map.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
"use client";

import { MapContainer, Marker, Popup, TileLayer } from "react-leaflet";
import { MapContainer, TileLayer } from "react-leaflet";
import L, { FitBoundsOptions } from "leaflet";
import "leaflet/dist/leaflet.css";
import ReactDOMServer from "react-dom/server";
import IconMarker from "../ui/icons/marker";
import { ReactNode } from "react";
import "./map.css";

type TMarker = {
type: "parking" | "wall";
position: [number, number];
popupContent?: ReactNode;
};
import MapMarker, { TMarker } from "./map-marker";

type TLazyMapProps = {
children?: ReactNode;
Expand Down Expand Up @@ -64,27 +57,13 @@ function LazyMap({
/>

{markers?.map((marker, index) => (
<Marker
key={index}
icon={L.divIcon({
className: "",
html: ReactDOMServer.renderToString(
<IconMarker type={marker.type} />
),
iconSize: [52, 52],
iconAnchor: [26, 52],
popupAnchor: [0, -46],
})}
position={marker.position}
>
<Popup>{marker.popupContent}</Popup>
</Marker>
<MapMarker key={index} marker={marker} index={index} />
))}

{children}
</MapContainer>
);
}

export type { TLazyMapProps, TMarker };
export type { TLazyMapProps };
export default LazyMap;
39 changes: 39 additions & 0 deletions src/components/map/map-marker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Marker, Popup } from "react-leaflet";
import L from "leaflet";
import IconMarker from "../ui/icons/marker";
import { ReactNode } from "react";
import { useClientRenderToString } from "@/hooks/useClientRenderToString";

type TMapMarkerProps = {
marker: TMarker;
index: number;
};

type TMarker = {
type: "parking" | "wall";
position: [number, number];
popupContent?: ReactNode;
};

function MapMarker({ marker, index }: TMapMarkerProps) {
const [icon] = useClientRenderToString(<IconMarker type={marker.type} />);

return (
<Marker
key={index}
icon={L.divIcon({
className: "",
html: icon,
iconSize: [52, 52],
iconAnchor: [26, 52],
popupAnchor: [0, -46],
})}
position={marker.position}
>
<Popup>{marker.popupContent}</Popup>
</Marker>
);
}

export type { TMarker };
export default MapMarker;
2 changes: 1 addition & 1 deletion src/components/map/map.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
@apply bg-white shadow-lg;
@apply bg-white shadow-lg;
}

.leaflet-popup-content-wrapper {
Expand Down
41 changes: 41 additions & 0 deletions src/hooks/useClientRenderToString.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useEffect, useState } from "react";
import { createRoot } from "react-dom/client";

type TUseClientRenderToString = (
input: React.ReactElement | React.ReactElement[],
deps?: any[]
) => string[];

const clientRenderToString = (element: React.ReactElement): Promise<string> =>
new Promise((resolve) => {
const container = document.createElement("div");
const renderCallback = () => {
resolve(container.firstElementChild?.innerHTML || "");
};

createRoot(container).render(<div ref={renderCallback}>{element}</div>);
});

export const useClientRenderToString: TUseClientRenderToString = (
input,
deps = []
) => {
const [htmlStringList, setHtmlStringList] = useState<string[]>([]);
const elementList = Array.isArray(input) ? input : [input];

useEffect(() => {
(async () => {
const markupPromises = elementList.map(clientRenderToString);
const markup: string[] = await Promise.all(markupPromises);

if (!setHtmlStringList) {
return;
}

setHtmlStringList(markup);
})();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, deps);

return htmlStringList;
};

0 comments on commit b1d6ebc

Please sign in to comment.