# useConnect

The `useConnect` hook provides a powerful, programmatic way to open, close, and manage the `DidConnect` UI modal. It's the ideal solution when you need more control over the connection flow than the declarative `Button` component offers, such as triggering the modal from a custom UI element, a menu item, or in response to an application event.

This hook is the engine behind the `Button` component and gives you direct access to the same core functionalities.

## How It Works

The `useConnect` hook returns two main elements:

1.  **`connectHolder`**: A React element that must be rendered in your component tree. This element is responsible for rendering the `DidConnect` modal when it's activated. It remains invisible until the `open` function is called.
2.  **`connectApi`**: An object containing the functions (`open`, `close`, `openPopup`, `loginOAuth`) you'll use to control the modal's lifecycle.

<!-- DIAGRAM_IMAGE_START:flowchart:4:3:1765962229 -->
![useConnect](assets/diagram/use-connect-diagram-0.jpg)
<!-- DIAGRAM_IMAGE_END -->

## Setup

To use the hook, import it and call it within your component. Then, ensure you render the `connectHolder` somewhere in your application, preferably at a top-level component to ensure the modal can overlay all other content.

```javascript Basic Setup icon=logos:javascript
import React from 'react';
import { useConnect } from '@arcblock/did-connect-react';

function MyComponent() {
  // 1. Initialize the hook
  const { connectHolder, connectApi } = useConnect();

  const handleLogin = () => {
    // 2. Use the API to open the modal
    connectApi.open({
      action: 'login',
      onSuccess: (result) => {
        console.log('Login successful!', result);
      },
      onClose: () => {
        console.log('Modal closed by user.');
      }
    });
  };

  return (
    <div>
      <button type="button" onClick={handleLogin}>
        Login with DID
      </button>

      {/* 3. Render the holder component */}
      {connectHolder}
    </div>
  );
}

export default MyComponent;
```

## API Reference

The `connectApi` object provides the following methods to control the connection process.

### `connectApi.open(options)`

This is the primary function to trigger and display the `DidConnect` modal. It accepts a single `options` object to configure the behavior, appearance, and callbacks for the connection session.

**Parameters (`options`)**

<x-field-group>
  <x-field data-name="action" data-type="string" data-required="true">
    <x-field-desc markdown>The purpose of the connection request, e.g., `login`, `claim`, `sign`, etc. This determines the workflow within the wallet.</x-field-desc>
  </x-field>
  <x-field data-name="onSuccess" data-type="(result: object) => void" data-required="false">
    <x-field-desc markdown>Callback function executed when the user successfully completes the action in their wallet. The `result` object contains the response from the wallet.</x-field-desc>
  </x-field>
  <x-field data-name="onClose" data-type="() => void" data-required="false">
    <x-field-desc markdown>Callback function executed when the user manually closes the modal without completing the action.</x-field-desc>
  </x-field>
  <x-field data-name="onError" data-type="(error: any) => void" data-required="false">
    <x-field-desc markdown>Callback function executed if an error occurs during the process, such as a timeout or a network issue.</x-field-desc>
  </x-field>
  <x-field data-name="messages" data-type="ConnectMessages" data-required="false">
    <x-field-desc markdown>An object to customize the text displayed in the modal. See `ConnectMessages` type for details.</x-field-desc>
    <x-field data-name="title" data-type="string" data-desc="Modal title."></x-field>
    <x-field data-name="scan" data-type="string" data-desc="Text accompanying the QR code."></x-field>
    <x-field data-name="confirm" data-type="string" data-desc="Text for the confirmation step."></x-field>
    <x-field data-name="success" data-type="ReactNode" data-desc="Content for the success screen."></x-field>
  </x-field>
  <x-field data-name="popup" data-type="boolean" data-default="true">
    <x-field-desc markdown>If `true`, the UI is displayed as a modal dialog. If `false`, it renders inline, requiring `containerEl` to be set.</x-field-desc>
  </x-field>
  <x-field data-name="containerEl" data-type="Element" data-required="false">
    <x-field-desc markdown>A DOM element where the `DidConnect` component will be rendered if `popup` is set to `false`.</x-field-desc>
  </x-field>
  <x-field data-name="closeTimeout" data-type="number" data-default="2000">
    <x-field-desc markdown>The delay in milliseconds before the modal automatically closes after a successful connection.</x-field-desc>
  </x-field>
  <x-field data-name="checkInterval" data-type="number" data-default="2000">
    <x-field-desc markdown>The interval in milliseconds for polling the server to check the session status.</x-field-desc>
  </x-field>
  <x-field data-name="checkTimeout" data-type="number" data-default="300000">
    <x-field-desc markdown>The total time in milliseconds before the connection attempt times out.</x-field-desc>
  </x-field>
  <x-field data-name="extraParams" data-type="object" data-default="{}">
    <x-field-desc markdown>Any extra parameters to be included in the session creation request, which can be retrieved on the server-side.</x-field-desc>
  </x-field>
</x-field-group>

### `connectApi.close()`

Manually closes the `DidConnect` modal. The modal closes automatically on success or user cancellation, but you can call this function if you need to close it programmatically for other reasons.

```javascript icon=lucide:x-circle
// Example: Close the modal after a short delay in the success callback
connectApi.open({
  action: 'login',
  onSuccess: () => {
    showTemporarySuccessMessage();
    setTimeout(() => {
      connectApi.close();
    }, 1500);
  },
  closeTimeout: 999999 // Prevent auto-close
});
```

### `connectApi.openPopup(params, options)`

This function provides an alternative connection method that opens the DID Connect flow in a new browser popup window instead of a modal within the current page. This is useful for certain OAuth-like flows or when integrating with sites where you cannot inject a modal.

**Parameters**

<x-field-group>
  <x-field data-name="params" data-type="ConnectProps" data-required="true">
    <x-field-desc markdown>Similar to the `open` method's options. A key difference is that `params.extraParams.provider` is **required** to identify the authentication method (e.g., 'github', 'google').</x-field-desc>
  </x-field>
  <x-field data-name="options" data-type="object" data-required="false">
    <x-field-desc markdown>Configuration for the popup window itself.</x-field-desc>
    <x-field data-name="baseUrl" data-type="string" data-desc="The base URL for constructing the popup URL."></x-field>
    <x-field data-name="locale" data-type="string" data-default="en" data-desc="The locale for the popup content."></x-field>
    <x-field data-name="popupOptions" data-type="object" data-desc="Options passed directly to `window.open()` for customizing the popup's size and features."></x-field>
  </x-field>
</x-field-group>

**Usage**

The `openPopup` function returns a `Promise` that resolves with the authentication data on success or rejects on failure or cancellation.

```javascript icon=lucide:external-link
const handleGithubLogin = async () => {
  try {
    const result = await connectApi.openPopup({
      action: 'login',
      onSuccess: () => console.log('This callback is also triggered'),
      extraParams: { provider: 'github' } // This is required
    });
    console.log('Login successful via popup:', result);
  } catch (err) {
    if (err.message === 'Popup closed') {
      console.log('User closed the popup window.');
    } else {
      console.error('An error occurred:', err);
    }
  }
};
```

### `connectApi.loginOAuth(options)`

This is a helper function to directly initiate an OAuth login flow. It's a lower-level utility that is internally used by other parts of the library.

**Parameters (`options`)**

<x-field-group>
  <x-field data-name="provider" data-type="string" data-required="true" data-desc="The OAuth provider to use, e.g., 'github', 'google'."></x-field>
  <x-field data-name="action" data-type="string" data-required="true" data-desc="The action, typically 'login'."></x-field>
  <x-field data-name="extraParams" data-type="object" data-required="false" data-desc="Additional parameters for the OAuth flow."></x-field>
  <x-field data-name="onLogin" data-type="function" data-required="true" data-desc="Callback function executed upon successful login."></x-field>
</x-field-group>