phlexi-display 0.0.1 → 0.0.3

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/lib/phlexi/display/base.rb +37 -169
  3. data/lib/phlexi/display/builder.rb +117 -0
  4. data/lib/phlexi/display/components/base.rb +1 -42
  5. data/lib/phlexi/display/components/concerns/displays_value.rb +54 -0
  6. data/lib/phlexi/display/components/date_time.rb +49 -0
  7. data/lib/phlexi/display/components/{error.rb → description.rb} +5 -5
  8. data/lib/phlexi/display/components/hint.rb +1 -1
  9. data/lib/phlexi/display/components/label.rb +3 -15
  10. data/lib/phlexi/display/components/number.rb +37 -0
  11. data/lib/phlexi/display/components/placeholder.rb +15 -0
  12. data/lib/phlexi/display/components/string.rb +17 -0
  13. data/lib/phlexi/display/components/wrapper.rb +4 -18
  14. data/lib/phlexi/display/theme.rb +22 -0
  15. data/lib/phlexi/display/version.rb +1 -1
  16. data/lib/phlexi/display.rb +1 -1
  17. metadata +24 -43
  18. data/lib/phlexi/display/components/checkbox.rb +0 -48
  19. data/lib/phlexi/display/components/collection_checkboxes.rb +0 -44
  20. data/lib/phlexi/display/components/collection_radio_buttons.rb +0 -35
  21. data/lib/phlexi/display/components/concerns/handles_array_input.rb +0 -21
  22. data/lib/phlexi/display/components/concerns/handles_input.rb +0 -53
  23. data/lib/phlexi/display/components/concerns/has_options.rb +0 -37
  24. data/lib/phlexi/display/components/concerns/submits_form.rb +0 -39
  25. data/lib/phlexi/display/components/file_input.rb +0 -32
  26. data/lib/phlexi/display/components/full_error.rb +0 -21
  27. data/lib/phlexi/display/components/input.rb +0 -84
  28. data/lib/phlexi/display/components/input_array.rb +0 -45
  29. data/lib/phlexi/display/components/radio_button.rb +0 -41
  30. data/lib/phlexi/display/components/select.rb +0 -69
  31. data/lib/phlexi/display/components/submit_button.rb +0 -41
  32. data/lib/phlexi/display/components/textarea.rb +0 -34
  33. data/lib/phlexi/display/field_options/associations.rb +0 -21
  34. data/lib/phlexi/display/field_options/autofocus.rb +0 -18
  35. data/lib/phlexi/display/field_options/collection.rb +0 -54
  36. data/lib/phlexi/display/field_options/disabled.rb +0 -18
  37. data/lib/phlexi/display/field_options/errors.rb +0 -92
  38. data/lib/phlexi/display/field_options/hints.rb +0 -22
  39. data/lib/phlexi/display/field_options/inferred_types.rb +0 -155
  40. data/lib/phlexi/display/field_options/labels.rb +0 -28
  41. data/lib/phlexi/display/field_options/length.rb +0 -53
  42. data/lib/phlexi/display/field_options/limit.rb +0 -66
  43. data/lib/phlexi/display/field_options/min_max.rb +0 -92
  44. data/lib/phlexi/display/field_options/multiple.rb +0 -65
  45. data/lib/phlexi/display/field_options/pattern.rb +0 -38
  46. data/lib/phlexi/display/field_options/placeholder.rb +0 -18
  47. data/lib/phlexi/display/field_options/readonly.rb +0 -18
  48. data/lib/phlexi/display/field_options/required.rb +0 -37
  49. data/lib/phlexi/display/field_options/themes.rb +0 -207
  50. data/lib/phlexi/display/field_options/validators.rb +0 -48
  51. data/lib/phlexi/display/option_mapper.rb +0 -154
  52. data/lib/phlexi/display/structure/dom.rb +0 -62
  53. data/lib/phlexi/display/structure/field_builder.rb +0 -236
  54. data/lib/phlexi/display/structure/field_collection.rb +0 -54
  55. data/lib/phlexi/display/structure/namespace.rb +0 -135
  56. data/lib/phlexi/display/structure/namespace_collection.rb +0 -48
  57. data/lib/phlexi/display/structure/node.rb +0 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b140e54c49ca3a4a8808a12bb7a91dd8d250c91e2d7d29a8d7f9be2c20a7dbf5
4
- data.tar.gz: 9c70cec19581873bb9b93fc887571d6c8d5d65c95a25576bdf26a67e2bb30046
3
+ metadata.gz: 3de078e9bdc0e066c1b4f3af7b9b8ef966faf1fec3779358b79fb969ff6ebdf8
4
+ data.tar.gz: 3ac581e38926c8adaf04ce1b312741d1978d7223aa83df42c18723db7be8382b
5
5
  SHA512:
6
- metadata.gz: 466d34728adaedd7c4669a7419ec53929e49e1b4466135e5a7cc1eb42c88aa196b344ca4e29d8f27fb56a1e83437500678a2b003ca95fc82bbf70ab1ad017afc
7
- data.tar.gz: 047a28cd2c6afba47d9b6c8a833437ac2c009e626f747663dc9f506ef8d805b7979b8f59e4b0fe6e59a8180538d7e66cf323aba83e26e671e567ff12a3236a2c
6
+ metadata.gz: a90ec354ee5aa5a18156b6dff6e5c4b0b5220adf2a11e94004595cba305723d8398de25d6e356e0381305378800e48b188404c0c13fd42c597ead9937760eea1
7
+ data.tar.gz: 3f7a054aa04d8b3862e618370035fed1d89725fcde4ae13792122085c6301f0ea664c8c7064986ad629a7caab367617200f1677f84ef4fd473bd62393edde3d4
@@ -1,98 +1,72 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/module/delegation"
4
- require "active_support/string_inquirer"
5
- require "active_support/core_ext/hash/deep_merge"
6
4
  require "active_support/core_ext/string/inflections"
7
5
 
8
6
  module Phlexi
9
7
  module Display
10
- # A form component for building flexible and customizable forms.
8
+ # A display component for rendering flexible and customizable data views.
11
9
  #
12
10
  # @example Basic usage
13
- # Phlexi::Display.new(user, action: '/users', method: 'post') do |f|
14
- # render field(:name).placeholder("Name").input_tag
15
- # render field(:email).placeholder("Email").input_tag
11
+ # Phlexi::Display.new(user) do |d|
12
+ # render d.field(:name).text
13
+ # render d.field(:email).text
16
14
  # end
17
15
  #
18
- # @attr_reader [Symbol] key The form's key, derived from the record or explicitly set
19
- # @attr_reader [ActiveModel::Model, nil] object The form's associated object
16
+ # @attr_reader [Symbol] key The display's key, derived from the record or explicitly set
17
+ # @attr_reader [ActiveModel::Model, nil] object The display's associated object
20
18
  class Base < COMPONENT_BASE
21
- class Namespace < Structure::Namespace; end
19
+ class Namespace < Phlexi::Field::Structure::Namespace; end
22
20
 
23
- class FieldBuilder < Structure::FieldBuilder; end
21
+ class Builder < Builder; end
24
22
 
25
23
  attr_reader :key, :object
26
24
 
27
- delegate :field, :submit_button, :nest_one, :nest_many, to: :@namespace
25
+ delegate :field, :nest_one, :nest_many, to: :@namespace
28
26
 
29
27
  # Initializes a new Display instance.
30
28
  #
31
- # @param record [ActiveModel::Model, Symbol, String] The form's associated record or key
32
- # @param action [String, nil] The form's action URL
33
- # @param method [String, nil] The form's HTTP method
34
- # @param attributes [Hash] Additional HTML attributes for the form tag
35
- # @param options [Hash] Additional options for form configuration
36
- # @option options [String] :class CSS classes for the form
29
+ # @param record [ActiveModel::Model, Symbol, String] The display's associated record or key
30
+ # @param attributes [Hash] Additional HTML attributes for the display container
31
+ # @param options [Hash] Additional options for display configuration
32
+ # @option options [String] :class CSS classes for the display
37
33
  # @option options [Class] :namespace_klass Custom namespace class
38
34
  # @option options [Class] :builder_klass Custom field builder class
39
- def initialize(record, action: nil, method: nil, attributes: {}, **options)
40
- @form_action = action
41
- @form_method = method
42
- @form_class = options.delete(:class)
35
+ def initialize(record, attributes: {}, **options)
36
+ @display_class = options.delete(:class)
43
37
  @attributes = attributes
44
- @namespace_klass = options.delete(:namespace_klass) || default_namespace_klass
45
- @builder_klass = options.delete(:builder_klass) || default_builder_klass
38
+ @namespace_klass = options.delete(:namespace_klass) || self.class::Namespace
39
+ @builder_klass = options.delete(:builder_klass) || self.class::Builder
46
40
  @options = options
47
41
 
48
42
  initialize_object_and_key(record)
49
43
  initialize_namespace
50
- initialize_attributes
51
44
  end
52
45
 
53
- # Renders the form template.
46
+ # Renders the display template.
54
47
  #
55
48
  # @return [void]
56
49
  def view_template
57
- form_tag { form_template }
50
+ display_template
58
51
  end
59
52
 
60
- # Executes the form's content block.
61
- # Override this in subclasses to defie a static form.
53
+ # Executes the display's content block.
54
+ # Override this in subclasses to define a static display.
62
55
  #
63
56
  # @return [void]
64
- def form_template
57
+ def display_template
65
58
  instance_exec(&@_content_block) if @_content_block
66
59
  end
67
60
 
68
- # Renders the form tag with its contents.
69
- #
70
- # @yield The form's content
71
- # @return [void]
72
- def form_tag(&)
73
- form(**form_attributes) do
74
- render_hidden_method_field
75
- render_authenticity_token if authenticity_token?
76
- yield
77
- end
78
- end
79
-
80
- def extract_input(params)
81
- call unless @_rendered
82
- @namespace.extract_input(params)
83
- end
84
-
85
61
  protected
86
62
 
87
63
  attr_reader :options, :attributes, :namespace_klass, :builder_klass
88
64
 
89
65
  # Initializes the object and key based on the given record.
90
66
  #
91
- # @param record [ActiveModel::Model, Symbol, String] The form's associated record or key
67
+ # @param record [ActiveModel::Model, Symbol, String] The display's associated record or key
92
68
  # @return [void]
93
69
  def initialize_object_and_key(record)
94
- # always pop these keys
95
- # add support for `as` to make it more rails friendly
96
70
  @key = options.delete(:key) || options.delete(:as)
97
71
 
98
72
  case record
@@ -102,141 +76,35 @@ module Phlexi
102
76
  else
103
77
  @object = record
104
78
  if @key.nil?
105
- unless object.respond_to?(:model_name) && object.model_name.respond_to?(:param_key) && object.model_name.param_key.present?
106
- raise ArgumentError, "record must respond to #model_name.param_key with a non nil value or set `key` option e.g. Phlexi::Display(record, key: :record)"
79
+ @key = if object.respond_to?(:model_name) && object.model_name.respond_to?(:param_key) && object.model_name.param_key.present?
80
+ object.model_name.param_key
81
+ else
82
+ object.class.name.demodulize.underscore
107
83
  end
108
- @key = object.model_name.param_key
109
84
  end
110
85
  end
111
86
  @key = @key.to_sym
112
87
  end
113
88
 
114
- # Initializes the namespace for the form.
89
+ # Initializes the namespace for the display.
115
90
  #
116
91
  # @return [void]
117
92
  def initialize_namespace
118
93
  @namespace = namespace_klass.root(key, object: object, builder_klass: builder_klass)
119
94
  end
120
-
121
- # Initializes form attributes.
122
- #
123
- # @return [void]
124
- def initialize_attributes
125
- attributes.fetch(:accept_charset) { attributes[:accept_charset] = "UTF-8" }
126
- end
127
-
128
- # Determines the form's action URL.
129
- #
130
- # @return [String, nil] The form's action URL
131
- def form_action
132
- puts ""
133
- # if @form_action != false
134
- # @form_action ||= if options[:format].nil?
135
- # polymorphic_path(object, {})
136
- # else
137
- # polymorphic_path(object, format: options[:format])
138
- # end
139
- # end
140
- @form_action
141
- end
142
-
143
- # Determines the form's HTTP method.
95
+ # Retrieves the display's CSS classes.
144
96
  #
145
- # @return [ActiveSupport::StringInquirer] The form's HTTP method
146
- def form_method
147
- @form_method ||= (object_form_method || "get").to_s.downcase
148
- ActiveSupport::StringInquirer.new(@form_method)
149
- end
97
+ # @return [String] The display's CSS classes
98
+ attr_reader :display_class
150
99
 
151
- # Retrieves the form's CSS classes.
100
+ # Generates the display attributes hash.
152
101
  #
153
- # @return [String] The form's CSS classes
154
- attr_reader :form_class
155
-
156
- # Checks if the authenticity token should be included.
157
- #
158
- # @return [Boolean] True if the authenticity token should be included, false otherwise
159
- def authenticity_token?
160
- defined?(helpers) && options.fetch(:authenticity_token) { !form_method.get? }
161
- end
162
-
163
- # Retrieves the authenticity token.
164
- #
165
- # @return [String] The authenticity token
166
- def authenticity_token
167
- options.fetch(:authenticity_token) { helpers.form_authenticity_token }
168
- end
169
-
170
- # Renders the authenticity token field.
171
- #
172
- # @param name [String] The name attribute for the authenticity token field
173
- # @param value [String] The value for the authenticity token field
174
- # @return [void]
175
- def authenticity_token_field(name = "authenticity_token", value = authenticity_token)
176
- input(name: name, value: value, type: "hidden", hidden: true)
177
- end
178
-
179
- # Determines the appropriate form method based on the object's state.
180
- #
181
- # @return [String, nil] The appropriate form method
182
- def object_form_method
183
- if object.respond_to?(:persisted?)
184
- object.persisted? ? "patch" : "post"
185
- elsif object.present?
186
- "post"
187
- end
188
- end
189
-
190
- # Renders the hidden method field for non-standard HTTP methods.
191
- #
192
- # @return [void]
193
- def render_hidden_method_field
194
- return if standard_form_method?
195
- input(name: "_method", value: form_method, type: "hidden", hidden: true)
196
- end
197
-
198
- # Checks if the form method is standard (GET or POST).
199
- #
200
- # @return [Boolean] True if the form method is standard, false otherwise
201
- def standard_form_method?
202
- form_method.get? || form_method.post?
203
- end
204
-
205
- # Returns the standardized form method for the HTML form tag.
206
- #
207
- # @return [String] The standardized form method
208
- def standardized_form_method
209
- standard_form_method? ? form_method : "post"
210
- end
211
-
212
- # Generates the form attributes hash.
213
- #
214
- # @return [Hash] The form attributes
215
- def form_attributes
216
- {
102
+ # @return [Hash] The display attributes
103
+ def display_attributes
104
+ mix({
217
105
  id: @namespace.dom_id,
218
- action: form_action,
219
- method: standardized_form_method,
220
- class: form_class,
221
- **attributes
222
- }
223
- end
224
-
225
- # Renders the authenticity token if required.
226
- #
227
- # @return [void]
228
- def render_authenticity_token
229
- authenticity_token_field
230
- end
231
-
232
- private
233
-
234
- def default_namespace_klass
235
- self.class::Namespace
236
- end
237
-
238
- def default_builder_klass
239
- self.class::FieldBuilder
106
+ class: display_class
107
+ }, attributes)
240
108
  end
241
109
  end
242
110
  end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "phlex"
4
+
5
+ module Phlexi
6
+ module Display
7
+ # Builder class is responsible for building display fields with various options and components.
8
+ #
9
+ # @attr_reader [Structure::DOM] dom The DOM structure for the field.
10
+ # @attr_reader [Hash] options Options for the field.
11
+ # @attr_reader [Object] object The object associated with the field.
12
+ # @attr_reader [Hash] attributes Attributes for the field.
13
+ # @attr_accessor [Object] value The value of the field.
14
+ class Builder < Phlexi::Field::Builder
15
+ # Creates a label tag for the field.
16
+ #
17
+ # @param attributes [Hash] Additional attributes for the label.
18
+ # @return [Components::Label] The label component.
19
+ def label_tag(**, &)
20
+ create_component(Components::Label, :label, **, &)
21
+ end
22
+
23
+ # Creates a Placeholder tag for the field.
24
+ #
25
+ # @param attributes [Hash] Additional attributes for the placeholder.
26
+ # @return [Components::Placeholder] The placeholder component.
27
+ def placeholder_tag(**, &)
28
+ create_component(Components::Placeholder, :placeholder, **, &)
29
+ end
30
+
31
+ # Creates a Description tag for the field.
32
+ #
33
+ # @param attributes [Hash] Additional attributes for the description.
34
+ # @return [Components::Description] The description component.
35
+ def description_tag(**, &)
36
+ create_component(Components::Description, :description, **, &)
37
+ end
38
+
39
+ # Creates a string display tag for the field.
40
+ #
41
+ # @param attributes [Hash] Additional attributes for the string display.
42
+ # @return [Components::String] The string component.
43
+ def string_tag(**, &)
44
+ create_component(Components::String, :string, **, &)
45
+ end
46
+
47
+ # # Creates a text display tag for the field.
48
+ # #
49
+ # # @param attributes [Hash] Additional attributes for the text display.
50
+ # # @return [Components::Text] The text component.
51
+ # def text_tag(**, &)
52
+ # create_component(Components::Text, :text, **, &)
53
+ # end
54
+
55
+ # Creates a number display tag for the field.
56
+ #
57
+ # @param attributes [Hash] Additional attributes for the number display.
58
+ # @return [Components::Number] The number component.
59
+ def number_tag(**, &)
60
+ create_component(Components::Number, :number, **, &)
61
+ end
62
+
63
+ # Creates a datetime display for the field.
64
+ #
65
+ # @param attributes [Hash] Additional attributes for the datetime display.
66
+ # @return [Components::DateTime] The datetime component.
67
+ def datetime_tag(**, &)
68
+ create_component(Components::DateTime, :datetime, **, &)
69
+ end
70
+
71
+ # # Creates a boolean display tag for the field.
72
+ # #
73
+ # # @param attributes [Hash] Additional attributes for the boolean display.
74
+ # # @return [Components::Boolean] The boolean component.
75
+ # def boolean_tag(**, &)
76
+ # create_component(Components::Boolean, :boolean, **, &)
77
+ # end
78
+
79
+ # # Creates an association display tag for the field.
80
+ # #
81
+ # # @param attributes [Hash] Additional attributes for the association display.
82
+ # # @return [Components::Association] The association component.
83
+ # def association_tag(**, &)
84
+ # create_component(Components::Association, :association, **, &)
85
+ # end
86
+
87
+ # # Creates an attachment display tag for the field.
88
+ # #
89
+ # # @param attributes [Hash] Additional attributes for the attachment display.
90
+ # # @return [Components::Attachment] The attachment component.
91
+ # def attachment_tag(**, &)
92
+ # create_component(Components::Attachment, :attachment, **, &)
93
+ # end
94
+
95
+ # Wraps the field with additional markup.
96
+ #
97
+ # @param attributes [Hash] Additional attributes for the wrapper.
98
+ # @yield [block] The block to be executed within the wrapper.
99
+ # @return [Components::Wrapper] The wrapper component.
100
+ def wrapped(**, &)
101
+ create_component(Components::Wrapper, :wrapper, **, &)
102
+ end
103
+
104
+ protected
105
+
106
+ def create_component(component_class, theme_key, **attributes, &)
107
+ theme_key = attributes.delete(:theme) || theme_key
108
+ attributes = mix({class: themed(theme_key)}, attributes) unless attributes.key?(:class!)
109
+ component_class.new(self, **attributes, &)
110
+ end
111
+
112
+ def themed(component)
113
+ Phlexi::Display::Theme.instance.resolve_theme(component)
114
+ end
115
+ end
116
+ end
117
+ end
@@ -3,49 +3,8 @@
3
3
  module Phlexi
4
4
  module Display
5
5
  module Components
6
- class Base < COMPONENT_BASE
7
- attr_reader :field, :attributes
8
-
9
- def initialize(field, **attributes)
10
- @field = field
11
- @attributes = attributes
12
-
13
- build_attributes
14
- append_attribute_classes
15
- end
16
-
17
- protected
18
-
19
- def build_attributes
20
- attributes.fetch(:id) { attributes[:id] = "#{field.dom.id}_#{component_name}" }
21
- end
22
-
23
- def append_attribute_classes
24
- return if attributes[:class] == false
25
-
26
- attributes[:class] = tokens(
27
- component_name,
28
- attributes[:class],
29
- -> { attributes[:required] } => "required",
30
- -> { !attributes[:required] } => "optional",
31
- -> { field.has_errors? } => "invalid",
32
- -> { attributes[:readonly] } => "readonly",
33
- -> { attributes[:disabled] } => "disabled"
34
- )
35
- end
36
-
37
- def component_name
38
- @component_name ||= self.class.name.demodulize.underscore
39
- end
6
+ class Base < Phlexi::Field::Components::Base
40
7
  end
41
8
  end
42
9
  end
43
10
  end
44
-
45
-
46
-
47
- User
48
- name: :string
49
- validate :name, presence: true
50
-
51
- f.input :name
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Display
5
+ module Components
6
+ module Concerns
7
+ module DisplaysValue
8
+ def view_template
9
+ value = normalize_value(field.value)
10
+ if value.blank?
11
+ render field.placeholder_tag(**@placeholder_attributes)
12
+ else
13
+ render_value(value)
14
+ end
15
+ end
16
+
17
+ # Renders the field value for display.
18
+ #
19
+ # @return [String] the formatted field value for display.
20
+ def render_value(value)
21
+ raise NotImplementedError, "#{self.class}#render_value"
22
+ # format_value()
23
+ end
24
+
25
+ protected
26
+
27
+ def build_attributes
28
+ super
29
+
30
+ @placeholder_attributes = attributes.delete(:placeholder_attributes) || {}
31
+ attributes[:id] = field.dom.id if attributes[:id] == "#{field.dom.id}_#{component_name}"
32
+ end
33
+
34
+ # def format_value(value)
35
+ # case value
36
+ # when Array
37
+ # format_array_value(value)
38
+ # else
39
+ # format_single_value(value)
40
+ # end
41
+ # end
42
+
43
+ # def format_array_value(array)
44
+ # array.map { |item| format_single_value(item) }.join(", ")
45
+ # end
46
+
47
+ def normalize_value(value)
48
+ value.to_s
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Display
5
+ module Components
6
+ class DateTime < Base
7
+ include Concerns::DisplaysValue
8
+
9
+ # Renders the date time value
10
+ #
11
+ # @param value [String, Date, Time, DateTime] The value to be rendered
12
+ # @return [void]
13
+ def render_value(value)
14
+ formatted_value = format_date_time(value)
15
+ p(**attributes) { formatted_value }
16
+ end
17
+
18
+ protected
19
+
20
+ def build_attributes
21
+ super
22
+
23
+ @options = {
24
+ format: default_format
25
+ }.merge(attributes.delete(:options) || {}).compact
26
+ end
27
+
28
+ private
29
+
30
+ def format_date_time(value)
31
+ I18n.l(value, **@options)
32
+ end
33
+
34
+ def default_format
35
+ :long
36
+ end
37
+
38
+ def normalize_value(value)
39
+ case value
40
+ when Date, DateTime, Time, nil
41
+ value
42
+ else
43
+ raise ArgumentError, "Value must be a Date, DateTime or Time object. #{value.inspect} given."
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -3,17 +3,17 @@
3
3
  module Phlexi
4
4
  module Display
5
5
  module Components
6
- class Error < Base
6
+ class Description < Base
7
7
  def view_template
8
- p(**attributes) do
9
- field.error
10
- end
8
+ p(**attributes) {
9
+ field.description
10
+ }
11
11
  end
12
12
 
13
13
  private
14
14
 
15
15
  def render?
16
- field.show_errors? && field.has_errors?
16
+ field.has_description?
17
17
  end
18
18
  end
19
19
  end
@@ -13,7 +13,7 @@ module Phlexi
13
13
  private
14
14
 
15
15
  def render?
16
- field.hint.present? && (!field.show_errors? || !field.has_errors?)
16
+ field.has_hint?
17
17
  end
18
18
  end
19
19
  end
@@ -5,21 +5,9 @@ module Phlexi
5
5
  module Components
6
6
  class Label < Base
7
7
  def view_template
8
- label(**attributes) do
9
- if field.required?
10
- abbr(title: "required") { "*" }
11
- whitespace
12
- end
13
- plain field.label
14
- end
15
- end
16
-
17
- protected
18
-
19
- def build_attributes
20
- super
21
-
22
- attributes.fetch(:for) { attributes[:for] = field.dom.id }
8
+ h5(**attributes) {
9
+ field.label
10
+ }
23
11
  end
24
12
  end
25
13
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/number_helper"
4
+
5
+ module Phlexi
6
+ module Display
7
+ module Components
8
+ class Number < Base
9
+ include Concerns::DisplaysValue
10
+
11
+ def render_value(value)
12
+ p(**attributes) {
13
+ format_number(value)
14
+ }
15
+ end
16
+
17
+ protected
18
+
19
+ def build_attributes
20
+ super
21
+
22
+ @options = attributes.delete(:options) || {}
23
+ end
24
+
25
+ private
26
+
27
+ def format_number(value)
28
+ ActiveSupport::NumberHelper.number_to_delimited(value, **@options)
29
+ end
30
+
31
+ def normalize_value(value)
32
+ Float(value.to_s)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Phlexi
4
+ module Display
5
+ module Components
6
+ class Placeholder < Base
7
+ def view_template
8
+ p(**attributes) {
9
+ field.placeholder
10
+ }
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end