| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- import SwiftUI
- protocol SegmentedTabItem: Hashable, Identifiable, CaseIterable {
- var title: String { get }
- }
- extension CommentWriterTab: SegmentedTabItem {}
- extension PostGeneratorTab: SegmentedTabItem {}
- extension TitleOptimizerTab: SegmentedTabItem {}
- struct ToolSegmentedTabBar<Tab: SegmentedTabItem>: View {
- @Binding var selection: Tab
- var accentColor: Color
- var width: CGFloat
- var badgeCount: ((Tab) -> Int?)?
- private let buttonCornerRadius: CGFloat = 8
- var body: some View {
- HStack(spacing: 6) {
- ForEach(Array(Tab.allCases)) { tab in
- tabButton(for: tab)
- }
- }
- .frame(width: width)
- }
- private func tabButton(for tab: Tab) -> some View {
- let isSelected = selection == tab
- return Button {
- withAnimation(.easeInOut(duration: 0.15)) {
- selection = tab
- }
- } label: {
- HStack(spacing: 4) {
- Text(tab.title)
- .font(.system(size: 11, weight: isSelected ? .bold : .medium))
- if let count = badgeCount?(tab) {
- Text("\(count)")
- .font(.system(size: 9, weight: .bold))
- .foregroundStyle(.white)
- .padding(.horizontal, 5)
- .padding(.vertical, 2)
- .background(accentColor)
- .clipShape(Capsule())
- }
- }
- .foregroundStyle(isSelected ? accentColor : AppTheme.textSecondary)
- .frame(maxWidth: .infinity)
- .padding(.vertical, 7)
- .background(
- RoundedRectangle(cornerRadius: buttonCornerRadius, style: .continuous)
- .fill(isSelected ? accentColor.opacity(0.12) : AppTheme.cardBackground)
- )
- .overlay(
- RoundedRectangle(cornerRadius: buttonCornerRadius, style: .continuous)
- .stroke(
- isSelected ? accentColor.opacity(0.5) : AppTheme.cardBorder,
- lineWidth: isSelected ? 1.5 : 1
- )
- )
- .shadow(
- color: accentColor.opacity(isSelected ? 0.15 : 0),
- radius: 2,
- y: 1
- )
- }
- .buttonStyle(.plain)
- .hoverCursor()
- .hoverOverlay(cornerRadius: buttonCornerRadius, isEnabled: !isSelected)
- }
- }
|