A small section header with a title, optional subtitle, and an optional trailing action.
Contexts are illustrative. Final screens will reference actual GCash patterns.
yes/no instead of true/false (C2). leading control only available when leading icon=yes and trailing icon=no -- implicit dependency not expressed in property schema.| State | iOS | Android | Figma Property | Notes |
|---|---|---|---|---|
| Default | Yes | Yes | 5 boolean properties | Navigation bar. No interaction states beyond tap targets on icons and control text. |
- Boolean properties use
yes/nostrings.leading icon,trailing icon,leading control,subtext,title block— all incompatible with SwiftBool/ KotlinBooleanfor Code Connect. C2 · Variant & Property Naming - Trailing icon is a placeholder RECTANGLE. The 24×24
icon-placeholderblocks instance swap — native icon slot mapping can't be wired until this becomes a swappable Icon instance. C6 · Asset & Icon Quality - Code Connect mappings not registered. Blocked until boolean values and placeholder rectangles are fixed. C7 · Code Connect Linkability
- Rename boolean values from
yes/nototrue/false. Direct native boolean mapping eliminates the string-to-bool layer when wiring Code Connect. Rename - Replace trailing icon placeholder with a real Icon instance. Drop in an actual icon from the DS library (e.g. more/ellipsis, share, search) so product teams can instance-swap without editing the master. Slot
- Make
leading controldependency explicit. Today it requiresleading icon=yesandtrailing icon=no— document it in the spec or promote it to a separate property so the constraint is enforced, not assumed. Docs - Add a dark / transparent variant. For screens with hero images or gradient backgrounds (home, campaign pages, onboarding), the current opaque bar is wrong — a transparent variant lets the hero breathe through. Property
- Document the
showAssetproperty. Currently only available whentitle block=yes; its purpose (background image behind the title) should be explicitly described in the component spec. Docs
Standard title bar without title block. Status bar (44px) + title row with optional icons, control, and subtext. Height ranges from 84px to 100px depending on subtext.
Single color scheme -- no appearance modes. All colors bound to main/title-bar/color/ tokens. Display/navigation component with no state-driven color changes.
| Role | Token | Value |
|---|---|---|
| Background | main/title-bar/color/bg | #1972F9 |
| Title label | main/title-bar/color/label-title | #FFFFFF |
| Header label | main/title-bar/color/label-header | #FFFFFF |
| Subtext / URL | main/title-bar/color/label-url | #F6F9FDCC (80% opacity) |
| CTA text | main/title-bar/color/label-cta | #FFFFFF |
| Icon | main/title-bar/color/icon | #FFFFFF |
Title bar with expanded header block (72px) below the title row. Used for screens with prominent section headers. Adds "Header" text at 26px Semibold.
| Role | Token |
|---|---|
| Status bar height | 44px |
| Title row padding H | 20px |
| Title row padding V | 12px |
| Leading icon size | 24 x 24 |
| Trailing icon size | 24 x 24 |
| Title block height | 72px |
| Title block padding H | 24px |
| Total height (no subtext, no block) | ~84px |
| Total height (with subtext, no block) | ~100px |
| Total height (with block) | ~156--172px |
iOS -- Swift Package Manager
// In Xcode: File -> Add Package Dependencies "https://github.com/AY-Org/eb-ds-ios"
Android -- Gradle (Kotlin DSL)
dependencies { implementation("com.eastblue.ds:titlebar:1.0.0") }
Import
import EastBlueDS // SwiftUI import com.eastblue.ds.titlebar.* // Compose
Package not yet published. These are the planned distribution paths.
| Figma Property | SwiftUI | Compose |
|---|---|---|
| leading icon (yes/no) | .ebLeadingIcon(Image?) | leadingIcon: @Composable (() -> Unit)? |
| trailing icon (yes/no) | .ebTrailingIcon(Image?) | trailingIcon: @Composable (() -> Unit)? |
| leading control (yes/no) | .ebLeadingControl("Done") | leadingControlText: String? |
| subtext (yes/no) | .ebSubtext("m.gcash.com") | subtext: String? |
| title block (yes/no) | .ebTitleBlock("Header") | titleBlock: String? |
EBTitleBar("Send Money")
EBTitleBar( title = "Send Money" )
EBTitleBar("Send Money") .ebLeadingIcon(Image(systemName: "arrow.left"))
EBTitleBar( title = "Send Money", leadingIcon = { Icon(Icons.Default.ArrowBack, "Back") } )
EBTitleBar("GCash") .ebLeadingIcon(Image(systemName: "arrow.left")) .ebTrailingIcon(Image(systemName: "ellipsis")) .ebSubtext("m.gcash.com") .ebTitleBlock("My Wallet")
EBTitleBar( title = "GCash", leadingIcon = { Icon(Icons.Default.ArrowBack, "Back") }, trailingIcon = { Icon(Icons.Default.MoreVert, "More") }, subtext = "m.gcash.com", titleBlock = "My Wallet" )
EBTitleBar("Edit Profile") .ebLeadingIcon(Image(systemName: "arrow.left")) .ebLeadingControl("Done")
EBTitleBar( title = "Edit Profile", leadingIcon = { Icon(Icons.Default.ArrowBack, "Back") }, leadingControlText = "Done" )
| Requirement | iOS | Android |
|---|---|---|
| Minimum touch target | 44 x 44 pt (icons and control) | 48 x 48 dp (icons and control) |
| Back button label | .accessibilityLabel("Back") | contentDescription = "Navigate back" |
| Trailing icon label | .accessibilityLabel("More options") | contentDescription = "More options" |
| Heading semantics | .accessibilityAddTraits(.isHeader) on title | semantics { heading() } on title |
Do
Use EBTitleBar as the top-level navigation element on every screen. Keep the title short and descriptive.
Don't
Nest a title bar inside scrollable content or use it as a section header within a page -- use a section heading component instead.
Do
Use the title block for high-level section headers like "My Wallet" or "Dashboard" where the large text reinforces the current context.
Don't
Show both trailing icon and leading control simultaneously -- they occupy the same trailing slot. Use one or the other.
| ID | Criterion | Status | Notes |
|---|---|---|---|
| C1 | Layer Structure & Naming | Ready | Semantic layer names: title, Title Bar, title-block, Leading Icon, Placeholder. |
| C2 | Variant & Property Naming | Needs Refinement | All 5 boolean properties use yes/no instead of true/false. leading control has implicit dependency on other properties. |
| C3 | Token Coverage | Ready | All 6 color roles bound to main/title-bar/color/ tokens. |
| C4 | Native Mappability | Ready | Maps to NavigationBar (iOS) / TopAppBar (Android, Material 3). |
| C5 | Interaction State Coverage | Ready | Navigation bar -- no interaction states needed beyond individual tap targets on icons and control. |
| C6 | Asset & Icon Quality | Needs Refinement | Trailing icon uses icon-placeholder RECTANGLE instead of a swappable icon instance. |
| C7 | Code Connect Linkability | Needs Refinement | No CLI mappings registered yet. |
| Aspect | Status | Notes |
|---|---|---|
| Property naming | Needs Refinement | All booleans use yes/no -- must be renamed to true/false before Code Connect mapping |
| Asset quality | Needs Refinement | Trailing icon placeholder RECTANGLE needs replacement with icon instance |
| State coverage | Ready | Navigation bar -- no interaction states needed |
| Native component file | Needs Refinement | EBTitleBar.swift / EBTitleBar.kt not yet created |
5 boolean properties (leading icon, trailing icon, leading control, subtext, title block) with implicit constraints yield 20 variants: 10 without title block + 10 with title block.
| title block | Combinations covered | Count |
|---|---|---|
| no | 10 combos of leading/trailing icon + leading control + subtext | 10 |
| yes | Same 10 combos with title block enabled | 10 |
main/title-bar/color/ tokens.
Documentedleading icon, trailing icon, leading control, subtext, title block) use yes/no instead of true/false. Incompatible with Swift Bool and Kotlin Boolean for Code Connect mapping.
Openicon-placeholder is a 24x24 RECTANGLE instead of a swappable icon instance from the DS icon library. Blocks native icon slot mapping.
Open