@zionmezba/bd-map
v1.0.7
Published
A fully customizable React SVG map component of Bangladesh's administrative divisions and districts
Downloads
396
Maintainers
Readme
@zionmezba/bd-map
A fully customizable React SVG map library for Bangladesh — supports both division-level (8 divisions) and district-level (63 districts) interactive maps.
- Zero dependencies (React is a peer dep)
- Ships ESM + CJS
- Full per-region color, hover, selected, stroke, tooltip, and label customization
- Keyboard accessible
- TypeScript-friendly JSDoc types
Installation
npm install @zionmezba/bd-map
# or
yarn add @zionmezba/bd-mapPeer dependencies: React 17+
Import the CSS once in your app entry point:
import '@zionmezba/bd-map/dist/style.css';Quick Start
Division Map
import { BangladeshMap } from '@zionmezba/bd-map';
import '@zionmezba/bd-map/dist/style.css';
export default function App() {
return (
<BangladeshMap
width={600}
height={600}
onDivisionClick={(id, data) => console.log(id, data.name)}
/>
);
}District Map
import { BangladeshDistrictMap } from '@zionmezba/bd-map';
import '@zionmezba/bd-map/dist/style.css';
export default function App() {
return (
<BangladeshDistrictMap
width={600}
height={600}
onDistrictClick={(id, data) => console.log(id, data.name, data.divisionId)}
/>
);
}<BangladeshMap> — Division Map
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| width | number | 500 | SVG width in px |
| height | number | 500 | SVG height in px |
| defaultFill | string | '#6f9c76' | Default division fill color |
| defaultHoverFill | string | '#4a7a52' | Fill on mouse hover |
| defaultSelectedFill | string | '#2e5f38' | Fill when selected |
| defaultStroke | string | '#ffffff' | Border stroke color |
| defaultStrokeWidth | number | 0.5 | Border stroke width |
| showLabels | boolean | true | Show division name labels |
| labelStyle | object | {} | CSS properties for label text |
| showTooltip | boolean | true | Show tooltip on hover |
| tooltipStyle | object | {} | CSS properties for tooltip container |
| renderTooltip | (data) => ReactNode | — | Custom tooltip renderer |
| divisions | object | {} | Per-division config (see below) |
| selectedDivision | string | — | Controlled selected division ID |
| onDivisionClick | (id, data, event) => void | — | Click handler |
| onDivisionHover | (id, data, event) => void | — | Mouse enter handler |
| onDivisionLeave | (id, data, event) => void | — | Mouse leave handler |
| className | string | — | Class for the root SVG element |
| style | object | — | Inline styles for the root SVG element |
Per-division config (divisions prop)
Pass an object keyed by division ID to customize individual divisions:
<BangladeshMap
divisions={{
BDA: { fill: '#e88c3b', hoverFill: '#c47030', label: 'Barishal' },
BDB: { fill: '#5b8db8', disabled: true },
BDC: { fill: '#c45b5b', stroke: '#fff', strokeWidth: 1 },
}}
/>| Key | Type | Description |
|---|---|---|
| fill | string | Fill color |
| hoverFill | string | Hover fill |
| selectedFill | string | Selected fill |
| stroke | string | Border color |
| strokeWidth | number | Border width |
| label | string | Override label text |
| className | string | Extra CSS class |
| style | object | Inline styles |
| disabled | boolean | Disable interactions (dimmed, no events) |
Division IDs
| ID | Division |
|---|---|
| BDA | Barisal |
| BDB | Chittagong |
| BDC | Dhaka |
| BDD | Khulna |
| BDH | Mymensingh |
| BDE | Rajshahi |
| BDF | Rangpur |
| BDG | Sylhet |
<BangladeshDistrictMap> — District Map
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| width | number | 500 | SVG width in px |
| height | number | 500 | SVG height in px |
| defaultFill | string | '#a8cfa0' | Default district fill |
| defaultHoverFill | string | '#5a8c63' | Hover fill |
| defaultSelectedFill | string | '#2e5f38' | Selected fill |
| defaultStroke | string | '#231F20' | Border color |
| defaultStrokeWidth | number | 0.3 | Border width |
| showLabels | boolean | false | Show district name labels (dense; off by default) |
| labelStyle | object | {} | CSS properties for label text |
| showTooltip | boolean | true | Show tooltip on hover |
| tooltipStyle | object | {} | Tooltip container styles |
| renderTooltip | (data) => ReactNode | — | Custom tooltip renderer |
| districts | object | {} | Per-district config (see below) |
| highlightDivision | string[] | — | Division IDs to highlight; districts outside are dimmed |
| selectedDistrict | string | — | Controlled selected district ID |
| onDistrictClick | (id, data, event) => void | — | Click handler |
| onDistrictHover | (id, data, event) => void | — | Mouse enter handler |
| onDistrictLeave | (id, data, event) => void | — | Mouse leave handler |
| className | string | — | Class for the root SVG element |
| style | object | — | Inline styles for the root SVG element |
Per-district config (districts prop)
Same keys as per-division config, keyed by district ID:
<BangladeshDistrictMap
districts={{
dhaka: { fill: '#c45b5b', hoverFill: '#a03030' },
chittagong: { fill: '#5b8db8' },
sylhet: { disabled: true },
}}
/>Highlighting a division
Use highlightDivision to dim districts outside a set of divisions. Useful for drill-down UX:
const [active, setActive] = useState(null);
<BangladeshMap onDivisionClick={(id) => setActive(id)} />
<BangladeshDistrictMap highlightDivision={active ? [active] : undefined} />District IDs (63 districts)
Districts are identified by lowercase URL-style keys:
| Division | District IDs |
|---|---|
| Barisal (BDA) | barisal bhola borguna jhalokathi patuakhali pirojpur |
| Chittagong (BDB) | bandarban brahmonbaria chandpur chittagong comilla feni khagrachari lakshmipur noakhali rangamati |
| Dhaka (BDC) | dhaka faridpur gazipur gopalgonj kishoregonj madaripur manikgonj munsigonj narayangonj norsinghdi rajbari shariatpur tangail |
| Khulna (BDD) | bagerhat chuadanga jessore jhenaidah khulna kushtia magura meherpur narail satkhira |
| Mymensingh (BDH) | jamalpur mymensingh netrokona sherpur |
| Rajshahi (BDE) | bogra chapainawabganj jaipurhat naogaon natore pabna rajshahi sirajganj |
| Rangpur (BDF) | dinajpur gaibandha kurigram lalmonirhat nilphamari panchagarh rangpur thakurgaong |
| Sylhet (BDG) | habiganj maulavibazar sunamganj sylhet |
Data Exports
All metadata is exported and can be used independently:
import {
DIVISIONS, DIVISION_IDS, DIVISION_LIST,
DISTRICTS, DISTRICT_IDS, DISTRICT_LIST,
getDistrictsByDivision,
} from '@zionmezba/bd-map';| Export | Type | Description |
|---|---|---|
| DIVISIONS | object | Map of division ID → { id, name, labelX, labelY } |
| DIVISION_IDS | string[] | All 8 division IDs |
| DIVISION_LIST | object[] | Array of division metadata objects |
| DISTRICTS | object | Map of district ID → { id, name, divisionId } |
| DISTRICT_IDS | string[] | All 63 district IDs |
| DISTRICT_LIST | object[] | Array of district metadata objects |
| getDistrictsByDivision(divisionId) | function | Returns district list for a given division |
import { getDistrictsByDivision } from '@zionmezba/bd-map';
const dhakaDistricts = getDistrictsByDivision('BDC');
// [{ id: 'dhaka', name: 'Dhaka', divisionId: 'BDC' }, ...]Styling
The library ships minimal base CSS. Import it once:
import '@zionmezba/bd-map/dist/style.css';You can override the CSS classes for deeper customization:
| Class | Applied to |
|---|---|
| .bdmap-wrapper | Root wrapper div |
| .bdmap-svg | SVG element |
| .bdmap-division | Each division or district <g> element |
| .bdmap-division--disabled | Disabled division/district (opacity 0.6) |
| .bdmap-label | Division name label text |
| .bdmap-tooltip | Tooltip container div |
Development
# Start demo app (http://localhost:5173)
npm run dev
# Build the library (outputs to dist/)
npm run build
# Build the demo app
npm run build:demo
# Re-extract SVG paths from source files (if SVGs change)
npm run extract-paths # divisions only
npm run extract-districts # districts only
npm run extract-all # bothExample: Division / District Toggle (Next.js / TypeScript)
A common real-world pattern — a toggle that switches between the division and district map, with controlled selection state.
'use client';
import { useState } from 'react';
import { BangladeshMap, BangladeshDistrictMap } from '@zionmezba/bd-map';
import '@zionmezba/bd-map/dist/react-bdmap.css';
type MapMode = 'division' | 'district';
export default function MapViewPanel() {
const [mode, setMode] = useState<MapMode>('division');
const [selectedDivision, setSelectedDivision] = useState<string | undefined>(undefined);
const [selectedDistrict, setSelectedDistrict] = useState<string | undefined>(undefined);
return (
<div className="relative w-full h-full flex items-center justify-center">
{/* Mode toggle */}
<div className="absolute top-3 right-3 z-10 flex rounded-lg overflow-hidden border border-gray-200 shadow-sm text-sm font-medium">
<button
onClick={() => setMode('division')}
className={`px-3 py-1.5 transition-colors ${
mode === 'division'
? 'bg-green-700 text-white'
: 'bg-white text-gray-600 hover:bg-gray-50'
}`}
>
Division
</button>
<button
onClick={() => setMode('district')}
className={`px-3 py-1.5 transition-colors border-l border-gray-200 ${
mode === 'district'
? 'bg-green-700 text-white'
: 'bg-white text-gray-600 hover:bg-gray-50'
}`}
>
District
</button>
</div>
{/* Map */}
{mode === 'division' ? (
<BangladeshMap
width={600}
height={600}
selectedDivision={selectedDivision}
showLabels
showTooltip
onDivisionClick={(id, data) => {
setSelectedDivision(id);
console.log('Division:', id, data.name);
}}
/>
) : (
<BangladeshDistrictMap
width={600}
height={600}
selectedDistrict={selectedDistrict}
showTooltip
onDistrictClick={(id, data) => {
setSelectedDistrict(id);
console.log('District:', id, data.name, data.divisionId);
}}
/>
)}
</div>
);
}Note: If you're using Next.js with the App Router, add
'use client'at the top since the maps use React state and browser events.
Drill-down: click a division to see its districts
import { useState } from 'react';
import { BangladeshMap, BangladeshDistrictMap } from '@zionmezba/bd-map';
import '@zionmezba/bd-map/dist/style.css';
export default function DrillDownMap() {
const [activeDivision, setActiveDivision] = useState<string | null>(null);
return (
<div style={{ display: 'flex', gap: 24 }}>
<BangladeshMap
width={400}
height={400}
selectedDivision={activeDivision ?? undefined}
onDivisionClick={(id) => setActiveDivision(id)}
/>
<BangladeshDistrictMap
width={400}
height={400}
highlightDivision={activeDivision ? [activeDivision] : undefined}
/>
</div>
);
}