Caracal Starter
UI & Theming

Component Showcase

Interactive component examples demonstrating HeroUI Native components with live code and best practices.

The Caracal starter includes a component showcase system — a collection of 30 interactive screens demonstrating every HeroUI Native component with real code examples, variants, and usage patterns.

What is the Component Showcase?

Think of it as a living style guide built directly into your app. Each showcase screen demonstrates:

  • All component variants — explore different styles and configurations
  • Props in action — see how props affect component behavior
  • Usage patterns — real-world examples you can copy
  • Dark mode support — see components in both themes
  • Interactive demos — press buttons, toggle switches, see results
  • Source code reference — view implementation in src/app/(components)/

Purpose: Learn HeroUI Native components by interacting with them, then reference the source code to understand implementation.


Accessing the Showcase

Run the App

# Start development server
pnpm start

# Or run on specific platform
pnpm ios
pnpm android
  1. Launch the app on your device/simulator
  2. Navigate to the Components section
  3. Browse the list of 30 component showcases
  4. Tap any component to see its interactive demo

Component List Screen: src/app/(components)/component-list.tsx


Showcase Categories

The 30 showcases are organized into 4 categories:

Form Components (8 showcases)

Interactive form inputs and controls.

ComponentFileDescription
TextFieldtext-field.tsxText input with variants, validation states, icons
Buttonbutton.tsxButtons with all variants (solid, outline, ghost, light, flat)
Checkboxcheckbox.tsxCheckboxes with labels and controlled state
Switchswitch.tsxToggle switches with theming
RadioGroupradio-group.tsxRadio button groups with single selection
Selectselect.tsxDropdown select component
SelectNativeModalselect-native-modal.tsxSelect with native modal presentation
FormFieldform-field.tsxComplete form field with label, helper, error

Layout Components (7 showcases)

Container and organizational components.

ComponentFileDescription
Cardcard.tsxContent cards with header, body, footer sections
Tabstabs.tsxTabbed navigation with customizable styles
Accordionaccordion.tsxCollapsible content sections
Dividerdivider.tsxVisual separators with orientations
Surfacesurface.tsxContainer with elevation and shadow effects
ScrollShadowscroll-shadow.tsxScroll container with shadow indicators
PressableFeedbackpressable-feedback.tsxPressable wrapper with visual feedback

Feedback Components (9 showcases)

User feedback, notifications, and overlays.

ComponentFileDescription
Dialogdialog.tsxModal dialogs with actions
DialogNativeModaldialog-native-modal.tsxDialog with native modal
Toasttoast.tsxNotification toasts with auto-dismiss
ToastNativeModaltoast-native-modal.tsxToast with native modal
Popoverpopover.tsxContextual popovers attached to elements
PopoverNativeModalpopover-native-modal.tsxPopover with native modal
BottomSheetbottom-sheet.tsxBottom sheet modals for mobile UX
BottomSheetNativeModalbottom-sheet-native-modal.tsxBottom sheet with native modal
Spinnerspinner.tsxLoading spinners with various sizes
Skeletonskeleton.tsxLoading placeholders for content

Display Components (6 showcases)

Visual elements and indicators.

ComponentFileDescription
Avataravatar.tsxUser avatars with image, initials, or icon
Chipchip.tsxTags and labels with removable support
ErrorViewerror-view.tsxError state displays with retry actions
ComponentListcomponent-list.tsxNavigation hub for all showcases

How to Use the Showcase

1. Explore Interactively

Run the app and interact with each component:

pnpm start

What to look for:

  • Different variants (solid, outline, ghost, etc.)
  • Size options (sm, md, lg)
  • Color themes (primary, secondary, success, warning, danger)
  • Disabled and loading states
  • Dark mode behavior

2. View Source Code

Each showcase file demonstrates best practices:

// Example: src/app/(components)/button.tsx
import { Button } from 'heroui-native';
import { View, Text } from '@/components/ui';

export default function ButtonShowcase() {
  return (
    <View className="flex-1 gap-4 p-4">
      <Text className="text-xl font-bold">Button Variants</Text>

      <Button variant="solid" color="primary">
        Solid Button
      </Button>

      <Button variant="outline" color="primary">
        Outline Button
      </Button>

      <Button variant="ghost" color="primary">
        Ghost Button
      </Button>

      <Button variant="light" color="primary">
        Light Button
      </Button>

      <Button variant="flat" color="primary">
        Flat Button
      </Button>
    </View>
  );
}

3. Copy Patterns to Your Code

Use showcase implementations as templates:

import { Button, TextField } from 'heroui-native';
import { View } from '@/components/ui';

export function MyForm() {
  return (
    <View className="gap-4 p-4">
      {/* Pattern from text-field.tsx showcase */}
      <TextField
        label="Email"
        placeholder="Enter your email"
        variant="outline"
      />

      {/* Pattern from button.tsx showcase */}
      <Button variant="solid" color="primary">
        Submit
      </Button>
    </View>
  );
}

Showcase Patterns

Common Structure

All showcases follow a consistent pattern:

import { ComponentName } from 'heroui-native';
import { View, Text, ScrollView } from '@/components/ui';

export default function ComponentShowcase() {
  return (
    <ScrollView className="flex-1">
      <View className="gap-6 p-4">
        {/* Section 1: Basic variants */}
        <View className="gap-4">
          <Text className="text-xl font-bold">Variants</Text>
          <ComponentName variant="option1" />
          <ComponentName variant="option2" />
        </View>

        {/* Section 2: Sizes */}
        <View className="gap-4">
          <Text className="text-xl font-bold">Sizes</Text>
          <ComponentName size="sm" />
          <ComponentName size="md" />
          <ComponentName size="lg" />
        </View>

        {/* Section 3: Colors */}
        <View className="gap-4">
          <Text className="text-xl font-bold">Colors</Text>
          <ComponentName color="primary" />
          <ComponentName color="secondary" />
          <ComponentName color="success" />
        </View>

        {/* Section 4: States */}
        <View className="gap-4">
          <Text className="text-xl font-bold">States</Text>
          <ComponentName isDisabled />
          <ComponentName isLoading />
        </View>
      </View>
    </ScrollView>
  );
}

Learning from Showcases

Example: Button Showcase

File: src/app/(components)/button.tsx

What you'll learn:

  1. Variants: solid, outline, ghost, light, flat
  2. Sizes: sm, md, lg
  3. Colors: primary, secondary, success, warning, danger, default
  4. States: normal, disabled, loading
  5. Icons: startContent, endContent
  6. Full width: isFullWidth prop
  7. Radius: rounded corners customization

Example: TextField Showcase

File: src/app/(components)/text-field.tsx

What you'll learn:

  1. Variants: outline, filled, underline
  2. Label positioning: inside, outside, outside-left
  3. Helper text: description prop
  4. Error states: errorMessage, isInvalid
  5. Icons: startContent, endContent
  6. Input types: password (secureTextEntry), number, email
  7. Keyboard types: email-address, phone-pad, numeric

Example: Card Showcase

File: src/app/(components)/card.tsx

What you'll learn:

  1. Structure: Card, Card.Header, Card.Body, Card.Footer
  2. Variants: elevated, outlined, filled
  3. Press behavior: isPressable, onPress
  4. Images: Card with image content
  5. Composition: building complex cards

Showcase-Specific Features

Native Modal Variants

Some components have two versions:

Regular Version — uses JS-based modal rendering with more customization options (e.g., dialog.tsx)

Native Modal Version — uses platform-native modals for better performance on some devices (e.g., dialog-native-modal.tsx)

Try both in the showcase to see the difference.

Interactive Demos

Many showcases include interactive elements:

  • Button Showcase: press counters, action logs, loading state toggles
  • Dialog Showcase: open/close dialogs, confirm/cancel actions, form submission demos
  • Toast Showcase: trigger toasts, different positions, auto-dismiss timing

Adding Your Own Showcases

Step 1: Create Showcase File

// src/app/(components)/my-component.tsx
import { MyComponent } from 'heroui-native';
import { View, Text, ScrollView } from '@/components/ui';

export default function MyComponentShowcase() {
  return (
    <ScrollView className="flex-1">
      <View className="gap-6 p-4">
        <Text className="text-2xl font-bold">My Component</Text>

        <View className="gap-4">
          <Text className="text-xl font-bold">Basic Usage</Text>
          <MyComponent />
        </View>
      </View>
    </ScrollView>
  );
}

Step 2: Add to Navigation

The component-list.tsx file automatically shows all routes in the (components) group, so your new showcase will appear automatically.

Step 3: Follow Patterns

Look at existing showcases for inspiration:

  • Button showcase for action components
  • TextField showcase for input components
  • Card showcase for container components
  • Dialog showcase for overlay components

src/app/
└── (components)/
    ├── _layout.tsx          # Stack navigator
    ├── component-list.tsx   # Navigation hub
    ├── button.tsx           # Individual showcases...
    ├── text-field.tsx
    └── [28 more showcases]

URL Pattern:

  • List: /component-list
  • Detail: /button, /text-field, etc.
import { router } from 'expo-router';

// Navigate to specific showcase
router.push('/(components)/button');
router.push('/(components)/text-field');

// Go back to list
router.back();

Showcase vs Production Code

Showcase Code

Purpose: demonstration and learning

  • Focuses on visual presentation
  • Shows all variants quickly
  • Minimal logic/state management
  • No error handling
  • Static data
// Showcase — static demo
<Button variant="solid">Click Me</Button>
<Button variant="outline">Click Me</Button>
<Button variant="ghost">Click Me</Button>

Production Code

Purpose: real user interactions

  • Handles user input
  • Manages state properly
  • Includes validation
  • Has error handling
  • Uses real data
const [isLoading, setIsLoading] = useState(false);

const handleSubmit = async () => {
  setIsLoading(true);
  try {
    await api.submit(data);
  } catch (error) {
    showError(error.message);
  } finally {
    setIsLoading(false);
  }
};

<Button
  variant="solid"
  onPress={handleSubmit}
  isLoading={isLoading}
  isDisabled={!isValid}
>
  Submit Form
</Button>

Common Use Cases

Building a Form

import { Button, TextField, Checkbox } from 'heroui-native';
import { View } from '@/components/ui';

// Patterns from: text-field.tsx, button.tsx, checkbox.tsx showcases
export function SignupForm() {
  return (
    <View className="gap-4 p-4">
      <TextField label="Email" placeholder="you@example.com" />
      <TextField label="Password" secureTextEntry />
      <Checkbox>I agree to terms</Checkbox>
      <Button variant="solid" color="primary">
        Sign Up
      </Button>
    </View>
  );
}

Building a Settings Screen

import { Switch, Card } from 'heroui-native';
import { View, Text } from '@/components/ui';

// Patterns from: switch.tsx, card.tsx showcases
export function SettingsScreen() {
  return (
    <View className="gap-4 p-4">
      <Card>
        <Card.Body>
          <View className="flex-row items-center justify-between">
            <Text>Enable Notifications</Text>
            <Switch />
          </View>
        </Card.Body>
      </Card>

      <Card>
        <Card.Body>
          <View className="flex-row items-center justify-between">
            <Text>Dark Mode</Text>
            <Switch />
          </View>
        </Card.Body>
      </Card>
    </View>
  );
}

Building a Feed

import { Card, Avatar, Chip } from 'heroui-native';
import { View, Text } from '@/components/ui';

// Patterns from: card.tsx, avatar.tsx, chip.tsx showcases
export function PostCard({ post }) {
  return (
    <Card>
      <Card.Header>
        <View className="flex-row items-center gap-2">
          <Avatar src={post.authorAvatar} />
          <Text className="font-bold">{post.authorName}</Text>
        </View>
      </Card.Header>
      <Card.Body>
        <Text>{post.content}</Text>
        <View className="flex-row gap-2">
          {post.tags.map(tag => (
            <Chip key={tag} size="sm">{tag}</Chip>
          ))}
        </View>
      </Card.Body>
    </Card>
  );
}

Troubleshooting

Showcase screen is blank

Cause: Component import error or syntax issue

Solution:

  1. Check console for errors
  2. Verify HeroUI Native component import
  3. Restart Metro bundler: pnpm start -c

Component looks different than showcase

Cause: Theme or styling differences

Solution:

  1. Check src/themes/sky.css for token overrides
  2. Verify className props match showcase
  3. Test in both light and dark modes

Can't find specific showcase

Cause: Looking for wrong component name

Solution:

  1. Check component-list.tsx for all showcases
  2. Component names match HeroUI Native docs
  3. Use search in your IDE to find showcase files

Resources


Summary

The component showcase system provides:

  • 30 interactive examples of HeroUI Native components
  • Live demonstrations you can interact with
  • Source code reference for implementation patterns
  • Dark mode testing built-in
  • Learning resource for developers
  • Copy-paste templates for production code

How to use:

  1. Run the app: pnpm start
  2. Navigate to Components section
  3. Explore each showcase interactively
  4. View source code in src/app/(components)/
  5. Copy patterns to your own components

Remember: Showcases are for learning — adapt patterns to your production needs with proper validation, error handling, and state management.


Quick Reference

CategoryCountExamples
Form Components8TextField, Button, Checkbox, Switch, RadioGroup, Select
Layout Components7Card, Tabs, Accordion, Divider, Surface
Feedback Components9Dialog, Toast, Popover, BottomSheet, Spinner, Skeleton
Display Components6Avatar, Chip, ErrorView, ComponentList
Total Showcases30Complete HeroUI Native component coverage

File Location: src/app/(components)/[component-name].tsx Navigation: App → Components → Select Component

On this page