Upgrading LocoMotion

This guide covers upgrading from v0.6.0 to v0.7.0. It is a big release: the Labelable start / end API is renamed, icons render through the new loco_icon engine, and checkboxes submit like Rails checkboxes. Three new components (Megamenu, OTP, and Aura) come along for the ride.

1. Update your packages

Bump the gem and the matching npm package. The new Megamenu, OTP, and Aura components rely on styles introduced in DaisyUI 5.6, so the npm package now declares daisyui ^5.6.0 as a peer dependency — bump it alongside:

# Gemfile
gem "loco_motion-rails", "~> 0.7.0"
yarn add @profoundry-us/loco_motion@0.7.0
yarn add daisyui@^5.6.7

Breaking 2. Rename start / end to leading / trailing

The start / end pair is renamed everywhere: start is now leading and end is now trailing. (end is a Ruby reserved word, so its generated slot reader forced send(:end) workarounds; the new pair is symmetric and reserved-word free.) This is a hard rename with no deprecation aliases, affecting:

  • The labelable inputs (and their form-builder equivalents like f.daisy_checkbox): daisy_text_input (and its daisy_input alias), daisy_select, daisy_checkbox, daisy_toggle, daisy_radio, and daisy_cally_input
  • The Navbar's start / end slots (center is unchanged)
  • The Timeline event's start / end slots and its with_event(start:, end:) options (middle / middle_icon are unchanged)
  • The Modal's start_actions / end_actions slots and parts, which become leading_actions / trailing_actions

Every spelling of the pair changes — keyword arguments, slot calls, and the generated part options:

BeforeAfterApplies to
start: end:
leading: trailing:
Keyword arguments
with_start with_end
with_leading with_trailing
Slot calls
with_start_actions with_end_actions
with_leading_actions with_trailing_actions
Modal action slots
start_* end_*
leading_* trailing_*
Generated part options (css, html, aria, data)
has_start_label? has_end_label?
has_leading_label? has_trailing_label?
Labelable predicates

One thing does not change: the rendered HTML. The emitted CSS classes (navbar-start, timeline-end, ...) are DaisyUI's own selectors, so your stylesheets keep working untouched — the rename is confined to the Ruby API.

Before
= daisy_text_input(name: "username", start: "Username:")
= daisy_checkbox(name: "terms", end: "I agree")
= daisy_navbar do |navbar|
  - navbar.with_start do
    Logo
= daisy_timeline do |timeline|
  - timeline.with_event(start: "1984", end: "Born")
After
= daisy_text_input(name: "username", leading: "Username:")
= daisy_checkbox(name: "terms", trailing: "I agree")
= daisy_navbar do |navbar|
  - navbar.with_leading do
    Logo
= daisy_timeline do |timeline|
  - timeline.with_event(leading: "1984", trailing: "Born")

Automated Let the migration task do it

v0.7.0 ships a rake task that performs the rename for you. It scans app/ and rewrites only usage it can confidently attribute to the renamed components above. Run it without arguments for a dry-run report, then apply:

bin/rails loco_motion:migrate:leading_trailing
review the dry-run report, then...
APPLY=1 bin/rails loco_motion:migrate:leading_trailing

Manual follow-ups

  • Prose and headings: comments, docs, or UI copy that talk about the start / end labels (the task only rewrites code).
  • Custom components that include LocoMotion::Concerns::LabelableComponent: the parts, slots, and predicates are renamed too — has_start_label? / has_end_label? are now has_leading_label? / has_trailing_label?.
  • Direct component renders (TimelineEventComponent.new(start: ...)) and system / e2e tests that assert on the old markup or wording.

Breaking 3. Icons: hero_icon is gone, meet loco_icon

LocoMotion no longer bundles rails_heroicon. Every icon — including the ones components render via icon: options — now resolves through the pluggable loco_icon engine, which reads SVGs synced into your own app. The short version:

  1. Sync your icons once and commit the SVGs: bin/rails loco_motion:icons:add heroicons (or loco_motion:icons:sync to vendor only the icons you use).
  2. Rename hero_icon / heroicon calls to loco_icon.
  3. Replace Hero::IconComponent with loco_icon("name") — the component and the Hero module are removed.
  4. Fold variant: / library: into the icon tokenloco_icon("bolt", variant: :solid) becomes loco_icon("bolt/solid"), and icon_options: { variant: :solid } becomes icon: "name/solid". Passing variant: or library: now raises an ArgumentError. The Dock section's icon_variant: option is likewise replaced by the token form (icon: "home/solid").

Component icon: options work with zero setup for the bundled set (the chrome icons plus the standard Alert icons); anything else needs the one-time sync from step 1.

Read the full icon migration guide

Behavior change 4. Checkboxes and toggles now submit an unchecked value

A named, enabled daisy_checkbox / daisy_toggle now renders a companion <input type="hidden" value="0"> before the checkbox — the same trick as Rails' own check_box — so an unchecked box still submits a value and "uncheck to disable" forms work without hand-rolled hidden_field_tag pairs.

If you already added your own hidden field (or your controller expects the parameter to be absent), opt out with include_hidden: false, or change the submitted value with unchecked_value:. Request specs and system tests that assert the exact rendered markup or posted params may need updating.

No action needed 5. New in 0.7.0

Everything below ships in 0.7.0 and works without any changes to your app — click through to each component's examples.

Upgrade checklist

These are real daisy_checkbox components — and per step 4, unchecking one would now submit a 0 😉

Made with by Profoundry .
Copyright © 2023-2026 Profoundry LLC.
All rights reserved.