diff --git a/apps/design-system/content/docs/components/button.mdx b/apps/design-system/content/docs/components/button.mdx
index d4535fc407f..88b9355511f 100644
--- a/apps/design-system/content/docs/components/button.mdx
+++ b/apps/design-system/content/docs/components/button.mdx
@@ -100,13 +100,17 @@ Used for actions that are not as important as the primary action, or for actions
-### Only an icon
+### Icon-only
-Displaying only an Icon in a button.
+Render an [icon](./icons) in a button without accompanying text. Ensure the button is accessible by:
-
- We should update the button component to support this use case better.
-
+- Wrapping it in a [Tooltip](./tooltip) for sighted users.
+- Adding an `aria-label` prop for screen readers.
+- Setting its `aria-describedby` prop to `undefined` when the tooltip content repeats the label. Otherwise screen readers read the label twice.
+
+Consider also squaring off the button container as shown in the example below. For the default `tiny` size (`h-[26px]`), use `w-6.5` so the button is square.
+
+Compact icon-only buttons may also benefit from the `hit-area` utility. This increases their tap target slightly each side without changing the visual layout. See the [Table](./table#actions) component for more information.
diff --git a/apps/design-system/registry/default/example/button-icon.tsx b/apps/design-system/registry/default/example/button-icon.tsx
index e9cac7c1660..89600f1cce1 100644
--- a/apps/design-system/registry/default/example/button-icon.tsx
+++ b/apps/design-system/registry/default/example/button-icon.tsx
@@ -1,6 +1,21 @@
-import { ChevronRight } from 'lucide-react'
-import { Button } from 'ui'
+import { ExternalLink } from 'lucide-react'
+import { Button, Tooltip, TooltipContent, TooltipTrigger } from 'ui'
export default function ButtonIcon() {
- return }>
+ return (
+
+
+ }
+ // Match tooltip content for screen readers
+ aria-label="View logs"
+ // Tooltip repeats the label; clear describedby so screen readers don't hear it twice
+ // Skip this if the tooltip adds information beyond the label
+ aria-describedby={undefined}
+ >
+
+ View logs
+
+ )
}
diff --git a/packages/ui/src/components/Button/Button.tsx b/packages/ui/src/components/Button/Button.tsx
index cfba89ea915..ea4e7844d0a 100644
--- a/packages/ui/src/components/Button/Button.tsx
+++ b/packages/ui/src/components/Button/Button.tsx
@@ -119,6 +119,9 @@ const buttonVariants = cva(
rounded: {
true: 'rounded-full',
},
+ iconOnly: {
+ true: 'hit-area-1 w-6.5',
+ },
},
// Match