@buoy-gg/redux 7.0.38 → 7.0.39

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 (68) hide show
  1. package/lib/commonjs/index.js +256 -1
  2. package/lib/commonjs/preset.js +90 -1
  3. package/lib/commonjs/redux/components/ReduxActionButton.js +131 -1
  4. package/lib/commonjs/redux/components/ReduxActionDetailContent.js +437 -1
  5. package/lib/commonjs/redux/components/ReduxActionDetailView.js +401 -1
  6. package/lib/commonjs/redux/components/ReduxActionInfoView.js +836 -1
  7. package/lib/commonjs/redux/components/ReduxActionItem.js +334 -1
  8. package/lib/commonjs/redux/components/ReduxAutoInstrument.js +20 -1
  9. package/lib/commonjs/redux/components/ReduxDetailViewToggle.js +50 -1
  10. package/lib/commonjs/redux/components/ReduxIcon.js +18 -1
  11. package/lib/commonjs/redux/components/ReduxModal.js +703 -1
  12. package/lib/commonjs/redux/hooks/useAutoInstrumentRedux.js +187 -1
  13. package/lib/commonjs/redux/hooks/useReduxActions.js +58 -1
  14. package/lib/commonjs/redux/sync/reduxSyncAdapter.js +191 -1
  15. package/lib/commonjs/redux/utils/activeStoreRegistry.js +104 -1
  16. package/lib/commonjs/redux/utils/autoInstrument.js +231 -1
  17. package/lib/commonjs/redux/utils/buoyReduxMiddleware.js +202 -1
  18. package/lib/commonjs/redux/utils/createReduxHistoryAdapter.js +146 -1
  19. package/lib/commonjs/redux/utils/devtoolsHook.js +152 -1
  20. package/lib/commonjs/redux/utils/reduxActionStore.js +473 -1
  21. package/lib/commonjs/redux/utils/snapshotProvider.js +158 -1
  22. package/lib/commonjs/redux/utils/testIDs.js +75 -1
  23. package/lib/module/index.js +125 -1
  24. package/lib/module/preset.js +87 -1
  25. package/lib/module/redux/components/ReduxActionButton.js +128 -1
  26. package/lib/module/redux/components/ReduxActionDetailContent.js +433 -1
  27. package/lib/module/redux/components/ReduxActionDetailView.js +397 -1
  28. package/lib/module/redux/components/ReduxActionInfoView.js +831 -1
  29. package/lib/module/redux/components/ReduxActionItem.js +330 -1
  30. package/lib/module/redux/components/ReduxAutoInstrument.js +17 -1
  31. package/lib/module/redux/components/ReduxDetailViewToggle.js +45 -1
  32. package/lib/module/redux/components/ReduxIcon.js +8 -1
  33. package/lib/module/redux/components/ReduxModal.js +698 -1
  34. package/lib/module/redux/hooks/useAutoInstrumentRedux.js +183 -1
  35. package/lib/module/redux/hooks/useReduxActions.js +54 -1
  36. package/lib/module/redux/sync/reduxSyncAdapter.js +188 -1
  37. package/lib/module/redux/utils/activeStoreRegistry.js +92 -1
  38. package/lib/module/redux/utils/autoInstrument.js +201 -1
  39. package/lib/module/redux/utils/buoyReduxMiddleware.js +188 -1
  40. package/lib/module/redux/utils/createReduxHistoryAdapter.js +142 -1
  41. package/lib/module/redux/utils/devtoolsHook.js +145 -1
  42. package/lib/module/redux/utils/reduxActionStore.js +465 -1
  43. package/lib/module/redux/utils/snapshotProvider.js +157 -1
  44. package/lib/module/redux/utils/testIDs.js +68 -1
  45. package/lib/typescript/index.d.ts.map +1 -0
  46. package/lib/typescript/preset.d.ts.map +1 -0
  47. package/lib/typescript/redux/components/ReduxActionButton.d.ts.map +1 -0
  48. package/lib/typescript/redux/components/ReduxActionDetailContent.d.ts.map +1 -0
  49. package/lib/typescript/redux/components/ReduxActionDetailView.d.ts.map +1 -0
  50. package/lib/typescript/redux/components/ReduxActionInfoView.d.ts.map +1 -0
  51. package/lib/typescript/redux/components/ReduxActionItem.d.ts.map +1 -0
  52. package/lib/typescript/redux/components/ReduxAutoInstrument.d.ts.map +1 -0
  53. package/lib/typescript/redux/components/ReduxDetailViewToggle.d.ts.map +1 -0
  54. package/lib/typescript/redux/components/ReduxIcon.d.ts.map +1 -0
  55. package/lib/typescript/redux/components/ReduxModal.d.ts.map +1 -0
  56. package/lib/typescript/redux/hooks/useAutoInstrumentRedux.d.ts.map +1 -0
  57. package/lib/typescript/redux/hooks/useReduxActions.d.ts.map +1 -0
  58. package/lib/typescript/redux/sync/reduxSyncAdapter.d.ts.map +1 -0
  59. package/lib/typescript/redux/types/index.d.ts.map +1 -0
  60. package/lib/typescript/redux/utils/activeStoreRegistry.d.ts.map +1 -0
  61. package/lib/typescript/redux/utils/autoInstrument.d.ts.map +1 -0
  62. package/lib/typescript/redux/utils/buoyReduxMiddleware.d.ts.map +1 -0
  63. package/lib/typescript/redux/utils/createReduxHistoryAdapter.d.ts.map +1 -0
  64. package/lib/typescript/redux/utils/devtoolsHook.d.ts.map +1 -0
  65. package/lib/typescript/redux/utils/reduxActionStore.d.ts.map +1 -0
  66. package/lib/typescript/redux/utils/snapshotProvider.d.ts.map +1 -0
  67. package/lib/typescript/redux/utils/testIDs.d.ts.map +1 -0
  68. package/package.json +4 -4
@@ -1 +1,330 @@
1
- "use strict";import{memo}from"react";import{View,Text,StyleSheet}from"react-native";import{ChangeRow,buoyColors,AlertCircle,monoFont}from"@buoy-gg/shared-ui";import{reduxActionStore}from"../utils/reduxActionStore";import{jsxs as _jsxs,jsx as _jsx}from"react/jsx-runtime";const OPERATION_COLORS=[{bg:"rgba(99, 102, 241, 0.25)",text:"#818CF8"},{bg:"rgba(236, 72, 153, 0.25)",text:"#F472B6"},{bg:"rgba(14, 165, 233, 0.25)",text:"#38BDF8"},{bg:"rgba(245, 158, 11, 0.25)",text:"#FBBF24"},{bg:"rgba(16, 185, 129, 0.25)",text:"#34D399"},{bg:"rgba(168, 85, 247, 0.25)",text:"#C084FC"},{bg:"rgba(239, 68, 68, 0.25)",text:"#F87171"},{bg:"rgba(20, 184, 166, 0.25)",text:"#2DD4BF"}];function getOperationColor(e){return e<=0?{bg:"rgba(142, 142, 147, 0.2)",text:buoyColors.textSecondary}:OPERATION_COLORS[(e-1)%OPERATION_COLORS.length]}const SLICE_COLORS={cart:"#10B981",user:"#3B82F6",auth:"#8B5CF6",app:"#6366F1",ui:"#EC4899",settings:"#F59E0B",api:"#14B8A6",data:"#06B6D4"};function getSliceColor(e){if(!e)return"#6B7280";const t=e.toLowerCase();if(SLICE_COLORS[t])return SLICE_COLORS[t];for(const[e,r]of Object.entries(SLICE_COLORS))if(t.includes(e))return r;return`hsl(${137*e.split("").reduce((e,t)=>e+t.charCodeAt(0),0)%360}, 70%, 60%)`}function getStatusLabel(e,t){switch(e){case"pending":return"Pending";case"fulfilled":return"Success";case"rejected":return"Error";case"internal":return"Internal";case"query":return"Query";case"mutation":return"Mutation";default:return t?t.charAt(0).toUpperCase()+t.slice(1):"Action"}}function getStatusColor(e,t,r){switch(e){case"pending":return buoyColors.warning;case"fulfilled":return buoyColors.success;case"rejected":return buoyColors.error;case"internal":return buoyColors.textMuted;case"query":case"mutation":return buoyColors.info;default:return getSliceColor(r)}}function getSublabel(e){const t=[];return void 0!==e.duration&&e.duration>=.1&&t.push(`${e.duration.toFixed(1)}ms`),e.hasStateChange?e.changedKeysCount&&e.changedKeysCount>0?t.push(`${e.changedKeysCount} key${e.changedKeysCount>1?"s":""} changed`):t.push(e.diffSummary||"state changed"):t.push("no state change"),t.join(" · ")}function getActionBadge(e){return e.actionName?.toUpperCase()||e.type.split("/").pop()?.toUpperCase()||""}function getPrimaryText(e){return"internal"===e.category?e.type:e.sliceName?`${e.sliceName}/${e.actionName.toLowerCase()}`:e.type}export const ReduxActionItem=memo(function({action:e,onPress:t,linkedCount:r,testID:o}){const n=e.sliceName??void 0,a=getStatusColor(e.category,e.hasStateChange,n),s=getStatusLabel(e.category,n),i=getSublabel(e),c=getPrimaryText(e),u=getActionBadge(e),g=(r??0)>1,l=g?reduxActionStore.getLinkedActions(e):[],d=g?l.findIndex(t=>t.id===e.id)+1:0,C=g&&e.meta?.requestId?reduxActionStore.getAsyncOperationIndex(e.meta.requestId):0,x=getOperationColor(C),b=g?_jsx(View,{style:[styles.asyncSequenceBadge,{backgroundColor:x.bg}],children:_jsxs(Text,{style:[styles.asyncSequenceText,{color:x.text}],testID:o?`${o}-seq`:void 0,children:[d,"/",r," #",C]})}):void 0,y={statusColor:a,statusLabel:s,sublabel:i,primaryText:c,timestamp:e.timestamp,onPress:()=>t(e),testID:o,accessibilityLabel:`${c}, ${s}, ${i}`};return e.isSlowAction?_jsx(ChangeRow,{...y,badgePrefix:b,slow:!0}):"rejected"===e.category?_jsx(ChangeRow,{...y,customBadge:_jsxs(View,{style:styles.badgeContainer,children:[b,_jsx(View,{style:styles.errorBadge,testID:o?`${o}-error`:void 0,children:_jsx(AlertCircle,{size:12,color:buoyColors.error})})]})}):g?_jsx(ChangeRow,{...y,badgePrefix:b,changed:e.hasStateChange}):e.hasStateChange?_jsx(ChangeRow,{...y,badgeText:u,changed:!0}):_jsx(ChangeRow,{...y,plainBadgeText:u})});const styles=StyleSheet.create({badgeContainer:{flexDirection:"row",alignItems:"center",gap:4},errorBadge:{paddingHorizontal:4},asyncSequenceBadge:{paddingHorizontal:6,paddingVertical:2,borderRadius:4},asyncSequenceText:{fontSize:10,fontWeight:"600",fontFamily:monoFont}});
1
+ "use strict";
2
+
3
+ /**
4
+ * Compact list item for displaying a Redux action
5
+ * Uses shared CompactRow for consistent styling with React Query devtools
6
+ */
7
+
8
+ import { memo } from "react";
9
+ import { View, Text, StyleSheet } from "react-native";
10
+ import { ChangeRow, buoyColors, AlertCircle, monoFont } from "@buoy-gg/shared-ui";
11
+ import { reduxActionStore } from "../utils/reduxActionStore";
12
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
13
+ /**
14
+ * Color palette for async operation badges
15
+ * Each operation gets a distinct color to make matching easy
16
+ */
17
+ const OPERATION_COLORS = [{
18
+ bg: "rgba(99, 102, 241, 0.25)",
19
+ text: "#818CF8"
20
+ },
21
+ // indigo
22
+ {
23
+ bg: "rgba(236, 72, 153, 0.25)",
24
+ text: "#F472B6"
25
+ },
26
+ // pink
27
+ {
28
+ bg: "rgba(14, 165, 233, 0.25)",
29
+ text: "#38BDF8"
30
+ },
31
+ // sky
32
+ {
33
+ bg: "rgba(245, 158, 11, 0.25)",
34
+ text: "#FBBF24"
35
+ },
36
+ // amber
37
+ {
38
+ bg: "rgba(16, 185, 129, 0.25)",
39
+ text: "#34D399"
40
+ },
41
+ // emerald
42
+ {
43
+ bg: "rgba(168, 85, 247, 0.25)",
44
+ text: "#C084FC"
45
+ },
46
+ // purple
47
+ {
48
+ bg: "rgba(239, 68, 68, 0.25)",
49
+ text: "#F87171"
50
+ },
51
+ // red
52
+ {
53
+ bg: "rgba(20, 184, 166, 0.25)",
54
+ text: "#2DD4BF"
55
+ } // teal
56
+ ];
57
+ function getOperationColor(index) {
58
+ if (index <= 0) return {
59
+ bg: "rgba(142, 142, 147, 0.2)",
60
+ text: buoyColors.textSecondary
61
+ };
62
+ return OPERATION_COLORS[(index - 1) % OPERATION_COLORS.length];
63
+ }
64
+
65
+ /**
66
+ * Slice color palette - consistent colors per slice name
67
+ * Makes it easy to visually track actions from the same slice
68
+ */
69
+ const SLICE_COLORS = {
70
+ cart: "#10B981",
71
+ // emerald - shopping/commerce
72
+ user: "#3B82F6",
73
+ // blue - user related
74
+ auth: "#8B5CF6",
75
+ // purple - authentication
76
+ app: "#6366F1",
77
+ // indigo - app-wide
78
+ ui: "#EC4899",
79
+ // pink - UI state
80
+ settings: "#F59E0B",
81
+ // amber - settings
82
+ api: "#14B8A6",
83
+ // teal - API calls
84
+ data: "#06B6D4" // cyan - data management
85
+ };
86
+
87
+ /**
88
+ * Get consistent color for a slice based on its name
89
+ */
90
+ function getSliceColor(sliceName) {
91
+ if (!sliceName) return "#6B7280"; // gray for unknown
92
+
93
+ const lowerSlice = sliceName.toLowerCase();
94
+
95
+ // Check for exact match first
96
+ if (SLICE_COLORS[lowerSlice]) {
97
+ return SLICE_COLORS[lowerSlice];
98
+ }
99
+
100
+ // Check for partial matches
101
+ for (const [key, color] of Object.entries(SLICE_COLORS)) {
102
+ if (lowerSlice.includes(key)) {
103
+ return color;
104
+ }
105
+ }
106
+
107
+ // Generate consistent color from slice name hash
108
+ const hash = sliceName.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0);
109
+ const hue = hash * 137 % 360;
110
+ return `hsl(${hue}, 70%, 60%)`;
111
+ }
112
+
113
+ /**
114
+ * Get status label based on category and slice
115
+ */
116
+ function getStatusLabel(category, sliceName) {
117
+ switch (category) {
118
+ case "pending":
119
+ return "Pending";
120
+ case "fulfilled":
121
+ return "Success";
122
+ case "rejected":
123
+ return "Error";
124
+ case "internal":
125
+ return "Internal";
126
+ case "query":
127
+ return "Query";
128
+ case "mutation":
129
+ return "Mutation";
130
+ default:
131
+ // For regular actions, show slice name if available
132
+ return sliceName ? sliceName.charAt(0).toUpperCase() + sliceName.slice(1) : "Action";
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Get color for action category
138
+ */
139
+ function getStatusColor(category, hasStateChange, sliceName) {
140
+ switch (category) {
141
+ case "pending":
142
+ return buoyColors.warning;
143
+ case "fulfilled":
144
+ return buoyColors.success;
145
+ case "rejected":
146
+ return buoyColors.error;
147
+ case "internal":
148
+ return buoyColors.textMuted;
149
+ case "query":
150
+ return buoyColors.info;
151
+ case "mutation":
152
+ return buoyColors.info;
153
+ default:
154
+ // For regular actions, use slice-based color
155
+ return getSliceColor(sliceName);
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Get sublabel with duration and diff info
161
+ */
162
+ function getSublabel(action) {
163
+ const parts = [];
164
+
165
+ // Add duration if available and meaningful
166
+ if (action.duration !== undefined && action.duration >= 0.1) {
167
+ parts.push(`${action.duration.toFixed(1)}ms`);
168
+ }
169
+
170
+ // Add diff summary - be more descriptive
171
+ if (action.hasStateChange) {
172
+ if (action.changedKeysCount && action.changedKeysCount > 0) {
173
+ parts.push(`${action.changedKeysCount} key${action.changedKeysCount > 1 ? 's' : ''} changed`);
174
+ } else {
175
+ parts.push(action.diffSummary || "state changed");
176
+ }
177
+ } else {
178
+ parts.push("no state change");
179
+ }
180
+ return parts.join(" · ");
181
+ }
182
+
183
+ /**
184
+ * Get action name badge text
185
+ */
186
+ function getActionBadge(action) {
187
+ // Show the action name in uppercase (e.g., ADDITEM, ORDERCOMPLETED)
188
+ return action.actionName?.toUpperCase() || action.type.split('/').pop()?.toUpperCase() || "";
189
+ }
190
+
191
+ /**
192
+ * Get primary text - use action name for cleaner display
193
+ */
194
+ function getPrimaryText(action) {
195
+ // For internal actions, show the full type
196
+ if (action.category === "internal") {
197
+ return action.type;
198
+ }
199
+
200
+ // For others, show slice/actionName format
201
+ if (action.sliceName) {
202
+ return `${action.sliceName}/${action.actionName.toLowerCase()}`;
203
+ }
204
+ return action.type;
205
+ }
206
+
207
+ // Memo justified by profiling (tool-bench 2026-07-06): ReduxActionItem
208
+ // x172 renders during a 5s idle dwell at 200 seeded actions. The relative
209
+ // timestamp is delegated to the shared <RelativeTime/> leaf so the 5s
210
+ // tick re-renders only that Text, not this row.
211
+ export const ReduxActionItem = /*#__PURE__*/memo(function ReduxActionItem({
212
+ action,
213
+ onPress,
214
+ linkedCount,
215
+ testID
216
+ }) {
217
+ const sliceName = action.sliceName ?? undefined;
218
+ const statusColor = getStatusColor(action.category, action.hasStateChange, sliceName);
219
+ const statusLabel = getStatusLabel(action.category, sliceName);
220
+ const sublabel = getSublabel(action);
221
+ const primaryText = getPrimaryText(action);
222
+ const actionBadge = getActionBadge(action);
223
+
224
+ // Check for linked async actions. The COUNT comes from the list (see the
225
+ // prop's doc); the ordered list is only needed to say where in the flow this
226
+ // action sits, and only when there is a flow at all.
227
+ const hasLinkedActions = (linkedCount ?? 0) > 1;
228
+ const linkedActions = hasLinkedActions ? reduxActionStore.getLinkedActions(action) : [];
229
+
230
+ // Get position in async sequence (1/2, 2/2, etc.)
231
+ const asyncPosition = hasLinkedActions ? linkedActions.findIndex(a => a.id === action.id) + 1 : 0;
232
+
233
+ // Get sequential operation index to distinguish concurrent requests (#1, #2, etc.)
234
+ const operationIndex = hasLinkedActions && action.meta?.requestId ? reduxActionStore.getAsyncOperationIndex(action.meta.requestId) : 0;
235
+
236
+ // Get color for this operation's badge
237
+ const opColor = getOperationColor(operationIndex);
238
+
239
+ // The async-sequence chip ("1/2 #3") sits in front of whatever indicator
240
+ // the row shows; the ⚡ / 🕒 indicators and the mono action verb are drawn
241
+ // by the shared ChangeRow.
242
+ const sequenceChip = hasLinkedActions ? /*#__PURE__*/_jsx(View, {
243
+ style: [styles.asyncSequenceBadge, {
244
+ backgroundColor: opColor.bg
245
+ }],
246
+ children: /*#__PURE__*/_jsxs(Text, {
247
+ style: [styles.asyncSequenceText, {
248
+ color: opColor.text
249
+ }],
250
+ testID: testID ? `${testID}-seq` : undefined,
251
+ children: [asyncPosition, "/", linkedCount, " #", operationIndex]
252
+ })
253
+ }) : undefined;
254
+ const common = {
255
+ statusColor,
256
+ statusLabel,
257
+ sublabel,
258
+ primaryText,
259
+ timestamp: action.timestamp,
260
+ onPress: () => onPress(action),
261
+ testID,
262
+ accessibilityLabel: `${primaryText}, ${statusLabel}, ${sublabel}`
263
+ };
264
+ if (action.isSlowAction) {
265
+ // Slow action warning (with the sequence chip when part of a flow).
266
+ return /*#__PURE__*/_jsx(ChangeRow, {
267
+ ...common,
268
+ badgePrefix: sequenceChip,
269
+ slow: true
270
+ });
271
+ }
272
+ if (action.category === "rejected") {
273
+ // Error badge for rejected actions.
274
+ return /*#__PURE__*/_jsx(ChangeRow, {
275
+ ...common,
276
+ customBadge: /*#__PURE__*/_jsxs(View, {
277
+ style: styles.badgeContainer,
278
+ children: [sequenceChip, /*#__PURE__*/_jsx(View, {
279
+ style: styles.errorBadge,
280
+ testID: testID ? `${testID}-error` : undefined,
281
+ children: /*#__PURE__*/_jsx(AlertCircle, {
282
+ size: 12,
283
+ color: buoyColors.error
284
+ })
285
+ })]
286
+ })
287
+ });
288
+ }
289
+ if (hasLinkedActions) {
290
+ // Linked indicator for async actions.
291
+ return /*#__PURE__*/_jsx(ChangeRow, {
292
+ ...common,
293
+ badgePrefix: sequenceChip,
294
+ changed: action.hasStateChange
295
+ });
296
+ }
297
+ if (action.hasStateChange) {
298
+ // State change indicator with the action verb.
299
+ return /*#__PURE__*/_jsx(ChangeRow, {
300
+ ...common,
301
+ badgeText: actionBadge,
302
+ changed: true
303
+ });
304
+ }
305
+ // Nothing special: CompactRow's plain badge with the action verb.
306
+ return /*#__PURE__*/_jsx(ChangeRow, {
307
+ ...common,
308
+ plainBadgeText: actionBadge
309
+ });
310
+ });
311
+ const styles = StyleSheet.create({
312
+ badgeContainer: {
313
+ flexDirection: "row",
314
+ alignItems: "center",
315
+ gap: 4
316
+ },
317
+ errorBadge: {
318
+ paddingHorizontal: 4
319
+ },
320
+ asyncSequenceBadge: {
321
+ paddingHorizontal: 6,
322
+ paddingVertical: 2,
323
+ borderRadius: 4
324
+ },
325
+ asyncSequenceText: {
326
+ fontSize: 10,
327
+ fontWeight: "600",
328
+ fontFamily: monoFont
329
+ }
330
+ });
@@ -1 +1,17 @@
1
- "use strict";import{useAutoInstrumentRedux}from"../hooks/useAutoInstrumentRedux";export function ReduxAutoInstrument(){return useAutoInstrumentRedux(),null}
1
+ "use strict";
2
+
3
+ import { useAutoInstrumentRedux } from "../hooks/useAutoInstrumentRedux";
4
+
5
+ /**
6
+ * Headless startup instrumentation. Auto-rendered by FloatingDevTools (same
7
+ * pattern as RouteTracker & the overlay tools) so the Redux store is bound
8
+ * from app mount — action log, MCP getState/dispatch, and desktop sync all
9
+ * work WITHOUT the user ever opening the Redux tool. Renders nothing.
10
+ *
11
+ * Safe anywhere: if react-redux is missing or there's no Provider above, the
12
+ * hook records the diagnostic and fails gracefully.
13
+ */
14
+ export function ReduxAutoInstrument() {
15
+ useAutoInstrumentRedux();
16
+ return null;
17
+ }
@@ -1 +1,45 @@
1
- "use strict";import React,{memo}from"react";import{DetailViewToggle,FileText,Database,GitBranch}from"@buoy-gg/shared-ui";import{jsx as _jsx}from"react/jsx-runtime";const VIEWS=[{key:"action",label:"ACTION",description:"View action details",icon:FileText},{key:"state",label:"STATE",description:"View current state",icon:Database},{key:"diff",label:"DIFF",description:"Compare changes",icon:GitBranch}],DIFF_DISABLED=["diff"];export const ReduxDetailViewToggle=memo(function({activeView:e,onViewChange:i,diffDisabled:t=!1}){return _jsx(DetailViewToggle,{views:VIEWS,activeView:e,onViewChange:i,disabledKeys:t?DIFF_DISABLED:void 0,testIDPrefix:"buoy-redux"})});
1
+ "use strict";
2
+
3
+ /**
4
+ * ReduxDetailViewToggle
5
+ *
6
+ * Three-card toggle for switching between Action, State, and Diff views.
7
+ * The cards themselves are the shared `DetailViewToggle`; this file owns
8
+ * the redux view list and testID prefix.
9
+ */
10
+
11
+ import React, { memo } from "react";
12
+ import { DetailViewToggle, FileText, Database, GitBranch } from "@buoy-gg/shared-ui";
13
+ import { jsx as _jsx } from "react/jsx-runtime";
14
+ // Active-card chrome takes the single night accent (the per-view
15
+ // warning/info/success tints were selection chrome, not data).
16
+ const VIEWS = [{
17
+ key: "action",
18
+ label: "ACTION",
19
+ description: "View action details",
20
+ icon: FileText
21
+ }, {
22
+ key: "state",
23
+ label: "STATE",
24
+ description: "View current state",
25
+ icon: Database
26
+ }, {
27
+ key: "diff",
28
+ label: "DIFF",
29
+ description: "Compare changes",
30
+ icon: GitBranch
31
+ }];
32
+ const DIFF_DISABLED = ["diff"];
33
+ export const ReduxDetailViewToggle = /*#__PURE__*/memo(function ReduxDetailViewToggle({
34
+ activeView,
35
+ onViewChange,
36
+ diffDisabled = false
37
+ }) {
38
+ return /*#__PURE__*/_jsx(DetailViewToggle, {
39
+ views: VIEWS,
40
+ activeView: activeView,
41
+ onViewChange: onViewChange,
42
+ disabledKeys: diffDisabled ? DIFF_DISABLED : undefined,
43
+ testIDPrefix: "buoy-redux"
44
+ });
45
+ });
@@ -1 +1,8 @@
1
- "use strict";export{ReduxIcon,REDUX_ICON_COLOR}from"@buoy-gg/floating-tools-core";
1
+ "use strict";
2
+
3
+ /**
4
+ * Redux DevTools icon
5
+ * Re-exports from floating-tools-core for consistency
6
+ */
7
+
8
+ export { ReduxIcon, REDUX_ICON_COLOR } from "@buoy-gg/floating-tools-core";