/** * ------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. * See License in the project root for license information. * ------------------------------------------------------------------------------------------- */ import { property, state } from 'lit/decorators.js'; import { html, PropertyValueMap, PropertyValues, TemplateResult } from 'lit'; import { equals } from '../utils/equals'; import { MgtBaseComponent } from './baseComponent'; import { TemplateContext } from '../utils/TemplateContext'; import { TemplateHelper } from '../utils/TemplateHelper'; /** * Lookup for rendered component templates and contexts by slot name. */ export type RenderedTemplates = Record< string, { /** * Reference to the data context used to render the slot. */ context: Record; /** * Reference to the rendered DOM element corresponding to the slot. */ slot: HTMLElement; } >; export interface TemplateRenderedData { templateType: string; context: Record; element: HTMLElement; } export type OrderedHtmlTemplate = HTMLTemplateElement & { templateOrder: number }; /** * An abstract class that defines a templatable web component * * @export * @abstract * @class MgtTemplatedComponent * @extends {MgtBaseComponent} * @deprecated Use MgtTemplatedTaskComponent instead * * @fires {CustomEvent} templateRendered - fires when a template is rendered */ export abstract class MgtTemplatedComponent extends MgtBaseComponent { /** * Additional data context to be used in template binding * Use this to add event listeners or value converters * * @type {MgtElement.TemplateContext} * @memberof MgtTemplatedComponent */ @property({ attribute: false }) public templateContext: TemplateContext; /** * * Gets or sets the error (if any) of the request * * @type object * @memberof MgtSearchResults */ @state() protected error: object; /** * Holds all templates defined by developer * * @protected * @memberof MgtTemplatedComponent */ protected templates: Record = {}; private _renderedSlots = false; private _renderedTemplates: RenderedTemplates = {}; private _slotNamesAddedDuringRender = []; constructor() { super(); this.templateContext = this.templateContext || {}; } /** * Updates the element. This method reflects property values to attributes. * It can be overridden to render and keep updated element DOM. * Setting properties inside this method will *not* trigger * another update. * * * @param _changedProperties Map of changed properties with old values */ protected update(changedProperties: PropertyValueMap | Map) { this.templates = this.getTemplates(); this._slotNamesAddedDuringRender = []; super.update(changedProperties); } /** * Invoked whenever the element is updated. Implement to perform * post-updating tasks via DOM APIs, for example, focusing an element. * * Setting properties inside this method will trigger the element to update * again after this update cycle completes. * * * @param changedProperties Map of changed properties with old values */ protected updated(changedProperties: PropertyValues) { super.updated(changedProperties); this.removeUnusedSlottedElements(); } /** * Render a