SidebarNavItemView.swift 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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. Text(subtitle)
  55. .font(.system(size: 10))
  56. .foregroundStyle(AppTheme.textSecondary)
  57. }
  58. .padding(.leading, 2)
  59. Spacer(minLength: 0)
  60. if showsChevron {
  61. Image(systemName: "chevron.right")
  62. .font(.system(size: 10, weight: .semibold))
  63. .foregroundStyle(AppTheme.textSecondary)
  64. }
  65. }
  66. .padding(.horizontal, AppTheme.sidebarRowPaddingH)
  67. .padding(.vertical, AppTheme.sidebarRowPaddingV)
  68. .contentShape(RoundedRectangle(cornerRadius: AppTheme.cornerRadiusSmall))
  69. .background(rowBackground)
  70. }
  71. @ViewBuilder
  72. private var rowBackground: some View {
  73. if showsCardBackground {
  74. RoundedRectangle(cornerRadius: AppTheme.cornerRadiusSmall)
  75. .fill(AppTheme.quickAccessBackground)
  76. .overlay(
  77. RoundedRectangle(cornerRadius: AppTheme.cornerRadiusSmall)
  78. .stroke(
  79. isSelected ? selectedBorderColor : AppTheme.cardBorder,
  80. lineWidth: 1
  81. )
  82. )
  83. } else if isSelected {
  84. RoundedRectangle(cornerRadius: AppTheme.cornerRadiusSmall)
  85. .fill(Color.white.opacity(0.05))
  86. }
  87. }
  88. }
  89. struct SidebarSectionHeader: View {
  90. let title: String
  91. var body: some View {
  92. Text(title)
  93. .font(.system(size: 10, weight: .bold))
  94. .foregroundStyle(AppTheme.textTertiary)
  95. .tracking(1.0)
  96. .frame(maxWidth: .infinity, alignment: .leading)
  97. .padding(.horizontal, AppTheme.sidebarRowPaddingH)
  98. .padding(.top, 5)
  99. .padding(.bottom, 4)
  100. }
  101. }