First off, thank you for considering contributing to react-iran-maps! π This project aims to make creating interactive maps of Iran simple and powerful for React developers. Your contributions help make this library better for everyone.
- Code of Conduct
- How Can I Contribute?
- Getting Started
- Development Workflow
- Project Structure
- Making Changes
- Testing Your Changes
- Submitting a Pull Request
- Coding Standards
- Commit Message Guidelines
- Community and Support
This project and everyone participating in it is governed by our Code of Conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to rezasohrab20@gmail.com.
There are many ways you can contribute to react-iran-maps:
Before creating bug reports, please check existing issues to avoid duplicates. When creating a bug report, include:
- Clear title and description
- Steps to reproduce the behavior
- Expected behavior vs actual behavior
- Screenshots if applicable
- Environment details (React version, browser, OS)
- Code samples demonstrating the issue
Enhancement suggestions are tracked as GitHub issues. When creating an enhancement suggestion, include:
- Clear title and description
- Use case - why would this be useful?
- Proposed solution if you have one in mind
- Alternative solutions you've considered
- Examples from other libraries if applicable
Documentation improvements are always welcome! This includes:
- Fixing typos or unclear explanations
- Adding more examples
- Improving API documentation
- Creating tutorials or guides
- Translating documentation
We welcome code contributions! This includes:
- Fixing bugs
- Implementing new features
- Improving performance
- Adding tests
- Refactoring code
Before you begin, ensure you have the following installed:
- Node.js >= 20
- pnpm >= 9.0.0 (required - we enforce this with
only-allow)
-
Fork the repository on GitHub
-
Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/react-iran-maps.git cd react-iran-maps -
Add the upstream repository:
git remote add upstream https://github.com/rezasohrabi/react-iran-maps.git
-
Install dependencies:
pnpm install
-
Build the project:
pnpm build
Note: This project uses Turborepo for monorepo management. All commands should be run from the project root - Turbo will automatically handle running tasks in the appropriate packages with intelligent caching and parallelization.
From the project root, you can run:
# Build all packages
pnpm build
# Start development mode with watch
pnpm dev
# Run linting across all packages
pnpm lint
# Type check all packages
pnpm check-types
# Format code with Prettier
pnpm formatThe main library code is in packages/react-iran-maps/. Since this is a Turborepo, all commands should be run from the project root - Turbo will handle running them in the appropriate packages:
# Watch mode - rebuilds on changes across all packages
pnpm dev
# Build production bundle for all packages
pnpm build
# Run linting across all packages
pnpm lint
# Type checking across all packages
pnpm check-typesTurbo intelligently runs tasks only in packages that need them and caches results for faster builds.
The apps/dev directory contains a Next.js app for testing your changes:
-
Start the dev app (from project root):
pnpm dev
Turbo will run the dev server for both the library (in watch mode) and the Next.js app simultaneously.
-
Open http://localhost:3000 in your browser
-
Test your changes using the sample pages or create new test pages
The dev app automatically links to the local react-iran-maps package, so your changes will be reflected immediately thanks to Turbo's watch mode.
Sample implementations are in apps/dev/app/samples/. These serve as both examples and test cases:
- Each sample demonstrates a specific feature or use case
- Follow the existing pattern when adding new samples
- Update
samples/index.tsto export new samples - Keep samples simple and focused on one concept
react-iran-maps/
βββ apps/
β βββ dev/ # Next.js development/testing app
β β βββ app/
β β β βββ samples/ # Example implementations
β β β βββ ...
β β βββ ...
β βββ docs/ # Docusaurus documentation site
β βββ ...
βββ packages/
β βββ react-iran-maps/ # Main library package
β β βββ src/
β β β βββ assets/ # TopoJSON data files
β β β βββ components/
β β β β βββ Breadcrumbs.tsx
β β β β βββ ChoroplethMap.tsx
β β β β βββ Legend.tsx
β β β β βββ Tooltip.tsx
β β β βββ data/ # Data processing utilities
β β β βββ hooks/ # Custom React hooks
β β β βββ lib/ # Utility functions
β β β βββ types/ # TypeScript type definitions
β β β βββ index.tsx # Main entry point
β β βββ dist/ # Built files (generated)
β β βββ package.json
β βββ eslint-config/ # Shared ESLint configurations
β βββ typescript-config/ # Shared TypeScript configurations
βββ CODE_OF_CONDUCT.md
βββ CONTRIBUTING.md
βββ LICENSE
βββ README.md
βββ package.json
βββ pnpm-workspace.yaml
βββ turbo.json
packages/react-iran-maps/src/components/ChoroplethMap.tsx- Main map componentpackages/react-iran-maps/src/assets/counties.json- TopoJSON data for Iranpackages/react-iran-maps/src/hooks/- Custom hooks for map functionalitypackages/react-iran-maps/src/types/- TypeScript type definitionsapps/dev/app/samples/- Example implementations and test cases
Always create a new branch for your work:
# Update your local main branch
git checkout main
git pull upstream main
# Create a new feature branch
git checkout -b feature/amazing-feature
# Or for bug fixes
git checkout -b fix/bug-descriptionUse descriptive branch names with one of these prefixes:
feature/- New features or enhancementsfix/- Bug fixesdocs/- Documentation changesrefactor/- Code refactoringtest/- Adding or updating testschore/- Maintenance tasks
Examples:
feature/custom-markersfix/tooltip-positioningdocs/improve-api-reference
- Make your changes in your feature branch
- Follow the coding standards (see below)
- Add or update tests if applicable
- Update documentation if you're changing functionality
- Test thoroughly in the dev app
Regularly sync your branch with upstream:
git fetch upstream
git rebase upstream/main-
Start the dev app:
pnpm dev
-
Test your changes in various scenarios:
- Different data types (quantitative, qualitative)
- Different screen sizes (responsive behavior)
- Interactive features (drill-down, hover, click)
- Edge cases (empty data, missing values, etc.)
-
Create a new sample in
apps/dev/app/samples/to demonstrate your feature
Ensure there are no TypeScript errors:
pnpm check-typesRun ESLint to check code quality:
pnpm lintFix linting issues automatically when possible:
# Turbo will run lint --fix across all packages
pnpm lint -- --fixEnsure the package builds successfully:
pnpm build- β Your code follows the project's coding standards
- β You've tested your changes thoroughly
- β
All TypeScript types are correct (
pnpm check-typespasses) - β
Linting passes (
pnpm lintpasses) - β
The package builds successfully (
pnpm buildpasses) - β You've updated documentation if needed
- β You've added samples/examples for new features
- β Your commits follow the commit message guidelines
-
Push your branch to your fork:
git push origin feature/amazing-feature
-
Create a Pull Request on GitHub:
- Go to your fork on GitHub
- Click "Pull Request" button
- Select your feature branch
- Fill out the PR template
-
PR Title: Use a clear, descriptive title
- Good: "Add custom marker support with icon rendering"
- Bad: "Update map"
-
PR Description: Include:
- What - What changes you made
- Why - Why these changes are needed
- How - How you implemented the changes
- Testing - How you tested the changes
- Screenshots - For visual changes
- Related Issues - Reference any related issues (#123)
- Respond to feedback - Maintainers may request changes
- Keep your PR updated - Rebase if main branch has changed
- Be patient - Reviews may take time
- Be respectful - Follow the Code of Conduct
- Automated checks run (linting, type checking, build)
- Maintainers review your code
- Feedback may be provided with requested changes
- Updates are made based on feedback
- Approval and merge once everything looks good
- Use TypeScript for all new code
- Define types explicitly - avoid
any - Export types that are part of the public API
- Use interfaces for object shapes
- Use type for unions, intersections, and primitives
Example:
// Good
interface MapProps {
drilldown?: boolean;
data?: ProvinceData[];
}
// Avoid
const handleClick = (data: any) => { ... }- Use functional components with hooks
- Extract custom hooks for reusable logic
- Use TypeScript for props and state
- Avoid inline styles - use CSS/Tailwind when possible
- Memoize expensive calculations with useMemo
- Use proper dependencies in useEffect/useMemo/useCallback
Example:
// Good
interface TooltipProps {
content: string;
visible: boolean;
}
export const Tooltip: React.FC<TooltipProps> = ({ content, visible }) => {
return visible ? <div>{content}</div> : null;
};- Use ESLint - Follow the project's ESLint configuration
- Use Prettier - Run
pnpm formatto format code - Meaningful names - Use descriptive variable and function names
- Keep functions small - Each function should do one thing well
- Comment complex logic - Explain "why", not "what"
- Remove console.logs - Don't commit debugging code
- One component per file (with related types)
- Co-locate related files (hooks, types, utils)
- Export from index.tsx - Main entry point exports public API
- Use barrel exports - Re-export from index files
We follow a structured commit message format to maintain a clear history.
<type>(<scope>): <subject>
<body>
<footer>
Use one of these types:
- feat: New feature
- fix: Bug fix
- docs: Documentation changes
- style: Code style changes (formatting, no functional change)
- refactor: Code refactoring (no functional change)
- perf: Performance improvements
- test: Adding or updating tests
- chore: Maintenance tasks, dependencies, build config
The scope should specify the area of the change:
- map: Main map component
- legend: Legend component
- tooltip: Tooltip component
- hooks: Custom hooks
- types: Type definitions
- data: Data processing
- docs: Documentation
- dev: Dev app changes
- Use imperative mood: "add" not "added" or "adds"
- Don't capitalize first letter
- No period at the end
- Maximum 50 characters
- Explain what and why, not how
- Wrap at 72 characters
- Separate from subject with a blank line
- Reference issues: "Closes #123" or "Fixes #456"
- Note breaking changes: "BREAKING CHANGE: description"
feat(map): add custom marker support
Add ability to place custom markers on the map with icons and labels.
Markers can be positioned using lat/long coordinates.
Closes #123
fix(tooltip): correct positioning on mobile devices
The tooltip was appearing off-screen on small viewports.
Now calculates available space and adjusts position accordingly.
docs(readme): update installation instructions
Add pnpm installation command and update Node.js version requirement.
refactor(hooks): extract province geometry logic
Move geometry generation logic into separate hook for better reusability.
No functional changes.
- GitHub Issues - Ask questions or report problems
- Discussions - Join conversations about features and ideas
- Email - Contact maintainers at rezasohrab20@gmail.com
- Watch the repository to get notifications
- Star the project to show your support
- Follow releases to stay informed about new versions
All contributors will be recognized in:
- The project's README (Contributors section)
- Release notes (when your PR is included)
- npm package (as a contributor)
Your contributions make react-iran-maps better for everyone. We appreciate your time and effort in helping improve this project. Happy coding! π
Questions? Feel free to open an issue or reach out to the maintainers.