diff --git a/src/components/index.ts b/src/components/index.ts
index 40294d1f..cece20ee 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -15,4 +15,5 @@ export * from "./page";
export * from "./paginator";
export * from "./tabs";
export * from "./toolbar";
+export * from "./tooltip";
export * from "./typography";
diff --git a/src/components/tooltip/index.ts b/src/components/tooltip/index.ts
new file mode 100644
index 00000000..3c61782a
--- /dev/null
+++ b/src/components/tooltip/index.ts
@@ -0,0 +1 @@
+export * from "./tooltip";
diff --git a/src/components/tooltip/tooltip.scss b/src/components/tooltip/tooltip.scss
new file mode 100644
index 00000000..ced8a75b
--- /dev/null
+++ b/src/components/tooltip/tooltip.scss
@@ -0,0 +1,35 @@
+.mykn-tooltip {
+ transition: opacity 0.5s;
+ transform: scale(0.8);
+ opacity: 0;
+ border-radius: var(--border-radius-m);
+
+ &--open {
+ opacity: 1;
+ background-color: var(--theme-color-primary-200);
+ box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
+ transform: scale(1);
+ }
+
+ &__arrow {
+ fill: var(--theme-color-tertiary-400);
+ }
+
+ &__content {
+ padding: var(--spacing-h-m) var(--spacing-v-m);
+ box-sizing: border-box;
+ overflow-wrap: break-word;
+
+ &--sm {
+ max-width: 200px;
+ }
+
+ &--md {
+ max-width: 400px;
+ }
+
+ &--lg {
+ max-width: 600px;
+ }
+ }
+}
diff --git a/src/components/tooltip/tooltip.stories.tsx b/src/components/tooltip/tooltip.stories.tsx
new file mode 100644
index 00000000..6465cc2e
--- /dev/null
+++ b/src/components/tooltip/tooltip.stories.tsx
@@ -0,0 +1,97 @@
+import type { Meta, StoryObj } from "@storybook/react";
+import React from "react";
+
+import { Button } from "../button";
+import { Outline } from "../icon";
+import { Tooltip } from "./tooltip";
+
+const meta = {
+ title: "Controls/Tooltip",
+ component: Tooltip,
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
+} satisfies Meta;
+
+export default meta;
+type Story = StoryObj;
+
+export const TooltipComponent: Story = {
+ args: {
+ children: (
+
+ ),
+ content:
+ "This tooltip works by hovering over any react element, and it can be placed in any direction.",
+ },
+};
+
+export const TooltipTop: Story = {
+ args: {
+ ...TooltipComponent.args,
+ placement: "top",
+ },
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
+};
+
+export const TooltipRight: Story = {
+ args: {
+ ...TooltipComponent.args,
+ placement: "right",
+ },
+};
+
+export const TooltipBottom: Story = {
+ args: {
+ ...TooltipComponent.args,
+ placement: "bottom",
+ },
+};
+
+export const TooltipLeft: Story = {
+ args: {
+ ...TooltipComponent.args,
+ placement: "left",
+ },
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
+};
+
+export const TooltipBigText: Story = {
+ args: {
+ ...TooltipComponent.args,
+ content: (
+
+
+ This tooltip works by hovering over any react element, and it can be
+ placed in any direction.
+
+
+ This tooltip works by hovering over any react element, and it can be
+ placed in any direction.
+
+
+ This tooltip works by hovering over any react element, and it can be
+ placed in any direction.
+
+
+ ),
+ },
+};
diff --git a/src/components/tooltip/tooltip.tsx b/src/components/tooltip/tooltip.tsx
new file mode 100644
index 00000000..e3a49890
--- /dev/null
+++ b/src/components/tooltip/tooltip.tsx
@@ -0,0 +1,114 @@
+import {
+ FloatingArrow,
+ Placement,
+ arrow,
+ autoUpdate,
+ flip,
+ offset,
+ shift,
+ useDismiss,
+ useFloating,
+ useFocus,
+ useHover,
+ useInteractions,
+ useRole,
+ useTransitionStyles,
+} from "@floating-ui/react";
+import clsx from "clsx";
+import React, { ReactNode, useRef, useState } from "react";
+
+import { P } from "../typography";
+import "./tooltip.scss";
+
+type TooltipProps = React.PropsWithChildren<{
+ /* The content to display in the tooltip */
+ content?: ReactNode;
+
+ /* The placement of the tooltip */
+ placement?: Placement;
+
+ /* The size of the tooltip, defaults to md */
+ size?: "sm" | "md" | "lg";
+}>;
+
+export const Tooltip = ({
+ content,
+ children,
+ placement,
+ size = "md",
+}: TooltipProps) => {
+ const [isOpen, setIsOpen] = useState(false);
+ const arrowRef = useRef(null);
+
+ const {
+ refs: { setReference, setFloating },
+ floatingStyles,
+ context,
+ } = useFloating({
+ open: isOpen,
+ onOpenChange: setIsOpen,
+ placement,
+ middleware: [
+ offset(12),
+ flip(),
+ shift(),
+ arrow({
+ element: arrowRef,
+ }),
+ ],
+ whileElementsMounted: autoUpdate,
+ });
+
+ const hover = useHover(context, { move: false });
+ const focus = useFocus(context);
+ const dismiss = useDismiss(context);
+ const role = useRole(context, { role: "tooltip" });
+
+ const { getReferenceProps, getFloatingProps } = useInteractions([
+ hover,
+ focus,
+ dismiss,
+ role,
+ ]);
+
+ const { styles: transitionStyles } = useTransitionStyles(context, {
+ initial: {
+ opacity: 0,
+ transform: "scale(0.8)",
+ },
+ });
+
+ return (
+ <>
+ {React.cloneElement(children as React.ReactElement, {
+ ...getReferenceProps(),
+ ref: setReference,
+ })}
+
+ >
+ );
+};