Skip to content

Commit a15d0b8

Browse files
Merge pull request basecamp#1189 from seanpdoyle/document-trix-action-invoke-event
Document the `trix-action-invoke` event
2 parents 457a834 + 3363db1 commit a15d0b8

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed

README.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,75 @@ Place an empty `<trix-editor></trix-editor>` tag on the page. Trix will automati
5353

5454
Like an HTML `<textarea>`, `<trix-editor>` accepts `autofocus` and `placeholder` attributes. Unlike a `<textarea>`, `<trix-editor>` automatically expands vertically to fit its contents.
5555

56+
## Creating a Toolbar
57+
58+
Trix automatically will create a toolbar for you and attach it right before the `<trix-editor>` element. If you'd like to place the toolbar in a different place you can use the `toolbar` attribute:
59+
60+
```html
61+
<main>
62+
<trix-toolbar id="my_toolbar"></trix-toolbar>
63+
<div class="more-stuff-inbetween"></div>
64+
<trix-editor toolbar="my_toolbar" input="my_input"></trix-editor>
65+
</main>
66+
```
67+
68+
To change the toolbar without modifying Trix, you can overwrite the `Trix.config.toolbar.getDefaultHTML()` function. The default toolbar HTML is in `config/toolbar.js`. Trix uses data attributes to determine how to respond to a toolbar button click.
69+
70+
**Toggle Attribute**
71+
72+
With `data-trix-attribute="<attribute name>"`, you can add an attribute to the current selection.
73+
For example, to apply bold styling to the selected text the button is:
74+
75+
``` html
76+
<button type="button" class="bold" data-trix-attribute="bold" data-trix-key="b"></button>
77+
```
78+
79+
Trix will determine that a range of text is selected and will apply the formatting defined in `Trix.config.textAttributes` (found in `config/text_attributes.js`).
80+
81+
`data-trix-key="b"` tells Trix that this attribute should be applied when you use <kbd>meta</kbd>+<kbd>b</kdb>
82+
83+
If the attribute is defined in `Trix.config.blockAttributes`, Trix will apply the attribute to the current block of text.
84+
85+
``` html
86+
<button type="button" class="quote" data-trix-attribute="quote"></button>
87+
```
88+
89+
Clicking the quote button toggles whether the block should be rendered with `<blockquote>`.
90+
91+
## Invoking Internal Trix Actions
92+
93+
Internal actions are defined in `controllers/editor_controller.js` and consist of:
94+
95+
* undo
96+
* redo
97+
* link
98+
* increaseBlockLevel
99+
* decreaseBlockLevel
100+
101+
``` html
102+
<button type="button" class="block-level decrease" data-trix-action="decreaseBlockLevel"></button>
103+
```
104+
105+
## Invoking External Custom Actions
106+
107+
If you want to add a button to the toolbar and have it invoke an external action, you can prefix your action name with `x-`. For example, if I want to print a log statement any time my new button is clicked, I would set by button's data attribute to be `data-trix-action="x-log"`
108+
109+
``` html
110+
<button id="log-button" type="button" data-trix-action="x-log"></button>
111+
```
112+
113+
To respond to the action, listen for `trix-action-invoke`. The event's `target` property returns a reference to the `<trix-editor>` element, its `invokingElement` property returns a reference to the `<button>` element, and its `actionName` property returns the value of the `[data-trix-action]` attribute. Use the value of the `actionName` property to detect which external action was invoked.
114+
115+
```javascript
116+
document.addEventListener("trix-action-invoke", function(event) {
117+
const { target, invokingElement, actionName } = event
118+
119+
if (actionName === "x-log") {
120+
console.log(`Custom ${actionName} invoked from ${invokingElement.id} button on ${target.id} trix-editor`)
121+
}
122+
})
123+
```
124+
56125
## Integrating With Forms
57126

58127
To submit the contents of a `<trix-editor>` with a form, first define a hidden input field in the form and assign it an `id`. Then reference that `id` in the editor’s `input` attribute.
@@ -371,6 +440,8 @@ The `<trix-editor>` element emits several events which you can use to observe an
371440

372441
* `trix-attachment-remove` fires when an attachment is removed from the document. You can access the Trix attachment object through the `attachment` property on the event. You may wish to use this event to clean up remotely stored files.
373442

443+
* `trix-action-invoke` fires when a Trix action is invoked. You can access the `<trix-editor>` element through the event's `target` property, the element responsible for invoking the action through the `invokingElement` property, and the action's name through the `actionName` property. The `trix-action-invoke` event will only fire for [custom](#invoking-external-custom-actions) actions and not for [built-in](#invoking-internal-trix-actions).
444+
374445
# Contributing to Trix
375446

376447
Trix is open-source software, freely distributable under the terms of an [MIT-style license](LICENSE). The [source code is hosted on GitHub](https://github.com/basecamp/trix).

src/test/system/custom_element_test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,30 @@ testGroup("Custom element API", { template: "editor_empty" }, () => {
133133
assert.equal(eventCount, 5)
134134
})
135135

136+
test("invoking internal actions does not dispatch a trix-action-invoke event", async () => {
137+
let event = null
138+
139+
addEventListener("trix-action-invoke", (ev) => event = ev, { once: true })
140+
await clickToolbarButton({ action: "link" })
141+
142+
assert.equal(null, event)
143+
})
144+
145+
test("invoking external actions dispatches a trix-action-invoke event", async () => {
146+
let event = null
147+
const editor = getEditorElement()
148+
editor.toolbarElement.insertAdjacentHTML("beforeend", `
149+
<button id="test-action" type="button" data-trix-action="x-test"></button>
150+
`)
151+
152+
addEventListener("trix-action-invoke", (ev) => event = ev, { once: true })
153+
await clickToolbarButton({ action: "x-test" })
154+
155+
assert.equal(editor, event.target)
156+
assert.equal("x-test", event.actionName)
157+
assert.equal(document.getElementById("test-action"), event.invokingElement)
158+
})
159+
136160
test("element triggers trix-change event after toggling attributes", async () => {
137161
const element = getEditorElement()
138162
const { editor } = element

0 commit comments

Comments
 (0)