Newer Older
70 lines | 2.29kb
Bogdan Timofte authored 2 months ago
1
//
Bogdan Timofte authored 2 months ago
2
//  MeterInfoCardView.swift
Bogdan Timofte authored 2 months ago
3
//  USB Meter
4
//
5

            
6
import SwiftUI
7

            
Bogdan Timofte authored a month ago
8
struct MeterInfoCardView<Content: View, TrailingActions: View>: View {
Bogdan Timofte authored 2 months ago
9
    let title: String
Bogdan Timofte authored a month ago
10
    let infoMessage: String?
Bogdan Timofte authored 2 months ago
11
    let tint: Color
Bogdan Timofte authored a month ago
12
    let isCollapsible: Bool
13
    @State private var isExpanded: Bool
Bogdan Timofte authored a month ago
14
    @ViewBuilder var trailingActions: TrailingActions
Bogdan Timofte authored 2 months ago
15
    @ViewBuilder var content: Content
16

            
Bogdan Timofte authored a month ago
17
    init(
18
        title: String,
19
        infoMessage: String? = nil,
20
        tint: Color,
Bogdan Timofte authored a month ago
21
        isCollapsible: Bool = false,
22
        initiallyExpanded: Bool = true,
Bogdan Timofte authored a month ago
23
        @ViewBuilder trailingActions: () -> TrailingActions = { EmptyView() },
Bogdan Timofte authored a month ago
24
        @ViewBuilder content: () -> Content
25
    ) {
26
        self.title = title
27
        self.infoMessage = infoMessage
28
        self.tint = tint
Bogdan Timofte authored a month ago
29
        self.isCollapsible = isCollapsible
30
        self._isExpanded = State(initialValue: initiallyExpanded)
Bogdan Timofte authored a month ago
31
        self.trailingActions = trailingActions()
Bogdan Timofte authored a month ago
32
        self.content = content()
33
    }
34

            
Bogdan Timofte authored 2 months ago
35
    var body: some View {
Bogdan Timofte authored a month ago
36
        VStack(alignment: .leading, spacing: isExpanded ? 12 : 0) {
Bogdan Timofte authored a month ago
37
            HStack(spacing: 8) {
38
                Text(title)
39
                    .font(.headline)
40
                if let infoMessage {
41
                    ContextInfoButton(title: title, message: infoMessage)
42
                }
Bogdan Timofte authored a month ago
43
                Spacer(minLength: 0)
44
                trailingActions
Bogdan Timofte authored a month ago
45
                if isCollapsible {
46
                    Image(systemName: "chevron.up")
47
                        .font(.caption.weight(.semibold))
48
                        .foregroundColor(.secondary)
49
                        .rotationEffect(.degrees(isExpanded ? 0 : -180))
50
                        .animation(.easeInOut(duration: 0.2), value: isExpanded)
51
                }
52
            }
53
            .contentShape(Rectangle())
54
            .onTapGesture {
55
                guard isCollapsible else { return }
56
                withAnimation(.easeInOut(duration: 0.25)) {
57
                    isExpanded.toggle()
58
                }
59
            }
60

            
61
            if isExpanded {
62
                content
63
                    .transition(.opacity.combined(with: .move(edge: .top)))
Bogdan Timofte authored a month ago
64
            }
Bogdan Timofte authored 2 months ago
65
        }
66
        .frame(maxWidth: .infinity, alignment: .leading)
67
        .padding(18)
68
        .meterCard(tint: tint, fillOpacity: 0.18, strokeOpacity: 0.24)
69
    }
Bogdan Timofte authored a month ago
70
}