useTouchPresentation@astryxdesign/core v0.7.5 · useTouchPresentation

Usage

Experimental: this hook may change or be removed in a patch release. The one answer to "is this a touch presentation?" that Astryx's adaptive components share, so a menu, a selector and a sheet never disagree on one device. It is SSR-safe: it renders the server default, then updates after hydration and when the conditions change (a window resized, a mouse attached). An iPad mini in portrait is not compact and keeps anchored popovers; a phone in landscape is compact. readTouchPresentation() reads the same answer once, for a decision taken at one moment, such as how a menu presents as it opens. For styles, write the same queries as media keys (@media (pointer: coarse)), so the first paint is already right.

ts
import {useTouchPresentation} from '@astryxdesign/core'

Best practices

GuidancePractices
Do

Choose touch behaviors on isTouch, layout on isCompact, and sheet-versus-popover on isCompactTouch.

Do

Pass a serverDefault when the server knows the device, to avoid a layout change after hydration.

Do

Gate iOS-only looks and motion on idiom === 'ios', or in styles on the two nested keys of IOS_TOUCH_STYLE_KEYS (the media query outside, the supports query inside), never on the coarse pointer alone.

Don't

Write your own phone media query; components would disagree about the same device.

Parameters

ParamTypeDescription
serverDefault
{isTouch?: boolean; isCompact?: boolean; idiom?: 'ios' | 'default'}

What to render before hydration, where no media query can be read (for example from a user-agent hint). isTouch and isCompact default to false, idiom to 'default'.

Returns

FieldTypeDescription
isTouchboolean

The primary pointer is coarse, a finger: (pointer: coarse). Key touch behaviors on it.

isCompactboolean

The viewport is compact: narrower than 744px or shorter than 500px, the closest a size gets to UIKit's compact size class. Key layout on it.

isCompactTouchboolean

Both, for presentations that need both, such as a bottom sheet in place of a popover.

idiom'ios' | 'default'

ios for WebKit on iOS or iPadOS (the engine that supports -webkit-touch-callout) under a coarse pointer; default otherwise, Android included. It follows pointer changes live. Gate iOS-only looks and motion on it; useTouchIdiom() reads it alone, and IOS_TOUCH_STYLE_KEYS are the same gate as nested StyleX keys.

Use with shadcn

Already using the shadcn registry workflow? Install the real Astryx package and a local public re-export. Component implementation source stays in Astryx.

This install URL expires with the draft preview.
bash
npx shadcn@4.19.0 add https://astryx-8h0jqi3w6-fbopensource.vercel.app/shadcn/hooks/use-touch-presentation.json