An interactive SVG map of Turkey for React applications. Ships all 81 provinces, supports single and multiple selection, and is keyboard accessible by default.
81 built-in provinces · Selection · Zoom & pan · Accessible navigation · Custom tooltips · Choropleth color scales · CSS-variable theming · React 16.8–19
Live demo · npm package · Changelog · Issues
npm install turkey-map-reactor with Yarn:
yarn add turkey-map-reactReact and React DOM >=16.8 are peer dependencies. React is not bundled; your application's copy is used at runtime. TypeScript definitions are included.
import TurkeyMap from 'turkey-map-react';
export default function App() {
return <TurkeyMap />;
}The root entry includes the built-in 81-province dataset. See Getting started for events, custom data, and all entry points.
The built-in dataset carries optional region, centroid, neighbors, areaKm2, population, isoCode, nutsCode, and altNames fields, plus a consumer-owned meta record. The component, core entry, and hook are generic over a city subtype, so typed metadata flows through data and callbacks:
type SalesCity = Omit<CityType, "meta"> & { meta: { sales: number } };
<TurkeyMap<SalesCity> data={salesData} onHover={(city) => city.meta.sales} />See custom data for field meanings, units, centroid coordinates, and data sources.
Convert GeoJSON polygons into the data shape without hand-writing SVG paths:
import TurkeyMap from 'turkey-map-react';
import { geoJsonToCities } from 'turkey-map-react/geojson';
const cities = geoJsonToCities(provinceGeoJson, {
idKey: 'ADM1_CODE',
nameKey: 'NAME_1',
plateKey: 'PLATE',
});
<TurkeyMap data={{ cities }} />;Polygon and MultiPolygon are supported, including holes. The helper projects longitude/latitude into the map's viewBox and accepts a custom project hook. It lives in a separate entry point and is not part of the default bundle. See GeoJSON conversion for options and limitations.
Color provinces by any metric with values, keyed by city id:
const values = { istanbul: 92, ankara: 45, izmir: 61 };
<TurkeyMap
values={values}
colorScale={['#f7fbff', '#08306b']}
scaleType="linear"
noDataColor="#eeeeee"
/>;Linear, quantize, quantile, and threshold scales are built in, with getColor as an escape hatch. Provinces without a value use noDataColor, hover and selection keep the metric fill, and renderTooltip receives the current value. See Choropleth values and color scales for the data contract and examples.
Zoom and pan are opt-in. Wheel, pinch, double-click, and drag work out of the box, with accessible controls and a typed ref for programmatic focus:
const ref = useRef(null);
<TurkeyMap zoomable minZoom={1} maxZoom={8} zoomControls ref={ref} />;
ref.current?.focusCity('istanbul');
ref.current?.zoomTo(2);
ref.current?.resetView();The viewport can be controlled with viewport and onViewportChange. See Zoom and pan for gestures, keyboard shortcuts, bounds, and the full ref API.
Use useTurkeyMap when you want the interaction engine without the component's markup. The hook renders nothing, requires data, and returns selection state, handlers, ARIA props, roving focus, announcements, and tooltip state:
import { useTurkeyMap } from 'turkey-map-react';
import { cities } from 'turkey-map-react/data';
function HeadlessMap() {
const {
getContainerProps,
getCityProps,
getTooltipProps,
selectedCities,
tooltipCity,
announcement,
} = useTurkeyMap({
data: { cities },
selectionMode: 'multiple',
showTooltip: true,
});
return (
<div>
<svg {...getContainerProps()}>
{cities.map((city) => (
<path
key={city.id}
d={city.path}
{...getCityProps(city)}
style={{
fill: selectedCities.some((item) => item.id === city.id) ? '#dc3522' : '#444',
cursor: 'pointer',
}}
/>
))}
</svg>
{tooltipCity && <div {...getTooltipProps()}>{tooltipCity.name}</div>}
<div role="status" aria-live="polite" aria-atomic="true" style={{ position: 'absolute', width: 1, height: 1, overflow: 'hidden' }}>
{announcement}
</div>
</div>
);
}The hook is exported from both turkey-map-react and turkey-map-react/core, supports custom city metadata generics, and works with SVG or non-SVG renderers. See Headless hook for recipes, generics, tooltips, the live region, a native-select fallback, memoization, and SSR.
| Entry point | What it provides | Use it when |
|---|---|---|
turkey-map-react |
The default TurkeyMap component plus the built-in 81-province dataset. |
You want the one-line <TurkeyMap /> map. |
turkey-map-react/core |
The same component without the built-in dataset. data is required. |
You supply your own data and want the dataset out of your bundle. |
turkey-map-react/data |
The built-in dataset as a named cities export. |
You want to read, filter, or extend the built-in provinces yourself. |
turkey-map-react/geojson |
geoJsonToCities, which converts GeoJSON polygons into CityType[] for data. |
You have GeoJSON and do not want to hand-write SVG paths. |
The root and core entries also export the named useTurkeyMap hook. The hook never imports the built-in dataset and requires data, so turkey-map-react/core is the smallest choice for a headless map with custom data. The root entry is roughly 96 kB gzipped, core is roughly 11 kB gzipped before your data, data is roughly 81 kB gzipped, and the optional geojson helper is roughly 3 kB gzipped. See entry points and bundle size for examples and guidance.
Detailed guides live in docs/.
| Guide | What it covers |
|---|---|
| Getting started | Installation, requirements, quick start, events, entry points, and bundle size. |
| Headless hook | useTurkeyMap state, prop getters, custom metadata, non-SVG renderers, tooltips, and SSR. |
| Selection and forms | Single and multiple selection, controlled and uncontrolled values, limits, and form integration. |
| Custom data and cities | Custom datasets, disabled provinces, and city wrapping. |
| GeoJSON conversion | geoJsonToCities, key mapping, custom projections, viewBox fitting, holes, and limitations. |
| Choropleth values | Numeric values, linear/quantize/quantile/threshold scales, no-data styling, and transitions. |
| Zoom and pan | Opt-in gestures, controlled and uncontrolled viewports, keyboard shortcuts, controls, and the ref API. |
| Tooltips | Custom content, positioning, portals, delays, keyboard focus, and reduced motion. |
| Accessibility | Keyboard navigation, ARIA semantics, live regions, and the native select fallback. |
| Styling and DOM ids | CSS custom properties, customStyle, getCityStyle, container props, and instance ids. |
| API reference | Every prop and exported TypeScript type. |
| Versioning and releases | Versioning scheme and the automated release process. |
Pull requests are welcome. See CONTRIBUTING.md for the full workflow, and use Conventional Commits for commit messages.
Released under the MIT License.
Derived from dnomak's svg-turkiye-haritasi project.