Class: Daisy::DataInput::OtpComponent

Inherits:
LocoMotion::BaseComponent show all
Includes:
LocoMotion::Concerns::AriableComponent
Defined in:
app/components/daisy/data_input/otp_component.rb

Overview

Note:

DaisyUI sizes the boxes for up to 8 digits, so length must be between 1 and 8.

The OTP component renders a DaisyUI styled input for one-time passwords — the 4-6 digit verification codes used in two-factor authentication and passwordless login flows. It draws one character box per digit while backing them with a single <input>, so the value submits like any other form field and no JavaScript is required.

The wrapper is a <label>, so clicking anywhere on the boxes focuses the underlying input. The input is rendered with inputmode="numeric" (mobile numeric keypad), autocomplete="one-time-code" (OS auto-fill from SMS), and a maxlength / pattern matching the digit count.

Constant Summary collapse

MAX_LENGTH =

The largest digit count DaisyUI's otp CSS can lay out.

8

Constants inherited from LocoMotion::BaseComponent

LocoMotion::BaseComponent::EMPTY_PART_IGNORED_TAGS, LocoMotion::BaseComponent::SELF_CLOSING_TAGS

Instance Attribute Summary collapse

Attributes inherited from LocoMotion::BaseComponent

#config, #loco_parent

Instance Method Summary collapse

Methods inherited from LocoMotion::BaseComponent

build, #component_ref, #config_option, #cssify, define_modifier, define_modifiers, define_part, define_parts, define_size, define_sizes, #empty_part_content, #inspect, #part, register_component_initializer, register_component_setup, #rendered_css, #rendered_data, #rendered_html, #rendered_stimulus_controllers, #rendered_tag_name, renders_many, renders_one, set_component_name, #set_loco_parent, #strip_spaces

Methods included from LocoMotion::Concerns::InspectableComponent

#build_inspect_string

Constructor Details

#initialize(**kws) ⇒ OtpComponent

Instantiate a new OTP component.

Parameters:

  • kws (Hash)

    The keyword arguments for the component.

Options Hash (**kws):

  • length (Integer)

    The number of digits in the code, from 1 to 8. Also sets the input's maxlength and pattern (\d{length}) attributes. Defaults to 4.

  • name (String)

    The name attribute for the underlying input.

  • id (String)

    The ID attribute for the underlying input.

  • value (String)

    An optional pre-filled value for the input.

  • required (Boolean)

    Whether the input is required for form validation. Defaults to false.

Raises:

  • (ArgumentError)


69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'app/components/daisy/data_input/otp_component.rb', line 69

def initialize(**kws)
  super

  @length = config_option(:length, 4)
  @name = config_option(:name)
  @id = config_option(:id)
  @value = config_option(:value, nil)
  @required = config_option(:required, false)

  return if (1..MAX_LENGTH).cover?(@length)

  raise ArgumentError,
        "daisy_otp length must be between 1 and #{MAX_LENGTH} " \
        "(got #{@length.inspect})."
end

Instance Attribute Details

#idObject (readonly)

Returns the value of attribute id.



49
50
51
# File 'app/components/daisy/data_input/otp_component.rb', line 49

def id
  @id
end

#lengthObject (readonly)

Returns the value of attribute length.



49
50
51
# File 'app/components/daisy/data_input/otp_component.rb', line 49

def length
  @length
end

#nameObject (readonly)

Returns the value of attribute name.



49
50
51
# File 'app/components/daisy/data_input/otp_component.rb', line 49

def name
  @name
end

#requiredObject (readonly)

Returns the value of attribute required.



49
50
51
# File 'app/components/daisy/data_input/otp_component.rb', line 49

def required
  @required
end

#valueObject (readonly)

Returns the value of attribute value.



49
50
51
# File 'app/components/daisy/data_input/otp_component.rb', line 49

def value
  @value
end

Instance Method Details

#before_renderObject

Calls the #setup_component method before rendering the component.



88
89
90
91
92
# File 'app/components/daisy/data_input/otp_component.rb', line 88

def before_render
  super

  setup_component
end

#setup_componentObject

Sets up the wrapper <label>, the digit <span> boxes, and the underlying <input> with its numeric / one-time-code attributes.

The digit spans must precede the input: DaisyUI positions and sizes the boxes with nth-child selectors that count every child of the wrapper.



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'app/components/daisy/data_input/otp_component.rb', line 102

def setup_component
  set_tag_name(:component, :label)
  add_css(:component, "otp")

  set_tag_name(:digit, :span)

  set_tag_name(:input, :input)
  add_html(:input, {
             type: "text",
             inputmode: "numeric",
             autocomplete: "one-time-code",
             maxlength: @length,
             pattern: "\\d{#{@length}}",
             name: @name,
             id: @id,
             value: @value,
             required: @required
           })
end