[REF] web: rename a usePosition arg for clarity

**Before**
The "reference" argument of the usePosition hook is badly named as it
easily be confused with useRef's references.

**After**
The argument has been renamed "target",
which is a terminology used in other places, for example for popovers.

Part-of: odoo/odoo#116499
This commit is contained in:
Bruno Boi
2023-04-12 18:58:29 +02:00
committed by Leonardo Pavan Rocha
parent 4f2e06d0ca
commit 0613af8fa7
2 changed files with 42 additions and 43 deletions
+28 -29
View File
@@ -76,18 +76,18 @@ const DEFAULTS = {
* Returns the best positioning solution staying in the container or falls back
* to the requested position.
* The positioning data used to determine each possible position is based on
* the reference, popper, and container sizes.
* the target, popper, and container sizes.
* Particularly, a popper must not overflow the container in any direction,
* it should actually stay at `margin` distance from the border to look good.
*
* @param {HTMLElement} reference
* @param {HTMLElement} target
* @param {HTMLElement} popper
* @param {Options} options
* @returns {PositioningSolution} the best positioning solution, relative to
* the containing block of the popper.
* => can be applied to popper.style.(top|left)
*/
function getBestPosition(reference, popper, { container, margin, position }) {
function getBestPosition(target, popper, { container, margin, position }) {
// Retrieve directions and variants
const [directionKey, variantKey = "middle"] = position.split("-");
const directions =
@@ -100,7 +100,7 @@ function getBestPosition(reference, popper, { container, margin, position }) {
// Boxes
const popBox = popper.getBoundingClientRect();
const refBox = reference.getBoundingClientRect();
const targetBox = target.getBoundingClientRect();
const contBox = container.getBoundingClientRect();
const containerIsHTMLNode = container === document.firstElementChild;
@@ -108,21 +108,21 @@ function getBestPosition(reference, popper, { container, margin, position }) {
// Compute positioning data
/** @type {DirectionsData} */
const directionsData = {
t: refBox.top - popBox.height - margin,
b: refBox.bottom + margin,
r: refBox.right + margin,
l: refBox.left - popBox.width - margin,
t: targetBox.top - popBox.height - margin,
b: targetBox.bottom + margin,
r: targetBox.right + margin,
l: targetBox.left - popBox.width - margin,
};
/** @type {VariantsData} */
const variantsData = {
vf: refBox.left,
vs: refBox.left,
vm: refBox.left + refBox.width / 2 + -popBox.width / 2,
ve: refBox.right - popBox.width,
hf: refBox.top,
hs: refBox.top,
hm: refBox.top + refBox.height / 2 + -popBox.height / 2,
he: refBox.bottom - popBox.height,
vf: targetBox.left,
vs: targetBox.left,
vm: targetBox.left + targetBox.width / 2 + -popBox.width / 2,
ve: targetBox.right - popBox.width,
hf: targetBox.top,
hs: targetBox.top,
hm: targetBox.top + targetBox.height / 2 + -popBox.height / 2,
he: targetBox.bottom - popBox.height,
};
function getPositioningData(d = directions[0], v = variants[0], containerRestricted = false) {
@@ -209,11 +209,11 @@ function getBestPosition(reference, popper, { container, margin, position }) {
* When the final position is applied, a corresponding CSS class is also added to the popper.
* This could be used to further styling.
*
* @param {HTMLElement} reference
* @param {HTMLElement} target
* @param {HTMLElement} popper
* @param {Options} options
*/
export function reposition(reference, popper, options) {
export function reposition(target, popper, options) {
options = { ...DEFAULTS, container: document.documentElement, ...options };
let [directionKey, variantKey = "middle"] = options.position.split("-");
@@ -234,14 +234,14 @@ export function reposition(reference, popper, options) {
popper.style.left = "0px";
// Get best positioning solution and apply it
const position = getBestPosition(reference, popper, options);
const position = getBestPosition(target, popper, options);
const { top, left, variant } = position;
popper.style.top = `${top}px`;
popper.style.left = `${left}px`;
if (variant === "fit") {
const styleProperty = ["top", "bottom"].includes(directionKey) ? "width" : "height";
popper.style[styleProperty] = reference.getBoundingClientRect()[styleProperty] + "px";
popper.style[styleProperty] = target.getBoundingClientRect()[styleProperty] + "px";
}
if (options.onPositioned) {
@@ -251,7 +251,7 @@ export function reposition(reference, popper, options) {
/**
* Makes sure that the `popper` element is always
* placed at `position` from the `reference` element.
* placed at `position` from the `target` element.
* If doing so the `popper` element is clipped off `container`,
* sensible fallback positions are tried.
* If all of fallback positions are also clipped off `container`,
@@ -260,17 +260,16 @@ export function reposition(reference, popper, options) {
* Note: The popper element should be indicated in your template with a t-ref reference.
* This could be customized with the `popper` option.
*
* @param {HTMLElement | (() => HTMLElement)} reference
* @param {HTMLElement | (() => HTMLElement)} target
* @param {Options} options
*/
export function usePosition(reference, options) {
const popper = options.popper || DEFAULTS.popper;
const popperRef = useRef(popper);
const getReference = reference instanceof HTMLElement ? () => reference : reference;
export function usePosition(target, options) {
const popperRef = useRef(options.popper || DEFAULTS.popper);
const getTarget = target instanceof HTMLElement ? () => target : target;
const update = () => {
const ref = getReference();
if (popperRef.el && ref) {
reposition(ref, popperRef.el, options);
const targetEl = getTarget();
if (popperRef.el && targetEl) {
reposition(targetEl, popperRef.el, options);
}
};
useEffect(update);
@@ -22,16 +22,16 @@ let container;
* @returns {Component}
*/
function getTestComponent(popperOptions = {}) {
const reference = document.createElement("div");
reference.id = "reference";
reference.style.backgroundColor = "yellow";
reference.style.height = "50px";
reference.style.width = "50px";
container.appendChild(reference);
const target = document.createElement("div");
target.id = "target";
target.style.backgroundColor = "yellow";
target.style.height = "50px";
target.style.width = "50px";
container.appendChild(target);
class TestComp extends Component {
setup() {
usePosition(reference, { container, ...popperOptions });
usePosition(target, { container, ...popperOptions });
}
}
TestComp.template = xml`<div id="popper" t-ref="popper" />`;
@@ -111,7 +111,7 @@ QUnit.test("popper is an inner element", async (assert) => {
await mount(TestComp, container);
});
QUnit.test("can change the popper reference name", async (assert) => {
QUnit.test("can change the popper target name", async (assert) => {
assert.expect(2);
const TestComp = getTestComponent({
popper: "myRef",
@@ -252,8 +252,8 @@ const CONTAINER_STYLE_MAP = {
left: { justifyContent: "flex-start" },
right: { justifyContent: "flex-end" },
slimfit: { height: "100px", width: "100px" }, // height and width of popper
h125: { height: "125px" }, // height of popper + 1/2 reference
w125: { width: "125px" }, // width of popper + 1/2 reference
h125: { height: "125px" }, // height of popper + 1/2 target
w125: { width: "125px" }, // width of popper + 1/2 target
};
function getRepositionTest(from, to, containerStyleChanges) {
@@ -893,7 +893,7 @@ QUnit.test(
"reposition from left-fit to right-fit",
getRepositionTest("left-fit", "right-fit", "left")
);
QUnit.test("bottom-fit has the same width as the reference", getFittingTest("bottom-fit", "width"));
QUnit.test("top-fit has the same width as the reference", getFittingTest("top-fit", "width"));
QUnit.test("left-fit has the same height as the reference", getFittingTest("left-fit", "height"));
QUnit.test("right-fit has the same height as the reference", getFittingTest("right-fit", "height"));
QUnit.test("bottom-fit has the same width as the target", getFittingTest("bottom-fit", "width"));
QUnit.test("top-fit has the same width as the target", getFittingTest("top-fit", "width"));
QUnit.test("left-fit has the same height as the target", getFittingTest("left-fit", "height"));
QUnit.test("right-fit has the same height as the target", getFittingTest("right-fit", "height"));