Search code examples
cssgoogle-apps-scriptgoogle-sheetspositiontooltip

Absolute positioned tooltip (emoji picker) in a GAS dialog?


I have a dialog in my GAS script, and I'd like to add emoji picker to it. This is my picker of choice: https://www.npmjs.com/package/emoji-picker-element#usage All goes well until the moment of actual rendering of the picker. At which time I realize that absolute positioned element still remains strictly inside of a dialog window. So, as it goes now, my only choice is to have a really big dialog. Or is it? Is there any way to make the element render outside of a GAS dialog window?

I've tried to fiddle with z-index, position etc. The tooltip remains inside of a dialog no matter what.

Below is the code that will allow to reproduce the problem.

Debug.js

function emojiTest() {

  const html = HtmlService.createTemplateFromFile('forms/EmojiTest');

  var htmlOutput = html.evaluate()
    .setSandboxMode(HtmlService.SandboxMode.IFRAME)
    .setWidth(250)
    .setHeight(250);

  SpreadsheetApp.getUi()
    .showModalDialog(htmlOutput, 'Test Emoji'); 

}

forms/EmojiTest.html

<!DOCTYPE html>
<html>

<head>
  <base target="_top">
  <script type="module" src="https://cdn.jsdelivr.net/npm/emoji-picker-element@^1/index.js"></script>

  <style>

    /* emoji */
    .tooltip:not(.shown) {
      display: none;
    }

    .tooltip {
      position: absolute;
      top: -30px;
      right: 0;
      left: 0;
      bottom: 0;
    }

  </style>
</head>

<body>

  <form id="nameChangeForm" onsubmit="">
    <input type="text" name="cat" required id="nameField">

    <button onclick="event.preventDefault();">😏</button>
    <div class="tooltip" role="tooltip">
      <emoji-picker></emoji-picker>
    </div> 

    <div id="buttons">
      <input type="submit" value="Submit"  >
    </div>
  </form>

  <script type="module">
    import 'https://cdn.jsdelivr.net/npm/emoji-picker-element@^1/index.js'
  import insertText from 'https://cdn.jsdelivr.net/npm/[email protected]/index.js'

  document.querySelector('emoji-picker').addEventListener('emoji-click', e => {
    insertText(document.querySelector('input'), e.detail.unicode)
  })
  </script>

  <script type="module">
    import * as Popper from 'https://cdn.jsdelivr.net/npm/@popperjs/core@^2/dist/esm/index.js'
  const button = document.querySelector('button')
  const tooltip = document.querySelector('.tooltip')
  Popper.createPopper(button, tooltip)

  document.querySelector('button').onclick = () => {
    tooltip.classList.toggle('shown')
  }
  </script> 

</body>

</html>

Solution

  • From your question and reply, how about the following modification?

    From:

    .tooltip {
      position: absolute;
      top: -30px;
      right: 0;
      left: 0;
      bottom: 0;
    }
    

    And,

    <div class="tooltip" role="tooltip">
      <emoji-picker></emoji-picker>
    </div> 
    

    To:

    .tooltip {
      position: absolute;
      top: auto !important;
      right: 0;
      left: 0;
      bottom: 0;
      transform: none !important;
      width: 230px;
      height: 210px;
    }
    
    .emoji-picker {
      width: 100%;
      height: 100%;
    }
    

    And,

    <div class="tooltip" role="tooltip">
      <emoji-picker class="emoji-picker"></emoji-picker>
    </div>
    

    When this modification is reflected in your showing script, it becomes as follows.

    enter image description here

    If you don't want to use width and height, please remove them.