Skip to content

Commit

Permalink
Merge pull request #57 from github/fix-positioning-error
Browse files Browse the repository at this point in the history
Fix positioning error
  • Loading branch information
iansan5653 authored May 28, 2024
2 parents c0fc9fc + 1be094c commit fc7f9b6
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 33 deletions.
12 changes: 10 additions & 2 deletions examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@
<meta charset="utf-8" />
<title>text-expander demo</title>
<style>
[aria-selected='true'] {
background: #eee;
.menu {
position: absolute;
list-style-type: none;
padding: 0;
background: lightgray;

[aria-selected='true'] {
background: #eee;
}
}
</style>
</head>
Expand All @@ -30,6 +37,7 @@ <h2>Multiword text-expander element</h2>
const {key, provide, text} = event.detail
if (key === '#') {
const menu = document.createElement('ul')
menu.classList.add('menu')
menu.role = 'listbox'
for (const issue of [
'#1 Implement a text-expander element',
Expand Down
53 changes: 22 additions & 31 deletions src/text-expander-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,6 @@ type Key = {

const states = new WeakMap()

function isTopLayer(el: Element) {
try {
if (el.matches(':popover-open')) return true
} catch {
/* fall through */
}
try {
if (el.matches('dialog:modal')) return true
} catch {
/* fall through */
}
try {
if (el.matches(':fullscreen')) return true
} catch {
/* fall through */
}
return false
}

class TextExpander {
expander: TextExpanderElement
input: HTMLInputElement | HTMLTextAreaElement
Expand Down Expand Up @@ -103,18 +84,7 @@ class TextExpander {

this.expander.dispatchEvent(new Event('text-expander-activate'))

let {top, left} = new InputRange(this.input, match.position).getBoundingClientRect()
if (isTopLayer(menu)) {
const rect = this.input.getBoundingClientRect()
top += rect.top
left += rect.left
if (getComputedStyle(menu).position === 'absolute') {
top += window.scrollY
left += window.scrollX
}
}
menu.style.top = `${top}px`
menu.style.left = `${left}px`
this.positionMenu(menu, match.position)

this.combobox.start()
menu.addEventListener('combobox-commit', this.oncommit)
Expand All @@ -124,6 +94,27 @@ class TextExpander {
this.combobox.navigate(1)
}

private positionMenu(menu: HTMLElement, position: number) {
const caretRect = new InputRange(this.input, position).getBoundingClientRect()
const targetPosition = {left: caretRect.left, top: caretRect.top + caretRect.height}

const currentPosition = menu.getBoundingClientRect()

const delta = {
left: targetPosition.left - currentPosition.left,
top: targetPosition.top - currentPosition.top
}

if (delta.left !== 0 || delta.top !== 0) {
// Use computedStyle to avoid nesting calc() deeper and deeper
const currentStyle = getComputedStyle(menu)

// Using `calc` avoids having to parse the current pixel value
menu.style.left = currentStyle.left ? `calc(${currentStyle.left} + ${delta.left}px)` : `${delta.left}px`
menu.style.top = currentStyle.top ? `calc(${currentStyle.top} + ${delta.top}px)` : `${delta.top}px`
}
}

private deactivate() {
const menu = this.menu
if (!menu || !this.combobox) return false
Expand Down

0 comments on commit fc7f9b6

Please sign in to comment.