expo-liquid-glass-view

repository·main·Indexed 43 days ago

https://github.com/rit3zh/expo-liquid-glass-view

Native liquid glass views for Expo powered by SwiftUI and expo-modules-core. Provides the LiquidGlassView and LiquidGlassContainer components to implement Apple's native glass material effects on iOS. It utilizes UIGlassEffect on iOS 26+ and a custom high-performance Metal renderer for iOS 16.4–25, with support for fine-tuning refraction, dispersion, and frost via GlassMetalOptions.

Tokens
6.8K
Snippets
32
Records
41
Agent score
56%

What's inside expo-liquid-glass-view

  1. Install expo-liquid-glass-view

    main

    To use expo-liquid-glass-view, install the package and run a prebuild for iOS. Note that this library is iOS only. On Android and web, components will render as plain views.

    npx expo install expo-liquid-glass-view
    npx expo prebuild --platform ios
    npx expo run:ios
  2. Configure Metro for monorepo/workspace environments

    main

    When using expo-liquid-glass-view in a monorepo or a workspace where the package source is located in a parent directory, you must configure metro.config.js to prevent duplicate module instances and dependency conflicts.

    Key requirements:

    1. Exclude parent node_modules: Use config.resolver.blockList to prevent Metro from bundling react and react-native from the root node_modules, which avoids version mismatches.
    2. Exclude build artifacts: If the root contains both src and build folders, add the build directory to the blockList to prevent "Tried to register two views with the same name" errors caused by duplicate native view registrations.
    3. Set nodeModulesPaths: Include both the local node_modules and the root node_modules to ensure the resolver finds necessary dependencies.
    4. Map extraNodeModules: Explicitly map the package name expo-liquid-glass-view to its source directory to ensure imports resolve correctly to the source code rather than a compiled version.
    5. Add watchFolders: Include the project root in config.watchFolders so Metro tracks changes in the source directory.
    const { getDefaultConfig } = require("expo/metro-config");
    const path = require("path");
    
    const config = getDefaultConfig(__dirname);
    const root = path.resolve(__dirname, "..");
    
    config.resolver.blockList = [
      ...Array.from(config.resolver.blockList ?? []),
      new RegExp(path.resolve(root, "node_modules", "react").replace(/\\/g, "\\\\")),
      new RegExp(path.resolve(root, "node_modules", "react-native").replace(/\\/g, "\\\\")),
      new RegExp(`^${path.resolve(root, "build").replace(/\\/g, "\\\\")}/.*$`),
    ];
    
    config.resolver.nodeModulesPaths = [
      path.resolve(__dirname, "./node_modules"),
      path.resolve(root, "node_modules"),
    ];
    
    config.resolver.extraNodeModules = {
      "expo-liquid-glass-view": path.resolve(root, "src"),
    };
    
    config.watchFolders = [root];
    
    module.exports = config;
  3. Use the LiquidGlassView component

    main

    The LiquidGlassView component provides a glass material effect. You can customize its appearance using props like variant, cornerRadius, and tint.

    Corners can be set using a single number for all corners or an object for per-corner control.

    import { LiquidGlassView } from "expo-liquid-glass-view";
    
    <LiquidGlassView
      variant="regular"
      cornerRadius={32}
      tint="#4da3ff33"
      interactive
      style={{ width: 260, height: 120 }}
      containerStyle={{ alignItems: "center", justifyContent: "center" }}
    >
      <Text style={{ color: "#fff" }}>Liquid Glass</Text>
    </LiquidGlassView>;
  4. Use LiquidGlassContainer to merge glass views

    main

    The LiquidGlassContainer component wraps sibling LiquidGlassView components so they merge into one another as they get close, mimicking system controls. This behavior is available on iOS 26+; on other platforms, it behaves as a plain View.

    Use the spacing prop to define the distance (in points) at which nested glass elements begin to merge.

    import { LiquidGlassContainer, LiquidGlassView } from "expo-liquid-glass-view";
    
    <LiquidGlassContainer spacing={40} style={{ flexDirection: "row", gap: 12 }}>
      <LiquidGlassView cornerRadius={24} style={{ width: 64, height: 64 }} />
      <LiquidGlassView cornerRadius={24} style={{ width: 64, height: 64 }} />
    </LiquidGlassContainer>;
  5. Configure LiquidGlassView renderers and check support

    main

    The renderer prop defaults to "auto". It uses UIGlassEffect on iOS 26+ and the custom Metal renderer on older versions. You can force a specific backend using renderer="native" or renderer="metal".

    To check if the device supports the native iOS 26+ glass effect, use the supportsNativeGlass boolean, which is resolved once at import.

    You can monitor which renderer is active using the onRendererChange callback.

    import { supportsNativeGlass } from "expo-liquid-glass-view";
    
    // Check support
    console.log(supportsNativeGlass);
    
    // Monitor renderer changes
    <LiquidGlassView onRendererChange={(renderer) => console.log(renderer)} />
  6. Configure the Metal renderer with metal prop

    main

    The metal prop allows fine-grained tuning of the custom Metal renderer. These settings are ignored when the renderer is set to "native" (iOS 26+). Use this prop when renderer="metal" to shape the visual characteristics like refraction, dispersion, and frost.

    <LiquidGlassView
      renderer="metal"
      metal={{
        blurRadius: 4,
        frost: 0.4,
        saturation: 1.8,
        refraction: { amount: 80, width: 24, height: 24, depth: 1 },
        dispersion: { amount: 8 },
        highlight: { intensity: 0.3, angle: 135 },
        border: { width: 1, opacity: 0.3 },
      }}
    />
  7. Reference LiquidGlassView props

    main

    The following props are available for LiquidGlassView:

    PropTypeDefaultDescription
    variant"regular" | "clear""regular"Material character. clear is thinner and less frosted.
    renderer"auto" | "native" | "metal""auto"Which backend draws the glass.
    cornerRadiusnumber | { topLeft?, topRight?, bottomRight?, bottomLeft? }0One radius for every corner, or one per corner.
    cornerStyle"continuous" | "circular""continuous"Corner curvature.
    tintColorValue—Colour washed through the glass; alpha controls strength.
    interactivebooleanfalseSystem touch response. iOS 26+ only; ignored by the Metal renderer.
    metalGlassMetalOptions—Metal-renderer tuning.
    styleStyleProp<ViewStyle>—Style for the native glass view.
    containerStyleStyleProp<ViewStyle>—Style for the wrapper around children.
    childrenReact.ReactNode—Content rendered inside the glass.
    onRendererChange(renderer) => void—Fires with "native", "metal", or "fallback-blur".
  8. Reference GlassMetalOptions (metal prop)

    main

    The metal prop accepts a GlassMetalOptions object with the following fields:

    FieldTypeDescription
    blurRadiusnumberBackdrop blur radius, in points.
    captureQualitynumberBackdrop capture resolution, as a multiplier on screen scale. Floor 0.25, default 1.
    opacitynumberOpacity of the glass layer, 0–1. Default 1.
    frostnumberHow far the backdrop is pulled toward the interface background colour.
    saturationnumberBackdrop saturation multiplier.
    noisenumberFilm grain, hiding banding in the blurred backdrop.
    lightnumberFlat brightness added before the rim sheen. Small values, 0–0.1.
    refraction.amountnumberHow far the rim drags the backdrop, in points.
    refraction.width / .heightnumberHow far in from the edges the stretch reaches.
    refraction.depthnumberDirection blend, edge normal (0) to radial (1).
    refraction.curve{ power?, bias? }Falloff shaping across the band.
    dispersion.amountnumberChromatic split along the edge, in points.
    dispersion.reachnumberHow far in from the edge the split reaches.
    highlight.intensitynumberSpecular rim strength, 0–1.
    highlight.anglenumberLight direction in degrees. Default 135.
    border.widthnumberEdge stroke width. 0 disables. Default 1.
    border.opacitynumberEdge stroke opacity.