Skip to main content
BETA
View Zag.js on Github
Join the Discord server

Rating

Rating allows a user to add and remove rating to an item.

Properties

Features

  • Syncs with disabled state of fieldset
  • Syncs with form reset events

Installation

To use the rating machine in your project, run the following command in your command line:

npm install @zag-js/rating @zag-js/react # or yarn add @zag-js/rating @zag-js/react

This command will install the framework agnostic rating logic and the reactive utilities for your framework of choice.

Anatomy

To set up the rating correctly, you'll need to understand its anatomy and how we name its parts.

Each part includes a data-part attribute to help identify them in the DOM.

On a high level, the rating consists of:

  • Root: The root container for the rating
  • Label: The label that gives the user information on the rating
  • Item: The element that visually represents the each rating item.
  • Item Group: The radiogroup wrapper for the rating items.
  • Input: The native html input that is visually hidden in the rating.

Usage

First, import the rating package into your project

import * as rating from "@zag-js/rating"

The rating package exports two key functions:

  • machine — The state machine logic for the rating 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 the useSetup hook. This is used to ensure that every part has a unique identifier.

Next, import the required hooks and functions for your framework and use the rating machine in your project 🔥

import * as rating from "@zag-js/rating" import { useMachine, normalizeProps } from "@zag-js/react" import { HalfStar, Star } from "./icons" function Rating() { const [state, send] = useMachine(rating.machine({ id: "1" })) const api = rating.connect(state, send, normalizeProps) return ( <div {...api.rootProps}> <label {...api.labelProps}>Rate:</label> <div {...api.itemGroupProps}> {api.sizeArray.map((index) => { const state = api.getRatingState(index) return ( <span key={index} {...api.getItemProps({ index })}> {state.isHalf ? <HalfStar /> : <Star />} </span> ) })} </div> <input {...api.inputProps} /> </div> ) }

Disabling the rating

To make rating disabled, set the context's disabled property to true

const [state, send] = useMachine( rating.machine({ disabled: true, }), )

Readonly rating

To make rating readonly, set the context's readonly property to true

const [state, send] = useMachine( rating.machine({ readonly: true, }), )

Setting the initial value

To set the rating's initial value, set the context's value property.

const [state, send] = useMachine( rating.machine({ value: 2.5, }), )

Listening for changes

When the rating value changes, the onChange callback is invoked.

const [state, send] = useMachine( rating.machine({ onChange({ value }) { console.log("rating value is:", value) // '1' | '2.5' | '4' }, }), )

Methods and Properties

The rating's api provides helpful properties and methods

PropertyDescription
isHoveringWhether the rating is being hovered
valueValue of the rating
hoveredValueHovered value of rating
sizeSize of the rating
getRatingStateGet info about a particular rating item by providing it's index
const api = connect(state, send) api.value // '1' | '2.5' | '4' api.isHovering // true | false api.getRatingState(0) /* { isEqual: true, isValueEmpty: false, isHighlighted: false, isHalf true, isChecked: true, } */

Usage within forms

To use rating within forms, use the exposed inputProps from the connect function and ensure you pass name value to the machine's context. It will render a hidden input and ensure the value changes get propagated to the form correctly.

const [state, send] = useMachine( rating.machine({ name: "rating", }), )

Styling guide

Earlier, we mentioned that each rating part has a data-part attribute added to them to select and style them in the DOM.

Focused State

When the rating input is focused, the data-focus attribute is added to the root, control and label parts.

[data-part="item"][data-focus] { /* styles for item focus state */ } [data-part="label"][data-focus] { /* styles for item control focus state */ } [data-part="input"][data-focus] { /* styles for item label focus state */ }

Disabled State

When the rating is disabled, the data-disabled attribute is added to the root, control and label parts.

[data-part="item"][data-disabled] { /* styles for item disabled state */ } [data-part="label"][data-disabled] { /* styles for item control disabled state */ } [data-part="input"][data-disabled] { /* styles for item label disabled state */ }

Invalid State

When the rating is invalid, the data-invalid attribute is added to the root, control and label parts.

[data-part="item"][data-invalid] { /* styles for item invalid state */ } [data-part="label"][data-invalid] { /* styles for item control invalid state */ } [data-part="input"][data-invalid] { /* styles for item label invalid state */ }

Edit this page on GitHub

On this page