Button

The Button component allows users to trigger actions. It supports various styles, sizes, loading states, and can be grouped with ButtonGroup.

Installation

$ cbui-cli install button

Import

index.tsx
1import { Button, ButtonGroup, ButtonGroupContext, useButtonGroup } from '@/crossbuildui/button'; 2// import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; // If using icons

Button Component

Basic Usage

Provide children (text or ReactNode) and a color prop.

index.tsx
1<Button color="primary">Primary Button</Button> 2<Button color="secondary" style={{marginLeft: 8}}>Secondary Button</Button>

Variants

Buttons support multiple visual variant options: solid (default), faded, bordered, light, flat, ghost, shadow, and glass.

index.tsx
1<View style={{flexDirection: 'row', flexWrap: 'wrap', gap: 8}}> 2 <Button color="primary" variant="solid">Solid</Button> 3 <Button color="primary" variant="faded">Faded</Button> 4 <Button color="primary" variant="bordered">Bordered</Button> 5 <Button color="primary" variant="light">Light</Button> 6 <Button color="primary" variant="flat">Flat</Button> 7 <Button color="primary" variant="ghost">Ghost</Button> 8 <Button color="primary" variant="shadow">Shadow</Button> 9 <Button color="primary" variant="glass">Glass</Button> 10</View>

Sizes

Adjust button size with sm, md (default), or lg.

index.tsx
1<View style={{flexDirection: 'row', alignItems: 'center', gap: 8}}> 2 <Button color="success" size="sm">Small</Button> 3 <Button color="success" size="md">Medium (Default)</Button> 4 <Button color="success" size="lg">Large</Button> 5</View>

Radius

Control the border radius with none, sm, md (default), lg, or full.

index.tsx
1<View style={{flexDirection: 'row', flexWrap: 'wrap', gap: 8}}> 2 <Button color="warning" radius="none">None</Button> 3 <Button color="warning" radius="sm">Small</Button> 4 <Button color="warning" radius="md">Medium (Default)</Button> 5 <Button color="warning" radius="lg">Large</Button> 6 <Button color="warning" radius="full">Full</Button> 7</View>

With Icons

Add icons using startContent or endContent. Use isIconOnly for buttons containing only an icon.

index.tsx
1// Example using hypothetical Icon component 2<View style={{flexDirection: 'row', alignItems: 'center', gap: 8}}> 3 <Button color="danger" startContent={<Icon name="delete" size={18} />}> 4 Delete 5 </Button> 6 <Button color="primary" endContent={<Icon name="send" size={18} />}> 7 Send 8 </Button> 9 <Button color="secondary" isIconOnly> 10 <Icon name="cog" size={20} /> 11 </Button> 12</View>

Loading State

Set isLoading= to display a spinner. You can provide a custom spinner element.

index.tsx
1<Button color="primary" isLoading> 2 Loading... 3</Button> 4 5{/* Example with custom spinner */} 6<Button 7 color="secondary" 8 isLoading 9 spinner={<ActivityIndicator color="white" size="small" />} 10 style={{marginTop: 8}} 11> 12 Processing 13</Button>

Full Width

Make the button span the full width of its parent with fullWidth=.

index.tsx
1<Button color="default" fullWidth> 2 Full Width Button 3</Button>

Disabled State

Disable the button using the disabled prop.

index.tsx
1<Button color="primary" disabled> 2 Disabled Button 3</Button>

Glass Variant

The glass variant applies a frosted glass effect to the button background using expo-blur. Customize it with glassIntensity (0-100) and glassTint ('light', 'dark', 'default'). Text and icon colors for this variant typically default to the theme's foreground color.

index.tsx
1<View style={{flexDirection: 'row', flexWrap: 'wrap', gap: 8}}> 2 <Button color="primary" variant="glass" glassIntensity={70} glassTint="light"> 3 Light Glass 4 </Button> 5 <Button color="secondary" variant="glass" glassIntensity={40} glassTint="dark" startContent={<Icon name="blur-on" size={18} color="white" />}> 6 Dark Glass 7 </Button> 8 <Button variant="glass" isIconOnly> 9 <Icon name="settings" size={20} /> 10 </Button> 11</View> 12 13<ButtonGroup color="success" variant="glass" glassIntensity={50} style={{marginTop: 10}}> 14 <Button>Glass Group 1</Button> 15 <Button>Glass Group 2</Button> 16</ButtonGroup>

ButtonGroup Component

Basic Usage

Group multiple Button components. Props like color, variant, size, radius, and glass props (glassTint, glassIntensity) can be set on ButtonGroup to apply to all children.

index.tsx
1<ButtonGroup color="primary" variant="solid"> 2 <Button>One</Button> 3 <Button>Two</Button> 4 <Button>Three</Button> 5</ButtonGroup>

Attached Buttons

Use isAttached= to remove spacing between buttons and create a visually connected group. The radius prop on ButtonGroup will then apply to the outer corners of the group. Use isVertical for vertical stacking.

index.tsx
1<ButtonGroup color="secondary" variant="bordered" isAttached radius="md"> 2 <Button>Left</Button> 3 <Button>Middle</Button> 4 <Button>Right</Button> 5</ButtonGroup> 6 7<ButtonGroup color="success" variant="faded" isAttached isVertical radius="lg" style={{marginTop: 10}}> 8 <Button>Top</Button> 9 <Button>Center</Button> 10 <Button>Bottom</Button> 11</ButtonGroup>

Individual Overrides

Props set on individual Button components within a ButtonGroup will override the group's settings.

index.tsx
1<ButtonGroup color="warning" size="lg"> 2 <Button>Large Warn</Button> 3 <Button color="danger" size="sm">Small Danger</Button> 4 <Button>Large Warn</Button> 5</ButtonGroup>

Using ButtonGroup Context

For advanced scenarios, or if you need to create custom components that react to the ButtonGroup's properties, you can use the useButtonGroup hook. This hook provides access to the ButtonGroupContext, which includes properties like color, size, variant, isDisabled, isAttached, isVertical, and glass props.

Any component calling useButtonGroup must be a descendant of a ButtonGroup component.

MyCustomGroupComponent.tsx
1import { Button, ButtonGroup, useButtonGroup } from '@/crossbuildui/button'; 2import { Text, View } from 'react-native'; 3 4const GroupInfoDisplay = () => { 5 const context = useButtonGroup(); 6 7 if (!context) { 8 // This should not happen if GroupInfoDisplay is used correctly within a ButtonGroup 9 return <Text>Not within a ButtonGroup context.</Text>; 10 } 11 12 const { color, size, variant, isDisabled, isAttached, isVertical } = context; 13 14 return ( 15 <View style={{ marginTop: 8, padding: 8, backgroundColor: '#f0f0f0', borderRadius: 4 }}> 16 <Text>Group Context:</Text> 17 <Text>- Color: {color || 'default'}</Text> 18 <Text>- Size: {size || 'md'}</Text> 19 <Text>- Variant: {variant || 'solid'}</Text> 20 <Text>- Disabled: {isDisabled ? 'Yes' : 'No'}</Text> 21 <Text>- Attached: {isAttached ? 'Yes' : 'No'}, Vertical: {isVertical ? 'Yes' : 'No'}</Text> 22 </View> 23 ); 24}; 25<ButtonGroup color="success" size="sm" isAttached><Button>First</Button><Button>Second</Button><GroupInfoDisplay /></ButtonGroup>

Props Overview

Button Props

PROPTYPEDEFAULTDESCRIPTION
childrenReactNode-Content of the button.
variantButtonVariant'solid'Visual style.
colorButtonColor'default'Semantic color.
sizeButtonSize'md'Size of the button.
radiusButtonRadius'md'Border radius.
fullWidthbooleanfalseTake full parent width.
isLoadingbooleanfalseLoading state.
spinnerReactElement-Custom spinner element.
spinnerPropsActivityIndicatorProps-Props for default spinner.
startContentReactElement-Content before children.
endContentReactElement-Content after children.
isIconOnlybooleanfalseStyle for icon-only button.
styleStyleProp<ViewStyle>-Custom style for the Pressable.
textStyleStyleProp<TextStyle>-Custom style for text children.
disabledbooleanfalseDisable the button.
onPressPressableProps['onPress']-Callback on press.
glassTint'default' | 'light' | 'dark'Theme-derivedTint for the 'glass' variant blur effect.
glassIntensitynumber50Intensity (0-100) for the 'glass' variant blur effect.
...PressablePropsvarious-Other props from React Native's Pressable.

ButtonGroup Props

PROPTYPEDEFAULTDESCRIPTION
childrenReactElement<ButtonProps>[]-Button components to group.
variantButtonVariant-Default variant for grouped buttons.
colorButtonColor-Default color for grouped buttons.
sizeButtonSize-Default size for grouped buttons.
radiusButtonRadius-Default radius for grouped buttons (applies to outer corners if attached).
fullWidthbooleanfalseGroup takes full parent width.
isVerticalbooleanfalseStack buttons vertically.
isAttachedbooleanfalseAttach buttons (no space, shared borders).
glassTint'default' | 'light' | 'dark'Theme-derivedDefault tint for 'glass' variant on grouped buttons.
glassIntensitynumber50Default intensity (0-100) for 'glass' variant.
styleStyleProp<ViewStyle>-Custom style for the group container.

Styling

Customize appearance using:

  • Button:
    • style: Applied to the root Pressable component of the button.
    • textStyle: Applied to the Text component if children is a string.
    • For the glass variant, the background is rendered by BlurView from expo-blur, controlled by glassIntensity and glassTint. The style prop's backgroundColor will be overridden for this variant.
  • ButtonGroup:
    • style: Applied to the root View container of the group.
    • Individual buttons within a group can also have their own style prop, which will be merged with styles derived from the group (e.g., for attached borders).
index.tsx
1<Button 2 color="primary" 3 variant="solid" 4 style={{ marginVertical: 10, transform: [{ skewX: '-5deg' }] }} // Styles the outer Pressable 5 textStyle={{ fontWeight: 'bold', letterSpacing: 1 }} 6 startContent={<Icon name="star" size={18} />} 7> 8 Styled Button 9</Button> 10 11<ButtonGroup 12 style={{ padding: 10, backgroundColor: '#f0f0f0', borderRadius: 12 }} 13 isAttached 14 radius="lg" 15 color="default" 16> 17 <Button>Grouped Styled 1</Button> 18 <Button style={{borderColor: 'purple', borderWidth: 1}}>Grouped Styled 2</Button> 19</ButtonGroup>

Accessibility

The Button component is built on Pressable and includes accessibility features:

  • accessibilityRole="button" is set by default.
  • accessibilityState includes disabled and busy (when isLoading is true).
  • Ensure meaningful text content or provide an accessibilityLabel for icon-only buttons.