Skip to content

Commit

Permalink
feat(tooltip): swapped to use floatingui (#2037)
Browse files Browse the repository at this point in the history
  • Loading branch information
agliga authored and LuLaValva committed Dec 23, 2023
1 parent d6348b9 commit 55c758f
Show file tree
Hide file tree
Showing 22 changed files with 3,389 additions and 3,573 deletions.
6,347 changes: 3,177 additions & 3,170 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
72 changes: 71 additions & 1 deletion src/components/components/ebay-tooltip-base/component-browser.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import Expander from "makeup-expander";
import focusables from "makeup-focusables";
import { inline, autoUpdate, flip, computePosition, shift, offset, arrow, type Placement } from '@floating-ui/dom';
import { pointerStyles } from './constants'

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

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

handleCollapse() {
Expand Down Expand Up @@ -75,7 +85,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 +100,65 @@ 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.placement || pointerStyles[this.input.pointer ?? 'bottom'],
middleware: [
offset(this.input.offset || 6),
inline(),
flip(),
shift(),
arrow({ element: this.arrowEl as HTMLElement, padding: 20 }),
],
}).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 +214,10 @@ class TooltipBase extends Marko.Component<Input> {
this._expander.destroy();
this._expander = undefined;
}
if (this.cleanup) {
this.cleanup();
this.cleanup = undefined;
}
}
}

Expand Down
16 changes: 16 additions & 0 deletions src/components/components/ebay-tooltip-base/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { Placement } from '@floating-ui/dom';

export const pointerStyles:{[index: string]: Placement} = {
"left": "right",
"left-top": "right-start",
"left-bottom": "right-end",
"right": "left",
"right-top": "left-start",
"right-bottom": "left-end",
"top": "bottom",
"top-left": "bottom-start",
"top-right": "bottom-end",
"bottom-right": "top-end",
"bottom-left": "top-start",
"bottom": "top",
} as const;
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import type { AttrClass } from "marko/tags-html";
import type { pointerStyles, typeRoles } from "./constants";
export const typeRoles = {
tourtip: "region",
tooltip: "tooltip",
infotip: "tooltip",
} as const;

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
93 changes: 0 additions & 93 deletions src/components/components/ebay-tooltip-overlay/constants.ts

This file was deleted.

30 changes: 6 additions & 24 deletions src/components/components/ebay-tooltip-overlay/index.marko
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { processHtmlAttributes } from "../../../common/html-attributes";
import { typeRoles, pointerStyles } from "./constants";
import { typeRoles } from "./component-browser";

static function noop() {}

Expand All @@ -8,30 +8,12 @@ $ input.toJSON = noop;
$ const {
id,
type,
styleTop,
styleLeft,
styleRight,
styleBottom,
pointer,
heading,
content,
footer,
a11yCloseText,
} = input;

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

<span
id=id
class=`${type}__overlay`
Expand All @@ -41,11 +23,11 @@ $ var overlayStyles = hasUserStyles ? {
heading &&
component.elId("tourtip-label")
)
style=overlayStyles>
<span class=`${type}__pointer ${type}__pointer--${pointer}`/>
<span class=`${type}__mask`>
<span class=`${type}__cell`>
<span class=`${type}__content`>
>
<span class=`${input.type}__pointer`/>
<span class=`${input.type}__mask`>
<span class=`${input.type}__cell`>
<span class=`${input.type}__content`>
<if(heading)>
$ const {
as: headingAs,
Expand Down
10 changes: 4 additions & 6 deletions src/components/ebay-infotip/component.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { pointerStyles } from "../components/ebay-tooltip-overlay/constants";
import EbayTooltipBase from "../components/ebay-tooltip-base/component-browser";
import type { Input as TooltipBaseInput } from "../components/ebay-tooltip-base/component-browser";

interface InfotipInput extends Omit<Marko.Input<"span">, `on${string}`> {
open?: boolean;
variant?: "modal" | "default";
pointer?: keyof typeof pointerStyles;
offset?: TooltipBaseInput['offset'];
pointer?: TooltipBaseInput['pointer'];
placement?: TooltipBaseInput['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
12 changes: 3 additions & 9 deletions src/components/ebay-infotip/index.marko
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ $ const {
icon,
open,
pointer = "bottom",
styleBottom,
styleLeft,
styleRight,
styleTop,
variant,
...htmlInput
} = input;
Expand All @@ -27,6 +23,9 @@ $ var classPrefix = !isModal ? "infotip" : "dialog--mini";
key="base"
type=classPrefix
overlayId:scoped="overlay"
offset=input.offset
pointer=input.pointer
placement=input.placement
onBase-expand(isModal ? undefined : "handleExpand")
onBase-collapse(isModal ? undefined : "handleCollapse")>
<span
Expand Down Expand Up @@ -60,11 +59,6 @@ $ var classPrefix = !isModal ? "infotip" : "dialog--mini";
<ebay-tooltip-overlay
type="infotip"
id:scoped="overlay"
styleLeft=styleLeft
styleTop=styleTop
styleRight=styleRight
styleBottom=styleBottom
pointer=pointer
heading=heading
content=content
a11y-close-text=a11yCloseButtonText
Expand Down
Loading

0 comments on commit 55c758f

Please sign in to comment.