UNPKG

@govbr-ds/core

Version:

Padrão Digital de Governo

209 lines (198 loc) 6.03 kB
/** Classe para instanciar um objeto BRInput*/ class BRInput { /** * Instancia do objeto * @param {string} name - Nome do componente em minúsculo * @param {object} component - Objeto referenciando a raiz do componente DOM */ constructor(name, component) { this.name = name this.component = component this._currentFocus = -1 this._setBehavior() } /** * Define comportamentos do componente * @private */ _setBehavior() { this._setPasswordViewBehavior() this._setAutocompleteBehavior() } /** * Define comportamentos do componente * @private */ _setPasswordViewBehavior() { for (const inputPassword of this.component.querySelectorAll('input[type="password"]')) { if (!inputPassword.disabled) { for (const buttonIcon of inputPassword.parentNode.querySelectorAll('.br-button')) { buttonIcon.addEventListener( 'click', (event) => { this._toggleShowPassword(event) }, false ) } } } } /** * Define comportamentos do componente * @private * @param {event} event - referência ao elemento que dispara a ação */ _toggleShowPassword(event) { for (const icon of event.currentTarget.querySelectorAll('.fas')) { if (icon.classList.contains('fa-eye')) { icon.classList.remove('fa-eye') icon.classList.add('fa-eye-slash') for (const input of this.component.querySelectorAll('input[type="password"]')) { input.setAttribute('type', 'text') } for (const button of this.component.querySelectorAll('button[aria-label="Exibir senha"]')) { button.setAttribute('aria-checked', 'true') } } else if (icon.classList.contains('fa-eye-slash')) { icon.classList.remove('fa-eye-slash') icon.classList.add('fa-eye') for (const input of this.component.querySelectorAll('input[type="text"]')) { input.setAttribute('type', 'password') } for (const button of this.component.querySelectorAll('button[aria-label="Exibir senha"]')) { button.setAttribute('aria-checked', 'false') } } } } /** * Define comportamentos do componente * @private */ _setAutocompleteBehavior() { for (const inputAutocomplete of this.component.querySelectorAll('input.search-autocomplete')) { inputAutocomplete.addEventListener( 'input', (event) => { this._clearSearchItems() this._buildSearchItems(event.currentTarget) }, false ) inputAutocomplete.addEventListener( 'keydown', (event) => { this._handleArrowKeys(event) }, false ) } } /** * Monta os items de busca para o elemento input * @private * @param {object} element - referencia ao elemento input */ _buildSearchItems(element) { const searchList = window.document.createElement('div') searchList.setAttribute('class', 'search-items') this.component.appendChild(searchList) if (element.value !== '') { for (const data of this.dataList) { if (data.substr(0, element.value.length).toUpperCase() === element.value.toUpperCase()) { const item = window.document.createElement('div') item.innerHTML = `<strong>${data.substr(0, element.value.length)}</strong>` item.innerHTML += data.substr(element.value.length) item.innerHTML += `<input type="hidden" value="${data}">` item.addEventListener( 'click', (event) => { for (const input of event.currentTarget.querySelectorAll('input[type="hidden"]')) { element.value = input.value } this._clearSearchItems() }, false ) searchList.appendChild(item) } } } else { this._clearSearchItems() } } /** * Limpa elementos da busca * @private */ _clearSearchItems() { for (const searchItems of this.component.querySelectorAll('.search-items')) { for (const item of searchItems.querySelectorAll('div')) { searchItems.removeChild(item) } this.component.removeChild(searchItems) } } /** * Define comportamentos do teclado * @private * @param {event} event - referência ao elemento que dispara a ação do teclado */ _handleArrowKeys(event) { switch (event.keyCode) { case 13: if (this._currentFocus > -1) { event.preventDefault() for (const searchItems of this.component.querySelectorAll('.search-items')) { for (const itemActive of searchItems.querySelectorAll('div.is-active')) { itemActive.click() } } this._currentFocus = -1 } break case 38: if (this._currentFocus > 0) { this._currentFocus -= 1 } this._switchFocus() break case 40: for (const searchItems of this.component.querySelectorAll('.search-items')) { if (this._currentFocus < searchItems.querySelectorAll('div').length - 1) { this._currentFocus += 1 } } this._switchFocus() break default: break } } /** * Muda o foco do item de busca * @private */ _switchFocus() { for (const searchItems of this.component.querySelectorAll('.search-items')) { for (const [index, item] of searchItems.querySelectorAll('div').entries()) { if (index === this._currentFocus) { item.classList.add('is-active') } if (index !== this._currentFocus) { item.classList.remove('is-active') } } } } /** * Preenche lista de dados * @private * @param {string[]} dataList - Lista de dados */ setAutocompleteData(dataList) { this.dataList = dataList } } export default BRInput