A manga-inspired UIKit design system for iOS.
Paper-cream surfaces, sumi-ink text, a vermillion hanko-stamp accent — a small
set of token-driven components that replace the stock UIAlertController family
with a coherent, production-grade look. Every component ships as its own SPM
product, so you import only the chrome you actually use.
Sumi began as the in-house design system of a production iOS app, then was extracted and open-sourced. For the full story — the why, the aesthetic, and the architecture — see docs/ABOUT.md.
Every component, exercised in the bundled Demo catalog:
![]() SumiAlert |
![]() SumiSheet |
![]() SumiToast |
![]() SumiDialog |
![]() SumiMenu |
![]() SumiContextMenu |
![]() SumiPicker |
![]() SumiStepper |
These are just one example of each. Every component ships many variants — one / two / three actions,
destructive·cancel·primarystyles, icon columns, toggles, sliders, badges, single / multi / tri-state selection, search, submenus, and edge-case layouts — all configurable through the component's API. Need something bespoke? AcustomContentslot lets you drop an arbitraryUIViewinto an alert or dialog. The Demo app exercises every variation.
Two-layer token model:
| Layer | What | Where |
|---|---|---|
| Brand | Raw palette named after manga materials (kamiCanvas, sumiInk, shuVermillion) |
Sumi.Brand.* |
| Semantic | Role-named tokens consumers use (surface, textPrimary, accent, danger) |
Sumi.Color.*, Sumi.Shadow.*, Sumi.Font.* |
Light-only by design — the cream surface is the identity.
| Module | What it provides |
|---|---|
Sumi |
Design tokens (colour, shadow, typography, spacing, radius, motion). Every component depends on this. |
SumiAlert |
Modal decision dialog with an async/await API. Replaces UIAlertController(.alert). |
SumiSheet |
Bottom action sheet with icon column, destructive style, swipe-to-dismiss. Replaces UIAlertController(.actionSheet). |
SumiToast |
Non-blocking transient overlay with queue, swipe, and optional action. |
SumiDialog |
Material-style dialog with text fields, inline async validation, and custom content slots. |
SumiMenu |
Tap-anchored popover with sections, search, toggles, and sliders. |
SumiContextMenu |
Long-press preview + actions on a blurred backdrop. |
SumiPicker |
Single / multi / tri-state choice dialog with animated indicators. |
SumiStepper |
Hero-sized integer stepper card for dialog content slots. |
SumiTable |
Compact key → value table for embedding inside an alert / dialog. |
SumiMenuKit |
Shared infrastructure for SumiMenu + SumiContextMenu. |
- iOS 13+
- Swift 5.9 / Xcode 15+
- Pointer feedback on iPadOS 13.4+ and Apple silicon Macs running the Designed for iPad version
Sumi components participate in system pointer interactions by default. Custom rows and buttons use the same restrained visual state as touch-down feedback, while isolated controls use system highlight or lift effects. Hovering never fires an action, starts hold-to-confirm progress, or produces haptics.
Pointer support is progressive enhancement: it is inert on iPhone and on iPad when no pointing device is present. Disable it only when a host interaction would conflict with the component:
let action = SumiDialog.Action(
title: "Done",
style: .primary,
pointerBehavior: .disabled
)Action models support per-item opt-out. Container APIs such as Menu,
ContextMenu, SumiSheet, ChoiceDialog, and SumiStepperView also accept
pointerBehavior: .disabled to disable pointer feedback for the entire
component instance.
Swift Package Manager — add the package and depend on the products you need:
dependencies: [
.package(url: "https://github.com/nobottomline/Sumi.git", from: "0.2.0")
],
targets: [
.target(
name: "MyFeature",
dependencies: [
.product(name: "Sumi", package: "Sumi"),
.product(name: "SumiAlert", package: "Sumi"),
]
)
]import SumiAlert
let pick = await Alert.present(
title: "Delete item?",
message: "This can't be undone.",
actions: [
.init(title: "Cancel", style: .cancel),
.init(title: "Delete", style: .destructive)
]
)
if pick?.style == .destructive { delete() }Importing SumiAlert pulls in only the alert and the Sumi token layer —
nothing else.
The Demo/ app is an interactive catalog: open a component and exercise every
variant (single / multi / tri-state, destructive / cancel, icon / icon-less
rows, edge cases) without wiring it into a host app.
open Demo/Demo.xcodeproj墨 — sumi, the ink used in manga line-art. Every surface is paper, every stroke is ink, every accent is a hanko-stamp seal. The design system is the language for putting that ink down on screen.







