React component library to add an AI prompt with mentions.
npm install prompt-mentionsA 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
``bash`
npm install prompt-mentions
`bash`
yarn add prompt-mentions
`bash`
pnpm add prompt-mentions
`tsx
import { 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 (
mentionConfigs={[{ trigger: "@", options }]}
onChange={(value, mentions) => {
console.log("Value:", value);
console.log("Mentions:", mentions);
}}
/>
);
}
`
The main input component with mention support.
`tsx`
import { Prompt } from "prompt-mentions";
#### Props
| 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 |
#### MentionConfig
`typescript`
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)
}
#### MentionOption
`typescript`
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.
`tsx
import { Message } from "prompt-mentions";
mentionConfigs={[{ trigger: "@", options }]}
onMentionClick={(mention) => console.log("Clicked:", mention)}
/>;
`
#### Props
| 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 |
`tsx`
Pass a PromptTheme object for full control:
`tsx
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",
},
};
`
Override only specific properties:
`tsx`
focusBorderColor: "#f43f5e",
pill: {
backgroundColor: "#16a34a",
},
}}
/>
All styling is controlled via CSS variables. Override them in your CSS:
`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:
`tsx`
mentionConfigs={[
{ trigger: "@", options: peopleOptions },
{ trigger: "#", options: tagOptions },
{ trigger: "/", options: commandOptions, menuPosition: "above" },
]}
/>
Create hierarchical option structures:
`tsx`
const options = [
{
id: "team",
label: "Team Members",
icon:
children: [
{ id: "alice", label: "Alice Johnson" },
{ id: "bob", label: "Bob Smith" },
],
},
{
id: "projects",
label: "Projects",
icon:
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:
`tsx`
const fileOptions = [
{
id: "prompt-tsx",
label: "Prompt.tsx",
labelRight: "src/components/",
icon:
indent: 1,
},
];
Automatically add file type icons based on file extensions:
`tsx`
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:
`tsx`
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:
`tsx
import { useRef } from "react";
import { Prompt, PromptHandle, MentionOption } from "prompt-mentions";
function MyComponent() {
const promptRef = useRef
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 (
<>
mentionConfigs={[
{ trigger: "@", options: userOptions },
{ trigger: "#", options: tagOptions },
]}
/>
>
);
}
`
#### PromptHandle Methods
| 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:
`tsx`
mentionConfigs={[{ trigger: "@", options }]}
/>
The format is trigger[id] where id matches an option's id field.
`typescript
// 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)
`bashInstall dependencies
npm install
Contributing
Contributions are welcome! Please read our contributing guidelines and submit pull requests to the main repository.
1. Fork the repository
2. Create your feature branch (
git checkout -b feature/amazing-feature)
3. Commit your changes (git commit -m 'Add amazing feature')
4. Push to the branch (git push origin feature/amazing-feature`)MIT Β© (https://github.com/getnao/prompt-mentions/blob/main/LICENSE)
---
Made with β€οΈ by nao Labs