Yattee v2 rewrite

This commit is contained in:
Arkadiusz Fal
2026-02-08 18:31:16 +01:00
parent 20d0cfc0c7
commit 05f921d605
1043 changed files with 163875 additions and 68430 deletions

View File

@@ -0,0 +1,71 @@
//
// DynamicSheet.swift
// Yattee
//
// Primitives for dynamic sheet height based on calculated content size.
// For List/Form content that doesn't have intrinsic size.
//
import SwiftUI
// MARK: - Environment Key for Sheet Height
private struct SheetHeightKey: EnvironmentKey {
static let defaultValue: Binding<CGFloat>? = nil
}
extension EnvironmentValues {
/// Binding to report calculated content height to the sheet container.
var sheetContentHeight: Binding<CGFloat>? {
get { self[SheetHeightKey.self] }
set { self[SheetHeightKey.self] = newValue }
}
}
// MARK: - Dynamic Sheet Container
/// A sheet container that adjusts detents based on reported content height.
/// Child views should write to `sheetContentHeight` environment to report their size.
struct DynamicSheetContainer<Content: View>: View {
var animation: Animation = .smooth(duration: 0.35)
@ViewBuilder var content: Content
@State private var contentHeight: CGFloat = 0
var body: some View {
content
.environment(\.sheetContentHeight, Binding(
get: { contentHeight },
set: { newValue in
if contentHeight == 0 {
contentHeight = newValue
} else {
withAnimation(animation) {
contentHeight = newValue
}
}
}
))
#if os(iOS)
.modifier(SheetHeightModifier(height: contentHeight))
#endif
}
}
// MARK: - Animatable Sheet Height Modifier
/// ViewModifier that applies presentation detents with smooth animation.
/// Conforms to Animatable so SwiftUI can interpolate height changes.
private struct SheetHeightModifier: ViewModifier, Animatable {
var height: CGFloat
var animatableData: CGFloat {
get { height }
set { height = newValue }
}
func body(content: Content) -> some View {
content
.presentationDetents(height == 0 ? [.medium, .large] : [.height(height), .large])
}
}