import { OptionTable } from 'components/table'

export function ToggleBox({ title, children }) {
  return (
    <details className="last-of-type:mb-0 rounded-lg bg-neutral-50 dark:bg-neutral-800 p-2 mt-4">
      <summary>
        <strong className="text-lg">{title}</strong>
      </summary>
      <div className="nx-p-2">{children}</div>
    </details>
  )
}

# Tour props

Properties to customize the Tour

### `steps?`

Type: `StepType[]`

Array of elements to highlight with special info and props.

<ToggleBox title={<code>StepType</code>}>
  <OptionTable
    options={[
      [
        'selector',
        'string | Element',
        'A string containing one CSS Selector to match and highlight the element at the time of this step.',
      ],
      [
        'content',
        `string | ({ setCurrentStep, transition, isHighlightingObserved, currentStep, setIsOpen }) => void`,
        'The content to show inside the Popover at the time of this step. Using a function, there are parameters with values, available to use as content.',
      ],
      [
        'position?',
        "'top' | 'right' | 'bottom' | 'left' | 'center' | [number, number]",
        'The preferred postion to position the Popover in relation with the highlighted element. Will be automatically calculated in case of unavailable space.',
      ],
      [
        'highlightedSelectors?',
        'string[]',
        'Array of CSS Selector to be included (by union) in the highlighted region of the Mask',
      ],
      [
        'mutationObservables?',
        'string[]',
        'Array of CSS Selector that when resizeing each will triggered a rerender of the Mask shape',
      ],
      [
        'navDotAriaLabel?',
        'string',
        'String to assign to `aria-label` attribute of the Dot button relative of this step in the navigation.',
      ],
      [
        'stepInteraction?',
        'boolean',
        'Allow to reenable the interaction for this specific step, when `disableInteraction` (from `TourProvider`) is `true`',
      ],
      [
        'action?',
        '(elem: Element | null) => void',
        'Action fired as soon as Tour arrives in this step.',
      ],
      [
        'actionAfter?',
        '(elem: Element | null) => void',
        'Action fired as soon as Tour leaves this step.',
      ],
      [
        'disableActions?',
        'boolean',
        'Disable all possible actions when the Tour is in this step.',
      ],
      ['padding?', 'Padding', 'Control padding spaces for this specific step.'],
      [
        'bypassElem?',
        'boolean',
        'Excludes the main `selector` when calculating highlited area if present `highlightedSelectors`.',
      ],
      [
        'styles?',
        'StylesObj & PopoverStylesObj & MaskStylesObj',
        'Customize styles fro this specific step.',
      ],
    ]}
  />
</ToggleBox>

### `components?`

Type: `PopoverComponentsType`

Customize granurally each Component inside the [Popover](/popover/quickstart).

<ToggleBox title={<code>Components</code>}>

Available Components and its `props`

<OptionTable
  options={[
    ['Badge', 'styles',],
    ['Close', 'styles, onClick, disabled',],
    ['Content', 'content,setCurrentStep,transition, isHighlightingObserved,currentStep,setIsOpen',],
    ['Navigation', 'styles,setCurrentStep, steps, currentStep, disableDots, nextButton, prevButton, setIsOpen, hideButtons, hideDots, disableAll, rtl, Arrow',],
    ['Arrow', 'styles, inverted, disabled',],
    
  ]}
/>
</ToggleBox>

<ToggleBox title="Example">

```js
import { components } from '@reactour/tour'

function Badge({ children }) {
  return (
    <components.Badge
      styles={{ badge: (base) => ({ ...base, backgroundColor: 'red' }) }}
    >
      👉 {children} 👈
    </components.Badge>
  )
}

function Close({ onClick }) {
  return (
    <button
      onClick={onClick}
      style={{ position: 'absolute', right: 0, top: 0 }}
    >
      x
    </button>
  )
}

const steps = [
  /* ... */
]

export default function App() {
  return (
    <TourProvider steps={steps} components={{ Badge, Close }}>
      {/* ... */}
    </TourProvider>
  )
}
```

</ToggleBox>

### `styles?`

Type: `StylesObj & PopoverStylesObj & MaskStylesObj`

Prop to customize styles for the different parts of the Mask, Popover and Tour using a function that allows to extend the base styles an take advantage of some state props.

<ToggleBox title={<code>StylesObj</code>}>
Styles keys and its props available to customize. Refer to [Mask docs](/mask/props) and [Popover docs](/popover/props) for its specific styles keys

<OptionTable
  options={[
    ['badge'],
    ['controls'],
    ['button', 'disabled'],
    ['arrow', 'disabled'],
    ['dot', 'current, disabled, showNumber'],
    ['close', 'disabled'],
  ]}
/>
</ToggleBox>

<ToggleBox title="Example">

```js
const styles = {
  maskWrapper: (base) => ({
    ...base,
    color: 'red',
  }),
  highlightedArea: (base, { x, y }) => ({
    ...base,
    x: x + 10,
    y: y + 10,
  }),
  badge: (base) => ({ ...base, color: 'blue' }),
}

function App() {
  return <TourProvider styles={styles} />
}
```

</ToggleBox>

### `padding?`

Type: `Padding`

Extra space to add between the Mask and the Popover and the highlighted element. A single number coordinates both spaces. Otherwise, passing an Object specifying the Component space.

<ToggleBox title={<code>Padding</code>}>
  Type: `number | { mask?: ComponentPadding, popover?: ComponentPadding, wrapper?: ComponentPadding }`

  <ToggleBox title="ComponentPadding">
      Calculation is based on [padding shorthand syntax](https://developer.mozilla.org/en-US/docs/Web/CSS/padding#syntax)
      <OptionTable
        options={[
          ['value', 'number', 'Apply to all four sides`'],
          ['[x, y]', 'number[]', 'top and bottom | left and right'],
          ['[top, x, bottom]', 'number[]', 'top | left and right | bottom'],
          ['[top, right, bottom, left]', 'number[]', 'top | right | bottom | left'],
        ]}
      />
    </ToggleBox>
</ToggleBox>

### `position?`

Type: `Position`

Set the global position value for the [Popover](/popover/quickstart) in all steps

<ToggleBox title={<code>Position</code>}>
Type: `'top' | 'right' | 'bottom' | 'left' | 'center' | [number, number] | ((postionsProps: PositionProps, prevRect: RectResult) => Position)`

Fixed in case of `[number, number]`, calculated prefered position in case of `string`.

  <ToggleBox title={<code>PositionProps</code>}>
    <OptionTable
      options={[
        ['bottom', 'number',],
        ['height', 'number',],
        ['left', 'number',],
        ['right', 'number',],
        ['top', 'number',],
        ['width', 'number',],
        ['windowWidth', 'number',],
        ['windowHeight', 'number',],
      ]}
    />
  </ToggleBox>
</ToggleBox>

### `setCurrentStep?`

Type: `Dispatch<React.SetStateAction<number>>`

Function to control the Tour current step state.

### `currentStep?`

Type: `number`

Custom Tour current step state.

### `disableInteraction?`

Type: `boolean | ((clickProps: Pick<ClickProps, 'currentStep' | 'steps' | 'meta'>) => boolean)`

Disables the ability to click or interact in any way with the Highlighted element on every step.

This option can be overrided on specific steps using `stepInteraction` prop.

### `disableFocusLock?`

Type: `boolean`

The Tour uses [FocusScope](https://react-spectrum.adobe.com/react-aria/FocusScope.html) in order to lock the focus iteration inside the [Popover](/popover/quickstart) when _Tour_ is active. This prop disables this behaviour.

### `disableDotsNavigation?`

Type: `boolean`

Disable interactivity with Dot navigation inside [Popover](/popover/quickstart).

### `disableWhenSelectorFalsy?`

Type: `boolean`

If true, don't show tours when selector or `document.getElementById(step.selector)` is falsy.

### `disableKeyboardNavigation?`

Type: `boolean | KeyboardParts[]`

Default: `false`

Disable all keyboard navigation events when true, disable only selected keys when array.

<ToggleBox title={<code>KeyboardParts</code>}>
  Type: `'esc' | 'left' | 'right'`
</ToggleBox>

### `className?`

Type: `string`

Default: `reactour__popover`

[CSS classname](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/class) assigned to the [Popover](/popover/quickstart)

### `maskClassName?`

Type: `string`

Default: `reactour__mask`

[CSS classname](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/class) assigned to the [Mask](/mask/quickstart)

### `highlightedMaskClassName?`

Type: `string`

Default: `reactour__mask`

[CSS classname](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/class) assigned to _highlighted_ part of the [Mask](/mask/quickstart). Useful when using `disableInteraction`.

### `nextButton?`

Type: `(props: BtnFnProps) => void`

Helper functions to customize the Next button inside [Popover](/popover/quickstart), with useful parameters. It is possible to use the base _Button_ and customize the props.

### `prevButton?`

Type: `(props: BtnFnProps) => void`

Helper functions to customize the Prev button inside [Popover](/popover/quickstart), with useful parameters. It is possible to use the base _Button_ and customize the props.

<ToggleBox title={<code>BtnFnProps</code>}>
  <OptionTable
    options={[
      ['Button', 'React.FC<NavButtonProps>'],
      ['setCurrentStep', 'Dispatch<React.SetStateAction<number>>'],
      ['stepsLength', 'number'],
      ['currentStep', 'number'],
      ['setIsOpen', 'Dispatch<React.SetStateAction<boolean>>'],
    ]}
  />
  <ToggleBox title={<code>NavButtonProps</code>}>
    <OptionTable
      options={[
        ['onClick?', '() => void'],
        ['kind?', "'next' | 'prev'"],
        ['hideArrow?', 'boolean'],
      ]}
    />
  </ToggleBox>
</ToggleBox>

### `afterOpen?`

Type: `(target: Element | null) => void`

Action fired just after the Tour is open.

### `beforeClose?`

Type: `(target: Element | null) => void`

Action fired just before the Tour is closed.

### `onClickMask?`

Type: `(clickProps: ClickProps) => void`

Function that overrides the default close behavior of the [Mask](/mask/quickstart) click handler. Comes with useful parameters to play with.

### `onClickClose?`

Type: `(clickProps: ClickProps) => void`

Function that overrides the default close behavior of the Close icon click handler. Comes with useful parameters to play with.

### `onClickHighlighted?`

Type: `(e: MouseEventHandler<SVGRectElement>, clickProps: ClickProps) => void`

Click handler for highlighted area. Only works when `disableInteraction` is active.

Useful in case is needed to avoid `onClickMask` when clicking the highlighted element.

 <ToggleBox title="Example">

```js
<TourProvider
  steps={steps}
  disableInteraction
  onClickHighlighted={(e, clickProps) => {
    console.log('No interaction at all')
    if (clickProps.currentStep < 2) {
      e.stopPropagation()
      event.preventDefault()
      clickProps.setCurrentStep(
        Math.min(clickProps.currentStep + 1, clickProps.steps.length - 1)
      )
    }
  }}
>
  {/* ... */}
</TourProvider>
```

</ToggleBox>

<ToggleBox title={<code>ClickProps</code>}>
  <OptionTable
    options={[
      ['setIsOpen', 'Dispatch<React.SetStateAction<boolean>>'],
      ['setCurrentStep', 'Dispatch<React.SetStateAction<number>>'],
      ['setSteps', 'Dispatch<React.SetStateAction<StepType[]>>'],
      ['setMeta', 'Dispatch<React.SetStateAction<string>>'],
      ['currentStep', 'number'],
      ['steps', 'StepType[]'],
      ['meta', 'string'],
    ]}
  />
</ToggleBox>

### `keyboardHandler?`

Type: `KeyboardHandler`

Function to handle keyboard events in a custom way.

<ToggleBox title={<code>KeyboardHandler</code>}>
  Type: `(e: KeyboardEvent, clickProps?: ClickProps, status?: { isEscDisabled?: boolean, isRightDisabled?: boolean, isLeftDisabled?: boolean }) => void`
</ToggleBox>

<ToggleBox title="Example">

```js
<TourProvider
  steps={steps}
  disableInteraction
  keyboardHandler={(e, clickProps) => {
    if (e.key === 'ArrowRight') {
      clickProps.setCurrentStep(
        Math.min(clickProps.currentStep + 1, clickProps.steps.length - 1)
      )
    }
    if (e.key === 'ArrowLeft') {
      clickProps.setCurrentStep(Math.max(clickProps.currentStep - 1, 0))
    }
    if (e.key === 'Escape') {
      const nextStep = Math.floor(Math.random() * clickProps.steps.length)
      clickProps.setCurrentStep(nextStep)
    }
  }}
>
  {/* ... */}
</TourProvider>
```

</ToggleBox>

### `badgeContent?`

Type: `(badgeProps: BadgeProps) => any`

Function to customize the content of the _Badge_ using helper parameters like the current and total steps and if the Tour is transitioning between steps.

<ToggleBox title={<code>BadgeProps</code>}>
  <OptionTable
    options={[
      ['totalSteps', 'number'],
      ['currentStep', 'number'],
      ['transition', 'boolean'],
    ]}
  />
</ToggleBox>

### `showNavigation?`

Type: `boolean`

Show or hide the Navigation (Prev and Next buttons and Dots) inside [Popover](/popover/quickstart).

### `showPrevNextButtons?`

Type: `boolean`

Show or hide Prev and Next buttons inside [Popover](/popover/quickstart).

### `showCloseButton?`

Type: `boolean`

Show or hide the Close button inside [Popover](/popover/quickstart).

### `showBadge?`

Type: `boolean`

Show or hide the Badge inside [Popover](/popover/quickstart).

### `showDots?`

Type: `boolean`

Show or hide dots navigation inside [Popover](/popover/quickstart).

### `scrollSmooth?`

Type: `boolean`

Activate smooth scroll behavior when steps are outside viewport.

### `inViewThreshold?`

Type: `{ x?: number, y?: number } | number`

Tolerance in pixels to add when calculating if the step element is outside viewport to scroll into view.

### `accessibilityOptions?`

Type: `A11yOptions`

Configure generic accessibility related attributes like [aria-labelledby](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-labelledby_attribute), [aria-label](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute) for Close button and if show or hide Dot navigation in screen readers.

<ToggleBox title={<code>A11yOptions</code>}>
  <OptionTable
    options={[
      ['ariaLabelledBy', 'string'],
      ['closeButtonAriaLabel', 'number'],
      ['showNavigationScreenReaders', 'boolean'],
    ]}
  />
</ToggleBox>

### `rtl?`

Type: `boolean`

Option to navigate and show Navigation in right-to-left mode

### `maskId?`

Type: `string`

String to be assigned to the `<mask />` element (otherwise an automatic unique id) of [Mask](/mask/props#maskid) Component

### `clipId?`

Type: `string`

String to be assigned to the `<clipPath />` element (otherwise an automatic unique id) of [Mask](/mask/props#clipid) Component

### `onTransition?`

Type: `PositionType`

Function to control the behavior of [Popover](/popover/quickstart) when is transitioning/scrolling from one step to another, calculating with [Popover](/popover/quickstart) next position and previous one.

<ToggleBox title={<code>PositionType</code>}>
  Type: `(postionsProps: PositionProps, prev: RectResult) => 'top' | 'right' |
  'bottom' | 'left' | 'center' | [number, number]`
</ToggleBox>

### `ContentComponent?`

Type: `ComponentType<PopoverContentProps>`

Completelly custom component to render inside the [Popover](/popover/quickstart).

<ToggleBox title={<code>PopoverContentProps</code>}>
  <OptionTable
    options={[
      ['styles?', 'StylesObj & PopoverStylesObj & MaskStylesObj'],
      ['badgeContent?', '(badgeProps: BadgeProps) => any'],
      ['components?', 'PopoverComponentsType'],
      ['accessibilityOptions?', 'A11yOptions'],
      ['disabledActions?', 'boolean'],
      ['onClickClose?', 'boolean'],
      ['setCurrentStep?', 'Dispatch<React.SetStateAction<number>>'],
      ['currentStep', 'number'],
      ['transition?', 'boolean'],
      ['isHighlightingObserved?', 'boolean'],
      ['setIsOpen', 'Dispatch<React.SetStateAction<boolean>>'],
      ['steps', 'StepType[]'],
      ['showNavigation?', 'boolean'],
      ['showPrevNextButtons?', 'boolean'],
      ['showCloseButton?', 'boolean'],
      ['showBadge?', 'boolean'],
      ['nextButton?', '(props: BtnFnProps) => void'],
      ['prevButton?', '(props: BtnFnProps) => void'],
      ['disableDotsNavigation?', 'boolean'],
      ['rtl?', 'boolean'],
    ]}
  />
</ToggleBox>

<ToggleBox title="Example">

```js
function ContentComponent(props) {
  const isLastStep = props.currentStep === props.steps.length - 1
  const content = props.steps[props.currentStep].content
  return (
    <div style={{ border: '5px solid red', padding: 10, background: 'white' }}>
      {/* Check if the step.content is a function or a string */}
      {typeof content === 'function'
        ? content({ ...props, someOtherStuff: 'Custom Text' })
        : content}
      <button
        onClick={() => {
          if (isLastStep) {
            props.setIsOpen(false)
          } else {
            props.setCurrentStep((s) => s + 1)
          }
        }}
      >
        {isLastStep ? 'x' : '>'}
      </button>
    </div>
  )
}

const steps = [
  /* ... */
]

function App() {
  return (
    <TourProvider
      steps={steps}
      ContentComponent={ContentComponent}
      styles={{ popover: (base) => ({ ...base, padding: 0 }) }}
    >
      {/* ... */}
    </TourProvider>
  )
}
```

</ToggleBox>

### `Wrapper?`

Type: `ComponentType`

Default: `React.Fragment`

Element which wraps the Tour. Useful in case is needed to port the Tour into a [Portal](https://react.dev/reference/react-dom/createPortal).
