npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@get-set/gs-tooltip

v1.0.2

Published

Get-Set Tooltip

Readme

@get-set/gs-tooltip

A dependency-free, fully accessible tooltip / popover plugin available in two flavours from one codebase:

  • Native / vanilla JS — a window.GSTooltip(selectorOrElement, params) factory (also exposed as a jQuery plugin and an HTMLElement.prototype method), plus zero-config auto-init for any [data-gs-tooltip] element.
  • React — a <GSTooltip /> forwardRef component that wraps a single child and renders the floating tooltip through a portal.

Both surfaces drive one shared core (actions/, constants/, helpers/, types/), so behaviour is identical across the two — every option works in both targets (except the few tagged React-only / native-only below).

Features

  • 12 RTL-aware placementstop, bottom, left, right, each with -start / -end alignment variants, with auto-flip on viewport collision and auto-shift to stay on screen.
  • 5 entrance/exit animationsfade, scale, shift-away, shift-toward, perspective (plus none), each honoring prefers-reduced-motion.
  • Combinable triggershover, focus, click, manual (Bootstrap-style 'hover focus' strings, arrays, or single values).
  • Smooth follow-cursortrue / 'horizontal' / 'vertical' / 'initial'.
  • Interactive tooltips — keep open while the pointer is over the box, with a configurable hover bridge.
  • Per-phase delaysshowDelay / hideDelay, or the delay shorthand.
  • Arrow — toggleable, size-configurable, auto-centered and clamped.
  • Themingdark / light / auto (follows prefers-color-scheme) / custom, plus an accentColor, and rich glass / gradient / elevated surface classes.
  • First-class a11yrole="tooltip", automatic aria-describedby wiring, and Escape-to-close.
  • Robust positioningappendTo any container, boundaryPadding, skidding / distance offset, sticky reposition on scroll/resize, and hide-on-scroll-out-of-view.
  • Touch support, disabled state, hideOnClick, RTL, per-part customClass overrides, and a React-only scoped-styles gsx prop.

Compatibility

| Target | Requirement | |---|---| | React (the <GSTooltip> component) | React 16.8+ (Hooks + forwardRef), and 17 / 18 / 19. React is an optional peer dependency — you only need it for the component. | | Native / vanilla (window.GSTooltip) | No framework. Any modern evergreen browser. Optional jQuery ($(...).GSTooltip(...)) and HTMLElement.prototype.GSTooltip(...) adapters are registered automatically by the bundle. | | TypeScript | First-class — type declarations (.d.ts) ship in the package. | | SSR / Next.js | Safe to import server-side (the portal is client-gated). The tooltip is browser-only, so render it inside a Client Component ('use client'). |

The peer range is ^16.8.0 || ^17.0 || ^18.0 || ^19.0, with react/ react-dom marked optional so the native build has zero dependencies.

Project layout

GSTooltip.ts                 # native entry (webpack -> dist-js/bundle.js, window global)
components/GSTooltip.tsx      # React component (tsc -> dist/, npm entry)
actions/                     # shared engine (init/show/hide/update/animate/refresh/destroy)
constants/                   # animations, placements, default params
helpers/                     # layout, content, position, ui helpers
types/                       # Params / Ref / Window augmentation
components/styles/            # SCSS + compiled CSS + CSS-as-TS (runtime injection for React)
styles/                      # SCSS + compiled CSS (for <link> use by the native build)

Install

npm install @get-set/gs-tooltip

Build & test

npm install
npm run build          # builds both targets
npm run build:js       # native bundle -> dist-js/bundle.js
npm run build:react    # React + types  -> dist/
npm test               # vitest

See example.html for a runnable native showcase exercising placements, animations, triggers, follow-cursor, themes, and the imperative API.


Usage — Native JS

Load the bundle and the stylesheet, then construct the tooltip. The factory accepts either a CSS selector string or a DOM element as its first argument.

<link rel="stylesheet" href="node_modules/@get-set/gs-tooltip/styles/GSTooltip.css" />
<script src="node_modules/@get-set/gs-tooltip/dist-js/bundle.js"></script>

<button id="save">Save</button>

<script>
  // (a) by selector string
  GSTooltip('#save', {
    reference: 'save-tip',
    content: 'Save your changes',
    placement: 'top',
    animation: 'scale'
  });

  // (b) by element — both forms are supported
  const el = document.getElementById('save');
  GSTooltip(el, { reference: 'save-tip-2', content: 'Same, via element' });
</script>

The factory returns a ref object with the full imperative API:

const tip = GSTooltip('#save', { reference: 'save', content: 'Hi', trigger: 'manual' });
tip.show();
tip.hide();
tip.toggle();
tip.isVisible();          // boolean
tip.setContent('Updated');
tip.setProps({ theme: 'light', placement: 'bottom' });
tip.enable();
tip.disable();
tip.isEnabled();          // boolean
tip.update();             // recompute position
tip.refresh();            // rebuild from current params
tip.destroy();            // tear down + unregister

Auto-init via [data-gs-tooltip]

Any element carrying data-gs-tooltip is initialized automatically on load — no JavaScript required. data-gs-placement and data-gs-theme are read too, and a native title is promoted to the content (and removed to avoid a double tip).

<button data-gs-tooltip="Auto tooltip" data-gs-placement="bottom" data-gs-theme="light">
  Hover me
</button>

The window.GSTooltipConfigue registry

Every instance is registered under its reference (a GUID is generated when you omit one):

GSTooltip('#save', { reference: 'save', content: 'Hi' });

const tip = window.GSTooltipConfigue.instance('save'); // -> the ref
tip.show();
window.GSTooltipConfigue.references;                    // -> [{ key, ref }, ...]

Usage — jQuery

The bundle auto-registers $.fn.GSTooltip when jQuery is present. It passes the element to the factory for each matched node:

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="node_modules/@get-set/gs-tooltip/dist-js/bundle.js"></script>

<script>
  $('.has-tip').GSTooltip({ content: 'From jQuery', placement: 'right' });
</script>

Usage — HTMLElement.prototype

The bundle also registers HTMLElement.prototype.GSTooltip, so any element can tooltip itself (the element is passed to the factory):

document.querySelector('#save').GSTooltip({
  content: 'From the prototype method',
  trigger: 'hover focus'
});

Usage — React

<GSTooltip> wraps a single child (the reference element) and portals the floating tooltip out. Pass options as props; drive it imperatively via ref.

'use client';
import { useRef } from 'react';
import GSTooltip, { GSTooltipHandle } from '@get-set/gs-tooltip';

export default function Demo() {
  const tip = useRef<GSTooltipHandle>(null);

  return (
    <>
      <GSTooltip
        ref={tip}
        content="Save your changes"
        placement="top"
        animation="scale"
        trigger="hover focus"
        theme="auto"
        arrow
        interactive>
        <button>Save</button>
      </GSTooltip>

      <button onClick={() => tip.current?.show()}>Show programmatically</button>
    </>
  );
}

content may be a string, an HTML string (with allowHTML), or any React node:

<GSTooltip content={<strong>Rich <em>node</em> content</strong>}>
  <span>hover</span>
</GSTooltip>

The ref handle — GSTooltipHandle

| Method | Signature | Description | |---|---|---| | show | () => void | Show the tooltip. | | hide | () => void | Hide the tooltip. | | toggle | () => void | Toggle visibility. | | isVisible | () => boolean | Whether the tooltip is currently visible. | | setContent | (content: ReactNode) => void | Replace the tooltip content. | | update | () => void | Recompute the tooltip position. | | enable | () => void | Enable triggers. | | disable | () => void | Disable triggers (hides if open). | | isEnabled | () => boolean | Whether triggers are enabled. | | destroy | () => void | Tear down: unmount the tooltip and unregister it. |

Controlled vs. uncontrolled

// Uncontrolled (default): triggers drive it; defaultVisible sets the initial state.
<GSTooltip content="x" defaultVisible><button>x</button></GSTooltip>

// Controlled: you own the `visible` prop.
<GSTooltip content="x" visible={open} onShow={...} onHide={...}>
  <button>x</button>
</GSTooltip>

React-only gsx (scoped styles)

gsx injects a <style> scoped to this instance via [data-key], added on mount and removed on unmount:

<GSTooltip
  content="Branded"
  theme="custom"
  gsx={{
    '.gs-tooltip-content': { background: '#7c3aed', color: '#fff' },
    '.gs-tooltip-arrow': { background: '#7c3aed' }
  }}>
  <button>Hover</button>
</GSTooltip>

Props

Every option works in both the native params object and as a React prop, unless tagged. Native-only options resolve elements; React derives the reference from the wrapped child.

| Prop | Type | Default | Description | |---|---|---|---| | reference | string | auto GUID | Stable key used in the registry. | | content | string (native) / ReactNode (React) | '' | Tooltip content. | | allowHTML | boolean | false | Treat a string content as raw HTML instead of escaped text. | | placement | GSTooltipPlacement | 'top' | Preferred placement (12 variants). | | flip | boolean | true | Auto-flip to the opposite side on viewport collision. | | shift | boolean | true | Shift along the side to stay in the viewport. | | boundaryPadding | number | 8 | Padding (px) kept between the tooltip and the viewport edge. | | offset | { skidding?: number; distance?: number } | { skidding: 0, distance: 8 } | Shift along the side / gap from the reference. | | trigger | GSTooltipTrigger | 'hover focus' | How the tooltip opens (combinable). | | showDelay | number | 0 | Delay (ms) before showing. | | hideDelay | number | 0 | Delay (ms) before hiding. | | delay | number \| { show?: number; hide?: number } | — | Combined delay shorthand (overrides showDelay/hideDelay). | | hideOnClick | boolean | true | Hide when the reference / outside is clicked. | | interactive | boolean | false | Keep open while the pointer is over the tooltip. | | interactiveBorder | number | 6 | Hover-bridge padding (px) for interactive tooltips. | | followCursor | boolean \| 'horizontal' \| 'vertical' \| 'initial' | false | Follow the cursor while hovering. | | touch | boolean \| 'hold' | true | Touch support (tap, or long-press with 'hold'). | | animation | GSTooltipAnimation \| false | 'fade' | Entrance/exit animation. false disables motion. | | animationDuration | number \| { enter?: number; exit?: number } | 200 | Animation duration in ms. | | animationEasing | string | cubic-bezier(.16,1,.3,1) | CSS easing for the animation. | | reducedMotion | 'auto' \| boolean | 'auto' | Honor prefers-reduced-motion. | | arrow | boolean | true | Show the pointing arrow. | | arrowSize | number | 8 | Arrow size in px. | | theme | 'dark' \| 'light' \| 'auto' \| 'custom' | 'auto' | Visual theme. | | accentColor | string | — | Accent / background color (CSS var --gst-bg). | | maxWidth | number \| string | 300 | Max width. Number = px; string = raw CSS. | | zIndex | number | 9999 | z-index of the floating tooltip. | | rtl | boolean | false | Right-to-left layout. | | customClass | { box?, content?, arrow? } | — | Per-part class overrides. | | className | string | — | Extra class on the tooltip box. | | appendTo | 'body' \| 'parent' \| string \| HTMLElement \| ref | 'body' | Where to append the floating tooltip. | | disabled | boolean | false | Start disabled (no triggers fire). | | aria | boolean | true | Wire aria-describedby on the reference. | | hideOnScroll | boolean | true | Hide when the reference scrolls out of view. | | sticky | boolean | true | Reposition on scroll/resize while open. | | target | selector / element / ref (native) | the constructed element | Explicit reference element(s). | | gsx | NestedCSS (React-only) | — | Scoped inline styles injected for this instance. | | visible | boolean (React-only) | — | Controlled visibility. | | defaultVisible | boolean (React-only) | false | Uncontrolled initial visibility. | | beforeShow | () => void \| boolean | — | Fired before showing. Return false to cancel. | | afterShow | () => void | — | Fired after the show transition is set up. | | beforeHide | () => void \| boolean | — | Fired before hiding. Return false to cancel. | | afterHide | () => void | — | Fired after the tooltip has fully hidden. | | onPosition | (placement) => void | — | Fired whenever the tooltip is repositioned. | | onShow | () => void (React-only) | — | Fired when the tooltip shows. | | onHide | () => void (React-only) | — | Fired when the tooltip hides. |


Catalogs

Placements (placement, 12)

top, top-start, top-end, bottom, bottom-start, bottom-end, left, left-start, left-end, right, right-start, right-end.

The -start / -end variants align the tooltip to the start / end edge of the reference along the cross axis (RTL-aware).

Animations (animation)

| Name | Motion | |---|---| | fade | Opacity only. | | scale | Opacity + scale from 0.85. | | shift-away | Slides in away from the reference side. | | shift-toward | Slides in toward the reference side. | | perspective | 3D perspective tilt + lift. | | none | No motion (also the reduced-motion fallback). |

Triggers (trigger)

hover, focus, click, manual — combine with a space/comma string ('hover focus'), an array (['click', 'focus']), or a single value. manual disables all built-in triggers (control via the imperative API only).

Themes (theme)

dark, light, auto (follows prefers-color-scheme), custom (chrome comes entirely from accentColor / gsx / customClass). Add a gs-tooltip-glass, gs-tooltip-gradient, or gs-tooltip-elevated class (via className / customClass.box) for the rich surface variants.

follow-cursor (followCursor)

true (both axes), 'horizontal' (X only), 'vertical' (Y only), 'initial' (positioned at the pointer once on open, then anchored), false (anchored to the reference).


License

ISC © Get-Set