Skip to content
phantom-ui v0.10.0

Changelog

2026-05-06

  • Duplicate custom element registration (#10, #11). phantom-ui can now be imported multiple times without throwing `NotSupportedError`. The `@customElement` decorator was replaced with a guarded `customElements.define()` call, making the library safe for micro-frontends, lazy-loaded modules, dynamic imports, and HMR / hot reload environments.

First-load behavior is unchanged. Re-imports become a no-op.

2026-05-02

  • `debug` attribute that outlines each measured block with an index for visual inspection of how phantom-ui interprets the DOM. Leaf blocks get pink outlines with numeric indices, container blocks get blue outlines with C-prefixed indices.
  • HTMX added to the supported frameworks list
  • Qwik SSR usage example
  • `aria-busy` accessibility behavior documented

2026-04-13

  • shimmer-direction attribute — control the direction of the shimmer sweep: ltr (default), rtl, ttb, or btt. Only applies to animation="shimmer".
  • Upgraded Biome to v2.4
  • Upgraded TypeScript to v6.0
  • Added HTMX framework guide and example app
  • Added direction control to the interactive demo page
  • Fixed Solid attr:loading to properly remove attribute using ternary pattern
  • Added data fetching example to Angular app
  • 30 tests (5 new for shimmer-direction)

2026-04-10

  • Extracted light-DOM styles and JSX types into separate files for cleaner architecture
  • Replaced inline style strings with Lit styleMap in block rendering
  • Disconnected MutationObserver during measurement to prevent double re-trigger from table cell text measurement
  • data-shimmer-width or data-shimmer-height set alone no longer silently skips the element
  • Removed dead tag field from ElementInfo
  • Removed HR duplicate from VOID_TAGS (already in ALWAYS_LEAF_TAGS)

2026-04-10

  • Container replication on count: When count > 1, repeated skeleton rows now replicate the slotted element’s background, border, border-radius, and box-shadow. Previously only the first row showed the card styling.

Benchmarked the DOM measurement pipeline:

ElementsLeaf nodesTime
100334~20ms
5001,667~25ms
1,0003,334~31ms
  • Added tests verifying container blocks are emitted for styled elements and skipped for transparent ones (25 total)
  • Performance section in README and How It Works page
  • Card-based count example in demo playground
  • Favicon on standalone demo page
  • Body scroll lock when mobile settings sheet is open

2026-04-10

  • JSX types: added key, ref, data-* attributes and style object to PhantomUiAttributes for React/Solid compatibility
  • JSDoc on every prop: hover documentation for all attributes in supported IDEs
  • Updated code examples: use class instead of className (React 19+ supports it natively)
  • React Query + phantom-ui interactive demo (StackBlitz)
  • Redesigned demo page: ghost SVG hero, Get Started / GitHub stars nav
  • Version badge in docs header (fetched from npm at build)
  • Landing page button polish and social icon colors

2026-04-09

  • loading="false" treated as falsy — No more || undefined workaround. Pass booleans directly in React <19, Qwik, Solid, and vanilla HTML. React 19+, Vue, and Svelte already handled this natively.

  • Auto-generated changelog — Docs now include a Changelog page pulled from GitHub releases at build time. Stays up to date automatically on every deploy.

  • Redesigned demo controls: ghost mascot toggle button with bounce animation
  • Handwritten “click me!” chalk annotation on desktop
  • Mobile: floating action button + bottom sheet for settings (swipe to close)
  • Compact bottom sheet layout: 2-column grid for colors and sliders
  • Responsive dashboard card grid (4→2 columns on mobile)
  • Ghost-style back button with arrow icon
  • Landing page cards with subtle colored borders and tinted backgrounds
  • Matched docs background colors to demo page (dark/light)
  • Improved data fetching guide: clarified that layout structure is the skeleton, no fake placeholder text needed
  • Removed || undefined pattern from all code examples across docs, README, and framework guides

2026-04-09

  • data-shimmer-ignore: elements with data-shimmer-ignore now properly stay visible during loading. Previously, light DOM styles (-webkit-text-fill-color: transparent, opacity: 0) were hiding text and media inside ignored zones.
  • Added tests verifying data-shimmer-ignore keeps text and images visible during loading state.
  • Standalone interactive demo page with 11 card types, sticky controls bar, and theme switcher
  • Custom moon/sun theme toggle component for docs
  • Package manager tabs (npm/pnpm/yarn/bun) on all install commands
  • Data fetching guide with TanStack Query, SWR, and Vue composable patterns
  • Improved light mode contrast and purple accent color
  • Fixed default color values in README

2026-04-09

SSR pre-hydration CSS — Prevents content flash before JavaScript hydrates. The postinstall script now auto-detects SSR frameworks (Next.js, Nuxt, SvelteKit, Remix, Qwik) and injects import "@aejkatappaja/phantom-ui/ssr.css" into your layout file.

data-shimmer-width / data-shimmer-height — Override measured dimensions for elements that have no size yet (images without explicit width/height, JS-filled containers). Elements with zero dimensions are normally skipped — these attributes force a skeleton block.

CLI tests — 54 bun tests covering framework detection, SSR detection, CSS injection, indentation preservation, and idempotency.

2026-04-08

  • Hide buttons during loading — buttons and [role="button"] elements are now hidden (opacity: 0) during loading state, preventing colored backgrounds from bleeding through the shimmer blocks

2026-04-08

  • Fix border visibility during loading — borders using currentColor (e.g. border: 2px solid) are no longer hidden by the loading styles
  • Neutral default colors — shimmer defaults changed from white-based to neutral gray, now visible on both light and dark backgrounds
  • Docs and playground updated to reflect new defaults

2026-04-08

  • Media load re-measurement — Skeleton blocks re-measure automatically when images/videos finish loading via a capture-phase load listener. Images without explicit width/height are picked up once they load.
  • Deep descendant hiding — All nested elements (not just direct slot children) are now hidden during loading. A light DOM stylesheet targets phantom-ui[loading] * to hide deeply nested images, text, and media.
  • Reveal transition fix — The reveal fade-out now works correctly. The overlay stays in the DOM during the CSS opacity transition instead of being removed and recreated.
  • Animated SVG preview — Replaced the 2.7MB preview GIF in the README with lightweight animated SVGs.
  • Browser test suite — 19 tests running on Chromium, Firefox, and WebKit via @web/test-runner + Playwright.
  • Interactive playgroundbun run playground serves a local test page with controls for every attribute.
  • Contributing guide — Added CONTRIBUTING.md with setup, testing, and PR guidelines.
  • CI improvements — Test job added to CI pipeline, Playwright browsers cached for faster runs.
  • Framework examples — README examples now showcase more attributes (animation, stagger, reveal, count) and include a React list example with repeat mode.
  • Examples point to local package — All framework examples in examples/ now use file:../.. instead of a pinned npm version.
  • Input validationcount clamped to minimum 1, count-gap clamped to minimum 0.
  • Repo cleanup — Removed unused preview.gif and logo.svg, moved README assets to .github/assets/.

2026-04-08

  • count attribute — Generate multiple skeleton rows from a single template element. Useful for lists, tables, and feeds where data isn’t loaded yet.
  • count-gap attribute — Control spacing (in pixels) between repeated skeleton rows.
  • Input validation: count is clamped to minimum 1, count-gap to minimum 0.
<phantom-ui loading count="5" count-gap="8">
<div class="user-row">
<img src="avatar.png" width="32" height="32" />
<span>John Doe</span>
<span>john@acme.io</span>
</div>
</phantom-ui>

2026-04-07

New animation modes, stagger effect, reveal transition, and accessibility.

  • 4 animation modes: shimmer (default), pulse, breathe, solid
  • Stagger attribute: progressive delay between blocks for wave effect
  • Reveal attribute: smooth fade-out when loading ends
  • aria-busy automatically set on host element
  • Updated demo page and documentation with new controls

2026-04-07

Fix shimmer animation on Firefox and improve loop smoothness.

  • Gradient now uses block background color at edges instead of transparent, eliminating the visible gap between animation cycles
  • Moved gradient declaration out of keyframes (Firefox cannot interpolate between full background shorthand values)
  • Changed easing from ease-in-out to linear for seamless looping
  • Fixed slotted leaf elements (p, img, span) not being captured as skeleton blocks

2026-04-06

Fix: slotted leaf elements (p, img, span) were not captured as skeleton blocks when they were direct children of the slot.

2026-03-30

Add repository field for webcomponents.org

2026-03-30

Structure-aware skeleton loader. One Web Component, every framework.

  • Wrap your real UI in <phantom-ui loading> and get perfect shimmer placeholders automatically
  • Works in React, Vue, Svelte, Angular, Solid, Qwik, and plain HTML
  • ~8kb gzipped CDN build (Lit included)
  • Runtime DOM measurement via getBoundingClientRect()
  • CSS custom properties for theming
  • data-shimmer-ignore and data-shimmer-no-children for fine-grained control
  • TypeScript types with auto-generated JSX declarations
  • Starlight documentation site

bun add @aejkatappaja/phantom-ui