> Portal Navigation:
> 
> - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version.
> - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages).
> - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`).
> - Top-level index of all portals: https://dev.wix.com/docs/llms.txt
> - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt

## Resource: Functions

## Article: Functions

## Article Link: https://dev.wix.com/docs/sdk/site-sdk/accessibility-and-devices/tabbing/functions.md

## Article Content:

import { Property, PropertyList, ExpandableSection, RequestResponseExamples } from "@wix/docs-ui/content";

{/* Generated by @wix/tw-typedoc-to-wix-docs from packages/site-service-tabbing/src/definition/index.ts. Do not edit this file directly — edit the TSDoc in the source package. */}

# Tabbing Functions

## reset()

Releases the focus trap, so that every element on the page is reachable by Tab again.

Call it from browser code when the dialog, popup, or menu that set the trap closes, and when its
component unmounts while it's open. It has no effect while the page renders on the server.

There's one trap for the whole page, so the method releases it whichever component set it. It does
nothing when there's no trap, so calling it twice is safe.

When it releases the trap, the method:
- Restores the `tabindex` that each element had before the trap, overwriting any `tabindex` your code
  set on it while the trap was on.
- Leaves focus where it is, so return focus to the element that opened the dialog or menu yourself.
- Changes the page in the next animation frame, not immediately.

### Method Declaration

```ts
reset(): void
```

### Examples

<RequestResponseExamples defaultName="reset" requestName="JavaScript" requestType="JavaScript" examples={[
  {
    title: `Release the trap when a dialog closes`,
    content: {
      methodExample: {
        Request: `~~~tsx
import { useService } from '@wix/services-manager-react'
import { TabbingDefinition } from '@wix/site-service-tabbing/definition'

function CloseDialogButton({ onClose }: { onClose: () => void }) {
    const tabbingService = useService(TabbingDefinition)

    const close = () => {
        tabbingService.reset()
        onClose()
    }

    return <button onClick={close}>Close</button>
}
~~~`
      }
    }
  },
  {
    title: `Return focus to the button that opened a menu`,
    content: {
      methodExample: {
        Request: `~~~ts
// tabbingService is resolved from @wix/site-service-tabbing, as in the first example.
let opener: HTMLElement | null = null

function openMenu() {
    opener = document.activeElement as HTMLElement | null
    tabbingService.setParentComponents(['comp-m3q9t2vz', 'comp-lxk2h8f1'])
}

function closeMenu() {
    tabbingService.reset()
    // The trap doesn't move focus, so return it to the element that opened the menu.
    opener?.focus()
}
~~~`
      }
    }
  }
]} />

---

## setParentComponents()

Traps keyboard focus in the specified containers, so that Tab and Shift+Tab reach only elements
inside them.

Call it when a dialog, popup, or menu opens over the page, so that site visitors using a keyboard
can't reach controls hidden behind it.

It takes the following elements outside the containers out of the Tab order: buttons, form fields,
iframes, links with an `href`, and elements with a `tabindex`. Other focusable elements, such as
`contenteditable` regions, media controls, and anything inside a shadow root, stay reachable.

Call it from browser code, such as an event handler or an effect, once the containers are on the
page, because:
- It has no effect while the page renders on the server.
- IDs that match no element on the page take all of these elements on the page out of the Tab order,
  including the ones you meant to keep reachable. An empty array does the same.
- The page changes in the next animation frame, and the trap covers only the elements on the page at
  that point.

The method doesn't move focus, so move focus to an element inside a container yourself.

There's one trap for the whole page, so each call replaces the current trap rather than adding to it.
To release the trap, call `reset()`.

### Method Declaration

```ts
setParentComponents(parentCompIds: string[]): void
```

### Method Parameters

<PropertyList bordered>
  <Property name="parentCompIds" type="string[]" required>
    Values of the container elements' `id` attributes.
  </Property>
</PropertyList>

### Examples

<RequestResponseExamples defaultName="setParentComponents" requestName="JavaScript" requestType="JavaScript" examples={[
  {
    title: `Keep focus inside a dialog while it's open`,
    content: {
      methodExample: {
        Request: `~~~tsx
import { useEffect, useRef } from 'react'
import { useService } from '@wix/services-manager-react'
import { TabbingDefinition } from '@wix/site-service-tabbing/definition'

function Dialog({ id, isOpen, onClose }: { id: string; isOpen: boolean; onClose: () => void }) {
    const tabbingService = useService(TabbingDefinition)
    const closeButtonRef = useRef<HTMLButtonElement>(null)

    useEffect(() => {
        if (!isOpen) {
            return
        }
        tabbingService.setParentComponents([id])
        // The trap doesn't move focus, so move it into the dialog.
        closeButtonRef.current?.focus()

        // Release the trap when the dialog closes or unmounts.
        return () => tabbingService.reset()
    }, [tabbingService, id, isOpen])

    return isOpen ? (
        <div id={id} role="dialog" aria-modal="true">
            <button ref={closeButtonRef} onClick={onClose}>Close</button>
        </div>
    ) : null
}
~~~`
      }
    }
  },
  {
    title: `Trap focus in a menu and its toggle button`,
    content: {
      methodExample: {
        Request: `~~~ts
// tabbingService is resolved from @wix/site-service-tabbing, as in the first example.
function openMenu() {
    // Show the menu, then trap focus in the toggle button and the menu,
    // so the toggle button stays reachable to close the menu.
    tabbingService.setParentComponents(['comp-m3q9t2vz', 'comp-lxk2h8f1'])
}

function closeMenu() {
    tabbingService.reset()
    // Hide the menu.
}
~~~`
      }
    }
  }
]} />