Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking β€œSign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(rich-text-editor): DLT-2017 emojis positioning #486

Merged
merged 5 commits into from
Sep 5, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 23 additions & 23 deletions package.json
Original file line number Diff line number Diff line change
@@ -107,27 +107,27 @@
"@dialpad/dialtone-emojis": "workspace:*",
"@dialpad/dialtone-icons": "workspace:*",
"@dialpad/dialtone-tokens": "workspace:*",
"@tiptap/core": "2.3.0",
"@tiptap/extension-blockquote": "2.3.0",
"@tiptap/extension-bold": "2.3.0",
"@tiptap/extension-bullet-list": "2.3.0",
"@tiptap/extension-code-block": "2.3.0",
"@tiptap/extension-document": "2.3.0",
"@tiptap/extension-hard-break": "2.3.0",
"@tiptap/extension-history": "2.3.0",
"@tiptap/extension-italic": "2.3.0",
"@tiptap/extension-link": "2.3.0",
"@tiptap/extension-list-item": "2.3.0",
"@tiptap/extension-mention": "2.3.0",
"@tiptap/extension-ordered-list": "2.3.0",
"@tiptap/extension-paragraph": "2.3.0",
"@tiptap/extension-placeholder": "2.3.0",
"@tiptap/extension-strike": "2.3.0",
"@tiptap/extension-text": "2.3.0",
"@tiptap/extension-text-align": "2.3.0",
"@tiptap/extension-underline": "2.3.0",
"@tiptap/pm": "2.3.0",
"@tiptap/suggestion": "2.3.0",
"@tiptap/core": "^2.6.6",
"@tiptap/extension-blockquote": "^2.6.6",
"@tiptap/extension-bold": "^2.6.6",
"@tiptap/extension-bullet-list": "^2.6.6",
"@tiptap/extension-code-block": "^2.6.6",
"@tiptap/extension-document": "^2.6.6",
"@tiptap/extension-hard-break": "^2.6.6",
"@tiptap/extension-history": "^2.6.6",
"@tiptap/extension-italic": "^2.6.6",
"@tiptap/extension-link": "^2.6.6",
"@tiptap/extension-list-item": "^2.6.6",
"@tiptap/extension-mention": "^2.6.6",
"@tiptap/extension-ordered-list": "^2.6.6",
"@tiptap/extension-paragraph": "^2.6.6",
"@tiptap/extension-placeholder": "^2.6.6",
"@tiptap/extension-strike": "^2.6.6",
"@tiptap/extension-text": "^2.6.6",
"@tiptap/extension-text-align": "^2.6.6",
"@tiptap/extension-underline": "^2.6.6",
"@tiptap/pm": "^2.6.6",
"@tiptap/suggestion": "^2.6.6",
"date-fns": "2.30.0",
"docopt": "0.6.2",
"emoji-toolkit": "8.0.0",
@@ -182,8 +182,8 @@
},
"peerDependencies": {
"@linusborg/vue-simple-portal": "0.1.5",
"@tiptap/vue-2": "2.3.0",
"@tiptap/vue-3": "2.3.0",
"@tiptap/vue-2": "^2.6.6",
"@tiptap/vue-3": "^2.6.6",
"vue": "^2 || ^3"
},
"peerDependenciesMeta": {
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { mergeAttributes, Node, nodeInputRule, nodePasteRule } from '@tiptap/core';
import { VueNodeViewRenderer } from '@tiptap/vue-2';
import EmojiComponent from './EmojiComponent.vue';
import { codeToEmojiData, emojiShortCodeRegex, emojiRegex, stringToUnicode } from '@/common/emoji';
import { InputRule, mergeAttributes, Node, nodePasteRule } from '@tiptap/core';
import { PluginKey } from '@tiptap/pm/state';

import { VueNodeViewRenderer } from '@tiptap/vue-2';
import Suggestion from '@tiptap/suggestion';
import suggestionOptions from './suggestion';
import { emojiPattern } from 'regex-combined-emojis';

export const EmojiPluginKey = new PluginKey('emoji');
import EmojiComponent from './EmojiComponent.vue';
import { codeToEmojiData, emojiShortCodeRegex, emojiRegex, stringToUnicode } from '@/common/emoji';
import suggestionOptions from './suggestion';

const inputShortCodeRegex = /(^| |(?<=:))(:\w+:)$/;
const inputShortCodeRegex = /(:\w+:)$/;
const inputUnicodeRegex = new RegExp(emojiPattern + '$');

const inputRuleMatch = (match) => {
@@ -19,11 +17,7 @@ const inputRuleMatch = (match) => {
// needs to be a dict returned
// ref type InputRuleMatch:
// https://github.com/ueberdosis/tiptap/blob/main/packages/core/src/InputRule.ts#L16
return {
index: match.index,
text,
match,
};
return { text };
}
};

@@ -40,19 +34,16 @@ const shortCodePasteMatch = (text) => {
};

export const Emoji = Node.create({
name: 'emoji',
addOptions () {
return {
HTMLAttributes: {},
suggestion: {
char: ':',
pluginKey: EmojiPluginKey,
},
};
},
name: 'emoji',
group: 'inline',
inline: true,
selectable: true,
selectable: false,
atom: true,

addNodeView () {
return VueNodeViewRenderer(EmojiComponent);
@@ -87,33 +78,18 @@ export const Emoji = Node.create({

addInputRules () {
return [
// shortcode input
nodeInputRule({
new InputRule({
find: (text) => {
const match = text.match(inputShortCodeRegex);
const match = text.match(inputShortCodeRegex) || text.match(inputUnicodeRegex);
if (!match) return;
return inputRuleMatch(match);
},
type: this.type,
getAttributes (attrs) {
return {
code: attrs[0],
};
},
}),

nodeInputRule({
find: (text) => {
const match = text.match(inputUnicodeRegex);
if (!match) return;
return inputRuleMatch(match);
},
type: this.type,
getAttributes (attrs) {
const emoji = codeToEmojiData(attrs[0]).shortname;
return {
code: emoji,
};
handler: ({ state, range, match, commands, chain, can }) => {
const { tr } = state;
const start = range.from;
const end = range.to;
tr.replaceWith(start, end, this.type.create({ code: match[0] }));
},
}),
];
@@ -145,10 +121,31 @@ export const Emoji = Node.create({
addProseMirrorPlugins () {
return [
Suggestion({
char: ':',
pluginKey: new PluginKey('emoji'),
editor: this.editor,
...this.options.suggestion,
...suggestionOptions,
}),
];
},

addKeyboardShortcuts () {
return {
Backspace: () => this.editor.commands.command(({ tr, state }) => {
let isEmoji = false;
const { selection } = state;
const { empty, anchor } = selection;
if (!empty) { return false; }
state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
if (node.type.name === this.name) {
isEmoji = true;
tr.insertText('', pos, pos + node.nodeSize);
return false;
}
});
return isEmoji;
}),
};
},
});
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Emoji } from './emoji';

export * from './emoji';

export default Emoji;
Original file line number Diff line number Diff line change
@@ -40,10 +40,6 @@ export default {
type: 'emoji',
attrs: props,
},
{
type: 'text',
text: ' ',
},
])
.run();

44 changes: 22 additions & 22 deletions packages/dialtone-vue2/package.json
Original file line number Diff line number Diff line change
@@ -31,28 +31,28 @@
"@dialpad/dialtone-emojis": "workspace:*",
"@dialpad/dialtone-icons": "workspace:*",
"@linusborg/vue-simple-portal": "0.1.5",
"@tiptap/core": "2.3.0",
"@tiptap/extension-blockquote": "2.3.0",
"@tiptap/extension-bold": "2.3.0",
"@tiptap/extension-bullet-list": "2.3.0",
"@tiptap/extension-code-block": "2.3.0",
"@tiptap/extension-document": "2.3.0",
"@tiptap/extension-hard-break": "2.3.0",
"@tiptap/extension-history": "2.3.0",
"@tiptap/extension-italic": "2.3.0",
"@tiptap/extension-link": "2.3.0",
"@tiptap/extension-list-item": "2.3.0",
"@tiptap/extension-mention": "2.3.0",
"@tiptap/extension-ordered-list": "2.3.0",
"@tiptap/extension-paragraph": "2.3.0",
"@tiptap/extension-placeholder": "2.3.0",
"@tiptap/extension-strike": "2.3.0",
"@tiptap/extension-text": "2.3.0",
"@tiptap/extension-text-align": "2.3.0",
"@tiptap/extension-underline": "2.3.0",
"@tiptap/pm": "2.3.0",
"@tiptap/suggestion": "2.3.0",
"@tiptap/vue-2": "2.3.0",
"@tiptap/core": "^2.6.6",
"@tiptap/extension-blockquote": "^2.6.6",
"@tiptap/extension-bold": "^2.6.6",
"@tiptap/extension-bullet-list": "^2.6.6",
"@tiptap/extension-code-block": "^2.6.6",
"@tiptap/extension-document": "^2.6.6",
"@tiptap/extension-hard-break": "^2.6.6",
"@tiptap/extension-history": "^2.6.6",
"@tiptap/extension-italic": "^2.6.6",
"@tiptap/extension-link": "^2.6.6",
"@tiptap/extension-list-item": "^2.6.6",
"@tiptap/extension-mention": "^2.6.6",
"@tiptap/extension-ordered-list": "^2.6.6",
"@tiptap/extension-paragraph": "^2.6.6",
"@tiptap/extension-placeholder": "^2.6.6",
"@tiptap/extension-strike": "^2.6.6",
"@tiptap/extension-text": "^2.6.6",
"@tiptap/extension-text-align": "^2.6.6",
"@tiptap/extension-underline": "^2.6.6",
"@tiptap/pm": "^2.6.6",
"@tiptap/suggestion": "^2.6.6",
"@tiptap/vue-2": "^2.6.6",
"date-fns": "2.30.0",
"emoji-toolkit": "8.0.0",
"overlayscrollbars": "2.10.0",
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import { mergeAttributes, Node, nodeInputRule, nodePasteRule } from '@tiptap/core';
import { VueNodeViewRenderer } from '@tiptap/vue-3';
import EmojiComponent from './EmojiComponent.vue';
import { codeToEmojiData, emojiShortCodeRegex, emojiRegex, stringToUnicode } from '@/common/emoji';
import { InputRule, mergeAttributes, Node, nodePasteRule } from '@tiptap/core';
import { PluginKey } from '@tiptap/pm/state';

import { VueNodeViewRenderer } from '@tiptap/vue-3';
import Suggestion from '@tiptap/suggestion';
import suggestionOptions from './suggestion';
import { emojiPattern } from 'regex-combined-emojis';

export const EmojiPluginKey = new PluginKey('emoji');
import EmojiComponent from './EmojiComponent.vue';
import { codeToEmojiData, emojiShortCodeRegex, emojiRegex, stringToUnicode } from '@/common/emoji';
import suggestionOptions from './suggestion';

const inputShortCodeRegex = /(^| |(?<=:))(:\w+:)$/;
const inputShortCodeRegex = /(:\w+:)$/;
const inputUnicodeRegex = new RegExp(emojiPattern + '$');

const inputRuleMatch = (match) => {
@@ -19,11 +17,7 @@ const inputRuleMatch = (match) => {
// needs to be a dict returned
// ref type InputRuleMatch:
// https://github.com/ueberdosis/tiptap/blob/main/packages/core/src/InputRule.ts#L16
return {
index: match.index,
text,
match,
};
return { text };
}
};

@@ -40,19 +34,16 @@ const shortCodePasteMatch = (text) => {
};

export const Emoji = Node.create({
name: 'emoji',
addOptions () {
return {
HTMLAttributes: {},
suggestion: {
char: ':',
pluginKey: EmojiPluginKey,
},
};
},
name: 'emoji',
group: 'inline',
inline: true,
selectable: true,
selectable: false,
atom: true,
braddialpad marked this conversation as resolved.
Show resolved Hide resolved

addNodeView () {
return VueNodeViewRenderer(EmojiComponent);
@@ -87,33 +78,18 @@ export const Emoji = Node.create({

addInputRules () {
return [
// shortcode input
nodeInputRule({
new InputRule({
find: (text) => {
const match = text.match(inputShortCodeRegex);
const match = text.match(inputShortCodeRegex) || text.match(inputUnicodeRegex);
if (!match) return;
return inputRuleMatch(match);
},
type: this.type,
getAttributes (attrs) {
return {
code: attrs[0],
};
},
}),

nodeInputRule({
find: (text) => {
const match = text.match(inputUnicodeRegex);
if (!match) return;
return inputRuleMatch(match);
},
type: this.type,
getAttributes (attrs) {
const emoji = codeToEmojiData(attrs[0]).shortname;
return {
code: emoji,
};
handler: ({ state, range, match, commands, chain, can }) => {
const { tr } = state;
const start = range.from;
const end = range.to;
tr.replaceWith(start, end, this.type.create({ code: match[0] }));
},
}),
];
@@ -145,10 +121,31 @@ export const Emoji = Node.create({
addProseMirrorPlugins () {
return [
Suggestion({
char: ':',
pluginKey: new PluginKey('emoji'),
editor: this.editor,
...this.options.suggestion,
...suggestionOptions,
}),
];
},

addKeyboardShortcuts () {
return {
Backspace: () => this.editor.commands.command(({ tr, state }) => {
let isEmoji = false;
const { selection } = state;
const { empty, anchor } = selection;
if (!empty) { return false; }
state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
if (node.type.name === this.name) {
isEmoji = true;
tr.insertText('', pos, pos + node.nodeSize);
return false;
}
});
return isEmoji;
}),
};
braddialpad marked this conversation as resolved.
Show resolved Hide resolved
},
});
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Emoji } from './emoji';

export * from './emoji';

export default Emoji;
Loading
Loading