stimulizer 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c4c0fe32e16955ce1cd02692f9c128243e3c7dcab8e55a0eca02e2a158d11e4d
4
- data.tar.gz: 85e92867bb922c53924d2205f8db804f5aee7b41dd67d656ee49ea0a4eb7bf50
3
+ metadata.gz: b7ff225da6cb516af29d0cd30787586c6c13a9ac6db4bb26eaa2e8dc11f832d0
4
+ data.tar.gz: 88c7d3e6259d1052c19e254f15402ff859ccd8e480d21254b13f29f141d80ff6
5
5
  SHA512:
6
- metadata.gz: 0ad40b936ef85923d186925342c25631066657dec4a1ebc8c7cb5adbf704d403fcb82ced1e922e4369a4cb7e036769fd96728ab4480d6e48cf1c4916bf762ae4
7
- data.tar.gz: 90c2bc2f3cdd12cb919ba4f5d2d301a9cf49d11c4441a18d59c6825cb0e35a15fce7c9027a54a18634c2137cc8640a392924394ce8e970c96680b0076b0a34a1
6
+ metadata.gz: f4b33e806d801cebce6220f0c6d63ed14facc335fd6e8eeb38c893b38fffba85e8fa6cde19b30d9a42d0bea36dcf7e833b895c2648a54c9a8d9da231cfb26da3
7
+ data.tar.gz: d7049053a80543023684f9581c37ac4d32b11a6ab835079af617a9a6a7a12850cabcad8b316d3b4ecd8c4053bb693d2490f7be98de6ad4ffda4e323db60d0a4a
data/README.md CHANGED
@@ -1,8 +1,36 @@
1
1
  # Stimulizer
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/stimulizer`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Easily work with StimulusJS `data-*` attributes in ViewComponents, Phlex templates, etc.
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ This gem is particularly handy in ViewComponents and Phlex when you have a 1-1 relationship between a component and a Stimulus controller, especially when using 'sidecar' controllers.
6
+
7
+ For example:
8
+
9
+ ### ViewComponent
10
+ ```ruby
11
+ class Mynamespace::Deeper::ButtonsGridComponent < ApplicationComponent
12
+ # ...
13
+ ```
14
+ #### Before
15
+ ```html
16
+ <div
17
+ data-controller="mynamespace--deeper--buttons-grid-component"
18
+ data-mynamespace--deeper--buttons-grid-component-url-value="http://example.com"
19
+ data-mynamespace--deeper--buttons-grid-component-url-color="#ff0000"
20
+ data-action="click->data-mynamespace--deeper--buttons-grid-component#doSomething"
21
+ >
22
+ ```
23
+
24
+ #### After
25
+ ```html
26
+ <div
27
+ <%= stimulus(
28
+ :controller,
29
+ values: {url: "http://example.com", color: "#ff0000"},
30
+ action: "click->doSomething"
31
+ )%>
32
+ >
33
+ ```
6
34
 
7
35
  ## Installation
8
36
 
@@ -21,8 +49,121 @@ Or install it yourself as:
21
49
  $ gem install stimulizer
22
50
 
23
51
  ## Usage
52
+ Include this in your class:
53
+
54
+ ```ruby
55
+ class MyComponent < ApplicationComponent
56
+ include Stimulizer
57
+ # ...
58
+ ```
59
+
60
+ Render the stimulusjs data strings into your template...
61
+
62
+ ```html
63
+ <!-- use the derived controller name -->
64
+ <%= stimulus(:controller) %>
65
+
66
+ <!-- specify the controller explicity, and/or add more controllers space-separated -->
67
+ <%= stimulus(controller: "another foo")
68
+
69
+ <!-- Note: 'action' is singular because it works like 'data-action' -->
70
+ <%= stimulus(action: "click->doThing")
71
+
72
+ <!-- but you can have multiple actions separated by spaces -->
73
+ <%= stimulus(action: "click->doThing mouseup->otherThing")
74
+
75
+ <!-- you can also skip the event, just like usual -->
76
+ <%= stimulus(action: "doThing")
77
+
78
+ <!--
79
+ target for this element (if you need to also target it for other controllers, you'll have to do that manually with the old 'data-blah-target=' approach)
80
+ -->
81
+ <%= stimulus(target: "button")
82
+
83
+ <!-- supports the 'classes' feature -->
84
+ <%= stimulus(classes: {foo: "text-red-500", busy: "opacity-50 animate-spin"})
85
+
86
+ <!-- supports the 'values' feature -->
87
+ <%= stimulus(values: {url: "https://example.com"})
88
+
89
+ <!-- supports the 'params' feature -->
90
+ <%= stimulus(params: {foo: "bar", this_thing: "whatever"})
91
+ ```
92
+ ... or combine them:
93
+ ```
94
+ <%= stimulus(:controller, target: "button", action: "click->doThing")
95
+ ```
96
+
97
+ ## Options
98
+
99
+ ### `stimulize`
100
+ Use the `stimulize` method after including the module to set some config options...
101
+
102
+ #### `ignore_prefix`
103
+ Use the `ignore_prefix` option to chop off some of the namespacing if you want to shorten up those crazy-long controller filenames.
104
+ ```ruby
105
+ stimulize ignore_prefix: "Components::"
106
+ ```
107
+
108
+ #### `output`
109
+ Use the `output` option to change from an html-style string of data attributes (default) to a Hash of data attributes, useful in other circumstances, like tag builders and Phlex views.
110
+ ```ruby
111
+ stimulize output: :hash
112
+ ```
113
+
114
+ ## Overriding the derived controller name
115
+ My main use case for Stimulizer is with so-called 'sidecar' javascript. That is, if I have a component in the filepath `components/foo/bar/other/button_component.rb`, I will also have a stimulus controller at `components/foo/bar/other/button_component_controller.js`.
116
+
117
+ **In this case, Stimulizer will auto-derive the controller name properly.**
118
+
119
+ If you're not doing things this way, you may need to manually set your controller name in each component/template...
24
120
 
25
- TODO: Write usage instructions here
121
+ ```ruby
122
+ def stimulus_controller
123
+ "whatever--name--you-want-here"
124
+ end
125
+ ```
126
+
127
+ **or...**
128
+
129
+ You can also pass the controller name directly to the `stimulus()` method. This starts to become less automagical, but still handy in reducing the repetition of those controller names.
130
+
131
+ ```ruby
132
+ <div
133
+ <%= stimulus(
134
+ controller_name: "my--fancy--buttons",
135
+ action: "click->show",
136
+ values: {url: "example.com"}
137
+ ) %>
138
+ >
139
+
140
+ # => <div data-controller='my--fancy--buttons' data-action='click->my--fancy--buttons#show' data-my--fancy--buttons-url-value="example.com">
141
+ ```
142
+
143
+ ## Using with Phlex (or if you want a hash for some other reason)
144
+ By default, Stimulizer returns a html-style string of `data-*` attributes from the `stimulus()` method. But if you're using something like Phlex templates, or if you want to use this with a tag-building method, you might want the original Hash instead. You have two options:
145
+
146
+ ### 1. Class-level configuration
147
+ ```ruby
148
+ module Views
149
+ class ApplicationView < Phlex::View
150
+ include Stimulizer
151
+ stimulize output: :hash
152
+ ```
153
+
154
+ ### 2. Specifically ask for a hash with `stimulus_hash` instead
155
+ ```ruby
156
+ stimulus_hash(:controller, action: "click->doThis")
157
+ ```
158
+
159
+ ## Phlex: Destructuring for the win!
160
+ Thanks to [@joeldrapper](https://github.com/joeldrapper) for suggesting this and for inspiring the idea of this gem. You can use destructuring to great effect in Phlex views:
161
+
162
+ ```ruby
163
+ div(**stimulus(:controller, action: "click->show"), class: "text-red-500") do
164
+ # ...
165
+ ```
166
+ *Note that this example is assuming you've turned on `:hash` mode as above. You could also use `**stimulus_hash()` in the same way.*
26
167
 
27
168
  ## Development
28
169
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Stimulizer
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.2"
5
5
  end
data/lib/stimulizer.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "stimulizer"
4
+
3
5
  require "active_support/concern"
4
6
  require "dry-configurable"
5
7
  require "lucky_case"
@@ -31,8 +33,20 @@ module Stimulizer
31
33
  build_stimulus_controller
32
34
  end
33
35
 
36
+ def stimulus_hash(*args)
37
+ if args.size == 1 && !args.first.is_a?(Hash)
38
+ build_stimulus_hash(args.first)
39
+ elsif args.size == 1 && args.first.is_a?(Hash)
40
+ build_stimulus_hash(**args.first)
41
+ elsif args.size == 2 && args[1..].all? { |a| a.is_a?(Hash) }
42
+ build_stimulus_hash(args[0], **args[1..].first)
43
+ else
44
+ raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 1..2)"
45
+ end
46
+ end
47
+
34
48
  def stimulus(*args)
35
- output = build_stimulus_hash(*args)
49
+ output = stimulus_hash(*args)
36
50
  return output if _stimulizer_opts[:output] == :hash
37
51
 
38
52
  raw(
@@ -71,7 +85,8 @@ module Stimulizer
71
85
  # ... or combine them:
72
86
  #
73
87
  # <%= stimulus(:controller, target: "button", action: "click->doThing")
74
- def build_stimulus_hash(default_controller = false, controller: nil, target: nil, action: nil, params: nil, values: nil, classes: nil)
88
+ def build_stimulus_hash(default_controller = false, controller_name: nil, controller: nil, target: nil, action: nil, params: nil, values: nil, classes: nil)
89
+ raise ArgumentError(":controller_name specified, but blank") if controller_name&.blank?
75
90
  raise ArgumentError(":controller specified, but blank") if controller&.blank?
76
91
  raise ArgumentError(":target specified, but blank") if target&.blank?
77
92
  raise ArgumentError(":action specified, but blank") if action&.blank?
@@ -82,8 +97,13 @@ module Stimulizer
82
97
  {}.tap do |hash|
83
98
  hash[:"data-controller"] = ""
84
99
 
100
+ local_controller_name = stimulus_controller
101
+
85
102
  if default_controller.to_s.downcase.to_sym == :controller
86
103
  hash[:"data-controller"] += " #{stimulus_controller}"
104
+ elsif controller_name.present?
105
+ hash[:"data-controller"] += " #{controller_name}"
106
+ local_controller_name = controller_name
87
107
  end
88
108
 
89
109
  hash[:"data-controller"] += " #{controller}" if controller
@@ -100,7 +120,7 @@ module Stimulizer
100
120
  if function.include?("#")
101
121
  "#{event}#{function}"
102
122
  else
103
- "#{event}#{stimulus_controller}##{function}"
123
+ "#{event}#{local_controller_name}##{function}"
104
124
  end
105
125
  end.compact
106
126
 
@@ -108,18 +128,18 @@ module Stimulizer
108
128
  end
109
129
 
110
130
  params&.each do |key, value|
111
- hash[:"data-#{stimulus_controller}-#{LuckyCase.dash_case(key.to_s)}-param"] = value
131
+ hash[:"data-#{local_controller_name}-#{LuckyCase.dash_case(key.to_s)}-param"] = value
112
132
  end
113
133
 
114
134
  values&.each do |key, value|
115
- hash[:"data-#{stimulus_controller}-#{LuckyCase.dash_case(key.to_s)}-value"] = value
135
+ hash[:"data-#{local_controller_name}-#{LuckyCase.dash_case(key.to_s)}-value"] = value
116
136
  end
117
137
 
118
138
  classes&.each do |key, value|
119
- hash[:"data-#{stimulus_controller}-#{LuckyCase.dash_case(key.to_s)}-class"] = value
139
+ hash[:"data-#{local_controller_name}-#{LuckyCase.dash_case(key.to_s)}-class"] = value
120
140
  end
121
141
 
122
- hash[:"data-#{stimulus_controller}-target"] = target if target
142
+ hash[:"data-#{local_controller_name}-target"] = target if target
123
143
  end
124
144
  end
125
145
  end
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stimulizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt E Patterson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
11
  date: 2022-11-04 00:00:00.000000000 Z
@@ -52,7 +52,7 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- description:
55
+ description:
56
56
  email:
57
57
  - mattp@digimonkey.com
58
58
  executables: []
@@ -81,7 +81,7 @@ metadata:
81
81
  homepage_uri: https://github.com/mepatterson/stimulizer
82
82
  source_code_uri: https://github.com/mepatterson/stimulizer
83
83
  changelog_uri: https://github.com/mepatterson/stimulizer/blob/main/CHANGELOG.md
84
- post_install_message:
84
+ post_install_message:
85
85
  rdoc_options: []
86
86
  require_paths:
87
87
  - lib
@@ -96,8 +96,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
96
  - !ruby/object:Gem::Version
97
97
  version: '0'
98
98
  requirements: []
99
- rubygems_version: 3.1.6
100
- signing_key:
99
+ rubygems_version: 3.3.7
100
+ signing_key:
101
101
  specification_version: 4
102
102
  summary: Stimulizer provides convenience methods for working with StimulusJS in views,
103
103
  templates, and components.