Skip to content

Commit

Permalink
Feat--more-popover-positions (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
rossrobino authored Aug 28, 2023
1 parent 4eb8069 commit eef92ad
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 15 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "drab",
"version": "3.0.2",
"version": "3.0.3",
"description": "An Unstyled Svelte Component Library",
"keywords": [
"components",
Expand Down
57 changes: 45 additions & 12 deletions src/lib/components/Popover.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Displays a popover in relation to the `target`.
- `class`
- `display` - shows / hides the popover
- `id`
- `position` - where the popover is displayed in relation to the `target`
- `position` - where the popover is displayed in relation to the `target`, ex: `br` is bottom, right aligned
- `target` - target element to position the popover in relation to
- `transition` - scales the popover, set to `false` to disable
Expand Down Expand Up @@ -66,8 +66,22 @@ Displays a popover in relation to the `target`.
/** shows / hides the popover */
export let display = true;
/** where the popover is displayed in relation to the `target` */
export let position: "t" | "b" | "l" | "r" = "b";
type Position =
| "tl"
| "t"
| "tr"
| "rt"
| "r"
| "rb"
| "br"
| "b"
| "bl"
| "lb"
| "l"
| "lt";
/** where the popover is displayed in relation to the `target`, ex: `br` is bottom, right aligned */
export let position: Position = "b";
/** target element to position the popover in relation to */
export let target: HTMLElement;
Expand All @@ -80,39 +94,57 @@ Displays a popover in relation to the `target`.
let coordinates: { x: number; y: number } = { x: 0, y: 0 };
const setPosition = async () => {
if (position === "t" || position === "b") {
coordinates.x = target.offsetWidth / 2 - popover.offsetWidth / 2;
if (position === "t") {
if (position.startsWith("t") || position.startsWith("b")) {
if (position.startsWith("t")) {
coordinates.y = -popover.offsetHeight;
} else {
coordinates.y = target.offsetHeight;
}
if (position.endsWith("l")) {
coordinates.x = 0;
} else if (position.endsWith("r")) {
coordinates.x = target.offsetWidth - popover.offsetWidth;
} else {
coordinates.x = target.offsetWidth / 2 - popover.offsetWidth / 2;
}
} else {
coordinates.y = target.offsetHeight / 2 - popover.offsetHeight / 2;
if (position === "l") {
if (position.startsWith("l")) {
coordinates.x = -popover.offsetWidth;
} else {
coordinates.x = target.offsetWidth;
}
if (position.endsWith("t")) {
coordinates.y = 0;
} else if (position.endsWith("b")) {
coordinates.y = target.offsetHeight - popover.offsetHeight;
} else {
coordinates.y = target.offsetHeight / 2 - popover.offsetHeight / 2;
}
}
const targetRect = target.getBoundingClientRect();
// add the position of the `target` and scroll
coordinates.x += targetRect.x + window.scrollX;
coordinates.y += targetRect.y + window.scrollY;
await tick();
const popoverRect = popover.getBoundingClientRect();
const extraMargin = 10;
// correct position if not visible
if (popoverRect.x < 0) {
coordinates.x += Math.abs(popoverRect.x);
if (popoverRect.x < extraMargin) {
coordinates.x += Math.abs(popoverRect.x) + extraMargin;
} else if (popoverRect.x + popover.offsetWidth > window.innerWidth) {
coordinates.x -=
popoverRect.x + popover.offsetWidth - window.innerWidth + 16;
popoverRect.x + popover.offsetWidth - window.innerWidth + extraMargin;
}
if (popoverRect.y < 0) {
coordinates.y += Math.abs(popoverRect.y);
coordinates.y += Math.abs(popoverRect.y) + extraMargin;
} else if (popoverRect.y + popover.offsetHeight > window.innerHeight) {
coordinates.y -=
popoverRect.y + popover.offsetHeight - window.innerHeight;
Expand Down Expand Up @@ -151,5 +183,6 @@ Displays a popover in relation to the `target`.
<style>
div {
position: absolute;
margin: 0;
}
</style>

1 comment on commit eef92ad

@vercel
Copy link

@vercel vercel bot commented on eef92ad Aug 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.