shoelace-rails 0.4.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +11 -61
  3. data/.gitignore +1 -6
  4. data/Appraisals +6 -0
  5. data/CHANGELOG.md +22 -5
  6. data/Gemfile +0 -3
  7. data/Rakefile +2 -17
  8. data/app/helpers/shoelace/form_helper.rb +63 -14
  9. data/gemfiles/rails_60.gemfile +0 -1
  10. data/gemfiles/rails_61.gemfile +0 -1
  11. data/gemfiles/rails_70.gemfile +0 -1
  12. data/gemfiles/rails_71.gemfile +10 -0
  13. data/gemfiles/rails_edge.gemfile +0 -1
  14. data/lib/shoelace/rails/version.rb +1 -1
  15. data/shoelace-rails.gemspec +1 -1
  16. data/test/helpers/form_helper_test.rb +40 -11
  17. data/test/helpers/translation_test.rb +160 -0
  18. metadata +7 -58
  19. data/dist/.keep +0 -0
  20. data/dist/types/.keep +0 -0
  21. data/package.json +0 -50
  22. data/rollup.config.js +0 -49
  23. data/src/index.ts +0 -2
  24. data/src/turbo/index.ts +0 -6
  25. data/src/turbo/polyfills/formdata-event.js +0 -27
  26. data/src/turbo/sl-turbo-form.ts +0 -110
  27. data/src/turbolinks/features/confirm.ts +0 -42
  28. data/src/turbolinks/features/disable.ts +0 -94
  29. data/src/turbolinks/features/remote.ts +0 -107
  30. data/src/turbolinks/index.ts +0 -6
  31. data/src/turbolinks/selectors.ts +0 -38
  32. data/src/turbolinks/start.ts +0 -38
  33. data/src/turbolinks/turbolinks.ts +0 -78
  34. data/src/turbolinks/utils/ajax.ts +0 -146
  35. data/src/turbolinks/utils/csp.ts +0 -20
  36. data/src/turbolinks/utils/csrf.ts +0 -33
  37. data/src/turbolinks/utils/dom.ts +0 -40
  38. data/src/turbolinks/utils/event.ts +0 -57
  39. data/src/turbolinks/utils/form.ts +0 -58
  40. data/test/dummy_app/Gemfile +0 -19
  41. data/test/dummy_app/Rakefile +0 -6
  42. data/test/dummy_app/app/controllers/hotwire_forms_controller.rb +0 -46
  43. data/test/dummy_app/app/controllers/turbolinks_forms_controller.rb +0 -37
  44. data/test/dummy_app/app/models/user.rb +0 -16
  45. data/test/dummy_app/app/packs/entrypoints/hotwire.js +0 -1
  46. data/test/dummy_app/app/packs/entrypoints/turbolinks.js +0 -5
  47. data/test/dummy_app/app/views/hotwire_forms/form.html.erb +0 -45
  48. data/test/dummy_app/app/views/hotwire_forms/show.html.erb +0 -5
  49. data/test/dummy_app/app/views/layouts/application.html.erb +0 -39
  50. data/test/dummy_app/app/views/turbolinks_forms/form.html.erb +0 -44
  51. data/test/dummy_app/app/views/turbolinks_forms/show.html.erb +0 -5
  52. data/test/dummy_app/bin/rails +0 -5
  53. data/test/dummy_app/bin/webpack +0 -18
  54. data/test/dummy_app/bin/yarn +0 -18
  55. data/test/dummy_app/config/application.rb +0 -16
  56. data/test/dummy_app/config/boot.rb +0 -4
  57. data/test/dummy_app/config/environment.rb +0 -2
  58. data/test/dummy_app/config/environments/development.rb +0 -10
  59. data/test/dummy_app/config/environments/test.rb +0 -18
  60. data/test/dummy_app/config/routes.rb +0 -4
  61. data/test/dummy_app/config/webpack/development.js +0 -5
  62. data/test/dummy_app/config/webpack/production.js +0 -1
  63. data/test/dummy_app/config/webpack/test.js +0 -5
  64. data/test/dummy_app/config/webpacker.yml +0 -33
  65. data/test/dummy_app/config.ru +0 -6
  66. data/test/dummy_app/package.json +0 -24
  67. data/test/dummy_app/test/system/hotwire_form_test.rb +0 -63
  68. data/test/dummy_app/test/system/turbolinks_form_test.rb +0 -38
  69. data/test/dummy_app/test/test_helper.rb +0 -68
  70. data/tsconfig.json +0 -19
  71. data/yarn.lock +0 -249
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7a2dfd18c31e8151980211fe86c5911629f795652e2662315055695f31b7e2d6
4
- data.tar.gz: a2c224c7c8ba4fd199d9190d77e37246650753f9c76d29156c25b4754c65018b
3
+ metadata.gz: 206ca8361dedd910c96e3c13469e9bad996af7d2a91a0ca0af2cb8e1a7430808
4
+ data.tar.gz: 64df314d89557bd02dbf791bddcc49185017f5cb1d22c5046a23f1767df5bf18
5
5
  SHA512:
6
- metadata.gz: 8a78a2537a9851beb4f9d7e33214e51fbff8c3539cef0d244951b6ac36d7f0837a84129a8dfe36a46f8e7eec8f474e65b9a45078abde2a508b3a3b90f5322060
7
- data.tar.gz: 5a99554ecd05cd33ffbe41929984a82828961db94ac3f4a4c796e6685bff57c08afef96ed8d8c58e055edaada87e2e0be0ebc5761b870bec74164a476c7e36e6
6
+ metadata.gz: 284ca5c08643f593de6554d02bb8e4857d141c8a4ddc02def92e573a273a3b45694e2ce14783779fbafe83eea1b9cbc85fd80ba52f36dc235e11d5cec6e9f6b1
7
+ data.tar.gz: 22ca68a850b08eebb0ad6d8fd48a8a7b65a3a4647acd34171f04cac20eca635475147804194957efe75fb4aeef68741b4b65fc3f10edc214165b3eb51addefcb
@@ -9,6 +9,7 @@ jobs:
9
9
  strategy:
10
10
  matrix:
11
11
  ruby_version:
12
+ - '3.3'
12
13
  - '3.2'
13
14
  - '3.1'
14
15
  - '3.0'
@@ -16,17 +17,20 @@ jobs:
16
17
  - 'jruby-9.3'
17
18
  - 'jruby-9.4'
18
19
  gemfile:
20
+ - gemfiles/rails_71.gemfile
19
21
  - gemfiles/rails_70.gemfile
20
22
  - gemfiles/rails_61.gemfile
21
23
  - gemfiles/rails_60.gemfile
22
24
  exclude:
25
+ - ruby_version: 'jruby-9.3'
26
+ gemfile: gemfiles/rails_71.gemfile
23
27
  - ruby_version: 'jruby-9.3'
24
28
  gemfile: gemfiles/rails_70.gemfile
25
29
  runs-on: ubuntu-22.04
26
30
  env:
27
31
  BUNDLE_GEMFILE: ${{ matrix.gemfile }}
28
32
  steps:
29
- - uses: actions/checkout@v3
33
+ - uses: actions/checkout@v4
30
34
  - name: Set up Ruby
31
35
  uses: ruby/setup-ruby@v1
32
36
  with:
@@ -34,89 +38,35 @@ jobs:
34
38
  bundler-cache: true
35
39
  - run: bundle exec rake test
36
40
 
37
- system:
38
- needs: unit
39
- runs-on: ubuntu-22.04
40
- steps:
41
- - uses: actions/checkout@v3
42
- - name: Set up Ruby
43
- uses: ruby/setup-ruby@v1
44
- with:
45
- ruby-version: 3.2.0
46
- bundler-cache: true
47
- - name: Install dependencies
48
- run: |
49
- rm -rf node_modules &&
50
- yarn install &&
51
- yarn add tslib &&
52
- bundle
53
- - name: Run the system test in the dummy app
54
- run: rake test:system
55
-
56
41
  rails_edge:
57
- needs: system
42
+ needs: unit
58
43
  runs-on: ubuntu-22.04
59
44
  env:
60
45
  BUNDLE_GEMFILE: gemfiles/rails_edge.gemfile
61
46
  steps:
62
- - uses: actions/checkout@v3
47
+ - uses: actions/checkout@v4
63
48
  - name: Set up Ruby
64
49
  uses: ruby/setup-ruby@v1
65
50
  with:
66
- ruby-version: 3.1
51
+ ruby-version: 3.3
67
52
  bundler-cache: true
68
53
  - run: bundle exec rake test || echo "Rails edge test is done."
69
54
 
70
55
  ruby_edge:
71
- needs: system
56
+ needs: unit
72
57
  strategy:
73
58
  matrix:
74
59
  gemfile:
75
60
  - gemfiles/rails_edge.gemfile
76
- - gemfiles/rails_70.gemfile
61
+ - gemfiles/rails_71.gemfile
77
62
  runs-on: ubuntu-22.04
78
63
  env:
79
64
  BUNDLE_GEMFILE: ${{ matrix.gemfile }}
80
65
  steps:
81
- - uses: actions/checkout@v3
66
+ - uses: actions/checkout@v4
82
67
  - name: Set up Ruby
83
68
  uses: ruby/setup-ruby@v1
84
69
  with:
85
70
  ruby-version: 'ruby-head'
86
71
  bundler-cache: true
87
72
  - run: bundle exec rake || echo "Ruby edge test is done."
88
-
89
- # browser_tests:
90
- # runs-on: ubuntu-22.04
91
- # steps:
92
- # - uses: actions/checkout@v3
93
- # - name: Set up Ruby
94
- # uses: ruby/setup-ruby@v1
95
- # with:
96
- # ruby-version: 3.2.0
97
- # bundler-cache: true
98
- # - name: Install dependencies
99
- # run: |
100
- # rm -rf node_modules &&
101
- # yarn install &&
102
- # yarn add tslib &&
103
- # bundle
104
- # - name: 'BrowserStack Env Setup'
105
- # uses: 'browserstack/github-actions/setup-env@master'
106
- # with:
107
- # username: ${{ secrets.BROWSERSTACK_USERNAME }}
108
- # access-key: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
109
- # - name: 'Start BrowserStackLocal Tunnel'
110
- # uses: 'browserstack/github-actions/setup-local@master'
111
- # with:
112
- # local-testing: 'start'
113
- # local-logging-level: 'all-logs'
114
- # local-identifier: 'random'
115
- # - name: Run the system test in the dummy app
116
- # run: rake test:system
117
- # env:
118
- # BROWSERSTACK_URL: ${{ secrets.BROWSERSTACK_URL }}
119
- # - name: 'Stop BrowserStackLocal'
120
- # uses: 'browserstack/github-actions/setup-local@master'
121
- # with:
122
- # local-testing: 'stop'
data/.gitignore CHANGED
@@ -7,14 +7,9 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  Gemfile.lock
10
- node_modules
11
- dist
12
10
  .npmrc
13
11
 
14
- test/dummy_app/yarn.lock
15
- test/dummy_app/log/
16
- test/dummy_app/tmp/
17
- test/dummy_app/public/
18
12
  .pryrc
19
13
  gemfiles/*.lock
14
+ gemfiles/.bundle
20
15
  BrowserStackLocal
data/Appraisals CHANGED
@@ -6,6 +6,12 @@ appraise "rails_edge" do
6
6
  end
7
7
  end
8
8
 
9
+ appraise "rails_71" do
10
+ gem "rails", "~> 7.1.0"
11
+ gem "railties", "~> 7.1.0"
12
+ gem "activesupport", "~> 7.1.0"
13
+ end
14
+
9
15
  appraise "rails_70" do
10
16
  gem "rails", "~> 7.0.0"
11
17
  gem "railties", "~> 7.0.0"
data/CHANGELOG.md CHANGED
@@ -1,11 +1,28 @@
1
- ## v0.4.1
1
+ ## v0.6.0
2
2
 
3
- _<sup>released at 2023-03-21 05:01:50 UTC</sup>_
3
+ #### ⭐️ Features
4
+
5
+ - Add the ability to use translations with form helpers
6
+
7
+ ## [v0.5.0](https://github.com/yuki24/shoelace-rails/tree/v0.5.0)
8
+
9
+ _<sup>released at 2024-03-09 08:54:30 UTC</sup>_
10
+
11
+ #### ⭐️ Features
12
+
13
+ - Add support for Ruby 3.3 ([<tt>399f255</tt>](https://github.com/yuki24/shoelace-rails/commit/399f25567f964d0ea2e250eba6db28a2bcd038a3))
14
+ - Add support for Rails 7.1 ([#4](https://github.com/yuki24/shoelace-rails/pull/4))
15
+ - Add `#grouped_collection_select` ([<tt>2b91023</tt>](https://github.com/yuki24/shoelace-rails/commit/2b91023d51e1d0a218f2102232241afa82aaf872))
16
+ - Make the `<sl-radio>` form helpers compatible with Shoelace [2.0.0-beta.80](https://shoelace.style/resources/changelog#id_2_0_0-beta_80) and above ([<tt>ef9a834</tt>](https://github.com/yuki24/shoelace-rails/commit/ef9a8345f2c5c921847aef15e19cf64a471d6473))
17
+
18
+ ## [v0.4.1](https://github.com/yuki24/shoelace-rails/tree/v0.4.1)
19
+
20
+ _<sup>released at 2023-03-21 04:03:27 UTC</sup>_
4
21
 
5
22
  #### 🐞Bug Fixes
6
23
 
7
- - Fixes a bug where `FormHelper` may not be defined when someone loads `ActionView` too early (d91ed3b595c01ce2dfc471b12b14311e0660d3d7)
8
- - Fixes a bug where the Shoelace rake tasks blow up when the project does not depend on Sprockets or Propshaft (0e64cd6dc38a037171be04eaf1d3f59c3c8529eb, 75adf831b1faa7f5d1faeed26e672d4bc89b9513)
24
+ - Fixes a bug where `FormHelper` may not be defined when someone loads `ActionView` too early ([<tt>d91ed3b</tt>](https://github.com/yuki24/shoelace-rails/commit/d91ed3b595c01ce2dfc471b12b14311e0660d3d7))
25
+ - Fixes a bug where the Shoelace rake tasks blow up when the project does not depend on Sprockets or Propshaft ([<tt>0e64cd6</tt>](https://github.com/yuki24/shoelace-rails/commit/0e64cd6dc38a037171be04eaf1d3f59c3c8529eb), [<tt>75adf83</tt>](https://github.com/yuki24/shoelace-rails/commit/75adf831b1faa7f5d1faeed26e672d4bc89b9513))
9
26
 
10
27
  ## [v0.4.0](https://github.com/yuki24/shoelace-rails/tree/v0.4.0)
11
28
 
@@ -13,7 +30,7 @@ _<sup>released at 2023-01-07 07:23:50 UTC</sup>_
13
30
 
14
31
  #### 🚨 Breaking Changes
15
32
 
16
- - No longer works with `2.0.0-beta.88` and below.
33
+ - No longer works with `2.0.0-beta.87` and below.
17
34
 
18
35
  #### ⭐️ Features
19
36
 
data/Gemfile CHANGED
@@ -6,6 +6,3 @@ source "https://rubygems.org"
6
6
  gemspec
7
7
 
8
8
  gem "rake", "~> 13.0"
9
-
10
- # Need this PR: https://github.com/rails/rails-dom-testing/pull/84 for easier DOM testing:
11
- gem 'rails-dom-testing', git: "https://github.com/rails/rails-dom-testing.git", ref: "8f5acdfc"
data/Rakefile CHANGED
@@ -6,22 +6,7 @@ require "rake/testtask"
6
6
  Rake::TestTask.new(:test) do |t|
7
7
  t.libs << "test"
8
8
  t.libs << "lib"
9
- t.test_files = FileList["test/**/*_test.rb"].exclude("test/dummy_app/**/*")
9
+ t.test_files = FileList["test/**/*_test.rb"]
10
10
  end
11
11
 
12
- namespace :test do
13
- task :system do
14
- Bundler.with_original_env do
15
- sh <<~CMD
16
- yarn build &&
17
- cd test/dummy_app &&
18
- yarn &&
19
- bundle &&
20
- RAILS_ENV=test rails webpacker:compile
21
- rails test:system
22
- CMD
23
- end
24
- end
25
- end
26
-
27
- task default: [:test, :'test:system']
12
+ task default: [:test]
@@ -57,8 +57,9 @@ module Shoelace
57
57
  options = @options.stringify_keys
58
58
  options["value"] = options.fetch("value") { value_before_type_cast }
59
59
  add_default_name_and_id(options)
60
+ label = options.delete('label').presence || @method_name.humanize
60
61
 
61
- @template_object.content_tag('sl-switch', @method_name.to_s.humanize, options, &block)
62
+ @template_object.content_tag('sl-switch', label, options, &block)
62
63
  end
63
64
  end
64
65
 
@@ -104,11 +105,26 @@ module Shoelace
104
105
  end
105
106
  end
106
107
 
108
+ class ShoelaceGroupedCollectionSelect < ActionView::Helpers::Tags::GroupedCollectionSelect #:nodoc:
109
+ def option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil)
110
+ @template_object.sl_option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key)
111
+ end
112
+
113
+ def select_content_tag(option_tags, _options, html_options)
114
+ html_options = html_options.stringify_keys
115
+ html_options['value'] ||= value
116
+ add_default_name_and_id(html_options)
117
+
118
+ @template_object.content_tag("sl-select", option_tags, html_options)
119
+ end
120
+ end
121
+
107
122
  class ShoelaceCheckBox < ActionView::Helpers::Tags::CheckBox #:nodoc:
108
123
  def render(&block)
109
124
  options = @options.stringify_keys
110
125
  options["value"] = @checked_value
111
126
  options["checked"] = true if input_checked?(options)
127
+ label = options.delete("label") || @method_name.humanize
112
128
 
113
129
  if options["multiple"]
114
130
  add_default_name_and_id_for_value(@checked_value, options)
@@ -122,7 +138,7 @@ module Shoelace
122
138
  sl_checkbox_tag = if block_given?
123
139
  @template_object.content_tag('sl-checkbox', '', options, &block)
124
140
  else
125
- @template_object.content_tag('sl-checkbox', @method_name.to_s.humanize, options)
141
+ @template_object.content_tag('sl-checkbox', label || @method_name.to_s.humanize, options)
126
142
  end
127
143
 
128
144
  if include_hidden
@@ -137,8 +153,8 @@ module Shoelace
137
153
  def render(&block)
138
154
  options = @options.stringify_keys
139
155
  options["value"] = @tag_value
140
- options["checked"] = "checked" if input_checked?(options)
141
156
  add_default_name_and_id_for_value(@tag_value, options)
157
+ options.delete("name")
142
158
 
143
159
  @template_object.content_tag('sl-radio', '', options.except("type"), &block)
144
160
  end
@@ -164,7 +180,12 @@ module Shoelace
164
180
  private
165
181
 
166
182
  def render_collection(&block)
167
- @template_object.content_tag('sl-radio-group', 'label' => @method_name.to_s.humanize) { super(&block) }
183
+ html_options = @html_options.stringify_keys
184
+ html_options["value"] = value
185
+ add_default_name_and_id(html_options)
186
+ html_options["label"] = @options[:label].presence || @method_name.humanize
187
+
188
+ @template_object.content_tag('sl-radio-group', html_options) { super(&block) }
168
189
  end
169
190
 
170
191
  def hidden_field
@@ -188,48 +209,56 @@ module Shoelace
188
209
  url: :url
189
210
  }.each do |field_type, field_class|
190
211
  # def email_field(method, **options, &block)
191
- # ShoelaceInputField.new(:email, object_name, method, @template, options.with_defaults(label: method.to_s.humanize)).render(&block)
212
+ # ShoelaceInputField.new(:email, object_name, method, @template, options.with_defaults(label: label_text(method))).render(&block)
192
213
  # end
193
214
  eval <<-RUBY, nil, __FILE__, __LINE__ + 1
194
215
  def #{field_type}_field(method, **options, &block)
195
- ShoelaceInputField.new(:#{field_class}, object_name, method, @template, options.with_defaults(object: @object, label: method.to_s.humanize)).render(&block)
216
+ ShoelaceInputField.new(:#{field_class}, object_name, method, @template, options.with_defaults(object: @object, label: label_text(method))).render(&block)
196
217
  end
197
218
  RUBY
198
219
  end
199
220
 
200
221
  def color_field(method, **options)
201
- ShoelaceColorPicker.new(object_name, method, @template, options.with_defaults(object: @object)).render
222
+ ShoelaceColorPicker.new(object_name, method, @template, options.with_defaults(object: @object, label: label_text(method))).render
202
223
  end
203
224
  alias color_picker color_field
204
225
 
205
226
  def range_field(method, **options)
206
- ShoelaceRange.new(object_name, method, @template, options.with_defaults(object: @object, label: method.to_s.humanize)).render
227
+ ShoelaceRange.new(object_name, method, @template, options.with_defaults(object: @object, label: label_text(method))).render
207
228
  end
208
229
  alias range range_field
209
230
 
210
231
  def switch_field(method, **options, &block)
211
- ShoelaceSwitch.new(object_name, method, @template, options.with_defaults(object: @object)).render(&block)
232
+ if block_given?
233
+ ShoelaceSwitch.new(object_name, method, @template, options.with_defaults(object: @object)).render(&block)
234
+ else
235
+ ShoelaceSwitch.new(object_name, method, @template, options.with_defaults(object: @object, label: label_text(method))).render(&block)
236
+ end
212
237
  end
213
238
  alias switch switch_field
214
239
 
215
240
  def text_area(method, **options, &block)
216
- ShoelaceTextArea.new(object_name, method, @template, options.with_defaults(object: @object, label: method.to_s.humanize, resize: 'auto')).render(&block)
241
+ ShoelaceTextArea.new(object_name, method, @template, options.with_defaults(object: @object, label: label_text(method), resize: 'auto')).render(&block)
217
242
  end
218
243
 
219
244
  def check_box(method, options = {}, checked_value = "1", unchecked_value = "0", &block)
220
- ShoelaceCheckBox.new(object_name, method, @template, checked_value, unchecked_value, options.merge(object: @object)).render(&block)
245
+ ShoelaceCheckBox.new(object_name, method, @template, checked_value, unchecked_value, options.with_defaults(label: label_text(method)).merge(object: @object)).render(&block)
221
246
  end
222
247
 
223
248
  def select(method, choices = nil, options = {}, html_options = {}, &block)
224
- ShoelaceSelect.new(object_name, method, @template, choices, options.with_defaults(object: @object), html_options.with_defaults(label: method.to_s.humanize), &block).render
249
+ ShoelaceSelect.new(object_name, method, @template, choices, options.with_defaults(object: @object), html_options.with_defaults(label: label_text(method)), &block).render
225
250
  end
226
251
 
227
252
  def collection_select(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
228
- ShoelaceCollectionSelect.new(object_name, method, @template, collection, value_method, text_method, options.with_defaults(object: @object), html_options.with_defaults(label: method.to_s.humanize), &block).render
253
+ ShoelaceCollectionSelect.new(object_name, method, @template, collection, value_method, text_method, options.with_defaults(object: @object), html_options.with_defaults(label: label_text(method)), &block).render
254
+ end
255
+
256
+ def grouped_collection_select(method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
257
+ ShoelaceGroupedCollectionSelect.new(object_name, method, @template, collection, group_method, group_label_method, option_key_method, option_value_method, options.with_defaults(object: @object), html_options.with_defaults(label: label_text(method))).render
229
258
  end
230
259
 
231
260
  def collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
232
- ShoelaceCollectionRadioButtons.new(object_name, method, @template, collection, value_method, text_method, options.with_defaults(object: @object), html_options).render(&block)
261
+ ShoelaceCollectionRadioButtons.new(object_name, method, @template, collection, value_method, text_method, options.with_defaults(object: @object, label: label_text(method)), html_options).render(&block)
233
262
  end
234
263
 
235
264
  def submit(value = nil, options = {})
@@ -237,6 +266,12 @@ module Shoelace
237
266
 
238
267
  @template.sl_submit_tag(value || submit_default_value, **options)
239
268
  end
269
+
270
+ private
271
+
272
+ def label_text(method, tag_value = nil)
273
+ ::ActionView::Helpers::Tags::Label::LabelBuilder.new(@template, object_name, method, object, tag_value).translation
274
+ end
240
275
  end
241
276
 
242
277
  DEFAULT_FORM_PARAMETERS = { builder: ShoelaceFormBuilder }
@@ -307,6 +342,20 @@ module Shoelace
307
342
  end.join("\n").html_safe
308
343
  end
309
344
 
345
+ def sl_option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil)
346
+ body = "".html_safe
347
+
348
+ collection.each_with_index do |group, index|
349
+ option_tags = sl_options_from_collection_for_select(value_for_collection(group, group_method), option_key_method, option_value_method, selected_key)
350
+
351
+ body.safe_concat(DIVIDER_TAG) if index > 0
352
+ body.safe_concat(content_tag("small", value_for_collection(group, group_label_method)))
353
+ body.safe_concat(option_tags)
354
+ end
355
+
356
+ body
357
+ end
358
+
310
359
  # Returns a string of +<sl-option>+ tags compiled by iterating over the collection and assigning the result of
311
360
  # a call to the +value_method+ as the option value and the +text_method+ as the option text.
312
361
  def sl_options_from_collection_for_select(collection, value_method, text_method, selected = nil)
@@ -3,7 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "rake", "~> 13.0"
6
- gem "rails-dom-testing", git: "https://github.com/rails/rails-dom-testing.git", ref: "8f5acdfc"
7
6
  gem "rails", "~> 6.0.0"
8
7
  gem "railties", "~> 6.0.0"
9
8
  gem "activesupport", "~> 6.0.0"
@@ -3,7 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "rake", "~> 13.0"
6
- gem "rails-dom-testing", git: "https://github.com/rails/rails-dom-testing.git", ref: "8f5acdfc"
7
6
  gem "rails", "~> 6.1.0"
8
7
  gem "railties", "~> 6.1.0"
9
8
  gem "activesupport", "~> 6.1.0"
@@ -3,7 +3,6 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "rake", "~> 13.0"
6
- gem "rails-dom-testing", git: "https://github.com/rails/rails-dom-testing.git", ref: "8f5acdfc"
7
6
  gem "rails", "~> 7.0.0"
8
7
  gem "railties", "~> 7.0.0"
9
8
  gem "activesupport", "~> 7.0.0"
@@ -0,0 +1,10 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rake", "~> 13.0"
6
+ gem "rails", "~> 7.1.0"
7
+ gem "railties", "~> 7.1.0"
8
+ gem "activesupport", "~> 7.1.0"
9
+
10
+ gemspec path: "../"
@@ -9,6 +9,5 @@ git "https://github.com/rails/rails.git", branch: "main" do
9
9
  end
10
10
 
11
11
  gem "rake", "~> 13.0"
12
- gem "rails-dom-testing", git: "https://github.com/rails/rails-dom-testing.git", ref: "8f5acdfc"
13
12
 
14
13
  gemspec path: "../"
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Shoelace
4
4
  module Rails
5
- VERSION = "0.4.1"
5
+ VERSION = "0.6.0"
6
6
  end
7
7
  end
@@ -31,5 +31,5 @@ Gem::Specification.new do |spec|
31
31
 
32
32
  spec.add_development_dependency "appraisal"
33
33
  spec.add_development_dependency "minitest", ">= 5.14.4"
34
- spec.add_development_dependency "rails-dom-testing", ">= 2.0.3"
34
+ spec.add_development_dependency "rails-dom-testing", ">= 2.2.0"
35
35
  end
@@ -46,7 +46,7 @@ class FormHelperTest < ActionView::TestCase
46
46
 
47
47
  test "#sl_radio_button" do
48
48
  assert_dom_equal(<<~HTML, sl_radio_button(:user, :name, 'userid-314', checked: true) { "Yuki Nishijima" })
49
- <sl-radio value="userid-314" checked="checked" name="user[name]" id="user_name_userid-314">Yuki Nishijima</sl-radio>
49
+ <sl-radio value="userid-314" checked="checked" id="user_name_userid-314">Yuki Nishijima</sl-radio>
50
50
  HTML
51
51
  end
52
52
 
@@ -149,7 +149,7 @@ class FormHelperTest < ActionView::TestCase
149
149
  test "#color_field" do
150
150
  sl_form_for(User.new, url: "/") do |form|
151
151
  assert_dom_equal <<~HTML, form.color_field(:name)
152
- <sl-color-picker name="user[name]" id="user_name"></sl-color-picker>
152
+ <sl-color-picker name="user[name]" id="user_name" label="Name"></sl-color-picker>
153
153
  HTML
154
154
  end
155
155
  end
@@ -412,7 +412,7 @@ class FormHelperTest < ActionView::TestCase
412
412
  end
413
413
  end
414
414
 
415
- test "#collection_select with a defalut value" do
415
+ test "#collection_select with a default value" do
416
416
  users = {
417
417
  1 => "Yuki Nishijima",
418
418
  2 => "Matz",
@@ -430,6 +430,35 @@ class FormHelperTest < ActionView::TestCase
430
430
  end
431
431
  end
432
432
 
433
+ test "#grouped_collection_select" do
434
+ users = [
435
+ OpenStruct.new(
436
+ group_name: "Main maintainers",
437
+ members: [
438
+ OpenStruct.new(id: 1, name: "Matz"),
439
+ OpenStruct.new(id: 2, name: "Koichi Sasada"),
440
+ ]
441
+ ),
442
+ OpenStruct.new(
443
+ group_name: "Default gem maintainers",
444
+ members: [OpenStruct.new(id: 3, name: "Yuki Nishijima")]
445
+ ),
446
+ ]
447
+
448
+ sl_form_for(User.new(name: "2"), url: "/") do |form|
449
+ assert_dom_equal <<~HTML, form.grouped_collection_select(:name, users, :members, :group_name, :id, :name)
450
+ <sl-select label="Name" name="user[name]" id="user_name" value="2">
451
+ <small>Main maintainers</small>
452
+ <sl-option value="1">Matz</sl-option>
453
+ <sl-option value="2" checked="checked">Koichi Sasada</sl-option>
454
+ <sl-divider></sl-divider>
455
+ <small>Default gem maintainers</small>
456
+ <sl-option value="3">Yuki Nishijima</sl-option>
457
+ </sl-select>
458
+ HTML
459
+ end
460
+ end
461
+
433
462
  test "#collection_radio_buttons" do
434
463
  users = {
435
464
  1 => "Yuki Nishijima",
@@ -439,10 +468,10 @@ class FormHelperTest < ActionView::TestCase
439
468
 
440
469
  sl_form_for(User.new, url: "/") do |form|
441
470
  assert_dom_equal <<~HTML, form.collection_radio_buttons(:name, users, :first, :last)
442
- <sl-radio-group label="Name">
443
- <sl-radio name="user[name]" value="1" id="user_name_1">Yuki Nishijima</sl-radio>
444
- <sl-radio name="user[name]" value="2" id="user_name_2">Matz</sl-radio>
445
- <sl-radio name="user[name]" value="3" id="user_name_3">Koichi Sasada</sl-radio>
471
+ <sl-radio-group label="Name" name="user[name]" id="user_name">
472
+ <sl-radio value="1" id="user_name_1">Yuki Nishijima</sl-radio>
473
+ <sl-radio value="2" id="user_name_2">Matz</sl-radio>
474
+ <sl-radio value="3" id="user_name_3">Koichi Sasada</sl-radio>
446
475
  </sl-radio-group>
447
476
  HTML
448
477
  end
@@ -457,10 +486,10 @@ class FormHelperTest < ActionView::TestCase
457
486
 
458
487
  sl_form_for(User.new(name: 1), url: "/") do |form|
459
488
  assert_dom_equal <<~HTML, form.collection_radio_buttons(:name, users, :first, :last)
460
- <sl-radio-group label="Name">
461
- <sl-radio name="user[name]" value="1" id="user_name_1" checked="checked">Yuki Nishijima</sl-radio>
462
- <sl-radio name="user[name]" value="2" id="user_name_2">Matz</sl-radio>
463
- <sl-radio name="user[name]" value="3" id="user_name_3">Koichi Sasada</sl-radio>
489
+ <sl-radio-group label="Name" name="user[name]" value="1" id="user_name">
490
+ <sl-radio value="1" id="user_name_1">Yuki Nishijima</sl-radio>
491
+ <sl-radio value="2" id="user_name_2">Matz</sl-radio>
492
+ <sl-radio value="3" id="user_name_3">Koichi Sasada</sl-radio>
464
493
  </sl-radio-group>
465
494
  HTML
466
495
  end