phlexi-display 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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