Skip to content

Commit

Permalink
feat: 🎸 auto scrolling for step progress indicator (#575)
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaoyu0722 authored Jun 1, 2023
1 parent 392d04a commit a465fbd
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 12 deletions.
2 changes: 2 additions & 0 deletions Sources/FioriSwiftUICore/Models/ModelDefinitions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,8 @@ public protocol SingleStepModel {
// sourcery: virtualPropAxis = "var axis: Axis = .horizontal"
// sourcery: virtualPropStepsData = "var stepItems: [StepItem] = []"
// sourcery: virtualPropIsPresented = "@State var isPresented: Bool = false"
// sourcery: virtualPropStepFrames = "@State var stepFrames: [String: CGRect] = [:]"
// sourcery: virtualPropScrollBounds = "@State var scrollBounds: CGRect = .zero"
// sourcery: generated_component_composite
public protocol StepProgressIndicatorModel: AnyObject {
// sourcery: bindingProperty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,33 @@ extension StepProgressIndicator: View {
@ViewBuilder var stepsContainer: some View {
switch axis {
case .horizontal:
ScrollView(.horizontal, showsIndicators: false) {
StepProgressIndicatorContainer(selection: _selection,
steps: steps)
ScrollViewReader { proxy in
ScrollView(.horizontal, showsIndicators: false) {
StepProgressIndicatorContainer(selection: _selection,
steps: steps)
.environment(\.stepFrames, $stepFrames)
.onChange(of: _selection.wrappedValue) { newValue in
if let currentFrame = stepFrames[newValue],
!scrollBounds.contains(currentFrame)
{
withAnimation {
proxy.scrollTo(newValue, anchor: .leading)
}
}
}
}
}
.coordinateSpace(name: "SPICoordinateSpace")
.frameReader(in: .local) { rect in
scrollBounds = rect
}
case .vertical:
ScrollView(.vertical, showsIndicators: false) {
StepProgressIndicatorContainer(selection: _selection,
steps: steps)
}.padding(20)
ScrollViewReader { _ in
ScrollView(.vertical, showsIndicators: false) {
StepProgressIndicatorContainer(selection: _selection,
steps: steps)
}.padding(20)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,17 @@ extension EnvironmentValues {
}
}

struct StepFramesKey: EnvironmentKey {
static let defaultValue: Binding<[String: CGRect]> = .constant([:])
}

extension EnvironmentValues {
var stepFrames: Binding<[String: CGRect]> {
get { self[StepFramesKey.self] }
set { self[StepFramesKey.self] = newValue }
}
}

extension View {
func stepAxis(_ axis: Axis) -> some View {
self.environment(\.stepAxis, axis)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public struct _DefaultSteps: IndexedViewContainer {
selection: $selection,
isSubstep: isSubstep,
showLine: showLine)
.id(data.id)
if !data.substeps.isEmpty {
StepProgressIndicatorContainer(selection: $selection,
steps: _DefaultSteps(stepItems: data.substeps,
Expand All @@ -50,7 +51,8 @@ public struct _DefaultSteps: IndexedViewContainer {
struct DefaultSingleStep: View {
@Environment(\.dynamicTypeSize) var dynamicTypeSize
@Environment(\.stepAxis) var stepAxis

@Environment(\.stepFrames) var stepFrames

var stepItem: StepItem
@Binding var selection: String
var isSubstep: Bool = false
Expand All @@ -71,10 +73,15 @@ struct DefaultSingleStep: View {
}

var body: some View {
if isSubstep {
singleSubstep()
} else {
singleStep()
Group {
if isSubstep {
singleSubstep()
} else {
singleStep()
}
}
.frameReader(in: .named("SPICoordinateSpace")) { rect in
stepFrames.wrappedValue[stepItem.id] = rect
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ public struct StepProgressIndicator<Title: View, ActionView: View, Steps: Indexe
@Environment(\.cancelActionModifier) private var cancelActionModifier
@Environment(\.presentationMode) var presentationMode

@State var stepFrames: [String: CGRect] = [:]
@State var scrollBounds: CGRect = .zero

var _selection: Binding<String>
let _title: Title
let _action: ActionView
Expand Down

0 comments on commit a465fbd

Please sign in to comment.