Develop
Develop
Select your platform

Button

Updated: Oct 7, 2024

Overview

Buttons initiate actions based on user interaction. The Meta Horizon OS UI Set provides several button variants and types to cover common use cases in spatial interfaces. All buttons support standard interaction states (default, hover, pressed, disabled) and utilize the SpatialTheme for styling.
Shows both the button UI code and how buttons are rendered.

Common features

  • Interaction feedback: Provide visual feedback on hover and press (slight background change, scaling).
  • Theming: Colors, shapes, and typography are derived from SpatialTheme.
  • Accessibility: Designed with minimum target sizes in mind (though exact hit target implementation depends on Compose behavior).
  • isEnabled parameter: Controls interactability and visual state.

Button variants

These define the primary visual style and semantic meaning.

Primary button

  • Composable: PrimaryButton, PrimaryIconButton, PrimaryCircleButton
  • Usage: For the most common or recommended action on a surface (for example, “Done”, “Confirm”, “Save”). High emphasis.
  • Appearance: Typically uses the theme’s primaryButton background color and primaryOpaqueButton foreground color.
import com.meta.spatial.uiset.button.PrimaryButton
import com.meta.spatial.uiset.button.PrimaryCircleButton
import com.meta.spatial.uiset.theme.icons.SpatialIcons
import com.meta.spatial.uiset.theme.icons.regular.Chat
import androidx.compose.material3.Icon

// Label Only
PrimaryButton(label = "Confirm", onClick = { /* ... */ })

// Icon and Label
PrimaryButton(
    label = "Message",
    leading = { Icon(SpatialIcons.Regular.Chat, null) },
    onClick = { /* ... */ }
)

// Icon Only (Circle)
PrimaryCircleButton(
    icon = { Icon(SpatialIcons.Regular.Chat, null) },
    onClick = { /* ... */ }
)

// Disabled
PrimaryButton(label = "Confirm", onClick = { /* ... */ }, isEnabled = false)

Secondary button

  • Composable: SecondaryButton, SecondaryIconButton, SecondaryCircleButton
  • Usage: For medium-emphasis actions, inverse actions (for example, “Cancel”, “Remove”), or supporting actions.
  • Appearance: Typically uses the theme’s secondaryButton background color and primaryAlphaBackground foreground color.
import com.meta.spatial.uiset.button.SecondaryButton
// ... other imports

// Label Only
SecondaryButton(label = "Cancel", onClick = { /* ... */ })

// Icon and Label
SecondaryButton(
    label = "See More",
    leading = { Icon(SpatialIcons.Regular.ChevronDown, null) },
    onClick = { /* ... */ }
)

// Icon Only (Circle)
SecondaryCircleButton(
    icon = { Icon(SpatialIcons.Regular.MoreHorizontal, null) },
    onClick = { /* ... */ }
)

Borderless button

  • Composable: BorderlessButton, BorderlessIconButton, BorderlessCircleButton
  • Usage: For low-emphasis actions, often used in toolbars or when multiple less-critical actions are present.
  • Appearance: Transparent background, uses primaryAlphaBackground for foreground color.
import com.meta.spatial.uiset.button.BorderlessButton
// ... other imports

// Label Only
BorderlessButton(label = "Learn More", onClick = { /* ... */ })

// Icon and Label
BorderlessButton(
    label = "Settings",
    leading = { Icon(SpatialIcons.Regular.Settings, null) },
    onClick = { /* ... */ }
)

// Icon Only (Circle)
BorderlessCircleButton(
    icon = { Icon(SpatialIcons.Regular.Close, null) },
    onClick = { /* ... */ }
)

Destructive button

  • Composable: DestructiveButton, DestructiveIconButton, DestructiveCircleButton
  • Usage: For actions that result in data loss or significant irreversible changes (for example, “Delete”, “End Call”). The color warns the user.
  • Appearance: Uses the theme’s negativeButton background color and primaryOpaqueButton foreground color.
import com.meta.spatial.uiset.button.DestructiveButton
// ... other imports

// Label Only
DestructiveButton(label = "Delete", onClick = { /* ... */ })

// Icon and Label
DestructiveButton(
    label = "End Call",
    leading = { Icon(SpatialIcons.Regular.CallEnd, null) },
    onClick = { /* ... */ }
)

// Icon Only (Circle)
DestructiveCircleButton(
    icon = { Icon(SpatialIcons.Regular.Trash, null) },
    onClick = { /* ... */ }
)

Button types (layout variations)

These components use the underlying button variants but arrange content differently.

Text tile button

  • Composable: TextTileButton
  • Usage: Often used in grids or lists for selectable items, representing entities like files, apps, or options. Has a distinct selected state.
  • Layout: Stacked layout, can contain an icon, primary label, and optional secondary label.
  • State: Uses selected: Boolean and onSelectionChange: (Boolean) -> Unit props. Background and foreground colors change based on selection state (using TextTileButtonDefaults).
import com.meta.spatial.uiset.button.TextTileButton
// ... other imports

var isSelected by remember { mutableStateOf(false) }

TextTileButton(
    label = "Document Title",
    secondaryLabel = "Edited 2 hours ago",
    icon = { Icon(SpatialIcons.Regular.Document, null) },
    selected = isSelected,
    onSelectionChange = { isSelected = it } // Often !isSelected
)

Button shelf

  • Composable: ButtonShelf
  • Usage: Typically used in horizontal rows (like a “shelf”) for quick actions or toggles, often in system UIs or toolbars.
  • Layout: Stacked icon-over-label layout within a fixed size.
  • State: Uses selected: Boolean and onSelectionChange: (Boolean) -> Unit props. Background and foreground colors change based on selection state (using ButtonShelfDefaults).
import com.meta.spatial.uiset.button.ButtonShelf
// ... other imports

var isMicOn by remember { mutableStateOf(false) }

ButtonShelf(
    label = "Microphone",
    icon = { Icon(SpatialIcons.Regular.MicrophoneOn, null) }, // Icon might change based on state too
    selected = isMicOn,
    onSelectionChange = { isMicOn = it }
)

Common parameters

  • onClick: () -> Unit: Lambda executed when the button is clicked (for non-selectable buttons).
  • onSelectionChange: (Boolean) -> Unit: Lambda executed when a selectable button’s state changes.
  • label: String: The primary text displayed.
  • leading: @Composable (() -> Unit)?: Composable for an icon placed before the label (for standard button variants).
  • icon: @Composable (() -> Unit): Composable for the icon (required for icon buttons, ButtonShelf, optional for TextTileButton).
  • secondaryLabel: String?: Optional secondary text (for TextTileButton).
  • isEnabled: Boolean = true: Controls interactability.
  • selected: Boolean = false: Current selection state (for TextTileButton, ButtonShelf).
  • expanded: Boolean = false: If true, the button attempts to fill the available width (for standard button variants).
  • modifier: Modifier = Modifier: Standard Compose modifier.
Choose the appropriate button variant and type based on the action’s emphasis, function (action vs. selection), and required layout.
Did you find this page helpful?