@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.
Files changed (32) hide show
  1. package/lib/commonjs/jotai/components/JotaiAtomChangeItem.js +7 -52
  2. package/lib/commonjs/jotai/components/JotaiAtomDetailContent.js +8 -87
  3. package/lib/commonjs/jotai/components/JotaiEventFilterView.js +21 -299
  4. package/lib/commonjs/jotai/components/JotaiModal.js +20 -85
  5. package/lib/commonjs/jotai/hooks/useJotaiAtomChanges.js +33 -49
  6. package/lib/commonjs/jotai/sync/jotaiSyncAdapter.js +19 -66
  7. package/lib/commonjs/jotai/utils/jotaiStateStore.js +23 -188
  8. package/lib/commonjs/jotai/utils/snapshotProvider.js +7 -25
  9. package/lib/commonjs/preset.js +14 -22
  10. package/lib/module/jotai/components/JotaiAtomChangeItem.js +9 -54
  11. package/lib/module/jotai/components/JotaiAtomDetailContent.js +9 -88
  12. package/lib/module/jotai/components/JotaiEventFilterView.js +24 -302
  13. package/lib/module/jotai/components/JotaiModal.js +22 -87
  14. package/lib/module/jotai/hooks/useJotaiAtomChanges.js +34 -50
  15. package/lib/module/jotai/sync/jotaiSyncAdapter.js +20 -67
  16. package/lib/module/jotai/utils/jotaiStateStore.js +23 -188
  17. package/lib/module/jotai/utils/snapshotProvider.js +8 -26
  18. package/lib/module/preset.js +13 -20
  19. package/lib/typescript/jotai/components/JotaiAtomChangeItem.d.ts.map +1 -1
  20. package/lib/typescript/jotai/components/JotaiAtomDetailContent.d.ts.map +1 -1
  21. package/lib/typescript/jotai/components/JotaiEventFilterView.d.ts +2 -2
  22. package/lib/typescript/jotai/components/JotaiEventFilterView.d.ts.map +1 -1
  23. package/lib/typescript/jotai/components/JotaiModal.d.ts.map +1 -1
  24. package/lib/typescript/jotai/hooks/useJotaiAtomChanges.d.ts +2 -1
  25. package/lib/typescript/jotai/hooks/useJotaiAtomChanges.d.ts.map +1 -1
  26. package/lib/typescript/jotai/sync/jotaiSyncAdapter.d.ts +54 -68
  27. package/lib/typescript/jotai/sync/jotaiSyncAdapter.d.ts.map +1 -1
  28. package/lib/typescript/jotai/utils/jotaiStateStore.d.ts +2 -25
  29. package/lib/typescript/jotai/utils/jotaiStateStore.d.ts.map +1 -1
  30. package/lib/typescript/preset.d.ts +2 -8
  31. package/lib/typescript/preset.d.ts.map +1 -1
  32. package/package.json +3 -3
@@ -3,10 +3,10 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.createJotaiTool = createJotaiTool;
7
- exports.jotaiToolPreset = void 0;
6
+ exports.jotaiToolPreset = exports.createJotaiTool = void 0;
8
7
  var _JotaiModal = require("./jotai/components/JotaiModal");
9
8
  var _JotaiIcon = require("./jotai/components/JotaiIcon");
9
+ var _sharedUi = require("@buoy-gg/shared-ui");
10
10
  var _jsxRuntime = require("react/jsx-runtime");
11
11
  /**
12
12
  * Pre-configured Jotai DevTools preset for FloatingDevTools
@@ -48,7 +48,7 @@ var _jsxRuntime = require("react/jsx-runtime");
48
48
  * - Filter by atom label
49
49
  * - Changed keys tracking for object atoms
50
50
  */
51
- const jotaiToolPreset = exports.jotaiToolPreset = {
51
+ const jotaiToolPreset = exports.jotaiToolPreset = (0, _sharedUi.defineToolPreset)({
52
52
  id: "jotai",
53
53
  name: "JOTAI",
54
54
  description: "Jotai atom & state inspector",
@@ -62,7 +62,7 @@ const jotaiToolPreset = exports.jotaiToolPreset = {
62
62
  props: {
63
63
  enableSharedModalDimensions: false
64
64
  }
65
- };
65
+ });
66
66
 
67
67
  /**
68
68
  * Create a custom Jotai DevTools configuration.
@@ -78,21 +78,13 @@ const jotaiToolPreset = exports.jotaiToolPreset = {
78
78
  * });
79
79
  * ```
80
80
  */
81
- function createJotaiTool(options) {
82
- return {
83
- id: options?.id || "jotai",
84
- name: options?.name || "JOTAI",
85
- description: options?.description || "Jotai atom & state inspector",
86
- slot: "both",
87
- icon: ({
88
- size
89
- }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_JotaiIcon.JotaiIcon, {
90
- size: size,
91
- color: options?.iconColor
92
- }),
93
- component: _JotaiModal.JotaiModal,
94
- props: {
95
- enableSharedModalDimensions: options?.enableSharedModalDimensions !== undefined ? options.enableSharedModalDimensions : false
96
- }
97
- };
98
- }
81
+ const createJotaiTool = exports.createJotaiTool = (0, _sharedUi.createToolFactory)(jotaiToolPreset, options => ({
82
+ enableSharedModalDimensions: options.enableSharedModalDimensions ?? false
83
+ }), options => ({
84
+ icon: ({
85
+ size
86
+ }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_JotaiIcon.JotaiIcon, {
87
+ size: size,
88
+ color: options.iconColor
89
+ })
90
+ }));
@@ -7,10 +7,9 @@
7
7
  */
8
8
 
9
9
  import { memo } from "react";
10
- import { View, Text, StyleSheet } from "react-native";
11
- import { CompactRow, buoyColors, night, Zap, RelativeTime } from "@buoy-gg/shared-ui";
10
+ import { ChangeRow, night } from "@buoy-gg/shared-ui";
12
11
  import { jotaiStateStore } from "../utils/jotaiStateStore";
13
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
+ import { jsx as _jsx } from "react/jsx-runtime";
14
13
  function getStatusLabel(category, atomLabel) {
15
14
  if (category === "initial") return "Initial";
16
15
  return atomLabel.charAt(0).toUpperCase() + atomLabel.slice(1);
@@ -68,59 +67,15 @@ export const JotaiAtomChangeItem = /*#__PURE__*/memo(function JotaiAtomChangeIte
68
67
  const sublabel = getSublabel(change);
69
68
  const primaryText = getPrimaryText(change);
70
69
  const badgeText = getBadgeText(change);
71
-
72
- // Always a custom badge, even when there is no icon to hang off it. The
73
- // alternative — letting CompactRow draw `badgeText` itself — leaves the one
74
- // row whose badge matters most (a write that moved the atom's identity but
75
- // none of its contents) as the only row in the list with no handle on its
76
- // badge. Same call, and the same reason, as ZustandStateChangeItem.
77
- const customBadge = /*#__PURE__*/_jsxs(View, {
78
- style: styles.badgeContainer,
79
- children: [/*#__PURE__*/_jsx(Text, {
80
- style: [styles.badgeText, {
81
- color: statusColor
82
- }],
83
- testID: testID ? `${testID}-badge` : undefined,
84
- children: badgeText
85
- }), change.hasValueChange ? /*#__PURE__*/_jsx(View, {
86
- style: styles.changeBadge,
87
- testID: testID ? `${testID}-change` : undefined,
88
- children: /*#__PURE__*/_jsx(Zap, {
89
- size: 12,
90
- color: buoyColors.warning
91
- })
92
- }) : null]
93
- });
94
- return /*#__PURE__*/_jsx(CompactRow, {
95
- statusDotColor: statusColor,
70
+ return /*#__PURE__*/_jsx(ChangeRow, {
71
+ statusColor: statusColor,
96
72
  statusLabel: statusLabel,
97
- statusSublabel: sublabel,
73
+ sublabel: sublabel,
98
74
  primaryText: primaryText,
99
- bottomRightText: /*#__PURE__*/_jsx(RelativeTime, {
100
- timestamp: change.timestamp
101
- }),
102
- customBadge: customBadge,
103
- badgeColor: statusColor,
104
- showChevron: true,
75
+ timestamp: change.timestamp,
76
+ badgeText: badgeText,
77
+ changed: change.hasValueChange,
105
78
  onPress: () => onPress(change),
106
- testID: testID,
107
- statusTestID: testID ? `${testID}-status` : undefined,
108
- statusSublabelTestID: testID ? `${testID}-sublabel` : undefined,
109
- primaryTestID: testID ? `${testID}-keys` : undefined
79
+ testID: testID
110
80
  });
111
- });
112
- const styles = StyleSheet.create({
113
- badgeContainer: {
114
- flexDirection: "row",
115
- alignItems: "center",
116
- gap: 4
117
- },
118
- badgeText: {
119
- fontSize: 11,
120
- fontWeight: "600",
121
- fontFamily: "monospace"
122
- },
123
- changeBadge: {
124
- paddingHorizontal: 4
125
- }
126
81
  });
@@ -12,8 +12,8 @@
12
12
  */
13
13
 
14
14
  import React, { memo, useState, useCallback, useMemo } from "react";
15
- import { View, Text, StyleSheet, ScrollView, TouchableOpacity } from "react-native";
16
- import { buoyColors, night, EventStepperFooter, formatRelativeTime, parseValue, Info, Zap, FileText, Database, GitBranch, copyToClipboard, ProUpgradeModal, DiffModeTabs, CompareBar } from "@buoy-gg/shared-ui";
15
+ import { View, Text, StyleSheet, ScrollView } from "react-native";
16
+ import { buoyColors, night, EventStepperFooter, formatRelativeTime, parseValue, Info, Zap, FileText, Database, GitBranch, copyToClipboard, ProUpgradeModal, DiffModeTabs, CompareBar, DetailViewToggle } from "@buoy-gg/shared-ui";
17
17
  import { DataViewer, SplitDiffViewer, TreeDiffViewer, diffThemes } from "@buoy-gg/shared-ui/dataViewer";
18
18
  import { useIsPro } from "@buoy-gg/license";
19
19
  import { jotaiStateStore } from "../utils/jotaiStateStore";
@@ -24,61 +24,17 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
24
24
  const VIEW_CONFIGS = [{
25
25
  key: "change",
26
26
  label: "CHANGE",
27
- icon: FileText,
28
- activeColor: night.color.accent
27
+ icon: FileText
29
28
  }, {
30
29
  key: "value",
31
30
  label: "VALUE",
32
- icon: Database,
33
- activeColor: night.color.accent
31
+ icon: Database
34
32
  }, {
35
33
  key: "diff",
36
34
  label: "DIFF",
37
- icon: GitBranch,
38
- activeColor: night.color.accent
35
+ icon: GitBranch
39
36
  }];
40
- function DetailViewToggle({
41
- activeView,
42
- onViewChange,
43
- diffDisabled
44
- }) {
45
- return /*#__PURE__*/_jsx(View, {
46
- style: toggleStyles.container,
47
- children: VIEW_CONFIGS.map(config => {
48
- const isActive = activeView === config.key;
49
- const isDisabled = config.key === "diff" && diffDisabled;
50
- const IconComponent = config.icon;
51
- return /*#__PURE__*/_jsx(TouchableOpacity, {
52
- style: [toggleStyles.card, isActive && [toggleStyles.cardActive, {
53
- borderColor: config.activeColor
54
- }], isDisabled && toggleStyles.cardDisabled],
55
- onPress: () => !isDisabled && onViewChange(config.key),
56
- activeOpacity: 0.7,
57
- testID: `${JOTAI_TEST_ID}-view-${config.key}`,
58
- accessibilityRole: "button",
59
- accessibilityLabel: config.label,
60
- accessibilityState: {
61
- disabled: isDisabled,
62
- selected: isActive
63
- },
64
- children: /*#__PURE__*/_jsxs(View, {
65
- style: toggleStyles.cardContent,
66
- children: [/*#__PURE__*/_jsx(IconComponent, {
67
- size: 14,
68
- color: isActive ? config.activeColor : isDisabled ? night.color.textTertiary : night.color.textSecondary
69
- }), /*#__PURE__*/_jsx(Text, {
70
- style: [toggleStyles.cardLabel, isActive && {
71
- color: config.activeColor
72
- }, isDisabled && {
73
- color: night.color.textTertiary
74
- }],
75
- children: config.label
76
- })]
77
- })
78
- }, config.key);
79
- })
80
- });
81
- }
37
+ const DIFF_DISABLED = ["diff"];
82
38
 
83
39
  // ---- Helpers ----
84
40
 
@@ -428,9 +384,11 @@ export function JotaiAtomDetailContent({
428
384
  return /*#__PURE__*/_jsxs(View, {
429
385
  style: styles.container,
430
386
  children: [/*#__PURE__*/_jsx(DetailViewToggle, {
387
+ views: VIEW_CONFIGS,
431
388
  activeView: activeView,
432
389
  onViewChange: setActiveView,
433
- diffDisabled: diffDisabled
390
+ disabledKeys: diffDisabled ? DIFF_DISABLED : undefined,
391
+ testIDPrefix: JOTAI_TEST_ID
434
392
  }), /*#__PURE__*/_jsxs(View, {
435
393
  style: [styles.contentArea, showInternalFooter && styles.contentAreaFooterPad],
436
394
  children: [activeView === "change" && /*#__PURE__*/_jsx(JotaiAtomInfoView, {
@@ -582,43 +540,6 @@ const styles = StyleSheet.create({
582
540
  fontFamily: "monospace"
583
541
  }
584
542
  });
585
- const toggleStyles = StyleSheet.create({
586
- container: {
587
- flexDirection: "row",
588
- gap: 8,
589
- padding: 14,
590
- // Transparent so the night sheet's star field shows through.
591
- backgroundColor: "transparent"
592
- },
593
- card: {
594
- flex: 1,
595
- backgroundColor: night.color.surface,
596
- borderRadius: 12,
597
- borderWidth: 1,
598
- borderColor: night.color.border,
599
- paddingVertical: 10,
600
- paddingHorizontal: 10,
601
- justifyContent: "center"
602
- },
603
- cardActive: {
604
- borderWidth: 1.5,
605
- backgroundColor: night.color.accentSoft
606
- },
607
- cardDisabled: {
608
- opacity: 0.5
609
- },
610
- cardContent: {
611
- flexDirection: "row",
612
- alignItems: "center",
613
- gap: 6
614
- },
615
- cardLabel: {
616
- fontSize: 10,
617
- fontWeight: "700",
618
- letterSpacing: 0.5,
619
- color: night.color.textSecondary
620
- }
621
- });
622
543
  const infoStyles = StyleSheet.create({
623
544
  container: {
624
545
  flex: 1
@@ -3,315 +3,37 @@
3
3
  /**
4
4
  * JotaiEventFilterView
5
5
  *
6
- * Filter configuration UI for hiding atoms from the Atoms and Events tabs.
7
- * Mirrors ZustandEventFilterView.tsx from @buoy-gg/zustand.
6
+ * The shared `EntityFilterView` with jotai's nouns: watched atoms you can
7
+ * tap to hide, active atom-name patterns, and how it works.
8
8
  */
9
9
 
10
- import { useState } from "react";
11
- import { View, Text, TextInput, StyleSheet, ScrollView, TouchableOpacity } from "react-native";
12
- import { SectionHeader, night, Filter, X } from "@buoy-gg/shared-ui";
13
- import { jotaiStateStore } from "../utils/jotaiStateStore";
10
+ import { useMemo } from "react";
11
+ import { EntityFilterView } from "@buoy-gg/shared-ui";
14
12
  import { JOTAI_TEST_ID, slugForTestID } from "../utils/testIDs";
15
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
16
- function getAtomColorForPattern(pattern, atoms) {
17
- const match = atoms.find(a => a.label.toLowerCase().includes(pattern.toLowerCase()));
18
- return match ? match.color : null;
19
- }
13
+ import { jsx as _jsx } from "react/jsx-runtime";
14
+ const EXAMPLES = ["• count -> hides countAtom from atoms & events", "• auth -> hides authAtom, authStatusAtom", "• user -> hides userAtom from both tabs"];
20
15
  export function JotaiEventFilterView({
21
16
  ignoredPatterns,
22
17
  onTogglePattern,
23
18
  onAddPattern,
24
19
  atoms
25
20
  }) {
26
- const [newPattern, setNewPattern] = useState("");
27
- const handleAddPattern = () => {
28
- const trimmed = newPattern.trim();
29
- if (trimmed && !ignoredPatterns.has(trimmed)) {
30
- onAddPattern(trimmed);
31
- setNewPattern("");
32
- }
33
- };
34
- return /*#__PURE__*/_jsxs(ScrollView, {
35
- style: styles.container,
36
- contentContainerStyle: styles.scrollContent,
37
- showsVerticalScrollIndicator: false,
38
- nestedScrollEnabled: true,
39
- testID: `${JOTAI_TEST_ID}-filters-scroll`,
40
- children: [/*#__PURE__*/_jsxs(View, {
41
- style: styles.section,
42
- children: [/*#__PURE__*/_jsxs(SectionHeader, {
43
- children: [/*#__PURE__*/_jsx(SectionHeader.Icon, {
44
- icon: Filter,
45
- color: night.color.textSecondary,
46
- size: 12
47
- }), /*#__PURE__*/_jsx(SectionHeader.Title, {
48
- children: "REGISTERED ATOMS"
49
- })]
50
- }), atoms.length === 0 ? /*#__PURE__*/_jsx(Text, {
51
- style: styles.emptyText,
52
- testID: `${JOTAI_TEST_ID}-filters-atoms-empty`,
53
- children: "No atoms registered yet."
54
- }) : /*#__PURE__*/_jsx(ScrollView, {
55
- style: styles.atomList,
56
- contentContainerStyle: styles.atomListContent,
57
- nestedScrollEnabled: true,
58
- testID: `${JOTAI_TEST_ID}-filters-atom-list`,
59
- children: atoms.map(atom => {
60
- const atomColor = jotaiStateStore.getAtomColor(atom.label);
61
- const isFiltered = Array.from(ignoredPatterns).some(p => atom.label.toLowerCase().includes(p.toLowerCase()));
62
- return /*#__PURE__*/_jsxs(TouchableOpacity, {
63
- style: [styles.atomRow, isFiltered && styles.atomRowFiltered],
64
- onPress: () => onTogglePattern(atom.label),
65
- activeOpacity: 0.7,
66
- testID: `${JOTAI_TEST_ID}-filters-atom-${slugForTestID(atom.label)}`,
67
- accessibilityRole: "button",
68
- accessibilityLabel: isFiltered ? `Show ${atom.label}` : `Hide ${atom.label}`,
69
- accessibilityState: {
70
- selected: isFiltered
71
- },
72
- children: [/*#__PURE__*/_jsx(View, {
73
- style: [styles.atomDot, {
74
- backgroundColor: atomColor
75
- }]
76
- }), /*#__PURE__*/_jsx(Text, {
77
- style: [styles.atomRowText, {
78
- color: atomColor
79
- }, isFiltered && styles.atomRowTextFiltered],
80
- numberOfLines: 1,
81
- children: atom.label
82
- }), isFiltered ? /*#__PURE__*/_jsx(Text, {
83
- style: styles.filteredLabel,
84
- children: "filtered"
85
- }) : /*#__PURE__*/_jsx(Text, {
86
- style: [styles.addLabel, {
87
- color: atomColor
88
- }],
89
- children: "+ add"
90
- })]
91
- }, atom.label);
92
- })
93
- }), /*#__PURE__*/_jsx(View, {
94
- style: styles.addInputWrapper,
95
- children: /*#__PURE__*/_jsx(TextInput, {
96
- testID: `${JOTAI_TEST_ID}-filters-add-input`,
97
- accessibilityLabel: "Add an ignore pattern",
98
- value: newPattern,
99
- onChangeText: setNewPattern,
100
- onSubmitEditing: handleAddPattern,
101
- placeholder: "Type a pattern and press Enter...",
102
- placeholderTextColor: night.color.placeholder,
103
- returnKeyType: "done",
104
- autoCapitalize: "none",
105
- autoCorrect: false,
106
- style: styles.patternInput
107
- })
108
- })]
109
- }), ignoredPatterns.size > 0 && /*#__PURE__*/_jsxs(View, {
110
- style: styles.section,
111
- children: [/*#__PURE__*/_jsxs(SectionHeader, {
112
- children: [/*#__PURE__*/_jsx(SectionHeader.Icon, {
113
- icon: Filter,
114
- color: night.color.textSecondary,
115
- size: 12
116
- }), /*#__PURE__*/_jsx(SectionHeader.Title, {
117
- children: "ACTIVE FILTERS"
118
- })]
119
- }), /*#__PURE__*/_jsx(View, {
120
- style: styles.patternList,
121
- children: Array.from(ignoredPatterns).map(pattern => {
122
- const atomColor = getAtomColorForPattern(pattern, atoms);
123
- return /*#__PURE__*/_jsxs(TouchableOpacity, {
124
- style: styles.patternRow,
125
- onPress: () => onTogglePattern(pattern),
126
- activeOpacity: 0.8,
127
- testID: `${JOTAI_TEST_ID}-filters-chip-${slugForTestID(pattern)}`,
128
- accessibilityRole: "button",
129
- accessibilityLabel: `Remove filter ${pattern}`,
130
- children: [atomColor ? /*#__PURE__*/_jsx(View, {
131
- style: [styles.atomDot, {
132
- backgroundColor: atomColor
133
- }]
134
- }) : null, /*#__PURE__*/_jsx(Text, {
135
- style: [styles.patternText, atomColor ? {
136
- color: atomColor
137
- } : null],
138
- numberOfLines: 1,
139
- children: pattern
140
- }), /*#__PURE__*/_jsx(X, {
141
- size: 12,
142
- color: night.color.accent + "80"
143
- })]
144
- }, pattern);
145
- })
146
- })]
147
- }), /*#__PURE__*/_jsxs(View, {
148
- style: styles.section,
149
- children: [/*#__PURE__*/_jsxs(SectionHeader, {
150
- children: [/*#__PURE__*/_jsx(SectionHeader.Icon, {
151
- icon: Filter,
152
- color: night.color.textSecondary,
153
- size: 12
154
- }), /*#__PURE__*/_jsx(SectionHeader.Title, {
155
- children: "HOW ATOM FILTERS WORK"
156
- })]
157
- }), /*#__PURE__*/_jsx(Text, {
158
- style: styles.howItWorksText,
159
- 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."
160
- }), /*#__PURE__*/_jsxs(View, {
161
- style: styles.examplesContainer,
162
- children: [/*#__PURE__*/_jsx(Text, {
163
- style: styles.examplesTitle,
164
- children: "EXAMPLES:"
165
- }), ["• count -> hides countAtom from atoms & events", "• auth -> hides authAtom, authStatusAtom", "• user -> hides userAtom from both tabs"].map(ex => /*#__PURE__*/_jsx(Text, {
166
- style: styles.exampleItem,
167
- children: ex
168
- }, ex))]
169
- })]
170
- })]
21
+ const entities = useMemo(() => atoms.map(atom => ({
22
+ name: atom.label,
23
+ color: atom.color
24
+ })), [atoms]);
25
+ return /*#__PURE__*/_jsx(EntityFilterView, {
26
+ entities: entities,
27
+ ignoredPatterns: ignoredPatterns,
28
+ onTogglePattern: onTogglePattern,
29
+ onAddPattern: onAddPattern,
30
+ entityNoun: "ATOMS",
31
+ entitySingular: "atom",
32
+ entityKey: "atom",
33
+ testIDPrefix: JOTAI_TEST_ID,
34
+ slug: slugForTestID,
35
+ 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.",
36
+ examples: EXAMPLES,
37
+ emptyMessage: "No atoms are being watched yet."
171
38
  });
172
- }
173
- const styles = StyleSheet.create({
174
- container: {
175
- flex: 1,
176
- // Transparent so the night sheet's star field shows through.
177
- backgroundColor: "transparent"
178
- },
179
- scrollContent: {
180
- paddingTop: 16,
181
- paddingHorizontal: 16,
182
- paddingBottom: 24,
183
- gap: 16
184
- },
185
- section: {
186
- backgroundColor: night.color.surface,
187
- borderRadius: 16,
188
- borderWidth: 1,
189
- borderColor: night.color.border,
190
- overflow: "hidden"
191
- },
192
- atomList: {
193
- maxHeight: 180
194
- },
195
- atomListContent: {
196
- paddingHorizontal: 16,
197
- paddingTop: 8,
198
- paddingBottom: 16,
199
- gap: 10
200
- },
201
- atomRow: {
202
- flexDirection: "row",
203
- alignItems: "center",
204
- gap: 10,
205
- paddingVertical: 10,
206
- paddingHorizontal: 12,
207
- backgroundColor: night.color.surfaceElevated,
208
- borderRadius: 8,
209
- borderWidth: 1,
210
- borderColor: night.color.border
211
- },
212
- atomRowFiltered: {
213
- opacity: 0.45
214
- },
215
- atomDot: {
216
- width: 7,
217
- height: 7,
218
- borderRadius: 3.5
219
- },
220
- atomRowText: {
221
- flex: 1,
222
- fontSize: 12,
223
- fontWeight: "600",
224
- fontFamily: "monospace"
225
- },
226
- atomRowTextFiltered: {
227
- color: night.color.textTertiary,
228
- textDecorationLine: "line-through"
229
- },
230
- filteredLabel: {
231
- fontSize: 10,
232
- fontWeight: "500",
233
- color: night.color.textTertiary,
234
- fontFamily: "monospace"
235
- },
236
- addLabel: {
237
- fontSize: 10,
238
- fontWeight: "600",
239
- fontFamily: "monospace"
240
- },
241
- addInputWrapper: {
242
- paddingHorizontal: 16,
243
- paddingTop: 8,
244
- paddingBottom: 8
245
- },
246
- patternList: {
247
- paddingHorizontal: 16,
248
- paddingBottom: 16,
249
- gap: 8
250
- },
251
- patternRow: {
252
- flexDirection: "row",
253
- alignItems: "center",
254
- justifyContent: "space-between",
255
- paddingVertical: 10,
256
- paddingHorizontal: 12,
257
- backgroundColor: night.color.surfaceElevated,
258
- borderRadius: 8,
259
- borderWidth: 1,
260
- borderColor: night.color.border,
261
- gap: 8
262
- },
263
- patternText: {
264
- flex: 1,
265
- fontSize: 12,
266
- fontFamily: "monospace",
267
- color: night.color.text
268
- },
269
- howItWorksText: {
270
- fontSize: 11,
271
- color: night.color.textSecondary,
272
- lineHeight: 16,
273
- marginTop: 8,
274
- paddingHorizontal: 16,
275
- fontFamily: "monospace"
276
- },
277
- examplesContainer: {
278
- paddingTop: 8,
279
- paddingHorizontal: 16,
280
- paddingBottom: 16,
281
- borderTopWidth: 1,
282
- borderTopColor: night.color.border,
283
- marginTop: 12
284
- },
285
- examplesTitle: {
286
- fontSize: 10,
287
- fontWeight: "600",
288
- color: night.color.textTertiary,
289
- fontFamily: "monospace",
290
- letterSpacing: 0.5,
291
- marginBottom: 6
292
- },
293
- exampleItem: {
294
- fontSize: 10,
295
- color: night.color.textTertiary,
296
- fontFamily: "monospace",
297
- lineHeight: 16
298
- },
299
- emptyText: {
300
- fontSize: 11,
301
- color: night.color.textTertiary,
302
- paddingHorizontal: 16,
303
- paddingVertical: 12,
304
- fontFamily: "monospace"
305
- },
306
- patternInput: {
307
- borderWidth: 1,
308
- borderColor: night.color.accentBorder,
309
- borderRadius: 8,
310
- paddingHorizontal: 12,
311
- paddingVertical: 8,
312
- fontSize: 12,
313
- color: night.color.text,
314
- fontFamily: "monospace",
315
- backgroundColor: night.color.surfaceElevated
316
- }
317
- });
39
+ }