npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fluid-ui-native

v1.0.2

Published

Performant, accessible React Native & Expo UI, Media & Utility Ecosystem with Material You and Adaptive Low-End Device Engine

Readme

Fluid UI Native

A clean, fast UI component library for React Native and Expo.

npm install fluid-ui-native

What to Do After Installing (Step-by-Step)

Step 1: Install Peer Dependencies (Optional)

If you want vector icons, install react-native-svg:

# For Expo apps:
npx expo install react-native-svg

# For React Native CLI:
npm install react-native-svg
cd ios && pod install # (iOS only)

Step 2: Set Up the Providers in Your Root File

Wrap your app in DynamicThemeProvider (for colors and dark mode) and FluidToastPortal (for popup toasts):

If you use Expo Router (app/_layout.tsx):

import { Slot } from 'expo-router';
import { DynamicThemeProvider, FluidToastPortal } from 'fluid-ui-native';

export default function RootLayout() {
  return (
    <DynamicThemeProvider seedColor="#6366F1" mode="system">
      <Slot />
      <FluidToastPortal />
    </DynamicThemeProvider>
  );
}

If you use standard React Native (App.tsx):

import React from 'react';
import { SafeAreaView } from 'react-native';
import { DynamicThemeProvider, FluidToastPortal, FluidButton, FluidCard, FluidText, toast } from 'fluid-ui-native';

export default function App() {
  return (
    <DynamicThemeProvider seedColor="#6366F1" mode="system">
      <SafeAreaView style={{ flex: 1, padding: 16 }}>
        <FluidCard style={{ padding: 20 }}>
          <FluidText variant="titleLarge">Hello Fluid UI!</FluidText>
          <FluidText variant="bodyMedium" color="#64748B" style={{ marginTop: 6 }}>
            Your app is ready. Start importing any of the 84 components.
          </FluidText>

          <FluidButton
            title="Show Toast Notification"
            variant="filled"
            onPress={() => toast.success('Fluid UI is working!')}
            style={{ marginTop: 16 }}
          />
        </FluidCard>
      </SafeAreaView>
      <FluidToastPortal />
    </DynamicThemeProvider>
  );
}

How to Customize Colors & Themes

Fluid UI uses a Material You HCT color system that automatically generates WCAG AAA/AA accessible color schemes for both Light and Dark modes.

1. Changing the Primary Seed Color

Pass any color format (Hex, OKLCH, RGB, HSL, or Named Color) to seedColor:

// Using Hex
<DynamicThemeProvider seedColor="#6366F1">

// Using OKLCH (CSS 4)
<DynamicThemeProvider seedColor="oklch(0.65 0.24 265)">

// Using RGB / RGBA
<DynamicThemeProvider seedColor="rgb(16, 185, 129)">

// Using HSL
<DynamicThemeProvider seedColor="hsl(350, 89%, 60%)">

// Using Named Color (emerald, indigo, rose, amber, purple, ocean, etc.)
<DynamicThemeProvider seedColor="emerald">

2. Toggling Light & Dark Mode

Use the useFluidTheme hook inside any component:

import { useFluidTheme, FluidButton } from 'fluid-ui-native';

function HeaderThemeToggle() {
  const { mode, setMode, isDark, toggleMode } = useFluidTheme();

  return (
    <FluidButton
      title={isDark ? 'Switch to Light' : 'Switch to Dark'}
      onPress={toggleMode}
    />
  );
}

3. Using Semantic Theme Colors in Custom Components

Use the useColors() hook to access active theme tokens:

import { View, Text } from 'react-native';
import { useColors } from 'fluid-ui-native';

function CustomCard() {
  const colors = useColors();

  return (
    <View style={{ backgroundColor: colors.surface, borderColor: colors.outlineVariant }}>
      <Text style={{ color: colors.onSurface }}>Heading</Text>
      <Text style={{ color: colors.primary }}>Primary Brand Text</Text>
    </View>
  );
}

How to Use & Customize Icons

Fluid UI comes with built-in 24x24 scalable vector icons that require zero font setup.

1. Using Built-in Icons

import { 
  HomeIcon, SearchIcon, BellIcon, ShoppingCartIcon, 
  UserIcon, CameraIcon, QrCodeIcon, MessageIcon, PhoneIcon,
  CheckIcon, CloseIcon, LockIcon, StarIcon, ArrowLeftIcon 
} from 'fluid-ui-native';

// Customize size, color, strokeWidth
<SearchIcon size={22} color="#6366F1" strokeWidth={2.5} />
<StarIcon size={18} color="#F59E0B" filled={true} />

2. Passing Custom Icons to Components

Every component has custom icon slots where you can pass Lucide, Ionicons, MaterialIcons, or your own SVGs:

import { FluidButton, FluidEmptyState, FluidMessageInput } from 'fluid-ui-native';
import { Heart, Send, Sparkles } from 'lucide-react-native'; // Optional external icons

// Button with custom leading icon
<FluidButton 
  title="Favorite" 
  icon={<Heart size={18} color="#FFFFFF" />} 
/>

// Empty state with custom graphic/icon
<FluidEmptyState
  title="No Favorites Found"
  description="Items you favorite will appear here."
  icon={<Sparkles size={40} color="#6366F1" />}
  actionTitle="Explore Catalog"
  onActionPress={() => {}}
/>

// Message input with custom icons
<FluidMessageInput
  onSend={(msg) => console.log(msg)}
  attachIcon={<Sparkles size={20} color="#94A3B8" />}
/>

Main Components Guide & Examples

1. Camera Viewfinder & QR/Barcode Scanner

4-in-1 Camera Viewfinder (FluidCamera):

import { FluidCamera } from 'fluid-ui-native';

<FluidCamera
  mode="photo" // 'photo' | 'video' | 'qr' | 'document'
  flashMode="auto" // 'off' | 'on' | 'auto' | 'torch'
  zoom={1} // 0.5, 1, 2
  showGrid={true}
  onCapture={(mode) => console.log('Captured photo in mode:', mode)}
  onToggleCamera={() => console.log('Camera flipped')}
/>

Glowing Laser QR & Barcode Scanner (FluidQRScanner):

import { FluidQRScanner } from 'fluid-ui-native';

<FluidQRScanner
  hasPermission={true}
  vibrateOnScan={true} // Triggers haptic vibration on successful scan
  onRequestPermission={() => console.log('Request permission')}
  onScan={(data) => console.log('Scanned Barcode / QR:', data)}
/>

2. Security: Passcode Keypad & Pattern Lock

Banking Numeric Passcode Keypad (FluidPasscodeKeypad):

import { FluidPasscodeKeypad } from 'fluid-ui-native';

<FluidPasscodeKeypad
  length={4}
  title="Enter Security PIN"
  shuffleKeys={true} // Shuffles numbers for banking grade security
  hasError={false} // Set true to trigger shake animation
  onComplete={(pin) => console.log('PIN verified:', pin)}
  onBiometricPress={() => console.log('Trigger FaceID')}
/>

3x3 Android Pattern Unlock Grid (FluidPatternLock):

import { FluidPatternLock } from 'fluid-ui-native';

<FluidPatternLock
  size={300}
  onPatternComplete={(pattern) => {
    // Array of connected node indices e.g. [0, 1, 2, 4, 6]
    console.log('Pattern drawn:', pattern);
  }}
/>

3. Chat, Voice Notes & Messaging

Chat Message Input with Voice Recording (FluidMessageInput):

import { FluidMessageInput } from 'fluid-ui-native';

<FluidMessageInput
  placeholder="Type a message..."
  onSend={(text) => console.log('Send text:', text)}
  onAttach={() => console.log('Open photo gallery')}
  onVoiceRecordStart={() => console.log('Hold-to-record voice started')}
  onVoiceRecordEnd={() => console.log('Voice note recorded')}
/>

Chat Bubble with Reactions & Status Checks (FluidChatBubble):

import { FluidChatBubble } from 'fluid-ui-native';

<FluidChatBubble
  text="Hey! Can you send me the invoice PDF?"
  timestamp="10:42 AM"
  isSender={false}
  status="read" // 'sending' | 'sent' | 'delivered' | 'read'
  reactions={[{ emoji: '+1', count: 2, userReacted: true }]}
  onReactionPress={(emoji) => console.log('Reacted:', emoji)}
/>

Voice Note Audio Waveform Player (FluidAudioMessage):

import { FluidAudioMessage } from 'fluid-ui-native';

<FluidAudioMessage
  durationSeconds={45}
  isPlaying={false}
  playbackSpeed={1.5}
  onTogglePlay={() => {}}
  onSpeedChange={(newSpeed) => console.log('Speed:', newSpeed)}
/>

4. Saved Address Selector with GPS Coordinates (FluidAddressPicker):

import { FluidAddressPicker } from 'fluid-ui-native';

<FluidAddressPicker
  addresses={[
    { 
      id: '1', 
      type: 'home', 
      title: 'Home', 
      addressLine: '124 Market Street, Suite 400',
      city: 'San Francisco',
      postalCode: '94103',
      latitude: 37.7749,
      longitude: -122.4194,
      isDefault: true 
    },
    { 
      id: '2', 
      type: 'work', 
      title: 'Office HQ', 
      addressLine: '500 Howard St, Floor 12',
      city: 'San Francisco',
      postalCode: '94105',
      latitude: 37.7892,
      longitude: -122.3972 
    },
  ]}
  selectedId="1"
  onSelectAddress={(addr) => console.log('Selected:', addr.title, addr.latitude, addr.longitude)}
  onUseCurrentLocation={() => console.log('GPS Location button clicked')}
  onAddNewAddress={() => console.log('Open add address modal')}
/>

5. File Upload Dropzone (FluidFileUploader):

import { FluidFileUploader } from 'fluid-ui-native';

<FluidFileUploader
  maxSizeMB={10}
  maxFiles={5}
  allowedExtensions={['pdf', 'docx', 'jpg', 'png']}
  onFilesSelected={(files) => console.log('Files to upload:', files)}
/>

6. Interactive FAQ Accordion List (FluidAccordionGroup):

import { FluidAccordionGroup } from 'fluid-ui-native';

<FluidAccordionGroup
  allowMultiple={false} // Set true to allow multiple FAQs open at once
  items={[
    { id: 1, question: 'Does Fluid UI work with Expo?', answer: 'Yes, full iOS, Android, and Web Expo support out of the box.' },
    { id: 2, question: 'Do I need NativeWind?', answer: 'No! It works with regular inline styles or our built-in tw() helper.' },
    { id: 3, question: 'Can I use custom icons?', answer: 'Yes! All components accept custom icon props.' },
  ]}
/>

7. Gamification: Spin-to-Win Wheel & Scratch Card

Lucky Draw Spin Wheel (FluidSpinWheel):

import { FluidSpinWheel } from 'fluid-ui-native';

<FluidSpinWheel
  segments={[
    { label: '$10 Off', color: '#6366F1' },
    { label: 'Free Shipping', color: '#10B981' },
    { label: '20% Discount', color: '#F59E0B' },
    { label: 'Try Again', color: '#94A3B8' },
    { label: '$50 Gift Card', color: '#EC4899' },
    { label: '5% Cash', color: '#3B82F6' },
  ]}
  onSpinComplete={(winner) => alert(`You won: ${winner.label}!`)}
/>

Scratch-to-Reveal Reward Card (FluidScratchCard):

import { FluidScratchCard, FluidText } from 'fluid-ui-native';

<FluidScratchCard
  width={300}
  height={160}
  revealThresholdPercent={50}
  onRevealed={() => console.log('Reward revealed!')}
>
  <View style={{ alignItems: 'center', justifyContent: 'center', flex: 1 }}>
    <FluidText variant="headlineSmall" weight="bold" color="#10B981">
      PROMO: FLUID50
    </FluidText>
    <FluidText variant="bodySmall">50% off your next checkout</FluidText>
  </View>
</FluidScratchCard>

8. Charts: Speedometer Gauge, Donut & Bar Charts

import { FluidGaugeChart, FluidDonutChart, FluidCharts } from 'fluid-ui-native';

// Credit / Health Score Radial Speedometer Gauge
<FluidGaugeChart
  value={750}
  minValue={300}
  maxValue={850}
  unit="pts"
  statusLabel="Excellent"
/>

// Circular Donut Chart with Center Metric Label
<FluidDonutChart
  data={[
    { label: 'Completed', value: 70, color: '#10B981' },
    { label: 'In Progress', value: 20, color: '#6366F1' },
    { label: 'Pending', value: 10, color: '#F59E0B' },
  ]}
  centerMetric="70%"
  centerLabel="Efficiency"
/>

// Tactile Bar Chart
<FluidCharts
  type="bar"
  data={[
    { label: 'Mon', value: 45 },
    { label: 'Tue', value: 80 },
    { label: 'Wed', value: 65 },
    { label: 'Thu', value: 95 },
    { label: 'Fri', value: 75 },
  ]}
/>

3 Flexible Ways to Style

1. Built-in tw helper (No Tailwind setup needed)

import { View, Text } from 'react-native';
import { tw } from 'fluid-ui-native';

<View style={tw('flex-row items-center justify-between p-4 bg-white rounded-xl shadow-md')}>
  <Text style={tw('font-bold text-lg text-black')}>Order Details</Text>
</View>

2. NativeWind v4 (className)

<FluidButton title="Submit" className="bg-primary hover:bg-primary/90 p-4 rounded-xl" />

3. Standard React Native style prop

<FluidButton title="Cancel" style={{ padding: 12, borderRadius: 8 }} />

CLI Setup (Optional: Copy Component Source Files)

If you prefer copying components directly into your project (like shadcn/ui):

# 1. Initialize configuration & theme tokens
npx fluid-ui-native init

# 2. Add individual components to your @/components/ui folder
npx fluid-ui-native add button input card sheet accordion qr-scanner

All 84 Components Reference

| Category | Components | |---|---| | Inputs | FluidButton, FluidInput, FluidOutlinedInput, FluidOtpInput, FluidPasscodeKeypad, FluidPatternLock, FluidSignaturePad, FluidSwitch, FluidCheckbox, FluidSegmentedControl, FluidSlider, FluidPriceSlider, FluidSelect, FluidWheelPicker, FluidDatePicker, FluidCalendarRangePicker, FluidRating, FluidSearchBar, FluidFloatingSearchFilter, FluidFileUploader, FluidMessageInput, FluidSpeedDialMenu, FluidSwipeButton, FluidSlideToUnlock, FluidColorPicker, FluidFAB | | Surfaces & Cards | FluidCard, GlassSurface, FluidBadge, FluidChip, FluidTabs, FluidSwipeableRow, FluidDivider, FluidCarousel, FluidTable, FluidTimeline, FluidTree, FluidHeader, FluidStickyHeaderScrollView, FluidBottomNav, FluidStepper, FluidStatusDot, FluidChatBubble, FluidLiveTrackingCard, FluidCouponCard, FluidAddressPicker, FluidEmptyState, FluidBadgeNotificationCenter, FluidCodeBlock | | Modals & Sheets | FluidSheet, FluidDialog, FluidDrawer, FluidModal, FluidActionSheet, FluidCheckoutDrawer, FluidMenu, FluidAccordion, FluidAccordionGroup, FluidTooltip, FluidBiometricPrompt, FluidReactionPicker, FluidCommentSheet, FluidOnboardingTour, FluidSpotlightTour | | Media & Scanner | FluidCamera, FluidQRScanner, FluidDocumentScanner, FluidImage, FluidImageViewer, FluidStoryViewer, FluidVideo, FluidAudio, FluidAudioMessage, FluidAudioWaveformRecorder, FluidPinchZoomView, FluidAvatar, FluidAvatarGroup, FluidLazyLoader | | Charts | FluidCharts (Bar / Sparkline), FluidGaugeChart, FluidDonutChart, FluidActivityHeatmap | | Feedback | FluidToastPortal, toast, FluidSkeleton, FluidConfetti, FluidSpinWheel, FluidScratchCard, FluidBannerAlert |


FAQ & Troubleshooting

Q: Do I need to install NativeWind or Tailwind?

No. You can style components using standard React Native style={{}} or our built-in style={tw('p-4 bg-white')} helper without installing any extra styling libraries.

Q: Can I use custom icons from Lucide or FontAwesome?

Yes. All components have an icon?: React.ReactNode slot where you can pass any custom icon component.

Q: What color formats can I pass to seedColor?

You can pass Hex (#6366F1), OKLCH (oklch(0.65 0.24 265)), RGB (rgb(99, 102, 241)), HSL (hsl(239, 84%, 67%)), or Named Colors (emerald, indigo, rose).


License

MIT (c) Fluid UI Team