feat(ios): unify action hierarchy and surfaces

Refine primary and toolbar actions, align row buttons, normalize status surfaces, and split storage from destructive cleanup. Verified with Swift tests and the simulator build.
This commit is contained in:
chick
2026-09-12 16:15:57 +08:00
parent 0f2866a853
commit 20632be86a
7 changed files with 220 additions and 123 deletions
@@ -41,6 +41,7 @@ public struct AIButtonStyle: ButtonStyle {
case regular
case large
case toolbar
case toolbarInline
}
private let kind: Kind
@@ -66,13 +67,16 @@ public struct AIButtonStyle: ButtonStyle {
switch size {
case .compact: AITheme.compactButtonHeight
case .large: AITheme.largeButtonHeight
case .regular: AITheme.buttonHeight
case .toolbar: AITheme.toolbarButtonHeight
case .regular: AITheme.buttonHeight
case .toolbar: AITheme.toolbarButtonHeight
case .toolbarInline: AITheme.toolbarButtonHeight
}
configuration.label
configuration.label
.labelStyle(.titleAndIcon)
.font(.system(size: size == .toolbar ? 15 : 16, weight: .semibold))
.font(
.system(size: size == .compact || size == .toolbarInline ? 15 : 16, weight: .semibold)
)
.lineLimit(1)
.foregroundStyle(kind.foregroundColor(isEnabled: isEnabled))
.padding(.horizontal, fixedWidth == nil ? (kind == .secondary ? 12 : 14) : 0)
@@ -83,19 +87,38 @@ public struct AIButtonStyle: ButtonStyle {
.frame(maxWidth: fillsWidth ? .infinity : nil)
.frame(width: fixedWidth)
.background(
RoundedRectangle(cornerRadius: AITheme.buttonRadius, style: .continuous)
.fill(kind.backgroundColor(isEnabled: isEnabled))
.shadow(
color: (kind == .secondary || !isEnabled) ? .clear : .black.opacity(0.10),
radius: 12,
x: 0,
y: 5
kind == .primary && isEnabled && size != .toolbarInline
? AnyShapeStyle(
LinearGradient(
colors: [AITheme.primaryTop, AITheme.primaryBottom],
startPoint: .top,
endPoint: .bottom
)
)
: AnyShapeStyle(kind.backgroundColor(isEnabled: isEnabled))
)
.shadow(
color: (kind == .secondary || !isEnabled) ? .clear : .black.opacity(0.10),
radius: 12,
x: 0,
y: 5
)
.clipShape(
RoundedRectangle(
cornerRadius: size == .toolbarInline ? AITheme.toolbarButtonHeight / 2 : AITheme.buttonRadius,
style: .continuous
)
)
.clipShape(RoundedRectangle(cornerRadius: AITheme.buttonRadius, style: .continuous))
.overlay {
RoundedRectangle(cornerRadius: AITheme.buttonRadius, style: .continuous)
.strokeBorder(kind == .secondary || !isEnabled ? AITheme.line : .clear)
RoundedRectangle(
cornerRadius: size == .toolbarInline ? AITheme.toolbarButtonHeight / 2 : AITheme.buttonRadius,
style: .continuous
)
.strokeBorder(
size == .toolbarInline && kind == .primary
? AITheme.primary.opacity(0.28)
: (kind == .secondary || !isEnabled ? AITheme.line : .clear)
)
}
.scaleEffect(configuration.isPressed ? Self.pressedScale : 1)
.opacity(configuration.isPressed ? 0.82 : 1)
@@ -106,7 +129,7 @@ public struct AIButtonStyle: ButtonStyle {
case .compact: return AITheme.compactButtonMinWidth
case .regular: return AITheme.regularButtonMinWidth
case .large: return 92
case .toolbar: return AITheme.toolbarButtonMinWidth
case .toolbar, .toolbarInline: return AITheme.toolbarButtonMinWidth
}
}