Pressable
Pressable handles press interactions across mouse, touch, keyboard, and screen readers.
Pressed 0 times
Long Pressed 0 times
Features
- Handles mouse and touch events
- Handles Enter or Space key presses
- Handles screen reader virtual clicks
- Uses pointer events where available, with fallbacks to mouse and touch events
- Normalizes focus behavior on mouse and touch interactions across browsers
- Handles disabling text selection on mobile while the press interaction is active
- Normalizes many cross browser inconsistencies
Installation
To use the pressable machine in your project, run the following command in your command line:
npm install @zag-js/pressable @zag-js/react # or yarn add @zag-js/pressable @zag-js/react
npm install @zag-js/pressable @zag-js/vue # or yarn add @zag-js/pressable @zag-js/vue
npm install @zag-js/pressable @zag-js/vue # or yarn add @zag-js/pressable @zag-js/vue
npm install @zag-js/pressable @zag-js/solid # or yarn add @zag-js/pressable @zag-js/solid
This command will install the framework agnostic pressable logic and the reactive utilities for your framework of choice.
Usage
First, import the pressable package into your project
import * as pressable from "@zag-js/pressable"
The pressable package exports two key functions:
machine
— The state machine logic for the pressable widget.connect
— The function that translates the machine's state to JSX attributes and event handlers.
You'll also need to provide a unique
id
to theuseMachine
hook. This is used to ensure that every pressable has a unique identifier. Next, import the required hooks and functions for your framework and use the pressable machine in your project 🔥
import * as pressable from "@zag-js/pressable" import { useMachine, normalizeProps } from "@zag-js/react" function Pressable() { const [state, send] = useMachine( pressable.machine({ id: "pressable", onPress() { console.log("press") }, onLongPress() { console.log("long press") }, }), ) const api = pressable.connect(state, send, normalizeProps) return ( <button {...api.pressableProps}> {api.isPressed ? "Pressed!" : "Press Me"} </button> ) }
import * as pressable from "@zag-js/pressable" import { normalizeProps, useMachine } from "@zag-js/vue" import { defineComponent, h, Fragment, computed } from "vue" export default defineComponent({ name: "Pressable", setup() { const [state, send] = useMachine( pressable.machine({ id: "pressable", onPress() { console.log("press") }, onLongPress() { console.log("long press") }, }), ) const apiRef = computed(() => pressable.connect(state.value, send, normalizeProps), ) return () => { const api = apiRef.value return ( <button {...api.pressableProps}> {api.isPressed ? "Pressed!" : "Press Me"} </button> ) } }, })
<script setup> import * as pressable from "@zag-js/pressable" import { normalizeProps, useMachine } from "@zag-js/vue" import { computed } from "vue" const [state, send] = useMachine(pressable.machine({ id: "1" })) const api = computed(() => pressable.connect(state.value, send, normalizeProps)) </script> <template> <button v-bind="api.pressableProps"> <span v-if="api.isPressed">Pressed!</span> <span v-else>Press Me</span> </button> </template>
import * as pressable from "@zag-js/pressable" import { normalizeProps, useMachine } from "@zag-js/solid" import { createMemo, createUniqueId } from "solid-js" function Pressable() { const [state, send] = useMachine( pressable.machine({ id: createUniqueId(), onPress() { console.log("press") }, onLongPress() { console.log("long press") }, }), ) const api = createMemo(() => pressable.connect(state, send, normalizeProps)) return ( <button {...api().pressableProps}> {api().isPressed ? "Pressed!" : "Press Me"} </button> ) }
Disabling the pressable
To make pressable disabled, set the context's disabled
property to true
const [state, send] = useMachine( pressable.machine({ disabled: true, }), )
Handlers
The pressable fires these handlers
Property | Description |
---|---|
onPress | Handler that is called when the press is released over the target. |
onPressStart | Handler that is called when a press interaction starts. |
onPressEnd | Handler that is called when a press interaction ends, either over the target or when the pointer leaves the target. |
onPressUp | Handler that is called when a press is released over the target, regardless of whether it started on the target or not. |
onLongPress | Handler that is called when the element has been pressed for 500 milliseconds |
Each of these handlers is fired with a PressEvent, which exposes information about the target and the type of event that triggered the interaction.
Property | Description | Type |
---|---|---|
type | The type of press event being fired. | pressstart or pressend or pressup or press or longpress |
pointerType | The pointer type that triggered the press event. | PointerType |
target | The target element of the press event. | HTMLElement |
originalEvent | The original fired event | PointerEvent |
Styling guide
Pressed State
When the pressable element is pressed, the data-pressed
attribute is added to
the target
[data-pressed] { /* styles for pressable pressed state */ }
Disabled State
When the pressable element is disabled, the data-disabled
attribute is added
to the target
[data-disabled] { /* styles for pressable disabled state */ }
Methods and Properties
The pressable's api
provides helpful properties and methods
isPressed
boolean
Whether the element is pressed.
Edit this page on GitHub