UNPKG

@kontent-ai/smart-link

Version:

Kontent.ai Smart Link SDK allowing to automatically inject [smart links](https://docs.kontent.ai/tutorials/develop-apps/build-strong-foundation/set-up-editing-from-preview#a-using-smart-links) to Kontent.ai according to manually specified [HTML data attri

186 lines (179 loc) 6.5 kB
import { ButtonType } from './KSLButtonElement'; import { IconName } from './KSLIconElement'; import { assert } from '../utils/assert'; import { ElementPositionOffset, KSLPositionedElement } from './abstract/KSLPositionedElement'; import { KSLContainerElement } from './KSLContainerElement'; import { createTemplateForCustomElement } from '../utils/domElement'; import { logWarn } from '../lib/Logger'; import { Colors } from './tokens/colors'; import { Shadows } from './tokens/shadows'; import { BaseZIndex } from './tokens/zIndex'; import { getHighlightTypeForElement, HighlightType } from '../utils/dataAttributes/elementHighlight'; import { parseEditButtonDataAttributes } from '../utils/dataAttributes/parser'; const templateHTML = ` <style> :host, :host * { box-sizing: border-box; } :host { display: block; position: absolute; pointer-events: none; touch-action: none; min-height: 40px; min-width: 40px; width: 100%; height: 100%; border: 2px dashed; border-color: var(--ksl-color-primary-transparent, ${Colors.PrimaryTransparent}); border-radius: 5px; } :host([hidden]) { display: none; } :host(:hover), :host([selected]) { border-color: var(--ksl-color-primary, ${Colors.Primary}); z-index: calc(var(--ksl-z-index, ${BaseZIndex}) + 10); } :host(:focus) { outline: none; } .ksl-highlight__toolbar { position: absolute; top: 0; right: 0; display: flex; flex-direction: row; justify-content: center; align-items: center; pointer-events: all; touch-action: auto; min-height: 40px; max-height: 40px; border-radius: 8px; background-color: var(--ksl-color-background-default, ${Colors.BackgroundDefault}); z-index: var(--ksl-z-index, ${BaseZIndex}); padding: 8px; box-shadow: var(--ksl-shadow-default, ${Shadows.Default}); } .ksl-highlight__toolbar:hover { z-index: calc(var(--ksl-z-index, ${BaseZIndex}) + 10); } .ksl-highlight__toolbar-button + .ksl-highlight__toolbar-button { margin-left: 4px; } </style> <div id="ksl-toolbar" class="ksl-highlight__toolbar"> <ksl-button id="ksl-edit" class="ksl-highlight__toolbar-button" type="${ButtonType.Quinary}" tooltip-position="${ElementPositionOffset.BottomEnd}" > <ksl-icon icon-name="${IconName.Edit}" /> </ksl-button> </div> `; export class KSLHighlightElement extends KSLPositionedElement { static get is() { return 'ksl-highlight'; } get type() { return getHighlightTypeForElement(this.targetRef); } get selected() { return this.hasAttribute('selected'); } set selected(value) { this.updateAttribute('selected', value); } editButtonRef; constructor() { super(); assert(this.shadowRoot, 'Shadow root must be always accessible in "open" mode.'); this.editButtonRef = this.shadowRoot.querySelector('#ksl-edit'); } static initializeTemplate() { return createTemplateForCustomElement(templateHTML); } static getEditButtonTooltip(type) { switch (type) { case HighlightType.Element: return 'Edit element'; case HighlightType.ContentComponent: return 'Edit component'; case HighlightType.ContentItem: return 'Edit item'; default: return 'Edit'; } } connectedCallback() { super.connectedCallback(); this.editButtonRef.addEventListener('click', this.handleEditButtonClick); } disconnectedCallback() { super.connectedCallback(); this.editButtonRef.removeEventListener('click', this.handleEditButtonClick); this.unregisterTargetNodeListeners(); } attachTo = (node) => { this.unregisterTargetNodeListeners(); super.attachTo(node); const type = this.type; this.hidden = type === HighlightType.None; this.editButtonRef.tooltipMessage = KSLHighlightElement.getEditButtonTooltip(type); if (this.targetRef) { this.targetRef.addEventListener('mousemove', this.handleTargetNodeMouseEnter); this.targetRef.addEventListener('mouseleave', this.handleTargetNodeMouseLeave); this.targetRef.addEventListener('click', this.handleEditButtonClick); } }; adjustPosition = () => { if (!this.targetRef || !this.offsetParent) { return; } if (!(this.offsetParent instanceof KSLContainerElement)) { logWarn('KSLHighlightElement: should be located inside KSLContainerElement to be positioned properly.'); } const offsetParentRect = this.offsetParent.getBoundingClientRect(); const targetRect = this.targetRef.getBoundingClientRect(); this.style.top = `${targetRect.top - offsetParentRect.top}px`; this.style.left = `${targetRect.left - offsetParentRect.left}px`; this.style.width = `${targetRect.width}px`; this.style.height = `${targetRect.height}px`; }; unregisterTargetNodeListeners = () => { if (this.targetRef) { this.targetRef.removeEventListener('mousemove', this.handleTargetNodeMouseEnter); this.targetRef.removeEventListener('mouseleave', this.handleTargetNodeMouseLeave); this.targetRef.removeEventListener('click', this.handleEditButtonClick); } }; handleTargetNodeMouseEnter = () => { this.selected = true; }; handleTargetNodeMouseLeave = () => { this.selected = false; }; handleEditButtonClick = (event) => { assert(this.targetRef, 'Target node is not set for this highlight.'); event.preventDefault(); event.stopPropagation(); const dataAttributes = parseEditButtonDataAttributes(this.targetRef); this.dispatchEditEvent(dataAttributes); }; dispatchEditEvent = (data) => { assert(this.targetRef, 'Target node is not set for this highlight element.'); const customEvent = new CustomEvent('ksl:highlight:edit', { detail: { data, targetNode: this.targetRef, }, }); this.dispatchEvent(customEvent); }; } //# sourceMappingURL=KSLHighlightElement.js.map