app/pb_kits/playbook/pb_text_input/text_input.rb
# frozen_string_literal: true
# rubocop:disable Style/SingleArgumentDig
module Playbook
module PbTextInput
class TextInput < Playbook::KitBase
VALID_MASKS = %w[currency zip_code postal_code ssn credit_card cvv].freeze
MASK_PATTERNS = {
"currency" => '^\$\d{1,3}(?:,\d{3})*(?:\.\d{2})?$',
"zip_code" => '\d{5}',
"postal_code" => '\d{5}-\d{4}',
"ssn" => '\d{3}-\d{2}-\d{4}',
"credit_card" => '\d{4} \d{4} \d{4} \d{4}',
"cvv" => '\d{3,4}',
}.freeze
prop :autocomplete, type: Playbook::Props::Boolean,
default: true
prop :disabled, type: Playbook::Props::Boolean,
default: false
prop :error
prop :inline, type: Playbook::Props::Boolean,
default: false
prop :input_options, type: Playbook::Props::HashProp,
default: {}
prop :label
prop :name
prop :placeholder
prop :required, type: Playbook::Props::Boolean,
default: false
prop :type, default: "text"
prop :validation, type: Playbook::Props::HashProp,
default: {}
prop :value
prop :add_on, type: Playbook::Props::NestedProps,
nested_kit: Playbook::PbTextInput::AddOn
prop :mask, type: Playbook::Props::Enum,
values: ["currency", "zip_code", "postal_code", "ssn", "credit_card", "cvv", nil],
default: nil
def classname
default_margin_bottom = margin_bottom.present? ? "" : " mb_sm"
generate_classname("pb_text_input_kit") + default_margin_bottom + error_class + inline_class
end
def input_tag
tag(:input, all_input_options)
end
def has_add_on?
add_on.present?
end
def add_on_class
has_add_on? ? "text_input_wrapper_add_on" : nil
end
def add_on_props
{ dark: dark }.merge(add_on || {})
end
def sanitized_id
"#{object.id}-sanitized" if id.present?
end
private
def all_input_options
{
autocomplete: autocomplete ? nil : "off",
class: "text_input #{input_options.dig(:classname) || ''}",
data: validation_data,
disabled: disabled,
id: input_options.dig(:id) || id,
name: mask.present? ? "" : name,
pattern: validation_pattern || mask_pattern,
placeholder: placeholder,
required: required,
type: type,
value: value,
mask: mask,
}.merge(input_options)
end
def validation_message
validation[:message] || ""
end
def validation_pattern
validation[:pattern] || nil
end
def validation_data
fields = input_options.dig(:data) || {}
fields[:message] = validation_message unless validation_message.blank?
mask ? fields.merge(pb_input_mask: true) : fields
end
def error_class
error ? " error" : ""
end
def inline_class
inline ? " inline" : ""
end
def mask_data
return {} unless mask
raise ArgumentError, "mask must be one of: #{VALID_MASKS.join(', ')}" unless VALID_MASKS.include?(mask)
{ mask: mask }
end
def mask_pattern
return nil unless mask
MASK_PATTERNS[mask]
end
end
end
end
# rubocop:enable Style/SingleArgumentDig