@np-dev/ui-ai-anotation 0.1.0
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/README.md +245 -0
- package/dist/cjs/index.cjs +1550 -0
- package/dist/cjs/index.cjs.map +7 -0
- package/dist/cjs/index.native.cjs +1004 -0
- package/dist/cjs/index.native.cjs.map +7 -0
- package/dist/cjs/index.web.cjs +83 -0
- package/dist/cjs/index.web.cjs.map +7 -0
- package/dist/esm/index.js +1524 -0
- package/dist/esm/index.js.map +7 -0
- package/dist/esm/index.native.js +1012 -0
- package/dist/esm/index.native.js.map +7 -0
- package/dist/esm/index.web.js +62 -0
- package/dist/esm/index.web.js.map +7 -0
- package/dist/types/components/AnnotationInput.d.ts +8 -0
- package/dist/types/components/AnnotationList.d.ts +1 -0
- package/dist/types/components/Draggable.d.ts +10 -0
- package/dist/types/components/Highlighter.d.ts +1 -0
- package/dist/types/components/Toolbar.d.ts +1 -0
- package/dist/types/index.d.ts +20 -0
- package/dist/types/index.web.d.ts +69 -0
- package/dist/types/store.d.ts +66 -0
- package/dist/types/utils/fiber.d.ts +51 -0
- package/dist/types/utils/platform.d.ts +8 -0
- package/dist/types/utils/screenshot.d.ts +28 -0
- package/package.json +115 -0
- package/src/components/AnnotationInput.tsx +269 -0
- package/src/components/AnnotationList.tsx +248 -0
- package/src/components/Draggable.tsx +73 -0
- package/src/components/Highlighter.tsx +497 -0
- package/src/components/Toolbar.tsx +213 -0
- package/src/components/native/AnnotationInput.tsx +227 -0
- package/src/components/native/AnnotationList.tsx +157 -0
- package/src/components/native/Draggable.tsx +65 -0
- package/src/components/native/Highlighter.tsx +239 -0
- package/src/components/native/Toolbar.tsx +192 -0
- package/src/components/native/index.ts +6 -0
- package/src/components/web/AnnotationInput.tsx +150 -0
- package/src/components/web/AnnotationList.tsx +117 -0
- package/src/components/web/Draggable.tsx +74 -0
- package/src/components/web/Highlighter.tsx +329 -0
- package/src/components/web/Toolbar.tsx +198 -0
- package/src/components/web/index.ts +6 -0
- package/src/extension.tsx +15 -0
- package/src/index.native.tsx +50 -0
- package/src/index.tsx +41 -0
- package/src/index.web.tsx +124 -0
- package/src/store.tsx +120 -0
- package/src/utils/fiber.native.ts +90 -0
- package/src/utils/fiber.ts +255 -0
- package/src/utils/platform.ts +33 -0
- package/src/utils/screenshot.native.ts +139 -0
- package/src/utils/screenshot.ts +162 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/index.native.tsx", "../../src/store.tsx", "../../src/components/native/Toolbar.tsx", "../../src/components/native/Draggable.tsx", "../../src/components/native/Highlighter.tsx", "../../src/components/native/AnnotationInput.tsx", "../../src/components/native/AnnotationList.tsx", "../../src/utils/screenshot.native.ts", "../../src/utils/fiber.native.ts", "../../src/utils/platform.ts"],
|
|
4
|
+
"sourcesContent": ["import React from 'react';\nimport { View } from 'react-native';\nimport { AiAnnotationProvider as Provider } from './store';\nimport { Toolbar } from './components/native/Toolbar';\n\nexport interface AiAnnotationProviderProps {\n children: React.ReactNode;\n}\n\n/**\n * React Native AI Annotation Provider\n * Wraps your app to provide annotation functionality\n */\nexport function AiAnnotationProvider({ children }: AiAnnotationProviderProps) {\n return (\n <Provider>\n <View style={{ flex: 1 }}>\n {children}\n <Toolbar />\n </View>\n </Provider>\n );\n}\n\n// Re-export store\nexport * from './store';\n\n// Export native components\nexport { Toolbar } from './components/native/Toolbar';\nexport { Highlighter } from './components/native/Highlighter';\nexport { AnnotationInput } from './components/native/AnnotationInput';\nexport { AnnotationList } from './components/native/AnnotationList';\nexport { Draggable } from './components/native/Draggable';\n\n// Export native screenshot utility\nexport { captureScreenshot } from './utils/screenshot.native';\nexport type { ScreenshotOptions, ScreenshotResult } from './utils/screenshot.native';\n\n// Export native fiber utilities\nexport {\n getReactFiber,\n getComponentDisplayName,\n getElementFromFiber,\n inspectComponent,\n} from './utils/fiber.native';\nexport type { ComponentInfo } from './utils/fiber.native';\n\n// Export platform utilities\nexport { isWeb, isNative, getPlatform, isTauriEnv } from './utils/platform';\nexport type { PlatformType } from './utils/platform';\n", "import React, { createContext, useContext, useReducer, ReactNode } from 'react';\nimport type { ComponentDetails, ChildComponentInfo, ElementInfo } from './utils/fiber';\n\n// Re-export types for external use\nexport type { ComponentDetails, ChildComponentInfo, ElementInfo };\n\nexport type Annotation = {\n id: string;\n componentName: string;\n note: string;\n timestamp: number;\n /** Enhanced component details (optional for backward compatibility) */\n details?: ComponentDetails;\n};\n\nexport type Mode = 'disabled' | 'inspecting';\n\n/**\n * Platform-agnostic element type\n * - On web: HTMLElement\n * - On native: View ref or null\n */\nexport type HoveredElement = any;\n\n/**\n * Enhanced component info with full details\n */\nexport interface HoveredComponentInfo {\n name: string;\n /** Full component details including hierarchy, children, and element info */\n details?: ComponentDetails;\n}\n\ninterface State {\n mode: Mode;\n annotations: Annotation[];\n hoveredElement: HoveredElement;\n hoveredComponentInfo: HoveredComponentInfo | null;\n isMinimized: boolean;\n showList: boolean;\n}\n\ntype Action =\n | { type: 'SET_MODE'; payload: Mode }\n | { type: 'ADD_ANNOTATION'; payload: Annotation }\n | { type: 'REMOVE_ANNOTATION'; payload: string }\n | { type: 'CLEAR_ALL_ANNOTATIONS' }\n | { type: 'SET_HOVERED'; payload: { element: HoveredElement; name: string | null; details?: ComponentDetails } }\n | { type: 'TOGGLE_MINIMIZED' }\n | { type: 'TOGGLE_LIST' }\n | { type: 'RESET_HOVER' };\n\nconst initialState: State = {\n mode: 'disabled',\n annotations: [],\n hoveredElement: null,\n hoveredComponentInfo: null,\n isMinimized: false,\n showList: false,\n};\n\nconst AnnotationContext = createContext<{\n state: State;\n dispatch: React.Dispatch<Action>;\n} | undefined>(undefined);\n\nfunction reducer(state: State, action: Action): State {\n switch (action.type) {\n case 'SET_MODE':\n return { ...state, mode: action.payload };\n case 'ADD_ANNOTATION':\n return { ...state, annotations: [...state.annotations, action.payload] };\n case 'REMOVE_ANNOTATION':\n return {\n ...state,\n annotations: state.annotations.filter((a) => a.id !== action.payload),\n };\n case 'CLEAR_ALL_ANNOTATIONS':\n return {\n ...state,\n annotations: [],\n };\n case 'SET_HOVERED':\n // Avoid updates if same\n if (state.hoveredElement === action.payload.element) return state;\n return {\n ...state,\n hoveredElement: action.payload.element,\n hoveredComponentInfo: action.payload.name\n ? { name: action.payload.name, details: action.payload.details }\n : null\n };\n case 'RESET_HOVER':\n return { ...state, hoveredElement: null, hoveredComponentInfo: null };\n case 'TOGGLE_MINIMIZED':\n return { ...state, isMinimized: !state.isMinimized };\n case 'TOGGLE_LIST':\n return { ...state, showList: !state.showList };\n default:\n return state;\n }\n}\n\nexport function AiAnnotationProvider({ children }: { children: ReactNode }) {\n const [state, dispatch] = useReducer(reducer, initialState);\n\n return (\n <AnnotationContext.Provider value={{ state, dispatch }}>\n {children}\n </AnnotationContext.Provider>\n );\n}\n\nexport function useAiAnnotation() {\n const context = useContext(AnnotationContext);\n if (!context) {\n throw new Error('useAiAnnotation must be used within an AiAnnotationProvider');\n }\n return context;\n}\n", "import React, { useState } from 'react';\nimport {\n View,\n Text,\n TouchableOpacity,\n StyleSheet,\n Platform,\n} from 'react-native';\nimport { useAiAnnotation } from '../../store';\nimport { Draggable } from './Draggable';\nimport { Highlighter } from './Highlighter';\nimport { AnnotationList } from './AnnotationList';\n\n// Dynamic clipboard import to handle different React Native versions\nconst copyToClipboard = async (text: string) => {\n try {\n // Try expo-clipboard first\n const ExpoClipboard = await import('expo-clipboard');\n await ExpoClipboard.setStringAsync(text);\n } catch {\n try {\n // Fallback to @react-native-clipboard/clipboard\n const RNClipboard = await import('@react-native-clipboard/clipboard');\n RNClipboard.default.setString(text);\n } catch {\n console.warn('No clipboard module available');\n }\n }\n};\n\nexport function Toolbar() {\n const { state, dispatch } = useAiAnnotation();\n const [showCopied, setShowCopied] = useState(false);\n\n const handleCopy = async () => {\n const data = state.annotations.map((a) => ({\n component: a.componentName,\n instruction: a.note,\n }));\n const text = JSON.stringify(data, null, 2);\n\n await copyToClipboard(text);\n\n setShowCopied(true);\n setTimeout(() => setShowCopied(false), 2000);\n };\n\n const toggleMode = () => {\n dispatch({\n type: 'SET_MODE',\n payload: state.mode === 'disabled' ? 'inspecting' : 'disabled',\n });\n };\n\n const handleToggleMinimized = () => {\n dispatch({ type: 'TOGGLE_MINIMIZED' });\n };\n\n return (\n <>\n <Highlighter />\n <AnnotationList />\n <Draggable>\n <View style={styles.toolbar}>\n {/* Drag Handle */}\n <View style={styles.dragHandle}>\n <Text style={styles.dragHandleText}>\u22EE\u22EE</Text>\n </View>\n\n {!state.isMinimized && (\n <>\n <View style={styles.separator} />\n\n {/* Toggle inspection mode */}\n <TouchableOpacity\n style={[\n styles.button,\n state.mode === 'inspecting' && styles.buttonActive,\n ]}\n onPress={toggleMode}\n >\n <Text style={styles.buttonText}>\n {state.mode === 'inspecting' ? '\uD83D\uDC46' : '\uD83D\uDEAB'}\n </Text>\n </TouchableOpacity>\n\n {/* List annotations */}\n <TouchableOpacity\n style={styles.button}\n onPress={() => dispatch({ type: 'TOGGLE_LIST' })}\n >\n <Text style={styles.buttonText}>\uD83D\uDCCB</Text>\n {state.annotations.length > 0 && (\n <View style={styles.badge}>\n <Text style={styles.badgeText}>{state.annotations.length}</Text>\n </View>\n )}\n </TouchableOpacity>\n\n {/* Copy annotations */}\n <TouchableOpacity\n style={[styles.button, showCopied && styles.buttonSuccess]}\n onPress={handleCopy}\n >\n <Text style={styles.buttonText}>{showCopied ? '\u2713' : '\uD83D\uDCCB'}</Text>\n {showCopied && <Text style={styles.copiedText}>Copied!</Text>}\n </TouchableOpacity>\n </>\n )}\n\n <View style={styles.separator} />\n\n {/* Minimize/Expand */}\n <TouchableOpacity style={styles.button} onPress={handleToggleMinimized}>\n <Text style={styles.buttonText}>{state.isMinimized ? '\u2B1C' : '\u2796'}</Text>\n </TouchableOpacity>\n </View>\n </Draggable>\n </>\n );\n}\n\nconst styles = StyleSheet.create({\n toolbar: {\n backgroundColor: '#1e1e1e',\n borderWidth: 1,\n borderColor: '#333',\n borderRadius: 8,\n padding: 8,\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n shadowColor: '#000',\n shadowOffset: { width: 0, height: 4 },\n shadowOpacity: 0.3,\n shadowRadius: 12,\n elevation: 8,\n },\n dragHandle: {\n paddingHorizontal: 4,\n },\n dragHandleText: {\n color: '#666',\n fontSize: 16,\n },\n separator: {\n width: 1,\n height: 24,\n backgroundColor: '#333',\n },\n button: {\n width: 32,\n height: 32,\n borderRadius: 4,\n justifyContent: 'center',\n alignItems: 'center',\n position: 'relative',\n },\n buttonActive: {\n backgroundColor: '#3b82f6',\n },\n buttonSuccess: {\n backgroundColor: '#22c55e',\n flexDirection: 'row',\n width: 'auto',\n paddingHorizontal: 8,\n gap: 4,\n },\n buttonText: {\n fontSize: 16,\n },\n copiedText: {\n color: 'white',\n fontSize: 12,\n },\n badge: {\n position: 'absolute',\n top: -4,\n right: -4,\n backgroundColor: '#ef4444',\n borderRadius: 7,\n width: 14,\n height: 14,\n justifyContent: 'center',\n alignItems: 'center',\n },\n badgeText: {\n color: 'white',\n fontSize: 9,\n fontWeight: 'bold',\n },\n});\n", "import React, { useRef, ReactNode } from 'react';\nimport {\n View,\n PanResponder,\n Animated,\n StyleSheet,\n ViewStyle,\n GestureResponderEvent,\n PanResponderGestureState,\n} from 'react-native';\n\ninterface DraggableProps {\n children: ReactNode;\n initialPos?: { x: number; y: number };\n style?: ViewStyle;\n}\n\nexport function Draggable({ children, initialPos = { x: 20, y: 20 }, style }: DraggableProps) {\n const pan = useRef(new Animated.ValueXY(initialPos)).current;\n const lastOffset = useRef(initialPos);\n\n const panResponder = useRef(\n PanResponder.create({\n onStartShouldSetPanResponder: () => true,\n onMoveShouldSetPanResponder: () => true,\n onPanResponderGrant: () => {\n pan.setOffset(lastOffset.current);\n pan.setValue({ x: 0, y: 0 });\n },\n onPanResponderMove: Animated.event(\n [null, { dx: pan.x, dy: pan.y }],\n { useNativeDriver: false }\n ),\n onPanResponderRelease: (_e: GestureResponderEvent, gestureState: PanResponderGestureState) => {\n lastOffset.current = {\n x: lastOffset.current.x + gestureState.dx,\n y: lastOffset.current.y + gestureState.dy,\n };\n pan.flattenOffset();\n },\n })\n ).current;\n\n return (\n <Animated.View\n {...panResponder.panHandlers}\n style={[\n styles.container,\n style,\n {\n transform: [{ translateX: pan.x }, { translateY: pan.y }],\n },\n ]}\n >\n {children}\n </Animated.View>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n position: 'absolute',\n zIndex: 9999,\n },\n});\n", "import React, { useState, useCallback, useRef } from 'react';\nimport {\n View,\n Text,\n TouchableOpacity,\n StyleSheet,\n Dimensions,\n GestureResponderEvent,\n} from 'react-native';\nimport { useAiAnnotation } from '../../store';\nimport { AnnotationInput } from './AnnotationInput';\n\ninterface HighlightRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\ninterface HighlighterProps {\n /**\n * Called when a touch occurs in inspection mode.\n * Return component info { name, rect } to highlight, or null to ignore.\n */\n onInspect?: (event: GestureResponderEvent) => {\n name: string;\n rect: HighlightRect;\n } | null;\n}\n\nexport function Highlighter({ onInspect }: HighlighterProps) {\n const { state, dispatch } = useAiAnnotation();\n const { mode } = state;\n\n const [highlightRect, setHighlightRect] = useState<HighlightRect | null>(null);\n const [componentName, setComponentName] = useState<string>('');\n const [showInput, setShowInput] = useState(false);\n const [showTooltip, setShowTooltip] = useState(false);\n const [tooltipPos, setTooltipPos] = useState({ x: 0, y: 0 });\n\n const screenDimensions = Dimensions.get('window');\n\n const handleTouch = useCallback(\n (event: GestureResponderEvent) => {\n if (mode !== 'inspecting') return;\n\n const { pageX, pageY } = event.nativeEvent;\n\n if (onInspect) {\n const result = onInspect(event);\n if (result) {\n setHighlightRect(result.rect);\n setComponentName(result.name);\n setTooltipPos({ x: pageX, y: pageY });\n setShowTooltip(true);\n return;\n }\n }\n\n // Default behavior: show tooltip at touch location\n setTooltipPos({ x: pageX, y: pageY });\n setShowTooltip(true);\n setComponentName('TouchedComponent');\n setHighlightRect({\n x: pageX - 50,\n y: pageY - 50,\n width: 100,\n height: 100,\n });\n },\n [mode, onInspect]\n );\n\n const handleAddAnnotation = () => {\n setShowInput(true);\n setShowTooltip(false);\n };\n\n const handleCloseInput = () => {\n setShowInput(false);\n setHighlightRect(null);\n setComponentName('');\n };\n\n const handleDismiss = () => {\n setShowTooltip(false);\n setHighlightRect(null);\n setComponentName('');\n };\n\n if (mode !== 'inspecting') return null;\n\n // Calculate tooltip position to keep it on screen\n const tooltipWidth = 120;\n const tooltipHeight = 50;\n let adjustedX = tooltipPos.x + 16;\n let adjustedY = tooltipPos.y + 16;\n\n if (adjustedX + tooltipWidth > screenDimensions.width) {\n adjustedX = tooltipPos.x - tooltipWidth - 16;\n }\n if (adjustedY + tooltipHeight > screenDimensions.height) {\n adjustedY = tooltipPos.y - tooltipHeight - 16;\n }\n\n return (\n <View style={StyleSheet.absoluteFill} pointerEvents=\"box-none\">\n {/* Touch capture overlay */}\n <TouchableOpacity\n style={styles.touchOverlay}\n activeOpacity={1}\n onPress={handleTouch}\n />\n\n {/* Highlight rectangle */}\n {highlightRect && (\n <>\n <View\n style={[\n styles.highlight,\n {\n left: highlightRect.x - 2,\n top: highlightRect.y - 2,\n width: highlightRect.width + 4,\n height: highlightRect.height + 4,\n },\n ]}\n pointerEvents=\"none\"\n />\n\n {/* Component name label */}\n {componentName && (\n <View\n style={[\n styles.nameLabel,\n {\n left: highlightRect.x,\n top: highlightRect.y - 24,\n },\n ]}\n pointerEvents=\"none\"\n >\n <Text style={styles.nameLabelText}>{componentName}</Text>\n </View>\n )}\n </>\n )}\n\n {/* Floating tooltip */}\n {showTooltip && (\n <View\n style={[\n styles.tooltip,\n {\n left: adjustedX,\n top: adjustedY,\n },\n ]}\n >\n <TouchableOpacity style={styles.tooltipButton} onPress={handleAddAnnotation}>\n <Text style={styles.tooltipButtonText}>+</Text>\n </TouchableOpacity>\n <TouchableOpacity style={styles.dismissButton} onPress={handleDismiss}>\n <Text style={styles.dismissButtonText}>\u2715</Text>\n </TouchableOpacity>\n </View>\n )}\n\n {/* Annotation input modal */}\n {showInput && (\n <AnnotationInput onClose={handleCloseInput} componentName={componentName || 'Unknown'} />\n )}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n touchOverlay: {\n ...StyleSheet.absoluteFillObject,\n backgroundColor: 'transparent',\n },\n highlight: {\n position: 'absolute',\n borderWidth: 2,\n borderColor: '#3b82f6',\n borderRadius: 4,\n backgroundColor: 'rgba(59, 130, 246, 0.1)',\n },\n nameLabel: {\n position: 'absolute',\n backgroundColor: '#3b82f6',\n paddingHorizontal: 8,\n paddingVertical: 2,\n borderRadius: 4,\n },\n nameLabelText: {\n color: 'white',\n fontSize: 12,\n fontFamily: 'monospace',\n },\n tooltip: {\n position: 'absolute',\n flexDirection: 'row',\n gap: 6,\n padding: 6,\n backgroundColor: 'rgba(0, 0, 0, 0.9)',\n borderRadius: 8,\n shadowColor: '#000',\n shadowOffset: { width: 0, height: 4 },\n shadowOpacity: 0.3,\n shadowRadius: 12,\n elevation: 8,\n },\n tooltipButton: {\n width: 32,\n height: 32,\n borderRadius: 6,\n backgroundColor: '#3b82f6',\n justifyContent: 'center',\n alignItems: 'center',\n },\n tooltipButtonText: {\n color: 'white',\n fontSize: 18,\n fontWeight: 'bold',\n },\n dismissButton: {\n width: 32,\n height: 32,\n borderRadius: 6,\n backgroundColor: '#6b7280',\n justifyContent: 'center',\n alignItems: 'center',\n },\n dismissButtonText: {\n color: 'white',\n fontSize: 14,\n },\n});\n", "import React, { useState, useEffect } from 'react';\nimport {\n View,\n Text,\n Modal,\n TextInput,\n TouchableOpacity,\n StyleSheet,\n Animated,\n KeyboardAvoidingView,\n Platform,\n} from 'react-native';\nimport { useAiAnnotation } from '../../store';\n\ninterface AnnotationInputProps {\n onClose: () => void;\n componentName: string;\n}\n\nexport function AnnotationInput({ onClose, componentName }: AnnotationInputProps) {\n const { dispatch } = useAiAnnotation();\n const [note, setNote] = useState('');\n const [fadeAnim] = useState(new Animated.Value(0));\n const [scaleAnim] = useState(new Animated.Value(0.95));\n\n useEffect(() => {\n Animated.parallel([\n Animated.timing(fadeAnim, {\n toValue: 1,\n duration: 200,\n useNativeDriver: true,\n }),\n Animated.spring(scaleAnim, {\n toValue: 1,\n friction: 8,\n useNativeDriver: true,\n }),\n ]).start();\n }, []);\n\n const handleClose = () => {\n Animated.parallel([\n Animated.timing(fadeAnim, {\n toValue: 0,\n duration: 150,\n useNativeDriver: true,\n }),\n Animated.timing(scaleAnim, {\n toValue: 0.95,\n duration: 150,\n useNativeDriver: true,\n }),\n ]).start(() => {\n onClose();\n });\n };\n\n const handleSubmit = () => {\n if (!note.trim()) return;\n\n dispatch({\n type: 'ADD_ANNOTATION',\n payload: {\n id: Date.now().toString(),\n componentName,\n note: note.trim(),\n timestamp: Date.now(),\n },\n });\n handleClose();\n };\n\n return (\n <Modal\n visible\n transparent\n animationType=\"none\"\n onRequestClose={handleClose}\n >\n <KeyboardAvoidingView\n behavior={Platform.OS === 'ios' ? 'padding' : 'height'}\n style={styles.keyboardView}\n >\n <Animated.View style={[styles.overlay, { opacity: fadeAnim }]}>\n <TouchableOpacity\n style={styles.backdropTouchable}\n activeOpacity={1}\n onPress={handleClose}\n >\n <Animated.View\n style={[\n styles.container,\n {\n opacity: fadeAnim,\n transform: [{ scale: scaleAnim }],\n },\n ]}\n >\n <TouchableOpacity activeOpacity={1}>\n <View style={styles.header}>\n <Text style={styles.title}>Add Annotation</Text>\n <TouchableOpacity onPress={handleClose} style={styles.closeButton}>\n <Text style={styles.closeButtonText}>\u2715</Text>\n </TouchableOpacity>\n </View>\n\n <Text style={styles.componentLabel}>\n Component: <Text style={styles.componentName}>{componentName}</Text>\n </Text>\n\n <TextInput\n style={styles.textInput}\n value={note}\n onChangeText={setNote}\n placeholder=\"Describe what this component does...\"\n placeholderTextColor=\"#6b7280\"\n multiline\n numberOfLines={4}\n textAlignVertical=\"top\"\n autoFocus\n />\n\n <View style={styles.buttonContainer}>\n <TouchableOpacity style={styles.cancelButton} onPress={handleClose}>\n <Text style={styles.cancelButtonText}>Cancel</Text>\n </TouchableOpacity>\n <TouchableOpacity style={styles.submitButton} onPress={handleSubmit}>\n <Text style={styles.submitButtonText}>Save Annotation</Text>\n </TouchableOpacity>\n </View>\n </TouchableOpacity>\n </Animated.View>\n </TouchableOpacity>\n </Animated.View>\n </KeyboardAvoidingView>\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n keyboardView: {\n flex: 1,\n },\n overlay: {\n flex: 1,\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n justifyContent: 'center',\n alignItems: 'center',\n },\n backdropTouchable: {\n flex: 1,\n width: '100%',\n justifyContent: 'center',\n alignItems: 'center',\n },\n container: {\n backgroundColor: '#1e1e1e',\n borderRadius: 8,\n padding: 20,\n width: '90%',\n maxWidth: 400,\n },\n header: {\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginBottom: 16,\n },\n title: {\n color: '#e5e7eb',\n fontSize: 18,\n fontWeight: 'bold',\n },\n closeButton: {\n padding: 4,\n },\n closeButtonText: {\n color: '#e5e7eb',\n fontSize: 20,\n },\n componentLabel: {\n color: '#9ca3af',\n fontSize: 14,\n marginBottom: 12,\n },\n componentName: {\n color: '#e5e7eb',\n fontWeight: 'bold',\n },\n textInput: {\n backgroundColor: '#2d2d2d',\n borderWidth: 1,\n borderColor: '#404040',\n borderRadius: 4,\n padding: 8,\n color: 'white',\n height: 100,\n marginBottom: 16,\n fontSize: 14,\n },\n buttonContainer: {\n flexDirection: 'row',\n justifyContent: 'flex-end',\n gap: 8,\n },\n cancelButton: {\n paddingHorizontal: 12,\n paddingVertical: 8,\n borderRadius: 4,\n borderWidth: 1,\n borderColor: '#404040',\n },\n cancelButtonText: {\n color: 'white',\n fontSize: 14,\n },\n submitButton: {\n backgroundColor: '#3b82f6',\n paddingHorizontal: 12,\n paddingVertical: 8,\n borderRadius: 4,\n },\n submitButtonText: {\n color: 'white',\n fontSize: 14,\n },\n});\n", "import React from 'react';\nimport {\n View,\n Text,\n Modal,\n TouchableOpacity,\n ScrollView,\n StyleSheet,\n} from 'react-native';\nimport { useAiAnnotation } from '../../store';\n\nexport function AnnotationList() {\n const { state, dispatch } = useAiAnnotation();\n\n if (!state.showList) return null;\n\n return (\n <Modal\n visible={state.showList}\n transparent\n animationType=\"fade\"\n onRequestClose={() => dispatch({ type: 'TOGGLE_LIST' })}\n >\n <View style={styles.overlay}>\n <View style={styles.container}>\n <View style={styles.header}>\n <Text style={styles.title}>Annotations ({state.annotations.length})</Text>\n <View style={styles.headerActions}>\n {state.annotations.length > 0 && (\n <TouchableOpacity\n style={styles.clearButton}\n onPress={() => dispatch({ type: 'CLEAR_ALL_ANNOTATIONS' })}\n >\n <Text style={styles.clearButtonText}>Clear All</Text>\n </TouchableOpacity>\n )}\n <TouchableOpacity\n style={styles.closeButton}\n onPress={() => dispatch({ type: 'TOGGLE_LIST' })}\n >\n <Text style={styles.closeButtonText}>\u2715</Text>\n </TouchableOpacity>\n </View>\n </View>\n\n <ScrollView style={styles.listContainer}>\n {state.annotations.length === 0 ? (\n <Text style={styles.emptyText}>No annotations yet.</Text>\n ) : (\n state.annotations.map((ann) => (\n <View key={ann.id} style={styles.annotationItem}>\n <View style={styles.annotationContent}>\n <Text style={styles.componentName}>{ann.componentName}</Text>\n <Text style={styles.annotationNote}>{ann.note}</Text>\n </View>\n <TouchableOpacity\n style={styles.deleteButton}\n onPress={() => dispatch({ type: 'REMOVE_ANNOTATION', payload: ann.id })}\n >\n <Text style={styles.deleteButtonText}>\uD83D\uDDD1</Text>\n </TouchableOpacity>\n </View>\n ))\n )}\n </ScrollView>\n </View>\n </View>\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n overlay: {\n flex: 1,\n backgroundColor: 'rgba(0, 0, 0, 0.5)',\n justifyContent: 'center',\n alignItems: 'center',\n },\n container: {\n backgroundColor: '#1e1e1e',\n borderRadius: 8,\n width: '90%',\n maxWidth: 500,\n maxHeight: '80%',\n padding: 20,\n },\n header: {\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginBottom: 16,\n },\n title: {\n color: '#e5e7eb',\n fontSize: 18,\n fontWeight: 'bold',\n },\n headerActions: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n },\n clearButton: {\n backgroundColor: '#ef4444',\n paddingHorizontal: 12,\n paddingVertical: 6,\n borderRadius: 4,\n },\n clearButtonText: {\n color: 'white',\n fontSize: 12,\n },\n closeButton: {\n padding: 4,\n },\n closeButtonText: {\n color: '#e5e7eb',\n fontSize: 20,\n },\n listContainer: {\n flex: 1,\n },\n emptyText: {\n color: '#9ca3af',\n textAlign: 'center',\n padding: 20,\n },\n annotationItem: {\n backgroundColor: '#2d2d2d',\n padding: 12,\n borderRadius: 4,\n marginBottom: 8,\n flexDirection: 'row',\n justifyContent: 'space-between',\n alignItems: 'flex-start',\n },\n annotationContent: {\n flex: 1,\n marginRight: 12,\n },\n componentName: {\n color: '#60a5fa',\n fontWeight: 'bold',\n fontSize: 14,\n marginBottom: 4,\n },\n annotationNote: {\n color: '#e5e7eb',\n fontSize: 14,\n },\n deleteButton: {\n padding: 4,\n },\n deleteButtonText: {\n fontSize: 16,\n },\n});\n", "import { RefObject } from 'react';\nimport { View, Platform } from 'react-native';\n\nexport interface ScreenshotOptions {\n /** Scale factor for higher resolution (default: 2) */\n scale?: number;\n /** Image format (default: 'png') */\n format?: 'png' | 'jpg';\n /** Quality for jpg format (0-1, default: 0.9) */\n quality?: number;\n /** Whether to copy to clipboard (default: true, requires expo-clipboard) */\n copyToClipboard?: boolean;\n /** Whether to save to camera roll (default: false, requires expo-media-library) */\n saveToCameraRoll?: boolean;\n}\n\nexport interface ScreenshotResult {\n success: boolean;\n uri?: string;\n base64?: string;\n error?: string;\n}\n\n/**\n * Captures a screenshot of a React Native View using react-native-view-shot\n * \n * Requirements:\n * - react-native-view-shot must be installed\n * - Optionally: expo-clipboard for clipboard support\n * - Optionally: expo-media-library for camera roll support\n * \n * @param viewRef - Reference to the View to capture\n * @param options - Screenshot options\n */\nexport async function captureScreenshot(\n viewRef: RefObject<View>,\n options: ScreenshotOptions = {}\n): Promise<ScreenshotResult> {\n const {\n scale = 2,\n format = 'png',\n quality = 0.9,\n copyToClipboard = false,\n saveToCameraRoll = false,\n } = options;\n\n try {\n // Dynamic import to avoid issues if not installed\n let captureRef: any;\n try {\n const viewShot = await import('react-native-view-shot');\n captureRef = viewShot.captureRef;\n } catch {\n return {\n success: false,\n error: 'react-native-view-shot is not installed. Run: npm install react-native-view-shot',\n };\n }\n\n if (!viewRef.current) {\n return {\n success: false,\n error: 'View reference is null',\n };\n }\n\n // Capture the view\n const uri = await captureRef(viewRef, {\n format,\n quality,\n result: 'tmpfile',\n snapshotContentContainer: false,\n });\n\n // Get base64 if needed\n let base64: string | undefined;\n if (copyToClipboard) {\n const base64Result = await captureRef(viewRef, {\n format,\n quality,\n result: 'base64',\n snapshotContentContainer: false,\n });\n base64 = base64Result;\n }\n\n // Copy to clipboard if requested\n if (copyToClipboard && base64) {\n try {\n const Clipboard = await import('expo-clipboard');\n // expo-clipboard doesn't support image directly, \n // we'll copy the base64 string\n await Clipboard.setStringAsync(base64);\n } catch {\n console.warn('expo-clipboard not available for clipboard support');\n }\n }\n\n // Save to camera roll if requested\n if (saveToCameraRoll) {\n try {\n const MediaLibrary = await import('expo-media-library');\n const { status } = await MediaLibrary.requestPermissionsAsync();\n if (status === 'granted') {\n await MediaLibrary.saveToLibraryAsync(uri);\n }\n } catch {\n console.warn('expo-media-library not available for saving to camera roll');\n }\n }\n\n return {\n success: true,\n uri,\n base64,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n console.error('Screenshot capture failed:', message);\n return {\n success: false,\n error: message,\n };\n }\n}\n\n/**\n * Placeholder for web compatibility\n * The actual web implementation is in screenshot.ts\n */\nexport function captureScreenshotWeb(\n _element: any,\n _options: any\n): Promise<ScreenshotResult> {\n return Promise.resolve({\n success: false,\n error: 'Use the web-specific captureScreenshot function',\n });\n}\n", "/**\n * React Fiber utilities for React Native\n * \n * Note: React Native has different fiber access compared to web.\n * These utilities provide a similar interface but with native-specific logic.\n */\n\n/**\n * Attempts to get the React Fiber from a native view instance\n * This is less reliable in React Native than on web\n */\nexport function getReactFiber(instance: any): any {\n if (!instance) return null;\n \n // React Native stores fiber differently\n // Try to find the fiber via internal props\n const key = Object.keys(instance).find((k) =>\n k.startsWith('__reactFiber$') || \n k.startsWith('__reactInternalInstance$') ||\n k.startsWith('_reactInternals')\n );\n \n return key ? instance[key] : null;\n}\n\n/**\n * Gets the display name of a React component from its fiber\n */\nexport function getComponentDisplayName(fiber: any): string {\n if (!fiber) return 'Unknown';\n \n let curr = fiber;\n while (curr) {\n const type = curr.type;\n if (type) {\n // Check for displayName or name\n const name = type.displayName || type.name;\n if (name && typeof name === 'string') {\n // Skip internal React Native components\n if (!name.startsWith('RCT') && !name.startsWith('_')) {\n return name;\n }\n }\n }\n curr = curr.return;\n }\n return 'Unknown';\n}\n\n/**\n * For React Native, we can't easily get DOM elements from fibers\n * This is a no-op that returns null\n */\nexport function getElementFromFiber(_fiber: any): null {\n return null;\n}\n\n/**\n * Interface for component inspection result\n */\nexport interface ComponentInfo {\n name: string;\n props?: Record<string, any>;\n}\n\n/**\n * Inspects a React Native component instance to get info\n * This works with refs passed to components\n */\nexport function inspectComponent(ref: any): ComponentInfo | null {\n if (!ref) return null;\n \n // Try to get fiber from the ref\n const fiber = getReactFiber(ref);\n if (fiber) {\n return {\n name: getComponentDisplayName(fiber),\n props: fiber.memoizedProps,\n };\n }\n \n // Fallback: try to infer from the ref itself\n if (ref.constructor && ref.constructor.name) {\n return {\n name: ref.constructor.name,\n };\n }\n \n return null;\n}\n", "/**\n * Platform detection utilities for cross-platform support\n */\n\n// Check if we're running in a web environment\nexport const isWeb = typeof document !== 'undefined' && typeof window !== 'undefined';\n\n// Check if we're running in React Native\n// We check for the absence of DOM and presence of native-specific globals\nexport const isNative = !isWeb && typeof global !== 'undefined';\n\n// Get the current platform\nexport type PlatformType = 'web' | 'ios' | 'android' | 'native';\n\nexport function getPlatform(): PlatformType {\n if (isWeb) return 'web';\n \n // In React Native, we need to dynamically check Platform\n try {\n // This will only work in React Native environment\n const { Platform } = require('react-native');\n if (Platform.OS === 'ios') return 'ios';\n if (Platform.OS === 'android') return 'android';\n return 'native';\n } catch {\n return 'native';\n }\n}\n\n// Check if running in Tauri environment (web only)\nexport function isTauriEnv(): boolean {\n return isWeb && typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["View", "useState", "View", "Text", "TouchableOpacity", "StyleSheet", "jsx", "useState", "View", "Text", "TouchableOpacity", "StyleSheet", "View", "StyleSheet", "Animated", "jsx", "Animated", "styles", "View", "StyleSheet", "jsx", "jsxs", "useState", "View", "StyleSheet", "TouchableOpacity", "styles", "Text", "View", "Text", "Modal", "TouchableOpacity", "StyleSheet", "jsx", "jsxs", "Modal", "View", "styles", "Text", "TouchableOpacity", "StyleSheet", "Fragment", "jsx", "jsxs", "useState", "View", "styles", "Text", "TouchableOpacity", "StyleSheet", "copyToClipboard", "Platform", "jsx", "jsxs", "AiAnnotationProvider", "View"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// src/index.web.tsx
|
|
2
|
+
import { createContext, useContext, useReducer } from "react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
var initialState = {
|
|
5
|
+
mode: "inspecting",
|
|
6
|
+
// Start enabled for extension
|
|
7
|
+
annotations: [],
|
|
8
|
+
hoveredElement: null,
|
|
9
|
+
hoveredComponentInfo: null,
|
|
10
|
+
isMinimized: false,
|
|
11
|
+
showList: false
|
|
12
|
+
};
|
|
13
|
+
var AnnotationContext = createContext(void 0);
|
|
14
|
+
function reducer(state, action) {
|
|
15
|
+
switch (action.type) {
|
|
16
|
+
case "SET_MODE":
|
|
17
|
+
return { ...state, mode: action.payload };
|
|
18
|
+
case "ADD_ANNOTATION":
|
|
19
|
+
return { ...state, annotations: [...state.annotations, action.payload] };
|
|
20
|
+
case "REMOVE_ANNOTATION":
|
|
21
|
+
return {
|
|
22
|
+
...state,
|
|
23
|
+
annotations: state.annotations.filter((a) => a.id !== action.payload)
|
|
24
|
+
};
|
|
25
|
+
case "CLEAR_ALL_ANNOTATIONS":
|
|
26
|
+
return {
|
|
27
|
+
...state,
|
|
28
|
+
annotations: []
|
|
29
|
+
};
|
|
30
|
+
case "SET_HOVERED":
|
|
31
|
+
if (state.hoveredElement === action.payload.element) return state;
|
|
32
|
+
return {
|
|
33
|
+
...state,
|
|
34
|
+
hoveredElement: action.payload.element,
|
|
35
|
+
hoveredComponentInfo: action.payload.name ? { name: action.payload.name, details: action.payload.details } : null
|
|
36
|
+
};
|
|
37
|
+
case "RESET_HOVER":
|
|
38
|
+
return { ...state, hoveredElement: null, hoveredComponentInfo: null };
|
|
39
|
+
case "TOGGLE_MINIMIZED":
|
|
40
|
+
return { ...state, isMinimized: !state.isMinimized };
|
|
41
|
+
case "TOGGLE_LIST":
|
|
42
|
+
return { ...state, showList: !state.showList };
|
|
43
|
+
default:
|
|
44
|
+
return state;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function AiAnnotationProvider({ children }) {
|
|
48
|
+
const [state, dispatch] = useReducer(reducer, initialState);
|
|
49
|
+
return /* @__PURE__ */ jsx(AnnotationContext.Provider, { value: { state, dispatch }, children });
|
|
50
|
+
}
|
|
51
|
+
function useAiAnnotation() {
|
|
52
|
+
const context = useContext(AnnotationContext);
|
|
53
|
+
if (!context) {
|
|
54
|
+
throw new Error("useAiAnnotation must be used within an AiAnnotationProvider");
|
|
55
|
+
}
|
|
56
|
+
return context;
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
AiAnnotationProvider,
|
|
60
|
+
useAiAnnotation
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=index.web.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/index.web.tsx"],
|
|
4
|
+
"sourcesContent": ["/**\n * Web-only entry point for Chrome Extension\n * This avoids any React Native imports\n */\n\nimport React, { createContext, useContext, useReducer, ReactNode } from 'react';\nimport type { ComponentDetails, ChildComponentInfo, ElementInfo } from './utils/fiber';\n\n// Re-export types for external use\nexport type { ComponentDetails, ChildComponentInfo, ElementInfo };\n\nexport type Annotation = {\n id: string;\n componentName: string;\n note: string;\n timestamp: number;\n /** Enhanced component details (optional for backward compatibility) */\n details?: ComponentDetails;\n};\n\nexport type Mode = 'disabled' | 'inspecting';\n\n/**\n * Platform-agnostic element type\n * - On web: HTMLElement\n */\nexport type HoveredElement = HTMLElement | null;\n\n/**\n * Enhanced component info with full details\n */\nexport interface HoveredComponentInfo {\n name: string;\n /** Full component details including hierarchy, children, and element info */\n details?: ComponentDetails;\n}\n\ninterface State {\n mode: Mode;\n annotations: Annotation[];\n hoveredElement: HoveredElement;\n hoveredComponentInfo: HoveredComponentInfo | null;\n isMinimized: boolean;\n showList: boolean;\n}\n\ntype Action =\n | { type: 'SET_MODE'; payload: Mode }\n | { type: 'ADD_ANNOTATION'; payload: Annotation }\n | { type: 'REMOVE_ANNOTATION'; payload: string }\n | { type: 'CLEAR_ALL_ANNOTATIONS' }\n | { type: 'SET_HOVERED'; payload: { element: HoveredElement; name: string | null; details?: ComponentDetails } }\n | { type: 'TOGGLE_MINIMIZED' }\n | { type: 'TOGGLE_LIST' }\n | { type: 'RESET_HOVER' };\n\nconst initialState: State = {\n mode: 'inspecting', // Start enabled for extension\n annotations: [],\n hoveredElement: null,\n hoveredComponentInfo: null,\n isMinimized: false,\n showList: false,\n};\n\nconst AnnotationContext = createContext<{\n state: State;\n dispatch: React.Dispatch<Action>;\n} | undefined>(undefined);\n\nfunction reducer(state: State, action: Action): State {\n switch (action.type) {\n case 'SET_MODE':\n return { ...state, mode: action.payload };\n case 'ADD_ANNOTATION':\n return { ...state, annotations: [...state.annotations, action.payload] };\n case 'REMOVE_ANNOTATION':\n return {\n ...state,\n annotations: state.annotations.filter((a) => a.id !== action.payload),\n };\n case 'CLEAR_ALL_ANNOTATIONS':\n return {\n ...state,\n annotations: [],\n };\n case 'SET_HOVERED':\n // Avoid updates if same\n if (state.hoveredElement === action.payload.element) return state;\n return {\n ...state,\n hoveredElement: action.payload.element,\n hoveredComponentInfo: action.payload.name\n ? { name: action.payload.name, details: action.payload.details }\n : null\n };\n case 'RESET_HOVER':\n return { ...state, hoveredElement: null, hoveredComponentInfo: null };\n case 'TOGGLE_MINIMIZED':\n return { ...state, isMinimized: !state.isMinimized };\n case 'TOGGLE_LIST':\n return { ...state, showList: !state.showList };\n default:\n return state;\n }\n}\n\nexport function AiAnnotationProvider({ children }: { children: ReactNode }) {\n const [state, dispatch] = useReducer(reducer, initialState);\n\n return (\n <AnnotationContext.Provider value={{ state, dispatch }}>\n {children}\n </AnnotationContext.Provider>\n );\n}\n\nexport function useAiAnnotation() {\n const context = useContext(AnnotationContext);\n if (!context) {\n throw new Error('useAiAnnotation must be used within an AiAnnotationProvider');\n }\n return context;\n}\n"],
|
|
5
|
+
"mappings": ";AAKA,SAAgB,eAAe,YAAY,kBAA6B;AA0GpE;AAvDJ,IAAM,eAAsB;AAAA,EAC1B,MAAM;AAAA;AAAA,EACN,aAAa,CAAC;AAAA,EACd,gBAAgB;AAAA,EAChB,sBAAsB;AAAA,EACtB,aAAa;AAAA,EACb,UAAU;AACZ;AAEA,IAAM,oBAAoB,cAGX,MAAS;AAExB,SAAS,QAAQ,OAAc,QAAuB;AACpD,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,MAAM,OAAO,QAAQ;AAAA,IAC1C,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,aAAa,CAAC,GAAG,MAAM,aAAa,OAAO,OAAO,EAAE;AAAA,IACzE,KAAK;AACH,aAAO;AAAA,QACL,GAAG;AAAA,QACH,aAAa,MAAM,YAAY,OAAO,CAAC,MAAM,EAAE,OAAO,OAAO,OAAO;AAAA,MACtE;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,GAAG;AAAA,QACH,aAAa,CAAC;AAAA,MAChB;AAAA,IACF,KAAK;AAED,UAAI,MAAM,mBAAmB,OAAO,QAAQ,QAAS,QAAO;AAC5D,aAAO;AAAA,QACH,GAAG;AAAA,QACH,gBAAgB,OAAO,QAAQ;AAAA,QAC/B,sBAAsB,OAAO,QAAQ,OACjC,EAAE,MAAM,OAAO,QAAQ,MAAM,SAAS,OAAO,QAAQ,QAAQ,IAC7D;AAAA,MACR;AAAA,IACJ,KAAK;AACD,aAAO,EAAE,GAAG,OAAO,gBAAgB,MAAM,sBAAsB,KAAK;AAAA,IACxE,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,aAAa,CAAC,MAAM,YAAY;AAAA,IACrD,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,UAAU,CAAC,MAAM,SAAS;AAAA,IAC/C;AACE,aAAO;AAAA,EACX;AACF;AAEO,SAAS,qBAAqB,EAAE,SAAS,GAA4B;AAC1E,QAAM,CAAC,OAAO,QAAQ,IAAI,WAAW,SAAS,YAAY;AAE1D,SACE,oBAAC,kBAAkB,UAAlB,EAA2B,OAAO,EAAE,OAAO,SAAS,GAClD,UACH;AAEJ;AAEO,SAAS,kBAAkB;AAChC,QAAM,UAAU,WAAW,iBAAiB;AAC5C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,6DAA6D;AAAA,EAC/E;AACA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ComponentDetails } from '../store';
|
|
2
|
+
interface AnnotationInputProps {
|
|
3
|
+
onClose: () => void;
|
|
4
|
+
componentName: string;
|
|
5
|
+
componentDetails?: ComponentDetails;
|
|
6
|
+
}
|
|
7
|
+
export declare function AnnotationInput({ onClose, componentName, componentDetails }: AnnotationInputProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function AnnotationList(): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface DraggableProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
initialPos?: {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export declare function Draggable({ children, initialPos }: DraggableProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function Highlighter(): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function Toolbar(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface AiAnnotationProviderProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Web AI Annotation Provider
|
|
7
|
+
* Wraps your app to provide annotation functionality
|
|
8
|
+
*/
|
|
9
|
+
export declare function AiAnnotationProvider({ children }: AiAnnotationProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export * from './store';
|
|
11
|
+
export { Toolbar } from './components/Toolbar';
|
|
12
|
+
export { Highlighter } from './components/Highlighter';
|
|
13
|
+
export { AnnotationInput } from './components/AnnotationInput';
|
|
14
|
+
export { AnnotationList } from './components/AnnotationList';
|
|
15
|
+
export { Draggable } from './components/Draggable';
|
|
16
|
+
export { captureScreenshot } from './utils/screenshot';
|
|
17
|
+
export type { ScreenshotOptions, ScreenshotResult } from './utils/screenshot';
|
|
18
|
+
export { getReactFiber, getComponentDisplayName, getElementFromFiber } from './utils/fiber';
|
|
19
|
+
export { isWeb, isNative, getPlatform, isTauriEnv } from './utils/platform';
|
|
20
|
+
export type { PlatformType } from './utils/platform';
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web-only entry point for Chrome Extension
|
|
3
|
+
* This avoids any React Native imports
|
|
4
|
+
*/
|
|
5
|
+
import React, { ReactNode } from 'react';
|
|
6
|
+
import type { ComponentDetails, ChildComponentInfo, ElementInfo } from './utils/fiber';
|
|
7
|
+
export type { ComponentDetails, ChildComponentInfo, ElementInfo };
|
|
8
|
+
export type Annotation = {
|
|
9
|
+
id: string;
|
|
10
|
+
componentName: string;
|
|
11
|
+
note: string;
|
|
12
|
+
timestamp: number;
|
|
13
|
+
/** Enhanced component details (optional for backward compatibility) */
|
|
14
|
+
details?: ComponentDetails;
|
|
15
|
+
};
|
|
16
|
+
export type Mode = 'disabled' | 'inspecting';
|
|
17
|
+
/**
|
|
18
|
+
* Platform-agnostic element type
|
|
19
|
+
* - On web: HTMLElement
|
|
20
|
+
*/
|
|
21
|
+
export type HoveredElement = HTMLElement | null;
|
|
22
|
+
/**
|
|
23
|
+
* Enhanced component info with full details
|
|
24
|
+
*/
|
|
25
|
+
export interface HoveredComponentInfo {
|
|
26
|
+
name: string;
|
|
27
|
+
/** Full component details including hierarchy, children, and element info */
|
|
28
|
+
details?: ComponentDetails;
|
|
29
|
+
}
|
|
30
|
+
interface State {
|
|
31
|
+
mode: Mode;
|
|
32
|
+
annotations: Annotation[];
|
|
33
|
+
hoveredElement: HoveredElement;
|
|
34
|
+
hoveredComponentInfo: HoveredComponentInfo | null;
|
|
35
|
+
isMinimized: boolean;
|
|
36
|
+
showList: boolean;
|
|
37
|
+
}
|
|
38
|
+
type Action = {
|
|
39
|
+
type: 'SET_MODE';
|
|
40
|
+
payload: Mode;
|
|
41
|
+
} | {
|
|
42
|
+
type: 'ADD_ANNOTATION';
|
|
43
|
+
payload: Annotation;
|
|
44
|
+
} | {
|
|
45
|
+
type: 'REMOVE_ANNOTATION';
|
|
46
|
+
payload: string;
|
|
47
|
+
} | {
|
|
48
|
+
type: 'CLEAR_ALL_ANNOTATIONS';
|
|
49
|
+
} | {
|
|
50
|
+
type: 'SET_HOVERED';
|
|
51
|
+
payload: {
|
|
52
|
+
element: HoveredElement;
|
|
53
|
+
name: string | null;
|
|
54
|
+
details?: ComponentDetails;
|
|
55
|
+
};
|
|
56
|
+
} | {
|
|
57
|
+
type: 'TOGGLE_MINIMIZED';
|
|
58
|
+
} | {
|
|
59
|
+
type: 'TOGGLE_LIST';
|
|
60
|
+
} | {
|
|
61
|
+
type: 'RESET_HOVER';
|
|
62
|
+
};
|
|
63
|
+
export declare function AiAnnotationProvider({ children }: {
|
|
64
|
+
children: ReactNode;
|
|
65
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
66
|
+
export declare function useAiAnnotation(): {
|
|
67
|
+
state: State;
|
|
68
|
+
dispatch: React.Dispatch<Action>;
|
|
69
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import type { ComponentDetails, ChildComponentInfo, ElementInfo } from './utils/fiber';
|
|
3
|
+
export type { ComponentDetails, ChildComponentInfo, ElementInfo };
|
|
4
|
+
export type Annotation = {
|
|
5
|
+
id: string;
|
|
6
|
+
componentName: string;
|
|
7
|
+
note: string;
|
|
8
|
+
timestamp: number;
|
|
9
|
+
/** Enhanced component details (optional for backward compatibility) */
|
|
10
|
+
details?: ComponentDetails;
|
|
11
|
+
};
|
|
12
|
+
export type Mode = 'disabled' | 'inspecting';
|
|
13
|
+
/**
|
|
14
|
+
* Platform-agnostic element type
|
|
15
|
+
* - On web: HTMLElement
|
|
16
|
+
* - On native: View ref or null
|
|
17
|
+
*/
|
|
18
|
+
export type HoveredElement = any;
|
|
19
|
+
/**
|
|
20
|
+
* Enhanced component info with full details
|
|
21
|
+
*/
|
|
22
|
+
export interface HoveredComponentInfo {
|
|
23
|
+
name: string;
|
|
24
|
+
/** Full component details including hierarchy, children, and element info */
|
|
25
|
+
details?: ComponentDetails;
|
|
26
|
+
}
|
|
27
|
+
interface State {
|
|
28
|
+
mode: Mode;
|
|
29
|
+
annotations: Annotation[];
|
|
30
|
+
hoveredElement: HoveredElement;
|
|
31
|
+
hoveredComponentInfo: HoveredComponentInfo | null;
|
|
32
|
+
isMinimized: boolean;
|
|
33
|
+
showList: boolean;
|
|
34
|
+
}
|
|
35
|
+
type Action = {
|
|
36
|
+
type: 'SET_MODE';
|
|
37
|
+
payload: Mode;
|
|
38
|
+
} | {
|
|
39
|
+
type: 'ADD_ANNOTATION';
|
|
40
|
+
payload: Annotation;
|
|
41
|
+
} | {
|
|
42
|
+
type: 'REMOVE_ANNOTATION';
|
|
43
|
+
payload: string;
|
|
44
|
+
} | {
|
|
45
|
+
type: 'CLEAR_ALL_ANNOTATIONS';
|
|
46
|
+
} | {
|
|
47
|
+
type: 'SET_HOVERED';
|
|
48
|
+
payload: {
|
|
49
|
+
element: HoveredElement;
|
|
50
|
+
name: string | null;
|
|
51
|
+
details?: ComponentDetails;
|
|
52
|
+
};
|
|
53
|
+
} | {
|
|
54
|
+
type: 'TOGGLE_MINIMIZED';
|
|
55
|
+
} | {
|
|
56
|
+
type: 'TOGGLE_LIST';
|
|
57
|
+
} | {
|
|
58
|
+
type: 'RESET_HOVER';
|
|
59
|
+
};
|
|
60
|
+
export declare function AiAnnotationProvider({ children }: {
|
|
61
|
+
children: ReactNode;
|
|
62
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
63
|
+
export declare function useAiAnnotation(): {
|
|
64
|
+
state: State;
|
|
65
|
+
dispatch: React.Dispatch<Action>;
|
|
66
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export declare function getReactFiber(dom: HTMLElement): any;
|
|
2
|
+
export declare function getComponentDisplayName(fiber: any): string;
|
|
3
|
+
export declare function getElementFromFiber(fiber: any): HTMLElement | null;
|
|
4
|
+
/**
|
|
5
|
+
* Component info with hierarchy details
|
|
6
|
+
*/
|
|
7
|
+
export interface ComponentDetails {
|
|
8
|
+
name: string;
|
|
9
|
+
parentHierarchy: string[];
|
|
10
|
+
childComponents: ChildComponentInfo[];
|
|
11
|
+
elementInfo: ElementInfo;
|
|
12
|
+
props?: Record<string, any>;
|
|
13
|
+
}
|
|
14
|
+
export interface ChildComponentInfo {
|
|
15
|
+
name: string;
|
|
16
|
+
depth: number;
|
|
17
|
+
count: number;
|
|
18
|
+
hasChildren: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface ElementInfo {
|
|
21
|
+
tagName: string;
|
|
22
|
+
id?: string;
|
|
23
|
+
className?: string;
|
|
24
|
+
attributes: Record<string, string>;
|
|
25
|
+
childElementCount: number;
|
|
26
|
+
textContent?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get parent component hierarchy (from current component up to root)
|
|
30
|
+
*/
|
|
31
|
+
export declare function getParentHierarchy(fiber: any, maxDepth?: number): string[];
|
|
32
|
+
/**
|
|
33
|
+
* Get child components from a fiber node
|
|
34
|
+
*/
|
|
35
|
+
export declare function getChildComponents(fiber: any, maxDepth?: number): ChildComponentInfo[];
|
|
36
|
+
/**
|
|
37
|
+
* Get DOM element information
|
|
38
|
+
*/
|
|
39
|
+
export declare function getElementInfo(element: HTMLElement): ElementInfo;
|
|
40
|
+
/**
|
|
41
|
+
* Get component props (filtered for safety - removes functions and large objects)
|
|
42
|
+
*/
|
|
43
|
+
export declare function getComponentProps(fiber: any, maxProps?: number): Record<string, any> | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Get comprehensive component details for the selected element
|
|
46
|
+
*/
|
|
47
|
+
export declare function getComponentDetails(element: HTMLElement, options?: {
|
|
48
|
+
includeProps?: boolean;
|
|
49
|
+
maxParentDepth?: number;
|
|
50
|
+
maxChildDepth?: number;
|
|
51
|
+
}): ComponentDetails;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform detection utilities for cross-platform support
|
|
3
|
+
*/
|
|
4
|
+
export declare const isWeb: boolean;
|
|
5
|
+
export declare const isNative: boolean;
|
|
6
|
+
export type PlatformType = 'web' | 'ios' | 'android' | 'native';
|
|
7
|
+
export declare function getPlatform(): PlatformType;
|
|
8
|
+
export declare function isTauriEnv(): boolean;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface ScreenshotOptions {
|
|
2
|
+
/** Scale factor for higher resolution (default: 2) */
|
|
3
|
+
scale?: number;
|
|
4
|
+
/** Background color (default: transparent) */
|
|
5
|
+
backgroundColor?: string | null;
|
|
6
|
+
/** Whether to copy to clipboard (default: true) */
|
|
7
|
+
copyToClipboard?: boolean;
|
|
8
|
+
/** Whether to download as file (default: false) */
|
|
9
|
+
download?: boolean;
|
|
10
|
+
/** Filename when downloading (default: 'screenshot.png') */
|
|
11
|
+
filename?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ScreenshotResult {
|
|
14
|
+
success: boolean;
|
|
15
|
+
dataUrl?: string;
|
|
16
|
+
blob?: Blob;
|
|
17
|
+
error?: string;
|
|
18
|
+
}
|
|
19
|
+
declare global {
|
|
20
|
+
interface Window {
|
|
21
|
+
__TAURI_INTERNALS__?: unknown;
|
|
22
|
+
__TAURI_CLIPBOARD_WRITE_IMAGE__?: (bytes: Uint8Array) => Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Captures a screenshot of the given HTML element
|
|
27
|
+
*/
|
|
28
|
+
export declare function captureScreenshot(element: HTMLElement, options?: ScreenshotOptions): Promise<ScreenshotResult>;
|
package/package.json
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@np-dev/ui-ai-anotation",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "AI-powered annotation toolkit for UI inspection and annotation",
|
|
5
|
+
"main": "dist/cjs/index.cjs",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
7
|
+
"react-native": "dist/esm/index.native.js",
|
|
8
|
+
"types": "dist/types/index.d.ts",
|
|
9
|
+
"sideEffects": false,
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"react-native": {
|
|
13
|
+
"types": "./dist/types/index.native.d.ts",
|
|
14
|
+
"import": "./dist/esm/index.native.js",
|
|
15
|
+
"require": "./dist/cjs/index.native.cjs"
|
|
16
|
+
},
|
|
17
|
+
"types": "./dist/types/index.d.ts",
|
|
18
|
+
"import": "./dist/esm/index.js",
|
|
19
|
+
"require": "./dist/cjs/index.cjs"
|
|
20
|
+
},
|
|
21
|
+
"./native": {
|
|
22
|
+
"types": "./dist/types/index.native.d.ts",
|
|
23
|
+
"import": "./dist/esm/index.native.js",
|
|
24
|
+
"require": "./dist/cjs/index.native.cjs"
|
|
25
|
+
},
|
|
26
|
+
"./web": {
|
|
27
|
+
"types": "./dist/types/index.web.d.ts",
|
|
28
|
+
"import": "./dist/esm/index.web.js",
|
|
29
|
+
"require": "./dist/cjs/index.web.cjs"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"src",
|
|
34
|
+
"dist"
|
|
35
|
+
],
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "bun run scripts/publish.ts --dry-run",
|
|
38
|
+
"build:extension": "bun run scripts/build-extension.ts",
|
|
39
|
+
"dev:extension": "bun --watch scripts/build-extension.ts",
|
|
40
|
+
"typecheck": "tsc --noEmit",
|
|
41
|
+
"typecheck:extension": "tsc --noEmit --project tsconfig.extension.json",
|
|
42
|
+
"publish:patch": "bun run scripts/publish.ts patch",
|
|
43
|
+
"publish:minor": "bun run scripts/publish.ts minor",
|
|
44
|
+
"publish:major": "bun run scripts/publish.ts major",
|
|
45
|
+
"publish:dry": "bun run scripts/publish.ts --dry-run",
|
|
46
|
+
"release": "bun run scripts/publish.ts"
|
|
47
|
+
},
|
|
48
|
+
"keywords": [
|
|
49
|
+
"react",
|
|
50
|
+
"react-native",
|
|
51
|
+
"annotation",
|
|
52
|
+
"ai",
|
|
53
|
+
"component-inspector",
|
|
54
|
+
"developer-tools",
|
|
55
|
+
"chrome-extension"
|
|
56
|
+
],
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"clsx": "^2.1.0",
|
|
59
|
+
"tailwind-merge": "^2.2.1"
|
|
60
|
+
},
|
|
61
|
+
"peerDependencies": {
|
|
62
|
+
"react": ">=16.8.0",
|
|
63
|
+
"react-dom": ">=16.8.0",
|
|
64
|
+
"react-native": ">=0.60.0",
|
|
65
|
+
"@tauri-apps/api": "^2",
|
|
66
|
+
"@tauri-apps/plugin-clipboard-manager": "^2",
|
|
67
|
+
"react-native-view-shot": ">=3.0.0",
|
|
68
|
+
"expo-clipboard": ">=4.0.0",
|
|
69
|
+
"expo-media-library": ">=15.0.0"
|
|
70
|
+
},
|
|
71
|
+
"peerDependenciesMeta": {
|
|
72
|
+
"react-dom": {
|
|
73
|
+
"optional": true
|
|
74
|
+
},
|
|
75
|
+
"react-native": {
|
|
76
|
+
"optional": true
|
|
77
|
+
},
|
|
78
|
+
"@tauri-apps/api": {
|
|
79
|
+
"optional": true
|
|
80
|
+
},
|
|
81
|
+
"@tauri-apps/plugin-clipboard-manager": {
|
|
82
|
+
"optional": true
|
|
83
|
+
},
|
|
84
|
+
"react-native-view-shot": {
|
|
85
|
+
"optional": true
|
|
86
|
+
},
|
|
87
|
+
"expo-clipboard": {
|
|
88
|
+
"optional": true
|
|
89
|
+
},
|
|
90
|
+
"expo-media-library": {
|
|
91
|
+
"optional": true
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"optionalDependencies": {
|
|
95
|
+
"framer-motion": "^12.26.2",
|
|
96
|
+
"html2canvas": "^1.4.1",
|
|
97
|
+
"lucide-react": "^0.562.0"
|
|
98
|
+
},
|
|
99
|
+
"devDependencies": {
|
|
100
|
+
"@types/bun": "^1.2.12",
|
|
101
|
+
"@types/chrome": "^0.0.287",
|
|
102
|
+
"@types/react": "^19.2.9",
|
|
103
|
+
"@types/react-dom": "^19.2.3",
|
|
104
|
+
"@types/react-native": "^0.73.0",
|
|
105
|
+
"@types/sharp": "^0.32.0",
|
|
106
|
+
"@vitejs/plugin-react": "^4.3.4",
|
|
107
|
+
"crx3": "^2.0.0",
|
|
108
|
+
"esbuild": "^0.25.4",
|
|
109
|
+
"react": "^19.1.0",
|
|
110
|
+
"react-dom": "^19.1.0",
|
|
111
|
+
"sharp": "^0.34.5",
|
|
112
|
+
"typescript": "^5.9.3",
|
|
113
|
+
"vite": "^6.3.5"
|
|
114
|
+
}
|
|
115
|
+
}
|