### Basic RadialPad Usage Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/RadialPadGuide.md Demonstrates the basic setup for RadialPad, binding to offset and angle states. ```swift import SwiftUI struct ContentView: View { @State var dist = 0.0 @State var dir = Angle.zero var body: some View { RadialPad(offset: $dist, angle: $dir) .frame(width: 260, height: 260) } } ``` -------------------------------- ### Preview Documentation Locally Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Building_Documentation.md Tests the generated documentation webpage locally by starting a preview server. The --disable-sandbox flag is used for this command. ```sh swift package --disable-sandbox preview-documentation --target Sliders ``` -------------------------------- ### Basic LSlider Examples Source: https://context7.com/kieranb662/sliders-swiftui/llms.txt Demonstrates horizontal, vertical, and step-spaced tick mark configurations for LSlider. Ensure the Sliders and SwiftUI frameworks are imported. ```swift import Sliders import SwiftUI struct AudioMixerView: View { @State private var volume = 0.7 @State private var bass = 0.4 @State private var treble = 0.6 var body: some View { VStack(spacing: 24) { // Horizontal slider with tick marks and haptics LSlider( $volume, range: 0...1, keepThumbInTrack: true, trackThickness: 20, tickMarkSpacing: .count(11), hapticFeedbackEnabled: true ) { Label("\(Int(value * 100))%", systemImage: "speaker.wave.2") } .frame(height: 60) // Vertical slider (90 °) LSlider($bass, range: 0...1, angle: .degrees(90), keepThumbInTrack: true) .frame(width: 60, height: 200) // Step-spaced ticks every 0.1 LSlider( $treble, range: 0...1, keepThumbInTrack: true, trackThickness: 20, tickMarkSpacing: .spacing(0.1), hapticFeedbackEnabled: true ) .frame(height: 60) } .padding() .labelsVisibility(.hidden) // hides all floating labels in this VStack } } ``` -------------------------------- ### DoubleRSlider Examples Source: https://context7.com/kieranb662/sliders-swiftui/llms.txt Demonstrates various configurations of DoubleRSlider, including clock-face range selection, snap-enabled 0-1 range, and custom styling. ```swift import Sliders import SwiftUI struct TimeWindowView: View { @State private var startHour = 8.0 @State private var endHour = 17.0 var body: some View { VStack(spacing: 24) { // Clock-face range selector DoubleRSlider( lowerValue: $startHour, upperValue: $endHour, range: 0...24, originAngle: .degrees(-90), minimumDistance: 1, tickSpacing: .count(25) ) { v in Text(String(format: "%02d:00", Int(v))) } upperLabel: { v in Text(String(format: "%02d:00", Int(v))) } .frame(width: 260, height: 260) // Snap-enabled 0…1 range DoubleRSlider( lowerValue: $startHour, upperValue: $endHour, range: 0...1, tickSpacing: .count(9), affinityEnabled: true, affinityRadius: 0.03, affinityResistance: 0.015 ) .frame(width: 220, height: 220) // Built-in default style DoubleRSlider(lowerValue: $startHour, upperValue: $endHour, range: 0...24) .doubleRadialSliderStyle( .default( trackColor: Color(white: 0.25), trackFilledColor: .indigo, lowerThumbColor: .white, upperThumbColor: .white, activeThumbColor: .cyan, trackThickness: 20 ) ) .frame(width: 220, height: 220) } } } ``` -------------------------------- ### Custom OverflowSlider Style Implementation Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/OverflowSliderGuide.md Provides an example of a custom `OverflowSliderStyle` by implementing `makeThumb` and `makeTrack` methods. This allows for custom visual appearances for the slider's thumb and track. ```swift struct MyOverflowSliderStyle: OverflowSliderStyle { func makeThumb(configuration: OverflowSliderConfiguration) -> some View { RoundedRectangle(cornerRadius: 5) .fill(configuration.thumbIsActive ? Color.orange : Color.blue) .opacity(0.5) .frame(width: 20, height: 50) } func makeTrack(configuration: OverflowSliderConfiguration) -> some View { let totalLength = configuration.max - configuration.min let spacing = configuration.tickSpacing return TickMarks( spacing: CGFloat(spacing), ticks: Int(totalLength / Double(spacing)) ) .stroke(Color.gray) .frame(width: CGFloat(totalLength)) } } ``` -------------------------------- ### Reading Joystick State Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/JoystickGuide.md This example demonstrates how to read and display the current state of the Joystick, including its angle, radial offset, and lock status. Use the computed properties of `JoyState` to access this information. ```swift @State private var joyState: JoyState = .inactive VStack { Text("Angle: \(joyState.angle.degrees, specifier: \"%.0f\")°") Text("Offset: \(joyState.radialOffset, specifier: \"%.1f\")") Text("Locked: \(joyState.isLocked ? \"Yes\" : \"No\")") Joystick(state: $joyState, radius: 60) .frame(width: 300, height: 300) } ``` -------------------------------- ### OverflowSlider for Timeline Scrubbing Source: https://context7.com/kieranb662/sliders-swiftui/llms.txt Shows how to use OverflowSlider for a meter-style velocity slider, ideal for navigating large value domains. Includes examples with different ranges and custom styles. ```swift import Sliders import SwiftUI struct TimelineScrubbingView: View { @State private var position = 250.0 var body: some View { VStack(spacing: 16) { Text("Position: \(Int(position))") .font(.headline.monospacedDigit()) // Fine-grained 0…500 range with tick every 10 units OverflowSlider(value: $position, range: 0...500, spacing: 10, isDisabled: false) .overflowSliderStyle(MyOverflowSliderStyle()) .frame(height: 60) // Coarser 0…1000 range OverflowSlider(value: $position, range: 0...1000, spacing: 25, isDisabled: false) .frame(height: 60) } .padding() } } struct MyOverflowSliderStyle: OverflowSliderStyle { func makeThumb(configuration: OverflowSliderConfiguration) -> some View { RoundedRectangle(cornerRadius: 5) .fill(configuration.thumbIsActive ? Color.orange : Color.blue) .opacity(0.5) .frame(width: 20, height: 50) } func makeTrack(configuration: OverflowSliderConfiguration) -> some View { let totalLength = configuration.max - configuration.min return TickMarks( spacing: CGFloat(configuration.tickSpacing), ticks: Int(totalLength / configuration.tickSpacing) ) .stroke(Color.gray) .frame(width: CGFloat(totalLength)) } } ``` -------------------------------- ### Configure Labels for DoubleRSlider Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/DoubleRSliderGuide.md Customize the floating labels displayed near each thumb by providing custom view builders for `lowerLabel` and `upperLabel`. This example sets the range from 0 to 100. ```swift @State private var lower = 0.25 @State private var upper = 0.75 DoubleRSlider( lowerValue: $lower, upperValue: $upper, range: 0...100 ) { Text("from \(Int(v))") } upperLabel: { Text("to \(Int(v))") } .frame(width: 220, height: 220) ``` -------------------------------- ### Diagonal DoubleLSlider Orientation Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/DoubleLSliderGuide.md Configure a slider at an angle by specifying the `angle` parameter in degrees. This example shows a 30-degree orientation. ```swift @State private var lower = 0.2 @State private var upper = 0.8 DoubleLSlider( lowerValue: $lower, upperValue: $upper, range: 0...1, angle: .degrees(30), keepThumbInTrack: true, trackThickness: 20 ) .frame(width: 300, height: 120) ``` -------------------------------- ### RSlider with Multiple Rotations Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/RSliderGuide.md Control the number of full rotations the slider thumb can complete within the specified range using the `maxWinds` parameter. This example allows for 3 full rotations. ```swift @State private var revolutionsValue = 0.0 RSlider($revolutionsValue, range: 0...1, maxWinds: 3) .frame(width: 220, height: 220) ``` -------------------------------- ### RSlider with Custom Range and Origin Angle Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/RSliderGuide.md Configure the slider's value range and the starting angle for the minimum value using `range` and `originAngle`. `originAngle: .degrees(-90)` places the minimum value at the top. ```swift @State private var temperature = 20.0 RSlider($temperature, range: 0...100, originAngle: .degrees(-90)) .frame(width: 220, height: 220) ``` -------------------------------- ### Configure Tick Marks for DoubleRSlider Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/DoubleRSliderGuide.md Display tick marks on the slider track by providing a `TickMarkSpacing` value to the `tickSpacing` parameter. This example uses `.count(9)` to show 9 ticks. ```swift DoubleRSlider( lowerValue: $lower, upperValue: $upper, range: 0...1, tickSpacing: .count(9) ) .frame(width: 220, height: 220) ``` -------------------------------- ### Displaying Tick Marks with Count Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/DoubleLSliderGuide.md Add evenly spaced tick marks to the slider track by using the `.count(n)` option for `tickMarkSpacing`. This example shows 11 tick marks. ```swift DoubleLSlider( lowerValue: $lower, upperValue: $upper, range: 0...1, keepThumbInTrack: true, trackThickness: 20, tickMarkSpacing: .count(11) ) .frame(height: 60) ``` -------------------------------- ### LSlider with Specific Tick Mark Values Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/LSliderGuide.md Define precise tick mark locations using `.values([...])`, providing an array of specific values within the range where tick marks should appear. Haptic feedback is explicitly disabled in this example. ```swift @State var position = 0.5 LSlider( $position, range: 0...1, keepThumbInTrack: true, trackThickness: 20, tickMarkSpacing: .values([0.0, 0.25, 0.5, 0.75, 1.0]), hapticFeedbackEnabled: false ) .frame(height: 60) ``` -------------------------------- ### Apply Cascading Styles to LSliders Source: https://context7.com/kieranb662/sliders-swiftui/llms.txt Apply a style modifier to a container view to affect all LSliders within it. This example demonstrates hiding labels and applying a custom bar style to multiple sliders. ```swift import Sliders import SwiftUI // One style modifier on a container applies to every LSlider inside struct RGBSliderPanel: View { @State private var red = 0.8 @State private var green = 0.3 @State private var blue = 0.6 var body: some View { VStack(spacing: 12) { LSlider($red, range: 0...1) LSlider($green, range: 0...1) LSlider($blue, range: 0...1) } .linearSliderStyle(BarLSliderStyle()) // cascades to all three LSliders .labelsVisibility(.hidden) // cascades to hide all labels .padding() .background(Color.black.cornerRadius(16)) } } ``` -------------------------------- ### Basic Joystick Usage Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/JoystickGuide.md This snippet shows the fundamental way to initialize a Joystick with a binding to its state and a specified radius. Ensure you have a `@State` variable for `JoyState` to manage the joystick's behavior. ```swift @State private var joyState: JoyState = .inactive Joystick(state: $joyState, radius: 60) .frame(width: 300, height: 300) ``` -------------------------------- ### RadialPad with Customizations Source: https://context7.com/kieranb662/sliders-swiftui/llms.txt Shows how to use RadialPad with a previous-value ghost marker, polar tick grids, and single-tap placement for intuitive 2D polar control. ```swift import Sliders import SwiftUI struct PolarControlView: View { @State var dist = 0.0 @State var dir = Angle.zero var body: some View { VStack(spacing: 20) { Text(String(format: "%.0f° r=%.2f", dir.degrees, dist)) .font(.caption.monospacedDigit()) RadialPad(offset: $dist, angle: $dir) { offset, angle in Text(String(format: "r=%.2f", offset)) } // Previous-value ghost marker with snap .showPreviousValue(true) // 4 radial rings + 8 angular spokes = 32 snap intersections .tickCountR(4) .tickCountTheta(8) // Allow a single tap to place the thumb .allowsSingleTapSelect(true) .frame(width: 260, height: 260) } } } ``` -------------------------------- ### Basic OverflowSlider Usage Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/OverflowSliderGuide.md Demonstrates the fundamental initialization of an OverflowSlider with essential parameters: value binding, range, and tick spacing. The frame height is also set. ```swift @State private var value = 50.0 OverflowSlider(value: $value, range: 0...500, spacing: 10, isDisabled: false) .frame(height: 60) ``` -------------------------------- ### Basic TrackPad Usage Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/TrackPadGuide.md Initialize a TrackPad with a binding to a CGPoint. The default ranges for x and y are 0...1. Ensure the TrackPad has a defined frame height. ```swift @State var point = CGPoint(x: 0.5, y: 0.5) TrackPad($point) .frame(height: 260) ``` -------------------------------- ### Generate Documentation Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Building_Documentation.md Generates static documentation files for the Sliders target and outputs them to the ./docs directory. Use --allow-writing-to-directory to specify the output location. ```sh swift package --allow-writing-to-directory ./docs \ generate-documentation --target Sliders \ --disable-indexing \ --transform-for-static-hosting \ --hosting-base-path Sliders-SwiftUI \ --output-path ./docs ``` -------------------------------- ### RSlider - Circular Slider with Custom Labels and Range Source: https://context7.com/kieranb662/sliders-swiftui/llms.txt Use RSlider for circular range selection. Customize the starting angle and range for fine-grained control. Supports snapping to tick marks. ```swift import Sliders import SwiftUI struct SpeedometerView: View { @State private var speed = 0.0 var body: some View { VStack(spacing: 32) { // Circular slider starting at top (12 o'clock) with km/h label RSlider($speed, range: 0...200, originAngle: .degrees(-90)) { Text("\(Int(value)) km/h") .font(.headline) } .frame(width: 220, height: 220) // Three-rotation slider for precise trimming RSlider($speed, range: 0...1, maxWinds: 3) .frame(width: 220, height: 220) // Snapping radial slider RSlider( $speed, range: 0...1, tickSpacing: .count(11), affinityEnabled: true, affinityRadius: 0.02, affinityResistance: 0.01 ) .frame(width: 220, height: 220) } } } // Custom radial style struct CyanRSliderStyle: RSliderStyle { func makeThumb(configuration: RSliderConfiguration) -> some View { Circle() .fill(configuration.isActive ? Color.cyan : Color.white) .frame(width: 28, height: 28) .shadow(radius: 2) } func makeTrack(configuration: RSliderConfiguration) -> some View { ZStack { Circle().stroke(Color.gray.opacity(0.3), lineWidth: 18) CircularArc(percent: configuration.withinWind) .stroke(Color.cyan, style: StrokeStyle(lineWidth: 18, lineCap: .round)) } .padding(9) } func makeTickMark(configuration: RSliderConfiguration, tickValue: Double) -> some View { let range = configuration.max - configuration.min let thumbPct = range > 0 ? (configuration.value - configuration.min) / range : 0 let tickPct = range > 0 ? (tickValue - configuration.min) / range : 0 let proximity = max(0, 1 - abs(thumbPct - tickPct) / 0.20) return Circle() .fill(Color.white.opacity(0.35 + 0.65 * proximity)) .frame(width: 4 + 6 * proximity, height: 4 + 6 * proximity) } } RSlider($speed) .radialSliderStyle(CyanRSliderStyle()) .frame(width: 220, height: 220) ``` -------------------------------- ### Basic PSlider Usage Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/PSliderGuide.md Use any SwiftUI Shape as the track for a PSlider. Ensure the binding for the value is provided. ```swift PSlider($value, shape: Circle()) .frame(width: 200, height: 200) ``` -------------------------------- ### TrackPad with Separate Double Bindings Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/TrackPadGuide.md If your model uses separate `Double` properties for x and y, use the `x:` and `y:` initializers to bind them directly to the TrackPad. This avoids the need for a `CGPoint` if your data structure differs. ```swift @State var pan: Double = 0.0 @State var tilt: Double = 0.0 TrackPad(x: $pan, y: $tilt, rangeX: -1...1, rangeY: -1...1) .frame(height: 260) ``` -------------------------------- ### TrackPad with Custom Ranges Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/TrackPadGuide.md Configure the TrackPad with custom ranges for the x and y axes using `rangeX` and `rangeY`. This allows for different domains for each axis. ```swift TrackPad($point, rangeX: -1...1, rangeY: 0...10) .frame(height: 260) ``` -------------------------------- ### Basic LSlider Usage in SwiftUI Source: https://github.com/kieranb662/sliders-swiftui/blob/master/README.md Demonstrates how to use the LSlider control in a SwiftUI view. Ensure the Sliders framework is imported. The slider's value is bound to a @State variable. ```swift import Sliders struct ContentView: View { @State private var value = 0.5 var body: some View { LSlider($value, range: 0...1, keepThumbInTrack: true, trackThickness: 20) .frame(height: 60) .padding() } } ``` -------------------------------- ### TickMarkSpacing Configuration for LSlider Source: https://context7.com/kieranb662/sliders-swiftui/llms.txt Illustrates different ways to configure tick mark spacing for LSlider using .count, .spacing, and .values options. Haptic feedback can also be enabled or disabled. ```swift import Sliders import SwiftUI struct TickMarkExamplesView: View { @State private var valueA = 0.5 @State private var valueB = 5.0 @State private var valueC = 0.5 var body: some View { VStack(spacing: 20) { // .count(n) — exactly n evenly distributed ticks including endpoints LSlider($valueA, range: 0...1, keepThumbInTrack: true, tickMarkSpacing: .count(11), hapticFeedbackEnabled: true) .frame(height: 60) // .spacing(step) — one tick every `step` value units LSlider($valueB, range: 0...10, keepThumbInTrack: true, tickMarkSpacing: .spacing(1), hapticFeedbackEnabled: true) .frame(height: 60) // .values([...]) — ticks at specific values LSlider($valueC, range: 0...1, keepThumbInTrack: true, tickMarkSpacing: .values([0.0, 0.25, 0.5, 0.75, 1.0]), hapticFeedbackEnabled: false) .frame(height: 60) } .padding() } } ``` -------------------------------- ### Joystick with Custom Style Source: https://context7.com/kieranb662/sliders-swiftui/llms.txt Illustrates a Joystick component with a custom style, including definitions for hit-box, lock-box, track, and thumb appearance. It also displays the current joystick state. ```swift import Sliders import SwiftUI struct GameControlView: View { @State private var joyState: JoyState = .inactive var body: some View { VStack { HStack(spacing: 16) { Text("Angle: \(joyState.angle.degrees, specifier: \"%.0f\")°") Text("Offset: \(joyState.radialOffset, specifier: \"%.2f\")") Text(joyState.isLocked ? "🔒 Locked" : joyState.isDragging ? "✋ Drag" : "💤 Idle") } .font(.caption.monospacedDigit()) Joystick(state: $joyState, radius: 60, canLock: true, isDisabled: false) .joystickStyle(MyJoystickStyle()) .frame(width: 300, height: 300) } } } struct MyJoystickStyle: JoystickStyle { func makeHitBox(configuration: JoystickConfiguration) -> some View { Rectangle().fill(Color.white.opacity(0.05)) } func makeLockBox(configuration: JoystickConfiguration) -> some View { ZStack { Circle().fill(Color.black) Circle().fill(Color.yellow).scaleEffect(0.7) } .frame(width: 25, height: 25) } func makeTrack(configuration: JoystickConfiguration) -> some View { Circle().fill(Color.gray.opacity(0.4)) } func makeThumb(configuration: JoystickConfiguration) -> some View { Circle() .fill(configuration.isActive ? Color.green : Color.blue) .frame(width: 45, height: 45) } } ``` -------------------------------- ### Implement Custom RSlider Style Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/RSliderGuide.md Conform to RSliderStyle and implement makeThumb, makeTrack, and makeTickMark to define the visual appearance of the slider. Use RSliderConfiguration to access the slider's current state. ```swift struct ExampleRSliderStyle: RSliderStyle { func makeThumb(configuration: RSliderConfiguration) -> some View { Circle() .fill(configuration.isActive ? Color.cyan : Color.white) .frame(width: 28, height: 28) .shadow(radius: 2) } func makeTrack(configuration: RSliderConfiguration) -> some View { ZStack { Circle() .stroke(Color.gray.opacity(0.3), lineWidth: 18) CircularArc(percent: configuration.withinWind) .stroke(Color.cyan, style: StrokeStyle(lineWidth: 18, lineCap: .round)) } .padding(9) } func makeTickMark(configuration: RSliderConfiguration, tickValue: Double) -> some View { let range = configuration.max - configuration.min let thumbPct = range > 0 ? (configuration.value - configuration.min) / range : 0 let tickPct = range > 0 ? (tickValue - configuration.min) / range : 0 let proximity = max(0, 1 - abs(thumbPct - tickPct) / 0.20) let size = 4.0 + 6.0 * proximity let opacity = 0.35 + 0.65 * proximity return Circle() .fill(Color.white.opacity(opacity)) .frame(width: size, height: size) .animation(.easeOut(duration: 0.1), value: proximity) } } ``` -------------------------------- ### Custom PSlider Style Implementation Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/PSliderGuide.md Implement PSliderStyle by defining makeThumb and makeTrack methods to customize the slider's appearance. The thumb can be styled based on its active state, and the track can be visually represented using the shape and fill percentage. ```swift struct MyPSliderStyle: PSliderStyle { func makeThumb(configuration: PSliderConfiguration) -> some View { Circle() .frame(width: 30, height: 30) .foregroundColor(configuration.isActive ? Color.yellow : Color.white) } func makeTrack(configuration: PSliderConfiguration) -> some View { ZStack { configuration.shape .stroke(Color.gray, lineWidth: 8) configuration.shape .trim(from: 0, to: CGFloat(configuration.pctFill)) .stroke(Color.purple, lineWidth: 10) } } } ``` -------------------------------- ### PSlider with Circle and RoundedRectangle Paths Source: https://context7.com/kieranb662/sliders-swiftui/llms.txt Demonstrates using PSlider with different SwiftUI Shapes like Circle and RoundedRectangle. Custom styles can be applied to modify the thumb and track appearance. ```swift import Sliders import SwiftUI struct ShapeSliderDemoView: View { @State private var progress = 0.5 @State private var hue = 0.0 var body: some View { VStack(spacing: 40) { // Circle path PSlider($progress, shape: Circle()) .pathSliderStyle(MyPSliderStyle()) .frame(width: 200, height: 200) // Rounded-rectangle path with custom range PSlider($hue, range: 0...360, shape: RoundedRectangle(cornerRadius: 20)) .pathSliderStyle(MyPSliderStyle()) .frame(width: 250, height: 150) } } } struct MyPSliderStyle: PSliderStyle { func makeThumb(configuration: PSliderConfiguration) -> some View { Circle() .foregroundColor(configuration.isActive ? .yellow : .white) .frame(width: 30, height: 30) } func makeTrack(configuration: PSliderConfiguration) -> some View { ZStack { configuration.shape.stroke(Color.gray, lineWidth: 8) configuration.shape .trim(from: 0, to: CGFloat(configuration.pctFill)) .stroke(Color.purple, lineWidth: 10) } } } ``` -------------------------------- ### TrackPad with Previous Value Indicator Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/TrackPadGuide.md Enable the previous value indicator by setting `showPreviousValue` to `true`. This displays a ghost marker at the last committed position, aiding in returning to previous states. ```swift TrackPad($point) .showPreviousValue(true) .frame(height: 260) ``` -------------------------------- ### Applying a Custom OverflowSlider Style Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/OverflowSliderGuide.md Demonstrates how to apply a custom style, `MyOverflowSliderStyle`, to an `OverflowSlider` using the `.overflowSliderStyle()` modifier. This customizes the slider's appearance. ```swift OverflowSlider(value: $value, range: 0...500, spacing: 10, isDisabled: false) .overflowSliderStyle(MyOverflowSliderStyle()) .frame(height: 60) ``` -------------------------------- ### TrackPad with Independent Tick Counts Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/TrackPadGuide.md Specify different numbers of tick marks for the x and y axes using `tickCountX` and `tickCountY`. This allows for asymmetrical grids, providing more granular control where needed. ```swift TrackPad($point) .tickCountX(3) .tickCountY(5) .frame(height: 260) ``` -------------------------------- ### Custom Joystick Styling Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/JoystickGuide.md Implement the `JoystickStyle` protocol to create custom views for the joystick's hit-box, lock-box, track, and thumb. Apply your custom style using the `.joystickStyle()` modifier. ```swift struct MyJoystickStyle: JoystickStyle { func makeHitBox(configuration: JoystickConfiguration) -> some View { Rectangle() .fill(Color.white.opacity(0.05)) } func makeLockBox(configuration: JoystickConfiguration) -> some View { ZStack { Circle().fill(Color.black) Circle().fill(Color.yellow).scaleEffect(0.7) } .frame(width: 25, height: 25) } func makeTrack(configuration: JoystickConfiguration) -> some View { Circle() .fill(Color.gray.opacity(0.4)) } func makeThumb(configuration: JoystickConfiguration) -> some View { Circle() .fill(configuration.isActive ? Color.green : Color.blue) .frame(width: 45, height: 45) } } ``` -------------------------------- ### TrackPad with Custom Label Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/TrackPadGuide.md Use a custom label to display the current x and y values. The label updates live as the thumb is dragged. Ensure the TrackPad has a defined frame height. ```swift @State var point = CGPoint(x: 0.5, y: 0.5) TrackPad($point, rangeX: -1...1, rangeY: -1...1) { Text(String(format: "x: %.2f y: %.2f", x, y)) } .frame(height: 260) ``` -------------------------------- ### TrackPad with Shared Range Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/TrackPadGuide.md When both axes share the same domain, you can use the `range` parameter for a concise configuration. This sets both `rangeX` and `rangeY` to the same specified range. ```swift TrackPad($point, range: 0...100) .frame(height: 260) ``` -------------------------------- ### Add Sliders-SwiftUI Package to Package.swift Source: https://github.com/kieranb662/sliders-swiftui/blob/master/README.md Integrate the Sliders-SwiftUI package into your project by adding the provided dependency to your Package.swift file. Ensure you specify a version constraint. ```swift dependencies: [ .package(url: "https://github.com/kieranb662/Sliders-SwiftUI", from: "1.0.0") ] ``` -------------------------------- ### Customizing TrackPad Default Style Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/TrackPadGuide.md Apply the default TrackPad style with custom colors and thumb size. This is useful for quick visual adjustments without defining a full custom style. ```swift TrackPad($point) .trackPadStyle( .default( trackColor: Color.indigo.opacity(0.15), trackStrokeColor: Color.indigo, thumbInactiveColor: Color.indigo, thumbActiveColor: Color.white, thumbSize: 44 ) ) .frame(height: 260) ``` -------------------------------- ### Apply Custom Default Styling Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/DoubleLSliderGuide.md Customize the appearance of the DoubleLSlider using the `.default()` style initializer. You can modify colors for tracks, thumbs, and specify track thickness. ```swift DoubleLSlider(lowerValue: $lower, upperValue: $upper) .doubleLSliderStyle( .default( trackColor: Color(white: 0.25), trackFilledColor: .indigo, lowerThumbColor: .white, upperThumbColor: .white, activeThumbColor: .cyan, trackThickness: 20 ) ) .frame(height: 60) ``` -------------------------------- ### Enable Tick Affinity (Snapping) for DoubleRSlider Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/DoubleRSliderGuide.md Enable snapping behavior for the thumbs to align with tick marks by setting `affinityEnabled` to `true`. Configure the snap radius and resistance with `affinityRadius` and `affinityResistance`. ```swift DoubleRSlider( lowerValue: $lower, upperValue: $upper, range: 0...1, tickSpacing: .count(9), affinityEnabled: true, affinityRadius: 0.03, affinityResistance: 0.015 ) .frame(width: 220, height: 220) ``` -------------------------------- ### RadialPad with Previous Value Indicator Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/RadialPadGuide.md Enables the 'previous value indicator' on RadialPad, which shows a ghost marker at the last committed position. ```swift RadialPad(offset: $dist, angle: $dir) .showPreviousValue(true) .frame(width: 260, height: 260) ``` -------------------------------- ### TrackPad with Default Tick Marks Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/TrackPadGuide.md Divide the TrackPad into a regular grid by setting `tickCount` to a positive integer. This enables snapping to the nearest tick intersection. The default behavior divides both axes equally. ```swift TrackPad($point) .tickCount(4) .frame(height: 260) ``` -------------------------------- ### Basic Horizontal LSlider Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/LSliderGuide.md Configure a basic horizontal LSlider with a specified range and track thickness. The `keepThumbInTrack` parameter ensures the thumb remains within the visible track. ```swift @State var volume = 0.5 LSlider($volume, range: 0...1, keepThumbInTrack: true, trackThickness: 20) .frame(height: 60) ``` -------------------------------- ### PSliderConfiguration Structure Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/PSliderGuide.md The PSliderConfiguration struct provides state values to custom styles, including disabled status, active state, fill percentage, current value, angle, and range. ```swift struct PSliderConfiguration { let isDisabled: Bool let isActive: Bool let pctFill: Double let value: Double let angle: Angle let min: Double let max: Double let shape: AnyShape } ``` -------------------------------- ### Custom Bar LSlider Style Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/LSliderGuide.md Implements LSliderStyle to create a slider with a rectangular thumb and a track that visually indicates fill percentage and proximity to the thumb. Use this for a distinct visual appearance. ```swift struct BarLSliderStyle: LSliderStyle { func makeThumb(configuration: LSliderConfiguration) -> some View { RoundedRectangle(cornerRadius: 4) .fill(configuration.isActive ? Color.orange : Color.white) .frame(width: configuration.trackThickness, height: configuration.trackThickness * 1.4) .shadow(radius: 3) } func makeTrack(configuration: LSliderConfiguration) -> some View { let adjustment: Double = configuration.keepThumbInTrack ? configuration.trackThickness * (1 - configuration.pctFill) : configuration.trackThickness / 2 return ZStack { AdaptiveLine(thickness: configuration.trackThickness, angle: configuration.angle) .fill(Color(white: 0.2)) AdaptiveLine( thickness: configuration.trackThickness, angle: configuration.angle, percentFilled: configuration.pctFill, cap: .square, adjustmentForThumb: adjustment / 2 ) .fill(Color.orange) .mask(AdaptiveLine(thickness: configuration.trackThickness, angle: configuration.angle)) } } func makeTickMark(configuration: LSliderConfiguration, tickValue: Double) -> some View { let range = configuration.max - configuration.min let thumbPct = range > 0 ? (configuration.value - configuration.min) / range : 0 let tickPct = range > 0 ? (tickValue - configuration.min) / range : 0 let distance = abs(thumbPct - tickPct) let proximity = max(0, 1 - distance / 0.15) let size = 6.0 + 6.0 * proximity let opacity = 0.4 + 0.6 * proximity return Rectangle() .fill(Color.orange.opacity(opacity)) .frame(width: size, height: size) .rotationEffect(.degrees(45)) .animation(.easeOut(duration: 0.08), value: proximity) } } ``` -------------------------------- ### Applying Default Style with Custom Colors Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/DoubleRSliderGuide.md Customize the appearance of the Double Radial Slider using the default style with specific colors for tracks, thumbs, and active states. Adjust track thickness for visual emphasis. ```swift DoubleRSlider(lowerValue: $lower, upperValue: $upper) .doubleRadialSliderStyle( .default( trackColor: Color(white: 0.25), trackFilledColor: .indigo, lowerThumbColor: .white, upperThumbColor: .white, activeThumbColor: .cyan, trackThickness: 20 ) ) .frame(width: 220, height: 220) ``` -------------------------------- ### Adjusting Tick Spacing in OverflowSlider Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/OverflowSliderGuide.md Shows how to modify the `spacing` parameter to control the distance between tick marks, affecting the visual density of the slider's meter-like display. The range is also adjusted. ```swift OverflowSlider(value: $value, range: 0...1000, spacing: 25, isDisabled: false) .frame(height: 60) ``` -------------------------------- ### LSliderConfiguration Structure Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/LSliderGuide.md Exposes the current state of the slider, including its disabled/active status, fill percentage, current value, angle, range, and track properties. ```swift struct LSliderConfiguration { let isDisabled: Bool let isActive: Bool let pctFill: Double let value: Double let angle: Angle let min: Double let max: Double let keepThumbInTrack: Bool let trackThickness: Double let tickMarkSpacing: TickMarkSpacing? let tickValues: [Double] } ``` -------------------------------- ### LSlider with Spacing Tick Marks Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/LSliderGuide.md Configure tick marks with `.spacing(step)` to place a tick mark at regular intervals defined by `step` across the slider's value domain. Haptic feedback is enabled. ```swift @State var temperature = 3.0 LSlider( $temperature, range: 0...10, keepThumbInTrack: true, trackThickness: 20, tickMarkSpacing: .spacing(1), hapticFeedbackEnabled: true ) .frame(height: 60) ``` -------------------------------- ### Basic DoubleRSlider Usage Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/DoubleRSliderGuide.md Initialize DoubleRSlider with binding for lower and upper values and a specified range. The default range is 0 to 1. ```swift @State private var lower = 0.25 @State private var upper = 0.75 DoubleRSlider( lowerValue: $lower, upperValue: $upper, range: 0...1 ) .frame(width: 220, height: 220) ``` -------------------------------- ### Basic RSlider Usage Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/RSliderGuide.md The most basic implementation of RSlider requires a binding to a Double value and a frame modifier. This sets up a default slider with a range of 0 to 1. ```swift @State private var value = 0.5 RSlider($value) .frame(width: 180, height: 180) ``` -------------------------------- ### Set Tick Marks by Specific Values Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/DoubleLSliderGuide.md Use `.values(_:)` to define precise locations for tick marks. This allows for non-uniform tick placement, ideal for sliders representing specific data points. ```swift DoubleLSlider( lowerValue: $lower, upperValue: $upper, range: 0...1, keepThumbInTrack: true, trackThickness: 20, tickMarkSpacing: .values([0.0, 0.25, 0.5, 0.75, 1.0]) ) .frame(height: 60) ``` -------------------------------- ### Vertical LSlider Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/LSliderGuide.md Create a vertical LSlider by setting the `angle` parameter to `.degrees(90)`. Adjust the frame to accommodate the vertical orientation and desired size. ```swift @State var brightness = 0.75 LSlider($brightness, range: 0...1, angle: .degrees(90), keepThumbInTrack: true) .frame(width: 60, height: 200) ``` -------------------------------- ### Enable Tick Affinity (Snapping) Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/DoubleLSliderGuide.md When `affinityEnabled` is true, thumbs magnetically snap to the nearest tick mark within `affinityRadius`. The thumb remains locked until dragged beyond `affinityRadius + affinityResistance`. ```swift DoubleLSlider( lowerValue: $lower, upperValue: $upper, range: 0...1, keepThumbInTrack: true, trackThickness: 20, tickMarkSpacing: .count(11), affinityEnabled: true, affinityRadius: 0.03, affinityResistance: 0.015 ) .frame(height: 60) ``` -------------------------------- ### Apply Default Radial Slider Style Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/RSliderGuide.md Use the .radialSliderStyle modifier with the .default option to apply a predefined radial slider appearance. Customize track thickness as needed. ```swift RSlider($value) .radialSliderStyle(.default(trackThickness: 18)) ``` -------------------------------- ### Custom LSlider Style Implementation Source: https://context7.com/kieranb662/sliders-swiftui/llms.txt Defines a custom style for LSlider, including thumb, track, and tick mark appearances. This style uses adaptive elements and proximity-reactive tick marks. ```swift // Custom style — orange bar with proximity-reactive diamond tick marks struct BarLSliderStyle: LSliderStyle { func makeThumb(configuration: LSliderConfiguration) -> some View { RoundedRectangle(cornerRadius: 4) .fill(configuration.isActive ? Color.orange : Color.white) .frame(width: configuration.trackThickness, height: configuration.trackThickness * 1.4) .shadow(radius: 3) } func makeTrack(configuration: LSliderConfiguration) -> some View { let adj = configuration.keepThumbInTrack ? configuration.trackThickness * (1 - configuration.pctFill) : configuration.trackThickness / 2 return ZStack { AdaptiveLine(thickness: configuration.trackThickness, angle: configuration.angle) .fill(Color(white: 0.2)) AdaptiveLine( thickness: configuration.trackThickness, angle: configuration.angle, percentFilled: configuration.pctFill, cap: .square, adjustmentForThumb: adj / 2 ) .fill(Color.orange) .mask(AdaptiveLine(thickness: configuration.trackThickness, angle: configuration.angle)) } } func makeTickMark(configuration: LSliderConfiguration, tickValue: Double) -> some View { let range = configuration.max - configuration.min let thumbPct = range > 0 ? (configuration.value - configuration.min) / range : 0 let tickPct = range > 0 ? (tickValue - configuration.min) / range : 0 let proximity = max(0, 1 - abs(thumbPct - tickPct) / 0.15) return Rectangle() .fill(Color.orange.opacity(0.4 + 0.6 * proximity)) .frame(width: 6 + 6 * proximity, height: 6 + 6 * proximity) .rotationEffect(.degrees(45)) .animation(.easeOut(duration: 0.08), value: proximity) } } ``` -------------------------------- ### RadialPad with Custom Label Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/RadialPadGuide.md Configures RadialPad to display a custom label showing the current angle in degrees and normalized radial distance. ```swift RadialPad(offset: $dist, angle: $dir) { offset, angle in Text(String(format: "%.0f° r=%.2f", angle.degrees, offset)) } .frame(width: 260, height: 260) ``` -------------------------------- ### PSlider with Custom Shape Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/PSliderGuide.md Utilize any conforming SwiftUI Shape, including custom ones, as the track for a PSlider. ```swift PSlider($value, shape: RoundedRectangle(cornerRadius: 20)) .frame(width: 250, height: 150) ``` -------------------------------- ### Apply Knob Radial Slider Style Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/RSliderGuide.md Apply the .knob style using the .radialSliderStyle modifier for a different predefined radial slider appearance. ```swift RSlider($value) .radialSliderStyle(.knob) ``` -------------------------------- ### DoubleLSlider - Basic Range Slider with Custom Labels Source: https://context7.com/kieranb662/sliders-swiftui/llms.txt Use DoubleLSlider for linear range selection with independent lower and upper thumb bindings. Customize labels and track appearance. Ensure thumbs do not collide using `minimumDistance`. ```swift import Sliders import SwiftUI struct DateRangePickerView: View { @State private var startMonth = 1.0 @State private var endMonth = 6.0 var body: some View { VStack(spacing: 32) { // Basic range slider with custom labels DoubleLSlider( lowerValue: $startMonth, upperValue: $endMonth, range: 1...12, keepThumbInTrack: true, trackThickness: 20, minimumDistance: 1, tickMarkSpacing: .spacing(1), hapticFeedbackEnabled: true ) { Text("From \(Int(v))") } upperLabel: { Text("To \(Int(v))") } .frame(height: 60) // Magnetic snap on a 0…1 range DoubleLSlider( lowerValue: $startMonth, upperValue: $endMonth, range: 0...1, keepThumbInTrack: true, trackThickness: 20, tickMarkSpacing: .count(11), affinityEnabled: true, affinityRadius: 0.03, affinityResistance: 0.015 ) .frame(height: 60) // Built-in default style with custom accent colour DoubleLSlider(lowerValue: $startMonth, upperValue: $endMonth, range: 0...12) .doubleLSliderStyle( .default( trackColor: Color(white: 0.25), trackFilledColor: .indigo, lowerThumbColor: .white, upperThumbColor: .white, activeThumbColor: .cyan, trackThickness: 20 ) ) .frame(height: 60) } .padding() } } ``` -------------------------------- ### Add Sliders Package to Project Source: https://context7.com/kieranb662/sliders-swiftui/llms.txt Add the Sliders package to your Xcode project using Swift Package Manager by providing the repository URL. ```swift // Package.swift dependencies: [ .package(url: "https://github.com/kieranb662/Sliders-SwiftUI", from: "1.0.0") ] ``` -------------------------------- ### Set Tick Marks by Spacing Source: https://github.com/kieranb662/sliders-swiftui/blob/master/Sources/Sliders/Documentation.docc/DoubleLSliderGuide.md Use `.spacing(_:)` to place a tick mark at regular intervals within the slider's range. This is useful for creating sliders with consistent divisions. ```swift DoubleLSlider( lowerValue: $lower, upperValue: $upper, range: 0...12, keepThumbInTrack: true, trackThickness: 20, tickMarkSpacing: .spacing(1) ) .frame(height: 60) ```