Class: Yattho::Forms::Dsl::Input

Inherits:
Object
  • Object
show all
Includes:
ClassNameHelper
Defined in:
lib/yattho/forms/dsl/input.rb

Overview

:nodoc:

Constant Summary collapse

SPACE_DELIMITED_ARIA_ATTRIBUTES =
%i[describedby].freeze
DEFAULT_SIZE =
:medium
SIZE_MAPPINGS =
{
  :small => "FormControl-small",
  DEFAULT_SIZE => "FormControl-medium",
  :large => "FormControl-large"
}.freeze
SIZE_OPTIONS =
SIZE_MAPPINGS.keys

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ClassNameHelper

#class_names

Constructor Details

#initialize(builder:, form:, **system_arguments) ⇒ Input

Returns a new instance of Input.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/yattho/forms/dsl/input.rb', line 24

def initialize(builder:, form:, **system_arguments)
  @builder = builder
  @form = form

  @input_arguments = system_arguments
  @label_arguments = @input_arguments.delete(:label_arguments) || {}

  @label_arguments[:class] = class_names(
    @label_arguments[:class],
    @input_arguments.fetch(:visually_hide_label, false) ? "sr-only" : nil
  )

  @input_arguments.delete(:visually_hide_label)

  @input_arguments.delete(:class) if @input_arguments[:class].blank?
  @label_arguments.delete(:class) if @label_arguments[:class].blank?

  @caption = @input_arguments.delete(:caption)
  @validation_message = @input_arguments.delete(:validation_message)
  @invalid = @input_arguments.delete(:invalid)
  @full_width = @input_arguments.delete(:full_width)
  @size = @input_arguments.delete(:size)

  # If scope_name_to_model is false, the name of the input for eg. `my_field`
  # will be `my_field` instead of the Rails default of `model[my_field]`.
  #
  # We achieve this by passing the `name` option to Rails form builder
  # methods. These methods will use the passed name if provided instead
  # of generating a scoped one.
  #
  # rubocop:disable Style/IfUnlessModifier
  unless @input_arguments.delete(:scope_name_to_model) { true }
    @input_arguments[:name] = name
  end
  # rubocop:enable Style/IfUnlessModifier

  # If scope_id_to_model is false, the name of the input for eg. `my_field`
  # will be `my_field` instead of the Rails default of `model_my_field`.
  #
  # We achieve this by passing the `id` option to Rails form builder
  # methods. These methods will use the passed id if provided instead
  # of generating a scoped one. The id is the name of the field unless
  # explicitly provided in system_arguments.
  #
  @input_arguments[:id] = @input_arguments.delete(:id) { name } unless @input_arguments.delete(:scope_id_to_model) { true }
  # Whether or not to wrap the component in a FormControl, which renders a
  # label above and validation message beneath the input.
  @form_control = @input_arguments.delete(:form_control) { true }

  @input_arguments[:invalid] = "true" if invalid?

  base_id = SecureRandom.uuid

  @ids = {}.tap do |id_map|
    id_map[:validation] = "validation-#{base_id}" if invalid?
    id_map[:caption] = "caption-#{base_id}" if caption? || caption_template?
  end

  add_input_aria(:required, true) if required?
  add_input_aria(:describedby, ids.values) if ids.any?

  # avoid browser-native validation, which doesn't match Yattho's style
  input_arguments.delete(:required)
end

Instance Attribute Details

#builderObject (readonly)

Returns the value of attribute builder.



19
20
21
# File 'lib/yattho/forms/dsl/input.rb', line 19

def builder
  @builder
end

#captionObject (readonly)

Returns the value of attribute caption.



19
20
21
# File 'lib/yattho/forms/dsl/input.rb', line 19

def caption
  @caption
end

#formObject (readonly)

Returns the value of attribute form.



19
20
21
# File 'lib/yattho/forms/dsl/input.rb', line 19

def form
  @form
end

#form_controlObject (readonly) Also known as: form_control?

Returns the value of attribute form_control.



19
20
21
# File 'lib/yattho/forms/dsl/input.rb', line 19

def form_control
  @form_control
end

#idsObject (readonly)

Returns the value of attribute ids.



19
20
21
# File 'lib/yattho/forms/dsl/input.rb', line 19

def ids
  @ids
end

#input_argumentsObject (readonly)

Returns the value of attribute input_arguments.



19
20
21
# File 'lib/yattho/forms/dsl/input.rb', line 19

def input_arguments
  @input_arguments
end

#label_argumentsObject (readonly)

Returns the value of attribute label_arguments.



19
20
21
# File 'lib/yattho/forms/dsl/input.rb', line 19

def label_arguments
  @label_arguments
end

#validation_messageObject (readonly)

Returns the value of attribute validation_message.



19
20
21
# File 'lib/yattho/forms/dsl/input.rb', line 19

def validation_message
  @validation_message
end

Instance Method Details

#add_input_aria(key, value) ⇒ Object



101
102
103
104
105
106
107
108
109
# File 'lib/yattho/forms/dsl/input.rb', line 101

def add_input_aria(key, value)
  @input_arguments[:aria] ||= {}

  @input_arguments[:aria][key] = if space_delimited_aria_attribute?(key)
                                   aria_join(@input_arguments[:aria][key], *Array(value))
                                 else
                                   value
                                 end
end

#add_input_classes(*class_names) ⇒ Object



89
90
91
92
93
# File 'lib/yattho/forms/dsl/input.rb', line 89

def add_input_classes(*class_names)
  input_arguments[:class] = class_names(
    input_arguments[:class], *class_names
  )
end

#add_input_data(key, value) ⇒ Object



111
112
113
# File 'lib/yattho/forms/dsl/input.rb', line 111

def add_input_data(key, value)
  input_data[key] = value
end

#add_label_classes(*class_names) ⇒ Object



95
96
97
98
99
# File 'lib/yattho/forms/dsl/input.rb', line 95

def add_label_classes(*class_names)
  label_arguments[:class] = class_names(
    label_arguments[:class], *class_names
  )
end

#autofocus!Object



202
203
204
# File 'lib/yattho/forms/dsl/input.rb', line 202

def autofocus!
  input_arguments[:autofocus] = true
end

#caption?Boolean

Returns:

  • (Boolean)


146
147
148
# File 'lib/yattho/forms/dsl/input.rb', line 146

def caption?
  caption.present?
end

#caption_idObject



142
143
144
# File 'lib/yattho/forms/dsl/input.rb', line 142

def caption_id
  ids[:caption]
end

#caption_template?Boolean

Returns:

  • (Boolean)


150
151
152
153
154
# File 'lib/yattho/forms/dsl/input.rb', line 150

def caption_template?
  return false unless form

  form.caption_template?(caption_template_name)
end

#disabled?Boolean

Returns:

  • (Boolean)


179
180
181
# File 'lib/yattho/forms/dsl/input.rb', line 179

def disabled?
  input_arguments.include?(:disabled)
end

#focusable?Boolean

:nocov:

Returns:

  • (Boolean)


224
225
226
# File 'lib/yattho/forms/dsl/input.rb', line 224

def focusable?
  false
end

#full_width?Boolean

Returns:

  • (Boolean)


183
184
185
# File 'lib/yattho/forms/dsl/input.rb', line 183

def full_width?
  @full_width
end

#hidden?Boolean

Returns:

  • (Boolean)


168
169
170
# File 'lib/yattho/forms/dsl/input.rb', line 168

def hidden?
  !!input_arguments[:hidden]
end

#input?Boolean

Returns:

  • (Boolean)


228
229
230
# File 'lib/yattho/forms/dsl/input.rb', line 228

def input?
  true
end

#invalid?Boolean

Returns:

  • (Boolean)


164
165
166
# File 'lib/yattho/forms/dsl/input.rb', line 164

def invalid?
  !valid?
end

#labelObject



211
212
213
# File 'lib/yattho/forms/dsl/input.rb', line 211

def label
  raise_for_abstract_method!(__method__)
end

#merge_input_arguments!(arguments) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/yattho/forms/dsl/input.rb', line 119

def merge_input_arguments!(arguments)
  arguments.each do |k, v|
    case k
    when :class, :classes, "class", "classes"
      add_input_classes(v)
    when :aria, "aria"
      v.each do |aria_k, aria_v|
        add_input_aria(aria_k, aria_v)
      end
    when :data, "data"
      v.each do |data_k, data_v|
        add_input_data(data_k, data_v)
      end
    else
      @input_arguments[k] = v
    end
  end
end

#nameObject

:nocov:



207
208
209
# File 'lib/yattho/forms/dsl/input.rb', line 207

def name
  raise_for_abstract_method!(__method__)
end

#need_validation_element?Boolean

Returns:

  • (Boolean)


232
233
234
# File 'lib/yattho/forms/dsl/input.rb', line 232

def need_validation_element?
  invalid?
end

#remove_input_data(key) ⇒ Object



115
116
117
# File 'lib/yattho/forms/dsl/input.rb', line 115

def remove_input_data(key)
  input_data.delete(key)
end

#render_caption_templateObject



156
157
158
# File 'lib/yattho/forms/dsl/input.rb', line 156

def render_caption_template
  form.render_caption_template(caption_template_name)
end

#required?Boolean

Returns:

  • (Boolean)


172
173
174
175
176
177
# File 'lib/yattho/forms/dsl/input.rb', line 172

def required?
  input_arguments[:required] ||
    input_arguments[:aria_required] ||
    input_arguments[:'aria-required'] ||
    input_arguments.dig(:aria, :required)
end

#sizeObject



187
188
189
# File 'lib/yattho/forms/dsl/input.rb', line 187

def size
  @size ||= SIZE_MAPPINGS.include?(@size) ? @size : DEFAULT_SIZE
end

#to_componentObject



219
220
221
# File 'lib/yattho/forms/dsl/input.rb', line 219

def to_component
  raise_for_abstract_method!(__method__)
end

#typeObject



215
216
217
# File 'lib/yattho/forms/dsl/input.rb', line 215

def type
  raise_for_abstract_method!(__method__)
end

#valid?Boolean

Returns:

  • (Boolean)


160
161
162
# File 'lib/yattho/forms/dsl/input.rb', line 160

def valid?
  validation_messages.empty? && !@invalid
end

#validation_argumentsObject



236
237
238
239
240
241
242
# File 'lib/yattho/forms/dsl/input.rb', line 236

def validation_arguments
  {
    class: "FormControl-inlineValidation",
    id: validation_id,
    hidden: valid?
  }
end

#validation_idObject



138
139
140
# File 'lib/yattho/forms/dsl/input.rb', line 138

def validation_id
  ids[:validation]
end

#validation_message_argumentsObject



244
245
246
# File 'lib/yattho/forms/dsl/input.rb', line 244

def validation_message_arguments
  {}
end

#validation_messagesObject



191
192
193
194
195
196
197
198
199
200
# File 'lib/yattho/forms/dsl/input.rb', line 191

def validation_messages
  @validation_messages ||=
    if validation_message
      [validation_message]
    elsif builder.object.respond_to?(:errors)
      name ? builder.object.errors.full_messages_for(name) : []
    else
      []
    end
end