Creates extensions for core Tiptap formats
- Adds icon registry for custom icons - Adds placeholder extensions for Umbraco's Embed and URL Picker features
This commit is contained in:
committed by
Jacob Overgaard
parent
2d9eb20d68
commit
d19caa9a6e
@@ -0,0 +1,81 @@
|
||||
import { UmbIconRegistry } from '@umbraco-cms/backoffice/icon';
|
||||
|
||||
export class UmbTiptapIconRegistry extends UmbIconRegistry {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.defineIcon(
|
||||
'bold',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bold"><path d="M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8" /></svg>`,
|
||||
);
|
||||
|
||||
this.defineIcon(
|
||||
'italic',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-italic"><line x1="19" x2="10" y1="4" y2="4" /><line x1="14" x2="5" y1="20" y2="20" /><line x1="15" x2="9" y1="4" y2="20" /></svg>`,
|
||||
);
|
||||
this.defineIcon(
|
||||
'underline',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-underline"><path d="M6 4v6a6 6 0 0 0 12 0V4" /><line x1="4" x2="20" y1="20" y2="20" /></svg>`,
|
||||
);
|
||||
this.defineIcon(
|
||||
'strike',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-strikethrough"><path d="M16 4H9a3 3 0 0 0-2.83 4" /><path d="M14 12a4 4 0 0 1 0 8H6" /><line x1="4" x2="20" y1="12" y2="12" /></svg>`,
|
||||
);
|
||||
this.defineIcon(
|
||||
'heading1',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-heading-1"><path d="M4 12h8" /><path d="M4 18V6" /><path d="M12 18V6" /><path d="m17 12 3-2v8" /></svg>`,
|
||||
);
|
||||
this.defineIcon(
|
||||
'heading2',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-heading-2"><path d="M4 12h8" /><path d="M4 18V6" /><path d="M12 18V6" /><path d="M21 18h-4c0-4 4-3 4-6 0-1.5-2-2.5-4-1" /></svg>`,
|
||||
);
|
||||
this.defineIcon(
|
||||
'heading3',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-heading-3"><path d="M4 12h8" /><path d="M4 18V6" /><path d="M12 18V6" /><path d="M17.5 10.5c1.7-1 3.5 0 3.5 1.5a2 2 0 0 1-2 2" /><path d="M17 17.5c2 1.5 4 .3 4-1.5a2 2 0 0 0-2-2" /></svg>`,
|
||||
);
|
||||
this.defineIcon(
|
||||
'blockquote',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-text-quote"><path d="M17 6H3" /><path d="M21 12H8" /><path d="M21 18H8" /><path d="M3 12v6" /></svg>`,
|
||||
);
|
||||
this.defineIcon(
|
||||
'code-block',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-code"><polyline points="16 18 22 12 16 6" /><polyline points="8 6 2 12 8 18" /></svg>`,
|
||||
);
|
||||
this.defineIcon(
|
||||
'bullet-list',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-list"><line x1="8" x2="21" y1="6" y2="6" /><line x1="8" x2="21" y1="12" y2="12" /><line x1="8" x2="21" y1="18" y2="18" /><line x1="3" x2="3.01" y1="6" y2="6" /><line x1="3" x2="3.01" y1="12" y2="12" /><line x1="3" x2="3.01" y1="18" y2="18" /></svg>`,
|
||||
);
|
||||
this.defineIcon(
|
||||
'ordered-list',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-list-ordered"><line x1="10" x2="21" y1="6" y2="6" /><line x1="10" x2="21" y1="12" y2="12" /><line x1="10" x2="21" y1="18" y2="18" /><path d="M4 6h1v4" /><path d="M4 10h2" /><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1" /></svg>`,
|
||||
);
|
||||
this.defineIcon(
|
||||
'horizontal-rule',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-separator-horizontal"><line x1="3" x2="21" y1="12" y2="12" /><polyline points="8 8 12 4 16 8" /><polyline points="16 16 12 20 8 16" /></svg>`,
|
||||
);
|
||||
this.defineIcon(
|
||||
'text-align-left',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-align-left"><line x1="21" x2="3" y1="6" y2="6" /><line x1="15" x2="3" y1="12" y2="12" /><line x1="17" x2="3" y1="18" y2="18" /></svg>`,
|
||||
);
|
||||
this.defineIcon(
|
||||
'text-align-center',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-align-center"><line x1="21" x2="3" y1="6" y2="6" /><line x1="17" x2="7" y1="12" y2="12" /><line x1="19" x2="5" y1="18" y2="18" /></svg>`,
|
||||
);
|
||||
this.defineIcon(
|
||||
'text-align-right',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-align-right"><line x1="21" x2="3" y1="6" y2="6" /><line x1="21" x2="9" y1="12" y2="12" /><line x1="21" x2="7" y1="18" y2="18" /></svg>`,
|
||||
);
|
||||
this.defineIcon(
|
||||
'text-align-justify',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-align-justify"><line x1="3" x2="21" y1="6" y2="6" /><line x1="3" x2="21" y1="12" y2="12" /><line x1="3" x2="21" y1="18" y2="18" /></svg>`,
|
||||
);
|
||||
this.defineIcon(
|
||||
'link',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" /><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" /></svg>`,
|
||||
);
|
||||
this.defineIcon(
|
||||
'umbraco',
|
||||
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 315.89 315.89" fill="currentColor"><path d="M0,157.74A157.95,157.95,0,1,1,158,315.89,157.95,157.95,0,0,1,0,157.74Zm154.74,54.09a155.41,155.41,0,0,1-36.5-3.29,27.92,27.92,0,0,1-19.94-16q-5.35-12.34-5.21-38.1a243,243,0,0,1,1.69-26.84q1.55-13,3.09-21.46l1.07-5.59a2,2,0,0,0,0-.49,3.2,3.2,0,0,0-2.65-3.17L75.92,93.67h-.44a3.19,3.19,0,0,0-3.11,2.48c-.35,1.31-.56,2.27-1.17,5.38-1.16,6-2.24,11.85-3.43,20.38a264.17,264.17,0,0,0-2.3,27.94,145.24,145.24,0,0,0,0,19.57q.72,25.94,8.9,41.42t27.72,22.3q19.53,6.81,54.43,6.66h2.91q34.94.15,54.41-6.66t27.71-22.3q8.17-15.53,8.91-41.42a145.24,145.24,0,0,0,0-19.57,266.84,266.84,0,0,0-2.3-27.94c-1.2-8.44-2.27-14.26-3.44-20.38-.61-3.11-.81-4.07-1.16-5.38a3.21,3.21,0,0,0-3.12-2.48h-.52l-20.38,3.18a3.2,3.2,0,0,0-2.68,3.17,4,4,0,0,0,0,.49l1.08,5.59q1.55,8.48,3.12,21.46a245.68,245.68,0,0,1,1.65,26.84q.27,25.69-5.21,38.07a27.9,27.9,0,0,1-19.76,16.07,155.19,155.19,0,0,1-36.48,3.29Z" /></svg>`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,268 +0,0 @@
|
||||
import { html } from '@umbraco-cms/backoffice/external/lit';
|
||||
|
||||
const iconSize = '16px';
|
||||
export const bold = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width=${iconSize}
|
||||
height=${iconSize}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-bold">
|
||||
<path d="M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8" />
|
||||
</svg>`;
|
||||
|
||||
export const italic = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width=${iconSize}
|
||||
height=${iconSize}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-italic">
|
||||
<line x1="19" x2="10" y1="4" y2="4" />
|
||||
<line x1="14" x2="5" y1="20" y2="20" />
|
||||
<line x1="15" x2="9" y1="4" y2="20" />
|
||||
</svg>`;
|
||||
|
||||
export const underline = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width=${iconSize}
|
||||
height=${iconSize}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-underline">
|
||||
<path d="M6 4v6a6 6 0 0 0 12 0V4" />
|
||||
<line x1="4" x2="20" y1="20" y2="20" />
|
||||
</svg>`;
|
||||
|
||||
export const strikethrough = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width=${iconSize}
|
||||
height=${iconSize}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-strikethrough">
|
||||
<path d="M16 4H9a3 3 0 0 0-2.83 4" />
|
||||
<path d="M14 12a4 4 0 0 1 0 8H6" />
|
||||
<line x1="4" x2="20" y1="12" y2="12" />
|
||||
</svg>`;
|
||||
export const heading1 = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width=${iconSize}
|
||||
height=${iconSize}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-heading-1">
|
||||
<path d="M4 12h8" />
|
||||
<path d="M4 18V6" />
|
||||
<path d="M12 18V6" />
|
||||
<path d="m17 12 3-2v8" />
|
||||
</svg>`;
|
||||
export const heading2 = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width=${iconSize}
|
||||
height=${iconSize}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-heading-2">
|
||||
<path d="M4 12h8" />
|
||||
<path d="M4 18V6" />
|
||||
<path d="M12 18V6" />
|
||||
<path d="M21 18h-4c0-4 4-3 4-6 0-1.5-2-2.5-4-1" />
|
||||
</svg>`;
|
||||
export const heading3 = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width=${iconSize}
|
||||
height=${iconSize}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-heading-3">
|
||||
<path d="M4 12h8" />
|
||||
<path d="M4 18V6" />
|
||||
<path d="M12 18V6" />
|
||||
<path d="M17.5 10.5c1.7-1 3.5 0 3.5 1.5a2 2 0 0 1-2 2" />
|
||||
<path d="M17 17.5c2 1.5 4 .3 4-1.5a2 2 0 0 0-2-2" />
|
||||
</svg>`;
|
||||
export const blockquote = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width=${iconSize}
|
||||
height=${iconSize}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-text-quote">
|
||||
<path d="M17 6H3" />
|
||||
<path d="M21 12H8" />
|
||||
<path d="M21 18H8" />
|
||||
<path d="M3 12v6" />
|
||||
</svg>`;
|
||||
export const code = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width=${iconSize}
|
||||
height=${iconSize}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-code">
|
||||
<polyline points="16 18 22 12 16 6" />
|
||||
<polyline points="8 6 2 12 8 18" />
|
||||
</svg>`;
|
||||
export const bulletList = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width=${iconSize}
|
||||
height=${iconSize}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-list">
|
||||
<line x1="8" x2="21" y1="6" y2="6" />
|
||||
<line x1="8" x2="21" y1="12" y2="12" />
|
||||
<line x1="8" x2="21" y1="18" y2="18" />
|
||||
<line x1="3" x2="3.01" y1="6" y2="6" />
|
||||
<line x1="3" x2="3.01" y1="12" y2="12" />
|
||||
<line x1="3" x2="3.01" y1="18" y2="18" />
|
||||
</svg>`;
|
||||
export const orderedList = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width=${iconSize}
|
||||
height=${iconSize}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-list-ordered">
|
||||
<line x1="10" x2="21" y1="6" y2="6" />
|
||||
<line x1="10" x2="21" y1="12" y2="12" />
|
||||
<line x1="10" x2="21" y1="18" y2="18" />
|
||||
<path d="M4 6h1v4" />
|
||||
<path d="M4 10h2" />
|
||||
<path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1" />
|
||||
</svg>`;
|
||||
export const horizontalRule = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width=${iconSize}
|
||||
height=${iconSize}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-separator-horizontal">
|
||||
<line x1="3" x2="21" y1="12" y2="12" />
|
||||
<polyline points="8 8 12 4 16 8" />
|
||||
<polyline points="16 16 12 20 8 16" />
|
||||
</svg>`;
|
||||
export const alignLeft = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width=${iconSize}
|
||||
height=${iconSize}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-align-left">
|
||||
<line x1="21" x2="3" y1="6" y2="6" />
|
||||
<line x1="15" x2="3" y1="12" y2="12" />
|
||||
<line x1="17" x2="3" y1="18" y2="18" />
|
||||
</svg>`;
|
||||
export const alignCenter = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width=${iconSize}
|
||||
height=${iconSize}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-align-center">
|
||||
<line x1="21" x2="3" y1="6" y2="6" />
|
||||
<line x1="17" x2="7" y1="12" y2="12" />
|
||||
<line x1="19" x2="5" y1="18" y2="18" />
|
||||
</svg>`;
|
||||
export const alignRight = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width=${iconSize}
|
||||
height=${iconSize}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-align-right">
|
||||
<line x1="21" x2="3" y1="6" y2="6" />
|
||||
<line x1="21" x2="9" y1="12" y2="12" />
|
||||
<line x1="21" x2="7" y1="18" y2="18" />
|
||||
</svg>`;
|
||||
export const alignJustify = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width=${iconSize}
|
||||
height=${iconSize}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-align-justify">
|
||||
<line x1="3" x2="21" y1="6" y2="6" />
|
||||
<line x1="3" x2="21" y1="12" y2="12" />
|
||||
<line x1="3" x2="21" y1="18" y2="18" />
|
||||
</svg>`;
|
||||
|
||||
export const link = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width=${iconSize}
|
||||
height=${iconSize}
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
class="lucide lucide-link">
|
||||
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" />
|
||||
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />
|
||||
</svg>`;
|
||||
@@ -3,28 +3,14 @@ import { css, customElement, html, property, state, when } from '@umbraco-cms/ba
|
||||
import { loadManifestApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import {
|
||||
Blockquote,
|
||||
Bold,
|
||||
BulletList,
|
||||
Code,
|
||||
CodeBlock,
|
||||
Document,
|
||||
Dropcursor,
|
||||
Editor,
|
||||
Gapcursor,
|
||||
HardBreak,
|
||||
Heading,
|
||||
History,
|
||||
HorizontalRule,
|
||||
Italic,
|
||||
Link,
|
||||
ListItem,
|
||||
OrderedList,
|
||||
Paragraph,
|
||||
Strike,
|
||||
Text,
|
||||
TextAlign,
|
||||
Underline,
|
||||
} from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
@@ -83,26 +69,7 @@ export class UmbInputTiptapElement extends UmbFormControlMixin<string, typeof Um
|
||||
this._editor = new Editor({
|
||||
element: element,
|
||||
editable: !this.readonly,
|
||||
extensions: [
|
||||
...this.#requiredExtensions,
|
||||
Blockquote,
|
||||
Bold,
|
||||
BulletList,
|
||||
Code,
|
||||
CodeBlock,
|
||||
Heading,
|
||||
HorizontalRule,
|
||||
Italic,
|
||||
Link.configure({ openOnClick: false }),
|
||||
ListItem, // This is needed for BulletList and OrderedList. When moving to an umbraco-extension, how should we handle shared extensions?
|
||||
OrderedList,
|
||||
Strike,
|
||||
TextAlign.configure({
|
||||
types: ['heading', 'paragraph', 'blockquote', 'orderedList', 'bulletList', 'codeBlock'],
|
||||
}),
|
||||
Underline,
|
||||
...extensions,
|
||||
],
|
||||
extensions: [...this.#requiredExtensions, ...extensions],
|
||||
content: this.value,
|
||||
onUpdate: ({ editor }) => {
|
||||
this.value = editor.getHTML();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import type { UmbTiptapToolbarButton } from '../../extensions/types.js';
|
||||
import type { ManifestTiptapExtension } from '../../extensions/tiptap-extension.js';
|
||||
import * as icons from './icons.js';
|
||||
import { css, customElement, html, property, state, when } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbTiptapIconRegistry } from './icon.registry.js';
|
||||
import { css, customElement, html, property } from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
@@ -10,135 +9,6 @@ export class UmbTiptapFixedMenuElement extends UmbLitElement {
|
||||
@property({ type: Boolean, reflect: true })
|
||||
readonly = false;
|
||||
|
||||
@state()
|
||||
actions: Array<UmbTiptapToolbarButton> = [
|
||||
// TODO: I don't think we need a paragraph button. It's the default state.
|
||||
// {
|
||||
// name: 'paragraph',
|
||||
// icon: html`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20">
|
||||
// <path fill="none" d="M0 0h24v24H0z" />
|
||||
// <path d="M12 6v15h-2v-5a6 6 0 1 1 0-12h10v2h-3v15h-2V6h-3zm-2 0a4 4 0 1 0 0 8V6z" fill="currentColor" />
|
||||
// </svg>`,
|
||||
// command: (editor) => editor?.chain().focus().setParagraph().run(),
|
||||
// },
|
||||
{
|
||||
name: 'bold',
|
||||
icon: icons.bold,
|
||||
isActive: (editor) => editor?.isActive('bold'),
|
||||
command: (editor) => editor?.chain().focus().toggleBold().run(),
|
||||
},
|
||||
{
|
||||
name: 'italic',
|
||||
icon: icons.italic,
|
||||
isActive: (editor) => editor?.isActive('italic'),
|
||||
command: (editor) => editor?.chain().focus().toggleItalic().run(),
|
||||
},
|
||||
{
|
||||
name: 'underline',
|
||||
icon: icons.underline,
|
||||
isActive: (editor) => editor?.isActive('underline'),
|
||||
command: (editor) => editor?.chain().focus().toggleUnderline().run(),
|
||||
},
|
||||
{
|
||||
name: 'strikethrough',
|
||||
icon: icons.strikethrough,
|
||||
isActive: (editor) => editor?.isActive('strike'),
|
||||
command: (editor) => editor?.chain().focus().toggleStrike().run(),
|
||||
},
|
||||
{
|
||||
name: 'h1',
|
||||
icon: icons.heading1,
|
||||
isActive: (editor) => editor?.isActive('heading', { level: 1 }),
|
||||
command: (editor) => editor?.chain().focus().toggleHeading({ level: 1 }).run(),
|
||||
},
|
||||
{
|
||||
name: 'h2',
|
||||
icon: icons.heading2,
|
||||
isActive: (editor) => editor?.isActive('heading', { level: 2 }),
|
||||
command: (editor) => editor?.chain().focus().toggleHeading({ level: 2 }).run(),
|
||||
},
|
||||
{
|
||||
name: 'h3',
|
||||
icon: icons.heading3,
|
||||
isActive: (editor) => editor?.isActive('heading', { level: 3 }),
|
||||
command: (editor) => editor?.chain().focus().toggleHeading({ level: 3 }).run(),
|
||||
},
|
||||
{
|
||||
name: 'blockquote',
|
||||
icon: icons.blockquote,
|
||||
isActive: (editor) => editor?.isActive('blockquote'),
|
||||
command: (editor) => editor?.chain().focus().toggleBlockquote().run(),
|
||||
},
|
||||
{
|
||||
name: 'code',
|
||||
icon: icons.code,
|
||||
isActive: (editor) => editor?.isActive('codeBlock'),
|
||||
command: (editor) => editor?.chain().focus().toggleCodeBlock().run(),
|
||||
},
|
||||
{
|
||||
name: 'bullet-list',
|
||||
icon: icons.bulletList,
|
||||
isActive: (editor) => editor?.isActive('bulletList'),
|
||||
command: (editor) => editor?.chain().focus().toggleBulletList().run(),
|
||||
},
|
||||
{
|
||||
name: 'ordered-list',
|
||||
icon: icons.orderedList,
|
||||
isActive: (editor) => editor?.isActive('orderedList'),
|
||||
command: (editor) => editor?.chain().focus().toggleOrderedList().run(),
|
||||
},
|
||||
{
|
||||
name: 'horizontal-rule',
|
||||
icon: icons.horizontalRule,
|
||||
isActive: (editor) => editor?.isActive('horizontalRule'),
|
||||
command: (editor) => editor?.chain().focus().setHorizontalRule().run(),
|
||||
},
|
||||
{
|
||||
name: 'align-left',
|
||||
icon: icons.alignLeft,
|
||||
isActive: (editor) => editor?.isActive({ textAlign: 'left' }),
|
||||
command: (editor) => editor?.chain().focus().setTextAlign('left').run(),
|
||||
},
|
||||
{
|
||||
name: 'align-center',
|
||||
icon: icons.alignCenter,
|
||||
isActive: (editor) => editor?.isActive({ textAlign: 'center' }),
|
||||
command: (editor) => editor?.chain().focus().setTextAlign('center').run(),
|
||||
},
|
||||
{
|
||||
name: 'align-right',
|
||||
icon: icons.alignRight,
|
||||
isActive: (editor) => editor?.isActive({ textAlign: 'right' }),
|
||||
command: (editor) => editor?.chain().focus().setTextAlign('right').run(),
|
||||
},
|
||||
{
|
||||
name: 'align-justify',
|
||||
icon: icons.alignJustify,
|
||||
isActive: (editor) => editor?.isActive({ textAlign: 'justify' }),
|
||||
command: (editor) => editor?.chain().focus().setTextAlign('justify').run(),
|
||||
},
|
||||
{
|
||||
name: 'link',
|
||||
icon: icons.link,
|
||||
isActive: (editor) => editor?.isActive('link'),
|
||||
command: () => {
|
||||
const text = prompt('Enter the text');
|
||||
const url = prompt('Enter the URL');
|
||||
|
||||
if (url && text && this.editor) {
|
||||
const { from } = this.editor.state.selection;
|
||||
this.editor
|
||||
.chain()
|
||||
.focus()
|
||||
.insertContent(text)
|
||||
.setTextSelection({ from: from, to: from + text.length })
|
||||
.setLink({ href: url, target: '_blank' })
|
||||
.run();
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@property({ attribute: false })
|
||||
set editor(value) {
|
||||
const oldValue = this.#editor;
|
||||
@@ -158,22 +28,15 @@ export class UmbTiptapFixedMenuElement extends UmbLitElement {
|
||||
this.requestUpdate();
|
||||
};
|
||||
|
||||
#registry = new UmbTiptapIconRegistry();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.#registry.attach(this);
|
||||
}
|
||||
|
||||
override render() {
|
||||
return html`
|
||||
${this.actions.map(
|
||||
(action) => html`
|
||||
<button
|
||||
class=${action.isActive?.(this.editor) ? 'active' : ''}
|
||||
title=${action.name}
|
||||
@click=${() => action.command(this.editor)}>
|
||||
${when(
|
||||
typeof action.icon === 'string',
|
||||
() => html`<umb-icon name=${action.icon}></umb-icon>`,
|
||||
() => action.icon,
|
||||
)}
|
||||
</button>
|
||||
`,
|
||||
)}
|
||||
<umb-extension-with-api-slot
|
||||
type="tiptapExtension"
|
||||
.filter=${(ext: ManifestTiptapExtension) => !!ext.kind || !!ext.element}
|
||||
|
||||
@@ -24,7 +24,6 @@ export class UmbTiptapHoverMenuElement extends LitElement {
|
||||
}
|
||||
|
||||
#onUpdate = () => {
|
||||
console.log('LINK ACTIVE');
|
||||
if (this.editor?.isActive('link')) {
|
||||
// show the popover
|
||||
this.showPopover();
|
||||
@@ -34,7 +33,6 @@ export class UmbTiptapHoverMenuElement extends LitElement {
|
||||
};
|
||||
|
||||
override render() {
|
||||
console.log('RENDER HOVER MENU');
|
||||
return html`<uui-popover-container></uui-popover-container>`;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { UmbTiptapExtensionApi } from '../types.js';
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { Blockquote } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.Blockquote',
|
||||
name: 'Blockquote Tiptap Extension',
|
||||
api: () => import('./blockquote.extension.js'),
|
||||
weight: 995,
|
||||
meta: {
|
||||
alias: 'blockquote',
|
||||
icon: 'blockquote',
|
||||
label: 'Blockquote',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapBlockquotePlugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions = () => [Blockquote];
|
||||
|
||||
override execute(editor?: Editor) {
|
||||
editor?.chain().focus().toggleBlockquote().run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { UmbTiptapExtensionApi } from '../types.js';
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { Bold } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.Bold',
|
||||
name: 'Bold Tiptap Extension',
|
||||
api: () => import('./bold.extension.js'),
|
||||
weight: 999,
|
||||
meta: {
|
||||
alias: 'bold',
|
||||
icon: 'bold',
|
||||
label: 'Bold',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapBoldPlugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions = () => [Bold];
|
||||
|
||||
override execute(editor?: Editor) {
|
||||
editor?.chain().focus().toggleBold().run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { UmbTiptapExtensionApi } from '../types.js';
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { BulletList, ListItem } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.BulletList',
|
||||
name: 'Bullet List Tiptap Extension',
|
||||
api: () => import('./bullet-list.extension.js'),
|
||||
weight: 993,
|
||||
meta: {
|
||||
alias: 'bullet-list',
|
||||
icon: 'bullet-list',
|
||||
label: 'Bullet List',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapBulletListPlugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions = () => [BulletList, ListItem];
|
||||
|
||||
override execute(editor?: Editor) {
|
||||
editor?.chain().focus().toggleBulletList().run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { UmbTiptapExtensionApi } from '../types.js';
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { Code, CodeBlock } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.CodeBlock',
|
||||
name: 'Code Block Tiptap Extension',
|
||||
api: () => import('./code-block.extension.js'),
|
||||
weight: 994,
|
||||
meta: {
|
||||
alias: 'code-block',
|
||||
icon: 'code-block',
|
||||
label: 'Code Block',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapCodePlugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions = () => [Code, CodeBlock];
|
||||
|
||||
override execute(editor?: Editor) {
|
||||
// editor.chain().focus().toggleCode().run();
|
||||
editor?.chain().focus().toggleCodeBlock().run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { UmbTiptapExtensionApi } from '../types.js';
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { Heading } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.Heading1',
|
||||
name: 'Heading 1 Tiptap Extension',
|
||||
api: () => import('./heading1.extension.js'),
|
||||
weight: 949,
|
||||
meta: {
|
||||
alias: 'heading1',
|
||||
icon: 'heading1',
|
||||
label: 'Heading 1',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapHeading1Plugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions = () => [Heading];
|
||||
|
||||
override execute(editor?: Editor) {
|
||||
editor?.chain().focus().toggleHeading({ level: 1 }).run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { UmbTiptapExtensionApi } from '../types.js';
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { Heading } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.Heading2',
|
||||
name: 'Heading 2 Tiptap Extension',
|
||||
api: () => import('./heading2.extension.js'),
|
||||
weight: 948,
|
||||
meta: {
|
||||
alias: 'heading2',
|
||||
icon: 'heading2',
|
||||
label: 'Heading 2',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapHeading1Plugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions = () => [Heading];
|
||||
|
||||
override execute(editor?: Editor) {
|
||||
editor?.chain().focus().toggleHeading({ level: 2 }).run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { UmbTiptapExtensionApi } from '../types.js';
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { Heading } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.Heading3',
|
||||
name: 'Heading 3 Tiptap Extension',
|
||||
api: () => import('./heading3.extension.js'),
|
||||
weight: 947,
|
||||
meta: {
|
||||
alias: 'heading3',
|
||||
icon: 'heading3',
|
||||
label: 'Heading 3',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapHeading1Plugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions = () => [Heading];
|
||||
|
||||
override execute(editor?: Editor) {
|
||||
editor?.chain().focus().toggleHeading({ level: 3 }).run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { UmbTiptapExtensionApi } from '../types.js';
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { HorizontalRule } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.HorizontalRule',
|
||||
name: 'Horizontal Rule Tiptap Extension',
|
||||
api: () => import('./horizontal-rule.extension.js'),
|
||||
weight: 991,
|
||||
meta: {
|
||||
alias: 'horizontal-rule',
|
||||
icon: 'horizontal-rule',
|
||||
label: 'Horizontal Rule',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapHorizontalRulePlugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions = () => [HorizontalRule];
|
||||
|
||||
override execute(editor?: Editor) {
|
||||
editor?.chain().focus().setHorizontalRule().run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { UmbTiptapExtensionApi } from '../types.js';
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { UmbImage } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
alias: 'Umb.Tiptap.Image',
|
||||
name: 'Image Tiptap Extension',
|
||||
api: () => import('./image.extension.js'),
|
||||
meta: {},
|
||||
};
|
||||
|
||||
export default class UmbTiptapImageExtension extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions() {
|
||||
return [UmbImage.configure({ inline: true })];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { UmbTiptapExtensionApi } from '../types.js';
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { Italic } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.Italic',
|
||||
name: 'Italic Tiptap Extension',
|
||||
api: () => import('./italic.extension.js'),
|
||||
weight: 998,
|
||||
meta: {
|
||||
alias: 'italic',
|
||||
icon: 'italic',
|
||||
label: 'Italic',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapItalicPlugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions = () => [Italic];
|
||||
|
||||
override execute(editor?: Editor) {
|
||||
editor?.chain().focus().toggleItalic().run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { manifest as blockquote } from './blockquote.extension.js';
|
||||
import { manifest as bold } from './bold.extension.js';
|
||||
import { manifest as bulletList } from './bullet-list.extension.js';
|
||||
import { manifest as codeBlock } from './code-block.extension.js';
|
||||
import { manifest as image } from './image.extension.js';
|
||||
import { manifest as italic } from './italic.extension.js';
|
||||
import { manifest as heading1 } from './heading1.extension.js';
|
||||
import { manifest as heading2 } from './heading2.extension.js';
|
||||
import { manifest as heading3 } from './heading3.extension.js';
|
||||
import { manifest as horizontalRule } from './horizontal-rule.extension.js';
|
||||
import { manifest as orderedList } from './ordered-list.extension.js';
|
||||
import { manifest as strike } from './strike.extension.js';
|
||||
import { manifest as textAlignLeft } from './text-align-left.extension.js';
|
||||
import { manifest as textAlignCenter } from './text-align-center.extension.js';
|
||||
import { manifest as textAlignRight } from './text-align-right.extension.js';
|
||||
import { manifest as textAlignJustify } from './text-align-justify.extension.js';
|
||||
import { manifest as underline } from './underline.extension.js';
|
||||
|
||||
export const manifests: Array<ManifestTiptapExtension> = [
|
||||
blockquote,
|
||||
bold,
|
||||
bulletList,
|
||||
codeBlock,
|
||||
image,
|
||||
italic,
|
||||
heading1,
|
||||
heading2,
|
||||
heading3,
|
||||
horizontalRule,
|
||||
orderedList,
|
||||
strike,
|
||||
textAlignLeft,
|
||||
textAlignCenter,
|
||||
textAlignRight,
|
||||
textAlignJustify,
|
||||
underline,
|
||||
];
|
||||
@@ -0,0 +1,26 @@
|
||||
import { UmbTiptapExtensionApi } from '../types.js';
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { OrderedList, ListItem } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.OrderedList',
|
||||
name: 'Ordered List Tiptap Extension',
|
||||
api: () => import('./ordered-list.extension.js'),
|
||||
weight: 992,
|
||||
meta: {
|
||||
alias: 'ordered-list',
|
||||
icon: 'ordered-list',
|
||||
label: 'Ordered List',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapOrderedListPlugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions = () => [OrderedList, ListItem];
|
||||
|
||||
override execute(editor?: Editor) {
|
||||
editor?.chain().focus().toggleOrderedList().run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { UmbTiptapExtensionApi } from '../types.js';
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { Strike } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.Strike',
|
||||
name: 'Strike Tiptap Extension',
|
||||
api: () => import('./strike.extension.js'),
|
||||
weight: 996,
|
||||
meta: {
|
||||
alias: 'strike',
|
||||
icon: 'strike',
|
||||
label: 'Strike',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapStrikePlugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions = () => [Strike];
|
||||
|
||||
override execute(editor?: Editor) {
|
||||
editor?.chain().focus().toggleStrike().run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { UmbTiptapExtensionApi } from '../types.js';
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { TextAlign } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.TextAlignCenter',
|
||||
name: 'Text Align Center Tiptap Extension',
|
||||
api: () => import('./text-align-center.extension.js'),
|
||||
weight: 918,
|
||||
meta: {
|
||||
alias: 'text-align-center',
|
||||
icon: 'text-align-center',
|
||||
label: 'Text Align Center',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapTextAlignCenterPlugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions = () => [
|
||||
TextAlign.configure({
|
||||
types: ['heading', 'paragraph', 'blockquote', 'orderedList', 'bulletList', 'codeBlock'],
|
||||
}),
|
||||
];
|
||||
|
||||
override execute(editor?: Editor) {
|
||||
editor?.chain().focus().setTextAlign('center').run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { UmbTiptapExtensionApi } from '../types.js';
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { TextAlign } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.TextAlignJustify',
|
||||
name: 'Text Align Justify Tiptap Extension',
|
||||
api: () => import('./text-align-justify.extension.js'),
|
||||
weight: 916,
|
||||
meta: {
|
||||
alias: 'text-align-justify',
|
||||
icon: 'text-align-justify',
|
||||
label: 'Text Align Justify',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapTextAlignJustifyPlugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions = () => [
|
||||
TextAlign.configure({
|
||||
types: ['heading', 'paragraph', 'blockquote', 'orderedList', 'bulletList', 'codeBlock'],
|
||||
}),
|
||||
];
|
||||
|
||||
override execute(editor?: Editor) {
|
||||
editor?.chain().focus().setTextAlign('justify').run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { UmbTiptapExtensionApi } from '../types.js';
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { TextAlign } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.TextAlignLeft',
|
||||
name: 'Text Align Left Tiptap Extension',
|
||||
api: () => import('./text-align-left.extension.js'),
|
||||
weight: 919,
|
||||
meta: {
|
||||
alias: 'text-align-left',
|
||||
icon: 'text-align-left',
|
||||
label: 'Text Align Left',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapTextAlignLeftPlugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions = () => [
|
||||
TextAlign.configure({
|
||||
types: ['heading', 'paragraph', 'blockquote', 'orderedList', 'bulletList', 'codeBlock'],
|
||||
}),
|
||||
];
|
||||
|
||||
override execute(editor?: Editor) {
|
||||
editor?.chain().focus().setTextAlign('left').run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { UmbTiptapExtensionApi } from '../types.js';
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { TextAlign } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.TextAlignRight',
|
||||
name: 'Text Align Right Tiptap Extension',
|
||||
api: () => import('./text-align-right.extension.js'),
|
||||
weight: 917,
|
||||
meta: {
|
||||
alias: 'text-align-right',
|
||||
icon: 'text-align-right',
|
||||
label: 'Text Align Right',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapTextAlignRightPlugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions = () => [
|
||||
TextAlign.configure({
|
||||
types: ['heading', 'paragraph', 'blockquote', 'orderedList', 'bulletList', 'codeBlock'],
|
||||
}),
|
||||
];
|
||||
|
||||
override execute(editor?: Editor) {
|
||||
editor?.chain().focus().setTextAlign('right').run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { UmbTiptapExtensionApi } from '../types.js';
|
||||
import type { ManifestTiptapExtension } from '../tiptap-extension.js';
|
||||
import { Underline } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.Underline',
|
||||
name: 'Underline Tiptap Extension',
|
||||
api: () => import('./underline.extension.js'),
|
||||
weight: 997,
|
||||
meta: {
|
||||
alias: 'underline',
|
||||
icon: 'underline',
|
||||
label: 'Underline',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapItalicPlugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions = () => [Underline];
|
||||
|
||||
override execute(editor?: Editor) {
|
||||
editor?.chain().focus().toggleUnderline().run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { UmbTiptapExtensionApi } from './types.js';
|
||||
import type { ManifestTiptapExtension } from './tiptap-extension.js';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.Embed',
|
||||
name: 'Embed Tiptap Extension',
|
||||
api: () => import('./embed.extension.js'),
|
||||
meta: {
|
||||
alias: 'umb-embed',
|
||||
icon: 'umbraco',
|
||||
label: 'Embed',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapEmbedPlugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions = () => [];
|
||||
|
||||
override async execute(editor?: Editor) {
|
||||
console.log('umb-embed.execute', editor);
|
||||
// Research: https://github.com/ueberdosis/tiptap/tree/main/packages/extension-youtube
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
import type { ManifestTiptapExtension } from './tiptap-extension.js';
|
||||
import { manifests as core } from './core/manifests.js';
|
||||
import { manifest as embed } from './embed.extension.js';
|
||||
import { manifest as mediaPicker } from './mediapicker.extension.js';
|
||||
import { manifest as urlPicker } from './urlpicker.extension.js';
|
||||
import type { ManifestTypes, UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
const kinds: Array<UmbExtensionManifestKind> = [
|
||||
@@ -13,28 +17,6 @@ const kinds: Array<UmbExtensionManifestKind> = [
|
||||
},
|
||||
];
|
||||
|
||||
const extensions: Array<ManifestTiptapExtension> = [
|
||||
{
|
||||
type: 'tiptapExtension',
|
||||
alias: 'Umb.Tiptap.Image',
|
||||
name: 'Image Tiptap Extension',
|
||||
weight: 1000,
|
||||
api: () => import('./tiptap-image.extension.js'),
|
||||
meta: {},
|
||||
},
|
||||
{
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.MediaPicker',
|
||||
name: 'Media Picker Tiptap Extension',
|
||||
weight: 900,
|
||||
api: () => import('./tiptap-mediapicker.extension.js'),
|
||||
meta: {
|
||||
alias: 'umb-media',
|
||||
icon: 'icon-picture',
|
||||
label: 'Media picker',
|
||||
},
|
||||
},
|
||||
];
|
||||
const extensions: Array<ManifestTiptapExtension> = [...core, embed, mediaPicker, urlPicker];
|
||||
|
||||
export const manifests: Array<ManifestTypes | UmbExtensionManifestKind> = [...kinds, ...extensions];
|
||||
|
||||
@@ -1,9 +1,23 @@
|
||||
import { UmbTiptapExtensionApi } from './types.js';
|
||||
import type { ManifestTiptapExtension } from './tiptap-extension.js';
|
||||
import { mergeAttributes, Node } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import { UMB_MEDIA_PICKER_MODAL } from '@umbraco-cms/backoffice/media';
|
||||
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.MediaPicker',
|
||||
name: 'Media Picker Tiptap Extension',
|
||||
api: () => import('./mediapicker.extension.js'),
|
||||
meta: {
|
||||
alias: 'umb-media',
|
||||
icon: 'umbraco',
|
||||
label: 'Media picker',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapMediaPickerPlugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions() {
|
||||
return [
|
||||
@@ -1,8 +0,0 @@
|
||||
import { UmbTiptapExtensionApi } from './types.js';
|
||||
import { UmbImage } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export default class UmbTiptapImageExtension extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions() {
|
||||
return [UmbImage.configure({ inline: true })];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { UmbTiptapExtensionApi } from './types.js';
|
||||
import type { ManifestTiptapExtension } from './tiptap-extension.js';
|
||||
import { Link } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
|
||||
|
||||
export const manifest: ManifestTiptapExtension = {
|
||||
type: 'tiptapExtension',
|
||||
kind: 'button',
|
||||
alias: 'Umb.Tiptap.UrlPicker',
|
||||
name: 'URL Picker Tiptap Extension',
|
||||
api: () => import('./urlpicker.extension.js'),
|
||||
meta: {
|
||||
alias: 'umb-link',
|
||||
icon: 'umbraco',
|
||||
label: 'URL picker',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UmbTiptapUrlPickerPlugin extends UmbTiptapExtensionApi {
|
||||
getTiptapExtensions() {
|
||||
return [Link.extend({ openOnClick: false })];
|
||||
}
|
||||
|
||||
override async execute(editor?: Editor) {
|
||||
console.log('umb-link.execute', editor);
|
||||
|
||||
const text = prompt('Enter the text');
|
||||
const url = prompt('Enter the URL');
|
||||
|
||||
if (url && text && editor) {
|
||||
const { from } = editor.state.selection;
|
||||
editor
|
||||
.chain()
|
||||
.focus()
|
||||
.insertContent(text)
|
||||
.setTextSelection({ from: from, to: from + text.length })
|
||||
.setLink({ href: url, target: '_blank' })
|
||||
.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user