# React Image Section Mapper

A TypeScript React component for creating interactive, resizable, and draggable sections on images. Perfect for creating image maps, hotspots, or annotated areas on images.

![npm](https://img.shields.io/npm/v/react-image-section-mapper)
![license](https://img.shields.io/npm/l/react-image-section-mapper)
![typescript](https://img.shields.io/badge/TypeScript-Ready-blue)

## Features

- 🎯 Create clickable sections on images
- 🖱️ Drag & resize sections with handles
- 📱 Responsive design
- 🎨 Customizable themes
- 💾 Save & load section data
- ⌨️ TypeScript support
- 🔒 Read-only mode
- 🎛️ Minimum size constraints
- 🔢 Maximum sections limit
- 🪝 Event hooks for clicks and hovers

# Demo & Examples

Live Demo: [https://react-image-section-mapper-demo.vercel.app/](https://react-image-section-mapper-demo.vercel.app/)

Demo Repo: [https://github.com/mdtanvirahamedshanto/react-image-section-mapper-demo](https://github.com/mdtanvirahamedshanto/react-image-section-mapper-demo)

## Installation

```bash
npm install react-image-section-mapper
# or
yarn add react-image-section-mapper
# or
pnpm add react-image-section-mapper
```

## Basic Usage

```tsx
import { ImageSectionMapper } from 'react-image-section-mapper';

function App() {
  const handleSave = (sections) => {
    console.log('Sections:', sections);
    // Save sections to your backend
  };

  return (
    <ImageSectionMapper
      imageUrl="/path/to/your/image.jpg"
      onSave={handleSave}
    />
  );
}
```

## Advanced Usage

```tsx
import { ImageSectionMapper, Section } from 'react-image-section-mapper';

function AdvancedExample() {
  // Initial sections data
  const initialSections: Section[] = [
    {
      id: '1',
      x: 100,
      y: 100,
      width: 200,
      height: 150,
      title: 'Custom Section',
      link: '/custom-link'
    }
  ];

  // Handlers
  const handleSave = async (sections: Section[]) => {
    try {
      await saveToBackend(sections);
    } catch (error) {
      console.error('Failed to save sections:', error);
    }
  };

  const handleSectionClick = (section: Section) => {
    console.log('Clicked section:', section);
  };

  const handleSectionHover = (section: Section | null) => {
    if (section) {
      console.log('Hovering section:', section);
    }
  };

  return (
    <ImageSectionMapper
      imageUrl="/path/to/your/image.jpg"
      initialSections={initialSections}
      onSave={handleSave}
      onSectionClick={handleSectionClick}
      onSectionHover={handleSectionHover}
      sectionTitlePrefix="Area"
      minSectionSize={50}
      maxSections={10}
      theme={{
        primary: 'blue',
        secondary: 'gray',
        danger: 'red',
        success: 'green'
      }}
      readOnly={false}
      controls={true}
      className="custom-mapper"
    />
  );
}
```

## Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `imageUrl` | `string` | Required | URL of the image to map sections on |
| `onSave` | `(sections: Section[]) => void \| Promise<void>` | - | Callback when sections are saved |
| `initialSections` | `Section[]` | `[]` | Initial sections to display |
| `sectionTitlePrefix` | `string` | `'Section'` | Prefix for auto-generated section titles |
| `className` | `string` | `''` | Additional CSS classes |
| `controls` | `boolean` | `true` | Show/hide control buttons |
| `theme` | `Theme` | `defaultTheme` | Custom theme colors |
| `minSectionSize` | `number` | `20` | Minimum width/height of sections |
| `maxSections` | `number` | - | Maximum number of sections allowed |
| `readOnly` | `boolean` | `false` | Disable editing capabilities |
| `onSectionClick` | `(section: Section) => void` | - | Callback when a section is clicked |
| `onSectionHover` | `(section: Section \| null) => void` | - | Callback when a section is hovered |

## Types

### Section

```typescript
interface Section {
  id?: string;
  x: number;
  y: number;
  width: number;
  height: number;
  title: string;
  link?: string;
}
```

### Theme

```typescript
interface Theme {
  primary: string;
  secondary: string;
  danger: string;
  success: string;
}
```

## Styling

The component uses Tailwind CSS classes by default. You can customize the appearance by:

1. Using the `theme` prop to change colors
2. Providing custom classes via the `className` prop
3. Overriding the default styles in your CSS

```css
/* Example custom styles */
.custom-mapper .section-title {
  font-weight: bold;
}

.custom-mapper .resize-handle:hover {
  background-color: #4a90e2;
}
```

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
4. Push to the branch (`git push origin feature/AmazingFeature`)
5. Open a Pull Request

## Development

```bash
# Install dependencies
npm install

# Run type checking
npm run type-check

# Build the package
npm run build

# Run tests
npm test
```

## License

MIT © [Md Tanvir Ahamed Shanto](https://mdtanvirahamedshanto.vercel.app/)

## Support

If you have any questions or need help, please:

1. Check the [issues](https://github.com/mdtanvirahamedshanto/react-image-section-mapper/issues) for existing problems and solutions
2. Create a new issue if your problem isn't already reported
3. Contact the maintainers

---

Made with ❤️ by Md Tanvir Ahamed Shanto