fix: connection pill — revert to .principal, swap dot for state SF Symbol

Rolling back the .primaryAction placement (the pill shifted right and
lost its centered position in the toolbar). The "funny background with
shadow" visible in the toolbar is macOS's own .principal emphasis bezel
— not something Scarf draws, and not something we can cleanly hide
without disabling the toolbar surface itself. The native bezel is the
pill's frame; we just have to make the pill's interior read well inside
it.

Two changes to make the pill itself look like a toolbar tool inside
that bezel:

- Drop the colored dot, replace with a state-specific SF Symbol. The
  icon's shape signals clickability (looks like a tool button), and its
  color signals state (green/orange/yellow/red hierarchical). Less
  "status chip", more "toolbar button with status".
- Icons per state:
  - connected  → checkmark.circle.fill (click to re-probe)
  - degraded   → stethoscope (click to run diagnostics, matches the
                 stethoscope on the Manage Servers row)
  - idle       → arrow.triangle.2.circlepath (checking/retry)
  - error      → exclamationmark.triangle.fill (click for stderr)

Horizontal padding = 4 so the icon-and-label sit balanced inside the
bezel rather than pushed up against its edges.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alan Wizemann
2026-04-20 14:22:35 -07:00
parent ee1d705abc
commit d3055702ef
2 changed files with 27 additions and 13 deletions
+5 -6
View File
@@ -21,12 +21,11 @@ struct ContentView: View {
ServerSwitcherToolbar()
}
if serverContext.isRemote {
// `.principal` placement renders the item inside a
// centered emphasis bezel on macOS, which reads as
// an unwanted capsule-with-shadow around the pill.
// `.primaryAction` (right side of the toolbar) has
// no decorative background what we want.
ToolbarItem(placement: .primaryAction) {
// `.principal` centers the pill in the toolbar
// the native emphasis bezel is the intended frame;
// the pill's own visual content (icon + label, no
// background) sits inside it in balance.
ToolbarItem(placement: .principal) {
ConnectionStatusPill(status: connectionStatus)
}
}
@@ -23,18 +23,20 @@ struct ConnectionStatusPill: View {
status.retry()
}
} label: {
// No explicit background the SwiftUI toolbar gives the item
// its own bezel, and painting a second capsule on top looked
// doubly-framed. Just the colored dot + label reads cleanly.
HStack(spacing: 4) {
Circle()
.fill(color)
.frame(width: 8, height: 8)
// Leading SF Symbol does double duty: its color is the status
// signal (green/orange/yellow/red), and its shape reads as a
// clickable toolbar tool. No custom background the toolbar's
// `.principal` emphasis bezel is the frame.
HStack(spacing: 5) {
Image(systemName: iconName)
.foregroundStyle(color)
.symbolRenderingMode(.hierarchical)
Text(label)
.font(.caption)
.foregroundStyle(.secondary)
.lineLimit(1)
}
.padding(.horizontal, 4)
}
.buttonStyle(.plain)
.help(tooltip)
@@ -55,6 +57,19 @@ struct ConnectionStatusPill: View {
}
}
/// State-specific SF Symbol. The icon shape itself signals what the
/// click will do: checkmark for connected (click to re-probe),
/// stethoscope for degraded (click to run diagnostics), spinning
/// arrows for probing, triangle for error.
private var iconName: String {
switch status.status {
case .connected: return "checkmark.circle.fill"
case .degraded: return "stethoscope"
case .idle: return "arrow.triangle.2.circlepath"
case .error: return "exclamationmark.triangle.fill"
}
}
private var label: String {
switch status.status {
case .connected: return "Connected"