UNPKG

ranui

Version:

A framework-agnostic Web Components UI library built on native custom elements, with TypeScript types, light/dark theming, SSR and PWA support.

106 lines (105 loc) 4.88 kB
import { RanElement } from '../../utils'; /** * `r-glass` — a liquid / frosted glass surface. * * Frosts and refracts whatever is behind it: `backdrop-filter` blur + saturate * for the frost, an SVG `feDisplacementMap` (strength = `displace`) for the * liquid light-bending, plus a specular rim/highlight. All visual knobs are * exposed as attributes and `--ran-glass-*` tokens; content goes in the default * slot. Parts: `glass` (the pane), `specular` (the highlight layer). * * Backdrop note: this samples the DOM behind the host — the portable technique. * A full WebGL/WebGPU shader path that rasterizes the *backdrop itself* into a * texture would look more "liquid" and work identically across browsers, but * costs the backdrop's interactivity/accessibility (buttons, selectable text, * live video behind the glass all become a flat pixel buffer) and a much * heavier bundle — deliberately not pursued here. * * `rim` is the middle ground: an opt-in WebGL layer (see `rim.ts`) that adds a * more physically-lit specular edge + chromatic fringe, computed purely from * the panel's own shape (never the backdrop), so it costs none of that. */ export declare class Glass extends RanElement { _shadowDom: ShadowRoot; private _glass; /** The specular layer the rim renderer mounts into. */ private _specular; private _turb; private _disp; private _uid; private _events; private _tabIndexOwnedByComponent; private _rimRenderer; static get observedAttributes(): string[]; constructor(); /** Backdrop saturation, as a percentage number (e.g. `180`). */ get saturate(): string; set saturate(v: string); /** Liquid refraction strength — the SVG displacement scale. `0` is a flat pane. */ get displace(): string; set displace(v: string); /** Turbulence base frequency — smaller = larger, smoother liquid ripples. */ get frequency(): string; set frequency(v: string); /** Corner radius, in px. */ get radius(): string; set radius(v: string); /** Glass fill tint (any CSS background value). */ get tint(): string; set tint(v: string); /** Animated specular sweep across the surface. */ get sheen(): boolean; set sheen(v: boolean); /** * Hover lift + press-scale feedback, for clickable glass. Also makes the host * a keyboard-operable button: `role="button"`, a tab stop (unless the consumer * already set one), and Enter/Space dispatch a click — see `_syncInteractive`/ * `_onKeydown`. */ get interactive(): boolean; set interactive(v: boolean); /** * Opt-in GPU specular rim + chromatic edge, lit from a fixed top-left light — * shape-only, never samples the backdrop (see the class doc for why that's the * point). Renders on WebGL first, always; transparently upgrades to WebGPU in * the background if available (same pixel output, not a performance change — * see `rim-webgpu.ts`). Silently falls back to the plain CSS specular gradient * when neither GPU API is available (old browser, disabled, SSR). See `rim.ts`. */ get rim(): boolean; set rim(v: boolean); /** Inject the per-instance SVG displacement filter (client only, once). */ private _ensureFilter; /** * Lazily create the rim renderer — only while `rim` is set, so a page that * never uses it never spends one of the browser's limited WebGL/WebGPU * context slots. `createRimRenderer` owns its own canvas(es) and resize * tracking (see `rim.ts`) — this just mounts it into the specular layer and * keeps it alive across disconnect/reconnect, same as the SVG displacement * filter above; only `_teardownRim` frees it, when `rim` is explicitly * turned back off. */ private _ensureRim; private _teardownRim; private _apply; /** Set a host custom property, appending a unit only when the value is bare-numeric. */ private _setVar; /** * `interactive` makes the whole panel a click target (see the `sheen`/hover-lift * CSS — "for clickable glass"), so it needs the same keyboard activation a real * `<button>` gets for free: Enter/Space act like a click. Mirrors r-button's and * r-colorpicker's swatch keydown handler. */ private _onKeydown; /** * role="button" + a tab stop only while `interactive` — a purely decorative * glass panel must stay out of the tab order and off the accessibility tree; * without this a keyboard/screen-reader user had no way to tell (or reach) * that a glass panel was clickable at all. */ private _syncInteractive; connectedCallback(): void; disconnectedCallback(): void; attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void; } export default Glass;