npm package: @felix-health/capacitor-native-ui
Description: Native UI components for Capacitor
Author: Charm Team
Latest version: 0.1.1

# @felix-health/capacitor-native-ui

Native UI components for Capacitor applications.

## Components

### NativeTabBar

Native iOS tab bar with liquid glass effect (iOS 26+). The tab bar automatically hides when the keyboard appears and shows again when the keyboard dismisses.

## Installation

```bash
npm install @felix-health/capacitor-native-ui
npx cap sync
```

## Usage

### Check Availability

The native tab bar is only available on iOS 26+. Always check availability before using:

```typescript
import { NativeTabBar } from '@felix-health/capacitor-native-ui'

const { available } = await NativeTabBar.isAvailable()
if (available) {
  // Safe to use native tab bar
}
```

### Basic Usage

```typescript
import { NativeTabBar } from '@felix-health/capacitor-native-ui'

// Configure the tab bar (required before showing)
await NativeTabBar.configure({
  items: [
    {
      title: 'Home',
      tag: 0,
      icon: 'assets://HomeIcon',
      activeIcon: 'assets://HomeIconFilled',
    },
    {
      title: 'Profile',
      tag: 1,
      icon: 'assets://ProfileIcon',
      activeIcon: 'assets://ProfileIconFilled',
    },
  ],
  appearance: {
    selectedColor: '#31302F',
    unselectedColor: '#5F5E5A',
    fontFamily: 'Matter-Regular',
    selectedFontFamily: 'Matter-Medium',
    fontSize: 12,
  },
})

// Show the tab bar
await NativeTabBar.show()

// Hide the tab bar
await NativeTabBar.hide()

// Set active tab programmatically
await NativeTabBar.setActiveTab({ index: 0 })

// Listen to tab selection
await NativeTabBar.addListener('tabSelected', (info) => {
  console.log('Tab selected:', info.index)
})
```

### Appearance Configuration

The `appearance` object is **required** and controls the visual styling:

| Property | Type | Description |
|----------|------|-------------|
| `selectedColor` | string | Hex color for selected tab items (e.g., `"#31302F"`) |
| `unselectedColor` | string | Hex color for unselected tab items (e.g., `"#5F5E5A"`) |
| `fontFamily` | string | Font family name for unselected items (e.g., `"Matter-Regular"`) |
| `selectedFontFamily` | string | Font family name for selected items (e.g., `"Matter-Medium"`) |
| `fontSize` | number | Font size in points (e.g., `12`) |

### Icon Format Options

The plugin supports two icon formats:

1. **Asset Catalog** (Recommended for custom icons)
   - Reference PNG images from your iOS Asset Catalog
   - Format: `assets://<asset-name>`
   - Add image sets to `ios/App/App/Assets.xcassets/` in Xcode
   - Supports @2x and @3x resolution variants automatically

2. **SF Symbols** (For system icons)
   - Use built-in iOS SF Symbol names
   - Example: `house`, `person.circle`, `cart.fill`, etc.
   - Browse all symbols: https://developer.apple.com/sf-symbols/

### Adding Custom Icons to Asset Catalog

1. Open your iOS project in Xcode: `ios/App/App.xcworkspace`
2. Navigate to `Assets.xcassets` in the project navigator
3. Right-click and select "New Image Set"
4. Name the image set (e.g., `HomeIcon`)
5. Drag your PNG files into the appropriate slots (@1x, @2x, @3x)
6. Reference in code using `assets://HomeIcon`

**Example structure:**
```
ios/App/App/Assets.xcassets/
├── HomeIcon.imageset/
│   ├── Contents.json
│   ├── HomeIcon@2x.png
│   └── HomeIcon@3x.png
└── HomeIconFilled.imageset/
    ├── Contents.json
    ├── HomeIconFilled@2x.png
    └── HomeIconFilled@3x.png
```

### Adding Custom Fonts

To use custom fonts, you must add them to your iOS project:

1. Add font files (`.ttf` or `.otf`) to `ios/App/App/Fonts/`
2. Register fonts in `ios/App/App/Info.plist`:
   ```xml
   <key>UIAppFonts</key>
   <array>
     <string>Matter-Regular.otf</string>
     <string>Matter-Medium.otf</string>
   </array>
   ```
3. Reference in code using the font's PostScript name (e.g., `"Matter-Regular"`)

## Keyboard Behavior

The tab bar automatically responds to keyboard events:
- **Keyboard shows**: Tab bar animates out (hidden)
- **Keyboard hides**: Tab bar animates back in (visible)

This ensures the tab bar doesn't overlap with the keyboard during text input.

## API

### Methods

#### `isAvailable(): Promise<{ available: boolean }>`

Check if the native tab bar is available on this platform/version.

**Returns:**
- `available`: `true` only on iOS 26+, `false` otherwise

#### `configure(config: TabBarConfig): Promise<void>`

Configure the tab bar with custom items and appearance. **Must be called before `show()`.**

**Parameters:**
- `config.items`: Array of tab item configurations
  - `title` (string): The tab title
  - `tag` (number): Unique identifier for the tab
  - `icon` (string): Icon as SF Symbol name or asset path (`assets://IconName`)
  - `activeIcon` (string, optional): Icon to display when tab is selected
- `config.appearance`: Required appearance configuration (see above)

#### `show(): Promise<void>`

Show the native tab bar with animation.

#### `hide(): Promise<void>`

Hide the native tab bar with animation.

#### `setActiveTab(options: { index: number }): Promise<void>`

Set the active tab programmatically.

**Parameters:**
- `options.index`: Zero-based index of the tab to activate

#### `addListener(eventName: 'tabSelected', callback): Promise<PluginListenerHandle>`

Listen for tab selection events.

#### `removeAllListeners(): Promise<void>`

Remove all event listeners.

### Events

#### `tabSelected`

Emitted when a tab is selected by the user.

**Event Data:**
- `index` (number): Zero-based index of the selected tab

## Platform Support

| Platform | Support | Notes |
|----------|---------|-------|
| iOS 26+ | ✅ Full | Liquid glass effect with custom appearance |
| iOS < 26 | ⚠️ No-op | Methods resolve but do nothing |
| Android | ⚠️ Stub | Not implemented |
| Web | ⚠️ Stub | Not implemented |

Use `isAvailable()` to check support at runtime and fall back to a web-based tab bar on unsupported platforms.

## License

MIT