A beautiful React component library for building AI prompts with @mentions. Features a sleek mention menu, nested submenus, keyboard navigation, custom theming, and file extension icons.
- 🎨 Multiple preset themes — Light, Cursor Dark, GitHub Dark, Minimal
- 🎯 Multiple trigger characters — Use
@,#,/, or any character - 📁 Nested menus — Navigate hierarchical options with Tab/Escape
- ⌨️ Full keyboard navigation — Arrow keys, Enter, Tab, Escape
- 🏷️ Mention pills — Beautiful styled tags for selected mentions
- 🖼️ Icons custom and auto — Add icons to menu items, mentions. File extension icons are supported.
- 🎛️ Imperative API — Programmatically append mentions via ref
- 📱 Message component — Render sent messages with formatted mentions
- 🎨 Fully CSS customizable — CSS variables and theme objects
npm install prompt-mentionsyarn add prompt-mentionspnpm add prompt-mentionsimport { Prompt } from "prompt-mentions";
import "prompt-mentions/style.css";
const options = [
{ id: "alice", label: "Alice Johnson" },
{ id: "bob", label: "Bob Smith" },
{ id: "main-ts", label: "main.ts" },
];
function App() {
return (
<Prompt
placeholder="Type @ to mention..."
mentionConfigs={[{ trigger: "@", options }]}
onChange={(value, mentions) => {
console.log("Value:", value);
console.log("Mentions:", mentions);
}}
/>
);
}The main input component with mention support.
import { Prompt } from "prompt-mentions";| Prop | Type | Default | Description |
|---|---|---|---|
initialValue |
string |
"" |
Initial text content with optional mentions in @[id] format |
placeholder |
string |
"" |
Placeholder text when input is empty |
mentionConfigs |
MentionConfig[] |
[{ trigger: '@', options: [] }] |
Array of mention trigger configurations |
theme |
PresetThemeName | PromptTheme |
— | Theme preset name or custom theme object |
className |
string |
"" |
Additional CSS class name |
style |
CSSProperties |
— | Inline styles |
extensionIcons |
boolean |
false |
Auto-add file icons based on extension |
onChange |
(value: string, mentions: SelectedMention[]) => void |
— | Called on every text change |
onEnter |
(value: string, mentions: SelectedMention[]) => void |
— | Called when Enter is pressed |
onMentionAdded |
(mention: SelectedMention) => void |
— | Called when a mention is selected |
onMentionDeleted |
(mention: SelectedMention) => void |
— | Called when a mention is removed |
onMentionClick |
(mention: SelectedMention) => void |
— | Called when a mention pill is clicked |
interface MentionConfig {
trigger: string; // Character that triggers the menu (e.g., '@', '#', '/')
options: MentionOption[]; // Array of mention options
menuPosition?: "above" | "below"; // Menu position relative to cursor
showTrigger?: boolean; // Show trigger character in pill (default: false)
}interface MentionOption {
id: string; // Unique identifier
label: string; // Display text
icon?: ReactNode; // Optional icon component
type?: "item" | "divider" | "title"; // Item type
children?: MentionOption[]; // Nested submenu items
labelRight?: string; // Secondary label (e.g., file path)
indent?: number; // Visual indent level
}Display sent messages with formatted mention pills.
import { Message } from "prompt-mentions";
<Message
value="Hello @[alice]! Please review @[main-ts]"
mentionConfigs={[{ trigger: "@", options }]}
onMentionClick={(mention) => console.log("Clicked:", mention)}
/>;| Prop | Type | Default | Description |
|---|---|---|---|
value |
string |
— | Message text with mentions in trigger[id] format |
mentionConfigs |
MessageMentionConfig[] |
[{ trigger: '@' }] |
Mention configurations for label/icon lookup |
theme |
PresetThemeName | PromptTheme |
— | Theme preset or custom theme |
className |
string |
"" |
Additional CSS class name |
style |
CSSProperties |
— | Inline styles |
extensionIcons |
boolean |
false |
Auto-add file icons based on extension |
onMentionClick |
(mention) => void |
— | Called when a mention pill is clicked |
<Prompt theme="light" /> // Default light theme
<Prompt theme="cursorDark" /> // Cursor IDE dark theme
<Prompt theme="githubDark" /> // GitHub dark theme
<Prompt theme="minimal" /> // Clean minimal themePass a PromptTheme object for full control:
const customTheme: PromptTheme = {
backgroundColor: "#1a1625",
color: "#e0d4f7",
placeholderColor: "#6b5b8c",
fontSize: "14px",
borderRadius: "12px",
borderColor: "#2d2640",
focusBorderColor: "#9c6ade",
menu: {
backgroundColor: "#1a1625",
borderColor: "#2d2640",
color: "#c4b5dc",
itemHoverColor: "#2d2640",
},
pill: {
backgroundColor: "linear-gradient(135deg, #7c3aed, #c026d3)",
borderRadius: "8px",
color: "white",
},
};
<Prompt theme={customTheme} />;Override only specific properties:
<Prompt
theme={{
focusBorderColor: "#f43f5e",
pill: {
backgroundColor: "#16a34a",
},
}}
/>All styling is controlled via CSS variables. Override them in your CSS:
.prompt-container {
--prompt-background-color: white;
--prompt-color: black;
--prompt-placeholder-color: #9ca3af;
--prompt-border-radius: 0.375rem;
--prompt-border-color: #d1d5db;
--prompt-focus-border-color: #6366f1;
--prompt-mention-pill-background-color: linear-gradient(
135deg,
#6366f1,
#8b5cf6
);
--prompt-mention-pill-color: white;
--prompt-mention-pill-border-radius: 9999px;
--prompt-mention-menu-background-color: white;
--prompt-mention-menu-border-color: #e5e7eb;
--prompt-mention-menu-item-hover-color: #f3f4f6;
}Configure different triggers for different types of mentions:
<Prompt
placeholder="Type @, #, or / ..."
mentionConfigs={[
{ trigger: "@", options: peopleOptions },
{ trigger: "#", options: tagOptions },
{ trigger: "/", options: commandOptions, menuPosition: "above" },
]}
/>Create hierarchical option structures:
const options = [
{
id: "team",
label: "Team Members",
icon: <UsersIcon />,
children: [
{ id: "alice", label: "Alice Johnson" },
{ id: "bob", label: "Bob Smith" },
],
},
{
id: "projects",
label: "Projects",
icon: <FolderIcon />,
children: [
{ id: "alpha", label: "Project Alpha" },
{ id: "beta", label: "Project Beta" },
],
},
];Navigate with:
- Tab or → — Enter submenu
- Escape or ← — Exit submenu
Add icons and secondary labels to options:
const fileOptions = [
{
id: "prompt-tsx",
label: "Prompt.tsx",
labelRight: "src/components/",
icon: <TypeScriptIcon />,
indent: 1,
},
];Automatically add file type icons based on file extensions:
<Prompt
extensionIcons={true}
mentionConfigs={[{ trigger: "@", options: fileOptions }]}
/>Supports: .ts, .tsx, .js, .jsx, .css, .html, .json, .md, .py, .go, .rs, .sql, and many more.
Organize options with visual separators:
const options = [
{ id: "title-people", label: "People", type: "title" },
{ id: "alice", label: "Alice" },
{ id: "bob", label: "Bob" },
{ id: "divider-1", label: "", type: "divider" },
{ id: "title-files", label: "Files", type: "title" },
{ id: "readme", label: "README.md" },
];Use the imperative handle to control the prompt externally:
import { useRef } from "react";
import { Prompt, PromptHandle, MentionOption } from "prompt-mentions";
function MyComponent() {
const promptRef = useRef<PromptHandle>(null);
const handleAddMention = (option: MentionOption) => {
// Append mention with default trigger (@)
promptRef.current?.appendMention(option);
// Or with a specific trigger
promptRef.current?.appendMention(option, "#");
// Focus the input
promptRef.current?.focus();
};
const handleInsertText = () => {
// Insert text at current cursor position (or at end if not focused)
// Behaves like typing - triggers mention menu when a trigger character is inserted
promptRef.current?.insertText("Hello ");
// Insert a trigger to open the mention menu
promptRef.current?.insertText("@");
};
return (
<>
<Prompt
ref={promptRef}
mentionConfigs={[
{ trigger: "@", options: userOptions },
{ trigger: "#", options: tagOptions },
]}
/>
<button onClick={() => handleAddMention({ id: "alice", label: "Alice" })}>
Add @Alice
</button>
<button onClick={handleInsertText}>Insert Text</button>
</>
);
}| Method | Signature | Description |
|---|---|---|
appendMention |
(option: MentionOption, trigger?: string) => void |
Appends a mention pill to the end of the input |
focus |
() => void |
Focuses the prompt input |
insertText |
(text: string) => void |
Inserts text at cursor position. Behaves like typing—triggers mention menu when a trigger character is inserted |
Pre-populate the input with existing mentions:
<Prompt
initialValue="Hello @[alice]! Please check @[main-ts]"
mentionConfigs={[{ trigger: "@", options }]}
/>The format is trigger[id] where id matches an option's id field.
// Components
export { Prompt, Message } from "prompt-mentions";
// Types
export type {
MentionOption,
MentionItemType,
SelectedMention,
PromptTheme,
PresetThemeName,
} from "prompt-mentions";
// Theme utilities
export { themeToStyles, presetThemes, defaultTheme } from "prompt-mentions";
// Extension icon utilities
export {
getExtensionIcon,
extensionIconMap,
filenameIconMap,
DefaultFileIcon,
DefaultFolderIcon,
} from "prompt-mentions";| Key | Action |
|---|---|
↑ / ↓ |
Navigate menu options |
Enter |
Select highlighted option |
Tab / → |
Enter submenu (if available) |
Escape / ← |
Exit submenu or close menu |
Backspace |
Delete mention (when cursor is adjacent) |
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
# Install dependencies
npm install
# Run Storybook for development
npm run storybook
# Run tests
npm run test
# Build the library
npm run buildContributions are welcome! Please read our contributing guidelines and submit pull requests to the main repository.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Made with ❤️ by nao Labs