rn-backstage 1.2.0 → 1.3.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.
Files changed (110) hide show
  1. package/README.md +84 -2
  2. package/lib/commonjs/Backstage.js +46 -33
  3. package/lib/commonjs/Backstage.js.map +1 -1
  4. package/lib/commonjs/ThemeContext.js +43 -0
  5. package/lib/commonjs/ThemeContext.js.map +1 -0
  6. package/lib/commonjs/components/BackstagePanel.js +35 -12
  7. package/lib/commonjs/components/BackstagePanel.js.map +1 -1
  8. package/lib/commonjs/components/FlagsTab.js +60 -57
  9. package/lib/commonjs/components/FlagsTab.js.map +1 -1
  10. package/lib/commonjs/components/FloatingPill.js +86 -24
  11. package/lib/commonjs/components/FloatingPill.js.map +1 -1
  12. package/lib/commonjs/components/InfoTab.js +77 -107
  13. package/lib/commonjs/components/InfoTab.js.map +1 -1
  14. package/lib/commonjs/components/JsonTreeView.js +39 -34
  15. package/lib/commonjs/components/JsonTreeView.js.map +1 -1
  16. package/lib/commonjs/components/LogItem.js +39 -29
  17. package/lib/commonjs/components/LogItem.js.map +1 -1
  18. package/lib/commonjs/components/LogsTab.js +39 -42
  19. package/lib/commonjs/components/LogsTab.js.map +1 -1
  20. package/lib/commonjs/components/NetworkItem.js +111 -135
  21. package/lib/commonjs/components/NetworkItem.js.map +1 -1
  22. package/lib/commonjs/components/NetworkTab.js +50 -49
  23. package/lib/commonjs/components/NetworkTab.js.map +1 -1
  24. package/lib/commonjs/components/StorageTab.js +655 -0
  25. package/lib/commonjs/components/StorageTab.js.map +1 -0
  26. package/lib/commonjs/components/TabBar.js +8 -5
  27. package/lib/commonjs/components/TabBar.js.map +1 -1
  28. package/lib/commonjs/constants.js +96 -7
  29. package/lib/commonjs/constants.js.map +1 -1
  30. package/lib/commonjs/index.js +96 -0
  31. package/lib/commonjs/index.js.map +1 -1
  32. package/lib/commonjs/types.js +1 -0
  33. package/lib/commonjs/types.js.map +1 -1
  34. package/lib/module/Backstage.js +46 -33
  35. package/lib/module/Backstage.js.map +1 -1
  36. package/lib/module/ThemeContext.js +37 -0
  37. package/lib/module/ThemeContext.js.map +1 -0
  38. package/lib/module/components/BackstagePanel.js +37 -14
  39. package/lib/module/components/BackstagePanel.js.map +1 -1
  40. package/lib/module/components/FlagsTab.js +61 -58
  41. package/lib/module/components/FlagsTab.js.map +1 -1
  42. package/lib/module/components/FloatingPill.js +90 -28
  43. package/lib/module/components/FloatingPill.js.map +1 -1
  44. package/lib/module/components/InfoTab.js +77 -107
  45. package/lib/module/components/InfoTab.js.map +1 -1
  46. package/lib/module/components/JsonTreeView.js +42 -38
  47. package/lib/module/components/JsonTreeView.js.map +1 -1
  48. package/lib/module/components/LogItem.js +41 -31
  49. package/lib/module/components/LogItem.js.map +1 -1
  50. package/lib/module/components/LogsTab.js +40 -43
  51. package/lib/module/components/LogsTab.js.map +1 -1
  52. package/lib/module/components/NetworkItem.js +113 -137
  53. package/lib/module/components/NetworkItem.js.map +1 -1
  54. package/lib/module/components/NetworkTab.js +51 -50
  55. package/lib/module/components/NetworkTab.js.map +1 -1
  56. package/lib/module/components/StorageTab.js +650 -0
  57. package/lib/module/components/StorageTab.js.map +1 -0
  58. package/lib/module/components/TabBar.js +10 -7
  59. package/lib/module/components/TabBar.js.map +1 -1
  60. package/lib/module/constants.js +95 -6
  61. package/lib/module/constants.js.map +1 -1
  62. package/lib/module/index.js +14 -0
  63. package/lib/module/index.js.map +1 -1
  64. package/lib/module/types.js +2 -0
  65. package/lib/module/types.js.map +1 -1
  66. package/lib/typescript/Backstage.d.ts.map +1 -1
  67. package/lib/typescript/ThemeContext.d.ts +11 -0
  68. package/lib/typescript/ThemeContext.d.ts.map +1 -0
  69. package/lib/typescript/components/BackstagePanel.d.ts +3 -1
  70. package/lib/typescript/components/BackstagePanel.d.ts.map +1 -1
  71. package/lib/typescript/components/FlagsTab.d.ts.map +1 -1
  72. package/lib/typescript/components/FloatingPill.d.ts +2 -0
  73. package/lib/typescript/components/FloatingPill.d.ts.map +1 -1
  74. package/lib/typescript/components/InfoTab.d.ts +1 -0
  75. package/lib/typescript/components/InfoTab.d.ts.map +1 -1
  76. package/lib/typescript/components/JsonTreeView.d.ts.map +1 -1
  77. package/lib/typescript/components/LogItem.d.ts +1 -0
  78. package/lib/typescript/components/LogItem.d.ts.map +1 -1
  79. package/lib/typescript/components/LogsTab.d.ts +1 -0
  80. package/lib/typescript/components/LogsTab.d.ts.map +1 -1
  81. package/lib/typescript/components/NetworkItem.d.ts +1 -0
  82. package/lib/typescript/components/NetworkItem.d.ts.map +1 -1
  83. package/lib/typescript/components/NetworkTab.d.ts +1 -0
  84. package/lib/typescript/components/NetworkTab.d.ts.map +1 -1
  85. package/lib/typescript/components/StorageTab.d.ts +9 -0
  86. package/lib/typescript/components/StorageTab.d.ts.map +1 -0
  87. package/lib/typescript/components/TabBar.d.ts.map +1 -1
  88. package/lib/typescript/constants.d.ts +60 -4
  89. package/lib/typescript/constants.d.ts.map +1 -1
  90. package/lib/typescript/index.d.ts +14 -1
  91. package/lib/typescript/index.d.ts.map +1 -1
  92. package/lib/typescript/types.d.ts +20 -0
  93. package/lib/typescript/types.d.ts.map +1 -1
  94. package/package.json +6 -4
  95. package/src/Backstage.tsx +45 -33
  96. package/src/ThemeContext.tsx +38 -0
  97. package/src/components/BackstagePanel.tsx +89 -61
  98. package/src/components/FlagsTab.tsx +125 -174
  99. package/src/components/FloatingPill.tsx +127 -30
  100. package/src/components/InfoTab.tsx +153 -186
  101. package/src/components/JsonTreeView.tsx +53 -73
  102. package/src/components/LogItem.tsx +64 -100
  103. package/src/components/LogsTab.tsx +110 -132
  104. package/src/components/NetworkItem.tsx +306 -417
  105. package/src/components/NetworkTab.tsx +129 -163
  106. package/src/components/StorageTab.tsx +607 -0
  107. package/src/components/TabBar.tsx +51 -47
  108. package/src/constants.ts +103 -4
  109. package/src/index.ts +17 -0
  110. package/src/types.ts +28 -0
@@ -58,6 +58,16 @@ export interface FeatureFlag {
58
58
  /** Optional description shown below the label */
59
59
  description?: string;
60
60
  }
61
+ export interface StorageAdapter {
62
+ /** Return all stored keys */
63
+ getAllKeys: () => Promise<string[]>;
64
+ /** Get value for a key. Return null if not found */
65
+ getItem: (key: string) => Promise<string | null>;
66
+ /** Set a value for a key */
67
+ setItem: (key: string, value: string) => Promise<void>;
68
+ /** Remove an entry by key */
69
+ removeItem: (key: string) => Promise<void>;
70
+ }
61
71
  export interface BackstageTab {
62
72
  key: string;
63
73
  title: string;
@@ -87,6 +97,8 @@ export interface BackstageTheme {
87
97
  export interface BackstageProps {
88
98
  /** Whether the floating pill trigger is visible. Default: true */
89
99
  visible?: boolean;
100
+ /** Theme preference: 'light', 'dark', or 'auto' (follows device setting). Default: 'auto' */
101
+ theme?: 'light' | 'dark' | 'auto';
90
102
  /** App version string (e.g., "1.2.3") */
91
103
  appVersion?: string;
92
104
  /** Build number (e.g., "42") */
@@ -103,6 +115,8 @@ export interface BackstageProps {
103
115
  featureFlags?: FeatureFlag[];
104
116
  /** Callback when a feature flag is toggled */
105
117
  onToggleFeatureFlag?: (key: string, value: boolean) => void;
118
+ /** Storage adapter for the Storage Viewer tab (AsyncStorage, MMKV, etc.) */
119
+ storageAdapter?: StorageAdapter;
106
120
  /** Maximum number of logs to retain in memory. Default: 500 */
107
121
  maxLogs?: number;
108
122
  /** Log messages containing these strings will be excluded */
@@ -121,6 +135,10 @@ export interface BackstageProps {
121
135
  initialY?: number;
122
136
  /** Text displayed on the floating pill. Defaults to appVersion or "DEV" */
123
137
  pillText?: string;
138
+ /** Width of the floating pill. Default: 60 */
139
+ pillWidth?: number;
140
+ /** Height of the floating pill. Default: 32 */
141
+ pillHeight?: number;
124
142
  /** Whether to enable network request interception. Default: true */
125
143
  enableNetworkInspector?: boolean;
126
144
  /** Maximum number of network entries to retain in memory. Default: 500 */
@@ -131,6 +149,8 @@ export interface BackstageProps {
131
149
  networkFilters?: string[];
132
150
  /** Auto-filter console.logs from network callbacks (e.g., Axios interceptors) out of the Logs tab. Default: true */
133
151
  autoFilterNetworkLogs?: boolean;
152
+ /** Max nesting depth for JSON tree views (state tree, log data, network bodies). Default: 10 */
153
+ jsonMaxDepth?: number;
134
154
  }
135
155
  export interface BackstageStyleOverrides {
136
156
  pillStyle?: StyleProp<ViewStyle>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rn-backstage",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "A zero-dependency developer/QA debug panel for React Native apps",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -16,6 +16,8 @@
16
16
  "!**/.*"
17
17
  ],
18
18
  "scripts": {
19
+ "example:ios": "cd example && npx expo run:ios",
20
+ "example:android": "cd example && npx expo run:android",
19
21
  "typecheck": "tsc --noEmit",
20
22
  "lint": "prettier --write \"**/*.{js,ts,tsx}\" && eslint \"**/*.{js,ts,tsx}\"",
21
23
  "prepack": "bob build",
@@ -44,12 +46,12 @@
44
46
  "access": "public"
45
47
  },
46
48
  "devDependencies": {
47
- "@types/react": "~18.3.0",
49
+ "@types/react": "~19.2.10",
48
50
  "del-cli": "^6.0.0",
49
51
  "eslint": "^9.0.0",
50
52
  "prettier": "^3.0.0",
51
- "react": "18.3.1",
52
- "react-native": "^0.78.0",
53
+ "react": "19.2.0",
54
+ "react-native": "0.83.4",
53
55
  "react-native-builder-bob": "^0.35.0",
54
56
  "release-it": "^18.0.0",
55
57
  "typescript": "^5.0.0",
package/src/Backstage.tsx CHANGED
@@ -16,6 +16,7 @@ import {
16
16
  } from './network-interceptor'
17
17
  import { FloatingPill } from './components/FloatingPill'
18
18
  import { BackstagePanel } from './components/BackstagePanel'
19
+ import { BackstageThemeProvider } from './ThemeContext'
19
20
  import type { BackstageProps, BackstageRef, LogEntry, NetworkEntry } from './types'
20
21
 
21
22
  // ─── Component ───────────────────────────────────────────────────────────────
@@ -24,6 +25,7 @@ export const Backstage = forwardRef<BackstageRef, BackstageProps>(
24
25
  (
25
26
  {
26
27
  visible = true,
28
+ theme: themePreference = 'auto',
27
29
  appVersion,
28
30
  buildNumber,
29
31
  bundleId,
@@ -32,6 +34,7 @@ export const Backstage = forwardRef<BackstageRef, BackstageProps>(
32
34
  quickActions,
33
35
  featureFlags,
34
36
  onToggleFeatureFlag,
37
+ storageAdapter,
35
38
  maxLogs = DEFAULT_MAX_LOGS,
36
39
  logFilters,
37
40
  onCopyLogs,
@@ -41,11 +44,14 @@ export const Backstage = forwardRef<BackstageRef, BackstageProps>(
41
44
  initialX,
42
45
  initialY,
43
46
  pillText,
47
+ pillWidth,
48
+ pillHeight,
44
49
  enableNetworkInspector = true,
45
50
  maxNetworkEntries = DEFAULT_MAX_NETWORK_ENTRIES,
46
51
  maxNetworkBodySize,
47
52
  networkFilters,
48
53
  autoFilterNetworkLogs = true,
54
+ jsonMaxDepth,
49
55
  },
50
56
  ref,
51
57
  ) => {
@@ -153,39 +159,45 @@ export const Backstage = forwardRef<BackstageRef, BackstageProps>(
153
159
  const displayText = pillText || (appVersion ? `v${appVersion}` : 'DEV')
154
160
 
155
161
  return (
156
- <View style={styles.container} pointerEvents="box-none">
157
- <FloatingPill
158
- text={displayText}
159
- hasError={hasError}
160
- onPress={openPanel}
161
- initialX={initialX}
162
- initialY={initialY}
163
- styles={propStyles}
164
- />
165
- <BackstagePanel
166
- visible={panelVisible}
167
- onClose={closePanel}
168
- appVersion={appVersion}
169
- buildNumber={buildNumber}
170
- bundleId={bundleId}
171
- deviceInfo={deviceInfo}
172
- state={state}
173
- quickActions={quickActions}
174
- featureFlags={featureFlags}
175
- onToggleFeatureFlag={onToggleFeatureFlag}
176
- logs={logs}
177
- onRefreshLogs={refreshLogs}
178
- onCopyLogs={onCopyLogs}
179
- networkEntries={networkEntries}
180
- onRefreshNetwork={refreshNetwork}
181
- onClearNetwork={clearNetwork}
182
- onCopyNetwork={onCopyLogs}
183
- extraTabs={extraTabs}
184
- styles={propStyles}
185
- >
186
- {children}
187
- </BackstagePanel>
188
- </View>
162
+ <BackstageThemeProvider preference={themePreference}>
163
+ <View style={styles.container} pointerEvents="box-none">
164
+ <FloatingPill
165
+ text={displayText}
166
+ hasError={hasError}
167
+ onPress={openPanel}
168
+ initialX={initialX}
169
+ initialY={initialY}
170
+ pillWidth={pillWidth}
171
+ pillHeight={pillHeight}
172
+ styles={propStyles}
173
+ />
174
+ <BackstagePanel
175
+ visible={panelVisible}
176
+ onClose={closePanel}
177
+ appVersion={appVersion}
178
+ buildNumber={buildNumber}
179
+ bundleId={bundleId}
180
+ deviceInfo={deviceInfo}
181
+ state={state}
182
+ quickActions={quickActions}
183
+ featureFlags={featureFlags}
184
+ onToggleFeatureFlag={onToggleFeatureFlag}
185
+ logs={logs}
186
+ onRefreshLogs={refreshLogs}
187
+ onCopyLogs={onCopyLogs}
188
+ networkEntries={networkEntries}
189
+ onRefreshNetwork={refreshNetwork}
190
+ onClearNetwork={clearNetwork}
191
+ onCopyNetwork={onCopyLogs}
192
+ extraTabs={extraTabs}
193
+ jsonMaxDepth={jsonMaxDepth}
194
+ storageAdapter={storageAdapter}
195
+ styles={propStyles}
196
+ >
197
+ {children}
198
+ </BackstagePanel>
199
+ </View>
200
+ </BackstageThemeProvider>
189
201
  )
190
202
  },
191
203
  )
@@ -0,0 +1,38 @@
1
+ import React, { createContext, useContext, useMemo } from 'react'
2
+ import { useColorScheme } from 'react-native'
3
+ import { DarkTheme, LightTheme } from './constants'
4
+ import type { BackstageTheme } from './types'
5
+
6
+ // ─── Theme Preference ────────────────────────────────────────────────────────
7
+
8
+ export type ThemePreference = 'light' | 'dark' | 'auto'
9
+
10
+ // ─── Context ─────────────────────────────────────────────────────────────────
11
+
12
+ const ThemeContext = createContext<BackstageTheme>(DarkTheme)
13
+
14
+ // ─── Provider ────────────────────────────────────────────────────────────────
15
+
16
+ interface ThemeProviderProps {
17
+ preference: ThemePreference
18
+ children: React.ReactNode
19
+ }
20
+
21
+ export const BackstageThemeProvider: React.FC<ThemeProviderProps> = ({ preference, children }) => {
22
+ const systemScheme = useColorScheme()
23
+
24
+ const theme = useMemo(() => {
25
+ if (preference === 'light') return LightTheme
26
+ if (preference === 'dark') return DarkTheme
27
+ // 'auto' — follow system, fallback to dark
28
+ return systemScheme === 'light' ? LightTheme : DarkTheme
29
+ }, [preference, systemScheme])
30
+
31
+ return <ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
32
+ }
33
+
34
+ // ─── Hook ────────────────────────────────────────────────────────────────────
35
+
36
+ export function useBackstageTheme(): BackstageTheme {
37
+ return useContext(ThemeContext)
38
+ }
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react'
1
+ import React, { useMemo, useState } from 'react'
2
2
  import {
3
3
  Modal,
4
4
  SafeAreaView,
@@ -8,12 +8,14 @@ import {
8
8
  TouchableOpacity,
9
9
  View,
10
10
  } from 'react-native'
11
- import { DarkTheme, MonospaceFont, TestIDs } from '../constants'
11
+ import { MonospaceFont, TestIDs } from '../constants'
12
+ import { useBackstageTheme } from '../ThemeContext'
12
13
  import { TabBar } from './TabBar'
13
14
  import { InfoTab } from './InfoTab'
14
15
  import { LogsTab } from './LogsTab'
15
16
  import { NetworkTab } from './NetworkTab'
16
17
  import { FlagsTab } from './FlagsTab'
18
+ import { StorageTab } from './StorageTab'
17
19
  import type {
18
20
  AppInfoItem,
19
21
  BackstageStyleOverrides,
@@ -22,6 +24,7 @@ import type {
22
24
  LogEntry,
23
25
  NetworkEntry,
24
26
  QuickAction,
27
+ StorageAdapter,
25
28
  } from '../types'
26
29
 
27
30
  // ─── Types ───────────────────────────────────────────────────────────────────
@@ -54,6 +57,12 @@ interface BackstagePanelProps {
54
57
  // Extensibility
55
58
  extraTabs?: BackstageTab[]
56
59
 
60
+ // JSON tree
61
+ jsonMaxDepth?: number
62
+
63
+ // Storage
64
+ storageAdapter?: StorageAdapter
65
+
57
66
  // Styling
58
67
  styles?: BackstageStyleOverrides
59
68
  children?: React.ReactNode
@@ -68,6 +77,8 @@ const ALWAYS_ON_TABS = [
68
77
 
69
78
  const FLAGS_TAB = { key: 'flags', title: 'Flags', icon: '🎚' }
70
79
 
80
+ const STORAGE_TAB = { key: 'storage', title: 'Storage', icon: '🗄' }
81
+
71
82
  const LOGS_TAB = { key: 'logs', title: 'Logs', icon: '📋' }
72
83
 
73
84
  // ─── Component ───────────────────────────────────────────────────────────────
@@ -91,16 +102,22 @@ export const BackstagePanel: React.FC<BackstagePanelProps> = ({
91
102
  onClearNetwork,
92
103
  onCopyNetwork,
93
104
  extraTabs = [],
105
+ jsonMaxDepth,
106
+ storageAdapter,
94
107
  styles: propStyles,
95
108
  children,
96
109
  }) => {
97
110
  const [activeTab, setActiveTab] = useState('info')
111
+ const theme = useBackstageTheme()
112
+ const styles = useMemo(() => createStyles(theme), [theme])
98
113
 
99
114
  // Compose all tabs: built-in (conditionally including Flags) + extra
100
115
  const hasFlags = featureFlags && featureFlags.length > 0
116
+ const hasStorage = !!storageAdapter
101
117
  const allTabs = [
102
118
  ...ALWAYS_ON_TABS,
103
119
  ...(hasFlags ? [FLAGS_TAB] : []),
120
+ ...(hasStorage ? [STORAGE_TAB] : []),
104
121
  LOGS_TAB,
105
122
  ...extraTabs.map(t => ({ key: t.key, title: t.title, icon: t.icon })),
106
123
  ]
@@ -117,6 +134,7 @@ export const BackstagePanel: React.FC<BackstagePanelProps> = ({
117
134
  deviceInfo={deviceInfo}
118
135
  state={state}
119
136
  quickActions={quickActions}
137
+ jsonMaxDepth={jsonMaxDepth}
120
138
  onClosePanel={onClose}
121
139
  styles={propStyles}
122
140
  >
@@ -124,12 +142,11 @@ export const BackstagePanel: React.FC<BackstagePanelProps> = ({
124
142
  </InfoTab>
125
143
  )
126
144
  case 'flags':
127
- return (
128
- <FlagsTab
129
- flags={featureFlags ?? []}
130
- onToggle={onToggleFeatureFlag}
131
- />
132
- )
145
+ return <FlagsTab flags={featureFlags ?? []} onToggle={onToggleFeatureFlag} />
146
+ case 'storage':
147
+ return storageAdapter ? (
148
+ <StorageTab adapter={storageAdapter} jsonMaxDepth={jsonMaxDepth} />
149
+ ) : null
133
150
  case 'network':
134
151
  return (
135
152
  <NetworkTab
@@ -137,6 +154,7 @@ export const BackstagePanel: React.FC<BackstagePanelProps> = ({
137
154
  onRefresh={onRefreshNetwork}
138
155
  onClear={onClearNetwork}
139
156
  onCopy={onCopyNetwork}
157
+ jsonMaxDepth={jsonMaxDepth}
140
158
  />
141
159
  )
142
160
  case 'logs':
@@ -145,6 +163,7 @@ export const BackstagePanel: React.FC<BackstagePanelProps> = ({
145
163
  logs={logs}
146
164
  onRefresh={onRefreshLogs}
147
165
  onCopyLogs={onCopyLogs}
166
+ jsonMaxDepth={jsonMaxDepth}
148
167
  styles={propStyles}
149
168
  />
150
169
  )
@@ -161,20 +180,28 @@ export const BackstagePanel: React.FC<BackstagePanelProps> = ({
161
180
 
162
181
  return (
163
182
  <Modal
164
- testID={TestIDs.panel}
183
+ testID={TestIDs.panelModal}
165
184
  animationType="slide"
166
185
  transparent={false}
167
186
  visible={visible}
168
187
  onRequestClose={onClose}
169
188
  statusBarTranslucent
170
189
  >
171
- <StatusBar barStyle="light-content" backgroundColor={DarkTheme.background} />
172
- <SafeAreaView style={[styles.safeArea, propStyles?.panelStyle]}>
190
+ <StatusBar
191
+ barStyle={theme.background < '#888' ? 'light-content' : 'dark-content'}
192
+ backgroundColor={theme.background}
193
+ />
194
+ <SafeAreaView testID={TestIDs.panel} style={[styles.safeArea, propStyles?.panelStyle]}>
173
195
  {/* ── Header ──────────────────────────────────────────── */}
174
- <View style={styles.header}>
196
+ <View testID={TestIDs.header.container} style={styles.header}>
175
197
  <View style={styles.headerLeft}>
176
198
  <Text style={styles.headerBrand}>⚙</Text>
177
- <Text style={[styles.headerTitle, propStyles?.headerTitleStyle]}>Backstage</Text>
199
+ <Text
200
+ testID={TestIDs.header.title}
201
+ style={[styles.headerTitle, propStyles?.headerTitleStyle]}
202
+ >
203
+ Backstage
204
+ </Text>
178
205
  </View>
179
206
  <TouchableOpacity
180
207
  testID={TestIDs.header.closeButton}
@@ -199,51 +226,52 @@ export const BackstagePanel: React.FC<BackstagePanelProps> = ({
199
226
 
200
227
  // ─── Styles ──────────────────────────────────────────────────────────────────
201
228
 
202
- const styles = StyleSheet.create({
203
- safeArea: {
204
- flex: 1,
205
- backgroundColor: DarkTheme.background,
206
- },
207
- header: {
208
- flexDirection: 'row',
209
- alignItems: 'center',
210
- justifyContent: 'space-between',
211
- paddingHorizontal: 16,
212
- paddingVertical: 12,
213
- borderBottomWidth: 1,
214
- borderBottomColor: DarkTheme.border,
215
- },
216
- headerLeft: {
217
- flexDirection: 'row',
218
- alignItems: 'center',
219
- },
220
- headerBrand: {
221
- fontSize: 20,
222
- marginRight: 8,
223
- },
224
- headerTitle: {
225
- fontFamily: MonospaceFont,
226
- fontSize: 18,
227
- fontWeight: '800',
228
- color: DarkTheme.text,
229
- letterSpacing: 1,
230
- },
231
- closeButton: {
232
- width: 32,
233
- height: 32,
234
- borderRadius: 16,
235
- backgroundColor: DarkTheme.surfaceElevated,
236
- borderWidth: 1,
237
- borderColor: DarkTheme.border,
238
- alignItems: 'center',
239
- justifyContent: 'center',
240
- },
241
- closeButtonText: {
242
- fontSize: 14,
243
- color: DarkTheme.textSecondary,
244
- fontWeight: '700',
245
- },
246
- content: {
247
- flex: 1,
248
- },
249
- })
229
+ const createStyles = (t: import('../types').BackstageTheme) =>
230
+ StyleSheet.create({
231
+ safeArea: {
232
+ flex: 1,
233
+ backgroundColor: t.background,
234
+ },
235
+ header: {
236
+ flexDirection: 'row',
237
+ alignItems: 'center',
238
+ justifyContent: 'space-between',
239
+ paddingHorizontal: 16,
240
+ paddingVertical: 12,
241
+ borderBottomWidth: 1,
242
+ borderBottomColor: t.border,
243
+ },
244
+ headerLeft: {
245
+ flexDirection: 'row',
246
+ alignItems: 'center',
247
+ },
248
+ headerBrand: {
249
+ fontSize: 20,
250
+ marginRight: 8,
251
+ },
252
+ headerTitle: {
253
+ fontFamily: MonospaceFont,
254
+ fontSize: 18,
255
+ fontWeight: '800',
256
+ color: t.text,
257
+ letterSpacing: 1,
258
+ },
259
+ closeButton: {
260
+ width: 32,
261
+ height: 32,
262
+ borderRadius: 16,
263
+ backgroundColor: t.surfaceElevated,
264
+ borderWidth: 1,
265
+ borderColor: t.border,
266
+ alignItems: 'center',
267
+ justifyContent: 'center',
268
+ },
269
+ closeButtonText: {
270
+ fontSize: 14,
271
+ color: t.textSecondary,
272
+ fontWeight: '700',
273
+ },
274
+ content: {
275
+ flex: 1,
276
+ },
277
+ })