Skip to content

Commit cfe32da

Browse files
committed
Remove js_event_name_prefix and add stimulus_scoped_event/stimulus_scoped_event_on_window
1 parent 632e024 commit cfe32da

File tree

6 files changed

+83
-9
lines changed

6 files changed

+83
-9
lines changed

README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,37 @@ stimulus do
381381
end
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

386417
For more control, configure Stimulus attributes manually:

lib/vident/stimulus_attributes.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,25 @@
22

33
module 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

lib/vident/stimulus_component.rb

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff 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

llm.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,24 @@ stimulus do
103103
end
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
108126
def root_element_attributes

test/components/greeters/greeter_with_trigger_component_test.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff 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

test/components/phlex_greeters/greeter_with_trigger_component_test.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff 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

0 commit comments

Comments
 (0)