Skip to content

Commit

Permalink
No issue - combine the alert and info tooltips
Browse files Browse the repository at this point in the history
  • Loading branch information
Manvel committed Mar 28, 2024
1 parent e8afccf commit afca815
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 80 deletions.
97 changes: 37 additions & 60 deletions src/cba-list/cba-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import ConstructableCSS from '../ConstructableCSS';
const constructableCSS = new ConstructableCSS(shadowCSS);

/**
* @typedef {object} Alert - alert object.
* @property {string} [text] - alert text.
* @property {"error"} [type] - alert type.
* @typedef {object} Info - information tooltip.
* @property {string} [description] - tooltip text.
* @property {"error" | "info"} [type] - tooltip type.
* @property {string} [link] - tooltip link.
* @property {string} [linkText] - tooltip link text.
*/

/**
Expand All @@ -16,7 +18,7 @@ const constructableCSS = new ConstructableCSS(shadowCSS);
* @property {string} text - Text to be displayed.
* @property {boolean} selected - Is the item selected.
* @property {boolean} editable - Is the item editable.
* @property {Alert} alert - highlight row.
* @property {Info} [info] - information tooltip.
*/

/**
Expand All @@ -27,7 +29,7 @@ const constructableCSS = new ConstructableCSS(shadowCSS);
* @property {ListSubItem["selected"]} selected - Is the item selected.
* @property {ListSubItem["editable"]} editable - Is the item editable.
* @property {ListSubItem[]} subItems - Sub items of the item.
* @property {Alert} [alert] - highlight row.
* @property {Info} [info] - information tooltip.
*/

const infoIcon = html`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" viewBox="0 0 487.65 487.65" width="12px" height="12px">
Expand Down Expand Up @@ -530,61 +532,37 @@ export class List extends HTMLElement
this.subheading.textContent = this.getAttribute("subheading");
}

/**
* Get tooltip text from the item
* @param {object} item row item object
* @param {string} tooltip "tooltip" attribute value
*/
_getText(item, tooltip)
{
if (!tooltip || !item)
{
return "";
}
if (tooltip.includes("."))
{
return tooltip.split(".").reduce((acc, prop) => acc[prop] || "" , item);
}
else if (tooltip.includes("$"))
{
return tooltip.split("$").reduce((acc, prop, index, {length}) =>
{
if (index -1 === length)
return acc[parseInt(prop, 10)] || "";
else
return acc[prop] || "";
}, item);
}
return item[tooltip] || "";
}

showTooltip({target})
{
const itemId = target.closest("li").dataset.id;
const item = this.getItem(itemId);
const infoText = this._getText(item, this.tooltipText);
if (infoText)
if (item.info)
{
const isFirstRender = !this.tooltip.querySelector("p");
// On first tooltip render when cba-list is placed inside of flexbox the
// tooltip location is calculated wrongly, recalculation fixes that.
if (!this.tooltip.querySelector("p"))
this._renderTooltip(target, item);
this._renderTooltip(target, item);
this._renderTooltip(target, item.info);
if (isFirstRender)
{
setTimeout(() => this._renderTooltip(target, item.info), 50);
}
}
}

/**
* @param {HTMLElement} infoElem info icon wrapper
* @param {Info} item row item object
*/
_renderTooltip(infoElem, item)
{
const infoText = this._getText(item, this.tooltipText);
const infoLink = this._getText(item, this.tooltipLink);
const infoLinkText = this._getText(item, this.tooltipLinkText) ||
this.tooltipLinkTextDefault;
const subitems = infoLink ? html`<a href="${infoLink}">${infoLinkText}</a>` : "";
const infoText = item.description || "";
const subitems = item.link ? html`<a href="${item.link}">${item.linkText}</a>` : "";
render(html`<p>${infoText}</p>${subitems}`, this.tooltip);
const infoRect = infoElem.getBoundingClientRect();
const tooltipRect = this.tooltip.getBoundingClientRect();
this.style.setProperty("--tooltip-offset-y", `${infoRect.top}px`);
this.style.setProperty("--tooltip-offset-x", `${tooltipRect.width}px`);
const offsetTop = (infoRect.top + infoRect.height / 2) - this.getBoundingClientRect().top - 2;
const offsetRight = infoRect.width + 5;
this.style.setProperty("--tooltip-offset-y", `${offsetTop}px`);
this.style.setProperty("--tooltip-offset-x", `${offsetRight}px`);
this.tooltip.classList.add("visible");
}

Expand All @@ -608,22 +586,21 @@ export class List extends HTMLElement
const classes = ["row"];
if (selected)
classes.push("highlight");
let alertTmpl = "";
if (item.alert)
const row = html`<span class="${classes.join(" ")}" draggable="${this.drag}" title="${text}" tabindex="${selected ? 0 : -1}" contenteditable="${editable}" class="text">${text}</span>`;
if (item.info)
{
alertTmpl = html`<span class="alert ${item.alert.type}"><cba-tooltip text="${item.alert.text}" arrow="x">${infoIcon}</cba-tooltip></span>`;
}
const row = html`<div><span class="${classes.join(" ")}" draggable="${this.drag}" title="${text}" tabindex="${selected ? 0 : -1}" contenteditable="${editable}" class="text">${text}</span>${alertTmpl}</div>`;
const infoText = this._getText(item, this.tooltipText);
if (infoText)
{
const tooltip = html`<span class="${infoText ? "hasInfo" : ""}" @mouseenter="${this.showTooltip.bind(this)}" @mouseleave="${this.hideTooltip.bind(this)}"></span>`;
return html`${tooltip}${row}`;
}
else
{
return row;
const infoTypeClassname = item.info.type === "error" ? "alert" : "default";
const tooltip = html`<span class="${infoTypeClassname} info" @mouseenter="${this.showTooltip.bind(this)}" @mouseleave="${this.hideTooltip.bind(this)}">${infoIcon}</span>`;
if (item.info.type === "error")
{
return html`<div class="rowWrapper">${tooltip}${row}</div>`;
}
else
{
return html`<div class="rowWrapper">${tooltip}${row}</div>`;
}
}
return html`<div class="rowWrapper">${row}</div>`;
}
const createList = (item) =>
{
Expand Down
28 changes: 20 additions & 8 deletions src/cba-list/shadow.css
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,8 @@ ul
li .row
{
display: flex;
flex: 1;
align-items: center;
border: solid 1px var(--color-border);
border-top-width: 0;
border-left-width: 0;
border-right-width: 0;
font-weight: 300;
padding-left: 5px;
}
Expand All @@ -143,19 +140,33 @@ li .row:not(.highlight):hover
cursor: pointer;
}

li .alert
li .info
{
position: absolute;
right: 5px;
top: 0px;
cursor: pointer;
}

li .alert svg g
.rowWrapper
{
display: flex;
border: solid 1px var(--color-border);
border-top-width: 0;
border-left-width: 0;
border-right-width: 0;
}

li .info.alert svg g
{
fill: rgb(255, 131, 131);
}

li .info.default svg g
{
fill: #999;
}

ul li
{
position: relative;
Expand Down Expand Up @@ -257,7 +268,7 @@ li > button.collapsed
{
--arrow-adjust-x: calc(0px - var(--tooltip-arrow-size) / 2 - var(--tooltip-border-size));
--arrow-adjust-y: calc(var(--arrow-adjust-x) + var(--tooltip-arrow-size));
--tooltip-adjust-x: calc((var(--tooltip-offset-x) * -1) - var(--tooltip-arrow-size));
--tooltip-adjust-x: calc(var(--tooltip-offset-x) + var(--tooltip-arrow-size));
--tooltip-adjust-y: calc(var(--tooltip-offset-y) - var(--tooltip-arrow-size));

border: var(--tooltip-border-size) solid var(--tooltip-border-color);
Expand All @@ -266,12 +277,13 @@ li > button.collapsed
padding: 10px;
position: absolute;
max-width: var(--tooltip-max-width);
width: 100%;
visibility: visible;
opacity: 1;
transition: visibility 0.3s, opacity 0.3s linear;
font-size: 1em;
top: var(--tooltip-adjust-y);
left: var(--tooltip-adjust-x);
right: var(--tooltip-adjust-x);
z-index: 21;
}

Expand Down
2 changes: 1 addition & 1 deletion src/cba-tooltip/shadow.css
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
visibility: visible;
opacity: 1;
transition: visibility 0.3s, opacity 0.3s linear;
z-index: 1;
z-index: 21;
}

:host(:not(:hover)) #tooltip,
Expand Down
5 changes: 3 additions & 2 deletions tests/smoke/cba-list/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#sortable
{
height: 100%;
--tooltip-icon: url("info.svg#default");
}
#subItemList
{
Expand All @@ -54,8 +55,8 @@ <h1>cba-list</h1>
<input type="text" name="data"><br>
</div>
</div>
<div class="wrapper" style="vertical-align: top; width: 150px">
<cba-list sort="true" id="sortable" heading="Heading" subheading="Column"></cba-list>
<div class="wrapper" style="width: 150px;">
<cba-list id="sortable" heading="Heading" subheading="Column"></cba-list>
</div>
</div>

Expand Down
21 changes: 12 additions & 9 deletions tests/smoke/cba-list/smoke.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ const items = [
id: "row1",
data: "Info",
text: "List1",
alert: {
text: "Topmost element Alert text",
info: {
description: "Topmost element Alert text",
type: "error"
}
},
Expand All @@ -23,8 +23,8 @@ const items = [
id: "subrow2",
data: "Info",
text: "Sub List2",
alert: {
text: "Subitem Alert text",
info: {
description: "Subitem Alert text",
type: "error"
}
},
Expand All @@ -51,7 +51,7 @@ for (let i = 4; i < 20; i++)
if (i === 10)
{
item.alert = {
text: "Middle Alert text",
description: "Middle Alert text",
type: "error"
}
}
Expand All @@ -61,8 +61,8 @@ items.push({
id: "row20",
data: "Info",
text: "List20",
alert: {
text: "Bottom Alert text",
info: {
description: "Bottom Alert text",
type: "error"
}
});
Expand All @@ -71,10 +71,13 @@ cbaList.items = items;
const cbaSortableList = document.querySelector("#sortable");
cbaSortableList.items = [
{
text: "A longer List1 to test wrap"
text: "A longer",
},
{
text: "List3"
text: "List3",
info: {
description: "Info description to be visible when hovered over the icon."
},
},
{
text: "List2"
Expand Down

0 comments on commit afca815

Please sign in to comment.