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-button

v0.103.0

Published

A cross-platform React button component with primary/secondary variants, multiple color tones, sizes, loading states, and icon support. Works on both React (web) and React Native.

Readme

Button

A cross-platform React button component with primary/secondary variants, multiple color tones, sizes, loading states, and icon support. Works on both React (web) and React Native.

Installation

npm install @xsolla/xui-button
# or
yarn add @xsolla/xui-button

Demo

Basic Button

import * as React from 'react';
import { Button } from '@xsolla/xui-button';

export default function BasicButton() {
  return (
    <Button onPress={() => console.log('Pressed!')}>
      Click me
    </Button>
  );
}

Button Variants

import * as React from 'react';
import { Button } from '@xsolla/xui-button';

export default function ButtonVariants() {
  return (
    <div style={{ display: 'flex', gap: 16 }}>
      <Button variant="primary">Primary</Button>
      <Button variant="secondary">Secondary</Button>
      <Button variant="tertiary">Tertiary</Button>
    </div>
  );
}

Button Tones

import * as React from 'react';
import { Button } from '@xsolla/xui-button';

export default function ButtonTones() {
  return (
    <div style={{ display: 'flex', gap: 16 }}>
      <Button tone="brand">Brand</Button>
      <Button tone="brandExtra">Brand Extra</Button>
      <Button tone="alert">Alert</Button>
      <Button tone="mono">Mono</Button>
    </div>
  );
}

Button Sizes

import * as React from 'react';
import { Button } from '@xsolla/xui-button';

export default function ButtonSizes() {
  return (
    <div style={{ display: 'flex', gap: 16, alignItems: 'center' }}>
      <Button size="xs">Extra Small</Button>
      <Button size="sm">Small</Button>
      <Button size="md">Medium</Button>
      <Button size="lg">Large</Button>
      <Button size="xl">Extra Large</Button>
    </div>
  );
}

Button with Icons

import * as React from 'react';
import { Button } from '@xsolla/xui-button';
import { Plus, ChevronDown, FileDownloadOut } from '@xsolla/xui-icons-base';
import { ArrowRight } from '@xsolla/xui-icons';

export default function ButtonWithIcons() {
  return (
    <div style={{ display: 'flex', gap: 16 }}>
      <Button iconLeft={<Plus />}>
        Add Item
      </Button>
      <Button iconRight={<ArrowRight />}>
        Next Step
      </Button>
      <Button
        iconLeft={<FileDownloadOut />}
        iconRight={<ChevronDown />}
      >
        Download
      </Button>
    </div>
  );
}

Loading Button

import * as React from 'react';
import { Button } from '@xsolla/xui-button';

export default function LoadingButton() {
  const [loading, setLoading] = React.useState(false);

  const handlePress = () => {
    setLoading(true);
    setTimeout(() => setLoading(false), 2000);
  };

  return (
    <Button loading={loading} onPress={handlePress}>
      {loading ? 'Processing...' : 'Submit'}
    </Button>
  );
}

Anatomy

Import the component and use it directly:

import { Button, IconButton, FlexButton, ButtonGroup } from '@xsolla/xui-button';
import { Plus } from '@xsolla/xui-icons-base';

// Basic button
<Button>Label</Button>

// Icon-only button
<IconButton icon={<Plus />} aria-label="Add item" />

// Flexible styling button
<FlexButton variant="brand">Label</FlexButton>

// Group of buttons
<ButtonGroup>
  <Button>First</Button>
  <Button>Second</Button>
</ButtonGroup>

Examples

Full Width Button

Use the fullWidth prop to make the button span the entire container width.

import * as React from 'react';
import { Button } from '@xsolla/xui-button';

export default function FullWidthButton() {
  return (
    <div style={{ width: 300 }}>
      <Button fullWidth>Full Width Button</Button>
    </div>
  );
}

Disabled Button

import * as React from 'react';
import { Button } from '@xsolla/xui-button';

export default function DisabledButton() {
  return (
    <div style={{ display: 'flex', gap: 16 }}>
      <Button disabled>Disabled Primary</Button>
      <Button variant="secondary" disabled>Disabled Secondary</Button>
    </div>
  );
}

Icon Button

Use IconButton for buttons that contain only an icon.

import * as React from 'react';
import { IconButton } from '@xsolla/xui-button';
import { Plus, TrashCan } from '@xsolla/xui-icons-base';
import { Settings } from '@xsolla/xui-icons';

export default function IconButtonExample() {
  return (
    <div style={{ display: 'flex', gap: 16 }}>
      <IconButton
        icon={<Plus />}
        aria-label="Add"
        size="md"
      />
      <IconButton
        icon={<TrashCan />}
        aria-label="Delete"
        tone="alert"
      />
      <IconButton
        icon={<Settings />}
        aria-label="Settings"
        variant="secondary"
      />
    </div>
  );
}

Button Group

Use ButtonGroup to group related buttons together.

import * as React from 'react';
import { Button, ButtonGroup } from '@xsolla/xui-button';

export default function ButtonGroupExample() {
  return (
    <ButtonGroup orientation="horizontal" size="md">
      <Button variant="secondary">Cancel</Button>
      <Button>Confirm</Button>
    </ButtonGroup>
  );
}

Vertical Button Group

import * as React from 'react';
import { Button, ButtonGroup } from '@xsolla/xui-button';

export default function VerticalButtonGroup() {
  return (
    <ButtonGroup orientation="vertical" size="md">
      <Button fullWidth>Option 1</Button>
      <Button fullWidth>Option 2</Button>
      <Button fullWidth>Option 3</Button>
    </ButtonGroup>
  );
}

Flex Button

FlexButton provides more flexible styling options with different background modes.

import * as React from 'react';
import { FlexButton } from '@xsolla/xui-button';
import { Link } from '@xsolla/xui-icons-base';

export default function FlexButtonExample() {
  return (
    <div style={{ display: 'flex', gap: 16 }}>
      <FlexButton variant="brand" background>
        With Background
      </FlexButton>
      <FlexButton variant="brand">
        Text Only
      </FlexButton>
      <FlexButton variant="tertiary" iconLeft={<Link />}>
        Link Style
      </FlexButton>
    </div>
  );
}

Form Submit Button

import * as React from 'react';
import { Button } from '@xsolla/xui-button';

export default function FormSubmitButton() {
  return (
    <form onSubmit={(e) => {
      e.preventDefault();
      console.log('Form submitted');
    }}>
      <Button type="submit">Submit Form</Button>
    </form>
  );
}

Button with Sublabel

Use the sublabel prop to add secondary text inline with the main label.

import * as React from 'react';
import { Button } from '@xsolla/xui-button';
import { Apple } from '@xsolla/xui-icons-brand';

export default function ButtonWithSublabel() {
  return (
    <Button 
      iconLeft={<Apple />}
      sublabel="$39.99"
      labelAlignment="left"
    >
      Buy Now
    </Button>
  );
}

Button with Divider

The divider prop controls whether a separator line appears between icons and content.

import * as React from 'react';
import { Button } from '@xsolla/xui-button';
import { ArrowRight } from '@xsolla/xui-icons-base';

export default function ButtonWithDivider() {
  return (
    <div style={{ display: 'flex', gap: 16 }}>
      <Button iconRight={<ArrowRight />} divider>
        With Divider
      </Button>
      <Button iconRight={<ArrowRight />} divider={false}>
        No Divider
      </Button>
    </div>
  );
}

Button with Custom Content

Use customContent to add badges, tags, or other elements inside the button.

import * as React from 'react';
import { Button } from '@xsolla/xui-button';
import { Tag } from '@xsolla/xui-tag';
import { ArrowRight } from '@xsolla/xui-icons-base';

export default function ButtonWithCustomContent() {
  return (
    <Button 
      iconRight={<ArrowRight />}
      customContent={<Tag size="sm">5x</Tag>}
      divider
    >
      Claim Reward
    </Button>
  );
}

Tertiary Variant

The tertiary variant provides a minimal, text-like button style.

import * as React from 'react';
import { Button, IconButton } from '@xsolla/xui-button';
import { Settings } from '@xsolla/xui-icons-base';

export default function TertiaryButtons() {
  return (
    <div style={{ display: 'flex', gap: 16 }}>
      <Button variant="tertiary">Learn More</Button>
      <IconButton 
        variant="tertiary" 
        icon={<Settings />} 
        aria-label="Settings"
      />
    </div>
  );
}

API Reference

Button

The main button component. Renders a semantic <button> element.

Button Props:

| Prop | Type | Default | Description | | :--- | :--- | :------ | :---------- | | children | ReactNode | - | The button label content. | | variant | "primary" \| "secondary" \| "tertiary" | "primary" | The visual style variant. | | tone | "brand" \| "brandExtra" \| "alert" \| "mono" | "brand" | The color tone of the button. | | size | "xl" \| "lg" \| "md" \| "sm" \| "xs" | "md" | The size of the button. | | disabled | boolean | false | Whether the button is disabled. | | loading | boolean | false | Whether to show loading spinner. Disables interaction when true. | | onPress | () => void | - | Callback fired when button is pressed. | | iconLeft | ReactNode | - | Icon to display on the left side. | | iconRight | ReactNode | - | Icon to display on the right side. | | divider | boolean | true when icon present | Whether to show divider between icon and label. | | sublabel | string | - | Secondary label text displayed inline with main label at 40% opacity. | | labelIcon | ReactNode | - | Small icon displayed directly next to the label text. | | labelAlignment | "left" \| "center" | "center" | Alignment of the label content within the button. | | customContent | ReactNode | - | Custom content slot for badges, tags, or other elements. | | fullWidth | boolean | false | Whether button should span full container width. | | type | "button" \| "submit" \| "reset" | "button" | The HTML button type attribute. | | aria-label | string | - | Accessible label for the button. | | aria-describedby | string | - | ID of element that describes the button. | | aria-expanded | boolean | - | Indicates if controlled element is expanded. | | aria-haspopup | boolean \| "menu" \| "listbox" \| "tree" \| "grid" \| "dialog" | - | Indicates popup type triggered by button. | | aria-pressed | boolean \| "mixed" | - | Indicates pressed state for toggle buttons. | | aria-controls | string | - | ID of element controlled by this button. | | testID | string | - | Test identifier for testing frameworks. | | id | string | - | HTML id attribute. |


IconButton

A button variant that displays only an icon. Requires aria-label for accessibility.

IconButton Props:

| Prop | Type | Default | Description | | :--- | :--- | :------ | :---------- | | icon | ReactNode | - | Required. The icon to display. | | aria-label | string | - | Required. Accessible label for the button. | | variant | "primary" \| "secondary" \| "tertiary" | "primary" | The visual style variant. | | tone | "brand" \| "brandExtra" \| "alert" \| "mono" | "brand" | The color tone of the button. | | size | "xl" \| "lg" \| "md" \| "sm" \| "xs" | "md" | The size of the button. | | disabled | boolean | false | Whether the button is disabled. | | loading | boolean | false | Whether to show loading spinner. | | onPress | () => void | - | Callback fired when button is pressed. | | type | "button" \| "submit" \| "reset" | "button" | The HTML button type attribute. |


FlexButton

A flexible button with more granular control over background and styling.

FlexButton Props:

| Prop | Type | Default | Description | | :--- | :--- | :------ | :---------- | | children | ReactNode | - | The button label content. | | variant | "brand" \| "primary" \| "secondary" \| "tertiary" \| "brandExtra" \| "inverse" | "brand" | The visual style variant. | | size | "xl" \| "lg" \| "md" \| "sm" \| "xs" | "md" | The size of the button. | | background | boolean | false | Whether to show background fill. | | disabled | boolean | false | Whether the button is disabled. | | loading | boolean | false | Whether to show loading spinner. | | iconLeft | ReactNode | - | Icon to display on the left side. | | iconRight | ReactNode | - | Icon to display on the right side. | | onPress | () => void | - | Callback fired when button is pressed. | | type | "button" \| "submit" \| "reset" | "button" | The HTML button type attribute. |


ButtonGroup

A container for grouping related buttons together.

ButtonGroup Props:

| Prop | Type | Default | Description | | :--- | :--- | :------ | :---------- | | children | ReactNode | - | Required. Button children to group. | | orientation | "horizontal" \| "vertical" | "horizontal" | Layout direction of the buttons. | | size | "xl" \| "lg" \| "md" \| "sm" \| "xs" | "md" | Size applied to the group spacing. | | gap | number | - | Custom gap between buttons (overrides size default). | | description | string | - | Description text shown below the group. | | error | string | - | Error message (replaces description when present). | | aria-label | string | - | Accessible label for the button group. | | aria-labelledby | string | - | ID of element labeling the group. | | aria-describedby | string | - | ID of element describing the group. | | id | string | - | HTML id attribute. | | testID | string | - | Test identifier for testing frameworks. |

ButtonGroup Gap Defaults:

| Size | Vertical Gap | Horizontal Gap | | :--- | :----------- | :------------- | | xl | 16 | 16 | | lg | 16 | 16 | | md | 12 | 16 | | sm | 8 | 12 | | xs | 4 | 12 |

Theming

Button components use the design system theme for colors and sizing:

// Colors accessed via theme
theme.colors.control.[tone].[variant].bg      // Background color
theme.colors.control.[tone].[variant].bgHover // Hover background
theme.colors.control.[tone].[variant].bgPress // Pressed background
theme.colors.control.[tone].[variant].text    // Text color
theme.colors.control.[tone].[variant].border  // Border color

// Sizing accessed via theme
theme.sizing.button(size).height
theme.sizing.button(size).paddingHorizontal
theme.sizing.button(size).fontSize
theme.sizing.button(size).iconSize

// Border radius
theme.radius.button

Accessibility

  • All buttons use semantic <button> elements
  • IconButton requires aria-label for screen reader support
  • ButtonGroup uses role="group" with proper ARIA attributes
  • Focus indicators follow WCAG guidelines
  • Disabled buttons are properly announced to assistive technology
  • Loading state is communicated via aria-busy attribute