The first release of SlidingTabs — a Safari-style horizontal tab bar for SwiftUI with drag-to-reor
der. You bring the data and the chip view; SlidingTabs owns the drag mechanic.
Highlights
- Drag-to-reorder that feels like Safari. A dragged chip swaps slots the instant the cursor enters
another chip's[anchorX, anchorX + width)range — no midpoint lag, no overshoot. - Variable chip widths. Each chip's natural width is measured with
onGeometryChange, so chips ca
n size to their content instead of a fixed grid. - Bring your own item and chip.
SlidingTabBaris generic over anyIdentifiableitem and any ch
ipView. You own the array and the active selection; the bar mutates your binding once on drop. DefaultTabChipdrop-in. Active highlight, hover-revealed close button, and an unseen-changes d
ot, with every color themeable.- Optional "+" button. Pass
onAddand the bar renders an add button after the chips.
API
public struct SlidingTabBar<Item: Identifiable, Chip: View>: View where Item.ID: Hashable
public struct DefaultTabChip: ViewSlidingTabBar initializer parameters:
| Parameter | Default | Description |
|---|---|---|
items |
— | Binding to the ordered items array. Mutated in place on drop. |
activeID |
— | Binding to the active tab's id, or nil. |
spacing |
6 |
Horizontal gap between chips. |
defaultItemWidth |
200 |
Fallback width for chips not yet measured. |
barHeight |
36 |
Pinned bar height. |
horizontalPadding |
12 |
Leading/trailing padding inside the bar. |
verticalPadding |
6 |
Top/bottom padding inside the bar. |
onReorderCommit |
nil |
Called once after a drop mutates the array. Persist the new order here. |
|
| onAdd | nil | If non-nil, renders a "+" button after the chips. |
| chip | — | View builder receiving (Item, Bool) — the item and whether it is active. |
DefaultTabChip takes title, systemImage, isActive, hasUnseen, and onClose, plus accent,
inactiveBackground, inactiveBorder, textColor, and mutedColor for theming.
Requirements
- Swift 6.3+ (builds in Swift 6 language mode)
- iOS 18 · macOS 15 · tvOS 18 · watchOS 11
