@buoy-gg/zustand 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.
- package/lib/commonjs/index.js +105 -1
- package/lib/commonjs/preset.js +102 -1
- package/lib/commonjs/zustand/components/ZustandActionButton.js +118 -1
- package/lib/commonjs/zustand/components/ZustandDetailViewToggle.js +48 -1
- package/lib/commonjs/zustand/components/ZustandEventFilterView.js +43 -1
- package/lib/commonjs/zustand/components/ZustandIcon.js +18 -1
- package/lib/commonjs/zustand/components/ZustandModal.js +772 -1
- package/lib/commonjs/zustand/components/ZustandStateChangeItem.js +117 -1
- package/lib/commonjs/zustand/components/ZustandStateDetailContent.js +372 -1
- package/lib/commonjs/zustand/components/ZustandStateInfoView.js +488 -1
- package/lib/commonjs/zustand/components/ZustandStoreBrowser.js +204 -1
- package/lib/commonjs/zustand/components/ZustandStoreDetailContent.js +471 -1
- package/lib/commonjs/zustand/components/ZustandStoreEditorScreen.js +393 -1
- package/lib/commonjs/zustand/hooks/useZustandStateChanges.js +74 -1
- package/lib/commonjs/zustand/sync/zustandSyncAdapter.js +382 -1
- package/lib/commonjs/zustand/utils/buoyZustandMiddleware.js +284 -1
- package/lib/commonjs/zustand/utils/editableState.js +146 -1
- package/lib/commonjs/zustand/utils/snapshotProvider.js +209 -1
- package/lib/commonjs/zustand/utils/testIDs.js +82 -1
- package/lib/commonjs/zustand/utils/zustandStateStore.js +379 -1
- package/lib/module/index.js +90 -1
- package/lib/module/preset.js +98 -1
- package/lib/module/zustand/components/ZustandActionButton.js +114 -1
- package/lib/module/zustand/components/ZustandDetailViewToggle.js +43 -1
- package/lib/module/zustand/components/ZustandEventFilterView.js +39 -1
- package/lib/module/zustand/components/ZustandIcon.js +11 -1
- package/lib/module/zustand/components/ZustandModal.js +767 -1
- package/lib/module/zustand/components/ZustandStateChangeItem.js +113 -1
- package/lib/module/zustand/components/ZustandStateDetailContent.js +368 -1
- package/lib/module/zustand/components/ZustandStateInfoView.js +483 -1
- package/lib/module/zustand/components/ZustandStoreBrowser.js +200 -1
- package/lib/module/zustand/components/ZustandStoreDetailContent.js +469 -1
- package/lib/module/zustand/components/ZustandStoreEditorScreen.js +389 -1
- package/lib/module/zustand/hooks/useZustandStateChanges.js +70 -1
- package/lib/module/zustand/sync/zustandSyncAdapter.js +380 -1
- package/lib/module/zustand/utils/buoyZustandMiddleware.js +278 -1
- package/lib/module/zustand/utils/editableState.js +138 -1
- package/lib/module/zustand/utils/snapshotProvider.js +209 -1
- package/lib/module/zustand/utils/testIDs.js +74 -1
- package/lib/module/zustand/utils/zustandStateStore.js +375 -1
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/preset.d.ts.map +1 -0
- package/lib/typescript/zustand/components/ZustandActionButton.d.ts.map +1 -0
- package/lib/typescript/zustand/components/ZustandDetailViewToggle.d.ts.map +1 -0
- package/lib/typescript/zustand/components/ZustandEventFilterView.d.ts.map +1 -0
- package/lib/typescript/zustand/components/ZustandIcon.d.ts.map +1 -0
- package/lib/typescript/zustand/components/ZustandModal.d.ts.map +1 -0
- package/lib/typescript/zustand/components/ZustandStateChangeItem.d.ts.map +1 -0
- package/lib/typescript/zustand/components/ZustandStateDetailContent.d.ts.map +1 -0
- package/lib/typescript/zustand/components/ZustandStateInfoView.d.ts.map +1 -0
- package/lib/typescript/zustand/components/ZustandStoreBrowser.d.ts.map +1 -0
- package/lib/typescript/zustand/components/ZustandStoreDetailContent.d.ts.map +1 -0
- package/lib/typescript/zustand/components/ZustandStoreEditorScreen.d.ts.map +1 -0
- package/lib/typescript/zustand/hooks/useZustandStateChanges.d.ts.map +1 -0
- package/lib/typescript/zustand/sync/zustandSyncAdapter.d.ts.map +1 -0
- package/lib/typescript/zustand/types/index.d.ts.map +1 -0
- package/lib/typescript/zustand/utils/buoyZustandMiddleware.d.ts.map +1 -0
- package/lib/typescript/zustand/utils/editableState.d.ts.map +1 -0
- package/lib/typescript/zustand/utils/snapshotProvider.d.ts.map +1 -0
- package/lib/typescript/zustand/utils/testIDs.d.ts.map +1 -0
- package/lib/typescript/zustand/utils/zustandStateStore.d.ts.map +1 -0
- package/package.json +3 -3
|
@@ -1 +1,117 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ZustandStateChangeItem = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
9
|
+
var _zustandStateStore = require("../utils/zustandStateStore");
|
|
10
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
11
|
+
/**
|
|
12
|
+
* Compact list item for displaying a Zustand state change
|
|
13
|
+
*
|
|
14
|
+
* Mirrors ReduxActionItem.tsx - uses shared CompactRow for consistent styling
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get status label based on category
|
|
19
|
+
*/
|
|
20
|
+
function getStatusLabel(category, storeName) {
|
|
21
|
+
switch (category) {
|
|
22
|
+
case "replace":
|
|
23
|
+
return "Replace";
|
|
24
|
+
case "persist":
|
|
25
|
+
return "Hydrate";
|
|
26
|
+
case "initial":
|
|
27
|
+
return "Initial";
|
|
28
|
+
default:
|
|
29
|
+
return storeName.charAt(0).toUpperCase() + storeName.slice(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get color for category
|
|
35
|
+
*/
|
|
36
|
+
function getCategoryColor(category, storeName) {
|
|
37
|
+
switch (category) {
|
|
38
|
+
case "replace":
|
|
39
|
+
return _sharedUi.buoyColors.warning;
|
|
40
|
+
case "persist":
|
|
41
|
+
return _sharedUi.buoyColors.info;
|
|
42
|
+
case "initial":
|
|
43
|
+
return _sharedUi.night.color.textTertiary;
|
|
44
|
+
default:
|
|
45
|
+
return _zustandStateStore.zustandStateStore.getStoreColor(storeName);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Get sublabel with duration and diff info
|
|
51
|
+
*/
|
|
52
|
+
function getSublabel(change) {
|
|
53
|
+
const parts = [];
|
|
54
|
+
if (change.duration !== undefined && change.duration >= 0.1) {
|
|
55
|
+
parts.push(`${change.duration.toFixed(1)}ms`);
|
|
56
|
+
}
|
|
57
|
+
if (change.hasStateChange) {
|
|
58
|
+
if (change.changedKeysCount > 0) {
|
|
59
|
+
parts.push(`${change.changedKeysCount} key${change.changedKeysCount > 1 ? "s" : ""} changed`);
|
|
60
|
+
} else {
|
|
61
|
+
parts.push(change.diffSummary || "state changed");
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
parts.push("no state change");
|
|
65
|
+
}
|
|
66
|
+
return parts.join(" \u00B7 ");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get badge text for the change
|
|
71
|
+
*/
|
|
72
|
+
function getBadgeText(change) {
|
|
73
|
+
if (change.category === "replace") return "REPLACE";
|
|
74
|
+
if (change.category === "persist") return "HYDRATE";
|
|
75
|
+
if (change.category === "initial") return "INIT";
|
|
76
|
+
return "SET";
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get primary display text
|
|
81
|
+
*/
|
|
82
|
+
function getPrimaryText(change) {
|
|
83
|
+
if (change.changedKeys.length > 0 && change.changedKeys.length <= 3) {
|
|
84
|
+
return change.changedKeys.join(", ");
|
|
85
|
+
}
|
|
86
|
+
if (change.changedKeys.length > 3) {
|
|
87
|
+
return `${change.changedKeys.slice(0, 2).join(", ")} +${change.changedKeys.length - 2}`;
|
|
88
|
+
}
|
|
89
|
+
return change.partialPreview || "setState()";
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Memo justified by profiling (tool-bench 2026-07-06): unmemoized, every
|
|
93
|
+
// visible row re-rendered on each store emission. Leaf w/ stable props
|
|
94
|
+
// ({change, onPress} — onPress is a stable useCallback in the modal).
|
|
95
|
+
const ZustandStateChangeItem = exports.ZustandStateChangeItem = /*#__PURE__*/(0, _react.memo)(function ZustandStateChangeItem({
|
|
96
|
+
change,
|
|
97
|
+
onPress,
|
|
98
|
+
testID
|
|
99
|
+
}) {
|
|
100
|
+
const statusColor = getCategoryColor(change.category, change.storeName);
|
|
101
|
+
const statusLabel = getStatusLabel(change.category, change.storeName);
|
|
102
|
+
const sublabel = getSublabel(change);
|
|
103
|
+
const primaryText = getPrimaryText(change);
|
|
104
|
+
const badgeText = getBadgeText(change);
|
|
105
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChangeRow, {
|
|
106
|
+
statusColor: statusColor,
|
|
107
|
+
statusLabel: statusLabel,
|
|
108
|
+
sublabel: sublabel,
|
|
109
|
+
primaryText: primaryText,
|
|
110
|
+
timestamp: change.timestamp,
|
|
111
|
+
badgeText: badgeText,
|
|
112
|
+
changed: change.hasStateChange,
|
|
113
|
+
slow: change.isSlowUpdate,
|
|
114
|
+
onPress: () => onPress(change),
|
|
115
|
+
testID: testID
|
|
116
|
+
});
|
|
117
|
+
});
|
|
@@ -1 +1,372 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ZustandStateDetailContent = ZustandStateDetailContent;
|
|
7
|
+
exports.ZustandStateDetailFooter = ZustandStateDetailFooter;
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _react = require("react");
|
|
10
|
+
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
11
|
+
var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
|
|
12
|
+
var _ZustandDetailViewToggle = require("./ZustandDetailViewToggle");
|
|
13
|
+
var _ZustandStateInfoView = require("./ZustandStateInfoView");
|
|
14
|
+
var _zustandStateStore = require("../utils/zustandStateStore");
|
|
15
|
+
var _testIDs = require("../utils/testIDs");
|
|
16
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
17
|
+
/**
|
|
18
|
+
* ZustandStateDetailContent
|
|
19
|
+
*
|
|
20
|
+
* Detail view for a Zustand state change with 3 view modes:
|
|
21
|
+
* - CHANGE: View change details, partial, metadata
|
|
22
|
+
* - STATE: View current state after change
|
|
23
|
+
* - DIFF: Compare prev vs next state
|
|
24
|
+
*
|
|
25
|
+
* Mirrors ReduxActionDetailContent.tsx
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
function getChangeColor(change) {
|
|
29
|
+
return _zustandStateStore.zustandStateStore.getStoreColor(change.storeName);
|
|
30
|
+
}
|
|
31
|
+
function getChangeLabel(change) {
|
|
32
|
+
switch (change.category) {
|
|
33
|
+
case "replace":
|
|
34
|
+
return "REPLACE";
|
|
35
|
+
case "persist":
|
|
36
|
+
return "HYDRATE";
|
|
37
|
+
case "initial":
|
|
38
|
+
return "INIT";
|
|
39
|
+
default:
|
|
40
|
+
return "SET";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function getValueType(value) {
|
|
44
|
+
if (value === null) return "null";
|
|
45
|
+
if (value === undefined) return "undefined";
|
|
46
|
+
if (Array.isArray(value)) return "array";
|
|
47
|
+
return typeof value;
|
|
48
|
+
}
|
|
49
|
+
function formatTimestamp(timestamp) {
|
|
50
|
+
const date = new Date(timestamp);
|
|
51
|
+
return date.toLocaleTimeString("en-US", {
|
|
52
|
+
hour12: false,
|
|
53
|
+
hour: "2-digit",
|
|
54
|
+
minute: "2-digit",
|
|
55
|
+
second: "2-digit"
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
const DIFF_MODE_TABS = [{
|
|
59
|
+
key: "tree",
|
|
60
|
+
label: "TREE VIEW"
|
|
61
|
+
}, {
|
|
62
|
+
key: "split",
|
|
63
|
+
label: "SPLIT VIEW"
|
|
64
|
+
}];
|
|
65
|
+
function ZustandStateDetailContent({
|
|
66
|
+
change,
|
|
67
|
+
changes,
|
|
68
|
+
selectedIndex,
|
|
69
|
+
onIndexChange,
|
|
70
|
+
disableInternalFooter = false,
|
|
71
|
+
initialView = "change"
|
|
72
|
+
}) {
|
|
73
|
+
const [activeView, setActiveView] = (0, _react.useState)(initialView);
|
|
74
|
+
const [diffMode, setDiffMode] = (0, _react.useState)("tree");
|
|
75
|
+
const totalChanges = changes.length;
|
|
76
|
+
const changeColor = getChangeColor(change);
|
|
77
|
+
const changeLabel = getChangeLabel(change);
|
|
78
|
+
const stateType = getValueType((0, _sharedUi.parseValue)(change.nextState));
|
|
79
|
+
|
|
80
|
+
// Changes are in reverse chronological order (newest first)
|
|
81
|
+
const chronologicalNumber = totalChanges - selectedIndex;
|
|
82
|
+
const prevChronologicalNumber = chronologicalNumber - 1;
|
|
83
|
+
const prevChangeIndex = selectedIndex < totalChanges - 1 ? selectedIndex + 1 : null;
|
|
84
|
+
const prevChange = prevChangeIndex !== null ? changes[prevChangeIndex] : null;
|
|
85
|
+
|
|
86
|
+
// Compare bar info
|
|
87
|
+
const leftEvent = (0, _react.useMemo)(() => ({
|
|
88
|
+
index: prevChangeIndex ?? 0,
|
|
89
|
+
label: prevChronologicalNumber > 0 ? `#${prevChronologicalNumber}` : "Initial",
|
|
90
|
+
timestamp: prevChange ? formatTimestamp(prevChange.timestamp) : "",
|
|
91
|
+
relativeTime: prevChange ? (0, _sharedUi.formatRelativeTime)(new Date(prevChange.timestamp)) : "state",
|
|
92
|
+
badge: prevChange ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
93
|
+
style: [styles.changeBadgeSmall, {
|
|
94
|
+
backgroundColor: `${getChangeColor(prevChange)}20`
|
|
95
|
+
}],
|
|
96
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
97
|
+
style: [styles.changeTextSmall, {
|
|
98
|
+
color: getChangeColor(prevChange)
|
|
99
|
+
}],
|
|
100
|
+
children: getChangeLabel(prevChange)
|
|
101
|
+
})
|
|
102
|
+
}) : undefined
|
|
103
|
+
}), [prevChangeIndex, prevChange, prevChronologicalNumber]);
|
|
104
|
+
const rightEvent = (0, _react.useMemo)(() => ({
|
|
105
|
+
index: selectedIndex,
|
|
106
|
+
label: `#${chronologicalNumber}`,
|
|
107
|
+
timestamp: formatTimestamp(change.timestamp),
|
|
108
|
+
relativeTime: (0, _sharedUi.formatRelativeTime)(new Date(change.timestamp)),
|
|
109
|
+
badge: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
110
|
+
style: [styles.changeBadgeSmall, {
|
|
111
|
+
backgroundColor: `${changeColor}20`
|
|
112
|
+
}],
|
|
113
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
114
|
+
style: [styles.changeTextSmall, {
|
|
115
|
+
color: changeColor
|
|
116
|
+
}],
|
|
117
|
+
children: changeLabel
|
|
118
|
+
})
|
|
119
|
+
})
|
|
120
|
+
}), [selectedIndex, change.timestamp, changeColor, changeLabel, chronologicalNumber]);
|
|
121
|
+
const renderStateView = (0, _react.useCallback)(() => {
|
|
122
|
+
const parsed = (0, _sharedUi.parseValue)(change.nextState);
|
|
123
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
124
|
+
style: styles.contentCard,
|
|
125
|
+
testID: `${_testIDs.ZUSTAND_TEST_ID}-state-card`,
|
|
126
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
127
|
+
style: styles.valueHeader,
|
|
128
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
129
|
+
style: styles.valueLabel,
|
|
130
|
+
children: "STATE AFTER CHANGE"
|
|
131
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
132
|
+
style: styles.valueHeaderBadges,
|
|
133
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
134
|
+
style: [styles.changeBadge, {
|
|
135
|
+
backgroundColor: `${changeColor}20`
|
|
136
|
+
}],
|
|
137
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
138
|
+
style: [styles.changeText, {
|
|
139
|
+
color: changeColor
|
|
140
|
+
}],
|
|
141
|
+
children: changeLabel
|
|
142
|
+
})
|
|
143
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
144
|
+
style: styles.typeBadge,
|
|
145
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
146
|
+
style: styles.typeText,
|
|
147
|
+
testID: `${_testIDs.ZUSTAND_TEST_ID}-state-type`,
|
|
148
|
+
children: stateType.toUpperCase()
|
|
149
|
+
})
|
|
150
|
+
})]
|
|
151
|
+
})]
|
|
152
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
153
|
+
style: styles.dataViewerContainer,
|
|
154
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.DataViewer, {
|
|
155
|
+
title: "",
|
|
156
|
+
data: parsed,
|
|
157
|
+
showTypeFilter: true,
|
|
158
|
+
rawMode: true,
|
|
159
|
+
initialExpanded: true
|
|
160
|
+
})
|
|
161
|
+
})]
|
|
162
|
+
});
|
|
163
|
+
}, [change.nextState, changeColor, changeLabel, stateType]);
|
|
164
|
+
const renderDiffContent = (0, _react.useCallback)(() => {
|
|
165
|
+
const prevState = (0, _sharedUi.parseValue)(change.prevState);
|
|
166
|
+
const nextState = (0, _sharedUi.parseValue)(change.nextState);
|
|
167
|
+
if (diffMode === "split") {
|
|
168
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
|
|
169
|
+
style: {
|
|
170
|
+
flex: 1
|
|
171
|
+
},
|
|
172
|
+
showsVerticalScrollIndicator: true,
|
|
173
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.SplitDiffViewer, {
|
|
174
|
+
oldValue: prevState,
|
|
175
|
+
newValue: nextState,
|
|
176
|
+
theme: _dataViewer.diffThemes.devToolsDefault,
|
|
177
|
+
options: {
|
|
178
|
+
hideLineNumbers: false,
|
|
179
|
+
disableWordDiff: false,
|
|
180
|
+
showDiffOnly: false,
|
|
181
|
+
compareMethod: "words",
|
|
182
|
+
contextLines: 3
|
|
183
|
+
},
|
|
184
|
+
showThemeName: false
|
|
185
|
+
})
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.TreeDiffViewer, {
|
|
189
|
+
oldValue: prevState,
|
|
190
|
+
newValue: nextState
|
|
191
|
+
});
|
|
192
|
+
}, [change.prevState, change.nextState, diffMode]);
|
|
193
|
+
const handleFooterPrevious = (0, _react.useCallback)(() => {
|
|
194
|
+
onIndexChange(Math.min(totalChanges - 1, selectedIndex + 1));
|
|
195
|
+
}, [selectedIndex, totalChanges, onIndexChange]);
|
|
196
|
+
const handleFooterNext = (0, _react.useCallback)(() => {
|
|
197
|
+
onIndexChange(Math.max(0, selectedIndex - 1));
|
|
198
|
+
}, [selectedIndex, onIndexChange]);
|
|
199
|
+
|
|
200
|
+
// The diff compares THIS change's prevState/nextState — both live on the
|
|
201
|
+
// change itself, so it needs no siblings. Gating on `changes.length` greyed
|
|
202
|
+
// DIFF out for every zustand event opened from the Events timeline, which
|
|
203
|
+
// hands this component a one-element array. Only a change with no captured
|
|
204
|
+
// previous state (initial creation) has nothing to compare.
|
|
205
|
+
const diffDisabled = change.prevState === undefined;
|
|
206
|
+
const showInternalFooter = !disableInternalFooter && totalChanges > 1;
|
|
207
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
208
|
+
style: styles.container,
|
|
209
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ZustandDetailViewToggle.ZustandDetailViewToggle, {
|
|
210
|
+
activeView: activeView,
|
|
211
|
+
onViewChange: setActiveView,
|
|
212
|
+
diffDisabled: diffDisabled
|
|
213
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
214
|
+
style: [styles.contentArea, showInternalFooter && styles.contentAreaFooterPad],
|
|
215
|
+
children: [activeView === "change" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_ZustandStateInfoView.ZustandStateInfoView, {
|
|
216
|
+
change: change
|
|
217
|
+
}), activeView === "state" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
218
|
+
style: styles.stateContainer,
|
|
219
|
+
children: renderStateView()
|
|
220
|
+
}), activeView === "diff" && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
221
|
+
style: styles.diffContainer,
|
|
222
|
+
testID: `${_testIDs.ZUSTAND_TEST_ID}-diff`,
|
|
223
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.DiffModeTabs, {
|
|
224
|
+
tabs: DIFF_MODE_TABS,
|
|
225
|
+
activeTab: diffMode,
|
|
226
|
+
onTabChange: setDiffMode,
|
|
227
|
+
testIDPrefix: `${_testIDs.ZUSTAND_TEST_ID}-diff-tab`
|
|
228
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CompareBar, {
|
|
229
|
+
leftEvent: leftEvent,
|
|
230
|
+
rightEvent: rightEvent
|
|
231
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
232
|
+
style: styles.diffContent,
|
|
233
|
+
testID: `${_testIDs.ZUSTAND_TEST_ID}-diff-content`,
|
|
234
|
+
children: renderDiffContent()
|
|
235
|
+
})]
|
|
236
|
+
})]
|
|
237
|
+
}), showInternalFooter && /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.EventStepperFooter, {
|
|
238
|
+
currentIndex: chronologicalNumber - 1,
|
|
239
|
+
totalItems: totalChanges,
|
|
240
|
+
onPrevious: handleFooterPrevious,
|
|
241
|
+
onNext: handleFooterNext,
|
|
242
|
+
itemLabel: "Change",
|
|
243
|
+
subtitle: (0, _sharedUi.formatRelativeTime)(new Date(change.timestamp)),
|
|
244
|
+
absolute: true
|
|
245
|
+
})]
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* External footer component for modal use
|
|
251
|
+
*/
|
|
252
|
+
function ZustandStateDetailFooter({
|
|
253
|
+
change,
|
|
254
|
+
changes,
|
|
255
|
+
selectedIndex,
|
|
256
|
+
onIndexChange
|
|
257
|
+
}) {
|
|
258
|
+
const totalChanges = changes.length;
|
|
259
|
+
if (totalChanges <= 1) return null;
|
|
260
|
+
const chronologicalNumber = totalChanges - selectedIndex;
|
|
261
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.EventStepperFooter, {
|
|
262
|
+
currentIndex: chronologicalNumber - 1,
|
|
263
|
+
totalItems: totalChanges,
|
|
264
|
+
onPrevious: () => onIndexChange(Math.min(totalChanges - 1, selectedIndex + 1)),
|
|
265
|
+
onNext: () => onIndexChange(Math.max(0, selectedIndex - 1)),
|
|
266
|
+
itemLabel: "Change",
|
|
267
|
+
subtitle: (0, _sharedUi.formatRelativeTime)(new Date(change.timestamp))
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
const styles = _reactNative.StyleSheet.create({
|
|
271
|
+
container: {
|
|
272
|
+
flex: 1,
|
|
273
|
+
// Transparent so the night sheet's star field shows through.
|
|
274
|
+
backgroundColor: "transparent"
|
|
275
|
+
},
|
|
276
|
+
contentArea: {
|
|
277
|
+
flex: 1
|
|
278
|
+
},
|
|
279
|
+
// Clearance for the absolute EventStepperFooter — only when it renders,
|
|
280
|
+
// otherwise hosts like the Events tool get a dead band at the sheet bottom.
|
|
281
|
+
contentAreaFooterPad: {
|
|
282
|
+
paddingBottom: 96
|
|
283
|
+
},
|
|
284
|
+
stateContainer: {
|
|
285
|
+
flex: 1,
|
|
286
|
+
padding: 14
|
|
287
|
+
},
|
|
288
|
+
contentCard: {
|
|
289
|
+
backgroundColor: _sharedUi.night.color.surface,
|
|
290
|
+
borderRadius: 14,
|
|
291
|
+
padding: 14,
|
|
292
|
+
borderWidth: 1,
|
|
293
|
+
borderColor: _sharedUi.night.color.border
|
|
294
|
+
},
|
|
295
|
+
valueHeader: {
|
|
296
|
+
flexDirection: "row",
|
|
297
|
+
alignItems: "center",
|
|
298
|
+
justifyContent: "space-between",
|
|
299
|
+
marginBottom: 8
|
|
300
|
+
},
|
|
301
|
+
valueLabel: {
|
|
302
|
+
fontSize: 10,
|
|
303
|
+
color: _sharedUi.night.color.textSecondary,
|
|
304
|
+
fontFamily: _sharedUi.monoFont,
|
|
305
|
+
letterSpacing: 0.5,
|
|
306
|
+
fontWeight: "600"
|
|
307
|
+
},
|
|
308
|
+
valueHeaderBadges: {
|
|
309
|
+
flexDirection: "row",
|
|
310
|
+
alignItems: "center",
|
|
311
|
+
gap: 6
|
|
312
|
+
},
|
|
313
|
+
changeBadge: {
|
|
314
|
+
paddingHorizontal: 8,
|
|
315
|
+
paddingVertical: 2,
|
|
316
|
+
borderRadius: 4
|
|
317
|
+
},
|
|
318
|
+
changeText: {
|
|
319
|
+
fontSize: 9,
|
|
320
|
+
fontWeight: "700",
|
|
321
|
+
fontFamily: _sharedUi.monoFont,
|
|
322
|
+
letterSpacing: 0.3
|
|
323
|
+
},
|
|
324
|
+
typeBadge: {
|
|
325
|
+
paddingHorizontal: 8,
|
|
326
|
+
paddingVertical: 2,
|
|
327
|
+
borderRadius: 4,
|
|
328
|
+
backgroundColor: _sharedUi.night.color.surfaceElevated
|
|
329
|
+
},
|
|
330
|
+
typeText: {
|
|
331
|
+
fontSize: 9,
|
|
332
|
+
fontWeight: "600",
|
|
333
|
+
color: _sharedUi.night.color.textTertiary,
|
|
334
|
+
fontFamily: _sharedUi.monoFont
|
|
335
|
+
},
|
|
336
|
+
valueBox: {
|
|
337
|
+
// Inset code box — darker than the card, the night track color.
|
|
338
|
+
backgroundColor: _sharedUi.night.color.bg,
|
|
339
|
+
borderRadius: 6,
|
|
340
|
+
borderWidth: 1,
|
|
341
|
+
borderColor: _sharedUi.night.color.border,
|
|
342
|
+
padding: 8
|
|
343
|
+
},
|
|
344
|
+
valueText: {
|
|
345
|
+
fontSize: 12,
|
|
346
|
+
color: _sharedUi.night.color.text,
|
|
347
|
+
fontFamily: _sharedUi.monoFont,
|
|
348
|
+
lineHeight: 18
|
|
349
|
+
},
|
|
350
|
+
diffContainer: {
|
|
351
|
+
flex: 1
|
|
352
|
+
},
|
|
353
|
+
diffContent: {
|
|
354
|
+
flex: 1,
|
|
355
|
+
paddingHorizontal: 14
|
|
356
|
+
},
|
|
357
|
+
changeBadgeSmall: {
|
|
358
|
+
paddingHorizontal: 6,
|
|
359
|
+
paddingVertical: 1,
|
|
360
|
+
borderRadius: 3
|
|
361
|
+
},
|
|
362
|
+
changeTextSmall: {
|
|
363
|
+
fontSize: 8,
|
|
364
|
+
fontWeight: "700",
|
|
365
|
+
fontFamily: _sharedUi.monoFont
|
|
366
|
+
},
|
|
367
|
+
dataViewerContainer: {
|
|
368
|
+
marginTop: -12,
|
|
369
|
+
marginHorizontal: -12,
|
|
370
|
+
marginBottom: -12
|
|
371
|
+
}
|
|
372
|
+
});
|