Button

iOS 16.4+iPadOS 16.4+

Triggers an action or event, such as submitting a form.

FLXButton variants
import SwiftUIstruct ButtonUsageExample: View {    var body: some View {        VStack(spacing: FLXSpacing.md) {            FLXButton("Primary", variant: .primary) {}            FLXButton("Destructive", role: .destructive) {}            FLXButton("Outline", variant: .outline) {}            FLXButton("Secondary", variant: .secondary) {}            FLXButton("Ghost", variant: .ghost) {}            FLXButton("Link", variant: .link) {}        }        .padding(FLXSpacing.xl)    }}

Installation

Requires the design system foundation (tokens and theme).

pnpm dlx shadcn@latest add https://swiftui.flexnative.com/r/ios-button.json

Usage

FLXButton("Save", variant: .primary) { /* action */ }

Variants

Five variants, set via variant:.

Primary

FLXButton primary variant
FLXButton("Primary", variant: .primary) {}

Outline

FLXButton outline variant
FLXButton("Outline", variant: .outline) {}

Secondary

FLXButton secondary variant
FLXButton("Secondary", variant: .secondary) {}

Ghost

FLXButton ghost variant
FLXButton("Ghost", variant: .ghost) {}
FLXButton link variant
FLXButton("Link", variant: .link) {}

Destructive

Set via role:, like the native Button.

FLXButton destructive role
FLXButton("Destructive", role: .destructive) {}

Sizes

Set via .controlSize(_:), like native controls. For an icon-only button, use .labelStyle(.iconOnly).

FLXButton sizes
FLXButton("Small") {}  .controlSize(.small)FLXButton("Regular") {}FLXButton("Large") {}  .controlSize(.large)FLXButton("Add", systemImage: "plus") {}  .labelStyle(.iconOnly)

Custom styling

FLXButtonStyle conforms to SwiftUI's native ButtonStyle. Override rendering for a subtree with any ButtonStyle via .flxButtonStyle(_:):

FLXButton custom styling
struct FLXPillButtonStyle: ButtonStyle {  func makeBody(configuration: Configuration) -> some View {      configuration.label          .flxFont(.body, weight: .medium)          .padding(.horizontal, FLXSpacing.xl)          .padding(.vertical, FLXSpacing.md)          .foregroundStyle(.white)          .background(.blue.gradient)          .clipShape(Capsule())          .opacity(configuration.isPressed ? FLXOpacity.pressed : 1)  }}HStack(spacing: FLXSpacing.md) {  FLXButton("Pill", variant: .primary) {}  FLXButton("Pill", variant: .primary) {}      .flxButtonStyle(FLXPillButtonStyle())}

API Reference

FLXButton

init(    role: ButtonRole? = nil,    variant: FLXButtonVariant = .primary,    action: @escaping () -> Void,    @ViewBuilder label: @escaping () -> Label)init(    _ titleKey: LocalizedStringKey,    role: ButtonRole? = nil,    variant: FLXButtonVariant = .primary,    action: @escaping () -> Void)init(    _ titleResource: LocalizedStringResource,    role: ButtonRole? = nil,    variant: FLXButtonVariant = .primary,    action: @escaping () -> Void)init<S: StringProtocol>(    _ title: S,    role: ButtonRole? = nil,    variant: FLXButtonVariant = .primary,    action: @escaping () -> Void)init(    _ titleKey: LocalizedStringKey,    systemImage: String,    role: ButtonRole? = nil,    variant: FLXButtonVariant = .primary,    action: @escaping () -> Void)init(    _ titleResource: LocalizedStringResource,    systemImage: String,    role: ButtonRole? = nil,    variant: FLXButtonVariant = .primary,    action: @escaping () -> Void)init<S: StringProtocol>(    _ title: S,    systemImage: String,    role: ButtonRole? = nil,    variant: FLXButtonVariant = .primary,    action: @escaping () -> Void)

Variants

CaseDescription
primaryFilled with theme.colors.primary.
outlineTransparent, bordered.
secondaryFilled with theme.colors.secondary.
ghostTransparent, no border.
linkText-only, styled like a hyperlink.

For more information about FLXButton props, see the Apple documentation.