coveo-search-ui
Version:
Coveo JavaScript Search Framework
151 lines (134 loc) • 5.54 kB
text/typescript
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);