umbraco-tiptap-statusbar-extension について
Umbraco Tiptap のステータスバー拡張を作成するためのスキルです。最新ドキュメントの確認から、マニフェストと要素の作成、テスト方法の説明までを案内します。
主な機能
- 01ステータスバー拡張の案内
- 02マニフェストと要素の例
- 03エディターコンテキストとイベントへのアクセス
- 04ドキュメント確認を優先するワークフロー
活用シーン
- 01単語数や文字数の表示
- 02要素パスのパンくず表示
- 03カーソル位置やエディター状態の追跡
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ umbraco/ umbraco-cms-backoffice-skills --skill umbraco-tiptap-statusbar-extensionインストール後、Claude Code で/umbraco-tiptap-statusbar-extensionを入力して読み込まれたか確認します。
詳細
Umbraco Tiptap ステータスバー拡張機能
これは何ですか?
Tiptap ステータスバー拡張機能は、リッチテキストエディター下部のステータスバーにコンポーネントを追加します。一般的な用途としては、要素パス(パンくずナビゲーション)の表示、単語数、文字数、その他のエディター状態情報の表示などがあります。ツールバー拡張機能とは異なり、ステータスバー拡張機能は純粋に視覚的・情報的な要素です。
ドキュメント
実装前に必ず最新のドキュメントを取得してください:
- 拡張機能の種類: https://docs.umbraco.com/umbraco-cms/extend-your-project/backoffice-extensions/extending-overview/extension-types
- リッチテキストエディター: https://docs.umbraco.com/umbraco-cms/model-your-content/property-editors/built-in-umbraco-property-editors/rich-text-editor
- Tiptap ドキュメント: https://tiptap.dev/docs/editor/extensions/overview
- 基礎: https://docs.umbraco.com/umbraco-cms/extend-your-project/backoffice-extensions/foundation
関連スキル
-
Tiptap 拡張機能: エディター機能を追加するため
- 参照スキル:
umbraco-tiptap-extension
- 参照スキル:
-
Umbraco 要素: ステータスバー要素を実装するため
- 参照スキル:
umbraco-umbraco-element
- 参照スキル:
-
Context API: Tiptap RTE コンテキストにアクセスするため
- 参照スキル:
umbraco-context-api
- 参照スキル:
ワークフロー
- ドキュメントを取得 - 上記の URL に対して WebFetch を使用します
- 質問する - どのような情報を表示しますか? リアルタイム更新は必要ですか?
- ファイルを生成 - 最新のドキュメントに基づいてマニフェスト + 要素を作成します
- 説明 - 作成された内容とテスト方法を示します
最小限の例
マニフェスト (manifests.ts)
import type { ManifestTiptapStatusbarExtension } from '@umbraco-cms/backoffice/extension-registry';
const manifest: ManifestTiptapStatusbarExtension = {
type: 'tiptapStatusbarExtension',
alias: 'My.TiptapStatusbar.WordCount',
name: 'Word Count Statusbar',
element: () => import('./word-count.statusbar-element.js'),
forExtensions: [], // Optional: link to specific tiptap extensions
meta: {
alias: 'wordCount',
icon: 'icon-document',
label: 'Word Count',
},
};
export const manifests = [manifest];
ステータスバー要素 (word-count.statusbar-element.ts)
import { html, css, customElement, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UMB_TIPTAP_RTE_CONTEXT } from '@umbraco-cms/backoffice/tiptap';
@customElement('my-word-count-statusbar')
export class WordCountStatusbarElement extends UmbLitElement {
@state()
private _wordCount = 0;
@state()
private _charCount = 0;
constructor() {
super();
this.consumeContext(UMB_TIPTAP_RTE_CONTEXT, (context) => {
this.observe(context.editor, (editor) => {
if (editor) {
// Update counts when editor content changes
editor.on('update', () => this.#updateCounts(editor));
// Initial count
this.#updateCounts(editor);
}
});
});
}
#updateCounts(editor: any) {
const text = editor.getText();
this._charCount = text.length;
this._wordCount = text.trim() ? text.trim().split(/\s+/).length : 0;
}
render() {
return html`
<span class="count">Words: ${this._wordCount}</span>
<span class="count">Characters: ${this._charCount}</span>
`;
}
static styles = css`
:host {
display: flex;
gap: var(--uui-size-space-4);
font-size: var(--uui-type-small-size);
color: var(--uui-color-text-alt);
}
.count {
padding: 0 var(--uui-size-space-2);
}
`;
}
export default WordCountStatusbarElement;
declare global {
interface HTMLElementTagNameMap {
'my-word-count-statusbar': WordCountStatusbarElement;
}
}
要素パスステータスバー(パンくずナビゲーション)
import { html, css, customElement, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UMB_TIPTAP_RTE_CONTEXT } from '@umbraco-cms/backoffice/tiptap';
@customElement('my-element-path-statusbar')
export class ElementPathStatusbarElement extends UmbLitElement {
@state()
private _path: string[] = [];
constructor() {
super();
this.consumeContext(UMB_TIPTAP_RTE_CONTEXT, (context) => {
this.observe(context.editor, (editor) => {
if (editor) {
editor.on('selectionUpdate', () => this.#updatePath(editor));
this.#updatePath(editor);
}
});
});
}
#updatePath(editor: any) {
const { $from } = editor.state.selection;
const path: string[] = [];
for (let depth = $from.depth; depth > 0; depth--) {
const node = $from.node(depth);
path.unshift(node.type.name);
}
this._path = path;
}
#handleClick(index: number) {
// Could implement navigation to that element
console.log('Navigate to:', this._path[index]);
}
render() {
return html`
${this._path.map(
(name, index) => html`
${index > 0 ? html`<span class="separator">›</span>` : ''}
<button @click=${() => this.#handleClick(index)}>${name}</button>
`
)}
`;
}
static styles = css`
:host {
display: flex;
align-items: center;
font-size: var(--uui-type-small-size);
}
button {
background: none;
border: none;
padding: var(--uui-size-space-1) var(--uui-size-space-2);
cursor: pointer;
color: var(--uui-color-text-alt);
}
button:hover {
color: var(--uui-color-text);
text-decoration: underline;
}
.separator {
color: var(--uui-color-border);
margin: 0 var(--uui-size-space-1);
}
`;
}
export default ElementPathStatusbarElement;
カーソル位置ステータスバー
import { html, css, customElement, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UMB_TIPTAP_RTE_CONTEXT } from '@umbraco-cms/backoffice/tiptap';
@customElement('my-cursor-position-statusbar')
export class CursorPositionStatusbarElement extends UmbLitElement {
@state()
private _line = 1;
@state()
private _column = 1;
constructor() {
super();
this.consumeContext(UMB_TIPTAP_RTE_CONTEXT, (context) => {
this.observe(context.editor, (editor) => {
if (editor) {
editor.on('selectionUpdate', () => this.#updatePosition(editor));
}
});
});
}
#updatePosition(editor: any) {
const { from } = editor.state.selection;
// Simplified line/column calculation
const doc = editor.state.doc;
let pos = 0;
let line = 1;
doc.descendants((node: any, nodePos: number) => {
if (nodePos >= from) return false;
if (node.isBlock) line++;
return true;
});
this._line = line;
this._column = from - pos;
}
render() {
return html`
<span>Ln ${this._line}, Col ${this._column}</span>
`;
}
static styles = css`
:host {
font-size: var(--uui-type-small-size);
color: var(--uui-color-text-alt);
}
`;
}
export default CursorPositionStatusbarElement;
メタプロパティ
| プロパティ | 説明 |
|---|---|
alias | ステータスバー項目の一意の識別子 |
icon | アイコン(構成 UI で使用されます) |
label | 表示名 |
エディターコンテキストへのアクセス
UMB_TIPTAP_RTE_CONTEXT を使用して Tiptap エディターインスタンスにアクセスし、以下のようなイベントを購読します:
update- コンテンツが変更されましたselectionUpdate- カーソル/選択範囲が変更されましたfocus/blur- フォーカス状態が変更されました
以上です! 常に最新のドキュメントを取得し、例を最小限に保ち、完全に動作するコードを生成してください。
コメント
Markdown 対応