diff --git a/src/text-expander-element.ts b/src/text-expander-element.ts index e0fc1bb..f0c57ce 100644 --- a/src/text-expander-element.ts +++ b/src/text-expander-element.ts @@ -71,7 +71,9 @@ class TextExpander { } private activate(match: Match, menu: HTMLElement) { - if (this.input !== document.activeElement) return + if (this.input !== document.activeElement && this.input !== document.activeElement?.shadowRoot?.activeElement) { + return + } this.deactivate() this.menu = menu diff --git a/test/WrapperComponent.js b/test/WrapperComponent.js new file mode 100644 index 0000000..789f34c --- /dev/null +++ b/test/WrapperComponent.js @@ -0,0 +1,27 @@ +export class WrapperComponent extends HTMLElement { + constructor() { + super() + const shadow = this.attachShadow({mode: 'open'}) + const textExpander = document.createElement('text-expander') + textExpander.setAttribute('keys', '@') + const textarea = document.createElement('textarea') + textExpander.append(textarea) + shadow.appendChild(textExpander) + } + + connectedCallback() { + const textExpander = this.shadowRoot.querySelector('text-expander') + textExpander.addEventListener('text-expander-change', function (event) { + const {key, provide} = event.detail + + if (key !== '@') return + + const suggestions = document.createElement('ul') + suggestions.innerHTML = ` +
  • a
  • +
  • aa
  • + ` + provide(Promise.resolve({matched: true, fragment: suggestions})) + }) + } +} diff --git a/test/text-expander-element-test.js b/test/text-expander-element-test.js index 1f5082f..ac020d8 100644 --- a/test/text-expander-element-test.js +++ b/test/text-expander-element-test.js @@ -1,3 +1,5 @@ +import {WrapperComponent} from './WrapperComponent' + describe('text-expander element', function () { describe('element creation', function () { it('creates from document.createElement', function () { @@ -204,6 +206,31 @@ describe('text-expander element', function () { assert.equal('step 1 #step 2 #step 3', text) }) }) + + describe('use inside a ShadowDOM', function () { + before(function () { + customElements.define('wrapper-component', WrapperComponent) + }) + + beforeEach(function () { + const container = document.createElement('div') + container.innerHTML = '' + document.body.append(container) + }) + + afterEach(function () { + document.body.innerHTML = '' + }) + + it('show results on input', async function () { + const component = document.querySelector('wrapper-component') + const input = component.shadowRoot.querySelector('textarea') + input.focus() + triggerInput(input, '@a') + await waitForAnimationFrame() + assert.exists(component.shadowRoot.querySelector('ul')) + }) + }) }) function once(element, eventName) {