glendix/js/environment

Reads browser environment preferences behind a typed boundary.

This module hides window.matchMedia so widgets never call it directly and never keep an application-local FFI for reading the color-scheme preference. The queries report the operating-system preference as a typed value, and a separate query resolves what actually applies when the preference is left to the system.

Dynamic preference-change subscriptions (MediaQueryList change events) are intentionally out of scope. A widget re-queries these functions during its own props- or revision-driven re-render; when and how to re-render, the default theme, and the palette all remain application policy.

The color scheme is often built into a plain JavaScript object and passed to an external React component as a single prop. glendix/js/object builds the object from ordered typed entries, and glendix/binding passes it through a Redraw attribute without any application-local React FFI:

import glendix/binding
import glendix/js/environment
import glendix/js/object
import redraw
import redraw/dom/attribute

pub fn themed_component(
  component component: binding.JsComponent,
) -> redraw.Element {
  let theme = case environment.resolved_color_scheme() {
    environment.ResolvedDark -> "dark"
    environment.ResolvedLight -> "light"
    environment.ResolutionUnavailable -> "light"
  }
  // `object.from_entries` preserves entry order and keeps the last value for
  // a duplicate key; the object becomes one external-component prop.
  let configuration =
    object.from_entries([#("theme", object.string(theme))])
  binding.element(
    component,
    [attribute.attribute("config", object.from_object(configuration))],
    [],
  )
}

Types

Represents the operating-system color-scheme preference.

pub type ColorScheme {
  Light
  Dark
  System
}

Constructors

  • Light

    The system explicitly prefers a light color scheme.

  • Dark

    The system explicitly prefers a dark color scheme.

  • System

    No explicit preference is expressed, or the preference cannot be read.

Represents the color scheme that actually applies after resolving System.

pub type ResolvedColorScheme {
  ResolvedLight
  ResolvedDark
  ResolutionUnavailable
}

Constructors

  • ResolvedLight

    A light color scheme applies, including the default when no preference is expressed.

  • ResolvedDark

    A dark color scheme applies.

  • ResolutionUnavailable

    The preference cannot be resolved because matchMedia is unavailable.

Values

pub fn color_scheme() -> ColorScheme

Reads the operating-system color-scheme preference.

Returns System both when no explicit preference is expressed and when matchMedia is unavailable, because neither case names a concrete scheme.

pub fn resolved_color_scheme() -> ResolvedColorScheme

Resolves the color scheme that applies, treating System as light.

Returns ResolutionUnavailable when matchMedia cannot be queried, so an unavailable environment is distinct from a resolved light preference.

Search Document