{"_id":"@data_is_null/tooltip-native-expo","name":"@data_is_null/tooltip-native-expo","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@data_is_null/tooltip-native-expo","version":"0.1.0","description":"Zero-latency tooltip with 60/120fps target tracking via Reanimated UI-thread measure","main":"build/index.js","workspaces":["example"],"types":"build/index.d.ts","expo":{"modules":["expo-module.config.json"]},"scripts":{"build":"expo-module build","clean":"expo-module clean","lint":"expo-module lint","test":"expo-module test","prepare":"expo-module prepare","prepublishOnly":"expo-module prepublishOnly","expo-module":"expo-module","open:ios":"xed example/ios","open:android":"open -a \"Android Studio\" example/android"},"keywords":["react-native","expo","@data_is_null/tooltip-native-expo","TooltipNativeExpo"],"repository":{"type":"git","url":"git+https://github.com/DataIsNull/tooltip-native-expo.git"},"bugs":{"url":"https://github.com/DataIsNull/tooltip-native-expo/issues"},"author":{"name":"Hamid Akhmedov","email":"hamidakhmedovwork@gmail.com","url":"https://github.com/DataIsNull"},"license":"MIT","homepage":"https://github.com/DataIsNull/tooltip-native-expo#readme","devDependencies":{"@types/react":"~19.1.1","expo":"~54.0.33","expo-module-scripts":"^4.0.4","react-native":"0.81.5","react-native-reanimated":"~4.1.1","react-native-worklets":"~0.8.3"},"peerDependencies":{"expo":"*","react":"*","react-native":"*","react-native-reanimated":">=3.0.0"},"_id":"@data_is_null/tooltip-native-expo@0.1.0","gitHead":"78e15a402b435833db67f99443e725cb13f8e8d8","_nodeVersion":"23.11.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-2t/Usa0Ydu2Py25G+Qgq+7D3Fd+bYZcBpqUNcLyIuEkTZreJl1rhAvzCwfUYfmPZhQ+hbW70I1Lv4gWBiKCTjA==","shasum":"4b1be143414a5b3ee4c8ad2442390c7bd7b94e97","tarball":"https://registry.npmjs.org/@data_is_null/tooltip-native-expo/-/tooltip-native-expo-0.1.0.tgz","fileCount":58,"unpackedSize":92310,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCID0kf3lxbRaIDPwtJDCdgFnQnsXsaXdRQ2eJRoOPxCUiAiBsdVQUA6e1yDcTDjXTh7hMoVH9SucmbPARyRnY53sg1A=="}]},"_npmUser":{"name":"data_is_null","email":"hamidakhmedovwork@gmail.com"},"directories":{},"maintainers":[{"name":"data_is_null","email":"hamidakhmedovwork@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/tooltip-native-expo_0.1.0_1779280885548_0.3578557195166867"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-20T12:41:25.292Z","0.1.0":"2026-05-20T12:41:25.675Z","modified":"2026-05-20T12:41:25.936Z"},"maintainers":[{"name":"data_is_null","email":"hamidakhmedovwork@gmail.com"}],"description":"Zero-latency tooltip with 60/120fps target tracking via Reanimated UI-thread measure","homepage":"https://github.com/DataIsNull/tooltip-native-expo#readme","keywords":["react-native","expo","@data_is_null/tooltip-native-expo","TooltipNativeExpo"],"repository":{"type":"git","url":"git+https://github.com/DataIsNull/tooltip-native-expo.git"},"author":{"name":"Hamid Akhmedov","email":"hamidakhmedovwork@gmail.com","url":"https://github.com/DataIsNull"},"bugs":{"url":"https://github.com/DataIsNull/tooltip-native-expo/issues"},"license":"MIT","readme":"# @data_is_null/tooltip-native-expo\n\nHigh-performance tooltip for React Native (Expo). Native CADisplayLink/Choreographer tracking at 60-120fps — no JS-thread polling.\n\n## Features\n\n- **Native tracking** — target position tracked via CADisplayLink (iOS) and Choreographer (Android), zero JS bridge overhead for stationary elements\n- **Spotlight overlay** — dim background with a precisely cut-out hole around the target, supports `borderRadius` for circular/rounded highlights\n- **Smart positioning** — auto-places tooltip where there's room (`top`, `bottom`, `left`, `right`, `auto`)\n- **Animated** — spring scale + opacity transitions via Reanimated\n- **Arrow** — directional arrow pointing at the target, follows placement\n- **Fully customizable** — colors, border radius, padding, offset, arrow size, custom content\n\n## Installation\n\n```bash\nnpx expo install @data_is_null/tooltip-native-expo\n```\n\n### Peer dependencies\n\n```bash\nnpx expo install react-native-reanimated\n```\n\n## Quick Start\n\nWrap your app with `TooltipProvider`, then use `Tooltip` around any target element:\n\n```tsx\nimport { TooltipProvider, Tooltip } from '@data_is_null/tooltip-native-expo';\n\nfunction App() {\n  return (\n    <TooltipProvider>\n      <HomeScreen />\n    </TooltipProvider>\n  );\n}\n\nfunction HomeScreen() {\n  const [visible, setVisible] = useState(false);\n\n  return (\n    <Tooltip\n      visible={visible}\n      content={<Text style={{ color: '#fff' }}>Hello!</Text>}\n      onDismiss={() => setVisible(false)}\n      padding={12}\n    >\n      <Pressable onPress={() => setVisible(true)}>\n        <Text>Tap me</Text>\n      </Pressable>\n    </Tooltip>\n  );\n}\n```\n\n## Spotlight\n\nHighlight the target element with a dimmed overlay:\n\n```tsx\n<Tooltip\n  visible={visible}\n  content={<Text style={{ color: '#fff' }}>Check this out</Text>}\n  onDismiss={() => setVisible(false)}\n  spotlight\n  spotlightBorderRadius={16}\n  spotlightPadding={8}\n  padding={12}\n>\n  <View style={{ width: 100, height: 100, borderRadius: 16 }}>\n    <Text>Target</Text>\n  </View>\n</Tooltip>\n```\n\nSet `spotlightBorderRadius={999}` for a circular spotlight around round elements.\n\n## API\n\n### `<TooltipProvider>`\n\nWrap your app (or a subtree) with this provider. Renders the overlay and tooltip bubble above all children.\n\n| Prop | Type | Description |\n|------|------|-------------|\n| `children` | `ReactNode` | App content |\n\n### `<Tooltip>`\n\nWraps a target element. Controls visibility and tooltip content.\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `visible` | `boolean` | — | Show/hide the tooltip |\n| `content` | `ReactNode` | — | Tooltip content |\n| `children` | `ReactNode` | — | Target element |\n| `onDismiss` | `() => void` | — | Called when overlay is tapped |\n| `placement` | `'auto' \\| 'top' \\| 'bottom' \\| 'left' \\| 'right'` | `'auto'` | Preferred placement |\n| `offset` | `number` | `8` | Distance from target (px) |\n| `padding` | `number` | `0` | Inner padding of the tooltip bubble |\n| `backgroundColor` | `string` | `'#1a1a2e'` | Tooltip background color |\n| `borderRadius` | `number` | `8` | Tooltip border radius |\n| `arrowSize` | `number` | `6` | Arrow size (px) |\n| `contentStyle` | `StyleProp<ViewStyle>` | — | Additional style for the tooltip bubble |\n| `spotlight` | `boolean` | `false` | Enable spotlight overlay |\n| `spotlightPadding` | `number` | `0` | Padding around the spotlight hole |\n| `spotlightBorderRadius` | `number` | `0` | Border radius of the spotlight hole |\n\n## How It Works\n\n1. **Native tracking**: When a tooltip becomes visible, the native module finds the target view by its React tag and starts a display-link callback (CADisplayLink on iOS, Choreographer on Android). Each frame, it checks the view's screen position — if it changed, it emits an event. For stationary targets, zero events are sent after the initial measurement.\n\n2. **Spotlight overlay**: A single `View` with a large `borderWidth` creates a dimmed overlay with a geometrically correct rounded hole — no SVG or masking dependencies required.\n\n3. **Positioning**: The tooltip bubble position is computed on the JS side using the target rect, available screen space, and preferred placement. If the preferred side doesn't have enough room, it flips to the opposite side.\n\n## Platforms\n\n- iOS 15.1+\n- Android\n- Web (not supported — native module required)\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-f8ba550ccc8aa90df0fe2e5a0ce773d3"}