Skip to content

Commit c7c30af

Browse files
committed
Update Popover Style
1 parent bc152a0 commit c7c30af

9 files changed

Lines changed: 100 additions & 52 deletions

File tree

CodeEdit/Features/ActivityViewer/Tasks/DropdownMenuItemStyleModifier.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,33 @@
77

88
import SwiftUI
99

10+
extension View {
11+
@ViewBuilder
12+
func dropdownItemStyle() -> some View {
13+
self.modifier(DropdownMenuItemStyleModifier())
14+
}
15+
}
16+
1017
struct DropdownMenuItemStyleModifier: ViewModifier {
1118
@State private var isHovering = false
1219

1320
func body(content: Content) -> some View {
1421
content
22+
.padding(.vertical, 4)
23+
.padding(.horizontal, 8)
1524
.background(
1625
isHovering
1726
? AnyView(EffectView(.selection, blendingMode: .withinWindow, emphasized: true))
1827
: AnyView(Color.clear)
1928
)
2029
.foregroundColor(isHovering ? Color(NSColor.white) : .primary)
30+
.if(.tahoe) {
31+
if #available(macOS 26, *) {
32+
$0.clipShape(ContainerRelativeShape())
33+
}
34+
} else: {
35+
$0.clipShape(RoundedRectangle(cornerRadius: 5))
36+
}
2137
.onHover(perform: { hovering in
2238
self.isHovering = hovering
2339
})

CodeEdit/Features/ActivityViewer/Tasks/OptionMenuItemView.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,8 @@ struct OptionMenuItemView: View {
1616
Text(label)
1717
Spacer()
1818
}
19-
.padding(.vertical, 4)
20-
.padding(.horizontal, 28)
21-
.modifier(DropdownMenuItemStyleModifier())
22-
.clipShape(RoundedRectangle(cornerRadius: 5))
19+
.padding(.horizontal, 20)
20+
.dropdownItemStyle()
2321
.onTapGesture {
2422
action()
2523
}

CodeEdit/Features/ActivityViewer/Tasks/SchemeDropDownView.swift

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -134,29 +134,24 @@ struct SchemeDropDownView: View {
134134
}
135135

136136
@ViewBuilder var popoverContent: some View {
137-
VStack(alignment: .leading, spacing: 0) {
138-
WorkspaceMenuItemView(
139-
workspaceFileManager: workspaceFileManager,
140-
item: workspaceFileManager?.workspaceItem
141-
)
142-
Divider()
143-
.padding(.vertical, 5)
144-
Group {
145-
OptionMenuItemView(label: "Add Folder...") {
146-
// TODO: Implment Add Folder
147-
print("NOT IMPLEMENTED")
148-
}
149-
.disabled(true)
150-
OptionMenuItemView(label: "Workspace Settings...") {
151-
NSApp.sendAction(
152-
#selector(CodeEditWindowController.openWorkspaceSettings(_:)), to: nil, from: nil
153-
)
154-
}
137+
WorkspaceMenuItemView(
138+
workspaceFileManager: workspaceFileManager,
139+
item: workspaceFileManager?.workspaceItem
140+
)
141+
Divider()
142+
.padding(.vertical, 5)
143+
Group {
144+
OptionMenuItemView(label: "Add Folder...") {
145+
// TODO: Implment Add Folder
146+
print("NOT IMPLEMENTED")
147+
}
148+
.disabled(true)
149+
OptionMenuItemView(label: "Workspace Settings...") {
150+
NSApp.sendAction(
151+
#selector(CodeEditWindowController.openWorkspaceSettings(_:)), to: nil, from: nil
152+
)
155153
}
156154
}
157-
.font(.subheadline)
158-
.padding(5)
159-
.frame(minWidth: 215)
160155
}
161156
}
162157

CodeEdit/Features/ActivityViewer/Tasks/TaskDropDownView.swift

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -111,25 +111,20 @@ struct TaskDropDownView: View {
111111
}
112112

113113
@ViewBuilder private var taskPopoverContent: some View {
114-
VStack(alignment: .leading, spacing: 0) {
115-
if !taskManager.availableTasks.isEmpty {
116-
ForEach(taskManager.availableTasks, id: \.id) { task in
117-
TasksPopoverMenuItem(taskManager: taskManager, task: task) {
118-
isTaskPopOverPresented = false
119-
}
114+
if !taskManager.availableTasks.isEmpty {
115+
ForEach(taskManager.availableTasks, id: \.id) { task in
116+
TasksPopoverMenuItem(taskManager: taskManager, task: task) {
117+
isTaskPopOverPresented = false
120118
}
121-
Divider()
122-
.padding(.vertical, 5)
123-
}
124-
OptionMenuItemView(label: "Add Task...") {
125-
NSApp.sendAction(#selector(CodeEditWindowController.openWorkspaceSettings(_:)), to: nil, from: nil)
126-
}
127-
OptionMenuItemView(label: "Manage Tasks...") {
128-
NSApp.sendAction(#selector(CodeEditWindowController.openWorkspaceSettings(_:)), to: nil, from: nil)
129119
}
120+
Divider()
121+
.padding(.vertical, 5)
122+
}
123+
OptionMenuItemView(label: "Add Task...") {
124+
NSApp.sendAction(#selector(CodeEditWindowController.openWorkspaceSettings(_:)), to: nil, from: nil)
125+
}
126+
OptionMenuItemView(label: "Manage Tasks...") {
127+
NSApp.sendAction(#selector(CodeEditWindowController.openWorkspaceSettings(_:)), to: nil, from: nil)
130128
}
131-
.font(.subheadline)
132-
.padding(5)
133-
.frame(minWidth: 215)
134129
}
135130
}

CodeEdit/Features/ActivityViewer/Tasks/TasksPopoverMenuItem.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,8 @@ struct TasksPopoverMenuItem: View {
2020
selectionIndicator
2121
popoverContent
2222
}
23-
.padding(.vertical, 4)
24-
.padding(.horizontal, 8)
25-
.modifier(DropdownMenuItemStyleModifier())
23+
.dropdownItemStyle()
2624
.onTapGesture(perform: selectAction)
27-
.clipShape(RoundedRectangle(cornerRadius: 5))
2825
.accessibilityElement()
2926
.accessibilityLabel(task.name)
3027
.accessibilityAction(.default, selectAction)

CodeEdit/Features/ActivityViewer/Tasks/WorkspaceMenuItemView.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ struct WorkspaceMenuItemView: View {
2727
Text(item?.name ?? "")
2828
Spacer()
2929
}
30-
.padding(.vertical, 4)
31-
.padding(.horizontal, 8)
32-
.modifier(DropdownMenuItemStyleModifier())
30+
.dropdownItemStyle()
3331
.onTapGesture { } // add accessibility action when this is filled in
3432
.clipShape(RoundedRectangle(cornerRadius: 5))
3533
.accessibilityElement()

CodeEdit/Features/CodeEditUI/Views/InstantPopoverModifier.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,13 @@ extension View {
126126
func instantPopover<Content: View>(
127127
isPresented: Binding<Bool>,
128128
arrowEdge: Edge = .bottom,
129-
@ViewBuilder content: () -> Content
129+
@ViewBuilder content: @escaping () -> Content
130130
) -> some View {
131131
self.modifier(
132132
InstantPopoverModifier(
133133
isPresented: isPresented,
134134
arrowEdge: arrowEdge,
135-
popoverContent: content()
135+
popoverContent: PopoverContainer(content: content)
136136
)
137137
)
138138
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//
2+
// PopoverContainer.swift
3+
// CodeEdit
4+
//
5+
// Created by Khan Winter on 8/29/25.
6+
//
7+
8+
import SwiftUI
9+
10+
/// Container for SwiftUI views presented in a popover.
11+
/// On tahoe and above, adds the correct container shape.
12+
struct PopoverContainer<ContentView: View>: View {
13+
let content: () -> ContentView
14+
15+
init(@ViewBuilder content: @escaping () -> ContentView) {
16+
self.content = content
17+
}
18+
19+
var body: some View {
20+
VStack(alignment: .leading, spacing: 0) {
21+
content()
22+
}
23+
.font(.subheadline)
24+
.if(.tahoe) {
25+
$0.padding(13).containerShape(RoundedRectangle(cornerRadius: 20, style: .continuous))
26+
} else: {
27+
$0.padding(5)
28+
}
29+
.frame(minWidth: 215)
30+
}
31+
}

CodeEdit/Utils/Extensions/View/View+if.swift

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,31 @@ extension View {
1414
/// - transform: The transform to apply to the source `View`.
1515
/// - Returns: Either the original `View` or the modified `View` if the condition is `true`.
1616
@ViewBuilder
17-
func `if`<Content: View>(_ condition: Bool, transform: (Self) -> Content) -> some View {
17+
func `if`<Content: View>(_ condition: Bool, @ViewBuilder transform: (Self) -> Content) -> some View {
1818
if condition {
1919
transform(self)
2020
} else {
2121
self
2222
}
2323
}
24+
25+
/// Applies the given transform if the given condition evaluates to `true`.
26+
/// - Parameters:
27+
/// - condition: The condition to evaluate.
28+
/// - transform: The transform to apply to the source `View`.
29+
/// - Returns: Either the original `View` or the modified `View` if the condition is `true`.
30+
@ViewBuilder
31+
func `if`<Content: View, ElseContent: View>(
32+
_ condition: Bool,
33+
@ViewBuilder transform: (Self) -> Content,
34+
@ViewBuilder else elseTransform: (Self) -> ElseContent
35+
) -> some View {
36+
if condition {
37+
transform(self)
38+
} else {
39+
elseTransform(self)
40+
}
41+
}
2442
}
2543

2644
extension Bool {

0 commit comments

Comments
 (0)