npm package: @naarni/design-system
Description: Naarni React Native Design System for EV Fleet Apps
Author: Naarni
Latest version: 0.0.21

# @naarni/design-system

A comprehensive React Native design system for EV Fleet applications, built with TypeScript and modern React Native patterns.

## 🚀 Features

- **TypeScript First**: Full TypeScript support with proper type definitions
- **Modern Components**: Built with React Native best practices
- **Customizable**: Easy to customize and extend
- **Performance Optimized**: Memoized components and optimized rendering
- **Accessibility**: Built-in accessibility support
- **Theme Support**: Flexible theming system
- **Chart Components**: Built-in LineChart and BarChart with Skia
- **Form Components**: InputBox with validation and grouping support

## 📦 Installation

```bash
npm install @naarni/design-system
# or
yarn add @naarni/design-system
```

## 🔧 Peer Dependencies

This package requires the following peer dependencies:

```json
{
  "react": ">=18.0.0",
  "react-native": ">=0.70.0",
  "react-native-vector-icons": ">=10.0.0",
  "react-native-safe-area-context": ">=4.0.0",
  "react-native-maps": ">=1.7.0"
}
```

**Note:** For Google Maps functionality, you'll need to:
1. Set up Google Maps API keys in your Android and iOS projects
2. Configure the necessary permissions for location services

## 🎨 Components

### Button

A versatile button component with multiple variants, sizes, and states.

```tsx
import { Button } from '@naarni/design-system';

// Basic usage
<Button variant="primary" onPress={() => console.log('Pressed!')}>
  Click Me
</Button>

// With different variants
<Button variant="secondary">Secondary</Button>
<Button variant="outline">Outline</Button>
<Button variant="text">Text Button</Button>
<Button variant="ghost">Ghost</Button>

// Different sizes
<Button variant="primary" size="small">Small</Button>
<Button variant="primary" size="medium">Medium</Button>
<Button variant="primary" size="large">Large</Button>

// States
<Button variant="primary" loading>Loading...</Button>
<Button variant="primary" disabled>Disabled</Button>
<Button variant="primary" loading loadingText="Processing...">
  Loading with Text
</Button>

// With icons
<Button 
  variant="primary" 
  icon={<Icon name="arrow-right" size={16} />} 
  iconPosition="right"
>
  Next
</Button>

// Full width
<Button variant="primary" fullWidth>Full Width Button</Button>
```

**Button Props:**
```tsx
interface ButtonProps {
  variant?: 'primary' | 'secondary' | 'outline' | 'text' | 'ghost';
  size?: 'small' | 'medium' | 'large';
  loading?: boolean;
  disabled?: boolean;
  fullWidth?: boolean;
  style?: ViewStyle;
  textStyle?: TextStyle;
  icon?: React.ReactNode;
  iconPosition?: 'left' | 'right';
  onPress?: () => void;
  onLongPress?: () => void;
  activeOpacity?: number;
  children: React.ReactNode;
  loadingText?: string;
  accessibilityLabel?: string;
  accessibilityHint?: string;
  testID?: string;
}
```

### Text

A flexible text component with predefined typography variants.

```tsx
import { Text } from '@naarni/design-system';

// Basic usage
<Text>Hello World</Text>

// Typography variants
<Text variant="h1">Heading 1</Text>
<Text variant="h2">Heading 2</Text>
<Text variant="h3">Heading 3</Text>
<Text variant="h4">Heading 4</Text>
<Text variant="h5">Heading 5</Text>
<Text variant="h6">Heading 6</Text>
<Text variant="body1">Body text</Text>
<Text variant="body2">Smaller body text</Text>
<Text variant="subtitle1">Subtitle 1</Text>
<Text variant="subtitle2">Subtitle 2</Text>
<Text variant="button">Button text</Text>
<Text variant="caption">Caption text</Text>
<Text variant="overline">Overline text</Text>
<Text variant="code">Code text</Text>

// Custom styling
<Text variant="h1" color="#007AFF" align="center" weight="bold">
  Custom Styled Text
</Text>

// Text truncation
<Text variant="body1" numberOfLines={2} ellipsizeMode="tail">
  This is a very long text that will be truncated after two lines...
</Text>
```

**Text Props:**
```tsx
interface TextProps {
  variant?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'body1' | 'body2' | 
           'subtitle1' | 'subtitle2' | 'button' | 'caption' | 'overline' | 'code';
  color?: string;
  align?: 'auto' | 'left' | 'right' | 'center' | 'justify';
  weight?: 'thin' | 'extralight' | 'light' | 'regular' | 'medium' | 
           'semibold' | 'bold' | 'extrabold' | 'black';
  style?: TextStyle;
  children: ReactNode;
  numberOfLines?: number;
  ellipsizeMode?: 'head' | 'middle' | 'tail' | 'clip';
  testID?: string;
}
```

### Card

A container component with optional title, subtitle, and animations.

```tsx
import { Card } from '@naarni/design-system';

// Basic card
<Card title="Card Title" subtitle="Card Subtitle">
  <Text variant="body1">Card content goes here</Text>
</Card>

// Card with image
<Card 
  title="Vehicle Info" 
  subtitle="Tesla Model 3"
  image={require('./assets/tesla.jpg')}
>
  <Text variant="body1">Electric vehicle details...</Text>
</Card>

// Animated cards
<Card 
  title="Animated Card" 
  animated 
  animationType="shine"
  loop={true}
>
  <Text variant="body1">This card has a shine animation</Text>
</Card>

// Custom styling
<Card 
  title="Custom Card" 
  backgroundColor="#f0f0f0"
  elevation={8}
  style={{ marginVertical: 16 }}
>
  <Text variant="body1">Custom styled card</Text>
</Card>
```

**Card Props:**
```tsx
interface CardProps {
  title?: string;
  subtitle?: string;
  image?: ImageSourcePropType;
  elevation?: number;
  style?: ViewStyle;
  children?: ReactNode;
  backgroundColor?: string;
  key?: string | number;
  animated?: boolean;
  animationType?: 'none' | 'shine' | 'sine-shine' | 'stars' | 'drops';
  loop?: boolean;
}
```

### Alert

A notification component for displaying messages to users.

```tsx
import { Alert } from '@naarni/design-system';

// Basic alert
<Alert 
  type="success" 
  title="Success!" 
  message="Operation completed successfully" 
/>

// Different alert types
<Alert type="info" title="Information" message="Here's some info" />
<Alert type="warning" title="Warning" message="Please be careful" />
<Alert type="error" title="Error" message="Something went wrong" />

// Dismissible alert
<Alert 
  type="info" 
  title="Dismissible" 
  message="You can close this alert"
  dismissible 
  onDismiss={() => console.log('Alert dismissed')}
/>

// Alert with actions
<Alert 
  type="warning" 
  title="Confirm Action" 
  message="Are you sure you want to proceed?"
  actions={[
    {
      label: 'Cancel',
      onPress: () => console.log('Cancelled'),
      variant: 'outline'
    },
    {
      label: 'Confirm',
      onPress: () => console.log('Confirmed'),
      variant: 'primary'
    }
  ]}
/>
```

**Alert Props:**
```tsx
interface AlertProps {
  variant?: 'info' | 'success' | 'warning' | 'error';
  title?: string;
  message: string;
  dismissible?: boolean;
  persistent?: boolean;
  onDismiss?: () => void;
  icon?: ReactNode;
  style?: ViewStyle;
  actions?: AlertAction[];
}

interface AlertAction {
  label: string;
  onPress: () => void;
  variant?: 'primary' | 'secondary' | 'outline' | 'text' | 'ghost';
}
```

### InputBox

A form input component with validation and icon support.

```tsx
import { InputBox, InputBoxGroup } from '@naarni/design-system';

// Basic input
<InputBox 
  placeholder="Enter your email"
  type="email"
  label="Email Address"
/>

// Input with validation
<InputBox 
  placeholder="Enter password"
  type="password"
  label="Password"
  error="Password must be at least 8 characters"
  leftIcon="lock"
/>

// Input with icons
<InputBox 
  placeholder="Search..."
  leftIcon="search"
  rightIcon="clear"
  onRightIconPress={() => console.log('Clear pressed')}
/>

// Different variants and sizes
<InputBox 
  variant="filled" 
  size="large" 
  placeholder="Large filled input"
/>

// Input group
<InputBoxGroup direction="horizontal" spacing={16}>
  <InputBox placeholder="First Name" />
  <InputBox placeholder="Last Name" />
</InputBoxGroup>

<InputBoxGroup direction="vertical" spacing={12}>
  <InputBox placeholder="Email" type="email" />
  <InputBox placeholder="Password" type="password" />
  <InputBox placeholder="Confirm Password" type="password" />
</InputBoxGroup>
```

**InputBox Props:**
```tsx
interface InputBoxProps extends Omit<TextInputProps, 'style'> {
  placeholder?: string;
  error?: string;
  type?: 'text' | 'email' | 'password' | 'phone' | 'number' | 'url';
  leftIcon?: string;
  rightIcon?: string;
  onRightIconPress?: () => void;
  disabled?: boolean;
  label?: string;
  helperText?: string;
  variant?: 'outlined' | 'filled';
  size?: 'small' | 'medium' | 'large';
  fullWidth?: boolean;
  style?: any;
  containerStyle?: any;
}

interface InputBoxGroupProps {
  children: React.ReactNode;
  direction?: 'horizontal' | 'vertical';
  spacing?: number;
  style?: any;
}
```

### Icon

A wrapper around react-native-vector-icons for consistent icon usage.

```tsx
import { Icon } from '@naarni/design-system';

// Basic icon
<Icon name="home" size={24} color="#007AFF" />

// Different sizes
<Icon name="star" size={16} />
<Icon name="star" size={24} />
<Icon name="star" size={32} />

// With custom colors
<Icon name="heart" size={24} color="#FF3B30" />
<Icon name="check" size={24} color="#34C759" />
```

**Icon Props:**
```tsx
interface IconProps {
  name: string;
  size?: number;
  color?: string;
  style?: any;
}
```

### Charts

Chart components built with React Native Skia for smooth animations.

#### LineChart

```tsx
import { LineChart } from '@naarni/design-system';

// Basic line chart
<LineChart 
  data={[10, 20, 15, 30, 25, 40, 35]}
  width={300}
  height={200}
/>

// With customization
<LineChart 
  data={[10, 20, 15, 30, 25, 40, 35]}
  width={300}
  height={200}
  color="#007AFF"
  showGrid={true}
  showXAxis={true}
  showYAxis={true}
  showTooltip={true}
  tooltipFormatter={(value, index) => `Point ${index}: ${value}`}
/>
```

#### BarChart

```tsx
import { BarChart } from '@naarni/design-system';

// Basic bar chart
<BarChart 
  data={[10, 20, 15, 30, 25, 40, 35]}
  width={300}
  height={200}
/>

// With customization
<BarChart 
  data={[10, 20, 15, 30, 25, 40, 35]}
  width={300}
  height={200}
  color="#34C759"
  showGrid={true}
  showXAxis={true}
  showYAxis={true}
  showTooltip={true}
  tooltipFormatter={(value, index) => `Bar ${index}: ${value}`}
/>
```

**Chart Props:**
```tsx
interface LineChartProps {
  data: number[];
  width: number;
  height: number;
  showXAxis?: boolean;
  showYAxis?: boolean;
  isLabelOnXaxis?: boolean;
  isLabelOnYaxis?: boolean;
  color?: string;
  showGrid?: boolean;
  showTooltip?: boolean;
  tooltipFormatter?: (value: number, index: number) => string;
}

interface BarChartProps {
  data: number[];
  width: number;
  height: number;
  showXAxis?: boolean;
  showYAxis?: boolean;
  isLabelOnXaxis?: boolean;
  isLabelOnYaxis?: boolean;
  color?: string;
  showGrid?: boolean;
  showTooltip?: boolean;
  tooltipFormatter?: (value: number, index: number) => string;
}
```

### BottomSheet

A modal component that slides up from the bottom.

```tsx
import { BottomSheet } from '@naarni/design-system';

// Basic bottom sheet
<BottomSheet 
  visible={isVisible} 
  onClose={() => setIsVisible(false)}
  title="Bottom Sheet"
>
  <Text variant="body1">Bottom sheet content goes here</Text>
</BottomSheet>

// With confirmation
<BottomSheet 
  visible={isVisible} 
  onClose={() => setIsVisible(false)}
  onConfirm={() => {
    console.log('Confirmed');
    setIsVisible(false);
  }}
  title="Confirm Action"
  confirmText="Confirm"
  cancelText="Cancel"
>
  <Text variant="body1">Are you sure you want to proceed?</Text>
</BottomSheet>

// Custom snap points
<BottomSheet 
  visible={isVisible} 
  onClose={() => setIsVisible(false)}
  snapPoints={[300, 500]}
  initialSnapPoint={300}
  showDragIndicator={true}
>
  <Text variant="body1">Custom height bottom sheet</Text>
</BottomSheet>
```

**BottomSheet Props:**
```tsx
interface BottomSheetProps {
  visible: boolean;
  title?: string;
  children: ReactNode;
  onClose: () => void;
  onConfirm?: () => void;
  showDragIndicator?: boolean;
  initialSnapPoint?: number;
  snapPoints?: number[];
  style?: ViewStyle;
  contentStyle?: ViewStyle;
  enablePanDownToClose?: boolean;
  confirmText?: string;
  cancelText?: string;
}
```

### Map

A comprehensive map component for vehicle tracking using Google Maps.

```tsx
import { Map, EnhancedMap, Vehicle } from '@naarni/design-system';

// Basic map with vehicles
const vehicles: Vehicle[] = [
  {
    id: '1',
    name: 'Tesla Model 3',
    latitude: 37.78825,
    longitude: -122.4324,
    speed: 65,
    battery: 85,
    status: 'active'
  }
];

<Map
  vehicles={vehicles}
  mapStyle="dark"
  onVehiclePress={(vehicle) => console.log(vehicle)}
/>

// Enhanced map with controls and vehicle info
<EnhancedMap
  vehicles={vehicles}
  mapStyle="blackAndWhite"
  showControls={true}
  showVehicleInfo={true}
  onVehicleSelect={(vehicle) => setSelectedVehicle(vehicle)}
/>

// Custom map styling
<Map
  vehicles={vehicles}
  customMapStyle={[
    {
      elementType: 'geometry',
      stylers: [{ color: '#212121' }]
    },
    {
      elementType: 'labels.text.fill',
      stylers: [{ color: '#757575' }]
    }
  ]}
/>
```

**Map Props:**
```tsx
interface MapProps {
  vehicles?: Vehicle[];
  initialRegion?: Region;
  style?: ViewStyle;
  mapStyle?: 'default' | 'dark' | 'light' | 'blackAndWhite';
  customMapStyle?: MapStyleConfig[];
  showVehicleInfo?: boolean;
  autoFitToVehicles?: boolean;
  onVehiclePress?: (vehicle: Vehicle) => void;
  onMapPress?: (event: any) => void;
  onRegionChange?: (region: Region) => void;
  zoomEnabled?: boolean;
  scrollEnabled?: boolean;
  rotateEnabled?: boolean;
  pitchEnabled?: boolean;
  showsUserLocation?: boolean;
  showsMyLocationButton?: boolean;
  showsCompass?: boolean;
  showsScale?: boolean;
  loadingEnabled?: boolean;
  loadingIndicatorColor?: string;
  loadingBackgroundColor?: string;
  testID?: string;
}
```

interface Vehicle {
  id?: string;
  name?: string;
  description?: string;
  latitude: number;
  longitude: number;
  heading?: number;
  color?: string;
  speed?: number;
  battery?: number;
  status?: 'active' | 'inactive' | 'charging' | 'maintenance';
  lastUpdate?: Date;
}
```

**EnhancedMap Props:**
```tsx
interface EnhancedMapProps extends MapProps {
  showControls?: boolean;
  showVehicleInfo?: boolean;
  selectedVehicle?: Vehicle | null;
  onVehicleSelect?: (vehicle: Vehicle | null) => void;
}
```

## 🎯 Complete Usage Examples

### Basic App Setup

```tsx
import React from 'react';
import { View, StyleSheet } from 'react-native';
import { 
  Button, 
  Text, 
  Card, 
  Alert, 
  InputBox, 
  InputBoxGroup 
} from '@naarni/design-system';

const App = () => {
  const [showAlert, setShowAlert] = React.useState(false);
  const [email, setEmail] = React.useState('');
  const [password, setPassword] = React.useState('');

  return (
    <View style={styles.container}>
      <Text variant="h1" style={styles.title}>
        Welcome to Naarni
      </Text>
      
      <Card title="Login Form" style={styles.card}>
        <InputBoxGroup direction="vertical" spacing={16}>
          <InputBox 
            placeholder="Enter your email"
            type="email"
            label="Email Address"
            value={email}
            onChangeText={setEmail}
          />
          <InputBox 
            placeholder="Enter your password"
            type="password"
            label="Password"
            value={password}
            onChangeText={setPassword}
          />
        </InputBoxGroup>
        
        <Button 
          variant="primary" 
          fullWidth 
          style={styles.button}
          onPress={() => setShowAlert(true)}
        >
          Login
        </Button>
      </Card>
      
      {showAlert && (
        <Alert 
          type="success" 
          title="Success!" 
          message="Login successful"
          dismissible
          onDismiss={() => setShowAlert(false)}
        />
      )}
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
    backgroundColor: '#f5f5f5',
  },
  title: {
    textAlign: 'center',
    marginVertical: 32,
  },
  card: {
    marginVertical: 16,
  },
  button: {
    marginTop: 24,
  },
});

export default App;
```

### Dashboard Example

```tsx
import React from 'react';
import { View, ScrollView, StyleSheet } from 'react-native';
import { 
  Text, 
  Card, 
  Button, 
  LineChart, 
  BarChart, 
  Icon,
  Map,
  Vehicle
} from '@naarni/design-system';

const Dashboard = () => {
  const chartData = [10, 20, 15, 30, 25, 40, 35];
  
  const vehicles: Vehicle[] = [
    {
      id: '1',
      name: 'Tesla Model 3',
      latitude: 37.78825,
      longitude: -122.4324,
      speed: 65,
      battery: 85,
      status: 'active'
    },
    {
      id: '2',
      name: 'Nissan Leaf',
      latitude: 37.78925,
      longitude: -122.4314,
      speed: 45,
      battery: 72,
      status: 'active'
    }
  ];

  return (
    <ScrollView style={styles.container}>
      <Text variant="h1" style={styles.title}>
        Fleet Dashboard
      </Text>
      
      {/* Stats Cards */}
      <View style={styles.statsRow}>
        <Card style={styles.statCard}>
          <Text variant="h3" color="#007AFF">24</Text>
          <Text variant="body2" color="#666">Active Vehicles</Text>
        </Card>
        <Card style={styles.statCard}>
          <Text variant="h3" color="#34C759">98%</Text>
          <Text variant="body2" color="#666">Uptime</Text>
        </Card>
      </View>
      
      {/* Vehicle Map */}
      <Card title="Live Vehicle Locations" style={styles.mapCard}>
        <Map
          vehicles={vehicles}
          mapStyle="dark"
          style={styles.map}
          onVehiclePress={(vehicle) => console.log('Vehicle pressed:', vehicle)}
        />
      </Card>
      
      {/* Charts */}
      <Card title="Weekly Performance" style={styles.chartCard}>
        <LineChart 
          data={chartData}
          width={300}
          height={200}
          color="#007AFF"
          showGrid={true}
          showTooltip={true}
        />
      </Card>
      
      <Card title="Monthly Usage" style={styles.chartCard}>
        <BarChart 
          data={chartData}
          width={300}
          height={200}
          color="#34C759"
          showGrid={true}
          showTooltip={true}
        />
      </Card>
      
      {/* Actions */}
      <View style={styles.actions}>
        <Button variant="primary" icon={<Icon name="plus" size={16} />}>
          Add Vehicle
        </Button>
        <Button variant="outline" icon={<Icon name="settings" size={16} />}>
          Settings
        </Button>
      </View>
    </ScrollView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
    backgroundColor: '#f5f5f5',
  },
  title: {
    marginBottom: 24,
  },
  statsRow: {
    flexDirection: 'row',
    gap: 16,
    marginBottom: 24,
  },
  statCard: {
    flex: 1,
    alignItems: 'center',
    padding: 16,
  },
  mapCard: {
    height: 300,
    marginBottom: 24,
  },
  map: {
    flex: 1,
    borderRadius: 8,
  },
  chartCard: {
    marginBottom: 24,
  },
  actions: {
    gap: 12,
    marginBottom: 24,
  },
});

export default Dashboard;
```

## 🔧 Development

### Building
```bash
npm run build
```

### Testing Package
```bash
npm run pack
npm run test:pack
```

### Publishing
```bash
# Patch version (1.0.0 -> 1.0.1)
npm run publish:patch

# Minor version (1.0.0 -> 1.1.0)
npm run publish:minor

# Major version (1.0.0 -> 2.0.0)
npm run publish:major
```

## 📚 Typography System

The design system includes a comprehensive typography system with predefined text styles:

- **Headings**: `h1`, `h2`, `h3`, `h4`, `h5`, `h6`
- **Body Text**: `body1`, `body2`
- **Subtitles**: `subtitle1`, `subtitle2`
- **Special**: `button`, `caption`, `overline`, `code`

Each variant has optimized font sizes, weights, and spacing for different use cases.

## 🎨 Theme Support

The design system supports theming through the typography system and individual component styling. You can customize colors, spacing, and other design tokens by extending the theme files.

## 🤝 Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request

## 📄 License

MIT License - see LICENSE file for details

## 🆘 Support

For support and questions:
- Create an issue on GitHub
- Check the examples in the `src/Examples` directory
- Review the component interfaces for detailed prop information