Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document the trix-action-invoke event #1189

Merged
Merged
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
71 changes: 71 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,75 @@ Place an empty `<trix-editor></trix-editor>` tag on the page. Trix will automati

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

## Creating a Toolbar

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:

```html
<main>
<trix-toolbar id="my_toolbar"></trix-toolbar>
<div class="more-stuff-inbetween"></div>
<trix-editor toolbar="my_toolbar" input="my_input"></trix-editor>
</main>
```

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.

**Toggle Attribute**

With `data-trix-attribute="<attribute name>"`, you can add an attribute to the current selection.
For example, to apply bold styling to the selected text the button is:

``` html
<button type="button" class="bold" data-trix-attribute="bold" data-trix-key="b"></button>
```

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`).

`data-trix-key="b"` tells Trix that this attribute should be applied when you use <kbd>meta</kbd>+<kbd>b</kdb>

If the attribute is defined in `Trix.config.blockAttributes`, Trix will apply the attribute to the current block of text.

``` html
<button type="button" class="quote" data-trix-attribute="quote"></button>
```

Clicking the quote button toggles whether the block should be rendered with `<blockquote>`.

## Invoking Internal Trix Actions

Internal actions are defined in `controllers/editor_controller.js` and consist of:

* undo
* redo
* link
* increaseBlockLevel
* decreaseBlockLevel

``` html
<button type="button" class="block-level decrease" data-trix-action="decreaseBlockLevel"></button>
```

## Invoking External Custom Actions

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"`

``` html
<button id="log-button" type="button" data-trix-action="x-log"></button>
```

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.

```javascript
document.addEventListener("trix-action-invoke", function(event) {
const { target, invokingElement, actionName } = event

if (actionName === "x-log") {
console.log(`Custom ${actionName} invoked from ${invokingElement.id} button on ${target.id} trix-editor`)
}
})
```

## Integrating With Forms

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.
Expand Down Expand Up @@ -371,6 +440,8 @@ The `<trix-editor>` element emits several events which you can use to observe an

* `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.

* `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).

# Contributing to Trix

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).
Expand Down
24 changes: 24 additions & 0 deletions src/test/system/custom_element_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,30 @@ testGroup("Custom element API", { template: "editor_empty" }, () => {
assert.equal(eventCount, 5)
})

test("invoking internal actions does not dispatch a trix-action-invoke event", async () => {
let event = null

addEventListener("trix-action-invoke", (ev) => event = ev, { once: true })
await clickToolbarButton({ action: "link" })

assert.equal(null, event)
})

test("invoking external actions dispatches a trix-action-invoke event", async () => {
let event = null
const editor = getEditorElement()
editor.toolbarElement.insertAdjacentHTML("beforeend", `
<button id="test-action" type="button" data-trix-action="x-test"></button>
`)

addEventListener("trix-action-invoke", (ev) => event = ev, { once: true })
await clickToolbarButton({ action: "x-test" })

assert.equal(editor, event.target)
assert.equal("x-test", event.actionName)
assert.equal(document.getElementById("test-action"), event.invokingElement)
})

test("element triggers trix-change event after toggling attributes", async () => {
const element = getEditorElement()
const { editor } = element
Expand Down
Loading