{
  "name": "tooltip",
  "title": {
    "es": "Tooltip",
    "en": "Tooltip"
  },
  "summary": {
    "es": "Etiqueta breve al pasar el ratón o enfocar.",
    "en": "Short label on hover or focus."
  },
  "category": "disclosure",
  "status": "stable",
  "nivel": "componentes",
  "updated": "2026-09-29",
  "license": "MIT",
  "page": "https://componentes-lovat.vercel.app/c/tooltip/",
  "requires": [
    "button"
  ],
  "files": [
    {
      "type": "html",
      "url": "https://componentes-lovat.vercel.app/raw/tooltip/tooltip.html",
      "content": "<div class=\"c-tooltip-row\">\n  <button class=\"c-btn c-btn--outline c-btn--icon\" type=\"button\" aria-label=\"Negrita\" aria-describedby=\"tip-bold\" data-c-tooltip=\"tip-bold\">\n    <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8\"/></svg>\n  </button>\n  <button class=\"c-btn c-btn--outline c-btn--icon\" type=\"button\" aria-label=\"Cursiva\" aria-describedby=\"tip-italic\" data-c-tooltip=\"tip-italic\">\n    <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M19 4h-9\"/><path d=\"M14 20H5\"/><path d=\"M15 4 9 20\"/></svg>\n  </button>\n  <button class=\"c-btn c-btn--outline\" type=\"button\" aria-describedby=\"tip-save\" data-c-tooltip=\"tip-save\">Guardar</button>\n</div>\n<div class=\"c-tooltip\" id=\"tip-bold\" role=\"tooltip\" popover=\"manual\">Negrita · ⌘B</div>\n<div class=\"c-tooltip\" id=\"tip-italic\" role=\"tooltip\" popover=\"manual\">Cursiva · ⌘I</div>\n<div class=\"c-tooltip\" id=\"tip-save\" role=\"tooltip\" popover=\"manual\">Se guarda en tu navegador</div>\n"
    },
    {
      "type": "css",
      "url": "https://componentes-lovat.vercel.app/raw/tooltip/tooltip.css",
      "content": "/* tooltip · Componentes (MIRÓ Labs). Diseño de coss ui (MIT, © coss.com, antes Origin UI).\n   Generado por tools/build_css.py desde tooltip.tw.json. No editar a mano. Necesita tokens.css. */\n.c-tooltip{position:relative;display:flex;border-radius:calc(var(--radius) - 2px);border-style:var(--tw-border-style);border-width:1px;background-color:var(--popover);padding-inline:calc(var(--spacing)*2);padding-block:calc(var(--spacing)*1);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));text-wrap:balance;color:var(--popover-foreground);--tw-shadow-alpha:5%;--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000000d),0 2px 4px -2px var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}\n@supports (color:lab(0% 0 0)){\n.c-tooltip{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,lab(0% 0 0/.05)),0 2px 4px -2px var(--tw-shadow-color,lab(0% 0 0/.05))}\n}\n.c-tooltip{transition-property:width,height,scale,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}\n.c-tooltip:not(:is(.dark *)){background-clip:padding-box}\n.c-tooltip:before{content:var(--tw-content);pointer-events:none;content:var(--tw-content);position:absolute;content:var(--tw-content);inset:calc(var(--spacing)*0);content:var(--tw-content);border-radius:calc(var(--radius-md) - 1px);content:var(--tw-content);--tw-shadow:0 1px var(--tw-shadow-color,#0000000a)}\n@supports (color:color-mix(in lab, red, red)){\n.c-tooltip:before{--tw-shadow:0 1px var(--tw-shadow-color,color-mix(in oklab,var(--color-black)4%,transparent))}\n}\n.c-tooltip:before{box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}\n.c-tooltip:is(.dark *):before{content:var(--tw-content);--tw-shadow:0 -1px var(--tw-shadow-color,#ffffff0f)}\n@supports (color:color-mix(in lab, red, red)){\n.c-tooltip:is(.dark *):before{--tw-shadow:0 -1px var(--tw-shadow-color,color-mix(in oklab,var(--color-white)6%,transparent))}\n}\n.c-tooltip:is(.dark *):before{box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}\n/* propio */\n.c-tooltip{position:fixed;margin:0;inset:auto;max-width:16rem;color:var(--popover-foreground);opacity:0;scale:.98;transition:opacity .15s,scale .15s,overlay .15s allow-discrete,display .15s allow-discrete}\n.c-tooltip:popover-open{opacity:1;scale:1}\n@starting-style{.c-tooltip:popover-open{opacity:0;scale:.98}}\n.c-tooltip-row{display:flex;flex-wrap:wrap;gap:.5rem;align-items:center}\n"
    },
    {
      "type": "js",
      "url": "https://componentes-lovat.vercel.app/raw/tooltip/tooltip.js",
      "content": "/* Tooltip: aparece al pasar el ratón (tras 400 ms) o al enfocar con teclado; Esc lo cierra.\n   Se puede pasar el ratón encima sin que se cierre (WCAG 1.4.13). El texto también va en aria-describedby. */\n(function () {\n  const C = (window.Componentes = window.Componentes || {});\n  const DELAY = 400, SKIP = 300, HIDE = 100;\n  let lastHidden = 0, current = null;\n\n  function place(trigger, tip) {\n    const r = trigger.getBoundingClientRect(), w = tip.offsetWidth, h = tip.offsetHeight;\n    const above = r.top - 6 - h >= 0;\n    tip.style.top = (above ? r.top - 6 - h : r.bottom + 6) + 'px';\n    tip.style.left = Math.max(8, Math.min(r.left + r.width / 2 - w / 2, innerWidth - w - 8)) + 'px';\n    tip.style.transformOrigin = above ? 'bottom center' : 'top center';\n  }\n\n  function setup(trigger) {\n    const tip = document.getElementById(trigger.dataset.cTooltip);\n    if (!tip || !tip.showPopover) return;\n    let showT, hideT;\n    const show = (now) => {\n      clearTimeout(hideT);\n      clearTimeout(showT);\n      const run = () => {\n        if (current && current !== tip && current.matches(':popover-open')) current.hidePopover();\n        if (!tip.matches(':popover-open')) tip.showPopover();\n        place(trigger, tip);\n        current = tip;\n      };\n      if (now || Date.now() - lastHidden < SKIP) run(); else showT = setTimeout(run, DELAY);\n    };\n    const hide = () => {\n      clearTimeout(showT);\n      hideT = setTimeout(() => { if (tip.matches(':popover-open')) { tip.hidePopover(); lastHidden = Date.now(); } }, HIDE);\n    };\n    trigger.addEventListener('pointerenter', (e) => { if (e.pointerType === 'mouse') show(false); });\n    trigger.addEventListener('pointerleave', hide);\n    tip.addEventListener('pointerenter', () => clearTimeout(hideT));\n    tip.addEventListener('pointerleave', hide);\n    trigger.addEventListener('focus', () => { if (trigger.matches(':focus-visible')) show(true); });\n    trigger.addEventListener('blur', hide);\n    trigger.addEventListener('pointerdown', () => { clearTimeout(showT); if (tip.matches(':popover-open')) tip.hidePopover(); });\n    document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && tip.matches(':popover-open')) { tip.hidePopover(); lastHidden = Date.now(); } });\n  }\n\n  function init(root) {\n    (root || document).querySelectorAll('[data-c-tooltip]:not([data-c-ready])').forEach((t) => {\n      t.dataset.cReady = '';\n      try { setup(t); } catch (e) { console.warn('[tooltip]', e); }\n    });\n  }\n\n  C.tooltip = { init };\n  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', () => init());\n  else init();\n})();\n"
    },
    {
      "type": "standalone",
      "url": "https://componentes-lovat.vercel.app/r/tooltip.html"
    }
  ],
  "tokensFile": "https://componentes-lovat.vercel.app/tokens.css",
  "darkTheme": "add class 'dark' to <html>",
  "contexto": "ambos",
  "densidad": "media",
  "tono": "sobria",
  "states": [
    "rest",
    "open"
  ],
  "use": {
    "es": [
      "Para nombrar botones con icono o dar un atajo."
    ],
    "en": [
      "To name icon buttons or show a shortcut."
    ]
  },
  "avoid": {
    "es": [
      "Para información importante: en pantallas táctiles no hay hover."
    ],
    "en": [
      "For important information: touch screens have no hover."
    ]
  },
  "a11y": {
    "roles": [
      "tooltip"
    ],
    "keyboard": [
      {
        "keys": "Tab",
        "es": "Muestra el tooltip al enfocar",
        "en": "Shows the tooltip on focus"
      },
      {
        "keys": "Esc",
        "es": "Lo oculta",
        "en": "Hides it"
      }
    ],
    "notes": {
      "es": [
        "El texto también va en aria-describedby.",
        "Se puede pasar el ratón encima sin que desaparezca (WCAG 1.4.13)."
      ],
      "en": [
        "The text is also in aria-describedby.",
        "You can hover the tooltip without it disappearing (WCAG 1.4.13)."
      ]
    },
    "test": {
      "es": [
        "Enfoca «Negrita» con Tab: aparece «Negrita · ⌘B»; Esc lo oculta."
      ],
      "en": [
        "Tab to “Bold”: “Bold · ⌘B” appears; Esc hides it."
      ]
    }
  },
  "issues": {
    "es": [],
    "en": []
  },
  "credits": [
    {
      "source": "coss ui (MIT) · tooltip.tsx",
      "url": "https://coss.com/ui"
    },
    {
      "source": "W3C WAI-ARIA APG, Tooltip",
      "url": "https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/"
    }
  ],
  "changes": [
    {
      "date": "2026-09-29",
      "es": "Diseño de coss ui en HTML, CSS y JS sin dependencias",
      "en": "coss ui design in dependency-free HTML, CSS and JS"
    }
  ],
  "partes": [],
  "pieza": "https://componentes-lovat.vercel.app/r/tooltip.html"
}
