@novodip/expo-router-devtools 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 [Your Name]
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,41 @@
1
+ # Expo Router DevTools
2
+
3
+ A lightweight development utility for inspecting and debugging routes in **Expo Router** applications.
4
+ Designed to be embedded directly into React Native apps without affecting production builds.
5
+
6
+ ---
7
+
8
+ ## Features
9
+
10
+ - View the current route in real time
11
+ - Inspect navigation state changes
12
+ - Minimal, non-intrusive UI
13
+ - Safe to include during development
14
+ - Built with TypeScript and Rollup
15
+
16
+ ---
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install expo-router-devtools
22
+
23
+ or
24
+
25
+ yarn add expo-router-devtools
26
+
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ ```bash
32
+ import { ExpoRouterDevTools } from 'expo-router-devtools';
33
+
34
+ export default function App() {
35
+ return (
36
+ <>
37
+ <ExpoRouterDevTools />
38
+ </>
39
+ );
40
+ }
41
+ ```
@@ -0,0 +1,263 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { usePathname, useGlobalSearchParams, useRouter } from 'expo-router';
3
+ import * as SecureStore from 'expo-secure-store';
4
+ import { useState, useEffect, useCallback } from 'react';
5
+ import { View, Pressable, Text, ScrollView, StyleSheet, Platform } from 'react-native';
6
+
7
+ const STORAGE_PREFIX = 'expo-router-devtools_';
8
+ const MAX_HISTORY = 10;
9
+ const ExpoRouterDevTools = ({ position = 'top', theme = 'light', hideInProduction = true, storageKeyPrefix = STORAGE_PREFIX, onRouteChange, enableHistory = true, maxHistory = MAX_HISTORY, maxNumOfLines = 3, }) => {
10
+ const pathname = usePathname();
11
+ const searchParams = useGlobalSearchParams();
12
+ const router = useRouter();
13
+ const [currentRoute, setCurrentRoute] = useState('');
14
+ const [savedRoutes, setSavedRoutes] = useState([]);
15
+ const [routeHistory, setRouteHistory] = useState([]);
16
+ const [isExpanded, setIsExpanded] = useState(false);
17
+ const [showHistory, setShowHistory] = useState(false);
18
+ const SAVED_ROUTES_KEY = `${storageKeyPrefix}saved-routes`;
19
+ const HISTORY_KEY = `${storageKeyPrefix}history`;
20
+ // Build current full route
21
+ useEffect(() => {
22
+ const query = Object.keys(searchParams).length
23
+ ? '?' +
24
+ Object.entries(searchParams)
25
+ .map(([key, value]) => `${key}=${encodeURIComponent(String(value))}`)
26
+ .join('&')
27
+ : '';
28
+ const fullRoute = `${pathname}${query}`;
29
+ setCurrentRoute(fullRoute);
30
+ onRouteChange === null || onRouteChange === void 0 ? void 0 : onRouteChange(fullRoute);
31
+ }, [pathname, searchParams, onRouteChange]);
32
+ // Load saved routes and history
33
+ useEffect(() => {
34
+ const loadData = async () => {
35
+ try {
36
+ const savedRoutesData = await SecureStore.getItemAsync(SAVED_ROUTES_KEY);
37
+ if (savedRoutesData) {
38
+ setSavedRoutes(JSON.parse(savedRoutesData));
39
+ }
40
+ if (enableHistory) {
41
+ const historyData = await SecureStore.getItemAsync(HISTORY_KEY);
42
+ if (historyData) {
43
+ setRouteHistory(JSON.parse(historyData));
44
+ }
45
+ }
46
+ }
47
+ catch (error) {
48
+ console.error('[ExpoRouterDevTools] Error loading data:', error);
49
+ }
50
+ };
51
+ loadData();
52
+ }, [SAVED_ROUTES_KEY, HISTORY_KEY, enableHistory]);
53
+ // Update history when route changes
54
+ useEffect(() => {
55
+ if (!enableHistory || !currentRoute)
56
+ return;
57
+ const updateHistory = async () => {
58
+ try {
59
+ const newHistory = [currentRoute, ...routeHistory.filter((r) => r !== currentRoute)].slice(0, maxHistory);
60
+ setRouteHistory(newHistory);
61
+ await SecureStore.setItemAsync(HISTORY_KEY, JSON.stringify(newHistory));
62
+ }
63
+ catch (error) {
64
+ console.error('[ExpoRouterDevTools] Error updating history:', error);
65
+ }
66
+ };
67
+ updateHistory();
68
+ }, [currentRoute, enableHistory, maxHistory, HISTORY_KEY]);
69
+ // Save current route
70
+ const saveRoute = useCallback(async () => {
71
+ const label = `Route ${savedRoutes.length + 1}`;
72
+ const newRoute = {
73
+ route: currentRoute,
74
+ label,
75
+ timestamp: Date.now(),
76
+ };
77
+ const updated = [...savedRoutes, newRoute];
78
+ setSavedRoutes(updated);
79
+ try {
80
+ await SecureStore.setItemAsync(SAVED_ROUTES_KEY, JSON.stringify(updated));
81
+ }
82
+ catch (error) {
83
+ console.error('[ExpoRouterDevTools] Error saving route:', error);
84
+ }
85
+ }, [currentRoute, savedRoutes, SAVED_ROUTES_KEY]);
86
+ // Navigate to route
87
+ const navigateToRoute = useCallback((route) => {
88
+ try {
89
+ router.push(route);
90
+ }
91
+ catch (error) {
92
+ console.error('[ExpoRouterDevTools] Navigation error:', error);
93
+ }
94
+ }, [router]);
95
+ // Delete saved route
96
+ const deleteSavedRoute = useCallback(async (index) => {
97
+ const updated = savedRoutes.filter((_, i) => i !== index);
98
+ setSavedRoutes(updated);
99
+ try {
100
+ await SecureStore.setItemAsync(SAVED_ROUTES_KEY, JSON.stringify(updated));
101
+ }
102
+ catch (error) {
103
+ console.error('[ExpoRouterDevTools] Error deleting route:', error);
104
+ }
105
+ }, [savedRoutes, SAVED_ROUTES_KEY]);
106
+ // Clear all data
107
+ const clearAll = useCallback(async () => {
108
+ setSavedRoutes([]);
109
+ setRouteHistory([]);
110
+ try {
111
+ await SecureStore.deleteItemAsync(SAVED_ROUTES_KEY);
112
+ await SecureStore.deleteItemAsync(HISTORY_KEY);
113
+ }
114
+ catch (error) {
115
+ console.error('[ExpoRouterDevTools] Error clearing data:', error);
116
+ }
117
+ }, [SAVED_ROUTES_KEY, HISTORY_KEY]);
118
+ const isDark = theme === 'dark';
119
+ const styles = createStyles(isDark, position);
120
+ // Check if we should render in production
121
+ if (hideInProduction && !__DEV__) {
122
+ return null;
123
+ }
124
+ return (jsxs(View, { style: styles.container, children: [jsxs(Pressable, { onPress: () => setIsExpanded(!isExpanded), style: styles.routeBar, children: [jsxs(Text, { style: styles.routeText, numberOfLines: maxNumOfLines, children: ["\uD83D\uDEE3\uFE0F ", currentRoute || '/'] }), jsx(Text, { style: styles.expandIcon, children: isExpanded ? '▼' : '▶' })] }), isExpanded && (jsxs(View, { style: styles.controls, children: [jsxs(View, { style: styles.buttonRow, children: [jsx(Pressable, { onPress: saveRoute, style: styles.button, children: jsx(Text, { style: styles.buttonText, children: "Save" }) }), enableHistory && (jsx(Pressable, { onPress: () => setShowHistory(!showHistory), style: styles.button, children: jsx(Text, { style: styles.buttonText, children: "History" }) })), jsx(Pressable, { onPress: clearAll, style: [styles.button, styles.dangerButton], children: jsx(Text, { style: styles.buttonText, children: "Clear" }) })] }), showHistory && enableHistory && routeHistory.length > 0 && (jsxs(View, { style: styles.section, children: [jsx(Text, { style: styles.sectionTitle, children: "Recent Routes" }), jsx(ScrollView, { style: styles.listContainer, children: routeHistory.map((route, index) => (jsx(Pressable, { onPress: () => navigateToRoute(route), style: ({ pressed }) => [styles.listItem, route === currentRoute && styles.selectedItem, pressed && styles.listItemPressed], children: jsx(Text, { style: styles.listItemText, numberOfLines: 1, children: route }) }, `${route}-${index}`))) })] })), savedRoutes.length > 0 && (jsxs(View, { style: styles.section, children: [jsx(Text, { style: styles.sectionTitle, children: "Saved Routes" }), jsx(ScrollView, { style: styles.listContainer, children: savedRoutes.map((saved, index) => (jsxs(Pressable, { onPress: () => navigateToRoute(saved.route), style: ({ pressed }) => [styles.savedItem, saved.route === currentRoute && styles.selectedItem, pressed && styles.listItemPressed], children: [jsxs(View, { style: styles.savedItemContent, children: [jsx(Text, { style: styles.savedItemLabel, children: saved.label }), jsx(Text, { style: styles.listItemText, numberOfLines: 1, children: saved.route })] }), jsx(Pressable, { onPress: (e) => {
125
+ var _a;
126
+ (_a = e.stopPropagation) === null || _a === void 0 ? void 0 : _a.call(e);
127
+ deleteSavedRoute(index);
128
+ }, style: styles.deleteButton, children: jsx(Text, { style: styles.deleteButtonText, children: "\u2715" }) })] }, `${saved.route}-${index}`))) })] }))] }))] }));
129
+ };
130
+ const createStyles = (isDark, position) => {
131
+ const bgColor = isDark ? '#1a1a1a' : '#ffffff';
132
+ const textColor = isDark ? '#e0e0e0' : '#333333';
133
+ const borderColor = isDark ? '#333333' : '#dddddd';
134
+ const buttonBg = isDark ? '#2563eb' : '#2563eb';
135
+ const secondaryBg = isDark ? '#262626' : '#f5f5f5';
136
+ const pressedBg = isDark ? '#1e40af' : '#dbeafe';
137
+ return StyleSheet.create({
138
+ container: {
139
+ backgroundColor: bgColor,
140
+ borderTopWidth: position === 'bottom' ? 1 : 0,
141
+ borderBottomWidth: position === 'top' ? 1 : 0,
142
+ borderColor,
143
+ ...Platform.select({
144
+ ios: {
145
+ shadowColor: '#000',
146
+ shadowOffset: { width: 0, height: 2 },
147
+ shadowOpacity: 0.1,
148
+ shadowRadius: 4,
149
+ },
150
+ android: {
151
+ elevation: 4,
152
+ },
153
+ }),
154
+ },
155
+ selectedItem: {
156
+ backgroundColor: pressedBg,
157
+ borderWidth: 1,
158
+ borderColor: '#2563eb',
159
+ },
160
+ routeBar: {
161
+ flexDirection: 'row',
162
+ alignItems: 'center',
163
+ justifyContent: 'space-between',
164
+ padding: 12,
165
+ paddingHorizontal: 16,
166
+ },
167
+ routeText: {
168
+ flex: 1,
169
+ fontSize: 12,
170
+ color: textColor,
171
+ fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
172
+ },
173
+ expandIcon: {
174
+ fontSize: 16,
175
+ color: textColor,
176
+ marginLeft: 8,
177
+ },
178
+ controls: {
179
+ padding: 12,
180
+ paddingTop: 0,
181
+ },
182
+ buttonRow: {
183
+ flexDirection: 'row',
184
+ gap: 8,
185
+ marginBottom: 12,
186
+ },
187
+ button: {
188
+ flex: 1,
189
+ paddingHorizontal: 12,
190
+ paddingVertical: 8,
191
+ backgroundColor: buttonBg,
192
+ borderRadius: 6,
193
+ alignItems: 'center',
194
+ },
195
+ dangerButton: {
196
+ backgroundColor: '#dc2626',
197
+ },
198
+ buttonText: {
199
+ color: '#ffffff',
200
+ fontSize: 12,
201
+ fontWeight: '600',
202
+ },
203
+ section: {
204
+ marginTop: 12,
205
+ },
206
+ sectionTitle: {
207
+ fontSize: 11,
208
+ fontWeight: '600',
209
+ color: textColor,
210
+ marginBottom: 8,
211
+ textTransform: 'uppercase',
212
+ letterSpacing: 0.5,
213
+ },
214
+ listContainer: {
215
+ maxHeight: 150,
216
+ },
217
+ listItem: {
218
+ padding: 8,
219
+ backgroundColor: secondaryBg,
220
+ borderRadius: 4,
221
+ marginBottom: 4,
222
+ },
223
+ listItemPressed: {
224
+ backgroundColor: pressedBg,
225
+ },
226
+ listItemText: {
227
+ fontSize: 11,
228
+ color: textColor,
229
+ fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
230
+ },
231
+ savedItem: {
232
+ flexDirection: 'row',
233
+ alignItems: 'center',
234
+ backgroundColor: secondaryBg,
235
+ borderRadius: 4,
236
+ marginBottom: 4,
237
+ overflow: 'hidden',
238
+ },
239
+ savedItemContent: {
240
+ flex: 1,
241
+ padding: 8,
242
+ },
243
+ savedItemLabel: {
244
+ fontSize: 10,
245
+ fontWeight: '600',
246
+ color: buttonBg,
247
+ marginBottom: 2,
248
+ },
249
+ deleteButton: {
250
+ padding: 8,
251
+ paddingHorizontal: 12,
252
+ backgroundColor: '#dc2626',
253
+ },
254
+ deleteButtonText: {
255
+ color: '#ffffff',
256
+ fontSize: 14,
257
+ fontWeight: 'bold',
258
+ },
259
+ });
260
+ };
261
+
262
+ export { ExpoRouterDevTools };
263
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":["../src/ExpoRouterDevTools.tsx"],"sourcesContent":["import { useGlobalSearchParams, usePathname, useRouter, type RelativePathString } from 'expo-router'\nimport * as SecureStore from 'expo-secure-store'\nimport React, { useCallback, useEffect, useState } from 'react'\nimport { Platform, Pressable, ScrollView, StyleSheet, Text, View } from 'react-native'\nimport { ExpoRouterDevToolsProps, SavedRoute } from './interfaces/base'\n\nconst STORAGE_PREFIX = 'expo-router-devtools_'\nconst MAX_HISTORY = 10\n\nconst ExpoRouterDevTools: React.FC<ExpoRouterDevToolsProps> = ({\n position = 'top',\n theme = 'light',\n hideInProduction = true,\n storageKeyPrefix = STORAGE_PREFIX,\n onRouteChange,\n enableHistory = true,\n maxHistory = MAX_HISTORY,\n maxNumOfLines = 3,\n}) => {\n const pathname = usePathname()\n const searchParams = useGlobalSearchParams()\n const router = useRouter()\n\n const [currentRoute, setCurrentRoute] = useState('')\n const [savedRoutes, setSavedRoutes] = useState<SavedRoute[]>([])\n const [routeHistory, setRouteHistory] = useState<string[]>([])\n const [isExpanded, setIsExpanded] = useState(false)\n const [showHistory, setShowHistory] = useState(false)\n\n const SAVED_ROUTES_KEY = `${storageKeyPrefix}saved-routes`\n const HISTORY_KEY = `${storageKeyPrefix}history`\n\n // Build current full route\n useEffect(() => {\n const query = Object.keys(searchParams).length\n ? '?' +\n Object.entries(searchParams)\n .map(([key, value]) => `${key}=${encodeURIComponent(String(value))}`)\n .join('&')\n : ''\n\n const fullRoute = `${pathname}${query}`\n setCurrentRoute(fullRoute)\n onRouteChange?.(fullRoute)\n }, [pathname, searchParams, onRouteChange])\n\n // Load saved routes and history\n useEffect(() => {\n const loadData = async () => {\n try {\n const savedRoutesData = await SecureStore.getItemAsync(SAVED_ROUTES_KEY)\n if (savedRoutesData) {\n setSavedRoutes(JSON.parse(savedRoutesData))\n }\n\n if (enableHistory) {\n const historyData = await SecureStore.getItemAsync(HISTORY_KEY)\n if (historyData) {\n setRouteHistory(JSON.parse(historyData))\n }\n }\n } catch (error) {\n console.error('[ExpoRouterDevTools] Error loading data:', error)\n }\n }\n\n loadData()\n }, [SAVED_ROUTES_KEY, HISTORY_KEY, enableHistory])\n\n // Update history when route changes\n useEffect(() => {\n if (!enableHistory || !currentRoute) return\n\n const updateHistory = async () => {\n try {\n const newHistory = [currentRoute, ...routeHistory.filter((r) => r !== currentRoute)].slice(0, maxHistory)\n setRouteHistory(newHistory)\n await SecureStore.setItemAsync(HISTORY_KEY, JSON.stringify(newHistory))\n } catch (error) {\n console.error('[ExpoRouterDevTools] Error updating history:', error)\n }\n }\n\n updateHistory()\n }, [currentRoute, enableHistory, maxHistory, HISTORY_KEY])\n\n // Save current route\n const saveRoute = useCallback(async () => {\n const label = `Route ${savedRoutes.length + 1}`\n const newRoute: SavedRoute = {\n route: currentRoute,\n label,\n timestamp: Date.now(),\n }\n\n const updated = [...savedRoutes, newRoute]\n setSavedRoutes(updated)\n\n try {\n await SecureStore.setItemAsync(SAVED_ROUTES_KEY, JSON.stringify(updated))\n } catch (error) {\n console.error('[ExpoRouterDevTools] Error saving route:', error)\n }\n }, [currentRoute, savedRoutes, SAVED_ROUTES_KEY])\n\n // Navigate to route\n const navigateToRoute = useCallback(\n (route: string) => {\n try {\n router.push(route as RelativePathString)\n } catch (error) {\n console.error('[ExpoRouterDevTools] Navigation error:', error)\n }\n },\n [router]\n )\n\n // Delete saved route\n const deleteSavedRoute = useCallback(\n async (index: number) => {\n const updated = savedRoutes.filter((_, i) => i !== index)\n setSavedRoutes(updated)\n\n try {\n await SecureStore.setItemAsync(SAVED_ROUTES_KEY, JSON.stringify(updated))\n } catch (error) {\n console.error('[ExpoRouterDevTools] Error deleting route:', error)\n }\n },\n [savedRoutes, SAVED_ROUTES_KEY]\n )\n\n // Clear all data\n const clearAll = useCallback(async () => {\n setSavedRoutes([])\n setRouteHistory([])\n\n try {\n await SecureStore.deleteItemAsync(SAVED_ROUTES_KEY)\n await SecureStore.deleteItemAsync(HISTORY_KEY)\n } catch (error) {\n console.error('[ExpoRouterDevTools] Error clearing data:', error)\n }\n }, [SAVED_ROUTES_KEY, HISTORY_KEY])\n\n const isDark = theme === 'dark'\n const styles = createStyles(isDark, position)\n\n // Check if we should render in production\n if (hideInProduction && !__DEV__) {\n return null\n }\n\n return (\n <View style={styles.container}>\n {/* Current route bar */}\n <Pressable onPress={() => setIsExpanded(!isExpanded)} style={styles.routeBar}>\n <Text style={styles.routeText} numberOfLines={maxNumOfLines}>\n 🛣️ {currentRoute || '/'}\n </Text>\n <Text style={styles.expandIcon}>{isExpanded ? '▼' : '▶'}</Text>\n </Pressable>\n\n {/* Expanded controls */}\n {isExpanded && (\n <View style={styles.controls}>\n {/* Action buttons */}\n <View style={styles.buttonRow}>\n <Pressable onPress={saveRoute} style={styles.button}>\n <Text style={styles.buttonText}>Save</Text>\n </Pressable>\n\n {enableHistory && (\n <Pressable onPress={() => setShowHistory(!showHistory)} style={styles.button}>\n <Text style={styles.buttonText}>History</Text>\n </Pressable>\n )}\n\n <Pressable onPress={clearAll} style={[styles.button, styles.dangerButton]}>\n <Text style={styles.buttonText}>Clear</Text>\n </Pressable>\n </View>\n\n {/* History section */}\n {showHistory && enableHistory && routeHistory.length > 0 && (\n <View style={styles.section}>\n <Text style={styles.sectionTitle}>Recent Routes</Text>\n <ScrollView style={styles.listContainer}>\n {routeHistory.map((route, index) => (\n <Pressable\n key={`${route}-${index}`}\n onPress={() => navigateToRoute(route)}\n style={({ pressed }) => [styles.listItem, route === currentRoute && styles.selectedItem, pressed && styles.listItemPressed]}\n >\n <Text style={styles.listItemText} numberOfLines={1}>\n {route}\n </Text>\n </Pressable>\n ))}\n </ScrollView>\n </View>\n )}\n\n {/* Saved routes section */}\n {savedRoutes.length > 0 && (\n <View style={styles.section}>\n <Text style={styles.sectionTitle}>Saved Routes</Text>\n <ScrollView style={styles.listContainer}>\n {savedRoutes.map((saved, index) => (\n <Pressable\n key={`${saved.route}-${index}`}\n onPress={() => navigateToRoute(saved.route)}\n style={({ pressed }) => [styles.savedItem, saved.route === currentRoute && styles.selectedItem, pressed && styles.listItemPressed]}\n >\n <View style={styles.savedItemContent}>\n <Text style={styles.savedItemLabel}>{saved.label}</Text>\n <Text style={styles.listItemText} numberOfLines={1}>\n {saved.route}\n </Text>\n </View>\n <Pressable\n onPress={(e) => {\n e.stopPropagation?.()\n deleteSavedRoute(index)\n }}\n style={styles.deleteButton}\n >\n <Text style={styles.deleteButtonText}>✕</Text>\n </Pressable>\n </Pressable>\n ))}\n </ScrollView>\n </View>\n )}\n </View>\n )}\n </View>\n )\n}\n\nconst createStyles = (isDark: boolean, position: 'top' | 'bottom') => {\n const bgColor = isDark ? '#1a1a1a' : '#ffffff'\n const textColor = isDark ? '#e0e0e0' : '#333333'\n const borderColor = isDark ? '#333333' : '#dddddd'\n const buttonBg = isDark ? '#2563eb' : '#2563eb'\n const secondaryBg = isDark ? '#262626' : '#f5f5f5'\n const pressedBg = isDark ? '#1e40af' : '#dbeafe'\n\n return StyleSheet.create({\n container: {\n backgroundColor: bgColor,\n borderTopWidth: position === 'bottom' ? 1 : 0,\n borderBottomWidth: position === 'top' ? 1 : 0,\n borderColor,\n ...Platform.select({\n ios: {\n shadowColor: '#000',\n shadowOffset: { width: 0, height: 2 },\n shadowOpacity: 0.1,\n shadowRadius: 4,\n },\n android: {\n elevation: 4,\n },\n }),\n },\n selectedItem: {\n backgroundColor: pressedBg,\n borderWidth: 1,\n borderColor: '#2563eb',\n },\n\n routeBar: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: 12,\n paddingHorizontal: 16,\n },\n routeText: {\n flex: 1,\n fontSize: 12,\n color: textColor,\n fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',\n },\n expandIcon: {\n fontSize: 16,\n color: textColor,\n marginLeft: 8,\n },\n controls: {\n padding: 12,\n paddingTop: 0,\n },\n buttonRow: {\n flexDirection: 'row',\n gap: 8,\n marginBottom: 12,\n },\n button: {\n flex: 1,\n paddingHorizontal: 12,\n paddingVertical: 8,\n backgroundColor: buttonBg,\n borderRadius: 6,\n alignItems: 'center',\n },\n dangerButton: {\n backgroundColor: '#dc2626',\n },\n buttonText: {\n color: '#ffffff',\n fontSize: 12,\n fontWeight: '600',\n },\n section: {\n marginTop: 12,\n },\n sectionTitle: {\n fontSize: 11,\n fontWeight: '600',\n color: textColor,\n marginBottom: 8,\n textTransform: 'uppercase',\n letterSpacing: 0.5,\n },\n listContainer: {\n maxHeight: 150,\n },\n listItem: {\n padding: 8,\n backgroundColor: secondaryBg,\n borderRadius: 4,\n marginBottom: 4,\n },\n listItemPressed: {\n backgroundColor: pressedBg,\n },\n listItemText: {\n fontSize: 11,\n color: textColor,\n fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',\n },\n savedItem: {\n flexDirection: 'row',\n alignItems: 'center',\n backgroundColor: secondaryBg,\n borderRadius: 4,\n marginBottom: 4,\n overflow: 'hidden',\n },\n savedItemContent: {\n flex: 1,\n padding: 8,\n },\n savedItemLabel: {\n fontSize: 10,\n fontWeight: '600',\n color: buttonBg,\n marginBottom: 2,\n },\n deleteButton: {\n padding: 8,\n paddingHorizontal: 12,\n backgroundColor: '#dc2626',\n },\n deleteButtonText: {\n color: '#ffffff',\n fontSize: 14,\n fontWeight: 'bold',\n },\n })\n}\n\nexport default ExpoRouterDevTools\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,284 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var expoRouter = require('expo-router');
5
+ var SecureStore = require('expo-secure-store');
6
+ var react = require('react');
7
+ var reactNative = require('react-native');
8
+
9
+ function _interopNamespaceDefault(e) {
10
+ var n = Object.create(null);
11
+ if (e) {
12
+ Object.keys(e).forEach(function (k) {
13
+ if (k !== 'default') {
14
+ var d = Object.getOwnPropertyDescriptor(e, k);
15
+ Object.defineProperty(n, k, d.get ? d : {
16
+ enumerable: true,
17
+ get: function () { return e[k]; }
18
+ });
19
+ }
20
+ });
21
+ }
22
+ n.default = e;
23
+ return Object.freeze(n);
24
+ }
25
+
26
+ var SecureStore__namespace = /*#__PURE__*/_interopNamespaceDefault(SecureStore);
27
+
28
+ const STORAGE_PREFIX = 'expo-router-devtools_';
29
+ const MAX_HISTORY = 10;
30
+ const ExpoRouterDevTools = ({ position = 'top', theme = 'light', hideInProduction = true, storageKeyPrefix = STORAGE_PREFIX, onRouteChange, enableHistory = true, maxHistory = MAX_HISTORY, maxNumOfLines = 3, }) => {
31
+ const pathname = expoRouter.usePathname();
32
+ const searchParams = expoRouter.useGlobalSearchParams();
33
+ const router = expoRouter.useRouter();
34
+ const [currentRoute, setCurrentRoute] = react.useState('');
35
+ const [savedRoutes, setSavedRoutes] = react.useState([]);
36
+ const [routeHistory, setRouteHistory] = react.useState([]);
37
+ const [isExpanded, setIsExpanded] = react.useState(false);
38
+ const [showHistory, setShowHistory] = react.useState(false);
39
+ const SAVED_ROUTES_KEY = `${storageKeyPrefix}saved-routes`;
40
+ const HISTORY_KEY = `${storageKeyPrefix}history`;
41
+ // Build current full route
42
+ react.useEffect(() => {
43
+ const query = Object.keys(searchParams).length
44
+ ? '?' +
45
+ Object.entries(searchParams)
46
+ .map(([key, value]) => `${key}=${encodeURIComponent(String(value))}`)
47
+ .join('&')
48
+ : '';
49
+ const fullRoute = `${pathname}${query}`;
50
+ setCurrentRoute(fullRoute);
51
+ onRouteChange === null || onRouteChange === void 0 ? void 0 : onRouteChange(fullRoute);
52
+ }, [pathname, searchParams, onRouteChange]);
53
+ // Load saved routes and history
54
+ react.useEffect(() => {
55
+ const loadData = async () => {
56
+ try {
57
+ const savedRoutesData = await SecureStore__namespace.getItemAsync(SAVED_ROUTES_KEY);
58
+ if (savedRoutesData) {
59
+ setSavedRoutes(JSON.parse(savedRoutesData));
60
+ }
61
+ if (enableHistory) {
62
+ const historyData = await SecureStore__namespace.getItemAsync(HISTORY_KEY);
63
+ if (historyData) {
64
+ setRouteHistory(JSON.parse(historyData));
65
+ }
66
+ }
67
+ }
68
+ catch (error) {
69
+ console.error('[ExpoRouterDevTools] Error loading data:', error);
70
+ }
71
+ };
72
+ loadData();
73
+ }, [SAVED_ROUTES_KEY, HISTORY_KEY, enableHistory]);
74
+ // Update history when route changes
75
+ react.useEffect(() => {
76
+ if (!enableHistory || !currentRoute)
77
+ return;
78
+ const updateHistory = async () => {
79
+ try {
80
+ const newHistory = [currentRoute, ...routeHistory.filter((r) => r !== currentRoute)].slice(0, maxHistory);
81
+ setRouteHistory(newHistory);
82
+ await SecureStore__namespace.setItemAsync(HISTORY_KEY, JSON.stringify(newHistory));
83
+ }
84
+ catch (error) {
85
+ console.error('[ExpoRouterDevTools] Error updating history:', error);
86
+ }
87
+ };
88
+ updateHistory();
89
+ }, [currentRoute, enableHistory, maxHistory, HISTORY_KEY]);
90
+ // Save current route
91
+ const saveRoute = react.useCallback(async () => {
92
+ const label = `Route ${savedRoutes.length + 1}`;
93
+ const newRoute = {
94
+ route: currentRoute,
95
+ label,
96
+ timestamp: Date.now(),
97
+ };
98
+ const updated = [...savedRoutes, newRoute];
99
+ setSavedRoutes(updated);
100
+ try {
101
+ await SecureStore__namespace.setItemAsync(SAVED_ROUTES_KEY, JSON.stringify(updated));
102
+ }
103
+ catch (error) {
104
+ console.error('[ExpoRouterDevTools] Error saving route:', error);
105
+ }
106
+ }, [currentRoute, savedRoutes, SAVED_ROUTES_KEY]);
107
+ // Navigate to route
108
+ const navigateToRoute = react.useCallback((route) => {
109
+ try {
110
+ router.push(route);
111
+ }
112
+ catch (error) {
113
+ console.error('[ExpoRouterDevTools] Navigation error:', error);
114
+ }
115
+ }, [router]);
116
+ // Delete saved route
117
+ const deleteSavedRoute = react.useCallback(async (index) => {
118
+ const updated = savedRoutes.filter((_, i) => i !== index);
119
+ setSavedRoutes(updated);
120
+ try {
121
+ await SecureStore__namespace.setItemAsync(SAVED_ROUTES_KEY, JSON.stringify(updated));
122
+ }
123
+ catch (error) {
124
+ console.error('[ExpoRouterDevTools] Error deleting route:', error);
125
+ }
126
+ }, [savedRoutes, SAVED_ROUTES_KEY]);
127
+ // Clear all data
128
+ const clearAll = react.useCallback(async () => {
129
+ setSavedRoutes([]);
130
+ setRouteHistory([]);
131
+ try {
132
+ await SecureStore__namespace.deleteItemAsync(SAVED_ROUTES_KEY);
133
+ await SecureStore__namespace.deleteItemAsync(HISTORY_KEY);
134
+ }
135
+ catch (error) {
136
+ console.error('[ExpoRouterDevTools] Error clearing data:', error);
137
+ }
138
+ }, [SAVED_ROUTES_KEY, HISTORY_KEY]);
139
+ const isDark = theme === 'dark';
140
+ const styles = createStyles(isDark, position);
141
+ // Check if we should render in production
142
+ if (hideInProduction && !__DEV__) {
143
+ return null;
144
+ }
145
+ return (jsxRuntime.jsxs(reactNative.View, { style: styles.container, children: [jsxRuntime.jsxs(reactNative.Pressable, { onPress: () => setIsExpanded(!isExpanded), style: styles.routeBar, children: [jsxRuntime.jsxs(reactNative.Text, { style: styles.routeText, numberOfLines: maxNumOfLines, children: ["\uD83D\uDEE3\uFE0F ", currentRoute || '/'] }), jsxRuntime.jsx(reactNative.Text, { style: styles.expandIcon, children: isExpanded ? '▼' : '▶' })] }), isExpanded && (jsxRuntime.jsxs(reactNative.View, { style: styles.controls, children: [jsxRuntime.jsxs(reactNative.View, { style: styles.buttonRow, children: [jsxRuntime.jsx(reactNative.Pressable, { onPress: saveRoute, style: styles.button, children: jsxRuntime.jsx(reactNative.Text, { style: styles.buttonText, children: "Save" }) }), enableHistory && (jsxRuntime.jsx(reactNative.Pressable, { onPress: () => setShowHistory(!showHistory), style: styles.button, children: jsxRuntime.jsx(reactNative.Text, { style: styles.buttonText, children: "History" }) })), jsxRuntime.jsx(reactNative.Pressable, { onPress: clearAll, style: [styles.button, styles.dangerButton], children: jsxRuntime.jsx(reactNative.Text, { style: styles.buttonText, children: "Clear" }) })] }), showHistory && enableHistory && routeHistory.length > 0 && (jsxRuntime.jsxs(reactNative.View, { style: styles.section, children: [jsxRuntime.jsx(reactNative.Text, { style: styles.sectionTitle, children: "Recent Routes" }), jsxRuntime.jsx(reactNative.ScrollView, { style: styles.listContainer, children: routeHistory.map((route, index) => (jsxRuntime.jsx(reactNative.Pressable, { onPress: () => navigateToRoute(route), style: ({ pressed }) => [styles.listItem, route === currentRoute && styles.selectedItem, pressed && styles.listItemPressed], children: jsxRuntime.jsx(reactNative.Text, { style: styles.listItemText, numberOfLines: 1, children: route }) }, `${route}-${index}`))) })] })), savedRoutes.length > 0 && (jsxRuntime.jsxs(reactNative.View, { style: styles.section, children: [jsxRuntime.jsx(reactNative.Text, { style: styles.sectionTitle, children: "Saved Routes" }), jsxRuntime.jsx(reactNative.ScrollView, { style: styles.listContainer, children: savedRoutes.map((saved, index) => (jsxRuntime.jsxs(reactNative.Pressable, { onPress: () => navigateToRoute(saved.route), style: ({ pressed }) => [styles.savedItem, saved.route === currentRoute && styles.selectedItem, pressed && styles.listItemPressed], children: [jsxRuntime.jsxs(reactNative.View, { style: styles.savedItemContent, children: [jsxRuntime.jsx(reactNative.Text, { style: styles.savedItemLabel, children: saved.label }), jsxRuntime.jsx(reactNative.Text, { style: styles.listItemText, numberOfLines: 1, children: saved.route })] }), jsxRuntime.jsx(reactNative.Pressable, { onPress: (e) => {
146
+ var _a;
147
+ (_a = e.stopPropagation) === null || _a === void 0 ? void 0 : _a.call(e);
148
+ deleteSavedRoute(index);
149
+ }, style: styles.deleteButton, children: jsxRuntime.jsx(reactNative.Text, { style: styles.deleteButtonText, children: "\u2715" }) })] }, `${saved.route}-${index}`))) })] }))] }))] }));
150
+ };
151
+ const createStyles = (isDark, position) => {
152
+ const bgColor = isDark ? '#1a1a1a' : '#ffffff';
153
+ const textColor = isDark ? '#e0e0e0' : '#333333';
154
+ const borderColor = isDark ? '#333333' : '#dddddd';
155
+ const buttonBg = isDark ? '#2563eb' : '#2563eb';
156
+ const secondaryBg = isDark ? '#262626' : '#f5f5f5';
157
+ const pressedBg = isDark ? '#1e40af' : '#dbeafe';
158
+ return reactNative.StyleSheet.create({
159
+ container: {
160
+ backgroundColor: bgColor,
161
+ borderTopWidth: position === 'bottom' ? 1 : 0,
162
+ borderBottomWidth: position === 'top' ? 1 : 0,
163
+ borderColor,
164
+ ...reactNative.Platform.select({
165
+ ios: {
166
+ shadowColor: '#000',
167
+ shadowOffset: { width: 0, height: 2 },
168
+ shadowOpacity: 0.1,
169
+ shadowRadius: 4,
170
+ },
171
+ android: {
172
+ elevation: 4,
173
+ },
174
+ }),
175
+ },
176
+ selectedItem: {
177
+ backgroundColor: pressedBg,
178
+ borderWidth: 1,
179
+ borderColor: '#2563eb',
180
+ },
181
+ routeBar: {
182
+ flexDirection: 'row',
183
+ alignItems: 'center',
184
+ justifyContent: 'space-between',
185
+ padding: 12,
186
+ paddingHorizontal: 16,
187
+ },
188
+ routeText: {
189
+ flex: 1,
190
+ fontSize: 12,
191
+ color: textColor,
192
+ fontFamily: reactNative.Platform.OS === 'ios' ? 'Menlo' : 'monospace',
193
+ },
194
+ expandIcon: {
195
+ fontSize: 16,
196
+ color: textColor,
197
+ marginLeft: 8,
198
+ },
199
+ controls: {
200
+ padding: 12,
201
+ paddingTop: 0,
202
+ },
203
+ buttonRow: {
204
+ flexDirection: 'row',
205
+ gap: 8,
206
+ marginBottom: 12,
207
+ },
208
+ button: {
209
+ flex: 1,
210
+ paddingHorizontal: 12,
211
+ paddingVertical: 8,
212
+ backgroundColor: buttonBg,
213
+ borderRadius: 6,
214
+ alignItems: 'center',
215
+ },
216
+ dangerButton: {
217
+ backgroundColor: '#dc2626',
218
+ },
219
+ buttonText: {
220
+ color: '#ffffff',
221
+ fontSize: 12,
222
+ fontWeight: '600',
223
+ },
224
+ section: {
225
+ marginTop: 12,
226
+ },
227
+ sectionTitle: {
228
+ fontSize: 11,
229
+ fontWeight: '600',
230
+ color: textColor,
231
+ marginBottom: 8,
232
+ textTransform: 'uppercase',
233
+ letterSpacing: 0.5,
234
+ },
235
+ listContainer: {
236
+ maxHeight: 150,
237
+ },
238
+ listItem: {
239
+ padding: 8,
240
+ backgroundColor: secondaryBg,
241
+ borderRadius: 4,
242
+ marginBottom: 4,
243
+ },
244
+ listItemPressed: {
245
+ backgroundColor: pressedBg,
246
+ },
247
+ listItemText: {
248
+ fontSize: 11,
249
+ color: textColor,
250
+ fontFamily: reactNative.Platform.OS === 'ios' ? 'Menlo' : 'monospace',
251
+ },
252
+ savedItem: {
253
+ flexDirection: 'row',
254
+ alignItems: 'center',
255
+ backgroundColor: secondaryBg,
256
+ borderRadius: 4,
257
+ marginBottom: 4,
258
+ overflow: 'hidden',
259
+ },
260
+ savedItemContent: {
261
+ flex: 1,
262
+ padding: 8,
263
+ },
264
+ savedItemLabel: {
265
+ fontSize: 10,
266
+ fontWeight: '600',
267
+ color: buttonBg,
268
+ marginBottom: 2,
269
+ },
270
+ deleteButton: {
271
+ padding: 8,
272
+ paddingHorizontal: 12,
273
+ backgroundColor: '#dc2626',
274
+ },
275
+ deleteButtonText: {
276
+ color: '#ffffff',
277
+ fontSize: 14,
278
+ fontWeight: 'bold',
279
+ },
280
+ });
281
+ };
282
+
283
+ exports.ExpoRouterDevTools = ExpoRouterDevTools;
284
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/ExpoRouterDevTools.tsx"],"sourcesContent":["import { useGlobalSearchParams, usePathname, useRouter, type RelativePathString } from 'expo-router'\nimport * as SecureStore from 'expo-secure-store'\nimport React, { useCallback, useEffect, useState } from 'react'\nimport { Platform, Pressable, ScrollView, StyleSheet, Text, View } from 'react-native'\nimport { ExpoRouterDevToolsProps, SavedRoute } from './interfaces/base'\n\nconst STORAGE_PREFIX = 'expo-router-devtools_'\nconst MAX_HISTORY = 10\n\nconst ExpoRouterDevTools: React.FC<ExpoRouterDevToolsProps> = ({\n position = 'top',\n theme = 'light',\n hideInProduction = true,\n storageKeyPrefix = STORAGE_PREFIX,\n onRouteChange,\n enableHistory = true,\n maxHistory = MAX_HISTORY,\n maxNumOfLines = 3,\n}) => {\n const pathname = usePathname()\n const searchParams = useGlobalSearchParams()\n const router = useRouter()\n\n const [currentRoute, setCurrentRoute] = useState('')\n const [savedRoutes, setSavedRoutes] = useState<SavedRoute[]>([])\n const [routeHistory, setRouteHistory] = useState<string[]>([])\n const [isExpanded, setIsExpanded] = useState(false)\n const [showHistory, setShowHistory] = useState(false)\n\n const SAVED_ROUTES_KEY = `${storageKeyPrefix}saved-routes`\n const HISTORY_KEY = `${storageKeyPrefix}history`\n\n // Build current full route\n useEffect(() => {\n const query = Object.keys(searchParams).length\n ? '?' +\n Object.entries(searchParams)\n .map(([key, value]) => `${key}=${encodeURIComponent(String(value))}`)\n .join('&')\n : ''\n\n const fullRoute = `${pathname}${query}`\n setCurrentRoute(fullRoute)\n onRouteChange?.(fullRoute)\n }, [pathname, searchParams, onRouteChange])\n\n // Load saved routes and history\n useEffect(() => {\n const loadData = async () => {\n try {\n const savedRoutesData = await SecureStore.getItemAsync(SAVED_ROUTES_KEY)\n if (savedRoutesData) {\n setSavedRoutes(JSON.parse(savedRoutesData))\n }\n\n if (enableHistory) {\n const historyData = await SecureStore.getItemAsync(HISTORY_KEY)\n if (historyData) {\n setRouteHistory(JSON.parse(historyData))\n }\n }\n } catch (error) {\n console.error('[ExpoRouterDevTools] Error loading data:', error)\n }\n }\n\n loadData()\n }, [SAVED_ROUTES_KEY, HISTORY_KEY, enableHistory])\n\n // Update history when route changes\n useEffect(() => {\n if (!enableHistory || !currentRoute) return\n\n const updateHistory = async () => {\n try {\n const newHistory = [currentRoute, ...routeHistory.filter((r) => r !== currentRoute)].slice(0, maxHistory)\n setRouteHistory(newHistory)\n await SecureStore.setItemAsync(HISTORY_KEY, JSON.stringify(newHistory))\n } catch (error) {\n console.error('[ExpoRouterDevTools] Error updating history:', error)\n }\n }\n\n updateHistory()\n }, [currentRoute, enableHistory, maxHistory, HISTORY_KEY])\n\n // Save current route\n const saveRoute = useCallback(async () => {\n const label = `Route ${savedRoutes.length + 1}`\n const newRoute: SavedRoute = {\n route: currentRoute,\n label,\n timestamp: Date.now(),\n }\n\n const updated = [...savedRoutes, newRoute]\n setSavedRoutes(updated)\n\n try {\n await SecureStore.setItemAsync(SAVED_ROUTES_KEY, JSON.stringify(updated))\n } catch (error) {\n console.error('[ExpoRouterDevTools] Error saving route:', error)\n }\n }, [currentRoute, savedRoutes, SAVED_ROUTES_KEY])\n\n // Navigate to route\n const navigateToRoute = useCallback(\n (route: string) => {\n try {\n router.push(route as RelativePathString)\n } catch (error) {\n console.error('[ExpoRouterDevTools] Navigation error:', error)\n }\n },\n [router]\n )\n\n // Delete saved route\n const deleteSavedRoute = useCallback(\n async (index: number) => {\n const updated = savedRoutes.filter((_, i) => i !== index)\n setSavedRoutes(updated)\n\n try {\n await SecureStore.setItemAsync(SAVED_ROUTES_KEY, JSON.stringify(updated))\n } catch (error) {\n console.error('[ExpoRouterDevTools] Error deleting route:', error)\n }\n },\n [savedRoutes, SAVED_ROUTES_KEY]\n )\n\n // Clear all data\n const clearAll = useCallback(async () => {\n setSavedRoutes([])\n setRouteHistory([])\n\n try {\n await SecureStore.deleteItemAsync(SAVED_ROUTES_KEY)\n await SecureStore.deleteItemAsync(HISTORY_KEY)\n } catch (error) {\n console.error('[ExpoRouterDevTools] Error clearing data:', error)\n }\n }, [SAVED_ROUTES_KEY, HISTORY_KEY])\n\n const isDark = theme === 'dark'\n const styles = createStyles(isDark, position)\n\n // Check if we should render in production\n if (hideInProduction && !__DEV__) {\n return null\n }\n\n return (\n <View style={styles.container}>\n {/* Current route bar */}\n <Pressable onPress={() => setIsExpanded(!isExpanded)} style={styles.routeBar}>\n <Text style={styles.routeText} numberOfLines={maxNumOfLines}>\n 🛣️ {currentRoute || '/'}\n </Text>\n <Text style={styles.expandIcon}>{isExpanded ? '▼' : '▶'}</Text>\n </Pressable>\n\n {/* Expanded controls */}\n {isExpanded && (\n <View style={styles.controls}>\n {/* Action buttons */}\n <View style={styles.buttonRow}>\n <Pressable onPress={saveRoute} style={styles.button}>\n <Text style={styles.buttonText}>Save</Text>\n </Pressable>\n\n {enableHistory && (\n <Pressable onPress={() => setShowHistory(!showHistory)} style={styles.button}>\n <Text style={styles.buttonText}>History</Text>\n </Pressable>\n )}\n\n <Pressable onPress={clearAll} style={[styles.button, styles.dangerButton]}>\n <Text style={styles.buttonText}>Clear</Text>\n </Pressable>\n </View>\n\n {/* History section */}\n {showHistory && enableHistory && routeHistory.length > 0 && (\n <View style={styles.section}>\n <Text style={styles.sectionTitle}>Recent Routes</Text>\n <ScrollView style={styles.listContainer}>\n {routeHistory.map((route, index) => (\n <Pressable\n key={`${route}-${index}`}\n onPress={() => navigateToRoute(route)}\n style={({ pressed }) => [styles.listItem, route === currentRoute && styles.selectedItem, pressed && styles.listItemPressed]}\n >\n <Text style={styles.listItemText} numberOfLines={1}>\n {route}\n </Text>\n </Pressable>\n ))}\n </ScrollView>\n </View>\n )}\n\n {/* Saved routes section */}\n {savedRoutes.length > 0 && (\n <View style={styles.section}>\n <Text style={styles.sectionTitle}>Saved Routes</Text>\n <ScrollView style={styles.listContainer}>\n {savedRoutes.map((saved, index) => (\n <Pressable\n key={`${saved.route}-${index}`}\n onPress={() => navigateToRoute(saved.route)}\n style={({ pressed }) => [styles.savedItem, saved.route === currentRoute && styles.selectedItem, pressed && styles.listItemPressed]}\n >\n <View style={styles.savedItemContent}>\n <Text style={styles.savedItemLabel}>{saved.label}</Text>\n <Text style={styles.listItemText} numberOfLines={1}>\n {saved.route}\n </Text>\n </View>\n <Pressable\n onPress={(e) => {\n e.stopPropagation?.()\n deleteSavedRoute(index)\n }}\n style={styles.deleteButton}\n >\n <Text style={styles.deleteButtonText}>✕</Text>\n </Pressable>\n </Pressable>\n ))}\n </ScrollView>\n </View>\n )}\n </View>\n )}\n </View>\n )\n}\n\nconst createStyles = (isDark: boolean, position: 'top' | 'bottom') => {\n const bgColor = isDark ? '#1a1a1a' : '#ffffff'\n const textColor = isDark ? '#e0e0e0' : '#333333'\n const borderColor = isDark ? '#333333' : '#dddddd'\n const buttonBg = isDark ? '#2563eb' : '#2563eb'\n const secondaryBg = isDark ? '#262626' : '#f5f5f5'\n const pressedBg = isDark ? '#1e40af' : '#dbeafe'\n\n return StyleSheet.create({\n container: {\n backgroundColor: bgColor,\n borderTopWidth: position === 'bottom' ? 1 : 0,\n borderBottomWidth: position === 'top' ? 1 : 0,\n borderColor,\n ...Platform.select({\n ios: {\n shadowColor: '#000',\n shadowOffset: { width: 0, height: 2 },\n shadowOpacity: 0.1,\n shadowRadius: 4,\n },\n android: {\n elevation: 4,\n },\n }),\n },\n selectedItem: {\n backgroundColor: pressedBg,\n borderWidth: 1,\n borderColor: '#2563eb',\n },\n\n routeBar: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: 12,\n paddingHorizontal: 16,\n },\n routeText: {\n flex: 1,\n fontSize: 12,\n color: textColor,\n fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',\n },\n expandIcon: {\n fontSize: 16,\n color: textColor,\n marginLeft: 8,\n },\n controls: {\n padding: 12,\n paddingTop: 0,\n },\n buttonRow: {\n flexDirection: 'row',\n gap: 8,\n marginBottom: 12,\n },\n button: {\n flex: 1,\n paddingHorizontal: 12,\n paddingVertical: 8,\n backgroundColor: buttonBg,\n borderRadius: 6,\n alignItems: 'center',\n },\n dangerButton: {\n backgroundColor: '#dc2626',\n },\n buttonText: {\n color: '#ffffff',\n fontSize: 12,\n fontWeight: '600',\n },\n section: {\n marginTop: 12,\n },\n sectionTitle: {\n fontSize: 11,\n fontWeight: '600',\n color: textColor,\n marginBottom: 8,\n textTransform: 'uppercase',\n letterSpacing: 0.5,\n },\n listContainer: {\n maxHeight: 150,\n },\n listItem: {\n padding: 8,\n backgroundColor: secondaryBg,\n borderRadius: 4,\n marginBottom: 4,\n },\n listItemPressed: {\n backgroundColor: pressedBg,\n },\n listItemText: {\n fontSize: 11,\n color: textColor,\n fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',\n },\n savedItem: {\n flexDirection: 'row',\n alignItems: 'center',\n backgroundColor: secondaryBg,\n borderRadius: 4,\n marginBottom: 4,\n overflow: 'hidden',\n },\n savedItemContent: {\n flex: 1,\n padding: 8,\n },\n savedItemLabel: {\n fontSize: 10,\n fontWeight: '600',\n color: buttonBg,\n marginBottom: 2,\n },\n deleteButton: {\n padding: 8,\n paddingHorizontal: 12,\n backgroundColor: '#dc2626',\n },\n deleteButtonText: {\n color: '#ffffff',\n fontSize: 14,\n fontWeight: 'bold',\n },\n })\n}\n\nexport default ExpoRouterDevTools\n"],"names":["usePathname","useGlobalSearchParams","useRouter","useState","useEffect","SecureStore","useCallback","_jsxs","View","Pressable","Text","_jsx","ScrollView","StyleSheet","Platform"],"mappings":"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"}
@@ -0,0 +1,261 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useGlobalSearchParams, usePathname, useRouter } from 'expo-router';
3
+ import * as SecureStore from 'expo-secure-store';
4
+ import { useCallback, useEffect, useState } from 'react';
5
+ import { Platform, Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
6
+ const STORAGE_PREFIX = 'expo-router-devtools_';
7
+ const MAX_HISTORY = 10;
8
+ const ExpoRouterDevTools = ({ position = 'top', theme = 'light', hideInProduction = true, storageKeyPrefix = STORAGE_PREFIX, onRouteChange, enableHistory = true, maxHistory = MAX_HISTORY, maxNumOfLines = 3, }) => {
9
+ const pathname = usePathname();
10
+ const searchParams = useGlobalSearchParams();
11
+ const router = useRouter();
12
+ const [currentRoute, setCurrentRoute] = useState('');
13
+ const [savedRoutes, setSavedRoutes] = useState([]);
14
+ const [routeHistory, setRouteHistory] = useState([]);
15
+ const [isExpanded, setIsExpanded] = useState(false);
16
+ const [showHistory, setShowHistory] = useState(false);
17
+ const SAVED_ROUTES_KEY = `${storageKeyPrefix}saved-routes`;
18
+ const HISTORY_KEY = `${storageKeyPrefix}history`;
19
+ // Build current full route
20
+ useEffect(() => {
21
+ const query = Object.keys(searchParams).length
22
+ ? '?' +
23
+ Object.entries(searchParams)
24
+ .map(([key, value]) => `${key}=${encodeURIComponent(String(value))}`)
25
+ .join('&')
26
+ : '';
27
+ const fullRoute = `${pathname}${query}`;
28
+ setCurrentRoute(fullRoute);
29
+ onRouteChange === null || onRouteChange === void 0 ? void 0 : onRouteChange(fullRoute);
30
+ }, [pathname, searchParams, onRouteChange]);
31
+ // Load saved routes and history
32
+ useEffect(() => {
33
+ const loadData = async () => {
34
+ try {
35
+ const savedRoutesData = await SecureStore.getItemAsync(SAVED_ROUTES_KEY);
36
+ if (savedRoutesData) {
37
+ setSavedRoutes(JSON.parse(savedRoutesData));
38
+ }
39
+ if (enableHistory) {
40
+ const historyData = await SecureStore.getItemAsync(HISTORY_KEY);
41
+ if (historyData) {
42
+ setRouteHistory(JSON.parse(historyData));
43
+ }
44
+ }
45
+ }
46
+ catch (error) {
47
+ console.error('[ExpoRouterDevTools] Error loading data:', error);
48
+ }
49
+ };
50
+ loadData();
51
+ }, [SAVED_ROUTES_KEY, HISTORY_KEY, enableHistory]);
52
+ // Update history when route changes
53
+ useEffect(() => {
54
+ if (!enableHistory || !currentRoute)
55
+ return;
56
+ const updateHistory = async () => {
57
+ try {
58
+ const newHistory = [currentRoute, ...routeHistory.filter((r) => r !== currentRoute)].slice(0, maxHistory);
59
+ setRouteHistory(newHistory);
60
+ await SecureStore.setItemAsync(HISTORY_KEY, JSON.stringify(newHistory));
61
+ }
62
+ catch (error) {
63
+ console.error('[ExpoRouterDevTools] Error updating history:', error);
64
+ }
65
+ };
66
+ updateHistory();
67
+ }, [currentRoute, enableHistory, maxHistory, HISTORY_KEY]);
68
+ // Save current route
69
+ const saveRoute = useCallback(async () => {
70
+ const label = `Route ${savedRoutes.length + 1}`;
71
+ const newRoute = {
72
+ route: currentRoute,
73
+ label,
74
+ timestamp: Date.now(),
75
+ };
76
+ const updated = [...savedRoutes, newRoute];
77
+ setSavedRoutes(updated);
78
+ try {
79
+ await SecureStore.setItemAsync(SAVED_ROUTES_KEY, JSON.stringify(updated));
80
+ }
81
+ catch (error) {
82
+ console.error('[ExpoRouterDevTools] Error saving route:', error);
83
+ }
84
+ }, [currentRoute, savedRoutes, SAVED_ROUTES_KEY]);
85
+ // Navigate to route
86
+ const navigateToRoute = useCallback((route) => {
87
+ try {
88
+ router.push(route);
89
+ }
90
+ catch (error) {
91
+ console.error('[ExpoRouterDevTools] Navigation error:', error);
92
+ }
93
+ }, [router]);
94
+ // Delete saved route
95
+ const deleteSavedRoute = useCallback(async (index) => {
96
+ const updated = savedRoutes.filter((_, i) => i !== index);
97
+ setSavedRoutes(updated);
98
+ try {
99
+ await SecureStore.setItemAsync(SAVED_ROUTES_KEY, JSON.stringify(updated));
100
+ }
101
+ catch (error) {
102
+ console.error('[ExpoRouterDevTools] Error deleting route:', error);
103
+ }
104
+ }, [savedRoutes, SAVED_ROUTES_KEY]);
105
+ // Clear all data
106
+ const clearAll = useCallback(async () => {
107
+ setSavedRoutes([]);
108
+ setRouteHistory([]);
109
+ try {
110
+ await SecureStore.deleteItemAsync(SAVED_ROUTES_KEY);
111
+ await SecureStore.deleteItemAsync(HISTORY_KEY);
112
+ }
113
+ catch (error) {
114
+ console.error('[ExpoRouterDevTools] Error clearing data:', error);
115
+ }
116
+ }, [SAVED_ROUTES_KEY, HISTORY_KEY]);
117
+ const isDark = theme === 'dark';
118
+ const styles = createStyles(isDark, position);
119
+ // Check if we should render in production
120
+ if (hideInProduction && !__DEV__) {
121
+ return null;
122
+ }
123
+ return (_jsxs(View, { style: styles.container, children: [_jsxs(Pressable, { onPress: () => setIsExpanded(!isExpanded), style: styles.routeBar, children: [_jsxs(Text, { style: styles.routeText, numberOfLines: maxNumOfLines, children: ["\uD83D\uDEE3\uFE0F ", currentRoute || '/'] }), _jsx(Text, { style: styles.expandIcon, children: isExpanded ? '▼' : '▶' })] }), isExpanded && (_jsxs(View, { style: styles.controls, children: [_jsxs(View, { style: styles.buttonRow, children: [_jsx(Pressable, { onPress: saveRoute, style: styles.button, children: _jsx(Text, { style: styles.buttonText, children: "Save" }) }), enableHistory && (_jsx(Pressable, { onPress: () => setShowHistory(!showHistory), style: styles.button, children: _jsx(Text, { style: styles.buttonText, children: "History" }) })), _jsx(Pressable, { onPress: clearAll, style: [styles.button, styles.dangerButton], children: _jsx(Text, { style: styles.buttonText, children: "Clear" }) })] }), showHistory && enableHistory && routeHistory.length > 0 && (_jsxs(View, { style: styles.section, children: [_jsx(Text, { style: styles.sectionTitle, children: "Recent Routes" }), _jsx(ScrollView, { style: styles.listContainer, children: routeHistory.map((route, index) => (_jsx(Pressable, { onPress: () => navigateToRoute(route), style: ({ pressed }) => [styles.listItem, route === currentRoute && styles.selectedItem, pressed && styles.listItemPressed], children: _jsx(Text, { style: styles.listItemText, numberOfLines: 1, children: route }) }, `${route}-${index}`))) })] })), savedRoutes.length > 0 && (_jsxs(View, { style: styles.section, children: [_jsx(Text, { style: styles.sectionTitle, children: "Saved Routes" }), _jsx(ScrollView, { style: styles.listContainer, children: savedRoutes.map((saved, index) => (_jsxs(Pressable, { onPress: () => navigateToRoute(saved.route), style: ({ pressed }) => [styles.savedItem, saved.route === currentRoute && styles.selectedItem, pressed && styles.listItemPressed], children: [_jsxs(View, { style: styles.savedItemContent, children: [_jsx(Text, { style: styles.savedItemLabel, children: saved.label }), _jsx(Text, { style: styles.listItemText, numberOfLines: 1, children: saved.route })] }), _jsx(Pressable, { onPress: (e) => {
124
+ var _a;
125
+ (_a = e.stopPropagation) === null || _a === void 0 ? void 0 : _a.call(e);
126
+ deleteSavedRoute(index);
127
+ }, style: styles.deleteButton, children: _jsx(Text, { style: styles.deleteButtonText, children: "\u2715" }) })] }, `${saved.route}-${index}`))) })] }))] }))] }));
128
+ };
129
+ const createStyles = (isDark, position) => {
130
+ const bgColor = isDark ? '#1a1a1a' : '#ffffff';
131
+ const textColor = isDark ? '#e0e0e0' : '#333333';
132
+ const borderColor = isDark ? '#333333' : '#dddddd';
133
+ const buttonBg = isDark ? '#2563eb' : '#2563eb';
134
+ const secondaryBg = isDark ? '#262626' : '#f5f5f5';
135
+ const pressedBg = isDark ? '#1e40af' : '#dbeafe';
136
+ return StyleSheet.create({
137
+ container: {
138
+ backgroundColor: bgColor,
139
+ borderTopWidth: position === 'bottom' ? 1 : 0,
140
+ borderBottomWidth: position === 'top' ? 1 : 0,
141
+ borderColor,
142
+ ...Platform.select({
143
+ ios: {
144
+ shadowColor: '#000',
145
+ shadowOffset: { width: 0, height: 2 },
146
+ shadowOpacity: 0.1,
147
+ shadowRadius: 4,
148
+ },
149
+ android: {
150
+ elevation: 4,
151
+ },
152
+ }),
153
+ },
154
+ selectedItem: {
155
+ backgroundColor: pressedBg,
156
+ borderWidth: 1,
157
+ borderColor: '#2563eb',
158
+ },
159
+ routeBar: {
160
+ flexDirection: 'row',
161
+ alignItems: 'center',
162
+ justifyContent: 'space-between',
163
+ padding: 12,
164
+ paddingHorizontal: 16,
165
+ },
166
+ routeText: {
167
+ flex: 1,
168
+ fontSize: 12,
169
+ color: textColor,
170
+ fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
171
+ },
172
+ expandIcon: {
173
+ fontSize: 16,
174
+ color: textColor,
175
+ marginLeft: 8,
176
+ },
177
+ controls: {
178
+ padding: 12,
179
+ paddingTop: 0,
180
+ },
181
+ buttonRow: {
182
+ flexDirection: 'row',
183
+ gap: 8,
184
+ marginBottom: 12,
185
+ },
186
+ button: {
187
+ flex: 1,
188
+ paddingHorizontal: 12,
189
+ paddingVertical: 8,
190
+ backgroundColor: buttonBg,
191
+ borderRadius: 6,
192
+ alignItems: 'center',
193
+ },
194
+ dangerButton: {
195
+ backgroundColor: '#dc2626',
196
+ },
197
+ buttonText: {
198
+ color: '#ffffff',
199
+ fontSize: 12,
200
+ fontWeight: '600',
201
+ },
202
+ section: {
203
+ marginTop: 12,
204
+ },
205
+ sectionTitle: {
206
+ fontSize: 11,
207
+ fontWeight: '600',
208
+ color: textColor,
209
+ marginBottom: 8,
210
+ textTransform: 'uppercase',
211
+ letterSpacing: 0.5,
212
+ },
213
+ listContainer: {
214
+ maxHeight: 150,
215
+ },
216
+ listItem: {
217
+ padding: 8,
218
+ backgroundColor: secondaryBg,
219
+ borderRadius: 4,
220
+ marginBottom: 4,
221
+ },
222
+ listItemPressed: {
223
+ backgroundColor: pressedBg,
224
+ },
225
+ listItemText: {
226
+ fontSize: 11,
227
+ color: textColor,
228
+ fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
229
+ },
230
+ savedItem: {
231
+ flexDirection: 'row',
232
+ alignItems: 'center',
233
+ backgroundColor: secondaryBg,
234
+ borderRadius: 4,
235
+ marginBottom: 4,
236
+ overflow: 'hidden',
237
+ },
238
+ savedItemContent: {
239
+ flex: 1,
240
+ padding: 8,
241
+ },
242
+ savedItemLabel: {
243
+ fontSize: 10,
244
+ fontWeight: '600',
245
+ color: buttonBg,
246
+ marginBottom: 2,
247
+ },
248
+ deleteButton: {
249
+ padding: 8,
250
+ paddingHorizontal: 12,
251
+ backgroundColor: '#dc2626',
252
+ },
253
+ deleteButtonText: {
254
+ color: '#ffffff',
255
+ fontSize: 14,
256
+ fontWeight: 'bold',
257
+ },
258
+ });
259
+ };
260
+ export default ExpoRouterDevTools;
261
+ //# sourceMappingURL=ExpoRouterDevTools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExpoRouterDevTools.js","sourceRoot":"","sources":["../../src/ExpoRouterDevTools.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { default as ExpoRouterDevTools } from './ExpoRouterDevTools';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/interfaces/base.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { ExpoRouterDevToolsProps } from './interfaces/base';
3
+ declare const ExpoRouterDevTools: React.FC<ExpoRouterDevToolsProps>;
4
+ export default ExpoRouterDevTools;
@@ -0,0 +1,2 @@
1
+ export { default as ExpoRouterDevTools } from './ExpoRouterDevTools';
2
+ export type { ExpoRouterDevToolsProps } from './interfaces/base';
@@ -0,0 +1,23 @@
1
+ export interface ExpoRouterDevToolsProps {
2
+ /** Position of the dev tools bar */
3
+ position?: 'top' | 'bottom';
4
+ /** Theme */
5
+ theme?: 'light' | 'dark';
6
+ /** Hide in production builds */
7
+ hideInProduction?: boolean;
8
+ /** Custom storage key prefix (alphanumeric, dots, dashes, and underscores only) */
9
+ storageKeyPrefix?: string;
10
+ /** Callback when route changes */
11
+ onRouteChange?: (route: string) => void;
12
+ /** Enable route history */
13
+ enableHistory?: boolean;
14
+ /** Maximum number of history items */
15
+ maxHistory?: number;
16
+ /** Maximum number of lines the route will show */
17
+ maxNumOfLines?: number;
18
+ }
19
+ export interface SavedRoute {
20
+ route: string;
21
+ label: string;
22
+ timestamp: number;
23
+ }
@@ -0,0 +1,23 @@
1
+ export interface ExpoRouterDevToolsProps {
2
+ /** Position of the dev tools bar */
3
+ position?: 'top' | 'bottom';
4
+ /** Theme */
5
+ theme?: 'light' | 'dark';
6
+ /** Hide in production builds */
7
+ hideInProduction?: boolean;
8
+ /** Custom storage key prefix (alphanumeric, dots, dashes, and underscores only) */
9
+ storageKeyPrefix?: string;
10
+ /** Callback when route changes */
11
+ onRouteChange?: (route: string) => void;
12
+ /** Enable route history */
13
+ enableHistory?: boolean;
14
+ /** Maximum number of history items */
15
+ maxHistory?: number;
16
+ /** Maximum number of lines the route will show */
17
+ maxNumOfLines?: number;
18
+ }
19
+ export interface SavedRoute {
20
+ route: string;
21
+ label: string;
22
+ timestamp: number;
23
+ }
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@novodip/expo-router-devtools",
3
+ "version": "1.0.0",
4
+ "description": "Development tools for Expo Router - visualize routes, save navigation states, and debug your app's navigation flow",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.esm.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "README.md",
11
+ "LICENSE"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc --outDir dist/lib --declarationDir dist/types --declaration true && rollup -c",
15
+ "prepare": "npm run build",
16
+ "test": "echo \"No tests yet\" && exit 0"
17
+ },
18
+ "keywords": [
19
+ "expo",
20
+ "expo-router",
21
+ "react-native",
22
+ "navigation",
23
+ "devtools",
24
+ "debugging",
25
+ "development",
26
+ "router",
27
+ "navigation-debug"
28
+ ],
29
+ "author": "Your Name",
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/Novo1999/expo-router-devtools.git"
34
+ },
35
+ "bugs": {
36
+ "url": "https://github.com/Novo1999/expo-router-devtools/issues"
37
+ },
38
+ "homepage": "https://github.com/Novo1999/expo-router-devtools#readme",
39
+ "peerDependencies": {
40
+ "expo-router": ">=3.0.0",
41
+ "expo-secure-store": ">=12.0.0",
42
+ "react": ">=18.0.0",
43
+ "react-native": ">=0.70.0"
44
+ },
45
+ "devDependencies": {
46
+ "@rollup/plugin-commonjs": "^29.0.0",
47
+ "@rollup/plugin-node-resolve": "^16.0.3",
48
+ "@rollup/plugin-typescript": "^12.3.0",
49
+ "@types/react": "^19.2.7",
50
+ "rollup": "^3.29.0",
51
+ "rollup-plugin-typescript2": "^0.36.0",
52
+ "typescript": "^5.2.0"
53
+ }
54
+ }