@govbr-ds/core
Version:
Padrão Digital de Governo
209 lines (198 loc) • 6.03 kB
JavaScript
/** 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