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:

src/theme/index.tsx

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

See all 12 lines

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.

Customizing the Primary Button

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)',
                  },
                },
              },
            },
          },

See all 5 lines

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.

Customizing with the sx Prop

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)',
              },
            },
          },
        }}
      />

See all 3 lines

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.

src/theme/types.ts

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:

src/theme/index.css

: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.

src/theme/typography.ts

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.