Просмотр исходного кода

Center the Check Grammar button and use a thinner text caret.

Group the button label and icons in the center, and replace the default TextEditor caret with a 1pt insertion point for a cleaner editing experience.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 1 месяц назад
Родитель
Сommit
d288650b37

+ 1 - 2
gramora/Views/Components/GradientButton.swift

@@ -12,8 +12,7 @@ struct GradientButton: View {
 
 
                 Text(title)
                 Text(title)
                     .font(.system(size: 16, weight: .semibold))
                     .font(.system(size: 16, weight: .semibold))
-
-                Spacer(minLength: 0)
+                    .textSelection(.disabled)
 
 
                 Image(systemName: "arrow.right")
                 Image(systemName: "arrow.right")
                     .font(.system(size: 14, weight: .semibold))
                     .font(.system(size: 14, weight: .semibold))

+ 72 - 0
gramora/Views/Components/ThinCaretTextEditor.swift

@@ -0,0 +1,72 @@
+import AppKit
+import SwiftUI
+
+private final class ThinCaretTextView: NSTextView {
+    private let caretWidth: CGFloat = 1
+
+    override func drawInsertionPoint(in rect: NSRect, color: NSColor, turnedOn flag: Bool) {
+        var caretRect = rect
+        caretRect.size.width = caretWidth
+        caretRect.origin.x += (rect.width - caretWidth) / 2
+        super.drawInsertionPoint(in: caretRect, color: color, turnedOn: flag)
+    }
+}
+
+struct ThinCaretTextEditor: NSViewRepresentable {
+    @Binding var text: String
+
+    func makeCoordinator() -> Coordinator {
+        Coordinator(parent: self)
+    }
+
+    func makeNSView(context: Context) -> NSScrollView {
+        let scrollView = NSScrollView()
+        scrollView.hasVerticalScroller = true
+        scrollView.hasHorizontalScroller = false
+        scrollView.autohidesScrollers = true
+        scrollView.borderType = .noBorder
+        scrollView.drawsBackground = false
+
+        let textView = ThinCaretTextView()
+        textView.isEditable = true
+        textView.isSelectable = true
+        textView.isRichText = false
+        textView.allowsUndo = true
+        textView.drawsBackground = false
+        textView.backgroundColor = .clear
+        textView.textContainer?.lineFragmentPadding = 0
+        textView.textContainerInset = NSSize(width: 0, height: 0)
+        textView.isAutomaticQuoteSubstitutionEnabled = false
+        textView.isAutomaticDashSubstitutionEnabled = false
+        textView.isAutomaticTextReplacementEnabled = false
+        textView.font = NSFont.systemFont(ofSize: 14)
+        textView.textColor = NSColor(AppTheme.textPrimary)
+        textView.delegate = context.coordinator
+        textView.string = text
+
+        scrollView.documentView = textView
+        context.coordinator.textView = textView
+        return scrollView
+    }
+
+    func updateNSView(_ scrollView: NSScrollView, context: Context) {
+        guard let textView = scrollView.documentView as? ThinCaretTextView else { return }
+        if textView.string != text {
+            textView.string = text
+        }
+    }
+
+    final class Coordinator: NSObject, NSTextViewDelegate {
+        var parent: ThinCaretTextEditor
+        weak var textView: NSTextView?
+
+        init(parent: ThinCaretTextEditor) {
+            self.parent = parent
+        }
+
+        func textDidChange(_ notification: Notification) {
+            guard let textView = notification.object as? NSTextView else { return }
+            parent.text = textView.string
+        }
+    }
+}

+ 1 - 1
gramora/Views/GrammarCheckerView.swift

@@ -69,7 +69,7 @@ struct GrammarCheckerView: View {
             }
             }
 
 
             ZStack(alignment: .bottomTrailing) {
             ZStack(alignment: .bottomTrailing) {
-                TextEditor(text: $viewModel.text)
+                ThinCaretTextEditor(text: $viewModel.text)
                     .font(.system(size: 14))
                     .font(.system(size: 14))
                     .foregroundStyle(AppTheme.textPrimary)
                     .foregroundStyle(AppTheme.textPrimary)
                     .scrollContentBackground(.hidden)
                     .scrollContentBackground(.hidden)