RangeSlider
A two-thumb range slider that selects a lower/upper value pair. It reuses the visual language of the single-value Slider — the cold-to-hot gradient, blended thumb borders, and floating value tooltip — showing the gradient across the active segment between the two thumbs over a neutral track, drawing a tooltip per thumb, and adding two distance constraints between the thumbs.
MAUI
Blazor
Features
Section titled “Features”- Two Thumbs – Selects a
LowerValue/UpperValuepair; both are two-way bindable. - Gradient Active Segment – The segment between the thumbs renders a gradient blended from
ColdColortoHotColorat the thumb positions; the rest of the track is a neutral surface color. - Blended Thumb Borders – Each thumb’s border color samples the gradient at its own position.
- Per-Thumb Tooltips – A tooltip badge floats above each thumb; replace both with a custom template.
- Custom Thumb Content –
ThumbTemplatefills both thumbs,LowerThumbTemplate/UpperThumbTemplateoverride it per end, andThumbWidth/ThumbHeight/ThumbCornerRadiusshape the box around it. - Minimum Gap (hard stop) –
MinimumRangeprevents the thumbs from getting closer than a set distance; the dragged thumb stops rather than crossing it. - Maximum Gap (push) –
MaximumRangecaps how far apart the thumbs may be; dragging one thumb past it pushes the other along. - Step Snapping – Values snap to the configured
Step. - Drag & Tap – Drag either thumb, or tap the track to move whichever thumb is nearer.
AI Skill
Section titled “AI Skill”Step 1 — Add the marketplace:
claude plugin marketplace add shinyorg/skillsStep 2 — Install the plugin:
claude plugin install shiny@shinyOne plugin installs all 36 Shiny skills. Your agent loads only the skill relevant to what you're building, so there's no cost to having them all available.
Step 1 — Add the marketplace:
copilot plugin marketplace add https://github.com/shinyorg/skillsStep 2 — Install the plugin:
copilot plugin install shiny@shinyOne plugin installs all 36 Shiny skills. Your agent loads only the skill relevant to what you're building, so there's no cost to having them all available.
Quick Start
Section titled “Quick Start”.NET MAUI
Section titled “.NET MAUI”<shiny:RangeSlider LowerValue="{Binding PriceLow}" UpperValue="{Binding PriceHigh}" Minimum="0" Maximum="1000" Step="10" MinimumRange="50" MaximumRange="500" ValueFormat="C0" />Blazor
Section titled “Blazor”<RangeSlider @bind-LowerValue="priceLow" @bind-UpperValue="priceHigh" Minimum="0" Maximum="1000" Step="10" MinimumRange="50" MaximumRange="500" ValueFormat="C0" />
@code { double priceLow = 250; double priceHigh = 750;}Properties
Section titled “Properties”| Property | MAUI Type | Blazor Type | Default | Description |
|---|---|---|---|---|
| LowerValue | double | double | 0 | Lower thumb value (TwoWay) |
| UpperValue | double | double | 100 | Upper thumb value (TwoWay) |
| Minimum | double | double | 0 | Minimum value |
| Maximum | double | double | 100 | Maximum value |
| Step | double | double | 1 | Snap increment |
| MinimumRange | double | double | 0 | Minimum gap between thumbs (hard stop); 0 = off |
| MaximumRange | double | double | 0 | Maximum gap between thumbs (pushes the other thumb); 0 = off |
| ColdColor | Color | string | #3B82F6 | Left (cold) gradient color |
| HotColor | Color | string | #EF4444 | Right (hot) gradient color |
| TrackHeight | double | double | 8 | Track height in px |
| ThumbSize | double | double | 24 | Thumb diameter in px |
| ThumbWidth | double | double | -1 | Thumb width; -1 keeps the thumbs square at ThumbSize |
| ThumbHeight | double | double | -1 | Thumb height; -1 keeps the thumbs square at ThumbSize |
| ThumbCornerRadius | double | string? | -1 / null | Fully rounded by default – a circle, or a pill once the thumbs are not square |
| ThumbPadding | Thickness | string? | 0 / null | Inset between a thumb border and its template content |
| ThumbTemplate | DataTemplate? | RenderFragment<double>? | null | Content drawn inside both thumbs |
| LowerThumbTemplate | DataTemplate? | RenderFragment<double>? | null | Content for the lower thumb only; falls back to ThumbTemplate |
| UpperThumbTemplate | DataTemplate? | RenderFragment<double>? | null | Content for the upper thumb only; falls back to ThumbTemplate |
| ThumbColor | Color | string | White | Thumb fill color |
| ThumbBorderWidth | double | double | 2 | Thumb border width |
| ShowTooltip | bool | bool | true | Show a value tooltip per thumb |
| TooltipBackgroundColor | Color | string | #1F2937 | Tooltip badge background |
| TooltipTextColor | Color | string | White | Tooltip text color |
| TooltipFontSize | double | double | 12 | Tooltip font size |
| ValueFormat | string? | string? | null | .NET format string for display |
| TooltipTemplate | DataTemplate? | RenderFragment<double>? | null | Custom tooltip content (applied to both thumbs) |
| IsEnabled | – | bool | true | Enable/disable (Blazor only; MAUI uses IsEnabled from VisualElement) |
Events & Commands
Section titled “Events & Commands”MAUI:
RangeChanged(EventHandler<SliderRange>) – Fired when either value changes;SliderRangeis arecord structwithLower/UpperRangeChangedCommand(ICommand) – Command fired with theSliderRangeon change
Blazor:
LowerValueChanged(EventCallback<double>) – Two-way binding callback for the lower thumbUpperValueChanged(EventCallback<double>) – Two-way binding callback for the upper thumbRangeChanged(EventCallback<(double Lower, double Upper)>) – Fired with both values on change
Custom Thumb Content
Section titled “Custom Thumb Content”ThumbTemplate puts your own content inside both thumbs; LowerThumbTemplate and
UpperThumbTemplate override it per end. Each template’s binding context (MAUI) / context parameter
(Blazor) is that thumb’s own value, so the two ends can label themselves independently.
<!-- xmlns:sys="clr-namespace:System;assembly=netstandard" --><shiny:RangeSlider LowerValue="{Binding ShiftStart}" UpperValue="{Binding ShiftEnd}" Minimum="0" Maximum="24" Step="1" ShowTooltip="False" ThumbWidth="46" ThumbHeight="26"> <shiny:RangeSlider.ThumbTemplate> <DataTemplate x:DataType="sys:Double"> <Label Text="{Binding ., StringFormat='{0:00}:00'}" FontSize="10" FontAttributes="Bold" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" /> </DataTemplate> </shiny:RangeSlider.ThumbTemplate></shiny:RangeSlider>Blazor
Section titled “Blazor”<RangeSlider @bind-LowerValue="shiftStart" @bind-UpperValue="shiftEnd" Minimum="0" Maximum="24" Step="1" ShowTooltip="false" ThumbWidth="46" ThumbHeight="26"> <ThumbTemplate Context="value"> <span style="font-size: 10px; font-weight: 700;">@value.ToString("00"):00</span> </ThumbTemplate></RangeSlider>The thumbs do not grow to fit their content. The travel is measured from the thumb, so the box has
to be known before anything is laid out – size them with ThumbSize, or with
ThumbWidth/ThumbHeight when the content is not square, and the content is centred and clipped
inside. ThumbCornerRadius turns the default pill into any other shape.
Behavior
Section titled “Behavior”- The active segment between the thumbs shows the gradient blended at each thumb’s position; the base track is the theme SurfaceVariant color
- Each thumb’s border takes the blended color at its position
- Values are clamped to
Minimum/Maximumand snapped toStep - MinimumRange is a hard stop — the dragged thumb will not come closer than this gap to the other thumb
- MaximumRange pushes the opposite thumb — dragging one thumb far enough drags the other so the gap never exceeds it
- Constraints apply to interaction (drag/tap); programmatically-set or data-bound values render as provided
- Setting
ShowTooltip="False"hides both tooltips - The control reserves the half of the thumb that hangs past the track at both ends, so a tall custom thumb is not clipped and does not overlap what follows it


