Module: Klods::Core

Defined in:
lib/klods/core.rb

Class Method Summary collapse

Class Method Details

.build(tag:, base:, modifiers: {}, props: {}, children: nil) ⇒ Object

BEM builder factory — resolves modifier props into BEM classes, passes everything else through as HTML attributes.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/klods/core.rb', line 44

def build(tag:, base:, modifiers: {}, props: {}, children: nil)
  props = props.dup

  resolved_children = if children.nil?
    props.delete(:children) || props.delete("children")
  else
    props.delete(:children)
    props.delete("children")
    children
  end

  mod_classes = []
  passthrough = {}

  props.each do |key, value|
    sym = key.is_a?(Symbol) ? key : key.to_s.to_sym
    mod = modifiers[sym] || modifiers[key.to_s]
    if mod
      if mod.respond_to?(:call)
        cls = mod.call(value)
        mod_classes << cls if cls
      elsif value
        mod_classes << mod
      end
    else
      passthrough[key] = value
    end
  end

  user_class = passthrough.delete(:class) || passthrough.delete("class")
  final_class = merge_classes(base, *mod_classes, user_class)

  attrs = passthrough
  attrs["class"] = final_class unless final_class.empty?

  Node.new(tag, attrs, resolved_children)
end

.class_names(*parts) ⇒ Object



23
24
25
# File 'lib/klods/core.rb', line 23

def class_names(*parts)
  parts.flatten.compact.map(&:to_s).reject(&:empty?).join(" ")
end

.el(tag, a = nil, b = nil) ⇒ Object



37
38
39
40
# File 'lib/klods/core.rb', line 37

def el(tag, a = nil, b = nil)
  props, children = normalize_args(a, b)
  Node.new(tag, props, children)
end

.merge_classes(*inputs) ⇒ Object



19
20
21
# File 'lib/klods/core.rb', line 19

def merge_classes(*inputs)
  inputs.map { |c| resolve_class(c) }.reject(&:empty?).join(" ")
end

.normalize_args(a = nil, b = nil) ⇒ Object

Splits (props_or_children, children?) into [props_hash, children]. A Hash first arg is props; anything else (string, array, Node, nil) is children.



29
30
31
32
33
34
35
# File 'lib/klods/core.rb', line 29

def normalize_args(a = nil, b = nil)
  if a.is_a?(Hash) || a.nil?
    [a || {}, b]
  else
    [{}, a]
  end
end

.raw(html) ⇒ Object



5
6
7
# File 'lib/klods/core.rb', line 5

def raw(html)
  RawHtml.new(html)
end

.resolve_class(input) ⇒ Object



9
10
11
12
13
14
15
16
17
# File 'lib/klods/core.rb', line 9

def resolve_class(input)
  case input
  when nil then ""
  when String then input.strip
  when Array then input.flatten.filter_map { |c| resolve_class(c) unless resolve_class(c).empty? }.join(" ")
  when Hash then input.filter_map { |k, v| k.to_s if v }.join(" ")
  else input.to_s.strip
  end
end

.slug_id(prefix, text) ⇒ Object



82
83
84
85
86
87
88
89
90
# File 'lib/klods/core.rb', line 82

def slug_id(prefix, text)
  safe = text.to_s
  slug = safe.downcase.gsub(/[^a-z0-9]+/, "-").gsub(/^-|-$/, "")
  return "#{prefix}-#{slug}" unless slug.empty?

  h = 5381
  safe.each_char { |c| h = ((h << 5) + h + c.ord) & 0xffffffff }
  "#{prefix}-#{h.to_s(36)}"
end