npm package: @kashybee/ui-widget
Description: Beautiful UI widget for Kashybee voucher payments - React, Vue, and Vanilla JS
Author: Kashybee
Latest version: 1.0.2

<p align="center">
  <img src="https://www.kashybee.com/nav-loog.svg" alt="Kashybee Logo" width="200" />
</p>

<h1 align="center">@kashybee/ui-widget</h1>

<p align="center">
  <strong>🎨 Beautiful, framework-agnostic UI widget for Kashybee voucher payments</strong>
</p>

<p align="center">
  <a href="https://www.npmjs.com/package/@kashybee/ui-widget">
    <img src="https://img.shields.io/npm/v/@kashybee/ui-widget.svg?style=flat-square&color=00D9FF" alt="npm version" />
  </a>
  <a href="https://www.npmjs.com/package/@kashybee/ui-widget">
    <img src="https://img.shields.io/npm/dm/@kashybee/ui-widget.svg?style=flat-square&color=00D9FF" alt="npm downloads" />
  </a>
  <a href="https://opensource.org/licenses/MIT">
    <img src="https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square" alt="License: MIT" />
  </a>
  <a href="#">
    <img src="https://img.shields.io/badge/TypeScript-Ready-blue.svg?style=flat-square" alt="TypeScript" />
  </a>
</p>

<p align="center">
  <a href="#-features">Features</a> •
  <a href="#-installation">Installation</a> •
  <a href="#-quick-start">Quick Start</a> •
  <a href="#-frameworks">Frameworks</a> •
  <a href="#-configuration">Configuration</a> •
  <a href="#-theming">Theming</a>
</p>

---

## ✨ Features

| Feature                   | Description                                                      |
| ------------------------- | ---------------------------------------------------------------- |
| 🎨 **Beautiful Design**   | Premium, modern UI matching Kashybee's brand identity            |
| 🔌 **Framework Agnostic** | First-class support for **React**, **Vue 3**, and **Vanilla JS** |
| 🎯 **Zero CSS Config**    | Styles are automatically injected—no manual imports needed       |
| 📱 **Mobile Responsive**  | Optimized modal experience on all screen sizes                   |
| 💳 **Dual Flows**         | Separate "Add Funds" and "Withdraw" modal experiences            |
| 🎛️ **Fully Customizable** | Theme support for colors, fonts, and more                        |
| 🔒 **Secure**             | All transactions go through your secure backend                  |
| 📦 **Lightweight**        | Minimal bundle size with no heavy dependencies                   |

---

## 📦 Installation

```bash
# npm
npm install @kashybee/ui-widget

# yarn
yarn add @kashybee/ui-widget

# pnpm
pnpm add @kashybee/ui-widget
```

---

## 🚀 Quick Start

### React

```jsx
import {
  KashybeeAddFundsButton,
  KashybeeWithdrawButton,
} from "@kashybee/ui-widget/react";

function App() {
  return (
    <div style={{ display: "flex", gap: "16px" }}>
      <KashybeeAddFundsButton
        addFundsUrl="https://api.yoursite.com/kashybee/add-funds"
        withdrawFundsUrl="https://api.yoursite.com/kashybee/withdraw-funds"
        userId="user-123"
        walletCurrency="USD"
        country="US"
        onSuccess={(response) => console.log("✅ Success:", response)}
        onError={(error) => console.error("❌ Error:", error)}
      />

      <KashybeeWithdrawButton
        addFundsUrl="https://api.yoursite.com/kashybee/add-funds"
        withdrawFundsUrl="https://api.yoursite.com/kashybee/withdraw-funds"
        userId="user-123"
        walletCurrency="USD"
        country="US"
        onSuccess={(response) => console.log("✅ Success:", response)}
        onError={(error) => console.error("❌ Error:", error)}
      />
    </div>
  );
}

export default App;
```

### Vue 3

```vue
<template>
  <div class="buttons">
    <KashybeeButton
      mode="add"
      :add-funds-url="addFundsUrl"
      :withdraw-funds-url="withdrawFundsUrl"
      :user-id="userId"
      wallet-currency="USD"
      country="US"
      @success="handleSuccess"
      @error="handleError"
    />

    <KashybeeButton
      mode="withdraw"
      :add-funds-url="addFundsUrl"
      :withdraw-funds-url="withdrawFundsUrl"
      :user-id="userId"
      wallet-currency="USD"
      country="US"
      @success="handleSuccess"
      @error="handleError"
    />
  </div>
</template>

<script setup lang="ts">
import { KashybeeButton } from "@kashybee/ui-widget/vue";

const addFundsUrl = "https://api.yoursite.com/kashybee/add-funds";
const withdrawFundsUrl = "https://api.yoursite.com/kashybee/withdraw-funds";
const userId = "user-123";

const handleSuccess = (response) => console.log("✅ Success:", response);
const handleError = (error) => console.error("❌ Error:", error);
</script>

<style>
.buttons {
  display: flex;
  gap: 16px;
}
</style>
```

### Vanilla JavaScript (ES Modules)

```javascript
import { createKashybeeWidget } from "@kashybee/ui-widget";

const widget = createKashybeeWidget({
  addFundsUrl: "/api/add-funds",
  withdrawFundsUrl: "/api/withdraw-funds",
  userId: "user-123",
  walletCurrency: "USD",
  country: "US",
  onSuccess: (response) => console.log("✅ Success:", response),
  onError: (error) => console.error("❌ Error:", error),
});

// Create separate Add Funds and Withdraw buttons
const container = document.getElementById("kashybee-container");

const addBtn = widget.createButton("Add Funds", "add");
const withdrawBtn = widget.createButton("Withdraw Funds", "withdraw");

container.appendChild(addBtn);
container.appendChild(withdrawBtn);
```

### Vanilla JavaScript (Script Tag)

```html
<!DOCTYPE html>
<html>
  <head>
    <title>Kashybee Widget Demo</title>
  </head>
  <body>
    <div id="kashybee-container"></div>

    <script type="module">
      import { createKashybeeWidget } from "https://unpkg.com/@kashybee/ui-widget/dist/index.mjs";

      const widget = createKashybeeWidget({
        addFundsUrl: "/api/add-funds",
        withdrawFundsUrl: "/api/withdraw-funds",
        userId: "user-123",
        walletCurrency: "USD",
        country: "US",
        onSuccess: (response) => {
          console.log("Success:", response);
        },
        onError: (error) => {
          console.error("Error:", error);
        },
      });

      // Create separate Add Funds and Withdraw buttons
      const container = document.getElementById("kashybee-container");

      const addBtn = widget.createButton("Add Funds", "add");
      const withdrawBtn = widget.createButton("Withdraw Funds", "withdraw");

      container.appendChild(addBtn);
      container.appendChild(withdrawBtn);
    </script>
  </body>
</html>
```

### Vanilla JavaScript (UMD / Script Tag)

For environments that don't support ES modules, use the UMD build:

```html
<!DOCTYPE html>
<html>
  <head>
    <title>Kashybee Widget Demo</title>
  </head>
  <body>
    <div id="kashybee-container"></div>

    <script src="https://unpkg.com/@kashybee/ui-widget/dist/index.umd.js"></script>
    <script>
      const widget = KashybeeWidget.createKashybeeWidget({
        addFundsUrl: "/api/add-funds",
        withdrawFundsUrl: "/api/withdraw-funds",
        userId: "user-123",
        walletCurrency: "USD",
        country: "US",
        onSuccess: (response) => {
          console.log("Success:", response);
        },
        onError: (error) => {
          console.error("Error:", error);
        },
      });

      // Create separate Add Funds and Withdraw buttons
      const container = document.getElementById("kashybee-container");

      const addBtn = widget.createButton("Add Funds", "add");
      const withdrawBtn = widget.createButton("Withdraw Funds", "withdraw");

      container.appendChild(addBtn);
      container.appendChild(withdrawBtn);
    </script>
  </body>
</html>
```

---

## 🖼️ Frameworks

### React Components

The React package exports specialized components and a hook for custom implementations:

#### Components

| Component                | Description                                  |
| ------------------------ | -------------------------------------------- |
| `KashybeeAddFundsButton` | Pre-configured button for adding funds       |
| `KashybeeWithdrawButton` | Pre-configured button for withdrawing funds  |
| `KashybeeButton`         | Generic button with configurable `mode` prop |

#### Hook: `useKashybeeWidget`

For complete control, use the hook to build custom UI:

```jsx
import { useKashybeeWidget } from "@kashybee/ui-widget/react";

function CustomPaymentUI() {
  const { open, close } = useKashybeeWidget({
    addFundsUrl: "/api/add-funds",
    withdrawFundsUrl: "/api/withdraw-funds",
    userId: "user-123",
    onSuccess: (response) => {
      console.log("Transaction complete:", response);
    },
  });

  return (
    <div className="my-custom-ui">
      <button className="my-add-btn" onClick={() => open("add")}>
        💰 Top Up Wallet
      </button>
      <button className="my-withdraw-btn" onClick={() => open("withdraw")}>
        💸 Cash Out
      </button>
    </div>
  );
}
```

#### Custom Children

You can also use your own button design with the component:

```jsx
<KashybeeAddFundsButton
  addFundsUrl="/api/add-funds"
  withdrawFundsUrl="/api/withdraw-funds"
  userId="user-123"
>
  <MyCustomButton>Add Funds with Kashybee</MyCustomButton>
</KashybeeAddFundsButton>
```

---

### Vue 3 Component

The Vue package exports a single flexible component:

```vue
<template>
  <KashybeeButton
    mode="add"
    :add-funds-url="'/api/add-funds'"
    :withdraw-funds-url="'/api/withdraw-funds'"
    :user-id="'user-123'"
    wallet-currency="USD"
    button-text="Top Up My Wallet"
    @success="onSuccess"
    @error="onError"
    @open="onModalOpen"
    @close="onModalClose"
  />

  <KashybeeButton
    mode="withdraw"
    :add-funds-url="'/api/add-funds'"
    :withdraw-funds-url="'/api/withdraw-funds'"
    :user-id="'user-123'"
    wallet-currency="USD"
    button-text="Cash Out"
    @success="onSuccess"
    @error="onError"
    @open="onModalOpen"
    @close="onModalClose"
  />
</template>

<script setup lang="ts">
import { KashybeeButton } from "@kashybee/ui-widget/vue";

const onSuccess = (response) => {
  alert(`Success! Transaction ID: ${response.data?.transactionId}`);
};

const onError = (error) => {
  alert(`Error: ${error.message}`);
};

const onModalOpen = () => console.log("Modal opened");
const onModalClose = () => console.log("Modal closed");
</script>
```

#### Props

| Prop               | Type                  | Default | Description                                |
| ------------------ | --------------------- | ------- | ------------------------------------------ |
| `mode`             | `'add' \| 'withdraw'` | `'add'` | Modal mode to open                         |
| `addFundsUrl`      | `string`              | —       | Your server endpoint for adding funds      |
| `withdrawFundsUrl` | `string`              | —       | Your server endpoint for withdrawing funds |
| `userId`           | `string`              | —       | User ID for the transaction                |
| `walletCurrency`   | `string`              | `'USD'` | Default currency code                      |
| `country`          | `string`              | —       | User's country code                        |
| `buttonText`       | `string`              | Auto    | Custom button text                         |

#### Events

| Event      | Payload               | Description                     |
| ---------- | --------------------- | ------------------------------- |
| `@success` | `TransactionResponse` | Fired on successful transaction |
| `@error`   | `Error`               | Fired when an error occurs      |
| `@open`    | —                     | Fired when modal opens          |
| `@close`   | —                     | Fired when modal closes         |

---

### Data Attributes (No JavaScript)

Auto-initialize widgets using HTML attributes only:

```html
<script src="https://unpkg.com/@kashybee/ui-widget/dist/index.umd.js"></script>

<!-- Add Funds Button -->
<div
  data-kashybee-widget
  data-mode="add"
  data-add-funds-url="/api/add-funds"
  data-withdraw-funds-url="/api/withdraw-funds"
  data-user-id="user-123"
  data-wallet-currency="USD"
  data-button-text="Add Funds"
></div>

<!-- Withdraw Button -->
<div
  data-kashybee-widget
  data-mode="withdraw"
  data-add-funds-url="/api/add-funds"
  data-withdraw-funds-url="/api/withdraw-funds"
  data-user-id="user-123"
  data-wallet-currency="USD"
  data-button-text="Withdraw"
></div>
```

---

## ⚙️ Configuration

### `KashybeeWidgetConfig`

| Option             | Type            | Required | Default | Description                                |
| ------------------ | --------------- | :------: | ------- | ------------------------------------------ |
| `addFundsUrl`      | `string`        |    ✅    | —       | Your server endpoint for adding funds      |
| `withdrawFundsUrl` | `string`        |    ✅    | —       | Your server endpoint for withdrawing funds |
| `userId`           | `string`        |    ✅    | —       | Unique identifier for the user             |
| `walletCurrency`   | `string`        |    ❌    | `"USD"` | Default currency code                      |
| `country`          | `string`        |    ❌    | —       | User's country code (e.g., `"US"`, `"BD"`) |
| `headers`          | `object`        |    ❌    | —       | Custom headers for API requests            |
| `theme`            | `KashybeeTheme` |    ❌    | —       | Theme customization options                |
| `onSuccess`        | `function`      |    ❌    | —       | Callback on successful transaction         |
| `onError`          | `function`      |    ❌    | —       | Callback on error                          |
| `onOpen`           | `function`      |    ❌    | —       | Callback when modal opens                  |
| `onClose`          | `function`      |    ❌    | —       | Callback when modal closes                 |
| `editableFields`   | `object`        |    ❌    | —       | Configure which fields are editable        |

---

## 🎨 Theming

Customize the widget's appearance with the `theme` option:

```javascript
const widget = createKashybeeWidget({
  // ... other config
  theme: {
    primaryColor: "#00D9FF",
    primaryHoverColor: "#00B8D9",
    textColor: "#1A1A2E",
    backgroundColor: "#FFFFFF",
    borderRadius: "12px",
    fontFamily: "Inter, system-ui, sans-serif",
  },
});
```

### Theme Properties

| Property            | Type     | Default     | Description                |
| ------------------- | -------- | ----------- | -------------------------- |
| `primaryColor`      | `string` | `#00D9FF`   | Primary brand color        |
| `primaryHoverColor` | `string` | `#00B8D9`   | Hover state color          |
| `textColor`         | `string` | `#1A1A2E`   | Main text color            |
| `backgroundColor`   | `string` | `#FFFFFF`   | Modal background color     |
| `borderRadius`      | `string` | `12px`      | Border radius for elements |
| `fontFamily`        | `string` | System font | Font family for text       |

---

## 🔗 Server Integration

The widget communicates with **your backend**, which then uses the `@kashybee/node-sdk` to securely interact with the Kashybee API.

### Architecture

```
┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   Your Client   │────▶│   Your Server   │────▶│  Kashybee API   │
│  (UI Widget)    │◀────│  (Node SDK)     │◀────│                 │
└─────────────────┘     └─────────────────┘     └─────────────────┘
```

### Add Funds Endpoint

Your endpoint receives:

```json
{
  "voucherCode": "ABC123XYZ",
  "amount": 100,
  "userId": "user-123",
  "walletCurrency": "USD",
  "country": "US"
}
```

### Withdraw Funds Endpoint

Your endpoint receives:

```json
{
  "email": "user@example.com",
  "amount": 50,
  "userId": "user-123",
  "walletCurrency": "USD",
  "country": "US"
}
```

### Example Server (Express.js)

```javascript
const express = require("express");
const { KashybeeClient } = require("@kashybee/node-sdk");

const app = express();
app.use(express.json());

const kashybee = new KashybeeClient({
  apiKey: process.env.KASHYBEE_API_KEY,
  hmacSecret: process.env.KASHYBEE_HMAC_SECRET,
  isSandbox: true,
});

app.post("/api/add-funds", async (req, res) => {
  const result = await kashybee.addFunds(req.body);
  res.json(result);
});

app.post("/api/withdraw-funds", async (req, res) => {
  const result = await kashybee.withdrawFunds(req.body);
  res.json(result);
});

app.listen(3000);
```

👉 **See the full documentation at [`@kashybee/node-sdk`](https://www.npmjs.com/package/@kashybee/node-sdk)**

---

## 📋 TypeScript Support

This package is written in TypeScript and ships with full type declarations.

```typescript
import type {
  KashybeeWidgetConfig,
  KashybeeTheme,
  ModalMode,
  TransactionResponse,
  AddFundsPayload,
  WithdrawFundsPayload,
} from "@kashybee/ui-widget";
```

---

## 🌐 Browser Support

| Browser | Supported |
| ------- | :-------: |
| Chrome  |    ✅     |
| Firefox |    ✅     |
| Safari  |    ✅     |
| Edge    |    ✅     |
| IE 11   |    ❌     |

---

## 📄 License

MIT © [Kashybee](https://kashybee.com)

---

<p align="center">
  <strong>Built with ❤️ by the Kashybee Team</strong>
</p>

<p align="center">
  <a href="https://kashybee.com">Website</a> •
  <a href="https://kashybee.com/api-docs">Documentation</a> •
  <a href="https://github.com/kashybee">GitHub</a>
</p>