Sfoglia il codice sorgente

Restyle the model selector as a bordered dropdown button with name left and chevron right.

Replace the native Menu control with a button and popover so macOS no longer injects a leading chevron and the picker layout matches the intended toolbar design.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 3 settimane fa
parent
commit
4398e36ec1
1 ha cambiato i file con 56 aggiunte e 18 eliminazioni
  1. 56 18
      clone _of_clarus_ai_chat_bot/Views/ModelSelectorMenu.swift

+ 56 - 18
clone _of_clarus_ai_chat_bot/Views/ModelSelectorMenu.swift

@@ -2,43 +2,81 @@ import SwiftUI
 
 struct ModelSelectorMenu: View {
     @ObservedObject var viewModel: HomeViewModel
+    @State private var isHovered = false
+    @State private var isPresented = false
 
     var body: some View {
-        Menu {
-            ForEach(viewModel.availableModels) { model in
-                Button {
-                    viewModel.selectedModel = model
-                } label: {
-                    if model.isPremium {
-                        Label(model.name, systemImage: "crown.fill")
-                    } else {
-                        Text(model.name)
-                    }
-                }
-            }
+        Button {
+            isPresented.toggle()
         } label: {
             labelContent
         }
-        .menuStyle(.borderlessButton)
+        .buttonStyle(.plain)
         .fixedSize()
+        .onHover { isHovered = $0 }
+        .popover(isPresented: $isPresented, arrowEdge: .bottom) {
+            modelPickerList
+                .frame(minWidth: 196)
+        }
         .accessibilityLabel("Selected model, \(viewModel.selectedModel.name)")
+        .accessibilityHint("Opens model picker")
     }
 
     private var labelContent: some View {
-        HStack(spacing: 5) {
+        HStack(spacing: 6) {
             Text(viewModel.selectedModel.name)
-                .font(.system(size: 13, weight: .semibold))
+                .font(.system(size: 12, weight: .semibold))
                 .foregroundStyle(AppTheme.textPrimary)
+                .lineLimit(1)
 
             Image(systemName: "chevron.down")
-                .font(.system(size: 9, weight: .bold))
+                .font(.system(size: 9, weight: .semibold))
                 .foregroundStyle(AppTheme.textSecondary)
         }
         .padding(.horizontal, 12)
-        .padding(.vertical, 7)
+        .padding(.vertical, 8)
         .background(
             RoundedRectangle(cornerRadius: 10, style: .continuous)
-                .fill(AppTheme.chatToolbarPillBackground)
+                .fill(isHovered ? AppTheme.controlBackground : Color.white)
         )
+        .overlay(
+            RoundedRectangle(cornerRadius: 10, style: .continuous)
+                .stroke(AppTheme.chatActionButtonBorder, lineWidth: 1)
+        )
+        .contentShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
+    }
+
+    private var modelPickerList: some View {
+        VStack(alignment: .leading, spacing: 2) {
+            ForEach(viewModel.availableModels) { model in
+                Button {
+                    viewModel.selectedModel = model
+                    isPresented = false
+                } label: {
+                    HStack(spacing: 8) {
+                        if model.isPremium {
+                            Label(model.name, systemImage: "crown.fill")
+                        } else {
+                            Text(model.name)
+                        }
+
+                        Spacer(minLength: 12)
+
+                        if viewModel.selectedModel == model {
+                            Image(systemName: "checkmark")
+                                .font(.system(size: 11, weight: .bold))
+                        }
+                    }
+                    .font(.system(size: 13))
+                    .foregroundStyle(AppTheme.textPrimary)
+                    .padding(.horizontal, 12)
+                    .padding(.vertical, 7)
+                    .frame(maxWidth: .infinity, alignment: .leading)
+                    .contentShape(Rectangle())
+                }
+                .buttonStyle(.plain)
+            }
+        }
+        .padding(.vertical, 6)
     }
 }