stimulus_helpers 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/CHANGELOG.md +31 -0
- data/CLAUDE.md +137 -0
- data/README.md +52 -26
- data/lib/stimulus_helpers/version.rb +1 -1
- data/lib/stimulus_helpers.rb +46 -9
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 14c71e9cd468dd53e36d2ff91e05d42a05f3adc2b77a206cb54a92d3ada5b2aa
|
4
|
+
data.tar.gz: 8c74bf98bef6ea4be290669a45a27f0dd4ffdc22fa35bd77fb010aa7b0cb1c86
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a8089db24fa96a1791ac596b2287d0a934091c6b153fcc5714ef93f04539b615bf7aa1c3f6b362577a8cc36f93e217ffd63d2d0c4df2ff03a141ab303f1d959
|
7
|
+
data.tar.gz: e54556d56355788621c6ed9144beaa00dd20bdaa42947b27627b9495c4e294dbb2f022e7590dcb28addab75f689effb8464d38599559607e95cde44b71010293
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.3.5
|
data/CHANGELOG.md
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [Unreleased]
|
9
|
+
|
10
|
+
## [0.2.0] - 2025-01-06
|
11
|
+
|
12
|
+
### Performance
|
13
|
+
- Optimize string operations and concatenations for large attribute sets
|
14
|
+
- Add caching for dasherized keys to avoid repeated string transformations
|
15
|
+
- Implement batch JSON serialization to reduce overhead
|
16
|
+
- Improve action building performance by replacing array operations with direct string building
|
17
|
+
|
18
|
+
## [0.1.0] - 2024-XX-XX
|
19
|
+
|
20
|
+
### Added
|
21
|
+
- Initial release of stimulus_helpers gem
|
22
|
+
- Helper methods for Stimulus controller attributes:
|
23
|
+
- `stimulus_controller(name)` - Controller binding
|
24
|
+
- `stimulus_action(controller, action, listener)` and `stimulus_actions(controller, actions)` - Action bindings
|
25
|
+
- `stimulus_class(controller, name, value)` and `stimulus_classes(controller, classes)` - CSS class bindings
|
26
|
+
- `stimulus_value(controller, name, value)` and `stimulus_values(controller, values)` - Value bindings
|
27
|
+
- `stimulus_target(controller, target)` - Target bindings
|
28
|
+
- `stimulus_param(controller, name, value)` and `stimulus_params(controller, params)` - Parameter bindings
|
29
|
+
- `stimulus_outlet(controller, name, value)` and `stimulus_outlets(controller, outlets)` - Outlet bindings
|
30
|
+
- Automatic JSON serialization for complex values (Arrays and Hashes)
|
31
|
+
- Automatic dasherization of attribute names following Stimulus conventions
|
data/CLAUDE.md
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
# Instructions for Claude Code
|
2
|
+
|
3
|
+
## Project Overview
|
4
|
+
|
5
|
+
This is the `stimulus_helpers` Ruby gem - a utility library that provides helper methods for building Stimulus controller attributes in Ruby views. The gem makes it easier to work with Stimulus.js by providing a clean Ruby API for generating the necessary HTML attributes.
|
6
|
+
|
7
|
+
## Key Information
|
8
|
+
|
9
|
+
- **Gem Name**: stimulus_helpers
|
10
|
+
- **Current Version**: 0.1.0
|
11
|
+
- **Ruby Version**: 3.1.2
|
12
|
+
- **License**: MIT
|
13
|
+
- **Author**: Tomáš Celizna
|
14
|
+
|
15
|
+
## Project Structure
|
16
|
+
|
17
|
+
```
|
18
|
+
stimulus_helpers/
|
19
|
+
├── lib/
|
20
|
+
│ ├── stimulus_helpers.rb # Main module with all helper methods
|
21
|
+
│ └── stimulus_helpers/
|
22
|
+
│ └── version.rb # Version constant
|
23
|
+
├── test/
|
24
|
+
│ ├── stimulus_helpers_test.rb # Test suite
|
25
|
+
│ └── test_helper.rb # Test configuration
|
26
|
+
├── stimulus_helpers.gemspec # Gem specification
|
27
|
+
├── Gemfile # Dependencies
|
28
|
+
├── Rakefile # Build tasks
|
29
|
+
└── README.md # Documentation
|
30
|
+
```
|
31
|
+
|
32
|
+
## Development Workflow
|
33
|
+
|
34
|
+
### Running Tests
|
35
|
+
```bash
|
36
|
+
bundle exec rake test
|
37
|
+
# or simply
|
38
|
+
bundle exec rake
|
39
|
+
```
|
40
|
+
|
41
|
+
### Running Linter
|
42
|
+
```bash
|
43
|
+
bundle exec rubocop
|
44
|
+
```
|
45
|
+
|
46
|
+
### Installing Dependencies
|
47
|
+
```bash
|
48
|
+
bundle install
|
49
|
+
```
|
50
|
+
|
51
|
+
### Building the Gem
|
52
|
+
```bash
|
53
|
+
bundle exec rake build
|
54
|
+
```
|
55
|
+
|
56
|
+
### Releasing a New Version
|
57
|
+
1. Update the version number in `lib/stimulus_helpers/version.rb`
|
58
|
+
2. Update CHANGELOG.md with the changes
|
59
|
+
3. Commit the changes
|
60
|
+
4. Run `bundle exec rake release`
|
61
|
+
|
62
|
+
## Code Style Guidelines
|
63
|
+
|
64
|
+
- Follow the RuboCop configuration in `.rubocop.yml`
|
65
|
+
- Use Ruby 3.1+ syntax features (like value omission in hash literals)
|
66
|
+
- Keep methods focused and well-documented
|
67
|
+
- Maintain test coverage for all public methods
|
68
|
+
|
69
|
+
## Helper Methods Overview
|
70
|
+
|
71
|
+
The gem provides the following helper methods:
|
72
|
+
|
73
|
+
1. **Controller**: `stimulus_controller(name)`
|
74
|
+
2. **Actions**: `stimulus_action(controller, action, listener)` and `stimulus_actions(controller, actions)`
|
75
|
+
3. **Classes**: `stimulus_class(controller, name, value)` and `stimulus_classes(controller, classes)`
|
76
|
+
4. **Values**: `stimulus_value(controller, name, value)` and `stimulus_values(controller, values)`
|
77
|
+
5. **Target**: `stimulus_target(controller, target)`
|
78
|
+
6. **Params**: `stimulus_param(controller, name, value)` and `stimulus_params(controller, params)`
|
79
|
+
7. **Outlets**: `stimulus_outlet(controller, name, value)` and `stimulus_outlets(controller, outlets)`
|
80
|
+
|
81
|
+
## Implementation Notes
|
82
|
+
|
83
|
+
- The main module uses `build_stimulus_action` and `build_stimulus_attribute` private methods to construct the attribute hashes
|
84
|
+
- Complex values (Arrays and Hashes) are automatically converted to JSON
|
85
|
+
- Attribute names are dasherized to follow Stimulus conventions
|
86
|
+
- The gem depends on ActiveSupport for string inflections
|
87
|
+
|
88
|
+
## Testing Approach
|
89
|
+
|
90
|
+
- Tests are in `test/stimulus_helpers_test.rb`
|
91
|
+
- Each helper method has corresponding test coverage
|
92
|
+
- Tests verify the exact structure of returned hashes
|
93
|
+
- Run tests with `bundle exec rake test`
|
94
|
+
|
95
|
+
## Common Tasks
|
96
|
+
|
97
|
+
### Adding a New Helper Method
|
98
|
+
|
99
|
+
1. Add the public method to `lib/stimulus_helpers.rb`
|
100
|
+
2. Use the existing private methods (`build_stimulus_action` or `build_stimulus_attribute`) if applicable
|
101
|
+
3. Add corresponding tests to `test/stimulus_helpers_test.rb`
|
102
|
+
4. Update the README.md with usage examples
|
103
|
+
5. Run tests and linter to ensure everything passes
|
104
|
+
|
105
|
+
### Debugging
|
106
|
+
|
107
|
+
- Use `bin/console` to start an IRB session with the gem loaded
|
108
|
+
- The test suite uses Minitest - add debugging with `puts` or use a debugger gem
|
109
|
+
- Check the GitHub Actions workflow results for CI failures
|
110
|
+
|
111
|
+
## Important Considerations
|
112
|
+
|
113
|
+
1. **Backwards Compatibility**: This gem is used by other projects, so maintain backwards compatibility when making changes
|
114
|
+
2. **Dependencies**: Keep dependencies minimal - currently only requires ActiveSupport
|
115
|
+
3. **Documentation**: Update README.md when adding new features
|
116
|
+
4. **Versioning**: Follow semantic versioning (MAJOR.MINOR.PATCH)
|
117
|
+
|
118
|
+
## Git Workflow
|
119
|
+
|
120
|
+
- The main branch is protected
|
121
|
+
- Create feature branches for new work
|
122
|
+
- Ensure all tests pass before merging
|
123
|
+
- The GitHub Actions workflow runs on every push
|
124
|
+
|
125
|
+
## Troubleshooting
|
126
|
+
|
127
|
+
- If tests fail locally but pass in CI, check Ruby version (should be 3.1.2)
|
128
|
+
- RuboCop violations can often be auto-fixed with `bundle exec rubocop -A`
|
129
|
+
- Bundle install issues: try `bundle update` or delete `Gemfile.lock` and reinstall
|
130
|
+
|
131
|
+
## Future Improvements
|
132
|
+
|
133
|
+
Based on the current codebase, potential areas for enhancement:
|
134
|
+
- Add more comprehensive documentation/examples
|
135
|
+
- Consider adding type signatures (RBS file is currently minimal)
|
136
|
+
- Add more edge case testing
|
137
|
+
- Consider performance optimizations for large attribute sets
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[](https://github.com/tomasc/stimulus_helpers/actions/workflows/ruby.yml)
|
4
4
|
|
5
|
-
Helpers to build stimulus controller attributes for use in views and
|
5
|
+
Helpers to build stimulus controller attributes for use in views and controller-names.
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
@@ -32,42 +32,68 @@ ActionView::Base.send :include, StimulusHelpers
|
|
32
32
|
|
33
33
|
This will add the following helpers:
|
34
34
|
|
35
|
+
Controller:
|
36
|
+
|
35
37
|
```ruby
|
36
|
-
stimulus_controller("
|
37
|
-
# => { "controller" => "
|
38
|
+
stimulus_controller("controller-name")
|
39
|
+
# => { "controller" => "controller-name" }
|
40
|
+
```
|
38
41
|
|
39
|
-
|
40
|
-
# => { "action" => "click->component#open" }
|
42
|
+
Action:
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
+
```ruby
|
45
|
+
stimulus_action("controller-name", "click", "open")
|
46
|
+
# => { "action" => "click->controller-name#open" }
|
47
|
+
|
48
|
+
stimulus_actions("controller-name", click: "open", blur: "close")
|
49
|
+
# => { "action" => "click->controller-name#open blur->controller-name#close" }
|
50
|
+
```
|
44
51
|
|
45
|
-
|
46
|
-
# => { "component-open-class" => "component--open" }
|
52
|
+
Class:
|
47
53
|
|
48
|
-
|
49
|
-
|
54
|
+
```ruby
|
55
|
+
stimulus_class("controller-name", "open", "controller-name--open")
|
56
|
+
# => { "controller-name-open-class" => "controller-name--open" }
|
50
57
|
|
51
|
-
|
52
|
-
# => { "
|
58
|
+
stimulus_classes("controller-name", open: "controller-name--open", closed: "controller-name--closed")
|
59
|
+
# => { "controller-name-open-class" => "controller-name--open", "controller-name-closed-class" => "controller-name--closed" }
|
60
|
+
```
|
53
61
|
|
54
|
-
|
55
|
-
# => { "component-user-value" => "{\"name\":\"Jens\"}", "component-names-value" => "[\"foo\",\"bar\"]" }
|
62
|
+
Value:
|
56
63
|
|
57
|
-
|
58
|
-
|
64
|
+
```ruby
|
65
|
+
stimulus_value("controller-name", "open", true)
|
66
|
+
# => { "controller-name-open-value" => "true" }
|
59
67
|
|
60
|
-
|
61
|
-
# => { "
|
68
|
+
stimulus_values("controller-name", user: { name: "Jens" }, names: ["foo", "bar"])
|
69
|
+
# => { "controller-name-user-value" => "{\"name\":\"Jens\"}", "controller-name-names-value" => "[\"foo\",\"bar\"]" }
|
70
|
+
```
|
62
71
|
|
63
|
-
|
64
|
-
# => { "component-id-param" => "123", "component-name-param" => "Jens" }
|
72
|
+
Target:
|
65
73
|
|
66
|
-
|
67
|
-
|
74
|
+
```ruby
|
75
|
+
stimulus_target("controller-name", :input)
|
76
|
+
# => { "controller-name-target" => "input" }
|
77
|
+
```
|
78
|
+
|
79
|
+
Param:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
stimulus_param("controller-name", "id", 123)
|
83
|
+
# => { "controller-name-id-param" => "123" }
|
84
|
+
|
85
|
+
stimulus_params("controller-name", id: 123, name: "Jens")
|
86
|
+
# => { "controller-name-id-param" => "123", "controller-name-name-param" => "Jens" }
|
87
|
+
```
|
88
|
+
|
89
|
+
Outlet:
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
stimulus_outlet("controller-name", "result", ".result")
|
93
|
+
# => { "controller-name-result-outlet" => ".result" }
|
68
94
|
|
69
|
-
stimulus_outlets("
|
70
|
-
# => { "
|
95
|
+
stimulus_outlets("controller-name", result: ".result", output: ".output")
|
96
|
+
# => { "controller-name-result-outlet" => ".result", "controller-name-output-outlet" => ".output" }
|
71
97
|
```
|
72
98
|
|
73
99
|
## Development
|
@@ -78,4 +104,4 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
78
104
|
|
79
105
|
## Contributing
|
80
106
|
|
81
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
107
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/tomasc/stimulus_helpers.
|
data/lib/stimulus_helpers.rb
CHANGED
@@ -5,6 +5,14 @@ require "active_support/core_ext/string/inflections"
|
|
5
5
|
require "json"
|
6
6
|
|
7
7
|
module StimulusHelpers
|
8
|
+
# Cache for dasherized keys to avoid repeated string operations
|
9
|
+
@dasherized_cache = {}
|
10
|
+
@cache_mutex = Mutex.new
|
11
|
+
|
12
|
+
class << self
|
13
|
+
attr_reader :dasherized_cache, :cache_mutex
|
14
|
+
end
|
15
|
+
|
8
16
|
# @see https://blog.saeloun.com/2021/09/28/ruby-allow-value-omission-in-hash-literals
|
9
17
|
def stimulus_controller(controller)
|
10
18
|
{ controller: }
|
@@ -91,19 +99,48 @@ module StimulusHelpers
|
|
91
99
|
|
92
100
|
private
|
93
101
|
def build_stimulus_action(controller:, actions: {})
|
94
|
-
|
95
|
-
|
96
|
-
|
102
|
+
# Use string concatenation instead of array operations for better performance
|
103
|
+
action_parts = []
|
104
|
+
actions.each do |action_name, listeners|
|
105
|
+
Array(listeners).each do |listener|
|
106
|
+
action_parts << "#{action_name}->#{controller}##{listener}"
|
97
107
|
end
|
98
|
-
end
|
99
|
-
{ action: }
|
108
|
+
end
|
109
|
+
{ action: action_parts.join(" ") }
|
100
110
|
end
|
101
111
|
|
102
112
|
def build_stimulus_attribute(controller:, type: nil, attributes: {})
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
113
|
+
# Pre-process keys and batch JSON serialization for better performance
|
114
|
+
result = {}
|
115
|
+
json_values = {}
|
116
|
+
|
117
|
+
attributes.each do |key, value|
|
118
|
+
# Build the final key once
|
119
|
+
final_key = if type
|
120
|
+
"#{controller}-#{cached_dasherize("#{key}-#{type}")}"
|
121
|
+
else
|
122
|
+
"#{controller}-#{cached_dasherize(key.to_s)}"
|
123
|
+
end
|
124
|
+
|
125
|
+
# Batch JSON serialization
|
126
|
+
if value.is_a?(Array) || value.is_a?(Hash)
|
127
|
+
json_values[final_key] = value
|
128
|
+
else
|
129
|
+
result[final_key] = value.to_s
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Serialize all JSON values at once to reduce overhead
|
134
|
+
json_values.each do |key, value|
|
135
|
+
result[key] = value.to_json
|
136
|
+
end
|
137
|
+
|
138
|
+
result
|
139
|
+
end
|
140
|
+
|
141
|
+
def cached_dasherize(string)
|
142
|
+
StimulusHelpers.cache_mutex.synchronize do
|
143
|
+
StimulusHelpers.dasherized_cache[string] ||= string.dasherize
|
107
144
|
end
|
108
145
|
end
|
109
146
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stimulus_helpers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomas Celizna
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2025-06-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -106,6 +106,7 @@ files:
|
|
106
106
|
- ".rubocop.yml"
|
107
107
|
- ".ruby-version"
|
108
108
|
- CHANGELOG.md
|
109
|
+
- CLAUDE.md
|
109
110
|
- Gemfile
|
110
111
|
- LICENSE
|
111
112
|
- README.md
|
@@ -136,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
137
|
- !ruby/object:Gem::Version
|
137
138
|
version: '0'
|
138
139
|
requirements: []
|
139
|
-
rubygems_version: 3.
|
140
|
+
rubygems_version: 3.5.16
|
140
141
|
signing_key:
|
141
142
|
specification_version: 4
|
142
143
|
summary: Helper methods for stimulus controllers.
|