npm package: @gluex/widget
Description: A powerful and customizable Web3 widget that enables seamless integration of decentralized finance functionality into any web application. Bring the full capabilities of DeFi directly into your app with just a few lines of code.
Latest version: 1.0.47

# GlueX Widget

A powerful and customizable Web3 widget that enables seamless integration of decentralized finance functionality into any web application. Bring the full capabilities of DeFi directly into your app with just a few lines of code.

## Table of Contents
- [Overview](#overview)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [Customization](#customization)
  - [UI Customization](#ui-customization)
  - [Display Options](#display-options)
  - [Layout Customization](#layout-customization)
  - [Shape Customization](#shape-customization)
  - [Typography & Fonts](#typography-fonts)
  - [Color System](#color-system)
  - [Component Customization](#component-customization)
  - [Wallet Integration](#wallet-integration)
  - [Chain Configuration](#chain-configuration)
- [Custom Components](#custom-components)
  - [Amount Selection](#amount-selection-percentageamountselector)
  - [Token Amount Display](#token-amount-display-tokenamountprice)
  - [Transaction Details](#transaction-details-transactiondetails)
  - [Completed Transaction](#completed-transaction-completedtransactiondetails)
- [Widget Events](#widget-events)
  - [Events setup](#event-setup)
  - [Available Events](#available-events)
  - [Integration Example](#integration-example)
## Overview

The GlueX Widget is a comprehensive Web3 integration solution designed to make DeFi integration effortless while maintaining complete flexibility:

- **Quick Integration**: Get started in minutes with just a few lines of code
- **Full UI Customization**: Customize colors, typography, shapes, and every visual aspect to match your brand
- **Multiple Display Modes**: Choose from default, drawer, or compact display options
- **Theme System**: Comprehensive theming with light, dark, and auto mode support
- **Configurable Components**: Show, hide, or customize any widget component as needed
- **Wallet Integration**: Seamless integration with multiple wallet providers

## Installation

```bash
# Using npm
npm install wagmi @tanstack/react-query @gluex/widget @gluex/sdk

# Using yarn
yarn add wagmi @tanstack/react-query @gluex/widget @gluex/sdk

# Using pnpm
pnpm add wagmi @tanstack/react-query @gluex/widget @gluex/sdk
```

## Quick Start

First, you'll need an API key and integrator ID from the [GlueX Developer Portal](https://portal.gluex.xyz/login). Then, you can integrate the widget with just a few lines of code:

```tsx
import { GlueXWidget, WidgetConfig } from '@gluex/widget';

const config: Partial<WidgetConfig> = {
  apiKey: process.env.NEXT_PUBLIC_GLUEX_API_KEY,
  integrator: "your-integrator-id",              
  appearance: "dark",                          
};

export const WidgetPage = () => {
  return <GlueXWidget config={config} />;
};
```

## Customization

The GlueX Widget offers comprehensive customization options to match your application's design and functionality requirements. The widget's layout stays consistent, but you can modify colors, fonts, styles, disable or hide parts of the UI, and more.

### UI Customization

The widget provides several ways to customize its appearance and behavior:

```tsx
interface WidgetConfig {
  // Set the default appearance - light, dark or auto (system)
  appearance?: "light" | "dark" | "auto";

  // Disable specific UI elements
  disabled?: Array<
    | "fromAmount"    // Disable amount input in the source section
    | "fromToken"     // Disable token selection in the source section
    | "toAddress"     // Disable destination address input
    | "toToken"       // Disable token selection in the destination section
  >;

  // Hide specific UI elements from the UI
  hidden?: Array<
    | "appearance"           // Hide theme switcher
    | "drawerCloseButton"   // Hide drawer close button
    | "history"             // Hide transaction history
    | "language"            // Hide language selector
    | "poweredBy"          // Hide powered by footer
    | "toAddress"          // Hide destination address field
    | "toToken"            // Hide destination token selector
    | "walletMenu"         // Hide wallet menu
    | "integratorStepDetails"  // Hide integrator step details
    | "reverseTokensButton"    // Hide token swap button
    | "routeTokenDescription"  // Hide route token description
    | "walletHeader"          // Hide wallet header
  >;

  // Make specific UI elements required
  required?: Array<
    | "toAddress"    // Make destination address required
  >;

  // Theme customization options
  theme?: WidgetTheme;
}
```

Example usage:

```tsx
const config = {
  // Appearance configuration
  appearance: "dark",
  
  // UI element control
  disabled: ["fromAmount"],     // Disable amount input
  hidden: [                     // Hide specific UI elements
    "poweredBy",               // Hide powered by footer
    "language"                  // Hide transaction history
  ],
  required: ["toAddress"],     // Make destination address required
  
  // ... other configuration options
};
```

### Display Options

The widget supports three display variants:

1. **Compact**: A more condensed version of the widget
3. **Drawer**: Opens as a sliding drawer from the side

```tsx
const config = {
  variant: "drawer",              // 'drawer' | 'compact'
  subvariant: "router",          // 'router'
  appearance: "light"            // 'light' | 'dark' | 'auto'
}
```

### Layout Customization

Control the widget's layout and dimensions:

```tsx
const config = {
  theme: {
    container: {
      width: "400px",
      height: "600px",           // For fixed height
      maxHeight: "800px",        // For restricted max height
      boxShadow: "0px 8px 32px rgba(0, 0, 0, 0.08)",
      padding: "16px"
    }
  }
}
```

### Shape Customization

Customize border radius for different components:

```tsx
const config = {
  theme: {
    shape: {
      borderRadius: 12,           // Card/container border radius 
      borderRadiusSecondary: 16   // Button border radius
    }
  }
}
```

### Typography & Fonts

Configure font families and text styles:

```tsx
const config = {
  theme: {
    typography: {
      fontFamily: "Verdana, sans-serif",
      fontSize: 14,
      fontWeightRegular: 400,
      fontWeightMedium: 500,
      fontWeightBold: 700
    }
  }
}
```

### Color System

The widget uses a powerful theme system with support for both light and dark modes:

```tsx
const config = {
  theme: {
    colorSchemes: {
      light: {
        palette: {
          primary: {
            main: "#02F994",      // Primary color
            review: "#02F994"     // Review button, animations
          },
          secondary: {
            main: "#F5B5FF"       // Secondary color
          },
          background: {
            default: "#FFFFFF",   // Body background
            paper: "#F5F5F5",     // Token containers, buttons
            selected: "#E0E0E0"   // Selected items
          },
          text: {
            primary: "#1A1A1A",   // Main text color
            secondary: "#757575"   // Secondary text color
          },
          success: { main: "#4CAF50" },
          error: { main: "#F44336" },
          warning: { main: "#FF9800" },
          info: { main: "#2196F3" }
        }
      },
      dark: {
        // Same structure as light theme
        palette: {
          // Dark mode colors
        }
      }
    }
  }
}
```

### Component Customization

Fine-tune individual components:

```tsx
const config = {
  override: {
    // Token selection customization
    selectTokenHeader: {
      style: {},                 // Base styles
      hoverStyle: {},           // Hover state
      selectedStyle: {},        // Selected state
      titleStyle: {},           // Title text
      subheaderStyle: {},       // Subheader text
      avatarContainerStyle: {}  // Token icon container
    },

    // Amount input customization
    amountSlider: {
      useSlider: true,          // Enable/disable slider
      style: {}                 // Slider styles
    },

    // Percentage buttons
    percentageButtons: {
      style: {},                // Container styles
      button25: {},             // 25% button styles
      button50: {},             // 50% button styles
      button75: {},             // 75% button styles
      button100: {}             // 100% button styles
    },

    // Token Details
    reciveTokenDetails: {
      style: {},
      display: {
        showTokenPrice: true,    // Show/hide USD price
        showPriceImpact: true   // Show/hide price impact
      }
    },

    // Settings button
    settingsButton: {
      animate: true,            // Enable/disable animation
      style: {},               // Button styles
      icon: null               // Custom icon
    }
  }
}
```

## Custom Components

The GlueX Widget supports extensive component customization through custom component overrides. Follow these steps to customize the widget UI:

### Step 1: Create a Custom Component

Let's start with a simple example of customizing the token selection button:

```tsx
// custom/token-selector.tsx
import { type SelectTokenButtonProps } from "@gluex/widget"

export const CustomTokenHeader = ({
  formType,    // "from" | "to" - Indicates if this is the source or destination token
  token,       // Selected token information
  chain,       // Selected chain information
  isSelected,  // is token selected
  compact,     // Whether to show compact view
  onClick      // Handler for when the selector is clicked
}: SelectTokenButtonProps) => {
  return (
    <div>
      {/* Your custom token header UI */}
    </div>
  )
}
```

### Step 2: Use in Config

Import and use your custom component in the widget configuration. For token selection, you can customize both "from" and "to" buttons separately:

```tsx
import type { WidgetConfigPartialProps } from "@gluex/widget"
import { GlueXWidget } from "@gluex/widget"
import { CustomTokenHeader } from "./custom/token-selector"

export function Widget() {
  const config: WidgetConfigPartialProps["config"] = {
    integrator: "YOUR_INTEGRATOR_ID",
    apiKey: "YOUR_API_KEY",
    appearance: "light",
    
    // Add your custom components
    components: {
      // Use different components or styles for from/to
      SelectTokenButton: {
        from: CustomTokenHeader,  // Custom component for "from" token
        to: CustomTokenHeader     // Custom component for "to" token
      }
    }
  }

  return <GlueXWidget config={config} />
}
```

### Available Custom Components

Here are all the components you can customize in the widget:

#### Amount Selection (PercentageAmountSelector)

```tsx
import { type PercentageAmountSelectorProps } from "@gluex/widget"

export const CustomPercentageAmountSelector = ({
  onAmountChange,  // (percentage: number) => void
  isLoading        // Whether data is loading
}: PercentageAmountSelectorProps) => {
  const percentages = [
    { value: 0.25, label: "25%" },
    { value: 0.5, label: "50%" },
    { value: 0.75, label: "75%" },
    { value: 1, label: "MAX" }
  ]

  return (
    <div>
      {/* Your custom percentage selection UI */}
    </div>
  )
}
```

#### Token Amount Display (TokenAmountPrice)

```tsx
import { type TokenAmountPriceProps } from "@gluex/widget"

export const CustomTokenAmountPrice = ({
  amount,      // Token amount
  token,       // Token information
  tokenPrice,  // Current token price
  isLoading    // Whether data is loading
}: TokenAmountPriceProps) => {
  return (
    <div>
      {/* Your custom amount display UI */}
    </div>
  )
}
```

#### Transaction Details (TransactionDetails)

```tsx
import { type TransactionDetailsProps } from "@gluex/widget"

export const CustomTransactionDetails = ({
  tokens,       // From/To token information
  fees,         // Network, protocol, and total fees
  minReceived,  // Minimum amount to receive
  providers     // List of providers used
}: TransactionDetailsProps) => {
  return (
    <div>
      {/* Your custom transaction details UI */}
    </div>
  )
}
```

#### Completed Transaction (CompletedTransactionDetails)

```tsx
import { type CompletedTransactionDetailsProps } from "@gluex/widget"

export const CustomCompletedTransaction = ({
  tokens,        // From/To token information
  amounts,       // Transaction amounts
  fees,          // Transaction fees
  transaction,   // Transaction details with hash and link
  providers,     // List of providers used
  showRouteSection,    // Whether to show route section
  showDetailsSection   // Whether to show details section
}: CompletedTransactionDetailsProps) => {
  return (
    <div>
      {/* Your custom completed transaction UI */}
    </div>
  )
}
```

- [Widget Events](#widget-events)
  - [Event Setup](#event-setup)
  - [Available Events](#available-events)
  - [Integration Example](#integration-example)

## Widget Events

The GlueX Widget provides a comprehensive event system through the `useWidgetEvents` hook that allows you to subscribe to various widget events. This enables you to track swap progress, monitor quote execution, observe chain and token selections, track UI interactions, and more.

### Event Setup

First, import the necessary types and hooks:

```tsx
import { WidgetEvent, useWidgetEvents } from "@gluex/widget"
import type { Route, RouteExecutionUpdate } from "@gluex/widget"

export const WidgetEvents = () => {
  const widgetEvents = useWidgetEvents()

  useEffect(() => {
    // Event handlers for route execution
    const onRouteExecutionStarted = (route: Route) => {
      // Handle route start
    }
    const onRouteExecutionUpdated = (update: RouteExecutionUpdate) => {
      // Handle route updates
    }
    const onRouteExecutionCompleted = (route: Route) => {
      // Handle route completion
    }
    const onRouteExecutionFailed = (update: RouteExecutionUpdate) => {
      // Handle route failure
    }

    // Subscribe to events
    widgetEvents.on(WidgetEvent.RouteExecutionStarted, onRouteExecutionStarted)
    widgetEvents.on(WidgetEvent.RouteExecutionUpdated, onRouteExecutionUpdated)
    widgetEvents.on(WidgetEvent.RouteExecutionCompleted, onRouteExecutionCompleted)
    widgetEvents.on(WidgetEvent.RouteExecutionFailed, onRouteExecutionFailed)

    // Cleanup subscriptions
    return () => widgetEvents.all.clear()
  }, [widgetEvents])

  return null
}
```

### Available Events

The widget emits various events that you can listen to:

```tsx
enum WidgetEvent {
  // Route Events
  RouteExecutionStarted = "routeExecutionStarted"    // When a route starts executing
  RouteExecutionUpdated = "routeExecutionUpdated"    // Progress updates during execution
  RouteExecutionCompleted = "routeExecutionCompleted" // When route completes successfully
  RouteExecutionFailed = "routeExecutionFailed"      // When route execution fails
  RouteHighValueLoss = "routeHighValueLoss"          // High value loss detection
  RouteSelected = "routeSelected"                     // When a route is selected
  
  // Chain & Token Events
  SourceChainTokenSelected = "sourceChainTokenSelected"
  DestinationChainTokenSelected = "destinationChainTokenSelected"
  
  // Wallet Events
  WalletConnected = "walletConnected"
  SendToWalletToggled = "sendToWalletToggled"
  
  // UI & Form Events
  PageEntered = "pageEntered"
  WidgetExpanded = "widgetExpanded"
  FormFieldChanged = "formFieldChanged"
  SettingUpdated = "settingUpdated"
  TokenSearch = "tokenSearch"
  TransactionError = "transactionError"
}
```

### Integration Example

Here's how to integrate widget events into your application:

```tsx
// app/page.tsx
import { Widget } from '@/components/Widget'
import { WidgetEvents } from '@/components/WidgetEvents'

export default function Home() {
  return (
    <main>
      <WidgetEvents />  {/* Event handler component */}
      <Widget />       {/* Main widget component */}
    </main>
  )
}
```