UNPKG

@microsoft/sp-webpart-base

Version:

SharePoint Framework support for building web parts

342 lines 14 kB
import { DisplayMode } from '@microsoft/sp-core-library'; import { type IReadonlyTheme } from '@microsoft/sp-component-base'; import BaseWebPart from './BaseWebPart'; import type WebPartContext from './WebPartContext'; import type { IRenderProps } from '@msinternal/sp-renderable-components-base'; import type { ITranspileContext } from './transpile/ITranspileContext'; /** * This abstract class implements the the base functionality for a client-side web part. Every client-side web part * needs to inherit from this class. * * @remarks * Along with the base functionality, this class provides some APIs that can be * used by the web part. These APIs fall in two catagories. * * The first category of APIs provide data and functionality. Example, the web part context (i.e. this.context). This * API should be used to access contextual data relevant to this web part instance. * * The second category of APIs provide a base implementation for the web part lifecycle and can be overridden for an * updated implementation. The render() API is the only API that is mandatory to be implemented/overridden by a web * part. All other life cycle APIs have a base implementation and can be overridden based on the needs of the web part. * Please refer to the documentation of the individual APIs to make the right decision. * * @public */ export default abstract class BaseClientSideWebPart<TProperties extends {}> extends BaseWebPart<TProperties> { /** * {@inheritDoc @microsoft/sp-component-base#BaseComponent.context} */ readonly context: WebPartContext; private _firstTimeRenderPromises; private _renderedOnce; private _logSource; /** * Container width allocated for the web part */ private _width; /** * A timer guard, QOS monitor and resolver delegate for the Async render scenarios. An async render scenario * is one in which the web part is rendering an IFRAME OR fetching async data outside of the onInit API * OR rendering an image tag. In these cases much of the web part rendering lifecycle is controlled by external * factors once the IFRAME is created or the data fetch request is sent OR the image tag is set. The web part * needs to call the renderCompleted API once the final rendering is complete and data is displayed. */ private _asyncRenderGuardTimer; private _asyncRenderQosMonitor; private _renderPromiseResolver; private _renderPromiseRejecter; private _asyncRenderCompleteCalled; private _asyncRenderCompleteDidUpdate; /** * Whether the web part is visible. */ private _isVisible; /** * Theme Provider to handle theme changes */ private _internalThemeProvider; /** * Current theme */ private _internalThemeVariant; private _internalIsDisposing; /** * Time when syncRender is finished. */ private _syncRenderTime; /** * Constructor for the BaseClientSideWebPart class. * * @remarks * It is highly recommended that the web part use the `onInit()` API to perform any web part specific * initialization. Most of the web part features like this.context and `this.properties` are not * available to be used before the the `onInit()` part of the web part loading lifecycle. */ constructor(); /** * This property is a pointer to the root DOM element of the web part. This is a DIV element and contains the whole * DOM subtree of the web part. * * @readonly */ protected get domElement(): HTMLElement; /** * This property returns the width of the container for the web part. * @returns Width (in pixels) of the container for the web part. * * @remarks * Web parts should utilize this property to perform operations such as any conditional styling of components * based on the initial available width for the web part. * @readonly */ protected get width(): number; /** * This property indicates whether the web part has been rendered once or not. After the first time rendering, * the value of this property is always true until a full re-render of the web part happens. * * @readonly */ protected get renderedOnce(): boolean; /** * This property indicates whether the web part was rendered from the persisted data (serialized state from the * last time that the web part was saved) or not. * * @remarks * Example: When web part is added for the first time using toolbox then the value is false. * * @readonly */ protected get renderedFromPersistedData(): boolean; /** * This property indicates whether a web part can open a popup on initial render. * * @remarks * In some environments the host * re-renders the web parts frequently, and therefore opening popups during render will cause popups to open * repeatedly, which is a poor user experience. As an example, the classic SharePoint pages perform postbacks * causing the page to re-render on all button clicks. * * If a web part needs to open a popup on render, it should use this API before opening the popup. If this API * returns false, the web part should not open popup on initial render. Some web parts that open popups during * render are the document embed web part that pops up the file picker on initial render, embedded video web part * that pops up the PropertyPane on initial render. * * @readonly */ protected get canOpenPopupOnRender(): boolean; /** * Indicates whether the web part is rendering in Async mode. * * @remarks * If the web part overrides this field to return true, then it needs to call renderCompleted API * after the web part rendering is complete. * * The default value is false. * * @virtual */ protected get isRenderAsync(): boolean; /** * API to hide or show the web part. It tells the host whether the web part is supposed to be hidden. * The host might decide to remove or recover the side effects that are not rendered by web part implementation. * @remarks * This does NOT work in edit mode. * * @alpha */ protected get isVisible(): boolean; protected set isVisible(value: boolean); /** * If the web part is being disposed * @internal */ get _isDisposing(): boolean; /** * Internal API to update the webpart upon a resize of the DOM window's viewport * * See onAfterResize for more details. * * @internal */ _internalOnAfterResize(): void; /** * Internal API for the first time render of the web part. The purpose of this API is to enforce initialization steps * before the actual render is called. This API is called only once during the web part loading lifecycle. * * @returns The promise indicates the render loop is finished (success or fail). * * @internal */ _internalFirstTimeRender(): Promise<number | void>; /** * @internal */ _internalSetDisplayMode(newDisplayMode: DisplayMode): void; /** * Internal API for the web part transpile invoke * * @returns Transpile result * * @internal */ _internalTranspile(context: ITranspileContext): IRenderProps[]; /** * @internal * {@inheritDoc BaseWebPart._internalInitialize} */ _internalInitialize(webPartContext: WebPartContext, addedFromPersistedData: boolean, mode: DisplayMode): void; /** * Internal API to dispose the web part. * * See onDispose for more details. * * @internal */ _internalDispose(): void; /** * This API should be called to find the render props used to transpile the webpart * @param context - transpile context * * @internal */ protected onTranspile(context: ITranspileContext): IRenderProps[]; /** * This API is called to render the web part. There is no base implementation of this API and the web part is * required to override this API. */ protected abstract render(): void; /** * This API should be called by web parts that perform Async rendering. Those web part are required to override * the isRenderAsync API and return true. One such example is web parts that render content in an IFrame. The * web part initiates the IFrame rendering in the `render()` API but the actual rendering is complete only after * the iframe loading completes. * * @param error - error object indicating async render has completed with an error * @param didUpdate - used to override end performance time with sync render time */ protected renderCompleted(error?: Error, didUpdate?: boolean): void; /** * This event method is called when the display mode of a web part is changed. * * @remarks * The default implementation of this API calls * the web part render method to re-render the web part with the new display mode. If a web part developer does not * want a full re-render to happen on display mode change, they can override this API and perform specific updates * to the web part DOM to switch its display mode. * * If the web part is initialized or re-initialized when switching to a different display mode then this * lifecycle method is not called. Example: SharePoint Site Page. * * @param oldDisplayMode - The old display mode. * * @virtual */ protected onDisplayModeChanged(oldDisplayMode: DisplayMode): void; /** * This API should be used to refresh the contents of the PropertyPane. * * @remarks * This API is called at the end of the web part lifecycle on a page. It should be used to dispose any local * resources (i.e. DOM elements) that the web part is holding onto. This API is expected to be called in scenarios * like page navigation i.e. the host is transitioning from one page to another and disposes the page that is being * transitioned out. * * @virtual */ protected onDispose(): void; /** * This API is invoked when the web part container dom element width is changed, e.g. when the browser * browser window is resized and when the property pane is toggled open/closed. * * @param newWidth - Width (in pixels) of the container for the web part after the resize event. * @remarks * Web parts should utilize this method to perform operations such as potentially re-rendering components * based on the new available width for the web part. * * @virtual */ protected onAfterResize(newWidth: number): void; /** * This API is called when a theme is initialized or changed on the page or for the current section. * @param theme - New theme for the page or section * @remarks * Developers sould not call render in overridden method. It can lead to unpredicted re-flow of the web part. * render will be called from the base class when needed. * * @virtual */ protected onThemeChanged(theme: IReadonlyTheme | undefined): void; /** * This API should be used to render an error message in the web part display area. Also logs the error message * using the trace logger. * * @param error - An error object containing the error message to render. */ protected renderError(error: Error): void; /** * This API should be used to clear the error message from the web part display area. */ protected clearError(): void; /** * Internal API to trigger a refresh to the WebPart's visual rendition. * In this implementation of the BaseWebPart class we call the render API. * * @internal */ protected _refresh(): void; /** * Internal API triggered by a dynamic property's callback. * In this implementation of the BaseWebPart class we call the render API, only if rendered once. * * @internal */ protected _dynamicPropertyRefresh(): void; /** * Waits for all render promises to resolve before disposing. */ private _disposeAfterRenderPromises; /** * @returns extends base width cache key with additional info to minimize reflows. * Otherwise if base cache key does not exist return undefined. * @internal */ private _getExtendedWidthCacheKey; /** * The actual initialization and rendering of the Web part starts when it is close enough * to the Viewport */ private _onInViewport; /** * Wraps render to ensure any type of rendering has access to the latest context * to provide the most accurate accessible info to screen readers. */ private _renderWithAccessibleTitle; /** * Start async guard timer. This timer is to help avoid losing performance markers for a web part * that renders asynchronously but does not call the `renderCompleted` API; */ private _startAsyncRenderGuardTimer; /** * Render completed. * * @param didUpdate - used to override end performance time with sync render time. */ private _renderCompleted; private _handleAsyncRenderFailed; /** * Async render timed out. Log error information and */ private _asyncRenderTimeout; private _logAsyncRenderError; private _clearAsyncRenderGuardTimer; /** * This is called for every web part whether sync or async once rendering is completed. * * @param error - error object indicating asycn render has completed with an error * @param didUpdate - used to override end performance time with sync render time. */ private _resolveOrRejectOnRenderPromise; private _clearRenderPromises; private _internalHandleThemeChangedEvent; } //# sourceMappingURL=BaseClientSideWebPart.d.ts.map