Skip to main content

Button

Button is used to trigger an action or event, such as submitting a form, opening a dialog, canceling an action, or performing a delete operation. By default, it renders the Pressable component.

Import#

import { Button } from "pearl-ui";

Usage#

<Button>I'm a button</Button>

Button sizes#

Use the size prop to change the size of the button. You can set the value to the keys available in PearlTheme.components.Button["sizes"], which are "xs", "s", "m", and "l" in the default theme.

<Button size="xs">Tiny Button</Button>
<Button size="s">Small Button</Button>
<Button size="m">Regular Button</Button>
<Button size="l">Large Button</Button>

Button variants#

Use the variant prop to change the visual style of the button. You can set the value to the keys available in PearlTheme.components.Button["variants"], which are "solid", "outline", and "ghost" in the default theme.

<Button variant="solid">Solid Button</Button>
<Button variant="outline">Outline Button</Button>
<Button variant="ghost">Ghost Button</Button>

Button with icon#

You can add left and right icons to Button using the leftIcon and rightIcon props respectively.

info

The leftIcon and rightIcon prop values should be React elements, NOT strings.

import { Icon } from "pearl-ui";
<Button  leftIcon={<Icon iconFamily="AntDesign" iconName="heart" />}>  Button with left icon</Button>
<Button  variant="outline"  rightIcon={<Icon iconFamily="AntDesign" iconName="cloudupload" />}>  Button with right icon</Button>

Button loading state#

Pass the isLoading prop to show a loading state on the button. By default, Button will show a spinner and leave the button's width unchanged.

You can also pass the loadingText prop to show a spinner and the loading text. When a loadingText is present, you can change the placement of the spinner element to either start or end using the spinnerPlacement prop. It is start by default.

<Button isLoading>Basic loading button</Button>
<Button isLoading loadingText="Loading">Button with loading text</Button>
<Button  isLoading  loadingText="Loading"  spinnerPlacement="end">  Button with spinner at the end</Button>

Button color scheme#

Use the colorScheme prop to change the color palette of the button. This is much more powerful than simply passing a backgroundColor style prop as the colorScheme prop changes all the use color values in a palette through a single prop.

You can set the value only to the keys available in PearlTheme.palette that contain a palette of colors represented as an object, which are "primary", "secondary", "neutral", etc in the default Pearl theme.

<Button colorScheme="primary">Primary Button</Button>
<Button colorScheme="secondary">Secondary Button</Button>

Android Ripple effect#

In order to preserve the native ripple effect on Android devices, Button provides a default ripple effect that should work for most scenarios. By default, the ripple color is the 200 palette value of the active color scheme.

Override Style#

The Button component also supports a variety of style props which can be used to override the pre-defined variant style in the theme. Manual style props passed into the component have a higher precedance than the default component style.

// passing style prop m="xl" overrides the default component style value of m="xxs"// passing style prop boxShadow="xl" adds a box shadow to the button<Button m="xl" boxShadow="3xl" variant="outline" />

Example#

info

Since the Spinner component doesn't play nicely with Expo web, please run the following example on either an Android or iOS device for better accuracy.

Accessibility#

  • Button has the role of button.
  • Button has the default accessibility label set as the text value passed into it. When the button is in a loading state, the accessibility label is set as "Loading". A custom label can be specified using the accessibilityLabel prop.
  • When the Button is disabled or loading, it is reflected as disabled and busy respectively in screen readers.
  • Similar to Pressable, Button expects an actionDescription prop to specify the intented outcome of interacting with the component eg. 'Closes modal', 'Go to the homepage', etc.

Props#

Supported style props#

Since the Button component composes the Pressable component, you can pass all Pressable related props to Button, in addition to the props given below.

Additional props#

NameRequiredTypeDefaultDescription
sizefalsePearlTheme.components.Button["sizes"]"m"Size of the button.
variantfalsePearlTheme.components.Button["variants"]"filled"Variant of the button.
isLoadingfalsebooleanfalseWhether the button is in a loading state.
isFullWidthfalsebooleanfalseWhether the button should span the entire width of the parent container.
loadingTextfalsestringnullThe text value to display when the button is in a loading state.
colorSchemefalsePearlTheme.palette"primary"Active color palette of the button. The expected value is the key of a palette object eg primary, secondary, neutral, etc. instead of an individual color
spinnerPlacementfalse"start" | "end""start"The position of the loading spinner with respect to the loadingText.
leftIconfalseReact.ReactElementnullIcon to display on the left side of the main text.
rightIconfalseReact.ReactElementnullIcon to display on the right side of the main text.

Default component Style#

export default {  parts: ["root", "text", "spinner", "icon"],  baseStyle: {    root: {      my: "xxs",      justifyContent: "center",      alignItems: "center",      activeOpacity: 0.9,    },  },  sizes: {    xs: {      root: {        py: "xxs",        px: "xs",        borderRadius: "s",      },      text: {        variant: "btn4",      },      spinner: {        my: "xxs",        size: "s",      },      icon: {        size: "s",      },    },    s: {      root: {        py: "xs",        px: "xs",        borderRadius: "s",      },      text: {        variant: "btn3",      },      spinner: {        size: "m",      },      icon: {        size: "s",      },    },    m: {      root: {        py: "s",        px: "s",        borderRadius: "m",      },      text: {        variant: "btn2",      },      spinner: {        size: "m",      },      icon: {        size: "m",      },    },    l: {      root: {        py: "m",        px: "m",        borderRadius: "m",      },      text: {        variant: "btn1",      },      spinner: {        size: "l",      },      icon: {        size: "m",      },    },  },  variants: {    filled: {      root: {        activeBackgroundColor: "primary.400",        backgroundColor: "primary.500",      },      text: { color: "neutral.50" },      spinner: {        color: "neutral.50",      },      icon: {        color: "neutral.50",      },    },    outline: {      root: {        activeBackgroundColor: {          light: "primary.50",          dark: "primary.800",        },        backgroundColor: {          light: "neutral.50",          dark: "neutral.800",        },        borderWidth: 1,        borderColor: "primary.500",      },      text: { color: "primary.500" },      spinner: {        color: "primary.500",      },      icon: {        color: "primary.500",      },    },    ghost: {      root: {        activeBackgroundColor: {          light: "primary.50",          dark: "primary.800",        },        backgroundColor: {          light: "neutral.50",          dark: "neutral.800",        },      },      text: { color: "primary.500" },      spinner: {        color: "primary.500",      },      icon: {        color: "primary.500",      },    },  },  defaults: {    size: "m",    variant: "filled",  },};