1.0.2 • Published 6 months ago

@rtkstack/mapper v1.0.2

Weekly downloads
-
License
MIT
Repository
github
Last release
6 months ago

RTK Mapping Component

A flexible React TypeScript component for creating mappings with searchable dropdowns, dynamic row management, and full mobile responsiveness.

✨ Features

  • 🔍 Searchable Dropdowns - Quick filtering of options with built-in search functionality
  • Dynamic Row Management - Add or remove mapping rows on the fly
  • 🚫 Duplicate Prevention - Automatically prevents duplicate mappings across rows
  • 📱 Mobile Responsive - Optimized layout for all screen sizes with touch-friendly controls
  • 🎨 Fully Customizable - Style with CSS-in-JS or CSS classes
  • 🏷️ TypeScript Support - Full type definitions included for better DX
  • Zero Dependencies - Only requires React as a peer dependency
  • 🔄 Two-way Data Binding - Initialize with data and get updates via onChange
  • 🎯 Flexible Constraints - Optional min/max row limits
  • 🏷️ Custom Labels - Configurable column headers

🎥 Demo

Live Demo

📦 Installation

# Using npm
npm install @rtkstack/mapper

🚀 Quick Start

import React, { useState } from 'react';
import { RTKMapper } from '@rtkstack/mapper';

function App() {
  const [mappings, setMappings] = useState<Record<string, string>>({});

  return (
    <div>
      <RTKMapper
        sourceOptions={['value A', 'value B', 'value C']}
        targetOptions={['value 1', 'value 2', 'value 3']}
        onChange={setMappings}
      />
      
      <pre>{JSON.stringify(mappings, null, 2)}</pre>
    </div>
  );
}

📖 API Reference

Props

PropTypeDefaultDescription
sourceOptionsstring[]['value A', 'value B', 'value C', 'value D', 'value E']Array of source value options
targetOptionsstring[]['value 1', 'value 2', 'value 3', 'value 4', 'value 5']Array of target value options
initialMappingsRecord<string, string>{}Initial mapping configuration
minRowsnumber \| undefinedundefinedMinimum number of mapping rows. If undefined, users can delete all rows
maxRowsnumber \| undefinedundefinedMaximum number of mapping rows. If undefined, unlimited rows allowed
sourceLabelstring'Source'Label for the source column header
targetLabelstring'Destination'Label for the target column header
onChange(mappings: Record<string, string>) => void-Callback fired when mappings change
stylesStylesConfig-Custom styles object for fine-grained styling
classNamesClassNamesConfig-Custom CSS class names for each component part

Style Objects

interface StylesConfig {
  container?: CSSProperties;
  header?: CSSProperties;
  headerText?: CSSProperties;
  mappingRow?: CSSProperties;
  dropdown?: CSSProperties;
  dropdownContainer?: CSSProperties;
  searchInput?: CSSProperties;
  optionsList?: CSSProperties;
  option?: CSSProperties;
  arrow?: CSSProperties;
  deleteButton?: CSSProperties;
  addButton?: CSSProperties;
  rowsContainer?: CSSProperties;
}

Class Names

interface ClassNamesConfig {
  container?: string;
  header?: string;
  headerText?: string;
  mappingRow?: string;
  dropdown?: string;
  dropdownContainer?: string;
  searchInput?: string;
  optionsList?: string;
  option?: string;
  arrow?: string;
  deleteButton?: string;
  addButton?: string;
  rowsContainer?: string;
}

💡 Examples

Basic Usage

<RTKMapper
  onChange={(mappings) => console.log('Mappings:', mappings)}
/>

With Initial Mappings

const initialMappings = {
  'value A': 'value 1',
  'value B': 'value 3'
};

<RTKMapper
  initialMappings={initialMappings}
  onChange={handleMappingChange}
/>

Custom Labels and Limits

<RTKMapper
  sourceOptions={['Input 1', 'Input 2', 'Input 3']}
  targetOptions={['Output A', 'Output B', 'Output C']}
  sourceLabel="Input Port"
  targetLabel="Output Port"
  minRows={2}
  maxRows={5}
  onChange={handleMappingChange}
/>

With Custom Styling

const customStyles = {
  container: {
    backgroundColor: '#f8f9fa',
    border: '2px solid #dee2e6',
    borderRadius: '12px',
  },
  deleteButton: {
    backgroundColor: '#dc3545',
  },
  addButton: {
    borderColor: '#28a745',
    color: '#28a745',
  },
  searchInput: {
    borderColor: '#0066cc',
  }
};

<RTKMapper
  styles={customStyles}
  onChange={handleMappingChange}
/>

With CSS Classes

<RTKMapper
  classNames={{
    container: 'my-custom-container',
    mappingRow: 'my-mapping-row',
    dropdown: 'my-dropdown-class'
  }}
  onChange={handleMappingChange}
/>

Unlimited Rows Example

// No min or max constraints - users have full control
<RTKMapper
  sourceOptions={['Src 1', 'Src 2', 'Src 3']}
  targetOptions={['Dest A', 'Dest B', 'Dest C']}
  onChange={handleMappingChange}
/>

🎨 Styling

The component provides multiple ways to customize its appearance:

1. CSS-in-JS Styles

Pass a styles object to customize individual components:

const styles = {
  container: {
    padding: '24px',
    backgroundColor: '#ffffff',
    boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
  },
  dropdown: {
    borderRadius: '8px',
    fontSize: '16px'
  },
  deleteButton: {
    backgroundColor: '#ff4757',
    '&:hover': {
      backgroundColor: '#ff3838'
    }
  }
};

<RTKMapper styles={styles} />

2. CSS Classes

Use your own CSS classes:

/* styles.css */
.custom-mapper-container {
  background: linear-gradient(to right, #667eea, #764ba2);
  padding: 2rem;
}

.custom-dropdown {
  border: 2px solid #4c51bf;
  transition: all 0.3s ease;
}

.custom-dropdown:focus {
  border-color: #667eea;
  box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
<RTKMapper
  classNames={{
    container: 'custom-mapper-container',
    dropdown: 'custom-dropdown'
  }}
/>

3. CSS Variables

The component uses CSS classes that you can target:

.rtk-mapper-container { }
.rtk-mapper-header { }
.rtk-mapper-row { }