@buoy-gg/shared-ui 7.0.16 → 7.0.18

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 (111) hide show
  1. package/lib/commonjs/dataViewer/ThemedSplitView.js +622 -0
  2. package/lib/commonjs/dataViewer/index.js +32 -0
  3. package/lib/commonjs/dataViewer/objectDiff.js +304 -0
  4. package/lib/commonjs/hooks/index.js +7 -0
  5. package/lib/commonjs/hooks/safe-area-impl.js +1 -1
  6. package/lib/commonjs/hooks/usePersistedState.js +71 -0
  7. package/lib/commonjs/icons/index.js +14 -0
  8. package/lib/commonjs/index.js +61 -0
  9. package/lib/commonjs/storage/devToolsStorageKeys.js +31 -0
  10. package/lib/commonjs/sync/wireBudget.js +97 -0
  11. package/lib/commonjs/ui/components/HeaderSearchButton.js +6 -1
  12. package/lib/commonjs/ui/components/ModalHeader.js +69 -0
  13. package/lib/commonjs/ui/components/ToolButton.js +90 -0
  14. package/lib/commonjs/ui/components/index.js +7 -0
  15. package/lib/commonjs/ui/index.js +8 -0
  16. package/lib/commonjs/ui/toolTheme.js +96 -0
  17. package/lib/commonjs/utils/index.js +38 -0
  18. package/lib/commonjs/utils/persistentStorage.js +6 -3
  19. package/lib/commonjs/utils/stateSnapshotRegistry.js +71 -0
  20. package/lib/module/dataViewer/ThemedSplitView.js +617 -0
  21. package/lib/module/dataViewer/index.js +7 -1
  22. package/lib/module/dataViewer/objectDiff.js +297 -0
  23. package/lib/module/hooks/index.js +1 -0
  24. package/lib/module/hooks/safe-area-impl.js +1 -1
  25. package/lib/module/hooks/usePersistedState.js +68 -0
  26. package/lib/module/icons/index.js +1 -0
  27. package/lib/module/index.js +6 -1
  28. package/lib/module/storage/devToolsStorageKeys.js +31 -0
  29. package/lib/module/sync/wireBudget.js +92 -0
  30. package/lib/module/ui/components/HeaderSearchButton.js +6 -1
  31. package/lib/module/ui/components/ModalHeader.js +70 -2
  32. package/lib/module/ui/components/ToolButton.js +86 -0
  33. package/lib/module/ui/components/index.js +1 -0
  34. package/lib/module/ui/index.js +3 -0
  35. package/lib/module/ui/toolTheme.js +93 -0
  36. package/lib/module/utils/index.js +2 -0
  37. package/lib/module/utils/persistentStorage.js +6 -3
  38. package/lib/module/utils/stateSnapshotRegistry.js +64 -0
  39. package/lib/typescript/commonjs/dataViewer/ThemedSplitView.d.ts +28 -0
  40. package/lib/typescript/commonjs/dataViewer/ThemedSplitView.d.ts.map +1 -0
  41. package/lib/typescript/commonjs/dataViewer/index.d.ts +2 -0
  42. package/lib/typescript/commonjs/dataViewer/index.d.ts.map +1 -1
  43. package/lib/typescript/commonjs/dataViewer/objectDiff.d.ts +67 -0
  44. package/lib/typescript/commonjs/dataViewer/objectDiff.d.ts.map +1 -0
  45. package/lib/typescript/commonjs/hooks/index.d.ts +1 -0
  46. package/lib/typescript/commonjs/hooks/index.d.ts.map +1 -1
  47. package/lib/typescript/commonjs/hooks/safe-area-impl.d.ts +1 -1
  48. package/lib/typescript/commonjs/hooks/usePersistedState.d.ts +16 -0
  49. package/lib/typescript/commonjs/hooks/usePersistedState.d.ts.map +1 -0
  50. package/lib/typescript/commonjs/icons/index.d.ts +1 -0
  51. package/lib/typescript/commonjs/icons/index.d.ts.map +1 -1
  52. package/lib/typescript/commonjs/index.d.ts +3 -2
  53. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  54. package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts +28 -0
  55. package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts.map +1 -1
  56. package/lib/typescript/commonjs/sync/wireBudget.d.ts +50 -0
  57. package/lib/typescript/commonjs/sync/wireBudget.d.ts.map +1 -0
  58. package/lib/typescript/commonjs/ui/components/HeaderSearchButton.d.ts +3 -1
  59. package/lib/typescript/commonjs/ui/components/HeaderSearchButton.d.ts.map +1 -1
  60. package/lib/typescript/commonjs/ui/components/ModalHeader.d.ts +13 -1
  61. package/lib/typescript/commonjs/ui/components/ModalHeader.d.ts.map +1 -1
  62. package/lib/typescript/commonjs/ui/components/ToolButton.d.ts +24 -0
  63. package/lib/typescript/commonjs/ui/components/ToolButton.d.ts.map +1 -0
  64. package/lib/typescript/commonjs/ui/components/index.d.ts +4 -0
  65. package/lib/typescript/commonjs/ui/components/index.d.ts.map +1 -1
  66. package/lib/typescript/commonjs/ui/index.d.ts +1 -0
  67. package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
  68. package/lib/typescript/commonjs/ui/toolTheme.d.ts +68 -0
  69. package/lib/typescript/commonjs/ui/toolTheme.d.ts.map +1 -0
  70. package/lib/typescript/commonjs/utils/index.d.ts +2 -0
  71. package/lib/typescript/commonjs/utils/index.d.ts.map +1 -1
  72. package/lib/typescript/commonjs/utils/persistentStorage.d.ts.map +1 -1
  73. package/lib/typescript/commonjs/utils/stateSnapshotRegistry.d.ts +111 -0
  74. package/lib/typescript/commonjs/utils/stateSnapshotRegistry.d.ts.map +1 -0
  75. package/lib/typescript/module/dataViewer/ThemedSplitView.d.ts +28 -0
  76. package/lib/typescript/module/dataViewer/ThemedSplitView.d.ts.map +1 -0
  77. package/lib/typescript/module/dataViewer/index.d.ts +2 -0
  78. package/lib/typescript/module/dataViewer/index.d.ts.map +1 -1
  79. package/lib/typescript/module/dataViewer/objectDiff.d.ts +67 -0
  80. package/lib/typescript/module/dataViewer/objectDiff.d.ts.map +1 -0
  81. package/lib/typescript/module/hooks/index.d.ts +1 -0
  82. package/lib/typescript/module/hooks/index.d.ts.map +1 -1
  83. package/lib/typescript/module/hooks/safe-area-impl.d.ts +1 -1
  84. package/lib/typescript/module/hooks/usePersistedState.d.ts +16 -0
  85. package/lib/typescript/module/hooks/usePersistedState.d.ts.map +1 -0
  86. package/lib/typescript/module/icons/index.d.ts +1 -0
  87. package/lib/typescript/module/icons/index.d.ts.map +1 -1
  88. package/lib/typescript/module/index.d.ts +3 -2
  89. package/lib/typescript/module/index.d.ts.map +1 -1
  90. package/lib/typescript/module/storage/devToolsStorageKeys.d.ts +28 -0
  91. package/lib/typescript/module/storage/devToolsStorageKeys.d.ts.map +1 -1
  92. package/lib/typescript/module/sync/wireBudget.d.ts +50 -0
  93. package/lib/typescript/module/sync/wireBudget.d.ts.map +1 -0
  94. package/lib/typescript/module/ui/components/HeaderSearchButton.d.ts +3 -1
  95. package/lib/typescript/module/ui/components/HeaderSearchButton.d.ts.map +1 -1
  96. package/lib/typescript/module/ui/components/ModalHeader.d.ts +13 -1
  97. package/lib/typescript/module/ui/components/ModalHeader.d.ts.map +1 -1
  98. package/lib/typescript/module/ui/components/ToolButton.d.ts +24 -0
  99. package/lib/typescript/module/ui/components/ToolButton.d.ts.map +1 -0
  100. package/lib/typescript/module/ui/components/index.d.ts +4 -0
  101. package/lib/typescript/module/ui/components/index.d.ts.map +1 -1
  102. package/lib/typescript/module/ui/index.d.ts +1 -0
  103. package/lib/typescript/module/ui/index.d.ts.map +1 -1
  104. package/lib/typescript/module/ui/toolTheme.d.ts +68 -0
  105. package/lib/typescript/module/ui/toolTheme.d.ts.map +1 -0
  106. package/lib/typescript/module/utils/index.d.ts +2 -0
  107. package/lib/typescript/module/utils/index.d.ts.map +1 -1
  108. package/lib/typescript/module/utils/persistentStorage.d.ts.map +1 -1
  109. package/lib/typescript/module/utils/stateSnapshotRegistry.d.ts +111 -0
  110. package/lib/typescript/module/utils/stateSnapshotRegistry.d.ts.map +1 -0
  111. package/package.json +4 -4
@@ -0,0 +1,622 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ThemedSplitView = ThemedSplitView;
7
+ var _react = require("react");
8
+ var _reactNative = require("react-native");
9
+ var _lineDiff = require("./lineDiff.js");
10
+ var _DiffSummary = require("./DiffSummary.js");
11
+ var _jsxRuntime = require("react/jsx-runtime");
12
+ /**
13
+ * ThemedSplitView — the production-grade split diff renderer, promoted from
14
+ * packages/storage (its original home) so every tool shares ONE copy.
15
+ *
16
+ * Compared to SplitDiffViewer: GitHub-style auto-folding of unchanged runs
17
+ * (CONTEXT_LINES / MIN_FOLD_SIZE), a memoized single-pass summary, FlatList
18
+ * virtualization when scrolling — and a documented inline branch, because a
19
+ * FlatList can't virtualize inside a page ScrollView (no viewport of its own
20
+ * to measure against), so inline mode renders rows directly.
21
+ */
22
+
23
+ /** Rendering options (the shape storage's DiffOptionsPanel edits). */
24
+
25
+ const DEFAULT_OPTIONS = {
26
+ hideLineNumbers: false,
27
+ disableWordDiff: false,
28
+ showDiffOnly: false,
29
+ compareMethod: "words",
30
+ contextLines: 3,
31
+ lineOffset: 0
32
+ };
33
+ function ThemedSplitView({
34
+ oldValue,
35
+ newValue,
36
+ theme,
37
+ options = DEFAULT_OPTIONS,
38
+ showThemeName = false,
39
+ scrollEnabled = true
40
+ }) {
41
+ // Inline mode drops the fixed 400pt pane so the container grows with the
42
+ // rows; the ancestor ScrollView is what scrolls them.
43
+ const dynamicStyles = (0, _react.useMemo)(() => createDynamicStyles(theme, scrollEnabled), [theme, scrollEnabled]);
44
+ const diffComputeOptions = (0, _react.useMemo)(() => ({
45
+ compareMethod: options.compareMethod,
46
+ disableWordDiff: options.disableWordDiff,
47
+ showDiffOnly: options.showDiffOnly,
48
+ contextLines: options.contextLines
49
+ }), [options.compareMethod, options.disableWordDiff, options.showDiffOnly, options.contextLines]);
50
+ const lineDiffs = (0, _react.useMemo)(() => (0, _lineDiff.computeLineDiff)(oldValue, newValue, diffComputeOptions), [oldValue, newValue, diffComputeOptions]);
51
+
52
+ // One pass for the summary instead of three .filter() calls per render.
53
+ const summary = (0, _react.useMemo)(() => {
54
+ let added = 0;
55
+ let removed = 0;
56
+ let modified = 0;
57
+ for (const d of lineDiffs) {
58
+ if (d.type === _lineDiff.DiffType.ADDED) added++;else if (d.type === _lineDiff.DiffType.REMOVED) removed++;else if (d.type === _lineDiff.DiffType.MODIFIED) modified++;
59
+ }
60
+ return {
61
+ added,
62
+ removed,
63
+ modified
64
+ };
65
+ }, [lineDiffs]);
66
+
67
+ // Auto-collapse runs of unchanged lines that aren't near a change. Keeps
68
+ // CONTEXT_LINES on either side of every change visible (GitHub-style), folds
69
+ // the rest into a tappable header.
70
+ const [expandedFolds, setExpandedFolds] = (0, _react.useState)(() => new Set());
71
+
72
+ // Reset fold expansion when the user actually switches comparisons. Parent
73
+ // memoizes oldValue/newValue, so this only fires on a real change — not on
74
+ // every re-render. First run is a no-op (initial state is already empty).
75
+ const hasMountedRef = (0, _react.useRef)(false);
76
+ (0, _react.useEffect)(() => {
77
+ if (!hasMountedRef.current) {
78
+ hasMountedRef.current = true;
79
+ return;
80
+ }
81
+ setExpandedFolds(new Set());
82
+ }, [oldValue, newValue]);
83
+ const items = (0, _react.useMemo)(() => buildSplitItems(lineDiffs, expandedFolds), [lineDiffs, expandedFolds]);
84
+ const toggleFold = (0, _react.useCallback)(foldId => {
85
+ setExpandedFolds(prev => {
86
+ const next = new Set(prev);
87
+ if (next.has(foldId)) next.delete(foldId);else next.add(foldId);
88
+ return next;
89
+ });
90
+ }, []);
91
+ const keyExtractor = (0, _react.useCallback)(item => item.kind === "row" ? `r:${item.diffIndex}` : `f:${item.foldId}`, []);
92
+ const renderSplitItem = (0, _react.useCallback)(item => {
93
+ if (item.kind === "fold") {
94
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(FoldHeader, {
95
+ foldId: item.foldId,
96
+ count: item.count,
97
+ expanded: item.expanded,
98
+ theme: theme,
99
+ styles: dynamicStyles,
100
+ onToggle: toggleFold
101
+ });
102
+ }
103
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(DiffRow, {
104
+ diff: item.diff,
105
+ showSeparator: false,
106
+ theme: theme,
107
+ options: options,
108
+ styles: dynamicStyles
109
+ });
110
+ }, [theme, options, dynamicStyles, toggleFold]);
111
+ const renderItem = (0, _react.useCallback)(({
112
+ item
113
+ }) => renderSplitItem(item), [renderSplitItem]);
114
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
115
+ style: [dynamicStyles.container, theme.glowColor && {
116
+ shadowColor: theme.glowColor,
117
+ shadowOffset: {
118
+ width: 0,
119
+ height: 0
120
+ },
121
+ shadowOpacity: theme.neonIntensity && theme.neonIntensity > 0.7 ? 0.5 : theme.neonIntensity && theme.neonIntensity > 0.3 ? 0.3 : 0.1,
122
+ shadowRadius: theme.neonIntensity && theme.neonIntensity > 0.7 ? 10 : theme.neonIntensity && theme.neonIntensity > 0.3 ? 5 : 2
123
+ }],
124
+ children: [showThemeName && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
125
+ style: dynamicStyles.themeBadge,
126
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
127
+ style: dynamicStyles.themeName,
128
+ children: theme.name
129
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
130
+ style: dynamicStyles.themeDescription,
131
+ children: theme.description
132
+ })]
133
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
134
+ style: dynamicStyles.header,
135
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
136
+ style: dynamicStyles.headerLeft,
137
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
138
+ style: dynamicStyles.headerTitle,
139
+ children: "PREV"
140
+ })
141
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
142
+ style: dynamicStyles.divider
143
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
144
+ style: dynamicStyles.headerRight,
145
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
146
+ style: dynamicStyles.headerTitle,
147
+ children: "CUR"
148
+ })
149
+ })]
150
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_DiffSummary.DiffSummary, {
151
+ added: summary.added,
152
+ removed: summary.removed,
153
+ modified: summary.modified,
154
+ theme: theme
155
+ }), lineDiffs.length === 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
156
+ style: dynamicStyles.emptyState,
157
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
158
+ style: dynamicStyles.emptyText,
159
+ children: options.showDiffOnly ? "No differences found" : "No content to display"
160
+ })
161
+ }) : scrollEnabled ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.FlatList, {
162
+ style: dynamicStyles.scrollView,
163
+ contentContainerStyle: dynamicStyles.scrollContent,
164
+ data: items,
165
+ renderItem: renderItem,
166
+ keyExtractor: keyExtractor,
167
+ showsVerticalScrollIndicator: false,
168
+ initialNumToRender: 20,
169
+ maxToRenderPerBatch: 20,
170
+ windowSize: 7,
171
+ removeClippedSubviews: true
172
+ }) :
173
+ /*#__PURE__*/
174
+ // A FlatList can't virtualize inside a page ScrollView — it has no
175
+ // viewport of its own to measure against — so render the rows directly.
176
+ // Folding already keeps this list short (unchanged runs collapse).
177
+ (0, _jsxRuntime.jsx)(_reactNative.View, {
178
+ style: dynamicStyles.scrollContent,
179
+ children: items.map(item => /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.Fragment, {
180
+ children: renderSplitItem(item)
181
+ }, keyExtractor(item)))
182
+ })]
183
+ });
184
+ }
185
+
186
+ // Number of context lines kept visible on either side of every change.
187
+ const CONTEXT_LINES = 3;
188
+ // Don't bother folding tiny gaps — toggling them is more friction than scroll.
189
+ const MIN_FOLD_SIZE = 4;
190
+ function buildSplitItems(lineDiffs, expandedFolds) {
191
+ const n = lineDiffs.length;
192
+ if (n === 0) return [];
193
+
194
+ // Mark every line that should always be visible: any change, plus
195
+ // CONTEXT_LINES on either side of it.
196
+ const visible = new Array(n).fill(false);
197
+ for (let i = 0; i < n; i++) {
198
+ if (lineDiffs[i].type !== _lineDiff.DiffType.DEFAULT) {
199
+ const start = Math.max(0, i - CONTEXT_LINES);
200
+ const end = Math.min(n - 1, i + CONTEXT_LINES);
201
+ for (let k = start; k <= end; k++) visible[k] = true;
202
+ }
203
+ }
204
+ const items = [];
205
+ let foldId = 0;
206
+ let i = 0;
207
+ while (i < n) {
208
+ if (visible[i]) {
209
+ items.push({
210
+ kind: "row",
211
+ diff: lineDiffs[i],
212
+ diffIndex: i
213
+ });
214
+ i++;
215
+ continue;
216
+ }
217
+ let j = i;
218
+ while (j < n && !visible[j]) j++;
219
+ const runLength = j - i;
220
+ if (runLength < MIN_FOLD_SIZE) {
221
+ for (let k = i; k < j; k++) {
222
+ items.push({
223
+ kind: "row",
224
+ diff: lineDiffs[k],
225
+ diffIndex: k
226
+ });
227
+ }
228
+ } else {
229
+ const id = foldId++;
230
+ const expanded = expandedFolds.has(id);
231
+ items.push({
232
+ kind: "fold",
233
+ foldId: id,
234
+ count: runLength,
235
+ expanded
236
+ });
237
+ if (expanded) {
238
+ for (let k = i; k < j; k++) {
239
+ items.push({
240
+ kind: "row",
241
+ diff: lineDiffs[k],
242
+ diffIndex: k
243
+ });
244
+ }
245
+ }
246
+ }
247
+ i = j;
248
+ }
249
+ return items;
250
+ }
251
+ const FoldHeader = /*#__PURE__*/(0, _react.memo)(function FoldHeader({
252
+ foldId,
253
+ count,
254
+ expanded,
255
+ theme,
256
+ styles,
257
+ onToggle
258
+ }) {
259
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
260
+ style: [styles.foldHeader, {
261
+ backgroundColor: theme.separatorBackground
262
+ }],
263
+ onPress: () => onToggle(foldId),
264
+ activeOpacity: 0.7,
265
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
266
+ style: [styles.foldHeaderText, {
267
+ color: theme.separatorText
268
+ }],
269
+ children: expanded ? `▼ ${count} unchanged line${count === 1 ? "" : "s"} — tap to hide` : `▶ ${count} unchanged line${count === 1 ? "" : "s"} — tap to expand`
270
+ })
271
+ });
272
+ });
273
+ const DiffRow = /*#__PURE__*/(0, _react.memo)(function DiffRow({
274
+ diff,
275
+ showSeparator,
276
+ theme,
277
+ options,
278
+ styles
279
+ }) {
280
+ const isRemoved = diff.type === _lineDiff.DiffType.REMOVED;
281
+ const isAdded = diff.type === _lineDiff.DiffType.ADDED;
282
+ const isModified = diff.type === _lineDiff.DiffType.MODIFIED;
283
+ const isDefault = diff.type === _lineDiff.DiffType.DEFAULT;
284
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_react.Fragment, {
285
+ children: [showSeparator && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
286
+ style: styles.separator,
287
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
288
+ style: styles.separatorText,
289
+ children: "\u2022 \u2022 \u2022"
290
+ })
291
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
292
+ style: styles.row,
293
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
294
+ style: styles.leftSide,
295
+ children: isRemoved || isModified || isDefault ? /*#__PURE__*/(0, _jsxRuntime.jsx)(LineSide, {
296
+ lineNumber: diff.leftLineNumber,
297
+ content: diff.leftContent,
298
+ type: isModified ? _lineDiff.DiffType.REMOVED : diff.type,
299
+ marker: isRemoved || isModified ? "-" : " ",
300
+ theme: theme,
301
+ options: options,
302
+ styles: styles
303
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(EmptyLineSide, {
304
+ options: options,
305
+ styles: styles
306
+ })
307
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
308
+ style: styles.centerDivider
309
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
310
+ style: styles.rightSide,
311
+ children: isAdded || isModified || isDefault ? /*#__PURE__*/(0, _jsxRuntime.jsx)(LineSide, {
312
+ lineNumber: diff.rightLineNumber,
313
+ content: diff.rightContent,
314
+ type: isModified ? _lineDiff.DiffType.ADDED : diff.type,
315
+ marker: isAdded || isModified ? "+" : " ",
316
+ theme: theme,
317
+ options: options,
318
+ styles: styles
319
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(EmptyLineSide, {
320
+ options: options,
321
+ styles: styles
322
+ })
323
+ })]
324
+ })]
325
+ });
326
+ });
327
+ function LineSide({
328
+ lineNumber,
329
+ content,
330
+ type,
331
+ marker,
332
+ theme,
333
+ options,
334
+ styles
335
+ }) {
336
+ const colors = getDiffColors(type, theme);
337
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_react.Fragment, {
338
+ children: [!options.hideLineNumbers && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
339
+ style: [styles.gutter, {
340
+ backgroundColor: theme.lineNumberBackground
341
+ }],
342
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
343
+ style: styles.lineNumber,
344
+ children: lineNumber || " "
345
+ })
346
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
347
+ style: [styles.marker, {
348
+ backgroundColor: colors.markerBg
349
+ }],
350
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
351
+ style: [styles.markerText, {
352
+ color: theme.markerText
353
+ }],
354
+ children: marker
355
+ })
356
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
357
+ style: [styles.contentCell, {
358
+ backgroundColor: colors.background
359
+ }],
360
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
361
+ style: [styles.content, {
362
+ color: colors.text
363
+ }],
364
+ children: Array.isArray(content) ? content.map((word, idx) => {
365
+ let backgroundColor = "transparent";
366
+ if (word.type === _lineDiff.DiffType.ADDED) {
367
+ backgroundColor = theme.addedWordHighlight;
368
+ } else if (word.type === _lineDiff.DiffType.REMOVED) {
369
+ backgroundColor = theme.removedWordHighlight;
370
+ }
371
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
372
+ style: [styles.wordDiff, {
373
+ backgroundColor
374
+ }],
375
+ children: word.value
376
+ }, idx);
377
+ }) : content || " "
378
+ })
379
+ })]
380
+ });
381
+ }
382
+ function EmptyLineSide({
383
+ options,
384
+ styles
385
+ }) {
386
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_react.Fragment, {
387
+ children: [!options.hideLineNumbers && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
388
+ style: [styles.gutter, styles.emptyGutter],
389
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
390
+ style: styles.lineNumber,
391
+ children: " "
392
+ })
393
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
394
+ style: [styles.marker, styles.emptyMarker],
395
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
396
+ style: styles.markerText,
397
+ children: " "
398
+ })
399
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
400
+ style: [styles.contentCell, styles.emptyContent],
401
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
402
+ style: styles.content,
403
+ children: " "
404
+ })
405
+ })]
406
+ });
407
+ }
408
+ function getDiffColors(type, theme) {
409
+ switch (type) {
410
+ case _lineDiff.DiffType.ADDED:
411
+ return {
412
+ background: theme.addedBackground,
413
+ text: theme.addedText,
414
+ markerBg: theme.markerAddedBackground
415
+ };
416
+ case _lineDiff.DiffType.REMOVED:
417
+ return {
418
+ background: theme.removedBackground,
419
+ text: theme.removedText,
420
+ markerBg: theme.markerRemovedBackground
421
+ };
422
+ case _lineDiff.DiffType.DEFAULT:
423
+ default:
424
+ return {
425
+ background: theme.unchangedBackground,
426
+ text: theme.unchangedText,
427
+ markerBg: "transparent"
428
+ };
429
+ }
430
+ }
431
+
432
+ // Create dynamic styles based on theme
433
+ function createDynamicStyles(theme, scrollEnabled) {
434
+ return _reactNative.StyleSheet.create({
435
+ container: {
436
+ // Fixed pane only when the rows scroll themselves; inline mode sizes to
437
+ // content so the page scroll reveals it.
438
+ ...(scrollEnabled ? {
439
+ height: 400
440
+ } : null),
441
+ backgroundColor: theme.background,
442
+ borderRadius: 8,
443
+ overflow: "hidden",
444
+ borderWidth: 1,
445
+ borderColor: theme.borderColor
446
+ },
447
+ themeBadge: {
448
+ backgroundColor: theme.panelBackground,
449
+ paddingHorizontal: 12,
450
+ paddingVertical: 8,
451
+ borderBottomWidth: 1,
452
+ borderBottomColor: theme.borderColor
453
+ },
454
+ themeName: {
455
+ fontSize: 12,
456
+ fontWeight: "700",
457
+ color: theme.accentColor || theme.unchangedText,
458
+ fontFamily: "monospace",
459
+ letterSpacing: 0.5
460
+ },
461
+ themeDescription: {
462
+ fontSize: 10,
463
+ color: theme.unchangedText,
464
+ fontFamily: "monospace",
465
+ marginTop: 2,
466
+ opacity: 0.8
467
+ },
468
+ header: {
469
+ flexDirection: "row",
470
+ backgroundColor: theme.headerBackground,
471
+ borderBottomWidth: 1,
472
+ borderBottomColor: theme.borderColor
473
+ },
474
+ headerLeft: {
475
+ flex: 1,
476
+ paddingVertical: 8,
477
+ paddingHorizontal: 12
478
+ },
479
+ headerRight: {
480
+ flex: 1,
481
+ paddingVertical: 8,
482
+ paddingHorizontal: 12
483
+ },
484
+ headerTitle: {
485
+ fontSize: 10,
486
+ fontWeight: "700",
487
+ color: theme.accentColor || theme.unchangedText,
488
+ fontFamily: "monospace",
489
+ letterSpacing: 0.5,
490
+ textTransform: "uppercase"
491
+ },
492
+ divider: {
493
+ width: 1,
494
+ backgroundColor: theme.dividerColor
495
+ },
496
+ scrollView: {
497
+ flex: 1
498
+ },
499
+ scrollContent: {
500
+ paddingBottom: 10
501
+ },
502
+ row: {
503
+ flexDirection: "row",
504
+ minHeight: 20
505
+ },
506
+ leftSide: {
507
+ flex: 1,
508
+ flexDirection: "row"
509
+ },
510
+ rightSide: {
511
+ flex: 1,
512
+ flexDirection: "row"
513
+ },
514
+ centerDivider: {
515
+ width: 1,
516
+ backgroundColor: theme.dividerColor
517
+ },
518
+ gutter: {
519
+ width: 35,
520
+ paddingHorizontal: 4,
521
+ justifyContent: "center",
522
+ alignItems: "flex-end",
523
+ backgroundColor: theme.lineNumberBackground,
524
+ borderRightWidth: 1,
525
+ borderRightColor: theme.lineNumberBorder
526
+ },
527
+ emptyGutter: {
528
+ backgroundColor: theme.contextBackground
529
+ },
530
+ lineNumber: {
531
+ fontSize: 9,
532
+ fontFamily: "monospace",
533
+ color: theme.lineNumberText
534
+ },
535
+ marker: {
536
+ width: 20,
537
+ justifyContent: "center",
538
+ alignItems: "center"
539
+ },
540
+ emptyMarker: {
541
+ backgroundColor: theme.contextBackground
542
+ },
543
+ markerText: {
544
+ fontSize: 10,
545
+ fontFamily: "monospace",
546
+ fontWeight: "600"
547
+ },
548
+ contentCell: {
549
+ flex: 1,
550
+ paddingHorizontal: 8,
551
+ paddingVertical: 2
552
+ },
553
+ emptyContent: {
554
+ backgroundColor: theme.contextBackground
555
+ },
556
+ content: {
557
+ fontSize: 10,
558
+ fontFamily: "monospace",
559
+ lineHeight: 16
560
+ },
561
+ wordDiff: {
562
+ fontSize: 10,
563
+ fontFamily: "monospace"
564
+ },
565
+ summaryBar: {
566
+ flexDirection: "row",
567
+ alignItems: "center",
568
+ justifyContent: "center",
569
+ gap: 16,
570
+ paddingVertical: 6,
571
+ backgroundColor: theme.summaryBackground,
572
+ borderTopWidth: 1,
573
+ borderTopColor: theme.borderColor
574
+ },
575
+ summaryItem: {
576
+ flexDirection: "row",
577
+ alignItems: "center"
578
+ },
579
+ summaryText: {
580
+ fontSize: 10,
581
+ fontFamily: "monospace",
582
+ fontWeight: "700"
583
+ },
584
+ separator: {
585
+ height: 20,
586
+ justifyContent: "center",
587
+ alignItems: "center",
588
+ backgroundColor: theme.separatorBackground
589
+ },
590
+ separatorText: {
591
+ fontSize: 8,
592
+ color: theme.separatorText,
593
+ fontFamily: "monospace",
594
+ letterSpacing: 2
595
+ },
596
+ foldHeader: {
597
+ paddingVertical: 6,
598
+ paddingHorizontal: 12,
599
+ alignItems: "center",
600
+ justifyContent: "center",
601
+ borderTopWidth: 1,
602
+ borderBottomWidth: 1,
603
+ borderColor: theme.borderColor
604
+ },
605
+ foldHeaderText: {
606
+ fontSize: 10,
607
+ fontFamily: "monospace",
608
+ letterSpacing: 0.5
609
+ },
610
+ emptyState: {
611
+ padding: 40,
612
+ alignItems: "center",
613
+ justifyContent: "center"
614
+ },
615
+ emptyText: {
616
+ fontSize: 11,
617
+ color: theme.emptyStateText,
618
+ fontStyle: "italic",
619
+ fontFamily: "monospace"
620
+ }
621
+ });
622
+ }
@@ -69,6 +69,12 @@ Object.defineProperty(exports, "SplitDiffViewer", {
69
69
  return _SplitDiffViewer.SplitDiffViewer;
70
70
  }
71
71
  });
72
+ Object.defineProperty(exports, "ThemedSplitView", {
73
+ enumerable: true,
74
+ get: function () {
75
+ return _ThemedSplitView.ThemedSplitView;
76
+ }
77
+ });
72
78
  Object.defineProperty(exports, "TreeDiffViewer", {
73
79
  enumerable: true,
74
80
  get: function () {
@@ -93,6 +99,12 @@ Object.defineProperty(exports, "applyJsonOp", {
93
99
  return _jsonOps.applyJsonOp;
94
100
  }
95
101
  });
102
+ Object.defineProperty(exports, "boundedDeepEqual", {
103
+ enumerable: true,
104
+ get: function () {
105
+ return _objectDiff.boundedDeepEqual;
106
+ }
107
+ });
96
108
  Object.defineProperty(exports, "breadcrumb", {
97
109
  enumerable: true,
98
110
  get: function () {
@@ -141,6 +153,18 @@ Object.defineProperty(exports, "isEditableContainer", {
141
153
  return _jsonOps.isEditableContainer;
142
154
  }
143
155
  });
156
+ Object.defineProperty(exports, "jsonLikelyLargerThan", {
157
+ enumerable: true,
158
+ get: function () {
159
+ return _objectDiff.jsonLikelyLargerThan;
160
+ }
161
+ });
162
+ Object.defineProperty(exports, "objectDiff", {
163
+ enumerable: true,
164
+ get: function () {
165
+ return _objectDiff.objectDiff;
166
+ }
167
+ });
144
168
  Object.defineProperty(exports, "selectionPathAfterOp", {
145
169
  enumerable: true,
146
170
  get: function () {
@@ -153,6 +177,12 @@ Object.defineProperty(exports, "suggestedNewValue", {
153
177
  return _jsonOps.suggestedNewValue;
154
178
  }
155
179
  });
180
+ Object.defineProperty(exports, "toDiffable", {
181
+ enumerable: true,
182
+ get: function () {
183
+ return _objectDiff.toDiffable;
184
+ }
185
+ });
156
186
  Object.defineProperty(exports, "treeActionMap", {
157
187
  enumerable: true,
158
188
  get: function () {
@@ -186,4 +216,6 @@ var _SplitDiffViewer = require("./SplitDiffViewer.js");
186
216
  var _DiffSummary = require("./DiffSummary.js");
187
217
  var _lineDiff = require("./lineDiff.js");
188
218
  var _diffThemes = require("./diffThemes.js");
219
+ var _objectDiff = require("./objectDiff.js");
220
+ var _ThemedSplitView = require("./ThemedSplitView.js");
189
221
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }