Module: Phlex::Reactive::ClientBindings
- Extended by:
- ActiveSupport::Concern
- Included in:
- Component
- Defined in:
- lib/phlex/reactive/client_bindings.rb
Overview
The blessed CLIENT-ONLY include (issue #180). A view that only shows/hides (reactive_show), filters (reactive_filter), computes client-side (reactive_compute), or runs zero-round-trip ops (on_client/js) — with NO server actions and NO signed token — includes this instead of the full Phlex::Reactive::Component.
Why it exists: including the full Component pulls in Streamable, whose class/instance methods (replace/update/append/prepend/remove, to_stream_*) collide by NAME with an app's own Turbo-stream concern — so adopters cherry-picked an internal module and hand-rolled a token-less root (and defined a dummy #id "never read at render" just to keep phlex_reactive:doctor quiet). ClientBindings is that missing seam, blessed:
class ExerciseFilter < ApplicationComponent
include Phlex::Reactive::ClientBindings
reactive_scope :form
def reactive_values = { role: @role }
def view_template
div(**reactive_root) do # token-less: no #id required
select(name: "form[role]") { }
div(**reactive_show(if: { role: "individual" })) { demographics }
end
end
end
It includes the DECLARATION DSL and the view Helpers, but NOT Streamable (nothing to clobber) or Identity (no token). So a ClientBindings class never enters Streamable.registered_classes and is invisible to phlex_reactive:doctor's #id check — no dummy #id, no nag.
The client-only DSL macros (reactive_scope, reactive_compute) work; the SERVER-ACTION macros (action, reactive_record, reactive_state) RAISE at class-definition time — without Identity they could only silently no-op (sign nothing, dispatch nowhere), so the guard fails loudly (the guard lives in Component::DSL#require_server_actions!, keyed on Identity presence).
Helpers is token-tolerant (issue #180): reactive_attrs emits a token only when reactive_token is available, and reactive_root uses #id only when defined — so the client-only view helpers work with no Identity/Streamable.
The full Component includes ClientBindings too (ONE implementation of the client-only surface), then layers Streamable + Identity on top — so a token-bearing reactive_root is a SUPERSET, not a fork.
Constant Summary
Constants included from Phlex::Reactive::Component::Helpers
Phlex::Reactive::Component::Helpers::EMPTY_PARAMS_JSON, Phlex::Reactive::Component::Helpers::LEGACY_SHOW_CONNECTIVE_KEYS, Phlex::Reactive::Component::Helpers::LEGACY_SHOW_PREDICATE_KEYS, Phlex::Reactive::Component::Helpers::LISTNAV_ACTIONS, Phlex::Reactive::Component::Helpers::OPTIMISTIC_CLASS_OPS, Phlex::Reactive::Component::Helpers::SHOW_CONDITION_KEYS
Constants included from Phlex::Reactive::Component::DSL
Phlex::Reactive::Component::DSL::MIRROR_ID_SELECTOR
Method Summary
Methods included from Phlex::Reactive::Component::Helpers
#busy_on, #compute_inputs_param, #compute_mirror_param, #js, #mark_authorized!, #nested_attributes, #nested_update!, #on, #on_client, #reactive_attrs, #reactive_compute_attrs, #reactive_connection_id, #reactive_field, #reactive_filter, #reactive_input, #reactive_listnav, #reactive_root, #reactive_select, #reactive_show, #reactive_show_targets, #reactive_text, #reply