> ## Documentation Index
> Fetch the complete documentation index at: https://primer.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Shape Tokens

> Corner radius, border width, and component size override tokens

<Warning>
  Primer Checkout iOS SDK is currently in **beta** (v3.0.0-beta.1).
  The API is subject to change before the stable release.
</Warning>

Shape tokens control the geometry of Primer Checkout components: how rounded their corners are, how thick their borders are, and how large their fixed-dimension elements (icons, touch targets) render.

There are three override structs, each passed to the matching parameter of [`PrimerCheckoutTheme`](/docs/sdk/ios-checkout/v3.0.0-beta/api/theming/primer-theme):

| Struct                 | `PrimerCheckoutTheme` parameter | Controls                   |
| ---------------------- | ------------------------------- | -------------------------- |
| `RadiusOverrides`      | `radius`                        | Corner radius scale        |
| `BorderWidthOverrides` | `borderWidth`                   | Border / stroke thickness  |
| `SizeOverrides`        | `sizes`                         | Fixed component dimensions |

Every property is an optional `CGFloat?`. Values you leave as `nil` fall back to the SDK's internal design tokens, so you only override what you need.

<Info>
  All three structs are `Equatable` and annotated `@available(iOS 15.0, *)`, matching the platform minimum for Primer Checkout.
</Info>

## RadiusOverrides

Corner radius scale, in points. Property names match the SDK's internal `DesignTokens`.

```swift theme={"dark"}
@available(iOS 15.0, *)
public struct RadiusOverrides: Equatable {
    public let primerRadiusXsmall: CGFloat?
    public let primerRadiusSmall: CGFloat?
    public let primerRadiusMedium: CGFloat?
    public let primerRadiusLarge: CGFloat?
    public let primerRadiusBase: CGFloat?

    public init(
        primerRadiusXsmall: CGFloat? = nil,
        primerRadiusSmall: CGFloat? = nil,
        primerRadiusMedium: CGFloat? = nil,
        primerRadiusLarge: CGFloat? = nil,
        primerRadiusBase: CGFloat? = nil
    )
}
```

| Token                | Type       | Default | Description                                    |
| -------------------- | ---------- | ------- | ---------------------------------------------- |
| `primerRadiusXsmall` | `CGFloat?` | 2       | Subtle rounding for the smallest elements      |
| `primerRadiusSmall`  | `CGFloat?` | 4       | Small radius for chips and tags                |
| `primerRadiusMedium` | `CGFloat?` | 8       | Default radius for input fields and cards      |
| `primerRadiusLarge`  | `CGFloat?` | 12      | Large radius for sheets and prominent surfaces |
| `primerRadiusBase`   | `CGFloat?` | 4       | Base unit the radius scale derives from        |

## BorderWidthOverrides

Border and stroke thickness, in points.

```swift theme={"dark"}
@available(iOS 15.0, *)
public struct BorderWidthOverrides: Equatable {
    public let primerBorderWidthThin: CGFloat?
    public let primerBorderWidthMedium: CGFloat?
    public let primerBorderWidthThick: CGFloat?

    public init(
        primerBorderWidthThin: CGFloat? = nil,
        primerBorderWidthMedium: CGFloat? = nil,
        primerBorderWidthThick: CGFloat? = nil
    )
}
```

| Token                     | Type       | Default | Description                      |
| ------------------------- | ---------- | ------- | -------------------------------- |
| `primerBorderWidthThin`   | `CGFloat?` | 1       | Input borders and dividers       |
| `primerBorderWidthMedium` | `CGFloat?` | 2       | Focus rings and selected borders |
| `primerBorderWidthThick`  | `CGFloat?` | 3       | Heavy emphasis borders           |

## SizeOverrides

Fixed component dimensions, in points. Used for icons, touch targets, and other elements with an intrinsic size.

```swift theme={"dark"}
@available(iOS 15.0, *)
public struct SizeOverrides: Equatable {
    public let primerSizeSmall: CGFloat?
    public let primerSizeMedium: CGFloat?
    public let primerSizeLarge: CGFloat?
    public let primerSizeXlarge: CGFloat?
    public let primerSizeXxlarge: CGFloat?
    public let primerSizeXxxlarge: CGFloat?
    public let primerSizeBase: CGFloat?

    public init(
        primerSizeSmall: CGFloat? = nil,
        primerSizeMedium: CGFloat? = nil,
        primerSizeLarge: CGFloat? = nil,
        primerSizeXlarge: CGFloat? = nil,
        primerSizeXxlarge: CGFloat? = nil,
        primerSizeXxxlarge: CGFloat? = nil,
        primerSizeBase: CGFloat? = nil
    )
}
```

| Token                | Type       | Default | Description                           |
| -------------------- | ---------- | ------- | ------------------------------------- |
| `primerSizeSmall`    | `CGFloat?` | 16      | Small icons                           |
| `primerSizeMedium`   | `CGFloat?` | 20      | Default icons                         |
| `primerSizeLarge`    | `CGFloat?` | 24      | Large icons                           |
| `primerSizeXlarge`   | `CGFloat?` | 32      | Payment method icons                  |
| `primerSizeXxlarge`  | `CGFloat?` | 44      | Touch targets                         |
| `primerSizeXxxlarge` | `CGFloat?` | 56      | Large touch targets                   |
| `primerSizeBase`     | `CGFloat?` | 4       | Base unit the size scale derives from |

## Overriding shape tokens

Pass any combination of the three structs to `PrimerCheckoutTheme`. Unset properties inherit the SDK defaults.

```swift theme={"dark"}
import SwiftUI
import PrimerSDK

let theme = PrimerCheckoutTheme(
    radius: RadiusOverrides(
        primerRadiusMedium: 12,
        primerRadiusLarge: 20
    ),
    sizes: SizeOverrides(
        primerSizeXlarge: 40,
        primerSizeXxlarge: 48
    ),
    borderWidth: BorderWidthOverrides(
        primerBorderWidthThin: 1.5,
        primerBorderWidthMedium: 2.5
    )
)
```

Apply the theme on the prebuilt modal by passing it to `primerTheme`:

```swift theme={"dark"}
struct CheckoutView: View {
    let clientToken: String

    var body: some View {
        PrimerCheckout(
            clientToken: clientToken,
            primerTheme: theme
        ) { state in
            handle(state)
        }
    }
}
```

When you embed the composable views inline, pass the theme to the [`PrimerCheckoutSession`](/docs/sdk/ios-checkout/v3.0.0-beta/api/primer-checkout-session) instead. The composable views resolve the merged tokens from the session.

```swift theme={"dark"}
struct InlineCheckoutView: View {
    @StateObject private var session = PrimerCheckoutSession(
        clientToken: clientToken,
        theme: theme
    )

    var body: some View {
        ScrollView {
            PrimerCardForm()
        }
        .primerCheckoutSession(session) { state in
            handle(state)
        }
    }
}
```

<Tip>
  Because every token is optional, you can override a single value, for example `RadiusOverrides(primerRadiusMedium: 12)`, and leave the rest of the scale untouched. Combine shape overrides with [color tokens](/docs/sdk/ios-checkout/v3.0.0-beta/api/theming/color-tokens) and the other override structs on `PrimerCheckoutTheme` to build a complete custom appearance.
</Tip>

## See also

<CardGroup cols={2}>
  <Card title="PrimerTheme" icon="palette" href="/docs/sdk/ios-checkout/v3.0.0-beta/api/theming/primer-theme">
    Assemble shape, color, spacing, and typography overrides into a theme.
  </Card>

  <Card title="Color Tokens" icon="droplet" href="/docs/sdk/ios-checkout/v3.0.0-beta/api/theming/color-tokens">
    Override brand, semantic, text, border, and icon colors.
  </Card>

  <Card title="Spacing Tokens" icon="ruler" href="/docs/sdk/ios-checkout/v3.0.0-beta/api/theming/spacing-tokens">
    Override the spacing scale used for layout and padding.
  </Card>

  <Card title="Typography Tokens" icon="font" href="/docs/sdk/ios-checkout/v3.0.0-beta/api/theming/typography-tokens">
    Override font family, weight, size, and line height per text style.
  </Card>
</CardGroup>
