Tooltip
Hover/focus tooltip that positions above, below, left, or right of the trigger.
Overview
The Tooltip component is a core building block of the Byteion design system, providing a robust, accessibility-compliant interface for its specific UI capabilities.
Why this exists
Tooltips provide supplementary information on hover or focus without cluttering the interface. They are the"what is this?" layer of UI.
Mental model
A tooltip appears when the user hovers or focuses on an element. It provides a brief explanation. It should never contain critical information or interactive elements.
When to use
When not to use
Basic example
The following example demonstrates standard usage, fully compliant with Byteion's token-first approach.
Placements
On icon buttons
Inline help
Your account has used 42 GB of storage this month.
import { Button, Tooltip } from '@byteion/react/client';
export default function TooltipDemo() {
return (
<div className="flex flex-wrap items-center gap-6 p-12">
<Tooltip content="Top tooltip" side="top" ><Button variant="outline">Top</Button></Tooltip>
<Tooltip content="Right tooltip" side="right" ><Button variant="outline">Right</Button></Tooltip>
<Tooltip content="Bottom tooltip" side="bottom"><Button variant="outline">Bottom</Button></Tooltip>
<Tooltip content="Left tooltip" side="left" ><Button variant="outline">Left</Button></Tooltip>
<Tooltip content="Delete this row permanently" tone="danger">
<Button aria-label="Delete" iconOnly variant="soft" tone="danger">
<i className="ti ti-trash" />
</Button>
</Tooltip>
</div>
);
}
<script setup lang="ts">
import { Button, Tooltip } from '@byteion/vue';
</script>
<template>
<div class="flex flex-wrap items-center gap-6 p-12">
<Tooltip content="Top tooltip" side="top" ><Button variant="outline">Top</Button></Tooltip>
<Tooltip content="Right tooltip" side="right" ><Button variant="outline">Right</Button></Tooltip>
<Tooltip content="Bottom tooltip" side="bottom"><Button variant="outline">Bottom</Button></Tooltip>
<Tooltip content="Left tooltip" side="left" ><Button variant="outline">Left</Button></Tooltip>
<Tooltip content="Delete this row permanently" tone="danger">
<Button aria-label="Delete" icon-only variant="soft" tone="danger">
<i class="ti ti-trash" />
</Button>
</Tooltip>
</div>
</template>
Variants
Each variant communicates a different meaning. Choose based on priority, not aesthetics.
Single default variant.
Sizes
Size should match the importance and context of the component.
- md — md size.
States
This component reacts seamlessly to the following interaction and data states:
- hidden — Not rendered in the DOM.
- visible — Rendered and interactive.
- default — Resting appearance before interaction.
- hover — Pointer is over the element — visual feedback via color or shadow.
- focus — Keyboard or tab focus — shows ring indicator for accessibility.
- active — Currently selected or in use.
- disabled — Non-interactive — grayed out, cursor not-allowed.
- open — Component is expanded or visible.
- closed — Component is collapsed or hidden.
Anatomy
Usage guidelines
- Keep text under 60 characters.
- Show after 500ms delay (not instant).
- Never put interactive elements inside a tooltip.
Do and Don't
Do
- Keep text short.
- Add a delay before showing.
- Show on focus for keyboard users.
Don't
- Do not put links or buttons inside.
- Do not show instantly — add delay.
- Do not use for critical information.
Accessibility
Tooltip uses role="tooltip" with aria-describedby on the trigger. Also appears on focus, not just hover.
Role:tooltip
ARIA Attributes
aria-describedby
Keyboard Navigation
- Escape: Closes the overlay or cancels the action
Customization
Background and text color follow popover tokens. Z-index uses --z-tooltip.
Compose with React cva()
Use the exportedcva() +cn() utilities to compose your own variant on top of the Byteion tokens.
import { cva, cn, type VariantProps } from '@byteion/react';
const myTooltip = cva('base classes…', {
variants: {
accent: { soft:'border-primary-200', loud:'border-primary-500' },
},
defaultVariants: { accent:'soft' },
});
type Props = React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof myTooltip>;
Compose with Vue cva()
Use the exportedcva() +cn() utilities inside standard Vue setup blocks.
<script setup lang="ts">
import { computed, useAttrs } from 'vue';
import { cva, type VariantProps } from '@byteion/vue';
interface Props { accent?:'soft' |'loud' }
const props = withDefaults(defineProps<Props>(), { accent:'soft' });
const attrs = useAttrs();
const myTooltip = cva('base classes…', {
variants: { accent: { soft:'border-primary-200', loud:'border-primary-500' } },
});
const cls = computed(() => myTooltip({ accent: props.accent, class: attrs.class as string | undefined }));
</script>
Runtime events
Byteion keeps framework APIs idiomatic: HTML uses DOM custom events, React uses callback props, and Vue uses emitted events / v-model updates.
HTML / JS events
bi:tooltip:hidebi:tooltip:show
React callbacks
onOpenChange(open: boolean) => void
Vue emits
update:open[v: boolean]
Remote / AJAX
This component does not implement Byteion JS remote loading. Use normal HTML form submission, framework state, or your application data layer around it.
API Reference
Requires data-bi-component="tooltip" with data-bi-tooltip="content".
HTML Data Attributes
data-bi-tooltipdata-bi-tooltip-placement
React Props · TooltipProps
Extracted directly fromreact/src/components/Tooltip.tsx.
export interface TooltipProps {
content: ReactNode;
/** The triggering element (must accept ref + aria props). */
children: ReactElement<any>;
side?: 'top' | 'right' | 'bottom' | 'left';
/** Delay before showing on hover, in ms. */
delay?: number;
/** Controlled open state. */
open?: boolean;
onOpenChange?: (open: boolean) => void;
className?: string;
}
Vue Props · TooltipProps
Extracted directly fromvue/src/components/Tooltip.vue.
export interface TooltipProps {
content?: string;
side?: 'top' | 'right' | 'bottom' | 'left';
/** Delay before showing on hover, in ms. */
delay?: number;
/** Controlled open state. */
open?: boolean;
}
Developer tips
overflow-hidden parents. Verify the tooltip renders outside the clipped container.
• Always pair icon-only buttons with aria-label: the tooltip is not an accessible name replacement.
• Viewport edges: near edges, tooltip should flip to stay visible (check your positioning library support).Common mistakes
Production usage tips
- Test hover and keyboard focus on every trigger — tooltips must be focus-triggered.
- Test Escape dismissal — supported via
useEscapeKeyin both React and Vue. - Test dark mode and branded themes — tooltip uses
bg-foreground/text-backgroundwhich invert automatically. - Test viewport edges — near edges the tooltip should flip to stay visible (check your positioning library's collision detection).
- Test icon-only buttons with screen readers —
aria-labelmust be present; the tooltip is additional, not primary. - Test on touch devices — provide visible fallback text for important guidance that cannot live in tooltips alone.
- Keep React and Vue APIs aligned with the core HTML schema —
content/sideprops map todata-bi-tooltip/data-bi-tooltip-placement.
Premium examples
Advanced patterns available in Byteion Pro:
prefers-reduced-motion via motion-safe:animate-fade-inRelated components
Unlock Premium Patterns
Get access to copy-paste ready Pro blocks, SaaS templates, and advanced data-tables built with this component.
Explore Pro Components