Skip to main content

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.

KPDF handles the platform file picker for you. Call requestOpenFromDevice() to launch the picker, observe openDocumentState for the result, and call viewerState.open(selectedSource) when the user selects a file. The kpdf-compose module binds the platform effects automatically when you use rememberPdfViewerState, so no additional setup is needed.

Full pattern

The example below shows the complete flow: a button that triggers the picker and a LaunchedEffect that opens the document when the picker returns a selection.
@Composable
fun OpenFromDeviceExample(viewerState: KPdfViewerState) {
    val openState by viewerState.openDocumentState.collectAsState()

    // Open the document as soon as the picker returns a file
    LaunchedEffect(openState) {
        val selectedSource = (openState as? KPdfOpenDocumentState.Success)?.source
            ?: return@LaunchedEffect

        viewerState.open(selectedSource)
    }

    Button(onClick = { viewerState.requestOpenFromDevice() }) {
        Text("Open local PDF")
    }
}

KPdfOpenDocumentState variants

openDocumentState is a StateFlow<KPdfOpenDocumentState>. React to each variant to keep your UI consistent with the picker lifecycle.
StateWhen it occursSuggested UI reaction
IdleInitial state, no pick in progressNo indicator
AwaitingSelectionPicker is open, waiting for the userShow a loading or “choosing…” indicator
SuccessUser selected a fileCall viewerState.open(source) to load it
CancelledUser dismissed the pickerDismiss any indicator, restore previous state
ErrorPicker failed or the file could not be readShow an error message
when (openState) {
    KPdfOpenDocumentState.Idle -> Unit
    is KPdfOpenDocumentState.AwaitingSelection -> {
        CircularProgressIndicator()
    }
    is KPdfOpenDocumentState.Success -> {
        // handled in LaunchedEffect above
    }
    KPdfOpenDocumentState.Cancelled -> {
        Text("No file selected.")
    }
    is KPdfOpenDocumentState.Error -> {
        Text("Could not open file: ${openState.reason}")
    }
}
If openDocumentState appears stuck at Idle after tapping the button, the most common cause is that viewerState is being recreated on every recomposition. This happens when you construct KPdfViewerConfig inline, outside a remember block. Wrap the config in remember { KPdfViewerConfig.builder()…build() } to keep the state instance stable.