rn-backstage 1.1.0 → 1.2.1

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 (103) hide show
  1. package/README.md +41 -19
  2. package/lib/commonjs/Backstage.js +42 -31
  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 +38 -16
  7. package/lib/commonjs/components/BackstagePanel.js.map +1 -1
  8. package/lib/commonjs/components/FlagsTab.js +256 -0
  9. package/lib/commonjs/components/FlagsTab.js.map +1 -0
  10. package/lib/commonjs/components/FloatingPill.js +4 -2
  11. package/lib/commonjs/components/FloatingPill.js.map +1 -1
  12. package/lib/commonjs/components/InfoTab.js +73 -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 +33 -29
  17. package/lib/commonjs/components/LogItem.js.map +1 -1
  18. package/lib/commonjs/components/LogsTab.js +37 -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 +48 -49
  23. package/lib/commonjs/components/NetworkTab.js.map +1 -1
  24. package/lib/commonjs/components/TabBar.js +8 -5
  25. package/lib/commonjs/components/TabBar.js.map +1 -1
  26. package/lib/commonjs/constants.js +24 -1
  27. package/lib/commonjs/constants.js.map +1 -1
  28. package/lib/commonjs/index.js +19 -0
  29. package/lib/commonjs/index.js.map +1 -1
  30. package/lib/commonjs/types.js +1 -0
  31. package/lib/commonjs/types.js.map +1 -1
  32. package/lib/module/Backstage.js +42 -31
  33. package/lib/module/Backstage.js.map +1 -1
  34. package/lib/module/ThemeContext.js +37 -0
  35. package/lib/module/ThemeContext.js.map +1 -0
  36. package/lib/module/components/BackstagePanel.js +40 -18
  37. package/lib/module/components/BackstagePanel.js.map +1 -1
  38. package/lib/module/components/FlagsTab.js +251 -0
  39. package/lib/module/components/FlagsTab.js.map +1 -0
  40. package/lib/module/components/FloatingPill.js +5 -3
  41. package/lib/module/components/FloatingPill.js.map +1 -1
  42. package/lib/module/components/InfoTab.js +73 -107
  43. package/lib/module/components/InfoTab.js.map +1 -1
  44. package/lib/module/components/JsonTreeView.js +42 -38
  45. package/lib/module/components/JsonTreeView.js.map +1 -1
  46. package/lib/module/components/LogItem.js +35 -31
  47. package/lib/module/components/LogItem.js.map +1 -1
  48. package/lib/module/components/LogsTab.js +38 -43
  49. package/lib/module/components/LogsTab.js.map +1 -1
  50. package/lib/module/components/NetworkItem.js +113 -137
  51. package/lib/module/components/NetworkItem.js.map +1 -1
  52. package/lib/module/components/NetworkTab.js +49 -50
  53. package/lib/module/components/NetworkTab.js.map +1 -1
  54. package/lib/module/components/TabBar.js +10 -7
  55. package/lib/module/components/TabBar.js.map +1 -1
  56. package/lib/module/constants.js +23 -0
  57. package/lib/module/constants.js.map +1 -1
  58. package/lib/module/index.js +1 -0
  59. package/lib/module/index.js.map +1 -1
  60. package/lib/module/types.js +2 -0
  61. package/lib/module/types.js.map +1 -1
  62. package/lib/typescript/Backstage.d.ts.map +1 -1
  63. package/lib/typescript/ThemeContext.d.ts +11 -0
  64. package/lib/typescript/ThemeContext.d.ts.map +1 -0
  65. package/lib/typescript/components/BackstagePanel.d.ts +4 -1
  66. package/lib/typescript/components/BackstagePanel.d.ts.map +1 -1
  67. package/lib/typescript/components/FlagsTab.d.ts +9 -0
  68. package/lib/typescript/components/FlagsTab.d.ts.map +1 -0
  69. package/lib/typescript/components/FloatingPill.d.ts.map +1 -1
  70. package/lib/typescript/components/InfoTab.d.ts +1 -0
  71. package/lib/typescript/components/InfoTab.d.ts.map +1 -1
  72. package/lib/typescript/components/JsonTreeView.d.ts.map +1 -1
  73. package/lib/typescript/components/LogItem.d.ts +1 -0
  74. package/lib/typescript/components/LogItem.d.ts.map +1 -1
  75. package/lib/typescript/components/LogsTab.d.ts +1 -0
  76. package/lib/typescript/components/LogsTab.d.ts.map +1 -1
  77. package/lib/typescript/components/NetworkItem.d.ts +1 -0
  78. package/lib/typescript/components/NetworkItem.d.ts.map +1 -1
  79. package/lib/typescript/components/NetworkTab.d.ts +1 -0
  80. package/lib/typescript/components/NetworkTab.d.ts.map +1 -1
  81. package/lib/typescript/components/TabBar.d.ts.map +1 -1
  82. package/lib/typescript/constants.d.ts +1 -0
  83. package/lib/typescript/constants.d.ts.map +1 -1
  84. package/lib/typescript/index.d.ts +3 -1
  85. package/lib/typescript/index.d.ts.map +1 -1
  86. package/lib/typescript/types.d.ts +18 -0
  87. package/lib/typescript/types.d.ts.map +1 -1
  88. package/package.json +1 -1
  89. package/src/Backstage.tsx +41 -31
  90. package/src/ThemeContext.tsx +38 -0
  91. package/src/components/BackstagePanel.tsx +84 -56
  92. package/src/components/FlagsTab.tsx +198 -0
  93. package/src/components/FloatingPill.tsx +6 -3
  94. package/src/components/InfoTab.tsx +152 -186
  95. package/src/components/JsonTreeView.tsx +53 -73
  96. package/src/components/LogItem.tsx +55 -100
  97. package/src/components/LogsTab.tsx +110 -132
  98. package/src/components/NetworkItem.tsx +306 -417
  99. package/src/components/NetworkTab.tsx +129 -163
  100. package/src/components/TabBar.tsx +51 -47
  101. package/src/constants.ts +23 -0
  102. package/src/index.ts +3 -0
  103. package/src/types.ts +25 -0
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useState } from 'react'
1
+ import React, { useCallback, useMemo, useState } from 'react'
2
2
  import {
3
3
  LayoutAnimation,
4
4
  Platform,
@@ -8,7 +8,9 @@ import {
8
8
  UIManager,
9
9
  View,
10
10
  } from 'react-native'
11
- import { DarkTheme, MonospaceFont } from '../constants'
11
+ import { MonospaceFont } from '../constants'
12
+ import { useBackstageTheme } from '../ThemeContext'
13
+ import type { BackstageTheme } from '../types'
12
14
 
13
15
  // Enable LayoutAnimation on Android
14
16
  if (Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental) {
@@ -35,12 +37,12 @@ interface JsonNodeProps {
35
37
 
36
38
  // ─── Color Mapping ───────────────────────────────────────────────────────────
37
39
 
38
- function getValueColor(value: unknown): string {
39
- if (value === null || value === undefined) return DarkTheme.textMuted
40
- if (typeof value === 'string') return '#98C379' // green
41
- if (typeof value === 'number') return '#61AFEF' // cyan
42
- if (typeof value === 'boolean') return '#C678DD' // purple
43
- return DarkTheme.text
40
+ function getValueColor(value: unknown, t: BackstageTheme): string {
41
+ if (value === null || value === undefined) return t.textMuted
42
+ if (typeof value === 'string') return '#98C379'
43
+ if (typeof value === 'number') return '#61AFEF'
44
+ if (typeof value === 'boolean') return '#C678DD'
45
+ return t.text
44
46
  }
45
47
 
46
48
  function getPreview(value: unknown): string {
@@ -79,7 +81,9 @@ const JsonNode: React.FC<JsonNodeProps> = ({
79
81
  isLast,
80
82
  hideKey = false,
81
83
  }) => {
82
- const [expanded, setExpanded] = useState(depth < 1)
84
+ const theme = useBackstageTheme()
85
+ const s = useMemo(() => createStyles(theme), [theme])
86
+ const [expanded, setExpanded] = useState(false)
83
87
  const expandable = isExpandable(value)
84
88
  const reachedMaxDepth = depth >= maxDepth
85
89
 
@@ -95,18 +99,18 @@ const JsonNode: React.FC<JsonNodeProps> = ({
95
99
  const displayValue = reachedMaxDepth && expandable ? getPreview(value) : formatValue(value)
96
100
 
97
101
  return (
98
- <View style={[styles.row, { paddingLeft: indent }]}>
99
- {!hideKey && keyName !== null && <Text style={styles.key}>{`${keyName}: `}</Text>}
102
+ <View style={[s.row, { paddingLeft: indent }]}>
103
+ {!hideKey && keyName !== null && <Text style={s.key}>{`${keyName}: `}</Text>}
100
104
  <Text
101
105
  style={[
102
- styles.value,
103
- { color: reachedMaxDepth ? DarkTheme.textMuted : getValueColor(value) },
106
+ s.value,
107
+ { color: reachedMaxDepth ? theme.textMuted : getValueColor(value, theme) },
104
108
  ]}
105
109
  numberOfLines={3}
106
110
  >
107
111
  {displayValue}
108
112
  </Text>
109
- {!isLast && <Text style={styles.comma}>,</Text>}
113
+ {!isLast && <Text style={s.comma}>,</Text>}
110
114
  </View>
111
115
  )
112
116
  }
@@ -124,16 +128,16 @@ const JsonNode: React.FC<JsonNodeProps> = ({
124
128
  <TouchableOpacity
125
129
  onPress={toggleExpand}
126
130
  activeOpacity={0.7}
127
- style={[styles.row, { paddingLeft: indent }]}
131
+ style={[s.row, { paddingLeft: indent }]}
128
132
  >
129
- <Text style={styles.chevron}>{expanded ? '▼' : '▶'}</Text>
130
- {!hideKey && keyName !== null && <Text style={styles.key}>{`${keyName}: `}</Text>}
131
- <Text style={styles.bracket}>{bracketOpen}</Text>
133
+ <Text style={s.chevron}>{expanded ? '▼' : '▶'}</Text>
134
+ {!hideKey && keyName !== null && <Text style={s.key}>{`${keyName}: `}</Text>}
135
+ <Text style={s.bracket}>{bracketOpen}</Text>
132
136
  {!expanded && (
133
137
  <>
134
- <Text style={styles.preview}>{` ${getPreview(value)} `}</Text>
135
- <Text style={styles.bracket}>{bracketClose}</Text>
136
- {!isLast && <Text style={styles.comma}>,</Text>}
138
+ <Text style={s.preview}>{` ${getPreview(value)} `}</Text>
139
+ <Text style={s.bracket}>{bracketClose}</Text>
140
+ {!isLast && <Text style={s.comma}>,</Text>}
137
141
  </>
138
142
  )}
139
143
  </TouchableOpacity>
@@ -150,9 +154,9 @@ const JsonNode: React.FC<JsonNodeProps> = ({
150
154
  isLast={i === entries.length - 1}
151
155
  />
152
156
  ))}
153
- <View style={[styles.row, { paddingLeft: indent }]}>
154
- <Text style={styles.bracket}>{bracketClose}</Text>
155
- {!isLast && <Text style={styles.comma}>,</Text>}
157
+ <View style={[s.row, { paddingLeft: indent }]}>
158
+ <Text style={s.bracket}>{bracketClose}</Text>
159
+ {!isLast && <Text style={s.comma}>,</Text>}
156
160
  </View>
157
161
  </>
158
162
  )}
@@ -167,12 +171,15 @@ export const JsonTreeView: React.FC<JsonTreeViewProps> = ({
167
171
  hideRoot = false,
168
172
  maxDepth = 10,
169
173
  }) => {
174
+ const theme = useBackstageTheme()
175
+ const s = useMemo(() => createStyles(theme), [theme])
176
+
170
177
  if (data === null || data === undefined) {
171
- return <Text style={[styles.value, { color: DarkTheme.textMuted }]}>{String(data)}</Text>
178
+ return <Text style={[s.value, { color: theme.textMuted }]}>{String(data)}</Text>
172
179
  }
173
180
 
174
181
  if (!isExpandable(data)) {
175
- return <Text style={[styles.value, { color: getValueColor(data) }]}>{formatValue(data)}</Text>
182
+ return <Text style={[s.value, { color: getValueColor(data, theme) }]}>{formatValue(data)}</Text>
176
183
  }
177
184
 
178
185
  if (hideRoot) {
@@ -181,7 +188,7 @@ export const JsonTreeView: React.FC<JsonTreeViewProps> = ({
181
188
  : Object.entries(data as Record<string, unknown>)
182
189
 
183
190
  return (
184
- <View style={styles.container}>
191
+ <View style={s.container}>
185
192
  {entries.map(([k, v], i) => (
186
193
  <JsonNode
187
194
  key={`${k}_${i}`}
@@ -197,7 +204,7 @@ export const JsonTreeView: React.FC<JsonTreeViewProps> = ({
197
204
  }
198
205
 
199
206
  return (
200
- <View style={styles.container}>
207
+ <View style={s.container}>
201
208
  <JsonNode
202
209
  keyName={null}
203
210
  value={data}
@@ -212,48 +219,21 @@ export const JsonTreeView: React.FC<JsonTreeViewProps> = ({
212
219
 
213
220
  // ─── Styles ──────────────────────────────────────────────────────────────────
214
221
 
215
- const styles = StyleSheet.create({
216
- container: {
217
- paddingVertical: 4,
218
- },
219
- row: {
220
- flexDirection: 'row',
221
- alignItems: 'flex-start',
222
- paddingVertical: 2,
223
- flexWrap: 'wrap',
224
- },
225
- chevron: {
226
- fontFamily: MonospaceFont,
227
- fontSize: 10,
228
- color: DarkTheme.textMuted,
229
- marginRight: 6,
230
- marginTop: 2,
231
- width: 12,
232
- },
233
- key: {
234
- fontFamily: MonospaceFont,
235
- fontSize: 13,
236
- color: '#E06C75', // red-ish for keys
237
- },
238
- value: {
239
- fontFamily: MonospaceFont,
240
- fontSize: 13,
241
- flexShrink: 1,
242
- },
243
- bracket: {
244
- fontFamily: MonospaceFont,
245
- fontSize: 13,
246
- color: DarkTheme.textSecondary,
247
- },
248
- preview: {
249
- fontFamily: MonospaceFont,
250
- fontSize: 13,
251
- color: DarkTheme.textMuted,
252
- fontStyle: 'italic',
253
- },
254
- comma: {
255
- fontFamily: MonospaceFont,
256
- fontSize: 13,
257
- color: DarkTheme.textMuted,
258
- },
259
- })
222
+ const createStyles = (t: BackstageTheme) =>
223
+ StyleSheet.create({
224
+ container: { paddingVertical: 4 },
225
+ row: { flexDirection: 'row', alignItems: 'flex-start', paddingVertical: 2, flexWrap: 'wrap' },
226
+ chevron: {
227
+ fontFamily: MonospaceFont,
228
+ fontSize: 10,
229
+ color: t.textMuted,
230
+ marginRight: 6,
231
+ marginTop: 2,
232
+ width: 12,
233
+ },
234
+ key: { fontFamily: MonospaceFont, fontSize: 13, color: '#E06C75' },
235
+ value: { fontFamily: MonospaceFont, fontSize: 13, flexShrink: 1 },
236
+ bracket: { fontFamily: MonospaceFont, fontSize: 13, color: t.textSecondary },
237
+ preview: { fontFamily: MonospaceFont, fontSize: 13, color: t.textMuted, fontStyle: 'italic' },
238
+ comma: { fontFamily: MonospaceFont, fontSize: 13, color: t.textMuted },
239
+ })
@@ -1,8 +1,9 @@
1
- import React, { useCallback, useState } from 'react'
1
+ import React, { useCallback, useMemo, useState } from 'react'
2
2
  import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'
3
- import { DarkTheme, MonospaceFont } from '../constants'
3
+ import { MonospaceFont } from '../constants'
4
+ import { useBackstageTheme } from '../ThemeContext'
4
5
  import { LogLevel } from '../types'
5
- import type { LogEntry, BackstageStyleOverrides } from '../types'
6
+ import type { LogEntry, BackstageStyleOverrides, BackstageTheme } from '../types'
6
7
  import { formatTimestamp } from '../utils/formatTimestamp'
7
8
  import { JsonTreeView } from './JsonTreeView'
8
9
 
@@ -11,50 +12,39 @@ import { JsonTreeView } from './JsonTreeView'
11
12
  interface LogItemProps {
12
13
  item: LogEntry
13
14
  onCopy?: (text: string) => void
15
+ jsonMaxDepth?: number
14
16
  styles?: BackstageStyleOverrides
15
17
  }
16
18
 
17
19
  // ─── Badge Colors ────────────────────────────────────────────────────────────
18
20
 
19
- function getBadgeConfig(level: LogLevel): {
20
- label: string
21
- color: string
22
- bgColor: string
23
- rowBg: string
24
- } {
21
+ function getBadgeConfig(
22
+ level: LogLevel,
23
+ t: BackstageTheme,
24
+ ): { label: string; color: string; bgColor: string; rowBg: string } {
25
25
  switch (level) {
26
26
  case LogLevel.error:
27
27
  return {
28
28
  label: 'ERROR',
29
- color: DarkTheme.error,
30
- bgColor: DarkTheme.errorDim,
29
+ color: t.error,
30
+ bgColor: t.errorDim,
31
31
  rowBg: 'rgba(255, 77, 106, 0.06)',
32
32
  }
33
33
  case LogLevel.warn:
34
34
  return {
35
35
  label: 'WARN',
36
- color: DarkTheme.warning,
37
- bgColor: DarkTheme.warningDim,
36
+ color: t.warning,
37
+ bgColor: t.warningDim,
38
38
  rowBg: 'rgba(255, 178, 36, 0.06)',
39
39
  }
40
40
  case LogLevel.info:
41
- return {
42
- label: 'INFO',
43
- color: DarkTheme.info,
44
- bgColor: DarkTheme.infoDim,
45
- rowBg: 'transparent',
46
- }
41
+ return { label: 'INFO', color: t.info, bgColor: t.infoDim, rowBg: 'transparent' }
47
42
  case LogLevel.debug:
48
- return {
49
- label: 'DEBUG',
50
- color: DarkTheme.debugColor,
51
- bgColor: DarkTheme.debugDim,
52
- rowBg: 'transparent',
53
- }
43
+ return { label: 'DEBUG', color: t.debugColor, bgColor: t.debugDim, rowBg: 'transparent' }
54
44
  default:
55
45
  return {
56
46
  label: 'LOG',
57
- color: DarkTheme.textSecondary,
47
+ color: t.textSecondary,
58
48
  bgColor: 'rgba(160, 160, 176, 0.1)',
59
49
  rowBg: 'transparent',
60
50
  }
@@ -64,9 +54,11 @@ function getBadgeConfig(level: LogLevel): {
64
54
  // ─── Component ───────────────────────────────────────────────────────────────
65
55
 
66
56
  export const LogItem: React.FC<LogItemProps> = React.memo(
67
- ({ item, onCopy, styles: propStyles }) => {
57
+ ({ item, onCopy, jsonMaxDepth, styles: propStyles }) => {
58
+ const theme = useBackstageTheme()
59
+ const s = useMemo(() => createStyles(theme), [theme])
68
60
  const [expanded, setExpanded] = useState(false)
69
- const badge = getBadgeConfig(item.level)
61
+ const badge = getBadgeConfig(item.level, theme)
70
62
  const hasData = item.data !== undefined
71
63
 
72
64
  const toggleExpand = useCallback(() => {
@@ -82,47 +74,43 @@ export const LogItem: React.FC<LogItemProps> = React.memo(
82
74
 
83
75
  return (
84
76
  <TouchableOpacity
85
- style={[styles.container, { backgroundColor: badge.rowBg }]}
77
+ style={[s.container, { backgroundColor: badge.rowBg }]}
86
78
  onPress={hasData ? toggleExpand : undefined}
87
79
  onLongPress={handleCopy}
88
80
  activeOpacity={hasData ? 0.7 : 1}
89
81
  >
90
- {/* Header row: badge + timestamp + copy */}
91
- <View style={styles.headerRow}>
92
- <View style={[styles.badge, { backgroundColor: badge.bgColor }]}>
93
- <Text style={[styles.badgeText, { color: badge.color }]}>{badge.label}</Text>
82
+ <View style={s.headerRow}>
83
+ <View style={[s.badge, { backgroundColor: badge.bgColor }]}>
84
+ <Text style={[s.badgeText, { color: badge.color }]}>{badge.label}</Text>
94
85
  </View>
95
- <Text style={[styles.timestamp, propStyles?.logTimestampStyle]}>
86
+ <Text style={[s.timestamp, propStyles?.logTimestampStyle]}>
96
87
  {formatTimestamp(item.timestamp)}
97
88
  </Text>
98
89
  {onCopy && (
99
90
  <TouchableOpacity
100
- style={styles.copyButton}
91
+ style={s.copyButton}
101
92
  onPress={handleCopy}
102
93
  hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
103
94
  >
104
- <Text style={styles.copyButtonText}>⧉</Text>
95
+ <Text style={s.copyButtonText}>⧉</Text>
105
96
  </TouchableOpacity>
106
97
  )}
107
98
  </View>
108
99
 
109
- {/* Message */}
110
100
  <Text
111
- style={[styles.message, propStyles?.logMessageStyle]}
101
+ style={[s.message, propStyles?.logMessageStyle]}
112
102
  numberOfLines={expanded ? undefined : 3}
113
103
  >
114
104
  {item.message}
115
105
  </Text>
116
106
 
117
- {/* Expandable data */}
118
107
  {expanded && hasData && (
119
- <View style={styles.dataContainer}>
120
- <JsonTreeView data={item.data} hideRoot maxDepth={5} />
108
+ <View style={s.dataContainer}>
109
+ <JsonTreeView data={item.data} hideRoot maxDepth={jsonMaxDepth} />
121
110
  </View>
122
111
  )}
123
112
 
124
- {/* Expand hint */}
125
- {hasData && !expanded && <Text style={styles.expandHint}>tap to expand ▾</Text>}
113
+ {hasData && !expanded && <Text style={s.expandHint}>tap to expand ▾</Text>}
126
114
  </TouchableOpacity>
127
115
  )
128
116
  },
@@ -130,60 +118,27 @@ export const LogItem: React.FC<LogItemProps> = React.memo(
130
118
 
131
119
  // ─── Styles ──────────────────────────────────────────────────────────────────
132
120
 
133
- const styles = StyleSheet.create({
134
- container: {
135
- paddingHorizontal: 14,
136
- paddingVertical: 10,
137
- borderBottomWidth: 1,
138
- borderBottomColor: DarkTheme.border,
139
- },
140
- headerRow: {
141
- flexDirection: 'row',
142
- alignItems: 'center',
143
- marginBottom: 4,
144
- },
145
- badge: {
146
- borderRadius: 4,
147
- paddingHorizontal: 6,
148
- paddingVertical: 2,
149
- marginRight: 8,
150
- },
151
- badgeText: {
152
- fontFamily: MonospaceFont,
153
- fontSize: 10,
154
- fontWeight: '800',
155
- letterSpacing: 0.5,
156
- },
157
- timestamp: {
158
- fontFamily: MonospaceFont,
159
- fontSize: 11,
160
- color: DarkTheme.textMuted,
161
- flex: 1,
162
- },
163
- copyButton: {
164
- padding: 4,
165
- },
166
- copyButtonText: {
167
- fontSize: 16,
168
- color: DarkTheme.textMuted,
169
- },
170
- message: {
171
- fontFamily: MonospaceFont,
172
- fontSize: 12,
173
- color: DarkTheme.text,
174
- lineHeight: 18,
175
- },
176
- dataContainer: {
177
- marginTop: 8,
178
- paddingTop: 8,
179
- borderTopWidth: 1,
180
- borderTopColor: DarkTheme.border,
181
- },
182
- expandHint: {
183
- fontFamily: MonospaceFont,
184
- fontSize: 10,
185
- color: DarkTheme.textMuted,
186
- marginTop: 4,
187
- fontStyle: 'italic',
188
- },
189
- })
121
+ const createStyles = (t: BackstageTheme) =>
122
+ StyleSheet.create({
123
+ container: {
124
+ paddingHorizontal: 14,
125
+ paddingVertical: 10,
126
+ borderBottomWidth: 1,
127
+ borderBottomColor: t.border,
128
+ },
129
+ headerRow: { flexDirection: 'row', alignItems: 'center', marginBottom: 4 },
130
+ badge: { borderRadius: 4, paddingHorizontal: 6, paddingVertical: 2, marginRight: 8 },
131
+ badgeText: { fontFamily: MonospaceFont, fontSize: 10, fontWeight: '800', letterSpacing: 0.5 },
132
+ timestamp: { fontFamily: MonospaceFont, fontSize: 11, color: t.textMuted, flex: 1 },
133
+ copyButton: { padding: 4 },
134
+ copyButtonText: { fontSize: 16, color: t.textMuted },
135
+ message: { fontFamily: MonospaceFont, fontSize: 12, color: t.text, lineHeight: 18 },
136
+ dataContainer: { marginTop: 8, paddingTop: 8, borderTopWidth: 1, borderTopColor: t.border },
137
+ expandHint: {
138
+ fontFamily: MonospaceFont,
139
+ fontSize: 10,
140
+ color: t.textMuted,
141
+ marginTop: 4,
142
+ fontStyle: 'italic',
143
+ },
144
+ })