Skip to content

Commit

Permalink
feat(tooltip): swapped to use floatingui
Browse files Browse the repository at this point in the history
  • Loading branch information
agliga committed Dec 14, 2023
1 parent 91b78ee commit 67100f4
Show file tree
Hide file tree
Showing 15 changed files with 2,617 additions and 2,412 deletions.
4,711 changes: 2,519 additions & 2,192 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@
},
"dependencies": {
"@marko-tags/subscribe": "^0.5.0",
"@floating-ui/core": "^1.5.2",
"makeup-active-descendant": "0.6.1",
"makeup-expander": "~0.10.1",
"makeup-floating-label": "~0.3.2",
Expand Down
68 changes: 67 additions & 1 deletion src/components/components/ebay-tooltip-base/component-browser.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Expander from "makeup-expander";
import focusables from "makeup-focusables";
import { inline, autoUpdate, flip, computePosition, shift, offset, arrow, type Placement } from '@floating-ui/dom';

interface TooptipBaseInput {
open?: boolean;
Expand All @@ -9,6 +10,7 @@ interface TooptipBaseInput {
"overlay-style"?: string;
"overlay-id"?: string;
"render-body"?: Marko.Renderable;
pointer?: Placement;
"on-base-expand"?: (event: { originalEvent: Event }) => void;
"on-base-collapse"?: (event: { originalEvent: Event }) => void;
}
Expand All @@ -18,9 +20,14 @@ class TooltipBase extends Marko.Component<Input> {
declare action: "expand" | "collapse" | null;
declare _expander: any;
declare cancelFocus: ReturnType<typeof focusables>;
hostEl: HTMLElement | null;
overlayEl: HTMLElement | null;
arrowEl: HTMLElement | null;
cleanup: (() => void) | undefined;

handleExpand() {
this.emit("base-expand");
this.updateTip();
}

handleCollapse() {
Expand Down Expand Up @@ -75,7 +82,7 @@ class TooltipBase extends Marko.Component<Input> {
const expanderEl = container?.getElementsByClassName(type)[0];

if (host && !isTourtip) {
this._expander = new Expander(expanderEl, {
this._expander = new Expander(expanderEl, {
hostSelector: hostSelector,
contentSelector: `.${type}__overlay`,
expandedClass: `${type}--expanded`,
Expand All @@ -90,9 +97,64 @@ class TooltipBase extends Marko.Component<Input> {
host.setAttribute("aria-describedby", input.overlayId!);
}
}
if (this.hostEl && this.overlayEl) {
this.updateTip();
this.cleanup = autoUpdate(
this.hostEl,
this.overlayEl,
this.update.bind(this),
);
}
}

updateTip() {
computePosition((this.hostEl as HTMLElement), (this.overlayEl as HTMLElement), {
placement: this.input.pointer,
middleware: [
inline(),
flip(),
shift(),
arrow({ element: this.arrowEl as HTMLElement }),
],
}).then(({ x, y, placement, middlewareData }) => {
Object.assign(this.overlayEl?.style || {}, {
left: `${x}px`,
top: `${y}px`,
});

// Accessing the data
const arrowX = middlewareData.arrow?.x;
const arrowY = middlewareData.arrow?.y;

const staticSide = {
top: 'bottom',
strategy: 'fixed',
right: 'left',
bottom: 'top',
left: 'right',
}[placement.split('-')[0]];

Object.assign(this.arrowEl?.style || {}, {
left: arrowX !== null ? `${arrowX}px` : '',
top: arrowY !== null ? `${arrowY}px` : '',
right: '',
bottom: '',
[staticSide || '']: '-4px',
});
});
}


_setupBaseTooltip() {
const { type } = this.input;
const hostClass = `${type}__host`;
const hostSelector = `.${hostClass}`;

this.hostEl = this.el?.querySelector(hostSelector) || null;
this.overlayEl = this.el?.querySelector(`.${type}__overlay`) || null;
this.arrowEl = this.el?.querySelector(`.${type}__pointer`) || null;


if (this.input.type !== "dialog--mini") {
this._setupMakeup();
}
Expand Down Expand Up @@ -148,6 +210,10 @@ class TooltipBase extends Marko.Component<Input> {
this._expander.destroy();
this._expander = undefined;
}
if (this.cleanup) {
this.cleanup();
this.cleanup = undefined;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import type { AttrClass } from "marko/tags-html";
import type { pointerStyles, typeRoles } from "./constants";
import type { typeRoles } from "./constants";

interface TooltipOverlayInput {
toJSON?: any;
"style-top"?: string;
"style-left"?: string;
"style-right"?: string;
"style-bottom"?: string;
pointer?: keyof typeof pointerStyles;
heading?: Marko.Input<"span"> & {
as: Marko.NativeTags;
renderBody: Marko.Body;
Expand Down
88 changes: 0 additions & 88 deletions src/components/components/ebay-tooltip-overlay/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,91 +3,3 @@ export const typeRoles = {
tooltip: "tooltip",
infotip: "tooltip",
} as const;

// Added scale3d for safari to trigger gpu rerendering to fix a bug with filter
export const pointerStyles = {
left: {
transform: "translateX(16px) translateY(-50%) scale3d(1,1,1)",
left: "100%",
right: "auto",
top: "-6px",
bottom: "auto",
},
"left-top": {
transform: "translateX(16px) scale3d(1,1,1)",
left: "100%",
right: "auto",
top: "-100%",
bottom: "auto",
},
"left-bottom": {
transform: "translateX(16px) scale3d(1,1,1)",
left: "100%",
right: "auto",
top: "auto",
bottom: "-8px",
},
right: {
transform: "translateX(-16px) translateY(-50%) scale3d(1,1,1)",
left: "auto",
right: "100%",
top: "-6px",
bottom: "auto",
},
"right-top": {
transform: "translateX(-16px) scale3d(1,1,1)",
left: "auto",
right: "100%",
top: "-100%",
bottom: "auto",
},
"right-bottom": {
transform: "translateX(-16px) scale3d(1,1,1)",
left: "auto",
right: "100%",
top: "auto",
bottom: "calc(-50% + 2px)",
},
top: {
transform: "translateX(-50%) scale3d(1,1,1)",
left: "50%",
right: "auto",
top: "calc(100% - 2px)",
bottom: "auto",
},
"top-left": {
transform: "scale3d(1,1,1)",
left: "-6px",
right: "auto",
top: "calc(100% - 2px)",
bottom: "auto",
},
"top-right": {
transform: "scale3d(1,1,1)",
left: "auto",
right: "-5px",
top: "calc(100% - 2px)",
bottom: "auto",
},
"bottom-right": {
transform: "scale3d(1,1,1)",
left: "auto",
right: "-5px",
top: "auto",
bottom: "calc(100% + 12px)",
},
"bottom-left": {
transform: "scale3d(1,1,1)",
left: "-8px",
right: "auto",
top: "auto",
bottom: "calc(100% + 12px)",
},
bottom: {
transform: "translateX(-50%) scale3d(1,1,1)",
left: "50%",
right: "auto",
top: "auto",
bottom: "calc(100% + 12px)",
},
} as const;
19 changes: 3 additions & 16 deletions src/components/components/ebay-tooltip-overlay/index.marko
Original file line number Diff line number Diff line change
@@ -1,23 +1,10 @@
import { processHtmlAttributes } from "../../../common/html-attributes";
import { typeRoles, pointerStyles } from "./constants";
import { typeRoles } from "./constants";

static function noop() {}
static var ignoredHeaderAttributes = ["id", "as", "class"];

$ input.toJSON = noop;

$ var hasUserStyles = (
input.styleTop ||
input.styleLeft ||
input.styleRight ||
input.styleBottom
);
$ var overlayStyles = hasUserStyles ? {
top: input.styleTop,
left: input.styleLeft,
right: input.styleRight,
bottom: input.styleBottom
} : pointerStyles[input.pointer || "bottom"];
$ var heading = input.heading;

<span
Expand All @@ -29,8 +16,8 @@ $ var heading = input.heading;
heading &&
component.elId("tourtip-label")
)
style=overlayStyles>
<span class=`${input.type}__pointer ${input.type}__pointer--${input.pointer}`/>
>
<span class=`${input.type}__pointer`/>
<span class=`${input.type}__mask`>
<span class=`${input.type}__cell`>
<span class=`${input.type}__content`>
Expand Down
8 changes: 2 additions & 6 deletions src/components/ebay-infotip/component.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import { pointerStyles } from "../components/ebay-tooltip-overlay/constants";
import EbayTooltipBase from "../components/ebay-tooltip-base/component-browser";
import { Placement } from '@floating-ui/dom';

interface InfotipInput extends Omit<Marko.Input<"span">, `on${string}`> {
open?: boolean;
variant?: "modal" | "default";
pointer?: keyof typeof pointerStyles;
pointer?: Placement;
disabled?: boolean;
"aria-label"?: string;
icon?: Marko.AttrTag<{ renderBody: Marko.Renderable }>;
"style-left"?: string;
"style-right"?: string;
"style-top"?: string;
"style-bottom"?: string;
heading: Marko.Input<"span"> & {
as: Marko.NativeTags;
renderBody: Marko.Renderable;
Expand Down
6 changes: 1 addition & 5 deletions src/components/ebay-infotip/index.marko
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ $ var pointer = input.pointer || "bottom";
key="base"
type=classPrefix
overlayId:scoped="overlay"
pointer=pointer
onBase-expand(isModal ? undefined : "handleExpand")
onBase-collapse(isModal ? undefined : "handleCollapse")>
<span
Expand Down Expand Up @@ -58,11 +59,6 @@ $ var pointer = input.pointer || "bottom";
<ebay-tooltip-overlay
type="infotip"
id:scoped="overlay"
styleLeft=input.styleLeft
styleTop=input.styleTop
styleRight=input.styleRight
styleBottom=input.styleBottom
pointer=pointer
heading=input.heading
content=input.content
a11y-close-text=input.a11yCloseButtonText
Expand Down
37 changes: 6 additions & 31 deletions src/components/ebay-infotip/infotip.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,44 +43,19 @@ export default {
"Either modal or default. If modal will show the mobile version of infotip",
},
pointer: {
control: { type: "select" },
options: [
"top-left",
"top",
"top-right",
"right",
"right-bottom",
"right-top",
"bottom-left",
"bottom-right",
"bottom",
"left",
"left-bottom",
"left-top",
],
'top', 'right', 'bottom', 'left',
'top-start', 'right-start', 'bottom-start', 'left-start',
'top-end', 'right-end', 'bottom-end', 'left-end',
],
control: { type: "select" },
description:
"options are `top-left`, `top`, `top-right`, `right`, `right-bottom`, `right-top`, `bottom-left`, `bottom-right`, `bottom`, `left`, `left-bottom`, `left-top`",
"places infotip position",
},
disabled: {
control: { type: "boolean" },
description: "adds a `disabled` attribute to the button",
},
styleTop: {
control: { type: "text" },
description: "a style property for the CSS `top` rule",
},
styleLeft: {
control: { type: "text" },
description: "a style property for the CSS `top` rule",
},
styleRight: {
control: { type: "text" },
description: "a style property for the CSS `top` rule",
},
styleBottom: {
control: { type: "text" },
description: "a style property for the CSS `top` rule",
},
a11yCloseButtonText: {
control: { type: "text" },
description: "A11y text for close button",
Expand Down
6 changes: 1 addition & 5 deletions src/components/ebay-tooltip/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,9 @@ interface TooltipInput extends Omit<Marko.Input<"span">, `on${string}`> {
open?: boolean;
"no-hover"?: TooltipBaseInput["noHover"];
host?: Marko.AttrTag<{ renderBody: Marko.Body }>;
pointer?: TooltipOverlayInput["pointer"];
"style-left"?: TooltipOverlayInput["styleLeft"];
"style-right"?: TooltipOverlayInput["styleRight"];
"style-top"?: TooltipOverlayInput["styleTop"];
"style-bottom"?: TooltipOverlayInput["styleBottom"];
heading?: TooltipOverlayInput["heading"];
content?: TooltipOverlayInput["content"];
pointer?: TooltipBaseInput['pointer'];
"on-expand"?: () => void;
"on-collapse"?: () => void;
}
Expand Down
6 changes: 1 addition & 5 deletions src/components/ebay-tooltip/index.marko
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ $ var pointer = input.pointer || "bottom";
type="tooltip"
overlayId:scoped="overlay"
noHover=input.noHover
pointer=pointer
onBase-expand("handleExpand")
onBase-collapse("handleCollapse")>
<span
Expand All @@ -35,11 +36,6 @@ $ var pointer = input.pointer || "bottom";
<ebay-tooltip-overlay
type="tooltip"
id:scoped="overlay"
pointer=pointer
styleLeft=input.styleLeft
styleTop=input.styleTop
styleRight=input.styleRight
styleBottom=input.styleBottom
heading=input.heading
content=input.content/>
</span>
Expand Down
Loading

0 comments on commit 67100f4

Please sign in to comment.