New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

text-input-cursor

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

text-input-cursor

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

latest
Source
npmnpm
Version
0.1.1
Version published
Maintainers
1
Created
Source

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:

  • Wrap the TextInput and positioned elements in a common parent View
  • Use position: 'absolute' on the positioned element
  • 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

PlatformSupport
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

Keywords

react-native

FAQs

Package last updated on 17 Dec 2025

Related posts