File tree Expand file tree Collapse file tree 6 files changed +83
-9
lines changed
Expand file tree Collapse file tree 6 files changed +83
-9
lines changed Original file line number Diff line number Diff line change @@ -381,6 +381,37 @@ stimulus do
381381end
382382```
383383
384+ ### Scoped Custom Events
385+
386+ Vident provides helper methods to generate scoped event names for dispatching custom events that are unique to your component:
387+
388+ ``` ruby
389+ class MyComponent < Vident ::ViewComponent ::Base
390+ stimulus do
391+ # Define an action that responds to a scoped event
392+ actions [stimulus_scoped_event_on_window(:data_loaded ), :handle_data_loaded ]
393+ end
394+
395+ def handle_click
396+ # Dispatch a scoped event from JavaScript
397+ # This would generate: "my-component:dataLoaded"
398+ puts stimulus_scoped_event(:data_loaded )
399+
400+ # For window events, this generates: "my-component:dataLoaded@window"
401+ puts stimulus_scoped_event_on_window(:data_loaded )
402+ end
403+ end
404+
405+ # Available as both class and instance methods:
406+ MyComponent .stimulus_scoped_event(:data_loaded ) # => "my-component:dataLoaded"
407+ MyComponent .new .stimulus_scoped_event(:data_loaded ) # => "my-component:dataLoaded"
408+ ```
409+
410+ This is useful for:
411+ - Dispatching events from Stimulus controllers to communicate between components
412+ - Creating unique event names that won't conflict with other components
413+ - Setting up window-level event listeners with scoped names
414+
384415### Manual Stimulus Configuration
385416
386417For more control, configure Stimulus attributes manually:
Original file line number Diff line number Diff line change 22
33module Vident
44 module StimulusAttributes
5+ extend ActiveSupport ::Concern
6+
7+ class_methods do
8+ # Class methods for generating scoped event names
9+ def stimulus_scoped_event ( event )
10+ "#{ component_name } :#{ stimulus_js_name ( event ) } "
11+ end
12+
13+ def stimulus_scoped_event_on_window ( event )
14+ "#{ component_name } :#{ stimulus_js_name ( event ) } @window"
15+ end
16+
17+ private
18+
19+ def stimulus_js_name ( name )
20+ name . to_s . camelize ( :lower )
21+ end
22+ end
23+
524 # Parse inputs to create a StimulusController instance representing a Stimulus controller attribute
625 # examples:
726 # stimulus_controller("my_controller") => StimulusController that converts to {"controller" => "my-controller"}
@@ -212,6 +231,15 @@ def add_stimulus_classes(named_classes)
212231 end
213232 end
214233
234+ # Stimulus events name for this component
235+ def stimulus_scoped_event ( event )
236+ self . class . stimulus_scoped_event ( event )
237+ end
238+
239+ def stimulus_scoped_event_on_window ( event )
240+ self . class . stimulus_scoped_event_on_window ( event )
241+ end
242+
215243 private
216244
217245 def implied_controller
Original file line number Diff line number Diff line change @@ -33,8 +33,6 @@ def stimulus_identifier = ::Vident::StimulusComponent.stimulus_identifier_from_p
3333 def component_name
3434 @component_name ||= stimulus_identifier
3535 end
36- # It is also used to generate the prefix for Stimulus events
37- alias_method :js_event_name_prefix , :component_name
3836 end
3937
4038 # Components have the following properties
@@ -69,9 +67,6 @@ def stimulus_identifier = self.class.stimulus_identifier
6967 # An name that can helps identify the component type in the DOM or for styling purposes (its also used as a class name on the root element)
7068 def component_name = self . class . component_name
7169
72- # The prefix for Stimulus events, which is used to generate the event names for Stimulus actions
73- def js_event_name_prefix = self . class . js_event_name_prefix
74-
7570 # The `component` class name is used to create the controller name.
7671 # The path of the Stimulus controller when none is explicitly set
7772 def default_controller_path = self . class . stimulus_identifier_path
Original file line number Diff line number Diff line change @@ -103,6 +103,24 @@ stimulus do
103103end
104104```
105105
106+ ## Scoped Custom Events
107+ Generate unique event names for component communication:
108+
109+ ```ruby
110+ # Define actions that respond to scoped events
111+ stimulus do
112+ actions [stimulus_scoped_event_on_window(:data_loaded), :handle_data_loaded]
113+ end
114+
115+ # Generate scoped event names
116+ stimulus_scoped_event(:data_loaded) # => "component-name:dataLoaded"
117+ stimulus_scoped_event_on_window(:data_loaded) # => "component-name:dataLoaded@window"
118+
119+ # Available as both class and instance methods
120+ MyComponent.stimulus_scoped_event(:click)
121+ component_instance.stimulus_scoped_event(:click)
122+ ```
123+
106124## Manual Stimulus Configuration
107125```ruby
108126def root_element_attributes
Original file line number Diff line number Diff line change @@ -261,9 +261,10 @@ def test_component_stimulus_identifier_path
261261 assert_equal expected_path , Greeters ::GreeterWithTriggerComponent . stimulus_identifier_path
262262 end
263263
264- def test_component_js_event_name_prefix
264+ def test_component_stimulus_scoped_events
265265 expected_prefix = "greeters--greeter-with-trigger-component"
266- assert_equal expected_prefix , Greeters ::GreeterWithTriggerComponent . js_event_name_prefix
266+ assert_equal "#{ expected_prefix } :click" , Greeters ::GreeterWithTriggerComponent . stimulus_scoped_event ( :click )
267+ assert_equal "#{ expected_prefix } :click@window" , Greeters ::GreeterWithTriggerComponent . stimulus_scoped_event_on_window ( :click )
267268 end
268269
269270 def test_root_element_attributes_structure
Original file line number Diff line number Diff line change @@ -221,9 +221,10 @@ def test_component_stimulus_identifier_path
221221 assert_equal expected_path , PhlexGreeters ::GreeterWithTriggerComponent . stimulus_identifier_path
222222 end
223223
224- def test_component_js_event_name_prefix
224+ def test_component_stimulus_scoped_events
225225 expected_prefix = "phlex-greeters--greeter-with-trigger-component"
226- assert_equal expected_prefix , PhlexGreeters ::GreeterWithTriggerComponent . js_event_name_prefix
226+ assert_equal "#{ expected_prefix } :click" , PhlexGreeters ::GreeterWithTriggerComponent . stimulus_scoped_event ( :click )
227+ assert_equal "#{ expected_prefix } :click@window" , PhlexGreeters ::GreeterWithTriggerComponent . stimulus_scoped_event_on_window ( :click )
227228 end
228229
229230 def test_root_element_attributes_structure
You can’t perform that action at this time.
0 commit comments