@buoy-gg/highlight-updates 7.0.78 → 7.0.80
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.
- package/lib/commonjs/highlight-updates/components/HighlightFilterView.js +1 -1
- package/lib/commonjs/highlight-updates/components/IsolatedRenderList.js +1 -1
- package/lib/commonjs/highlight-updates/utils/domScreenElements.js +1 -1
- package/lib/commonjs/highlight-updates/utils/screenElements.js +1 -1
- package/lib/module/highlight-updates/components/HighlightFilterView.js +1 -1
- package/lib/module/highlight-updates/components/IsolatedRenderList.js +1 -1
- package/lib/module/highlight-updates/utils/domScreenElements.js +1 -1
- package/lib/module/highlight-updates/utils/screenElements.js +1 -1
- package/lib/typescript/highlight-updates/utils/screenElements.d.ts +2 -0
- package/lib/web/index.mjs +14 -14
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.HighlightFilterView=HighlightFilterView;exports.default=void 0;var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _IdentifierBadge=require("./IdentifierBadge");var _testIDs=require("../utils/testIDs");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(n,l){if("function"==typeof WeakMap)var i=new WeakMap,r=new WeakMap;return(_interopRequireWildcard=function(t,a){if(!a&&t&&t.__esModule)return t;var s,d,g={__proto__:null,default:t};if(null===t||"object"!=typeof t&&"function"!=typeof t)return g;if(s=a?r:i){if(s.has(t))return s.get(t);s.set(t,g)}for(const u in t)"default"!==u&&{}.hasOwnProperty.call(t,u)&&((d=(s=Object.defineProperty)&&Object.getOwnPropertyDescriptor(t,u))&&(d.get||d.set)?s(g,u,d):g[u]=t[u]);return g})(n,l)}const getFilterConfig=n=>_IdentifierBadge.IDENTIFIER_CONFIG[n];const FILTER_TYPES=["any","viewType","testID","nativeID","component","accessibilityLabel"];function TypePicker({mode:n,onSelect:l,onCancel:i}){return(0,_jsxRuntime.jsxs)(_reactNative.View,{nativeID:"__rn_buoy__type-picker",testID:`buoy-highlight-${n}-types`,style:styles.typePicker,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.typePickerRow,children:FILTER_TYPES.map(r=>{const t=getFilterConfig(r);const a=t.icon;return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:`buoy-highlight-${n}-type-${r.toLowerCase()}`,accessibilityRole:"button",accessibilityLabel:t.label,style:[styles.typeOption,{backgroundColor:t.color+"15",borderColor:t.color+"40"}],onPress:()=>l(r),children:[(0,_jsxRuntime.jsx)(a,{size:14,color:t.color}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.typeOptionText,{color:t.color}],children:t.label})]},r)})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`buoy-highlight-${n}-types-cancel`,accessibilityRole:"button",accessibilityLabel:"Cancel",onPress:i,style:styles.typePickerCancel,children:(0,_jsxRuntime.jsx)(_sharedUi.X,{size:16,color:_sharedUi.night.color.textTertiary})})]})}function PatternInput({mode:n,type:l,onSubmit:i,onCancel:r}){const[t,a]=(0,_react.useState)("");const s=getFilterConfig(l);const d=()=>{if(t.trim()){i(t.trim())}};return(0,_jsxRuntime.jsxs)(_reactNative.View,{nativeID:"__rn_buoy__pattern-input",testID:`buoy-highlight-${n}-input-row`,style:styles.patternInputContainer,children:[(0,_jsxRuntime.jsx)(_IdentifierBadge.IdentifierBadge,{type:l,value:"",badgeOnly:true,compact:true}),(0,_jsxRuntime.jsx)(_reactNative.TextInput,{testID:`buoy-highlight-${n}-input`,value:t,onChangeText:a,onSubmitEditing:d,placeholder:"Enter pattern...",placeholderTextColor:_sharedUi.night.color.placeholder,style:styles.patternInput,autoFocus:true,returnKeyType:"done",autoCorrect:false,autoCapitalize:"none"}),t.trim()&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`buoy-highlight-${n}-submit`,accessibilityRole:"button",accessibilityLabel:"Add pattern",onPress:d,style:[styles.addPatternButton,{backgroundColor:s.color+"20"}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.addPatternButtonText,{color:s.color}],children:"Add"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`buoy-highlight-${n}-input-cancel`,accessibilityRole:"button",accessibilityLabel:"Cancel",onPress:r,style:styles.cancelButton,children:(0,_jsxRuntime.jsx)(_sharedUi.X,{size:16,color:_sharedUi.night.color.textTertiary})})]})}function PatternChip({mode:n,pattern:l,onRemove:i}){const r=getFilterConfig(l.type);return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:(0,_testIDs.patternChipTestID)(n,l.type,l.value),accessibilityRole:"button",accessibilityLabel:`${r.label} ${l.value}, tap to remove`,style:[styles.patternChip,{borderColor:r.color+"40"}],onPress:i,activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.patternChipBadge,{backgroundColor:r.color+"20"}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.patternChipBadgeText,{color:r.color}],children:r.shortLabel})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.patternChipValue,numberOfLines:1,children:l.value}),(0,_jsxRuntime.jsx)(_sharedUi.X,{size:12,color:_sharedUi.night.color.textTertiary,style:styles.patternChipX})]})}const ALL_CATEGORY_CONFIG={label:"All",shortLabel:"All",color:_sharedUi.night.color.textSecondary,icon:_sharedUi.Box};function DetectedCategoryBadge({filterType:n,count:l,isSelected:i,onPress:r}){const t=n==="all"?ALL_CATEGORY_CONFIG:getFilterConfig(n);const a=`buoy-highlight-detected-cat-${String(n).toLowerCase()}`;return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:a,accessibilityRole:"button",accessibilityLabel:`${t.label}, ${l}`,style:[styles.categoryBadge,{backgroundColor:t.color+"15",borderColor:i?t.color:t.color+"40",borderWidth:i?2:1}],onPress:r,children:[(0,_jsxRuntime.jsx)(t.icon,{size:12,color:t.color}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.categoryBadgeText,{color:t.color}],children:t.label}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.categoryBadgeCountBubble,{backgroundColor:t.color+"25"}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:`${a}-count`,style:[styles.categoryBadgeCount,{color:t.color}],children:l})})]})}const BATCH_SIZE_PRESETS=[{value:20,label:"20"},{value:50,label:"50"},{value:100,label:"100"},{value:150,label:"150"},{value:250,label:"250"},{value:500,label:"500"}];const DEBUG_LOG_LEVEL_PRESETS=[{value:"off",label:"Off",description:"No debug logging"},{value:"minimal",label:"Minimal",description:"Only hook value changes"},{value:"verbose",label:"Verbose",description:"Component + cause + changes"},{value:"all",label:"All",description:"Full fiber dump"}];function HighlightFilterView({filters:n,onFilterChange:l,settings:i,onSettingsChange:r,availableProps:t,activeTab:a}){const[s,d]=(0,_react.useState)(false);const[g,u]=(0,_react.useState)(false);const[b,T]=(0,_react.useState)(null);const[f,m]=(0,_react.useState)(null);const[h,p]=(0,_react.useState)("all");const[c,y]=(0,_react.useState)(null);const v=e=>{switch(e){case"viewType":return t.viewTypes.map(o=>({value:o,type:"viewType"}));case"testID":return t.testIDs.map(o=>({value:o,type:"testID"}));case"nativeID":return t.nativeIDs.map(o=>({value:o,type:"nativeID"}));case"component":return t.componentNames.map(o=>({value:o,type:"component"}));case"accessibilityLabel":return t.accessibilityLabels.map(o=>({value:o,type:"accessibilityLabel"}));case"all":default:return[...t.viewTypes.map(o=>({value:o,type:"viewType"})),...t.testIDs.map(o=>({value:o,type:"testID"})),...t.nativeIDs.map(o=>({value:o,type:"nativeID"})),...t.componentNames.map(o=>({value:o,type:"component"})),...t.accessibilityLabels.map(o=>({value:o,type:"accessibilityLabel"}))]}};const w=v(h);const S=t.viewTypes.length+t.testIDs.length+t.nativeIDs.length+t.componentNames.length+t.accessibilityLabels.length;const I=(0,_react.useCallback)((e,o)=>{const x=[...n.includePatterns,{type:e,value:o}];l({includePatterns:x});T(null)},[n.includePatterns,l]);const j=(0,_react.useCallback)((e,o)=>{const x=[...n.excludePatterns,{type:e,value:o}];l({excludePatterns:x});m(null)},[n.excludePatterns,l]);const D=(0,_react.useCallback)(e=>{const o=n.includePatterns.filter((x,C)=>C!==e);l({includePatterns:o})},[n.includePatterns,l]);const R=(0,_react.useCallback)(e=>{const o=n.excludePatterns.filter((x,C)=>C!==e);l({excludePatterns:o})},[n.excludePatterns,l]);const P=(0,_react.useCallback)((e,o)=>{y({type:e,value:o})},[]);const V=(0,_react.useCallback)(()=>{if(c){I(c.type,c.value);y(null)}},[c,I]);const z=(0,_react.useCallback)(()=>{if(c){j(c.type,c.value);y(null)}},[c,j]);return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.container,children:(0,_jsxRuntime.jsx)(_reactNative.ScrollView,{keyboardShouldPersistTaps:"handled",nativeID:"__rn_buoy__filter-view",testID:"buoy-highlight-filter-scroll",style:styles.scrollView,contentContainerStyle:styles.scrollContent,showsVerticalScrollIndicator:false,children:a==="filters"?(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Eye,color:_sharedUi.night.color.accent,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"INCLUDE ONLY"}),n.includePatterns.length>0&&(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Badge,{testID:"buoy-highlight-include-count",count:n.includePatterns.length,color:_sharedUi.night.color.accent})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionDescription,children:"Show only components matching these patterns. If any are set, components must match at least one."}),n.includePatterns.length>0&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.patternChips,children:n.includePatterns.map((e,o)=>(0,_jsxRuntime.jsx)(PatternChip,{mode:"include",pattern:e,onRemove:()=>D(o)},`${e.type}-${e.value}-${o}`))}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.addPatternRow,children:s?(0,_jsxRuntime.jsx)(TypePicker,{mode:"include",onSelect:e=>{d(false);T(e)},onCancel:()=>d(false)}):b?(0,_jsxRuntime.jsx)(PatternInput,{mode:"include",type:b,onSubmit:e=>I(b,e),onCancel:()=>T(null)}):(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"buoy-highlight-include-add",accessibilityRole:"button",accessibilityLabel:"Add include pattern",style:[styles.addButton,{borderColor:_sharedUi.night.color.accentBorderStrong}],onPress:()=>d(true),children:[(0,_jsxRuntime.jsx)(_sharedUi.Plus,{size:14,color:_sharedUi.night.color.accent}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.addButtonText,{color:_sharedUi.night.color.accent}],children:"Add include pattern"})]})})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Filter,color:_sharedUi.night.color.accent,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"EXCLUDE"}),n.excludePatterns.length>0&&(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Badge,{testID:"buoy-highlight-exclude-count",count:n.excludePatterns.length,color:_sharedUi.night.color.accent})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionDescription,children:"Hide components matching these patterns from the list."}),n.excludePatterns.length>0&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.patternChips,children:n.excludePatterns.map((e,o)=>(0,_jsxRuntime.jsx)(PatternChip,{mode:"exclude",pattern:e,onRemove:()=>R(o)},`${e.type}-${e.value}-${o}`))}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.addPatternRow,children:g?(0,_jsxRuntime.jsx)(TypePicker,{mode:"exclude",onSelect:e=>{u(false);m(e)},onCancel:()=>u(false)}):f?(0,_jsxRuntime.jsx)(PatternInput,{mode:"exclude",type:f,onSubmit:e=>j(f,e),onCancel:()=>m(null)}):(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"buoy-highlight-exclude-add",accessibilityRole:"button",accessibilityLabel:"Add exclude pattern",style:[styles.addButton,{borderColor:_sharedUi.night.color.accentBorderStrong}],onPress:()=>u(true),children:[(0,_jsxRuntime.jsx)(_sharedUi.Plus,{size:14,color:_sharedUi.night.color.accent}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.addButtonText,{color:_sharedUi.night.color.accent}],children:"Add exclude pattern"})]})})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Hash,color:_sharedUi.night.color.warning,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"RENDER COUNT RANGE"}),(n.minRenderCount!==void 0||n.maxRenderCount!==void 0)&&(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Badge,{count:1,color:_sharedUi.night.color.warning})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionDescription,children:"Show only components with render count in a specific range."}),(0,_jsxRuntime.jsxs)(_reactNative.View,{nativeID:"__rn_buoy__render-count-range",testID:"buoy-highlight-range",style:styles.renderCountRangeContainer,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.renderCountInputRow,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.renderCountInputGroup,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.renderCountLabel,children:"Min"}),(0,_jsxRuntime.jsx)(_reactNative.TextInput,{value:n.minRenderCount!==void 0?String(n.minRenderCount):"",onChangeText:e=>{const o=parseInt(e,10);if(e===""||e===void 0){l({minRenderCount:void 0})}else if(!isNaN(o)&&o>=0){l({minRenderCount:o})}},testID:"buoy-highlight-range-min",placeholder:"0",placeholderTextColor:_sharedUi.night.color.placeholder,style:styles.renderCountInput,keyboardType:"number-pad",returnKeyType:"done"})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.renderCountSeparator,children:"to"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.renderCountInputGroup,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.renderCountLabel,children:"Max"}),(0,_jsxRuntime.jsx)(_reactNative.TextInput,{value:n.maxRenderCount!==void 0?String(n.maxRenderCount):"",onChangeText:e=>{const o=parseInt(e,10);if(e===""||e===void 0){l({maxRenderCount:void 0})}else if(!isNaN(o)&&o>=0){l({maxRenderCount:o})}},testID:"buoy-highlight-range-max",placeholder:"\u221E",placeholderTextColor:_sharedUi.night.color.placeholder,style:styles.renderCountInput,keyboardType:"number-pad",returnKeyType:"done"})]})]}),(n.minRenderCount!==void 0||n.maxRenderCount!==void 0)&&(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"buoy-highlight-range-clear",accessibilityRole:"button",accessibilityLabel:"Clear range",style:styles.clearRangeButton,onPress:()=>l({minRenderCount:void 0,maxRenderCount:void 0}),children:[(0,_jsxRuntime.jsx)(_sharedUi.X,{size:12,color:_sharedUi.night.color.warning}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.clearRangeButtonText,children:"Clear Range"})]})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Box,color:_sharedUi.night.color.textSecondary,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"DETECTED ITEMS"})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionDescription,children:"Tap an item to quickly add it as an exclude pattern."}),(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{horizontal:true,showsHorizontalScrollIndicator:false,style:styles.categoryBadgeScroll,contentContainerStyle:styles.categoryBadgeScrollContent,children:[S>0&&(0,_jsxRuntime.jsx)(DetectedCategoryBadge,{filterType:"all",count:S,isSelected:h==="all",onPress:()=>p("all")}),t.viewTypes.length>0&&(0,_jsxRuntime.jsx)(DetectedCategoryBadge,{filterType:"viewType",count:t.viewTypes.length,isSelected:h==="viewType",onPress:()=>p("viewType")}),t.testIDs.length>0&&(0,_jsxRuntime.jsx)(DetectedCategoryBadge,{filterType:"testID",count:t.testIDs.length,isSelected:h==="testID",onPress:()=>p("testID")}),t.nativeIDs.length>0&&(0,_jsxRuntime.jsx)(DetectedCategoryBadge,{filterType:"nativeID",count:t.nativeIDs.length,isSelected:h==="nativeID",onPress:()=>p("nativeID")}),t.componentNames.length>0&&(0,_jsxRuntime.jsx)(DetectedCategoryBadge,{filterType:"component",count:t.componentNames.length,isSelected:h==="component",onPress:()=>p("component")}),t.accessibilityLabels.length>0&&(0,_jsxRuntime.jsx)(DetectedCategoryBadge,{filterType:"accessibilityLabel",count:t.accessibilityLabels.length,isSelected:h==="accessibilityLabel",onPress:()=>p("accessibilityLabel")})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{nativeID:"__rn_buoy__detected-items",testID:"buoy-highlight-detected",style:styles.detectedItemsContainer,children:w.length>0?(0,_jsxRuntime.jsx)(_reactNative.ScrollView,{keyboardShouldPersistTaps:"handled",testID:"buoy-highlight-detected-scroll",style:styles.detectedItemsScroll,contentContainerStyle:styles.detectedItems,nestedScrollEnabled:true,showsVerticalScrollIndicator:true,children:w.map(e=>{const o=getFilterConfig(e.type);return(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:(0,_testIDs.detectedItemTestID)(e.type,e.value),accessibilityRole:"button",accessibilityLabel:`${o.label} ${e.value}`,style:[styles.detectedItem,{borderColor:o.color+"40"}],onPress:()=>P(e.type,e.value),children:h==="all"?(0,_jsxRuntime.jsx)(_IdentifierBadge.IdentifierBadge,{type:e.type,value:e.value,compact:true,shortLabel:true}):(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detectedItemText,numberOfLines:1,children:e.value})},`${e.type}-${e.value}`)})}):(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:"buoy-highlight-detected-empty",style:styles.emptyText,children:"No items detected yet. Start tracking to see components here."})})]}),(0,_jsxRuntime.jsx)(_reactNative.Modal,{visible:c!==null,transparent:true,animationType:"fade",onRequestClose:()=>y(null),children:(0,_jsxRuntime.jsx)(_reactNative.Pressable,{accessible:false,testID:"buoy-highlight-detected-popup-backdrop",style:styles.modalOverlay,onPress:()=>y(null),children:(0,_jsxRuntime.jsx)(_reactNative.View,{accessible:false,testID:"buoy-highlight-detected-popup",style:styles.actionPopup,children:c&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.actionPopupHeader,children:(0,_jsxRuntime.jsx)(_IdentifierBadge.IdentifierBadge,{type:c.type,value:c.value,compact:true,shortLabel:true})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.actionPopupButtons,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"buoy-highlight-detected-popup-include",accessibilityRole:"button",accessibilityLabel:"Include only",style:[styles.actionPopupButton,styles.actionPopupInclude],onPress:V,children:[(0,_jsxRuntime.jsx)(_sharedUi.Eye,{size:16,color:_sharedUi.night.color.accent}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionPopupButtonText,{color:_sharedUi.night.color.accent}],children:"Include Only"})]}),(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"buoy-highlight-detected-popup-exclude",accessibilityRole:"button",accessibilityLabel:"Exclude",style:[styles.actionPopupButton,styles.actionPopupExclude],onPress:z,children:[(0,_jsxRuntime.jsx)(_sharedUi.Filter,{size:16,color:_sharedUi.night.color.accent}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionPopupButtonText,{color:_sharedUi.night.color.accent}],children:"Exclude"})]})]}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:"buoy-highlight-detected-popup-cancel",accessibilityRole:"button",accessibilityLabel:"Cancel",style:styles.actionPopupCancel,onPress:()=>y(null),children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.actionPopupCancelText,children:"Cancel"})})]})})})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Filter,color:_sharedUi.night.color.textTertiary,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"HOW FILTERS WORK"})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.howItWorks,children:(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.howItWorksText,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.howItWorksBold,children:"Any:"})," Matches against all fields","\n",(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.howItWorksBold,children:"ViewType:"})," Native component class (RCTView, RCTText)","\n",(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.howItWorksBold,children:"testID:"})," Component testID prop","\n",(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.howItWorksBold,children:"Component:"})," React component name from fiber"]})})]})]}):(0,_jsxRuntime.jsx)(_jsxRuntime.Fragment,{children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Settings,color:_sharedUi.night.color.textTertiary,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"SETTINGS"})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingsSection,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingItem,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingLabel,children:"Show Render Count"}),(0,_jsxRuntime.jsx)(_reactNative.Switch,{testID:(0,_testIDs.settingTestID)("showRenderCount"),value:i.showRenderCount,onValueChange:e=>{r({showRenderCount:e});if(!e&&i.trackRenderCauses){r({trackRenderCauses:false})}},trackColor:{false:_sharedUi.night.color.surfaceElevated,true:_sharedUi.night.color.accent+"80"},thumbColor:i.showRenderCount?_sharedUi.night.color.accent:_sharedUi.night.color.knob})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingDescription,children:"Display render count badge on highlights. Disabling improves performance by skipping count tracking."})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.settingItem,styles.settingItemSpaced],children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.settingLabel,!i.showRenderCount&&styles.settingLabelDisabled],children:"Track Render Causes"}),(0,_jsxRuntime.jsx)(_reactNative.Switch,{testID:(0,_testIDs.settingTestID)("trackRenderCauses"),value:i.trackRenderCauses,onValueChange:e=>r({trackRenderCauses:e}),trackColor:{false:_sharedUi.night.color.surfaceElevated,true:_sharedUi.night.color.warning+"80"},thumbColor:i.trackRenderCauses?_sharedUi.night.color.warning:_sharedUi.night.color.knob,disabled:!i.showRenderCount})]}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.settingDescription,children:["Detect WHY components render (props, hooks, parent re-render).",!i.showRenderCount&&(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.settingWarning,children:["\n",'Requires "Show Render Count" to be enabled.']})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.settingItem,styles.settingItemSpaced],children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.settingLabel,!i.trackRenderCauses&&styles.settingLabelDisabled],children:"Enable Render History"}),(0,_jsxRuntime.jsx)(_reactNative.Switch,{testID:(0,_testIDs.settingTestID)("enableRenderHistory"),value:i.enableRenderHistory,onValueChange:e=>r({enableRenderHistory:e}),trackColor:{false:_sharedUi.night.color.surfaceElevated,true:_sharedUi.night.color.accent+"80"},thumbColor:i.enableRenderHistory?_sharedUi.night.color.accent:_sharedUi.night.color.knob,disabled:!i.trackRenderCauses})]}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.settingDescription,children:["Store render events for each component to view in the History tab.",!i.trackRenderCauses&&(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.settingWarning,children:["\n",'Requires "Track Render Causes" to be enabled.']})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.settingItem,styles.settingItemSpaced],children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingLabel,children:"Debug Log Level"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.settingValue,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:"buoy-highlight-setting-debugLogLevel-value",style:[styles.settingValueText,i.debugLogLevel!=="off"&&{color:_sharedUi.night.color.warning}],children:DEBUG_LOG_LEVEL_PRESETS.find(e=>e.value===i.debugLogLevel)?.label||"Off"})})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingDescription,children:"Control console logging verbosity for render cause detection."}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.batchSizePresets,children:DEBUG_LOG_LEVEL_PRESETS.map(e=>(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.batchSizePreset,i.debugLogLevel===e.value&&styles.batchSizePresetActive,e.value!=="off"&&i.debugLogLevel===e.value&&{backgroundColor:_sharedUi.night.color.warningSoft,borderColor:_sharedUi.night.color.warning}],onPress:()=>r({debugLogLevel:e.value}),testID:`buoy-highlight-preset-log-${e.value}`,accessibilityRole:"button",accessibilityLabel:`Debug log level ${e.label}`,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.batchSizePresetText,i.debugLogLevel===e.value&&styles.batchSizePresetTextActive,e.value!=="off"&&i.debugLogLevel===e.value&&{color:_sharedUi.night.color.warning}],children:e.label})},e.value))}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.settingDescriptionMuted,children:[DEBUG_LOG_LEVEL_PRESETS.find(e=>e.value===i.debugLogLevel)?.description,i.debugLogLevel!=="off"&&" \u2022 Check Metro console for logs"]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.settingItem,styles.settingItemSpaced],children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingLabel,children:"Batch Size"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.settingValue,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:"buoy-highlight-setting-batchSize-value",style:styles.settingValueText,children:i.batchSize})})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingDescription,children:"Maximum components to highlight per render update. Higher values capture more re-renders but may impact performance on complex screens."}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.batchSizePresets,children:BATCH_SIZE_PRESETS.map(e=>(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.batchSizePreset,i.batchSize===e.value&&styles.batchSizePresetActive],onPress:()=>r({batchSize:e.value}),testID:`buoy-highlight-preset-batch-${e.value}`,accessibilityRole:"button",accessibilityLabel:`Batch size ${e.label}`,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.batchSizePresetText,i.batchSize===e.value&&styles.batchSizePresetTextActive],children:e.label})},e.value))})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.settingItem,styles.settingItemSpaced],children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingLabel,children:"Show host views"}),(0,_jsxRuntime.jsx)(_reactNative.Switch,{testID:(0,_testIDs.settingTestID)("showHostViews"),value:!!i.showHostViews,onValueChange:e=>r({showHostViews:e}),trackColor:{false:_sharedUi.night.color.surfaceElevated,true:_sharedUi.night.color.accent+"80"},thumbColor:i.showHostViews?_sharedUi.night.color.accent:_sharedUi.night.color.knob})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingDescription,children:"Include anonymous View / RCTView / Text hosts. Off by default so the list is named composites (what actually re-rendered)."})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.settingItem,styles.settingItemSpaced],children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingLabel,children:"Highlight Dev Tools"}),(0,_jsxRuntime.jsx)(_reactNative.Switch,{testID:(0,_testIDs.settingTestID)("excludeDevTools"),value:!i.excludeDevTools,onValueChange:e=>r({excludeDevTools:!e}),trackColor:{false:_sharedUi.night.color.surfaceElevated,true:_sharedUi.night.color.accent+"80"},thumbColor:!i.excludeDevTools?_sharedUi.night.color.accent:_sharedUi.night.color.knob})]}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.settingDescription,children:["Show re-render highlights on Buoy dev tools (floating menu, modals, etc.). Useful for optimizing the dev tools themselves.",!i.excludeDevTools&&(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.settingWarning,children:["\n","The highlight overlay is always excluded to prevent infinite loops."]})]})]})]})]})})})})}const styles=_reactNative.StyleSheet.create({container:{flex:1,backgroundColor:"transparent"},scrollView:{flex:1},scrollContent:{paddingHorizontal:16,paddingTop:12,paddingBottom:32},section:{backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,marginBottom:12,overflow:"hidden"},sectionDescription:{fontSize:11,color:_sharedUi.night.color.textSecondary,paddingHorizontal:16,paddingTop:8,lineHeight:16},patternChips:{flexDirection:"row",flexWrap:"wrap",gap:8,paddingHorizontal:16,paddingTop:12},patternChip:{flexDirection:"row",alignItems:"center",backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:6,borderWidth:1,paddingVertical:4,paddingLeft:4,paddingRight:6,maxWidth:"100%",gap:4},patternChipBadge:{paddingVertical:2,paddingHorizontal:5,borderRadius:4},patternChipBadgeText:{fontSize:9,fontWeight:"700"},patternChipValue:{fontSize:11,color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont,flexShrink:1},patternChipX:{marginLeft:2},addPatternRow:{paddingHorizontal:16,paddingTop:12,paddingBottom:16},addButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",paddingVertical:10,paddingHorizontal:16,borderRadius:8,borderWidth:1,borderStyle:"dashed",gap:6},addButtonText:{fontSize:12,fontWeight:"500"},typePicker:{flexDirection:"row",alignItems:"center",gap:8},typePickerRow:{flex:1,flexDirection:"row",flexWrap:"wrap",gap:8},typeOption:{flexDirection:"row",alignItems:"center",paddingVertical:8,paddingHorizontal:12,borderRadius:6,borderWidth:1,backgroundColor:_sharedUi.night.color.surfaceElevated,gap:6},typeOptionText:{fontSize:11,fontWeight:"600"},typePickerCancel:{padding:8},patternInputContainer:{flexDirection:"row",alignItems:"center",backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,paddingLeft:4,paddingRight:8,paddingVertical:4,gap:4},patternInput:{flex:1,fontSize:12,color:_sharedUi.night.color.text,paddingVertical:6,paddingHorizontal:4},addPatternButton:{paddingVertical:6,paddingHorizontal:10,borderRadius:4},addPatternButtonText:{fontSize:11,fontWeight:"600"},cancelButton:{padding:4},categoryBadgeScroll:{marginTop:12},categoryBadgeScrollContent:{paddingHorizontal:16,gap:8},categoryBadge:{flexDirection:"row",alignItems:"center",paddingVertical:8,paddingLeft:10,paddingRight:6,borderRadius:8,borderWidth:1,gap:6},categoryBadgeText:{fontSize:11,fontWeight:"600"},categoryBadgeCountBubble:{paddingHorizontal:6,paddingVertical:2,borderRadius:10,minWidth:20,alignItems:"center"},categoryBadgeCount:{fontSize:10,fontWeight:"600"},detectedItemsContainer:{paddingHorizontal:16,paddingTop:12,paddingBottom:16},detectedItemsScroll:{maxHeight:200},detectedItems:{flexDirection:"row",flexWrap:"wrap",gap:8},detectedItem:{flexDirection:"row",alignItems:"center",backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:6,borderWidth:1,paddingVertical:6,paddingHorizontal:10,gap:6},detectedItemText:{fontSize:11,color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},emptyText:{fontSize:11,color:_sharedUi.night.color.textTertiary,fontStyle:"italic",textAlign:"center",paddingVertical:16,paddingHorizontal:16},howItWorks:{paddingHorizontal:16,paddingVertical:12},howItWorksText:{fontSize:11,color:_sharedUi.night.color.textTertiary,lineHeight:18,fontFamily:_sharedUi.monoFont},howItWorksBold:{fontWeight:"700",color:_sharedUi.night.color.textSecondary},modalOverlay:{flex:1,backgroundColor:"rgba(0, 0, 0, 0.5)",justifyContent:"center",alignItems:"center",padding:32},actionPopup:{backgroundColor:_sharedUi.night.color.surface,borderRadius:12,borderWidth:1,borderColor:_sharedUi.night.color.border,width:"100%",maxWidth:300,overflow:"hidden"},actionPopupHeader:{padding:16,borderBottomWidth:1,borderBottomColor:_sharedUi.night.color.separator,alignItems:"center"},actionPopupButtons:{flexDirection:"row",padding:12,gap:8},actionPopupButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",paddingVertical:12,paddingHorizontal:12,borderRadius:8,gap:8},actionPopupInclude:{backgroundColor:_sharedUi.night.color.accentSoft},actionPopupExclude:{backgroundColor:_sharedUi.night.color.accentSoft},actionPopupButtonText:{fontSize:13,fontWeight:"600"},actionPopupCancel:{padding:12,borderTopWidth:1,borderTopColor:_sharedUi.night.color.separator,alignItems:"center"},actionPopupCancelText:{fontSize:13,color:_sharedUi.night.color.textTertiary,fontWeight:"500"},settingsSection:{paddingHorizontal:16,paddingTop:8,paddingBottom:16},settingItem:{gap:8},settingItemSpaced:{marginTop:16,paddingTop:16,borderTopWidth:1,borderTopColor:_sharedUi.night.color.separator},settingHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between"},settingLabel:{fontSize:13,fontWeight:"600",color:_sharedUi.night.color.text},settingValue:{backgroundColor:_sharedUi.night.color.fillSecondary,paddingHorizontal:10,paddingVertical:4,borderRadius:6},settingValueText:{fontSize:12,fontWeight:"700",color:_sharedUi.night.color.textTertiary,fontFamily:_sharedUi.monoFont},settingDescription:{fontSize:11,color:_sharedUi.night.color.textSecondary,lineHeight:16},settingDescriptionMuted:{fontSize:10,color:_sharedUi.night.color.textTertiary,lineHeight:14,marginTop:4,fontStyle:"italic"},settingLabelDisabled:{color:_sharedUi.night.color.textTertiary},settingWarning:{color:_sharedUi.night.color.warning,fontWeight:"500"},batchSizePresets:{flexDirection:"row",flexWrap:"wrap",gap:8,marginTop:4},batchSizePreset:{paddingVertical:8,paddingHorizontal:14,borderRadius:6,backgroundColor:_sharedUi.night.color.surfaceElevated,borderWidth:1,borderColor:_sharedUi.night.color.border},batchSizePresetActive:{backgroundColor:_sharedUi.night.color.fillSecondary,borderColor:_sharedUi.night.color.fillTertiary},batchSizePresetText:{fontSize:12,fontWeight:"500",color:_sharedUi.night.color.textSecondary,fontFamily:_sharedUi.monoFont},batchSizePresetTextActive:{color:_sharedUi.night.color.textTertiary,fontWeight:"700"},renderCountRangeContainer:{paddingHorizontal:16,paddingTop:12,paddingBottom:16,gap:12},renderCountInputRow:{flexDirection:"row",alignItems:"center",gap:12},renderCountInputGroup:{flex:1,gap:4},renderCountLabel:{fontSize:10,fontWeight:"600",color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},renderCountInput:{backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,paddingVertical:10,paddingHorizontal:12,fontSize:14,fontWeight:"600",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont,textAlign:"center"},renderCountSeparator:{fontSize:12,color:_sharedUi.night.color.textTertiary,marginTop:18},clearRangeButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",paddingVertical:8,paddingHorizontal:12,borderRadius:6,backgroundColor:_sharedUi.night.color.warningSoft,borderWidth:1,borderColor:_sharedUi.night.color.warning+"40",gap:6,alignSelf:"center"},clearRangeButtonText:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.warning}});var _default=exports.default=HighlightFilterView;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.HighlightFilterView=HighlightFilterView;exports.default=void 0;var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _IdentifierBadge=require("./IdentifierBadge");var _testIDs=require("../utils/testIDs");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(n,l){if("function"==typeof WeakMap)var i=new WeakMap,r=new WeakMap;return(_interopRequireWildcard=function(t,a){if(!a&&t&&t.__esModule)return t;var s,d,g={__proto__:null,default:t};if(null===t||"object"!=typeof t&&"function"!=typeof t)return g;if(s=a?r:i){if(s.has(t))return s.get(t);s.set(t,g)}for(const u in t)"default"!==u&&{}.hasOwnProperty.call(t,u)&&((d=(s=Object.defineProperty)&&Object.getOwnPropertyDescriptor(t,u))&&(d.get||d.set)?s(g,u,d):g[u]=t[u]);return g})(n,l)}const getFilterConfig=n=>_IdentifierBadge.IDENTIFIER_CONFIG[n];const FILTER_TYPES=["any","viewType","testID","nativeID","component","accessibilityLabel"];function TypePicker({mode:n,onSelect:l,onCancel:i}){return(0,_jsxRuntime.jsxs)(_reactNative.View,{nativeID:"__rn_buoy__type-picker",testID:`buoy-highlight-${n}-types`,style:styles.typePicker,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.typePickerRow,children:FILTER_TYPES.map(r=>{const t=getFilterConfig(r);const a=t.icon;return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:`buoy-highlight-${n}-type-${r.toLowerCase()}`,accessibilityRole:"button",accessibilityLabel:t.label,style:[styles.typeOption,{backgroundColor:t.color+"15",borderColor:t.color+"40"}],onPress:()=>l(r),children:[(0,_jsxRuntime.jsx)(a,{size:14,color:t.color}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.typeOptionText,{color:t.color}],children:t.label})]},r)})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`buoy-highlight-${n}-types-cancel`,accessibilityRole:"button",accessibilityLabel:"Cancel",onPress:i,style:styles.typePickerCancel,children:(0,_jsxRuntime.jsx)(_sharedUi.X,{size:16,color:_sharedUi.night.color.textTertiary})})]})}function PatternInput({mode:n,type:l,onSubmit:i,onCancel:r}){const[t,a]=(0,_react.useState)("");const s=getFilterConfig(l);const d=()=>{if(t.trim()){i(t.trim())}};return(0,_jsxRuntime.jsxs)(_reactNative.View,{nativeID:"__rn_buoy__pattern-input",testID:`buoy-highlight-${n}-input-row`,style:styles.patternInputContainer,children:[(0,_jsxRuntime.jsx)(_IdentifierBadge.IdentifierBadge,{type:l,value:"",badgeOnly:true,compact:true}),(0,_jsxRuntime.jsx)(_reactNative.TextInput,{testID:`buoy-highlight-${n}-input`,value:t,onChangeText:a,onSubmitEditing:d,placeholder:"Enter pattern...",placeholderTextColor:_sharedUi.night.color.placeholder,style:styles.patternInput,autoFocus:true,returnKeyType:"done",autoCorrect:false,autoCapitalize:"none"}),t.trim()&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`buoy-highlight-${n}-submit`,accessibilityRole:"button",accessibilityLabel:"Add pattern",onPress:d,style:[styles.addPatternButton,{backgroundColor:s.color+"20"}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.addPatternButtonText,{color:s.color}],children:"Add"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`buoy-highlight-${n}-input-cancel`,accessibilityRole:"button",accessibilityLabel:"Cancel",onPress:r,style:styles.cancelButton,children:(0,_jsxRuntime.jsx)(_sharedUi.X,{size:16,color:_sharedUi.night.color.textTertiary})})]})}function PatternChip({mode:n,pattern:l,onRemove:i}){const r=getFilterConfig(l.type);return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:(0,_testIDs.patternChipTestID)(n,l.type,l.value),accessibilityRole:"button",accessibilityLabel:`${r.label} ${l.value}, tap to remove`,style:[styles.patternChip,{borderColor:r.color+"40"}],onPress:i,activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.patternChipBadge,{backgroundColor:r.color+"20"}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.patternChipBadgeText,{color:r.color}],children:r.shortLabel})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.patternChipValue,numberOfLines:1,children:l.value}),(0,_jsxRuntime.jsx)(_sharedUi.X,{size:12,color:_sharedUi.night.color.textTertiary,style:styles.patternChipX})]})}const ALL_CATEGORY_CONFIG={label:"All",shortLabel:"All",color:_sharedUi.night.color.textSecondary,icon:_sharedUi.Box};function DetectedCategoryBadge({filterType:n,count:l,isSelected:i,onPress:r}){const t=n==="all"?ALL_CATEGORY_CONFIG:getFilterConfig(n);const a=`buoy-highlight-detected-cat-${String(n).toLowerCase()}`;return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:a,accessibilityRole:"button",accessibilityLabel:`${t.label}, ${l}`,style:[styles.categoryBadge,{backgroundColor:t.color+"15",borderColor:i?t.color:t.color+"40",borderWidth:i?2:1}],onPress:r,children:[(0,_jsxRuntime.jsx)(t.icon,{size:12,color:t.color}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.categoryBadgeText,{color:t.color}],children:t.label}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.categoryBadgeCountBubble,{backgroundColor:t.color+"25"}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:`${a}-count`,style:[styles.categoryBadgeCount,{color:t.color}],children:l})})]})}const BATCH_SIZE_PRESETS=[{value:20,label:"20"},{value:50,label:"50"},{value:100,label:"100"},{value:150,label:"150"},{value:250,label:"250"},{value:500,label:"500"}];const DEBUG_LOG_LEVEL_PRESETS=[{value:"off",label:"Off",description:"No debug logging"},{value:"minimal",label:"Minimal",description:"Only hook value changes"},{value:"verbose",label:"Verbose",description:"Component + cause + changes"},{value:"all",label:"All",description:"Full fiber dump"}];function HighlightFilterView({filters:n,onFilterChange:l,settings:i,onSettingsChange:r,availableProps:t,activeTab:a}){const[s,d]=(0,_react.useState)(false);const[g,u]=(0,_react.useState)(false);const[b,T]=(0,_react.useState)(null);const[f,m]=(0,_react.useState)(null);const[h,p]=(0,_react.useState)("all");const[c,y]=(0,_react.useState)(null);const v=e=>{switch(e){case"viewType":return t.viewTypes.map(o=>({value:o,type:"viewType"}));case"testID":return t.testIDs.map(o=>({value:o,type:"testID"}));case"nativeID":return t.nativeIDs.map(o=>({value:o,type:"nativeID"}));case"component":return t.componentNames.map(o=>({value:o,type:"component"}));case"accessibilityLabel":return t.accessibilityLabels.map(o=>({value:o,type:"accessibilityLabel"}));case"all":default:return[...t.viewTypes.map(o=>({value:o,type:"viewType"})),...t.testIDs.map(o=>({value:o,type:"testID"})),...t.nativeIDs.map(o=>({value:o,type:"nativeID"})),...t.componentNames.map(o=>({value:o,type:"component"})),...t.accessibilityLabels.map(o=>({value:o,type:"accessibilityLabel"}))]}};const w=v(h);const S=t.viewTypes.length+t.testIDs.length+t.nativeIDs.length+t.componentNames.length+t.accessibilityLabels.length;const I=(0,_react.useCallback)((e,o)=>{const x=[...n.includePatterns,{type:e,value:o}];l({includePatterns:x});T(null)},[n.includePatterns,l]);const j=(0,_react.useCallback)((e,o)=>{const x=[...n.excludePatterns,{type:e,value:o}];l({excludePatterns:x});m(null)},[n.excludePatterns,l]);const D=(0,_react.useCallback)(e=>{const o=n.includePatterns.filter((x,C)=>C!==e);l({includePatterns:o})},[n.includePatterns,l]);const R=(0,_react.useCallback)(e=>{const o=n.excludePatterns.filter((x,C)=>C!==e);l({excludePatterns:o})},[n.excludePatterns,l]);const P=(0,_react.useCallback)((e,o)=>{y({type:e,value:o})},[]);const V=(0,_react.useCallback)(()=>{if(c){I(c.type,c.value);y(null)}},[c,I]);const k=(0,_react.useCallback)(()=>{if(c){j(c.type,c.value);y(null)}},[c,j]);return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.container,children:(0,_jsxRuntime.jsx)(_reactNative.ScrollView,{keyboardShouldPersistTaps:"handled",nativeID:"__rn_buoy__filter-view",testID:"buoy-highlight-filter-scroll",style:styles.scrollView,contentContainerStyle:styles.scrollContent,showsVerticalScrollIndicator:false,children:a==="filters"?(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Eye,color:_sharedUi.night.color.accent,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"INCLUDE ONLY"}),n.includePatterns.length>0&&(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Badge,{testID:"buoy-highlight-include-count",count:n.includePatterns.length,color:_sharedUi.night.color.accent})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionDescription,children:"Show only components matching these patterns. If any are set, components must match at least one."}),n.includePatterns.length>0&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.patternChips,children:n.includePatterns.map((e,o)=>(0,_jsxRuntime.jsx)(PatternChip,{mode:"include",pattern:e,onRemove:()=>D(o)},`${e.type}-${e.value}-${o}`))}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.addPatternRow,children:s?(0,_jsxRuntime.jsx)(TypePicker,{mode:"include",onSelect:e=>{d(false);T(e)},onCancel:()=>d(false)}):b?(0,_jsxRuntime.jsx)(PatternInput,{mode:"include",type:b,onSubmit:e=>I(b,e),onCancel:()=>T(null)}):(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"buoy-highlight-include-add",accessibilityRole:"button",accessibilityLabel:"Add include pattern",style:[styles.addButton,{borderColor:_sharedUi.night.color.accentBorderStrong}],onPress:()=>d(true),children:[(0,_jsxRuntime.jsx)(_sharedUi.Plus,{size:14,color:_sharedUi.night.color.accent}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.addButtonText,{color:_sharedUi.night.color.accent}],children:"Add include pattern"})]})})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Filter,color:_sharedUi.night.color.accent,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"EXCLUDE"}),n.excludePatterns.length>0&&(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Badge,{testID:"buoy-highlight-exclude-count",count:n.excludePatterns.length,color:_sharedUi.night.color.accent})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionDescription,children:"Hide components matching these patterns from the list."}),n.excludePatterns.length>0&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.patternChips,children:n.excludePatterns.map((e,o)=>(0,_jsxRuntime.jsx)(PatternChip,{mode:"exclude",pattern:e,onRemove:()=>R(o)},`${e.type}-${e.value}-${o}`))}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.addPatternRow,children:g?(0,_jsxRuntime.jsx)(TypePicker,{mode:"exclude",onSelect:e=>{u(false);m(e)},onCancel:()=>u(false)}):f?(0,_jsxRuntime.jsx)(PatternInput,{mode:"exclude",type:f,onSubmit:e=>j(f,e),onCancel:()=>m(null)}):(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"buoy-highlight-exclude-add",accessibilityRole:"button",accessibilityLabel:"Add exclude pattern",style:[styles.addButton,{borderColor:_sharedUi.night.color.accentBorderStrong}],onPress:()=>u(true),children:[(0,_jsxRuntime.jsx)(_sharedUi.Plus,{size:14,color:_sharedUi.night.color.accent}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.addButtonText,{color:_sharedUi.night.color.accent}],children:"Add exclude pattern"})]})})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Hash,color:_sharedUi.night.color.warning,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"RENDER COUNT RANGE"}),(n.minRenderCount!==void 0||n.maxRenderCount!==void 0)&&(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Badge,{count:1,color:_sharedUi.night.color.warning})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionDescription,children:"Show only components with render count in a specific range."}),(0,_jsxRuntime.jsxs)(_reactNative.View,{nativeID:"__rn_buoy__render-count-range",testID:"buoy-highlight-range",style:styles.renderCountRangeContainer,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.renderCountInputRow,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.renderCountInputGroup,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.renderCountLabel,children:"Min"}),(0,_jsxRuntime.jsx)(_reactNative.TextInput,{value:n.minRenderCount!==void 0?String(n.minRenderCount):"",onChangeText:e=>{const o=parseInt(e,10);if(e===""||e===void 0){l({minRenderCount:void 0})}else if(!isNaN(o)&&o>=0){l({minRenderCount:o})}},testID:"buoy-highlight-range-min",placeholder:"0",placeholderTextColor:_sharedUi.night.color.placeholder,style:styles.renderCountInput,keyboardType:"number-pad",returnKeyType:"done"})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.renderCountSeparator,children:"to"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.renderCountInputGroup,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.renderCountLabel,children:"Max"}),(0,_jsxRuntime.jsx)(_reactNative.TextInput,{value:n.maxRenderCount!==void 0?String(n.maxRenderCount):"",onChangeText:e=>{const o=parseInt(e,10);if(e===""||e===void 0){l({maxRenderCount:void 0})}else if(!isNaN(o)&&o>=0){l({maxRenderCount:o})}},testID:"buoy-highlight-range-max",placeholder:"\u221E",placeholderTextColor:_sharedUi.night.color.placeholder,style:styles.renderCountInput,keyboardType:"number-pad",returnKeyType:"done"})]})]}),(n.minRenderCount!==void 0||n.maxRenderCount!==void 0)&&(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"buoy-highlight-range-clear",accessibilityRole:"button",accessibilityLabel:"Clear range",style:styles.clearRangeButton,onPress:()=>l({minRenderCount:void 0,maxRenderCount:void 0}),children:[(0,_jsxRuntime.jsx)(_sharedUi.X,{size:12,color:_sharedUi.night.color.warning}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.clearRangeButtonText,children:"Clear Range"})]})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Box,color:_sharedUi.night.color.textSecondary,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"DETECTED ITEMS"})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionDescription,children:"Tap an item to quickly add it as an exclude pattern."}),(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{keyboardShouldPersistTaps:"handled",horizontal:true,showsHorizontalScrollIndicator:false,style:styles.categoryBadgeScroll,contentContainerStyle:styles.categoryBadgeScrollContent,children:[S>0&&(0,_jsxRuntime.jsx)(DetectedCategoryBadge,{filterType:"all",count:S,isSelected:h==="all",onPress:()=>p("all")}),t.viewTypes.length>0&&(0,_jsxRuntime.jsx)(DetectedCategoryBadge,{filterType:"viewType",count:t.viewTypes.length,isSelected:h==="viewType",onPress:()=>p("viewType")}),t.testIDs.length>0&&(0,_jsxRuntime.jsx)(DetectedCategoryBadge,{filterType:"testID",count:t.testIDs.length,isSelected:h==="testID",onPress:()=>p("testID")}),t.nativeIDs.length>0&&(0,_jsxRuntime.jsx)(DetectedCategoryBadge,{filterType:"nativeID",count:t.nativeIDs.length,isSelected:h==="nativeID",onPress:()=>p("nativeID")}),t.componentNames.length>0&&(0,_jsxRuntime.jsx)(DetectedCategoryBadge,{filterType:"component",count:t.componentNames.length,isSelected:h==="component",onPress:()=>p("component")}),t.accessibilityLabels.length>0&&(0,_jsxRuntime.jsx)(DetectedCategoryBadge,{filterType:"accessibilityLabel",count:t.accessibilityLabels.length,isSelected:h==="accessibilityLabel",onPress:()=>p("accessibilityLabel")})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{nativeID:"__rn_buoy__detected-items",testID:"buoy-highlight-detected",style:styles.detectedItemsContainer,children:w.length>0?(0,_jsxRuntime.jsx)(_reactNative.ScrollView,{keyboardShouldPersistTaps:"handled",testID:"buoy-highlight-detected-scroll",style:styles.detectedItemsScroll,contentContainerStyle:styles.detectedItems,nestedScrollEnabled:true,showsVerticalScrollIndicator:true,children:w.map(e=>{const o=getFilterConfig(e.type);return(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:(0,_testIDs.detectedItemTestID)(e.type,e.value),accessibilityRole:"button",accessibilityLabel:`${o.label} ${e.value}`,style:[styles.detectedItem,{borderColor:o.color+"40"}],onPress:()=>P(e.type,e.value),children:h==="all"?(0,_jsxRuntime.jsx)(_IdentifierBadge.IdentifierBadge,{type:e.type,value:e.value,compact:true,shortLabel:true}):(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detectedItemText,numberOfLines:1,children:e.value})},`${e.type}-${e.value}`)})}):(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:"buoy-highlight-detected-empty",style:styles.emptyText,children:"No items detected yet. Start tracking to see components here."})})]}),(0,_jsxRuntime.jsx)(_reactNative.Modal,{visible:c!==null,transparent:true,animationType:"fade",onRequestClose:()=>y(null),children:(0,_jsxRuntime.jsx)(_reactNative.Pressable,{accessible:false,testID:"buoy-highlight-detected-popup-backdrop",style:styles.modalOverlay,onPress:()=>y(null),children:(0,_jsxRuntime.jsx)(_reactNative.View,{accessible:false,testID:"buoy-highlight-detected-popup",style:styles.actionPopup,children:c&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.actionPopupHeader,children:(0,_jsxRuntime.jsx)(_IdentifierBadge.IdentifierBadge,{type:c.type,value:c.value,compact:true,shortLabel:true})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.actionPopupButtons,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"buoy-highlight-detected-popup-include",accessibilityRole:"button",accessibilityLabel:"Include only",style:[styles.actionPopupButton,styles.actionPopupInclude],onPress:V,children:[(0,_jsxRuntime.jsx)(_sharedUi.Eye,{size:16,color:_sharedUi.night.color.accent}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionPopupButtonText,{color:_sharedUi.night.color.accent}],children:"Include Only"})]}),(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:"buoy-highlight-detected-popup-exclude",accessibilityRole:"button",accessibilityLabel:"Exclude",style:[styles.actionPopupButton,styles.actionPopupExclude],onPress:k,children:[(0,_jsxRuntime.jsx)(_sharedUi.Filter,{size:16,color:_sharedUi.night.color.accent}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionPopupButtonText,{color:_sharedUi.night.color.accent}],children:"Exclude"})]})]}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:"buoy-highlight-detected-popup-cancel",accessibilityRole:"button",accessibilityLabel:"Cancel",style:styles.actionPopupCancel,onPress:()=>y(null),children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.actionPopupCancelText,children:"Cancel"})})]})})})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Filter,color:_sharedUi.night.color.textTertiary,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"HOW FILTERS WORK"})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.howItWorks,children:(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.howItWorksText,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.howItWorksBold,children:"Any:"})," Matches against all fields","\n",(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.howItWorksBold,children:"ViewType:"})," Native component class (RCTView, RCTText)","\n",(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.howItWorksBold,children:"testID:"})," Component testID prop","\n",(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.howItWorksBold,children:"Component:"})," React component name from fiber"]})})]})]}):(0,_jsxRuntime.jsx)(_jsxRuntime.Fragment,{children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Settings,color:_sharedUi.night.color.textTertiary,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"SETTINGS"})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingsSection,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingItem,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingLabel,children:"Show Render Count"}),(0,_jsxRuntime.jsx)(_reactNative.Switch,{testID:(0,_testIDs.settingTestID)("showRenderCount"),value:i.showRenderCount,onValueChange:e=>{r({showRenderCount:e});if(!e&&i.trackRenderCauses){r({trackRenderCauses:false})}},trackColor:{false:_sharedUi.night.color.surfaceElevated,true:_sharedUi.night.color.accent+"80"},thumbColor:i.showRenderCount?_sharedUi.night.color.accent:_sharedUi.night.color.knob})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingDescription,children:"Display render count badge on highlights. Disabling improves performance by skipping count tracking."})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.settingItem,styles.settingItemSpaced],children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.settingLabel,!i.showRenderCount&&styles.settingLabelDisabled],children:"Track Render Causes"}),(0,_jsxRuntime.jsx)(_reactNative.Switch,{testID:(0,_testIDs.settingTestID)("trackRenderCauses"),value:i.trackRenderCauses,onValueChange:e=>r({trackRenderCauses:e}),trackColor:{false:_sharedUi.night.color.surfaceElevated,true:_sharedUi.night.color.warning+"80"},thumbColor:i.trackRenderCauses?_sharedUi.night.color.warning:_sharedUi.night.color.knob,disabled:!i.showRenderCount})]}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.settingDescription,children:["Detect WHY components render (props, hooks, parent re-render).",!i.showRenderCount&&(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.settingWarning,children:["\n",'Requires "Show Render Count" to be enabled.']})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.settingItem,styles.settingItemSpaced],children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.settingLabel,!i.trackRenderCauses&&styles.settingLabelDisabled],children:"Enable Render History"}),(0,_jsxRuntime.jsx)(_reactNative.Switch,{testID:(0,_testIDs.settingTestID)("enableRenderHistory"),value:i.enableRenderHistory,onValueChange:e=>r({enableRenderHistory:e}),trackColor:{false:_sharedUi.night.color.surfaceElevated,true:_sharedUi.night.color.accent+"80"},thumbColor:i.enableRenderHistory?_sharedUi.night.color.accent:_sharedUi.night.color.knob,disabled:!i.trackRenderCauses})]}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.settingDescription,children:["Store render events for each component to view in the History tab.",!i.trackRenderCauses&&(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.settingWarning,children:["\n",'Requires "Track Render Causes" to be enabled.']})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.settingItem,styles.settingItemSpaced],children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingLabel,children:"Debug Log Level"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.settingValue,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:"buoy-highlight-setting-debugLogLevel-value",style:[styles.settingValueText,i.debugLogLevel!=="off"&&{color:_sharedUi.night.color.warning}],children:DEBUG_LOG_LEVEL_PRESETS.find(e=>e.value===i.debugLogLevel)?.label||"Off"})})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingDescription,children:"Control console logging verbosity for render cause detection."}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.batchSizePresets,children:DEBUG_LOG_LEVEL_PRESETS.map(e=>(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.batchSizePreset,i.debugLogLevel===e.value&&styles.batchSizePresetActive,e.value!=="off"&&i.debugLogLevel===e.value&&{backgroundColor:_sharedUi.night.color.warningSoft,borderColor:_sharedUi.night.color.warning}],onPress:()=>r({debugLogLevel:e.value}),testID:`buoy-highlight-preset-log-${e.value}`,accessibilityRole:"button",accessibilityLabel:`Debug log level ${e.label}`,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.batchSizePresetText,i.debugLogLevel===e.value&&styles.batchSizePresetTextActive,e.value!=="off"&&i.debugLogLevel===e.value&&{color:_sharedUi.night.color.warning}],children:e.label})},e.value))}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.settingDescriptionMuted,children:[DEBUG_LOG_LEVEL_PRESETS.find(e=>e.value===i.debugLogLevel)?.description,i.debugLogLevel!=="off"&&" \u2022 Check Metro console for logs"]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.settingItem,styles.settingItemSpaced],children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingLabel,children:"Batch Size"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.settingValue,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{testID:"buoy-highlight-setting-batchSize-value",style:styles.settingValueText,children:i.batchSize})})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingDescription,children:"Maximum components to highlight per render update. Higher values capture more re-renders but may impact performance on complex screens."}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.batchSizePresets,children:BATCH_SIZE_PRESETS.map(e=>(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.batchSizePreset,i.batchSize===e.value&&styles.batchSizePresetActive],onPress:()=>r({batchSize:e.value}),testID:`buoy-highlight-preset-batch-${e.value}`,accessibilityRole:"button",accessibilityLabel:`Batch size ${e.label}`,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.batchSizePresetText,i.batchSize===e.value&&styles.batchSizePresetTextActive],children:e.label})},e.value))})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.settingItem,styles.settingItemSpaced],children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingLabel,children:"Show host views"}),(0,_jsxRuntime.jsx)(_reactNative.Switch,{testID:(0,_testIDs.settingTestID)("showHostViews"),value:!!i.showHostViews,onValueChange:e=>r({showHostViews:e}),trackColor:{false:_sharedUi.night.color.surfaceElevated,true:_sharedUi.night.color.accent+"80"},thumbColor:i.showHostViews?_sharedUi.night.color.accent:_sharedUi.night.color.knob})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingDescription,children:"Include anonymous View / RCTView / Text hosts. Off by default so the list is named composites (what actually re-rendered)."})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.settingItem,styles.settingItemSpaced],children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.settingHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.settingLabel,children:"Highlight Dev Tools"}),(0,_jsxRuntime.jsx)(_reactNative.Switch,{testID:(0,_testIDs.settingTestID)("excludeDevTools"),value:!i.excludeDevTools,onValueChange:e=>r({excludeDevTools:!e}),trackColor:{false:_sharedUi.night.color.surfaceElevated,true:_sharedUi.night.color.accent+"80"},thumbColor:!i.excludeDevTools?_sharedUi.night.color.accent:_sharedUi.night.color.knob})]}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.settingDescription,children:["Show re-render highlights on Buoy dev tools (floating menu, modals, etc.). Useful for optimizing the dev tools themselves.",!i.excludeDevTools&&(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.settingWarning,children:["\n","The highlight overlay is always excluded to prevent infinite loops."]})]})]})]})]})})})})}const styles=_reactNative.StyleSheet.create({container:{flex:1,backgroundColor:"transparent"},scrollView:{flex:1},scrollContent:{paddingHorizontal:16,paddingTop:12,paddingBottom:32},section:{backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,marginBottom:12,overflow:"hidden"},sectionDescription:{fontSize:11,color:_sharedUi.night.color.textSecondary,paddingHorizontal:16,paddingTop:8,lineHeight:16},patternChips:{flexDirection:"row",flexWrap:"wrap",gap:8,paddingHorizontal:16,paddingTop:12},patternChip:{flexDirection:"row",alignItems:"center",backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:6,borderWidth:1,paddingVertical:4,paddingLeft:4,paddingRight:6,maxWidth:"100%",gap:4},patternChipBadge:{paddingVertical:2,paddingHorizontal:5,borderRadius:4},patternChipBadgeText:{fontSize:9,fontWeight:"700"},patternChipValue:{fontSize:11,color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont,flexShrink:1},patternChipX:{marginLeft:2},addPatternRow:{paddingHorizontal:16,paddingTop:12,paddingBottom:16},addButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",paddingVertical:10,paddingHorizontal:16,borderRadius:8,borderWidth:1,borderStyle:"dashed",gap:6},addButtonText:{fontSize:12,fontWeight:"500"},typePicker:{flexDirection:"row",alignItems:"center",gap:8},typePickerRow:{flex:1,flexDirection:"row",flexWrap:"wrap",gap:8},typeOption:{flexDirection:"row",alignItems:"center",paddingVertical:8,paddingHorizontal:12,borderRadius:6,borderWidth:1,backgroundColor:_sharedUi.night.color.surfaceElevated,gap:6},typeOptionText:{fontSize:11,fontWeight:"600"},typePickerCancel:{padding:8},patternInputContainer:{flexDirection:"row",alignItems:"center",backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,paddingLeft:4,paddingRight:8,paddingVertical:4,gap:4},patternInput:{flex:1,fontSize:12,color:_sharedUi.night.color.text,paddingVertical:6,paddingHorizontal:4},addPatternButton:{paddingVertical:6,paddingHorizontal:10,borderRadius:4},addPatternButtonText:{fontSize:11,fontWeight:"600"},cancelButton:{padding:4},categoryBadgeScroll:{marginTop:12},categoryBadgeScrollContent:{paddingHorizontal:16,gap:8},categoryBadge:{flexDirection:"row",alignItems:"center",paddingVertical:8,paddingLeft:10,paddingRight:6,borderRadius:8,borderWidth:1,gap:6},categoryBadgeText:{fontSize:11,fontWeight:"600"},categoryBadgeCountBubble:{paddingHorizontal:6,paddingVertical:2,borderRadius:10,minWidth:20,alignItems:"center"},categoryBadgeCount:{fontSize:10,fontWeight:"600"},detectedItemsContainer:{paddingHorizontal:16,paddingTop:12,paddingBottom:16},detectedItemsScroll:{maxHeight:200},detectedItems:{flexDirection:"row",flexWrap:"wrap",gap:8},detectedItem:{flexDirection:"row",alignItems:"center",backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:6,borderWidth:1,paddingVertical:6,paddingHorizontal:10,gap:6},detectedItemText:{fontSize:11,color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},emptyText:{fontSize:11,color:_sharedUi.night.color.textTertiary,fontStyle:"italic",textAlign:"center",paddingVertical:16,paddingHorizontal:16},howItWorks:{paddingHorizontal:16,paddingVertical:12},howItWorksText:{fontSize:11,color:_sharedUi.night.color.textTertiary,lineHeight:18,fontFamily:_sharedUi.monoFont},howItWorksBold:{fontWeight:"700",color:_sharedUi.night.color.textSecondary},modalOverlay:{flex:1,backgroundColor:"rgba(0, 0, 0, 0.5)",justifyContent:"center",alignItems:"center",padding:32},actionPopup:{backgroundColor:_sharedUi.night.color.surface,borderRadius:12,borderWidth:1,borderColor:_sharedUi.night.color.border,width:"100%",maxWidth:300,overflow:"hidden"},actionPopupHeader:{padding:16,borderBottomWidth:1,borderBottomColor:_sharedUi.night.color.separator,alignItems:"center"},actionPopupButtons:{flexDirection:"row",padding:12,gap:8},actionPopupButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",paddingVertical:12,paddingHorizontal:12,borderRadius:8,gap:8},actionPopupInclude:{backgroundColor:_sharedUi.night.color.accentSoft},actionPopupExclude:{backgroundColor:_sharedUi.night.color.accentSoft},actionPopupButtonText:{fontSize:13,fontWeight:"600"},actionPopupCancel:{padding:12,borderTopWidth:1,borderTopColor:_sharedUi.night.color.separator,alignItems:"center"},actionPopupCancelText:{fontSize:13,color:_sharedUi.night.color.textTertiary,fontWeight:"500"},settingsSection:{paddingHorizontal:16,paddingTop:8,paddingBottom:16},settingItem:{gap:8},settingItemSpaced:{marginTop:16,paddingTop:16,borderTopWidth:1,borderTopColor:_sharedUi.night.color.separator},settingHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between"},settingLabel:{fontSize:13,fontWeight:"600",color:_sharedUi.night.color.text},settingValue:{backgroundColor:_sharedUi.night.color.fillSecondary,paddingHorizontal:10,paddingVertical:4,borderRadius:6},settingValueText:{fontSize:12,fontWeight:"700",color:_sharedUi.night.color.textTertiary,fontFamily:_sharedUi.monoFont},settingDescription:{fontSize:11,color:_sharedUi.night.color.textSecondary,lineHeight:16},settingDescriptionMuted:{fontSize:10,color:_sharedUi.night.color.textTertiary,lineHeight:14,marginTop:4,fontStyle:"italic"},settingLabelDisabled:{color:_sharedUi.night.color.textTertiary},settingWarning:{color:_sharedUi.night.color.warning,fontWeight:"500"},batchSizePresets:{flexDirection:"row",flexWrap:"wrap",gap:8,marginTop:4},batchSizePreset:{paddingVertical:8,paddingHorizontal:14,borderRadius:6,backgroundColor:_sharedUi.night.color.surfaceElevated,borderWidth:1,borderColor:_sharedUi.night.color.border},batchSizePresetActive:{backgroundColor:_sharedUi.night.color.fillSecondary,borderColor:_sharedUi.night.color.fillTertiary},batchSizePresetText:{fontSize:12,fontWeight:"500",color:_sharedUi.night.color.textSecondary,fontFamily:_sharedUi.monoFont},batchSizePresetTextActive:{color:_sharedUi.night.color.textTertiary,fontWeight:"700"},renderCountRangeContainer:{paddingHorizontal:16,paddingTop:12,paddingBottom:16,gap:12},renderCountInputRow:{flexDirection:"row",alignItems:"center",gap:12},renderCountInputGroup:{flex:1,gap:4},renderCountLabel:{fontSize:10,fontWeight:"600",color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},renderCountInput:{backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,paddingVertical:10,paddingHorizontal:12,fontSize:14,fontWeight:"600",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont,textAlign:"center"},renderCountSeparator:{fontSize:12,color:_sharedUi.night.color.textTertiary,marginTop:18},clearRangeButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",paddingVertical:8,paddingHorizontal:12,borderRadius:6,backgroundColor:_sharedUi.night.color.warningSoft,borderWidth:1,borderColor:_sharedUi.night.color.warning+"40",gap:6,alignSelf:"center"},clearRangeButtonText:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.warning}});var _default=exports.default=HighlightFilterView;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.default=exports.IsolatedRenderList=void 0;var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _RenderTracker=require("../utils/RenderTracker");var _RenderListItem=require("./RenderListItem");var _sharedUi=require("@buoy-gg/shared-ui");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(n,f){if("function"==typeof WeakMap)var l=new WeakMap,c=new WeakMap;return(_interopRequireWildcard=function(e,d){if(!d&&e&&e.__esModule)return e;var o,r,s={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return s;if(o=d?c:l){if(o.has(e))return o.get(e);o.set(e,s)}for(const i in e)"default"!==i&&{}.hasOwnProperty.call(e,i)&&((r=(o=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,i))&&(r.get||r.set)?o(s,i,r):s[i]=e[i]);return s})(n,f)}function IsolatedRenderListInner({searchText:n,filters:f,onSelectRender:l,onStatsChange:c,onRendersChange:e,isTracking:d,isPro:o=false}){const[r,s]=(0,_react.useState)(()=>_RenderTracker.RenderTracker.getFilteredRenders(n));const i=(0,_react.useRef)(null);(0,_react.useEffect)(()=>{const t=_RenderTracker.RenderTracker.subscribe(()=>{const a=_RenderTracker.RenderTracker.getFilteredRenders(n);s(a);c(_RenderTracker.RenderTracker.getStats());e?.(a)});return t},[n,c,e]);(0,_react.useEffect)(()=>{const t=_RenderTracker.RenderTracker.getFilteredRenders(n);s(t);e?.(t)},[n,f,e]);const
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.default=exports.IsolatedRenderList=void 0;var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _RenderTracker=require("../utils/RenderTracker");var _RenderListItem=require("./RenderListItem");var _sharedUi=require("@buoy-gg/shared-ui");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(n,f){if("function"==typeof WeakMap)var l=new WeakMap,c=new WeakMap;return(_interopRequireWildcard=function(e,d){if(!d&&e&&e.__esModule)return e;var o,r,s={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return s;if(o=d?c:l){if(o.has(e))return o.get(e);o.set(e,s)}for(const i in e)"default"!==i&&{}.hasOwnProperty.call(e,i)&&((r=(o=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,i))&&(r.get||r.set)?o(s,i,r):s[i]=e[i]);return s})(n,f)}function IsolatedRenderListInner({searchText:n,filters:f,onSelectRender:l,onStatsChange:c,onRendersChange:e,isTracking:d,isPro:o=false}){const[r,s]=(0,_react.useState)(()=>_RenderTracker.RenderTracker.getFilteredRenders(n));const i=(0,_react.useRef)(null);(0,_react.useEffect)(()=>{const t=_RenderTracker.RenderTracker.subscribe(()=>{const a=_RenderTracker.RenderTracker.getFilteredRenders(n);s(a);c(_RenderTracker.RenderTracker.getStats());e?.(a)});return t},[n,c,e]);(0,_react.useEffect)(()=>{const t=_RenderTracker.RenderTracker.getFilteredRenders(n);s(t);e?.(t)},[n,f,e]);const m=(0,_sharedUi.useLimit)("highlightUpdates.components");const u=o?Infinity:m;const g=(0,_react.useMemo)(()=>{return r.slice(0,u)},[r,u]);const p=(0,_react.useMemo)(()=>{return Math.max(0,r.length-u)},[r.length,u]);const h=(0,_react.useCallback)(t=>t.id,[]);const y=(0,_react.useCallback)(({item:t,index:a})=>(0,_jsxRuntime.jsx)(_RenderListItem.RenderListItem,{render:t,onPress:()=>{_reactNative.Keyboard.dismiss();l(t,a,g)}}),[l,g]);const b=(0,_react.useCallback)(()=>{if(p<=0)return null;return(0,_jsxRuntime.jsxs)(_reactNative.View,{testID:"buoy-highlight-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-locked-text",style:styles.lockedBannerText,children:[p," more ",p===1?"component":"components"," locked"]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.lockedBannerSubtext,children:"Upgrade to Pro"})]})},[p]);if(r.length===0){const t=n.trim();const a=_RenderTracker.RenderTracker.getStats().totalComponents;const k=t?_RenderTracker.RenderTracker.getFilteredRenders("").length:0;const R=(0,_sharedUi.resolveListEmptyState)({subject:"components",verb:"tracked",search:n,total:t?k:a,capturing:d,blocked:t&&k===0&&a>0?"The active filters hide everything tracked, so there is nothing to search.":void 0,waiting:{otto:"stare",title:"No renders tracked",message:"Component renders will appear here"},paused:{title:"No renders tracked",message:"Enable tracking to start capturing"}});return(0,_jsxRuntime.jsx)(_sharedUi.ToolEmptyState,{...R,testID:"buoy-highlight-empty"})}return(0,_jsxRuntime.jsx)(_reactNative.FlatList,{testID:"buoy-highlight-list",ref:i,keyboardShouldPersistTaps:"handled",data:g,renderItem:y,keyExtractor:h,contentContainerStyle:styles.listContent,showsVerticalScrollIndicator:true,initialNumToRender:10,maxToRenderPerBatch:10,windowSize:10,scrollEnabled:false,ListFooterComponent:b})}const IsolatedRenderList=exports.IsolatedRenderList=(0,_react.memo)(IsolatedRenderListInner);const styles=_reactNative.StyleSheet.create({listContent:{paddingTop:8},lockedBanner:{flexDirection:"row",alignItems:"center",justifyContent:"center",paddingVertical:12,paddingHorizontal:16,marginTop:8,gap:8},lockedBannerText:{color:_sharedUi.night.color.warning,fontSize:13,fontWeight:"500"},lockedBannerSubtext:{color:_sharedUi.night.color.textTertiary,fontSize:12}});var _default=exports.default=IsolatedRenderList;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.collectDOMElements=collectDOMElements;exports.domElementName=domElementName;exports.labeledField=labeledField;exports.watchDOMChanges=watchDOMChanges;var _utils=require("@buoy-gg/shared-ui/utils");const INTERACTIVE_ROLES=new Set(["button","link","menuitem","tab","switch","checkbox","radio","option","textbox","slider"]);const SKIP_TAGS=new Set(["SCRIPT","STYLE","NOSCRIPT","TEMPLATE","SVG","PATH","HEAD","META","LINK"]);const MAX_TEXT=80;function isReactContainer(
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.collectDOMElements=collectDOMElements;exports.domElementName=domElementName;exports.labeledField=labeledField;exports.watchDOMChanges=watchDOMChanges;var _utils=require("@buoy-gg/shared-ui/utils");const INTERACTIVE_ROLES=new Set(["button","link","menuitem","tab","switch","checkbox","radio","option","textbox","slider"]);const SKIP_TAGS=new Set(["SCRIPT","STYLE","NOSCRIPT","TEMPLATE","SVG","PATH","HEAD","META","LINK"]);const MAX_TEXT=80;function isReactContainer(t){for(const r in t){if(r.startsWith("__reactContainer$")||r==="_reactRootContainer")return true}return false}function isHidden(t){if(t.getAttribute("aria-hidden")==="true")return true;const r=getComputedStyle(t);return r.display==="none"||r.visibility==="hidden"}function hasClick(t){const r=t;return typeof r.$$click==="function"||typeof r.onclick==="function"||t.tabIndex>=0&&t.hasAttribute("tabindex")}const INLINE_TAGS=new Set(["B","STRONG","EM","I","U","S","SPAN","SMALL","MARK","CODE","SUB","SUP","ABBR","CITE","Q","TIME","BR"]);function hasOwnText(t){return Array.from(t.childNodes).some(r=>r.nodeType===3&&(r.textContent??"").trim()!=="")}function isPlainInline(t){return INLINE_TAGS.has(t.tagName.toUpperCase())&&!t.hasAttribute("data-testid")&&!t.hasAttribute("aria-label")&&!t.hasAttribute("role")&&!hasClick(t)&&!t.querySelector(`${CONTROLS}, [role], [data-testid], [aria-label]`)}function ownText(t){let r="";const n=hasOwnText(t);const e=o=>{if(o.nodeType===3)r+=o.textContent??"";else if(n&&o.nodeType===1){const i=o;if(i.tagName==="BR")r+=" ";else if(isPlainInline(i)&&!isHidden(i))i.childNodes.forEach(e)}};t.childNodes.forEach(e);r=r.replace(/\s+/g," ").trim();return r||void 0}function clip(t,r){if(!t)return void 0;return r||t.length<=MAX_TEXT?t:`${t.slice(0,MAX_TEXT)}\u2026`}function allText(t,r){return clip((t.innerText??t.textContent??"").replace(/\s+/g," ").trim(),r)}const FIELDS="input, textarea, select";const CONTROLS=`${FIELDS}, button, a[href]`;function readText(t){let r="";const n=e=>{if(e.nodeType===3)r+=e.textContent??"";else if(e.nodeType===1&&!e.matches(FIELDS))e.childNodes.forEach(n)};n(t);return r.replace(/\s+/g," ").trim()}function nearbyLabel(t){let r=t;for(let n=0;n<3;n++){const e=r.previousElementSibling;if(e){const i=readText(e);return i&&i.length<=MAX_TEXT&&!e.matches(CONTROLS)&&!e.querySelector(CONTROLS)?e:null}const o=r.parentElement;if(!o||o.querySelectorAll(FIELDS).length>1)return null;r=o}return null}function accessibleName(t){const r=(t.getAttribute("aria-labelledby")??"").split(/\s+/).map(o=>o&&document.getElementById(o)?readText(document.getElementById(o)):"").filter(Boolean).join(" ");const n=Array.from(t.labels??[]).map(readText).filter(Boolean).join(" ");const e=t.matches(FIELDS)?nearbyLabel(t):null;return r||t.getAttribute("aria-label")||n||t.getAttribute("title")||t.getAttribute("placeholder")||(e?readText(e):"")}function labeledField(t){const r=t.closest("label")?.control;if(r instanceof HTMLElement)return r;const n=t.closest("[id]")?.id;if(n){for(const e of Array.from(document.querySelectorAll("[aria-labelledby]"))){if(e.matches(`${FIELDS}, [role=textbox]`)&&e.getAttribute("aria-labelledby").split(/\s+/).includes(n))return e}}for(let e=t,o=0;e&&o<3;e=e.parentElement,o++){const i=e.nextElementSibling;const s=i?.matches(FIELDS)?i:i?.querySelector(FIELDS);if(s instanceof HTMLElement&&nearbyLabel(s)===e)return s}return null}function collectDOMElements(t={}){if(typeof document==="undefined"||!document.body)return[];const r=[];const n=(e,o,i)=>{if(SKIP_TAGS.has(e.tagName.toUpperCase())||isReactContainer(e)||isHidden(e))return;const s=i||e.hasAttribute("data-buoy-root")||e.hasAttribute("data-buoy-portal-host");const a=e.tagName.toLowerCase();const l=e.getAttribute("role")??void 0;const c=a==="button"||a==="a"&&e.hasAttribute("href")||a==="input"||a==="textarea"||a==="select"||l!==void 0&&INTERACTIVE_ROLES.has(l)||hasClick(e);const f=e.getAttribute("data-testid")??void 0;const b=c?clip(accessibleName(e),!!t.fullText):e.getAttribute("aria-label")??void 0;const h=c?allText(e,!!t.fullText):o?void 0:ownText(e);if(c||f||b||h){const u={"data-testid":f,"aria-label":b,role:l,id:e.id||void 0};if(c&&a!=="input"&&a!=="textarea"&&a!=="select")u.onClick=()=>e.click();const d=(0,_utils.getDOMControlProps)(e,u);if(l==="switch"||l==="checkbox"){const y=e.getAttribute("aria-checked")==="true";d.value=y;d.onValueChange=A=>{if(Boolean(A)!==(e.getAttribute("aria-checked")==="true"))e.click()};delete d.onPress}if(e.disabled)delete d.onPress;r.push({element:e,props:d,text:h,buoy:s})}const p=!c&&!o&&hasOwnText(e);for(const u of Array.from(e.children)){if(p&&isPlainInline(u))continue;if(u instanceof HTMLElement)n(u,o||c,s)}};n(document.body,false,false);return r}function domElementName(t){const r=globalThis[Symbol.for("buoy.dom.componentName")];try{const n=r?.(t);if(n)return n}catch{}return t.tagName.toLowerCase()}function watchDOMChanges(){if(typeof MutationObserver==="undefined"||typeof document==="undefined")return()=>0;let t=0;const r=new MutationObserver(()=>{t+=1});r.observe(document.body,{subtree:true,childList:true,characterData:true,attributes:true});return()=>{r.disconnect();return t}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.describeScreen=describeScreen;exports.hitTest=hitTest;exports.readMaps=readMaps;exports.resolveTouchTarget=resolveTouchTarget;exports.tapElement=tapElement;exports.waitFor=waitFor;var _utils=require("@buoy-gg/shared-ui/utils");var _reactNative=require("react-native");var _tapMatch=require("./tapMatch");var _domScreenElements=require("./domScreenElements");const HostComponent=5;const OffscreenComponent=22;const INTERNAL_NAMES=new Set(["View","RCTView","ScrollView","RCTScrollView","RCTScrollContentView","SafeAreaView","RCTSafeAreaView","AndroidHorizontalScrollContentView","KeyboardAvoidingView","Pressable","PlatformPressable","TouchableOpacity","TouchableHighlight","TouchableWithoutFeedback","TouchableNativeFeedback","AnimatedComponent","Wrapper"]);function getReactDevToolsHook(){if(typeof global==="undefined")return null;return global.__REACT_DEVTOOLS_GLOBAL_HOOK__??null}let commitCount=0;let commitCounterInstalled=false;function ensureCommitCounter(){if(commitCounterInstalled)return;const e=getReactDevToolsHook();if(!e)return;const t=e.onCommitFiberRoot;e.onCommitFiberRoot=function(...n){commitCount++;return typeof t==="function"?t.apply(e,n):void 0};commitCounterInstalled=true}const TAP_SETTLE_MS=250;function makeChromeCheck(){const e=new Map;return t=>{const n=[];let r=t;let i=0;let l=false;while(r&&i<400){const a=e.get(r);if(a!==void 0){l=a;break}if(getProps(r)?.__buoyDevToolsRoot){l=true;e.set(r,true);break}n.push(r);r=r.return;i++}for(const a of n)e.set(a,l);return l}}function getAllFiberRoots(){const e=getReactDevToolsHook();if(!e)return[];const t=[];try{if(e.renderers&&typeof e.renderers.forEach==="function"){e.renderers.forEach((n,r)=>{try{const i=e.getFiberRoots?.(r);if(i)i.forEach(l=>t.push(l))}catch{}})}if(t.length===0&&e.getFiberRoots){const n=e.getFiberRoots(1);if(n)n.forEach(r=>t.push(r))}}catch{}return t}function isHiddenOffscreen(e){return e.tag===OffscreenComponent&&e.memoizedState!==null}let includeHiddenScreens=false;let prunedHiddenScreens=0;let fullVisibleText=false;function withHiddenScreens(e,t){const n=includeHiddenScreens;includeHiddenScreens=e;try{return t()}finally{includeHiddenScreens=n}}function isNotShowingScreen(e){const t=e.memoizedProps;if(!t)return false;if(t["aria-hidden"]===true&&(t.activityState!==void 0||"shouldFreeze"in t))return true;if(t.isFocused===false&&(t.routeKey!==void 0||"freezeContents"in t))return true;return false}function isInactiveScreen(e){const t=e.memoizedProps?.activityState;if(t===0||t===1)return true;if(e.memoizedProps?.isPageFocused===false)return true;if(!includeHiddenScreens&&isNotShowingScreen(e)){prunedHiddenScreens++;return true}return false}function traverseFiberTree(e,t,n=0,r=new Set){if(!e||r.has(e)||n>500)return;r.add(e);if(isHiddenOffscreen(e)||isInactiveScreen(e)){if(e.sibling)traverseFiberTree(e.sibling,t,n,r);return}t(e);if(e.child)traverseFiberTree(e.child,t,n+1,r);if(e.sibling)traverseFiberTree(e.sibling,t,n,r)}function getPublicInstance(e){const t=(0,_utils.getDOMPublicInstance)(e);if(t)return t;if(!e)return null;const n=e;if(n.canonical?.publicInstance)return n.canonical.publicInstance;if(n.canonical&&typeof n.canonical.measure==="function"){return n.canonical}if(typeof n.measure==="function"||typeof n.measureInWindow==="function"){return n}return null}function getNativeTag(e){const t=(0,_utils.getDOMNodeHandle)(e);if(t!==null)return t;if(e==null)return null;const n=e;if(typeof n.__nativeTag==="number")return n.__nativeTag;if(typeof n._nativeTag==="number")return n._nativeTag;if(typeof n.nativeTag==="number")return n.nativeTag;if(n.canonical){if(typeof n.canonical.__nativeTag==="number")return n.canonical.__nativeTag;if(typeof n.canonical._nativeTag==="number")return n.canonical._nativeTag;if(typeof n.canonical.nativeTag==="number")return n.canonical.nativeTag}return null}function findHostInstance(e){const t=getPublicInstance(e.stateNode);if(t){return{instance:t,nativeTag:getNativeTag(e.stateNode),stateNode:e.stateNode}}const n=[];if(e.child)n.push(e.child);let r=0;while(n.length>0&&r<4e3){r++;const i=n.pop();if(!i)continue;const l=getPublicInstance(i.stateNode);if(l)return{instance:l,nativeTag:getNativeTag(i.stateNode),stateNode:i.stateNode};if(i.child)n.push(i.child);if(i.sibling)n.push(i.sibling)}return null}function findScrollAncestor(e){let t=e;let n=0;while(t&&n++<200){const r=t.stateNode;if(r&&typeof r.scrollTo==="function"){const i=typeof r.getNativeScrollRef==="function"&&r.getNativeScrollRef()||null;const l=typeof r.getInnerViewNode==="function"&&r.getInnerViewNode()||typeof r.getScrollableNode==="function"&&r.getScrollableNode()||r;return{instance:r,nativeRef:i,innerNode:l}}t=t.return}return null}async function scrollIntoView(e,t,n,r){try{if((0,_utils.isDOMElement)(n)){n.scrollIntoView({block:"nearest",inline:"nearest",behavior:"instant"});await new Promise(u=>setTimeout(u,16));return true}const i=findScrollAncestor(e);if(!i)return false;const l=t;let a=null;const o=u=>new Promise(s=>{let c=false;const d=m=>{if(c)return;c=true;s(m)};const g=setTimeout(()=>d(null),600);try{u(m=>{clearTimeout(g);d(m)})}catch{clearTimeout(g);d(null)}});if(i.nativeRef&&typeof l.measureLayout==="function"){a=await o(u=>l.measureLayout(i.nativeRef,(s,c)=>u(c),()=>u(null)))}if(a==null){const u=(0,_reactNative.findNodeHandle)(t);const s=typeof i.innerNode==="number"?i.innerNode:(0,_reactNative.findNodeHandle)(i.innerNode);if(u!=null&&s!=null){a=await o(c=>_reactNative.UIManager.measureLayout(u,s,()=>c(null),(d,g)=>c(g)))}}if(a==null)return false;i.instance.scrollTo({y:Math.max(0,a-r),animated:false});await new Promise(u=>setTimeout(u,120));return true}catch{return false}}function getComponentName(e){const t=e?.type;if(!t)return null;if(typeof t==="string")return t;return t.displayName||t.name||null}function getOwningComponentName(e){let t=e?._debugOwner||e?.return;let n=0;while(t&&n<30){n++;const r=getComponentName(t);if(r&&!INTERNAL_NAMES.has(r)&&typeof t.type!=="string"){return r}t=t.return}return null}function getProps(e){return(0,_utils.getDOMControlProps)(e?.stateNode,e?.memoizedProps??e?.pendingProps??null)}function flattenText(e,t=0){if(typeof e==="string")return e;if(typeof e==="number"&&Number.isFinite(e))return String(e);if(Array.isArray(e)&&t<4){const n=[];for(const r of e){const i=flattenText(r,t+1);if(i)n.push(i)}return n.length>0?n.join(""):void 0}return void 0}function normalizeVisibleText(e){return e.replace(/\s+/g," ").trim()}function getVisibleText(e){if(!e)return void 0;const t=n=>{const r=flattenText(n);if(r===void 0)return void 0;const i=normalizeVisibleText(r);return i?fullVisibleText?i:i.slice(0,80):void 0};return t(e.children)??t(e.title)??t(e.label)??t(e.placeholder)??void 0}function collectDescendantText(e,t){const n=[];const r=(l,a)=>{if(!l||a>t||n.length>=4)return;if(l!==e){const u=getProps(l);if(u&&(typeof u.onPress==="function"||typeof u.onLongPress==="function"))return}const o=getVisibleText(getProps(l));if(o&&!n.includes(o))n.push(o);if(l.child)r(l.child,a+1);if(l!==e&&l.sibling)r(l.sibling,a)};if(e.child)r(e.child,1);const i=n.join(" ").trim();return i?i.slice(0,80):void 0}function findPressHandler(e){let t=e;let n=0;let r=null;let i=null;while(t&&n<25&&!(r&&i)){const l=getProps(t);if(l){if(!r&&typeof l.onPress==="function")r=l.onPress;if(!i&&typeof l.onLongPress==="function")i=l.onLongPress}t=t.return;n++}if(r)return{handler:r,kind:"onPress",longPress:i??void 0};return i?{handler:i,kind:"onLongPress"}:null}function measureInstance(e){return new Promise(t=>{let n=false;const r=i=>{if(n)return;n=true;t(i)};setTimeout(()=>r(null),1e3);try{if(typeof e.measureInWindow==="function"){e.measureInWindow((i,l,a,o)=>{if(a>0&&o>0)r({x:i,y:l,width:a,height:o});else r(null)})}else if(typeof e.measure==="function"){e.measure((i,l,a,o,u,s)=>{if(a>0&&o>0&&u!=null&&s!=null){r({x:u,y:s,width:a,height:o})}else{r(null)}})}else{r(null)}}catch{r(null)}})}const SPINNER_HOSTS=new Set(["RCTActivityIndicatorView","AndroidProgressBar"]);function collectCandidates(){const e=getAllFiberRoots();const t=[];const n=new Map;const r=new Map;const i=makeChromeCheck();for(const l of e){traverseFiberTree(l.current,a=>{const o=getProps(a);if(!o)return;const u=typeof o.onPress==="function"||typeof o.onLongPress==="function";const s=typeof o.onValueChange==="function";const c=typeof o.onChangeText==="function";const d=o.testID||void 0;const g=o.accessibilityLabel||void 0;const m=o.accessibilityRole||o.role||void 0;let b=getVisibleText(o);const w=m==="button"||m==="link"||m==="menuitem"||m==="tab"||m==="switch"||m==="checkbox";const v=typeof a.type==="string"&&SPINNER_HOSTS.has(a.type)&&o.animating!==false;if(!u&&!s&&!c&&!d&&!g&&!b&&!w&&!v){return}let x=null;let P=null;let N=null;if(s){const D=o.value;const S=typeof D==="number"||typeof o.minimumValue==="number";P={handler:o.onValueChange,kind:S?"slider":"toggle",current:D,min:typeof o.minimumValue==="number"?o.minimumValue:void 0,max:typeof o.maximumValue==="number"?o.maximumValue:void 0}}else if(c){N={handler:o.onChangeText,current:typeof o.value==="string"?o.value:void 0}}else{x=findPressHandler(a)}const C=getComponentName(a);let f=C??"Unknown";if(!C||INTERNAL_NAMES.has(C)||typeof a.type==="string"){f=getOwningComponentName(a)??C??"Unknown"}const h=findHostInstance(a);if(!h&&!d)return;if(!b&&!g&&u){b=collectDescendantText(a,6)}const y=h?.instance??null;const T=h?.nativeTag??null;const p=(y?n.get(y):void 0)??(T!=null?r.get(T):void 0);if(p){if(!p.press&&x)p.press=x;else if(p.press&&x?.longPress&&!p.press.longPress){p.press.longPress=x.longPress}if(!p.valueControl&&P)p.valueControl=P;if(!p.textControl&&N)p.textControl=N;if(!p.testID&&d)p.testID=d;if(!p.label&&g)p.label=g;if(!p.text&&b)p.text=b;if(y&&!n.has(y))n.set(y,p);if(T!=null&&!r.has(T))r.set(T,p);return}const I={nativeTag:T,name:f,role:m??(v?"progressbar":void 0),testID:d,label:g,text:b,instance:y,stateNode:h?.stateNode??null,fiber:a,press:x,valueControl:P,textControl:N,rect:null,buoy:i(a)};t.push(I);if(y)n.set(y,I);if(T!=null)r.set(T,I)})}t.push(...collectDOMCandidates());return t}function collectDOMCandidates(){return(0,_domScreenElements.collectDOMElements)({fullText:fullVisibleText}).map(({element:e,props:t,text:n,buoy:r})=>{const i=typeof t.onValueChange==="function"?{handler:t.onValueChange,kind:typeof t.value==="number"?"slider":"toggle",current:t.value,min:t.minimumValue,max:t.maximumValue}:null;const l=!i&&typeof t.onChangeText==="function"?{handler:t.onChangeText,current:t.value}:null;const a=!i&&!l&&typeof t.onPress==="function"?{handler:t.onPress,kind:"onPress"}:null;return{nativeTag:(0,_utils.getDOMNodeHandle)(e),name:(0,_domScreenElements.domElementName)(e),role:t.accessibilityRole,testID:t.testID,label:t.accessibilityLabel,text:n,instance:(0,_utils.getDOMPublicInstance)(e),stateNode:e,fiber:null,buoy:r,press:a,valueControl:i,textControl:l,rect:null}})}function explicitlyTargets(e,t){if(t.nativeTag!=null)return e.nativeTag===t.nativeTag;if(t.testID&&e.testID)return e.testID.toLowerCase()===t.testID.toLowerCase();return false}function appCandidates(e){const t=collectCandidates();if(e.includeBuoy)return t;return t.filter(n=>!n.buoy||explicitlyTargets(n,e))}async function measureCandidates(e){await Promise.all(e.map(async t=>{if(t.instance)t.rect=await measureInstance(t.instance)}))}const LIST_WRAPPERS=/^(FlatList|SectionList|VirtualizedSectionList|VirtualizedList|Animated\(.*\)|AnimatedComponent.*)$/;async function collectLists(e,t){const n=[];const r=makeChromeCheck();for(const l of getAllFiberRoots()){traverseFiberTree(l.current,a=>{if(getComponentName(a)!=="VirtualizedList")return;const o=a.memoizedProps;if(!o||typeof o.getItemCount!=="function")return;if(!e&&r(a))return;let u;try{u=Number(o.getItemCount(o.data))}catch{return}if(!Number.isFinite(u)||u<=0)return;const s=[];const c=(m,b)=>{for(let w=m?.child;w;w=w.sibling){const v=getComponentName(w);if(v==="VirtualizedList")continue;if(v==="CellRenderer"){s.push(w);continue}if(b<40)c(w,b+1)}};c(a,0);let d=a;let g=getOwningComponentName(d);for(let m=0;m<6&&g&&LIST_WRAPPERS.test(g);m++){d=d._debugOwner||d.return;g=getOwningComponentName(d)}n.push({owner:g,items:u,cells:s})})}const i=[];for(const l of n){const a=await Promise.all(l.cells.map(async u=>{const s=findHostInstance(u);return s?measureInstance(s.instance):null}));const o=a.filter(t).length;if(o>0&&l.items>o)i.push({owner:l.owner,items:l.items,listed:o})}return i}async function describeScreen(e={}){const t=includeHiddenScreens;const n=fullVisibleText;includeHiddenScreens=!!e.includeHidden;fullVisibleText=!!e.fullText;try{return await describeScreenInner(e)}finally{includeHiddenScreens=t;fullVisibleText=n}}async function describeScreenInner(e){prunedHiddenScreens=0;const t=collectCandidates();const n=prunedHiddenScreens;const r=e.includeBuoy?t:t.filter(c=>!c.buoy);const i=t.length-r.length;await measureCandidates(r);const l=_reactNative.Dimensions.get("window");const a=Math.round(l.width)||1;const o=Math.round(l.height)||1;const u=[];for(const c of r){const d=c.rect;if(!d&&!c.testID)continue;let g;let m;if(d){const v=d.x+d.width/2;const x=d.y+d.height/2;if(x<-o*.1||x>o*1.1||v<-a*.1||v>a*1.1){continue}g={x:round2(v/a),y:round2(x/o)};m={x:round2(d.x/a),y:round2(d.y/o),width:round2(d.width/a),height:round2(d.height/o)}}const b=c.valueControl?c.valueControl.kind:c.textControl?"text":void 0;const w=c.valueControl?c.valueControl.current:c.textControl?.current;u.push({nativeTag:c.nativeTag,name:c.name,role:c.role,testID:c.testID,label:c.label,text:c.text,interactive:!!(c.press||c.valueControl||c.textControl),longPressable:c.press&&(c.press.kind==="onLongPress"||c.press.longPress)?true:void 0,control:b,value:w,tap:g,frame:m})}u.sort((c,d)=>{const g=c.tap?.y??2;const m=d.tap?.y??2;if(Math.abs(g-m)>.02)return g-m;return(c.tap?.x??2)-(d.tap?.x??2)});const s=await collectLists(!!e.includeBuoy,c=>{if(!c)return false;const d=c.x+c.width/2;return c.y<=o*1.1&&c.y+c.height>=-o*.1&&d>=-a*.1&&d<=a*1.1});return{screen:{width:a,height:o},count:u.length,elements:u,...i>0?{hiddenBuoy:i}:{},...n>0?{hiddenScreens:n}:{},...s.length?{lists:s}:{}}}function round2(e){return Math.round(e*100)/100}function fieldsOf(e){return{nativeTag:e.nativeTag,testID:e.testID,label:e.label,text:e.text,name:e.name}}function matchScore(e,t){return(0,_tapMatch.scoreTapMatch)(fieldsOf(e),t)}function tapPoint(e,t,n){if(!e||!t||!n)return void 0;return{x:(e.x+e.width/2)/t,y:(e.y+e.height/2)/n}}function makeSyntheticPressEvent(e){const t=e?e.x+e.width/2:0;const n=e?e.y+e.height/2:0;const r={locationX:e?e.width/2:0,locationY:e?e.height/2:0,pageX:t,pageY:n,timestamp:0,target:null,identifier:1,touches:[],changedTouches:[]};return{nativeEvent:r,persist:()=>{},preventDefault:()=>{},stopPropagation:()=>{},isDefaultPrevented:()=>false,isPropagationStopped:()=>false,target:null,currentTarget:null,type:"press",timeStamp:0}}async function tapElement(e){const t=withHiddenScreens(!!e.includeHidden,()=>appCandidates(e));if(t.length===0){return{tapped:false,reason:"Nothing on screen to tap: no React elements and no page elements were found."}}const n=t.map(f=>({c:f,score:matchScore(f,e)})).filter(f=>f.score>0).sort((f,h)=>h.score-f.score);const r=f=>!!(f.press||f.valueControl||f.textControl);if(n.length===0&&!e.includeHidden){const f=withHiddenScreens(true,()=>appCandidates(e)).map(h=>({c:h,score:matchScore(h,e)})).filter(h=>h.score>0);if(f.length>0){return{tapped:false,reason:"That element is only on a screen that isn't showing (another tab, or a screen under the current one). Navigate to it first, or pass includeHidden:true if you really mean the hidden one."}}}if(n.length===0){return{tapped:false,reason:"No element matched. Call describe_screen to see available elements (match by testID, text, or name).",candidates:t.filter(r).slice(0,12).map(f=>({nativeTag:f.nativeTag,name:f.name,testID:f.testID,text:f.text}))}}const i=_reactNative.Dimensions.get("window");const l=i.width||1;const a=i.height||1;const o=n.slice(0,15);await Promise.all(o.map(async f=>{if(f.c.instance&&!f.c.rect)f.c.rect=await measureInstance(f.c.instance)}));for(const f of o){f.score=(0,_tapMatch.scoreTapMatch)({...fieldsOf(f.c),tap:tapPoint(f.c.rect,l,a)},e)}o.sort((f,h)=>h.score-f.score);if(e.text!==void 0){for(const f of o){const h=!r(f.c)&&(0,_utils.isDOMElement)(f.c.stateNode)?(0,_domScreenElements.labeledField)(f.c.stateNode):null;const y=h?t.find(T=>T.stateNode===h&&T.textControl):void 0;if(y)f.c=y}}const u=o.find(f=>r(f.c))??n.find(f=>r(f.c))??o[0];const s=u.c;const c=(f,h)=>f.press&&f.press.handler===h.press?.handler||f.valueControl&&f.valueControl.handler===h.valueControl?.handler||f.textControl&&f.textControl.handler===h.textControl?.handler;const d=o.filter(f=>f!==u&&r(f.c)&&f.score===u.score).filter(f=>!c(f.c,s)).filter((f,h,y)=>y.findIndex(T=>c(T.c,f.c))===h).slice(0,3).map(f=>({nativeTag:f.c.nativeTag,name:f.c.name,testID:f.c.testID,text:f.c.text,tap:tapPoint(f.c.rect,l,a)}));const g=e.nativeTag==null&&!(e.testID&&!e.query);if(g&&d.length>0){const f=[s,...d.map(h=>o.find(y=>y.c.nativeTag===h.nativeTag)?.c).filter(Boolean)];return{tapped:false,reason:`"${e.query}" matches ${f.length} different controls equally well, so nothing was tapped. Tap one by its nativeTag.`,candidates:f.map(h=>({nativeTag:h.nativeTag,name:h.name,testID:h.testID,text:h.text}))}}const m=o[0];if(g&&m&&m!==u&&!r(m.c)&&m.score>=90&&u.score<m.score-40){return{tapped:false,reason:`The best match for "${e.query}" is "${m.c.text??m.c.label??m.c.name}", which has no JS press handler (it may be native, like a tab bar button). The closest pressable match, "${s.text??s.label??s.name}", is a much weaker match, so nothing was tapped. Use navigate, or tap a specific element by nativeTag.`,candidates:[{nativeTag:s.nativeTag,name:s.name,testID:s.testID,text:s.text}]}}if(!r(s)){return{tapped:false,reason:(0,_utils.isDOMElement)(s.stateNode)?`Matched "${s.name}"${s.text?` ("${s.text}")`:""}, but it is not a button or a field. This element can't be driven in JS.`:`Matched "${s.name}"${s.text?` ("${s.text}")`:""} but it has no onPress / onValueChange / onChangeText handler (e.g. a react-native-gesture-handler GestureDetector). This element can't be driven in JS.`,matched:{nativeTag:s.nativeTag,name:s.name,testID:s.testID,label:s.label,text:s.text,via:"onPress"}}}if(s.instance&&!s.rect)s.rect=await measureInstance(s.instance);let b=false;const w=s.rect==null||!(0,_tapMatch.isRectCenterOnScreen)(s.rect,l,a);if(w&&e.scrollIntoView!==false&&s.instance){b=await scrollIntoView(s.fiber,s.instance,s.stateNode,80);if(b)s.rect=await measureInstance(s.instance)}const v={nativeTag:s.nativeTag,name:s.name,testID:s.testID,label:s.label,text:s.text};ensureCommitCounter();const x=commitCount;const P=s.fiber===null&&(0,_utils.isDOMElement)(s.stateNode)?(0,_domScreenElements.watchDOMChanges)():null;const N=Date.now();const C=async f=>{await new Promise(h=>setTimeout(h,TAP_SETTLE_MS));return{tapped:true,scrolled:b,matched:f,effect:{commits:P?P():commitCount-x,observedMs:Date.now()-N},...d.length?{alsoMatched:d}:{}}};try{if(s.press){if(e.longPress){const h=s.press.kind==="onLongPress"?s.press.handler:s.press.longPress;if(!h){return{tapped:false,scrolled:b,reason:`Matched "${s.name}"${s.text?` ("${s.text}")`:""} but it has no onLongPress handler \u2014 call tap_element without longPress to tap it normally.`,matched:{...v,via:"onPress"}}}h(makeSyntheticPressEvent(s.rect));return await C({...v,via:"onLongPress"})}s.press.handler(makeSyntheticPressEvent(s.rect));return await C({...v,via:s.press.kind})}if(s.valueControl){const h=s.valueControl;let y;if(h.kind==="toggle"){y=typeof e.value==="boolean"?e.value:!h.current}else{const T=h.min??0;const p=h.max??1;if(typeof e.value==="number"){y=Math.min(p,Math.max(T,e.value))}else{y=h.current===p?T:p}}h.handler(y);return await C({...v,via:"onValueChange",value:y})}const f=e.text??(typeof e.value==="string"?e.value:"");s.textControl.handler(f);return await C({...v,via:"onChangeText",value:f})}catch(f){P?.();return{tapped:false,scrolled:b,reason:`handler threw: ${f instanceof Error?f.message:String(f)}`,matched:{...v,via:s.press?s.press.kind:s.valueControl?"onValueChange":"onChangeText"}}}}const WAIT_DEFAULT_MS=5e3;const WAIT_MAX_MS=3e4;const WAIT_MIN_POLL_MS=50;const WAIT_DEFAULT_POLL_MS=150;async function waitFor(e){const t=e.nativeTag!=null||!!String(e.testID??"").trim()||!!String(e.query??"").trim();if(!t){return{ok:false,waitedMs:0,polls:0,reason:"Nothing to wait for \u2014 pass nativeTag, testID or query."}}const n=Math.min(Math.max(e.timeoutMs??WAIT_DEFAULT_MS,0),WAIT_MAX_MS);const r=Math.max(e.pollMs??WAIT_DEFAULT_POLL_MS,WAIT_MIN_POLL_MS);const i=e.gone===true;const l=Date.now();let a=0;for(;;){a+=1;const{hit:o,closest:u}=await findOnScreen(e);if(i?!o:!!o){return{ok:true,waitedMs:Date.now()-l,polls:a,matched:o??void 0}}if(Date.now()-l>=n){const s=u?.length?u:void 0;const c=i?`Still on screen after ${n}ms.`:s?`Not on screen after ${n}ms \u2014 ${s.length===1?"one element":`${s.length} elements`} matched but ${s.some(d=>d.onScreen)?"not well enough":"none is visible"}. See \`closest\`; do not retry with different words, call describeScreen.`:`Not on screen after ${n}ms, and nothing matched those words at all. Call describeScreen to see what is there.`;return{ok:false,waitedMs:Date.now()-l,polls:a,reason:c,matched:o??void 0,closest:s}}await new Promise(s=>setTimeout(s,r))}}async function findOnScreen(e){const t=appCandidates(e).map(o=>({c:o,score:matchScore(o,e)})).filter(o=>o.score>0).sort((o,u)=>u.score-o.score).slice(0,8);if(t.length===0)return{hit:null,closest:void 0};await measureCandidates(t.map(o=>o.c));const n=_reactNative.Dimensions.get("window");const r=Math.round(n.width)||1;const i=Math.round(n.height)||1;let l=null;for(const{c:o}of t){if(!(0,_tapMatch.isRectCenterOnScreen)(o.rect,r,i))continue;l={nativeTag:o.nativeTag,name:o.name,testID:o.testID,label:o.label,text:o.text,interactive:!!(o.press||o.valueControl||o.textControl)};break}const a=t.slice(0,3).map(({c:o})=>({name:o.name,testID:o.testID,text:o.text,onScreen:(0,_tapMatch.isRectCenterOnScreen)(o.rect,r,i)}));return{hit:l,closest:a}}function isBuoyChrome(e){let t=e;let n=0;while(t&&n<400){if(getProps(t)?.__buoyDevToolsRoot)return true;t=t.return;n++}return false}function preferHandlerOwner(e,t){const n=getProps(e.fiber);if(typeof n?.onPress==="function"||typeof n?.onValueChange==="function"||typeof n?.onChangeText==="function"){return e}let r=null;let i=e.fiber?.return;let l=0;while(i&&l<25){if(typeof getProps(i)?.onPress==="function"){r=i;break}i=i.return;l++}if(!r)return e;let a=r;for(let o=0;o<6&&a;o++){const u=t.get(a);if(u)return u;a=a.return}return e}function resolveTouchTarget(e){const t=collectCandidates();if(t.length===0)return null;const n=new Map;for(const a of t)n.set(a.fiber,a);const r=t.find(a=>a.nativeTag===e);let i=null;if(!r){for(const a of getAllFiberRoots()){traverseFiberTree(a.current,o=>{if(i)return;if(o.stateNode&&getNativeTag(o.stateNode)===e){i=o}});if(i)break}}let l=r??null;if(!l&&i){let a=i;let o=0;let u=null;while(a&&o<25){const s=n.get(a);if(s){if(s.press||s.valueControl||s.textControl){l=s;break}if(!u)u=s}a=a.return;o++}if(!l)l=u}if(!l?.fiber&&!i){const a=l?.stateNode;const o=(0,_utils.isDOMElement)(a)?a:domElementForTag(e);if(o){for(let u=o;u;u=u.parentElement){const s=t.find(c=>c.stateNode===u&&(c.press||c.valueControl||c.textControl));if(s)return s.buoy?null:touchTargetOf(s)}return null}}if(!l)return null;l=preferHandlerOwner(l,n);if(!l.press&&!l.valueControl&&!l.textControl)return null;if(isBuoyChrome(l.fiber))return null;return touchTargetOf(l)}function domElementForTag(e){const t=global.document;if(!t?.querySelectorAll)return null;return Array.from(t.querySelectorAll("*")).find(n=>(0,_utils.getDOMNodeHandle)(n)===e)??null}function touchTargetOf(e){return{nativeTag:e.nativeTag,name:e.name,role:e.role,testID:e.testID,label:e.label,text:e.text,control:e.valueControl?e.valueControl.kind:e.textControl?"text":"press",value:e.valueControl?e.valueControl.current:e.textControl?.current}}function fiberForTag(e){let t=null;for(const n of getAllFiberRoots()){traverseFiberTree(n.current,r=>{if(!t&&r.stateNode&&getNativeTag(r.stateNode)===e)t=r});if(t)break}return t}function rootHostFibers(){const e=[];for(const t of getAllFiberRoots()){let n=t.current?.child;let r=0;while(n&&r++<200){if(n.tag===HostComponent&&n.stateNode){e.push(n);break}n=n.child}}return e}function fabricFiberAt(e,t){const n=global.nativeFabricUIManager;if(!n||typeof n.findNodeAtPoint!=="function")return null;const r=rootHostFibers().filter(i=>i.stateNode?.node);if(!r.length)return null;return new Promise(i=>{const l=setTimeout(()=>i(null),1e3);let a=r.length;let o=null;r.forEach((u,s)=>{try{n.findNodeAtPoint(u.stateNode.node,e,t,c=>{if(c&&(!o||s>=o.i))o={i:s,fiber:c};if(--a===0){clearTimeout(l);i(o?.fiber??null)}})}catch{if(--a===0){clearTimeout(l);i(o?.fiber??null)}}})})}function paperFiberAt(e,t){const n=_reactNative.UIManager?.findSubviewIn;if(typeof n!=="function")return null;const r=rootHostFibers()[0];const i=r?getNativeTag(r.stateNode)??(0,_reactNative.findNodeHandle)(r.stateNode):null;if(i==null)return null;return new Promise(l=>{const a=setTimeout(()=>l(null),1e3);try{n.call(_reactNative.UIManager,i,[e,t],o=>{clearTimeout(a);l(typeof o==="number"?fiberForTag(o):null)})}catch{clearTimeout(a);l(null)}})}function visibleHostFibers(){const e=[];const t=new Set;const n=i=>{const l=[];const a=(o,u)=>{for(let s=o;s&&l.length<5e3;s=s.sibling){if(t.has(s)||u>500)continue;if(isHiddenOffscreen(s)||isInactiveScreen(s))continue;if(s.tag===HostComponent&&s.stateNode)l.push(s);else if(s.child)a(s.child,u+1)}};if(i.child)a(i.child,0);return l};const r=(i,l)=>{if(t.has(i)||l>500)return;t.add(i);e.push(i);sortByZ(n(i)).forEach(a=>r(a,l+1))};for(const i of getAllFiberRoots())sortByZ(n(i.current)).forEach(l=>r(l,0));return e}function sortByZ(e){const t=e.map(n=>{const r=Number(flatStyle(getProps(n)?.style).zIndex);return Number.isFinite(r)?r:0});return e.map((n,r)=>({h:n,i:r})).sort((n,r)=>t[n.i]-t[r.i]||n.i-r.i).map(({h:n})=>n)}function flatStyle(e,t=0){if(!e||typeof e!=="object"||t>10)return{};if(Array.isArray(e))return Object.assign({},...e.map(n=>flatStyle(n,t+1)));return e}const SCROLL_HOSTS=new Set(["RCTScrollView","AndroidHorizontalScrollView","RCTScrollContentView"]);function clipsChildren(e){if(typeof e.type==="string"&&SCROLL_HOSTS.has(e.type)&&e.type!=="RCTScrollContentView")return true;const t=flatStyle(getProps(e)?.style).overflow;return t==="hidden"||t==="scroll"}function passesTouchesThrough(e){let t=getProps(e)?.pointerEvents??getProps(e)?.style?.pointerEvents;if(t==="none")return"all";let n=e.return;let r=0;while(n&&r++<200){const i=getProps(n)?.pointerEvents??getProps(n)?.style?.pointerEvents;if(i==="none")return"all";if(i==="box-only"&&n.tag===HostComponent)return"all";n=n.return}return t==="box-none"?"self":null}async function measuredFiberAt(e,t,n){const r=await Promise.all(n.map(o=>{const u=getPublicInstance(o.stateNode);return u?measureInstance(u):Promise.resolve(null)}));const i=new Map;n.forEach((o,u)=>i.set(o,r[u]));const l=o=>!!o&&e>=o.x&&e<=o.x+o.width&&t>=o.y&&t<=o.y+o.height;const a=o=>{for(let u=o.return,s=0;u&&s<300;u=u.return,s++){if(u.tag===HostComponent&&i.has(u)&&clipsChildren(u)&&!l(i.get(u)))return true}return false};for(let o=n.length-1;o>=0;o--){if(!l(r[o])||passesTouchesThrough(n[o])||a(n[o]))continue;return n[o]}return null}function domFiberAt(e,t){const n=global.document;const r=global.window;if(!n?.elementFromPoint||!r)return null;let i=n.elementFromPoint(e*r.innerWidth,t*r.innerHeight);while(i){const l=Object.keys(i).find(a=>a.startsWith("__reactFiber$"));if(l)return i[l];i=i.parentElement}return null}function domPageHit(e,t){const n=global.document;const r=global.window;if(!n?.elementFromPoint||!r)return null;const i=n.elementFromPoint(e*r.innerWidth,t*r.innerHeight);if(!i)return null;for(let c=i;c;c=c.parentElement){if(Object.keys(c).some(d=>d.startsWith("__reactFiber$")||d.startsWith("__reactContainer$")))return null}const l=!!i.closest("[data-buoy-root], [data-buoy-portal-host]");const a=collectDOMCandidates();const o=a.find(c=>c.stateNode===i);let u;for(let c=i;c&&!u;c=c.parentElement){u=a.find(d=>d.stateNode===c&&(d.press||d.valueControl||d.textControl))}const s=[];for(let c=i;c&&s.length<6;c=c.parentElement){const d=(0,_domScreenElements.domElementName)(c);if(d!==c.tagName.toLowerCase()&&s[s.length-1]!==d)s.push(d)}return{found:true,method:"dom",buoy:l,view:{name:(0,_domScreenElements.domElementName)(i),nativeTag:(0,_utils.getDOMNodeHandle)(i),testID:o?.testID,label:o?.label,text:o?.text},path:s,target:u&&!l?touchTargetOf(u):null}}async function hitTest(e){const t=Math.min(1,Math.max(0,Number(e?.x)));const n=Math.min(1,Math.max(0,Number(e?.y)));if(!Number.isFinite(t)||!Number.isFinite(n))return{found:false,method:"none",reason:"x and y must be numbers from 0 to 1."};const r=_reactNative.Dimensions.get("window");const i=t*r.width;const l=n*r.height;let a="none";let o=null;const u=domFiberAt(t,n);const s=u?null:domPageHit(t,n);if(s)return s;if(u){a="dom";o=u}else{const w=fabricFiberAt(i,l);if(w){a="fabric";o=await w}else{const x=paperFiberAt(i,l);if(x){a="paper";o=await x}}const v=visibleHostFibers();if(!o||!new Set(v).has(o)){o=await measuredFiberAt(i,l,v);a="measured"}}if(!o)return{found:false,method:a};const c=getProps(o)??{};const d=getNativeTag(o.stateNode);const g=[];let m=o;let b=0;while(m&&b++<80&&g.length<6){const w=getComponentName(m);if(w&&typeof m.type!=="string"&&!INTERNAL_NAMES.has(w)&&g[g.length-1]!==w)g.push(w);m=m.return}return{found:true,method:a,buoy:isBuoyChrome(o),view:{name:getComponentName(o)??"Unknown",nativeTag:d,testID:c.testID||void 0,label:c.accessibilityLabel||c["aria-label"]||void 0,text:getVisibleText(c)},path:g,target:d!=null?resolveTouchTarget(d):null}}async function readMaps(){const e=[];for(const i of getAllFiberRoots()){traverseFiberTree(i.current,l=>{const a=l.stateNode;if(l.tag===1&&a&&typeof a.getCamera==="function"&&!isBuoyChrome(l))e.push(l)})}const t=_reactNative.Dimensions.get("window");const n=i=>Promise.race([i,new Promise(l=>setTimeout(()=>l(null),1e3))]);const r=await Promise.all(e.slice(0,5).map(async i=>{try{const l=await n(Promise.resolve(i.stateNode.getCamera()));if(!l)return null;const a=findHostInstance(i);const o=a?await measureInstance(a.instance):null;const u=getProps(i)??{};return{name:getComponentName(i)??"Map",testID:typeof u.testID==="string"?u.testID:void 0,frame:o&&t.width&&t.height?{x:round2(o.x/t.width),y:round2(o.y/t.height),width:round2(o.width/t.width),height:round2(o.height/t.height)}:void 0,camera:{heading:typeof l.heading==="number"?l.heading:void 0,pitch:typeof l.pitch==="number"?l.pitch:void 0,altitude:typeof l.altitude==="number"?l.altitude:void 0,zoom:typeof l.zoom==="number"?l.zoom:void 0,center:l.center}}}catch{return null}}));return{maps:r.filter(i=>!!i)}}
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.describeScreen=describeScreen;exports.hitTest=hitTest;exports.readMaps=readMaps;exports.resolveTouchTarget=resolveTouchTarget;exports.tapElement=tapElement;exports.waitFor=waitFor;var _utils=require("@buoy-gg/shared-ui/utils");var _reactNative=require("react-native");var _tapMatch=require("./tapMatch");var _domScreenElements=require("./domScreenElements");const HostComponent=5;const OffscreenComponent=22;const INTERNAL_NAMES=new Set(["View","RCTView","ScrollView","RCTScrollView","RCTScrollContentView","SafeAreaView","RCTSafeAreaView","AndroidHorizontalScrollContentView","KeyboardAvoidingView","Pressable","PlatformPressable","TouchableOpacity","TouchableHighlight","TouchableWithoutFeedback","TouchableNativeFeedback","AnimatedComponent","Wrapper"]);function getReactDevToolsHook(){if(typeof global==="undefined")return null;return global.__REACT_DEVTOOLS_GLOBAL_HOOK__??null}let commitCount=0;let commitCounterInstalled=false;function ensureCommitCounter(){if(commitCounterInstalled)return;const e=getReactDevToolsHook();if(!e)return;const t=e.onCommitFiberRoot;e.onCommitFiberRoot=function(...n){commitCount++;return typeof t==="function"?t.apply(e,n):void 0};commitCounterInstalled=true}const TAP_SETTLE_MS=250;function makeChromeCheck(){const e=new Map;return t=>{const n=[];let r=t;let i=0;let s=false;while(r&&i<400){const a=e.get(r);if(a!==void 0){s=a;break}if(getProps(r)?.__buoyDevToolsRoot){s=true;e.set(r,true);break}n.push(r);r=r.return;i++}for(const a of n)e.set(a,s);return s}}function getAllFiberRoots(){const e=getReactDevToolsHook();if(!e)return[];const t=[];try{if(e.renderers&&typeof e.renderers.forEach==="function"){e.renderers.forEach((n,r)=>{try{const i=e.getFiberRoots?.(r);if(i)i.forEach(s=>t.push(s))}catch{}})}if(t.length===0&&e.getFiberRoots){const n=e.getFiberRoots(1);if(n)n.forEach(r=>t.push(r))}}catch{}return t}function isHiddenOffscreen(e){return e.tag===OffscreenComponent&&e.memoizedState!==null}let includeHiddenScreens=false;let prunedHiddenScreens=0;let fullVisibleText=false;function withHiddenScreens(e,t){const n=includeHiddenScreens;includeHiddenScreens=e;try{return t()}finally{includeHiddenScreens=n}}function isNotShowingScreen(e){const t=e.memoizedProps;if(!t)return false;if(t["aria-hidden"]===true&&(t.activityState!==void 0||"shouldFreeze"in t))return true;if(t.isFocused===false&&(t.routeKey!==void 0||"freezeContents"in t))return true;return false}function isInactiveScreen(e){const t=e.memoizedProps?.activityState;if(t===0||t===1)return true;if(e.memoizedProps?.isPageFocused===false)return true;if(!includeHiddenScreens&&isNotShowingScreen(e)){prunedHiddenScreens++;return true}return false}function traverseFiberTree(e,t,n=0,r=new Set){if(!e||r.has(e)||n>500)return;r.add(e);if(isHiddenOffscreen(e)||isInactiveScreen(e)){if(e.sibling)traverseFiberTree(e.sibling,t,n,r);return}t(e);if(e.child)traverseFiberTree(e.child,t,n+1,r);if(e.sibling)traverseFiberTree(e.sibling,t,n,r)}function getPublicInstance(e){const t=(0,_utils.getDOMPublicInstance)(e);if(t)return t;if(!e)return null;const n=e;if(n.canonical?.publicInstance)return n.canonical.publicInstance;if(n.canonical&&typeof n.canonical.measure==="function"){return n.canonical}if(typeof n.measure==="function"||typeof n.measureInWindow==="function"){return n}return null}function getNativeTag(e){const t=(0,_utils.getDOMNodeHandle)(e);if(t!==null)return t;if(e==null)return null;const n=e;if(typeof n.__nativeTag==="number")return n.__nativeTag;if(typeof n._nativeTag==="number")return n._nativeTag;if(typeof n.nativeTag==="number")return n.nativeTag;if(n.canonical){if(typeof n.canonical.__nativeTag==="number")return n.canonical.__nativeTag;if(typeof n.canonical._nativeTag==="number")return n.canonical._nativeTag;if(typeof n.canonical.nativeTag==="number")return n.canonical.nativeTag}return null}function findHostInstance(e){const t=getPublicInstance(e.stateNode);if(t){return{instance:t,nativeTag:getNativeTag(e.stateNode),stateNode:e.stateNode}}const n=[];if(e.child)n.push(e.child);let r=0;while(n.length>0&&r<4e3){r++;const i=n.pop();if(!i)continue;const s=getPublicInstance(i.stateNode);if(s)return{instance:s,nativeTag:getNativeTag(i.stateNode),stateNode:i.stateNode};if(i.child)n.push(i.child);if(i.sibling)n.push(i.sibling)}return null}function findScrollAncestor(e){let t=e;let n=0;while(t&&n++<200){const r=t.stateNode;if(r&&typeof r.scrollTo==="function"){const i=typeof r.getNativeScrollRef==="function"&&r.getNativeScrollRef()||null;const s=typeof r.getInnerViewNode==="function"&&r.getInnerViewNode()||typeof r.getScrollableNode==="function"&&r.getScrollableNode()||r;return{instance:r,nativeRef:i,innerNode:s}}t=t.return}return null}async function scrollIntoView(e,t,n,r){try{if((0,_utils.isDOMElement)(n)){n.scrollIntoView({block:"nearest",inline:"nearest",behavior:"instant"});await new Promise(u=>setTimeout(u,16));return true}const i=findScrollAncestor(e);if(!i)return false;const s=t;let a=null;const o=u=>new Promise(l=>{let c=false;const d=m=>{if(c)return;c=true;l(m)};const g=setTimeout(()=>d(null),600);try{u(m=>{clearTimeout(g);d(m)})}catch{clearTimeout(g);d(null)}});if(i.nativeRef&&typeof s.measureLayout==="function"){a=await o(u=>s.measureLayout(i.nativeRef,(l,c)=>u(c),()=>u(null)))}if(a==null){const u=(0,_reactNative.findNodeHandle)(t);const l=typeof i.innerNode==="number"?i.innerNode:(0,_reactNative.findNodeHandle)(i.innerNode);if(u!=null&&l!=null){a=await o(c=>_reactNative.UIManager.measureLayout(u,l,()=>c(null),(d,g)=>c(g)))}}if(a==null)return false;i.instance.scrollTo({y:Math.max(0,a-r),animated:false});await new Promise(u=>setTimeout(u,120));return true}catch{return false}}function getComponentName(e){const t=e?.type;if(!t)return null;if(typeof t==="string")return t;return t.displayName||t.name||null}function getOwningComponentName(e){let t=e?._debugOwner||e?.return;let n=0;while(t&&n<30){n++;const r=getComponentName(t);if(r&&!INTERNAL_NAMES.has(r)&&typeof t.type!=="string"){return r}t=t.return}return null}function getProps(e){return(0,_utils.getDOMControlProps)(e?.stateNode,e?.memoizedProps??e?.pendingProps??null)}function flattenText(e,t=0){if(typeof e==="string")return e;if(typeof e==="number"&&Number.isFinite(e))return String(e);if(Array.isArray(e)&&t<4){const n=[];for(const r of e){const i=flattenText(r,t+1);if(i)n.push(i)}return n.length>0?n.join(""):void 0}return void 0}function normalizeVisibleText(e){return e.replace(/\s+/g," ").trim()}function getVisibleText(e){if(!e)return void 0;const t=n=>{const r=flattenText(n);if(r===void 0)return void 0;const i=normalizeVisibleText(r);return i?fullVisibleText?i:i.slice(0,80):void 0};return t(e.children)??t(e.title)??t(e.label)??t(e.placeholder)??void 0}function collectDescendantText(e,t){const n=[];const r=(s,a)=>{if(!s||a>t||n.length>=4)return;if(s!==e){const u=getProps(s);if(u&&(typeof u.onPress==="function"||typeof u.onLongPress==="function"))return}const o=getVisibleText(getProps(s));if(o&&!n.includes(o))n.push(o);if(s.child)r(s.child,a+1);if(s!==e&&s.sibling)r(s.sibling,a)};if(e.child)r(e.child,1);const i=n.join(" ").trim();return i?i.slice(0,80):void 0}function findPressHandler(e){let t=e;let n=0;let r=null;let i=null;while(t&&n<25&&!(r&&i)){const s=getProps(t);if(s){if(!r&&typeof s.onPress==="function")r=s.onPress;if(!i&&typeof s.onLongPress==="function")i=s.onLongPress}t=t.return;n++}if(r)return{handler:r,kind:"onPress",longPress:i??void 0};return i?{handler:i,kind:"onLongPress"}:null}function measureInstance(e){return new Promise(t=>{let n=false;const r=i=>{if(n)return;n=true;t(i)};setTimeout(()=>r(null),1e3);try{if(typeof e.measureInWindow==="function"){e.measureInWindow((i,s,a,o)=>{if(a>0&&o>0)r({x:i,y:s,width:a,height:o});else r(null)})}else if(typeof e.measure==="function"){e.measure((i,s,a,o,u,l)=>{if(a>0&&o>0&&u!=null&&l!=null){r({x:u,y:l,width:a,height:o})}else{r(null)}})}else{r(null)}}catch{r(null)}})}const SPINNER_HOSTS=new Set(["RCTActivityIndicatorView","AndroidProgressBar"]);function collectCandidates(){const e=getAllFiberRoots();const t=[];const n=new Map;const r=new Map;const i=makeChromeCheck();for(const s of e){traverseFiberTree(s.current,a=>{const o=getProps(a);if(!o)return;const u=typeof o.onPress==="function"||typeof o.onLongPress==="function";const l=typeof o.onValueChange==="function";const c=typeof o.onChangeText==="function";const d=o.testID||void 0;const g=o.accessibilityLabel||void 0;const m=o.accessibilityRole||o.role||void 0;let w=getVisibleText(o);const y=m==="button"||m==="link"||m==="menuitem"||m==="tab"||m==="switch"||m==="checkbox";const b=typeof a.type==="string"&&SPINNER_HOSTS.has(a.type)&&o.animating!==false;if(!u&&!l&&!c&&!d&&!g&&!w&&!y&&!b){return}let x=null;let N=null;let I=null;if(l){const D=o.value;const S=typeof D==="number"||typeof o.minimumValue==="number";N={handler:o.onValueChange,kind:S?"slider":"toggle",current:D,min:typeof o.minimumValue==="number"?o.minimumValue:void 0,max:typeof o.maximumValue==="number"?o.maximumValue:void 0}}else if(c){I={handler:o.onChangeText,current:typeof o.value==="string"?o.value:void 0}}else{x=findPressHandler(a)}const C=getComponentName(a);let f=C??"Unknown";if(!C||INTERNAL_NAMES.has(C)||typeof a.type==="string"){f=getOwningComponentName(a)??C??"Unknown"}const h=findHostInstance(a);if(!h&&!d)return;if(!w&&!g&&u){w=collectDescendantText(a,6)}const p=h?.instance??null;const T=h?.nativeTag??null;const v=(p?n.get(p):void 0)??(T!=null?r.get(T):void 0);if(v){if(x)v.press=x;if(!v.valueControl&&N)v.valueControl=N;if(!v.textControl&&I)v.textControl=I;if(!v.testID&&d)v.testID=d;if(!v.label&&g)v.label=g;if(!v.text&&w)v.text=w;if(p&&!n.has(p))n.set(p,v);if(T!=null&&!r.has(T))r.set(T,v);return}const P={nativeTag:T,name:f,role:m??(b?"progressbar":void 0),testID:d,label:g,text:w,instance:p,stateNode:h?.stateNode??null,fiber:a,press:x,valueControl:N,textControl:I,rect:null,buoy:i(a)};t.push(P);if(p)n.set(p,P);if(T!=null)r.set(T,P)})}t.push(...collectDOMCandidates());return t}function collectDOMCandidates(){return(0,_domScreenElements.collectDOMElements)({fullText:fullVisibleText}).map(({element:e,props:t,text:n,buoy:r})=>{const i=typeof t.onValueChange==="function"?{handler:t.onValueChange,kind:typeof t.value==="number"?"slider":"toggle",current:t.value,min:t.minimumValue,max:t.maximumValue}:null;const s=!i&&typeof t.onChangeText==="function"?{handler:t.onChangeText,current:t.value}:null;const a=!i&&!s&&typeof t.onPress==="function"?{handler:t.onPress,kind:"onPress"}:null;return{nativeTag:(0,_utils.getDOMNodeHandle)(e),name:(0,_domScreenElements.domElementName)(e),role:t.accessibilityRole,testID:t.testID,label:t.accessibilityLabel,text:n,instance:(0,_utils.getDOMPublicInstance)(e),stateNode:e,fiber:null,buoy:r,press:a,valueControl:i,textControl:s,rect:null}})}function explicitlyTargets(e,t){if(t.nativeTag!=null)return e.nativeTag===t.nativeTag;if(t.testID&&e.testID)return e.testID.toLowerCase()===t.testID.toLowerCase();return false}function appCandidates(e){const t=collectCandidates();if(e.includeBuoy)return t;return t.filter(n=>!n.buoy||explicitlyTargets(n,e))}async function measureCandidates(e){await Promise.all(e.map(async t=>{if(t.instance)t.rect=await measureInstance(t.instance)}))}const LIST_WRAPPERS=/^(FlatList|SectionList|VirtualizedSectionList|VirtualizedList|Animated\(.*\)|AnimatedComponent.*)$/;async function collectLists(e,t){const n=[];const r=makeChromeCheck();for(const s of getAllFiberRoots()){traverseFiberTree(s.current,a=>{if(getComponentName(a)!=="VirtualizedList")return;const o=a.memoizedProps;if(!o||typeof o.getItemCount!=="function")return;if(!e&&r(a))return;let u;try{u=Number(o.getItemCount(o.data))}catch{return}if(!Number.isFinite(u)||u<=0)return;const l=[];const c=(m,w)=>{for(let y=m?.child;y;y=y.sibling){const b=getComponentName(y);if(b==="VirtualizedList")continue;if(b==="CellRenderer"){l.push(y);continue}if(w<40)c(y,w+1)}};c(a,0);let d=a;let g=getOwningComponentName(d);for(let m=0;m<6&&g&&LIST_WRAPPERS.test(g);m++){d=d._debugOwner||d.return;g=getOwningComponentName(d)}n.push({owner:g,items:u,cells:l})})}const i=[];for(const s of n){const a=await Promise.all(s.cells.map(async u=>{const l=findHostInstance(u);return l?measureInstance(l.instance):null}));const o=a.filter(t).length;if(o>0&&s.items>o)i.push({owner:s.owner,items:s.items,listed:o})}return i}async function describeScreen(e={}){const t=includeHiddenScreens;const n=fullVisibleText;includeHiddenScreens=!!e.includeHidden;fullVisibleText=!!e.fullText;try{return await describeScreenInner(e)}finally{includeHiddenScreens=t;fullVisibleText=n}}async function describeScreenInner(e){prunedHiddenScreens=0;const t=collectCandidates();const n=prunedHiddenScreens;const r=e.includeBuoy?t:t.filter(c=>!c.buoy);const i=t.length-r.length;await measureCandidates(r);const s=_reactNative.Dimensions.get("window");const a=Math.round(s.width)||1;const o=Math.round(s.height)||1;const u=[];for(const c of r){const d=c.rect;if(!d&&!c.testID)continue;let g;let m;if(d){const b=d.x+d.width/2;const x=d.y+d.height/2;if(x<-o*.1||x>o*1.1||b<-a*.1||b>a*1.1){continue}g={x:round2(b/a),y:round2(x/o)};m={x:round2(d.x/a),y:round2(d.y/o),width:round2(d.width/a),height:round2(d.height/o)}}const w=c.valueControl?c.valueControl.kind:c.textControl?"text":void 0;const y=c.valueControl?c.valueControl.current:c.textControl?.current;u.push({nativeTag:c.nativeTag,name:c.name,role:c.role,testID:c.testID,label:c.label,text:c.text,interactive:!!(c.press||c.valueControl||c.textControl),longPressable:c.press&&(c.press.kind==="onLongPress"||c.press.longPress)?true:void 0,control:w,value:y,tap:g,frame:m,...c.buoy?{buoy:true}:{}})}u.sort((c,d)=>{const g=c.tap?.y??2;const m=d.tap?.y??2;if(Math.abs(g-m)>.02)return g-m;return(c.tap?.x??2)-(d.tap?.x??2)});const l=await collectLists(!!e.includeBuoy,c=>{if(!c)return false;const d=c.x+c.width/2;return c.y<=o*1.1&&c.y+c.height>=-o*.1&&d>=-a*.1&&d<=a*1.1});return{screen:{width:a,height:o},count:u.length,elements:u,...i>0?{hiddenBuoy:i}:{},...n>0?{hiddenScreens:n}:{},...l.length?{lists:l}:{}}}function round2(e){return Math.round(e*100)/100}function fieldsOf(e){return{nativeTag:e.nativeTag,testID:e.testID,label:e.label,text:e.text,name:e.name}}function matchScore(e,t){return(0,_tapMatch.scoreTapMatch)(fieldsOf(e),t)}function tapPoint(e,t,n){if(!e||!t||!n)return void 0;return{x:(e.x+e.width/2)/t,y:(e.y+e.height/2)/n}}function makeSyntheticPressEvent(e){const t=e?e.x+e.width/2:0;const n=e?e.y+e.height/2:0;const r={locationX:e?e.width/2:0,locationY:e?e.height/2:0,pageX:t,pageY:n,timestamp:0,target:null,identifier:1,touches:[],changedTouches:[]};return{nativeEvent:r,persist:()=>{},preventDefault:()=>{},stopPropagation:()=>{},isDefaultPrevented:()=>false,isPropagationStopped:()=>false,target:null,currentTarget:null,type:"press",timeStamp:0}}async function tapElement(e){const t=withHiddenScreens(!!e.includeHidden,()=>appCandidates(e));if(t.length===0){return{tapped:false,reason:"Nothing on screen to tap: no React elements and no page elements were found."}}const n=t.map(f=>({c:f,score:matchScore(f,e)})).filter(f=>f.score>0).sort((f,h)=>h.score-f.score);const r=f=>!!(f.press||f.valueControl||f.textControl);if(n.length===0&&!e.includeHidden){const f=withHiddenScreens(true,()=>appCandidates(e)).map(h=>({c:h,score:matchScore(h,e)})).filter(h=>h.score>0);if(f.length>0){return{tapped:false,reason:"That element is only on a screen that isn't showing (another tab, or a screen under the current one). Navigate to it first, or pass includeHidden:true if you really mean the hidden one."}}}if(n.length===0){return{tapped:false,reason:"No element matched. Call describe_screen to see available elements (match by testID, text, or name).",candidates:t.filter(r).slice(0,12).map(f=>({nativeTag:f.nativeTag,name:f.name,testID:f.testID,text:f.text}))}}const i=_reactNative.Dimensions.get("window");const s=i.width||1;const a=i.height||1;const o=n.slice(0,15);await Promise.all(o.map(async f=>{if(f.c.instance&&!f.c.rect)f.c.rect=await measureInstance(f.c.instance)}));for(const f of o){f.score=(0,_tapMatch.scoreTapMatch)({...fieldsOf(f.c),tap:tapPoint(f.c.rect,s,a)},e)}o.sort((f,h)=>h.score-f.score);if(e.text!==void 0){for(const f of o){const h=!r(f.c)&&(0,_utils.isDOMElement)(f.c.stateNode)?(0,_domScreenElements.labeledField)(f.c.stateNode):null;const p=h?t.find(T=>T.stateNode===h&&T.textControl):void 0;if(p)f.c=p}}const u=o.find(f=>r(f.c))??n.find(f=>r(f.c))??o[0];const l=u.c;const c=(f,h)=>f.press&&f.press.handler===h.press?.handler||f.valueControl&&f.valueControl.handler===h.valueControl?.handler||f.textControl&&f.textControl.handler===h.textControl?.handler;const d=o.filter(f=>f!==u&&r(f.c)&&f.score===u.score).filter(f=>!c(f.c,l)).filter((f,h,p)=>p.findIndex(T=>c(T.c,f.c))===h).slice(0,3).map(f=>({nativeTag:f.c.nativeTag,name:f.c.name,testID:f.c.testID,text:f.c.text,tap:tapPoint(f.c.rect,s,a)}));const g=e.nativeTag==null&&!(e.testID&&!e.query);if(g&&d.length>0){const f=[l,...d.map(h=>o.find(p=>p.c.nativeTag===h.nativeTag)?.c).filter(Boolean)];return{tapped:false,reason:`"${e.query}" matches ${f.length} different controls equally well, so nothing was tapped. Tap one by its nativeTag.`,candidates:f.map(h=>({nativeTag:h.nativeTag,name:h.name,testID:h.testID,text:h.text}))}}const m=o[0];if(g&&m&&m!==u&&!r(m.c)&&m.score>=90&&u.score<m.score-40){return{tapped:false,reason:`The best match for "${e.query}" is "${m.c.text??m.c.label??m.c.name}", which has no JS press handler (it may be native, like a tab bar button). The closest pressable match, "${l.text??l.label??l.name}", is a much weaker match, so nothing was tapped. Use navigate, or tap a specific element by nativeTag.`,candidates:[{nativeTag:l.nativeTag,name:l.name,testID:l.testID,text:l.text}]}}if(!r(l)){return{tapped:false,reason:(0,_utils.isDOMElement)(l.stateNode)?`Matched "${l.name}"${l.text?` ("${l.text}")`:""}, but it is not a button or a field. This element can't be driven in JS.`:`Matched "${l.name}"${l.text?` ("${l.text}")`:""} but it has no onPress / onValueChange / onChangeText handler (e.g. a react-native-gesture-handler GestureDetector). This element can't be driven in JS.`,matched:{nativeTag:l.nativeTag,name:l.name,testID:l.testID,label:l.label,text:l.text,via:"onPress"}}}if(l.instance&&!l.rect)l.rect=await measureInstance(l.instance);let w=false;const y=l.rect==null||!(0,_tapMatch.isRectCenterOnScreen)(l.rect,s,a);if(y&&e.scrollIntoView!==false&&l.instance){w=await scrollIntoView(l.fiber,l.instance,l.stateNode,80);if(w)l.rect=await measureInstance(l.instance)}const b={nativeTag:l.nativeTag,name:l.name,testID:l.testID,label:l.label,text:l.text};ensureCommitCounter();const x=commitCount;const N=l.fiber===null&&(0,_utils.isDOMElement)(l.stateNode)?(0,_domScreenElements.watchDOMChanges)():null;const I=Date.now();const C=async f=>{await new Promise(h=>setTimeout(h,TAP_SETTLE_MS));return{tapped:true,scrolled:w,matched:f,effect:{commits:N?N():commitCount-x,observedMs:Date.now()-I},...d.length?{alsoMatched:d}:{}}};try{if(l.press){if(e.longPress){const h=l.press.kind==="onLongPress"?l.press.handler:l.press.longPress;if(!h){return{tapped:false,scrolled:w,reason:`Matched "${l.name}"${l.text?` ("${l.text}")`:""} but it has no onLongPress handler \u2014 call tap_element without longPress to tap it normally.`,matched:{...b,via:"onPress"}}}h(makeSyntheticPressEvent(l.rect));return await C({...b,via:"onLongPress"})}l.press.handler(makeSyntheticPressEvent(l.rect));return await C({...b,via:l.press.kind})}if(l.valueControl){const h=l.valueControl;let p;if(h.kind==="toggle"){p=typeof e.value==="boolean"?e.value:!h.current}else{const T=h.min??0;const v=h.max??1;if(typeof e.value==="number"){p=Math.min(v,Math.max(T,e.value))}else{p=h.current===v?T:v}}h.handler(p);return await C({...b,via:"onValueChange",value:p})}const f=e.text??(typeof e.value==="string"?e.value:"");l.textControl.handler(f);return await C({...b,via:"onChangeText",value:f})}catch(f){N?.();return{tapped:false,scrolled:w,reason:`handler threw: ${f instanceof Error?f.message:String(f)}`,matched:{...b,via:l.press?l.press.kind:l.valueControl?"onValueChange":"onChangeText"}}}}const WAIT_DEFAULT_MS=5e3;const WAIT_MAX_MS=3e4;const WAIT_MIN_POLL_MS=50;const WAIT_DEFAULT_POLL_MS=150;async function waitFor(e){const t=e.nativeTag!=null||!!String(e.testID??"").trim()||!!String(e.query??"").trim();if(!t){return{ok:false,waitedMs:0,polls:0,reason:"Nothing to wait for \u2014 pass nativeTag, testID or query."}}const n=Math.min(Math.max(e.timeoutMs??WAIT_DEFAULT_MS,0),WAIT_MAX_MS);const r=Math.max(e.pollMs??WAIT_DEFAULT_POLL_MS,WAIT_MIN_POLL_MS);const i=e.gone===true;const s=Date.now();let a=0;for(;;){a+=1;const{hit:o,closest:u}=await findOnScreen(e);if(i?!o:!!o){return{ok:true,waitedMs:Date.now()-s,polls:a,matched:o??void 0}}if(Date.now()-s>=n){const l=u?.length?u:void 0;const c=i?`Still on screen after ${n}ms.`:l?`Not on screen after ${n}ms \u2014 ${l.length===1?"one element":`${l.length} elements`} matched but ${l.some(d=>d.onScreen)?"not well enough":"none is visible"}. See \`closest\`; do not retry with different words, call describeScreen.`:`Not on screen after ${n}ms, and nothing matched those words at all. Call describeScreen to see what is there.`;return{ok:false,waitedMs:Date.now()-s,polls:a,reason:c,matched:o??void 0,closest:l}}await new Promise(l=>setTimeout(l,r))}}async function findOnScreen(e){const t=appCandidates(e).map(o=>({c:o,score:matchScore(o,e)})).filter(o=>o.score>0).sort((o,u)=>u.score-o.score).slice(0,8);if(t.length===0)return{hit:null,closest:void 0};await measureCandidates(t.map(o=>o.c));const n=_reactNative.Dimensions.get("window");const r=Math.round(n.width)||1;const i=Math.round(n.height)||1;let s=null;for(const{c:o}of t){if(!(0,_tapMatch.isRectCenterOnScreen)(o.rect,r,i))continue;s={nativeTag:o.nativeTag,name:o.name,testID:o.testID,label:o.label,text:o.text,interactive:!!(o.press||o.valueControl||o.textControl)};break}const a=t.slice(0,3).map(({c:o})=>({name:o.name,testID:o.testID,text:o.text,onScreen:(0,_tapMatch.isRectCenterOnScreen)(o.rect,r,i)}));return{hit:s,closest:a}}function isBuoyChrome(e){let t=e;let n=0;while(t&&n<400){if(getProps(t)?.__buoyDevToolsRoot)return true;t=t.return;n++}return false}function preferHandlerOwner(e,t){const n=getProps(e.fiber);if(typeof n?.onPress==="function"||typeof n?.onValueChange==="function"||typeof n?.onChangeText==="function"){return e}let r=null;let i=e.fiber?.return;let s=0;while(i&&s<25){if(typeof getProps(i)?.onPress==="function"){r=i;break}i=i.return;s++}if(!r)return e;let a=r;for(let o=0;o<6&&a;o++){const u=t.get(a);if(u)return u;a=a.return}return e}function resolveTouchTarget(e){const t=collectCandidates();if(t.length===0)return null;const n=new Map;for(const a of t)n.set(a.fiber,a);const r=t.find(a=>a.nativeTag===e);let i=null;if(!r){for(const a of getAllFiberRoots()){traverseFiberTree(a.current,o=>{if(i)return;if(o.stateNode&&getNativeTag(o.stateNode)===e){i=o}});if(i)break}}let s=r??null;if(!s&&i){let a=i;let o=0;let u=null;while(a&&o<25){const l=n.get(a);if(l){if(l.press||l.valueControl||l.textControl){s=l;break}if(!u)u=l}a=a.return;o++}if(!s)s=u}if(!s?.fiber&&!i){const a=s?.stateNode;const o=(0,_utils.isDOMElement)(a)?a:domElementForTag(e);if(o){for(let u=o;u;u=u.parentElement){const l=t.find(c=>c.stateNode===u&&(c.press||c.valueControl||c.textControl));if(l)return l.buoy?null:touchTargetOf(l)}return null}}if(!s)return null;s=preferHandlerOwner(s,n);if(!s.press&&!s.valueControl&&!s.textControl)return null;if(isBuoyChrome(s.fiber))return null;return touchTargetOf(s)}function domElementForTag(e){const t=global.document;if(!t?.querySelectorAll)return null;return Array.from(t.querySelectorAll("*")).find(n=>(0,_utils.getDOMNodeHandle)(n)===e)??null}function touchTargetOf(e){return{nativeTag:e.nativeTag,name:e.name,role:e.role,testID:e.testID,label:e.label,text:e.text,control:e.valueControl?e.valueControl.kind:e.textControl?"text":"press",value:e.valueControl?e.valueControl.current:e.textControl?.current}}function fiberForTag(e){let t=null;for(const n of getAllFiberRoots()){traverseFiberTree(n.current,r=>{if(!t&&r.stateNode&&getNativeTag(r.stateNode)===e)t=r});if(t)break}return t}function rootHostFibers(){const e=[];for(const t of getAllFiberRoots()){let n=t.current?.child;let r=0;while(n&&r++<200){if(n.tag===HostComponent&&n.stateNode){e.push(n);break}n=n.child}}return e}function fabricFiberAt(e,t){const n=global.nativeFabricUIManager;if(!n||typeof n.findNodeAtPoint!=="function")return null;const r=rootHostFibers().filter(i=>i.stateNode?.node);if(!r.length)return null;return new Promise(i=>{const s=setTimeout(()=>i(null),1e3);let a=r.length;let o=null;r.forEach((u,l)=>{try{n.findNodeAtPoint(u.stateNode.node,e,t,c=>{if(c&&(!o||l>=o.i))o={i:l,fiber:c};if(--a===0){clearTimeout(s);i(o?.fiber??null)}})}catch{if(--a===0){clearTimeout(s);i(o?.fiber??null)}}})})}function paperFiberAt(e,t){const n=_reactNative.UIManager?.findSubviewIn;if(typeof n!=="function")return null;const r=rootHostFibers()[0];const i=r?getNativeTag(r.stateNode)??(0,_reactNative.findNodeHandle)(r.stateNode):null;if(i==null)return null;return new Promise(s=>{const a=setTimeout(()=>s(null),1e3);try{n.call(_reactNative.UIManager,i,[e,t],o=>{clearTimeout(a);s(typeof o==="number"?fiberForTag(o):null)})}catch{clearTimeout(a);s(null)}})}function visibleHostFibers(){const e=[];const t=new Set;const n=i=>{const s=[];const a=(o,u)=>{for(let l=o;l&&s.length<5e3;l=l.sibling){if(t.has(l)||u>500)continue;if(isHiddenOffscreen(l)||isInactiveScreen(l))continue;if(l.tag===HostComponent&&l.stateNode)s.push(l);else if(l.child)a(l.child,u+1)}};if(i.child)a(i.child,0);return s};const r=(i,s)=>{if(t.has(i)||s>500)return;t.add(i);e.push(i);sortByZ(n(i)).forEach(a=>r(a,s+1))};for(const i of getAllFiberRoots())sortByZ(n(i.current)).forEach(s=>r(s,0));return e}function sortByZ(e){const t=e.map(n=>{const r=Number(flatStyle(getProps(n)?.style).zIndex);return Number.isFinite(r)?r:0});return e.map((n,r)=>({h:n,i:r})).sort((n,r)=>t[n.i]-t[r.i]||n.i-r.i).map(({h:n})=>n)}function flatStyle(e,t=0){if(!e||typeof e!=="object"||t>10)return{};if(Array.isArray(e))return Object.assign({},...e.map(n=>flatStyle(n,t+1)));return e}const SCROLL_HOSTS=new Set(["RCTScrollView","AndroidHorizontalScrollView","RCTScrollContentView"]);function clipsChildren(e){if(typeof e.type==="string"&&SCROLL_HOSTS.has(e.type)&&e.type!=="RCTScrollContentView")return true;const t=flatStyle(getProps(e)?.style).overflow;return t==="hidden"||t==="scroll"}function passesTouchesThrough(e){let t=getProps(e)?.pointerEvents??getProps(e)?.style?.pointerEvents;if(t==="none")return"all";let n=e.return;let r=0;while(n&&r++<200){const i=getProps(n)?.pointerEvents??getProps(n)?.style?.pointerEvents;if(i==="none")return"all";if(i==="box-only"&&n.tag===HostComponent)return"all";n=n.return}return t==="box-none"?"self":null}async function measuredFiberAt(e,t,n){const r=await Promise.all(n.map(o=>{const u=getPublicInstance(o.stateNode);return u?measureInstance(u):Promise.resolve(null)}));const i=new Map;n.forEach((o,u)=>i.set(o,r[u]));const s=o=>!!o&&e>=o.x&&e<=o.x+o.width&&t>=o.y&&t<=o.y+o.height;const a=o=>{for(let u=o.return,l=0;u&&l<300;u=u.return,l++){if(u.tag===HostComponent&&i.has(u)&&clipsChildren(u)&&!s(i.get(u)))return true}return false};for(let o=n.length-1;o>=0;o--){if(!s(r[o])||passesTouchesThrough(n[o])||a(n[o]))continue;return n[o]}return null}function domFiberAt(e,t){const n=global.document;const r=global.window;if(!n?.elementFromPoint||!r)return null;let i=n.elementFromPoint(e*r.innerWidth,t*r.innerHeight);while(i){const s=Object.keys(i).find(a=>a.startsWith("__reactFiber$"));if(s)return i[s];i=i.parentElement}return null}function domPageHit(e,t){const n=global.document;const r=global.window;if(!n?.elementFromPoint||!r)return null;const i=n.elementFromPoint(e*r.innerWidth,t*r.innerHeight);if(!i)return null;for(let c=i;c;c=c.parentElement){if(Object.keys(c).some(d=>d.startsWith("__reactFiber$")||d.startsWith("__reactContainer$")))return null}const s=!!i.closest("[data-buoy-root], [data-buoy-portal-host]");const a=collectDOMCandidates();const o=a.find(c=>c.stateNode===i);let u;for(let c=i;c&&!u;c=c.parentElement){u=a.find(d=>d.stateNode===c&&(d.press||d.valueControl||d.textControl))}const l=[];for(let c=i;c&&l.length<6;c=c.parentElement){const d=(0,_domScreenElements.domElementName)(c);if(d!==c.tagName.toLowerCase()&&l[l.length-1]!==d)l.push(d)}return{found:true,method:"dom",buoy:s,view:{name:(0,_domScreenElements.domElementName)(i),nativeTag:(0,_utils.getDOMNodeHandle)(i),testID:o?.testID,label:o?.label,text:o?.text},path:l,target:u&&!s?touchTargetOf(u):null}}async function hitTest(e){const t=Math.min(1,Math.max(0,Number(e?.x)));const n=Math.min(1,Math.max(0,Number(e?.y)));if(!Number.isFinite(t)||!Number.isFinite(n))return{found:false,method:"none",reason:"x and y must be numbers from 0 to 1."};const r=_reactNative.Dimensions.get("window");const i=t*r.width;const s=n*r.height;let a="none";let o=null;const u=domFiberAt(t,n);const l=u?null:domPageHit(t,n);if(l)return l;if(u){a="dom";o=u}else{const y=fabricFiberAt(i,s);if(y){a="fabric";o=await y}else{const x=paperFiberAt(i,s);if(x){a="paper";o=await x}}const b=visibleHostFibers();if(!o||!new Set(b).has(o)){o=await measuredFiberAt(i,s,b);a="measured"}}if(!o)return{found:false,method:a};const c=getProps(o)??{};const d=getNativeTag(o.stateNode);const g=[];let m=o;let w=0;while(m&&w++<80&&g.length<6){const y=getComponentName(m);if(y&&typeof m.type!=="string"&&!INTERNAL_NAMES.has(y)&&g[g.length-1]!==y)g.push(y);m=m.return}return{found:true,method:a,buoy:isBuoyChrome(o),view:{name:getComponentName(o)??"Unknown",nativeTag:d,testID:c.testID||void 0,label:c.accessibilityLabel||c["aria-label"]||void 0,text:getVisibleText(c)},path:g,target:d!=null?resolveTouchTarget(d):null}}async function readMaps(){const e=[];for(const i of getAllFiberRoots()){traverseFiberTree(i.current,s=>{const a=s.stateNode;if(s.tag===1&&a&&typeof a.getCamera==="function"&&!isBuoyChrome(s))e.push(s)})}const t=_reactNative.Dimensions.get("window");const n=i=>Promise.race([i,new Promise(s=>setTimeout(()=>s(null),1e3))]);const r=await Promise.all(e.slice(0,5).map(async i=>{try{const s=await n(Promise.resolve(i.stateNode.getCamera()));if(!s)return null;const a=findHostInstance(i);const o=a?await measureInstance(a.instance):null;const u=getProps(i)??{};return{name:getComponentName(i)??"Map",testID:typeof u.testID==="string"?u.testID:void 0,frame:o&&t.width&&t.height?{x:round2(o.x/t.width),y:round2(o.y/t.height),width:round2(o.width/t.width),height:round2(o.height/t.height)}:void 0,camera:{heading:typeof s.heading==="number"?s.heading:void 0,pitch:typeof s.pitch==="number"?s.pitch:void 0,altitude:typeof s.altitude==="number"?s.altitude:void 0,zoom:typeof s.zoom==="number"?s.zoom:void 0,center:s.center}}}catch{return null}}));return{maps:r.filter(i=>!!i)}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import fe,{useState as f,useCallback as I}from"react";import{View as a,Text as i,TouchableOpacity as g,TextInput as A,StyleSheet as ie,ScrollView as O,Modal as ce,Pressable as ae,Switch as w}from"react-native";import{Eye as q,Filter as N,Plus as K,X as L,Box as X,Settings as de,Hash as se,SectionHeader as p,night as o,monoFont as v}from"@buoy-gg/shared-ui";import{IdentifierBadge as G,IDENTIFIER_CONFIG as ue}from"./IdentifierBadge";import{detectedItemTestID as he,patternChipTestID as pe,settingTestID as R}from"../utils/testIDs";import{jsx as t,jsxs as l,Fragment as M}from"react/jsx-runtime";const P=d=>ue[d];const ge=["any","viewType","testID","nativeID","component","accessibilityLabel"];function Y({mode:d,onSelect:u,onCancel:s}){return l(a,{nativeID:"__rn_buoy__type-picker",testID:`buoy-highlight-${d}-types`,style:e.typePicker,children:[t(a,{style:e.typePickerRow,children:ge.map(h=>{const r=P(h);const b=r.icon;return l(g,{testID:`buoy-highlight-${d}-type-${h.toLowerCase()}`,accessibilityRole:"button",accessibilityLabel:r.label,style:[e.typeOption,{backgroundColor:r.color+"15",borderColor:r.color+"40"}],onPress:()=>u(h),children:[t(b,{size:14,color:r.color}),t(i,{style:[e.typeOptionText,{color:r.color}],children:r.label})]},h)})}),t(g,{testID:`buoy-highlight-${d}-types-cancel`,accessibilityRole:"button",accessibilityLabel:"Cancel",onPress:s,style:e.typePickerCancel,children:t(L,{size:16,color:o.color.textTertiary})})]})}function Z({mode:d,type:u,onSubmit:s,onCancel:h}){const[r,b]=f("");const z=P(u);const C=()=>{if(r.trim()){s(r.trim())}};return l(a,{nativeID:"__rn_buoy__pattern-input",testID:`buoy-highlight-${d}-input-row`,style:e.patternInputContainer,children:[t(G,{type:u,value:"",badgeOnly:true,compact:true}),t(A,{testID:`buoy-highlight-${d}-input`,value:r,onChangeText:b,onSubmitEditing:C,placeholder:"Enter pattern...",placeholderTextColor:o.color.placeholder,style:e.patternInput,autoFocus:true,returnKeyType:"done",autoCorrect:false,autoCapitalize:"none"}),r.trim()&&t(g,{testID:`buoy-highlight-${d}-submit`,accessibilityRole:"button",accessibilityLabel:"Add pattern",onPress:C,style:[e.addPatternButton,{backgroundColor:z.color+"20"}],children:t(i,{style:[e.addPatternButtonText,{color:z.color}],children:"Add"})}),t(g,{testID:`buoy-highlight-${d}-input-cancel`,accessibilityRole:"button",accessibilityLabel:"Cancel",onPress:h,style:e.cancelButton,children:t(L,{size:16,color:o.color.textTertiary})})]})}function J({mode:d,pattern:u,onRemove:s}){const h=P(u.type);return l(g,{testID:pe(d,u.type,u.value),accessibilityRole:"button",accessibilityLabel:`${h.label} ${u.value}, tap to remove`,style:[e.patternChip,{borderColor:h.color+"40"}],onPress:s,activeOpacity:.7,children:[t(a,{style:[e.patternChipBadge,{backgroundColor:h.color+"20"}],children:t(i,{style:[e.patternChipBadgeText,{color:h.color}],children:h.shortLabel})}),t(i,{style:e.patternChipValue,numberOfLines:1,children:u.value}),t(L,{size:12,color:o.color.textTertiary,style:e.patternChipX})]})}const ye={label:"All",shortLabel:"All",color:o.color.textSecondary,icon:X};function D({filterType:d,count:u,isSelected:s,onPress:h}){const r=d==="all"?ye:P(d);const b=`buoy-highlight-detected-cat-${String(d).toLowerCase()}`;return l(g,{testID:b,accessibilityRole:"button",accessibilityLabel:`${r.label}, ${u}`,style:[e.categoryBadge,{backgroundColor:r.color+"15",borderColor:s?r.color:r.color+"40",borderWidth:s?2:1}],onPress:h,children:[t(r.icon,{size:12,color:r.color}),t(i,{style:[e.categoryBadgeText,{color:r.color}],children:r.label}),t(a,{style:[e.categoryBadgeCountBubble,{backgroundColor:r.color+"25"}],children:t(i,{testID:`${b}-count`,style:[e.categoryBadgeCount,{color:r.color}],children:u})})]})}const be=[{value:20,label:"20"},{value:50,label:"50"},{value:100,label:"100"},{value:150,label:"150"},{value:250,label:"250"},{value:500,label:"500"}];const j=[{value:"off",label:"Off",description:"No debug logging"},{value:"minimal",label:"Minimal",description:"Only hook value changes"},{value:"verbose",label:"Verbose",description:"Component + cause + changes"},{value:"all",label:"All",description:"Full fiber dump"}];export function HighlightFilterView({filters:d,onFilterChange:u,settings:s,onSettingsChange:h,availableProps:r,activeTab:b}){const[z,C]=f(false);const[Q,k]=f(false);const[B,H]=f(null);const[W,E]=f(null);const[m,x]=f("all");const[y,T]=f(null);const ee=n=>{switch(n){case"viewType":return r.viewTypes.map(c=>({value:c,type:"viewType"}));case"testID":return r.testIDs.map(c=>({value:c,type:"testID"}));case"nativeID":return r.nativeIDs.map(c=>({value:c,type:"nativeID"}));case"component":return r.componentNames.map(c=>({value:c,type:"component"}));case"accessibilityLabel":return r.accessibilityLabels.map(c=>({value:c,type:"accessibilityLabel"}));case"all":default:return[...r.viewTypes.map(c=>({value:c,type:"viewType"})),...r.testIDs.map(c=>({value:c,type:"testID"})),...r.nativeIDs.map(c=>({value:c,type:"nativeID"})),...r.componentNames.map(c=>({value:c,type:"component"})),...r.accessibilityLabels.map(c=>({value:c,type:"accessibilityLabel"}))]}};const F=ee(m);const U=r.viewTypes.length+r.testIDs.length+r.nativeIDs.length+r.componentNames.length+r.accessibilityLabels.length;const V=I((n,c)=>{const S=[...d.includePatterns,{type:n,value:c}];u({includePatterns:S});H(null)},[d.includePatterns,u]);const _=I((n,c)=>{const S=[...d.excludePatterns,{type:n,value:c}];u({excludePatterns:S});E(null)},[d.excludePatterns,u]);const te=I(n=>{const c=d.includePatterns.filter((S,$)=>$!==n);u({includePatterns:c})},[d.includePatterns,u]);const oe=I(n=>{const c=d.excludePatterns.filter((S,$)=>$!==n);u({excludePatterns:c})},[d.excludePatterns,u]);const ne=I((n,c)=>{T({type:n,value:c})},[]);const le=I(()=>{if(y){V(y.type,y.value);T(null)}},[y,V]);const re=I(()=>{if(y){_(y.type,y.value);T(null)}},[y,_]);return t(a,{style:e.container,children:t(O,{keyboardShouldPersistTaps:"handled",nativeID:"__rn_buoy__filter-view",testID:"buoy-highlight-filter-scroll",style:e.scrollView,contentContainerStyle:e.scrollContent,showsVerticalScrollIndicator:false,children:b==="filters"?l(M,{children:[l(a,{style:e.section,children:[l(p,{children:[t(p.Icon,{icon:q,color:o.color.accent,size:12}),t(p.Title,{children:"INCLUDE ONLY"}),d.includePatterns.length>0&&t(p.Badge,{testID:"buoy-highlight-include-count",count:d.includePatterns.length,color:o.color.accent})]}),t(i,{style:e.sectionDescription,children:"Show only components matching these patterns. If any are set, components must match at least one."}),d.includePatterns.length>0&&t(a,{style:e.patternChips,children:d.includePatterns.map((n,c)=>t(J,{mode:"include",pattern:n,onRemove:()=>te(c)},`${n.type}-${n.value}-${c}`))}),t(a,{style:e.addPatternRow,children:z?t(Y,{mode:"include",onSelect:n=>{C(false);H(n)},onCancel:()=>C(false)}):B?t(Z,{mode:"include",type:B,onSubmit:n=>V(B,n),onCancel:()=>H(null)}):l(g,{testID:"buoy-highlight-include-add",accessibilityRole:"button",accessibilityLabel:"Add include pattern",style:[e.addButton,{borderColor:o.color.accentBorderStrong}],onPress:()=>C(true),children:[t(K,{size:14,color:o.color.accent}),t(i,{style:[e.addButtonText,{color:o.color.accent}],children:"Add include pattern"})]})})]}),l(a,{style:e.section,children:[l(p,{children:[t(p.Icon,{icon:N,color:o.color.accent,size:12}),t(p.Title,{children:"EXCLUDE"}),d.excludePatterns.length>0&&t(p.Badge,{testID:"buoy-highlight-exclude-count",count:d.excludePatterns.length,color:o.color.accent})]}),t(i,{style:e.sectionDescription,children:"Hide components matching these patterns from the list."}),d.excludePatterns.length>0&&t(a,{style:e.patternChips,children:d.excludePatterns.map((n,c)=>t(J,{mode:"exclude",pattern:n,onRemove:()=>oe(c)},`${n.type}-${n.value}-${c}`))}),t(a,{style:e.addPatternRow,children:Q?t(Y,{mode:"exclude",onSelect:n=>{k(false);E(n)},onCancel:()=>k(false)}):W?t(Z,{mode:"exclude",type:W,onSubmit:n=>_(W,n),onCancel:()=>E(null)}):l(g,{testID:"buoy-highlight-exclude-add",accessibilityRole:"button",accessibilityLabel:"Add exclude pattern",style:[e.addButton,{borderColor:o.color.accentBorderStrong}],onPress:()=>k(true),children:[t(K,{size:14,color:o.color.accent}),t(i,{style:[e.addButtonText,{color:o.color.accent}],children:"Add exclude pattern"})]})})]}),l(a,{style:e.section,children:[l(p,{children:[t(p.Icon,{icon:se,color:o.color.warning,size:12}),t(p.Title,{children:"RENDER COUNT RANGE"}),(d.minRenderCount!==void 0||d.maxRenderCount!==void 0)&&t(p.Badge,{count:1,color:o.color.warning})]}),t(i,{style:e.sectionDescription,children:"Show only components with render count in a specific range."}),l(a,{nativeID:"__rn_buoy__render-count-range",testID:"buoy-highlight-range",style:e.renderCountRangeContainer,children:[l(a,{style:e.renderCountInputRow,children:[l(a,{style:e.renderCountInputGroup,children:[t(i,{style:e.renderCountLabel,children:"Min"}),t(A,{value:d.minRenderCount!==void 0?String(d.minRenderCount):"",onChangeText:n=>{const c=parseInt(n,10);if(n===""||n===void 0){u({minRenderCount:void 0})}else if(!isNaN(c)&&c>=0){u({minRenderCount:c})}},testID:"buoy-highlight-range-min",placeholder:"0",placeholderTextColor:o.color.placeholder,style:e.renderCountInput,keyboardType:"number-pad",returnKeyType:"done"})]}),t(i,{style:e.renderCountSeparator,children:"to"}),l(a,{style:e.renderCountInputGroup,children:[t(i,{style:e.renderCountLabel,children:"Max"}),t(A,{value:d.maxRenderCount!==void 0?String(d.maxRenderCount):"",onChangeText:n=>{const c=parseInt(n,10);if(n===""||n===void 0){u({maxRenderCount:void 0})}else if(!isNaN(c)&&c>=0){u({maxRenderCount:c})}},testID:"buoy-highlight-range-max",placeholder:"\u221E",placeholderTextColor:o.color.placeholder,style:e.renderCountInput,keyboardType:"number-pad",returnKeyType:"done"})]})]}),(d.minRenderCount!==void 0||d.maxRenderCount!==void 0)&&l(g,{testID:"buoy-highlight-range-clear",accessibilityRole:"button",accessibilityLabel:"Clear range",style:e.clearRangeButton,onPress:()=>u({minRenderCount:void 0,maxRenderCount:void 0}),children:[t(L,{size:12,color:o.color.warning}),t(i,{style:e.clearRangeButtonText,children:"Clear Range"})]})]})]}),l(a,{style:e.section,children:[l(p,{children:[t(p.Icon,{icon:X,color:o.color.textSecondary,size:12}),t(p.Title,{children:"DETECTED ITEMS"})]}),t(i,{style:e.sectionDescription,children:"Tap an item to quickly add it as an exclude pattern."}),l(O,{horizontal:true,showsHorizontalScrollIndicator:false,style:e.categoryBadgeScroll,contentContainerStyle:e.categoryBadgeScrollContent,children:[U>0&&t(D,{filterType:"all",count:U,isSelected:m==="all",onPress:()=>x("all")}),r.viewTypes.length>0&&t(D,{filterType:"viewType",count:r.viewTypes.length,isSelected:m==="viewType",onPress:()=>x("viewType")}),r.testIDs.length>0&&t(D,{filterType:"testID",count:r.testIDs.length,isSelected:m==="testID",onPress:()=>x("testID")}),r.nativeIDs.length>0&&t(D,{filterType:"nativeID",count:r.nativeIDs.length,isSelected:m==="nativeID",onPress:()=>x("nativeID")}),r.componentNames.length>0&&t(D,{filterType:"component",count:r.componentNames.length,isSelected:m==="component",onPress:()=>x("component")}),r.accessibilityLabels.length>0&&t(D,{filterType:"accessibilityLabel",count:r.accessibilityLabels.length,isSelected:m==="accessibilityLabel",onPress:()=>x("accessibilityLabel")})]}),t(a,{nativeID:"__rn_buoy__detected-items",testID:"buoy-highlight-detected",style:e.detectedItemsContainer,children:F.length>0?t(O,{keyboardShouldPersistTaps:"handled",testID:"buoy-highlight-detected-scroll",style:e.detectedItemsScroll,contentContainerStyle:e.detectedItems,nestedScrollEnabled:true,showsVerticalScrollIndicator:true,children:F.map(n=>{const c=P(n.type);return t(g,{testID:he(n.type,n.value),accessibilityRole:"button",accessibilityLabel:`${c.label} ${n.value}`,style:[e.detectedItem,{borderColor:c.color+"40"}],onPress:()=>ne(n.type,n.value),children:m==="all"?t(G,{type:n.type,value:n.value,compact:true,shortLabel:true}):t(i,{style:e.detectedItemText,numberOfLines:1,children:n.value})},`${n.type}-${n.value}`)})}):t(i,{testID:"buoy-highlight-detected-empty",style:e.emptyText,children:"No items detected yet. Start tracking to see components here."})})]}),t(ce,{visible:y!==null,transparent:true,animationType:"fade",onRequestClose:()=>T(null),children:t(ae,{accessible:false,testID:"buoy-highlight-detected-popup-backdrop",style:e.modalOverlay,onPress:()=>T(null),children:t(a,{accessible:false,testID:"buoy-highlight-detected-popup",style:e.actionPopup,children:y&&l(M,{children:[t(a,{style:e.actionPopupHeader,children:t(G,{type:y.type,value:y.value,compact:true,shortLabel:true})}),l(a,{style:e.actionPopupButtons,children:[l(g,{testID:"buoy-highlight-detected-popup-include",accessibilityRole:"button",accessibilityLabel:"Include only",style:[e.actionPopupButton,e.actionPopupInclude],onPress:le,children:[t(q,{size:16,color:o.color.accent}),t(i,{style:[e.actionPopupButtonText,{color:o.color.accent}],children:"Include Only"})]}),l(g,{testID:"buoy-highlight-detected-popup-exclude",accessibilityRole:"button",accessibilityLabel:"Exclude",style:[e.actionPopupButton,e.actionPopupExclude],onPress:re,children:[t(N,{size:16,color:o.color.accent}),t(i,{style:[e.actionPopupButtonText,{color:o.color.accent}],children:"Exclude"})]})]}),t(g,{testID:"buoy-highlight-detected-popup-cancel",accessibilityRole:"button",accessibilityLabel:"Cancel",style:e.actionPopupCancel,onPress:()=>T(null),children:t(i,{style:e.actionPopupCancelText,children:"Cancel"})})]})})})}),l(a,{style:e.section,children:[l(p,{children:[t(p.Icon,{icon:N,color:o.color.textTertiary,size:12}),t(p.Title,{children:"HOW FILTERS WORK"})]}),t(a,{style:e.howItWorks,children:l(i,{style:e.howItWorksText,children:[t(i,{style:e.howItWorksBold,children:"Any:"})," Matches against all fields","\n",t(i,{style:e.howItWorksBold,children:"ViewType:"})," Native component class (RCTView, RCTText)","\n",t(i,{style:e.howItWorksBold,children:"testID:"})," Component testID prop","\n",t(i,{style:e.howItWorksBold,children:"Component:"})," React component name from fiber"]})})]})]}):t(M,{children:l(a,{style:e.section,children:[l(p,{children:[t(p.Icon,{icon:de,color:o.color.textTertiary,size:12}),t(p.Title,{children:"SETTINGS"})]}),l(a,{style:e.settingsSection,children:[l(a,{style:e.settingItem,children:[l(a,{style:e.settingHeader,children:[t(i,{style:e.settingLabel,children:"Show Render Count"}),t(w,{testID:R("showRenderCount"),value:s.showRenderCount,onValueChange:n=>{h({showRenderCount:n});if(!n&&s.trackRenderCauses){h({trackRenderCauses:false})}},trackColor:{false:o.color.surfaceElevated,true:o.color.accent+"80"},thumbColor:s.showRenderCount?o.color.accent:o.color.knob})]}),t(i,{style:e.settingDescription,children:"Display render count badge on highlights. Disabling improves performance by skipping count tracking."})]}),l(a,{style:[e.settingItem,e.settingItemSpaced],children:[l(a,{style:e.settingHeader,children:[t(i,{style:[e.settingLabel,!s.showRenderCount&&e.settingLabelDisabled],children:"Track Render Causes"}),t(w,{testID:R("trackRenderCauses"),value:s.trackRenderCauses,onValueChange:n=>h({trackRenderCauses:n}),trackColor:{false:o.color.surfaceElevated,true:o.color.warning+"80"},thumbColor:s.trackRenderCauses?o.color.warning:o.color.knob,disabled:!s.showRenderCount})]}),l(i,{style:e.settingDescription,children:["Detect WHY components render (props, hooks, parent re-render).",!s.showRenderCount&&l(i,{style:e.settingWarning,children:["\n",'Requires "Show Render Count" to be enabled.']})]})]}),l(a,{style:[e.settingItem,e.settingItemSpaced],children:[l(a,{style:e.settingHeader,children:[t(i,{style:[e.settingLabel,!s.trackRenderCauses&&e.settingLabelDisabled],children:"Enable Render History"}),t(w,{testID:R("enableRenderHistory"),value:s.enableRenderHistory,onValueChange:n=>h({enableRenderHistory:n}),trackColor:{false:o.color.surfaceElevated,true:o.color.accent+"80"},thumbColor:s.enableRenderHistory?o.color.accent:o.color.knob,disabled:!s.trackRenderCauses})]}),l(i,{style:e.settingDescription,children:["Store render events for each component to view in the History tab.",!s.trackRenderCauses&&l(i,{style:e.settingWarning,children:["\n",'Requires "Track Render Causes" to be enabled.']})]})]}),l(a,{style:[e.settingItem,e.settingItemSpaced],children:[l(a,{style:e.settingHeader,children:[t(i,{style:e.settingLabel,children:"Debug Log Level"}),t(a,{style:e.settingValue,children:t(i,{testID:"buoy-highlight-setting-debugLogLevel-value",style:[e.settingValueText,s.debugLogLevel!=="off"&&{color:o.color.warning}],children:j.find(n=>n.value===s.debugLogLevel)?.label||"Off"})})]}),t(i,{style:e.settingDescription,children:"Control console logging verbosity for render cause detection."}),t(a,{style:e.batchSizePresets,children:j.map(n=>t(g,{style:[e.batchSizePreset,s.debugLogLevel===n.value&&e.batchSizePresetActive,n.value!=="off"&&s.debugLogLevel===n.value&&{backgroundColor:o.color.warningSoft,borderColor:o.color.warning}],onPress:()=>h({debugLogLevel:n.value}),testID:`buoy-highlight-preset-log-${n.value}`,accessibilityRole:"button",accessibilityLabel:`Debug log level ${n.label}`,children:t(i,{style:[e.batchSizePresetText,s.debugLogLevel===n.value&&e.batchSizePresetTextActive,n.value!=="off"&&s.debugLogLevel===n.value&&{color:o.color.warning}],children:n.label})},n.value))}),l(i,{style:e.settingDescriptionMuted,children:[j.find(n=>n.value===s.debugLogLevel)?.description,s.debugLogLevel!=="off"&&" \u2022 Check Metro console for logs"]})]}),l(a,{style:[e.settingItem,e.settingItemSpaced],children:[l(a,{style:e.settingHeader,children:[t(i,{style:e.settingLabel,children:"Batch Size"}),t(a,{style:e.settingValue,children:t(i,{testID:"buoy-highlight-setting-batchSize-value",style:e.settingValueText,children:s.batchSize})})]}),t(i,{style:e.settingDescription,children:"Maximum components to highlight per render update. Higher values capture more re-renders but may impact performance on complex screens."}),t(a,{style:e.batchSizePresets,children:be.map(n=>t(g,{style:[e.batchSizePreset,s.batchSize===n.value&&e.batchSizePresetActive],onPress:()=>h({batchSize:n.value}),testID:`buoy-highlight-preset-batch-${n.value}`,accessibilityRole:"button",accessibilityLabel:`Batch size ${n.label}`,children:t(i,{style:[e.batchSizePresetText,s.batchSize===n.value&&e.batchSizePresetTextActive],children:n.label})},n.value))})]}),l(a,{style:[e.settingItem,e.settingItemSpaced],children:[l(a,{style:e.settingHeader,children:[t(i,{style:e.settingLabel,children:"Show host views"}),t(w,{testID:R("showHostViews"),value:!!s.showHostViews,onValueChange:n=>h({showHostViews:n}),trackColor:{false:o.color.surfaceElevated,true:o.color.accent+"80"},thumbColor:s.showHostViews?o.color.accent:o.color.knob})]}),t(i,{style:e.settingDescription,children:"Include anonymous View / RCTView / Text hosts. Off by default so the list is named composites (what actually re-rendered)."})]}),l(a,{style:[e.settingItem,e.settingItemSpaced],children:[l(a,{style:e.settingHeader,children:[t(i,{style:e.settingLabel,children:"Highlight Dev Tools"}),t(w,{testID:R("excludeDevTools"),value:!s.excludeDevTools,onValueChange:n=>h({excludeDevTools:!n}),trackColor:{false:o.color.surfaceElevated,true:o.color.accent+"80"},thumbColor:!s.excludeDevTools?o.color.accent:o.color.knob})]}),l(i,{style:e.settingDescription,children:["Show re-render highlights on Buoy dev tools (floating menu, modals, etc.). Useful for optimizing the dev tools themselves.",!s.excludeDevTools&&l(i,{style:e.settingWarning,children:["\n","The highlight overlay is always excluded to prevent infinite loops."]})]})]})]})]})})})})}const e=ie.create({container:{flex:1,backgroundColor:"transparent"},scrollView:{flex:1},scrollContent:{paddingHorizontal:16,paddingTop:12,paddingBottom:32},section:{backgroundColor:o.color.surface,borderRadius:8,borderWidth:1,borderColor:o.color.border,marginBottom:12,overflow:"hidden"},sectionDescription:{fontSize:11,color:o.color.textSecondary,paddingHorizontal:16,paddingTop:8,lineHeight:16},patternChips:{flexDirection:"row",flexWrap:"wrap",gap:8,paddingHorizontal:16,paddingTop:12},patternChip:{flexDirection:"row",alignItems:"center",backgroundColor:o.color.surfaceElevated,borderRadius:6,borderWidth:1,paddingVertical:4,paddingLeft:4,paddingRight:6,maxWidth:"100%",gap:4},patternChipBadge:{paddingVertical:2,paddingHorizontal:5,borderRadius:4},patternChipBadgeText:{fontSize:9,fontWeight:"700"},patternChipValue:{fontSize:11,color:o.color.text,fontFamily:v,flexShrink:1},patternChipX:{marginLeft:2},addPatternRow:{paddingHorizontal:16,paddingTop:12,paddingBottom:16},addButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",paddingVertical:10,paddingHorizontal:16,borderRadius:8,borderWidth:1,borderStyle:"dashed",gap:6},addButtonText:{fontSize:12,fontWeight:"500"},typePicker:{flexDirection:"row",alignItems:"center",gap:8},typePickerRow:{flex:1,flexDirection:"row",flexWrap:"wrap",gap:8},typeOption:{flexDirection:"row",alignItems:"center",paddingVertical:8,paddingHorizontal:12,borderRadius:6,borderWidth:1,backgroundColor:o.color.surfaceElevated,gap:6},typeOptionText:{fontSize:11,fontWeight:"600"},typePickerCancel:{padding:8},patternInputContainer:{flexDirection:"row",alignItems:"center",backgroundColor:o.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:o.color.border,paddingLeft:4,paddingRight:8,paddingVertical:4,gap:4},patternInput:{flex:1,fontSize:12,color:o.color.text,paddingVertical:6,paddingHorizontal:4},addPatternButton:{paddingVertical:6,paddingHorizontal:10,borderRadius:4},addPatternButtonText:{fontSize:11,fontWeight:"600"},cancelButton:{padding:4},categoryBadgeScroll:{marginTop:12},categoryBadgeScrollContent:{paddingHorizontal:16,gap:8},categoryBadge:{flexDirection:"row",alignItems:"center",paddingVertical:8,paddingLeft:10,paddingRight:6,borderRadius:8,borderWidth:1,gap:6},categoryBadgeText:{fontSize:11,fontWeight:"600"},categoryBadgeCountBubble:{paddingHorizontal:6,paddingVertical:2,borderRadius:10,minWidth:20,alignItems:"center"},categoryBadgeCount:{fontSize:10,fontWeight:"600"},detectedItemsContainer:{paddingHorizontal:16,paddingTop:12,paddingBottom:16},detectedItemsScroll:{maxHeight:200},detectedItems:{flexDirection:"row",flexWrap:"wrap",gap:8},detectedItem:{flexDirection:"row",alignItems:"center",backgroundColor:o.color.surfaceElevated,borderRadius:6,borderWidth:1,paddingVertical:6,paddingHorizontal:10,gap:6},detectedItemText:{fontSize:11,color:o.color.text,fontFamily:v},emptyText:{fontSize:11,color:o.color.textTertiary,fontStyle:"italic",textAlign:"center",paddingVertical:16,paddingHorizontal:16},howItWorks:{paddingHorizontal:16,paddingVertical:12},howItWorksText:{fontSize:11,color:o.color.textTertiary,lineHeight:18,fontFamily:v},howItWorksBold:{fontWeight:"700",color:o.color.textSecondary},modalOverlay:{flex:1,backgroundColor:"rgba(0, 0, 0, 0.5)",justifyContent:"center",alignItems:"center",padding:32},actionPopup:{backgroundColor:o.color.surface,borderRadius:12,borderWidth:1,borderColor:o.color.border,width:"100%",maxWidth:300,overflow:"hidden"},actionPopupHeader:{padding:16,borderBottomWidth:1,borderBottomColor:o.color.separator,alignItems:"center"},actionPopupButtons:{flexDirection:"row",padding:12,gap:8},actionPopupButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",paddingVertical:12,paddingHorizontal:12,borderRadius:8,gap:8},actionPopupInclude:{backgroundColor:o.color.accentSoft},actionPopupExclude:{backgroundColor:o.color.accentSoft},actionPopupButtonText:{fontSize:13,fontWeight:"600"},actionPopupCancel:{padding:12,borderTopWidth:1,borderTopColor:o.color.separator,alignItems:"center"},actionPopupCancelText:{fontSize:13,color:o.color.textTertiary,fontWeight:"500"},settingsSection:{paddingHorizontal:16,paddingTop:8,paddingBottom:16},settingItem:{gap:8},settingItemSpaced:{marginTop:16,paddingTop:16,borderTopWidth:1,borderTopColor:o.color.separator},settingHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between"},settingLabel:{fontSize:13,fontWeight:"600",color:o.color.text},settingValue:{backgroundColor:o.color.fillSecondary,paddingHorizontal:10,paddingVertical:4,borderRadius:6},settingValueText:{fontSize:12,fontWeight:"700",color:o.color.textTertiary,fontFamily:v},settingDescription:{fontSize:11,color:o.color.textSecondary,lineHeight:16},settingDescriptionMuted:{fontSize:10,color:o.color.textTertiary,lineHeight:14,marginTop:4,fontStyle:"italic"},settingLabelDisabled:{color:o.color.textTertiary},settingWarning:{color:o.color.warning,fontWeight:"500"},batchSizePresets:{flexDirection:"row",flexWrap:"wrap",gap:8,marginTop:4},batchSizePreset:{paddingVertical:8,paddingHorizontal:14,borderRadius:6,backgroundColor:o.color.surfaceElevated,borderWidth:1,borderColor:o.color.border},batchSizePresetActive:{backgroundColor:o.color.fillSecondary,borderColor:o.color.fillTertiary},batchSizePresetText:{fontSize:12,fontWeight:"500",color:o.color.textSecondary,fontFamily:v},batchSizePresetTextActive:{color:o.color.textTertiary,fontWeight:"700"},renderCountRangeContainer:{paddingHorizontal:16,paddingTop:12,paddingBottom:16,gap:12},renderCountInputRow:{flexDirection:"row",alignItems:"center",gap:12},renderCountInputGroup:{flex:1,gap:4},renderCountLabel:{fontSize:10,fontWeight:"600",color:o.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},renderCountInput:{backgroundColor:o.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:o.color.border,paddingVertical:10,paddingHorizontal:12,fontSize:14,fontWeight:"600",color:o.color.text,fontFamily:v,textAlign:"center"},renderCountSeparator:{fontSize:12,color:o.color.textTertiary,marginTop:18},clearRangeButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",paddingVertical:8,paddingHorizontal:12,borderRadius:6,backgroundColor:o.color.warningSoft,borderWidth:1,borderColor:o.color.warning+"40",gap:6,alignSelf:"center"},clearRangeButtonText:{fontSize:11,fontWeight:"600",color:o.color.warning}});export default HighlightFilterView;
|
|
1
|
+
"use strict";import fe,{useState as f,useCallback as I}from"react";import{View as a,Text as i,TouchableOpacity as g,TextInput as A,StyleSheet as ie,ScrollView as O,Modal as ce,Pressable as ae,Switch as w}from"react-native";import{Eye as q,Filter as N,Plus as K,X as L,Box as X,Settings as de,Hash as se,SectionHeader as p,night as o,monoFont as v}from"@buoy-gg/shared-ui";import{IdentifierBadge as G,IDENTIFIER_CONFIG as ue}from"./IdentifierBadge";import{detectedItemTestID as he,patternChipTestID as pe,settingTestID as R}from"../utils/testIDs";import{jsx as t,jsxs as l,Fragment as M}from"react/jsx-runtime";const P=d=>ue[d];const ge=["any","viewType","testID","nativeID","component","accessibilityLabel"];function Y({mode:d,onSelect:u,onCancel:s}){return l(a,{nativeID:"__rn_buoy__type-picker",testID:`buoy-highlight-${d}-types`,style:e.typePicker,children:[t(a,{style:e.typePickerRow,children:ge.map(h=>{const r=P(h);const b=r.icon;return l(g,{testID:`buoy-highlight-${d}-type-${h.toLowerCase()}`,accessibilityRole:"button",accessibilityLabel:r.label,style:[e.typeOption,{backgroundColor:r.color+"15",borderColor:r.color+"40"}],onPress:()=>u(h),children:[t(b,{size:14,color:r.color}),t(i,{style:[e.typeOptionText,{color:r.color}],children:r.label})]},h)})}),t(g,{testID:`buoy-highlight-${d}-types-cancel`,accessibilityRole:"button",accessibilityLabel:"Cancel",onPress:s,style:e.typePickerCancel,children:t(L,{size:16,color:o.color.textTertiary})})]})}function Z({mode:d,type:u,onSubmit:s,onCancel:h}){const[r,b]=f("");const z=P(u);const C=()=>{if(r.trim()){s(r.trim())}};return l(a,{nativeID:"__rn_buoy__pattern-input",testID:`buoy-highlight-${d}-input-row`,style:e.patternInputContainer,children:[t(G,{type:u,value:"",badgeOnly:true,compact:true}),t(A,{testID:`buoy-highlight-${d}-input`,value:r,onChangeText:b,onSubmitEditing:C,placeholder:"Enter pattern...",placeholderTextColor:o.color.placeholder,style:e.patternInput,autoFocus:true,returnKeyType:"done",autoCorrect:false,autoCapitalize:"none"}),r.trim()&&t(g,{testID:`buoy-highlight-${d}-submit`,accessibilityRole:"button",accessibilityLabel:"Add pattern",onPress:C,style:[e.addPatternButton,{backgroundColor:z.color+"20"}],children:t(i,{style:[e.addPatternButtonText,{color:z.color}],children:"Add"})}),t(g,{testID:`buoy-highlight-${d}-input-cancel`,accessibilityRole:"button",accessibilityLabel:"Cancel",onPress:h,style:e.cancelButton,children:t(L,{size:16,color:o.color.textTertiary})})]})}function J({mode:d,pattern:u,onRemove:s}){const h=P(u.type);return l(g,{testID:pe(d,u.type,u.value),accessibilityRole:"button",accessibilityLabel:`${h.label} ${u.value}, tap to remove`,style:[e.patternChip,{borderColor:h.color+"40"}],onPress:s,activeOpacity:.7,children:[t(a,{style:[e.patternChipBadge,{backgroundColor:h.color+"20"}],children:t(i,{style:[e.patternChipBadgeText,{color:h.color}],children:h.shortLabel})}),t(i,{style:e.patternChipValue,numberOfLines:1,children:u.value}),t(L,{size:12,color:o.color.textTertiary,style:e.patternChipX})]})}const ye={label:"All",shortLabel:"All",color:o.color.textSecondary,icon:X};function S({filterType:d,count:u,isSelected:s,onPress:h}){const r=d==="all"?ye:P(d);const b=`buoy-highlight-detected-cat-${String(d).toLowerCase()}`;return l(g,{testID:b,accessibilityRole:"button",accessibilityLabel:`${r.label}, ${u}`,style:[e.categoryBadge,{backgroundColor:r.color+"15",borderColor:s?r.color:r.color+"40",borderWidth:s?2:1}],onPress:h,children:[t(r.icon,{size:12,color:r.color}),t(i,{style:[e.categoryBadgeText,{color:r.color}],children:r.label}),t(a,{style:[e.categoryBadgeCountBubble,{backgroundColor:r.color+"25"}],children:t(i,{testID:`${b}-count`,style:[e.categoryBadgeCount,{color:r.color}],children:u})})]})}const be=[{value:20,label:"20"},{value:50,label:"50"},{value:100,label:"100"},{value:150,label:"150"},{value:250,label:"250"},{value:500,label:"500"}];const j=[{value:"off",label:"Off",description:"No debug logging"},{value:"minimal",label:"Minimal",description:"Only hook value changes"},{value:"verbose",label:"Verbose",description:"Component + cause + changes"},{value:"all",label:"All",description:"Full fiber dump"}];export function HighlightFilterView({filters:d,onFilterChange:u,settings:s,onSettingsChange:h,availableProps:r,activeTab:b}){const[z,C]=f(false);const[Q,k]=f(false);const[B,H]=f(null);const[W,E]=f(null);const[m,x]=f("all");const[y,T]=f(null);const ee=n=>{switch(n){case"viewType":return r.viewTypes.map(c=>({value:c,type:"viewType"}));case"testID":return r.testIDs.map(c=>({value:c,type:"testID"}));case"nativeID":return r.nativeIDs.map(c=>({value:c,type:"nativeID"}));case"component":return r.componentNames.map(c=>({value:c,type:"component"}));case"accessibilityLabel":return r.accessibilityLabels.map(c=>({value:c,type:"accessibilityLabel"}));case"all":default:return[...r.viewTypes.map(c=>({value:c,type:"viewType"})),...r.testIDs.map(c=>({value:c,type:"testID"})),...r.nativeIDs.map(c=>({value:c,type:"nativeID"})),...r.componentNames.map(c=>({value:c,type:"component"})),...r.accessibilityLabels.map(c=>({value:c,type:"accessibilityLabel"}))]}};const F=ee(m);const U=r.viewTypes.length+r.testIDs.length+r.nativeIDs.length+r.componentNames.length+r.accessibilityLabels.length;const V=I((n,c)=>{const D=[...d.includePatterns,{type:n,value:c}];u({includePatterns:D});H(null)},[d.includePatterns,u]);const _=I((n,c)=>{const D=[...d.excludePatterns,{type:n,value:c}];u({excludePatterns:D});E(null)},[d.excludePatterns,u]);const te=I(n=>{const c=d.includePatterns.filter((D,$)=>$!==n);u({includePatterns:c})},[d.includePatterns,u]);const oe=I(n=>{const c=d.excludePatterns.filter((D,$)=>$!==n);u({excludePatterns:c})},[d.excludePatterns,u]);const ne=I((n,c)=>{T({type:n,value:c})},[]);const le=I(()=>{if(y){V(y.type,y.value);T(null)}},[y,V]);const re=I(()=>{if(y){_(y.type,y.value);T(null)}},[y,_]);return t(a,{style:e.container,children:t(O,{keyboardShouldPersistTaps:"handled",nativeID:"__rn_buoy__filter-view",testID:"buoy-highlight-filter-scroll",style:e.scrollView,contentContainerStyle:e.scrollContent,showsVerticalScrollIndicator:false,children:b==="filters"?l(M,{children:[l(a,{style:e.section,children:[l(p,{children:[t(p.Icon,{icon:q,color:o.color.accent,size:12}),t(p.Title,{children:"INCLUDE ONLY"}),d.includePatterns.length>0&&t(p.Badge,{testID:"buoy-highlight-include-count",count:d.includePatterns.length,color:o.color.accent})]}),t(i,{style:e.sectionDescription,children:"Show only components matching these patterns. If any are set, components must match at least one."}),d.includePatterns.length>0&&t(a,{style:e.patternChips,children:d.includePatterns.map((n,c)=>t(J,{mode:"include",pattern:n,onRemove:()=>te(c)},`${n.type}-${n.value}-${c}`))}),t(a,{style:e.addPatternRow,children:z?t(Y,{mode:"include",onSelect:n=>{C(false);H(n)},onCancel:()=>C(false)}):B?t(Z,{mode:"include",type:B,onSubmit:n=>V(B,n),onCancel:()=>H(null)}):l(g,{testID:"buoy-highlight-include-add",accessibilityRole:"button",accessibilityLabel:"Add include pattern",style:[e.addButton,{borderColor:o.color.accentBorderStrong}],onPress:()=>C(true),children:[t(K,{size:14,color:o.color.accent}),t(i,{style:[e.addButtonText,{color:o.color.accent}],children:"Add include pattern"})]})})]}),l(a,{style:e.section,children:[l(p,{children:[t(p.Icon,{icon:N,color:o.color.accent,size:12}),t(p.Title,{children:"EXCLUDE"}),d.excludePatterns.length>0&&t(p.Badge,{testID:"buoy-highlight-exclude-count",count:d.excludePatterns.length,color:o.color.accent})]}),t(i,{style:e.sectionDescription,children:"Hide components matching these patterns from the list."}),d.excludePatterns.length>0&&t(a,{style:e.patternChips,children:d.excludePatterns.map((n,c)=>t(J,{mode:"exclude",pattern:n,onRemove:()=>oe(c)},`${n.type}-${n.value}-${c}`))}),t(a,{style:e.addPatternRow,children:Q?t(Y,{mode:"exclude",onSelect:n=>{k(false);E(n)},onCancel:()=>k(false)}):W?t(Z,{mode:"exclude",type:W,onSubmit:n=>_(W,n),onCancel:()=>E(null)}):l(g,{testID:"buoy-highlight-exclude-add",accessibilityRole:"button",accessibilityLabel:"Add exclude pattern",style:[e.addButton,{borderColor:o.color.accentBorderStrong}],onPress:()=>k(true),children:[t(K,{size:14,color:o.color.accent}),t(i,{style:[e.addButtonText,{color:o.color.accent}],children:"Add exclude pattern"})]})})]}),l(a,{style:e.section,children:[l(p,{children:[t(p.Icon,{icon:se,color:o.color.warning,size:12}),t(p.Title,{children:"RENDER COUNT RANGE"}),(d.minRenderCount!==void 0||d.maxRenderCount!==void 0)&&t(p.Badge,{count:1,color:o.color.warning})]}),t(i,{style:e.sectionDescription,children:"Show only components with render count in a specific range."}),l(a,{nativeID:"__rn_buoy__render-count-range",testID:"buoy-highlight-range",style:e.renderCountRangeContainer,children:[l(a,{style:e.renderCountInputRow,children:[l(a,{style:e.renderCountInputGroup,children:[t(i,{style:e.renderCountLabel,children:"Min"}),t(A,{value:d.minRenderCount!==void 0?String(d.minRenderCount):"",onChangeText:n=>{const c=parseInt(n,10);if(n===""||n===void 0){u({minRenderCount:void 0})}else if(!isNaN(c)&&c>=0){u({minRenderCount:c})}},testID:"buoy-highlight-range-min",placeholder:"0",placeholderTextColor:o.color.placeholder,style:e.renderCountInput,keyboardType:"number-pad",returnKeyType:"done"})]}),t(i,{style:e.renderCountSeparator,children:"to"}),l(a,{style:e.renderCountInputGroup,children:[t(i,{style:e.renderCountLabel,children:"Max"}),t(A,{value:d.maxRenderCount!==void 0?String(d.maxRenderCount):"",onChangeText:n=>{const c=parseInt(n,10);if(n===""||n===void 0){u({maxRenderCount:void 0})}else if(!isNaN(c)&&c>=0){u({maxRenderCount:c})}},testID:"buoy-highlight-range-max",placeholder:"\u221E",placeholderTextColor:o.color.placeholder,style:e.renderCountInput,keyboardType:"number-pad",returnKeyType:"done"})]})]}),(d.minRenderCount!==void 0||d.maxRenderCount!==void 0)&&l(g,{testID:"buoy-highlight-range-clear",accessibilityRole:"button",accessibilityLabel:"Clear range",style:e.clearRangeButton,onPress:()=>u({minRenderCount:void 0,maxRenderCount:void 0}),children:[t(L,{size:12,color:o.color.warning}),t(i,{style:e.clearRangeButtonText,children:"Clear Range"})]})]})]}),l(a,{style:e.section,children:[l(p,{children:[t(p.Icon,{icon:X,color:o.color.textSecondary,size:12}),t(p.Title,{children:"DETECTED ITEMS"})]}),t(i,{style:e.sectionDescription,children:"Tap an item to quickly add it as an exclude pattern."}),l(O,{keyboardShouldPersistTaps:"handled",horizontal:true,showsHorizontalScrollIndicator:false,style:e.categoryBadgeScroll,contentContainerStyle:e.categoryBadgeScrollContent,children:[U>0&&t(S,{filterType:"all",count:U,isSelected:m==="all",onPress:()=>x("all")}),r.viewTypes.length>0&&t(S,{filterType:"viewType",count:r.viewTypes.length,isSelected:m==="viewType",onPress:()=>x("viewType")}),r.testIDs.length>0&&t(S,{filterType:"testID",count:r.testIDs.length,isSelected:m==="testID",onPress:()=>x("testID")}),r.nativeIDs.length>0&&t(S,{filterType:"nativeID",count:r.nativeIDs.length,isSelected:m==="nativeID",onPress:()=>x("nativeID")}),r.componentNames.length>0&&t(S,{filterType:"component",count:r.componentNames.length,isSelected:m==="component",onPress:()=>x("component")}),r.accessibilityLabels.length>0&&t(S,{filterType:"accessibilityLabel",count:r.accessibilityLabels.length,isSelected:m==="accessibilityLabel",onPress:()=>x("accessibilityLabel")})]}),t(a,{nativeID:"__rn_buoy__detected-items",testID:"buoy-highlight-detected",style:e.detectedItemsContainer,children:F.length>0?t(O,{keyboardShouldPersistTaps:"handled",testID:"buoy-highlight-detected-scroll",style:e.detectedItemsScroll,contentContainerStyle:e.detectedItems,nestedScrollEnabled:true,showsVerticalScrollIndicator:true,children:F.map(n=>{const c=P(n.type);return t(g,{testID:he(n.type,n.value),accessibilityRole:"button",accessibilityLabel:`${c.label} ${n.value}`,style:[e.detectedItem,{borderColor:c.color+"40"}],onPress:()=>ne(n.type,n.value),children:m==="all"?t(G,{type:n.type,value:n.value,compact:true,shortLabel:true}):t(i,{style:e.detectedItemText,numberOfLines:1,children:n.value})},`${n.type}-${n.value}`)})}):t(i,{testID:"buoy-highlight-detected-empty",style:e.emptyText,children:"No items detected yet. Start tracking to see components here."})})]}),t(ce,{visible:y!==null,transparent:true,animationType:"fade",onRequestClose:()=>T(null),children:t(ae,{accessible:false,testID:"buoy-highlight-detected-popup-backdrop",style:e.modalOverlay,onPress:()=>T(null),children:t(a,{accessible:false,testID:"buoy-highlight-detected-popup",style:e.actionPopup,children:y&&l(M,{children:[t(a,{style:e.actionPopupHeader,children:t(G,{type:y.type,value:y.value,compact:true,shortLabel:true})}),l(a,{style:e.actionPopupButtons,children:[l(g,{testID:"buoy-highlight-detected-popup-include",accessibilityRole:"button",accessibilityLabel:"Include only",style:[e.actionPopupButton,e.actionPopupInclude],onPress:le,children:[t(q,{size:16,color:o.color.accent}),t(i,{style:[e.actionPopupButtonText,{color:o.color.accent}],children:"Include Only"})]}),l(g,{testID:"buoy-highlight-detected-popup-exclude",accessibilityRole:"button",accessibilityLabel:"Exclude",style:[e.actionPopupButton,e.actionPopupExclude],onPress:re,children:[t(N,{size:16,color:o.color.accent}),t(i,{style:[e.actionPopupButtonText,{color:o.color.accent}],children:"Exclude"})]})]}),t(g,{testID:"buoy-highlight-detected-popup-cancel",accessibilityRole:"button",accessibilityLabel:"Cancel",style:e.actionPopupCancel,onPress:()=>T(null),children:t(i,{style:e.actionPopupCancelText,children:"Cancel"})})]})})})}),l(a,{style:e.section,children:[l(p,{children:[t(p.Icon,{icon:N,color:o.color.textTertiary,size:12}),t(p.Title,{children:"HOW FILTERS WORK"})]}),t(a,{style:e.howItWorks,children:l(i,{style:e.howItWorksText,children:[t(i,{style:e.howItWorksBold,children:"Any:"})," Matches against all fields","\n",t(i,{style:e.howItWorksBold,children:"ViewType:"})," Native component class (RCTView, RCTText)","\n",t(i,{style:e.howItWorksBold,children:"testID:"})," Component testID prop","\n",t(i,{style:e.howItWorksBold,children:"Component:"})," React component name from fiber"]})})]})]}):t(M,{children:l(a,{style:e.section,children:[l(p,{children:[t(p.Icon,{icon:de,color:o.color.textTertiary,size:12}),t(p.Title,{children:"SETTINGS"})]}),l(a,{style:e.settingsSection,children:[l(a,{style:e.settingItem,children:[l(a,{style:e.settingHeader,children:[t(i,{style:e.settingLabel,children:"Show Render Count"}),t(w,{testID:R("showRenderCount"),value:s.showRenderCount,onValueChange:n=>{h({showRenderCount:n});if(!n&&s.trackRenderCauses){h({trackRenderCauses:false})}},trackColor:{false:o.color.surfaceElevated,true:o.color.accent+"80"},thumbColor:s.showRenderCount?o.color.accent:o.color.knob})]}),t(i,{style:e.settingDescription,children:"Display render count badge on highlights. Disabling improves performance by skipping count tracking."})]}),l(a,{style:[e.settingItem,e.settingItemSpaced],children:[l(a,{style:e.settingHeader,children:[t(i,{style:[e.settingLabel,!s.showRenderCount&&e.settingLabelDisabled],children:"Track Render Causes"}),t(w,{testID:R("trackRenderCauses"),value:s.trackRenderCauses,onValueChange:n=>h({trackRenderCauses:n}),trackColor:{false:o.color.surfaceElevated,true:o.color.warning+"80"},thumbColor:s.trackRenderCauses?o.color.warning:o.color.knob,disabled:!s.showRenderCount})]}),l(i,{style:e.settingDescription,children:["Detect WHY components render (props, hooks, parent re-render).",!s.showRenderCount&&l(i,{style:e.settingWarning,children:["\n",'Requires "Show Render Count" to be enabled.']})]})]}),l(a,{style:[e.settingItem,e.settingItemSpaced],children:[l(a,{style:e.settingHeader,children:[t(i,{style:[e.settingLabel,!s.trackRenderCauses&&e.settingLabelDisabled],children:"Enable Render History"}),t(w,{testID:R("enableRenderHistory"),value:s.enableRenderHistory,onValueChange:n=>h({enableRenderHistory:n}),trackColor:{false:o.color.surfaceElevated,true:o.color.accent+"80"},thumbColor:s.enableRenderHistory?o.color.accent:o.color.knob,disabled:!s.trackRenderCauses})]}),l(i,{style:e.settingDescription,children:["Store render events for each component to view in the History tab.",!s.trackRenderCauses&&l(i,{style:e.settingWarning,children:["\n",'Requires "Track Render Causes" to be enabled.']})]})]}),l(a,{style:[e.settingItem,e.settingItemSpaced],children:[l(a,{style:e.settingHeader,children:[t(i,{style:e.settingLabel,children:"Debug Log Level"}),t(a,{style:e.settingValue,children:t(i,{testID:"buoy-highlight-setting-debugLogLevel-value",style:[e.settingValueText,s.debugLogLevel!=="off"&&{color:o.color.warning}],children:j.find(n=>n.value===s.debugLogLevel)?.label||"Off"})})]}),t(i,{style:e.settingDescription,children:"Control console logging verbosity for render cause detection."}),t(a,{style:e.batchSizePresets,children:j.map(n=>t(g,{style:[e.batchSizePreset,s.debugLogLevel===n.value&&e.batchSizePresetActive,n.value!=="off"&&s.debugLogLevel===n.value&&{backgroundColor:o.color.warningSoft,borderColor:o.color.warning}],onPress:()=>h({debugLogLevel:n.value}),testID:`buoy-highlight-preset-log-${n.value}`,accessibilityRole:"button",accessibilityLabel:`Debug log level ${n.label}`,children:t(i,{style:[e.batchSizePresetText,s.debugLogLevel===n.value&&e.batchSizePresetTextActive,n.value!=="off"&&s.debugLogLevel===n.value&&{color:o.color.warning}],children:n.label})},n.value))}),l(i,{style:e.settingDescriptionMuted,children:[j.find(n=>n.value===s.debugLogLevel)?.description,s.debugLogLevel!=="off"&&" \u2022 Check Metro console for logs"]})]}),l(a,{style:[e.settingItem,e.settingItemSpaced],children:[l(a,{style:e.settingHeader,children:[t(i,{style:e.settingLabel,children:"Batch Size"}),t(a,{style:e.settingValue,children:t(i,{testID:"buoy-highlight-setting-batchSize-value",style:e.settingValueText,children:s.batchSize})})]}),t(i,{style:e.settingDescription,children:"Maximum components to highlight per render update. Higher values capture more re-renders but may impact performance on complex screens."}),t(a,{style:e.batchSizePresets,children:be.map(n=>t(g,{style:[e.batchSizePreset,s.batchSize===n.value&&e.batchSizePresetActive],onPress:()=>h({batchSize:n.value}),testID:`buoy-highlight-preset-batch-${n.value}`,accessibilityRole:"button",accessibilityLabel:`Batch size ${n.label}`,children:t(i,{style:[e.batchSizePresetText,s.batchSize===n.value&&e.batchSizePresetTextActive],children:n.label})},n.value))})]}),l(a,{style:[e.settingItem,e.settingItemSpaced],children:[l(a,{style:e.settingHeader,children:[t(i,{style:e.settingLabel,children:"Show host views"}),t(w,{testID:R("showHostViews"),value:!!s.showHostViews,onValueChange:n=>h({showHostViews:n}),trackColor:{false:o.color.surfaceElevated,true:o.color.accent+"80"},thumbColor:s.showHostViews?o.color.accent:o.color.knob})]}),t(i,{style:e.settingDescription,children:"Include anonymous View / RCTView / Text hosts. Off by default so the list is named composites (what actually re-rendered)."})]}),l(a,{style:[e.settingItem,e.settingItemSpaced],children:[l(a,{style:e.settingHeader,children:[t(i,{style:e.settingLabel,children:"Highlight Dev Tools"}),t(w,{testID:R("excludeDevTools"),value:!s.excludeDevTools,onValueChange:n=>h({excludeDevTools:!n}),trackColor:{false:o.color.surfaceElevated,true:o.color.accent+"80"},thumbColor:!s.excludeDevTools?o.color.accent:o.color.knob})]}),l(i,{style:e.settingDescription,children:["Show re-render highlights on Buoy dev tools (floating menu, modals, etc.). Useful for optimizing the dev tools themselves.",!s.excludeDevTools&&l(i,{style:e.settingWarning,children:["\n","The highlight overlay is always excluded to prevent infinite loops."]})]})]})]})]})})})})}const e=ie.create({container:{flex:1,backgroundColor:"transparent"},scrollView:{flex:1},scrollContent:{paddingHorizontal:16,paddingTop:12,paddingBottom:32},section:{backgroundColor:o.color.surface,borderRadius:8,borderWidth:1,borderColor:o.color.border,marginBottom:12,overflow:"hidden"},sectionDescription:{fontSize:11,color:o.color.textSecondary,paddingHorizontal:16,paddingTop:8,lineHeight:16},patternChips:{flexDirection:"row",flexWrap:"wrap",gap:8,paddingHorizontal:16,paddingTop:12},patternChip:{flexDirection:"row",alignItems:"center",backgroundColor:o.color.surfaceElevated,borderRadius:6,borderWidth:1,paddingVertical:4,paddingLeft:4,paddingRight:6,maxWidth:"100%",gap:4},patternChipBadge:{paddingVertical:2,paddingHorizontal:5,borderRadius:4},patternChipBadgeText:{fontSize:9,fontWeight:"700"},patternChipValue:{fontSize:11,color:o.color.text,fontFamily:v,flexShrink:1},patternChipX:{marginLeft:2},addPatternRow:{paddingHorizontal:16,paddingTop:12,paddingBottom:16},addButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",paddingVertical:10,paddingHorizontal:16,borderRadius:8,borderWidth:1,borderStyle:"dashed",gap:6},addButtonText:{fontSize:12,fontWeight:"500"},typePicker:{flexDirection:"row",alignItems:"center",gap:8},typePickerRow:{flex:1,flexDirection:"row",flexWrap:"wrap",gap:8},typeOption:{flexDirection:"row",alignItems:"center",paddingVertical:8,paddingHorizontal:12,borderRadius:6,borderWidth:1,backgroundColor:o.color.surfaceElevated,gap:6},typeOptionText:{fontSize:11,fontWeight:"600"},typePickerCancel:{padding:8},patternInputContainer:{flexDirection:"row",alignItems:"center",backgroundColor:o.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:o.color.border,paddingLeft:4,paddingRight:8,paddingVertical:4,gap:4},patternInput:{flex:1,fontSize:12,color:o.color.text,paddingVertical:6,paddingHorizontal:4},addPatternButton:{paddingVertical:6,paddingHorizontal:10,borderRadius:4},addPatternButtonText:{fontSize:11,fontWeight:"600"},cancelButton:{padding:4},categoryBadgeScroll:{marginTop:12},categoryBadgeScrollContent:{paddingHorizontal:16,gap:8},categoryBadge:{flexDirection:"row",alignItems:"center",paddingVertical:8,paddingLeft:10,paddingRight:6,borderRadius:8,borderWidth:1,gap:6},categoryBadgeText:{fontSize:11,fontWeight:"600"},categoryBadgeCountBubble:{paddingHorizontal:6,paddingVertical:2,borderRadius:10,minWidth:20,alignItems:"center"},categoryBadgeCount:{fontSize:10,fontWeight:"600"},detectedItemsContainer:{paddingHorizontal:16,paddingTop:12,paddingBottom:16},detectedItemsScroll:{maxHeight:200},detectedItems:{flexDirection:"row",flexWrap:"wrap",gap:8},detectedItem:{flexDirection:"row",alignItems:"center",backgroundColor:o.color.surfaceElevated,borderRadius:6,borderWidth:1,paddingVertical:6,paddingHorizontal:10,gap:6},detectedItemText:{fontSize:11,color:o.color.text,fontFamily:v},emptyText:{fontSize:11,color:o.color.textTertiary,fontStyle:"italic",textAlign:"center",paddingVertical:16,paddingHorizontal:16},howItWorks:{paddingHorizontal:16,paddingVertical:12},howItWorksText:{fontSize:11,color:o.color.textTertiary,lineHeight:18,fontFamily:v},howItWorksBold:{fontWeight:"700",color:o.color.textSecondary},modalOverlay:{flex:1,backgroundColor:"rgba(0, 0, 0, 0.5)",justifyContent:"center",alignItems:"center",padding:32},actionPopup:{backgroundColor:o.color.surface,borderRadius:12,borderWidth:1,borderColor:o.color.border,width:"100%",maxWidth:300,overflow:"hidden"},actionPopupHeader:{padding:16,borderBottomWidth:1,borderBottomColor:o.color.separator,alignItems:"center"},actionPopupButtons:{flexDirection:"row",padding:12,gap:8},actionPopupButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",paddingVertical:12,paddingHorizontal:12,borderRadius:8,gap:8},actionPopupInclude:{backgroundColor:o.color.accentSoft},actionPopupExclude:{backgroundColor:o.color.accentSoft},actionPopupButtonText:{fontSize:13,fontWeight:"600"},actionPopupCancel:{padding:12,borderTopWidth:1,borderTopColor:o.color.separator,alignItems:"center"},actionPopupCancelText:{fontSize:13,color:o.color.textTertiary,fontWeight:"500"},settingsSection:{paddingHorizontal:16,paddingTop:8,paddingBottom:16},settingItem:{gap:8},settingItemSpaced:{marginTop:16,paddingTop:16,borderTopWidth:1,borderTopColor:o.color.separator},settingHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between"},settingLabel:{fontSize:13,fontWeight:"600",color:o.color.text},settingValue:{backgroundColor:o.color.fillSecondary,paddingHorizontal:10,paddingVertical:4,borderRadius:6},settingValueText:{fontSize:12,fontWeight:"700",color:o.color.textTertiary,fontFamily:v},settingDescription:{fontSize:11,color:o.color.textSecondary,lineHeight:16},settingDescriptionMuted:{fontSize:10,color:o.color.textTertiary,lineHeight:14,marginTop:4,fontStyle:"italic"},settingLabelDisabled:{color:o.color.textTertiary},settingWarning:{color:o.color.warning,fontWeight:"500"},batchSizePresets:{flexDirection:"row",flexWrap:"wrap",gap:8,marginTop:4},batchSizePreset:{paddingVertical:8,paddingHorizontal:14,borderRadius:6,backgroundColor:o.color.surfaceElevated,borderWidth:1,borderColor:o.color.border},batchSizePresetActive:{backgroundColor:o.color.fillSecondary,borderColor:o.color.fillTertiary},batchSizePresetText:{fontSize:12,fontWeight:"500",color:o.color.textSecondary,fontFamily:v},batchSizePresetTextActive:{color:o.color.textTertiary,fontWeight:"700"},renderCountRangeContainer:{paddingHorizontal:16,paddingTop:12,paddingBottom:16,gap:12},renderCountInputRow:{flexDirection:"row",alignItems:"center",gap:12},renderCountInputGroup:{flex:1,gap:4},renderCountLabel:{fontSize:10,fontWeight:"600",color:o.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},renderCountInput:{backgroundColor:o.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:o.color.border,paddingVertical:10,paddingHorizontal:12,fontSize:14,fontWeight:"600",color:o.color.text,fontFamily:v,textAlign:"center"},renderCountSeparator:{fontSize:12,color:o.color.textTertiary,marginTop:18},clearRangeButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",paddingVertical:8,paddingHorizontal:12,borderRadius:6,backgroundColor:o.color.warningSoft,borderWidth:1,borderColor:o.color.warning+"40",gap:6,alignSelf:"center"},clearRangeButtonText:{fontSize:11,fontWeight:"600",color:o.color.warning}});export default HighlightFilterView;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import q,{useState as j,useEffect as k,useRef as C,useCallback as m,memo as v,useMemo as y}from"react";import{View as z,Text as b,FlatList as D,StyleSheet as P}from"react-native";import{RenderTracker as r}from"../utils/RenderTracker";import{RenderListItem as
|
|
1
|
+
"use strict";import q,{useState as j,useEffect as k,useRef as C,useCallback as m,memo as v,useMemo as y}from"react";import{View as z,Text as b,FlatList as D,StyleSheet as P,Keyboard as N}from"react-native";import{RenderTracker as r}from"../utils/RenderTracker";import{RenderListItem as V}from"./RenderListItem";import{Lock as M,night as u,useLimit as U,ToolEmptyState as _,resolveListEmptyState as H}from"@buoy-gg/shared-ui";import{jsx as s,jsxs as I}from"react/jsx-runtime";function K({searchText:t,filters:R,onSelectRender:g,onStatsChange:p,onRendersChange:i,isTracking:S,isPro:x=false}){const[o,h]=j(()=>r.getFilteredRenders(t));const w=C(null);k(()=>{const e=r.subscribe(()=>{const n=r.getFilteredRenders(t);h(n);p(r.getStats());i?.(n)});return e},[t,p,i]);k(()=>{const e=r.getFilteredRenders(t);h(e);i?.(e)},[t,R,i]);const L=U("highlightUpdates.components");const l=x?Infinity:L;const d=y(()=>{return o.slice(0,l)},[o,l]);const c=y(()=>{return Math.max(0,o.length-l)},[o.length,l]);const B=m(e=>e.id,[]);const E=m(({item:e,index:n})=>s(V,{render:e,onPress:()=>{N.dismiss();g(e,n,d)}}),[g,d]);const F=m(()=>{if(c<=0)return null;return I(z,{testID:"buoy-highlight-locked",style:a.lockedBanner,children:[s(M,{size:14,color:u.color.warning}),I(b,{testID:"buoy-highlight-locked-text",style:a.lockedBannerText,children:[c," more ",c===1?"component":"components"," locked"]}),s(b,{style:a.lockedBannerSubtext,children:"Upgrade to Pro"})]})},[c]);if(o.length===0){const e=t.trim();const n=r.getStats().totalComponents;const f=e?r.getFilteredRenders("").length:0;const T=H({subject:"components",verb:"tracked",search:t,total:e?f:n,capturing:S,blocked:e&&f===0&&n>0?"The active filters hide everything tracked, so there is nothing to search.":void 0,waiting:{otto:"stare",title:"No renders tracked",message:"Component renders will appear here"},paused:{title:"No renders tracked",message:"Enable tracking to start capturing"}});return s(_,{...T,testID:"buoy-highlight-empty"})}return s(D,{testID:"buoy-highlight-list",ref:w,keyboardShouldPersistTaps:"handled",data:d,renderItem:E,keyExtractor:B,contentContainerStyle:a.listContent,showsVerticalScrollIndicator:true,initialNumToRender:10,maxToRenderPerBatch:10,windowSize:10,scrollEnabled:false,ListFooterComponent:F})}export const IsolatedRenderList=v(K);const a=P.create({listContent:{paddingTop:8},lockedBanner:{flexDirection:"row",alignItems:"center",justifyContent:"center",paddingVertical:12,paddingHorizontal:16,marginTop:8,gap:8},lockedBannerText:{color:u.color.warning,fontSize:13,fontWeight:"500"},lockedBannerSubtext:{color:u.color.textTertiary,fontSize:12}});export default IsolatedRenderList;
|