Merge pull request #19 from iulia-b/main
Introduce dismiss event for text-expander-element
This commit is contained in:
Коммит
013352b711
|
@ -21,10 +21,10 @@ export default function query(
|
|||
const keyIndex = text.lastIndexOf(key, cursor - 1)
|
||||
if (keyIndex === -1) return
|
||||
|
||||
if (multiWord) {
|
||||
// Stop matching at the lookBackIndex
|
||||
if (keyIndex < lookBackIndex) return
|
||||
// Stop matching at the lookBackIndex
|
||||
if (keyIndex < lookBackIndex) return
|
||||
|
||||
if (multiWord) {
|
||||
// Space immediately after activation key
|
||||
const charAfterKey = text[keyIndex + 1]
|
||||
if (charAfterKey === ' ') return
|
||||
|
|
|
@ -64,7 +64,13 @@ class TextExpander {
|
|||
this.input.removeEventListener('blur', this.onblur)
|
||||
}
|
||||
|
||||
activate(match: Match, menu: HTMLElement) {
|
||||
dismissMenu() {
|
||||
if (this.deactivate()) {
|
||||
this.lookBackIndex = this.input.selectionEnd || this.lookBackIndex
|
||||
}
|
||||
}
|
||||
|
||||
private activate(match: Match, menu: HTMLElement) {
|
||||
if (this.input !== document.activeElement) return
|
||||
|
||||
this.deactivate()
|
||||
|
@ -86,19 +92,22 @@ class TextExpander {
|
|||
this.combobox.navigate(1)
|
||||
}
|
||||
|
||||
deactivate() {
|
||||
private deactivate() {
|
||||
const menu = this.menu
|
||||
if (!menu || !this.combobox) return
|
||||
if (!menu || !this.combobox) return false
|
||||
this.menu = null
|
||||
|
||||
menu.removeEventListener('combobox-commit', this.oncommit)
|
||||
menu.removeEventListener('mousedown', this.onmousedown)
|
||||
|
||||
this.combobox.destroy()
|
||||
this.combobox = null
|
||||
menu.remove()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
onCommit({target}: Event) {
|
||||
private onCommit({target}: Event) {
|
||||
const item = target
|
||||
if (!(item instanceof HTMLElement)) return
|
||||
if (!this.combobox) return
|
||||
|
@ -118,17 +127,17 @@ class TextExpander {
|
|||
|
||||
this.input.value = beginning + value + remaining
|
||||
|
||||
const cursor = beginning.length + value.length
|
||||
|
||||
this.deactivate()
|
||||
this.input.focus()
|
||||
|
||||
const cursor = beginning.length + value.length
|
||||
this.input.selectionStart = cursor
|
||||
this.input.selectionEnd = cursor
|
||||
|
||||
this.lookBackIndex = cursor
|
||||
}
|
||||
|
||||
onBlur() {
|
||||
private onBlur() {
|
||||
if (this.interactingWithList) {
|
||||
this.interactingWithList = false
|
||||
return
|
||||
|
@ -137,7 +146,7 @@ class TextExpander {
|
|||
this.deactivate()
|
||||
}
|
||||
|
||||
onPaste() {
|
||||
private onPaste() {
|
||||
this.justPasted = true
|
||||
}
|
||||
|
||||
|
@ -193,19 +202,20 @@ class TextExpander {
|
|||
return fragments[0]
|
||||
}
|
||||
|
||||
onMousedown() {
|
||||
private onMousedown() {
|
||||
this.interactingWithList = true
|
||||
}
|
||||
|
||||
onKeydown(event: KeyboardEvent) {
|
||||
if (event.key === 'Escape' && (this.menu || this.combobox)) {
|
||||
this.deactivate()
|
||||
event.stopImmediatePropagation()
|
||||
event.preventDefault()
|
||||
private onKeydown(event: KeyboardEvent) {
|
||||
if (event.key === 'Escape') {
|
||||
if (this.deactivate()) {
|
||||
this.lookBackIndex = this.input.selectionEnd || this.lookBackIndex
|
||||
event.stopImmediatePropagation()
|
||||
event.preventDefault()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default class TextExpanderElement extends HTMLElement {
|
||||
get keys(): Key[] {
|
||||
const keysAttr = this.getAttribute('keys')
|
||||
|
@ -226,9 +236,15 @@ export default class TextExpanderElement extends HTMLElement {
|
|||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
const state = states.get(this)
|
||||
const state: TextExpander = states.get(this)
|
||||
if (!state) return
|
||||
state.destroy()
|
||||
states.delete(this)
|
||||
}
|
||||
|
||||
dismiss() {
|
||||
const state: TextExpander = states.get(this)
|
||||
if (!state) return
|
||||
state.dismissMenu()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,27 @@ describe('text-expander element', function() {
|
|||
const {key} = event.detail
|
||||
assert.equal(':', key)
|
||||
})
|
||||
|
||||
it('dismisses the menu when dismiss() is called', async function() {
|
||||
const expander = document.querySelector('text-expander')
|
||||
const input = expander.querySelector('textarea')
|
||||
const menu = document.createElement('ul')
|
||||
menu.appendChild(document.createElement('li'))
|
||||
|
||||
expander.addEventListener('text-expander-change', event => {
|
||||
const {provide} = event.detail
|
||||
provide(Promise.resolve({matched: true, fragment: menu}))
|
||||
})
|
||||
|
||||
input.focus()
|
||||
triggerInput(input, ':')
|
||||
await waitForAnimationFrame()
|
||||
assert.exists(expander.querySelector('ul'))
|
||||
|
||||
expander.dismiss()
|
||||
await waitForAnimationFrame()
|
||||
assert.isNull(expander.querySelector('ul'))
|
||||
})
|
||||
})
|
||||
|
||||
describe('multi-word scenarios', function() {
|
||||
|
@ -120,3 +141,9 @@ function triggerInput(input, value) {
|
|||
input.value = value
|
||||
return input.dispatchEvent(new InputEvent('input'))
|
||||
}
|
||||
|
||||
async function waitForAnimationFrame() {
|
||||
return new Promise(resolve => {
|
||||
window.requestAnimationFrame(resolve)
|
||||
})
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче