Free trial timeline paywall for Jetpack Compose
TrialTimelinePaywall is design 3 of M3 Expressive Paywall. Explains exactly what happens during the trial: full access today, a reminder before it ends, and the day billing starts. The timeline describes the first plan that has a trialText, and fades when the user selects a plan without a trial.


implementation("com.github.sanikantv:m3-expressive-paywall:v1.0.0")When to use it
Section titled “When to use it”- You offer a free trial and want more people to start it with confidence.
- You want to reduce “I forgot to cancel” refund requests.
Basic usage
Section titled “Basic usage”TrialTimelinePaywall( plans = listOf(Sample.yearly, Sample.monthly), legal = Sample.legal, onPurchase = buy, onRestore = restore, onClose = close,)A 14-day trial
Section titled “A 14-day trial”TrialTimelinePaywall( plans = listOf(Sample.yearly.copy(trialText = "14-day free trial")), legal = Sample.legal, onPurchase = buy, onRestore = restore, onClose = close, steps = defaultTrialSteps(Sample.yearly, trialDays = 14, reminderDay = 12),)Your own steps
Section titled “Your own steps”val steps = listOf( TrialStep("Today", "Every Pro feature unlocks right away.", PaywallIcons.LockOpen), TrialStep("Day 5", "We email you a reminder. No surprise charges.", PaywallIcons.Bell), TrialStep("Day 7", "Your plan starts at ${Sample.yearly.price} ${Sample.yearly.period}.", PaywallIcons.Calendar),)TrialTimelinePaywall( plans = listOf(Sample.yearly, Sample.monthly), legal = Sample.legal, onPurchase = buy, onRestore = restore, onClose = close, steps = steps,)Parameters
Section titled “Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
plans |
List<PaywallPlan> |
required | Plans to offer. The first plan with trialText drives the timeline. |
legal |
PaywallLegal |
required | Terms and Privacy URLs for the footer links. |
onPurchase |
(PaywallPlan) -> Unit |
required | Called with the selected plan when the button is tapped. Start your billing flow here. |
onRestore |
() -> Unit |
required | Called from the Restore link. |
onClose |
() -> Unit |
required | Called from the close button. |
modifier |
Modifier |
Modifier |
Applied to the paywall’s root. |
title |
String |
“How your free trial works” | Headline. |
subtitle |
String? |
“No surprises. We remind you before you pay.” | Line under the headline. |
steps |
List<TrialStep> |
defaultTrialSteps(trialPlan) |
Timeline steps. The default is Today, Day 5 and Day 7. |
initialPlanId |
String? |
null |
Plan to preselect. Defaults to the first plan with a trial. |
defaultTrialSteps
Section titled “defaultTrialSteps”defaultTrialSteps(plan: PaywallPlan, trialDays: Int = 7, reminderDay: Int = trialDays - 2): List<TrialStep>
builds the three default steps from the plan’s price and period. It is @Composable because it reads
the translated strings.
Full signature: TrialTimelinePaywall in the API reference.
Customization
Section titled “Customization”Pass your own TrialStep list to change the copy or icons. Keep the last step’s price identical to the plan’s price; the footer repeats it.
Accessibility
Section titled “Accessibility”- Timeline icons are decorative; the step title and description carry the meaning for TalkBack.
- The selected plan is announced as a radio option.
Common mistakes
Section titled “Common mistakes”- Promising a reminder you never send. If the timeline says Day 5, schedule that notification (for example with WorkManager).
- A
trialTextthat disagrees with the store’s real trial length.
Related
Section titled “Related”Built by Sanikant. Set in Google Sans Flex (SIL Open Font License). Not affiliated with Google.