Skip to content

Commit

Permalink
🐛 fix(core, tooltip): positionnement du tooltip dans header & modale …
Browse files Browse the repository at this point in the history
…[DS-3733] (#1010)

- Correction du placement du tooltip dans un élément possédant un filter (modal, header)
- Gestion du placement en position absolute plutot que fixed
  • Loading branch information
keryanS authored Oct 28, 2024
1 parent 1f7c292 commit 0b33bd9
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 30 deletions.
1 change: 1 addition & 0 deletions src/component/tooltip/script/tooltip/tooltip-selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ import api from '../../api.js';
export const TooltipSelector = {
TOOLTIP: api.internals.ns.selector('tooltip'),
SHOWN: api.internals.ns.selector('tooltip--shown'),
HIDDING: api.internals.ns.selector('tooltip--hidding'),
BUTTON: api.internals.ns.selector('btn--tooltip')
};
7 changes: 6 additions & 1 deletion src/component/tooltip/script/tooltip/tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class Tooltip extends api.core.Placement {

transitionEnd () {
if (this._state === TooltipState.HIDING) {
this.removeClass(TooltipSelector.SHOWN);
this.removeClass(TooltipSelector.HIDDING);
this._state = TooltipState.HIDDEN;
this.isShown = false;
}
Expand All @@ -43,24 +45,27 @@ class Tooltip extends api.core.Placement {
case value:
this._state = TooltipState.SHOWN;
this.addClass(TooltipSelector.SHOWN);
this.removeClass(TooltipSelector.HIDDING);
this.dispatch(TooltipEvent.SHOW);
super.isShown = true;
break;

case this.isShown && !value && this._state === TooltipState.SHOWN:
this._state = TooltipState.HIDING;
this.removeClass(TooltipSelector.SHOWN);
this.addClass(TooltipSelector.HIDDING);
break;

case this.isShown && !value && this._state === TooltipState.HIDDEN:
this.dispatch(TooltipEvent.HIDE);
this.removeClass(TooltipSelector.HIDDING);
super.isShown = false;
break;
}
}

render () {
super.render();
this.rect = this.getRect();
let x = this.referentRect.center - this.rect.center;
const limit = this.rect.width * 0.5 - 8;
if (x < -limit) x = -limit;
Expand Down
5 changes: 4 additions & 1 deletion src/component/tooltip/style/_module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,14 @@
}

&:not(&--shown) {
// transition in/out
display: none;
opacity: 0;
}

&--hidding {
opacity: 0;
}

&#{ns(placement)} {
&--bottom {
@include padding-top(5v);
Expand Down
83 changes: 56 additions & 27 deletions src/core/script/placement/placement.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Placement extends Instance {
this._aligns = aligns;
this._safeAreaMargin = safeAreaMargin;
this._isShown = false;
this._x = this._y = 0;
}

static get instanceClassName () {
Expand Down Expand Up @@ -169,21 +170,11 @@ class Placement extends Instance {
this._referent = referent;
}

resize () {
this.safeArea = {
top: this._safeAreaMargin,
right: window.innerWidth - this._safeAreaMargin,
bottom: window.innerHeight - this._safeAreaMargin,
left: this._safeAreaMargin,
center: window.innerWidth * 0.5,
middle: window.innerHeight * 0.5
};
}

render () {
if (!this._referent) return;
this.rect = this.getRect();
this.referentRect = this._referent.getRect();
this.rect = this.getRect();
this.safeArea = this.getSafeArea();

if (this.mode === PlacementMode.AUTO) {
this.place = this.getPlace();
Expand All @@ -203,19 +194,19 @@ class Placement extends Instance {

switch (this.place) {
case PlacementPosition.TOP:
y = this.referentRect.top - this.rect.height;
y = this.referentRect.top - this.rect.top - this.rect.height;
break;

case PlacementPosition.RIGHT:
x = this.referentRect.right;
x = this.referentRect.left - this.rect.left + this.referentRect.width;
break;

case PlacementPosition.BOTTOM:
y = this.referentRect.bottom;
y = this.referentRect.top - this.rect.top + this.referentRect.height;
break;

case PlacementPosition.LEFT:
x = this.referentRect.left - this.rect.width;
x = this.referentRect.left - this.rect.left - this.rect.width;
break;
}

Expand All @@ -224,15 +215,15 @@ class Placement extends Instance {
case PlacementPosition.BOTTOM:
switch (this.align) {
case PlacementAlign.CENTER:
x = this.referentRect.center - this.rect.width * 0.5;
x = this.referentRect.left - this.rect.left + this.referentRect.width * 0.5 - this.rect.width * 0.5;
break;

case PlacementAlign.START:
x = this.referentRect.left;
x = this.referentRect.left - this.rect.left;
break;

case PlacementAlign.END:
x = this.referentRect.right - this.rect.width;
x = this.referentRect.left - this.rect.left + this.referentRect.width - this.rect.width;
break;
}
break;
Expand All @@ -241,25 +232,23 @@ class Placement extends Instance {
case PlacementPosition.LEFT:
switch (this.align) {
case PlacementAlign.CENTER:
y = this.referentRect.middle - this.rect.height * 0.5;
y = this.referentRect.top - this.rect.top + this.referentRect.height * 0.5 - this.rect.height * 0.5;
break;

case PlacementAlign.START:
y = this.referentRect.top;
y = this.referentRect.top - this.rect.top;
break;

case PlacementAlign.END:
y = this.referentRect.bottom - this.rect.height;
y = this.referentRect.top - this.rect.top - this.rect.height;
break;
}
break;
}

if (this._x !== x || this._y !== y) {
this._x = (x + 0.5) | 0;
this._y = (y + 0.5) | 0;
this.node.style.transform = `translate(${this._x}px,${this._y}px)`;
}
this._x += (x + 0.5) | 0;
this._y += (y + 0.5) | 0;
this.node.style.transform = `translate(${this._x}px,${this._y}px)`;
}

getPlace () {
Expand Down Expand Up @@ -326,6 +315,46 @@ class Placement extends Instance {
return this._aligns[0];
}

getSafeArea () {
let element = this.node;
let isX, isY;
let top = this._safeAreaMargin;
let right = window.innerWidth - this._safeAreaMargin;
let bottom = window.innerHeight - this._safeAreaMargin;
let left = this._safeAreaMargin;

while (element) {
if (element === document.body) break;
element = element.parentElement;
const style = window.getComputedStyle(element);

const overflow = /(visible|(\w+))(\s(visible|(\w+)))?/.exec(style.overflow);
isX = overflow[2] !== undefined;
isY = overflow[3] !== undefined ? overflow[5] !== undefined : overflow[2] !== undefined;

if (!isX && !isY) continue;
const rect = element.getBoundingClientRect();

if (isX) {
if (rect.left > left) left = rect.left;
if (rect.right < right) right = rect.right;
}
if (isY) {
if (rect.top > top) top = rect.top;
if (rect.bottom < bottom) bottom = rect.bottom;
}
}

return {
top: top,
right: right,
bottom: bottom,
left: left,
center: left + (right - left) * 0.5,
middle: top + (bottom - top) * 0.5
};
}

dispose () {
this._referent = null;
super.dispose();
Expand Down
3 changes: 2 additions & 1 deletion src/core/style/placement/_module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
@use 'module/spacing';

#{ns(placement)} {
@include fixed(0, null, null, 0);
@include absolute;
width: max-content;
}

0 comments on commit 0b33bd9

Please sign in to comment.