83 lines
1.8 KiB
Ruby
83 lines
1.8 KiB
Ruby
class Dsfr::InputComponent < ApplicationComponent
|
|
include Dsfr::InputErrorable
|
|
|
|
delegate :object, to: :@form
|
|
delegate :errors, to: :object
|
|
|
|
# use it to indicate detailed about the inputs, ex: https://www.systeme-de-design.gouv.fr/elements-d-interface/modeles-et-blocs-fonctionnels/demande-de-mot-de-passe
|
|
# it uses aria-describedby on input and link it to yielded content
|
|
renders_one :describedby
|
|
renders_one :label
|
|
|
|
def initialize(form:, attribute:, input_type: :text_field, opts: {}, required: true)
|
|
@form = form
|
|
@attribute = attribute
|
|
@input_type = input_type
|
|
@opts = opts
|
|
@required = required
|
|
end
|
|
|
|
def dsfr_champ_container
|
|
:div
|
|
end
|
|
|
|
# add invalid class on input when input is invalid
|
|
# and and valid on input only if another input is invalid
|
|
def input_group_opts
|
|
opts = {
|
|
class: class_names({
|
|
'fr-input-group': true,
|
|
'fr-password': password?
|
|
}.merge(input_group_error_class_names))
|
|
}
|
|
if email?
|
|
opts[:data] = { controller: 'email-input' }
|
|
end
|
|
opts
|
|
end
|
|
|
|
def label_opts
|
|
{ class: class_names('fr-label': true, 'fr-password__label': password?) }
|
|
end
|
|
|
|
# errors helpers
|
|
def error_messages
|
|
errors.full_messages_for(attribute_or_rich_body)
|
|
end
|
|
|
|
def describedby_id
|
|
dom_id(object, "#{@attribute}-messages")
|
|
end
|
|
|
|
# i18n lookups
|
|
def label
|
|
get_slot(:label).presence || default_label
|
|
end
|
|
|
|
def dsfr_input_classname
|
|
'fr-input'
|
|
end
|
|
|
|
# kind of input helpers
|
|
def password?
|
|
@input_type == :password_field
|
|
end
|
|
|
|
def email?
|
|
@input_type == :email_field
|
|
end
|
|
|
|
def required?
|
|
@required
|
|
end
|
|
|
|
def show_password_id
|
|
dom_id(object, "#{@attribute}_show_password")
|
|
end
|
|
|
|
private
|
|
|
|
def default_label
|
|
object.class.human_attribute_name(@attribute)
|
|
end
|
|
end
|