ExpoStartup

Stack

A flexible layout component for arranging elements vertically or horizontally with consistent spacing.

Stack

The Stack component provides a simple way to create consistently spaced vertical or horizontal layouts. It's ideal for arranging items in a sequence with uniform spacing between them.

Features

  • Direction Control: Arrange items vertically or horizontally
  • Consistent Spacing: Uniform gaps between elements
  • Alignment Options: Control alignment along both axes
  • Responsive: Works well in various screen sizes
  • Nesting Support: Stack components can be nested for complex layouts
  • Styling Control: Accepts additional Tailwind classes and style objects

Import

import Stack from '@/components/layout/Stack';

Props

PropTypeDefaultDescription
spacingnumber4Spacing between items (in points)
direction'vertical' | 'horizontal''vertical'Direction of the stack layout
align'start' | 'center' | 'end' | 'stretch''start'Alignment of items perpendicular to the stack direction
justify'start' | 'center' | 'end' | 'between' | 'around''start'Justification of items along the stack direction
classNamestring''Additional Tailwind classes
styleViewStyleAdditional style object
childrenReact.ReactNodeRequiredContent to display in the stack

Usage Examples

Basic Vertical Stack

<Stack spacing={8}>
  <Text>Item 1</Text>
  <Text>Item 2</Text>
  <Text>Item 3</Text>
</Stack>

Horizontal Stack

<Stack direction="horizontal" spacing={12}>
  <View className="w-8 h-8 bg-blue-500 rounded" />
  <View className="w-8 h-8 bg-green-500 rounded" />
  <View className="w-8 h-8 bg-red-500 rounded" />
</Stack>

Stack with Alignment

<Stack 
  spacing={8} 
  align="center" 
  justify="center"
  className="bg-gray-100 p-4 rounded"
>
  <Text>Centered Item 1</Text>
  <Text>Centered Item 2</Text>
  <Text>Centered Item 3</Text>
</Stack>

Nested Stacks

<Stack spacing={16}>
  <Text className="text-lg font-bold">Personal Information</Text>
  
  <Stack spacing={8}>
    <Input label="First Name" />
    <Input label="Last Name" />
  </Stack>
  
  <Stack spacing={8}>
    <Text className="font-medium">Contact Details</Text>
    <Input label="Email" />
    <Input label="Phone" />
  </Stack>
</Stack>

Form Layout Example

function ProfileForm() {
  const [form, setForm] = useState({
    firstName: '',
    lastName: '',
    email: '',
    bio: ''
  });
 
  const updateField = (field, value) => {
    setForm({
      ...form,
      [field]: value
    });
  };
 
  return (
    <Stack spacing={16} className="p-4">
      <Text className="text-xl font-bold">Edit Profile</Text>
      
      <Stack direction="horizontal" spacing={12} justify="between">
        <View className="flex-1">
          <Input
            label="First Name"
            value={form.firstName}
            onChangeText={(text) => updateField('firstName', text)}
          />
        </View>
        
        <View className="flex-1">
          <Input
            label="Last Name"
            value={form.lastName}
            onChangeText={(text) => updateField('lastName', text)}
          />
        </View>
      </Stack>
      
      <Input
        label="Email"
        value={form.email}
        onChangeText={(text) => updateField('email', text)}
        keyboardType="email-address"
      />
      
      <Input
        label="Bio"
        value={form.bio}
        onChangeText={(text) => updateField('bio', text)}
        isMultiline={true}
      />
      
      <Stack direction="horizontal" spacing={12} justify="end">
        <Button title="Cancel" variant="outline" />
        <Button title="Save" />
      </Stack>
    </Stack>
  );
}

Card Layout Example

function FeatureCard({ title, description, icon }) {
  return (
    <Card className="p-4">
      <Stack spacing={12} align="center">
        <View className="bg-highlight/20 p-3 rounded-full">
          <Icon name={icon} size={24} color="#5271FF" />
        </View>
        
        <Text className="text-lg font-medium text-center">{title}</Text>
        
        <Text className="text-center text-gray-600">{description}</Text>
        
        <Button title="Learn More" size="sm" variant="ghost" />
      </Stack>
    </Card>
  );
}
 
function FeatureSection() {
  return (
    <Stack spacing={24}>
      <Text className="text-2xl font-bold text-center">Key Features</Text>
      
      <Stack direction="horizontal" spacing={16} justify="center" className="flex-wrap">
        <FeatureCard 
          title="Fast Performance" 
          description="Lightning fast load times and smooth interactions" 
          icon="Zap"
        />
        
        <FeatureCard 
          title="Secure Storage" 
          description="Data encryption and secure authentication" 
          icon="Shield"
        />
        
        <FeatureCard 
          title="Cloud Sync" 
          description="Access your data from any device" 
          icon="Cloud"
        />
      </Stack>
    </Stack>
  );
}

Best Practices

Choose Appropriate Direction

Select the direction based on your content:

// Use vertical for forms and lists
<Stack spacing={8}>
  <Input label="Email" />
  <Input label="Password" />
  <Button title="Submit" />
</Stack>
 
// Use horizontal for toolbars and button groups
<Stack direction="horizontal" spacing={8}>
  <Button title="Save" />
  <Button title="Cancel" variant="outline" />
  <Button title="Delete" variant="danger" />
</Stack>

Consistent Spacing

Use consistent spacing values throughout your application for a polished look:

// Define spacing constants
const SPACING = {
  xs: 4,
  sm: 8,
  md: 16,
  lg: 24,
  xl: 32
};
 
// Use them consistently
<Stack spacing={SPACING.md}>
  <Text className="text-xl font-bold">Section Title</Text>
  <Stack spacing={SPACING.sm}>
    <Text>Some content here</Text>
    <Text>More content here</Text>
  </Stack>
</Stack>

Use with Other Layout Components

Combine Stack with other layout components for complex UIs:

<Section title="Profile Information">
  <Stack spacing={16}>
    <Grid columns={2} spacing={12}>
      <Input label="First Name" />
      <Input label="Last Name" />
    </Grid>
    
    <Input label="Email" />
    
    <Divider />
    
    <Text className="font-medium">Bio</Text>
    <Input isMultiline={true} numberOfLines={4} />
  </Stack>
</Section>

Implementation Details

The Stack component uses React Native's View component and applies Tailwind CSS classes for direction, alignment, and justification. The spacing between items is implemented using the gap style property.

The component handles rendering null or undefined children by filtering them out, which ensures that the layout remains consistent even when some items are conditionally rendered.

The alignment and justification properties are mapped to the corresponding Tailwind CSS classes:

  • align controls items-* classes
  • justify controls justify-* classes

Notes

  • The Stack component is ideal for creating consistent vertical or horizontal layouts
  • For grid layouts, consider using the Grid component instead
  • The spacing prop is measured in logical pixels rather than in a responsive unit
  • Empty or null children are automatically filtered out to avoid layout issues
  • The component works well on both iOS and Android

On this page