Skip to content
This repository has been archived by the owner on Oct 18, 2024. It is now read-only.

Commit

Permalink
feat: create tooltip web-component
Browse files Browse the repository at this point in the history
  • Loading branch information
Raspincel committed Dec 18, 2023
1 parent 47d86d1 commit 759189e
Show file tree
Hide file tree
Showing 4 changed files with 266 additions and 0 deletions.
119 changes: 119 additions & 0 deletions src/web-components/tooltip/index.style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { css } from 'lit';

export const dropdownStyle = css`
.superviz-who-is-online__tooltip {
--host-heigth: 0px;
--host-width: 0px;
background-color: rgb(var(--sv-gray-600));
padding: 8px;
display: flex;
flex-direction: column;
gap: 8px;
align-items: center;
position: absolute;
left: 50%;
transform: translateX(-50%);
opacity: 0;
border-radius: 2px;
cursor: default;
display: none;
transition: opacity 0.2s ease-in-out display 0s;
overflow-x: clip;
}
.tooltip-extras {
left: 29px;
top: 60px;
z-index: 10;
}
.superviz-who-is-online__tooltip-arrow {
width: 13px;
height: 13px;
position: absolute;
background-color: rgb(var(--sv-gray-600));
transform: rotate(45deg);
border-top-left-radius: 3px;
border-bottom-right-radius: 3px;
}
.show-tooltip {
opacity: 1;
display: block;
}
.tooltip-name,
.tooltip-action {
margin: 0;
font-family: roboto;
white-space: nowrap;
text-align: center;
}
.tooltip-name {
color: white;
font-size: 14px;
}
.tooltip-action {
color: rgb(var(--sv-gray-400));
font-size: 12px;
}
.tooltip-top {
top: auto;
bottom: calc(var(--host-heigth) + 12px);
}
.tooltip-bottom {
top: calc(var(--host-heigth) + 12px);
bottom: auto;
}
.tooltip-left {
translate: -50% 0;
}
.tooltip-center {
left: 50%;
transform: translateX(-50%);
right: auto;
}
.tooltip-right {
translate: 50% 0;
}
.tooltip-bottom .superviz-who-is-online__tooltip-arrow {
top: -6.5px;
}
.tooltip-top .superviz-who-is-online__tooltip-arrow {
bottom: -6.5px;
}
.tooltip-center .superviz-who-is-online__tooltip-arrow {
left: 0;
margin-left: 50%;
translate: -50% 0;
}
.tooltip-left .superviz-who-is-online__tooltip-arrow {
translate: 50% 0;
border-radius: 0;
right: 0;
}
.tooltip-right .superviz-who-is-online__tooltip-arrow {
translate: -100% 0;
border-radius: 0;
}
@media (max-width: 780px) {
.tooltip-extras {
top: 52px;
left: 25px;
}
}
`;
Empty file.
138 changes: 138 additions & 0 deletions src/web-components/tooltip/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { CSSResultGroup, LitElement, PropertyValueMap, html } from 'lit';
import { customElement } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';

import { WebComponentsBase } from '../base';

import { dropdownStyle } from './index.style';
import { Positions, PositionsEnum } from './types';

const WebComponentsBaseElement = WebComponentsBase(LitElement);
const styles: CSSResultGroup[] = [WebComponentsBaseElement.styles, dropdownStyle];

@customElement('superviz-tooltip')
export class Tooltip extends WebComponentsBaseElement {
static styles = styles;

declare tooltipData: { name: string; action: string };

declare tooltip: HTMLElement;
declare tooltipOnLeft: boolean;
declare showTooltip: boolean;
declare tooltipVerticalPosition: Positions;
declare tooltipHorizontalPosition: Positions;

declare hostSizes: { height: number; width: number };

static properties = {
tooltipData: { type: Object },
tooltipOnLeft: { type: Boolean },
showTooltip: { type: Boolean },
tooltip: { type: Object },
tooltipVerticalPosition: { type: String },
tooltipHorizontalPosition: { type: String },
hostSizes: { type: Object },
};

constructor() {
super();
this.tooltipVerticalPosition = PositionsEnum['TOOLTIP-BOTTOM'];
this.tooltipHorizontalPosition = PositionsEnum['TOOLTIP-CENTER'];
}

protected firstUpdated(
_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>,
): void {}

protected updated(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {
if (changedProperties.has('dropdown')) {
//
}

if (changedProperties.has('showTooltip') && this.showTooltip) {
const { height, width } = (this.getRootNode() as any).host.getBoundingClientRect();
if (this.hostSizes?.height !== height || this.hostSizes?.width !== width) {
this.hostSizes = { height, width };
}

this.tooltipVerticalPosition = PositionsEnum['TOOLTIP-BOTTOM'];
this.tooltipHorizontalPosition = PositionsEnum['TOOLTIP-CENTER'];
}
}

private adjustTooltipVerticalPosition = () => {
const { left, right, bottom, top } = this.tooltip.getBoundingClientRect();
const maxY = window.innerHeight;

if (this.tooltipVerticalPosition.includes('top') && top < 0) {
this.tooltipVerticalPosition = this.tooltipVerticalPosition.replace(
'top',
'bottom',
) as Positions;
}

if (this.tooltipVerticalPosition.includes('bottom') && bottom > maxY) {
this.tooltipVerticalPosition = this.tooltipVerticalPosition.replace(
'bottom',
'top',
) as Positions;
}
};

private adjustTooltipHorizontalPosition = () => {
const { left, right } = this.tooltip.getBoundingClientRect();
const maxX = window.innerWidth;

if (left < 0) {
this.tooltipHorizontalPosition = this.tooltipHorizontalPosition.replace(
'center',
'right',
) as Positions;
}

if (right > maxX) {
this.tooltipHorizontalPosition = this.tooltipHorizontalPosition.replace(
'center',
'left',
) as Positions;
}
};

private adjustTooltipPosition = () => {
if (!this.tooltip) {
this.tooltip = this.shadowRoot.querySelector('.superviz-who-is-online__tooltip');
}

this.adjustTooltipVerticalPosition();
this.adjustTooltipHorizontalPosition();
};

private renderTooltip() {
setTimeout(() => this.adjustTooltipPosition());
const verticalPosition = this.tooltipVerticalPosition;
const horizontalPosition = this.tooltipHorizontalPosition;

const classList = {
'superviz-who-is-online__tooltip': true,
'tooltip-extras': this.tooltipOnLeft,
'show-tooltip': this.showTooltip,
};
classList[verticalPosition] = true;
classList[horizontalPosition] = true;

console.error(horizontalPosition);

return html`<div
class=${classMap(classList)}
style="--host-heigth: ${this.hostSizes?.height}px; --host-width: ${this.hostSizes?.width}px;"
>
<p class="tooltip-name">${this.tooltipData.name}</p>
<p class="tooltip-action">${this.tooltipData.action}</p>
<div class="superviz-who-is-online__tooltip-arrow"></div>
</div>`;
}

protected render() {
return html`${this.renderTooltip()}`;
}
}
9 changes: 9 additions & 0 deletions src/web-components/tooltip/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export enum PositionsEnum {
'TOOLTIP-BOTTOM' = 'tooltip-bottom',
'TOOLTIP-TOP' = 'tooltip-top',
'TOOLTIP-LEFT' = 'tooltip-left',
'TOOLTIP-RIGHT' = 'tooltip-right',
'TOOLTIP-CENTER' = 'tooltip-center',
}

export type Positions = PositionsEnum | `${PositionsEnum}`;

0 comments on commit 759189e

Please sign in to comment.