UNPKG

coveo-search-ui

Version:

Coveo JavaScript Search Framework

151 lines (134 loc) 5.54 kB
import 'styling/_Backdrop'; import { ModalBox as ModalBoxModule } from '../../ExternalModulesShim'; import { exportGlobally } from '../../GlobalExports'; import { IQueryResult } from '../../rest/QueryResult'; import { $$ } from '../../utils/Dom'; import { Utils } from '../../utils/Utils'; import { Component } from '../Base/Component'; import { IComponentBindings } from '../Base/ComponentBindings'; import { ComponentOptions } from '../Base/ComponentOptions'; import { IFieldOption } from '../Base/IComponentOptions'; import { Initialization } from '../Base/Initialization'; import { IResultsComponentBindings } from '../Base/ResultsComponentBindings'; import { IYouTubeThumbnailOptions, YouTubeThumbnail } from '../YouTube/YouTubeThumbnail'; import { AccessibleButton } from '../../utils/AccessibleButton'; export interface IBackdropOptions { imageUrl?: string; imageField?: IFieldOption; overlayColor?: string; overlayGradient?: boolean; } /** * The Backdrop component renders an image URL (either passed as a direct URL or contained in a result field) as a * background image. It is useful for displaying information in front of a dynamic background image. * * The Backdrop component will automatically initialize components embedded within itself: * * ```html * <div class="CoveoBackdrop" data-image-field="ytthumbnailurl"> * <div class="CoveoFieldValue" data-field="somefield"></div> * </div> * ``` */ export class Backdrop extends Component { static ID = 'Backdrop'; static doExport = () => { exportGlobally({ Backdrop: Backdrop }); }; /** * @componentOptions */ static options: IBackdropOptions = { /** * Specifies a direct URL from which the background image will be sourced. * * Has priority over {@link Backdrop.options.imageField}. */ imageUrl: ComponentOptions.buildStringOption(), /** * Specifies the field from which the background image will be pulled. * * If {@link Backdrop.options.imageUrl} is specified, it will override this option. */ imageField: ComponentOptions.buildFieldOption(), /** * Specifies the color that will be overlaid on top of the background image. * This option needs to be declared as a CSS color. Be sure to use RGBA with an alpha value lower than 1 in order to * be able to see the image behind the overlay color. * * Example value : "`rgba(101, 123, 76, 0.5)`" */ overlayColor: ComponentOptions.buildColorOption(), /** * Specifies whether the overlay color should be instead be rendered as a top-to-bottom gradient from * {@link Backdrop.options.overlayColor} to transparent. * * Default value is `false`. */ overlayGradient: ComponentOptions.buildBooleanOption({ defaultValue: false, depend: 'overlayColor' }) }; /** * Creates a new Backdrop component. * @param element The HTMLElement on which the component will be instantiated. * @param options The options for the Backdrop component. * @param bindings The bindings that the component requires to function normally. If not set, it will be automatically * resolved (with a slower execution time). * @param result The {@link IQueryResult}. */ constructor( public element: HTMLElement, public options?: IBackdropOptions, bindings?: IComponentBindings, public result?: IQueryResult, public _window?: Window, public ModalBox = ModalBoxModule ) { super(element, Backdrop.ID, bindings); this.options = ComponentOptions.initComponentOptions(element, Backdrop, options); this._window = this._window || window; let background = ''; if (this.options.overlayColor) { background += `linear-gradient(${this.options.overlayColor}, ` + (this.options.overlayGradient ? 'rgba(0,0,0,0)' : this.options.overlayColor) + '), '; } const imageSource = this.options.imageUrl || Utils.getFieldValue(result, <string>this.options.imageField); background += `url('${imageSource}') center center`; this.element.style.background = background; this.element.style.backgroundSize = 'cover'; Initialization.automaticallyCreateComponentsInsideResult(element, result); this.configureSpecialBackdropActions(); } private configureSpecialBackdropActions() { // If the current backdrop is used for a youtube thumbnail, we automatically configure a component for this if (Utils.getFieldValue(this.result, 'ytthumbnailurl')) { // We create the element "in memory", but do not append it to the DOM. // We don't want to see a duplicate of the preview for youtube : the backdrop already renders a preview. let thumbnailYouTube = new YouTubeThumbnail( $$('div').el, <IYouTubeThumbnailOptions>{ embed: true }, <IResultsComponentBindings>this.getBindings(), this.result, this.ModalBox, this.element ); new AccessibleButton() .withElement(this.element) .withLabel(this.result.title) .withSelectAction(e => { // Since the backdrop often contain a result link, we must make sure the click did no originate from one. // Otherwise, we might end up opening 2 results at the same time if (!$$(<HTMLElement>e.target).hasClass('CoveoResultLink')) { thumbnailYouTube.openResultLink(); } }) .build(); } } } Initialization.registerAutoCreateComponent(Backdrop);