class Playbook::KitBase

def combined_html_options

def combined_html_options
  ho = html_options
  inline = dynamic_inline_props
  # Fast path: no custom html_options and no inline styles (the common case)
  return data_attributes if ho.empty? && inline.nil?
  merged = default_html_options.dup
  ho.each do |key, value|
    if key == :style && value.is_a?(Hash)
      merged[:style] = value.map { |k, v| "#{k.to_s.tr('_', '-')}: #{v}" }.join("; ")
    else
      merged[key] = value
    end
  end
  if inline
    merged[:style] = merged[:style] ? "#{merged[:style]}; #{inline}" : inline
  end
  merged.deep_merge(data_attributes)
end

def data_attributes

def data_attributes
  { data: data, aria: aria }
end

def default_html_options

def default_html_options
  {}
end

def dynamic_inline_props

def dynamic_inline_props
  return @dynamic_inline_props if defined?(@dynamic_inline_props)
  @dynamic_inline_props = begin
    gip = global_inline_props
    if gip.empty?
      nil
    else
      styles = gip.filter_map { |key, value| "#{key.to_s.tr('_', '-')}: #{value}" if inline_validator(key, value) }
      styles.empty? ? nil : styles.join("; ")
    end
  end
end

def global_inline_props

def global_inline_props
  h = height
  mh = min_height
  xh = max_height
  return EMPTY_HASH if h.nil? && mh.nil? && xh.nil?
  r = {}
  r[:height] = h if h
  r[:min_height] = mh if mh
  r[:max_height] = xh if xh
  r
end

def inline_validator(key, value)

def inline_validator(key, value)
  return false if value.nil?
  return false if height_values.include?(value) && key == :height
  return false if min_height_values.include?(value) && key == :min_height
  return false if max_height_values.include?(value) && key == :max_height
  true
end

def kit_base_default_options

def kit_base_default_options
  options = {
    id: id,
    data: data,
    class: classname,
    aria: aria,
  }
  inline_styles = dynamic_inline_props
  options[:style] = inline_styles if inline_styles.present? && !html_options.key?(:style)
  options
end

def object

def object
  self
end

def pb_content_tag(name = :div, content_or_options_with_block = {}, options = {}, escape = true, &block)

rubocop:disable Style/OptionalBooleanParameter
def pb_content_tag(name = :div, content_or_options_with_block = {}, options = {}, escape = true, &block)
  combined_options = options
                     .merge(combined_html_options)
                     .merge(kit_base_default_options.merge(content_or_options_with_block))
  content_tag(name, combined_options, options, escape, &block)
end

def react_component(component_name, props = {}, html_options = {})

Sister def in app/helpers/react_helper in playbook-website. Any changes here should be reflected there.
The mounting script will look for these divs and mount the appropriate React components
This will render a div with data attributes for the component name and props
Custom react_component helper to replace Webpacker React
def react_component(component_name, props = {}, html_options = {})
  # Convert props to JSON for the data attribute
  props_json = props.to_json
  # Build the HTML attributes
  html_attrs = {
    "data-pb-react-component" => component_name,
    "data-pb-react-props" => props_json,
  }
  # Merge with any additional HTML options
  html_attrs.merge!(html_options)
  # Return the div element
  content_tag(:div, "", html_attrs)
end