Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
3881cea
Implement Bootstrap 6 form markup
pardeyke Jul 2, 2026
fe56c0a
Add datepicker_field helper for the Bootstrap 6 datepicker
pardeyke Jul 2, 2026
4a5395f
Document selected_dates option for datepicker_field
pardeyke Jul 2, 2026
a2d3ca6
Use Bootstrap 6 form-field as the default form group wrapper
pardeyke Jul 2, 2026
52aec39
Add combobox helper for the Bootstrap 6 combobox component
pardeyke Jul 2, 2026
c426c7a
Complete Bootstrap 6 forms coverage: adorn, OTP, strength, validation
pardeyke Jul 3, 2026
7675c89
update demo app ruby to 4.0.7
pardeyke Oct 15, 2026
449dd2d
Update demo app to Rails 8.1
pardeyke Oct 15, 2026
560a094
Remove Webpacker leftovers from the demo app
pardeyke Oct 15, 2026
363c5b7
Load Bootstrap 6.0.0-alpha.1 in the demo app
pardeyke Oct 15, 2026
7ed5201
Update the demo app's remaining npm packages
pardeyke Oct 15, 2026
292d196
use bootstarp classes over custom css
pardeyke Oct 15, 2026
011023c
Cover every Bootstrap 6 forms docs page in the demo app
pardeyke Oct 15, 2026
f24a95a
Fix combobox ids in forms with a namespace
pardeyke Oct 15, 2026
232bee3
Give the collection checkboxes hidden field no id
pardeyke Oct 15, 2026
f062917
Honour the id option on collection checkboxes and radios
pardeyke Oct 15, 2026
c7160a6
Link help text to its control with aria-describedby
pardeyke Oct 15, 2026
dce9b0f
Add chip_input helper for the Bootstrap 6 chips component
pardeyke Oct 15, 2026
9349543
Allow classes and attributes on the switch wrapper
pardeyke Oct 15, 2026
dd12c17
Add range option for wrapper classes and the value bubble
pardeyke Oct 15, 2026
e4bdc7c
Extend the combobox helper to cover the Bootstrap 6 docs
pardeyke Oct 15, 2026
3022768
Add inline and button-trigger datepickers
pardeyke Oct 15, 2026
e3db966
Support static password strength levels
pardeyke Oct 15, 2026
309d3be
Nest floating labels inside input groups like Bootstrap 6
pardeyke Oct 15, 2026
3c0be5a
Add static validation feedback, tooltips and the valid state
pardeyke Oct 16, 2026
b64b410
Render adorned fields with a label wrapper like Bootstrap 6
pardeyke Oct 16, 2026
4b8295e
Add card option for checks and radios; drop dangling group label for
pardeyke Oct 16, 2026
dcf6225
Keep static strength meters and inline datepickers working with Boots…
pardeyke Oct 16, 2026
404bbe4
Exercise the demo's Bootstrap 6 components in a system test
pardeyke Oct 16, 2026
4ca7bd8
Tidy the demo component test and layout tweaks
pardeyke Oct 16, 2026
02dc0ab
Keep help text and feedback outside the form-floating wrapper
pardeyke Oct 16, 2026
39ae945
Regenerate README examples and demo screenshots
pardeyke Oct 16, 2026
3bed735
Load the gem's stylesheet in the demo via Sass @use
pardeyke Oct 16, 2026
c996413
Update sass to 1.105.2 in the demo
pardeyke Oct 16, 2026
c9249b6
save a line of code
pardeyke Oct 16, 2026
1fc4434
Load the Trix stylesheet in the demo
pardeyke Oct 16, 2026
f95c4cf
Use the generated actiontext.css in the demo
pardeyke Oct 16, 2026
635da1c
Run the demo's compiled CSS through PostCSS to prefix Bootstrap's var…
pardeyke Oct 16, 2026
b2b569b
Fix RuboCop offences
pardeyke Oct 16, 2026
cf61e37
Add changelog entry and Bootstrap 6 install notes to the README
pardeyke Oct 16, 2026
d97b024
Make the gem tests pass on Rails 7.2 and 8.0
pardeyke Oct 16, 2026
d182aac
Expect the Bootstrap 6 alert class in the error summary test
pardeyke Oct 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ demo/public/assets

# Ignore master key for decrypting credentials and more.
demo/config/master.key
demo/public/packs
demo/public/packs-test
demo/app/assets/builds/*
!demo/app/assets/builds/.keep
demo/node_modules
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ The tooling to support our old way of doing the change log doesn't work anymore,

### Breaking changes

* Target Bootstrap 6: generate the Bootstrap 6 form markup (`form-field` wrappers, `check`/`radio`/`switch` classes, `form-range` wrappers, floating labels and adornments) and add helpers for the new combobox, datepicker, chips, OTP and password strength components. Requires Bootstrap 6 CSS and JavaScript - [@pardeyke](https://github.com/pardeyke).
* [#618](https://github.com/bootstrap-ruby/bootstrap_form/pull/618): Allow overriding the wrapper class - [@donv](https://github.com/donv).
* Your contribution here!

Expand Down
1,382 changes: 1,077 additions & 305 deletions README.md

Large diffs are not rendered by default.

131 changes: 131 additions & 0 deletions UPGRADE-6.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Upgrading to `bootstrap_form` 6.0

`bootstrap_form` 6.0 generates mark-up for Bootstrap 6. Bootstrap 6 renames and restructures many of the form-related classes, so the mark-up generated by this gem changes accordingly. If your application styles or scripts against the generated mark-up, or if you pass Bootstrap utility classes to the helpers, you will need to make changes.

## Bootstrap 6 Changes

Upgrading `bootstrap_form` to version 6 means you must upgrade your whole application to Bootstrap 6. Read the [Bootstrap 6 migration guide](https://github.com/twbs/bootstrap/blob/v6-dev/skills/bootstrap-v5-v6-migration/SKILL.md) and the [Bootstrap 6 forms documentation](https://v6-dev--twbs-bootstrap.netlify.app/docs/6.0/forms/overview/) to see what changes you have to make to your views.

## Changes to Generated Mark-up

### Form Group Wrappers

Bootstrap 6 introduces the [`form-field` wrapper](https://v6-dev--twbs-bootstrap.netlify.app/docs/6.0/forms/field/), a CSS-grid container that lays out a control together with its label, help text, and validation feedback. `bootstrap_form` now uses it as the default form group wrapper:

- Vertical form groups are wrapped in `class="form-field mb-3"` (was `class="mb-3"`).
- Collections rendered with `group_around_collections = true` are wrapped in `class="form-group mb-3"`, Bootstrap 6's wrapper for multiple `form-field`s under a shared label.
- Horizontal groups (`mb-3 row`), inline groups, and floating label groups (`mb-3 form-floating`) are unchanged, because they use Bootstrap's grid or the `form-floating` component for layout instead.
- A custom `wrapper_class`/`wrapper: { class: ... }` still *replaces* the default classes. Include `form-field` in your custom class if you want to keep Bootstrap 6's field layout.

### Help Text

Help text is now rendered as `<small class="form-text">` without the `text-muted` class. Bootstrap 6 removes `text-muted` (its replacement is `fg-secondary`), and `form-text` styles itself.

### Selects

Bootstrap 6 styles `<select>` elements with `.form-control` instead of `.form-select`. All select helpers (`select`, `collection_select`, `grouped_collection_select`, `time_zone_select`, and the date/time select helpers) now generate `class="form-control"`.

### Checkboxes and Radio Buttons

Bootstrap 6 replaces the `.form-check` component with the `.form-field` wrapper and dedicated control classes:

- The wrapper `<div>` is now `class="form-field"` instead of `class="form-check"`.
- Checkbox inputs get `class="check"` instead of `class="form-check-input"`.
- Radio inputs get `class="radio"` instead of `class="form-check-input"`.
- Labels no longer get the `form-check-label` class (a plain `<label>` is used).
- Inline checks (`inline: true`) use the `d-inline-grid me-3` utilities on the wrapper instead of `form-check-inline`, since Bootstrap 6 has no dedicated inline class.

### Switches

Bootstrap 6 gives switches their own structure. `check_box ..., switch: true` now generates:

```html
<div class="form-field mb-3">
<div class="switch">
<input name="user[remember_me]" type="hidden" value="0">
<input id="user_remember_me" name="user[remember_me]" role="switch" switch="switch" type="checkbox" value="1">
</div>
<label for="user_remember_me">Remember me</label>
</div>
```

instead of the v5 `form-check form-switch` wrapper with a `form-check-input` class.

### Range Fields

Bootstrap 6 wraps range inputs in a component element. `range_field` now generates:

```html
<div class="form-range">
<input class="form-range-input" ... type="range">
</div>
```

instead of a bare `<input class="form-range">`.

### Floating Labels

Bootstrap 6 requires the `<label>` to come *before* the control inside `.form-floating` (the CSS relies on `:has()`). `bootstrap_form` now renders floating labels before the field instead of after it.

### Buttons

Bootstrap 6 removes the `.btn` base class and single-class color variants in favour of composed style + theme classes:

- `submit` and `button` default to `class="btn-solid theme-secondary"` (was `btn btn-secondary`).
- `primary` defaults to `class="btn-solid theme-primary"` (was `btn btn-primary`).

If you pass your own `class:` to these helpers, update it to the new Bootstrap 6 button classes yourself.

### Horizontal Forms and Grid Classes

Bootstrap 6 changes responsive class syntax from suffix to prefix: `.col-sm-2` becomes `.sm:col-2`, `.offset-sm-2` becomes `.sm:offset-2`.

- The default `label_col` is now `"sm:col-2"` (was `"col-sm-2"`).
- The default `control_col` is now `"sm:col-10"` (was `"col-sm-10"`).
- If you pass custom `label_col`/`control_col` values, use the new syntax; the automatic offset calculation for label-less groups understands only the new syntax (e.g. `sm:col-2` → `sm:offset-2`).
- Inline layout labels get `class="form-label sm:me-2"` (was `form-label me-sm-2`).

### Validation Feedback Placement

Bootstrap 6 changes where validation feedback lives:

- For checkboxes, radios, and switches, the label and the `invalid-feedback` element (and any help text) are now nested in a `form-field-content` wrapper next to the control, keeping them aligned in the `form-field` grid.
- For fields with `prepend`/`append` add-ons, the `invalid-feedback` element is now rendered *outside* the `input-group`, as a sibling within the `form-field` wrapper (it was inside the input group in v5).

### Input Group Buttons

Bootstrap 6 requires the `input-group-btn` class on buttons inside input groups. `bootstrap_form` passes your `prepend`/`append` content through as-is, so add the class to buttons you pass in, e.g. `link_to("Go", "#", class: "btn-solid theme-secondary input-group-btn")`.

### Alerts

`alert_message` now defaults to `class="alert theme-danger"` instead of `class="alert alert-danger"`, following Bootstrap 6's composed theme classes. Pass `class: "alert alert-danger"` explicitly if you need the old mark-up.

## New Features

### Datepicker Helper

Bootstrap 6 introduces a datepicker component. The new `datepicker_field` helper generates a text field with `data-bs-toggle="datepicker"` and renders the `:datepicker` option hash as `data-bs-*` configuration attributes. See the README for details.

### Combobox Helper

Bootstrap 6 introduces a combobox component — a select-like control with optional search and multiple selection that replaces third-party plugins such as `use-bootstrap-select`. The new `combobox` helper generates the full mark-up (toggle button, menu items, pre-selected state) from a choices collection. See the README for details.

### Adorned Fields

The new `adorn` option on text-style field helpers generates Bootstrap 6's `form-adorn` mark-up: an icon or text decoration inside the field's border, with the input rendered as a `form-ghost`. See the README for details.

### OTP Input Helper

The new `otp_field` helper generates Bootstrap 6's OTP input: a single text input inside a `.otp[data-bs-otp]` container, rendered as digit slots by Bootstrap's JavaScript. The `:otp` option hash is rendered as `data-bs-*` configuration attributes.

### Password Strength Meters

The new `strength` option on `password_field` renders Bootstrap 6's password strength meter (segmented or bar variant, with optional text feedback and minimum length) after the input.

### Client-Side Validation

Pass `validate: true` (or `validate: "valid"` for success styling) to the form helpers to emit Bootstrap 6's `data-bs-validate` attribute and `novalidate` on the `<form>`.

## Unchanged

The following classes are unchanged in Bootstrap 6 and continue to be generated as before: `form-label`, `form-text` (now without `text-muted`), `form-control` (and its `-sm`/`-lg`/`-color`/`-plaintext` variants), `form-floating`, `input-group`, `input-group-text`, `col-form-label`, `is-invalid`/`is-valid`, `invalid-feedback`/`valid-feedback`, and `visually-hidden`.
3 changes: 0 additions & 3 deletions demo/.postcssrc.yml

This file was deleted.

2 changes: 1 addition & 1 deletion demo/.ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ruby-3.2.7
4.0.7
2 changes: 1 addition & 1 deletion demo/Procfile.dev
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
web: bin/rails server -b 0.0.0.0
js: yarn build --watch
css: yarn build:css --watch
css: yarn watch:css
2 changes: 1 addition & 1 deletion demo/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# DEMO APP (Rails 7.0)
# DEMO APP (Rails 8.1)

### Usage

Expand Down
9 changes: 0 additions & 9 deletions demo/app/assets/builds/application.js.LICENSE.txt

This file was deleted.

Loading
Loading