27.4k

v3.0.0-beta.2

Three new components (ComboBox, Modal, Dropdown), Select API improvements, and component refinements.

November 16, 2025

This release introduces three essential new components, improves the Select component API, and includes various refinements and bug fixes.

Installation

Update to the latest version:

npm i @heroui/styles@beta @heroui/react@beta
pnpm add @heroui/styles@beta @heroui/react@beta
yarn add @heroui/styles@beta @heroui/react@beta
bun add @heroui/styles@beta @heroui/react@beta

Using AI assistants? Simply prompt "Hey Cursor, update HeroUI to the latest version" and your AI assistant will automatically compare versions and apply the necessary changes. Learn more about the HeroUI MCP Server.

What's New

New Components

This release introduces 3 new essential components:

ComboBox

"use client";

import {ComboBox, Input, Label, ListBox} from "@heroui/react";

export function Default() {
  return (
    <ComboBox className="w-[256px]">
      <Label>Favorite Animal</Label>
      <ComboBox.InputGroup>
        <Input placeholder="Search animals..." />
        <ComboBox.Trigger />
      </ComboBox.InputGroup>
      <ComboBox.Popover>
        <ListBox>
          <ListBox.Item id="aardvark" textValue="Aardvark">
            Aardvark
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="cat" textValue="Cat">
            Cat
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="dog" textValue="Dog">
            Dog
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="kangaroo" textValue="Kangaroo">
            Kangaroo
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="panda" textValue="Panda">
            Panda
            <ListBox.ItemIndicator />
          </ListBox.Item>
          <ListBox.Item id="snake" textValue="Snake">
            Snake
            <ListBox.ItemIndicator />
          </ListBox.Item>
        </ListBox>
      </ComboBox.Popover>
    </ComboBox>
  );
}
"use client";

import {Button, Modal} from "@heroui/react";
import {Icon} from "@iconify/react";

export function Default() {
  return (
    <Modal>
      <Button variant="secondary">Open Modal</Button>
      <Modal.Container>
        <Modal.Dialog className="sm:max-w-[360px]">
          {({close}) => (
            <>
              <Modal.CloseTrigger />
              <Modal.Header>
                <div className="bg-default ring-muted/25 flex size-10 items-center justify-center rounded-full ring-1">
                  <Icon className="size-5" icon="gravity-ui:rocket" />
                </div>
                <h2 className="text-foreground text-lg font-semibold leading-6">
                  Welcome to HeroUI
                </h2>
              </Modal.Header>
              <Modal.Body>
                <p>
                  A beautiful, fast, and modern React UI library for building accessible and
                  customizable web applications with ease.
                </p>
              </Modal.Body>
              <Modal.Footer>
                <Button className="w-full" onPress={close}>
                  Continue
                </Button>
              </Modal.Footer>
            </>
          )}
        </Modal.Dialog>
      </Modal.Container>
    </Modal>
  );
}
"use client";

import {Button, Dropdown, Label} from "@heroui/react";

export function Default() {
  return (
    <Dropdown>
      <Button aria-label="Menu" variant="secondary">
        Actions
      </Button>
      <Dropdown.Popover>
        <Dropdown.Menu onAction={(key) => console.log(`Selected: ${key}`)}>
          <Dropdown.Item id="new-file" textValue="New file">
            <Label>New file</Label>
          </Dropdown.Item>
          <Dropdown.Item id="copy-link" textValue="Copy link">
            <Label>Copy link</Label>
          </Dropdown.Item>
          <Dropdown.Item id="edit-file" textValue="Edit file">
            <Label>Edit file</Label>
          </Dropdown.Item>
          <Dropdown.Item id="delete-file" textValue="Delete file" variant="danger">
            <Label>Delete file</Label>
          </Dropdown.Item>
        </Dropdown.Menu>
      </Dropdown.Popover>
    </Dropdown>
  );
}

Component Improvements

Select Component API Update

The Select component's API has been improved for better consistency with other components. The Content subcomponent has been renamed to Popover.

Before:

<Select>
  <Select.Trigger>
    <Select.Value />
    <Select.Indicator />
  </Select.Trigger>
  <Select.Content>
    <ListBox>
      {/* items */}
    </ListBox>
  </Select.Content>
</Select>

After:

<Select>
  <Select.Trigger>
    <Select.Value />
    <Select.Indicator />
  </Select.Trigger>
  <Select.Popover>
    <ListBox>
      {/* items */}
    </ListBox>
  </Select.Popover>
</Select>

Chip Component Refinements

Chip component sizes have been updated for better consistency:

  • Small (sm): px-1 py-0 text-xs
  • Medium (md): text-xs (now explicitly set)
  • Large (lg): px-3 py-1 text-sm font-medium

Separator Component Enhancement

The Separator component now automatically detects when it's placed inside a surface component (one that uses bg-surface) and applies the appropriate divider color for better visibility. A new isOnSurface prop is also available for manual control.

New Calculated Variable:

  • --color-separator-on-surface: A calculated variable (automatically generated using color-mix) that ensures the separator is visible when placed on a surface background. Like other calculated variables, it can be overridden in your theme.

Usage:

<div className="bg-surface">
  <Separator isOnSurface />
</div>

The isOnSurface prop is automatically applied when the Separator detects a SurfaceContext provider (used by components like Card, Alert, Popover, Modal, etc.).

You can also use the calculated variable directly with Tailwind classes:

<div className="bg-surface">
  <div className="h-px w-full bg-separator-on-surface" />
</div>

Animation Improvements

  • Loading state spinner color updated for better visibility
  • Select and Slider component styles adjusted for improved animations
  • Checkbox animation improved (faster transition)
  • Better support for prefers-reduced-motion with pseudo elements

⚠️ Breaking Changes

Select Component

The Select.Content subcomponent has been renamed to Select.Popover for consistency with other components like ComboBox and Dropdown.

Migration:

Replace all instances of Select.Content with Select.Popover:

// Before
<Select.Content>
  <ListBox>...</ListBox>
</Select.Content>

// After
<Select.Popover>
  <ListBox>...</ListBox>
</Select.Popover>

Type imports:

// Before
import type { SelectContentProps } from "@heroui/react"

// After
import type { SelectPopoverProps } from "@heroui/react"

Named exports:

// Before
import { SelectContent } from "@heroui/react"

// After
import { SelectPopover } from "@heroui/react"

CSS Variables and Utilities: Divider → Separator

All CSS variables and utility classes related to divider have been renamed to separator for consistency with the Separator component name.

CSS Variables:

/* Before */
border-bottom: 1px solid var(--divider);

/* After */
border-bottom: 1px solid var(--separator);

Tailwind Utility Classes:

// Before
<div className="bg-divider" />
<div className="border-divider" />

// After
<div className="bg-separator" />
<div className="border-separator" />

Theme Overrides:

If you have custom themes that override the divider variable, update them:

/* Before */
:root {
  --divider: oklch(92% 0.004 286.32);
}

.dark {
  --divider: oklch(22% 0.006 286.033);
}

/* After */
:root {
  --separator: oklch(92% 0.004 286.32);
}

.dark {
  --separator: oklch(22% 0.006 286.033);
}

Bug Fixes

  • Fixed loading state spinner color for better visibility
  • Fixed bordered focus styles taking precedence over hover states
  • Fixed animation stuttering in documentation
  • Improved modal form styling
  • Enhanced motion reduce support for pseudo elements

Contributors

Thanks to everyone who contributed to this release!