Skip to content
Open
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"npmClient": "yarn",
"useWorkspaces": true,
"version": "2.0.0-alpha.3",
"version": "2.0.0-alpha.4",
"packages": [
"packages/*"
]
Expand Down
2 changes: 1 addition & 1 deletion packages/docs/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
4 changes: 2 additions & 2 deletions packages/test-e2e/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand All @@ -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": {
Expand Down
4 changes: 4 additions & 0 deletions packages/test-e2e/src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
50 changes: 50 additions & 0 deletions packages/test-e2e/src/views/AllowSpace.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<script>
export default {
data () {
return {
text: '',
items: [
{
value: 'akryum',
firstName: 'Guillaume',
},
{
value: 'posva',
firstName: 'Eduardo',
},
{
value: 'space invader',
firstName: 'Space Invader',
},
],
}
},
}
</script>

<template>
<div
class="demo"
>
<Mentionable
:keys="['@']"
:items="items"
allow-space
popper-class="defaults-mention"
>
<textarea
v-model="text"
rows="6"
class="input"
/>
</Mentionable>

<div class="preview">{{ text }}</div>
</div>
</template>

<style>
.defaults-mention .mention-selected {
background: #aaffc7;
}
</style>
22 changes: 22 additions & 0 deletions packages/test-e2e/tests/e2e/specs/allow-space.js
Original file line number Diff line number Diff line change
@@ -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')
})
})
20 changes: 18 additions & 2 deletions packages/vue-mention/src/Mentionable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -76,7 +81,7 @@ export default defineComponent({
const currentKey = ref<string>(null)
let currentKeyIndex: number
const oldKey = ref<string>(null)

const isMentioning = ref<boolean>(false)
// Items

const searchText = ref<string>(null)
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -323,13 +336,15 @@ export default defineComponent({
updateCaretPosition()
selectedIndex.value = 0
emit('open', currentKey.value)
isMentioning.value = true
}
}

function closeMenu () {
if (currentKey.value != null) {
oldKey.value = currentKey.value
currentKey.value = null
isMentioning.value = false
emit('close', oldKey.value)
}
}
Expand Down Expand Up @@ -362,6 +377,7 @@ export default defineComponent({
el,
currentKey,
oldKey,
isMentioning,
caretPosition,
displayedItems,
selectedIndex,
Expand Down