npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

text-input-cursor

v0.1.1

Published

An expo module to get the cursor's on screen coordinates in a text input. Helps to build suggestion tooltips etc.

Readme

text-input-cursor

An Expo module for retrieving the on-screen coordinates of the text cursor in TextInput components. This module enables precise positioning of UI elements such as autocomplete dropdowns, mention suggestions, and tooltips relative to the cursor position.

Installation

npm install text-input-cursor

or

yarn add text-input-cursor

Demo

Mention Demo

Performance Demo

Usage

Standard Mode

The TextInputWithCursor component provides automatic cursor tracking with real-time coordinate updates on every text change.

import { useState } from 'react';
import { View, StyleSheet } from 'react-native';
import { TextInputWithCursor, type CursorCoordinates } from 'text-input-cursor';

export default function Example() {
  const [text, setText] = useState('');
  const [cursorCoords, setCursorCoords] = useState<CursorCoordinates | null>(null);

  return (
    <View style={styles.container}>
      <View>
        <TextInputWithCursor
          value={text}
          onChangeText={setText}
          onCursorCoordinatesChange={({ coordinates }) => {
            setCursorCoords(coordinates);
          }}
          placeholder="Type @ to mention someone..."
          multiline
          style={styles.input}
        />
        {cursorCoords && (
          <View 
            style={[
              styles.dropdown,
              {
                top: cursorCoords.y,
                left: cursorCoords.x,
              }
            ]}
          >
            {/* Your dropdown content */}
          </View>
        )}
      </View>
    </View>
  );
}

Performance Mode

For performance-critical applications, use getCursorCoordinates to fetch coordinates only when needed. This approach eliminates unnecessary calculations during normal typing and only queries cursor position when specific triggers are detected.

import { useState, useRef } from 'react';
import { View, TextInput } from 'react-native';
import { getCursorCoordinates, type CursorCoordinates } from 'text-input-cursor';

export default function PerformanceExample() {
  const [text, setText] = useState('');
  const [cursorCoords, setCursorCoords] = useState<CursorCoordinates | null>(null);
  const inputRef = useRef<TextInput>(null);

  const handleTextChange = async (newText: string) => {
    setText(newText);
    
    // Code to detect @ symbol
    // Code to check if mention is still active (no space after @)
    
    if (/* mention detected */) {
      // Fetch coordinates only when needed
      const coords = await getCursorCoordinates(inputRef);
      setCursorCoords(coords);
    } else {
      setCursorCoords(null);
    }
  };

  return (
    <View style={styles.container}>
      <View>
        <TextInput
          ref={inputRef}
          value={text}
          onChangeText={handleTextChange}
          placeholder="Type @ to mention someone..."
          multiline
          style={styles.input}
        />
        {cursorCoords && (
          <View 
            style={[
              styles.dropdown,
              {
                top: cursorCoords.y,
                left: cursorCoords.x,
              }
            ]}
          >
            {/* Your dropdown content */}
          </View>
        )}
      </View>
    </View>
  );
}

Important: Coordinate Positioning

The returned coordinates (x, y) are relative to the TextInput component, not the screen. To position elements correctly:

  1. Wrap the TextInput and positioned elements in a common parent View
  2. Use position: 'absolute' on the positioned element
  3. Apply the coordinates directly to the element's top and left style properties

The parent View establishes the coordinate space for both the TextInput and the absolutely positioned element. Make sure the parent View doesn't have a padding.

API Reference

TextInputWithCursor

A component that extends React Native's TextInput with automatic cursor tracking.

Props

  • All standard TextInput props
  • onCursorCoordinatesChange?: (event: CursorCoordinatesChangeEvent) => void

CursorCoordinatesChangeEvent

{
  coordinates: CursorCoordinates | null;
  cursorPosition: number;
}

getCursorCoordinates

Function to retrieve cursor coordinates on demand.

function getCursorCoordinates(
  inputRef: RefObject<TextInput>
): Promise<CursorCoordinates | null>

CursorCoordinates

{
  x: number;          // Horizontal position (points)
  y: number;          // Vertical position (points)
  lineHeight: number; // Height of cursor line (points)
}

Returns null if the input reference is unavailable, platform is unsupported, or an error occurs.

Platform Support

| Platform | Support | |----------|---------| | iOS | ✅ | | Android | ✅ | | Web | ✅ |

Implementation Details

This module uses native platform APIs for accurate cursor positioning. Improvements and suggestions are welcome!

  • iOS: UITextView.caretRect(for:) and UITextField.caretRect(for:)
  • Android: Layout.getPrimaryHorizontal(), Layout.getLineTop(), and Layout.getLineBottom()
  • Web: Shadow element technique that creates an invisible mirror div with identical styles and text content, using getBoundingClientRect() on a span element to measure the exact cursor position

License

MIT