---
title: Reaction
description: Emoji reaction pill with count and toggle state
visibility: guest
draft: false
---

# Reaction

An emoji reaction button for chat messages, comments, and social interactions. Supports active/inactive toggle state, count display, and screen-reader-friendly user lists.

## Basic Usage

:::preview{title="Simple reaction"}
<x-wirekit::row gap="sm">
    <x-wirekit::reaction emoji="👍" :count="5" />
    <x-wirekit::reaction emoji="❤️" :count="3" />
    <x-wirekit::reaction emoji="🎉" :count="1" />
</x-wirekit::row>
:::

## Active State

Highlight a reaction the current user has selected:

:::preview{title="Active vs inactive"}
<x-wirekit::row gap="sm">
    <x-wirekit::reaction emoji="👍" :count="5" :active="true" />
    <x-wirekit::reaction emoji="❤️" :count="3" :active="false" />
    <x-wirekit::reaction emoji="🎉" :count="7" :active="true" />
</x-wirekit::row>
:::

## Zero Count (Hidden)

When count is zero, only the emoji is shown:

:::preview{title="Zero count reaction"}
<x-wirekit::reaction emoji="➕" :count="0" />
:::

## With User List

Provide a list of users for screen reader context:

:::preview{title="Reaction with user attribution"}
<x-wirekit::reaction emoji="👍" :count="3" :users="['Alice', 'Bob', 'Charlie']" />
:::

## With Livewire Integration

:::preview{title="Livewire toggle example"}
<x-wirekit::row gap="sm">
    <x-wirekit::reaction emoji="👍" :count="12" :active="true" wire:click="toggleReaction('thumbs-up')" />
    <x-wirekit::reaction emoji="😂" :count="4" :active="false" wire:click="toggleReaction('laugh')" />
</x-wirekit::row>
:::

## Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `emoji` | `string` | `null` | The emoji character to display |
| `count` | `int` | `0` | Number of reactions |
| `active` | `bool` | `false` | Whether the current user has reacted |
| `users` | `array` | `[]` | List of user names (for screen readers) |

## Accessibility

- `<button type="button">` for keyboard activation
- `aria-pressed="true|false"` reflects active state
- `aria-label` combines emoji with reaction count (e.g. "👍, 5 people reacted")
- When `users` is provided, a `sr-only` span with `aria-describedby` lists all names

## Keyboard Interaction

| Key | Action |
|-----|--------|
| `Tab` | Move focus to the button |
| `Enter` / `Space` | Activate the button |

## Pitfalls

- **Don't bind `wire:click.live` on every reaction button.** Each click round-trips to the server with full component state. The component's `:on-react` callback prop debounces; use it.

## Design Tokens

| Token | Used for |
| --- | --- |
| `--font-wk-sans` | Button font family |
| `--font-wk-heading-weight` | Count weight |
| `--text-wk-sm` | Count font size |
| `--color-wk-text-muted` | Inactive count text |
| `--color-wk-accent` / `--color-wk-accent-content` | Active border + count text |
| `--color-wk-bg` / `--color-wk-bg-elevated` / `--color-wk-bg-muted` | Background per active / hover state |
| `--color-wk-border` | Inactive border |
| `--border-wk-width` | Border width |
| `--radius-wk-full` | Pill border radius |
| `--transition-wk-duration` / `--transition-wk-easing` | Hover / toggle transition |
