@buoy-gg/jotai 7.0.38 → 7.0.40
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 +112 -1
- package/lib/commonjs/jotai/components/JotaiAtomBrowser.js +199 -1
- package/lib/commonjs/jotai/components/JotaiAtomChangeItem.js +85 -1
- package/lib/commonjs/jotai/components/JotaiAtomDetailContent.js +715 -1
- package/lib/commonjs/jotai/components/JotaiAtomValueDetailContent.js +444 -1
- package/lib/commonjs/jotai/components/JotaiEventFilterView.js +43 -1
- package/lib/commonjs/jotai/components/JotaiIcon.js +18 -1
- package/lib/commonjs/jotai/components/JotaiModal.js +743 -1
- package/lib/commonjs/jotai/hooks/useJotaiAtomChanges.js +69 -1
- package/lib/commonjs/jotai/sync/jotaiSyncAdapter.js +306 -1
- package/lib/commonjs/jotai/utils/jotaiStateStore.js +321 -1
- package/lib/commonjs/jotai/utils/snapshotProvider.js +215 -1
- package/lib/commonjs/jotai/utils/testIDs.js +90 -1
- package/lib/commonjs/jotai/utils/watchAtoms.js +162 -1
- package/lib/commonjs/jotai/utils/writeSemantics.js +47 -1
- package/lib/commonjs/preset.js +90 -1
- package/lib/module/index.js +85 -1
- package/lib/module/jotai/components/JotaiAtomBrowser.js +195 -1
- package/lib/module/jotai/components/JotaiAtomChangeItem.js +81 -1
- package/lib/module/jotai/components/JotaiAtomDetailContent.js +710 -1
- package/lib/module/jotai/components/JotaiAtomValueDetailContent.js +442 -1
- package/lib/module/jotai/components/JotaiEventFilterView.js +39 -1
- package/lib/module/jotai/components/JotaiIcon.js +11 -1
- package/lib/module/jotai/components/JotaiModal.js +738 -1
- package/lib/module/jotai/hooks/useJotaiAtomChanges.js +65 -1
- package/lib/module/jotai/sync/jotaiSyncAdapter.js +303 -1
- package/lib/module/jotai/utils/jotaiStateStore.js +317 -1
- package/lib/module/jotai/utils/snapshotProvider.js +214 -1
- package/lib/module/jotai/utils/testIDs.js +82 -1
- package/lib/module/jotai/utils/watchAtoms.js +157 -1
- package/lib/module/jotai/utils/writeSemantics.js +43 -1
- package/lib/module/preset.js +87 -1
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/jotai/components/JotaiAtomBrowser.d.ts.map +1 -0
- package/lib/typescript/jotai/components/JotaiAtomChangeItem.d.ts.map +1 -0
- package/lib/typescript/jotai/components/JotaiAtomDetailContent.d.ts.map +1 -0
- package/lib/typescript/jotai/components/JotaiAtomValueDetailContent.d.ts.map +1 -0
- package/lib/typescript/jotai/components/JotaiEventFilterView.d.ts.map +1 -0
- package/lib/typescript/jotai/components/JotaiIcon.d.ts.map +1 -0
- package/lib/typescript/jotai/components/JotaiModal.d.ts.map +1 -0
- package/lib/typescript/jotai/hooks/useJotaiAtomChanges.d.ts.map +1 -0
- package/lib/typescript/jotai/sync/jotaiSyncAdapter.d.ts.map +1 -0
- package/lib/typescript/jotai/types/index.d.ts.map +1 -0
- package/lib/typescript/jotai/utils/jotaiStateStore.d.ts.map +1 -0
- package/lib/typescript/jotai/utils/snapshotProvider.d.ts.map +1 -0
- package/lib/typescript/jotai/utils/testIDs.d.ts.map +1 -0
- package/lib/typescript/jotai/utils/watchAtoms.d.ts.map +1 -0
- package/lib/typescript/jotai/utils/writeSemantics.d.ts.map +1 -0
- package/lib/typescript/preset.d.ts.map +1 -0
- package/package.json +3 -3
package/lib/commonjs/index.js
CHANGED
|
@@ -1 +1,112 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "JOTAI_ICON_COLOR", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _JotaiIcon.JOTAI_ICON_COLOR;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "JotaiAtomChangeItem", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _JotaiAtomChangeItem.JotaiAtomChangeItem;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "JotaiAtomDetailContent", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _JotaiAtomDetailContent.JotaiAtomDetailContent;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "JotaiAtomDetailFooter", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _JotaiAtomDetailContent.JotaiAtomDetailFooter;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(exports, "JotaiAtomValueDetailContent", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () {
|
|
33
|
+
return _JotaiAtomValueDetailContent.JotaiAtomValueDetailContent;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(exports, "JotaiIcon", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () {
|
|
39
|
+
return _JotaiIcon.JotaiIcon;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(exports, "JotaiModal", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function () {
|
|
45
|
+
return _JotaiModal.JotaiModal;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(exports, "JotaiToolView", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function () {
|
|
51
|
+
return _JotaiModal.JotaiToolView;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
Object.defineProperty(exports, "createJotaiTool", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function () {
|
|
57
|
+
return _preset.createJotaiTool;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
Object.defineProperty(exports, "isAtomWatched", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
get: function () {
|
|
63
|
+
return _watchAtoms.isAtomWatched;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
Object.defineProperty(exports, "jotaiStateStore", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
get: function () {
|
|
69
|
+
return _jotaiStateStore.jotaiStateStore;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
Object.defineProperty(exports, "jotaiSyncAdapter", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
get: function () {
|
|
75
|
+
return _jotaiSyncAdapter.jotaiSyncAdapter;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
Object.defineProperty(exports, "jotaiToolPreset", {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
get: function () {
|
|
81
|
+
return _preset.jotaiToolPreset;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
Object.defineProperty(exports, "useJotaiAtomChanges", {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
get: function () {
|
|
87
|
+
return _useJotaiAtomChanges.useJotaiAtomChanges;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
Object.defineProperty(exports, "watchAtoms", {
|
|
91
|
+
enumerable: true,
|
|
92
|
+
get: function () {
|
|
93
|
+
return _watchAtoms.watchAtoms;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
Object.defineProperty(exports, "watchDefaultStoreAtoms", {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
get: function () {
|
|
99
|
+
return _watchAtoms.watchDefaultStoreAtoms;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
require("./jotai/utils/snapshotProvider");
|
|
103
|
+
var _preset = require("./preset");
|
|
104
|
+
var _watchAtoms = require("./jotai/utils/watchAtoms");
|
|
105
|
+
var _useJotaiAtomChanges = require("./jotai/hooks/useJotaiAtomChanges");
|
|
106
|
+
var _JotaiModal = require("./jotai/components/JotaiModal");
|
|
107
|
+
var _JotaiAtomChangeItem = require("./jotai/components/JotaiAtomChangeItem");
|
|
108
|
+
var _JotaiAtomDetailContent = require("./jotai/components/JotaiAtomDetailContent");
|
|
109
|
+
var _JotaiAtomValueDetailContent = require("./jotai/components/JotaiAtomValueDetailContent");
|
|
110
|
+
var _JotaiIcon = require("./jotai/components/JotaiIcon");
|
|
111
|
+
var _jotaiSyncAdapter = require("./jotai/sync/jotaiSyncAdapter");
|
|
112
|
+
var _jotaiStateStore = require("./jotai/utils/jotaiStateStore");
|
|
@@ -1 +1,199 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.JotaiAtomBrowser = JotaiAtomBrowser;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
10
|
+
var _jotaiStateStore = require("../utils/jotaiStateStore");
|
|
11
|
+
var _testIDs = require("../utils/testIDs");
|
|
12
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
13
|
+
/**
|
|
14
|
+
* JotaiAtomBrowser
|
|
15
|
+
*
|
|
16
|
+
* Atoms tab — shows all registered Jotai atoms and their current value.
|
|
17
|
+
* Mirrors ZustandStoreBrowser.tsx from @buoy-gg/zustand: tapping a card
|
|
18
|
+
* NAVIGATES to the atom's detail screen (live editor + details + read-only
|
|
19
|
+
* tree) rather than expanding in place — the modal owns that selection.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
function getValuePreview(atom) {
|
|
23
|
+
try {
|
|
24
|
+
const value = atom.getValue();
|
|
25
|
+
if (value && typeof value === "object" && value.__buoyValueOnDevice === true) {
|
|
26
|
+
return "on device";
|
|
27
|
+
}
|
|
28
|
+
if (value === undefined) return "undefined";
|
|
29
|
+
if (value === null) return "null";
|
|
30
|
+
if (Array.isArray(value)) {
|
|
31
|
+
if (value.length === 0) return "[]";
|
|
32
|
+
return `[${value.length} item${value.length === 1 ? "" : "s"}]`;
|
|
33
|
+
}
|
|
34
|
+
if (typeof value === "object") {
|
|
35
|
+
const keys = Object.keys(value);
|
|
36
|
+
if (keys.length === 0) return "{}";
|
|
37
|
+
if (keys.length <= 3) return keys.join(", ");
|
|
38
|
+
return `${keys.slice(0, 2).join(", ")} +${keys.length - 2}`;
|
|
39
|
+
}
|
|
40
|
+
return String(value).slice(0, 40);
|
|
41
|
+
} catch {
|
|
42
|
+
return "";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The card's categorical slot — the atom's write story, mirroring the
|
|
48
|
+
* zustand card's "persisted"/"in-memory" backing label.
|
|
49
|
+
*/
|
|
50
|
+
function getWriteKindLabel(atom) {
|
|
51
|
+
if (atom.writeKind === "value") return "primitive";
|
|
52
|
+
if (atom.writeKind === "action") return "custom write";
|
|
53
|
+
return atom.setValue ? "writable" : "derived";
|
|
54
|
+
}
|
|
55
|
+
function EmptyBrowserState() {
|
|
56
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ToolEmptyState, {
|
|
57
|
+
testID: `${_testIDs.JOTAI_TEST_ID}-atoms-empty`
|
|
58
|
+
// scanning = "scanning for targets… and finding none". The registry is
|
|
59
|
+
// discovered, not configured, so an empty one is a scan result.
|
|
60
|
+
,
|
|
61
|
+
otto: "scanning",
|
|
62
|
+
title: "No atoms registered",
|
|
63
|
+
message: "Use watchAtoms(store, { atomName }) to register your Jotai atoms.\nThey will appear here with their current value."
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function JotaiAtomBrowser({
|
|
67
|
+
atoms,
|
|
68
|
+
searchQuery,
|
|
69
|
+
onOpenAtom
|
|
70
|
+
}) {
|
|
71
|
+
const filteredAtoms = (0, _react.useMemo)(() => {
|
|
72
|
+
if (!searchQuery) return atoms;
|
|
73
|
+
const search = searchQuery.toLowerCase();
|
|
74
|
+
return atoms.filter(a => a.label.toLowerCase().includes(search));
|
|
75
|
+
}, [atoms, searchQuery]);
|
|
76
|
+
if (filteredAtoms.length === 0 && !searchQuery) {
|
|
77
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(EmptyBrowserState, {});
|
|
78
|
+
}
|
|
79
|
+
if (filteredAtoms.length === 0 && searchQuery) {
|
|
80
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ToolEmptyState, {
|
|
81
|
+
testID: `${_testIDs.JOTAI_TEST_ID}-atoms-no-match`,
|
|
82
|
+
...(0, _sharedUi.resolveListEmptyState)({
|
|
83
|
+
subject: "atoms",
|
|
84
|
+
verb: "registered",
|
|
85
|
+
search: searchQuery,
|
|
86
|
+
total: atoms.length,
|
|
87
|
+
waiting: {
|
|
88
|
+
otto: "scanning",
|
|
89
|
+
title: "No atoms registered",
|
|
90
|
+
message: "Use watchAtoms() to register your Jotai atoms."
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
|
|
96
|
+
style: styles.container,
|
|
97
|
+
contentContainerStyle: styles.scrollContent,
|
|
98
|
+
showsVerticalScrollIndicator: true,
|
|
99
|
+
testID: `${_testIDs.JOTAI_TEST_ID}-atoms-scroll`,
|
|
100
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
101
|
+
style: styles.sectionHeader,
|
|
102
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
103
|
+
style: styles.sectionTitle,
|
|
104
|
+
children: "ATOMS"
|
|
105
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
106
|
+
style: styles.sectionCountBadge,
|
|
107
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
108
|
+
style: styles.sectionCountText,
|
|
109
|
+
testID: `${_testIDs.JOTAI_TEST_ID}-atoms-count`,
|
|
110
|
+
children: filteredAtoms.length
|
|
111
|
+
})
|
|
112
|
+
})]
|
|
113
|
+
}), filteredAtoms.map(atom => {
|
|
114
|
+
const valuePreview = getValuePreview(atom);
|
|
115
|
+
const atomColor = _jotaiStateStore.jotaiStateStore.getAtomColor(atom.label);
|
|
116
|
+
const rowID = (0, _testIDs.atomRowTestID)(atom.label);
|
|
117
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
118
|
+
style: styles.atomRowWrapper,
|
|
119
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CompactRow, {
|
|
120
|
+
statusDotColor: atomColor,
|
|
121
|
+
statusLabel: getWriteKindLabel(atom),
|
|
122
|
+
primaryText: atom.label,
|
|
123
|
+
secondaryText: valuePreview || undefined,
|
|
124
|
+
showChevron: true,
|
|
125
|
+
onPress: () => onOpenAtom(atom.label),
|
|
126
|
+
testID: rowID,
|
|
127
|
+
statusTestID: `${rowID}-kind`,
|
|
128
|
+
primaryTestID: `${rowID}-name`,
|
|
129
|
+
secondaryTestID: `${rowID}-preview`
|
|
130
|
+
}), atom.changeCount > 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
131
|
+
style: [styles.absCountBadge, {
|
|
132
|
+
backgroundColor: atomColor + "22",
|
|
133
|
+
borderColor: atomColor + "55"
|
|
134
|
+
}],
|
|
135
|
+
pointerEvents: "none",
|
|
136
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
137
|
+
style: [styles.absCountText, {
|
|
138
|
+
color: atomColor
|
|
139
|
+
}],
|
|
140
|
+
testID: `${rowID}-count`,
|
|
141
|
+
children: String(atom.changeCount)
|
|
142
|
+
})
|
|
143
|
+
})]
|
|
144
|
+
}, atom.label);
|
|
145
|
+
})]
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
const styles = _reactNative.StyleSheet.create({
|
|
149
|
+
container: {
|
|
150
|
+
flex: 1
|
|
151
|
+
},
|
|
152
|
+
atomRowWrapper: {
|
|
153
|
+
position: "relative"
|
|
154
|
+
},
|
|
155
|
+
absCountBadge: {
|
|
156
|
+
position: "absolute",
|
|
157
|
+
top: 4,
|
|
158
|
+
right: 10,
|
|
159
|
+
paddingHorizontal: 5,
|
|
160
|
+
paddingVertical: 1,
|
|
161
|
+
borderRadius: 4,
|
|
162
|
+
borderWidth: 1,
|
|
163
|
+
zIndex: 1
|
|
164
|
+
},
|
|
165
|
+
absCountText: {
|
|
166
|
+
fontSize: 9,
|
|
167
|
+
fontWeight: "700",
|
|
168
|
+
fontFamily: _sharedUi.monoFont
|
|
169
|
+
},
|
|
170
|
+
scrollContent: {
|
|
171
|
+
paddingTop: 8,
|
|
172
|
+
paddingBottom: 20
|
|
173
|
+
},
|
|
174
|
+
sectionHeader: {
|
|
175
|
+
flexDirection: "row",
|
|
176
|
+
alignItems: "center",
|
|
177
|
+
paddingHorizontal: 16,
|
|
178
|
+
paddingVertical: 8,
|
|
179
|
+
gap: 8
|
|
180
|
+
},
|
|
181
|
+
sectionTitle: {
|
|
182
|
+
fontSize: 11,
|
|
183
|
+
fontWeight: "700",
|
|
184
|
+
letterSpacing: 0.5,
|
|
185
|
+
color: _sharedUi.night.color.textTertiary
|
|
186
|
+
},
|
|
187
|
+
sectionCountBadge: {
|
|
188
|
+
backgroundColor: _sharedUi.night.color.accentFill,
|
|
189
|
+
paddingHorizontal: 8,
|
|
190
|
+
paddingVertical: 2,
|
|
191
|
+
borderRadius: 4
|
|
192
|
+
},
|
|
193
|
+
sectionCountText: {
|
|
194
|
+
fontSize: 10,
|
|
195
|
+
fontWeight: "700",
|
|
196
|
+
color: _sharedUi.night.color.accent,
|
|
197
|
+
fontFamily: _sharedUi.monoFont
|
|
198
|
+
}
|
|
199
|
+
});
|
|
@@ -1 +1,85 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.JotaiAtomChangeItem = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
9
|
+
var _jotaiStateStore = require("../utils/jotaiStateStore");
|
|
10
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
11
|
+
/**
|
|
12
|
+
* Compact list item for displaying a Jotai atom change
|
|
13
|
+
*
|
|
14
|
+
* Mirrors ZustandStateChangeItem.tsx — uses shared CompactRow for consistent styling
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
function getStatusLabel(category, atomLabel) {
|
|
18
|
+
if (category === "initial") return "Initial";
|
|
19
|
+
return atomLabel.charAt(0).toUpperCase() + atomLabel.slice(1);
|
|
20
|
+
}
|
|
21
|
+
function getCategoryColor(category, atomLabel) {
|
|
22
|
+
if (category === "initial") return _sharedUi.night.color.textTertiary;
|
|
23
|
+
return _jotaiStateStore.jotaiStateStore.getAtomColor(atomLabel);
|
|
24
|
+
}
|
|
25
|
+
function formatCompact(value, maxLen = 20) {
|
|
26
|
+
if (value === undefined) return "undefined";
|
|
27
|
+
if (value === null) return "null";
|
|
28
|
+
if (typeof value === "boolean") return String(value);
|
|
29
|
+
if (typeof value === "number") return String(value);
|
|
30
|
+
if (typeof value === "string") {
|
|
31
|
+
const truncated = value.length > maxLen ? value.slice(0, maxLen - 1) + "…" : value;
|
|
32
|
+
return `"${truncated}"`;
|
|
33
|
+
}
|
|
34
|
+
if (Array.isArray(value)) {
|
|
35
|
+
return value.length === 0 ? "[]" : `[${value.length} item${value.length === 1 ? "" : "s"}]`;
|
|
36
|
+
}
|
|
37
|
+
if (typeof value === "object") {
|
|
38
|
+
const keys = Object.keys(value);
|
|
39
|
+
if (keys.length === 0) return "{}";
|
|
40
|
+
return `{${keys.slice(0, 2).join(", ")}${keys.length > 2 ? "…" : ""}}`;
|
|
41
|
+
}
|
|
42
|
+
return String(value).slice(0, maxLen);
|
|
43
|
+
}
|
|
44
|
+
function getSublabel(change) {
|
|
45
|
+
if (!change.hasValueChange) return "no change";
|
|
46
|
+
return `${formatCompact(change.prevValue)} → ${formatCompact(change.nextValue)}`;
|
|
47
|
+
}
|
|
48
|
+
function getBadgeText(change) {
|
|
49
|
+
if (change.category === "initial") return "INIT";
|
|
50
|
+
return "WRITE";
|
|
51
|
+
}
|
|
52
|
+
function getPrimaryText(change) {
|
|
53
|
+
if (change.changedKeys.length > 0 && change.changedKeys.length <= 3) {
|
|
54
|
+
return change.changedKeys.join(", ");
|
|
55
|
+
}
|
|
56
|
+
if (change.changedKeys.length > 3) {
|
|
57
|
+
return `${change.changedKeys.slice(0, 2).join(", ")} +${change.changedKeys.length - 2}`;
|
|
58
|
+
}
|
|
59
|
+
return change.valuePreview || "atom()";
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Memo justified by profiling (tool-bench 2026-07-06) — see
|
|
63
|
+
// ZustandStateChangeItem (same pattern).
|
|
64
|
+
const JotaiAtomChangeItem = exports.JotaiAtomChangeItem = /*#__PURE__*/(0, _react.memo)(function JotaiAtomChangeItem({
|
|
65
|
+
change,
|
|
66
|
+
onPress,
|
|
67
|
+
testID
|
|
68
|
+
}) {
|
|
69
|
+
const statusColor = getCategoryColor(change.category, change.atomLabel);
|
|
70
|
+
const statusLabel = getStatusLabel(change.category, change.atomLabel);
|
|
71
|
+
const sublabel = getSublabel(change);
|
|
72
|
+
const primaryText = getPrimaryText(change);
|
|
73
|
+
const badgeText = getBadgeText(change);
|
|
74
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChangeRow, {
|
|
75
|
+
statusColor: statusColor,
|
|
76
|
+
statusLabel: statusLabel,
|
|
77
|
+
sublabel: sublabel,
|
|
78
|
+
primaryText: primaryText,
|
|
79
|
+
timestamp: change.timestamp,
|
|
80
|
+
badgeText: badgeText,
|
|
81
|
+
changed: change.hasValueChange,
|
|
82
|
+
onPress: () => onPress(change),
|
|
83
|
+
testID: testID
|
|
84
|
+
});
|
|
85
|
+
});
|