GhostComplete đŸ‘ģ

Smart autocomplete (38kB) that learns from user input and works perfectly with React controlled components

🧠 Word Learning âš›ī¸ React-Friendly đŸˇī¸ Multi-Group đŸĒļ Lightweight

The React Controlled Component Problem

Traditional autocomplete breaks with React's controlled components. GhostComplete provides a reliable solution that learns common words.

❌ Traditional Autocomplete

Problematic React Code
// ❌ Often breaks with controlled components
function SearchInput() {
  const [value, setValue] = useState('');
  
  return (
    <input
      value={value}
      onChange={(e) => setValue(e.target.value)}
      autoComplete="on" // Unreliable
    />
  );
}

Native autocomplete often fails with React's controlled inputs due to state management conflicts.

✅ GhostComplete Solution

Reliable with GhostComplete
// ✅ Works perfectly with controlled components
import 'ghostcomplete'; // Auto-initializes and exposes GhostComplete globally

function SearchInput() {
  const [value, setValue] = useState('');
  const inputRef = useGhostComplete('search');
  
  return (
    <input
      ref={inputRef}
      value={value}
      onChange={(e) => setValue(e.target.value)}
      data-autocomplete="search"
    />
  );
}

GhostComplete seamlessly integrates with React's controlled components and learns common words from user input.

Live Demo

Try typing in the inputs below. The library shows suggestions from the first character and learns words (3+ chars) for future use.

Try typing any character like "j", "h", "w" - suggestions appear instantly!
Start with words like "Great", "Amazing", "Perfect", etc.

How it works: Suggestions appear from the first character you type. Words with 3+ characters are saved to build vocabulary for each input group.

Why Choose GhostComplete?

Built specifically for modern web applications with word learning capabilities

🧠

Word Learning

Shows suggestions from the first character typed, learns words (3+ chars) to build smart vocabulary and provide increasingly relevant completions.

âš›ī¸

React-Friendly

Designed specifically for React controlled components where native autocomplete often fails.

đŸˇī¸

Multi-Group Support

Organize completions by context - search queries, comments, forms - each with their own vocabulary.

đŸŽ¯

Context-Aware

Provides word suggestions based on typing frequency and context within each group.

đŸĒļ

Lightweight

Only 38kB package size with zero dependencies. Fast loading and minimal impact on your bundle size.

⚡

High Performance

Efficient trie-based search with intelligent debouncing and memory management.

Installation & Quick Start

đŸ“Ļ NPM Installation

Install via NPM
npm install ghostcomplete

🔗 CDN Usage

Include via CDN
<script src="https://unpkg.com/ghostcomplete@latest/dist/index.umd.js"></script>

🚀 Basic Usage

HTML + JavaScript
<!-- ✅ Automatic - Just add data-autocomplete attribute -->
<input type="text" data-autocomplete="search" placeholder="Start typing...">
<textarea data-autocomplete="comments" placeholder="Write comment..."></textarea>

<script>
// Import the library (automatically detects and initializes inputs)
import 'ghostcomplete';

// That's it! Elements with data-autocomplete work automatically

// âš ī¸ Manual initialization only needed for:
// - Dynamic elements created after page load
// - React components (useEffect hooks)  
// - Elements without data-autocomplete attribute

GhostComplete.init('#my-input', 'search');  // For specific elements
GhostComplete.initAll('default');           // For all elements at once

// Configure groups as needed
GhostComplete.setGroupConfig('search', {
  MAX_SUGGESTIONS: 8,
  DEBOUNCE_DELAY: 100
});
</script>

When Do I Need init()?

✅ No init() Required

GhostComplete works automatically when:

  • â€ĸ Elements have data-autocomplete attribute
  • â€ĸ Elements exist when page loads
  • â€ĸ Using static HTML
Automatic Usage
<!-- Just works automatically! -->
<input data-autocomplete="search" placeholder="Search...">
<textarea data-autocomplete="comments"></textarea>

âš ī¸ Manual init() Required

You need to call init() when:

  • â€ĸ Creating elements dynamically with JavaScript
  • â€ĸ Working with React/Vue components
  • â€ĸ Elements don't have data-autocomplete
Manual Initialization
// Dynamic elements
const input = document.createElement('input');
GhostComplete.init(input, 'search');

// React components
useEffect(() => {
  GhostComplete.init(inputRef.current, 'search');
}, []);
💡

Pro Tip

Start with the automatic data-autocomplete approach. Only use manual init() when you need it for dynamic content or framework components.

React Integration Examples

Custom React Hook

useGhostComplete.js
import { useEffect, useRef } from 'react';
// Import GhostComplete (auto-initializes)
import 'ghostcomplete';

function useGhostComplete(group = 'default', config = {}) {
  const ref = useRef(null);
  
  useEffect(() => {
    if (ref.current) {
      // Apply configuration
      if (Object.keys(config).length > 0) {
        GhostComplete.setGroupConfig(group, config);
      }
      
      // Manual init required for React components
      GhostComplete.init(ref.current, group);
    }
  }, [group]);
  
  return ref;
}

// Usage
function SearchInput() {
  const searchRef = useGhostComplete('search', {
    MAX_SUGGESTIONS: 8,
    DEBOUNCE_DELAY: 100
  });
  
  return (
    <input
      ref={searchRef}
      data-autocomplete="search"
      placeholder="Search..."
    />
  );
}

// Note: For static HTML, no init() needed:
// <input data-autocomplete="search" placeholder="Search..." />

Multi-Input Form

ContactForm.jsx
function ContactForm() {
  const nameRef = useGhostComplete('names');
  const companyRef = useGhostComplete('companies');
  const messageRef = useGhostComplete('messages', {
    MAX_WORDS: 500
  });
  
  return (
    <form>
      <input
        ref={nameRef}
        data-autocomplete="names"
        placeholder="Your name"
      />
      <input
        ref={companyRef}
        data-autocomplete="companies"
        placeholder="Company name"
      />
      <textarea
        ref={messageRef}
        data-autocomplete="messages"
        placeholder="Your message"
      />
    </form>
  );
}

Dynamic Configuration

DynamicSearch.jsx
function DynamicSearch({ category }) {
  const searchRef = useRef(null);
  const [query, setQuery] = useState('');
  
  useEffect(() => {
    if (searchRef.current) {
      // Configure different settings based on category
      const configs = {
        products: { MAX_SUGGESTIONS: 10, MAX_WORDS: 1000 },
        users: { MAX_SUGGESTIONS: 8, MAX_WORDS: 500 },
        tags: { MAX_SUGGESTIONS: 6, MAX_WORDS: 300 }
      };
      
      const groupName = `search-${category}`;
      GhostComplete.setGroupConfig(groupName, configs[category] || {});
      GhostComplete.init(searchRef.current, groupName);
    }
  }, [category]);
  
  return (
    <input
      ref={searchRef}
      value={query}
      onChange={(e) => setQuery(e.target.value)}
      data-autocomplete={`search-${category}`}
      placeholder={`Search ${category}...`}
    />
  );
}

API Reference

Core Methods

Method Parameters Description
GhostComplete.init(element, group) element: HTMLElement, group: string Initialize autocomplete on a specific element
GhostComplete.initAll(group) group: string (optional) Initialize all elements with data-autocomplete attribute
GhostComplete.setGroupConfig(group, config, classes) group: string, config: object, classes: object Configure settings and styling for a specific group
GhostComplete.getGroupConfig(group) group: string Get current configuration for a group

Data Management

Method Parameters Description
GhostComplete.clearWords(group) group: string Clear learned words for a specific group
GhostComplete.clearAll(group) group: string Clear all data for a group
GhostComplete.getStats(group) group: string Get statistics about learned data for a group

Performance Configuration

Option Default Description
MAX_WORDS 300 Maximum words to store per group
MAX_SUGGESTIONS 5 Maximum suggestions to show
MAX_STABLE 10 Stable words that won't be removed

Timing Configuration

Option Default Description
DEBOUNCE_DELAY 160ms Delay before processing input
STORAGE_SYNC_DELAY 600ms Delay before saving to localStorage
IDLE_CLEANUP_DELAY 2000ms Delay before cleaning unused data

🎨 CSS Class Customization

Class Property Target Element
popupContainer Suggestions popup container
popupRow Individual suggestion rows
popupRowSelected Currently selected suggestion
popupHint Hint text in popup

Configuration Example:

GhostComplete.setGroupConfig('search', {
  MAX_SUGGESTIONS: 8,
  DEBOUNCE_DELAY: 100,
  MAX_WORDS: 500
}, {
  popupContainer: 'my-search-popup',
  popupRowSelected: 'active-suggestion',
  popupHint: 'search-hint-text'
});