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

react-native-premium-support

v0.1.5

Published

A highly customizable, premium help and support module for React Native apps.

Readme

react-native-premium-support

A highly customizable, premium help and support module for React Native apps.

🔌 Extensibility

Custom Form Fields

You can add custom fields to the ContactForm (e.g., Order ID, Phone Number) that will be included in the metadata object of the submitted ticket.

<SupportModule
  config={{
    customFields: [
      { key: 'order_id', label: 'Order ID', placeholder: 'e.g. #12345', type: 'text' },
      { key: 'urgency', label: 'Urgency Level', placeholder: 'Low/Medium/High', type: 'text' }
    ],
    onSend: async (data) => {
      console.log('Ticket Data:', data.message);
      console.log('Custom Data:', data.metadata); // Contains { order_id: '...', urgency: '...' }
    }
  }}
/>

Rich Text FAQs

The answer field in SupportFAQ now accepts a ReactNode, allowing you to include links, images, or custom components in your FAQs.

const faqs = [
  {
    id: '1',
    question: 'How do I contact support?',
    answer: (
      <View>
        <Text>You can email us or call our hotline at:</Text>
        <TouchableOpacity onPress={() => Linking.openURL('tel:123456789')}>
          <Text style={{ color: 'blue', fontWeight: 'bold' }}>+1 (234) 567-89</Text>
        </TouchableOpacity>
      </View>
    )
  }
];

🛠️ Roadmap & TODO

Check the todo.md file for planned features like AI deflection, Live Chat, and Push Notification support.

  • 📂 Premium Media Suite: Horizontal attachment lists, media-only bubbles, and full-screen image previews.
  • 🚀 Modular & Expandable: Pure JS/TS implementation.
  • 🎨 White-Label Ready: Total control over icons, text, and layouts.
  • 🛡️ Admin Suite: Built-in dashboard for managing user tickets, app ratings, and real-time status updates (supported in both inline and full-screen modes).
  • 📂 Attachment Support: Native attachment picking and inline previews in chat threads.
  • 📬 Backend Agnostic: Bring your own logic via onSend and onReply.
  • 💬 Threaded Conversations: Full multi-turn support messages with bubble UI.
  • Premium UX: RTL support, Maintenance mode, and sticky FAQ headers.
  • 📱 Flexible Layouts: Grid or List FAQ views, screen-specific visibility controls.
  • 🏗️ Interactive Polish: Skeleton loading states, Floating Action Buttons (FAB), and custom empty states.
  • 🎨 Deep Aesthetic Control: Glassmorphism, gradient support, and customizable chat bubble tail styles.

Installation

npm install react-native-premium-support

Usage

import { SupportProvider, SupportModule } from 'react-native-premium-support';

const supportConfig = {
  isAdmin: false, 
  onSend: async (data) => {
    console.log('Sending ticket:', data);
  },
  onReply: async (ticketId, message, attachments) => {
    console.log('Replying to ticket:', ticketId, message, attachments);
  },
  // NEW: Custom Statuses & Colors
  statusOptions: ['open', 'pending', 'closed'],
  statusColors: {
    open: '#EF4444',
    pending: '#F59E0B',
    closed: '#10B981',
  },
  onUpdateTicketStatus: async (ticketId, status) => {
    console.log('Updating status:', ticketId, status);
  },
  onPickAttachment: async () => {
    // Return { uri, name, type }
  },
  layout: {
    expansionMode: 'screen', 
    tabPosition: 'top',
    statusPosition: 'top', 
    headerAlignment: 'left', // 'left' | 'center'
    isRTL: false, // RTL support
    faqLayout: 'grid', // 'grid' or 'list'
    showFAB: true, // Floating Action Button
    fabPosition: 'bottom-right',
    stickyFAQCategories: true, // Sticky headers in FAQ
    compactMode: false, // Reduced spacing/font sizes
    bubbleTailStyle: 'round', // 'round', 'sharp', or 'none'
    // Screen-specific controls
    faq: { hideHeader: false, hideSearch: false },
    contact: { hideHeader: true }, 
    history: { hideTitle: true },
  },
  isMaintenanceMode: false, // Maintenance mode
  isLoading: false, // Show skeleton loaders
};

export default function App() {
  return (
    <SupportProvider config={supportConfig}>
      <SupportModule />
    </SupportProvider>
  );
}

📱 Layout & UI Customization

The library offers high-fidelity layout control via the layout configuration object:

| Prop | Type | Description | |------|------|-------------| | expansionMode | 'inline' \| 'screen' | How threads expand. inline uses an accordion, screen opens a full-screen modal. | | searchPosition | 'header' \| 'content' \| 'hidden' | Placement of the FAQ search bar. | | filterType | 'pills' \| 'dropdown' \| 'modal' | Styling for category filters in the FAQ list. | | tabPosition | 'top' \| 'bottom' | Placement of the Support/History tabs. | | isRTL | boolean | Flips the UI layout for Right-to-Left languages. | | headerAlignment | 'left' \| 'center' | Alignment for the main header title and subtitle. | | faqLayout | 'grid' \| 'list' | Changes FAQ item presentation. | | showFAB | boolean | Toggles the Floating Action Button. | | fabPosition | 'bottom-left' \| 'bottom-right' \| 'top-left' \| 'top-right' | Position of the FAB. | | stickyFAQCategories | boolean | Enables sticky category headers in the FAQ list. | | bubbleTailStyle | 'round' \| 'sharp' \| 'none' | Tail style for chat bubbles. | | compactMode | boolean | Reduced padding and text sizes for high-density UI. |

⚙️ Root Configuration

Props passed directly to the config object:

| Prop | Type | Description | |------|------|-------------| | isAdmin | boolean | Enables administrative dashboard mode. | | isLoading | boolean | Toggles skeleton loading states globally. | | isMaintenanceMode | boolean | Displays a maintenance screen and disables interaction. | | onPickAttachment | () => Promise<Attachment \| Attachment[]> | Callback for handling file/image attachments. Returns a single { uri, name, type } or an array of them. | | statusOptions | string[] | Custom status labels for ticket management. | | renderEmptyState | (type) => ReactNode | Custom renderer for empty FAQ, history, or search results. | | renderSkeleton | (type) => ReactNode | Custom renderer for FAQ or history loading states. | | onError | (error, context) => void | Global callback triggered whenever an internal async operation fails. | | showInternalErrors | boolean | Toggles the built-in red error notification box. Default: true. |

layout: {
  expansionMode: 'screen', 
  searchPosition: 'header',
  filterType: 'modal',
  showHistoryByDefault: false,
}

🎨 Granular Styling

Use the styles prop for deep customization of any UI component without overriding themes.

styles: {
  card: { borderRadius: 20, padding: 12 },
  bubble: { borderRadius: 15, maxWidth: '80%' },
  button: { height: 50, borderRadius: 25 },
  headerTitle: { fontSize: 24, fontWeight: '900' }
}

Admin Features 🛡️

Enable isAdmin: true in your configuration to switch the SupportModule into an administrative management dashboard.

1. Ticket Management

Admins can view all user tickets by providing the allTickets array in the config.

2. Status Updates & Search 🔍

Admins can update ticket status in real-time and utilize the Filtered Search bar to instantly find tickets by subject, user name, or email.

Custom Statuses:

statusOptions: ['open', 'in-progress', 'resolved'],
onUpdateTicketStatus: async (id, status) => { /* update backend */ }

3. User Identity Integration 👤

The SupportTicket interface now includes first-class identity fields, which are automatically displayed in the admin dashboard:

  • userName: The full name of the user who opened the ticket.
  • userEmail: The primary contact email.

4. App Rating Management ⭐

Admins can view and respond to app store ratings directly within the dashboard.

  • ratings: An array of SupportRating objects.
  • onReplyToRating: Callback triggered when an admin responds to a specific rating.

Thread Expansion Modes 💬

Customize how users and admins interact with conversation threads:

  • inline: Threads expand directly within the list using a smooth accordion animation. Best for short, frequent interactions.
  • screen: Threads open in a focused, full-screen modal. Best for long, detailed support conversations.

UI Enhancements ✨

  • Thread Previews: layout.showThreadPreview enables a one-line snippet of the first message on the ticket card.
  • Message Badges: layout.showThreadMessageCount displays a subtle count badge indicating the total number of messages in the thread.

Media & Attachment Suite 📂

The library includes a first-class media handling experience:

  • Horizontal Scroll: Multiple attachments are displayed in a sleek horizontal row within the chat bubble.
  • Media-Only Bubbles: Optimized layout for messages containing only attachments.
  • Smart Thumbnails: Automatic image detection for http, file, and content URIs.
  • Full-Screen Preview: Tap any image attachment to view it in a high-fidelity full-screen modal.
  • Read-Only Intelligence: Attachment interaction controls (like the remove button) are automatically hidden in the conversation history.
  • Controlled Stability: Selected attachments are managed via controlled state, ensuring they are only cleared upon successful submission and preventing data loss during network failures.

Theme Customization

const customTheme = {
  colors: {
    primary: '#4F46E5',
    background: '#FFFFFF',
    card: '#F9FAFB',
    pending: '#F59E0B',
  },
  borderRadius: {
    md: 12,
    lg: 16,
  }
};

<SupportProvider config={{ ...config, theme: customTheme }}>
  <SupportModule />
</SupportProvider>

Advanced Customization (Styles Override) 🎨

For granular control over specific components without changing the global theme, use the styles property:

const supportConfig = {
  // ... other config
  styles: {
    card: { borderRadius: 20, padding: 24, marginVertical: 10 },
    button: { borderRadius: 30, height: 60, shadowOpacity: 0.2 },
    buttonText: { fontSize: 18, fontWeight: '800', letterSpacing: 1.2 },
    bubble: { borderRadius: 18, maxWidth: '85%' },
    bubbleText: { lineHeight: 22, fontSize: 16 },
    input: { borderRadius: 15, fontSize: 16, minHeight: 100 },
    stars: { size: 24, activeColor: '#FFC107', inactiveColor: '#E0E0E0' },
    tabBar: { borderRadius: 50, padding: 6 },
    headerTitle: { fontSize: 32, fontWeight: '900' },
    headerSubtitle: { textTransform: 'none', letterSpacing: 0 }
  }
};

Backend Integration Examples

1. Using Supabase Edge Functions

onSend: async (data) => {
  const { error } = await supabase.functions.invoke('send-support-email', {
    body: data,
  });
  if (error) throw error;
}

2. Using Resend (Node.js)

onSend: async (data) => {
  const response = await fetch('https://api.resend.com/emails', {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ from: '[email protected]', to: '[email protected]', ...data }),
  });
}

Advanced Error Handling 🛡️

By default, the library shows a built-in red error box when an async operation (like sending a ticket) fails. You can disable this and handle errors manually using showInternalErrors and onError.

<SupportProvider config={{
  showInternalErrors: false, // Turn off built-in UI
  onError: (error, context) => {
    // Log to your analytics service
    Analytics.logError(error, context.action);
    
    // Show a custom Toast or SnackBar
    Toast.show({
      type: 'error',
      text1: 'Oops!',
      text2: error.message
    });
  },
  onSend: async (data) => {
    // ... your logic
  }
}}>
  <SupportModule />
</SupportProvider>

License

MIT