stimulus-use-actions 0.3.2 → 0.3.4

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.
Files changed (3) hide show
  1. package/README.md +5 -1
  2. package/index.js +38 -27
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -20,11 +20,13 @@ export default class extends Controller {
20
20
  static actions = {
21
21
  field: "input->update",
22
22
  checkbox: "change->rerender",
23
+ element: "submit->save",
23
24
  window: "resize->layout",
24
25
  }
25
26
 
26
27
  update(event) { /* ... */ }
27
28
  rerender(event) { /* ... */ }
29
+ save(event) { /* ... */ }
28
30
  layout(event) { /* ... */ }
29
31
  }
30
32
  ```
@@ -45,6 +47,7 @@ Each key in `static actions` is a **target name** matching an entry in
45
47
  | Key | Listens on | Matches events from |
46
48
  | --------- | ------------------- | -------------------------------------------- |
47
49
  | `field` | controller element | descendants with `data-<id>-target="field"` |
50
+ | `element` | controller element | the controller element itself |
48
51
  | `window` | `window` | the window itself |
49
52
 
50
53
  ### Values
@@ -74,6 +77,7 @@ export default class extends Controller {
74
77
  connect() {
75
78
  useActions(this, {
76
79
  buttonTargets: ["click->submit", "keyup->preview"],
80
+ element: "submit->save",
77
81
  window: "resize->reflow",
78
82
  })
79
83
  }
@@ -92,7 +96,7 @@ observer.
92
96
 
93
97
  - **controller** -- your Stimulus controller instance (`this`)
94
98
  - **actions** -- map of target keys to action descriptors
95
- - Keys: `<name>Target`, `<name>Targets`, or `window`
99
+ - Keys: `<name>Target`, `<name>Targets`, `element`, or `window`
96
100
  - Values: a string or array of `"event->method"` strings
97
101
  - Event inference (e.g. `"submit"` without `click->`) is supported here --
98
102
  Stimulus infers the default event for the element
package/index.js CHANGED
@@ -87,8 +87,9 @@ function bindDelegatedActions(controller) {
87
87
  Object.entries(actions).forEach(([key, descriptors]) => {
88
88
  const descriptorList = Array.isArray(descriptors) ? descriptors : [descriptors]
89
89
  const isWindow = key === "window"
90
+ const isElement = key === "element"
90
91
  let targetName
91
- if (!isWindow) {
92
+ if (!isWindow && !isElement) {
92
93
  if (key.endsWith("Targets")) targetName = key.slice(0, -7)
93
94
  else if (key.endsWith("Target")) targetName = key.slice(0, -6)
94
95
  else targetName = key
@@ -99,29 +100,33 @@ function bindDelegatedActions(controller) {
99
100
  if (!parsed) return
100
101
  const { eventName, filter, methodName, options } = parsed
101
102
 
103
+ let listenTarget, guard
102
104
  if (isWindow) {
103
- const handler = (event) => {
104
- if (filter && event.key !== (KEY_MAP[filter] || filter)) return
105
- if (options.includes("stop")) event.stopPropagation()
106
- if (options.includes("prevent")) event.preventDefault()
107
- controller[methodName](event)
108
- }
109
- window.addEventListener(eventName, handler)
110
- listeners.push({ target: window, eventName, handler })
105
+ listenTarget = window
106
+ guard = () => true
107
+ } else if (isElement) {
108
+ listenTarget = controller.element
109
+ guard = (event) => !options.includes("self") || event.target === controller.element
111
110
  } else {
112
111
  const selector = `[data-${identifier}-target~="${targetName}"]`
113
- const handler = (event) => {
112
+ listenTarget = controller.element
113
+ guard = (event) => {
114
114
  const matched = event.target.closest(selector)
115
- if (!matched || !controller.element.contains(matched)) return
116
- if (filter && event.key !== (KEY_MAP[filter] || filter)) return
117
- if (options.includes("self") && event.target !== matched) return
118
- if (options.includes("stop")) event.stopPropagation()
119
- if (options.includes("prevent")) event.preventDefault()
120
- controller[methodName](event)
115
+ if (!matched || !controller.element.contains(matched)) return false
116
+ return !options.includes("self") || event.target === matched
121
117
  }
122
- controller.element.addEventListener(eventName, handler)
123
- listeners.push({ target: controller.element, eventName, handler })
124
118
  }
119
+
120
+ const handler = (event) => {
121
+ if (!guard(event)) return
122
+ if (filter && event.key !== (KEY_MAP[filter] || filter)) return
123
+ if (options.includes("stop")) event.stopPropagation()
124
+ if (options.includes("prevent")) event.preventDefault()
125
+ controller[methodName](event)
126
+ }
127
+ const capture = !isWindow && !isElement
128
+ listenTarget.addEventListener(eventName, handler, capture)
129
+ listeners.push({ target: listenTarget, eventName, handler, capture })
125
130
  })
126
131
  })
127
132
 
@@ -129,19 +134,25 @@ function bindDelegatedActions(controller) {
129
134
  }
130
135
 
131
136
  function unbindDelegatedActions(listeners) {
132
- listeners.forEach(({ target, eventName, handler }) => {
133
- target.removeEventListener(eventName, handler)
137
+ listeners.forEach(({ target, eventName, handler, capture }) => {
138
+ target.removeEventListener(eventName, handler, capture)
134
139
  })
135
140
  }
136
141
 
137
142
  export class Controller extends StimulusController {
138
- connect() {
139
- super.connect()
140
- this._useActionListeners = bindDelegatedActions(this)
141
- }
142
- disconnect() {
143
- super.disconnect()
144
- unbindDelegatedActions(this._useActionListeners)
143
+ initialize() {
144
+ super.initialize()
145
145
  this._useActionListeners = []
146
+ const userConnect = this.connect
147
+ const userDisconnect = this.disconnect
148
+ this.connect = () => {
149
+ userConnect.call(this)
150
+ this._useActionListeners = bindDelegatedActions(this)
151
+ }
152
+ this.disconnect = () => {
153
+ unbindDelegatedActions(this._useActionListeners)
154
+ this._useActionListeners = []
155
+ userDisconnect.call(this)
156
+ }
146
157
  }
147
158
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stimulus-use-actions",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "Stimulus mixin for declaring actions in the controller",
5
5
  "type": "module",
6
6
  "main": "index.js",