npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xsolla/xui-status-dropdown

v0.209.1

Published

A compact interactive status tag that opens a menu to change the current status. Cross-platform (web and native).

Readme

StatusDropdown

A compact interactive status tag that opens a menu to change the current status. Cross-platform (web and native).

A compact inline tag-trigger that displays the current status of a record and opens a ContextMenu for changing it. Combines a coloured dot, a status label, and a chevron into a single small interactive element. Designed for use inside table rows, list items, and detail panels where inline status editing is required without navigating away.

When to use

  • In data tables where each row has a status that users can update directly (e.g. order status, moderation state, task progress)
  • In detail panels or forms where a status field must be editable inline without a modal
  • When the list of statuses is predefined and finite, and selecting a new one immediately applies a change
  • When the available status palette carries semantic meaning (success, warning, alert) that should be communicated through colour

When not to use

  • When the status is read-only — use Status or Tag component instead
  • When there are more than ~7–8 status options, or when options require descriptions longer than a single line — consider a Select or a dedicated side panel
  • When the status change triggers a complex confirmation flow — use a full Dialog rather than an inline dropdown
  • As a navigation element — StatusDropdown changes a value, it does not navigate

Content guidelines

  • Status labels — keep labels short: one or two words maximum. Examples: "Active", "Pending", "Rejected", "In review", "Draft". Avoid verbose labels like "Currently under moderation review".
  • Description lines — use the optional ContextMenu description line to clarify what a status means or what happens when it is selected. Example: label "Archived", description "Hidden from all users. Can be restored."
  • Palette assignment — assign palettes semantically and consistently across the product. Do not use Alert (red) for a neutral state. Do not use Success (green) for a warning state. Document the palette-to-status mapping in the product's status glossary.
  • Number of options — keep the ContextMenu list to 7 options or fewer. If more are needed, consider grouping them or using a different pattern.

Behaviour guidelines

  • Opening — clicking or pressing Enter / Space on the trigger opens the ContextMenu. The trigger switches to Open=True state and the chevron rotates.
  • Selection — clicking a ContextMenu item immediately applies the new status: the trigger label and dot update to reflect the selection, the menu closes, and the change is committed. There is no separate confirm step.
  • Current selection — the currently active status is shown with a checked Checkbox in the menu and should not trigger a change if re-selected. Clicking the currently active item closes the menu without any state change.
  • Closing — the ContextMenu closes on: selecting an item, clicking outside the menu, pressing Escape, or pressing Tab past the last item.
  • Optimistic update — update the trigger UI immediately on selection and send the change to the backend in the background. If the request fails, revert the trigger to the previous status and surface an error (e.g. a Toast notification).
  • Loading state — if the status change requires an async operation that takes noticeable time, show a spinner in the context-menu while the request is in flight.
  • Width — the trigger width is determined by the current label text plus dot and chevron. It is not fixed — expect it to change width when the status label changes. Ensure the surrounding layout accommodates this (e.g. avoid placing adjacent elements at a fixed offset from the trigger's right edge).
  • Placement in tables — in a table cell, left-align the trigger. Do not stretch it to fill the cell width unless the table column width is narrow enough that all options need the full width.

Accessibility

  • The trigger must have role="button" with aria-haspopup="listbox" and aria-expanded set to true when open and false when closed.
  • Provide aria-label on the trigger that includes both the field name and the current value — e.g. aria-label="Status: Active". Do not rely on the visual dot colour alone.
  • The ContextMenu list must have role="listbox" with aria-label="Change status".
  • Each option must have role="option" with aria-selected="true" for the current selection and aria-selected="false" for all others.
  • Keyboard navigation inside the open menu: ↑ / ↓ moves between options; Enter / Space selects; Escape closes without selecting.
  • When the menu closes after a selection, return focus to the trigger.
  • Do not rely on the Palette colour alone to convey the status — always pair it with the text label. This satisfies WCAG 1.4.1 (Use of Colour).
  • If Dot=False, the chevron remains the only visual affordance that the trigger is interactive — ensure it is clearly visible against the background at all palette variants.

Installation

npm install @xsolla/xui-status-dropdown

Imports

import { StatusDropdown } from '@xsolla/xui-status-dropdown';
import type { StatusDropdownProps, StatusDropdownPalette } from '@xsolla/xui-status-dropdown';
import { ContextMenuItem } from '@xsolla/xui-context-menu';

Also re-exported from the @xsolla/xui-controls meta-package:

import { StatusDropdown } from '@xsolla/xui-controls';

Quick start

const [status, setStatus] = useState('Success');

<StatusDropdown label={status} palette="Success" dot>
  <ContextMenuItem onPress={() => setStatus('Success')}>Success</ContextMenuItem>
  <ContextMenuItem onPress={() => setStatus('Warning')}>Warning</ContextMenuItem>
  <ContextMenuItem onPress={() => setStatus('Alert')}>Alert</ContextMenuItem>
</StatusDropdown>;

API Reference

<StatusDropdown>

| Prop | Type | Default | Description | | --- | --- | --- | --- | | label | string | — | Current status text shown on the trigger. | | palette | 'Neutral' \| 'Success' \| 'Warning' \| 'Alert' \| 'Brand' | 'Neutral' | Colour palette for the trigger. | | dot | boolean | false | Show a small status dot before the label. | | children | ReactNode | — | Menu content; typically ContextMenuItem elements. | | placement | ContextMenuPlacement | 'bottom-start' | Menu placement relative to the trigger. | | onSelect | (value: any) => void | — | Fired when a menu item is selected. | | isOpen | boolean | — | Controlled open state. | | onOpenChange | (isOpen: boolean) => void | — | Fires when the open state changes. | | aria-label | string | `Status: ${label}` | Accessible label for the trigger. | | id | string | — | HTML id on the underlying dropdown. | | testID | string | — | Test identifier; suffixed for inner trigger and dot. |

Inherits ThemeOverrideProps (themeMode, themeProductContext).

Types

type StatusDropdownPalette = 'Neutral' | 'Success' | 'Warning' | 'Alert' | 'Brand';

Examples

Controlled selection

Item-level onPress handlers on each ContextMenuItem drive the controlled value; this is the recommended pattern.

const STATUSES = [
  { label: 'Success', palette: 'Success' },
  { label: 'Warning', palette: 'Warning' },
  { label: 'Alert', palette: 'Alert' },
  { label: 'Neutral', palette: 'Neutral' },
  { label: 'Brand', palette: 'Brand' },
] as const;

const [current, setCurrent] = useState(STATUSES[0]);

<StatusDropdown label={current.label} palette={current.palette} dot>
  {STATUSES.map((s) => (
    <ContextMenuItem key={s.label} onPress={() => setCurrent(s)}>
      {s.label}
    </ContextMenuItem>
  ))}
</StatusDropdown>

Without dot

<StatusDropdown label="Warning" palette="Warning">
  <ContextMenuItem>Success</ContextMenuItem>
  <ContextMenuItem>Warning</ContextMenuItem>
</StatusDropdown>

Accessibility

  • Trigger renders with role="button" and aria-haspopup="listbox".
  • An aria-label is auto-generated from label when not supplied.
  • Menu open state is communicated through the underlying Dropdown; chevron rotates with the open state.