Alert Dialog
A modal dialog that interrupts the user with important content and expects a response.
Usage
Example
Are you absolutely sure?
This action cannot be undone. This will permanently delete your account and remove your data from our servers.
AlertDialog do AlertDialogTrigger do Button { "Show dialog" } end AlertDialogContent do AlertDialogHeader do AlertDialogTitle { "Are you absolutely sure?" } AlertDialogDescription { "This action cannot be undone. This will permanently delete your account and remove your data from our servers." } end AlertDialogFooter do AlertDialogCancel { "Cancel" } AlertDialogAction { "Continue" } # Will probably be a link to a controller action (e.g. delete account) end end end
Installation
Using RubyUI CLI
Run the install command
rails g ruby_ui:component AlertDialog
Manual installation
1
Add RubyUI::AlertDialog
to app/components/ruby_ui/alert_dialog.rb
# frozen_string_literal: true module RubyUI class AlertDialog < Base def initialize(open: false, **attrs) @open = open super(**attrs) end def view_template(&) div(**attrs, &) end private def default_attrs { data: { controller: "ruby-ui--alert-dialog", ruby_ui__alert_dialog_open_value: @open.to_s }, class: "inline-block" } end end end
2
Add RubyUI::AlertDialogAction
to app/components/ruby_ui/alert_dialog/alert_dialog_action.rb
# frozen_string_literal: true module RubyUI class AlertDialogAction < Base def view_template(&) render RubyUI::Button.new(**attrs, &) end private def default_attrs { variant: :primary } end end end
3
Add RubyUI::AlertDialogCancel
to app/components/ruby_ui/alert_dialog/alert_dialog_cancel.rb
# frozen_string_literal: true module RubyUI class AlertDialogCancel < Base def view_template(&) render RubyUI::Button.new(**attrs, &) end private def default_attrs { variant: :outline, data: { action: "click->ruby-ui--alert-dialog#dismiss" }, class: "mt-2 sm:mt-0" } end end end
4
Add RubyUI::AlertDialogContent
to app/components/ruby_ui/alert_dialog/alert_dialog_content.rb
# frozen_string_literal: true module RubyUI class AlertDialogContent < Base def view_template(&block) template(**attrs) do div(data: {controller: "ruby-ui--alert-dialog"}) do background container(&block) end end end def background div( data_state: "open", class: "fixed inset-0 z-50 bg-black/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", style: "pointer-events:auto", data_aria_hidden: "true", aria_hidden: "true" ) end def container(&) div( role: "alertdialog", data_state: "open", class: "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg md:w-full", style: "pointer-events:auto", & ) end private def default_attrs { data: { ruby_ui__alert_dialog_target: "content" } } end end end
5
Add RubyUI::AlertDialogDescription
to app/components/ruby_ui/alert_dialog/alert_dialog_description.rb
# frozen_string_literal: true module RubyUI class AlertDialogDescription < Base def view_template(&) p(**attrs, &) end private def default_attrs { class: "text-sm text-muted-foreground" } end end end
6
Add RubyUI::AlertDialogFooter
to app/components/ruby_ui/alert_dialog/alert_dialog_footer.rb
# frozen_string_literal: true module RubyUI class AlertDialogFooter < Base def view_template(&) div(**attrs, &) end private def default_attrs { class: "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2" } end end end
7
Add RubyUI::AlertDialogHeader
to app/components/ruby_ui/alert_dialog/alert_dialog_header.rb
# frozen_string_literal: true module RubyUI class AlertDialogHeader < Base def view_template(&) div(**attrs, &) end private def default_attrs { class: "flex flex-col space-y-2 text-center sm:text-left" } end end end
8
Add RubyUI::AlertDialogTitle
to app/components/ruby_ui/alert_dialog/alert_dialog_title.rb
# frozen_string_literal: true module RubyUI class AlertDialogTitle < Base def view_template(&) h2(**attrs, &) end private def default_attrs { class: "text-lg font-semibold" } end end end
9
Add RubyUI::AlertDialogTrigger
to app/components/ruby_ui/alert_dialog/alert_dialog_trigger.rb
# frozen_string_literal: true module RubyUI class AlertDialogTrigger < Base def view_template(&) div(**attrs, &) end private def default_attrs { data: {action: "click->ruby-ui--alert-dialog#open"}, class: "inline-block" } end end end
10
Add alert_dialog_controller.js
to app/javascript/controllers/ruby_ui/alert_dialog_controller.js
import { Controller } from "@hotwired/stimulus"; // Connects to data-controller="ruby-ui--alert-dialog" export default class extends Controller { static targets = ["content"]; static values = { open: { type: Boolean, default: false, }, }; connect() { if (this.openValue) { this.open(); } } open() { document.body.insertAdjacentHTML("beforeend", this.contentTarget.innerHTML); // prevent scroll on body document.body.classList.add("overflow-hidden"); } dismiss(e) { // allow scroll on body document.body.classList.remove("overflow-hidden"); // remove the element this.element.remove(); } }
11
Update the Stimulus controllers manifest file
Importmap!
rake stimulus:manifest:update
12
Install required components
Component AlertDialog
relies on the following RubyUI components. Refer to their individual installation guides for setup instructions:
Components
Component | Built using | Source |
---|---|---|
AlertDialog | Phlex | |
AlertDialogAction | Phlex | |
AlertDialogCancel | Phlex | |
AlertDialogContent | Phlex | |
AlertDialogDescription | Phlex | |
AlertDialogFooter | Phlex | |
AlertDialogHeader | Phlex | |
AlertDialogTitle | Phlex | |
AlertDialogTrigger | Phlex | |
AlertDialogController | Stimulus JS |