# Styling | Swift AI Autocomplete Docs

> For the complete documentation index, see [llms.txt](https://ai-autocomplete.com/llms.txt). A markdown version of any page on this site is available by appending `.md` to its URL path — the homepage is at `/index.md`.

Styling guide for integrating the AI Autocomplete SDK with Swift. Code examples, setup, and API reference.

Source: https://ai-autocomplete.com/docs/swift/styling

---

One value type — AIAutocompleteAppearance — holds every visual token: fonts, colors, radii, spacing, animation. Defaults follow the stock design and adapt to light/dark automatically.

## Applying an appearance

Build a value, override what you need, and apply it — the environment modifier in SwiftUI, the appearance property in UIKit.

**BrandAppearance.swift**

```swift
import AIAutocompleteUIKit

var brand = AIAutocompleteAppearance()
brand.font = .systemFont(ofSize: 18)
brand.inputCornerRadius = 12
brand.pillBorderStyle = .dashed
brand.pillBorderColor = .systemIndigo
brand.columns = 2

// SwiftUI — applies to every AIAutocomplete / AIAutocompleteDropdown below it
AIAutocomplete(configuration: config)
    .aiAutocompleteAppearance(brand)

// UIKit — assign to the view; restyles in place
autocompleteView.appearance = brand
```

AIAutocompleteAppearance lives in the AIAutocompleteUIKit module (it stores UIColor / UIFont), so import that module wherever you build one — SwiftUI apps included.

## Light and dark mode

Every default color is a dynamic UIColor that resolves against the system appearance — light and dark both look right with no work. Custom colors can do the same: pass a UIColor closure keyed on userInterfaceStyle, or an asset-catalog color.

**DynamicColors.swift**

```swift
var appearance = AIAutocompleteAppearance()
appearance.inputBackgroundColor = UIColor { traits in
    traits.userInterfaceStyle == .dark ? .black : .white
}
```

## Typography

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `font` | `UIFont` | `16pt system, Dynamic Type` | Base font for input text and completed params; pills and options fall back to it. Scales with Dynamic Type. |
| `pillFont` | `UIFont?` | `nil (falls back to font)` | Pill chip font. |
| `optionFont` | `UIFont?` | `14pt system, Dynamic Type` | Dropdown option font. |
| `optionSelectedFontWeight` | `UIFont.Weight` | `.semibold` | Font weight of the highlighted / selected option's text; the regular face is restored on deselect. Applied through the descriptor, so a custom optionFont keeps its family. |
| `maxInputLines` | `Int?` | `5` | Lines the input grows to before scrolling internally. nil grows without bound. |
| `lineSpacing` | `CGFloat` | `9` | Extra spacing between wrapped input lines, in points. |
| `maximumContentSizeCategory` | `UIContentSizeCategory` | `.accessibilityExtraLarge` | Dynamic Type cap for option text — scales up to this category and no further. |

## Colors

All UIColor. Defaults are dynamic light/dark pairs mirroring the web SDK's stock palette.

| Prop | Type | Description |
| --- | --- | --- |
| `textColor` | `UIColor` | Free-typed text and completed params in the input. |
| `placeholderColor` | `UIColor` | Placeholder text and unfilled placeholder pills. |
| `caretColor` | `UIColor` | The text caret. |
| `pillBackgroundColor / pillTextColor` | `UIColor` | Pill fill and label text. The stock fill is transparent and the stock border style is .none, so pills read as plain labels. |
| `pillBorderColor` | `UIColor` | Outline color of unfilled pills. |
| `completedParamBackgroundColor / completedParamActiveBackgroundColor` | `UIColor` | Completed-param chip fill — resting, and while the param is re-edited. Used when completedParamEmphasis contains .highlight. |
| `completedParamTextColor` | `UIColor?` | Completed-param chip text color. Defaults to the solid fill's inverse ink (white on light, black on dark); nil follows textColor instead. |
| `completedParamShimmerColor` | `UIColor?` | Band tint of the promotion glint swept across a just-completed param. nil (the default) follows the chip fill, so the glint reads on the chip's ink and stays invisible over the fill. |
| `inputBackgroundColor / inputBorderColor` | `UIColor` | Input surface fill and border. |
| `dropdownBackgroundColor / dropdownBorderColor` | `UIColor` | Dropdown surface fill and border (solid mode). |
| `optionTextColor / optionSelectedTextColor` | `UIColor` | Option text, normal and highlighted. |
| `optionHighlightBackgroundColor` | `UIColor` | Highlighted option's background fill. |
| `shimmerColor` | `UIColor` | Loading shimmer / skeleton base. |
| `submitButtonBackgroundColor / submitButtonForegroundColor` | `UIColor` | Built-in submit button fill and glyph. Ignored with a custom button. |

## Pills and completed params

Unfilled suggestion pills render as hollow small-caps chips — no fill, with a solid outline on the pill being filled (queued pills wait borderless; outline them all via showsInactivePillBorders). Once a param is filled it renders as a solid high-contrast capsule — black on light, white on dark, with inverse ink — that lifts toward the surface while it's being re-edited. Every look is tokenized: restyle the outline, pick a different emphasis, or turn the chips off entirely.

**PillStyles.swift**

```swift
var appearance = AIAutocompleteAppearance()

// Unfilled pills: a solid outline on the ACTIVE pill by default —
// restyle it, outline every pill, or drop outlines entirely
appearance.pillBorderStyle = .dashed   // or .solid (default) / .none
appearance.pillBorderColor = .systemIndigo
appearance.showsInactivePillBorders = true   // outline the queued pills too

// Completed params: a solid black/white capsule by default (.highlight)
appearance.completedParamEmphasis = [.highlight, .bold]  // fill + semibold
appearance.completedParamEmphasis = .bold                // semibold only
appearance.completedParamEmphasis = []                   // plain text
```

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `pillBorderStyle` | `.none \| .dashed \| .solid` | `.solid` | Pill outline: .none (plain label text), .dashed, or .solid — inline and in the dropdown pill bar. |
| `pillBorderWidth` | `CGFloat` | `1` | Width of the pill outline. |
| `showsInactivePillBorders` | `Bool` | `false` | false reserves the pill outline for the active param alone, so the queue reads as one outlined slot being filled. Inert when pillBorderStyle is .none. |
| `completedParamEmphasis` | `CompletedParamEmphasis` | `.highlight` | .highlight draws the chip fill (with horizontal room reserved around each param), .bold sets semibold text. Combine both, or pass [] for plain text. |

## Layout

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `inputCornerRadius` | `CGFloat` | `12` | Input surface radius. |
| `dropdownCornerRadius` | `CGFloat` | `12` | Dropdown card radius. |
| `pillCornerRadius` | `CGFloat` | `6` | Pill chip radius, clamped to half the chip height — a rounded rectangle by default. |
| `optionCornerRadius` | `CGFloat` | `4` | Highlighted option fill (and streak) radius. |
| `inputBorderWidth / dropdownBorderWidth` | `CGFloat` | `0.8 / 0.2` | Hairline borders around the input and dropdown. |
| `inputInsets` | `UIEdgeInsets` | `10pt all sides` | Padding between the input surface's edge and its content. |
| `dropdownGap` | `CGFloat` | `6` | Vertical gap between input and dropdown. |
| `dropdownMaxHeight` | `CGFloat?` | `nil` | Optional hard cap on the option grid's height, in points. Applied together with maxVisibleOptionRows and the keyboard bound — the smallest wins. |
| `maxVisibleOptionRows` | `Int?` | `5` | Option rows shown before the grid scrolls. Expressed in rows, so the cap tracks the option font and Dynamic Type. nil removes the cap. |
| `optionLeadingInset` | `CGFloat` | `5` | Extra leading inset for option text. The default lines options up with the input's text; 0 lines them up with the dropdown pill bar instead. |
| `optionVerticalPadding` | `CGFloat` | `9.75` | Vertical padding around each option's text — the text-to-text gap between adjacent options is twice this. Options wrap to as many lines as they need; each row is exactly tall enough for its option. |
| `completedParamHorizontalPadding / completedParamVerticalPadding` | `CGFloat` | `7 / 2.5` | Chip capsule padding around the param's text, per side. Vertical expands into the line gap — keep it at or below half of lineSpacing, or wrapped chips overlap the line above. |
| `dropdownShadow` | `Shadow?` | `.default` | Drop shadow cast by the dropdown card — the stock .default is a soft shadow (offset y 8pt, blur radius 6pt). nil draws no shadow. Solid mode only; glass supplies its own depth. |
| `columns` | `Int` | `1` | Columns in the option grid. |
| `submitButtonSize / submitButtonSpacing` | `CGFloat` | `28 / 12` | Built-in submit button diameter and its gap from the text. |

## Animation, haptics, surfaces

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `animations` | `Bool` | `true` | Master switch for the selection streak and shimmer. The system Reduce Motion setting always wins. |
| `haptics` | `Bool` | `true` | Light haptic tick on param promotion. Independent of animations. |
| `dropdownSurface` | `.solid \| .glass` | `.solid` | Solid fill, or system glass. |
| `showBrandFooter` | `Bool` | `false` | Whether the AI Autocomplete brand row renders at the dropdown's far edge. Hiding it also releases the scroll band reserved beneath it. |

Glass surfaces

.glass renders the dropdown with system Liquid Glass on iOS 26+, falling back to a blur material on earlier versions. The material supplies the surface, so dropdownBackgroundColor applies only in .solid mode.
