Documentation Index
Fetch the complete documentation index at: https://mahmoud-b28887f9.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
KPdfViewerState is the single controller for one PDF viewer instance. It owns the document load pipeline, page navigation, zoom level, and all platform-integration flows. Every KPDF component — KPdfViewer, KPdfViewerToolbar, and KPdfThumbnailStrip — reads from the same state instance, so the entire UI stays in sync automatically without any extra wiring on your part.
Unidirectional data flow
KPDF follows a strict unidirectional pattern: your UI calls an action on KPdfViewerState, the state processes the request internally, and the result surfaces through one of the observable StateFlow properties. Your composables collect those flows and rebuild in response. You never write directly to the state fields.
User action
│
▼
KPdfViewerState.action()
│
▼
Internal processing
│
▼
StateFlow emits new value
│
▼
Composable recomposes
Observable properties
| Property | Type | Description |
|---|
source | KPdfSource | The source that is currently open or being loaded. |
config | KPdfViewerConfig | The active configuration for this viewer instance. |
loadState | StateFlow<KPdfLoadState> | Lifecycle state of the document load pipeline — Idle, Loading, Ready, or Error. |
currentPageIndex | StateFlow<Int> | 0-based index of the page currently shown. |
currentZoom | StateFlow<Float> | Active zoom factor. |
renderedPage | StateFlow<KPdfRenderedPageState> | Result of the most recent page render. |
openDocumentState | StateFlow<KPdfOpenDocumentState> | Lifecycle of the platform file picker flow. |
saveState | StateFlow<KPdfSaveState> | Lifecycle of an in-progress save or export operation. |
externalOpenState | StateFlow<KPdfExternalOpenState> | Lifecycle of an open-in-external-app operation. |
Actions
Document management
| Action | Description |
|---|
open(source) | Open a source, cancelling any in-flight work. Defaults to the current source (retry). |
retry() | Retry the most recent open call. |
close() | Close the active document and release resources. |
exportPdf() | Export the current PDF as raw bytes. Returns Result<ByteArray>. Suspend function. |
Page navigation
| Action | Description |
|---|
nextPage() | Advance to the next page. |
previousPage() | Go back to the previous page. |
goToPage(index) | Jump to a specific page by its 0-based index. |
Zoom
| Action | Description |
|---|
setZoom(zoom) | Set an exact zoom factor. |
zoomIn() | Increase zoom by one viewer-defined step. |
zoomOut() | Decrease zoom by one viewer-defined step. |
resetZoom() | Reset zoom to the configured minimum. |
Rendering
| Action | Description |
|---|
renderPage(pageIndex, targetWidth, targetHeight, zoom) | Render a page to a bitmap for custom UI layers. Suspend function, returns Result<KPdfPageBitmap>. |
| Action | Description |
|---|
requestOpenFromDevice(mimeTypes) | Trigger the platform file picker. |
requestSave(suggestedFileName, mimeType) | Initiate the platform save flow. |
savePdf(suggestedFileName, mimeType) | Alias for requestSave. |
openInExternalApp(suggestedFileName, mimeType) | Hand the current PDF to an external app. |
requestOpenInExternalApp(suggestedFileName, mimeType) | Explicit form of openInExternalApp. |
Creating viewer state
In Compose, use rememberPdfViewerState to create and remember a state instance tied to the composition lifecycle:
@Composable
fun PdfScreen(url: String) {
val source = remember(url) { KPdfSource.Url(url) }
val config = remember { KPdfViewerConfig.builder().build() }
val viewerState = rememberPdfViewerState(
source = source,
config = config,
)
KPdfViewer(
state = viewerState,
modifier = Modifier.fillMaxSize(),
)
}
If you manage lifecycle yourself outside of Compose, create state through the core facade:
val sdk = KPdfFactory.create()
val viewerState = sdk.viewerState(
source = KPdfSource.Url("https://example.com/file.pdf"),
config = KPdfViewerConfig.builder().build(),
)
Sharing state across components
Pass the same viewerState instance to every KPDF component. All three components read and react to the same flows, so navigation, zoom, and load state stay synchronized without any extra code:
@Composable
fun FullPdfScreen(source: KPdfSource) {
val viewerState = rememberPdfViewerState(source = source)
var thumbnailsVisible by remember { mutableStateOf(true) }
val scope = rememberCoroutineScope()
Column(modifier = Modifier.fillMaxSize()) {
// Toolbar shares the same state
KPdfViewerToolbar(
state = viewerState,
isThumbnailStripVisible = thumbnailsVisible,
onThumbnailToggle = { thumbnailsVisible = it },
onShareClick = {
scope.launch {
viewerState.exportPdf().onSuccess { bytes -> sharePdfBytes(bytes) }
}
},
)
// Main viewer surface
KPdfViewer(
state = viewerState,
modifier = Modifier.weight(1f),
)
// Thumbnail strip shares the same state
if (thumbnailsVisible) {
KPdfThumbnailStrip(
state = viewerState,
onPageClick = { viewerState.goToPage(it) },
)
}
}
}
Collecting state in your UI
Collect StateFlow properties with collectAsState() to drive your own UI elements:
@Composable
fun PageCounter(viewerState: KPdfViewerState) {
val loadState by viewerState.loadState.collectAsState()
val currentPage by viewerState.currentPageIndex.collectAsState()
val pageCount = (loadState as? KPdfLoadState.Ready)?.pageCount ?: 0
Text("Page ${currentPage + 1} of $pageCount")
}