@buoy-gg/image-overlay 7.0.68 → 7.0.70
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/imageOverlay/components/ImageOverlayModal.js +1 -1
- package/lib/commonjs/imageOverlay/components/ImageOverlayStandalone.js +1 -1
- package/lib/commonjs/imageOverlay/components/OverlayControls.js +1 -1
- package/lib/commonjs/imageOverlay/components/TargetList.js +1 -1
- package/lib/module/imageOverlay/components/ImageOverlayModal.js +1 -1
- package/lib/module/imageOverlay/components/ImageOverlayStandalone.js +1 -1
- package/lib/module/imageOverlay/components/OverlayControls.js +1 -1
- package/lib/module/imageOverlay/components/TargetList.js +1 -1
- package/lib/web/index.mjs +4 -4
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.ImageOverlayModal=ImageOverlayModal;exports.ImageOverlayToolView=ImageOverlayToolView;var _imageClipboard=require("../utils/imageClipboard");var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _ImageOverlayController=require("../utils/ImageOverlayController");var _fiberScanner=require("../utils/fiberScanner");var _TargetList=require("./TargetList");var _OverlayControls=require("./OverlayControls");var _jsxRuntime=require("react/jsx-runtime");let persistedImageUrl="";function ImageOverlayModal({visible:c,onClose:m,onBack:T,onMinimize:C,enableSharedModalDimensions:z=false,initialModalState:j,minimizeTargetPosition:v,inline:O=false,initialView:d}){const[o,l]=(0,_react.useState)(()=>{if(d)return d;const e=_ImageOverlayController.ImageOverlayController.getState();if(e.mode==="free")return"free";if(e.targetRect)return"controls";return"idle"});const[y,g]=(0,_react.useState)(()=>d==="targets"?(0,_fiberScanner.scanForImageTargets)():[]);const[t,w]=(0,_react.useState)(()=>_ImageOverlayController.ImageOverlayController.getState());const[n,i]=(0,_react.useState)(persistedImageUrl);const[h,I]=(0,_react.useState)(()=>_ImageOverlayController.ImageOverlayController.isAutoTracking());(0,_react.useEffect)(()=>{persistedImageUrl=n},[n]);(0,_react.useEffect)(()=>{return _ImageOverlayController.ImageOverlayController.subscribe(w)},[]);(0,_react.useEffect)(()=>{_ImageOverlayController.ImageOverlayController.setAutoTrack(h);return()=>{}},[h]);const x=(0,_react.useCallback)(()=>{const e=(0,_fiberScanner.scanForImageTargets)();g(e);l("targets")},[]);const S=(0,_react.useCallback)(async e=>{await _ImageOverlayController.ImageOverlayController.setTarget(e.instance,e.label,e.fiber);if(persistedImageUrl.trim()){await _ImageOverlayController.ImageOverlayController.setImageUri(persistedImageUrl.trim());_ImageOverlayController.ImageOverlayController.setEnabled(true)}l("controls")},[]);const s=(0,_react.useCallback)(async()=>{const e=persistedImageUrl.trim();if(!e)return;if(o==="free"){await _ImageOverlayController.ImageOverlayController.startFreeMode(e)}else{await _ImageOverlayController.ImageOverlayController.setImageUri(e);_ImageOverlayController.ImageOverlayController.setEnabled(true)}},[o]);const b=(0,_react.useCallback)(async()=>{let e=null;try{e=(0,_imageClipboard.loadImageClipboard)()}catch{}let a=null;if(!e){try{const r=(0,_imageClipboard.loadTextClipboard)();a=r.default||r}catch{}}if(!e&&!a){_reactNative.Alert.alert("Clipboard not available","Install expo-clipboard or @react-native-clipboard/clipboard to use paste.");return}try{if(e&&typeof e.hasImageAsync==="function"){const P=await e.hasImageAsync();if(P){const u=await e.getImageAsync({format:"png"});if(u?.data){if(o==="free"){await _ImageOverlayController.ImageOverlayController.startFreeMode(u.data)}else{await _ImageOverlayController.ImageOverlayController.setImageUri(u.data);_ImageOverlayController.ImageOverlayController.setEnabled(true)}return}}}let r=null;if(e&&typeof e.getStringAsync==="function"){r=await e.getStringAsync()}else if(a&&typeof a.getString==="function"){r=await a.getString()}if(r&&(r.startsWith("http")||r.startsWith("data:"))){i(r);persistedImageUrl=r;return}if(!e){_reactNative.Alert.alert("Image paste requires expo-clipboard","Your project uses @react-native-clipboard/clipboard which only supports text. Install expo-clipboard to paste images directly, or paste an image URL instead.")}else{_reactNative.Alert.alert("No image detected","Try saving your design image, opening it in Photos or Preview, and copying it from there.")}}catch{_reactNative.Alert.alert("Paste failed","Something went wrong reading the clipboard. Try copying the image again.")}},[o]);const B=(0,_react.useCallback)(()=>{_ImageOverlayController.ImageOverlayController.reset();persistedImageUrl="";l("idle");i("");g([])},[]);const V=(0,_react.useCallback)(()=>{if(o==="controls"){const e=(0,_fiberScanner.scanForImageTargets)();g(e);l("targets")}else if(o==="targets"||o==="free"){_ImageOverlayController.ImageOverlayController.reset();l("idle")}else{l("idle")}},[o]);const R=(()=>{switch(o){case"targets":return`Targets (${y.length})`;case"controls":return t.targetLabel||"Component Match";case"free":return"Free Placement";default:return"Image Overlay"}})();const f={showToggleButton:false,customContent:(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:o!=="idle"?V:T}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:R}),(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader.Actions,{children:[o==="targets"&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.headerTextButton,onPress:x,activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.headerTextButtonLabel,children:"Scan"})}),(o==="controls"||o==="free")&&t.imageUri&&(0,_jsxRuntime.jsx)(_sharedUi.PowerToggleButton,{isEnabled:t.enabled,onToggle:()=>_ImageOverlayController.ImageOverlayController.toggle(),accessibilityLabel:"Toggle image overlay"}),o!=="idle"&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.headerActionButton,onPress:B,activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_sharedUi.Trash2,{size:14,color:_sharedUi.night.color.textSecondary})})]})]})};const p=(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.container,children:[o==="idle"&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.homeContainer,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.homeSubtitle,children:"Choose a mode"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.modeGrid,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.modePanel,onPress:x,activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.modeIconCircle,{backgroundColor:_sharedUi.night.color.accentSoft}],children:(0,_jsxRuntime.jsx)(_sharedUi.SquareDashed,{size:24,color:_sharedUi.night.color.accent})}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.modePanelTitle,children:["Component","\n","Match"]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.modePanelDesc,children:"Overlay on a tagged component"})]}),(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.modePanel,onPress:()=>l("free"),activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.modeIconCircle,{backgroundColor:_sharedUi.night.color.accentSoft}],children:(0,_jsxRuntime.jsx)(_sharedUi.Image,{size:24,color:_sharedUi.night.color.accent})}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.modePanelTitle,children:["Free","\n","Placement"]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.modePanelDesc,children:"Drag and resize anywhere"})]})]})]}),o==="targets"&&(0,_jsxRuntime.jsx)(_TargetList.TargetList,{targets:y,onSelect:S}),o==="controls"&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.controlsContainer,children:[t.targetRect&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoCard,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Component"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoValue,children:t.targetLabel})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Size"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,children:[Math.round(t.targetRect.width)," x ",Math.round(t.targetRect.height)]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Position"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,children:[Math.round(t.targetRect.x),", ",Math.round(t.targetRect.y)]})]}),t.imageWidth!=null&&t.imageHeight!=null&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Image"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,children:[t.imageWidth," x ",t.imageHeight]})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.inputSection,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionLabel,children:"Image"}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.pasteButton,onPress:b,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.pasteButtonText,children:"Paste from Clipboard"})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.urlRow,children:[(0,_jsxRuntime.jsx)(_reactNative.TextInput,{style:styles.urlInput,value:n,onChangeText:i,placeholder:"or enter URL...",placeholderTextColor:_sharedUi.night.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:s}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.loadButton,!n.trim()&&styles.loadButtonDisabled],onPress:s,disabled:!n.trim(),activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.loadButtonText,children:"Load"})})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.toggleSection,children:[(0,_jsxRuntime.jsx)(_sharedUi.ToggleRow,{label:"Show Outline",value:t.showOutline,onValueChange:e=>_ImageOverlayController.ImageOverlayController.setShowOutline(e)}),(0,_jsxRuntime.jsx)(_sharedUi.ToggleRow,{label:"Auto Track",value:h,onValueChange:I}),t.imageUri&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.toggleLabel,children:"Opacity"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.blendButtons,children:[0,25,50,75,100].map(e=>(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,Math.round(t.opacity*100)===e&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.setOpacity(e/100),activeOpacity:.7,children:(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:[styles.blendButtonText,Math.round(t.opacity*100)===e&&styles.blendButtonTextActive],children:[e,"%"]})},e))})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.toggleLabel,children:"Flip"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendButtons,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,t.invertX&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.toggleInvertX(),activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.blendButtonText,t.invertX&&styles.blendButtonTextActive],children:"Horizontal"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,t.invertY&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.toggleInvertY(),activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.blendButtonText,t.invertY&&styles.blendButtonTextActive],children:"Vertical"})})]})]})]})]}),t.imageUri&&(0,_jsxRuntime.jsx)(_OverlayControls.OverlayControls,{opacity:t.opacity,scale:t.scale,offsetX:t.offsetX,offsetY:t.offsetY,onOpacityChange:e=>_ImageOverlayController.ImageOverlayController.setOpacity(e),onScaleChange:e=>_ImageOverlayController.ImageOverlayController.setScale(e),onOffsetChange:(e,a)=>_ImageOverlayController.ImageOverlayController.setOffset(e,a)}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.actions,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.actionButton,onPress:()=>_ImageOverlayController.ImageOverlayController.resetSettings(),activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.actionButtonText,children:"Reset Settings"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.actionButton,onPress:()=>_ImageOverlayController.ImageOverlayController.remeasure(),activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.actionButtonText,children:"Remeasure"})})]})]}),o==="free"&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.controlsContainer,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.inputSection,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionLabel,children:"Image"}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.pasteButton,onPress:b,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.pasteButtonText,children:"Paste from Clipboard"})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.urlRow,children:[(0,_jsxRuntime.jsx)(_reactNative.TextInput,{style:styles.urlInput,value:n,onChangeText:i,placeholder:"or enter URL...",placeholderTextColor:_sharedUi.night.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:s}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.loadButton,!n.trim()&&styles.loadButtonDisabled],onPress:s,disabled:!n.trim(),activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.loadButtonText,children:"Load"})})]})]}),t.imageUri&&t.mode==="free"&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoCard,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Position"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,children:[Math.round(t.freeX),", ",Math.round(t.freeY)]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Size"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,children:[Math.round(t.freeWidth)," x ",Math.round(t.freeHeight)]})]}),t.imageWidth!=null&&t.imageHeight!=null&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Original"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,children:[t.imageWidth," x ",t.imageHeight]})]})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.inputSection,children:(0,_jsxRuntime.jsx)(_OverlayControls.OverlayControls,{opacity:t.opacity,scale:1,offsetX:0,offsetY:0,onOpacityChange:e=>_ImageOverlayController.ImageOverlayController.setOpacity(e),onScaleChange:()=>{},onOffsetChange:()=>{},opacityOnly:true})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.toggleSection,children:[(0,_jsxRuntime.jsx)(_sharedUi.ToggleRow,{label:"Lock Position",tone:"warning",value:t.locked,onValueChange:e=>_ImageOverlayController.ImageOverlayController.setLocked(e)}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.toggleLabel,children:"Opacity"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.blendButtons,children:[0,25,50,75,100].map(e=>(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,Math.round(t.opacity*100)===e&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.setOpacity(e/100),activeOpacity:.7,children:(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:[styles.blendButtonText,Math.round(t.opacity*100)===e&&styles.blendButtonTextActive],children:[e,"%"]})},e))})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.toggleLabel,children:"Flip"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendButtons,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,t.invertX&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.toggleInvertX(),activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.blendButtonText,t.invertX&&styles.blendButtonTextActive],children:"Horizontal"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,t.invertY&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.toggleInvertY(),activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.blendButtonText,t.invertY&&styles.blendButtonTextActive],children:"Vertical"})})]})]})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.actions,children:(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.actionButton,onPress:()=>_ImageOverlayController.ImageOverlayController.resetSettings(),activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.actionButtonText,children:"Reset Position"})})})]})]})]});if(O){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.inlineRoot,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.inlineHeader,..._sharedUi.windowDragProps,children:f.customContent}),p]})}return(0,_jsxRuntime.jsx)(_sharedUi.JsModal,{visible:c,onClose:m,onMinimize:C,minimizeTargetPosition:v,initialModalState:j,header:f,initialMode:"bottomSheet",persistenceKey:"buoy-image-overlay-modal",enablePersistence:true,children:p})}function ImageOverlayToolView(c={}){return(0,_jsxRuntime.jsx)(ImageOverlayModal,{...c,inline:true,visible:true,onClose:()=>{}})}const styles=_reactNative.StyleSheet.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:_sharedUi.macOSColors.background.base},inlineHeader:{borderBottomWidth:1,borderBottomColor:_sharedUi.macOSColors.border.default,backgroundColor:"transparent"},container:{flex:1,backgroundColor:"transparent"},headerTextButton:{height:32,paddingHorizontal:12,borderRadius:8,backgroundColor:_sharedUi.night.color.buttonSurface,borderWidth:1,borderColor:_sharedUi.night.color.border,alignItems:"center",justifyContent:"center"},headerTextButtonLabel:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.accent},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:_sharedUi.night.color.buttonSurface,borderWidth:1,borderColor:_sharedUi.night.color.border,alignItems:"center",justifyContent:"center"},homeContainer:{flex:1,paddingHorizontal:12,paddingTop:16,paddingBottom:20,gap:12},homeSubtitle:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:.5,textAlign:"center"},modeGrid:{flexDirection:"row",gap:10},modePanel:{flex:1,alignItems:"center",paddingVertical:20,paddingHorizontal:12,backgroundColor:_sharedUi.night.color.surface,borderRadius:12,borderWidth:1,borderColor:_sharedUi.night.color.border,gap:8},modeIconCircle:{width:48,height:48,borderRadius:24,alignItems:"center",justifyContent:"center",marginBottom:4},modePanelTitle:{fontSize:13,fontWeight:"700",color:_sharedUi.night.color.text,textAlign:"center",lineHeight:17},modePanelDesc:{fontSize:11,color:_sharedUi.night.color.textTertiary,textAlign:"center",lineHeight:15},controlsContainer:{flex:1,paddingTop:8,paddingBottom:24,gap:10},infoCard:{marginHorizontal:12,backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:10,gap:4},infoRow:{flexDirection:"row",justifyContent:"space-between",alignItems:"center"},infoLabel:{fontSize:11,fontWeight:"500",color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:.3},infoValue:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.text},infoValueMono:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},inputSection:{paddingHorizontal:12,gap:6},sectionLabel:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},pasteButton:{paddingVertical:10,borderRadius:8,backgroundColor:_sharedUi.night.color.accentSoft,borderWidth:1,borderColor:_sharedUi.night.color.accentBorderStrong,alignItems:"center"},pasteButtonText:{fontSize:13,fontWeight:"600",color:_sharedUi.night.color.accent},urlRow:{flexDirection:"row",gap:8},urlInput:{flex:1,height:36,borderRadius:10,backgroundColor:_sharedUi.night.color.surfaceElevated,borderWidth:1,borderColor:_sharedUi.night.color.border,paddingHorizontal:12,fontSize:13,color:_sharedUi.night.color.text},loadButton:{height:36,paddingHorizontal:14,borderRadius:8,backgroundColor:_sharedUi.night.color.accent,justifyContent:"center",alignItems:"center"},loadButtonDisabled:{opacity:.4},loadButtonText:{fontSize:13,fontWeight:"600",color:_sharedUi.night.color.onAccent},toggleSection:{paddingHorizontal:12,gap:6},toggleRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,paddingHorizontal:12,paddingVertical:8},toggleLabel:{fontSize:13,fontWeight:"500",color:_sharedUi.night.color.textSecondary},blendRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,paddingHorizontal:12,paddingVertical:6},blendButtons:{flexDirection:"row",gap:4},blendButton:{paddingHorizontal:10,paddingVertical:5,borderRadius:6,backgroundColor:"transparent"},blendButtonActive:{backgroundColor:_sharedUi.night.color.accentSoft},blendButtonText:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.textTertiary},blendButtonTextActive:{color:_sharedUi.night.color.accent},actions:{flexDirection:"row",paddingHorizontal:12,gap:8,marginTop:4},actionButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",gap:6,paddingVertical:8,paddingHorizontal:12,borderRadius:8,backgroundColor:_sharedUi.night.color.surfaceElevated,borderWidth:1,borderColor:_sharedUi.night.color.border},actionButtonText:{fontSize:12,fontWeight:"500",color:_sharedUi.night.color.textSecondary}});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.ImageOverlayModal=ImageOverlayModal;exports.ImageOverlayToolView=ImageOverlayToolView;var _imageClipboard=require("../utils/imageClipboard");var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _ImageOverlayController=require("../utils/ImageOverlayController");var _fiberScanner=require("../utils/fiberScanner");var _TargetList=require("./TargetList");var _OverlayControls=require("./OverlayControls");var _jsxRuntime=require("react/jsx-runtime");let persistedImageUrl="";function ImageOverlayModal({visible:c,onClose:p,onBack:v,onMinimize:T,enableSharedModalDimensions:P=false,initialModalState:C,minimizeTargetPosition:j,inline:I=false,initialView:d}){const[o,l]=(0,_react.useState)(()=>{if(d)return d;const e=_ImageOverlayController.ImageOverlayController.getState();if(e.mode==="free")return"free";if(e.targetRect)return"controls";return"idle"});const[h,g]=(0,_react.useState)(()=>d==="targets"?(0,_fiberScanner.scanForImageTargets)():[]);const[t,O]=(0,_react.useState)(()=>_ImageOverlayController.ImageOverlayController.getState());const[n,i]=(0,_react.useState)(persistedImageUrl);const[u,w]=(0,_react.useState)(()=>_ImageOverlayController.ImageOverlayController.isAutoTracking());(0,_react.useEffect)(()=>{persistedImageUrl=n},[n]);(0,_react.useEffect)(()=>{return _ImageOverlayController.ImageOverlayController.subscribe(O)},[]);(0,_react.useEffect)(()=>{_ImageOverlayController.ImageOverlayController.setAutoTrack(u);return()=>{}},[u]);const b=(0,_react.useCallback)(()=>{const e=(0,_fiberScanner.scanForImageTargets)();g(e);l("targets")},[]);const S=(0,_react.useCallback)(async e=>{await _ImageOverlayController.ImageOverlayController.setTarget(e.instance,e.label,e.fiber);if(persistedImageUrl.trim()){await _ImageOverlayController.ImageOverlayController.setImageUri(persistedImageUrl.trim());_ImageOverlayController.ImageOverlayController.setEnabled(true)}l("controls")},[]);const s=(0,_react.useCallback)(async()=>{const e=persistedImageUrl.trim();if(!e)return;if(o==="free"){await _ImageOverlayController.ImageOverlayController.startFreeMode(e)}else{await _ImageOverlayController.ImageOverlayController.setImageUri(e);_ImageOverlayController.ImageOverlayController.setEnabled(true)}},[o]);const x=(0,_react.useCallback)(async()=>{let e=null;try{e=(0,_imageClipboard.loadImageClipboard)()}catch{}let a=null;if(!e){try{const r=(0,_imageClipboard.loadTextClipboard)();a=r.default||r}catch{}}if(!e&&!a){_reactNative.Alert.alert("Clipboard not available","Install expo-clipboard or @react-native-clipboard/clipboard to use paste.");return}try{if(e&&typeof e.hasImageAsync==="function"){const R=await e.hasImageAsync();if(R){const y=await e.getImageAsync({format:"png"});if(y?.data){if(o==="free"){await _ImageOverlayController.ImageOverlayController.startFreeMode(y.data)}else{await _ImageOverlayController.ImageOverlayController.setImageUri(y.data);_ImageOverlayController.ImageOverlayController.setEnabled(true)}return}}}let r=null;if(e&&typeof e.getStringAsync==="function"){r=await e.getStringAsync()}else if(a&&typeof a.getString==="function"){r=await a.getString()}if(r&&(r.startsWith("http")||r.startsWith("data:"))){i(r);persistedImageUrl=r;return}if(!e){_reactNative.Alert.alert("Image paste requires expo-clipboard","Your project uses @react-native-clipboard/clipboard which only supports text. Install expo-clipboard to paste images directly, or paste an image URL instead.")}else{_reactNative.Alert.alert("No image detected","Try saving your design image, opening it in Photos or Preview, and copying it from there.")}}catch{_reactNative.Alert.alert("Paste failed","Something went wrong reading the clipboard. Try copying the image again.")}},[o]);const B=(0,_react.useCallback)(()=>{_ImageOverlayController.ImageOverlayController.reset();persistedImageUrl="";l("idle");i("");g([])},[]);const V=(0,_react.useCallback)(()=>{if(o==="controls"){const e=(0,_fiberScanner.scanForImageTargets)();g(e);l("targets")}else if(o==="targets"||o==="free"){_ImageOverlayController.ImageOverlayController.reset();l("idle")}else{l("idle")}},[o]);const D=(()=>{switch(o){case"targets":return`Targets (${h.length})`;case"controls":return t.targetLabel||"Component Match";case"free":return"Free Placement";default:return"Image Overlay"}})();const m={showToggleButton:false,customContent:(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:o!=="idle"?V:v}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:D,testID:"buoy-image-overlay-title"}),(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader.Actions,{children:[o==="targets"&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.headerTextButton,onPress:b,testID:"buoy-image-overlay-scan",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.headerTextButtonLabel,children:"Scan"})}),(o==="controls"||o==="free")&&t.imageUri&&(0,_jsxRuntime.jsx)(_sharedUi.PowerToggleButton,{isEnabled:t.enabled,onToggle:()=>_ImageOverlayController.ImageOverlayController.toggle(),accessibilityLabel:"Toggle image overlay",testID:"buoy-image-overlay-power"}),o!=="idle"&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.headerActionButton,onPress:B,testID:"buoy-image-overlay-clear",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_sharedUi.Trash2,{size:14,color:_sharedUi.night.color.textSecondary})})]})]})};const f=(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.container,children:[o==="idle"&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.homeContainer,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.homeSubtitle,testID:"buoy-image-overlay-home",children:"Choose a mode"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.modeGrid,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.modePanel,onPress:b,testID:"buoy-image-overlay-mode-component",activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.modeIconCircle,{backgroundColor:_sharedUi.night.color.accentSoft}],children:(0,_jsxRuntime.jsx)(_sharedUi.SquareDashed,{size:24,color:_sharedUi.night.color.accent})}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.modePanelTitle,children:["Component","\n","Match"]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.modePanelDesc,children:"Overlay on a tagged component"})]}),(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.modePanel,onPress:()=>l("free"),testID:"buoy-image-overlay-mode-free",activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.modeIconCircle,{backgroundColor:_sharedUi.night.color.accentSoft}],children:(0,_jsxRuntime.jsx)(_sharedUi.Image,{size:24,color:_sharedUi.night.color.accent})}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.modePanelTitle,children:["Free","\n","Placement"]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.modePanelDesc,children:"Drag and resize anywhere"})]})]})]}),o==="targets"&&(0,_jsxRuntime.jsx)(_TargetList.TargetList,{targets:h,onSelect:S}),o==="controls"&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.controlsContainer,children:[t.targetRect&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoCard,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Component"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoValue,testID:"buoy-image-overlay-info-component",children:t.targetLabel})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Size"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(t.targetRect.width)," x ",Math.round(t.targetRect.height)]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Position"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(t.targetRect.x),", ",Math.round(t.targetRect.y)]})]}),t.imageWidth!=null&&t.imageHeight!=null&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Image"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-image",children:[t.imageWidth," x ",t.imageHeight]})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.inputSection,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionLabel,children:"Image"}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.pasteButton,onPress:x,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.pasteButtonText,children:"Paste from Clipboard"})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.urlRow,children:[(0,_jsxRuntime.jsx)(_reactNative.TextInput,{style:styles.urlInput,testID:"buoy-image-overlay-url",value:n,onChangeText:i,placeholder:"or enter URL...",placeholderTextColor:_sharedUi.night.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:s}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.loadButton,!n.trim()&&styles.loadButtonDisabled],onPress:s,disabled:!n.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.loadButtonText,children:"Load"})})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.toggleSection,children:[(0,_jsxRuntime.jsx)(_sharedUi.ToggleRow,{label:"Show Outline",testID:"buoy-image-overlay-outline-toggle",value:t.showOutline,onValueChange:e=>_ImageOverlayController.ImageOverlayController.setShowOutline(e)}),(0,_jsxRuntime.jsx)(_sharedUi.ToggleRow,{label:"Auto Track",value:u,onValueChange:w,testID:"buoy-image-overlay-autotrack"}),t.imageUri&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.toggleLabel,children:"Opacity"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.blendButtons,children:[0,25,50,75,100].map(e=>(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`buoy-image-overlay-opacity-${e}`,style:[styles.blendButton,Math.round(t.opacity*100)===e&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.setOpacity(e/100),activeOpacity:.7,children:(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:[styles.blendButtonText,Math.round(t.opacity*100)===e&&styles.blendButtonTextActive],children:[e,"%"]})},e))})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.toggleLabel,children:"Flip"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendButtons,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,t.invertX&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.blendButtonText,t.invertX&&styles.blendButtonTextActive],testID:t.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,t.invertY&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.blendButtonText,t.invertY&&styles.blendButtonTextActive],testID:t.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]})]}),t.imageUri&&(0,_jsxRuntime.jsx)(_OverlayControls.OverlayControls,{opacity:t.opacity,scale:t.scale,offsetX:t.offsetX,offsetY:t.offsetY,onOpacityChange:e=>_ImageOverlayController.ImageOverlayController.setOpacity(e),onScaleChange:e=>_ImageOverlayController.ImageOverlayController.setScale(e),onOffsetChange:(e,a)=>_ImageOverlayController.ImageOverlayController.setOffset(e,a)}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.actions,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.actionButton,onPress:()=>_ImageOverlayController.ImageOverlayController.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-settings",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.actionButtonText,children:"Reset Settings"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.actionButton,onPress:()=>_ImageOverlayController.ImageOverlayController.remeasure(),activeOpacity:.7,testID:"buoy-image-overlay-remeasure",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.actionButtonText,children:"Remeasure"})})]})]}),o==="free"&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.controlsContainer,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.inputSection,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionLabel,children:"Image"}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.pasteButton,onPress:x,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.pasteButtonText,children:"Paste from Clipboard"})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.urlRow,children:[(0,_jsxRuntime.jsx)(_reactNative.TextInput,{style:styles.urlInput,testID:"buoy-image-overlay-url",value:n,onChangeText:i,placeholder:"or enter URL...",placeholderTextColor:_sharedUi.night.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:s}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.loadButton,!n.trim()&&styles.loadButtonDisabled],onPress:s,disabled:!n.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.loadButtonText,children:"Load"})})]})]}),t.imageUri&&t.mode==="free"&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoCard,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Position"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(t.freeX),", ",Math.round(t.freeY)]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Size"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(t.freeWidth)," x ",Math.round(t.freeHeight)]})]}),t.imageWidth!=null&&t.imageHeight!=null&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.infoLabel,children:"Original"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.infoValueMono,testID:"buoy-image-overlay-info-original",children:[t.imageWidth," x ",t.imageHeight]})]})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.inputSection,children:(0,_jsxRuntime.jsx)(_OverlayControls.OverlayControls,{opacity:t.opacity,scale:1,offsetX:0,offsetY:0,onOpacityChange:e=>_ImageOverlayController.ImageOverlayController.setOpacity(e),onScaleChange:()=>{},onOffsetChange:()=>{},opacityOnly:true})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.toggleSection,children:[(0,_jsxRuntime.jsx)(_sharedUi.ToggleRow,{label:"Lock Position",testID:"buoy-image-overlay-lock",tone:"warning",value:t.locked,onValueChange:e=>_ImageOverlayController.ImageOverlayController.setLocked(e)}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.toggleLabel,children:"Opacity"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.blendButtons,children:[0,25,50,75,100].map(e=>(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`buoy-image-overlay-opacity-${e}`,style:[styles.blendButton,Math.round(t.opacity*100)===e&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.setOpacity(e/100),activeOpacity:.7,children:(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:[styles.blendButtonText,Math.round(t.opacity*100)===e&&styles.blendButtonTextActive],children:[e,"%"]})},e))})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.toggleLabel,children:"Flip"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.blendButtons,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,t.invertX&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.blendButtonText,t.invertX&&styles.blendButtonTextActive],testID:t.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.blendButton,t.invertY&&styles.blendButtonActive],onPress:()=>_ImageOverlayController.ImageOverlayController.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.blendButtonText,t.invertY&&styles.blendButtonTextActive],testID:t.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.actions,children:(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.actionButton,onPress:()=>_ImageOverlayController.ImageOverlayController.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-position",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.actionButtonText,children:"Reset Position"})})})]})]})]});if(I){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.inlineRoot,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.inlineHeader,..._sharedUi.windowDragProps,children:m.customContent}),f]})}return(0,_jsxRuntime.jsx)(_sharedUi.JsModal,{visible:c,onClose:p,onMinimize:T,minimizeTargetPosition:j,initialModalState:C,header:m,initialMode:"bottomSheet",persistenceKey:"buoy-image-overlay-modal",enablePersistence:true,children:f})}function ImageOverlayToolView(c={}){return(0,_jsxRuntime.jsx)(ImageOverlayModal,{...c,inline:true,visible:true,onClose:()=>{}})}const styles=_reactNative.StyleSheet.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:_sharedUi.macOSColors.background.base},inlineHeader:{borderBottomWidth:1,borderBottomColor:_sharedUi.macOSColors.border.default,backgroundColor:"transparent"},container:{flex:1,backgroundColor:"transparent"},headerTextButton:{height:32,paddingHorizontal:12,borderRadius:8,backgroundColor:_sharedUi.night.color.buttonSurface,borderWidth:1,borderColor:_sharedUi.night.color.border,alignItems:"center",justifyContent:"center"},headerTextButtonLabel:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.accent},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:_sharedUi.night.color.buttonSurface,borderWidth:1,borderColor:_sharedUi.night.color.border,alignItems:"center",justifyContent:"center"},homeContainer:{flex:1,paddingHorizontal:12,paddingTop:16,paddingBottom:20,gap:12},homeSubtitle:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:.5,textAlign:"center"},modeGrid:{flexDirection:"row",gap:10},modePanel:{flex:1,alignItems:"center",paddingVertical:20,paddingHorizontal:12,backgroundColor:_sharedUi.night.color.surface,borderRadius:12,borderWidth:1,borderColor:_sharedUi.night.color.border,gap:8},modeIconCircle:{width:48,height:48,borderRadius:24,alignItems:"center",justifyContent:"center",marginBottom:4},modePanelTitle:{fontSize:13,fontWeight:"700",color:_sharedUi.night.color.text,textAlign:"center",lineHeight:17},modePanelDesc:{fontSize:11,color:_sharedUi.night.color.textTertiary,textAlign:"center",lineHeight:15},controlsContainer:{flex:1,paddingTop:8,paddingBottom:24,gap:10},infoCard:{marginHorizontal:12,backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:10,gap:4},infoRow:{flexDirection:"row",justifyContent:"space-between",alignItems:"center"},infoLabel:{fontSize:11,fontWeight:"500",color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:.3},infoValue:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.text},infoValueMono:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},inputSection:{paddingHorizontal:12,gap:6},sectionLabel:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},pasteButton:{paddingVertical:10,borderRadius:8,backgroundColor:_sharedUi.night.color.accentSoft,borderWidth:1,borderColor:_sharedUi.night.color.accentBorderStrong,alignItems:"center"},pasteButtonText:{fontSize:13,fontWeight:"600",color:_sharedUi.night.color.accent},urlRow:{flexDirection:"row",gap:8},urlInput:{flex:1,height:36,borderRadius:10,backgroundColor:_sharedUi.night.color.surfaceElevated,borderWidth:1,borderColor:_sharedUi.night.color.border,paddingHorizontal:12,fontSize:13,color:_sharedUi.night.color.text},loadButton:{height:36,paddingHorizontal:14,borderRadius:8,backgroundColor:_sharedUi.night.color.accent,justifyContent:"center",alignItems:"center"},loadButtonDisabled:{opacity:.4},loadButtonText:{fontSize:13,fontWeight:"600",color:_sharedUi.night.color.onAccent},toggleSection:{paddingHorizontal:12,gap:6},toggleRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,paddingHorizontal:12,paddingVertical:8},toggleLabel:{fontSize:13,fontWeight:"500",color:_sharedUi.night.color.textSecondary},blendRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,paddingHorizontal:12,paddingVertical:6},blendButtons:{flexDirection:"row",gap:4},blendButton:{paddingHorizontal:10,paddingVertical:5,borderRadius:6,backgroundColor:"transparent"},blendButtonActive:{backgroundColor:_sharedUi.night.color.accentSoft},blendButtonText:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.textTertiary},blendButtonTextActive:{color:_sharedUi.night.color.accent},actions:{flexDirection:"row",paddingHorizontal:12,gap:8,marginTop:4},actionButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",gap:6,paddingVertical:8,paddingHorizontal:12,borderRadius:8,backgroundColor:_sharedUi.night.color.surfaceElevated,borderWidth:1,borderColor:_sharedUi.night.color.border},actionButtonText:{fontSize:12,fontWeight:"500",color:_sharedUi.night.color.textSecondary}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.ImageOverlayStandalone=ImageOverlayStandalone;var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _ImageOverlayController=require("../utils/ImageOverlayController");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(x,
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.ImageOverlayStandalone=ImageOverlayStandalone;var _react=_interopRequireWildcard(require("react"));var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _ImageOverlayController=require("../utils/ImageOverlayController");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(x,v){if("function"==typeof WeakMap)var w=new WeakMap,p=new WeakMap;return(_interopRequireWildcard=function(r,c){if(!c&&r&&r.__esModule)return r;var a,o,g={__proto__:null,default:r};if(null===r||"object"!=typeof r&&"function"!=typeof r)return g;if(a=c?p:w){if(a.has(r))return a.get(r);a.set(r,g)}for(const n in r)"default"!==n&&{}.hasOwnProperty.call(r,n)&&((o=(a=Object.defineProperty)&&Object.getOwnPropertyDescriptor(r,n))&&(o.get||o.set)?a(g,n,o):g[n]=r[n]);return g})(x,v)}function OverlayImage({uri:x,style:v,invertX:w,invertY:p}){const r=[];if(w)r.push({scaleX:-1});if(p)r.push({scaleY:-1});const c=r.length>0?{transform:r}:{};return(0,_jsxRuntime.jsx)(_reactNative.Image,{testID:"buoy-internal-image-overlay",source:{uri:x},style:[v,c],pointerEvents:"none"})}const FREE_MIN_SIZE=30;function FreePlacement({imageUri:x,x:v,y:w,width:p,height:r,opacity:c,aspectRatio:a,invertX:o,invertY:g,locked:n}){const[y,u]=(0,_react.useState)(false);const I=(0,_react.useRef)({x:0,y:0});const C=(0,_react.useRef)({x:0,y:0,width:0,height:0});const h=_reactNative.Dimensions.get("window");const _=(0,_react.useMemo)(()=>_reactNative.PanResponder.create({onStartShouldSetPanResponder:()=>!n,onMoveShouldSetPanResponder:(b,s)=>!n&&(Math.abs(s.dx)>2||Math.abs(s.dy)>2),onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{const b=_ImageOverlayController.ImageOverlayController.getState();I.current={x:b.freeX,y:b.freeY};u(true)},onPanResponderMove:(b,s)=>{const j=_ImageOverlayController.ImageOverlayController.getState();const f=Math.max(0,Math.min(I.current.x+s.dx,h.width-j.freeWidth));const d=Math.max(0,Math.min(I.current.y+s.dy,h.height-j.freeHeight));_ImageOverlayController.ImageOverlayController.setFreePosition(f,d)},onPanResponderRelease:()=>u(false),onPanResponderTerminate:()=>u(false)}),[h.width,h.height,n]);const R=(0,_react.useCallback)(b=>_reactNative.PanResponder.create({onStartShouldSetPanResponder:()=>!n,onMoveShouldSetPanResponder:()=>!n,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{const s=_ImageOverlayController.ImageOverlayController.getState();C.current={x:s.freeX,y:s.freeY,width:s.freeWidth,height:s.freeHeight};u(true)},onPanResponderMove:(s,j)=>{const{dx:f,dy:d}=j;if(Math.abs(f)<.5&&Math.abs(d)<.5)return;const e=C.current;const l=a>0?a:e.width/e.height;const O=Math.abs(f);const W=Math.abs(d);const P=O>=W;let t;let i;let M=e.x;let m=e.y;switch(b){case"bottomRight":{t=P?e.width+f:(e.height+d)*l;t=Math.max(FREE_MIN_SIZE,Math.min(t,h.width-e.x));i=t/l;break}case"bottomLeft":{t=P?e.width-f:(e.height+d)*l;t=Math.max(FREE_MIN_SIZE,t);i=t/l;M=e.x+e.width-t;M=Math.max(0,M);t=Math.min(t,e.x+e.width);i=t/l;break}case"topRight":{t=P?e.width+f:(e.height-d)*l;t=Math.max(FREE_MIN_SIZE,Math.min(t,h.width-e.x));i=t/l;m=e.y+e.height-i;m=Math.max(0,m);i=Math.min(i,e.y+e.height);t=i*l;break}case"topLeft":{t=P?e.width-f:(e.height-d)*l;t=Math.max(FREE_MIN_SIZE,t);i=t/l;M=e.x+e.width-t;m=e.y+e.height-i;M=Math.max(0,M);m=Math.max(0,m);t=Math.min(t,e.x+e.width);i=t/l;m=e.y+e.height-i;break}}t=Math.max(FREE_MIN_SIZE,Math.round(t));i=Math.max(FREE_MIN_SIZE,Math.round(i));_ImageOverlayController.ImageOverlayController.setFreeDimensions(t,i,Math.round(M),Math.round(m))},onPanResponderRelease:()=>u(false),onPanResponderTerminate:()=>u(false)}),[h.width,h.height,a,n]);const S=(0,_react.useMemo)(()=>({topLeft:R("topLeft"),topRight:R("topRight"),bottomLeft:R("bottomLeft"),bottomRight:R("bottomRight")}),[R]);const H={..._sharedUi.absoluteFill,opacity:c};return(0,_jsxRuntime.jsxs)(_reactNative.View,{testID:"buoy-image-overlay-free-box",style:{position:"absolute",left:v,top:w,width:p,height:r},pointerEvents:n?"none":"auto",children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:_reactNative.StyleSheet.absoluteFill,...n?{}:_.panHandlers,children:(0,_jsxRuntime.jsx)(OverlayImage,{uri:x,style:H,invertX:o,invertY:g})}),(0,_jsxRuntime.jsx)(_reactNative.View,{pointerEvents:"none",style:[styles.freeBorder,y&&styles.freeBorderActive,n&&styles.freeBorderLocked]}),!n&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.View,{...S.topLeft.panHandlers,style:[styles.cornerWrapper,{top:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.cornerHandle,y&&styles.cornerHandleActive]})}),(0,_jsxRuntime.jsx)(_reactNative.View,{...S.topRight.panHandlers,style:[styles.cornerWrapper,{top:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.cornerHandle,y&&styles.cornerHandleActive]})}),(0,_jsxRuntime.jsx)(_reactNative.View,{...S.bottomLeft.panHandlers,style:[styles.cornerWrapper,{bottom:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.cornerHandle,y&&styles.cornerHandleActive]})}),(0,_jsxRuntime.jsx)(_reactNative.View,{...S.bottomRight.panHandlers,style:[styles.cornerWrapper,{bottom:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.cornerHandle,y&&styles.cornerHandleActive]})})]})]})}function ImageOverlayStandalone(){const[x,v]=(0,_react.useState)(()=>_ImageOverlayController.ImageOverlayController.getState());(0,_react.useEffect)(()=>{return _ImageOverlayController.ImageOverlayController.subscribe(v)},[]);const{mode:w,enabled:p,imageUri:r,imageWidth:c,imageHeight:a,targetRect:o,targetLabel:g,showOutline:n,opacity:y,scale:u,offsetX:I,offsetY:C,invertX:h,invertY:_,locked:R,freeX:S,freeY:H,freeWidth:b,freeHeight:s}=x;const j=c&&a&&a>0?c/a:0;if(w==="free"&&p&&r){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:(0,_jsxRuntime.jsx)(FreePlacement,{imageUri:r,x:S,y:H,width:b,height:s,opacity:y,aspectRatio:j,invertX:h,invertY:_,locked:R})})}if(!o)return null;const f=p&&r;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:[n&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.View,{pointerEvents:"none",nativeID:"__image_overlay_highlight__",testID:"buoy-image-overlay-outline",style:[styles.highlight,{left:o.x-3,top:o.y-3,width:o.width+6,height:o.height+6}]}),g&&(0,_jsxRuntime.jsx)(_reactNative.View,{pointerEvents:"none",style:[styles.label,{left:o.x,top:o.y-20}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.labelText,testID:"buoy-image-overlay-outline-label",children:g})})]}),f&&(()=>{const d=(c??o.width)*u;const e=(a??o.height)*u;const l=o.x+o.width/2;const O=o.y+o.height/2;const W={position:"absolute",left:l-d/2+I,top:O-e/2+C,width:d,height:e,opacity:y};return(0,_jsxRuntime.jsx)(OverlayImage,{uri:r,style:W,invertX:h,invertY:_})})()]})}const styles=_reactNative.StyleSheet.create({overlay:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:_reactNative.Platform.OS==="web"?999:999999,elevation:999999,borderWidth:0},highlight:{position:"absolute",borderWidth:2,borderStyle:"dashed",borderColor:"#20C997",backgroundColor:"transparent"},label:{position:"absolute",backgroundColor:"#20C997",paddingHorizontal:6,paddingVertical:2,borderRadius:3},labelText:{color:"#fff",fontSize:10,fontWeight:"700",fontFamily:_sharedUi.monoFont},freeBorder:{position:"absolute",top:-6,left:-6,right:-6,bottom:-6,borderWidth:1,borderColor:"transparent",borderRadius:4},freeBorderActive:{borderColor:"#20C997",borderStyle:"dashed"},freeBorderLocked:{borderColor:"#f59e0b",borderStyle:"solid"},cornerWrapper:{position:"absolute",width:24,height:24,zIndex:1e3,alignItems:"center",justifyContent:"center"},cornerHandle:{width:12,height:12,borderRadius:6,backgroundColor:"#20C997",borderWidth:2,borderColor:"#fff"},cornerHandleActive:{backgroundColor:"#10b981",shadowColor:"#10b981",shadowOffset:{width:0,height:0},shadowOpacity:.8,shadowRadius:6}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.OverlayControls=OverlayControls;var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _jsxRuntime=require("react/jsx-runtime");function SliderStepper({label:
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.OverlayControls=OverlayControls;var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _jsxRuntime=require("react/jsx-runtime");function SliderStepper({label:a,testID:n,value:o,min:t,max:r,step:i,displayValue:c,onChange:l}){const s=(0,_react.useRef)(0);const h=(0,_react.useRef)(0);const u=(0,_react.useCallback)(e=>Math.max(t,Math.min(r,e)),[t,r]);const p=r>t?(o-t)/(r-t):0;const x=(0,_react.useRef)(l);const y=(0,_react.useRef)(u);const d=(0,_react.useRef)(t);const g=(0,_react.useRef)(r);x.current=l;y.current=u;d.current=t;g.current=r;const b=(0,_react.useCallback)(e=>{const v=e-h.current;const m=Math.max(0,Math.min(1,v/s.current));const R=d.current+m*(g.current-d.current);x.current(y.current(R))},[]);const j=(0,_react.useRef)(_reactNative.PanResponder.create({onStartShouldSetPanResponder:()=>true,onMoveShouldSetPanResponder:()=>true,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:e=>{b(e.nativeEvent.pageX)},onPanResponderMove:e=>{b(e.nativeEvent.pageX)}})).current;const T=(0,_react.useCallback)(e=>{s.current=e.nativeEvent.layout.width},[]);const f=(0,_react.useRef)(null);const w=(0,_react.useCallback)(()=>{f.current?.measure?.((e,v,m,R,S)=>{h.current=S})},[]);return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.controlRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.label,children:a}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.controlRight,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.stepperButton,onPress:()=>l(u(o-i)),testID:`${n}-minus`,activeOpacity:.6,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.stepperButtonText,children:"-"})}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.sliderHitArea,...j.panHandlers,testID:n,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{ref:f,style:styles.sliderTrack,onLayout:e=>{T(e);w()},pointerEvents:"none",children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.sliderFill,{width:`${p*100}%`}]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.sliderThumb,{left:`${p*100}%`}]})]})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.stepperButton,onPress:()=>l(u(o+i)),testID:`${n}-plus`,activeOpacity:.6,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.stepperButtonText,children:"+"})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.valueText,testID:`${n}-value`,children:c})]})]})}function OverlayControls({opacity:a,scale:n,offsetX:o,offsetY:t,onOpacityChange:r,onScaleChange:i,onOffsetChange:c,opacityOnly:l}){if(l){return(0,_jsxRuntime.jsx)(SliderStepper,{label:"Opacity",testID:"buoy-image-overlay-slider-opacity",value:a,min:0,max:1,step:.05,displayValue:`${Math.round(a*100)}%`,onChange:r})}return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.container,children:[(0,_jsxRuntime.jsx)(SliderStepper,{label:"Opacity",testID:"buoy-image-overlay-slider-opacity",value:a,min:0,max:1,step:.05,displayValue:`${Math.round(a*100)}%`,onChange:r}),(0,_jsxRuntime.jsx)(SliderStepper,{label:"Scale",testID:"buoy-image-overlay-slider-scale",value:n,min:.05,max:3,step:.05,displayValue:`${Math.round(n*100)}%`,onChange:i}),(0,_jsxRuntime.jsx)(SliderStepper,{label:"Offset X",testID:"buoy-image-overlay-slider-offset-x",value:o,min:-200,max:200,step:2,displayValue:`${Math.round(o)}px`,onChange:s=>c(Math.round(s),t)}),(0,_jsxRuntime.jsx)(SliderStepper,{label:"Offset Y",testID:"buoy-image-overlay-slider-offset-y",value:t,min:-200,max:200,step:2,displayValue:`${Math.round(t)}px`,onChange:s=>c(o,Math.round(s))})]})}const THUMB_SIZE=18;const styles=_reactNative.StyleSheet.create({container:{gap:8},controlRow:{paddingHorizontal:12,gap:4},label:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},controlRight:{flexDirection:"row",alignItems:"center",gap:6},stepperButton:{zIndex:1,width:28,height:28,borderRadius:6,backgroundColor:_sharedUi.night.color.surfaceElevated,borderWidth:1,borderColor:_sharedUi.night.color.border,justifyContent:"center",alignItems:"center"},stepperButtonText:{fontSize:16,fontWeight:"700",color:_sharedUi.night.color.text,lineHeight:18},sliderHitArea:{flex:1,paddingVertical:20,paddingHorizontal:40,marginVertical:-20,marginHorizontal:-40},sliderTrack:{height:28,justifyContent:"center",borderRadius:6,backgroundColor:_sharedUi.night.color.bg,borderWidth:1,borderColor:_sharedUi.night.color.border,overflow:"hidden"},sliderFill:{position:"absolute",left:0,top:0,bottom:0,backgroundColor:_sharedUi.night.color.accentFill,borderRadius:5},sliderThumb:{position:"absolute",width:4,top:4,bottom:4,marginLeft:-2,borderRadius:2,backgroundColor:_sharedUi.night.color.accent},valueText:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.text,width:45,textAlign:"right",fontFamily:_sharedUi.monoFont}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.TargetList=TargetList;var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _jsxRuntime=require("react/jsx-runtime");function TargetRow({target:e,onSelect:t}){return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.card,onPress:t,activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.colorIndicator}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.content,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.topRow,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.label,numberOfLines:1,children:e.label})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.bottomRow,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.badgeRow,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.testIdBadge,children:[(0,_jsxRuntime.jsx)(_sharedUi.Hash,{size:8,color:_sharedUi.night.color.accent}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.testIdBadgeText,children:"testID"})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.testIdValue,numberOfLines:1,children:e.testID})]}),e.componentName&&(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.componentName,numberOfLines:1,children:e.componentName})]})]}),(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:16,color:_sharedUi.night.color.textTertiary})]})}function TargetList({targets:e,onSelect:t}){if(e.length===0){return(0,_jsxRuntime.jsx)(_sharedUi.ToolEmptyState,{testID:"buoy-image-overlay-empty",otto:"scanning",title:"No targets found",message:'Tag components with\ntestID="image-target:YourLabel"'})}return(0,_jsxRuntime.jsx)(_reactNative.ScrollView,{style:styles.list,contentContainerStyle:styles.listContent,children:e.map(o=>(0,_jsxRuntime.jsx)(TargetRow,{target:o,onSelect:()=>t(o)},o.testID))})}const styles=_reactNative.StyleSheet.create({list:{flex:1},listContent:{paddingTop:8,paddingBottom:20},card:{flexDirection:"row",alignItems:"center",paddingVertical:10,paddingHorizontal:12,marginHorizontal:12,marginBottom:6,backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border},colorIndicator:{width:4,height:36,borderRadius:2,marginRight:10,backgroundColor:_sharedUi.night.color.accent},content:{flex:1,marginRight:8},topRow:{flexDirection:"row",alignItems:"center",marginBottom:4},label:{fontSize:13,fontWeight:"600",color:_sharedUi.night.color.text,flex:1},bottomRow:{gap:2},badgeRow:{flexDirection:"row",alignItems:"center",gap:4},testIdBadge:{flexDirection:"row",alignItems:"center",paddingVertical:2,paddingHorizontal:5,borderRadius:4,backgroundColor:_sharedUi.night.color.accentSoft,gap:3},testIdBadgeText:{fontSize:9,fontWeight:"700",color:_sharedUi.night.color.accent},testIdValue:{fontSize:11,color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont,flex:1},componentName:{fontSize:10,color:"#a855f7",fontFamily:_sharedUi.monoFont,marginTop:1},emptyState:{alignItems:"center",paddingVertical:40,paddingHorizontal:32},emptyTitle:{color:_sharedUi.night.color.text,fontSize:14,fontWeight:"600",marginBottom:6},emptyText:{color:_sharedUi.night.color.textTertiary,fontSize:12,textAlign:"center",lineHeight:18,fontFamily:_sharedUi.monoFont}});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.TargetList=TargetList;var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _jsxRuntime=require("react/jsx-runtime");function TargetRow({target:e,onSelect:t}){return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.card,onPress:t,activeOpacity:.7,testID:`buoy-image-overlay-target-${e.label}`,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.colorIndicator}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.content,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.topRow,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.label,numberOfLines:1,testID:`buoy-image-overlay-target-${e.label}-label`,children:e.label})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.bottomRow,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.badgeRow,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.testIdBadge,children:[(0,_jsxRuntime.jsx)(_sharedUi.Hash,{size:8,color:_sharedUi.night.color.accent}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.testIdBadgeText,children:"testID"})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.testIdValue,numberOfLines:1,testID:`buoy-image-overlay-target-${e.label}-testid`,children:e.testID})]}),e.componentName&&(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.componentName,numberOfLines:1,testID:`buoy-image-overlay-target-${e.label}-component`,children:e.componentName})]})]}),(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:16,color:_sharedUi.night.color.textTertiary})]})}function TargetList({targets:e,onSelect:t}){if(e.length===0){return(0,_jsxRuntime.jsx)(_sharedUi.ToolEmptyState,{testID:"buoy-image-overlay-empty",otto:"scanning",title:"No targets found",message:'Tag components with\ntestID="image-target:YourLabel"'})}return(0,_jsxRuntime.jsx)(_reactNative.ScrollView,{style:styles.list,contentContainerStyle:styles.listContent,children:e.map(o=>(0,_jsxRuntime.jsx)(TargetRow,{target:o,onSelect:()=>t(o)},o.testID))})}const styles=_reactNative.StyleSheet.create({list:{flex:1},listContent:{paddingTop:8,paddingBottom:20},card:{flexDirection:"row",alignItems:"center",paddingVertical:10,paddingHorizontal:12,marginHorizontal:12,marginBottom:6,backgroundColor:_sharedUi.night.color.surface,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border},colorIndicator:{width:4,height:36,borderRadius:2,marginRight:10,backgroundColor:_sharedUi.night.color.accent},content:{flex:1,marginRight:8},topRow:{flexDirection:"row",alignItems:"center",marginBottom:4},label:{fontSize:13,fontWeight:"600",color:_sharedUi.night.color.text,flex:1},bottomRow:{gap:2},badgeRow:{flexDirection:"row",alignItems:"center",gap:4},testIdBadge:{flexDirection:"row",alignItems:"center",paddingVertical:2,paddingHorizontal:5,borderRadius:4,backgroundColor:_sharedUi.night.color.accentSoft,gap:3},testIdBadgeText:{fontSize:9,fontWeight:"700",color:_sharedUi.night.color.accent},testIdValue:{fontSize:11,color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont,flex:1},componentName:{fontSize:10,color:"#a855f7",fontFamily:_sharedUi.monoFont,marginTop:1},emptyState:{alignItems:"center",paddingVertical:40,paddingHorizontal:32},emptyTitle:{color:_sharedUi.night.color.text,fontSize:14,fontWeight:"600",marginBottom:6},emptyText:{color:_sharedUi.night.color.textTertiary,fontSize:12,textAlign:"center",lineHeight:18,fontFamily:_sharedUi.monoFont}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{loadImageClipboard as Q,loadTextClipboard as Z}from"../utils/imageClipboard";import{useState as p,useEffect as I,useCallback as f}from"react";import{View as a,Text as i,TextInput as W,TouchableOpacity as s,StyleSheet as ee,Alert as C}from"react-native";import{JsModal as te,ModalHeader as T,macOSColors as H,night as l,Trash2 as oe,SquareDashed as ne,Image as re,PowerToggleButton as le,windowDragProps as ie,ToggleRow as P,monoFont as ae}from"@buoy-gg/shared-ui";import{ImageOverlayController as c}from"../utils/ImageOverlayController";import{scanForImageTargets as O}from"../utils/fiberScanner";import{TargetList as ce}from"./TargetList";import{OverlayControls as V}from"./OverlayControls";import{jsx as t,jsxs as r,Fragment as D}from"react/jsx-runtime";let b="";export function ImageOverlayModal({visible:B,onClose:j,onBack:U,onMinimize:E,enableSharedModalDimensions:de=false,initialModalState:F,minimizeTargetPosition:Y,inline:X=false,initialView:v}){const[d,h]=p(()=>{if(v)return v;const o=c.getState();if(o.mode==="free")return"free";if(o.targetRect)return"controls";return"idle"});const[z,S]=p(()=>v==="targets"?O():[]);const[n,K]=p(()=>c.getState());const[u,m]=p(b);const[w,_]=p(()=>c.isAutoTracking());I(()=>{b=u},[u]);I(()=>{return c.subscribe(K)},[]);I(()=>{c.setAutoTrack(w);return()=>{}},[w]);const L=f(()=>{const o=O();S(o);h("targets")},[]);const q=f(async o=>{await c.setTarget(o.instance,o.label,o.fiber);if(b.trim()){await c.setImageUri(b.trim());c.setEnabled(true)}h("controls")},[]);const x=f(async()=>{const o=b.trim();if(!o)return;if(d==="free"){await c.startFreeMode(o)}else{await c.setImageUri(o);c.setEnabled(true)}},[d]);const A=f(async()=>{let o=null;try{o=Q()}catch{}let y=null;if(!o){try{const g=Z();y=g.default||g}catch{}}if(!o&&!y){C.alert("Clipboard not available","Install expo-clipboard or @react-native-clipboard/clipboard to use paste.");return}try{if(o&&typeof o.hasImageAsync==="function"){const $=await o.hasImageAsync();if($){const R=await o.getImageAsync({format:"png"});if(R?.data){if(d==="free"){await c.startFreeMode(R.data)}else{await c.setImageUri(R.data);c.setEnabled(true)}return}}}let g=null;if(o&&typeof o.getStringAsync==="function"){g=await o.getStringAsync()}else if(y&&typeof y.getString==="function"){g=await y.getString()}if(g&&(g.startsWith("http")||g.startsWith("data:"))){m(g);b=g;return}if(!o){C.alert("Image paste requires expo-clipboard","Your project uses @react-native-clipboard/clipboard which only supports text. Install expo-clipboard to paste images directly, or paste an image URL instead.")}else{C.alert("No image detected","Try saving your design image, opening it in Photos or Preview, and copying it from there.")}}catch{C.alert("Paste failed","Something went wrong reading the clipboard. Try copying the image again.")}},[d]);const G=f(()=>{c.reset();b="";h("idle");m("");S([])},[]);const N=f(()=>{if(d==="controls"){const o=O();S(o);h("targets")}else if(d==="targets"||d==="free"){c.reset();h("idle")}else{h("idle")}},[d]);const J=(()=>{switch(d){case"targets":return`Targets (${z.length})`;case"controls":return n.targetLabel||"Component Match";case"free":return"Free Placement";default:return"Image Overlay"}})();const M={showToggleButton:false,customContent:r(T,{children:[t(T.Navigation,{onBack:d!=="idle"?N:U}),t(T.Content,{title:J}),r(T.Actions,{children:[d==="targets"&&t(s,{style:e.headerTextButton,onPress:L,activeOpacity:.7,children:t(i,{style:e.headerTextButtonLabel,children:"Scan"})}),(d==="controls"||d==="free")&&n.imageUri&&t(le,{isEnabled:n.enabled,onToggle:()=>c.toggle(),accessibilityLabel:"Toggle image overlay"}),d!=="idle"&&t(s,{style:e.headerActionButton,onPress:G,activeOpacity:.7,children:t(oe,{size:14,color:l.color.textSecondary})})]})]})};const k=r(a,{style:e.container,children:[d==="idle"&&r(a,{style:e.homeContainer,children:[t(i,{style:e.homeSubtitle,children:"Choose a mode"}),r(a,{style:e.modeGrid,children:[r(s,{style:e.modePanel,onPress:L,activeOpacity:.7,children:[t(a,{style:[e.modeIconCircle,{backgroundColor:l.color.accentSoft}],children:t(ne,{size:24,color:l.color.accent})}),r(i,{style:e.modePanelTitle,children:["Component","\n","Match"]}),t(i,{style:e.modePanelDesc,children:"Overlay on a tagged component"})]}),r(s,{style:e.modePanel,onPress:()=>h("free"),activeOpacity:.7,children:[t(a,{style:[e.modeIconCircle,{backgroundColor:l.color.accentSoft}],children:t(re,{size:24,color:l.color.accent})}),r(i,{style:e.modePanelTitle,children:["Free","\n","Placement"]}),t(i,{style:e.modePanelDesc,children:"Drag and resize anywhere"})]})]})]}),d==="targets"&&t(ce,{targets:z,onSelect:q}),d==="controls"&&r(a,{style:e.controlsContainer,children:[n.targetRect&&r(a,{style:e.infoCard,children:[r(a,{style:e.infoRow,children:[t(i,{style:e.infoLabel,children:"Component"}),t(i,{style:e.infoValue,children:n.targetLabel})]}),r(a,{style:e.infoRow,children:[t(i,{style:e.infoLabel,children:"Size"}),r(i,{style:e.infoValueMono,children:[Math.round(n.targetRect.width)," x ",Math.round(n.targetRect.height)]})]}),r(a,{style:e.infoRow,children:[t(i,{style:e.infoLabel,children:"Position"}),r(i,{style:e.infoValueMono,children:[Math.round(n.targetRect.x),", ",Math.round(n.targetRect.y)]})]}),n.imageWidth!=null&&n.imageHeight!=null&&r(a,{style:e.infoRow,children:[t(i,{style:e.infoLabel,children:"Image"}),r(i,{style:e.infoValueMono,children:[n.imageWidth," x ",n.imageHeight]})]})]}),r(a,{style:e.inputSection,children:[t(i,{style:e.sectionLabel,children:"Image"}),t(s,{style:e.pasteButton,onPress:A,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",children:t(i,{style:e.pasteButtonText,children:"Paste from Clipboard"})}),r(a,{style:e.urlRow,children:[t(W,{style:e.urlInput,value:u,onChangeText:m,placeholder:"or enter URL...",placeholderTextColor:l.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:x}),t(s,{style:[e.loadButton,!u.trim()&&e.loadButtonDisabled],onPress:x,disabled:!u.trim(),activeOpacity:.7,children:t(i,{style:e.loadButtonText,children:"Load"})})]})]}),r(a,{style:e.toggleSection,children:[t(P,{label:"Show Outline",value:n.showOutline,onValueChange:o=>c.setShowOutline(o)}),t(P,{label:"Auto Track",value:w,onValueChange:_}),n.imageUri&&r(D,{children:[r(a,{style:e.blendRow,children:[t(i,{style:e.toggleLabel,children:"Opacity"}),t(a,{style:e.blendButtons,children:[0,25,50,75,100].map(o=>t(s,{style:[e.blendButton,Math.round(n.opacity*100)===o&&e.blendButtonActive],onPress:()=>c.setOpacity(o/100),activeOpacity:.7,children:r(i,{style:[e.blendButtonText,Math.round(n.opacity*100)===o&&e.blendButtonTextActive],children:[o,"%"]})},o))})]}),r(a,{style:e.blendRow,children:[t(i,{style:e.toggleLabel,children:"Flip"}),r(a,{style:e.blendButtons,children:[t(s,{style:[e.blendButton,n.invertX&&e.blendButtonActive],onPress:()=>c.toggleInvertX(),activeOpacity:.7,children:t(i,{style:[e.blendButtonText,n.invertX&&e.blendButtonTextActive],children:"Horizontal"})}),t(s,{style:[e.blendButton,n.invertY&&e.blendButtonActive],onPress:()=>c.toggleInvertY(),activeOpacity:.7,children:t(i,{style:[e.blendButtonText,n.invertY&&e.blendButtonTextActive],children:"Vertical"})})]})]})]})]}),n.imageUri&&t(V,{opacity:n.opacity,scale:n.scale,offsetX:n.offsetX,offsetY:n.offsetY,onOpacityChange:o=>c.setOpacity(o),onScaleChange:o=>c.setScale(o),onOffsetChange:(o,y)=>c.setOffset(o,y)}),r(a,{style:e.actions,children:[t(s,{style:e.actionButton,onPress:()=>c.resetSettings(),activeOpacity:.7,children:t(i,{style:e.actionButtonText,children:"Reset Settings"})}),t(s,{style:e.actionButton,onPress:()=>c.remeasure(),activeOpacity:.7,children:t(i,{style:e.actionButtonText,children:"Remeasure"})})]})]}),d==="free"&&r(a,{style:e.controlsContainer,children:[r(a,{style:e.inputSection,children:[t(i,{style:e.sectionLabel,children:"Image"}),t(s,{style:e.pasteButton,onPress:A,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",children:t(i,{style:e.pasteButtonText,children:"Paste from Clipboard"})}),r(a,{style:e.urlRow,children:[t(W,{style:e.urlInput,value:u,onChangeText:m,placeholder:"or enter URL...",placeholderTextColor:l.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:x}),t(s,{style:[e.loadButton,!u.trim()&&e.loadButtonDisabled],onPress:x,disabled:!u.trim(),activeOpacity:.7,children:t(i,{style:e.loadButtonText,children:"Load"})})]})]}),n.imageUri&&n.mode==="free"&&r(D,{children:[r(a,{style:e.infoCard,children:[r(a,{style:e.infoRow,children:[t(i,{style:e.infoLabel,children:"Position"}),r(i,{style:e.infoValueMono,children:[Math.round(n.freeX),", ",Math.round(n.freeY)]})]}),r(a,{style:e.infoRow,children:[t(i,{style:e.infoLabel,children:"Size"}),r(i,{style:e.infoValueMono,children:[Math.round(n.freeWidth)," x ",Math.round(n.freeHeight)]})]}),n.imageWidth!=null&&n.imageHeight!=null&&r(a,{style:e.infoRow,children:[t(i,{style:e.infoLabel,children:"Original"}),r(i,{style:e.infoValueMono,children:[n.imageWidth," x ",n.imageHeight]})]})]}),t(a,{style:e.inputSection,children:t(V,{opacity:n.opacity,scale:1,offsetX:0,offsetY:0,onOpacityChange:o=>c.setOpacity(o),onScaleChange:()=>{},onOffsetChange:()=>{},opacityOnly:true})}),r(a,{style:e.toggleSection,children:[t(P,{label:"Lock Position",tone:"warning",value:n.locked,onValueChange:o=>c.setLocked(o)}),r(a,{style:e.blendRow,children:[t(i,{style:e.toggleLabel,children:"Opacity"}),t(a,{style:e.blendButtons,children:[0,25,50,75,100].map(o=>t(s,{style:[e.blendButton,Math.round(n.opacity*100)===o&&e.blendButtonActive],onPress:()=>c.setOpacity(o/100),activeOpacity:.7,children:r(i,{style:[e.blendButtonText,Math.round(n.opacity*100)===o&&e.blendButtonTextActive],children:[o,"%"]})},o))})]}),r(a,{style:e.blendRow,children:[t(i,{style:e.toggleLabel,children:"Flip"}),r(a,{style:e.blendButtons,children:[t(s,{style:[e.blendButton,n.invertX&&e.blendButtonActive],onPress:()=>c.toggleInvertX(),activeOpacity:.7,children:t(i,{style:[e.blendButtonText,n.invertX&&e.blendButtonTextActive],children:"Horizontal"})}),t(s,{style:[e.blendButton,n.invertY&&e.blendButtonActive],onPress:()=>c.toggleInvertY(),activeOpacity:.7,children:t(i,{style:[e.blendButtonText,n.invertY&&e.blendButtonTextActive],children:"Vertical"})})]})]})]}),t(a,{style:e.actions,children:t(s,{style:e.actionButton,onPress:()=>c.resetSettings(),activeOpacity:.7,children:t(i,{style:e.actionButtonText,children:"Reset Position"})})})]})]})]});if(X){return r(a,{style:e.inlineRoot,children:[t(a,{style:e.inlineHeader,...ie,children:M.customContent}),k]})}return t(te,{visible:B,onClose:j,onMinimize:E,minimizeTargetPosition:Y,initialModalState:F,header:M,initialMode:"bottomSheet",persistenceKey:"buoy-image-overlay-modal",enablePersistence:true,children:k})}export function ImageOverlayToolView(B={}){return t(ImageOverlayModal,{...B,inline:true,visible:true,onClose:()=>{}})}const e=ee.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:H.background.base},inlineHeader:{borderBottomWidth:1,borderBottomColor:H.border.default,backgroundColor:"transparent"},container:{flex:1,backgroundColor:"transparent"},headerTextButton:{height:32,paddingHorizontal:12,borderRadius:8,backgroundColor:l.color.buttonSurface,borderWidth:1,borderColor:l.color.border,alignItems:"center",justifyContent:"center"},headerTextButtonLabel:{fontSize:12,fontWeight:"600",color:l.color.accent},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:l.color.buttonSurface,borderWidth:1,borderColor:l.color.border,alignItems:"center",justifyContent:"center"},homeContainer:{flex:1,paddingHorizontal:12,paddingTop:16,paddingBottom:20,gap:12},homeSubtitle:{fontSize:12,fontWeight:"600",color:l.color.textTertiary,textTransform:"uppercase",letterSpacing:.5,textAlign:"center"},modeGrid:{flexDirection:"row",gap:10},modePanel:{flex:1,alignItems:"center",paddingVertical:20,paddingHorizontal:12,backgroundColor:l.color.surface,borderRadius:12,borderWidth:1,borderColor:l.color.border,gap:8},modeIconCircle:{width:48,height:48,borderRadius:24,alignItems:"center",justifyContent:"center",marginBottom:4},modePanelTitle:{fontSize:13,fontWeight:"700",color:l.color.text,textAlign:"center",lineHeight:17},modePanelDesc:{fontSize:11,color:l.color.textTertiary,textAlign:"center",lineHeight:15},controlsContainer:{flex:1,paddingTop:8,paddingBottom:24,gap:10},infoCard:{marginHorizontal:12,backgroundColor:l.color.surface,borderRadius:8,borderWidth:1,borderColor:l.color.border,padding:10,gap:4},infoRow:{flexDirection:"row",justifyContent:"space-between",alignItems:"center"},infoLabel:{fontSize:11,fontWeight:"500",color:l.color.textTertiary,textTransform:"uppercase",letterSpacing:.3},infoValue:{fontSize:12,fontWeight:"600",color:l.color.text},infoValueMono:{fontSize:12,fontWeight:"600",color:l.color.text,fontFamily:ae},inputSection:{paddingHorizontal:12,gap:6},sectionLabel:{fontSize:11,fontWeight:"600",color:l.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},pasteButton:{paddingVertical:10,borderRadius:8,backgroundColor:l.color.accentSoft,borderWidth:1,borderColor:l.color.accentBorderStrong,alignItems:"center"},pasteButtonText:{fontSize:13,fontWeight:"600",color:l.color.accent},urlRow:{flexDirection:"row",gap:8},urlInput:{flex:1,height:36,borderRadius:10,backgroundColor:l.color.surfaceElevated,borderWidth:1,borderColor:l.color.border,paddingHorizontal:12,fontSize:13,color:l.color.text},loadButton:{height:36,paddingHorizontal:14,borderRadius:8,backgroundColor:l.color.accent,justifyContent:"center",alignItems:"center"},loadButtonDisabled:{opacity:.4},loadButtonText:{fontSize:13,fontWeight:"600",color:l.color.onAccent},toggleSection:{paddingHorizontal:12,gap:6},toggleRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:l.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:l.color.border,paddingHorizontal:12,paddingVertical:8},toggleLabel:{fontSize:13,fontWeight:"500",color:l.color.textSecondary},blendRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:l.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:l.color.border,paddingHorizontal:12,paddingVertical:6},blendButtons:{flexDirection:"row",gap:4},blendButton:{paddingHorizontal:10,paddingVertical:5,borderRadius:6,backgroundColor:"transparent"},blendButtonActive:{backgroundColor:l.color.accentSoft},blendButtonText:{fontSize:12,fontWeight:"600",color:l.color.textTertiary},blendButtonTextActive:{color:l.color.accent},actions:{flexDirection:"row",paddingHorizontal:12,gap:8,marginTop:4},actionButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",gap:6,paddingVertical:8,paddingHorizontal:12,borderRadius:8,backgroundColor:l.color.surfaceElevated,borderWidth:1,borderColor:l.color.border},actionButtonText:{fontSize:12,fontWeight:"500",color:l.color.textSecondary}});
|
|
1
|
+
"use strict";import{loadImageClipboard as Q,loadTextClipboard as Z}from"../utils/imageClipboard";import{useState as m,useEffect as D,useCallback as f}from"react";import{View as a,Text as l,TextInput as M,TouchableOpacity as d,StyleSheet as ee,Alert as x}from"react-native";import{JsModal as te,ModalHeader as C,macOSColors as W,night as i,Trash2 as oe,SquareDashed as ne,Image as re,PowerToggleButton as ie,windowDragProps as le,ToggleRow as R,monoFont as ae}from"@buoy-gg/shared-ui";import{ImageOverlayController as c}from"../utils/ImageOverlayController";import{scanForImageTargets as P}from"../utils/fiberScanner";import{TargetList as ce}from"./TargetList";import{OverlayControls as H}from"./OverlayControls";import{jsx as t,jsxs as r,Fragment as V}from"react/jsx-runtime";let b="";export function ImageOverlayModal({visible:I,onClose:j,onBack:U,onMinimize:Y,enableSharedModalDimensions:se=false,initialModalState:X,minimizeTargetPosition:E,inline:F=false,initialView:T}){const[s,y]=m(()=>{if(T)return T;const o=c.getState();if(o.mode==="free")return"free";if(o.targetRect)return"controls";return"idle"});const[z,B]=m(()=>T==="targets"?P():[]);const[n,K]=m(()=>c.getState());const[u,p]=m(b);const[S,_]=m(()=>c.isAutoTracking());D(()=>{b=u},[u]);D(()=>{return c.subscribe(K)},[]);D(()=>{c.setAutoTrack(S);return()=>{}},[S]);const O=f(()=>{const o=P();B(o);y("targets")},[]);const $=f(async o=>{await c.setTarget(o.instance,o.label,o.fiber);if(b.trim()){await c.setImageUri(b.trim());c.setEnabled(true)}y("controls")},[]);const v=f(async()=>{const o=b.trim();if(!o)return;if(s==="free"){await c.startFreeMode(o)}else{await c.setImageUri(o);c.setEnabled(true)}},[s]);const L=f(async()=>{let o=null;try{o=Q()}catch{}let h=null;if(!o){try{const g=Z();h=g.default||g}catch{}}if(!o&&!h){x.alert("Clipboard not available","Install expo-clipboard or @react-native-clipboard/clipboard to use paste.");return}try{if(o&&typeof o.hasImageAsync==="function"){const J=await o.hasImageAsync();if(J){const w=await o.getImageAsync({format:"png"});if(w?.data){if(s==="free"){await c.startFreeMode(w.data)}else{await c.setImageUri(w.data);c.setEnabled(true)}return}}}let g=null;if(o&&typeof o.getStringAsync==="function"){g=await o.getStringAsync()}else if(h&&typeof h.getString==="function"){g=await h.getString()}if(g&&(g.startsWith("http")||g.startsWith("data:"))){p(g);b=g;return}if(!o){x.alert("Image paste requires expo-clipboard","Your project uses @react-native-clipboard/clipboard which only supports text. Install expo-clipboard to paste images directly, or paste an image URL instead.")}else{x.alert("No image detected","Try saving your design image, opening it in Photos or Preview, and copying it from there.")}}catch{x.alert("Paste failed","Something went wrong reading the clipboard. Try copying the image again.")}},[s]);const q=f(()=>{c.reset();b="";y("idle");p("");B([])},[]);const G=f(()=>{if(s==="controls"){const o=P();B(o);y("targets")}else if(s==="targets"||s==="free"){c.reset();y("idle")}else{y("idle")}},[s]);const N=(()=>{switch(s){case"targets":return`Targets (${z.length})`;case"controls":return n.targetLabel||"Component Match";case"free":return"Free Placement";default:return"Image Overlay"}})();const k={showToggleButton:false,customContent:r(C,{children:[t(C.Navigation,{onBack:s!=="idle"?G:U}),t(C.Content,{title:N,testID:"buoy-image-overlay-title"}),r(C.Actions,{children:[s==="targets"&&t(d,{style:e.headerTextButton,onPress:O,testID:"buoy-image-overlay-scan",activeOpacity:.7,children:t(l,{style:e.headerTextButtonLabel,children:"Scan"})}),(s==="controls"||s==="free")&&n.imageUri&&t(ie,{isEnabled:n.enabled,onToggle:()=>c.toggle(),accessibilityLabel:"Toggle image overlay",testID:"buoy-image-overlay-power"}),s!=="idle"&&t(d,{style:e.headerActionButton,onPress:q,testID:"buoy-image-overlay-clear",activeOpacity:.7,children:t(oe,{size:14,color:i.color.textSecondary})})]})]})};const A=r(a,{style:e.container,children:[s==="idle"&&r(a,{style:e.homeContainer,children:[t(l,{style:e.homeSubtitle,testID:"buoy-image-overlay-home",children:"Choose a mode"}),r(a,{style:e.modeGrid,children:[r(d,{style:e.modePanel,onPress:O,testID:"buoy-image-overlay-mode-component",activeOpacity:.7,children:[t(a,{style:[e.modeIconCircle,{backgroundColor:i.color.accentSoft}],children:t(ne,{size:24,color:i.color.accent})}),r(l,{style:e.modePanelTitle,children:["Component","\n","Match"]}),t(l,{style:e.modePanelDesc,children:"Overlay on a tagged component"})]}),r(d,{style:e.modePanel,onPress:()=>y("free"),testID:"buoy-image-overlay-mode-free",activeOpacity:.7,children:[t(a,{style:[e.modeIconCircle,{backgroundColor:i.color.accentSoft}],children:t(re,{size:24,color:i.color.accent})}),r(l,{style:e.modePanelTitle,children:["Free","\n","Placement"]}),t(l,{style:e.modePanelDesc,children:"Drag and resize anywhere"})]})]})]}),s==="targets"&&t(ce,{targets:z,onSelect:$}),s==="controls"&&r(a,{style:e.controlsContainer,children:[n.targetRect&&r(a,{style:e.infoCard,children:[r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Component"}),t(l,{style:e.infoValue,testID:"buoy-image-overlay-info-component",children:n.targetLabel})]}),r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Size"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(n.targetRect.width)," x ",Math.round(n.targetRect.height)]})]}),r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Position"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(n.targetRect.x),", ",Math.round(n.targetRect.y)]})]}),n.imageWidth!=null&&n.imageHeight!=null&&r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Image"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-image",children:[n.imageWidth," x ",n.imageHeight]})]})]}),r(a,{style:e.inputSection,children:[t(l,{style:e.sectionLabel,children:"Image"}),t(d,{style:e.pasteButton,onPress:L,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:t(l,{style:e.pasteButtonText,children:"Paste from Clipboard"})}),r(a,{style:e.urlRow,children:[t(M,{style:e.urlInput,testID:"buoy-image-overlay-url",value:u,onChangeText:p,placeholder:"or enter URL...",placeholderTextColor:i.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:v}),t(d,{style:[e.loadButton,!u.trim()&&e.loadButtonDisabled],onPress:v,disabled:!u.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:t(l,{style:e.loadButtonText,children:"Load"})})]})]}),r(a,{style:e.toggleSection,children:[t(R,{label:"Show Outline",testID:"buoy-image-overlay-outline-toggle",value:n.showOutline,onValueChange:o=>c.setShowOutline(o)}),t(R,{label:"Auto Track",value:S,onValueChange:_,testID:"buoy-image-overlay-autotrack"}),n.imageUri&&r(V,{children:[r(a,{style:e.blendRow,children:[t(l,{style:e.toggleLabel,children:"Opacity"}),t(a,{style:e.blendButtons,children:[0,25,50,75,100].map(o=>t(d,{testID:`buoy-image-overlay-opacity-${o}`,style:[e.blendButton,Math.round(n.opacity*100)===o&&e.blendButtonActive],onPress:()=>c.setOpacity(o/100),activeOpacity:.7,children:r(l,{style:[e.blendButtonText,Math.round(n.opacity*100)===o&&e.blendButtonTextActive],children:[o,"%"]})},o))})]}),r(a,{style:e.blendRow,children:[t(l,{style:e.toggleLabel,children:"Flip"}),r(a,{style:e.blendButtons,children:[t(d,{style:[e.blendButton,n.invertX&&e.blendButtonActive],onPress:()=>c.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:t(l,{style:[e.blendButtonText,n.invertX&&e.blendButtonTextActive],testID:n.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),t(d,{style:[e.blendButton,n.invertY&&e.blendButtonActive],onPress:()=>c.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:t(l,{style:[e.blendButtonText,n.invertY&&e.blendButtonTextActive],testID:n.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]})]}),n.imageUri&&t(H,{opacity:n.opacity,scale:n.scale,offsetX:n.offsetX,offsetY:n.offsetY,onOpacityChange:o=>c.setOpacity(o),onScaleChange:o=>c.setScale(o),onOffsetChange:(o,h)=>c.setOffset(o,h)}),r(a,{style:e.actions,children:[t(d,{style:e.actionButton,onPress:()=>c.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-settings",children:t(l,{style:e.actionButtonText,children:"Reset Settings"})}),t(d,{style:e.actionButton,onPress:()=>c.remeasure(),activeOpacity:.7,testID:"buoy-image-overlay-remeasure",children:t(l,{style:e.actionButtonText,children:"Remeasure"})})]})]}),s==="free"&&r(a,{style:e.controlsContainer,children:[r(a,{style:e.inputSection,children:[t(l,{style:e.sectionLabel,children:"Image"}),t(d,{style:e.pasteButton,onPress:L,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:t(l,{style:e.pasteButtonText,children:"Paste from Clipboard"})}),r(a,{style:e.urlRow,children:[t(M,{style:e.urlInput,testID:"buoy-image-overlay-url",value:u,onChangeText:p,placeholder:"or enter URL...",placeholderTextColor:i.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:v}),t(d,{style:[e.loadButton,!u.trim()&&e.loadButtonDisabled],onPress:v,disabled:!u.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:t(l,{style:e.loadButtonText,children:"Load"})})]})]}),n.imageUri&&n.mode==="free"&&r(V,{children:[r(a,{style:e.infoCard,children:[r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Position"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(n.freeX),", ",Math.round(n.freeY)]})]}),r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Size"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(n.freeWidth)," x ",Math.round(n.freeHeight)]})]}),n.imageWidth!=null&&n.imageHeight!=null&&r(a,{style:e.infoRow,children:[t(l,{style:e.infoLabel,children:"Original"}),r(l,{style:e.infoValueMono,testID:"buoy-image-overlay-info-original",children:[n.imageWidth," x ",n.imageHeight]})]})]}),t(a,{style:e.inputSection,children:t(H,{opacity:n.opacity,scale:1,offsetX:0,offsetY:0,onOpacityChange:o=>c.setOpacity(o),onScaleChange:()=>{},onOffsetChange:()=>{},opacityOnly:true})}),r(a,{style:e.toggleSection,children:[t(R,{label:"Lock Position",testID:"buoy-image-overlay-lock",tone:"warning",value:n.locked,onValueChange:o=>c.setLocked(o)}),r(a,{style:e.blendRow,children:[t(l,{style:e.toggleLabel,children:"Opacity"}),t(a,{style:e.blendButtons,children:[0,25,50,75,100].map(o=>t(d,{testID:`buoy-image-overlay-opacity-${o}`,style:[e.blendButton,Math.round(n.opacity*100)===o&&e.blendButtonActive],onPress:()=>c.setOpacity(o/100),activeOpacity:.7,children:r(l,{style:[e.blendButtonText,Math.round(n.opacity*100)===o&&e.blendButtonTextActive],children:[o,"%"]})},o))})]}),r(a,{style:e.blendRow,children:[t(l,{style:e.toggleLabel,children:"Flip"}),r(a,{style:e.blendButtons,children:[t(d,{style:[e.blendButton,n.invertX&&e.blendButtonActive],onPress:()=>c.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:t(l,{style:[e.blendButtonText,n.invertX&&e.blendButtonTextActive],testID:n.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),t(d,{style:[e.blendButton,n.invertY&&e.blendButtonActive],onPress:()=>c.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:t(l,{style:[e.blendButtonText,n.invertY&&e.blendButtonTextActive],testID:n.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]}),t(a,{style:e.actions,children:t(d,{style:e.actionButton,onPress:()=>c.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-position",children:t(l,{style:e.actionButtonText,children:"Reset Position"})})})]})]})]});if(F){return r(a,{style:e.inlineRoot,children:[t(a,{style:e.inlineHeader,...le,children:k.customContent}),A]})}return t(te,{visible:I,onClose:j,onMinimize:Y,minimizeTargetPosition:E,initialModalState:X,header:k,initialMode:"bottomSheet",persistenceKey:"buoy-image-overlay-modal",enablePersistence:true,children:A})}export function ImageOverlayToolView(I={}){return t(ImageOverlayModal,{...I,inline:true,visible:true,onClose:()=>{}})}const e=ee.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:W.background.base},inlineHeader:{borderBottomWidth:1,borderBottomColor:W.border.default,backgroundColor:"transparent"},container:{flex:1,backgroundColor:"transparent"},headerTextButton:{height:32,paddingHorizontal:12,borderRadius:8,backgroundColor:i.color.buttonSurface,borderWidth:1,borderColor:i.color.border,alignItems:"center",justifyContent:"center"},headerTextButtonLabel:{fontSize:12,fontWeight:"600",color:i.color.accent},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:i.color.buttonSurface,borderWidth:1,borderColor:i.color.border,alignItems:"center",justifyContent:"center"},homeContainer:{flex:1,paddingHorizontal:12,paddingTop:16,paddingBottom:20,gap:12},homeSubtitle:{fontSize:12,fontWeight:"600",color:i.color.textTertiary,textTransform:"uppercase",letterSpacing:.5,textAlign:"center"},modeGrid:{flexDirection:"row",gap:10},modePanel:{flex:1,alignItems:"center",paddingVertical:20,paddingHorizontal:12,backgroundColor:i.color.surface,borderRadius:12,borderWidth:1,borderColor:i.color.border,gap:8},modeIconCircle:{width:48,height:48,borderRadius:24,alignItems:"center",justifyContent:"center",marginBottom:4},modePanelTitle:{fontSize:13,fontWeight:"700",color:i.color.text,textAlign:"center",lineHeight:17},modePanelDesc:{fontSize:11,color:i.color.textTertiary,textAlign:"center",lineHeight:15},controlsContainer:{flex:1,paddingTop:8,paddingBottom:24,gap:10},infoCard:{marginHorizontal:12,backgroundColor:i.color.surface,borderRadius:8,borderWidth:1,borderColor:i.color.border,padding:10,gap:4},infoRow:{flexDirection:"row",justifyContent:"space-between",alignItems:"center"},infoLabel:{fontSize:11,fontWeight:"500",color:i.color.textTertiary,textTransform:"uppercase",letterSpacing:.3},infoValue:{fontSize:12,fontWeight:"600",color:i.color.text},infoValueMono:{fontSize:12,fontWeight:"600",color:i.color.text,fontFamily:ae},inputSection:{paddingHorizontal:12,gap:6},sectionLabel:{fontSize:11,fontWeight:"600",color:i.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},pasteButton:{paddingVertical:10,borderRadius:8,backgroundColor:i.color.accentSoft,borderWidth:1,borderColor:i.color.accentBorderStrong,alignItems:"center"},pasteButtonText:{fontSize:13,fontWeight:"600",color:i.color.accent},urlRow:{flexDirection:"row",gap:8},urlInput:{flex:1,height:36,borderRadius:10,backgroundColor:i.color.surfaceElevated,borderWidth:1,borderColor:i.color.border,paddingHorizontal:12,fontSize:13,color:i.color.text},loadButton:{height:36,paddingHorizontal:14,borderRadius:8,backgroundColor:i.color.accent,justifyContent:"center",alignItems:"center"},loadButtonDisabled:{opacity:.4},loadButtonText:{fontSize:13,fontWeight:"600",color:i.color.onAccent},toggleSection:{paddingHorizontal:12,gap:6},toggleRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:i.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:i.color.border,paddingHorizontal:12,paddingVertical:8},toggleLabel:{fontSize:13,fontWeight:"500",color:i.color.textSecondary},blendRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:i.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:i.color.border,paddingHorizontal:12,paddingVertical:6},blendButtons:{flexDirection:"row",gap:4},blendButton:{paddingHorizontal:10,paddingVertical:5,borderRadius:6,backgroundColor:"transparent"},blendButtonActive:{backgroundColor:i.color.accentSoft},blendButtonText:{fontSize:12,fontWeight:"600",color:i.color.textTertiary},blendButtonTextActive:{color:i.color.accent},actions:{flexDirection:"row",paddingHorizontal:12,gap:8,marginTop:4},actionButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",gap:6,paddingVertical:8,paddingHorizontal:12,borderRadius:8,backgroundColor:i.color.surfaceElevated,borderWidth:1,borderColor:i.color.border},actionButtonText:{fontSize:12,fontWeight:"500",color:i.color.textSecondary}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import
|
|
1
|
+
"use strict";import oe,{useState as T,useEffect as N,useRef as z,useMemo as B,useCallback as U}from"react";import{View as i,Text as V,Image as Z,StyleSheet as j,PanResponder as k,Dimensions as J,Platform as K}from"react-native";import{absoluteFill as Q,monoFont as $}from"@buoy-gg/shared-ui";import{ImageOverlayController as R}from"../utils/ImageOverlayController";import{jsx as r,Fragment as q,jsxs as L}from"react/jsx-runtime";function G({uri:P,style:C,invertX:W,invertY:M}){const d=[];if(W)d.push({scaleX:-1});if(M)d.push({scaleY:-1});const x=d.length>0?{transform:d}:{};return r(Z,{testID:"buoy-internal-image-overlay",source:{uri:P},style:[C,x],pointerEvents:"none"})}const I=30;function ee({imageUri:P,x:C,y:W,width:M,height:d,opacity:x,aspectRatio:m,invertX:n,invertY:D,locked:l}){const[b,p]=T(false);const _=z({x:0,y:0});const X=z({x:0,y:0,width:0,height:0});const c=J.get("window");const Y=B(()=>k.create({onStartShouldSetPanResponder:()=>!l,onMoveShouldSetPanResponder:(u,s)=>!l&&(Math.abs(s.dx)>2||Math.abs(s.dy)>2),onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{const u=R.getState();_.current={x:u.freeX,y:u.freeY};p(true)},onPanResponderMove:(u,s)=>{const H=R.getState();const f=Math.max(0,Math.min(_.current.x+s.dx,c.width-H.freeWidth));const g=Math.max(0,Math.min(_.current.y+s.dy,c.height-H.freeHeight));R.setFreePosition(f,g)},onPanResponderRelease:()=>p(false),onPanResponderTerminate:()=>p(false)}),[c.width,c.height,l]);const v=U(u=>k.create({onStartShouldSetPanResponder:()=>!l,onMoveShouldSetPanResponder:()=>!l,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{const s=R.getState();X.current={x:s.freeX,y:s.freeY,width:s.freeWidth,height:s.freeHeight};p(true)},onPanResponderMove:(s,H)=>{const{dx:f,dy:g}=H;if(Math.abs(f)<.5&&Math.abs(g)<.5)return;const e=X.current;const h=m>0?m:e.width/e.height;const A=Math.abs(f);const O=Math.abs(g);const E=A>=O;let t;let a;let w=e.x;let y=e.y;switch(u){case"bottomRight":{t=E?e.width+f:(e.height+g)*h;t=Math.max(I,Math.min(t,c.width-e.x));a=t/h;break}case"bottomLeft":{t=E?e.width-f:(e.height+g)*h;t=Math.max(I,t);a=t/h;w=e.x+e.width-t;w=Math.max(0,w);t=Math.min(t,e.x+e.width);a=t/h;break}case"topRight":{t=E?e.width+f:(e.height-g)*h;t=Math.max(I,Math.min(t,c.width-e.x));a=t/h;y=e.y+e.height-a;y=Math.max(0,y);a=Math.min(a,e.y+e.height);t=a*h;break}case"topLeft":{t=E?e.width-f:(e.height-g)*h;t=Math.max(I,t);a=t/h;w=e.x+e.width-t;y=e.y+e.height-a;w=Math.max(0,w);y=Math.max(0,y);t=Math.min(t,e.x+e.width);a=t/h;y=e.y+e.height-a;break}}t=Math.max(I,Math.round(t));a=Math.max(I,Math.round(a));R.setFreeDimensions(t,a,Math.round(w),Math.round(y))},onPanResponderRelease:()=>p(false),onPanResponderTerminate:()=>p(false)}),[c.width,c.height,m,l]);const S=B(()=>({topLeft:v("topLeft"),topRight:v("topRight"),bottomLeft:v("bottomLeft"),bottomRight:v("bottomRight")}),[v]);const F={...Q,opacity:x};return L(i,{testID:"buoy-image-overlay-free-box",style:{position:"absolute",left:C,top:W,width:M,height:d},pointerEvents:l?"none":"auto",children:[r(i,{style:j.absoluteFill,...l?{}:Y.panHandlers,children:r(G,{uri:P,style:F,invertX:n,invertY:D})}),r(i,{pointerEvents:"none",style:[o.freeBorder,b&&o.freeBorderActive,l&&o.freeBorderLocked]}),!l&&L(q,{children:[r(i,{...S.topLeft.panHandlers,style:[o.cornerWrapper,{top:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:r(i,{style:[o.cornerHandle,b&&o.cornerHandleActive]})}),r(i,{...S.topRight.panHandlers,style:[o.cornerWrapper,{top:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:r(i,{style:[o.cornerHandle,b&&o.cornerHandleActive]})}),r(i,{...S.bottomLeft.panHandlers,style:[o.cornerWrapper,{bottom:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:r(i,{style:[o.cornerHandle,b&&o.cornerHandleActive]})}),r(i,{...S.bottomRight.panHandlers,style:[o.cornerWrapper,{bottom:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:r(i,{style:[o.cornerHandle,b&&o.cornerHandleActive]})})]})]})}export function ImageOverlayStandalone(){const[P,C]=T(()=>R.getState());N(()=>{return R.subscribe(C)},[]);const{mode:W,enabled:M,imageUri:d,imageWidth:x,imageHeight:m,targetRect:n,targetLabel:D,showOutline:l,opacity:b,scale:p,offsetX:_,offsetY:X,invertX:c,invertY:Y,locked:v,freeX:S,freeY:F,freeWidth:u,freeHeight:s}=P;const H=x&&m&&m>0?x/m:0;if(W==="free"&&M&&d){return r(i,{style:o.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:r(ee,{imageUri:d,x:S,y:F,width:u,height:s,opacity:b,aspectRatio:H,invertX:c,invertY:Y,locked:v})})}if(!n)return null;const f=M&&d;return L(i,{style:o.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:[l&&L(q,{children:[r(i,{pointerEvents:"none",nativeID:"__image_overlay_highlight__",testID:"buoy-image-overlay-outline",style:[o.highlight,{left:n.x-3,top:n.y-3,width:n.width+6,height:n.height+6}]}),D&&r(i,{pointerEvents:"none",style:[o.label,{left:n.x,top:n.y-20}],children:r(V,{style:o.labelText,testID:"buoy-image-overlay-outline-label",children:D})})]}),f&&(()=>{const g=(x??n.width)*p;const e=(m??n.height)*p;const h=n.x+n.width/2;const A=n.y+n.height/2;const O={position:"absolute",left:h-g/2+_,top:A-e/2+X,width:g,height:e,opacity:b};return r(G,{uri:d,style:O,invertX:c,invertY:Y})})()]})}const o=j.create({overlay:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:K.OS==="web"?999:999999,elevation:999999,borderWidth:0},highlight:{position:"absolute",borderWidth:2,borderStyle:"dashed",borderColor:"#20C997",backgroundColor:"transparent"},label:{position:"absolute",backgroundColor:"#20C997",paddingHorizontal:6,paddingVertical:2,borderRadius:3},labelText:{color:"#fff",fontSize:10,fontWeight:"700",fontFamily:$},freeBorder:{position:"absolute",top:-6,left:-6,right:-6,bottom:-6,borderWidth:1,borderColor:"transparent",borderRadius:4},freeBorderActive:{borderColor:"#20C997",borderStyle:"dashed"},freeBorderLocked:{borderColor:"#f59e0b",borderStyle:"solid"},cornerWrapper:{position:"absolute",width:24,height:24,zIndex:1e3,alignItems:"center",justifyContent:"center"},cornerHandle:{width:12,height:12,borderRadius:6,backgroundColor:"#20C997",borderWidth:2,borderColor:"#fff"},cornerHandleActive:{backgroundColor:"#10b981",shadowColor:"#10b981",shadowOffset:{width:0,height:0},shadowOpacity:.8,shadowRadius:6}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{useRef as a,useCallback as
|
|
1
|
+
"use strict";import{useRef as a,useCallback as b}from"react";import{View as c,Text as f,TouchableOpacity as P,StyleSheet as E,PanResponder as _}from"react-native";import{night as l,monoFont as j}from"@buoy-gg/shared-ui";import{jsx as e,jsxs as v}from"react/jsx-runtime";function h({label:d,testID:i,value:s,min:o,max:n,step:y,displayValue:g,onChange:u}){const p=a(0);const R=a(0);const m=b(r=>Math.max(o,Math.min(n,r)),[o,n]);const T=n>o?(s-o)/(n-o):0;const S=a(u);const M=a(m);const x=a(o);const k=a(n);S.current=u;M.current=m;x.current=o;k.current=n;const w=b(r=>{const I=r-R.current;const $=Math.max(0,Math.min(1,I/p.current));const H=x.current+$*(k.current-x.current);S.current(M.current(H))},[]);const V=a(_.create({onStartShouldSetPanResponder:()=>true,onMoveShouldSetPanResponder:()=>true,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:r=>{w(r.nativeEvent.pageX)},onPanResponderMove:r=>{w(r.nativeEvent.pageX)}})).current;const z=b(r=>{p.current=r.nativeEvent.layout.width},[]);const C=a(null);const B=b(()=>{C.current?.measure?.((r,I,$,H,D)=>{R.current=D})},[]);return v(c,{style:t.controlRow,children:[e(f,{style:t.label,children:d}),v(c,{style:t.controlRight,children:[e(P,{style:t.stepperButton,onPress:()=>u(m(s-y)),testID:`${i}-minus`,activeOpacity:.6,children:e(f,{style:t.stepperButtonText,children:"-"})}),e(c,{style:t.sliderHitArea,...V.panHandlers,testID:i,children:v(c,{ref:C,style:t.sliderTrack,onLayout:r=>{z(r);B()},pointerEvents:"none",children:[e(c,{style:[t.sliderFill,{width:`${T*100}%`}]}),e(c,{style:[t.sliderThumb,{left:`${T*100}%`}]})]})}),e(P,{style:t.stepperButton,onPress:()=>u(m(s+y)),testID:`${i}-plus`,activeOpacity:.6,children:e(f,{style:t.stepperButtonText,children:"+"})}),e(f,{style:t.valueText,testID:`${i}-value`,children:g})]})]})}export function OverlayControls({opacity:d,scale:i,offsetX:s,offsetY:o,onOpacityChange:n,onScaleChange:y,onOffsetChange:g,opacityOnly:u}){if(u){return e(h,{label:"Opacity",testID:"buoy-image-overlay-slider-opacity",value:d,min:0,max:1,step:.05,displayValue:`${Math.round(d*100)}%`,onChange:n})}return v(c,{style:t.container,children:[e(h,{label:"Opacity",testID:"buoy-image-overlay-slider-opacity",value:d,min:0,max:1,step:.05,displayValue:`${Math.round(d*100)}%`,onChange:n}),e(h,{label:"Scale",testID:"buoy-image-overlay-slider-scale",value:i,min:.05,max:3,step:.05,displayValue:`${Math.round(i*100)}%`,onChange:y}),e(h,{label:"Offset X",testID:"buoy-image-overlay-slider-offset-x",value:s,min:-200,max:200,step:2,displayValue:`${Math.round(s)}px`,onChange:p=>g(Math.round(p),o)}),e(h,{label:"Offset Y",testID:"buoy-image-overlay-slider-offset-y",value:o,min:-200,max:200,step:2,displayValue:`${Math.round(o)}px`,onChange:p=>g(s,Math.round(p))})]})}const L=18;const t=E.create({container:{gap:8},controlRow:{paddingHorizontal:12,gap:4},label:{fontSize:11,fontWeight:"600",color:l.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},controlRight:{flexDirection:"row",alignItems:"center",gap:6},stepperButton:{zIndex:1,width:28,height:28,borderRadius:6,backgroundColor:l.color.surfaceElevated,borderWidth:1,borderColor:l.color.border,justifyContent:"center",alignItems:"center"},stepperButtonText:{fontSize:16,fontWeight:"700",color:l.color.text,lineHeight:18},sliderHitArea:{flex:1,paddingVertical:20,paddingHorizontal:40,marginVertical:-20,marginHorizontal:-40},sliderTrack:{height:28,justifyContent:"center",borderRadius:6,backgroundColor:l.color.bg,borderWidth:1,borderColor:l.color.border,overflow:"hidden"},sliderFill:{position:"absolute",left:0,top:0,bottom:0,backgroundColor:l.color.accentFill,borderRadius:5},sliderThumb:{position:"absolute",width:4,top:4,bottom:4,marginLeft:-2,borderRadius:2,backgroundColor:l.color.accent},valueText:{fontSize:11,fontWeight:"600",color:l.color.text,width:45,textAlign:"right",fontFamily:j}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{View as r,Text as
|
|
1
|
+
"use strict";import{View as r,Text as i,TouchableOpacity as d,StyleSheet as m,ScrollView as g}from"react-native";import{ChevronRight as y,night as o,Hash as f,ToolEmptyState as p,monoFont as s}from"@buoy-gg/shared-ui";import{jsx as n,jsxs as l}from"react/jsx-runtime";function b({target:t,onSelect:a}){return l(d,{style:e.card,onPress:a,activeOpacity:.7,testID:`buoy-image-overlay-target-${t.label}`,children:[n(r,{style:e.colorIndicator}),l(r,{style:e.content,children:[n(r,{style:e.topRow,children:n(i,{style:e.label,numberOfLines:1,testID:`buoy-image-overlay-target-${t.label}-label`,children:t.label})}),l(r,{style:e.bottomRow,children:[l(r,{style:e.badgeRow,children:[l(r,{style:e.testIdBadge,children:[n(f,{size:8,color:o.color.accent}),n(i,{style:e.testIdBadgeText,children:"testID"})]}),n(i,{style:e.testIdValue,numberOfLines:1,testID:`buoy-image-overlay-target-${t.label}-testid`,children:t.testID})]}),t.componentName&&n(i,{style:e.componentName,numberOfLines:1,testID:`buoy-image-overlay-target-${t.label}-component`,children:t.componentName})]})]}),n(y,{size:16,color:o.color.textTertiary})]})}export function TargetList({targets:t,onSelect:a}){if(t.length===0){return n(p,{testID:"buoy-image-overlay-empty",otto:"scanning",title:"No targets found",message:'Tag components with\ntestID="image-target:YourLabel"'})}return n(g,{style:e.list,contentContainerStyle:e.listContent,children:t.map(c=>n(b,{target:c,onSelect:()=>a(c)},c.testID))})}const e=m.create({list:{flex:1},listContent:{paddingTop:8,paddingBottom:20},card:{flexDirection:"row",alignItems:"center",paddingVertical:10,paddingHorizontal:12,marginHorizontal:12,marginBottom:6,backgroundColor:o.color.surface,borderRadius:8,borderWidth:1,borderColor:o.color.border},colorIndicator:{width:4,height:36,borderRadius:2,marginRight:10,backgroundColor:o.color.accent},content:{flex:1,marginRight:8},topRow:{flexDirection:"row",alignItems:"center",marginBottom:4},label:{fontSize:13,fontWeight:"600",color:o.color.text,flex:1},bottomRow:{gap:2},badgeRow:{flexDirection:"row",alignItems:"center",gap:4},testIdBadge:{flexDirection:"row",alignItems:"center",paddingVertical:2,paddingHorizontal:5,borderRadius:4,backgroundColor:o.color.accentSoft,gap:3},testIdBadgeText:{fontSize:9,fontWeight:"700",color:o.color.accent},testIdValue:{fontSize:11,color:o.color.text,fontFamily:s,flex:1},componentName:{fontSize:10,color:"#a855f7",fontFamily:s,marginTop:1},emptyState:{alignItems:"center",paddingVertical:40,paddingHorizontal:32},emptyTitle:{color:o.color.text,fontSize:14,fontWeight:"600",marginBottom:6},emptyText:{color:o.color.textTertiary,fontSize:12,textAlign:"center",lineHeight:18,fontFamily:s}});
|
package/lib/web/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use client";var He=Object.defineProperty;var it=Object.getOwnPropertyDescriptor;var lt=Object.getOwnPropertyNames;var st=Object.prototype.hasOwnProperty;var ct=(e,t)=>{for(var n in t)He(e,n,{get:t[n],enumerable:true})},Ae=(e,t,n,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of lt(t))!st.call(e,r)&&r!==n&&He(e,r,{get:()=>t[r],enumerable:!(a=it(t,r))||a.enumerable});return e},dt=(e,t,n)=>(Ae(e,t,"default"),n&&Ae(n,t,"default"));var en=(()=>{try{let e=globalThis.Capacitor;if(e&&typeof e.isNativePlatform=="function"&&e.isNativePlatform())return e.DEBUG===true}catch{}return process.env.NODE_ENV!=="production"})();typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);import{ImageOverlayIcon as ht,createToolFactory as ut,defineToolPreset as gt}from"@buoy-gg/shared-ui/web";var ie;function ft(){return typeof navigator>"u"||!navigator.clipboard?null:{async hasImageAsync(){if(ie=void 0,!navigator.clipboard.read)return false;let e=await navigator.clipboard.read();for(let t of e){let n=t.types.find(a=>a.startsWith("image/"));if(n)return ie=await t.getType(n),true}return false},async getImageAsync(){if(!ie)return null;let e=ie;return ie=void 0,{data:await new Promise((t,n)=>{let a=new FileReader;a.onload=()=>t(String(a.result)),a.onerror=n,a.readAsDataURL(e)})}},getStringAsync:()=>navigator.clipboard.readText()}}function pt(){return null}import{useState as le,useEffect as Ce,useCallback as oe}from"react";var Ee={};ct(Ee,{AccessibilityInfo:()=>vt,ActivityIndicator:()=>mo,Alert:()=>ce,Animated:()=>xt,AppRegistry:()=>St,AppState:()=>Ct,Appearance:()=>wt,BackHandler:()=>Tt,Button:()=>yo,CheckBox:()=>Wt,Clipboard:()=>Rt,DeviceEventEmitter:()=>Qt,Dimensions:()=>me,Easing:()=>Mt,FlatList:()=>Vt,I18nManager:()=>Bt,Image:()=>Te,ImageBackground:()=>Dt,InteractionManager:()=>Pt,Keyboard:()=>It,KeyboardAvoidingView:()=>Ft,LayoutAnimation:()=>kt,Linking:()=>Lt,LogBox:()=>Jt,Modal:()=>fo,NativeEventEmitter:()=>Ot,NativeModules:()=>bt,PanResponder:()=>ye,Picker:()=>Yt,PixelRatio:()=>Ht,Platform:()=>At,Pressable:()=>go,ProgressBar:()=>Xt,RefreshControl:()=>Nt,SafeAreaView:()=>jt,ScrollView:()=>Fe,SectionList:()=>Ut,Share:()=>Et,StatusBar:()=>_t,StyleSheet:()=>ne,Switch:()=>po,Text:()=>f,TextInput:()=>Me,Touchable:()=>Kt,TouchableHighlight:()=>ho,TouchableNativeFeedback:()=>$t,TouchableOpacity:()=>R,TouchableWithoutFeedback:()=>uo,UIManager:()=>ze,Vibration:()=>zt,View:()=>s,VirtualizedList:()=>qt,YellowBox:()=>Gt,findNodeHandle:()=>Xe,unstable_createElement:()=>yt,useColorScheme:()=>Zt,useLocaleContext:()=>eo,useWindowDimensions:()=>to});dt(Ee,mt);import*as mt from"react-native-web";import{unstable_createElement as yt,NativeModules as bt,AccessibilityInfo as vt,Animated as xt,Appearance as wt,AppRegistry as St,AppState as Ct,BackHandler as Tt,Clipboard as Rt,Dimensions as me,Easing as Mt,I18nManager as Bt,Keyboard as It,InteractionManager as Pt,LayoutAnimation as kt,Linking as Lt,NativeEventEmitter as Ot,PanResponder as ye,PixelRatio as Ht,Platform as At,Share as Et,StyleSheet as ne,UIManager as ze,Vibration as zt,CheckBox as Wt,FlatList as Vt,Image as Te,ImageBackground as Dt,KeyboardAvoidingView as Ft,Picker as Yt,ProgressBar as Xt,RefreshControl as Nt,SafeAreaView as jt,SectionList as Ut,StatusBar as _t,Touchable as Kt,TouchableNativeFeedback as $t,VirtualizedList as qt,YellowBox as Gt,LogBox as Jt,DeviceEventEmitter as Qt,useColorScheme as Zt,useLocaleContext as eo,useWindowDimensions as to}from"react-native-web";import*as D from"react-native-web";import{createElement as Re,forwardRef as We,useCallback as oo,useRef as no}from"react";import{useEffect as ro,useState as ao}from"react";import{createPortal as io}from"react-dom";var lo='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';import{jsx as so}from"react/jsx-runtime";var se=Symbol.for("@buoy-gg/portal-host"),Ve=e=>{if(!(e instanceof Element))return false;if(e.closest("input, textarea, select"))return true;let t=e.closest("[contenteditable]")?.getAttribute("contenteditable")?.toLowerCase();return t===""||t==="true"||t==="plaintext-only"};function De(){let e=document;if(e[se])return e[se].host;let t=document.createElement("div");t.dataset.buoyPortalHost="",Object.assign(t.style,{position:"fixed",inset:"0",zIndex:"2147483647",pointerEvents:"none",fontFamily:lo});let n=()=>{let d=document.fullscreenElement,M=d&&d.tagName!=="CANVAS"?d:document.body;t.parentElement!==M&&M.appendChild(t)},a=new Map,r=d=>{(!t.contains(d.target)||!Ve(d.target))&&a.set(d.code||d.key,{key:d.key,code:d.code,location:d.location,keyCode:d.keyCode,which:d.which,altKey:d.altKey,ctrlKey:d.ctrlKey,metaKey:d.metaKey,shiftKey:d.shiftKey})},g=d=>{a.delete(d.code||d.key)},x=()=>a.clear(),m=()=>{let d=[...a.values()];a.clear();for(let M of d)document.dispatchEvent(new KeyboardEvent("keyup",{...M,bubbles:true}))},b=d=>{Ve(d.target)&&d.stopPropagation()},c=d=>d.stopPropagation();return n(),document.addEventListener("fullscreenchange",n),document.addEventListener("keydown",r,true),document.addEventListener("keyup",g,true),window.addEventListener("blur",x),t.addEventListener("focusin",m),t.addEventListener("keydown",b),t.addEventListener("keyup",b),t.addEventListener("keypress",b),t.addEventListener("wheel",c,{passive:true}),e[se]={host:t,users:0,dispose:()=>{document.removeEventListener("fullscreenchange",n),document.removeEventListener("keydown",r,true),document.removeEventListener("keyup",g,true),window.removeEventListener("blur",x),t.remove(),delete e[se]}},t}function co({children:e}){let[t,n]=ao(null);return ro(()=>{let a=De(),r=document[se];return r.users++,n(a),()=>{--r.users===0&&r.dispose()}},[]),t?io(so("div",{"data-buoy-root":"",style:{display:"contents",pointerEvents:"auto"},children:e}),t):null}function j(e){let t=We((a,r)=>{let{accessibilityState:g,accessibilityValue:x,...m}=a;for(let b of["busy","checked","disabled","expanded","selected"])g?.[b]!==void 0&&m[`aria-${b}`]===void 0&&(m[`aria-${b}`]=g[b]);for(let[b,c]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))x?.[b]!==void 0&&m[`aria-${c}`]===void 0&&(m[`aria-${c}`]=x[b]);return Re(e,{...m,ref:r})}),n=e.State;return n&&Object.assign(t,{State:n}),t.displayName=e.displayName??e.name??"NativeWebView",t}var s=j(D.View),f=j(D.Text),Me=j(D.TextInput),R=j(D.TouchableOpacity),ho=j(D.TouchableHighlight),uo=j(D.TouchableWithoutFeedback),go=j(D.Pressable),Fe=j(D.ScrollView),Ye=We((e,t)=>{let n=no(null),a=oo(r=>{if(r){let g=r;for(;g.parentElement&&g.parentElement!==document.body;)g=g.parentElement;g.parentElement===document.body&&(n.current=g,Object.assign(g.style,{position:"relative",zIndex:"2147483647",pointerEvents:"auto"}),De().appendChild(g))}else n.current&&(document.body.appendChild(n.current),n.current=null);typeof t=="function"?t(r):t&&(t.current=r)},[t]);return Re(co,null,Re(D.Modal,{...e,ref:a}))});Ye.displayName="Modal";var fo=j(Ye),po=j(D.Switch),mo=j(D.ActivityIndicator),yo=j(D.Button),Xe=D.findNodeHandle,ce={alert(e,t,n,a){if(typeof document>"u")return;let r=document.createElement("dialog");r.dataset.buoyRoot="",r.setAttribute("aria-label",e),r.style.cssText="position:fixed;inset:0;margin:auto;width:min(440px,90vw);padding:24px;border:1px solid #475569;border-radius:14px;background:#17212e;color:#f1f5f9;font:14px system-ui;box-shadow:0 20px 80px #0008;z-index:2147483647";let g=document.createElement("h2");if(g.textContent=e,g.style.cssText="font-size:18px;margin:0 0 12px",r.appendChild(g),t){let c=document.createElement("p");c.textContent=t,c.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",r.appendChild(c)}let x=document.createElement("div");x.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let m=n?.length?n:[{text:"OK"}],b=()=>{r.close?.(),r.remove()};for(let c of m){let d=document.createElement("button");d.type="button",d.textContent=c.text??"OK",d.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${c.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,d.onclick=()=>{b(),c.onPress?.()},x.appendChild(d)}r.addEventListener("cancel",c=>{c.preventDefault(),a?.cancelable!==false&&(b(),a?.onDismiss?.())}),r.appendChild(x),document.body.appendChild(r),r.showModal?r.showModal():r.setAttribute("open","")}};import{JsModal as bo,ModalHeader as be,macOSColors as Ne,night as y,Trash2 as vo,SquareDashed as xo,Image as wo,PowerToggleButton as So,windowDragProps as Co,ToggleRow as Be,monoFont as To}from"@buoy-gg/shared-ui/web";function Ie(e){return new Promise(t=>{try{let n=[];e&&n.push(e),e?.canonical?.publicInstance&&n.push(e.canonical.publicInstance),e?.canonical&&e.canonical!==e&&n.push(e.canonical);for(let a of n)if(typeof a.getBoundingClientRect=="function")try{let r=a.getBoundingClientRect();if(r&&typeof r.x=="number"&&typeof r.y=="number"&&typeof r.width=="number"&&typeof r.height=="number"&&r.width>0&&r.height>0){t({x:r.x,y:r.y,width:r.width,height:r.height});return}}catch{}for(let a of n)if(typeof a.measure=="function"){let r=setTimeout(()=>t(null),200);a.measure((g,x,m,b,c,d)=>{clearTimeout(r),c!=null&&d!=null&&m!=null&&b!=null&&m>0&&b>0?t({x:c,y:d,width:m,height:b}):t(null)});return}try{let a=Xe(e);if(a!=null){let r=setTimeout(()=>t(null),200);ze.measure(a,(g,x,m,b,c,d)=>{clearTimeout(r),c!=null&&d!=null&&m!=null&&b!=null&&m>0&&b>0?t({x:c,y:d,width:m,height:b}):t(null)});return}}catch{}t(null)}catch{t(null)}})}var je=null;function Ro(e){je=e??null}function Ue(){return je||(typeof globalThis>"u"?null:globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__??null)}var _e="image-target:",Mo=5,Bo=22;function Io(){let e=Ue();if(!e?.getFiberRoots)return[];let t=new Set,n=e.renderers?.keys?Array.from(e.renderers.keys()):[1];for(let a of n)try{e.getFiberRoots(a)?.forEach(r=>t.add(r))}catch{}return[...t]}function Po(e){return e.tag===Bo&&e.memoizedState!==null}function ko(e){return e.memoizedProps?.activityState===0}function de(e,t,n=0,a=new Set){if(!(!e||a.has(e)||n>500)){if(a.add(e),Po(e)){e.sibling&&de(e.sibling,t,n,a);return}if(ko(e)){e.sibling&&de(e.sibling,t,n,a);return}t(e,n),e.child&&de(e.child,t,n+1,a),e.sibling&&de(e.sibling,t,n,a)}}function Lo(e){let t=new Set(["View","RCTView","Text","RCTText","Image","RCTImageView","ScrollView","RCTScrollView","TextInput","RCTTextInput","TouchableOpacity","TouchableHighlight","TouchableWithoutFeedback","Pressable","FlatList","SectionList","SafeAreaView"]),n=e._debugOwner||e.return,a=0;for(;n&&a<30;){a++;let r=n.type;if(r){let g=typeof r=="string"?r:r.displayName||r.name;if(g&&!t.has(g))return g}n=n.return}return null}function he(){let e=Io();if(e.length===0)return[];let t=[];for(let n of e)de(n.current,a=>{if(a.tag!==Mo)return;let r=a.memoizedProps?.testID??a.pendingProps?.testID??a.memoizedProps?.["data-testid"]??a.pendingProps?.["data-testid"];if(!r||!r.startsWith(_e))return;let g=r.slice(_e.length);g&&t.push({label:g,testID:r,fiber:a,instance:a.stateNode,componentName:Lo(a)})});return t}var Ke={mode:null,enabled:false,imageUri:null,imageWidth:null,imageHeight:null,targetTag:null,targetLabel:null,targetRect:null,showOutline:true,opacity:.5,scale:1,offsetX:0,offsetY:0,invertX:false,invertY:false,locked:false,freeX:0,freeY:0,freeWidth:200,freeHeight:200},i={...Ke},Pe=new Set,$=null,ve=null,ue=false,ge=null,Oo=null;function B(){for(let e of Pe)e(i)}function Ho(e){return e?typeof e._nativeTag=="number"?e._nativeTag:typeof e.canonical?._nativeTag=="number"?e.canonical._nativeTag:typeof e.__nativeTag=="number"?e.__nativeTag:null:null}async function $e(e,t){let n=await Ie(e);if(n)return{rect:n,freshInstance:e};let a=he().find(r=>r.label===t);return a&&(n=await Ie(a.instance),n)?{rect:n,freshInstance:a.instance}:{rect:null,freshInstance:e}}function Ao(){if(ge)return;let e=Ue();if(e){if(e.rendererInterfaces)for(let[,t]of e.rendererInterfaces)typeof t.setTraceUpdatesEnabled=="function"&&t.setTraceUpdatesEnabled(true);typeof e.sub=="function"&&(ge=e.sub("traceUpdates",Wo))}}var re=null,ke=false;function Eo(){if(re!==null||typeof requestAnimationFrame!="function")return;let e=()=>{re=requestAnimationFrame(e),!(ke||!ue||!$)&&(ke=true,Ge().finally(()=>{ke=false}))};re=requestAnimationFrame(e)}function zo(){re!==null&&typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(re),re=null}function qe(){zo(),ge&&(ge(),ge=null)}function Wo(e){!ue||!$||Ge()}function Ge(){return Ie($).then(e=>{if(e&&i.targetRect){let t=i.targetRect;(Math.abs(e.x-t.x)>.5||Math.abs(e.y-t.y)>.5||Math.abs(e.width-t.width)>.5||Math.abs(e.height-t.height)>.5)&&(i={...i,targetRect:e},B())}}).catch(()=>{})}function Je(e){return new Promise(t=>{Te.getSize(e,(n,a)=>t({width:n,height:a}),()=>t(null))})}var v={subscribe(e){return Pe.add(e),e(i),()=>Pe.delete(e)},getState(){return i},async setTarget(e,t,n){$=e,ve=t;let a=n?.stateNode??e,{rect:r,freshInstance:g}=await $e(a,t);$=g;let x=Ho($);i={...i,mode:"component",targetTag:x,targetLabel:t,targetRect:r},B()},async setImageUri(e){let t=await Je(e),n=1;t&&i.targetRect&&t.width>0&&(n=i.targetRect.width/t.width),i={...i,imageUri:e,imageWidth:t?.width??null,imageHeight:t?.height??null,scale:n,showOutline:false},B()},setOpacity(e){i={...i,opacity:Math.max(0,Math.min(1,e))},B()},setScale(e){i={...i,scale:Math.max(.01,Math.min(5,e))},B()},setOffset(e,t){i={...i,offsetX:e,offsetY:t},B()},toggleInvertX(){i={...i,invertX:!i.invertX},B()},toggleInvertY(){i={...i,invertY:!i.invertY},B()},setLocked(e){i={...i,locked:e},B()},setAutoTrack(e){ue=e,e?(Ao(),Eo()):qe()},isAutoTracking(){return ue},setShowOutline(e){i={...i,showOutline:e},B()},setEnabled(e){i={...i,enabled:e},B()},toggle(){i={...i,enabled:!i.enabled},B()},fitWidth(){i.imageWidth&&i.targetRect&&i.imageWidth>0&&(i={...i,scale:i.targetRect.width/i.imageWidth},B())},fitHeight(){i.imageHeight&&i.targetRect&&i.imageHeight>0&&(i={...i,scale:i.targetRect.height/i.imageHeight},B())},resetSettings(){if(i={...i,invertX:false,invertY:false},i.mode==="free"){let e=me.get("window"),t=i.imageWidth??200,n=i.imageHeight??200;i={...i,opacity:.5,freeX:(e.width-t)/2,freeY:(e.height-n)/2,freeWidth:t,freeHeight:n}}else{let e=1;i.imageWidth&&i.targetRect&&i.imageWidth>0&&(e=i.targetRect.width/i.imageWidth),i={...i,opacity:.5,scale:e,offsetX:0,offsetY:0}}B()},async remeasure(){if(!ve)return;let{rect:e,freshInstance:t}=await $e($,ve);$=t,e&&(i={...i,targetRect:e},B())},async startFreeMode(e){let t=await Je(e),n=me.get("window"),a=t?.width??200,r=t?.height??200,g=a,x=r,m=n.width*.8,b=n.height*.6;if(g>m||x>b){let c=Math.min(m/g,b/x);g=Math.round(g*c),x=Math.round(x*c)}i={...i,mode:"free",enabled:true,imageUri:e,imageWidth:t?.width??null,imageHeight:t?.height??null,opacity:.5,freeX:Math.round((n.width-g)/2),freeY:Math.round((n.height-x)/2),freeWidth:Math.round(g),freeHeight:Math.round(x)},B()},setFreePosition(e,t){i={...i,freeX:e,freeY:t},B()},setFreeDimensions(e,t,n,a){i={...i,freeWidth:e,freeHeight:t,freeX:n,freeY:a},B()},reset(){qe(),ue=false,Oo=null,$=null,ve=null,i={...Ke},B()}};import{ChevronRight as Vo,night as _,Hash as Do,ToolEmptyState as Fo,monoFont as Le}from"@buoy-gg/shared-ui/web";import{jsx as K,jsxs as fe}from"react/jsx-runtime";function Yo({target:e,onSelect:t}){return fe(R,{style:F.card,onPress:t,activeOpacity:.7,children:[K(s,{style:F.colorIndicator}),fe(s,{style:F.content,children:[K(s,{style:F.topRow,children:K(f,{style:F.label,numberOfLines:1,children:e.label})}),fe(s,{style:F.bottomRow,children:[fe(s,{style:F.badgeRow,children:[fe(s,{style:F.testIdBadge,children:[K(Do,{size:8,color:_.color.accent}),K(f,{style:F.testIdBadgeText,children:"testID"})]}),K(f,{style:F.testIdValue,numberOfLines:1,children:e.testID})]}),e.componentName&&K(f,{style:F.componentName,numberOfLines:1,children:e.componentName})]})]}),K(Vo,{size:16,color:_.color.textTertiary})]})}function Xo({targets:e,onSelect:t}){return e.length===0?K(Fo,{testID:"buoy-image-overlay-empty",otto:"scanning",title:"No targets found",message:`Tag components with
|
|
2
|
-
testID="image-target:YourLabel"`})
|
|
3
|
-
`,"Match"]}),l(
|
|
4
|
-
`,"Placement"]}),l(f,{style:o.modePanelDesc,children:"Drag and resize anywhere"})]})]})]}),c==="targets"&&l(Xo,{targets:M,onSelect:C}),c==="controls"&&p(s,{style:o.controlsContainer,children:[u.targetRect&&p(s,{style:o.infoCard,children:[p(s,{style:o.infoRow,children:[l(f,{style:o.infoLabel,children:"Component"}),l(f,{style:o.infoValue,children:u.targetLabel})]}),p(s,{style:o.infoRow,children:[l(f,{style:o.infoLabel,children:"Size"}),p(f,{style:o.infoValueMono,children:[Math.round(u.targetRect.width)," x ",Math.round(u.targetRect.height)]})]}),p(s,{style:o.infoRow,children:[l(f,{style:o.infoLabel,children:"Position"}),p(f,{style:o.infoValueMono,children:[Math.round(u.targetRect.x),", ",Math.round(u.targetRect.y)]})]}),u.imageWidth!=null&&u.imageHeight!=null&&p(s,{style:o.infoRow,children:[l(f,{style:o.infoLabel,children:"Image"}),p(f,{style:o.infoValueMono,children:[u.imageWidth," x ",u.imageHeight]})]})]}),p(s,{style:o.inputSection,children:[l(f,{style:o.sectionLabel,children:"Image"}),l(R,{style:o.pasteButton,onPress:O,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",children:l(f,{style:o.pasteButtonText,children:"Paste from Clipboard"})}),p(s,{style:o.urlRow,children:[l(Me,{style:o.urlInput,value:L,onChangeText:E,placeholder:"or enter URL...",placeholderTextColor:y.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:z}),l(R,{style:[o.loadButton,!L.trim()&&o.loadButtonDisabled],onPress:z,disabled:!L.trim(),activeOpacity:.7,children:l(f,{style:o.loadButtonText,children:"Load"})})]})]}),p(s,{style:o.toggleSection,children:[l(Be,{label:"Show Outline",value:u.showOutline,onValueChange:h=>v.setShowOutline(h)}),l(Be,{label:"Auto Track",value:N,onValueChange:G}),u.imageUri&&p(Ze,{children:[p(s,{style:o.blendRow,children:[l(f,{style:o.toggleLabel,children:"Opacity"}),l(s,{style:o.blendButtons,children:[0,25,50,75,100].map(h=>l(R,{style:[o.blendButton,Math.round(u.opacity*100)===h&&o.blendButtonActive],onPress:()=>v.setOpacity(h/100),activeOpacity:.7,children:p(f,{style:[o.blendButtonText,Math.round(u.opacity*100)===h&&o.blendButtonTextActive],children:[h,"%"]})},h))})]}),p(s,{style:o.blendRow,children:[l(f,{style:o.toggleLabel,children:"Flip"}),p(s,{style:o.blendButtons,children:[l(R,{style:[o.blendButton,u.invertX&&o.blendButtonActive],onPress:()=>v.toggleInvertX(),activeOpacity:.7,children:l(f,{style:[o.blendButtonText,u.invertX&&o.blendButtonTextActive],children:"Horizontal"})}),l(R,{style:[o.blendButton,u.invertY&&o.blendButtonActive],onPress:()=>v.toggleInvertY(),activeOpacity:.7,children:l(f,{style:[o.blendButtonText,u.invertY&&o.blendButtonTextActive],children:"Vertical"})})]})]})]})]}),u.imageUri&&l(Qe,{opacity:u.opacity,scale:u.scale,offsetX:u.offsetX,offsetY:u.offsetY,onOpacityChange:h=>v.setOpacity(h),onScaleChange:h=>v.setScale(h),onOffsetChange:(h,S)=>v.setOffset(h,S)}),p(s,{style:o.actions,children:[l(R,{style:o.actionButton,onPress:()=>v.resetSettings(),activeOpacity:.7,children:l(f,{style:o.actionButtonText,children:"Reset Settings"})}),l(R,{style:o.actionButton,onPress:()=>v.remeasure(),activeOpacity:.7,children:l(f,{style:o.actionButtonText,children:"Remeasure"})})]})]}),c==="free"&&p(s,{style:o.controlsContainer,children:[p(s,{style:o.inputSection,children:[l(f,{style:o.sectionLabel,children:"Image"}),l(R,{style:o.pasteButton,onPress:O,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",children:l(f,{style:o.pasteButtonText,children:"Paste from Clipboard"})}),p(s,{style:o.urlRow,children:[l(Me,{style:o.urlInput,value:L,onChangeText:E,placeholder:"or enter URL...",placeholderTextColor:y.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:z}),l(R,{style:[o.loadButton,!L.trim()&&o.loadButtonDisabled],onPress:z,disabled:!L.trim(),activeOpacity:.7,children:l(f,{style:o.loadButtonText,children:"Load"})})]})]}),u.imageUri&&u.mode==="free"&&p(Ze,{children:[p(s,{style:o.infoCard,children:[p(s,{style:o.infoRow,children:[l(f,{style:o.infoLabel,children:"Position"}),p(f,{style:o.infoValueMono,children:[Math.round(u.freeX),", ",Math.round(u.freeY)]})]}),p(s,{style:o.infoRow,children:[l(f,{style:o.infoLabel,children:"Size"}),p(f,{style:o.infoValueMono,children:[Math.round(u.freeWidth)," x ",Math.round(u.freeHeight)]})]}),u.imageWidth!=null&&u.imageHeight!=null&&p(s,{style:o.infoRow,children:[l(f,{style:o.infoLabel,children:"Original"}),p(f,{style:o.infoValueMono,children:[u.imageWidth," x ",u.imageHeight]})]})]}),l(s,{style:o.inputSection,children:l(Qe,{opacity:u.opacity,scale:1,offsetX:0,offsetY:0,onOpacityChange:h=>v.setOpacity(h),onScaleChange:()=>{},onOffsetChange:()=>{},opacityOnly:true})}),p(s,{style:o.toggleSection,children:[l(Be,{label:"Lock Position",tone:"warning",value:u.locked,onValueChange:h=>v.setLocked(h)}),p(s,{style:o.blendRow,children:[l(f,{style:o.toggleLabel,children:"Opacity"}),l(s,{style:o.blendButtons,children:[0,25,50,75,100].map(h=>l(R,{style:[o.blendButton,Math.round(u.opacity*100)===h&&o.blendButtonActive],onPress:()=>v.setOpacity(h/100),activeOpacity:.7,children:p(f,{style:[o.blendButtonText,Math.round(u.opacity*100)===h&&o.blendButtonTextActive],children:[h,"%"]})},h))})]}),p(s,{style:o.blendRow,children:[l(f,{style:o.toggleLabel,children:"Flip"}),p(s,{style:o.blendButtons,children:[l(R,{style:[o.blendButton,u.invertX&&o.blendButtonActive],onPress:()=>v.toggleInvertX(),activeOpacity:.7,children:l(f,{style:[o.blendButtonText,u.invertX&&o.blendButtonTextActive],children:"Horizontal"})}),l(R,{style:[o.blendButton,u.invertY&&o.blendButtonActive],onPress:()=>v.toggleInvertY(),activeOpacity:.7,children:l(f,{style:[o.blendButtonText,u.invertY&&o.blendButtonTextActive],children:"Vertical"})})]})]})]}),l(s,{style:o.actions,children:l(R,{style:o.actionButton,onPress:()=>v.resetSettings(),activeOpacity:.7,children:l(f,{style:o.actionButtonText,children:"Reset Position"})})})]})]})]});return m?p(s,{style:o.inlineRoot,children:[l(s,{style:o.inlineHeader,...Co,children:ee.customContent}),te]}):l(bo,{visible:e,onClose:t,onMinimize:a,minimizeTargetPosition:x,initialModalState:g,header:ee,initialMode:"bottomSheet",persistenceKey:"buoy-image-overlay-modal",enablePersistence:true,children:te})}function jo(e={}){return l(Oe,{...e,inline:true,visible:true,onClose:()=>{}})}var o=ne.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:Ne.background.base},inlineHeader:{borderBottomWidth:1,borderBottomColor:Ne.border.default,backgroundColor:"transparent"},container:{flex:1,backgroundColor:"transparent"},headerTextButton:{height:32,paddingHorizontal:12,borderRadius:8,backgroundColor:y.color.buttonSurface,borderWidth:1,borderColor:y.color.border,alignItems:"center",justifyContent:"center"},headerTextButtonLabel:{fontSize:12,fontWeight:"600",color:y.color.accent},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:y.color.buttonSurface,borderWidth:1,borderColor:y.color.border,alignItems:"center",justifyContent:"center"},homeContainer:{flex:1,paddingHorizontal:12,paddingTop:16,paddingBottom:20,gap:12},homeSubtitle:{fontSize:12,fontWeight:"600",color:y.color.textTertiary,textTransform:"uppercase",letterSpacing:.5,textAlign:"center"},modeGrid:{flexDirection:"row",gap:10},modePanel:{flex:1,alignItems:"center",paddingVertical:20,paddingHorizontal:12,backgroundColor:y.color.surface,borderRadius:12,borderWidth:1,borderColor:y.color.border,gap:8},modeIconCircle:{width:48,height:48,borderRadius:24,alignItems:"center",justifyContent:"center",marginBottom:4},modePanelTitle:{fontSize:13,fontWeight:"700",color:y.color.text,textAlign:"center",lineHeight:17},modePanelDesc:{fontSize:11,color:y.color.textTertiary,textAlign:"center",lineHeight:15},controlsContainer:{flex:1,paddingTop:8,paddingBottom:24,gap:10},infoCard:{marginHorizontal:12,backgroundColor:y.color.surface,borderRadius:8,borderWidth:1,borderColor:y.color.border,padding:10,gap:4},infoRow:{flexDirection:"row",justifyContent:"space-between",alignItems:"center"},infoLabel:{fontSize:11,fontWeight:"500",color:y.color.textTertiary,textTransform:"uppercase",letterSpacing:.3},infoValue:{fontSize:12,fontWeight:"600",color:y.color.text},infoValueMono:{fontSize:12,fontWeight:"600",color:y.color.text,fontFamily:To},inputSection:{paddingHorizontal:12,gap:6},sectionLabel:{fontSize:11,fontWeight:"600",color:y.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},pasteButton:{paddingVertical:10,borderRadius:8,backgroundColor:y.color.accentSoft,borderWidth:1,borderColor:y.color.accentBorderStrong,alignItems:"center"},pasteButtonText:{fontSize:13,fontWeight:"600",color:y.color.accent},urlRow:{flexDirection:"row",gap:8},urlInput:{flex:1,height:36,borderRadius:10,backgroundColor:y.color.surfaceElevated,borderWidth:1,borderColor:y.color.border,paddingHorizontal:12,fontSize:13,color:y.color.text},loadButton:{height:36,paddingHorizontal:14,borderRadius:8,backgroundColor:y.color.accent,justifyContent:"center",alignItems:"center"},loadButtonDisabled:{opacity:.4},loadButtonText:{fontSize:13,fontWeight:"600",color:y.color.onAccent},toggleSection:{paddingHorizontal:12,gap:6},toggleRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:y.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:y.color.border,paddingHorizontal:12,paddingVertical:8},toggleLabel:{fontSize:13,fontWeight:"500",color:y.color.textSecondary},blendRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:y.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:y.color.border,paddingHorizontal:12,paddingVertical:6},blendButtons:{flexDirection:"row",gap:4},blendButton:{paddingHorizontal:10,paddingVertical:5,borderRadius:6,backgroundColor:"transparent"},blendButtonActive:{backgroundColor:y.color.accentSoft},blendButtonText:{fontSize:12,fontWeight:"600",color:y.color.textTertiary},blendButtonTextActive:{color:y.color.accent},actions:{flexDirection:"row",paddingHorizontal:12,gap:8,marginTop:4},actionButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",gap:6,paddingVertical:8,paddingHorizontal:12,borderRadius:8,backgroundColor:y.color.surfaceElevated,borderWidth:1,borderColor:y.color.border},actionButtonText:{fontSize:12,fontWeight:"500",color:y.color.textSecondary}});import{jsx as Uo}from"react/jsx-runtime";var _o="#A855F7",et=gt({id:"image-overlay",name:"IMG",description:"Design mockup overlay",slot:"both",icon:({size:e})=>Uo(ht,{size:e,color:_o}),component:Oe,props:{enableSharedModalDimensions:false}}),Ko=ut(et,e=>({enableSharedModalDimensions:e.enableSharedModalDimensions??false}));import{useState as tt,useEffect as $o,useRef as ot,useMemo as nt,useCallback as qo}from"react";import{absoluteFill as Go,monoFont as Jo}from"@buoy-gg/shared-ui/web";import{Fragment as rt,jsx as P,jsxs as Se}from"react/jsx-runtime";function at({uri:e,style:t,invertX:n,invertY:a}){let r=[];n&&r.push({scaleX:-1}),a&&r.push({scaleY:-1});let g=r.length>0?{transform:r}:{};return P(Te,{testID:"buoy-internal-image-overlay",source:{uri:e},style:[t,g],pointerEvents:"none"})}var ae=30;function Qo({imageUri:e,x:t,y:n,width:a,height:r,opacity:g,aspectRatio:x,invertX:m,invertY:b,locked:c}){let[d,M]=tt(false),X=ot({x:0,y:0}),u=ot({x:0,y:0,width:0,height:0}),k=me.get("window"),L=nt(()=>ye.create({onStartShouldSetPanResponder:()=>!c,onMoveShouldSetPanResponder:(V,C)=>!c&&(Math.abs(C.dx)>2||Math.abs(C.dy)>2),onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{let V=v.getState();X.current={x:V.freeX,y:V.freeY},M(true)},onPanResponderMove:(V,C)=>{let z=v.getState(),O=Math.max(0,Math.min(X.current.x+C.dx,k.width-z.freeWidth)),H=Math.max(0,Math.min(X.current.y+C.dy,k.height-z.freeHeight));v.setFreePosition(O,H)},onPanResponderRelease:()=>M(false),onPanResponderTerminate:()=>M(false)}),[k.width,k.height,c]),E=qo(V=>ye.create({onStartShouldSetPanResponder:()=>!c,onMoveShouldSetPanResponder:()=>!c,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{let C=v.getState();u.current={x:C.freeX,y:C.freeY,width:C.freeWidth,height:C.freeHeight},M(true)},onPanResponderMove:(C,z)=>{let{dx:O,dy:H}=z;if(Math.abs(O)<.5&&Math.abs(H)<.5)return;let w=u.current,A=x>0?x:w.width/w.height,ee=Math.abs(O),te=Math.abs(H),h=ee>=te,S,T,U=w.x,J=w.y;switch(V){case"bottomRight":{S=h?w.width+O:(w.height+H)*A,S=Math.max(ae,Math.min(S,k.width-w.x)),T=S/A;break}case"bottomLeft":{S=h?w.width-O:(w.height+H)*A,S=Math.max(ae,S),T=S/A,U=w.x+w.width-S,U=Math.max(0,U),S=Math.min(S,w.x+w.width),T=S/A;break}case"topRight":{S=h?w.width+O:(w.height-H)*A,S=Math.max(ae,Math.min(S,k.width-w.x)),T=S/A,J=w.y+w.height-T,J=Math.max(0,J),T=Math.min(T,w.y+w.height),S=T*A;break}case"topLeft":{S=h?w.width-O:(w.height-H)*A,S=Math.max(ae,S),T=S/A,U=w.x+w.width-S,J=w.y+w.height-T,U=Math.max(0,U),J=Math.max(0,J),S=Math.min(S,w.x+w.width),T=S/A,J=w.y+w.height-T;break}}S=Math.max(ae,Math.round(S)),T=Math.max(ae,Math.round(T)),v.setFreeDimensions(S,T,Math.round(U),Math.round(J))},onPanResponderRelease:()=>M(false),onPanResponderTerminate:()=>M(false)}),[k.width,k.height,x,c]),N=nt(()=>({topLeft:E("topLeft"),topRight:E("topRight"),bottomLeft:E("bottomLeft"),bottomRight:E("bottomRight")}),[E]),G={...Go,opacity:g};return Se(s,{style:{position:"absolute",left:t,top:n,width:a,height:r},pointerEvents:c?"none":"auto",children:[P(s,{style:ne.absoluteFill,...c?{}:L.panHandlers,children:P(at,{uri:e,style:G,invertX:m,invertY:b})}),P(s,{pointerEvents:"none",style:[I.freeBorder,d&&I.freeBorderActive,c&&I.freeBorderLocked]}),!c&&Se(rt,{children:[P(s,{...N.topLeft.panHandlers,style:[I.cornerWrapper,{top:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:P(s,{style:[I.cornerHandle,d&&I.cornerHandleActive]})}),P(s,{...N.topRight.panHandlers,style:[I.cornerWrapper,{top:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:P(s,{style:[I.cornerHandle,d&&I.cornerHandleActive]})}),P(s,{...N.bottomLeft.panHandlers,style:[I.cornerWrapper,{bottom:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:P(s,{style:[I.cornerHandle,d&&I.cornerHandleActive]})}),P(s,{...N.bottomRight.panHandlers,style:[I.cornerWrapper,{bottom:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:P(s,{style:[I.cornerHandle,d&&I.cornerHandleActive]})})]})]})}function Zo(){let[e,t]=tt(()=>v.getState());$o(()=>v.subscribe(t),[]);let{mode:n,enabled:a,imageUri:r,imageWidth:g,imageHeight:x,targetRect:m,targetLabel:b,showOutline:c,opacity:d,scale:M,offsetX:X,offsetY:u,invertX:k,invertY:L,locked:E,freeX:N,freeY:G,freeWidth:V,freeHeight:C}=e,z=g&&x&&x>0?g/x:0;if(n==="free"&&a&&r)return P(s,{style:I.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:P(Qo,{imageUri:r,x:N,y:G,width:V,height:C,opacity:d,aspectRatio:z,invertX:k,invertY:L,locked:E})});if(!m)return null;let O=a&&r;return Se(s,{style:I.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:[c&&Se(rt,{children:[P(s,{pointerEvents:"none",nativeID:"__image_overlay_highlight__",style:[I.highlight,{left:m.x-3,top:m.y-3,width:m.width+6,height:m.height+6}]}),b&&P(s,{pointerEvents:"none",style:[I.label,{left:m.x,top:m.y-20}],children:P(f,{style:I.labelText,children:b})})]}),O&&(()=>{let H=(g??m.width)*M,w=(x??m.height)*M,A=m.x+m.width/2,ee=m.y+m.height/2,te={position:"absolute",left:A-H/2+X,top:ee-w/2+u,width:H,height:w,opacity:d};return P(at,{uri:r,style:te,invertX:k,invertY:L})})()]})}var I=ne.create({overlay:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:999999,elevation:999999,borderWidth:0},highlight:{position:"absolute",borderWidth:2,borderStyle:"dashed",borderColor:"#20C997",backgroundColor:"transparent"},label:{position:"absolute",backgroundColor:"#20C997",paddingHorizontal:6,paddingVertical:2,borderRadius:3},labelText:{color:"#fff",fontSize:10,fontWeight:"700",fontFamily:Jo},freeBorder:{position:"absolute",top:-6,left:-6,right:-6,bottom:-6,borderWidth:1,borderColor:"transparent",borderRadius:4},freeBorderActive:{borderColor:"#20C997",borderStyle:"dashed"},freeBorderLocked:{borderColor:"#f59e0b",borderStyle:"solid"},cornerWrapper:{position:"absolute",width:24,height:24,zIndex:1e3,alignItems:"center",justifyContent:"center"},cornerHandle:{width:12,height:12,borderRadius:6,backgroundColor:"#20C997",borderWidth:2,borderColor:"#fff"},cornerHandleActive:{backgroundColor:"#10b981",shadowColor:"#10b981",shadowOffset:{width:0,height:0},shadowOpacity:.8,shadowRadius:6}});export{v as ImageOverlayController,Oe as ImageOverlayModal,Zo as ImageOverlayStandalone,jo as ImageOverlayToolView,Ko as createImageOverlayTool,et as imageOverlayToolPreset,he as scanForImageTargets,Ro as setDevToolsHookOverride};
|
|
1
|
+
"use client";var Oe=Object.defineProperty;var lt=Object.getOwnPropertyDescriptor;var st=Object.getOwnPropertyNames;var ct=Object.prototype.hasOwnProperty;var dt=(e,t)=>{for(var n in t)Oe(e,n,{get:t[n],enumerable:true})},Ae=(e,t,n,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of st(t))!ct.call(e,r)&&r!==n&&Oe(e,r,{get:()=>t[r],enumerable:!(a=lt(t,r))||a.enumerable});return e},ut=(e,t,n)=>(Ae(e,t,"default"),n&&Ae(n,t,"default"));var en=(()=>{try{let e=globalThis.Capacitor;if(e&&typeof e.isNativePlatform=="function"&&e.isNativePlatform())return e.DEBUG===true}catch{}return process.env.NODE_ENV!=="production"})();typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);import{ImageOverlayIcon as ht,createToolFactory as gt,defineToolPreset as yt}from"@buoy-gg/shared-ui/web";var ie;function pt(){return typeof navigator>"u"||!navigator.clipboard?null:{async hasImageAsync(){if(ie=void 0,!navigator.clipboard.read)return false;let e=await navigator.clipboard.read();for(let t of e){let n=t.types.find(a=>a.startsWith("image/"));if(n)return ie=await t.getType(n),true}return false},async getImageAsync(){if(!ie)return null;let e=ie;return ie=void 0,{data:await new Promise((t,n)=>{let a=new FileReader;a.onload=()=>t(String(a.result)),a.onerror=n,a.readAsDataURL(e)})}},getStringAsync:()=>navigator.clipboard.readText()}}function ft(){return null}import{useState as le,useEffect as Se,useCallback as oe}from"react";var He={};dt(He,{AccessibilityInfo:()=>xt,ActivityIndicator:()=>fo,Alert:()=>ce,Animated:()=>wt,AppRegistry:()=>St,AppState:()=>Ct,Appearance:()=>It,BackHandler:()=>Tt,Button:()=>mo,CheckBox:()=>Et,Clipboard:()=>Rt,DeviceEventEmitter:()=>Qt,Dimensions:()=>fe,Easing:()=>Bt,FlatList:()=>Wt,I18nManager:()=>Mt,Image:()=>Ce,ImageBackground:()=>Vt,InteractionManager:()=>Pt,Keyboard:()=>Dt,KeyboardAvoidingView:()=>Ft,LayoutAnimation:()=>kt,Linking:()=>Lt,LogBox:()=>Jt,Modal:()=>yo,NativeEventEmitter:()=>Ot,NativeModules:()=>vt,PanResponder:()=>me,Picker:()=>Yt,PixelRatio:()=>At,Platform:()=>ze,Pressable:()=>go,ProgressBar:()=>Xt,RefreshControl:()=>jt,SafeAreaView:()=>Nt,ScrollView:()=>Ye,SectionList:()=>Ut,Share:()=>Ht,StatusBar:()=>_t,StyleSheet:()=>ne,Switch:()=>po,Text:()=>y,TextInput:()=>Re,Touchable:()=>$t,TouchableHighlight:()=>uo,TouchableNativeFeedback:()=>Kt,TouchableOpacity:()=>T,TouchableWithoutFeedback:()=>ho,UIManager:()=>Ee,Vibration:()=>zt,View:()=>s,VirtualizedList:()=>qt,YellowBox:()=>Gt,findNodeHandle:()=>je,unstable_createElement:()=>bt,useColorScheme:()=>Zt,useLocaleContext:()=>eo,useWindowDimensions:()=>to});ut(He,mt);import*as mt from"react-native-web";import{unstable_createElement as bt,NativeModules as vt,AccessibilityInfo as xt,Animated as wt,Appearance as It,AppRegistry as St,AppState as Ct,BackHandler as Tt,Clipboard as Rt,Dimensions as fe,Easing as Bt,I18nManager as Mt,Keyboard as Dt,InteractionManager as Pt,LayoutAnimation as kt,Linking as Lt,NativeEventEmitter as Ot,PanResponder as me,PixelRatio as At,Platform as ze,Share as Ht,StyleSheet as ne,UIManager as Ee,Vibration as zt,CheckBox as Et,FlatList as Wt,Image as Ce,ImageBackground as Vt,KeyboardAvoidingView as Ft,Picker as Yt,ProgressBar as Xt,RefreshControl as jt,SafeAreaView as Nt,SectionList as Ut,StatusBar as _t,Touchable as $t,TouchableNativeFeedback as Kt,VirtualizedList as qt,YellowBox as Gt,LogBox as Jt,DeviceEventEmitter as Qt,useColorScheme as Zt,useLocaleContext as eo,useWindowDimensions as to}from"react-native-web";import*as V from"react-native-web";import{createElement as Te,forwardRef as We,useCallback as oo,useRef as no}from"react";import{useEffect as ro,useState as ao}from"react";import{createPortal as io}from"react-dom";var lo='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';import{jsx as so}from"react/jsx-runtime";var se=Symbol.for("@buoy-gg/portal-host"),Ve=e=>{if(!(e instanceof Element))return false;if(e.closest("input, textarea, select"))return true;let t=e.closest("[contenteditable]")?.getAttribute("contenteditable")?.toLowerCase();return t===""||t==="true"||t==="plaintext-only"};function Fe(){let e=document;if(e[se])return e[se].host;let t=document.createElement("div");t.dataset.buoyPortalHost="",Object.assign(t.style,{position:"fixed",inset:"0",zIndex:"2147483647",pointerEvents:"none",fontFamily:lo});let n=()=>{let c=document.fullscreenElement,R=c&&c.tagName!=="CANVAS"?c:document.body;t.parentElement!==R&&R.appendChild(t)},a=new Map,r=c=>{(!t.contains(c.target)||!Ve(c.target))&&a.set(c.code||c.key,{key:c.key,code:c.code,location:c.location,keyCode:c.keyCode,which:c.which,altKey:c.altKey,ctrlKey:c.ctrlKey,metaKey:c.metaKey,shiftKey:c.shiftKey})},g=c=>{a.delete(c.code||c.key)},w=()=>a.clear(),p=()=>{let c=[...a.values()];a.clear();for(let R of c)document.dispatchEvent(new KeyboardEvent("keyup",{...R,bubbles:true}))},b=c=>{Ve(c.target)&&c.stopPropagation()},d=c=>c.stopPropagation();return n(),document.addEventListener("fullscreenchange",n),document.addEventListener("keydown",r,true),document.addEventListener("keyup",g,true),window.addEventListener("blur",w),t.addEventListener("focusin",p),t.addEventListener("keydown",b),t.addEventListener("keyup",b),t.addEventListener("keypress",b),t.addEventListener("wheel",d,{passive:true}),e[se]={host:t,users:0,dispose:()=>{document.removeEventListener("fullscreenchange",n),document.removeEventListener("keydown",r,true),document.removeEventListener("keyup",g,true),window.removeEventListener("blur",w),t.remove(),delete e[se]}},t}function co({children:e}){let[t,n]=ao(null);return ro(()=>{let a=Fe(),r=document[se];return r.users++,n(a),()=>{--r.users===0&&r.dispose()}},[]),t?io(so("div",{"data-buoy-root":"",style:{display:"contents",pointerEvents:"auto"},children:e}),t):null}function N(e){let t=We((a,r)=>{let{accessibilityState:g,accessibilityValue:w,...p}=a;for(let b of["busy","checked","disabled","expanded","selected"])g?.[b]!==void 0&&p[`aria-${b}`]===void 0&&(p[`aria-${b}`]=g[b]);for(let[b,d]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))w?.[b]!==void 0&&p[`aria-${d}`]===void 0&&(p[`aria-${d}`]=w[b]);return Te(e,{...p,ref:r})}),n=e.State;return n&&Object.assign(t,{State:n}),t.displayName=e.displayName??e.name??"NativeWebView",t}var s=N(V.View),y=N(V.Text),Re=N(V.TextInput),T=N(V.TouchableOpacity),uo=N(V.TouchableHighlight),ho=N(V.TouchableWithoutFeedback),go=N(V.Pressable),Ye=N(V.ScrollView),Xe=We((e,t)=>{let n=no(null),a=oo(r=>{if(r){let g=r;for(;g.parentElement&&g.parentElement!==document.body;)g=g.parentElement;g.parentElement===document.body&&(n.current=g,Object.assign(g.style,{position:"relative",zIndex:"2147483647",pointerEvents:"auto"}),Fe().appendChild(g))}else n.current&&(document.body.appendChild(n.current),n.current=null);typeof t=="function"?t(r):t&&(t.current=r)},[t]);return Te(co,null,Te(V.Modal,{...e,ref:a}))});Xe.displayName="Modal";var yo=N(Xe),po=N(V.Switch),fo=N(V.ActivityIndicator),mo=N(V.Button),je=V.findNodeHandle,ce={alert(e,t,n,a){if(typeof document>"u")return;let r=document.createElement("dialog");r.dataset.buoyRoot="",r.setAttribute("aria-label",e),r.style.cssText="position:fixed;inset:0;margin:auto;width:min(440px,90vw);padding:24px;border:1px solid #475569;border-radius:14px;background:#17212e;color:#f1f5f9;font:14px system-ui;box-shadow:0 20px 80px #0008;z-index:2147483647";let g=document.createElement("h2");if(g.textContent=e,g.style.cssText="font-size:18px;margin:0 0 12px",r.appendChild(g),t){let d=document.createElement("p");d.textContent=t,d.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",r.appendChild(d)}let w=document.createElement("div");w.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let p=n?.length?n:[{text:"OK"}],b=()=>{r.close?.(),r.remove()};for(let d of p){let c=document.createElement("button");c.type="button",c.textContent=d.text??"OK",c.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${d.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,c.onclick=()=>{b(),d.onPress?.()},w.appendChild(c)}r.addEventListener("cancel",d=>{d.preventDefault(),a?.cancelable!==false&&(b(),a?.onDismiss?.())}),r.appendChild(w),document.body.appendChild(r),r.showModal?r.showModal():r.setAttribute("open","")}};import{JsModal as bo,ModalHeader as be,macOSColors as Ne,night as m,Trash2 as vo,SquareDashed as xo,Image as wo,PowerToggleButton as Io,windowDragProps as So,ToggleRow as Be,monoFont as Co}from"@buoy-gg/shared-ui/web";function Me(e){return new Promise(t=>{try{let n=[];e&&n.push(e),e?.canonical?.publicInstance&&n.push(e.canonical.publicInstance),e?.canonical&&e.canonical!==e&&n.push(e.canonical);for(let a of n)if(typeof a.getBoundingClientRect=="function")try{let r=a.getBoundingClientRect();if(r&&typeof r.x=="number"&&typeof r.y=="number"&&typeof r.width=="number"&&typeof r.height=="number"&&r.width>0&&r.height>0){t({x:r.x,y:r.y,width:r.width,height:r.height});return}}catch{}for(let a of n)if(typeof a.measure=="function"){let r=setTimeout(()=>t(null),200);a.measure((g,w,p,b,d,c)=>{clearTimeout(r),d!=null&&c!=null&&p!=null&&b!=null&&p>0&&b>0?t({x:d,y:c,width:p,height:b}):t(null)});return}try{let a=je(e);if(a!=null){let r=setTimeout(()=>t(null),200);Ee.measure(a,(g,w,p,b,d,c)=>{clearTimeout(r),d!=null&&c!=null&&p!=null&&b!=null&&p>0&&b>0?t({x:d,y:c,width:p,height:b}):t(null)});return}}catch{}t(null)}catch{t(null)}})}var Ue=null;function To(e){Ue=e??null}function _e(){return Ue||(typeof globalThis>"u"?null:globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__??null)}var $e="image-target:",Ro=5,Bo=22;function Mo(){let e=_e();if(!e?.getFiberRoots)return[];let t=new Set,n=e.renderers?.keys?Array.from(e.renderers.keys()):[1];for(let a of n)try{e.getFiberRoots(a)?.forEach(r=>t.add(r))}catch{}return[...t]}function Do(e){return e.tag===Bo&&e.memoizedState!==null}function Po(e){return e.memoizedProps?.activityState===0}function de(e,t,n=0,a=new Set){if(!(!e||a.has(e)||n>500)){if(a.add(e),Do(e)){e.sibling&&de(e.sibling,t,n,a);return}if(Po(e)){e.sibling&&de(e.sibling,t,n,a);return}t(e,n),e.child&&de(e.child,t,n+1,a),e.sibling&&de(e.sibling,t,n,a)}}function ko(e){let t=new Set(["View","RCTView","Text","RCTText","Image","RCTImageView","ScrollView","RCTScrollView","TextInput","RCTTextInput","TouchableOpacity","TouchableHighlight","TouchableWithoutFeedback","Pressable","FlatList","SectionList","SafeAreaView"]),n=e._debugOwner||e.return,a=0;for(;n&&a<30;){a++;let r=n.type;if(r){let g=typeof r=="string"?r:r.displayName||r.name;if(g&&!t.has(g))return g}n=n.return}return null}function ue(){let e=Mo();if(e.length===0)return[];let t=[];for(let n of e)de(n.current,a=>{if(a.tag!==Ro)return;let r=a.memoizedProps?.testID??a.pendingProps?.testID??a.memoizedProps?.["data-testid"]??a.pendingProps?.["data-testid"];if(!r||!r.startsWith($e))return;let g=r.slice($e.length);g&&t.push({label:g,testID:r,fiber:a,instance:a.stateNode,componentName:ko(a)})});return t}var Ke={mode:null,enabled:false,imageUri:null,imageWidth:null,imageHeight:null,targetTag:null,targetLabel:null,targetRect:null,showOutline:true,opacity:.5,scale:1,offsetX:0,offsetY:0,invertX:false,invertY:false,locked:false,freeX:0,freeY:0,freeWidth:200,freeHeight:200},i={...Ke},De=new Set,K=null,ve=null,he=false,ge=null,Lo=null;function B(){for(let e of De)e(i)}function Oo(e){return e?typeof e._nativeTag=="number"?e._nativeTag:typeof e.canonical?._nativeTag=="number"?e.canonical._nativeTag:typeof e.__nativeTag=="number"?e.__nativeTag:null:null}async function qe(e,t){let n=await Me(e);if(n)return{rect:n,freshInstance:e};let a=ue().find(r=>r.label===t);return a&&(n=await Me(a.instance),n)?{rect:n,freshInstance:a.instance}:{rect:null,freshInstance:e}}function Ao(){if(ge)return;let e=_e();if(e){if(e.rendererInterfaces)for(let[,t]of e.rendererInterfaces)typeof t.setTraceUpdatesEnabled=="function"&&t.setTraceUpdatesEnabled(true);typeof e.sub=="function"&&(ge=e.sub("traceUpdates",Eo))}}var re=null,Pe=false;function Ho(){if(re!==null||typeof requestAnimationFrame!="function")return;let e=()=>{re=requestAnimationFrame(e),!(Pe||!he||!K)&&(Pe=true,Je().finally(()=>{Pe=false}))};re=requestAnimationFrame(e)}function zo(){re!==null&&typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(re),re=null}function Ge(){zo(),ge&&(ge(),ge=null)}function Eo(e){!he||!K||Je()}function Je(){return Me(K).then(e=>{if(e&&i.targetRect){let t=i.targetRect;(Math.abs(e.x-t.x)>.5||Math.abs(e.y-t.y)>.5||Math.abs(e.width-t.width)>.5||Math.abs(e.height-t.height)>.5)&&(i={...i,targetRect:e},B())}}).catch(()=>{})}function Qe(e){return new Promise(t=>{Ce.getSize(e,(n,a)=>t({width:n,height:a}),()=>t(null))})}var v={subscribe(e){return De.add(e),e(i),()=>De.delete(e)},getState(){return i},async setTarget(e,t,n){K=e,ve=t;let a=n?.stateNode??e,{rect:r,freshInstance:g}=await qe(a,t);K=g;let w=Oo(K);i={...i,mode:"component",targetTag:w,targetLabel:t,targetRect:r},B()},async setImageUri(e){let t=await Qe(e),n=1;t&&i.targetRect&&t.width>0&&(n=i.targetRect.width/t.width),i={...i,imageUri:e,imageWidth:t?.width??null,imageHeight:t?.height??null,scale:n,showOutline:false},B()},setOpacity(e){i={...i,opacity:Math.max(0,Math.min(1,e))},B()},setScale(e){i={...i,scale:Math.max(.01,Math.min(5,e))},B()},setOffset(e,t){i={...i,offsetX:e,offsetY:t},B()},toggleInvertX(){i={...i,invertX:!i.invertX},B()},toggleInvertY(){i={...i,invertY:!i.invertY},B()},setLocked(e){i={...i,locked:e},B()},setAutoTrack(e){he=e,e?(Ao(),Ho()):Ge()},isAutoTracking(){return he},setShowOutline(e){i={...i,showOutline:e},B()},setEnabled(e){i={...i,enabled:e},B()},toggle(){i={...i,enabled:!i.enabled},B()},fitWidth(){i.imageWidth&&i.targetRect&&i.imageWidth>0&&(i={...i,scale:i.targetRect.width/i.imageWidth},B())},fitHeight(){i.imageHeight&&i.targetRect&&i.imageHeight>0&&(i={...i,scale:i.targetRect.height/i.imageHeight},B())},resetSettings(){if(i={...i,invertX:false,invertY:false},i.mode==="free"){let e=fe.get("window"),t=i.imageWidth??200,n=i.imageHeight??200;i={...i,opacity:.5,freeX:(e.width-t)/2,freeY:(e.height-n)/2,freeWidth:t,freeHeight:n}}else{let e=1;i.imageWidth&&i.targetRect&&i.imageWidth>0&&(e=i.targetRect.width/i.imageWidth),i={...i,opacity:.5,scale:e,offsetX:0,offsetY:0}}B()},async remeasure(){if(!ve)return;let{rect:e,freshInstance:t}=await qe(K,ve);K=t,e&&(i={...i,targetRect:e},B())},async startFreeMode(e){let t=await Qe(e),n=fe.get("window"),a=t?.width??200,r=t?.height??200,g=a,w=r,p=n.width*.8,b=n.height*.6;if(g>p||w>b){let d=Math.min(p/g,b/w);g=Math.round(g*d),w=Math.round(w*d)}i={...i,mode:"free",enabled:true,imageUri:e,imageWidth:t?.width??null,imageHeight:t?.height??null,opacity:.5,freeX:Math.round((n.width-g)/2),freeY:Math.round((n.height-w)/2),freeWidth:Math.round(g),freeHeight:Math.round(w)},B()},setFreePosition(e,t){i={...i,freeX:e,freeY:t},B()},setFreeDimensions(e,t,n,a){i={...i,freeWidth:e,freeHeight:t,freeX:n,freeY:a},B()},reset(){Ge(),he=false,Lo=null,K=null,ve=null,i={...Ke},B()}};import{ChevronRight as Wo,night as _,Hash as Vo,ToolEmptyState as Fo,monoFont as ke}from"@buoy-gg/shared-ui/web";import{jsx as $,jsxs as ye}from"react/jsx-runtime";function Yo({target:e,onSelect:t}){return ye(T,{style:F.card,onPress:t,activeOpacity:.7,testID:`buoy-image-overlay-target-${e.label}`,children:[$(s,{style:F.colorIndicator}),ye(s,{style:F.content,children:[$(s,{style:F.topRow,children:$(y,{style:F.label,numberOfLines:1,testID:`buoy-image-overlay-target-${e.label}-label`,children:e.label})}),ye(s,{style:F.bottomRow,children:[ye(s,{style:F.badgeRow,children:[ye(s,{style:F.testIdBadge,children:[$(Vo,{size:8,color:_.color.accent}),$(y,{style:F.testIdBadgeText,children:"testID"})]}),$(y,{style:F.testIdValue,numberOfLines:1,testID:`buoy-image-overlay-target-${e.label}-testid`,children:e.testID})]}),e.componentName&&$(y,{style:F.componentName,numberOfLines:1,testID:`buoy-image-overlay-target-${e.label}-component`,children:e.componentName})]})]}),$(Wo,{size:16,color:_.color.textTertiary})]})}function Xo({targets:e,onSelect:t}){return e.length===0?$(Fo,{testID:"buoy-image-overlay-empty",otto:"scanning",title:"No targets found",message:`Tag components with
|
|
2
|
+
testID="image-target:YourLabel"`}):$(Ye,{style:F.list,contentContainerStyle:F.listContent,children:e.map(n=>$(Yo,{target:n,onSelect:()=>t(n)},n.testID))})}var F=ne.create({list:{flex:1},listContent:{paddingTop:8,paddingBottom:20},card:{flexDirection:"row",alignItems:"center",paddingVertical:10,paddingHorizontal:12,marginHorizontal:12,marginBottom:6,backgroundColor:_.color.surface,borderRadius:8,borderWidth:1,borderColor:_.color.border},colorIndicator:{width:4,height:36,borderRadius:2,marginRight:10,backgroundColor:_.color.accent},content:{flex:1,marginRight:8},topRow:{flexDirection:"row",alignItems:"center",marginBottom:4},label:{fontSize:13,fontWeight:"600",color:_.color.text,flex:1},bottomRow:{gap:2},badgeRow:{flexDirection:"row",alignItems:"center",gap:4},testIdBadge:{flexDirection:"row",alignItems:"center",paddingVertical:2,paddingHorizontal:5,borderRadius:4,backgroundColor:_.color.accentSoft,gap:3},testIdBadgeText:{fontSize:9,fontWeight:"700",color:_.color.accent},testIdValue:{fontSize:11,color:_.color.text,fontFamily:ke,flex:1},componentName:{fontSize:10,color:"#a855f7",fontFamily:ke,marginTop:1},emptyState:{alignItems:"center",paddingVertical:40,paddingHorizontal:32},emptyTitle:{color:_.color.text,fontSize:14,fontWeight:"600",marginBottom:6},emptyText:{color:_.color.textTertiary,fontSize:12,textAlign:"center",lineHeight:18,fontFamily:ke}});import{useRef as J,useCallback as xe}from"react";import{night as q,monoFont as jo}from"@buoy-gg/shared-ui/web";import{jsx as W,jsxs as we}from"react/jsx-runtime";function pe({label:e,testID:t,value:n,min:a,max:r,step:g,displayValue:w,onChange:p}){let b=J(0),d=J(0),c=xe(C=>Math.max(a,Math.min(r,C)),[a,r]),R=r>a?(n-a)/(r-a):0,X=J(p),h=J(c),P=J(a),O=J(r);X.current=p,h.current=c,P.current=a,O.current=r;let z=xe(C=>{let A=C-d.current,H=Math.max(0,Math.min(1,A/b.current)),x=P.current+H*(O.current-P.current);X.current(h.current(x))},[]),j=J(me.create({onStartShouldSetPanResponder:()=>true,onMoveShouldSetPanResponder:()=>true,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:C=>{z(C.nativeEvent.pageX)},onPanResponderMove:C=>{z(C.nativeEvent.pageX)}})).current,Q=xe(C=>{b.current=C.nativeEvent.layout.width},[]),E=J(null),k=xe(()=>{E.current?.measure?.((C,A,H,x,L)=>{d.current=L})},[]);return we(s,{style:Y.controlRow,children:[W(y,{style:Y.label,children:e}),we(s,{style:Y.controlRight,children:[W(T,{style:Y.stepperButton,onPress:()=>p(c(n-g)),testID:`${t}-minus`,activeOpacity:.6,children:W(y,{style:Y.stepperButtonText,children:"-"})}),W(s,{style:Y.sliderHitArea,...j.panHandlers,testID:t,children:we(s,{ref:E,style:Y.sliderTrack,onLayout:C=>{Q(C),k()},pointerEvents:"none",children:[W(s,{style:[Y.sliderFill,{width:`${R*100}%`}]}),W(s,{style:[Y.sliderThumb,{left:`${R*100}%`}]})]})}),W(T,{style:Y.stepperButton,onPress:()=>p(c(n+g)),testID:`${t}-plus`,activeOpacity:.6,children:W(y,{style:Y.stepperButtonText,children:"+"})}),W(y,{style:Y.valueText,testID:`${t}-value`,children:w})]})]})}function Ze({opacity:e,scale:t,offsetX:n,offsetY:a,onOpacityChange:r,onScaleChange:g,onOffsetChange:w,opacityOnly:p}){return p?W(pe,{label:"Opacity",testID:"buoy-image-overlay-slider-opacity",value:e,min:0,max:1,step:.05,displayValue:`${Math.round(e*100)}%`,onChange:r}):we(s,{style:Y.container,children:[W(pe,{label:"Opacity",testID:"buoy-image-overlay-slider-opacity",value:e,min:0,max:1,step:.05,displayValue:`${Math.round(e*100)}%`,onChange:r}),W(pe,{label:"Scale",testID:"buoy-image-overlay-slider-scale",value:t,min:.05,max:3,step:.05,displayValue:`${Math.round(t*100)}%`,onChange:g}),W(pe,{label:"Offset X",testID:"buoy-image-overlay-slider-offset-x",value:n,min:-200,max:200,step:2,displayValue:`${Math.round(n)}px`,onChange:b=>w(Math.round(b),a)}),W(pe,{label:"Offset Y",testID:"buoy-image-overlay-slider-offset-y",value:a,min:-200,max:200,step:2,displayValue:`${Math.round(a)}px`,onChange:b=>w(n,Math.round(b))})]})}var Y=ne.create({container:{gap:8},controlRow:{paddingHorizontal:12,gap:4},label:{fontSize:11,fontWeight:"600",color:q.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},controlRight:{flexDirection:"row",alignItems:"center",gap:6},stepperButton:{zIndex:1,width:28,height:28,borderRadius:6,backgroundColor:q.color.surfaceElevated,borderWidth:1,borderColor:q.color.border,justifyContent:"center",alignItems:"center"},stepperButtonText:{fontSize:16,fontWeight:"700",color:q.color.text,lineHeight:18},sliderHitArea:{flex:1,paddingVertical:20,paddingHorizontal:40,marginVertical:-20,marginHorizontal:-40},sliderTrack:{height:28,justifyContent:"center",borderRadius:6,backgroundColor:q.color.bg,borderWidth:1,borderColor:q.color.border,overflow:"hidden"},sliderFill:{position:"absolute",left:0,top:0,bottom:0,backgroundColor:q.color.accentFill,borderRadius:5},sliderThumb:{position:"absolute",width:4,top:4,bottom:4,marginLeft:-2,borderRadius:2,backgroundColor:q.color.accent},valueText:{fontSize:11,fontWeight:"600",color:q.color.text,width:45,textAlign:"right",fontFamily:jo}});import{Fragment as et,jsx as l,jsxs as f}from"react/jsx-runtime";var Z="";function Le({visible:e,onClose:t,onBack:n,onMinimize:a,enableSharedModalDimensions:r=false,initialModalState:g,minimizeTargetPosition:w,inline:p=false,initialView:b}){let[d,c]=le(()=>{if(b)return b;let u=v.getState();return u.mode==="free"?"free":u.targetRect?"controls":"idle"}),[R,X]=le(()=>b==="targets"?ue():[]),[h,P]=le(()=>v.getState()),[O,z]=le(Z),[j,Q]=le(()=>v.isAutoTracking());Se(()=>{Z=O},[O]),Se(()=>v.subscribe(P),[]),Se(()=>(v.setAutoTrack(j),()=>{}),[j]);let E=oe(()=>{let u=ue();X(u),c("targets")},[]),k=oe(async u=>{await v.setTarget(u.instance,u.label,u.fiber),Z.trim()&&(await v.setImageUri(Z.trim()),v.setEnabled(true)),c("controls")},[]),C=oe(async()=>{let u=Z.trim();u&&(d==="free"?await v.startFreeMode(u):(await v.setImageUri(u),v.setEnabled(true)))},[d]),A=oe(async()=>{let u=null;try{u=pt()}catch{}let I=null;if(!u)try{let S=ft();I=S.default||S}catch{}if(!u&&!I){ce.alert("Clipboard not available","Install expo-clipboard or @react-native-clipboard/clipboard to use paste.");return}try{if(u&&typeof u.hasImageAsync=="function"&&await u.hasImageAsync()){let U=await u.getImageAsync({format:"png"});if(U?.data){d==="free"?await v.startFreeMode(U.data):(await v.setImageUri(U.data),v.setEnabled(true));return}}let S=null;if(u&&typeof u.getStringAsync=="function"?S=await u.getStringAsync():I&&typeof I.getString=="function"&&(S=await I.getString()),S&&(S.startsWith("http")||S.startsWith("data:"))){z(S),Z=S;return}u?ce.alert("No image detected","Try saving your design image, opening it in Photos or Preview, and copying it from there."):ce.alert("Image paste requires expo-clipboard","Your project uses @react-native-clipboard/clipboard which only supports text. Install expo-clipboard to paste images directly, or paste an image URL instead.")}catch{ce.alert("Paste failed","Something went wrong reading the clipboard. Try copying the image again.")}},[d]),H=oe(()=>{v.reset(),Z="",c("idle"),z(""),X([])},[]),x=oe(()=>{if(d==="controls"){let u=ue();X(u),c("targets")}else(d==="targets"||d==="free")&&v.reset(),c("idle")},[d]),L=(()=>{switch(d){case"targets":return`Targets (${R.length})`;case"controls":return h.targetLabel||"Component Match";case"free":return"Free Placement";default:return"Image Overlay"}})(),ee={showToggleButton:false,customContent:f(be,{children:[l(be.Navigation,{onBack:d!=="idle"?x:n}),l(be.Content,{title:L,testID:"buoy-image-overlay-title"}),f(be.Actions,{children:[d==="targets"&&l(T,{style:o.headerTextButton,onPress:E,testID:"buoy-image-overlay-scan",activeOpacity:.7,children:l(y,{style:o.headerTextButtonLabel,children:"Scan"})}),(d==="controls"||d==="free")&&h.imageUri&&l(Io,{isEnabled:h.enabled,onToggle:()=>v.toggle(),accessibilityLabel:"Toggle image overlay",testID:"buoy-image-overlay-power"}),d!=="idle"&&l(T,{style:o.headerActionButton,onPress:H,testID:"buoy-image-overlay-clear",activeOpacity:.7,children:l(vo,{size:14,color:m.color.textSecondary})})]})]})},te=f(s,{style:o.container,children:[d==="idle"&&f(s,{style:o.homeContainer,children:[l(y,{style:o.homeSubtitle,testID:"buoy-image-overlay-home",children:"Choose a mode"}),f(s,{style:o.modeGrid,children:[f(T,{style:o.modePanel,onPress:E,testID:"buoy-image-overlay-mode-component",activeOpacity:.7,children:[l(s,{style:[o.modeIconCircle,{backgroundColor:m.color.accentSoft}],children:l(xo,{size:24,color:m.color.accent})}),f(y,{style:o.modePanelTitle,children:["Component",`
|
|
3
|
+
`,"Match"]}),l(y,{style:o.modePanelDesc,children:"Overlay on a tagged component"})]}),f(T,{style:o.modePanel,onPress:()=>c("free"),testID:"buoy-image-overlay-mode-free",activeOpacity:.7,children:[l(s,{style:[o.modeIconCircle,{backgroundColor:m.color.accentSoft}],children:l(wo,{size:24,color:m.color.accent})}),f(y,{style:o.modePanelTitle,children:["Free",`
|
|
4
|
+
`,"Placement"]}),l(y,{style:o.modePanelDesc,children:"Drag and resize anywhere"})]})]})]}),d==="targets"&&l(Xo,{targets:R,onSelect:k}),d==="controls"&&f(s,{style:o.controlsContainer,children:[h.targetRect&&f(s,{style:o.infoCard,children:[f(s,{style:o.infoRow,children:[l(y,{style:o.infoLabel,children:"Component"}),l(y,{style:o.infoValue,testID:"buoy-image-overlay-info-component",children:h.targetLabel})]}),f(s,{style:o.infoRow,children:[l(y,{style:o.infoLabel,children:"Size"}),f(y,{style:o.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(h.targetRect.width)," x ",Math.round(h.targetRect.height)]})]}),f(s,{style:o.infoRow,children:[l(y,{style:o.infoLabel,children:"Position"}),f(y,{style:o.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(h.targetRect.x),", ",Math.round(h.targetRect.y)]})]}),h.imageWidth!=null&&h.imageHeight!=null&&f(s,{style:o.infoRow,children:[l(y,{style:o.infoLabel,children:"Image"}),f(y,{style:o.infoValueMono,testID:"buoy-image-overlay-info-image",children:[h.imageWidth," x ",h.imageHeight]})]})]}),f(s,{style:o.inputSection,children:[l(y,{style:o.sectionLabel,children:"Image"}),l(T,{style:o.pasteButton,onPress:A,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:l(y,{style:o.pasteButtonText,children:"Paste from Clipboard"})}),f(s,{style:o.urlRow,children:[l(Re,{style:o.urlInput,testID:"buoy-image-overlay-url",value:O,onChangeText:z,placeholder:"or enter URL...",placeholderTextColor:m.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:C}),l(T,{style:[o.loadButton,!O.trim()&&o.loadButtonDisabled],onPress:C,disabled:!O.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:l(y,{style:o.loadButtonText,children:"Load"})})]})]}),f(s,{style:o.toggleSection,children:[l(Be,{label:"Show Outline",testID:"buoy-image-overlay-outline-toggle",value:h.showOutline,onValueChange:u=>v.setShowOutline(u)}),l(Be,{label:"Auto Track",value:j,onValueChange:Q,testID:"buoy-image-overlay-autotrack"}),h.imageUri&&f(et,{children:[f(s,{style:o.blendRow,children:[l(y,{style:o.toggleLabel,children:"Opacity"}),l(s,{style:o.blendButtons,children:[0,25,50,75,100].map(u=>l(T,{testID:`buoy-image-overlay-opacity-${u}`,style:[o.blendButton,Math.round(h.opacity*100)===u&&o.blendButtonActive],onPress:()=>v.setOpacity(u/100),activeOpacity:.7,children:f(y,{style:[o.blendButtonText,Math.round(h.opacity*100)===u&&o.blendButtonTextActive],children:[u,"%"]})},u))})]}),f(s,{style:o.blendRow,children:[l(y,{style:o.toggleLabel,children:"Flip"}),f(s,{style:o.blendButtons,children:[l(T,{style:[o.blendButton,h.invertX&&o.blendButtonActive],onPress:()=>v.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:l(y,{style:[o.blendButtonText,h.invertX&&o.blendButtonTextActive],testID:h.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),l(T,{style:[o.blendButton,h.invertY&&o.blendButtonActive],onPress:()=>v.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:l(y,{style:[o.blendButtonText,h.invertY&&o.blendButtonTextActive],testID:h.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]})]}),h.imageUri&&l(Ze,{opacity:h.opacity,scale:h.scale,offsetX:h.offsetX,offsetY:h.offsetY,onOpacityChange:u=>v.setOpacity(u),onScaleChange:u=>v.setScale(u),onOffsetChange:(u,I)=>v.setOffset(u,I)}),f(s,{style:o.actions,children:[l(T,{style:o.actionButton,onPress:()=>v.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-settings",children:l(y,{style:o.actionButtonText,children:"Reset Settings"})}),l(T,{style:o.actionButton,onPress:()=>v.remeasure(),activeOpacity:.7,testID:"buoy-image-overlay-remeasure",children:l(y,{style:o.actionButtonText,children:"Remeasure"})})]})]}),d==="free"&&f(s,{style:o.controlsContainer,children:[f(s,{style:o.inputSection,children:[l(y,{style:o.sectionLabel,children:"Image"}),l(T,{style:o.pasteButton,onPress:A,activeOpacity:.7,accessibilityLabel:"Paste from clipboard",accessibilityRole:"button",testID:"buoy-image-overlay-paste",children:l(y,{style:o.pasteButtonText,children:"Paste from Clipboard"})}),f(s,{style:o.urlRow,children:[l(Re,{style:o.urlInput,testID:"buoy-image-overlay-url",value:O,onChangeText:z,placeholder:"or enter URL...",placeholderTextColor:m.color.placeholder,autoCapitalize:"none",autoCorrect:false,returnKeyType:"go",onSubmitEditing:C}),l(T,{style:[o.loadButton,!O.trim()&&o.loadButtonDisabled],onPress:C,disabled:!O.trim(),activeOpacity:.7,testID:"buoy-image-overlay-load",children:l(y,{style:o.loadButtonText,children:"Load"})})]})]}),h.imageUri&&h.mode==="free"&&f(et,{children:[f(s,{style:o.infoCard,children:[f(s,{style:o.infoRow,children:[l(y,{style:o.infoLabel,children:"Position"}),f(y,{style:o.infoValueMono,testID:"buoy-image-overlay-info-position",children:[Math.round(h.freeX),", ",Math.round(h.freeY)]})]}),f(s,{style:o.infoRow,children:[l(y,{style:o.infoLabel,children:"Size"}),f(y,{style:o.infoValueMono,testID:"buoy-image-overlay-info-size",children:[Math.round(h.freeWidth)," x ",Math.round(h.freeHeight)]})]}),h.imageWidth!=null&&h.imageHeight!=null&&f(s,{style:o.infoRow,children:[l(y,{style:o.infoLabel,children:"Original"}),f(y,{style:o.infoValueMono,testID:"buoy-image-overlay-info-original",children:[h.imageWidth," x ",h.imageHeight]})]})]}),l(s,{style:o.inputSection,children:l(Ze,{opacity:h.opacity,scale:1,offsetX:0,offsetY:0,onOpacityChange:u=>v.setOpacity(u),onScaleChange:()=>{},onOffsetChange:()=>{},opacityOnly:true})}),f(s,{style:o.toggleSection,children:[l(Be,{label:"Lock Position",testID:"buoy-image-overlay-lock",tone:"warning",value:h.locked,onValueChange:u=>v.setLocked(u)}),f(s,{style:o.blendRow,children:[l(y,{style:o.toggleLabel,children:"Opacity"}),l(s,{style:o.blendButtons,children:[0,25,50,75,100].map(u=>l(T,{testID:`buoy-image-overlay-opacity-${u}`,style:[o.blendButton,Math.round(h.opacity*100)===u&&o.blendButtonActive],onPress:()=>v.setOpacity(u/100),activeOpacity:.7,children:f(y,{style:[o.blendButtonText,Math.round(h.opacity*100)===u&&o.blendButtonTextActive],children:[u,"%"]})},u))})]}),f(s,{style:o.blendRow,children:[l(y,{style:o.toggleLabel,children:"Flip"}),f(s,{style:o.blendButtons,children:[l(T,{style:[o.blendButton,h.invertX&&o.blendButtonActive],onPress:()=>v.toggleInvertX(),testID:"buoy-image-overlay-flip-x",activeOpacity:.7,children:l(y,{style:[o.blendButtonText,h.invertX&&o.blendButtonTextActive],testID:h.invertX?"buoy-image-overlay-flip-x-on":void 0,children:"Horizontal"})}),l(T,{style:[o.blendButton,h.invertY&&o.blendButtonActive],onPress:()=>v.toggleInvertY(),testID:"buoy-image-overlay-flip-y",activeOpacity:.7,children:l(y,{style:[o.blendButtonText,h.invertY&&o.blendButtonTextActive],testID:h.invertY?"buoy-image-overlay-flip-y-on":void 0,children:"Vertical"})})]})]})]}),l(s,{style:o.actions,children:l(T,{style:o.actionButton,onPress:()=>v.resetSettings(),activeOpacity:.7,testID:"buoy-image-overlay-reset-position",children:l(y,{style:o.actionButtonText,children:"Reset Position"})})})]})]})]});return p?f(s,{style:o.inlineRoot,children:[l(s,{style:o.inlineHeader,...So,children:ee.customContent}),te]}):l(bo,{visible:e,onClose:t,onMinimize:a,minimizeTargetPosition:w,initialModalState:g,header:ee,initialMode:"bottomSheet",persistenceKey:"buoy-image-overlay-modal",enablePersistence:true,children:te})}function No(e={}){return l(Le,{...e,inline:true,visible:true,onClose:()=>{}})}var o=ne.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:Ne.background.base},inlineHeader:{borderBottomWidth:1,borderBottomColor:Ne.border.default,backgroundColor:"transparent"},container:{flex:1,backgroundColor:"transparent"},headerTextButton:{height:32,paddingHorizontal:12,borderRadius:8,backgroundColor:m.color.buttonSurface,borderWidth:1,borderColor:m.color.border,alignItems:"center",justifyContent:"center"},headerTextButtonLabel:{fontSize:12,fontWeight:"600",color:m.color.accent},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:m.color.buttonSurface,borderWidth:1,borderColor:m.color.border,alignItems:"center",justifyContent:"center"},homeContainer:{flex:1,paddingHorizontal:12,paddingTop:16,paddingBottom:20,gap:12},homeSubtitle:{fontSize:12,fontWeight:"600",color:m.color.textTertiary,textTransform:"uppercase",letterSpacing:.5,textAlign:"center"},modeGrid:{flexDirection:"row",gap:10},modePanel:{flex:1,alignItems:"center",paddingVertical:20,paddingHorizontal:12,backgroundColor:m.color.surface,borderRadius:12,borderWidth:1,borderColor:m.color.border,gap:8},modeIconCircle:{width:48,height:48,borderRadius:24,alignItems:"center",justifyContent:"center",marginBottom:4},modePanelTitle:{fontSize:13,fontWeight:"700",color:m.color.text,textAlign:"center",lineHeight:17},modePanelDesc:{fontSize:11,color:m.color.textTertiary,textAlign:"center",lineHeight:15},controlsContainer:{flex:1,paddingTop:8,paddingBottom:24,gap:10},infoCard:{marginHorizontal:12,backgroundColor:m.color.surface,borderRadius:8,borderWidth:1,borderColor:m.color.border,padding:10,gap:4},infoRow:{flexDirection:"row",justifyContent:"space-between",alignItems:"center"},infoLabel:{fontSize:11,fontWeight:"500",color:m.color.textTertiary,textTransform:"uppercase",letterSpacing:.3},infoValue:{fontSize:12,fontWeight:"600",color:m.color.text},infoValueMono:{fontSize:12,fontWeight:"600",color:m.color.text,fontFamily:Co},inputSection:{paddingHorizontal:12,gap:6},sectionLabel:{fontSize:11,fontWeight:"600",color:m.color.textTertiary,textTransform:"uppercase",letterSpacing:.5},pasteButton:{paddingVertical:10,borderRadius:8,backgroundColor:m.color.accentSoft,borderWidth:1,borderColor:m.color.accentBorderStrong,alignItems:"center"},pasteButtonText:{fontSize:13,fontWeight:"600",color:m.color.accent},urlRow:{flexDirection:"row",gap:8},urlInput:{flex:1,height:36,borderRadius:10,backgroundColor:m.color.surfaceElevated,borderWidth:1,borderColor:m.color.border,paddingHorizontal:12,fontSize:13,color:m.color.text},loadButton:{height:36,paddingHorizontal:14,borderRadius:8,backgroundColor:m.color.accent,justifyContent:"center",alignItems:"center"},loadButtonDisabled:{opacity:.4},loadButtonText:{fontSize:13,fontWeight:"600",color:m.color.onAccent},toggleSection:{paddingHorizontal:12,gap:6},toggleRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:m.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:m.color.border,paddingHorizontal:12,paddingVertical:8},toggleLabel:{fontSize:13,fontWeight:"500",color:m.color.textSecondary},blendRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",backgroundColor:m.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:m.color.border,paddingHorizontal:12,paddingVertical:6},blendButtons:{flexDirection:"row",gap:4},blendButton:{paddingHorizontal:10,paddingVertical:5,borderRadius:6,backgroundColor:"transparent"},blendButtonActive:{backgroundColor:m.color.accentSoft},blendButtonText:{fontSize:12,fontWeight:"600",color:m.color.textTertiary},blendButtonTextActive:{color:m.color.accent},actions:{flexDirection:"row",paddingHorizontal:12,gap:8,marginTop:4},actionButton:{flex:1,flexDirection:"row",alignItems:"center",justifyContent:"center",gap:6,paddingVertical:8,paddingHorizontal:12,borderRadius:8,backgroundColor:m.color.surfaceElevated,borderWidth:1,borderColor:m.color.border},actionButtonText:{fontSize:12,fontWeight:"500",color:m.color.textSecondary}});import{jsx as Uo}from"react/jsx-runtime";var _o="#A855F7",tt=yt({id:"image-overlay",name:"IMG",description:"Design mockup overlay",slot:"both",icon:({size:e})=>Uo(ht,{size:e,color:_o}),component:Le,props:{enableSharedModalDimensions:false}}),$o=gt(tt,e=>({enableSharedModalDimensions:e.enableSharedModalDimensions??false}));import{useState as ot,useEffect as Ko,useRef as nt,useMemo as rt,useCallback as qo}from"react";import{absoluteFill as Go,monoFont as Jo}from"@buoy-gg/shared-ui/web";import{Fragment as at,jsx as D,jsxs as Ie}from"react/jsx-runtime";function it({uri:e,style:t,invertX:n,invertY:a}){let r=[];n&&r.push({scaleX:-1}),a&&r.push({scaleY:-1});let g=r.length>0?{transform:r}:{};return D(Ce,{testID:"buoy-internal-image-overlay",source:{uri:e},style:[t,g],pointerEvents:"none"})}var ae=30;function Qo({imageUri:e,x:t,y:n,width:a,height:r,opacity:g,aspectRatio:w,invertX:p,invertY:b,locked:d}){let[c,R]=ot(false),X=nt({x:0,y:0}),h=nt({x:0,y:0,width:0,height:0}),P=fe.get("window"),O=rt(()=>me.create({onStartShouldSetPanResponder:()=>!d,onMoveShouldSetPanResponder:(E,k)=>!d&&(Math.abs(k.dx)>2||Math.abs(k.dy)>2),onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{let E=v.getState();X.current={x:E.freeX,y:E.freeY},R(true)},onPanResponderMove:(E,k)=>{let C=v.getState(),A=Math.max(0,Math.min(X.current.x+k.dx,P.width-C.freeWidth)),H=Math.max(0,Math.min(X.current.y+k.dy,P.height-C.freeHeight));v.setFreePosition(A,H)},onPanResponderRelease:()=>R(false),onPanResponderTerminate:()=>R(false)}),[P.width,P.height,d]),z=qo(E=>me.create({onStartShouldSetPanResponder:()=>!d,onMoveShouldSetPanResponder:()=>!d,onPanResponderTerminationRequest:()=>false,onPanResponderGrant:()=>{let k=v.getState();h.current={x:k.freeX,y:k.freeY,width:k.freeWidth,height:k.freeHeight},R(true)},onPanResponderMove:(k,C)=>{let{dx:A,dy:H}=C;if(Math.abs(A)<.5&&Math.abs(H)<.5)return;let x=h.current,L=w>0?w:x.width/x.height,ee=Math.abs(A),te=Math.abs(H),u=ee>=te,I,S,U=x.x,G=x.y;switch(E){case"bottomRight":{I=u?x.width+A:(x.height+H)*L,I=Math.max(ae,Math.min(I,P.width-x.x)),S=I/L;break}case"bottomLeft":{I=u?x.width-A:(x.height+H)*L,I=Math.max(ae,I),S=I/L,U=x.x+x.width-I,U=Math.max(0,U),I=Math.min(I,x.x+x.width),S=I/L;break}case"topRight":{I=u?x.width+A:(x.height-H)*L,I=Math.max(ae,Math.min(I,P.width-x.x)),S=I/L,G=x.y+x.height-S,G=Math.max(0,G),S=Math.min(S,x.y+x.height),I=S*L;break}case"topLeft":{I=u?x.width-A:(x.height-H)*L,I=Math.max(ae,I),S=I/L,U=x.x+x.width-I,G=x.y+x.height-S,U=Math.max(0,U),G=Math.max(0,G),I=Math.min(I,x.x+x.width),S=I/L,G=x.y+x.height-S;break}}I=Math.max(ae,Math.round(I)),S=Math.max(ae,Math.round(S)),v.setFreeDimensions(I,S,Math.round(U),Math.round(G))},onPanResponderRelease:()=>R(false),onPanResponderTerminate:()=>R(false)}),[P.width,P.height,w,d]),j=rt(()=>({topLeft:z("topLeft"),topRight:z("topRight"),bottomLeft:z("bottomLeft"),bottomRight:z("bottomRight")}),[z]),Q={...Go,opacity:g};return Ie(s,{testID:"buoy-image-overlay-free-box",style:{position:"absolute",left:t,top:n,width:a,height:r},pointerEvents:d?"none":"auto",children:[D(s,{style:ne.absoluteFill,...d?{}:O.panHandlers,children:D(it,{uri:e,style:Q,invertX:p,invertY:b})}),D(s,{pointerEvents:"none",style:[M.freeBorder,c&&M.freeBorderActive,d&&M.freeBorderLocked]}),!d&&Ie(at,{children:[D(s,{...j.topLeft.panHandlers,style:[M.cornerWrapper,{top:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:D(s,{style:[M.cornerHandle,c&&M.cornerHandleActive]})}),D(s,{...j.topRight.panHandlers,style:[M.cornerWrapper,{top:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:D(s,{style:[M.cornerHandle,c&&M.cornerHandleActive]})}),D(s,{...j.bottomLeft.panHandlers,style:[M.cornerWrapper,{bottom:-20,left:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:D(s,{style:[M.cornerHandle,c&&M.cornerHandleActive]})}),D(s,{...j.bottomRight.panHandlers,style:[M.cornerWrapper,{bottom:-20,right:-20}],hitSlop:{top:10,left:10,right:10,bottom:10},children:D(s,{style:[M.cornerHandle,c&&M.cornerHandleActive]})})]})]})}function Zo(){let[e,t]=ot(()=>v.getState());Ko(()=>v.subscribe(t),[]);let{mode:n,enabled:a,imageUri:r,imageWidth:g,imageHeight:w,targetRect:p,targetLabel:b,showOutline:d,opacity:c,scale:R,offsetX:X,offsetY:h,invertX:P,invertY:O,locked:z,freeX:j,freeY:Q,freeWidth:E,freeHeight:k}=e,C=g&&w&&w>0?g/w:0;if(n==="free"&&a&&r)return D(s,{style:M.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:D(Qo,{imageUri:r,x:j,y:Q,width:E,height:k,opacity:c,aspectRatio:C,invertX:P,invertY:O,locked:z})});if(!p)return null;let A=a&&r;return Ie(s,{style:M.overlay,pointerEvents:"box-none",nativeID:"image-overlay-standalone",children:[d&&Ie(at,{children:[D(s,{pointerEvents:"none",nativeID:"__image_overlay_highlight__",testID:"buoy-image-overlay-outline",style:[M.highlight,{left:p.x-3,top:p.y-3,width:p.width+6,height:p.height+6}]}),b&&D(s,{pointerEvents:"none",style:[M.label,{left:p.x,top:p.y-20}],children:D(y,{style:M.labelText,testID:"buoy-image-overlay-outline-label",children:b})})]}),A&&(()=>{let H=(g??p.width)*R,x=(w??p.height)*R,L=p.x+p.width/2,ee=p.y+p.height/2,te={position:"absolute",left:L-H/2+X,top:ee-x/2+h,width:H,height:x,opacity:c};return D(it,{uri:r,style:te,invertX:P,invertY:O})})()]})}var M=ne.create({overlay:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:ze.OS==="web"?999:999999,elevation:999999,borderWidth:0},highlight:{position:"absolute",borderWidth:2,borderStyle:"dashed",borderColor:"#20C997",backgroundColor:"transparent"},label:{position:"absolute",backgroundColor:"#20C997",paddingHorizontal:6,paddingVertical:2,borderRadius:3},labelText:{color:"#fff",fontSize:10,fontWeight:"700",fontFamily:Jo},freeBorder:{position:"absolute",top:-6,left:-6,right:-6,bottom:-6,borderWidth:1,borderColor:"transparent",borderRadius:4},freeBorderActive:{borderColor:"#20C997",borderStyle:"dashed"},freeBorderLocked:{borderColor:"#f59e0b",borderStyle:"solid"},cornerWrapper:{position:"absolute",width:24,height:24,zIndex:1e3,alignItems:"center",justifyContent:"center"},cornerHandle:{width:12,height:12,borderRadius:6,backgroundColor:"#20C997",borderWidth:2,borderColor:"#fff"},cornerHandleActive:{backgroundColor:"#10b981",shadowColor:"#10b981",shadowOffset:{width:0,height:0},shadowOpacity:.8,shadowRadius:6}});export{v as ImageOverlayController,Le as ImageOverlayModal,Zo as ImageOverlayStandalone,No as ImageOverlayToolView,$o as createImageOverlayTool,tt as imageOverlayToolPreset,ue as scanForImageTargets,To as setDevToolsHookOverride};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buoy-gg/image-overlay",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.70",
|
|
4
4
|
"description": "Overlay a design mockup on a running React Native app and adjust opacity to compare spacing and alignment.",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
],
|
|
35
35
|
"sideEffects": false,
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@buoy-gg/shared-ui": "^7.0.
|
|
37
|
+
"@buoy-gg/shared-ui": "^7.0.70"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"react": "*"
|