PrismGlow
Spectral light cones that rise from an edge and flow left to right.
Installation
pnpm add @talex-touch/tuffex
import { TxPrismGlow } from '@talex-touch/tuffex/prism-glow'
import '@talex-touch/tuffex/prism-glow/style.css'
import '@talex-touch/tuffex/base.css' // tokens + resets, once per app
Usage
Card
The root is the card: put the background and radius on the root, and the light paints over that background and under the slot.
Loading demo...
Collapse on Grow
When the host grows, the light sinks into its edge in about 140ms instead of fading, and stays off until active is switched off and on again.
Loading demo...
Overlay
Without a slot, it sits behind a host's content, as in the CoreBox search bar. The host must be a stacking context; position the root absolutely at z-index: -1.
Loading demo...
Best Practices
- Turn it on only while work is in progress: set
activetotruewhen it starts and back tofalsewhen it ends. Don't use it as permanent decoration. - When the glow sits in a fixed-height part, point
growTargetat the outer container that grows; turncollapseOnGrowoff only for hosts that grow while loading. - The component renders no text and announces nothing; pair it with visible status text or a
role="status"region (sr-only is fine). - Put the background on the root or the host, never on the slot, or it covers the light.
- Keep the main text away from the edge the light rises from, and use one per view.
API Reference
Props
| Name | Type | Default | Description |
|---|---|---|---|
active | boolean | true | On / off; fades in over 0.3s, fades out over 0.45s, then unmounts. |
palette | 'spectrum' | 'accent' | 'spectrum' | spectrum spans the whole wheel; accent uses neighbouring hues of --tx-color-primary. |
placement | 'bottom' | 'top' | 'bottom' | The edge the light rises from; it flows left to right either way. |
intensity | number | 1 | Light-layer opacity, clamped to 0–1; non-finite counts as 1. The slot is unaffected. |
duration | number | 6 | Base flow period in seconds; smaller is faster. Falls back to 6 unless positive and finite. |
collapseOnGrow | boolean | true | Sinks the light into its edge in about 140ms when the watched element grows over 8px. |
growTarget | HTMLElement | null | null | The element collapseOnGrow watches; null means the component root. |
Slots
| Slot | Description |
|---|---|
default | Content rendered above the light layer; leave it out to use the component as an overlay. |
CSS Variables
The props write these into the root's inline style; change them through the props:
| Variable | Source | Description |
|---|---|---|
--tx-prism-glow-intensity | intensity | Light-layer opacity, clamped to 0–1. |
--tx-prism-glow-duration | duration | Base flow period, with its s unit. |
These are declared on the root, with defaults for light and dark surfaces:
| Variable | Light | Dark | Description |
|---|---|---|---|
--tx-prism-glow-l / --tx-prism-glow-c | 0.76 / 0.19 | 0.74 / 0.19 | oklch lightness and chroma of the cone colour. |
--tx-prism-glow-l-core / -c-core / -a-core | 0.78 / 0.18 / 0.5 | 0.95 / 0.05 / 0.78 | Lightness, chroma, and alpha of the core along the edge. |
--tx-prism-glow-a-halo | 0.22 | 0.3 | Alpha of the halo. |
--tx-prism-glow-a-fringe | 0.3 | 0.44 | Alpha of the two dispersion fringes. |
--tx-prism-glow-a-ray | 0.05 | 0.07 | Alpha of the vertical rays. |
--tx-prism-glow-blend | normal | plus-lighter | Blend mode between cones. |
--tx-prism-glow-reach | 1 | 1 | Cone height factor; 0.45 in high contrast, 0 on the leaving layer during a collapse. |
- To override them, use a selector more specific than the component's theme blocks (light is
.tx-prism-glow, dark is:is([data-theme='dark'], .dark) .tx-prism-glow), and give dark its own rule. --tx-pg-*are internal and not part of the API.
Overview
- The root,
div.tx-prism-glow, carriestx-prism-glow--{palette}andtx-prism-glow--{placement}(plusis-collapsingduring a collapse) andisolation: isolate, making it its own stacking context; itsposition: relativesits in:where(), at zero specificity. - The light layer,
.tx-prism-glow__field, isabsolute; inset: 0; z-index: -1: it paints over the root's background and under the slot, is clipped to the root's radius, and isaria-hidden="true"with no pointer events. - While the light is on or fading out, it collapses once the watched element is more than 8px taller than its lowest height since the light came on, pinning the leaving layer to the pre-growth height. Shrinking and changes within 8px never trigger it, and after a collapse it stays off until
activeturns on again. - Dark is detected from an ancestor: under
[data-theme='dark']or.darkthe dark tuning applies (near-white core,plus-lighterblending); otherwise the light tuning. There is no theme prop. - Under reduced motion, every animation and transition stops, the six cones hold one finished frame spread edge to edge, and the layer appears and disappears with
activeat once. - In high contrast (
html.contrast,html[data-tx-contrast='high'], orprefers-contrast: morewithouthtml[data-tx-contrast='normal']), the cones shrink to a band along the edge and the rays are hidden.
Technologies
- Motion is compositor-only (
translate,scale,opacity); no keyframe reads avar()and there is no JS frame loop, so the flow stays smooth while the main thread is busy. - The look is inspired by Unicorn Studio's "New AI canvas loading state" clip, posted by George Hastings (@soulegit) on 2026-09-23. Only the look was borrowed; no code came from it.
- Source:
packages/tuffex/packages/components/src/prism-glow/, with the cone parameters incones.ts.
View source
packages/tuffex/packages/components/src/prism-glow/index.ts
Use cases
- A loading or working state on a card, input, search bar, or message composer.
- The wait during a long AI generation (a canvas, an image, a long answer).
- The "searching" state of the CoreBox search bar.
Related components
- BorderBeam: a beam that travels along or breathes around a border; it draws the border, not cones rising from an edge.
- ThinkingOrb: a standalone orb with its own
label; to light up a card or input that is already there, use PrismGlow. - GlowText: a shine that sweeps across text or a card.