Class: HakumiComponents::Statistic::Component

Inherits:
BaseComponent
  • Object
show all
Extended by:
T::Sig
Includes:
ActionView::Helpers::NumberHelper
Defined in:
app/components/hakumi_components/statistic/component.rb

Constant Summary collapse

Value =
T.type_alias { T.nilable(T.any(Numeric, String, BaseComponent::DateLikeValue)) }
FormatValue =
T.type_alias { T.nilable(String) }
PrecisionInput =
T.type_alias { T.nilable(T.any(Integer, String)) }
DurationInput =
T.type_alias { T.any(Numeric, String) }
DEFAULT_DURATION =
T.let(800, Integer)
DEFAULT_COUNTDOWN_FORMAT =
T.let("HH:mm:ss", String)

Constants inherited from BaseComponent

BaseComponent::ControllerOptions, BaseComponent::DateInput, BaseComponent::DateLikeValue, BaseComponent::DimensionInput, BaseComponent::HtmlPayloadInput, BaseComponent::I18nOptionValue, BaseComponent::PresenceArray, BaseComponent::PresenceScalar, BaseComponent::PresenceValue, BaseComponent::RawHtmlInput, BaseComponent::SIZES, BaseComponent::SizeValue, BaseComponent::SymbolInput

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from BaseComponent

#append_data_token, boolean_html_param, #build_inline_style, cast_boolean, #cast_boolean, #class_names, #component_classes, #data_attributes_from, #dimension_to_css, #ensure_dom_id!, float_html_param, #generate_id, #html_classes, html_param, html_primitive_param, #html_style, #i18n_scope, integer_html_param, #merge_attributes, #render_value, #size_to_pixels, #stimulus_attrs, string_html_param, string_or_symbol_array_html_param, symbol_html_param, #t_default, #translate_with_default, #validate_inclusion!, #validate_required!, #value_present?

Constructor Details

#initialize(title: nil, value: nil, precision: nil, prefix: nil, suffix: nil, animated: false, duration: DEFAULT_DURATION, countdown: false, format: nil, aria_label: nil, **html_options) ⇒ Component

Returns a new instance of Component.



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'app/components/hakumi_components/statistic/component.rb', line 94

def initialize(
  title: nil,
  value: nil,
  precision: nil,
  prefix: nil,
  suffix: nil,
  animated: false,
  duration: DEFAULT_DURATION,
  countdown: false,
  format: nil,
  aria_label: nil,
  **html_options
)
  @title = T.let(title, Types::Renderable)
  @value = T.let(value, Value)
  @precision = T.let(normalize_precision(precision), T.nilable(Integer))
  @prefix = T.let(prefix, Types::Renderable)
  @suffix = T.let(suffix, Types::Renderable)
  @animated = T.let(cast_boolean(animated) ? true : false, T::Boolean)
  @duration = T.let(normalize_duration(duration), Float)
  @countdown = T.let(cast_boolean(countdown) ? true : false, T::Boolean)
  @format = T.let(normalize_format(format), T.nilable(String))
  @aria_label = T.let(normalize_string(aria_label), T.nilable(String))
  @html_options = T.let(html_options, Types::HtmlAttributes)
  @numeric_value = T.let(resolve_numeric_value(@value), T.nilable(Float))

  validate_props!
end

Class Method Details

.extract_controller_locals(params) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'app/components/hakumi_components/statistic/component.rb', line 28

def self.extract_controller_locals(params)
  {
    title: html_primitive_param(html_param(params, :title)),
    value: parse_value_param(html_param(params, :value)),
    precision: parse_integer(html_param(params, :precision)),
    prefix: html_primitive_param(html_param(params, :prefix)),
    suffix: html_primitive_param(html_param(params, :suffix)),
    animated: boolean_html_param(html_param(params, :animated)),
    duration: parse_number(html_param(params, :duration)),
    countdown: boolean_html_param(html_param(params, :countdown)),
    format: html_primitive_param(html_param(params, :format)),
    aria_label: html_primitive_param(html_param(params, :aria_label))
  }
end

.parse_integer(value) ⇒ Object



68
69
70
71
72
73
74
75
76
77
# File 'app/components/hakumi_components/statistic/component.rb', line 68

def self.parse_integer(value)
  return nil if value.nil?
  return value if value.is_a?(Integer)
  return value.to_i if value.is_a?(Float)
  return nil unless value.is_a?(String)

  Integer(value) if value.strip != ""
rescue ArgumentError
  nil
end

.parse_number(value) ⇒ Object



57
58
59
60
61
62
63
64
65
# File 'app/components/hakumi_components/statistic/component.rb', line 57

def self.parse_number(value)
  return nil if value.nil?
  return value.to_f if value.is_a?(Numeric)
  return nil unless value.is_a?(String)

  Float(value) if value.strip != ""
rescue ArgumentError
  nil
end

.parse_value_param(value) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
# File 'app/components/hakumi_components/statistic/component.rb', line 44

def self.parse_value_param(value)
  return nil if value.nil?
  return value if value.is_a?(Numeric)

  string_value = value.to_s.strip
  return nil if string_value.empty?

  Float(string_value)
rescue ArgumentError
  string_value
end

Instance Method Details

#animated?Boolean

Returns:

  • (Boolean)


173
174
175
# File 'app/components/hakumi_components/statistic/component.rb', line 173

def animated?
  @animated
end

#countdown?Boolean

Returns:

  • (Boolean)


168
169
170
# File 'app/components/hakumi_components/statistic/component.rb', line 168

def countdown?
  @countdown
end

#countdown_formatObject



188
189
190
191
192
# File 'app/components/hakumi_components/statistic/component.rb', line 188

def countdown_format
  return nil unless countdown?

  @format || DEFAULT_COUNTDOWN_FORMAT
end

#countdown_target_timestampObject



178
179
180
181
182
183
184
185
# File 'app/components/hakumi_components/statistic/component.rb', line 178

def countdown_target_timestamp
  return nil unless countdown?

  target = normalize_countdown_target(@value)
  return nil unless target

  (target.to_f * 1000).round
end

#display_valueObject



158
159
160
161
162
163
164
165
# File 'app/components/hakumi_components/statistic/component.rb', line 158

def display_value
  block_content = content
  return block_content if block_content.present?
  return formatted_countdown_value if countdown?
  return formatted_numeric_value unless @numeric_value.nil?

  fallback_display_value
end

#numeric_valueObject



195
196
197
# File 'app/components/hakumi_components/statistic/component.rb', line 195

def numeric_value
  @numeric_value
end

#prefix_contentObject



144
145
146
147
148
# File 'app/components/hakumi_components/statistic/component.rb', line 144

def prefix_content
  return render_value(prefix) if prefix?

  render_value(@prefix)
end

#suffix_contentObject



151
152
153
154
155
# File 'app/components/hakumi_components/statistic/component.rb', line 151

def suffix_content
  return render_value(suffix) if suffix?

  render_value(@suffix)
end

#title_contentObject



137
138
139
140
141
# File 'app/components/hakumi_components/statistic/component.rb', line 137

def title_content
  return render_value(title) if title?

  render_value(@title)
end

#wrapper_attributesObject



124
125
126
127
128
129
130
131
132
133
134
# File 'app/components/hakumi_components/statistic/component.rb', line 124

def wrapper_attributes
  attrs = {
    class: wrapper_classes,
    role: countdown? ? "timer" : "status",
    "aria-live": countdown? || animated? ? "polite" : nil,
    "aria-label": @aria_label,
    data: data_attributes
  }

  merge_attributes(attrs, @html_options)
end