
This release adds a Turbo-aware Drawer component, a `scaffold_templates` generator that makes `rails generate scaffold` produce styled views, and engine helpers included in the generated helper module. It's also a first for the project: most of it came from contributors.

## Drawer

A slide-out panel with an overlay backdrop, built from sub-partials the same way Card and Sidebar are. A `provider` owns the state; `header`, `content`, and `footer` structure the panel; a `trigger` toggles it and a `close` dismisses it.

```erb
<%%= render "components/drawer/provider", default_open: drawer_open? do %>
  <%%= render "components/drawer", state: drawer_state do %>
    <%%= render "components/drawer/header" do %>
      <h2 class="text-lg font-semibold">Filters</h2>
      <%%= render "components/drawer/close" %>
    <%% end %>

    <%%= render "components/drawer/content" do %>
      <!-- Panel body -->
    <%% end %>

    <%%= render "components/drawer/footer" do %>
      <!-- Apply / Reset -->
    <%% end %>
  <%% end %>
<%% end %>
```

Drop a `trigger` anywhere on the page as a plain toggle button:

```erb
<%%= render "components/drawer/trigger" %>
```

The drawer opens from the right by default; pass `side: :left` to open from the other edge.

**Features:** compound structure (`provider`, `header`, `content`, `footer`, `trigger`, `close`), left or right side with an overlay backdrop, a configurable `Cmd/Ctrl+D` shortcut, cookie-based state persistence, and full Turbo Drive and Morph compatibility.

### Surviving Turbo

The reason a drawer is more than a CSS transition is the lifecycle around it. The controller handles the three places Turbo usually breaks a stateful component:

**Cache teardown.** Before Turbo snapshots the page for its cache, the drawer closes and hides its backdrop. A restored snapshot never comes back frozen mid-transition.

**Morph awareness.** With `turbo_refresh_method_tag :morph`, the server re-renders the page in its default state—it doesn't know the drawer was open. The controller re-reads its cookie on morph and reasserts the correct state—the same fix [the sidebar got in 0.4.0](https://maquina.app/blog/2026/02/maquina-components-0-4-0-turbo-compatibility/).

**Persistence.** State lives in a cookie, so the drawer holds across full page loads and Turbo navigations alike.

That state is exposed through three helpers, so your server-rendered markup and the client agree on the first paint:

```ruby
drawer_state    # => :open or :closed
drawer_open?    # => true / false
drawer_closed?  # => true / false
```

Passing `default_open: drawer_open?` into the provider and `state: drawer_state` into the drawer, as in the usage above, is what closes the loop between the cookie and the initial render.

## Scaffold Templates

Having a component library is one thing; getting your generated code to use it is another. The new `scaffold_templates` generator closes that gap.

```bash
bin/rails generate maquina_components:scaffold_templates
```

It copies a set of ERB scaffold templates—`index`, `show`, `new`, `edit`, `_form`, and the record partial—into `lib/templates/erb/scaffold/`. Rails has always let you override its generator templates from that path; what was missing was a set that renders with the component library. Now they ship with the gem.

From then on, the standard scaffold generator produces styled views out of the box:

```bash
bin/rails generate scaffold Post title:string body:text
```

You get tables, buttons, and form fields built with Maquina Components instead of Rails' default markup—before writing any view code. Because the templates are copied into your app, they're yours to edit afterward.

## Engine Helpers in the Generated Module

A quieter change in the same direction. The generated `MaquinaComponentsHelper` now includes `IconsHelper`, `SidebarHelper`, and `ToastHelper`. Helpers like `icon_for`, `sidebar_open?`, and `toast_flash_messages` are available in host-app views without an extra `include` in `ApplicationHelper`. It's a one-line diff in the template that removes a papercut every new install used to hit—reaching for `icon_for` and getting a `NoMethodError` because the module wasn't wired up yet.

## Icon Class Handling

The one bug fix this release tightens `apply_icon_options`. It now guards against `nil` and non-string class values, HTML-escapes the class before it reaches the markup, and injects a `class` attribute onto `<svg>` elements that didn't already have one. Small, but exactly the kind of edge case that only surfaces once icons are being passed around inside real templates.

## Contributors

This release was built mostly by two people who aren't me:

- [@GregorioNeto](https://github.com/GregorioNeto) — the Drawer component (#21) and the icon class handling fix (#17)
- [@JuanVqz](https://github.com/JuanVqz) — the `scaffold_templates` generator (#20) and the engine helper modules in the generated helper (#19)

Thank you both.

## Upgrading

```bash
bundle update maquina_components
```

Then, when you want styled scaffolds, install the templates:

```bash
bin/rails generate maquina_components:scaffold_templates
```

There are no breaking changes in this release.

## What This Reinforced

Three of the four changes pull the same way: they make the gem lean on Rails instead of sitting next to it. The scaffold templates go through Rails' own generator override path. Helpers are included the way any Rails helper is. And the Drawer keeps its state in a cookie and reacts to Turbo's morph, the way the sidebar already does. Less to learn, fewer seams to trip over.

The other thing worth saying is that I reviewed this release more than I wrote it. Gregorio and Juan built the components; I merged them. That says more about where the project is than any one feature does.

## Documentation

- [Drawer](https://maquina.app/documentation/components/drawer/)
- [Component documentation](https://maquina.app/documentation/components/)

## Source

- [Maquina Components](https://github.com/maquina-app/maquina_components)
- [Full Changelog](https://github.com/maquina-app/maquina_components/compare/v0.4.4...v0.5.0)
- [Gem on RubyGems](https://rubygems.org/gems/maquina-components/versions/0.5.0)
