phlexi-form 0.3.0 → 0.4.1
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 +4 -4
- data/README.md +1 -1
- data/gemfiles/default.gemfile.lock +34 -32
- data/gemfiles/rails_7.gemfile.lock +16 -18
- data/lib/phlexi/form/base.rb +18 -9
- data/lib/phlexi/form/builder.rb +297 -0
- data/lib/phlexi/form/components/base.rb +1 -1
- data/lib/phlexi/form/components/input.rb +16 -2
- data/lib/phlexi/form/components/select.rb +4 -0
- data/lib/phlexi/form/html.rb +18 -0
- data/lib/phlexi/form/{field_options → options}/autofocus.rb +1 -1
- data/lib/phlexi/form/{field_options → options}/collection.rb +6 -2
- data/lib/phlexi/form/{field_options → options}/disabled.rb +1 -1
- data/lib/phlexi/form/{field_options → options}/errors.rb +11 -11
- data/lib/phlexi/form/options/hints.rb +13 -0
- data/lib/phlexi/form/options/inferred_types.rb +32 -0
- data/lib/phlexi/form/{field_options → options}/length.rb +3 -3
- data/lib/phlexi/form/{field_options → options}/limit.rb +2 -2
- data/lib/phlexi/form/options/max.rb +55 -0
- data/lib/phlexi/form/options/min.rb +55 -0
- data/lib/phlexi/form/{field_options → options}/pattern.rb +2 -2
- data/lib/phlexi/form/{field_options → options}/readonly.rb +1 -1
- data/lib/phlexi/form/{field_options → options}/required.rb +2 -2
- data/lib/phlexi/form/options/step.rb +39 -0
- data/lib/phlexi/form/options/validators.rb +24 -0
- data/lib/phlexi/form/structure/field_collection.rb +9 -29
- data/lib/phlexi/form/structure/namespace.rb +2 -114
- data/lib/phlexi/form/structure/namespace_collection.rb +1 -32
- data/lib/phlexi/form/theme.rb +160 -0
- data/lib/phlexi/form/version.rb +1 -1
- data/lib/phlexi/form.rb +3 -6
- metadata +34 -23
- data/lib/phlexi/form/field_options/associations.rb +0 -21
- data/lib/phlexi/form/field_options/hints.rb +0 -26
- data/lib/phlexi/form/field_options/inferred_types.rb +0 -159
- data/lib/phlexi/form/field_options/labels.rb +0 -28
- data/lib/phlexi/form/field_options/min_max.rb +0 -92
- data/lib/phlexi/form/field_options/multiple.rb +0 -65
- data/lib/phlexi/form/field_options/placeholder.rb +0 -18
- data/lib/phlexi/form/field_options/themes.rb +0 -207
- data/lib/phlexi/form/field_options/validators.rb +0 -48
- data/lib/phlexi/form/structure/dom.rb +0 -62
- data/lib/phlexi/form/structure/field_builder.rb +0 -243
- data/lib/phlexi/form/structure/node.rb +0 -28
@@ -3,19 +3,7 @@
|
|
3
3
|
module Phlexi
|
4
4
|
module Form
|
5
5
|
module Structure
|
6
|
-
class NamespaceCollection <
|
7
|
-
include Enumerable
|
8
|
-
|
9
|
-
def initialize(key, parent:, collection: nil, &block)
|
10
|
-
raise ArgumentError, "block is required" unless block.present?
|
11
|
-
|
12
|
-
super(key, parent: parent)
|
13
|
-
|
14
|
-
@collection = collection
|
15
|
-
@block = block
|
16
|
-
each(&block)
|
17
|
-
end
|
18
|
-
|
6
|
+
class NamespaceCollection < Phlexi::Field::Structure::NamespaceCollection
|
19
7
|
def extract_input(params)
|
20
8
|
namespace = build_namespace(0)
|
21
9
|
@block.call(namespace)
|
@@ -23,25 +11,6 @@ module Phlexi
|
|
23
11
|
inputs = params[key].map { |param| namespace.extract_input([param]) }
|
24
12
|
{key => inputs}
|
25
13
|
end
|
26
|
-
|
27
|
-
private
|
28
|
-
|
29
|
-
def each(&)
|
30
|
-
namespaces.each(&)
|
31
|
-
end
|
32
|
-
|
33
|
-
# Builds and memoizes namespaces for the collection.
|
34
|
-
#
|
35
|
-
# @return [Array<Namespace>] An array of namespace objects.
|
36
|
-
def namespaces
|
37
|
-
@namespaces ||= @collection.map.with_index do |object, key|
|
38
|
-
build_namespace(key, object: object)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def build_namespace(index, **)
|
43
|
-
parent.class.new(index, parent: self, builder_klass: parent.builder_klass, **)
|
44
|
-
end
|
45
14
|
end
|
46
15
|
end
|
47
16
|
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
module Phlexi
|
2
|
+
module Form
|
3
|
+
class Theme < Phlexi::Field::Theme
|
4
|
+
def self.theme
|
5
|
+
@theme ||= {
|
6
|
+
# == Base
|
7
|
+
base: nil,
|
8
|
+
hint: nil,
|
9
|
+
error: nil,
|
10
|
+
full_error: :error,
|
11
|
+
wrapper: nil,
|
12
|
+
inner_wrapper: nil,
|
13
|
+
button: nil,
|
14
|
+
submit_button: :button,
|
15
|
+
|
16
|
+
# == Label
|
17
|
+
label: nil,
|
18
|
+
invalid_label: nil,
|
19
|
+
valid_label: nil,
|
20
|
+
neutral_label: nil,
|
21
|
+
|
22
|
+
# == Input
|
23
|
+
input: nil,
|
24
|
+
valid_input: nil,
|
25
|
+
invalid_input: nil,
|
26
|
+
neutral_input: nil,
|
27
|
+
|
28
|
+
# String
|
29
|
+
string: :input,
|
30
|
+
valid_string: :valid_input,
|
31
|
+
invalid_string: :invalid_input,
|
32
|
+
neutral_string: :neutral_input,
|
33
|
+
|
34
|
+
# Email
|
35
|
+
email: :input,
|
36
|
+
valid_email: :valid_input,
|
37
|
+
invalid_email: :invalid_input,
|
38
|
+
neutral_email: :neutral_input,
|
39
|
+
|
40
|
+
# Password
|
41
|
+
password: :input,
|
42
|
+
valid_password: :valid_input,
|
43
|
+
invalid_password: :invalid_input,
|
44
|
+
neutral_password: :neutral_input,
|
45
|
+
|
46
|
+
# Phone
|
47
|
+
phone: :input,
|
48
|
+
valid_phone: :valid_input,
|
49
|
+
invalid_phone: :invalid_input,
|
50
|
+
neutral_phone: :neutral_input,
|
51
|
+
|
52
|
+
# Color
|
53
|
+
color: :input,
|
54
|
+
valid_color: :valid_input,
|
55
|
+
invalid_color: :invalid_input,
|
56
|
+
neutral_color: :neutral_input,
|
57
|
+
|
58
|
+
# Url
|
59
|
+
url: :input,
|
60
|
+
valid_url: :valid_input,
|
61
|
+
invalid_url: :invalid_input,
|
62
|
+
neutral_url: :neutral_input,
|
63
|
+
|
64
|
+
# Search
|
65
|
+
search: :input,
|
66
|
+
valid_search: :valid_input,
|
67
|
+
invalid_search: :invalid_input,
|
68
|
+
neutral_search: :neutral_input,
|
69
|
+
|
70
|
+
# Number
|
71
|
+
number: :input,
|
72
|
+
valid_number: :valid_input,
|
73
|
+
invalid_number: :invalid_input,
|
74
|
+
neutral_number: :neutral_input,
|
75
|
+
|
76
|
+
# Date
|
77
|
+
date: :input,
|
78
|
+
valid_date: :valid_input,
|
79
|
+
invalid_date: :invalid_input,
|
80
|
+
neutral_date: :neutral_input,
|
81
|
+
|
82
|
+
# Time
|
83
|
+
time: :input,
|
84
|
+
valid_time: :valid_input,
|
85
|
+
invalid_time: :invalid_input,
|
86
|
+
neutral_time: :neutral_input,
|
87
|
+
|
88
|
+
# DateTime
|
89
|
+
datetime: :input,
|
90
|
+
valid_datetime: :valid_input,
|
91
|
+
invalid_datetime: :invalid_input,
|
92
|
+
neutral_datetime: :neutral_input,
|
93
|
+
|
94
|
+
# Checkbox
|
95
|
+
checkbox: :input,
|
96
|
+
valid_checkbox: :valid_input,
|
97
|
+
invalid_checkbox: :invalid_input,
|
98
|
+
neutral_checkbox: :neutral_input,
|
99
|
+
|
100
|
+
# Boolean
|
101
|
+
boolan: :checkbox,
|
102
|
+
valid_boolan: :valid_checkbox,
|
103
|
+
invalid_boolan: :invalid_checkbox,
|
104
|
+
neutral_boolan: :neutral_checkbox,
|
105
|
+
|
106
|
+
# Textarea
|
107
|
+
textarea: :input,
|
108
|
+
valid_textarea: :valid_input,
|
109
|
+
invalid_textarea: :invalid_input,
|
110
|
+
neutral_textarea: :neutral_input,
|
111
|
+
|
112
|
+
# Hstore
|
113
|
+
hstore: :textarea,
|
114
|
+
valid_hstore: :valid_textarea,
|
115
|
+
invalid_hstore: :invalid_textarea,
|
116
|
+
neutral_hstore: :neutral_textarea,
|
117
|
+
|
118
|
+
# Select
|
119
|
+
select: :input,
|
120
|
+
valid_select: :valid_input,
|
121
|
+
invalid_select: :invalid_input,
|
122
|
+
neutral_select: :neutral_input,
|
123
|
+
|
124
|
+
# File
|
125
|
+
file: :input,
|
126
|
+
valid_file: :valid_input,
|
127
|
+
invalid_file: :invalid_input,
|
128
|
+
neutral_file: :neutral_input
|
129
|
+
|
130
|
+
}.freeze
|
131
|
+
end
|
132
|
+
|
133
|
+
# Resolves the theme for a component based on its current validity state
|
134
|
+
#
|
135
|
+
# This method determines the validity state of the field (valid, invalid, or neutral)
|
136
|
+
# and returns the corresponding theme by prepending the state to the component name.
|
137
|
+
#
|
138
|
+
# @param property [Symbol, String] The base theme property to resolve
|
139
|
+
# @return [String, nil] The resolved validity-specific theme or nil if not found
|
140
|
+
#
|
141
|
+
# @example Resolving a validity theme
|
142
|
+
# # Assuming the field has errors and the theme includes { invalid_input: "error-class" }
|
143
|
+
# resolve_validity_theme(:input)
|
144
|
+
# # => "error-class"
|
145
|
+
def resolve_validity_theme(property, field)
|
146
|
+
return unless field
|
147
|
+
|
148
|
+
validity_property = if field.has_errors?
|
149
|
+
:"invalid_#{property}"
|
150
|
+
elsif field.object_valid?
|
151
|
+
:"valid_#{property}"
|
152
|
+
else
|
153
|
+
:"neutral_#{property}"
|
154
|
+
end
|
155
|
+
|
156
|
+
resolve_theme(validity_property)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
data/lib/phlexi/form/version.rb
CHANGED
data/lib/phlexi/form.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require "zeitwerk"
|
4
4
|
require "phlex"
|
5
|
+
require "phlexi-field"
|
5
6
|
require "active_support/core_ext/object/blank"
|
6
7
|
|
7
8
|
module Phlexi
|
@@ -11,21 +12,17 @@ module Phlexi
|
|
11
12
|
loader.inflector.inflect(
|
12
13
|
"phlexi-form" => "Phlexi",
|
13
14
|
"phlexi" => "Phlexi",
|
14
|
-
"
|
15
|
+
"html" => "HTML"
|
15
16
|
)
|
16
17
|
loader.push_dir(File.expand_path("..", __dir__))
|
17
18
|
loader.ignore(File.expand_path("../generators", __dir__))
|
18
19
|
loader.setup
|
19
20
|
end
|
20
21
|
|
21
|
-
COMPONENT_BASE = (defined?(::ApplicationComponent) ? ::ApplicationComponent : Phlex::HTML)
|
22
|
-
|
23
|
-
NIL_VALUE = :__i_phlexi_form_nil_value_i__
|
24
|
-
|
25
22
|
class Error < StandardError; end
|
26
23
|
end
|
27
24
|
end
|
28
25
|
|
29
26
|
def Phlexi.Form(...)
|
30
|
-
Phlexi::Form::Base.
|
27
|
+
Phlexi::Form::Base.inline(...)
|
31
28
|
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
|
+
version: 0.4.1
|
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-09-
|
11
|
+
date: 2024-09-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: phlex
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.11'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: phlexi-field
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: activesupport
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -190,6 +204,7 @@ files:
|
|
190
204
|
- lib/phlexi-form.rb
|
191
205
|
- lib/phlexi/form.rb
|
192
206
|
- lib/phlexi/form/base.rb
|
207
|
+
- lib/phlexi/form/builder.rb
|
193
208
|
- lib/phlexi/form/components/base.rb
|
194
209
|
- lib/phlexi/form/components/checkbox.rb
|
195
210
|
- lib/phlexi/form/components/collection_checkboxes.rb
|
@@ -211,31 +226,27 @@ files:
|
|
211
226
|
- lib/phlexi/form/components/submit_button.rb
|
212
227
|
- lib/phlexi/form/components/textarea.rb
|
213
228
|
- lib/phlexi/form/components/wrapper.rb
|
214
|
-
- lib/phlexi/form/
|
215
|
-
- lib/phlexi/form/field_options/autofocus.rb
|
216
|
-
- lib/phlexi/form/field_options/collection.rb
|
217
|
-
- lib/phlexi/form/field_options/disabled.rb
|
218
|
-
- lib/phlexi/form/field_options/errors.rb
|
219
|
-
- lib/phlexi/form/field_options/hints.rb
|
220
|
-
- lib/phlexi/form/field_options/inferred_types.rb
|
221
|
-
- lib/phlexi/form/field_options/labels.rb
|
222
|
-
- lib/phlexi/form/field_options/length.rb
|
223
|
-
- lib/phlexi/form/field_options/limit.rb
|
224
|
-
- lib/phlexi/form/field_options/min_max.rb
|
225
|
-
- lib/phlexi/form/field_options/multiple.rb
|
226
|
-
- lib/phlexi/form/field_options/pattern.rb
|
227
|
-
- lib/phlexi/form/field_options/placeholder.rb
|
228
|
-
- lib/phlexi/form/field_options/readonly.rb
|
229
|
-
- lib/phlexi/form/field_options/required.rb
|
230
|
-
- lib/phlexi/form/field_options/themes.rb
|
231
|
-
- lib/phlexi/form/field_options/validators.rb
|
229
|
+
- lib/phlexi/form/html.rb
|
232
230
|
- lib/phlexi/form/option_mapper.rb
|
233
|
-
- lib/phlexi/form/
|
234
|
-
- lib/phlexi/form/
|
231
|
+
- lib/phlexi/form/options/autofocus.rb
|
232
|
+
- lib/phlexi/form/options/collection.rb
|
233
|
+
- lib/phlexi/form/options/disabled.rb
|
234
|
+
- lib/phlexi/form/options/errors.rb
|
235
|
+
- lib/phlexi/form/options/hints.rb
|
236
|
+
- lib/phlexi/form/options/inferred_types.rb
|
237
|
+
- lib/phlexi/form/options/length.rb
|
238
|
+
- lib/phlexi/form/options/limit.rb
|
239
|
+
- lib/phlexi/form/options/max.rb
|
240
|
+
- lib/phlexi/form/options/min.rb
|
241
|
+
- lib/phlexi/form/options/pattern.rb
|
242
|
+
- lib/phlexi/form/options/readonly.rb
|
243
|
+
- lib/phlexi/form/options/required.rb
|
244
|
+
- lib/phlexi/form/options/step.rb
|
245
|
+
- lib/phlexi/form/options/validators.rb
|
235
246
|
- lib/phlexi/form/structure/field_collection.rb
|
236
247
|
- lib/phlexi/form/structure/namespace.rb
|
237
248
|
- lib/phlexi/form/structure/namespace_collection.rb
|
238
|
-
- lib/phlexi/form/
|
249
|
+
- lib/phlexi/form/theme.rb
|
239
250
|
- lib/phlexi/form/version.rb
|
240
251
|
- sig/phlexi/form.rbs
|
241
252
|
homepage: https://github.com/radioactive-labs/phlexi-form
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlexi
|
4
|
-
module Form
|
5
|
-
module FieldOptions
|
6
|
-
module Associations
|
7
|
-
protected
|
8
|
-
|
9
|
-
def association_reflection
|
10
|
-
@association_reflection ||= find_association_reflection
|
11
|
-
end
|
12
|
-
|
13
|
-
def find_association_reflection
|
14
|
-
if object.class.respond_to?(:reflect_on_association)
|
15
|
-
object.class.reflect_on_association(key)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlexi
|
4
|
-
module Form
|
5
|
-
module FieldOptions
|
6
|
-
module Hints
|
7
|
-
def hint(hint = nil)
|
8
|
-
if hint.nil?
|
9
|
-
options[:hint]
|
10
|
-
else
|
11
|
-
options[:hint] = hint
|
12
|
-
self
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def has_hint?
|
17
|
-
hint.present?
|
18
|
-
end
|
19
|
-
|
20
|
-
def show_hint?
|
21
|
-
has_hint? && !show_errors?
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,159 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "bigdecimal"
|
4
|
-
|
5
|
-
module Phlexi
|
6
|
-
module Form
|
7
|
-
module FieldOptions
|
8
|
-
module InferredTypes
|
9
|
-
def inferred_db_type
|
10
|
-
@inferred_db_type ||= infer_db_type
|
11
|
-
end
|
12
|
-
|
13
|
-
# This will give you the component type e.g. input, textarea, select
|
14
|
-
def inferred_component_type
|
15
|
-
@inferred_component_type ||= infer_component_type
|
16
|
-
end
|
17
|
-
|
18
|
-
# This will give you the subtype of the input component e.g input type="text|date|checkbox" etc
|
19
|
-
def inferred_input_component_subtype
|
20
|
-
@inferred_input_component_subtype ||= infer_input_component_subtype(inferred_component_type)
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
# this returns the element type
|
26
|
-
# one of :input, :textarea, :select
|
27
|
-
def infer_component_type
|
28
|
-
return :select unless collection.nil?
|
29
|
-
|
30
|
-
case inferred_db_type
|
31
|
-
when :text, :json, :jsonb, :hstore
|
32
|
-
:textarea
|
33
|
-
else
|
34
|
-
:input
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
# this only applies when input_component is `:input`
|
39
|
-
# resolves the type attribute of input components
|
40
|
-
def infer_input_component_subtype(component)
|
41
|
-
case inferred_db_type
|
42
|
-
when :string
|
43
|
-
infer_string_input_type(key)
|
44
|
-
when :integer, :float, :decimal
|
45
|
-
:number
|
46
|
-
when :date
|
47
|
-
:date
|
48
|
-
when :datetime
|
49
|
-
:datetime
|
50
|
-
when :time
|
51
|
-
:time
|
52
|
-
when :boolean
|
53
|
-
:checkbox
|
54
|
-
else
|
55
|
-
:text
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def infer_db_type
|
60
|
-
if object.class.respond_to?(:columns_hash)
|
61
|
-
# ActiveRecord object
|
62
|
-
column = object.class.columns_hash[key.to_s]
|
63
|
-
return column.type if column
|
64
|
-
end
|
65
|
-
|
66
|
-
if object.class.respond_to?(:attribute_types)
|
67
|
-
# ActiveModel::Attributes
|
68
|
-
custom_type = object.class.attribute_types[key.to_s]
|
69
|
-
return custom_type.type if custom_type&.type
|
70
|
-
end
|
71
|
-
|
72
|
-
# Check if object responds to the key
|
73
|
-
if object.respond_to?(key)
|
74
|
-
# Fallback to inferring type from the value
|
75
|
-
return infer_db_type_from_value(object.send(key))
|
76
|
-
end
|
77
|
-
|
78
|
-
# Default to string if we can't determine the type
|
79
|
-
:string
|
80
|
-
end
|
81
|
-
|
82
|
-
def infer_db_type_from_value(value)
|
83
|
-
case value
|
84
|
-
when Integer
|
85
|
-
:integer
|
86
|
-
when Float
|
87
|
-
:float
|
88
|
-
when BigDecimal
|
89
|
-
:decimal
|
90
|
-
when TrueClass, FalseClass
|
91
|
-
:boolean
|
92
|
-
when Date
|
93
|
-
:date
|
94
|
-
when Time, DateTime
|
95
|
-
:datetime
|
96
|
-
else
|
97
|
-
:string
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
def infer_string_input_type(key)
|
102
|
-
key = key.to_s.downcase
|
103
|
-
|
104
|
-
return :password if is_password_field?
|
105
|
-
|
106
|
-
custom_type = custom_string_input_type(key)
|
107
|
-
return custom_type if custom_type
|
108
|
-
|
109
|
-
if has_validators?
|
110
|
-
infer_string_input_type_from_validations
|
111
|
-
else
|
112
|
-
:text
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def custom_string_input_type(key)
|
117
|
-
custom_mappings = {
|
118
|
-
/url$|^link|^site/ => :url,
|
119
|
-
/^email/ => :email,
|
120
|
-
/^search/ => :search,
|
121
|
-
/phone|tel(ephone)?/ => :tel,
|
122
|
-
/^time/ => :time,
|
123
|
-
/^date/ => :date,
|
124
|
-
/^number|_count$|_amount$/ => :number,
|
125
|
-
/^color/ => :color
|
126
|
-
}
|
127
|
-
|
128
|
-
custom_mappings.each do |pattern, type|
|
129
|
-
return type if key.match?(pattern)
|
130
|
-
end
|
131
|
-
|
132
|
-
nil
|
133
|
-
end
|
134
|
-
|
135
|
-
def infer_string_input_type_from_validations
|
136
|
-
if attribute_validators.find { |v| v.kind == :numericality }
|
137
|
-
:number
|
138
|
-
elsif attribute_validators.find { |v| v.kind == :format && v.options[:with] == URI::MailTo::EMAIL_REGEXP }
|
139
|
-
:email
|
140
|
-
else
|
141
|
-
:text
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
def is_password_field?
|
146
|
-
key = self.key.to_s.downcase
|
147
|
-
|
148
|
-
exact_matches = ["password"]
|
149
|
-
prefixes = ["encrypted_"]
|
150
|
-
suffixes = ["_password", "_digest", "_hash"]
|
151
|
-
|
152
|
-
exact_matches.include?(key) ||
|
153
|
-
prefixes.any? { |prefix| key.start_with?(prefix) } ||
|
154
|
-
suffixes.any? { |suffix| key.end_with?(suffix) }
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlexi
|
4
|
-
module Form
|
5
|
-
module FieldOptions
|
6
|
-
module Labels
|
7
|
-
def label(label = nil)
|
8
|
-
if label.nil?
|
9
|
-
options[:label] = options.fetch(:label) { calculate_label }
|
10
|
-
else
|
11
|
-
options[:label] = label
|
12
|
-
self
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def calculate_label
|
19
|
-
if object.class.respond_to?(:human_attribute_name)
|
20
|
-
object.class.human_attribute_name(key.to_s, {base: object})
|
21
|
-
else
|
22
|
-
key.to_s.humanize
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,92 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlexi
|
4
|
-
module Form
|
5
|
-
module FieldOptions
|
6
|
-
module MinMax
|
7
|
-
def min(min_value = nil)
|
8
|
-
if min_value.nil?
|
9
|
-
options[:min] = options.fetch(:min) { calculate_min }
|
10
|
-
else
|
11
|
-
options[:min] = min_value
|
12
|
-
self
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def max(max_value = nil)
|
17
|
-
if max_value.nil?
|
18
|
-
options[:max] = options.fetch(:max) { calculate_max }
|
19
|
-
else
|
20
|
-
options[:max] = max_value
|
21
|
-
self
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def step
|
26
|
-
1 if min || max
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def calculate_min
|
32
|
-
if (numericality_validator = find_numericality_validator)
|
33
|
-
get_min_from_validator(numericality_validator)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def calculate_max
|
38
|
-
if (numericality_validator = find_numericality_validator)
|
39
|
-
get_max_from_validator(numericality_validator)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def find_numericality_validator
|
44
|
-
find_validator(:numericality)
|
45
|
-
end
|
46
|
-
|
47
|
-
def get_min_from_validator(validator)
|
48
|
-
options = validator.options
|
49
|
-
min = if options.key?(:greater_than)
|
50
|
-
{value: options[:greater_than], exclusive: true}
|
51
|
-
elsif options.key?(:greater_than_or_equal_to)
|
52
|
-
{value: options[:greater_than_or_equal_to], exclusive: false}
|
53
|
-
end
|
54
|
-
evaluate_and_adjust_min(min)
|
55
|
-
end
|
56
|
-
|
57
|
-
def get_max_from_validator(validator)
|
58
|
-
options = validator.options
|
59
|
-
max = if options.key?(:less_than)
|
60
|
-
{value: options[:less_than], exclusive: true}
|
61
|
-
elsif options.key?(:less_than_or_equal_to)
|
62
|
-
{value: options[:less_than_or_equal_to], exclusive: false}
|
63
|
-
end
|
64
|
-
evaluate_and_adjust_max(max)
|
65
|
-
end
|
66
|
-
|
67
|
-
def evaluate_and_adjust_min(min)
|
68
|
-
return nil unless min
|
69
|
-
|
70
|
-
value = evaluate_numericality_validator_option(min[:value])
|
71
|
-
min[:exclusive] ? value + 1 : value
|
72
|
-
end
|
73
|
-
|
74
|
-
def evaluate_and_adjust_max(max)
|
75
|
-
return nil unless max
|
76
|
-
|
77
|
-
value = evaluate_numericality_validator_option(max[:value])
|
78
|
-
max[:exclusive] ? value - 1 : value
|
79
|
-
end
|
80
|
-
|
81
|
-
def evaluate_numericality_validator_option(option)
|
82
|
-
case option
|
83
|
-
when Proc
|
84
|
-
option.arity.zero? ? option.call : option.call(object)
|
85
|
-
else
|
86
|
-
option
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|