{"_id":"@dpawlikowski/liquid-glass","name":"@dpawlikowski/liquid-glass","dist-tags":{"latest":"0.3.0"},"versions":{"0.3.0":{"name":"@dpawlikowski/liquid-glass","version":"0.3.0","publishConfig":{"access":"public"},"description":"Pure CSS and SVG liquid glass refraction effect inspired by iOS and visionOS.","author":{"name":"Dominik Pawlikowski"},"type":"module","types":"./src/index.d.ts","sideEffects":["./src/core/liquid-glass.css"],"exports":{".":{"types":"./src/index.d.ts","import":"./src/index.js"},"./css":"./src/core/liquid-glass.css","./filter.svg":"./src/core/liquid-glass.svg","./react":{"types":"./src/react/LiquidGlass.d.ts","import":"./src/react/LiquidGlass.js"}},"scripts":{"dev":"vite --config vite.demo.config.js","build:demo":"vite build --config vite.demo.config.js","check":"node ./scripts/smoke-check.js","test":"node --test tests/*.test.js","prepack":"npm test && npm run check"},"devDependencies":{"@vitejs/plugin-react":"^4.7.0","happy-dom":"^20.10.6","playwright":"^1.61.1","react":"^19.2.7","react-dom":"^19.2.7","styled-components":"^6.4.3","vite":"^5.3.0"},"peerDependencies":{"react":">=18"},"peerDependenciesMeta":{"react":{"optional":true}},"keywords":["liquid-glass","glassmorphism","svg-filter","backdrop-filter","css","refraction","chromatic-aberration","react"],"license":"MIT","repository":{"type":"git","url":"git+https://github.com/dpawlikowski/liquid-glass.git"},"homepage":"https://dpawlikowski0.github.io/liquid-glass/","gitHead":"d0f06f35cd937cab9910d3df469ba3c672c76e8f","_id":"@dpawlikowski/liquid-glass@0.3.0","bugs":{"url":"https://github.com/dpawlikowski/liquid-glass/issues"},"_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-Qw55/OdjSTa0mfd7tg8MNjmlKa/szhplP/gyKW+1qDK4wt4vtkkAjlADWBHjTxZX3ZWi5Ier4FqfXXzgWpQeeA==","shasum":"1e90288fa6a1ec781fc32ecb38a3b0f03c5e4a4b","tarball":"https://registry.npmjs.org/@dpawlikowski/liquid-glass/-/liquid-glass-0.3.0.tgz","fileCount":17,"unpackedSize":97615,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHIY+xeptFKXB57pwHLxoBWTFpkNSvP4k+mYwTMig6HXAiEA9gQKxfkCbMJ2SuNbI7gWL8mPtgwW2Y/6XDxlFMrtuL8="}]},"_npmUser":{"name":"dpawlikowski","email":"dpawlikowski0@gmail.com"},"directories":{},"maintainers":[{"name":"dpawlikowski","email":"dpawlikowski0@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/liquid-glass_0.3.0_1783013247890_0.806791647718331"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-02T17:27:27.720Z","0.3.0":"2026-07-02T17:27:28.085Z","modified":"2026-07-02T17:27:28.353Z"},"maintainers":[{"name":"dpawlikowski","email":"dpawlikowski0@gmail.com"}],"description":"Pure CSS and SVG liquid glass refraction effect inspired by iOS and visionOS.","homepage":"https://dpawlikowski0.github.io/liquid-glass/","keywords":["liquid-glass","glassmorphism","svg-filter","backdrop-filter","css","refraction","chromatic-aberration","react"],"repository":{"type":"git","url":"git+https://github.com/dpawlikowski/liquid-glass.git"},"author":{"name":"Dominik Pawlikowski"},"bugs":{"url":"https://github.com/dpawlikowski/liquid-glass/issues"},"license":"MIT","readme":"# liquid-glass\n\n[![npm](https://img.shields.io/npm/v/@dpawlikowski/liquid-glass)](https://www.npmjs.com/package/@dpawlikowski/liquid-glass)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![Bundle size](https://img.shields.io/bundlephobia/minzip/@dpawlikowski/liquid-glass)](https://bundlephobia.com/package/@dpawlikowski/liquid-glass)\n\nLiquid glass refraction effect built entirely from CSS and SVG — no WebGL, no canvas, no runtime dependencies.\n\n- Refraction via `feTurbulence` + `feDisplacementMap` on a duplicated scene layer\n- Chromatic edge aberration via `mix-blend-mode: screen` pseudo-elements\n- Animated turbulence that auto-pauses for `prefers-reduced-motion`\n- `backdrop-filter: blur() saturate()` frosted glass surface\n- Three presets (`subtle`, `vivid`, `vision`) with full CSS variable override\n- React component with TypeScript declarations included\n\n**[Live demo →](https://dpawlikowski0.github.io/liquid-glass/)**\n\n---\n\n## Install\n\n```sh\nnpm install @dpawlikowski/liquid-glass\n```\n\n---\n\n## Quick start\n\n### HTML + vanilla JS\n\n```html\n<link rel=\"stylesheet\" href=\"node_modules/@dpawlikowski/liquid-glass/src/core/liquid-glass.css\">\n\n<div class=\"liquid-glass liquid-glass--vivid\">\n  <span class=\"liquid-glass__refraction\" aria-hidden=\"true\"></span>\n  <div class=\"liquid-glass__content\">\n    Hello\n  </div>\n</div>\n\n<script type=\"module\">\n  import { injectLiquidGlassFilter } from \"@dpawlikowski/liquid-glass\";\n  injectLiquidGlassFilter();\n</script>\n```\n\nSet `--lg-scene-background` to match your page background for strongest refraction:\n\n```css\n.liquid-glass {\n  --lg-scene-background: url(\"./bg.svg\");\n}\n```\n\n### React\n\n```jsx\nimport \"@dpawlikowski/liquid-glass/css\";\nimport { LiquidGlass } from \"@dpawlikowski/liquid-glass/react\";\n\nexport function Card() {\n  return (\n    <LiquidGlass intensity=\"vision\" style={{ \"--lg-radius\": \"36px\" }}>\n      Settings\n    </LiquidGlass>\n  );\n}\n```\n\n---\n\n## Presets\n\n| Class | Description |\n|---|---|\n| `liquid-glass--subtle` | Minimal blur, low opacity — good for chrome and overlays |\n| `liquid-glass--vivid` | Strong saturation, sharp refraction — the default |\n| `liquid-glass--vision` | visionOS-style: large radius, deep shadow, wide blur |\n\n---\n\n## CSS variables\n\n| Variable | Default | Description |\n|---|---|---|\n| `--lg-blur` | `8px` | `backdrop-filter` blur radius |\n| `--lg-saturate` | `180%` | `backdrop-filter` saturation |\n| `--lg-opacity` | `0.58` | White tint fill opacity |\n| `--lg-radius` | `24px` | Border radius |\n| `--lg-border-opacity` | `0.45` | Top/side border alpha |\n| `--lg-tint` | `255 255 255` | Tint RGB (space-separated, used in `rgb()`) |\n| `--lg-shadow` | `0 22px 70px …` | Box shadow |\n| `--lg-scene-background` | `transparent` | Background on `.liquid-glass__refraction` |\n\nOverride any variable on the element or a parent:\n\n```css\n.my-panel {\n  --lg-blur: 16px;\n  --lg-opacity: 0.3;\n  --lg-radius: 32px;\n}\n```\n\n---\n\n## JavaScript API\n\n```js\nimport {\n  injectLiquidGlassFilter,\n  updateLiquidGlassFilter,\n  setLiquidGlassMotion,\n  filterDefaults,\n  SCALE_MIN,\n  SCALE_MAX,\n} from \"@dpawlikowski/liquid-glass\";\n\n// Inject once — idempotent, safe to call multiple times.\ninjectLiquidGlassFilter({ scale: filterDefaults.scale });\n\n// Live-update without re-injection.\nupdateLiquidGlassFilter(\"liquid-glass-filter\", { scale: 14 });\n\n// Pause / resume the turbulence animation.\nsetLiquidGlassMotion(\"liquid-glass-filter\", false);\n\n// Scale is clamped to [SCALE_MIN, SCALE_MAX] = [0, 25].\nconsole.log(SCALE_MIN, SCALE_MAX); // 0 25\n```\n\n### `injectLiquidGlassFilter(options?)`\n\n| Option | Default | Description |\n|---|---|---|\n| `id` | `\"liquid-glass-filter\"` | SVG filter element id |\n| `baseFrequency` | `0.008` | `feTurbulence` base frequency |\n| `numOctaves` | `2` | Turbulence octaves |\n| `scale` | `18` | `feDisplacementMap` scale (clamped to `[0, 25]`) |\n| `seed` | `7` | Noise seed |\n| `animate` | `true` | Animate turbulence frequency |\n| `duration` | `\"7s\"` | Animation cycle duration |\n\nAll defaults are available as `filterDefaults` so you never need to hardcode them:\n\n```js\nimport { filterDefaults } from \"@dpawlikowski/liquid-glass\";\n\n// Reference defaults instead of duplicating magic numbers.\ninjectLiquidGlassFilter({ scale: filterDefaults.scale * 0.75 });\n```\n\n### `updateLiquidGlassFilter(id, options)`\n\nLive-updates scale or baseFrequency on an already-injected filter. Returns the `<filter>` element, or `null` if the id is not found.\n\n### `setLiquidGlassMotion(id, enabled, options?)`\n\nEnables or disables the `<animate>` turbulence animation. Pass `{ baseFrequency, duration }` in `options` to change animation parameters at the same time.\n\n---\n\n## React component\n\n```jsx\nimport \"@dpawlikowski/liquid-glass/css\";\nimport { LiquidGlass } from \"@dpawlikowski/liquid-glass/react\";\n\n<LiquidGlass\n  intensity=\"vivid\"       // preset suffix\n  refractive={true}       // include refraction layer\n  filterId=\"my-filter\"    // custom SVG filter id\n  as=\"section\"            // root element type\n  style={{ \"--lg-radius\": \"28px\" }}\n>\n  Glass content\n</LiquidGlass>\n```\n\n### Props\n\n| Prop | Default | Description |\n|---|---|---|\n| `intensity` | `\"vivid\"` | Preset: `\"subtle\"`, `\"vivid\"`, `\"vision\"`, or a custom suffix |\n| `refractive` | `true` | Include `.liquid-glass__refraction` layer |\n| `as` | `\"div\"` | Root element tag |\n| `filterId` | `\"liquid-glass-filter\"` | SVG filter id — the filter is injected automatically |\n| `style` | — | Forwarded; merge CSS variable overrides here |\n\nAll other props (`className`, `onClick`, `aria-*`, etc.) are forwarded to the root element.\n\n---\n\n## Browser support\n\n| Browser | Status |\n|---|---|\n| Chrome / Edge 105+ | Full |\n| Safari 16+ | Full (keep `scale ≤ 18` to avoid artifacts) |\n| Firefox 103+ | Full |\n| No `backdrop-filter` | Graceful fallback: opaque white tint |\n\n---\n\n## Performance\n\nSVG turbulence and displacement map have a real GPU cost. Follow these rules to keep the effect smooth:\n\n- Keep `scale` between `12` and `18`. Values above `25` are clamped and cause Safari artifacts.\n- Animate one or two hero surfaces — not every card on the page.\n- Use `refractive={false}` (or omit `.liquid-glass__refraction`) when exact backdrop mirroring is not needed.\n- Test on a mid-range Android device, not just a desktop browser.\n- Use `setLiquidGlassMotion(id, false)` to pause animation on low-power or battery-saver conditions.\n\n---\n\n## Development\n\n```sh\nnpm install\nnpm test            # unit tests (node:test + happy-dom)\nnpm run check       # smoke check — validates files, API surface, and CSS selectors\nnpm run dev         # interactive demo server\nnpm run build:demo  # production demo build → dist-demo/\nnpm pack            # preview the published tarball (runs test + check via prepack)\n```\n\n## Publish\n\nThe package is published as `@dpawlikowski/liquid-glass` (the unscoped `liquid-glass` name is taken on npm).\n\n```sh\nnpm login\nnpm publish --access public\n```\n\n---\n\n## License\n\nMIT © Dominik Pawlikowski\n","readmeFilename":"README.md","_rev":"1-031d9e8ff13fe157d1d14abf04e48740"}