Veto
Components

Slider

A number picked by dragging along a rail - with notches, named stops, and a second thumb when you need a span rather than a point.

Basic

Zero to a hundred out of the box. Drag it, or focus it and use the arrow keys - it is a native range input underneath, so the browser supplies the keyboard, the touch handling and the pointer capture.

40%

Defaults to a 0-100 scale in steps of one.

40
razor
<VetoSlider TValue="int"
            Label="Volume"
            ShowValue="true"
            Suffix="%"
            @bind-Value="_volume" />

Your own scale

Min, Max and Step are all yours, and the component is generic over the number type - bind it to an int, a double or a decimal. Prefix and Suffix dress the printed figure.

20°C
$1.2m
razor
<VetoSlider TValue="int"
            Label="Temperature"
            Min="-20" Max="40" Step="5"
            ShowValue="true" Suffix="°C"
            @bind-Value="_temperature" />

<VetoSlider TValue="decimal"
            Label="Budget"
            Min="0" Max="2.5m" Step="0.1m"
            Format="0.0" Prefix="$" Suffix="m"
            ShowValue="true"
            @bind-Value="_budget" />

Marks

Notches on the rail. Set ShowMarks and the slider lays one out every MarkEvery - or every Step - and labels it with its own number.

50
razor
<VetoSlider TValue="int"
            Label="Quality"
            Step="5"
            ShowMarks="true"
            MarkEvery="25"
            ShowValue="true"
            @bind-Value="_quality" />

Marks with words instead of numbers

A mark's label is just text, so a scale can read Low / Medium / High where the number underneath means nothing to the reader. Add SnapToMarks and the thumb settles on a stop rather than anywhere between them, which turns the slider into a chooser.

50
razor
<VetoSlider TValue="int"
            Label="Priority"
            Marks="Stops"
            SnapToMarks="true"
            @bind-Value="_priority" />

@code {
    private static readonly VetoSliderMark[] Stops =
    [
        new(0, "Low"),
        new(50, "Medium"),
        new(100, "High")
    ];
}

Two thumbs, one span

Set Range and the slider grows a second thumb: Value is the low end, UpperValue the high one, each with its own accessible name. The thumbs may meet but never pass each other.

$200 – $800
200 – 800
razor
<VetoSlider TValue="int"
            Range="true"
            Label="Price"
            Min="0" Max="1000" Step="50"
            Prefix="$"
            ShowValue="true"
            LowerThumbLabel="Lowest price"
            UpperThumbLabel="Highest price"
            @bind-Value="_from"
            @bind-UpperValue="_to" />

Value over the thumb

ThumbValue puts the value in a bubble over each thumb - Active while it is hovered, focused or dragged, Always to keep it up. It uses the same Format, Prefix and Suffix as ShowValue; the input's own min, max and step are always written culture-free, so a format like N0 never reaches them.

99 – 99
razor
<VetoSlider TValue="int" Label="Monthly budget"
            Min="0" Max="5000" Step="250" Format="N0" Prefix="$"
            ThumbValue="VetoSliderThumbValue.Always"
            @bind-Value="_monthly" />

<VetoSlider TValue="int" Range="true" Label="Age" Min="18" Max="99"
            ThumbValue="VetoSliderThumbValue.Active"
            @bind-Value="_from" @bind-UpperValue="_to" />

Sizes, colours and variants

The same enums the rest of the library uses.

razor
<VetoSlider TValue="int" Size="VetoSize.Small" Label="Small" @bind-Value="_v" />
<VetoSlider TValue="int" Color="VetoColor.Success" Label="Success" @bind-Value="_v" />
<VetoSlider TValue="int" Variant="VetoVariant.Filled" Label="Filled" @bind-Value="_v" />

Disabled and read-only

Disabled cannot be focused. Read-only can be focused and read out, but the thumb springs back to where it was.

70
70
razor
<VetoSlider TValue="int" Label="Disabled" Disabled="true" @bind-Value="_v" />
<VetoSlider TValue="int" Label="Read-only" ReadOnly="true" @bind-Value="_v" />

Validation

Inside an EditForm the slider picks up the model's validation attributes like any other input.

0

At least three.

razor
<EditForm Model="_form" OnValidSubmit="Save">
    <DataAnnotationsValidator />

    <VetoSlider Label="Effort"
                Required="true"
                Max="10"
                ShowValue="true"
                @bind-Value="_form.Effort" />

    <button type="submit">Save</button>
</EditForm>

@code {
    private sealed class FormModel
    {
        [Range(3, 10, ErrorMessage = "Effort must be at least 3.")]
        public int Effort { get; set; }
    }
}

Parameters

Parameter Type Default Description
Value TValue default The value, or the low end of a range. Use @bind-Value.
UpperValue TValue 100 The high end of a range. Use @bind-UpperValue.
Range bool false Grow a second thumb and pick a span rather than a point.
Min / Max TValue 0 / 100 The ends of the scale.
Step TValue 1 The smallest change a drag or an arrow key can make.
Marks IReadOnlyList<VetoSliderMark>? null The notches: a position and an optional label, numeric or not.
ShowMarks bool false Generate labelled notches when none are supplied.
MarkEvery double? null Spacing of generated marks. Defaults to Step.
ShowMarkLabels bool true Draw the notches' labels.
SnapToMarks bool false Settle on the nearest mark rather than anywhere on the scale.
ShowValue bool false Print the current value above the rail.
Format / Prefix / Suffix string? null How every printed number is formatted and dressed.
RangeSeparator string " – " What goes between the two numbers of a printed range.
LowerThumbLabel / UpperThumbLabel string "Minimum" / "Maximum" Accessible names for a range's two thumbs.
ThumbValue VetoSliderThumbValue Never A value bubble over each thumb: Never, Active (hovered, focused or dragged) or Always.
Immediate bool true Follow the thumb as it is dragged, rather than updating only when the drag ends.
Color VetoColor Primary The accent the filled rail takes.
Size VetoSize Medium ExtraSmall, Small, Medium, Large or ExtraLarge.
Variant VetoVariant Outlined Outlined, Filled, Text, Soft, Underlined, Ghost or Elevated.
Disabled / ReadOnly / Required bool false The usual input states.
OnValueChanged EventCallback<TValue> — Raised after the value changes.
Something went wrong. Reload 🗙