# Popover

> Position Driver.js popovers with the side and align options, choose which buttons they show, change the button text, and add your own buttons and click handlers.

Every step and highlight shows a popover next to its element. This page covers where the popover sits and which buttons it shows. See [Styling](https://driverjs.com/docs/styling.md) to change how it looks.

## Position

You can control the popover position using the `side` and `align` options. The `side` option controls which side of the element the popover is shown on (`top`, `right`, `bottom`, or `left`, defaulting to `bottom`). The `align` option controls how the popover is aligned along that side: `start` lines its leading edge up with the element, `center` centers it, and `end` lines up the trailing edges (defaults to `start`).

> **Note:** Popover is intelligent enough to adjust itself to fit in the viewport. So, if you set `side` to `left` and `align` to `start`, but the popover doesn't fit in the viewport, it will automatically adjust itself to fit in the viewport. Consider highlighting and scrolling the browser to the element below to see this in action.

```js
import { driver } from "driver.js";
import "driver.js/dist/driver.css";

const driverObj = driver();
driverObj.highlight({
  element: "#left-start",
  popover: {
    title: "Animated Tour Example",
    description: "Here is the code example showing animated tour. Let's walk you through it.",
    side: "left",
    align: "start",
  },
});
```

## Buttons

You can use the `showButtons` option to choose which buttons to show in the popover. The default value is `['next', 'previous', 'close']`.

```js
import { driver } from "driver.js";
import "driver.js/dist/driver.css";

const driverObj = driver({
  showButtons: [
    'next',
    'previous',
    'close'
  ],
  steps: [
    {
      element: '#first-element',
      popover: {
        title: 'Popover Title',
        description: 'Popover Description'
      }
    },
    {
      element: '#second-element',
      popover: {
        title: 'Popover Title',
        description: 'Popover Description'
      }
    }
  ]
});

driverObj.drive();
```

### Change Button Text

You can also change the text of buttons using `nextBtnText`, `prevBtnText` and `doneBtnText` options. Use `closeBtnLabel` to change the screen reader label of the close button.

```js
import { driver } from "driver.js";
import "driver.js/dist/driver.css";

const driverObj = driver({
  nextBtnText: '—›',
  prevBtnText: '‹—',
  doneBtnText: '✕',
  closeBtnLabel: 'Close tour',
  showProgress: true,
  steps: [
    // ...
  ]
});

driverObj.drive();
```

### Event Handlers

You can use the `onNextClick`, `onPrevClick`, `onCloseClick` and `onDoneClick` callbacks to implement custom functionality when the user clicks on the buttons.

> Please note that when you configure these callbacks, the default functionality of the buttons will be disabled. You will have to implement the functionality yourself.

> `onDoneClick` runs when the done button (the next button on the last step) is clicked. When provided, it runs instead of `onNextClick` on the last step, so you can detect when the user finishes the tour. Driver.js won't tear down the tour for you here — call `driverObj.destroy()` yourself.

```js
import { driver } from "driver.js";
import "driver.js/dist/driver.css";

const driverObj = driver({
  onNextClick:() => {
    console.log('Next Button Clicked');
    // Implement your own functionality here
    driverObj.moveNext();
  },
  onPrevClick:() => {
    console.log('Previous Button Clicked');
    // Implement your own functionality here
    driverObj.movePrevious();
  },
  onCloseClick:() => {
    console.log('Close Button Clicked');
    // Implement your own functionality here
    driverObj.destroy();
  },
  onDoneClick:() => {
    console.log('Done Button Clicked');
    // Runs on the last step instead of onNextClick
    driverObj.destroy();
  },
  steps: [
    // ...
  ]
});

driverObj.drive();
```

### Custom Buttons

You can add custom buttons using `onPopoverRender` callback. This callback is called before the popover is rendered. In the following example, we are adding a custom button that takes the user to the first step.

```js
import { driver } from "driver.js";
import "driver.js/dist/driver.css";

const driverObj = driver({
  // Get full control over the popover rendering.
  // Here we are adding a custom button that takes
  // user to the first step.
  onPopoverRender: (popover, { config, state }) => {
    const firstButton = document.createElement("button");
    firstButton.className = "driver-popover-footer-btn";
    firstButton.innerText = "Go to First";
    // Add this class to give the button the default driver.js styling.
    // Leave it out if you want to apply your own styles instead.
    firstButton.classList.add("driver-popover-footer-btn");
    popover.footerButtons.appendChild(firstButton);

    firstButton.addEventListener("click", () => {
      driverObj.drive(0);
    });
  },
  steps: [
    // ..
  ]
});

driverObj.drive();
```
