Skip to content

Organisms

Complete, self-contained sections — cards, overlays, and full booking-flow surfaces composed from atoms and molecules.

73 organisms. 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.

A collapsible content section.

Accordion("Title", initiallyExpanded: false) { Text("Body") }

A group of accordions with single- or multi-expand modes.

AccordionGroup(faqs) { $0.q } content: { Text($0.a) }.mode(.single)

An OTA/agent price comparison row.

AgentPriceRow("Trip.com") { open() }.logo(url).rating(4.2).badge("Cheapest").original(4_100).price(3_538).cta("Go to site").recommended()

A toast/snackbar notification card.

AlertToast("Saved").variant(.success).onClose { }

An add-on/ancillary purchase row with a quantity stepper.

AncillaryCard("Checked baggage").icon("suitcase.fill").subtitle("20 kg").price(450, suffix: "/ bag").quantity($bags, range: 0...4) // or .added($on)

A blog/article preview card.

BlogCard(title: "") { mediaView }.excerpt("").readMore { }

A boarding-pass card with gate, seat, and barcode.

BoardingPass(passenger: "Alex Morgan", from: "SAW", to: "BER").airline("Pegasus").flightNo("PC 1234").times(departure: "13:15", arrival: "16:05").gate("A12", seat: "14C", boarding: "12:45").barcode("")

A presented bottom sheet with configurable detents.

// install once: .sheetHost()
@Environment(SheetPresenter.self) var sheet: SheetPresenter
sheet.present(detents: [.height(280), .large]) { FilterView() }
// or declarative: someView.bottomSheet(isPresented: $open, detents: [.medium]) { … }

Browser-chrome mockup frame around any content.

BrowserFrame(url: "https://themekit.dev") { content }.accent(.primary)

An inline message callout.

Callout("Message").variant(.success).calloutStyle(.plain)

The base surface/shell container — every card-family organism routes its shell through CardStyle.

Card { content }.elevation(.soft)

An auto-playing media carousel with arrows.

Carousel(items) { item in mediaView }.autoplay(2).arrows()

A chat message bubble.

ChatBubble("Hi!", time: "09:24").side(.outgoing).accent(.success)

A days/hours/minutes countdown readout.

Counter(days: 2, hours: 8, minutes: 45)

A copyable coupon code card.

Coupon(code: "UXMUQ", onCopy: { }).couponStyle(.outlined)

A sortable, paginated data table.

DataTable(columns: cols, rows: rows, selection: $selected).pageSize(10)

A destination discovery card with a ribbon, rating, and favorite toggle.

DestinationCard("Bali & 3-Days", image: url).ribbon("Top #1").price(1_450).rating(4.8).favorite($fav).tags(["Beach", "Culture"]).onTap { }

A presented modal dialog with a content and footer builder.

view.dialog(isPresented: $show, title: "") { content } footer: { buttons }

A before/after comparison slider.

Diff { beforeView } after: { afterView }.aspect(1.6)

A presented side drawer with drag-to-dismiss.

someView.drawer(isPresented: $open, edge: .leading) { menu }
// or imperative: install .drawerHost(); @Environment(DrawerPresenter.self) var drawer: DrawerPresenter
drawer.present(edge: .leading) { menu } // drag-to-dismiss built in

An empty/error state placeholder with a primary and secondary action.

EmptyState("Empty").icon("tray").message("").primaryAction("Retry") { }

A floating action button with speed-dial actions.

FloatingActionButton(systemImage: "plus", actions: [.init(systemImage: "camera", action: { })])

A fare-family comparison card with an included-features list.

FareFamilyCard("Super Eco", price: 1_871.99).accent(.success).features([FareFeature("Cabin bag", systemImage: "handbag")]).selection($picked)

An itemized fare summary with a hero total.

FareSummary([.item("Base fare", 1_100, info: ""), .discount("Member", 100), .total("Total", 1_199)]).onInfo { line in } footer: { TermsLink() }

A toast/snackbar presenter host — install once, present from anywhere.

@Environment(FeedbackPresenter.self) var feedback: FeedbackPresenter
feedback.toast("Saved", kind: .success) // stacks
feedback.toast("Deleted", action: ToastAction("Undo") { }, duration: nil)
await feedback.toastTask(loading: "Saving…", success: "Saved") { try await save() }
// install once: .feedbackHost(maxVisibleToasts: 3, toastPosition: .bottom)

A horizontal quick-filter bar that collapses on scroll.

FilterBar([QuickFilter("8+ rating"), QuickFilter("Seafront"), ], selection: $active).onFilter { }.onSort { } // leading buttons collapse on scroll

A titled list of filter options with a select-all action.

FilterList([FilterOption("Direct", count: 128), ], selection: $stops).title("Stops").bordered().selectAll("All")

A flight search result card — times, route, price, and a select action.

FlightCard(airline: "Anadolu Air", from: "IST", to: "ESB", departure: dep, arrival: arr).stops(0).price(1_299).badge("Cheapest").scarcity(3).fareBrand("Eco Flex").onSelect { }
// multi-leg: FlightCard(legs: [outbound, ret]).price(7_178)

A flight search result row, with an optional return leg.

FlightResultRow(airline: "Anadolu Air", from: "IST", to: "AYT", departure: dep, arrival: arr).flightNo("TK 2434").price(3_538.99).baggage("15 kg").badge("Cheapest").returnLeg(from: "AYT", to: "IST", departure: d2, arrival: a2).onSelect { }

A style-driven flight search-result list item: the component holds the data (legs, fares, price, deal signals, schedule, baggage) and a FlightListItemStyle owns the entire layout. Nine built-in styles cover the industry archetypes — .compact (one-line row), .timeline (route-track card, default), .fareBoard (fare-family chips), .deal (price judgment + sparkline), .ticket (perforated pass), .journey (expandable leg timeline), .slices (round-trip/multi-city card), .timetable (carrier departure chips), .tray (nested card + CTA rail, from the design-system spec) — and custom styles receive the same typed configuration.

FlightListItem(airline: "Skyline Air", from: "IST", to: "LHR", departure: dep, arrival: arr)
.flightNo("SK 1123")
.price(214, currencyCode: "USD", caption: "from")
.badge("Best")
.onSelect { }
.flightListItemStyle(.deal) // or .compact, .ticket, .journey, …

A compact flight ticket summary card.

FlightTicketCard(from: "NYC", to: "SFO").cities(from: "New York City", to: "San Francisco").duration("1h 45m").times(departure: "10:00 AM", arrival: "11:30 AM").airline("Garuda").price(140, currencyCode: "USD").favorite($fav)

A multi-column site/app footer.

Footer(columns: [.init("Company", items: [.init("About")])], note: "© 2026")

A grid image gallery.

Gallery(items) { item in mediaView }.columns(2).aspect(.square)

A hero banner section with title, subtitle, and CTA.

Hero(title: "").subtitle("").cta("Explore", action: { })

A hotel search result card — images, score, price, and discount.

HotelResultCard(name: "Mirage Park Resort").images(urls).score(8.9, reviews: 949).features([]).original(248_000).discountBadge("-23%").price(190_960).extraDiscount("Extra 8%", 175_683).favorite($fav).onSelect { }

A 1–4+ tile photo collage with a “+N” overflow tile.

ImageCollage(urls) { index in open(index) }.height(220) // 1·2·3·4+ layouts + "+N"

A full-width informational banner with inline links.

InfoBanner("Message", links: [("link", action)]).variant(.info)

A bordered key/value summary table.

KeyValueTable(rows: [...]).title("Summary").bordered()

A lazy list container with header/footer and border styles.

ListView(items) { ListRow($0.title) }.header("Settings").footer("3 items").bordered()

A single list row; ListSectionHeader groups rows under a titled section.

ListRow("Account", action: { }).subtitle("").trailing(.chevron)

A MapKit preview card with an address and distance.

LocationCard(title: "Marina Bay Hotel", latitude: 38.42, longitude: 27.14).subtitle("").distance("1.2 km").directions().pois(pins).snapshot()

A loyalty tier/points card that flips to a membership QR/barcode face.

LoyaltyCard(tier: "Gold", points: 8_430).memberName("Elif K.").progress(0.62, toNextTier: "Platinum").membership(.qr(id)).flippable().logo { }

A map pin callout card, for use over any Map.

MapCallout(title: "Mirage Park Resort").image(url).score(8.9).price(9_600).onSelect { } // over any Map, no MapKit dep

A card of navigable menu items.

MenuCard(items: [.init(title: "Reservations", systemImage: "calendar")])

A bottom tab navigation bar.

NavigationBar(items: [.init(systemImage: "house")], selection: $tab)

A notification/inbox card with read/unread state.

NotificationCard(title: "").message("").date("").unread()

A page title bar with a back action.

PageHeader("Title").subtitle("").onBack { }

A paged carousel with a peeking edge.

PagingCarousel(items) { item in mediaView }.peek(36).autoplay(2)

Phone bezel mockup frame, with notch/island styles.

PhoneFrame { AppScreen() }.notch(.island).bezel(.neutral)

An inline tap-to-confirm popover.

trigger.popconfirm(isPresented: $show, title: "Delete?", confirmTitle: "Delete") { delete() }

A price-alert opt-in card with a trend indicator.

PriceAlertCard("Get price alerts", isOn: $alerts).subtitle("").price(3_538).trend(.down, "-8%")

A promotional banner with an icon and a CTA.

PromoBanner("", action: { }).icon("sun.max.fill").ctaTitle("Go")

An aggregate rating summary with a review count.

RatingSummary(score: 9.0).label("Excellent").reviews(count: 1200)

A full-page result state — not found, error, success…

ResultView(.notFound, title: "Page not found").message("").primaryAction("Home") { }

A single review card with a score, text, and photo strip.

ReviewCard(author: "Elif K.", score: 9.2, text: "").date(d).title("").verified().stars().expandable().photos(urls).onPhotoTap { }

A hotel room offer card with board type and price.

RoomCard(name: "Deluxe Room").board("All-inclusive").features([FareFeature()]).original(12_000).discountBadge("-20%").price(9_600).unit("/ night").onSelect { }

A seat-selection grid for flights, with aisles and per-seat state.

SeatMap(columns: "ABC DEF", rows: Array(1...30), selection: $picked) { id, row, col in
SeatInfo(available: !sold.contains(id), price: row <= 3 ? 600 : 80, tier: row == 14 ? .exit : .standard)
}.legend().showsSeatInfo().recommended(["11C"])

A scrollable tab bar with per-tab badges.

SegmentedTabBar([TabItem("Reviews", badge: "12"), TabItem("Off", isEnabled: false)], selection: $i).tabStyle(.pill)

RadioCard / CheckboxCard {#selectioncards}

Section titled “RadioCard / CheckboxCard {#selectioncards}”

Radio- and checkbox-style selectable option cards.

RadioCard("Standard", isSelected: sel == id) { sel = id }.description("")

A modal sheet header with a back/close action and progress.

SheetHeader("Passengers").onBack { }.onClose { }.progress(0.4) // modal header (not the tab NavigationBar)

A swipeable, fanned card deck.

CardStack(items) { item in cardView }

A sticky bottom booking bar with price and a primary action.

StickyBookingBar("Book now") { }.price(9_600).original(12_000).discountBadge("-20%").note("2 rooms · 4 nights") // .safeAreaInset(.bottom)

A notched, perforated ticket shell around any content and stub.

TicketStub { FlightCard(...) }.stub { Barcode(id).showsValue() }.notchRadius(12).perforation().elevation(.elevated)

A vertical or horizontal event timeline.

Timeline([.init(title: "Placed", state: .done, color: .success)]).pending("Awaiting…")

A guided coach-mark tour across tagged targets.

view.tourTarget("search"); root.tourHost(tour, steps: [TourStep("search", title: "", message: "")])

An upload list bound to an UploadController, with per-file progress.

@State var uploads = UploadController()
UploadList(controller: uploads) { /* pick */ }
await uploads.upload(name: file.name) { progress in /* report 0…1 */ }

An inline video player with loop, mute, and a mute toggle.

VideoPlayerView(url).loop().muted().muteToggle()

OS window-chrome mockup frame around any content.

WindowFrame("Preferences") { content }.accent(.info)