UNPKG

uzb-d3-map

Version:

A flexible, customizable SVG map component for Uzbekistan built with D3 and React

112 lines 3.98 kB
import { jsx as _jsx } from "react/jsx-runtime"; import * as d3 from "d3"; import React from "react"; import { DEFAULT_LEADER_COLOR, DEFAULT_ACTIVE_COLOR, DEFAULT_FILL_COLOR, DEFAULT_HOVER_COLOR, DEFAULT_STROKE_COLOR, VIEWBOX, } from "./constants"; import { getRegionName } from "./locales"; import regionPaths from "./region-paths.json"; import { drawMap } from "./utils/draw-map"; import "./map.css"; /** * MapSvgD3 - A flexible, customizable SVG map component built with D3 * * @example * ```tsx * <MapSvgD3 * locale="en" * style={{ * colors: { * default: "#b3c3ee", * hover: "#A0D57A", * active: "#325ECD" * }, * stroke: { * color: "#FFFFFF", * width: 2 * } * }} * labelRender={(data, node) => ( * <div> * <strong>{data.name}</strong> * {data.value && <div>{data.value}</div>} * </div> * )} * onRegionClick={(key, data) => console.log(key, data)} * /> * ``` */ const MapSvgD3 = ({ data: customData, width = "100%", height = "100%", viewBox = VIEWBOX, colors: customColors, stroke: customStroke, leaderColor = DEFAULT_LEADER_COLOR, locale = "uz-cyrl", onRegionClick, labelRender, labelConfig: customLabelConfig, showLabels = true, className, style, activeKey = null, svgProps, getPathStyle, }) => { const svgRef = React.useRef(null); const gRef = React.useRef(null); const colors = React.useMemo(() => ({ default: customColors?.default ?? DEFAULT_FILL_COLOR, hover: customColors?.hover ?? DEFAULT_HOVER_COLOR, active: customColors?.active ?? DEFAULT_ACTIVE_COLOR, }), [customColors]); const stroke = React.useMemo(() => ({ color: customStroke?.color ?? DEFAULT_STROKE_COLOR, width: customStroke?.width ?? 2, }), [customStroke]); const data = React.useMemo(() => { if (customData) { return customData.map((region) => ({ ...region, name: region.name || getRegionName(region.key, locale), })); } return Object.entries(regionPaths).map(([key, d]) => { const translatedName = getRegionName(key, locale); return { key, d: String(d), name: translatedName, }; }); }, [customData, locale]); const handleClick = React.useCallback((key) => { const regionData = data.find((d) => d.key === key); if (regionData) { onRegionClick?.(key, regionData); } }, [data, onRegionClick]); const shouldShowLabels = showLabels; React.useEffect(() => { if (!svgRef.current || !gRef.current) return; const cleanup = drawMap({ d3, svg: svgRef.current, rootG: gRef.current, data, activeKey, leaderColor, colors, stroke, onClick: handleClick, labelConfig: customLabelConfig, labelRender, showLabels: shouldShowLabels, getPathStyle, }); return cleanup; }, [ data, activeKey, leaderColor, colors, stroke, handleClick, customLabelConfig, labelRender, shouldShowLabels, getPathStyle, ]); const finalContainerStyle = { position: "relative", width: "100%", height: typeof height === "number" ? `${height}px` : height === "100%" ? "520px" : height, ...style, }; return (_jsx("div", { className: `map-container ${className || ""}`, style: finalContainerStyle, children: _jsx("svg", { ref: svgRef, viewBox: viewBox, width: width, height: height, xmlns: "http://www.w3.org/2000/svg", role: "img", preserveAspectRatio: "xMidYMid meet", className: "map-svg", ...svgProps, children: _jsx("g", { ref: gRef }) }) })); }; export default React.memo(MapSvgD3); //# sourceMappingURL=map.js.map