Skip to content

Commit 32017c4

Browse files
committed
Add Slider and Double FormValue conformance
1 parent 0331e9e commit 32017c4

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

Sources/LiveViewNative/BuiltinRegistry.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ struct BuiltinRegistry {
6262
Toggle(element: element, context: context)
6363
case "menu":
6464
Menu(element: element, context: context)
65+
case "slider":
66+
Slider(element: element, context: context)
6567
case "phx-form":
6668
PhxForm<R>(element: element, context: context)
6769
case "phx-submit-button":

Sources/LiveViewNative/ViewModel.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,15 @@ extension Bool: FormValue {
219219
self = value
220220
}
221221
}
222+
223+
extension Double: FormValue {
224+
public var formValue: String {
225+
self.formatted()
226+
}
227+
228+
public init?(formValue: String) {
229+
guard let value = Double(formValue)
230+
else { return nil }
231+
self = value
232+
}
233+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//
2+
// Slider.swift
3+
//
4+
//
5+
// Created by Carson Katri on 1/24/23.
6+
//
7+
8+
import SwiftUI
9+
10+
struct Slider<R: CustomRegistry>: View {
11+
@ObservedElement private var element: ElementNode
12+
let context: LiveContext<R>
13+
14+
@FormState(default: 0) var value: Double
15+
16+
init(element: ElementNode, context: LiveContext<R>) {
17+
self.context = context
18+
}
19+
20+
public var body: some View {
21+
let lowerBound = element.attributeValue(for: "lower-bound").flatMap(Double.init) ?? 0
22+
let upperBound = element.attributeValue(for: "upper-bound").flatMap(Double.init) ?? 1
23+
if let step = element.attributeValue(for: "step").flatMap(Double.Stride.init) {
24+
SwiftUI.Slider(
25+
value: $value,
26+
in: lowerBound...upperBound,
27+
step: step
28+
) {
29+
context.buildChildren(of: element, defaultSlotFor: "slider")
30+
context.buildChildren(of: element, withTagName: "label", namespace: "slider")
31+
} minimumValueLabel: {
32+
context.buildChildren(of: element, withTagName: "minimum-value-label", namespace: "slider")
33+
} maximumValueLabel: {
34+
context.buildChildren(of: element, withTagName: "maximum-value-label", namespace: "slider")
35+
}
36+
} else {
37+
SwiftUI.Slider(
38+
value: $value,
39+
in: lowerBound...upperBound
40+
) {
41+
context.buildChildren(of: element, defaultSlotFor: "slider")
42+
context.buildChildren(of: element, withTagName: "label", namespace: "slider")
43+
} minimumValueLabel: {
44+
context.buildChildren(of: element, withTagName: "minimum-value-label", namespace: "slider")
45+
} maximumValueLabel: {
46+
context.buildChildren(of: element, withTagName: "maximum-value-label", namespace: "slider")
47+
}
48+
}
49+
}
50+
}

0 commit comments

Comments
 (0)