UNPKG

5.16 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(
42 this.options.selectorClearIcon
43 );
44 const input = this.element.querySelector(this.options.selectorSearchInput);
45 if (!input) {
46 throw new Error('Cannot find the search input.');
47 }
48
49 if (closeIcon) {
50 this.manage(
51 on(closeIcon, 'click', () => {
52 svgToggleClass(closeIcon, this.options.classClearHidden, true);
53 input.value = '';
54 input.focus();
55 })
56 );
57 }
58
59 this.manage(
60 on(this.element, 'click', (evt) => {
61 const toggleItem = eventMatches(
62 evt,
63 this.options.selectorIconContainer
64 );
65 if (toggleItem) this.toggleLayout(toggleItem);
66 })
67 );
68
69 this.manage(
70 on(input, 'input', (evt) => {
71 if (closeIcon) this.showClear(evt.target.value, closeIcon);
72 })
73 );
74 }
75
76 /**
77 * Toggles between the grid and list layout.
78 * @param {HTMLElement} element The element contining the layout toggle.
79 */
80 toggleLayout(element) {
81 toArray(element.querySelectorAll(this.options.selectorSearchView)).forEach(
82 (item) => {
83 item.classList.toggle(this.options.classLayoutHidden);
84 }
85 );
86 }
87
88 /**
89 * Toggles the clear icon visibility
90 * @param {HTMLElement} value The element serving as the search input.
91 * @param {HTMLElement} icon The element serving as close icon.
92 */
93 showClear(value, icon) {
94 svgToggleClass(icon, this.options.classClearHidden, value.length === 0);
95 }
96
97 /**
98 * The component options.
99 * If `options` is specified in the constructor,
100 * {@linkcode Search.create .create()}, or {@linkcode Search.init .init()},
101 * properties in this object are overriden for the instance being created
102 * and how {@linkcode Search.init .init()} works.
103 * @member Search.options
104 * @type {object}
105 * @property {string} [options.selectorInit]
106 * The selector to find search UIs with options.
107 * @property {string} [options.selectorSearchView]
108 * The selector to find the search view icon containers.
109 * @property {string} [options.selectorSearchInput]
110 * The selector to find the search input.
111 * @property {string} [options.selectorClearIcon]
112 * The selector for the clear icon that clears the search box.
113 * @property {string} [options.selectorIconContainer] The data attribute selector for the icon layout container.
114 * @property {string} [options.classClearHidden] The class used to hide the clear icon.
115 * @property {string} [options.classLayoutHidden] The class used to hide nonselected layout view.
116 */
117 static get options() {
118 const { prefix } = settings;
119 return {
120 selectorInit: '[data-search]',
121 selectorSearchView: '[data-search-view]',
122 selectorSearchInput: `.${prefix}--search-input`,
123 selectorClearIcon: `.${prefix}--search-close`,
124 selectorIconContainer: `.${prefix}--search-button[data-search-toggle]`,
125 classClearHidden: `${prefix}--search-close--hidden`,
126 classLayoutHidden: `${prefix}--search-view--hidden`,
127 };
128 }
129
130 /**
131 * The map associating DOM element and search instance.
132 * @member Search.components
133 * @type {WeakMap}
134 */
135 static components /* #__PURE_CLASS_PROPERTY__ */ = new WeakMap();
136}
137
138export default Search;