primer_view_components 0.0.85 → 0.0.86

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -0
  3. data/app/assets/javascripts/primer_view_components.js +1 -1
  4. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  5. data/app/components/primer/alpha/auto_complete/item.rb +1 -1
  6. data/app/components/primer/alpha/auto_complete.rb +1 -1
  7. data/app/components/primer/alpha/button_marketing.rb +1 -1
  8. data/app/components/primer/alpha/text_field.rb +105 -0
  9. data/app/components/primer/alpha/tool-tip-element.d.ts +3 -1
  10. data/app/components/primer/alpha/tool-tip-element.js +20 -13
  11. data/app/components/primer/alpha/tool-tip-element.ts +23 -14
  12. data/app/components/primer/alpha/tooltip.rb +1 -1
  13. data/app/components/primer/beta/base_button.rb +47 -0
  14. data/app/components/primer/{alpha → beta}/border_box/header.html.erb +0 -0
  15. data/app/components/primer/{alpha → beta}/border_box/header.rb +6 -6
  16. data/app/components/primer/{border_box_component.html.erb → beta/border_box.html.erb} +0 -0
  17. data/app/components/primer/beta/border_box.rb +147 -0
  18. data/app/components/primer/blankslate_component.rb +2 -150
  19. data/app/components/primer/border_box_component.rb +2 -140
  20. data/app/components/primer/button_component.html.erb +12 -4
  21. data/app/components/primer/button_component.rb +2 -2
  22. data/app/components/primer/clipboard_copy.rb +6 -2
  23. data/app/components/primer/close_button.rb +1 -1
  24. data/app/components/primer/hellip_button.rb +1 -1
  25. data/app/components/primer/icon_button.html.erb +6 -0
  26. data/app/components/primer/icon_button.rb +46 -10
  27. data/app/components/primer/link_component.html.erb +12 -0
  28. data/app/components/primer/link_component.rb +2 -9
  29. data/app/lib/primer/join_style_arguments_helper.rb +1 -1
  30. data/lib/primer/classify/utilities.rb +3 -6
  31. data/lib/primer/form_components.rb +36 -0
  32. data/lib/primer/forms/acts_as_component.rb +118 -0
  33. data/lib/primer/forms/base.html.erb +8 -0
  34. data/lib/primer/forms/base.rb +137 -0
  35. data/lib/primer/forms/base_component.rb +58 -0
  36. data/lib/primer/forms/buffer_rewriter.rb +50 -0
  37. data/lib/primer/forms/caption.html.erb +10 -0
  38. data/lib/primer/forms/caption.rb +29 -0
  39. data/lib/primer/forms/check_box.html.erb +9 -0
  40. data/lib/primer/forms/check_box.rb +16 -0
  41. data/lib/primer/forms/check_box_group.html.erb +12 -0
  42. data/lib/primer/forms/check_box_group.rb +14 -0
  43. data/lib/primer/forms/dsl/check_box_group_input.rb +41 -0
  44. data/lib/primer/forms/dsl/check_box_input.rb +27 -0
  45. data/lib/primer/forms/dsl/form_object.rb +25 -0
  46. data/lib/primer/forms/dsl/form_reference_input.rb +36 -0
  47. data/lib/primer/forms/dsl/hidden_input.rb +29 -0
  48. data/lib/primer/forms/dsl/input.rb +259 -0
  49. data/lib/primer/forms/dsl/input_group.rb +41 -0
  50. data/lib/primer/forms/dsl/input_methods.rb +86 -0
  51. data/lib/primer/forms/dsl/multi_input.rb +58 -0
  52. data/lib/primer/forms/dsl/radio_button_group_input.rb +38 -0
  53. data/lib/primer/forms/dsl/radio_button_input.rb +37 -0
  54. data/lib/primer/forms/dsl/select_list_input.rb +53 -0
  55. data/lib/primer/forms/dsl/submit_button_input.rb +28 -0
  56. data/lib/primer/forms/dsl/text_area_input.rb +33 -0
  57. data/lib/primer/forms/dsl/text_field_input.rb +65 -0
  58. data/lib/primer/forms/form_control.html.erb +18 -0
  59. data/lib/primer/forms/form_control.rb +23 -0
  60. data/lib/primer/forms/form_list.html.erb +5 -0
  61. data/lib/primer/forms/form_list.rb +21 -0
  62. data/lib/primer/forms/form_reference.html.erb +3 -0
  63. data/lib/primer/forms/form_reference.rb +14 -0
  64. data/lib/primer/forms/group.html.erb +5 -0
  65. data/lib/primer/forms/group.rb +27 -0
  66. data/lib/primer/forms/hidden_field.html.erb +1 -0
  67. data/lib/primer/forms/hidden_field.rb +15 -0
  68. data/lib/primer/forms/multi.html.erb +3 -0
  69. data/lib/primer/forms/multi.rb +14 -0
  70. data/lib/primer/forms/radio_button.html.erb +14 -0
  71. data/lib/primer/forms/radio_button.rb +29 -0
  72. data/lib/primer/forms/radio_button_group.html.erb +12 -0
  73. data/lib/primer/forms/radio_button_group.rb +14 -0
  74. data/lib/primer/forms/select_list.html.erb +5 -0
  75. data/lib/primer/forms/select_list.rb +26 -0
  76. data/lib/primer/forms/separator.html.erb +1 -0
  77. data/lib/primer/forms/separator.rb +8 -0
  78. data/lib/primer/forms/spacing_wrapper.html.erb +3 -0
  79. data/lib/primer/forms/spacing_wrapper.rb +8 -0
  80. data/lib/primer/forms/submit_button.html.erb +4 -0
  81. data/lib/primer/forms/submit_button.rb +50 -0
  82. data/lib/primer/forms/text_area.html.erb +5 -0
  83. data/lib/primer/forms/text_area.rb +16 -0
  84. data/lib/primer/forms/text_field.html.erb +19 -0
  85. data/lib/primer/forms/text_field.rb +14 -0
  86. data/lib/primer/view_components/engine.rb +23 -0
  87. data/lib/primer/view_components/linters/argument_mappers/button.rb +2 -2
  88. data/lib/primer/view_components/linters/button_component_migration_counter.rb +1 -1
  89. data/lib/primer/view_components/linters/helpers/deprecated_components_helpers.rb +2 -8
  90. data/lib/primer/view_components/version.rb +1 -1
  91. data/lib/rubocop/cop/primer/component_name_migration.rb +3 -0
  92. data/lib/tasks/deprecated.rake +22 -0
  93. data/lib/tasks/docs.rake +5 -3
  94. data/static/arguments.yml +148 -39
  95. data/static/audited_at.json +4 -2
  96. data/static/classes.yml +2 -1
  97. data/static/constants.json +44 -39
  98. data/static/statuses.json +7 -5
  99. metadata +66 -7
  100. data/app/components/primer/base_button.rb +0 -43
  101. data/app/components/primer/blankslate_component.html.erb +0 -30
@@ -0,0 +1,259 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "primer/classify"
4
+
5
+ module Primer
6
+ module Forms
7
+ module Dsl
8
+ # :nodoc:
9
+ class Input
10
+ SPACE_DELIMITED_ARIA_ATTRIBUTES = %i[describedby].freeze
11
+ DEFAULT_SIZE = :medium
12
+ SIZE_MAPPINGS = {
13
+ :small => "FormControl-small",
14
+ DEFAULT_SIZE => "FormControl-medium",
15
+ :large => "FormControl-large"
16
+ }.freeze
17
+ SIZE_OPTIONS = SIZE_MAPPINGS.keys
18
+
19
+ UTILITY_KEYS = Primer::Classify::Utilities::UTILITIES.keys.freeze
20
+
21
+ include Primer::ClassNameHelper
22
+
23
+ attr_reader :builder, :form, :input_arguments, :label_arguments, :caption, :validation_message, :ids
24
+
25
+ def initialize(builder:, form:, **system_arguments)
26
+ @builder = builder
27
+ @form = form
28
+
29
+ @input_arguments = system_arguments
30
+ process_classes!(@input_arguments)
31
+
32
+ @label_arguments = @input_arguments.delete(:label_arguments) || {}
33
+ process_classes!(@label_arguments)
34
+
35
+ @label_arguments[:class] = class_names(
36
+ @label_arguments[:class],
37
+ @input_arguments.fetch(:visually_hide_label, true) ? "sr-only" : nil
38
+ )
39
+
40
+ @input_arguments.delete(:visually_hide_label)
41
+
42
+ @input_arguments.delete(:class) if @input_arguments[:class].blank?
43
+ @label_arguments.delete(:class) if @label_arguments[:class].blank?
44
+
45
+ @caption = @input_arguments.delete(:caption)
46
+ @validation_message = @input_arguments.delete(:validation_message)
47
+ @invalid = @input_arguments.delete(:invalid)
48
+ @full_width = @input_arguments.delete(:full_width)
49
+ @size = @input_arguments.delete(:size)
50
+
51
+ @input_arguments[:invalid] = "true" if invalid?
52
+
53
+ base_id = SecureRandom.hex[0..5]
54
+
55
+ @ids = {}.tap do |id_map|
56
+ id_map[:validation] = "validation-#{base_id}" if invalid?
57
+ id_map[:caption] = "caption-#{base_id}" if caption? || caption_template?
58
+ end
59
+
60
+ add_input_aria(:required, true) if required?
61
+ add_input_aria(:describedby, ids.values) if ids.any?
62
+
63
+ # avoid browser-native validation, which doesn't match Primer's style
64
+ input_arguments.delete(:required)
65
+ end
66
+
67
+ def add_input_classes(*class_names)
68
+ input_arguments[:class] = class_names(
69
+ input_arguments[:class], *class_names
70
+ )
71
+ end
72
+
73
+ def add_label_classes(*class_names)
74
+ label_arguments[:class] = class_names(
75
+ label_arguments[:class], *class_names
76
+ )
77
+ end
78
+
79
+ def add_input_aria(key, value)
80
+ @input_arguments[:aria] ||= {}
81
+
82
+ @input_arguments[:aria][key] = if space_delimited_aria_attribute?(key)
83
+ aria_join(@input_arguments[:aria][key], *Array(value))
84
+ else
85
+ value
86
+ end
87
+ end
88
+
89
+ def add_input_data(key, value)
90
+ input_data[key] = value
91
+ end
92
+
93
+ def remove_input_data(key)
94
+ input_data.delete(key)
95
+ end
96
+
97
+ def merge_input_arguments!(arguments)
98
+ arguments.each do |k, v|
99
+ case k
100
+ when :class, :classes, "class", "classes"
101
+ add_input_classes(v)
102
+ when :aria, "aria"
103
+ v.each do |aria_k, aria_v|
104
+ add_input_aria(aria_k, aria_v)
105
+ end
106
+ when :data, "data"
107
+ v.each do |data_k, data_v|
108
+ add_input_data(data_k, data_v)
109
+ end
110
+ else
111
+ @input_arguments[k] = v
112
+ end
113
+ end
114
+ end
115
+
116
+ def validation_id
117
+ ids[:validation]
118
+ end
119
+
120
+ def caption_id
121
+ ids[:caption]
122
+ end
123
+
124
+ def caption?
125
+ caption.present?
126
+ end
127
+
128
+ def caption_template?
129
+ return false unless form
130
+
131
+ form.caption_template?(caption_template_name)
132
+ end
133
+
134
+ def render_caption_template
135
+ form.render_caption_template(caption_template_name)
136
+ end
137
+
138
+ def valid?
139
+ validation_messages.empty? && !@invalid
140
+ end
141
+
142
+ def invalid?
143
+ !valid?
144
+ end
145
+
146
+ def hidden?
147
+ !!input_arguments[:hidden]
148
+ end
149
+
150
+ def required?
151
+ input_arguments[:required] ||
152
+ input_arguments[:aria_required] ||
153
+ input_arguments[:"aria-required"] ||
154
+ input_arguments.dig(:aria, :required)
155
+ end
156
+
157
+ def disabled?
158
+ input_arguments.include?(:disabled)
159
+ end
160
+
161
+ def full_width?
162
+ @full_width
163
+ end
164
+
165
+ def size
166
+ @size ||= SIZE_MAPPINGS.include?(@size) ? @size : DEFAULT_SIZE
167
+ end
168
+
169
+ def validation_messages
170
+ @validation_messages ||=
171
+ if validation_message
172
+ [validation_message]
173
+ elsif builder.object.respond_to?(:errors)
174
+ name ? builder.object.errors.full_messages_for(name) : []
175
+ else
176
+ []
177
+ end
178
+ end
179
+
180
+ def autofocus!
181
+ input_arguments[:autofocus] = true
182
+ end
183
+
184
+ # :nocov:
185
+ def name
186
+ raise_for_abstract_method!(__method__)
187
+ end
188
+
189
+ def label
190
+ raise_for_abstract_method!(__method__)
191
+ end
192
+
193
+ def type
194
+ raise_for_abstract_method!(__method__)
195
+ end
196
+
197
+ def to_component
198
+ raise_for_abstract_method!(__method__)
199
+ end
200
+ # :nocov:
201
+
202
+ def focusable?
203
+ false
204
+ end
205
+
206
+ def input?
207
+ true
208
+ end
209
+
210
+ # Avoid using Rails delegation here for performance reasons
211
+ # rubocop:disable Rails/Delegate
212
+ def render_in(view_context)
213
+ to_component.render_in(view_context)
214
+ end
215
+ # rubocop:enable Rails/Delegate
216
+
217
+ private
218
+
219
+ def process_classes!(args)
220
+ args[:classes] = class_names(args.delete(:class), args[:classes])
221
+ args.merge!(Primer::Classify.call(args))
222
+ args[:class] = class_names(args[:class], args.delete(:classes))
223
+ args.except!(*UTILITY_KEYS)
224
+ args
225
+ end
226
+
227
+ def input_data
228
+ @input_arguments[:data] ||= {}
229
+ end
230
+
231
+ def caption_template_name
232
+ return nil unless name
233
+
234
+ @caption_template_name ||= if respond_to?(:value)
235
+ :"#{name}_#{value}"
236
+ else
237
+ name.to_sym
238
+ end
239
+ end
240
+
241
+ def space_delimited_aria_attribute?(attrib)
242
+ SPACE_DELIMITED_ARIA_ATTRIBUTES.include?(attrib)
243
+ end
244
+
245
+ def aria_join(*values)
246
+ values = values.flat_map { |v| v.to_s.split }
247
+ values.reject!(&:empty?)
248
+ values.join(" ")
249
+ end
250
+
251
+ # :nocov:
252
+ def raise_for_abstract_method!(method_name)
253
+ raise NotImplementedError, "subclasses must implement ##{method_name}."
254
+ end
255
+ # :nocov:
256
+ end
257
+ end
258
+ end
259
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Forms
5
+ module Dsl
6
+ # :nodoc:
7
+ class InputGroup
8
+ include InputMethods
9
+
10
+ attr_reader :builder, :form, :system_arguments
11
+
12
+ def initialize(builder:, form:, **system_arguments)
13
+ @builder = builder
14
+ @form = form
15
+ @system_arguments = system_arguments
16
+
17
+ yield(self) if block_given?
18
+ end
19
+
20
+ def to_component
21
+ Group.new(inputs: inputs, builder: builder, form: form, **@system_arguments)
22
+ end
23
+
24
+ def type
25
+ :group
26
+ end
27
+
28
+ def input?
29
+ true
30
+ end
31
+
32
+ # Avoid using Rails delegation here for performance reasons
33
+ # rubocop:disable Rails/Delegate
34
+ def render_in(view_context)
35
+ to_component.render_in(view_context)
36
+ end
37
+ # rubocop:enable Rails/Delegate
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Forms
5
+ module Dsl
6
+ # :nodoc:
7
+ module InputMethods
8
+ def fields_for(*args, **kwargs, &block)
9
+ add_input FormReferenceInput.new(*args, builder: builder, form: form, **kwargs, &block)
10
+ end
11
+
12
+ def multi(**options, &block)
13
+ add_input MultiInput.new(builder: builder, form: form, **options, &block)
14
+ end
15
+
16
+ def hidden(**options)
17
+ add_input HiddenInput.new(builder: builder, form: form, **options)
18
+ end
19
+
20
+ def check_box(**options)
21
+ add_input CheckBoxInput.new(builder: builder, form: form, **options)
22
+ end
23
+
24
+ def radio_button_group(**options, &block)
25
+ add_input RadioButtonGroupInput.new(builder: builder, form: form, **options, &block)
26
+ end
27
+
28
+ def check_box_group(**options, &block)
29
+ add_input CheckBoxGroupInput.new(builder: builder, form: form, **options, &block)
30
+ end
31
+
32
+ def separator
33
+ add_input Separator.new
34
+ end
35
+
36
+ # START text input methods
37
+
38
+ def text_field(**options, &block)
39
+ options = decorate_options(**options)
40
+ add_input TextFieldInput.new(builder: builder, form: form, **options, &block)
41
+ end
42
+
43
+ def text_area(**options, &block)
44
+ options = decorate_options(**options)
45
+ add_input TextAreaInput.new(builder: builder, form: form, **options, &block)
46
+ end
47
+
48
+ # END text input methods
49
+
50
+ # START select input methods
51
+
52
+ def select_list(**options, &block)
53
+ options = decorate_options(**options)
54
+ add_input SelectListInput.new(builder: builder, form: form, **options, &block)
55
+ end
56
+
57
+ # END select input methods
58
+
59
+ # START button input methods
60
+
61
+ def submit(**options, &block)
62
+ options = decorate_options(**options)
63
+ add_input SubmitButtonInput.new(builder: builder, form: form, **options, &block)
64
+ end
65
+
66
+ # END button input methods
67
+
68
+ def inputs
69
+ @inputs ||= []
70
+ end
71
+
72
+ private
73
+
74
+ def add_input(input)
75
+ inputs << input
76
+ end
77
+
78
+ # Called before the corresponding Input class is instantiated. The return value of this method is passed
79
+ # to the Input class's constructor.
80
+ def decorate_options(**options)
81
+ options
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Forms
5
+ module Dsl
6
+ # :nodoc:
7
+ class MultiInput < Input
8
+ include InputMethods
9
+
10
+ attr_reader :name, :label
11
+
12
+ def initialize(name:, label:, **system_arguments)
13
+ @name = name
14
+ @label = label
15
+
16
+ super(**system_arguments)
17
+
18
+ yield(self) if block_given?
19
+ end
20
+
21
+ def to_component
22
+ Multi.new(input: self)
23
+ end
24
+
25
+ def type
26
+ :multi
27
+ end
28
+
29
+ private
30
+
31
+ def add_input(input)
32
+ super
33
+
34
+ check_one_input_visible!
35
+ end
36
+
37
+ def decorate_options(name: nil, **options)
38
+ check_name!(name) if name
39
+ new_options = { name: name || @name, label: nil, **options }
40
+ new_options[:id] = nil if options[:hidden]
41
+ new_options
42
+ end
43
+
44
+ def check_name!(name)
45
+ return if name == @name
46
+
47
+ raise ArgumentError, "Inputs inside a `multi' block must all have the same name. Expected '#{@name}', got '#{name}'."
48
+ end
49
+
50
+ def check_one_input_visible!
51
+ return if inputs.count { |input| !input.hidden? } <= 1
52
+
53
+ raise ArgumentError, "Only one input can be visible at a time in a `multi' block."
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Forms
5
+ module Dsl
6
+ # :nodoc:
7
+ class RadioButtonGroupInput < Input
8
+ attr_reader :name, :label, :radio_buttons
9
+
10
+ def initialize(name:, label: nil, **system_arguments)
11
+ @name = name
12
+ @label = label
13
+ @radio_buttons = []
14
+
15
+ super(**system_arguments)
16
+
17
+ add_label_classes("FormControl-label", "mb-2")
18
+
19
+ yield(self) if block_given?
20
+ end
21
+
22
+ def to_component
23
+ RadioButtonGroup.new(input: self)
24
+ end
25
+
26
+ def type
27
+ :radio_button_group
28
+ end
29
+
30
+ def radio_button(**system_arguments, &block)
31
+ @radio_buttons << RadioButtonInput.new(
32
+ builder: @builder, form: @form, name: @name, **system_arguments, &block
33
+ )
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Forms
5
+ module Dsl
6
+ # :nodoc:
7
+ class RadioButtonInput < Input
8
+ attr_reader :name, :value, :label, :nested_form_block, :nested_form_arguments
9
+
10
+ def initialize(name:, value:, label:, **system_arguments)
11
+ @name = name
12
+ @value = value
13
+ @label = label
14
+
15
+ super(**system_arguments)
16
+
17
+ yield(self) if block_given?
18
+ end
19
+
20
+ def to_component
21
+ RadioButton.new(input: self)
22
+ end
23
+
24
+ def nested_form(**system_arguments, &block)
25
+ @nested_form_arguments = system_arguments
26
+ @nested_form_block = block
27
+ end
28
+
29
+ # :nocov:
30
+ def type
31
+ :radio_button
32
+ end
33
+ # :nocov:
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Forms
5
+ module Dsl
6
+ # :nodoc:
7
+ class SelectListInput < Input
8
+ # :nodoc:
9
+ class Option
10
+ attr_reader :label, :value, :system_arguments
11
+
12
+ def initialize(label:, value:, **system_arguments)
13
+ @label = label
14
+ @value = value
15
+ @system_arguments = system_arguments
16
+ end
17
+ end
18
+
19
+ attr_reader :name, :label, :options
20
+
21
+ def initialize(name:, label:, **system_arguments)
22
+ @name = name
23
+ @label = label
24
+ @options = []
25
+
26
+ super(**system_arguments)
27
+
28
+ yield(self) if block_given?
29
+ end
30
+
31
+ def option(**system_arguments)
32
+ @options << Option.new(**system_arguments)
33
+ end
34
+
35
+ def to_component
36
+ SelectList.new(input: self)
37
+ end
38
+
39
+ # :nocov:
40
+ def type
41
+ :select_list
42
+ end
43
+ # :nocov:
44
+
45
+ # :nocov:
46
+ def focusable?
47
+ true
48
+ end
49
+ # :nocov:
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Forms
5
+ module Dsl
6
+ # :nodoc:
7
+ class SubmitButtonInput < Input
8
+ attr_reader :name, :label, :block
9
+
10
+ def initialize(name:, label:, **system_arguments, &block)
11
+ @name = name
12
+ @label = label
13
+ @block = block
14
+
15
+ super(**system_arguments)
16
+ end
17
+
18
+ def to_component
19
+ SubmitButton.new(input: self)
20
+ end
21
+
22
+ def type
23
+ :submit_button
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Forms
5
+ module Dsl
6
+ # :nodoc:
7
+ class TextAreaInput < Input
8
+ attr_reader :name, :label
9
+
10
+ def initialize(name:, label:, **system_arguments)
11
+ @name = name
12
+ @label = label
13
+
14
+ super(**system_arguments)
15
+ end
16
+
17
+ def to_component
18
+ TextArea.new(input: self)
19
+ end
20
+
21
+ def type
22
+ :text_area
23
+ end
24
+
25
+ # :nocov:
26
+ def focusable?
27
+ true
28
+ end
29
+ # :nocov:
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Forms
5
+ module Dsl
6
+ # :nodoc:
7
+ class TextFieldInput < Input
8
+ attr_reader(
9
+ *%i[
10
+ name label show_clear_button leading_visual clear_button_id
11
+ visually_hide_label inset monospace field_wrap_classes
12
+ ]
13
+ )
14
+
15
+ def initialize(name:, label:, **system_arguments)
16
+ @name = name
17
+ @label = label
18
+
19
+ @show_clear_button = system_arguments.delete(:show_clear_button)
20
+ @leading_visual = system_arguments.delete(:leading_visual)
21
+ @clear_button_id = system_arguments.delete(:clear_button_id)
22
+ @inset = system_arguments.delete(:inset)
23
+ @monospace = system_arguments.delete(:monospace)
24
+
25
+ super(**system_arguments)
26
+
27
+ add_input_classes(
28
+ "FormControl-input",
29
+ Primer::Forms::Dsl::Input::SIZE_MAPPINGS[size]
30
+ )
31
+
32
+ add_input_classes("FormControl-inset") if inset?
33
+ add_input_classes("FormControl-monospace") if monospace?
34
+
35
+ @field_wrap_classes = class_names(
36
+ "FormControl-input-wrap",
37
+ Primer::Forms::Dsl::Input::SIZE_MAPPINGS[size],
38
+ "FormControl-input-wrap--trailingAction": show_clear_button?,
39
+ "FormControl-input-wrap--leadingVisual": leading_visual?
40
+ )
41
+ end
42
+
43
+ alias show_clear_button? show_clear_button
44
+ alias inset? inset
45
+ alias monospace? monospace
46
+
47
+ def to_component
48
+ TextField.new(input: self)
49
+ end
50
+
51
+ def type
52
+ :text_field
53
+ end
54
+
55
+ def focusable?
56
+ true
57
+ end
58
+
59
+ def leading_visual?
60
+ !!@leading_visual
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end