}
diff --git a/web/src/ui/util/TooltipButton.css b/web/src/ui/util/TooltipButton.css
new file mode 100644
index 0000000..e539546
--- /dev/null
+++ b/web/src/ui/util/TooltipButton.css
@@ -0,0 +1,36 @@
+button.with-tooltip {
+ position: relative;
+
+ div.button-tooltip {
+ display: none;
+ position: absolute;
+ z-index: 5;
+ background-color: white;
+ border: 1px solid var(--border-color);
+ padding: .25rem;
+ border-radius: .25rem;
+ text-wrap: wrap;
+ width: max-content;
+
+ &.button-tooltip-top {
+ bottom: 100%;
+ margin-bottom: .25rem;
+ }
+ &.button-tooltip-bottom {
+ top: 100%;
+ margin-top: .25rem;
+ }
+ &.button-tooltip-left {
+ right: 100%;
+ margin-right: .25rem;
+ }
+ &.button-tooltip-right {
+ left: 100%;
+ margin-left: .25rem;
+ }
+ }
+
+ &:hover > div.button-tooltip {
+ display: block;
+ }
+}
diff --git a/web/src/ui/util/TooltipButton.tsx b/web/src/ui/util/TooltipButton.tsx
new file mode 100644
index 0000000..99527f6
--- /dev/null
+++ b/web/src/ui/util/TooltipButton.tsx
@@ -0,0 +1,42 @@
+// gomuks - A Matrix client written in Go.
+// Copyright (C) 2024 Tulir Asokan
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+import { HTMLAttributes, ReactNode } from "react"
+import "./TooltipButton.css"
+
+export interface TooltipButtonProps extends HTMLAttributes {
+ tooltipDirection?: "top" | "bottom" | "left" | "right"
+ tooltipText: string
+ tooltipProps?: HTMLAttributes
+ children: ReactNode
+}
+
+const TooltipButton = ({
+ tooltipDirection, tooltipText, children, className, tooltipProps, ...attrs
+}: TooltipButtonProps) => {
+ if (!tooltipDirection) {
+ tooltipDirection = "top"
+ }
+ className = className ? `with-tooltip ${className}` : "with-tooltip"
+ const tooltipClassName = `button-tooltip button-tooltip-${tooltipDirection} ${tooltipProps?.className ?? ""}`
+ return
+}
+
+export default TooltipButton