Package Exports
- @ariakit/utils
- @ariakit/utils/package.json
Readme
@ariakit/utils
Important: This package is an internal dependency of Ariakit and does not follow semantic versioning, meaning breaking changes may occur in patch and minor versions.
Shared framework-agnostic utilities used by Ariakit packages.
Contents
Installation
npm i @ariakit/utilsUsage
Import helpers from the package root:
import { invariant } from "@ariakit/utils";This package is ESM-only and exposes a single public entrypoint.
API reference
- Array utilities
- DOM utilities
- Event utilities
- Focus utilities
isFocusableisTabbablegetAllFocusableIngetAllFocusablegetFirstFocusableIngetFirstFocusablegetAllTabbableIngetAllTabbablegetFirstTabbableIngetFirstTabbablegetLastTabbableIngetLastTabbablegetNextTabbableIngetNextTabbablegetPreviousTabbableIngetPreviousTabbablegetClosestFocusablehasFocushasFocusWithinfocusIfNeededdisableFocusdisableFocusInrestoreFocusInfocusIntoView
- General utilities
- Platform utilities
- Type utilities
- Undo utilities
Array utilities
Array helpers used by Ariakit packages.
toArray
function toArray<T>(arg: T): T extends readonly any[] ? T : T[];Transforms arg into an array if it's not already.
Example:
toArray("a"); // ["a"]
toArray(["a"]); // ["a"]addItemToArray
function addItemToArray<T extends any[]>(
array: T,
item: T[number],
index = -1,
): T;Immutably adds an item to an array.
Returns: A new array with the item in the passed array index.
Example:
addItemToArray(["a", "b", "d"], "c", 2); // ["a", "b", "c", "d"]flatten2DArray
function flatten2DArray<T>(array: T[][]): T[];Flattens a 2D array into a one-dimensional array.
Returns: A one-dimensional array.
Example:
flatten2DArray([["a"], ["b"], ["c"]]); // ["a", "b", "c"]reverseArray
function reverseArray<T>(array: T[]): T[];Immutably reverses an array.
Returns: Reversed array.
Example:
reverseArray(["a", "b", "c"]); // ["c", "b", "a"]DOM utilities
DOM helpers for browser, iframe, text input, popup, and scrolling behavior.
canUseDOM
const canUseDOM: boolean;It's true if it is running in a browser environment or false if it is not (SSR).
Example:
const title = canUseDOM ? document.title : "";getDocument
function getDocument(node?: Window | Document | Node | null): Document;Returns element.ownerDocument || document.
getWindow
function getWindow(node?: Window | Document | Node | null): Window;Returns element.ownerDocument.defaultView || window.
getActiveElement
function getActiveElement(
node?: Node | null,
activeDescendant = false,
): HTMLElement | null;Returns element.ownerDocument.activeElement.
contains
function contains(parent: Node, child: Node): boolean;Similar to Element.prototype.contains, but a little bit faster when element is the same as child.
Example:
contains(document.getElementById("parent"), document.getElementById("child"));isElement
function isElement(target: EventTarget | null | undefined): target is Element;Checks whether the given event target is an element.
event.target and event.relatedTarget are EventTargets, which aren't necessarily elements — for example window or an XMLHttpRequest when an event is dispatched programmatically. Calling Element-only methods such as hasAttribute on those throws, so guard with this before treating them as elements. When you only need a Node — for example to call contains — use isNode instead.
It tests nodeType rather than instanceof Element so that elements coming from same-origin child frames (which addGlobalEventListener also listens on) aren't wrongly rejected for belonging to a different realm.
Example:
if (isElement(event.target)) {
event.target.hasAttribute("data-active");
}isNode
function isNode(target: EventTarget | null | undefined): target is Node;Checks whether the given event target is a node.
Like isElement, but only requires the target to be a Node rather than an element — useful before calling contains, which accepts any node. It still rejects non-node EventTargets (such as window or an XMLHttpRequest) that would make contains throw.
Example:
if (isNode(event.target)) {
contains(element, event.target);
}isFrame
function isFrame(element: Element): element is HTMLIFrameElement;Checks whether element is a frame element.
isButton
function isButton(element: { tagName: string; type?: string }): boolean;Checks whether element is a native HTML button element.
Example:
isButton(document.querySelector("button")); // true
isButton(document.querySelector("input[type='button']")); // true
isButton(document.querySelector("div")); // false
isButton(document.querySelector("input[type='text']")); // false
isButton(document.querySelector("div[role='button']")); // falseisVisible
function isVisible(element: Element): boolean;Checks if the element is visible or not.
isTextField
function isTextField(
element: Element,
): element is HTMLInputElement | HTMLTextAreaElement;Check whether the given element is a text field, where text field is defined by the ability to select within the input.
Example:
isTextField(document.querySelector("div")); // false
isTextField(document.querySelector("input")); // true
isTextField(document.querySelector("input[type='button']")); // false
isTextField(document.querySelector("textarea")); // trueisTextbox
function isTextbox(element: HTMLElement): boolean;Check whether the given element is a text field or a content editable element.
getTextboxValue
function getTextboxValue(element: HTMLElement): string;Returns the value of the text field or content editable element as a string.
getTextboxSelection
function getTextboxSelection(element: HTMLElement): {
start: number;
end: number;
};Returns the start and end offsets of the selection in the element.
getPopupRole
function getPopupRole(
element?: Element | null,
fallback?: AriaHasPopup,
): AriaHasPopup;Returns the popup role from the element's role attribute, if it has one.
getPopupItemRole
function getPopupItemRole(
element?: Element | null,
fallback?: AriaRole,
): string | undefined;Returns the item role attribute based on the popup's role.
scrollIntoViewIfNeeded
function scrollIntoViewIfNeeded(
element: Element,
arg?: boolean | ScrollIntoViewOptions,
): void;Calls element.scrollIntoView() if the element is hidden or partly hidden in the viewport.
getScrollingElement
function getScrollingElement(
element?: Element | null,
): HTMLElement | Element | null;Returns the scrolling container element of a given element.
isPartiallyHidden
function isPartiallyHidden(element: Element): boolean;Determines whether an element is hidden or partially hidden in the viewport.
setSelectionRange
function setSelectionRange(
element: HTMLInputElement | HTMLTextAreaElement,
...args: Parameters<typeof HTMLInputElement.prototype.setSelectionRange>
): void;SelectionRange only works on a few types of input. Calling setSelectionRange on an unsupported input type may throw an error on certain browsers. To avoid it, we check if its type supports SelectionRange first. It will be a noop to non-supported types until we find a workaround.
See: https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange
sortBasedOnDOMPosition
function sortBasedOnDOMPosition<T>(
items: T[],
getElement: (item: T) => Element | null | undefined,
): T[];Sort the items based on their DOM position.
Event utilities
Event helpers for dispatching and interpreting browser events.
isPortalEvent
function isPortalEvent(event: Pick<Event, "currentTarget" | "target">): boolean;Returns true if event has been fired within a React Portal element.
isSelfTarget
function isSelfTarget(event: Pick<Event, "target" | "currentTarget">): boolean;Returns true if event.target and event.currentTarget are the same.
isOpeningInNewTab
function isOpeningInNewTab(
event: Pick<MouseEvent, "currentTarget" | "metaKey" | "ctrlKey">,
): boolean;Checks whether the user event is triggering a page navigation in a new tab.
isDownloading
function isDownloading(
event: Pick<MouseEvent, "altKey" | "currentTarget">,
): boolean;Checks whether the user event is triggering a download.
fireEvent
function fireEvent(
element: Element,
type: string,
eventInit?: EventInit,
): boolean;Creates and dispatches an event.
Example:
fireEvent(document.getElementById("id"), "blur", {
bubbles: true,
cancelable: true,
});fireBlurEvent
function fireBlurEvent(element: Element, eventInit?: FocusEventInit): boolean;Creates and dispatches a blur event.
Example:
fireBlurEvent(document.getElementById("id"));fireFocusEvent
function fireFocusEvent(element: Element, eventInit?: FocusEventInit): boolean;Creates and dispatches a focus event.
Example:
fireFocusEvent(document.getElementById("id"));fireKeyboardEvent
function fireKeyboardEvent(
element: Element,
type: string,
eventInit?: KeyboardEventInit,
): boolean;Creates and dispatches a keyboard event.
Example:
fireKeyboardEvent(document.getElementById("id"), "keydown", {
key: "ArrowDown",
shiftKey: true,
});fireClickEvent
function fireClickEvent(
element: Element,
eventInit?: PointerEventInit,
): boolean;Creates and dispatches a click event.
Example:
fireClickEvent(document.getElementById("id"));isFocusEventOutside
function isFocusEventOutside(
event: Pick<FocusEvent, "currentTarget" | "relatedTarget">,
container?: Element | null,
): boolean;Checks whether the focus/blur event is happening from/to outside of the container element.
Example:
const element = document.getElementById("id");
element.addEventListener("blur", (event) => {
if (isFocusEventOutside(event)) {
// ...
}
});getInputType
function getInputType(
event: Event | { nativeEvent: Event },
): string | undefined;Returns the inputType property of the event, if available.
queueBeforeEvent
function queueBeforeEvent(
element: Element,
type: string,
callback: () => void,
timeout?: number,
): () => void;Runs a callback on the next animation frame, but before a certain event.
addGlobalEventListener
function addGlobalEventListener<K extends keyof DocumentEventMap>(
type: K,
listener: (event: DocumentEventMap[K]) => any,
options?: boolean | AddEventListenerOptions,
scope?: Window,
): () => void;
function addGlobalEventListener(
type: string,
listener: EventListenerOrEventListenerObject,
options?: boolean | AddEventListenerOptions,
scope?: Window,
): () => void;Adds a global event listener, including on child frames.
Focus utilities
Focus management helpers for focusable and tabbable elements.
isFocusable
function isFocusable(element: Element): boolean;Checks whether element is focusable or not.
Example:
isFocusable(document.querySelector("input")); // true
isFocusable(document.querySelector("input[tabindex='-1']")); // true
isFocusable(document.querySelector("input[hidden]")); // false
isFocusable(document.querySelector("input:disabled")); // falseisTabbable
function isTabbable(
element: Element | HTMLElement | HTMLInputElement,
): element is HTMLElement;Checks whether element is tabbable or not.
Example:
isTabbable(document.querySelector("input")); // true
isTabbable(document.querySelector("input[tabindex='-1']")); // false
isTabbable(document.querySelector("input[hidden]")); // false
isTabbable(document.querySelector("input:disabled")); // falsegetAllFocusableIn
function getAllFocusableIn(
container: HTMLElement,
includeContainer?: boolean,
): HTMLElement[];Returns all the focusable elements in container.
getAllFocusable
function getAllFocusable(includeBody?: boolean): HTMLElement[];Returns all the focusable elements in the document.
getFirstFocusableIn
function getFirstFocusableIn(
container: HTMLElement,
includeContainer?: boolean,
): HTMLElement | null;Returns the first focusable element in container.
getFirstFocusable
function getFirstFocusable(includeBody?: boolean): HTMLElement | null;Returns the first focusable element in the document.
getAllTabbableIn
function getAllTabbableIn(
container: HTMLElement,
includeContainer?: boolean,
fallbackToFocusable?: boolean,
): HTMLElement[];Returns all the tabbable elements in container, including the container itself.
getAllTabbable
function getAllTabbable(fallbackToFocusable?: boolean): HTMLElement[];Returns all the tabbable elements in the document.
getFirstTabbableIn
function getFirstTabbableIn(
container: HTMLElement,
includeContainer?: boolean,
fallbackToFocusable?: boolean,
): HTMLElement | null;Returns the first tabbable element in container, including the container itself if it's tabbable.
getFirstTabbable
function getFirstTabbable(fallbackToFocusable?: boolean): HTMLElement | null;Returns the first tabbable element in the document.
getLastTabbableIn
function getLastTabbableIn(
container: HTMLElement,
includeContainer?: boolean,
fallbackToFocusable?: boolean,
): HTMLElement | null;Returns the last tabbable element in container, including the container itself if it's tabbable.
getLastTabbable
function getLastTabbable(fallbackToFocusable?: boolean): HTMLElement | null;Returns the last tabbable element in the document.
getNextTabbableIn
function getNextTabbableIn(
container: HTMLElement,
includeContainer?: boolean,
fallbackToFirst?: boolean,
fallbackToFocusable?: boolean,
): HTMLElement | null;Returns the next tabbable element in container.
getNextTabbable
function getNextTabbable(
fallbackToFirst?: boolean,
fallbackToFocusable?: boolean,
): HTMLElement | null;Returns the next tabbable element in the document.
getPreviousTabbableIn
function getPreviousTabbableIn(
container: HTMLElement,
includeContainer?: boolean,
fallbackToLast?: boolean,
fallbackToFocusable?: boolean,
): HTMLElement | null;Returns the previous tabbable element in container.
getPreviousTabbable
function getPreviousTabbable(
fallbackToFirst?: boolean,
fallbackToFocusable?: boolean,
): HTMLElement | null;Returns the previous tabbable element in the document.
getClosestFocusable
function getClosestFocusable(element?: HTMLElement | null): HTMLElement | null;Returns the closest focusable element.
hasFocus
function hasFocus(element: Element): boolean;Checks if element has focus. Elements that are referenced by aria-activedescendant are also considered.
Example:
hasFocus(document.getElementById("id"));hasFocusWithin
function hasFocusWithin(element: Node | Element): boolean;Checks if element has focus within. Elements that are referenced by aria-activedescendant are also considered.
Example:
hasFocusWithin(document.getElementById("id"));focusIfNeeded
function focusIfNeeded(element: HTMLElement): void;Focus on an element only if it's not already focused.
disableFocus
function disableFocus(element: HTMLElement): void;Disable focus on element.
disableFocusIn
function disableFocusIn(
container: HTMLElement,
includeContainer?: boolean,
): void;Makes elements inside container not tabbable.
restoreFocusIn
function restoreFocusIn(container: HTMLElement): void;Restores tabbable elements inside container that were affected by disableFocusIn.
focusIntoView
function focusIntoView(
element: HTMLElement,
options?: ScrollIntoViewOptions,
): void;Focus on element and scroll into view.
General utilities
General-purpose helpers for state, objects, strings, scheduling, and assertions.
noop
function noop(..._: any[]): any;Empty function.
shallowEqual
function shallowEqual(a?: AnyObject, b?: AnyObject): boolean;Compares two objects.
Example:
shallowEqual({ a: "a" }, {}); // false
shallowEqual({ a: "a" }, { b: "b" }); // false
shallowEqual({ a: "a" }, { a: "a" }); // true
shallowEqual({ a: "a" }, { a: "a", b: "b" }); // falseapplyState
function applyState<T>(
argument: SetStateAction<T>,
currentValue: T | (() => T),
): T;Receives a setState argument and calls it with currentValue if it's a function. Otherwise return the argument as the new value.
Example:
applyState((value) => value + 1, 1); // 2
applyState(2, 1); // 2isObject
function isObject(arg: any): arg is Record<any, unknown>;Checks whether arg is an object or not.
isEmpty
function isEmpty(arg: any): boolean;Checks whether arg is empty or not.
Example:
isEmpty([]); // true
isEmpty(["a"]); // false
isEmpty({}); // true
isEmpty({ a: "a" }); // false
isEmpty(); // true
isEmpty(null); // true
isEmpty(undefined); // true
isEmpty(""); // trueisInteger
function isInteger(arg: any): boolean;Checks whether arg is an integer or not.
Example:
isInteger(1); // true
isInteger(1.5); // false
isInteger("1"); // true
isInteger("1.5"); // falsehasOwnProperty
function hasOwnProperty<T extends AnyObject>(
object: T,
prop: keyof any,
): prop is keyof T;Checks whether prop is an own property of obj or not.
chain
function chain<T>(
...fns: T[]
): (...args: T extends AnyFunction ? Parameters<T> : never) => void;Receives functions as arguments and returns a new function that calls all.
cx
function cx(
...args: Array<string | null | false | 0 | undefined>
): string | undefined;Returns a string with the truthy values of args separated by space.
normalizeString
function normalizeString(str: string): string;Removes diacritics from a string.
omit
function omit<T extends AnyObject, K extends keyof T>(
object: T,
keys: ReadonlyArray<K> | K[],
): Omit<T, K>;Omits specific keys from an object.
Example:
omit({ a: "a", b: "b" }, ["a"]); // { b: "b" }pick
function pick<T extends AnyObject, K extends keyof T>(
object: T,
paths: ReadonlyArray<K> | K[],
): Pick<T, K>;Picks specific keys from an object.
Example:
pick({ a: "a", b: "b" }, ["a"]); // { a: "a" }identity
function identity<T>(value: T): T;Returns the same argument.
beforePaint
function beforePaint(cb: () => void = noop): () => void;Runs right before the next paint.
afterPaint
function afterPaint(cb: () => void = noop): () => void;Runs after the next paint.
invariant
function invariant(
condition: any,
message?: string | boolean,
): asserts condition;Asserts that a condition is true, otherwise throws an error.
Example:
invariant(
condition,
process.env.NODE_ENV !== "production" && "Invariant failed",
);getKeys
function getKeys<T extends object>(obj: T): (keyof T)[];Similar to Object.keys but returns a type-safe array of keys.
isFalsyBooleanCallback
function isFalsyBooleanCallback<T extends unknown[]>(
booleanOrCallback?: boolean | ((...args: T) => boolean),
...args: T
): boolean;Checks whether a boolean event prop (e.g., hideOnInteractOutside) was intentionally set to false, either with a boolean value or a callback that returns false.
disabledFromProps
function disabledFromProps(props: {
disabled?: boolean;
"aria-disabled"?: boolean | "true" | "false";
}): boolean;Checks whether something is disabled or not based on its props.
disabledFromElement
function disabledFromElement(element: Element): boolean;Checks whether something is disabled or not based on its DOM attributes.
removeUndefinedValues
function removeUndefinedValues<T extends AnyObject>(obj: T): T;Removes undefined values from an object.
defaultValue
type DefaultValue<T extends readonly any[], Other = never> = T extends [
infer Head,
...infer Rest,
]
? Rest extends []
? T[number] | Other
: undefined extends Head
? DefaultValue<Rest, Exclude<Other | Head, undefined>>
: Exclude<T[number], undefined>
: never;
function defaultValue<T extends readonly any[]>(...values: T): DefaultValue<T>;Returns the first value that is not undefined.
Platform utilities
Browser and platform detection helpers.
isTouchDevice
function isTouchDevice(): boolean;Detects if the device has touch capabilities.
isApple
function isApple(): boolean;Detects Apple device.
isSafari
function isSafari(): boolean;Detects Safari browser.
isFirefox
function isFirefox(): boolean;Detects Firefox browser.
isMac
function isMac(): boolean;Detects Mac computer.
Type utilities
Shared type utilities used across Ariakit packages.
AnyObject
type AnyObject = Record<string, any>;Any object.
EmptyObject
type EmptyObject = Record<keyof any, never>;Empty object.
AnyFunction
type AnyFunction = (...args: any) => any;Any function.
BivariantCallback
type BivariantCallback<T extends AnyFunction> = {
bivarianceHack(...args: Parameters<T>): ReturnType<T>;
}["bivarianceHack"];Workaround for variance issues.
SetStateAction
type SetStateAction<T> = T | BivariantCallback<(prevState: T) => T>;SetState
type SetState<T> = BivariantCallback<(value: SetStateAction<T>) => void>;The type of the setState function in [state, setState] = useState().
BooleanOrCallback
type BooleanOrCallback<T> = boolean | BivariantCallback<(arg: T) => boolean>;A boolean value or a callback that returns a boolean value.
StringWithValue
type StringWithValue<T extends string> = T | (string & Record<never, never>);A string that will provide autocomplete for specific strings.
ToPrimitive
type ToPrimitive<T> = T extends string
? string
: T extends number
? number
: T extends boolean
? boolean
: T extends AnyFunction
? (...args: Parameters<T>) => ReturnType<T>
: T;Transforms a type into a primitive type.
Example:
// string
ToPrimitive<"a">;
// number
ToPrimitive<1>;PickByValue
type PickByValue<T, Value> = {
[K in keyof T as [Value] extends [T[K]]
? T[K] extends Value | undefined
? K
: never
: never]: T[K];
};Picks only the properties from a type that have a specific value.
PickRequired
type PickRequired<T, P extends keyof T> = T &
{
[K in keyof T]: Pick<Required<T>, K>;
}[P];Picks only the required properties from a type.
AriaHasPopup
type AriaHasPopup =
| boolean
| "false"
| "true"
| "menu"
| "listbox"
| "tree"
| "grid"
| "dialog"
| undefined;Indicates the availability and type of interactive popup element, such as menu or dialog, that can be triggered by an element.
AriaRole
type AriaRole =
| "alert"
| "alertdialog"
| "application"
| "article"
| "banner"
| "button"
| "cell"
| "checkbox"
| "columnheader"
| "combobox"
| "complementary"
| "contentinfo"
| "definition"
// ... 53 more lines
| "tree"
| "treegrid"
| "treeitem"
| (string & {});All the WAI-ARIA 1.1 role attribute values from https://www.w3.org/TR/wai-aria-1.1/#role_definitions
Undo utilities
Undo and redo manager utilities.
UndoManager
type Callback = void | (() => Callback | Promise<Callback>);
const UndoManager: {
canUndo: () => boolean;
canRedo: () => boolean;
undo: () => Promise<void>;
redo: () => Promise<void>;
execute: (callback: Callback, group?: string) => Promise<void>;
};Shared undo manager instance.
createUndoManager
type Callback = void | (() => Callback | Promise<Callback>);
interface CreateUndoManagerOptions {
limit?: number;
}
function createUndoManager({ limit = 100 }: CreateUndoManagerOptions = {}): {
canUndo: () => boolean;
canRedo: () => boolean;
undo: () => Promise<void>;
redo: () => Promise<void>;
execute: (callback: Callback, group?: string) => Promise<void>;
};Creates an undo manager with undo and redo stacks.