UNPKG

4.49 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';
15
16export default class TextInput extends mixin(createComponent, initComponentBySearch, handles) {
17 /**
18 * Text Input.
19 * @extends CreateComponent
20 * @extends InitComponentBySearch
21 * @extends Handles
22 * @param {HTMLElement} element - The element functioning as a text field.
23 */
24 constructor(element, options) {
25 super(element, options);
26 this.manage(
27 on(this.element, 'click', event => {
28 const toggleVisibilityButton = eventMatches(event, this.options.selectorPasswordVisibilityButton);
29 if (toggleVisibilityButton) {
30 this._toggle({ element, button: toggleVisibilityButton });
31 }
32 })
33 );
34 }
35
36 /**
37 *
38 * @param {Object} obj - Object containing selectors and visibility status
39 * @param {HTMLElement} obj.iconVisibilityOn - The element functioning as
40 * the SVG icon for visibility on
41 * @param {HTMLElement} obj.iconVisibilityOff - The element functioning as
42 * the SVG icon for visibility off
43 * @param {boolean} obj.passwordIsVisible - The visibility of the password in the
44 * input field
45 */
46 _setIconVisibility = ({ iconVisibilityOn, iconVisibilityOff, passwordIsVisible, selectorPasswordVisibilityButton }) => {
47 if (passwordIsVisible) {
48 iconVisibilityOn.setAttribute('hidden', true);
49 iconVisibilityOff.removeAttribute('hidden');
50 selectorPasswordVisibilityButton.setAttribute('aria-label', 'Hide password');
51 return;
52 }
53 iconVisibilityOn.removeAttribute('hidden');
54 iconVisibilityOff.setAttribute('hidden', true);
55 selectorPasswordVisibilityButton.setAttribute('aria-label', 'Show password');
56 };
57
58 /**
59 * Toggles the visibility of the password in the input field and changes the
60 * SVG icon indicating password visibility
61 * @param {Object} obj - The elements that can change in the component
62 * @param {HTMLElement} obj.element - The element functioning as a text field
63 * @param {HTMLElement} obj.button - The button toggling password visibility
64 */
65 _toggle = ({ element, button }) => {
66 // toggle action must come before querying the classList
67 element.classList.toggle(this.options.passwordIsVisible);
68 const passwordIsVisible = element.classList.contains(this.options.passwordIsVisible);
69 const iconVisibilityOn = button.querySelector(this.options.svgIconVisibilityOn);
70 const iconVisibilityOff = button.querySelector(this.options.svgIconVisibilityOff);
71 const input = element.querySelector(this.options.selectorPasswordField);
72 const selectorPasswordVisibilityButton = element.querySelector(this.options.selectorPasswordVisibilityButton);
73 this._setIconVisibility({
74 iconVisibilityOn,
75 iconVisibilityOff,
76 passwordIsVisible,
77 selectorPasswordVisibilityButton,
78 });
79 input.type = passwordIsVisible ? 'text' : 'password';
80 };
81
82 /**
83 * The component options.
84 *
85 * If `options` is specified in the constructor,
86 * {@linkcode TextInput.create .create()},
87 * or {@linkcode TextInput.init .init()},
88 * properties in this object are overriden for the instance being
89 * created and how {@linkcode TextInput.init .init()} works.
90 * @property {string} selectorInit The CSS selector to find text input UIs.
91 */
92 static get options() {
93 const { prefix } = settings;
94 return {
95 selectorInit: '[data-text-input]',
96 selectorPasswordField: `.${prefix}--text-input[data-toggle-password-visibility]`,
97 selectorPasswordVisibilityButton: `.${prefix}--text-input--password__visibility`,
98 passwordIsVisible: `${prefix}--text-input--password-visible`,
99 svgIconVisibilityOn: `svg.${prefix}--icon--visibility-on`,
100 svgIconVisibilityOff: `svg.${prefix}--icon--visibility-off`,
101 };
102 }
103
104 /**
105 * The map associating DOM element and text input UI instance.
106 * @type {WeakMap}
107 */
108 static components /* #__PURE_CLASS_PROPERTY__ */ = new WeakMap();
109}