Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 🐛 [JIRA: 0] list picker item styles issue #802

Merged
merged 4 commits into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ struct ListPickerItemExample: View {
case identifiable
case objectItem
case stringItem
case differentStyles
case activeChildren
case searchable
case searchableListView
Expand Down Expand Up @@ -86,6 +87,12 @@ struct ListPickerItemExample: View {
{
Text("StringItem")
}
case .differentStyles:
NavigationLink(
destination: ListPickerItemStylesExample())
{
Text("Different Styles")
}
case .activeChildren:
NavigationLink(
destination: ListPickerItemActiveChildrenExample())
Expand Down Expand Up @@ -342,6 +349,40 @@ struct ListPickerItemActiveChildrenExample: View {
}
}

public struct ListPickerItemStylesExample: View {
private let model = ["First", "Second", "Third", "Fourth", "Fifth"]

@State var selections: Set<String> = ["Second"]

@State var isEnabled: Bool = true
@State var axis: Axis = .horizontal

public var body: some View {
List {
Section("List Picker Item") {
ListPickerItem(key: {
Text("Choice")
}, value: {
let str = Array(selections).joined(separator: ", ")
Text(str)
}, axis: self.axis,
configuration:
ListPickerItemConfiguration(self.model, selection: self.$selections))
.disabled(!self.isEnabled)
}

Section("Styles Panel") {
Toggle("Is Enabled", isOn: self.$isEnabled)
Picker("Axis", selection: self.$axis) {
Text("Horizontal").tag(Axis.horizontal)
Text("Vertical").tag(Axis.vertical)
}
}
}
.navigationBarTitle(Text("Form"))
}
}

struct ListPickerItemPreview: PreviewProvider {
static var previews: some View {
NavigationStack {
Expand Down
6 changes: 5 additions & 1 deletion Sources/FioriSwiftUICore/Models/ModelDefinitions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,11 @@ public protocol ActivityItemsModel: ActionItemsComponent {}
// sourcery: add_env_props = "listpickerListStyle"
// sourcery: add_env_props = "listPickerListViewModifier"
// sourcery: virtualPropDestinationConfiguration = "var destinationConfiguration: ListPickerItemConfiguration? = nil"
public protocol ListPickerItemModel: KeyComponent, ValueComponent {}
public protocol ListPickerItemModel: KeyComponent, ValueComponent {
// sourcery: default.value = .horizontal
// sourcery: no_view
var axis: Axis { get }
}

// sourcery: generated_component_not_configurable
public protocol ProgressIndicatorModel: ProgressIndicatorComponent {}
Expand Down
51 changes: 51 additions & 0 deletions Sources/FioriSwiftUICore/Utils/FioriVStack.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import SwiftUI

// This VStack will ignore subviews which width or height is 0, so no extra space will be added.
struct CompactVStack: Layout {
var alignment: HorizontalAlignment
var spacing: CGFloat

init(alignment: HorizontalAlignment = .center, spacing: CGFloat = 8) {
self.alignment = alignment
self.spacing = spacing
}

func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
guard let containerWidth = proposal.width else { return }
var currentY: CGFloat = bounds.minY
for subview in subviews {
let size = subview.sizeThatFits(ProposedViewSize(width: containerWidth, height: nil))
let xPosition: CGFloat
switch self.alignment {
case .leading:
xPosition = bounds.minX
case .trailing:
xPosition = bounds.maxX - size.width
default:
xPosition = bounds.midX - size.width / 2
}

subview.place(at: CGPoint(x: xPosition, y: currentY), proposal: ProposedViewSize(width: containerWidth, height: size.height))
currentY += size.height + self.spacing
}
}

func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
guard let containerWidth = proposal.width else { return .zero }
var totalHeight: CGFloat = 0
var maxWidth: CGFloat = 0

for subview in subviews {
let size = subview.sizeThatFits(ProposedViewSize(width: containerWidth, height: nil))
if size.width > 0, size.height > 0 {
totalHeight += size.height
maxWidth = max(maxWidth, size.width)
totalHeight += self.spacing
}
}
if totalHeight > 0 {
totalHeight -= self.spacing
}
return CGSize(width: maxWidth, height: totalHeight)
}
}
7 changes: 1 addition & 6 deletions Sources/FioriSwiftUICore/Views/KeyValueItem+View.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import Foundation
import SwiftUI

// TODO: - Implement Fiori style definitions

extension Fiori {
enum KeyValueItem {
typealias KeyCumulative = EmptyModifier
Expand Down Expand Up @@ -32,11 +30,9 @@ extension Fiori {
}
}

// TODO: - Implement KeyValueItem View body

extension KeyValueItem: View {
public var body: some View {
VStack(alignment: .leading) {
CompactVStack(alignment: .leading) {
if _axis == .horizontal {
HStack {
key
Expand All @@ -46,7 +42,6 @@ extension KeyValueItem: View {
.frame(maxWidth: .infinity)
} else {
key
.padding(.bottom, 3)
value
}
}
Expand Down
12 changes: 7 additions & 5 deletions Sources/FioriSwiftUICore/Views/ListPickerItem+View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ extension Fiori {
enum ListPickerItem {
struct Key: ViewModifier {
func body(content: Content) -> some View {
content.font(.fiori(forTextStyle: .headline)).foregroundColor(.preferredColor(.primaryLabel))
content.font(.fiori(forTextStyle: .subheadline, weight: .bold)).foregroundColor(.preferredColor(.primaryLabel))
}
}

Expand All @@ -34,11 +34,11 @@ extension ListPickerItem: View {
NavigationLink(
destination: self.destinationView,
label: {
KeyValueItem {
KeyValueItem(key: {
key
} value: {
}, value: {
value
}
}, axis: _axis)
}
)
}
Expand All @@ -62,13 +62,15 @@ public extension ListPickerItem {
/// - Parameters:
/// - key: The key view of the list.
/// - value: The value view of the list.
/// - axis: Axis for key and value layout.
/// - configuration: The configuration for constructing the list picker.
init(
@ViewBuilder key: @escaping () -> Key,
@ViewBuilder value: @escaping () -> Value,
axis: Axis = .horizontal,
configuration: ListPickerItemConfiguration? = nil
) {
self.init(key: key, value: value)
self.init(key: key, value: value, axis: axis)
self.destinationConfiguration = configuration
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,19 @@ public struct ListPickerItem<Key: View, Value: View> {

let _key: Key
let _value: Value
let _axis: Axis
var destinationConfiguration: ListPickerItemConfiguration? = nil
private var isModelInit: Bool = false
private var isValueNil: Bool = false

public init(
@ViewBuilder key: () -> Key,
@ViewBuilder value: () -> Value
@ViewBuilder value: () -> Value,
axis: Axis = .horizontal
) {
self._key = key()
self._value = value()
self._axis = axis
}

@ViewBuilder var key: some View {
Expand All @@ -47,12 +50,13 @@ extension ListPickerItem where Key == Text,
Value == _ConditionalContent<Text, EmptyView> {

public init(model: ListPickerItemModel) {
self.init(key: model.key, value: model.value)
self.init(key: model.key, value: model.value, axis: model.axis)
}

public init(key: String, value: String? = nil) {
public init(key: String, value: String? = nil, axis: Axis = .horizontal) {
self._key = Text(key)
self._value = value != nil ? ViewBuilder.buildEither(first: Text(value!)) : ViewBuilder.buildEither(second: EmptyView())
self._axis = axis

isModelInit = true
isValueNil = value == nil ? true : false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import SwiftUI

extension ListPickerItem where Value == EmptyView {
public init(
@ViewBuilder key: () -> Key
@ViewBuilder key: () -> Key,
axis: Axis = .horizontal
) {
self.init(
key: key,
value: { EmptyView() }
value: { EmptyView() },
axis: axis
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Generated using Sourcery 2.1.7 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
import SwiftUI

public extension ListPickerItemModel {
var axis: Axis {
return .horizontal
}
}
Loading