SidebarNavItemView.swift 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import SwiftUI
  2. struct SidebarNavItemView: View {
  3. let item: SidebarNavItem
  4. let isSelected: Bool
  5. let action: () -> Void
  6. var body: some View {
  7. Button(action: action) {
  8. SidebarItemRow(
  9. title: item.title,
  10. subtitle: item.subtitle,
  11. isSelected: isSelected
  12. ) {
  13. ModernSidebarIconView(kind: item.iconKind)
  14. }
  15. }
  16. .buttonStyle(.plain)
  17. }
  18. }
  19. struct SidebarQuickAccessItemView: View {
  20. let isSelected: Bool
  21. let action: () -> Void
  22. var body: some View {
  23. Button(action: action) {
  24. SidebarItemRow(
  25. title: "Open Reddit",
  26. subtitle: "Browse Reddit in-app",
  27. isSelected: isSelected,
  28. showsCardBackground: true,
  29. showsChevron: true,
  30. selectedBorderColor: AppTheme.accentPurple.opacity(0.4)
  31. ) {
  32. ModernRedditIconView()
  33. }
  34. }
  35. .buttonStyle(.plain)
  36. }
  37. }
  38. private struct SidebarItemRow<Icon: View>: View {
  39. let title: String
  40. let subtitle: String
  41. var isSelected: Bool = false
  42. var showsCardBackground: Bool = false
  43. var showsChevron: Bool = false
  44. var selectedBorderColor: Color = .clear
  45. @ViewBuilder let icon: () -> Icon
  46. var body: some View {
  47. HStack(alignment: .center, spacing: AppTheme.sidebarRowSpacing) {
  48. icon()
  49. .frame(width: AppTheme.iconContainerSize, height: AppTheme.iconContainerSize)
  50. VStack(alignment: .leading, spacing: 1) {
  51. Text(title)
  52. .font(.system(size: 12, weight: .semibold))
  53. .foregroundStyle(AppTheme.textPrimary)
  54. if !subtitle.isEmpty {
  55. Text(subtitle)
  56. .font(.system(size: 10))
  57. .foregroundStyle(AppTheme.textSecondary)
  58. }
  59. }
  60. .padding(.leading, 2)
  61. Spacer(minLength: 0)
  62. if showsChevron {
  63. Image(systemName: "chevron.right")
  64. .font(.system(size: 10, weight: .semibold))
  65. .foregroundStyle(AppTheme.textSecondary)
  66. }
  67. }
  68. .padding(.horizontal, AppTheme.sidebarRowPaddingH)
  69. .padding(.vertical, AppTheme.sidebarRowPaddingV)
  70. .contentShape(RoundedRectangle(cornerRadius: AppTheme.cornerRadiusSmall))
  71. .background(rowBackground)
  72. }
  73. @ViewBuilder
  74. private var rowBackground: some View {
  75. if showsCardBackground {
  76. RoundedRectangle(cornerRadius: AppTheme.cornerRadiusSmall)
  77. .fill(AppTheme.quickAccessBackground)
  78. .overlay(
  79. RoundedRectangle(cornerRadius: AppTheme.cornerRadiusSmall)
  80. .stroke(
  81. isSelected ? selectedBorderColor : AppTheme.cardBorder,
  82. lineWidth: 1
  83. )
  84. )
  85. } else if isSelected {
  86. RoundedRectangle(cornerRadius: AppTheme.cornerRadiusSmall)
  87. .fill(Color.white.opacity(0.05))
  88. }
  89. }
  90. }
  91. struct SidebarSectionHeader: View {
  92. let title: String
  93. var body: some View {
  94. Text(title)
  95. .font(.system(size: 10, weight: .bold))
  96. .foregroundStyle(AppTheme.textTertiary)
  97. .tracking(1.0)
  98. .frame(maxWidth: .infinity, alignment: .leading)
  99. .padding(.horizontal, AppTheme.sidebarRowPaddingH)
  100. .padding(.top, 5)
  101. .padding(.bottom, 4)
  102. }
  103. }