Components
Confirm
The dialog an action's .Confirm("…") asks in, in place of the browser's own confirm and prompt. Place Ui.Confirm in the layout once and every .Confirm on every page asks through it. Not one of Flux UI's components: the kit's own, a Ui.Modal drawn as Flux's confirmation.
Confirm an action
This tab's layout places a Ui.Confirm, so the button asks in it. heading: is the question's own title; No, the close button, Escape and a press outside call the delete off, and Yes lets the same press go.
namespace Rask.Site.Features.UiDocs.Examples;
// This tab's layout places Ui.Confirm once, so every .Confirm("…") on its pages asks in that dialog. heading: is
// this question's own title, and the question is the sentence beneath it.
public sealed partial class ConfirmExample : Component
{
private string _project = "Rask";
protected override Component? Render() =>
Div.Class("flex flex-wrap items-center gap-4")[
Ui.Button.Danger.Id("uc-delete")
.OnClick(() => _project = "")
.Confirm("You're about to delete this project. This action cannot be reversed.", heading: "Delete project?")["Delete project"],
Ui.Button.Ghost.Id("uc-restore").OnClick(() => _project = "Rask")["Restore"],
Ui.Text.Id("uc-state")[_project.Length > 0 ? $"The {_project} project is still there." : "You deleted the project."]
];
}The Rask project is still there.
Type to confirm
With expect: the dialog shows a field, and Yes waits until the answer is typed exactly, case and all. Livewire's wire:confirm.prompt.
namespace Rask.Site.Features.UiDocs.Examples;
// expect: shows a field in the dialog, and Yes waits until the answer is typed exactly, case and all.
public sealed partial class ConfirmExpectExample : Component
{
private readonly List<string> _partners = ["Acme", "Globex", "Initech"];
protected override Component? Render() =>
Div.Class("space-y-3")[
Ul.Class("max-w-sm divide-y divide-zinc-800/10 dark:divide-white/20")[
_partners.Select(name => Li.Key(name).Class("flex items-center gap-2 py-2")[
Ui.Text.Class("grow")[name],
Ui.Button.Sm.Danger.Id($"uc-wipe-{name}")
.OnClick(() => _partners.Remove(name))
.Confirm($"Type {name} to delete it.", expect: name, heading: "Delete partner?")["Delete"]
])
],
Ui.Text.Id("uc-left")[$"{_partners.Count} partners"]
];
}Acme
Globex
Initech
3 partners
On a form
On a form it asks before the submit, and the form is held only once Yes lets it go. On a submit button it asks before the submit that button makes.
namespace Rask.Site.Features.UiDocs.Examples;
// On a form, .Confirm asks before the submit, and the form is held only once Yes lets it go.
public sealed partial class ConfirmFormExample : Component
{
private readonly Order _order = new();
private string? _sent;
protected override Component? Render() =>
Div.Class("space-y-3")[
Form.Model(_order).OnSubmit(Send).Id("uc-form").Class("flex flex-wrap items-end gap-4")
.Confirm("The kitchen starts cooking as soon as it arrives.", heading: "Send the order?")[
Ui.Input.Bind(() => _order.Dish).Label("Dish").Id("uc-dish").Class("max-w-xs"),
Ui.Button.Primary.Submit.Id("uc-send")["Send order"]
],
Ui.Text.Id("uc-sent")[_sent is null ? "Nothing sent yet." : "Sent: " + _sent]
];
private void Send(Order order) => _sent = order.Dish;
public sealed class Order
{
public string Dish { get; set; } = "Pancakes";
}
}Nothing sent yet.
Your own words
Heading, No and Yes are the layout's, for every question on the page; a question with heading: brings its own title. A layout of its own, framed, because a page holds one dialog.
namespace Rask.Site.Features.UiDocs.Examples;
// A layout of your own places the dialog once, in your words: the title a question without heading: gets, and
// the two buttons.
public sealed partial class ConfirmWordsExample : Component
{
private int _companies = 3;
protected override Component? Render() =>
[
Ui.Main.Class("flex min-h-dvh items-center justify-center")[
Div.Class("flex flex-wrap items-center gap-4")[
Ui.Button.Danger.Id("uc-words-delete")
.OnClick(() => _companies--)
.Confirm("Biztosan törli a céget?", heading: "Cég törlése")["Törlés"],
Ui.Button.Id("uc-words-archive")
.OnClick(() => _companies--)
.Confirm("Archiválja a céget?")["Archiválás"],
Ui.Text.Id("uc-words-left")[$"{_companies} cég"]
]
],
Ui.Confirm.Heading("Megerősítés").No("Nem").Yes("Igen")
];
}Behaviour
Placed once
Ui.Confirm goes in the layout, beside Ui.Toast, and every .Confirm("…") under it asks in that dialog. The call sites do not change: .Confirm is a step on every element, a plain Button, a Ui.Button, a Form, a submit button and a Ui.MenuItem alike.
Without it the same .Confirm asks in the browser's own window.confirm, or window.prompt for expect:, and heading: is not shown.
No, and yes
Only Yes lets the action go: the same press, or the same submit by the same button. The page may render while the reader is asked; Yes presses the button as the page stands then, and one that is gone runs nothing. Focus goes back to the control that was pressed.
The reader | What happens |
|---|---|
| presses No, the close button or Escape, or presses outside | The action is called off. Nothing is sent. |
| presses Yes | The click or the submit goes, and a form is held only now. |
types into the expect: field | Yes stays disabled until the answer matches exactly; then Enter is Yes. |
Asked in the browser
The dialog is rendered closed and the runtime writes the question into it and opens it (data-rask-confirm, data-rask-confirm-expect), so opening, typing and closing send the server nothing, on both hosts. A cancelled action sends nothing either: not the click, and not the bound fields waiting to go with it.
The expected answer is written into the page, so it guards against a slip, never a secret.
Its words
Heading, No and Yes default from the string catalog (ConfirmHeading, ConfirmNo, ConfirmYes), so a localized app needs no step at all. A question's heading: replaces the title for that question alone.
Drawn as Flux's confirmation: min-w-[22rem], a ghost button that says no and a danger button that says yes. The answer field, and a Yes that is no submit button, are its two departures.
Reference
Ui.Confirm
The dialog every .Confirm("…") under its layout asks in, in place of the browser's confirm and prompt. One per page.
Step | Takes | What it does |
|---|---|---|
.Heading(…) | string | The short title above the question. "Confirm" when unset; a question's own heading: replaces it. |
.No(…) | string | The label of the button that calls the action off. "No" when unset. |
.Yes(…) | string | The label of the button that lets the action go. "Yes" when unset. |