useDeviceKind

@sushindustries/ui

Which machine the stylesheet is currently drawing, as a value. Null until mounted, on purpose.

5 min read
View as MarkdownEdit on GitHub

Examples are the tab where the component is shown doing a job, not demonstrating a prop. The API tab already lists the props.

Viewport width
Phone22remthe floor, the narrowest this promises to work at
tanstacktanstack add https://adamjurek.com/r/tanstack/use-device-kind.jsonshadcnpnpm dlx shadcn@latest add https://adamjurek.com/r/shadcn/use-device-kind.json

Press Compare. The frames are real viewports, so a layout that breaks at 320 breaks here too rather than in somebody's hands.

In a page

The desktop shelf on this site's home page needs a column count as a number, not as CSS, because snapping a dropped icon to a cell is arithmetic:

import { DEVICES, useDeviceKind } from "@sushindustries/ui";

function deviceColumns(kind: ReturnType<typeof useDeviceKind>): number {
	const found = DEVICES.find((device) => device.kind === kind);
	return found ? found.columns : DEVICES[0].columns;
}

export function IconGrid() {
	const columns = deviceColumns(useDeviceKind());
	return <div style={{ "--columns": columns } as React.CSSProperties}>...</div>;
}
tsx

kind is null on the very first call, and DEVICES[0] - the narrowest machine - is the fallback: three columns fits everywhere, where guessing the laptop's seven would pack icons into a grid too narrow for them on the first paint of every phone that loads the page.

What this example is not

This is not the pattern for deciding what to render. It only ever feeds a number into layout math that already runs after mount; the grid itself is present in the DOM from the server render regardless of kind.

Used byDeviceDeviceA phone, a tablet or a laptop in CSS 3D, chosen by the stylesheet rather than by JavaScript, whose screen is a real scroll container with real controls in it.@sushindustries/ui · layoutShowcaseShowcaseA component in a real iframe at every width it has to survive, side by side, with its source and install commands.@sushindustries/ui · docs