useBreakpoint

Responsive state derived from the window size.

The React Native answer to a media query. Reports the largest Tailwind breakpoint the window satisfies, plus its dimensions and orientation.

For styling, prefer Uniwind's responsive prefixes — md:flex-row costs nothing at runtime. Reach for this hook when the behaviour changes, not just the look: rendering a sheet on a phone and a dialog on a tablet.

Usage

import { useBreakpoint, BottomSheet, Dialog } from 'panelui-native';

function Picker(props) {
  const { isAtLeast } = useBreakpoint();

  return isAtLeast('md') ? <Dialog {...props} /> : <BottomSheet {...props} />;
}

Examples

Reading the current breakpoint

const { current, width, isLandscape } = useBreakpoint();
// current: 'base' | 'sm' | 'md' | 'lg' | 'xl'

Changing a list's column count

const { isAtLeast } = useBreakpoint();
const columns = isAtLeast('lg') ? 3 : isAtLeast('md') ? 2 : 1;

<FlatList
  key={columns} // numColumns cannot change on a mounted list
  data={products}
  numColumns={columns}
  renderItem={renderItem}
/>;

App-specific breakpoint names

Create the contract once, outside a component. Its provider owns one window subscription; every bound hook below it reads the same dimensions. Names and isAtLeast arguments are inferred from the definition.

import { createBreakpoints } from 'panelui-native';

export const AppBreakpoints = createBreakpoints({
  compact: 0,
  medium: 600,
  expanded: 900,
});

// At the app root:
<AppBreakpoints.Provider>
  <App />
</AppBreakpoints.Provider>;

// In a descendant:
const { current, isAtLeast } = AppBreakpoints.useBreakpoint();
// current: 'base' | 'compact' | 'medium' | 'expanded'
const showSidebar = isAtLeast('expanded');

Thresholds must be finite, non-negative, and strictly ascending in declaration order. An invalid definition throws where createBreakpoints is called rather than producing different answers later. Widths below the first threshold use base; setting the first threshold to 0 makes that name the compact fallback.

Branching on orientation

const { isLandscape } = useBreakpoint();

<View className={isLandscape ? 'flex-row gap-6' : 'gap-4'}>
  <Player />
  <Playlist />
</View>;

When not to use it

Styling that only changes appearance belongs in Uniwind's responsive prefixes — they cost nothing at runtime, where this hook re-renders on every dimension change.

{/* Prefer this… */}
<View className="flex-col gap-4 md:flex-row md:gap-6" />

{/* …over this. */}
<View className={isAtLeast('md') ? 'flex-row gap-6' : 'flex-col gap-4'} />

API Reference

Returns

ValueTypeDescription
current'base' | 'sm' | 'md' | 'lg' | 'xl'Largest breakpoint the window satisfies.
isAtLeast(bp: Breakpoint) => booleanWhether the window is at least that wide.
widthnumberWindow width in px.
heightnumberWindow height in px.
isLandscapebooleanWhether width exceeds height.

Breakpoints

Exported as BREAKPOINTS, matching Tailwind's:

NameMin width
sm640
md768
lg1024
xl1280

These defaults and useBreakpoint() remain unchanged. createBreakpoints() is an opt-in semantic layer for apps whose layouts speak in names such as compact, medium, and expanded rather than Tailwind's defaults.

On this page