Navigation Feedback owns temporary presentation. The feature that performs a jump owns selection, focus, and scrolling. For complete footnote navigation, use the Footnote API.
NavigationFeedbackPlugin is included in the React editor defaults. Configure
the default duration through navigationFeedback:
import { createEditor } from 'platejs/react';
const editor = createEditor({
navigationFeedback: { duration: 1200 },
});import { createEditor } from 'platejs/react';
const editor = createEditor({
navigationFeedback: { duration: 1200 },
});The default duration is 1600 milliseconds. Set navigationFeedback: false
to disable the plugin.
Call the API from the mounted editor returned by useEditor().
Resolve an element's NodeKey in that view and pass the
presentation for this action:
import { useEditor } from 'platejs/react';
export function FlashFirstBlock() {
const editor = useEditor();
return (
<button
type="button"
onClick={() => {
const key = editor.key([0]);
if (!key) return;
editor.api.navigation.flashTarget({
key,
attributes: { className: 'rounded-md bg-yellow-100' },
duration: 1200,
});
}}
>
Highlight first block
</button>
);
}import { useEditor } from 'platejs/react';
export function FlashFirstBlock() {
const editor = useEditor();
return (
<button
type="button"
onClick={() => {
const key = editor.key([0]);
if (!key) return;
editor.api.navigation.flashTarget({
key,
attributes: { className: 'rounded-md bg-yellow-100' },
duration: 1200,
});
Flashing does not change the document, selection, focus, scroll position, or
history. Each mounted view has its own target and timer, even when several
views display the same document. A base editor without a mounted view returns
false; it does not choose another view.
The API returns false for a deleted key, a text node, a key from another
editor or content root, or an unmounted view. An invalid target leaves the
current flash intact. A duration must be finite and non-negative.
attributes accepts render-safe whole-element presentation, including
className, style, and data-* or aria-* attributes. It excludes event
handlers, refs, and HTML injection. The plugin copies the attributes and style
object for each flash.
The active element also receives these plugin-owned lifecycle markers:
| Attribute | Value |
|---|---|
data-nav-target | "true" while the target is active. |
data-nav-cycle | "0" or "1", alternating with each flash. |
data-nav-pulse | Increasing pulse counter for the mounted view. |
--plate-nav-feedback-duration | CSS duration such as "1200ms". |
These markers take precedence over values passed in attributes. For an
animation, use data-nav-cycle to alternate between two animation names so a
repeated flash restarts. Put the corresponding styles in the copied feature
that requests the feedback.
A standard EditorElement receives the attributes on its root. To highlight a
nested control, style it from the neutral marker on its element:
import type { FootnotePlugin } from 'platejs/footnote/react';
import { EditorElement, type EditorElementProps } from 'platejs/react';
export function FootnoteReferenceElement(
props: EditorElementProps<typeof FootnotePlugin>
) {
return (
<EditorElement {...props} as="sup" className="group/footnote">
<button
className="group-data-[nav-target=true]/footnote:bg-yellow-100"
contentEditable={false}
type="button"
>
[{props.element.ref}]
</button>
{props.children}
</EditorElement>
);
}import type { FootnotePlugin } from 'platejs/footnote/react';
import { EditorElement, type EditorElementProps } from 'platejs/react';
export function FootnoteReferenceElement(
props: EditorElementProps<typeof FootnotePlugin>
) {
return (
<EditorElement {...props} as="sup" className="group/footnote">
<button
className="group-data-[nav-target=true]/footnote:bg-yellow-100"
contentEditable={false}
type="button"
>
[{props.element.ref}]
editor.api.navigation.clear();editor.api.navigation.clear();Clearing cancels the timer and returns whether this view had an active target.
Flash one live element in the calling mounted view. Replaces that view's current target and restarts its timer.