index.ts 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import { Tooltip } from 'bootstrap'
  2. function getElementWidth(el: Element) {
  3. const elComputedStyle = window.getComputedStyle(el)
  4. const elPaddingX =
  5. parseFloat(elComputedStyle.paddingLeft) +
  6. parseFloat(elComputedStyle.paddingRight)
  7. const elBorderX =
  8. parseFloat(elComputedStyle.borderLeftWidth) +
  9. parseFloat(elComputedStyle.borderRightWidth)
  10. return el.scrollWidth - elPaddingX - elBorderX
  11. }
  12. const visibleInstances = new Set<Tooltip>()
  13. function handleEscapeKey(e: KeyboardEvent) {
  14. if (e.key === 'Escape') {
  15. visibleInstances.forEach(instance => instance.hide())
  16. e.stopPropagation()
  17. }
  18. }
  19. function createTooltip(element: Element): Tooltip {
  20. const instance = new Tooltip(element)
  21. element.addEventListener('show.bs.tooltip', () => {
  22. if (visibleInstances.size === 0) {
  23. document.addEventListener('keydown', handleEscapeKey, { capture: true })
  24. }
  25. visibleInstances.add(instance)
  26. })
  27. element.addEventListener('hide.bs.tooltip', () => {
  28. visibleInstances.delete(instance)
  29. if (visibleInstances.size === 0) {
  30. document.removeEventListener('keydown', handleEscapeKey, {
  31. capture: true,
  32. })
  33. }
  34. })
  35. return instance
  36. }
  37. const footerLanguageElement = document.querySelector(
  38. '[data-ol-lang-selector-tooltip]'
  39. ) as Element
  40. if (footerLanguageElement) {
  41. createTooltip(footerLanguageElement)
  42. }
  43. const allTooltips = document.querySelectorAll('[data-bs-toggle="tooltip"]')
  44. allTooltips.forEach(element => {
  45. createTooltip(element)
  46. })
  47. const possibleBadgeTooltips = document.querySelectorAll('[data-badge-tooltip]')
  48. possibleBadgeTooltips.forEach(element => {
  49. // Put data-badge-tooltip on .badge-content
  50. // then tooltip is only shown if content is clipped due to max-width on .badge
  51. // Due to font loading, the width calculated on page load might change, so we might
  52. // incorrectly determine a tooltip is not needed. This is why max-width will always be set to none
  53. // if no tooltip is shown so that content is fully visible in those scenarios.
  54. if (element.parentElement) {
  55. const parentWidth = getElementWidth(element.parentElement)
  56. if (element.scrollWidth > parentWidth) {
  57. createTooltip(element)
  58. } else {
  59. element.parentElement.style.maxWidth = 'none'
  60. }
  61. }
  62. })