@buoy-gg/jotai 7.0.33 → 7.0.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/jotai/components/JotaiAtomChangeItem.js +7 -52
- package/lib/commonjs/jotai/components/JotaiAtomDetailContent.js +8 -87
- package/lib/commonjs/jotai/components/JotaiEventFilterView.js +21 -299
- package/lib/commonjs/jotai/components/JotaiModal.js +20 -85
- package/lib/commonjs/jotai/hooks/useJotaiAtomChanges.js +33 -49
- package/lib/commonjs/jotai/sync/jotaiSyncAdapter.js +19 -66
- package/lib/commonjs/jotai/utils/jotaiStateStore.js +23 -188
- package/lib/commonjs/jotai/utils/snapshotProvider.js +7 -25
- package/lib/commonjs/preset.js +14 -22
- package/lib/module/jotai/components/JotaiAtomChangeItem.js +9 -54
- package/lib/module/jotai/components/JotaiAtomDetailContent.js +9 -88
- package/lib/module/jotai/components/JotaiEventFilterView.js +24 -302
- package/lib/module/jotai/components/JotaiModal.js +22 -87
- package/lib/module/jotai/hooks/useJotaiAtomChanges.js +34 -50
- package/lib/module/jotai/sync/jotaiSyncAdapter.js +20 -67
- package/lib/module/jotai/utils/jotaiStateStore.js +23 -188
- package/lib/module/jotai/utils/snapshotProvider.js +8 -26
- package/lib/module/preset.js +13 -20
- package/lib/typescript/jotai/components/JotaiAtomChangeItem.d.ts.map +1 -1
- package/lib/typescript/jotai/components/JotaiAtomDetailContent.d.ts.map +1 -1
- package/lib/typescript/jotai/components/JotaiEventFilterView.d.ts +2 -2
- package/lib/typescript/jotai/components/JotaiEventFilterView.d.ts.map +1 -1
- package/lib/typescript/jotai/components/JotaiModal.d.ts.map +1 -1
- package/lib/typescript/jotai/hooks/useJotaiAtomChanges.d.ts +2 -1
- package/lib/typescript/jotai/hooks/useJotaiAtomChanges.d.ts.map +1 -1
- package/lib/typescript/jotai/sync/jotaiSyncAdapter.d.ts +54 -68
- package/lib/typescript/jotai/sync/jotaiSyncAdapter.d.ts.map +1 -1
- package/lib/typescript/jotai/utils/jotaiStateStore.d.ts +2 -25
- package/lib/typescript/jotai/utils/jotaiStateStore.d.ts.map +1 -1
- package/lib/typescript/preset.d.ts +2 -8
- package/lib/typescript/preset.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.JotaiAtomChangeItem = void 0;
|
|
7
7
|
var _react = require("react");
|
|
8
|
-
var _reactNative = require("react-native");
|
|
9
8
|
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
10
9
|
var _jotaiStateStore = require("../utils/jotaiStateStore");
|
|
11
10
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
@@ -72,59 +71,15 @@ const JotaiAtomChangeItem = exports.JotaiAtomChangeItem = /*#__PURE__*/(0, _reac
|
|
|
72
71
|
const sublabel = getSublabel(change);
|
|
73
72
|
const primaryText = getPrimaryText(change);
|
|
74
73
|
const badgeText = getBadgeText(change);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
// alternative — letting CompactRow draw `badgeText` itself — leaves the one
|
|
78
|
-
// row whose badge matters most (a write that moved the atom's identity but
|
|
79
|
-
// none of its contents) as the only row in the list with no handle on its
|
|
80
|
-
// badge. Same call, and the same reason, as ZustandStateChangeItem.
|
|
81
|
-
const customBadge = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
82
|
-
style: styles.badgeContainer,
|
|
83
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
84
|
-
style: [styles.badgeText, {
|
|
85
|
-
color: statusColor
|
|
86
|
-
}],
|
|
87
|
-
testID: testID ? `${testID}-badge` : undefined,
|
|
88
|
-
children: badgeText
|
|
89
|
-
}), change.hasValueChange ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
90
|
-
style: styles.changeBadge,
|
|
91
|
-
testID: testID ? `${testID}-change` : undefined,
|
|
92
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Zap, {
|
|
93
|
-
size: 12,
|
|
94
|
-
color: _sharedUi.buoyColors.warning
|
|
95
|
-
})
|
|
96
|
-
}) : null]
|
|
97
|
-
});
|
|
98
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CompactRow, {
|
|
99
|
-
statusDotColor: statusColor,
|
|
74
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChangeRow, {
|
|
75
|
+
statusColor: statusColor,
|
|
100
76
|
statusLabel: statusLabel,
|
|
101
|
-
|
|
77
|
+
sublabel: sublabel,
|
|
102
78
|
primaryText: primaryText,
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
customBadge: customBadge,
|
|
107
|
-
badgeColor: statusColor,
|
|
108
|
-
showChevron: true,
|
|
79
|
+
timestamp: change.timestamp,
|
|
80
|
+
badgeText: badgeText,
|
|
81
|
+
changed: change.hasValueChange,
|
|
109
82
|
onPress: () => onPress(change),
|
|
110
|
-
testID: testID
|
|
111
|
-
statusTestID: testID ? `${testID}-status` : undefined,
|
|
112
|
-
statusSublabelTestID: testID ? `${testID}-sublabel` : undefined,
|
|
113
|
-
primaryTestID: testID ? `${testID}-keys` : undefined
|
|
83
|
+
testID: testID
|
|
114
84
|
});
|
|
115
|
-
});
|
|
116
|
-
const styles = _reactNative.StyleSheet.create({
|
|
117
|
-
badgeContainer: {
|
|
118
|
-
flexDirection: "row",
|
|
119
|
-
alignItems: "center",
|
|
120
|
-
gap: 4
|
|
121
|
-
},
|
|
122
|
-
badgeText: {
|
|
123
|
-
fontSize: 11,
|
|
124
|
-
fontWeight: "600",
|
|
125
|
-
fontFamily: "monospace"
|
|
126
|
-
},
|
|
127
|
-
changeBadge: {
|
|
128
|
-
paddingHorizontal: 4
|
|
129
|
-
}
|
|
130
85
|
});
|
|
@@ -29,61 +29,17 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
|
|
|
29
29
|
const VIEW_CONFIGS = [{
|
|
30
30
|
key: "change",
|
|
31
31
|
label: "CHANGE",
|
|
32
|
-
icon: _sharedUi.FileText
|
|
33
|
-
activeColor: _sharedUi.night.color.accent
|
|
32
|
+
icon: _sharedUi.FileText
|
|
34
33
|
}, {
|
|
35
34
|
key: "value",
|
|
36
35
|
label: "VALUE",
|
|
37
|
-
icon: _sharedUi.Database
|
|
38
|
-
activeColor: _sharedUi.night.color.accent
|
|
36
|
+
icon: _sharedUi.Database
|
|
39
37
|
}, {
|
|
40
38
|
key: "diff",
|
|
41
39
|
label: "DIFF",
|
|
42
|
-
icon: _sharedUi.GitBranch
|
|
43
|
-
activeColor: _sharedUi.night.color.accent
|
|
40
|
+
icon: _sharedUi.GitBranch
|
|
44
41
|
}];
|
|
45
|
-
|
|
46
|
-
activeView,
|
|
47
|
-
onViewChange,
|
|
48
|
-
diffDisabled
|
|
49
|
-
}) {
|
|
50
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
51
|
-
style: toggleStyles.container,
|
|
52
|
-
children: VIEW_CONFIGS.map(config => {
|
|
53
|
-
const isActive = activeView === config.key;
|
|
54
|
-
const isDisabled = config.key === "diff" && diffDisabled;
|
|
55
|
-
const IconComponent = config.icon;
|
|
56
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
57
|
-
style: [toggleStyles.card, isActive && [toggleStyles.cardActive, {
|
|
58
|
-
borderColor: config.activeColor
|
|
59
|
-
}], isDisabled && toggleStyles.cardDisabled],
|
|
60
|
-
onPress: () => !isDisabled && onViewChange(config.key),
|
|
61
|
-
activeOpacity: 0.7,
|
|
62
|
-
testID: `${_testIDs.JOTAI_TEST_ID}-view-${config.key}`,
|
|
63
|
-
accessibilityRole: "button",
|
|
64
|
-
accessibilityLabel: config.label,
|
|
65
|
-
accessibilityState: {
|
|
66
|
-
disabled: isDisabled,
|
|
67
|
-
selected: isActive
|
|
68
|
-
},
|
|
69
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
70
|
-
style: toggleStyles.cardContent,
|
|
71
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(IconComponent, {
|
|
72
|
-
size: 14,
|
|
73
|
-
color: isActive ? config.activeColor : isDisabled ? _sharedUi.night.color.textTertiary : _sharedUi.night.color.textSecondary
|
|
74
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
75
|
-
style: [toggleStyles.cardLabel, isActive && {
|
|
76
|
-
color: config.activeColor
|
|
77
|
-
}, isDisabled && {
|
|
78
|
-
color: _sharedUi.night.color.textTertiary
|
|
79
|
-
}],
|
|
80
|
-
children: config.label
|
|
81
|
-
})]
|
|
82
|
-
})
|
|
83
|
-
}, config.key);
|
|
84
|
-
})
|
|
85
|
-
});
|
|
86
|
-
}
|
|
42
|
+
const DIFF_DISABLED = ["diff"];
|
|
87
43
|
|
|
88
44
|
// ---- Helpers ----
|
|
89
45
|
|
|
@@ -432,10 +388,12 @@ function JotaiAtomDetailContent({
|
|
|
432
388
|
const showInternalFooter = !disableInternalFooter && totalChanges > 1;
|
|
433
389
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
434
390
|
style: styles.container,
|
|
435
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(DetailViewToggle, {
|
|
391
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.DetailViewToggle, {
|
|
392
|
+
views: VIEW_CONFIGS,
|
|
436
393
|
activeView: activeView,
|
|
437
394
|
onViewChange: setActiveView,
|
|
438
|
-
diffDisabled:
|
|
395
|
+
disabledKeys: diffDisabled ? DIFF_DISABLED : undefined,
|
|
396
|
+
testIDPrefix: _testIDs.JOTAI_TEST_ID
|
|
439
397
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
440
398
|
style: [styles.contentArea, showInternalFooter && styles.contentAreaFooterPad],
|
|
441
399
|
children: [activeView === "change" && /*#__PURE__*/(0, _jsxRuntime.jsx)(JotaiAtomInfoView, {
|
|
@@ -587,43 +545,6 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
587
545
|
fontFamily: "monospace"
|
|
588
546
|
}
|
|
589
547
|
});
|
|
590
|
-
const toggleStyles = _reactNative.StyleSheet.create({
|
|
591
|
-
container: {
|
|
592
|
-
flexDirection: "row",
|
|
593
|
-
gap: 8,
|
|
594
|
-
padding: 14,
|
|
595
|
-
// Transparent so the night sheet's star field shows through.
|
|
596
|
-
backgroundColor: "transparent"
|
|
597
|
-
},
|
|
598
|
-
card: {
|
|
599
|
-
flex: 1,
|
|
600
|
-
backgroundColor: _sharedUi.night.color.surface,
|
|
601
|
-
borderRadius: 12,
|
|
602
|
-
borderWidth: 1,
|
|
603
|
-
borderColor: _sharedUi.night.color.border,
|
|
604
|
-
paddingVertical: 10,
|
|
605
|
-
paddingHorizontal: 10,
|
|
606
|
-
justifyContent: "center"
|
|
607
|
-
},
|
|
608
|
-
cardActive: {
|
|
609
|
-
borderWidth: 1.5,
|
|
610
|
-
backgroundColor: _sharedUi.night.color.accentSoft
|
|
611
|
-
},
|
|
612
|
-
cardDisabled: {
|
|
613
|
-
opacity: 0.5
|
|
614
|
-
},
|
|
615
|
-
cardContent: {
|
|
616
|
-
flexDirection: "row",
|
|
617
|
-
alignItems: "center",
|
|
618
|
-
gap: 6
|
|
619
|
-
},
|
|
620
|
-
cardLabel: {
|
|
621
|
-
fontSize: 10,
|
|
622
|
-
fontWeight: "700",
|
|
623
|
-
letterSpacing: 0.5,
|
|
624
|
-
color: _sharedUi.night.color.textSecondary
|
|
625
|
-
}
|
|
626
|
-
});
|
|
627
548
|
const infoStyles = _reactNative.StyleSheet.create({
|
|
628
549
|
container: {
|
|
629
550
|
flex: 1
|
|
@@ -5,317 +5,39 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.JotaiEventFilterView = JotaiEventFilterView;
|
|
7
7
|
var _react = require("react");
|
|
8
|
-
var _reactNative = require("react-native");
|
|
9
8
|
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
10
|
-
var _jotaiStateStore = require("../utils/jotaiStateStore");
|
|
11
9
|
var _testIDs = require("../utils/testIDs");
|
|
12
10
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
13
11
|
/**
|
|
14
12
|
* JotaiEventFilterView
|
|
15
13
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* The shared `EntityFilterView` with jotai's nouns: watched atoms you can
|
|
15
|
+
* tap to hide, active atom-name patterns, and how it works.
|
|
18
16
|
*/
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
const match = atoms.find(a => a.label.toLowerCase().includes(pattern.toLowerCase()));
|
|
22
|
-
return match ? match.color : null;
|
|
23
|
-
}
|
|
18
|
+
const EXAMPLES = ["• count -> hides countAtom from atoms & events", "• auth -> hides authAtom, authStatusAtom", "• user -> hides userAtom from both tabs"];
|
|
24
19
|
function JotaiEventFilterView({
|
|
25
20
|
ignoredPatterns,
|
|
26
21
|
onTogglePattern,
|
|
27
22
|
onAddPattern,
|
|
28
23
|
atoms
|
|
29
24
|
}) {
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon, {
|
|
48
|
-
icon: _sharedUi.Filter,
|
|
49
|
-
color: _sharedUi.night.color.textSecondary,
|
|
50
|
-
size: 12
|
|
51
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Title, {
|
|
52
|
-
children: "REGISTERED ATOMS"
|
|
53
|
-
})]
|
|
54
|
-
}), atoms.length === 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
55
|
-
style: styles.emptyText,
|
|
56
|
-
testID: `${_testIDs.JOTAI_TEST_ID}-filters-atoms-empty`,
|
|
57
|
-
children: "No atoms registered yet."
|
|
58
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
|
|
59
|
-
style: styles.atomList,
|
|
60
|
-
contentContainerStyle: styles.atomListContent,
|
|
61
|
-
nestedScrollEnabled: true,
|
|
62
|
-
testID: `${_testIDs.JOTAI_TEST_ID}-filters-atom-list`,
|
|
63
|
-
children: atoms.map(atom => {
|
|
64
|
-
const atomColor = _jotaiStateStore.jotaiStateStore.getAtomColor(atom.label);
|
|
65
|
-
const isFiltered = Array.from(ignoredPatterns).some(p => atom.label.toLowerCase().includes(p.toLowerCase()));
|
|
66
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
67
|
-
style: [styles.atomRow, isFiltered && styles.atomRowFiltered],
|
|
68
|
-
onPress: () => onTogglePattern(atom.label),
|
|
69
|
-
activeOpacity: 0.7,
|
|
70
|
-
testID: `${_testIDs.JOTAI_TEST_ID}-filters-atom-${(0, _testIDs.slugForTestID)(atom.label)}`,
|
|
71
|
-
accessibilityRole: "button",
|
|
72
|
-
accessibilityLabel: isFiltered ? `Show ${atom.label}` : `Hide ${atom.label}`,
|
|
73
|
-
accessibilityState: {
|
|
74
|
-
selected: isFiltered
|
|
75
|
-
},
|
|
76
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
77
|
-
style: [styles.atomDot, {
|
|
78
|
-
backgroundColor: atomColor
|
|
79
|
-
}]
|
|
80
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
81
|
-
style: [styles.atomRowText, {
|
|
82
|
-
color: atomColor
|
|
83
|
-
}, isFiltered && styles.atomRowTextFiltered],
|
|
84
|
-
numberOfLines: 1,
|
|
85
|
-
children: atom.label
|
|
86
|
-
}), isFiltered ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
87
|
-
style: styles.filteredLabel,
|
|
88
|
-
children: "filtered"
|
|
89
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
90
|
-
style: [styles.addLabel, {
|
|
91
|
-
color: atomColor
|
|
92
|
-
}],
|
|
93
|
-
children: "+ add"
|
|
94
|
-
})]
|
|
95
|
-
}, atom.label);
|
|
96
|
-
})
|
|
97
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
98
|
-
style: styles.addInputWrapper,
|
|
99
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
|
|
100
|
-
testID: `${_testIDs.JOTAI_TEST_ID}-filters-add-input`,
|
|
101
|
-
accessibilityLabel: "Add an ignore pattern",
|
|
102
|
-
value: newPattern,
|
|
103
|
-
onChangeText: setNewPattern,
|
|
104
|
-
onSubmitEditing: handleAddPattern,
|
|
105
|
-
placeholder: "Type a pattern and press Enter...",
|
|
106
|
-
placeholderTextColor: _sharedUi.night.color.placeholder,
|
|
107
|
-
returnKeyType: "done",
|
|
108
|
-
autoCapitalize: "none",
|
|
109
|
-
autoCorrect: false,
|
|
110
|
-
style: styles.patternInput
|
|
111
|
-
})
|
|
112
|
-
})]
|
|
113
|
-
}), ignoredPatterns.size > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
114
|
-
style: styles.section,
|
|
115
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.SectionHeader, {
|
|
116
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon, {
|
|
117
|
-
icon: _sharedUi.Filter,
|
|
118
|
-
color: _sharedUi.night.color.textSecondary,
|
|
119
|
-
size: 12
|
|
120
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Title, {
|
|
121
|
-
children: "ACTIVE FILTERS"
|
|
122
|
-
})]
|
|
123
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
124
|
-
style: styles.patternList,
|
|
125
|
-
children: Array.from(ignoredPatterns).map(pattern => {
|
|
126
|
-
const atomColor = getAtomColorForPattern(pattern, atoms);
|
|
127
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
128
|
-
style: styles.patternRow,
|
|
129
|
-
onPress: () => onTogglePattern(pattern),
|
|
130
|
-
activeOpacity: 0.8,
|
|
131
|
-
testID: `${_testIDs.JOTAI_TEST_ID}-filters-chip-${(0, _testIDs.slugForTestID)(pattern)}`,
|
|
132
|
-
accessibilityRole: "button",
|
|
133
|
-
accessibilityLabel: `Remove filter ${pattern}`,
|
|
134
|
-
children: [atomColor ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
135
|
-
style: [styles.atomDot, {
|
|
136
|
-
backgroundColor: atomColor
|
|
137
|
-
}]
|
|
138
|
-
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
139
|
-
style: [styles.patternText, atomColor ? {
|
|
140
|
-
color: atomColor
|
|
141
|
-
} : null],
|
|
142
|
-
numberOfLines: 1,
|
|
143
|
-
children: pattern
|
|
144
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.X, {
|
|
145
|
-
size: 12,
|
|
146
|
-
color: _sharedUi.night.color.accent + "80"
|
|
147
|
-
})]
|
|
148
|
-
}, pattern);
|
|
149
|
-
})
|
|
150
|
-
})]
|
|
151
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
152
|
-
style: styles.section,
|
|
153
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.SectionHeader, {
|
|
154
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon, {
|
|
155
|
-
icon: _sharedUi.Filter,
|
|
156
|
-
color: _sharedUi.night.color.textSecondary,
|
|
157
|
-
size: 12
|
|
158
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Title, {
|
|
159
|
-
children: "HOW ATOM FILTERS WORK"
|
|
160
|
-
})]
|
|
161
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
162
|
-
style: styles.howItWorksText,
|
|
163
|
-
children: "Patterns hide matching atoms from both the Atoms tab and the Events tab. Tap an atom above to quickly add it as a filter."
|
|
164
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
165
|
-
style: styles.examplesContainer,
|
|
166
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
167
|
-
style: styles.examplesTitle,
|
|
168
|
-
children: "EXAMPLES:"
|
|
169
|
-
}), ["• count -> hides countAtom from atoms & events", "• auth -> hides authAtom, authStatusAtom", "• user -> hides userAtom from both tabs"].map(ex => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
170
|
-
style: styles.exampleItem,
|
|
171
|
-
children: ex
|
|
172
|
-
}, ex))]
|
|
173
|
-
})]
|
|
174
|
-
})]
|
|
25
|
+
const entities = (0, _react.useMemo)(() => atoms.map(atom => ({
|
|
26
|
+
name: atom.label,
|
|
27
|
+
color: atom.color
|
|
28
|
+
})), [atoms]);
|
|
29
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.EntityFilterView, {
|
|
30
|
+
entities: entities,
|
|
31
|
+
ignoredPatterns: ignoredPatterns,
|
|
32
|
+
onTogglePattern: onTogglePattern,
|
|
33
|
+
onAddPattern: onAddPattern,
|
|
34
|
+
entityNoun: "ATOMS",
|
|
35
|
+
entitySingular: "atom",
|
|
36
|
+
entityKey: "atom",
|
|
37
|
+
testIDPrefix: _testIDs.JOTAI_TEST_ID,
|
|
38
|
+
slug: _testIDs.slugForTestID,
|
|
39
|
+
howItWorks: "Patterns hide matching atoms from both the Atoms tab and the Events tab. Tap an atom above to quickly add it as a filter.",
|
|
40
|
+
examples: EXAMPLES,
|
|
41
|
+
emptyMessage: "No atoms are being watched yet."
|
|
175
42
|
});
|
|
176
|
-
}
|
|
177
|
-
const styles = _reactNative.StyleSheet.create({
|
|
178
|
-
container: {
|
|
179
|
-
flex: 1,
|
|
180
|
-
// Transparent so the night sheet's star field shows through.
|
|
181
|
-
backgroundColor: "transparent"
|
|
182
|
-
},
|
|
183
|
-
scrollContent: {
|
|
184
|
-
paddingTop: 16,
|
|
185
|
-
paddingHorizontal: 16,
|
|
186
|
-
paddingBottom: 24,
|
|
187
|
-
gap: 16
|
|
188
|
-
},
|
|
189
|
-
section: {
|
|
190
|
-
backgroundColor: _sharedUi.night.color.surface,
|
|
191
|
-
borderRadius: 16,
|
|
192
|
-
borderWidth: 1,
|
|
193
|
-
borderColor: _sharedUi.night.color.border,
|
|
194
|
-
overflow: "hidden"
|
|
195
|
-
},
|
|
196
|
-
atomList: {
|
|
197
|
-
maxHeight: 180
|
|
198
|
-
},
|
|
199
|
-
atomListContent: {
|
|
200
|
-
paddingHorizontal: 16,
|
|
201
|
-
paddingTop: 8,
|
|
202
|
-
paddingBottom: 16,
|
|
203
|
-
gap: 10
|
|
204
|
-
},
|
|
205
|
-
atomRow: {
|
|
206
|
-
flexDirection: "row",
|
|
207
|
-
alignItems: "center",
|
|
208
|
-
gap: 10,
|
|
209
|
-
paddingVertical: 10,
|
|
210
|
-
paddingHorizontal: 12,
|
|
211
|
-
backgroundColor: _sharedUi.night.color.surfaceElevated,
|
|
212
|
-
borderRadius: 8,
|
|
213
|
-
borderWidth: 1,
|
|
214
|
-
borderColor: _sharedUi.night.color.border
|
|
215
|
-
},
|
|
216
|
-
atomRowFiltered: {
|
|
217
|
-
opacity: 0.45
|
|
218
|
-
},
|
|
219
|
-
atomDot: {
|
|
220
|
-
width: 7,
|
|
221
|
-
height: 7,
|
|
222
|
-
borderRadius: 3.5
|
|
223
|
-
},
|
|
224
|
-
atomRowText: {
|
|
225
|
-
flex: 1,
|
|
226
|
-
fontSize: 12,
|
|
227
|
-
fontWeight: "600",
|
|
228
|
-
fontFamily: "monospace"
|
|
229
|
-
},
|
|
230
|
-
atomRowTextFiltered: {
|
|
231
|
-
color: _sharedUi.night.color.textTertiary,
|
|
232
|
-
textDecorationLine: "line-through"
|
|
233
|
-
},
|
|
234
|
-
filteredLabel: {
|
|
235
|
-
fontSize: 10,
|
|
236
|
-
fontWeight: "500",
|
|
237
|
-
color: _sharedUi.night.color.textTertiary,
|
|
238
|
-
fontFamily: "monospace"
|
|
239
|
-
},
|
|
240
|
-
addLabel: {
|
|
241
|
-
fontSize: 10,
|
|
242
|
-
fontWeight: "600",
|
|
243
|
-
fontFamily: "monospace"
|
|
244
|
-
},
|
|
245
|
-
addInputWrapper: {
|
|
246
|
-
paddingHorizontal: 16,
|
|
247
|
-
paddingTop: 8,
|
|
248
|
-
paddingBottom: 8
|
|
249
|
-
},
|
|
250
|
-
patternList: {
|
|
251
|
-
paddingHorizontal: 16,
|
|
252
|
-
paddingBottom: 16,
|
|
253
|
-
gap: 8
|
|
254
|
-
},
|
|
255
|
-
patternRow: {
|
|
256
|
-
flexDirection: "row",
|
|
257
|
-
alignItems: "center",
|
|
258
|
-
justifyContent: "space-between",
|
|
259
|
-
paddingVertical: 10,
|
|
260
|
-
paddingHorizontal: 12,
|
|
261
|
-
backgroundColor: _sharedUi.night.color.surfaceElevated,
|
|
262
|
-
borderRadius: 8,
|
|
263
|
-
borderWidth: 1,
|
|
264
|
-
borderColor: _sharedUi.night.color.border,
|
|
265
|
-
gap: 8
|
|
266
|
-
},
|
|
267
|
-
patternText: {
|
|
268
|
-
flex: 1,
|
|
269
|
-
fontSize: 12,
|
|
270
|
-
fontFamily: "monospace",
|
|
271
|
-
color: _sharedUi.night.color.text
|
|
272
|
-
},
|
|
273
|
-
howItWorksText: {
|
|
274
|
-
fontSize: 11,
|
|
275
|
-
color: _sharedUi.night.color.textSecondary,
|
|
276
|
-
lineHeight: 16,
|
|
277
|
-
marginTop: 8,
|
|
278
|
-
paddingHorizontal: 16,
|
|
279
|
-
fontFamily: "monospace"
|
|
280
|
-
},
|
|
281
|
-
examplesContainer: {
|
|
282
|
-
paddingTop: 8,
|
|
283
|
-
paddingHorizontal: 16,
|
|
284
|
-
paddingBottom: 16,
|
|
285
|
-
borderTopWidth: 1,
|
|
286
|
-
borderTopColor: _sharedUi.night.color.border,
|
|
287
|
-
marginTop: 12
|
|
288
|
-
},
|
|
289
|
-
examplesTitle: {
|
|
290
|
-
fontSize: 10,
|
|
291
|
-
fontWeight: "600",
|
|
292
|
-
color: _sharedUi.night.color.textTertiary,
|
|
293
|
-
fontFamily: "monospace",
|
|
294
|
-
letterSpacing: 0.5,
|
|
295
|
-
marginBottom: 6
|
|
296
|
-
},
|
|
297
|
-
exampleItem: {
|
|
298
|
-
fontSize: 10,
|
|
299
|
-
color: _sharedUi.night.color.textTertiary,
|
|
300
|
-
fontFamily: "monospace",
|
|
301
|
-
lineHeight: 16
|
|
302
|
-
},
|
|
303
|
-
emptyText: {
|
|
304
|
-
fontSize: 11,
|
|
305
|
-
color: _sharedUi.night.color.textTertiary,
|
|
306
|
-
paddingHorizontal: 16,
|
|
307
|
-
paddingVertical: 12,
|
|
308
|
-
fontFamily: "monospace"
|
|
309
|
-
},
|
|
310
|
-
patternInput: {
|
|
311
|
-
borderWidth: 1,
|
|
312
|
-
borderColor: _sharedUi.night.color.accentBorder,
|
|
313
|
-
borderRadius: 8,
|
|
314
|
-
paddingHorizontal: 12,
|
|
315
|
-
paddingVertical: 8,
|
|
316
|
-
fontSize: 12,
|
|
317
|
-
color: _sharedUi.night.color.text,
|
|
318
|
-
fontFamily: "monospace",
|
|
319
|
-
backgroundColor: _sharedUi.night.color.surfaceElevated
|
|
320
|
-
}
|
|
321
|
-
});
|
|
43
|
+
}
|
|
@@ -25,17 +25,6 @@ var _jsxRuntime = require("react/jsx-runtime");
|
|
|
25
25
|
* - Events tab: Live atom change monitoring with diffs
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
|
-
/**
|
|
29
|
-
* Cell clipping, off in e2e bundles only.
|
|
30
|
-
*
|
|
31
|
-
* `removeClippedSubviews` unmounts the views of rows scrolled out of the
|
|
32
|
-
* window, which is what makes a long change list cheap — and which makes
|
|
33
|
-
* Detox report a perfectly rendered row as un-hittable. The env var is
|
|
34
|
-
* inlined at bundle time, so a bundler that does NOT inline it leaves the
|
|
35
|
-
* production behaviour exactly as it was.
|
|
36
|
-
*/
|
|
37
|
-
const CLIP_OFFSCREEN_CELLS = !(typeof process !== "undefined" && process.env?.EXPO_PUBLIC_E2E);
|
|
38
|
-
|
|
39
28
|
/**
|
|
40
29
|
* The change log's "nothing here". Everything but the nouns is the shared
|
|
41
30
|
* precedence — see `ToolEmptyState` in shared-ui for why it lives there.
|
|
@@ -358,49 +347,24 @@ function JotaiModal({
|
|
|
358
347
|
onBack: onBack
|
|
359
348
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ModalHeader.Content, {
|
|
360
349
|
title: "",
|
|
361
|
-
children: isSearchActive ? /*#__PURE__*/(0, _jsxRuntime.
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
// header went back to its TABS — whose counts are of the
|
|
380
|
-
// WHOLE capture — while the list stayed filtered, so the tool
|
|
381
|
-
// showed "Atoms (8)" above a single row and offered nothing to
|
|
382
|
-
// explain the gap. The only way back was to reopen a field the
|
|
383
|
-
// user had no reason to think was still armed. Same shape, and
|
|
384
|
-
// the same fix, as the Redux, Events and Zustand tools.
|
|
385
|
-
,
|
|
386
|
-
onBlur: () => {
|
|
387
|
-
if (searchText.length === 0) setIsSearchActive(false);
|
|
388
|
-
},
|
|
389
|
-
accessibilityLabel: "Search Jotai atoms and events",
|
|
390
|
-
autoCapitalize: "none",
|
|
391
|
-
autoCorrect: false,
|
|
392
|
-
returnKeyType: "search"
|
|
393
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
394
|
-
onPress: closeSearch,
|
|
395
|
-
style: styles.headerSearchClear,
|
|
396
|
-
testID: `${_testIDs.JOTAI_TEST_ID}-search-clear`,
|
|
397
|
-
accessibilityRole: "button",
|
|
398
|
-
accessibilityLabel: "Close search",
|
|
399
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.X, {
|
|
400
|
-
size: 14,
|
|
401
|
-
color: _sharedUi.night.color.textSecondary
|
|
402
|
-
})
|
|
403
|
-
})]
|
|
350
|
+
children: isSearchActive ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ModalHeader.Search, {
|
|
351
|
+
value: searchText,
|
|
352
|
+
onChangeText: handleSearch,
|
|
353
|
+
onCancel: closeSearch,
|
|
354
|
+
placeholder: activeTab === "atoms" ? "Search atoms..." : "Search events...",
|
|
355
|
+
accessibilityLabel: "Search Jotai atoms and events",
|
|
356
|
+
iconSize: 14,
|
|
357
|
+
testID: `${_testIDs.JOTAI_TEST_ID}-search-field`,
|
|
358
|
+
containerTestID: `${_testIDs.JOTAI_TEST_ID}-search`,
|
|
359
|
+
clearTestID: `${_testIDs.JOTAI_TEST_ID}-search-clear`
|
|
360
|
+
// Stay open while the query is still narrowing the list: the
|
|
361
|
+
// header would otherwise go back to its TABS — whose counts are
|
|
362
|
+
// of the WHOLE capture — above a filtered list, with nothing to
|
|
363
|
+
// explain the gap.
|
|
364
|
+
,
|
|
365
|
+
onBlur: () => {
|
|
366
|
+
if (searchText.length === 0) setIsSearchActive(false);
|
|
367
|
+
}
|
|
404
368
|
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.TabSelector, {
|
|
405
369
|
tabs: [{
|
|
406
370
|
key: "atoms",
|
|
@@ -490,11 +454,7 @@ function JotaiModal({
|
|
|
490
454
|
keyExtractor: keyExtractor,
|
|
491
455
|
contentContainerStyle: styles.listContent,
|
|
492
456
|
showsVerticalScrollIndicator: true,
|
|
493
|
-
|
|
494
|
-
initialNumToRender: 12,
|
|
495
|
-
maxToRenderPerBatch: 8,
|
|
496
|
-
windowSize: 5,
|
|
497
|
-
updateCellsBatchingPeriod: 50
|
|
457
|
+
..._sharedUi.EVENT_LIST_PRESET
|
|
498
458
|
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ToolEmptyState, {
|
|
499
459
|
testID: `${_testIDs.JOTAI_TEST_ID}-history-empty`,
|
|
500
460
|
...(0, _sharedUi.resolveListEmptyState)({
|
|
@@ -583,11 +543,7 @@ function JotaiModal({
|
|
|
583
543
|
keyExtractor: keyExtractor,
|
|
584
544
|
contentContainerStyle: styles.listContent,
|
|
585
545
|
showsVerticalScrollIndicator: true,
|
|
586
|
-
|
|
587
|
-
initialNumToRender: 12,
|
|
588
|
-
maxToRenderPerBatch: 8,
|
|
589
|
-
windowSize: 5,
|
|
590
|
-
updateCellsBatchingPeriod: 50
|
|
546
|
+
..._sharedUi.EVENT_LIST_PRESET
|
|
591
547
|
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(EventsEmptyState, {
|
|
592
548
|
isEnabled: isEnabled,
|
|
593
549
|
searchText: searchText,
|
|
@@ -701,27 +657,6 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
701
657
|
// Transparent so JsModal's ToolBackground shows through (the modal paints opaque base beneath it).
|
|
702
658
|
backgroundColor: "transparent"
|
|
703
659
|
},
|
|
704
|
-
headerSearchContainer: {
|
|
705
|
-
flexDirection: "row",
|
|
706
|
-
alignItems: "center",
|
|
707
|
-
backgroundColor: _sharedUi.night.color.surfaceElevated,
|
|
708
|
-
borderRadius: _sharedUi.night.radius.row,
|
|
709
|
-
borderWidth: 1,
|
|
710
|
-
borderColor: _sharedUi.night.color.border,
|
|
711
|
-
paddingHorizontal: 12,
|
|
712
|
-
paddingVertical: 5
|
|
713
|
-
},
|
|
714
|
-
headerSearchInput: {
|
|
715
|
-
flex: 1,
|
|
716
|
-
color: _sharedUi.night.color.text,
|
|
717
|
-
fontSize: 13,
|
|
718
|
-
marginLeft: 6,
|
|
719
|
-
paddingVertical: 2
|
|
720
|
-
},
|
|
721
|
-
headerSearchClear: {
|
|
722
|
-
marginLeft: 6,
|
|
723
|
-
padding: 4
|
|
724
|
-
},
|
|
725
660
|
headerActionButton: {
|
|
726
661
|
width: 32,
|
|
727
662
|
height: 32,
|