From 80381692088f51cb816c244371b01c15ba82c66d Mon Sep 17 00:00:00 2001 From: "Mark H. Wilkinson" Date: Fri, 21 May 2021 10:02:40 +0100 Subject: [PATCH] Bootstrap 5 updates (#329) * Update bootstrap dependency to 5.0.0.beta2 * .custom-* styles merged in to native ones * Use map-merge to add custom colors to theme * Update header markup * Breadcrumbs have no padding now * data-toggle and data-target get 'bs-' prefix * data-placement gets 'bs-' prefix; drop data-trigger * Drop top margin; update horizontal margin * Rework stack/split button group * Hide toggle buttons below medium breakpoint * data-dismiss gets 'bs-' prefix on modal * Use bootstrap's close button on modal * .form-text now subsumes and .text-muted * Drop .form-group-{invalid,valid} They aren't used by bootstrap and .form-group has gone in v5 as well. * verticals: .form-group -> .mb-3 * verticals: labels need .form-label * verticals: .form-control-file -> .form-control * verticals: .form-control -> .form-select Also add :vertical_select wrapper for `` element is added between the `` and first `
` wrapping a radio button. Bootstrap's styling floats the legend left and needs the following element to be cleared, but this does not work if the following element is not displayed. We add an additional rule to target the first following wrapper `
`. * Rework event handling for stack/split toggle .active has gone; check for .btn so we only process events from the input elements, not the labels. Don't preventDefault() on the event, so the radio button will toggle. * Get stack/split state from radio buttons * horizontals: .form-group -> .mb-3 * horizontals: .form-control-file -> .form-control * horizontals: .form-control -> .form-select As for horizontals, add :horizontal_select wrapper for `` example Not supported by Bootstrap 5's floating labels implementation. * floating_labels: .custom-select -> .form-select * floating_labels: docs recommend against rows="" * input_groups: add .has-validation, move feedback New .has-validation class was added so validation feedback can move inside input-group. This works ok for simple_form, but the plain HTML version with both .valid-feedback and .invalid-feedback divs loses the rounded end on the input group. See https://github.com/twbs/bootstrap/issues/25110 * remove .d-block where it is not needed * fix inclusion of stylesheets in documentation * Update version number on home page * Replace .media and .media-body * `div` is the default for `tag` in wrappers * Update bootstrap dependency to 5.0.0 * Add `offcanvas` to `application.scss` * Bump bootstrap rubygem to v5.0.1 Co-authored-by: m5o --- Gemfile | 2 +- Gemfile.lock | 14 +- app/assets/images/custom.png | Bin 2041 -> 0 bytes app/assets/javascripts/password_controller.js | 8 +- app/assets/javascripts/toggle_controller.js | 10 +- app/assets/stylesheets/application.scss | 55 ++- .../stylesheets/application/_breadcrumb.scss | 4 +- .../_form_collection_label.scss | 24 - .../_form_floating_labels.scss | 106 ----- .../_form_legend_clear.scss | 10 + .../_form_multi_select.scss | 11 +- .../_simple_form-bootstrap.scss | 2 +- app/controllers/examples/base_controller.rb | 2 +- .../examples/customs_controller.rb | 15 - app/helpers/error_messages_helper.rb | 10 +- app/views/application/_breadcrumb.html.erb | 17 +- app/views/application/_flash.html.erb | 8 +- app/views/application/_header.html.erb | 16 +- app/views/application/_jumbotron.html.erb | 2 +- app/views/documentation/index.html.erb | 2 +- .../examples/base/_card_bootstrap.html.erb | 2 +- .../examples/base/_card_simple_form.html.erb | 2 +- .../examples/customs/_bootstrap.html.erb | 415 ------------------ app/views/examples/customs/_form.html.erb | 46 -- app/views/examples/customs/new.html.erb | 21 - .../floating_labels/_bootstrap.html.erb | 38 +- .../examples/floating_labels/_form.html.erb | 2 - .../examples/horizontals/_bootstrap.html.erb | 104 ++--- app/views/examples/horizontals/_form.html.erb | 5 +- .../examples/inlines/_bootstrap.html.erb | 38 +- app/views/examples/inlines/_form.html.erb | 10 +- .../examples/input_groups/_bootstrap.html.erb | 68 ++- .../examples/verticals/_bootstrap.html.erb | 124 +++--- app/views/shared/_modal.html.erb | 6 +- config/initializers/simple_form_bootstrap.rb | 301 +++++-------- config/locales/en.yml | 4 - config/routes.rb | 1 - lib/components/input_group_component.rb | 6 +- test/helpers/error_messages_helper_test.rb | 2 +- .../custom_fields_test.rb | 193 -------- .../simple_form-bootstrap/date_fields_test.rb | 34 +- .../fields_with_errors_test.rb | 6 +- .../floating_labels_test.rb | 34 +- .../horizontal_form_test.rb | 84 ++-- .../simple_form-bootstrap/inline_form_test.rb | 26 +- .../simple_form-bootstrap/input_group_test.rb | 40 +- .../vertical_form_test.rb | 94 ++-- 47 files changed, 564 insertions(+), 1460 deletions(-) delete mode 100644 app/assets/images/custom.png delete mode 100644 app/assets/stylesheets/simple_form-bootstrap/_form_floating_labels.scss create mode 100644 app/assets/stylesheets/simple_form-bootstrap/_form_legend_clear.scss delete mode 100644 app/controllers/examples/customs_controller.rb delete mode 100644 app/views/examples/customs/_bootstrap.html.erb delete mode 100644 app/views/examples/customs/_form.html.erb delete mode 100644 app/views/examples/customs/new.html.erb delete mode 100644 test/simple_form-bootstrap/custom_fields_test.rb diff --git a/Gemfile b/Gemfile index a4853dc9..ca9375ed 100644 --- a/Gemfile +++ b/Gemfile @@ -57,7 +57,7 @@ gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] # Custom -gem 'bootstrap', '~> 4.6.0' +gem 'bootstrap', '~> 5.0.1' gem 'inline_svg', '~> 1.7' gem 'jquery-rails' gem 'kramdown', '~> 2.3' diff --git a/Gemfile.lock b/Gemfile.lock index 4484807f..405204eb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -62,14 +62,14 @@ GEM zeitwerk (~> 2.3) addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) - autoprefixer-rails (10.2.0.0) - execjs + autoprefixer-rails (10.2.5.0) + execjs (< 2.8.0) bindex (0.8.1) bootsnap (1.7.2) msgpack (~> 1.0) - bootstrap (4.6.0) + bootstrap (5.0.1) autoprefixer-rails (>= 9.1.0) - popper_js (>= 1.14.3, < 2) + popper_js (>= 2.9.2, < 3) sassc-rails (>= 2.0.0) builder (3.2.4) byebug (11.1.3) @@ -89,7 +89,7 @@ GEM nokogiri (>= 1.4.3) erubi (1.10.0) execjs (2.7.0) - ffi (1.14.2) + ffi (1.15.0) globalid (0.4.2) activesupport (>= 4.2.0) i18n (1.8.10) @@ -126,7 +126,7 @@ GEM mini_portile2 (~> 2.5.0) racc (~> 1.4) pg (1.2.3) - popper_js (1.16.0) + popper_js (2.9.2) public_suffix (4.0.6) puma (5.3.1) nio4r (~> 2.0) @@ -229,7 +229,7 @@ PLATFORMS DEPENDENCIES bootsnap (>= 1.4.4) - bootstrap (~> 4.6.0) + bootstrap (~> 5.0.1) byebug capybara (>= 3.26) diffy diff --git a/app/assets/images/custom.png b/app/assets/images/custom.png deleted file mode 100644 index e7dad6d60d56bd02bd5f49e71d8551337d7cade7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2041 zcmZ8i4Lp-;8=p=mvlZK^q)zIfbdp#kv5;Bw5$0n!Az6os=4(bild~;*r&_&hqREJS zoJP||#fHt{_*yCDh*l{PjvVPs`FtPWe(&%4J-_FA?)$p$>$>m%|N1}wadEcY0NDls zfj}GV?a*!@kdhR59KhcJBae39oBP=0;)px8FSge{t)E=*xBtzdn4;ly(I`VWQqVAV zUp8h>VB$ir2Aun^_vPodUZEytmd3`$*6zfUtT(s|VoOIn#-CEzu85!)n;|Wkf)9RS z7m10i-x%x|%5^;DzHefo&52k?;?2WW4v{%MNQ{Tq#YP(!y!|hs*r)>6Aevv)HPQtZ z+67NYtMLfC`n2b3Sy|ca?5tcaZ>r>%mX_Wtmp<*1pU0ROA0gao>~0rb53(^aHuJnt z(()1rlD}#f-3asar-B5+ z&5mfc1fSMGAQ14E8tM5hbUHmVGZW8{;u(LW<~Gm;Bl-1X(oV(HrLtZSXkCsy+8P(D zG%Qagbz?Sy{C)ZxPVY!d@G{Kzov{*+zrMbsfBKD%@TeqXtwDqx4LQ>hsvNZzG0_*s ztIv*j7n#L-GStr2rQ8kj3pRQfFNqj`^v{p`bu{aXuMd8n_(En$*avTg&CMXj<62D_ zFf9}n4A(}}=bckAQdZ%WcaE9tZ>)BK(>kvwi4{$69nKpxCS_Yhx0;5id)qAsFF6q6 zoTZ4o{@S@~lxB4=`Pts#V#zR$5z~E)^WjAMkIN5SA|? zB>DIAu%0M*%!6jd9;$UWx8nCqwY%_;rq*vN)8g1tt0*Z3iBEMhY#`^cKt!geRZ*=XaTqHQnlQ|vg11}Mr^fYNNDHn zP~TUK&g|OR5Rfbi&?G+D!K)>x10fpa(<-@&!upMXUj(=(tHBn&C6V@?q$Y90+xuO)FfYBT}z0 zVIkiyWPuRz9hKvxJ zuK{tqmsOdh{QbAVXBA-u+k?}7mfjR|_S$x7Gx!7`Bo_$L9}he9lknJc)6HObLvoYk zHaP99eimZtxaz8^B61Ti_=NRPYs z8fZy{qc3p?z1$ny$<;G`obc-DKE!8M`1?=EiCnC+xcBHJtDgpjr_V8XL17*$TRWlXAB}dB~qrhY4L!m&Y?m!DV34lGXsFXSt*dS2Z21=5Fc< z;>V>Gr8=#KfViNA5TZ%(8XpQSMTS}t$$wHQaep$|L(>Om1v*ocJrw1!E0pGcRX;sJ zs;19np+bnzpLo9EN`OPirI96bwN5>X6lwGrVlN|BOJsbLWDR)VUp^q<%o(&L`D|lB zuzIjXDCQbf7O6fHj~Mw{LK45}PmX~WhaOm6Et(#&g9@Hrf5>XSlU6WXRP;HiT}8u{ z+e>i*OorN)zC5(#JalW=xvxAfX@cMMb}(}%Ag!|5^(3wua}pZ=&d{L7?CM8V(H-EI O4zfSyj4nm_|Mov5aFSX8 diff --git a/app/assets/javascripts/password_controller.js b/app/assets/javascripts/password_controller.js index c7221919..a1939aa0 100644 --- a/app/assets/javascripts/password_controller.js +++ b/app/assets/javascripts/password_controller.js @@ -1,8 +1,8 @@ $(document).ready(function() { 'use strict'; - var $bootstrap = $('#exampleInputPassword').next('.input-group-append'); - var $simple_form = $('#user_password').next('.input-group-append'); + var $bootstrap = $("#exampleInputPassword").next(".input-group-text"); + var $simple_form = $("#user_password").next(".input-group-text"); var $pw_appends = $bootstrap.add($simple_form); @@ -11,10 +11,10 @@ $(document).ready(function() { $(this).toggleClass('active'); if ( $(this).hasClass('active') ) { $(this).prev().prop("type", "text"); - $(this).find('.input-group-text').html("🙈"); + $(this).text("🙈"); } else { $(this).prev().prop("type", "password"); - $(this).find('.input-group-text').html("🙊"); + $(this).text("🙊"); } $(this).prev().focus(); }); diff --git a/app/assets/javascripts/toggle_controller.js b/app/assets/javascripts/toggle_controller.js index 9ef1a81b..9938f770 100644 --- a/app/assets/javascripts/toggle_controller.js +++ b/app/assets/javascripts/toggle_controller.js @@ -2,8 +2,8 @@ $(document).ready(function() { 'use strict'; var $grid_target = $('[data-target="toggle.grid"]'); - var $button = $('[data-toggle="button"]'); - var $buttons = $('[data-toggle="buttons"]'); + var $button = $('[data-bs-toggle="button"]'); + var $buttons = $('[data-bs-toggle="buttons"]'); // init if ( $grid_target.length >= 2 ) { @@ -18,9 +18,9 @@ $(document).ready(function() { // stack / split view $buttons.click(function(event) { - event.preventDefault(); - if ( $(event.target).hasClass("active") ) { return } - $grid_target.toggleClass("col-md-12"); + if ( $(event.target).hasClass("btn") ) { return; } + var stack = $buttons.find(":checked").attr("id") === "stack"; + $grid_target.toggleClass("col-md-12", stack); }); // swap by press "s" diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index baf024db..52197bf5 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -1,5 +1,56 @@ -$theme-colors: ( "bootstrap": #563d7c, "simpleform": #00617f ); -@import "bootstrap"; +/* + * Keep in sync with `assets/stylesheets/_bootstrap.scss` from + * `bootstrap-rubygem`. + */ + +@import "bootstrap/functions"; + +$custom-colors: ( "bootstrap": #563d7c, "simpleform": #00617f ); + +@import "bootstrap/variables"; +@import "bootstrap/mixins"; + +$theme-colors: map-merge($theme-colors, $custom-colors); + +@import "bootstrap/utilities"; + +// Layout & components +@import "bootstrap/root"; +@import "bootstrap/reboot"; +@import "bootstrap/type"; +@import "bootstrap/images"; +@import "bootstrap/containers"; +@import "bootstrap/grid"; +@import "bootstrap/tables"; +@import "bootstrap/forms"; +@import "bootstrap/buttons"; +@import "bootstrap/transitions"; +@import "bootstrap/dropdown"; +@import "bootstrap/button-group"; +@import "bootstrap/nav"; +@import "bootstrap/navbar"; +@import "bootstrap/card"; +@import "bootstrap/accordion"; +@import "bootstrap/breadcrumb"; +@import "bootstrap/pagination"; +@import "bootstrap/badge"; +@import "bootstrap/alert"; +@import "bootstrap/progress"; +@import "bootstrap/list-group"; +@import "bootstrap/close"; +@import "bootstrap/toasts"; +@import "bootstrap/modal"; +@import "bootstrap/tooltip"; +@import "bootstrap/popover"; +@import "bootstrap/carousel"; +@import "bootstrap/spinners"; +@import "bootstrap/offcanvas"; + +// Helpers +@import "bootstrap/helpers"; + +// Utilities +@import "bootstrap/utilities/api"; // App sections @import "application/breadcrumb"; diff --git a/app/assets/stylesheets/application/_breadcrumb.scss b/app/assets/stylesheets/application/_breadcrumb.scss index b205ea40..07e05a9f 100644 --- a/app/assets/stylesheets/application/_breadcrumb.scss +++ b/app/assets/stylesheets/application/_breadcrumb.scss @@ -1,6 +1,6 @@ .app-breadcrumb { - [data-toggle] { - @include media-breakpoint-down(sm) { + [data-bs-toggle] { + @include media-breakpoint-down(md) { & { display: none; } } } diff --git a/app/assets/stylesheets/simple_form-bootstrap/_form_collection_label.scss b/app/assets/stylesheets/simple_form-bootstrap/_form_collection_label.scss index c9bbcca8..26222836 100644 --- a/app/assets/stylesheets/simple_form-bootstrap/_form_collection_label.scss +++ b/app/assets/stylesheets/simple_form-bootstrap/_form_collection_label.scss @@ -7,27 +7,3 @@ } } } - -// optional custom form spacing -.custom-control-inline { - .custom-control-label { - &.collection_check_boxes, - &.collection_radio_buttons { - margin-right: .265625rem; - } - } -} - -// required custom form radio button fix -.form-group.radio_buttons { - > .custom-control { - @extend .custom-radio; - } -} - -// required custom form check box fix -.form-group.check_boxes { - > .custom-control { - @extend .custom-checkbox; - } -} diff --git a/app/assets/stylesheets/simple_form-bootstrap/_form_floating_labels.scss b/app/assets/stylesheets/simple_form-bootstrap/_form_floating_labels.scss deleted file mode 100644 index 5484b923..00000000 --- a/app/assets/stylesheets/simple_form-bootstrap/_form_floating_labels.scss +++ /dev/null @@ -1,106 +0,0 @@ -// extracted from: -// https://getbootstrap.com/docs/4.3/examples/floating-labels/ - -$sf-floating-input-padding-x: $input-padding-x !default; -$sf-floating-input-padding-y: $input-padding-y * 2 !default; - -.form-label-group { - position: relative; - margin-bottom: 1rem; -} - -.form-label-group > input, -.form-label-group > .custom-select:not([multiple]) { - height: 3.125rem; -} - -.form-label-group > textarea, -.form-label-group > input, -.form-label-group > select, -.form-label-group > label { - padding: $sf-floating-input-padding-y $sf-floating-input-padding-x; -} - -.form-label-group { - > label { - position: absolute; - top: 0; - left: 0; - display: block; - width: 100%; - margin-bottom: 0; /* Override default `