|
@@ -77,29 +77,41 @@ struct ToolbarButton: View {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
struct IconButton: View {
|
|
struct IconButton: View {
|
|
|
- let iconName: String
|
|
|
|
|
let action: () -> Void
|
|
let action: () -> Void
|
|
|
|
|
+ private let iconName: String?
|
|
|
|
|
+ private let customIcon: (() -> AnyView)?
|
|
|
|
|
|
|
|
@State private var isHovered = false
|
|
@State private var isHovered = false
|
|
|
|
|
|
|
|
- var body: some View {
|
|
|
|
|
- Button(action: action) {
|
|
|
|
|
|
|
+ init(iconName: String, action: @escaping () -> Void) {
|
|
|
|
|
+ self.iconName = iconName
|
|
|
|
|
+ self.customIcon = nil
|
|
|
|
|
+ self.action = action
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ init<Content: View>(@ViewBuilder icon: @escaping () -> Content, action: @escaping () -> Void) {
|
|
|
|
|
+ self.iconName = nil
|
|
|
|
|
+ self.customIcon = { AnyView(icon()) }
|
|
|
|
|
+ self.action = action
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @ViewBuilder
|
|
|
|
|
+ private var iconContent: some View {
|
|
|
|
|
+ if let iconName {
|
|
|
Image(systemName: iconName)
|
|
Image(systemName: iconName)
|
|
|
.font(.system(size: 14))
|
|
.font(.system(size: 14))
|
|
|
|
|
+ } else if let customIcon {
|
|
|
|
|
+ customIcon()
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var body: some View {
|
|
|
|
|
+ Button(action: action) {
|
|
|
|
|
+ iconContent
|
|
|
.foregroundStyle(isHovered ? AppTheme.toolbarForegroundHover : AppTheme.textSecondary)
|
|
.foregroundStyle(isHovered ? AppTheme.toolbarForegroundHover : AppTheme.textSecondary)
|
|
|
- .frame(width: 36, height: 36)
|
|
|
|
|
- .background(isHovered ? AppTheme.toolbarBackgroundHover : Color.white)
|
|
|
|
|
- .clipShape(RoundedRectangle(cornerRadius: 8))
|
|
|
|
|
- .overlay(
|
|
|
|
|
- RoundedRectangle(cornerRadius: 8)
|
|
|
|
|
- .stroke(isHovered ? AppTheme.toolbarBorderHover : AppTheme.border, lineWidth: 1)
|
|
|
|
|
- )
|
|
|
|
|
- .shadow(
|
|
|
|
|
- color: isHovered ? AppTheme.toolbarShadowHover : AppTheme.toolbarShadow,
|
|
|
|
|
- radius: isHovered ? 5 : 3,
|
|
|
|
|
- y: isHovered ? 2 : 1
|
|
|
|
|
- )
|
|
|
|
|
- .scaleEffect(isHovered ? 1.02 : 1.0)
|
|
|
|
|
|
|
+ .padding(4)
|
|
|
|
|
+ .contentShape(Rectangle())
|
|
|
|
|
+ .scaleEffect(isHovered ? 1.05 : 1.0)
|
|
|
.animation(.easeOut(duration: 0.15), value: isHovered)
|
|
.animation(.easeOut(duration: 0.15), value: isHovered)
|
|
|
}
|
|
}
|
|
|
.buttonStyle(.plain)
|
|
.buttonStyle(.plain)
|