diff --git a/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/components/input-tiptap/tiptap-fixed-menu.element.ts b/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/components/input-tiptap/tiptap-fixed-menu.element.ts index 5b879b5c4a..f276ecc7df 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/components/input-tiptap/tiptap-fixed-menu.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/components/input-tiptap/tiptap-fixed-menu.element.ts @@ -3,6 +3,8 @@ import { css, customElement, html, property } from '@umbraco-cms/backoffice/exte import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { Editor } from '@umbraco-cms/backoffice/external/tiptap'; +import '../toolbar/tiptap-toolbar-dropdown.element.js'; + const elementName = 'umb-tiptap-fixed-menu'; @customElement(elementName) @@ -30,6 +32,7 @@ export class UmbTiptapFixedMenuElement extends UmbLitElement { .filter=${(ext: ManifestTiptapExtension) => !!ext.kind || !!ext.element} .elementProps=${{ editor: this.editor }}> + `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/components/toolbar/tiptap-toolbar-dropdown.element.ts b/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/components/toolbar/tiptap-toolbar-dropdown.element.ts new file mode 100644 index 0000000000..205af34d1e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/rte/tiptap/components/toolbar/tiptap-toolbar-dropdown.element.ts @@ -0,0 +1,145 @@ +import type { ManifestTiptapExtensionButtonKind } from '../../extensions/tiptap-extension.js'; +import type { UmbTiptapToolbarElementApi } from '../../extensions/types.js'; +import type { Editor } from '@umbraco-cms/backoffice/external/tiptap'; +import { + css, + customElement, + html, + ifDefined, + nothing, + repeat, + state, + when, + type TemplateResult, +} from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import type { UUIPopoverContainerElement } from '@umbraco-ui/uui'; + +const elementName = 'umb-tiptap-toolbar-dropdown'; + +type DropdownItem = { + label: string; + nested?: DropdownItem[]; +}; + +@customElement(elementName) +export class UmbTiptapToolbarDropdownElement extends UmbLitElement { + #testDropdownItems: Array = [ + { + label: 'Headings', + nested: [ + { + label: 'Page header', + }, + { + label: 'Section header', + }, + { + label: 'Paragraph header', + nested: [ + { + label: 'Paragraph header 1', + }, + { + label: 'Paragraph header 2', + }, + ], + }, + ], + }, + { + label: 'Blocks', + nested: [ + { + label: 'Paragraph', + }, + ], + }, + { + label: 'Containers', + nested: [ + { + label: 'Quote', + }, + { + label: 'Code', + }, + ], + }, + ]; + + #onMouseEnter = (popoverId: string) => { + const popover = this.shadowRoot?.querySelector(`#${this.#makeAlias(popoverId)}`) as UUIPopoverContainerElement; + if (!popover) return; + popover.showPopover(); + }; + + #onMouseLeave = (popoverId: string) => { + popoverId = popoverId.replace(/\s/g, '-').toLowerCase(); + const popover = this.shadowRoot?.querySelector(`#${this.#makeAlias(popoverId)}`) as UUIPopoverContainerElement; + if (!popover) return; + popover.hidePopover(); + }; + + #makeAlias(label: string) { + return label.replace(/\s/g, '-').toLowerCase(); + } + + #renderItem(item: DropdownItem): TemplateResult { + return html` + + `; + } + + #renderItems(items: Array) { + return html` ${repeat( + items, + (item) => item.label, + (item) => html`${this.#renderItem(item)}`, + )}`; + } + + override render() { + return html` + Text styles + + `; + } + + static override readonly styles = css` + :host { + position: absolute; + top: -67px; + --uui-button-content-align: left; + } + + uui-popover-container { + box-shadow: var(--uui-shadow-depth-3); + } + + .dropdown-item { + background-color: var(--uui-color-surface); + display: flex; + flex-direction: column; + text-wrap: nowrap; + } + `; +} + +export { UmbTiptapToolbarDropdownElement as element }; + +declare global { + interface HTMLElementTagNameMap { + [elementName]: UmbTiptapToolbarDropdownElement; + } +}