# Hooks (/themes/sdk/reference/ui/hooks)

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

## `useMediaQuery` [#usemediaquery]

Whether the browser's viewport matches a media query; false on the server and while hydrating.

```ts
useMediaQuery(query: string): boolean
```

**Parameters**

- `query: string`: A media query as `matchMedia` takes it, such as `(min-width: 768px)`.

**Returns:** True once the browser reports a match.

**Example**

```tsx
import { useMediaQuery } from '@poltura/theme-sdk/ui';

export function Layout() {
  const wide = useMediaQuery('(min-width: 768px)');
  return <p>{wide ? 'Wide screen' : 'Narrow screen'}</p>;
}
```

## `useInView` [#useinview]

A reveal-on-scroll flag for an entrance animation; it starts true so content never stays hidden.

```ts
useInView(options?: InViewOptions): InView
```

**Parameters**

- `options?: InViewOptions`: When the element counts as in view, and whether that is permanent.

**Returns:** A ref for the element and whether it is in view.

**Example**

```tsx
import { useInView } from '@poltura/theme-sdk/ui';

export function Reveal({ children }: { children: string }) {
  const { ref, inView } = useInView({ threshold: 0.2 });
  return (
    <div ref={ref} className={inView ? 'opacity-100 transition' : 'opacity-0'}>
      {children}
    </div>
  );
}
```

## `useSnapCarousel` [#usesnapcarousel]

Drives a CSS scroll-snap track: autoplay, the active slide and the controls behind dots or thumbnails.

```ts
useSnapCarousel(count: number, opts: SnapCarouselOptions): SnapCarousel
```

**Parameters**

- `count: number`: How many slides the track holds.
- `opts: SnapCarouselOptions`: Whether to autoplay and how often.

**Returns:** The track ref, the active index, a function to go to a slide and the autoplay state.

**Example**

```tsx
import { useSnapCarousel } from '@poltura/theme-sdk/ui';

export function Slides({ slides }: { slides: string[] }) {
  const { trackRef, activeIndex, goTo } = useSnapCarousel(slides.length, {
    autoplay: true,
    intervalMs: 5000,
  });
  return (
    <div>
      <div ref={trackRef} className='flex snap-x snap-mandatory overflow-x-auto'>
        {slides.map((slide) => (
          <div key={slide} className='w-full shrink-0 snap-start'>
            {slide}
          </div>
        ))}
      </div>
      <button type='button' onClick={() => goTo(activeIndex + 1)}>
        Next
      </button>
    </div>
  );
}
```

## `useRovingTabs` [#userovingtabs]

Arrow, Home and End key handling for a tablist whose selected tab alone is in the tab order.

```ts
useRovingTabs<Id extends string>(options: RovingTabsOptions<Id>): (event: KeyboardEvent<HTMLButtonElement>, index: number) => void
```

**Parameters**

- `options: RovingTabsOptions<Id>`: The tabs, what selecting one does and how to find a tab's button.

**Returns:** A keydown handler for the tab buttons, called with the event and the tab's index.

**Example**

```tsx
import { useState } from 'react';
import { useRovingTabs } from '@poltura/theme-sdk/ui';

const tabs = [{ id: 'details' }, { id: 'reviews' }];

export function Tabs() {
  const [active, setActive] = useState('details');
  const onKeyDown = useRovingTabs({
    tabs,
    onSelect: setActive,
    tabDomId: (id) => `tab-${id}`,
  });
  return (
    <div role='tablist'>
      {tabs.map((tab, index) => (
        <button
          key={tab.id}
          id={`tab-${tab.id}`}
          role='tab'
          type='button'
          aria-selected={tab.id === active}
          tabIndex={tab.id === active ? 0 : -1}
          onKeyDown={(event) => onKeyDown(event, index)}
        >
          {tab.id}
        </button>
      ))}
    </div>
  );
}
```
