Skip to content

Commit

Permalink
Merge pull request #26 from mojabyte/master
Browse files Browse the repository at this point in the history
Improve arrow positioning
  • Loading branch information
simonwep authored Jan 17, 2024
2 parents 4913582 + 97aacb5 commit 4be79b8
Show file tree
Hide file tree
Showing 15 changed files with 90 additions and 10 deletions.
44 changes: 34 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ type AvailableVariants = {
he: number;
};

type AvailableArrowVariants = {
s: number;
m: number;
e: number;
};

type PositionPairs = [Direction, Direction];

export type PositionMatch = 'ts' | 'tm' | 'te' | 'bs' | 'bm' | 'be' | 'ls' | 'lm' | 'le' | 'rs' | 'rm' | 're';
Expand Down Expand Up @@ -190,19 +196,37 @@ export const reposition = (
if (arrow) {
// Calculate refBox's center offset from its variant position for arrow positioning
const refBoxCenterOffset = vertical ? refBox.width / 2 : refBox.height / 2;

// When refBox is larger than popBox, have the arrow's variant position be the center of popBox instead.
const arrowVariantVal = refBoxCenterOffset * 2 < variantSize ?
refBox[variantKey] + refBoxCenterOffset : variantVal + variantSize / 2;

// Arrow position is either on one side of the popBox or the other.
if (positionVal < refBox[positionKey]) {
positionVal += positionSize;
}
const popBoxCenterOffset = variantSize / 2;

// Check if refBox is larger than popBox
const isRefBoxLarger = refBoxCenterOffset > popBoxCenterOffset;

/**
* Holds corresponding offset variants (start, middle, end) of arrow from the popper variant values.
* When refBox is larger than popBox, have the arrow's variant position be the center of popBox instead.
*/
const arrowVariantStore: AvailableArrowVariants = {
s: isRefBoxLarger ? popBoxCenterOffset : refBoxCenterOffset,
m: popBoxCenterOffset,
e: isRefBoxLarger ? popBoxCenterOffset : variantSize - refBoxCenterOffset,
};

/**
* Holds offsets of top, left, bottom and right alignment of arrow from the popper position values.
*/
const arrowPositionStore: AvailablePositions = {
t: positionSize,
b: 0,
r: 0,
l: positionSize
};

const arrowVariantVal = variantVal + arrowVariantStore[v as keyof AvailableArrowVariants];
const arrowPositionVal = positionVal + arrowPositionStore[p as keyof AvailablePositions];

// Apply styles to arrow
arrow.style[variantKey] = `${arrowVariantVal}px`;
arrow.style[positionKey] = `${positionVal}px`;
arrow.style[positionKey] = `${arrowPositionVal}px`;
}

return (p + v) as PositionMatch;
Expand Down
55 changes: 55 additions & 0 deletions tests/_pages/with-arrow-transformed-parent.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<div id="container">
<div id="transform">
<div id="reference"></div>
<div id="popper"></div>
<div id="arrow"></div>
</div>
</div>

<style>
@import '_reset.css';

#container {
display: flex;
align-items: center;
justify-content: center;
}

#transform {
transform: translate(10px, 10px);
display: flex;
align-items: center;
justify-content: center;
}

#reference {
width: 40px;
height: 40px;
}

#popper {
width: 100px;
height: 100px;
}

#arrow{
position: fixed;
width: 10px;
height: 10px;
background: black;
transform: translate(-50%, -50%) rotate(45deg);
}
</style>

<script type="module">
import {reposition} from '/dist/nanopop.mjs';

const reference = document.querySelector('#reference');
const popper = document.querySelector('#popper');
const arrow = document.querySelector('#arrow');

reposition(reference, popper, {
position: location.hash.slice(1),
arrow: arrow
});
</script>
1 change: 1 addition & 0 deletions tests/arrow.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ test.describe('Popper with arrow option', () => {
test(`Should position ${pos} with proper arrow placement`, async ({ page }) => {
await testPage(page, `with-arrow-custom-position.html#${pos}`);
await testPage(page, `with-arrow-large-popper.html#${pos}`);
await testPage(page, `with-arrow-transformed-parent.html#${pos}`);
});
}
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 4be79b8

Please sign in to comment.