lib/widgets/mqVirtualKeyboard/Button.js

import { j3pAddTxt } from 'src/legacy/core/functions'
import { getCssDimension } from 'src/lib/utils/css'

const displayValue = (value) => value.replace('*', '×').replace('/', '÷')

/**
 * @typedef ButtonOptions
 * @type Object
 * @property {string} [className] une classe css éventuelle
 * @property {string|number} [fontSize] Une taille (si number ce sera l’unité px, sinon préciser l’unité css)
 * @property {function} [onClick] un listener click & touch éventuel
 * @property {string} [value] Le texte du bouton (ne pas le fournir et le compléter ultérieurement s’il y a besoin de mettre du html dedans)
 */

class Button {
  /**
   * Créé un <button> générique (mais ne l’ajoute pas dans le dom)
   * @param {ButtonOptions} options
   * @class Button
   * @constructor
   */
  constructor (options = {}) {
    const { className, fontSize, onClick, value } = options
    const btn = document.createElement('button')
    if (value) j3pAddTxt(btn, displayValue(value))
    if (className) btn.classList.add(className)
    if (fontSize) {
      const cleanFontSize = getCssDimension(fontSize)
      if (cleanFontSize) btn.style.fontSize = cleanFontSize
    }
    // On désactive l’accès par tabulation aux boutons, pour qu’un tab passe d’un input à l’autre sans s’arrêter sur chaque bouton
    // (si on a un clavier on s’attend à ce comportement et on a pas besoin de clavier virtuel)
    btn.setAttribute('tabindex', -1)
    if (typeof onClick === 'function') {
      btn.addEventListener('click', onClick)
    }
    // Si on est sur tablette il ne faut pas qu’un double clic sur un bouton génère un zoom sur la page
    // au lieu d’un click.
    // On apppelle donc preventDefault() et stopPropagation(à) ce qui fera que l’événement clic ne sera
    // pas généré et un zomm sur la page non plus.
    btn.addEventListener('touchstart', (event) => {
      onClick(event)
      if (typeof event.cancelable !== 'boolean' || event.cancelable) event.preventDefault()
      event.stopPropagation()
    }, { passive: false })
    // faut pas que nos boutons puissent avoir le focus sinon la touche entrée du clavier physique agit comme un clic sur le bouton
    btn.addEventListener('focus', () => btn.blur())
    /**
     * L’élément <button> créé
     * @type {HTMLButtonElement}
     */
    this.element = btn
  }
}

export default Button