Skip to content

Commit 013352b

Browse files
authored
Merge pull request #19 from iulia-b/main
Introduce dismiss event for text-expander-element
2 parents 760da4a + 91eec2b commit 013352b

File tree

3 files changed

+62
-19
lines changed

3 files changed

+62
-19
lines changed

src/query.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ export default function query(
2121
const keyIndex = text.lastIndexOf(key, cursor - 1)
2222
if (keyIndex === -1) return
2323

24-
if (multiWord) {
25-
// Stop matching at the lookBackIndex
26-
if (keyIndex < lookBackIndex) return
24+
// Stop matching at the lookBackIndex
25+
if (keyIndex < lookBackIndex) return
2726

27+
if (multiWord) {
2828
// Space immediately after activation key
2929
const charAfterKey = text[keyIndex + 1]
3030
if (charAfterKey === ' ') return

src/text-expander-element.ts

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,13 @@ class TextExpander {
6464
this.input.removeEventListener('blur', this.onblur)
6565
}
6666

67-
activate(match: Match, menu: HTMLElement) {
67+
dismissMenu() {
68+
if (this.deactivate()) {
69+
this.lookBackIndex = this.input.selectionEnd || this.lookBackIndex
70+
}
71+
}
72+
73+
private activate(match: Match, menu: HTMLElement) {
6874
if (this.input !== document.activeElement) return
6975

7076
this.deactivate()
@@ -86,19 +92,22 @@ class TextExpander {
8692
this.combobox.navigate(1)
8793
}
8894

89-
deactivate() {
95+
private deactivate() {
9096
const menu = this.menu
91-
if (!menu || !this.combobox) return
97+
if (!menu || !this.combobox) return false
9298
this.menu = null
9399

94100
menu.removeEventListener('combobox-commit', this.oncommit)
95101
menu.removeEventListener('mousedown', this.onmousedown)
102+
96103
this.combobox.destroy()
97104
this.combobox = null
98105
menu.remove()
106+
107+
return true
99108
}
100109

101-
onCommit({target}: Event) {
110+
private onCommit({target}: Event) {
102111
const item = target
103112
if (!(item instanceof HTMLElement)) return
104113
if (!this.combobox) return
@@ -118,17 +127,17 @@ class TextExpander {
118127

119128
this.input.value = beginning + value + remaining
120129

130+
const cursor = beginning.length + value.length
131+
121132
this.deactivate()
122133
this.input.focus()
123134

124-
const cursor = beginning.length + value.length
125135
this.input.selectionStart = cursor
126136
this.input.selectionEnd = cursor
127-
128137
this.lookBackIndex = cursor
129138
}
130139

131-
onBlur() {
140+
private onBlur() {
132141
if (this.interactingWithList) {
133142
this.interactingWithList = false
134143
return
@@ -137,7 +146,7 @@ class TextExpander {
137146
this.deactivate()
138147
}
139148

140-
onPaste() {
149+
private onPaste() {
141150
this.justPasted = true
142151
}
143152

@@ -193,19 +202,20 @@ class TextExpander {
193202
return fragments[0]
194203
}
195204

196-
onMousedown() {
205+
private onMousedown() {
197206
this.interactingWithList = true
198207
}
199208

200-
onKeydown(event: KeyboardEvent) {
201-
if (event.key === 'Escape' && (this.menu || this.combobox)) {
202-
this.deactivate()
203-
event.stopImmediatePropagation()
204-
event.preventDefault()
209+
private onKeydown(event: KeyboardEvent) {
210+
if (event.key === 'Escape') {
211+
if (this.deactivate()) {
212+
this.lookBackIndex = this.input.selectionEnd || this.lookBackIndex
213+
event.stopImmediatePropagation()
214+
event.preventDefault()
215+
}
205216
}
206217
}
207218
}
208-
209219
export default class TextExpanderElement extends HTMLElement {
210220
get keys(): Key[] {
211221
const keysAttr = this.getAttribute('keys')
@@ -226,9 +236,15 @@ export default class TextExpanderElement extends HTMLElement {
226236
}
227237

228238
disconnectedCallback() {
229-
const state = states.get(this)
239+
const state: TextExpander = states.get(this)
230240
if (!state) return
231241
state.destroy()
232242
states.delete(this)
233243
}
244+
245+
dismiss() {
246+
const state: TextExpander = states.get(this)
247+
if (!state) return
248+
state.dismissMenu()
249+
}
234250
}

test/text-expander-element-test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,27 @@ describe('text-expander element', function() {
4747
const {key} = event.detail
4848
assert.equal(':', key)
4949
})
50+
51+
it('dismisses the menu when dismiss() is called', async function() {
52+
const expander = document.querySelector('text-expander')
53+
const input = expander.querySelector('textarea')
54+
const menu = document.createElement('ul')
55+
menu.appendChild(document.createElement('li'))
56+
57+
expander.addEventListener('text-expander-change', event => {
58+
const {provide} = event.detail
59+
provide(Promise.resolve({matched: true, fragment: menu}))
60+
})
61+
62+
input.focus()
63+
triggerInput(input, ':')
64+
await waitForAnimationFrame()
65+
assert.exists(expander.querySelector('ul'))
66+
67+
expander.dismiss()
68+
await waitForAnimationFrame()
69+
assert.isNull(expander.querySelector('ul'))
70+
})
5071
})
5172

5273
describe('multi-word scenarios', function() {
@@ -120,3 +141,9 @@ function triggerInput(input, value) {
120141
input.value = value
121142
return input.dispatchEvent(new InputEvent('input'))
122143
}
144+
145+
async function waitForAnimationFrame() {
146+
return new Promise(resolve => {
147+
window.requestAnimationFrame(resolve)
148+
})
149+
}

0 commit comments

Comments
 (0)