Class: Emjay::BodyComponent
- Defined in:
- lib/emjay/body_component.rb
Overview
Base class for body components. Port of JS BodyComponent from createComponent.js.
Direct Known Subclasses
Components::MjAccordion, Components::MjAccordionElement, Components::MjAccordionText, Components::MjAccordionTitle, Components::MjBody, Components::MjButton, Components::MjCarousel, Components::MjCarouselImage, Components::MjColumn, Components::MjDivider, Components::MjGroup, Components::MjHero, Components::MjImage, Components::MjNavbar, Components::MjNavbarLink, Components::MjRaw, Components::MjSection, Components::MjSocial, Components::MjSocialElement, Components::MjSpacer, Components::MjTable, Components::MjText
Instance Attribute Summary
Attributes inherited from Component
Instance Method Summary collapse
- #get_box_widths ⇒ Object
- #get_child_context ⇒ Object
- #get_shorthand_attr_value(attribute, direction) ⇒ Object
- #get_shorthand_border_value(direction, attribute = "border") ⇒ Object
- #get_styles ⇒ Object
-
#html_attributes(attrs) ⇒ Object
Builds an HTML attribute string.
-
#render_children(children = nil, opts = {}) ⇒ Object
Renders child components.
-
#styles(name_or_hash) ⇒ Object
Converts a style hash (or style name string) to an inline CSS string.
Methods inherited from Component
allowed_attributes, component_name, default_attributes, ending_tag?, #get_attribute, #get_content, #initialize, raw_element?
Constructor Details
This class inherits a constructor from Emjay::Component
Instance Method Details
#get_box_widths ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/emjay/body_component.rb', line 68 def get_box_widths container_width = @context[:container_width] parsed_width = container_width.to_i paddings = get_shorthand_attr_value("padding", "right") + get_shorthand_attr_value("padding", "left") borders = get_shorthand_border_value("right") + get_shorthand_border_value("left") { total_width: parsed_width, borders: borders, paddings: paddings, box: parsed_width - paddings - borders } end |
#get_child_context ⇒ Object
86 87 88 |
# File 'lib/emjay/body_component.rb', line 86 def get_child_context @context end |
#get_shorthand_attr_value(attribute, direction) ⇒ Object
52 53 54 55 56 57 58 59 60 |
# File 'lib/emjay/body_component.rb', line 52 def get_shorthand_attr_value(attribute, direction) dir_attr = get_attribute("#{attribute}-#{direction}") return dir_attr.to_i if dir_attr base_attr = get_attribute(attribute) return 0 unless base_attr ShorthandParser.call(base_attr, direction) end |
#get_shorthand_border_value(direction, attribute = "border") ⇒ Object
62 63 64 65 66 |
# File 'lib/emjay/body_component.rb', line 62 def get_shorthand_border_value(direction, attribute = "border") border_direction = direction && get_attribute("#{attribute}-#{direction}") border = get_attribute(attribute) BorderParser.call(border_direction || border || "0") end |
#get_styles ⇒ Object
10 11 12 |
# File 'lib/emjay/body_component.rb', line 10 def get_styles {} end |
#html_attributes(attrs) ⇒ Object
Builds an HTML attribute string. The ‘style:` key auto-resolves through #styles.
40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/emjay/body_component.rb', line 40 def html_attributes(attrs) attrs.each_with_object(+"") do |(name, value), output| next if value.nil? resolved = if name.to_s == "style" styles(value) else value end output << " #{name}=\"#{resolved}\"" end end |
#render_children(children = nil, opts = {}) ⇒ Object
Renders child components. Supports renderer: lambda, attributes: merge, raw_xml: mode.
91 92 93 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 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/emjay/body_component.rb', line 91 def render_children(children = nil, opts = {}) renderer = opts[:renderer] || ->(component) { component.render } extra_attributes = opts[:attributes] || {} extra_props = opts[:props] || {} children = children || @props[:children] || [] sibling = children.length components = @context[:components] || {} raw_components = components.values.select { |c| c.raw_element? } non_raw_siblings = children.count { |child| !raw_components.any? { |c| c.component_name == child[:tag_name] } } output = +"" children.each_with_index do |child, index| component_class = components[child[:tag_name]] next unless component_class child_data = { attributes: extra_attributes.merge(child[:attributes] || {}), children: child[:children] || [], content: child[:content] || "", context: get_child_context, global_attributes: child[:global_attributes] || {}, raw_attrs: child[:raw_attrs] || {}, props: extra_props.merge( first: index == 0, index: index, last: index + 1 == sibling, sibling: sibling, non_raw_siblings: non_raw_siblings ) } component = component_class.new(child_data) if component.respond_to?(:head_style) @context[:add_head_style]&.call(child[:tag_name], component.method(:head_style)) end if component.respond_to?(:component_head_style) @context[:add_component_head_style]&.call(component.method(:component_head_style)) end output << renderer.call(component) end output end |
#styles(name_or_hash) ⇒ Object
Converts a style hash (or style name string) to an inline CSS string. Supports dot-notation for nested style lookups (e.g., “carousel.div”).
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/emjay/body_component.rb', line 16 def styles(name_or_hash) styles_object = if name_or_hash.is_a?(String) if name_or_hash.include?(".") parts = name_or_hash.split(".") result = get_styles parts.each { |part| result = result&.dig(part.to_sym) || result&.dig(part) } result else get_styles[name_or_hash.to_sym] || get_styles[name_or_hash] end elsif name_or_hash.is_a?(Symbol) get_styles[name_or_hash] else name_or_hash end return "" unless styles_object styles_object.each_with_object(+"") do |(name, value), output| output << "#{name}:#{value};" unless value.nil? end end |