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.
- package/README.md +5 -1
- package/index.js +38 -27
- 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
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
-
|
|
112
|
+
listenTarget = controller.element
|
|
113
|
+
guard = (event) => {
|
|
114
114
|
const matched = event.target.closest(selector)
|
|
115
|
-
if (!matched || !controller.element.contains(matched)) return
|
|
116
|
-
|
|
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
|
-
|
|
139
|
-
super.
|
|
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
|
}
|