protos-protoform 0.0.1 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c57b1b4645f529c7f8b132e92b0776a839448cd20eb3c689fbcf3689f2f7cfda
4
- data.tar.gz: da70f9680fed7bb2815deaa61ffb049ab9edfac706bb9e8b9e60f2ac8e5904a4
3
+ metadata.gz: d87996776d7c98ac20d0f3f043bda6364cfe22be19ed00820e5c48df504837a5
4
+ data.tar.gz: 506204d5092faccefb7eaab6506e437f43faa8b741322e84533589e8f5cd7334
5
5
  SHA512:
6
- metadata.gz: 7dbee5d770d7efed179c43eb39892f8bf4fc8d7935b65160ab84876688a64bb3612a2226ffb421094c32412e895af9fbfcebe44872b54680b2cd7951f9d82c4d
7
- data.tar.gz: 8bd336c38077d8c15855329c01c63a9897320b62117e06a4f747b7f2f3e9c9849b4bf37a0bd4bce8d854e9994fd6c0fa19ba0551e2275ee8511ac57d4dab1bfa
6
+ metadata.gz: d6d4dad661cafa7395860cd52f131f8a536311f2a8c150f4c673d0136c6fa9dd69b66b144d06dec171c72d868ac5b00e8b890eb693073bf4c530d938e1d470c1
7
+ data.tar.gz: f25ccd64a68b57a41be47590cc5d3ed4d4cc39f3f8f055fb69bf6ed60008aff768fef68158030313ffb2aa0df4b1d6250b1e26c8779120b0308d12b7cb2ebd55
data/.rubocop.yml CHANGED
@@ -6,4 +6,4 @@ inherit_gem:
6
6
  - config/default.yml
7
7
 
8
8
  AllCops:
9
- TargetRubyVersion: 3.1
9
+ TargetRubyVersion: 3.2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  ## [Unreleased]
2
2
 
3
- ## [0.1.0] - 2023-06-23
3
+ ## [0.1.0] - 2024-09-04
4
+
5
+ - Adds tests for all Rails components
6
+ - Adds `Time`, `Datetime`, `Date`, and `RadioButton` components
7
+ - Fixes a bug in `Button` component calling the wrong method on `attrs`
8
+ - Bumps supported Ruby version to 3.2
9
+ - Adds value suffix to labels allowing them to match radio button ids
10
+ - Bumps `protos` dependency to `v0.6.0`
11
+
12
+ ## [0.0.2] - 2024-08-14
13
+
14
+ - Adds handling client supplied values like files and images
15
+ - Fixes overriding methods on forms when supplying a Rails model
16
+ - Adds `include_blank` option on select component to match Rails API
17
+ - Transfers ownership of repo from `nolantait` to `inhouse-work` organization to
18
+ match other `protos-` gems
19
+
20
+ ## [0.0.1] - 2023-06-23
4
21
 
5
22
  - Initial release
data/Gemfile.lock CHANGED
@@ -1,48 +1,56 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- protos-protoform (0.0.1)
4
+ protos-protoform (0.1.0)
5
+ activerecord (~> 7.0)
6
+ activesupport (~> 7.0)
5
7
  phlex-rails (~> 1.0)
6
- protos (~> 0.2)
8
+ protos (~> 0.6)
7
9
  zeitwerk (~> 2.6)
8
10
 
9
11
  GEM
10
12
  remote: https://rubygems.org/
11
13
  specs:
12
- actionpack (7.1.3.2)
13
- actionview (= 7.1.3.2)
14
- activesupport (= 7.1.3.2)
14
+ actionpack (7.2.1)
15
+ actionview (= 7.2.1)
16
+ activesupport (= 7.2.1)
15
17
  nokogiri (>= 1.8.5)
16
18
  racc
17
- rack (>= 2.2.4)
19
+ rack (>= 2.2.4, < 3.2)
18
20
  rack-session (>= 1.0.1)
19
21
  rack-test (>= 0.6.3)
20
22
  rails-dom-testing (~> 2.2)
21
23
  rails-html-sanitizer (~> 1.6)
22
- actionview (7.1.3.2)
23
- activesupport (= 7.1.3.2)
24
+ useragent (~> 0.16)
25
+ actionview (7.2.1)
26
+ activesupport (= 7.2.1)
24
27
  builder (~> 3.1)
25
28
  erubi (~> 1.11)
26
29
  rails-dom-testing (~> 2.2)
27
30
  rails-html-sanitizer (~> 1.6)
28
- activemodel (7.1.3.2)
29
- activesupport (= 7.1.3.2)
30
- activesupport (7.1.3.2)
31
+ activemodel (7.2.1)
32
+ activesupport (= 7.2.1)
33
+ activerecord (7.2.1)
34
+ activemodel (= 7.2.1)
35
+ activesupport (= 7.2.1)
36
+ timeout (>= 0.4.0)
37
+ activesupport (7.2.1)
31
38
  base64
32
39
  bigdecimal
33
- concurrent-ruby (~> 1.0, >= 1.0.2)
40
+ concurrent-ruby (~> 1.0, >= 1.3.1)
34
41
  connection_pool (>= 2.2.5)
35
42
  drb
36
43
  i18n (>= 1.6, < 2)
44
+ logger (>= 1.4.2)
37
45
  minitest (>= 5.1)
38
- mutex_m
39
- tzinfo (~> 2.0)
40
- addressable (2.8.6)
41
- public_suffix (>= 2.0.2, < 6.0)
46
+ securerandom (>= 0.3)
47
+ tzinfo (~> 2.0, >= 2.0.5)
48
+ addressable (2.8.7)
49
+ public_suffix (>= 2.0.2, < 7.0)
42
50
  ast (2.4.2)
43
51
  base64 (0.2.0)
44
- bigdecimal (3.1.7)
45
- builder (3.2.4)
52
+ bigdecimal (3.1.8)
53
+ builder (3.3.0)
46
54
  capybara (3.40.0)
47
55
  addressable
48
56
  matrix
@@ -52,7 +60,7 @@ GEM
52
60
  rack-test (>= 0.6.3)
53
61
  regexp_parser (>= 1.5, < 3.0)
54
62
  xpath (~> 3.2)
55
- concurrent-ruby (1.2.3)
63
+ concurrent-ruby (1.3.4)
56
64
  connection_pool (2.4.1)
57
65
  crass (1.0.6)
58
66
  debug (1.9.2)
@@ -63,7 +71,7 @@ GEM
63
71
  dry-core (1.0.1)
64
72
  concurrent-ruby (~> 1.0)
65
73
  zeitwerk (~> 2.6)
66
- dry-inflector (1.0.0)
74
+ dry-inflector (1.1.0)
67
75
  dry-initializer (3.1.1)
68
76
  dry-logic (1.5.0)
69
77
  concurrent-ruby (~> 1.0)
@@ -76,47 +84,48 @@ GEM
76
84
  dry-inflector (~> 1.0)
77
85
  dry-logic (~> 1.4)
78
86
  zeitwerk (~> 2.6)
79
- erubi (1.12.0)
80
- i18n (1.14.4)
87
+ erubi (1.13.0)
88
+ i18n (1.14.5)
81
89
  concurrent-ruby (~> 1.0)
82
90
  io-console (0.7.2)
83
- irb (1.12.0)
84
- rdoc
91
+ irb (1.14.0)
92
+ rdoc (>= 4.0.0)
85
93
  reline (>= 0.4.2)
86
94
  json (2.7.2)
87
95
  language_server-protocol (3.17.0.3)
96
+ logger (1.6.1)
88
97
  loofah (2.22.0)
89
98
  crass (~> 1.0.2)
90
99
  nokogiri (>= 1.12.0)
91
100
  lru_redux (1.1.0)
92
101
  matrix (0.4.2)
93
102
  mini_mime (1.1.5)
94
- minitest (5.22.3)
95
- mutex_m (0.2.0)
96
- nokogiri (1.16.4-aarch64-linux)
103
+ minitest (5.25.1)
104
+ nokogiri (1.16.7-aarch64-linux)
97
105
  racc (~> 1.4)
98
- nokogiri (1.16.4-arm-linux)
106
+ nokogiri (1.16.7-arm-linux)
99
107
  racc (~> 1.4)
100
- nokogiri (1.16.4-arm64-darwin)
108
+ nokogiri (1.16.7-arm64-darwin)
101
109
  racc (~> 1.4)
102
- nokogiri (1.16.4-x86-linux)
110
+ nokogiri (1.16.7-x86-linux)
103
111
  racc (~> 1.4)
104
- nokogiri (1.16.4-x86_64-darwin)
112
+ nokogiri (1.16.7-x86_64-darwin)
105
113
  racc (~> 1.4)
106
- nokogiri (1.16.4-x86_64-linux)
114
+ nokogiri (1.16.7-x86_64-linux)
107
115
  racc (~> 1.4)
108
- parallel (1.24.0)
109
- parser (3.3.0.5)
116
+ parallel (1.26.3)
117
+ parser (3.3.5.0)
110
118
  ast (~> 2.4.1)
111
119
  racc
112
- phlex (1.10.0)
113
- phlex-rails (1.2.1)
114
- phlex (~> 1.10.0)
120
+ phlex (1.11.0)
121
+ phlex-rails (1.1.1)
122
+ phlex (~> 1.9)
115
123
  railties (>= 6.1, < 8)
124
+ zeitwerk (~> 2.6)
116
125
  phlex-testing-capybara (0.1.0)
117
126
  capybara (~> 3.38)
118
127
  phlex (>= 0.5)
119
- protos (0.4.1)
128
+ protos (0.6.0)
120
129
  dry-core (~> 1.0)
121
130
  dry-initializer (~> 3.1)
122
131
  dry-types (~> 1.7)
@@ -124,9 +133,9 @@ GEM
124
133
  tailwind_merge (~> 0.10)
125
134
  psych (5.1.2)
126
135
  stringio
127
- public_suffix (5.0.5)
128
- racc (1.7.3)
129
- rack (3.0.10)
136
+ public_suffix (6.0.1)
137
+ racc (1.8.1)
138
+ rack (3.1.7)
130
139
  rack-session (2.0.0)
131
140
  rack (>= 3.0.0)
132
141
  rack-test (2.1.0)
@@ -141,88 +150,89 @@ GEM
141
150
  rails-html-sanitizer (1.6.0)
142
151
  loofah (~> 2.21)
143
152
  nokogiri (~> 1.14)
144
- railties (7.1.3.2)
145
- actionpack (= 7.1.3.2)
146
- activesupport (= 7.1.3.2)
147
- irb
153
+ railties (7.2.1)
154
+ actionpack (= 7.2.1)
155
+ activesupport (= 7.2.1)
156
+ irb (~> 1.13)
148
157
  rackup (>= 1.0.0)
149
158
  rake (>= 12.2)
150
159
  thor (~> 1.0, >= 1.2.2)
151
160
  zeitwerk (~> 2.6)
152
161
  rainbow (3.1.1)
153
162
  rake (13.2.1)
154
- rdoc (6.6.3.1)
163
+ rdoc (6.7.0)
155
164
  psych (>= 4.0.0)
156
- regexp_parser (2.9.0)
157
- reline (0.5.1)
165
+ regexp_parser (2.9.2)
166
+ reline (0.5.9)
158
167
  io-console (~> 0.5)
159
- rexml (3.2.6)
160
168
  rspec (3.13.0)
161
169
  rspec-core (~> 3.13.0)
162
170
  rspec-expectations (~> 3.13.0)
163
171
  rspec-mocks (~> 3.13.0)
164
- rspec-core (3.13.0)
172
+ rspec-core (3.13.1)
165
173
  rspec-support (~> 3.13.0)
166
- rspec-expectations (3.13.0)
174
+ rspec-expectations (3.13.2)
167
175
  diff-lcs (>= 1.2.0, < 2.0)
168
176
  rspec-support (~> 3.13.0)
169
- rspec-mocks (3.13.0)
177
+ rspec-mocks (3.13.1)
170
178
  diff-lcs (>= 1.2.0, < 2.0)
171
179
  rspec-support (~> 3.13.0)
172
180
  rspec-support (3.13.1)
173
- rubocop (1.63.1)
181
+ rubocop (1.66.1)
174
182
  json (~> 2.3)
175
183
  language_server-protocol (>= 3.17.0)
176
184
  parallel (~> 1.10)
177
185
  parser (>= 3.3.0.2)
178
186
  rainbow (>= 2.2.2, < 4.0)
179
- regexp_parser (>= 1.8, < 3.0)
180
- rexml (>= 3.2.5, < 4.0)
181
- rubocop-ast (>= 1.31.1, < 2.0)
187
+ regexp_parser (>= 2.4, < 3.0)
188
+ rubocop-ast (>= 1.32.2, < 2.0)
182
189
  ruby-progressbar (~> 1.7)
183
190
  unicode-display_width (>= 2.4.0, < 3.0)
184
- rubocop-ast (1.31.2)
185
- parser (>= 3.3.0.4)
186
- rubocop-capybara (2.20.0)
187
- rubocop (~> 1.41)
188
- rubocop-factory_bot (2.25.1)
191
+ rubocop-ast (1.32.2)
192
+ parser (>= 3.3.1.0)
193
+ rubocop-capybara (2.21.0)
189
194
  rubocop (~> 1.41)
190
- rubocop-inhouse (0.1.5)
195
+ rubocop-factory_bot (2.26.1)
196
+ rubocop (~> 1.61)
197
+ rubocop-inhouse (0.2.0)
191
198
  rubocop (>= 1.5)
192
199
  rubocop-capybara (>= 2.1)
200
+ rubocop-factory_bot (>= 2.2)
193
201
  rubocop-performance (>= 1.1)
194
202
  rubocop-rails (>= 2.2)
195
203
  rubocop-rake (>= 0.6)
196
204
  rubocop-rspec (>= 2.2)
197
- rubocop-performance (1.21.0)
205
+ rubocop-rspec_rails (>= 2.2)
206
+ rubocop-performance (1.21.1)
198
207
  rubocop (>= 1.48.1, < 2.0)
199
208
  rubocop-ast (>= 1.31.1, < 2.0)
200
- rubocop-rails (2.24.1)
209
+ rubocop-rails (2.26.0)
201
210
  activesupport (>= 4.2.0)
202
211
  rack (>= 1.1)
203
- rubocop (>= 1.33.0, < 2.0)
212
+ rubocop (>= 1.52.0, < 2.0)
204
213
  rubocop-ast (>= 1.31.1, < 2.0)
205
214
  rubocop-rake (0.6.0)
206
215
  rubocop (~> 1.0)
207
- rubocop-rspec (2.29.1)
208
- rubocop (~> 1.40)
209
- rubocop-capybara (~> 2.17)
210
- rubocop-factory_bot (~> 2.22)
211
- rubocop-rspec_rails (~> 2.28)
212
- rubocop-rspec_rails (2.28.3)
213
- rubocop (~> 1.40)
216
+ rubocop-rspec (3.0.4)
217
+ rubocop (~> 1.61)
218
+ rubocop-rspec_rails (2.30.0)
219
+ rubocop (~> 1.61)
220
+ rubocop-rspec (~> 3, >= 3.0.1)
214
221
  ruby-progressbar (1.13.0)
215
- stringio (3.1.0)
216
- tailwind_merge (0.11.0)
222
+ securerandom (0.3.1)
223
+ stringio (3.1.1)
224
+ tailwind_merge (0.13.0)
217
225
  lru_redux (~> 1.1)
218
- thor (1.3.1)
226
+ thor (1.3.2)
227
+ timeout (0.4.1)
219
228
  tzinfo (2.0.6)
220
229
  concurrent-ruby (~> 1.0)
221
230
  unicode-display_width (2.5.0)
231
+ useragent (0.16.10)
222
232
  webrick (1.8.1)
223
233
  xpath (3.2.0)
224
234
  nokogiri (~> 1.8)
225
- zeitwerk (2.6.13)
235
+ zeitwerk (2.6.18)
226
236
 
227
237
  PLATFORMS
228
238
  aarch64-linux
@@ -3,6 +3,16 @@
3
3
  class ApplicationForm < Protoform::Rails::Form
4
4
  include Phlex::Rails::Helpers::Pluralize
5
5
 
6
+ # These are the current dry-initializer options for the base class:
7
+ #
8
+ # param :model, reader: false
9
+ # option :helpers, reader: false, default: -> {}
10
+ # option :action, reader: false, default: -> {}
11
+ # option :method, reader: false, default: -> {}
12
+ # option :namespace, reader: false, default: -> do
13
+ # Namespace.root(key, object: @model, field_class: self.class::Field)
14
+ # end
15
+
6
16
  def row(component)
7
17
  div do
8
18
  render component.field.label(style: "display: block;")
@@ -28,8 +28,8 @@ module Protoform
28
28
 
29
29
  private
30
30
 
31
- def build_field(**kwargs)
32
- @field.class.new(current_index, parent: @field, **kwargs)
31
+ def build_field(**)
32
+ @field.class.new(current_index, parent: @field, **)
33
33
  end
34
34
 
35
35
  def current_index
@@ -120,8 +120,8 @@ module Protoform
120
120
  end
121
121
 
122
122
  # Creates a root Namespace, which is essentially a form.
123
- def self.root(*args, **kwargs, &block)
124
- new(*args, parent: nil, **kwargs, &block)
123
+ def self.root(*, **, &block)
124
+ new(*, parent: nil, **, &block)
125
125
  end
126
126
 
127
127
  protected
@@ -141,7 +141,7 @@ module Protoform
141
141
 
142
142
  # Checks if the child exists. If it does then it returns that. If it
143
143
  # doesn't, it will build the child.
144
- def create_child(key:, child_class:, **kwargs, &block)
144
+ def create_child(key:, child_class:, **, &block)
145
145
  if (child = @children.fetch(key, nil))
146
146
  # ensure that found children are also yielded
147
147
  child.tap { yield child if block }
@@ -150,7 +150,7 @@ module Protoform
150
150
  @children[key] = child_class.new(
151
151
  key,
152
152
  parent: self,
153
- **kwargs,
153
+ **,
154
154
  &block
155
155
  )
156
156
  end
@@ -37,12 +37,12 @@ module Protoform
37
37
  end
38
38
  end
39
39
 
40
- def build_namespace(index, **kwargs)
40
+ def build_namespace(index, **)
41
41
  parent.class.new(
42
42
  index,
43
43
  parent: self,
44
44
  field_class: @field_class,
45
- **kwargs,
45
+ **,
46
46
  &@template
47
47
  )
48
48
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/string/inflections"
4
+
5
+ module Protoform
6
+ module Rails
7
+ Component = ::ApplicationComponent
8
+ end
9
+ end
@@ -12,7 +12,8 @@ module Protoform
12
12
  private
13
13
 
14
14
  def button_text
15
- attrs.fetch(:value, dom.value).titleize
15
+ text = attrs[:value] || dom.value
16
+ text.titleize
16
17
  end
17
18
 
18
19
  def default_attrs
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/core_ext/string/inflections"
4
+
3
5
  module Protoform
4
6
  module Rails
5
7
  module Components
@@ -9,6 +11,10 @@ module Protoform
9
11
  def dom
10
12
  field.dom
11
13
  end
14
+
15
+ def title
16
+ field.key.to_s.titleize
17
+ end
12
18
  end
13
19
  end
14
20
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Protoform
4
+ module Rails
5
+ module Components
6
+ class Date < Input
7
+ option :value, default: -> { field.value }
8
+ option :min, default: -> { }
9
+ option :max, default: -> { }
10
+
11
+ private
12
+
13
+ def default_attrs
14
+ super.merge(
15
+ {
16
+ type: "date",
17
+ value: date_value(value)
18
+ }
19
+ ).tap do |attrs|
20
+ attrs[:min] = date_value(min) if min
21
+ attrs[:max] = date_value(max) if max
22
+ end
23
+ end
24
+
25
+ def date_value(value)
26
+ return unless value
27
+
28
+ if value.is_a?(String)
29
+ value = begin
30
+ Datetime.parse(value)
31
+ rescue Date::Error
32
+ nil
33
+ end
34
+ end
35
+
36
+ value.strftime("%Y-%m-%d")
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Protoform
4
+ module Rails
5
+ module Components
6
+ class Datetime < Input
7
+ option :value, default: -> { field.value }
8
+ option :include_seconds, default: -> { true }, reader: false
9
+ option :min, default: -> { }
10
+ option :max, default: -> { }
11
+
12
+ private
13
+
14
+ def default_attrs
15
+ super.merge(
16
+ {
17
+ type: "datetime-local",
18
+ value: datetime_value(value)
19
+ }
20
+ ).tap do |attrs|
21
+ attrs[:min] = datetime_value(min) if min
22
+ attrs[:max] = datetime_value(max) if max
23
+ end
24
+ end
25
+
26
+ def datetime_value(value)
27
+ return unless value
28
+
29
+ if value.is_a?(String)
30
+ value = begin
31
+ Datetime.parse(value)
32
+ rescue Date::Error
33
+ nil
34
+ end
35
+ end
36
+
37
+ if @include_seconds
38
+ value.strftime("%Y-%m-%dT%T")
39
+ else
40
+ value.strftime("%Y-%m-%dT%H:%M")
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -16,10 +16,20 @@ module Protoform
16
16
  {
17
17
  id: dom.id,
18
18
  name: dom.name,
19
- type: @type
20
- }.tap do |hash|
21
- hash[:value] = field.value unless @type.to_sym == :file
22
- end
19
+ type: @type,
20
+ value:
21
+ }
22
+ end
23
+
24
+ def client_provided_value?
25
+ {
26
+ file: true,
27
+ image: true
28
+ }.fetch(@type.to_sym, false)
29
+ end
30
+
31
+ def value
32
+ dom.value unless client_provided_value?
23
33
  end
24
34
 
25
35
  def inferred_type
@@ -28,9 +38,9 @@ module Protoform
28
38
  "url"
29
39
  when Integer
30
40
  "number"
31
- when Date, DateTime
41
+ when ::Date, ::DateTime
32
42
  "date"
33
- when Time
43
+ when ::Time
34
44
  "time"
35
45
  else
36
46
  "text"
@@ -4,16 +4,24 @@ module Protoform
4
4
  module Rails
5
5
  module Components
6
6
  class Label < Component
7
+ option :value, default: -> { }
8
+
7
9
  def view_template(&content)
8
- content ||= proc { field.key.to_s.titleize }
10
+ content ||= proc { title }
9
11
  label(**attrs, &content)
10
12
  end
11
13
 
12
14
  private
13
15
 
16
+ def label_id
17
+ return dom.id unless value
18
+
19
+ [dom.id, value.parameterize.underscore].join("_")
20
+ end
21
+
14
22
  def default_attrs
15
23
  {
16
- for: dom.id
24
+ for: label_id
17
25
  }
18
26
  end
19
27
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Protoform
4
+ module Rails
5
+ module Components
6
+ class RadioButton < Input
7
+ # This makes value manditory in this class instead of being absorbed by
8
+ # the html_options hash from Protos.
9
+ option :value
10
+
11
+ private
12
+
13
+ def radio_id
14
+ return dom.id if dom.value.nil?
15
+
16
+ [dom.id, dom.value.parameterize.underscore].join("_")
17
+ end
18
+
19
+ def checked?
20
+ dom.value == field.value
21
+ end
22
+
23
+ def default_attrs
24
+ {
25
+ id: radio_id,
26
+ name: dom.name,
27
+ value: dom.value,
28
+ type: "radio",
29
+ checked: checked? ? "checked" : false
30
+ }
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -5,7 +5,7 @@ module Protoform
5
5
  module Components
6
6
  class Select < FieldComponent
7
7
  option :collection, default: -> { [] }
8
- option :include_blank, default: -> { true }
8
+ option :include_blank, default: -> { true }, reader: false
9
9
  option :multiple, reader: false, default: -> { false }
10
10
 
11
11
  def view_template(&options)
@@ -23,7 +23,7 @@ module Protoform
23
23
  select(multiple: @multiple, **attrs, name:, &options)
24
24
  else
25
25
  select(multiple: @multiple, **attrs, name:) do
26
- blank_option
26
+ blank_option if @include_blank
27
27
  options(*@collection)
28
28
  end
29
29
  end
@@ -31,10 +31,7 @@ module Protoform
31
31
 
32
32
  def options(*collection)
33
33
  map_options(collection).each do |key, value|
34
- option(
35
- selected: selected_value_for(key) ? "selected" : false,
36
- value: key
37
- ) { value }
34
+ option(selected: selected_value_for(key), value: key) { value }
38
35
  end
39
36
  end
40
37
 
@@ -53,6 +50,10 @@ module Protoform
53
50
  protected
54
51
 
55
52
  def selected_value_for(key)
53
+ selected?(key) ? "selected" : false
54
+ end
55
+
56
+ def selected?(key)
56
57
  case field.value
57
58
  when String, Symbol
58
59
  field.value.to_s == key.to_s
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Protoform
4
+ module Rails
5
+ module Components
6
+ class Time < Input
7
+ option :value, default: -> { field.value }
8
+ option :include_seconds, default: -> { true }, reader: false
9
+ option :min, default: -> { }
10
+ option :max, default: -> { }
11
+
12
+ private
13
+
14
+ def default_attrs
15
+ super.merge(
16
+ {
17
+ type: "time",
18
+ value: time_value(value)
19
+ }
20
+ ).tap do |attrs|
21
+ attrs[:min] = time_value(min) if min
22
+ attrs[:max] = time_value(max) if max
23
+ end
24
+ end
25
+
26
+ def time_value(value)
27
+ return unless value
28
+
29
+ if value.is_a?(String)
30
+ value = begin
31
+ Datetime.parse(value)
32
+ rescue Date::Error
33
+ nil
34
+ end
35
+ end
36
+
37
+ if @include_seconds
38
+ value.strftime("%T.%L")
39
+ else
40
+ value.strftime("%H:%M")
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -36,6 +36,22 @@ module Protoform
36
36
  Components::Checkbox.new(self, ...)
37
37
  end
38
38
 
39
+ def date(...)
40
+ Components::Date.new(self, ...)
41
+ end
42
+
43
+ def time(...)
44
+ Components::Time.new(self, ...)
45
+ end
46
+
47
+ def datetime(...)
48
+ Components::Datetime.new(self, ...)
49
+ end
50
+
51
+ def radio_button(value, **)
52
+ Components::RadioButton.new(self, value:, **)
53
+ end
54
+
39
55
  def label(...)
40
56
  Components::Label.new(self, ...)
41
57
  end
@@ -2,7 +2,6 @@
2
2
 
3
3
  module Protoform
4
4
  module Rails
5
- Component = ::ApplicationComponent
6
5
  # A Protos::Component class that accepts a model and sets
7
6
  # a `Protoform::Namespace` with the `Object#model_name` as the key and maps
8
7
  # the object to form fields and namespaces.
@@ -16,9 +15,12 @@ module Protoform
16
15
  # `_method_field`.
17
16
  class Form < Component
18
17
  param :model, reader: false
19
- option :helpers, reader: false, default: -> {}
20
- option :action, reader: false, default: -> {}
21
- option :method, reader: false, default: -> {}
18
+ option :authenticity_token, reader: false, default: -> { true }
19
+ option :helpers, reader: false, default: -> { }
20
+ option :action, reader: false, default: -> { }
21
+ option :method,
22
+ reader: false,
23
+ default: -> { }
22
24
  option :namespace, reader: false, default: -> do
23
25
  Namespace.root(key, object: @model, field_class: self.class::Field)
24
26
  end
@@ -45,14 +47,20 @@ module Protoform
45
47
 
46
48
  def around_template(&block)
47
49
  form_tag do
48
- authenticity_token_field
50
+ authenticity_token_field if @authenticity_token
51
+
49
52
  _method_field
50
53
  super
51
54
  end
52
55
  end
53
56
 
54
57
  def form_tag(&block)
55
- form action:, method: form_method, **attrs, &block
58
+ form(
59
+ action: form_action,
60
+ method: form_method,
61
+ **attrs,
62
+ &block
63
+ )
56
64
  end
57
65
 
58
66
  def view_template(&block)
@@ -100,15 +108,17 @@ module Protoform
100
108
  end
101
109
 
102
110
  def resource_action
111
+ return :update if @method == :patch
112
+
103
113
  @model.persisted? ? :update : :create
104
114
  end
105
115
 
106
- def action
107
- @action ||= helpers.url_for(action: resource_action)
116
+ def form_action
117
+ @form_action ||= @action || helpers.url_for(action: resource_action)
108
118
  end
109
119
 
110
120
  def form_method
111
- @method.to_s.downcase == "get" ? "get" : "post"
121
+ @method == :get ? :get : :post
112
122
  end
113
123
 
114
124
  private
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_record"
4
+
3
5
  module Protoform
4
6
  module Rails
5
7
  # Accept a collection of objects and map them to options suitable for form
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Protoform
4
- VERSION = "0.0.1"
4
+ VERSION = "0.1.0"
5
5
  end
data/lib/protoform.rb CHANGED
@@ -7,7 +7,6 @@ module Protoform
7
7
  Loader = Zeitwerk::Loader.for_gem.tap do |loader|
8
8
  loader.ignore "#{__dir__}/generators"
9
9
  loader.inflector.inflect(
10
- # rubocop:disable Style/StringHashKeys
11
10
  "dom" => "DOM"
12
11
  # rubocop:enable Style/StringHashKeys
13
12
  )
@@ -10,9 +10,9 @@ Gem::Specification.new do |spec|
10
10
 
11
11
  spec.summary = "Phlex based form builder for Rails"
12
12
  spec.description = "Build phlex based forms using Rails conventions"
13
- spec.homepage = "https://github.com/nolantait/protos-protoform"
13
+ spec.homepage = "https://github.com/inhouse-work/protos-protoform"
14
14
  spec.license = "MIT"
15
- spec.required_ruby_version = ">= 3.1.0"
15
+ spec.required_ruby_version = ">= 3.2.0"
16
16
 
17
17
  spec.metadata["allowed_push_host"] = "https://rubygems.org"
18
18
 
@@ -42,8 +42,10 @@ Gem::Specification.new do |spec|
42
42
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
43
43
  spec.require_paths = ["lib"]
44
44
 
45
+ spec.add_dependency "activerecord", "~> 7.0"
46
+ spec.add_dependency "activesupport", "~> 7.0"
45
47
  spec.add_dependency "phlex-rails", "~> 1.0"
46
- spec.add_dependency "protos", "~> 0.2"
48
+ spec.add_dependency "protos", "~> 0.6"
47
49
  spec.add_dependency "zeitwerk", "~> 2.6"
48
50
  spec.metadata["rubygems_mfa_required"] = "true"
49
51
  end
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protos-protoform
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nolan Tait
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-13 00:00:00.000000000 Z
11
+ date: 2024-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '7.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '7.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '7.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '7.0'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: phlex-rails
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -30,14 +58,14 @@ dependencies:
30
58
  requirements:
31
59
  - - "~>"
32
60
  - !ruby/object:Gem::Version
33
- version: '0.2'
61
+ version: '0.6'
34
62
  type: :runtime
35
63
  prerelease: false
36
64
  version_requirements: !ruby/object:Gem::Requirement
37
65
  requirements:
38
66
  - - "~>"
39
67
  - !ruby/object:Gem::Version
40
- version: '0.2'
68
+ version: '0.6'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: zeitwerk
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -77,28 +105,33 @@ files:
77
105
  - lib/protoform/namespace.rb
78
106
  - lib/protoform/namespace_collection.rb
79
107
  - lib/protoform/node.rb
108
+ - lib/protoform/rails/component.rb
80
109
  - lib/protoform/rails/components/button.rb
81
110
  - lib/protoform/rails/components/checkbox.rb
82
111
  - lib/protoform/rails/components/component.rb
112
+ - lib/protoform/rails/components/date.rb
113
+ - lib/protoform/rails/components/datetime.rb
83
114
  - lib/protoform/rails/components/field_component.rb
84
115
  - lib/protoform/rails/components/input.rb
85
116
  - lib/protoform/rails/components/label.rb
117
+ - lib/protoform/rails/components/radio_button.rb
86
118
  - lib/protoform/rails/components/select.rb
87
119
  - lib/protoform/rails/components/textarea.rb
120
+ - lib/protoform/rails/components/time.rb
88
121
  - lib/protoform/rails/form.rb
89
122
  - lib/protoform/rails/form/field.rb
90
123
  - lib/protoform/rails/option_mapper.rb
91
124
  - lib/protoform/rails/strong_parameters.rb
92
125
  - lib/protoform/version.rb
93
126
  - protos-protoform.gemspec
94
- homepage: https://github.com/nolantait/protos-protoform
127
+ homepage: https://github.com/inhouse-work/protos-protoform
95
128
  licenses:
96
129
  - MIT
97
130
  metadata:
98
131
  allowed_push_host: https://rubygems.org
99
- homepage_uri: https://github.com/nolantait/protos-protoform
100
- source_code_uri: https://github.com/nolantait/protos-protoform
101
- changelog_uri: https://github.com/nolantait/protos-protoform
132
+ homepage_uri: https://github.com/inhouse-work/protos-protoform
133
+ source_code_uri: https://github.com/inhouse-work/protos-protoform
134
+ changelog_uri: https://github.com/inhouse-work/protos-protoform
102
135
  rubygems_mfa_required: 'true'
103
136
  post_install_message:
104
137
  rdoc_options: []
@@ -108,14 +141,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
108
141
  requirements:
109
142
  - - ">="
110
143
  - !ruby/object:Gem::Version
111
- version: 3.1.0
144
+ version: 3.2.0
112
145
  required_rubygems_version: !ruby/object:Gem::Requirement
113
146
  requirements:
114
147
  - - ">="
115
148
  - !ruby/object:Gem::Version
116
149
  version: '0'
117
150
  requirements: []
118
- rubygems_version: 3.5.7
151
+ rubygems_version: 3.5.18
119
152
  signing_key:
120
153
  specification_version: 4
121
154
  summary: Phlex based form builder for Rails