UNPKG

5.09 kBJavaScriptView Raw
1/**
2 * Copyright IBM Corp. 2016, 2018
3 *
4 * This source code is licensed under the Apache-2.0 license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8import settings from '../../globals/js/settings';
9import mixin from '../../globals/js/misc/mixin';
10import createComponent from '../../globals/js/mixins/create-component';
11import initComponentBySearch from '../../globals/js/mixins/init-component-by-search';
12import handles from '../../globals/js/mixins/handles';
13import eventMatches from '../../globals/js/misc/event-matches';
14import on from '../../globals/js/misc/on';
15import svgToggleClass from '../../globals/js/misc/svg-toggle-class';
16
17const toArray = arrayLike => Array.prototype.slice.call(arrayLike);
18
19class Search extends mixin(createComponent, initComponentBySearch, handles) {
20 /**
21 * Search with Options.
22 * @extends CreateComponent
23 * @extends InitComponentBySearch
24 * @extends Handles
25 * @param {HTMLElement} element The element working as the search component.
26 * @param {Object} [options] The component options
27 * @property {string} [options.selectorInit]
28 * The selector to find search UIs with options.
29 * @property {string} [options.selectorSearchView]
30 * The selector to find the search view icon containers.
31 * @property {string} [options.selectorSearchInput]
32 * The selector to find the search input.
33 * @property {string} [options.selectorClearIcon]
34 * The selector for the clear icon that clears the search box.
35 * @property {string} [options.selectorIconContainer] The data attribute selector for the icon layout container.
36 * @property {string} [options.classClearHidden] The class used to hide the clear icon.
37 * @property {string} [options.classLayoutHidden] The class used to hide nonselected layout view.
38 */
39 constructor(element, options) {
40 super(element, options);
41 const closeIcon = this.element.querySelector(this.options.selectorClearIcon);
42 const input = this.element.querySelector(this.options.selectorSearchInput);
43 if (!input) {
44 throw new Error('Cannot find the search input.');
45 }
46
47 if (closeIcon) {
48 this.manage(
49 on(closeIcon, 'click', () => {
50 svgToggleClass(closeIcon, this.options.classClearHidden, true);
51 input.value = '';
52 input.focus();
53 })
54 );
55 }
56
57 this.manage(
58 on(this.element, 'click', evt => {
59 const toggleItem = eventMatches(evt, this.options.selectorIconContainer);
60 if (toggleItem) this.toggleLayout(toggleItem);
61 })
62 );
63
64 this.manage(
65 on(input, 'input', evt => {
66 if (closeIcon) this.showClear(evt.target.value, closeIcon);
67 })
68 );
69 }
70
71 /**
72 * Toggles between the grid and list layout.
73 * @param {HTMLElement} element The element contining the layout toggle.
74 */
75 toggleLayout(element) {
76 toArray(element.querySelectorAll(this.options.selectorSearchView)).forEach(item => {
77 item.classList.toggle(this.options.classLayoutHidden);
78 });
79 }
80
81 /**
82 * Toggles the clear icon visibility
83 * @param {HTMLElement} value The element serving as the search input.
84 * @param {HTMLElement} icon The element serving as close icon.
85 */
86 showClear(value, icon) {
87 svgToggleClass(icon, this.options.classClearHidden, value.length === 0);
88 }
89
90 /**
91 * The component options.
92 * If `options` is specified in the constructor,
93 * {@linkcode Search.create .create()}, or {@linkcode Search.init .init()},
94 * properties in this object are overriden for the instance being created
95 * and how {@linkcode Search.init .init()} works.
96 * @member Search.options
97 * @type {Object}
98 * @property {string} [options.selectorInit]
99 * The selector to find search UIs with options.
100 * @property {string} [options.selectorSearchView]
101 * The selector to find the search view icon containers.
102 * @property {string} [options.selectorSearchInput]
103 * The selector to find the search input.
104 * @property {string} [options.selectorClearIcon]
105 * The selector for the clear icon that clears the search box.
106 * @property {string} [options.selectorIconContainer] The data attribute selector for the icon layout container.
107 * @property {string} [options.classClearHidden] The class used to hide the clear icon.
108 * @property {string} [options.classLayoutHidden] The class used to hide nonselected layout view.
109 */
110 static get options() {
111 const { prefix } = settings;
112 return {
113 selectorInit: '[data-search]',
114 selectorSearchView: '[data-search-view]',
115 selectorSearchInput: `.${prefix}--search-input`,
116 selectorClearIcon: `.${prefix}--search-close`,
117 selectorIconContainer: `.${prefix}--search-button[data-search-toggle]`,
118 classClearHidden: `${prefix}--search-close--hidden`,
119 classLayoutHidden: `${prefix}--search-view--hidden`,
120 };
121 }
122
123 /**
124 * The map associating DOM element and search instance.
125 * @member Search.components
126 * @type {WeakMap}
127 */
128 static components /* #__PURE_CLASS_PROPERTY__ */ = new WeakMap();
129}
130
131export default Search;