whisker-image — networked image component.
API shape — 1 (pure Component). See
docs/module-api-design.md
§"Shape 1". All state is captured by props; no imperative
handle. Mounts a whisker-image:Image element backed by:
- iOS:
UIImageView+ Kingfisher for URL fetching, in-memoryNSCache, and on-disk cache. - Android:
ImageView+ Coil for URL fetching,LruCache, and disk cache.
Why a separate module instead of Lynx's <image>?
Lynx ships a LynxServiceImageProtocol interface that's expected
to be implemented + registered by the host app (Lynx's own
LynxImageService uses SDWebImage on iOS / Fresco on Android,
but it's a separate subspec that consumers wire themselves). The
Whisker iOS / Android distribution doesn't include any
implementation, so a bare <image src="…"> mounts a UIImageView
whose image property never gets assigned. whisker-image skips
the Lynx image stack entirely and drives the URL load from the
native module directly — same idea as whisker-video for media
playback.
Usage
use whisker::prelude::*;
use whisker_image::{Image, ImageMode, ImageProps};
#[whisker::main]
fn app() -> Element {
render! {
Image(
src: "https://example.com/cover.jpg",
mode: ImageMode::AspectFill,
style: "width: 240px; height: 240px; border-radius: 8px;",
)
}
}
Props
src— image URL (HTTPS recommended;http://works if the host app's network security config allows cleartext).mode— content fit. Takes the typed [ImageMode] enum; defaults to [ImageMode::AspectFill].style— standard Whisker style string. Width / height must be set on the element (or via flex sizing) — Kingfisher / Coil target-size the fetched bitmap against the rendered size, so an element withwidth: 0; height: 0;would never paint.
Native source
Contributors: the matching platform module lives at
- iOS:
packages/whisker-image/ios/Sources/WhiskerImage/ImageModule.swift(view:ImageView.swift) - Android:
packages/whisker-image/android/src/main/kotlin/rs/whisker/elements/image/ImageModule.kt(view:WhiskerImageView.kt)