npm package: @seybar/react-native-notifier
Description: A beautiful, customizable notification component for React Native with theme support, smooth animations, and extensive icon library integration.
Author: Seybar
Latest version: 1.2.4

# @seybar/react-native-notifier

A powerful, customizable notification library for React Native with support for both modal dialogs and banner notifications. Features theme support, custom fonts, animations, flexible positioning, and focus mode.

## Features

- **Dual Notification Types**: Modal dialogs and banner notifications
- **Theme Support**: Built-in light/dark mode with auto-detection
- **Custom Icons**: Support for 12+ icon libraries from @expo/vector-icons
- **Smooth Animations**: Configurable entrance/exit animations with custom easing
- **Flexible Positioning**: Top, bottom, left, and right banner positions
- **Gesture Support**: Swipe to dismiss with customizable directions (up, down, left, right, both)
- **TypeScript**: Full type safety out of the box
- **Custom Fonts**: Apply custom font families to all text elements
- **Safe Area Aware**: Automatic handling of notches and status bars
- **Persistent Modals**: Option to prevent modal dismissal
- **Focus Mode**: Dim background with optional backdrop press handling
- **Close Icons**: Configurable close buttons on banner notifications
- **Custom Slide Directions**: Control banner entrance animations independently

## Installation

```bash
npm install @seybar/react-native-notifier
```

### Peer Dependencies

```bash
npm install react react-native @expo/vector-icons
```

## Quick Start

### 1. Setup NotificationContainer

Add the `NotificationContainer` to your root component (e.g., `App.tsx`):

```tsx
import React from 'react';
import { SafeAreaView } from 'react-native';
import Notifier from '@seybar/react-native-notifier';

export default function App() {
  return (
    <SafeAreaView style={{ flex: 1 }}>
      {/* Your app content */}
      
      {/* Add this at the root level */}
      <Notifier.Container />
    </SafeAreaView>
  );
}
```

### 2. Show Notifications

#### Banner Notifications

```tsx
import Notifier from '@seybar/react-native-notifier';

// Simple banner
Notifier.showNotificationBanner({
  title: "Success!",
  description: "Your changes have been saved.",
  duration: 3000,
});

// With icon and close button
Notifier.showNotificationBanner({
  title: "New Message",
  description: "You have a new message from John",
  icon: {
    library: "Ionicons",
    name: "mail",
    size: 24,
  },
  closeIcon: true, // Show default close button
  position: "top",
  duration: 4000,
});
```

#### Modal Notifications

```tsx
import React, { useState } from 'react';
import Notifier from '@seybar/react-native-notifier';

function MyComponent() {
  const [showModal, setShowModal] = useState(false);

  return (
    <>
      <Button title="Show Modal" onPress={() => setShowModal(true)} />
      
      <Notifier
        visible={showModal}
        onClose={() => setShowModal(false)}
        title="Success"
        message="Operation completed successfully!"
        icon="check-circle"
        primaryButton={{
          title: "OK",
          onPress: () => setShowModal(false),
        }}
      />
    </>
  );
}
```

## API Reference

### Banner Notifications

#### `Notifier.showNotificationBanner(config)`

Shows a banner notification.

**Parameters:**

```typescript
interface NotificationBannerConfig {
  // Required
  title: string;
  
  // Content
  description?: string;
  
  // Display Duration
  duration?: number; // Auto-hide duration in ms (0 = no auto-hide, default: 3000)
  
  // Positioning
  position?: 'top' | 'bottom' | 'left' | 'right'; // Default: 'top'
  slideDirection?: 'up' | 'down' | 'left' | 'right'; // Custom entrance animation
  
  // Icon Configuration
  icon?: IconConfig | string; // String uses default MaterialIcons
  closeIcon?: boolean | IconConfig; // Show close button (false | true | custom config)
  
  // Colors (supports theme-aware colors)
  backgroundColor?: ColorValue;
  borderColor?: ColorValue;
  titleColor?: ColorValue;
  descriptionColor?: ColorValue;
  
  // Font Families
  fontFamily?: {
    titleFontFamily?: string;
    messageFontFamily?: string;
    bannerTitleFontFamily?: string; // Specific to banner title
    bannerDescriptionFontFamily?: string; // Specific to banner description
  };
  
  // Gestures
  swipeDirection?: 'up' | 'down' | 'left' | 'right' | 'both' | 'none'; // Default: 'up'
  hideOnPress?: boolean; // Default: true
  
  // Focus Mode
  focus?: boolean | FocusConfig; // Dim background and focus on notification
  
  // Animations
  showAnimationDuration?: number; // Default: 300ms
  hideAnimationDuration?: number; // Default: 250ms
  showEasing?: (value: number) => number; // Custom easing function
  hideEasing?: (value: number) => number; // Custom easing function
  
  // Callbacks
  onPress?: () => void;
  onHidden?: () => void;
  
  // Theme
  theme?: 'light' | 'dark' | 'auto'; // Default: 'auto'
}

// Focus Configuration
interface FocusConfig {
  backgroundColor?: string; // Backdrop color (default: "rgba(0, 0, 0, 0.5)")
  hideOnBackdropPress?: boolean; // Hide on backdrop press (default: true)
}
```

**Returns:** `string` - Notification ID for manual dismissal

**Examples:**

##### Basic Notification with Close Button

```tsx
Notifier.showNotificationBanner({
  title: "Upload Complete",
  description: "Your file has been uploaded successfully.",
  position: "bottom",
  duration: 5000,
  closeIcon: true, // Show default close button
  icon: {
    library: "MaterialIcons",
    name: "cloud-upload",
    size: 28,
    color: "#4CAF50",
  },
  backgroundColor: { light: "#E8F5E9", dark: "#1B5E20" },
});
```

##### Custom Close Icon

```tsx
Notifier.showNotificationBanner({
  title: "New Update Available",
  description: "Version 2.0 is ready to install.",
  closeIcon: {
    library: "Ionicons",
    name: "close-circle",
    size: 24,
    color: "#FF5252",
  },
  onPress: () => console.log("Notification tapped"),
});
```

##### Focus Mode Notification

```tsx
Notifier.showNotificationBanner({
  title: "Important Notice",
  description: "Please read this carefully before proceeding.",
  duration: 0, // Stays until manually dismissed
  focus: {
    backgroundColor: "rgba(0, 0, 0, 0.7)", // Darker backdrop
    hideOnBackdropPress: true, // Can dismiss by tapping backdrop
  },
  closeIcon: true,
  icon: {
    library: "MaterialIcons",
    name: "warning",
    size: 32,
    color: "#FF9800",
  },
});
```

##### Custom Slide Direction

```tsx
Notifier.showNotificationBanner({
  title: "Slide from Right",
  description: "This notification slides in from the right side.",
  position: "top",
  slideDirection: "right", // Slides in from right regardless of position
  swipeDirection: "right", // Swipe right to dismiss
  duration: 4000,
});
```

##### Multi-directional Swipe

```tsx
Notifier.showNotificationBanner({
  title: "Flexible Dismiss",
  description: "Swipe in any direction to dismiss this notification.",
  swipeDirection: "both", // Allow swipe in any direction
  duration: 5000,
});
```

#### `Notifier.hideNotification(id)`

Manually hide a specific notification.

```tsx
const id = Notifier.showNotificationBanner({ 
  title: "Test",
  duration: 0 // Won't auto-hide
});

// Hide after 2 seconds
setTimeout(() => Notifier.hideNotification(id), 2000);
```

#### `Notifier.hideAllNotifications()`

Hide all active banner notifications.

```tsx
Notifier.hideAllNotifications();
```

### Modal Notifications

#### `<Notifier />`

Component props:

```typescript
interface NotifierProps {
  // Required
  visible: boolean;
  onClose: () => void;
  
  // Content
  title?: string;
  message?: string;
  
  // Icon Configuration
  icon?: IconConfig | string;
  iconColor?: ColorValue;
  iconBackGroundColor?: ColorValue;
  
  // Buttons
  primaryButton?: {
    title: string;
    onPress: () => void;
    primaryButtonColor?: ColorValue;
    primaryButtonText?: ColorValue;
  };
  secondaryButton?: {
    title: string;
    onPress: () => void;
    secondaryButtonColor?: ColorValue;
    secondaryButtonText?: ColorValue;
  };
  
  // Font Families
  fontFamily?: {
    titleFontFamily?: string;
    messageFontFamily?: string;
    buttonFontFamily?: string;
  };
  
  // Appearance
  backdropColor?: ColorValue;
  theme?: 'light' | 'dark' | 'auto'; // Default: 'auto'
  
  // Behavior
  persist?: boolean; // Prevent dismissal on backdrop press (default: false)
  
  // Animation
  animationDuration?: number; // Default: 300ms
}
```

**Examples:**

##### Basic Modal

```tsx
<Notifier
  visible={showModal}
  onClose={() => setShowModal(false)}
  title="Success"
  message="Your operation completed successfully!"
  icon="check-circle"
  primaryButton={{
    title: "OK",
    onPress: () => setShowModal(false),
  }}
/>
```

##### Persistent Modal (Cannot Dismiss)

```tsx
<Notifier
  visible={showModal}
  onClose={() => setShowModal(false)}
  title="Processing"
  message="Please wait while we process your request..."
  persist={true} // Cannot dismiss by tapping backdrop or back button
  icon={{
    library: "MaterialCommunityIcons",
    name: "loading",
    size: 48,
  }}
/>
```

##### Confirmation Dialog

```tsx
<Notifier
  visible={showConfirm}
  onClose={() => setShowConfirm(false)}
  title="Delete Account"
  message="This action cannot be undone. All your data will be permanently deleted."
  icon={{
    library: "MaterialIcons",
    name: "warning",
    size: 56,
    color: "#FF5252",
    backgroundColor: { light: "#FFEBEE", dark: "#B71C1C" },
    backgroundRadius: 32,
    backgroundPadding: 12,
  }}
  fontFamily={{
    titleFontFamily: "System-Bold",
    messageFontFamily: "System-Regular",
    buttonFontFamily: "System-Medium",
  }}
  primaryButton={{
    title: "Delete",
    onPress: handleDelete,
    primaryButtonColor: "#FF5252",
    primaryButtonText: "#FFFFFF",
  }}
  secondaryButton={{
    title: "Cancel",
    onPress: () => setShowConfirm(false),
  }}
  theme="auto"
/>
```

## Advanced Configuration

### Icon Configuration

#### Simple Icon (String)

```tsx
icon: "check-circle" // Uses MaterialIcons by default
```

#### Full Icon Config

```tsx
icon: {
  library: "Ionicons", // See supported libraries below
  name: "checkmark-circle",
  size: 48,
  color: "#4CAF50",
  backgroundColor: { light: "#E8F5E9", dark: "#1B5E20" },
  backgroundRadius: 28,
  backgroundPadding: 10,
}
```

#### Supported Icon Libraries

- MaterialIcons (default)
- Ionicons
- Feather
- AntDesign
- FontAwesome
- FontAwesome5
- Entypo
- MaterialCommunityIcons
- SimpleLineIcons
- Octicons
- Foundation
- EvilIcons

### Close Icon Configuration

The banner notification's close button can be customized:

```tsx
// Hide close button (default)
closeIcon: false

// Show default close button
closeIcon: true

// Custom close icon
closeIcon: {
  library: "Ionicons",
  name: "close-circle-outline",
  size: 22,
  color: "#666666",
}
```

### Theme-Aware Colors

Colors can be strings or theme-aware objects:

```tsx
// Simple color
backgroundColor: "#FFFFFF"

// Theme-aware color
backgroundColor: {
  light: "#FFFFFF",
  dark: "#1E1E1E"
}
```

### Custom Fonts

Apply custom fonts to different text elements:

```tsx
// Modal
<Notifier
  fontFamily={{
    titleFontFamily: "MyCustomFont-Bold",
    messageFontFamily: "MyCustomFont-Regular",
    buttonFontFamily: "MyCustomFont-Medium",
  }}
/>

// Banner
Notifier.showNotificationBanner({
  fontFamily: {
    bannerTitleFontFamily: "MyCustomFont-Bold",
    bannerDescriptionFontFamily: "MyCustomFont-Regular",
  }
});
```

### Banner Positions

```tsx
// Top (default) - appears at the top of the screen
position: "top"

// Bottom - good for actions above tab bars
position: "bottom"

// Left - vertical notification on the left side
position: "left"

// Right - vertical notification on the right side
position: "right"
```

### Slide Directions

Control the entrance animation independently from position:

```tsx
// Slide down from top (default for top position)
slideDirection: "down"

// Slide up from bottom (default for bottom position)
slideDirection: "up"

// Slide in from left (default for left position)
slideDirection: "left"

// Slide in from right (default for right position)
slideDirection: "right"
```

### Swipe Gestures

```tsx
swipeDirection: "up"      // Swipe up to dismiss (default)
swipeDirection: "down"    // Swipe down to dismiss
swipeDirection: "left"    // Swipe left to dismiss
swipeDirection: "right"   // Swipe right to dismiss
swipeDirection: "both"    // Swipe any direction (horizontal or vertical)
swipeDirection: "none"    // Disable swipe
```

### Focus Mode

Highlight a notification by dimming the background:

```tsx
// Simple focus (default backdrop)
focus: true

// Custom focus configuration
focus: {
  backgroundColor: "rgba(0, 0, 0, 0.8)", // Custom backdrop color
  hideOnBackdropPress: false, // Prevent backdrop dismissal
}
```

### Custom Animations

```tsx
import { Easing } from 'react-native';

Notifier.showNotificationBanner({
  title: "Custom Animation",
  showAnimationDuration: 500,
  hideAnimationDuration: 400,
  showEasing: Easing.elastic(1.5),
  hideEasing: Easing.bezier(0.25, 0.1, 0.25, 1),
});
```

## Complete Examples

### Success Notification with Close Button

```tsx
Notifier.showNotificationBanner({
  title: "Payment Successful",
  description: "Your payment of $99.99 has been processed.",
  duration: 4000,
  position: "top",
  closeIcon: true,
  icon: {
    library: "Ionicons",
    name: "checkmark-circle",
    size: 28,
    color: "#4CAF50",
  },
  backgroundColor: { light: "#E8F5E9", dark: "#1B5E20" },
  swipeDirection: "up",
});
```

### Error Notification with Focus

```tsx
Notifier.showNotificationBanner({
  title: "Connection Failed",
  description: "Unable to connect to the server. Please try again.",
  duration: 0, // Manual dismissal only
  position: "top",
  focus: {
    backgroundColor: "rgba(0, 0, 0, 0.6)",
    hideOnBackdropPress: true,
  },
  closeIcon: true,
  icon: {
    library: "MaterialIcons",
    name: "error",
    size: 28,
    color: "#F44336",
  },
  backgroundColor: { light: "#FFEBEE", dark: "#B71C1C" },
  onPress: () => {
    // Retry logic
    retryConnection();
  },
});
```

### Side Notification with Custom Swipe

```tsx
Notifier.showNotificationBanner({
  title: "New Feature",
  description: "Check out our latest update!",
  position: "right",
  slideDirection: "right",
  swipeDirection: "right",
  duration: 5000,
  closeIcon: {
    library: "Ionicons",
    name: "close",
    size: 20,
    color: "#666",
  },
  icon: {
    library: "MaterialCommunityIcons",
    name: "new-box",
    size: 24,
    color: "#2196F3",
  },
});
```

### Persistent Loading Modal

```tsx
const [loading, setLoading] = useState(false);

<Notifier
  visible={loading}
  onClose={() => setLoading(false)}
  title="Processing"
  message="Please wait while we process your request..."
  persist={true} // Cannot be dismissed
  icon={{
    library: "MaterialCommunityIcons",
    name: "cloud-sync",
    size: 48,
    color: "#2196F3",
    backgroundColor: { light: "#E3F2FD", dark: "#0D47A1" },
    backgroundRadius: 28,
    backgroundPadding: 10,
  }}
  animationDuration={400}
/>
```

### Confirmation with Focus

```tsx
<Notifier
  visible={showConfirm}
  onClose={() => setShowConfirm(false)}
  title="Logout"
  message="Are you sure you want to logout?"
  icon={{
    library: "MaterialIcons",
    name: "logout",
    size: 48,
    color: "#FF9800",
    backgroundColor: { light: "#FFF3E0", dark: "#E65100" },
    backgroundRadius: 28,
    backgroundPadding: 10,
  }}
  backdropColor={{ light: "rgba(0, 0, 0, 0.5)", dark: "rgba(0, 0, 0, 0.7)" }}
  primaryButton={{
    title: "Logout",
    onPress: handleLogout,
    primaryButtonColor: "#FF9800",
  }}
  secondaryButton={{
    title: "Cancel",
    onPress: () => setShowConfirm(false),
  }}
/>
```

## TypeScript Support

The library is fully typed. Import types as needed:

```typescript
import Notifier, { 
  NotificationBannerConfig, 
  NotificationWithId,
  NotifierProps,
  IconConfig,
  ColorValue,
  FocusConfig,
  FontFamilyConfig,
} from '@seybar/react-native-notifier';
```

## Best Practices

1. **Use Focus Mode for Important Notifications**: When you need user attention, enable focus mode to dim the background.

2. **Provide Close Options**: For persistent notifications (duration: 0), always include a close icon or button.

3. **Match Swipe to Position**: For intuitive UX, align swipe direction with position (e.g., swipe up for top notifications).

4. **Use Theme-Aware Colors**: Define both light and dark color variants for better user experience.

5. **Test Animations**: Custom easing functions can greatly enhance perceived performance.

6. **Persistent Modals for Critical Actions**: Use `persist: true` only for actions that require completion.

## Platform Compatibility

- iOS
- Android
- Expo
- React Native CLI

## Performance Tips

- Banner notifications automatically clean up after dismissal
- Use `duration: 0` for notifications that should stay until explicitly dismissed
- Focus mode backdrop animations are optimized with native drivers
- Icon pulsing animations in modals use efficient Animated API

## License

MIT

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Support

For issues and feature requests, please use the [GitHub issue tracker](https://github.com/mayotomiwa/react-native-notifier/issues).