Fix opaque solid-blue tab bar and MCP sidebar row (glassEffect misuse)
Rune caught this live: the selected MCP tab and "External MCP" sidebar
row rendered as solid opaque blue blocks completely hiding their
icon/label. Root cause: .glassEffect() was nested inside a
.background { } closure applied to a plain Color.clear placeholder,
which isn't how the API is meant to be used — it needs to wrap the real
content directly (as the skill's own examples show), not sit behind it
as an opaque background layer.
Also discovered the skill's documented isEnabled: parameter on
glassEffect(_:in:isEnabled:) isn't available on this SDK build
("extra argument in call") — worked around by branching the view
instead of using that parameter.
Since tabButton/mcpSidebarRow are actual Buttons, switched to the
more correct approach for buttons specifically: native
.buttonStyle(.glass)/.buttonStyle(.glassProminent) for the tab bar
(matching the skill's textbook button pattern) rather than hand-applying
.glassEffect() to custom content. mcpSidebarRow needed to stay on
direct .glassEffect() application (not button styles) since its row
needs to stretch full-width via a trailing Spacer(), which glass
button styles don't support — but applied directly to the real HStack
content this time, branched via if/else, not nested in .background.
Note for the next Rune check: native glass buttons add ~13pt of their
own internal padding, so manual padding was reduced/dropped on
tabButton's label — sizing may look different than before, adjust if
too large/small.
This commit is contained in:
@@ -637,21 +637,11 @@ It's better to admit "I need more information" or "I cannot do that" than to fak
|
|||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private func mcpSidebarRow(_ section: MCPSubsection) -> some View {
|
private func mcpSidebarRow(_ section: MCPSubsection) -> some View {
|
||||||
Button(action: { selectedMCPSubsection = section }) {
|
Button(action: { selectedMCPSubsection = section }) {
|
||||||
HStack(spacing: 10) {
|
Group {
|
||||||
Image(systemName: section.icon)
|
|
||||||
.font(.system(size: 14))
|
|
||||||
.frame(width: 18)
|
|
||||||
Text(section.label)
|
|
||||||
.font(.system(size: 13))
|
|
||||||
Spacer()
|
|
||||||
}
|
|
||||||
.padding(.horizontal, 10)
|
|
||||||
.padding(.vertical, 7)
|
|
||||||
.background {
|
|
||||||
if selectedMCPSubsection == section {
|
if selectedMCPSubsection == section {
|
||||||
Color.clear.glassEffect(.regular.tint(.blue), in: .rect(cornerRadius: 8))
|
mcpSidebarRowLabel(section).glassEffect(.regular.tint(.blue), in: .rect(cornerRadius: 8))
|
||||||
} else {
|
} else {
|
||||||
Color.clear
|
mcpSidebarRowLabel(section)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -659,6 +649,20 @@ It's better to admit "I need more information" or "I cannot do that" than to fak
|
|||||||
.foregroundStyle(selectedMCPSubsection == section ? .blue : .primary)
|
.foregroundStyle(selectedMCPSubsection == section ? .blue : .primary)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
private func mcpSidebarRowLabel(_ section: MCPSubsection) -> some View {
|
||||||
|
HStack(spacing: 10) {
|
||||||
|
Image(systemName: section.icon)
|
||||||
|
.font(.system(size: 14))
|
||||||
|
.frame(width: 18)
|
||||||
|
Text(section.label)
|
||||||
|
.font(.system(size: 13))
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 10)
|
||||||
|
.padding(.vertical, 7)
|
||||||
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var mcpTabWithSidebar: some View {
|
private var mcpTabWithSidebar: some View {
|
||||||
HStack(alignment: .top, spacing: 0) {
|
HStack(alignment: .top, spacing: 0) {
|
||||||
@@ -3313,41 +3317,50 @@ It's better to admit "I need more information" or "I cannot do that" than to fak
|
|||||||
|
|
||||||
// MARK: - Tab Navigation
|
// MARK: - Tab Navigation
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
private func tabButton(_ tag: Int, icon: String, label: LocalizedStringKey, beta: Bool = false) -> some View {
|
private func tabButton(_ tag: Int, icon: String, label: LocalizedStringKey, beta: Bool = false) -> some View {
|
||||||
Button(action: { selectedTab = tag }) {
|
let selected = selectedTab == tag
|
||||||
VStack(spacing: 3) {
|
Group {
|
||||||
ZStack(alignment: .topTrailing) {
|
if selected {
|
||||||
Image(systemName: icon)
|
Button(action: { selectedTab = tag }) {
|
||||||
.font(.system(size: 22))
|
tabButtonLabel(icon: icon, label: label, beta: beta, selected: true)
|
||||||
.frame(height: 28)
|
|
||||||
.foregroundStyle(selectedTab == tag ? .blue : .secondary)
|
|
||||||
if beta {
|
|
||||||
Text("β")
|
|
||||||
.font(.system(size: 9, weight: .heavy))
|
|
||||||
.foregroundStyle(.white)
|
|
||||||
.padding(.horizontal, 4)
|
|
||||||
.padding(.vertical, 2)
|
|
||||||
.background(Color.orange)
|
|
||||||
.clipShape(Capsule())
|
|
||||||
.offset(x: 8, y: -3)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Text(label)
|
.buttonStyle(.glassProminent)
|
||||||
.font(.system(size: 11))
|
.tint(.blue)
|
||||||
.foregroundStyle(selectedTab == tag ? .blue : .secondary)
|
} else {
|
||||||
}
|
Button(action: { selectedTab = tag }) {
|
||||||
.frame(minWidth: 55)
|
tabButtonLabel(icon: icon, label: label, beta: beta, selected: false)
|
||||||
.padding(.vertical, 6)
|
|
||||||
.padding(.horizontal, 4)
|
|
||||||
.background {
|
|
||||||
if selectedTab == tag {
|
|
||||||
Color.clear.glassEffect(.regular.tint(.blue), in: .rect(cornerRadius: 8))
|
|
||||||
} else {
|
|
||||||
Color.clear
|
|
||||||
}
|
}
|
||||||
|
.buttonStyle(.glass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.buttonStyle(.plain)
|
.buttonBorderShape(.roundedRectangle(radius: 8))
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
private func tabButtonLabel(icon: String, label: LocalizedStringKey, beta: Bool, selected: Bool) -> some View {
|
||||||
|
VStack(spacing: 3) {
|
||||||
|
ZStack(alignment: .topTrailing) {
|
||||||
|
Image(systemName: icon)
|
||||||
|
.font(.system(size: 22))
|
||||||
|
.frame(height: 28)
|
||||||
|
.foregroundStyle(selected ? .blue : .secondary)
|
||||||
|
if beta {
|
||||||
|
Text("β")
|
||||||
|
.font(.system(size: 9, weight: .heavy))
|
||||||
|
.foregroundStyle(.white)
|
||||||
|
.padding(.horizontal, 4)
|
||||||
|
.padding(.vertical, 2)
|
||||||
|
.background(Color.orange)
|
||||||
|
.clipShape(Capsule())
|
||||||
|
.offset(x: 8, y: -3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text(label)
|
||||||
|
.font(.system(size: 11))
|
||||||
|
.foregroundStyle(selected ? .blue : .secondary)
|
||||||
|
}
|
||||||
|
.frame(minWidth: 55)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func tabTitle(_ tag: Int) -> LocalizedStringKey {
|
private func tabTitle(_ tag: Int) -> LocalizedStringKey {
|
||||||
|
|||||||
Reference in New Issue
Block a user