Description
A headless mention component for React Native. It's a headless component, so you'll need to provide your styles and suggestions renderer.
Features
- Written In Typescript
- Offers CJS, and ESM builds
- Full TypeScript & JavaScript support
Install
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
Usage
For mention with autocomplete
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
andid
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.
Get mentions from 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));
For formatting
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}
/>
);
}
Buy me some doughnuts
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!
Contributors ✨
Thanks goes to these wonderful people: