Ir al contenido

Componentes · Ola 2 · Superposiciones

Tooltip

Texto breve que describe a un control al pasar el puntero o al enfocarlo. Es solo texto: la luz sobre el vacío, con una flecha hacia el control. Se abre con un retardo al pasar el puntero y al instante con el foco del teclado.

import { Tooltip, TooltipProvider } from '@archeblack/ui';

Ejemplos

Básico

Un botón de solo ícono con su aria-label y un tooltip que lo describe, como en el demo.

Svelte
<script lang="ts">
	import { Button, Tooltip } from '@archeblack/ui';
	import { IconCopy } from '@archeblack/ui/icons';
</script>

<!--
	El tooltip describe al botón (aria-describedby); el nombre sigue siendo el aria-label. Se abre
	con el puntero después del retardo, y al instante con el foco del teclado.
-->
<Tooltip content="Copiar ID">
	{#snippet trigger(props)}
		<Button {...props} icon={IconCopy} aria-label="Copiar ID del proyecto" />
	{/snippet}
</Tooltip>

Lados

side elige el lado: top (por defecto), right, bottom o left.

Svelte
<script lang="ts">
	import { Button, Tooltip, type TooltipSide } from '@archeblack/ui';

	const sides: { side: TooltipSide; label: string }[] = [
		{ side: 'top', label: 'Arriba' },
		{ side: 'right', label: 'Derecha' },
		{ side: 'bottom', label: 'Abajo' },
		{ side: 'left', label: 'Izquierda' }
	];
</script>

<!-- Si no entra del lado pedido, el tooltip pasa al opuesto. -->
<div style:display="flex" style:flex-wrap="wrap" style:gap="var(--arche-spacing-2)">
	{#each sides as { side, label } (side)}
		<Tooltip content="side=&quot;{side}&quot;" {side}>
			{#snippet trigger(props)}
				<Button {...props}>{label}</Button>
			{/snippet}
		</Tooltip>
	{/each}
</div>

Con proveedor

TooltipProvider comparte el retardo: después del primer tooltip, los vecinos se abren sin esperar. Va una sola vez, envolviendo el contenido del +layout.svelte raíz de la aplicación (esta documentación lo tiene ahí); sin él, cada tooltip usa los valores por defecto.

Svelte
<script lang="ts">
	import { Button, Tooltip } from '@archeblack/ui';
	import { IconBold, IconItalic, IconLink } from '@archeblack/ui/icons';
</script>

<!--
	El TooltipProvider va una sola vez, en el +layout.svelte de la aplicación (esta documentación lo
	tiene ahí). Por él, después del primer tooltip los vecinos se abren sin esperar.
-->
<div role="group" aria-label="Formato" style:display="flex" style:gap="var(--arche-spacing-1)">
	<Tooltip content="Negrita · ⌘B">
		{#snippet trigger(props)}
			<Button {...props} variant="ghost" icon={IconBold} aria-label="Negrita" />
		{/snippet}
	</Tooltip>
	<Tooltip content="Cursiva · ⌘I">
		{#snippet trigger(props)}
			<Button {...props} variant="ghost" icon={IconItalic} aria-label="Cursiva" />
		{/snippet}
	</Tooltip>
	<Tooltip content="Insertar link · ⌘K">
		{#snippet trigger(props)}
			<Button {...props} variant="ghost" icon={IconLink} aria-label="Insertar link" />
		{/snippet}
	</Tooltip>
</div>

Props

Tooltip

Props de Tooltip
PropDescripción
content string El texto del tooltip. Es solo texto: describe al disparador y nunca lleva links ni botones.
trigger Snippet<[TriggerAttributes]> El disparador, obligatorio: el tooltip lo describe y se ancla a él. Recibe los atributos del disparador (id, aria-describedby mientras está abierto, los eventos de puntero y de foco y la referencia), que se esparcen en un elemento que tome el foco, casi siempre un Button: {#snippet trigger(props)}<Button {...props}>…</Button>{/snippet}.
side? 'top' | 'right' | 'bottom' | 'left' Por defecto 'top'Lado del disparador en el que aparece. Si no entra, pasa al opuesto.
align? 'start' | 'center' | 'end' Por defecto 'center'Alineación sobre el lado elegido.
delay? number Retardo de apertura con el puntero, en ms. Por defecto, el del TooltipProvider (500). El foco lo abre sin esperar.
disabled? boolean Por defecto falseEl tooltip no se abre.
bind:open? boolean Por defecto falseSi el tooltip está abierto.
onOpenChange? (open: boolean) => void Se llama cada vez que se abre o se cierra por sí mismo (puntero, foco o Escape), con el estado nuevo. Llega después de actualizar open y solo si el cambio se aceptó: si un bind:open de función lo rechaza, no se llama.
class? ClassValue Clases del producto; se suman a arche-tooltip.
...rest HTMLAttributes<HTMLDivElement> Cualquier otro atributo va al <div role="tooltip">. El rol y el contenido los decide el componente.

TooltipProvider

Props de TooltipProvider
PropDescripción
delay? number Por defecto 500Retardo de apertura con el puntero, en ms, de todos los tooltips que envuelve.
skipDelay? number Por defecto 300Ventana en ms en la que, después de cerrar un tooltip, el siguiente se abre sin retardo.
children Snippet La aplicación. Va una sola vez, en el +layout.svelte de la raíz.

Accesibilidad

  • El contenido es un <div role="tooltip"> y, mientras está abierto, el disparador apunta a él con aria-describedby: el lector de pantalla lee primero el nombre del control y después el tooltip.
  • El tooltip describe, no nombra. Un botón de solo ícono sigue necesitando su aria-label; el tooltip puede repetirlo o sumar algo, como el atajo de teclado.
  • Se abre al pasar el puntero, después del retardo, y al instante cuando el disparador recibe el foco del teclado. Se cierra con Escape, al salir con el puntero o al perder el foco.
  • Se puede pasar el puntero del disparador al tooltip sin que se cierre, y no desaparece solo mientras el puntero o el foco siguen ahí (WCAG 1.4.13).
  • El disparador tiene que poder recibir el foco. Un <button disabled> no lo recibe ni dispara los eventos del puntero, así que su tooltip nunca aparece.
  • Texto on-primary sobre primary: el vacío sobre la luz, muy por encima de AA. En colores forzados, el tooltip lleva un borde del sistema.
  • Con movimiento reducido, aparece y desaparece sin escala ni fundido.

Qué evitar

  • Links, botones o texto largo dentro del tooltip. Un Popover: se abre con un clic, recibe el foco y admite contenido interactivo.
  • Un tooltip en lugar del nombre accesible de un botón de solo ícono. El aria-label en el botón y, si suma, un tooltip que lo describa.
  • Información imprescindible que solo está en el tooltip. Texto visible en la página o una ayuda del Field: en pantallas táctiles no hay hover.
  • Un TooltipProvider por componente o por página. Uno solo, en el +layout.svelte de la raíz.
  • Un tooltip sobre texto estático o sobre un botón deshabilitado. El texto a la vista, o explicar por qué el botón está deshabilitado junto a él.