Module: MaquinaStream::Components::Contract

Defined in:
lib/maquina_stream/components/contract.rb

Overview

The engine's half of a vendored component.

A vendored partial is a maquina_components component that happens to live here for now: it knows about variants, parts and css_classes, and about nothing else. Everything that belongs to THIS engine — the data-ms-* DOM contract from docs/javascript.md, the ms-* Stimulus identifiers, and the maquina_stream.* labels — is supplied from the call site, and this is the call site.

Contract.apply(:code_block, {lang: "ruby", source: raw}, config: config)
# => {lang: "ruby", source: raw,
#     data: {ms_code: "", ms_code_lang: "ruby"},
#     source_attributes: {"data-ms-code-source" => ""},
#     copy_label: "Copiar", …}

Two callers, and only two: ComponentsHelper#component and the fence renderer in Renderer::PostPass, which renders the same partial from outside a request. Components render through the seam, never directly — a host that reaches for a vendored partial by path gets markup with none of this on it. Extraction deletes nothing here: this file is what the engine keeps when the partials leave.

Caller locals win over ours, so a host can name a label itself. The exception is data, which is merged rather than replaced: the DOM contract is not the host's to drop, and controller concatenates so a host's own controller rides along with ours.

Four components have engine locals — :code_block, :snippet, :attachment and :suggestion. Any other name passes its locals through untouched.

Class Method Summary collapse

Class Method Details

.apply(name, locals, config: MaquinaStream.config) ⇒ Object

Returns locals with the engine's own locals folded in.

name is the component name, locals the Hash a call site passed. Unknown names return locals unchanged, so this is safe to call on every component render.



44
45
46
47
48
49
50
51
52
53
# File 'lib/maquina_stream/components/contract.rb', line 44

def apply(name, locals, config: MaquinaStream.config)
  engine = engine_locals(name.to_sym, locals, config)
  return locals if engine.empty?

  data = merge_data(engine.delete(:data) || {}, locals[:data] || locals["data"])
  merged = engine.merge(locals)
  merged.delete("data")
  merged[:data] = data unless data.empty?
  merged
end

.merge_data(own, provided) ⇒ Object

Merges the engine's data attributes with a caller's, and returns the result.

Same rule as ComponentsHelper#component_data, applied one level earlier: ours wins its own keys, controller and action concatenate with ours first. The helper travels to maquina_components with the partials; this stays, so the rule is written out here rather than borrowed.



63
64
65
66
67
68
69
70
# File 'lib/maquina_stream/components/contract.rb', line 63

def merge_data(own, provided)
  own = own.compact
  provided = (provided || {}).transform_keys { |key| key.to_s.tr("-", "_").to_sym }

  provided.merge(own) do |key, theirs, ours|
    i[controller action].include?(key) ? [ours, theirs].compact.join(" ").strip : ours
  end.compact
end