# PrimeReact
# LLMs.txt
LLMs.txt is a file that contains the LLMs for the PrimeReact documentation.
## /llms.txt
The [llms.txt](https://llmstxt.org/) file is an industry standard that helps AI models better understand and navigate the PrimeReact documentation. It lists key pages in a structured format, making it easier for LLMs to retrieve relevant information.
## /llms-full.txt
The `llms-full.txt` file is a complete list of all the pages in the PrimeReact documentation. It is used to help AI models understand the entire documentation set.
## .md extension
Add a `.md` to a page’s URL to display a Markdown version of that page.
# LLMs.txt
LLMs.txt is a file that contains the LLMs for the PrimeReact documentation.
## /llms.txt
The [llms.txt](https://llmstxt.org/) file is an industry standard that helps AI models better understand and navigate the PrimeReact documentation. It lists key pages in a structured format, making it easier for LLMs to retrieve relevant information.
## /llms-full.txt
The `llms-full.txt` file is a complete list of all the pages in the PrimeReact documentation. It is used to help AI models understand the entire documentation set.
## .md extension
Add a `.md` to a page’s URL to display a Markdown version of that page.
# LLMs.txt
LLMs.txt is a file that contains the LLMs for the PrimeReact documentation.
## /llms.txt
The [llms.txt](https://llmstxt.org/) file is an industry standard that helps AI models better understand and navigate the PrimeReact documentation. It lists key pages in a structured format, making it easier for LLMs to retrieve relevant information.
## /llms-full.txt
The `llms-full.txt` file is a complete list of all the pages in the PrimeReact documentation. It is used to help AI models understand the entire documentation set.
## .md extension
Add a `.md` to a page’s URL to display a Markdown version of that page.
# Add-Ons
Premium templates, UI blocks and design tooling that build on top of PrimeReact.
## Overview
Add-Ons are premium, production-ready resources built on top of PrimeReact. They help you skip the boilerplate and ship faster, from full application templates to ready-made UI blocks and design tooling.
## What's included
- **Templates**, complete, themeable application starters with layouts, pages and integrations wired up.
- **Blocks**, copy-and-paste UI sections for application, marketing and e-commerce pages.
- **Figma UI Kit**, the design source that mirrors the component library, for designing before you build.
- **Theme Designer**, a visual tool to craft and export your own design tokens and themes.
Pick a category from the sidebar to explore each add-on.
# Installation
Install PrimeReact's headless hooks and build fully custom components in your React project.
Start from our Next.js template, pre-configured with PrimeReact.
Headless hooks give you the behavior — state, keyboard navigation, focus and accessibility — while you own the markup and styles. They work in any React setup; the steps below show a Next.js example you can adapt to your own framework.
### Install Packages
Install the headless package using your favorite package manager:
```bash
npm install @primereact/headless
```
### PrimeReactProvider
Wrap your app with `PrimeReactProvider` so the hooks' shared context is available everywhere. No theme or preset is needed — you style everything yourself:
```tsx showLineNumbers title="components/prime-provider.tsx"
'use client';
import { PrimeReactProvider } from '@primereact/core';
export function PrimeProvider({ children }: { children: React.ReactNode }) {
return {children};
}
```
Then wrap your app with it in `app/layout.tsx`:
```tsx showLineNumbers title="app/layout.tsx" {1,6}
import { PrimeProvider } from '@/components/prime-provider';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
{children}
);
}
```
### Add a `cn` Helper (optional)
If you style with Tailwind, a `cn` helper makes merging class names easier. Install `tailwind-merge` and create `lib/utils.ts`:
```bash
npm install tailwind-merge
```
```ts showLineNumbers title="lib/utils.ts"
import { cn as _cn } from '@primeuix/utils';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: unknown[]) {
return twMerge(_cn(...inputs));
}
```
### Verify
Build a component with a hook and style it yourself — the hook wires up state, keyboard, focus and accessibility:
```tsx
'use client';
import { useButton } from '@primereact/headless/button';
import { cn } from '@primeuix/utils';
export default function VerifyDemo() {
const { rootProps } = useButton();
return (
);
}
```
```tsx showLineNumbers {2,6}
'use client';
import { useButton } from '@primereact/headless/button';
import { cn } from '@/lib/utils';
export default function VerifyInstallation() {
const { rootProps } = useButton();
return (
);
}
```
## Next Steps
[Browse the hooks](/docs/headless/components/autocomplete) and compose the behavior you need into your own markup and styles.
# Headless
React hooks that handle logic and accessibility. You bring your own markup and styles.
## Overview
Headless mode exposes each component as a hook, like `useDialog`, `useSelect`, or `useAutoComplete`. Hooks return props you spread onto your own elements. You get state management, keyboard interactions, focus handling, and ARIA wiring. You write the JSX and CSS.
Use headless mode when you want maximum control over markup and styling, or when you're building a custom component library on top of our logic.
## What you get
- 70+ hooks covering every interaction pattern
- Zero opinion on markup or styling
- Full TypeScript inference on returned props
- The foundation for our Styled, Tailwind, and Primitive layers
## Next steps
Browse the hooks in the sidebar or check [Getting Started](/docs/overview/gettingstarted/introduction) for setup.
# Resources
Support channels, legacy versions and places to discover more about PrimeReact.
## Overview
Everything around the library, where to get help, find older versions, and stay up to date.
## What's here
- **Support**, get help on Discord, the community forum, or through premium support.
- **Legacy**, documentation for previous major versions.
- **Discover**, the store and social channels.
Pick a category from the sidebar to jump in.
# Add-Ons
Premium templates, UI blocks and design tooling that build on top of PrimeReact.
## Overview
Add-Ons are premium, production-ready resources built on top of PrimeReact. They help you skip the boilerplate and ship faster, from full application templates to ready-made UI blocks and design tooling.
## What's included
- **Templates**, complete, themeable application starters with layouts, pages and integrations wired up.
- **Blocks**, copy-and-paste UI sections for application, marketing and e-commerce pages.
- **Figma UI Kit**, the design source that mirrors the component library, for designing before you build.
- **Theme Designer**, a visual tool to craft and export your own design tokens and themes.
Pick a category from the sidebar to explore each add-on.
# Installation
Install PrimeReact and compose unstyled primitive components in your React project.
Start from our Next.js template, pre-configured with PrimeReact.
Primitive components ship **unstyled** — you compose the behavior and bring your own styles. They work in any React setup; the steps below show a Next.js example you can adapt to your own framework.
### Install Packages
Install PrimeReact using your favorite package manager:
```bash
npm install primereact
```
### PrimeReactProvider
Wrap your app with `PrimeReactProvider` so the primitives' shared context is available everywhere. No theme or preset is needed — you style everything yourself:
```tsx showLineNumbers title="components/prime-provider.tsx"
'use client';
import { PrimeReactProvider } from '@primereact/core';
export function PrimeProvider({ children }: { children: React.ReactNode }) {
return {children};
}
```
Then wrap your app with it in `app/layout.tsx`:
```tsx showLineNumbers title="app/layout.tsx" {1,6}
import { PrimeProvider } from '@/components/prime-provider';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
{children}
);
}
```
### Add a `cn` Helper (optional)
If you style with Tailwind, a `cn` helper makes merging class names easier. Install `tailwind-merge` and create `lib/utils.ts`:
```bash
npm install tailwind-merge
```
```ts showLineNumbers title="lib/utils.ts"
import { cn as _cn } from '@primeuix/utils';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: unknown[]) {
return twMerge(_cn(...inputs));
}
```
### Verify
Render the unstyled `Button` primitive, styled with your `cn` helper, to confirm everything is wired up:
```tsx
import { cn } from '@primeuix/utils';
import { Button } from 'primereact/button';
export default function VerifyDemo() {
return (
);
}
```
```tsx showLineNumbers {1}
import { Button } from 'primereact/button';
import { cn } from '@/lib/utils';
export default function VerifyInstallation() {
return ;
}
```
## Next Steps
[Browse the components](/docs/primitive/components/autocomplete) and compose the unstyled primitives you need, styling them with any CSS solution.
# Primitive
Unstyled React components with composable subcomponents. Behavior included, styling up to you.
## Overview
Primitives are low-level React components built on top of our headless hooks. Unlike hooks, they provide a compound component API, `Dialog.Root`, `Dialog.Trigger`, `Dialog.Content`, so you compose pieces without wiring up hook props manually.
Use primitives when you want the ergonomics of a component API but full freedom over styles. They're what our Styled and Tailwind layers are built on.
## What you get
- 70+ components with a compound API
- No styles, use any CSS solution you like
- Data attributes for state-based styling (`data-state`, `data-disabled`)
- Full accessibility and keyboard navigation
## Next steps
Open any component in the sidebar to see its subcomponents and composition examples.
# Resources
Support channels, legacy versions and places to discover more about PrimeReact.
## Overview
Everything around the library, where to get help, find older versions, and stay up to date.
## What's here
- **Support**, get help on Discord, the community forum, or through premium support.
- **Legacy**, documentation for previous major versions.
- **Discover**, the store and social channels.
Pick a category from the sidebar to jump in.
# Introduction
A standalone collection of React hooks from @primereact/hooks.
## Overview
`@primereact/hooks` is a standalone library of React hooks. Each hook solves one concrete problem, filtering a list, formatting a number, watching a media query, reacting to a resize, and none of them render DOM or depend on PrimeReact components.
You can use it in any React project. It is the same package PrimeReact itself builds on, published separately so you can reach for a single hook without pulling in a component library.
## What you get
- **No framework lock-in.** The hooks work with any React setup, CRA, Vite, Next.js, Remix, React Native Web.
- **Tree-shakeable.** Every hook has its own entry point; bundlers only ship what you import.
- **Typed.** Full TypeScript declarations. Generic hooks pick up your data type automatically.
- **SSR-safe.** Hooks that touch the DOM are marked `'use client'` internally, importing from a server component is fine.
## Conventions
A few things are true across the suite:
- Stateful hooks support controlled and uncontrolled usage. Pass `value` + `onChange` to control, or start from a `default*` prop and let the hook own the state.
- Options are passed as a single object. Return shapes are destructurable, pick what you need.
- Hook names follow the `useX` convention and ship from `@primereact/hooks/use-x`.
```tsx
import { useFilter } from '@primereact/hooks/use-filter';
const { filteredData, setValue } = useFilter({
data: customers,
field: 'name',
value: query
});
```
# Setup
Install @primereact/hooks and start using it in any React project.
## Install
`@primereact/hooks` is a standalone package. Install it on its own:
```bash
npm install @primereact/hooks
```
If you already use `primereact`, the hooks are bundled, you don't need a separate install, but you can still depend on `@primereact/hooks` directly if you prefer explicit versioning.
Peer dependency: **React 18+**.
## Import
Each hook has its own sub-path entry for optimal tree-shaking:
```tsx
import { useFilter } from '@primereact/hooks/use-filter';
import { useLocalStorage } from '@primereact/hooks/use-local-storage';
import { useMatchMedia } from '@primereact/hooks/use-match-media';
```
The root entry re-exports everything when convenience matters more than the last few bytes:
```tsx
import { useFilter, useLocalStorage } from '@primereact/hooks';
```
## TypeScript
Types ship with the package. Generic hooks infer from the data you pass in:
```tsx
interface Customer {
id: number;
name: string;
country: string;
}
const { filteredData } = useFilter({
data: customers,
field: 'name',
value: query
});
// filteredData is Customer[]
```
## SSR / Next.js
Hooks can be imported from server components without extra setup. Any file that touches the DOM is marked `'use client'` internally, so it moves to the client boundary on demand.
# useAttrSelector
Produce a stable, unique string from React.useId, handy for scoping CSS and DOM selectors.
## Usage
```tsx
import { useAttrSelector } from '@primereact/hooks/use-attr-selector';
```
```tsx
const selector = useAttrSelector('panel-'); // e.g. "panel-r0"
```
Pass an optional prefix; the hook strips colons and other delimiters React adds to `useId()` so the result is safe to use inside attribute selectors like `[data-scope="panel-r0"]`.
## Signature
```ts
function useAttrSelector(prefix?: string): string;
```
## When to use it
Reach for this when you need a unique string that also works as a CSS selector fragment, scoped styles, data attributes, or query targets inside a single component instance.
# useControlledState
State that works controlled or uncontrolled, following the React convention of value + onChange with a defaultValue fallback.
## Usage
```tsx
import { useControlledState } from '@primereact/hooks/use-controlled-state';
```
```tsx
const [value, setValue, isControlled] = useControlledState({
value: props.value,
defaultValue: props.defaultValue,
onChange: props.onChange
});
```
When the parent passes `value`, the hook stays controlled and delegates every update through `onChange`. When `value` is `undefined`, it owns the state internally, `defaultValue` seeds the first render.
## Signature
```ts
function useControlledState(options: { value?: T; defaultValue?: T; onChange?: (next: E) => void }): [T | undefined, (next: T | ((prev?: T) => T)) => void, boolean];
```
The returned tuple is `[value, setValue, isControlled]`. `isControlled` is a boolean frozen at mount, matching how React decides controlled vs uncontrolled inputs.
## When to use it
Any reusable component that exposes both `value` / `onChange` and a `defaultValue`. This hook handles the glue so you don't branch on `value === undefined` everywhere.
# useEventListener
Attach DOM event listeners declaratively, with automatic cleanup and a bind/unbind pair for manual control.
## Usage
```tsx
import { useEventListener } from '@primereact/hooks/use-event-listener';
```
```tsx
const [bind, unbind] = useEventListener({
target: 'document',
type: 'click',
listener: (event) => console.log(event),
when: true
});
```
The listener is attached when `when` is `true` and torn down automatically on unmount. Toggle `when` to pause without unmounting.
## Options
- `target`, `'document' | 'window' | 'body' | HTMLElement | (() => HTMLElement) | Ref | string | null`. Accepts a selector string, a ref, or a function that resolves the element on demand.
- `type`, event name, e.g. `'click'`, `'keydown'`, or a custom event.
- `listener`, handler function.
- `options?`, standard `addEventListener` options (`capture`, `passive`, `once`).
- `when?`, defaults to `true`; set `false` to disable.
## Manual control
The returned `[bind, unbind]` lets you attach/detach imperatively, useful when you want to listen in response to a user action rather than a prop:
```tsx
```
# useFilter
Generic filter hook for flat collections, with built-in match modes, accent-insensitive matching, locale support, and custom matcher registration.
## Usage
```tsx
import { useFilter } from '@primereact/hooks/use-filter';
```
```tsx
const { filteredData, value, setValue, isFiltered } = useFilter({
data: products,
field: ['name', 'category'],
matchMode: 'contains'
});
```
`useFilter` is a framework-level hook from `@primereact/hooks` that takes arbitrary data plus one or more filter rules and returns the filtered result. The same built-in matcher registry powers DataTable's filter feature, so behaviour stays consistent across any component built on top of it.
## Signature
```ts
function useFilter(options: UseFilterOptions): UseFilterReturn;
```
## Rules
A rule targets one field (or an array of fields for multi-field search) with a value and a match mode.
```tsx
defaultRules: [
{ field: 'name', value: 'iphone', matchMode: 'startsWith' },
{ field: ['name', 'category', 'description'], value: 'blue' },
{ field: 'price', value: [100, 500], matchMode: 'between' }
];
```
Composite rules carry multiple constraints tied by an AND/OR operator:
```tsx
{
field: 'name',
operator: 'and',
constraints: [
{ value: 'A', matchMode: 'startsWith' },
{ value: 'Z', matchMode: 'notEquals' }
]
}
```
## Basic
For the common "single field/multi-field search" case you can skip the `rules` array and use the `field` / `value` / `matchMode` shorthand.
```tsx
'use client';
import { ProductService, type Product } from '@/shared/services/product.service';
import { Search } from '@primeicons/react/search';
import { useFilter } from '@primereact/hooks/use-filter';
import { IconField } from '@primereact/ui/iconfield';
import { InputText } from '@primereact/ui/inputtext';
import { Tag } from '@primereact/ui/tag';
import * as React from 'react';
const statusSeverity: Record = {
INSTOCK: 'success',
LOWSTOCK: 'warn',
OUTOFSTOCK: 'danger'
};
export default function BasicDemo() {
const [products, setProducts] = React.useState([]);
React.useEffect(() => {
setProducts(ProductService.getProductsData().slice(0, 12));
}, []);
const [search, setSearch] = React.useState('');
const { filteredData } = useFilter({
data: products,
field: ['name', 'category', 'code'],
value: search,
matchMode: 'contains'
});
return (
);
}
```
## Global matcher registry
For matchers you want available everywhere, `registerMatcher` writes into a shared table the hook consults alongside the built-ins.
```tsx
import { registerMatcher } from '@primereact/hooks/use-filter';
registerMatcher('greaterThanAvg', (value, filter) => Number(value) > Number(filter));
```
Local `matchers` option always wins when both are present. Call `unregisterMatcher(name)` to remove an entry (useful in tests).
## Lazy (server-side)
Set `lazy: true` to skip client-side filtering. `filteredData` is returned unchanged. Whenever the rules settle (respecting `filterDelay`), `onLazyLoad` fires with the current rule set, typically you turn that into a request and replace `data` with the server response.
```tsx
const [data, setData] = React.useState([]);
const [query, setQuery] = React.useState('');
useFilter({
data,
lazy: true,
field: ['name', 'country'],
value: query,
onValueChange: (v) => setQuery((v as string) ?? ''),
filterDelay: 300,
onLazyLoad: async ({ rules }) => {
const res = await fetch('/api/customers?' + toQuery(rules));
setData(await res.json());
}
});
```
## Cursor API
Setters by index:
```tsx
const { setValue, setMatchMode, setOperator, setConstraintValue } = useFilter({ ... });
setValue(0, 'amy');
setConstraintValue(0, 1, 'Z');
```
Or scoped by rule:
```tsx
const { rule } = useFilter({ ... });
rule(0)?.setValue('amy');
rule('name')?.addConstraint('equals');
rule('name')?.constraint(1)?.setValue('Z');
```
# useHotKey
Bind keyboard shortcuts with modifier combinations, single key or array of keys, with enable flag for scoping.
## Usage
```tsx
import { useHotKey } from '@primereact/hooks/use-hot-key';
```
```tsx
useHotKey('ctrl+k', (event) => {
event.preventDefault();
openCommandPalette();
});
```
Modifiers are case-insensitive and accept aliases: `ctrl`/`control`, `cmd`/`meta`/`command`, `alt`/`option`, `shift`. The special strings `space` and `spacebar` resolve to the space key.
Pass an array of specs to bind multiple shortcuts to the same handler:
```tsx
useHotKey(['ctrl+k', 'meta+k'], openCommandPalette);
```
## Signature
```ts
function useHotKey(
keys: string | string[],
handler: (event: KeyboardEvent) => void,
options?: {
target?: Document | HTMLElement | null;
event?: 'keydown' | 'keyup' | 'keypress';
when?: boolean;
}
): void;
```
Defaults: listens on `document` for `keydown` while `when` is true. Pass a target element to scope shortcuts to a specific region.
# useId
Stable unique identifier with an optional explicit override.
## Usage
```tsx
import { useId } from '@primereact/hooks/use-id';
```
```tsx
const id = useId(); // e.g. "pr_id_r0"
const fixed = useId('my-panel'); // "my-panel"
```
Pass a value to opt out of the generated id, useful for components that accept an optional `id` prop but need a fallback.
## Signature
```ts
function useId(initialValue?: string): string;
```
Internally wraps `React.useId()` and strips the characters React inserts (`:`, `«`, `»`) so the result is safe to use in selectors and HTML attributes.
# useIntersectionObserver
A thin wrapper over the IntersectionObserver API with imperative observe/unobserve controls.
## Usage
```tsx
import { useIntersectionObserver } from '@primereact/hooks/use-intersection-observer';
```
```tsx
const ref = React.useRef(null);
const { observe, isIntersecting } = useIntersectionObserver({
threshold: 0.5,
onIntersect: (entries) => console.log(entries)
});
React.useEffect(() => {
if (ref.current) observe(ref.current);
}, [observe]);
return
{isIntersecting ? 'visible' : 'off-screen'}
;
```
## Options
Standard `IntersectionObserverInit` fields (`root`, `rootMargin`, `threshold`) plus:
- `disabled?`, skip creating the observer entirely.
- `onIntersect?(entries, observer)`, called on every intersection change.
- `fallback?()`, invoked when `IntersectionObserver` is unavailable.
## Returns
- `entries`, current entries from the last callback.
- `isIntersecting`, `true` if any observed element is intersecting.
- `observe(el)`, `unobserve(el)`, `disconnect()`, imperative controls.
- `observer`, the underlying `IntersectionObserver` instance (or `null` when disabled).
## When to use it
Pick this hook when you need direct control, observing multiple elements, toggling dynamically, or integrating with virtualization. For simple "is this one element visible" cases, you may prefer the lighter-weight visibility patterns built on top of it.
# useIsMobile
Boolean flag that flips when the viewport crosses a mobile breakpoint.
## Usage
```tsx
import { useIsMobile } from '@primereact/hooks/use-is-mobile';
```
```tsx
const isMobile = useIsMobile(); // default breakpoint: 768px
const isTablet = useIsMobile(1024); // custom breakpoint
```
Returns `true` when the viewport width is **below** the breakpoint. Implemented on top of `useMatchMedia`, so it updates live as the window resizes.
## Signature
```ts
function useIsMobile(breakpoint?: number): boolean;
```
Default breakpoint is 768px. Pass any max-width you care about, the hook resolves the corresponding media query for you.
# useKeyFilter
Block individual keystrokes that don't match a pattern, before they reach the input.
## Usage
```tsx
import { useKeyFilter } from '@primereact/hooks/use-key-filter';
```
```tsx
const { onBeforeInput, onKeyPress, onPaste } = useKeyFilter({ pattern: 'int' });
;
```
Spread the returned handlers onto a native input. Keystrokes and pastes that don't match the pattern are rejected before they change the value.
## Signature
```ts
function useKeyFilter(options: UseKeyFilterOptions): UseKeyFilterExposes;
```
## Options
- `pattern`, a preset name or a `RegExp`. Presets: `pint`, `int`, `pnum`, `num`, `money`, `hex`, `email`, `alpha`, `alphanum`.
- `validateOnly?`, when `true`, individual keys are allowed and the whole value is validated instead (use `validate` on form events).
## Returns
`{ onBeforeInput, onKeyPress, onPaste, validate }`. The first three are input handlers to spread; `validate(event)` returns a boolean for the `validateOnly` flow.
## Basic
```tsx
'use client';
import { useKeyFilter } from '@primereact/hooks';
import { InputText } from '@primereact/ui/inputtext';
import { Label } from '@primereact/ui/label';
import * as React from 'react';
export default function PatternDemo() {
const { onKeyPress: onIntegerKeyPress } = useKeyFilter({ pattern: 'int' });
const { onKeyPress: onNumberKeyPress } = useKeyFilter({ pattern: 'num' });
const { onKeyPress: onMoneyKeyPress } = useKeyFilter({ pattern: 'money' });
const { onKeyPress: onHexKeyPress } = useKeyFilter({ pattern: 'hex' });
const { onKeyPress: onAlphaKeyPress } = useKeyFilter({ pattern: 'alpha' });
const { onKeyPress: onAlphanumKeyPress } = useKeyFilter({ pattern: 'alphanum' });
const [integer, setInteger] = React.useState('');
const [number, setNumber] = React.useState('');
const [money, setMoney] = React.useState('');
const [hex, setHex] = React.useState('');
const [alphabetic, setAlphabetic] = React.useState('');
const [alphanumeric, setAlphanumeric] = React.useState('');
return (
);
}
```
# useLocalStorage
State persisted to localStorage, with SSR-safe hydration and custom serialization.
## Usage
```tsx
import { useLocalStorage } from '@primereact/hooks/use-local-storage';
```
```tsx
const [sizes, setSizes, removeSizes] = useLocalStorage({
key: 'splitter-sizes',
initialValue: [50, 50]
});
```
The hook renders `initialValue` for SSR and the first client render, then reads the stored value in a layout effect, so the real value appears before paint and there's no hydration mismatch or flash.
## Options
- `key`, storage key.
- `initialValue`, value used when nothing is stored yet.
- `serializer?` / `deserializer?`, default to `JSON.stringify` / `JSON.parse`. Override for dates, maps, or custom codecs.
## Returns
`[value, setValue, remove]`. `setValue` accepts a value or an updater function (like `useState`). `remove()` clears the key from storage and resets to `initialValue`.
# useMask
Format an input as the user types, phone, date, currency and similar fixed patterns.
## Usage
```tsx
import { useMask } from '@primereact/hooks/use-mask';
```
```tsx
const { ref, value, rawValue, isComplete } = useMask({ mask: '(999) 999-9999' });
;
```
Attach `ref` to any component that forwards a ref to a native input. The hook formats keystrokes against `mask` and keeps both the masked and raw values in sync.
## Signature
```ts
function useMask(options: UseMaskOptions): UseMaskReturn;
```
## Options
- `mask`, pattern string: `9` numeric, `a` alphabetic, `*` alphanumeric. Literals like `(`, `)`, `-` and `/` are inserted automatically. A `?` marks everything after it as optional.
- `slotChar?`, placeholder for unfilled slots (default `_`). Pass a full template like `dd/mm/yyyy` to label each slot.
- `autoClear?`, clear an incomplete value on blur (default `true`).
- `value?` / `defaultValue?` / `onValueChange?`, controlled / uncontrolled masked value.
- `onComplete?`, fires when every required slot is filled.
## Returns
`{ ref, value, rawValue, isComplete, setValue }`. `value` is the masked string, `rawValue` strips the literals and placeholders, `isComplete` is `true` once all required slots are filled.
## Basic
```tsx
'use client';
import { useMask } from '@primereact/hooks';
import { InputText } from '@primereact/ui/inputtext';
export default function BasicDemo() {
const { ref } = useMask({ mask: '99-999999' });
return (
);
}
```
# useMatchMedia
Reactive boolean for any CSS media query.
## Usage
```tsx
import { useMatchMedia } from '@primereact/hooks/use-match-media';
```
```tsx
const prefersDark = useMatchMedia('(prefers-color-scheme: dark)');
const isNarrow = useMatchMedia('(max-width: 768px)');
```
Subscribes to the query via `window.matchMedia` and updates on change. Toggle the `when` flag to pause listening without unmounting:
```tsx
const matches = useMatchMedia('(max-width: 600px)', isActive);
```
## Signature
```ts
function useMatchMedia(query: string, when?: boolean): boolean;
```
Server renders return `false`; the hook syncs to the real value after hydration.
# useMountEffect
Run an effect exactly once, after the first render.
## Usage
```tsx
import { useMountEffect } from '@primereact/hooks/use-mount-effect';
```
```tsx
useMountEffect(() => {
console.log('mounted');
return () => console.log('cleanup');
});
```
Equivalent to `useEffect(fn, [])` but reads clearer at the call site. The optional return value is treated as the cleanup function, just like `useEffect`.
## Signature
```ts
function useMountEffect(effect: React.EffectCallback): void;
```
# useMounted
SSR-safe flag that flips to true once the component mounts on the client.
## Usage
```tsx
import { useMounted } from '@primereact/hooks/use-mounted';
```
```tsx
const mounted = useMounted();
if (!mounted) return null;
return ;
```
Useful when you need to gate content that depends on browser APIs without causing a hydration mismatch.
## Options
```ts
useMounted({
onMounted: () => console.log('mounted'),
onUnmounted: () => console.log('unmounted')
});
```
Both callbacks are optional.
## Signature
```ts
function useMounted(options?: { onMounted?: () => void; onUnmounted?: () => void }): boolean;
```
# useNumberFormatter
Locale-aware number formatting and parsing built on Intl.NumberFormat, decimal or currency, with custom prefix/suffix and rounding.
## Usage
```tsx
import { useNumberFormatter } from '@primereact/hooks/use-number-formatter';
```
```tsx
const formatter = useNumberFormatter({
value: 1234.56,
locale: 'en-US',
mode: 'currency',
currency: 'USD'
});
formatter.formattedValue; // "$1,234.56"
formatter.formatValue(99); // "$99.00"
formatter.parseValue('$1,234.56'); // 1234.56
```
## Options
- `value?`, optional input; if provided, `formattedValue` in the return mirrors it.
- `locale?`, `localeMatcher?`, passed to `Intl.NumberFormat`.
- `mode?`, `'decimal'` (default) or `'currency'`.
- `currency?`, `currencyDisplay?`, ISO code and display style.
- `useGrouping?`, thousands separators. Default `true`.
- `minFractionDigits?`, `maxFractionDigits?`, `roundingMode?`, fraction handling.
- `prefix?`, `suffix?`, additional text wrapped around the formatted value.
- `min?`, lower bound; controls whether a minus sign is allowed.
- `format?`, `false` returns the raw string without applying the formatter.
## Returns
- `formattedValue`, formatted representation of `options.value`.
- `formatValue(value)` / `parseValue(text)`, format or parse on demand.
- `addWithPrecision(base, inc)`, floating-point-safe addition, useful for steppers.
- Character classifiers (`isNumeralChar`, `isMinusSign`, `isDecimalSign`, `allowMinusSign`) and index helpers (`getDecimalCharIndexes`, `getCharIndexes`, `getDecimalLength`, `concatValues`) that power input-mask behaviour.
- `groupChar`, `prefixChar`, `suffixChar`, resolved separator characters for the active locale.
- `resolvedOptions()`, forwards `Intl.NumberFormat#resolvedOptions`.
- `constructParser()`, rebuild the internal parser; the hook calls it automatically when options change.
## When to use it
Anywhere you want consistent localized number rendering without maintaining your own parsers, inputs with currency/percent formatting, read-only totals, calculator-style UIs.
# usePresence
Coordinate enter/exit animations by delaying unmount until CSS transitions finish.
## Usage
```tsx
import { usePresence } from '@primereact/hooks/use-presence';
```
```tsx
function Dialog({ open }: { open: boolean }) {
const { present, mounted, ref } = usePresence(open);
if (!present) return null;
return (
...
);
}
```
The element stays in the tree after `open` flips to `false` until `transitionend` or `animationend` fires on it, giving your CSS a chance to run the exit animation.
## Signature
```ts
function usePresence(
open: boolean,
fallbackMs?: number
): {
present: boolean;
exiting: boolean;
mounted: boolean;
ref: (node: HTMLElement | null) => void;
};
```
- `present`, whether the element should render.
- `mounted`, set to `true` a few frames after opening; use it to toggle the visible state in CSS so the transition can play.
- `exiting`, `true` while the close animation is running.
- `ref`, callback ref that must be attached to the animated element. Without it the hook cannot observe the transition.
# usePrevious
Remember the value of a variable from the previous render.
## Usage
```tsx
import { usePrevious } from '@primereact/hooks/use-previous';
```
```tsx
const [count, setCount] = React.useState(0);
const prev = usePrevious(count);
React.useEffect(() => {
if (prev !== undefined && prev !== count) {
console.log(`changed from ${prev} to ${count}`);
}
}, [count, prev]);
```
Returns `null` on the first render, then the value from the prior render on every subsequent render.
## Signature
```ts
function usePrevious(value: T): T | null | undefined;
```
# useProps
Split incoming props into known props and extra attrs, preserving referential stability when values don't change.
## Usage
```tsx
import { useProps } from '@primereact/hooks/use-props';
```
```tsx
const defaults = { variant: 'primary', size: 'medium' };
const { props, attrs } = useProps(defaults, userProps);
;
```
- `props` contains only the keys that appear in `defaults`, with values taken from `userProps` when present.
- `attrs` contains the remaining keys from `userProps`, typically DOM attributes and event handlers you want to spread onto the rendered element.
If the computed `props` and `attrs` are shallowly equal to the previous result, the same references are returned. This prevents cascading `useMemo` / `React.memo` invalidations when a parent passes a new object literal with identical values.
## Signature
```ts
function useProps(
defaults?: P1,
userProps?: P2
): {
props: Pick;
attrs: Omit;
};
```
## When to use it
Building a reusable component that accepts both known props and passthrough attributes, `useProps` gives you a clean split without the boilerplate of `const { knownA, knownB, ...rest } = props`.
# useQueueTask
Deduplicate work by id and flush it on the next microtask.
## Usage
```tsx
import { useQueueTask } from '@primereact/hooks/use-queue-task';
```
```tsx
const queue = useQueueTask();
function schedule(rowId: string) {
queue(rowId, () => recalculate(rowId));
}
```
Calling `queue(id, task)` replaces any pending task for the same `id`. All queued tasks run together in a single microtask, so many calls within the same synchronous batch collapse into one flush.
## Signature
```ts
function useQueueTask(): (id: string | number, task: () => void) => void;
```
## When to use it
Coalescing expensive work triggered from multiple places in the same render, layout measurements, cache invalidations, or derived state updates where only the latest value per key matters.
# useScrollTop
useScrollTop is a hook that provides a way to scroll to the top of a container.
## Usage
```tsx
import { useScrollTop } from '@primereact/hooks/use-scrolltop';
```
```tsx
const scrollTop = useScrollTop();
```
## Examples
### Basic
useScrollTop listens window scroll by default.
```tsx
'use client';
import { AngleDown } from '@primeicons/react/angle-down';
import { ChevronUp } from '@primeicons/react/chevron-up';
import { useScrollTop } from '@primereact/hooks';
import { Button } from '@primereact/ui/button';
export default function BasicDemo() {
const { scrollToTop, visible } = useScrollTop();
return (
Scroll down the page to display the ScrollTop component.
{visible && (
)}
);
}
```
Setting the _target_ option binds useScrollTop to this element that has scrolling content.
### Element
```tsx
'use client';
import { ArrowUp } from '@primeicons/react';
import { useScrollTop } from '@primereact/hooks';
import { Button } from '@primereact/ui/button';
import * as React from 'react';
export default function ElementDemo() {
const [target, setTarget] = React.useState(null);
const { scrollToTop, visible } = useScrollTop({
target,
threshold: 100
});
return (
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae
et leo duis ut diam. Ultricies mi quis hendrerit dolor magna eget est lorem. Amet consectetur adipiscing elit ut. Nam libero justo
laoreet sit amet. Pharetra massa massa ultricies mi quis hendrerit dolor magna. Est ultricies integer quis auctor elit sed
vulputate. Consequat ac felis donec et. Tellus orci ac auctor augue mauris. Semper feugiat nibh sed pulvinar proin gravida
hendrerit lectus a. Tincidunt arcu non sodales neque sodales. Metus aliquam eleifend mi in nulla posuere sollicitudin aliquam
ultrices. Sodales ut etiam sit amet nisl purus. Cursus sit amet dictum sit amet. Tristique senectus et netus et malesuada fames ac
turpis egestas. Et tortor consequat id porta nibh venenatis cras sed. Diam maecenas ultricies mi eget mauris. Eget egestas purus
viverra accumsan in nisl nisi. Suscipit adipiscing bibendum est ultricies integer. Mattis aliquam faucibus purus in massa tempor
nec.
{visible && (
)}
);
}
```
# useSortableList
Reorder items in a list, optionally transfer them between lists, with state and handlers you spread onto your own DOM.
## Usage
```tsx
import { useSortableList } from '@primereact/hooks/use-sortable-list';
```
```tsx
const { dragState, getListHandlers, getItemHandlers } = useSortableList<'source' | 'target', Item>({
onReorder: (listId, from, to) => reorder(listId, from, to),
onTransfer: (sourceId, targetId, items, targetIndex) => transfer(sourceId, targetId, items, targetIndex)
});
```
Spread `getListHandlers(listId)` on the list wrapper and `getItemHandlers(listId, index, item)` on each draggable row. The hook tracks hover index internally so drop events always resolve to the right target, even when the user releases over a transitioning item.
## Options
- `onReorder(listId, from, to)`, same-list move.
- `onTransfer?(sourceId, targetId, items, targetIndex?)`, cross-list drop. Omit to make transfers no-ops.
- `canTransfer?(sourceId, targetId)`, opt out of specific pairings.
- `getSelectedItems?(listId, item)`, return an array for multi-drag (defaults to `[item]`).
## State
`dragState` exposes `isDragging`, `draggedItems`, `draggedIndex`, `sourceListId`, `dragOverListId`, `dragOverIndex`, enough to style placeholders, ghosts, or drop indicators.
## Basic
Reorder items inside a single list. The hook feeds you hover state so you can style the active drop target however you like.
```tsx
'use client';
import { useSortableList } from '@primereact/hooks/use-sortable-list';
import * as React from 'react';
interface Task {
id: number;
title: string;
}
const initialTasks: Task[] = [
{ id: 1, title: 'Review pull requests' },
{ id: 2, title: 'Write release notes' },
{ id: 3, title: 'Triage bug reports' },
{ id: 4, title: 'Prepare demo for Friday' },
{ id: 5, title: 'Answer community questions' }
];
export default function BasicDemo() {
const [tasks, setTasks] = React.useState(initialTasks);
const reorder = React.useCallback((_listId: 'tasks', from: number, to: number) => {
setTasks((prev) => {
const next = prev.slice();
const [moved] = next.splice(from, 1);
next.splice(to, 0, moved);
return next;
});
}, []);
const { dragState, getListHandlers, getItemHandlers } = useSortableList<'tasks', Task>({
onReorder: reorder
});
const listHandlers = getListHandlers('tasks');
return (
Lenient: a branch is kept if any descendant matches. Strict: leaves must match; parents are kept
only when a descendant matches.
);
}
```
## Rules
Same shape as `useFilter`. Fields resolve against `node.data` first, then against the node itself. So a flat `{ key, label, children }` works the same as the DataTable-style `{ key, data: { name, type }, children }`.
```tsx
// node.data.name
useTreeFilter({
nodes,
defaultRules: [{ field: 'name', value: 'doc', matchMode: 'contains' }],
filterMode: 'lenient'
});
// node.label (top-level)
useTreeFilter({
nodes,
defaultRules: [{ field: 'label', value: 'doc', matchMode: 'contains' }]
});
```
## Shorthand
For single-field filtering, skip the rules array and pass `field` directly. The hook builds a `{ field, value, matchMode }` rule for you and exposes `value` / `setValue` for the input.
```tsx
const { filteredNodes, value, setValue, isFiltered } = useTreeFilter({
nodes,
field: 'label',
matchMode: 'contains' // optional, defaults to 'contains'
});
setValue(e.target.value)} />;
```
`value` follows the standard controlled / uncontrolled convention:
| Mode | Setup | When to use |
| ---------------- | -------------------------------------------- | --------------------------------------------------------------------------- |
| **Uncontrolled** | omit `value`, optionally pass `defaultValue` | Default. The hook keeps the state and `setValue` updates it. |
| **Controlled** | pass both `value` and `onValueChange` | When the parent already owns the query (URL sync, parent re-renders, etc.). |
Passing `rules` or `defaultRules` turns the shorthand off, use one or the other.
## Lazy
With `lazy: true` the client-side walk is skipped and `filteredNodes` is returned untouched. `onLazyLoad` fires with the current rules and the active `filterMode`; forward both so your backend can apply the same branch logic.
```tsx
useTreeFilter({
nodes,
lazy: true,
defaultRules: [{ field: 'label', value: null }],
filterMode: 'lenient',
onLazyLoad: ({ rules, filterMode }) => {
// fetch filtered tree from the server
}
});
```
## Custom matchers
Reuse `matchers` and the shared `registerMatcher` / `unregisterMatcher` helpers from `@primereact/hooks/use-filter`.
# useUnmountEffect
Run an effect exactly once, when the component unmounts.
## Usage
```tsx
import { useUnmountEffect } from '@primereact/hooks/use-unmount-effect';
```
```tsx
useUnmountEffect(() => {
socket.close();
});
```
Equivalent to `useEffect(() => cleanup, [])`, expressed as the cleanup by itself. Reads clearer when the mount path has nothing to do.
## Signature
```ts
function useUnmountEffect(effect: React.EffectCallback): void;
```
# useUpdateEffect
useEffect that skips the initial mount and runs only on subsequent dependency changes.
## Usage
```tsx
import { useUpdateEffect } from '@primereact/hooks/use-update-effect';
```
```tsx
useUpdateEffect(() => {
onValueChange(value);
}, [value]);
```
The effect does not run on the first render. Every time one of the dependencies changes afterwards, it fires like a normal `useEffect`.
## Signature
```ts
function useUpdateEffect(effect: React.EffectCallback, deps?: React.DependencyList): void;
```
## When to use it
Triggering side effects that only make sense _after_ a user-driven change, firing a controlled `onChange`, syncing to a remote store, or announcing transitions.
# useViewTransition
Wrap state updates in the View Transitions API, with a graceful fallback on unsupported browsers.
## Usage
```tsx
import { useViewTransition } from '@primereact/hooks/use-view-transition';
```
```tsx
const startTransition = useViewTransition();
function toggleTheme() {
startTransition(() => {
setTheme(theme === 'light' ? 'dark' : 'light');
});
}
```
Calls `document.startViewTransition(callback)` when the API exists; otherwise the callback runs synchronously. That means your code always works, the animation is the enhancement.
## Signature
```ts
function useViewTransition(): (callback: () => void) => void;
```
## Notes
View Transitions are driven by CSS (`::view-transition-*` pseudo-elements and `view-transition-name`). This hook is a small API hook, pair it with the CSS your design system defines.
# useVisibilityChange
Reactive boolean that reflects the document's Page Visibility state.
## Usage
```tsx
import { useVisibilityChange } from '@primereact/hooks/use-visibility-change';
```
```tsx
const isVisible = useVisibilityChange();
React.useEffect(() => {
if (!isVisible) pauseTimers();
else resumeTimers();
}, [isVisible]);
```
Listens to the `visibilitychange` event and returns `true` while the tab is active, `false` when backgrounded or minimized.
## Signature
```ts
function useVisibilityChange(): boolean;
```
## When to use it
Throttle or pause work while the tab isn't visible, polling requests, animations, WebSocket pings, and resume when the user comes back.
# Add-Ons
Premium templates, UI blocks and design tooling that build on top of PrimeReact.
## Overview
Add-Ons are premium, production-ready resources built on top of PrimeReact. They help you skip the boilerplate and ship faster, from full application templates to ready-made UI blocks and design tooling.
## What's included
- **Templates**, complete, themeable application starters with layouts, pages and integrations wired up.
- **Blocks**, copy-and-paste UI sections for application, marketing and e-commerce pages.
- **Figma UI Kit**, the design source that mirrors the component library, for designing before you build.
- **Theme Designer**, a visual tool to craft and export your own design tokens and themes.
Pick a category from the sidebar to explore each add-on.
# Resources
Support channels, legacy versions and places to discover more about PrimeReact.
## Overview
Everything around the library, where to get help, find older versions, and stay up to date.
## What's here
- **Support**, get help on Discord, the community forum, or through premium support.
- **Legacy**, documentation for previous major versions.
- **Discover**, the store and social channels.
Pick a category from the sidebar to jump in.
# Configuration
Application wide configuration for PrimeReact.
## Provider
Wrap your app with `PrimeReactProvider` in your main file (like `main.tsx` or `App.tsx`). This enables PrimeReact features everywhere in your app:
```tsx showLineNumbers {10, 12}
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import { PrimeReactProvider } from "@primereact/core";
...
createRoot(document.getElementById('root')!).render(
,
)
```
## License
PrimeReact is a commercially licensed library. Provide your license key via the `license` property of the provider to activate it. You can obtain a key from your [PrimeUI](https://primeui.dev/pricing) account.
```tsx showLineNumbers {4}
import { PrimeReactProvider } from '@primereact/core';
ReactDOM.createRoot(document.getElementById('root')).render(
);
```
## Theme
Style mode offers theming based on a design token based architecture. See the [styled mode](/docs/theming/styled) documentation for details such as building your own theme.
```tsx full showLineNumbers {2,5-12,16}
...
import Aura from '@primeuix/themes/aura';
import { PrimeReactProvider } from '@primereact/core';
const theme = {
preset: Aura,
options: {
prefix: 'p',
darkModeSelector: 'system',
cssLayer: false,
cssVariables: true,
scoped: false
}
};
ReactDOM.createRoot(document.getElementById('root')).render(
);
```
## Unstyled
Unstyled mode instructs the components not to add any built-in style classes so that they can be styled using custom css or libraries like Tailwind and Bootstrap. Visit Unstyled mode documentation for more information.
```tsx showLineNumbers {6}
import { PrimeReactProvider } from '@primereact/core';
...
ReactDOM.createRoot(document.getElementById('root')).render(
);
```
The same prop works on a single component, which takes precedence over the provider. This suits an application that is themed overall but has one screen styled differently.
```tsx
…
```
There is also a third option that does not involve the flag at all. Importing from `primereact` gives the unstyled primitives directly, so the theming layer never enters the bundle:
```tsx
import { Select } from '@primereact/ui/select'; // themed, opt out with `unstyled`
import { Select } from 'primereact/select'; // unstyled by construction
```
## Preflight
Preflight resets the browser defaults on the native elements PrimeReact renders, such as `button`, `input`, `ul`, `table`, `img` and the heading tags. It removes the margins, borders, font inheritance and list styling browsers apply by default, so a component's own styles are the only ones in effect. It is on by default.
The reset only applies to elements PrimeReact renders itself, scoped through the `data-scope` attribute each component sets. A `