# UI Components

The `@blocklet/payment-react` library provides a set of granular UI Components designed to give you maximum flexibility when building your payment and checkout interfaces. Unlike the high-level [Checkout Components](./components-checkout.md), which encapsulate entire flows, these components are the building blocks for creating a custom user experience.

These components are ideal when you need to integrate payment functionality into an existing application layout or when the standard checkout flows do not meet your specific design requirements.

<x-cards data-columns="3">
  <x-card data-title="PricingTable" data-icon="lucide:layout-list" data-href="/components/ui/pricing-table">
    Display subscription plans and pricing options in a structured table, allowing users to select a plan and proceed to checkout.
  </x-card>
  <x-card data-title="PaymentSummary" data-icon="lucide:receipt" data-href="/components/ui/payment-summary">
    Show a detailed summary of an order, including line items, totals, and trial information within the checkout flow.
  </x-card>
  <x-card data-title="Form Elements" data-icon="lucide:form-input" data-href="/components/ui/form-elements">
    A collection of specialized input components for building custom payment and contact information forms, such as address, phone, and country selection.
  </x-card>
</x-cards>

## Composing Your Payment UI

UI Components are meant to be composed together to construct a complete payment page. Most of these components require access to the payment context for data like payment methods and settings, so they must be rendered within a `PaymentProvider`.

Below is a conceptual example of how you might combine `PricingTable` and `PaymentSummary` to create a custom checkout page.

```jsx A Custom Checkout Page icon=logos:react
import { PaymentProvider } from '@blocklet/payment-react';
import { PricingTable, PaymentSummary } from '@blocklet/payment-react/components';
// The useSessionContext hook is defined in the PaymentProvider documentation
import { useSessionContext } from '/path/to/session/context'; 

function CustomCheckoutPage() {
  const { session, connectApi } = useSessionContext();
  
  // In a real application, you would fetch this data from your backend
  const pricingData = { /* ... pricing table data object ... */ };
  const selectedItems = [ /* ... line items based on user selection ... */ ];
  const currency = { /* ... currency object ... */ };

  const handleSelect = (priceId, currencyId) => {
    console.log('User selected plan:', priceId, 'with currency:', currencyId);
    // Add the selected plan to the 'selectedItems' state and update the UI
  };

  return (
    <PaymentProvider
      apiHost={connectApi}
      sessionId={session.user?.did}
      locale="en"
    >
      <div className="checkout-container" style={{ display: 'flex', gap: '2rem' }}>
        <div className="pricing-section" style={{ flex: 2 }}>
          <h2>Choose Your Plan</h2>
          <PricingTable table={pricingData} onSelect={handleSelect} />
        </div>
        <div className="summary-section" style={{ flex: 1 }}>
          <h2>Order Summary</h2>
          <PaymentSummary items={selectedItems} currency={currency} />
        </div>
      </div>
    </PaymentProvider>
  );
}
```

In this example, `PricingTable` and `PaymentSummary` are used together on a custom page. The `PaymentProvider` wraps the entire structure, making payment settings and methods available to all child components.

## Next Steps

Now that you understand the role of UI Components, dive into the specifics of each one to start building your custom payment flow. We recommend starting with the `PricingTable`.

[Learn about the PricingTable component &rarr;](./components-ui-pricing-table.md)