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
<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
<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 spinnerPlacement prop. It is
<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
<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
roleofbutton. - 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 theaccessibilityLabelprop. - When the Button is disabled or loading, it is reflected as
disabledandbusyrespectively in screen readers. - Similar to Pressable, Button expects an
actionDescriptionprop 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#
| Name | Required | Type | Default | Description |
|---|---|---|---|---|
| size | false | "m" | Size of the button. | |
| variant | false | "filled" | Variant of the button. | |
| isLoading | false | false | Whether the button is in a loading state. | |
| isFullWidth | false | false | Whether the button should span the entire width of the parent container. | |
| loadingText | false | null | The text value to display when the button is in a loading state. | |
| colorScheme | false | "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 | |
| spinnerPlacement | false | "start" | The position of the loading spinner with respect to the loadingText. | |
| leftIcon | false | null | Icon to display on the left side of the main text. | |
| rightIcon | false | null | Icon 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", },};