# 主題化

了解如何使用內建的主題提供者和 Material-UI 主題選項來自訂支付元件的外觀。`@blocklet/payment-react` 函式庫建立在 Material-UI 之上，讓您對支付流程的外觀和風格有廣泛的控制權。

## `PaymentThemeProvider` 概覽

該函式庫包含一個專用的 `PaymentThemeProvider`，它包裝了所有支付元件。此提供者建立了一個預設主題，該主題繼承自 ArcBlock UX 主題 (`@arcblock/ux/lib/Theme`)，確保在 ArcBlock 生態系統中的視覺一致性。它還添加了自己的自訂功能，例如特殊的 `chip` 調色盤和對各種 MUI 元件的樣式覆寫。

以下是 `PaymentThemeProvider` 結構的簡化視圖：

```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>
  );
}
```

## 自訂元件樣式

自 1.14.22 版本起，您可以透過傳遞 `theme` 屬性輕鬆地為單個支付元件自訂主題。此屬性接受一個 Material-UI `ThemeOptions` 物件，為您提供了兩種主要方式來應用自訂樣式。

### 1. 使用 `styleOverrides`

對於深層的、結構性的變更，您可以在支付元件的範圍內覆寫特定 Material-UI 元件的樣式。這是標準的 MUI 主題化方式。

```tsx Customizing the Primary Button icon=logos:react
import { PaymentProvider, CheckoutForm } from '@blocklet/payment-react';
import { useSessionContext } from '@/hooks/session-context'; // 假設 session context 在此定義

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>
  );
}
```

在此範例中，我們鎖定主要包含按鈕 (`MuiButton.styleOverrides.containedPrimary`) 並更改其背景和文字顏色。

### 2. 使用 `sx` 屬性

對於快速、有針對性的 CSS 變更，您可以在 `theme` 屬性中傳遞一個 `sx` 物件。這允許您使用 CSS 選擇器來鎖定元件內的特定元素。

```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>
  );
}

```

當您需要覆寫一個透過標準元件樣式覆寫不易存取的樣式時，此方法非常有用。

## 理解預設主題

預設主題建立在一套用於顏色、間距和排版的 CSS 變數（設計權杖）系統之上，允許在淺色和深色模式下實現一致的樣式。

### 調色盤

該主題擴展了標準的 Material-UI 調色盤，增加了一個自訂的 `chip` 物件來為狀態指示器設定樣式。您可以在您的自訂主題中覆寫這些顏色。

```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
}
```

### 設計權杖（CSS 變數）

對於進階的全域自訂，您可以覆寫定義主題的 CSS 變數。這些變數為淺色（`:root`）和深色（`[data-theme='dark']`）模式都進行了定義。

以下是您可以鎖定的一些關鍵變數：

```css src/theme/index.css icon=logos:css-3
:root {
  /* 淺色主題 */
  --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'] {
  /* 深色主題 */
  --backgrounds-bg-base: #1b1b1f;
  --backgrounds-bg-interactive: #60a5fa;
  --foregrounds-fg-base: #edeef0;
  --foregrounds-fg-interactive: #60a5fa;
  --stroke-border-base: #2e3035;
  --radius-m: 0.5rem;
}
```

在您的全域樣式表中覆寫這些變數，將會對所有 `@blocklet/payment-react` 元件應用變更。

### 排版

預設的排版設定可以在 `src/theme/typography.ts` 中找到。您可以在您的自訂主題中覆寫任何這些設定，以匹配您應用程式的排版。

```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
};
```

透過理解這些自訂層次，您可以將支付元件無縫整合到您的應用程式中，並實現一致且精緻的設計。

---

接下來，探索各種實用工具函式，這些函式可以幫助您處理資料快取和日期格式化等任務。

<x-card data-title="下一步：實用工具" data-icon="lucide:wrench" data-href="/guides/utilities" data-cta="閱讀更多">
  該函式庫提供的實用工具函式參考，包括快取請求和日期格式化。
</x-card>