# Theming

Learn how to customize the appearance of payment components using the built-in theme provider and Material-UI theme options. The `@blocklet/payment-react` library is built on top of Material-UI, giving you extensive control over the look and feel of your payment flows.

## Overview of `PaymentThemeProvider`

The library includes a dedicated `PaymentThemeProvider` that wraps all payment components. This provider establishes a default theme that inherits from the ArcBlock UX theme (`@arcblock/ux/lib/Theme`), ensuring visual consistency within the ArcBlock ecosystem. It also adds its own customizations, such as a special `chip` color palette and style overrides for various MUI components.

Here is a simplified look at how `PaymentThemeProvider` is structured:

```tsx src/theme/index.tsx icon=logos:react
import { createTheme, ThemeProvider } from '@mui/material/styles';
import { create as createBlockletTheme, deepmerge } from '@arcblock/ux/lib/Theme';

export function PaymentThemeProvider({ children, theme: customTheme = {} }) {
  const parentTheme = useTheme();

  const mergeTheme = useMemo(() => {
    // Start with the base blocklet theme
    const blockletTheme = parentTheme.themeName === 'ArcBlock' ? parentTheme : createBlockletTheme();

    // Merge our custom payment theme options
    let paymentThemeOptions = deepmerge(blockletTheme, {
      // Custom palette extensions, e.g., for chips
      palette: {
        chip: { /* ... */ },
      },
      // Custom component style overrides
      components: {
        MuiButton: { /* ... */ },
        MuiOutlinedInput: { /* ... */ },
        // ... other components
      },
    });

    // Merge any user-provided custom theme
    paymentThemeOptions = deepmerge(paymentThemeOptions, customTheme);

    return createTheme(paymentThemeOptions);
  }, [parentTheme, customTheme]);

  return (
    <ThemeProvider theme={mergeTheme}>
      <CssBaseline />
      {children}
    </ThemeProvider>
  );
}
```

## Customizing Component Styles

Since version 1.14.22, you can easily customize the theme for individual payment components by passing a `theme` prop. This prop accepts a Material-UI `ThemeOptions` object, giving you two primary ways to apply custom styles.

### 1. Using `styleOverrides`

For deep, structural changes, you can override the styles for specific Material-UI components within the payment component's scope. This is the standard MUI way of theming.

```tsx Customizing the Primary Button icon=logos:react
import { PaymentProvider, CheckoutForm } from '@blocklet/payment-react';
import { useSessionContext } from '@/hooks/session-context'; // Assuming session context is defined here

function CustomStyledCheckout() {
  const { session, connectApi } = useSessionContext();

  return (
    <PaymentProvider session={session} connect={connectApi}>
      <CheckoutForm
        id="plink_xxx"
        onChange={console.info}
        theme={{
          components: {
            MuiButton: {
              styleOverrides: {
                containedPrimary: {
                  backgroundColor: '#1DC1C7',
                  color: '#fff',
                  '&:hover': {
                    backgroundColor: 'rgb(20, 135, 139)',
                  },
                },
              },
            },
          },
        }}
      />
    </PaymentProvider>
  );
}
```

In this example, we target the primary contained button (`MuiButton.styleOverrides.containedPrimary`) and change its background and text color.

### 2. Using the `sx` Prop

For quick, targeted CSS changes, you can pass an `sx` object within the `theme` prop. This allows you to use CSS selectors to target specific elements within the component.

```tsx Customizing with the sx Prop icon=logos:react
import { PaymentProvider, CheckoutForm } from '@blocklet/payment-react';
import { useSessionContext } from '@/hooks/session-context';

function SxStyledCheckout() {
  const { session, connectApi } = useSessionContext();

  return (
    <PaymentProvider session={session} connect={connectApi}>
      <CheckoutForm
        id="plink_xxx"
        showCheckoutSummary={false}
        onChange={console.info}
        theme={{
          sx: {
            // Target the submit button by its specific class name
            '.cko-submit-button': {
              backgroundColor: '#1DC1C7',
              color: '#fff',
              '&:hover': {
                backgroundColor: 'rgb(20, 135, 139)',
              },
            },
          },
        }}
      />
    </PaymentProvider>
  );
}

```

This method is useful when you need to override a style that isn't easily accessible through the standard component style overrides.

## Understanding the Default Theme

The default theme is built upon a system of CSS variables (Design Tokens) for colors, spacing, and typography, allowing for consistent styling across light and dark modes.

### Color Palette

The theme extends the standard Material-UI palette with a custom `chip` object to style status indicators. You can override these colors in your custom theme.

```ts src/theme/types.ts icon=mdi:language-typescript
declare module '@mui/material/styles' {
  interface Palette {
    chip: {
      success: { text: string; background: string; border: string; };
      default: { text: string; background: string; border: string; };
      secondary: { text: string; background: string; border: string; };
      error: { text: string; background: string; border: string; };
      warning: { text: string; background: string; border: string; };
      info: { text: string; background: string; border: string; };
    };
  }
  // ... PaletteOptions definition
}
```

### Design Tokens (CSS Variables)

For advanced, global customization, you can override the CSS variables that define the theme. These variables are defined for both light (`:root`) and dark (`[data-theme='dark']`) modes.

Here are some of the key variables you can target:

```css src/theme/index.css icon=logos:css-3
:root {
  /* Light Theme */
  --backgrounds-bg-base: #ffffff;
  --backgrounds-bg-interactive: #3b82f6;
  --foregrounds-fg-base: #030712;
  --foregrounds-fg-interactive: #3b82f6;
  --stroke-border-base: #eff1f5;
  --radius-m: 0.5rem; /* 8px */
}

[data-theme='dark'] {
  /* Dark Theme */
  --backgrounds-bg-base: #1b1b1f;
  --backgrounds-bg-interactive: #60a5fa;
  --foregrounds-fg-base: #edeef0;
  --foregrounds-fg-interactive: #60a5fa;
  --stroke-border-base: #2e3035;
  --radius-m: 0.5rem;
}
```

Overriding these variables in your global stylesheet will apply changes across all `@blocklet/payment-react` components.

### Typography

The default typography settings can be found in `src/theme/typography.ts`. You can override any of these settings in your custom theme to match your application's typography.

```ts src/theme/typography.ts icon=mdi:language-typescript
export const typography = {
  h1: {
    fontSize: '1.5rem',
    lineHeight: 1.2,
    fontWeight: 800,
  },
  body1: {
    fontSize: '0.875rem',
    lineHeight: 1.75,
  },
  // ... other typography settings
};
```

By understanding these layers of customization, you can seamlessly integrate the payment components into your application with a consistent and polished design.

---

Next, explore the various utility functions that can help you with tasks like data caching and date formatting.

<x-card data-title="Next: Utilities" data-icon="lucide:wrench" data-href="/guides/utilities" data-cta="Read More">
  A reference for utility functions provided by the library, including cached requests, and date formatting.
</x-card>
