phlexi-form 0.4.7 → 0.5.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: 26048462a9cc9beca66d75c24a8d477c5bfdadaae27fe5367aad44c386d826c8
4
- data.tar.gz: fe670159073f2bb7a6ddb4d4f3cdb7b61fa600d62581838eb2a24770366d647d
3
+ metadata.gz: 454cb0f7804d3a7c10a6afdb3fe9bb7342e63bc76ee02750ea4a65f95e853449
4
+ data.tar.gz: 97c56aabb6e2c6b3b83f0c4782ac8724427fd93d211f5ac16f1dd42a4f1c1ac0
5
5
  SHA512:
6
- metadata.gz: d5a5930ec1776f6fc972d6754fe5e81fb9a9bb67c4a2489d30983497237182087c45ffcef3f062d4241796a951b0247bbd3d8331a59dd79e4dc62532d94d2f30
7
- data.tar.gz: 5683debcf1062a1b99e0ac5207c231d6e1a437c1bd75d5a28177af750d15b419ae4fe659fe7eeb0e9fbbb34db2ddfd2f0ce3b67c6832c9cc03790873cbc64afa
6
+ metadata.gz: 46350c1288b35d787080eff648bf86b23a55a1a122d234dfe2611cf91133d922f0e0747826cbf5a3980af7ebad55c07947953432bc3c700456871e7ab99ccb00
7
+ data.tar.gz: 31936b709b68353f3c855ec809e582f1d43a2c5669bcadec9499a0ea315ed66c9cf74038176b9106d4f316953a8111669aeaa63bc44f1fe48c92d746b86fcb8c
@@ -8,7 +8,7 @@ module Phlexi
8
8
  include Options::Validators
9
9
  include Options::InferredTypes
10
10
  include Options::Errors
11
- include Options::Collection
11
+ include Options::Choices
12
12
  include Options::Hints
13
13
  include Options::Required
14
14
  include Options::Autofocus
@@ -2,58 +2,58 @@
2
2
 
3
3
  module Phlexi
4
4
  module Form
5
- # OptionMapper is responsible for converting a collection of objects into a hash of options
5
+ # ChoicesMapper is responsible for converting a collection of objects into a hash of options
6
6
  # suitable for form controls, such as `select > options`.
7
7
  # Both values and labels are converted to strings.
8
8
  #
9
9
  # @example Basic usage
10
10
  # collection = [["First", 1], ["Second", 2]]
11
- # mapper = OptionMapper.new(collection)
11
+ # mapper = ChoicesMapper.new(collection)
12
12
  # mapper.each { |value, label| puts "#{value}: #{label}" }
13
13
  #
14
14
  # @example Using with ActiveRecord objects
15
15
  # users = User.all
16
- # mapper = OptionMapper.new(users)
16
+ # mapper = ChoicesMapper.new(users)
17
17
  # mapper.each { |id, name| puts "#{id}: #{name}" }
18
18
  #
19
19
  # @example Array access with different value types
20
- # mapper = OptionMapper.new([["Integer", 1], ["String", "2"], ["Symbol", :three]])
20
+ # mapper = ChoicesMapper.new([["Integer", 1], ["String", "2"], ["Symbol", :three]])
21
21
  # puts mapper["1"] # Output: "Integer"
22
22
  # puts mapper["2"] # Output: "String"
23
23
  # puts mapper["three"] # Output: "Symbol"
24
24
  #
25
25
  # @note This class is thread-safe as it doesn't maintain mutable state.
26
- class OptionMapper
26
+ class ChoicesMapper
27
27
  include Enumerable
28
28
 
29
- # Initializes a new OptionMapper instance.
29
+ # Initializes a new ChoicesMapper instance.
30
30
  #
31
31
  # @param collection [#call, #to_a] The collection to be mapped.
32
32
  # @param label_method [Symbol, nil] The method to call on each object to get the label.
33
33
  # @param value_method [Symbol, nil] The method to call on each object to get the value.
34
34
  def initialize(collection, label_method: nil, value_method: nil)
35
- @raw_collection = collection
35
+ @collection = collection
36
36
  @label_method = label_method
37
37
  @value_method = value_method
38
38
  end
39
39
 
40
- # Iterates over the collection, yielding value-label pairs.
40
+ # Iterates over the choices, yielding value-label pairs.
41
41
  #
42
- # @yieldparam value [String] The string value for the current item.
43
- # @yieldparam label [String] The string label for the current item.
42
+ # @yieldparam value [String] The string value for the current choice.
43
+ # @yieldparam label [String] The string label for the current choice.
44
44
  # @return [Enumerator] If no block is given.
45
45
  def each(&)
46
- collection.each(&)
46
+ choices.each(&)
47
47
  end
48
48
 
49
- # @return [Array<String>] An array of all labels in the collection.
49
+ # @return [Array<String>] An array of all choice labels.
50
50
  def labels
51
- collection.values
51
+ choices.values
52
52
  end
53
53
 
54
- # @return [Array<String>] An array of all values in the collection.
54
+ # @return [Array<String>] An array of all choice values.
55
55
  def values
56
- collection.keys
56
+ choices.keys
57
57
  end
58
58
 
59
59
  # Retrieves the label for a given value.
@@ -61,22 +61,22 @@ module Phlexi
61
61
  # @param value [#to_s] The value to look up.
62
62
  # @return [String, nil] The label corresponding to the value, or nil if not found.
63
63
  def [](value)
64
- collection[value.to_s]
64
+ choices[value.to_s]
65
65
  end
66
66
 
67
67
  private
68
68
 
69
- # @return [Hash<String, String>] The materialized collection as a hash of string value => string label.
70
- def collection
71
- @collection ||= materialize_collection(@raw_collection)
69
+ # @return [Hash<String, String>] The choices as a hash of {"string value" => "string label"}.
70
+ def choices
71
+ @choices ||= materialize_choices(@collection)
72
72
  end
73
73
 
74
- # Converts the raw collection into a materialized hash.
74
+ # Converts a collection into a materialized hash of choices.
75
75
  #
76
76
  # @param collection [#call, #to_a] The collection to be materialized.
77
- # @return [Hash<String, String>] The materialized collection as a hash of string value => string label.
77
+ # @return [Hash<String, String>] The materialized choices as a hash of {"string value" => "string label"}.
78
78
  # @raise [ArgumentError] If the collection cannot be materialized into an enumerable.
79
- def materialize_collection(collection)
79
+ def materialize_choices(collection)
80
80
  case collection
81
81
  in Hash => hash
82
82
  hash.transform_keys(&:to_s).transform_values(&:to_s)
@@ -85,7 +85,7 @@ module Phlexi
85
85
  in Range => range
86
86
  range_to_hash(range)
87
87
  in Proc => proc
88
- materialize_collection(proc.call)
88
+ materialize_choices(proc.call)
89
89
  in Symbol
90
90
  raise ArgumentError, "Symbol collections are not supported in this context"
91
91
  in Set => set
@@ -94,7 +94,7 @@ module Phlexi
94
94
  array_to_hash(Array(collection))
95
95
  end
96
96
  rescue ArgumentError
97
- # Rails.logger.warn("Unhandled inclusion collection type: #{e}")
97
+ # Rails.logger.warn("Unhandled inclusion collection type: #{e}")TODO
98
98
  {}
99
99
  end
100
100
 
@@ -134,20 +134,20 @@ module Phlexi
134
134
  {value: :last, label: :first}
135
135
  else
136
136
  {
137
- value: @value_method || collection_value_methods.find { |m| sample.respond_to?(m) },
138
- label: @label_method || collection_label_methods.find { |m| sample.respond_to?(m) }
137
+ value: @value_method || choice_value_methods.find { |m| sample.respond_to?(m) },
138
+ label: @label_method || choice_label_methods.find { |m| sample.respond_to?(m) }
139
139
  }
140
140
  end
141
141
  end
142
142
 
143
- # @return [Array<Symbol>] An array of method names to try for collection values.
144
- def collection_value_methods
145
- @collection_value_methods ||= %i[id to_s].freeze
143
+ # @return [Array<Symbol>] An array of method names to try for choice values.
144
+ def choice_value_methods
145
+ @choice_value_methods ||= %i[to_value id to_s].freeze
146
146
  end
147
147
 
148
- # @return [Array<Symbol>] An array of method names to try for collection labels.
149
- def collection_label_methods
150
- @collection_label_methods ||= %i[to_label name title to_s].freeze
148
+ # @return [Array<Symbol>] An array of method names to try for choice labels.
149
+ def choice_label_methods
150
+ @choice_label_methods ||= %i[to_label name title to_s].freeze
151
151
  end
152
152
  end
153
153
  end
@@ -6,15 +6,15 @@ module Phlexi
6
6
  class CollectionCheckboxes < Base
7
7
  include Concerns::HandlesInput
8
8
  include Concerns::HandlesArrayInput
9
- include Concerns::HasOptions
9
+ include Concerns::AcceptsChoices
10
10
 
11
11
  def view_template
12
12
  div(**attributes.slice(:id, :class)) do
13
- field.repeated(option_mapper.values) do |builder|
13
+ field.repeated(choices.values) do |builder|
14
14
  render builder.hidden_field_tag if builder.index == 0
15
15
 
16
16
  field = builder.field(
17
- label: option_mapper[builder.key],
17
+ label: choices[builder.key],
18
18
  # We set the attributes here so they are applied to all input components even if the user decides to use a block
19
19
  input_attributes: {
20
20
  checked_value: builder.key,
@@ -5,15 +5,15 @@ module Phlexi
5
5
  module Components
6
6
  class CollectionRadioButtons < Base
7
7
  include Concerns::HandlesInput
8
- include Concerns::HasOptions
8
+ include Concerns::AcceptsChoices
9
9
 
10
10
  def view_template
11
11
  div(**attributes.slice(:id, :class)) do
12
- field.repeated(option_mapper.values) do |builder|
12
+ field.repeated(choices.values) do |builder|
13
13
  render builder.hidden_field_tag if builder.index == 0
14
14
 
15
15
  field = builder.field(
16
- label: option_mapper[builder.key],
16
+ label: choices[builder.key],
17
17
  # We set the attributes here so they are applied to all input components even if the user decides to use a block
18
18
  input_attributes: {
19
19
  checked_value: builder.key,
@@ -4,18 +4,18 @@ module Phlexi
4
4
  module Form
5
5
  module Components
6
6
  module Concerns
7
- module HasOptions
7
+ module AcceptsChoices
8
8
  protected
9
9
 
10
10
  def build_attributes
11
11
  super
12
- @collection = attributes.delete(:collection) || field.collection
12
+ @choice_collection = attributes.delete(:choices) || field.choices
13
13
  @label_method = attributes.delete(:label_method)
14
14
  @value_method = attributes.delete(:value_method)
15
15
  end
16
16
 
17
- def option_mapper
18
- @option_mapper ||= OptionMapper.new(@collection, label_method: @label_method, value_method: @value_method)
17
+ def choices
18
+ @choices ||= ChoicesMapper.new(@choice_collection, label_method: @label_method, value_method: @value_method)
19
19
  end
20
20
 
21
21
  def selected?(option)
@@ -28,7 +28,7 @@ module Phlexi
28
28
  end
29
29
 
30
30
  def normalize_simple_input(input_value)
31
- ([super] & option_mapper.values)[0]
31
+ ([super] & choices.values)[0]
32
32
  end
33
33
  end
34
34
  end
@@ -6,7 +6,7 @@ module Phlexi
6
6
  class Select < Base
7
7
  include Concerns::HandlesInput
8
8
  include Concerns::HandlesArrayInput
9
- include Concerns::HasOptions
9
+ include Concerns::AcceptsChoices
10
10
 
11
11
  def view_template
12
12
  input(type: :hidden, name: attributes[:name], value: "", autocomplete: "off", hidden: true) if include_hidden?
@@ -19,7 +19,7 @@ module Phlexi
19
19
  protected
20
20
 
21
21
  def options
22
- option_mapper.each do |value, label|
22
+ choices.each do |value, label|
23
23
  option(selected: selected?(value), value: value) { label }
24
24
  end
25
25
  end
@@ -3,27 +3,27 @@
3
3
  module Phlexi
4
4
  module Form
5
5
  module Options
6
- module Collection
7
- def collection(collection = nil)
8
- if collection.nil?
9
- options.fetch(:collection) { options[:collection] = infer_collection }
6
+ module Choices
7
+ def choices(choices = nil)
8
+ if choices.nil?
9
+ options.fetch(:choices) { options[:choices] = infer_choices }
10
10
  else
11
- options[:collection] = collection
11
+ options[:choices] = choices
12
12
  self
13
13
  end
14
14
  end
15
15
 
16
16
  private
17
17
 
18
- def infer_collection
18
+ def infer_choices
19
19
  if object.class.respond_to?(:defined_enums)
20
20
  return object.class.defined_enums.fetch(key.to_s).keys if object.class.defined_enums.key?(key.to_s)
21
21
  end
22
22
 
23
- collection_value_from_association || collection_value_from_validator
23
+ choices_from_association || choices_from_validator
24
24
  end
25
25
 
26
- def collection_value_from_association
26
+ def choices_from_association
27
27
  return unless association_reflection
28
28
 
29
29
  relation = association_reflection.klass.all
@@ -46,7 +46,7 @@ module Phlexi
46
46
  relation
47
47
  end
48
48
 
49
- def collection_value_from_validator
49
+ def choices_from_validator
50
50
  return unless has_validators?
51
51
 
52
52
  inclusion_validator = find_validator(:inclusion)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Phlexi
4
4
  module Form
5
- VERSION = "0.4.7"
5
+ VERSION = "0.5.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phlexi-form
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.7
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Froelich
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-10-27 00:00:00.000000000 Z
11
+ date: 2024-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: phlex
@@ -205,14 +205,15 @@ files:
205
205
  - lib/phlexi/form.rb
206
206
  - lib/phlexi/form/base.rb
207
207
  - lib/phlexi/form/builder.rb
208
+ - lib/phlexi/form/choices_mapper.rb
208
209
  - lib/phlexi/form/components/base.rb
209
210
  - lib/phlexi/form/components/checkbox.rb
210
211
  - lib/phlexi/form/components/collection_checkboxes.rb
211
212
  - lib/phlexi/form/components/collection_radio_buttons.rb
213
+ - lib/phlexi/form/components/concerns/accepts_choices.rb
212
214
  - lib/phlexi/form/components/concerns/extracts_input.rb
213
215
  - lib/phlexi/form/components/concerns/handles_array_input.rb
214
216
  - lib/phlexi/form/components/concerns/handles_input.rb
215
- - lib/phlexi/form/components/concerns/has_options.rb
216
217
  - lib/phlexi/form/components/concerns/submits_form.rb
217
218
  - lib/phlexi/form/components/error.rb
218
219
  - lib/phlexi/form/components/file_input.rb
@@ -228,9 +229,8 @@ files:
228
229
  - lib/phlexi/form/components/textarea.rb
229
230
  - lib/phlexi/form/components/wrapper.rb
230
231
  - lib/phlexi/form/html.rb
231
- - lib/phlexi/form/option_mapper.rb
232
232
  - lib/phlexi/form/options/autofocus.rb
233
- - lib/phlexi/form/options/collection.rb
233
+ - lib/phlexi/form/options/choices.rb
234
234
  - lib/phlexi/form/options/disabled.rb
235
235
  - lib/phlexi/form/options/errors.rb
236
236
  - lib/phlexi/form/options/hints.rb