react-mention-components
v1.0.0
Published
A comprehensive React library for mention functionality with customizable components, hooks, and utilities
Maintainers
Readme
React Mention Components
A comprehensive React library for mention functionality with customizable components, hooks, and utilities. Perfect for building chat applications, comment systems, and any interface that requires user mentions.
Features
- 🎯 Multiple Components:
MentionItem,MentionList, andMentionInput - 🎨 Customizable: Size variants, themes, and custom rendering
- 🔍 Smart Search: Built-in filtering and sorting with debounced search
- ⌨️ Keyboard Navigation: Full keyboard support with arrow keys
- 🌙 Dark Mode: Automatic dark theme support
- 📱 Responsive: Works on all screen sizes
- 🎣 React Hooks:
useMentionshook for state management - 🛠️ Utilities: Helper functions for filtering, formatting, and validation
- 📦 TypeScript: Full TypeScript support with type definitions
Installation
npm install react-mention-components
# or
yarn add react-mention-componentsQuick Start
import React, { useState } from "react";
import { MentionInput, Mention, useMentions } from "react-mention-components";
const App = () => {
const [value, setValue] = useState("");
const { mentions, filteredMentions, loading, setLoading } = useMentions({
initialMentions: [
{ id: "1", type: "user", name: "John Doe", email: "[email protected]" },
{ id: "2", type: "group", name: "Developers" },
],
});
const handleSearch = async (query: string) => {
setLoading(true);
// Simulate API call
await new Promise((resolve) => setTimeout(resolve, 500));
setLoading(false);
};
return (
<MentionInput
value={value}
onChange={setValue}
suggestions={filteredMentions}
loading={loading}
onSearch={handleSearch}
placeholder="Type @ to mention someone..."
/>
);
};Components
MentionItem
A single mention item component with customizable appearance.
import { MentionItem } from "react-mention-components";
const mention = {
id: "1",
type: "user",
name: "John Doe",
email: "[email protected]",
avatar: "https://example.com/avatar.jpg",
status: "online",
};
<MentionItem
mention={mention}
size="medium"
variant="detailed"
showStatus={true}
showAvatar={true}
onMouseEnter={(mention) => console.log("Hovered:", mention)}
insertMention={(mention) => console.log("Selected:", mention)}
/>;Props
| Prop | Type | Default | Description |
| -------------- | --------------------------------------- | ----------- | ----------------------------- |
| mention | Mention | - | The mention object to display |
| size | 'small' \| 'medium' \| 'large' | 'medium' | Size variant |
| variant | 'default' \| 'compact' \| 'detailed' | 'default' | Display variant |
| showStatus | boolean | true | Show online status indicator |
| showAvatar | boolean | true | Show avatar image |
| disabled | boolean | false | Disable interaction |
| selected | boolean | false | Highlight as selected |
| customRender | (mention: Mention) => React.ReactNode | - | Custom render function |
MentionList
A list component for displaying multiple mentions with filtering and keyboard navigation.
import { MentionList } from "react-mention-components";
<MentionList
mentions={mentions}
onSelect={(mention) => console.log("Selected:", mention)}
maxHeight="300px"
loading={false}
emptyMessage="No mentions found"
filterValue=""
onFilterChange={(value) => console.log("Filter:", value)}
/>;Props
| Prop | Type | Default | Description |
| ---------------- | --------------------------------------- | --------------------- | --------------------------------- |
| mentions | Mention[] | - | Array of mentions to display |
| onSelect | (mention: Mention) => void | - | Callback when mention is selected |
| maxHeight | string | '300px' | Maximum height of the list |
| loading | boolean | false | Show loading state |
| emptyMessage | string | 'No mentions found' | Message when no mentions |
| filterValue | string | - | Current filter value |
| onFilterChange | (value: string) => void | - | Filter change callback |
| renderItem | (mention: Mention) => React.ReactNode | - | Custom item renderer |
MentionInput
A complete input component with mention suggestions and auto-completion.
import { MentionInput } from "react-mention-components";
<MentionInput
value={value}
onChange={setValue}
onMentionSelect={(mention) => console.log("Mention selected:", mention)}
suggestions={suggestions}
loading={loading}
onSearch={handleSearch}
triggerChar="@"
placeholder="Type @ to mention someone..."
maxLength={1000}
/>;Props
| Prop | Type | Default | Description |
| ------------------ | --------------------------------------- | ------- | ----------------------------------- |
| value | string | - | Input value |
| onChange | (value: string) => void | - | Value change callback |
| onMentionSelect | (mention: Mention) => void | - | Mention selection callback |
| suggestions | Mention[] | [] | Available suggestions |
| loading | boolean | false | Show loading state |
| onSearch | (query: string) => void | - | Search callback |
| triggerChar | string | '@' | Character that triggers suggestions |
| renderSuggestion | (mention: Mention) => React.ReactNode | - | Custom suggestion renderer |
Hooks
useMentions
A custom hook for managing mention state and operations.
import { useMentions } from "react-mention-components";
const {
mentions,
filteredMentions,
searchQuery,
loading,
setSearchQuery,
setLoading,
addMention,
removeMention,
updateMention,
clearMentions,
searchMentions,
debouncedSearch,
} = useMentions({
initialMentions: [],
maxSuggestions: 10,
debounceMs: 300,
searchFields: ["name", "email", "id"],
typeOrder: ["user", "group", "channel", "role"],
});Utilities
The library provides several utility functions:
import {
filterMentions,
sortMentions,
formatMentionText,
validateMention,
createDefaultMention,
debounce,
extractMentionsFromText,
replaceMentionsInText,
} from "react-mention-components";
// Filter mentions by search query
const filtered = filterMentions(mentions, "john", ["name", "email"]);
// Sort mentions by relevance and type
const sorted = sortMentions(mentions, "john");
// Format mention for display
const formatted = formatMentionText(mention, "display");
// Validate mention object
const isValid = validateMention(mention);
// Create default mention
const defaultMention = createDefaultMention("1", "user", "John Doe");
// Extract mentions from text
const extracted = extractMentionsFromText("Hello @john and @jane!");
// Replace mentions in text
const replaced = replaceMentionsInText(text, mentions, "@", "display");Types
interface Mention {
id: string;
type: "user" | "group" | "channel" | "role";
name?: string;
avatar?: string;
email?: string;
status?: "online" | "offline" | "away" | "busy";
metadata?: Record<string, any>;
}Styling
The library includes built-in styles that support both light and dark themes. You can customize the appearance by overriding CSS variables or using custom CSS classes.
CSS Variables
:root {
--mention-primary-color: #007bff;
--mention-secondary-color: #6c757d;
--mention-success-color: #28a745;
--mention-warning-color: #ffc107;
--mention-danger-color: #dc3545;
--mention-border-radius: 6px;
--mention-transition: all 0.2s ease;
}Dark Theme
The library automatically detects and applies dark theme styles using prefers-color-scheme: dark.
Examples
Basic Chat Input
import React, { useState } from "react";
import { MentionInput, useMentions } from "react-mention-components";
const ChatInput = () => {
const [value, setValue] = useState("");
const { mentions, filteredMentions, loading, setLoading } = useMentions();
const handleSearch = async (query: string) => {
setLoading(true);
// Fetch mentions from API
const results = await fetchMentions(query);
setLoading(false);
};
const handleSubmit = () => {
console.log("Message:", value);
setValue("");
};
return (
<div>
<MentionInput
value={value}
onChange={setValue}
suggestions={filteredMentions}
loading={loading}
onSearch={handleSearch}
onMentionSelect={(mention) => console.log("Mentioned:", mention)}
/>
<button onClick={handleSubmit}>Send</button>
</div>
);
};Custom Mention Item
const CustomMentionItem = ({ mention }: { mention: Mention }) => (
<div className="custom-mention">
<img src={mention.avatar} alt={mention.name} />
<div>
<strong>{mention.name}</strong>
<small>{mention.email}</small>
</div>
</div>
);
<MentionList
mentions={mentions}
renderItem={(mention) => <CustomMentionItem mention={mention} />}
/>;Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
License
MIT License - see LICENSE file for details.
