Documentation

Liquid Glass

iOS 26 introduced Liquid Glass — the translucent, refractive material used across the system UI. Walnut treats it as a first-class part of the view vocabulary: one attribute on any element, correct APIs underneath, graceful fallback on older systems.

The two attributes

glass          : Attr msg    -- standard glass material
glassProminent : Attr msg    -- prominent / tinted / interactive glass

Use them anywhere:

-- Glass buttons
row [ spacing 12 ]
    [ button [ onTap Decrement, glass ] [ text "-" ]
    , button [ onTap Increment, glassProminent ] [ text "+" ]
    ]

-- A glass card
column [ glass, rounded 20, padding 16, spacing 8 ]
    [ el [ bold ] (text "Today")
    , text "Two walnuts cracked"
    ]

-- Glass over content
scroll []
    [ image [ height (px 320) ] "hero"
    , el [ glass, rounded 24, padding 20 ] (text "Caption on glass")
    ]

What the renderer does

ElementiOS 26+iOS 16–18 fallback
button [ glass ]UIButton.Configuration.glass().gray() configuration
button [ glassProminent ]UIButton.Configuration.prominentGlass().filled() configuration
any container with glassUIVisualEffectView + UIGlassEffectUIBlurEffect(.systemMaterial)
container with glassProminentUIGlassEffect with isInteractive = trueUIBlurEffect(.systemThickMaterial)

Use floatBottom on bars/toolbars so they sit over scrolling content — Liquid Glass needs something behind it to refract. A glass row in a plain column below the page only samples the solid background and reads as a flat gray capsule.

rounded n maps to cornerConfiguration (capsule-friendly continuous corners) so refraction follows the shape.

Version checks live in one file (the toolchain); your Walnut code never branches on OS version.

Combining with other attributes

  • tint color colors prominent glass buttons: button [ glassProminent, tint red ] [ text "Delete" ].
  • bg color is ignored under glass (the material provides the surface) — prefer tint.
  • opacity applies to the whole glass element.
  • Text and icons inside glass automatically get UIKit’s legibility treatments where the system provides them.

Design guidance

Borrowed from Apple’s Liquid Glass guidance, adapted to Walnut idioms:

  1. Glass is for the control layer, not the content layer. Buttons, bars, floating cards over content: yes. Whole screens of glass on glass: no. Keep content on bg-colored surfaces and let a few glass elements float above.
  2. Prominent glass is the accent. One glassProminent action per cluster (your primary action); glass for the rest — exactly how the system treats its own toolbars.
  3. Give glass something to refract. Over a plain white background, glass reads as gray. Put it over images, colored surfaces, or scrolling content.
  4. Test the fallback. On a pre-26 simulator your glass becomes blur — run it once to check contrast still works.

Testing glass views

Glass is data like everything else, so tests can assert it’s there:

button [ onTap Save, glassProminent ] [ text "Save" ]
--> VButton [OnTap Save, GlassProminent] [VText "Save"]

The core test suite does exactly this check on the example counter (see testViewProducesUiTree).