75 lines
2.4 KiB
Swift
75 lines
2.4 KiB
Swift
|
|
// CompletionPopover.swift
|
||
|
|
// CompletionItem lives in Shared/SharedModels.swift — not redeclared here.
|
||
|
|
import SwiftUI
|
||
|
|
|
||
|
|
struct CompletionPopover: View {
|
||
|
|
let items: [CompletionItem]
|
||
|
|
let onSelect: (CompletionItem) -> Void
|
||
|
|
@State private var selected: UUID?
|
||
|
|
|
||
|
|
var body: some View {
|
||
|
|
VStack(spacing: 0) {
|
||
|
|
ForEach(items.prefix(8)) { item in
|
||
|
|
CompletionRow(
|
||
|
|
item: item,
|
||
|
|
isSelected: item.id == selected,
|
||
|
|
onSelect: {
|
||
|
|
selected = item.id
|
||
|
|
onSelect(item)
|
||
|
|
}
|
||
|
|
)
|
||
|
|
if item.id != items.prefix(8).last?.id {
|
||
|
|
Divider().padding(.leading, 32)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
.background(.regularMaterial)
|
||
|
|
.clipShape(RoundedRectangle(cornerRadius: 8))
|
||
|
|
.shadow(color: .black.opacity(0.25), radius: 12, x: 0, y: 4)
|
||
|
|
.frame(width: 340)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
struct CompletionRow: View {
|
||
|
|
let item: CompletionItem
|
||
|
|
let isSelected: Bool
|
||
|
|
let onSelect: () -> Void
|
||
|
|
|
||
|
|
var body: some View {
|
||
|
|
Button(action: onSelect) {
|
||
|
|
HStack(spacing: 8) {
|
||
|
|
Image(systemName: item.symbolIcon)
|
||
|
|
.font(.system(size: 12))
|
||
|
|
.frame(width: 20)
|
||
|
|
.foregroundStyle(symbolColor(for: item.kind))
|
||
|
|
VStack(alignment: .leading, spacing: 1) {
|
||
|
|
Text(item.label)
|
||
|
|
.font(.system(.body, design: .monospaced))
|
||
|
|
.foregroundStyle(.primary)
|
||
|
|
if !item.detail.isEmpty {
|
||
|
|
Text(item.detail)
|
||
|
|
.font(.system(.caption2, design: .monospaced))
|
||
|
|
.foregroundStyle(.secondary)
|
||
|
|
.lineLimit(1)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
Spacer()
|
||
|
|
}
|
||
|
|
.padding(.horizontal, 10)
|
||
|
|
.padding(.vertical, 6)
|
||
|
|
.background(isSelected ? Color.accentColor.opacity(0.15) : .clear)
|
||
|
|
}
|
||
|
|
.buttonStyle(.plain)
|
||
|
|
}
|
||
|
|
|
||
|
|
private func symbolColor(for kind: Int) -> Color {
|
||
|
|
switch kind {
|
||
|
|
case 2, 3: return .purple
|
||
|
|
case 6: return .blue
|
||
|
|
case 7: return .orange
|
||
|
|
case 8: return .teal
|
||
|
|
default: return .secondary
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|