Optional Tooltip

by tnhu

HTML

<script src="https://cdn.rawgit.com/webcomponents/custom-elements/master/custom-elements.min.js"></script>
<optional-tooltip class="tooltip--bottom" data="This is a strong strong strong message">
  <strong>This is a strong</strong>
</optional-tooltip>


<optional-tooltip class="tooltip--bottom" data="This is a strong strong strong message">
  <strong style="max-width: 300px;">This is a strong</strong>
</optional-tooltip>

CSS

body {margin: 100px;}

optional-tooltip,
optional-tooltip > * {
  display: inline-block;
}

optional-tooltip > * {
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}

optional-tooltip:not([data-tooltip]):before,
optional-tooltip:not([data-tooltip]):after {
  display: none !important;
}


/* the :before pseudo-element contains the triangle */


/* the :after pseudo-element contains the text */

[class*=tooltip--] {
  position: relative;
}

[class*=tooltip--]:before,
[class*=tooltip--]:after {
  position: absolute;
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  box-sizing: border-box;
  transition: .5s ease;
  transition-delay: 0s;
}

.tooltip--show:before,
.tooltip--show:after,
[class*=tooltip--]:hover:before,
[class*=tooltip--]:hover:after {
  visibility: visible;
  opacity: 1;
  transition-delay: .1s;
}

[class*=tooltip--]:before {
  content: '';
  position: absolute;
  background: transparent;
  height: 6px;
  width: 6px;
  border: 6px solid transparent;
}

[class*=tooltip--]:after {
  background: #383838;
  font-weight: normal;
  color: white;
  padding: 6px 8px;
  font-size: 12px;
  line-height: 1.4;
  white-space: nowrap;
  box-shadow: 1px 1px 4px 1px rgba(0, 0, 0, .2);
  border-radius: 3px;
  text-align: left;
  content: attr(data-tooltip);
}

[class*=tooltip--top]:before {
  border-top-color: #383838;
}

[class*=tooltip--bottom]:before {
  border-bottom-color: #383838;
}

.tooltip--left:before {
  border-left-color: #383838;
}

.tooltip--right:before {
  border-right-color: #383838;
}

[class*=tooltip--top]:before {
  bottom: calc(100% - 6px)
}

[class*=tooltip--top]:after {
  bottom: calc(100% + 6px)
}

.tooltip--top:before {
  left: 50%;
  margin-left: -6px;
}

.tooltip--top:after {
  left: 50%;
  transform: translateX(-50%);
}

[class*=tooltip--bottom]:before {
  top: calc(100% - 6px)
}

[class*=tooltip--bottom]:after {
  top: calc(100% + 6px)
}

.tooltip--bottom:before {
  left: calc(50% -...

JavaScript

//
// Polyfill: https://cdn.rawgit.com/webcomponents/custom-elements/master/custom-elements.min.js
//

try {
  function defineProperties(target, props) {
    for (var i = 0; i < props.length; i++) {
      var descriptor = props[i];
      descriptor.enumerable = descriptor.enumerable || false;
      descriptor.configurable = true;
      if ("value" in descriptor) descriptor.writable = true;
      Object.defineProperty(target, descriptor.key, descriptor);
    }
  }

  var _createClass = (function() {
    return function(Constructor, protoProps, staticProps) {
      if (protoProps) defineProperties(Constructor.prototype, protoProps);
      if (staticProps) defineProperties(Constructor, staticProps);
      return Constructor;
    };
  })();

  var OptionalTooltip = (function(parent) {
    var upgrade = typeof Reflect === 'object' ?
      function() {
        return Reflect.construct(
          parent,
          arguments,
          this.constructor
        );
      } :
      function() {
        return parent.apply(this, arguments) || this;
      };

    function constructor() {}

    function OptionalTooltip() {
      var self = upgrade.apply(this, arguments);
      return constructor.apply(self, arguments) || self;
    }

    OptionalTooltip.prototype = Object.create(
      parent.prototype, {
        constructor: {
          configurable: true,
          writable: true,
          value: OptionalTooltip
        }
      }
    );

    OptionalTooltip.prototype.attributeChangedCallback = function attributeChangedCallback(
      attributeName,
      oldValue,
      newValue,
      namespace
    ) {
      var th = this;

      setTimeout(function() {
        th.adjustTooltip();
      }, 250);
    };

    OptionalTooltip.prototype.adjustTooltip = function adjustTooltip() {
      var ATTR = "data-tooltip";
      var child = this.firstElementChild;

      if (child && child.scrollWidth > child.offsetWidth) {
        this.setAttribute(ATTR, this.getAttribute("data"));
     ...