I have this Web Component that has cards with tooltips.
I am trying to accomplish 3 things. I am trying use Vanilla Javascript vs jQuery or other libraries.
-
Show when a button is clicked then hide if button is clicked again. This is currently working.
-
Hide when clicked outside of button. I tried selecting the document then comparing clicked element with the element I want to target, having trouble with targeting.
-
Only show 1 tooltip at a time so if 1 is open then you click another only the second one shows. Not sure how to approach this.
Here is what I have so far.
class BuildABox extends HTMLElement {
constructor() {
super();
this.querySelectorAll('[data-tooltip]').forEach((button) =>
button.addEventListener('click', this.toggleTooltip.bind(this))
);
}
toggleTooltip(e) {
e.preventDefault();
const toolTip = e.currentTarget.lastChild.previousSibling;
toolTip.classList.toggle('tw-invisible');
}
}
customElements.define('build-a-box', BuildABox);
<button id="info-btn" aria-label="Information" type="button" data-info="{{ block.settings.product_description }}">
<div data-tooltip="tooltip" class="tw-w-12">
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="w-12 h-12"
>
<path fill-rule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zm8.706-1.442c1.146-.573 2.437.463 2.126 1.706l-.709 2.836.042-.02a.75.75 0 01.67 1.34l-.04.022c-1.147.573-2.438-.463-2.127-1.706l.71-2.836-.042.02a.75.75 0 11-.671-1.34l.041-.022zM12 9a.75.75 0 100-1.5.75.75 0 000 1.5z" clip-rule="evenodd" />
</svg>
{% comment %} This is tooltip to hide/show {% endcomment %}
<div
id="tooltip"
class="tw-invisible z-50 tw-absolute tw-top-24 tw-max-w-[300px] tw-bg-blue-400 tw-text-white tw-border-graphite tw-border-2 tw-overflow-auto tw-rounded-2xl tw-p-4 tw-mt-1"
>
<p>{{ block.settings.product_description }}</p>
</div>
</div>
</button>
2
Answers
To expound upon my prior comments which I deleted; I updated your code slightly and added some CSS to show it clearly here. I have a data element to choose a target and then use that in the click handler.
You don’t want to create dependencies, thus keep as much of the logic inside the Web Component
Using shadowDOM here because it keeps the Web Component small
and you can style with global CSS using
::part
Key concept:
<my-button tooltip>
The
tooltip
attribute determines of it is visible, or notI whacked in additional styling to show more styling options.
For deep-deep-details on
<slot>
and::slotted
read: ::slotted CSS selector for nested children in shadowDOM slotsame code in: https://jsfiddle.net/WebComponents/xg3ns6od/