@buoy-gg/redux 2.1.12 → 2.1.13

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 (62) hide show
  1. package/lib/commonjs/index.js +1 -179
  2. package/lib/commonjs/preset.js +1 -98
  3. package/lib/commonjs/redux/components/ReduxActionButton.js +1 -129
  4. package/lib/commonjs/redux/components/ReduxActionDetailContent.js +1 -380
  5. package/lib/commonjs/redux/components/ReduxActionDetailView.js +1 -401
  6. package/lib/commonjs/redux/components/ReduxActionInfoView.js +1 -838
  7. package/lib/commonjs/redux/components/ReduxActionItem.js +1 -366
  8. package/lib/commonjs/redux/components/ReduxDetailViewToggle.js +1 -134
  9. package/lib/commonjs/redux/components/ReduxIcon.js +1 -18
  10. package/lib/commonjs/redux/components/ReduxModal.js +1 -530
  11. package/lib/commonjs/redux/components/index.js +1 -52
  12. package/lib/commonjs/redux/hooks/index.js +1 -25
  13. package/lib/commonjs/redux/hooks/useAutoInstrumentRedux.js +1 -197
  14. package/lib/commonjs/redux/hooks/useReduxActions.js +1 -75
  15. package/lib/commonjs/redux/index.js +1 -49
  16. package/lib/commonjs/redux/utils/autoInstrument.js +1 -270
  17. package/lib/commonjs/redux/utils/buoyReduxMiddleware.js +1 -166
  18. package/lib/commonjs/redux/utils/createReduxHistoryAdapter.js +1 -146
  19. package/lib/commonjs/redux/utils/index.js +1 -111
  20. package/lib/commonjs/redux/utils/reduxActionStore.js +1 -358
  21. package/lib/module/index.js +1 -87
  22. package/lib/module/preset.js +1 -94
  23. package/lib/module/redux/components/ReduxActionButton.js +1 -126
  24. package/lib/module/redux/components/ReduxActionDetailContent.js +1 -376
  25. package/lib/module/redux/components/ReduxActionDetailView.js +1 -397
  26. package/lib/module/redux/components/ReduxActionInfoView.js +1 -833
  27. package/lib/module/redux/components/ReduxActionItem.js +1 -362
  28. package/lib/module/redux/components/ReduxDetailViewToggle.js +1 -129
  29. package/lib/module/redux/components/ReduxIcon.js +1 -8
  30. package/lib/module/redux/components/ReduxModal.js +1 -525
  31. package/lib/module/redux/components/index.js +1 -7
  32. package/lib/module/redux/hooks/index.js +1 -4
  33. package/lib/module/redux/hooks/useAutoInstrumentRedux.js +1 -193
  34. package/lib/module/redux/hooks/useReduxActions.js +1 -71
  35. package/lib/module/redux/index.js +1 -13
  36. package/lib/module/redux/utils/autoInstrument.js +1 -260
  37. package/lib/module/redux/utils/buoyReduxMiddleware.js +1 -157
  38. package/lib/module/redux/utils/createReduxHistoryAdapter.js +1 -142
  39. package/lib/module/redux/utils/index.js +1 -8
  40. package/lib/module/redux/utils/reduxActionStore.js +1 -354
  41. package/package.json +4 -4
  42. package/lib/typescript/index.d.ts.map +0 -1
  43. package/lib/typescript/preset.d.ts.map +0 -1
  44. package/lib/typescript/redux/components/ReduxActionButton.d.ts.map +0 -1
  45. package/lib/typescript/redux/components/ReduxActionDetailContent.d.ts.map +0 -1
  46. package/lib/typescript/redux/components/ReduxActionDetailView.d.ts.map +0 -1
  47. package/lib/typescript/redux/components/ReduxActionInfoView.d.ts.map +0 -1
  48. package/lib/typescript/redux/components/ReduxActionItem.d.ts.map +0 -1
  49. package/lib/typescript/redux/components/ReduxDetailViewToggle.d.ts.map +0 -1
  50. package/lib/typescript/redux/components/ReduxIcon.d.ts.map +0 -1
  51. package/lib/typescript/redux/components/ReduxModal.d.ts.map +0 -1
  52. package/lib/typescript/redux/components/index.d.ts.map +0 -1
  53. package/lib/typescript/redux/hooks/index.d.ts.map +0 -1
  54. package/lib/typescript/redux/hooks/useAutoInstrumentRedux.d.ts.map +0 -1
  55. package/lib/typescript/redux/hooks/useReduxActions.d.ts.map +0 -1
  56. package/lib/typescript/redux/index.d.ts.map +0 -1
  57. package/lib/typescript/redux/types/index.d.ts.map +0 -1
  58. package/lib/typescript/redux/utils/autoInstrument.d.ts.map +0 -1
  59. package/lib/typescript/redux/utils/buoyReduxMiddleware.d.ts.map +0 -1
  60. package/lib/typescript/redux/utils/createReduxHistoryAdapter.d.ts.map +0 -1
  61. package/lib/typescript/redux/utils/index.d.ts.map +0 -1
  62. package/lib/typescript/redux/utils/reduxActionStore.d.ts.map +0 -1
@@ -1,397 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Detail view for inspecting a single Redux action
5
- */
6
-
7
- import { useState } from "react";
8
- import { View, Text, StyleSheet, ScrollView } from "react-native";
9
- import { macOSColors, TabSelector, DataInspector, CollapsibleSection, CopyButton } from "@buoy-gg/shared-ui";
10
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
- export function ReduxActionDetailView({
12
- action
13
- }) {
14
- const [activeTab, setActiveTab] = useState("action");
15
- const tabs = [{
16
- key: "action",
17
- label: "Action"
18
- }, {
19
- key: "state",
20
- label: "State"
21
- }, {
22
- key: "diff",
23
- label: "Diff"
24
- }];
25
-
26
- // Format timestamp
27
- const formattedTime = new Date(action.timestamp).toLocaleTimeString();
28
-
29
- // Generate copy text for the action
30
- const getCopyText = () => {
31
- return JSON.stringify({
32
- type: action.type,
33
- payload: action.payload,
34
- timestamp: action.timestamp,
35
- duration: action.duration,
36
- hasStateChange: action.hasStateChange
37
- }, null, 2);
38
- };
39
- return /*#__PURE__*/_jsxs(View, {
40
- style: styles.container,
41
- children: [/*#__PURE__*/_jsxs(View, {
42
- style: styles.header,
43
- children: [/*#__PURE__*/_jsxs(View, {
44
- style: styles.headerContent,
45
- children: [/*#__PURE__*/_jsx(Text, {
46
- style: styles.actionType,
47
- numberOfLines: 2,
48
- children: action.type
49
- }), /*#__PURE__*/_jsxs(View, {
50
- style: styles.headerMeta,
51
- children: [/*#__PURE__*/_jsx(Text, {
52
- style: styles.metaText,
53
- children: formattedTime
54
- }), action.duration !== undefined && /*#__PURE__*/_jsxs(Text, {
55
- style: styles.durationText,
56
- children: [action.duration.toFixed(2), "ms"]
57
- }), action.hasStateChange && /*#__PURE__*/_jsx(View, {
58
- style: styles.changeBadge,
59
- children: /*#__PURE__*/_jsx(Text, {
60
- style: styles.changeBadgeText,
61
- children: "State Changed"
62
- })
63
- })]
64
- })]
65
- }), /*#__PURE__*/_jsx(CopyButton, {
66
- value: getCopyText(),
67
- size: 16
68
- })]
69
- }), /*#__PURE__*/_jsx(View, {
70
- style: styles.tabContainer,
71
- children: /*#__PURE__*/_jsx(TabSelector, {
72
- tabs: tabs,
73
- activeTab: activeTab,
74
- onTabChange: tab => setActiveTab(tab)
75
- })
76
- }), /*#__PURE__*/_jsxs(ScrollView, {
77
- style: styles.content,
78
- showsVerticalScrollIndicator: true,
79
- children: [activeTab === "action" && /*#__PURE__*/_jsxs(View, {
80
- style: styles.section,
81
- children: [/*#__PURE__*/_jsx(CollapsibleSection, {
82
- title: "Payload",
83
- defaultOpen: true,
84
- children: action.payload !== undefined ? /*#__PURE__*/_jsx(DataInspector, {
85
- data: action.payload
86
- }) : /*#__PURE__*/_jsx(Text, {
87
- style: styles.emptyText,
88
- children: "No payload"
89
- })
90
- }), /*#__PURE__*/_jsx(CollapsibleSection, {
91
- title: "Full Action",
92
- defaultOpen: false,
93
- children: /*#__PURE__*/_jsx(DataInspector, {
94
- data: action.action
95
- })
96
- })]
97
- }), activeTab === "state" && /*#__PURE__*/_jsxs(View, {
98
- style: styles.section,
99
- children: [/*#__PURE__*/_jsx(CollapsibleSection, {
100
- title: "Previous State",
101
- defaultOpen: false,
102
- children: /*#__PURE__*/_jsx(DataInspector, {
103
- data: action.prevState
104
- })
105
- }), /*#__PURE__*/_jsx(CollapsibleSection, {
106
- title: "Next State",
107
- defaultOpen: true,
108
- children: /*#__PURE__*/_jsx(DataInspector, {
109
- data: action.nextState
110
- })
111
- })]
112
- }), activeTab === "diff" && /*#__PURE__*/_jsx(View, {
113
- style: styles.section,
114
- children: action.hasStateChange ? /*#__PURE__*/_jsx(StateDiff, {
115
- prevState: action.prevState,
116
- nextState: action.nextState
117
- }) : /*#__PURE__*/_jsx(View, {
118
- style: styles.noChangeContainer,
119
- children: /*#__PURE__*/_jsx(Text, {
120
- style: styles.noChangeText,
121
- children: "No state changes from this action"
122
- })
123
- })
124
- })]
125
- })]
126
- });
127
- }
128
-
129
- /**
130
- * Component to show state diff
131
- */
132
- function StateDiff({
133
- prevState,
134
- nextState
135
- }) {
136
- // Simple diff - find changed keys at top level
137
- const changes = findChanges(prevState, nextState);
138
- if (changes.length === 0) {
139
- return /*#__PURE__*/_jsx(View, {
140
- style: styles.noChangeContainer,
141
- children: /*#__PURE__*/_jsx(Text, {
142
- style: styles.noChangeText,
143
- children: "No differences detected"
144
- })
145
- });
146
- }
147
- return /*#__PURE__*/_jsx(View, {
148
- children: changes.map((change, index) => /*#__PURE__*/_jsxs(View, {
149
- style: styles.diffItem,
150
- children: [/*#__PURE__*/_jsxs(View, {
151
- style: styles.diffHeader,
152
- children: [/*#__PURE__*/_jsx(View, {
153
- style: [styles.diffTypeBadge, {
154
- backgroundColor: change.type === "added" ? macOSColors.semantic.successBackground : change.type === "removed" ? macOSColors.semantic.errorBackground : macOSColors.semantic.warningBackground
155
- }],
156
- children: /*#__PURE__*/_jsx(Text, {
157
- style: [styles.diffTypeText, {
158
- color: change.type === "added" ? macOSColors.semantic.success : change.type === "removed" ? macOSColors.semantic.error : macOSColors.semantic.warning
159
- }],
160
- children: change.type.toUpperCase()
161
- })
162
- }), /*#__PURE__*/_jsx(Text, {
163
- style: styles.diffPath,
164
- children: change.path
165
- })]
166
- }), change.type === "modified" && /*#__PURE__*/_jsxs(View, {
167
- style: styles.diffValues,
168
- children: [/*#__PURE__*/_jsxs(View, {
169
- style: styles.diffValue,
170
- children: [/*#__PURE__*/_jsx(Text, {
171
- style: styles.diffLabel,
172
- children: "Before:"
173
- }), /*#__PURE__*/_jsx(DataInspector, {
174
- data: change.oldValue
175
- })]
176
- }), /*#__PURE__*/_jsxs(View, {
177
- style: styles.diffValue,
178
- children: [/*#__PURE__*/_jsx(Text, {
179
- style: styles.diffLabel,
180
- children: "After:"
181
- }), /*#__PURE__*/_jsx(DataInspector, {
182
- data: change.newValue
183
- })]
184
- })]
185
- }), change.type === "added" && /*#__PURE__*/_jsx(View, {
186
- style: styles.diffValue,
187
- children: /*#__PURE__*/_jsx(DataInspector, {
188
- data: change.newValue
189
- })
190
- }), change.type === "removed" && /*#__PURE__*/_jsx(View, {
191
- style: styles.diffValue,
192
- children: /*#__PURE__*/_jsx(DataInspector, {
193
- data: change.oldValue
194
- })
195
- })]
196
- }, index))
197
- });
198
- }
199
- /**
200
- * Find changes between two state objects
201
- */
202
- function findChanges(prevState, nextState, path = "") {
203
- const changes = [];
204
-
205
- // Handle primitives
206
- if (typeof prevState !== "object" || typeof nextState !== "object") {
207
- if (prevState !== nextState) {
208
- changes.push({
209
- type: "modified",
210
- path: path || "root",
211
- oldValue: prevState,
212
- newValue: nextState
213
- });
214
- }
215
- return changes;
216
- }
217
-
218
- // Handle null
219
- if (prevState === null || nextState === null) {
220
- if (prevState !== nextState) {
221
- changes.push({
222
- type: "modified",
223
- path: path || "root",
224
- oldValue: prevState,
225
- newValue: nextState
226
- });
227
- }
228
- return changes;
229
- }
230
- const prevObj = prevState;
231
- const nextObj = nextState;
232
-
233
- // Find all keys
234
- const allKeys = new Set([...Object.keys(prevObj), ...Object.keys(nextObj)]);
235
- for (const key of allKeys) {
236
- const newPath = path ? `${path}.${key}` : key;
237
- const prevValue = prevObj[key];
238
- const nextValue = nextObj[key];
239
- if (!(key in prevObj)) {
240
- // Key was added
241
- changes.push({
242
- type: "added",
243
- path: newPath,
244
- newValue: nextValue
245
- });
246
- } else if (!(key in nextObj)) {
247
- // Key was removed
248
- changes.push({
249
- type: "removed",
250
- path: newPath,
251
- oldValue: prevValue
252
- });
253
- } else if (prevValue !== nextValue) {
254
- // Value changed - check if we should recurse
255
- if (typeof prevValue === "object" && typeof nextValue === "object" && prevValue !== null && nextValue !== null && !Array.isArray(prevValue) && !Array.isArray(nextValue)) {
256
- // Recurse into objects (but limit depth)
257
- if (newPath.split(".").length < 3) {
258
- changes.push(...findChanges(prevValue, nextValue, newPath));
259
- } else {
260
- changes.push({
261
- type: "modified",
262
- path: newPath,
263
- oldValue: prevValue,
264
- newValue: nextValue
265
- });
266
- }
267
- } else {
268
- changes.push({
269
- type: "modified",
270
- path: newPath,
271
- oldValue: prevValue,
272
- newValue: nextValue
273
- });
274
- }
275
- }
276
- }
277
- return changes;
278
- }
279
- const styles = StyleSheet.create({
280
- container: {
281
- flex: 1
282
- },
283
- header: {
284
- flexDirection: "row",
285
- alignItems: "flex-start",
286
- justifyContent: "space-between",
287
- paddingHorizontal: 12,
288
- paddingVertical: 12,
289
- backgroundColor: macOSColors.background.card,
290
- borderBottomWidth: 1,
291
- borderBottomColor: macOSColors.border.default
292
- },
293
- headerContent: {
294
- flex: 1,
295
- marginRight: 12
296
- },
297
- actionType: {
298
- fontSize: 14,
299
- fontWeight: "600",
300
- color: macOSColors.text.primary,
301
- fontFamily: "monospace",
302
- marginBottom: 6
303
- },
304
- headerMeta: {
305
- flexDirection: "row",
306
- alignItems: "center",
307
- gap: 12
308
- },
309
- metaText: {
310
- fontSize: 11,
311
- color: macOSColors.text.muted
312
- },
313
- durationText: {
314
- fontSize: 11,
315
- color: macOSColors.text.muted,
316
- fontFamily: "monospace"
317
- },
318
- changeBadge: {
319
- backgroundColor: macOSColors.semantic.warningBackground,
320
- paddingHorizontal: 6,
321
- paddingVertical: 2,
322
- borderRadius: 4
323
- },
324
- changeBadgeText: {
325
- fontSize: 10,
326
- color: macOSColors.semantic.warning,
327
- fontWeight: "600"
328
- },
329
- tabContainer: {
330
- paddingHorizontal: 12,
331
- paddingVertical: 8
332
- },
333
- content: {
334
- flex: 1
335
- },
336
- section: {
337
- paddingHorizontal: 12,
338
- paddingBottom: 20
339
- },
340
- emptyText: {
341
- fontSize: 12,
342
- color: macOSColors.text.muted,
343
- fontStyle: "italic",
344
- padding: 8
345
- },
346
- noChangeContainer: {
347
- padding: 20,
348
- alignItems: "center"
349
- },
350
- noChangeText: {
351
- fontSize: 13,
352
- color: macOSColors.text.muted
353
- },
354
- diffItem: {
355
- marginBottom: 12,
356
- backgroundColor: macOSColors.background.card,
357
- borderRadius: 8,
358
- borderWidth: 1,
359
- borderColor: macOSColors.border.default,
360
- overflow: "hidden"
361
- },
362
- diffHeader: {
363
- flexDirection: "row",
364
- alignItems: "center",
365
- gap: 8,
366
- padding: 8,
367
- borderBottomWidth: 1,
368
- borderBottomColor: macOSColors.border.default
369
- },
370
- diffTypeBadge: {
371
- paddingHorizontal: 6,
372
- paddingVertical: 2,
373
- borderRadius: 4
374
- },
375
- diffTypeText: {
376
- fontSize: 10,
377
- fontWeight: "700"
378
- },
379
- diffPath: {
380
- fontSize: 12,
381
- color: macOSColors.text.primary,
382
- fontFamily: "monospace"
383
- },
384
- diffValues: {
385
- padding: 8,
386
- gap: 8
387
- },
388
- diffValue: {
389
- padding: 8
390
- },
391
- diffLabel: {
392
- fontSize: 11,
393
- color: macOSColors.text.muted,
394
- marginBottom: 4,
395
- fontWeight: "600"
396
- }
397
- });
1
+ "use strict";import{useState}from"react";import{View,Text,StyleSheet,ScrollView}from"react-native";import{macOSColors,TabSelector,DataInspector,CollapsibleSection,CopyButton}from"@buoy-gg/shared-ui";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";export function ReduxActionDetailView({action:e}){const[t,a]=useState("action"),o=new Date(e.timestamp).toLocaleTimeString();return _jsxs(View,{style:styles.container,children:[_jsxs(View,{style:styles.header,children:[_jsxs(View,{style:styles.headerContent,children:[_jsx(Text,{style:styles.actionType,numberOfLines:2,children:e.type}),_jsxs(View,{style:styles.headerMeta,children:[_jsx(Text,{style:styles.metaText,children:o}),void 0!==e.duration&&_jsxs(Text,{style:styles.durationText,children:[e.duration.toFixed(2),"ms"]}),e.hasStateChange&&_jsx(View,{style:styles.changeBadge,children:_jsx(Text,{style:styles.changeBadgeText,children:"State Changed"})})]})]}),_jsx(CopyButton,{value:JSON.stringify({type:e.type,payload:e.payload,timestamp:e.timestamp,duration:e.duration,hasStateChange:e.hasStateChange},null,2),size:16})]}),_jsx(View,{style:styles.tabContainer,children:_jsx(TabSelector,{tabs:[{key:"action",label:"Action"},{key:"state",label:"State"},{key:"diff",label:"Diff"}],activeTab:t,onTabChange:e=>a(e)})}),_jsxs(ScrollView,{style:styles.content,showsVerticalScrollIndicator:!0,children:["action"===t&&_jsxs(View,{style:styles.section,children:[_jsx(CollapsibleSection,{title:"Payload",defaultOpen:!0,children:void 0!==e.payload?_jsx(DataInspector,{data:e.payload}):_jsx(Text,{style:styles.emptyText,children:"No payload"})}),_jsx(CollapsibleSection,{title:"Full Action",defaultOpen:!1,children:_jsx(DataInspector,{data:e.action})})]}),"state"===t&&_jsxs(View,{style:styles.section,children:[_jsx(CollapsibleSection,{title:"Previous State",defaultOpen:!1,children:_jsx(DataInspector,{data:e.prevState})}),_jsx(CollapsibleSection,{title:"Next State",defaultOpen:!0,children:_jsx(DataInspector,{data:e.nextState})})]}),"diff"===t&&_jsx(View,{style:styles.section,children:e.hasStateChange?_jsx(StateDiff,{prevState:e.prevState,nextState:e.nextState}):_jsx(View,{style:styles.noChangeContainer,children:_jsx(Text,{style:styles.noChangeText,children:"No state changes from this action"})})})]})]})}function StateDiff({prevState:e,nextState:t}){const a=findChanges(e,t);return 0===a.length?_jsx(View,{style:styles.noChangeContainer,children:_jsx(Text,{style:styles.noChangeText,children:"No differences detected"})}):_jsx(View,{children:a.map((e,t)=>_jsxs(View,{style:styles.diffItem,children:[_jsxs(View,{style:styles.diffHeader,children:[_jsx(View,{style:[styles.diffTypeBadge,{backgroundColor:"added"===e.type?macOSColors.semantic.successBackground:"removed"===e.type?macOSColors.semantic.errorBackground:macOSColors.semantic.warningBackground}],children:_jsx(Text,{style:[styles.diffTypeText,{color:"added"===e.type?macOSColors.semantic.success:"removed"===e.type?macOSColors.semantic.error:macOSColors.semantic.warning}],children:e.type.toUpperCase()})}),_jsx(Text,{style:styles.diffPath,children:e.path})]}),"modified"===e.type&&_jsxs(View,{style:styles.diffValues,children:[_jsxs(View,{style:styles.diffValue,children:[_jsx(Text,{style:styles.diffLabel,children:"Before:"}),_jsx(DataInspector,{data:e.oldValue})]}),_jsxs(View,{style:styles.diffValue,children:[_jsx(Text,{style:styles.diffLabel,children:"After:"}),_jsx(DataInspector,{data:e.newValue})]})]}),"added"===e.type&&_jsx(View,{style:styles.diffValue,children:_jsx(DataInspector,{data:e.newValue})}),"removed"===e.type&&_jsx(View,{style:styles.diffValue,children:_jsx(DataInspector,{data:e.oldValue})})]},t))})}function findChanges(e,t,a=""){const o=[];if("object"!=typeof e||"object"!=typeof t)return e!==t&&o.push({type:"modified",path:a||"root",oldValue:e,newValue:t}),o;if(null===e||null===t)return e!==t&&o.push({type:"modified",path:a||"root",oldValue:e,newValue:t}),o;const s=e,n=t,l=new Set([...Object.keys(s),...Object.keys(n)]);for(const e of l){const t=a?`${a}.${e}`:e,l=s[e],i=n[e];e in s?e in n?l!==i&&("object"!=typeof l||"object"!=typeof i||null===l||null===i||Array.isArray(l)||Array.isArray(i)?o.push({type:"modified",path:t,oldValue:l,newValue:i}):t.split(".").length<3?o.push(...findChanges(l,i,t)):o.push({type:"modified",path:t,oldValue:l,newValue:i})):o.push({type:"removed",path:t,oldValue:l}):o.push({type:"added",path:t,newValue:i})}return o}const styles=StyleSheet.create({container:{flex:1},header:{flexDirection:"row",alignItems:"flex-start",justifyContent:"space-between",paddingHorizontal:12,paddingVertical:12,backgroundColor:macOSColors.background.card,borderBottomWidth:1,borderBottomColor:macOSColors.border.default},headerContent:{flex:1,marginRight:12},actionType:{fontSize:14,fontWeight:"600",color:macOSColors.text.primary,fontFamily:"monospace",marginBottom:6},headerMeta:{flexDirection:"row",alignItems:"center",gap:12},metaText:{fontSize:11,color:macOSColors.text.muted},durationText:{fontSize:11,color:macOSColors.text.muted,fontFamily:"monospace"},changeBadge:{backgroundColor:macOSColors.semantic.warningBackground,paddingHorizontal:6,paddingVertical:2,borderRadius:4},changeBadgeText:{fontSize:10,color:macOSColors.semantic.warning,fontWeight:"600"},tabContainer:{paddingHorizontal:12,paddingVertical:8},content:{flex:1},section:{paddingHorizontal:12,paddingBottom:20},emptyText:{fontSize:12,color:macOSColors.text.muted,fontStyle:"italic",padding:8},noChangeContainer:{padding:20,alignItems:"center"},noChangeText:{fontSize:13,color:macOSColors.text.muted},diffItem:{marginBottom:12,backgroundColor:macOSColors.background.card,borderRadius:8,borderWidth:1,borderColor:macOSColors.border.default,overflow:"hidden"},diffHeader:{flexDirection:"row",alignItems:"center",gap:8,padding:8,borderBottomWidth:1,borderBottomColor:macOSColors.border.default},diffTypeBadge:{paddingHorizontal:6,paddingVertical:2,borderRadius:4},diffTypeText:{fontSize:10,fontWeight:"700"},diffPath:{fontSize:12,color:macOSColors.text.primary,fontFamily:"monospace"},diffValues:{padding:8,gap:8},diffValue:{padding:8},diffLabel:{fontSize:11,color:macOSColors.text.muted,marginBottom:4,fontWeight:"600"}});