---
title: PagerView
category: Layout
summary: Allows paging between views. Use with the `useRovingIndex` hook to control the [activeViewIndex](#activeViewIndex).
---

```jsx live
const views = [
  ['blue-5', 18],
  ['seagreen', 24],
  ['rebeccapurple', 32],
  ['hotpink', 20],
]
render(() => {
  const {
    activeIndex,
    moveActiveIndex,
    moveBackwardDisabled,
    moveForwardDisabled,
  } = hooks.useRovingIndex({
    maxIndex: views.length - 1,
  })
  return (
    <StackView spacing={1}>
      <PagerView
        activeViewIndex={activeIndex}
        width={40}
        backgroundColor="backgroundTertiary"
      >
        {views.map(([color, height], index) => (
          <PagerView.View
            key={color}
            minHeight={height}
            alignment="center"
            distribution="center"
            paddingHorizontal={4}
            fontSize={0}
            color="light-5"
            backgroundColor={color}
          >
            {index + 1}
          </PagerView.View>
        ))}
      </PagerView>
      <StackView axis="horizontal" distribution="center" spacing={1}>
        <Button
          title="Prev"
          icon={{ name: 'caret-left' }}
          radius="circle"
          disabled={moveBackwardDisabled}
          onClick={() => moveActiveIndex(-1)}
        />
        <Button
          title="Next"
          icon={{ name: 'caret-right' }}
          radius="circle"
          disabled={moveForwardDisabled}
          onClick={() => moveActiveIndex(1)}
        />
      </StackView>
    </StackView>
  )
})
```

```jsx live
function View({ children }) {
  return (
    <PagerView.View>
      <Card minHeight={24} padding={2}>
        {children}
      </Card>
    </PagerView.View>
  )
}

function Arrangement({ expanded, expandOrShrink }) {
  return (
    <View>
      <Toolbar
        title="Arrangement"
        helpContent="These files are only available in plans that use the Default Arrangement, no matter what key is chosen."
        actions={
          <Button
            title={expanded ? 'show single-view' : 'show multi-view'}
            icon={{ name: expanded ? 'caret-shrink' : 'caret-grow' }}
            variant="naked"
            onClick={expandOrShrink}
          />
        }
      />
    </View>
  )
}

function Key({ name, expanded, expandOrShrink }) {
  return (
    <View>
      <Toolbar
        title={name}
        actions={[
          <Button title="edit" icon={{ name: 'pencil' }} variant="naked" />,
          <Button
            title={expanded ? 'show single-view' : 'show multi-view'}
            icon={{ name: expanded ? 'caret-shrink' : 'caret-grow' }}
            variant="naked"
            onClick={expandOrShrink}
          />,
        ]}
      />
    </View>
  )
}

const keys = ['A', 'Ab', 'B', 'C', 'C#', 'D', 'Db', 'E', 'Eb', 'F', 'F#', 'G']

render(() => {
  const [expanded, setExpanded] = React.useState(false)
  const {
    activeIndex,
    moveActiveIndex,
    setActiveIndex,
    moveBackwardDisabled,
    moveForwardDisabled,
  } = hooks.useRovingIndex({
    maxIndex: keys.length - 1,
  })
  const viewsToShow = expanded ? 1 : 3
  const expandOrShrink = (nextIndex) => {
    setActiveIndex(nextIndex)
    setExpanded((bool) => !bool)
  }
  const isActiveIndex = (index) => {
    return index >= activeIndex && index < activeIndex + viewsToShow
  }
  return (
    <StackView width="100%" maxWidth={104} spacing={2}>
      <PagerView
        width="100%"
        activeViewIndex={activeIndex}
        viewsToShow={viewsToShow}
        spacing={2}
      >
        <Arrangement
          expanded={expanded && activeIndex === 0}
          expandOrShrink={() => expandOrShrink(0)}
        />
        {keys.map((key, index) => (
          <Key
            key={key}
            name={key}
            expanded={expanded && activeIndex === index + 1}
            expandOrShrink={() => expandOrShrink(index + 1)}
          />
        ))}
      </PagerView>
      <GridView columns="auto 1fr auto" spacing={1}>
        <Button
          title="Prev"
          icon={{ name: 'caret-left' }}
          radius="circle"
          disabled={moveBackwardDisabled}
          onClick={() => moveActiveIndex(-1)}
        />
        <StackView
          axis="horizontal"
          maxWidth="100%"
          marginHorizontal="auto"
          overflow="scroll"
        >
          {['Arrangement', ...keys].map((key, index) => {
            const buttonProps = {
              key,
              title: key,
              variant: 'naked',
              onClick: () => setActiveIndex(index),
            }
            if (isActiveIndex(index)) {
              buttonProps.theme = false
              buttonProps.radius = 0
              buttonProps.borderBottomWidth = 2
              buttonProps.borderBottomColor = 'primary'
              buttonProps.color = 'primary'
            }
            return <Button {...buttonProps} />
          })}
        </StackView>
        <Button
          title="Next"
          icon={{ name: 'caret-right' }}
          radius="circle"
          disabled={moveForwardDisabled}
          onClick={() => moveActiveIndex(1)}
        />
      </GridView>
    </StackView>
  )
})
```
