Pass the ActionEvent (with params) to registerActionOption callbacks · hotwired/stimulus@e1f111d

3 files changed

lines changed

Original file line numberDiff line numberDiff line change

@@ -215,12 +215,12 @@ route the event to the controller action, return `true`.

215215
216216

The callback accepts a single object argument with the following keys:

217217
218-

Name | Description

219-

--------|------------

220-

name | String: The option's name (`"open"` in the example above)

221-

value | Boolean: The value of the option (`:open` would yield `true`, `:!open` would yield `false`)

222-

event | [Event][]: The event instance

223-

element | [Element]: The element where the action descriptor is declared

218+

| Name | Description |

219+

| ------- | ----------------------------------------------------------------------------------------------------- |

220+

| name | String: The option's name (`"open"` in the example above) |

221+

| value | Boolean: The value of the option (`:open` would yield `true`, `:!open` would yield `false`) |

222+

| event | [Event][]: The event instance, including with the `params` action parameters on the submitter element |

223+

| element | [Element]: The element where the action descriptor is declared |

224224
225225

[toggle]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLDetailsElement/toggle_event

226226

[Event]: https://developer.mozilla.org/en-US/docs/web/api/event

Original file line numberDiff line numberDiff line change

@@ -29,8 +29,9 @@ export class Binding {

2929

}

3030
3131

handleEvent(event: Event) {

32-

if (this.willBeInvokedByEvent(event) && this.applyEventModifiers(event)) {

33-

this.invokeWithEvent(event)

32+

const actionEvent = this.prepareActionEvent(event)

33+

if (this.willBeInvokedByEvent(event) && this.applyEventModifiers(actionEvent)) {

34+

this.invokeWithEvent(actionEvent)

3435

}

3536

}

3637

@@ -65,12 +66,14 @@ export class Binding {

6566

return passes

6667

}

6768
68-

private invokeWithEvent(event: Event) {

69+

private prepareActionEvent(event: Event): ActionEvent {

70+

return Object.assign(event, { params: this.action.params })

71+

}

72+
73+

private invokeWithEvent(event: ActionEvent) {

6974

const { target, currentTarget } = event

7075

try {

71-

const { params } = this.action

72-

const actionEvent: ActionEvent = Object.assign(event, { params })

73-

this.method.call(this.controller, actionEvent)

76+

this.method.call(this.controller, event)

7477

this.context.logDebugActivity(this.methodName, { event, target, currentTarget, action: this.methodName })

7578

} catch (error: any) {

7679

const { identifier, controller, element, index } = this

Original file line numberDiff line numberDiff line change

@@ -213,6 +213,43 @@ export default class EventOptionsTests extends LogControllerTestCase {

213213

this.assertActions({ name: "log", eventType: "toggle" })

214214

}

215215
216+

async "test custom action option callback event contains params"() {

217+

let lastActionEventParams: Object = {}

218+
219+

// clone the params to ensure we check the value as the callback receives it

220+

// not the event after all actions have resolved

221+
222+

const mockCallback = ({ event: { params = {} } = {} }) => {

223+

lastActionEventParams = { ...params }

224+

}

225+
226+

this.application.registerActionOption("all", (options: Object) => {

227+

mockCallback(options)

228+

return true

229+

})

230+
231+

this.buttonElement.setAttribute("data-c-custom-number-param", "41")

232+

this.buttonElement.setAttribute("data-c-custom-string-param", "validation")

233+

this.buttonElement.setAttribute("data-c-custom-boolean-param", "true")

234+

this.buttonElement.setAttribute("data-d-should-ignore-param", "_IGNORED_")

235+
236+

await this.setAction(this.buttonElement, "click->c#log:all")

237+
238+

await this.triggerEvent(this.buttonElement, "click")

239+
240+

this.assertActions({ name: "log", identifier: "c", eventType: "click", currentTarget: this.buttonElement })

241+
242+

const expectedEventParams = {

243+

customBoolean: true,

244+

customNumber: 41,

245+

customString: "validation",

246+

}

247+
248+

this.assert.deepEqual(this.controllerConstructor.actionLog[0].params, expectedEventParams)

249+
250+

this.assert.deepEqual(lastActionEventParams, expectedEventParams)

251+

}

252+
216253

setAction(element: Element, value: string) {

217254

element.setAttribute("data-action", value)

218255

return this.nextFrame