Bh · Bootstrap Helpers
Bootstrap 6 in a Rails app, with the markup already written.
Every component, drawn and explained →
Bootstrap is a fine framework that asks for a lot of HTML. Bh answers with a form builder that dresses every field a page can ask for, helpers for the components Bootstrap ships behavior for and no markup — a combobox, a 6-digit code, a dialog, a toast, a thread of messages — and the one stylesheet and one script that carry them, served by the engine.
How to install
gem install bh
# Gemfile
gem 'bh', '~> 6.3.0'
~> 6.3.0 stops short of 6.4, and that is the pin to hold: until this line settles it
breaks on a minor, not on a major. Rails 8.1 and Ruby 3.2 are the minimum.
6.2.0 breaks everything before it and keeps its major anyway. 6.0 through 6.1.4 were an alpha in everything but the number — Bootstrap 3 wrappers with a Bootstrap 6 stopgap bolted on, cut while Bootstrap 6 was itself pre-release — so there was no settled API to break. Those numbers are taken and cannot be withdrawn, RubyGems keeping anything published over thirty days ago, so this release steps over them.
With the gem in the bundle an app serves /bh/css/bh.css and /bh/js/bh.js itself. One helper
puts both in the head, along with everything Bootstrap and Turbo read:
<%= bh_head_tags %>
The palettes
Nine of them, served at /bh/theme/<name>.css and linked one at a time, after the stylesheet:
bootstrap, dawn, dracula, gruvbox, monokai, nord, one_dark, solarized,
tokyo_night. Each restates all thirteen steps of every Bootstrap family it repaints, plus
--bs-white, --bs-black and the three text tones. Every accent clears 3:1 against its label
and every text tone 4:1, in both modes.
bootstrap declares nothing: upstream's palette comes back by dropping the others' block
rather than by writing one, and it is named so a toggle can reach it — a reader who rotates
through nine and never finds the one the pages started in has been shown a door with no handle
on the inside.
The scheme controller does the swapping, and the choice belongs to the reader:
<button type='button' data-controller='scheme' data-action='scheme#rotate'
data-scheme-themes-value='["bootstrap","dawn","dracula","gruvbox","monokai","nord","one_dark","solarized","tokyo_night"]'
data-scheme-path-value='/bh/theme' data-scheme-storage-value='scheme'>
Another palette
</button>
A click moves to another palette and into the mode it is not in. Put the stored choice back before the first paint, from the layout's own script: a controller connects far too late for that, and the page would otherwise flash the palette the server chose.
What you get
class ApplicationController < ActionController::Base
default_form_builder Bh::FormBuilder
end
fieldset label submit button |
the form's furniture, with the pill Bootstrap draws |
every *_field, text_area, select, check |
dressed at one size, so a view says which kind and nothing about how it looks |
phone_field |
a North American number, shaped 555-555-5555 as it is typed |
pin_field |
one real field drawn as six slots, offered by the phone from the text that brought it |
combobox |
a <select> drawn as a searchable menu, still the one thing the form submits |
dialog |
a link and the <dialog> it opens, sharing an id made from the link's own words |
notices |
the flash as toasts, held while they are read |
chat_with |
a thread of bubbles, and the field that posts the next one |
flow |
the page of a signup flow: a header, a title, one card, a footer |
| 22 Stimulus controllers | registered by the bundle, called by data-controller |
| 9 palettes | served at /bh/theme/, swapped by the scheme controller |
The page above draws every one of them beside the line of Ruby that produces it.
Trying it out
The gem carries a dummy app drawing every helper on one page, and a bin/rails at the root, so
there is no cd first. From the root of a clone:
bin/setup
rails s
localhost:3000 is every component at once, ?flash=1 adds the toasts, and /flow is the
signup page.
Elsewhere
- The page — every component, and how to reach it
- API reference — built from what RubyGems holds
- CHANGELOG — what each release is, and which of the three it is
MIT licensed. Drawn for houseaccount by the Earl of Bubblehum.
