Skip to content

Commit f51afd7

Browse files
committed
animate open/close context
1 parent 080b40e commit f51afd7

1 file changed

Lines changed: 35 additions & 15 deletions

File tree

Flitro/Sidebar/ContextCardView.swift

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ struct ContextCardView: View {
99
let isSelected: Bool
1010
let onIconChange: (String?, String?, String?) -> Void
1111

12-
@State private var isHovered = false
1312
@State private var showIconSelector = false
13+
@State private var iconRotation: Double = 0
14+
@State private var cardScale: CGFloat = 1.0
1415
@EnvironmentObject private var contextManager: ContextManager
1516

1617
private var iconColor: Color {
@@ -32,6 +33,10 @@ struct ContextCardView: View {
3233
return "\(total) items"
3334
}
3435

36+
private var isActive: Bool {
37+
contextManager.isActive(contextID: context.id)
38+
}
39+
3540
var body: some View {
3641
HStack(alignment: .center, spacing: 12) {
3742
// Icon
@@ -46,22 +51,26 @@ struct ContextCardView: View {
4651
.fill(Color(NSColor.windowBackgroundColor))
4752
.frame(width: 32, height: 32)
4853
}
49-
if let iconName = context.iconName, let icon = Ph(rawValue: iconName) {
50-
icon.regular
51-
.font(.title2)
52-
.foregroundColor(foregroundColor)
53-
} else {
54-
Image(systemName: "folder")
55-
.font(.title2)
56-
.foregroundColor(foregroundColor)
54+
Group {
55+
if let iconName = context.iconName, let icon = Ph(rawValue: iconName) {
56+
icon.regular
57+
.font(.title2)
58+
.foregroundColor(foregroundColor)
59+
} else {
60+
Image(systemName: "folder")
61+
.font(.title2)
62+
.foregroundColor(foregroundColor)
63+
}
5764
}
65+
.rotationEffect(.degrees(iconRotation))
66+
.animation(.spring(response: 0.5, dampingFraction: 0.6), value: iconRotation)
5867
}
5968
}
6069
.frame(width: 32, height: 32)
6170

6271
VStack(alignment: .leading, spacing: 2) {
6372
Text(context.name)
64-
.font(.system(size: 16, weight: .semibold))
73+
.font(.system(size: 16, weight: isSelected ? .semibold : .regular))
6574
.lineLimit(2)
6675
.truncationMode(.tail)
6776
.multilineTextAlignment(.leading)
@@ -77,10 +86,8 @@ struct ContextCardView: View {
7786
}
7887
.padding(8)
7988
.frame(maxWidth: .infinity, alignment: .leading)
80-
.animation(.spring(response: 0.3, dampingFraction: 0.7), value: isSelected)
81-
.onHover { hovering in
82-
isHovered = hovering
83-
}
89+
.scaleEffect(cardScale)
90+
.animation(.spring(response: 0.5, dampingFraction: 0.7), value: cardScale)
8491
.contextMenu {
8592
Button("Open") {
8693
contextManager.switchToContext(contextID: context.id)
@@ -108,5 +115,18 @@ struct ContextCardView: View {
108115
}
109116
)
110117
}
118+
.onAppear {
119+
iconRotation = isActive ? 360 : 0
120+
cardScale = isActive ? 1.04 : 1.0
121+
}
122+
.onChange(of: isActive) { active, _ in
123+
if active {
124+
iconRotation = 360
125+
cardScale = 1.04
126+
} else {
127+
iconRotation = 0
128+
cardScale = 1.0
129+
}
130+
}
111131
}
112-
}
132+
}

0 commit comments

Comments
 (0)