Skip to content

Latest commit

 

History

History
241 lines (179 loc) · 8.84 KB

File metadata and controls

241 lines (179 loc) · 8.84 KB

Lume logo

@staticcanvas/lume

npm-version jsr-version codecov license

Lume is a lightweight, zero-dependency JavaScript tooltip engine providing mutation-aware DOM lifecycle management, collision detection, and hardware-accelerated positioning.


Highlights

  • Zero Dependencies — Pure vanilla ESM/CJS build with a small production bundle checked against a 5 KB gzip budget.
  • Single-Node DOM Recycling — Reuses a single .lume-tooltip element to eliminate DOM bloat and thrashing.
  • Hardware-Accelerated Positioning — 60fps positioning powered by translate3d(x, y, 0).
  • Priority-Aware Collision Detection — Evaluates the complete tooltip rectangle, follows ordered fallback sides, and clamps only as a final safeguard near viewport edges.
  • Mutation-Aware Lifecycle — Automatically discovers newly inserted DOM elements and purges orphan tooltips without re-binding.
  • Formatting Tokens — Supports safe text formatting tokens, lists, line breaks, and composite pastel styles using the {/lme} terminator.
  • Editor Syntax Support — Includes VS Code, Neovim, and Zed LIRL syntax definitions in the repository's editors/ directory.
  • Trusted HTML Mode — Renders application-owned data-lume-content only with allowHTML: true; untrusted content must remain in text mode.
  • Reference Presentation Tiers — Minimal, simple, and advanced layouts support structured LIRL content.
  • Visual Decorations — Includes a CSS-only outlined info icon and custom-color pastel status dots.
  • Viewport-Safe Content — Constrains width and keeps unusually tall content inside the tooltip content region.
  • Configurable Interaction — Supports hover/focus or click/tap activation, motion presets, intensity, delays, alignment, boundaries, custom containers, and per-trigger overrides.
  • Optional Diagnostics — Metrics and debug modules can be loaded separately when needed.
  • Accessible — First-class keyboard focus/blur support and WAI-ARIA roles (role="tooltip", aria-hidden).

Installation

npm install @staticcanvas/lume
# Or using pnpm / yarn / bun
pnpm add @staticcanvas/lume
yarn add @staticcanvas/lume
bun add @staticcanvas/lume

Quick Start

1. Import JavaScript and CSS

import { Lume } from '@staticcanvas/lume';
import '@staticcanvas/lume/css';

// Automatically discovers and binds [data-lume] and [data-lume-content] elements
const lume = new Lume();

2. Add Markup

<!-- Basic Tooltip -->
<button data-lume="Save your project changes">Save</button>

<!-- Tooltip with Title and Custom Direction -->
<button
  data-lume="Export your dataset as CSV, JSON, or XML."
  data-lume-title="Export Options"
  data-lume-direction="bottom"
>
  Export
</button>

<!-- Inline Help Badge -->
<span class="lume-inline" data-lume="Contextual information preview"> More Info </span>

Trusted HTML content

Use HTML mode only for application-owned markup. It is not an HTML sanitizer.

const lume = new Lume({ allowHTML: true });
<button data-lume-content="<strong>Status:</strong> <span>Online</span>">Account status</button>

HTML content can be styled with .lume-tooltip and custom classes. Omit data-lume-title when the HTML body is the complete tooltip.


Declarative Data Attributes

Attribute Type Default Description
data-lume string "" Plain-text tooltip content with optional Lume formatting tokens.
data-lume-title string "" Optional header title rendered in .lume-header.
data-lume-direction string "top" Preferred direction: "auto", "top", "bottom", "left", or "right".
data-lume-priority string "top,bottom,right,left" Comma-separated fallback order for automatic and smart placement.
data-lume-offset number 14 Distance in pixels between target element and tooltip.
data-lume-content string "" Explicit content source; rendered as HTML only with allowHTML.
data-lume-icon string "" Application-owned SVG URL or info for the outlined info icon.
data-lume-dot CSS color "" Optional single-color status dot with pastel presentation.
data-lume-dot-position direction left Position of the status dot.
data-lume-class string "" Custom CSS class modifier for per-element styling.
data-lume-action hover | click hover Per-element interaction model.
data-lume-motion preset fade Per-element motion preset.
data-lume-intensity number 1 Per-element motion intensity from 0 through 3.
data-lume-smart boolean true Per-element collision detection override.

Programmatic API

import { Lume } from '@staticcanvas/lume';

const lume = new Lume({
  offset: 16, // Default pixel offset
  smart: true, // Enable collision flip
  className: 'theme', // Global custom class
  motion: 'lift',
  motionIntensity: 1,
  showDelay: 0,
  hideDelay: 0,
  padding: 10,
});

const button = document.querySelector('#action-btn');

// Show tooltip on a specific element
lume.show(button);

// Force position recalculation (e.g. after layout changes)
lume.reposition();

// Hide active tooltip
lume.hide();

// Destroy instance and remove DOM nodes
lume.destroy();

Framework Integration

React

import { useEffect } from 'react';
import { Lume } from '@staticcanvas/lume';
import '@staticcanvas/lume/css';

export function MyComponent() {
  useEffect(() => {
    const lume = new Lume();
    return () => lume.destroy();
  }, []);

  return (
    <button data-lume="Saved to cloud" data-lume-title="Status">
      Save
    </button>
  );
}

Vue 3

<script setup>
import { onMounted, onUnmounted } from 'vue';
import { Lume } from '@staticcanvas/lume';
import '@staticcanvas/lume/css';

let lume;

onMounted(() => {
  lume = new Lume();
});

onUnmounted(() => {
  lume?.destroy();
});
</script>

<template>
  <button data-lume="Vue Tooltip" data-lume-direction="bottom">Hover me</button>
</template>

Styling & CSS Variables

Easily theme tooltips using CSS custom properties:

:root {
  --lume-bg: #0f172a;
  --lume-text: #f8fafc;
  --lume-accent: rgba(255, 255, 255, 0.15);
  --lume-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3);
  --lume-radius: 8px;
  --lume-font-size: 13px;
  --lume-max-width: 280px;
}

Optional diagnostics

Diagnostics are separate modules so the core runtime remains focused:

import { createLumeMetrics } from '@staticcanvas/lume/metrics';
import { createLumeDebug } from '@staticcanvas/lume/debug';

const metrics = createLumeMetrics(lume);
const debug = createLumeDebug(lume);
console.table(metrics.snapshot());
// metrics.dispose();
// debug.dispose();

Links


License

Distributed under the MIT License. See LICENSE for more information.