@buoy-gg/highlight-updates 7.0.38 → 7.0.39

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 (103) hide show
  1. package/lib/commonjs/highlight-updates/HighlightUpdatesOverlay.js +281 -1
  2. package/lib/commonjs/highlight-updates/components/HighlightFilterView.js +1474 -1
  3. package/lib/commonjs/highlight-updates/components/HighlightUpdatesModal.js +641 -1
  4. package/lib/commonjs/highlight-updates/components/IdentifierBadge.js +273 -1
  5. package/lib/commonjs/highlight-updates/components/IsolatedRenderList.js +188 -1
  6. package/lib/commonjs/highlight-updates/components/ModalHeaderContent.js +293 -1
  7. package/lib/commonjs/highlight-updates/components/RenderCauseBadge.js +508 -1
  8. package/lib/commonjs/highlight-updates/components/RenderDetailView.js +846 -1
  9. package/lib/commonjs/highlight-updates/components/RenderHistoryViewer.js +915 -1
  10. package/lib/commonjs/highlight-updates/components/RenderListItem.js +235 -1
  11. package/lib/commonjs/highlight-updates/components/RendersCopySettingsView.js +469 -1
  12. package/lib/commonjs/highlight-updates/components/StatsDisplay.js +73 -1
  13. package/lib/commonjs/highlight-updates/types/copySettings.js +107 -1
  14. package/lib/commonjs/highlight-updates/utils/CommitProfiler.js +446 -1
  15. package/lib/commonjs/highlight-updates/utils/HighlightUpdatesController.js +1920 -1
  16. package/lib/commonjs/highlight-updates/utils/PerformanceLogger.js +359 -1
  17. package/lib/commonjs/highlight-updates/utils/ProfilerInterceptor.js +371 -1
  18. package/lib/commonjs/highlight-updates/utils/RenderCauseDetector.js +1840 -1
  19. package/lib/commonjs/highlight-updates/utils/RenderTracker.js +952 -1
  20. package/lib/commonjs/highlight-updates/utils/ViewTypeMapper.js +264 -1
  21. package/lib/commonjs/highlight-updates/utils/copySettingsStorage.js +32 -1
  22. package/lib/commonjs/highlight-updates/utils/devtoolsComponentNames.js +188 -1
  23. package/lib/commonjs/highlight-updates/utils/namedComposite.js +41 -1
  24. package/lib/commonjs/highlight-updates/utils/ownStateChanged.js +103 -1
  25. package/lib/commonjs/highlight-updates/utils/rawEventEmitter.js +50 -1
  26. package/lib/commonjs/highlight-updates/utils/renderExportFormatter.js +58 -1
  27. package/lib/commonjs/highlight-updates/utils/rendersExportFormatter.js +485 -1
  28. package/lib/commonjs/highlight-updates/utils/screenElements.js +1248 -1
  29. package/lib/commonjs/highlight-updates/utils/tapMatch.js +83 -1
  30. package/lib/commonjs/highlight-updates/utils/testIDs.js +68 -1
  31. package/lib/commonjs/highlight-updates/utils/touchCapture.js +277 -1
  32. package/lib/commonjs/index.js +429 -1
  33. package/lib/commonjs/preset.js +278 -1
  34. package/lib/commonjs/sync/highlightUpdatesSyncAdapter.js +235 -1
  35. package/lib/module/highlight-updates/HighlightUpdatesOverlay.js +274 -1
  36. package/lib/module/highlight-updates/components/HighlightFilterView.js +1468 -1
  37. package/lib/module/highlight-updates/components/HighlightUpdatesModal.js +634 -1
  38. package/lib/module/highlight-updates/components/IdentifierBadge.js +265 -1
  39. package/lib/module/highlight-updates/components/IsolatedRenderList.js +183 -1
  40. package/lib/module/highlight-updates/components/ModalHeaderContent.js +288 -1
  41. package/lib/module/highlight-updates/components/RenderCauseBadge.js +499 -1
  42. package/lib/module/highlight-updates/components/RenderDetailView.js +840 -1
  43. package/lib/module/highlight-updates/components/RenderHistoryViewer.js +908 -1
  44. package/lib/module/highlight-updates/components/RenderListItem.js +230 -1
  45. package/lib/module/highlight-updates/components/RendersCopySettingsView.js +465 -1
  46. package/lib/module/highlight-updates/components/StatsDisplay.js +70 -1
  47. package/lib/module/highlight-updates/types/copySettings.js +102 -1
  48. package/lib/module/highlight-updates/utils/CommitProfiler.js +442 -1
  49. package/lib/module/highlight-updates/utils/HighlightUpdatesController.js +1916 -1
  50. package/lib/module/highlight-updates/utils/PerformanceLogger.js +353 -1
  51. package/lib/module/highlight-updates/utils/ProfilerInterceptor.js +358 -1
  52. package/lib/module/highlight-updates/utils/RenderCauseDetector.js +1830 -1
  53. package/lib/module/highlight-updates/utils/RenderTracker.js +949 -1
  54. package/lib/module/highlight-updates/utils/ViewTypeMapper.js +255 -1
  55. package/lib/module/highlight-updates/utils/copySettingsStorage.js +26 -1
  56. package/lib/module/highlight-updates/utils/devtoolsComponentNames.js +178 -1
  57. package/lib/module/highlight-updates/utils/namedComposite.js +36 -1
  58. package/lib/module/highlight-updates/utils/ownStateChanged.js +98 -1
  59. package/lib/module/highlight-updates/utils/rawEventEmitter.js +46 -1
  60. package/lib/module/highlight-updates/utils/renderExportFormatter.js +54 -1
  61. package/lib/module/highlight-updates/utils/rendersExportFormatter.js +478 -1
  62. package/lib/module/highlight-updates/utils/screenElements.js +1242 -1
  63. package/lib/module/highlight-updates/utils/tapMatch.js +76 -1
  64. package/lib/module/highlight-updates/utils/testIDs.js +60 -1
  65. package/lib/module/highlight-updates/utils/touchCapture.js +270 -1
  66. package/lib/module/index.js +130 -1
  67. package/lib/module/preset.js +272 -1
  68. package/lib/module/sync/highlightUpdatesSyncAdapter.js +230 -1
  69. package/lib/typescript/highlight-updates/HighlightUpdatesOverlay.d.ts.map +1 -0
  70. package/lib/typescript/highlight-updates/components/HighlightFilterView.d.ts.map +1 -0
  71. package/lib/typescript/highlight-updates/components/HighlightUpdatesModal.d.ts.map +1 -0
  72. package/lib/typescript/highlight-updates/components/IdentifierBadge.d.ts.map +1 -0
  73. package/lib/typescript/highlight-updates/components/IsolatedRenderList.d.ts.map +1 -0
  74. package/lib/typescript/highlight-updates/components/ModalHeaderContent.d.ts.map +1 -0
  75. package/lib/typescript/highlight-updates/components/RenderCauseBadge.d.ts.map +1 -0
  76. package/lib/typescript/highlight-updates/components/RenderDetailView.d.ts.map +1 -0
  77. package/lib/typescript/highlight-updates/components/RenderHistoryViewer.d.ts.map +1 -0
  78. package/lib/typescript/highlight-updates/components/RenderListItem.d.ts.map +1 -0
  79. package/lib/typescript/highlight-updates/components/RendersCopySettingsView.d.ts.map +1 -0
  80. package/lib/typescript/highlight-updates/components/StatsDisplay.d.ts.map +1 -0
  81. package/lib/typescript/highlight-updates/types/copySettings.d.ts.map +1 -0
  82. package/lib/typescript/highlight-updates/utils/CommitProfiler.d.ts.map +1 -0
  83. package/lib/typescript/highlight-updates/utils/HighlightUpdatesController.d.ts.map +1 -0
  84. package/lib/typescript/highlight-updates/utils/PerformanceLogger.d.ts.map +1 -0
  85. package/lib/typescript/highlight-updates/utils/ProfilerInterceptor.d.ts.map +1 -0
  86. package/lib/typescript/highlight-updates/utils/RenderCauseDetector.d.ts.map +1 -0
  87. package/lib/typescript/highlight-updates/utils/RenderTracker.d.ts.map +1 -0
  88. package/lib/typescript/highlight-updates/utils/ViewTypeMapper.d.ts.map +1 -0
  89. package/lib/typescript/highlight-updates/utils/copySettingsStorage.d.ts.map +1 -0
  90. package/lib/typescript/highlight-updates/utils/devtoolsComponentNames.d.ts.map +1 -0
  91. package/lib/typescript/highlight-updates/utils/namedComposite.d.ts.map +1 -0
  92. package/lib/typescript/highlight-updates/utils/ownStateChanged.d.ts.map +1 -0
  93. package/lib/typescript/highlight-updates/utils/rawEventEmitter.d.ts.map +1 -0
  94. package/lib/typescript/highlight-updates/utils/renderExportFormatter.d.ts.map +1 -0
  95. package/lib/typescript/highlight-updates/utils/rendersExportFormatter.d.ts.map +1 -0
  96. package/lib/typescript/highlight-updates/utils/screenElements.d.ts.map +1 -0
  97. package/lib/typescript/highlight-updates/utils/tapMatch.d.ts.map +1 -0
  98. package/lib/typescript/highlight-updates/utils/testIDs.d.ts.map +1 -0
  99. package/lib/typescript/highlight-updates/utils/touchCapture.d.ts.map +1 -0
  100. package/lib/typescript/index.d.ts.map +1 -0
  101. package/lib/typescript/preset.d.ts.map +1 -0
  102. package/lib/typescript/sync/highlightUpdatesSyncAdapter.d.ts.map +1 -0
  103. package/package.json +7 -7
@@ -1 +1,915 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.RenderHistoryFooter=RenderHistoryFooter,exports.RenderHistoryViewer=RenderHistoryViewer,exports.default=void 0;var _react=_interopRequireWildcard(require("react")),_reactNative=require("react-native"),_sharedUi=require("@buoy-gg/shared-ui"),_dataViewer=require("@buoy-gg/shared-ui/dataViewer"),_RenderTracker=require("../utils/RenderTracker"),_RenderCauseBadge=require("./RenderCauseBadge"),_jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(e,t){if("function"==typeof WeakMap)var r=new WeakMap,i=new WeakMap;return(_interopRequireWildcard=function(e,t){if(!t&&e&&e.__esModule)return e;var o,s,n={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return n;if(o=t?i:r){if(o.has(e))return o.get(e);o.set(e,n)}for(const t in e)"default"!==t&&{}.hasOwnProperty.call(e,t)&&((s=(o=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,t))&&(s.get||s.set)?o(n,t,s):n[t]=e[t]);return n})(e,t)}function formatTimeWithMs(e){const t=new Date(e);return`${t.getHours().toString().padStart(2,"0")}:${t.getMinutes().toString().padStart(2,"0")}:${t.getSeconds().toString().padStart(2,"0")}.${t.getMilliseconds().toString().padStart(3,"0")}`}function RenderHistoryViewer({render:e,disableInternalFooter:t=!1,selectedEventIndex:r,onEventIndexChange:i,isPro:o=!1}){const[s,n]=(0,_react.useState)(0),a=r??s,l=i??n,[c,d]=(0,_react.useState)("current"),h=(0,_react.useMemo)(()=>e.renderHistory&&0!==e.renderHistory.length?[...e.renderHistory].sort((e,t)=>e.timestamp-t.timestamp):[],[e.renderHistory]),g=(0,_sharedUi.useLimit)("highlightUpdates.historyEvents"),x=o?1/0:g,u=(0,_react.useMemo)(()=>h.slice(-x),[h,x]),_=(0,_react.useMemo)(()=>Math.max(0,h.length-x),[h.length,x]),y=u.length,m=u[a],f=a>0?u[a-1]:null,p=(0,_react.useCallback)(()=>{a>0&&l(a-1)},[a,l]),j=(0,_react.useCallback)(()=>{a<y-1&&l(a+1)},[a,y,l]);if(0===y){const e=_RenderTracker.RenderTracker.getSettings().enableRenderHistory;return(0,_jsxRuntime.jsx)(_sharedUi.ToolEmptyState,{testID:"buoy-highlight-history-empty",otto:e?"stare":"paused",title:"No Render History",message:e?"History is on and armed — this component has not re-rendered since. Interact with the app to record one.":"Enable render history tracking in settings to see render events here."})}return(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.container,{paddingBottom:!t&&y>1?80:0}],children:[_>0&&(0,_jsxRuntime.jsxs)(_reactNative.View,{testID:"buoy-highlight-history-locked",style:styles.lockedBanner,children:[(0,_jsxRuntime.jsx)(_sharedUi.Lock,{size:14,color:_sharedUi.night.color.warning}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{testID:"buoy-highlight-history-locked-text",style:styles.lockedBannerText,children:[_," older ",1===_?"render":"renders"," locked"]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.lockedBannerSubtext,children:"Upgrade to Pro"})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.viewToggleContainer,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"buoy-highlight-history-mode-current",accessibilityRole:"button",accessibilityLabel:"Current state",style:[styles.viewToggleCard,"current"===c&&styles.viewToggleCardActive],onPress:()=>d("current"),activeOpacity:.8,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.viewToggleContent,children:[(0,_jsxRuntime.jsx)(_sharedUi.Database,{size:16,color:"current"===c?_sharedUi.night.color.accent:_sharedUi.night.color.textSecondary}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.viewToggleLabel,"current"===c&&styles.viewToggleLabelActive],children:"CURRENT STATE"})]}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:[styles.viewToggleDescription,"current"===c&&{color:_sharedUi.night.color.text}],children:["View render #",m?.renderNumber??0," details"]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{testID:"buoy-highlight-history-mode-diff",accessibilityLabel:"Diff view, coming soon",style:[styles.viewToggleCard,styles.viewToggleCardDisabled],children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.viewToggleContent,children:[(0,_jsxRuntime.jsx)(_sharedUi.GitBranch,{size:16,color:_sharedUi.night.color.textTertiary}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.viewToggleLabel,styles.viewToggleLabelDisabled],children:"DIFF VIEW"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.todoBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.todoBadgeText,children:"TODO"})})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.viewToggleDescription,{color:_sharedUi.night.color.textTertiary}],children:"Compare renders side by side (coming soon)"})]})]}),(0,_jsxRuntime.jsx)(_reactNative.ScrollView,{testID:"buoy-highlight-history-scroll",style:styles.contentScroll,contentContainerStyle:styles.contentContainer,showsVerticalScrollIndicator:!1,children:"current"===c?(0,_jsxRuntime.jsx)(CurrentStateView,{event:m,render:e}):(0,_jsxRuntime.jsx)(DiffView,{previousEvent:f,currentEvent:m,render:e})})]}),!t&&(0,_jsxRuntime.jsx)(_sharedUi.EventStepperFooter,{currentIndex:a,totalItems:y,onPrevious:p,onNext:j,itemLabel:"Render",subtitle:(0,_sharedUi.formatRelativeTime)(new Date(m?.timestamp??Date.now()))})]})}function CurrentStateView({event:e,render:t}){if(!e)return(0,_jsxRuntime.jsx)(_reactNative.View,{testID:"buoy-highlight-history-no-event",style:styles.noEventContainer,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.noEventText,children:"No event selected"})});const r=_RenderCauseBadge.CAUSE_CONFIG[e.cause.type];return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.currentStateContainer,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.eventHeader,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.eventHeaderLeft,children:[(0,_jsxRuntime.jsxs)(_reactNative.Text,{testID:"buoy-highlight-history-event-title",style:styles.eventTitle,children:["Render #",e.renderNumber]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:"buoy-highlight-history-event-time",style:styles.eventTime,children:formatTimeWithMs(e.timestamp)})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.eventBadge,{backgroundColor:t.color+"30"}],children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.eventBadgeDot,{backgroundColor:t.color}]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:"buoy-highlight-history-event-cause",style:[styles.eventBadgeText,{color:t.color}],children:e.cause.type.toUpperCase()})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Clock,color:r.color,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"WHY DID THIS RENDER?"})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.sectionContent,children:(0,_jsxRuntime.jsx)(_RenderCauseBadge.EnhancedCauseDisplay,{cause:e.cause,nativeType:t.viewType})})]}),e.capturedProps&&Object.keys(e.capturedProps).length>0&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Database,color:_sharedUi.night.color.accent,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"CAPTURED PROPS"})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.sectionContent,children:(0,_jsxRuntime.jsx)(_reactNative.ScrollView,{horizontal:!0,showsHorizontalScrollIndicator:!1,style:styles.propsScrollView,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:"buoy-highlight-history-props",style:styles.propsJson,children:JSON.stringify(e.capturedProps,null,2)})})})]})]})}function DiffView({previousEvent:e,currentEvent:t,render:r}){const[i,o]=(0,_react.useState)("props");if(!e||!t)return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.noEventContainer,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.noEventText,children:"Select an event with a previous event to compare"})});const s=_RenderCauseBadge.CAUSE_CONFIG[e.cause.type],n=_RenderCauseBadge.CAUSE_CONFIG[t.cause.type],a=e.capturedProps&&t.capturedProps,l=e.capturedState&&t.capturedState;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.diffContainer,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.compareBar,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.compareSide,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.compareLabelRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.compareLabel,{color:_sharedUi.buoyColors.warning}],children:"PREV"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.compareActionBadge,{backgroundColor:`${s.color}20`}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.compareActionText,{color:s.color}],children:e.cause.type.toUpperCase()})})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.compareMeta,children:[(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.compareIndex,children:["#",e.renderNumber]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.compareTime,children:formatTimeWithMs(e.timestamp)})]})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.compareDivider,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.compareArrow,children:"→"})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.compareSide,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.compareLabelRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.compareLabel,{color:_sharedUi.buoyColors.success}],children:"CUR"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.compareActionBadge,{backgroundColor:`${n.color}20`}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.compareActionText,{color:n.color}],children:t.cause.type.toUpperCase()})})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.compareMeta,children:[(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.compareIndex,children:["#",t.renderNumber]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.compareTime,children:formatTimeWithMs(t.timestamp)})]})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.diffModeTabs,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.diffModeTab,"cause"===i&&styles.diffModeTabActive],onPress:()=>o("cause"),activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.diffModeTabText,"cause"===i&&styles.diffModeTabTextActive],children:"CAUSE"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.diffModeTab,"props"===i&&styles.diffModeTabActive,!a&&styles.diffModeTabDisabled],onPress:()=>a&&o("props"),activeOpacity:a?.7:1,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.diffModeTabText,"props"===i&&styles.diffModeTabTextActive,!a&&styles.diffModeTabTextDisabled],children:"PROPS"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.diffModeTab,"state"===i&&styles.diffModeTabActive,!l&&styles.diffModeTabDisabled],onPress:()=>l&&o("state"),activeOpacity:l?.7:1,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.diffModeTabText,"state"===i&&styles.diffModeTabTextActive,!l&&styles.diffModeTabTextDisabled],children:"STATE"})})]}),"cause"===i&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.diffSummary,children:(0,_jsxRuntime.jsx)(_RenderCauseBadge.EnhancedCauseDisplay,{cause:t.cause,nativeType:r.viewType})}),"props"===i&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.treeDiffContainer,children:a?(0,_jsxRuntime.jsx)(_dataViewer.TreeDiffViewer,{oldValue:e.capturedProps,newValue:t.capturedProps,theme:"dark",showUnchanged:!0}):(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.noDiffData,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.noDiffDataTitle,children:"Props Not Captured"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.noDiffDataText,children:'Enable "Capture Props on Render" in settings to see props diff.'})]})}),"state"===i&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.treeDiffContainer,children:l?(0,_jsxRuntime.jsx)(_dataViewer.TreeDiffViewer,{oldValue:e.capturedState,newValue:t.capturedState,theme:"dark",showUnchanged:!0}):(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.noDiffData,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.noDiffDataTitle,children:"State Not Captured"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.noDiffDataText,children:'Enable "Capture State on Render" in settings to see state diff.'})]})})]})}function RenderHistoryFooter({render:e,selectedEventIndex:t=0,onEventIndexChange:r=()=>{},isPro:i=!1}){const o=(0,_react.useMemo)(()=>e.renderHistory&&0!==e.renderHistory.length?[...e.renderHistory].sort((e,t)=>e.timestamp-t.timestamp):[],[e.renderHistory]),s=(0,_sharedUi.useLimit)("highlightUpdates.historyEvents"),n=i?1/0:s,a=(0,_react.useMemo)(()=>o.slice(-n),[o,n]),l=a.length,c=a[t],d=(0,_react.useCallback)(()=>{r(Math.max(0,t-1))},[t,r]),h=(0,_react.useCallback)(()=>{r(Math.min(l-1,t+1))},[t,l,r]);return l<=1?null:(0,_jsxRuntime.jsx)(_sharedUi.EventStepperFooter,{currentIndex:t,totalItems:l,onPrevious:d,onNext:h,itemLabel:"Render",subtitle:c?(0,_sharedUi.formatRelativeTime)(new Date(c.timestamp)):void 0})}const styles=_reactNative.StyleSheet.create({container:{flex:1,backgroundColor:"transparent"},emptyContainer:{flex:1,alignItems:"center",justifyContent:"center",padding:32,gap:12},emptyTitle:{fontSize:16,fontWeight:"600",color:_sharedUi.night.color.text},emptyText:{fontSize:13,color:_sharedUi.night.color.textSecondary,textAlign:"center",lineHeight:18},viewToggleContainer:{flexDirection:"row",padding:12,gap:8},viewToggleCard:{flex:1,backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:10,gap:4},viewToggleCardActive:{borderColor:_sharedUi.night.color.accentBorderStrong,backgroundColor:_sharedUi.night.color.accentSoft},viewToggleCardDisabled:{opacity:.5},todoBadge:{backgroundColor:_sharedUi.night.color.fillSecondary,paddingHorizontal:6,paddingVertical:2,borderRadius:4,marginLeft:4},todoBadgeText:{fontSize:9,fontWeight:"700",color:_sharedUi.night.color.textTertiary,letterSpacing:.3},viewToggleContent:{flexDirection:"row",alignItems:"center",gap:6},viewToggleLabel:{fontSize:10,fontWeight:"700",color:_sharedUi.night.color.textSecondary,letterSpacing:.5},viewToggleLabelActive:{color:_sharedUi.night.color.accent},viewToggleLabelDisabled:{color:_sharedUi.night.color.textTertiary},viewToggleDescription:{fontSize:11,color:_sharedUi.night.color.textTertiary,marginTop:2},contentScroll:{flex:1},contentContainer:{padding:12,paddingTop:0},noEventContainer:{padding:24,alignItems:"center"},noEventText:{fontSize:13,color:_sharedUi.night.color.textTertiary},currentStateContainer:{gap:12},eventHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:12},eventHeaderLeft:{gap:2},eventTitle:{fontSize:15,fontWeight:"700",color:_sharedUi.night.color.text},eventTime:{fontSize:11,color:_sharedUi.night.color.textTertiary,fontFamily:_sharedUi.monoFont},eventBadge:{flexDirection:"row",alignItems:"center",paddingHorizontal:10,paddingVertical:4,borderRadius:12,gap:6},eventBadgeDot:{width:6,height:6,borderRadius:3},eventBadgeText:{fontSize:10,fontWeight:"700",fontFamily:_sharedUi.monoFont},section:{backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,overflow:"hidden"},sectionContent:{padding:12,paddingTop:8},causeContainer:{marginBottom:12},changedList:{marginBottom:12,paddingLeft:4},changedListTitle:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.textSecondary,marginBottom:6},changedItem:{fontSize:12,color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont,marginBottom:3,paddingLeft:8},propsScrollView:{maxHeight:150},propsJson:{fontSize:11,fontFamily:_sharedUi.monoFont,color:_sharedUi.night.color.text,backgroundColor:_sharedUi.night.color.bg,padding:10,borderRadius:6},diffContainer:{gap:12},compareBar:{flexDirection:"row",backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:10},compareSide:{flex:1,gap:4},compareLabelRow:{flexDirection:"row",alignItems:"center",gap:8},compareLabel:{fontSize:10,fontWeight:"700",letterSpacing:.5},compareActionBadge:{paddingHorizontal:6,paddingVertical:2,borderRadius:4},compareActionText:{fontSize:9,fontWeight:"600"},compareMeta:{flexDirection:"row",alignItems:"center",gap:6},compareIndex:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.text},compareTime:{fontSize:10,color:_sharedUi.night.color.textTertiary,fontFamily:_sharedUi.monoFont},compareDivider:{width:30,alignItems:"center",justifyContent:"center"},compareArrow:{fontSize:16,color:_sharedUi.night.color.textTertiary},diffSummary:{backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:12},diffSummaryTitle:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.textSecondary,marginBottom:8},diffChanges:{gap:4},diffChangeItem:{flexDirection:"row",alignItems:"center",gap:6},diffChangeIcon:{fontSize:12,fontWeight:"700",color:_sharedUi.night.color.warning,fontFamily:_sharedUi.monoFont},diffChangeKey:{fontSize:12,color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},diffNoChanges:{fontSize:12,color:_sharedUi.night.color.textTertiary,fontStyle:"italic"},diffPlaceholder:{fontSize:12,color:_sharedUi.night.color.textTertiary,fontStyle:"italic",textAlign:"center",padding:16},diffModeTabs:{flexDirection:"row",backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:4,gap:4},diffModeTab:{flex:1,paddingVertical:8,paddingHorizontal:12,borderRadius:6,alignItems:"center"},diffModeTabActive:{backgroundColor:_sharedUi.night.color.accentSoft},diffModeTabDisabled:{opacity:.4},diffModeTabText:{fontSize:10,fontWeight:"600",color:_sharedUi.night.color.textSecondary,letterSpacing:.5},diffModeTabTextActive:{color:_sharedUi.night.color.accent},diffModeTabTextDisabled:{color:_sharedUi.night.color.textTertiary},causeDiffContainer:{gap:8,marginBottom:12},causeDiffRow:{flexDirection:"row",alignItems:"center",gap:8},causeDiffLabel:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.textSecondary,minWidth:80},causeDiffValue:{fontSize:12,color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont,fontWeight:"500"},diffChangesTitle:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.textSecondary,marginBottom:6},treeDiffContainer:{backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,overflow:"hidden",minHeight:150},noDiffData:{padding:24,alignItems:"center",gap:8},noDiffDataTitle:{fontSize:13,fontWeight:"600",color:_sharedUi.night.color.text},noDiffDataText:{fontSize:12,color:_sharedUi.night.color.textTertiary,textAlign:"center",lineHeight:18},lockedBanner:{flexDirection:"row",alignItems:"center",justifyContent:"center",paddingVertical:10,paddingHorizontal:16,marginHorizontal:12,marginTop:8,backgroundColor:_sharedUi.night.color.warningSoft,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.warning+"30",gap:8},lockedBannerText:{color:_sharedUi.night.color.warning,fontSize:13,fontWeight:"500"},lockedBannerSubtext:{color:_sharedUi.night.color.textTertiary,fontSize:12}});var _default=exports.default=RenderHistoryViewer;
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.RenderHistoryFooter = RenderHistoryFooter;
7
+ exports.RenderHistoryViewer = RenderHistoryViewer;
8
+ exports.default = void 0;
9
+ var _react = _interopRequireWildcard(require("react"));
10
+ var _reactNative = require("react-native");
11
+ var _sharedUi = require("@buoy-gg/shared-ui");
12
+ var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
13
+ var _RenderTracker = require("../utils/RenderTracker");
14
+ var _RenderCauseBadge = require("./RenderCauseBadge");
15
+ var _jsxRuntime = require("react/jsx-runtime");
16
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
17
+ /**
18
+ * RenderHistoryViewer
19
+ *
20
+ * Displays render history for a component with event stepping.
21
+ * Allows navigating through render events chronologically.
22
+ * Shows current state view or diff view between renders.
23
+ */
24
+
25
+ /**
26
+ * `HH:MM:SS.mmm` — the same shape Redux, Zustand and Jotai print for the same
27
+ * job, and for the same reason: the milliseconds are the point.
28
+ *
29
+ * Built by hand rather than from `toLocaleTimeString`, which appends the day
30
+ * period on a 12-hour locale — so concatenating the milliseconds to the end of
31
+ * it produced "8:21:44 AM.351", with the fraction attached to the wrong part
32
+ * of the time. It also made the string depend on the hour of day, which is a
33
+ * fine way to have a test that only passes after 10am.
34
+ */
35
+ function formatTimeWithMs(timestamp) {
36
+ const date = new Date(timestamp);
37
+ const h = date.getHours().toString().padStart(2, "0");
38
+ const m = date.getMinutes().toString().padStart(2, "0");
39
+ const s = date.getSeconds().toString().padStart(2, "0");
40
+ const ms = date.getMilliseconds().toString().padStart(3, "0");
41
+ return `${h}:${m}:${s}.${ms}`;
42
+ }
43
+
44
+ /**
45
+ * Main RenderHistoryViewer component
46
+ */
47
+ function RenderHistoryViewer({
48
+ render,
49
+ disableInternalFooter = false,
50
+ selectedEventIndex: externalIndex,
51
+ onEventIndexChange: externalOnChange,
52
+ isPro = false
53
+ }) {
54
+ // Internal state for event index when not controlled externally
55
+ const [internalIndex, setInternalIndex] = (0, _react.useState)(0);
56
+
57
+ // Use external or internal state
58
+ const selectedEventIndex = externalIndex ?? internalIndex;
59
+ const onEventIndexChange = externalOnChange ?? setInternalIndex;
60
+
61
+ // View mode: "current" shows selected event, "diff" shows comparison
62
+ const [activeView, setActiveView] = (0, _react.useState)("current");
63
+
64
+ // Get all events sorted by timestamp (oldest first)
65
+ const allEvents = (0, _react.useMemo)(() => {
66
+ if (!render.renderHistory || render.renderHistory.length === 0) {
67
+ return [];
68
+ }
69
+ return [...render.renderHistory].sort((a, b) => a.timestamp - b.timestamp);
70
+ }, [render.renderHistory]);
71
+
72
+ // `isPro` stays a prop so callers can force the unlimited view; the tier cap
73
+ // applies otherwise. useLimit() already returns Infinity for Pro, so the two
74
+ // agree — this only preserves the prop contract for cross-package callers.
75
+ const tierLimit = (0, _sharedUi.useLimit)("highlightUpdates.historyEvents");
76
+ const eventLimit = isPro ? Infinity : tierLimit;
77
+
78
+ // Show the most recent N events (negative index clamps to 0, so an
79
+ // unlimited tier returns the whole list).
80
+ const events = (0, _react.useMemo)(() => allEvents.slice(-eventLimit), [allEvents, eventLimit]);
81
+ const lockedEventCount = (0, _react.useMemo)(() => Math.max(0, allEvents.length - eventLimit), [allEvents.length, eventLimit]);
82
+ const totalEvents = events.length;
83
+ const currentEvent = events[selectedEventIndex];
84
+ const previousEvent = selectedEventIndex > 0 ? events[selectedEventIndex - 1] : null;
85
+
86
+ // Navigation handlers
87
+ const goToPrevious = (0, _react.useCallback)(() => {
88
+ if (selectedEventIndex > 0) {
89
+ onEventIndexChange(selectedEventIndex - 1);
90
+ }
91
+ }, [selectedEventIndex, onEventIndexChange]);
92
+ const goToNext = (0, _react.useCallback)(() => {
93
+ if (selectedEventIndex < totalEvents - 1) {
94
+ onEventIndexChange(selectedEventIndex + 1);
95
+ }
96
+ }, [selectedEventIndex, totalEvents, onEventIndexChange]);
97
+
98
+ // If no history, show empty state
99
+ if (totalEvents === 0) {
100
+ // The copy used to tell EVERYONE to go and enable the setting, including
101
+ // the people who already had. Asking the tracker which it is costs one
102
+ // synchronous read on a branch that renders nothing else.
103
+ const historyEnabled = _RenderTracker.RenderTracker.getSettings().enableRenderHistory;
104
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ToolEmptyState, {
105
+ testID: "buoy-highlight-history-empty"
106
+ // paused = the recorder is switched off; stare = armed and watching,
107
+ // which is the truth once the setting is on and this component simply
108
+ // has not re-rendered yet.
109
+ ,
110
+ otto: historyEnabled ? "stare" : "paused",
111
+ title: "No Render History",
112
+ message: historyEnabled ? "History is on and armed — this component has not re-rendered since. Interact with the app to record one." : "Enable render history tracking in settings to see render events here."
113
+ });
114
+ }
115
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
116
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
117
+ style: [styles.container, {
118
+ paddingBottom: !disableInternalFooter && totalEvents > 1 ? 80 : 0
119
+ }],
120
+ children: [lockedEventCount > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
121
+ testID: "buoy-highlight-history-locked",
122
+ style: styles.lockedBanner,
123
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Lock, {
124
+ size: 14,
125
+ color: _sharedUi.night.color.warning
126
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
127
+ testID: "buoy-highlight-history-locked-text",
128
+ style: styles.lockedBannerText,
129
+ children: [lockedEventCount, " older ", lockedEventCount === 1 ? 'render' : 'renders', " locked"]
130
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
131
+ style: styles.lockedBannerSubtext,
132
+ children: "Upgrade to Pro"
133
+ })]
134
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
135
+ style: styles.viewToggleContainer,
136
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
137
+ testID: "buoy-highlight-history-mode-current",
138
+ accessibilityRole: "button",
139
+ accessibilityLabel: "Current state",
140
+ style: [styles.viewToggleCard, activeView === "current" && styles.viewToggleCardActive],
141
+ onPress: () => setActiveView("current"),
142
+ activeOpacity: 0.8,
143
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
144
+ style: styles.viewToggleContent,
145
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Database, {
146
+ size: 16,
147
+ color: activeView === "current" ? _sharedUi.night.color.accent : _sharedUi.night.color.textSecondary
148
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
149
+ style: [styles.viewToggleLabel, activeView === "current" && styles.viewToggleLabelActive],
150
+ children: "CURRENT STATE"
151
+ })]
152
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
153
+ style: [styles.viewToggleDescription, activeView === "current" && {
154
+ color: _sharedUi.night.color.text
155
+ }],
156
+ children: ["View render #", currentEvent?.renderNumber ?? 0, " details"]
157
+ })]
158
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
159
+ testID: "buoy-highlight-history-mode-diff",
160
+ accessibilityLabel: "Diff view, coming soon",
161
+ style: [styles.viewToggleCard, styles.viewToggleCardDisabled],
162
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
163
+ style: styles.viewToggleContent,
164
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.GitBranch, {
165
+ size: 16,
166
+ color: _sharedUi.night.color.textTertiary
167
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
168
+ style: [styles.viewToggleLabel, styles.viewToggleLabelDisabled],
169
+ children: "DIFF VIEW"
170
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
171
+ style: styles.todoBadge,
172
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
173
+ style: styles.todoBadgeText,
174
+ children: "TODO"
175
+ })
176
+ })]
177
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
178
+ style: [styles.viewToggleDescription, {
179
+ color: _sharedUi.night.color.textTertiary
180
+ }],
181
+ children: "Compare renders side by side (coming soon)"
182
+ })]
183
+ })]
184
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
185
+ testID: "buoy-highlight-history-scroll",
186
+ style: styles.contentScroll,
187
+ contentContainerStyle: styles.contentContainer,
188
+ showsVerticalScrollIndicator: false,
189
+ children: activeView === "current" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(CurrentStateView, {
190
+ event: currentEvent,
191
+ render: render
192
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(DiffView, {
193
+ previousEvent: previousEvent,
194
+ currentEvent: currentEvent,
195
+ render: render
196
+ })
197
+ })]
198
+ }), !disableInternalFooter && /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.EventStepperFooter, {
199
+ currentIndex: selectedEventIndex,
200
+ totalItems: totalEvents,
201
+ onPrevious: goToPrevious,
202
+ onNext: goToNext,
203
+ itemLabel: "Render",
204
+ subtitle: (0, _sharedUi.formatRelativeTime)(new Date(currentEvent?.timestamp ?? Date.now()))
205
+ })]
206
+ });
207
+ }
208
+
209
+ /**
210
+ * Current State View - shows details of the selected render event
211
+ */
212
+ function CurrentStateView({
213
+ event,
214
+ render
215
+ }) {
216
+ if (!event) {
217
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
218
+ testID: "buoy-highlight-history-no-event",
219
+ style: styles.noEventContainer,
220
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
221
+ style: styles.noEventText,
222
+ children: "No event selected"
223
+ })
224
+ });
225
+ }
226
+ const causeConfig = _RenderCauseBadge.CAUSE_CONFIG[event.cause.type];
227
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
228
+ style: styles.currentStateContainer,
229
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
230
+ style: styles.eventHeader,
231
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
232
+ style: styles.eventHeaderLeft,
233
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
234
+ testID: "buoy-highlight-history-event-title",
235
+ style: styles.eventTitle,
236
+ children: ["Render #", event.renderNumber]
237
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
238
+ testID: "buoy-highlight-history-event-time",
239
+ style: styles.eventTime,
240
+ children: formatTimeWithMs(event.timestamp)
241
+ })]
242
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
243
+ style: [styles.eventBadge, {
244
+ backgroundColor: render.color + "30"
245
+ }],
246
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
247
+ style: [styles.eventBadgeDot, {
248
+ backgroundColor: render.color
249
+ }]
250
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
251
+ testID: "buoy-highlight-history-event-cause",
252
+ style: [styles.eventBadgeText, {
253
+ color: render.color
254
+ }],
255
+ children: event.cause.type.toUpperCase()
256
+ })]
257
+ })]
258
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
259
+ style: styles.section,
260
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.SectionHeader, {
261
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon, {
262
+ icon: _sharedUi.Clock,
263
+ color: causeConfig.color,
264
+ size: 12
265
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Title, {
266
+ children: "WHY DID THIS RENDER?"
267
+ })]
268
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
269
+ style: styles.sectionContent,
270
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_RenderCauseBadge.EnhancedCauseDisplay, {
271
+ cause: event.cause,
272
+ nativeType: render.viewType
273
+ })
274
+ })]
275
+ }), event.capturedProps && Object.keys(event.capturedProps).length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
276
+ style: styles.section,
277
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.SectionHeader, {
278
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon, {
279
+ icon: _sharedUi.Database,
280
+ color: _sharedUi.night.color.accent,
281
+ size: 12
282
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Title, {
283
+ children: "CAPTURED PROPS"
284
+ })]
285
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
286
+ style: styles.sectionContent,
287
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
288
+ horizontal: true,
289
+ showsHorizontalScrollIndicator: false,
290
+ style: styles.propsScrollView,
291
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
292
+ testID: "buoy-highlight-history-props",
293
+ style: styles.propsJson,
294
+ children: JSON.stringify(event.capturedProps, null, 2)
295
+ })
296
+ })
297
+ })]
298
+ })]
299
+ });
300
+ }
301
+
302
+ /**
303
+ * Diff mode types
304
+ */
305
+
306
+ /**
307
+ * Diff View - shows comparison between two render events
308
+ */
309
+ function DiffView({
310
+ previousEvent,
311
+ currentEvent,
312
+ render
313
+ }) {
314
+ // Diff mode tab state
315
+ const [diffMode, setDiffMode] = (0, _react.useState)("props");
316
+ if (!previousEvent || !currentEvent) {
317
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
318
+ style: styles.noEventContainer,
319
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
320
+ style: styles.noEventText,
321
+ children: "Select an event with a previous event to compare"
322
+ })
323
+ });
324
+ }
325
+ const prevCauseConfig = _RenderCauseBadge.CAUSE_CONFIG[previousEvent.cause.type];
326
+ const currCauseConfig = _RenderCauseBadge.CAUSE_CONFIG[currentEvent.cause.type];
327
+
328
+ // Check what data is available for diff
329
+ const hasPropsData = previousEvent.capturedProps && currentEvent.capturedProps;
330
+ const hasStateData = previousEvent.capturedState && currentEvent.capturedState;
331
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
332
+ style: styles.diffContainer,
333
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
334
+ style: styles.compareBar,
335
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
336
+ style: styles.compareSide,
337
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
338
+ style: styles.compareLabelRow,
339
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
340
+ style: [styles.compareLabel, {
341
+ color: _sharedUi.buoyColors.warning
342
+ }],
343
+ children: "PREV"
344
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
345
+ style: [styles.compareActionBadge, {
346
+ backgroundColor: `${prevCauseConfig.color}20`
347
+ }],
348
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
349
+ style: [styles.compareActionText, {
350
+ color: prevCauseConfig.color
351
+ }],
352
+ children: previousEvent.cause.type.toUpperCase()
353
+ })
354
+ })]
355
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
356
+ style: styles.compareMeta,
357
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
358
+ style: styles.compareIndex,
359
+ children: ["#", previousEvent.renderNumber]
360
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
361
+ style: styles.compareTime,
362
+ children: formatTimeWithMs(previousEvent.timestamp)
363
+ })]
364
+ })]
365
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
366
+ style: styles.compareDivider,
367
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
368
+ style: styles.compareArrow,
369
+ children: "\u2192"
370
+ })
371
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
372
+ style: styles.compareSide,
373
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
374
+ style: styles.compareLabelRow,
375
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
376
+ style: [styles.compareLabel, {
377
+ color: _sharedUi.buoyColors.success
378
+ }],
379
+ children: "CUR"
380
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
381
+ style: [styles.compareActionBadge, {
382
+ backgroundColor: `${currCauseConfig.color}20`
383
+ }],
384
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
385
+ style: [styles.compareActionText, {
386
+ color: currCauseConfig.color
387
+ }],
388
+ children: currentEvent.cause.type.toUpperCase()
389
+ })
390
+ })]
391
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
392
+ style: styles.compareMeta,
393
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
394
+ style: styles.compareIndex,
395
+ children: ["#", currentEvent.renderNumber]
396
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
397
+ style: styles.compareTime,
398
+ children: formatTimeWithMs(currentEvent.timestamp)
399
+ })]
400
+ })]
401
+ })]
402
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
403
+ style: styles.diffModeTabs,
404
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
405
+ style: [styles.diffModeTab, diffMode === "cause" && styles.diffModeTabActive],
406
+ onPress: () => setDiffMode("cause"),
407
+ activeOpacity: 0.7,
408
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
409
+ style: [styles.diffModeTabText, diffMode === "cause" && styles.diffModeTabTextActive],
410
+ children: "CAUSE"
411
+ })
412
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
413
+ style: [styles.diffModeTab, diffMode === "props" && styles.diffModeTabActive, !hasPropsData && styles.diffModeTabDisabled],
414
+ onPress: () => hasPropsData && setDiffMode("props"),
415
+ activeOpacity: hasPropsData ? 0.7 : 1,
416
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
417
+ style: [styles.diffModeTabText, diffMode === "props" && styles.diffModeTabTextActive, !hasPropsData && styles.diffModeTabTextDisabled],
418
+ children: "PROPS"
419
+ })
420
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
421
+ style: [styles.diffModeTab, diffMode === "state" && styles.diffModeTabActive, !hasStateData && styles.diffModeTabDisabled],
422
+ onPress: () => hasStateData && setDiffMode("state"),
423
+ activeOpacity: hasStateData ? 0.7 : 1,
424
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
425
+ style: [styles.diffModeTabText, diffMode === "state" && styles.diffModeTabTextActive, !hasStateData && styles.diffModeTabTextDisabled],
426
+ children: "STATE"
427
+ })
428
+ })]
429
+ }), diffMode === "cause" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
430
+ style: styles.diffSummary,
431
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_RenderCauseBadge.EnhancedCauseDisplay, {
432
+ cause: currentEvent.cause,
433
+ nativeType: render.viewType
434
+ })
435
+ }), diffMode === "props" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
436
+ style: styles.treeDiffContainer,
437
+ children: hasPropsData ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.TreeDiffViewer, {
438
+ oldValue: previousEvent.capturedProps,
439
+ newValue: currentEvent.capturedProps,
440
+ theme: "dark",
441
+ showUnchanged: true
442
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
443
+ style: styles.noDiffData,
444
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
445
+ style: styles.noDiffDataTitle,
446
+ children: "Props Not Captured"
447
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
448
+ style: styles.noDiffDataText,
449
+ children: "Enable \"Capture Props on Render\" in settings to see props diff."
450
+ })]
451
+ })
452
+ }), diffMode === "state" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
453
+ style: styles.treeDiffContainer,
454
+ children: hasStateData ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.TreeDiffViewer, {
455
+ oldValue: previousEvent.capturedState,
456
+ newValue: currentEvent.capturedState,
457
+ theme: "dark",
458
+ showUnchanged: true
459
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
460
+ style: styles.noDiffData,
461
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
462
+ style: styles.noDiffDataTitle,
463
+ children: "State Not Captured"
464
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
465
+ style: styles.noDiffDataText,
466
+ children: "Enable \"Capture State on Render\" in settings to see state diff."
467
+ })]
468
+ })
469
+ })]
470
+ });
471
+ }
472
+
473
+ /**
474
+ * External footer component for modal integration
475
+ * Uses renderHistory for events (only available when history tracking is enabled)
476
+ */
477
+ function RenderHistoryFooter({
478
+ render,
479
+ selectedEventIndex = 0,
480
+ onEventIndexChange = () => {},
481
+ isPro = false
482
+ }) {
483
+ // Get all events from render history (sorted by timestamp)
484
+ const allEvents = (0, _react.useMemo)(() => {
485
+ if (!render.renderHistory || render.renderHistory.length === 0) {
486
+ return [];
487
+ }
488
+ return [...render.renderHistory].sort((a, b) => a.timestamp - b.timestamp);
489
+ }, [render.renderHistory]);
490
+
491
+ // Same cap as RenderHistoryViewer above; `isPro` remains a caller override.
492
+ const tierLimit = (0, _sharedUi.useLimit)("highlightUpdates.historyEvents");
493
+ const eventLimit = isPro ? Infinity : tierLimit;
494
+
495
+ // Most recent N (negative index clamps to 0, so unlimited returns all).
496
+ const events = (0, _react.useMemo)(() => allEvents.slice(-eventLimit), [allEvents, eventLimit]);
497
+ const totalEvents = events.length;
498
+ const currentEvent = events[selectedEventIndex];
499
+ const goToPrevious = (0, _react.useCallback)(() => {
500
+ onEventIndexChange(Math.max(0, selectedEventIndex - 1));
501
+ }, [selectedEventIndex, onEventIndexChange]);
502
+ const goToNext = (0, _react.useCallback)(() => {
503
+ onEventIndexChange(Math.min(totalEvents - 1, selectedEventIndex + 1));
504
+ }, [selectedEventIndex, totalEvents, onEventIndexChange]);
505
+
506
+ // Don't render if no history events (history tracking might be disabled)
507
+ if (totalEvents <= 1) {
508
+ return null;
509
+ }
510
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.EventStepperFooter, {
511
+ currentIndex: selectedEventIndex,
512
+ totalItems: totalEvents,
513
+ onPrevious: goToPrevious,
514
+ onNext: goToNext,
515
+ itemLabel: "Render",
516
+ subtitle: currentEvent ? (0, _sharedUi.formatRelativeTime)(new Date(currentEvent.timestamp)) : undefined
517
+ });
518
+ }
519
+ const styles = _reactNative.StyleSheet.create({
520
+ container: {
521
+ flex: 1,
522
+ // Transparent so JsModal's ToolBackground shows through (the modal paints opaque base beneath it).
523
+ backgroundColor: "transparent"
524
+ },
525
+ emptyContainer: {
526
+ flex: 1,
527
+ alignItems: "center",
528
+ justifyContent: "center",
529
+ padding: 32,
530
+ gap: 12
531
+ },
532
+ emptyTitle: {
533
+ fontSize: 16,
534
+ fontWeight: "600",
535
+ color: _sharedUi.night.color.text
536
+ },
537
+ emptyText: {
538
+ fontSize: 13,
539
+ color: _sharedUi.night.color.textSecondary,
540
+ textAlign: "center",
541
+ lineHeight: 18
542
+ },
543
+ viewToggleContainer: {
544
+ flexDirection: "row",
545
+ padding: 12,
546
+ gap: 8
547
+ },
548
+ viewToggleCard: {
549
+ flex: 1,
550
+ backgroundColor: _sharedUi.night.color.surface,
551
+ borderRadius: 8,
552
+ borderWidth: 1,
553
+ borderColor: _sharedUi.night.color.border,
554
+ padding: 10,
555
+ gap: 4
556
+ },
557
+ viewToggleCardActive: {
558
+ borderColor: _sharedUi.night.color.accentBorderStrong,
559
+ backgroundColor: _sharedUi.night.color.accentSoft
560
+ },
561
+ viewToggleCardDisabled: {
562
+ opacity: 0.5
563
+ },
564
+ todoBadge: {
565
+ backgroundColor: _sharedUi.night.color.fillSecondary,
566
+ paddingHorizontal: 6,
567
+ paddingVertical: 2,
568
+ borderRadius: 4,
569
+ marginLeft: 4
570
+ },
571
+ todoBadgeText: {
572
+ fontSize: 9,
573
+ fontWeight: "700",
574
+ color: _sharedUi.night.color.textTertiary,
575
+ letterSpacing: 0.3
576
+ },
577
+ viewToggleContent: {
578
+ flexDirection: "row",
579
+ alignItems: "center",
580
+ gap: 6
581
+ },
582
+ viewToggleLabel: {
583
+ fontSize: 10,
584
+ fontWeight: "700",
585
+ color: _sharedUi.night.color.textSecondary,
586
+ letterSpacing: 0.5
587
+ },
588
+ viewToggleLabelActive: {
589
+ color: _sharedUi.night.color.accent
590
+ },
591
+ viewToggleLabelDisabled: {
592
+ color: _sharedUi.night.color.textTertiary
593
+ },
594
+ viewToggleDescription: {
595
+ fontSize: 11,
596
+ color: _sharedUi.night.color.textTertiary,
597
+ marginTop: 2
598
+ },
599
+ contentScroll: {
600
+ flex: 1
601
+ },
602
+ contentContainer: {
603
+ padding: 12,
604
+ paddingTop: 0
605
+ },
606
+ noEventContainer: {
607
+ padding: 24,
608
+ alignItems: "center"
609
+ },
610
+ noEventText: {
611
+ fontSize: 13,
612
+ color: _sharedUi.night.color.textTertiary
613
+ },
614
+ currentStateContainer: {
615
+ gap: 12
616
+ },
617
+ eventHeader: {
618
+ flexDirection: "row",
619
+ alignItems: "center",
620
+ justifyContent: "space-between",
621
+ backgroundColor: _sharedUi.night.color.surface,
622
+ borderRadius: 8,
623
+ borderWidth: 1,
624
+ borderColor: _sharedUi.night.color.border,
625
+ padding: 12
626
+ },
627
+ eventHeaderLeft: {
628
+ gap: 2
629
+ },
630
+ eventTitle: {
631
+ fontSize: 15,
632
+ fontWeight: "700",
633
+ color: _sharedUi.night.color.text
634
+ },
635
+ eventTime: {
636
+ fontSize: 11,
637
+ color: _sharedUi.night.color.textTertiary,
638
+ fontFamily: _sharedUi.monoFont
639
+ },
640
+ eventBadge: {
641
+ flexDirection: "row",
642
+ alignItems: "center",
643
+ paddingHorizontal: 10,
644
+ paddingVertical: 4,
645
+ borderRadius: 12,
646
+ gap: 6
647
+ },
648
+ eventBadgeDot: {
649
+ width: 6,
650
+ height: 6,
651
+ borderRadius: 3
652
+ },
653
+ eventBadgeText: {
654
+ fontSize: 10,
655
+ fontWeight: "700",
656
+ fontFamily: _sharedUi.monoFont
657
+ },
658
+ section: {
659
+ backgroundColor: _sharedUi.night.color.surface,
660
+ borderRadius: 8,
661
+ borderWidth: 1,
662
+ borderColor: _sharedUi.night.color.border,
663
+ overflow: "hidden"
664
+ },
665
+ sectionContent: {
666
+ padding: 12,
667
+ paddingTop: 8
668
+ },
669
+ causeContainer: {
670
+ marginBottom: 12
671
+ },
672
+ changedList: {
673
+ marginBottom: 12,
674
+ paddingLeft: 4
675
+ },
676
+ changedListTitle: {
677
+ fontSize: 11,
678
+ fontWeight: "600",
679
+ color: _sharedUi.night.color.textSecondary,
680
+ marginBottom: 6
681
+ },
682
+ changedItem: {
683
+ fontSize: 12,
684
+ color: _sharedUi.night.color.text,
685
+ fontFamily: _sharedUi.monoFont,
686
+ marginBottom: 3,
687
+ paddingLeft: 8
688
+ },
689
+ propsScrollView: {
690
+ maxHeight: 150
691
+ },
692
+ propsJson: {
693
+ fontSize: 11,
694
+ fontFamily: _sharedUi.monoFont,
695
+ color: _sharedUi.night.color.text,
696
+ // Inset code box — the night track color.
697
+ backgroundColor: _sharedUi.night.color.bg,
698
+ padding: 10,
699
+ borderRadius: 6
700
+ },
701
+ diffContainer: {
702
+ gap: 12
703
+ },
704
+ compareBar: {
705
+ flexDirection: "row",
706
+ backgroundColor: _sharedUi.night.color.surface,
707
+ borderRadius: 8,
708
+ borderWidth: 1,
709
+ borderColor: _sharedUi.night.color.border,
710
+ padding: 10
711
+ },
712
+ compareSide: {
713
+ flex: 1,
714
+ gap: 4
715
+ },
716
+ compareLabelRow: {
717
+ flexDirection: "row",
718
+ alignItems: "center",
719
+ gap: 8
720
+ },
721
+ compareLabel: {
722
+ fontSize: 10,
723
+ fontWeight: "700",
724
+ letterSpacing: 0.5
725
+ },
726
+ compareActionBadge: {
727
+ paddingHorizontal: 6,
728
+ paddingVertical: 2,
729
+ borderRadius: 4
730
+ },
731
+ compareActionText: {
732
+ fontSize: 9,
733
+ fontWeight: "600"
734
+ },
735
+ compareMeta: {
736
+ flexDirection: "row",
737
+ alignItems: "center",
738
+ gap: 6
739
+ },
740
+ compareIndex: {
741
+ fontSize: 12,
742
+ fontWeight: "600",
743
+ color: _sharedUi.night.color.text
744
+ },
745
+ compareTime: {
746
+ fontSize: 10,
747
+ color: _sharedUi.night.color.textTertiary,
748
+ fontFamily: _sharedUi.monoFont
749
+ },
750
+ compareDivider: {
751
+ width: 30,
752
+ alignItems: "center",
753
+ justifyContent: "center"
754
+ },
755
+ compareArrow: {
756
+ fontSize: 16,
757
+ color: _sharedUi.night.color.textTertiary
758
+ },
759
+ diffSummary: {
760
+ backgroundColor: _sharedUi.night.color.surface,
761
+ borderRadius: 8,
762
+ borderWidth: 1,
763
+ borderColor: _sharedUi.night.color.border,
764
+ padding: 12
765
+ },
766
+ diffSummaryTitle: {
767
+ fontSize: 11,
768
+ fontWeight: "600",
769
+ color: _sharedUi.night.color.textSecondary,
770
+ marginBottom: 8
771
+ },
772
+ diffChanges: {
773
+ gap: 4
774
+ },
775
+ diffChangeItem: {
776
+ flexDirection: "row",
777
+ alignItems: "center",
778
+ gap: 6
779
+ },
780
+ diffChangeIcon: {
781
+ fontSize: 12,
782
+ fontWeight: "700",
783
+ color: _sharedUi.night.color.warning,
784
+ fontFamily: _sharedUi.monoFont
785
+ },
786
+ diffChangeKey: {
787
+ fontSize: 12,
788
+ color: _sharedUi.night.color.text,
789
+ fontFamily: _sharedUi.monoFont
790
+ },
791
+ diffNoChanges: {
792
+ fontSize: 12,
793
+ color: _sharedUi.night.color.textTertiary,
794
+ fontStyle: "italic"
795
+ },
796
+ diffPlaceholder: {
797
+ fontSize: 12,
798
+ color: _sharedUi.night.color.textTertiary,
799
+ fontStyle: "italic",
800
+ textAlign: "center",
801
+ padding: 16
802
+ },
803
+ // Diff mode tabs
804
+ diffModeTabs: {
805
+ flexDirection: "row",
806
+ backgroundColor: _sharedUi.night.color.surface,
807
+ borderRadius: 8,
808
+ borderWidth: 1,
809
+ borderColor: _sharedUi.night.color.border,
810
+ padding: 4,
811
+ gap: 4
812
+ },
813
+ diffModeTab: {
814
+ flex: 1,
815
+ paddingVertical: 8,
816
+ paddingHorizontal: 12,
817
+ borderRadius: 6,
818
+ alignItems: "center"
819
+ },
820
+ diffModeTabActive: {
821
+ backgroundColor: _sharedUi.night.color.accentSoft
822
+ },
823
+ diffModeTabDisabled: {
824
+ opacity: 0.4
825
+ },
826
+ diffModeTabText: {
827
+ fontSize: 10,
828
+ fontWeight: "600",
829
+ color: _sharedUi.night.color.textSecondary,
830
+ letterSpacing: 0.5
831
+ },
832
+ diffModeTabTextActive: {
833
+ color: _sharedUi.night.color.accent
834
+ },
835
+ diffModeTabTextDisabled: {
836
+ color: _sharedUi.night.color.textTertiary
837
+ },
838
+ // Cause diff styles
839
+ causeDiffContainer: {
840
+ gap: 8,
841
+ marginBottom: 12
842
+ },
843
+ causeDiffRow: {
844
+ flexDirection: "row",
845
+ alignItems: "center",
846
+ gap: 8
847
+ },
848
+ causeDiffLabel: {
849
+ fontSize: 11,
850
+ fontWeight: "600",
851
+ color: _sharedUi.night.color.textSecondary,
852
+ minWidth: 80
853
+ },
854
+ causeDiffValue: {
855
+ fontSize: 12,
856
+ color: _sharedUi.night.color.text,
857
+ fontFamily: _sharedUi.monoFont,
858
+ fontWeight: "500"
859
+ },
860
+ diffChangesTitle: {
861
+ fontSize: 11,
862
+ fontWeight: "600",
863
+ color: _sharedUi.night.color.textSecondary,
864
+ marginBottom: 6
865
+ },
866
+ // Tree diff container
867
+ treeDiffContainer: {
868
+ backgroundColor: _sharedUi.night.color.surface,
869
+ borderRadius: 8,
870
+ borderWidth: 1,
871
+ borderColor: _sharedUi.night.color.border,
872
+ overflow: "hidden",
873
+ minHeight: 150
874
+ },
875
+ noDiffData: {
876
+ padding: 24,
877
+ alignItems: "center",
878
+ gap: 8
879
+ },
880
+ noDiffDataTitle: {
881
+ fontSize: 13,
882
+ fontWeight: "600",
883
+ color: _sharedUi.night.color.text
884
+ },
885
+ noDiffDataText: {
886
+ fontSize: 12,
887
+ color: _sharedUi.night.color.textTertiary,
888
+ textAlign: "center",
889
+ lineHeight: 18
890
+ },
891
+ lockedBanner: {
892
+ flexDirection: "row",
893
+ alignItems: "center",
894
+ justifyContent: "center",
895
+ paddingVertical: 10,
896
+ paddingHorizontal: 16,
897
+ marginHorizontal: 12,
898
+ marginTop: 8,
899
+ backgroundColor: _sharedUi.night.color.warningSoft,
900
+ borderRadius: 8,
901
+ borderWidth: 1,
902
+ borderColor: _sharedUi.night.color.warning + "30",
903
+ gap: 8
904
+ },
905
+ lockedBannerText: {
906
+ color: _sharedUi.night.color.warning,
907
+ fontSize: 13,
908
+ fontWeight: "500"
909
+ },
910
+ lockedBannerSubtext: {
911
+ color: _sharedUi.night.color.textTertiary,
912
+ fontSize: 12
913
+ }
914
+ });
915
+ var _default = exports.default = RenderHistoryViewer;