Skip to content

feat(BottomTabBar): add optional badge on tab items#250

Open
caiqueslp wants to merge 3 commits into
mainfrom
feat/bottom-tab-bar-badge
Open

feat(BottomTabBar): add optional badge on tab items#250
caiqueslp wants to merge 3 commits into
mainfrom
feat/bottom-tab-bar-badge

Conversation

@caiqueslp

Copy link
Copy Markdown
Collaborator

What

BottomTabBarItem gains an optional badge: String?. When set, a small LemonadeUi.Tag renders over the icon's top-trailing corner via Material3 BadgedBox — so a tab can flag a "Soon" / "New" state without shifting the icon or label. null keeps the current icon-only layout (no behavior change for existing call sites — the param is defaulted).

Driven by the app needing a "Soon" badge on the Teya AI tab while the feature is behind a flag.

Changes

  • BottomTabBarItem.badge: String? = null (+ KDoc).
  • BottomTabBarItemContent wraps the icon in BadgedBox, rendering LemonadeUi.Tag(label = badge, voice = .Neutral) when present.
  • Binary-compat .api dumps regenerated (apiDump): android / desktop / klib.
  • Demo (BottomTabBarDisplay) shows the badge on the "Teya AI" item.

Design notes / for review

  • Voice: used TagVoice.Neutral (gray pill). The app's reference design (web) shows a lime/brand "Soon" pill — there's no brand TagVoice today, so the exact color needs a design/token call. Happy to switch to whichever voice (or a new brand voice) you prefer.
  • Positioning: BadgedBox default top-end placement; a text Tag is wider than a dot badge, so on very narrow slots it can sit close to the edge. Open to a tighter/size-capped badge variant if preferred.

Verify

  • :expressive:compileDebugKotlinAndroid
  • :expressive:apiDump ✅ (committed)

🤖 Generated with Claude Code

BottomTabBarItem gains an optional `badge: String?` rendered as a small
Tag over the icon's top-trailing corner via Material3 BadgedBox, so a tab
can flag a "Soon"/"New" state without shifting the icon or label. Null
keeps the current icon-only layout. Demo shows it on the "Teya AI" item.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@caiqueslp caiqueslp requested a review from a team as a code owner June 21, 2026 19:39
Copilot AI review requested due to automatic review settings June 21, 2026 19:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an optional text badge to BottomTabBarItem so tabs can display a small “Soon/New” pill over the icon using Material3 BadgedBox, and updates the demo + API dumps accordingly.

Changes:

  • Added BottomTabBarItem.badge: String? = null (public API) with KDoc.
  • Rendered the badge via BadgedBox and LemonadeUi.Tag(voice = TagVoice.Neutral) when badge != null.
  • Updated the composeApp demo to show a "Soon" badge on the “Teya AI” tab; regenerated API dumps.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
kmp/expressive/src/commonMain/kotlin/com/teya/lemonade/BottomTabBar.kt Public API adds badge; UI now overlays a Tag badge on the tab icon via BadgedBox.
kmp/expressive/api/expressive.klib.api Regenerated API dump reflecting the new badge property and updated ctor/copy/component signatures.
kmp/expressive/api/desktop/expressive.api Regenerated desktop API dump for the same public API changes.
kmp/expressive/api/android/expressive.api Regenerated android API dump for the same public API changes.
kmp/composeApp/src/commonMain/kotlin/com/teya/lemonade/BottomTabBarDisplay.kt Demo updated to showcase the new badge on one tab item.

Comment on lines +297 to +302
Box(
modifier = Modifier.graphicsLayer {
scaleX = iconScale
scaleY = iconScale
},
) {
Comment on lines 68 to 73
public data class BottomTabBarItem(
val label: String,
val icon: LemonadeIcons,
val selectedIcon: LemonadeIcons? = null,
val badge: String? = null,
)
Adding `badge` to the BottomTabBarItem data class changed the primary
constructor, copy and copy$default signatures — an ABI break that tripped
the API Stability Review gate. Per the binary-compatibility skill, append
the property (done) and restore the old `<init>` and `copy` symbols as
@deprecated(HIDDEN) shims. The retained symbols dump as `synthetic`
(identical descriptor), so the classifier now reads ADDITIONS_ONLY and CI
auto-passes — no maintainer gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@caiqueslp

Copy link
Copy Markdown
Collaborator Author

API Dump (updated after binary-compat fix)

Verdict: ADDITIONS_ONLY (confirmed via .claude/skills/binary-compatibility/scripts/bcv-check.sh) — CI auto-passes, no maintainer gate needed.

badge: String? was appended to the BottomTabBarItem data class (never inserted), and the pre-badge <init> / copy / copy$default symbols are restored as @Deprecated(HIDDEN) shims. Those retained symbols dump as synthetic with identical descriptors, so the classifier counts the -/+ pairs as additive rather than removals. Already-compiled consumers keep linking whether they call the old constructor, copy(...), or copy().

No property renames/removals, no abstract interface members, no enum changes.

Use the dedicated Badge component (brand-coloured pill) instead of a
neutral Tag, matching the "Soon" treatment in the design. Public API is
unchanged (still `badge: String?`), so the BCV baseline is untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants