import SwiftUI

public extension View {
    func trackKeyboardHeight(_ keyboardHeight: Binding<CGFloat>) -> some View {
        self
            .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) { notification in
                guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else {
                    return
                }
                withAnimation(.easeOut(duration: 0.3)) {
                    keyboardHeight.wrappedValue = keyboardFrame.height
                }
            }
            .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification)) { _ in
                withAnimation(.easeOut(duration: 0.3)) {
                    keyboardHeight.wrappedValue = 0
                }
            }
    }
}

#Preview {
    struct PreviewExample: View {
        @State private var keyboardHeight: CGFloat = 0
        @FocusState private var isFocused: Bool

        var body: some View {
            VStack {
                Text("Height: \(Int(keyboardHeight))pt")
                    .font(.headline)

                TextField("Tap to show keyboard", text: .constant(""))
                    .textFieldStyle(.roundedBorder)
                    .focused($isFocused)
            }
            .padding()
            .trackKeyboardHeight($keyboardHeight)
        }
    }
    return PreviewExample()
}
