Primitive React components and hooks for implementing caption functionality in Plate rich-text editors.
—
The core plugin system provides the foundation for caption functionality in Plate editors through BaseCaptionPlugin and the withCaption editor enhancement.
import {
BaseCaptionPlugin,
withCaption,
type CaptionConfig
} from "@udecode/plate-caption";
import type {
OverrideEditor,
PluginConfig,
SlateEditor,
Path
} from "@udecode/plate";Core plugin that integrates caption functionality with Plate's plugin system, managing state for focus paths, visibility, and element queries.
/**
* Core caption plugin with configuration options
*/
const BaseCaptionPlugin = createTSlatePlugin<CaptionConfig>({
key: KEYS.caption,
options: {
focusEndPath: null,
focusStartPath: null,
query: { allow: [] },
visibleId: null,
},
});
type CaptionConfig = PluginConfig<
'caption',
{
/** When defined, focus end of caption textarea with the same path. */
focusEndPath: Path | null;
/** When defined, focus start of caption textarea with the same path. */
focusStartPath: Path | null;
query: {
/** Plugin keys to enable caption. */
allow: string[];
};
/** ID of currently visible caption element */
visibleId: string | null;
},
{},
{},
{
/** Check if caption is visible for given element ID */
isVisible?: (elementId: string) => boolean;
}
>;Usage Examples:
import { createPlateEditor } from "@udecode/plate";
import { BaseCaptionPlugin } from "@udecode/plate-caption";
// Basic configuration
const editor = createPlateEditor({
plugins: [
BaseCaptionPlugin.configure({
options: {
query: { allow: ['img', 'media', 'video'] } // Enable captions for these element types
}
})
]
});
// Access plugin options
const captionOptions = editor.getOptions(BaseCaptionPlugin);
console.log(captionOptions.query.allow); // ['img', 'media', 'video']
// Set visibility for specific element
editor.setOption(BaseCaptionPlugin, 'visibleId', 'element-123');
// Check if element caption is visible
const isVisible = editor.getSelector(BaseCaptionPlugin).isVisible('element-123');Editor override function that adds caption-specific behavior including selection handling and keyboard navigation.
/**
* Editor override that adds caption-specific behavior including selection handling and keyboard navigation.
* This is an OverrideEditor function that's automatically applied by BaseCaptionPlugin.
*/
const withCaption: OverrideEditor<CaptionConfig>;
type OverrideEditor<T extends PluginConfig> = (config: {
editor: SlateEditor;
getOptions: () => T['options'];
tf: any;
}) => any;Key Behaviors:
Usage Examples:
import { createPlateEditor } from "@udecode/plate";
import { BaseCaptionPlugin } from "@udecode/plate-caption";
// The plugin automatically applies withCaption when configured
const editor = createPlateEditor({
plugins: [BaseCaptionPlugin]
});
// withCaption is automatically applied by the plugin system - no manual application needed
// The editor enhancement handles selection and keyboard navigation behavior internallyControls which element types can have captions:
// Enable captions for specific element types
BaseCaptionPlugin.configure({
options: {
query: {
allow: ['img', 'media', 'video', 'embed']
}
}
})
// Disable captions entirely
BaseCaptionPlugin.configure({
options: {
query: { allow: [] }
}
})Control focus behavior for caption interaction:
// Programmatically set focus to caption
editor.setOption(BaseCaptionPlugin, 'focusEndPath', [0, 1]); // Focus end of caption at path [0, 1]
editor.setOption(BaseCaptionPlugin, 'focusStartPath', [0, 1]); // Focus start of caption at path [0, 1]
// Clear focus paths
editor.setOption(BaseCaptionPlugin, 'focusEndPath', null);
editor.setOption(BaseCaptionPlugin, 'focusStartPath', null);Control which caption is currently visible:
// Show caption for specific element
editor.setOption(BaseCaptionPlugin, 'visibleId', 'img-element-123');
// Hide all captions
editor.setOption(BaseCaptionPlugin, 'visibleId', null);
// Check visibility
const isVisible = editor.getSelector(BaseCaptionPlugin).isVisible('img-element-123');Caption functionality integrates with existing Plate elements by extending them with caption data:
// Element with caption
interface TCaptionElement extends TElement {
id: string; // Required for caption identification
caption?: TElement[]; // Optional caption content
}
// Example element structure
const imageWithCaption: TCaptionElement = {
id: 'img-123',
type: 'img',
url: 'example.jpg',
children: [{ text: '' }],
caption: [{ text: 'This is the image caption' }]
};The plugin handles various edge cases and errors:
Install with Tessl CLI
npx tessl i tessl/npm-udecode--plate-caption