@buoy-gg/shared-ui 7.0.4 → 7.0.6

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 (191) hide show
  1. package/lib/commonjs/colors/index.js +49 -0
  2. package/lib/commonjs/dataViewer/DataTreeActionBar.js +389 -0
  3. package/lib/commonjs/dataViewer/DataTreeActionDock.js +222 -0
  4. package/lib/commonjs/dataViewer/DataViewer.js +18 -3
  5. package/lib/commonjs/dataViewer/VirtualizedDataExplorer.js +227 -28
  6. package/lib/commonjs/dataViewer/index.js +88 -0
  7. package/lib/commonjs/dataViewer/jsonOps.js +320 -0
  8. package/lib/commonjs/dataViewer/lineDiff.js +285 -83
  9. package/lib/commonjs/dataViewer/tree/TreeDiffViewer.js +20 -5
  10. package/lib/commonjs/dataViewer/treeActions.js +167 -0
  11. package/lib/commonjs/env/EnvironmentSelector.js +2 -2
  12. package/lib/commonjs/env/EnvironmentSelectorInline.js +2 -2
  13. package/lib/commonjs/hooks/safe-area-impl.js +1 -1
  14. package/lib/commonjs/icons/index.js +79 -3
  15. package/lib/commonjs/icons/lucide-icons-original-full.js +5 -1
  16. package/lib/commonjs/icons/lucide-icons.js +59 -2
  17. package/lib/commonjs/index.js +35 -0
  18. package/lib/commonjs/settings/components/BubbleSettingsSection.js +21 -19
  19. package/lib/commonjs/storage/devToolsStorageKeys.js +6 -3
  20. package/lib/commonjs/ui/components/Badge.js +2 -0
  21. package/lib/commonjs/ui/components/CompactRow.js +7 -0
  22. package/lib/commonjs/ui/components/CopyButton.js +27 -4
  23. package/lib/commonjs/ui/components/DevToolsCard.js +11 -0
  24. package/lib/commonjs/ui/components/DynamicFilterView.js +8 -1
  25. package/lib/commonjs/ui/components/EmptyState.js +12 -5
  26. package/lib/commonjs/ui/components/ErrorBoundary.js +3 -2
  27. package/lib/commonjs/ui/components/EventHistoryViewer/EventHistoryViewer.js +63 -11
  28. package/lib/commonjs/ui/components/ExpandableSection.js +4 -3
  29. package/lib/commonjs/ui/components/ExpandableSectionHeader.js +2 -1
  30. package/lib/commonjs/ui/components/FilterViewPattern.js +8 -7
  31. package/lib/commonjs/ui/components/ListItem.js +7 -5
  32. package/lib/commonjs/ui/components/PowerToggleButton.js +4 -1
  33. package/lib/commonjs/ui/components/TabSelector.js +3 -0
  34. package/lib/commonjs/ui/console/CyberpunkConsoleSection.js +1 -1
  35. package/lib/commonjs/ui/console/GalaxyButton.js +1 -1
  36. package/lib/commonjs/ui/gameUI/components/GameUICompactStats.js +2 -2
  37. package/lib/commonjs/ui/gameUI/constants/gameUIColors.js +28 -6
  38. package/lib/commonjs/ui/gameUI/constants/macOSDesignSystemColors.js +22 -4
  39. package/lib/commonjs/utils/index.js +25 -0
  40. package/lib/commonjs/utils/reloadApp.js +144 -0
  41. package/lib/module/colors/index.js +21 -0
  42. package/lib/module/dataViewer/DataTreeActionBar.js +384 -0
  43. package/lib/module/dataViewer/DataTreeActionDock.js +218 -0
  44. package/lib/module/dataViewer/DataViewer.js +18 -3
  45. package/lib/module/dataViewer/VirtualizedDataExplorer.js +228 -30
  46. package/lib/module/dataViewer/index.js +16 -1
  47. package/lib/module/dataViewer/jsonOps.js +311 -0
  48. package/lib/module/dataViewer/lineDiff.js +284 -82
  49. package/lib/module/dataViewer/tree/TreeDiffViewer.js +20 -5
  50. package/lib/module/dataViewer/treeActions.js +161 -0
  51. package/lib/module/env/EnvironmentSelector.js +2 -2
  52. package/lib/module/env/EnvironmentSelectorInline.js +2 -2
  53. package/lib/module/hooks/safe-area-impl.js +1 -1
  54. package/lib/module/icons/index.js +10 -1
  55. package/lib/module/icons/lucide-icons-original-full.js +5 -1
  56. package/lib/module/icons/lucide-icons.js +56 -0
  57. package/lib/module/index.js +4 -0
  58. package/lib/module/settings/components/BubbleSettingsSection.js +21 -19
  59. package/lib/module/storage/devToolsStorageKeys.js +6 -3
  60. package/lib/module/ui/components/Badge.js +2 -0
  61. package/lib/module/ui/components/CompactRow.js +7 -0
  62. package/lib/module/ui/components/CopyButton.js +29 -6
  63. package/lib/module/ui/components/DevToolsCard.js +11 -0
  64. package/lib/module/ui/components/DynamicFilterView.js +8 -1
  65. package/lib/module/ui/components/EmptyState.js +12 -5
  66. package/lib/module/ui/components/ErrorBoundary.js +3 -2
  67. package/lib/module/ui/components/EventHistoryViewer/EventHistoryViewer.js +63 -11
  68. package/lib/module/ui/components/ExpandableSection.js +4 -3
  69. package/lib/module/ui/components/ExpandableSectionHeader.js +2 -1
  70. package/lib/module/ui/components/FilterViewPattern.js +9 -7
  71. package/lib/module/ui/components/ListItem.js +7 -5
  72. package/lib/module/ui/components/PowerToggleButton.js +4 -1
  73. package/lib/module/ui/components/TabSelector.js +3 -0
  74. package/lib/module/ui/console/CyberpunkConsoleSection.js +1 -1
  75. package/lib/module/ui/console/GalaxyButton.js +1 -1
  76. package/lib/module/ui/gameUI/components/GameUICompactStats.js +2 -2
  77. package/lib/module/ui/gameUI/constants/gameUIColors.js +27 -6
  78. package/lib/module/ui/gameUI/constants/macOSDesignSystemColors.js +19 -2
  79. package/lib/module/utils/index.js +1 -0
  80. package/lib/module/utils/reloadApp.js +137 -0
  81. package/lib/typescript/commonjs/colors/index.d.ts +22 -0
  82. package/lib/typescript/commonjs/colors/index.d.ts.map +1 -0
  83. package/lib/typescript/commonjs/dataViewer/DataTreeActionBar.d.ts +53 -0
  84. package/lib/typescript/commonjs/dataViewer/DataTreeActionBar.d.ts.map +1 -0
  85. package/lib/typescript/commonjs/dataViewer/DataTreeActionDock.d.ts +33 -0
  86. package/lib/typescript/commonjs/dataViewer/DataTreeActionDock.d.ts.map +1 -0
  87. package/lib/typescript/commonjs/dataViewer/DataViewer.d.ts +14 -1
  88. package/lib/typescript/commonjs/dataViewer/DataViewer.d.ts.map +1 -1
  89. package/lib/typescript/commonjs/dataViewer/VirtualizedDataExplorer.d.ts +30 -1
  90. package/lib/typescript/commonjs/dataViewer/VirtualizedDataExplorer.d.ts.map +1 -1
  91. package/lib/typescript/commonjs/dataViewer/__tests__/jsonOps.test.d.ts +19 -0
  92. package/lib/typescript/commonjs/dataViewer/__tests__/jsonOps.test.d.ts.map +1 -0
  93. package/lib/typescript/commonjs/dataViewer/index.d.ts +5 -1
  94. package/lib/typescript/commonjs/dataViewer/index.d.ts.map +1 -1
  95. package/lib/typescript/commonjs/dataViewer/jsonOps.d.ts +124 -0
  96. package/lib/typescript/commonjs/dataViewer/jsonOps.d.ts.map +1 -0
  97. package/lib/typescript/commonjs/dataViewer/lineDiff.d.ts +27 -0
  98. package/lib/typescript/commonjs/dataViewer/lineDiff.d.ts.map +1 -1
  99. package/lib/typescript/commonjs/dataViewer/tree/TreeDiffViewer.d.ts +8 -1
  100. package/lib/typescript/commonjs/dataViewer/tree/TreeDiffViewer.d.ts.map +1 -1
  101. package/lib/typescript/commonjs/dataViewer/treeActions.d.ts +83 -0
  102. package/lib/typescript/commonjs/dataViewer/treeActions.d.ts.map +1 -0
  103. package/lib/typescript/commonjs/hooks/safe-area-impl.d.ts +1 -1
  104. package/lib/typescript/commonjs/icons/index.d.ts +6 -1
  105. package/lib/typescript/commonjs/icons/index.d.ts.map +1 -1
  106. package/lib/typescript/commonjs/icons/lucide-icons-original-full.d.ts.map +1 -1
  107. package/lib/typescript/commonjs/icons/lucide-icons.d.ts +9 -0
  108. package/lib/typescript/commonjs/icons/lucide-icons.d.ts.map +1 -1
  109. package/lib/typescript/commonjs/index.d.ts +2 -1
  110. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  111. package/lib/typescript/commonjs/settings/components/BubbleSettingsSection.d.ts.map +1 -1
  112. package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts +5 -1
  113. package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts.map +1 -1
  114. package/lib/typescript/commonjs/ui/components/CopyButton.d.ts +7 -1
  115. package/lib/typescript/commonjs/ui/components/CopyButton.d.ts.map +1 -1
  116. package/lib/typescript/commonjs/ui/components/EmptyState.d.ts.map +1 -1
  117. package/lib/typescript/commonjs/ui/components/ErrorBoundary.d.ts.map +1 -1
  118. package/lib/typescript/commonjs/ui/components/EventHistoryViewer/EventHistoryViewer.d.ts.map +1 -1
  119. package/lib/typescript/commonjs/ui/components/EventHistoryViewer/types.d.ts +23 -7
  120. package/lib/typescript/commonjs/ui/components/EventHistoryViewer/types.d.ts.map +1 -1
  121. package/lib/typescript/commonjs/ui/components/ExpandableSection.d.ts.map +1 -1
  122. package/lib/typescript/commonjs/ui/components/ExpandableSectionHeader.d.ts.map +1 -1
  123. package/lib/typescript/commonjs/ui/components/FilterViewPattern.d.ts.map +1 -1
  124. package/lib/typescript/commonjs/ui/components/ListItem.d.ts.map +1 -1
  125. package/lib/typescript/commonjs/ui/gameUI/constants/gameUIColors.d.ts +36 -30
  126. package/lib/typescript/commonjs/ui/gameUI/constants/gameUIColors.d.ts.map +1 -1
  127. package/lib/typescript/commonjs/ui/gameUI/constants/macOSDesignSystemColors.d.ts +5 -0
  128. package/lib/typescript/commonjs/ui/gameUI/constants/macOSDesignSystemColors.d.ts.map +1 -1
  129. package/lib/typescript/commonjs/utils/index.d.ts +1 -0
  130. package/lib/typescript/commonjs/utils/index.d.ts.map +1 -1
  131. package/lib/typescript/commonjs/utils/reloadApp.d.ts +68 -0
  132. package/lib/typescript/commonjs/utils/reloadApp.d.ts.map +1 -0
  133. package/lib/typescript/module/colors/index.d.ts +22 -0
  134. package/lib/typescript/module/colors/index.d.ts.map +1 -0
  135. package/lib/typescript/module/dataViewer/DataTreeActionBar.d.ts +53 -0
  136. package/lib/typescript/module/dataViewer/DataTreeActionBar.d.ts.map +1 -0
  137. package/lib/typescript/module/dataViewer/DataTreeActionDock.d.ts +33 -0
  138. package/lib/typescript/module/dataViewer/DataTreeActionDock.d.ts.map +1 -0
  139. package/lib/typescript/module/dataViewer/DataViewer.d.ts +14 -1
  140. package/lib/typescript/module/dataViewer/DataViewer.d.ts.map +1 -1
  141. package/lib/typescript/module/dataViewer/VirtualizedDataExplorer.d.ts +30 -1
  142. package/lib/typescript/module/dataViewer/VirtualizedDataExplorer.d.ts.map +1 -1
  143. package/lib/typescript/module/dataViewer/__tests__/jsonOps.test.d.ts +19 -0
  144. package/lib/typescript/module/dataViewer/__tests__/jsonOps.test.d.ts.map +1 -0
  145. package/lib/typescript/module/dataViewer/index.d.ts +5 -1
  146. package/lib/typescript/module/dataViewer/index.d.ts.map +1 -1
  147. package/lib/typescript/module/dataViewer/jsonOps.d.ts +124 -0
  148. package/lib/typescript/module/dataViewer/jsonOps.d.ts.map +1 -0
  149. package/lib/typescript/module/dataViewer/lineDiff.d.ts +27 -0
  150. package/lib/typescript/module/dataViewer/lineDiff.d.ts.map +1 -1
  151. package/lib/typescript/module/dataViewer/tree/TreeDiffViewer.d.ts +8 -1
  152. package/lib/typescript/module/dataViewer/tree/TreeDiffViewer.d.ts.map +1 -1
  153. package/lib/typescript/module/dataViewer/treeActions.d.ts +83 -0
  154. package/lib/typescript/module/dataViewer/treeActions.d.ts.map +1 -0
  155. package/lib/typescript/module/hooks/safe-area-impl.d.ts +1 -1
  156. package/lib/typescript/module/icons/index.d.ts +6 -1
  157. package/lib/typescript/module/icons/index.d.ts.map +1 -1
  158. package/lib/typescript/module/icons/lucide-icons-original-full.d.ts.map +1 -1
  159. package/lib/typescript/module/icons/lucide-icons.d.ts +9 -0
  160. package/lib/typescript/module/icons/lucide-icons.d.ts.map +1 -1
  161. package/lib/typescript/module/index.d.ts +2 -1
  162. package/lib/typescript/module/index.d.ts.map +1 -1
  163. package/lib/typescript/module/settings/components/BubbleSettingsSection.d.ts.map +1 -1
  164. package/lib/typescript/module/storage/devToolsStorageKeys.d.ts +5 -1
  165. package/lib/typescript/module/storage/devToolsStorageKeys.d.ts.map +1 -1
  166. package/lib/typescript/module/ui/components/CopyButton.d.ts +7 -1
  167. package/lib/typescript/module/ui/components/CopyButton.d.ts.map +1 -1
  168. package/lib/typescript/module/ui/components/EmptyState.d.ts.map +1 -1
  169. package/lib/typescript/module/ui/components/ErrorBoundary.d.ts.map +1 -1
  170. package/lib/typescript/module/ui/components/EventHistoryViewer/EventHistoryViewer.d.ts.map +1 -1
  171. package/lib/typescript/module/ui/components/EventHistoryViewer/types.d.ts +23 -7
  172. package/lib/typescript/module/ui/components/EventHistoryViewer/types.d.ts.map +1 -1
  173. package/lib/typescript/module/ui/components/ExpandableSection.d.ts.map +1 -1
  174. package/lib/typescript/module/ui/components/ExpandableSectionHeader.d.ts.map +1 -1
  175. package/lib/typescript/module/ui/components/FilterViewPattern.d.ts.map +1 -1
  176. package/lib/typescript/module/ui/components/ListItem.d.ts.map +1 -1
  177. package/lib/typescript/module/ui/gameUI/constants/gameUIColors.d.ts +36 -30
  178. package/lib/typescript/module/ui/gameUI/constants/gameUIColors.d.ts.map +1 -1
  179. package/lib/typescript/module/ui/gameUI/constants/macOSDesignSystemColors.d.ts +5 -0
  180. package/lib/typescript/module/ui/gameUI/constants/macOSDesignSystemColors.d.ts.map +1 -1
  181. package/lib/typescript/module/utils/index.d.ts +1 -0
  182. package/lib/typescript/module/utils/index.d.ts.map +1 -1
  183. package/lib/typescript/module/utils/reloadApp.d.ts +68 -0
  184. package/lib/typescript/module/utils/reloadApp.d.ts.map +1 -0
  185. package/package.json +15 -4
  186. package/lib/commonjs/icons/ImageOverlayIcon.js +0 -142
  187. package/lib/module/icons/ImageOverlayIcon.js +0 -137
  188. package/lib/typescript/commonjs/icons/ImageOverlayIcon.d.ts +0 -14
  189. package/lib/typescript/commonjs/icons/ImageOverlayIcon.d.ts.map +0 -1
  190. package/lib/typescript/module/icons/ImageOverlayIcon.d.ts +0 -14
  191. package/lib/typescript/module/icons/ImageOverlayIcon.d.ts.map +0 -1
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Palette-only entry point.
5
+ *
6
+ * WHY THIS EXISTS: the desktop dashboard re-tints the design system by mutating
7
+ * these objects in place, and that has to happen BEFORE any component module is
8
+ * evaluated — React Native `StyleSheet.create({...})` calls run at module load
9
+ * and freeze whatever colors they read.
10
+ *
11
+ * Importing the palettes from the package root (`@buoy-gg/shared-ui`) does the
12
+ * opposite: the root barrel re-exports every component, so pulling one constant
13
+ * out of it evaluates all of their StyleSheets first, and the re-tint lands too
14
+ * late — panels keep dark surfaces while inline reads go light.
15
+ *
16
+ * This subpath pulls in the two constants modules and nothing else, so the
17
+ * bootstrap can swap palettes with an empty component graph behind it. Import
18
+ * from here in anything that runs before the app mounts.
19
+ */
20
+ export { macOSColors, macOSGameUIColors, refreshMacOSGameUIColors } from "../ui/gameUI/constants/macOSDesignSystemColors.js";
21
+ export { gameUIColors, buoyColors, dialColors, refreshGameUIColors } from "../ui/gameUI/constants/gameUIColors.js";
@@ -0,0 +1,384 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Footer bar for the data explorer's selected node — the editor's controls.
5
+ *
6
+ * Ports the action strip from the desktop mockup ("Desktop app network dev
7
+ * tools redesign" → Value card footer): the selected node's label and type on
8
+ * the left, its available operations on the right, and a hint line when nothing
9
+ * is selected yet.
10
+ *
11
+ * The controls deliberately do NOT live inside the tree rows. A row is 28px
12
+ * tall and already carries a caret, a key, a value and a copy button, so
13
+ * per-row icon buttons land around 20px — under the touch target a phone needs,
14
+ * and immediately beside the copy button, which makes mis-taps easy. Hosting
15
+ * them in one bar keeps every target full size and in a predictable place.
16
+ *
17
+ * So the split is: the tree owns SELECTION, this bar owns ACTIONS.
18
+ *
19
+ * Nothing here mutates. Each control emits a {@link JsonOp} against the
20
+ * selection's path and the host applies it, so the explorer stays a pure view.
21
+ */
22
+
23
+ import { useState } from "react";
24
+ import { StyleSheet, Text, TextInput, TouchableOpacity, View } from "react-native";
25
+ import { ChevronDown, ChevronUp, Copy, Edit3, Minus, Plus } from "../icons/index.js";
26
+ import { macOSColors } from "../ui/gameUI/index.js";
27
+ import { breadcrumb, treeActionMap, treeActionsFor, typeLabel } from "./treeActions.js";
28
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
29
+ /**
30
+ * Palette. The explorer renders on the phone's dark modal AND inside the
31
+ * dashboard's light table, so every value is paired rather than hardcoded —
32
+ * the light column is the mockup's own ramp.
33
+ */
34
+ const T = {
35
+ barBg: macOSColors.background.card,
36
+ barBorder: macOSColors.border.default,
37
+ label: macOSColors.text.primary,
38
+ badgeBg: macOSColors.background.hover,
39
+ badgeText: macOSColors.text.secondary,
40
+ hint: macOSColors.text.muted,
41
+ btnBg: macOSColors.background.hover,
42
+ btnBorder: macOSColors.border.default,
43
+ btnText: macOSColors.text.primary,
44
+ btnIcon: macOSColors.text.secondary,
45
+ dangerBorder: macOSColors.semantic.error + "55",
46
+ dangerText: macOSColors.semantic.error
47
+ };
48
+ const ICON = 13;
49
+ function Button({
50
+ label,
51
+ onPress,
52
+ icon,
53
+ danger,
54
+ iconOnly,
55
+ disabled,
56
+ style
57
+ }) {
58
+ return /*#__PURE__*/_jsxs(TouchableOpacity, {
59
+ "sentry-label": "ignore devtools tree action",
60
+ accessibilityLabel: label,
61
+ accessibilityState: {
62
+ disabled: !!disabled
63
+ },
64
+ onPress: disabled ? undefined : onPress,
65
+ disabled: disabled,
66
+ hitSlop: {
67
+ top: 8,
68
+ bottom: 8,
69
+ left: 6,
70
+ right: 6
71
+ },
72
+ style: [styles.button, iconOnly && styles.buttonIconOnly, danger && {
73
+ borderColor: T.dangerBorder
74
+ }, disabled && styles.buttonDisabled, style],
75
+ children: [icon, iconOnly ? null : /*#__PURE__*/_jsx(Text, {
76
+ style: [styles.buttonText, danger && {
77
+ color: T.dangerText
78
+ }],
79
+ children: label
80
+ })]
81
+ });
82
+ }
83
+ export function DataTreeActionBar({
84
+ root,
85
+ selection,
86
+ onEdit,
87
+ onRequestInlineEdit,
88
+ chipStyle
89
+ }) {
90
+ const has = selection != null;
91
+ // The bar's inline editor is a single-line field in a 28px row, so it can't
92
+ // take a container — hence `containersEditable` left off.
93
+ const a = treeActionMap(treeActionsFor(root, selection));
94
+ const apply = op => op && onEdit(op);
95
+ return /*#__PURE__*/_jsxs(View, {
96
+ style: styles.bar,
97
+ children: [/*#__PURE__*/_jsx(Text, {
98
+ style: [styles.selectionLabel, !has && styles.selectionLabelEmpty],
99
+ numberOfLines: 1,
100
+ children: has ? breadcrumb(selection.path) : "Select a row to edit"
101
+ }), /*#__PURE__*/_jsx(View, {
102
+ style: styles.badge,
103
+ children: /*#__PURE__*/_jsx(Text, {
104
+ style: styles.badgeText,
105
+ children: has ? typeLabel(selection.value) : "—"
106
+ })
107
+ }), /*#__PURE__*/_jsxs(View, {
108
+ style: styles.actions,
109
+ children: [/*#__PURE__*/_jsx(Button, {
110
+ label: a.editValue.label,
111
+ disabled: !a.editValue.enabled,
112
+ style: chipStyle,
113
+ icon: /*#__PURE__*/_jsx(Edit3, {
114
+ size: ICON,
115
+ color: T.btnIcon
116
+ }),
117
+ onPress: () => a.editValue.op ? onEdit(a.editValue.op) : onRequestInlineEdit()
118
+ }), /*#__PURE__*/_jsx(Button, {
119
+ label: a.add.label,
120
+ disabled: !a.add.enabled,
121
+ style: chipStyle,
122
+ icon: /*#__PURE__*/_jsx(Plus, {
123
+ size: ICON,
124
+ color: T.btnIcon
125
+ }),
126
+ onPress: () => apply(a.add.op)
127
+ }), /*#__PURE__*/_jsx(Button, {
128
+ label: a.moveUp.label,
129
+ iconOnly: true,
130
+ disabled: !a.moveUp.enabled,
131
+ style: chipStyle,
132
+ icon: /*#__PURE__*/_jsx(ChevronUp, {
133
+ size: 14,
134
+ color: T.btnIcon
135
+ }),
136
+ onPress: () => apply(a.moveUp.op)
137
+ }), /*#__PURE__*/_jsx(Button, {
138
+ label: a.moveDown.label,
139
+ iconOnly: true,
140
+ disabled: !a.moveDown.enabled,
141
+ style: chipStyle,
142
+ icon: /*#__PURE__*/_jsx(ChevronDown, {
143
+ size: 14,
144
+ color: T.btnIcon
145
+ }),
146
+ onPress: () => apply(a.moveDown.op)
147
+ }), /*#__PURE__*/_jsx(Button, {
148
+ label: a.duplicate.label,
149
+ disabled: !a.duplicate.enabled,
150
+ style: chipStyle,
151
+ icon: /*#__PURE__*/_jsx(Copy, {
152
+ size: ICON,
153
+ color: T.btnIcon
154
+ }),
155
+ onPress: () => apply(a.duplicate.op)
156
+ }), /*#__PURE__*/_jsx(Button, {
157
+ label: a.remove.label,
158
+ danger: true,
159
+ disabled: !a.remove.enabled,
160
+ style: chipStyle,
161
+ icon: /*#__PURE__*/_jsx(Minus, {
162
+ size: ICON,
163
+ color: T.dangerText
164
+ }),
165
+ onPress: () => apply(a.remove.op)
166
+ })]
167
+ })]
168
+ });
169
+ }
170
+
171
+ /**
172
+ * The field that replaces a row's value while editing it, per the mockup.
173
+ *
174
+ * Type-preserving by construction rather than by parsing guesswork: the
175
+ * ORIGINAL value's type decides how the draft is read back, so editing a number
176
+ * can only ever produce a number. Booleans skip text entirely — there is
177
+ * nothing to type, so they commit straight from a two-way toggle.
178
+ */
179
+ export function DataTreeInlineEditor({
180
+ value,
181
+ onCommit,
182
+ onCancel
183
+ }) {
184
+ const [draft, setDraft] = useState(() => value === null || value === undefined ? "" : String(value));
185
+ if (typeof value === "boolean") {
186
+ return /*#__PURE__*/_jsxs(View, {
187
+ style: styles.inlineRow,
188
+ children: [[true, false].map(option => /*#__PURE__*/_jsx(TouchableOpacity, {
189
+ accessibilityLabel: `Set ${option}`,
190
+ onPress: () => onCommit(option),
191
+ hitSlop: {
192
+ top: 8,
193
+ bottom: 8,
194
+ left: 6,
195
+ right: 6
196
+ },
197
+ style: [styles.button, value === option && styles.buttonActive],
198
+ children: /*#__PURE__*/_jsx(Text, {
199
+ style: styles.buttonText,
200
+ children: String(option)
201
+ })
202
+ }, String(option))), /*#__PURE__*/_jsx(TouchableOpacity, {
203
+ accessibilityLabel: "Cancel edit",
204
+ onPress: onCancel,
205
+ hitSlop: {
206
+ top: 8,
207
+ bottom: 8,
208
+ left: 6,
209
+ right: 6
210
+ },
211
+ style: styles.button,
212
+ children: /*#__PURE__*/_jsx(Text, {
213
+ style: styles.buttonText,
214
+ children: "Cancel"
215
+ })
216
+ })]
217
+ });
218
+ }
219
+ const isNumber = typeof value === "number";
220
+ const invalid = isNumber && (draft.trim() === "" || Number.isNaN(Number(draft)));
221
+ const commit = () => {
222
+ if (invalid) return;
223
+ onCommit(isNumber ? Number(draft) : draft);
224
+ };
225
+ return /*#__PURE__*/_jsxs(View, {
226
+ style: styles.inlineRow,
227
+ children: [/*#__PURE__*/_jsx(TextInput, {
228
+ value: draft,
229
+ onChangeText: setDraft,
230
+ onSubmitEditing: commit,
231
+ autoFocus: true,
232
+ autoCapitalize: "none",
233
+ autoCorrect: false,
234
+ spellCheck: false,
235
+ keyboardType: isNumber ? "numeric" : "default",
236
+ style: [styles.input, invalid && styles.inputInvalid],
237
+ placeholderTextColor: T.hint
238
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
239
+ accessibilityLabel: "Save value",
240
+ onPress: commit,
241
+ hitSlop: {
242
+ top: 8,
243
+ bottom: 8,
244
+ left: 6,
245
+ right: 6
246
+ },
247
+ style: [styles.saveButton, invalid && styles.saveButtonDisabled],
248
+ children: /*#__PURE__*/_jsx(Text, {
249
+ style: styles.saveText,
250
+ children: "Save"
251
+ })
252
+ }), /*#__PURE__*/_jsx(TouchableOpacity, {
253
+ accessibilityLabel: "Cancel edit",
254
+ onPress: onCancel,
255
+ hitSlop: {
256
+ top: 8,
257
+ bottom: 8,
258
+ left: 6,
259
+ right: 6
260
+ },
261
+ style: styles.button,
262
+ children: /*#__PURE__*/_jsx(Text, {
263
+ style: styles.buttonText,
264
+ children: "Cancel"
265
+ })
266
+ })]
267
+ });
268
+ }
269
+ const styles = StyleSheet.create({
270
+ inlineRow: {
271
+ flex: 1,
272
+ flexDirection: "row",
273
+ alignItems: "center",
274
+ gap: 6
275
+ },
276
+ input: {
277
+ flex: 1,
278
+ minWidth: 0,
279
+ height: 28,
280
+ color: T.label,
281
+ backgroundColor: macOSColors.background.input,
282
+ borderWidth: 1,
283
+ borderColor: macOSColors.border.input,
284
+ borderRadius: 7,
285
+ paddingHorizontal: 9,
286
+ paddingVertical: 0,
287
+ fontSize: 12,
288
+ fontFamily: "monospace"
289
+ },
290
+ inputInvalid: {
291
+ borderColor: macOSColors.semantic.error
292
+ },
293
+ saveButton: {
294
+ height: 28,
295
+ justifyContent: "center",
296
+ paddingHorizontal: 10,
297
+ borderRadius: 7,
298
+ backgroundColor: macOSColors.semantic.success
299
+ },
300
+ saveButtonDisabled: {
301
+ opacity: 0.4
302
+ },
303
+ saveText: {
304
+ color: macOSColors.background.base,
305
+ fontSize: 12,
306
+ fontWeight: "600"
307
+ },
308
+ buttonActive: {
309
+ borderColor: macOSColors.semantic.success
310
+ },
311
+ bar: {
312
+ flexDirection: "row",
313
+ flexWrap: "wrap",
314
+ alignItems: "center",
315
+ gap: 8,
316
+ paddingHorizontal: 12,
317
+ paddingVertical: 9,
318
+ borderTopWidth: 1,
319
+ borderTopColor: T.barBorder,
320
+ backgroundColor: T.barBg
321
+ },
322
+ actions: {
323
+ flexDirection: "row",
324
+ flexWrap: "wrap",
325
+ alignItems: "center",
326
+ gap: 6,
327
+ marginLeft: "auto"
328
+ },
329
+ selectionLabelEmpty: {
330
+ color: T.hint,
331
+ fontWeight: "400"
332
+ },
333
+ selectionLabel: {
334
+ color: T.label,
335
+ fontSize: 12,
336
+ fontWeight: "600",
337
+ fontFamily: "monospace",
338
+ flexShrink: 1
339
+ },
340
+ badge: {
341
+ paddingHorizontal: 7,
342
+ paddingVertical: 1,
343
+ borderRadius: 5,
344
+ backgroundColor: T.badgeBg
345
+ },
346
+ badgeText: {
347
+ color: T.badgeText,
348
+ fontSize: 11,
349
+ fontWeight: "600"
350
+ },
351
+ button: {
352
+ flexDirection: "row",
353
+ alignItems: "center",
354
+ gap: 6,
355
+ // Sized for a finger, not just a cursor — this bar is shared with the phone.
356
+ minHeight: 32,
357
+ paddingHorizontal: 11,
358
+ borderRadius: 8,
359
+ borderWidth: 1,
360
+ borderColor: T.btnBorder,
361
+ backgroundColor: T.btnBg
362
+ },
363
+ buttonDisabled: {
364
+ // Dimmed, not removed. An action that vanishes when it stops applying
365
+ // reflows every other control — so moving the selection between siblings
366
+ // would shuffle the buttons under the user's finger.
367
+ opacity: 0.35
368
+ },
369
+ buttonIconOnly: {
370
+ paddingHorizontal: 0,
371
+ width: 32,
372
+ justifyContent: "center"
373
+ },
374
+ buttonText: {
375
+ color: T.btnText,
376
+ fontSize: 12,
377
+ fontWeight: "600"
378
+ },
379
+ hint: {
380
+ color: T.hint,
381
+ fontSize: 12,
382
+ flexShrink: 1
383
+ }
384
+ });
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * The phone's edit controls — a fixed grid of six thumb-sized tiles, docked
5
+ * under a full-screen tree.
6
+ *
7
+ * The dashboard renders the same six actions as {@link DataTreeActionBar}: a
8
+ * row of small chips, which is right beside a cursor and wrong under a thumb.
9
+ * Both read their list from `treeActionsFor`, so what's legal can't drift
10
+ * between them — only the shape does.
11
+ *
12
+ * Two tiles per row of three, always in the same slots, disabled rather than
13
+ * hidden. See `treeActionsFor` for why the list is fixed-length.
14
+ */
15
+
16
+ import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
17
+ import { ChevronDown, ChevronUp, Copy, Edit3, Minus, Plus } from "../icons/index.js";
18
+ import { macOSColors } from "../ui/gameUI/index.js";
19
+ import { breadcrumb, treeActionsFor, typeLabel } from "./treeActions.js";
20
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
21
+ const T = {
22
+ dockBg: macOSColors.background.card,
23
+ dockBorder: macOSColors.border.default,
24
+ tileBg: macOSColors.background.hover,
25
+ tileBorder: macOSColors.border.default,
26
+ tileText: macOSColors.text.primary,
27
+ tileIcon: macOSColors.text.secondary,
28
+ hint: macOSColors.text.muted,
29
+ label: macOSColors.text.primary,
30
+ badgeBg: macOSColors.background.hover,
31
+ badgeText: macOSColors.text.secondary,
32
+ dangerBorder: macOSColors.semantic.error + "55",
33
+ dangerText: macOSColors.semantic.error
34
+ };
35
+ const ICON = 16;
36
+
37
+ /** Icons live with the renderer, not the action list — see `treeActions`. */
38
+ function iconFor(id, color) {
39
+ switch (id) {
40
+ case "editValue":
41
+ return /*#__PURE__*/_jsx(Edit3, {
42
+ size: ICON,
43
+ color: color
44
+ });
45
+ case "add":
46
+ return /*#__PURE__*/_jsx(Plus, {
47
+ size: ICON,
48
+ color: color
49
+ });
50
+ case "duplicate":
51
+ return /*#__PURE__*/_jsx(Copy, {
52
+ size: ICON,
53
+ color: color
54
+ });
55
+ case "moveUp":
56
+ return /*#__PURE__*/_jsx(ChevronUp, {
57
+ size: ICON + 2,
58
+ color: color
59
+ });
60
+ case "moveDown":
61
+ return /*#__PURE__*/_jsx(ChevronDown, {
62
+ size: ICON + 2,
63
+ color: color
64
+ });
65
+ case "remove":
66
+ return /*#__PURE__*/_jsx(Minus, {
67
+ size: ICON,
68
+ color: color
69
+ });
70
+ }
71
+ }
72
+ function Tile({
73
+ action,
74
+ onPress
75
+ }) {
76
+ const {
77
+ enabled,
78
+ danger,
79
+ label,
80
+ id
81
+ } = action;
82
+ const color = danger && enabled ? T.dangerText : T.tileIcon;
83
+ return /*#__PURE__*/_jsxs(TouchableOpacity, {
84
+ "sentry-label": "ignore devtools tree action",
85
+ accessibilityLabel: label,
86
+ accessibilityState: {
87
+ disabled: !enabled
88
+ },
89
+ disabled: !enabled,
90
+ onPress: enabled ? onPress : undefined,
91
+ style: [styles.tile, danger && enabled && {
92
+ borderColor: T.dangerBorder
93
+ }, !enabled && styles.tileDisabled],
94
+ children: [iconFor(id, color), /*#__PURE__*/_jsx(Text, {
95
+ style: [styles.tileText, danger && enabled && {
96
+ color: T.dangerText
97
+ }],
98
+ numberOfLines: 1,
99
+ children: label
100
+ })]
101
+ });
102
+ }
103
+ export function DataTreeActionDock({
104
+ root,
105
+ selection,
106
+ onEdit,
107
+ onSelectPath,
108
+ onEditValue,
109
+ containersEditable = true
110
+ }) {
111
+ const actions = treeActionsFor(root, selection, {
112
+ containersEditable
113
+ });
114
+ const has = selection != null;
115
+ const run = action => {
116
+ // No op means the host has to ask the user something — today that's only
117
+ // "edit this value". A boolean arrives here WITH an op and so just flips.
118
+ if (!action.op) {
119
+ onEditValue();
120
+ return;
121
+ }
122
+ onEdit(action.op);
123
+ // Ops that CREATE a node say where it landed; the ones that move or delete
124
+ // one are handled by `selectionPathAfterOp` inside the host's draft.
125
+ if (action.selectAfter) onSelectPath(action.selectAfter);
126
+ };
127
+ return /*#__PURE__*/_jsxs(View, {
128
+ style: styles.dock,
129
+ children: [/*#__PURE__*/_jsxs(View, {
130
+ style: styles.header,
131
+ children: [/*#__PURE__*/_jsx(Text, {
132
+ style: [styles.selectionLabel, !has && styles.selectionLabelEmpty],
133
+ numberOfLines: 1,
134
+ children: has ? breadcrumb(selection.path) : "Tap a row to select it"
135
+ }), /*#__PURE__*/_jsx(View, {
136
+ style: styles.badge,
137
+ children: /*#__PURE__*/_jsx(Text, {
138
+ style: styles.badgeText,
139
+ children: has ? typeLabel(selection.value) : "—"
140
+ })
141
+ })]
142
+ }), /*#__PURE__*/_jsx(View, {
143
+ style: styles.grid,
144
+ children: actions.map(action => /*#__PURE__*/_jsx(Tile, {
145
+ action: action,
146
+ onPress: () => run(action)
147
+ }, action.id))
148
+ })]
149
+ });
150
+ }
151
+ const styles = StyleSheet.create({
152
+ dock: {
153
+ borderTopWidth: 1,
154
+ borderTopColor: T.dockBorder,
155
+ backgroundColor: T.dockBg,
156
+ paddingHorizontal: 10,
157
+ paddingTop: 8,
158
+ paddingBottom: 10,
159
+ gap: 8
160
+ },
161
+ header: {
162
+ flexDirection: "row",
163
+ alignItems: "center",
164
+ gap: 8,
165
+ paddingHorizontal: 2
166
+ },
167
+ selectionLabel: {
168
+ flex: 1,
169
+ color: T.label,
170
+ fontSize: 12,
171
+ fontWeight: "600",
172
+ fontFamily: "monospace"
173
+ },
174
+ selectionLabelEmpty: {
175
+ color: T.hint,
176
+ fontWeight: "400"
177
+ },
178
+ badge: {
179
+ paddingHorizontal: 7,
180
+ paddingVertical: 1,
181
+ borderRadius: 5,
182
+ backgroundColor: T.badgeBg
183
+ },
184
+ badgeText: {
185
+ color: T.badgeText,
186
+ fontSize: 11,
187
+ fontWeight: "600"
188
+ },
189
+ grid: {
190
+ flexDirection: "row",
191
+ flexWrap: "wrap",
192
+ gap: 8
193
+ },
194
+ tile: {
195
+ // Three per row, sized off the gaps rather than a fixed width so the grid
196
+ // survives a narrow phone and a tablet split view alike.
197
+ flexBasis: "31%",
198
+ flexGrow: 1,
199
+ minHeight: 54,
200
+ alignItems: "center",
201
+ justifyContent: "center",
202
+ gap: 3,
203
+ paddingHorizontal: 6,
204
+ borderRadius: 10,
205
+ borderWidth: 1,
206
+ borderColor: T.tileBorder,
207
+ backgroundColor: T.tileBg
208
+ },
209
+ tileDisabled: {
210
+ // Dimmed, not removed — see `treeActionsFor`.
211
+ opacity: 0.35
212
+ },
213
+ tileText: {
214
+ color: T.tileText,
215
+ fontSize: 11,
216
+ fontWeight: "600"
217
+ }
218
+ });
@@ -22,7 +22,12 @@ export const DataViewer = ({
22
22
  rawMode = true,
23
23
  showTypeFilter = true,
24
24
  initialExpanded = false,
25
- disableCopy = false
25
+ disableCopy = false,
26
+ onSelectionChange,
27
+ onRequestInlineEdit,
28
+ inlineEditPath,
29
+ renderInlineEditor,
30
+ selectPath
26
31
  }) => {
27
32
  const [activeFilter, setActiveFilter] = useState(null);
28
33
 
@@ -91,7 +96,12 @@ export const DataViewer = ({
91
96
 
92
97
  // Render content based on filter state
93
98
  const renderContent = () => {
94
- // Show filtered results if filter is active
99
+ // Show filtered results if filter is active.
100
+ //
101
+ // Selection is deliberately NOT forwarded here: the filtered view is a
102
+ // DERIVED object, so its row paths address that projection rather than the
103
+ // real document. An op built from one would edit an unrelated node —
104
+ // silently, and with a plausible-looking result.
95
105
  if (activeFilter && getFilteredData) {
96
106
  return /*#__PURE__*/_jsx(VirtualizedDataExplorer, {
97
107
  title: `${activeFilter} values`,
@@ -110,7 +120,12 @@ export const DataViewer = ({
110
120
  maxDepth: maxDepth,
111
121
  rawMode: rawMode,
112
122
  initialExpanded: initialExpanded,
113
- disableCopy: disableCopy
123
+ disableCopy: disableCopy,
124
+ onSelectionChange: onSelectionChange,
125
+ onRequestInlineEdit: onRequestInlineEdit,
126
+ inlineEditPath: inlineEditPath,
127
+ renderInlineEditor: renderInlineEditor,
128
+ selectPath: selectPath
114
129
  });
115
130
  };
116
131
  return /*#__PURE__*/_jsxs(View, {