@buoy-gg/highlight-updates 7.0.33 → 7.0.34

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.
@@ -30,41 +30,23 @@ const SearchSectionInner = /*#__PURE__*/(0, _react.memo)(function SearchSection(
30
30
  onSearchClose
31
31
  }) {
32
32
  if (!isActive) return null;
33
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
34
- nativeID: "__rn_buoy__search-container",
35
- testID: "buoy-highlight-search-container",
36
- style: styles.headerSearchContainer,
37
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Search, {
38
- size: 14,
39
- color: _sharedUi.night.color.textSecondary
40
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
41
- testID: "buoy-highlight-search-field",
42
- style: styles.headerSearchInput,
43
- placeholder: "Search testID, nativeID, component...",
44
- placeholderTextColor: _sharedUi.night.color.placeholder,
45
- value: searchText,
46
- onChangeText: onSearchChange,
47
- onSubmitEditing: onSearchClose,
48
- onBlur: onSearchClose,
49
- accessibilityLabel: "Search renders",
50
- autoCapitalize: "none",
51
- autoCorrect: false,
52
- returnKeyType: "search",
53
- autoFocus: true
54
- }), searchText.length > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
55
- testID: "buoy-highlight-search-clear",
56
- accessibilityRole: "button",
57
- accessibilityLabel: "Clear search",
58
- onPress: () => {
59
- onSearchChange("");
60
- onSearchClose();
61
- },
62
- style: styles.headerSearchClear,
63
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.X, {
64
- size: 14,
65
- color: _sharedUi.night.color.textSecondary
66
- })
67
- }) : null]
33
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ModalHeader.Search, {
34
+ value: searchText,
35
+ onChangeText: onSearchChange,
36
+ onCancel: () => {
37
+ onSearchChange("");
38
+ onSearchClose();
39
+ },
40
+ onDismiss: onSearchClose,
41
+ dismissOnBlur: true,
42
+ clearOnlyWhenText: true,
43
+ placeholder: "Search testID, nativeID, component...",
44
+ accessibilityLabel: "Search renders",
45
+ iconSize: 14,
46
+ testID: "buoy-highlight-search-field",
47
+ containerTestID: "buoy-highlight-search-container",
48
+ containerNativeID: "__rn_buoy__search-container",
49
+ clearTestID: "buoy-highlight-search-clear"
68
50
  });
69
51
  });
70
52
  const SearchSection = exports.SearchSection = SearchSectionInner;
@@ -287,27 +269,6 @@ const CopySettingsViewHeader = exports.CopySettingsViewHeader = /*#__PURE__*/(0,
287
269
  // ============================================================================
288
270
 
289
271
  const styles = _reactNative.StyleSheet.create({
290
- headerSearchContainer: {
291
- flexDirection: "row",
292
- alignItems: "center",
293
- backgroundColor: _sharedUi.night.color.surfaceElevated,
294
- borderRadius: 10,
295
- borderWidth: 1,
296
- borderColor: _sharedUi.night.color.border,
297
- paddingHorizontal: 12,
298
- paddingVertical: 5
299
- },
300
- headerSearchInput: {
301
- flex: 1,
302
- color: _sharedUi.night.color.text,
303
- fontSize: 13,
304
- marginLeft: 6,
305
- paddingVertical: 2
306
- },
307
- headerSearchClear: {
308
- marginLeft: 6,
309
- padding: 4
310
- },
311
272
  headerActionButton: {
312
273
  width: 32,
313
274
  height: 32,
@@ -195,77 +195,35 @@ function RendersCopySettingsView({
195
195
  totalComponents,
196
196
  totalRenders
197
197
  } = (0, _rendersExportFormatter.getExportSummary)(previewRenders);
198
- if (!isPreviewExpanded) {
199
- const warningColor = sizeWarningLevel === "danger" ? _sharedUi.night.color.danger : sizeWarningLevel === "warning" ? _sharedUi.night.color.warning : _sharedUi.night.color.textSecondary;
200
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
201
- style: styles.collapsedPreview,
202
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
203
- testID: "buoy-highlight-copy-preview-show",
204
- accessibilityRole: "button",
205
- accessibilityLabel: "Show preview",
206
- style: styles.expandButton,
207
- onPress: () => setIsPreviewExpanded(true),
208
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
209
- style: styles.expandButtonContent,
210
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Eye, {
211
- size: 16,
212
- color: _sharedUi.night.color.info
213
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
214
- style: styles.expandButtonTextContainer,
215
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
216
- style: styles.expandButtonTitle,
217
- children: "Show Preview"
218
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
219
- testID: "buoy-highlight-copy-preview-summary",
220
- style: styles.expandButtonSubtitle,
221
- children: [totalComponents, " component", totalComponents !== 1 ? "s" : "", " \xB7 ", totalRenders, " renders \xB7 ~", formatBytes(estimatedSize), !hasLiveData ? " (mock data)" : ""]
222
- })]
223
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronDown, {
224
- size: 16,
225
- color: _sharedUi.night.color.textTertiary
226
- })]
198
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ExportPreview, {
199
+ expanded: isPreviewExpanded,
200
+ onExpandedChange: setIsPreviewExpanded,
201
+ summary: `${totalComponents} component${totalComponents !== 1 ? "s" : ""} · ${totalRenders} renders · ~${formatBytes(estimatedSize)}${!hasLiveData ? " (mock data)" : ""}`,
202
+ warningLevel: sizeWarningLevel,
203
+ warningText: {
204
+ warning: "Large payload — preview may be slow",
205
+ danger: "Very large payload — try a smaller topN or turn off history"
206
+ },
207
+ testIDs: {
208
+ expand: "buoy-highlight-copy-preview-show",
209
+ collapse: "buoy-highlight-copy-preview-hide",
210
+ summary: "buoy-highlight-copy-preview-summary",
211
+ warning: "buoy-highlight-copy-size-warning"
212
+ },
213
+ renderBody: () => {
214
+ const exportText = generateCopyText();
215
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
216
+ testID: "buoy-highlight-copy-preview-scroll",
217
+ style: styles.previewScroll,
218
+ nestedScrollEnabled: true,
219
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
220
+ testID: "buoy-highlight-copy-preview-text",
221
+ style: styles.previewText,
222
+ selectable: true,
223
+ children: exportText
227
224
  })
228
- }), sizeWarningLevel !== "none" && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
229
- testID: "buoy-highlight-copy-size-warning",
230
- style: [styles.sizeWarning, sizeWarningLevel === "danger" && styles.sizeWarningDanger],
231
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.AlertTriangle, {
232
- size: 12,
233
- color: warningColor
234
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
235
- style: [styles.sizeWarningText, {
236
- color: warningColor
237
- }],
238
- children: sizeWarningLevel === "danger" ? "Very large payload — try a smaller topN or turn off history" : "Large payload — preview may be slow"
239
- })]
240
- })]
241
- });
242
- }
243
- const exportText = generateCopyText();
244
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
245
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
246
- testID: "buoy-highlight-copy-preview-hide",
247
- accessibilityRole: "button",
248
- accessibilityLabel: "Hide preview",
249
- style: styles.collapseButton,
250
- onPress: () => setIsPreviewExpanded(false),
251
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
252
- style: styles.collapseButtonText,
253
- children: "Hide Preview"
254
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronUp, {
255
- size: 14,
256
- color: _sharedUi.night.color.textSecondary
257
- })]
258
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
259
- testID: "buoy-highlight-copy-preview-scroll",
260
- style: styles.previewScroll,
261
- nestedScrollEnabled: true,
262
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
263
- testID: "buoy-highlight-copy-preview-text",
264
- style: styles.previewText,
265
- selectable: true,
266
- children: exportText
267
- })
268
- })]
225
+ });
226
+ }
269
227
  });
270
228
  }, [isPreviewExpanded, previewRenders, estimatedSize, sizeWarningLevel, hasLiveData, generateCopyText]);
271
229
  const renderPreviewHeaderActions = (0, _react.useCallback)(() => {
@@ -490,71 +448,6 @@ function RendersCopySettingsView({
490
448
  });
491
449
  }
492
450
  const styles = _reactNative.StyleSheet.create({
493
- collapsedPreview: {
494
- gap: 8
495
- },
496
- expandButton: {
497
- backgroundColor: _sharedUi.night.color.surfaceElevated,
498
- borderRadius: 8,
499
- borderWidth: 1,
500
- borderColor: _sharedUi.night.color.border,
501
- padding: 12
502
- },
503
- expandButtonContent: {
504
- flexDirection: "row",
505
- alignItems: "center",
506
- gap: 10
507
- },
508
- expandButtonTextContainer: {
509
- flex: 1
510
- },
511
- expandButtonTitle: {
512
- fontSize: 13,
513
- fontWeight: "600",
514
- color: _sharedUi.night.color.text
515
- },
516
- expandButtonSubtitle: {
517
- fontSize: 11,
518
- color: _sharedUi.night.color.textSecondary,
519
- marginTop: 2
520
- },
521
- collapseButton: {
522
- flexDirection: "row",
523
- alignItems: "center",
524
- justifyContent: "center",
525
- gap: 6,
526
- paddingVertical: 8,
527
- marginBottom: 8,
528
- backgroundColor: _sharedUi.night.color.surfaceElevated,
529
- borderRadius: 6,
530
- borderWidth: 1,
531
- borderColor: _sharedUi.night.color.border
532
- },
533
- collapseButtonText: {
534
- fontSize: 12,
535
- fontWeight: "500",
536
- color: _sharedUi.night.color.textSecondary
537
- },
538
- sizeWarning: {
539
- flexDirection: "row",
540
- alignItems: "center",
541
- gap: 6,
542
- paddingHorizontal: 10,
543
- paddingVertical: 6,
544
- backgroundColor: _sharedUi.night.color.warningSoft,
545
- borderRadius: 6,
546
- borderWidth: 1,
547
- borderColor: _sharedUi.night.color.warning + "30"
548
- },
549
- sizeWarningDanger: {
550
- backgroundColor: _sharedUi.night.color.dangerSoft,
551
- borderColor: _sharedUi.night.color.danger + "30"
552
- },
553
- sizeWarningText: {
554
- fontSize: 11,
555
- fontWeight: "500",
556
- flex: 1
557
- },
558
451
  previewScroll: {
559
452
  maxHeight: 360
560
453
  },
@@ -11,39 +11,22 @@ var _copySettings = require("../types/copySettings");
11
11
  /**
12
12
  * Copy Settings Storage
13
13
  *
14
- * Persists the highlight-updates copy/export settings.
14
+ * Persists the highlight-updates copy/export settings through the shared
15
+ * `definePersistedSetting` (merge-over-defaults, best-effort save/clear).
15
16
  */
16
17
 
18
+ const copySettings = (0, _sharedUi.definePersistedSetting)(_sharedUi.devToolsStorageKeys.highlightUpdates.copySettings(), _copySettings.DEFAULT_COPY_SETTINGS, {
19
+ sanitize: (merged, stored) => ({
20
+ ...merged,
21
+ filterCauses: stored?.filterCauses ?? _copySettings.DEFAULT_COPY_SETTINGS.filterCauses
22
+ })
23
+ });
17
24
  async function saveCopySettings(settings) {
18
- try {
19
- const key = _sharedUi.devToolsStorageKeys.highlightUpdates.copySettings();
20
- await _sharedUi.persistentStorage.setItem(key, JSON.stringify(settings));
21
- } catch {
22
- // Silently fail — persistence is optional
23
- }
25
+ await copySettings.save(settings);
24
26
  }
25
27
  async function loadCopySettings() {
26
- try {
27
- const key = _sharedUi.devToolsStorageKeys.highlightUpdates.copySettings();
28
- const value = await _sharedUi.persistentStorage.getItem(key);
29
- if (value && value !== "") {
30
- const parsed = JSON.parse(value);
31
- return {
32
- ..._copySettings.DEFAULT_COPY_SETTINGS,
33
- ...parsed,
34
- filterCauses: parsed.filterCauses ?? _copySettings.DEFAULT_COPY_SETTINGS.filterCauses
35
- };
36
- }
37
- return null;
38
- } catch {
39
- return null;
40
- }
28
+ return copySettings.loadOrNull();
41
29
  }
42
30
  async function clearCopySettings() {
43
- try {
44
- const key = _sharedUi.devToolsStorageKeys.highlightUpdates.copySettings();
45
- await _sharedUi.persistentStorage.removeItem(key);
46
- } catch {
47
- // Silently fail
48
- }
31
+ await copySettings.clear();
49
32
  }
@@ -10,8 +10,8 @@
10
10
  */
11
11
 
12
12
  import React, { memo } from "react";
13
- import { View, TouchableOpacity, TextInput, StyleSheet } from "react-native";
14
- import { Trash2, Search, Filter, X, Pause, Copy, ModalHeader, TabSelector, night, PowerToggleButton } from "@buoy-gg/shared-ui";
13
+ import { TouchableOpacity, StyleSheet } from "react-native";
14
+ import { Trash2, Search, Filter, Pause, Copy, ModalHeader, TabSelector, night, PowerToggleButton } from "@buoy-gg/shared-ui";
15
15
  import { StatsDisplay } from "./StatsDisplay";
16
16
 
17
17
  // ============================================================================
@@ -25,41 +25,23 @@ const SearchSectionInner = /*#__PURE__*/memo(function SearchSection({
25
25
  onSearchClose
26
26
  }) {
27
27
  if (!isActive) return null;
28
- return /*#__PURE__*/_jsxs(View, {
29
- nativeID: "__rn_buoy__search-container",
30
- testID: "buoy-highlight-search-container",
31
- style: styles.headerSearchContainer,
32
- children: [/*#__PURE__*/_jsx(Search, {
33
- size: 14,
34
- color: night.color.textSecondary
35
- }), /*#__PURE__*/_jsx(TextInput, {
36
- testID: "buoy-highlight-search-field",
37
- style: styles.headerSearchInput,
38
- placeholder: "Search testID, nativeID, component...",
39
- placeholderTextColor: night.color.placeholder,
40
- value: searchText,
41
- onChangeText: onSearchChange,
42
- onSubmitEditing: onSearchClose,
43
- onBlur: onSearchClose,
44
- accessibilityLabel: "Search renders",
45
- autoCapitalize: "none",
46
- autoCorrect: false,
47
- returnKeyType: "search",
48
- autoFocus: true
49
- }), searchText.length > 0 ? /*#__PURE__*/_jsx(TouchableOpacity, {
50
- testID: "buoy-highlight-search-clear",
51
- accessibilityRole: "button",
52
- accessibilityLabel: "Clear search",
53
- onPress: () => {
54
- onSearchChange("");
55
- onSearchClose();
56
- },
57
- style: styles.headerSearchClear,
58
- children: /*#__PURE__*/_jsx(X, {
59
- size: 14,
60
- color: night.color.textSecondary
61
- })
62
- }) : null]
28
+ return /*#__PURE__*/_jsx(ModalHeader.Search, {
29
+ value: searchText,
30
+ onChangeText: onSearchChange,
31
+ onCancel: () => {
32
+ onSearchChange("");
33
+ onSearchClose();
34
+ },
35
+ onDismiss: onSearchClose,
36
+ dismissOnBlur: true,
37
+ clearOnlyWhenText: true,
38
+ placeholder: "Search testID, nativeID, component...",
39
+ accessibilityLabel: "Search renders",
40
+ iconSize: 14,
41
+ testID: "buoy-highlight-search-field",
42
+ containerTestID: "buoy-highlight-search-container",
43
+ containerNativeID: "__rn_buoy__search-container",
44
+ clearTestID: "buoy-highlight-search-clear"
63
45
  });
64
46
  });
65
47
  export const SearchSection = SearchSectionInner;
@@ -282,27 +264,6 @@ export const CopySettingsViewHeader = /*#__PURE__*/memo(function CopySettingsVie
282
264
  // ============================================================================
283
265
 
284
266
  const styles = StyleSheet.create({
285
- headerSearchContainer: {
286
- flexDirection: "row",
287
- alignItems: "center",
288
- backgroundColor: night.color.surfaceElevated,
289
- borderRadius: 10,
290
- borderWidth: 1,
291
- borderColor: night.color.border,
292
- paddingHorizontal: 12,
293
- paddingVertical: 5
294
- },
295
- headerSearchInput: {
296
- flex: 1,
297
- color: night.color.text,
298
- fontSize: 13,
299
- marginLeft: 6,
300
- paddingVertical: 2
301
- },
302
- headerSearchClear: {
303
- marginLeft: 6,
304
- padding: 4
305
- },
306
267
  headerActionButton: {
307
268
  width: 32,
308
269
  height: 32,
@@ -8,12 +8,12 @@
8
8
  */
9
9
 
10
10
  import { useCallback, useEffect, useMemo, useState } from "react";
11
- import { Text, StyleSheet, ScrollView, View, TouchableOpacity } from "react-native";
12
- import { DynamicFilterView, macOSColors, night, FileText, FileCode, Zap, Settings, Eye, ChevronDown, ChevronUp, AlertTriangle, Layers, ToolbarCopyButton } from "@buoy-gg/shared-ui";
11
+ import { Text, StyleSheet, ScrollView } from "react-native";
12
+ import { DynamicFilterView, macOSColors, night, FileText, FileCode, Zap, Settings, Eye, Layers, ToolbarCopyButton, ExportPreview } from "@buoy-gg/shared-ui";
13
13
  import { DEFAULT_COPY_SETTINGS, COPY_PRESETS, PRESET_METADATA, detectActivePreset } from "../types/copySettings";
14
14
  import { generateExport, estimateExportSize, getExportSummary } from "../utils/rendersExportFormatter";
15
15
  import { loadCopySettings, saveCopySettings } from "../utils/copySettingsStorage";
16
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
16
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
17
17
  const SIZE_WARNING_THRESHOLD = 50 * 1024;
18
18
  const SIZE_DANGER_THRESHOLD = 200 * 1024;
19
19
  const CAUSE_OPTIONS = [{
@@ -191,77 +191,35 @@ export function RendersCopySettingsView({
191
191
  totalComponents,
192
192
  totalRenders
193
193
  } = getExportSummary(previewRenders);
194
- if (!isPreviewExpanded) {
195
- const warningColor = sizeWarningLevel === "danger" ? night.color.danger : sizeWarningLevel === "warning" ? night.color.warning : night.color.textSecondary;
196
- return /*#__PURE__*/_jsxs(View, {
197
- style: styles.collapsedPreview,
198
- children: [/*#__PURE__*/_jsx(TouchableOpacity, {
199
- testID: "buoy-highlight-copy-preview-show",
200
- accessibilityRole: "button",
201
- accessibilityLabel: "Show preview",
202
- style: styles.expandButton,
203
- onPress: () => setIsPreviewExpanded(true),
204
- children: /*#__PURE__*/_jsxs(View, {
205
- style: styles.expandButtonContent,
206
- children: [/*#__PURE__*/_jsx(Eye, {
207
- size: 16,
208
- color: night.color.info
209
- }), /*#__PURE__*/_jsxs(View, {
210
- style: styles.expandButtonTextContainer,
211
- children: [/*#__PURE__*/_jsx(Text, {
212
- style: styles.expandButtonTitle,
213
- children: "Show Preview"
214
- }), /*#__PURE__*/_jsxs(Text, {
215
- testID: "buoy-highlight-copy-preview-summary",
216
- style: styles.expandButtonSubtitle,
217
- children: [totalComponents, " component", totalComponents !== 1 ? "s" : "", " \xB7 ", totalRenders, " renders \xB7 ~", formatBytes(estimatedSize), !hasLiveData ? " (mock data)" : ""]
218
- })]
219
- }), /*#__PURE__*/_jsx(ChevronDown, {
220
- size: 16,
221
- color: night.color.textTertiary
222
- })]
194
+ return /*#__PURE__*/_jsx(ExportPreview, {
195
+ expanded: isPreviewExpanded,
196
+ onExpandedChange: setIsPreviewExpanded,
197
+ summary: `${totalComponents} component${totalComponents !== 1 ? "s" : ""} · ${totalRenders} renders · ~${formatBytes(estimatedSize)}${!hasLiveData ? " (mock data)" : ""}`,
198
+ warningLevel: sizeWarningLevel,
199
+ warningText: {
200
+ warning: "Large payload — preview may be slow",
201
+ danger: "Very large payload — try a smaller topN or turn off history"
202
+ },
203
+ testIDs: {
204
+ expand: "buoy-highlight-copy-preview-show",
205
+ collapse: "buoy-highlight-copy-preview-hide",
206
+ summary: "buoy-highlight-copy-preview-summary",
207
+ warning: "buoy-highlight-copy-size-warning"
208
+ },
209
+ renderBody: () => {
210
+ const exportText = generateCopyText();
211
+ return /*#__PURE__*/_jsx(ScrollView, {
212
+ testID: "buoy-highlight-copy-preview-scroll",
213
+ style: styles.previewScroll,
214
+ nestedScrollEnabled: true,
215
+ children: /*#__PURE__*/_jsx(Text, {
216
+ testID: "buoy-highlight-copy-preview-text",
217
+ style: styles.previewText,
218
+ selectable: true,
219
+ children: exportText
223
220
  })
224
- }), sizeWarningLevel !== "none" && /*#__PURE__*/_jsxs(View, {
225
- testID: "buoy-highlight-copy-size-warning",
226
- style: [styles.sizeWarning, sizeWarningLevel === "danger" && styles.sizeWarningDanger],
227
- children: [/*#__PURE__*/_jsx(AlertTriangle, {
228
- size: 12,
229
- color: warningColor
230
- }), /*#__PURE__*/_jsx(Text, {
231
- style: [styles.sizeWarningText, {
232
- color: warningColor
233
- }],
234
- children: sizeWarningLevel === "danger" ? "Very large payload — try a smaller topN or turn off history" : "Large payload — preview may be slow"
235
- })]
236
- })]
237
- });
238
- }
239
- const exportText = generateCopyText();
240
- return /*#__PURE__*/_jsxs(View, {
241
- children: [/*#__PURE__*/_jsxs(TouchableOpacity, {
242
- testID: "buoy-highlight-copy-preview-hide",
243
- accessibilityRole: "button",
244
- accessibilityLabel: "Hide preview",
245
- style: styles.collapseButton,
246
- onPress: () => setIsPreviewExpanded(false),
247
- children: [/*#__PURE__*/_jsx(Text, {
248
- style: styles.collapseButtonText,
249
- children: "Hide Preview"
250
- }), /*#__PURE__*/_jsx(ChevronUp, {
251
- size: 14,
252
- color: night.color.textSecondary
253
- })]
254
- }), /*#__PURE__*/_jsx(ScrollView, {
255
- testID: "buoy-highlight-copy-preview-scroll",
256
- style: styles.previewScroll,
257
- nestedScrollEnabled: true,
258
- children: /*#__PURE__*/_jsx(Text, {
259
- testID: "buoy-highlight-copy-preview-text",
260
- style: styles.previewText,
261
- selectable: true,
262
- children: exportText
263
- })
264
- })]
221
+ });
222
+ }
265
223
  });
266
224
  }, [isPreviewExpanded, previewRenders, estimatedSize, sizeWarningLevel, hasLiveData, generateCopyText]);
267
225
  const renderPreviewHeaderActions = useCallback(() => {
@@ -486,71 +444,6 @@ export function RendersCopySettingsView({
486
444
  });
487
445
  }
488
446
  const styles = StyleSheet.create({
489
- collapsedPreview: {
490
- gap: 8
491
- },
492
- expandButton: {
493
- backgroundColor: night.color.surfaceElevated,
494
- borderRadius: 8,
495
- borderWidth: 1,
496
- borderColor: night.color.border,
497
- padding: 12
498
- },
499
- expandButtonContent: {
500
- flexDirection: "row",
501
- alignItems: "center",
502
- gap: 10
503
- },
504
- expandButtonTextContainer: {
505
- flex: 1
506
- },
507
- expandButtonTitle: {
508
- fontSize: 13,
509
- fontWeight: "600",
510
- color: night.color.text
511
- },
512
- expandButtonSubtitle: {
513
- fontSize: 11,
514
- color: night.color.textSecondary,
515
- marginTop: 2
516
- },
517
- collapseButton: {
518
- flexDirection: "row",
519
- alignItems: "center",
520
- justifyContent: "center",
521
- gap: 6,
522
- paddingVertical: 8,
523
- marginBottom: 8,
524
- backgroundColor: night.color.surfaceElevated,
525
- borderRadius: 6,
526
- borderWidth: 1,
527
- borderColor: night.color.border
528
- },
529
- collapseButtonText: {
530
- fontSize: 12,
531
- fontWeight: "500",
532
- color: night.color.textSecondary
533
- },
534
- sizeWarning: {
535
- flexDirection: "row",
536
- alignItems: "center",
537
- gap: 6,
538
- paddingHorizontal: 10,
539
- paddingVertical: 6,
540
- backgroundColor: night.color.warningSoft,
541
- borderRadius: 6,
542
- borderWidth: 1,
543
- borderColor: night.color.warning + "30"
544
- },
545
- sizeWarningDanger: {
546
- backgroundColor: night.color.dangerSoft,
547
- borderColor: night.color.danger + "30"
548
- },
549
- sizeWarningText: {
550
- fontSize: 11,
551
- fontWeight: "500",
552
- flex: 1
553
- },
554
447
  previewScroll: {
555
448
  maxHeight: 360
556
449
  },
@@ -3,41 +3,24 @@
3
3
  /**
4
4
  * Copy Settings Storage
5
5
  *
6
- * Persists the highlight-updates copy/export settings.
6
+ * Persists the highlight-updates copy/export settings through the shared
7
+ * `definePersistedSetting` (merge-over-defaults, best-effort save/clear).
7
8
  */
8
9
 
9
- import { persistentStorage, devToolsStorageKeys } from "@buoy-gg/shared-ui";
10
+ import { definePersistedSetting, devToolsStorageKeys } from "@buoy-gg/shared-ui";
10
11
  import { DEFAULT_COPY_SETTINGS } from "../types/copySettings";
12
+ const copySettings = definePersistedSetting(devToolsStorageKeys.highlightUpdates.copySettings(), DEFAULT_COPY_SETTINGS, {
13
+ sanitize: (merged, stored) => ({
14
+ ...merged,
15
+ filterCauses: stored?.filterCauses ?? DEFAULT_COPY_SETTINGS.filterCauses
16
+ })
17
+ });
11
18
  export async function saveCopySettings(settings) {
12
- try {
13
- const key = devToolsStorageKeys.highlightUpdates.copySettings();
14
- await persistentStorage.setItem(key, JSON.stringify(settings));
15
- } catch {
16
- // Silently fail — persistence is optional
17
- }
19
+ await copySettings.save(settings);
18
20
  }
19
21
  export async function loadCopySettings() {
20
- try {
21
- const key = devToolsStorageKeys.highlightUpdates.copySettings();
22
- const value = await persistentStorage.getItem(key);
23
- if (value && value !== "") {
24
- const parsed = JSON.parse(value);
25
- return {
26
- ...DEFAULT_COPY_SETTINGS,
27
- ...parsed,
28
- filterCauses: parsed.filterCauses ?? DEFAULT_COPY_SETTINGS.filterCauses
29
- };
30
- }
31
- return null;
32
- } catch {
33
- return null;
34
- }
22
+ return copySettings.loadOrNull();
35
23
  }
36
24
  export async function clearCopySettings() {
37
- try {
38
- const key = devToolsStorageKeys.highlightUpdates.copySettings();
39
- await persistentStorage.removeItem(key);
40
- } catch {
41
- // Silently fail
42
- }
25
+ await copySettings.clear();
43
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ModalHeaderContent.d.ts","sourceRoot":"","sources":["../../../../src/highlight-updates/components/ModalHeaderContent.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAoC,MAAM,OAAO,CAAC;AACzD,OAAO,EAIL,SAAS,EAEV,MAAM,cAAc,CAAC;AAmBtB,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;CACnD;AAkDD,eAAO,MAAM,aAAa,gDAAqB,CAAC;AAMhD,UAAU,kBAAkB;IAC1B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;CACrB;AAyHD,eAAO,MAAM,aAAa,gDAAqB,CAAC;AAMhD,UAAU,mBAAmB;IAC3B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;CACnD;AAED,eAAO,MAAM,cAAc,iDAgDzB,CAAC;AAMH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,UAAU,CAAC;AAEnD,UAAU,qBAAqB;IAC7B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,EAAE,aAAa,CAAC;IACzB,WAAW,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,CAAC;IAC1C,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,gBAAgB,mDA4B3B,CAAC;AAMH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,CAAC;AAElD,UAAU,qBAAqB;IAC7B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,EAAE,aAAa,CAAC;IACzB,WAAW,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,CAAC;IAC1C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,gBAAgB,mDAyB3B,CAAC;AAMH,UAAU,2BAA2B;IACnC,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,eAAO,MAAM,sBAAsB,yDAYjC,CAAC"}
1
+ {"version":3,"file":"ModalHeaderContent.d.ts","sourceRoot":"","sources":["../../../../src/highlight-updates/components/ModalHeaderContent.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAoC,MAAM,OAAO,CAAC;AACzD,OAAO,EAIL,SAAS,EAEV,MAAM,cAAc,CAAC;AAmBtB,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;CACnD;AAgCD,eAAO,MAAM,aAAa,gDAAqB,CAAC;AAMhD,UAAU,kBAAkB;IAC1B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;CACrB;AAyHD,eAAO,MAAM,aAAa,gDAAqB,CAAC;AAMhD,UAAU,mBAAmB;IAC3B,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;CACnD;AAED,eAAO,MAAM,cAAc,iDAgDzB,CAAC;AAMH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,UAAU,CAAC;AAEnD,UAAU,qBAAqB;IAC7B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,EAAE,aAAa,CAAC;IACzB,WAAW,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,CAAC;IAC1C,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,gBAAgB,mDA4B3B,CAAC;AAMH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,CAAC;AAElD,UAAU,qBAAqB;IAC7B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,SAAS,EAAE,aAAa,CAAC;IACzB,WAAW,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,IAAI,CAAC;IAC1C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,gBAAgB,mDAyB3B,CAAC;AAMH,UAAU,2BAA2B;IACnC,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,eAAO,MAAM,sBAAsB,yDAYjC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"RendersCopySettingsView.d.ts","sourceRoot":"","sources":["../../../../src/highlight-updates/components/RendersCopySettingsView.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAqBH,OAAO,KAAK,EAAE,aAAa,EAAmB,MAAM,wBAAwB,CAAC;AAmB7E,UAAU,4BAA4B;IACpC,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AA+ED,wBAAgB,uBAAuB,CAAC,EACtC,OAAO,GACR,EAAE,4BAA4B,+BAsb9B"}
1
+ {"version":3,"file":"RendersCopySettingsView.d.ts","sourceRoot":"","sources":["../../../../src/highlight-updates/components/RendersCopySettingsView.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAsBH,OAAO,KAAK,EAAE,aAAa,EAAmB,MAAM,wBAAwB,CAAC;AAmB7E,UAAU,4BAA4B;IACpC,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AA+ED,wBAAgB,uBAAuB,CAAC,EACtC,OAAO,GACR,EAAE,4BAA4B,+BAuY9B"}
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * Copy Settings Storage
3
3
  *
4
- * Persists the highlight-updates copy/export settings.
4
+ * Persists the highlight-updates copy/export settings through the shared
5
+ * `definePersistedSetting` (merge-over-defaults, best-effort save/clear).
5
6
  */
6
7
  import type { RendersCopySettings } from "../types/copySettings";
7
8
  export declare function saveCopySettings(settings: RendersCopySettings): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"copySettingsStorage.d.ts","sourceRoot":"","sources":["../../../../src/highlight-updates/utils/copySettingsStorage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAGjE,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,mBAAmB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAiB5E;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAOvD"}
1
+ {"version":3,"file":"copySettingsStorage.d.ts","sourceRoot":"","sources":["../../../../src/highlight-updates/utils/copySettingsStorage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAgBjE,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnF;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAE5E;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAEvD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buoy-gg/highlight-updates",
3
- "version": "7.0.33",
3
+ "version": "7.0.34",
4
4
  "description": "Render highlighter for React Native — see every render with its cause: mount, state, props, or parent. Part of Buoy devtools.",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -26,14 +26,14 @@
26
26
  ],
27
27
  "sideEffects": false,
28
28
  "dependencies": {
29
- "@buoy-gg/floating-tools-core": "^7.0.33",
30
- "@buoy-gg/shared-ui": "^7.0.33"
29
+ "@buoy-gg/shared-ui": "^7.0.34",
30
+ "@buoy-gg/floating-tools-core": "^7.0.34"
31
31
  },
32
32
  "peerDependencies": {
33
- "@buoy-gg/license": "7.0.33",
33
+ "@buoy-gg/license": "7.0.34",
34
34
  "react": "*",
35
35
  "react-native": "*",
36
- "@buoy-gg/core": "^7.0.33"
36
+ "@buoy-gg/core": "^7.0.34"
37
37
  },
38
38
  "peerDependenciesMeta": {
39
39
  "@buoy-gg/core": {
@@ -44,8 +44,8 @@
44
44
  "@types/react": "^19.1.0",
45
45
  "@types/react-native": "^0.73.0",
46
46
  "typescript": "~5.8.3",
47
- "@buoy-gg/core": "^7.0.33",
48
- "@buoy-gg/license": "^7.0.33"
47
+ "@buoy-gg/core": "^7.0.34",
48
+ "@buoy-gg/license": "^7.0.34"
49
49
  },
50
50
  "react-native-builder-bob": {
51
51
  "source": "src",