Fluxbit::ModalComponent or fx_modal
The Fluxbit::ModalComponent
is a component for rendering customizable modals. It extends Fluxbit::Component
and provides options for configuring the modal's appearance, behavior, and content areas. You can control the modal's title, size, placement, backdrop behavior, and other interactive elements. The modal is divided into different sections (header, content, and footer), each of which can be styled or customized through various properties.
To start using the modal, you can use the default way to call the component:
<%= render Fluxbit::ModalComponent.new(title: "My Modal", opened: true) do %> <p>Your modal content goes here.</p><% end %>
or you can use the alias (from the helpers):
<%= fx_modal(title: "My Modal", opened: true) do %> <p>Your modal content goes here.</p><% end %>
The result look like this:
Options
Param | Default | Description |
---|---|---|
title: | nil | The title text displayed in the modal header. |
opened: | false | Determines if the modal is initially open (visible). |
close_button: | true | Determines if a close button should be displayed in the header. |
flat: | false | Applies a "flat" style for the header and footer (removes border lines, etc.). |
size: | 1 | The size of the modal, corresponding to predefined Tailwind classes (e.g., 0 to 9). |
placement: | nil | The placement of the modal (e.g., :center , :top , :bottom ). When set, it adds data-modal-placement="<placement>" to the outer container. |
only_css: | false | If true , a button to open isn't obligatory. |
static: | false | If true , the modal will not close when clicking the backdrop or pressing the ESC key (i.e., it’s “static”). |
remove_class: | "" | Classes to be removed from the default modal class list. |
content_props: | {} | Additional HTML attributes for the content wrapper (the inner container of the modal). |
header_props: | {} | Additional HTML attributes for the header section. |
footer_props: | {} | Additional HTML attributes for the footer section. |
closebuttonprops: | {} | Additional HTML attributes for the close button. |
**props | Remaining options declared as HTML attributes, applied to the outer modal container. |
Slots
The component supports the following slots:
- with_title (or simply
title
): Renders a slot for the modal title. - with_footer (or simply
footer
): Renders a slot for the modal footer.
Note: If you set
title:
via the constructor and also providewith_title
block content, both will appear unless you handle that manually. Typically, you’d choose one approach.
Examples
Default Modal
Modal with slots Title and Footer
Modal placements
Modal sizes
Flat Modal
Static (Non-closable) Modal
Backdrop-close (CSS-only) Modal
Adding/Removing Classes
Customization
You can customize the appearance and behavior of this component by passing different initialization parameters or adding custom styles. For a more global customization, you could update or override the component’s default styles in an initializer, e.g.:
# config/initializers/change_modal_component_defaults.rbFluxbit::Config::ModalComponent.styles[:root][:base] = "fixed inset-x-0 top-0 z-[9999] h-screen overflow-y-auto overflow-x-hidden md:inset-0 md:h-full flex"Fluxbit::Config::ModalComponent.opened = false # default valueFluxbit::Config::ModalComponent.close_button = true # default valueFluxbit::Config::ModalComponent.flat = false # default valueFluxbit::Config::ModalComponent.size = 2 # default valueFluxbit::Config::ModalComponent.only_css = false # default valueFluxbit::Config::ModalComponent.static = false # default value
Dependencies
- Anyicon: Used for rendering icons (close button).
- Tailwind CSS: Used for styling the component.
- Flowbite: Used for styling, including the backdrop and default classes.
Styles
To view the current styles configuration for the Fluxbit::ModalComponent
, you can inspect:
{ "root": { "base": "fixed inset-x-0 top-0 z-50 h-screen overflow-y-auto overflow-x-hidden md:inset-0 md:h-full flex", "backdrop": "bg-gray-900/50 dark:bg-gray-900/80", "show": { "on": "", "off": "hidden" }, "size": [ "max-w-sm", "max-w-md", "max-w-lg", "max-w-xl", "max-w-2xl", "max-w-3xl", "max-w-4xl", "max-w-5xl", "max-w-6xl", "max-w-7xl" ], "placements": { "top-left": "items-start justify-start", "top-center": "items-start justify-center", "top-right": "items-start justify-end", "center-left": "items-center justify-start", "center": "items-center justify-center", "center-right": "items-center justify-end", "bottom-right": "items-end justify-end", "bottom-center": "items-end justify-center", "bottom-left": "items-end justify-start" } }, "content": { "base": "relative h-full w-full p-4 md:h-auto", "inner": "relative flex max-h-[90dvh] flex-col rounded-lg bg-white shadow-sm dark:bg-gray-700" }, "body": { "base": "flex-1 overflow-auto p-6", "flat": "pt-0", "no_title": "-mt-4" }, "header": { "base": "flex items-start justify-between rounded-t border-b p-5 dark:border-gray-600", "flat": "border-b-0 p-2", "title": "text-xl font-medium text-gray-900 dark:text-white", "close": { "base": "close-button ml-auto inline-flex items-center rounded-lg bg-transparent p-1.5 text-sm text-gray-400 hover:bg-gray-200 hover:text-gray-900 dark:hover:bg-gray-600 dark:hover:text-white", "icon": "h-5 w-5" } }, "footer": { "base": "flex items-center space-x-2 rounded-b border-t border-gray-200 p-6 dark:border-gray-600", "flat": "border-t-0" }}
which will output a JSON representation of the default style mappings.