Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/martinzamuner/overlastic

Fantastically easy overlays, dialog modals and slide-out-panes using Hotwire.
https://github.com/martinzamuner/overlastic

dialogs hotwire modals overlays panes rails ruby turbo

Last synced: about 1 month ago
JSON representation

Fantastically easy overlays, dialog modals and slide-out-panes using Hotwire.

Awesome Lists containing this project

README

        




Overlastic


Overlastic


Fantastically easy overlays using Hotwire.


Build
Gem
rails version
turbo-rails version
License

Load any page inside an overlay (dialog modal, slide-out pane, or whatever else floats your boat). As easy as replacing `link_to` with `link_to_dialog`.

### Benefits

Built on top of your existing code

No need to bend your codebase in weird ways or add lots of lines that feel out of place. Just change a link whenever you want something to open as an overlay. **The rest of your views, controllers and helpers stay the same**.

Reuse your existing overlay views

Already have a partial for your gorgeous dialog modal? **Just tell Overlastic about it inside an initializer** and it will handle the rest.

Progressive enhancement

Are you a compulsive tab opener? Overlay links render as normal pages if you open them in a new tab. On top of that, everything will **still work perfectly without Javascript**. Overlay links will just turn into _blank links.

## Installation

This gem requires a modern Rails application running [turbo-rails](https://github.com/hotwired/turbo-rails). It supports both import map and node setups.

1. `bundle add overlastic`
2. `rails overlastic:install`

## Usage

Most of the time you'll just need to replace a `link_to` with one of the overlay helpers:

```erb
<%= link_to_dialog "Open dialog", edit_article_path %>
<%= link_to_pane "Open slide-out pane", edit_article_path %>
<%= link_to_overlay "Open default overlay type", edit_article_path %>
<%= link_to_overlay "Open dialog", edit_article_path, overlay_type: :dialog %>
```

They work just as `link_to` and accept the same options. You can also pass locals to the overlay view:

```erb
<%= link_to_dialog "Open dialog", edit_article_path, overlay_args: { title: "Dialog title" } %>
```

Nested overlays will stack on top of each other. You can instead replace the last one or the whole stack:

```erb
<%= link_to_dialog "Open dialog", edit_article_path, overlay: :last %>
<%= link_to_dialog "Open dialog", edit_article_path, overlay: :first %>
```

By default, links and forms inside an overlay will drive the entire page (target _top). To keep navigation within the overlay you can set its target to _self:

```erb
<%= link_to_dialog "Open dialog", edit_article_path, overlay_target: :_self %>
```

To break out of an overlay with target _self you can use:

```erb
<%= link_to "Open whole page", edit_article_path, overlay: false %>
```

A common use case is to render a form inside an overlay. When the form is submitted, you'll validate the data and redirect to a different page if it's successful or render the form again with errors. Overlastic will handle both cases gracefully without any modifications:

```rb
if @article.save
redirect_to article_url(@article), status: :see_other
else
render :new, status: :unprocessable_entity
end
```

In case the form overlay was nested inside another overlay, you could prefer to apply the redirection to the parent overlay:

```rb
redirect_to article_url(@article), overlay: :previous, status: :see_other
```

### Intermediate features

Adapting a view using the overlay variant

Sometimes, you may want to alter the content of a view depending on whether it's inside an overlay or not. Overlastic defines a new `:overlay` request variant that you can use to create custom views like `new.html+overlay.erb` or inside a controller like so:

```rb
respond_to do |format|
format.turbo_stream.overlay { render :custom_view }
format.turbo_stream.any
format.html
end
```

Closing an overlay from the server

If you don't need to render any more content you can also close an overlay from the server:

```rb
if request.variant.overlay?
close_overlay
# close_overlay :last
# close_overlay :all
# close_overlay :overlay2
else
redirect_to articles_url, status: :see_other
end
```

Attaching to lifecycle events

If you want to add custom behavior every time an overlay is removed or attached to the DOM, you can listen to their lifecycle events:

- `overlastic:connected`
- `overlastic:disconnected`

They target the first element in your view to make it easy to add listeners using libraries like Stimulus. You could, for example, have something like this:

```html


...

```

The `overlastic:disconnect` event can be paused and resumed, which allows you to run lengthy functions, like animations, before being closed or replaced by another overlay:

```js
close(event) {
event.preventDefault()

this.leave().then(() => {
event.detail.resume()
})
}
```

If there are many overlays being closed at the same time, all of them will be dispatched an `overlastic:disconnect` event. This is great to have independent animations for each of them.

### Advanced features

Appending Turbo Streams to close_overlay

Sometimes, you may want not only to close an overlay, but also to deliver some other page change using a Turbo Stream:

```rb
close_overlay do
turbo_stream.prepend("flash-messages", "Deleted!")
end
```

Appending Turbo Streams to every response

Overlastic can be configured to append a Turbo Stream to every response that contains an overlay.
This can be very useful for automatically rendering new flash messages whenever they're available:

```rb
Overlastic.configure do |config|
config.append_turbo_stream do
turbo_stream.replace("flash-messages", partial: "shared/flash_messages")
end
end
```

Then you'd only need to specify a flash message inside your action, when closing an overlay, or when redirecting to a different path:

```rb
def show
flash.now[:notice] = "You've been noticed!"
end

# or

close_overlay notice: "Deleted!"

# or

redirect_to articles_path, notice: "Deleted!", status: :see_other
```

Rendering an overlay without an initiator

Overlastic extends the `render` method inside a controller to add all the same options as `link_to_overlay`. This allows you to force an action to render an overlay, even if it wasn't requested:

```rb
render :new, overlay: :first, overlay_target: :_self, overlay_args: { title: "New article" }
# render :edit, overlay: :last, overlay_type: :pane
```

## Configuration

```rb
# config/initializers/overlastic.rb

Overlastic.configure do |config|
config.overlay_types = %i[dialog pane]
config.default_overlay = :dialog # Options: One of the defined overlay types
config.default_action = :stack # Options: :stack, :replace_last, :replace_all
config.default_target = :_top # Options: :_top, :_self

# You can define a custom partial for each overlay type
config.dialog_overlay_view_path = "overlays/dialog"
config.pane_overlay_view_path = "overlays/pane"

# You can append Turbo Streams to every response containing an overlay
config.append_turbo_stream do
turbo_stream.replace("flash-messages", partial: "shared/flash_messages")
end
end
```

## UI customization

Overlastic comes with default views for both the dialog and pane overlays. They are intended to provide an easy way to try the gem. For real-world usage you're expected to implement your own UI elements, or use something like [Bootstrap](https://getbootstrap.com) or [TailwindCSS Stimulus Components](https://github.com/excid3/tailwindcss-stimulus-components).

Default overlays

**Dialog**

Dialog


**Pane**

Dialog

Generate customizable views

Overlastic provides a generator to build your own views using the default overlays as a base. It's not advisable, though. You're better off using a UI library.

```sh
# Available options: inline, tailwind
./bin/rails generate overlastic:views --css tailwind
```

## Development

Running the demo application

- First you need to install dependencies with `bundle && yarn && yarn build`
- Then you need to setup the DB with `rails db:setup`
- Lastly you can run the demo app with `rails server --port 3000`

Running the tests

- You can run the whole suite with `./bin/test test/**/*_test.rb`

## License

Overlastic is released under the [MIT License](https://opensource.org/licenses/MIT).