react-native-debug-toolkit
Version:
A simple yet powerful debugging toolkit for React Native with a convenient floating UI for development
239 lines (224 loc) • 6.2 kB
JavaScript
import React, { useState, useEffect } from 'react';
import {
View,
Text,
StyleSheet,
FlatList,
TouchableOpacity,
TextInput,
Platform,
} from 'react-native';
const SubViewThirdPartyLibs = ({ libraries = [] }) => {
const [expandedLibs, setExpandedLibs] = useState(new Set());
const [actionParams, setActionParams] = useState({});
// Set all libraries to expanded by default and set default product ID
useEffect(() => {
// Create a set of all library IDs to set them as expanded
const allLibIds = new Set(libraries.map(lib => lib.id));
setExpandedLibs(allLibIds);
// Initialize default product ID for all actions that might need it
const defaultParams = {};
libraries.forEach(lib => {
lib.actions.forEach(action => {
if (action.hasParam) {
defaultParams[`${lib.id}_${action.id}`] = 'default';
}
});
});
setActionParams(defaultParams);
}, [libraries]);
// Handle lib expansion/collapse
const toggleLibExpand = (libId) => {
setExpandedLibs(prev => {
const newSet = new Set(prev);
if (newSet.has(libId)) {
newSet.delete(libId);
} else {
newSet.add(libId);
}
return newSet;
});
};
// Execute library action
const executeAction = (action, libId) => {
try {
if (action.hasParam) {
// Get parameter value (if needed)
const paramValue = actionParams[`${libId}_${action.id}`] || 'default';
action.method(paramValue);
} else {
action.method();
}
// No alerts shown as per requirement
} catch (error) {
// Silent error handling as per requirement
console.error(`Failed to execute ${action.label}:`, error);
}
};
// Handle param input change
const handleParamChange = (libId, actionId, value) => {
setActionParams({
...actionParams,
[`${libId}_${actionId}`]: value,
});
};
// Render a single library card
const renderLibraryItem = ({ item }) => {
const isExpanded = expandedLibs.has(item.id);
const isPlatformSupported = item.platform === 'both' ||
item.platform === Platform.OS;
if (!isPlatformSupported) return null;
return (
<View style={styles.libraryCard}>
<TouchableOpacity
style={styles.libraryHeader}
onPress={() => toggleLibExpand(item.id)}>
<View style={styles.libraryTitle}>
<Text style={styles.libraryName}>{item.name}</Text>
<Text style={styles.platformBadge}>
{item.platform === 'both' ? 'iOS & Android' : item.platform}
</Text>
</View>
<Text style={styles.expandIcon}>{isExpanded ? '▼' : '▶'}</Text>
</TouchableOpacity>
<Text style={styles.libraryDescription}>{item.description}</Text>
{isExpanded && (
<View style={styles.actionsContainer}>
{item.actions.map((action) => (
<View key={action.id} style={styles.actionItem}>
{action.hasParam && (
<TextInput
style={styles.paramInput}
placeholder={action.paramPlaceholder || 'Parameter'}
value={actionParams[`${item.id}_${action.id}`] || 'default'}
onChangeText={(text) =>
handleParamChange(item.id, action.id, text)
}
/>
)}
<TouchableOpacity
style={styles.actionButton}
onPress={() => executeAction(action, item.id)}>
<Text style={styles.actionButtonText}>{action.label}</Text>
</TouchableOpacity>
</View>
))}
</View>
)}
</View>
);
};
// Filter platform-supported libraries
const supportedLibraries = libraries.filter(
lib => lib.platform === 'both' || lib.platform === Platform.OS
);
return (
<View style={styles.container}>
{supportedLibraries.length === 0 ? (
<Text style={styles.emptyText}>
No debug libraries available for this platform
</Text>
) : (
<FlatList
data={supportedLibraries}
renderItem={renderLibraryItem}
keyExtractor={(item) => item.id}
contentContainerStyle={styles.listContent}
/>
)}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
listContent: {
padding: 12,
},
emptyText: {
textAlign: 'center',
color: '#999',
marginTop: 20,
fontSize: 16,
},
libraryCard: {
backgroundColor: '#f8f9fa',
borderRadius: 8,
borderWidth: 1,
borderColor: '#e9ecef',
marginBottom: 16,
padding: 12,
elevation: 1,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.1,
shadowRadius: 1,
},
libraryHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
libraryTitle: {
flexDirection: 'row',
alignItems: 'center',
flex: 1,
},
libraryName: {
fontSize: 18,
fontWeight: 'bold',
color: '#333',
marginRight: 8,
},
platformBadge: {
fontSize: 12,
color: '#666',
backgroundColor: '#e9ecef',
paddingHorizontal: 8,
paddingVertical: 2,
borderRadius: 12,
overflow: 'hidden',
},
expandIcon: {
fontSize: 14,
color: '#666',
},
libraryDescription: {
marginTop: 8,
marginBottom: 12,
color: '#666',
fontSize: 14,
lineHeight: 20,
},
actionsContainer: {
marginTop: 8,
borderTopWidth: 1,
borderTopColor: '#eee',
paddingTop: 12,
},
actionItem: {
marginBottom: 8,
},
paramInput: {
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 4,
padding: 8,
marginBottom: 8,
fontSize: 14,
},
actionButton: {
backgroundColor: '#0D96F2',
padding: 10,
borderRadius: 4,
alignItems: 'center',
},
actionButtonText: {
color: '#fff',
fontWeight: '500',
fontSize: 14,
},
});
export default SubViewThirdPartyLibs;