phlexi-display 0.0.1 → 0.0.2
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/lib/phlexi/display/base.rb +35 -158
- data/lib/phlexi/display/components/base.rb +1 -14
- data/lib/phlexi/display/components/concerns/displays_value.rb +54 -0
- data/lib/phlexi/display/components/date_time.rb +49 -0
- data/lib/phlexi/display/components/{error.rb → description.rb} +5 -5
- data/lib/phlexi/display/components/hint.rb +1 -1
- data/lib/phlexi/display/components/label.rb +3 -15
- data/lib/phlexi/display/components/number.rb +37 -0
- data/lib/phlexi/display/components/placeholder.rb +15 -0
- data/lib/phlexi/display/components/string.rb +17 -0
- data/lib/phlexi/display/components/wrapper.rb +4 -18
- data/lib/phlexi/display/field_options/associations.rb +2 -2
- data/lib/phlexi/display/field_options/attachments.rb +21 -0
- data/lib/phlexi/display/field_options/description.rb +22 -0
- data/lib/phlexi/display/field_options/hints.rb +1 -1
- data/lib/phlexi/display/field_options/inferred_types.rb +26 -52
- data/lib/phlexi/display/field_options/{placeholder.rb → placeholders.rb} +2 -2
- data/lib/phlexi/display/field_options/themes.rb +45 -120
- data/lib/phlexi/display/structure/dom.rb +7 -27
- data/lib/phlexi/display/structure/field_builder.rb +75 -151
- data/lib/phlexi/display/structure/field_collection.rb +5 -20
- data/lib/phlexi/display/structure/namespace.rb +22 -34
- data/lib/phlexi/display/structure/namespace_collection.rb +1 -9
- data/lib/phlexi/display/structure/node.rb +9 -3
- data/lib/phlexi/display/version.rb +1 -1
- data/lib/phlexi/display.rb +0 -1
- metadata +11 -31
- data/lib/phlexi/display/components/checkbox.rb +0 -48
- data/lib/phlexi/display/components/collection_checkboxes.rb +0 -44
- data/lib/phlexi/display/components/collection_radio_buttons.rb +0 -35
- data/lib/phlexi/display/components/concerns/handles_array_input.rb +0 -21
- data/lib/phlexi/display/components/concerns/handles_input.rb +0 -53
- data/lib/phlexi/display/components/concerns/has_options.rb +0 -37
- data/lib/phlexi/display/components/concerns/submits_form.rb +0 -39
- data/lib/phlexi/display/components/file_input.rb +0 -32
- data/lib/phlexi/display/components/full_error.rb +0 -21
- data/lib/phlexi/display/components/input.rb +0 -84
- data/lib/phlexi/display/components/input_array.rb +0 -45
- data/lib/phlexi/display/components/radio_button.rb +0 -41
- data/lib/phlexi/display/components/select.rb +0 -69
- data/lib/phlexi/display/components/submit_button.rb +0 -41
- data/lib/phlexi/display/components/textarea.rb +0 -34
- data/lib/phlexi/display/field_options/autofocus.rb +0 -18
- data/lib/phlexi/display/field_options/collection.rb +0 -54
- data/lib/phlexi/display/field_options/disabled.rb +0 -18
- data/lib/phlexi/display/field_options/errors.rb +0 -92
- data/lib/phlexi/display/field_options/length.rb +0 -53
- data/lib/phlexi/display/field_options/limit.rb +0 -66
- data/lib/phlexi/display/field_options/min_max.rb +0 -92
- data/lib/phlexi/display/field_options/multiple.rb +0 -65
- data/lib/phlexi/display/field_options/pattern.rb +0 -38
- data/lib/phlexi/display/field_options/readonly.rb +0 -18
- data/lib/phlexi/display/field_options/required.rb +0 -37
- data/lib/phlexi/display/field_options/validators.rb +0 -48
@@ -14,26 +14,16 @@ module Phlexi
|
|
14
14
|
# @attr_accessor [Object] value The value of the field.
|
15
15
|
class FieldBuilder < Node
|
16
16
|
include Phlex::Helpers
|
17
|
-
include FieldOptions::Associations
|
18
17
|
include FieldOptions::Themes
|
19
|
-
include FieldOptions::
|
20
|
-
include FieldOptions::
|
21
|
-
include FieldOptions::Hints
|
22
|
-
include FieldOptions::Errors
|
18
|
+
include FieldOptions::Associations
|
19
|
+
include FieldOptions::Attachments
|
23
20
|
include FieldOptions::InferredTypes
|
24
|
-
include FieldOptions::
|
25
|
-
include FieldOptions::
|
26
|
-
include FieldOptions::
|
27
|
-
include FieldOptions::
|
28
|
-
|
29
|
-
|
30
|
-
include FieldOptions::Length
|
31
|
-
include FieldOptions::MinMax
|
32
|
-
include FieldOptions::Pattern
|
33
|
-
include FieldOptions::Multiple
|
34
|
-
include FieldOptions::Limit
|
35
|
-
|
36
|
-
attr_reader :dom, :options, :object, :input_attributes, :value
|
21
|
+
include FieldOptions::Labels
|
22
|
+
include FieldOptions::Placeholders
|
23
|
+
include FieldOptions::Description
|
24
|
+
# include FieldOptions::Hints
|
25
|
+
|
26
|
+
attr_reader :dom, :options, :object, :value
|
37
27
|
|
38
28
|
# Initializes a new FieldBuilder instance.
|
39
29
|
#
|
@@ -41,14 +31,12 @@ module Phlexi
|
|
41
31
|
# @param parent [Structure::Namespace] The parent object.
|
42
32
|
# @param object [Object, nil] The associated object.
|
43
33
|
# @param value [Object] The initial value for the field.
|
44
|
-
# @param input_attributes [Hash] Default attributes to apply to input fields.
|
45
34
|
# @param options [Hash] Additional options for the field.
|
46
|
-
def initialize(key, parent:, object: nil, value: NIL_VALUE,
|
35
|
+
def initialize(key, parent:, object: nil, value: NIL_VALUE, **options)
|
47
36
|
super(key, parent: parent)
|
48
37
|
|
49
38
|
@object = object
|
50
|
-
@value =
|
51
|
-
@input_attributes = input_attributes
|
39
|
+
@value = determine_value(value)
|
52
40
|
@options = options
|
53
41
|
@dom = Structure::DOM.new(field: self)
|
54
42
|
end
|
@@ -61,175 +49,111 @@ module Phlexi
|
|
61
49
|
create_component(Components::Label, :label, **attributes, &)
|
62
50
|
end
|
63
51
|
|
64
|
-
# Creates
|
65
|
-
#
|
66
|
-
# @param attributes [Hash] Additional attributes for the input.
|
67
|
-
# @return [Components::Input] The input component.
|
68
|
-
def input_tag(**attributes, &)
|
69
|
-
create_component(Components::Input, :input, **attributes, &)
|
70
|
-
end
|
71
|
-
|
72
|
-
def file_input_tag(**attributes, &)
|
73
|
-
create_component(Components::FileInput, :file, **attributes, &)
|
74
|
-
end
|
75
|
-
|
76
|
-
# Creates a checkbox tag for the field.
|
77
|
-
#
|
78
|
-
# @param attributes [Hash] Additional attributes for the checkbox.
|
79
|
-
# @return [Components::Checkbox] The checkbox component.
|
80
|
-
def checkbox_tag(**attributes, &)
|
81
|
-
create_component(Components::Checkbox, :checkbox, **attributes, &)
|
82
|
-
end
|
83
|
-
|
84
|
-
# Creates collection checkboxes for the field.
|
85
|
-
#
|
86
|
-
# @param attributes [Hash] Additional attributes for the collection checkboxes.
|
87
|
-
# @yield [block] The block to be executed for each checkbox.
|
88
|
-
# @return [Components::CollectionCheckboxes] The collection checkboxes component.
|
89
|
-
def collection_checkboxes_tag(**attributes, &)
|
90
|
-
create_component(Components::CollectionCheckboxes, :collection_checkboxes, **attributes, &)
|
91
|
-
end
|
92
|
-
|
93
|
-
# Creates a radio button tag for the field.
|
94
|
-
#
|
95
|
-
# @param attributes [Hash] Additional attributes for the radio button.
|
96
|
-
# @return [Components::RadioButton] The radio button component.
|
97
|
-
def radio_button_tag(**attributes, &)
|
98
|
-
create_component(Components::RadioButton, :radio, **attributes, &)
|
99
|
-
end
|
100
|
-
|
101
|
-
# Creates collection radio buttons for the field.
|
52
|
+
# Creates a Placeholder tag for the field.
|
102
53
|
#
|
103
|
-
# @param attributes [Hash] Additional attributes for the
|
104
|
-
# @
|
105
|
-
|
106
|
-
|
107
|
-
create_component(Components::CollectionRadioButtons, :collection_radio_buttons, **attributes, &)
|
54
|
+
# @param attributes [Hash] Additional attributes for the placeholder.
|
55
|
+
# @return [Components::Placeholder] The placeholder component.
|
56
|
+
def placeholder_tag(**attributes, &)
|
57
|
+
create_component(Components::Placeholder, :placeholder, **attributes, &)
|
108
58
|
end
|
109
59
|
|
110
|
-
# Creates a
|
60
|
+
# Creates a Description tag for the field.
|
111
61
|
#
|
112
|
-
# @param attributes [Hash] Additional attributes for the
|
113
|
-
# @return [Components::
|
114
|
-
def
|
115
|
-
create_component(Components::
|
62
|
+
# @param attributes [Hash] Additional attributes for the description.
|
63
|
+
# @return [Components::Description] The description component.
|
64
|
+
def description_tag(**attributes, &)
|
65
|
+
create_component(Components::Description, :description, **attributes, &)
|
116
66
|
end
|
117
67
|
|
118
|
-
# Creates a
|
68
|
+
# Creates a string display tag for the field.
|
119
69
|
#
|
120
|
-
# @param attributes [Hash] Additional attributes for the
|
121
|
-
# @return [Components::
|
122
|
-
def
|
123
|
-
create_component(
|
70
|
+
# @param attributes [Hash] Additional attributes for the string display.
|
71
|
+
# @return [Components::String] The string component.
|
72
|
+
def string_tag(**attributes, &)
|
73
|
+
create_component(Components::String, :string, **attributes, &)
|
124
74
|
end
|
125
75
|
|
126
|
-
|
127
|
-
|
128
|
-
|
76
|
+
# # Creates a text display tag for the field.
|
77
|
+
# #
|
78
|
+
# # @param attributes [Hash] Additional attributes for the text display.
|
79
|
+
# # @return [Components::Text] The text component.
|
80
|
+
# def text_tag(**attributes, &)
|
81
|
+
# create_component(Components::Text, :text, **attributes, &)
|
82
|
+
# end
|
129
83
|
|
130
|
-
# Creates a
|
84
|
+
# Creates a number display tag for the field.
|
131
85
|
#
|
132
|
-
# @param attributes [Hash] Additional attributes for the
|
133
|
-
# @return [Components::
|
134
|
-
def
|
135
|
-
create_component(Components::
|
86
|
+
# @param attributes [Hash] Additional attributes for the number display.
|
87
|
+
# @return [Components::Number] The number component.
|
88
|
+
def number_tag(**attributes, &)
|
89
|
+
create_component(Components::Number, :number, **attributes, &)
|
136
90
|
end
|
137
91
|
|
138
|
-
# Creates
|
92
|
+
# Creates a datetime display for the field.
|
139
93
|
#
|
140
|
-
# @param attributes [Hash] Additional attributes for the
|
141
|
-
# @return [Components::
|
142
|
-
def
|
143
|
-
create_component(Components::
|
144
|
-
end
|
145
|
-
|
146
|
-
# Creates a
|
147
|
-
#
|
148
|
-
# @param attributes [Hash] Additional attributes for the
|
149
|
-
# @return [Components::
|
150
|
-
def
|
151
|
-
|
152
|
-
end
|
94
|
+
# @param attributes [Hash] Additional attributes for the datetime display.
|
95
|
+
# @return [Components::DateTime] The datetime component.
|
96
|
+
def datetime_tag(**attributes, &)
|
97
|
+
create_component(Components::DateTime, :datetime, **attributes, &)
|
98
|
+
end
|
99
|
+
|
100
|
+
# # Creates a boolean display tag for the field.
|
101
|
+
# #
|
102
|
+
# # @param attributes [Hash] Additional attributes for the boolean display.
|
103
|
+
# # @return [Components::Boolean] The boolean component.
|
104
|
+
# def boolean_tag(**attributes, &)
|
105
|
+
# create_component(Components::Boolean, :boolean, **attributes, &)
|
106
|
+
# end
|
107
|
+
|
108
|
+
# # Creates an association display tag for the field.
|
109
|
+
# #
|
110
|
+
# # @param attributes [Hash] Additional attributes for the association display.
|
111
|
+
# # @return [Components::Association] The association component.
|
112
|
+
# def association_tag(**attributes, &)
|
113
|
+
# create_component(Components::Association, :association, **attributes, &)
|
114
|
+
# end
|
115
|
+
|
116
|
+
# # Creates an attachment display tag for the field.
|
117
|
+
# #
|
118
|
+
# # @param attributes [Hash] Additional attributes for the attachment display.
|
119
|
+
# # @return [Components::Attachment] The attachment component.
|
120
|
+
# def attachment_tag(**attributes, &)
|
121
|
+
# create_component(Components::Attachment, :attachment, **attributes, &)
|
122
|
+
# end
|
153
123
|
|
154
124
|
# Wraps the field with additional markup.
|
155
125
|
#
|
156
|
-
# @param inner [Hash] Attributes for the inner wrapper.
|
157
126
|
# @param attributes [Hash] Additional attributes for the wrapper.
|
158
127
|
# @yield [block] The block to be executed within the wrapper.
|
159
128
|
# @return [Components::Wrapper] The wrapper component.
|
160
|
-
def wrapped(
|
161
|
-
|
162
|
-
inner[:class] = inner.delete(:class) || themed(inner.delete(:theme) || :inner_wrapper)
|
163
|
-
Components::Wrapper.new(self, class: wrapper_class, inner: inner, **attributes, &)
|
129
|
+
def wrapped(**attributes, &)
|
130
|
+
create_component(Components::Wrapper, :wrapper, **attributes, &)
|
164
131
|
end
|
165
132
|
|
166
|
-
# Creates a
|
133
|
+
# Creates a repeated field collection.
|
167
134
|
#
|
168
|
-
# @param range [
|
135
|
+
# @param range [#each] The collection of items to generate displays for.
|
169
136
|
# @yield [block] The block to be executed for each item in the collection.
|
170
137
|
# @return [FieldCollection] The field collection.
|
171
|
-
def
|
172
|
-
FieldCollection.new(field: self,
|
173
|
-
end
|
174
|
-
|
175
|
-
# Creates a submit button
|
176
|
-
#
|
177
|
-
# @param attributes [Hash] Additional attributes for the submit.
|
178
|
-
# @return [Components::SubmitButton] The submit button component.
|
179
|
-
def submit_button_tag(**attributes, &)
|
180
|
-
create_component(Components::SubmitButton, :submit_button, **attributes, &)
|
181
|
-
end
|
182
|
-
|
183
|
-
def extract_input(params)
|
184
|
-
raise "field##{dom.name} did not define an input component" unless @field_input_component
|
185
|
-
|
186
|
-
@field_input_component.extract_input(params)
|
138
|
+
def repeated(collection = [], &)
|
139
|
+
FieldCollection.new(field: self, collection:, &)
|
187
140
|
end
|
188
141
|
|
189
142
|
protected
|
190
143
|
|
191
144
|
def create_component(component_class, theme_key, **attributes, &)
|
192
|
-
|
193
|
-
raise "input component already defined: #{@field_input_component.inspect}" if @field_input_component
|
194
|
-
|
195
|
-
attributes = input_attributes.deep_merge(attributes)
|
196
|
-
@field_input_component = component_class.new(self, class: component_class_for(theme_key, attributes), **attributes, &)
|
197
|
-
else
|
198
|
-
component_class.new(self, class: component_class_for(theme_key, attributes), **attributes, &)
|
199
|
-
end
|
145
|
+
component_class.new(self, class: component_class_for(theme_key, attributes), **attributes, &)
|
200
146
|
end
|
201
147
|
|
202
148
|
def component_class_for(theme_key, attributes)
|
203
149
|
attributes.delete(:class) || themed(attributes.key?(:theme) ? attributes.delete(:theme) : theme_key)
|
204
150
|
end
|
205
151
|
|
206
|
-
def
|
207
|
-
value.present?
|
208
|
-
end
|
209
|
-
|
210
|
-
def determine_initial_value(value)
|
152
|
+
def determine_value(value)
|
211
153
|
return value unless value == NIL_VALUE
|
212
154
|
|
213
|
-
determine_from_association || determine_value_from_object
|
214
|
-
end
|
215
|
-
|
216
|
-
def determine_value_from_object
|
217
155
|
object.respond_to?(key) ? object.public_send(key) : nil
|
218
156
|
end
|
219
|
-
|
220
|
-
def determine_from_association
|
221
|
-
return nil unless reflection.present?
|
222
|
-
|
223
|
-
value = object.public_send(key)
|
224
|
-
case reflection.macro
|
225
|
-
when :has_many, :has_and_belongs_to_many
|
226
|
-
value&.map { |v| v.public_send(reflection.klass.primary_key) }
|
227
|
-
when :belongs_to, :has_one
|
228
|
-
value&.public_send(reflection.klass.primary_key)
|
229
|
-
else
|
230
|
-
raise ArgumentError, "Unsupported association type: #{reflection.macro}"
|
231
|
-
end
|
232
|
-
end
|
233
157
|
end
|
234
158
|
end
|
235
159
|
end
|
@@ -16,36 +16,21 @@ module Phlexi
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def field(**)
|
19
|
-
@field.class.new(key,
|
19
|
+
@field.class.new(key, **, parent: @field).tap do |field|
|
20
20
|
yield field if block_given?
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
24
|
-
def hidden_field_tag(value: "", force: false)
|
25
|
-
raise "Attempting to build hidden field on non-first field in a collection" unless index == 0 || force
|
26
|
-
|
27
|
-
@field.class
|
28
|
-
.new("hidden", parent: @field)
|
29
|
-
.input_tag(type: :hidden, value:)
|
30
|
-
end
|
31
23
|
end
|
32
24
|
|
33
|
-
def initialize(field:,
|
25
|
+
def initialize(field:, collection:, &)
|
34
26
|
@field = field
|
35
|
-
@
|
36
|
-
when Range, Array
|
37
|
-
range
|
38
|
-
when Integer
|
39
|
-
1..range
|
40
|
-
else
|
41
|
-
range.to_a
|
42
|
-
end
|
27
|
+
@collection = collection
|
43
28
|
each(&) if block_given?
|
44
29
|
end
|
45
30
|
|
46
31
|
def each(&)
|
47
|
-
@
|
48
|
-
yield Builder.new(
|
32
|
+
@collection.each.with_index do |item, index|
|
33
|
+
yield Builder.new(item, @field, index)
|
49
34
|
end
|
50
35
|
end
|
51
36
|
end
|
@@ -3,13 +3,18 @@
|
|
3
3
|
module Phlexi
|
4
4
|
module Display
|
5
5
|
module Structure
|
6
|
-
# A Namespace maps
|
6
|
+
# A Namespace maps an object to values, but doesn't actually have a value itself. For
|
7
7
|
# example, a `User` object or ActiveRecord model could be passed into the `:user` namespace.
|
8
|
-
# To access the values on a Namespace, the `field` can be called for single values.
|
9
8
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
9
|
+
# To access single values on a Namespace, #field can be used.
|
10
|
+
#
|
11
|
+
# To access nested objects within a namespace, two methods are available:
|
12
|
+
#
|
13
|
+
# 1. #nest_one: Used for single nested objects, such as if a `User belongs_to :profile` in
|
14
|
+
# ActiveRecord. This method returns another Namespace object.
|
15
|
+
#
|
16
|
+
# 2. #nest_many: Used for collections of nested objects, such as if a `User has_many :addresses` in
|
17
|
+
# ActiveRecord. This method returns a NamespaceCollection object.
|
13
18
|
class Namespace < Structure::Node
|
14
19
|
include Enumerable
|
15
20
|
|
@@ -29,21 +34,17 @@ module Phlexi
|
|
29
34
|
end
|
30
35
|
end
|
31
36
|
|
32
|
-
def submit_button(key = nil, **attributes, &)
|
33
|
-
field(key || SecureRandom.hex).submit_button_tag(**attributes, &)
|
34
|
-
end
|
35
|
-
|
36
37
|
# Creates a `Namespace` child instance with the parent set to the current instance, adds to
|
37
38
|
# the `@children` Hash to ensure duplicate child namespaces aren't created, then calls the
|
38
39
|
# method on the `@object` to get the child object to pass into that namespace.
|
39
40
|
#
|
40
41
|
# For example, if a `User#permission` returns a `Permission` object, we could map that to a
|
41
|
-
#
|
42
|
+
# display like this:
|
42
43
|
#
|
43
44
|
# ```ruby
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
45
|
+
# Phlexi::Display(user) do |display|
|
46
|
+
# display.nest_one :profile do |profile|
|
47
|
+
# render profile.field(:gender).text
|
47
48
|
# end
|
48
49
|
# end
|
49
50
|
# ```
|
@@ -56,13 +57,13 @@ module Phlexi
|
|
56
57
|
# an enumerable or array of `Address` classes:
|
57
58
|
#
|
58
59
|
# ```ruby
|
59
|
-
# Phlexi::Display
|
60
|
-
# render
|
61
|
-
# render
|
62
|
-
#
|
63
|
-
# render address.field(:street).
|
64
|
-
# render address.field(:state).
|
65
|
-
# render address.field(:zip).
|
60
|
+
# Phlexi::Display(user) do |display|
|
61
|
+
# render display.field(:email).text
|
62
|
+
# render display.field(:name).text
|
63
|
+
# display.nest_many :addresses do |address|
|
64
|
+
# render address.field(:street).text
|
65
|
+
# render address.field(:state).text
|
66
|
+
# render address.field(:zip).text
|
66
67
|
# end
|
67
68
|
# end
|
68
69
|
# ```
|
@@ -73,19 +74,6 @@ module Phlexi
|
|
73
74
|
create_child(key, NamespaceCollection, collection:, &)
|
74
75
|
end
|
75
76
|
|
76
|
-
def extract_input(params)
|
77
|
-
if params.is_a?(Array)
|
78
|
-
each_with_object({}) do |child, hash|
|
79
|
-
hash.merge! child.extract_input(params[0])
|
80
|
-
end
|
81
|
-
else
|
82
|
-
input = each_with_object({}) do |child, hash|
|
83
|
-
hash.merge! child.extract_input(params[key])
|
84
|
-
end
|
85
|
-
{key => input}
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
77
|
# Iterates through the children of the current namespace, which could be `Namespace` or `Field`
|
90
78
|
# objects.
|
91
79
|
def each(&)
|
@@ -105,7 +93,7 @@ module Phlexi
|
|
105
93
|
end
|
106
94
|
end
|
107
95
|
|
108
|
-
# Creates a root Namespace
|
96
|
+
# Creates a root Namespace
|
109
97
|
def self.root(*, builder_klass:, **, &)
|
110
98
|
new(*, parent: nil, builder_klass:, **, &)
|
111
99
|
end
|
@@ -16,14 +16,6 @@ module Phlexi
|
|
16
16
|
each(&block)
|
17
17
|
end
|
18
18
|
|
19
|
-
def extract_input(params)
|
20
|
-
namespace = build_namespace(0)
|
21
|
-
@block.call(namespace)
|
22
|
-
|
23
|
-
inputs = params[key].map { |param| namespace.extract_input([param]) }
|
24
|
-
{key => inputs}
|
25
|
-
end
|
26
|
-
|
27
19
|
private
|
28
20
|
|
29
21
|
def each(&)
|
@@ -32,7 +24,7 @@ module Phlexi
|
|
32
24
|
|
33
25
|
# Builds and memoizes namespaces for the collection.
|
34
26
|
#
|
35
|
-
# @return [Array<
|
27
|
+
# @return [Array<Namespace>] An array of namespace objects.
|
36
28
|
def namespaces
|
37
29
|
@namespaces ||= @collection.map.with_index do |object, key|
|
38
30
|
build_namespace(key, object: object)
|
@@ -3,13 +3,19 @@
|
|
3
3
|
module Phlexi
|
4
4
|
module Display
|
5
5
|
module Structure
|
6
|
-
# Superclass for Namespace and Field classes.
|
7
|
-
#
|
6
|
+
# Superclass for Namespace and Field classes. Represents a node in the display tree structure.
|
7
|
+
#
|
8
|
+
# @attr_reader [Symbol] key The node's key
|
9
|
+
# @attr_reader [Node, nil] parent The node's parent in the tree structure
|
8
10
|
class Node
|
9
11
|
attr_reader :key, :parent
|
10
12
|
|
13
|
+
# Initializes a new Node instance.
|
14
|
+
#
|
15
|
+
# @param key [Symbol, String] The key for the node
|
16
|
+
# @param parent [Node, nil] The parent node
|
11
17
|
def initialize(key, parent:)
|
12
|
-
@key = key
|
18
|
+
@key = :"#{key}"
|
13
19
|
@parent = parent
|
14
20
|
end
|
15
21
|
end
|
data/lib/phlexi/display.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: phlexi-display
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
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-08-
|
11
|
+
date: 2024-08-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: phlex
|
@@ -186,43 +186,23 @@ files:
|
|
186
186
|
- lib/phlexi/display.rb
|
187
187
|
- lib/phlexi/display/base.rb
|
188
188
|
- lib/phlexi/display/components/base.rb
|
189
|
-
- lib/phlexi/display/components/
|
190
|
-
- lib/phlexi/display/components/
|
191
|
-
- lib/phlexi/display/components/
|
192
|
-
- lib/phlexi/display/components/concerns/handles_array_input.rb
|
193
|
-
- lib/phlexi/display/components/concerns/handles_input.rb
|
194
|
-
- lib/phlexi/display/components/concerns/has_options.rb
|
195
|
-
- lib/phlexi/display/components/concerns/submits_form.rb
|
196
|
-
- lib/phlexi/display/components/error.rb
|
197
|
-
- lib/phlexi/display/components/file_input.rb
|
198
|
-
- lib/phlexi/display/components/full_error.rb
|
189
|
+
- lib/phlexi/display/components/concerns/displays_value.rb
|
190
|
+
- lib/phlexi/display/components/date_time.rb
|
191
|
+
- lib/phlexi/display/components/description.rb
|
199
192
|
- lib/phlexi/display/components/hint.rb
|
200
|
-
- lib/phlexi/display/components/input.rb
|
201
|
-
- lib/phlexi/display/components/input_array.rb
|
202
193
|
- lib/phlexi/display/components/label.rb
|
203
|
-
- lib/phlexi/display/components/
|
204
|
-
- lib/phlexi/display/components/
|
205
|
-
- lib/phlexi/display/components/
|
206
|
-
- lib/phlexi/display/components/textarea.rb
|
194
|
+
- lib/phlexi/display/components/number.rb
|
195
|
+
- lib/phlexi/display/components/placeholder.rb
|
196
|
+
- lib/phlexi/display/components/string.rb
|
207
197
|
- lib/phlexi/display/components/wrapper.rb
|
208
198
|
- lib/phlexi/display/field_options/associations.rb
|
209
|
-
- lib/phlexi/display/field_options/
|
210
|
-
- lib/phlexi/display/field_options/
|
211
|
-
- lib/phlexi/display/field_options/disabled.rb
|
212
|
-
- lib/phlexi/display/field_options/errors.rb
|
199
|
+
- lib/phlexi/display/field_options/attachments.rb
|
200
|
+
- lib/phlexi/display/field_options/description.rb
|
213
201
|
- lib/phlexi/display/field_options/hints.rb
|
214
202
|
- lib/phlexi/display/field_options/inferred_types.rb
|
215
203
|
- lib/phlexi/display/field_options/labels.rb
|
216
|
-
- lib/phlexi/display/field_options/
|
217
|
-
- lib/phlexi/display/field_options/limit.rb
|
218
|
-
- lib/phlexi/display/field_options/min_max.rb
|
219
|
-
- lib/phlexi/display/field_options/multiple.rb
|
220
|
-
- lib/phlexi/display/field_options/pattern.rb
|
221
|
-
- lib/phlexi/display/field_options/placeholder.rb
|
222
|
-
- lib/phlexi/display/field_options/readonly.rb
|
223
|
-
- lib/phlexi/display/field_options/required.rb
|
204
|
+
- lib/phlexi/display/field_options/placeholders.rb
|
224
205
|
- lib/phlexi/display/field_options/themes.rb
|
225
|
-
- lib/phlexi/display/field_options/validators.rb
|
226
206
|
- lib/phlexi/display/option_mapper.rb
|
227
207
|
- lib/phlexi/display/structure/dom.rb
|
228
208
|
- lib/phlexi/display/structure/field_builder.rb
|
@@ -1,48 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlexi
|
4
|
-
module Display
|
5
|
-
module Components
|
6
|
-
class Checkbox < Input
|
7
|
-
def view_template
|
8
|
-
input(type: :hidden, name: attributes[:name], value: @unchecked_value, autocomplete: "off", hidden: true) if include_hidden?
|
9
|
-
input(**attributes, value: @checked_value)
|
10
|
-
end
|
11
|
-
|
12
|
-
protected
|
13
|
-
|
14
|
-
def build_input_attributes
|
15
|
-
attributes[:type] = :checkbox
|
16
|
-
super
|
17
|
-
|
18
|
-
@include_hidden = attributes.delete(:include_hidden)
|
19
|
-
@checked_value = (attributes.key?(:checked_value) ? attributes.delete(:checked_value) : "1").to_s
|
20
|
-
@unchecked_value = (attributes.key?(:unchecked_value) ? attributes.delete(:unchecked_value) : "0").to_s
|
21
|
-
|
22
|
-
attributes[:value] = @checked_value
|
23
|
-
attributes[:checked] = attributes.fetch(:checked) { checked? }
|
24
|
-
end
|
25
|
-
|
26
|
-
def include_hidden?
|
27
|
-
@include_hidden != false
|
28
|
-
end
|
29
|
-
|
30
|
-
def checked?
|
31
|
-
return false if field.dom.value == @unchecked_value
|
32
|
-
|
33
|
-
if @checked_value == "1" # using default values
|
34
|
-
# handle nils, numbers and booleans
|
35
|
-
!["", "0", "false"].include?(field.dom.value)
|
36
|
-
else # custom value, so explicit match
|
37
|
-
field.dom.value == @checked_value
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def normalize_input(...)
|
42
|
-
input_value = super
|
43
|
-
[@checked_value, @unchecked_value].include?(input_value) ? input_value : @unchecked_value
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Phlexi
|
4
|
-
module Display
|
5
|
-
module Components
|
6
|
-
class CollectionCheckboxes < Base
|
7
|
-
include Concerns::HandlesInput
|
8
|
-
include Concerns::HandlesArrayInput
|
9
|
-
include Concerns::HasOptions
|
10
|
-
|
11
|
-
def view_template
|
12
|
-
div(**attributes.slice(:id, :class)) do
|
13
|
-
field.multi(option_mapper.values) do |builder|
|
14
|
-
render builder.hidden_field_tag if builder.index == 0
|
15
|
-
|
16
|
-
field = builder.field(
|
17
|
-
label: option_mapper[builder.key],
|
18
|
-
# We set the attributes here so they are applied to all input components even if the user decides to use a block
|
19
|
-
input_attributes: {
|
20
|
-
checked_value: builder.key,
|
21
|
-
include_hidden: false,
|
22
|
-
checked: selected?(builder.key)
|
23
|
-
}
|
24
|
-
)
|
25
|
-
if block_given?
|
26
|
-
yield field
|
27
|
-
else
|
28
|
-
render field.checkbox_tag
|
29
|
-
render field.label_tag
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
protected
|
36
|
-
|
37
|
-
def build_attributes
|
38
|
-
super
|
39
|
-
attributes[:multiple] = true
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|