Components
Radio
One option from a set that excludes the others. The group binds one value, of any type, and each radio says what the value becomes when it is chosen.
Drawn and behaving as Flux UI's radio does, measured against its live docs.
Radio
namespace Rask.Site.Features.UiDocs.Examples;
public sealed partial class RadioExample : Component
{
private string Payment { get; set; } = "cc";
protected override Component? Render() =>
Div.Class("space-y-3")[
Ui.RadioGroup.Bind(() => Payment).Live().Id("rd-payment").Label("Select your payment method")[
Ui.Radio.Value("cc").Label("Credit Card"),
Ui.Radio.Value("paypal").Label("Paypal"),
Ui.Radio.Value("ach").Label("Bank transfer")
],
Ui.Text.Data("testid", "ui-radio-state")[$"Paying by {Payment}."]
];
}Paying by cc.
With descriptions
A description sits under each radio's label.
namespace Rask.Site.Features.UiDocs.Examples;
public sealed partial class RadioDescriptionsExample : Component
{
private string Role { get; set; } = "administrator";
protected override Component? Render() =>
Ui.RadioGroup.Bind(() => Role).Label("Role")[
Ui.Radio.Value("administrator").Label("Administrator").Description("Administrator users can perform any action."),
Ui.Radio.Value("editor").Label("Editor").Description("Editor users have the ability to read, create, and update."),
Ui.Radio.Value("viewer").Label("Viewer")
.Description("Viewer users only have the ability to read. Create, and update are restricted.")
];
}Within fieldset
The group inside a fieldset, whose legend names it.
namespace Rask.Site.Features.UiDocs.Examples;
public sealed partial class RadioFieldsetExample : Component
{
private string Role { get; set; } = "administrator";
protected override Component? Render() =>
Ui.Fieldset[
Ui.Legend["Role"],
Ui.RadioGroup.Bind(() => Role)[
Ui.Radio.Value("administrator").Label("Administrator").Description("Administrator users can perform any action."),
Ui.Radio.Value("editor").Label("Editor").Description("Editor users have the ability to read, create, and update."),
Ui.Radio.Value("viewer").Label("Viewer")
.Description("Viewer users only have the ability to read. Create, and update are restricted.")
]
];
}Segmented
A more compact row of the same radios.
namespace Rask.Site.Features.UiDocs.Examples;
public sealed partial class RadioSegmentedExample : Component
{
private string Role { get; set; } = "administrator";
protected override Component? Render() =>
Div.Class("space-y-3")[
Ui.RadioGroup.Bind(() => Role).Live().Id("rd-segmented").Label("Role").Segmented[
Ui.Radio.Value("administrator").Label("Admin"),
Ui.Radio.Value("editor").Label("Editor"),
Ui.Radio.Value("viewer").Label("Viewer")
],
Ui.Text.Data("testid", "ui-radio-segmented-state")[$"Role: {Role}."]
];
}Role: administrator.
Small segmented
namespace Rask.Site.Features.UiDocs.Examples;
public sealed partial class RadioSegmentedSmallExample : Component
{
private string Role { get; set; } = "administrator";
protected override Component? Render() =>
Ui.RadioGroup.Bind(() => Role).Label("Role").Segmented.Sm[
Ui.Radio.Value("administrator").Label("Admin"),
Ui.Radio.Value("editor").Label("Editor"),
Ui.Radio.Value("viewer").Label("Viewer")
];
}Segmented with icons
namespace Rask.Site.Features.UiDocs.Examples;
public sealed partial class RadioSegmentedIconsExample : Component
{
private string Role { get; set; } = "administrator";
protected override Component? Render() =>
Ui.RadioGroup.Bind(() => Role).Segmented[
Ui.Radio.Value("administrator").Label("Admin").Icon(Ui.IconName.Wrench),
Ui.Radio.Value("editor").Label("Editor").Icon(Ui.IconName.PencilSquare),
Ui.Radio.Value("viewer").Label("Viewer").Icon(Ui.IconName.Eye)
];
}Radio cards
A bordered card is the radio: a press anywhere on it chooses it. max-sm:flex-col stacks the cards on a phone.
namespace Rask.Site.Features.UiDocs.Examples;
public sealed partial class RadioCardsExample : Component
{
private string Shipping { get; set; } = "standard";
protected override Component? Render() =>
Div.Class("space-y-3")[
Ui.RadioGroup.Bind(() => Shipping).Live().Id("rd-cards").Label("Shipping").Cards.Class("max-sm:flex-col")[
Ui.Radio.Value("standard").Label("Standard").Description("4-10 business days"),
Ui.Radio.Value("fast").Label("Fast").Description("2-5 business days"),
Ui.Radio.Value("next-day").Label("Next day").Description("1 business day")
],
Ui.Text.Data("testid", "ui-radio-cards-state")[$"Shipping {Shipping}."]
];
}Shipping standard.
Vertical cards
namespace Rask.Site.Features.UiDocs.Examples;
public sealed partial class RadioVerticalCardsExample : Component
{
private string Shipping { get; set; } = "standard";
protected override Component? Render() =>
Ui.RadioGroup.Bind(() => Shipping).Label("Shipping").Cards.Class("max-w-md flex-col")[
Ui.Radio.Value("standard").Label("Standard").Description("4-10 business days"),
Ui.Radio.Value("fast").Label("Fast").Description("2-5 business days"),
Ui.Radio.Value("next-day").Label("Next day").Description("1 business day")
];
}Cards with icons
namespace Rask.Site.Features.UiDocs.Examples;
public sealed partial class RadioCardIconsExample : Component
{
private string Shipping { get; set; } = "standard";
protected override Component? Render() =>
Ui.RadioGroup.Bind(() => Shipping).Label("Shipping").Cards.Class("max-sm:flex-col")[
Ui.Radio.Value("standard").Icon(Ui.IconName.Truck).Label("Standard").Description("4-10 business days"),
Ui.Radio.Value("fast").Icon(Ui.IconName.Cube).Label("Fast").Description("2-5 business days"),
Ui.Radio.Value("next-day").Icon(Ui.IconName.Clock).Label("Next day").Description("1 business day")
];
}Cards without indicators
Indicator(false) leaves the dot out, for a cleaner card.
namespace Rask.Site.Features.UiDocs.Examples;
public sealed partial class RadioBareCardsExample : Component
{
private string Shipping { get; set; } = "standard";
protected override Component? Render() =>
Ui.RadioGroup.Bind(() => Shipping).Label("Shipping").Cards.Indicator(false).Class("max-sm:flex-col")[
Ui.Radio.Value("standard").Icon(Ui.IconName.Truck).Label("Standard").Description("4-10 business days"),
Ui.Radio.Value("fast").Icon(Ui.IconName.Cube).Label("Fast").Description("2-5 business days"),
Ui.Radio.Value("next-day").Icon(Ui.IconName.Clock).Label("Next day").Description("1 business day")
];
}Custom card content
A card's children replace its label and description; Ui.RadioIndicator puts the dot among them.
namespace Rask.Site.Features.UiDocs.Examples;
public sealed partial class RadioCustomCardsExample : Component
{
private string Shipping { get; set; } = "standard";
protected override Component? Render() =>
Ui.RadioGroup.Bind(() => Shipping).Label("Shipping").Cards.Class("max-sm:flex-col")[
Ui.Radio.Value("standard")[
Ui.RadioIndicator,
Div.Class("flex-1")[
Ui.Heading.Class("leading-4")["Standard"],
Ui.Text.Sm.Class("mt-2")["4-10 business days"]
]
],
Ui.Radio.Value("fast")[
Ui.RadioIndicator,
Div.Class("flex-1")[
Ui.Heading.Class("leading-4")["Fast"],
Ui.Text.Sm.Class("mt-2")["2-5 business days"]
]
],
Ui.Radio.Value("next-day")[
Ui.RadioIndicator,
Div.Class("flex-1")[
Ui.Heading.Class("leading-4")["Next day"],
Ui.Text.Sm.Class("mt-2")["1 business day"]
]
]
];
}Pills
namespace Rask.Site.Features.UiDocs.Examples;
public sealed partial class RadioPillsExample : Component
{
private string Priority { get; set; } = "medium";
protected override Component? Render() =>
Ui.RadioGroup.Bind(() => Priority).Label("Priority").Pills[
Ui.Radio.Value("low").Label("Low"),
Ui.Radio.Value("medium").Label("Medium"),
Ui.Radio.Value("high").Label("High"),
Ui.Radio.Value("critical").Label("Critical")
];
}Buttons
Radios drawn as a toolbar. A radio's children are its words, as a button's are.
namespace Rask.Site.Features.UiDocs.Examples;
public sealed partial class RadioButtonsExample : Component
{
private string Feedback { get; set; } = "bug";
protected override Component? Render() =>
Ui.RadioGroup.Bind(() => Feedback).Buttons.Class("w-full *:flex-1").Label("Feedback type")[
Ui.Radio.Value("bug").Icon(Ui.IconName.BugAnt)["Bug report"],
Ui.Radio.Value("suggestion").Icon(Ui.IconName.LightBulb)["Suggestion"],
Ui.Radio.Value("question").Icon(Ui.IconName.QuestionMarkCircle)["Question"]
];
}Behaviour
One value, of any type
The group binds one value: Ui.RadioGroup.Bind(() => m.Plan) over a string, an enum or a number, or Value(plan).OnChange(…) for one the page owns. Each Ui.Radio's Value is what the member becomes when that radio is chosen, and Ui.Radio.Checked() chooses one only while the group holds no value. Segmented (with Sm), Cards (with Indicator(false)), Pills and Buttons draw the same radios.
The keyboard
Each radio is a <label> around a real <input type="radio"> that shares the group's name, so the keys are the browser's in every variant, and so are a click on the label and the form post.
Key | What happens |
|---|---|
| ArrowDown, ArrowRight | Moves to the next radio and chooses it, wrapping from the last to the first. |
| ArrowUp, ArrowLeft | Moves to the previous radio and chooses it, wrapping from the first to the last. |
| Tab | Enters the group at the chosen radio, and leaves it. |
| Space | Chooses the focused radio. |
What it posts
A radio group names its radios after its own id unless Name says otherwise, and a Name on one radio replaces the group's for that radio. A bound group is invalid on its own while its form holds a message for the member, and Invalid() says so by hand.
Reference
Ui.RadioGroup
Radios over one value. Its type is the type of their values.
Step | Takes | What it does |
|---|---|---|
.Bind(…) | () => a T | The model's member it reads and writes: () => m.Plan. Or Value with OnChange. |
.Value(…) | T, the type of the radios' values | The chosen value, for a page that holds it itself. |
.OnChange(…) | a handler given the new value | Runs with the new value when a radio is chosen. |
.AfterBind(…) | a handler given the new value | Runs after Bind has written the model. |
.Validate(…) | a validator | A rule the value is checked by when it is written. |
.Live() | bool | Writes the model as soon as a radio is chosen, not with the next action. |
.Variant(…) | Ui.RadioGroupVariantDefault Segmented Cards Pills Buttons Each is a step of its own too, unless an HTML tag has its name. | How the radios are drawn. A column when unset. |
.Size(…) | Ui.RadioGroupSizeBase Sm Each is a step of its own too, unless an HTML tag has its name. | Sm for a smaller segmented row. |
.Indicator() | bool | False leaves the dot off the cards. |
.Label(…) | string | Draws a field around it, with this label and the error. |
.Description(…) | string | Help text between the label and the radios. |
.Invalid() | bool | Error styling the form did not ask for. |
.Name(…) | string | What the radios are posted under. The group's id when unset. |
.ShowValidation() | bool | False leaves the member's message to a Ui.Error placed elsewhere. |
Ui.Radio
One choice in a label. Its children are a button's words, or a custom card.
Step | Takes | What it does |
|---|---|---|
.Value(…) | a value of the group's type | What the group's member becomes when it is chosen. |
.Label(…) | string | Its words, beside it. |
.Description(…) | string | Help text under its label. |
.Icon(…) | Ui.IconName — one of 317 names | An icon on a segment, a card or a button. |
.Checked() | bool | Chooses it while the group holds no value. |
.Disabled() | bool | Dims it and takes it out of reach. |
.Name(…) | string | What it is posted under, in place of the group's. |
.Attributes(…) | ("aria-label", "Search") pairs | Attributes for the <input> itself. |
Ui.RadioIndicator
The dot, placed among a custom card's own content.
No steps of its own: what goes inside it is its content.