Rask
Rask
v0.23.1-alpha.0.494

Components

Date picker

A day or a range picked from a calendar in a popup, for filtering data or scheduling events. For a date far in the past or the future, such as a birthday, a date input serves better.

Drawn and behaving as Flux UI's date picker does, measured against its live docs.

Date picker

A field-shaped button over the calendar: a day closes it on the pick.

DatePickerExample.cs
using System.Globalization;

namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerExample : Component
{
    private DateOnly _date;

    protected override Component? Render() =>
        Div.Class("max-w-xs space-y-3")[
            Ui.DatePicker.Value(_date).OnChange(date => { _date = date; }),
            Ui.Text.Data("testid", "ui-date-picker-state")[_date == default ? "No date chosen." : "Chosen: " + Iso(_date)]
        ];

    private static string Iso(DateOnly date) => date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
}
Live result
October 2026
Su
Mo
Tu
We
Th
Fr
Sa

No date chosen.

Basic usage

Bound to a DateOnly? that starts on today, as Flux's value does.

DatePickerBoundExample.cs
using System.Globalization;

namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerBoundExample : Component
{
    private readonly Post _post = new();

    protected override Component? Render() =>
        Div.Class("max-w-xs space-y-3")[
            Ui.DatePicker.Bind(() => _post.PublishedAt).Live().Label("Publish on"),
            Ui.Text[_post.PublishedAt is { } day ? "Publishes " + day.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture) + "." : "Not scheduled."]
        ];

    public sealed class Post
    {
        public DateOnly? PublishedAt { get; set; } = DateOnly.FromDateTime(TimeProvider.System.GetLocalNow().Date);
    }
}
Live result
October 2026
Su
Mo
Tu
We
Th
Fr
Sa

Publishes 2026-10-22.

Input trigger

Month, day and year typed as one field: a part that is full moves on to the next, and the chevron opens the calendar.

DatePickerInputExample.cs
using System.Globalization;

namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerInputExample : Component
{
    private DateOnly _date;

    protected override Component? Render() =>
        Div.Class("max-w-xs space-y-3")[
            Ui.DatePicker.Value(_date).OnChange(date => { _date = date; }).Type(Ui.DatePickerType.Input),
            Ui.Text.Data("testid", "ui-date-picker-input-state")[
                _date == default ? "No date chosen." : "Chosen: " + _date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)
            ]
        ];
}
Live result
//
October 2026
Su
Mo
Tu
We
Th
Fr
Sa

No date chosen.

Range picker

Two months and a UiDateRange, closed by the second click.

DatePickerRangeExample.cs
using System.Globalization;

namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerRangeExample : Component
{
    private UiDateRange _range;

    protected override Component? Render() =>
        Div.Class("max-w-xs space-y-3")[
            Ui.DatePicker.Range.Value(_range).OnChange(range => { _range = range; }),
            Ui.Text.Data("testid", "ui-date-picker-range-state")[
                _range == default ? "No range chosen." : $"Range: {Iso(_range.Start)} to {Iso(_range.End)}"
            ]
        ];

    private static string Iso(DateOnly date) => date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
}
Live result
October 2026
Su
Mo
Tu
We
Th
Fr
Sa
November 2026
Su
Mo
Tu
We
Th
Fr
Sa

No range chosen.

Range limits

At least three days, and at most ten.

DatePickerRangeLimitsExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerRangeLimitsExample : Component
{
    protected override Component? Render() =>
        Div.Class("max-w-xs space-y-4")[
            Ui.DatePicker.Range.Value(default(UiDateRange)).MinRange(3),
            Ui.DatePicker.Range.Value(default(UiDateRange)).MaxRange(10)
        ];
}
Live result
October 2026
Su
Mo
Tu
We
Th
Fr
Sa
November 2026
Su
Mo
Tu
We
Th
Fr
Sa
October 2026
Su
Mo
Tu
We
Th
Fr
Sa
November 2026
Su
Mo
Tu
We
Th
Fr
Sa

Range with inputs

A trigger of your own: a field for the start and one for the end, each typed into and each opening the calendar.

DatePickerRangeInputsExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerRangeInputsExample : Component
{
    protected override Component? Render() =>
        Ui.DatePicker.Range.Value(default(UiDateRange)).Trigger(
            Div.Class("flex flex-col gap-6 sm:flex-row sm:gap-4")[
                Ui.DatePickerInput.Key("start").Label("Start"),
                Ui.DatePickerInput.Key("end").Label("End")
            ]);
}
Live result
//
//
October 2026
Su
Mo
Tu
We
Th
Fr
Sa
November 2026
Su
Mo
Tu
We
Th
Fr
Sa

With inputs

WithInputs() puts the start and the end over the months, to type into: drawn as parts, Flux's custom variant.

DatePickerWithInputsExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerWithInputsExample : Component
{
    protected override Component? Render() =>
        Div.Class("max-w-xs")[
            Ui.DatePicker.Range.Value(default(UiDateRange)).WithInputs()
        ];
}
Live result
//
//
October 2026
Su
Mo
Tu
We
Th
Fr
Sa
November 2026
Su
Mo
Tu
We
Th
Fr
Sa

Native inputs

The browser's own date fields in the same box, Flux's native variant: over the months, and as the trigger itself.

DatePickerNativeInputsExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerNativeInputsExample : Component
{
    protected override Component? Render() =>
        Div.Class("max-w-xs space-y-4")[
            Ui.DatePicker.Range.Value(default(UiDateRange)).WithInputs(Ui.DatePickerInputVariant.Native),
            Ui.DatePicker.Value(default(DateOnly)).Trigger(Ui.DatePickerInput.Native)
        ];
}
Live result
October 2026
Su
Mo
Tu
We
Th
Fr
Sa
November 2026
Su
Mo
Tu
We
Th
Fr
Sa
October 2026
Su
Mo
Tu
We
Th
Fr
Sa

Presets

Today, Yesterday, This Week, Last 7 Days, This Month, Year to Date and All Time, which starts at Min. A preset closes the picker.

DatePickerPresetsExample.cs
using System.Globalization;

namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerPresetsExample : Component
{
    private UiDateRange _range;

    protected override Component? Render() =>
        Div.Class("max-w-xs space-y-3")[
            // Min is where "All Time" starts.
            Ui.DatePicker.Range.Value(_range).OnChange(range => { _range = range; }).WithPresets().Min(new DateOnly(2012, 1, 1)),
            Ui.Text.Data("testid", "ui-date-picker-presets-state")[_range == default ? "No range chosen." : "Range: " + Named(_range)]
        ];

    private static string Named(UiDateRange range) =>
        range.Start.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture) + " to " + range.End.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
}
Live result
October 2026
Su
Mo
Tu
We
Th
Fr
Sa
November 2026
Su
Mo
Tu
We
Th
Fr
Sa

No range chosen.

Choosing the presets

Presets lists the ones you name, in your order. With Custom among them, a range that matches no other preset is "Custom Range".

DatePickerPresetListExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerPresetListExample : Component
{
    protected override Component? Render() =>
        Div.Class("max-w-xs")[
            Ui.DatePicker.Range.Value(default(UiDateRange)).Min(new DateOnly(2012, 1, 1)).Presets([
                Ui.DateRangePreset.Today, Ui.DateRangePreset.Yesterday, Ui.DateRangePreset.ThisWeek, Ui.DateRangePreset.Last7Days,
                Ui.DateRangePreset.ThisMonth, Ui.DateRangePreset.YearToDate, Ui.DateRangePreset.AllTime, Ui.DateRangePreset.Custom,
            ])
        ];
}
Live result
October 2026
Su
Mo
Tu
We
Th
Fr
Sa
November 2026
Su
Mo
Tu
We
Th
Fr
Sa

Unavailable dates

DatePickerUnavailableExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerUnavailableExample : Component
{
    private static readonly DateOnly Today = DateOnly.FromDateTime(TimeProvider.System.GetLocalNow().Date);

    protected override Component? Render() =>
        Div.Class("max-w-xs")[
            Ui.DatePicker.Value(default(DateOnly)).Unavailable([Today.AddDays(-1), Today.AddDays(1)])
        ];
}
Live result
October 2026
Su
Mo
Tu
We
Th
Fr
Sa

With today shortcut

DatePickerTodayExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerTodayExample : Component
{
    protected override Component? Render() =>
        Div.Class("max-w-xs")[
            Ui.DatePicker.Value(default(DateOnly)).WithToday()
        ];
}
Live result
October 2026
Su
Mo
Tu
We
Th
Fr
Sa

Selectable header

DatePickerHeaderExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerHeaderExample : Component
{
    protected override Component? Render() =>
        Div.Class("max-w-xs")[
            Ui.DatePicker.Value(default(DateOnly)).SelectableHeader()
        ];
}
Live result
October 2026
Su
Mo
Tu
We
Th
Fr
Sa

Fixed weeks

DatePickerFixedWeeksExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerFixedWeeksExample : Component
{
    protected override Component? Render() =>
        Div.Class("max-w-xs")[
            Ui.DatePicker.Value(default(DateOnly)).FixedWeeks()
        ];
}
Live result
October 2026
Su
Mo
Tu
We
Th
Fr
Sa

Start day

DatePickerStartDayExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerStartDayExample : Component
{
    protected override Component? Render() =>
        Div.Class("max-w-xs")[
            Ui.DatePicker.Value(default(DateOnly)).StartDay(DayOfWeek.Monday)
        ];
}
Live result
October 2026
Mo
Tu
We
Th
Fr
Sa
Su

Open to

Where the calendar opens while nothing is chosen; with ForceOpenTo, whatever is chosen.

DatePickerOpenToExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerOpenToExample : Component
{
    private static readonly DateOnly Today = DateOnly.FromDateTime(TimeProvider.System.GetLocalNow().Date);

    // The first of next month, a year on.
    private static readonly DateOnly NextYear = new DateOnly(Today.Year, Today.Month, 1).AddMonths(1).AddYears(1);

    protected override Component? Render() =>
        Div.Class("max-w-xs space-y-4")[
            Ui.DatePicker.Value(default(DateOnly)).OpenTo(NextYear),
            Ui.DatePicker.Value(Today).OpenTo(NextYear).ForceOpenTo()
        ];
}
Live result
November 2027
Su
Mo
Tu
We
Th
Fr
Sa
November 2027
Su
Mo
Tu
We
Th
Fr
Sa

Week numbers

DatePickerWeekNumbersExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerWeekNumbersExample : Component
{
    protected override Component? Render() =>
        Div.Class("max-w-xs")[
            Ui.DatePicker.Value(default(DateOnly)).WeekNumbers()
        ];
}
Live result
October 2026
#
Su
Mo
Tu
We
Th
Fr
Sa
40
41
42
43
44

Localization

DatePickerLocaleExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerLocaleExample : Component
{
    protected override Component? Render() =>
        Div.Class("max-w-xs")[
            Ui.DatePicker.Value(default(DateOnly)).Locale("ja-JP")
        ];
}
Live result
2026年10月
日
月
火
水
木
金
土

Clearable

A button inside the trigger, before its chevron, while a date is chosen, beside a time picker that has one too.

DatePickerClearableExample.cs
namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class DatePickerClearableExample : Component
{
    private DateOnly _day = DateOnly.FromDateTime(TimeProvider.System.GetLocalNow().Date);
    private TimeOnly? _time = new TimeOnly(9, 30);

    protected override Component? Render() =>
        Div.Class("max-w-md space-y-3")[
            Div.Class("flex flex-wrap gap-2").Data("testid", "ui-picker-clear")[
                Ui.DatePicker.Value(_day).OnChange(day => { _day = day; }).Clearable().Class("grow"),
                Ui.TimePicker.Value(_time).OnChange(time => { _time = time; }).Clearable().Id("ui-time-clear")
            ],
            Ui.Text.Data("testid", "ui-picker-clear-state")[(_day == default ? "No day" : "A day") + ", " + (_time is null ? "no time" : "a time")]
        ];
}
Live result
October 2026
Su
Mo
Tu
We
Th
Fr
Sa

A day, a time

Behaviour

A popup the browser opens

The calendar is in a popover, so the top layer, Escape, a click outside and the focus back on the button come with it. A day closes it on the pick, a range on its second click, a preset at once. While it is open the page behind it neither scrolls nor takes the pointer (data-rask-lock).

It takes the calendar's steps (Min, Max, Unavailable, MinRange, MaxRange, Months, OpenTo, StartDay, WeekNumbers, SelectableHeader, WithToday, FixedWeeks, Locale) and a field's. WithConfirmation() writes nothing until "Select date". There is no multiple mode, as in Flux: several days are the calendar's.

On a phone

Under 640 px the same popup is Flux's sheet, with nothing to write for it: centred over a page dimmed 10%, one month whatever Months says, 44 px days, the presets a native select under the days, and Cancel and Select date (Select range on a range) at its foot. A pick marks the day and writes nothing; the button writes it, through the same binding. Cancel, Escape and a press on the dimmed page leave the value as it was. The page hears which of the two it is from a box only the stylesheet sizes (data-rask-measure).

Typed dates

Type(Ui.DatePickerType.Input), Ui.DatePickerInput and WithInputs() draw month, day and year as parts in the locale's order, Flux's custom. Ui.DatePickerInput.Native and WithInputs(Ui.DatePickerInputVariant.Native) draw the browser's own <input type="date"> in the same box, Flux's native. Flux's docs default to native and call custom the recommended and future default; its own pages draw custom, and so does the kit unless told.

The typed trigger is one field in three parts: digits only, a part that can take no more moves on (3 is March), the horizontal arrows walk the parts and the vertical ones step them, and a pasted date is shared out. A whole date is written as soon as the year has four digits. Everything in the trigger but a part opens the calendar. The parts are the runtime's data-rask-segments, and one hidden field carries yyyy-MM-dd to the binding.

Where it departs from Flux, by the owner's decision: Flux keeps the last whole date behind parts that no longer show it. Here a half-filled date is no date: the field says "Enter a valid date.", the save is refused, and with every part emptied the picker holds nothing.

Presets

WithPresets() lists Flux's default seven; Presets([..]) lists the Ui.DateRangePresets you name, in your order. A preset writes UiDateRange.Of(preset, today, startDay, Min), whose Preset names it, and the button then shows the preset's label. All Time starts at Min. The presets are a radio group one arrow walks, and the preset an arrow reaches is chosen, which closes the picker.

Clearing

Clearable(), on the picker or on a Ui.DatePickerButton or Ui.DatePickerInput in its Trigger, puts a button in the trigger, before its chevron, while a date is chosen. A bound DateOnly? or UiDateRange? becomes null, one that cannot be null goes back to its unset value, and a range is emptied whole. Flux documents the prop and draws it on none of its pages, so the button is the time picker's: the same 32 px cross, 30 px from the trigger's end.

The keyboard

As measured on Flux. Inside the popup the calendar's own keys apply.

Key
What happens
Enter, Space, ArrowDown, ArrowUpOpen the closed button.
Escape, a click outsideClose; the focus goes back to the button.
An arrow in the presetsChooses the next preset, which closes the picker.
Digits in a typed partFill it, and move on once it can take no more.

Reference

Ui.DatePicker

flux:date-picker

A field-shaped button over a calendar in a popup. Ui.DatePicker picks a day, Ui.DatePicker.Range a range.

Step
Takes
What it does
.Bind(…)() => a DateOnly, or a UiDateRangeThe member it reads and writes: () => m.Day, or a UiDateRange. Or Value with OnChange.
.Value(…)a DateOnly, or a UiDateRangeWhat it holds, for a page that holds it itself.
.OnChange(…)a handler given the new valueRuns with the new value when it is picked.
.AfterBind(…)a handler given the new valueRuns after Bind has written the model.
.Validate(…)a validatorA rule the value is checked by when it is written.
.Live()boolWrites the model as soon as it is picked, not with the next action.
.Mode(…)
Ui.DatePickerMode
Single
Range

Each is a step of its own too, unless an HTML tag has its name.

What is picked, as a value. The opening step says it; this has to agree with what is bound.
.Type(…)
Ui.DatePickerType
Button
Input

Each is a step of its own too, unless an HTML tag has its name.

What opens it: a button showing the choice, or a field to type it into. The button when unset.
.Trigger(…)ComponentA trigger of your own: Ui.DatePickerInput fields, or a Ui.DatePickerButton.
.Label(…)stringDraws a field around it, with this label and the error.
.Description(…)stringHelp text between the label and the picker.
.DescriptionTrailing(…)stringHelp text under the picker.
.Badge(…)stringA word beside the label: "Optional".
.Placeholder(…)stringWhat the trigger shows while nothing is chosen. By mode when unset.
.Min(…)a DateOnlyThe earliest day that can be picked; also where All Time starts.
.Max(…)a DateOnlyThe latest day that can be picked.
.Unavailable(…)DateOnly days: [today.AddDays(1)]Days that cannot be picked.
.MinRange(…)intThe fewest days a range may hold.
.MaxRange(…)intThe most days a range may hold.
.OpenTo(…)a DateOnlyThe day the calendar opens to while nothing is chosen.
.ForceOpenTo()boolOpens to OpenTo whatever is chosen.
.Months(…)intHow many months are shown side by side. One, or two for a range, when unset.
.Size(…)
Ui.DatePickerSize
Default
Sm
Lg
Xl
Xxl

Each is a step of its own too, unless an HTML tag has its name.

How large the calendar's day cells are.
.StartDay(…)
DayOfWeek
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday

Each is a step of its own too, unless an HTML tag has its name.

The day the week starts on. The locale's own when unset.
.WeekNumbers()boolShows each week's number.
.SelectableHeader()boolMakes the month and the year in the header selects.
.WithToday()boolA button that comes back to this month, and picks today once there.
.FixedWeeks()boolAlways six weeks, so paging never changes the height.
.WithInputs(…)
Ui.DatePickerInputVariant
Custom
Native

Each is a step of its own too, unless an HTML tag has its name.

Fields over the months to type into: WithInputs() as parts, WithInputs(Ui.DatePickerInputVariant.Native) as the browser's.
.WithConfirmation()boolHolds the choice until the reader presses Select date.
.WithPresets()boolLists Flux's seven preset ranges beside the calendar.
.Presets(…)Ui.DateRangePreset values: [Ui.DateRangePreset.Today]The presets listed, in this order. Setting it lists them.
.Clearable()boolA button in the trigger that empties the picker, while a date is chosen.
.Disabled()boolA picker that cannot be opened.
.Invalid()boolError styling the form did not ask for.
.Locale(…)stringThe locale the names, the week and the shown date follow. The app's culture when unset.
.ShowValidation()boolFalse leaves the member's message to a Ui.Error placed elsewhere.

Ui.DatePickerInput

flux:date-picker.input

A field in a picker's Trigger to type its date into, which also opens the calendar. Native is the browser's own date field.

Step
Takes
What it does
.Label(…)stringThe label over the field, which wraps it in a field.
.Description(…)stringHelp text between the label and the field.
.Variant(…)
Ui.DatePickerInputVariant
Custom
Native

Each is a step of its own too, unless an HTML tag has its name.

Typed as parts, or in the browser's own date field. Parts when unset.
.Size(…)
Ui.DatePickerInputSize
Base
Sm
Xs

Each is a step of its own too, unless an HTML tag has its name.

How tall the field is.
.Clearable()boolA button that empties the picker, while a date is chosen. The picker's own when unset.
.Disabled()boolA field that cannot be typed into or open the picker.
.Invalid()boolDraws the field as holding an error.

Ui.DatePickerButton

flux:date-picker.button

The field-shaped button in a picker's Trigger, for what the picker's own steps do not reach.

Step
Takes
What it does
.Placeholder(…)stringWhat it shows while nothing is chosen. The picker's own when unset.
.Size(…)
Ui.DatePickerButtonSize
Base
Sm
Xs

Each is a step of its own too, unless an HTML tag has its name.

How tall it is.
.Clearable()boolA button that empties the picker, while a date is chosen. The picker's own when unset.
.Disabled()boolA button that cannot open the picker.
.Invalid()boolDraws the button as holding an error.
Confirm