// // Copyright 2025 Element Creations Ltd. // Copyright 2023-2025 New Vector Ltd. // // SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. // Please see LICENSE files in the repository root for full details. // import Compound import SwiftUI struct FormattingToolbar: View { /// The list of items to render in the toolbar var formatItems: [FormatItem] /// The action when an item is selected var formatAction: (FormatType) -> Void var body: some View { ScrollView(.horizontal) { HStack(spacing: 5) { ForEach(formatItems) { item in Button { formatAction(item.type) } label: { CompoundIcon(item.icon, size: .small, relativeTo: .compound.headingLG) .foregroundColor(item.foregroundColor) .padding(8) .background(item.backgroundColor) .cornerRadius(8) .padding(.vertical, Compound.supportsGlass ? 10 : 3) } .disabled(item.state == .disabled) .accessibilityIdentifier(item.accessibilityIdentifier) .accessibilityLabel(item.accessibilityLabel) } } } } } private extension FormatItem { var foregroundColor: Color { switch state { case .reversed: return .compound.iconAccentPrimary case .enabled: return .compound.iconSecondary case .disabled: return .compound.iconDisabled } } var backgroundColor: Color { switch state { case .reversed: return .compound.bgAccentSelected case .enabled, .disabled: return .compound.bgCanvasDefault } } } struct FormattingToolbar_Previews: PreviewProvider, TestablePreview { static let items = FormatType.allCases.map { FormatItem(type: $0, state: .enabled) } static let reversedItems = FormatType.allCases.map { FormatItem(type: $0, state: .reversed) } static let disabledItems = FormatType.allCases.map { FormatItem(type: $0, state: .disabled) } static var previews: some View { VStack(spacing: 16.0) { FormattingToolbar(formatItems: items) { _ in } FormattingToolbar(formatItems: reversedItems) { _ in } FormattingToolbar(formatItems: disabledItems) { _ in } } } }