@buoy-gg/highlight-updates 3.0.1 → 4.0.1

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 (83) hide show
  1. package/lib/commonjs/highlight-updates/HighlightUpdatesOverlay.js +285 -1
  2. package/lib/commonjs/highlight-updates/components/HighlightFilterView.js +1371 -1
  3. package/lib/commonjs/highlight-updates/components/HighlightUpdatesModal.js +564 -1
  4. package/lib/commonjs/highlight-updates/components/IdentifierBadge.js +267 -1
  5. package/lib/commonjs/highlight-updates/components/IsolatedRenderList.js +178 -1
  6. package/lib/commonjs/highlight-updates/components/ModalHeaderContent.js +309 -1
  7. package/lib/commonjs/highlight-updates/components/RenderCauseBadge.js +500 -1
  8. package/lib/commonjs/highlight-updates/components/RenderDetailView.js +803 -1
  9. package/lib/commonjs/highlight-updates/components/RenderHistoryViewer.js +894 -1
  10. package/lib/commonjs/highlight-updates/components/RenderListItem.js +220 -1
  11. package/lib/commonjs/highlight-updates/components/RendersCopySettingsView.js +562 -1
  12. package/lib/commonjs/highlight-updates/components/StatsDisplay.js +70 -1
  13. package/lib/commonjs/highlight-updates/components/index.js +97 -1
  14. package/lib/commonjs/highlight-updates/types/copySettings.js +107 -1
  15. package/lib/commonjs/highlight-updates/utils/HighlightUpdatesController.js +1819 -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 +1828 -1
  19. package/lib/commonjs/highlight-updates/utils/RenderTracker.js +919 -1
  20. package/lib/commonjs/highlight-updates/utils/ViewTypeMapper.js +264 -1
  21. package/lib/commonjs/highlight-updates/utils/copySettingsStorage.js +49 -1
  22. package/lib/commonjs/highlight-updates/utils/renderExportFormatter.js +58 -1
  23. package/lib/commonjs/highlight-updates/utils/rendersExportFormatter.js +485 -1
  24. package/lib/commonjs/index.js +320 -1
  25. package/lib/commonjs/preset.js +278 -1
  26. package/lib/commonjs/sync/highlightUpdatesSyncAdapter.js +83 -0
  27. package/lib/module/highlight-updates/HighlightUpdatesOverlay.js +278 -1
  28. package/lib/module/highlight-updates/components/HighlightFilterView.js +1365 -1
  29. package/lib/module/highlight-updates/components/HighlightUpdatesModal.js +558 -1
  30. package/lib/module/highlight-updates/components/IdentifierBadge.js +259 -1
  31. package/lib/module/highlight-updates/components/IsolatedRenderList.js +174 -1
  32. package/lib/module/highlight-updates/components/ModalHeaderContent.js +304 -1
  33. package/lib/module/highlight-updates/components/RenderCauseBadge.js +491 -1
  34. package/lib/module/highlight-updates/components/RenderDetailView.js +797 -1
  35. package/lib/module/highlight-updates/components/RenderHistoryViewer.js +888 -1
  36. package/lib/module/highlight-updates/components/RenderListItem.js +215 -1
  37. package/lib/module/highlight-updates/components/RendersCopySettingsView.js +558 -1
  38. package/lib/module/highlight-updates/components/StatsDisplay.js +67 -1
  39. package/lib/module/highlight-updates/components/index.js +16 -1
  40. package/lib/module/highlight-updates/types/copySettings.js +102 -1
  41. package/lib/module/highlight-updates/utils/HighlightUpdatesController.js +1815 -1
  42. package/lib/module/highlight-updates/utils/PerformanceLogger.js +353 -1
  43. package/lib/module/highlight-updates/utils/ProfilerInterceptor.js +358 -1
  44. package/lib/module/highlight-updates/utils/RenderCauseDetector.js +1818 -1
  45. package/lib/module/highlight-updates/utils/RenderTracker.js +916 -1
  46. package/lib/module/highlight-updates/utils/ViewTypeMapper.js +255 -1
  47. package/lib/module/highlight-updates/utils/copySettingsStorage.js +43 -1
  48. package/lib/module/highlight-updates/utils/renderExportFormatter.js +54 -1
  49. package/lib/module/highlight-updates/utils/rendersExportFormatter.js +478 -1
  50. package/lib/module/index.js +74 -1
  51. package/lib/module/preset.js +272 -1
  52. package/lib/module/sync/highlightUpdatesSyncAdapter.js +78 -0
  53. package/lib/typescript/highlight-updates/HighlightUpdatesOverlay.d.ts.map +1 -0
  54. package/lib/typescript/highlight-updates/components/HighlightFilterView.d.ts.map +1 -0
  55. package/lib/typescript/highlight-updates/components/HighlightUpdatesModal.d.ts.map +1 -0
  56. package/lib/typescript/highlight-updates/components/IdentifierBadge.d.ts.map +1 -0
  57. package/lib/typescript/highlight-updates/components/IsolatedRenderList.d.ts.map +1 -0
  58. package/lib/typescript/highlight-updates/components/ModalHeaderContent.d.ts.map +1 -0
  59. package/lib/typescript/highlight-updates/components/RenderCauseBadge.d.ts.map +1 -0
  60. package/lib/typescript/highlight-updates/components/RenderDetailView.d.ts.map +1 -0
  61. package/lib/typescript/highlight-updates/components/RenderHistoryViewer.d.ts.map +1 -0
  62. package/lib/typescript/highlight-updates/components/RenderListItem.d.ts.map +1 -0
  63. package/lib/typescript/highlight-updates/components/RendersCopySettingsView.d.ts.map +1 -0
  64. package/lib/typescript/highlight-updates/components/StatsDisplay.d.ts.map +1 -0
  65. package/lib/typescript/highlight-updates/components/index.d.ts.map +1 -0
  66. package/lib/typescript/highlight-updates/types/copySettings.d.ts.map +1 -0
  67. package/lib/typescript/highlight-updates/utils/HighlightUpdatesController.d.ts +90 -0
  68. package/lib/typescript/highlight-updates/utils/HighlightUpdatesController.d.ts.map +1 -0
  69. package/lib/typescript/highlight-updates/utils/PerformanceLogger.d.ts.map +1 -0
  70. package/lib/typescript/highlight-updates/utils/ProfilerInterceptor.d.ts.map +1 -0
  71. package/lib/typescript/highlight-updates/utils/RenderCauseDetector.d.ts.map +1 -0
  72. package/lib/typescript/highlight-updates/utils/RenderTracker.d.ts +10 -0
  73. package/lib/typescript/highlight-updates/utils/RenderTracker.d.ts.map +1 -0
  74. package/lib/typescript/highlight-updates/utils/ViewTypeMapper.d.ts.map +1 -0
  75. package/lib/typescript/highlight-updates/utils/copySettingsStorage.d.ts.map +1 -0
  76. package/lib/typescript/highlight-updates/utils/renderExportFormatter.d.ts.map +1 -0
  77. package/lib/typescript/highlight-updates/utils/rendersExportFormatter.d.ts.map +1 -0
  78. package/lib/typescript/index.d.ts +1 -0
  79. package/lib/typescript/index.d.ts.map +1 -0
  80. package/lib/typescript/preset.d.ts.map +1 -0
  81. package/lib/typescript/sync/highlightUpdatesSyncAdapter.d.ts +36 -0
  82. package/lib/typescript/sync/highlightUpdatesSyncAdapter.d.ts.map +1 -0
  83. package/package.json +7 -7
@@ -1 +1,803 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.RenderDetailView=RenderDetailView,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"),_RenderCauseBadge=require("./RenderCauseBadge"),_rendersExportFormatter=require("../utils/rendersExportFormatter"),_jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(e,t){if("function"==typeof WeakMap)var r=new WeakMap,s=new WeakMap;return(_interopRequireWildcard=function(e,t){if(!t&&e&&e.__esModule)return e;var i,a,o={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return o;if(i=t?s:r){if(i.has(e))return i.get(e);i.set(e,o)}for(const t in e)"default"!==t&&{}.hasOwnProperty.call(e,t)&&((a=(i=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,t))&&(a.get||a.set)?i(o,t,a):o[t]=e[t]);return o})(e,t)}const FREE_TIER_EVENT_LIMIT=5;function RenderDetailView({render:e,disableInternalFooter:t=!1,selectedEventIndex:r,onEventIndexChange:s,onAddFilter:i,isPro:a=!1}){const[o,n]=(0,_react.useState)(0),l=r??o,d=s??n,c=(0,_react.useMemo)(()=>e.renderHistory&&0!==e.renderHistory.length?[...e.renderHistory].sort((e,t)=>e.timestamp-t.timestamp):[],[e.renderHistory]),u=c.length,y=c[l],x=(0,_react.useMemo)(()=>a?0:Math.max(0,u-FREE_TIER_EVENT_LIMIT),[a,u]),_=y?.cause||e.lastRenderCause,m=(0,_react.useCallback)(()=>{l>0&&d(l-1)},[l,d]),h=(0,_react.useCallback)(()=>{const e=a?u-1:Math.min(FREE_TIER_EVENT_LIMIT-1,u-1);l<e&&d(l+1)},[l,u,d,a]),p=(0,_react.useMemo)(()=>(0,_rendersExportFormatter.generateSingleComponentExport)(e),[e]),b=e.componentName||e.displayName,j=e.viewType,C=e.lastRenderTime-e.firstRenderTime,g=C>0?(e.renderCount/(C/1e3)).toFixed(1):e.renderCount.toString(),f=!t&&u>1;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.container,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.header,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.headerLeft,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.componentName,numberOfLines:1,children:b}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.nativeTypeBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.nativeTypeText,children:j})})]}),(0,_jsxRuntime.jsx)(_sharedUi.CopyButton,{value:p,size:14})]}),(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{style:styles.scrollView,contentContainerStyle:[styles.scrollContent,f&&{paddingBottom:100}],showsVerticalScrollIndicator:!1,children:[_&&(0,_jsxRuntime.jsx)(AnswerCard,{cause:_,renderNumber:y?.renderNumber}),(0,_jsxRuntime.jsx)(DetailsSection,{render:e,rendersPerSec:g}),x>0&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.lockedBanner,children:[(0,_jsxRuntime.jsx)(_sharedUi.Lock,{size:14,color:_sharedUi.buoyColors.warning}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.lockedBannerText,children:[x," ",1===x?"event":"events"," hidden"]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.lockedBannerSubtext,children:"Upgrade to Pro"})]}),i&&(0,_jsxRuntime.jsx)(QuickActionsSection,{render:e,onAddFilter:i})]}),f&&(0,_jsxRuntime.jsx)(_sharedUi.EventStepperFooter,{currentIndex:l,totalItems:u,onPrevious:m,onNext:h,itemLabel:"Render",subtitle:y?.timestamp?(0,_sharedUi.formatRelativeTime)(new Date(y.timestamp)):void 0,applySafeAreaInset:!1,absolute:!0})]})}function AnswerCard({cause:e,renderNumber:t}){const r=e.componentCause||e.type,s=e.componentCause?_RenderCauseBadge.COMPONENT_CAUSE_CONFIG[e.componentCause]:_RenderCauseBadge.CAUSE_CONFIG[e.type],i=e.hookChanges&&e.hookChanges.length>0,a=e.changedKeys&&e.changedKeys.length>0;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.answerCard,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.causeBadgeRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.causeLabel,children:"mount"===e.type?"First render":"parent"===r?"Triggered by":"Changed:"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.causeBadgeLarge,{backgroundColor:s.color+"20"}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.causeBadgeLargeText,{color:s.color}],children:s.label.toUpperCase()})})]}),i&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.hookChangesContainer,children:e.hookChanges.map((e,t)=>{const r=`${e.type}[${e.index}]`,s={[r]:e.previousValue},i={[r]:e.currentValue};return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.hookDiffContainer,children:(0,_jsxRuntime.jsx)(_dataViewer.TreeDiffViewer,{oldValue:s,newValue:i,theme:"dark",showUnchanged:!1})},t)})}),!i&&a&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.propsChangesContainer,children:e.changedKeys.filter(e=>!e.includes("(ref only)")).slice(0,5).map((e,t)=>(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.propChangeChip,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.propChangeText,children:e})},t))})]})}function DetailsSection({render:e,rendersPerSec:t}){const r=e.testID||e.nativeID||e.accessibilityLabel,s=e.measurements;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.detailsSection,children:[r&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.detailsCard,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailsCardTitle,children:"Identifiers"}),e.testID&&(0,_jsxRuntime.jsx)(DetailRow,{label:"testID",value:e.testID}),e.nativeID&&(0,_jsxRuntime.jsx)(DetailRow,{label:"nativeID",value:e.nativeID}),e.accessibilityLabel&&(0,_jsxRuntime.jsx)(DetailRow,{label:"a11y",value:e.accessibilityLabel})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.statsRow,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.statItem,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.statValue,{color:e.color}],children:e.renderCount}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.statLabel,children:"renders"})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.statDivider}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.statItem,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.statValue,children:t}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.statLabel,children:"/sec"})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.statDivider}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.statItem,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.statValue,children:e.nativeTag}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.statLabel,children:"tag"})]})]}),s&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.measurementsRow,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.measurementItem,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.measurementLabel,children:"x"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.measurementValue,children:Math.round(e.measurements.x)})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.measurementItem,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.measurementLabel,children:"y"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.measurementValue,children:Math.round(e.measurements.y)})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.measurementItem,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.measurementLabel,children:"w"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.measurementValue,children:Math.round(e.measurements.width)})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.measurementItem,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.measurementLabel,children:"h"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.measurementValue,children:Math.round(e.measurements.height)})]})]})]})}function DetailRow({label:e,value:t}){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.detailRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailLabel,children:e}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailValue,numberOfLines:1,children:t})]})}function QuickActionsSection({render:e,onAddFilter:t}){const[r,s]=(0,_react.useState)(null),i=(0,_react.useMemo)(()=>{const t=[];return e.nativeID&&t.push({type:"nativeID",value:e.nativeID,label:"nativeID"}),e.testID&&t.push({type:"testID",value:e.testID,label:"testID"}),e.accessibilityLabel&&t.push({type:"accessibilityLabel",value:e.accessibilityLabel,label:"a11y"}),e.componentName&&t.push({type:"component",value:e.componentName,label:"component"}),t.push({type:"viewType",value:e.viewType,label:"viewType"}),t},[e]),a=null!==r?i[r]:null,o=(0,_react.useCallback)(e=>{s(t=>t===e?null:e)},[]),n=(0,_react.useCallback)(()=>{a&&(t({type:a.type,value:a.value},"include"),s(null))},[a,t]),l=(0,_react.useCallback)(()=>{a&&(t({type:a.type,value:a.value},"exclude"),s(null))},[a,t]);return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.quickActionsSection,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.quickActionsTitle,children:"Quick Filters"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.filterOptionsList,children:i.map((e,t)=>(0,_jsxRuntime.jsx)(FilterOptionCard,{label:e.label,value:e.value,isSelected:r===t,onSelect:()=>o(t)},e.type))}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.filterActionButtons,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:[styles.filterActionButton,styles.filterActionButtonInclude,!a&&styles.filterActionButtonDisabled],onPress:n,disabled:!a,activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_sharedUi.PlusIcon,{size:14,color:a?_sharedUi.buoyColors.success:_sharedUi.buoyColors.textMuted}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.filterActionButtonText,{color:a?_sharedUi.buoyColors.success:_sharedUi.buoyColors.textMuted}],children:"Only Show This"})]}),(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:[styles.filterActionButton,styles.filterActionButtonExclude,!a&&styles.filterActionButtonDisabled],onPress:l,disabled:!a,activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_sharedUi.MinusIcon,{size:14,color:a?_sharedUi.buoyColors.error:_sharedUi.buoyColors.textMuted}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.filterActionButtonText,{color:a?_sharedUi.buoyColors.error:_sharedUi.buoyColors.textMuted}],children:"Hide This"})]})]})]})}function FilterOptionCard({label:e,value:t,isSelected:r,onSelect:s}){return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:[styles.filterOptionCard,r&&styles.filterOptionCardSelected],onPress:s,activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.filterOptionLabel,r&&styles.filterOptionLabelSelected],children:e}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.filterOptionValue,r&&styles.filterOptionValueSelected],numberOfLines:1,children:t})]})}const styles=_reactNative.StyleSheet.create({container:{flex:1,backgroundColor:_sharedUi.buoyColors.base},header:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:12,padding:16,paddingBottom:0},scrollView:{flex:1},scrollContent:{padding:16,paddingTop:12,paddingBottom:80,gap:12},headerLeft:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",gap:10},componentName:{fontSize:18,fontWeight:"700",color:_sharedUi.buoyColors.text,flexShrink:1},nativeTypeBadge:{backgroundColor:_sharedUi.buoyColors.input,paddingVertical:3,paddingHorizontal:8,borderRadius:4},nativeTypeText:{fontSize:11,fontWeight:"600",color:_sharedUi.buoyColors.textMuted,fontFamily:"monospace"},answerCard:{backgroundColor:_sharedUi.buoyColors.card,borderRadius:8,borderWidth:1,borderColor:_sharedUi.buoyColors.border,padding:12,gap:6},causeBadgeRow:{flexDirection:"row",alignItems:"center",gap:8},causeBadgeLarge:{paddingVertical:4,paddingHorizontal:10,borderRadius:4},causeBadgeLargeText:{fontSize:11,fontWeight:"700",letterSpacing:.5},causeLabel:{fontSize:12,color:_sharedUi.buoyColors.textSecondary,fontWeight:"500"},hookChangesContainer:{gap:6},hookDiffContainer:{backgroundColor:_sharedUi.buoyColors.input,borderRadius:6,overflow:"hidden"},propsChangesContainer:{flexDirection:"row",flexWrap:"wrap",gap:4},propChangeChip:{backgroundColor:_sharedUi.buoyColors.input,paddingVertical:2,paddingHorizontal:6,borderRadius:4},propChangeText:{fontSize:11,color:_sharedUi.buoyColors.text,fontFamily:"monospace"},detailsSection:{gap:10},detailsCard:{backgroundColor:_sharedUi.buoyColors.card,borderRadius:8,borderWidth:1,borderColor:_sharedUi.buoyColors.border,padding:12,gap:6},detailsCardTitle:{fontSize:10,fontWeight:"600",color:_sharedUi.buoyColors.textMuted,letterSpacing:.5,textTransform:"uppercase",marginBottom:4},detailRow:{flexDirection:"row",alignItems:"center",gap:8},detailLabel:{fontSize:11,fontWeight:"600",color:_sharedUi.buoyColors.textSecondary,minWidth:55},detailValue:{fontSize:12,color:_sharedUi.buoyColors.text,fontFamily:"monospace",flex:1},statsRow:{flexDirection:"row",alignItems:"center",justifyContent:"center",backgroundColor:_sharedUi.buoyColors.card,borderRadius:8,borderWidth:1,borderColor:_sharedUi.buoyColors.border,paddingVertical:10,paddingHorizontal:16},statItem:{flex:1,alignItems:"center"},statValue:{fontSize:16,fontWeight:"700",color:_sharedUi.buoyColors.text,fontFamily:"monospace"},statLabel:{fontSize:10,color:_sharedUi.buoyColors.textMuted,marginTop:2},statDivider:{width:1,height:24,backgroundColor:_sharedUi.buoyColors.border,marginHorizontal:12},measurementsRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-around",backgroundColor:_sharedUi.buoyColors.card,borderRadius:8,borderWidth:1,borderColor:_sharedUi.buoyColors.border,paddingVertical:8,paddingHorizontal:12},measurementItem:{flexDirection:"row",alignItems:"baseline",gap:4},measurementLabel:{fontSize:10,fontWeight:"600",color:_sharedUi.buoyColors.textMuted,textTransform:"uppercase"},measurementValue:{fontSize:12,fontWeight:"600",color:_sharedUi.buoyColors.text,fontFamily:"monospace"},quickActionsSection:{backgroundColor:_sharedUi.buoyColors.card,borderRadius:8,borderWidth:1,borderColor:_sharedUi.buoyColors.border,padding:12,gap:10},quickActionsTitle:{fontSize:10,fontWeight:"600",color:_sharedUi.buoyColors.textMuted,letterSpacing:.5,textTransform:"uppercase",marginBottom:2},filterOptionsList:{gap:6},filterOptionCard:{flexDirection:"row",alignItems:"center",backgroundColor:_sharedUi.buoyColors.input,borderRadius:6,paddingVertical:10,paddingHorizontal:12,borderWidth:1,borderColor:"transparent",gap:10},filterOptionCardSelected:{borderColor:_sharedUi.buoyColors.success,backgroundColor:_sharedUi.buoyColors.success+"15"},filterOptionLabel:{fontSize:10,fontWeight:"600",color:_sharedUi.buoyColors.textMuted,minWidth:70},filterOptionLabelSelected:{color:_sharedUi.buoyColors.success},filterOptionValue:{fontSize:12,color:_sharedUi.buoyColors.text,fontFamily:"monospace",flex:1},filterOptionValueSelected:{color:_sharedUi.buoyColors.text},filterActionButtons:{flexDirection:"row",gap:8,marginTop:12},filterActionButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:4,paddingVertical:8,paddingHorizontal:10,borderRadius:6,borderWidth:1},filterActionButtonInclude:{backgroundColor:_sharedUi.buoyColors.success+"15",borderColor:_sharedUi.buoyColors.success+"40"},filterActionButtonExclude:{backgroundColor:_sharedUi.buoyColors.error+"15",borderColor:_sharedUi.buoyColors.error+"40"},filterActionButtonDisabled:{backgroundColor:_sharedUi.buoyColors.input,borderColor:_sharedUi.buoyColors.border,opacity:.5},filterActionButtonText:{fontSize:11,fontWeight:"600"},lockedBanner:{flexDirection:"row",alignItems:"center",justifyContent:"center",backgroundColor:_sharedUi.buoyColors.card,borderRadius:8,borderWidth:1,borderColor:_sharedUi.buoyColors.warning+"40",paddingVertical:12,paddingHorizontal:16,gap:8},lockedBannerText:{color:_sharedUi.buoyColors.warning,fontSize:13,fontWeight:"600"},lockedBannerSubtext:{color:_sharedUi.buoyColors.textMuted,fontSize:12}});var _default=exports.default=RenderDetailView;
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.RenderDetailView = RenderDetailView;
7
+ exports.default = void 0;
8
+ var _react = _interopRequireWildcard(require("react"));
9
+ var _reactNative = require("react-native");
10
+ var _sharedUi = require("@buoy-gg/shared-ui");
11
+ var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
12
+ var _RenderCauseBadge = require("./RenderCauseBadge");
13
+ var _rendersExportFormatter = require("../utils/rendersExportFormatter");
14
+ var _jsxRuntime = require("react/jsx-runtime");
15
+ 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); }
16
+ /**
17
+ * RenderDetailView
18
+ *
19
+ * Minimal, glanceable view for render details.
20
+ * Design principle: Dev should understand WHY in 3 seconds.
21
+ *
22
+ * Layout:
23
+ * - Header: Component name + native type
24
+ * - Answer Card: Cause badges + hook change (THE answer)
25
+ * - History Row: Compact inline navigation
26
+ */
27
+
28
+ // Free tier limit for render history events
29
+ const FREE_TIER_EVENT_LIMIT = 5;
30
+ function RenderDetailView({
31
+ render,
32
+ disableInternalFooter = false,
33
+ selectedEventIndex: externalIndex,
34
+ onEventIndexChange: externalOnChange,
35
+ onAddFilter,
36
+ isPro = false
37
+ }) {
38
+ // Internal state for event index when not controlled externally
39
+ const [internalIndex, setInternalIndex] = (0, _react.useState)(0);
40
+
41
+ // Use external or internal state
42
+ const selectedEventIndex = externalIndex ?? internalIndex;
43
+ const onEventIndexChange = externalOnChange ?? setInternalIndex;
44
+
45
+ // Get events sorted by timestamp (oldest first)
46
+ const events = (0, _react.useMemo)(() => {
47
+ if (!render.renderHistory || render.renderHistory.length === 0) {
48
+ return [];
49
+ }
50
+ return [...render.renderHistory].sort((a, b) => a.timestamp - b.timestamp);
51
+ }, [render.renderHistory]);
52
+ const totalEvents = events.length;
53
+ const currentEvent = events[selectedEventIndex];
54
+
55
+ // Calculate hidden events for free tier
56
+ const hiddenEventCount = (0, _react.useMemo)(() => {
57
+ if (isPro) return 0;
58
+ return Math.max(0, totalEvents - FREE_TIER_EVENT_LIMIT);
59
+ }, [isPro, totalEvents]);
60
+
61
+ // Use current event's cause if available, otherwise fall back to lastRenderCause
62
+ const displayCause = currentEvent?.cause || render.lastRenderCause;
63
+
64
+ // Navigation handlers
65
+ const goToPrevious = (0, _react.useCallback)(() => {
66
+ if (selectedEventIndex > 0) {
67
+ onEventIndexChange(selectedEventIndex - 1);
68
+ }
69
+ }, [selectedEventIndex, onEventIndexChange]);
70
+ const goToNext = (0, _react.useCallback)(() => {
71
+ // Limit navigation for free tier users
72
+ const maxIndex = isPro ? totalEvents - 1 : Math.min(FREE_TIER_EVENT_LIMIT - 1, totalEvents - 1);
73
+ if (selectedEventIndex < maxIndex) {
74
+ onEventIndexChange(selectedEventIndex + 1);
75
+ }
76
+ }, [selectedEventIndex, totalEvents, onEventIndexChange, isPro]);
77
+
78
+ // Memoize copy data
79
+ const copyData = (0, _react.useMemo)(() => (0, _rendersExportFormatter.generateSingleComponentExport)(render), [render]);
80
+
81
+ // Get component name (prefer componentName, fall back to displayName)
82
+ const componentName = render.componentName || render.displayName;
83
+ const nativeType = render.viewType;
84
+
85
+ // Calculate render stats
86
+ const renderDuration = render.lastRenderTime - render.firstRenderTime;
87
+ const rendersPerSec = renderDuration > 0 ? (render.renderCount / (renderDuration / 1000)).toFixed(1) : render.renderCount.toString();
88
+
89
+ // Determine if we should show footer (either history or filters)
90
+ const showHistoryFooter = !disableInternalFooter && totalEvents > 1;
91
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
92
+ style: styles.container,
93
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
94
+ style: styles.header,
95
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
96
+ style: styles.headerLeft,
97
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
98
+ style: styles.componentName,
99
+ numberOfLines: 1,
100
+ children: componentName
101
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
102
+ style: styles.nativeTypeBadge,
103
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
104
+ style: styles.nativeTypeText,
105
+ children: nativeType
106
+ })
107
+ })]
108
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CopyButton, {
109
+ value: copyData,
110
+ size: 14
111
+ })]
112
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
113
+ style: styles.scrollView,
114
+ contentContainerStyle: [styles.scrollContent, showHistoryFooter && {
115
+ paddingBottom: 100
116
+ }],
117
+ showsVerticalScrollIndicator: false,
118
+ children: [displayCause && /*#__PURE__*/(0, _jsxRuntime.jsx)(AnswerCard, {
119
+ cause: displayCause,
120
+ renderNumber: currentEvent?.renderNumber
121
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(DetailsSection, {
122
+ render: render,
123
+ rendersPerSec: rendersPerSec
124
+ }), hiddenEventCount > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
125
+ style: styles.lockedBanner,
126
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Lock, {
127
+ size: 14,
128
+ color: _sharedUi.buoyColors.warning
129
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
130
+ style: styles.lockedBannerText,
131
+ children: [hiddenEventCount, " ", hiddenEventCount === 1 ? 'event' : 'events', " hidden"]
132
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
133
+ style: styles.lockedBannerSubtext,
134
+ children: "Upgrade to Pro"
135
+ })]
136
+ }), onAddFilter && /*#__PURE__*/(0, _jsxRuntime.jsx)(QuickActionsSection, {
137
+ render: render,
138
+ onAddFilter: onAddFilter
139
+ })]
140
+ }), showHistoryFooter && /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.EventStepperFooter, {
141
+ currentIndex: selectedEventIndex,
142
+ totalItems: totalEvents,
143
+ onPrevious: goToPrevious,
144
+ onNext: goToNext,
145
+ itemLabel: "Render",
146
+ subtitle: currentEvent?.timestamp ? (0, _sharedUi.formatRelativeTime)(new Date(currentEvent.timestamp)) : undefined,
147
+ applySafeAreaInset: false,
148
+ absolute: true
149
+ })]
150
+ });
151
+ }
152
+
153
+ /**
154
+ * AnswerCard - The hero section showing WHY the component rendered
155
+ * Design: Single badge + what changed below it
156
+ */
157
+ function AnswerCard({
158
+ cause,
159
+ renderNumber
160
+ }) {
161
+ // Use component cause if available, otherwise native cause
162
+ const displayCauseType = cause.componentCause || cause.type;
163
+ const config = cause.componentCause ? _RenderCauseBadge.COMPONENT_CAUSE_CONFIG[cause.componentCause] : _RenderCauseBadge.CAUSE_CONFIG[cause.type];
164
+ const hasHookChanges = cause.hookChanges && cause.hookChanges.length > 0;
165
+ const hasChangedKeys = cause.changedKeys && cause.changedKeys.length > 0;
166
+
167
+ // Get contextual label based on cause type
168
+ const getLabel = () => {
169
+ if (cause.type === "mount") return "First render";
170
+ if (displayCauseType === "parent") return "Triggered by";
171
+ return "Changed:";
172
+ };
173
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
174
+ style: styles.answerCard,
175
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
176
+ style: styles.causeBadgeRow,
177
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
178
+ style: styles.causeLabel,
179
+ children: getLabel()
180
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
181
+ style: [styles.causeBadgeLarge, {
182
+ backgroundColor: config.color + "20"
183
+ }],
184
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
185
+ style: [styles.causeBadgeLargeText, {
186
+ color: config.color
187
+ }],
188
+ children: config.label.toUpperCase()
189
+ })
190
+ })]
191
+ }), hasHookChanges && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
192
+ style: styles.hookChangesContainer,
193
+ children: cause.hookChanges.map((hook, index) => {
194
+ const hookKey = `${hook.type}[${hook.index}]`;
195
+ const oldValue = {
196
+ [hookKey]: hook.previousValue
197
+ };
198
+ const newValue = {
199
+ [hookKey]: hook.currentValue
200
+ };
201
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
202
+ style: styles.hookDiffContainer,
203
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.TreeDiffViewer, {
204
+ oldValue: oldValue,
205
+ newValue: newValue,
206
+ theme: "dark",
207
+ showUnchanged: false
208
+ })
209
+ }, index);
210
+ })
211
+ }), !hasHookChanges && hasChangedKeys && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
212
+ style: styles.propsChangesContainer,
213
+ children: cause.changedKeys.filter(k => !k.includes("(ref only)")).slice(0, 5).map((key, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
214
+ style: styles.propChangeChip,
215
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
216
+ style: styles.propChangeText,
217
+ children: key
218
+ })
219
+ }, index))
220
+ })]
221
+ });
222
+ }
223
+
224
+ /**
225
+ * DetailsSection - Component identifiers, measurements, and stats
226
+ * Helps devs find the component in their codebase
227
+ */
228
+ function DetailsSection({
229
+ render,
230
+ rendersPerSec
231
+ }) {
232
+ const hasIdentifiers = render.testID || render.nativeID || render.accessibilityLabel;
233
+ const hasMeasurements = render.measurements;
234
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
235
+ style: styles.detailsSection,
236
+ children: [hasIdentifiers && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
237
+ style: styles.detailsCard,
238
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
239
+ style: styles.detailsCardTitle,
240
+ children: "Identifiers"
241
+ }), render.testID && /*#__PURE__*/(0, _jsxRuntime.jsx)(DetailRow, {
242
+ label: "testID",
243
+ value: render.testID
244
+ }), render.nativeID && /*#__PURE__*/(0, _jsxRuntime.jsx)(DetailRow, {
245
+ label: "nativeID",
246
+ value: render.nativeID
247
+ }), render.accessibilityLabel && /*#__PURE__*/(0, _jsxRuntime.jsx)(DetailRow, {
248
+ label: "a11y",
249
+ value: render.accessibilityLabel
250
+ })]
251
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
252
+ style: styles.statsRow,
253
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
254
+ style: styles.statItem,
255
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
256
+ style: [styles.statValue, {
257
+ color: render.color
258
+ }],
259
+ children: render.renderCount
260
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
261
+ style: styles.statLabel,
262
+ children: "renders"
263
+ })]
264
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
265
+ style: styles.statDivider
266
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
267
+ style: styles.statItem,
268
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
269
+ style: styles.statValue,
270
+ children: rendersPerSec
271
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
272
+ style: styles.statLabel,
273
+ children: "/sec"
274
+ })]
275
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
276
+ style: styles.statDivider
277
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
278
+ style: styles.statItem,
279
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
280
+ style: styles.statValue,
281
+ children: render.nativeTag
282
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
283
+ style: styles.statLabel,
284
+ children: "tag"
285
+ })]
286
+ })]
287
+ }), hasMeasurements && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
288
+ style: styles.measurementsRow,
289
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
290
+ style: styles.measurementItem,
291
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
292
+ style: styles.measurementLabel,
293
+ children: "x"
294
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
295
+ style: styles.measurementValue,
296
+ children: Math.round(render.measurements.x)
297
+ })]
298
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
299
+ style: styles.measurementItem,
300
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
301
+ style: styles.measurementLabel,
302
+ children: "y"
303
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
304
+ style: styles.measurementValue,
305
+ children: Math.round(render.measurements.y)
306
+ })]
307
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
308
+ style: styles.measurementItem,
309
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
310
+ style: styles.measurementLabel,
311
+ children: "w"
312
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
313
+ style: styles.measurementValue,
314
+ children: Math.round(render.measurements.width)
315
+ })]
316
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
317
+ style: styles.measurementItem,
318
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
319
+ style: styles.measurementLabel,
320
+ children: "h"
321
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
322
+ style: styles.measurementValue,
323
+ children: Math.round(render.measurements.height)
324
+ })]
325
+ })]
326
+ })]
327
+ });
328
+ }
329
+
330
+ /**
331
+ * DetailRow - Single row for identifier display
332
+ */
333
+ function DetailRow({
334
+ label,
335
+ value
336
+ }) {
337
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
338
+ style: styles.detailRow,
339
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
340
+ style: styles.detailLabel,
341
+ children: label
342
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
343
+ style: styles.detailValue,
344
+ numberOfLines: 1,
345
+ children: value
346
+ })]
347
+ });
348
+ }
349
+
350
+ /**
351
+ * QuickActionsSection - Quick filter actions for the component
352
+ * Users select a filter option, then use action buttons to include/exclude
353
+ */
354
+ function QuickActionsSection({
355
+ render,
356
+ onAddFilter
357
+ }) {
358
+ const [selectedIndex, setSelectedIndex] = (0, _react.useState)(null);
359
+
360
+ // Build list of available filter options (most specific to most general)
361
+ const filterOptions = (0, _react.useMemo)(() => {
362
+ const options = [];
363
+
364
+ // Most specific first
365
+ if (render.nativeID) {
366
+ options.push({
367
+ type: "nativeID",
368
+ value: render.nativeID,
369
+ label: "nativeID"
370
+ });
371
+ }
372
+ if (render.testID) {
373
+ options.push({
374
+ type: "testID",
375
+ value: render.testID,
376
+ label: "testID"
377
+ });
378
+ }
379
+ if (render.accessibilityLabel) {
380
+ options.push({
381
+ type: "accessibilityLabel",
382
+ value: render.accessibilityLabel,
383
+ label: "a11y"
384
+ });
385
+ }
386
+ if (render.componentName) {
387
+ options.push({
388
+ type: "component",
389
+ value: render.componentName,
390
+ label: "component"
391
+ });
392
+ }
393
+ // Most general last (always available)
394
+ options.push({
395
+ type: "viewType",
396
+ value: render.viewType,
397
+ label: "viewType"
398
+ });
399
+ return options;
400
+ }, [render]);
401
+ const selectedOption = selectedIndex !== null ? filterOptions[selectedIndex] : null;
402
+ const handleSelectOption = (0, _react.useCallback)(index => {
403
+ setSelectedIndex(prev => prev === index ? null : index);
404
+ }, []);
405
+ const handleInclude = (0, _react.useCallback)(() => {
406
+ if (selectedOption) {
407
+ onAddFilter({
408
+ type: selectedOption.type,
409
+ value: selectedOption.value
410
+ }, "include");
411
+ setSelectedIndex(null);
412
+ }
413
+ }, [selectedOption, onAddFilter]);
414
+ const handleExclude = (0, _react.useCallback)(() => {
415
+ if (selectedOption) {
416
+ onAddFilter({
417
+ type: selectedOption.type,
418
+ value: selectedOption.value
419
+ }, "exclude");
420
+ setSelectedIndex(null);
421
+ }
422
+ }, [selectedOption, onAddFilter]);
423
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
424
+ style: styles.quickActionsSection,
425
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
426
+ style: styles.quickActionsTitle,
427
+ children: "Quick Filters"
428
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
429
+ style: styles.filterOptionsList,
430
+ children: filterOptions.map((option, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(FilterOptionCard, {
431
+ label: option.label,
432
+ value: option.value,
433
+ isSelected: selectedIndex === index,
434
+ onSelect: () => handleSelectOption(index)
435
+ }, option.type))
436
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
437
+ style: styles.filterActionButtons,
438
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
439
+ style: [styles.filterActionButton, styles.filterActionButtonInclude, !selectedOption && styles.filterActionButtonDisabled],
440
+ onPress: handleInclude,
441
+ disabled: !selectedOption,
442
+ activeOpacity: 0.7,
443
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.PlusIcon, {
444
+ size: 14,
445
+ color: selectedOption ? _sharedUi.buoyColors.success : _sharedUi.buoyColors.textMuted
446
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
447
+ style: [styles.filterActionButtonText, {
448
+ color: selectedOption ? _sharedUi.buoyColors.success : _sharedUi.buoyColors.textMuted
449
+ }],
450
+ children: "Only Show This"
451
+ })]
452
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
453
+ style: [styles.filterActionButton, styles.filterActionButtonExclude, !selectedOption && styles.filterActionButtonDisabled],
454
+ onPress: handleExclude,
455
+ disabled: !selectedOption,
456
+ activeOpacity: 0.7,
457
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.MinusIcon, {
458
+ size: 14,
459
+ color: selectedOption ? _sharedUi.buoyColors.error : _sharedUi.buoyColors.textMuted
460
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
461
+ style: [styles.filterActionButtonText, {
462
+ color: selectedOption ? _sharedUi.buoyColors.error : _sharedUi.buoyColors.textMuted
463
+ }],
464
+ children: "Hide This"
465
+ })]
466
+ })]
467
+ })]
468
+ });
469
+ }
470
+
471
+ /**
472
+ * FilterOptionCard - A selectable filter option card
473
+ */
474
+ function FilterOptionCard({
475
+ label,
476
+ value,
477
+ isSelected,
478
+ onSelect
479
+ }) {
480
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
481
+ style: [styles.filterOptionCard, isSelected && styles.filterOptionCardSelected],
482
+ onPress: onSelect,
483
+ activeOpacity: 0.7,
484
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
485
+ style: [styles.filterOptionLabel, isSelected && styles.filterOptionLabelSelected],
486
+ children: label
487
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
488
+ style: [styles.filterOptionValue, isSelected && styles.filterOptionValueSelected],
489
+ numberOfLines: 1,
490
+ children: value
491
+ })]
492
+ });
493
+ }
494
+ const styles = _reactNative.StyleSheet.create({
495
+ container: {
496
+ flex: 1,
497
+ backgroundColor: _sharedUi.buoyColors.base
498
+ },
499
+ // Header
500
+ header: {
501
+ flexDirection: "row",
502
+ alignItems: "center",
503
+ justifyContent: "center",
504
+ gap: 12,
505
+ padding: 16,
506
+ paddingBottom: 0
507
+ },
508
+ // ScrollView
509
+ scrollView: {
510
+ flex: 1
511
+ },
512
+ scrollContent: {
513
+ padding: 16,
514
+ paddingTop: 12,
515
+ paddingBottom: 80,
516
+ gap: 12
517
+ },
518
+ headerLeft: {
519
+ flex: 1,
520
+ flexDirection: "row",
521
+ alignItems: "center",
522
+ justifyContent: "center",
523
+ gap: 10
524
+ },
525
+ componentName: {
526
+ fontSize: 18,
527
+ fontWeight: "700",
528
+ color: _sharedUi.buoyColors.text,
529
+ flexShrink: 1
530
+ },
531
+ nativeTypeBadge: {
532
+ backgroundColor: _sharedUi.buoyColors.input,
533
+ paddingVertical: 3,
534
+ paddingHorizontal: 8,
535
+ borderRadius: 4
536
+ },
537
+ nativeTypeText: {
538
+ fontSize: 11,
539
+ fontWeight: "600",
540
+ color: _sharedUi.buoyColors.textMuted,
541
+ fontFamily: "monospace"
542
+ },
543
+ // Answer Card
544
+ answerCard: {
545
+ backgroundColor: _sharedUi.buoyColors.card,
546
+ borderRadius: 8,
547
+ borderWidth: 1,
548
+ borderColor: _sharedUi.buoyColors.border,
549
+ padding: 12,
550
+ gap: 6
551
+ },
552
+ causeBadgeRow: {
553
+ flexDirection: "row",
554
+ alignItems: "center",
555
+ gap: 8
556
+ },
557
+ causeBadgeLarge: {
558
+ paddingVertical: 4,
559
+ paddingHorizontal: 10,
560
+ borderRadius: 4
561
+ },
562
+ causeBadgeLargeText: {
563
+ fontSize: 11,
564
+ fontWeight: "700",
565
+ letterSpacing: 0.5
566
+ },
567
+ causeLabel: {
568
+ fontSize: 12,
569
+ color: _sharedUi.buoyColors.textSecondary,
570
+ fontWeight: "500"
571
+ },
572
+ hookChangesContainer: {
573
+ gap: 6
574
+ },
575
+ hookDiffContainer: {
576
+ backgroundColor: _sharedUi.buoyColors.input,
577
+ borderRadius: 6,
578
+ overflow: "hidden"
579
+ },
580
+ propsChangesContainer: {
581
+ flexDirection: "row",
582
+ flexWrap: "wrap",
583
+ gap: 4
584
+ },
585
+ propChangeChip: {
586
+ backgroundColor: _sharedUi.buoyColors.input,
587
+ paddingVertical: 2,
588
+ paddingHorizontal: 6,
589
+ borderRadius: 4
590
+ },
591
+ propChangeText: {
592
+ fontSize: 11,
593
+ color: _sharedUi.buoyColors.text,
594
+ fontFamily: "monospace"
595
+ },
596
+ // Details Section
597
+ detailsSection: {
598
+ gap: 10
599
+ },
600
+ detailsCard: {
601
+ backgroundColor: _sharedUi.buoyColors.card,
602
+ borderRadius: 8,
603
+ borderWidth: 1,
604
+ borderColor: _sharedUi.buoyColors.border,
605
+ padding: 12,
606
+ gap: 6
607
+ },
608
+ detailsCardTitle: {
609
+ fontSize: 10,
610
+ fontWeight: "600",
611
+ color: _sharedUi.buoyColors.textMuted,
612
+ letterSpacing: 0.5,
613
+ textTransform: "uppercase",
614
+ marginBottom: 4
615
+ },
616
+ detailRow: {
617
+ flexDirection: "row",
618
+ alignItems: "center",
619
+ gap: 8
620
+ },
621
+ detailLabel: {
622
+ fontSize: 11,
623
+ fontWeight: "600",
624
+ color: _sharedUi.buoyColors.textSecondary,
625
+ minWidth: 55
626
+ },
627
+ detailValue: {
628
+ fontSize: 12,
629
+ color: _sharedUi.buoyColors.text,
630
+ fontFamily: "monospace",
631
+ flex: 1
632
+ },
633
+ // Stats Row
634
+ statsRow: {
635
+ flexDirection: "row",
636
+ alignItems: "center",
637
+ justifyContent: "center",
638
+ backgroundColor: _sharedUi.buoyColors.card,
639
+ borderRadius: 8,
640
+ borderWidth: 1,
641
+ borderColor: _sharedUi.buoyColors.border,
642
+ paddingVertical: 10,
643
+ paddingHorizontal: 16
644
+ },
645
+ statItem: {
646
+ flex: 1,
647
+ alignItems: "center"
648
+ },
649
+ statValue: {
650
+ fontSize: 16,
651
+ fontWeight: "700",
652
+ color: _sharedUi.buoyColors.text,
653
+ fontFamily: "monospace"
654
+ },
655
+ statLabel: {
656
+ fontSize: 10,
657
+ color: _sharedUi.buoyColors.textMuted,
658
+ marginTop: 2
659
+ },
660
+ statDivider: {
661
+ width: 1,
662
+ height: 24,
663
+ backgroundColor: _sharedUi.buoyColors.border,
664
+ marginHorizontal: 12
665
+ },
666
+ // Measurements Row
667
+ measurementsRow: {
668
+ flexDirection: "row",
669
+ alignItems: "center",
670
+ justifyContent: "space-around",
671
+ backgroundColor: _sharedUi.buoyColors.card,
672
+ borderRadius: 8,
673
+ borderWidth: 1,
674
+ borderColor: _sharedUi.buoyColors.border,
675
+ paddingVertical: 8,
676
+ paddingHorizontal: 12
677
+ },
678
+ measurementItem: {
679
+ flexDirection: "row",
680
+ alignItems: "baseline",
681
+ gap: 4
682
+ },
683
+ measurementLabel: {
684
+ fontSize: 10,
685
+ fontWeight: "600",
686
+ color: _sharedUi.buoyColors.textMuted,
687
+ textTransform: "uppercase"
688
+ },
689
+ measurementValue: {
690
+ fontSize: 12,
691
+ fontWeight: "600",
692
+ color: _sharedUi.buoyColors.text,
693
+ fontFamily: "monospace"
694
+ },
695
+ // Quick Actions Section
696
+ quickActionsSection: {
697
+ backgroundColor: _sharedUi.buoyColors.card,
698
+ borderRadius: 8,
699
+ borderWidth: 1,
700
+ borderColor: _sharedUi.buoyColors.border,
701
+ padding: 12,
702
+ gap: 10
703
+ },
704
+ quickActionsTitle: {
705
+ fontSize: 10,
706
+ fontWeight: "600",
707
+ color: _sharedUi.buoyColors.textMuted,
708
+ letterSpacing: 0.5,
709
+ textTransform: "uppercase",
710
+ marginBottom: 2
711
+ },
712
+ filterOptionsList: {
713
+ gap: 6
714
+ },
715
+ filterOptionCard: {
716
+ flexDirection: "row",
717
+ alignItems: "center",
718
+ backgroundColor: _sharedUi.buoyColors.input,
719
+ borderRadius: 6,
720
+ paddingVertical: 10,
721
+ paddingHorizontal: 12,
722
+ borderWidth: 1,
723
+ borderColor: "transparent",
724
+ gap: 10
725
+ },
726
+ filterOptionCardSelected: {
727
+ borderColor: _sharedUi.buoyColors.success,
728
+ backgroundColor: _sharedUi.buoyColors.success + "15"
729
+ },
730
+ filterOptionLabel: {
731
+ fontSize: 10,
732
+ fontWeight: "600",
733
+ color: _sharedUi.buoyColors.textMuted,
734
+ minWidth: 70
735
+ },
736
+ filterOptionLabelSelected: {
737
+ color: _sharedUi.buoyColors.success
738
+ },
739
+ filterOptionValue: {
740
+ fontSize: 12,
741
+ color: _sharedUi.buoyColors.text,
742
+ fontFamily: "monospace",
743
+ flex: 1
744
+ },
745
+ filterOptionValueSelected: {
746
+ color: _sharedUi.buoyColors.text
747
+ },
748
+ filterActionButtons: {
749
+ flexDirection: "row",
750
+ gap: 8,
751
+ marginTop: 12
752
+ },
753
+ filterActionButton: {
754
+ flexDirection: "row",
755
+ alignItems: "center",
756
+ justifyContent: "center",
757
+ gap: 4,
758
+ paddingVertical: 8,
759
+ paddingHorizontal: 10,
760
+ borderRadius: 6,
761
+ borderWidth: 1
762
+ },
763
+ filterActionButtonInclude: {
764
+ backgroundColor: _sharedUi.buoyColors.success + "15",
765
+ borderColor: _sharedUi.buoyColors.success + "40"
766
+ },
767
+ filterActionButtonExclude: {
768
+ backgroundColor: _sharedUi.buoyColors.error + "15",
769
+ borderColor: _sharedUi.buoyColors.error + "40"
770
+ },
771
+ filterActionButtonDisabled: {
772
+ backgroundColor: _sharedUi.buoyColors.input,
773
+ borderColor: _sharedUi.buoyColors.border,
774
+ opacity: 0.5
775
+ },
776
+ filterActionButtonText: {
777
+ fontSize: 11,
778
+ fontWeight: "600"
779
+ },
780
+ // Locked Banner
781
+ lockedBanner: {
782
+ flexDirection: "row",
783
+ alignItems: "center",
784
+ justifyContent: "center",
785
+ backgroundColor: _sharedUi.buoyColors.card,
786
+ borderRadius: 8,
787
+ borderWidth: 1,
788
+ borderColor: _sharedUi.buoyColors.warning + "40",
789
+ paddingVertical: 12,
790
+ paddingHorizontal: 16,
791
+ gap: 8
792
+ },
793
+ lockedBannerText: {
794
+ color: _sharedUi.buoyColors.warning,
795
+ fontSize: 13,
796
+ fontWeight: "600"
797
+ },
798
+ lockedBannerSubtext: {
799
+ color: _sharedUi.buoyColors.textMuted,
800
+ fontSize: 12
801
+ }
802
+ });
803
+ var _default = exports.default = RenderDetailView;