# Defaults: ProductTabs (/themes/sdk/reference/product/defaults-7)

```ts
import { … } from '@poltura/theme-sdk/product';
```

## `ProductTabs` [#producttabs]

The product page's tabs as the merchant arranged them: built-in content, their own text and product tables; nothing when all are empty.

```ts
ProductTabs(props: ProductTabsProps): ReactElement | null
```

The built-in tabs are the description with keywords, the specifications, the guides and downloads, and the warranty.

**Props:** [`ProductTabsProps`](/themes/sdk/reference/product/types-7#producttabsprops)

<Tab value='Example'>

```tsx
import { ProductTabs } from '@poltura/theme-sdk/product';

export function Body() {
  return <ProductTabs display='accordion' />;
}
```

</Tab>
<Tab value='Source'>

```tsx title="source/product-tabs.tsx"
import { useState, type ReactElement } from 'react';
import { Minus, Plus } from 'lucide-react';
import {
  ProductTabContent,
  useProductTabs,
  type ProductTabsProps,
} from '@poltura/theme-sdk/product';
import { cn, useMediaQuery, useRovingTabs } from '@poltura/theme-sdk/ui';

const TAB =
  'px-3 sm:px-6 py-3 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap uppercase';

const HEADING =
  'flex w-full items-center justify-between gap-4 border-b border-border py-4 text-left text-sm font-semibold text-foreground';

export function ProductTabs({
  display = 'tabs',
  specsLayout,
  className,
}: ProductTabsProps): ReactElement | null {
  const tabs = useProductTabs();
  const [chosen, setChosen] = useState<string | null>(null);
  const [opened, setOpened] = useState<readonly string[] | null>(null);
  const first = tabs[0]?.id;
  const wide = useMediaQuery('(min-width: 640px)');
  const moveTabFocus = useRovingTabs({
    tabs,
    onSelect: setChosen,
    tabDomId: (id) => `product-tab-${id}`,
  });
  if (first === undefined) return null;
  const active = tabs.find((tab) => tab.id === chosen)?.id ?? first;
  const open = opened ?? [first];
  const asTabs = display === 'tabs';
  const toggle = (id: string): void =>
    setOpened(open.includes(id) ? open.filter((entry) => entry !== id) : [...open, id]);
  return (
    <div className={cn('space-y-5 sm:space-y-6', className)}>
      {asTabs ? (
        <div role='tablist' className='hidden sm:flex border-b border-border overflow-x-auto'>
          {tabs.map((tab, index) => (
            <button
              key={tab.id}
              type='button'
              role='tab'
              id={`product-tab-${tab.id}`}
              aria-selected={active === tab.id}
              aria-controls={`product-tab-panel-${tab.id}`}
              tabIndex={active === tab.id ? 0 : -1}
              onClick={() => setChosen(tab.id)}
              onKeyDown={(event) => moveTabFocus(event, index)}
              className={cn(
                TAB,
                active === tab.id
                  ? 'border-primary text-primary'
                  : 'border-transparent text-muted-foreground hover:text-foreground',
              )}
            >
              {tab.label}
            </button>
          ))}
        </div>
      ) : null}
      <div className={cn('border-t border-border', asTabs && 'sm:border-t-0')}>
        {tabs.map((tab) => {
          const expanded = open.includes(tab.id);
          return (
            <section key={tab.id}>
              <h3 className={cn(asTabs && 'sm:hidden')}>
                <button
                  type='button'
                  id={asTabs ? undefined : `product-tab-${tab.id}`}
                  aria-expanded={expanded}
                  aria-controls={`product-tab-panel-${tab.id}`}
                  onClick={() => toggle(tab.id)}
                  className={HEADING}
                >
                  {tab.label}
                  {expanded ? (
                    <Minus className='size-4 shrink-0' />
                  ) : (
                    <Plus className='size-4 shrink-0' />
                  )}
                </button>
              </h3>
              <div
                role={asTabs && wide ? 'tabpanel' : 'region'}
                id={`product-tab-panel-${tab.id}`}
                aria-labelledby={`product-tab-${tab.id}`}
                className={cn(
                  expanded ? 'block' : 'hidden',
                  'py-4',
                  asTabs && ['sm:py-0', active === tab.id ? 'sm:block' : 'sm:hidden'],
                )}
              >
                <ProductTabContent tab={tab} specsLayout={specsLayout} />
              </div>
            </section>
          );
        })}
      </div>
    </div>
  );
}
```

</Tab>


**See also:** [`useProductTabs`](/themes/sdk/reference/product/hooks-2#useproducttabs), [`ProductTabContent`](/themes/sdk/reference/product/parts-3#producttabcontent)
