Class: Weft::Component
- Inherits:
-
Arbre::Component
- Object
- Arbre::Component
- Weft::Component
- Extended by:
- Registry::Eligibility
- Includes:
- Weft::Context::Interception, DSL::Actions, DSL::Attributes, DSL::Containers, DSL::Inclusions, DSL::Recoveries, DSL::Triggers, DSL::Updates
- Defined in:
- lib/weft/component.rb
Overview
Base class for all Weft components. Extends Arbre::Component with:
- Attribute DSL for declaring wire state
- Convention-based DOM ID and partial URL
- Auto-registration with the global Registry
Direct Known Subclasses
Class Attribute Summary collapse
-
.component_path ⇒ Object
Class-level path override (string or proc).
Attributes included from DSL::Attributes
Class Method Summary collapse
-
.inferred_routable? ⇒ Boolean
Inferred routability from declared state, ignoring any explicit override (see Weft::Registry::Eligibility#routable?).
- .inherited(subclass) ⇒ Object
-
.render(**attributes) ⇒ Object
Render this component as an HTML string, outside any Arbre DSL context.
-
.resolved_component_path ⇒ Object
Resolves the actual path string for this component class.
-
.weft_id_for(attrs = {}) ⇒ Object
Compute the would-be DOM ID for an instance of this class given a plain attrs hash, without instantiating.
Instance Method Summary collapse
- #build(attributes = {}) ⇒ Object
-
#weft_id ⇒ Object
Convention-based DOM ID: dasherized class name + primary attribute value.
-
#weft_url(**overrides) ⇒ Object
URL to this component's Weft route with current attrs as query params.
Methods included from Registry::Eligibility
abstract!, routable!, routable?, stale?
Methods included from Weft::Context::Interception
Methods included from DSL::Containers
Methods included from DSL::Actions
Methods included from DSL::Updates
Methods included from DSL::Inclusions
Methods included from DSL::Triggers
Methods included from DSL::Recoveries
Methods included from DSL::Attributes
Class Attribute Details
.component_path ⇒ Object
Class-level path override (string or proc). Inherited by subclasses.
24 25 26 27 28 29 30 |
# File 'lib/weft/component.rb', line 24 def component_path if instance_variable_defined?(:@component_path) @component_path elsif superclass.respond_to?(:component_path) superclass.component_path end end |
Class Method Details
.inferred_routable? ⇒ Boolean
Inferred routability from declared state, ignoring any explicit override (see Weft::Registry::Eligibility#routable?). A component is independently addressable when it declares interactive behavior — attributes, actions, refresh triggers, or push config. Pure presentational components (none of those) register but are never served. Subclasses fall back to this when they have no override of their own, so an abstract parent does not disable concrete children.
52 53 54 |
# File 'lib/weft/component.rb', line 52 def inferred_routable? attributes.any? || actions.any? || refresh_triggers.any? || !push_config.nil? end |
.inherited(subclass) ⇒ Object
56 57 58 59 |
# File 'lib/weft/component.rb', line 56 def inherited(subclass) super Weft.registry.register(subclass) end |
.render(**attributes) ⇒ Object
Render this component as an HTML string, outside any Arbre DSL context. Used by the Router for partial responses, and available to users for testing, REPL exploration, or any standalone rendering need.
StatCard.render(status: "shipped") # => "<div id=\"...\">...</div>"
66 67 68 69 70 71 |
# File 'lib/weft/component.rb', line 66 def render(**attributes) klass = self Weft::Context.new({}, nil) do insert_tag(klass, **attributes) end.to_s end |
.resolved_component_path ⇒ Object
Resolves the actual path string for this component class. An explicit class-level override (string or proc) wins; otherwise the configured default proc derives one from the class name (see default_component_path).
37 38 39 40 41 42 43 |
# File 'lib/weft/component.rb', line 37 def resolved_component_path case (path = component_path) when Proc then path.call(self) when String then path else default_component_path end end |
.weft_id_for(attrs = {}) ⇒ Object
Compute the would-be DOM ID for an instance of this class given a
plain attrs hash, without instantiating. The Router uses this to
populate the :component_id auto-injected attribute when a recovery
target opts in. Single source of truth; the instance method delegates.
77 78 79 80 81 |
# File 'lib/weft/component.rb', line 77 def weft_id_for(attrs = {}) base = name.underscore.tr("/", "-").tr("_", "-") primary_value = attrs.respond_to?(:values) ? attrs.values.first : nil primary_value ? "#{base}-#{primary_value}" : base end |
Instance Method Details
#build(attributes = {}) ⇒ Object
113 114 115 116 117 118 119 120 |
# File 'lib/weft/component.rb', line 113 def build(attributes = {}) schema = self.class.attributes @attrs = Weft::Attributes.extract_from(attributes, using: schema) super(attributes.except(*schema.keys)) self.id = weft_id apply_refresh_attrs apply_push_attrs end |
#weft_id ⇒ Object
Convention-based DOM ID: dasherized class name + primary attribute value.
135 136 137 |
# File 'lib/weft/component.rb', line 135 def weft_id self.class.weft_id_for(@attrs ? @attrs.to_h : {}) end |
#weft_url(**overrides) ⇒ Object
URL to this component's Weft route with current attrs as query params. Pass overrides to change specific attr values in the URL.
weft_url # => "/_components/orders_panel?status=shipped&page=1"
weft_url(page: 2) # => "/_components/orders_panel?status=shipped&page=2"
weft_url(status: nil, page: 1) # => "/_components/orders_panel?page=1"
128 129 130 131 132 |
# File 'lib/weft/component.rb', line 128 def weft_url(**overrides) path = self.class.resolved_component_path params = @attrs.to_h.merge(overrides).compact params.empty? ? path : "#{path}?#{URI.encode_www_form(params)}" end |