InstructionList.swift 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. //
  2. // InstructionList.swift
  3. // LoopKitUI
  4. //
  5. // Created by Nathaniel Hamming on 2020-02-20.
  6. // Copyright © 2020 LoopKit Authors. All rights reserved.
  7. //
  8. import SwiftUI
  9. public struct InstructionList: View {
  10. struct Instruction {
  11. let text: String
  12. let subtext: String?
  13. }
  14. let instructions: [Instruction]
  15. let startingIndex: Int
  16. let instructionColor: Color
  17. @Environment(\.isEnabled) var isEnabled
  18. public init(instructions: [String], startingIndex: Int = 1, instructionColor: Color = .primary) {
  19. self.instructions = instructions.map { Instruction(text: $0, subtext: nil) }
  20. self.startingIndex = startingIndex
  21. self.instructionColor = instructionColor
  22. }
  23. public init(instructions: [(String, String)], startingIndex: Int = 1, instructionColor: Color = .primary) {
  24. self.instructions = instructions.map { Instruction(text: $0.0, subtext: $0.1) }
  25. self.startingIndex = startingIndex
  26. self.instructionColor = instructionColor
  27. }
  28. public var body: some View {
  29. VStack(alignment: .leading, spacing: 10) {
  30. ForEach(instructions.indices, id: \.self) { index in
  31. HStack(alignment: .top) {
  32. Text("\(index+startingIndex)")
  33. .opacity(isEnabled ? 1.0 : 0.8)
  34. .padding(6)
  35. .background(Circle().fill(Color.accentColor))
  36. .foregroundColor(Color.white)
  37. .font(.caption)
  38. .accessibility(label: Text("\(index+1), ")) // Adds a pause after the number
  39. instructionView(instructions[index])
  40. }
  41. .accessibilityElement(children: .combine)
  42. }
  43. }
  44. }
  45. @ViewBuilder
  46. private func instructionView(_ instruction: Instruction) -> some View {
  47. VStack(alignment: .leading, spacing: 2) {
  48. Text(instruction.text)
  49. .fixedSize(horizontal: false, vertical: true)
  50. if let subtext = instruction.subtext {
  51. Text(subtext)
  52. .fixedSize(horizontal: false, vertical: true)
  53. .foregroundColor(isEnabled ? instructionColor : Color.secondary)
  54. .font(.caption)
  55. }
  56. }
  57. .padding(2)
  58. .foregroundColor(isEnabled ? instructionColor : Color.secondary)
  59. }
  60. }
  61. struct InstructionList_Previews: PreviewProvider {
  62. static var previews: some View {
  63. let instructions: [String] = [
  64. "This is the first step.",
  65. "This second step is a bit more tricky and needs more description to support the user, albeit it could be more concise.",
  66. "With this final step, the task will be accomplished."
  67. ]
  68. return InstructionList(instructions: instructions)
  69. }
  70. }