npm package: @moraby/app-launcher
Description: A Google-style app launcher component for React/Next.js applications
Author: Morteza Araby
Latest version: 2.0.17

# @moraby/app-launcher

A Google-style app launcher component for React/Next.js applications.

## Installation

```bash
npm install @moraby/app-launcher
# or
yarn add @moraby/app-launcher
```

## Usage

### React / Next.js

Import and use the component as usual:

```tsx
import { AppLauncher } from '@moraby/app-launcher';
import '@moraby/app-launcher/styles.css';

function MyApp() {
  return <AppLauncher configUrl="/apps.json" />;
}
```

### HTML / Vanilla JavaScript (Web Component)

You can use the bundled Web Component version which includes all dependencies (React/ReactDOM).

**Option 1: Using via CDN (No Build Step)**

```html
<!-- Load the script (includes React + AppLauncher) -->
<script src="https://unpkg.com/@moraby/app-launcher/dist/app-launcher-element.global.js"></script>
<!-- Load styles -->
<link rel="stylesheet" href="https://unpkg.com/@moraby/app-launcher/dist/index.css" />

<!-- Use the component -->
<app-launcher
  default-apps='[{"id":"1","name":"Dashboard","url":"/","icon":"MdDashboard","color":"#4285F4"}]'
  class-name="my-launcher"
></app-launcher>

<script>
  // You can also interact with it via JS
  const launcher = document.querySelector('app-launcher');
</script>
```

**Option 2: From NPM**

```html
<script src="./node_modules/@moraby/app-launcher/dist/app-launcher-element.global.js"></script>
<link rel="stylesheet" href="./node_modules/@moraby/app-launcher/dist/index.css" />
```

#### Attributes

- `default-apps`: JSON string defining the apps to show.
- `class-name`: Custom class name for the wrapper.

### Quick Start (Zero-Config)

Use the smart component that handles local storage and settings automatically:

```tsx
import { LocalAppLauncher } from '@moraby/app-launcher';
import '@moraby/app-launcher/styles.css';

function Header() {
  return (
    <header>
      <h1>My App</h1>
      <LocalAppLauncher />
    </header>
  );
}
```

This will automatically:

1. Show a Settings button in the footer
2. Save custom apps to browser's LocalStorage
3. Allow users to add/edit/delete apps immediately

### Custom Implementation (Advanced)

If you want full control over the state or to load from a remote URL:

### With Configuration URL

```tsx
import { AppLauncher } from '@moraby/app-launcher';
import '@moraby/app-launcher/styles.css';

function Header() {
  return (
    <header>
      <h1>My App</h1>
      <AppLauncher configUrl="https://example.com/apps.json" />
    </header>
  );
}
```

### With Direct Apps Array

```tsx
import { AppLauncher, AppItem } from '@moraby/app-launcher';
import '@moraby/app-launcher/styles.css';

const apps: AppItem[] = [
  {
    id: 'dashboard',
    name: 'Dashboard',
    url: '/dashboard',
    icon: 'MdDashboard',
    color: '#4285F4',
  },
  {
    id: 'settings',
    name: 'Settings',
    url: '/settings',
    icon: 'FaCog',
    color: '#5f6368',
  },
];

function Header() {
  return (
    <header>
      <AppLauncher apps={apps} />
    </header>
  );
}
```

### With Settings UI (Custom User Apps)

The `AppLauncher` can now intelligently handle custom user applications and automatically merge them with your default configuration. Simply add the `allowCustomApps` prop along with a `storageKey`:

```tsx
import { AppLauncher } from '@moraby/app-launcher';
import '@moraby/app-launcher/styles.css';

function Header() {
  return (
    <header>
      <AppLauncher
        configUrl="https://example.com/apps.json"
        storageKey="my-user-apps-storage-key"
        allowCustomApps={true}
      />
    </header>
  );
}
```

This setup will automatically:
1. Fetch default applications from `configUrl`.
2. Inject a "Settings" button in the App Launcher dropdown footer.
3. Show the built-in Settings modal allowing users to intuitively add, edit, export, and delete custom apps.
4. Merge default apps with user-defined apps intrinsically.
5. Persist the user's custom preferences safely in `localStorage` securely!

### Modal Rendering & CSS Isolation

The `AppSettings` modal renders using a **React Portal** directly attached to `document.body`. 

- **Placement & Clipping:** This prevents the modal from being clipped by host application styles such as `overflow: hidden` or complex `z-index` stacking contexts.
- **Client-Side Only:** In Next.js App Router, ensure the component (or its parent wrapper) is a Client Component (`'use client'`) since `document.body` is required.
- **CSS Isolation:** The launcher utilizes targeted CSS resets (`all: revert`, explicit `box-sizing`) to protect its buttons and SVG icons from host application global styles (e.g., global `button {}` or `svg {}` styles bleeding into the component).

## Configuration JSON Format

Export your configuration from the admin app and host it as a JSON file:

```json
{
  "version": "1.0",
  "exportedAt": "2024-01-15T10:00:00.000Z",
  "apps": [
    {
      "id": "my-app",
      "name": "My App",
      "url": "https://myapp.example.com",
      "icon": "FaRocket",
      "color": "#4285F4",
      "description": "My awesome app"
    }
  ]
}
```

## Props

| Prop               | Type                     | Description                                                        |
| ------------------ | ------------------------ | ------------------------------------------------------------------ |
| `configUrl`        | `string`                 | URL to fetch default configuration from (JSON or API)              |
| `apps`             | `AppItem[]`              | Direct array of default apps to display                            |
| `className`        | `string`                 | Custom class name for the container                                |
| `onAppClick`       | `(app: AppItem) => void` | Custom click handler                                               |
| `storageKey`       | `string`                 | Optional localStorage key to save custom apps alongside defaults   |
| `allowCustomApps`  | `boolean`                | If true, intrinsically shows the Settings UI to manage user apps   |
| `renderFooter`     | `() => ReactNode`        | Optional explicitly rendered footer inside the dropdown            |

## Icons

### Built-in Icons (react-icons)

Use the icon name as a string:

```json
{ "icon": "FaRocket" }
```

### Custom Icons (URLs)

You can also use your own icons from URLs or public folder:

```json
// From Next.js public folder
{ "icon": "/icons/my-icon.svg" }

// From external URL
{ "icon": "https://cdn.example.com/icon.png" }
```

**Example with custom icon:**

```json
{
  "id": "my-app",
  "name": "My App",
  "url": "https://myapp.com",
  "icon": "/motorcycle-icon.svg",
  "color": "transparent"
}
```

## Available Built-in Icons

The package includes 50+ icons from react-icons. Use any of these names:

**Business:** FaBriefcase, IoBusinessSharp, MdWork, FaGraduationCap

**Security:** MdOutlineSecurity, FaLock, FaKey, AiOutlineSecurityScan

**Communication:** FaEnvelope, MdEmail, FaBell

**Media:** FaYoutube, FaMusic, FaCamera, FaImage, FaGamepad

**Productivity:** FaCalendarAlt, FaClipboard, FaCalculator, FaFolder, FaFile, FaBookmark, FaTable, FaNewspaper

**Navigation:** FaMapMarkerAlt, FaGlobe, FaHome

**Development:** FaCode, FaTerminal, FaDatabase, FaPuzzlePiece

**Analytics:** FaChartBar, MdDashboard, MdAnalytics

**General:** FaRocket, FaUser, FaCog, FaHeart, FaStar, IoApps

## License

MIT