Button

Use the Button component to trigger an action or event. The Button component utilizes Pressable under the hood to provide touchable behavior.

Props

children

Use this to set the text of the button.

TypeDefaultDescription
ReactNode/Placed inside Text component.

Example

Source code
<UIButton>
  Button text
</UIButton>

variant

Use this to set the button variant. Either both the variant and color props should be used together, or none at all, as they go in pairs.

TypeDefaultDescription
'solid' 
| 'outline'
'solid'This setting affects how the Color property will apply to text, background, and border color.

Example

Source code
<View>
  <UIButton>
    Solid
  </UIButton>
  <UIButton variant="outline">
    Outline
  </UIButton>
</View>

color

Use this to change the button color. Either both the variant and color props should be used together, or none at all, as they go in pairs.

TypeDefaultDescription
'primary' 
| 'secondary' 
| 'danger' 
| string
'primary'Colors are defined on the Theme page. For example, primary corresponds to theme.color.primaryMain.

Example

Source code
<View>
  <UIButton>
    Primary
  </UIButton>
  <UIButton color="secondary">
    Secondary
  </UIButton>
  <UIButton color="danger">
    Danger
  </UIButton>
  <UIButton color="#f29c38">
    Custom string
  </UIButton>
  <UIButton variant="outline">
    Primary
  </UIButton>
  <UIButton variant="outline" color="secondary">
    Secondary
  </UIButton>
  <UIButton variant="outline" color="danger">
    Danger
  </UIButton>
  <UIButton variant="outline" color="#f29c38">
    Custom string
  </UIButton>
</View>

size

Use this to change the button size.

TypeDefaultDescription
'sm' | 'md'
'md'Button size values are defined on Theme page. For example md corresponds to theme.size.buttonInputMD.

Example

Source code
<View>
  <UIButton icon={<MaterialIcons name="shopping-cart" />}>
    Size md
  </UIButton>
  <UIButton
    size="sm"
    icon={<MaterialIcons name="shopping-cart" />}
  >
    Size sm
  </UIButton>
</View>

icon

Use this to set an icon.

TypeDefaultDescription
ReactNode
/We are using the MaterialIcons component from react-native-vector-icons package.

Example

Source code
<UIButton icon={<MaterialIcons name="shopping-cart" />}>
  Button with icon
</UIButton>

...rest

Use this to spread the rest of the props to the Pressable element.

TypeDefaultDescription
PressableProps/If you need more control over the Pressable element inside the Button, you can use any prop from Pressable this way.

Example

Source code
<Pressable {...rest}>
  {/* ... */}
</Pressable>

Static

border

Use this to set the border width.

borderColor

Use this to set the border color. Visible only if variant and color props are not enabled.

bg

Use this to set the background color. Visible only if variant and color props are not enabled.

h

Use this to set the height of the button. Visible only if size prop is not enabled.

borderStyle

Use this to set the border style.

minW

Use this to set the minimum width of the button. Sometimes, it can be useful to prevent the button from shrinking too much (for example, when the text is too short).

px

Use this to set horizontal padding.

rounded - when size prop is enabled

Use this to set the border radius.

rounded - when size prop is not enabled

Use this to set the border radius.

iconPosition

Use this to set the position of the icon relative to the text.

iconGap

The distance between the icon and text.

iconAlignment

This option is visible only when the button is full width and the content doesn't take the entire space. For example, if the parent layout determines the button's width.

iconSize

Use this to set the size of the icon. Visible only if size prop is not enabled.

textSize

Use this to set the size of the text. Visible only if size prop is not enabled.

textColor

Use this to set the color of the text. Visible only if variant and color props are not enabled.

activeOpacity

Use this to set the opacity of the button when it's active.

Preview

align

Use this to change the parent layout alignment and check how the button behaves. It can be useful when changing iconAlignment from static tab.

Example

Source code
<View>
  <View>
    {/* Button with iconAlignment="center" (inside static tab) */}
    <UIButton
      icon={<MaterialIcons name="shopping-cart" />}
    >
      Parent stretch
    </UIButton>
  </View>
  <View style={{alignItems: 'center'}}>
    {/* Button with iconAlignment="center" (inside static tab) */}
    <UIButton
      icon={<MaterialIcons name="shopping-cart" />}
    >
      Parent center
    </UIButton>
  </View>
  <View>
    {/* Button with iconAlignment="edge" (inside static tab) */}
    <UIButton
      icon={<MaterialIcons name="shopping-cart" />}
    >
      Parent stretch
    </UIButton>
  </View>
  <View style={{alignItems: 'center'}}>
    {/* Button with iconAlignment="edge" (inside static tab) */}
    <UIButton
      icon={<MaterialIcons name="shopping-cart" />}
    >
      Parent center
    </UIButton>
  </View>
</View>

Tips

Consider keeping the border

This helps prevent misalignment issues, especially when items are closely positioned vertically. For instance, if you have two buttons with different styling, such as one with no border and a solid background, and the other with a border, border color, and transparent background, the misalignment becomes noticeable when the icon is aligned on the edge.

Button's height

We set a fixed height to maintain consistency across different content lengths and parent layouts. This ensures that the button's height remains constant, even if its content or adjacent elements vary in size. Particularly when it's within a flexbox with flexDirection: 'row'; alignItems: 'stretch', and if a sibling element has a larger height than the button itself.

Editor

Source code
import React from 'react';
import {Pressable, Text} from 'react-native';

const UIButton = ({
  variant = 'solid',
  color = 'primary',
  size = 'md',
  icon,
  style,
  children,
  ...rest
}) => {
  const colorToValue = {
    primary: '#169f94',
    secondary: '#3b84a5',
    danger: '#e15240',
  }[color] || color;

  const styles = {
    btn: {
      flexDirection: 'row',
      flexShrink: 1,
      alignItems: 'center',
      justifyContent: 'center',
      minWidth: 100,
      maxWidth: '100%',
      borderWidth: 1,
      borderStyle: 'solid',
      overflow: 'hidden',
    },
    btnVariantSolid: {
      backgroundColor: colorToValue,
      borderColor: colorToValue,
    },
    btnVariantOutline: {
      backgroundColor: '#ffffff00',
      borderColor: colorToValue,
    },
    btnSizeSM: {
      height: 28,
      paddingHorizontal: 12,
      borderRadius: 4,
    },
    btnSizeMD: {
      height: 46,
      paddingHorizontal: 20,
      borderRadius: 8,
    },
    btnText: {
      flexShrink: 1,
    },
    btnTextVariantSolid: {
      color: '#ffffff',
    },
    btnTextVariantOutline: {
      color: colorToValue,
    },
    btnTextSizeSM: {
      fontSize: 16,
    },
    btnTextSizeMD: {
      fontSize: 20
    },
    btnIcon: {
      flexShrink: 0,
    },
    btnIconVariantSolid: {
      color: '#ffffff',
    },
    btnIconVariantOutline: {
      color: colorToValue,
    },
    btnIconSM: {
      width: 20,
      height: 20,
      fontSize: 20,
      marginRight: 7,
    },
    btnIconMD: {
      width: 24,
      height: 24,
      fontSize: 24,
      marginRight: 12,
    },
  };

  const btnSizeBasedStyles = {
    'sm': styles.btnSizeSM,
    'md': styles.btnSizeMD,
  }[size];
  const btnTextSizeBasedStyles = {
    'sm': styles.btnTextSizeSM,
    'md': styles.btnTextSizeMD,
  }[size];
  const btnIconSizeBasedStyles = {
    'sm': styles.btnIconSM,
    'md': styles.btnIconMD,
  }[size];
  const btnVariantBasedStyles = {
    'solid': styles.btnVariantSolid,
    'outline': styles.btnVariantOutline,
  }[variant];
  const btnTextVariantBasedStyles = {
    'solid': styles.btnTextVariantSolid,
    'outline': styles.btnTextVariantOutline,
  }[variant];
  const btnIconVariantBasedStyles = {
    'solid': styles.btnIconVariantSolid,
    'outline': styles.btnIconVariantOutline,
  }[variant];
  
  return (
    <Pressable style={({pressed}) => [styles.btn, btnSizeBasedStyles, btnVariantBasedStyles, {opacity: pressed ? 0.8 : 1}, style]} {...rest}>
      {icon ? (
        React.cloneElement(icon, {style: [styles.btnIcon, btnIconSizeBasedStyles, btnIconVariantBasedStyles, icon?.props?.style]})
      ) : null}
      {children ? (
        <Text style={[styles.btnText, btnTextSizeBasedStyles, btnTextVariantBasedStyles]} numberOfLines={1}>{children}</Text>
      ) : null}
    </Pressable>
  )
};

export default UIButton;
Usage example
<UIButton
  icon={<MaterialIcons name="shopping-cart" />}
>
  Add to Cart
</UIButton>