Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions Sources/Luminare/Components/Composes/LuminareButtonRow.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
//
// LuminareButtonRow.swift
// Luminare
//
// Created by Adon Omeri on 23/3/2026.
//

import SwiftUI

@resultBuilder
public struct LuminareButtonBuilder {
public static func buildExpression(_ expression: some View) -> [AnyView] {
[AnyView(expression)]
}

public static func buildBlock(_ components: [AnyView]...) -> [AnyView] {
components.flatMap(\.self)
}

public static func buildOptional(_ component: [AnyView]?) -> [AnyView] {
component ?? []
}

public static func buildEither(first component: [AnyView]) -> [AnyView] {
component
}

public static func buildEither(second component: [AnyView]) -> [AnyView] {
component
}

public static func buildArray(_ components: [[AnyView]]) -> [AnyView] {
components.flatMap(\.self)
}

public static func buildLimitedAvailability(_ component: [AnyView]) -> [AnyView] {
component
}
}

public struct LuminareButtonRow: View {
@Environment(\.luminareButtonComposeSpacing) private var spacing

@Environment(\.luminareTopLeadingRounded) private var topLeadingRounded
@Environment(\.luminareTopTrailingRounded) private var topTrailingRounded
@Environment(\.luminareBottomLeadingRounded) private var bottomLeadingRounded
@Environment(\.luminareBottomTrailingRounded) private var bottomTrailingRounded

private let buttons: [AnyView]

public init(
@LuminareButtonBuilder _ buttons: () -> [AnyView]
) {
self.buttons = buttons()
}

public var body: some View {
HStack(spacing: spacing) {
ForEach(buttons.indices, id: \.self) { index in
let button = buttons[index]
let isFirst = index == 0
let isLast = index == buttons.count - 1

button
.luminareRoundingBehavior(
topLeading: isFirst ? topLeadingRounded : false,
topTrailing: isLast ? topTrailingRounded : false,
bottomLeading: isFirst ? bottomLeadingRounded : false,
bottomTrailing: isLast ? bottomTrailingRounded : false
)
}
}
.buttonStyle(.luminare)
}
}

// MARK: - Preview

@available(macOS 15.0, *)
#Preview(
"LuminareButtonRow",
traits: .sizeThatFitsLayout
) {
LuminarePane {
LuminareSection {
LuminareButtonRow {
Button {
print(1)
} label: {
Text("Button 1")
}

Button {
print(2)
} label: {
Text("Button 2")
}

Button {
print(3)
} label: {
Text("Button 3")
}
}
.luminareRoundingBehavior(top: true)

Text("Other content ...")
.foregroundStyle(.secondary)
}
}
}
3 changes: 1 addition & 2 deletions Sources/Luminare/Components/Stepper/LuminareStepper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -440,8 +440,7 @@ public struct LuminareStepper<V>: View where V: Strideable & BinaryFloatingPoint

private func magnifyFactor(at index: Int) -> CGFloat {
let standardDeviation = 0.5
let value = bellCurve(shift(at: index), standardDeviation: standardDeviation)
return value
return bellCurve(shift(at: index), standardDeviation: standardDeviation)
}

private func blurFactor(at index: Int) -> CGFloat {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# ``Luminare/LuminareButtonRow``

A horizontalrow of Luminare buttons.



@Row {
@Column {
```swift
LuminareButtonRow {
Button {
print(1)
} label: {
Text("Button 1")
}

Button {
print(2)
} label: {
Text("Button 2")
}

Button {
print(3)
} label: {
Text("Button 3")
}
}
```
}
}

@Row {
@Column {
![LuminareButtonRow](LuminareButtonRow)
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import AppKit
import SwiftUI

/// A shorthand for storing colors in hue-saturation-brightness format
struct HSBColor: Equatable, Hashable, Codable, Sendable {
struct HSBColor: Equatable, Hashable, Codable {
var hue: Double
var saturation: Double
var brightness: Double
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ public extension EnvironmentValues {
/// If 0, then luminareSection will be of fixed size.
@Entry var luminareSectionMaxWidth: CGFloat? = .infinity

// MARK: Button Compose

@Entry var luminareButtonComposeSpacing: CGFloat = 4

// MARK: Compose

@Entry var luminareComposeControlSize: LuminareComposeControlSize = .automatic
Expand Down
6 changes: 6 additions & 0 deletions Sources/Luminare/Utilities/Extensions/View+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,12 @@ public extension View {
)
}

Comment thread
omeriadon marked this conversation as resolved.
// MARK: Button Compose

func luminareButtonComposeSpacing(_ spacing: CGFloat) -> some View {
environment(\.luminareButtonComposeSpacing, spacing)
}

// MARK: Tool Tip

func luminareToolTipTrigger(_ trigger: LuminareToolTipTrigger) -> some View {
Expand Down
Loading