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 androidNavigate to Component Showcase
- Launch the app on your device/simulator
- Navigate to the Components section
- Browse the list of 30 component showcases
- 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.
| Component | File | Description |
|---|---|---|
| TextField | text-field.tsx | Text input with variants, validation states, icons |
| Button | button.tsx | Buttons with all variants (solid, outline, ghost, light, flat) |
| Checkbox | checkbox.tsx | Checkboxes with labels and controlled state |
| Switch | switch.tsx | Toggle switches with theming |
| RadioGroup | radio-group.tsx | Radio button groups with single selection |
| Select | select.tsx | Dropdown select component |
| SelectNativeModal | select-native-modal.tsx | Select with native modal presentation |
| FormField | form-field.tsx | Complete form field with label, helper, error |
Layout Components (7 showcases)
Container and organizational components.
| Component | File | Description |
|---|---|---|
| Card | card.tsx | Content cards with header, body, footer sections |
| Tabs | tabs.tsx | Tabbed navigation with customizable styles |
| Accordion | accordion.tsx | Collapsible content sections |
| Divider | divider.tsx | Visual separators with orientations |
| Surface | surface.tsx | Container with elevation and shadow effects |
| ScrollShadow | scroll-shadow.tsx | Scroll container with shadow indicators |
| PressableFeedback | pressable-feedback.tsx | Pressable wrapper with visual feedback |
Feedback Components (9 showcases)
User feedback, notifications, and overlays.
| Component | File | Description |
|---|---|---|
| Dialog | dialog.tsx | Modal dialogs with actions |
| DialogNativeModal | dialog-native-modal.tsx | Dialog with native modal |
| Toast | toast.tsx | Notification toasts with auto-dismiss |
| ToastNativeModal | toast-native-modal.tsx | Toast with native modal |
| Popover | popover.tsx | Contextual popovers attached to elements |
| PopoverNativeModal | popover-native-modal.tsx | Popover with native modal |
| BottomSheet | bottom-sheet.tsx | Bottom sheet modals for mobile UX |
| BottomSheetNativeModal | bottom-sheet-native-modal.tsx | Bottom sheet with native modal |
| Spinner | spinner.tsx | Loading spinners with various sizes |
| Skeleton | skeleton.tsx | Loading placeholders for content |
Display Components (6 showcases)
Visual elements and indicators.
| Component | File | Description |
|---|---|---|
| Avatar | avatar.tsx | User avatars with image, initials, or icon |
| Chip | chip.tsx | Tags and labels with removable support |
| ErrorView | error-view.tsx | Error state displays with retry actions |
| ComponentList | component-list.tsx | Navigation hub for all showcases |
How to Use the Showcase
1. Explore Interactively
Run the app and interact with each component:
pnpm startWhat 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:
- Variants: solid, outline, ghost, light, flat
- Sizes: sm, md, lg
- Colors: primary, secondary, success, warning, danger, default
- States: normal, disabled, loading
- Icons: startContent, endContent
- Full width:
isFullWidthprop - Radius: rounded corners customization
Example: TextField Showcase
File: src/app/(components)/text-field.tsx
What you'll learn:
- Variants: outline, filled, underline
- Label positioning: inside, outside, outside-left
- Helper text:
descriptionprop - Error states:
errorMessage,isInvalid - Icons: startContent, endContent
- Input types: password (secureTextEntry), number, email
- Keyboard types: email-address, phone-pad, numeric
Example: Card Showcase
File: src/app/(components)/card.tsx
What you'll learn:
- Structure: Card, Card.Header, Card.Body, Card.Footer
- Variants: elevated, outlined, filled
- Press behavior:
isPressable,onPress - Images: Card with image content
- 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
Navigation Structure
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.
Navigation Between Showcases
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:
- Check console for errors
- Verify HeroUI Native component import
- Restart Metro bundler:
pnpm start -c
Component looks different than showcase
Cause: Theme or styling differences
Solution:
- Check
src/themes/sky.cssfor token overrides - Verify className props match showcase
- Test in both light and dark modes
Can't find specific showcase
Cause: Looking for wrong component name
Solution:
- Check
component-list.tsxfor all showcases - Component names match HeroUI Native docs
- Use search in your IDE to find showcase files
Resources
- Official HeroUI Native Docs: https://v3.heroui.com/native
- LLM-Optimized Docs: https://v3.heroui.com/native/llms-full.txt
- HeroUI Native Guide: HeroUI Native Components
- Custom Components: Custom Components Guide
- Forms: Forms Documentation
- UI & Theming: UI & Theming Guide
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:
- Run the app:
pnpm start - Navigate to Components section
- Explore each showcase interactively
- View source code in
src/app/(components)/ - 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
| Category | Count | Examples |
|---|---|---|
| Form Components | 8 | TextField, Button, Checkbox, Switch, RadioGroup, Select |
| Layout Components | 7 | Card, Tabs, Accordion, Divider, Surface |
| Feedback Components | 9 | Dialog, Toast, Popover, BottomSheet, Spinner, Skeleton |
| Display Components | 6 | Avatar, Chip, ErrorView, ComponentList |
| Total Showcases | 30 | Complete HeroUI Native component coverage |
File Location: src/app/(components)/[component-name].tsx
Navigation: App → Components → Select Component