@buoy-gg/shared-ui 7.0.32 → 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 (237) hide show
  1. package/lib/commonjs/JsModal.js +70 -28
  2. package/lib/commonjs/hooks/index.js +26 -0
  3. package/lib/commonjs/hooks/safe-area-impl.js +1 -1
  4. package/lib/commonjs/hooks/useChangeLog.js +55 -0
  5. package/lib/commonjs/hooks/useEventStoreEvents.js +65 -0
  6. package/lib/commonjs/hooks/usePersistedState.js +45 -10
  7. package/lib/commonjs/index.js +143 -0
  8. package/lib/commonjs/storage/definePersistedSetting.js +67 -0
  9. package/lib/commonjs/storage/devToolsStorageKeys.js +12 -0
  10. package/lib/commonjs/storage/index.js +8 -1
  11. package/lib/commonjs/stores/ChangeLog.js +197 -0
  12. package/lib/commonjs/stores/createToolStore.js +175 -0
  13. package/lib/commonjs/stores/index.js +15 -1
  14. package/lib/commonjs/sync/toolSyncAdapter.js +63 -0
  15. package/lib/commonjs/sync/wireForm.js +172 -0
  16. package/lib/commonjs/tools/defineTool.js +79 -0
  17. package/lib/commonjs/ui/components/ChangeRow.js +110 -0
  18. package/lib/commonjs/ui/components/ChipStrip.js +94 -0
  19. package/lib/commonjs/ui/components/DetailViewToggle.js +130 -0
  20. package/lib/commonjs/ui/components/DevToolsCard.js +3 -1
  21. package/lib/commonjs/ui/components/EmptyState.js +10 -2
  22. package/lib/commonjs/ui/components/EntityFilterView.js +354 -0
  23. package/lib/commonjs/ui/components/ExportPreview.js +174 -0
  24. package/lib/commonjs/ui/components/InfoRow.js +90 -0
  25. package/lib/commonjs/ui/components/ModalHeader.js +40 -7
  26. package/lib/commonjs/ui/components/Pill.js +114 -0
  27. package/lib/commonjs/ui/components/ToggleRow.js +116 -0
  28. package/lib/commonjs/ui/components/ToolEmptyState.js +154 -0
  29. package/lib/commonjs/ui/components/ToolFooter.js +204 -0
  30. package/lib/commonjs/ui/components/WindowControls.js +8 -5
  31. package/lib/commonjs/ui/components/index.js +113 -1
  32. package/lib/commonjs/ui/index.js +36 -2
  33. package/lib/commonjs/ui/listPresets.js +43 -0
  34. package/lib/commonjs/ui/night/primitives.js +3 -1
  35. package/lib/commonjs/ui/otto/OttoSprite.js +510 -0
  36. package/lib/commonjs/ui/otto/index.js +38 -0
  37. package/lib/commonjs/ui/otto/ottoEngine.js +2734 -0
  38. package/lib/commonjs/ui/otto/ottoSheet.js +191 -0
  39. package/lib/commonjs/utils/snapshotProviderKit.js +167 -0
  40. package/lib/commonjs/utils/stateTools.js +160 -0
  41. package/lib/module/JsModal.js +70 -28
  42. package/lib/module/hooks/index.js +3 -1
  43. package/lib/module/hooks/safe-area-impl.js +1 -1
  44. package/lib/module/hooks/useChangeLog.js +50 -0
  45. package/lib/module/hooks/useEventStoreEvents.js +61 -0
  46. package/lib/module/hooks/usePersistedState.js +44 -10
  47. package/lib/module/index.js +11 -1
  48. package/lib/module/storage/definePersistedSetting.js +63 -0
  49. package/lib/module/storage/devToolsStorageKeys.js +12 -0
  50. package/lib/module/storage/index.js +2 -1
  51. package/lib/module/stores/ChangeLog.js +192 -0
  52. package/lib/module/stores/createToolStore.js +171 -0
  53. package/lib/module/stores/index.js +3 -1
  54. package/lib/module/sync/toolSyncAdapter.js +58 -0
  55. package/lib/module/sync/wireForm.js +159 -0
  56. package/lib/module/tools/defineTool.js +74 -0
  57. package/lib/module/ui/components/ChangeRow.js +105 -0
  58. package/lib/module/ui/components/ChipStrip.js +91 -0
  59. package/lib/module/ui/components/DetailViewToggle.js +125 -0
  60. package/lib/module/ui/components/DevToolsCard.js +3 -1
  61. package/lib/module/ui/components/EmptyState.js +10 -2
  62. package/lib/module/ui/components/EntityFilterView.js +350 -0
  63. package/lib/module/ui/components/ExportPreview.js +169 -0
  64. package/lib/module/ui/components/InfoRow.js +86 -0
  65. package/lib/module/ui/components/ModalHeader.js +40 -7
  66. package/lib/module/ui/components/Pill.js +110 -0
  67. package/lib/module/ui/components/ToggleRow.js +112 -0
  68. package/lib/module/ui/components/ToolEmptyState.js +149 -0
  69. package/lib/module/ui/components/ToolFooter.js +196 -0
  70. package/lib/module/ui/components/WindowControls.js +8 -5
  71. package/lib/module/ui/components/index.js +13 -1
  72. package/lib/module/ui/index.js +7 -1
  73. package/lib/module/ui/listPresets.js +39 -0
  74. package/lib/module/ui/night/primitives.js +3 -1
  75. package/lib/module/ui/otto/OttoSprite.js +496 -0
  76. package/lib/module/ui/otto/index.js +20 -0
  77. package/lib/module/ui/otto/ottoEngine.js +2726 -0
  78. package/lib/module/ui/otto/ottoSheet.js +180 -0
  79. package/lib/module/utils/snapshotProviderKit.js +156 -0
  80. package/lib/module/utils/stateTools.js +154 -0
  81. package/lib/typescript/commonjs/JsModal.d.ts.map +1 -1
  82. package/lib/typescript/commonjs/hooks/index.d.ts +3 -1
  83. package/lib/typescript/commonjs/hooks/index.d.ts.map +1 -1
  84. package/lib/typescript/commonjs/hooks/safe-area-impl.d.ts +1 -1
  85. package/lib/typescript/commonjs/hooks/useChangeLog.d.ts +38 -0
  86. package/lib/typescript/commonjs/hooks/useChangeLog.d.ts.map +1 -0
  87. package/lib/typescript/commonjs/hooks/useEventStoreEvents.d.ts +25 -0
  88. package/lib/typescript/commonjs/hooks/useEventStoreEvents.d.ts.map +1 -0
  89. package/lib/typescript/commonjs/hooks/usePersistedState.d.ts +34 -5
  90. package/lib/typescript/commonjs/hooks/usePersistedState.d.ts.map +1 -1
  91. package/lib/typescript/commonjs/index.d.ts +6 -1
  92. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  93. package/lib/typescript/commonjs/storage/definePersistedSetting.d.ts +39 -0
  94. package/lib/typescript/commonjs/storage/definePersistedSetting.d.ts.map +1 -0
  95. package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts +12 -0
  96. package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts.map +1 -1
  97. package/lib/typescript/commonjs/storage/index.d.ts +1 -0
  98. package/lib/typescript/commonjs/storage/index.d.ts.map +1 -1
  99. package/lib/typescript/commonjs/stores/ChangeLog.d.ts +100 -0
  100. package/lib/typescript/commonjs/stores/ChangeLog.d.ts.map +1 -0
  101. package/lib/typescript/commonjs/stores/createToolStore.d.ts +92 -0
  102. package/lib/typescript/commonjs/stores/createToolStore.d.ts.map +1 -0
  103. package/lib/typescript/commonjs/stores/index.d.ts +2 -0
  104. package/lib/typescript/commonjs/stores/index.d.ts.map +1 -1
  105. package/lib/typescript/commonjs/sync/toolSyncAdapter.d.ts +66 -0
  106. package/lib/typescript/commonjs/sync/toolSyncAdapter.d.ts.map +1 -0
  107. package/lib/typescript/commonjs/sync/wireForm.d.ts +100 -0
  108. package/lib/typescript/commonjs/sync/wireForm.d.ts.map +1 -0
  109. package/lib/typescript/commonjs/tools/defineTool.d.ts +100 -0
  110. package/lib/typescript/commonjs/tools/defineTool.d.ts.map +1 -0
  111. package/lib/typescript/commonjs/ui/components/ChangeRow.d.ts +52 -0
  112. package/lib/typescript/commonjs/ui/components/ChangeRow.d.ts.map +1 -0
  113. package/lib/typescript/commonjs/ui/components/ChipStrip.d.ts +41 -0
  114. package/lib/typescript/commonjs/ui/components/ChipStrip.d.ts.map +1 -0
  115. package/lib/typescript/commonjs/ui/components/DetailViewToggle.d.ts +36 -0
  116. package/lib/typescript/commonjs/ui/components/DetailViewToggle.d.ts.map +1 -0
  117. package/lib/typescript/commonjs/ui/components/DevToolsCard.d.ts +8 -1
  118. package/lib/typescript/commonjs/ui/components/DevToolsCard.d.ts.map +1 -1
  119. package/lib/typescript/commonjs/ui/components/EmptyState.d.ts +14 -1
  120. package/lib/typescript/commonjs/ui/components/EmptyState.d.ts.map +1 -1
  121. package/lib/typescript/commonjs/ui/components/EntityFilterView.d.ts +51 -0
  122. package/lib/typescript/commonjs/ui/components/EntityFilterView.d.ts.map +1 -0
  123. package/lib/typescript/commonjs/ui/components/ExportPreview.d.ts +48 -0
  124. package/lib/typescript/commonjs/ui/components/ExportPreview.d.ts.map +1 -0
  125. package/lib/typescript/commonjs/ui/components/InfoRow.d.ts +33 -0
  126. package/lib/typescript/commonjs/ui/components/InfoRow.d.ts.map +1 -0
  127. package/lib/typescript/commonjs/ui/components/ModalHeader.d.ts +31 -1
  128. package/lib/typescript/commonjs/ui/components/ModalHeader.d.ts.map +1 -1
  129. package/lib/typescript/commonjs/ui/components/Pill.d.ts +38 -0
  130. package/lib/typescript/commonjs/ui/components/Pill.d.ts.map +1 -0
  131. package/lib/typescript/commonjs/ui/components/ToggleRow.d.ts +33 -0
  132. package/lib/typescript/commonjs/ui/components/ToggleRow.d.ts.map +1 -0
  133. package/lib/typescript/commonjs/ui/components/ToolEmptyState.d.ts +113 -0
  134. package/lib/typescript/commonjs/ui/components/ToolEmptyState.d.ts.map +1 -0
  135. package/lib/typescript/commonjs/ui/components/ToolFooter.d.ts +69 -0
  136. package/lib/typescript/commonjs/ui/components/ToolFooter.d.ts.map +1 -0
  137. package/lib/typescript/commonjs/ui/components/WindowControls.d.ts +7 -1
  138. package/lib/typescript/commonjs/ui/components/WindowControls.d.ts.map +1 -1
  139. package/lib/typescript/commonjs/ui/components/index.d.ts +11 -0
  140. package/lib/typescript/commonjs/ui/components/index.d.ts.map +1 -1
  141. package/lib/typescript/commonjs/ui/index.d.ts +2 -0
  142. package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
  143. package/lib/typescript/commonjs/ui/listPresets.d.ts +28 -0
  144. package/lib/typescript/commonjs/ui/listPresets.d.ts.map +1 -0
  145. package/lib/typescript/commonjs/ui/night/primitives.d.ts +3 -1
  146. package/lib/typescript/commonjs/ui/night/primitives.d.ts.map +1 -1
  147. package/lib/typescript/commonjs/ui/otto/OttoSprite.d.ts +103 -0
  148. package/lib/typescript/commonjs/ui/otto/OttoSprite.d.ts.map +1 -0
  149. package/lib/typescript/commonjs/ui/otto/index.d.ts +19 -0
  150. package/lib/typescript/commonjs/ui/otto/index.d.ts.map +1 -0
  151. package/lib/typescript/commonjs/ui/otto/ottoEngine.d.ts +2205 -0
  152. package/lib/typescript/commonjs/ui/otto/ottoEngine.d.ts.map +1 -0
  153. package/lib/typescript/commonjs/ui/otto/ottoSheet.d.ts +73 -0
  154. package/lib/typescript/commonjs/ui/otto/ottoSheet.d.ts.map +1 -0
  155. package/lib/typescript/commonjs/utils/snapshotProviderKit.d.ts +81 -0
  156. package/lib/typescript/commonjs/utils/snapshotProviderKit.d.ts.map +1 -0
  157. package/lib/typescript/commonjs/utils/stateTools.d.ts +44 -0
  158. package/lib/typescript/commonjs/utils/stateTools.d.ts.map +1 -0
  159. package/lib/typescript/module/JsModal.d.ts.map +1 -1
  160. package/lib/typescript/module/hooks/index.d.ts +3 -1
  161. package/lib/typescript/module/hooks/index.d.ts.map +1 -1
  162. package/lib/typescript/module/hooks/safe-area-impl.d.ts +1 -1
  163. package/lib/typescript/module/hooks/useChangeLog.d.ts +38 -0
  164. package/lib/typescript/module/hooks/useChangeLog.d.ts.map +1 -0
  165. package/lib/typescript/module/hooks/useEventStoreEvents.d.ts +25 -0
  166. package/lib/typescript/module/hooks/useEventStoreEvents.d.ts.map +1 -0
  167. package/lib/typescript/module/hooks/usePersistedState.d.ts +34 -5
  168. package/lib/typescript/module/hooks/usePersistedState.d.ts.map +1 -1
  169. package/lib/typescript/module/index.d.ts +6 -1
  170. package/lib/typescript/module/index.d.ts.map +1 -1
  171. package/lib/typescript/module/storage/definePersistedSetting.d.ts +39 -0
  172. package/lib/typescript/module/storage/definePersistedSetting.d.ts.map +1 -0
  173. package/lib/typescript/module/storage/devToolsStorageKeys.d.ts +12 -0
  174. package/lib/typescript/module/storage/devToolsStorageKeys.d.ts.map +1 -1
  175. package/lib/typescript/module/storage/index.d.ts +1 -0
  176. package/lib/typescript/module/storage/index.d.ts.map +1 -1
  177. package/lib/typescript/module/stores/ChangeLog.d.ts +100 -0
  178. package/lib/typescript/module/stores/ChangeLog.d.ts.map +1 -0
  179. package/lib/typescript/module/stores/createToolStore.d.ts +92 -0
  180. package/lib/typescript/module/stores/createToolStore.d.ts.map +1 -0
  181. package/lib/typescript/module/stores/index.d.ts +2 -0
  182. package/lib/typescript/module/stores/index.d.ts.map +1 -1
  183. package/lib/typescript/module/sync/toolSyncAdapter.d.ts +66 -0
  184. package/lib/typescript/module/sync/toolSyncAdapter.d.ts.map +1 -0
  185. package/lib/typescript/module/sync/wireForm.d.ts +100 -0
  186. package/lib/typescript/module/sync/wireForm.d.ts.map +1 -0
  187. package/lib/typescript/module/tools/defineTool.d.ts +100 -0
  188. package/lib/typescript/module/tools/defineTool.d.ts.map +1 -0
  189. package/lib/typescript/module/ui/components/ChangeRow.d.ts +52 -0
  190. package/lib/typescript/module/ui/components/ChangeRow.d.ts.map +1 -0
  191. package/lib/typescript/module/ui/components/ChipStrip.d.ts +41 -0
  192. package/lib/typescript/module/ui/components/ChipStrip.d.ts.map +1 -0
  193. package/lib/typescript/module/ui/components/DetailViewToggle.d.ts +36 -0
  194. package/lib/typescript/module/ui/components/DetailViewToggle.d.ts.map +1 -0
  195. package/lib/typescript/module/ui/components/DevToolsCard.d.ts +8 -1
  196. package/lib/typescript/module/ui/components/DevToolsCard.d.ts.map +1 -1
  197. package/lib/typescript/module/ui/components/EmptyState.d.ts +14 -1
  198. package/lib/typescript/module/ui/components/EmptyState.d.ts.map +1 -1
  199. package/lib/typescript/module/ui/components/EntityFilterView.d.ts +51 -0
  200. package/lib/typescript/module/ui/components/EntityFilterView.d.ts.map +1 -0
  201. package/lib/typescript/module/ui/components/ExportPreview.d.ts +48 -0
  202. package/lib/typescript/module/ui/components/ExportPreview.d.ts.map +1 -0
  203. package/lib/typescript/module/ui/components/InfoRow.d.ts +33 -0
  204. package/lib/typescript/module/ui/components/InfoRow.d.ts.map +1 -0
  205. package/lib/typescript/module/ui/components/ModalHeader.d.ts +31 -1
  206. package/lib/typescript/module/ui/components/ModalHeader.d.ts.map +1 -1
  207. package/lib/typescript/module/ui/components/Pill.d.ts +38 -0
  208. package/lib/typescript/module/ui/components/Pill.d.ts.map +1 -0
  209. package/lib/typescript/module/ui/components/ToggleRow.d.ts +33 -0
  210. package/lib/typescript/module/ui/components/ToggleRow.d.ts.map +1 -0
  211. package/lib/typescript/module/ui/components/ToolEmptyState.d.ts +113 -0
  212. package/lib/typescript/module/ui/components/ToolEmptyState.d.ts.map +1 -0
  213. package/lib/typescript/module/ui/components/ToolFooter.d.ts +69 -0
  214. package/lib/typescript/module/ui/components/ToolFooter.d.ts.map +1 -0
  215. package/lib/typescript/module/ui/components/WindowControls.d.ts +7 -1
  216. package/lib/typescript/module/ui/components/WindowControls.d.ts.map +1 -1
  217. package/lib/typescript/module/ui/components/index.d.ts +11 -0
  218. package/lib/typescript/module/ui/components/index.d.ts.map +1 -1
  219. package/lib/typescript/module/ui/index.d.ts +2 -0
  220. package/lib/typescript/module/ui/index.d.ts.map +1 -1
  221. package/lib/typescript/module/ui/listPresets.d.ts +28 -0
  222. package/lib/typescript/module/ui/listPresets.d.ts.map +1 -0
  223. package/lib/typescript/module/ui/night/primitives.d.ts +3 -1
  224. package/lib/typescript/module/ui/night/primitives.d.ts.map +1 -1
  225. package/lib/typescript/module/ui/otto/OttoSprite.d.ts +103 -0
  226. package/lib/typescript/module/ui/otto/OttoSprite.d.ts.map +1 -0
  227. package/lib/typescript/module/ui/otto/index.d.ts +19 -0
  228. package/lib/typescript/module/ui/otto/index.d.ts.map +1 -0
  229. package/lib/typescript/module/ui/otto/ottoEngine.d.ts +2205 -0
  230. package/lib/typescript/module/ui/otto/ottoEngine.d.ts.map +1 -0
  231. package/lib/typescript/module/ui/otto/ottoSheet.d.ts +73 -0
  232. package/lib/typescript/module/ui/otto/ottoSheet.d.ts.map +1 -0
  233. package/lib/typescript/module/utils/snapshotProviderKit.d.ts +81 -0
  234. package/lib/typescript/module/utils/snapshotProviderKit.d.ts.map +1 -0
  235. package/lib/typescript/module/utils/stateTools.d.ts +44 -0
  236. package/lib/typescript/module/utils/stateTools.d.ts.map +1 -0
  237. package/package.json +4 -4
@@ -0,0 +1,350 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * EntityFilterView — the "hide these by name" filter screen the state tools
5
+ * share: a list of registered entities (stores, atoms) you can tap to hide,
6
+ * the active name patterns with a remove ✕, an add-pattern affordance, and
7
+ * a how-it-works card.
8
+ *
9
+ * zustand and jotai each shipped their own copy (~370 lines apiece). The
10
+ * tool supplies the entities, the nouns and the testID prefix; the screen
11
+ * is drawn once.
12
+ *
13
+ * testID convention (unchanged from zustand's):
14
+ * `${prefix}-filters-scroll`, `${prefix}-filters-${entityKey}-count`,
15
+ * `${prefix}-filters-${entityKey}-${slug(name)}`, `${prefix}-filters-count`,
16
+ * `${prefix}-filters-add-open`, `${prefix}-filters-add-input`,
17
+ * `${prefix}-filters-chip-${slug(pattern)}`.
18
+ */
19
+
20
+ import { useState } from "react";
21
+ import { ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native";
22
+ import { Filter, X } from "../../icons/index.js";
23
+ import { night } from "../night/nightTheme.js";
24
+ import { SectionHeader } from "./SectionHeader.js";
25
+ import { AddFilterButton, AddFilterInput } from "./FilterComponents.js";
26
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
27
+ /** True if any active pattern hides this entity. */
28
+ function isHidden(entity, ignoredPatterns) {
29
+ return Array.from(ignoredPatterns).some(p => entity.name.toLowerCase().includes(p.toLowerCase()));
30
+ }
31
+
32
+ /** The entity color for a pattern that exactly names a registered entity. */
33
+ function colorForPattern(pattern, entities) {
34
+ const match = entities.find(e => e.name.toLowerCase() === pattern.toLowerCase());
35
+ return match ? match.color : null;
36
+ }
37
+ export function EntityFilterView({
38
+ entities,
39
+ ignoredPatterns,
40
+ onTogglePattern,
41
+ onAddPattern,
42
+ entityNoun,
43
+ entitySingular,
44
+ entityKey,
45
+ testIDPrefix,
46
+ slug,
47
+ howItWorks,
48
+ examples,
49
+ addPlaceholder,
50
+ emptyMessage
51
+ }) {
52
+ const [showAddInput, setShowAddInput] = useState(false);
53
+ const [inputValue, setInputValue] = useState("");
54
+ const handleAddPattern = () => {
55
+ const trimmed = inputValue.trim();
56
+ if (trimmed) {
57
+ onAddPattern(trimmed);
58
+ setInputValue("");
59
+ setShowAddInput(false);
60
+ }
61
+ };
62
+ return /*#__PURE__*/_jsxs(ScrollView, {
63
+ style: styles.container,
64
+ contentContainerStyle: styles.scrollContent,
65
+ showsVerticalScrollIndicator: false,
66
+ nestedScrollEnabled: true,
67
+ testID: `${testIDPrefix}-filters-scroll`,
68
+ children: [entities.length === 0 && emptyMessage ? /*#__PURE__*/_jsxs(View, {
69
+ style: styles.section,
70
+ children: [/*#__PURE__*/_jsx(SectionHeader, {
71
+ children: /*#__PURE__*/_jsxs(SectionHeader.Title, {
72
+ children: ["REGISTERED ", entityNoun]
73
+ })
74
+ }), /*#__PURE__*/_jsx(Text, {
75
+ style: styles.emptyText,
76
+ testID: `${testIDPrefix}-filters-${entityKey}s-empty`,
77
+ children: emptyMessage
78
+ })]
79
+ }) : null, entities.length > 0 && /*#__PURE__*/_jsxs(View, {
80
+ style: styles.section,
81
+ children: [/*#__PURE__*/_jsxs(SectionHeader, {
82
+ children: [/*#__PURE__*/_jsxs(SectionHeader.Title, {
83
+ children: ["REGISTERED ", entityNoun]
84
+ }), /*#__PURE__*/_jsx(SectionHeader.Badge, {
85
+ count: entities.length,
86
+ color: night.color.accent,
87
+ testID: `${testIDPrefix}-filters-${entityKey}-count`
88
+ })]
89
+ }), /*#__PURE__*/_jsx(ScrollView, {
90
+ style: styles.entityList,
91
+ contentContainerStyle: styles.entityListContent,
92
+ showsVerticalScrollIndicator: true,
93
+ nestedScrollEnabled: true,
94
+ testID: `${testIDPrefix}-filters-${entityKey}-list`,
95
+ children: entities.map(entity => {
96
+ const hidden = isHidden(entity, ignoredPatterns);
97
+ return /*#__PURE__*/_jsxs(TouchableOpacity, {
98
+ style: [styles.entityRow, hidden && styles.entityRowHidden],
99
+ onPress: () => onAddPattern(entity.name),
100
+ disabled: hidden,
101
+ testID: `${testIDPrefix}-filters-${entityKey}-${slug(entity.name)}`,
102
+ accessibilityRole: "button",
103
+ accessibilityLabel: `Hide ${entity.name}`,
104
+ accessibilityState: {
105
+ disabled: hidden
106
+ },
107
+ children: [/*#__PURE__*/_jsx(View, {
108
+ style: [styles.dot, {
109
+ backgroundColor: hidden ? night.color.textTertiary : entity.color
110
+ }]
111
+ }), /*#__PURE__*/_jsx(Text, {
112
+ style: [styles.entityText, hidden ? styles.entityTextHidden : {
113
+ color: entity.color
114
+ }],
115
+ numberOfLines: 1,
116
+ children: entity.name
117
+ }), hidden ? /*#__PURE__*/_jsx(Text, {
118
+ style: styles.hiddenLabel,
119
+ children: "hidden"
120
+ }) : /*#__PURE__*/_jsx(Text, {
121
+ style: [styles.addLabel, {
122
+ color: entity.color + "99"
123
+ }],
124
+ children: "+ hide"
125
+ })]
126
+ }, entity.name);
127
+ })
128
+ })]
129
+ }), /*#__PURE__*/_jsxs(View, {
130
+ style: styles.section,
131
+ children: [/*#__PURE__*/_jsxs(SectionHeader, {
132
+ children: [/*#__PURE__*/_jsx(SectionHeader.Icon, {
133
+ icon: Filter,
134
+ color: night.color.accent,
135
+ size: 12
136
+ }), /*#__PURE__*/_jsxs(SectionHeader.Title, {
137
+ children: [entitySingular.toUpperCase(), " NAME FILTERS"]
138
+ }), ignoredPatterns.size > 0 && /*#__PURE__*/_jsx(SectionHeader.Badge, {
139
+ count: ignoredPatterns.size,
140
+ color: night.color.accent,
141
+ testID: `${testIDPrefix}-filters-count`
142
+ })]
143
+ }), /*#__PURE__*/_jsx(View, {
144
+ style: styles.addInputWrapper,
145
+ children: !showAddInput ? /*#__PURE__*/_jsx(AddFilterButton, {
146
+ onPress: () => setShowAddInput(true),
147
+ color: night.color.accent,
148
+ label: `Add ${entitySingular} name pattern`,
149
+ testID: `${testIDPrefix}-filters-add-open`
150
+ }) : /*#__PURE__*/_jsx(AddFilterInput, {
151
+ value: inputValue,
152
+ onChange: setInputValue,
153
+ onSubmit: handleAddPattern,
154
+ onCancel: () => {
155
+ setShowAddInput(false);
156
+ setInputValue("");
157
+ },
158
+ placeholder: addPlaceholder ?? `Enter ${entitySingular} name pattern to hide...`,
159
+ color: night.color.accent,
160
+ testID: `${testIDPrefix}-filters-add-input`
161
+ })
162
+ }), ignoredPatterns.size > 0 && /*#__PURE__*/_jsx(View, {
163
+ style: styles.patternList,
164
+ children: Array.from(ignoredPatterns).map(pattern => {
165
+ const color = colorForPattern(pattern, entities);
166
+ return /*#__PURE__*/_jsxs(TouchableOpacity, {
167
+ style: styles.patternRow,
168
+ onPress: () => onTogglePattern(pattern),
169
+ activeOpacity: 0.8,
170
+ testID: `${testIDPrefix}-filters-chip-${slug(pattern)}`,
171
+ accessibilityRole: "button",
172
+ accessibilityLabel: `Remove filter ${pattern}`,
173
+ children: [color ? /*#__PURE__*/_jsx(View, {
174
+ style: [styles.dot, {
175
+ backgroundColor: color
176
+ }]
177
+ }) : null, /*#__PURE__*/_jsx(Text, {
178
+ style: [styles.patternText, color ? {
179
+ color
180
+ } : null],
181
+ numberOfLines: 1,
182
+ children: pattern
183
+ }), /*#__PURE__*/_jsx(X, {
184
+ size: 12,
185
+ color: night.color.accent + "80"
186
+ })]
187
+ }, pattern);
188
+ })
189
+ })]
190
+ }), /*#__PURE__*/_jsxs(View, {
191
+ style: styles.section,
192
+ children: [/*#__PURE__*/_jsxs(SectionHeader, {
193
+ children: [/*#__PURE__*/_jsx(SectionHeader.Icon, {
194
+ icon: Filter,
195
+ color: night.color.textSecondary,
196
+ size: 12
197
+ }), /*#__PURE__*/_jsx(SectionHeader.Title, {
198
+ children: "HOW EVENT FILTERS WORK"
199
+ })]
200
+ }), /*#__PURE__*/_jsx(Text, {
201
+ style: styles.howItWorksText,
202
+ children: howItWorks
203
+ }), /*#__PURE__*/_jsxs(View, {
204
+ style: styles.examplesContainer,
205
+ children: [/*#__PURE__*/_jsx(Text, {
206
+ style: styles.examplesTitle,
207
+ children: "EXAMPLES:"
208
+ }), examples.map(ex => /*#__PURE__*/_jsx(Text, {
209
+ style: styles.exampleItem,
210
+ children: ex
211
+ }, ex))]
212
+ })]
213
+ })]
214
+ });
215
+ }
216
+ const styles = StyleSheet.create({
217
+ container: {
218
+ flex: 1,
219
+ // Transparent so the night sheet's star field shows through.
220
+ backgroundColor: "transparent"
221
+ },
222
+ scrollContent: {
223
+ paddingTop: 16,
224
+ paddingHorizontal: 16,
225
+ paddingBottom: 24,
226
+ gap: 16
227
+ },
228
+ section: {
229
+ backgroundColor: night.color.surface,
230
+ borderRadius: 16,
231
+ borderWidth: 1,
232
+ borderColor: night.color.border,
233
+ overflow: "hidden"
234
+ },
235
+ entityList: {
236
+ maxHeight: 180
237
+ },
238
+ entityListContent: {
239
+ paddingHorizontal: 16,
240
+ paddingTop: 8,
241
+ paddingBottom: 16,
242
+ gap: 10
243
+ },
244
+ entityRow: {
245
+ flexDirection: "row",
246
+ alignItems: "center",
247
+ gap: 10,
248
+ paddingVertical: 10,
249
+ paddingHorizontal: 12,
250
+ backgroundColor: night.color.surfaceElevated,
251
+ borderRadius: 8,
252
+ borderWidth: 1,
253
+ borderColor: night.color.border
254
+ },
255
+ entityRowHidden: {
256
+ opacity: 0.45
257
+ },
258
+ dot: {
259
+ width: 7,
260
+ height: 7,
261
+ borderRadius: 3.5
262
+ },
263
+ entityText: {
264
+ flex: 1,
265
+ fontSize: 12,
266
+ fontWeight: "600",
267
+ fontFamily: "monospace"
268
+ },
269
+ entityTextHidden: {
270
+ color: night.color.textTertiary,
271
+ textDecorationLine: "line-through"
272
+ },
273
+ hiddenLabel: {
274
+ fontSize: 10,
275
+ fontWeight: "500",
276
+ color: night.color.textTertiary,
277
+ fontFamily: "monospace"
278
+ },
279
+ addLabel: {
280
+ fontSize: 10,
281
+ fontWeight: "600",
282
+ fontFamily: "monospace"
283
+ },
284
+ addInputWrapper: {
285
+ paddingHorizontal: 16,
286
+ paddingTop: 8,
287
+ paddingBottom: 8
288
+ },
289
+ patternList: {
290
+ paddingHorizontal: 16,
291
+ paddingBottom: 16,
292
+ gap: 8
293
+ },
294
+ patternRow: {
295
+ flexDirection: "row",
296
+ alignItems: "center",
297
+ justifyContent: "space-between",
298
+ paddingVertical: 10,
299
+ paddingHorizontal: 12,
300
+ backgroundColor: night.color.surfaceElevated,
301
+ borderRadius: 8,
302
+ borderWidth: 1,
303
+ borderColor: night.color.border,
304
+ gap: 8
305
+ },
306
+ patternText: {
307
+ flex: 1,
308
+ fontSize: 12,
309
+ fontFamily: "monospace",
310
+ color: night.color.text
311
+ },
312
+ emptyText: {
313
+ fontSize: 11,
314
+ color: night.color.textTertiary,
315
+ paddingHorizontal: 16,
316
+ paddingTop: 8,
317
+ paddingBottom: 16,
318
+ fontFamily: "monospace"
319
+ },
320
+ howItWorksText: {
321
+ fontSize: 11,
322
+ color: night.color.textSecondary,
323
+ lineHeight: 16,
324
+ marginTop: 8,
325
+ paddingHorizontal: 16,
326
+ fontFamily: "monospace"
327
+ },
328
+ examplesContainer: {
329
+ paddingTop: 8,
330
+ paddingHorizontal: 16,
331
+ paddingBottom: 16,
332
+ borderTopWidth: 1,
333
+ borderTopColor: night.color.border,
334
+ marginTop: 12
335
+ },
336
+ examplesTitle: {
337
+ fontSize: 10,
338
+ fontWeight: "600",
339
+ color: night.color.textTertiary,
340
+ fontFamily: "monospace",
341
+ letterSpacing: 0.5,
342
+ marginBottom: 6
343
+ },
344
+ exampleItem: {
345
+ fontSize: 10,
346
+ color: night.color.textTertiary,
347
+ fontFamily: "monospace",
348
+ lineHeight: 16
349
+ }
350
+ });
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * ExportPreview — the collapsible "what will be copied" panel at the bottom
5
+ * of a copy-settings screen.
6
+ *
7
+ * Collapsed, it is a card: an eye icon, "Show Preview", a one-line summary
8
+ * ("14 events · ~12.3 KB (mock data)"), a chevron — and, when the estimated
9
+ * payload is big, an amber or red size warning under it. Expanded, it is a
10
+ * "Hide Preview" bar over whatever the tool renders (a DataViewer for JSON,
11
+ * a mono text block otherwise).
12
+ *
13
+ * network, events and highlight-updates each drew this (~120 lines apiece).
14
+ * Tools keep their own summary string, warning copy and body; the chrome
15
+ * and the size-threshold ladder live here.
16
+ */
17
+
18
+ import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
19
+ import { AlertTriangle, ChevronDown, ChevronUp, Eye } from "../../icons/index.js";
20
+ import { night } from "../night/nightTheme.js";
21
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
22
+ /** The two-step ladder every copy view used (thresholds differ per tool). */
23
+ export function sizeWarningLevel(bytes, thresholds) {
24
+ if (bytes >= thresholds.danger) return "danger";
25
+ if (bytes >= thresholds.warning) return "warning";
26
+ return "none";
27
+ }
28
+ const DEFAULT_WARNING = {
29
+ warning: "Large payload — preview may be slow",
30
+ danger: "Very large payload — may cause performance issues"
31
+ };
32
+ export function ExportPreview({
33
+ expanded,
34
+ onExpandedChange,
35
+ summary,
36
+ warningLevel = "none",
37
+ warningText = DEFAULT_WARNING,
38
+ testIDs,
39
+ renderBody
40
+ }) {
41
+ if (!expanded) {
42
+ const warningColor = warningLevel === "danger" ? night.color.danger : warningLevel === "warning" ? night.color.warning : night.color.textSecondary;
43
+ return /*#__PURE__*/_jsxs(View, {
44
+ style: styles.collapsed,
45
+ children: [/*#__PURE__*/_jsx(TouchableOpacity, {
46
+ style: styles.expandButton,
47
+ onPress: () => onExpandedChange(true),
48
+ testID: testIDs?.expand,
49
+ accessibilityRole: "button",
50
+ accessibilityLabel: "Show export preview",
51
+ children: /*#__PURE__*/_jsxs(View, {
52
+ style: styles.expandButtonContent,
53
+ children: [/*#__PURE__*/_jsx(Eye, {
54
+ size: 16,
55
+ color: night.color.info
56
+ }), /*#__PURE__*/_jsxs(View, {
57
+ style: styles.expandButtonTextContainer,
58
+ children: [/*#__PURE__*/_jsx(Text, {
59
+ style: styles.expandButtonTitle,
60
+ children: "Show Preview"
61
+ }), /*#__PURE__*/_jsx(Text, {
62
+ style: styles.expandButtonSubtitle,
63
+ testID: testIDs?.summary,
64
+ children: summary
65
+ })]
66
+ }), /*#__PURE__*/_jsx(ChevronDown, {
67
+ size: 16,
68
+ color: night.color.textTertiary
69
+ })]
70
+ })
71
+ }), warningLevel !== "none" ? /*#__PURE__*/_jsxs(View, {
72
+ style: [styles.sizeWarning, warningLevel === "danger" && styles.sizeWarningDanger],
73
+ testID: testIDs?.warning,
74
+ children: [/*#__PURE__*/_jsx(AlertTriangle, {
75
+ size: 12,
76
+ color: warningColor
77
+ }), /*#__PURE__*/_jsx(Text, {
78
+ style: [styles.sizeWarningText, {
79
+ color: warningColor
80
+ }],
81
+ children: warningLevel === "danger" ? warningText.danger : warningText.warning
82
+ })]
83
+ }) : null]
84
+ });
85
+ }
86
+ return /*#__PURE__*/_jsxs(View, {
87
+ children: [/*#__PURE__*/_jsxs(TouchableOpacity, {
88
+ style: styles.collapseButton,
89
+ onPress: () => onExpandedChange(false),
90
+ testID: testIDs?.collapse,
91
+ accessibilityRole: "button",
92
+ accessibilityLabel: "Hide export preview",
93
+ children: [/*#__PURE__*/_jsx(Text, {
94
+ style: styles.collapseButtonText,
95
+ children: "Hide Preview"
96
+ }), /*#__PURE__*/_jsx(ChevronUp, {
97
+ size: 14,
98
+ color: night.color.textSecondary
99
+ })]
100
+ }), renderBody()]
101
+ });
102
+ }
103
+ const styles = StyleSheet.create({
104
+ collapsed: {
105
+ gap: 8
106
+ },
107
+ expandButton: {
108
+ backgroundColor: night.color.surfaceElevated,
109
+ borderRadius: 8,
110
+ borderWidth: 1,
111
+ borderColor: night.color.border,
112
+ padding: 12
113
+ },
114
+ expandButtonContent: {
115
+ flexDirection: "row",
116
+ alignItems: "center",
117
+ gap: 10
118
+ },
119
+ expandButtonTextContainer: {
120
+ flex: 1
121
+ },
122
+ expandButtonTitle: {
123
+ fontSize: 13,
124
+ fontWeight: "600",
125
+ color: night.color.text
126
+ },
127
+ expandButtonSubtitle: {
128
+ fontSize: 11,
129
+ color: night.color.textSecondary,
130
+ marginTop: 2
131
+ },
132
+ collapseButton: {
133
+ flexDirection: "row",
134
+ alignItems: "center",
135
+ justifyContent: "center",
136
+ gap: 6,
137
+ paddingVertical: 8,
138
+ marginBottom: 8,
139
+ backgroundColor: night.color.surfaceElevated,
140
+ borderRadius: 6,
141
+ borderWidth: 1,
142
+ borderColor: night.color.border
143
+ },
144
+ collapseButtonText: {
145
+ fontSize: 12,
146
+ fontWeight: "500",
147
+ color: night.color.textSecondary
148
+ },
149
+ sizeWarning: {
150
+ flexDirection: "row",
151
+ alignItems: "center",
152
+ gap: 6,
153
+ paddingHorizontal: 10,
154
+ paddingVertical: 6,
155
+ backgroundColor: night.color.warningSoft,
156
+ borderRadius: 6,
157
+ borderWidth: 1,
158
+ borderColor: night.color.warning + "30"
159
+ },
160
+ sizeWarningDanger: {
161
+ backgroundColor: night.color.dangerSoft,
162
+ borderColor: night.color.danger + "30"
163
+ },
164
+ sizeWarningText: {
165
+ fontSize: 11,
166
+ fontWeight: "500",
167
+ flex: 1
168
+ }
169
+ });
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * InfoRow — the label / value line of every detail screen.
5
+ *
6
+ * Thirteen tools hand-rolled this (redux and zustand byte-for-byte). The
7
+ * night-theme recipe below is theirs: 11 px, tertiary label on the left,
8
+ * right-aligned value that truncates in the MIDDLE so both ends of an id or
9
+ * a path stay readable, optional monospace, optional color.
10
+ *
11
+ * `ellipsizeMode="middle"` truncates the RENDERED text and iOS reports the
12
+ * truncated string back, so anything a test reads off one of these rows has
13
+ * to be short enough to fit on the line.
14
+ */
15
+
16
+ import { StyleSheet, Text, View } from "react-native";
17
+ import { night } from "../night/nightTheme.js";
18
+ import { CopyButton } from "./CopyButton.js";
19
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
+ export function InfoRow({
21
+ label,
22
+ value,
23
+ valueColor,
24
+ mono = false,
25
+ copyable = false,
26
+ numberOfLines = 1,
27
+ testID,
28
+ style,
29
+ labelStyle,
30
+ valueStyle
31
+ }) {
32
+ const isText = typeof value === "string" || typeof value === "number";
33
+ return /*#__PURE__*/_jsxs(View, {
34
+ style: [styles.row, style],
35
+ children: [/*#__PURE__*/_jsx(Text, {
36
+ style: [styles.label, labelStyle],
37
+ numberOfLines: 1,
38
+ children: label
39
+ }), isText ? /*#__PURE__*/_jsx(Text, {
40
+ testID: testID,
41
+ style: [styles.value, mono && styles.valueMono, valueColor ? {
42
+ color: valueColor
43
+ } : undefined, valueStyle],
44
+ numberOfLines: numberOfLines,
45
+ ellipsizeMode: "middle",
46
+ children: String(value)
47
+ }) : /*#__PURE__*/_jsx(View, {
48
+ style: styles.valueNode,
49
+ testID: testID,
50
+ children: value
51
+ }), copyable && isText ? /*#__PURE__*/_jsx(CopyButton, {
52
+ value: String(value),
53
+ size: 12
54
+ }) : null]
55
+ });
56
+ }
57
+ const styles = StyleSheet.create({
58
+ row: {
59
+ flexDirection: "row",
60
+ alignItems: "center",
61
+ justifyContent: "space-between"
62
+ },
63
+ label: {
64
+ fontSize: 11,
65
+ color: night.color.textTertiary,
66
+ fontWeight: "500"
67
+ },
68
+ value: {
69
+ fontSize: 11,
70
+ color: night.color.text,
71
+ fontWeight: "500",
72
+ flex: 1,
73
+ textAlign: "right",
74
+ marginLeft: 12
75
+ },
76
+ valueMono: {
77
+ fontFamily: "monospace"
78
+ },
79
+ valueNode: {
80
+ flex: 1,
81
+ flexDirection: "row",
82
+ justifyContent: "flex-end",
83
+ alignItems: "center",
84
+ marginLeft: 12
85
+ }
86
+ });
@@ -139,16 +139,32 @@ export function HeaderSearch({
139
139
  onCancel,
140
140
  placeholder = "Search...",
141
141
  autoFocus = true,
142
- testID
142
+ testID,
143
+ containerTestID,
144
+ clearTestID,
145
+ accessibilityLabel,
146
+ onBlur,
147
+ iconSize = 12,
148
+ dismissOnBlur = false,
149
+ onDismiss,
150
+ clearOnlyWhenText = false,
151
+ inputProps,
152
+ containerNativeID
143
153
  }) {
144
154
  const inputRef = useRef(null);
155
+ // Set while the ✕ is pressed so the blur it causes doesn't dismiss first.
156
+ const clearPressRef = useRef(false);
145
157
  useEffect(() => {
146
158
  if (autoFocus) inputRef.current?.focus();
147
159
  }, [autoFocus]);
160
+ const dismiss = onDismiss ?? onCancel;
161
+ const showClear = !clearOnlyWhenText || value.length > 0;
148
162
  return /*#__PURE__*/_jsxs(View, {
149
163
  style: styles.searchContainer,
164
+ testID: containerTestID,
165
+ nativeID: containerNativeID,
150
166
  children: [/*#__PURE__*/_jsx(SearchIcon, {
151
- size: 12,
167
+ size: iconSize,
152
168
  color: night.color.textSecondary
153
169
  }), /*#__PURE__*/_jsx(TextInput, {
154
170
  ref: inputRef,
@@ -157,21 +173,38 @@ export function HeaderSearch({
157
173
  placeholderTextColor: night.color.placeholder,
158
174
  value: value,
159
175
  onChangeText: onChangeText,
176
+ onSubmitEditing: () => dismissOnBlur ? dismiss() : inputRef.current?.blur(),
177
+ onBlur: () => {
178
+ if (dismissOnBlur && !clearPressRef.current) dismiss();
179
+ onBlur?.();
180
+ },
160
181
  autoCorrect: false,
161
182
  autoCapitalize: "none",
183
+ returnKeyType: "search",
162
184
  testID: testID,
163
- accessibilityLabel: placeholder
164
- }), /*#__PURE__*/_jsx(TouchableOpacity, {
165
- onPress: onCancel,
185
+ accessibilityLabel: accessibilityLabel ?? placeholder,
186
+ ...inputProps
187
+ }), showClear ? /*#__PURE__*/_jsx(TouchableOpacity, {
188
+ onPress: onCancel
189
+ // react-native-web delays press-in ~50ms by default (native fires it
190
+ // immediately), which would put it AFTER the blur.
191
+ ,
192
+ delayPressIn: 0,
193
+ onPressIn: () => {
194
+ clearPressRef.current = true;
195
+ },
196
+ onPressOut: () => {
197
+ clearPressRef.current = false;
198
+ },
166
199
  style: styles.searchCancelButton,
167
200
  accessibilityRole: "button",
168
201
  accessibilityLabel: "Clear search",
169
- testID: testID ? `${testID}-clear` : undefined,
202
+ testID: clearTestID ?? (testID ? `${testID}-clear` : undefined),
170
203
  children: /*#__PURE__*/_jsx(X, {
171
204
  size: 12,
172
205
  color: night.color.textSecondary
173
206
  })
174
- })]
207
+ }) : null]
175
208
  });
176
209
  }
177
210