view_component-form 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 869789c616058368805d6dba5564a79c4e2ddb9fe85919721a052da761d34e91
4
- data.tar.gz: 58b02a2e260e61a97386e41d0c891d5aee3344ca4b5c6aebe3fb1f00514b75f4
3
+ metadata.gz: 85efb54495b971620e090764d16af0253225b448f47cd65e688e45d5b156ff2d
4
+ data.tar.gz: ba85d7de360b93c16e1c74868169c82e555290b0d783427a77e61cad46e9b129
5
5
  SHA512:
6
- metadata.gz: 82b77433712fbe3b1453d6dceebaa02bb01be4deba4ddcab28e97b1fe60667feacfaf50cc0d8cf2dcecc18db83738ae5a07441255db4728fcfe8420ef4340d86
7
- data.tar.gz: 2c08a19fa894929aaeb2a03afa0bd666fa05e9f63bed5e85671f74d32190d2a3d45f58c761a7da1bad2eb20744c7e498da3a9a6c2dcb40f9ba3c15e5afdcb967
6
+ metadata.gz: 1cb013fe12f393f641faa269d38268f5bd3a3c959078c33b5266c0612c1f046d24a2354e3b8b1dbf4d635cd8cfdb0da9d455b3fd1b4bd6aac2456cdd9a44316e
7
+ data.tar.gz: 44c37beaaed85850e70819cd0b6df1f7f14ce6edb79e334f3fcdc4f2b232e78374f9463b4f8ad84047689f1a46e08dcf9a392a1d788f7a19228efdfbe04e2ee2
data/CHANGELOG.md CHANGED
@@ -5,6 +5,28 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
+ Nothing yet
9
+
10
+ ## [0.1.2] - 2021-12-07
11
+ ### Added
12
+ - Add missing component specs (#75)
13
+ - Add missing builder specs for return values (#76)
14
+ - Add accurate test cases for all helpers from ActionView::Helpers::FormBuilder
15
+ documentation (#85)
16
+
17
+ ### Changed
18
+ - Cross-documented Rails form helpers (#84)
19
+ - Made tag_klass optional when inheriting from a component class (#87)
20
+ - Improve README: generator, html_class example (#88)
21
+ - Make rails version condition used the same way (#92)
22
+ - Add rails 7.0 and make rails head works (#94)
23
+ - Allow `Base` and `FieldComponent` to support forms without objects (#95)
24
+
25
+ ### Fixed
26
+ - Fix `phone_field` helper (#74)
27
+ - Fix `datetime_local_field` helper (#76)
28
+ - Fix `time_zone_select` helper (#76)
29
+ - Resolve Rails 6.1 deprecation on ActiveModel::Errors#keys call (#91)
8
30
 
9
31
  ## [0.1.1] - 2021-09-27
10
32
 
@@ -17,7 +39,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
17
39
  ## [0.1.0] - 2021-09-16
18
40
 
19
41
  ### Added
20
-
21
42
  - `FormBuilder`: add `.namespace` method to allow local lookup of components (#54)
22
43
  - Add basic `ViewComponent::Form::Builder` that can be used in place of Rails' `ActionView::Helpers::FormBuilder` (#1)
23
44
  - Add all standard FormBuilder helpers provided by Rails, implemented as ViewComponents (#4)
@@ -25,6 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
25
46
  - Add CHANGELOG (#50)
26
47
  - Add CI (#2)
27
48
 
28
- [Unreleased]: https://github.com/pantographe/view_component-form/compare/v0.1.1...HEAD
49
+ [Unreleased]: https://github.com/pantographe/view_component-form/compare/v0.1.2...HEAD
50
+ [0.1.2]: https://github.com/pantographe/view_component-form/compare/v0.1.1...v0.1.2
29
51
  [0.1.1]: https://github.com/pantographe/view_component-form/compare/v0.1.0...v0.1.1
30
52
  [0.1.0]: https://github.com/pantographe/view_component-form/releases/tag/v0.1.0
data/README.md CHANGED
@@ -24,7 +24,7 @@ And then execute:
24
24
 
25
25
  ## Usage
26
26
 
27
- Add a `builder` param to your `form_for` of `form_with`:
27
+ Add a `builder` param to your `form_for`, `form_with`, `fields_for` or `fields`:
28
28
 
29
29
  ```diff
30
30
  - <%= form_for @user do |f| %>
@@ -64,10 +64,10 @@ It should work out of the box, but does nothing particularly interesting for now
64
64
 
65
65
  <label for="user_last_name">Last name</label>
66
66
  <input type="text" value="Doe" name="user[last_name]" id="user_last_name" />
67
-
67
+
68
68
  <label for="user_email">E-mail</label>
69
69
  <input type="email" value="john.doe@example.com" name="user[email]" id="user_email" />
70
-
70
+
71
71
  <label for="user_password">Password</label>
72
72
  <input type="password" name="user[password]" id="user_password" />
73
73
  </form>
@@ -91,14 +91,14 @@ This allows you to pick the namespace your components will be loaded from.
91
91
  # lib/custom_form_builder.rb
92
92
  class CustomFormBuilder < ViewComponent::Form::Builder
93
93
  # Set the namespace you want to use for your own components
94
- namespace Form
94
+ namespace Custom::Form
95
95
  end
96
96
  ```
97
97
 
98
- You can change the default namespace and path:
98
+ Use the generator options to change the default namespace or the path where the file will be created:
99
99
 
100
100
  ```console
101
- bin/rails generate vcf:builder AnotherCustomFormBuilder --namespace Forms::Components --path app/forms
101
+ bin/rails generate vcf:builder AnotherCustomFormBuilder --namespace AnotherCustom::Form --path app/forms
102
102
 
103
103
  create app/forms/another_custom_form_builder.rb
104
104
  ```
@@ -107,23 +107,22 @@ bin/rails generate vcf:builder AnotherCustomFormBuilder --namespace Forms::Compo
107
107
  # app/forms/another_custom_form_builder.rb
108
108
  class AnotherCustomFormBuilder < ViewComponent::Form::Builder
109
109
  # Set the namespace you want to use for your own components
110
- namespace Forms::Components
110
+ namespace AnotherCustom::Form
111
111
  end
112
112
  ```
113
113
 
114
- :warning: **Everything below this line describes the future usage and is subject to change. It does not work yet as the gem is still under heavy development.**
115
-
116
- Now let's generate your own components to customize the rendering.
114
+ Now let's generate your own components to customize their rendering. We can use the standard view_component generator:
117
115
 
118
116
  ```console
119
- bin/rails generate vcf:component Form::TextField
117
+ bin/rails generate component Custom::Form::TextField --inline --parent ViewComponent::Form::TextFieldComponent
120
118
 
121
119
  invoke test_unit
122
- create test/components/form/text_field_component_test.rb
123
- create app/components/form/text_field_component.rb
124
- create app/components/form/text_field_component.html.erb
120
+ create test/components/custom/form/text_field_component_test.rb
121
+ create app/components/custom/form/text_field_component.rb
125
122
  ```
126
123
 
124
+ :warning: The `--parent` option is available since ViewComponent [`v2.41.0`](https://viewcomponent.org/CHANGELOG.html#2410). If you're using a previous version, you can always edit the generated `Custom::Form::CustomTextFieldComponent` class to make it inherit from `ViewComponent::Form::TextFieldComponent`.
125
+
127
126
  Change your forms to use your new builder:
128
127
 
129
128
  ```diff
@@ -131,26 +130,43 @@ Change your forms to use your new builder:
131
130
  + <%= form_for @user, builder: CustomFormBuilder do |f| %>
132
131
  ```
133
132
 
134
- You can then customize the behavior of your `Form::TextFieldComponent`:
133
+ You can then customize the behavior of your `Custom::Form::CustomTextFieldComponent`:
135
134
 
136
135
  ```rb
137
- # app/components/form/text_field_component.rb
136
+ # app/components/custom/form/text_field_component.rb
138
137
 
139
- module Form
140
- class TextFieldComponent < ViewComponent::Form::TextFieldComponent
141
- def html_class
142
- class_names("text-field", "border-error": method_errors?)
143
- end
138
+ class Admin::Form::TextFieldComponent < ViewComponent::Form::TextFieldComponent
139
+ def html_class
140
+ class_names("custom-text-field", "has-error": method_errors?)
144
141
  end
145
142
  end
146
143
  ```
147
144
 
148
- The generated form field with now have your class names:
145
+ In this case we leverage the [`#class_names`](https://api.rubyonrails.org/classes/ActionView/Helpers/TagHelper.html#method-i-class_names) helper to:
146
+ - always add the `custom-text-field` class;
147
+ - add the `has-error` class if there is an error on the attribute (using `ViewComponent::Form::FieldComponent#method_errors?`).
148
+
149
+ The rendered form field will now look like this:
149
150
 
150
151
  ```html
151
- <input class="text-field" type="text" value="John" name="user[first_name]" id="user_first_name">
152
+ <input class="custom-text-field" type="text" value="John" name="user[first_name]" id="user_first_name">
152
153
  ```
153
154
 
155
+ You can use the same approach to inject options, wrap the input in a `<div>`, etc.
156
+
157
+ We'll add more use cases to the documentation soon.
158
+
159
+ ### Using your form components without a backing model
160
+
161
+ If you want to ensure that your fields display consistently across your app, you'll need to lean on Rails' own helpers. You may be used to using form tag helpers such as `text_field_tag` to generate tags, or even writing out plain HTML tags. These can't be integrated with a form builder, so they won't offer you the benefits of this gem.
162
+
163
+ You'll most likely want to use either:
164
+
165
+ - [`form_with`](https://api.rubyonrails.org/v6.1.4/classes/ActionView/Helpers/FormHelper.html#method-i-form_with) and supply a route as the endpoint, e.g. `form_with url: users_path do |f| ...`, or
166
+ - [`fields`](https://api.rubyonrails.org/v6.1.4/classes/ActionView/Helpers/FormHelper.html#method-i-fields), supplying a namespace if necessary. `fields do |f| ...` ought to work in the most basic case.
167
+
168
+ [`fields_for`](https://api.rubyonrails.org/v6.1.4/classes/ActionView/Helpers/FormHelper.html#method-i-fields_for) may also be of interest. To make consistent use of `view_component-form`, you'll want to be using these three helpers to build your forms wherever possible.
169
+
154
170
  ## Development
155
171
 
156
172
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -14,8 +14,8 @@ module ViewComponent
14
14
 
15
15
  attr_reader :form, :object_name, :options
16
16
 
17
- delegate :object, to: :form
18
- delegate :errors, to: :object, prefix: true
17
+ delegate :object, to: :form, allow_nil: true
18
+ delegate :errors, to: :object, prefix: true, allow_nil: true
19
19
 
20
20
  def initialize(form, object_name, options = {})
21
21
  @form = form
@@ -28,6 +28,8 @@ module ViewComponent
28
28
  end
29
29
 
30
30
  def object_errors?
31
+ return false unless object
32
+
31
33
  object.errors.any?
32
34
  end
33
35
 
@@ -3,9 +3,8 @@
3
3
  module ViewComponent
4
4
  module Form
5
5
  class FieldComponent < BaseComponent
6
- class << self
7
- attr_accessor :tag_klass
8
- end
6
+ class_attribute :tag_klass, instance_reader: false, instance_writer: false, instance_accessor: false,
7
+ instance_predicate: false
9
8
 
10
9
  attr_reader :method_name
11
10
 
@@ -31,8 +30,18 @@ module ViewComponent
31
30
  .map(&:upcase_first)
32
31
  end
33
32
 
34
- def method_errors?
35
- (object_errors.keys & object_method_names).any?
33
+ if Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new("6.1")
34
+ def method_errors?
35
+ return false unless object_errors
36
+
37
+ (object_errors.attribute_names & object_method_names).any?
38
+ end
39
+ else
40
+ def method_errors?
41
+ return false unless object_errors
42
+
43
+ (object_errors.keys & object_method_names).any?
44
+ end
36
45
  end
37
46
 
38
47
  def value
@@ -35,7 +35,18 @@ module ViewComponent
35
35
  super
36
36
  end
37
37
 
38
- (field_helpers - %i[label check_box radio_button fields_for fields hidden_field file_field]).each do |selector|
38
+ (field_helpers - %i[
39
+ check_box
40
+ datetime_field
41
+ datetime_local_field
42
+ fields
43
+ fields_for
44
+ file_field
45
+ hidden_field
46
+ label
47
+ phone_field
48
+ radio_button
49
+ ]).each do |selector|
39
50
  class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
40
51
  def #{selector}(method, options = {}) # def text_field(method, options = {})
41
52
  render_component( # render_component(
@@ -47,12 +58,20 @@ module ViewComponent
47
58
  end # end
48
59
  RUBY_EVAL
49
60
  end
61
+ alias phone_field telephone_field
50
62
 
51
63
  # See: https://github.com/rails/rails/blob/33d60cb02dcac26d037332410eabaeeb0bdc384c/actionview/lib/action_view/helpers/form_helper.rb#L2280
52
64
  def label(method, text = nil, options = {}, &block)
53
65
  render_component(:label, @object_name, method, text, objectify_options(options), &block)
54
66
  end
55
67
 
68
+ def datetime_field(method, options = {})
69
+ render_component(
70
+ :datetime_local_field, @object_name, method, objectify_options(options)
71
+ )
72
+ end
73
+ alias datetime_locale_field datetime_field
74
+
56
75
  def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")
57
76
  render_component(
58
77
  :check_box, @object_name, method, checked_value, unchecked_value, objectify_options(options)
@@ -88,18 +107,6 @@ module ViewComponent
88
107
  render_component(:button, value, options, &block)
89
108
  end
90
109
 
91
- # SELECTORS.each do |selector|
92
- # class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
93
- # def #{selector}(*args)
94
- # render_component(
95
- # :#{selector},
96
- # *args,
97
- # super,
98
- # )
99
- # end
100
- # RUBY_EVAL
101
- # end
102
-
103
110
  # See: https://github.com/rails/rails/blob/fe76a95b0d252a2d7c25e69498b720c96b243ea2/actionview/lib/action_view/helpers/form_options_helper.rb
104
111
  def select(method, choices = nil, options = {}, html_options = {}, &block)
105
112
  render_component(
@@ -169,9 +176,9 @@ module ViewComponent
169
176
  )
170
177
  end
171
178
 
172
- def time_zone_select(method, options = {}, html_options = {})
179
+ def time_zone_select(method, priority_zones = nil, options = {}, html_options = {})
173
180
  render_component(
174
- :time_zone_select, @object_name, method,
181
+ :time_zone_select, @object_name, method, priority_zones,
175
182
  objectify_options(options), @default_html_options.merge(html_options)
176
183
  )
177
184
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Backport of https://api.rubyonrails.org/classes/ActionView/Helpers/TagHelper.html#method-i-class_names
4
+ # :nocov:
4
5
  module ViewComponent
5
6
  module Form
6
7
  module ClassNamesHelper
@@ -35,3 +36,4 @@ module ViewComponent
35
36
  end
36
37
  end
37
38
  end
39
+ # :nocov:
@@ -7,20 +7,24 @@ require "action_view"
7
7
  module ViewComponent
8
8
  module Form
9
9
  module TestHelpers
10
- def form_with(object, options = {})
11
- ViewComponent::Form::Builder.new(object_name, object, template, options)
10
+ def form_with(object, builder: ViewComponent::Form::Builder, **options)
11
+ builder.new(object_name, object, template, options)
12
12
  end
13
13
 
14
14
  def object_name
15
15
  :user
16
16
  end
17
17
 
18
- def template
19
- lookup_context = ActionView::LookupContext.new(ActionController::Base.view_paths)
18
+ if Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new("6.1")
19
+ def template
20
+ lookup_context = ActionView::LookupContext.new(ActionController::Base.view_paths)
20
21
 
21
- if Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new("6.1")
22
22
  ActionView::Base.new(lookup_context, {}, ApplicationController.new)
23
- else
23
+ end
24
+ else
25
+ def template
26
+ lookup_context = ActionView::LookupContext.new(ActionController::Base.view_paths)
27
+
24
28
  ActionView::Base.new(lookup_context, {})
25
29
  end
26
30
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ViewComponent
4
4
  module Form
5
- VERSION = "0.1.1"
5
+ VERSION = "0.1.2"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: view_component-form
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pantographe
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-27 00:00:00.000000000 Z
11
+ date: 2021-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionview
@@ -89,7 +89,6 @@ files:
89
89
  - app/components/view_component/form/color_field_component.rb
90
90
  - app/components/view_component/form/date_field_component.rb
91
91
  - app/components/view_component/form/date_select_component.rb
92
- - app/components/view_component/form/datetime_field_component.rb
93
92
  - app/components/view_component/form/datetime_local_field_component.rb
94
93
  - app/components/view_component/form/datetime_select_component.rb
95
94
  - app/components/view_component/form/email_field_component.rb
@@ -130,7 +129,8 @@ metadata:
130
129
  changelog_uri: https://github.com/pantographe/view_component-form/blob/master/CHANGELOG.md
131
130
  source_code_uri: https://github.com/pantographe/view_component-form
132
131
  bug_tracker_uri: https://github.com/pantographe/view_component-form/issues
133
- post_install_message:
132
+ rubygems_mfa_required: 'true'
133
+ post_install_message:
134
134
  rdoc_options: []
135
135
  require_paths:
136
136
  - lib
@@ -145,8 +145,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
145
  - !ruby/object:Gem::Version
146
146
  version: '0'
147
147
  requirements: []
148
- rubygems_version: 3.2.26
149
- signing_key:
148
+ rubygems_version: 3.2.9
149
+ signing_key:
150
150
  specification_version: 4
151
151
  summary: Rails FormBuilder for ViewComponent
152
152
  test_files: []
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ViewComponent
4
- module Form
5
- class DatetimeFieldComponent < FieldComponent
6
- self.tag_klass = ActionView::Helpers::Tags::DatetimeField
7
- end
8
- end
9
- end