-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WP-96: Tooltip Web Component #78
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0"> | ||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | ||
<title>Web Component: Tooltip</title> | ||
|
||
<link rel="stylesheet" href="../../dist/tooltip/style.css" media="all"> | ||
<script type="module" src="../../dist/tooltip/index.js"></script> | ||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"> | ||
<style> | ||
*, | ||
*:before, | ||
*:after { | ||
box-sizing: border-box; | ||
} | ||
|
||
|
||
body { | ||
font-family: Arial, sans-serif; | ||
padding: 20px; | ||
background-color: #f4f4f4; | ||
} | ||
|
||
.card-container { | ||
display: flex; | ||
flex-wrap: wrap; /* Makes cards wrap on smaller screens */ | ||
justify-content: center; /* Centers the cards horizontally */ | ||
gap: 20px; /* Adds space between cards */ | ||
} | ||
|
||
.card { | ||
background-color: white; | ||
border: 1px solid #ddd; | ||
border-radius: 8px; | ||
width: 300px; /* Fixed width for cards */ | ||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | ||
transition: transform 0.3s ease; | ||
} | ||
|
||
.card-header { | ||
display: flex; | ||
padding: 0 20px; | ||
justify-content: space-between; | ||
align-items: center; | ||
} | ||
|
||
.info-icon { | ||
color: #555; | ||
font-size: 20px; | ||
cursor: pointer; | ||
transition: color 0.3s ease; | ||
} | ||
|
||
.info-icon:hover { | ||
color: #007BFF; /* Changes icon color on hover */ | ||
} | ||
|
||
@media (max-width: 768px) { | ||
.card { | ||
width: 100%; /* Cards take full width on smaller screens */ | ||
} | ||
} | ||
</style> | ||
</head> | ||
<body style="padding: 0; margin: 0"> | ||
<main > | ||
<tp-tooltip> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @harshdeep-gill Let's remove this component, and allow the user to be define their own ID |
||
<tp-tooltip-trigger> | ||
<div class="my-btn">Hover Me</div> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @harshdeep-gill Let's use a |
||
</tp-tooltip-trigger> | ||
<tp-tooltip-popover style="width: 265px;padding: 5px;border: 2px solid red;">Lorem ipsum dolor sit amet consectetur adipisicing elit. Mollitia molestiae distinctio tempore nobis rem provident libero voluptatum excepturi optio pariatur, accusantium minus ex, doloremque a, repellendus iure quae eaque consectetur!</tp-tooltip-popover> | ||
</tp-tooltip> | ||
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Doloribus eum nulla quam optio numquam reprehenderit, fugit modi eos pariatur, doloremque magnam consequatur atque officiis necessitatibus, deleniti odit quia commodi ullam. Mollitia, reiciendis ipsum impedit quos nobis molestias sit qui vitae voluptate pariatur, fugiat eveniet, veniam magni tenetur repellat eum. Facere aspernatur nobis laborum fuga dolorem quis fugiat, expedita atque cumque quae quia ut in asperiores? Eum, sunt laudantium beatae voluptas architecto impedit itaque ipsam consequatur, blanditiis atque distinctio corporis consectetur ipsum et ut, adipisci dolore exercitationem harum culpa quia. Id tempora laudantium, amet provident maxime ut est nemo veritatis vel.</p> | ||
<tp-tooltip> | ||
<tp-tooltip-trigger> | ||
<div class="my-btn" style="display: flex;gap: 10px;"> | ||
<div>Hover me</div> | ||
<i>i</i> | ||
</div> | ||
</tp-tooltip-trigger> | ||
<tp-tooltip-popover style="width: 265px;">Lorem ipsum dolor sit amet consectetur adipisicing elit. Mollitia molestiae distinctio tempore nobis rem provident libero voluptatum excepturi optio pariatur, accusantium minus ex, doloremque a, repellendus iure quae eaque consectetur!</tp-tooltip-popover> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @harshdeep-gill Let's add |
||
</tp-tooltip> | ||
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Doloribus eum nulla quam optio numquam reprehenderit, fugit modi eos pariatur, doloremque magnam consequatur atque officiis necessitatibus, deleniti odit quia commodi ullam. Mollitia, reiciendis ipsum impedit quos nobis molestias sit qui vitae voluptate pariatur, fugiat eveniet, veniam magni tenetur repellat eum. Facere aspernatur nobis laborum fuga dolorem quis fugiat, expedita atque cumque quae quia ut in asperiores? Eum, sunt laudantium beatae voluptas architecto impedit itaque ipsam consequatur, blanditiis atque distinctio corporis consectetur ipsum et ut, adipisci dolore exercitationem harum culpa quia. Id tempora laudantium, amet provident maxime ut est nemo veritatis vel.</p> | ||
<div style="padding: 20px; border: 1px solid red; margin: 0 20px;"> | ||
<tp-tooltip> | ||
<tp-tooltip-trigger> | ||
<div class="my-btn" style="display: flex;gap: 10px;"> | ||
<div>Hover me</div> | ||
<i>i</i> | ||
</div> | ||
</tp-tooltip-trigger> | ||
<tp-tooltip-popover style="width: 265px;">Lorem ipsum dolor sit amet consectetur adipisicing elit. Mollitia molestiae distinctio tempore nobis rem provident libero voluptatum excepturi optio pariatur, accusantium minus ex, doloremque a, repellendus iure quae eaque consectetur!</tp-tooltip-popover> | ||
</tp-tooltip> | ||
<tp-tooltip> | ||
<tp-tooltip-trigger> | ||
<div class="my-btn" style="display: flex;gap: 10px;"> | ||
<div>Hover me</div> | ||
<i>i</i> | ||
</div> | ||
</tp-tooltip-trigger> | ||
<tp-tooltip-popover style="width: 265px;">Lorem ipsum dolor sit amet consectetur adipisicing elit. Mollitia molestiae distinctio tempore nobis rem provident libero voluptatum excepturi optio pariatur, accusantium minus ex, doloremque a, repellendus iure quae eaque consectetur!</tp-tooltip-popover> | ||
</tp-tooltip> | ||
<tp-tooltip> | ||
<tp-tooltip-trigger> | ||
<div class="my-btn" style="display: flex;gap: 10px;"> | ||
<div>Hover me</div> | ||
<i>i</i> | ||
</div> | ||
</tp-tooltip-trigger> | ||
<tp-tooltip-popover style="width: 265px;">Lorem ipsum dolor sit amet consectetur adipisicing elit. Mollitia molestiae distinctio tempore nobis rem provident libero voluptatum excepturi optio pariatur, accusantium minus ex, doloremque a, repellendus iure quae eaque consectetur!</tp-tooltip-popover> | ||
</tp-tooltip> | ||
<tp-tooltip> | ||
<tp-tooltip-trigger> | ||
<div class="my-btn" style="display: flex;gap: 10px;"> | ||
<div>Hover me</div> | ||
<i>i</i> | ||
</div> | ||
</tp-tooltip-trigger> | ||
<tp-tooltip-popover style="width: 265px;">Lorem ipsum dolor sit amet consectetur adipisicing elit. Mollitia molestiae distinctio tempore nobis rem provident libero voluptatum excepturi optio pariatur, accusantium minus ex, doloremque a, repellendus iure quae eaque consectetur!</tp-tooltip-popover> | ||
</tp-tooltip> | ||
<tp-tooltip> | ||
<tp-tooltip-trigger> | ||
<div class="my-btn" style="display: flex;gap: 10px;"> | ||
<div>Hover me</div> | ||
<i>i</i> | ||
</div> | ||
</tp-tooltip-trigger> | ||
<tp-tooltip-popover style="width: 265px;">Lorem ipsum dolor sit amet consectetur adipisicing elit. Mollitia molestiae distinctio tempore nobis rem provident libero voluptatum excepturi optio pariatur, accusantium minus ex, doloremque a, repellendus iure quae eaque consectetur!</tp-tooltip-popover> | ||
</tp-tooltip> | ||
<tp-tooltip> | ||
<tp-tooltip-trigger> | ||
<div class="my-btn" style="display: flex;gap: 10px;"> | ||
<div>Hover me</div> | ||
<i>i</i> | ||
</div> | ||
</tp-tooltip-trigger> | ||
<tp-tooltip-popover style="width: 265px;">Lorem ipsum dolor sit amet consectetur adipisicing elit. Mollitia molestiae distinctio tempore nobis rem provident libero voluptatum excepturi optio pariatur, accusantium minus ex, doloremque a, repellendus iure quae eaque consectetur!</tp-tooltip-popover> | ||
</tp-tooltip> | ||
<tp-tooltip> | ||
<tp-tooltip-trigger> | ||
<div class="my-btn" style="display: flex;gap: 10px;"> | ||
<div>Hover me</div> | ||
<i>i</i> | ||
</div> | ||
</tp-tooltip-trigger> | ||
<tp-tooltip-popover style="width: 265px;">Lorem ipsum dolor sit amet consectetur adipisicing elit. Mollitia molestiae distinctio tempore nobis rem provident libero voluptatum excepturi optio pariatur, accusantium minus ex, doloremque a, repellendus iure quae eaque consectetur!</tp-tooltip-popover> | ||
</tp-tooltip> | ||
<tp-tooltip> | ||
<tp-tooltip-trigger> | ||
<div class="my-btn" style="display: flex;gap: 10px;"> | ||
<div>Hover me</div> | ||
<i>i</i> | ||
</div> | ||
</tp-tooltip-trigger> | ||
<tp-tooltip-popover style="width: 265px;">Lorem ipsum dolor sit amet consectetur adipisicing elit. Mollitia molestiae distinctio tempore nobis rem provident libero voluptatum excepturi optio pariatur, accusantium minus ex, doloremque a, repellendus iure quae eaque consectetur!</tp-tooltip-popover> | ||
</tp-tooltip> | ||
</div> | ||
|
||
|
||
<div class="card-container"> | ||
<div class="card"> | ||
<div class="card-header"> | ||
<h2>Card 1</h2> | ||
<tp-tooltip> | ||
<tp-tooltip-trigger> | ||
<i class="fas fa-info-circle info-icon"></i> | ||
</tp-tooltip-trigger> | ||
<tp-tooltip-popover style="width: 265px;">Lorem ipsum dolor sit amet consectetur adipisicing elit. Mollitia molestiae | ||
distinctio tempore nobis rem provident libero voluptatum excepturi optio pariatur, accusantium minus ex, doloremque | ||
a, repellendus iure quae eaque consectetur! | ||
</tp-tooltip-popover> | ||
</tp-tooltip> | ||
</div> | ||
<p>This is the first card.</p> | ||
</div> | ||
<div class="card"> | ||
<div class="card-header"> | ||
<h2>Card 2</h2> | ||
<tp-tooltip> | ||
<tp-tooltip-trigger> | ||
<i class="fas fa-info-circle info-icon"></i> | ||
</tp-tooltip-trigger> | ||
<tp-tooltip-popover style="width: 265px;">Lorem ipsum dolor sit amet consectetur adipisicing elit. Mollitia molestiae | ||
distinctio tempore nobis rem provident libero voluptatum excepturi optio pariatur, accusantium minus ex, doloremque | ||
a, repellendus iure quae eaque consectetur! | ||
</tp-tooltip-popover> | ||
</tp-tooltip> | ||
</div> | ||
<p>This is the first card.</p> | ||
</div> | ||
<div class="card"> | ||
<div class="card-header"> | ||
<h2>Card 3</h2> | ||
<tp-tooltip> | ||
<tp-tooltip-trigger> | ||
<i class="fas fa-info-circle info-icon"></i> | ||
</tp-tooltip-trigger> | ||
<tp-tooltip-popover style="width: 265px;">Lorem ipsum dolor sit amet consectetur adipisicing elit. Mollitia molestiae | ||
distinctio tempore nobis rem provident libero voluptatum excepturi optio pariatur, accusantium minus ex, doloremque | ||
a, repellendus iure quae eaque consectetur! | ||
</tp-tooltip-popover> | ||
</tp-tooltip> | ||
</div> | ||
<p>This is the first card.</p> | ||
</div> | ||
</div> | ||
</main> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/** | ||
* Styles. | ||
*/ | ||
import './style.scss'; | ||
|
||
/** | ||
* Components. | ||
*/ | ||
import { TPTooltipElement } from './tp-tooltip'; | ||
import { TPTooltipTriggerElement } from './tp-tooltip-trigger'; | ||
import { TPTooltipPopoverElement } from './tp-tooltip-popover'; | ||
|
||
|
||
Check failure on line 13 in src/tooltip/index.ts GitHub Actions / test
|
||
/** | ||
* Register Components. | ||
*/ | ||
|
||
customElements.define( 'tp-tooltip', TPTooltipElement ); | ||
customElements.define( 'tp-tooltip-trigger', TPTooltipTriggerElement ); | ||
customElements.define( 'tp-tooltip-popover', TPTooltipPopoverElement ); | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
tp-tooltip-trigger > button { | ||
background-color: transparent; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @harshdeep-gill Let's remove all styles that are not essential |
||
border: none; | ||
outline: none; | ||
cursor: pointer; | ||
padding: 0; | ||
} | ||
|
||
tp-tooltip-popover { | ||
--arrow-top-positioning: 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @harshdeep-gill Let's rename to |
||
--arrow-left-positioning: 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @harshdeep-gill Let's rename to |
||
--border-top-color: transparent; | ||
--border-bottom-color: transparent; | ||
background-color: #fff; | ||
|
||
&::backdrop { | ||
width: 0; | ||
height: 0; | ||
border-width: 8px; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @harshdeep-gill Let's make all these styles as bare-bones as possible |
||
border-style: solid; | ||
border-top-color: var(--border-top-color); | ||
border-bottom-color: var(--border-bottom-color); | ||
border-left-color: transparent; | ||
border-right-color: transparent; | ||
top: var(--arrow-top-positioning); | ||
left: var(--arrow-left-positioning); | ||
transform: translateX(-50%); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
import { TPTooltipElement } from "./tp-tooltip"; | ||
Check failure on line 1 in src/tooltip/tp-tooltip-popover.ts GitHub Actions / test
|
||
|
||
/** | ||
* TP Tooltip Popover. | ||
*/ | ||
export class TPTooltipPopoverElement extends HTMLElement { | ||
/** | ||
* Properties. | ||
*/ | ||
protected trigger: TPTooltipElement | null; | ||
protected tooltipWidth: number; | ||
protected tooltipArrowHeight: number; | ||
protected tooltipGap: number; | ||
|
||
constructor() { | ||
Check failure on line 15 in src/tooltip/tp-tooltip-popover.ts GitHub Actions / test
Check failure on line 15 in src/tooltip/tp-tooltip-popover.ts GitHub Actions / test
|
||
|
||
// Initialize parent. | ||
super(); | ||
|
||
this.trigger = this.closest( 'tp-tooltip' ); | ||
this.tooltipWidth = parseInt(this.style.width) || 0; | ||
this.tooltipArrowHeight = parseInt(this.getAttribute( 'arrow-height' ) || '8'); | ||
this.tooltipGap = parseInt(this.getAttribute( 'gap' ) || '10'); | ||
} | ||
|
||
showTooltip() { | ||
this.showPopover(); | ||
this.positionTooltip(); | ||
} | ||
|
||
hideTooltip() { | ||
this.hidePopover(); | ||
} | ||
|
||
/** | ||
* Position tooltip according to the position of the trigger element. | ||
* Position is calculated based on the following rules: | ||
* 1. If there is enough space above the trigger element, tooltip will be placed below the trigger element else it will be above. | ||
* 2. If there is enough space to the right of the trigger element tooltip will be aligned with the parent container of tp-tooltip element | ||
* the tooltip will be placed to the left of the trigger element. | ||
* 3. Similarly if there is not enough space on right of the trigger element. | ||
*/ | ||
positionTooltip() { | ||
// Early return if button not found. | ||
if( !this.trigger ) { | ||
return; | ||
} | ||
|
||
// Getting positions of elements of interest. | ||
// Getting position for tooltip popover. | ||
const tooltipPopoverPosition = this.getElementPosition( this ); | ||
console.log(tooltipPopoverPosition); | ||
|
||
// Getting position for tooltip trigger button. | ||
const tooltipTriggerPosition = this.getElementPosition( this.trigger ); | ||
|
||
// Getting position for tooltip parent element. | ||
// It will be used to position tooltip when there is not enough space to the right and left. | ||
const parentPosition = this.getElementPosition( this.trigger.parentNode as Element ); | ||
|
||
if( tooltipPopoverPosition && tooltipTriggerPosition && parentPosition) { | ||
const distanceFromTopWall = (tooltipTriggerPosition.bottom - tooltipTriggerPosition.height); | ||
|
||
// Getting viewport width. | ||
const viewportWidth = Math.max( document.documentElement.clientWidth || 0, window.innerWidth || 0 ); | ||
|
||
const tooltipTriggerHalfWidth = tooltipTriggerPosition.width / 2; | ||
const tooltipPopupHalfWidth = this.tooltipWidth / 2; | ||
const marginFromWalls = 0; | ||
|
||
// Setting tooltip text and arrow position in Y direction | ||
let textMarginTop; | ||
let arrowTopPosition; | ||
|
||
if( tooltipPopoverPosition.height + marginFromWalls > distanceFromTopWall ) { | ||
textMarginTop = tooltipTriggerPosition.bottom + this.tooltipGap + this.tooltipArrowHeight; | ||
this.style.setProperty( '--border-bottom-color', "#121212" ); | ||
arrowTopPosition = tooltipTriggerPosition.bottom - this.tooltipArrowHeight + this.tooltipGap; | ||
} else { | ||
textMarginTop = tooltipTriggerPosition.bottom - tooltipPopoverPosition.height - tooltipTriggerPosition.height - this.tooltipGap - this.tooltipArrowHeight; | ||
this.style.setProperty( '--border-top-color', "#121212" ); | ||
arrowTopPosition = tooltipTriggerPosition.bottom - tooltipTriggerPosition.height - this.tooltipGap - this.tooltipArrowHeight; | ||
} | ||
console.log(tooltipTriggerPosition.bottom, textMarginTop, arrowTopPosition); | ||
|
||
this.style.marginTop = `calc(${ textMarginTop }px )`; | ||
this.style.setProperty( '--arrow-top-positioning', `${ arrowTopPosition }px` ); | ||
|
||
|
||
// Position tooltip in X direction. | ||
let textMarginLeft; | ||
const arrowLeftPosition = tooltipTriggerPosition.right - tooltipTriggerHalfWidth; | ||
|
||
if ( viewportWidth - tooltipTriggerPosition.right + tooltipTriggerHalfWidth < tooltipPopupHalfWidth + marginFromWalls ) { | ||
// Position of tooltip if there is not enough space to the right. | ||
textMarginLeft = parentPosition.right - this.tooltipWidth; | ||
} else if ( tooltipTriggerPosition.right - tooltipTriggerHalfWidth < tooltipPopupHalfWidth + marginFromWalls ) { | ||
// Position of tooltip if there is not enough space to the left. | ||
textMarginLeft = parentPosition.right - parentPosition.width; | ||
} else { | ||
textMarginLeft = tooltipTriggerPosition.right - tooltipPopupHalfWidth - tooltipTriggerHalfWidth; | ||
} | ||
|
||
// Setting location of the tooltip text. | ||
this.style.marginLeft = textMarginLeft + 'px'; | ||
this.style.setProperty( '--arrow-left-positioning', `${ arrowLeftPosition }px` ); | ||
} | ||
} | ||
|
||
/** | ||
* Gets the position of a given element in the viewport. | ||
*/ | ||
getElementPosition( element : Element | null ) { | ||
const elementRect = element?.getBoundingClientRect(); | ||
return elementRect; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/** | ||
* TP Tooltip Trigger. | ||
*/ | ||
export class TPTooltipTriggerElement extends HTMLElement { | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@harshdeep-gill Let's make this file bare-bones and only contain code and styles that are absolutely required (won't work without it)