1.0.2 • Published 6 months ago
@rtkstack/mapper v1.0.2
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
📦 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
| Prop | Type | Default | Description |
|---|---|---|---|
sourceOptions | string[] | ['value A', 'value B', 'value C', 'value D', 'value E'] | Array of source value options |
targetOptions | string[] | ['value 1', 'value 2', 'value 3', 'value 4', 'value 5'] | Array of target value options |
initialMappings | Record<string, string> | {} | Initial mapping configuration |
minRows | number \| undefined | undefined | Minimum number of mapping rows. If undefined, users can delete all rows |
maxRows | number \| undefined | undefined | Maximum number of mapping rows. If undefined, unlimited rows allowed |
sourceLabel | string | 'Source' | Label for the source column header |
targetLabel | string | 'Destination' | Label for the target column header |
onChange | (mappings: Record<string, string>) => void | - | Callback fired when mappings change |
styles | StylesConfig | - | Custom styles object for fine-grained styling |
classNames | ClassNamesConfig | - | 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 { }