View DSL
Complete reference for the SwiftUI-like declarative view builder available to extensions.
View DSL
Extensions build their UI using the global View object — a declarative, SwiftUI-inspired view builder. Views render natively as SwiftUI components; there is no HTML or DOM.
Layout
View.hstack(children, options?)
Horizontal stack layout.
View.hstack([
View.icon("music.note"),
View.text("Now Playing"),
], { spacing: 8, align: "center" })Options:
| Option | Type | Default | Description |
|---|---|---|---|
spacing | number | 8 | Gap between children |
align | "top" | "center" | "bottom" | "center" | Cross-axis alignment |
distribution | "leading" | "center" | "trailing" | "spaceBetween" | "leading" | Main-axis distribution |
View.vstack(children, options?)
Vertical stack layout.
View.vstack([
View.text("Title", { style: "headline" }),
View.text("Subtitle", { color: "#888" }),
], { spacing: 4, align: "leading" })View.zstack(children)
Layered stack (Z-axis). Children are stacked on top of each other.
View.spacer(minLength?)
Flexible space that fills available room.
View.hstack([
View.text("Left"),
View.spacer(),
View.text("Right"),
])View.scroll(child, options?)
Scrollable container.
View.scroll(
View.vstack(items.map(i => View.text(i))),
{ axes: "vertical", showsIndicators: false }
)Content
View.text(value, options?)
View.text("Hello world", {
style: "caption", // "caption2" | "caption" | "footnote" | "subheadline" | "body" | "headline" | "title3" | "title2" | "title" | "largeTitle"
color: "#e8e8e8", // hex color
lineLimit: 1, // max lines (0 = unlimited)
bold: true, // bold weight
italic: false,
})View.icon(name, options?)
SF Symbols icon by name.
View.icon("star.fill", {
size: 16, // points
color: "#f59e0b", // hex or system color name
})Common icons: music.note, battery.75percent, calendar, cloud.sun.fill, bell.fill, wifi, speaker.wave.2, moon.fill, timer, checkmark.circle, xmark.circle, star.fill, heart.fill, arrow.up, arrow.down
View.image(url, options?)
Remote or local image.
View.image("https://example.com/avatar.png", {
width: 32,
height: 32,
cornerRadius: 16, // circular
})View.progress(value, options?)
Linear progress bar.
View.progress(0.65, {
total: 1.0,
color: "#a855f7",
})View.circularProgress(value, options?)
Circular progress ring.
View.circularProgress(0.75, {
total: 1.0,
lineWidth: 3,
color: "#a855f7",
})View.gauge(value, options?)
System gauge view.
View.gauge(72, {
min: 0,
max: 100,
label: View.text("CPU"),
})View.divider()
Horizontal separator line.
Interactive
View.button(label, actionID)
Tappable button. Fires onAction(actionID) when tapped.
View.button(
View.text("Start", { style: "caption", color: "#a855f7" }),
"start-timer"
)View.toggle(isOn, label, actionID)
Toggle switch. Fires onAction(actionID, newValue).
View.toggle(
DynamicIsland.store.get("enabled") ?? false,
View.text("Enable"),
"toggle-enabled"
)View.slider(value, min, max, actionID)
Slider. Fires onAction(actionID, newValue) on change.
View.slider(0.5, 0.0, 1.0, "set-opacity")Modifiers
Modifiers wrap a view and return a new view node.
View.padding(child, options?)
View.padding(View.text("Padded"), { edges: "all", amount: 8 })
// edges: "all" | "horizontal" | "vertical" | "top" | "bottom" | "leading" | "trailing"View.frame(child, options?)
View.frame(View.icon("star"), { width: 32, height: 32 })
View.frame(content, { maxWidth: Infinity }) // full widthView.background(child, color)
View.background(View.text("Chip"), "rgba(168,85,247,0.15)")View.cornerRadius(child, radius)
View.cornerRadius(View.image(url), 12)View.opacity(child, value)
View.opacity(View.text("Dim"), 0.5)View.animate(child, kind)
Looping animation on the child.
View.animate(View.icon("waveform"), "pulse")
// kind: "pulse" | "bounce" | "spin" | "blink"Special
View.when(condition, thenNode, elseNode?)
Conditional rendering.
View.when(
isRunning,
View.text("● Running", { color: "#22c55e" }),
View.text("○ Stopped", { color: "#888" })
)View.timerText(seconds, options?)
Formatted countdown / timer display.
View.timerText(1500, { style: "headline" })
// Renders: "25:00"View.mascot(options?)
Render the user's selected mascot companion.
View.mascot({ size: 48, expression: "happy" })Shared components
DynamicIsland.components.inputComposer(options)
A pre-built text input bar (used by WhatsApp extension).
DynamicIsland.components.inputComposer({
placeholder: "Reply...",
text: DynamicIsland.store.get("draft") ?? "",
action: "send-message",
clearAfterSend: true,
})