diff --git a/lerna.json b/lerna.json
index 1dd5d3b..82d2718 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,7 +1,7 @@
{
"npmClient": "yarn",
"useWorkspaces": true,
- "version": "2.0.0-alpha.3",
+ "version": "2.0.0-alpha.4",
"packages": [
"packages/*"
]
diff --git a/packages/docs/package.json b/packages/docs/package.json
index b1852e8..5cfcea6 100644
--- a/packages/docs/package.json
+++ b/packages/docs/package.json
@@ -1,6 +1,6 @@
{
"name": "vue-mention-docs",
- "version": "0.1.7",
+ "version": "2.0.0-alpha.4",
"private": true,
"scripts": {
"dev": "vuepress dev src",
diff --git a/packages/test-e2e/package.json b/packages/test-e2e/package.json
index 0de3300..43eaa19 100644
--- a/packages/test-e2e/package.json
+++ b/packages/test-e2e/package.json
@@ -1,6 +1,6 @@
{
"name": "test-e2e",
- "version": "2.0.0-alpha.3",
+ "version": "2.0.0-alpha.4",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
@@ -13,7 +13,7 @@
"core-js": "^3.6.4",
"floating-vue": "^2.0.0-beta.1",
"vue": "^3.2.26",
- "vue-mention": "^2.0.0-alpha.1",
+ "vue-mention": "^2.0.0-alpha.4",
"vue-router": "^4.0.12"
},
"devDependencies": {
diff --git a/packages/test-e2e/src/router.js b/packages/test-e2e/src/router.js
index 2b8153c..d0d1e61 100644
--- a/packages/test-e2e/src/router.js
+++ b/packages/test-e2e/src/router.js
@@ -45,6 +45,10 @@ const routes = [
path: '/content-editable',
component: () => import('./views/ContentEditable.vue'),
},
+ {
+ path: '/allow-space',
+ component: () => import('./views/AllowSpace.vue'),
+ },
]
const router = createRouter({
diff --git a/packages/test-e2e/src/views/AllowSpace.vue b/packages/test-e2e/src/views/AllowSpace.vue
new file mode 100644
index 0000000..9a6efaf
--- /dev/null
+++ b/packages/test-e2e/src/views/AllowSpace.vue
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
diff --git a/packages/test-e2e/tests/e2e/specs/allow-space.js b/packages/test-e2e/tests/e2e/specs/allow-space.js
new file mode 100644
index 0000000..a918534
--- /dev/null
+++ b/packages/test-e2e/tests/e2e/specs/allow-space.js
@@ -0,0 +1,22 @@
+describe('with allow-space prop', () => {
+ it('shows suggestions after typing mention containing space', () => {
+ cy.visit('/allow-space')
+ cy.get('.input').type('abc @space in')
+ cy.get('.v-popper__popper').should('be.visible')
+ .should('contain', 'space invader')
+ cy.get('.input').type('{enter}')
+ cy.get('.preview').should('contain', '@space invader')
+ })
+
+ it.only('do not show suggestions when deleting applied mention', () => {
+ cy.visit('/allow-space')
+ cy.get('.input').type('abc @space in')
+ cy.get('.v-popper__popper').should('be.visible')
+ .should('contain', 'space invader')
+ cy.get('.input').type('{enter}')
+ cy.get('.input')
+ .type('{backspace}'.repeat(14))
+ cy.get('.v-popper__popper').should('not.be.visible')
+ cy.get('.preview').should('not.contain', '@space invader')
+ })
+})
diff --git a/packages/vue-mention/src/Mentionable.vue b/packages/vue-mention/src/Mentionable.vue
index 98ea7c8..be11727 100644
--- a/packages/vue-mention/src/Mentionable.vue
+++ b/packages/vue-mention/src/Mentionable.vue
@@ -49,6 +49,11 @@ export default defineComponent({
default: false,
},
+ allowSpace: {
+ type: Boolean,
+ default: false,
+ },
+
mapInsert: {
type: Function as PropType<(item: MentionItem, key: string) => string>,
default: null,
@@ -76,7 +81,7 @@ export default defineComponent({
const currentKey = ref(null)
let currentKeyIndex: number
const oldKey = ref(null)
-
+ const isMentioning = ref(false)
// Items
const searchText = ref(null)
@@ -256,10 +261,15 @@ export default defineComponent({
if (index >= 0) {
const { key, keyIndex } = getLastKeyBeforeCaret(index)
const text = lastSearchText = getLastSearchText(index, keyIndex)
+ // Makes sure that key is not first character in editable element and
+ // that there is a space before the key. Returns false if these conditions are
+ // not met
if (!(keyIndex < 1 || /\s/.test(getValue()[keyIndex - 1]))) {
return false
}
- if (text != null) {
+ const keyIsBeforeCaret = getValue()[index - 1] === key
+ const shouldOpen = props.allowSpace ? isMentioning.value || keyIsBeforeCaret : true
+ if (text != null && shouldOpen) {
openMenu(key, keyIndex)
searchText.value = text
return true
@@ -280,6 +290,9 @@ export default defineComponent({
function getLastSearchText (caretIndex: number, keyIndex: number) {
if (keyIndex !== -1) {
const text = getValue().substring(keyIndex + 1, caretIndex)
+ if (props.allowSpace) {
+ return text.trim()
+ }
// If there is a space we close the menu
if (!/\s/.test(text)) {
return text
@@ -323,6 +336,7 @@ export default defineComponent({
updateCaretPosition()
selectedIndex.value = 0
emit('open', currentKey.value)
+ isMentioning.value = true
}
}
@@ -330,6 +344,7 @@ export default defineComponent({
if (currentKey.value != null) {
oldKey.value = currentKey.value
currentKey.value = null
+ isMentioning.value = false
emit('close', oldKey.value)
}
}
@@ -362,6 +377,7 @@ export default defineComponent({
el,
currentKey,
oldKey,
+ isMentioning,
caretPosition,
displayedItems,
selectedIndex,