A headless mention component for React Native. It's a headless component, so you'll need to provide your styles and suggestions renderer.
- Written In Typescript
- Offers CJS, and ESM builds
- Full TypeScript & JavaScript support
You can use the following command to install this package, or replace npm install with your package manager of choice.
npm i react-native-headless-mention
import { useState, useRef, useEffect } from 'react';
import { Pressable, Text, View } from 'react-native';
import { Input, type MentionSuggestionsProps } from 'react-native-headless-mention';
const suggestions = [
{ id: '1', name: 'Parbez' },
{ id: '2', name: 'Voxelli' },
{ id: '3', name: 'Sho' },
{ id: '4', name: 'Hound' },
{ id: '5', name: 'Sarcaster' },
];
const renderSuggestions = ({ keyword, onSuggestionPress }: MentionSuggestionsProps) => {
if (keyword === undefined) return null;
return (
<View>
{suggestions
.filter((one) => one.name.toLocaleLowerCase().includes(keyword.toLocaleLowerCase()))
.map((one) => (
<Pressable key={one.id} onPress={() => onSuggestionPress(one)} style={{ padding: 12 }}>
<Text>{one.name}</Text>
</Pressable>
))}
</View>
);
};
export default function Campaigns() {
const [value, setValue] = useState('');
return (
<Input
onChange={setValue}
partTypes={[
{
trigger: '@',
renderSuggestions,
textStyle: { fontWeight: 'bold', color: 'blue' },
getLabel(mention) {
const user = suggestions.find((one) => one.id === mention.id);
return user ? `@${user.name}` : `<@${mention.id}>`;
},
pattern: /<(?<trigger>@)(?<id>\d+)>/g,
},
]}
value={value}
/>
);
}
Important
The pattern must be a global regex. If it's a mention regex then don't forget to add the group name trigger
and id
in the regex.
Note
2nd param of onChange
provides all the parts of the value. You can use it to get the mentions present in the value.
import { parseValue, type MentionPartType } from 'react-native-headless-mention';
const partTypes: MentionPartType[] = [
{
trigger: '@',
renderSuggestions,
textStyle: { fontWeight: '500' },
getLabel(mention) {
const user = suggestions.find((one) => one.id === mention.id);
return user ? `@${user.name}` : `<@${mention.id}>`;
},
pattern: /<(?<trigger>@)(?<id>\d+)>/g,
renderPosition: 'bottom',
},
];
const values = parseValue(value, partTypes);
console.log(values.parts.filter((part) => part.data?.trigger === '@').map((part) => part.data?.id));
This lib can also be used for formatting. It doesn't provide any pre-defined formatting but you can do it with regex. Here's a simple demo to achive simple markdown support
import { useState, useRef, useEffect } from 'react';
import { Pressable, Text, View } from 'react-native';
import { Input } from 'react-native-headless-mention';
export default function Campaigns() {
const [value, setValue] = useState('');
return (
<Input
onChange={setValue}
partTypes={[
{
textStyle: { fontWeight: '700' },
pattern: /\*\*(?<text>\S(?:.*?\S)?)\*\*/g,
},
{
textStyle: { textDecorationLine: 'underline' },
pattern: /__(?<text>\S(?:.*?\S)?)__/g,
},
{
textStyle: { fontStyle: 'italic' },
pattern: /\*(?<text>\S(?:.*?\S)?)\*/g,
},
{
textStyle: { fontStyle: 'italic' },
pattern: /_(?<text>\S(?:.*?\S)?)_/g,
},
{
textStyle: { textDecorationLine: 'line-through' },
pattern: /~(?<text>\S(?:.*?\S)?)~/g,
},
]}
value={value}
/>
);
}
If you want to support me by donating, you can do so by using any of the following methods. Thank you very much in advance!
Thanks goes to these wonderful people: