> ## Documentation Index
> Fetch the complete documentation index at: https://mahmoud-b28887f9.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# KPdfViewerState: control and observe your PDF viewer

> Understand how KPdfViewerState drives every KPDF component through observable StateFlows and actions for navigation, zoom, save, and document management.

`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>`. |

### Platform integrations

| 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:

```kotlin theme={null}
@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:

```kotlin theme={null}
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:

```kotlin theme={null}
@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:

```kotlin theme={null}
@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")
}
```
