Rask
Rask
v0.23.1-alpha.0.494

Components

Toggle

A setting turned on or off from a compact, button-shaped control. Use a toggle for icon-sized settings and modes, and a switch when the setting needs a visible label.

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

Toggle

Nobody listens to this one, so the browser turns it and the page is sent nothing.

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

public sealed partial class ToggleExample : Component
{
    protected override Component? Render() =>
        Ui.Toggle.Icon(Ui.IconName.Bolt).Tooltip("Fast mode");
}
Live result

Saving changes

Bound, with OnChange to save: the member is written first, and the toggle shows a spinner while the save runs.

ToggleSavingExample.cs
using System.Globalization;

namespace Rask.Site.Features.UiDocs.Examples;

public sealed partial class ToggleSavingExample : Component
{
    private readonly Project _project = new();
    private bool _saved;
    private int _saves;

    protected override Component? Render() =>
        Div.Class("flex flex-wrap items-center gap-3")[
            Ui.Toggle.Bind(() => _project.Active).OnChange(Save).Icon(Ui.IconName.LightBulb).Tooltip("Active project"),
            Ui.Text.Data("testid", "ui-toggle-saves")[
                (_saved ? "Saved as active" : "Saved as inactive") + " · " + _saves.ToString(CultureInfo.InvariantCulture) + " saves"
            ]
        ];

    // Flux's wire:change="save": the member is written by the time this runs, and the toggle waits on it.
    private async Task Save(bool active)
    {
        await Task.Delay(600);
        _saved = active;
        _saves++;
    }

    public sealed class Project
    {
        public bool Active { get; set; }
    }
}
Live result

Saved as inactive · 0 saves

Sizes

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

public sealed partial class ToggleSizesExample : Component
{
    protected override Component? Render() =>
        Div.Class("flex flex-wrap items-center gap-3")[
            Ui.Toggle.Icon(Ui.IconName.Bolt),
            Ui.Toggle.Icon(Ui.IconName.Bolt).Sm,
            Ui.Toggle.Icon(Ui.IconName.Bolt).Xs
        ];
}
Live result

Variants

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

public sealed partial class ToggleVariantsExample : Component
{
    protected override Component? Render() =>
        Div.Class("flex flex-wrap items-center gap-3")[
            Ui.Toggle.Icon(Ui.IconName.Bolt),
            Ui.Toggle.Icon(Ui.IconName.Bolt).Filled,
            Ui.Toggle.Icon(Ui.IconName.Bolt).Ghost,
            Ui.Toggle.Icon(Ui.IconName.Bolt).Subtle
        ];
}
Live result

Color

The colour of the icon when on. Off, it stays neutral.

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

public sealed partial class ToggleColorExample : Component
{
    protected override Component? Render() =>
        Div.Class("flex flex-wrap items-center gap-3")[
            Ui.Toggle.Icon(Ui.IconName.Bolt).Color(Ui.Color.Blue).Checked(),
            Ui.Toggle.Icon(Ui.IconName.Heart).Color(Ui.Color.Red).Checked(),
            Ui.Toggle.Icon(Ui.IconName.Bell).Color(Ui.Color.Amber).Checked()
        ];
}
Live result

With label

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

public sealed partial class ToggleLabelExample : Component
{
    protected override Component? Render() =>
        Ui.Toggle.Icon(Ui.IconName.Bolt).Label("Fast mode");
}
Live result

Stateful icon

A different icon for each state, kept by the page.

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

public sealed partial class ToggleStatefulIconExample : Component
{
    private bool _sound;

    protected override Component? Render() =>
        Div.Class("flex flex-wrap items-center gap-3")[
            Ui.Toggle.OnIcon(Ui.IconName.SpeakerWave).OffIcon(Ui.IconName.SpeakerXMark).Tooltip("Toggle sound")
                .Checked(_sound).OnChange(on => { _sound = on; }),
            Ui.Text.Data("testid", "ui-toggle-sound")[_sound ? "Playing" : "Muted"]
        ];
}
Live result

Muted

Custom icons

Icons of your own, each shown for its state with group-data-checked:.

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

public sealed partial class ToggleCustomIconsExample : Component
{
    // Lucide's shrink and expand, as Flux's page imports them: each drawn for its own state with group-data-checked.
    private const string Lucide =
        " xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\""
        + " stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">";

    private const string Shrink =
        "<svg class=\"size-5 hidden group-data-checked:block text-accent-content\"" + Lucide
        + "<path d=\"m15 15 6 6m-6-6v4.8m0-4.8h4.8\"/><path d=\"M9 19.8V15m0 0H4.2M9 15l-6 6\"/>"
        + "<path d=\"M15 4.2V9m0 0h4.8M15 9l6-6\"/><path d=\"M9 4.2V9m0 0H4.2M9 9 3 3\"/></svg>";

    private const string Expand =
        "<svg class=\"size-5 group-data-checked:hidden text-zinc-500/85 dark:text-zinc-300/80\"" + Lucide
        + "<path d=\"m15 15 6 6\"/><path d=\"m15 9 6-6\"/><path d=\"M21 16v5h-5\"/><path d=\"M21 8V3h-5\"/>"
        + "<path d=\"M3 16v5h5\"/><path d=\"m3 21 6-6\"/><path d=\"M3 8V3h5\"/><path d=\"M9 9 3 3\"/></svg>";

    protected override Component? Render() =>
        Ui.Toggle.Icon(Raw.Value(Shrink + Expand)).Tooltip("Toggle fullscreen");
}
Live result

Stateful label

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

public sealed partial class ToggleStatefulLabelExample : Component
{
    protected override Component? Render() =>
        Ui.Toggle.OnLabel("Sound on").OffLabel("Sound off");
}
Live result

Disabled

Dimmed, and out of the tab order.

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

public sealed partial class ToggleDisabledExample : Component
{
    protected override Component? Render() =>
        Ui.Toggle.Icon(Ui.IconName.Bolt).Label("Fast mode").Disabled();
}
Live result

Behaviour

A real switch

It is a <button role="switch">: a press, Space and Enter turn it, and a screen reader says "on" or "off". A toggle that shows only an icon is named by its Tooltip. Icon draws a Heroicon's outline when off and its solid drawing when on, and OnIcon, OffIcon, OnLabel and OffLabel say each state apart.

Whose state it is

Bind two-way binds a bool: the member is written with the next action, as every kit control's is, and at once with .Live(). A bound toggle the page listens to with OnChange is written at once too, and OnChange runs after the write: Flux's wire:model beside wire:change, one round trip that saves. While its handler runs the runtime marks the button data-loading: what it shows gives way to a spinner and it takes no further press.

Unbound and listened to with OnChange, it reports each turn, and a page that hands it a different Checked has the last word.

A toggle nobody listens to sends nothing

With no Bind and no OnChange a press only changes what the toggle draws, so the browser does it (data-rask-switch): aria-checked and data-checked flip there, and not one frame goes to the page. Checked is then where it starts.

Reference

Ui.Toggle

flux:toggle

A setting turned on or off from a compact button. Its children, when it has any, are its label.

Step
Takes
What it does
.Bind(…)() => a boolThe bool it reads and writes: () => m.FastMode.
.OnChange(…)a handler given the state it is now in: open => …Runs with the new state at each turn, after the write when it is bound: Flux's wire:change.
.Live()boolWrites the model as soon as it is turned, not with the next action.
.Checked()boolWhether it is on, for a toggle that is not bound: where it starts.
.Icon(…)Ui.IconName, or a componentA Heroicon, outlined when off and solid when on, or icons of your own.
.OnIcon(…)Ui.IconName — one of 317 namesThe icon shown when on, in place of Icon.
.OffIcon(…)Ui.IconName — one of 317 namesThe icon shown when off, in place of Icon.
.Label(…)stringWords beside the icon, in both states.
.OnLabel(…)stringThe words shown when on.
.OffLabel(…)stringThe words shown when off.
.Size(…)
Ui.ToggleSize
Base
Sm
Xs

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

How large it is. Base, 40px, when unset.
.Variant(…)
Ui.ToggleVariant
Outline
Filled
Ghost
Subtle

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

How it is drawn. Outline when unset.
.Color(…)Ui.Color: one of Tailwind's hues, each a step too (.Blue)The icon's colour when on. The accent when unset.
.Tooltip(…)stringA hint on hover, which also names a toggle that shows only an icon.
.Disabled()boolDimmed, and out of the tab order.
Confirm