feat: Updates flagged status label styles
This commit is contained in:
@@ -24,5 +24,5 @@ public struct FlaggedMessageLabel: View {
|
|||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
FlaggedStatusLabel(status: .warning)
|
FlaggedStatusLabel(status: .warning)
|
||||||
.flaggedStatusLabelStyle(.heavyTitle2)
|
.flaggedStatusLabelStyle(.textLabel(.heavyTitle2))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,15 +15,23 @@ public struct FlaggedStatusLabel: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public var body: some View {
|
public var body: some View {
|
||||||
TextLabel(status.title)
|
style.makeBody(
|
||||||
.textLabelStyle(
|
configuration: FlaggedStatusLabelStyleConfiguration(
|
||||||
.colored(status.flagColor)
|
status: status
|
||||||
.combining(style)
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
FlaggedStatusLabel(status: .warning)
|
VStack {
|
||||||
.flaggedStatusLabelStyle(.heavyTitle2)
|
FlaggedStatusLabel(status: .warning)
|
||||||
|
.flaggedStatusLabelStyle(.textLabel(.heavyTitle2))
|
||||||
|
|
||||||
|
FlaggedStatusLabel(status: .warning)
|
||||||
|
.flaggedStatusLabelStyle(.pill)
|
||||||
|
|
||||||
|
// FlaggedStatusLabel(status: .warning
|
||||||
|
// .flaggedStatusLabelStyle(.pill(.heavyTitle2))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,9 +38,7 @@ public struct AnyFlaggedMessageViewStyle: FlaggedMessageViewStyle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct DefaultFlaggedMessageViewStyle: FlaggedMessageViewStyle {
|
public struct HorizontalFlaggedMessageViewStyle: FlaggedMessageViewStyle {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
public func makeBody(configuration: Configuration) -> some View {
|
public func makeBody(configuration: Configuration) -> some View {
|
||||||
@@ -66,17 +64,38 @@ public struct VerticalFlaggedMessageViewStyle: FlaggedMessageViewStyle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct AutomaticFlaggedMessageViewStyle: FlaggedMessageViewStyle {
|
||||||
|
|
||||||
|
let horizontalSizeClass: UserInterfaceSizeClass?
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
public func makeBody(configuration: Configuration) -> some View {
|
||||||
|
if horizontalSizeClass == .compact {
|
||||||
|
VerticalFlaggedMessageViewStyle().makeBody(configuration: configuration)
|
||||||
|
} else {
|
||||||
|
HorizontalFlaggedMessageViewStyle().makeBody(configuration: configuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension FlaggedMessageViewStyle where Self == VerticalFlaggedMessageViewStyle {
|
extension FlaggedMessageViewStyle where Self == VerticalFlaggedMessageViewStyle {
|
||||||
public static var vertical: Self { .init() }
|
public static var vertical: Self { .init() }
|
||||||
}
|
}
|
||||||
|
|
||||||
extension FlaggedMessageViewStyle where Self == DefaultFlaggedMessageViewStyle {
|
extension FlaggedMessageViewStyle where Self == HorizontalFlaggedMessageViewStyle {
|
||||||
public static var horizontal: Self { .init() }
|
public static var horizontal: Self { .init() }
|
||||||
public static var `default`: Self { .init() }
|
}
|
||||||
|
|
||||||
|
extension FlaggedMessageViewStyle where Self == AutomaticFlaggedMessageViewStyle {
|
||||||
|
public static func automatic(horizontalSizeClass: UserInterfaceSizeClass? = nil) -> Self {
|
||||||
|
.init(horizontalSizeClass: horizontalSizeClass)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct FlaggedMessageViewStyleKey: EnvironmentKey {
|
private struct FlaggedMessageViewStyleKey: EnvironmentKey {
|
||||||
static var defaultValue = AnyFlaggedMessageViewStyle(DefaultFlaggedMessageViewStyle())
|
static var defaultValue = AnyFlaggedMessageViewStyle(
|
||||||
|
AutomaticFlaggedMessageViewStyle(horizontalSizeClass: nil)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
extension EnvironmentValues {
|
extension EnvironmentValues {
|
||||||
@@ -98,7 +117,7 @@ extension View {
|
|||||||
|
|
||||||
extension Flagged.CheckResult.Status {
|
extension Flagged.CheckResult.Status {
|
||||||
|
|
||||||
var flagColor: Color {
|
public var color: Color {
|
||||||
switch self {
|
switch self {
|
||||||
case .good:
|
case .good:
|
||||||
return .green
|
return .green
|
||||||
|
|||||||
@@ -2,23 +2,131 @@ import SharedModels
|
|||||||
import Styleguide
|
import Styleguide
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
public protocol FlaggedStatusLabelStyle {
|
||||||
|
associatedtype Body: View
|
||||||
|
typealias Configuration = FlaggedStatusLabelStyleConfiguration
|
||||||
|
|
||||||
|
func makeBody(configuration: Self.Configuration) -> Self.Body
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct FlaggedStatusLabelStyleConfiguration {
|
||||||
|
public let status: Flagged.CheckResult.Status
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct AnyFlaggedStatusLabelStyle: FlaggedStatusLabelStyle {
|
||||||
|
private let _makeBody: (Configuration) -> AnyView
|
||||||
|
|
||||||
|
internal init(makeBody: @escaping (Configuration) -> AnyView) {
|
||||||
|
self._makeBody = makeBody
|
||||||
|
}
|
||||||
|
|
||||||
|
public init<Style: FlaggedStatusLabelStyle>(_ style: Style) {
|
||||||
|
self.init { configuration in
|
||||||
|
AnyView(style.makeBody(configuration: configuration))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func makeBody(configuration: Configuration) -> some View {
|
||||||
|
_makeBody(configuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct FlaggedStatusTextLabelStyle: FlaggedStatusLabelStyle {
|
||||||
|
|
||||||
|
let textLabelStyle: AnyTextLabelStyle?
|
||||||
|
|
||||||
|
public func makeBody(configuration: Configuration) -> some View {
|
||||||
|
TextLabel(configuration.status.title)
|
||||||
|
.textLabelStyle(
|
||||||
|
textLabelStyle
|
||||||
|
?? AnyTextLabelStyle(
|
||||||
|
style: .colored(configuration.status.color).font(.caption, fontWeight: .bold)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private struct FlaggedStatusLabelStyleKey: EnvironmentKey {
|
private struct FlaggedStatusLabelStyleKey: EnvironmentKey {
|
||||||
static var defaultValue = AnyTextLabelStyle(style: .font(.caption, fontWeight: .bold))
|
static var defaultValue = AnyFlaggedStatusLabelStyle(
|
||||||
|
FlaggedStatusTextLabelStyle(
|
||||||
|
textLabelStyle: AnyTextLabelStyle(
|
||||||
|
style: .font(.callout, fontWeight: .bold)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FlaggedStatusLabelStyle where Self == FlaggedStatusTextLabelStyle {
|
||||||
|
|
||||||
|
public static var textLabel: Self { textLabel() }
|
||||||
|
|
||||||
|
public static func textLabel(
|
||||||
|
_ style: AnyTextLabelStyle? = nil
|
||||||
|
) -> Self {
|
||||||
|
.init(textLabelStyle: style)
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func textLabel<S: TextLabelStyle>(
|
||||||
|
_ style: S
|
||||||
|
) -> Self {
|
||||||
|
.init(textLabelStyle: AnyTextLabelStyle(style: style))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct FlaggedStatusPillStyle: FlaggedStatusLabelStyle {
|
||||||
|
let labelStyle: AnyTextLabelStyle?
|
||||||
|
let opacity: Double
|
||||||
|
|
||||||
|
public func makeBody(configuration: Configuration) -> some View {
|
||||||
|
TextLabel(configuration.status.title)
|
||||||
|
.textLabelStyle(labelStyle ?? AnyTextLabelStyle(
|
||||||
|
style: .font(.caption, fontWeight: .bold).combining(.colored(.white))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.padding(.horizontal, 10)
|
||||||
|
.padding(.vertical, 5)
|
||||||
|
.background {
|
||||||
|
Capsule()
|
||||||
|
.foregroundStyle(configuration.status.color.opacity(opacity))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FlaggedStatusLabelStyle where Self == FlaggedStatusPillStyle {
|
||||||
|
|
||||||
|
public static var pill: Self { .pill() }
|
||||||
|
|
||||||
|
public static func pill(
|
||||||
|
_ style: AnyTextLabelStyle? = nil,
|
||||||
|
opacity: Double = 1
|
||||||
|
) -> Self {
|
||||||
|
.init(labelStyle: style, opacity: opacity)
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func pill<S: TextLabelStyle>(_ style: S, opacity: Double = 1) -> Self {
|
||||||
|
.init(labelStyle: AnyTextLabelStyle(style: style), opacity: opacity)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension EnvironmentValues {
|
extension EnvironmentValues {
|
||||||
public var flaggedStatusLabelStyle: AnyTextLabelStyle {
|
public var flaggedStatusLabelStyle: AnyFlaggedStatusLabelStyle {
|
||||||
get { self[FlaggedStatusLabelStyleKey.self] }
|
get { self[FlaggedStatusLabelStyleKey.self] }
|
||||||
set { self[FlaggedStatusLabelStyleKey.self] = newValue }
|
set { self[FlaggedStatusLabelStyleKey.self] = newValue }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension View {
|
extension View {
|
||||||
public func flaggedStatusLabelStyle(_ style: AnyTextLabelStyle) -> some View {
|
public func flaggedStatusLabelStyle(
|
||||||
environment(\.flaggedStatusLabelStyle, style)
|
_ style: AnyFlaggedStatusLabelStyle
|
||||||
|
) -> some View {
|
||||||
|
environment(
|
||||||
|
\.flaggedStatusLabelStyle,
|
||||||
|
style
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func flaggedStatusLabelStyle<S: TextLabelStyle>(_ style: S) -> some View {
|
public func flaggedStatusLabelStyle<S: FlaggedStatusLabelStyle>(_ style: S) -> some View {
|
||||||
flaggedStatusLabelStyle(AnyTextLabelStyle(style: style))
|
flaggedStatusLabelStyle(AnyFlaggedStatusLabelStyle(style))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,12 +116,15 @@ public struct FlaggedGridRowStyle: FlaggedViewStyle {
|
|||||||
.foregroundStyle(Color.secondary)
|
.foregroundStyle(Color.secondary)
|
||||||
FlaggedMessageView(flagged: configuration.flagged)
|
FlaggedMessageView(flagged: configuration.flagged)
|
||||||
}
|
}
|
||||||
Text(
|
Spacer()
|
||||||
configuration.flagged.wrappedValue,
|
HStack(spacing: 10) {
|
||||||
format: .number.precision(.fractionLength(fractionLength))
|
Text(
|
||||||
)
|
configuration.flagged.wrappedValue,
|
||||||
configuration.flagged.flagImage
|
format: .number.precision(.fractionLength(fractionLength))
|
||||||
.gridCellAnchor(.trailing)
|
)
|
||||||
|
configuration.flagged.flagImage
|
||||||
|
}
|
||||||
|
.gridCellAnchor(.trailing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,11 +154,11 @@ extension FlaggedViewStyle where Self == DefaultFlagViewStyle {
|
|||||||
|
|
||||||
|
|
||||||
extension Flagged {
|
extension Flagged {
|
||||||
var flagColor: Color { self.status.flagColor }
|
public var statusColor: Color { self.status.color }
|
||||||
|
|
||||||
public var flagImage: some View {
|
public var flagImage: some View {
|
||||||
Image(systemName: "flag.fill")
|
Image(systemName: "flag.fill")
|
||||||
.foregroundStyle(flagColor)
|
.foregroundStyle(statusColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
public var messageView: some View {
|
public var messageView: some View {
|
||||||
|
|||||||
@@ -228,7 +228,9 @@ public struct FlaggedMeasurementListView: View {
|
|||||||
}
|
}
|
||||||
ForEach(store.estimatedMeasurements) { measurement in
|
ForEach(store.estimatedMeasurements) { measurement in
|
||||||
Section {
|
Section {
|
||||||
FlaggedEquipmentMeasurementView(measurement.flaggedMeasurement)
|
FlaggedEquipmentMeasurementView(
|
||||||
|
measurement.flaggedMeasurement
|
||||||
|
)
|
||||||
} header: {
|
} header: {
|
||||||
HStack {
|
HStack {
|
||||||
Text(measurement.name)
|
Text(measurement.name)
|
||||||
@@ -268,12 +270,10 @@ public struct FlaggedMeasurementListView: View {
|
|||||||
}
|
}
|
||||||
.onAppear { send(.onAppear) }
|
.onAppear { send(.onAppear) }
|
||||||
.flaggedMessageViewStyle(
|
.flaggedMessageViewStyle(
|
||||||
horizontalSizeClass == .compact
|
.automatic(horizontalSizeClass: horizontalSizeClass)
|
||||||
? AnyFlaggedMessageViewStyle(.vertical)
|
|
||||||
: AnyFlaggedMessageViewStyle(.horizontal)
|
|
||||||
)
|
)
|
||||||
// .flaggedStatusLabelStyle(.font(.caption))
|
.flaggedStatusLabelStyle(.textLabel)
|
||||||
// .flaggedMessageLabelStyle(.font(.caption, fontWeight: .bold))
|
.flaggedMessageLabelStyle(.font(.caption))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,4 +313,19 @@ private let flaggedMeasurements = IdentifiedArrayOf<FlaggedMeasurementsList.Stat
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#Preview("Landscape", traits: .landscapeLeft) {
|
||||||
|
NavigationStack {
|
||||||
|
FlaggedMeasurementListView(
|
||||||
|
store: Store(
|
||||||
|
initialState: FlaggedMeasurementsList.State(
|
||||||
|
sharedSettings: Shared(sharedSettings)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
FlaggedMeasurementsList()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -159,6 +159,30 @@ extension AnyTextLabelStyle {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct PillViewTextLabelStyle: TextLabelStyle {
|
||||||
|
|
||||||
|
let labelColor: Color?
|
||||||
|
let pillColor: Color
|
||||||
|
|
||||||
|
public func makeBody(configuration: Configuration) -> some View {
|
||||||
|
configuration.label
|
||||||
|
.foregroundStyle(labelColor ?? .primary)
|
||||||
|
.background {
|
||||||
|
Capsule()
|
||||||
|
.foregroundStyle(pillColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension TextLabelStyle where Self == PillViewTextLabelStyle {
|
||||||
|
public static func pill(
|
||||||
|
pillColor: Color,
|
||||||
|
labelColor: Color? = nil
|
||||||
|
) -> Self {
|
||||||
|
.init(labelColor: labelColor, pillColor: pillColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension View {
|
extension View {
|
||||||
|
|
||||||
public func textLabelStyle(_ style: AnyTextLabelStyle) -> some View {
|
public func textLabelStyle(_ style: AnyTextLabelStyle) -> some View {
|
||||||
|
|||||||
Reference in New Issue
Block a user