@buoy-gg/highlight-updates 7.0.40 → 7.0.42

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 +11 -67
  2. package/lib/commonjs/highlight-updates/HighlightUpdatesOverlay.js +1 -281
  3. package/lib/commonjs/highlight-updates/components/HighlightFilterView.js +1 -1474
  4. package/lib/commonjs/highlight-updates/components/HighlightUpdatesModal.js +1 -641
  5. package/lib/commonjs/highlight-updates/components/IdentifierBadge.js +1 -273
  6. package/lib/commonjs/highlight-updates/components/IsolatedRenderList.js +1 -188
  7. package/lib/commonjs/highlight-updates/components/ModalHeaderContent.js +1 -293
  8. package/lib/commonjs/highlight-updates/components/RenderCauseBadge.js +1 -508
  9. package/lib/commonjs/highlight-updates/components/RenderDetailView.js +1 -846
  10. package/lib/commonjs/highlight-updates/components/RenderHistoryViewer.js +1 -915
  11. package/lib/commonjs/highlight-updates/components/RenderListItem.js +1 -235
  12. package/lib/commonjs/highlight-updates/components/RendersCopySettingsView.js +1 -469
  13. package/lib/commonjs/highlight-updates/components/StatsDisplay.js +1 -73
  14. package/lib/commonjs/highlight-updates/types/copySettings.js +1 -107
  15. package/lib/commonjs/highlight-updates/utils/CommitProfiler.js +1 -446
  16. package/lib/commonjs/highlight-updates/utils/HighlightUpdatesController.js +1 -1920
  17. package/lib/commonjs/highlight-updates/utils/PerformanceLogger.js +26 -359
  18. package/lib/commonjs/highlight-updates/utils/ProfilerInterceptor.js +1 -371
  19. package/lib/commonjs/highlight-updates/utils/RenderCauseDetector.js +5 -1840
  20. package/lib/commonjs/highlight-updates/utils/RenderTracker.js +1 -952
  21. package/lib/commonjs/highlight-updates/utils/ViewTypeMapper.js +1 -264
  22. package/lib/commonjs/highlight-updates/utils/copySettingsStorage.js +1 -32
  23. package/lib/commonjs/highlight-updates/utils/devtoolsComponentNames.js +1 -188
  24. package/lib/commonjs/highlight-updates/utils/namedComposite.js +1 -41
  25. package/lib/commonjs/highlight-updates/utils/ownStateChanged.js +1 -103
  26. package/lib/commonjs/highlight-updates/utils/rawEventEmitter.js +1 -50
  27. package/lib/commonjs/highlight-updates/utils/rawEventEmitter.web.js +1 -0
  28. package/lib/commonjs/highlight-updates/utils/renderExportFormatter.js +1 -58
  29. package/lib/commonjs/highlight-updates/utils/rendersExportFormatter.js +1 -485
  30. package/lib/commonjs/highlight-updates/utils/screenElements.js +1 -1248
  31. package/lib/commonjs/highlight-updates/utils/tapMatch.js +1 -83
  32. package/lib/commonjs/highlight-updates/utils/testIDs.js +1 -68
  33. package/lib/commonjs/highlight-updates/utils/touchCapture.js +1 -277
  34. package/lib/commonjs/index.js +1 -429
  35. package/lib/commonjs/preset.js +1 -278
  36. package/lib/commonjs/sync/highlightUpdatesSyncAdapter.js +1 -235
  37. package/lib/module/highlight-updates/HighlightUpdatesOverlay.js +1 -274
  38. package/lib/module/highlight-updates/components/HighlightFilterView.js +1 -1468
  39. package/lib/module/highlight-updates/components/HighlightUpdatesModal.js +1 -634
  40. package/lib/module/highlight-updates/components/IdentifierBadge.js +1 -265
  41. package/lib/module/highlight-updates/components/IsolatedRenderList.js +1 -183
  42. package/lib/module/highlight-updates/components/ModalHeaderContent.js +1 -288
  43. package/lib/module/highlight-updates/components/RenderCauseBadge.js +1 -499
  44. package/lib/module/highlight-updates/components/RenderDetailView.js +1 -840
  45. package/lib/module/highlight-updates/components/RenderHistoryViewer.js +1 -908
  46. package/lib/module/highlight-updates/components/RenderListItem.js +1 -230
  47. package/lib/module/highlight-updates/components/RendersCopySettingsView.js +1 -465
  48. package/lib/module/highlight-updates/components/StatsDisplay.js +1 -70
  49. package/lib/module/highlight-updates/types/copySettings.js +1 -102
  50. package/lib/module/highlight-updates/utils/CommitProfiler.js +1 -442
  51. package/lib/module/highlight-updates/utils/HighlightUpdatesController.js +1 -1916
  52. package/lib/module/highlight-updates/utils/PerformanceLogger.js +26 -353
  53. package/lib/module/highlight-updates/utils/ProfilerInterceptor.js +1 -358
  54. package/lib/module/highlight-updates/utils/RenderCauseDetector.js +5 -1830
  55. package/lib/module/highlight-updates/utils/RenderTracker.js +1 -949
  56. package/lib/module/highlight-updates/utils/ViewTypeMapper.js +1 -255
  57. package/lib/module/highlight-updates/utils/copySettingsStorage.js +1 -26
  58. package/lib/module/highlight-updates/utils/devtoolsComponentNames.js +1 -178
  59. package/lib/module/highlight-updates/utils/namedComposite.js +1 -36
  60. package/lib/module/highlight-updates/utils/ownStateChanged.js +1 -98
  61. package/lib/module/highlight-updates/utils/rawEventEmitter.js +1 -46
  62. package/lib/module/highlight-updates/utils/rawEventEmitter.web.js +1 -0
  63. package/lib/module/highlight-updates/utils/renderExportFormatter.js +1 -54
  64. package/lib/module/highlight-updates/utils/rendersExportFormatter.js +1 -478
  65. package/lib/module/highlight-updates/utils/screenElements.js +1 -1242
  66. package/lib/module/highlight-updates/utils/tapMatch.js +1 -76
  67. package/lib/module/highlight-updates/utils/testIDs.js +1 -60
  68. package/lib/module/highlight-updates/utils/touchCapture.js +1 -270
  69. package/lib/module/index.js +1 -130
  70. package/lib/module/preset.js +1 -272
  71. package/lib/module/sync/highlightUpdatesSyncAdapter.js +1 -230
  72. package/lib/typescript/highlight-updates/utils/HighlightUpdatesController.d.ts +0 -26
  73. package/lib/typescript/highlight-updates/utils/rawEventEmitter.web.d.ts +3 -0
  74. package/lib/typescript/highlight-updates/utils/screenElements.d.ts +0 -19
  75. package/lib/web/index.mjs +38 -0
  76. package/package.json +34 -14
  77. package/lib/typescript/highlight-updates/HighlightUpdatesOverlay.d.ts.map +0 -1
  78. package/lib/typescript/highlight-updates/components/HighlightFilterView.d.ts.map +0 -1
  79. package/lib/typescript/highlight-updates/components/HighlightUpdatesModal.d.ts.map +0 -1
  80. package/lib/typescript/highlight-updates/components/IdentifierBadge.d.ts.map +0 -1
  81. package/lib/typescript/highlight-updates/components/IsolatedRenderList.d.ts.map +0 -1
  82. package/lib/typescript/highlight-updates/components/ModalHeaderContent.d.ts.map +0 -1
  83. package/lib/typescript/highlight-updates/components/RenderCauseBadge.d.ts.map +0 -1
  84. package/lib/typescript/highlight-updates/components/RenderDetailView.d.ts.map +0 -1
  85. package/lib/typescript/highlight-updates/components/RenderHistoryViewer.d.ts.map +0 -1
  86. package/lib/typescript/highlight-updates/components/RenderListItem.d.ts.map +0 -1
  87. package/lib/typescript/highlight-updates/components/RendersCopySettingsView.d.ts.map +0 -1
  88. package/lib/typescript/highlight-updates/components/StatsDisplay.d.ts.map +0 -1
  89. package/lib/typescript/highlight-updates/types/copySettings.d.ts.map +0 -1
  90. package/lib/typescript/highlight-updates/utils/CommitProfiler.d.ts.map +0 -1
  91. package/lib/typescript/highlight-updates/utils/HighlightUpdatesController.d.ts.map +0 -1
  92. package/lib/typescript/highlight-updates/utils/PerformanceLogger.d.ts.map +0 -1
  93. package/lib/typescript/highlight-updates/utils/ProfilerInterceptor.d.ts.map +0 -1
  94. package/lib/typescript/highlight-updates/utils/RenderCauseDetector.d.ts.map +0 -1
  95. package/lib/typescript/highlight-updates/utils/RenderTracker.d.ts.map +0 -1
  96. package/lib/typescript/highlight-updates/utils/ViewTypeMapper.d.ts.map +0 -1
  97. package/lib/typescript/highlight-updates/utils/copySettingsStorage.d.ts.map +0 -1
  98. package/lib/typescript/highlight-updates/utils/devtoolsComponentNames.d.ts.map +0 -1
  99. package/lib/typescript/highlight-updates/utils/namedComposite.d.ts.map +0 -1
  100. package/lib/typescript/highlight-updates/utils/ownStateChanged.d.ts.map +0 -1
  101. package/lib/typescript/highlight-updates/utils/rawEventEmitter.d.ts.map +0 -1
  102. package/lib/typescript/highlight-updates/utils/renderExportFormatter.d.ts.map +0 -1
  103. package/lib/typescript/highlight-updates/utils/rendersExportFormatter.d.ts.map +0 -1
  104. package/lib/typescript/highlight-updates/utils/screenElements.d.ts.map +0 -1
  105. package/lib/typescript/highlight-updates/utils/tapMatch.d.ts.map +0 -1
  106. package/lib/typescript/highlight-updates/utils/testIDs.d.ts.map +0 -1
  107. package/lib/typescript/highlight-updates/utils/touchCapture.d.ts.map +0 -1
  108. package/lib/typescript/index.d.ts.map +0 -1
  109. package/lib/typescript/preset.d.ts.map +0 -1
  110. package/lib/typescript/sync/highlightUpdatesSyncAdapter.d.ts.map +0 -1
@@ -1,915 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.RenderHistoryFooter = RenderHistoryFooter;
7
- exports.RenderHistoryViewer = RenderHistoryViewer;
8
- exports.default = void 0;
9
- var _react = _interopRequireWildcard(require("react"));
10
- var _reactNative = require("react-native");
11
- var _sharedUi = require("@buoy-gg/shared-ui");
12
- var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
13
- var _RenderTracker = require("../utils/RenderTracker");
14
- var _RenderCauseBadge = require("./RenderCauseBadge");
15
- var _jsxRuntime = require("react/jsx-runtime");
16
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
17
- /**
18
- * RenderHistoryViewer
19
- *
20
- * Displays render history for a component with event stepping.
21
- * Allows navigating through render events chronologically.
22
- * Shows current state view or diff view between renders.
23
- */
24
-
25
- /**
26
- * `HH:MM:SS.mmm` — the same shape Redux, Zustand and Jotai print for the same
27
- * job, and for the same reason: the milliseconds are the point.
28
- *
29
- * Built by hand rather than from `toLocaleTimeString`, which appends the day
30
- * period on a 12-hour locale — so concatenating the milliseconds to the end of
31
- * it produced "8:21:44 AM.351", with the fraction attached to the wrong part
32
- * of the time. It also made the string depend on the hour of day, which is a
33
- * fine way to have a test that only passes after 10am.
34
- */
35
- function formatTimeWithMs(timestamp) {
36
- const date = new Date(timestamp);
37
- const h = date.getHours().toString().padStart(2, "0");
38
- const m = date.getMinutes().toString().padStart(2, "0");
39
- const s = date.getSeconds().toString().padStart(2, "0");
40
- const ms = date.getMilliseconds().toString().padStart(3, "0");
41
- return `${h}:${m}:${s}.${ms}`;
42
- }
43
-
44
- /**
45
- * Main RenderHistoryViewer component
46
- */
47
- function RenderHistoryViewer({
48
- render,
49
- disableInternalFooter = false,
50
- selectedEventIndex: externalIndex,
51
- onEventIndexChange: externalOnChange,
52
- isPro = false
53
- }) {
54
- // Internal state for event index when not controlled externally
55
- const [internalIndex, setInternalIndex] = (0, _react.useState)(0);
56
-
57
- // Use external or internal state
58
- const selectedEventIndex = externalIndex ?? internalIndex;
59
- const onEventIndexChange = externalOnChange ?? setInternalIndex;
60
-
61
- // View mode: "current" shows selected event, "diff" shows comparison
62
- const [activeView, setActiveView] = (0, _react.useState)("current");
63
-
64
- // Get all events sorted by timestamp (oldest first)
65
- const allEvents = (0, _react.useMemo)(() => {
66
- if (!render.renderHistory || render.renderHistory.length === 0) {
67
- return [];
68
- }
69
- return [...render.renderHistory].sort((a, b) => a.timestamp - b.timestamp);
70
- }, [render.renderHistory]);
71
-
72
- // `isPro` stays a prop so callers can force the unlimited view; the tier cap
73
- // applies otherwise. useLimit() already returns Infinity for Pro, so the two
74
- // agree — this only preserves the prop contract for cross-package callers.
75
- const tierLimit = (0, _sharedUi.useLimit)("highlightUpdates.historyEvents");
76
- const eventLimit = isPro ? Infinity : tierLimit;
77
-
78
- // Show the most recent N events (negative index clamps to 0, so an
79
- // unlimited tier returns the whole list).
80
- const events = (0, _react.useMemo)(() => allEvents.slice(-eventLimit), [allEvents, eventLimit]);
81
- const lockedEventCount = (0, _react.useMemo)(() => Math.max(0, allEvents.length - eventLimit), [allEvents.length, eventLimit]);
82
- const totalEvents = events.length;
83
- const currentEvent = events[selectedEventIndex];
84
- const previousEvent = selectedEventIndex > 0 ? events[selectedEventIndex - 1] : null;
85
-
86
- // Navigation handlers
87
- const goToPrevious = (0, _react.useCallback)(() => {
88
- if (selectedEventIndex > 0) {
89
- onEventIndexChange(selectedEventIndex - 1);
90
- }
91
- }, [selectedEventIndex, onEventIndexChange]);
92
- const goToNext = (0, _react.useCallback)(() => {
93
- if (selectedEventIndex < totalEvents - 1) {
94
- onEventIndexChange(selectedEventIndex + 1);
95
- }
96
- }, [selectedEventIndex, totalEvents, onEventIndexChange]);
97
-
98
- // If no history, show empty state
99
- if (totalEvents === 0) {
100
- // The copy used to tell EVERYONE to go and enable the setting, including
101
- // the people who already had. Asking the tracker which it is costs one
102
- // synchronous read on a branch that renders nothing else.
103
- const historyEnabled = _RenderTracker.RenderTracker.getSettings().enableRenderHistory;
104
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ToolEmptyState, {
105
- testID: "buoy-highlight-history-empty"
106
- // paused = the recorder is switched off; stare = armed and watching,
107
- // which is the truth once the setting is on and this component simply
108
- // has not re-rendered yet.
109
- ,
110
- otto: historyEnabled ? "stare" : "paused",
111
- title: "No Render History",
112
- message: historyEnabled ? "History is on and armed — this component has not re-rendered since. Interact with the app to record one." : "Enable render history tracking in settings to see render events here."
113
- });
114
- }
115
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
116
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
117
- style: [styles.container, {
118
- paddingBottom: !disableInternalFooter && totalEvents > 1 ? 80 : 0
119
- }],
120
- children: [lockedEventCount > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
121
- testID: "buoy-highlight-history-locked",
122
- style: styles.lockedBanner,
123
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Lock, {
124
- size: 14,
125
- color: _sharedUi.night.color.warning
126
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
127
- testID: "buoy-highlight-history-locked-text",
128
- style: styles.lockedBannerText,
129
- children: [lockedEventCount, " older ", lockedEventCount === 1 ? 'render' : 'renders', " locked"]
130
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
131
- style: styles.lockedBannerSubtext,
132
- children: "Upgrade to Pro"
133
- })]
134
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
135
- style: styles.viewToggleContainer,
136
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
137
- testID: "buoy-highlight-history-mode-current",
138
- accessibilityRole: "button",
139
- accessibilityLabel: "Current state",
140
- style: [styles.viewToggleCard, activeView === "current" && styles.viewToggleCardActive],
141
- onPress: () => setActiveView("current"),
142
- activeOpacity: 0.8,
143
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
144
- style: styles.viewToggleContent,
145
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Database, {
146
- size: 16,
147
- color: activeView === "current" ? _sharedUi.night.color.accent : _sharedUi.night.color.textSecondary
148
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
149
- style: [styles.viewToggleLabel, activeView === "current" && styles.viewToggleLabelActive],
150
- children: "CURRENT STATE"
151
- })]
152
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
153
- style: [styles.viewToggleDescription, activeView === "current" && {
154
- color: _sharedUi.night.color.text
155
- }],
156
- children: ["View render #", currentEvent?.renderNumber ?? 0, " details"]
157
- })]
158
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
159
- testID: "buoy-highlight-history-mode-diff",
160
- accessibilityLabel: "Diff view, coming soon",
161
- style: [styles.viewToggleCard, styles.viewToggleCardDisabled],
162
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
163
- style: styles.viewToggleContent,
164
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.GitBranch, {
165
- size: 16,
166
- color: _sharedUi.night.color.textTertiary
167
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
168
- style: [styles.viewToggleLabel, styles.viewToggleLabelDisabled],
169
- children: "DIFF VIEW"
170
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
171
- style: styles.todoBadge,
172
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
173
- style: styles.todoBadgeText,
174
- children: "TODO"
175
- })
176
- })]
177
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
178
- style: [styles.viewToggleDescription, {
179
- color: _sharedUi.night.color.textTertiary
180
- }],
181
- children: "Compare renders side by side (coming soon)"
182
- })]
183
- })]
184
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
185
- testID: "buoy-highlight-history-scroll",
186
- style: styles.contentScroll,
187
- contentContainerStyle: styles.contentContainer,
188
- showsVerticalScrollIndicator: false,
189
- children: activeView === "current" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(CurrentStateView, {
190
- event: currentEvent,
191
- render: render
192
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(DiffView, {
193
- previousEvent: previousEvent,
194
- currentEvent: currentEvent,
195
- render: render
196
- })
197
- })]
198
- }), !disableInternalFooter && /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.EventStepperFooter, {
199
- currentIndex: selectedEventIndex,
200
- totalItems: totalEvents,
201
- onPrevious: goToPrevious,
202
- onNext: goToNext,
203
- itemLabel: "Render",
204
- subtitle: (0, _sharedUi.formatRelativeTime)(new Date(currentEvent?.timestamp ?? Date.now()))
205
- })]
206
- });
207
- }
208
-
209
- /**
210
- * Current State View - shows details of the selected render event
211
- */
212
- function CurrentStateView({
213
- event,
214
- render
215
- }) {
216
- if (!event) {
217
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
218
- testID: "buoy-highlight-history-no-event",
219
- style: styles.noEventContainer,
220
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
221
- style: styles.noEventText,
222
- children: "No event selected"
223
- })
224
- });
225
- }
226
- const causeConfig = _RenderCauseBadge.CAUSE_CONFIG[event.cause.type];
227
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
228
- style: styles.currentStateContainer,
229
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
230
- style: styles.eventHeader,
231
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
232
- style: styles.eventHeaderLeft,
233
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
234
- testID: "buoy-highlight-history-event-title",
235
- style: styles.eventTitle,
236
- children: ["Render #", event.renderNumber]
237
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
238
- testID: "buoy-highlight-history-event-time",
239
- style: styles.eventTime,
240
- children: formatTimeWithMs(event.timestamp)
241
- })]
242
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
243
- style: [styles.eventBadge, {
244
- backgroundColor: render.color + "30"
245
- }],
246
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
247
- style: [styles.eventBadgeDot, {
248
- backgroundColor: render.color
249
- }]
250
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
251
- testID: "buoy-highlight-history-event-cause",
252
- style: [styles.eventBadgeText, {
253
- color: render.color
254
- }],
255
- children: event.cause.type.toUpperCase()
256
- })]
257
- })]
258
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
259
- style: styles.section,
260
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.SectionHeader, {
261
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon, {
262
- icon: _sharedUi.Clock,
263
- color: causeConfig.color,
264
- size: 12
265
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Title, {
266
- children: "WHY DID THIS RENDER?"
267
- })]
268
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
269
- style: styles.sectionContent,
270
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_RenderCauseBadge.EnhancedCauseDisplay, {
271
- cause: event.cause,
272
- nativeType: render.viewType
273
- })
274
- })]
275
- }), event.capturedProps && Object.keys(event.capturedProps).length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
276
- style: styles.section,
277
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.SectionHeader, {
278
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon, {
279
- icon: _sharedUi.Database,
280
- color: _sharedUi.night.color.accent,
281
- size: 12
282
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Title, {
283
- children: "CAPTURED PROPS"
284
- })]
285
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
286
- style: styles.sectionContent,
287
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
288
- horizontal: true,
289
- showsHorizontalScrollIndicator: false,
290
- style: styles.propsScrollView,
291
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
292
- testID: "buoy-highlight-history-props",
293
- style: styles.propsJson,
294
- children: JSON.stringify(event.capturedProps, null, 2)
295
- })
296
- })
297
- })]
298
- })]
299
- });
300
- }
301
-
302
- /**
303
- * Diff mode types
304
- */
305
-
306
- /**
307
- * Diff View - shows comparison between two render events
308
- */
309
- function DiffView({
310
- previousEvent,
311
- currentEvent,
312
- render
313
- }) {
314
- // Diff mode tab state
315
- const [diffMode, setDiffMode] = (0, _react.useState)("props");
316
- if (!previousEvent || !currentEvent) {
317
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
318
- style: styles.noEventContainer,
319
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
320
- style: styles.noEventText,
321
- children: "Select an event with a previous event to compare"
322
- })
323
- });
324
- }
325
- const prevCauseConfig = _RenderCauseBadge.CAUSE_CONFIG[previousEvent.cause.type];
326
- const currCauseConfig = _RenderCauseBadge.CAUSE_CONFIG[currentEvent.cause.type];
327
-
328
- // Check what data is available for diff
329
- const hasPropsData = previousEvent.capturedProps && currentEvent.capturedProps;
330
- const hasStateData = previousEvent.capturedState && currentEvent.capturedState;
331
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
332
- style: styles.diffContainer,
333
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
334
- style: styles.compareBar,
335
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
336
- style: styles.compareSide,
337
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
338
- style: styles.compareLabelRow,
339
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
340
- style: [styles.compareLabel, {
341
- color: _sharedUi.buoyColors.warning
342
- }],
343
- children: "PREV"
344
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
345
- style: [styles.compareActionBadge, {
346
- backgroundColor: `${prevCauseConfig.color}20`
347
- }],
348
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
349
- style: [styles.compareActionText, {
350
- color: prevCauseConfig.color
351
- }],
352
- children: previousEvent.cause.type.toUpperCase()
353
- })
354
- })]
355
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
356
- style: styles.compareMeta,
357
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
358
- style: styles.compareIndex,
359
- children: ["#", previousEvent.renderNumber]
360
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
361
- style: styles.compareTime,
362
- children: formatTimeWithMs(previousEvent.timestamp)
363
- })]
364
- })]
365
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
366
- style: styles.compareDivider,
367
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
368
- style: styles.compareArrow,
369
- children: "\u2192"
370
- })
371
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
372
- style: styles.compareSide,
373
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
374
- style: styles.compareLabelRow,
375
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
376
- style: [styles.compareLabel, {
377
- color: _sharedUi.buoyColors.success
378
- }],
379
- children: "CUR"
380
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
381
- style: [styles.compareActionBadge, {
382
- backgroundColor: `${currCauseConfig.color}20`
383
- }],
384
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
385
- style: [styles.compareActionText, {
386
- color: currCauseConfig.color
387
- }],
388
- children: currentEvent.cause.type.toUpperCase()
389
- })
390
- })]
391
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
392
- style: styles.compareMeta,
393
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
394
- style: styles.compareIndex,
395
- children: ["#", currentEvent.renderNumber]
396
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
397
- style: styles.compareTime,
398
- children: formatTimeWithMs(currentEvent.timestamp)
399
- })]
400
- })]
401
- })]
402
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
403
- style: styles.diffModeTabs,
404
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
405
- style: [styles.diffModeTab, diffMode === "cause" && styles.diffModeTabActive],
406
- onPress: () => setDiffMode("cause"),
407
- activeOpacity: 0.7,
408
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
409
- style: [styles.diffModeTabText, diffMode === "cause" && styles.diffModeTabTextActive],
410
- children: "CAUSE"
411
- })
412
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
413
- style: [styles.diffModeTab, diffMode === "props" && styles.diffModeTabActive, !hasPropsData && styles.diffModeTabDisabled],
414
- onPress: () => hasPropsData && setDiffMode("props"),
415
- activeOpacity: hasPropsData ? 0.7 : 1,
416
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
417
- style: [styles.diffModeTabText, diffMode === "props" && styles.diffModeTabTextActive, !hasPropsData && styles.diffModeTabTextDisabled],
418
- children: "PROPS"
419
- })
420
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
421
- style: [styles.diffModeTab, diffMode === "state" && styles.diffModeTabActive, !hasStateData && styles.diffModeTabDisabled],
422
- onPress: () => hasStateData && setDiffMode("state"),
423
- activeOpacity: hasStateData ? 0.7 : 1,
424
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
425
- style: [styles.diffModeTabText, diffMode === "state" && styles.diffModeTabTextActive, !hasStateData && styles.diffModeTabTextDisabled],
426
- children: "STATE"
427
- })
428
- })]
429
- }), diffMode === "cause" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
430
- style: styles.diffSummary,
431
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_RenderCauseBadge.EnhancedCauseDisplay, {
432
- cause: currentEvent.cause,
433
- nativeType: render.viewType
434
- })
435
- }), diffMode === "props" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
436
- style: styles.treeDiffContainer,
437
- children: hasPropsData ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.TreeDiffViewer, {
438
- oldValue: previousEvent.capturedProps,
439
- newValue: currentEvent.capturedProps,
440
- theme: "dark",
441
- showUnchanged: true
442
- }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
443
- style: styles.noDiffData,
444
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
445
- style: styles.noDiffDataTitle,
446
- children: "Props Not Captured"
447
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
448
- style: styles.noDiffDataText,
449
- children: "Enable \"Capture Props on Render\" in settings to see props diff."
450
- })]
451
- })
452
- }), diffMode === "state" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
453
- style: styles.treeDiffContainer,
454
- children: hasStateData ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.TreeDiffViewer, {
455
- oldValue: previousEvent.capturedState,
456
- newValue: currentEvent.capturedState,
457
- theme: "dark",
458
- showUnchanged: true
459
- }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
460
- style: styles.noDiffData,
461
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
462
- style: styles.noDiffDataTitle,
463
- children: "State Not Captured"
464
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
465
- style: styles.noDiffDataText,
466
- children: "Enable \"Capture State on Render\" in settings to see state diff."
467
- })]
468
- })
469
- })]
470
- });
471
- }
472
-
473
- /**
474
- * External footer component for modal integration
475
- * Uses renderHistory for events (only available when history tracking is enabled)
476
- */
477
- function RenderHistoryFooter({
478
- render,
479
- selectedEventIndex = 0,
480
- onEventIndexChange = () => {},
481
- isPro = false
482
- }) {
483
- // Get all events from render history (sorted by timestamp)
484
- const allEvents = (0, _react.useMemo)(() => {
485
- if (!render.renderHistory || render.renderHistory.length === 0) {
486
- return [];
487
- }
488
- return [...render.renderHistory].sort((a, b) => a.timestamp - b.timestamp);
489
- }, [render.renderHistory]);
490
-
491
- // Same cap as RenderHistoryViewer above; `isPro` remains a caller override.
492
- const tierLimit = (0, _sharedUi.useLimit)("highlightUpdates.historyEvents");
493
- const eventLimit = isPro ? Infinity : tierLimit;
494
-
495
- // Most recent N (negative index clamps to 0, so unlimited returns all).
496
- const events = (0, _react.useMemo)(() => allEvents.slice(-eventLimit), [allEvents, eventLimit]);
497
- const totalEvents = events.length;
498
- const currentEvent = events[selectedEventIndex];
499
- const goToPrevious = (0, _react.useCallback)(() => {
500
- onEventIndexChange(Math.max(0, selectedEventIndex - 1));
501
- }, [selectedEventIndex, onEventIndexChange]);
502
- const goToNext = (0, _react.useCallback)(() => {
503
- onEventIndexChange(Math.min(totalEvents - 1, selectedEventIndex + 1));
504
- }, [selectedEventIndex, totalEvents, onEventIndexChange]);
505
-
506
- // Don't render if no history events (history tracking might be disabled)
507
- if (totalEvents <= 1) {
508
- return null;
509
- }
510
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.EventStepperFooter, {
511
- currentIndex: selectedEventIndex,
512
- totalItems: totalEvents,
513
- onPrevious: goToPrevious,
514
- onNext: goToNext,
515
- itemLabel: "Render",
516
- subtitle: currentEvent ? (0, _sharedUi.formatRelativeTime)(new Date(currentEvent.timestamp)) : undefined
517
- });
518
- }
519
- const styles = _reactNative.StyleSheet.create({
520
- container: {
521
- flex: 1,
522
- // Transparent so JsModal's ToolBackground shows through (the modal paints opaque base beneath it).
523
- backgroundColor: "transparent"
524
- },
525
- emptyContainer: {
526
- flex: 1,
527
- alignItems: "center",
528
- justifyContent: "center",
529
- padding: 32,
530
- gap: 12
531
- },
532
- emptyTitle: {
533
- fontSize: 16,
534
- fontWeight: "600",
535
- color: _sharedUi.night.color.text
536
- },
537
- emptyText: {
538
- fontSize: 13,
539
- color: _sharedUi.night.color.textSecondary,
540
- textAlign: "center",
541
- lineHeight: 18
542
- },
543
- viewToggleContainer: {
544
- flexDirection: "row",
545
- padding: 12,
546
- gap: 8
547
- },
548
- viewToggleCard: {
549
- flex: 1,
550
- backgroundColor: _sharedUi.night.color.surface,
551
- borderRadius: 8,
552
- borderWidth: 1,
553
- borderColor: _sharedUi.night.color.border,
554
- padding: 10,
555
- gap: 4
556
- },
557
- viewToggleCardActive: {
558
- borderColor: _sharedUi.night.color.accentBorderStrong,
559
- backgroundColor: _sharedUi.night.color.accentSoft
560
- },
561
- viewToggleCardDisabled: {
562
- opacity: 0.5
563
- },
564
- todoBadge: {
565
- backgroundColor: _sharedUi.night.color.fillSecondary,
566
- paddingHorizontal: 6,
567
- paddingVertical: 2,
568
- borderRadius: 4,
569
- marginLeft: 4
570
- },
571
- todoBadgeText: {
572
- fontSize: 9,
573
- fontWeight: "700",
574
- color: _sharedUi.night.color.textTertiary,
575
- letterSpacing: 0.3
576
- },
577
- viewToggleContent: {
578
- flexDirection: "row",
579
- alignItems: "center",
580
- gap: 6
581
- },
582
- viewToggleLabel: {
583
- fontSize: 10,
584
- fontWeight: "700",
585
- color: _sharedUi.night.color.textSecondary,
586
- letterSpacing: 0.5
587
- },
588
- viewToggleLabelActive: {
589
- color: _sharedUi.night.color.accent
590
- },
591
- viewToggleLabelDisabled: {
592
- color: _sharedUi.night.color.textTertiary
593
- },
594
- viewToggleDescription: {
595
- fontSize: 11,
596
- color: _sharedUi.night.color.textTertiary,
597
- marginTop: 2
598
- },
599
- contentScroll: {
600
- flex: 1
601
- },
602
- contentContainer: {
603
- padding: 12,
604
- paddingTop: 0
605
- },
606
- noEventContainer: {
607
- padding: 24,
608
- alignItems: "center"
609
- },
610
- noEventText: {
611
- fontSize: 13,
612
- color: _sharedUi.night.color.textTertiary
613
- },
614
- currentStateContainer: {
615
- gap: 12
616
- },
617
- eventHeader: {
618
- flexDirection: "row",
619
- alignItems: "center",
620
- justifyContent: "space-between",
621
- backgroundColor: _sharedUi.night.color.surface,
622
- borderRadius: 8,
623
- borderWidth: 1,
624
- borderColor: _sharedUi.night.color.border,
625
- padding: 12
626
- },
627
- eventHeaderLeft: {
628
- gap: 2
629
- },
630
- eventTitle: {
631
- fontSize: 15,
632
- fontWeight: "700",
633
- color: _sharedUi.night.color.text
634
- },
635
- eventTime: {
636
- fontSize: 11,
637
- color: _sharedUi.night.color.textTertiary,
638
- fontFamily: _sharedUi.monoFont
639
- },
640
- eventBadge: {
641
- flexDirection: "row",
642
- alignItems: "center",
643
- paddingHorizontal: 10,
644
- paddingVertical: 4,
645
- borderRadius: 12,
646
- gap: 6
647
- },
648
- eventBadgeDot: {
649
- width: 6,
650
- height: 6,
651
- borderRadius: 3
652
- },
653
- eventBadgeText: {
654
- fontSize: 10,
655
- fontWeight: "700",
656
- fontFamily: _sharedUi.monoFont
657
- },
658
- section: {
659
- backgroundColor: _sharedUi.night.color.surface,
660
- borderRadius: 8,
661
- borderWidth: 1,
662
- borderColor: _sharedUi.night.color.border,
663
- overflow: "hidden"
664
- },
665
- sectionContent: {
666
- padding: 12,
667
- paddingTop: 8
668
- },
669
- causeContainer: {
670
- marginBottom: 12
671
- },
672
- changedList: {
673
- marginBottom: 12,
674
- paddingLeft: 4
675
- },
676
- changedListTitle: {
677
- fontSize: 11,
678
- fontWeight: "600",
679
- color: _sharedUi.night.color.textSecondary,
680
- marginBottom: 6
681
- },
682
- changedItem: {
683
- fontSize: 12,
684
- color: _sharedUi.night.color.text,
685
- fontFamily: _sharedUi.monoFont,
686
- marginBottom: 3,
687
- paddingLeft: 8
688
- },
689
- propsScrollView: {
690
- maxHeight: 150
691
- },
692
- propsJson: {
693
- fontSize: 11,
694
- fontFamily: _sharedUi.monoFont,
695
- color: _sharedUi.night.color.text,
696
- // Inset code box — the night track color.
697
- backgroundColor: _sharedUi.night.color.bg,
698
- padding: 10,
699
- borderRadius: 6
700
- },
701
- diffContainer: {
702
- gap: 12
703
- },
704
- compareBar: {
705
- flexDirection: "row",
706
- backgroundColor: _sharedUi.night.color.surface,
707
- borderRadius: 8,
708
- borderWidth: 1,
709
- borderColor: _sharedUi.night.color.border,
710
- padding: 10
711
- },
712
- compareSide: {
713
- flex: 1,
714
- gap: 4
715
- },
716
- compareLabelRow: {
717
- flexDirection: "row",
718
- alignItems: "center",
719
- gap: 8
720
- },
721
- compareLabel: {
722
- fontSize: 10,
723
- fontWeight: "700",
724
- letterSpacing: 0.5
725
- },
726
- compareActionBadge: {
727
- paddingHorizontal: 6,
728
- paddingVertical: 2,
729
- borderRadius: 4
730
- },
731
- compareActionText: {
732
- fontSize: 9,
733
- fontWeight: "600"
734
- },
735
- compareMeta: {
736
- flexDirection: "row",
737
- alignItems: "center",
738
- gap: 6
739
- },
740
- compareIndex: {
741
- fontSize: 12,
742
- fontWeight: "600",
743
- color: _sharedUi.night.color.text
744
- },
745
- compareTime: {
746
- fontSize: 10,
747
- color: _sharedUi.night.color.textTertiary,
748
- fontFamily: _sharedUi.monoFont
749
- },
750
- compareDivider: {
751
- width: 30,
752
- alignItems: "center",
753
- justifyContent: "center"
754
- },
755
- compareArrow: {
756
- fontSize: 16,
757
- color: _sharedUi.night.color.textTertiary
758
- },
759
- diffSummary: {
760
- backgroundColor: _sharedUi.night.color.surface,
761
- borderRadius: 8,
762
- borderWidth: 1,
763
- borderColor: _sharedUi.night.color.border,
764
- padding: 12
765
- },
766
- diffSummaryTitle: {
767
- fontSize: 11,
768
- fontWeight: "600",
769
- color: _sharedUi.night.color.textSecondary,
770
- marginBottom: 8
771
- },
772
- diffChanges: {
773
- gap: 4
774
- },
775
- diffChangeItem: {
776
- flexDirection: "row",
777
- alignItems: "center",
778
- gap: 6
779
- },
780
- diffChangeIcon: {
781
- fontSize: 12,
782
- fontWeight: "700",
783
- color: _sharedUi.night.color.warning,
784
- fontFamily: _sharedUi.monoFont
785
- },
786
- diffChangeKey: {
787
- fontSize: 12,
788
- color: _sharedUi.night.color.text,
789
- fontFamily: _sharedUi.monoFont
790
- },
791
- diffNoChanges: {
792
- fontSize: 12,
793
- color: _sharedUi.night.color.textTertiary,
794
- fontStyle: "italic"
795
- },
796
- diffPlaceholder: {
797
- fontSize: 12,
798
- color: _sharedUi.night.color.textTertiary,
799
- fontStyle: "italic",
800
- textAlign: "center",
801
- padding: 16
802
- },
803
- // Diff mode tabs
804
- diffModeTabs: {
805
- flexDirection: "row",
806
- backgroundColor: _sharedUi.night.color.surface,
807
- borderRadius: 8,
808
- borderWidth: 1,
809
- borderColor: _sharedUi.night.color.border,
810
- padding: 4,
811
- gap: 4
812
- },
813
- diffModeTab: {
814
- flex: 1,
815
- paddingVertical: 8,
816
- paddingHorizontal: 12,
817
- borderRadius: 6,
818
- alignItems: "center"
819
- },
820
- diffModeTabActive: {
821
- backgroundColor: _sharedUi.night.color.accentSoft
822
- },
823
- diffModeTabDisabled: {
824
- opacity: 0.4
825
- },
826
- diffModeTabText: {
827
- fontSize: 10,
828
- fontWeight: "600",
829
- color: _sharedUi.night.color.textSecondary,
830
- letterSpacing: 0.5
831
- },
832
- diffModeTabTextActive: {
833
- color: _sharedUi.night.color.accent
834
- },
835
- diffModeTabTextDisabled: {
836
- color: _sharedUi.night.color.textTertiary
837
- },
838
- // Cause diff styles
839
- causeDiffContainer: {
840
- gap: 8,
841
- marginBottom: 12
842
- },
843
- causeDiffRow: {
844
- flexDirection: "row",
845
- alignItems: "center",
846
- gap: 8
847
- },
848
- causeDiffLabel: {
849
- fontSize: 11,
850
- fontWeight: "600",
851
- color: _sharedUi.night.color.textSecondary,
852
- minWidth: 80
853
- },
854
- causeDiffValue: {
855
- fontSize: 12,
856
- color: _sharedUi.night.color.text,
857
- fontFamily: _sharedUi.monoFont,
858
- fontWeight: "500"
859
- },
860
- diffChangesTitle: {
861
- fontSize: 11,
862
- fontWeight: "600",
863
- color: _sharedUi.night.color.textSecondary,
864
- marginBottom: 6
865
- },
866
- // Tree diff container
867
- treeDiffContainer: {
868
- backgroundColor: _sharedUi.night.color.surface,
869
- borderRadius: 8,
870
- borderWidth: 1,
871
- borderColor: _sharedUi.night.color.border,
872
- overflow: "hidden",
873
- minHeight: 150
874
- },
875
- noDiffData: {
876
- padding: 24,
877
- alignItems: "center",
878
- gap: 8
879
- },
880
- noDiffDataTitle: {
881
- fontSize: 13,
882
- fontWeight: "600",
883
- color: _sharedUi.night.color.text
884
- },
885
- noDiffDataText: {
886
- fontSize: 12,
887
- color: _sharedUi.night.color.textTertiary,
888
- textAlign: "center",
889
- lineHeight: 18
890
- },
891
- lockedBanner: {
892
- flexDirection: "row",
893
- alignItems: "center",
894
- justifyContent: "center",
895
- paddingVertical: 10,
896
- paddingHorizontal: 16,
897
- marginHorizontal: 12,
898
- marginTop: 8,
899
- backgroundColor: _sharedUi.night.color.warningSoft,
900
- borderRadius: 8,
901
- borderWidth: 1,
902
- borderColor: _sharedUi.night.color.warning + "30",
903
- gap: 8
904
- },
905
- lockedBannerText: {
906
- color: _sharedUi.night.color.warning,
907
- fontSize: 13,
908
- fontWeight: "500"
909
- },
910
- lockedBannerSubtext: {
911
- color: _sharedUi.night.color.textTertiary,
912
- fontSize: 12
913
- }
914
- });
915
- var _default = exports.default = RenderHistoryViewer;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.RenderHistoryFooter=RenderHistoryFooter;exports.RenderHistoryViewer=RenderHistoryViewer;exports.default=void 0;var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _dataViewer=require("@buoy-gg/shared-ui/dataViewer");var _RenderTracker=require("../utils/RenderTracker");var _RenderCauseBadge=require("./RenderCauseBadge");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(e,t){if("function"==typeof WeakMap)var l=new WeakMap,n=new WeakMap;return(_interopRequireWildcard=function(o,c){if(!c&&o&&o.__esModule)return o;var s,r,i={__proto__:null,default:o};if(null===o||"object"!=typeof o&&"function"!=typeof o)return i;if(s=c?n:l){if(s.has(o))return s.get(o);s.set(o,i)}for(const a in o)"default"!==a&&{}.hasOwnProperty.call(o,a)&&((r=(s=Object.defineProperty)&&Object.getOwnPropertyDescriptor(o,a))&&(r.get||r.set)?s(i,a,r):i[a]=o[a]);return i})(e,t)}function formatTimeWithMs(e){const t=new Date(e);const l=t.getHours().toString().padStart(2,"0");const n=t.getMinutes().toString().padStart(2,"0");const o=t.getSeconds().toString().padStart(2,"0");const c=t.getMilliseconds().toString().padStart(3,"0");return`${l}:${n}:${o}.${c}`}function RenderHistoryViewer({render:e,disableInternalFooter:t=false,selectedEventIndex:l,onEventIndexChange:n,isPro:o=false}){const[c,s]=(0,_react.useState)(0);const r=l??c;const i=n??s;const[a,p]=(0,_react.useState)("current");const d=(0,_react.useMemo)(()=>{if(!e.renderHistory||e.renderHistory.length===0){return[]}return[...e.renderHistory].sort((x,S)=>x.timestamp-S.timestamp)},[e.renderHistory]);const u=(0,_sharedUi.useLimit)("highlightUpdates.historyEvents");const g=o?Infinity:u;const y=(0,_react.useMemo)(()=>d.slice(-g),[d,g]);const T=(0,_react.useMemo)(()=>Math.max(0,d.length-g),[d.length,g]);const h=y.length;const f=y[r];const m=r>0?y[r-1]:null;const b=(0,_react.useCallback)(()=>{if(r>0){i(r-1)}},[r,i]);const w=(0,_react.useCallback)(()=>{if(r<h-1){i(r+1)}},[r,h,i]);if(h===0){const x=_RenderTracker.RenderTracker.getSettings().enableRenderHistory;return(0,_jsxRuntime.jsx)(_sharedUi.ToolEmptyState,{testID:"buoy-highlight-history-empty",otto:x?"stare":"paused",title:"No Render History",message:x?"History is on and armed \u2014 this component has not re-rendered since. Interact with the app to record one.":"Enable render history tracking in settings to see render events here."})}return(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.container,{paddingBottom:!t&&h>1?80:0}],children:[T>0&&(0,_jsxRuntime.jsxs)(_reactNative.View,{testID:"buoy-highlight-history-locked",style:styles.lockedBanner,children:[(0,_jsxRuntime.jsx)(_sharedUi.Lock,{size:14,color:_sharedUi.night.color.warning}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{testID:"buoy-highlight-history-locked-text",style:styles.lockedBannerText,children:[T," older ",T===1?"render":"renders"," locked"]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.lockedBannerSubtext,children:"Upgrade to Pro"})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.viewToggleContainer,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"buoy-highlight-history-mode-current",accessibilityRole:"button",accessibilityLabel:"Current state",style:[styles.viewToggleCard,a==="current"&&styles.viewToggleCardActive],onPress:()=>p("current"),activeOpacity:.8,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.viewToggleContent,children:[(0,_jsxRuntime.jsx)(_sharedUi.Database,{size:16,color:a==="current"?_sharedUi.night.color.accent:_sharedUi.night.color.textSecondary}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.viewToggleLabel,a==="current"&&styles.viewToggleLabelActive],children:"CURRENT STATE"})]}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:[styles.viewToggleDescription,a==="current"&&{color:_sharedUi.night.color.text}],children:["View render #",f?.renderNumber??0," details"]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{testID:"buoy-highlight-history-mode-diff",accessibilityLabel:"Diff view, coming soon",style:[styles.viewToggleCard,styles.viewToggleCardDisabled],children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.viewToggleContent,children:[(0,_jsxRuntime.jsx)(_sharedUi.GitBranch,{size:16,color:_sharedUi.night.color.textTertiary}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.viewToggleLabel,styles.viewToggleLabelDisabled],children:"DIFF VIEW"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.todoBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.todoBadgeText,children:"TODO"})})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.viewToggleDescription,{color:_sharedUi.night.color.textTertiary}],children:"Compare renders side by side (coming soon)"})]})]}),(0,_jsxRuntime.jsx)(_reactNative.ScrollView,{testID:"buoy-highlight-history-scroll",style:styles.contentScroll,contentContainerStyle:styles.contentContainer,showsVerticalScrollIndicator:false,children:a==="current"?(0,_jsxRuntime.jsx)(CurrentStateView,{event:f,render:e}):(0,_jsxRuntime.jsx)(DiffView,{previousEvent:m,currentEvent:f,render:e})})]}),!t&&(0,_jsxRuntime.jsx)(_sharedUi.EventStepperFooter,{currentIndex:r,totalItems:h,onPrevious:b,onNext:w,itemLabel:"Render",subtitle:(0,_sharedUi.formatRelativeTime)(new Date(f?.timestamp??Date.now()))})]})}function CurrentStateView({event:e,render:t}){if(!e){return(0,_jsxRuntime.jsx)(_reactNative.View,{testID:"buoy-highlight-history-no-event",style:styles.noEventContainer,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.noEventText,children:"No event selected"})})}const l=_RenderCauseBadge.CAUSE_CONFIG[e.cause.type];return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.currentStateContainer,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.eventHeader,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.eventHeaderLeft,children:[(0,_jsxRuntime.jsxs)(_reactNative.Text,{testID:"buoy-highlight-history-event-title",style:styles.eventTitle,children:["Render #",e.renderNumber]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:"buoy-highlight-history-event-time",style:styles.eventTime,children:formatTimeWithMs(e.timestamp)})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.eventBadge,{backgroundColor:t.color+"30"}],children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.eventBadgeDot,{backgroundColor:t.color}]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:"buoy-highlight-history-event-cause",style:[styles.eventBadgeText,{color:t.color}],children:e.cause.type.toUpperCase()})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Clock,color:l.color,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"WHY DID THIS RENDER?"})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.sectionContent,children:(0,_jsxRuntime.jsx)(_RenderCauseBadge.EnhancedCauseDisplay,{cause:e.cause,nativeType:t.viewType})})]}),e.capturedProps&&Object.keys(e.capturedProps).length>0&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Database,color:_sharedUi.night.color.accent,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"CAPTURED PROPS"})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.sectionContent,children:(0,_jsxRuntime.jsx)(_reactNative.ScrollView,{horizontal:true,showsHorizontalScrollIndicator:false,style:styles.propsScrollView,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:"buoy-highlight-history-props",style:styles.propsJson,children:JSON.stringify(e.capturedProps,null,2)})})})]})]})}function DiffView({previousEvent:e,currentEvent:t,render:l}){const[n,o]=(0,_react.useState)("props");if(!e||!t){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.noEventContainer,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.noEventText,children:"Select an event with a previous event to compare"})})}const c=_RenderCauseBadge.CAUSE_CONFIG[e.cause.type];const s=_RenderCauseBadge.CAUSE_CONFIG[t.cause.type];const r=e.capturedProps&&t.capturedProps;const i=e.capturedState&&t.capturedState;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.diffContainer,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.compareBar,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.compareSide,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.compareLabelRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.compareLabel,{color:_sharedUi.buoyColors.warning}],children:"PREV"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.compareActionBadge,{backgroundColor:`${c.color}20`}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.compareActionText,{color:c.color}],children:e.cause.type.toUpperCase()})})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.compareMeta,children:[(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.compareIndex,children:["#",e.renderNumber]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.compareTime,children:formatTimeWithMs(e.timestamp)})]})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.compareDivider,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.compareArrow,children:"\u2192"})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.compareSide,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.compareLabelRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.compareLabel,{color:_sharedUi.buoyColors.success}],children:"CUR"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.compareActionBadge,{backgroundColor:`${s.color}20`}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.compareActionText,{color:s.color}],children:t.cause.type.toUpperCase()})})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.compareMeta,children:[(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.compareIndex,children:["#",t.renderNumber]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.compareTime,children:formatTimeWithMs(t.timestamp)})]})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.diffModeTabs,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.diffModeTab,n==="cause"&&styles.diffModeTabActive],onPress:()=>o("cause"),activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.diffModeTabText,n==="cause"&&styles.diffModeTabTextActive],children:"CAUSE"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.diffModeTab,n==="props"&&styles.diffModeTabActive,!r&&styles.diffModeTabDisabled],onPress:()=>r&&o("props"),activeOpacity:r?.7:1,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.diffModeTabText,n==="props"&&styles.diffModeTabTextActive,!r&&styles.diffModeTabTextDisabled],children:"PROPS"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.diffModeTab,n==="state"&&styles.diffModeTabActive,!i&&styles.diffModeTabDisabled],onPress:()=>i&&o("state"),activeOpacity:i?.7:1,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.diffModeTabText,n==="state"&&styles.diffModeTabTextActive,!i&&styles.diffModeTabTextDisabled],children:"STATE"})})]}),n==="cause"&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.diffSummary,children:(0,_jsxRuntime.jsx)(_RenderCauseBadge.EnhancedCauseDisplay,{cause:t.cause,nativeType:l.viewType})}),n==="props"&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.treeDiffContainer,children:r?(0,_jsxRuntime.jsx)(_dataViewer.TreeDiffViewer,{oldValue:e.capturedProps,newValue:t.capturedProps,theme:"dark",showUnchanged:true}):(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.noDiffData,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.noDiffDataTitle,children:"Props Not Captured"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.noDiffDataText,children:'Enable "Capture Props on Render" in settings to see props diff.'})]})}),n==="state"&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.treeDiffContainer,children:i?(0,_jsxRuntime.jsx)(_dataViewer.TreeDiffViewer,{oldValue:e.capturedState,newValue:t.capturedState,theme:"dark",showUnchanged:true}):(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.noDiffData,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.noDiffDataTitle,children:"State Not Captured"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.noDiffDataText,children:'Enable "Capture State on Render" in settings to see state diff.'})]})})]})}function RenderHistoryFooter({render:e,selectedEventIndex:t=0,onEventIndexChange:l=()=>{},isPro:n=false}){const o=(0,_react.useMemo)(()=>{if(!e.renderHistory||e.renderHistory.length===0){return[]}return[...e.renderHistory].sort((u,g)=>u.timestamp-g.timestamp)},[e.renderHistory]);const c=(0,_sharedUi.useLimit)("highlightUpdates.historyEvents");const s=n?Infinity:c;const r=(0,_react.useMemo)(()=>o.slice(-s),[o,s]);const i=r.length;const a=r[t];const p=(0,_react.useCallback)(()=>{l(Math.max(0,t-1))},[t,l]);const d=(0,_react.useCallback)(()=>{l(Math.min(i-1,t+1))},[t,i,l]);if(i<=1){return null}return(0,_jsxRuntime.jsx)(_sharedUi.EventStepperFooter,{currentIndex:t,totalItems:i,onPrevious:p,onNext:d,itemLabel:"Render",subtitle:a?(0,_sharedUi.formatRelativeTime)(new Date(a.timestamp)):void 0})}const styles=_reactNative.StyleSheet.create({container:{flex:1,backgroundColor:"transparent"},emptyContainer:{flex:1,alignItems:"center",justifyContent:"center",padding:32,gap:12},emptyTitle:{fontSize:16,fontWeight:"600",color:_sharedUi.night.color.text},emptyText:{fontSize:13,color:_sharedUi.night.color.textSecondary,textAlign:"center",lineHeight:18},viewToggleContainer:{flexDirection:"row",padding:12,gap:8},viewToggleCard:{flex:1,backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:10,gap:4},viewToggleCardActive:{borderColor:_sharedUi.night.color.accentBorderStrong,backgroundColor:_sharedUi.night.color.accentSoft},viewToggleCardDisabled:{opacity:.5},todoBadge:{backgroundColor:_sharedUi.night.color.fillSecondary,paddingHorizontal:6,paddingVertical:2,borderRadius:4,marginLeft:4},todoBadgeText:{fontSize:9,fontWeight:"700",color:_sharedUi.night.color.textTertiary,letterSpacing:.3},viewToggleContent:{flexDirection:"row",alignItems:"center",gap:6},viewToggleLabel:{fontSize:10,fontWeight:"700",color:_sharedUi.night.color.textSecondary,letterSpacing:.5},viewToggleLabelActive:{color:_sharedUi.night.color.accent},viewToggleLabelDisabled:{color:_sharedUi.night.color.textTertiary},viewToggleDescription:{fontSize:11,color:_sharedUi.night.color.textTertiary,marginTop:2},contentScroll:{flex:1},contentContainer:{padding:12,paddingTop:0},noEventContainer:{padding:24,alignItems:"center"},noEventText:{fontSize:13,color:_sharedUi.night.color.textTertiary},currentStateContainer:{gap:12},eventHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:12},eventHeaderLeft:{gap:2},eventTitle:{fontSize:15,fontWeight:"700",color:_sharedUi.night.color.text},eventTime:{fontSize:11,color:_sharedUi.night.color.textTertiary,fontFamily:_sharedUi.monoFont},eventBadge:{flexDirection:"row",alignItems:"center",paddingHorizontal:10,paddingVertical:4,borderRadius:12,gap:6},eventBadgeDot:{width:6,height:6,borderRadius:3},eventBadgeText:{fontSize:10,fontWeight:"700",fontFamily:_sharedUi.monoFont},section:{backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,overflow:"hidden"},sectionContent:{padding:12,paddingTop:8},causeContainer:{marginBottom:12},changedList:{marginBottom:12,paddingLeft:4},changedListTitle:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.textSecondary,marginBottom:6},changedItem:{fontSize:12,color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont,marginBottom:3,paddingLeft:8},propsScrollView:{maxHeight:150},propsJson:{fontSize:11,fontFamily:_sharedUi.monoFont,color:_sharedUi.night.color.text,backgroundColor:_sharedUi.night.color.bg,padding:10,borderRadius:6},diffContainer:{gap:12},compareBar:{flexDirection:"row",backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:10},compareSide:{flex:1,gap:4},compareLabelRow:{flexDirection:"row",alignItems:"center",gap:8},compareLabel:{fontSize:10,fontWeight:"700",letterSpacing:.5},compareActionBadge:{paddingHorizontal:6,paddingVertical:2,borderRadius:4},compareActionText:{fontSize:9,fontWeight:"600"},compareMeta:{flexDirection:"row",alignItems:"center",gap:6},compareIndex:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.text},compareTime:{fontSize:10,color:_sharedUi.night.color.textTertiary,fontFamily:_sharedUi.monoFont},compareDivider:{width:30,alignItems:"center",justifyContent:"center"},compareArrow:{fontSize:16,color:_sharedUi.night.color.textTertiary},diffSummary:{backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:12},diffSummaryTitle:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.textSecondary,marginBottom:8},diffChanges:{gap:4},diffChangeItem:{flexDirection:"row",alignItems:"center",gap:6},diffChangeIcon:{fontSize:12,fontWeight:"700",color:_sharedUi.night.color.warning,fontFamily:_sharedUi.monoFont},diffChangeKey:{fontSize:12,color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},diffNoChanges:{fontSize:12,color:_sharedUi.night.color.textTertiary,fontStyle:"italic"},diffPlaceholder:{fontSize:12,color:_sharedUi.night.color.textTertiary,fontStyle:"italic",textAlign:"center",padding:16},diffModeTabs:{flexDirection:"row",backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:4,gap:4},diffModeTab:{flex:1,paddingVertical:8,paddingHorizontal:12,borderRadius:6,alignItems:"center"},diffModeTabActive:{backgroundColor:_sharedUi.night.color.accentSoft},diffModeTabDisabled:{opacity:.4},diffModeTabText:{fontSize:10,fontWeight:"600",color:_sharedUi.night.color.textSecondary,letterSpacing:.5},diffModeTabTextActive:{color:_sharedUi.night.color.accent},diffModeTabTextDisabled:{color:_sharedUi.night.color.textTertiary},causeDiffContainer:{gap:8,marginBottom:12},causeDiffRow:{flexDirection:"row",alignItems:"center",gap:8},causeDiffLabel:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.textSecondary,minWidth:80},causeDiffValue:{fontSize:12,color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont,fontWeight:"500"},diffChangesTitle:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.textSecondary,marginBottom:6},treeDiffContainer:{backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,overflow:"hidden",minHeight:150},noDiffData:{padding:24,alignItems:"center",gap:8},noDiffDataTitle:{fontSize:13,fontWeight:"600",color:_sharedUi.night.color.text},noDiffDataText:{fontSize:12,color:_sharedUi.night.color.textTertiary,textAlign:"center",lineHeight:18},lockedBanner:{flexDirection:"row",alignItems:"center",justifyContent:"center",paddingVertical:10,paddingHorizontal:16,marginHorizontal:12,marginTop:8,backgroundColor:_sharedUi.night.color.warningSoft,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.warning+"30",gap:8},lockedBannerText:{color:_sharedUi.night.color.warning,fontSize:13,fontWeight:"500"},lockedBannerSubtext:{color:_sharedUi.night.color.textTertiary,fontSize:12}});var _default=exports.default=RenderHistoryViewer;