mirror of https://github.com/msgbyte/tailchat
feat: 文本输入框增加了mention功能
parent
a911fecad4
commit
9ff4f8858f
File diff suppressed because it is too large
Load Diff
@ -1,2 +1 @@
|
|||||||
# https://npm.taobao.org/mirrors/
|
registry = https://registry.npmmirror.com
|
||||||
registry = https://registry.npm.taobao.org
|
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
import React, { useContext } from 'react';
|
|
||||||
|
|
||||||
export interface ChatInputActionContextProps {
|
|
||||||
sendMsg: (message: string) => void;
|
|
||||||
}
|
|
||||||
export const ChatInputActionContext =
|
|
||||||
React.createContext<ChatInputActionContextProps | null>(null);
|
|
||||||
ChatInputActionContext.displayName = 'ChatInputContext';
|
|
||||||
|
|
||||||
export function useChatInputActionContext() {
|
|
||||||
return useContext(ChatInputActionContext);
|
|
||||||
}
|
|
@ -0,0 +1,45 @@
|
|||||||
|
import React, { useContext } from 'react';
|
||||||
|
import type { SuggestionDataItem } from 'react-mentions';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Input Actions
|
||||||
|
*/
|
||||||
|
export interface ChatInputActionContextProps {
|
||||||
|
sendMsg: (message: string) => void;
|
||||||
|
}
|
||||||
|
export const ChatInputActionContext =
|
||||||
|
React.createContext<ChatInputActionContextProps | null>(null);
|
||||||
|
ChatInputActionContext.displayName = 'ChatInputContext';
|
||||||
|
|
||||||
|
export function useChatInputActionContext() {
|
||||||
|
return useContext(ChatInputActionContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Input Mentions
|
||||||
|
*/
|
||||||
|
interface ChatInputMentionsContextProps {
|
||||||
|
users: SuggestionDataItem[];
|
||||||
|
}
|
||||||
|
const ChatInputMentionsContext =
|
||||||
|
React.createContext<ChatInputMentionsContextProps | null>(null);
|
||||||
|
ChatInputMentionsContext.displayName = 'ChatInputMentionsContext';
|
||||||
|
|
||||||
|
export const ChatInputMentionsContextProvider: React.FC<ChatInputMentionsContextProps> =
|
||||||
|
React.memo((props) => {
|
||||||
|
return (
|
||||||
|
<ChatInputMentionsContext.Provider value={{ users: props.users }}>
|
||||||
|
{props.children}
|
||||||
|
</ChatInputMentionsContext.Provider>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
ChatInputMentionsContextProvider.displayName =
|
||||||
|
'ChatInputMentionsContextProvider';
|
||||||
|
|
||||||
|
export function useChatInputMentionsContext(): ChatInputMentionsContextProps {
|
||||||
|
const context = useContext(ChatInputMentionsContext);
|
||||||
|
|
||||||
|
return {
|
||||||
|
users: context?.users ?? [],
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
.chatbox-mention-input {
|
||||||
|
@apply shadow-none border-0 px-4 py-2 flex-1;
|
||||||
|
|
||||||
|
&__control {
|
||||||
|
@apply relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__input {
|
||||||
|
@apply outline-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__suggestions {
|
||||||
|
@apply bg-transparent !important;
|
||||||
|
|
||||||
|
&__list {
|
||||||
|
@apply border border-gray-500 bg-content-light dark:bg-content-dark rounded;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
@apply rounded;
|
||||||
|
|
||||||
|
&--focused {
|
||||||
|
@apply bg-black bg-opacity-20 dark:bg-white dark:bg-opacity-20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
import { UserListItem } from '@/components/UserListItem';
|
||||||
|
import { getMessageTextDecorators } from '@/plugin/common';
|
||||||
|
import React from 'react';
|
||||||
|
import { Mention, MentionsInput } from 'react-mentions';
|
||||||
|
import { t } from 'tailchat-shared';
|
||||||
|
import { useChatInputMentionsContext } from './context';
|
||||||
|
|
||||||
|
import './input.less';
|
||||||
|
|
||||||
|
interface ChatInputBoxInputProps
|
||||||
|
extends Omit<
|
||||||
|
React.InputHTMLAttributes<HTMLInputElement | HTMLTextAreaElement>,
|
||||||
|
'value' | 'onChange'
|
||||||
|
> {
|
||||||
|
inputRef?: React.Ref<HTMLInputElement>;
|
||||||
|
value: string;
|
||||||
|
onChange: (message: string) => void;
|
||||||
|
}
|
||||||
|
export const ChatInputBoxInput: React.FC<ChatInputBoxInputProps> = React.memo(
|
||||||
|
(props) => {
|
||||||
|
const mentions = useChatInputMentionsContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MentionsInput
|
||||||
|
inputRef={props.inputRef}
|
||||||
|
className="chatbox-mention-input"
|
||||||
|
placeholder={t('输入一些什么')}
|
||||||
|
singleLine={true}
|
||||||
|
value={props.value}
|
||||||
|
onChange={(e) => props.onChange(e.target.value)}
|
||||||
|
onKeyDown={props.onKeyDown}
|
||||||
|
onPaste={props.onPaste}
|
||||||
|
allowSuggestionsAboveCursor={true}
|
||||||
|
forceSuggestionsAboveCursor={true}
|
||||||
|
>
|
||||||
|
<Mention
|
||||||
|
trigger="@"
|
||||||
|
data={mentions.users}
|
||||||
|
displayTransform={(id, display) => `@${display}`}
|
||||||
|
appendSpaceOnAdd={true}
|
||||||
|
renderSuggestion={(suggestion) => (
|
||||||
|
<UserListItem userId={String(suggestion.id)} />
|
||||||
|
)}
|
||||||
|
markup={getMessageTextDecorators().mention('__id__', '__display__')}
|
||||||
|
/>
|
||||||
|
</MentionsInput>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
ChatInputBoxInput.displayName = 'ChatInputBoxInput';
|
Loading…
Reference in New Issue