Button

A control that initiates an action when pressed.

Overview

Buttons are one of the most common UI elements. They trigger actions when tapped, like submitting forms, navigating to another screen, or performing operations.

Basic Usage

Button {
    print("Button pressed!")
} child: {
    Text("Click Me")
}

The first closure is the action handler, the child: closure is the button content.

Button Examples

Button Roles

Buttons can have different roles that affect their appearance:

// Primary (default) - Main actions
Button(role: .primary) {
    // action
} child: {
    Text("Save")
}

// Secondary - Less prominent actions
Button(role: .secondary) {
    // action
} child: {
    Text("Cancel")
}

// Destructive - Dangerous actions
Button(role: .destructive) {
    // action
} child: {
    Text("Delete")
}

// Cancel - Cancel operations
Button(role: .cancel) {
    // action
} child: {
    Text("Cancel")
}

// Link - Acts like a hyperlink
Button(role: .link) {
    // action
} child: {
    Text("Learn More")
}

Disabled State

Pass nil for onPressed to disable the button:

Button(onPressed: nil) {
    Text("Disabled")
}

With Icon

Add an icon next to the button label:

Button(
    icon: Text("→"),  // or use ShaftLucide icons
    role: .primary
) {
    print("Next")
} child: {
    Text("Next")
}

Selected State

Buttons can show a selected state:

Button(isSelected: true) {
    // action
} child: {
    Text("Selected")
}

Useful for toggle buttons or tab-like interfaces.

Custom Styling

Create custom button styles by conforming to Button.Style:

struct CustomButtonStyle: Button.Style {
    func build(context: any Button.StyleContext) -> any Widget {
        context.child
            .textStyle(.init(color: Color(0xFF_FFFFFF)))
            .padding(.all(16))
            .decoration(.box(
                color: context.isPressed 
                    ? Color(0xFF_FF6B6B)
                    : Color(0xFF_FF8787),
                borderRadius: .circular(8)
            ))
    }
}

// Apply to a button
Button { } child: { Text("Custom") }
    .buttonStyle(CustomButtonStyle())

// Apply to all descendant buttons
Column {
    Button { } child: { Text("Button 1") }
    Button { } child: { Text("Button 2") }
}
.buttonStyle(CustomButtonStyle())

Control Size

Adjust button size using ControlSize:

Column {
    Button { } child: { Text("Mini") }
    Button { } child: { Text("Small") }
    Button { } child: { Text("Regular") }
    Button { } child: { Text("Large") }
}
.controlSize(.mini)   // or .small, .regular, .large

Parameters

ParameterTypeDescription
iconWidget?Optional icon displayed alongside label
roleButtonRoleVisual role of the button (.primary, .secondary, etc.)
isSelectedBoolWhether button is in selected state
onPressedVoidCallback?Action when pressed. nil disables the button
childWidgetButton content (usually Text)

See Also