|
// Credit to Raffi for the design! https://twitter.com/raffichill/status/1781492309500027206 |
|
|
|
struct SquishyButtonThing: View { |
|
@State var expanded: Bool = false |
|
|
|
var body: some View { |
|
VStack { |
|
Spacer() |
|
|
|
VStack { |
|
HStack(spacing: 6) { |
|
HStack { |
|
Text("Apr 16") |
|
+ Text(" 2024") |
|
.foregroundStyle(.secondary) |
|
.font(.largeTitle.weight(.regular)) |
|
} |
|
.font(.largeTitle.weight(.semibold)) |
|
.foregroundStyle(.primary) |
|
.frame(maxWidth: .infinity, alignment: .leading) |
|
|
|
|
|
// Fake button for spacing. Presumes that there's room to the left |
|
SquishedButton(name: "pencil", isMinimial: !expanded, action: { }) |
|
.opacity(0) |
|
.overlay { fancyButtons } |
|
|
|
// |
|
SquishedButton(name: "xmark", action: { expanded.toggle() }) |
|
.opacity(expanded ? 0 : 1) |
|
.scaleEffect(expanded ? 0.3 : 1) |
|
} |
|
.padding() |
|
.animation(.snappy, value: expanded) |
|
} |
|
.frame(height: 350, alignment: .top) |
|
.background( |
|
RoundedRectangle(cornerRadius: 20) |
|
.foregroundStyle(Color.white) |
|
.edgesIgnoringSafeArea(.bottom) |
|
.shadow(color: Color.black.opacity(0.1), radius: 10) |
|
) |
|
|
|
} |
|
.background( |
|
Color(UIColor.systemGroupedBackground) |
|
) |
|
} |
|
|
|
|
|
var fancyButtons: some View { |
|
HStack(spacing: 6) { |
|
SquishedButton(name: "pencil", isMinimial: !expanded, action: { |
|
expanded.toggle() |
|
}) |
|
SquishedButton(name: "trash.fill", isMinimial: !expanded, isDelete: true, action: { |
|
expanded.toggle() |
|
}) |
|
SquishedButton(name: "arrow.uturn.backward", isMinimial: !expanded, action: { |
|
expanded.toggle() |
|
}) |
|
} |
|
.scaleEffect(expanded ? 1 : 0.2) |
|
} |
|
} |
|
|
|
|
|
struct SquishedButton: View { |
|
let name: String |
|
var isMinimial: Bool = false |
|
var isDelete: Bool = false |
|
var action: (() -> ()) = { } |
|
|
|
var body: some View { |
|
Button(action: { |
|
action() |
|
}, label: { |
|
Image(systemName: name) |
|
.opacity(isMinimial ? 0 : 1) |
|
.font(.subheadline.weight(.semibold)) |
|
.fontDesign(.rounded) |
|
.foregroundStyle(isDelete ? .red : .primary) |
|
.padding(9) |
|
.background( |
|
isMinimial ? .primary : (isDelete ? Color.red : Color.secondary).opacity(0.2), |
|
in: Circle() |
|
) |
|
}) |
|
.buttonStyle(PlainButtonStyle()) |
|
} |
|
} |
|
|
|
|
|
#Preview { |
|
SquishyButtonThing() |
|
} |