Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/reference/actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ Custom action option | Description
`:stop` | calls `.stopPropagation()` on the event before invoking the method
`:prevent` | calls `.preventDefault()` on the event before invoking the method
`:self` | only invokes the method if the event was fired by the element itself
`:!input` | suppress an event if it was fired while an input element has focus

You can register your own action options with the `Application.registerActionOption` method.

Expand Down
13 changes: 13 additions & 0 deletions src/core/action_descriptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,19 @@ export const defaultActionDescriptorFilters: ActionDescriptorFilters = {
return true
}
},

input({ event, value }) {
if (value) return true

const target = event.target
if (!(target instanceof Element)) return true

const isInput =
target.tagName === "INPUT" ||
target.tagName === "TEXTAREA" ||
(target instanceof HTMLElement && target.isContentEditable)
return !isInput
},
}

export interface ActionDescriptor {
Expand Down
21 changes: 21 additions & 0 deletions src/tests/modules/core/event_options_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default class EventOptionsTests extends LogControllerTestCase {
<div data-controller="c d">
<button></button>
<details></details>
<input>
</div>
<div id="outside"></div>
`
Expand Down Expand Up @@ -178,6 +179,22 @@ export default class EventOptionsTests extends LogControllerTestCase {
this.assertNoActions()
}

async "test true input option"() {
await this.setAction(this.inputElement, "keydown@window->c#log:input")

await this.triggerEvent(this.inputElement, "keydown")

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

async "test false input option"() {
await this.setAction(this.inputElement, "keydown@window->c#log:!input")

await this.triggerEvent(this.inputElement, "keydown")

this.assertNoActions()
}

async "test custom action option callback params contain the controller instance"() {
let lastActionOptions: { controller?: Controller<Element> } = {}

Expand Down Expand Up @@ -313,4 +330,8 @@ export default class EventOptionsTests extends LogControllerTestCase {
get detailsElement() {
return this.findElement("details")
}

get inputElement() {
return this.findElement("input")
}
}