Переглянути джерело

Tighten Your Content header layout and remove the logo separator line.

Extract a shared header component with reduced card padding so input areas feel more compact without changing the logo size.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 1 місяць тому
батько
коміт
4cbee4a2ad

BIN
gramora/Resources/Assets.xcassets/YourContentLogo.imageset/YourContentLogo.png


+ 4 - 0
gramora/Utilities/AppTheme.swift

@@ -12,6 +12,10 @@ enum AppTheme {
     /// Extra top inset so the sidebar logo clears the window traffic lights.
     static let trafficLightClearance: CGFloat = 16
     static let contentPadding: CGFloat = 40
+    static let contentCardPadding: CGFloat = 14
+    static let contentCardTopPadding: CGFloat = 6
+    static let contentCardSpacing: CGFloat = 10
+    static let yourContentLogoHeight: CGFloat = 46
 
     static var sidebarLogoTopInset: CGFloat {
         headerTopInset + trafficLightClearance

+ 20 - 0
gramora/Views/Components/YourContentHeader.swift

@@ -0,0 +1,20 @@
+import SwiftUI
+
+struct YourContentHeader: View {
+    var body: some View {
+        Image("YourContentLogo")
+            .resizable()
+            .aspectRatio(contentMode: .fit)
+            .frame(height: AppTheme.yourContentLogoHeight, alignment: .topLeading)
+            .frame(maxWidth: .infinity, alignment: .leading)
+            .accessibilityLabel("Your Content")
+    }
+}
+
+extension View {
+    func inputContentCardPadding() -> some View {
+        padding(.top, AppTheme.contentCardTopPadding)
+            .padding(.horizontal, AppTheme.contentCardPadding)
+            .padding(.bottom, AppTheme.contentCardPadding)
+    }
+}

+ 4 - 10
gramora/Views/DictionaryView.swift

@@ -78,14 +78,8 @@ struct DictionaryView: View {
     }
 
     private var contentCard: some View {
-        VStack(alignment: .leading, spacing: 18) {
-            Image("YourContentLogo")
-                .resizable()
-                .aspectRatio(contentMode: .fit)
-                .frame(height: 52, alignment: .topLeading)
-                .frame(height: 46, alignment: .topLeading)
-                .clipped()
-                .accessibilityLabel("Your Content")
+        VStack(alignment: .leading, spacing: AppTheme.contentCardSpacing) {
+            YourContentHeader()
 
             searchField
 
@@ -103,7 +97,7 @@ struct DictionaryView: View {
                 recentSearchesSection
             }
         }
-        .padding(22)
+        .inputContentCardPadding()
         .background(AppTheme.cardBackground)
         .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius))
         .overlay(
@@ -269,7 +263,7 @@ struct DictionaryView: View {
                         meaningSection(meaning)
                     }
                 }
-                .padding(22)
+                .padding(AppTheme.contentCardPadding)
                 .background(AppTheme.cardBackground)
                 .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius))
                 .overlay(

+ 3 - 9
gramora/Views/GrammarCheckerView.swift

@@ -121,14 +121,8 @@ struct GrammarCheckerView: View {
     }
 
     private var contentCard: some View {
-        VStack(alignment: .leading, spacing: 16) {
-            Image("YourContentLogo")
-                .resizable()
-                .aspectRatio(contentMode: .fit)
-                .frame(height: 52, alignment: .topLeading)
-                .frame(height: 46, alignment: .topLeading)
-                .clipped()
-                .accessibilityLabel("Your Content")
+        VStack(alignment: .leading, spacing: AppTheme.contentCardSpacing) {
+            YourContentHeader()
 
             VStack(alignment: .leading, spacing: 6) {
                 ThinCaretTextEditor(
@@ -166,7 +160,7 @@ struct GrammarCheckerView: View {
                 }
             }
         }
-        .padding(22)
+        .inputContentCardPadding()
         .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
         .background(AppTheme.cardBackground)
         .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius))

+ 5 - 11
gramora/Views/JournalFinderView.swift

@@ -196,14 +196,8 @@ struct JournalFinderView: View {
     // MARK: - Input Card
 
     private func inputCard(abstractMinHeight: CGFloat) -> some View {
-        VStack(alignment: .leading, spacing: 18) {
-            Image("YourContentLogo")
-                .resizable()
-                .aspectRatio(contentMode: .fit)
-                .frame(height: 52, alignment: .topLeading)
-                .frame(height: 46, alignment: .topLeading)
-                .clipped()
-                .accessibilityLabel("Your Content")
+        VStack(alignment: .leading, spacing: AppTheme.contentCardSpacing) {
+            YourContentHeader()
 
             titleField
             abstractEditor(minHeight: abstractMinHeight)
@@ -221,7 +215,7 @@ struct JournalFinderView: View {
                 }
             }
         }
-        .padding(22)
+        .inputContentCardPadding()
         .frame(maxWidth: .infinity, alignment: .topLeading)
         .background(AppTheme.cardBackground)
         .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius))
@@ -336,7 +330,7 @@ struct JournalFinderView: View {
                 }
             }
         }
-        .padding(22)
+        .padding(AppTheme.contentCardPadding)
         .background(AppTheme.cardBackground)
         .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius))
         .overlay(
@@ -442,7 +436,7 @@ struct JournalFinderView: View {
                     .stroke(AppTheme.border.opacity(0.6), lineWidth: 1)
             )
         }
-        .padding(22)
+        .padding(AppTheme.contentCardPadding)
         .background(AppTheme.cardBackground)
         .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius))
         .overlay(

+ 3 - 9
gramora/Views/LanguageTranslatorView.swift

@@ -80,14 +80,8 @@ struct LanguageTranslatorView: View {
     }
 
     private var contentCard: some View {
-        VStack(alignment: .leading, spacing: 16) {
-            Image("YourContentLogo")
-                .resizable()
-                .aspectRatio(contentMode: .fit)
-                .frame(height: 52, alignment: .topLeading)
-                .frame(height: 46, alignment: .topLeading)
-                .clipped()
-                .accessibilityLabel("Your Content")
+        VStack(alignment: .leading, spacing: AppTheme.contentCardSpacing) {
+            YourContentHeader()
 
             sourcePanel
                 .frame(maxHeight: .infinity)
@@ -108,7 +102,7 @@ struct LanguageTranslatorView: View {
                 .fixedSize(horizontal: false, vertical: true)
         }
         .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
-        .padding(22)
+        .inputContentCardPadding()
         .background(AppTheme.cardBackground)
         .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius))
         .overlay(

+ 4 - 10
gramora/Views/ParaphrasingView.swift

@@ -109,14 +109,8 @@ struct ParaphrasingView: View {
     }
 
     private var contentCard: some View {
-        VStack(alignment: .leading, spacing: 16) {
-            Image("YourContentLogo")
-                .resizable()
-                .aspectRatio(contentMode: .fit)
-                .frame(height: 52, alignment: .topLeading)
-                .frame(height: 46, alignment: .topLeading)
-                .clipped()
-                .accessibilityLabel("Your Content")
+        VStack(alignment: .leading, spacing: AppTheme.contentCardSpacing) {
+            YourContentHeader()
 
             VStack(alignment: .leading, spacing: 6) {
                 ThinCaretTextEditor(
@@ -154,7 +148,7 @@ struct ParaphrasingView: View {
                 }
             }
         }
-        .padding(22)
+        .inputContentCardPadding()
         .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
         .background(AppTheme.cardBackground)
         .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius))
@@ -191,7 +185,7 @@ struct ParaphrasingView: View {
                         .stroke(AppTheme.teal.opacity(0.2), lineWidth: 1)
                 )
         }
-        .padding(22)
+        .padding(AppTheme.contentCardPadding)
         .background(AppTheme.cardBackground)
         .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius))
         .overlay(

+ 4 - 10
gramora/Views/PunctuationCheckerView.swift

@@ -109,14 +109,8 @@ struct PunctuationCheckerView: View {
     }
 
     private var contentCard: some View {
-        VStack(alignment: .leading, spacing: 16) {
-            Image("YourContentLogo")
-                .resizable()
-                .aspectRatio(contentMode: .fit)
-                .frame(height: 52, alignment: .topLeading)
-                .frame(height: 46, alignment: .topLeading)
-                .clipped()
-                .accessibilityLabel("Your Content")
+        VStack(alignment: .leading, spacing: AppTheme.contentCardSpacing) {
+            YourContentHeader()
 
             VStack(alignment: .leading, spacing: 6) {
                 ThinCaretTextEditor(
@@ -154,7 +148,7 @@ struct PunctuationCheckerView: View {
                 }
             }
         }
-        .padding(22)
+        .inputContentCardPadding()
         .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
         .background(AppTheme.cardBackground)
         .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius))
@@ -191,7 +185,7 @@ struct PunctuationCheckerView: View {
                         .stroke(AppTheme.teal.opacity(0.2), lineWidth: 1)
                 )
         }
-        .padding(22)
+        .padding(AppTheme.contentCardPadding)
         .background(AppTheme.cardBackground)
         .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius))
         .overlay(

+ 3 - 9
gramora/Views/SpellCheckerView.swift

@@ -121,14 +121,8 @@ struct SpellCheckerView: View {
     }
 
     private var contentCard: some View {
-        VStack(alignment: .leading, spacing: 16) {
-            Image("YourContentLogo")
-                .resizable()
-                .aspectRatio(contentMode: .fit)
-                .frame(height: 52, alignment: .topLeading)
-                .frame(height: 46, alignment: .topLeading)
-                .clipped()
-                .accessibilityLabel("Your Content")
+        VStack(alignment: .leading, spacing: AppTheme.contentCardSpacing) {
+            YourContentHeader()
 
             VStack(alignment: .leading, spacing: 6) {
                 ThinCaretTextEditor(
@@ -166,7 +160,7 @@ struct SpellCheckerView: View {
                 }
             }
         }
-        .padding(22)
+        .inputContentCardPadding()
         .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
         .background(AppTheme.cardBackground)
         .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius))

+ 4 - 10
gramora/Views/SummarizerView.swift

@@ -109,14 +109,8 @@ struct SummarizerView: View {
     }
 
     private var contentCard: some View {
-        VStack(alignment: .leading, spacing: 16) {
-            Image("YourContentLogo")
-                .resizable()
-                .aspectRatio(contentMode: .fit)
-                .frame(height: 52, alignment: .topLeading)
-                .frame(height: 46, alignment: .topLeading)
-                .clipped()
-                .accessibilityLabel("Your Content")
+        VStack(alignment: .leading, spacing: AppTheme.contentCardSpacing) {
+            YourContentHeader()
 
             VStack(alignment: .leading, spacing: 6) {
                 ThinCaretTextEditor(
@@ -154,7 +148,7 @@ struct SummarizerView: View {
                 }
             }
         }
-        .padding(22)
+        .inputContentCardPadding()
         .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
         .background(AppTheme.cardBackground)
         .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius))
@@ -191,7 +185,7 @@ struct SummarizerView: View {
                         .stroke(AppTheme.teal.opacity(0.2), lineWidth: 1)
                 )
         }
-        .padding(22)
+        .padding(AppTheme.contentCardPadding)
         .background(AppTheme.cardBackground)
         .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius))
         .overlay(

+ 3 - 9
gramora/Views/WordsCountView.swift

@@ -62,14 +62,8 @@ struct WordsCountView: View {
     }
 
     private var contentCard: some View {
-        VStack(alignment: .leading, spacing: 16) {
-            Image("YourContentLogo")
-                .resizable()
-                .aspectRatio(contentMode: .fit)
-                .frame(height: 52, alignment: .topLeading)
-                .frame(height: 46, alignment: .topLeading)
-                .clipped()
-                .accessibilityLabel("Your Content")
+        VStack(alignment: .leading, spacing: AppTheme.contentCardSpacing) {
+            YourContentHeader()
 
             Text(viewModel.wordCountLabel)
                 .font(.system(size: 18, weight: .semibold))
@@ -115,7 +109,7 @@ struct WordsCountView: View {
             }
         }
         .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
-        .padding(22)
+        .inputContentCardPadding()
         .background(AppTheme.cardBackground)
         .clipShape(RoundedRectangle(cornerRadius: AppTheme.cardCornerRadius))
         .overlay(