Merge pull request #920 from basecamp/popup-orientation

Popup orientation
This commit is contained in:
Andy Smith
2025-08-18 12:50:53 -05:00
committed by GitHub
3 changed files with 39 additions and 0 deletions
+10
View File
@@ -17,6 +17,16 @@
display: flex;
}
&.orient-left {
inset-inline: auto 0;
transform: translateX(0);
}
&.orient-right {
inset-inline: 0 auto;
transform: translateX(0);
}
&:has(.popup__footer) {
--panel-padding: var(--block-space) var(--block-space) 0 var(--block-space);
}
@@ -1,4 +1,5 @@
import { Controller } from "@hotwired/stimulus"
import { orient } from "helpers/orientation_helpers"
export default class extends Controller {
static targets = [ "dialog" ]
@@ -17,7 +18,9 @@ export default class extends Controller {
this.dialogTarget.showModal()
} else {
this.dialogTarget.show()
orient(this.dialogTarget)
}
this.dialogTarget.setAttribute('aria-hidden', 'false')
this.dispatch("show")
}
@@ -34,6 +37,7 @@ export default class extends Controller {
this.dialogTarget.close()
this.dialogTarget.setAttribute('aria-hidden', 'true')
this.dialogTarget.blur()
orient(this.dialogTarget, false)
}
closeOnClickOutside({ target }) {
@@ -0,0 +1,25 @@
const EDGE_THRESHOLD = 16
export function orient(el, orient = true) {
const directions = [
["orient-left", spaceOnRight],
["orient-right", spaceOnLeft],
["orient-top", spaceOnBottom]
];
directions.forEach(([className, fn]) =>
el.classList[orient && fn(el) < EDGE_THRESHOLD ? "add" : "remove"](className)
);
}
function spaceOnLeft(el) {
return el.getBoundingClientRect().left
}
function spaceOnRight(el) {
return window.innerWidth - el.getBoundingClientRect().right
}
function spaceOnBottom(el) {
return window.innerHeight - el.getBoundingClientRect().bottom
}