@zizwar/react-native-debug-console 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ar.md +193 -0
- package/README.md +288 -0
- package/dist/DebugButton.d.ts +7 -0
- package/dist/DebugButton.js +58 -0
- package/dist/DebugConsole.d.ts +58 -0
- package/dist/DebugConsole.js +70 -0
- package/dist/DebugOverlay.d.ts +7 -0
- package/dist/DebugOverlay.js +176 -0
- package/dist/DebugProvider.d.ts +20 -0
- package/dist/DebugProvider.js +139 -0
- package/dist/Icons.d.ts +43 -0
- package/dist/Icons.js +37 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +33 -0
- package/dist/types.d.ts +71 -0
- package/dist/types.js +29 -0
- package/package.json +52 -0
- package/src/DebugButton.tsx +84 -0
- package/src/DebugConsole.tsx +112 -0
- package/src/DebugOverlay.tsx +310 -0
- package/src/DebugProvider.tsx +182 -0
- package/src/Icons.tsx +91 -0
- package/src/index.ts +46 -0
- package/src/types.ts +102 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* React Native Debug Console - Overlay
|
|
4
|
+
* Full-screen modal displaying captured logs
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { View, Text, ScrollView, TouchableOpacity, StyleSheet, Modal, SafeAreaView, Share, Platform, } from 'react-native';
|
|
8
|
+
import { useDebugConsole } from './DebugProvider';
|
|
9
|
+
import { DebugIcon } from './Icons';
|
|
10
|
+
const LogEntryItem = ({ entry, colors }) => {
|
|
11
|
+
const getTypeColor = (type) => {
|
|
12
|
+
switch (type) {
|
|
13
|
+
case 'error': return colors.error;
|
|
14
|
+
case 'warn': return colors.warning;
|
|
15
|
+
case 'info': return colors.info;
|
|
16
|
+
default: return colors.textSecondary;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const getTypeIcon = (type) => {
|
|
20
|
+
switch (type) {
|
|
21
|
+
case 'error': return 'close-circle';
|
|
22
|
+
case 'warn': return 'warning';
|
|
23
|
+
case 'info': return 'information-circle';
|
|
24
|
+
default: return 'ellipse';
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const formatTime = (date) => {
|
|
28
|
+
return date.toLocaleTimeString('en-US', {
|
|
29
|
+
hour12: false,
|
|
30
|
+
hour: '2-digit',
|
|
31
|
+
minute: '2-digit',
|
|
32
|
+
second: '2-digit',
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
return (_jsxs(View, { style: [
|
|
36
|
+
styles.logEntry,
|
|
37
|
+
{ backgroundColor: colors.surface, borderLeftColor: getTypeColor(entry.type) }
|
|
38
|
+
], children: [_jsxs(View, { style: styles.logHeader, children: [_jsx(DebugIcon, { name: getTypeIcon(entry.type), size: 14, color: getTypeColor(entry.type) }), _jsx(Text, { style: [styles.logTime, { color: colors.textSecondary }], children: formatTime(entry.timestamp) }), _jsx(Text, { style: [styles.logType, { color: getTypeColor(entry.type) }], children: entry.type.toUpperCase() })] }), _jsx(Text, { style: [styles.logMessage, { color: colors.text }], selectable: true, children: entry.message })] }));
|
|
39
|
+
};
|
|
40
|
+
export const DebugOverlay = () => {
|
|
41
|
+
const { logs, isVisible, hideConsole, clearLogs, config } = useDebugConsole();
|
|
42
|
+
const colors = config.colors;
|
|
43
|
+
const handleShare = async () => {
|
|
44
|
+
const logText = logs.map(log => `[${log.timestamp.toISOString()}] [${log.type.toUpperCase()}] ${log.message}`).join('\n');
|
|
45
|
+
try {
|
|
46
|
+
await Share.share({
|
|
47
|
+
message: logText,
|
|
48
|
+
title: `${config.appName} Debug Logs`,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
// Silently fail if sharing not available
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
if (!isVisible || !config.enabled)
|
|
56
|
+
return null;
|
|
57
|
+
const errorCount = logs.filter(l => l.type === 'error').length;
|
|
58
|
+
const warnCount = logs.filter(l => l.type === 'warn').length;
|
|
59
|
+
return (_jsx(Modal, { visible: isVisible, animationType: "slide", transparent: false, onRequestClose: hideConsole, children: _jsxs(SafeAreaView, { style: [styles.container, { backgroundColor: colors.background }], children: [_jsxs(View, { style: [styles.header, { borderBottomColor: colors.surface }], children: [_jsxs(View, { style: styles.headerLeft, children: [_jsx(DebugIcon, { name: "bug", size: 24, color: colors.error }), _jsx(Text, { style: [styles.headerTitle, { color: colors.text }], children: "Debug Console" })] }), _jsxs(View, { style: styles.headerStats, children: [errorCount > 0 && (_jsx(View, { style: [styles.statBadge, { backgroundColor: colors.error }], children: _jsxs(Text, { style: styles.statText, children: [errorCount, " errors"] }) })), warnCount > 0 && (_jsx(View, { style: [styles.statBadge, { backgroundColor: colors.warning }], children: _jsxs(Text, { style: [styles.statText, { color: '#000' }], children: [warnCount, " warns"] }) }))] }), _jsx(TouchableOpacity, { onPress: hideConsole, style: styles.closeButton, children: _jsx(DebugIcon, { name: "close", size: 24, color: colors.text }) })] }), _jsxs(View, { style: [styles.actions, { borderBottomColor: colors.surface }], children: [_jsxs(TouchableOpacity, { style: [styles.actionButton, { backgroundColor: colors.surface }], onPress: clearLogs, children: [_jsx(DebugIcon, { name: "trash", size: 18, color: colors.error }), _jsx(Text, { style: [styles.actionText, { color: colors.text }], children: "Clear" })] }), _jsxs(TouchableOpacity, { style: [styles.actionButton, { backgroundColor: colors.surface }], onPress: handleShare, children: [_jsx(DebugIcon, { name: "share", size: 18, color: colors.info }), _jsx(Text, { style: [styles.actionText, { color: colors.text }], children: "Share" })] }), _jsxs(Text, { style: [styles.logCount, { color: colors.textSecondary }], children: [logs.length, " logs"] })] }), _jsx(ScrollView, { style: styles.logsContainer, contentContainerStyle: styles.logsContent, showsVerticalScrollIndicator: true, children: logs.length === 0 ? (_jsxs(View, { style: styles.emptyState, children: [_jsx(DebugIcon, { name: "document", size: 48, color: colors.textSecondary }), _jsx(Text, { style: [styles.emptyText, { color: colors.textSecondary }], children: "No logs yet" }), _jsx(Text, { style: [styles.emptySubtext, { color: colors.textSecondary }], children: "Console logs will appear here" })] })) : (logs.map(entry => (_jsx(LogEntryItem, { entry: entry, colors: colors }, entry.id)))) }), _jsx(View, { style: [styles.footer, { borderTopColor: colors.surface }], children: _jsxs(Text, { style: [styles.footerText, { color: colors.textSecondary }], children: ["Tap on log to copy \u2022 ", config.appName] }) })] }) }));
|
|
60
|
+
};
|
|
61
|
+
const styles = StyleSheet.create({
|
|
62
|
+
container: {
|
|
63
|
+
flex: 1,
|
|
64
|
+
},
|
|
65
|
+
header: {
|
|
66
|
+
flexDirection: 'row',
|
|
67
|
+
alignItems: 'center',
|
|
68
|
+
justifyContent: 'space-between',
|
|
69
|
+
paddingHorizontal: 16,
|
|
70
|
+
paddingVertical: 12,
|
|
71
|
+
borderBottomWidth: 1,
|
|
72
|
+
},
|
|
73
|
+
headerLeft: {
|
|
74
|
+
flexDirection: 'row',
|
|
75
|
+
alignItems: 'center',
|
|
76
|
+
gap: 8,
|
|
77
|
+
},
|
|
78
|
+
headerTitle: {
|
|
79
|
+
fontSize: 18,
|
|
80
|
+
fontWeight: 'bold',
|
|
81
|
+
},
|
|
82
|
+
headerStats: {
|
|
83
|
+
flexDirection: 'row',
|
|
84
|
+
gap: 8,
|
|
85
|
+
},
|
|
86
|
+
statBadge: {
|
|
87
|
+
paddingHorizontal: 8,
|
|
88
|
+
paddingVertical: 4,
|
|
89
|
+
borderRadius: 12,
|
|
90
|
+
},
|
|
91
|
+
statText: {
|
|
92
|
+
fontSize: 12,
|
|
93
|
+
fontWeight: 'bold',
|
|
94
|
+
color: '#fff',
|
|
95
|
+
},
|
|
96
|
+
closeButton: {
|
|
97
|
+
padding: 8,
|
|
98
|
+
},
|
|
99
|
+
actions: {
|
|
100
|
+
flexDirection: 'row',
|
|
101
|
+
alignItems: 'center',
|
|
102
|
+
paddingHorizontal: 16,
|
|
103
|
+
paddingVertical: 8,
|
|
104
|
+
borderBottomWidth: 1,
|
|
105
|
+
gap: 16,
|
|
106
|
+
},
|
|
107
|
+
actionButton: {
|
|
108
|
+
flexDirection: 'row',
|
|
109
|
+
alignItems: 'center',
|
|
110
|
+
gap: 6,
|
|
111
|
+
paddingVertical: 6,
|
|
112
|
+
paddingHorizontal: 12,
|
|
113
|
+
borderRadius: 8,
|
|
114
|
+
},
|
|
115
|
+
actionText: {
|
|
116
|
+
fontSize: 14,
|
|
117
|
+
},
|
|
118
|
+
logCount: {
|
|
119
|
+
marginLeft: 'auto',
|
|
120
|
+
fontSize: 12,
|
|
121
|
+
},
|
|
122
|
+
logsContainer: {
|
|
123
|
+
flex: 1,
|
|
124
|
+
},
|
|
125
|
+
logsContent: {
|
|
126
|
+
padding: 8,
|
|
127
|
+
},
|
|
128
|
+
logEntry: {
|
|
129
|
+
borderRadius: 8,
|
|
130
|
+
padding: 10,
|
|
131
|
+
marginBottom: 8,
|
|
132
|
+
borderLeftWidth: 3,
|
|
133
|
+
},
|
|
134
|
+
logHeader: {
|
|
135
|
+
flexDirection: 'row',
|
|
136
|
+
alignItems: 'center',
|
|
137
|
+
gap: 8,
|
|
138
|
+
marginBottom: 4,
|
|
139
|
+
},
|
|
140
|
+
logTime: {
|
|
141
|
+
fontSize: 11,
|
|
142
|
+
fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
|
|
143
|
+
},
|
|
144
|
+
logType: {
|
|
145
|
+
fontSize: 10,
|
|
146
|
+
fontWeight: 'bold',
|
|
147
|
+
},
|
|
148
|
+
logMessage: {
|
|
149
|
+
fontSize: 12,
|
|
150
|
+
fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
|
|
151
|
+
lineHeight: 18,
|
|
152
|
+
},
|
|
153
|
+
emptyState: {
|
|
154
|
+
alignItems: 'center',
|
|
155
|
+
justifyContent: 'center',
|
|
156
|
+
paddingVertical: 60,
|
|
157
|
+
},
|
|
158
|
+
emptyText: {
|
|
159
|
+
marginTop: 12,
|
|
160
|
+
fontSize: 16,
|
|
161
|
+
fontWeight: '600',
|
|
162
|
+
},
|
|
163
|
+
emptySubtext: {
|
|
164
|
+
marginTop: 4,
|
|
165
|
+
fontSize: 14,
|
|
166
|
+
},
|
|
167
|
+
footer: {
|
|
168
|
+
padding: 12,
|
|
169
|
+
borderTopWidth: 1,
|
|
170
|
+
alignItems: 'center',
|
|
171
|
+
},
|
|
172
|
+
footerText: {
|
|
173
|
+
fontSize: 12,
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
export default DebugOverlay;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native Debug Console - Provider
|
|
3
|
+
* Context provider that captures console logs and manages state
|
|
4
|
+
*/
|
|
5
|
+
import React, { ReactNode } from 'react';
|
|
6
|
+
import { DebugConsoleConfig, DebugConsoleContextType } from './types';
|
|
7
|
+
interface DebugProviderProps {
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
config?: DebugConsoleConfig;
|
|
10
|
+
}
|
|
11
|
+
export declare const DebugProvider: React.FC<DebugProviderProps>;
|
|
12
|
+
/**
|
|
13
|
+
* Hook to access the debug console context
|
|
14
|
+
*/
|
|
15
|
+
export declare const useDebugConsole: () => DebugConsoleContextType;
|
|
16
|
+
/**
|
|
17
|
+
* Optional hook that doesn't throw if used outside provider
|
|
18
|
+
*/
|
|
19
|
+
export declare const useDebugConsoleOptional: () => DebugConsoleContextType | null;
|
|
20
|
+
export default DebugProvider;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* React Native Debug Console - Provider
|
|
4
|
+
* Context provider that captures console logs and manages state
|
|
5
|
+
*/
|
|
6
|
+
import React, { createContext, useContext, useState, useCallback, useEffect, useMemo, } from 'react';
|
|
7
|
+
import { DEFAULT_CONFIG, } from './types';
|
|
8
|
+
const DebugConsoleContext = createContext(undefined);
|
|
9
|
+
// Store original console methods
|
|
10
|
+
const originalConsole = {
|
|
11
|
+
log: console.log.bind(console),
|
|
12
|
+
warn: console.warn.bind(console),
|
|
13
|
+
error: console.error.bind(console),
|
|
14
|
+
info: console.info.bind(console),
|
|
15
|
+
};
|
|
16
|
+
export const DebugProvider = ({ children, config: userConfig }) => {
|
|
17
|
+
// Merge user config with defaults
|
|
18
|
+
const config = useMemo(() => {
|
|
19
|
+
return {
|
|
20
|
+
...DEFAULT_CONFIG,
|
|
21
|
+
...userConfig,
|
|
22
|
+
colors: {
|
|
23
|
+
...DEFAULT_CONFIG.colors,
|
|
24
|
+
...userConfig?.colors,
|
|
25
|
+
},
|
|
26
|
+
buttonPosition: {
|
|
27
|
+
...DEFAULT_CONFIG.buttonPosition,
|
|
28
|
+
...userConfig?.buttonPosition,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}, [userConfig]);
|
|
32
|
+
const [logs, setLogs] = useState([]);
|
|
33
|
+
const [isVisible, setIsVisible] = useState(false);
|
|
34
|
+
const addLog = useCallback((type, message, data) => {
|
|
35
|
+
const entry = {
|
|
36
|
+
id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
37
|
+
timestamp: new Date(),
|
|
38
|
+
type,
|
|
39
|
+
message: typeof message === 'string' ? message : JSON.stringify(message),
|
|
40
|
+
data,
|
|
41
|
+
};
|
|
42
|
+
setLogs(prev => {
|
|
43
|
+
const newLogs = [...prev, entry];
|
|
44
|
+
// Keep only last N logs based on config
|
|
45
|
+
if (newLogs.length > config.maxLogs) {
|
|
46
|
+
return newLogs.slice(-config.maxLogs);
|
|
47
|
+
}
|
|
48
|
+
return newLogs;
|
|
49
|
+
});
|
|
50
|
+
}, [config.maxLogs]);
|
|
51
|
+
const clearLogs = useCallback(() => {
|
|
52
|
+
setLogs([]);
|
|
53
|
+
}, []);
|
|
54
|
+
const toggleVisibility = useCallback(() => {
|
|
55
|
+
setIsVisible(prev => !prev);
|
|
56
|
+
}, []);
|
|
57
|
+
const showConsole = useCallback(() => {
|
|
58
|
+
setIsVisible(true);
|
|
59
|
+
}, []);
|
|
60
|
+
const hideConsole = useCallback(() => {
|
|
61
|
+
setIsVisible(false);
|
|
62
|
+
}, []);
|
|
63
|
+
// Override console methods to capture logs
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (!config.enabled) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const formatArgs = (args) => {
|
|
69
|
+
return args.map(arg => {
|
|
70
|
+
if (typeof arg === 'object') {
|
|
71
|
+
try {
|
|
72
|
+
return JSON.stringify(arg, null, 2);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return String(arg);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return String(arg);
|
|
79
|
+
}).join(' ');
|
|
80
|
+
};
|
|
81
|
+
const wrapConsole = (type, originalFn) => {
|
|
82
|
+
return (...args) => {
|
|
83
|
+
// Always call original console method
|
|
84
|
+
originalFn(...args);
|
|
85
|
+
// Add to our logs
|
|
86
|
+
const message = formatArgs(args);
|
|
87
|
+
addLog(type, message);
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
// Override console methods based on config
|
|
91
|
+
if (config.captureLog) {
|
|
92
|
+
console.log = wrapConsole('log', originalConsole.log);
|
|
93
|
+
}
|
|
94
|
+
if (config.captureWarn) {
|
|
95
|
+
console.warn = wrapConsole('warn', originalConsole.warn);
|
|
96
|
+
}
|
|
97
|
+
if (config.captureError) {
|
|
98
|
+
console.error = wrapConsole('error', originalConsole.error);
|
|
99
|
+
}
|
|
100
|
+
if (config.captureInfo) {
|
|
101
|
+
console.info = wrapConsole('info', originalConsole.info);
|
|
102
|
+
}
|
|
103
|
+
// Restore original methods on cleanup
|
|
104
|
+
return () => {
|
|
105
|
+
console.log = originalConsole.log;
|
|
106
|
+
console.warn = originalConsole.warn;
|
|
107
|
+
console.error = originalConsole.error;
|
|
108
|
+
console.info = originalConsole.info;
|
|
109
|
+
};
|
|
110
|
+
}, [config.enabled, config.captureLog, config.captureWarn, config.captureError, config.captureInfo, addLog]);
|
|
111
|
+
const contextValue = useMemo(() => ({
|
|
112
|
+
logs,
|
|
113
|
+
isVisible,
|
|
114
|
+
config,
|
|
115
|
+
addLog,
|
|
116
|
+
clearLogs,
|
|
117
|
+
toggleVisibility,
|
|
118
|
+
showConsole,
|
|
119
|
+
hideConsole,
|
|
120
|
+
}), [logs, isVisible, config, addLog, clearLogs, toggleVisibility, showConsole, hideConsole]);
|
|
121
|
+
return (_jsx(DebugConsoleContext.Provider, { value: contextValue, children: children }));
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Hook to access the debug console context
|
|
125
|
+
*/
|
|
126
|
+
export const useDebugConsole = () => {
|
|
127
|
+
const context = useContext(DebugConsoleContext);
|
|
128
|
+
if (!context) {
|
|
129
|
+
throw new Error('useDebugConsole must be used within a DebugProvider');
|
|
130
|
+
}
|
|
131
|
+
return context;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Optional hook that doesn't throw if used outside provider
|
|
135
|
+
*/
|
|
136
|
+
export const useDebugConsoleOptional = () => {
|
|
137
|
+
return useContext(DebugConsoleContext) ?? null;
|
|
138
|
+
};
|
|
139
|
+
export default DebugProvider;
|
package/dist/Icons.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native Debug Console - Icons
|
|
3
|
+
* Simple text-based icons to avoid external dependencies
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
interface IconProps {
|
|
7
|
+
name: IconName;
|
|
8
|
+
size?: number;
|
|
9
|
+
color?: string;
|
|
10
|
+
}
|
|
11
|
+
export type IconName = 'bug' | 'close' | 'close-circle' | 'warning' | 'information-circle' | 'trash' | 'share' | 'document' | 'ellipse';
|
|
12
|
+
export declare const DebugIcon: React.FC<IconProps>;
|
|
13
|
+
export declare const SvgIcons: {
|
|
14
|
+
Bug: ({ size, color }: {
|
|
15
|
+
size?: number;
|
|
16
|
+
color?: string;
|
|
17
|
+
}) => any;
|
|
18
|
+
Close: ({ size, color }: {
|
|
19
|
+
size?: number;
|
|
20
|
+
color?: string;
|
|
21
|
+
}) => any;
|
|
22
|
+
Error: ({ size, color }: {
|
|
23
|
+
size?: number;
|
|
24
|
+
color?: string;
|
|
25
|
+
}) => any;
|
|
26
|
+
Warning: ({ size, color }: {
|
|
27
|
+
size?: number;
|
|
28
|
+
color?: string;
|
|
29
|
+
}) => any;
|
|
30
|
+
Info: ({ size, color }: {
|
|
31
|
+
size?: number;
|
|
32
|
+
color?: string;
|
|
33
|
+
}) => any;
|
|
34
|
+
Trash: ({ size, color }: {
|
|
35
|
+
size?: number;
|
|
36
|
+
color?: string;
|
|
37
|
+
}) => any;
|
|
38
|
+
Share: ({ size, color }: {
|
|
39
|
+
size?: number;
|
|
40
|
+
color?: string;
|
|
41
|
+
}) => any;
|
|
42
|
+
};
|
|
43
|
+
export default DebugIcon;
|
package/dist/Icons.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* React Native Debug Console - Icons
|
|
4
|
+
* Simple text-based icons to avoid external dependencies
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { Text, View, StyleSheet } from 'react-native';
|
|
8
|
+
const ICONS = {
|
|
9
|
+
'bug': '🐛',
|
|
10
|
+
'close': '✕',
|
|
11
|
+
'close-circle': '⊗',
|
|
12
|
+
'warning': '⚠',
|
|
13
|
+
'information-circle': 'ℹ',
|
|
14
|
+
'trash': '🗑',
|
|
15
|
+
'share': '↗',
|
|
16
|
+
'document': '📄',
|
|
17
|
+
'ellipse': '●',
|
|
18
|
+
};
|
|
19
|
+
export const DebugIcon = ({ name, size = 16, color = '#fff' }) => {
|
|
20
|
+
return (_jsx(Text, { style: [styles.icon, { fontSize: size, color }], children: ICONS[name] || '●' }));
|
|
21
|
+
};
|
|
22
|
+
// SVG-based icons for better quality (optional, requires react-native-svg)
|
|
23
|
+
export const SvgIcons = {
|
|
24
|
+
Bug: ({ size = 24, color = '#fff' }) => (_jsx(View, { style: { width: size, height: size, justifyContent: 'center', alignItems: 'center' }, children: _jsx(Text, { style: { fontSize: size * 0.8, color }, children: "\uD83D\uDC1B" }) })),
|
|
25
|
+
Close: ({ size = 24, color = '#fff' }) => (_jsx(View, { style: { width: size, height: size, justifyContent: 'center', alignItems: 'center' }, children: _jsx(Text, { style: { fontSize: size * 0.8, color, fontWeight: 'bold' }, children: "\u2715" }) })),
|
|
26
|
+
Error: ({ size = 24, color = '#FF5252' }) => (_jsx(View, { style: { width: size, height: size, justifyContent: 'center', alignItems: 'center' }, children: _jsx(Text, { style: { fontSize: size * 0.8, color }, children: "\u2297" }) })),
|
|
27
|
+
Warning: ({ size = 24, color = '#FFD740' }) => (_jsx(View, { style: { width: size, height: size, justifyContent: 'center', alignItems: 'center' }, children: _jsx(Text, { style: { fontSize: size * 0.8, color }, children: "\u26A0" }) })),
|
|
28
|
+
Info: ({ size = 24, color = '#40C4FF' }) => (_jsx(View, { style: { width: size, height: size, justifyContent: 'center', alignItems: 'center' }, children: _jsx(Text, { style: { fontSize: size * 0.8, color }, children: "\u2139" }) })),
|
|
29
|
+
Trash: ({ size = 24, color = '#fff' }) => (_jsx(View, { style: { width: size, height: size, justifyContent: 'center', alignItems: 'center' }, children: _jsx(Text, { style: { fontSize: size * 0.8, color }, children: "\uD83D\uDDD1" }) })),
|
|
30
|
+
Share: ({ size = 24, color = '#fff' }) => (_jsx(View, { style: { width: size, height: size, justifyContent: 'center', alignItems: 'center' }, children: _jsx(Text, { style: { fontSize: size * 0.8, color }, children: "\u2197" }) })),
|
|
31
|
+
};
|
|
32
|
+
const styles = StyleSheet.create({
|
|
33
|
+
icon: {
|
|
34
|
+
textAlign: 'center',
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
export default DebugIcon;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native Debug Console
|
|
3
|
+
*
|
|
4
|
+
* A floating debug console for React Native / Expo apps.
|
|
5
|
+
* Captures console logs, errors, and warnings with a beautiful overlay UI.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import { DebugConsole } from 'react-native-debug-console';
|
|
10
|
+
*
|
|
11
|
+
* export default function App() {
|
|
12
|
+
* return (
|
|
13
|
+
* <DebugConsole
|
|
14
|
+
* config={{
|
|
15
|
+
* enabled: process.env.EXPO_PUBLIC_DEBUG === 'true',
|
|
16
|
+
* appName: 'MyApp',
|
|
17
|
+
* }}
|
|
18
|
+
* >
|
|
19
|
+
* <YourApp />
|
|
20
|
+
* </DebugConsole>
|
|
21
|
+
* );
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export { DebugConsole, withDebugConsole } from './DebugConsole';
|
|
26
|
+
export { DebugProvider, useDebugConsole, useDebugConsoleOptional } from './DebugProvider';
|
|
27
|
+
export { DebugOverlay } from './DebugOverlay';
|
|
28
|
+
export { DebugButton } from './DebugButton';
|
|
29
|
+
export { DebugIcon } from './Icons';
|
|
30
|
+
export type { LogEntry, LogType, DebugConsoleConfig, DebugConsoleColors, ButtonPosition, DebugConsoleContextType, } from './types';
|
|
31
|
+
export { DEFAULT_CONFIG } from './types';
|
|
32
|
+
export { DebugConsole as default } from './DebugConsole';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native Debug Console
|
|
3
|
+
*
|
|
4
|
+
* A floating debug console for React Native / Expo apps.
|
|
5
|
+
* Captures console logs, errors, and warnings with a beautiful overlay UI.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import { DebugConsole } from 'react-native-debug-console';
|
|
10
|
+
*
|
|
11
|
+
* export default function App() {
|
|
12
|
+
* return (
|
|
13
|
+
* <DebugConsole
|
|
14
|
+
* config={{
|
|
15
|
+
* enabled: process.env.EXPO_PUBLIC_DEBUG === 'true',
|
|
16
|
+
* appName: 'MyApp',
|
|
17
|
+
* }}
|
|
18
|
+
* >
|
|
19
|
+
* <YourApp />
|
|
20
|
+
* </DebugConsole>
|
|
21
|
+
* );
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
// Main components
|
|
26
|
+
export { DebugConsole, withDebugConsole } from './DebugConsole';
|
|
27
|
+
export { DebugProvider, useDebugConsole, useDebugConsoleOptional } from './DebugProvider';
|
|
28
|
+
export { DebugOverlay } from './DebugOverlay';
|
|
29
|
+
export { DebugButton } from './DebugButton';
|
|
30
|
+
export { DebugIcon } from './Icons';
|
|
31
|
+
export { DEFAULT_CONFIG } from './types';
|
|
32
|
+
// Default export
|
|
33
|
+
export { DebugConsole as default } from './DebugConsole';
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native Debug Console - Types
|
|
3
|
+
*/
|
|
4
|
+
export type LogType = 'log' | 'warn' | 'error' | 'info';
|
|
5
|
+
export interface LogEntry {
|
|
6
|
+
id: string;
|
|
7
|
+
timestamp: Date;
|
|
8
|
+
type: LogType;
|
|
9
|
+
message: string;
|
|
10
|
+
data?: any;
|
|
11
|
+
}
|
|
12
|
+
export interface DebugConsoleConfig {
|
|
13
|
+
/** Enable or disable the debug console (default: true) */
|
|
14
|
+
enabled?: boolean;
|
|
15
|
+
/** Maximum number of logs to keep (default: 100) */
|
|
16
|
+
maxLogs?: number;
|
|
17
|
+
/** Custom colors for the theme */
|
|
18
|
+
colors?: DebugConsoleColors;
|
|
19
|
+
/** Position of the floating button */
|
|
20
|
+
buttonPosition?: ButtonPosition;
|
|
21
|
+
/** Custom app name for sharing logs */
|
|
22
|
+
appName?: string;
|
|
23
|
+
/** Capture console.log (default: true) */
|
|
24
|
+
captureLog?: boolean;
|
|
25
|
+
/** Capture console.warn (default: true) */
|
|
26
|
+
captureWarn?: boolean;
|
|
27
|
+
/** Capture console.error (default: true) */
|
|
28
|
+
captureError?: boolean;
|
|
29
|
+
/** Capture console.info (default: true) */
|
|
30
|
+
captureInfo?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface DebugConsoleColors {
|
|
33
|
+
/** Primary background color */
|
|
34
|
+
background?: string;
|
|
35
|
+
/** Card/surface background color */
|
|
36
|
+
surface?: string;
|
|
37
|
+
/** Primary text color */
|
|
38
|
+
text?: string;
|
|
39
|
+
/** Secondary text color */
|
|
40
|
+
textSecondary?: string;
|
|
41
|
+
/** Error color */
|
|
42
|
+
error?: string;
|
|
43
|
+
/** Warning color */
|
|
44
|
+
warning?: string;
|
|
45
|
+
/** Info color */
|
|
46
|
+
info?: string;
|
|
47
|
+
/** Log color */
|
|
48
|
+
log?: string;
|
|
49
|
+
/** Floating button background color */
|
|
50
|
+
buttonBackground?: string;
|
|
51
|
+
/** Floating button icon color */
|
|
52
|
+
buttonIcon?: string;
|
|
53
|
+
}
|
|
54
|
+
export interface ButtonPosition {
|
|
55
|
+
bottom?: number;
|
|
56
|
+
right?: number;
|
|
57
|
+
left?: number;
|
|
58
|
+
top?: number;
|
|
59
|
+
}
|
|
60
|
+
export interface DebugConsoleContextType {
|
|
61
|
+
logs: LogEntry[];
|
|
62
|
+
isVisible: boolean;
|
|
63
|
+
config: Required<DebugConsoleConfig>;
|
|
64
|
+
addLog: (type: LogType, message: string, data?: any) => void;
|
|
65
|
+
clearLogs: () => void;
|
|
66
|
+
toggleVisibility: () => void;
|
|
67
|
+
showConsole: () => void;
|
|
68
|
+
hideConsole: () => void;
|
|
69
|
+
}
|
|
70
|
+
/** Default configuration */
|
|
71
|
+
export declare const DEFAULT_CONFIG: Required<DebugConsoleConfig>;
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native Debug Console - Types
|
|
3
|
+
*/
|
|
4
|
+
/** Default configuration */
|
|
5
|
+
export const DEFAULT_CONFIG = {
|
|
6
|
+
enabled: true,
|
|
7
|
+
maxLogs: 100,
|
|
8
|
+
appName: 'App',
|
|
9
|
+
captureLog: true,
|
|
10
|
+
captureWarn: true,
|
|
11
|
+
captureError: true,
|
|
12
|
+
captureInfo: true,
|
|
13
|
+
colors: {
|
|
14
|
+
background: '#1a1a2e',
|
|
15
|
+
surface: '#2a2a3e',
|
|
16
|
+
text: '#ffffff',
|
|
17
|
+
textSecondary: '#888888',
|
|
18
|
+
error: '#FF5252',
|
|
19
|
+
warning: '#FFD740',
|
|
20
|
+
info: '#40C4FF',
|
|
21
|
+
log: '#888888',
|
|
22
|
+
buttonBackground: '#FF6B6B',
|
|
23
|
+
buttonIcon: '#ffffff',
|
|
24
|
+
},
|
|
25
|
+
buttonPosition: {
|
|
26
|
+
bottom: 100,
|
|
27
|
+
right: 20,
|
|
28
|
+
},
|
|
29
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zizwar/react-native-debug-console",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A floating debug console for React Native / Expo apps. Captures console logs, errors, and warnings with a beautiful overlay UI.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"src"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"prepublishOnly": "npm run build",
|
|
15
|
+
"test": "echo \"No tests yet\""
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"typescript": "^5.0.0"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"react-native",
|
|
22
|
+
"expo",
|
|
23
|
+
"debug",
|
|
24
|
+
"console",
|
|
25
|
+
"logger",
|
|
26
|
+
"debugger",
|
|
27
|
+
"overlay",
|
|
28
|
+
"floating-button",
|
|
29
|
+
"error-tracking",
|
|
30
|
+
"development-tools"
|
|
31
|
+
],
|
|
32
|
+
"author": "Ibrahim BIDI",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"react": ">=17.0.0",
|
|
36
|
+
"react-native": ">=0.64.0",
|
|
37
|
+
"react-native-svg": ">=12.0.0"
|
|
38
|
+
},
|
|
39
|
+
"peerDependenciesMeta": {
|
|
40
|
+
"react-native-svg": {
|
|
41
|
+
"optional": true
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "https://github.com/Zizwar/react-native-debug-console"
|
|
47
|
+
},
|
|
48
|
+
"bugs": {
|
|
49
|
+
"url": "https://github.com/Zizwar/react-native-debug-console/issues"
|
|
50
|
+
},
|
|
51
|
+
"homepage": "https://github.com/Zizwar/tvslayer/tree/main/packages/react-native-debug-console#readme"
|
|
52
|
+
}
|