IssuesBlock

fun IssuesBlock(onEvent: (IssuesBlockEvent) -> Unit, modifier: Modifier = Modifier, source: IssuesBlockSource = IssuesBlockSource.all(), layout: IssuesLayout = IssuesLayout.horizontal(), title: String? = null, showHeaderAction: Boolean = false, limit: Int? = null, header: @Composable () -> Unit? = null, footer: @Composable () -> Unit? = null)

A shelf of issues as a self-contained section: the whole catalogue, a publication's archives, one year of them.

The block owns its whole lifecycle: it loads on first display, shows placeholders while loading, paginates as the user scrolls, offers a retry on failure, reloads by itself when the connection comes back, collapses when there is nothing to show or no identified session, and keeps its pages while it is off screen. Every cell carries the issue's reading progress, followed live. The cover cell of IssueCoverStyle.Standard carries its download state and, once the issue is saved for later, a bookmark as well, and its download and bookmark controls act on the SDK's records directly; the brand cover and the rich row have a single action slot, which the host's "more" occupies, so those two draw neither. The caller supplies onEvent and, optionally, its presentation.

IssuesBlock(
title = "Latest issues",
onEvent = { event ->
when (event) {
is IssuesBlockEvent.ItemClick -> openIssue(event.issue.id, page = event.page)
is IssuesBlockEvent.ItemMoreClick -> showOptions(event.issue)
IssuesBlockEvent.HeaderActionClick -> openIssueList()
}
}
)

Data is loaded only while the block is displayed. No coroutine scope, state holder or ViewModel is required from the caller. Several blocks on the same screen that show the same content share a single request.

The block needs a androidx.lifecycle.ViewModelStoreOwner in scope. Any ComponentActivity, AppCompatActivity or fragment already is one — writing no ViewModel of your own changes nothing, since the store comes with the activity. Only a view tree that has no owner at all, such as a ComposeView in a window the host set up by hand, has none; the block then fails on its first composition with "No ViewModelStoreOwner was provided via LocalViewModelStoreOwner", which names nothing of this SDK. Supplying one is a line: CompositionLocalProvider(LocalViewModelStoreOwner provides owner) { IssuesBlock(…) }.

The block then takes the retention of whichever owner it found — a NavBackStackEntry under Navigation-Compose, the activity or the fragment otherwise — and that choice is the caller's. Blocks under the same owner showing the same content share one request and its loaded pages, so an activity-wide owner has two different screens share them, and a refresh on one seen by the other; a per-destination owner does not. A transfer already under way is unaffected either way — downloads run on the SDK's own scheduler, not on the owner — but the tap that starts one is launched on the owner's scope, so an owner cleared in that instant can leave the download unstarted, with nothing reported.

With the default IssuesLayout.horizontal the block scrolls horizontally only, so it is safe inside a scrolling column owned by the caller. IssuesLayout.grid and IssuesLayout.richList go both ways: capped with limit they lay out the lines their items fall on and sit in the caller's column; uncapped they scroll and paginate on their own, and must be given bounded height instead.

Parameters

onEvent

invoked when the user interacts with the block. Navigation is the caller's responsibility: the block never routes anywhere.

modifier

modifier applied to the block's root.

source

which issues to show. The whole catalogue by default.

layout

the cell and the arrangement — see IssuesLayout.

title

optional heading shown above the items.

showHeaderAction

draws the heading's "see all" arrow, reported as IssuesBlockEvent.HeaderActionClick. Requires a title: the design system's header carries the arrow. Ignored, with the "see all" under a capped block's items, when header replaces the heading.

limit

caps the block to its first limit items and stops it paginating — a teaser for a fuller list the host opens on IssuesBlockEvent.HeaderActionClick. With showHeaderAction, the block also draws a "see all" under its items. Null shows everything, page after page.

header

replaces the built-in heading with caller-owned content. title and showHeaderAction are then ignored. Prefer title, which is styled by the design system; reach for this only when the heading needs something the SDK does not offer. Unlike a heading the caller draws above the block, this one collapses with it when there is nothing to show.

footer

optional caller-owned content drawn below the items, inside the block, collapsing with it.

Throws

if limit is not strictly positive, or if showHeaderAction is set without a title.