UNPKG

coveo-search-ui

Version:

Coveo JavaScript Search Framework

187 lines (165 loc) 7.27 kB
import 'styling/_Searchbox'; import { exportGlobally } from '../../GlobalExports'; import { $$ } from '../../utils/Dom'; import { SVGDom } from '../../utils/SVGDom'; import { SVGIcons } from '../../utils/SVGIcons'; import { SearchBoxResize } from '../../utils/SearchBoxResize'; import { Component } from '../Base/Component'; import { IComponentBindings } from '../Base/ComponentBindings'; import { ComponentOptions } from '../Base/ComponentOptions'; import { Initialization } from '../Base/Initialization'; import { IOmniboxOptions, Omnibox } from '../Omnibox/Omnibox'; import { Querybox } from '../Querybox/Querybox'; import { SearchButton } from '../SearchButton/SearchButton'; import { each, extend } from 'underscore'; export interface ISearchboxOptions extends IOmniboxOptions { addSearchButton?: boolean; enableOmnibox?: boolean; height?: number; } /** * The `Searchbox` component allows you to conveniently instantiate two components which end users frequently use to * enter and submit queries. * * This component attaches itself to a `div` element and takes care of instantiating either a * [`Querybox`]{@link Querybox} or an [`Omnibox`]{@link Omnibox} component (see the * [`enableOmnibox`]{@link Searchbox.options.enableOmnibox} option). Optionally, the `Searchbox` can also instantiate a * [`SearchButton`]{@link SearchButton} component, and append it inside the same `div` (see the * [`addSearchButton`]{@link Searchbox.options.addSearchButton} option). */ export class Searchbox extends Component { static ID = 'Searchbox'; static parent = Omnibox; static doExport = () => { exportGlobally({ Searchbox: Searchbox, SearchButton: SearchButton, Omnibox: Omnibox, Querybox: Querybox }); }; /** * Possible options for the {@link Searchbox} * @componentOptions */ static options: ISearchboxOptions = { /** * Specifies whether to instantiate a [`SearchButton`]{@link SearchButton} component. * * Default value is `true`. */ addSearchButton: ComponentOptions.buildBooleanOption({ defaultValue: true }), /** * A custom height for the search box (in pixels). * * Note: Avoid setting this option if you want to modify the search box styling through custom CSS. * * Minimum value is `25` * * Default behavior: The most specific CSS rules targeting HTML elements generated by the Searchbox component are used * (e.g., if you are only using the default CoveoFullSearch.css stylesheet with no further styling customizations, * the search box height will be set to 50 pixels by default). * * @availablesince [July 2019 Release (v2.6459)](https://docs.coveo.com/en/2938/) */ height: ComponentOptions.buildNumberOption({ min: 25 }), /** * Specifies whether to instantiate an [`Omnibox`]{@link Omnibox} component. * * When this option is `false`, the `Searchbox` instantiates a [`Querybox`]{@link Querybox} component instead. * * **Note:** * > You can use configuration options specific to the component you choose to instantiate with the `Searchbox`. * * **Examples:** * * In this first case, the `Searchbox` instantiates a `Querybox` component. You can configure this `Querybox` * instance using any of the `Querybox` component options, such as * [`triggerQueryOnClear`]{@link Querybox.options.triggerQueryOnClear}. * ```html * <div class='CoveoSearchbox' data-trigger-query-on-clear='true'></div> * ``` * * In this second case, the `Searchbox` instantiates an `Omnibox` component. You can configure this `Omnibox` * instance using any of the `Omnibox` component options, such as * [`placeholder`]{@link Omnibox.options.placeholder}. * Moreover, since the `Omnibox` component inherits all of the `Querybox` component options, the * `data-trigger-query-on-clear` option from the previous example would also work on this `Omnibox` instance. * ```html * <div class='CoveoSearchbox' data-enable-omnibox='true' data-placeholder='Please enter a query'></div> * ``` * * Default value is `true`. */ enableOmnibox: ComponentOptions.buildBooleanOption({ defaultValue: true }) }; /** * The [`SearchButton`]{@link SearchButton} component instance. */ public searchButton: SearchButton; /** * The component instance which allows end users to input queries. * * Can be either a [`Querybox`]{@link Querybox} or an [`Omnibox`]{@link Omnibox} component, depending on the value of * [`enableOmnibox`]{@link Searchbox.options.enableOmnibox}. */ public searchbox: Querybox | Omnibox; /** * Creates a new `Searchbox` component. Creates a new `Coveo.Magicbox` instance and wraps magic box methods (`onblur`, * `onsubmit`, etc.). Binds event on `buildingQuery` and on redirection (for standalone box). * @param element The HTMLElement on which to instantiate the component. This cannot be an HTMLInputElement for * technical reasons. * @param options The options for the `Searchbox component`. These will merge with the options from the component set * directly on the `HTMLElement`. * @param bindings The bindings that the component requires to function normally. If not set, these will be * automatically resolved (with a slower execution time). */ constructor(public element: HTMLElement, public options?: ISearchboxOptions, public bindings?: IComponentBindings) { super(element, Searchbox.ID, bindings); this.options = ComponentOptions.initComponentOptions(element, Searchbox, options); if (this.options.inline) { $$(element).addClass('coveo-inline'); } this.initSearchBox(); this.initSearchButton(); this.applyMagicBoxIcon(); this.applyCustomHeight(); } private initSearchBox() { const div = document.createElement('div'); this.element.appendChild(div); if (this.options.enableOmnibox) { this.searchbox = new Omnibox(div, this.options, this.bindings); } else { this.searchbox = new Querybox(div, this.options, this.bindings); } } private initSearchButton() { if (!this.options.addSearchButton) { return; } const anchor = $$('a'); this.element.appendChild(anchor.el); this.searchButton = new SearchButton(anchor.el, { searchbox: this.searchbox }, this.bindings); } private applyMagicBoxIcon() { const magicBoxIcon = $$(this.element).find('.magic-box-icon'); magicBoxIcon.innerHTML = SVGIcons.icons.mainClear; SVGDom.addClassToSVGInContainer(magicBoxIcon, 'magic-box-clear-svg'); } private applyCustomHeight() { if (!this.options.height) { return; } $$(this.element).addClass('coveo-custom-height'); SearchBoxResize.resize(this.element, this.options.height); } } Searchbox.options = { ...Searchbox.options, ...Omnibox.options, ...Querybox.options }; // Only parse omnibox option if omnibox is enabled each(<any>Searchbox.options, (value, key: string) => { if (key in Omnibox.options && !(key in Querybox.options)) { Searchbox.options[key] = extend({ depend: 'enableOmnibox' }, value); } }); Initialization.registerAutoCreateComponent(Searchbox);