Skip to content

Commit

Permalink
feat: establish Tooltip as its own ably-ui component
Browse files Browse the repository at this point in the history
  • Loading branch information
jamiehenson committed Mar 26, 2024
1 parent 7d35cb3 commit 234048f
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
27 changes: 27 additions & 0 deletions src/core/Tooltip/Tooltip.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from "react";
import Tooltip from "./component";

export default {
title: "Components/Tooltip",
component: Tooltip,
tags: ["autodocs"],
args: {
children: "Example content",
},
};

export const Central = {
render: (args) => (
<div className="w-256 h-256 flex items-center justify-center m-24 border">
<Tooltip>{args.children}</Tooltip>
</div>
),
};

export const LeftBound = {
render: (args) => (
<div className="w-256 h-256 flex items-center m-24 border">
<Tooltip>{args.children}</Tooltip>
</div>
),
};
60 changes: 60 additions & 0 deletions src/core/Tooltip/component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { PropsWithChildren, useEffect, useRef, useState } from "react";
import Icon from "../Icon/component.tsx";

const Tooltip = ({ children }: PropsWithChildren) => {
const [open, setOpen] = useState(false);
const [position, setPosition] = useState({ x: 0, y: 0 });
const offset = 8;
const reference = useRef<HTMLButtonElement>(null);
const floating = useRef<HTMLDivElement>(null);

useEffect(() => {
if (open) {
const floatingRect = floating.current?.getBoundingClientRect();
const referenceRect = reference.current?.getBoundingClientRect();

if (floatingRect && referenceRect) {
setPosition({
x:
Math.min(floatingRect.width / 2, floatingRect.left) -
referenceRect.width / 2,
y: Math.min(floatingRect.height, floatingRect.top) + offset,
});
}
} else {
setPosition({ x: 0, y: 0 });
}
}, [open]);

return (
<div className="relative inline-block align-top h-16">
<button
onMouseEnter={() => setOpen(true)}
onMouseLeave={() => setOpen(false)}
className="ml-8 p-0 relative top-1"
type="button"
ref={reference}
aria-describedby="tooltip"
>
<Icon name="icon-gui-info" size="1rem" />
</button>

{open ? (
<div
className="bg-light-grey p-12 rounded pointer-events-none absolute z-20"
role="tooltip"
ref={floating}
style={{
top: -position.y,
left: -position.x,
boxShadow: "4px 4px 15px rgba(0, 0, 0, 0.2)",
}}
>
<div className="w-256">{children}</div>
</div>
) : null}
</div>
);
};

export default Tooltip;

0 comments on commit 234048f

Please sign in to comment.