feat: Adds text labeled content and style.
This commit is contained in:
@@ -19,7 +19,7 @@ public struct EquipmentMeasurementForm {
|
|||||||
@ObservableState
|
@ObservableState
|
||||||
public struct State: Equatable, Sendable {
|
public struct State: Equatable, Sendable {
|
||||||
@Presents public var destination: Destination.State?
|
@Presents public var destination: Destination.State?
|
||||||
@Shared public var sharedSettings: SharedPressureEstimationSettings
|
@Shared public var sharedSettings: SharedPressureEstimationState
|
||||||
public var allowEquipmentTypeSelection: Bool
|
public var allowEquipmentTypeSelection: Bool
|
||||||
public var equipmentType: EquipmentMeasurement.EquipmentType
|
public var equipmentType: EquipmentMeasurement.EquipmentType
|
||||||
public var focusedField: Field?
|
public var focusedField: Field?
|
||||||
@@ -28,7 +28,7 @@ public struct EquipmentMeasurementForm {
|
|||||||
public init(
|
public init(
|
||||||
allowEquipmentTypeSelection: Bool = true,
|
allowEquipmentTypeSelection: Bool = true,
|
||||||
destination: Destination.State? = nil,
|
destination: Destination.State? = nil,
|
||||||
sharedSettings: Shared<SharedPressureEstimationSettings>,
|
sharedSettings: Shared<SharedPressureEstimationState>,
|
||||||
equipmentType: EquipmentMeasurement.EquipmentType = .airHandler,
|
equipmentType: EquipmentMeasurement.EquipmentType = .airHandler,
|
||||||
focusedField: Field? = nil,
|
focusedField: Field? = nil,
|
||||||
measurements: Measurements = .init()
|
measurements: Measurements = .init()
|
||||||
@@ -224,7 +224,7 @@ public struct EquipmentMeasurementForm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Store where State == EquipmentMeasurementForm.State {
|
fileprivate extension Store where State == EquipmentMeasurementForm.State {
|
||||||
|
|
||||||
func prompt(
|
func prompt(
|
||||||
field: EquipmentMeasurementForm.State.Field
|
field: EquipmentMeasurementForm.State.Field
|
||||||
@@ -258,7 +258,7 @@ extension Store where State == EquipmentMeasurementForm.State {
|
|||||||
case .supplyPlenumPressure:
|
case .supplyPlenumPressure:
|
||||||
return "Supply"
|
return "Supply"
|
||||||
case .airflow:
|
case .airflow:
|
||||||
return "Airflow"
|
return "CFM"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,12 +293,7 @@ public struct EquipmentMeasurementFormView: View {
|
|||||||
}
|
}
|
||||||
Section {
|
Section {
|
||||||
Grid(alignment: .leading, horizontalSpacing: 40) {
|
Grid(alignment: .leading, horizontalSpacing: 40) {
|
||||||
ForEach(store.pressureFields) { field in
|
ForEach(store.pressureFields, content: gridRow(for:))
|
||||||
GridRow {
|
|
||||||
TextLabel(store.label(field: field))
|
|
||||||
textField(for: field)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} header: {
|
} header: {
|
||||||
HStack {
|
HStack {
|
||||||
@@ -310,10 +305,7 @@ public struct EquipmentMeasurementFormView: View {
|
|||||||
|
|
||||||
Section {
|
Section {
|
||||||
Grid(alignment: .leading, horizontalSpacing: 60) {
|
Grid(alignment: .leading, horizontalSpacing: 60) {
|
||||||
GridRow {
|
gridRow(for: .airflow)
|
||||||
TextLabel(store.label(field: .airflow))
|
|
||||||
textField(for: .airflow)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} footer: {
|
} footer: {
|
||||||
HStack {
|
HStack {
|
||||||
@@ -325,6 +317,7 @@ public struct EquipmentMeasurementFormView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.bind($focusedField, to: $store.focusedField)
|
.bind($focusedField, to: $store.focusedField)
|
||||||
|
.labeledContentStyle(.gridRow)
|
||||||
.onAppear { send(.onAppear) }
|
.onAppear { send(.onAppear) }
|
||||||
.textLabelStyle(.boldSecondary)
|
.textLabelStyle(.boldSecondary)
|
||||||
.textFieldStyle(.roundedBorder)
|
.textFieldStyle(.roundedBorder)
|
||||||
@@ -350,6 +343,12 @@ public struct EquipmentMeasurementFormView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func gridRow(for field: EquipmentMeasurementForm.State.Field) -> some View {
|
||||||
|
TextLabeledContent(store.label(field: field)) {
|
||||||
|
textField(for: field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func textField(
|
private func textField(
|
||||||
for field: EquipmentMeasurementForm.State.Field
|
for field: EquipmentMeasurementForm.State.Field
|
||||||
) -> some View {
|
) -> some View {
|
||||||
@@ -424,7 +423,7 @@ fileprivate extension InfoViewFeature.State {
|
|||||||
NavigationStack {
|
NavigationStack {
|
||||||
EquipmentMeasurementFormView(
|
EquipmentMeasurementFormView(
|
||||||
store: Store(initialState: EquipmentMeasurementForm.State(
|
store: Store(initialState: EquipmentMeasurementForm.State(
|
||||||
sharedSettings: Shared(SharedPressureEstimationSettings()))
|
sharedSettings: Shared(SharedPressureEstimationState()))
|
||||||
) {
|
) {
|
||||||
EquipmentMeasurementForm()
|
EquipmentMeasurementForm()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,13 +26,13 @@ public struct EquipmentSettingsForm {
|
|||||||
public var includesFilterDrop: Bool
|
public var includesFilterDrop: Bool
|
||||||
public var equipmentType: EquipmentMeasurement.EquipmentType
|
public var equipmentType: EquipmentMeasurement.EquipmentType
|
||||||
public var focusedField: Field? = nil
|
public var focusedField: Field? = nil
|
||||||
@Shared public var sharedSettings: SharedPressureEstimationSettings
|
@Shared public var sharedSettings: SharedPressureEstimationState
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
destination: Destination.State? = nil,
|
destination: Destination.State? = nil,
|
||||||
includesFilterDrop: Bool = false,
|
includesFilterDrop: Bool = false,
|
||||||
equipmentType: EquipmentMeasurement.EquipmentType = .airHandler,
|
equipmentType: EquipmentMeasurement.EquipmentType = .airHandler,
|
||||||
sharedSettings: Shared<SharedPressureEstimationSettings>
|
sharedSettings: Shared<SharedPressureEstimationState>
|
||||||
) {
|
) {
|
||||||
self.destination = destination
|
self.destination = destination
|
||||||
self.includesFilterDrop = includesFilterDrop
|
self.includesFilterDrop = includesFilterDrop
|
||||||
@@ -46,12 +46,14 @@ public struct EquipmentSettingsForm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Note: These need to be in display order.
|
// Note: These need to be in display order.
|
||||||
public enum Field: Hashable, CaseIterable, FocusableField {
|
public enum Field: Hashable, CaseIterable, FocusableField, Identifiable {
|
||||||
case heatingCapacity
|
case heatingCapacity
|
||||||
case minimumStaticPressure
|
case minimumStaticPressure
|
||||||
case maximumStaticPressure
|
case maximumStaticPressure
|
||||||
case ratedStaticPressure
|
case ratedStaticPressure
|
||||||
case manufacturersIncludedFilterPressureDrop
|
case manufacturersIncludedFilterPressureDrop
|
||||||
|
|
||||||
|
public var id: Self { self }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,37 +185,9 @@ public struct EquipmentSettingsFormView: View {
|
|||||||
|
|
||||||
Section {
|
Section {
|
||||||
Grid(alignment: .leading, horizontalSpacing: 40) {
|
Grid(alignment: .leading, horizontalSpacing: 40) {
|
||||||
GridRow {
|
ForEach(RatingsField.allCases, content: ratingsRow(for:))
|
||||||
TextLabel("Minimum")
|
|
||||||
textField(
|
|
||||||
"Minimum Pressure",
|
|
||||||
value: $store.sharedSettings.ratedStaticPressures.minimum,
|
|
||||||
fractionLength: 2
|
|
||||||
)
|
|
||||||
.focused($focusedField, equals: .minimumStaticPressure)
|
|
||||||
.decimalPad()
|
|
||||||
}
|
|
||||||
GridRow {
|
|
||||||
TextLabel("Maximum")
|
|
||||||
textField(
|
|
||||||
"Maximum Pressure",
|
|
||||||
value: $store.sharedSettings.ratedStaticPressures.maximum,
|
|
||||||
fractionLength: 2
|
|
||||||
)
|
|
||||||
.focused($focusedField, equals: .maximumStaticPressure)
|
|
||||||
.decimalPad()
|
|
||||||
}
|
|
||||||
GridRow {
|
|
||||||
TextLabel("Rated")
|
|
||||||
textField(
|
|
||||||
"Rated Pressure",
|
|
||||||
value: $store.sharedSettings.ratedStaticPressures.rated,
|
|
||||||
fractionLength: 2
|
|
||||||
)
|
|
||||||
.focused($focusedField, equals: .ratedStaticPressure)
|
|
||||||
.decimalPad()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
.labeledContentStyle(.gridRow)
|
||||||
} header: {
|
} header: {
|
||||||
header("Rated Static Pressure", infoView: .ratedStaticPressures)
|
header("Rated Static Pressure", infoView: .ratedStaticPressures)
|
||||||
}
|
}
|
||||||
@@ -231,8 +205,7 @@ public struct EquipmentSettingsFormView: View {
|
|||||||
Spacer()
|
Spacer()
|
||||||
textField(
|
textField(
|
||||||
"Filter Drop",
|
"Filter Drop",
|
||||||
value: $store.sharedSettings.manufacturersIncludedFilterPressureDrop,
|
value: $store.sharedSettings.manufacturersIncludedFilterPressureDrop
|
||||||
fractionLength: 2
|
|
||||||
)
|
)
|
||||||
.focused($focusedField, equals: .manufacturersIncludedFilterPressureDrop)
|
.focused($focusedField, equals: .manufacturersIncludedFilterPressureDrop)
|
||||||
.decimalPad()
|
.decimalPad()
|
||||||
@@ -265,6 +238,27 @@ public struct EquipmentSettingsFormView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func ratingsRow(for ratingsField: RatingsField) -> some View {
|
||||||
|
|
||||||
|
func binding(for ratingsField: RatingsField) -> Binding<Double> {
|
||||||
|
switch ratingsField {
|
||||||
|
case .maximum:
|
||||||
|
return $store.sharedSettings.ratedStaticPressures.maximum
|
||||||
|
case .minimum:
|
||||||
|
return $store.sharedSettings.ratedStaticPressures.minimum
|
||||||
|
case .rated:
|
||||||
|
return $store.sharedSettings.ratedStaticPressures.rated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TextLabeledContent(ratingsField.label) {
|
||||||
|
TextField(ratingsField.prompt, value: binding(for: ratingsField), fractionLength: 2)
|
||||||
|
.decimalPad()
|
||||||
|
.focused($focusedField, equals: ratingsField.field)
|
||||||
|
.onSubmit { send(.submitField) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func header<Label: View>(
|
private func header<Label: View>(
|
||||||
infoView: EquipmentSettingsForm.InfoView,
|
infoView: EquipmentSettingsForm.InfoView,
|
||||||
label: @escaping () -> Label
|
label: @escaping () -> Label
|
||||||
@@ -283,20 +277,13 @@ public struct EquipmentSettingsFormView: View {
|
|||||||
header(infoView: infoView) { Text(title) }
|
header(infoView: infoView) { Text(title) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private func textField(
|
|
||||||
_ title: String,
|
|
||||||
value: Binding<Double>,
|
|
||||||
fractionLength: Int = 2
|
|
||||||
) -> some View {
|
|
||||||
TextField(title, value: value, fractionLength: fractionLength, prompt: Text(title))
|
|
||||||
}
|
|
||||||
|
|
||||||
private func textField(
|
private func textField(
|
||||||
_ title: String,
|
_ title: String,
|
||||||
value: Binding<Double?>,
|
value: Binding<Double?>,
|
||||||
fractionLength: Int = 2
|
fractionLength: Int = 2
|
||||||
) -> some View {
|
) -> some View {
|
||||||
TextField(title, value: value, fractionLength: fractionLength, prompt: Text(title))
|
TextField(title, value: value, fractionLength: fractionLength, prompt: Text(title))
|
||||||
|
.onSubmit { send(.submitField) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,12 +335,71 @@ fileprivate extension InfoViewFeature.State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileprivate enum RatingsField: String, Hashable, CaseIterable, Identifiable {
|
||||||
|
case maximum
|
||||||
|
case minimum
|
||||||
|
case rated
|
||||||
|
|
||||||
|
var id: Self { self }
|
||||||
|
|
||||||
|
var field: EquipmentSettingsForm.State.Field {
|
||||||
|
switch self {
|
||||||
|
case .maximum: return .maximumStaticPressure
|
||||||
|
case .minimum: return .minimumStaticPressure
|
||||||
|
case .rated: return .ratedStaticPressure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var label: String { rawValue.capitalized }
|
||||||
|
|
||||||
|
var prompt: String { "\(label) Pressure" }
|
||||||
|
}
|
||||||
|
|
||||||
|
//fileprivate extension Store where State == EquipmentSettingsForm.State {
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// func label(for ratingsField: RatingsField) -> String {
|
||||||
|
// self.label(for: ratingsField.field)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func prompt(for ratingsField: RatingsField) -> String {
|
||||||
|
// self.prompt(for: ratingsField.field)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func label(for field: EquipmentSettingsForm.State.Field) -> String {
|
||||||
|
// switch field {
|
||||||
|
// case .heatingCapacity:
|
||||||
|
// return "Heating"
|
||||||
|
// case .minimumStaticPressure:
|
||||||
|
// return "Minimum"
|
||||||
|
// case .maximumStaticPressure:
|
||||||
|
// return "Maximum"
|
||||||
|
// case .ratedStaticPressure:
|
||||||
|
// return "Rated"
|
||||||
|
// case .manufacturersIncludedFilterPressureDrop:
|
||||||
|
// return "Filter Drop"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// func prompt(for field: EquipmentSettingsForm.State.Field) -> String {
|
||||||
|
// switch field {
|
||||||
|
// case .heatingCapacity:
|
||||||
|
// return "Heating Capacity"
|
||||||
|
// case .minimumStaticPressure, .maximumStaticPressure, .ratedStaticPressure:
|
||||||
|
// return "\(label(for: field)) Pressure"
|
||||||
|
// case .manufacturersIncludedFilterPressureDrop:
|
||||||
|
// return label(for: field)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
EquipmentSettingsFormView(
|
EquipmentSettingsFormView(
|
||||||
store: Store(
|
store: Store(
|
||||||
initialState: EquipmentSettingsForm.State(
|
initialState: EquipmentSettingsForm.State(
|
||||||
sharedSettings: Shared(SharedPressureEstimationSettings())
|
sharedSettings: Shared(SharedPressureEstimationState())
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
EquipmentSettingsForm()._printChanges()
|
EquipmentSettingsForm()._printChanges()
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ public struct FlaggedMeasurementsList: Sendable {
|
|||||||
public struct State: Equatable {
|
public struct State: Equatable {
|
||||||
|
|
||||||
@Presents public var destination: Destination.State?
|
@Presents public var destination: Destination.State?
|
||||||
@Shared var sharedSettings: SharedPressureEstimationSettings
|
@Shared var sharedSettings: SharedPressureEstimationState
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
destination: Destination.State? = nil,
|
destination: Destination.State? = nil,
|
||||||
sharedSettings: Shared<SharedPressureEstimationSettings>
|
sharedSettings: Shared<SharedPressureEstimationState>
|
||||||
) {
|
) {
|
||||||
self.destination = destination
|
self.destination = destination
|
||||||
self._sharedSettings = sharedSettings
|
self._sharedSettings = sharedSettings
|
||||||
@@ -36,7 +36,7 @@ public struct FlaggedMeasurementsList: Sendable {
|
|||||||
return [.coilDrop, .filterDrop]
|
return [.coilDrop, .filterDrop]
|
||||||
}
|
}
|
||||||
|
|
||||||
public subscript<T>(dynamicMember keyPath: WritableKeyPath<SharedPressureEstimationSettings, T>) -> T {
|
public subscript<T>(dynamicMember keyPath: WritableKeyPath<SharedPressureEstimationState, T>) -> T {
|
||||||
get { sharedSettings[keyPath: keyPath] }
|
get { sharedSettings[keyPath: keyPath] }
|
||||||
set { sharedSettings[keyPath: keyPath] = newValue }
|
set { sharedSettings[keyPath: keyPath] = newValue }
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ public struct FlaggedMeasurementsList: Sendable {
|
|||||||
public enum View {
|
public enum View {
|
||||||
case addButtonTapped
|
case addButtonTapped
|
||||||
case destination(DestinationAction)
|
case destination(DestinationAction)
|
||||||
case editButtonTapped(id: SharedPressureEstimationSettings.FlaggedMeasurementContainer.ID)
|
case editButtonTapped(id: SharedPressureEstimationState.FlaggedMeasurementContainer.ID)
|
||||||
case onAppear
|
case onAppear
|
||||||
|
|
||||||
@CasePathable
|
@CasePathable
|
||||||
@@ -282,7 +282,7 @@ public struct FlaggedMeasurementListView: View {
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
|
||||||
private let budgets = BudgetedPercentEnvelope(equipmentType: .airHandler, fanType: .constantSpeed)
|
private let budgets = BudgetedPercentEnvelope(equipmentType: .airHandler, fanType: .constantSpeed)
|
||||||
private let flaggedMeasurements = IdentifiedArrayOf<SharedPressureEstimationSettings.FlaggedMeasurementContainer>(
|
private let flaggedMeasurements = IdentifiedArrayOf<SharedPressureEstimationState.FlaggedMeasurementContainer>(
|
||||||
uniqueElements: [
|
uniqueElements: [
|
||||||
.init(
|
.init(
|
||||||
id: UUID(0),
|
id: UUID(0),
|
||||||
@@ -303,7 +303,7 @@ private let flaggedMeasurements = IdentifiedArrayOf<SharedPressureEstimationSett
|
|||||||
store: Store(
|
store: Store(
|
||||||
initialState: FlaggedMeasurementsList.State(
|
initialState: FlaggedMeasurementsList.State(
|
||||||
sharedSettings: Shared(
|
sharedSettings: Shared(
|
||||||
SharedPressureEstimationSettings(
|
SharedPressureEstimationState(
|
||||||
budgets: budgets,
|
budgets: budgets,
|
||||||
equipmentMeasurement: .mock(type: .airHandler),
|
equipmentMeasurement: .mock(type: .airHandler),
|
||||||
flaggedEquipmentMeasurement: nil,
|
flaggedEquipmentMeasurement: nil,
|
||||||
|
|||||||
@@ -19,12 +19,12 @@ public struct PressureEstimationsFeature {
|
|||||||
@ObservableState
|
@ObservableState
|
||||||
public struct State: Equatable {
|
public struct State: Equatable {
|
||||||
@Presents public var destination: Destination.State?
|
@Presents public var destination: Destination.State?
|
||||||
@Shared(.sharedPressureEstimationSettings) var sharedSettings = SharedPressureEstimationSettings()
|
@Shared(.sharedPressureEstimationSettings) var sharedSettings = SharedPressureEstimationState()
|
||||||
public var equipmentSettings: EquipmentSettingsForm.State
|
public var equipmentSettings: EquipmentSettingsForm.State
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
destination: Destination.State? = nil,
|
destination: Destination.State? = nil,
|
||||||
sharedSettings: SharedPressureEstimationSettings = .init()
|
sharedSettings: SharedPressureEstimationState = .init()
|
||||||
) {
|
) {
|
||||||
self.destination = destination
|
self.destination = destination
|
||||||
self._sharedSettings = Shared(sharedSettings)
|
self._sharedSettings = Shared(sharedSettings)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import SharedModels
|
|||||||
|
|
||||||
/// Holds onto shared values for several of the views in this feature.
|
/// Holds onto shared values for several of the views in this feature.
|
||||||
@dynamicMemberLookup
|
@dynamicMemberLookup
|
||||||
public struct SharedPressureEstimationSettings: Equatable, Sendable {
|
public struct SharedPressureEstimationState: Equatable, Sendable {
|
||||||
public var budgets: BudgetedPercentEnvelope?
|
public var budgets: BudgetedPercentEnvelope?
|
||||||
public var equipmentMeasurement: EquipmentMeasurement?
|
public var equipmentMeasurement: EquipmentMeasurement?
|
||||||
public var equipmentMetadata: EquipmentMetadata
|
public var equipmentMetadata: EquipmentMetadata
|
||||||
@@ -53,7 +53,7 @@ public struct SharedPressureEstimationSettings: Equatable, Sendable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension PersistenceReaderKey where Self == InMemoryKey<SharedPressureEstimationSettings> {
|
extension PersistenceReaderKey where Self == InMemoryKey<SharedPressureEstimationState> {
|
||||||
static var sharedPressureEstimationSettings: Self {
|
static var sharedPressureEstimationSettings: Self {
|
||||||
.inMemory("sharedPressureEstimationSettings")
|
.inMemory("sharedPressureEstimationSettings")
|
||||||
}
|
}
|
||||||
@@ -49,11 +49,7 @@ public struct DefaultInfoButtonStyle<Style: LabelStyle>: PrimitiveButtonStyle {
|
|||||||
.foregroundStyle(color)
|
.foregroundStyle(color)
|
||||||
.labelStyle(labelStyle)
|
.labelStyle(labelStyle)
|
||||||
}
|
}
|
||||||
// configuration.label
|
.buttonStyle(.plain)
|
||||||
// .font(font)
|
|
||||||
// .foregroundStyle(color.opacity(configuration.isPressed ? 0.5 : 1))
|
|
||||||
// .labelStyle(labelStyle)
|
|
||||||
// .scaleEffect(configuration.isPressed ? 0.8 : 1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
17
Sources/Styleguide/Styles/TextLabeledContentStyle.swift
Normal file
17
Sources/Styleguide/Styles/TextLabeledContentStyle.swift
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
public struct GridRowTextLabeledContentStyle: LabeledContentStyle {
|
||||||
|
|
||||||
|
public func makeBody(configuration: Configuration) -> some View {
|
||||||
|
GridRow {
|
||||||
|
configuration.label
|
||||||
|
configuration.content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension LabeledContentStyle where Self == GridRowTextLabeledContentStyle {
|
||||||
|
public static var gridRow: Self {
|
||||||
|
GridRowTextLabeledContentStyle()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,6 +49,15 @@ extension TextLabeledContent where Label == Text {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
TextLabeledContent("Label") { Text("Content") }
|
VStack {
|
||||||
|
TextLabeledContent("Label") { Text("Content") }
|
||||||
|
.textLabelStyle(.boldSecondary)
|
||||||
|
|
||||||
|
Grid {
|
||||||
|
TextLabeledContent("One") { Text("One-Content") }
|
||||||
|
TextLabeledContent("Two") { Text("Two-Content") }
|
||||||
|
}
|
||||||
.textLabelStyle(.boldSecondary)
|
.textLabelStyle(.boldSecondary)
|
||||||
|
.labeledContentStyle(.gridRow)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user