merge modal location

This commit is contained in:
Ian Gulliver
2026-10-17 08:51:59 -07:00
parent 38643e65f5
commit 3e537c827d
5 changed files with 35 additions and 16 deletions
+26 -4
View File
@@ -25,6 +25,7 @@ struct OverlayModal {
let content: AnyView
let buttons: [ModalButton]
let anchor: CGRect?
let inPane: Bool
let canSubmit: @MainActor () -> Bool
let done: (String) -> Void
}
@@ -49,7 +50,7 @@ final class Overlays {
var leftTab = LeftTab.lead
var leadFocus = 0
@ObservationIgnored var pickerFrame: CGRect = .zero
@ObservationIgnored var mergeFrame: CGRect?
var paneFrame: CGRect = .zero
@ObservationIgnored private var monitor: Any?
var isOpen: Bool {
@@ -64,10 +65,10 @@ final class Overlays {
alerts.append(OverlayAlert(content: AnyView(content)))
}
func showModal(_ content: some View, _ buttons: [ModalButton], anchor: CGRect? = nil, canSubmit: @escaping @MainActor () -> Bool = { true }) async -> String {
func showModal(_ content: some View, _ buttons: [ModalButton], anchor: CGRect? = nil, inPane: Bool = false, canSubmit: @escaping @MainActor () -> Bool = { true }) async -> String {
modal?.done("cancel")
return await withCheckedContinuation { cont in
modal = OverlayModal(content: AnyView(content), buttons: buttons, anchor: anchor, canSubmit: canSubmit) { value in
modal = OverlayModal(content: AnyView(content), buttons: buttons, anchor: anchor, inPane: inPane, canSubmit: canSubmit) { value in
cont.resume(returning: value)
}
}
@@ -248,7 +249,7 @@ struct OverlayHost: View {
.onTapGesture {
overlays.answerModal("cancel")
}
ModalPlacement(modal: m) { value in
ModalPlacement(modal: m, pane: overlays.paneFrame) { value in
overlays.answerModal(value)
}
}
@@ -316,8 +317,25 @@ private struct AnchoredBox: Layout {
}
}
private struct PaneCenteredBox: Layout {
let pane: CGRect
func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
proposal.replacingUnspecifiedDimensions()
}
func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
let width = min(520, pane.width - 48)
let size = subviews[0].sizeThatFits(ProposedViewSize(width: width, height: nil))
let x = pane.midX - size.width / 2
let y = min(max(overlayMargin, pane.midY - size.height / 2), bounds.height - overlayMargin - size.height)
subviews[0].place(at: CGPoint(x: bounds.minX + x, y: bounds.minY + y), proposal: ProposedViewSize(width: width, height: size.height))
}
}
private struct ModalPlacement: View {
let modal: OverlayModal
let pane: CGRect
let answer: (String) -> Void
var body: some View {
@@ -327,6 +345,10 @@ private struct ModalPlacement: View {
AnchoredBox(anchor: anchor) {
box
}
} else if modal.inPane {
PaneCenteredBox(pane: pane) {
box
}
} else {
box
.padding(24)