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

# KPdfThumbnailStrip: scrollable page preview navigation

> Display a horizontal row of low-resolution page thumbnails that auto-scroll to the current page and let users jump to any page with a tap.

`KPdfThumbnailStrip` renders a horizontally scrollable row of page preview thumbnails connected to the same `KPdfViewerState` as your main viewer. It automatically scrolls to keep the current page in view, highlights the selected thumbnail with a distinct border, and calls `onPageClick` when the user taps a thumbnail. Thumbnails render at a fixed low resolution to keep memory usage low regardless of document length.

## Signature

```kotlin theme={null}
@Composable
fun KPdfThumbnailStrip(
    state: KPdfViewerState,
    modifier: Modifier = Modifier,
    onPageClick: ((Int) -> Unit)? = { pageIndex -> state.goToPage(pageIndex) },
    thumbnailWidth: Dp = 88.dp,
    thumbnailHeight: Dp = 124.dp,
    contentPadding: PaddingValues = PaddingValues(horizontal = 12.dp, vertical = 8.dp),
    itemSpacing: Dp = 12.dp,
    style: KPdfThumbnailStripStyle = KPdfThumbnailStripStyle.defaults(),
)
```

## Parameters

<ParamField path="state" type="KPdfViewerState" required>
  The shared state holder. The strip observes `loadState` to determine page count and `currentPageIndex` to track which thumbnail is selected and to drive auto-scroll.
</ParamField>

<ParamField path="modifier" type="Modifier" default="Modifier">
  Applied to the outer `Surface` container. Use it to constrain the height, set padding, or clip the strip to a shape.
</ParamField>

<ParamField path="onPageClick" type="((Int) -> Unit)?" default="{ pageIndex -> state.goToPage(pageIndex) }">
  Called when the user taps a thumbnail. Receives the 0-based page index. The default calls `state.goToPage(pageIndex)` to navigate the main viewer. Pass `null` to make thumbnails non-interactive.
</ParamField>

<ParamField path="thumbnailWidth" type="Dp" default="88.dp">
  Width of each thumbnail card in the strip.
</ParamField>

<ParamField path="thumbnailHeight" type="Dp" default="124.dp">
  Height of each thumbnail card in the strip.
</ParamField>

<ParamField path="contentPadding" type="PaddingValues" default="PaddingValues(horizontal = 12.dp, vertical = 8.dp)">
  Padding applied around the list of thumbnails inside the strip container.
</ParamField>

<ParamField path="itemSpacing" type="Dp" default="12.dp">
  Horizontal spacing between individual thumbnail cards.
</ParamField>

<ParamField path="style" type="KPdfThumbnailStripStyle" default="KPdfThumbnailStripStyle.defaults()">
  Controls the colors, shapes, borders, and elevation of the strip and its thumbnails. See [KPdfThumbnailStripStyle](#kpdfthumbnailstripstyle) below.
</ParamField>

## Rendering behavior

* **Auto-scroll** — whenever `currentPageIndex` changes, the strip animates to the corresponding thumbnail using `LazyListState.animateScrollToItem`.
* **Low-quality thumbnails** — each page is rendered at `thumbnailWidth × thumbnailHeight` pixels at zoom `1f`. This keeps memory usage predictable even for long documents.
* **Loading state** — each thumbnail shows a `CircularProgressIndicator` while its page renders asynchronously.
* **Error state** — if a page fails to render, the thumbnail shows the error message. Tapping an error thumbnail retries the render.
* **Empty state** — if the document has no pages yet (still loading), the strip displays a "No pages" placeholder at the configured height.

<Note>
  Thumbnails render independently per item. Scrolling quickly through a large document will trigger renders for newly visible thumbnails on demand, not all at once.
</Note>

## KPdfThumbnailStripStyle

Controls the visual appearance of the strip container and each thumbnail card. Call `KPdfThumbnailStripStyle.defaults()` for Material3-matched defaults, then use `.copy(...)` to override individual fields.

<ParamField path="stripShape" type="Shape" default="RoundedCornerShape(18.dp)">
  Shape of the outer strip container surface.
</ParamField>

<ParamField path="stripContainerColor" type="Color">
  Background color of the strip surface. Defaults to `colorScheme.surfaceVariant` at 32% alpha.
</ParamField>

<ParamField path="thumbnailShape" type="Shape" default="RoundedCornerShape(16.dp)">
  Shape of each individual thumbnail card.
</ParamField>

<ParamField path="thumbnailContainerColor" type="Color">
  Background color for unselected thumbnails. Defaults to `colorScheme.surface`.
</ParamField>

<ParamField path="selectedThumbnailContainerColor" type="Color">
  Background color for the selected thumbnail. Defaults to `colorScheme.surface`.
</ParamField>

<ParamField path="borderColor" type="Color">
  Border color for unselected thumbnails. Defaults to `colorScheme.outlineVariant`.
</ParamField>

<ParamField path="selectedBorderColor" type="Color">
  Border color for the selected thumbnail. Defaults to `colorScheme.primary`.
</ParamField>

<ParamField path="borderWidth" type="Dp" default="1.dp">
  Border stroke width for unselected thumbnails.
</ParamField>

<ParamField path="selectedBorderWidth" type="Dp" default="2.dp">
  Border stroke width for the selected thumbnail.
</ParamField>

<ParamField path="thumbnailElevation" type="Dp" default="0.dp">
  Tonal elevation for unselected thumbnails.
</ParamField>

<ParamField path="selectedThumbnailElevation" type="Dp" default="2.dp">
  Tonal elevation for the selected thumbnail.
</ParamField>

<ParamField path="thumbnailContentPadding" type="Dp" default="6.dp">
  Padding applied around the rendered page image inside each thumbnail card.
</ParamField>

<ParamField path="pageNumberColor" type="Color">
  Color of the page number label below unselected thumbnails. Defaults to `colorScheme.onSurfaceVariant`.
</ParamField>

<ParamField path="selectedPageNumberColor" type="Color">
  Color of the page number label below the selected thumbnail. Defaults to `colorScheme.primary`.
</ParamField>

<ParamField path="loadingContainerColor" type="Color">
  Background color of the thumbnail placeholder while a page is rendering.
</ParamField>

<ParamField path="errorContainerColor" type="Color">
  Background color of the thumbnail when a page fails to render.
</ParamField>

<ParamField path="errorContentColor" type="Color">
  Text color of the error message displayed inside a failed thumbnail.
</ParamField>

## Default usage

Pass `state` and an `onPageClick` handler that calls `goToPage` to navigate the main viewer.

```kotlin theme={null}
KPdfThumbnailStrip(
    state = viewerState,
    onPageClick = { pageIndex ->
        viewerState.goToPage(pageIndex)
    },
)
```

<Tip>
  The default value of `onPageClick` already calls `state.goToPage(pageIndex)`, so you can omit it entirely when you have no additional side-effects to run on tap.
</Tip>

## Disabling tap navigation

Pass `onPageClick = null` to render the strip as a read-only page overview with no tap interaction. The strip still auto-scrolls to track the current page.

```kotlin theme={null}
KPdfThumbnailStrip(
    state = viewerState,
    onPageClick = null,
)
```

## Custom dimensions

Adjust `thumbnailWidth` and `thumbnailHeight` to match your layout. The strip height in your layout should be at least `thumbnailHeight` plus the vertical `contentPadding` plus the page number label height.

```kotlin theme={null}
KPdfThumbnailStrip(
    state = viewerState,
    thumbnailWidth = 92.dp,
    thumbnailHeight = 128.dp,
    modifier = Modifier
        .fillMaxWidth()
        .height(172.dp),
)
```

<Warning>
  Setting `thumbnailWidth` and `thumbnailHeight` to very large values increases memory usage because each thumbnail is rendered at those pixel dimensions. Keep dimensions close to the visual size you display.
</Warning>

## Custom style

Use `KPdfThumbnailStripStyle.defaults().copy(...)` to override colors without losing the Material3 defaults for the fields you do not change.

```kotlin theme={null}
KPdfThumbnailStrip(
    state = viewerState,
    onPageClick = { pageIndex -> viewerState.goToPage(pageIndex) },
    style = KPdfThumbnailStripStyle.defaults().copy(
        stripContainerColor = Color(0xFFF4EFE6),
        selectedBorderColor = Color(0xFFB45F06),
        selectedPageNumberColor = Color(0xFFB45F06),
    ),
)
```

## Full layout example

The snippet below shows `KPdfThumbnailStrip` wired into a complete screen alongside `KPdfViewerToolbar` and `KPdfViewer`, with visibility controlled by the toolbar's thumbnail toggle.

```kotlin theme={null}
@Composable
fun FullPdfScreen(source: KPdfSource) {
    val viewerState = rememberPdfViewerState(source = source)
    var thumbnailsVisible by remember { mutableStateOf(true) }

    Column(modifier = Modifier.fillMaxSize()) {
        KPdfViewerToolbar(
            state = viewerState,
            isThumbnailStripVisible = thumbnailsVisible,
            onThumbnailToggle = { thumbnailsVisible = it },
            modifier = Modifier
                .fillMaxWidth()
                .padding(12.dp),
        )

        KPdfViewer(
            state = viewerState,
            modifier = Modifier
                .fillMaxWidth()
                .weight(1f),
        )

        if (thumbnailsVisible) {
            KPdfThumbnailStrip(
                state = viewerState,
                onPageClick = { pageIndex ->
                    viewerState.goToPage(pageIndex)
                },
                modifier = Modifier
                    .fillMaxWidth()
                    .height(172.dp)
                    .padding(horizontal = 12.dp),
            )
        }
    }
}
```
