Module: Plushie::Widget::Build

Defined in:
lib/plushie/widget/build.rb

Overview

Internal helpers for widget builder build implementations.

Class Method Summary collapse

Class Method Details

.children_to_nodes(children) ⇒ Object

Converts an array of children (Nodes or builder objects) to Nodes.



17
18
19
20
21
22
23
24
25
# File 'lib/plushie/widget/build.rb', line 17

def children_to_nodes(children)
  children.map do |child|
    case child
    when Plushie::Node then child
    else
      child.respond_to?(:build) ? child.build : child
    end
  end
end

.put_if(props, key, value) ⇒ Object

Adds key => value to props hash if value is non-nil.



11
12
13
14
# File 'lib/plushie/widget/build.rb', line 11

def put_if(props, key, value)
  props[key] = value unless value.nil?
  props
end

.resolve_a11y(props, defaults) ⇒ Hash{String => Object}?

Resolve a11y defaults for a widget.

Merges default a11y annotations (role, label) with any user-provided a11y. User overrides win per field. Returns a string-keyed hash matching the wire protocol format so downstream code (infer_radio_groups, encode_props) never sees mixed key types.

Parameters:

  • props (Hash)

    widget props (may include :a11y)

  • defaults (Hash)

    declared a11y defaults (:role, :label_from)

Returns:

  • (Hash{String => Object}, nil)

    resolved a11y hash, or nil if empty



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/plushie/widget/build.rb', line 72

def resolve_a11y(props, defaults)
  user_a11y = props[:a11y]

  # Build resolved hash with string keys (wire-ready format).
  resolved = {} #: Hash[String, untyped]
  resolved["role"] = defaults[:role].to_s if defaults[:role]

  # Derive label from another prop if declared
  if defaults[:label_from] && !user_a11y&.key?(:label) && !user_a11y&.key?("label")
    label_val = props[defaults[:label_from]]
    resolved["label"] = label_val.to_s if label_val
  end

  # Merge user overrides (user wins per field).
  # Normalize user keys to strings for consistency.
  if user_a11y.is_a?(Hash)
    user_a11y.each { |k, v| resolved[k.to_s] = v }
  end

  resolved.empty? ? nil : resolved
end

.validate_children_count!(id, type, children, expected) ⇒ Object

Validates that a widget has exactly the expected number of children.

Raises ArgumentError if the children count does not match expected. Called from #build for widgets with strict child count requirements (overlay requires exactly 2).

Parameters:

  • id (String)

    widget ID for the error message

  • type (String)

    widget type name for the error message

  • children (Array)

    children to validate

  • expected (Integer)

    required child count

Raises:

  • (ArgumentError)

    if children.length != expected



55
56
57
58
59
# File 'lib/plushie/widget/build.rb', line 55

def validate_children_count!(id, type, children, expected)
  return if children.length == expected
  raise ArgumentError,
    "#{type} #{id.inspect} requires exactly #{expected} children, got #{children.length}"
end

.validate_single_child!(id, type, children) ⇒ Object

Validates that a widget has at most one child.

Raises ArgumentError if the children list has more than one element. Called from #build in single-child wrappers (container, tooltip, pointer_area, scrollable, themer, floating, responsive, pin, sensor, window).

Parameters:

  • id (String)

    widget ID for the error message

  • type (String)

    widget type name for the error message

  • children (Array)

    children to validate

Raises:

  • (ArgumentError)

    if children.length > 1



38
39
40
41
42
# File 'lib/plushie/widget/build.rb', line 38

def validate_single_child!(id, type, children)
  return if children.length <= 1
  raise ArgumentError,
    "#{type} #{id.inspect} accepts at most 1 child, got #{children.length}"
end