Skip to content

Atoms

The smallest building blocks — a single visual idea each, with no internal composition of other ThemeKit components.

50 atoms. Every example below feeds modifiers with semantic color tokens (SemanticColor cases, theme.foreground(_:)…) — never a raw Color or CGFloat literal. See the DocC reference for the full API.

GIF/APNG animated image via ImageIO — no third-party dependency.

AnimatedImage(gifURL).contentMode(.fit).cornerRadius(16) // GIF/APNG via ImageIO — no dependency

A breathing glow halo behind a view, or standalone.

card.aura(.primary) // breathing glow halo · Aura().color(.purple).size(120).intensity(0.7)

Circular or square user avatar — initials, image, or icon, with a presence dot. AvatarGroup stacks a set of avatars with overflow.

Avatar(.initials("AB")).size(.md).presence(.online)

Small status/label pill with an icon and a semantic style.

Badge("Label").badgeStyle(.info).icon("star.fill")

Code 128 barcode generated on-device, with an optional caption.

Barcode("9824097217421298").height(56).showsValue() // Code 128, no dep

An animated light beam that travels around a view’s border.

card.borderBeam(cornerRadius: 16, lineWidth: 2)

Selectable filter/tag pill with a tonal or solid style.

Chip("Recommended", isSelected: $selected).chipStyle(.tonal)

Terminal-style code mockup with per-line semantic highlights.

CodeBlock([CodeLine("npm i themekit", prefix: "$"), CodeLine("Done!", prefix: ">", highlight: .success)]).copyable()

A one-shot celebratory confetti burst, triggerable from any view.

Confetti().pieceCount(60) // or: view.confetti(trigger: submissions)

.countBadge(_:) / .dotBadge() overlay a numeric or dot badge on any view; Ribbon wraps a corner banner around a card.

icon.countBadge(5) // .dotBadge() · Ribbon("New") { card }

Live HH:MM:SS countdown with an urgency escalation past a threshold.

CountdownTimer(until: deadline).style(.urgent).format(.boxed).size(.large).showsDays(false)

A horizontal or vertical rule with an optional inline title.

DividerView("OR").dashed().titleAlign(.center)

Included/excluded fare feature row with an icon and a status.

FareFeatureRow("Checked bag", systemImage: "suitcase.fill", detail: "1 × 20 kg", status: .included) // .included/.excluded/.info

Flight status pill — on-time, boarding, delayed, cancelled…

FlightStatusBadge(.delayed).time("+35m").solid() // on-time/boarding/delayed/cancelled…

Circular or linear gauge for a bounded value, with a label.

GaugeView(value: 0.72, label: "CPU").gaugeStyle(.circular).showsValue()

SF Symbol wrapper with a token-bound size and color.

Icon(systemName: "star.fill").size(.md).color(theme.foreground(.fgHero))

Rounded, accent-tinted icon tile used as a shared leading glyph.

IconTile("suitcase.fill").accent(.turquoise).size(46) // shared leading tile

Small dot or custom badge overlay modifier for any view.

icon.indicatorDot() // or .indicator { Badge("3") }

Paragraph text with tappable inline links.

InlineText("Accept the Terms.", links: [("Terms", { })]).inlineStyle(.bodyBase400).color(tint)

Form field label with a required asterisk and an info glyph.

InputLabel("Email").required().hasInfo()

Groups a row of views into one connected cluster with rounded outer corners.

Join(.horizontal) { ButtonA; ButtonB; ButtonC } // connected group, rounded outer corners

A keyboard-key glyph, for shortcuts and hints.

Kbd("").size(.lg) Kbd("K").size(.lg) // xs/sm/md/lg

Clips a view to a circle, squircle, hexagon, or star.

image.themeMask(.squircle) // .circle / .squircle / .hexagon / .star

Loyalty points/miles pill for earn, redeem, and balance states.

PointsBadge(1_250).unit("mil").style(.earn).size(.large).showsSign(true) // .earn · .redeem · .balance

Currency price display with a struck-through original price and an auto discount badge.

PriceTag(1_299).original(1_899).unit("/ night").size(.large).emphasis(.hero).discountBadge() // .free() · .soldOut() · .from() · .fractionDigits(2)

Linear progress bar with a percentage readout and step markers; StepIndicator renders discrete step dots.

ProgressBar(value: 0.4).showsPercentage()

Scannable QR code generated on-device via CoreImage.

QRCode("https://themekit.dev/pass/BID12025").size(160) // CoreImage, no dep

Circular ring progress indicator with an optional dashboard style.

RadialProgress(0.6).size(96).accent(.purple).showsLabel()

Star rating control with half-star and tap-to-rate support.

Rating(value: 4.5).allowHalf().onRate { value = $0 }

Async-loaded image with aspect ratio, corner radius, and circle clipping.

RemoteImage(url, ratio: "16:9").cornerRadius(12) // .gif/.apng animate natively

Odometer-style rolling-digit animation for numeric values.

RollingNumber(1284).size(40) // odometer digit roll

Compact numeric score badge (e.g. a review score).

ScoreBadge(9.0, large: false)

Small pill for search-context chips (dates, guests, filters).

SearchBadge("SAW") // soft-blue pill; .colors(background:foreground:) · .icon("bolt.fill")

Wraps the native SwiftUI ShareLink in ThemeKit styling.

ShareButton(item: url) // wraps SwiftUI ShareLink

Redacted-placeholder loading shimmer for any content.

Text("Loading…").skeleton(isLoading)

Loading spinner with ring, dots, bars, ball, or infinity styles.

Spinner().style(.dots).accent(.success).size(24) // ring/dots/bars/ball/infinity

Status dot with a label and an optional pulse animation.

StatusDot(.online, label: "Online").pulse()

Two-state icon toggle that crossfades between two symbols.

Swap(isOn: $on).symbols(on: "xmark", off: "line.3.horizontal")

Circular action button for flipping two bound values (e.g. origin/destination).

SwapButton { swap(&from, &to) }.size(34) // action flip; see Swap for the on/off toggle

Removable label pill with a semantic color and a solid/soft variant.

Tag("Sold out", onRemove: { }).tagStyle(.error).variant(.solid)

A tappable inline link with underline and accent color.

TextLink("Forgot password?") { }.accent(.primary) // .underline(false) to remove

Rotates through a list of strings on a timer.

TextRotate(["faster.", "themed.", "accessible."], interval: 2)

Touch/hover 3D tilt effect with spring-back and an optional specular shine.

card.tilt3D(shine: true) // drag to tilt · TiltCard { … }.maxAngle(.degrees(12))

Section title with a subtitle and a trailing action.

Title("Section").subtitle("Sub").action("See all", action: { })

Tiles a faint, rotated label across a view for provenance on exports (Ant Watermark).

ReportCard().watermark("CONFIDENTIAL", rotation: .degrees(-22))